How to compute message-digest in a SignerInfo?
Asked Answered
L

1

1

I'm trying to generate a pdf with LTV enabled. I generate a pkcs7 object with all the attributes necesary included the signerInfo object. The signature generated is valid but not LTV enabled. According to the PDF reference manual i need to include validation info (CRLS or OCSP...) and based on rfc3852 this content goes in the signedAttributes object and it must contain a content-type attribute and a message-digest attribute. My question is how to compute the message-digest value and is it necesary to sign alongside the pdf content?

Note: the adbe-revocationInfoArchival object containing the CRLs seems to be correct since acrobat reads the revocation info directly from the file. The only issue i seem to have is the message-digest included in the signedAttrs object and/or the signature value is not computed correctly. RFC is not very clear on what that message-digest should be or if it should be included in the digest that will be signed with the signers private key.

Levitan answered 27/9, 2021 at 17:43 Comment(8)
"My question is how to compute the message-digest value" - that the hash value of the signed byte ranges of the pdf - "and is it necesary to sign alongside the pdf content?" - what do you mean by this? You sign the pdf content by including its hash as message-digest value. "The only issue i seem to have" - actually your question seems to indicate that it is likely that there are other errors still.Collection
Not the message digest of the pdf document, i'm talking about the message-digest in the signed attributes field. I have no issue just signing the pdf, what i'm trying to do is add CRLs in the PKCS7 structure, that way the signature becomes LTV enabledLevitan
"Not the message digest of the pdf document, i'm talking about the message-digest in the signed attributes field." - Yes, you are talking about the message-digest signed attribute. The value of that attribute is the hash of the signed byte ranges of the PDF.Collection
So theese attributes are not signed ? The rfc states they are, thus the name "signedAttr". I've tried using the pdf digest (the same that's signed and verified correctly) and when i open the pdf no pdf reader can verify the signature, just as if the newly added attributes changed the full message-digest that was supposed to be signed. Here is another source a bit more readable that the rfcLevitan
"So theese attributes are not signed ?" - Why should those attributes be not signed?Collection
That's my question. Maybe i didn't express myself correctly, sorry. I want to know how do i add these attributes to the final digest to sign. I'm using SHA to digest the pdf, then sign it with the rsa private key and build the pkcs7 structure including the certificate chain, the signed message and a timestamp as an unsigned attribute. Now i want to include the crls to enable LTV. I add the crls as signed attributes with the OID 1.2.840.113583.1.1.8. then i add the content-type attr and the message-digest. How do i calculate that message-digest and how do i include it in the final digest?Levitan
"I'm using SHA to digest the pdf, then sign it with the rsa private key and build the pkcs7 structure including the certificate chain, the signed message and a timestamp as an unsigned attribute." - Ah, ok. That is completely wrong. I'll try and write an answer to sketch the relationships.Collection
Note that the pdf is verified correctly if i don't add the signed attributes, the signature breaks when i add them. Sorry for the confusion, english is not my main language.Levitan
C
1

After some back and forth in the comments to the question I'm still not sure what information you need, so here a few thoughts in general on the structure and contents of non-trivial CMS signature containers for PDF signatures.

The Specifications

First off, though, some words on the specifications to use. You mention the PDF reference manual and rfc3852. Both actually are not state-of-the-art anymore, but interestingly one less than the other.

  • Originally the Adobe PDF References for PDF up to 1.7 were the documentation to look at. Unfortunately Adobe saw these references as not normative in nature, i.e. if the current Reference and the current Acrobat version disagreed on something, the program was correct, not the Reference!

    The latest Adobe PDF Reference (for PDF 1.7) referred to RFC 2315 for the structure of the signature container.

  • Then Adobe transferred the authority over the format PDF to the International Organization for Standardization (ISO) who in 2008 published the first normative PDF specification, ISO 32000-1, which was very similar to the last PDF Reference in content but adopted the RFC'ish language.

    ISO 32000-1 refers both to RFC 3852 and RFC 2315 for the structure of the signature container. Which is weird, but most likely the remaining RFC 2315 reference was an oversight.

  • In 2017 the ISO published a PDF specification for PDF 2.0, ISO 32000-2, with a number of relevant changes, also in the context of signing.

    ISO 32000-2 refers to RFC 5652 for the structure of the signature container for adbe.pkcs7.detached signatures and to ETSI EN 319 122 for the structure of the signature container for ETSI.CAdES.detached signatures.

  • In 2020 the ISO updated ISO 32000-2 with a number of clarifications; the references for the signature container specification remained the same.

Thus, currently you should look at ISO 32000-2:2020 and RFC 5652.

CMS Signature Containers

In a late comment you say

I want to know how do i add these attributes to the final digest to sign. I'm using SHA to digest the pdf, then sign it with the rsa private key and build the pkcs7 structure including the certificate chain, the signed message and a timestamp as an unsigned attribute.

This procedure can only create simple signature containers without signed attributes as only in these simple containers the document hash is signed directly. But the adbe-revocationInfoArchival attribute you want to add must be a signed attribute, and as soon as signed attributes are involved, the document hash value is not signed directly anymore.

The CMS signature container contains a SignedData object with exactly one SignerInfo object. That SignerInfo object is defined as

  SignerInfo ::= SEQUENCE {
    version CMSVersion,
    sid SignerIdentifier,
    digestAlgorithm DigestAlgorithmIdentifier,
    signedAttrs [0] IMPLICIT SignedAttributes OPTIONAL,
    signatureAlgorithm SignatureAlgorithmIdentifier,
    signature SignatureValue,
    unsignedAttrs [1] IMPLICIT UnsignedAttributes OPTIONAL }

(RFC 5652 section 5.3. "SignerInfo Type")

In a signature container created by your working code the OPTIONAL signedAttrs are absent and the signature value is calculated immediately for the document hash.

As soon as there are signed attributes, though, the OPTIONAL signedAttrs is not absent anymore, instead it is a SET of Attribute instances including at least

  • a content-type attribute with id-data as value,
  • a message-digest attribute with the digest value of the to-be-signed PDF byte ranges as value,
  • and in your case an adbe-revocationInfoArchival attribute with the revocation information as value.

In this case the signature value is not calculated immediately for the document hash anymore but instead for the hash value of the signedAttrs!

To be more exact, it is calculated for the hash value of the complete DER encoding thereof, and not with the IMPLICIT [0] tag but with an EXPLICIT SET OF tag.

Thus, after using SHA to digest the pdf you instead of signing it with the rsa private key and building the pkcs7 structure proceed by

  • building the set of signed attributes with at least the attribute entries enumerated above, DER encoding that set and hashing it,
  • signing that hash value of the signed attributes with your private key, and
  • building the CMS signature container structure with these signed attributes and this signature value, and also with the certificate chain.

Additionally you may add a signature time stamp.

Collection answered 28/9, 2021 at 15:51 Comment(3)
Ohhhh, so instead of signing the hashed value of the pdf directly, i need to sign the hash value of the signedAttrs which contain the hashed value of the pdf and the crls right? I was trying to sign both the pdf digest and the signedAttrs digest togetherLevitan
Just tried it and got an LTV enabled verified pdf. Thank you so much!Levitan
"Ohhhh, so instead of..." - correct, the document hash then is signed indirectly. "Just tried it and got an LTV enabled verified pdf." - Great!Collection

© 2022 - 2024 — McMap. All rights reserved.