Skip to main content
Skip table of contents

How to enable LTV for a timestamp signature?

Acrobat tells me my signature is LTV enabled, but the timestamp signature is not. How can I make both LTV enabled?


I'm using iText to sign PDF documents. I need these documents to be timestamped and LTV-enabled. I followed the instructions and used the addLtv() method. I get a PDF with 2 signatures, which is normal: the first is my own signature, the second is the document-level timestamp.

However, Acrobat tells me my signature is LTV enabled, but the timestamp signature is not:

Image from Acrobat Pro XI

This is because the revocation info of the timestamp certificate is not embedded in the document :

Missing revocation info 1

Missing revocation info 2

From my understanding, the addLtv() method should get all revocation information needed and embed it in the document. Is that correct, or do I have to "manually" get and embed this information?

Posted on StackOverflow on Jan 11, 2015 by Silas

Answer provided by mkl:

This is the sample code this question is about:

public void addLtv(String src, String dest, OcspClient ocsp, CrlClient crl, TSAClient tsa)
    throws IOException, DocumentException, GeneralSecurityException {
    PdfReader r = new PdfReader(src);
    FileOutputStream fos = new FileOutputStream(dest);
    PdfStamper stp = PdfStamper.createSignature(r, fos, '\0', null, true);
    LtvVerification v = stp.getLtvVerification();
    AcroFields fields = stp.getAcroFields();
    List names = fields.getSignatureNames();
    String sigName = names.get(names.size() - 1);
    PdfPKCS7 pkcs7 = fields.verifySignature(sigName);
    if (pkcs7.isTsp()) {
        v.addVerification(sigName, ocsp, crl,
            LtvVerification.CertificateOption.SIGNING_CERTIFICATE,
            LtvVerification.Level.OCSP_CRL,
            LtvVerification.CertificateInclusion.NO);
    }
    else {
        for (String name : names) {
            v.addVerification(name, ocsp, crl,
                LtvVerification.CertificateOption.WHOLE_CHAIN,
                LtvVerification.Level.OCSP_CRL,
                LtvVerification.CertificateInclusion.NO);
        }
    }
    PdfSignatureAppearance sap = stp.getSignatureAppearance();
    LtvTimestamp.timestamp(sap, tsa, null);
}

This code identifies the most recently filled signature field of the PDF and checks whether it is a document time stamp or an usual signature.

If it is a document time stamp, the code adds validation information only for this document timestamp. Otherwise the code adds validation information for all signatures. (he assumed work flow behind this is that the document is signed (for certification and/or approval) a number of times first, and then the document enters LTV cycles adding validation information and document time stamps but no usual signatures anymore. Your work flow may vary and, therefore, your program logic, too.

Only after all this is done, a new document time stamp is added.

For this finally added time stamp no validation information are explicitly added to the PDF and this is why Adobe Reader/Acrobat usually does not consider this document time stamp LTV enabled. (if document time stamps from the same TSA have been applied in short succession, validation information included for a prior time stamp may be applicable.)

If you need validation information for this final document time stamp too, simply apply this method (the same as the method above, merely not adding a document time stamp) to the file with the document time stamp:

public void addLtvNoTS(String src, String dest, OcspClient ocsp, CrlClient crl)
    throws IOException, DocumentException, GeneralSecurityException {
    PdfReader r = new PdfReader(src);
    FileOutputStream fos = new FileOutputStream(dest);
    PdfStamper stp = new PdfStamper(r, fos, '\0', true);
    LtvVerification v = stp.getLtvVerification();
    AcroFields fields = stp.getAcroFields();
    List names = fields.getSignatureNames();
    String sigName = names.get(names.size() - 1);
    PdfPKCS7 pkcs7 = fields.verifySignature(sigName);
    if (pkcs7.isTsp()) {
        v.addVerification(sigName, ocsp, crl,
            LtvVerification.CertificateOption.SIGNING_CERTIFICATE,
            LtvVerification.Level.OCSP_CRL,
            LtvVerification.CertificateInclusion.NO);
    }
    else {
        for (String name : names) {
            v.addVerification(name, ocsp, crl,
                LtvVerification.CertificateOption.WHOLE_CHAIN,
                LtvVerification.Level.OCSP_CRL,
                LtvVerification.CertificateInclusion.NO);
        }
    }
    stp.close();
}

Background

The reason why the iText addLtv() example does not (necessarily) create LTV-enabled PDFs is that it is nearer to the best practices for LTV as proposed by ETSI in the PAdES specification than to Adobe's best practices for LTV.

According to ETSI TS 102 778-4 V1.1.2 (2009-12) the structure of a PDF document to which LTV is applied is illustrated in figure 2.

The life-time of the protection can be further extended beyond the life-of the last document Time-stamp applied by adding further DSS information to validate the previous last document Time-stamp along with a new document Time-stamp. This is illustrated in figure 3.

On the other hand, according to Adobe (as written by their PDF evangelist Leonard Rosenthol on the iText mailing list in January 2013),

LTV enabled means that all information necessary to validate the file (minus root certs) is contained within. So this statement of yours would be true.

the PDF is signed correctly and contains all necessary certificates, a valid CRL or OSCP response for every certificate

But since the only way for that statement to be true is for the presence of DSS, you must have DSS for LTV-enabled to appear. No timestamp (regular or document level) is required.

Due to this divergence PDF documents with LTV according to ETSI usually are presented by Adobe software to have one not LTV-enabled document time stamp.

See also:

Click this link if you want to see how to answer this question in iText 7.

JavaScript errors detected

Please note, these errors can depend on your browser setup.

If this problem persists, please contact our support.