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

From: Laurence Lundblade <[email-masked]>
Date: Mon, 19 Oct 2020 11:40:33 -0700

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?

But maybe I am grossly misunderstanding the intended use of x5u?

Thanks,

LL

---

From: Laurence Lundblade <[email-masked]>
Date: Mon, 19 Oct 2020 12:11:20 -0700

draft-ietf-cose-x509-07 says:

   Example COSE messages for the various header parameters defined below
   can be found at https://github.com/cose-wg/Examples <https://github.com/cose-wg/Examples>.

When I looked, I couldn’t find any (to help me answer other questions posted here). I grepped through all the JSON for 509, x5bag, x5u… and got no hits.

LL

---

From: Ivaylo Petrov <[email-masked]>
Date: Tue, 20 Oct 2020 08:30:35 +0300

Thank you Laurence for reporting this! If nobody is able to provide
examples (validated with running code if possible), I intend to remove this
paragraph.

Best regards,
Ivaylo

On Mon, Oct 19, 2020 at 10:11 PM Laurence Lundblade <[email-masked]>
wrote:

>    can be found at https://github.com/cose-wg/Examples.
>
>
>
> When I looked, I couldn’t find any (to help me answer other questions
> posted here). I grepped through all the JSON for 509, x5bag, x5u… and got
> no hits.
>
> LL
> _______________________________________________
> COSE mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/cose
>

---

From: Laurence Lundblade <[email-masked]>
Date: Tue, 20 Oct 2020 10:23:00 -0700

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: Benjamin Kaduk <[email-masked]>
Date: Thu, 22 Oct 2020 08:21:20 -0700

> 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.

-Ben

---

From: Laurence Lundblade <[email-masked]>
Date: Thu, 22 Oct 2020 11:56:24 -0700

> On Oct 22, 2020, at 8:21 AM, Benjamin Kaduk <[email-masked]> wrote:
> 

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 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.

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

If RFC 2585 (non-validated) fetching is allowed, then further options…

LL

---

From: Benjamin Kaduk <[email-masked]>
Date: Thu, 22 Oct 2020 12:12:23 -0700

Hi Laurence,

On Thu, Oct 22, 2020 at 11:56:24AM -0700, Laurence Lundblade wrote:
> 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.

> 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.
>

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.

> 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.
[Probably more comments possible here, but I didn't think very hard.]

-Ben

---

From: Laurence Lundblade <[email-masked]>
Date: Thu, 22 Oct 2020 13:56:58 -0700

Below...

> On Oct 22, 2020, at 12:12 PM, Benjamin Kaduk <[email-masked]> wrote:
> 
> Hi Laurence,
> 

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.

> *key*, not a certificate.

I’m not understanding how x5u is about a key, not about a certificate.

> 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.

LL

---

From: Benjamin Kaduk <[email-masked]>
Date: Thu, 22 Oct 2020 14:18:04 -0700

> 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. Pre…

I disagree.

> 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

---

From: Laurence Lundblade <[email-masked]>
Date: Fri, 23 Oct 2020 12:02:06 -0700

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:
>