Subject: Re: [Anima] [lamps] EST CSRATTRS specifying the SAN

From: Michael Richardson <[email-masked]>
Date: Mon, 05 Jul 2021 14:37:31 -0400

David von Oheimb <[email-masked]> wrote:
    > would have been more apparent.

well, you just used ASN.1 we didn't understand to explain other ASN.1 we
didn't understand :-)

What I took away was that my interpretation was not quite right for getting a
explicit value.

    > Further, RFC 7030 section 4.5.2 does not cover the fact that names and
    > name components in a CSR may be part of not only various X.509
    > extensions such as SAN (which are to be encoded via the extra
    > indirection of the extensionRequest OID) but also of the subject
    > field/attribute of type (Distinguished)Name.

Could you construct an example? Perhaps we could slip it in as errata.

    > At least a more comprehensive example would have been very helpful to
    > clarify the details of the intended encoding, and likewise any serious
    > reference/example implementation, for instance in Cisco's libEST, which
    > has remained extremely sketchy regarding the csrattrs topic.

Are there examples in libest that we can use?
Is there unit test code in there that could be exercised to validate other examples?

Are we back to redoing this in JSON?

--
Michael Richardson <[email-masked]>   . o O ( IPv6 IøT consulting )
           Sandelman Software Works Inc, Ottawa and Worldwide

---

From: Russ Housley <[email-masked]>
Date: Mon, 5 Jul 2021 15:41:40 -0400

David:

This proposed "isomorphic" definition:

  CsrAttrs ::= SEQUENCE {
        oids          SET OF OBEJECT IDENTIFIER
        attributes    SET OF Attribute{{ IOSet }}
    }

Does NOT produce the same bits on the wire as the structure defined in RF 7030.

Further, the use of SEQUENCE in RFC 7030 was to avoid the need for the sort that is imposed when DER encoding SET.

Russ

