Subject: RE: S/MIME version number

From: "Pawling, John" <[email-masked]>
Date: Fri, 13 Apr 2001 10:52:11 -0400

Russ,

The AC syntax is an integral part of the SignedData and EnvelopedData
syntaxes, so the SignedData and EnvelopedData version numbers should be
changed to indicate the new syntaxes.  Many generic ASN.1 toolkits (such as
SNACC) decode the entire syntax in one pass (except for data included within
ANY or OCTET STRING components which require a second pass).  There is not a
straight forward means of changing the generic ASN.1 toolkit to check
version numbers "mid-stream" while decoding the syntax.  Because the AC
syntax is not included in an ANY or OCTET STRING component, it is not
practical to check the AC version number before decoding the AC using a
generic ASN.1 toolkit.  

My proposal would allow implementers to perform a simple pre-check of the
signedData or EnvelopedData hex data before calling the generic ASN.1
toolkit to decode the hex data.  There is a fixed number of bytes preceding
the version number in the ASN.1 encoded SignedData and EnvelopedData hex
data, so the processing software could simply check the fixed byte position
to determine the version number.  For signedData, if the version number is
3, then the processing software would call the ASN.1 library using the
signedData syntax including the old AC syntax.  If the version number is 4,
then the processing software would call the ASN.1 library using the
signedData syntax including the new AC syntax.  Similar pre-processing could
be performed for EnvelopedData objects. 

Of course another option is to simply use trial and error.  We could try
decoding the SignedData or EnvelopedData using the syntax including the new
AC syntax.  If we get a decode error, then we could try using the syntax
containing the old AC syntax.  I would prefer that we define a clean
strategy (i.e. new SignedData and EnvelopedData version numbers), rather
than needing to resort to trial and error.

I people prefer that the S/MIME documents import ASN.1 structures from the
PKIX documents because they are freely available.  Care needs to be taken
that the PKIX documents define equivalent ASN.1 syntaxes as the ITU-T
documents and ANSI X9 documents, assuming that interoperability is required.
As expressed in previous messages sent to the S/MIME and PKIX lists, the
current PKIX AC profile document defines an AC syntax that is not equivalent
to the v2 AC syntax defined in the 2000 X.509 Recommendation.  

===========================================
John Pawling, [email-masked]
Getronics Government Solutions, LLC
===========================================

-----Original Message-----
From: Russ Housley [mailto:[email-masked]]
Sent: Thursday, April 12, 2001 1:45 PM
To: Pawling, John
Cc: [email-masked]'
Subject: RE: S/MIME version number

John:

I understand that X.509-2000 includes updated syntax for the attribute 
Certificate (AC).  However, this structure already includes a version 
number.  The earlier syntax has v1, and the later syntax has v2.  Since 
this stricture is "self versioning," why do we need to update the version 
number in the parent structure?

Would people prefer to import structures from the PKIX documents (as 
opposed to the ITU-T and ANSI X9 documents)?  At the time RFC 2630 was 
done, PKIX did not have a profile of ACs.  Note that the PKIX AC profile 
requires the use of v2 AC syntax.

Russ

At 10:51 AM 4/9/2001 -0400, Pawling, John wrote:
>However, there is another factor to discuss related to this issue.  The
>Attribute Certificate (AC) ASN.1 syntaxes defined in the 1997 and 2000
X.509
>Recommendations are incompatible.  I believe that it is planned for the
>"son-of-RFC 2630" to import the AC syntax from the 2000 X.509
Recommendation
>rather than from the 1997 X.509 Recommendation as with RFC 2630.  This will
>result in a change to the AC syntax included in the CertificateChoices
>syntax used in the CMS SignedData and EnvelopedData syntaxes.

---

From: Russ Housley <[email-masked]>
Date: Fri, 13 Apr 2001 14:14:30 -0400

John:

I am missing something.

Let's take SignedData as an example:

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

The optional certificates field can contain certificates or attribute 
certificates.  We deprecate the use of PKCS #6 extended certificates.  As 
follows:

       CertificateSet ::= SET OF CertificateChoices

       CertificateChoices ::= CHOICE {
          certificate Certificate,                 -- See X.509
          extendedCertificate [0] IMPLICIT ExtendedCertificate,
                                                   -- Obsolete
          attrCert [1] IMPLICIT AttributeCertificate }
                                                   -- See X.509 and X9.57

The certificate choice can be a v1, v2, or v3 X.509 public key 
certificate.  One must examine the version field within the certificate to 
determine the format.

At the time RFC 2630 was written, only v1 attribute certificates were 
defined.  Now that v2 attribute certificates have been defined, one must 
examine the version field to determine the format.  This is completely 
parallel to the public key certificate situation.

I am missing the reason that you think that the version number in 
SignedData needs to reflect the possibility that v2 attribute 
certificate.  If a v4 public key certificate were to be defined (hopefully 
it will not be needed), I would not expect to increment the version number 
either.

Now, to the toolkit issue.

I realize that implementation would be more straightforward if the version 
number proceeded an OCTET STRING or an ANY.  But neither public key 
certificates, attribute certificate, nor PKCS #7 were specified that 
way.  However, there are several implementations techniques that allow 
correct handling.  I will describe two.  There are many more.

First, two-pass decode.  In this alternative, a very ASN.1 simple structure 
is specified to extract the version.  Consider the SignedData syntax 
included above. The structure might look like this:

       SignedDataVersionCheck ::= SEQUENCE {
         version CMSVersion,
         theRest ANY }

While this might generate a warning that extra fields are present, it 
should return the version number.  The version can be examined to determine 
whether or not the provided version is supported.

Second, check if decode fails.  In this alternative, just try the 
decode.  If it fails, then examine version numbers (perhaps using the 
technique discussed above) to determine if the blob is malformed or it uses 
unsupported versions.

I prefer this approach to the first one because the extra decode operations 
are only performed if there is a problem.  Thus, successful messages are 
not encumbered with the extra processing.  Optimize for success.

What do other implementors think?

Russ