Digital signatures, OCSP, and timestamping Part 2 (iText 5)

Verifying the signatures in a document

The root certificates of CAs that are trusted by the distributor of the Java Runtime you use are stored in a file named cacerts. You can find this key store in the lib directory of the JAVA_HOME directory. Depending on the use case, different collections of CA certificates may be required, which may not include those already in that file.

The next bit of code uses the getSignatureNames() method to get all the names of the signature fields in the document. Then you can use the root certificates in a Key-Store to verify each signature.

Listing 12.18 Signatures.java

Listing 12.18 Signatures.java

You can check whether the signature covers the whole document by using the signa-tureCoversWholeDocument() method. This is true for the second signature, but the first signature only covers revision 1 of 2, and that’s not the complete document.

You can get the revision number for the signature with the getRevision() method, and the total number of revisions with getTotalRevisions(). The verification of the signature is done with the PdfPKCS7 object. This object can give you the public certificate of the signer and its parent certificates, as well as the signing date. You can use the verify() method to find out if the document was tampered with, and the verifyCertificates() method to check the certificates in the PDF against the certificates in the cacerts key store. In this example, you didn’t pass any CRLs, so the third parameter of the method is null.


Creating the digest and signing externally

In the previous examples, we’ve let iText make the digest, and we’ve let iText decide how to sign it using the PrivateKey object. But it isn’t always possible to create a PrivateKey object. If the private key is put on a token or a smart card, you can’t retrieve it programmatically. In this case, making and signing the digest has to be done on external hardware, such as a smart-card reader.

If a root certificate isn’t present, you can import it with the keytool utility. This key store can be loaded into a KeyStore object like this:

tmp40477_thumb[2]

FAQ How do I get a private key that is on my smart card ? There would be a serious security problem if you could extract a private key from a smart card. Your private key is secret, and the smart card should be designed to keep this secret safe. You don’t want an external application to use your private key. Instead, you send a hash to the card, and the card returns a signature or a PKCS#7 message. PKCS refers to a group of Public Key Cryptography Standards, and PKCS#7 defines the Cryptographic Message Syntax Standard.

Signing a PDF document using a smart-card reader involves middleware, and the code will depend on the type of smart-card reader you’re using. To get an idea of what needs to be done, we’ll look at some examples where the digest is made or signed externally.

The first part of this listing looks similar to what you’ve done before.

Listing 12.19 Signatures.java

Listing 12.19 Signatures.java

Let’s pretend you don’t have access to the private key, so you pass null to the set-Crypto() method O. You use the setExternalDigest() method to reserve space in the signature dictionary for keys whose content isn’t known yet ©. You don’t close the PdfStamper, but you preClose() the signature appearance G. Then you create a Signature object using the private key Q; this is something that could happen outside of your program. You pass the document bytes obtained with getRangeStream() to the Signature Q, and you create the /Contents (the signed digest) of the signature field G. When you close the appearance, the signature will be added.

The following listing shows a variation where you create a digest using the Secure Hash Algorithm 1 (SHA-1), and if sign is true, you sign it with the RSA algorithm.

Listing 12.20 Signatures.java

Listing 12.20 Signatures.java

If you look at the resources that come with this topic, you’ll also find an example that explains how to sign a PDF document using an external library.

NOTE Signing can become even more generic. There may be situations in which you don’t know the certificate chain before the signature is generated. Or you may have to split the signing process into parts, in which case you can’t keep the PdfStamper open all the time. It would lead us too far afield to discuss all the possible workarounds for each of these situations. More examples, including examples involving smart-card readers, can be found on SourceForge and on the official iText site (see section B.1, for the URLs).

Now let’s discuss some technologies that provide extra security features.

CRLs, OCSP, and timestamping

Suppose you receive a contract from person X who works at company Y.You can safely assume that the document is genuine, unless … person X was fired, but he still owns a copy of the private key of company Y. Such a contract probably wouldn’t be legal. Surely there must be a way for company Y to revoke the certificate for employee X so that he no longer can act on behalf of his former company.

CERTIFICATE REVOCATION LIST

Every certificate authority keeps lists of certificates that are no longer valid, whether because the owner thinks the private key was compromised, or the token containing the private key was lost or stolen, or the original owner of the key is no longer entitled to use it. Such a list is called a certificate revocation list (CRL), and they are made public at one or more URLs provided by the CA who signed the certificate. You can create a CRL object like this:

tmp40480_thumb[2]

An array of CRL objects can be passed as a parameter to the setCrypto() method. However, CRLs are generally large, and this technique is considered to be "old technology."

It might be a better idea to use the Online Certificate Status Protocol (OCSP).

ONLINE CERTIFICATE STATUS PROTOCOL

OCSP is an internet protocol for obtaining the revocation status of a certificate online. You can post a request to check the status of a certificate over HTTP, and the CA’s OCSP server will send you a response. You no longer need to parse and embed long CRLs. An OCSP response is small and constant in size, and can easily be included in the PKCS#7 object.

NOTE Revocation information in a PDF document is a signed attribute, which means that the signing software must capture the revocation information before signing. A similar requirement in this use case applies to the chain of certificates. The signing software must capture and validate the certificate’s chain before signing. CRLs will lead to bigger PDF documents, and using OCSP will not take as much space. But the OCSP connection to check the status can take time, whereas CRLs can easily be cached on the filesystem. It’s always a tradeoff.

Now let’s look at another problem that might arise. Suppose somebody sends you a signed contract. He has used a private key that is still valid, and you’re sure that the document you’ve received is genuine. However, at some point the author of the document regrets what he’s written. By resetting the clock on his computer, he could create a new document with a new digital signature that is as valid as the first one. This way, you could end up with two documents signed with the same private key at almost the same time, but with slightly different content. How can anybody know which document is more genuine?

