Subject: Re: [smime] Problems with versions

From: Peter Gutmann <[email-masked]>
Date: Fri, 6 May 2022 11:59:31 +0000

Russ Housley <[email-masked]> writes:

>I realize that your example is hypothetical.  However it cannot happen under
>RFC 5652.

It can't happen if the spec never, ever changes, but it will happen if changes
are necessary at some point, e.g. due to PQC.  As I mentioned in my original
message, this is exactly what the OpenPGP folks have run into right now as
they're trying to update RFC 4880, amd which the TLS folks ran into in spades
and had to add all sorts of kludges to deal with.  I was pointing out that if
there's ever a need to update CMS, or even there isn't and someone figures out
what a "certificate with a type of other" or "crl with a type of other" is for
the current RFC, it'll run into the same issues that TLS and OpenPGP have run
into.

From looking at the current text:

  IF ((certificates is present) AND
            (any certificates with a type of other are present)) OR
            ((crls is present) AND
            (any crls with a type of other are present))
         THEN version MUST be 5
         ELSE
            IF (certificates is present) AND
               (any version 2 attribute certificates are present)
            THEN version MUST be 4
            ELSE
               IF ((certificates is present) AND
                  (any version 1 attribute certificates are present)) OR
                  (any SignerInfo structures are version 3) OR
                  (encapContentInfo eContentType is other than id-data)
               THEN version MUST be 3
               ELSE version MUST be 1

what it's saying is:

  IF a certificate or CRL type that no-one can define is present 
    THEN version MUST be 5
  ELSE
    IF an attribute certificate but not quite the same attribute 
       certificate that would require a version of 3 is present
      THEN version MUST be 4
    ELSE
      IF an attribute certificate is present OR
         (some stuff that seems irrelevant at this point in the 
          processing)
         THEN version MUST be 3
      ELSE 
         version MUST be 1

which simplifies to:

      IF an attribute certificate is present 
         THEN version MUST be 3
      ELSE 
         version MUST be 1

although even then I can't see why the presence of an attribute certificate
somewhere further down or a non-data eContentType would require a change in
the SignedData version.

To illustrate why requirements to set arbitrary implementation-breaking
versions is a problem, here's the SignedData from PKCS #7 in 1992:

SignedData ::= SEQUENCE {
     version Version,
     digestAlgorithms DigestAlgorithmIdentifiers,
     contentInfo ContentInfo,
     certificates [0] IMPLICIT ExtendedCertificatesAndCertificates OPTIONAL,
     crls [1] IMPLICIT CertificateRevocationLists OPTIONAL,
     signerInfos SignerInfos }

And here's SignedData from RFC 5652 (and in between 2630, 3369, and 2853) as
it applies thirty years later:

SignedData ::= SEQUENCE {
     version CMSVersion,
     digestAlgorithms DigestAlgorithmIdentifiers,
     encapContentInfo EncapsulatedContentInfo,
     certificates [0] IMPLICIT CertificateSet OPTIONAL,
     crls [1] IMPLICIT RevocationInfoChoices OPTIONAL,
     signerInfos SignerInfos }

Apart from some fiddling with the ASN.1, e.g. deprecation of obsolete ASN.1
'88 forms, and changing of names, it's the same thing.  SignedData version 1
is the same as SignedData version 2 is the same as SignedData version 3 is the
same as SignedData version 4 is the same as SignedData version 5, the only
thing that's changed each time is a requirement to (potentially) set the
version field to something that ensures an existing implementation can't
process it any more.

Peter.