Subject: [lamps] EST CSR attrs discussion

From: Dan Harkins <[email-masked]>
Date: Thu, 29 Jul 2021 11:31:17 -0700

Hi,

   Sorry, I wasn't aware that this issue was being discussed and I wasn't
on the lamps/spasm list. But I'm largely responsible-- i.e. to blame-- for
the CSR Attrs text in RFC 7030 so perhaps I can try and explain.

   The intent of the CSR Attrs request is for the RA to ask the client
to construct the CSR in some particular way, not to impose values on
particular fields.

   As a for-instance, the RA could ask the client to:

    1. generate a public key in the NIST p384 curve;
    2. use ECDSA w/SHA384 to sign
    3. include the challengePassword
    4. include an extension with the device's serial number, a subject alt
       name, and its favorite drink

by sending the following base64-encoded blob:

ME4GCSqGSIb3DQEJBzASBgcqhkjOPQIBMQcGBSuBBAAiMCMGCSqGSIb3DQEJDjEWBgNVBAUGA1UdEQYKCZImiZPyLGQBBQYIKoZIzj0EAwM

That gets ASN.1 decoded as:

SEQUENCE (4 elem)
   OBJECT IDENTIFIER 1.2.840.113549.1.9.7 challengePassword (PKCS #9)
   SEQUENCE (2 elem)
     OBJECT IDENTIFIER 1.2.840.10045.2.1 ecPublicKey (ANSI X9.62 public 
key type)
     SET (1 elem)
       OBJECT IDENTIFIER 1.3.132.0.34 secp384r1 (SECG (Certicom) named 
elliptic curve)
   SEQUENCE (2 elem)
     OBJECT IDENTIFIER 1.2.840.113549.1.9.14 extensionRequest (PKCS #9 
via CRMF)
     SET (3 elem)
       OBJECT IDENTIFIER 2.5.4.5 serialNumber (X.520 DN component)
       OBJECT IDENTIFIER 2.5.29.17 subjectAltName (X.509 extension)
       OBJECT IDENTIFIER 0.9.2342.19200300.100.1.5 (favorite drink)
   OBJECT IDENTIFIER 1.2.840.10045.4.3.3 ecdsaWithSHA384 (ANSI X9.62 
ECDSA algorithm with SHA384)

And the client produces a CSR with an extension that gives its serial 
number,
some alternative name, and whatever drink it prefers. The idea isn't 
that the
RA would say, "your serial number is 279372 and you like scotch", it's "what
is your serial number and favorite drink?".

   If the RA wanted a particular length of RSA key, let's say of 3072 
bits, to
sign with a hash function appropriate for that bit length, and include the
challengePassword it would ask thusly:

MCkGCSqGSIb3DQEJBzARBgkqhkiG9w0BAQExBAICDAAGCSqGSIb3DQEBCw==

which gets decoded as:

SEQUENCE (3 elem)
   OBJECT IDENTIFIER 1.2.840.113549.1.9.7 challengePassword (PKCS #9)
   SEQUENCE (2 elem)
     OBJECT IDENTIFIER 1.2.840.113549.1.1.1 rsaEncryption (PKCS #1)
     SET (1 elem)
       INTEGER 3072
   OBJECT IDENTIFIER 1.2.840.113549.1.1.11 sha256WithRSAEncryption (PKCS #1)

   The idea is, this is a request to the client on how to generate a CSR in
the form that the CA expects/wants. One asks what a subject alternative name
would be, it doesn't impose one on the client.

   That was the intent anyway. And that's how I implemented it in my EST
reference implementation.

   regards,

   Dan.

-- 
"The object of life is not to be on the side of the majority, but to
escape finding oneself in the ranks of the insane." -- Marcus Aurelius

---

From: David von Oheimb <[email-masked]>
Date: Thu, 29 Jul 2021 22:24:32 +0200

Hi Dan,

thank you for your response, which helps clarifying the intention of the 
EST CSRAttrs feature.

At least it makes clear that there was no aim to to give the option to 
provide concrete values for attributes.
They may have have been useful/needed, though, to state for instance 
that the subject DN should include a certain organization name, 
location, etc.
Note that there are CAs around where policies can be defined giving 
constrains on such fields that must be adhered to by cert requestors.

It also confirms my criticism that the whole construct is entirely 
ad-hoc. That is, the attributes provided do not have a clear meaning.
There are just some examples that give some hints how certain OIDs and 
related values can be interpreted.
Since there is no systematic definition, the implementors of the server 
and client side need to seek agreement beforehand on each attribute 
potentially used.
There are also ambiguities on the values - for instance, it is intuitive 
that the integer that may follow the rsaEncryption OID should be 
interpreted as the modulus size in bits, but it could also be seen as 
the public exponent to use, for instance, or the width of a SHA 
algorithm to use for RSA signatures, or whatever.
Also the mix of OIDs in the extensionRequest sub-sequence is a bit 
strange, where e.g, the serialNumber OID makes little sense within an 
X.509 extension.
It was likely meant as a specifier of an RDN to include in the subject 
to be certified, but such a guessing could go wrong, and technically it 
would fit also in other contexts, for instance an issuer field 
potentially included in the CSR.
Moreover, there is the possibility to give conflicting requirements, 
such as ecdsaWithSHA384 and SHA256, and there is no specification how to 
avoid or handle such situations.
Still with some goodwill the feature can be used, which boils down to 
having to hard-code the interpretation consistently in all potential 
client and the server(s). Yet this is not interoperable.

Regards,
     David

---

From: Dan Harkins <[email-masked]>
Date: Thu, 29 Jul 2021 13:47:20 -0700

Hi David,

   CSR Attrs isn't the tool for you obviously. If you want to impose 
some naming
structure on particular fields of the CSR on the entity constructing a 
CSR then
you'll have to define your own tool with an unambiguous systematic 
definition,
making sure it fits other contexts and doesn't allow conflicting 
requirements.
I'm excited to see it!

   Dan.

On 7/29/21 1:24 PM, David von Oheimb wrote:
> Hi Dan,
>
> thank you for your response, which helps clarifying the intention of 
> the EST CSRAttrs feature.
>
> Since there is no systematic definition, the implementors of the 
> server and client side need to seek agreement beforehand on each 
> attribute potentially used.
> There are also ambiguities on the values - for instance, it is 
> intuitive that the integer that may follow the rsaEncryption OID 
> should be interpreted as the modulus size in bits, but it could also 
> be seen as the public exponent to use, for instance, or the width of a 
> SHA algorithm to use for RSA signatures, or whatever.
> to be certified, but such a guessing could go wrong, and technically 
> it would fit also in other contexts, for instance an issuer field 
> such as ecdsaWithSHA384 and SHA256, and there is no specification how 
> to avoid or handle such situations.
>>     OBJECT IDENTIFIER 1.2.840.10045.2.1 ecPublicKey (ANSI X9.62 
>> public key type)
>>     SET (1 elem)

---

From: David von Oheimb <[email-masked]>
Date: Fri, 30 Jul 2021 08:01:30 +0200

Hi Dan,

On 29.07.21 22:47, Dan Harkins wrote:
> CSR Attrs isn't the tool for you obviously.

yes, and unfortunately also others have their difficulties with it, as 
the e-mail discussion that we recently had here shows.
Part of the trouble is the verbatim but in-consequent re-use of the 
rather incomprehensible ASN.1 declaration from RFC 2986:

   Attribute { ATTRIBUTE:IOSet } ::= SEQUENCE {
         type   ATTRIBUTE.&id({IOSet}),
         values SET SIZE(1..MAX) OF ATTRIBUTE.&Type({IOSet}{@type}) }

In RFC 7030 you gave a very good and useful design idea:

   The structure of the CSR Attributes Response SHOULD, to the greatest
    extent possible, reflect the structure of the CSR it is requesting.

but for some reason this was not really followed there.

> If you want to impose some naming structure on particular fields of 
> the CSR on the entity constructing a CSR then

Indeed, and as I wrote early this month, this would have been possible 
to do in a rather straightforward way.
To be more concrete: you could have taken the relevant portions of

    CertificationRequestInfo ::= SEQUENCE {
         version       INTEGER { v1(0) } (v1,...),
         subject       Name,
         subjectPKInfo SubjectPublicKeyInfo{{ PKInfoAlgorithms }},
         attributes    [0] Attributes{{ CRIAttributes }}
    }

    CertificationRequest ::= SEQUENCE {
         certificationRequestInfo CertificationRequestInfo,
         signatureAlgorithm AlgorithmIdentifier{{ SignatureAlgorithms }},
         signature          BIT STRING
    }

for instance as follows:

    CsrAttrSpec ::= SEQUENCE {
         subject          Name OPTIONAL,
         subjectPKAlg [0] PKInfoAlgorithms OPTIONAL,
         attributes       Attributes{{ CRIAttributes }},
         signatureAlg     AlgorithmIdentifier{{ SignatureAlgorithms }} OPTIONAL
    }

and then specified that concrete values of given attributes can be left 
out (or replaced by empty strings)
in order to indicate that the client is supposed to fill them in.
This would have provided a straightforward and unambiguous way of 
specifying CSR contents, optionally including values,
and indirectly would have provided a way of avoiding/handling conflicts 
in the same way as (hopefully) done for PKCS#10.

> I'm excited to see it!

See above.

The only place that I am aware of where the above idea has been followed 
is the reuse of the CRMF cert request template structure
for specifying CSR attributes in CMP: 
https://datatracker.ietf.org/doc/html/draft-ietf-lamps-lightweight-cmp-profile#section-4.3.3 
<https://datatracker.ietf.org/doc/html/draft-ietf-lamps-lightweight-cmp-profile#section-4.3.3>

     David

>> At least it makes clear that there was no aim to give the option to 
>> There are just some examples that give some hints how certain OIDs 
>> and related values can be interpreted.
>> be seen as the public exponent to use, for instance, or the width of 
>> a SHA algorithm to use for RSA signatures, or whatever.
>> It was likely meant as a specifier of an RDN to include in the 
>> subject to be certified, but such a guessing could go wrong, and 
>> technically it would fit also in other contexts, for instance an 
>> issuer field potentially included in the CSR.
>> clients and the server(s). Yet this is not interoperable.
>>
>> Regards,
>>     David
>>
>>
>>
>>>       OBJECT IDENTIFIER 1.3.132.0.34 secp384r1 (SECG (Certicom) 
>>> named elliptic curve)
>>>   SEQUENCE (2 elem)
>>>     OBJECT IDENTIFIER 1.2.840.113549.1.9.14 extensionRequest (PKCS 
>>> #9 via CRMF)
>>>     SET (3 elem)
>>> And the client produces a CSR with an extension that gives its 
>>> serial number,

---

From: Eliot Lear <[email-masked]>
Date: Fri, 30 Jul 2021 08:24:16 +0200

Yes, this was my understanding as well.  In our implementation we did 
indeed end up having a backchannel to the CA for fields for which the RA 
had the content.  But I'm not sure it's the right long term approach, 
since that code can't be easily ported.  What I conclude, tho, is that 
the structure is a bit opaque, and really could stand for further 
elaboration, since it does seem one CAN specify values.  The best way to 
do that is probably a draft, aiming toward informational, but I'm out of 
bandwidth at the moment.

Eliot

---

From: David von Oheimb <[email-masked]>
Date: Sat, 31 Jul 2021 13:53:11 +0200

P.S. I've just checked: Also PKCS#10 (RFC 2986 and 5967) fails to
specify how to avoid or handle conflicting attributes.
Yet this can be done easily (like done, e.g., for X.509v3 extensions in
RFC 5280): there must not be more than one instance of a particular
attribute.

Regarding the example of potentially conflicting requirements I gave as
part of my below criticism of RFC 7030 section 4.5.2
<https://datatracker.ietf.org/doc/html/rfc7030#section-4.5.2>,
those kinds of conflicts cannot happen for the solution I sketched
yesterday because it provides only one place to specify a public-key
algorithm or a signature algorithm, which prevents contradicting values.

    David

On 30.07.21 08:01, David von Oheimb wrote:
> and then specified that concrete values of given attributes can be
> left out (or replaced by empty strings)
> and indirectly would have provided a way of avoiding/handling
> conflicts in the same way as (hopefully) done for PKCS#10.
>
>> I'm excited to see it!
>
> See above.
>
> The only place that I am aware of where the above idea has been
> followed is the reuse of the CRMF cert request template structure
>>> strange, where e.g, the serialNumber OID makes little sense within
>>> an X.509 extension.
>>> such as ecdsaWithSHA384 and SHA256, and there is no specification
>>> how to avoid or handle such situations.
>>> Still with some goodwill the feature can be used, which boils down
>>> to having to hard-code the interpretation consistently in all
>>> potential clients and the server(s). Yet this is not interoperable.
>>>
>>> Regards,
>>>     David
>>>
>>>
>>>
>>>> some alternative name, and whatever drink it prefers. The idea
>>>> isn't that the
>>>>   If the RA wanted a particular length of RSA key, let's say of
>>>> 3072 bits, to