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 2018/10/16 15:51:27 UTC

svn commit: r1844025 - in /pdfbox/trunk/examples/src/main/java/org/apache/pdfbox/examples/signature/cert: CRLVerifier.java CertificateVerifier.java

Author: tilman
Date: Tue Oct 16 15:51:26 2018
New Revision: 1844025

URL: http://svn.apache.org/viewvc?rev=1844025&view=rev
Log:
PDFBOX-3017: verify CRL against certificate; use signing date when verifying the certification chain

Modified:
    pdfbox/trunk/examples/src/main/java/org/apache/pdfbox/examples/signature/cert/CRLVerifier.java
    pdfbox/trunk/examples/src/main/java/org/apache/pdfbox/examples/signature/cert/CertificateVerifier.java

Modified: pdfbox/trunk/examples/src/main/java/org/apache/pdfbox/examples/signature/cert/CRLVerifier.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/examples/src/main/java/org/apache/pdfbox/examples/signature/cert/CRLVerifier.java?rev=1844025&r1=1844024&r2=1844025&view=diff
==============================================================================
--- pdfbox/trunk/examples/src/main/java/org/apache/pdfbox/examples/signature/cert/CRLVerifier.java (original)
+++ pdfbox/trunk/examples/src/main/java/org/apache/pdfbox/examples/signature/cert/CRLVerifier.java Tue Oct 16 15:51:26 2018
@@ -23,6 +23,7 @@ import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.URL;
+import java.security.PublicKey;
 import java.security.cert.CRLException;
 import java.security.cert.CertificateException;
 import java.security.cert.CertificateFactory;
@@ -33,6 +34,7 @@ import java.util.ArrayList;
 import java.util.Date;
 import java.util.Hashtable;
 import java.util.List;
+import java.util.Set;
 
 import javax.naming.Context;
 import javax.naming.NamingException;
@@ -74,9 +76,13 @@ public final class CRLVerifier
      *
      * @param cert the certificate to be checked for revocation
      * @param signDate the date when the signing took place
+     * @param additionalCerts set of trusted root CA certificates that will be
+     * used as "trust anchors" and intermediate CA certificates that will be
+     * used as part of the certification chain.
      * @throws CertificateVerificationException if the certificate is revoked
      */
-    public static void verifyCertificateCRLs(X509Certificate cert, Date signDate)
+    public static void verifyCertificateCRLs(X509Certificate cert, Date signDate,
+            Set<X509Certificate> additionalCerts)
             throws CertificateVerificationException
     {
         try
@@ -86,9 +92,27 @@ public final class CRLVerifier
             {
                 LOG.info("Checking distribution point URL: " + crlDistributionPointsURL);
                 X509CRL crl = downloadCRL(crlDistributionPointsURL);
-                //TODO verify CRL, see wikipedia:
+
+                // Verify CRL, see wikipedia:
                 // "To validate a specific CRL prior to relying on it,
                 //  the certificate of its corresponding CA is needed"
+                PublicKey issuerKey = null;
+                for (X509Certificate additionalCert : additionalCerts)
+                {
+                    if (crl.getIssuerX500Principal().equals(
+                            additionalCert.getSubjectX500Principal()))
+                    {
+                        issuerKey = additionalCert.getPublicKey();
+                    }
+                }
+                if (issuerKey == null)
+                {
+                    throw new CertificateVerificationException(
+                            "Certificate for " + crl.getIssuerX500Principal() +
+                            "not found in certificate chain, so the CRL at " +
+                            crlDistributionPointsURL + " could not be verified");
+                }
+                crl.verify(issuerKey);
                 X509CRLEntry revokedCRLEntry = crl.getRevokedCertificate(cert);
                 if (revokedCRLEntry != null &&
                     revokedCRLEntry.getRevocationDate().compareTo(signDate) <= 0)

Modified: pdfbox/trunk/examples/src/main/java/org/apache/pdfbox/examples/signature/cert/CertificateVerifier.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/examples/src/main/java/org/apache/pdfbox/examples/signature/cert/CertificateVerifier.java?rev=1844025&r1=1844024&r2=1844025&view=diff
==============================================================================
--- pdfbox/trunk/examples/src/main/java/org/apache/pdfbox/examples/signature/cert/CertificateVerifier.java (original)
+++ pdfbox/trunk/examples/src/main/java/org/apache/pdfbox/examples/signature/cert/CertificateVerifier.java Tue Oct 16 15:51:26 2018
@@ -105,11 +105,11 @@ public final class CertificateVerifier
 
             // Attempt to build the certification chain and verify it
             PKIXCertPathBuilderResult verifiedCertChain = verifyCertificate(
-                    cert, trustedRootCerts, intermediateCerts);
+                    cert, trustedRootCerts, intermediateCerts, signDate);
 
             // Check whether the certificate is revoked by the CRL
             // given in its CRL distribution point extension
-            CRLVerifier.verifyCertificateCRLs(cert, signDate);
+            CRLVerifier.verifyCertificateCRLs(cert, signDate, additionalCerts);
 
             // The chain is built and verified. Return it as a result
             return verifiedCertChain;
@@ -163,6 +163,7 @@ public final class CertificateVerifier
      * @param cert - certificate for validation
      * @param trustedRootCerts - set of trusted root CA certificates
      * @param intermediateCerts - set of intermediate certificates
+     * @param signDate the date when the signing took place
      * @return the certification chain (if verification is successful)
      * @throws GeneralSecurityException - if the verification is not successful
      * (e.g. certification path cannot be built or some certificate in the chain
@@ -170,9 +171,9 @@ public final class CertificateVerifier
      */
     private static PKIXCertPathBuilderResult verifyCertificate(
             X509Certificate cert, Set<X509Certificate> trustedRootCerts,
-            Set<X509Certificate> intermediateCerts) throws GeneralSecurityException
+            Set<X509Certificate> intermediateCerts, Date signDate)
+            throws GeneralSecurityException
     {
-
         // Create the selector that specifies the starting certificate
         X509CertSelector selector = new X509CertSelector();
         selector.setCertificate(cert);
@@ -190,12 +191,18 @@ public final class CertificateVerifier
         // Disable CRL checks (this is done manually as additional step)
         pkixParams.setRevocationEnabled(false);
 
+        pkixParams.setDate(signDate);
+
         // Specify a list of intermediate certificates
         CertStore intermediateCertStore = CertStore.getInstance("Collection",
                 new CollectionCertStoreParameters(intermediateCerts));
         pkixParams.addCertStore(intermediateCertStore);
 
         // Build and verify the certification chain
+        // If this doesn't work although it should, it can be debugged
+        // by starting java with -Djava.security.debug=certpath
+        // see also
+        // https://docs.oracle.com/javase/8/docs/technotes/guides/security/troubleshooting-security.html
         CertPathBuilder builder = CertPathBuilder.getInstance("PKIX");
         return (PKIXCertPathBuilderResult) builder.build(pkixParams);
     }