com.somospnt.signature.SigUtils Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of pdfbox-signature-api Show documentation
Show all versions of pdfbox-signature-api Show documentation
This is a libray to digital signing a PDF and a PFX valid certificate.
Based in PDFBox official SVN example.
The newest version!
/*
* Copyright 2017 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.somospnt.signature;
import java.security.cert.CertificateParsingException;
import java.security.cert.X509Certificate;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.pdfbox.cos.COSArray;
import org.apache.pdfbox.cos.COSBase;
import org.apache.pdfbox.cos.COSDictionary;
import org.apache.pdfbox.cos.COSName;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.interactive.digitalsignature.PDSignature;
import org.bouncycastle.asn1.x509.KeyPurposeId;
/**
* Utility class for the signature / timestamp examples.
*
* @author Tilman Hausherr
*/
final class SigUtils {
private static final Log LOG = LogFactory.getLog(SigUtils.class);
private SigUtils() {
}
/**
* Get the access permissions granted for this document in the DocMDP
* transform parameters dictionary. Details are described in the table
* "Entries in the DocMDP transform parameters dictionary" in the PDF
* specification.
*
* @param doc document.
* @return the permission value. 0 means no DocMDP transform parameters
* dictionary exists. Other return values are 1, 2 or 3. 2 is also returned
* if the DocMDP transform parameters dictionary is found but did not
* contain a /P entry, or if the value is outside the valid range.
*/
protected static int getMDPPermission(PDDocument doc) {
COSBase base = doc.getDocumentCatalog().getCOSObject().getDictionaryObject(COSName.PERMS);
if (base instanceof COSDictionary) {
COSDictionary permsDict = (COSDictionary) base;
base = permsDict.getDictionaryObject(COSName.DOCMDP);
if (base instanceof COSDictionary) {
COSDictionary signatureDict = (COSDictionary) base;
base = signatureDict.getDictionaryObject("Reference");
if (base instanceof COSArray) {
COSArray refArray = (COSArray) base;
for (int i = 0; i < refArray.size(); ++i) {
base = refArray.getObject(i);
if (base instanceof COSDictionary) {
COSDictionary sigRefDict = (COSDictionary) base;
if (COSName.DOCMDP.equals(sigRefDict.getDictionaryObject("TransformMethod"))) {
base = sigRefDict.getDictionaryObject("TransformParams");
if (base instanceof COSDictionary) {
COSDictionary transformDict = (COSDictionary) base;
int accessPermissions = transformDict.getInt(COSName.P, 2);
if (accessPermissions < 1 || accessPermissions > 3) {
accessPermissions = 2;
}
return accessPermissions;
}
}
}
}
}
}
}
return 0;
}
/**
* Set the access permissions granted for this document in the DocMDP
* transform parameters dictionary. Details are described in the table
* "Entries in the DocMDP transform parameters dictionary" in the PDF
* specification.
*
* @param doc The document.
* @param signature The signature object.
* @param accessPermissions The permission value (1, 2 or 3).
*/
protected static void setMDPPermission(PDDocument doc, PDSignature signature, int accessPermissions) {
COSDictionary sigDict = signature.getCOSObject();
COSDictionary transformParameters = new COSDictionary();
transformParameters.setItem(COSName.TYPE, COSName.getPDFName("TransformParams"));
transformParameters.setInt(COSName.P, accessPermissions);
transformParameters.setName(COSName.V, "1.2");
transformParameters.setNeedToBeUpdated(true);
COSDictionary referenceDict = new COSDictionary();
referenceDict.setItem(COSName.TYPE, COSName.getPDFName("SigRef"));
referenceDict.setItem("TransformMethod", COSName.DOCMDP);
referenceDict.setItem("DigestMethod", COSName.getPDFName("SHA256"));
referenceDict.setItem("TransformParams", transformParameters);
referenceDict.setNeedToBeUpdated(true);
COSArray referenceArray = new COSArray();
referenceArray.add(referenceDict);
sigDict.setItem("Reference", referenceArray);
referenceArray.setNeedToBeUpdated(true);
COSDictionary catalogDict = doc.getDocumentCatalog().getCOSObject();
COSDictionary permsDict = new COSDictionary();
catalogDict.setItem(COSName.PERMS, permsDict);
permsDict.setItem(COSName.DOCMDP, signature);
catalogDict.setNeedToBeUpdated(true);
permsDict.setNeedToBeUpdated(true);
}
/**
* Log if the certificate is not valid for signature usage. Doing this
* anyway results in Adobe Reader failing to validate the PDF.
*
* @param x509Certificate
* @throws java.security.cert.CertificateParsingException
*/
protected static void checkCertificateUsage(X509Certificate x509Certificate) throws CertificateParsingException {
boolean[] keyUsage = x509Certificate.getKeyUsage();
if (keyUsage != null && !keyUsage[0] && !keyUsage[1]) {
LOG.error("Certificate key usage does not include "
+ "digitalSignature nor nonRepudiation");
}
List extendedKeyUsage = x509Certificate.getExtendedKeyUsage();
if (extendedKeyUsage != null
&& !extendedKeyUsage.contains(KeyPurposeId.id_kp_emailProtection.toString())
&& !extendedKeyUsage.contains(KeyPurposeId.id_kp_codeSigning.toString())
&& !extendedKeyUsage.contains(KeyPurposeId.anyExtendedKeyUsage.toString())
&& !extendedKeyUsage.contains("1.2.840.113583.1.1.5")
&& !extendedKeyUsage.contains("1.3.6.1.4.1.311.10.3.12")) {
LOG.error("Certificate extended key usage does not include "
+ "emailProtection, nor codeSigning, nor anyExtendedKeyUsage, "
+ "nor 'Adobe Authentic Documents Trust'");
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy