RFC 6211

Cryptographic Message Syntax (CMS) Algorithm Identifier Protection Attribute

πŸ“… published April 2011, from ietf

RFC 6211: Cryptographic Message Syntax (CMS) Algorithm Identifier Protection Attribute πŸŽ€

Okay bestie, this is RFC 6211 πŸ’– It's a Standards Track document from the IETF (Internet Engineering Task Force), written by J. Schaad of Soaring Hawk Consulting and published in April 2011. Its ISSN is 2070-1721. The header doesn't list any obsoletes or updates, so there's no other RFC to chase down here 🧚

Abstract ✨

So the big problem is that CMS (Cryptographic Message Syntax) isn't protected against algorithm substitution attacks the way X.509/PKIX certificates are 😭 In one of these attacks, the attacker swaps out the algorithm or its parameters so the result of a signature verification changes. X.509 certificates avoid this because the signature algorithm is duplicated in the TBSCertificate.signature field, and the validator is told to compare both fields as part of signature validation. This document defines a new attribute that holds a copy of the relevant algorithm identifiers, so they're covered by the signature or authentication process πŸ”₯

Status of This Memo πŸ“œ

This is an Internet Standards Track document 🌸

It's a product of the IETF, which means it reflects the consensus of the IETF community. It got public review and was approved for publication by the Internet Engineering Steering Group (IESG). If you want more on Internet Standards, check Section 2 of RFC 5741.

For the current status, any errata, and how to send feedback, go to http://www.rfc-editor.org/info/rfc6211.

Copyright (c) 2011 IETF Trust and the persons identified as the document authors. All rights reserved.