TIMESTAMPING

This problem can be solved by involving a third party: a timestamping authority (TSA). The TSA will take the hash of the document and concatenate a timestamp to it. This is done on a timestamp server that is contacted during the signing process. The time-stamp server will return a hash that is signed using the private key of the TSA.

A signed PDF with a timestamp

Figure 12.9 A signed PDF with a timestamp

Figure 12.9 shows a PDF with a timestamped signature. In previous examples and screen shots, the signature panel informed you that the "Signature date/time are from the clock on the signer’s computer." Now it says: "Signature is timestamped." You can also check the certificate of the TSA in the signature properties. That solves the potential problem of antedated documents.

The next listing can be used to add a timestamp (if withTS is true) and to check the revocation status of the certificate with OCSP (if withOCSP is true).

Listing 12.21 Signatures.java

Listing 12.21 Signatures.javaListing 12.21 Signatures.java

In this example, you use the PdfSignature dictionary to create a detached PKCS#7 signature, as opposed to PKCS#7 signatures where the data is encapsulated in the digest. Before you preclose the appearance, you also need to estimate the length of the signature’s content.

Note that you need an account with a TSA (with a TSA_LOGIN and TSA_PASSWORD) to create a TSA client object. An account with a trustworthy TSA isn’t free, but you can probably find some free timestamp server for testing purposes.

The URL of the OCSP server that is needed to create an OCSP client object is available in the public certificate. That is, if the CA that signed the certificate supports OCSP. You retrieve it with the getOCSPURL() method.

If you set withTS and withOCSP to false in listing 12.21, you’ll get an example that shows how to create a detached signature with authenticated attributes. By combining the code snippets in this topic, we could make many more examples, experimenting with almost every option that is described in ISO-32000-1.

We’ll finish this topic by introducing a set of restrictions and extensions to the PDF standard developed by the European Telecommunications Standards Institute (ETSI) regarding PDF Advanced Electronic Signatures (PAdES) profiles.

PDF Advanced Electronic Signatures (PAdES) profiles

ETSI is a European standardization organization in the telecommunications industry. This institute issues technical specifications such as TS 101 733 (first published in 2000), "Cryptographic Message Syntax (CMS) Advanced Electronic Signatures (CAdES)," and TS 101 903 (first published in 2002), "XML Advanced Electronic Signatures (XAdES)." More recently, in 2009, ETSI brought the same capabilities pioneered in CAdES and XAdES to PDF, resulting in a five-part specification describing PDF Advanced Electronic Signatures profiles:

■ Part 1—This is an overview of support for signatures in PDF documents, and it lists the features of the PDF profiles in the other documents.

■ Part 2—PAdES Basic is based on ISO-32000-1. If you want to know more about digital signatures in PDF, you should read this specification before starting to dig into the PDF reference. Everything mentioned in PAdES part 2 is supported in iText.

■ Part 3—PAdES Enhanced describes profiles that are based on CAdES: PAdES Basic Electronic Signature (BES) and Explicit Policy Electronic Signature (EPES). If you want to implement PAdES part 3 using iText, you need to switch to creating a detached CMS signature and use ETSI.CAdES.detached as the /SubFilter.

■ Part 4—PAdES Long-Term Validation (LTV) is about protecting data beyond the expiry of the user signing certificate. This mechanism requires a Document Security Store (DSS), and this mechanism isn’t available in ISO-32000-1. PAdES part 4 isn’t supported in iText yet.

■ Part 5—PAdES for XML content describes profiles for XAdES signatures. For instance, after filling an XFA form, which is XML content embedded in a PDF file, a user may sign selected parts of the form. This isn’t supported in iText yet.

At the time this topic was written, neither Adobe Acrobat nor iText supported parts 3, 4, or 5. PAdES will solve one major issue that hasn’t been discussed in this topic: certificates have an expiration date. A document that is signed and verified today may be difficult to verify in seven years when the certificate has expired, or when it has been revoked (the validation data may not be available in the future).

The idea is to add new validation data and a new document timestamp to a Document Security Store in the PDF before the last document timestamp expires. This can be repeated multiple times, always before the expiration of the last document time-stamp. This way, PAdES LTV makes it possible to extend the lifetime of protection for the document.

Note that the DSS isn’t part of ISO-32000-1 and it’s not available in iText yet; it will be introduced in ISO-32000-2. We’ll find out more about ISO-32000-2 in the next part of this topic, but first let’s summarize what we’ve learned in this topic.

Summary

With this topic, we close part 3 of this topic. You’ve discovered that you can add different types of metadata to the documents created in parts 1 and 2. We discussed the compression of content streams, and we’ll use the decompression methods in the next part to inspect the PDF syntax that’s used to describe the content of a page.

In the sections about encryption and digital signatures, we talked about the protection of PDF documents. You used public-key cryptography to encrypt and decrypt a PDF document, and to digitally sign a PDF document. You’ve worked with key stores and certificates, signing documents in different ways. You’ve also learned about certificate and timestamp authorities, about certificate revocation lists, and the Online Certificate Status Protocol.

This topic completes the overview of essential iText skills you may need when creating or manipulating PDF documents. In the next part, we’ll dive into the PDF specification, and look at PDF at a much lower level. While doing this, you’ll learn about different types of PDFs such as PDF/X and PDF/A. We’ll work with PDF-specific functionality, such as optional content and marked content, and we’ll inspect different types of streams.

Next post:

Previous post: