* fix for tls13 when server selects a keyshare  with index > 0

* Update handshake_client_tls13.go

* resolved [uTLS section] problems

---------

Co-authored-by: Chaos Pjeles <chaos@fqr.us>
This commit is contained in:
Chaos Pjeles 2023-03-20 21:16:28 +00:00 committed by GitHub
parent 17e2929ff7
commit 6d2506f52f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 67 additions and 35 deletions

View file

@ -219,14 +219,15 @@ func (c *Conn) clientHandshake(ctx context.Context) (err error) {
if c.vers == VersionTLS13 {
hs := &clientHandshakeStateTLS13{
c: c,
ctx: ctx,
serverHello: serverHello,
hello: hello,
ecdheParams: ecdheParams,
session: session,
earlySecret: earlySecret,
binderKey: binderKey,
c: c,
ctx: ctx,
serverHello: serverHello,
hello: hello,
ecdheParams: ecdheParams,
keySharesEcdheParams: make(KeySharesEcdheParameters, 2), // [uTLS]
session: session,
earlySecret: earlySecret,
binderKey: binderKey,
}
// In TLS 1.3, session tickets are delivered after the handshake.

View file

@ -17,12 +17,30 @@ import (
"time"
)
// [uTLS SECTION START]
type KeySharesEcdheParameters map[CurveID]ecdheParameters
func (keymap KeySharesEcdheParameters) AddEcdheParams(curveID CurveID, params ecdheParameters) {
keymap[curveID] = params
}
func (keymap KeySharesEcdheParameters) GetEcdheParams(curveID CurveID) (params ecdheParameters, ok bool) {
params, ok = keymap[curveID]
return
}
func (keymap KeySharesEcdheParameters) GetPublicEcdheParams(curveID CurveID) (params EcdheParameters, ok bool) {
params, ok = keymap[curveID]
return
}
// [uTLS SECTION END]
type clientHandshakeStateTLS13 struct {
c *Conn
ctx context.Context
serverHello *serverHelloMsg
hello *clientHelloMsg
ecdheParams ecdheParameters
c *Conn
ctx context.Context
serverHello *serverHelloMsg
hello *clientHelloMsg
ecdheParams ecdheParameters
keySharesEcdheParams KeySharesEcdheParameters // [uTLS]
session *ClientSessionState
earlySecret []byte
@ -55,6 +73,14 @@ func (hs *clientHandshakeStateTLS13) handshake() error {
return errors.New("tls: server selected TLS 1.3 in a renegotiation")
}
// [uTLS SECTION START]
// set echdheParams to what we received from server
if ecdheParams, ok := hs.keySharesEcdheParams.GetEcdheParams(hs.serverHello.serverShare.group); ok {
hs.ecdheParams = ecdheParams
}
// [uTLS SECTION END]
// Consistency check on the presence of a keyShare and its parameters.
if hs.ecdheParams == nil || len(hs.hello.keyShares) < 1 { // [uTLS]
// keyshares "< 1" instead of "!= 1", as uTLS may send multiple

View file

@ -1948,6 +1948,7 @@ func (uconn *UConn) ApplyPreset(p *ClientHelloSpec) error {
}
uconn.HandshakeState.Hello = privateHello.getPublicPtr()
uconn.HandshakeState.State13.EcdheParams = ecdheParams
uconn.HandshakeState.State13.KeySharesEcdheParams = make(KeySharesEcdheParameters, 2)
hello := uconn.HandshakeState.Hello
session := uconn.HandshakeState.Session
@ -2050,6 +2051,7 @@ func (uconn *UConn) ApplyPreset(p *ClientHelloSpec) error {
return fmt.Errorf("unsupported Curve in KeyShareExtension: %v."+
"To mimic it, fill the Data(key) field manually", curveID)
}
uconn.HandshakeState.State13.KeySharesEcdheParams.AddEcdheParams(curveID, ecdheParams)
ext.KeyShares[i].Data = ecdheParams.PublicKey()
if !preferredCurveIsSet {
// only do this once for the first non-grease curve

View file

@ -34,15 +34,16 @@ type PubClientHandshakeState struct {
// TLS 1.3 only
type TLS13OnlyState struct {
Suite *PubCipherSuiteTLS13
EcdheParams EcdheParameters
EarlySecret []byte
BinderKey []byte
CertReq *CertificateRequestMsgTLS13
UsingPSK bool
SentDummyCCS bool
Transcript hash.Hash
TrafficSecret []byte // client_application_traffic_secret_0
Suite *PubCipherSuiteTLS13
EcdheParams EcdheParameters
KeySharesEcdheParams KeySharesEcdheParameters
EarlySecret []byte
BinderKey []byte
CertReq *CertificateRequestMsgTLS13
UsingPSK bool
SentDummyCCS bool
Transcript hash.Hash
TrafficSecret []byte // client_application_traffic_secret_0
}
// TLS 1.2 and before only
@ -56,10 +57,11 @@ func (chs *PubClientHandshakeState) toPrivate13() *clientHandshakeStateTLS13 {
return nil
} else {
return &clientHandshakeStateTLS13{
c: chs.C,
serverHello: chs.ServerHello.getPrivatePtr(),
hello: chs.Hello.getPrivatePtr(),
ecdheParams: chs.State13.EcdheParams,
c: chs.C,
serverHello: chs.ServerHello.getPrivatePtr(),
hello: chs.Hello.getPrivatePtr(),
ecdheParams: chs.State13.EcdheParams,
keySharesEcdheParams: chs.State13.KeySharesEcdheParams,
session: chs.Session,
earlySecret: chs.State13.EarlySecret,
@ -83,15 +85,16 @@ func (chs13 *clientHandshakeStateTLS13) toPublic13() *PubClientHandshakeState {
return nil
} else {
tls13State := TLS13OnlyState{
EcdheParams: chs13.ecdheParams,
EarlySecret: chs13.earlySecret,
BinderKey: chs13.binderKey,
CertReq: chs13.certReq.toPublic(),
UsingPSK: chs13.usingPSK,
SentDummyCCS: chs13.sentDummyCCS,
Suite: chs13.suite.toPublic(),
TrafficSecret: chs13.trafficSecret,
Transcript: chs13.transcript,
KeySharesEcdheParams: chs13.keySharesEcdheParams,
EcdheParams: chs13.ecdheParams,
EarlySecret: chs13.earlySecret,
BinderKey: chs13.binderKey,
CertReq: chs13.certReq.toPublic(),
UsingPSK: chs13.usingPSK,
SentDummyCCS: chs13.sentDummyCCS,
Suite: chs13.suite.toPublic(),
TrafficSecret: chs13.trafficSecret,
Transcript: chs13.transcript,
}
return &PubClientHandshakeState{
C: chs13.c,