Return-Path: X-Original-To: archive-asf-public-internal@cust-asf2.ponee.io Delivered-To: archive-asf-public-internal@cust-asf2.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by cust-asf2.ponee.io (Postfix) with ESMTP id C9E7E200AC8 for ; Tue, 7 Jun 2016 22:30:48 +0200 (CEST) Received: by cust-asf.ponee.io (Postfix) id C859B160A36; Tue, 7 Jun 2016 20:30:48 +0000 (UTC) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id E9804160968 for ; Tue, 7 Jun 2016 22:30:47 +0200 (CEST) Received: (qmail 22998 invoked by uid 500); 7 Jun 2016 20:30:47 -0000 Mailing-List: contact commits-help@pdfbox.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@pdfbox.apache.org Delivered-To: mailing list commits@pdfbox.apache.org Received: (qmail 22985 invoked by uid 99); 7 Jun 2016 20:30:47 -0000 Received: from pnap-us-west-generic-nat.apache.org (HELO spamd4-us-west.apache.org) (209.188.14.142) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 07 Jun 2016 20:30:47 +0000 Received: from localhost (localhost [127.0.0.1]) by spamd4-us-west.apache.org (ASF Mail Server at spamd4-us-west.apache.org) with ESMTP id 9BD97C0D08 for ; Tue, 7 Jun 2016 20:30:46 +0000 (UTC) X-Virus-Scanned: Debian amavisd-new at spamd4-us-west.apache.org X-Spam-Flag: NO X-Spam-Score: -0.426 X-Spam-Level: X-Spam-Status: No, score=-0.426 tagged_above=-999 required=6.31 tests=[KAM_LAZY_DOMAIN_SECURITY=1, RP_MATCHES_RCVD=-1.426] autolearn=disabled Received: from mx1-lw-us.apache.org ([10.40.0.8]) by localhost (spamd4-us-west.apache.org [10.40.0.11]) (amavisd-new, port 10024) with ESMTP id kImO5BPcM3xk for ; Tue, 7 Jun 2016 20:30:44 +0000 (UTC) Received: from mailrelay1-us-west.apache.org (mailrelay1-us-west.apache.org [209.188.14.139]) by mx1-lw-us.apache.org (ASF Mail Server at mx1-lw-us.apache.org) with ESMTP id 9AC9D5FD03 for ; Tue, 7 Jun 2016 20:30:44 +0000 (UTC) Received: from svn01-us-west.apache.org (svn.apache.org [10.41.0.6]) by mailrelay1-us-west.apache.org (ASF Mail Server at mailrelay1-us-west.apache.org) with ESMTP id 8E577E0290 for ; Tue, 7 Jun 2016 20:30:43 +0000 (UTC) Received: from svn01-us-west.apache.org (localhost [127.0.0.1]) by svn01-us-west.apache.org (ASF Mail Server at svn01-us-west.apache.org) with ESMTP id AAEB93A0336 for ; Tue, 7 Jun 2016 20:30:42 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1747314 - /pdfbox/trunk/examples/src/main/java/org/apache/pdfbox/examples/signature/ShowSignature.java Date: Tue, 07 Jun 2016 20:30:42 -0000 To: commits@pdfbox.apache.org From: tilman@apache.org X-Mailer: svnmailer-1.0.9 Message-Id: <20160607203042.AAEB93A0336@svn01-us-west.apache.org> archived-at: Tue, 07 Jun 2016 20:30:49 -0000 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 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 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 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 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. */