runner: Implement DHE-RSA.
Use it to test DHE-RSA in BoringSSL. Change-Id: I88f7bfa76507a6f60234d61d494c9f94b7df4e0a Reviewed-on: https://boringssl-review.googlesource.com/1377 Reviewed-by: Adam Langley <agl@google.com>
This commit is contained in:
committed by
Adam Langley
parent
884fdf1616
commit
f4e5c4e106
@@ -112,6 +112,7 @@ static SSL_CTX *setup_ctx(int is_server) {
|
||||
}
|
||||
|
||||
SSL_CTX *ssl_ctx = NULL;
|
||||
DH *dh = NULL;
|
||||
|
||||
ssl_ctx = SSL_CTX_new(
|
||||
is_server ? SSLv23_server_method() : SSLv23_client_method());
|
||||
@@ -127,6 +128,11 @@ static SSL_CTX *setup_ctx(int is_server) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
dh = DH_get_2048_256(NULL);
|
||||
if (!SSL_CTX_set_tmp_dh(ssl_ctx, dh)) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
SSL_CTX_set_session_cache_mode(ssl_ctx, SSL_SESS_CACHE_BOTH);
|
||||
|
||||
ssl_ctx->select_certificate_cb = select_certificate_callback;
|
||||
@@ -136,9 +142,13 @@ static SSL_CTX *setup_ctx(int is_server) {
|
||||
SSL_CTX_set_next_proto_select_cb(
|
||||
ssl_ctx, next_proto_select_callback, NULL);
|
||||
|
||||
DH_free(dh);
|
||||
return ssl_ctx;
|
||||
|
||||
err:
|
||||
if (dh != NULL) {
|
||||
DH_free(dh);
|
||||
}
|
||||
if (ssl_ctx != NULL) {
|
||||
SSL_CTX_free(ssl_ctx);
|
||||
}
|
||||
|
||||
@@ -82,11 +82,18 @@ var cipherSuites = []*cipherSuite{
|
||||
{TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, 16, 20, 16, ecdheECDSAKA, suiteECDHE | suiteECDSA, cipherAES, macSHA1, nil},
|
||||
{TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, 32, 20, 16, ecdheRSAKA, suiteECDHE, cipherAES, macSHA1, nil},
|
||||
{TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, 32, 20, 16, ecdheECDSAKA, suiteECDHE | suiteECDSA, cipherAES, macSHA1, nil},
|
||||
{TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, 16, 0, 4, dheRSAKA, suiteTLS12, nil, nil, aeadAESGCM},
|
||||
{TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, 32, 0, 4, dheRSAKA, suiteTLS12 | suiteSHA384, nil, nil, aeadAESGCM},
|
||||
{TLS_DHE_RSA_WITH_AES_128_CBC_SHA, 16, 20, 16, dheRSAKA, 0, cipherAES, macSHA1, nil},
|
||||
{TLS_DHE_RSA_WITH_AES_256_CBC_SHA, 32, 20, 16, dheRSAKA, 0, cipherAES, macSHA1, nil},
|
||||
{TLS_RSA_WITH_AES_128_GCM_SHA256, 16, 0, 4, rsaKA, suiteTLS12, nil, nil, aeadAESGCM},
|
||||
{TLS_RSA_WITH_AES_256_GCM_SHA384, 32, 0, 4, rsaKA, suiteTLS12 | suiteSHA384, nil, nil, aeadAESGCM},
|
||||
{TLS_RSA_WITH_RC4_128_SHA, 16, 20, 0, rsaKA, 0, cipherRC4, macSHA1, nil},
|
||||
{TLS_RSA_WITH_RC4_128_MD5, 16, 16, 0, rsaKA, 0, cipherRC4, macMD5, nil},
|
||||
{TLS_RSA_WITH_AES_128_CBC_SHA, 16, 20, 16, rsaKA, 0, cipherAES, macSHA1, nil},
|
||||
{TLS_RSA_WITH_AES_256_CBC_SHA, 32, 20, 16, rsaKA, 0, cipherAES, macSHA1, nil},
|
||||
{TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, 8, ecdheRSAKA, suiteECDHE, cipher3DES, macSHA1, nil},
|
||||
{TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, 8, dheRSAKA, 0, cipher3DES, macSHA1, nil},
|
||||
{TLS_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, 8, rsaKA, 0, cipher3DES, macSHA1, nil},
|
||||
}
|
||||
|
||||
@@ -241,15 +248,28 @@ func rsaKA(version uint16) keyAgreement {
|
||||
|
||||
func ecdheECDSAKA(version uint16) keyAgreement {
|
||||
return &ecdheKeyAgreement{
|
||||
sigType: signatureECDSA,
|
||||
version: version,
|
||||
signedKeyAgreement: signedKeyAgreement{
|
||||
sigType: signatureECDSA,
|
||||
version: version,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func ecdheRSAKA(version uint16) keyAgreement {
|
||||
return &ecdheKeyAgreement{
|
||||
sigType: signatureRSA,
|
||||
version: version,
|
||||
signedKeyAgreement: signedKeyAgreement{
|
||||
sigType: signatureRSA,
|
||||
version: version,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func dheRSAKA(version uint16) keyAgreement {
|
||||
return &dheKeyAgreement{
|
||||
signedKeyAgreement: signedKeyAgreement{
|
||||
sigType: signatureRSA,
|
||||
version: version,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -275,8 +295,15 @@ const (
|
||||
TLS_RSA_WITH_RC4_128_MD5 uint16 = 0x0004
|
||||
TLS_RSA_WITH_RC4_128_SHA uint16 = 0x0005
|
||||
TLS_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0x000a
|
||||
TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0x0016
|
||||
TLS_RSA_WITH_AES_128_CBC_SHA uint16 = 0x002f
|
||||
TLS_DHE_RSA_WITH_AES_128_CBC_SHA uint16 = 0x0033
|
||||
TLS_RSA_WITH_AES_256_CBC_SHA uint16 = 0x0035
|
||||
TLS_DHE_RSA_WITH_AES_256_CBC_SHA uint16 = 0x0039
|
||||
TLS_RSA_WITH_AES_128_GCM_SHA256 uint16 = 0x009c
|
||||
TLS_RSA_WITH_AES_256_GCM_SHA384 uint16 = 0x009d
|
||||
TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 uint16 = 0x009e
|
||||
TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 uint16 = 0x009f
|
||||
TLS_ECDHE_ECDSA_WITH_RC4_128_SHA uint16 = 0xc007
|
||||
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA uint16 = 0xc009
|
||||
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA uint16 = 0xc00a
|
||||
|
||||
+263
-124
@@ -9,6 +9,7 @@ import (
|
||||
"crypto/ecdsa"
|
||||
"crypto/elliptic"
|
||||
"crypto/md5"
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"crypto/sha1"
|
||||
"crypto/sha256"
|
||||
@@ -177,13 +178,148 @@ func curveForCurveID(id CurveID) (elliptic.Curve, bool) {
|
||||
|
||||
}
|
||||
|
||||
// signedKeyAgreement implements helper functions for key agreement
|
||||
// methods that involve signed parameters in the ServerKeyExchange.
|
||||
type signedKeyAgreement struct {
|
||||
version uint16
|
||||
sigType uint8
|
||||
}
|
||||
|
||||
func (ka *signedKeyAgreement) signParameters(config *Config, cert *Certificate, clientHello *clientHelloMsg, hello *serverHelloMsg, params []byte) (*serverKeyExchangeMsg, error) {
|
||||
var tls12HashId uint8
|
||||
var err error
|
||||
if ka.version >= VersionTLS12 {
|
||||
if tls12HashId, err = pickTLS12HashForSignature(ka.sigType, clientHello.signatureAndHashes); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
digest, hashFunc, err := hashForServerKeyExchange(ka.sigType, tls12HashId, ka.version, clientHello.random, hello.random, params)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if config.Bugs.InvalidSKXSignature {
|
||||
digest[0] ^= 0x80
|
||||
}
|
||||
|
||||
var sig []byte
|
||||
switch ka.sigType {
|
||||
case signatureECDSA:
|
||||
privKey, ok := cert.PrivateKey.(*ecdsa.PrivateKey)
|
||||
if !ok {
|
||||
return nil, errors.New("ECDHE ECDSA requires an ECDSA server private key")
|
||||
}
|
||||
r, s, err := ecdsa.Sign(config.rand(), privKey, digest)
|
||||
if err != nil {
|
||||
return nil, errors.New("failed to sign ECDHE parameters: " + err.Error())
|
||||
}
|
||||
order := privKey.Curve.Params().N
|
||||
r = maybeCorruptECDSAValue(r, config.Bugs.BadECDSAR, order)
|
||||
s = maybeCorruptECDSAValue(s, config.Bugs.BadECDSAS, order)
|
||||
sig, err = asn1.Marshal(ecdsaSignature{r, s})
|
||||
case signatureRSA:
|
||||
privKey, ok := cert.PrivateKey.(*rsa.PrivateKey)
|
||||
if !ok {
|
||||
return nil, errors.New("ECDHE RSA requires a RSA server private key")
|
||||
}
|
||||
sig, err = rsa.SignPKCS1v15(config.rand(), privKey, hashFunc, digest)
|
||||
if err != nil {
|
||||
return nil, errors.New("failed to sign ECDHE parameters: " + err.Error())
|
||||
}
|
||||
default:
|
||||
return nil, errors.New("unknown ECDHE signature algorithm")
|
||||
}
|
||||
|
||||
skx := new(serverKeyExchangeMsg)
|
||||
if config.Bugs.UnauthenticatedECDH {
|
||||
skx.key = params
|
||||
} else {
|
||||
sigAndHashLen := 0
|
||||
if ka.version >= VersionTLS12 {
|
||||
sigAndHashLen = 2
|
||||
}
|
||||
skx.key = make([]byte, len(params)+sigAndHashLen+2+len(sig))
|
||||
copy(skx.key, params)
|
||||
k := skx.key[len(params):]
|
||||
if ka.version >= VersionTLS12 {
|
||||
k[0] = tls12HashId
|
||||
k[1] = ka.sigType
|
||||
k = k[2:]
|
||||
}
|
||||
k[0] = byte(len(sig) >> 8)
|
||||
k[1] = byte(len(sig))
|
||||
copy(k[2:], sig)
|
||||
}
|
||||
|
||||
return skx, nil
|
||||
}
|
||||
|
||||
func (ka *signedKeyAgreement) verifyParameters(config *Config, clientHello *clientHelloMsg, serverHello *serverHelloMsg, cert *x509.Certificate, params []byte, sig []byte) error {
|
||||
if len(sig) < 2 {
|
||||
return errServerKeyExchange
|
||||
}
|
||||
|
||||
var tls12HashId uint8
|
||||
if ka.version >= VersionTLS12 {
|
||||
// handle SignatureAndHashAlgorithm
|
||||
var sigAndHash []uint8
|
||||
sigAndHash, sig = sig[:2], sig[2:]
|
||||
if sigAndHash[1] != ka.sigType {
|
||||
return errServerKeyExchange
|
||||
}
|
||||
tls12HashId = sigAndHash[0]
|
||||
if len(sig) < 2 {
|
||||
return errServerKeyExchange
|
||||
}
|
||||
}
|
||||
sigLen := int(sig[0])<<8 | int(sig[1])
|
||||
if sigLen+2 != len(sig) {
|
||||
return errServerKeyExchange
|
||||
}
|
||||
sig = sig[2:]
|
||||
|
||||
digest, hashFunc, err := hashForServerKeyExchange(ka.sigType, tls12HashId, ka.version, clientHello.random, serverHello.random, params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
switch ka.sigType {
|
||||
case signatureECDSA:
|
||||
pubKey, ok := cert.PublicKey.(*ecdsa.PublicKey)
|
||||
if !ok {
|
||||
return errors.New("ECDHE ECDSA requires a ECDSA server public key")
|
||||
}
|
||||
ecdsaSig := new(ecdsaSignature)
|
||||
if _, err := asn1.Unmarshal(sig, ecdsaSig); err != nil {
|
||||
return err
|
||||
}
|
||||
if ecdsaSig.R.Sign() <= 0 || ecdsaSig.S.Sign() <= 0 {
|
||||
return errors.New("ECDSA signature contained zero or negative values")
|
||||
}
|
||||
if !ecdsa.Verify(pubKey, digest, ecdsaSig.R, ecdsaSig.S) {
|
||||
return errors.New("ECDSA verification failure")
|
||||
}
|
||||
case signatureRSA:
|
||||
pubKey, ok := cert.PublicKey.(*rsa.PublicKey)
|
||||
if !ok {
|
||||
return errors.New("ECDHE RSA requires a RSA server public key")
|
||||
}
|
||||
if err := rsa.VerifyPKCS1v15(pubKey, hashFunc, digest, sig); err != nil {
|
||||
return err
|
||||
}
|
||||
default:
|
||||
return errors.New("unknown ECDHE signature algorithm")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ecdheRSAKeyAgreement implements a TLS key agreement where the server
|
||||
// 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 {
|
||||
version uint16
|
||||
sigType uint8
|
||||
signedKeyAgreement
|
||||
privateKey []byte
|
||||
curve elliptic.Curve
|
||||
x, y *big.Int
|
||||
@@ -249,72 +385,7 @@ NextCandidate:
|
||||
serverECDHParams[3] = byte(len(ecdhePublic))
|
||||
copy(serverECDHParams[4:], ecdhePublic)
|
||||
|
||||
var tls12HashId uint8
|
||||
if ka.version >= VersionTLS12 {
|
||||
if tls12HashId, err = pickTLS12HashForSignature(ka.sigType, clientHello.signatureAndHashes); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
digest, hashFunc, err := hashForServerKeyExchange(ka.sigType, tls12HashId, ka.version, clientHello.random, hello.random, serverECDHParams)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if config.Bugs.InvalidSKXSignature {
|
||||
digest[0] ^= 0x80
|
||||
}
|
||||
|
||||
var sig []byte
|
||||
switch ka.sigType {
|
||||
case signatureECDSA:
|
||||
privKey, ok := cert.PrivateKey.(*ecdsa.PrivateKey)
|
||||
if !ok {
|
||||
return nil, errors.New("ECDHE ECDSA requires an ECDSA server private key")
|
||||
}
|
||||
r, s, err := ecdsa.Sign(config.rand(), privKey, digest)
|
||||
if err != nil {
|
||||
return nil, errors.New("failed to sign ECDHE parameters: " + err.Error())
|
||||
}
|
||||
order := privKey.Curve.Params().N
|
||||
r = maybeCorruptECDSAValue(r, config.Bugs.BadECDSAR, order)
|
||||
s = maybeCorruptECDSAValue(s, config.Bugs.BadECDSAS, order)
|
||||
sig, err = asn1.Marshal(ecdsaSignature{r, s})
|
||||
case signatureRSA:
|
||||
privKey, ok := cert.PrivateKey.(*rsa.PrivateKey)
|
||||
if !ok {
|
||||
return nil, errors.New("ECDHE RSA requires a RSA server private key")
|
||||
}
|
||||
sig, err = rsa.SignPKCS1v15(config.rand(), privKey, hashFunc, digest)
|
||||
if err != nil {
|
||||
return nil, errors.New("failed to sign ECDHE parameters: " + err.Error())
|
||||
}
|
||||
default:
|
||||
return nil, errors.New("unknown ECDHE signature algorithm")
|
||||
}
|
||||
|
||||
skx := new(serverKeyExchangeMsg)
|
||||
if config.Bugs.UnauthenticatedECDH {
|
||||
skx.key = serverECDHParams
|
||||
} else {
|
||||
sigAndHashLen := 0
|
||||
if ka.version >= VersionTLS12 {
|
||||
sigAndHashLen = 2
|
||||
}
|
||||
skx.key = make([]byte, len(serverECDHParams)+sigAndHashLen+2+len(sig))
|
||||
copy(skx.key, serverECDHParams)
|
||||
k := skx.key[len(serverECDHParams):]
|
||||
if ka.version >= VersionTLS12 {
|
||||
k[0] = tls12HashId
|
||||
k[1] = ka.sigType
|
||||
k = k[2:]
|
||||
}
|
||||
k[0] = byte(len(sig) >> 8)
|
||||
k[1] = byte(len(sig))
|
||||
copy(k[2:], sig)
|
||||
}
|
||||
|
||||
return skx, nil
|
||||
return ka.signParameters(config, cert, clientHello, hello, serverECDHParams)
|
||||
}
|
||||
|
||||
func (ka *ecdheKeyAgreement) processClientKeyExchange(config *Config, cert *Certificate, ckx *clientKeyExchangeMsg, version uint16) ([]byte, error) {
|
||||
@@ -356,64 +427,9 @@ func (ka *ecdheKeyAgreement) processServerKeyExchange(config *Config, clientHell
|
||||
return errServerKeyExchange
|
||||
}
|
||||
serverECDHParams := skx.key[:4+publicLen]
|
||||
|
||||
sig := skx.key[4+publicLen:]
|
||||
if len(sig) < 2 {
|
||||
return errServerKeyExchange
|
||||
}
|
||||
|
||||
var tls12HashId uint8
|
||||
if ka.version >= VersionTLS12 {
|
||||
// handle SignatureAndHashAlgorithm
|
||||
var sigAndHash []uint8
|
||||
sigAndHash, sig = sig[:2], sig[2:]
|
||||
if sigAndHash[1] != ka.sigType {
|
||||
return errServerKeyExchange
|
||||
}
|
||||
tls12HashId = sigAndHash[0]
|
||||
if len(sig) < 2 {
|
||||
return errServerKeyExchange
|
||||
}
|
||||
}
|
||||
sigLen := int(sig[0])<<8 | int(sig[1])
|
||||
if sigLen+2 != len(sig) {
|
||||
return errServerKeyExchange
|
||||
}
|
||||
sig = sig[2:]
|
||||
|
||||
digest, hashFunc, err := hashForServerKeyExchange(ka.sigType, tls12HashId, ka.version, clientHello.random, serverHello.random, serverECDHParams)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
switch ka.sigType {
|
||||
case signatureECDSA:
|
||||
pubKey, ok := cert.PublicKey.(*ecdsa.PublicKey)
|
||||
if !ok {
|
||||
return errors.New("ECDHE ECDSA requires a ECDSA server public key")
|
||||
}
|
||||
ecdsaSig := new(ecdsaSignature)
|
||||
if _, err := asn1.Unmarshal(sig, ecdsaSig); err != nil {
|
||||
return err
|
||||
}
|
||||
if ecdsaSig.R.Sign() <= 0 || ecdsaSig.S.Sign() <= 0 {
|
||||
return errors.New("ECDSA signature contained zero or negative values")
|
||||
}
|
||||
if !ecdsa.Verify(pubKey, digest, ecdsaSig.R, ecdsaSig.S) {
|
||||
return errors.New("ECDSA verification failure")
|
||||
}
|
||||
case signatureRSA:
|
||||
pubKey, ok := cert.PublicKey.(*rsa.PublicKey)
|
||||
if !ok {
|
||||
return errors.New("ECDHE RSA requires a RSA server public key")
|
||||
}
|
||||
if err := rsa.VerifyPKCS1v15(pubKey, hashFunc, digest, sig); err != nil {
|
||||
return err
|
||||
}
|
||||
default:
|
||||
return errors.New("unknown ECDHE signature algorithm")
|
||||
}
|
||||
|
||||
return nil
|
||||
return ka.verifyParameters(config, clientHello, serverHello, cert, serverECDHParams, sig)
|
||||
}
|
||||
|
||||
func (ka *ecdheKeyAgreement) generateClientKeyExchange(config *Config, clientHello *clientHelloMsg, cert *x509.Certificate) ([]byte, *clientKeyExchangeMsg, error) {
|
||||
@@ -438,3 +454,126 @@ func (ka *ecdheKeyAgreement) generateClientKeyExchange(config *Config, clientHel
|
||||
|
||||
return preMasterSecret, ckx, nil
|
||||
}
|
||||
|
||||
// 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 {
|
||||
signedKeyAgreement
|
||||
p, g *big.Int
|
||||
yTheirs *big.Int
|
||||
xOurs *big.Int
|
||||
}
|
||||
|
||||
func (ka *dheKeyAgreement) generateServerKeyExchange(config *Config, cert *Certificate, clientHello *clientHelloMsg, hello *serverHelloMsg) (*serverKeyExchangeMsg, error) {
|
||||
// 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)
|
||||
|
||||
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...)
|
||||
|
||||
return ka.signParameters(config, cert, clientHello, hello, serverDHParams)
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
sig := k
|
||||
serverDHParams := skx.key[:len(skx.key)-len(sig)]
|
||||
|
||||
return ka.verifyParameters(config, clientHello, serverHello, cert, serverDHParams, sig)
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
@@ -607,20 +607,27 @@ var testCipherSuites = []struct {
|
||||
id uint16
|
||||
}{
|
||||
{"3DES-SHA", TLS_RSA_WITH_3DES_EDE_CBC_SHA},
|
||||
{"AES128-GCM", TLS_RSA_WITH_AES_128_GCM_SHA256},
|
||||
{"AES128-SHA", TLS_RSA_WITH_AES_128_CBC_SHA},
|
||||
{"AES256-GCM", TLS_RSA_WITH_AES_256_GCM_SHA384},
|
||||
{"AES256-SHA", TLS_RSA_WITH_AES_256_CBC_SHA},
|
||||
{"DHE-RSA-3DES-SHA", TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA},
|
||||
{"DHE-RSA-AES128-GCM", TLS_DHE_RSA_WITH_AES_128_GCM_SHA256},
|
||||
{"DHE-RSA-AES128-SHA", TLS_DHE_RSA_WITH_AES_128_CBC_SHA},
|
||||
{"DHE-RSA-AES256-GCM", TLS_DHE_RSA_WITH_AES_256_GCM_SHA384},
|
||||
{"DHE-RSA-AES256-SHA", TLS_DHE_RSA_WITH_AES_256_CBC_SHA},
|
||||
{"ECDHE-ECDSA-AES128-GCM", TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
|
||||
{"ECDHE-ECDSA-AES128-SHA", TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA},
|
||||
{"ECDHE-ECDSA-AES256-SHA", TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA},
|
||||
{"ECDHE-ECDSA-RC4-SHA", TLS_ECDHE_ECDSA_WITH_RC4_128_SHA},
|
||||
{"ECDHE-RSA-3DES-SHA", TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA},
|
||||
{"ECDHE-RSA-AES128-GCM", TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
|
||||
{"ECDHE-RSA-AES256-GCM", TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384},
|
||||
{"ECDHE-RSA-AES128-SHA", TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA},
|
||||
{"ECDHE-RSA-AES256-GCM", TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384},
|
||||
{"ECDHE-RSA-AES256-SHA", TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA},
|
||||
{"ECDHE-RSA-RC4-SHA", TLS_ECDHE_RSA_WITH_RC4_128_SHA},
|
||||
{"RC4-SHA", TLS_RSA_WITH_RC4_128_SHA},
|
||||
{"RC4-MD5", TLS_RSA_WITH_RC4_128_MD5},
|
||||
{"RC4-SHA", TLS_RSA_WITH_RC4_128_SHA},
|
||||
}
|
||||
|
||||
func addCipherSuiteTests() {
|
||||
|
||||
Reference in New Issue
Block a user