Steps to include timestamp in PDF signature

8.6k views Asked by At

Good day,

I'm trying to embedded timestamp information into a pdf signature so that adobe will report to me that the signature was timestamp. Currently, all I've achieved is that Adobe reports that "The signature includes an embedded timestamp but it could not be verified" and when you view the Date/Time properties it says that the "Timestamp Authority" s not available and the "Show Certificate" is greyed out.

Obviously, I am doing something wrong in constructing my PKCS#7 message. But I don't now what. Can someone please help me by describing the steps I need to take so that my signature will be timestamped? Or suggest a tool that can help me find the problem?

I'm using Crypto API. The steps I follow currently is as follows:

  1. Create a digest of the pdf data using the CryptHashMessage function (SHA256).
  2. Send this digest to the TSA using the CryptRetrieveTimeStamp function. I've set the *TIMESTAMP_DONT_HASH_DATA* flag so that the digest won't be hashed again.
  3. The repsonse from the TSA is added to a *CRYPT_SIGN_MESSAGE_PARA* structure as an unauthenticated attribute and the signing time is added as an authenticated attribute.
  4. Then I use the CryptSignMessage function to sign the original data which uses the above structure.

How can I check that the data is correct so that adobe can show me that the signature has been timestamped?

Regards, Magda

2

There are 2 answers

3
Michael Chourdakis On

Timestamping is not done correctly. Check my mime library. You need to add an unauthenticated field with oID "1.2.840.113549.1.9.16.2.14".

0
mkl On

In a nutshell: You are time stamping the wrong data, see the bottom of the answer.

Major differences between your signature and Adobe's signature:

  1. Adobe's signature contains a signed revocation information attribute; this attribute does not contains any actual revocation information.

    As this attribute is optional, it should not be relevant here.

  2. Your signature contains a signed signing time attribute.

    As you also have a time stamp embedded, a signing time is not necessary but it is not forbidden, either.

  3. Your signature has a signatureAlgorithm value of 1.2.840.113549.1.1.1, i.e. RSA encryption while Adobe's is 1.2.840.113549.1.1.11, i.e. sha256WithRSAEncryption

    Here Adobe's choice definitively is the better one but Adobe Reader seems to ignore the deficiency in your signature: After all, it says that the document had not been changed since signing.

  4. In your signature the time stamp stamps the hash of the PDF document, i.e. the same as in the signature's signed messageDigest attribute while in Adobe's signature the time stamp stamps a different one.

    BANG. This is the problem. Admittedly you'd said it in your original question but it didn't catch my eye:

    1. Create a digest of the pdf data using the CryptHashMessage function (SHA256).

    2. Send this digest to the TSA using the CryptRetrieveTimeStamp function. I've set the TIMESTAMP_DONT_HASH_DATA flag so that the digest won't be hashed again.

    This is wrong! The time stamp is added as an unsigned attribute, according to spec:

    Time stamp information as an unsigned attribute (PDF 1.6): The timestamp token shall conform to RFC 3161 and shall be computed and embedded into the PKCS#7 object as described in Appendix A of RFC 3161.

    (section 12.8.3.3.1 of ISO 32000-1)

    And RFC 3161 states:

    The value of messageImprint field within TimeStampToken shall be a hash of the value of signature field within SignerInfo for the signedData being time-stamped.

    (Appendix A of RFC 3161)

    Thus, you are time stamping the wrong hash! Adobe correctly expects you to time stamp the signature. So you should first create a regular signature, then look up its signature value, hash & time stamp that value, and then add that time stamp to the signature container signer info as unsigned time stamp attribute.

    Unfortunately I don't know the Windows Crypto API well enough to explain how to do that; I'm more at home in the Java crypto api.