Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(308)

Unified Diff: net/third_party/nss/ssl/ssl3con.c

Issue 111853013: Update net/third_party/nss to NSS 3.15.4. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Update the comment in sslenum.c for the two CHACHA20 cipher suites Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « net/third_party/nss/ssl/ssl.h ('k') | net/third_party/nss/ssl/ssl3ecc.c » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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, &param);
- 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, &param, &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*/);
« no previous file with comments | « net/third_party/nss/ssl/ssl.h ('k') | net/third_party/nss/ssl/ssl3ecc.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698