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:40 UTC
svn commit: r1797952 -
/pdfbox/trunk/examples/src/main/java/org/apache/pdfbox/examples/signature/ShowSignature.java
Author: tilman
Date: Wed Jun 7 15:40:40 2017
New Revision: 1797952
URL: http://svn.apache.org/viewvc?rev=1797952&view=rev
Log:
PDFBOX-3017: detect self-signed certs, tell whether signature covers the whole file, slight refactor
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=1797952&r1=1797951&r2=1797952&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 Wed Jun 7 15:40:40 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,8 +94,8 @@ public final class ShowSignature
else
{
String password = args[0];
- String infile = args[1];
- try (PDDocument document = PDDocument.load(new File(infile), password))
+ File infile = new File(args[1]);
+ try (PDDocument document = PDDocument.load(infile, password))
{
for (PDSignature sig : document.getSignatureDictionaries())
{
@@ -102,18 +103,36 @@ public final class ShowSignature
COSString contents = (COSString) sigDict.getDictionaryObject(COSName.CONTENTS);
// download the signed content
- FileInputStream fis = new FileInputStream(infile);
- byte[] buf = null;
- try
+ byte[] buf;
+ try (FileInputStream fis = new FileInputStream(infile))
{
buf = sig.getSignedContent(fis);
}
- finally
+
+ System.out.println("Signature found");
+
+ int[] byteRange = sig.getByteRange();
+ if (byteRange.length != 4)
{
- fis.close();
+ 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("Signature found");
System.out.println("Name: " + sig.getName());
System.out.println("Modified: " + sdf.format(sig.getSignDate().getTime()));
String subFilter = sig.getSubFilter();
@@ -186,7 +205,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
@@ -202,6 +222,16 @@ public final class ShowSignature
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");
@@ -212,6 +242,27 @@ 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 | InvalidKeyException sigEx)
+ {
+ return false;
+ }
+ }
+
/**
* This will print a usage message.
*/