This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (http://trustee.ietf.org/license-info) as they stand on the date of publication. Please read these carefully, because they spell out your rights and restrictions for this document. Code Components pulled out of this document must include the Simplified BSD License text, as described in Section 4.e of the Trust Legal Provisions, and they come without warranty, as the Simplified BSD License describes πŸ“„

Table of Contents πŸ—‚οΈ

1.  Introduction  . . . . . . . . . . . . . . . . . . . . . . . . . 3
  1.1.  Notation  . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.  Attribute Structure . . . . . . . . . . . . . . . . . . . . . . 5
3.  Verification Process  . . . . . . . . . . . . . . . . . . . . . 7
  3.1.  Signed Data Verification Changes  . . . . . . . . . . . . . 7
  3.2.  Authenticated Data Verification Changes . . . . . . . . . . 7
4.  IANA Considerations . . . . . . . . . . . . . . . . . . . . . . 8
5.  Security Considerations . . . . . . . . . . . . . . . . . . . . 8
6.  References  . . . . . . . . . . . . . . . . . . . . . . . . . . 8
  6.1.  Normative References  . . . . . . . . . . . . . . . . . . . 8
  6.2.  Informational References  . . . . . . . . . . . . . . . . . 9
Appendix A.  2008 ASN.1 Module  . . . . . . . . . . . . . . . . .  10

1. Introduction πŸ¦‹

Okay so the Cryptographic Message Syntax [CMS] is vulnerable to algorithm substitution attacks, and X.509/PKIX certificates [RFC5280] are not πŸ‘€ Same deal as the abstract: the attacker changes the algorithm being used or its parameters to change the result of a signature verification. Certificates are safe because the signature algorithm is duplicated in TBSCertificate.signature, and the validator is supposed to compare both fields during signature validation. This document defines a new attribute carrying a copy of the relevant algorithm identifiers, so they get protected by the signature or authentication process πŸ’…

Now, in an algorithm substitution attack, the attacker looks for a different algorithm that gives the same result as the one the signer used πŸ•΅οΈβ€β™€οΈ Say the creator hashed the content with SHA-1. The attacker then hunts for another hash algorithm that gives an output of the same length but where collisions are easier to find. SHA-0 and RIPEMD-160 are examples of other algorithms with same-length hash values. Parameterized algorithm identifiers can get attacked in similar ways. Randomized hashing functions, like the one in [RANDOM-HASH], come with security proofs that assume the parameters are controlled only by the originator and aren't picked by the attacker. Bestie, that assumption is the whole thing 🫢

Some algorithms were designed to resist this kind of attack from the start. An RSA PKCS #1 v.15 signature [RFC3447] can't have its hash algorithm swapped, because the hash algorithm is encoded as part of the signature ✨ The Digital Signature Algorithm (DSA) was originally defined to work only with SHA-1 as its hash algorithm. So if you know the public key from the certificate, you can be sure the hash algorithm can't change πŸ”’ There's also a convention, which the author says is undocumented as far as they can tell, that the same hash algorithm gets used for both the content digest and the signature digest. But some cases, like third-party signers who only get a content digest, mean that convention can't be enforced πŸ™ˆ

Attacks are always going to target stuff that's both long term and high value πŸ’Ž You'd expect these attacks to hit older documents more, since the algorithms used when the message was signed have had more time to degrade. Countersigning is the classic way to protect a signature, but it doesn't help against algorithm substitution. Countersignatures only sign the signature, and substitution attacks leave the signature value alone while changing the algorithms 😭

Next up, let's look closely at each field of the SignerInfo structure from CMS and figure out which ones the signature protects and which it doesn't πŸ” I've included a copy of the ASN.1 here for convenience. The AuthenticatedData structure gets the same kind of analysis, but I'm leaving that to the reader since it works in much the same way 🧠

      SignerInfo ::= SEQUENCE {
        version CMSVersion,
        sid SignerIdentifier,
        digestAlgorithm DigestAlgorithmIdentifier,
        signedAttrs [0] IMPLICIT SignedAttributes OPTIONAL,
        signatureAlgorithm SignatureAlgorithmIdentifier,
        signature SignatureValue,
        unsignedAttrs [1] IMPLICIT UnsignedAttributes OPTIONAL }
  • version is NOT protected by the signature. Lots of CMS implementations today ignore this field, so that's not a problem πŸ™ƒ If the value goes up, processing isn't expected to change. If the value goes down, implementations that respect the structure would fail to decode, but a bad signature validation wouldn't get through successfully.
  • sid can be protected using either version of the signing certificate authenticated attribute. SigningCertificateV2 is defined in [RFC5035], and SigningCertificate is defined in [ESS-BASE]. On top of protecting the signer identifier, the specific certificate gets protected by including a hash of the certificate that's used for validation πŸŽ€
  • digestAlgorithm has been implicitly protected, because CMS has only ever defined one digest algorithm per hash value length. (RIPEMD-160 was never standardized, FYI πŸ€“) There's also an unwritten convention that the same digest algorithm gets used here and for the signature algorithm. If newer digest algorithms get defined so there are multiple algorithms for a given hash length (the SHA-3 project is expected to do exactly that), or if parameters get defined for a specific algorithm, a lot of that implicit protection goes out the window 😬
  • signedAttributes are directly protected by the signature when they're present. The Distinguished Encoding Rules (DER) encoding of this value is what gets hashed for the signature computation πŸ’œ
  • signatureAlgorithm has been protected by implication in the past. An RSA public key implied the RSA v1.5 signature algorithm, and the hash algorithm plus that fact could be checked by the internal padding. That's no longer true now that the RSA-PSS signature algorithms exist 😡 A DSA public key implied SHA-1 as the hash algorithm, since it was the only possible one, with DSA as the public signature algorithm. That's still somewhat true, because there's an implicit tie between the length of the DSA public key and the length of the hash algorithm to be used. But that's known by convention only, and nothing explicitly enforces it 🫠
  • signature isn't directly protected by any other value unless a counter signature is present. It is, however, the cryptographically computed value that protects the rest of the signature information πŸ”
  • unsignedAttrs is NOT protected by the signature value. The SignedData structure was explicitly designed that way, so unsignedAttrs aren't covered by the signature value πŸ™…β€β™€οΈ

As you can see, the digestAlgorithm and signatureAlgorithm fields have been protected indirectly rather than explicitly in the past. With the new algorithms that have been defined or are being defined, that won't be true anymore 🚨 This document defines and describes a new attribute that explicitly protects these fields, along with the macAlgorithm field of the AuthenticatedData structure πŸ‘‘

1.1. Notation πŸ“

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC2119] 🌈


(to be continued in part 2 ✨)

2. Attribute Structure ✨

okay so this is the part where we get into the actual attribute πŸŽ€ the algorithm protection attribute has the ASN.1 type CMSAlgorithmProtection, and yes the naming is giving very "we had one job" energy πŸ’…

aa-cmsAlgorithmProtection ATTRIBUTE ::= {
    TYPE CMSAlgorithmProtection
    IDENTIFIED BY { id-aa-CMSAlgorithmProtection }
}

the object identifier that identifies this attribute is:

id-aa-CMSAlgorithmProtection OBJECT IDENTIFIER ::= { iso(1)
     member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs9(9) 52 }

and the attribute uses this ASN.1 type πŸ¦‹

