Compare commits

...

3 Commits

Author SHA1 Message Date
David Benjamin 345b735e31 Import RSAEphemeralKey tests from master.
This is a cherry-pick of https://boringssl-review.googlesource.com/#/c/2232/
and https://boringssl-review.googlesource.com/#/c/3650/ from master.

Change-Id: Ia488e629f20a92121beefcf7e106292030b41f67
Reviewed-on: https://boringssl-review.googlesource.com/3660
Reviewed-by: Adam Langley <agl@google.com>
2015-02-26 21:39:53 +00:00
Adam Langley 3fbc298104 Only allow ephemeral RSA keys in export ciphersuites.
OpenSSL clients would tolerate temporary RSA keys in non-export ciphersuites.
It also had an option SSL_OP_EPHEMERAL_RSA which enabled this server side.
Remove both options as they are a protocol violation.

Thanks to Karthikeyan Bhargavan for reporting this issue. (CVE-2015-0204)

(This is a backport of upstream's
37580f43b5a39f5f4e920d17273fab9713d3a744 to the M40 branch. In BoringSSL
master we fixed this with
https://boringssl.googlesource.com/boringssl/+/525a0fe315282ca1840f8f9f170c8a26ce5fab2a,
but that's a larger patch than we really want to be backporting.)

Change-Id: Ibfb0c46648bbecffb9d3b1a4ebdf10a5a79523b3
Reviewed-on: https://boringssl-review.googlesource.com/3640
Reviewed-by: David Benjamin <davidben@chromium.org>
Reviewed-by: Adam Langley <agl@google.com>
2015-02-26 21:35:29 +00:00
Eric Roman 54e455157a Set output EC_KEY to NULL when d2i_ECPrivateKey() fails.
BUG=crbug.com/445679

Change-Id: Ia012d806964bd7240148779797eccd326484f364
Reviewed-on: https://boringssl-review.googlesource.com/2722
Reviewed-by: Adam Langley <agl@google.com>
(cherry picked from commit 517073cd4b)
2015-01-06 14:52:10 -08:00
7 changed files with 143 additions and 54 deletions
+3
View File
@@ -373,6 +373,9 @@ err:
EC_KEY_free(ret);
}
ret = NULL;
if (a) {
*a = ret;
}
}
if (priv_key) {
+53
View File
@@ -229,6 +229,20 @@ static const uint8_t kExampleECKeyDER[] = {
0xc1,
};
/* kExampleBadECKeyDER is a sample EC private key encoded as an ECPrivateKey
* structure. The private key is equal to the order and will fail to import */
static const uint8_t kExampleBadECKeyDER[] = {
0x30, 0x66, 0x02, 0x01, 0x00, 0x30, 0x13, 0x06, 0x07, 0x2A, 0x86, 0x48,
0xCE, 0x3D, 0x02, 0x01, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03,
0x01, 0x07, 0x04, 0x4C, 0x30, 0x4A, 0x02, 0x01, 0x01, 0x04, 0x20, 0xFF,
0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xBC, 0xE6, 0xFA, 0xAD, 0xA7, 0x17, 0x9E, 0x84, 0xF3,
0xB9, 0xCA, 0xC2, 0xFC, 0x63, 0x25, 0x51, 0xA1, 0x23, 0x03, 0x21, 0x00,
0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xBC, 0xE6, 0xFA, 0xAD, 0xA7, 0x17, 0x9E, 0x84,
0xF3, 0xB9, 0xCA, 0xC2, 0xFC, 0x63, 0x25, 0x51
};
static EVP_PKEY *load_example_rsa_key(void) {
EVP_PKEY *ret = NULL;
const uint8_t *derp = kExampleRSAKeyDER;
@@ -539,6 +553,40 @@ done:
return ret;
}
/* Tests loading a bad key in PKCS8 format */
static int test_EVP_PKCS82PKEY(void) {
int ret = 0;
const uint8_t *derp = kExampleBadECKeyDER;
PKCS8_PRIV_KEY_INFO *p8inf = NULL;
EVP_PKEY *pkey = NULL;
p8inf = d2i_PKCS8_PRIV_KEY_INFO(NULL, &derp, sizeof(kExampleBadECKeyDER));
if (!p8inf || derp != kExampleBadECKeyDER + sizeof(kExampleBadECKeyDER)) {
fprintf(stderr, "Failed to parse key\n");
goto done;
}
pkey = EVP_PKCS82PKEY(p8inf);
if (pkey) {
fprintf(stderr, "Imported invalid EC key\n");
goto done;
}
ret = 1;
done:
if (p8inf != NULL) {
PKCS8_PRIV_KEY_INFO_free(p8inf);
}
if (pkey != NULL) {
EVP_PKEY_free(pkey);
}
return ret;
}
int main(void) {
CRYPTO_library_init();
ERR_load_crypto_strings();
@@ -581,6 +629,11 @@ int main(void) {
return 1;
}
if (!test_EVP_PKCS82PKEY()) {
fprintf(stderr, "test_EVP_PKCS82PKEY failed\n");
return 1;
}
printf("PASS\n");
return 0;
}
+1 -49
View File
@@ -1293,55 +1293,7 @@ int ssl3_get_server_key_exchange(SSL *s)
}
}
if (alg_k & SSL_kRSA)
{
CBS rsa_modulus, rsa_exponent;
/* TODO(davidben): This was originally for export
* reasons. Do we still need to support it? */
if (!CBS_get_u16_length_prefixed(&server_key_exchange, &rsa_modulus) ||
CBS_len(&rsa_modulus) == 0 ||
!CBS_get_u16_length_prefixed(&server_key_exchange, &rsa_exponent) ||
CBS_len(&rsa_exponent) == 0)
{
al = SSL_AD_DECODE_ERROR;
OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange, SSL_R_DECODE_ERROR);
goto f_err;
}
if ((rsa=RSA_new()) == NULL)
{
OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange, ERR_R_MALLOC_FAILURE);
goto err;
}
if (!(rsa->n = BN_bin2bn(CBS_data(&rsa_modulus),
CBS_len(&rsa_modulus), rsa->n)))
{
OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange, ERR_R_BN_LIB);
goto err;
}
if (!(rsa->e = BN_bin2bn(CBS_data(&rsa_exponent),
CBS_len(&rsa_exponent), rsa->e)))
{
OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange, ERR_R_BN_LIB);
goto err;
}
/* this should be because we are using an export cipher */
if (alg_a & SSL_aRSA)
pkey=X509_get_pubkey(s->session->sess_cert->peer_pkeys[SSL_PKEY_RSA_ENC].x509);
else
{
OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange, ERR_R_INTERNAL_ERROR);
goto err;
}
s->session->sess_cert->peer_rsa_tmp=rsa;
rsa=NULL;
}
else if (alg_k & SSL_kEDH)
if (alg_k & SSL_kEDH)
{
CBS dh_p, dh_g, dh_Ys;
+1 -1
View File
@@ -289,7 +289,7 @@ func (s tls10MAC) MAC(digestBuf, seq, header, length, data []byte) []byte {
}
func rsaKA(version uint16) keyAgreement {
return rsaKeyAgreement{}
return &rsaKeyAgreement{version: version}
}
func ecdheECDSAKA(version uint16) keyAgreement {
+5
View File
@@ -499,6 +499,11 @@ type ProtocolBugs struct {
// BadRenegotiationInfo causes the renegotiation extension value in a
// renegotiation handshake to be incorrect.
BadRenegotiationInfo bool
// RSAEphemeralKey, if true, causes the server to send a
// ServerKeyExchange message containing an ephemeral key (as in
// RSA_EXPORT) in the plain RSA key exchange.
RSAEphemeralKey bool
}
func (c *Config) serverInit() {
+69 -4
View File
@@ -25,10 +25,71 @@ 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.
type rsaKeyAgreement struct{}
type rsaKeyAgreement struct {
version uint16
exportKey *rsa.PrivateKey
}
func (ka rsaKeyAgreement) generateServerKeyExchange(config *Config, cert *Certificate, clientHello *clientHelloMsg, hello *serverHelloMsg) (*serverKeyExchangeMsg, error) {
return nil, nil
func (ka *rsaKeyAgreement) generateServerKeyExchange(config *Config, cert *Certificate, clientHello *clientHelloMsg, hello *serverHelloMsg) (*serverKeyExchangeMsg, error) {
if !config.Bugs.RSAEphemeralKey {
return nil, nil
}
// 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...)
var tls12HashId uint8
if ka.version >= VersionTLS12 {
if tls12HashId, err = pickTLS12HashForSignature(signatureRSA, clientHello.signatureAndHashes); err != nil {
return nil, err
}
}
digest, hashFunc, err := hashForServerKeyExchange(signatureRSA, tls12HashId, ka.version, clientHello.random, hello.random, serverRSAParams)
if err != nil {
return nil, err
}
var sig []byte
privKey, ok := cert.PrivateKey.(*rsa.PrivateKey)
if !ok {
return nil, errors.New("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 RSA parameters: " + err.Error())
}
skx := new(serverKeyExchangeMsg)
sigAndHashLen := 0
if ka.version >= VersionTLS12 {
sigAndHashLen = 2
}
skx.key = make([]byte, len(serverRSAParams)+sigAndHashLen+2+len(sig))
copy(skx.key, serverRSAParams)
k := skx.key[len(serverRSAParams):]
if ka.version >= VersionTLS12 {
k[0] = tls12HashId
k[1] = signatureRSA
k = k[2:]
}
k[0] = byte(len(sig) >> 8)
k[1] = byte(len(sig))
copy(k[2:], sig)
return skx, nil
}
func (ka rsaKeyAgreement) processClientKeyExchange(config *Config, cert *Certificate, ckx *clientKeyExchangeMsg, version uint16) ([]byte, error) {
@@ -51,7 +112,11 @@ func (ka rsaKeyAgreement) processClientKeyExchange(config *Config, cert *Certifi
ciphertext = ckx.ciphertext[2:]
}
err = rsa.DecryptPKCS1v15SessionKey(config.rand(), cert.PrivateKey.(*rsa.PrivateKey), ciphertext, preMasterSecret)
key := cert.PrivateKey.(*rsa.PrivateKey)
if ka.exportKey != nil {
key = ka.exportKey
}
err = rsa.DecryptPKCS1v15SessionKey(config.rand(), key, ciphertext, preMasterSecret)
if err != nil {
return nil, err
}
+11
View File
@@ -492,6 +492,17 @@ var testCases = []testCase{
shouldFail: true,
expectedError: ":WRONG_CIPHER_RETURNED:",
},
{
name: "RSAEphemeralKey",
config: Config{
CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA},
Bugs: ProtocolBugs{
RSAEphemeralKey: true,
},
},
shouldFail: true,
expectedError: ":UNEXPECTED_MESSAGE:",
},
}
func doExchange(test *testCase, config *Config, conn net.Conn, messageLen int, isResume bool) error {