Long-Term Validation of Signatures

When presented with a digitally signed document, most will probably just accept it at face value. The more technically minded will validate the signature, which confirms that the signature is unaltered, and that is signed by a Certificate which we trust. This means that the Certificate is signed by another Certificate, and so on up the chain until we reach a trusted root - a self-signed Certificate which we consider trusted and have in our KeyStore.

However, even this isn't enough once you consider Certificate Revocation.

A certificate can be revoked at any time, and there are two common methods to check if this has happened. A CRL (Certificate Revocation List) is, amazingly enough, a list of revoked Certificates, published at semi-regular intervals by the party that signed them. But they have been largely superseded by OCSP, which allows the status to be verified in real-time.

Usually when working with Certificates we're interested in their current state, but for a signed PDF we're actually interested in what the state of the Certificate was at the time of signing. Consider these scenarios.

  1. Company A signs a PDF in January, and in September finds out their identity had been compromised in April. They revoke the Certificate from April, but the document signature remains valid; the digital identity was un-compromised at the time of signing.
  2. Company B signs a PDF in April, and in September finds out their identity had been compromised in January. They revoke the Certificate from January, and the signature is no longer valid.

There are a few key points to consider from the above

  • If a signature has been verified, it doesn't mean it will stay verified. As far as anyone knew both signatures in our examples were considered valid as of June, and anyone verifying the signature then would have found no problems.
  • In order to verify a Certificate we need to know exactly when the PDF was signed. For this to be unequivocal, the signature has to be digitally timestamped.
  • The process of checking a Certificate requires a network connection.
  • Verifying a Certificate requires the OCSP or CRL responder for its Certificates to be online. This might not be the case: we now have no way of determining if a PDF signed 20 years ago by an Enron Corporate key was signed with Certificate that was later revoked. How would you know if it were trustworthy? Although perhaps Enron wasn't the best choice to demonstrate this.

These considerations have led to the introduction of "Long Term Validation" for Digital Signatures in PDF. Defined in PAdES Part 4 and supported in Acrobat XI or later and version 2.18.2 or later of our API, the specification takes a slightly eccentric approach which we have tried to simplify in our API.

How to create a Long-Term Validated Signature with Acrobat

Acrobat requires that you set this through the Preferences Dialog. Select Signatures, select Creation & Appearance and ensure the Include Signature Revocation Status option is selected. Also ensure that you have a TimeStamp server selected in the Document Timestamping dialog.

How to create a Long-Term Validated Signature with our API

This is actually very simple.

  1. You must set an RFC3161 TimeStamp server in the AcrobatSignatureHandlerFactory
  2. You must verify the Certificates at the time of signing and embed this verification in the signature, by calling setValidateCertificatesOnSigning

Although these methods existed prior to 2.18.2, we weren't doing everything that was required of us. If you want LTV, you need 2.18.2

How to verify a Long-Term Validated Signature with Acrobat

Acrobat will do this for you automatically - if a signature has been "Long Term Validated", the line "Signature is LTV enabled" will appear in the Signature property description. And that's all you get to work with.

How to verify a Long-Term Validated Signature with our API

Here is where we need to get into a bit more detail. A signature can have Long-Term validation information included with it at the time of signing, or it can be applied after the PDF is signed. The first option is by far the simplest (it's what we've described above), and it's also the simplest to verify: because the OCSP and CRL responses are included with the original signature, they're verified as part of the signature verification process (when you call FormSignature.verify). The following code will show you how to test whether the verified Signature is LTV enabled.

      FormSignature sig = (FormSignature)pdf.getForm().getElements().get(...);
      PKCS7SignatureHandler handler = (PKCS7SignatureHandler)sig.getSignatureHandler();
      List<PKCS7SignatureHandler.ValidationInformation> ltv = handler.getValidationInformation();
      if (ltv != null) {
          System.out.println("Signature is LTV enabled");

As I mentioned, it's also possible to add long-term validation information to the PDF after it was created. To verify a signature like this, you would still run all of the steps above, then go through the list of returned ValidationInformation objects and verify them by calling isComplete. This will test the embedded validation information, and confirm its both cryptographically intact, and that the Certificate chain goes up to a trusted root in the KeyStore you supply to that method.

This process will confirm the Signature had been confirmed valid at some point after it was initially applied. When was that? Well, we don't really know.

Adding Long-Term Validation information to an existing signature

Verifying a signature created with LTV information as described above is easy. But if you have a signature without the required LTV information that's OK too. You can verify it fairly easily by querying the appropriate OCSP responders when you open the PDF (one way to do this with our API is to add validation information, as discussed below).

Why would a signer choose not to make their signature LTV enabled by default? Perhaps inability - if the PDF was signed offline, there would be no way to obtain an OCSP or CRL response (or Timestamp) at the time of signing. Or cost: obtaining those responses involves network traffic, and if you are signing millions of documents this is something to consider.

So far, so normal. The unusual part is that once you have validated the PDF, you can add the result of that validation to the PDF by appending a document revision. In Acrobat XI and later, this is done by right clicking on the signature and selecting "Add Verification Information".

There are various ways this could have been done - the most obvious being to apply a new, regular signature (or timestamp signature) exactly as described above. Adobe chose not to do this, and instead we have a new type of structure in the PDF object which is meant to hold this data, a Document Security Store or DSS for short. This will hold the various OCSP and CRL responses for the signature, but strangely this object is not, itself, cryptographically verifiable.

Which means you can see that a signature has been verified, but have no way of knowing when that verification took place.

The specification recommends you apply another signature (with a timestamp) immediately after the verification information was added - this will guarantee that the verification was done at some point before the signature data, but nothing more. Acrobat offers only the single line "Signature is LTV enabled" to work with, which saves them having to explain the timing of this in more detail.

Adding Long-Term Validation information to an existing signature with our API

Our API can add validation information, and it can sign the PDF including this information once it's been added, but sadly these are two separate steps. Here's an example from our TimeStampHandlerFactory showing how:
      PDF pdf = new PDF(new PDFReader(new File("input.pdf")));
      KeyStore rootkeystore = FormSignature.loadDefaultKeyStore();
      for (FormElement elt : pdf.getForm().getElements().values()) {
        if (elt instanceof FormSignature) {
          FormSignature sig = (FormSignature)elt;
          SignatureHandler handler = sig.getSignatureHandler();
          if (handler instanceof PKCS7SignatureHandler) {
            PKCS7SignatureHandler pkcshandler = (PKCS7SignatureHandler)handler;
      ByteArrayOutputStream out = new ByteArrayOutputStream();

      pdf = new PDF(new PDFReader(new ByteArrayInputStream(out.toByteArray())));
      URL url = new URL("http://timestamp.entrust.net/TSS/RFC3161sha1TS");
      TimeStampHandlerFactory factory = new TimeStampHandlerFactory(url);
      FormSignature timestamp = new FormSignature();
      timestamp.sign(null, null, null, factory);
      pdf.getForm().getElements().put("timestamp", timestamp);
      pdf.render(new FileOutputStream("output.pdf"));

Note the save to a temporary byte array in the middle, but it could be worse: if you wanted to guarantee that the validation took place after a certain date as well as before, the only way to do this is to timestamp the PDF; re-load it and add validation information as shown above, save, reload it a second time and add another timestamped digital signature.

Because of all this strangeness we have tried to be even more complete than normal in our API documentation on this topic, so if you have a need to do anything with Long-Term Validation of signatures other than creating brand new ones, I suggest you have a good read through the API docs of the various methods involved.

Despite all this, LTV signatures are a useful addition, particularly when used in conjunction with PDF/A. A PDF/A document can be signed and verified, and (provided the root certificate remains trusted by the recipient) it will be possible to view the file and ascertain that its Signature and Certificates remain valid many years after it was signed. That's the theory, anyway.