2014-06-20 20:00:00 +01:00
// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
2015-09-29 23:21:04 +01:00
package runner
2014-06-20 20:00:00 +01:00
import (
"crypto/ecdsa"
"crypto/elliptic"
2014-08-02 22:35:45 +01:00
"crypto/rand"
2014-06-20 20:00:00 +01:00
"crypto/rsa"
2015-12-19 03:13:41 +00:00
"crypto/subtle"
2014-06-20 20:00:00 +01:00
"crypto/x509"
"errors"
2015-11-27 00:39:08 +00:00
"fmt"
2014-06-20 20:00:00 +01:00
"io"
"math/big"
2015-12-19 03:13:41 +00:00
"./curve25519"
2016-05-17 00:31:05 +01:00
"./newhope"
2014-06-20 20:00:00 +01:00
)
2016-06-21 23:19:24 +01:00
type keyType int
const (
keyTypeRSA keyType = iota + 1
keyTypeECDSA
)
2014-06-20 20:00:00 +01:00
var errClientKeyExchange = errors . New ( "tls: invalid ClientKeyExchange message" )
var errServerKeyExchange = errors . New ( "tls: invalid ServerKeyExchange message" )
// rsaKeyAgreement implements the standard TLS key agreement where the client
// encrypts the pre-master secret to the server's public key.
2014-12-11 09:22:37 +00:00
type rsaKeyAgreement struct {
2015-02-26 20:16:22 +00:00
version uint16
2014-12-11 09:22:37 +00:00
clientVersion uint16
2015-02-26 20:16:22 +00:00
exportKey * rsa . PrivateKey
2014-12-11 09:22:37 +00:00
}
func ( ka * rsaKeyAgreement ) generateServerKeyExchange ( config * Config , cert * Certificate , clientHello * clientHelloMsg , hello * serverHelloMsg ) ( * serverKeyExchangeMsg , error ) {
// Save the client version for comparison later.
ka . clientVersion = versionToWire ( clientHello . vers , clientHello . isDTLS )
2014-06-20 20:00:00 +01:00
2015-02-26 20:16:22 +00:00
if ! config . Bugs . RSAEphemeralKey {
return nil , nil
2014-11-08 16:41:14 +00:00
}
2015-02-26 20:16:22 +00:00
// Generate an ephemeral RSA key to use instead of the real
// one, as in RSA_EXPORT.
key , err := rsa . GenerateKey ( config . rand ( ) , 512 )
if err != nil {
return nil , err
}
ka . exportKey = key
modulus := key . N . Bytes ( )
exponent := big . NewInt ( int64 ( key . E ) ) . Bytes ( )
serverRSAParams := make ( [ ] byte , 0 , 2 + len ( modulus ) + 2 + len ( exponent ) )
serverRSAParams = append ( serverRSAParams , byte ( len ( modulus ) >> 8 ) , byte ( len ( modulus ) ) )
serverRSAParams = append ( serverRSAParams , modulus ... )
serverRSAParams = append ( serverRSAParams , byte ( len ( exponent ) >> 8 ) , byte ( len ( exponent ) ) )
serverRSAParams = append ( serverRSAParams , exponent ... )
2016-06-21 23:19:24 +01:00
var sigAlg signatureAlgorithm
2015-02-26 20:16:22 +00:00
if ka . version >= VersionTLS12 {
2016-07-10 05:02:01 +01:00
sigAlg , err = selectSignatureAlgorithm ( ka . version , cert . PrivateKey , config , clientHello . signatureAlgorithms )
2016-06-21 23:19:24 +01:00
if err != nil {
2015-02-26 20:16:22 +00:00
return nil , err
}
}
2016-06-21 23:19:24 +01:00
sig , err := signMessage ( ka . version , cert . PrivateKey , config , sigAlg , serverRSAParams )
2015-02-26 20:16:22 +00:00
if err != nil {
return nil , errors . New ( "failed to sign RSA parameters: " + err . Error ( ) )
}
skx := new ( serverKeyExchangeMsg )
2016-06-21 23:19:24 +01:00
sigAlgsLen := 0
2015-02-26 20:16:22 +00:00
if ka . version >= VersionTLS12 {
2016-06-21 23:19:24 +01:00
sigAlgsLen = 2
2015-02-26 20:16:22 +00:00
}
2016-06-21 23:19:24 +01:00
skx . key = make ( [ ] byte , len ( serverRSAParams ) + sigAlgsLen + 2 + len ( sig ) )
2015-02-26 20:16:22 +00:00
copy ( skx . key , serverRSAParams )
k := skx . key [ len ( serverRSAParams ) : ]
if ka . version >= VersionTLS12 {
2016-06-21 23:19:24 +01:00
k [ 0 ] = byte ( sigAlg >> 8 )
k [ 1 ] = byte ( sigAlg )
2015-02-26 20:16:22 +00:00
k = k [ 2 : ]
}
k [ 0 ] = byte ( len ( sig ) >> 8 )
k [ 1 ] = byte ( len ( sig ) )
copy ( k [ 2 : ] , sig )
return skx , nil
2014-06-20 20:00:00 +01:00
}
2014-12-11 09:22:37 +00:00
func ( ka * rsaKeyAgreement ) processClientKeyExchange ( config * Config , cert * Certificate , ckx * clientKeyExchangeMsg , version uint16 ) ( [ ] byte , error ) {
2014-06-20 20:00:00 +01:00
preMasterSecret := make ( [ ] byte , 48 )
_ , err := io . ReadFull ( config . rand ( ) , preMasterSecret [ 2 : ] )
if err != nil {
return nil , err
}
if len ( ckx . ciphertext ) < 2 {
return nil , errClientKeyExchange
}
ciphertext := ckx . ciphertext
if version != VersionSSL30 {
ciphertextLen := int ( ckx . ciphertext [ 0 ] ) << 8 | int ( ckx . ciphertext [ 1 ] )
if ciphertextLen != len ( ckx . ciphertext ) - 2 {
return nil , errClientKeyExchange
}
ciphertext = ckx . ciphertext [ 2 : ]
}
2015-02-26 20:16:22 +00:00
key := cert . PrivateKey . ( * rsa . PrivateKey )
if ka . exportKey != nil {
key = ka . exportKey
}
err = rsa . DecryptPKCS1v15SessionKey ( config . rand ( ) , key , ciphertext , preMasterSecret )
2014-06-20 20:00:00 +01:00
if err != nil {
return nil , err
}
2014-12-11 09:22:37 +00:00
// This check should be done in constant-time, but this is a testing
// implementation. See the discussion at the end of section 7.4.7.1 of
// RFC 4346.
vers := uint16 ( preMasterSecret [ 0 ] ) << 8 | uint16 ( preMasterSecret [ 1 ] )
if ka . clientVersion != vers {
return nil , errors . New ( "tls: invalid version in RSA premaster" )
}
2014-06-20 20:00:00 +01:00
return preMasterSecret , nil
}
2014-12-11 09:22:37 +00:00
func ( ka * rsaKeyAgreement ) processServerKeyExchange ( config * Config , clientHello * clientHelloMsg , serverHello * serverHelloMsg , cert * x509 . Certificate , skx * serverKeyExchangeMsg ) error {
2014-06-20 20:00:00 +01:00
return errors . New ( "tls: unexpected ServerKeyExchange" )
}
2014-12-11 09:22:37 +00:00
func ( ka * rsaKeyAgreement ) generateClientKeyExchange ( config * Config , clientHello * clientHelloMsg , cert * x509 . Certificate ) ( [ ] byte , * clientKeyExchangeMsg , error ) {
2015-12-01 23:53:13 +00:00
bad := config . Bugs . BadRSAClientKeyExchange
2014-06-20 20:00:00 +01:00
preMasterSecret := make ( [ ] byte , 48 )
2014-08-07 03:11:10 +01:00
vers := clientHello . vers
2015-12-01 23:53:13 +00:00
if bad == RSABadValueWrongVersion {
vers ^ = 1
2014-08-07 03:11:10 +01:00
}
2014-08-04 06:23:53 +01:00
vers = versionToWire ( vers , clientHello . isDTLS )
2014-08-07 03:11:10 +01:00
preMasterSecret [ 0 ] = byte ( vers >> 8 )
preMasterSecret [ 1 ] = byte ( vers )
2014-06-20 20:00:00 +01:00
_ , err := io . ReadFull ( config . rand ( ) , preMasterSecret [ 2 : ] )
if err != nil {
return nil , nil , err
}
2015-12-01 23:53:13 +00:00
sentPreMasterSecret := preMasterSecret
if bad == RSABadValueTooLong {
sentPreMasterSecret = make ( [ ] byte , len ( sentPreMasterSecret ) + 1 )
copy ( sentPreMasterSecret , preMasterSecret )
} else if bad == RSABadValueTooShort {
sentPreMasterSecret = sentPreMasterSecret [ : len ( sentPreMasterSecret ) - 1 ]
}
encrypted , err := rsa . EncryptPKCS1v15 ( config . rand ( ) , cert . PublicKey . ( * rsa . PublicKey ) , sentPreMasterSecret )
2014-06-20 20:00:00 +01:00
if err != nil {
return nil , nil , err
}
2015-12-01 23:53:13 +00:00
if bad == RSABadValueCorrupt {
2015-12-15 20:37:39 +00:00
encrypted [ len ( encrypted ) - 1 ] ^ = 1
// Clear the high byte to ensure |encrypted| is still below the RSA modulus.
encrypted [ 0 ] = 0
2015-12-01 23:53:13 +00:00
}
2014-06-20 20:00:00 +01:00
ckx := new ( clientKeyExchangeMsg )
2015-11-19 01:35:31 +00:00
if clientHello . vers != VersionSSL30 {
2014-08-14 21:25:34 +01:00
ckx . ciphertext = make ( [ ] byte , len ( encrypted ) + 2 )
ckx . ciphertext [ 0 ] = byte ( len ( encrypted ) >> 8 )
ckx . ciphertext [ 1 ] = byte ( len ( encrypted ) )
copy ( ckx . ciphertext [ 2 : ] , encrypted )
} else {
ckx . ciphertext = encrypted
}
2014-06-20 20:00:00 +01:00
return preMasterSecret , ckx , nil
}
2016-06-21 23:19:24 +01:00
func ( ka * rsaKeyAgreement ) peerSignatureAlgorithm ( ) signatureAlgorithm {
return 0
2014-06-20 20:00:00 +01:00
}
2015-12-19 03:13:41 +00:00
// A ecdhCurve is an instance of ECDH-style key agreement for TLS.
type ecdhCurve interface {
2016-05-16 22:27:14 +01:00
// offer generates a keypair using rand. It returns the encoded |publicKey|.
offer ( rand io . Reader ) ( publicKey [ ] byte , err error )
2015-12-19 03:13:41 +00:00
2016-05-16 22:27:14 +01:00
// accept responds to the |peerKey| generated by |offer| with the acceptor's
// |publicKey|, and returns agreed-upon |preMasterSecret| to the acceptor.
accept ( rand io . Reader , peerKey [ ] byte ) ( publicKey [ ] byte , preMasterSecret [ ] byte , err error )
// finish returns the computed |preMasterSecret|, given the |peerKey|
// generated by |accept|.
finish ( peerKey [ ] byte ) ( preMasterSecret [ ] byte , err error )
2015-12-19 03:13:41 +00:00
}
// ellipticECDHCurve implements ecdhCurve with an elliptic.Curve.
type ellipticECDHCurve struct {
curve elliptic . Curve
privateKey [ ] byte
}
2016-05-16 22:27:14 +01:00
func ( e * ellipticECDHCurve ) offer ( rand io . Reader ) ( publicKey [ ] byte , err error ) {
2015-12-19 03:13:41 +00:00
var x , y * big . Int
e . privateKey , x , y , err = elliptic . GenerateKey ( e . curve , rand )
if err != nil {
return nil , err
}
return elliptic . Marshal ( e . curve , x , y ) , nil
}
2016-05-16 22:27:14 +01:00
func ( e * ellipticECDHCurve ) accept ( rand io . Reader , peerKey [ ] byte ) ( publicKey [ ] byte , preMasterSecret [ ] byte , err error ) {
publicKey , err = e . offer ( rand )
if err != nil {
return nil , nil , err
}
preMasterSecret , err = e . finish ( peerKey )
if err != nil {
return nil , nil , err
}
return
}
func ( e * ellipticECDHCurve ) finish ( peerKey [ ] byte ) ( preMasterSecret [ ] byte , err error ) {
2015-12-19 03:13:41 +00:00
x , y := elliptic . Unmarshal ( e . curve , peerKey )
if x == nil {
return nil , errors . New ( "tls: invalid peer key" )
}
x , _ = e . curve . ScalarMult ( x , y , e . privateKey )
preMasterSecret = make ( [ ] byte , ( e . curve . Params ( ) . BitSize + 7 ) >> 3 )
xBytes := x . Bytes ( )
copy ( preMasterSecret [ len ( preMasterSecret ) - len ( xBytes ) : ] , xBytes )
return preMasterSecret , nil
}
// x25519ECDHCurve implements ecdhCurve with X25519.
type x25519ECDHCurve struct {
privateKey [ 32 ] byte
}
2016-05-16 22:27:14 +01:00
func ( e * x25519ECDHCurve ) offer ( rand io . Reader ) ( publicKey [ ] byte , err error ) {
2015-12-19 03:13:41 +00:00
_ , err = io . ReadFull ( rand , e . privateKey [ : ] )
if err != nil {
return
}
var out [ 32 ] byte
curve25519 . ScalarBaseMult ( & out , & e . privateKey )
return out [ : ] , nil
}
2016-05-16 22:27:14 +01:00
func ( e * x25519ECDHCurve ) accept ( rand io . Reader , peerKey [ ] byte ) ( publicKey [ ] byte , preMasterSecret [ ] byte , err error ) {
publicKey , err = e . offer ( rand )
if err != nil {
return nil , nil , err
}
preMasterSecret , err = e . finish ( peerKey )
if err != nil {
return nil , nil , err
}
return
}
func ( e * x25519ECDHCurve ) finish ( peerKey [ ] byte ) ( preMasterSecret [ ] byte , err error ) {
2015-12-19 03:13:41 +00:00
if len ( peerKey ) != 32 {
return nil , errors . New ( "tls: invalid peer key" )
}
var out , peerKeyCopy [ 32 ] byte
copy ( peerKeyCopy [ : ] , peerKey )
curve25519 . ScalarMult ( & out , & e . privateKey , & peerKeyCopy )
2016-01-23 06:04:15 +00:00
// Per RFC 7748, reject the all-zero value in constant time.
2015-12-19 03:13:41 +00:00
var zeros [ 32 ] byte
if subtle . ConstantTimeCompare ( zeros [ : ] , out [ : ] ) == 1 {
return nil , errors . New ( "tls: X25519 value with wrong order" )
}
return out [ : ] , nil
}
2016-05-17 00:31:05 +01:00
// cecpq1Curve is combined elliptic curve (X25519) and post-quantum (new hope) key
// agreement.
type cecpq1Curve struct {
x25519 * x25519ECDHCurve
newhope * newhope . Poly
}
func ( e * cecpq1Curve ) offer ( rand io . Reader ) ( publicKey [ ] byte , err error ) {
var x25519OfferMsg , newhopeOfferMsg [ ] byte
e . x25519 = new ( x25519ECDHCurve )
if x25519OfferMsg , err = e . x25519 . offer ( rand ) ; err != nil {
return nil , err
}
newhopeOfferMsg , e . newhope = newhope . Offer ( rand )
return append ( x25519OfferMsg , newhopeOfferMsg [ : ] ... ) , nil
}
func ( e * cecpq1Curve ) accept ( rand io . Reader , peerKey [ ] byte ) ( publicKey [ ] byte , preMasterSecret [ ] byte , err error ) {
if len ( peerKey ) != 32 + newhope . OfferMsgLen {
return nil , nil , errors . New ( "cecpq1: invalid offer message" )
}
var x25519AcceptMsg , newhopeAcceptMsg [ ] byte
var x25519Secret [ ] byte
var newhopeSecret newhope . Key
x25519 := new ( x25519ECDHCurve )
if x25519AcceptMsg , x25519Secret , err = x25519 . accept ( rand , peerKey [ : 32 ] ) ; err != nil {
return nil , nil , err
}
if newhopeSecret , newhopeAcceptMsg , err = newhope . Accept ( rand , peerKey [ 32 : ] ) ; err != nil {
return nil , nil , err
}
return append ( x25519AcceptMsg , newhopeAcceptMsg [ : ] ... ) , append ( x25519Secret , newhopeSecret [ : ] ... ) , nil
}
func ( e * cecpq1Curve ) finish ( peerKey [ ] byte ) ( preMasterSecret [ ] byte , err error ) {
if len ( peerKey ) != 32 + newhope . AcceptMsgLen {
return nil , errors . New ( "cecpq1: invalid accept message" )
}
var x25519Secret [ ] byte
var newhopeSecret newhope . Key
if x25519Secret , err = e . x25519 . finish ( peerKey [ : 32 ] ) ; err != nil {
return nil , err
}
if newhopeSecret , err = e . newhope . Finish ( peerKey [ 32 : ] ) ; err != nil {
return nil , err
}
return append ( x25519Secret , newhopeSecret [ : ] ... ) , nil
}
2015-12-19 03:13:41 +00:00
func curveForCurveID ( id CurveID ) ( ecdhCurve , bool ) {
2014-06-20 20:00:00 +01:00
switch id {
2015-04-20 16:13:01 +01:00
case CurveP224 :
2015-12-19 03:13:41 +00:00
return & ellipticECDHCurve { curve : elliptic . P224 ( ) } , true
2014-06-20 20:00:00 +01:00
case CurveP256 :
2015-12-19 03:13:41 +00:00
return & ellipticECDHCurve { curve : elliptic . P256 ( ) } , true
2014-06-20 20:00:00 +01:00
case CurveP384 :
2015-12-19 03:13:41 +00:00
return & ellipticECDHCurve { curve : elliptic . P384 ( ) } , true
2014-06-20 20:00:00 +01:00
case CurveP521 :
2015-12-19 03:13:41 +00:00
return & ellipticECDHCurve { curve : elliptic . P521 ( ) } , true
case CurveX25519 :
return & x25519ECDHCurve { } , true
2014-06-20 20:00:00 +01:00
default :
return nil , false
}
}
2014-10-27 06:23:15 +00:00
// keyAgreementAuthentication is a helper interface that specifies how
// to authenticate the ServerKeyExchange parameters.
type keyAgreementAuthentication interface {
signParameters ( config * Config , cert * Certificate , clientHello * clientHelloMsg , hello * serverHelloMsg , params [ ] byte ) ( * serverKeyExchangeMsg , error )
verifyParameters ( config * Config , clientHello * clientHelloMsg , serverHello * serverHelloMsg , cert * x509 . Certificate , params [ ] byte , sig [ ] byte ) error
}
// nilKeyAgreementAuthentication does not authenticate the key
// agreement parameters.
type nilKeyAgreementAuthentication struct { }
func ( ka * nilKeyAgreementAuthentication ) signParameters ( config * Config , cert * Certificate , clientHello * clientHelloMsg , hello * serverHelloMsg , params [ ] byte ) ( * serverKeyExchangeMsg , error ) {
skx := new ( serverKeyExchangeMsg )
skx . key = params
return skx , nil
}
func ( ka * nilKeyAgreementAuthentication ) verifyParameters ( config * Config , clientHello * clientHelloMsg , serverHello * serverHelloMsg , cert * x509 . Certificate , params [ ] byte , sig [ ] byte ) error {
return nil
}
// signedKeyAgreement signs the ServerKeyExchange parameters with the
// server's private key.
2014-08-02 22:35:45 +01:00
type signedKeyAgreement struct {
2016-06-21 23:19:24 +01:00
keyType keyType
version uint16
peerSignatureAlgorithm signatureAlgorithm
2014-06-20 20:00:00 +01:00
}
2014-08-02 22:35:45 +01:00
func ( ka * signedKeyAgreement ) signParameters ( config * Config , cert * Certificate , clientHello * clientHelloMsg , hello * serverHelloMsg , params [ ] byte ) ( * serverKeyExchangeMsg , error ) {
2016-06-21 23:19:24 +01:00
// The message to be signed is prepended by the randoms.
var msg [ ] byte
msg = append ( msg , clientHello . random ... )
msg = append ( msg , hello . random ... )
msg = append ( msg , params ... )
var sigAlg signatureAlgorithm
2014-08-02 22:35:45 +01:00
var err error
2014-06-20 20:00:00 +01:00
if ka . version >= VersionTLS12 {
2016-07-10 05:02:01 +01:00
sigAlg , err = selectSignatureAlgorithm ( ka . version , cert . PrivateKey , config , clientHello . signatureAlgorithms )
2016-06-21 23:19:24 +01:00
if err != nil {
2014-06-20 20:00:00 +01:00
return nil , err
}
}
2016-06-21 23:19:24 +01:00
sig , err := signMessage ( ka . version , cert . PrivateKey , config , sigAlg , msg )
2014-06-20 20:00:00 +01:00
if err != nil {
return nil , err
}
2016-07-09 00:28:04 +01:00
if config . Bugs . SendSignatureAlgorithm != 0 {
sigAlg = config . Bugs . SendSignatureAlgorithm
}
2014-06-20 20:00:00 +01:00
skx := new ( serverKeyExchangeMsg )
2014-07-12 05:48:23 +01:00
if config . Bugs . UnauthenticatedECDH {
2014-08-02 22:35:45 +01:00
skx . key = params
2014-07-12 05:48:23 +01:00
} else {
2016-06-21 23:19:24 +01:00
sigAlgsLen := 0
2014-07-12 05:48:23 +01:00
if ka . version >= VersionTLS12 {
2016-06-21 23:19:24 +01:00
sigAlgsLen = 2
2014-07-12 05:48:23 +01:00
}
2016-06-21 23:19:24 +01:00
skx . key = make ( [ ] byte , len ( params ) + sigAlgsLen + 2 + len ( sig ) )
2014-08-02 22:35:45 +01:00
copy ( skx . key , params )
k := skx . key [ len ( params ) : ]
2014-07-12 05:48:23 +01:00
if ka . version >= VersionTLS12 {
2016-06-21 23:19:24 +01:00
k [ 0 ] = byte ( sigAlg >> 8 )
k [ 1 ] = byte ( sigAlg )
2014-07-12 05:48:23 +01:00
k = k [ 2 : ]
}
k [ 0 ] = byte ( len ( sig ) >> 8 )
k [ 1 ] = byte ( len ( sig ) )
copy ( k [ 2 : ] , sig )
2014-06-20 20:00:00 +01:00
}
return skx , nil
}
2014-08-02 22:35:45 +01:00
func ( ka * signedKeyAgreement ) verifyParameters ( config * Config , clientHello * clientHelloMsg , serverHello * serverHelloMsg , cert * x509 . Certificate , params [ ] byte , sig [ ] byte ) error {
2016-06-21 23:19:24 +01:00
// The peer's key must match the cipher type.
switch ka . keyType {
case keyTypeECDSA :
_ , ok := cert . PublicKey . ( * ecdsa . PublicKey )
if ! ok {
return errors . New ( "tls: ECDHE ECDSA requires a ECDSA server public key" )
}
case keyTypeRSA :
_ , ok := cert . PublicKey . ( * rsa . PublicKey )
if ! ok {
return errors . New ( "tls: ECDHE RSA requires a RSA server public key" )
}
default :
return errors . New ( "tls: unknown key type" )
2014-06-20 20:00:00 +01:00
}
2016-06-21 23:19:24 +01:00
// The message to be signed is prepended by the randoms.
var msg [ ] byte
msg = append ( msg , clientHello . random ... )
msg = append ( msg , serverHello . random ... )
msg = append ( msg , params ... )
var sigAlg signatureAlgorithm
2014-06-20 20:00:00 +01:00
if ka . version >= VersionTLS12 {
if len ( sig ) < 2 {
return errServerKeyExchange
}
2016-06-21 23:19:24 +01:00
sigAlg = signatureAlgorithm ( sig [ 0 ] ) << 8 | signatureAlgorithm ( sig [ 1 ] )
sig = sig [ 2 : ]
// Stash the signature algorithm to be extracted by the handshake.
ka . peerSignatureAlgorithm = sigAlg
}
if len ( sig ) < 2 {
return errServerKeyExchange
2014-06-20 20:00:00 +01:00
}
sigLen := int ( sig [ 0 ] ) << 8 | int ( sig [ 1 ] )
if sigLen + 2 != len ( sig ) {
return errServerKeyExchange
}
sig = sig [ 2 : ]
2016-07-09 02:52:12 +01:00
return verifyMessage ( ka . version , cert . PublicKey , config , sigAlg , msg , sig )
2014-06-20 20:00:00 +01:00
}
2016-07-18 17:40:30 +01:00
// ecdheKeyAgreement implements a TLS key agreement where the server
2014-08-02 22:35:45 +01:00
// generates a ephemeral EC public/private key pair and signs it. The
// pre-master secret is then calculated using ECDH. The signature may
// either be ECDSA or RSA.
type ecdheKeyAgreement struct {
2015-12-19 03:13:41 +00:00
auth keyAgreementAuthentication
curve ecdhCurve
2016-07-18 17:40:30 +01:00
curveID CurveID
2015-12-19 03:13:41 +00:00
peerKey [ ] byte
2014-08-02 22:35:45 +01:00
}
func ( ka * ecdheKeyAgreement ) generateServerKeyExchange ( config * Config , cert * Certificate , clientHello * clientHelloMsg , hello * serverHelloMsg ) ( * serverKeyExchangeMsg , error ) {
var curveid CurveID
preferredCurves := config . curvePreferences ( )
NextCandidate :
for _ , candidate := range preferredCurves {
for _ , c := range clientHello . supportedCurves {
if candidate == c {
curveid = c
break NextCandidate
}
}
}
if curveid == 0 {
return nil , errors . New ( "tls: no supported elliptic curves offered" )
}
var ok bool
if ka . curve , ok = curveForCurveID ( curveid ) ; ! ok {
return nil , errors . New ( "tls: preferredCurves includes unsupported curve" )
}
2016-07-18 17:40:30 +01:00
ka . curveID = curveid
2014-08-02 22:35:45 +01:00
2016-05-16 22:27:14 +01:00
publicKey , err := ka . curve . offer ( config . rand ( ) )
2014-08-02 22:35:45 +01:00
if err != nil {
return nil , err
}
// http://tools.ietf.org/html/rfc4492#section-5.4
2016-05-25 20:06:05 +01:00
serverECDHParams := make ( [ ] byte , 1 + 2 + 1 + len ( publicKey ) )
serverECDHParams [ 0 ] = 3 // named curve
2016-06-29 23:13:53 +01:00
if config . Bugs . SendCurve != 0 {
curveid = config . Bugs . SendCurve
}
2016-05-25 20:06:05 +01:00
serverECDHParams [ 1 ] = byte ( curveid >> 8 )
serverECDHParams [ 2 ] = byte ( curveid )
serverECDHParams [ 3 ] = byte ( len ( publicKey ) )
copy ( serverECDHParams [ 4 : ] , publicKey )
2016-03-02 05:23:57 +00:00
if config . Bugs . InvalidECDHPoint {
serverECDHParams [ 4 ] ^ = 0xff
}
2014-08-02 22:35:45 +01:00
2014-10-27 06:23:15 +00:00
return ka . auth . signParameters ( config , cert , clientHello , hello , serverECDHParams )
2014-08-02 22:35:45 +01:00
}
func ( ka * ecdheKeyAgreement ) processClientKeyExchange ( config * Config , cert * Certificate , ckx * clientKeyExchangeMsg , version uint16 ) ( [ ] byte , error ) {
2016-05-25 20:06:05 +01:00
if len ( ckx . ciphertext ) == 0 || int ( ckx . ciphertext [ 0 ] ) != len ( ckx . ciphertext ) - 1 {
2014-08-02 22:35:45 +01:00
return nil , errClientKeyExchange
}
2016-05-25 20:06:05 +01:00
return ka . curve . finish ( ckx . ciphertext [ 1 : ] )
2014-08-02 22:35:45 +01:00
}
func ( ka * ecdheKeyAgreement ) processServerKeyExchange ( config * Config , clientHello * clientHelloMsg , serverHello * serverHelloMsg , cert * x509 . Certificate , skx * serverKeyExchangeMsg ) error {
if len ( skx . key ) < 4 {
return errServerKeyExchange
}
if skx . key [ 0 ] != 3 { // named curve
return errors . New ( "tls: server selected unsupported curve" )
}
curveid := CurveID ( skx . key [ 1 ] ) << 8 | CurveID ( skx . key [ 2 ] )
2016-07-18 17:40:30 +01:00
ka . curveID = curveid
2014-08-02 22:35:45 +01:00
var ok bool
if ka . curve , ok = curveForCurveID ( curveid ) ; ! ok {
return errors . New ( "tls: server selected unsupported curve" )
}
publicLen := int ( skx . key [ 3 ] )
2016-05-25 20:06:05 +01:00
if publicLen + 4 > len ( skx . key ) {
2014-08-02 22:35:45 +01:00
return errServerKeyExchange
}
2015-12-19 03:13:41 +00:00
// Save the peer key for later.
2016-05-25 20:06:05 +01:00
ka . peerKey = skx . key [ 4 : 4 + publicLen ]
2015-12-19 03:13:41 +00:00
// Check the signature.
2016-05-25 20:06:05 +01:00
serverECDHParams := skx . key [ : 4 + publicLen ]
sig := skx . key [ 4 + publicLen : ]
2014-10-27 06:23:15 +00:00
return ka . auth . verifyParameters ( config , clientHello , serverHello , cert , serverECDHParams , sig )
2014-08-02 22:35:45 +01:00
}
2014-06-20 20:00:00 +01:00
func ( ka * ecdheKeyAgreement ) generateClientKeyExchange ( config * Config , clientHello * clientHelloMsg , cert * x509 . Certificate ) ( [ ] byte , * clientKeyExchangeMsg , error ) {
if ka . curve == nil {
return nil , nil , errors . New ( "missing ServerKeyExchange message" )
}
2015-12-19 03:13:41 +00:00
2016-05-16 22:27:14 +01:00
publicKey , preMasterSecret , err := ka . curve . accept ( config . rand ( ) , ka . peerKey )
2014-06-20 20:00:00 +01:00
if err != nil {
return nil , nil , err
}
ckx := new ( clientKeyExchangeMsg )
2016-05-25 20:06:05 +01:00
ckx . ciphertext = make ( [ ] byte , 1 + len ( publicKey ) )
ckx . ciphertext [ 0 ] = byte ( len ( publicKey ) )
copy ( ckx . ciphertext [ 1 : ] , publicKey )
2016-03-02 05:23:57 +00:00
if config . Bugs . InvalidECDHPoint {
2016-05-25 20:06:05 +01:00
ckx . ciphertext [ 1 ] ^ = 0xff
2016-03-02 05:23:57 +00:00
}
2016-05-25 20:06:05 +01:00
return preMasterSecret , ckx , nil
}
2016-06-21 23:19:24 +01:00
func ( ka * ecdheKeyAgreement ) peerSignatureAlgorithm ( ) signatureAlgorithm {
if auth , ok := ka . auth . ( * signedKeyAgreement ) ; ok {
return auth . peerSignatureAlgorithm
}
return 0
}
2016-05-25 20:06:05 +01:00
// cecpq1RSAKeyAgreement is like an ecdheKeyAgreement, but using the cecpq1Curve
// pseudo-curve, and without any parameters (e.g. curve name) other than the
// keys being exchanged. The signature may either be ECDSA or RSA.
type cecpq1KeyAgreement struct {
auth keyAgreementAuthentication
curve ecdhCurve
peerKey [ ] byte
}
func ( ka * cecpq1KeyAgreement ) generateServerKeyExchange ( config * Config , cert * Certificate , clientHello * clientHelloMsg , hello * serverHelloMsg ) ( * serverKeyExchangeMsg , error ) {
ka . curve = & cecpq1Curve { }
publicKey , err := ka . curve . offer ( config . rand ( ) )
if err != nil {
return nil , err
}
2016-06-13 21:03:47 +01:00
if config . Bugs . CECPQ1BadX25519Part {
publicKey [ 0 ] ^ = 1
}
if config . Bugs . CECPQ1BadNewhopePart {
publicKey [ 32 ] ^ = 1
publicKey [ 33 ] ^ = 1
publicKey [ 34 ] ^ = 1
publicKey [ 35 ] ^ = 1
}
2016-05-25 20:06:05 +01:00
var params [ ] byte
params = append ( params , byte ( len ( publicKey ) >> 8 ) )
params = append ( params , byte ( len ( publicKey ) & 0xff ) )
params = append ( params , publicKey [ : ] ... )
return ka . auth . signParameters ( config , cert , clientHello , hello , params )
}
func ( ka * cecpq1KeyAgreement ) processClientKeyExchange ( config * Config , cert * Certificate , ckx * clientKeyExchangeMsg , version uint16 ) ( [ ] byte , error ) {
if len ( ckx . ciphertext ) < 2 {
return nil , errClientKeyExchange
}
peerKeyLen := int ( ckx . ciphertext [ 0 ] ) << 8 + int ( ckx . ciphertext [ 1 ] )
peerKey := ckx . ciphertext [ 2 : ]
if peerKeyLen != len ( peerKey ) {
return nil , errClientKeyExchange
}
return ka . curve . finish ( peerKey )
}
func ( ka * cecpq1KeyAgreement ) processServerKeyExchange ( config * Config , clientHello * clientHelloMsg , serverHello * serverHelloMsg , cert * x509 . Certificate , skx * serverKeyExchangeMsg ) error {
if len ( skx . key ) < 2 {
return errServerKeyExchange
}
peerKeyLen := int ( skx . key [ 0 ] ) << 8 + int ( skx . key [ 1 ] )
// Save the peer key for later.
if len ( skx . key ) < 2 + peerKeyLen {
return errServerKeyExchange
}
ka . peerKey = skx . key [ 2 : 2 + peerKeyLen ]
if peerKeyLen != len ( ka . peerKey ) {
return errServerKeyExchange
}
// Check the signature.
params := skx . key [ : 2 + peerKeyLen ]
sig := skx . key [ 2 + peerKeyLen : ]
return ka . auth . verifyParameters ( config , clientHello , serverHello , cert , params , sig )
}
func ( ka * cecpq1KeyAgreement ) generateClientKeyExchange ( config * Config , clientHello * clientHelloMsg , cert * x509 . Certificate ) ( [ ] byte , * clientKeyExchangeMsg , error ) {
curve := & cecpq1Curve { }
publicKey , preMasterSecret , err := curve . accept ( config . rand ( ) , ka . peerKey )
if err != nil {
return nil , nil , err
}
2016-06-13 21:03:47 +01:00
if config . Bugs . CECPQ1BadX25519Part {
publicKey [ 0 ] ^ = 1
}
if config . Bugs . CECPQ1BadNewhopePart {
publicKey [ 32 ] ^ = 1
publicKey [ 33 ] ^ = 1
publicKey [ 34 ] ^ = 1
publicKey [ 35 ] ^ = 1
}
2016-05-25 20:06:05 +01:00
ckx := new ( clientKeyExchangeMsg )
ckx . ciphertext = append ( ckx . ciphertext , byte ( len ( publicKey ) >> 8 ) )
ckx . ciphertext = append ( ckx . ciphertext , byte ( len ( publicKey ) & 0xff ) )
2016-05-17 00:31:05 +01:00
ckx . ciphertext = append ( ckx . ciphertext , publicKey [ : ] ... )
2014-06-20 20:00:00 +01:00
return preMasterSecret , ckx , nil
}
2014-08-02 22:35:45 +01:00
2016-06-21 23:19:24 +01:00
func ( ka * cecpq1KeyAgreement ) peerSignatureAlgorithm ( ) signatureAlgorithm {
if auth , ok := ka . auth . ( * signedKeyAgreement ) ; ok {
return auth . peerSignatureAlgorithm
}
return 0
}
2014-08-02 22:35:45 +01:00
// dheRSAKeyAgreement implements a TLS key agreement where the server generates
// an ephemeral Diffie-Hellman public/private key pair and signs it. The
// pre-master secret is then calculated using Diffie-Hellman.
type dheKeyAgreement struct {
2014-10-27 06:23:15 +00:00
auth keyAgreementAuthentication
2014-08-02 22:35:45 +01:00
p , g * big . Int
yTheirs * big . Int
xOurs * big . Int
}
func ( ka * dheKeyAgreement ) generateServerKeyExchange ( config * Config , cert * Certificate , clientHello * clientHelloMsg , hello * serverHelloMsg ) ( * serverKeyExchangeMsg , error ) {
2015-05-15 01:38:50 +01:00
var q * big . Int
if p := config . Bugs . DHGroupPrime ; p != nil {
ka . p = p
ka . g = big . NewInt ( 2 )
q = p
} else {
// 2048-bit MODP Group with 256-bit Prime Order Subgroup (RFC
// 5114, Section 2.3)
ka . p , _ = new ( big . Int ) . SetString ( "87A8E61DB4B6663CFFBBD19C651959998CEEF608660DD0F25D2CEED4435E3B00E00DF8F1D61957D4FAF7DF4561B2AA3016C3D91134096FAA3BF4296D830E9A7C209E0C6497517ABD5A8A9D306BCF67ED91F9E6725B4758C022E0B1EF4275BF7B6C5BFC11D45F9088B941F54EB1E59BB8BC39A0BF12307F5C4FDB70C581B23F76B63ACAE1CAA6B7902D52526735488A0EF13C6D9A51BFA4AB3AD8347796524D8EF6A167B5A41825D967E144E5140564251CCACB83E6B486F6B3CA3F7971506026C0B857F689962856DED4010ABD0BE621C3A3960A54E710C375F26375D7014103A4B54330C198AF126116D2276E11715F693877FAD7EF09CADB094AE91E1A1597" , 16 )
ka . g , _ = new ( big . Int ) . SetString ( "3FB32C9B73134D0B2E77506660EDBD484CA7B18F21EF205407F4793A1A0BA12510DBC15077BE463FFF4FED4AAC0BB555BE3A6C1B0C6B47B1BC3773BF7E8C6F62901228F8C28CBB18A55AE31341000A650196F931C77A57F2DDF463E5E9EC144B777DE62AAAB8A8628AC376D282D6ED3864E67982428EBC831D14348F6F2F9193B5045AF2767164E1DFC967C1FB3F2E55A4BD1BFFE83B9C80D052B985D182EA0ADB2A3B7313D3FE14C8484B1E052588B9B7D2BBD2DF016199ECD06E1557CD0915B3353BBB64E0EC377FD028370DF92B52C7891428CDC67EB6184B523D1DB246C32F63078490F00EF8D647D148D47954515E2327CFEF98C582664B4C0F6CC41659" , 16 )
q , _ = new ( big . Int ) . SetString ( "8CF83642A709A097B447997640129DA299B1A47D1EB3750BA308B0FE64F5FBD3" , 16 )
}
2014-08-02 22:35:45 +01:00
var err error
ka . xOurs , err = rand . Int ( config . rand ( ) , q )
if err != nil {
return nil , err
}
yOurs := new ( big . Int ) . Exp ( ka . g , ka . xOurs , ka . p )
// http://tools.ietf.org/html/rfc5246#section-7.4.3
pBytes := ka . p . Bytes ( )
gBytes := ka . g . Bytes ( )
yBytes := yOurs . Bytes ( )
serverDHParams := make ( [ ] byte , 0 , 2 + len ( pBytes ) + 2 + len ( gBytes ) + 2 + len ( yBytes ) )
serverDHParams = append ( serverDHParams , byte ( len ( pBytes ) >> 8 ) , byte ( len ( pBytes ) ) )
serverDHParams = append ( serverDHParams , pBytes ... )
serverDHParams = append ( serverDHParams , byte ( len ( gBytes ) >> 8 ) , byte ( len ( gBytes ) ) )
serverDHParams = append ( serverDHParams , gBytes ... )
serverDHParams = append ( serverDHParams , byte ( len ( yBytes ) >> 8 ) , byte ( len ( yBytes ) ) )
serverDHParams = append ( serverDHParams , yBytes ... )
2014-10-27 06:23:15 +00:00
return ka . auth . signParameters ( config , cert , clientHello , hello , serverDHParams )
2014-08-02 22:35:45 +01:00
}
func ( ka * dheKeyAgreement ) processClientKeyExchange ( config * Config , cert * Certificate , ckx * clientKeyExchangeMsg , version uint16 ) ( [ ] byte , error ) {
if len ( ckx . ciphertext ) < 2 {
return nil , errClientKeyExchange
}
yLen := ( int ( ckx . ciphertext [ 0 ] ) << 8 ) | int ( ckx . ciphertext [ 1 ] )
if yLen != len ( ckx . ciphertext ) - 2 {
return nil , errClientKeyExchange
}
yTheirs := new ( big . Int ) . SetBytes ( ckx . ciphertext [ 2 : ] )
if yTheirs . Sign ( ) <= 0 || yTheirs . Cmp ( ka . p ) >= 0 {
return nil , errClientKeyExchange
}
return new ( big . Int ) . Exp ( yTheirs , ka . xOurs , ka . p ) . Bytes ( ) , nil
}
func ( ka * dheKeyAgreement ) processServerKeyExchange ( config * Config , clientHello * clientHelloMsg , serverHello * serverHelloMsg , cert * x509 . Certificate , skx * serverKeyExchangeMsg ) error {
// Read dh_p
k := skx . key
if len ( k ) < 2 {
return errServerKeyExchange
}
pLen := ( int ( k [ 0 ] ) << 8 ) | int ( k [ 1 ] )
k = k [ 2 : ]
if len ( k ) < pLen {
return errServerKeyExchange
}
ka . p = new ( big . Int ) . SetBytes ( k [ : pLen ] )
k = k [ pLen : ]
// Read dh_g
if len ( k ) < 2 {
return errServerKeyExchange
}
gLen := ( int ( k [ 0 ] ) << 8 ) | int ( k [ 1 ] )
k = k [ 2 : ]
if len ( k ) < gLen {
return errServerKeyExchange
}
ka . g = new ( big . Int ) . SetBytes ( k [ : gLen ] )
k = k [ gLen : ]
// Read dh_Ys
if len ( k ) < 2 {
return errServerKeyExchange
}
yLen := ( int ( k [ 0 ] ) << 8 ) | int ( k [ 1 ] )
k = k [ 2 : ]
if len ( k ) < yLen {
return errServerKeyExchange
}
ka . yTheirs = new ( big . Int ) . SetBytes ( k [ : yLen ] )
k = k [ yLen : ]
if ka . yTheirs . Sign ( ) <= 0 || ka . yTheirs . Cmp ( ka . p ) >= 0 {
return errServerKeyExchange
}
2015-11-27 00:39:08 +00:00
if l := config . Bugs . RequireDHPublicValueLen ; l != 0 && l != yLen {
return fmt . Errorf ( "RequireDHPublicValueLen set to %d, but server's public value was %d bytes on the wire and %d bytes if minimal" , l , yLen , ( ka . yTheirs . BitLen ( ) + 7 ) / 8 )
}
2014-08-02 22:35:45 +01:00
sig := k
serverDHParams := skx . key [ : len ( skx . key ) - len ( sig ) ]
2014-10-27 06:23:15 +00:00
return ka . auth . verifyParameters ( config , clientHello , serverHello , cert , serverDHParams , sig )
2014-08-02 22:35:45 +01:00
}
func ( ka * dheKeyAgreement ) generateClientKeyExchange ( config * Config , clientHello * clientHelloMsg , cert * x509 . Certificate ) ( [ ] byte , * clientKeyExchangeMsg , error ) {
if ka . p == nil || ka . g == nil || ka . yTheirs == nil {
return nil , nil , errors . New ( "missing ServerKeyExchange message" )
}
xOurs , err := rand . Int ( config . rand ( ) , ka . p )
if err != nil {
return nil , nil , err
}
preMasterSecret := new ( big . Int ) . Exp ( ka . yTheirs , xOurs , ka . p ) . Bytes ( )
yOurs := new ( big . Int ) . Exp ( ka . g , xOurs , ka . p )
yBytes := yOurs . Bytes ( )
ckx := new ( clientKeyExchangeMsg )
ckx . ciphertext = make ( [ ] byte , 2 + len ( yBytes ) )
ckx . ciphertext [ 0 ] = byte ( len ( yBytes ) >> 8 )
ckx . ciphertext [ 1 ] = byte ( len ( yBytes ) )
copy ( ckx . ciphertext [ 2 : ] , yBytes )
return preMasterSecret , ckx , nil
}
2014-10-27 05:06:24 +00:00
2016-06-21 23:19:24 +01:00
func ( ka * dheKeyAgreement ) peerSignatureAlgorithm ( ) signatureAlgorithm {
if auth , ok := ka . auth . ( * signedKeyAgreement ) ; ok {
return auth . peerSignatureAlgorithm
}
return 0
}
2014-10-27 06:23:15 +00:00
// nilKeyAgreement is a fake key agreement used to implement the plain PSK key
// exchange.
type nilKeyAgreement struct { }
func ( ka * nilKeyAgreement ) generateServerKeyExchange ( config * Config , cert * Certificate , clientHello * clientHelloMsg , hello * serverHelloMsg ) ( * serverKeyExchangeMsg , error ) {
return nil , nil
}
func ( ka * nilKeyAgreement ) processClientKeyExchange ( config * Config , cert * Certificate , ckx * clientKeyExchangeMsg , version uint16 ) ( [ ] byte , error ) {
if len ( ckx . ciphertext ) != 0 {
return nil , errClientKeyExchange
}
// Although in plain PSK, otherSecret is all zeros, the base key
// agreement does not access to the length of the pre-shared
// key. pskKeyAgreement instead interprets nil to mean to use all zeros
// of the appropriate length.
return nil , nil
}
func ( ka * nilKeyAgreement ) processServerKeyExchange ( config * Config , clientHello * clientHelloMsg , serverHello * serverHelloMsg , cert * x509 . Certificate , skx * serverKeyExchangeMsg ) error {
if len ( skx . key ) != 0 {
return errServerKeyExchange
}
return nil
}
func ( ka * nilKeyAgreement ) generateClientKeyExchange ( config * Config , clientHello * clientHelloMsg , cert * x509 . Certificate ) ( [ ] byte , * clientKeyExchangeMsg , error ) {
// Although in plain PSK, otherSecret is all zeros, the base key
// agreement does not access to the length of the pre-shared
// key. pskKeyAgreement instead interprets nil to mean to use all zeros
// of the appropriate length.
return nil , & clientKeyExchangeMsg { } , nil
}
2016-06-21 23:19:24 +01:00
func ( ka * nilKeyAgreement ) peerSignatureAlgorithm ( ) signatureAlgorithm {
return 0
}
2014-10-27 06:23:15 +00:00
// makePSKPremaster formats a PSK pre-master secret based on otherSecret from
// the base key exchange and psk.
2014-10-27 05:06:24 +00:00
func makePSKPremaster ( otherSecret , psk [ ] byte ) [ ] byte {
out := make ( [ ] byte , 0 , 2 + len ( otherSecret ) + 2 + len ( psk ) )
out = append ( out , byte ( len ( otherSecret ) >> 8 ) , byte ( len ( otherSecret ) ) )
out = append ( out , otherSecret ... )
out = append ( out , byte ( len ( psk ) >> 8 ) , byte ( len ( psk ) ) )
out = append ( out , psk ... )
return out
}
// pskKeyAgreement implements the PSK key agreement.
type pskKeyAgreement struct {
2014-10-27 06:23:15 +00:00
base keyAgreement
2014-10-27 05:06:24 +00:00
identityHint string
}
func ( ka * pskKeyAgreement ) generateServerKeyExchange ( config * Config , cert * Certificate , clientHello * clientHelloMsg , hello * serverHelloMsg ) ( * serverKeyExchangeMsg , error ) {
2014-10-27 06:23:15 +00:00
// Assemble the identity hint.
2014-10-27 05:06:24 +00:00
bytes := make ( [ ] byte , 2 + len ( config . PreSharedKeyIdentity ) )
bytes [ 0 ] = byte ( len ( config . PreSharedKeyIdentity ) >> 8 )
bytes [ 1 ] = byte ( len ( config . PreSharedKeyIdentity ) )
copy ( bytes [ 2 : ] , [ ] byte ( config . PreSharedKeyIdentity ) )
2014-10-27 06:23:15 +00:00
// If there is one, append the base key agreement's
// ServerKeyExchange.
baseSkx , err := ka . base . generateServerKeyExchange ( config , cert , clientHello , hello )
if err != nil {
return nil , err
}
if baseSkx != nil {
bytes = append ( bytes , baseSkx . key ... )
2016-09-17 00:42:05 +01:00
} else if config . PreSharedKeyIdentity == "" && ! config . Bugs . AlwaysSendPreSharedKeyIdentityHint {
2014-10-27 06:23:15 +00:00
// ServerKeyExchange is optional if the identity hint is empty
// and there would otherwise be no ServerKeyExchange.
return nil , nil
}
2014-10-27 05:06:24 +00:00
skx := new ( serverKeyExchangeMsg )
skx . key = bytes
return skx , nil
}
func ( ka * pskKeyAgreement ) processClientKeyExchange ( config * Config , cert * Certificate , ckx * clientKeyExchangeMsg , version uint16 ) ( [ ] byte , error ) {
2014-10-27 06:23:15 +00:00
// First, process the PSK identity.
2014-10-27 05:06:24 +00:00
if len ( ckx . ciphertext ) < 2 {
return nil , errClientKeyExchange
}
identityLen := ( int ( ckx . ciphertext [ 0 ] ) << 8 ) | int ( ckx . ciphertext [ 1 ] )
2014-10-27 06:23:15 +00:00
if 2 + identityLen > len ( ckx . ciphertext ) {
2014-10-27 05:06:24 +00:00
return nil , errClientKeyExchange
}
2014-10-27 06:23:15 +00:00
identity := string ( ckx . ciphertext [ 2 : 2 + identityLen ] )
2014-10-27 05:06:24 +00:00
if identity != config . PreSharedKeyIdentity {
return nil , errors . New ( "tls: unexpected identity" )
}
if config . PreSharedKey == nil {
return nil , errors . New ( "tls: pre-shared key not configured" )
}
2014-10-27 06:23:15 +00:00
// Process the remainder of the ClientKeyExchange to compute the base
// pre-master secret.
newCkx := new ( clientKeyExchangeMsg )
newCkx . ciphertext = ckx . ciphertext [ 2 + identityLen : ]
otherSecret , err := ka . base . processClientKeyExchange ( config , cert , newCkx , version )
if err != nil {
return nil , err
}
if otherSecret == nil {
// Special-case for the plain PSK key exchanges.
otherSecret = make ( [ ] byte , len ( config . PreSharedKey ) )
}
2014-10-27 05:06:24 +00:00
return makePSKPremaster ( otherSecret , config . PreSharedKey ) , nil
}
func ( ka * pskKeyAgreement ) processServerKeyExchange ( config * Config , clientHello * clientHelloMsg , serverHello * serverHelloMsg , cert * x509 . Certificate , skx * serverKeyExchangeMsg ) error {
if len ( skx . key ) < 2 {
return errServerKeyExchange
}
identityLen := ( int ( skx . key [ 0 ] ) << 8 ) | int ( skx . key [ 1 ] )
2014-10-27 06:23:15 +00:00
if 2 + identityLen > len ( skx . key ) {
2014-10-27 05:06:24 +00:00
return errServerKeyExchange
}
2014-10-27 06:23:15 +00:00
ka . identityHint = string ( skx . key [ 2 : 2 + identityLen ] )
// Process the remainder of the ServerKeyExchange.
newSkx := new ( serverKeyExchangeMsg )
newSkx . key = skx . key [ 2 + identityLen : ]
return ka . base . processServerKeyExchange ( config , clientHello , serverHello , cert , newSkx )
2014-10-27 05:06:24 +00:00
}
func ( ka * pskKeyAgreement ) generateClientKeyExchange ( config * Config , clientHello * clientHelloMsg , cert * x509 . Certificate ) ( [ ] byte , * clientKeyExchangeMsg , error ) {
// The server only sends an identity hint but, for purposes of
// test code, the server always sends the hint and it is
// required to match.
if ka . identityHint != config . PreSharedKeyIdentity {
return nil , nil , errors . New ( "tls: unexpected identity" )
}
2014-10-27 06:23:15 +00:00
// Serialize the identity.
2014-10-27 05:06:24 +00:00
bytes := make ( [ ] byte , 2 + len ( config . PreSharedKeyIdentity ) )
bytes [ 0 ] = byte ( len ( config . PreSharedKeyIdentity ) >> 8 )
bytes [ 1 ] = byte ( len ( config . PreSharedKeyIdentity ) )
copy ( bytes [ 2 : ] , [ ] byte ( config . PreSharedKeyIdentity ) )
2014-10-27 06:23:15 +00:00
// Append the base key exchange's ClientKeyExchange.
otherSecret , baseCkx , err := ka . base . generateClientKeyExchange ( config , clientHello , cert )
if err != nil {
return nil , nil , err
}
2014-10-27 05:06:24 +00:00
ckx := new ( clientKeyExchangeMsg )
2014-10-27 06:23:15 +00:00
ckx . ciphertext = append ( bytes , baseCkx . ciphertext ... )
2014-10-27 05:06:24 +00:00
if config . PreSharedKey == nil {
return nil , nil , errors . New ( "tls: pre-shared key not configured" )
}
2014-10-27 06:23:15 +00:00
if otherSecret == nil {
otherSecret = make ( [ ] byte , len ( config . PreSharedKey ) )
}
2014-10-27 05:06:24 +00:00
return makePSKPremaster ( otherSecret , config . PreSharedKey ) , ckx , nil
}
2016-06-21 23:19:24 +01:00
func ( ka * pskKeyAgreement ) peerSignatureAlgorithm ( ) signatureAlgorithm {
return 0
}