Subject: Re: Questions on digest and signature algorithm identifiers in CMS

From: "Denis Pinkas" <[email-masked]>
Date: Fri, 19 Jan 2007 12:57:12 +0100

Julien,

On January 9, I addressed this topic on the list, but no one has responded yet.
Hereafter are some extracts of what I said, where the clarifications you are looking for 
are addressed in the third pararagraph.

"The current explanations from CMS (in fact from PKCS#7) are far insufficient 
to provide sufficient guidance for a correct verification. This needed to be fixed 
and has been fixed in the first text proposal".

"First replacement:

   A recipient verifies a signature in the following way : 
 
   It must first identify the signer's public key to be used for the 
   verification.  The signer's public key is referenced in the sid 
   value either by an issuer distinguished name along with an 
   issuer-specific serial number or by a subject key identifier that 
   identifies the certificate containing the public key.  If the 
   essCertID signed attribute is present, then the public key 
   contained in the referenced certificate shall be used.  The 
   signer's certificate may be included in the SignedData certificates 
   field.
 
   It must verify that the signatureAlgorithm indicated in the 
   SignerInfo value is compatible with the digestAlgorithm indicated 
   in the SignerInfo value and the algorithm contained in the 
   subjectPublicKeyInfo from the signer’s certificate, e.g. if the 
   signatureAlgorithm is sha-1WithRSAEncryption then the 
   digestAlgorithm must be id-sha1 and the algorithm contained in the 
   subjectPublicKeyInfo must be rsaEncryption. In addition, it must 
   verify that the strength and key size of these algorithms are 
   conformant with its local security policy, otherwise it shall 
   discard the signature.
 
   It must then use the specific digestAlgorithm indicated in the 
   SignerInfo value to compute a digest and the signatureAlgorithm 
   indicated in the SignerInfo value with to verify the signature 
   value, as defined in Section 5.3. 
 
   A given signer may apply more than one signature.  This may be 
   useful in particular when some recipients are unable to process 
   some algorithms during an algorithm migration phase".

Denis

>Folks,
>
>I have a few questions regarding the interpretation of the algorithm
>identifiers used in CMS in the SignerInfo structure.
>
>SignerInfo ::= SEQUENCE {
>	version CMSVersion,
>	sid SignerIdentifier,
>	digestAlgorithm DigestAlgorithmIdentifier,
>	signedAttrs [0] IMPLICIT SignedAttributes OPTIONAL,
>	signatureAlgorithm SignatureAlgorithmIdentifier,
>	signature SignatureValue,
>	unsignedAttrs [1] IMPLICIT UnsignedAttributes OPTIONAL }
>
>
>This structure includes both a digestAlgorithm and a signatureAlgorithm,
>and there are two cases: either signedAttrs are present or not.
>
>Let us first look at case 1, signedAttrs are present.
>In that case, we hash the content with the "digestAlgorithm",
>and then compute the signature on the DER of signedAttrs with
>"signatureAlgorithm".
>
>My first question is: is it authorized to have a _different_
>hash function is the digestAlgorithm and the signatureAlgorithm ?
>For instance, can I hash the content with MD5 and sign the signedAttrs
>with "RSA-SHA1" ? How about PSS ? About about the general case ?
>
>Now, in case 2, we have both a hash function defined in "digestAlgorithm"
>and a hash function (implicitely defined) in "signatureAlgorithm"
>(except for the special "rsaEncryption" identifier).
>
>In that case, is it authorized to have a _different_ hash function
>in digestAlgorithm and signatureAlgorithm ? And if so, how to interpret
>it ? Assuming I have MD5 for the digest and RSA-SHA1
>for the signature, should I interpret it as a RSA-MD5 signature ?
>As a RSA-SHA1 signature ? Or should I consider the CMS as invalid ?
>Is there a general rule ?
>
>Thank you very much for your clarifications.
>
>Regards,
>
>--
>Julien Stern

Denis Pinkas

---

From: "Julien Stern" <[email-masked]>
Date: Fri, 19 Jan 2007 14:43:55 +0100

> are addressed in the third pararagraph.

Denis,

thanks for your answer. And my apologies for not having seen your previous
mail. I'm subcribed to the list, but I apparently have missed that one.

Nevertheless, while I agree with you there is a minor clarification needed,
I'm afraid that your text still leaves some things unclear.

You say that if the signatureAlgorithm is sha-1WithRSAEncryption
then the digestAlgorithm must be id-sha1.

I have no specific issue with this rule, but
1) I could not find it anywhere in the current text
2) It contradicts (in spirit) the text from RFC4056, which does
not mandate the use of the same hash function.

--------------------------------------------------------------------
RFC4056:
digestAlgorithms SHOULD contain the one-way hash function used to
compute the message digest on the eContent value.

The same one-way hash function SHOULD be used for computing the
message digest on both the eContent and the signedAttributes
value if signedAttributes exist.

The same one-way hash function MUST be used for computing the message
digest on the signedAttributes and as the hashAlgorithm in the RSA-
PSS-params structure.
--------------------------------------------------------------------

The main problem I see in the current CMS is the fact that two
different techniques can be used for signing/verification (probably
due to legacy interoperability reason, I'm not trying to blame anyone
here :)).

When there are no signedAttrs, the signatureAlgorithm should be
understood as a fake OID, and interpreted differently from the other
RFCs. More precisely, it represents "the part of the signature that you
perform after the hashing". (In theory, that a big problem,
because not all signature algorithms can be expressed as a hash +
some other operations, but in practice, that essentially the case,
so let's live with it).

When there are signed attributes, however, both interpretations become
possible:

- the first one being "we hash the content with digestAlgorithm and then
we hash the signed attributes with the same digestAlgorithm and then
we perform the same half-signing as above".

- The second being: "we hash the content with digestAlgorithm and then
we sign the signedAttrs with the signatureAlgorithm (to be understood
as a _real_ signatureAlgorithm, e.g. including its own hash if it uses
one)."

Apparently, the wording of RFC4056 seem to imply that the second
interpretation should be used. The problem is that RFC4056 is totally
silent about the way to verify when signedAttrs are absent.

RFC3852 is not very verbal regarding the various interpretations,
but I would tend to think it suggests the first one.

Is there a consensus on the list on the correct interpretations ?
Or even better, a quote that clarifies it ?

Regards,

--
Julien Stern