> On Jul 5, 2021, at 2:26 PM, David von Oheimb <[email-masked]> wrote:
> 
> The ASN.1 declaration of the Attribute type, which is the core of CsrAttrs type given in RFC 7030 section 4.5.2:
> 
>   CsrAttrs ::= SEQUENCE SIZE (0..MAX) OF AttrOrOID
> 
>   AttrOrOID ::= CHOICE (oid OBJECT IDENTIFIER, attribute Attribute }
> 
>   Attribute { ATTRIBUTE:IOSet } ::= SEQUENCE {
>         type   ATTRIBUTE.&id({IOSet}),
>         values SET SIZE(1..MAX) OF ATTRIBUTE.&Type({IOSet}{@type}) }
> has been copied over from PKCS#10: https://datatracker.ietf.org/doc/html/rfc2986#section-4 <https://datatracker.ietf.org/doc/html/rfc2986#section-4>.
> Since it is pretty incomprehensible for ASN.1 non-experts (including myself), the reader has to rely in the interpretation following it in prose and on the example given, but unfortunately both of them are not very clear. In particular, the meaning of the values field or of a "value" in the given text remains ambiguous or even misleading. In the given example,
> 
>          Attribute:  type = extensionRequest (1.2.840.113549.1.9.14)
>                      value = macAddress (1.3.6.1.1.1.1.22)
> the "value" is not a MAC address but the OID of MAC addresses. This corresponds to what is explained as follows:
>    Requests for descriptive information from the client are made by an attribute, to be
>    represented as Attributes of the CSR, with a type indicating the
>    [RFC2985 <https://datatracker.ietf.org/doc/html/rfc2985>] extensionRequest and the values indicating the particular
>    attributes desired to be included in the resulting certificate's extensions.
> AFAICS, the key to understanding how to encode a concrete value (such as a MAC address, a SAN value, etc.) is to appreciate the following sentence, which provides the key idea for reusing the  Attribute type:
>   The structure of the CSR Attributes Response SHOULD, to the greatest
>    extent possible, reflect the structure of the CSR it is requesting.
> So in essence, the CSR attribute response is to be formed like the attributes part of a template PCKS#10 CertificationRequestInfo structure and simply can be given exactly as in a PKCS#10 CSR structure including any (actual) values, yet with two generalizations:
> Actual values may be left out, and this way are requested to be filled in by the client/EE.
> Additional OIDs may be given for requesting the use of the challengePassword and for specifying algorithms (such as the expected type of the public key).
> Note that under the (fair) assumption that the order of the AttrOrOID entries in the CsrAttrs sequence does not play a role, and glossing over some Attribute subtype peculiarities, the CsrAttrs type is isomorphic to 
> 
>   CsrAttrs ::= SEQUENCE {
>         oids          SET OF OBEJECT IDENTIFIER
>         attributes    SET OF Attribute{{ IOSet }}
>     }
>   Attribute { ATTRIBUTE:IOSet } ::= SEQUENCE {
>         type   ATTRIBUTE.&id({IOSet}),
>         values SET SIZE(1..MAX) OF ATTRIBUTE.&Type({IOSet}{@type})
>   }
> from which the similarity with a classical PKCS#10 structure:
>    CertificationRequestInfo ::= SEQUENCE {
>         version       INTEGER { v1(0) } (v1,...),
>         subject       Name,
>         subjectPKInfo SubjectPublicKeyInfo{{ PKInfoAlgorithms }},
>         attributes    [0] Attributes{{ CRIAttributes }}
>    }
> 
>    CRIAttributes  ATTRIBUTE  ::= {
>         ... -- add any locally defined attributes here -- }
> 
>    Attributes { ATTRIBUTE:IOSet } ::= SET OF Attribute{{ IOSet }}
> 
>    Attribute { ATTRIBUTE:IOSet } ::= SEQUENCE {
>          type   ATTRIBUTE.&id({IOSet}),
>          values SET SIZE(1..MAX) OF ATTRIBUTE.&Type({IOSet}{@type})
>    }
> Further, RFC 7030 section 4.5.2 does not cover the fact that names and name components in a CSR may be part of not only various X.509 extensions such as SAN (which are to be encoded via the extra indirection of the extensionRequest OID) but also of the subject field/attribute of type (Distinguished)Name.
> 
> At least a more comprehensive example would have been very helpful to clarify the details of the intended encoding, and likewise any serious reference/example implementation, for instance in Cisco's libEST, which has remained extremely sketchy regarding the csrattrs topic.
>     David
> 
> 
> 
> On 21.06.21 19:29, Sean Turner wrote:
>> Sorry for just getting to this now. I haven’t read upstream so if this gets answer there oops.
>> 
>>> On Jun 9, 2021, at 16:15, Michael Richardson <[email-masked]> <mailto:[email-masked]> wrote:
>>> 
>>> Signed PGP part
>>> 
>>> Eliot has suggested that:
>>>      https://datatracker.ietf.org/doc/html/rfc7030#section-4.5.2 <https://datatracker.ietf.org/doc/html/rfc7030#section-4.5.2>
>>> does not appear to allow the returned CSR Attributes to contain a value.
>>> Please correct me if I'm understanding the problem wrong.
>> Oh yeah it does! The whole point of CSRattrs is to allow the client to say “hey RA/CA what do you want my CSR to look like”. The response could just be an OID or it can be an actual attribute with some values:
>> 
>>   Requests for descriptive information from the client are made
>>   by an attribute, to be represented as Attributes of the CSR, with
>>   a type indicating the [RFC2985] extensionRequest and the
>>   values indicating the particular attributes desired to be included
>>   in the resulting certificate’s extensions. 
>> 
>> Note the word “values” above.
>> 
>> I also figured that there might be brain dead EEs out there so instead of returning a string of attributes the EST server could just return the entire CSR - see Appendix B of RFC 8295. That way the EE would only need sign the request (for PoP).
>> 
>>> RFC8994 assignment of IPv6 ULA can not, as far as I can understand, work
>>> without assigning a value.  The Registrar must allocate a prefix for the new
>>> ACP node, and this has to go into the CSR in order for the CA to sign it.
>>> 
>>> (Yes, the Registrar has to *check* that the CSR contains the right value along
>>> the way too.  Yes, if the Registrar is ALSO the CA, then it can shortcut, but
>>> that's not in general true)
>>> 
>>> My unit testing code is at:
>>>  https://github.com/AnimaGUS-minerva/fountain/blob/master/spec/models/csr_attributes_spec.rb <https://github.com/AnimaGUS-minerva/fountain/blob/master/spec/models/csr_attributes_spec.rb>
>>> 
>>> 
>>> I found the ASN.1 code in section 4.5.2 beyond my understanding, so I muddled
>>> through, since fortunately, there was an example.
>>> 
>>>   CsrAttrs ::= SEQUENCE SIZE (0..MAX) OF AttrOrOID
>>>   AttrOrOID ::= CHOICE (oid OBJECT IDENTIFIER, attribute Attribute }
>>>   Attribute { ATTRIBUTE:IOSet } ::= SEQUENCE {
>>>        type   ATTRIBUTE.&id({IOSet}),
>>>        values SET SIZE(1..MAX) OF ATTRIBUTE.&Type({IOSet}{@type}) }
>>> 
>>> What I think that this says is that one can have:
>>>  a) a Sequence of stuff.
>> a sequence of stuff that might be empty
>> 
>>>  b) the stuff is either an OID.
>>>  c) or the stuff is a SEQUENCE [ type, value ].
>>> The complicated &id... is just saying that when you have some attribute type
>>> "FOO", then you can have the things that would be valid as values.  I'm
>>> actually rather amazed at this level of meta-programming. (Can CDDL do that?)
>> So this is the parameterized ASN.1 syntax. What you could so is define an IOSet of attributes. These attributes value values. But, yeah if it’s an attribute it’s an OID and the associated syntax. e.g.,
>> 
>> pKCS7PDU ATTRIBUTE ::= {
>>        WITH SYNTAX ContentInfo
>>        ID pkcs-9-at-pkcs7PDU
>>        }
>> 
>>    pkcs-9-at-pkcs7PDU OBJECT IDENTIFIER ::= {
>>        iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs9(9)
>>        pkcs-9-at(25) 5
>>        }
>> 
>> The OID would be 1.2.840.113549.1.9.25.5
>> 
>> and the values (really only one) is:
>> 
>> PKIData ::= SEQUENCE {
>>        reqSequence        SEQUENCE SIZE(0..MAX) OF TaggedRequest
>>        }
>> 
>>> An example is provided:
>>>   MEEGCSqGSIb3DQEJBzASBgcqhkjOPQIBMQcGBSuBBAAiMBYGCSqGSIb3DQEJDjEJ
>>>   BgcrBgEBAQEWBggqhkjOPQQDAw==
>>> 
>>> %echo 'MEEGCSqGSIb3DQEJBzASBgcqhkjOPQIBMQcGBSuBBAAiMBYGCSqGSIb3DQEJDjEJBgcrBgEBAQEWBggqhkjOPQQDAw==' | base64 -d | dumpasn1 -
>>>  0  65: SEQUENCE {
>>>  2   9:   OBJECT IDENTIFIER challengePassword (1 2 840 113549 1 9 7)
>>> 13  18:   SEQUENCE {
>>> 15   7:     OBJECT IDENTIFIER ecPublicKey (1 2 840 10045 2 1)
>>> 24   7:     SET {
>>> 26   5:       OBJECT IDENTIFIER secp384r1 (1 3 132 0 34)
>>>       :       }
>>>       :     }
>>> 33  22:   SEQUENCE {
>>> 35   9:     OBJECT IDENTIFIER extensionRequest (1 2 840 113549 1 9 14)
>>> 46   9:     SET {
>>> 48   7:       OBJECT IDENTIFIER '1 3 6 1 1 1 1 22'
>>>       :       }
>>>       :     }
>>> 57   8:   OBJECT IDENTIFIER ecdsaWithSHA384 (1 2 840 10045 4 3 3)
>>>       :   }
>>> 
>>> 
>>> At 2, we have the OID "challengePassword", which tells the client that this
>>> attribute should be included (that's [b]).
>>> At 13-26, we have an attributed, ecPublicKey, with a *value* secp384r1.
>>> This tells the client what kind of things to sign with.  (that's [c])
>>> At 33, we have extensionRequest with oid value 1.3.6.1.1.1.1.22. (also [c])
>>> Finally, at 57, we have just the attribute ecdsaWithSHA384, which is telling
>>> the client to use SHA2-384.
>>> 
>>> In order to get this all right, I used the example above, made sure I could
>>> decode it, and then made sure that I could encode exactly that.
>> Yep!
>> 
>>> I have an example building the subjectAltName rfc822Name (yes, my code hasn't
>>> caught up to otherName as specified in RFC8994 yet) which is:
>>> 
>>> obiwan-[projects/pandora/fountain](2.6.6) mcr 10263 %dumpasn1 tmp/hellobulb0.der
>>>  0  32: SEQUENCE {
>>>  2  30:   SEQUENCE {
>>>  4   3:     OBJECT IDENTIFIER subjectAltName (2 5 29 17)
>>>  9  23:     SET {
>>> 11  21:       SEQUENCE {
>>> 13  19:         [1] {
>>> 15  17:           UTF8String [email-masked] <mailto:[email-masked]>'
>>>       :           }
>>>       :         }
>>>       :       }
>>>       :     }
>>>       :   }
>>> 
>>> I don't know what the [1] is actually, but possibly that's the rfc822Name.
>>> Yup, it is:
>>>  #        rfc822Name                      [1]     IA5String,   <-- this one
>> The one is the tag.
>> 
>>> So, I think that I'm entirely within spec for CSR Attributes, and I'd like to
>>> understand more from Owen and Eliot as to what problems they are having with
>>> CSR Attributes.
>>> 
>>> Eliot has suggested we do it all in JSON (CBOR?), and I would certainly be
>>> happy with that.
>>> 
>>> --
>>> Michael Richardson <[email-masked]> <mailto:[email-masked]>   . o O ( IPv6 IøT consulting )
> _______________________________________________
> Spasm mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/spasm

---

From: Michael Richardson <[email-masked]>
Date: Tue, 06 Jul 2021 09:59:07 -0400

Hi, if David von Oheimb is correct that we've gotten use this
Type=SpecificValue for the CSRATTRS wrong, then this certainly affects
RFC8994, which requires that the pledge enroll with a specific otherName,
allocated by the Registrar.

I don't think that we ever got reliably to /san when interoperating Registrars in
2018's round of BRSKI testing. (Remember all those base64 issues...)
I expect to attempt this again between Registrar's again this month.
So, at least, we'll know if RFC8994/RFC8995 implementors got it consistent.
(Whether RIGHT or WRONG).

One answer is to just axe /csrattrs, and assume that the RA/CA will sort
things out.   Eliot has proposed to do away with the ASN.1 in /CSRATTRS, and
do JSON and/or CBOR here instead.  It certainly would be trivial to do,
and draft-ietf-cbor-tags-oid-08 could help here.

It's a bit of a toss-up of which bit of code you want to extend.

LAMPS chairs: can we have ten minutes for this discussion on the Thursday
      Session III meeting at IETF111?
      The Monday Session II is conflicted with ANIMA.

I'm gonna voluntold Eliot to lead this discussion :-)

---

From: Russ Housley <[email-masked]>
Date: Tue, 6 Jul 2021 14:44:50 -0400

> I'm gonna voluntold Eliot to lead this discussion :-)

Yes, I'll add it.

Russ

---

From: Eliot Lear <[email-masked]>
Date: Tue, 6 Jul 2021 21:00:53 +0200

So voluntold.

---

From: "Blumenthal, Uri - 0553 - MITLL" <[email-masked]>
Date: Wed, 7 Jul 2021 12:43:07 +0000

Yet what can be done is to (ab-)use one or more of those Attribute structures as elements of CsrAttrs to specify concrete values for individual sub-components of the subject DN, 
namely single attributes of RDNs, e.g., 
             SEQUENCE {
               OBJECT IDENTIFIER commonName (2 5 4 3)
               UTF8String "myHostname"
               }
and 
             SEQUENCE {
               OBJECT IDENTIFIER serialNumber (2 5 4 5)
               PrintableString "JABA1234'
               }
Note that in this way one cannot express a particular desired structure of RDNs for the subject DN.

At least the above is implementable.

(BTW, the general structure of DNs being a sequence or RDNs, each of which can contain a set of name attributes, see https://datatracker.ietf.org/doc/html/rfc2253#section-2
is a rather weird thing that is hardly understood and not always implemented correctly/completely, but that's a different story).

Is that “weird thing” even necessary?  I feel like dumping a lot of accumulated crust and crud that proved to be more trouble than it seems worth…