Skip to content

Commit

Permalink
Use server's preferred key agreeement
Browse files Browse the repository at this point in the history
In contrast to upstream Go, we will send an HelloRetryRequest and
accept an extra roundtrip if there is a more preferred group, than
the one the client has provided a keyshare for in the initial ClientHello.

Cf. https://datatracker.ietf.org/doc/draft-davidben-tls-key-share-prediction/
  • Loading branch information
bwesterb committed Oct 6, 2023
1 parent b21c16b commit 2c4ed92
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 13 deletions.
1 change: 1 addition & 0 deletions src/crypto/tls/handshake_server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1930,6 +1930,7 @@ func TestAESCipherReorderingTLS13(t *testing.T) {
supportedVersions: []uint16{VersionTLS13},
compressionMethods: []uint8{compressionNone},
keyShares: []keyShare{{group: X25519, data: pk.PublicKey().Bytes()}},
supportedCurves: []CurveID{X25519},
},
}

Expand Down
25 changes: 12 additions & 13 deletions src/crypto/tls/handshake_server_tls13.go
Original file line number Diff line number Diff line change
Expand Up @@ -256,33 +256,32 @@ func (hs *serverHandshakeStateTLS13) processClientHello() error {
}
}

// Pick the ECDHE group in server preference order, but give priority to
// groups with a key share, to avoid a HelloRetryRequest round-trip.
// Pick group by server preference. In contrast to upstream Go, we will
// send an HelloRetryRequest and accept an extra roundtrip if there is
// a more preferred group, than those for which the client has sent
// a keyshare in the initial ClientHello.
// Cf. https://datatracker.ietf.org/doc/draft-davidben-tls-key-share-prediction/
var selectedGroup CurveID
var clientKeyShare *keyShare
GroupSelection:
for _, preferredGroup := range supportedCurves {
for _, ks := range hs.clientHello.keyShares {
if ks.group == preferredGroup {
selectedGroup = ks.group
clientKeyShare = &ks
break GroupSelection
}
}
if selectedGroup != 0 {
continue
}
for _, group := range hs.clientHello.supportedCurves {
if group == preferredGroup {
selectedGroup = group
break
break GroupSelection
}
}
}
if selectedGroup == 0 {
c.sendAlert(alertHandshakeFailure)
return errors.New("tls: no ECDHE curve supported by both client and server")
}
for _, ks := range hs.clientHello.keyShares {
if ks.group == selectedGroup {
clientKeyShare = &ks
break
}
}
if clientKeyShare == nil {
if err := hs.doHelloRetryRequest(selectedGroup); err != nil {
return err
Expand Down

0 comments on commit 2c4ed92

Please sign in to comment.