Skip to content

fix: keep private keys for secondary key shares - #416

Open
thesinakamali wants to merge 3 commits into
refraction-networking:masterfrom
thesinakamali:fix/keyshare-private-keys
Open

thesinakamali wants to merge 3 commits into
refraction-networking:masterfrom
thesinakamali:fix/keyshare-private-keys

Conversation

@thesinakamali

Copy link
Copy Markdown
Contributor

When a ClientHelloSpec offers more than one classical key share (e.g., the Firefox profiles send X25519 and P-256), ApplyPreset generates a private key for each but only keeps the first in KeyShareKeys.Ecdhe. If the server selects the second curve, clientSharedSecret runs ECDH with the wrong private key and the handshake fails with "tls: invalid server key share". Fix by storing the additional private keys in a new KeyShareKeys.EcdheFallback map keyed by CurveID, and having ecdhKeyExchange select the key matching the server's chosen group.

The first commit fixes a related issue where ApplyPreset unconditionally reset KeyShareKeys to an empty struct. When BuildHandshakeStateWithoutSession is called before BuildHandshakeState, the spec is reused and the key shares are already populated, so the second call discarded the private keys that matched the public shares already in the ClientHello. Only initialize KeyShareKeys when it is nil.

The second commit fixes the secondary key share bug and adds a test that does an in-process handshake with HelloFirefox_105/120/148 against a server with CurvePreferences = CurveP256. It fails with "invalid server key share" without the fix and negotiates P-256 with no HRR with it.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant