-
Notifications
You must be signed in to change notification settings - Fork 17.5k
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
crypto/tls: don't include supported_versions extension if MaxVersion < 1.3 #53384
Comments
For refs, RFC8446:
|
This is technically the client so I don't think that applies. But I noticed it does say:
So it appears that Google is in the wrong here since they support TLS 1.2 but don't expect to negotiate 1.2 if that extension is present. However, if a server doesn't support TLS 1.3, they wouldn't know about this extension. |
@rolandshoemaker @golang/security |
Odd! I can repro it with the script, but I'm pretty sure we test this case with BoringSSL, and it doesn't repro with other servers that use BoringSSL. This may be a bug in some code we have in Google's server. Searching around there... |
Ah, I see the issue. It's a combination of sending supported_versions, not including the ECDSA version of those ciphers, but including ECDSA in signature algorithms. (Doesn't look like Go lets you configure that one.) You should probably be including the ECDSA versions anyway, so hopefully that'll resolve it for you? Though I acknowledge the google.com behavior isn't great. Why this happens is that determining ECDSA support in TLS is bit of a mess and has migrated over time:
The TLS 1.3 behavior is cleaner but the combination of all three modes leaves a bit of a mess: google.com resolves SNI, ECDSA, etc., all at once, when we see the ClientHello. At that point, it's not quite yet known which TLS version we'll be using. So we assume that any client which sends supported_versions is at least new enough for the signature_algorithms extension to be accurate and assume the TLS 1.3 check is sufficient. So, with this ClientHello, we see ecdsa_secp256r1_sha256 in the signature algorithms extension and assume this must be a new enough client to speak ECDSA and configure the ECDSA certificate. From there, the handshake continues, we negotiate TLS 1.2 via supported_versions, and find there are no acceptable cipher suites for an ECDSA certificate. Thus the handshake fails with handshake_failure. More robust would be for BoringSSL to support configuring both certificates and internally select it, since the selection logic is far too messy to expect a caller to implement. |
Ah that's good to know! I appreciate the through investigation. For this one case, we actually are purposefully not including ECDSA so we can test the RSA certificate we've deployed to a GCP load balancer. We have 2 different configs one that includes ECDSA ciphers and one that doesn't. Not sure where we go from here. Should we be able to configure the signature algorithms in Go or is this squarely a bug on Google's end and there's no Go change necessary? Besides Google, do we envision problems with TLS 1.2 servers by sending |
Thank you for the investigation @davidben! The certificate compatibility logic is indeed a major mess, our own implementation was one of the most painful things I had to write. We could add some logic to not send ECDSA in As usual, Go doing something a little different is helpful in greasing the ecosystem, if we can afford it :) |
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
Yes
What operating system and processor architecture are you using (
go env
)?go env
OutputWhat did you do?
If you make a TLS 1.2 ClientHello to some servers and include a
supported_versions
extension the server will report back a handshake failure. I was comparing why Go failed butopenssl s_client ... -tls1_2 -cipher 'ECDHE-RSA-AES128-GCM-SHA256'
worked and I figured out that the difference is that Go sends thesupported_versions
and openssl doesn't.It seems that
supported_versions
is a TLS 1.3 extension so we probably shouldn't be including it when the MaxVersion is less than 1.3.Here's a way to reproduce it against google.com:
I realize the above is a contrived example but the fact that Google has this problem (and all GCP load balancers) seems to justify that it's not a random server that's misbehaving.
What did you expect to see?
I expected the program not to panic.
What did you see instead?
Instead I get
panic: Get "https://google.com/": remote error: tls: handshake failure
.If I change
marshal
inhandshake_messages.go
to:Then the above program no longer errors.
The text was updated successfully, but these errors were encountered: