You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pdfbox.apache.org by ti...@apache.org on 2016/06/07 20:30:42 UTC

svn commit: r1747314 - /pdfbox/trunk/examples/src/main/java/org/apache/pdfbox/examples/signature/ShowSignature.java

Author: tilman
Date: Tue Jun  7 20:30:42 2016
New Revision: 1747314

URL: http://svn.apache.org/viewvc?rev=1747314&view=rev
Log:
PDFBOX-3017: add simple verify for adbe.pkcs7.sha1 signatures

Modified:
    pdfbox/trunk/examples/src/main/java/org/apache/pdfbox/examples/signature/ShowSignature.java

Modified: pdfbox/trunk/examples/src/main/java/org/apache/pdfbox/examples/signature/ShowSignature.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/examples/src/main/java/org/apache/pdfbox/examples/signature/ShowSignature.java?rev=1747314&r1=1747313&r2=1747314&view=diff
==============================================================================
--- pdfbox/trunk/examples/src/main/java/org/apache/pdfbox/examples/signature/ShowSignature.java (original)
+++ pdfbox/trunk/examples/src/main/java/org/apache/pdfbox/examples/signature/ShowSignature.java Tue Jun  7 20:30:42 2016
@@ -21,12 +21,15 @@ import java.io.File;
 import java.io.IOException;
 import java.io.RandomAccessFile;
 import java.security.InvalidKeyException;
+import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
 import java.security.NoSuchProviderException;
 import java.security.SignatureException;
 import java.security.cert.Certificate;
 import java.security.cert.CertificateException;
+import java.security.cert.CertificateExpiredException;
 import java.security.cert.CertificateFactory;
+import java.security.cert.CertificateNotYetValidException;
 import java.security.cert.X509Certificate;
 import java.text.SimpleDateFormat;
 import java.util.Collection;
@@ -46,6 +49,7 @@ import org.bouncycastle.cms.SignerInform
 import org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoVerifierBuilder;
 import org.bouncycastle.operator.OperatorCreationException;
 import org.bouncycastle.util.Store;
+import org.bouncycastle.util.StoreException;
 
 /**
  * This will read a document from the filesystem, decrypt it and do something with the signature.
@@ -84,6 +88,8 @@ public final class ShowSignature
                                                      NoSuchAlgorithmException, InvalidKeyException,
                                                      NoSuchProviderException, SignatureException
     {
+        args = new String[]{"","C:\\Users\\Tilman Hausherr\\Documents\\Java\\PDFBoxPageImageExtraction\\annotations2_signed.pdf"};
+        args = new String[]{"","C:\\Users\\Tilman Hausherr\\Documents\\Java\\PDFBox reactor\\pdfbox\\src\\test\\resources\\input\\rendering\\PDFBOX-1452.pdf"};
         if( args.length != 2 )
         {
             usage();
@@ -120,57 +126,37 @@ public final class ShowSignature
                     {
                         if (subFilter.equals("adbe.pkcs7.detached"))
                         {
-                            CMSProcessable signedContent = new CMSProcessableByteArray(buf);
-
-                            // inspiration:
-                            // http://stackoverflow.com/a/26702631/535646
-                            // http://stackoverflow.com/a/9261365/535646
-                            CMSSignedData signedData = new CMSSignedData(signedContent, contents.getBytes());
-                            Store certificatesStore = signedData.getCertificates();
-                            Collection<SignerInformation> signers = signedData.getSignerInfos().getSigners();
-                            SignerInformation signerInformation = signers.iterator().next();
-                            Collection matches = certificatesStore.getMatches(signerInformation.getSID());
-                            X509CertificateHolder certificateHolder = (X509CertificateHolder) matches.iterator().next();
-                            X509Certificate certFromSignedData = new JcaX509CertificateConverter().getCertificate(certificateHolder);
-                            System.out.println("certFromSignedData: " + certFromSignedData);
-                            certFromSignedData.checkValidity(sig.getSignDate().getTime());
-
-                            // CMSVerifierCertificateNotValidException means that the keystore wasn't valid at signing time
-                            if (signerInformation.verify(new JcaSimpleSignerInfoVerifierBuilder().build(certFromSignedData)))
-                            {
-                                System.out.println("Signature verified");
-                            }
-                            else
-                            {
-                                System.out.println("Signature verification failed");
-                            }
+                            verifyPKCS7(buf, contents, sig);
                             
                             //TODO check certificate chain, revocation lists, timestamp...
                         }
-                        else if (subFilter.equals("adbe.x509.rsa_sha1"))
+                        else if (subFilter.equals("adbe.pkcs7.sha1"))
                         {
-                            // PDFBOX-2693.pdf
+                            // example: PDFBOX-1452.pdf
                             COSString certString = (COSString) sigDict.getDictionaryObject(
-                                    COSName.getPDFName("Cert"));
+                                    COSName.CONTENTS);
                             byte[] certData = certString.getBytes();
                             CertificateFactory factory = CertificateFactory.getInstance("X.509");
                             ByteArrayInputStream certStream = new ByteArrayInputStream(certData);
                             Collection<? extends Certificate> certs = factory.generateCertificates(certStream);
                             System.out.println("certs=" + certs);
+
+                            byte[] hash = MessageDigest.getInstance("SHA1").digest(buf);
+                            verifyPKCS7(hash, contents, sig);
                             
-                            //TODO verify signature
+                            //TODO check certificate chain, revocation lists, timestamp...
                         }
-                        else if (subFilter.equals("adbe.pkcs7.sha1"))
+                        else if (subFilter.equals("adbe.x509.rsa_sha1"))
                         {
-                            // PDFBOX-1452.pdf
+                            // example: PDFBOX-2693.pdf
                             COSString certString = (COSString) sigDict.getDictionaryObject(
-                                    COSName.CONTENTS);
+                                    COSName.getPDFName("Cert"));
                             byte[] certData = certString.getBytes();
                             CertificateFactory factory = CertificateFactory.getInstance("X.509");
                             ByteArrayInputStream certStream = new ByteArrayInputStream(certData);
                             Collection<? extends Certificate> certs = factory.generateCertificates(certStream);
                             System.out.println("certs=" + certs);
-
+                            
                             //TODO verify signature
                         }
                         else
@@ -202,6 +188,44 @@ public final class ShowSignature
         }
     }
 
+    /**
+     * Verify a PKCS7 signature.
+     *
+     * @param byteArray the byte sequence that has been signed
+     * @param contents the /Contents field as a COSString
+     * @param sig the PDF signature (the /V dictionary)
+     * @throws CertificateException
+     * @throws CMSException
+     * @throws StoreException
+     * @throws OperatorCreationException
+     */
+    private void verifyPKCS7(byte[] byteArray, COSString contents, PDSignature sig)
+            throws CMSException, CertificateException, StoreException, OperatorCreationException
+    {
+        // inspiration:
+        // http://stackoverflow.com/a/26702631/535646
+        // http://stackoverflow.com/a/9261365/535646
+        CMSProcessable signedContent = new CMSProcessableByteArray(byteArray);
+        CMSSignedData signedData = new CMSSignedData(signedContent, contents.getBytes());
+        Store certificatesStore = signedData.getCertificates();
+        Collection<SignerInformation> signers = signedData.getSignerInfos().getSigners();
+        SignerInformation signerInformation = signers.iterator().next();
+        Collection matches = certificatesStore.getMatches(signerInformation.getSID());
+        X509CertificateHolder certificateHolder = (X509CertificateHolder) matches.iterator().next();
+        X509Certificate certFromSignedData = new JcaX509CertificateConverter().getCertificate(certificateHolder);
+        System.out.println("certFromSignedData: " + certFromSignedData);
+        certFromSignedData.checkValidity(sig.getSignDate().getTime());
+        
+        if (signerInformation.verify(new JcaSimpleSignerInfoVerifierBuilder().build(certFromSignedData)))
+        {
+            System.out.println("Signature verified");
+        }
+        else
+        {
+            System.out.println("Signature verification failed");
+        }
+    }
+
     /**
      * This will print a usage message.
      */