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/21 06:49:55 UTC

svn commit: r1844462 - in /pdfbox/trunk/examples/src/main/java/org/apache/pdfbox/examples/signature: CreateSignatureBase.java SigUtils.java

Author: tilman
Date: Sun Oct 21 06:49:55 2018
New Revision: 1844462

URL: http://svn.apache.org/viewvc?rev=1844462&view=rev
Log:
PDFBOX-3017: check key usage when signing

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

Modified: pdfbox/trunk/examples/src/main/java/org/apache/pdfbox/examples/signature/CreateSignatureBase.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/examples/src/main/java/org/apache/pdfbox/examples/signature/CreateSignatureBase.java?rev=1844462&r1=1844461&r2=1844462&view=diff
==============================================================================
--- pdfbox/trunk/examples/src/main/java/org/apache/pdfbox/examples/signature/CreateSignatureBase.java (original)
+++ pdfbox/trunk/examples/src/main/java/org/apache/pdfbox/examples/signature/CreateSignatureBase.java Sun Oct 21 06:49:55 2018
@@ -84,6 +84,8 @@ public abstract class CreateSignatureBas
             {
                 // avoid expired certificate
                 ((X509Certificate) cert).checkValidity();
+                
+                SigUtils.checkCertificateUsage((X509Certificate) cert);
             }
             break;
         }

Modified: pdfbox/trunk/examples/src/main/java/org/apache/pdfbox/examples/signature/SigUtils.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/examples/src/main/java/org/apache/pdfbox/examples/signature/SigUtils.java?rev=1844462&r1=1844461&r2=1844462&view=diff
==============================================================================
--- pdfbox/trunk/examples/src/main/java/org/apache/pdfbox/examples/signature/SigUtils.java (original)
+++ pdfbox/trunk/examples/src/main/java/org/apache/pdfbox/examples/signature/SigUtils.java Sun Oct 21 06:49:55 2018
@@ -16,12 +16,18 @@
 
 package org.apache.pdfbox.examples.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.
@@ -30,6 +36,8 @@ import org.apache.pdfbox.pdmodel.interac
  */
 public class SigUtils
 {
+    private static final Log LOG = LogFactory.getLog(SigUtils.class);
+
     private SigUtils()
     {
     }
@@ -126,4 +134,40 @@ public class SigUtils
         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 
+     */
+    public static void checkCertificateUsage(X509Certificate x509Certificate)
+            throws CertificateParsingException
+    {
+        // Check whether signer certificate is "valid for usage"
+        // https://stackoverflow.com/a/52765021/535646
+        // https://www.adobe.com/devnet-docs/acrobatetk/tools/DigSig/changes.html#id1
+        boolean[] keyUsage = x509Certificate.getKeyUsage();
+        if (keyUsage != null && !keyUsage[0] && !keyUsage[1])
+        {
+            // (unclear what "signTransaction" is)
+            // https://tools.ietf.org/html/rfc5280#section-4.2.1.3
+            LOG.error("Certificate key usage does not include " +
+                    "digitalSignature nor nonRepudiation");
+        }
+        List<String> 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") &&
+            // not mentioned in Adobe document, but tolerated in practice
+            !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'");
+        }
+    }
 }