Subject: Re: [COSE] draft-ietf-cose-x509-07 and x5u header

From: Ivaylo Petrov <[email-masked]>
Date: Sun, 1 Nov 2020 19:51:22 +0100

Hello Laurence,

I am confident this discussion has been useful for the understanding of
everyone, so thank you for starting it! Do not hesitate to suggest text if
you believe anything needs to be explained in more details regarding why
some attributes need to be protected and why others do not.

Thanks,
Ivaylo

On Fri, Oct 23, 2020 at 9:02 PM Laurence Lundblade <[email-masked]>
wrote:

> OK. Got it. Thanks for writing it out.
>
> I think that means identification of an end-entity cert must usually be
> covered by the signature. Since x5t and x5chain identify end-entity certs,
> they should be protected headers. From an attackers point of view the
> unprotected headers can be manipulated to the same result as an x5u if it
> were unprotected.
>
> It is spelled out clearly here in Key Identification in RFC 7517
> <https://tools.ietf.org/html/rfc7515#section-6> (JWS). Seems like
> cose-x509 needs similar text.
>
> It seems like you could combine a protected x5t with an unprotected x5u to
> get the same result. Fetch the cert with x5u, then make sure it is right
> with x5t.
>
> I spent some time reading CMS, RFC 5652. It does not seem to address this.
> The SignerIdentifier which identifies the end-entity cert does not seem
> to be covered by the signature. This seems like an omission in CMS.
>
> If I’d read RFC 7515 before I read cose-x509, I would have been much less
> confused and caused a lot less trouble here.
>
> LL
>
>
>
> On Oct 22, 2020, at 2:18 PM, Benjamin Kaduk <[email-masked]> wrote:
>
> On Thu, Oct 22, 2020 at 01:56:58PM -0700, Laurence Lundblade wrote:
>
> Below...
>
> On Oct 22, 2020, at 12:12 PM, Benjamin Kaduk <[email-masked]> wrote:
>
> Hi Laurence,
>
> On Thu, Oct 22, 2020 at 11:56:24AM -0700, Laurence Lundblade wrote:
>
>
> On Oct 22, 2020, at 8:21 AM, Benjamin Kaduk <[email-masked]> wrote:
>
> On Mon, Oct 19, 2020 at 11:40:33AM -0700, Laurence Lundblade wrote:
>
> I’m trying to understand why the x5u header must be a COSE protected
> header parameter and in general what the expected use of this header is.
>
> My understanding is that it the relying party that is validating the cert
> chain is the one doing the HTTP fetching.
>
> In the case of application/pkix-cert, then only one DER cert is returned
> and that is the end-entity cert.
>
> My expectation for the way this would work is:
> - The relying party would use HTTP to with the x5u URL to fetch the
> end-entity cert
> - The relying party would have a trust anchor previously configured
> - The certs in the chain between the end-entity are either already possess
> by the relying party or are in the x5bag header
> - Then it is just a straight forward chain formation and validation.
>
> In this use, there is no requirement for security of the URL or for use of
> TLS to fetch it. All the necessary security is provided by standard chain
> validation.
>
> So why is there a requirement that the header be protected and that
> TLS/DTLS be used?
>
> Further, wouldn't the header protection be a form of self signing since
> the private key used to sign the header corresponds to the public key that
> is being fetched?
>
>
> It is in some sense a form of self-signing, yes.  But TLS (or equivalent)
> is still needed for fetching the certificate in order to verify that the
> *certificate* received is the one intended, not a different certificate
> that wraps the same public key.  There are plenty of attacks if you swap
> out the certificate for one with different key usage, SAN, etc.
> You might argue that it's hard to get a different cert (with
> attacker-controlled contents) for the same public key if the attacker
> doesn't have access to the corresponding private key, but that's not a very
> reliable security control.
>
>
> Hi Ben,
>
> It seems like your are interpreting the x5u header to be for the fetching
> of a single validated end-entity certificate. Some remote service did the
>
>
> I do not believe I am doing so.  The TLS (or other) authentication of the
> URI target does not inherently stand in for local validation of the
> certificate and chain.  (There may be particular special cases arranged by
> policy where it does, but not in the general case.)
>
> I am saying that you can have multiple certificates, call them A and B,
> that certify the same public key K.  Knowing K, you can validate the
> message signature, protected attributes, etc., including the URI used to
> fetch the certificate.  However, if the URI used to fetch the certificate
> uses a scheme that does not provide integrity protection or server
> authentication, then the party dereferencing the URI could obtain
> certificate A when the message originator intended for certificate B to be
> used for validation.  It is not too hard to imagine situations where both A
> and B can be used to build valid chains that end at root CAs trusted by the
> message recipient, and thus the insecure certificate fetch is (1)
> undetected and (2) causes the message to be interpreted differently than
> intended by the originator.  As I mentioned originally, A and B could have
> different X.509 extensions, (extended) key usage, subject information,
> etc., so there is a lot of room for the "interpreted differently" to be
> attacked.
>
>
> But isn’t this a problem with any and all cert chain construction and
> validation?  If this is an issue, then x5bag and x5chain should be
> protected headers.
>
>
> No; once you have a (EE) cert, you have Issuer information to find the
> next cert in the chain.  With just a COSE message you don't have that.
>
> Seems like the real problem is CA operation. CA’s shouldn’t be creating
> alternate certs for real keys that result in issues like this.
>
>
> Most of the time, for most scenarios.  But this is not a reliable security
> control.
>
> So it still seems to me that the primary reason for an x5u that is a
> protected header parameter and obtained with DTLS is so you don’t have to
> validate the end-entity on the constrained device. Presumably you already
> have a DTLS stack, so you are almost getting the validated cert for no
> extra code.
>
>
> I disagree.
>
>
>
> cert chain validation. You and other folks probably were involved in some
> ace work that I was not involved with to know that. I don’t think it says
> that clearly in cose-x509, though I can now see how you can triangulate
> your way to that understanding. If x5u is to work like this, it seems a
> lot of addition to security considerations is needed.
>
> RFC 2585 does not work this way. It assumes the chain validation is done
> locally (see RFC 2585 Security Considerations) and that there is no need
> for any transport layer security. This seems like a perfectly useful and
> good thing to do and to support in cose-x509.  This is what I outlined in
> bullet points above.
>
>
> With RFC 2585 you know enough information about the *certificate* that you
> want that you have what is (supposed to be, at least) a unique identifier
> for the *certificate*.  In the "x5u" case you only have information about a
> *key*, not a certificate.
>
>
> I’m not understanding how x5u is about a key, not about a certificate.
>
>
> The key is the only thing tying the COSE message to the certificate; other
> information in the certificate (e.g., SubjectPublicKeyInfo) is not
> available when processing the COSE message.  Let me try to walk through
> some steps:
>
> You have a COSE message; say it's a signed message.  The recipient has the
> (plain)text, the actual signature bytes, and the parameters, including x5u.
> If the recipient verifies the signature, they know that the x5u URI is the
> one intended by the holder of the private key that made the signature.  (In
> order to validate the signature, they presumably have to obtain the
> certificate first, but we're getting there.)  The only thing that ties the
> received message to the certificate obtained by dereferencing the URI is
> the signature in the message itself.  That signature does not contain or
> include any attributes of the certificate containing the public key
> corresponding to the private key that made the signature; there is no
> SubjectPublicKeyInfo or similar in the COSE message.  The only thing
> needed to validate the signature is the public key in question.  In
> principle that public key could be obtained in many ways (it could have
> been included as a COSE_Key for that matter), but in the x5u case, we're
> supposed to get that public key from a certificate found at a particular
> URI.  But the way that I tie the message+signature to the certificate is by
> using the public key in the certificate to validate the signature on the
> message.  So, it is the public key that is what I use to find the
> certificate that is associated with the signature, but there is not a
> unique mapping from public key to certificate, in general.  In order for
> the signing party to be confident that the recipient interprets the
> signature properly, there has to be a chain of custody from the
> message+signature to the intended certificate.  Using coap-not-s to obtain
> the certificate breakas the chain of custody -- in extreme cases the
> message could appear to have been generated by a completely different
> entity than it actually was!
>
> -Ben
>
>
>
> When I think about implementing cose-x509, I can see several options.
>
> 1. Just implement x5chain. Fail if x5chain is not present. Only need code
> for chain validation. No need for chain formation.
>
> 2. Just implement x5bag and x5t.  Fail if x5t and x5bag are not present.
> Now you need code for chain validation and chain formation.
>
> 3. Just implement x5u. Fail if x5u is not present. All you need is some
> ASN.1 parsing and DTLS code. No chain validation or formation needed.
>
> 4. Implement all, with a priority order like first try x5chain, then try
> x5bag/x5t, finally x5u.
>
> 5. Various combinations of the above
>
>
> I believe that there is some intent to use x5t for cases where the
> certificates in question are already in local storage on both parties, so
> the thumbprint is just a shortand reference for "use this one [that you
> already have]"; no need for the x5bag.
>
>
> Yes, agreed. Might not even need any chain formation code if the hierarchy
> is simple and certs are pre-distributed.
>
> [Probably more comments possible here, but I didn't think very hard.]
>
> -Ben
>
>
> LL
>
>
> _______________________________________________
> COSE mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/cose
>
>
> _______________________________________________
> COSE mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/cose
>

---

From: Ivaylo Petrov <[email-masked]>
Date: Sun, 1 Nov 2020 19:55:32 +0100

Hi,

Thank you for looking into this! To some extent I am wondering if we should
leave some flexibility here for the applications to decide, but probably
you are right that we should write those parts explicitly. More precisely:
1) I made the use of DER encoding explicit in the part where we specify
CDDL for x5bag.
2) I clarified that the hash is computed over the DER encoding of the
certificate. I am not completely sure that we should limit the use of x5t
to only reference the certificate containing the end-entity key, but that
is also fine with me.

