mirror of
https://github.com/refraction-networking/utls.git
synced 2025-04-01 19:17:36 +03:00
update: rm cf KEMkey & KeySharesParams in TLS13OnlyState
These can be set and read via KeySharePrivateKeys. While the breakage is unfortunate for backwards compatibility, it is already unavoidable in one direction: the cloudflare kem key does not store the mlkem seed and is therefore incompatible with crypto/mlkem.
This commit is contained in:
parent
9fada94f7e
commit
d24af4ae55
5 changed files with 55 additions and 146 deletions
|
@ -381,8 +381,6 @@ func (c *Conn) clientHandshake(ctx context.Context) (err error) {
|
||||||
earlySecret: earlySecret,
|
earlySecret: earlySecret,
|
||||||
binderKey: binderKey,
|
binderKey: binderKey,
|
||||||
echContext: ech,
|
echContext: ech,
|
||||||
|
|
||||||
keySharesParams: NewKeySharesParameters(), // [uTLS]
|
|
||||||
}
|
}
|
||||||
return hs.handshake()
|
return hs.handshake()
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,6 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"crypto"
|
"crypto"
|
||||||
"crypto/ecdh"
|
|
||||||
"crypto/hmac"
|
"crypto/hmac"
|
||||||
"crypto/mlkem"
|
"crypto/mlkem"
|
||||||
"crypto/rsa"
|
"crypto/rsa"
|
||||||
|
@ -19,74 +18,16 @@ import (
|
||||||
"slices"
|
"slices"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/cloudflare/circl/kem"
|
|
||||||
"github.com/refraction-networking/utls/internal/hkdf"
|
"github.com/refraction-networking/utls/internal/hkdf"
|
||||||
"github.com/refraction-networking/utls/internal/tls13"
|
"github.com/refraction-networking/utls/internal/tls13"
|
||||||
)
|
)
|
||||||
|
|
||||||
// [uTLS SECTION START]
|
|
||||||
// KeySharesParameters serves as a in-memory storage for generated keypairs by UTLS when generating
|
|
||||||
// ClientHello. It is used to store both ecdhe and kem keypairs.
|
|
||||||
type KeySharesParameters struct {
|
|
||||||
ecdhePrivKeymap map[CurveID]*ecdh.PrivateKey
|
|
||||||
ecdhePubKeymap map[CurveID]*ecdh.PublicKey
|
|
||||||
|
|
||||||
// based on cloudflare/go
|
|
||||||
kemPrivKeymap map[CurveID]kem.PrivateKey
|
|
||||||
kemPubKeymap map[CurveID]kem.PublicKey
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewKeySharesParameters() *KeySharesParameters {
|
|
||||||
return &KeySharesParameters{
|
|
||||||
ecdhePrivKeymap: make(map[CurveID]*ecdh.PrivateKey),
|
|
||||||
ecdhePubKeymap: make(map[CurveID]*ecdh.PublicKey),
|
|
||||||
|
|
||||||
kemPrivKeymap: make(map[CurveID]kem.PrivateKey),
|
|
||||||
kemPubKeymap: make(map[CurveID]kem.PublicKey),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ksp *KeySharesParameters) AddEcdheKeypair(curveID CurveID, ecdheKey *ecdh.PrivateKey, ecdhePubKey *ecdh.PublicKey) {
|
|
||||||
ksp.ecdhePrivKeymap[curveID] = ecdheKey
|
|
||||||
ksp.ecdhePubKeymap[curveID] = ecdhePubKey
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ksp *KeySharesParameters) GetEcdheKey(curveID CurveID) (ecdheKey *ecdh.PrivateKey, ok bool) {
|
|
||||||
ecdheKey, ok = ksp.ecdhePrivKeymap[curveID]
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ksp *KeySharesParameters) GetEcdhePubkey(curveID CurveID) (params *ecdh.PublicKey, ok bool) {
|
|
||||||
params, ok = ksp.ecdhePubKeymap[curveID]
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ksp *KeySharesParameters) AddKemKeypair(curveID CurveID, kemKey kem.PrivateKey, kemPubKey kem.PublicKey) {
|
|
||||||
// if curveID == x25519Kyber768Draft00 { // only store for x25519Kyber768Draft00
|
|
||||||
// ksp.kemPrivKeymap[curveID] = kemKey
|
|
||||||
// ksp.kemPubKeymap[curveID] = kemPubKey
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ksp *KeySharesParameters) GetKemKey(curveID CurveID) (kemKey kem.PrivateKey, ok bool) {
|
|
||||||
kemKey, ok = ksp.kemPrivKeymap[curveID]
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ksp *KeySharesParameters) GetKemPubkey(curveID CurveID) (params kem.PublicKey, ok bool) {
|
|
||||||
params, ok = ksp.kemPubKeymap[curveID]
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// [uTLS SECTION END]
|
|
||||||
|
|
||||||
type clientHandshakeStateTLS13 struct {
|
type clientHandshakeStateTLS13 struct {
|
||||||
c *Conn
|
c *Conn
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
serverHello *serverHelloMsg
|
serverHello *serverHelloMsg
|
||||||
hello *clientHelloMsg
|
hello *clientHelloMsg
|
||||||
keyShareKeys *keySharePrivateKeys
|
keyShareKeys *keySharePrivateKeys
|
||||||
keySharesParams *KeySharesParameters // [uTLS] support both ecdhe and kem
|
|
||||||
|
|
||||||
session *SessionState
|
session *SessionState
|
||||||
earlySecret *tls13.EarlySecret
|
earlySecret *tls13.EarlySecret
|
||||||
|
@ -117,24 +58,6 @@ func (hs *clientHandshakeStateTLS13) handshake() error {
|
||||||
return errors.New("tls: server selected TLS 1.3 in a renegotiation")
|
return errors.New("tls: server selected TLS 1.3 in a renegotiation")
|
||||||
}
|
}
|
||||||
|
|
||||||
// [uTLS SECTION START]
|
|
||||||
// if hs.keyShareKeys == nil {
|
|
||||||
// // set echdheParams to what we received from server
|
|
||||||
// if ecdheKey, ok := hs.keySharesParams.GetEcdheKey(hs.serverHello.serverShare.group); ok {
|
|
||||||
// hs.keyShareKeys.ecdhe = ecdheKey
|
|
||||||
// hs.keyShareKeys.curveID = hs.serverHello.serverShare.group
|
|
||||||
// }
|
|
||||||
// // set kemParams to what we received from server
|
|
||||||
// if kemKey, ok := hs.keySharesParams.GetKemKey(hs.serverHello.serverShare.group); ok {
|
|
||||||
// if kyberKey, ecdhKey, err := mlkemCirclToGo(kemKey); err == nil {
|
|
||||||
// hs.keyShareKeys.kyber = kyberKey
|
|
||||||
// hs.keyShareKeys.ecdhe = ecdhKey
|
|
||||||
// hs.keyShareKeys.curveID = hs.serverHello.serverShare.group
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// [uTLS SECTION END]
|
|
||||||
|
|
||||||
// Consistency check on the presence of a keyShare and its parameters.
|
// Consistency check on the presence of a keyShare and its parameters.
|
||||||
if hs.keyShareKeys == nil || hs.keyShareKeys.ecdhe == nil || len(hs.hello.keyShares) == 0 {
|
if hs.keyShareKeys == nil || hs.keyShareKeys.ecdhe == nil || len(hs.hello.keyShares) == 0 {
|
||||||
return c.sendAlert(alertInternalError)
|
return c.sendAlert(alertInternalError)
|
||||||
|
|
29
u_alias.go
29
u_alias.go
|
@ -1,5 +1,11 @@
|
||||||
package tls
|
package tls
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/ecdh"
|
||||||
|
|
||||||
|
"github.com/cloudflare/circl/kem"
|
||||||
|
)
|
||||||
|
|
||||||
// This file contains all the alias functions, symbols, names, etc. that
|
// This file contains all the alias functions, symbols, names, etc. that
|
||||||
// was once used in the old version of the library. This is to ensure
|
// was once used in the old version of the library. This is to ensure
|
||||||
// backwards compatibility with the old version of the library.
|
// backwards compatibility with the old version of the library.
|
||||||
|
@ -10,3 +16,26 @@ package tls
|
||||||
//
|
//
|
||||||
// Deprecated: Use ExtendedMasterSecretExtension instead.
|
// Deprecated: Use ExtendedMasterSecretExtension instead.
|
||||||
type UtlsExtendedMasterSecretExtension = ExtendedMasterSecretExtension
|
type UtlsExtendedMasterSecretExtension = ExtendedMasterSecretExtension
|
||||||
|
|
||||||
|
// Deprecated: Use KeySharePrivateKeys instead. This type is not used and will be removed in the future.
|
||||||
|
// KeySharesParameters serves as a in-memory storage for generated keypairs by UTLS when generating
|
||||||
|
// ClientHello. It is used to store both ecdhe and kem keypairs.
|
||||||
|
type KeySharesParameters struct{}
|
||||||
|
|
||||||
|
func NewKeySharesParameters() *KeySharesParameters { return &KeySharesParameters{} }
|
||||||
|
|
||||||
|
func (*KeySharesParameters) AddEcdheKeypair(curveID CurveID, ecdheKey *ecdh.PrivateKey, ecdhePubKey *ecdh.PublicKey) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*KeySharesParameters) GetEcdheKey(curveID CurveID) (ecdheKey *ecdh.PrivateKey, ok bool) { return }
|
||||||
|
|
||||||
|
func (*KeySharesParameters) GetEcdhePubkey(curveID CurveID) (params *ecdh.PublicKey, ok bool) { return }
|
||||||
|
|
||||||
|
func (*KeySharesParameters) AddKemKeypair(curveID CurveID, kemKey kem.PrivateKey, kemPubKey kem.PublicKey) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ksp *KeySharesParameters) GetKemKey(curveID CurveID) (kemKey kem.PrivateKey, ok bool) { return }
|
||||||
|
|
||||||
|
func (ksp *KeySharesParameters) GetKemPubkey(curveID CurveID) (params kem.PublicKey, ok bool) { return }
|
||||||
|
|
10
u_parrots.go
10
u_parrots.go
|
@ -2636,7 +2636,6 @@ func (uconn *UConn) ApplyPreset(p *ClientHelloSpec) error {
|
||||||
} else {
|
} else {
|
||||||
uconn.HandshakeState.State13.KeyShareKeys = &KeySharePrivateKeys{}
|
uconn.HandshakeState.State13.KeyShareKeys = &KeySharePrivateKeys{}
|
||||||
}
|
}
|
||||||
uconn.HandshakeState.State13.KeySharesParams = NewKeySharesParameters()
|
|
||||||
uconn.echCtx = ech
|
uconn.echCtx = ech
|
||||||
hello := uconn.HandshakeState.Hello
|
hello := uconn.HandshakeState.Hello
|
||||||
|
|
||||||
|
@ -2750,12 +2749,6 @@ func (uconn *UConn) ApplyPreset(p *ClientHelloSpec) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// circlKyberKey, err := kyberGoToCircl(kyberKey, ecdheKey)
|
|
||||||
// if err != nil {
|
|
||||||
// return err
|
|
||||||
// }
|
|
||||||
// uconn.HandshakeState.State13.KeySharesParams.AddKemKeypair(curveID, circlKyberKey, circlKyberKey.Public())
|
|
||||||
|
|
||||||
if curveID == X25519Kyber768Draft00 {
|
if curveID == X25519Kyber768Draft00 {
|
||||||
ext.KeyShares[i].Data = append(ecdheKey.PublicKey().Bytes(), mlkemKey.EncapsulationKey().Bytes()...)
|
ext.KeyShares[i].Data = append(ecdheKey.PublicKey().Bytes(), mlkemKey.EncapsulationKey().Bytes()...)
|
||||||
} else {
|
} else {
|
||||||
|
@ -2770,7 +2763,6 @@ func (uconn *UConn) ApplyPreset(p *ClientHelloSpec) error {
|
||||||
if len(ext.KeyShares) > i+1 && ext.KeyShares[i+1].Group == X25519 {
|
if len(ext.KeyShares) > i+1 && ext.KeyShares[i+1].Group == X25519 {
|
||||||
// Reuse the same X25519 ephemeral key for both keyshares, as allowed by draft-ietf-tls-hybrid-design-09, Section 3.2.
|
// Reuse the same X25519 ephemeral key for both keyshares, as allowed by draft-ietf-tls-hybrid-design-09, Section 3.2.
|
||||||
uconn.HandshakeState.State13.KeyShareKeys.Ecdhe = ecdheKey
|
uconn.HandshakeState.State13.KeyShareKeys.Ecdhe = ecdheKey
|
||||||
// uconn.HandshakeState.State13.KeySharesParams.AddEcdheKeypair(curveID, ecdheKey, ecdheKey.PublicKey())
|
|
||||||
ext.KeyShares[i+1].Data = ecdheKey.PublicKey().Bytes()
|
ext.KeyShares[i+1].Data = ecdheKey.PublicKey().Bytes()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -2780,8 +2772,6 @@ func (uconn *UConn) ApplyPreset(p *ClientHelloSpec) error {
|
||||||
"To mimic it, fill the Data(key) field manually", curveID)
|
"To mimic it, fill the Data(key) field manually", curveID)
|
||||||
}
|
}
|
||||||
|
|
||||||
// uconn.HandshakeState.State13.KeySharesParams.AddEcdheKeypair(curveID, ecdheKey, ecdheKey.PublicKey())
|
|
||||||
|
|
||||||
ext.KeyShares[i].Data = ecdheKey.PublicKey().Bytes()
|
ext.KeyShares[i].Data = ecdheKey.PublicKey().Bytes()
|
||||||
if !preferredCurveIsSet {
|
if !preferredCurveIsSet {
|
||||||
// only do this once for the first non-grease curve
|
// only do this once for the first non-grease curve
|
||||||
|
|
73
u_public.go
73
u_public.go
|
@ -41,9 +41,13 @@ type PubClientHandshakeState struct {
|
||||||
type TLS13OnlyState struct {
|
type TLS13OnlyState struct {
|
||||||
// Deprecated: Use KeyShareKeys instead. KeyShareKeys will take precedence if both are set.
|
// Deprecated: Use KeyShareKeys instead. KeyShareKeys will take precedence if both are set.
|
||||||
// Support may be removed in the future.
|
// Support may be removed in the future.
|
||||||
EcdheKey *ecdh.PrivateKey
|
EcdheKey *ecdh.PrivateKey
|
||||||
|
// Deprecated: Use KeyShareKeys instead. This variable is no longer used.
|
||||||
|
// Will be removed in the future.
|
||||||
KeySharesParams *KeySharesParameters
|
KeySharesParams *KeySharesParameters
|
||||||
KEMKey *KemPrivateKey
|
// Deprecated: Use KeyShareKeys instead. This variable is no longer used.
|
||||||
|
// Will be removed in the future.
|
||||||
|
KEMKey *KemPrivateKey
|
||||||
|
|
||||||
KeyShareKeys *KeySharePrivateKeys
|
KeyShareKeys *KeySharePrivateKeys
|
||||||
Suite *PubCipherSuiteTLS13
|
Suite *PubCipherSuiteTLS13
|
||||||
|
@ -62,46 +66,11 @@ type TLS12OnlyState struct {
|
||||||
Suite PubCipherSuite
|
Suite PubCipherSuite
|
||||||
}
|
}
|
||||||
|
|
||||||
// func mlkemCirclToGo(circlKey kem.PrivateKey) (*mlkem768.DecapsulationKey, *ecdh.PrivateKey, error) {
|
|
||||||
// if circlKey.Scheme().Name() != "Kyber768-X25519" {
|
|
||||||
// return nil, nil, fmt.Errorf("circl key is not Kyber768-X25519")
|
|
||||||
// }
|
|
||||||
|
|
||||||
// encodedKey, err := circlKey.MarshalBinary()
|
|
||||||
// if err != nil {
|
|
||||||
// return nil, nil, err
|
|
||||||
// }
|
|
||||||
|
|
||||||
// ecdhKey := encodedKey[:x25519PublicKeySize]
|
|
||||||
// kyberKey := encodedKey[x25519PublicKeySize:]
|
|
||||||
|
|
||||||
// goKyberkey, err := mlkem768.NewKeyFromExtendedEncoding(kyberKey)
|
|
||||||
// if err != nil {
|
|
||||||
// return nil, nil, err
|
|
||||||
// }
|
|
||||||
|
|
||||||
// goEcdhKey, err := ecdh.X25519().NewPrivateKey(ecdhKey)
|
|
||||||
// if err != nil {
|
|
||||||
// return nil, nil, err
|
|
||||||
// }
|
|
||||||
|
|
||||||
// return goKyberkey, goEcdhKey, nil
|
|
||||||
// }
|
|
||||||
|
|
||||||
func (chs *TLS13OnlyState) private13KeyShareKeys() *keySharePrivateKeys {
|
func (chs *TLS13OnlyState) private13KeyShareKeys() *keySharePrivateKeys {
|
||||||
if chs.KeyShareKeys != nil {
|
if chs.KeyShareKeys != nil {
|
||||||
return chs.KeyShareKeys.ToPrivate()
|
return chs.KeyShareKeys.ToPrivate()
|
||||||
}
|
}
|
||||||
|
|
||||||
// if chs.KEMKey != nil {
|
|
||||||
// if kyberKey, ecdhKey, err := mlkemCirclToGo(chs.KEMKey.SecretKey); err == nil {
|
|
||||||
// return &keySharePrivateKeys{
|
|
||||||
// kyber: kyberKey,
|
|
||||||
// ecdhe: ecdhKey,
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
if chs.EcdheKey != nil {
|
if chs.EcdheKey != nil {
|
||||||
return &keySharePrivateKeys{
|
return &keySharePrivateKeys{
|
||||||
ecdhe: chs.EcdheKey,
|
ecdhe: chs.EcdheKey,
|
||||||
|
@ -120,11 +89,10 @@ func (chs *PubClientHandshakeState) toPrivate13() *clientHandshakeStateTLS13 {
|
||||||
return nil
|
return nil
|
||||||
} else {
|
} else {
|
||||||
return &clientHandshakeStateTLS13{
|
return &clientHandshakeStateTLS13{
|
||||||
c: chs.C,
|
c: chs.C,
|
||||||
serverHello: chs.ServerHello.getPrivatePtr(),
|
serverHello: chs.ServerHello.getPrivatePtr(),
|
||||||
hello: chs.Hello.getPrivatePtr(),
|
hello: chs.Hello.getPrivatePtr(),
|
||||||
keyShareKeys: chs.State13.private13KeyShareKeys(),
|
keyShareKeys: chs.State13.private13KeyShareKeys(),
|
||||||
keySharesParams: chs.State13.KeySharesParams,
|
|
||||||
|
|
||||||
session: chs.Session,
|
session: chs.Session,
|
||||||
binderKey: chs.State13.BinderKey,
|
binderKey: chs.State13.BinderKey,
|
||||||
|
@ -146,16 +114,15 @@ func (chs13 *clientHandshakeStateTLS13) toPublic13() *PubClientHandshakeState {
|
||||||
return nil
|
return nil
|
||||||
} else {
|
} else {
|
||||||
tls13State := TLS13OnlyState{
|
tls13State := TLS13OnlyState{
|
||||||
KeySharesParams: chs13.keySharesParams,
|
KeyShareKeys: chs13.keyShareKeys.ToPublic(),
|
||||||
KeyShareKeys: chs13.keyShareKeys.ToPublic(),
|
EarlySecret: chs13.earlySecret.Secret(),
|
||||||
EarlySecret: chs13.earlySecret.Secret(),
|
BinderKey: chs13.binderKey,
|
||||||
BinderKey: chs13.binderKey,
|
CertReq: chs13.certReq.toPublic(),
|
||||||
CertReq: chs13.certReq.toPublic(),
|
UsingPSK: chs13.usingPSK,
|
||||||
UsingPSK: chs13.usingPSK,
|
SentDummyCCS: chs13.sentDummyCCS,
|
||||||
SentDummyCCS: chs13.sentDummyCCS,
|
Suite: chs13.suite.toPublic(),
|
||||||
Suite: chs13.suite.toPublic(),
|
TrafficSecret: chs13.trafficSecret,
|
||||||
TrafficSecret: chs13.trafficSecret,
|
Transcript: chs13.transcript,
|
||||||
Transcript: chs13.transcript,
|
|
||||||
}
|
}
|
||||||
return &PubClientHandshakeState{
|
return &PubClientHandshakeState{
|
||||||
C: chs13.c,
|
C: chs13.c,
|
||||||
|
@ -891,6 +858,8 @@ type kemPrivateKey struct {
|
||||||
curveID CurveID
|
curveID CurveID
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Deprecated: Use KeySharePrivateKeys instead. This type is no longer used.
|
||||||
|
// Will be removed in the future.
|
||||||
type KemPrivateKey struct {
|
type KemPrivateKey struct {
|
||||||
SecretKey kem.PrivateKey
|
SecretKey kem.PrivateKey
|
||||||
CurveID CurveID
|
CurveID CurveID
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue