pdfbox-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From til...@apache.org
Subject svn commit: r1848831 - /pdfbox/branches/2.0/examples/src/main/java/org/apache/pdfbox/examples/signature/validation/AddValidationInformation.java
Date Thu, 13 Dec 2018 09:03:02 GMT
Author: tilman
Date: Thu Dec 13 09:03:02 2018
New Revision: 1848831

URL: http://svn.apache.org/viewvc?rev=1848831&view=rev
Log:
PDFBOX-3017: include VRI for CSRL and OCSP signatures, as suggested by mkl

Modified:
    pdfbox/branches/2.0/examples/src/main/java/org/apache/pdfbox/examples/signature/validation/AddValidationInformation.java

Modified: pdfbox/branches/2.0/examples/src/main/java/org/apache/pdfbox/examples/signature/validation/AddValidationInformation.java
URL: http://svn.apache.org/viewvc/pdfbox/branches/2.0/examples/src/main/java/org/apache/pdfbox/examples/signature/validation/AddValidationInformation.java?rev=1848831&r1=1848830&r2=1848831&view=diff
==============================================================================
--- pdfbox/branches/2.0/examples/src/main/java/org/apache/pdfbox/examples/signature/validation/AddValidationInformation.java
(original)
+++ pdfbox/branches/2.0/examples/src/main/java/org/apache/pdfbox/examples/signature/validation/AddValidationInformation.java
Thu Dec 13 09:03:02 2018
@@ -24,6 +24,8 @@ import java.io.IOException;
 import java.io.OutputStream;
 import java.math.BigInteger;
 import java.security.GeneralSecurityException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
 import java.security.Security;
 import java.security.cert.CertificateEncodingException;
 import java.security.cert.X509CRL;
@@ -51,6 +53,8 @@ import org.apache.pdfbox.pdmodel.PDDocum
 import org.apache.pdfbox.pdmodel.PDDocumentCatalog;
 import org.apache.pdfbox.pdmodel.encryption.SecurityProvider;
 import org.apache.pdfbox.pdmodel.interactive.digitalsignature.PDSignature;
+import org.apache.pdfbox.util.Hex;
+import org.bouncycastle.asn1.ocsp.OCSPObjectIdentifiers;
 import org.bouncycastle.cert.ocsp.BasicOCSPResp;
 import org.bouncycastle.cert.ocsp.OCSPException;
 import org.bouncycastle.cert.ocsp.OCSPResp;
@@ -215,24 +219,7 @@ public class AddValidationInformation
         COSDictionary vri = new COSDictionary();
         vriBase.setItem(certInfo.getSignatureHash(), vri);
 
-        correspondingOCSPs = new COSArray();
-        correspondingCRLs = new COSArray();
-
-        addRevocationDataRecursive(certInfo);
-
-        //TODO this will have to be rewritten differently, because it is wrong to take the
whole
-        // list object for the OCSP / CRL entries. Each VRI must have its own.
-
-        if (correspondingOCSPs.size() > 0)
-        {
-            vri.setItem("OCSP", correspondingOCSPs);
-        }
-        if (correspondingCRLs.size() > 0)
-        {
-            vri.setItem("CRL", correspondingCRLs);
-        }
-
-        vri.setDate(COSName.TU, Calendar.getInstance());
+        updateVRI(certInfo, vri);
 
         if (certInfo.getTsaCerts() != null)
         {
@@ -381,13 +368,49 @@ public class AddValidationInformation
                 certInfo.getIssuerCertificate(),
                 new HashSet<X509Certificate>(certInformationHelper.getCertificatesMap().values()),
                 certInfo.getOcspUrl());
-
         OCSPResp ocspResp = ocspHelper.getResponseOcsp();
         BasicOCSPResp basicResponse = (BasicOCSPResp) ocspResp.getResponseObject();
+        X509Certificate ocspResponderCertificate = ocspHelper.getOcspResponderCertificate();
         certInformationHelper.addAllCertsFromHolders(basicResponse.getCerts());
-        
-        //TODO check revocation of responder + include in separate VRI (usually not needed).