Thanks,
Ivaylo

On Tue, Oct 20, 2020 at 7:23 PM Laurence Lundblade <[email-masked]>
wrote:

> I went through my open GitHub issues on cose-x509
> <https://github.com/cose-wg/X509/issues> and closed a few, but a few
> remain.  The comments on the issue diverged from their titles, but still
> seem valuable. They come down to two things.
>
> 1) There is agreement that only certs in the DER format is allowed.
> However, cose-x509-07 doesn’t seem to say that.
>
> 2) Confusion over the x5t parameter. I think it is to identify the
> end-entity cert in an x5bag or out of a collection fetched by URI or a
> collection the relying party already has, but I’m not sure from the text.
> (Maybe it is just my misunderstanding or misreading something).
>
> LL
>

---

From: Laurence Lundblade <[email-masked]>
Date: Mon, 2 Nov 2020 10:44:39 -0800

Hi Ivaylo,

> On Nov 1, 2020, at 10:55 AM, Ivaylo Petrov <[email-masked]> wrote:
> 
> 2) I clarified that the hash is computed over the DER encoding of the certificate. I am not completely sure that we should limit the use of x5t to only reference the certificate containing the end-entity key, but that is also fine with me.

JWS is clear about x5t as the end-entity cert:

   The "x5t" (X.509 certificate SHA-1 thumbprint) Header Parameter is a
   base64url-encoded SHA-1 thumbprint (a.k.a. digest) of the DER
   encoding of the X.509 certificate [RFC5280 <https://tools.ietf.org/html/rfc5280>] corresponding to the key
   used to digitally sign the JWS.

I can’t imagine any other use of x5t as all certs superior to the end-entity must be identified by secured identifiers in the certificate one below to defend against the attack Ben described (the same attack that requires x5t a protected header).

Appendix D in JWS also discusses use of x5t as the end-entity.

I don’t think I’m missing anything here, but tell me if I am.

Also, it looks to me that Appendix D of JWS <https://tools.ietf.org/html/rfc7515#appendix-D> is highly applicable to cose-x509. A non-normative link to it would be helpful in understanding cose-x509.

LL

---

From: Laurence Lundblade <[email-masked]>
Date: Mon, 2 Nov 2020 10:50:43 -0800

Here’s text from section 6 in JWS <https://tools.ietf.org/html/rfc7515#section-6> that seems pretty close:

   Specifically, the Header
   Parameters "jku", "jwk", "kid", "x5u", "x5c", "x5t", and "x5t#S256"
   can be used to identify the key used.  These Header Parameters MUST
   be integrity protected if the information that they convey is to be
   utilized in a trust decision...

My understanding is that “info used in a trust decision” typically refers to fields in the end-entity certificate other than the key.

LL

> On Nov 1, 2020, at 10:51 AM, Ivaylo Petrov <[email-masked]> wrote:
> 
> Hello Laurence,
> 
> I am confident this discussion has been useful for the understanding of everyone, so thank you for starting it! Do not hesitate to suggest text if you believe anything needs to be explained in more details regarding why some attributes need to be protected and why others do not.
> 
> Thanks,
> Ivaylo
> 
> 
> On Fri, Oct 23, 2020 at 9:02 PM Laurence Lundblade <[email-masked] <mailto:[email-masked]>> wrote:
> I think that means identification of an end-entity cert must usually be covered by the signature. Since x5t and x5chain identify end-entity certs, they should be protected headers. From an attackers point of view the unprotected headers can be manipulated to the same result as an x5u if it were unprotected.
> 
> It is spelled out clearly here in Key Identification in RFC 7517 <https://tools.ietf.org/html/rfc7515#section-6> (JWS). Seems like cose-x509 needs similar text.
> 
> It seems like you could combine a protected x5t with an unprotected x5u to get the same result. Fetch the cert with x5u, then make sure it is right with x5t.
> 
> I spent some time reading CMS, RFC 5652. It does not seem to address this. The SignerIdentifier which identifies the end-entity cert does not seem to be covered by the signature. This seems like an omission in CMS.
> 
> If I’d read RFC 7515 before I read cose-x509, I would have been much less confused and caused a lot less trouble here.
> 
> LL
> 
> 
> 
>> On Oct 22, 2020, at 2:18 PM, Benjamin Kaduk <[email-masked] <mailto:[email-masked]>> wrote:
>> 
>>>> On Oct 22, 2020, at 12:12 PM, Benjamin Kaduk <[email-masked] <mailto:[email-masked]>> wrote:
>>>> 
>>>> Hi Laurence,
>>>> 
>>>>>> On Oct 22, 2020, at 8:21 AM, Benjamin Kaduk <[email-masked] <mailto:[email-masked]>> wrote:
>>>>>> 
>>>>>>> I’m trying to understand why the x5u header must be a COSE protected header parameter and in general what the expected use of this header is.
>>>>>>> 
>>>>>>> My understanding is that it the relying party that is validating the cert chain is the one doing the HTTP fetching.
>>>>>>> 
>>>>>>> In the case of application/pkix-cert, then only one DER cert is returned and that is the end-entity cert.
>>>>>>> 
>>>>>>> - The relying party would use HTTP to with the x5u URL to fetch the end-entity cert
>>>>>>> - The certs in the chain between the end-entity are either already possess by the relying party or are in the x5bag header
>>>>>>> In this use, there is no requirement for security of the URL or for use of TLS to fetch it. All the necessary security is provided by standard chain validation.
>>>>>>> 
>>>>>>> So why is there a requirement that the header be protected and that TLS/DTLS be used?
>>>>>>> 
>>>>>>> Further, wouldn't the header protection be a form of self signing since the private key used to sign the header corresponds to the public key that is being fetched?
>>>>>> 
>>> But isn’t this a problem with any and all cert chain construction and validation?  If this is an issue, then x5bag and x5chain should be protected headers.
>> 
>>> Seems like the real problem is CA operation. CA’s shouldn’t be creating alternate certs for real keys that result in issues like this.
>> 
>>> So it still seems to me that the primary reason for an x5u that is a protected header parameter and obtained with DTLS is so you don’t have to validate the end-entity on the constrained device. Presumably you already have a DTLS stack, so you are almost getting the validated cert for no extra code.
>> 
>> I disagree.
>> 
>>> 
>>>> 
>>>>> RFC 2585 does not work this way. It assumes the chain validation is done locally (see RFC 2585 Security Considerations) and that there is no need for any transport layer security. This seems like a perfectly useful and good thing to do and to support in cose-x509.  This is what I outlined in bullet points above.
>>>> 
>>>>> 1. Just implement x5chain. Fail if x5chain is not present. Only need code for chain validation. No need for chain formation.
>>>>> 
>>>>> 2. Just implement x5bag and x5t.  Fail if x5t and x5bag are not present. Now you need code for chain validation and chain formation.
>>>>> 
>>>>> 3. Just implement x5u. Fail if x5u is not present. All you need is some ASN.1 parsing and DTLS code. No chain validation or formation needed.
>>>>> 
>>>>> 4. Implement all, with a priority order like first try x5chain, then try x5bag/x5t, finally x5u.
>>>>> 
>>> Yes, agreed. Might not even need any chain formation code if the hierarchy is simple and certs are pre-distributed.
>>> 
>> [email-masked] <mailto:[email-masked]>
>> https://www.ietf.org/mailman/listinfo/cose <https://www.ietf.org/mailman/listinfo/cose>
> [email-masked] <mailto:[email-masked]>
> https://www.ietf.org/mailman/listinfo/cose <https://www.ietf.org/mailman/listinfo/cose>