mirror of
https://github.com/refraction-networking/utls.git
synced 2025-04-03 20:17:36 +03:00
crypto/ecdh: new package
We use crypto/internal/edwards25519/field to implement X25519 directly, so that golang.org/x/crypto/curve25519 can be dropped from the src module dependencies, and eventually replaced with a crypto/ecdh wrapper, removing the need to keep golang.org/x/crypto/curve25519/internal/field in sync with crypto/internal/edwards25519/field. In crypto/internal/nistec, we add BytesX to serialize only the x coordinate, which we'll need for the horrible ECDSA x-coord-to-scalar operation, too. In crypto/tls, we replace the ECDHE implementation with crypto/ecdh, dropping the X25519 special cases and related scaffolding. Finally, FINALLY, we deprecate the ~white whale~ big.Int-based APIs of the crypto/elliptic package. •_•) ( •_•)>⌐■-■ (⌐■_■) Fixes #52182 Fixes #34648 Fixes #52221 Change-Id: Iccdda210319cc892e96bb28a0e7b7123551982c7 Reviewed-on: https://go-review.googlesource.com/c/go/+/398914 Reviewed-by: Fernando Lobato Meeser <felobato@google.com> Reviewed-by: Roland Shoemaker <roland@golang.org> Run-TryBot: Filippo Valsorda <filippo@golang.org> TryBot-Result: Gopher Robot <gobot@golang.org>
This commit is contained in:
parent
8011ffeccb
commit
f80ca9c941
6 changed files with 85 additions and 121 deletions
|
@ -6,6 +6,7 @@ package tls
|
|||
|
||||
import (
|
||||
"crypto"
|
||||
"crypto/ecdh"
|
||||
"crypto/md5"
|
||||
"crypto/rsa"
|
||||
"crypto/sha1"
|
||||
|
@ -157,7 +158,7 @@ func hashForServerKeyExchange(sigType uint8, hashFunc crypto.Hash, version uint1
|
|||
type ecdheKeyAgreement struct {
|
||||
version uint16
|
||||
isRSA bool
|
||||
params ecdheParameters
|
||||
key *ecdh.PrivateKey
|
||||
|
||||
// ckx and preMasterSecret are generated in processServerKeyExchange
|
||||
// and returned in generateClientKeyExchange.
|
||||
|
@ -177,18 +178,18 @@ func (ka *ecdheKeyAgreement) generateServerKeyExchange(config *Config, cert *Cer
|
|||
if curveID == 0 {
|
||||
return nil, errors.New("tls: no supported elliptic curves offered")
|
||||
}
|
||||
if _, ok := curveForCurveID(curveID); curveID != X25519 && !ok {
|
||||
if _, ok := curveForCurveID(curveID); !ok {
|
||||
return nil, errors.New("tls: CurvePreferences includes unsupported curve")
|
||||
}
|
||||
|
||||
params, err := generateECDHEParameters(config.rand(), curveID)
|
||||
key, err := generateECDHEKey(config.rand(), curveID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ka.params = params
|
||||
ka.key = key
|
||||
|
||||
// See RFC 4492, Section 5.4.
|
||||
ecdhePublic := params.PublicKey()
|
||||
ecdhePublic := key.PublicKey().Bytes()
|
||||
serverECDHEParams := make([]byte, 1+2+1+len(ecdhePublic))
|
||||
serverECDHEParams[0] = 3 // named curve
|
||||
serverECDHEParams[1] = byte(curveID >> 8)
|
||||
|
@ -259,8 +260,12 @@ func (ka *ecdheKeyAgreement) processClientKeyExchange(config *Config, cert *Cert
|
|||
return nil, errClientKeyExchange
|
||||
}
|
||||
|
||||
preMasterSecret := ka.params.SharedKey(ckx.ciphertext[1:])
|
||||
if preMasterSecret == nil {
|
||||
peerKey, err := ka.key.Curve().NewPublicKey(ckx.ciphertext[1:])
|
||||
if err != nil {
|
||||
return nil, errClientKeyExchange
|
||||
}
|
||||
preMasterSecret, err := ka.key.Curve().ECDH(ka.key, peerKey)
|
||||
if err != nil {
|
||||
return nil, errClientKeyExchange
|
||||
}
|
||||
|
||||
|
@ -288,22 +293,26 @@ func (ka *ecdheKeyAgreement) processServerKeyExchange(config *Config, clientHell
|
|||
return errServerKeyExchange
|
||||
}
|
||||
|
||||
if _, ok := curveForCurveID(curveID); curveID != X25519 && !ok {
|
||||
if _, ok := curveForCurveID(curveID); !ok {
|
||||
return errors.New("tls: server selected unsupported curve")
|
||||
}
|
||||
|
||||
params, err := generateECDHEParameters(config.rand(), curveID)
|
||||
key, err := generateECDHEKey(config.rand(), curveID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ka.params = params
|
||||
ka.key = key
|
||||
|
||||
ka.preMasterSecret = params.SharedKey(publicKey)
|
||||
if ka.preMasterSecret == nil {
|
||||
peerKey, err := key.Curve().NewPublicKey(publicKey)
|
||||
if err != nil {
|
||||
return errServerKeyExchange
|
||||
}
|
||||
ka.preMasterSecret, err = key.Curve().ECDH(key, peerKey)
|
||||
if err != nil {
|
||||
return errServerKeyExchange
|
||||
}
|
||||
|
||||
ourPublicKey := params.PublicKey()
|
||||
ourPublicKey := key.PublicKey().Bytes()
|
||||
ka.ckx = new(clientKeyExchangeMsg)
|
||||
ka.ckx.ciphertext = make([]byte, 1+len(ourPublicKey))
|
||||
ka.ckx.ciphertext[0] = byte(len(ourPublicKey))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue