Score:0

Verify message digest of time stamp token

at flag

I'm trying to verify a time stamp token embedded into a PDF using the PDF 2.0 feature of the "Document Time-stamp Dictionary". The embedded time stamp token is exactly the token of a time stamp response from a time stamp authority server.

Since the OpenSSL library of Ruby doesn't seem to provide the necessary interfaces to do the task, I'm trying to do it manually. And I'm stuck at verifying that the digest value of the time stamp token is equal to the digest value of original content.

Here is the openssl pkcs7 -in response.der -inform DER -print output of a sample time stamp token: https://pastebin.com/s4CTGeQX

What I was able to do:

  • I can navigate the ASN1 structure of the PKCS7 object to locate the used digest algorithm inside the SignerInfo. In the example case this is "SHA512".

  • I also found the authenticated attribute called "messageDigest (1.2.840.113549.1.9.4)".

However, the messageDigest attribute value doesn't match the result of using SHA512 over the original content.

I'm not quite sure whether I have to further process messageDigest somehow or whether the digest I'm looking for is hiding (in plain sight) somewhere else. So any information on how to verify the signed content digest in the time stamp token is appreciated - thanks!

dave_thompson_085 avatar
cn flag
Exactly what are you checking? If I take SHA512 of the bytes extracted with `openssl asn1parse ... -strparse 65 -out x`, which are the contentInfo value beginning 30 81 and ending 31 5A, I get b8e362aa8b2eaa8e4eb81a019f14ffb96b4af0910ce0ad4e15621ada378518d07f327a7feca3ec2523ef212ce3a1fa8bbab6a6aef68706d82caaa531a43266e3 which does match the value of messageDigest in signedattrs
gettalong avatar
at flag
Ah, thank you! Your comment really helps, especially that the `openssl` command output shows *another* DER encoded structure lurking in there. I *think* I can now get to what I want
gettalong avatar
at flag
Thanks again, I just figured it out. See [my answer](https://crypto.stackexchange.com/a/102692/104895) for details.
Score:0
at flag

Thanks to the comment of @dave_thompson_085 I found what I was looking for.

So it turns out that PKCS7/d.sign/contents/d.other contains the DER encoded version of the TSTInfo structure. And this structure contains the messageImprint field which contains the hash/digest of the PDF that was originally sent in the time stamp request.

I can compare that value to the re-computed value when verifying the time stamp token, to ensure that the token really covers the PDF.

In Ruby code this looks something like this:

# Parse the time stamp token
p7 = OpenSSL::ASN1.decode(signature_dict.contents)
raise "not a signed-data" if p7.value[0].value != "pkcs7-signedData"

# Retrieve the signed data portion d.sign
signed_data = p7.value.find { |x| x.tag_class == :CONTEXT_SPECIFIC && x.tag == 0 }.value[0]

# Retrieve the ContentInfo structure
content_info = signed_data.value[2]

# Parse the embedded TSTInfo structure
content = OpenSSL::ASN1.decode(content_info.value[1].value[0].value)
digest_algorithm = content.value[2].value[0].value[0].value

# Retrieve the original hash sent in the time stamp request and
# recompute the hash from the PDF data
original_hash = content.value[2].value[1].value
recomputed_hash = OpenSSL::Digest.new(digest_algorithm).digest(signature_dict.signed_data)
I sit in a Tesla and translated this thread with Ai:

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.