Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 345b735e31 | |||
| 3fbc298104 | |||
| 54e455157a |
@@ -373,6 +373,9 @@ err:
|
||||
EC_KEY_free(ret);
|
||||
}
|
||||
ret = NULL;
|
||||
if (a) {
|
||||
*a = ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (priv_key) {
|
||||
|
||||
@@ -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
@@ -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;
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user