| Index: net/third_party/nss/ssl/ssl3ecc.c
|
| ===================================================================
|
| --- net/third_party/nss/ssl/ssl3ecc.c (revision 202696)
|
| +++ net/third_party/nss/ssl/ssl3ecc.c (working copy)
|
| @@ -31,6 +31,12 @@
|
|
|
| #include <stdio.h>
|
|
|
| +/* This is a bodge to allow this code to be compiled against older NSS headers
|
| + * that don't contain the TLS 1.2 changes. */
|
| +#ifndef CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256
|
| +#define CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256 (CKM_NSS + 24)
|
| +#endif
|
| +
|
| #ifdef NSS_ENABLE_ECC
|
|
|
| /*
|
| @@ -217,9 +223,10 @@
|
|
|
| /* Caller must set hiLevel error code. */
|
| static SECStatus
|
| -ssl3_ComputeECDHKeyHash(SECItem ec_params, SECItem server_ecpoint,
|
| - SSL3Random *client_rand, SSL3Random *server_rand,
|
| - SSL3Hashes *hashes, PRBool bypassPKCS11)
|
| +ssl3_ComputeECDHKeyHash(SECOidTag hashAlg,
|
| + SECItem ec_params, SECItem server_ecpoint,
|
| + SSL3Random *client_rand, SSL3Random *server_rand,
|
| + SSL3Hashes *hashes, PRBool bypassPKCS11)
|
| {
|
| PRUint8 * hashBuf;
|
| PRUint8 * pBuf;
|
| @@ -255,11 +262,14 @@
|
| pBuf += server_ecpoint.len;
|
| PORT_Assert((unsigned int)(pBuf - hashBuf) == bufLen);
|
|
|
| - rv = ssl3_ComputeCommonKeyHash(hashBuf, bufLen, hashes, bypassPKCS11);
|
| + rv = ssl3_ComputeCommonKeyHash(hashAlg, hashBuf, bufLen, hashes,
|
| + bypassPKCS11);
|
|
|
| PRINT_BUF(95, (NULL, "ECDHkey hash: ", hashBuf, bufLen));
|
| - PRINT_BUF(95, (NULL, "ECDHkey hash: MD5 result", hashes->md5, MD5_LENGTH));
|
| - PRINT_BUF(95, (NULL, "ECDHkey hash: SHA1 result", hashes->sha, SHA1_LENGTH));
|
| + PRINT_BUF(95, (NULL, "ECDHkey hash: MD5 result",
|
| + hashes->u.s.md5, MD5_LENGTH));
|
| + PRINT_BUF(95, (NULL, "ECDHkey hash: SHA1 result",
|
| + hashes->u.s.sha, SHA1_LENGTH));
|
|
|
| if (hashBuf != buf)
|
| PORT_Free(hashBuf);
|
| @@ -273,7 +283,7 @@
|
| {
|
| PK11SymKey * pms = NULL;
|
| SECStatus rv = SECFailure;
|
| - PRBool isTLS;
|
| + PRBool isTLS, isTLS12;
|
| CK_MECHANISM_TYPE target;
|
| SECKEYPublicKey *pubKey = NULL; /* Ephemeral ECDH key */
|
| SECKEYPrivateKey *privKey = NULL; /* Ephemeral ECDH key */
|
| @@ -282,6 +292,7 @@
|
| PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
|
|
|
| isTLS = (PRBool)(ss->ssl3.pwSpec->version > SSL_LIBRARY_VERSION_3_0);
|
| + isTLS12 = (PRBool)(ss->ssl3.pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2);
|
|
|
| /* Generate ephemeral EC keypair */
|
| if (svrPubKey->keyType != ecKey) {
|
| @@ -300,8 +311,13 @@
|
| pubKey->u.ec.publicValue.data,
|
| pubKey->u.ec.publicValue.len));
|
|
|
| - if (isTLS) target = CKM_TLS_MASTER_KEY_DERIVE_DH;
|
| - else target = CKM_SSL3_MASTER_KEY_DERIVE_DH;
|
| + if (isTLS12) {
|
| + target = CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256;
|
| + } else if (isTLS) {
|
| + target = CKM_TLS_MASTER_KEY_DERIVE_DH;
|
| + } else {
|
| + target = CKM_SSL3_MASTER_KEY_DERIVE_DH;
|
| + }
|
|
|
| /* Determine the PMS */
|
| pms = PK11_PubDeriveWithKDF(privKey, svrPubKey, PR_FALSE, NULL, NULL,
|
| @@ -365,7 +381,7 @@
|
| SECStatus rv;
|
| SECKEYPublicKey clntPubKey;
|
| CK_MECHANISM_TYPE target;
|
| - PRBool isTLS;
|
| + PRBool isTLS, isTLS12;
|
|
|
| PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
|
| PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
|
| @@ -384,9 +400,15 @@
|
| }
|
|
|
| isTLS = (PRBool)(ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0);
|
| + isTLS12 = (PRBool)(ss->ssl3.prSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2);
|
|
|
| - if (isTLS) target = CKM_TLS_MASTER_KEY_DERIVE_DH;
|
| - else target = CKM_SSL3_MASTER_KEY_DERIVE_DH;
|
| + if (isTLS12) {
|
| + target = CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256;
|
| + } else if (isTLS) {
|
| + target = CKM_TLS_MASTER_KEY_DERIVE_DH;
|
| + } else {
|
| + target = CKM_SSL3_MASTER_KEY_DERIVE_DH;
|
| + }
|
|
|
| /* Determine the PMS */
|
| pms = PK11_PubDeriveWithKDF(srvrPrivKey, &clntPubKey, PR_FALSE, NULL, NULL,
|
| @@ -582,7 +604,7 @@
|
| {
|
| PRArenaPool * arena = NULL;
|
| SECKEYPublicKey *peerKey = NULL;
|
| - PRBool isTLS;
|
| + PRBool isTLS, isTLS12;
|
| SECStatus rv;
|
| int errCode = SSL_ERROR_RX_MALFORMED_SERVER_KEY_EXCH;
|
| SSL3AlertDescription desc = illegal_parameter;
|
| @@ -592,8 +614,12 @@
|
| SECItem ec_params = {siBuffer, NULL, 0};
|
| SECItem ec_point = {siBuffer, NULL, 0};
|
| unsigned char paramBuf[3]; /* only for curve_type == named_curve */
|
| + SSL3SignatureAndHashAlgorithm sigAndHash;
|
|
|
| + sigAndHash.hashAlg = SEC_OID_UNKNOWN;
|
| +
|
| isTLS = (PRBool)(ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0);
|
| + isTLS12 = (PRBool)(ss->ssl3.prSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2);
|
|
|
| /* XXX This works only for named curves, revisit this when
|
| * we support generic curves.
|
| @@ -625,6 +651,19 @@
|
| goto alert_loser;
|
| }
|
|
|
| + if (isTLS12) {
|
| + rv = ssl3_ConsumeSignatureAndHashAlgorithm(ss, &b, &length,
|
| + &sigAndHash);
|
| + if (rv != SECSuccess) {
|
| + goto loser; /* malformed or unsupported. */
|
| + }
|
| + rv = ssl3_CheckSignatureAndHashAlgorithmConsistency(
|
| + &sigAndHash, ss->sec.peerCert);
|
| + if (rv != SECSuccess) {
|
| + goto loser;
|
| + }
|
| + }
|
| +
|
| rv = ssl3_ConsumeHandshakeVariable(ss, &signature, 2, &b, &length);
|
| if (rv != SECSuccess) {
|
| goto loser; /* malformed. */
|
| @@ -647,10 +686,10 @@
|
| /*
|
| * check to make sure the hash is signed by right guy
|
| */
|
| - rv = ssl3_ComputeECDHKeyHash(ec_params, ec_point,
|
| - &ss->ssl3.hs.client_random,
|
| - &ss->ssl3.hs.server_random,
|
| - &hashes, ss->opt.bypassPKCS11);
|
| + rv = ssl3_ComputeECDHKeyHash(sigAndHash.hashAlg, ec_params, ec_point,
|
| + &ss->ssl3.hs.client_random,
|
| + &ss->ssl3.hs.server_random,
|
| + &hashes, ss->opt.bypassPKCS11);
|
|
|
| if (rv != SECSuccess) {
|
| errCode =
|
| @@ -714,12 +753,14 @@
|
| }
|
|
|
| SECStatus
|
| -ssl3_SendECDHServerKeyExchange(sslSocket *ss)
|
| +ssl3_SendECDHServerKeyExchange(
|
| + sslSocket *ss,
|
| + const SSL3SignatureAndHashAlgorithm *sigAndHash)
|
| {
|
| -const ssl3KEADef * kea_def = ss->ssl3.hs.kea_def;
|
| + const ssl3KEADef * kea_def = ss->ssl3.hs.kea_def;
|
| SECStatus rv = SECFailure;
|
| int length;
|
| - PRBool isTLS;
|
| + PRBool isTLS, isTLS12;
|
| SECItem signed_hash = {siBuffer, NULL, 0};
|
| SSL3Hashes hashes;
|
|
|
| @@ -729,7 +770,6 @@
|
| ECName curve;
|
| SSL3KEAType certIndex;
|
|
|
| -
|
| /* Generate ephemeral ECDH key pair and send the public key */
|
| curve = ssl3_GetCurveNameForServerSocket(ss);
|
| if (curve == ec_noName) {
|
| @@ -758,16 +798,19 @@
|
| goto loser;
|
| }
|
|
|
| - rv = ssl3_ComputeECDHKeyHash(ec_params, ecdhePub->u.ec.publicValue,
|
| - &ss->ssl3.hs.client_random,
|
| - &ss->ssl3.hs.server_random,
|
| - &hashes, ss->opt.bypassPKCS11);
|
| + rv = ssl3_ComputeECDHKeyHash(sigAndHash->hashAlg,
|
| + ec_params,
|
| + ecdhePub->u.ec.publicValue,
|
| + &ss->ssl3.hs.client_random,
|
| + &ss->ssl3.hs.server_random,
|
| + &hashes, ss->opt.bypassPKCS11);
|
| if (rv != SECSuccess) {
|
| ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
|
| goto loser;
|
| }
|
|
|
| isTLS = (PRBool)(ss->ssl3.pwSpec->version > SSL_LIBRARY_VERSION_3_0);
|
| + isTLS12 = (PRBool)(ss->ssl3.pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2);
|
|
|
| /* XXX SSLKEAType isn't really a good choice for
|
| * indexing certificates but that's all we have
|
| @@ -791,7 +834,7 @@
|
|
|
| length = ec_params.len +
|
| 1 + ecdhePub->u.ec.publicValue.len +
|
| - 2 + signed_hash.len;
|
| + (isTLS12 ? 2 : 0) + 2 + signed_hash.len;
|
|
|
| rv = ssl3_AppendHandshakeHeader(ss, server_key_exchange, length);
|
| if (rv != SECSuccess) {
|
| @@ -809,6 +852,13 @@
|
| goto loser; /* err set by AppendHandshake. */
|
| }
|
|
|
| + if (isTLS12) {
|
| + rv = ssl3_AppendSignatureAndHashAlgorithm(ss, sigAndHash);
|
| + if (rv != SECSuccess) {
|
| + goto loser; /* err set by AppendHandshake. */
|
| + }
|
| + }
|
| +
|
| rv = ssl3_AppendHandshakeVariable(ss, signed_hash.data,
|
| signed_hash.len, 2);
|
| if (rv != SECSuccess) {
|
|
|