1
votes

I've been working with iText to do digital signatures on PDF files for the past weeks and based on what i've understood that there is two ways to add the information to the PDF to make it LTV enabled:

  • Adding the information with the code provided in the iText example, this method requires the signature to be already present because the DSS & VRI dictionaries it creates references the signature.

  • Embedding the crl bytes & ocsp response in the signature at signing time.

Eventhough the first method results in a nice and tidy pdf file the problem with is is that it modifies the pdf file to create/append the entries which results in an invalidation of the certifying signature, the second one works fine but it increases the pdf size substantially depending on the size of the crl list (that will also probably increase overtime).

Wrapping up, is there any other way to make the certifying signature LTV enabled other than embedding the information in the signature itself? Is there any way to create the dds/vri dictionaries at signing time?

EDIT: Here's more info as requested on the comments:

The code used to add the ltv information:

    public static void processDocumentLtv(String filePath) throws IOException, GeneralSecurityException, DocumentException {

    long startTime = System.currentTimeMillis();

    File original = new File(filePath);
    File temp = new File(filePath + ".ltv");

    PdfReader reader = new PdfReader(filePath);
    PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(temp), '\0', true);

    LtvVerification ltvVerification = stamper.getLtvVerification();
    OcspClient ocspClient = new OcspClientBouncyCastle();
    AcroFields fields = stamper.getAcroFields();
    List<String> signatureNames = fields.getSignatureNames();
    String sigName = signatureNames.get(signatureNames.size() - 1);
    PdfPKCS7 pkcs7 = fields.verifySignature(sigName);
    Certificate[] chain = pkcs7.getSignCertificateChain();
    X509Certificate x509certificate = pkcs7.getSigningCertificate();

    byte[] ocspResponse = ocspClient.getEncoded(x509certificate, CertificateUtils.getParent(x509certificate, chain), null);
    Collection<byte[]> crlBytes = CertificateUtils.fetchCrlBytes(x509certificate, chain);
    Collection<byte[]> ocspBytes = null;

    if (ocspResponse != null) {
        ocspBytes = new ArrayList<>();
        ocspBytes.add(ocspResponse);
    }

    ltvVerification.addVerification(sigName, ocspBytes, crlBytes, null);

    ltvVerification.merge();

    stamper.close();
    reader.close();

    Files.copy(temp.toPath(), original.toPath(), StandardCopyOption.REPLACE_EXISTING);
    temp.delete();

    logger.info("Took {}ms to do add the ltv information to the document.", (System.currentTimeMillis() - startTime));
}

The document samples: Before trying to add LTV data: https://www.dropbox.com/s/79ll23ndt9mbh3g/pdf-sample-pre-ltv.pdf?dl=0

After running through the code above: https://www.dropbox.com/s/hjl73es6hrqspi3/pdf-sample-post-ltv.pdf?dl=0

I'm using Adobe Reader DC v15.017.20053 as my PDF Viewer.

1
which results in an invalidation of the certifying signature - according to which validator?mkl
Thank you for replying, when i open the pdf and check the signature field it will say "There have been changes made to this document that invalidate the signature". My current workflow is the following: Open a Reader & Stamper -> do the signature process -> close the Reader & stamper -> Start the Ltv process by opening another Reader & Stamper (with append mode set to true) -> Fetch Crl & ocsp response -> add them to the LtvVerification object -> call LtvVerification.merge() -> close the reader & stampeuser6696696
when i open the pdf and check the signature field it will say... - using which PDF viewer in which version? Furthermore, please supply a sample PDF (before & after adding LTV) and the pivotal parts of your code to allow analyzing the issue.mkl
@mkl i've updated the original post with the information you requesteduser6696696
Ok, I've inspected your file and how Adobe Reader reacts to it. It indeed looks like Adobe Reader does not accept LTV additions to PDFs with no-changes-allowed certification signatures even though PAdES-4 requires that. You might, as a last attempt, try and certify in PAdES mode instead of CMS mode. I have not checked but that might make a difference.mkl

1 Answers

1
votes

Observations with the sample file

I performed some tests with the OP's sample PDF. Indeed, Adobe Acrobat (Reader) does not like PAdES-4 LTV additions generated by iText to a PDF with no-changes-allowed certification, and it is a bit brain-split about it, saying both

Some of the changes that have been made to this document since this signature was applied are not permitted by the document author.

and

There have been no changes made to this document since this signature was applied.

Signature Properties dialog

(Adobe Acrobat signature properties dialog after pressing Compute Modifications List)

This situation remained even when I removed any change in excess of the addition of the LTV information (iText additionally adjusts the document modification date meta data), I eventually even removed the added Extensions entry ESIC (BaseVersion 1.7, ExtensionLevel 5) which indicates to a PDF viewer that PAdES-4 LTV content may be present, only the DSS reference and contents remained.

Thus, Adobe Acrobat violates the PAdES-4 specification which requires

DocMDP restrictions (see ISO 32000-1 1 clause 12.8.2.2) shall not apply to incremental updates to a PDF document containing a DSS dictionary and associated VRI, Certs, CRLs and OCSPs.

(ETSI TS 102 778-4 V1.1.2 (2009-12) Annex A.1 Document Security Store)

even though Leonard Rosenthol (the Adobe PDF evangelist at the time) assured on the iText mailing list

I checked with my engineers and they indeed verified that LTV is fully supported on DocMDP/Cert signatures.

(Reply to "Verify certified (with transform method DocMDP) signatures" dated Jan 17, 2012; 3:15pm)


I have not checked two options, though, probably Adobe Acrobat only adheres to the PAdES-4 requirement above if the certification signature is a PAdES-3 signature, or if the certified document already in the just certified version at least contains an Extensions entry ESIC (BaseVersion 1.7, ExtensionLevel 5).

The document at hand contains a legacy ISO 32000-1 signature (which can be regarded a PAdES-2 signature but which can also be regarded a PAdES-unaware signature) and indicates PDF version 1.3 without an ESIC extension entry.

Before finally calling it an Adobe Acrobat bug, I'd try changing using a PAdES-3 signature and the ESIC extension entry (or an ADBE one according to PAdES-4 section 4.4).

The question itself

Wrapping up, is there any other way to make the certifying signature LTV enabled other than embedding the information in the signature itself? Is there any way to create the dds/vri dictionaries at signing time?

The PAdES-4 additions are described as referring to signatures in prior revisions of the document, not to signatures added in the same revision. Thus, while it would be technically possible to add the information in the same revision, there is no guarantee they will be used by a conforming PDF viewer.