-        // See comment by mkl in PDFBOX-3017 on 21.11.2018
+        byte[] signatureHash;
+        try
+        {
+            signatureHash = MessageDigest.getInstance("SHA-1").digest(basicResponse.getSignature());
+        }
+        catch (NoSuchAlgorithmException ex)
+        {
+            throw new CertificateProccessingException(ex);
+        }
+        String signatureHashHex = Hex.getString(signatureHash);
+
+        if (!vriBase.containsKey(signatureHashHex))
+        {
+            COSArray savedCorrespondingOCSPs = correspondingOCSPs;
+            COSArray savedCorrespondingCRLs = correspondingCRLs;
+
+            COSDictionary vri = new COSDictionary();
+            vriBase.setItem(signatureHashHex, vri);
+            if (ocspResponderCertificate.getExtensionValue(OCSPObjectIdentifiers.id_pkix_ocsp_nocheck.getId())
== null)
+            {
+                CertSignatureInformation ocspCertInfo = certInformationHelper.getCertInfo(ocspResponderCertificate);
+
+                updateVRI(ocspCertInfo, vri);
+            }
+            COSArray correspondingCerts = new COSArray();
+            try
+            {
+                COSStream certStream = writeDataToStream(ocspResponderCertificate.getEncoded());
+                correspondingCerts.add(certStream);
+                certs.add(certStream);
+                vri.setItem(COSName.CERT, correspondingCerts);
+            }
+            catch (CertificateEncodingException ex)
+            {
+                throw new CertificateProccessingException(ex);
+            }
+            correspondingOCSPs = savedCorrespondingOCSPs;
+            correspondingCRLs = savedCorrespondingCRLs;
+        }
 
         byte[] ocspData = ocspResp.getEncoded();
 
@@ -414,17 +437,91 @@ public class AddValidationInformation
             CertificateVerificationException
     {
         X509CRL crl = CRLVerifier.downloadCRLFromWeb(certInfo.getCrlUrl());
-        crl.verify(certInfo.getIssuerCertificate().getPublicKey(), SecurityProvider.getProvider().getName());
+        X509Certificate issuerCertificate = certInfo.getIssuerCertificate();
+
+        // find the issuer certificate (usually issuer of signature certificate)
+        for (X509Certificate certificate : certInformationHelper.getCertificatesMap().values())
+        {
+            if (certificate.getSubjectX500Principal().equals(crl.getIssuerX500Principal()))
+            {
+                issuerCertificate = certificate;
+                break;
+            }
+        }
+        crl.verify(issuerCertificate.getPublicKey(), SecurityProvider.getProvider().getName());
         CRLVerifier.checkRevocation(crl, certInfo.getCertificate(), signDate.getTime(), certInfo.getCrlUrl());
         COSStream crlStream = writeDataToStream(crl.getEncoded());
         crls.add(crlStream);
         if (correspondingCRLs != null)
         {
             correspondingCRLs.add(crlStream);
+
+            byte[] signatureHash;
+            try
+            {
+                signatureHash = MessageDigest.getInstance("SHA-1").digest(crl.getSignature());
+            }
+            catch (NoSuchAlgorithmException ex)
+            {
+                throw new CertificateVerificationException(ex.getMessage(), ex);
+            }
+            String signatureHashHex = Hex.getString(signatureHash);
+
+            if (!vriBase.containsKey(signatureHashHex))
+            {
+                COSArray savedCorrespondingOCSPs = correspondingOCSPs;
+                COSArray savedCorrespondingCRLs = correspondingCRLs;
+
+                COSDictionary vri = new COSDictionary();
+                vriBase.setItem(signatureHashHex, vri);
+
+                CertSignatureInformation crlCertInfo;
+                try
+                {
+                    crlCertInfo = certInformationHelper.getCertInfo(issuerCertificate);
+                }
+                catch (CertificateProccessingException ex)
+                {
+                    throw new CertificateVerificationException(ex.getMessage(), ex);
+                }
+
+                updateVRI(crlCertInfo, vri);
+
+                COSArray correspondingCerts = new COSArray();
+                try
+                {
+                    COSStream certStream = writeDataToStream(issuerCertificate.getEncoded());
+                    correspondingCerts.add(certStream);
+                    certs.add(certStream);
+                    vri.setItem(COSName.CERT, correspondingCerts);
+                }
+                catch (CertificateEncodingException ex)
+                {
+                    throw new CertificateVerificationException(ex.getMessage(), ex);
+                }
+                correspondingOCSPs = savedCorrespondingOCSPs;
+                correspondingCRLs = savedCorrespondingCRLs;
+            }
         }
         foundRevocationInformation.add(certInfo.getCertificate().getSerialNumber());
     }
 
+    private void updateVRI(CertSignatureInformation certInfo, COSDictionary vri) throws IOException
+    {
+        correspondingOCSPs = new COSArray();
+        correspondingCRLs = new COSArray();
+        addRevocationDataRecursive(certInfo);
+        if (correspondingOCSPs.size() > 0)
+        {
+            vri.setItem("OCSP", correspondingOCSPs);
+        }
+        if (correspondingCRLs.size() > 0)
+        {
+            vri.setItem("CRL", correspondingCRLs);
+        }
+        vri.setDate(COSName.TU, Calendar.getInstance());
+    }
+
     /**
      * Adds all certs to the certs-array. Make sure, all certificates are inside the
      * certificateStore of certInformationHelper



Mime
View raw message