CMSAlgorithmProtection ::= SEQUENCE {
    digestAlgorithm         DigestAlgorithmIdentifier,
    signatureAlgorithm  [1] SignatureAlgorithmIdentifier OPTIONAL,
    macAlgorithm        [2] MessageAuthenticationCodeAlgorithm
                                     OPTIONAL
}
(WITH COMPONENTS { signatureAlgorithm PRESENT,
                   macAlgorithm ABSENT } |
 WITH COMPONENTS { signatureAlgorithm ABSENT,
                   macAlgorithm PRESENT })

here's the breakdown of the fields 🌸

  • digestAlgorithm is a copy of the SignerInfo.digestAlgorithm field or the AuthenticatedData.digestAlgorithm field, including any parameters that go with it.
  • signatureAlgorithm is a copy of the signature algorithm identifier and any parameters that go with it (SignerInfo.signatureAlgorithm). this field only gets filled in if the attribute is placed in a SignerInfo.signedAttrs sequence.
  • macAlgorithm is a copy of the message authentication code algorithm identifier and any parameters that go with it (AuthenticatedData.macAlgorithm). this field only gets filled in if the attribute is placed in an AuthenticatedData.authAttrs sequence.

so basically exactly one of signatureAlgorithm or macAlgorithm SHALL be present. one or the other, never both, never neither 🫢

there are also some strict rules about how many values this thing can have. an algorithm protection attribute MUST have a single attribute value, even though the syntax is defined as a SET OF AttributeValue. there MUST NOT be zero or multiple instances of AttributeValue present. so it's one and only one, bestie πŸ‘‘

the attribute also has to be locked down in the right spot. the algorithm protection attribute MUST be a signed attribute or an authenticated attribute. it MUST NOT be an unsigned attribute, an unauthenticated attribute, or an unprotected attribute. no sneaking it into the unprotected lane πŸ’€

last but not least, the SignedAttributes and AuthAttributes syntax are each defined as a SET of Attributes. the SignedAttributes in a signerInfo MUST include only one instance of the algorithm protection attribute. same deal for the AuthAttributes in an AuthenticatedData: they MUST include only one instance of the algorithm protection attribute. one per container, iconic ✨


3. Verification Process

so the exact verification steps depend on what structure is being checked, but there are some common rules for comparing the two algorithm structures, and these are the big ones πŸ”₯

  • a field with a default value MUST compare as identical, whether the value is defaulted or explicitly provided. this means a binary compare of the encoded bytes is not enough πŸ™ˆ
  • okay this one is a whole saga 😭 for some algorithms, like SHA-1, the parameter value of NULL can be included in the ASN.1 encoding by some implementations and left out by others. it's up to whoever implements this attribute to decide whether the comparison for equality is satisfied in this case. the general idea is that the same implementation is expected to produce both encoded values, so this corner case should be pretty unlikely. but it's still an issue, because some implementations omit a NULL element while others encode it for some digest algorithms like SHA-1 (see the comments in Section 2.1 of [RFC3370]). it's even messier because the NULL is absent in some cases (e.g., [RFC3370]) but is required in other cases (e.g., [RFC4056]) 🌈

3.1. Signed Data Verification Changes

if a CMS validator supports this attribute, the following additional verification steps MUST be performed:

  1. the SignerInfo.digestAlgorithm field MUST be compared to the digestAlgorithm field in the attribute. if the fields are not the same (modulo encoding), then signature validation MUST fail.
  2. the SignerInfo.signatureAlgorithm field MUST be compared to the signatureAlgorithm field in the attribute. if the fields are not the same (modulo encoding), then the signature validation MUST fail.

3.2. Authenticated Data Verification Changes

if a CMS validator supports this attribute, the following additional verification steps MUST be performed:

  1. the AuthenticatedData.digestAlgorithm field MUST be compared to the digestAlgorithm field in the attribute. if the fields are not the same (modulo encoding), then authentication MUST fail.
  2. the AuthenticatedData.macAlgorithm field MUST be compared to the macAlgorithm field in the attribute. if the fields are not the same (modulo encoding), then the authentication MUST fail.

4. IANA Considerations 🌸

all identifiers are assigned out of the S/MIME OID arc.

5. Security Considerations πŸ’€

this document is designed to address the security issue of algorithm substitution for the algorithms used by the validator. at this time there is no known method to exploit this type of attack. but if the attack could succeed, then either a weaker algorithm could be swapped in for a stronger one, or an attacker could modify the parameters to change how the hashing algorithm behaves. (one example would be changing the initial parameter value for [RFC6210].) this is serious stuff, bestie, so please take it seriously 🫢

the attribute defined in this document is meant to be placed in a location that is protected by the signature or message authentication code. if it's placed in an unsigned or unauthenticated location, this attribute does not provide any extra security at all 😭

