| Index: net/third_party/nss/ssl/ssl3con.c
|
| ===================================================================
|
| --- net/third_party/nss/ssl/ssl3con.c (revision 242942)
|
| +++ net/third_party/nss/ssl/ssl3con.c (working copy)
|
| @@ -111,98 +111,117 @@
|
| * precedence (desirability). It only includes cipher suites we implement.
|
| * This table is modified by SSL3_SetPolicy(). The ordering of cipher suites
|
| * in this table must match the ordering in SSL_ImplementedCiphers (sslenum.c)
|
| + *
|
| + * Important: See bug 946147 before enabling, reordering, or adding any cipher
|
| + * suites to this list.
|
| */
|
| static ssl3CipherSuiteCfg cipherSuites[ssl_V3_SUITES_IMPLEMENTED] = {
|
| - /* cipher_suite policy enabled is_present*/
|
| -#ifdef NSS_ENABLE_ECC
|
| - { TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
|
| - { TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
|
| - { TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
|
| - { TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
|
| -#endif /* NSS_ENABLE_ECC */
|
| - { TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, SSL_NOT_ALLOWED, PR_TRUE,PR_FALSE},
|
| - { TLS_RSA_WITH_AES_128_GCM_SHA256, SSL_NOT_ALLOWED, PR_TRUE,PR_FALSE},
|
| + /* cipher_suite policy enabled isPresent */
|
|
|
| #ifdef NSS_ENABLE_ECC
|
| - { TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
|
| - { TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
|
| + { TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, SSL_ALLOWED, PR_FALSE, PR_FALSE},
|
| + { TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, SSL_ALLOWED, PR_FALSE, PR_FALSE},
|
| + { TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, SSL_ALLOWED, PR_FALSE, PR_FALSE},
|
| + { TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, SSL_ALLOWED, PR_FALSE, PR_FALSE},
|
| + /* TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA is out of order to work around
|
| + * bug 946147.
|
| + */
|
| + { TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, SSL_ALLOWED, PR_FALSE, PR_FALSE},
|
| + { TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, SSL_ALLOWED, PR_FALSE, PR_FALSE},
|
| + { TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, SSL_ALLOWED, PR_FALSE, PR_FALSE},
|
| + { TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, SSL_ALLOWED, PR_FALSE, PR_FALSE},
|
| + { TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, SSL_ALLOWED, PR_FALSE, PR_FALSE},
|
| + { TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, SSL_ALLOWED, PR_FALSE, PR_FALSE},
|
| + { TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, SSL_ALLOWED, PR_FALSE, PR_FALSE},
|
| + { TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_ALLOWED, PR_FALSE, PR_FALSE},
|
| + { TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, SSL_ALLOWED, PR_FALSE, PR_FALSE},
|
| + { TLS_ECDHE_RSA_WITH_RC4_128_SHA, SSL_ALLOWED, PR_FALSE, PR_FALSE},
|
| #endif /* NSS_ENABLE_ECC */
|
| - { TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
|
| - { TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
|
| - { TLS_DHE_RSA_WITH_AES_256_CBC_SHA, SSL_NOT_ALLOWED, PR_TRUE,PR_FALSE},
|
| - { TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, SSL_NOT_ALLOWED, PR_TRUE,PR_FALSE},
|
| - { TLS_DHE_DSS_WITH_AES_256_CBC_SHA, SSL_NOT_ALLOWED, PR_TRUE,PR_FALSE},
|
| -#ifdef NSS_ENABLE_ECC
|
| - { TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
|
| - { TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
|
| -#endif /* NSS_ENABLE_ECC */
|
| - { TLS_RSA_WITH_CAMELLIA_256_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
|
| - { TLS_RSA_WITH_AES_256_CBC_SHA, SSL_NOT_ALLOWED, PR_TRUE,PR_FALSE},
|
| - { TLS_RSA_WITH_AES_256_CBC_SHA256, SSL_NOT_ALLOWED, PR_TRUE,PR_FALSE},
|
|
|
| -#ifdef NSS_ENABLE_ECC
|
| - { TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
|
| - { TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
|
| - { TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
|
| - { TLS_ECDHE_RSA_WITH_RC4_128_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
|
| - { TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
|
| - { TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
|
| -#endif /* NSS_ENABLE_ECC */
|
| - { TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
|
| - { TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
|
| - { TLS_DHE_DSS_WITH_RC4_128_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
|
| - { TLS_DHE_RSA_WITH_AES_128_CBC_SHA, SSL_NOT_ALLOWED, PR_TRUE,PR_FALSE},
|
| - { TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, SSL_NOT_ALLOWED, PR_TRUE,PR_FALSE},
|
| - { TLS_DHE_DSS_WITH_AES_128_CBC_SHA, SSL_NOT_ALLOWED, PR_TRUE,PR_FALSE},
|
| -#ifdef NSS_ENABLE_ECC
|
| - { TLS_ECDH_RSA_WITH_RC4_128_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
|
| - { TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
|
| - { TLS_ECDH_ECDSA_WITH_RC4_128_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
|
| - { TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
|
| -#endif /* NSS_ENABLE_ECC */
|
| - { TLS_RSA_WITH_SEED_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
|
| - { TLS_RSA_WITH_CAMELLIA_128_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
|
| - { SSL_RSA_WITH_RC4_128_SHA, SSL_NOT_ALLOWED, PR_TRUE,PR_FALSE},
|
| - { SSL_RSA_WITH_RC4_128_MD5, SSL_NOT_ALLOWED, PR_TRUE, PR_FALSE},
|
| - { TLS_RSA_WITH_AES_128_CBC_SHA, SSL_NOT_ALLOWED, PR_TRUE,PR_FALSE},
|
| - { TLS_RSA_WITH_AES_128_CBC_SHA256, SSL_NOT_ALLOWED, PR_TRUE,PR_FALSE},
|
| + { TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, SSL_ALLOWED, PR_TRUE, PR_FALSE},
|
| + { TLS_DHE_RSA_WITH_AES_128_CBC_SHA, SSL_ALLOWED, PR_TRUE, PR_FALSE},
|
| + { TLS_DHE_DSS_WITH_AES_128_CBC_SHA, SSL_ALLOWED, PR_TRUE, PR_FALSE},
|
| + { TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, SSL_ALLOWED, PR_TRUE, PR_FALSE},
|
| + { TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA, SSL_ALLOWED, PR_FALSE, PR_FALSE},
|
| + { TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA, SSL_ALLOWED, PR_FALSE, PR_FALSE},
|
| + { TLS_DHE_RSA_WITH_AES_256_CBC_SHA, SSL_ALLOWED, PR_TRUE, PR_FALSE},
|
| + { TLS_DHE_DSS_WITH_AES_256_CBC_SHA, SSL_ALLOWED, PR_TRUE, PR_FALSE},
|
| + { TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, SSL_ALLOWED, PR_TRUE, PR_FALSE},
|
| + { TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA, SSL_ALLOWED, PR_FALSE, PR_FALSE},
|
| + { TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA, SSL_ALLOWED, PR_FALSE, PR_FALSE},
|
| + { SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_ALLOWED, PR_TRUE, PR_FALSE},
|
| + { SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, SSL_ALLOWED, PR_TRUE, PR_FALSE},
|
| + { TLS_DHE_DSS_WITH_RC4_128_SHA, SSL_ALLOWED, PR_FALSE, PR_FALSE},
|
|
|
| #ifdef NSS_ENABLE_ECC
|
| - { TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
|
| - { TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
|
| + { TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, SSL_ALLOWED, PR_FALSE, PR_FALSE},
|
| + { TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, SSL_ALLOWED, PR_FALSE, PR_FALSE},
|
| + { TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, SSL_ALLOWED, PR_FALSE, PR_FALSE},
|
| + { TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, SSL_ALLOWED, PR_FALSE, PR_FALSE},
|
| + { TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, SSL_ALLOWED, PR_FALSE, PR_FALSE},
|
| + { TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, SSL_ALLOWED, PR_FALSE, PR_FALSE},
|
| + { TLS_ECDH_ECDSA_WITH_RC4_128_SHA, SSL_ALLOWED, PR_FALSE, PR_FALSE},
|
| + { TLS_ECDH_RSA_WITH_RC4_128_SHA, SSL_ALLOWED, PR_FALSE, PR_FALSE},
|
| #endif /* NSS_ENABLE_ECC */
|
| - { SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, PR_TRUE,PR_FALSE},
|
| - { SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, PR_TRUE,PR_FALSE},
|
| -#ifdef NSS_ENABLE_ECC
|
| - { TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
|
| - { TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
|
| -#endif /* NSS_ENABLE_ECC */
|
| - { SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE, PR_FALSE},
|
| - { SSL_RSA_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, PR_TRUE, PR_FALSE},
|
|
|
| + /* RSA */
|
| + { TLS_RSA_WITH_AES_128_GCM_SHA256, SSL_ALLOWED, PR_TRUE, PR_FALSE},
|
| + { TLS_RSA_WITH_AES_128_CBC_SHA, SSL_ALLOWED, PR_TRUE, PR_FALSE},
|
| + { TLS_RSA_WITH_AES_128_CBC_SHA256, SSL_ALLOWED, PR_TRUE, PR_FALSE},
|
| + { TLS_RSA_WITH_CAMELLIA_128_CBC_SHA, SSL_ALLOWED, PR_FALSE, PR_FALSE},
|
| + { TLS_RSA_WITH_AES_256_CBC_SHA, SSL_ALLOWED, PR_TRUE, PR_FALSE},
|
| + { TLS_RSA_WITH_AES_256_CBC_SHA256, SSL_ALLOWED, PR_TRUE, PR_FALSE},
|
| + { TLS_RSA_WITH_CAMELLIA_256_CBC_SHA, SSL_ALLOWED, PR_FALSE, PR_FALSE},
|
| + { TLS_RSA_WITH_SEED_CBC_SHA, SSL_ALLOWED, PR_FALSE, PR_FALSE},
|
| + { SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA, SSL_ALLOWED, PR_FALSE, PR_FALSE},
|
| + { SSL_RSA_WITH_3DES_EDE_CBC_SHA, SSL_ALLOWED, PR_TRUE, PR_FALSE},
|
| + { SSL_RSA_WITH_RC4_128_SHA, SSL_ALLOWED, PR_TRUE, PR_FALSE},
|
| + { SSL_RSA_WITH_RC4_128_MD5, SSL_ALLOWED, PR_TRUE, PR_FALSE},
|
|
|
| - { SSL_DHE_RSA_WITH_DES_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
|
| - { SSL_DHE_DSS_WITH_DES_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
|
| - { SSL_RSA_FIPS_WITH_DES_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE, PR_FALSE},
|
| - { SSL_RSA_WITH_DES_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE, PR_FALSE},
|
| - { TLS_RSA_EXPORT1024_WITH_RC4_56_SHA, SSL_NOT_ALLOWED, PR_FALSE, PR_FALSE},
|
| - { TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE, PR_FALSE},
|
| + /* 56-bit DES "domestic" cipher suites */
|
| + { SSL_DHE_RSA_WITH_DES_CBC_SHA, SSL_ALLOWED, PR_FALSE, PR_FALSE},
|
| + { SSL_DHE_DSS_WITH_DES_CBC_SHA, SSL_ALLOWED, PR_FALSE, PR_FALSE},
|
| + { SSL_RSA_FIPS_WITH_DES_CBC_SHA, SSL_ALLOWED, PR_FALSE, PR_FALSE},
|
| + { SSL_RSA_WITH_DES_CBC_SHA, SSL_ALLOWED, PR_FALSE, PR_FALSE},
|
|
|
| - { SSL_RSA_EXPORT_WITH_RC4_40_MD5, SSL_NOT_ALLOWED, PR_FALSE, PR_FALSE},
|
| - { SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5, SSL_NOT_ALLOWED, PR_FALSE, PR_FALSE},
|
| + /* export ciphersuites with 1024-bit public key exchange keys */
|
| + { TLS_RSA_EXPORT1024_WITH_RC4_56_SHA, SSL_ALLOWED, PR_FALSE, PR_FALSE},
|
| + { TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA, SSL_ALLOWED, PR_FALSE, PR_FALSE},
|
|
|
| + /* export ciphersuites with 512-bit public key exchange keys */
|
| + { SSL_RSA_EXPORT_WITH_RC4_40_MD5, SSL_ALLOWED, PR_FALSE, PR_FALSE},
|
| + { SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5, SSL_ALLOWED, PR_FALSE, PR_FALSE},
|
| +
|
| + /* ciphersuites with no encryption */
|
| #ifdef NSS_ENABLE_ECC
|
| - { TLS_ECDHE_ECDSA_WITH_NULL_SHA, SSL_NOT_ALLOWED, PR_FALSE, PR_FALSE},
|
| - { TLS_ECDHE_RSA_WITH_NULL_SHA, SSL_NOT_ALLOWED, PR_FALSE, PR_FALSE},
|
| - { TLS_ECDH_RSA_WITH_NULL_SHA, SSL_NOT_ALLOWED, PR_FALSE, PR_FALSE},
|
| - { TLS_ECDH_ECDSA_WITH_NULL_SHA, SSL_NOT_ALLOWED, PR_FALSE, PR_FALSE},
|
| + { TLS_ECDHE_ECDSA_WITH_NULL_SHA, SSL_ALLOWED, PR_FALSE, PR_FALSE},
|
| + { TLS_ECDHE_RSA_WITH_NULL_SHA, SSL_ALLOWED, PR_FALSE, PR_FALSE},
|
| + { TLS_ECDH_RSA_WITH_NULL_SHA, SSL_ALLOWED, PR_FALSE, PR_FALSE},
|
| + { TLS_ECDH_ECDSA_WITH_NULL_SHA, SSL_ALLOWED, PR_FALSE, PR_FALSE},
|
| #endif /* NSS_ENABLE_ECC */
|
| - { SSL_RSA_WITH_NULL_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
|
| - { TLS_RSA_WITH_NULL_SHA256, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
|
| - { SSL_RSA_WITH_NULL_MD5, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
|
| -
|
| + { SSL_RSA_WITH_NULL_SHA, SSL_ALLOWED, PR_FALSE, PR_FALSE},
|
| + { TLS_RSA_WITH_NULL_SHA256, SSL_ALLOWED, PR_FALSE, PR_FALSE},
|
| + { SSL_RSA_WITH_NULL_MD5, SSL_ALLOWED, PR_FALSE, PR_FALSE},
|
| };
|
|
|
| +/* Verify that SSL_ImplementedCiphers and cipherSuites are in consistent order.
|
| + */
|
| +#ifdef DEBUG
|
| +void ssl3_CheckCipherSuiteOrderConsistency()
|
| +{
|
| + unsigned int i;
|
| +
|
| + /* Note that SSL_ImplementedCiphers has more elements than cipherSuites
|
| + * because it SSL_ImplementedCiphers includes SSL 2.0 cipher suites.
|
| + */
|
| + PORT_Assert(SSL_NumImplementedCiphers >= PR_ARRAY_SIZE(cipherSuites));
|
| +
|
| + for (i = 0; i < PR_ARRAY_SIZE(cipherSuites); ++i) {
|
| + PORT_Assert(SSL_ImplementedCiphers[i] == cipherSuites[i].cipher_suite);
|
| + }
|
| +}
|
| +#endif
|
| +
|
| /* This list of SSL3 compression methods is sorted in descending order of
|
| * precedence (desirability). It only includes compression methods we
|
| * implement.
|
| @@ -494,8 +513,6 @@
|
| #define mmech_md5_hmac CKM_MD5_HMAC
|
| #define mmech_sha_hmac CKM_SHA_1_HMAC
|
| #define mmech_sha256_hmac CKM_SHA256_HMAC
|
| -#define mmech_sha384_hmac CKM_SHA384_HMAC
|
| -#define mmech_sha512_hmac CKM_SHA512_HMAC
|
|
|
| static const ssl3MACDef mac_defs[] = { /* indexed by SSL3MACAlgorithm */
|
| /* pad_size is only used for SSL 3.0 MAC. See RFC 6101 Sec. 5.2.3.1. */
|
| @@ -839,7 +856,7 @@
|
| int i, count = 0;
|
|
|
| if (SSL3_ALL_VERSIONS_DISABLED(&ss->vrange)) {
|
| - return 0;
|
| + return 0;
|
| }
|
| for (i = 0; i < ssl_V3_SUITES_IMPLEMENTED; i++) {
|
| if (config_match(&ss->cipherSuites[i], policy, enabled, &ss->vrange))
|
| @@ -905,16 +922,10 @@
|
| static SECStatus
|
| ssl3_GetNewRandom(SSL3Random *random)
|
| {
|
| - PRUint32 gmt = ssl_Time();
|
| SECStatus rv;
|
|
|
| - random->rand[0] = (unsigned char)(gmt >> 24);
|
| - random->rand[1] = (unsigned char)(gmt >> 16);
|
| - random->rand[2] = (unsigned char)(gmt >> 8);
|
| - random->rand[3] = (unsigned char)(gmt);
|
| -
|
| /* first 4 bytes are reserverd for time */
|
| - rv = PK11_GenerateRandom(&random->rand[4], SSL3_RANDOM_LENGTH - 4);
|
| + rv = PK11_GenerateRandom(random->rand, SSL3_RANDOM_LENGTH);
|
| if (rv != SECSuccess) {
|
| ssl_MapLowLevelError(SSL_ERROR_GENERATE_RANDOM_FAILURE);
|
| }
|
| @@ -1052,7 +1063,7 @@
|
| }
|
| /* Allow DER encoded DSA signatures in SSL 3.0 */
|
| if (isTLS || buf->len != SECKEY_SignatureLen(key)) {
|
| - signature = DSAU_DecodeDerSig(buf);
|
| + signature = DSAU_DecodeDerSigToLen(buf, SECKEY_SignatureLen(key));
|
| if (!signature) {
|
| PORT_SetError(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE);
|
| return SECFailure;
|
| @@ -1637,7 +1648,7 @@
|
|
|
| calg = cipher_def->calg;
|
|
|
| - if (calg == calg_aes_gcm) {
|
| + if (calg == ssl_calg_aes_gcm) {
|
| pwSpec->encode = NULL;
|
| pwSpec->decode = NULL;
|
| pwSpec->destroy = NULL;
|
| @@ -1753,6 +1764,7 @@
|
| case ssl_calg_rc2:
|
| case ssl_calg_idea:
|
| case ssl_calg_fortezza:
|
| + case ssl_calg_aes_gcm:
|
| break;
|
| }
|
|
|
| @@ -2506,20 +2518,6 @@
|
| return rv;
|
| }
|
|
|
| -/* This is a bodge to allow this code to be compiled against older NSS headers
|
| - * that don't contain the CBC constant-time changes. */
|
| -#ifndef CKM_NSS_HMAC_CONSTANT_TIME
|
| -#define CKM_NSS_HMAC_CONSTANT_TIME (CKM_NSS + 19)
|
| -#define CKM_NSS_SSL3_MAC_CONSTANT_TIME (CKM_NSS + 20)
|
| -
|
| -typedef struct CK_NSS_MAC_CONSTANT_TIME_PARAMS {
|
| - CK_MECHANISM_TYPE macAlg; /* in */
|
| - CK_ULONG ulBodyTotalLen; /* in */
|
| - CK_BYTE * pHeader; /* in */
|
| - CK_ULONG ulHeaderLen; /* in */
|
| -} CK_NSS_MAC_CONSTANT_TIME_PARAMS;
|
| -#endif
|
| -
|
| /* Called from: ssl3_HandleRecord()
|
| * Caller must already hold the SpecReadLock. (wish we could assert that!)
|
| *
|
| @@ -2540,8 +2538,7 @@
|
| {
|
| CK_MECHANISM_TYPE macType;
|
| CK_NSS_MAC_CONSTANT_TIME_PARAMS params;
|
| - PK11Context * mac_context;
|
| - SECItem param;
|
| + SECItem param, inputItem, outputItem;
|
| SECStatus rv;
|
| PK11SymKey * key;
|
|
|
| @@ -2573,27 +2570,34 @@
|
| param.len = sizeof(params);
|
| param.type = 0;
|
|
|
| + inputItem.data = (unsigned char *) input;
|
| + inputItem.len = inputLen;
|
| + inputItem.type = 0;
|
| +
|
| + outputItem.data = outbuf;
|
| + outputItem.len = *outLen;
|
| + outputItem.type = 0;
|
| +
|
| key = spec->server.write_mac_key;
|
| if (!useServerMacKey) {
|
| key = spec->client.write_mac_key;
|
| }
|
| - mac_context = PK11_CreateContextBySymKey(macType, CKA_SIGN, key, ¶m);
|
| - if (mac_context == NULL) {
|
| - /* Older versions of NSS may not support constant-time MAC. */
|
| - goto fallback;
|
| - }
|
|
|
| - rv = PK11_DigestBegin(mac_context);
|
| - rv |= PK11_DigestOp(mac_context, input, inputLen);
|
| - rv |= PK11_DigestFinal(mac_context, outbuf, outLen, spec->mac_size);
|
| - PK11_DestroyContext(mac_context, PR_TRUE);
|
| + rv = PK11_SignWithSymKey(key, macType, ¶m, &outputItem, &inputItem);
|
| + if (rv != SECSuccess) {
|
| + if (PORT_GetError() == SEC_ERROR_INVALID_ALGORITHM) {
|
| + goto fallback;
|
| + }
|
|
|
| - PORT_Assert(rv != SECSuccess || *outLen == (unsigned)spec->mac_size);
|
| -
|
| - if (rv != SECSuccess) {
|
| + *outLen = 0;
|
| rv = SECFailure;
|
| ssl_MapLowLevelError(SSL_ERROR_MAC_COMPUTATION_FAILURE);
|
| + return rv;
|
| }
|
| +
|
| + PORT_Assert(outputItem.len == (unsigned)spec->mac_size);
|
| + *outLen = outputItem.len;
|
| +
|
| return rv;
|
|
|
| fallback:
|
| @@ -2876,8 +2880,8 @@
|
| * addition, if the record layer version number of ClientHello is { 3, 2 }
|
| * (TLS 1.1) or higher, these servers reset the TCP connections. Lastly,
|
| * some F5 BIG-IP servers hang if a record containing a ClientHello has a
|
| - * version greater than 0x0301 and a length greater than 255. Set this flag
|
| - * to work around such servers.
|
| + * version greater than { 3, 1 } and a length greater than 255. Set this
|
| + * flag to work around such servers.
|
| */
|
| PRInt32
|
| ssl3_SendRecord( sslSocket * ss,
|
| @@ -4017,15 +4021,23 @@
|
| return SECFailure;
|
| }
|
|
|
| - /* A backup SHA-1 hash for a potential client auth signature. */
|
| + /* Create a backup SHA-1 hash for a potential client auth
|
| + * signature.
|
| + *
|
| + * In TLS 1.2, ssl3_ComputeHandshakeHashes always uses the
|
| + * handshake hash function (SHA-256). If the server or the client
|
| + * does not support SHA-256 as a signature hash, we can either
|
| + * maintain a backup SHA-1 handshake hash or buffer all handshake
|
| + * messages.
|
| + */
|
| if (!ss->sec.isServer) {
|
| - ss->ssl3.hs.md5 = PK11_CreateDigestContext(SEC_OID_SHA1);
|
| - if (ss->ssl3.hs.md5 == NULL) {
|
| + ss->ssl3.hs.backupHash = PK11_CreateDigestContext(SEC_OID_SHA1);
|
| + if (ss->ssl3.hs.backupHash == NULL) {
|
| ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
|
| return SECFailure;
|
| }
|
|
|
| - if (PK11_DigestBegin(ss->ssl3.hs.md5) != SECSuccess) {
|
| + if (PK11_DigestBegin(ss->ssl3.hs.backupHash) != SECSuccess) {
|
| ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
|
| return SECFailure;
|
| }
|
| @@ -4140,8 +4152,8 @@
|
| ssl_MapLowLevelError(SSL_ERROR_DIGEST_FAILURE);
|
| return rv;
|
| }
|
| - if (ss->ssl3.hs.md5) {
|
| - rv = PK11_DigestOp(ss->ssl3.hs.md5, b, l);
|
| + if (ss->ssl3.hs.backupHash) {
|
| + rv = PK11_DigestOp(ss->ssl3.hs.backupHash, b, l);
|
| if (rv != SECSuccess) {
|
| ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
|
| return rv;
|
| @@ -4902,9 +4914,10 @@
|
| SECStatus rv = SECSuccess;
|
|
|
| PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
|
| + PORT_Assert( !ss->sec.isServer );
|
| PORT_Assert( ss->ssl3.hs.hashType == handshake_hash_single );
|
|
|
| - rv = PK11_DigestFinal(ss->ssl3.hs.md5, hashes->u.raw, &hashes->len,
|
| + rv = PK11_DigestFinal(ss->ssl3.hs.backupHash, hashes->u.raw, &hashes->len,
|
| sizeof(hashes->u.raw));
|
| if (rv != SECSuccess) {
|
| ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
|
| @@ -4914,8 +4927,8 @@
|
| hashes->hashAlg = SEC_OID_SHA1;
|
|
|
| loser:
|
| - PK11_DestroyContext(ss->ssl3.hs.md5, PR_TRUE);
|
| - ss->ssl3.hs.md5 = NULL;
|
| + PK11_DestroyContext(ss->ssl3.hs.backupHash, PR_TRUE);
|
| + ss->ssl3.hs.backupHash = NULL;
|
| return rv;
|
| }
|
|
|
| @@ -4995,6 +5008,9 @@
|
| ss->ssl3.hs.sendingSCSV = PR_FALSE; /* Must be reset every handshake */
|
| PORT_Assert(IS_DTLS(ss) || !resending);
|
|
|
| + SECITEM_FreeItem(&ss->ssl3.hs.newSessionTicket.ticket, PR_FALSE);
|
| + ss->ssl3.hs.receivedNewSessionTicket = PR_FALSE;
|
| +
|
| /* We might be starting a session renegotiation in which case we should
|
| * clear previous state.
|
| */
|
| @@ -5119,11 +5135,6 @@
|
| requestingResume = PR_TRUE;
|
| SSL_AtomicIncrementLong(& ssl3stats.sch_sid_cache_hits );
|
|
|
| - /* Are we attempting a stateless session resume? */
|
| - if (sid->version > SSL_LIBRARY_VERSION_3_0 &&
|
| - sid->u.ssl3.sessionTicket.ticket.data)
|
| - SSL_AtomicIncrementLong(& ssl3stats.sch_sid_stateless_resumes );
|
| -
|
| PRINT_BUF(4, (ss, "client, found session-id:", sid->u.ssl3.sessionID,
|
| sid->u.ssl3.sessionIDLength));
|
|
|
| @@ -5192,12 +5203,24 @@
|
| ss->ssl3.hs.sendingSCSV = PR_TRUE;
|
| }
|
|
|
| + /* When we attempt session resumption (only), we must lock the sid to
|
| + * prevent races with other resumption connections that receive a
|
| + * NewSessionTicket that will cause the ticket in the sid to be replaced.
|
| + * Once we've copied the session ticket into our ClientHello message, it
|
| + * is OK for the ticket to change, so we just need to make sure we hold
|
| + * the lock across the calls to ssl3_CallHelloExtensionSenders.
|
| + */
|
| + if (sid->u.ssl3.lock) {
|
| + PR_RWLock_Rlock(sid->u.ssl3.lock);
|
| + }
|
| +
|
| if (isTLS || (ss->firstHsDone && ss->peerRequestedProtection)) {
|
| PRUint32 maxBytes = 65535; /* 2^16 - 1 */
|
| PRInt32 extLen;
|
|
|
| extLen = ssl3_CallHelloExtensionSenders(ss, PR_FALSE, maxBytes, NULL);
|
| if (extLen < 0) {
|
| + if (sid->u.ssl3.lock) { PR_RWLock_Unlock(sid->u.ssl3.lock); }
|
| return SECFailure;
|
| }
|
| maxBytes -= extLen;
|
| @@ -5224,8 +5247,10 @@
|
|
|
| /* how many suites are permitted by policy and user preference? */
|
| num_suites = count_cipher_suites(ss, ss->ssl3.policy, PR_TRUE);
|
| - if (!num_suites)
|
| + if (!num_suites) {
|
| + if (sid->u.ssl3.lock) { PR_RWLock_Unlock(sid->u.ssl3.lock); }
|
| return SECFailure; /* count_cipher_suites has set error code. */
|
| + }
|
|
|
| fallbackSCSV = ss->opt.enableFallbackSCSV && (!requestingResume ||
|
| ss->version < sid->version);
|
| @@ -5268,6 +5293,7 @@
|
|
|
| rv = ssl3_AppendHandshakeHeader(ss, client_hello, length);
|
| if (rv != SECSuccess) {
|
| + if (sid->u.ssl3.lock) { PR_RWLock_Unlock(sid->u.ssl3.lock); }
|
| return rv; /* err set by ssl3_AppendHandshake* */
|
| }
|
|
|
| @@ -5286,18 +5312,21 @@
|
| rv = ssl3_AppendHandshakeNumber(ss, ss->clientHelloVersion, 2);
|
| }
|
| if (rv != SECSuccess) {
|
| + if (sid->u.ssl3.lock) { PR_RWLock_Unlock(sid->u.ssl3.lock); }
|
| return rv; /* err set by ssl3_AppendHandshake* */
|
| }
|
|
|
| if (!resending) { /* Don't re-generate if we are in DTLS re-sending mode */
|
| rv = ssl3_GetNewRandom(&ss->ssl3.hs.client_random);
|
| if (rv != SECSuccess) {
|
| + if (sid->u.ssl3.lock) { PR_RWLock_Unlock(sid->u.ssl3.lock); }
|
| return rv; /* err set by GetNewRandom. */
|
| }
|
| }
|
| rv = ssl3_AppendHandshake(ss, &ss->ssl3.hs.client_random,
|
| SSL3_RANDOM_LENGTH);
|
| if (rv != SECSuccess) {
|
| + if (sid->u.ssl3.lock) { PR_RWLock_Unlock(sid->u.ssl3.lock); }
|
| return rv; /* err set by ssl3_AppendHandshake* */
|
| }
|
|
|
| @@ -5307,6 +5336,7 @@
|
| else
|
| rv = ssl3_AppendHandshakeVariable(ss, NULL, 0, 1);
|
| if (rv != SECSuccess) {
|
| + if (sid->u.ssl3.lock) { PR_RWLock_Unlock(sid->u.ssl3.lock); }
|
| return rv; /* err set by ssl3_AppendHandshake* */
|
| }
|
|
|
| @@ -5314,12 +5344,14 @@
|
| rv = ssl3_AppendHandshakeVariable(
|
| ss, ss->ssl3.hs.cookie, ss->ssl3.hs.cookieLen, 1);
|
| if (rv != SECSuccess) {
|
| + if (sid->u.ssl3.lock) { PR_RWLock_Unlock(sid->u.ssl3.lock); }
|
| return rv; /* err set by ssl3_AppendHandshake* */
|
| }
|
| }
|
|
|
| rv = ssl3_AppendHandshakeNumber(ss, num_suites*sizeof(ssl3CipherSuite), 2);
|
| if (rv != SECSuccess) {
|
| + if (sid->u.ssl3.lock) { PR_RWLock_Unlock(sid->u.ssl3.lock); }
|
| return rv; /* err set by ssl3_AppendHandshake* */
|
| }
|
|
|
| @@ -5328,6 +5360,7 @@
|
| rv = ssl3_AppendHandshakeNumber(ss, TLS_EMPTY_RENEGOTIATION_INFO_SCSV,
|
| sizeof(ssl3CipherSuite));
|
| if (rv != SECSuccess) {
|
| + if (sid->u.ssl3.lock) { PR_RWLock_Unlock(sid->u.ssl3.lock); }
|
| return rv; /* err set by ssl3_AppendHandshake* */
|
| }
|
| actual_count++;
|
| @@ -5336,6 +5369,7 @@
|
| rv = ssl3_AppendHandshakeNumber(ss, TLS_FALLBACK_SCSV,
|
| sizeof(ssl3CipherSuite));
|
| if (rv != SECSuccess) {
|
| + if (sid->u.ssl3.lock) { PR_RWLock_Unlock(sid->u.ssl3.lock); }
|
| return rv; /* err set by ssl3_AppendHandshake* */
|
| }
|
| actual_count++;
|
| @@ -5345,6 +5379,7 @@
|
| if (config_match(suite, ss->ssl3.policy, PR_TRUE, &ss->vrange)) {
|
| actual_count++;
|
| if (actual_count > num_suites) {
|
| + if (sid->u.ssl3.lock) { PR_RWLock_Unlock(sid->u.ssl3.lock); }
|
| /* set error card removal/insertion error */
|
| PORT_SetError(SSL_ERROR_TOKEN_INSERTION_REMOVAL);
|
| return SECFailure;
|
| @@ -5352,6 +5387,7 @@
|
| rv = ssl3_AppendHandshakeNumber(ss, suite->cipher_suite,
|
| sizeof(ssl3CipherSuite));
|
| if (rv != SECSuccess) {
|
| + if (sid->u.ssl3.lock) { PR_RWLock_Unlock(sid->u.ssl3.lock); }
|
| return rv; /* err set by ssl3_AppendHandshake* */
|
| }
|
| }
|
| @@ -5362,12 +5398,14 @@
|
| * the server.. */
|
| if (actual_count != num_suites) {
|
| /* Card removal/insertion error */
|
| + if (sid->u.ssl3.lock) { PR_RWLock_Unlock(sid->u.ssl3.lock); }
|
| PORT_SetError(SSL_ERROR_TOKEN_INSERTION_REMOVAL);
|
| return SECFailure;
|
| }
|
|
|
| rv = ssl3_AppendHandshakeNumber(ss, numCompressionMethods, 1);
|
| if (rv != SECSuccess) {
|
| + if (sid->u.ssl3.lock) { PR_RWLock_Unlock(sid->u.ssl3.lock); }
|
| return rv; /* err set by ssl3_AppendHandshake* */
|
| }
|
| for (i = 0; i < compressionMethodsCount; i++) {
|
| @@ -5375,6 +5413,7 @@
|
| continue;
|
| rv = ssl3_AppendHandshakeNumber(ss, compressions[i], 1);
|
| if (rv != SECSuccess) {
|
| + if (sid->u.ssl3.lock) { PR_RWLock_Unlock(sid->u.ssl3.lock); }
|
| return rv; /* err set by ssl3_AppendHandshake* */
|
| }
|
| }
|
| @@ -5385,23 +5424,35 @@
|
|
|
| rv = ssl3_AppendHandshakeNumber(ss, maxBytes, 2);
|
| if (rv != SECSuccess) {
|
| + if (sid->u.ssl3.lock) { PR_RWLock_Unlock(sid->u.ssl3.lock); }
|
| return rv; /* err set by AppendHandshake. */
|
| }
|
|
|
| extLen = ssl3_CallHelloExtensionSenders(ss, PR_TRUE, maxBytes, NULL);
|
| if (extLen < 0) {
|
| + if (sid->u.ssl3.lock) { PR_RWLock_Unlock(sid->u.ssl3.lock); }
|
| return SECFailure;
|
| }
|
| maxBytes -= extLen;
|
|
|
| extLen = ssl3_AppendPaddingExtension(ss, paddingExtensionLen, maxBytes);
|
| if (extLen < 0) {
|
| + if (sid->u.ssl3.lock) { PR_RWLock_Unlock(sid->u.ssl3.lock); }
|
| return SECFailure;
|
| }
|
| maxBytes -= extLen;
|
|
|
| PORT_Assert(!maxBytes);
|
| }
|
| +
|
| + if (sid->u.ssl3.lock) {
|
| + PR_RWLock_Unlock(sid->u.ssl3.lock);
|
| + }
|
| +
|
| + if (ss->xtnData.sentSessionTicketInClientHello) {
|
| + SSL_AtomicIncrementLong(&ssl3stats.sch_sid_stateless_resumes);
|
| + }
|
| +
|
| if (ss->ssl3.hs.sendingSCSV) {
|
| /* Since we sent the SCSV, pretend we sent empty RI extension. */
|
| TLSExtensionData *xtnData = &ss->xtnData;
|
| @@ -6208,14 +6259,10 @@
|
| SSL_GETPID(), ss->fd));
|
|
|
| ssl_GetSpecReadLock(ss);
|
| - /* In TLS 1.2, ssl3_ComputeHandshakeHashes always uses the handshake hash
|
| - * function (SHA-256). If the server or the client does not support SHA-256
|
| - * as a signature hash, we can either maintain a backup SHA-1 handshake
|
| - * hash or buffer all handshake messages.
|
| - */
|
| - if (ss->ssl3.hs.hashType == handshake_hash_single && ss->ssl3.hs.md5) {
|
| + if (ss->ssl3.hs.hashType == handshake_hash_single &&
|
| + ss->ssl3.hs.backupHash) {
|
| rv = ssl3_ComputeBackupHandshakeHashes(ss, &hashes);
|
| - PORT_Assert(ss->ssl3.hs.md5 == NULL);
|
| + PORT_Assert(!ss->ssl3.hs.backupHash);
|
| } else {
|
| rv = ssl3_ComputeHandshakeHashes(ss, ss->ssl3.pwSpec, &hashes, 0);
|
| }
|
| @@ -6611,8 +6658,7 @@
|
| SSL_AtomicIncrementLong(& ssl3stats.hsh_sid_cache_hits );
|
|
|
| /* If we sent a session ticket, then this is a stateless resume. */
|
| - if (sid->version > SSL_LIBRARY_VERSION_3_0 &&
|
| - sid->u.ssl3.sessionTicket.ticket.data != NULL)
|
| + if (ss->xtnData.sentSessionTicketInClientHello)
|
| SSL_AtomicIncrementLong(& ssl3stats.hsh_sid_stateless_resumes );
|
|
|
| if (ssl3_ExtensionNegotiated(ss, ssl_session_ticket_xtn))
|
| @@ -7037,7 +7083,7 @@
|
| *preferSha1 = PR_FALSE;
|
| }
|
|
|
| - done:
|
| +done:
|
| if (pubk)
|
| SECKEY_DestroyPublicKey(pubk);
|
| return rv;
|
| @@ -7059,7 +7105,14 @@
|
| PRBool needBackupHash = PR_FALSE;
|
| unsigned int i;
|
|
|
| - PORT_Assert(ss->ssl3.hs.md5);
|
| +#ifndef NO_PKCS11_BYPASS
|
| + /* Backup handshake hash is not supported in PKCS #11 bypass mode. */
|
| + if (ss->opt.bypassPKCS11) {
|
| + PORT_Assert(!ss->ssl3.hs.backupHash);
|
| + return;
|
| + }
|
| +#endif
|
| + PORT_Assert(ss->ssl3.hs.backupHash);
|
|
|
| /* Determine the key's signature algorithm and whether it prefers SHA-1. */
|
| rv = ssl3_ExtractClientKeyInfo(ss, &sigAlg, &preferSha1);
|
| @@ -7086,8 +7139,8 @@
|
|
|
| done:
|
| if (!needBackupHash) {
|
| - PK11_DestroyContext(ss->ssl3.hs.md5, PR_TRUE);
|
| - ss->ssl3.hs.md5 = NULL;
|
| + PK11_DestroyContext(ss->ssl3.hs.backupHash, PR_TRUE);
|
| + ss->ssl3.hs.backupHash = NULL;
|
| }
|
| }
|
|
|
| @@ -7283,7 +7336,7 @@
|
| }
|
| goto send_no_certificate;
|
| }
|
| - if (isTLS12) {
|
| + if (ss->ssl3.hs.hashType == handshake_hash_single) {
|
| ssl3_DestroyBackupHandshakeHashIfNotNeeded(ss, &algorithms);
|
| }
|
| break; /* not an error */
|
| @@ -7311,17 +7364,13 @@
|
| ss->ssl3.clientCertificate,
|
| certUsageSSLClient, PR_FALSE);
|
| if (ss->ssl3.clientCertChain == NULL) {
|
| - if (ss->ssl3.clientCertificate != NULL) {
|
| - CERT_DestroyCertificate(ss->ssl3.clientCertificate);
|
| - ss->ssl3.clientCertificate = NULL;
|
| - }
|
| - if (ss->ssl3.clientPrivateKey != NULL) {
|
| - SECKEY_DestroyPrivateKey(ss->ssl3.clientPrivateKey);
|
| - ss->ssl3.clientPrivateKey = NULL;
|
| - }
|
| + CERT_DestroyCertificate(ss->ssl3.clientCertificate);
|
| + ss->ssl3.clientCertificate = NULL;
|
| + SECKEY_DestroyPrivateKey(ss->ssl3.clientPrivateKey);
|
| + ss->ssl3.clientPrivateKey = NULL;
|
| goto send_no_certificate;
|
| }
|
| - if (isTLS12) {
|
| + if (ss->ssl3.hs.hashType == handshake_hash_single) {
|
| ssl3_DestroyBackupHandshakeHashIfNotNeeded(ss, &algorithms);
|
| }
|
| break; /* not an error */
|
| @@ -7559,10 +7608,11 @@
|
| ss->ssl3.clientPrivateKey != NULL);
|
|
|
| if (!sendClientCert &&
|
| - ss->ssl3.hs.hashType == handshake_hash_single && ss->ssl3.hs.md5) {
|
| + ss->ssl3.hs.hashType == handshake_hash_single &&
|
| + ss->ssl3.hs.backupHash) {
|
| /* Don't need the backup handshake hash. */
|
| - PK11_DestroyContext(ss->ssl3.hs.md5, PR_TRUE);
|
| - ss->ssl3.hs.md5 = NULL;
|
| + PK11_DestroyContext(ss->ssl3.hs.backupHash, PR_TRUE);
|
| + ss->ssl3.hs.backupHash = NULL;
|
| }
|
|
|
| /* We must wait for the server's certificate to be authenticated before
|
| @@ -8331,7 +8381,7 @@
|
| goto alert_loser;
|
|
|
| suite_found:
|
| - /* Look for a matching compression algorithm. */
|
| + /* Select a compression algorithm. */
|
| for (i = 0; i < comps.len; i++) {
|
| if (!compressionEnabled(ss, comps.data[i]))
|
| continue;
|
| @@ -9773,8 +9823,8 @@
|
| SECStatus
|
| ssl3_HandleNewSessionTicket(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
|
| {
|
| - SECStatus rv;
|
| - NewSessionTicket session_ticket;
|
| + SECStatus rv;
|
| + SECItem ticketData;
|
|
|
| SSL_TRC(3, ("%d: SSL3[%d]: handle session_ticket handshake",
|
| SSL_GETPID(), ss->fd));
|
| @@ -9782,35 +9832,41 @@
|
| PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
|
| PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
|
|
|
| + PORT_Assert(!ss->ssl3.hs.newSessionTicket.ticket.data);
|
| + PORT_Assert(!ss->ssl3.hs.receivedNewSessionTicket);
|
| +
|
| if (ss->ssl3.hs.ws != wait_new_session_ticket) {
|
| SSL3_SendAlert(ss, alert_fatal, unexpected_message);
|
| PORT_SetError(SSL_ERROR_RX_UNEXPECTED_NEW_SESSION_TICKET);
|
| return SECFailure;
|
| }
|
|
|
| - session_ticket.received_timestamp = ssl_Time();
|
| + /* RFC5077 Section 3.3: "The client MUST NOT treat the ticket as valid
|
| + * until it has verified the server's Finished message." See the comment in
|
| + * ssl3_FinishHandshake for more details.
|
| + */
|
| + ss->ssl3.hs.newSessionTicket.received_timestamp = ssl_Time();
|
| if (length < 4) {
|
| (void)SSL3_SendAlert(ss, alert_fatal, decode_error);
|
| PORT_SetError(SSL_ERROR_RX_MALFORMED_NEW_SESSION_TICKET);
|
| return SECFailure;
|
| }
|
| - session_ticket.ticket_lifetime_hint =
|
| + ss->ssl3.hs.newSessionTicket.ticket_lifetime_hint =
|
| (PRUint32)ssl3_ConsumeHandshakeNumber(ss, 4, &b, &length);
|
|
|
| - rv = ssl3_ConsumeHandshakeVariable(ss, &session_ticket.ticket, 2,
|
| - &b, &length);
|
| + rv = ssl3_ConsumeHandshakeVariable(ss, &ticketData, 2, &b, &length);
|
| if (length != 0 || rv != SECSuccess) {
|
| (void)SSL3_SendAlert(ss, alert_fatal, decode_error);
|
| PORT_SetError(SSL_ERROR_RX_MALFORMED_NEW_SESSION_TICKET);
|
| return SECFailure; /* malformed */
|
| }
|
| -
|
| - rv = ssl3_SetSIDSessionTicket(ss->sec.ci.sid, &session_ticket);
|
| + rv = SECITEM_CopyItem(NULL, &ss->ssl3.hs.newSessionTicket.ticket,
|
| + &ticketData);
|
| if (rv != SECSuccess) {
|
| - (void)SSL3_SendAlert(ss, alert_fatal, handshake_failure);
|
| - PORT_SetError(SSL_ERROR_INTERNAL_ERROR_ALERT);
|
| - return SECFailure;
|
| + return rv;
|
| }
|
| + ss->ssl3.hs.receivedNewSessionTicket = PR_TRUE;
|
| +
|
| ss->ssl3.hs.ws = wait_change_cipher;
|
| return SECSuccess;
|
| }
|
| @@ -10501,14 +10557,11 @@
|
| SSL_TRC(3, ("%d: SSL3[%p]: certificate authentication won the race with"
|
| " peer's finished message", SSL_GETPID(), ss->fd));
|
|
|
| - PORT_Assert(!ss->firstHsDone);
|
| - PORT_Assert(!ss->sec.isServer);
|
| PORT_Assert(!ss->ssl3.hs.isResuming);
|
| PORT_Assert(ss->ssl3.hs.ws != idle_handshake);
|
|
|
| if (ss->opt.enableFalseStart &&
|
| !ss->firstHsDone &&
|
| - !ss->sec.isServer &&
|
| !ss->ssl3.hs.isResuming &&
|
| ssl3_WaitingForStartOfServerSecondRound(ss)) {
|
| /* ssl3_SendClientSecondRound deferred the false start check because
|
| @@ -10607,7 +10660,8 @@
|
| return rv;
|
| }
|
|
|
| -/* called from ssl3_HandleServerHelloDone
|
| +/* called from ssl3_SendClientSecondRound
|
| + * ssl3_HandleFinished
|
| */
|
| static SECStatus
|
| ssl3_SendNextProto(sslSocket *ss)
|
| @@ -10880,7 +10934,7 @@
|
| return SECSuccess;
|
| }
|
|
|
| -/* called from ssl3_HandleServerHelloDone
|
| +/* called from ssl3_SendClientSecondRound
|
| * ssl3_HandleClientHello
|
| * ssl3_HandleFinished
|
| */
|
| @@ -11116,6 +11170,11 @@
|
| */
|
| if (isServer && !ss->ssl3.hs.isResuming &&
|
| ssl3_ExtensionNegotiated(ss, ssl_session_ticket_xtn)) {
|
| + /* RFC 5077 Section 3.3: "In the case of a full handshake, the
|
| + * server MUST verify the client's Finished message before sending
|
| + * the ticket." Presumably, this also means that the client's
|
| + * certificate, if any, must be verified beforehand too.
|
| + */
|
| rv = ssl3_SendNewSessionTicket(ss);
|
| if (rv != SECSuccess) {
|
| goto xmit_loser;
|
| @@ -11240,7 +11299,27 @@
|
| /* The first handshake is now completed. */
|
| ss->handshake = NULL;
|
|
|
| + /* RFC 5077 Section 3.3: "The client MUST NOT treat the ticket as valid
|
| + * until it has verified the server's Finished message." When the server
|
| + * sends a NewSessionTicket in a resumption handshake, we must wait until
|
| + * the handshake is finished (we have verified the server's Finished
|
| + * AND the server's certificate) before we update the ticket in the sid.
|
| + *
|
| + * This must be done before we call (*ss->sec.cache)(ss->sec.ci.sid)
|
| + * because CacheSID requires the session ticket to already be set, and also
|
| + * because of the lazy lock creation scheme used by CacheSID and
|
| + * ssl3_SetSIDSessionTicket.
|
| + */
|
| + if (ss->ssl3.hs.receivedNewSessionTicket) {
|
| + PORT_Assert(!ss->sec.isServer);
|
| + ssl3_SetSIDSessionTicket(ss->sec.ci.sid, &ss->ssl3.hs.newSessionTicket);
|
| + /* The sid took over the ticket data */
|
| + PORT_Assert(!ss->ssl3.hs.newSessionTicket.ticket.data);
|
| + ss->ssl3.hs.receivedNewSessionTicket = PR_FALSE;
|
| + }
|
| +
|
| if (ss->ssl3.hs.cacheSID && ss->sec.isServer) {
|
| + PORT_Assert(ss->sec.ci.sid->cached == never_cached);
|
| (*ss->sec.cache)(ss->sec.ci.sid);
|
| ss->ssl3.hs.cacheSID = PR_FALSE;
|
| }
|
| @@ -12311,6 +12390,10 @@
|
| ss->ssl3.hs.messages.buf = NULL;
|
| ss->ssl3.hs.messages.space = 0;
|
|
|
| + ss->ssl3.hs.receivedNewSessionTicket = PR_FALSE;
|
| + PORT_Memset(&ss->ssl3.hs.newSessionTicket, 0,
|
| + sizeof(ss->ssl3.hs.newSessionTicket));
|
| +
|
| ss->ssl3.initialized = PR_TRUE;
|
| return SECSuccess;
|
| }
|
| @@ -12745,6 +12828,8 @@
|
| /* free the SSL3Buffer (msg_body) */
|
| PORT_Free(ss->ssl3.hs.msg_body.buf);
|
|
|
| + SECITEM_FreeItem(&ss->ssl3.hs.newSessionTicket.ticket, PR_FALSE);
|
| +
|
| /* free up the CipherSpecs */
|
| ssl3_DestroyCipherSpec(&ss->ssl3.specs[0], PR_TRUE/*freeSrvName*/);
|
| ssl3_DestroyCipherSpec(&ss->ssl3.specs[1], PR_TRUE/*freeSrvName*/);
|
|
|