Search code examples
c#digital-signaturetrusted-timestampgembox-pdf

How can I add an embedded timestamp to an existing digital signature that was issued by a TSP


I am trying to achieve PAdES digital signature with an embedded timestamp for a .pdf document. Namely, what I'm trying to achieve:

DDS with an embedded timestamp

I'm using a trusted provider (TSP; external party) that performs the DDS and therefore I do not have access to the private key (.pfx cert) that the TSP uses to sign the message digest. I have been using the .NET class library from GemBox and have managed to successfully add the digital signature to a .pdf file using the function:

Gembox.Pdf.Form.PdfSignature Sign(Func<Stream, byte[]> signer, PdfSignatureFormat signatureFormat, int estimatedSignatureContentsLength) 

I pass in for the argument "signer" (see the above function) another function that simply calls an endpoint from the TSP provider which returns the mobile signature (as a byte[]). Then the signature gets successfully added the .pdf file (using GemBox's signature process):

DDS with no embeeded timestamp

Now I am in need of adding an embedded timestamp to the signature and I'm not sure how to achieve that since the DDS came from an external party. All code examples I've come across assume that you have the .pfx certificate, i.e. that the DDS is performed along with the timestamp (see e.g. here), and in my case I would then have to make a requirement to my TSP to provide me with a DDS that includes a timestamp from a trusted provider.

I hope someone can point me in the right direction here and explain to me if this is actually possible, i.e. to add an embedded timestamp when the DDS is being populated from an external party. Please notice, I'm open to explore other .NET libraries, i.e. other than GemBox if needed. However, I have found that library to be very useful for other purposes as well.

Thanks in advance!


Solution

  • Yes, it is possible to embed the timestamp into the signature after the signature is created so there is no need for your TSP to provide you with a DDS that includes a timestamp.

    The timestamp is usually added at the same time when the signature is being created because PDF signing process requires that you first estimate the size of the signature and the estimated size might be lower than required for the additional embedding of the timestamp. So, timestamping is first done over some dummy data to find out the size of the timestamp and this size is included in the calculation of the estimated size of the signature.

    Since you use the public GemBox.Pdf.Forms.PdfSignature GemBox.Pdf.Forms.PdfSignatureField.Sign(Func<Stream, byte> signer, PdfSignatureFormat signatureFormat, int estimatedSignatureContentsLength) method, it means that your TSP provider endpoint already returns a CMS-encoded signature and this CMS-encoded signature must be augmented with a timestamp before being inserted into a signed PDF file. GemBox.Pdf currently doesn't provide this timestamp augmentation, but I am sure this can be easily added if you ask GemBox for this over their official customer support channel.

    On the other hand, if your TSP provider also provides an endpoint that returns just the private key signature value, then you can leave the creation of CMS-encoded signature (that includes private key signature value, signer certificate, embedded timestamp, optional validation info (certificate chain, OCSP responses and/or CRLs that make the signature "LTV enabled") and all other data required for a valid PAdES signature) to GemBox.Pdf. Combination of examples Digitally sign a PDF file with an external signature (shows how to interoperate between GemBox.Pdf and your TSP provider endpoint that returns the private key signature value) and PAdES B-LT level (shows how to make a PAdES signature that has an embedded timestamp and is "LTV enabled") show how this can be done.