mirror of
https://github.com/refraction-networking/utls.git
synced 2025-03-31 10:37: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,
|
||||
binderKey: binderKey,
|
||||
echContext: ech,
|
||||
|
||||
keySharesParams: NewKeySharesParameters(), // [uTLS]
|
||||
}
|
||||
return hs.handshake()
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@ import (
|
|||
"bytes"
|
||||
"context"
|
||||
"crypto"
|
||||
"crypto/ecdh"
|
||||
"crypto/hmac"
|
||||
"crypto/mlkem"
|
||||
"crypto/rsa"
|
||||
|
@ -19,74 +18,16 @@ import (
|
|||
"slices"
|
||||
"time"
|
||||
|
||||
"github.com/cloudflare/circl/kem"
|
||||
"github.com/refraction-networking/utls/internal/hkdf"
|
||||
"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 {
|
||||
c *Conn
|
||||
ctx context.Context
|
||||
serverHello *serverHelloMsg
|
||||
hello *clientHelloMsg
|
||||
keyShareKeys *keySharePrivateKeys
|
||||
keySharesParams *KeySharesParameters // [uTLS] support both ecdhe and kem
|
||||
c *Conn
|
||||
ctx context.Context
|
||||
serverHello *serverHelloMsg
|
||||
hello *clientHelloMsg
|
||||
keyShareKeys *keySharePrivateKeys
|
||||
|
||||
session *SessionState
|
||||
earlySecret *tls13.EarlySecret
|
||||
|
@ -117,24 +58,6 @@ func (hs *clientHandshakeStateTLS13) handshake() error {
|
|||
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.
|
||||
if hs.keyShareKeys == nil || hs.keyShareKeys.ecdhe == nil || len(hs.hello.keyShares) == 0 {
|
||||
return c.sendAlert(alertInternalError)
|
||||
|
|
29
u_alias.go
29
u_alias.go
|
@ -1,5 +1,11 @@
|
|||
package tls
|
||||
|
||||
import (
|
||||
"crypto/ecdh"
|
||||
|
||||
"github.com/cloudflare/circl/kem"
|
||||
)
|
||||
|
||||
// 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
|
||||
// backwards compatibility with the old version of the library.
|
||||
|
@ -10,3 +16,26 @@ package tls
|
|||
//
|
||||
// Deprecated: Use ExtendedMasterSecretExtension instead.
|
||||
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 {
|
||||
uconn.HandshakeState.State13.KeyShareKeys = &KeySharePrivateKeys{}
|
||||
}
|
||||
uconn.HandshakeState.State13.KeySharesParams = NewKeySharesParameters()
|
||||
uconn.echCtx = ech
|
||||
hello := uconn.HandshakeState.Hello
|
||||
|
||||
|
@ -2750,12 +2749,6 @@ func (uconn *UConn) ApplyPreset(p *ClientHelloSpec) error {
|
|||
return err
|
||||
}
|
||||
|
||||
// circlKyberKey, err := kyberGoToCircl(kyberKey, ecdheKey)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
// uconn.HandshakeState.State13.KeySharesParams.AddKemKeypair(curveID, circlKyberKey, circlKyberKey.Public())
|
||||
|
||||
if curveID == X25519Kyber768Draft00 {
|
||||
ext.KeyShares[i].Data = append(ecdheKey.PublicKey().Bytes(), mlkemKey.EncapsulationKey().Bytes()...)
|
||||
} else {
|
||||
|
@ -2770,7 +2763,6 @@ func (uconn *UConn) ApplyPreset(p *ClientHelloSpec) error {
|
|||
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.
|
||||
uconn.HandshakeState.State13.KeyShareKeys.Ecdhe = ecdheKey
|
||||
// uconn.HandshakeState.State13.KeySharesParams.AddEcdheKeypair(curveID, ecdheKey, ecdheKey.PublicKey())
|
||||
ext.KeyShares[i+1].Data = ecdheKey.PublicKey().Bytes()
|
||||
}
|
||||
} else {
|
||||
|
@ -2780,8 +2772,6 @@ func (uconn *UConn) ApplyPreset(p *ClientHelloSpec) error {
|
|||
"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()
|
||||
if !preferredCurveIsSet {
|
||||
// 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 {
|
||||
// Deprecated: Use KeyShareKeys instead. KeyShareKeys will take precedence if both are set.
|
||||
// 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
|
||||
KEMKey *KemPrivateKey
|
||||
// Deprecated: Use KeyShareKeys instead. This variable is no longer used.
|
||||
// Will be removed in the future.
|
||||
KEMKey *KemPrivateKey
|
||||
|
||||
KeyShareKeys *KeySharePrivateKeys
|
||||
Suite *PubCipherSuiteTLS13
|
||||
|
@ -62,46 +66,11 @@ type TLS12OnlyState struct {
|
|||
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 {
|
||||
if chs.KeyShareKeys != nil {
|
||||
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 {
|
||||
return &keySharePrivateKeys{
|
||||
ecdhe: chs.EcdheKey,
|
||||
|
@ -120,11 +89,10 @@ func (chs *PubClientHandshakeState) toPrivate13() *clientHandshakeStateTLS13 {
|
|||
return nil
|
||||
} else {
|
||||
return &clientHandshakeStateTLS13{
|
||||
c: chs.C,
|
||||
serverHello: chs.ServerHello.getPrivatePtr(),
|
||||
hello: chs.Hello.getPrivatePtr(),
|
||||
keyShareKeys: chs.State13.private13KeyShareKeys(),
|
||||
keySharesParams: chs.State13.KeySharesParams,
|
||||
c: chs.C,
|
||||
serverHello: chs.ServerHello.getPrivatePtr(),
|
||||
hello: chs.Hello.getPrivatePtr(),
|
||||
keyShareKeys: chs.State13.private13KeyShareKeys(),
|
||||
|
||||
session: chs.Session,
|
||||
binderKey: chs.State13.BinderKey,
|
||||
|
@ -146,16 +114,15 @@ func (chs13 *clientHandshakeStateTLS13) toPublic13() *PubClientHandshakeState {
|
|||
return nil
|
||||
} else {
|
||||
tls13State := TLS13OnlyState{
|
||||
KeySharesParams: chs13.keySharesParams,
|
||||
KeyShareKeys: chs13.keyShareKeys.ToPublic(),
|
||||
EarlySecret: chs13.earlySecret.Secret(),
|
||||
BinderKey: chs13.binderKey,
|
||||
CertReq: chs13.certReq.toPublic(),
|
||||
UsingPSK: chs13.usingPSK,
|
||||
SentDummyCCS: chs13.sentDummyCCS,
|
||||
Suite: chs13.suite.toPublic(),
|
||||
TrafficSecret: chs13.trafficSecret,
|
||||
Transcript: chs13.transcript,
|
||||
KeyShareKeys: chs13.keyShareKeys.ToPublic(),
|
||||
EarlySecret: chs13.earlySecret.Secret(),
|
||||
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,
|
||||
|
@ -891,6 +858,8 @@ type kemPrivateKey struct {
|
|||
curveID CurveID
|
||||
}
|
||||
|
||||
// Deprecated: Use KeySharePrivateKeys instead. This type is no longer used.
|
||||
// Will be removed in the future.
|
||||
type KemPrivateKey struct {
|
||||
SecretKey kem.PrivateKey
|
||||
CurveID CurveID
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue