utls: Handshake fails when server selects a secondary key share
Hi!
I’m using ClientHello from Firefox(Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/114.0) x25519 doesn’t seem to be supported, for example this server selects x25519 as preferable curve - https://pbs.twimg.com/media/F47NEN4WUAAZwRg.jpg
verified by adding some additional error details here: https://github.com/refraction-networking/utls/blob/master/handshake_client_tls13.go#L530
mismatch is here:
curveIDForCurve(hs.ecdheKey.Curve()) = X25519
hs.serverHello.serverShare.group = CurveP256
As a result handshake fails and I cannot connect to this website with uTLS
About this issue
- Original URL
- State: closed
- Created 10 months ago
- Comments: 16 (7 by maintainers)
I will tag & release ASAP, since it is indeed an unintended breaking behavior.
Looks like I’m the one to blame. I literally could no longer recall why there was an overriding behavior – perhaps there’s no specific reason, or maybe a nil-pointer problem.
Hope this would work better.
For the target host
pbs.twimg.comhowever, they have at least 2 sets of configurations, TLS12-only and TLS13-compatible.For the TLS12-only ones, the connection WILL not fail as the server selects
x25519, the first advertised Key Share. The other group, TLS13-compatible servers will instead selectsecp256r1, the second, which is lost as mentioned.This problem happens ONLY if we advertise more than one key share at the same time (Firefox’s default behavior). Advertising the support of more than one key share (through
supported_groupsextension) does not cause any issue.After looking into this issue I found several problems.
For uTLS, when we generate and send key shares in a ClientHello message, they are saved to a
*KeySharesParametersto be retrieved later, while the first non-GREASE key share is copied and saved directly in the handshake states.https://github.com/refraction-networking/utls/blob/fc79497d3f1c0f25f1ceb6672c3772b79b99c30f/u_parrots.go#L2433-L2477
However in
(*UConn).clientHandshake, the*KeySharesParameterswas mistakenly overridden by aNewKeySharesParameters().https://github.com/refraction-networking/utls/blob/fc79497d3f1c0f25f1ceb6672c3772b79b99c30f/u_conn.go#L566-L571
It caused us to lose all but the first key share (saved elsewhere).
I will try to take a look tomorrow, but you can also try to reproduce this on your side with that server - pbs.twimg.com
I’m getting the same error on multiple other websites – mostly different bank websites, and moving to the older version as let4be indicated also works for me
Interesting. Since this error does not replicate on other sites (according to what you reported in this thread), I believe the problem is unlikely in KeyShareExtension or how SupportedGroups are handled in uTLS, but more likely due to a certain behavior that is unique to the target TLS server.
If possible you may want to pcap the entire TLS handshake process (possibly dump the keylog) and inspect what does server responds.
I am actually aware that most of modern browsers (including certain versions of Google Chrome and Mozilla Firefox) suffers from downgrading attack when the server selects a deprecated/not-advertised
supported_grouporcipher_suite(they may directly proceed or send a new ClientHello advertising the selected ones), while uTLS strictly forbids such behavior.