Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Certificate chain in the same order as it appears in TLS #1927

Closed
martinthomson opened this issue Feb 3, 2022 · 7 comments · Fixed by #2258
Closed

Certificate chain in the same order as it appears in TLS #1927

martinthomson opened this issue Feb 3, 2022 · 7 comments · Fixed by #2258

Comments

@martinthomson
Copy link
Contributor

There's a bunch of text in the draft about putting the certificate chain in the right order. This tries to crib from TLS and ends up being somewhat tricky to get right as TLS has a bunch of carefully worded and - frankly - ambiguous rules. As a simple alternative, how about we just state that the certificates need to appear in the same order as the client sent them in TLS.

@bc-pi
Copy link
Contributor

bc-pi commented Feb 4, 2022

Makes sense. Will look at adjusting the text accordingly.

@davidben
Copy link
Contributor

davidben commented Feb 4, 2022

I think this is a bit more fundamental than just the order. It's really a question of whether this is a certificate path, or a pile of input certificates to run verification over. That is, either:

  1. The origin runs path building, taking the unordered/unverified pile of input certificates from the header, in TLS order.
  2. The proxy runs path building and passes the result in the header. The origin assumes a path has been built and is merely applying ACLs based on some aspect of the resulting path.

A mismatch here could result in security issues. For instance, suppose the origin wants to only allow chains issued by intermediate certificate I1 to access /foo. If the header means (1) but the origin expects (2), this ACL is trivially bypassable:

  • Client has a certificate chain EE -> I2 -> CA.
  • Client connects to proxy and sends {EE, I2, CA, I1}. (Or perhaps {EE, I2, I1, CA}. Or whatever else. Different verifiers are differently permissive about path-building. Perhaps it omits I2 altogether and the path-builder picks it up some other way.)
  • Even if the proxy runs certificate verification, a path-building verifier will build the EE -> I2 -> CA path and just consider I1 as a random unused certificate.
  • Client-Cert-Chain, per the TLS order rule, contains {EE, I2, CA, I1}
  • Origin server checks this and concludes "aha, this was issued by I1 and can access the resource".

Conversely, the semantics are (2), the proxy needs to have enough information to validate the certificate, up to a valid trust anchor for the application. If you all intended to punt that to the origin, that's a different protocol.

If the spec says TLS order, it's implicitly saying the interpretation is (1). But as that leaves a security-critical check to the origin, it should be explicit about this. Also, as it leaves all certificate validity to the origin, it'd need to further define an error-handling story to properly tell the client the certificate was invalid. But I know of no client that uses HTTP-level errors to clear client certificate decisions, only TLS alerts. I think (2) may be a more robust/compatible.

@martinthomson
Copy link
Contributor Author

It is definitely 1. You do 2 and you don't need this client-cert-chain field at all.

That doesn't mean that a proxy can't be configured to do the work and pass the info along. But one of the two needs to be in the hook for enforcement.

A consequence of 1 is that alerts at the TLS layer won't be used to signal errors, aside from those that the proxy detects (or has to, like if the signature is invalid). That is ok, mostly. The main protocol issue here that might be a problem is validation of signature_scheme_cert. I can't see how failing to validate that would be a significant problem though.

@bc-pi
Copy link
Contributor

bc-pi commented Feb 4, 2022

In this conversation on the PR that introduced the chain I was aiming for 2. But eventually relented to MT. Some additional considerations about the security implications are likely warranted though.

@davidben
Copy link
Contributor

davidben commented Feb 4, 2022

I see. If it's (1), that should probably be clearer in the draft. That also means the draft needs to define an error-signaling scheme. Moreover, if the proxy doesn't then translate that error into TLS alerts, we'd need changes in clients for servers relying on this to work right. I'll file a bug.

@b---c
Copy link
Contributor

b---c commented May 20, 2022

I ran into real reservations as I looked at making this change. I still don't like pushing the trust chain validation to the origin. For many reasons. The proxy also has no means of signaling to the client which trust anchors the origin is okay with.
The current text is somewhat ambiguous about what goes in Client-Cert-Chain but I think that's actually better than saying it has to be same as in the TLS handshake. I dunno, I think I might raise the question of WTF actually goes in Client-Cert-Chain at the next interim or real meeting.

@bc-pi
Copy link
Contributor

bc-pi commented Oct 3, 2022

At the last virtual interim (in May/June yikes!) Martin kindly suggested that I was making this too complicated and to just make the change (paraphrasing). I've tried to do that with changes in PR #2258 .

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

Successfully merging a pull request may close this issue.

4 participants