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 2017/06/07 15:40:36 UTC
svn commit: r1797951 -
/pdfbox/branches/2.0/examples/src/main/java/org/apache/pdfbox/examples/signature/ShowSignature.java
Author: tilman
Date: Wed Jun 7 15:40:36 2017
New Revision: 1797951
URL: http://svn.apache.org/viewvc?rev=1797951&view=rev
Log:
PDFBOX-3017: detect self-signed certs, tell whether signature covers the whole file, slight refactor
Modified:
pdfbox/branches/2.0/examples/src/main/java/org/apache/pdfbox/examples/signature/ShowSignature.java
Modified: pdfbox/branches/2.0/examples/src/main/java/org/apache/pdfbox/examples/signature/ShowSignature.java
URL: http://svn.apache.org/viewvc/pdfbox/branches/2.0/examples/src/main/java/org/apache/pdfbox/examples/signature/ShowSignature.java?rev=1797951&r1=1797950&r2=1797951&view=diff
==============================================================================
--- pdfbox/branches/2.0/examples/src/main/java/org/apache/pdfbox/examples/signature/ShowSignature.java (original)
+++ pdfbox/branches/2.0/examples/src/main/java/org/apache/pdfbox/examples/signature/ShowSignature.java Wed Jun 7 15:40:36 2017
@@ -24,6 +24,7 @@ import java.security.InvalidKeyException
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
+import java.security.PublicKey;
import java.security.SignatureException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
@@ -93,11 +94,11 @@ public final class ShowSignature
else
{
String password = args[0];
- String infile = args[1];
+ File infile = new File(args[1]);
PDDocument document = null;
try
{
- document = PDDocument.load(new File(infile), password);
+ document = PDDocument.load(infile, password);
for (PDSignature sig : document.getSignatureDictionaries())
{
COSDictionary sigDict = sig.getCOSObject();
@@ -116,6 +117,29 @@ public final class ShowSignature
}
System.out.println("Signature found");
+
+ int[] byteRange = sig.getByteRange();
+ if (byteRange.length != 4)
+ {
+ System.err.println("Signature byteRange must have 4 items");
+ }
+ else
+ {
+ long fileLen = infile.length();
+ long rangeMax = byteRange[2] + byteRange[3];
+ // multiply content length with 2 (because it is in hex in the PDF) and add 2 for < and >
+ long contentLen = sigDict.getString(COSName.CONTENTS).length() * 2 + 2;
+ if (fileLen != rangeMax || byteRange[0] != 0 || byteRange[1] + contentLen != byteRange[2])
+ {
+ // a false result doesn't necessarily mean that the PDF is a fake
+ System.out.println("Signature does not cover whole document");
+ }
+ else
+ {
+ System.out.println("Signature covers whole document");
+ }
+ }
+
System.out.println("Name: " + sig.getName());
System.out.println("Modified: " + sdf.format(sig.getSignDate().getTime()));
String subFilter = sig.getSubFilter();
@@ -197,7 +221,8 @@ public final class ShowSignature
* @throws OperatorCreationException
*/
private void verifyPKCS7(byte[] byteArray, COSString contents, PDSignature sig)
- throws CMSException, CertificateException, StoreException, OperatorCreationException
+ throws CMSException, CertificateException, StoreException, OperatorCreationException,
+ NoSuchAlgorithmException, NoSuchProviderException
{
// inspiration:
// http://stackoverflow.com/a/26702631/535646
@@ -212,7 +237,17 @@ public final class ShowSignature
X509Certificate certFromSignedData = new JcaX509CertificateConverter().getCertificate(certificateHolder);
System.out.println("certFromSignedData: " + certFromSignedData);
certFromSignedData.checkValidity(sig.getSignDate().getTime());
-
+
+ if (isSelfSigned(certFromSignedData))
+ {
+ System.err.println("Certificate is self-signed, LOL!");
+ }
+ else
+ {
+ System.out.println("Certificate is not self-signed");
+ // todo rest of chain
+ }
+
if (signerInformation.verify(new JcaSimpleSignerInfoVerifierBuilder().build(certFromSignedData)))
{
System.out.println("Signature verified");
@@ -223,6 +258,31 @@ public final class ShowSignature
}
}
+ // https://svn.apache.org/repos/asf/cxf/tags/cxf-2.4.1/distribution/src/main/release/samples/sts_issue_operation/src/main/java/demo/sts/provider/cert/CertificateVerifier.java
+
+ /**
+ * Checks whether given X.509 certificate is self-signed.
+ */
+ private boolean isSelfSigned(X509Certificate cert)
+ throws CertificateException, NoSuchAlgorithmException, NoSuchProviderException
+ {
+ try
+ {
+ // Try to verify certificate signature with its own public key
+ PublicKey key = cert.getPublicKey();
+ cert.verify(key);
+ return true;
+ }
+ catch (SignatureException sigEx)
+ {
+ return false;
+ }
+ catch (InvalidKeyException keyEx)
+ {
+ return false;
+ }
+ }
+
/**
* This will print a usage message.
*/