6. References

6.1. Normative References

[ASN.1-2008]: ITU-T, "ITU-T Recommendations X.680, X.681, X.682, and X.683", 2008.

[CMS]: Housley, R., "Cryptographic Message Syntax (CMS)", RFC 5652, September 2009.

[ESS-BASE]: Hoffman, P., "Enhanced Security Services for S/MIME", RFC 2634, June 1999.

[RFC2119]: Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, March 1997.

[RFC5035]: Schaad, J., "Enhanced Security Services (ESS) Update: Adding CertID Algorithm Agility", RFC 5035, August 2007.

[RFC5912]: Hoffman, P. and J. Schaad, "New ASN.1 Modules for the Public Key Infrastructure Using X.509 (PKIX)", RFC 5912, June 2010.

6.2. Informative References

[RANDOM-HASH]: Halevi, S. and H. Krawczyk, "Strengthening Digital Signatures via Random Hashing", January 2007, <http://webee.technion.ac.il/~hugo/rhash/rhash.pdf>.

[RFC3370]: Housley, R., "Cryptographic Message Syntax (CMS) Algorithms", RFC 3370, August 2002.

[RFC3447]: Jonsson, J. and B. Kaliski, "Public-Key Cryptography Standards (PKCS) #1: RSA Cryptography Specifications Version 2.1", RFC 3447, February 2003.

[RFC4056]: Schaad, J., "Use of the RSASSA-PSS Signature Algorithm in Cryptographic Message Syntax (CMS)", RFC 4056, June 2005.

[RFC5280]: Cooper, D., Santesson, S., Farrell, S., Boeyen, S., Housley, R., and W. Polk, "Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile", RFC 5280, May 2008.

[RFC6210]: Schaad, J., "Experiment: Hash Functions with Parameters in the Cryptographic Message Syntax (CMS) and S/MIME", RFC 6210, April 2011.

Appendix A. 2008 ASN.1 Module 🧚

the ASN.1 module defined here uses the 2008 ASN.1 definitions found in [ASN.1-2008]. this module contains the ASN.1 module that holds the required definitions for the types and values defined in this document. the module uses the ATTRIBUTE class defined in [RFC5912].

CMSAlgorithmProtectionAttribute
  { iso(1) member-body(2) us(840) rsadsi(113549)
    pkcs(1) pkcs-9(9) smime(16) modules(0)
    id-mod-cms-algorithmProtect(52) }
DEFINITIONS IMPLICIT TAGS ::=
BEGIN
 IMPORTS

   -- Cryptographic Message Syntax (CMS) [CMS]

   DigestAlgorithmIdentifier, MessageAuthenticationCodeAlgorithm,
   SignatureAlgorithmIdentifier
   FROM  CryptographicMessageSyntax-2009
     { iso(1) member-body(2) us(840) rsadsi(113549)
       pkcs(1) pkcs-9(9) smime(16) modules(0) id-mod-cms-2004-02(41) }

   -- Common PKIX structures [RFC5912]

   ATTRIBUTE
   FROM PKIX-CommonTypes-2009
     { iso(1) identified-organization(3) dod(6) internet(1)
       security(5) mechanisms(5) pkix(7) id-mod(0)
       id-mod-pkixCommon-02(57)};

   --
   --  The CMS Algorithm Protection attribute is a Signed Attribute or
   --  an Authenticated Attribute.
   --
   --  Add this attribute to SignedAttributesSet in [CMS]
   --  Add this attribute to AuthAttributeSet in [CMS]
   --

   aa-cmsAlgorithmProtection ATTRIBUTE ::= {
      TYPE CMSAlgorithmProtection
      IDENTIFIED BY { id-aa-cmsAlgorithmProtect }
   }

   id-aa-cmsAlgorithmProtect OBJECT IDENTIFIER ::= {
      iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1)
      pkcs9(9) 52 }

   CMSAlgorithmProtection ::= SEQUENCE {
      digestAlgorithm         DigestAlgorithmIdentifier,
      signatureAlgorithm  [1] SignatureAlgorithmIdentifier OPTIONAL,
      macAlgorithm        [2] MessageAuthenticationCodeAlgorithm
                                        OPTIONAL
   }
   (WITH COMPONENTS { signatureAlgorithm PRESENT,
                      macAlgorithm ABSENT } |
    WITH COMPONENTS { signatureAlgorithm ABSENT,
                      macAlgorithm PRESENT })

END

Author's Address πŸŽ€

Jim Schaad Soaring Hawk Consulting

EMail: ietf@augustcellars.com

πŸ“¦ where this page comes from