diff options
-rw-r--r-- | net/socket/ssl_client_socket_nss.cc | 6 | ||||
-rw-r--r-- | net/third_party/nss/README.google | 3 | ||||
-rw-r--r-- | net/third_party/nss/nss.gyp | 7 | ||||
-rw-r--r-- | net/third_party/nss/patches/falsestart.patch | 319 | ||||
-rw-r--r-- | net/third_party/nss/ssl/ssl.h | 11 | ||||
-rw-r--r-- | net/third_party/nss/ssl/ssl3con.c | 20 | ||||
-rw-r--r-- | net/third_party/nss/ssl/ssl3gthr.c | 13 | ||||
-rw-r--r-- | net/third_party/nss/ssl/sslimpl.h | 3 | ||||
-rw-r--r-- | net/third_party/nss/ssl/sslsecur.c | 6 | ||||
-rw-r--r-- | net/third_party/nss/ssl/sslsock.c | 11 |
10 files changed, 396 insertions, 3 deletions
diff --git a/net/socket/ssl_client_socket_nss.cc b/net/socket/ssl_client_socket_nss.cc index 311b054..da7f90a 100644 --- a/net/socket/ssl_client_socket_nss.cc +++ b/net/socket/ssl_client_socket_nss.cc @@ -380,6 +380,12 @@ int SSLClientSocketNSS::InitializeSSLOptions() { LOG(INFO) << "SSL_ENABLE_DEFLATE failed. Old system nss?"; #endif +#ifdef SSL_ENABLE_FALSE_START + rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_FALSE_START, PR_TRUE); + if (rv != SECSuccess) + LOG(INFO) << "SSL_ENABLE_FALSE_START failed. Old system nss?"; +#endif + #ifdef SSL_ENABLE_RENEGOTIATION // We allow servers to request renegotiation. Since we're a client, // prohibiting this is rather a waste of time. Only servers are in a position diff --git a/net/third_party/nss/README.google b/net/third_party/nss/README.google index ce46e1a..291e176 100644 --- a/net/third_party/nss/README.google +++ b/net/third_party/nss/README.google @@ -9,6 +9,9 @@ Patches: patches/nextproto.patch http://codereview.chromium.org/415005 + * False start support + patches/falsestart.patch + * Commenting out a couple of functions because they need NSS symbols which may not exist in the system NSS library. patches/versionskew.patch diff --git a/net/third_party/nss/nss.gyp b/net/third_party/nss/nss.gyp index 5511066..1e7ef49 100644 --- a/net/third_party/nss/nss.gyp +++ b/net/third_party/nss/nss.gyp @@ -126,6 +126,13 @@ }, }], ], + 'configurations': { + 'Debug_Base': { + 'defines': [ + 'DEBUG', + ], + }, + }, }, ], } diff --git a/net/third_party/nss/patches/falsestart.patch b/net/third_party/nss/patches/falsestart.patch new file mode 100644 index 0000000..ad41b20e --- /dev/null +++ b/net/third_party/nss/patches/falsestart.patch @@ -0,0 +1,319 @@ +diff --git a/mozilla/security/nss/cmd/strsclnt/strsclnt.c b/mozilla/security/nss/cmd/strsclnt/strsclnt.c +index c266644..1f71434 100644 +--- a/mozilla/security/nss/cmd/strsclnt/strsclnt.c ++++ b/mozilla/security/nss/cmd/strsclnt/strsclnt.c +@@ -162,6 +162,7 @@ static PRBool disableLocking = PR_FALSE; + static PRBool ignoreErrors = PR_FALSE; + static PRBool enableSessionTickets = PR_FALSE; + static PRBool enableCompression = PR_FALSE; ++static PRBool enableFalseStart = PR_FALSE; + + PRIntervalTime maxInterval = PR_INTERVAL_NO_TIMEOUT; + +@@ -197,7 +198,8 @@ Usage(const char *progName) + " -U means enable throttling up threads\n" + " -B bypasses the PKCS11 layer for SSL encryption and MACing\n" + " -u enable TLS Session Ticket extension\n" +- " -z enable compression\n", ++ " -z enable compression\n" ++ " -g enable false start\n", + progName); + exit(1); + } +@@ -1244,6 +1246,12 @@ client_main( + errExit("SSL_OptionSet SSL_ENABLE_DEFLATE"); + } + ++ if (enableFalseStart) { ++ rv = SSL_OptionSet(model_sock, SSL_ENABLE_FALSE_START, PR_TRUE); ++ if (rv != SECSuccess) ++ errExit("SSL_OptionSet SSL_ENABLE_FALSE_START"); ++ } ++ + SSL_SetURL(model_sock, hostName); + + SSL_AuthCertificateHook(model_sock, mySSLAuthCertificate, +@@ -1354,7 +1362,7 @@ main(int argc, char **argv) + + + optstate = PL_CreateOptState(argc, argv, +- "23BC:DNP:TUW:a:c:d:f:in:op:qst:uvw:z"); ++ "23BC:DNP:TUW:a:c:d:f:gin:op:qst:uvw:z"); + while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) { + switch(optstate->option) { + +@@ -1384,6 +1392,8 @@ main(int argc, char **argv) + + case 'f': fileName = optstate->value; break; + ++ case 'g': enableFalseStart = PR_TRUE; break; ++ + case 'i': ignoreErrors = PR_TRUE; break; + + case 'n': nickName = PL_strdup(optstate->value); break; +diff --git a/mozilla/security/nss/cmd/tstclnt/tstclnt.c b/mozilla/security/nss/cmd/tstclnt/tstclnt.c +index c15a0ad..55684e6 100644 +--- a/mozilla/security/nss/cmd/tstclnt/tstclnt.c ++++ b/mozilla/security/nss/cmd/tstclnt/tstclnt.c +@@ -225,6 +225,7 @@ static void Usage(const char *progName) + fprintf(stderr, "%-20s Renegotiate N times (resuming session if N>1).\n", "-r N"); + fprintf(stderr, "%-20s Enable the session ticket extension.\n", "-u"); + fprintf(stderr, "%-20s Enable compression.\n", "-z"); ++ fprintf(stderr, "%-20s Enable false start.\n", "-g"); + fprintf(stderr, "%-20s Letter(s) chosen from the following list\n", + "-c ciphers"); + fprintf(stderr, +@@ -521,6 +522,7 @@ int main(int argc, char **argv) + int useExportPolicy = 0; + int enableSessionTickets = 0; + int enableCompression = 0; ++ int enableFalseStart = 0; + PRSocketOptionData opt; + PRNetAddr addr; + PRPollDesc pollset[2]; +@@ -551,7 +553,7 @@ int main(int argc, char **argv) + } + + optstate = PL_CreateOptState(argc, argv, +- "23BSTW:a:c:d:fh:m:n:op:qr:suvw:xz"); ++ "23BSTW:a:c:d:fgh:m:n:op:qr:suvw:xz"); + while ((optstatus = PL_GetNextOpt(optstate)) == PL_OPT_OK) { + switch (optstate->option) { + case '?': +@@ -578,6 +580,8 @@ int main(int argc, char **argv) + + case 'c': cipherString = PORT_Strdup(optstate->value); break; + ++ case 'g': enableFalseStart = 1; break; ++ + case 'd': certDir = PORT_Strdup(optstate->value); break; + + case 'f': clientSpeaksFirst = PR_TRUE; break; +@@ -863,7 +867,14 @@ int main(int argc, char **argv) + SECU_PrintError(progName, "error enabling compression"); + return 1; + } +- ++ ++ /* enable false start. */ ++ rv = SSL_OptionSet(s, SSL_ENABLE_FALSE_START, enableFalseStart); ++ if (rv != SECSuccess) { ++ SECU_PrintError(progName, "error enabling false start"); ++ return 1; ++ } ++ + SSL_SetPKCS11PinArg(s, &pwdata); + + SSL_AuthCertificateHook(s, SSL_AuthCertificate, (void *)handle); +diff --git a/mozilla/security/nss/lib/ssl/ssl.h b/mozilla/security/nss/lib/ssl/ssl.h +index e285ab4..bd1bfd3 100644 +--- a/mozilla/security/nss/lib/ssl/ssl.h ++++ b/mozilla/security/nss/lib/ssl/ssl.h +@@ -128,6 +128,17 @@ SSL_IMPORT PRFileDesc *SSL_ImportFD(PRFileDesc *model, PRFileDesc *fd); + /* Renegotiation Info (RI) */ + /* extension in ALL handshakes. */ + /* default: off */ ++#define SSL_ENABLE_FALSE_START 22 /* Enable SSL false start (off by */ ++ /* default, applies only to */ ++ /* clients). False start is a */ ++/* mode where an SSL client will start sending application data before */ ++/* verifying the server's Finished message. This means that we could end up */ ++/* sending data to an imposter. However, the data will be encrypted and */ ++/* only the true server can derive the session key. Thus, so long as the */ ++/* cipher isn't broken this is safe. Because of this, False Start will only */ ++/* occur on RSA or DH ciphersuites where the cipher's key length is >= 80 */ ++/* bits. The advantage of False Start is that it saves a round trip for */ ++/* client-speaks-first protocols when performing a full handshake. */ + + #ifdef SSL_DEPRECATED_FUNCTION + /* Old deprecated function names */ +diff --git a/mozilla/security/nss/lib/ssl/ssl3con.c b/mozilla/security/nss/lib/ssl/ssl3con.c +index 6b37c4f..f073431 100644 +--- a/mozilla/security/nss/lib/ssl/ssl3con.c ++++ b/mozilla/security/nss/lib/ssl/ssl3con.c +@@ -5656,7 +5656,17 @@ ssl3_RestartHandshakeAfterCertReq(sslSocket * ss, + return rv; + } + +- ++PRBool ++ssl3_CanFalseStart(sslSocket *ss) { ++ return ss->opt.enableFalseStart && ++ !ss->sec.isServer && ++ !ss->ssl3.hs.isResuming && ++ ss->ssl3.cwSpec && ++ ss->ssl3.cwSpec->cipher_def->secret_key_size >= 10 && ++ (ss->ssl3.hs.kea_def->exchKeyType == ssl_kea_rsa || ++ ss->ssl3.hs.kea_def->exchKeyType == ssl_kea_dh || ++ ss->ssl3.hs.kea_def->exchKeyType == ssl_kea_ecdh); ++} + + /* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete + * ssl3 Server Hello Done message. +@@ -5728,6 +5738,12 @@ ssl3_HandleServerHelloDone(sslSocket *ss) + ss->ssl3.hs.ws = wait_new_session_ticket; + else + ss->ssl3.hs.ws = wait_change_cipher; ++ ++ /* Do the handshake callback for sslv3 here. */ ++ if (ss->handshakeCallback != NULL && ssl3_CanFalseStart(ss)) { ++ (ss->handshakeCallback)(ss->fd, ss->handshakeCallbackData); ++ } ++ + return SECSuccess; + + loser: +@@ -8468,7 +8484,7 @@ xmit_loser: + ss->ssl3.hs.ws = idle_handshake; + + /* Do the handshake callback for sslv3 here. */ +- if (ss->handshakeCallback != NULL) { ++ if (ss->handshakeCallback != NULL && !ssl3_CanFalseStart(ss)) { + (ss->handshakeCallback)(ss->fd, ss->handshakeCallbackData); + } + +diff --git a/mozilla/security/nss/lib/ssl/ssl3gthr.c b/mozilla/security/nss/lib/ssl/ssl3gthr.c +index bdd2958..28fe154 100644 +--- a/mozilla/security/nss/lib/ssl/ssl3gthr.c ++++ b/mozilla/security/nss/lib/ssl/ssl3gthr.c +@@ -188,6 +188,7 @@ ssl3_GatherCompleteHandshake(sslSocket *ss, int flags) + { + SSL3Ciphertext cText; + int rv; ++ PRBool canFalseStart = PR_FALSE; + + PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) ); + do { +@@ -207,7 +208,17 @@ ssl3_GatherCompleteHandshake(sslSocket *ss, int flags) + if (rv < 0) { + return ss->recvdCloseNotify ? 0 : rv; + } +- } while (ss->ssl3.hs.ws != idle_handshake && ss->gs.buf.len == 0); ++ ++ if (ss->opt.enableFalseStart) { ++ ssl_GetSSL3HandshakeLock(ss); ++ canFalseStart = (ss->ssl3.hs.ws == wait_change_cipher || ++ ss->ssl3.hs.ws == wait_new_session_ticket) && ++ ssl3_CanFalseStart(ss); ++ ssl_ReleaseSSL3HandshakeLock(ss); ++ } ++ } while (ss->ssl3.hs.ws != idle_handshake && ++ !canFalseStart && ++ ss->gs.buf.len == 0); + + ss->gs.readOffset = 0; + ss->gs.writeOffset = ss->gs.buf.len; +diff --git a/mozilla/security/nss/lib/ssl/sslimpl.h b/mozilla/security/nss/lib/ssl/sslimpl.h +index 7581b98..00f0ce2 100644 +--- a/mozilla/security/nss/lib/ssl/sslimpl.h ++++ b/mozilla/security/nss/lib/ssl/sslimpl.h +@@ -333,6 +333,7 @@ typedef struct sslOptionsStr { + unsigned int enableDeflate : 1; /* 19 */ + unsigned int enableRenegotiation : 2; /* 20-21 */ + unsigned int requireSafeNegotiation : 1; /* 22 */ ++ unsigned int enableFalseStart : 1; /* 23 */ + } sslOptions; + + typedef enum { sslHandshakingUndetermined = 0, +@@ -1250,6 +1251,8 @@ extern void ssl_SetAlwaysBlock(sslSocket *ss); + + extern SECStatus ssl_EnableNagleDelay(sslSocket *ss, PRBool enabled); + ++extern PRBool ssl3_CanFalseStart(sslSocket *ss); ++ + #define SSL_LOCK_READER(ss) if (ss->recvLock) PZ_Lock(ss->recvLock) + #define SSL_UNLOCK_READER(ss) if (ss->recvLock) PZ_Unlock(ss->recvLock) + #define SSL_LOCK_WRITER(ss) if (ss->sendLock) PZ_Lock(ss->sendLock) +diff --git a/mozilla/security/nss/lib/ssl/sslsecur.c b/mozilla/security/nss/lib/ssl/sslsecur.c +index 8f79135..4dc0475 100644 +--- a/mozilla/security/nss/lib/ssl/sslsecur.c ++++ b/mozilla/security/nss/lib/ssl/sslsecur.c +@@ -148,6 +148,12 @@ ssl_Do1stHandshake(sslSocket *ss) + ss->gs.readOffset = 0; + break; + } ++ if (ss->version >= SSL_LIBRARY_VERSION_3_0 && ++ (ss->ssl3.hs.ws == wait_change_cipher || ++ ss->ssl3.hs.ws == wait_new_session_ticket) && ++ ssl3_CanFalseStart(ss)) { ++ break; ++ } + rv = (*ss->handshake)(ss); + ++loopCount; + /* This code must continue to loop on SECWouldBlock, +diff --git a/mozilla/security/nss/lib/ssl/sslsock.c b/mozilla/security/nss/lib/ssl/sslsock.c +index aab48d6..40f633a 100644 +--- a/mozilla/security/nss/lib/ssl/sslsock.c ++++ b/mozilla/security/nss/lib/ssl/sslsock.c +@@ -183,6 +183,7 @@ static sslOptions ssl_defaults = { + PR_FALSE, /* enableDeflate */ + 2, /* enableRenegotiation (default: requires extension) */ + PR_FALSE, /* requireSafeNegotiation */ ++ PR_FALSE, /* enableFalseStart */ + }; + + sslSessionIDLookupFunc ssl_sid_lookup; +@@ -728,6 +729,10 @@ SSL_OptionSet(PRFileDesc *fd, PRInt32 which, PRBool on) + ss->opt.requireSafeNegotiation = on; + break; + ++ case SSL_ENABLE_FALSE_START: ++ ss->opt.enableFalseStart = on; ++ break; ++ + default: + PORT_SetError(SEC_ERROR_INVALID_ARGS); + rv = SECFailure; +@@ -791,6 +796,7 @@ SSL_OptionGet(PRFileDesc *fd, PRInt32 which, PRBool *pOn) + on = ss->opt.enableRenegotiation; break; + case SSL_REQUIRE_SAFE_NEGOTIATION: + on = ss->opt.requireSafeNegotiation; break; ++ case SSL_ENABLE_FALSE_START: on = ss->opt.enableFalseStart; break; + + default: + PORT_SetError(SEC_ERROR_INVALID_ARGS); +@@ -841,6 +847,7 @@ SSL_OptionGetDefault(PRInt32 which, PRBool *pOn) + case SSL_REQUIRE_SAFE_NEGOTIATION: + on = ssl_defaults.requireSafeNegotiation; + break; ++ case SSL_ENABLE_FALSE_START: on = ssl_defaults.enableFalseStart; break; + + default: + PORT_SetError(SEC_ERROR_INVALID_ARGS); +@@ -984,6 +991,10 @@ SSL_OptionSetDefault(PRInt32 which, PRBool on) + ssl_defaults.requireSafeNegotiation = on; + break; + ++ case SSL_ENABLE_FALSE_START: ++ ssl_defaults.enableFalseStart = on; ++ break; ++ + default: + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; +diff --git a/mozilla/security/nss/tests/ssl/sslstress.txt b/mozilla/security/nss/tests/ssl/sslstress.txt +index 9a3aae8..c2a5c76 100644 +--- a/mozilla/security/nss/tests/ssl/sslstress.txt ++++ b/mozilla/security/nss/tests/ssl/sslstress.txt +@@ -42,9 +42,11 @@ + noECC 0 _ -c_1000_-C_A Stress SSL2 RC4 128 with MD5 + noECC 0 _ -c_1000_-C_c_-T Stress SSL3 RC4 128 with MD5 + noECC 0 _ -c_1000_-C_c Stress TLS RC4 128 with MD5 ++ noECC 0 _ -c_1000_-C_c_-h Stress TLS RC4 128 with MD5 (false start) + noECC 0 -u -2_-c_1000_-C_c_-u Stress TLS RC4 128 with MD5 (session ticket) + noECC 0 -z -2_-c_1000_-C_c_-z Stress TLS RC4 128 with MD5 (compression) + noECC 0 -u_-z -2_-c_1000_-C_c_-u_-z Stress TLS RC4 128 with MD5 (session ticket, compression) ++ noECC 0 -u_-z -2_-c_1000_-C_c_-u_-z_-h Stress TLS RC4 128 with MD5 (session ticket, compression, false start) + SNI 0 -u_-a_Host-sni.Dom -2_-3_-c_1000_-C_c_-u Stress TLS RC4 128 with MD5 (session ticket, SNI) + + # +@@ -55,7 +57,9 @@ + noECC 0 -r_-r -c_100_-C_c_-N_-n_TestUser Stress TLS RC4 128 with MD5 (no reuse, client auth) + noECC 0 -r_-r_-u -2_-c_100_-C_c_-n_TestUser_-u Stress TLS RC4 128 with MD5 (session ticket, client auth) + noECC 0 -r_-r_-z -2_-c_100_-C_c_-n_TestUser_-z Stress TLS RC4 128 with MD5 (compression, client auth) ++ noECC 0 -r_-r_-z -2_-c_100_-C_c_-n_TestUser_-z_-h Stress TLS RC4 128 with MD5 (compression, client auth, false start) + noECC 0 -r_-r_-u_-z -2_-c_100_-C_c_-n_TestUser_-u_-z Stress TLS RC4 128 with MD5 (session ticket, compression, client auth) ++ noECC 0 -r_-r_-u_-z -2_-c_100_-C_c_-n_TestUser_-u_-z_-h Stress TLS RC4 128 with MD5 (session ticket, compression, client auth, false start) + SNI 0 -r_-r_-u_-a_Host-sni.Dom -2_-3_-c_1000_-C_c_-u Stress TLS RC4 128 with MD5 (session ticket, SNI, client auth, default virt host) + SNI 0 -r_-r_-u_-a_Host-sni.Dom_-k_Host-sni.Dom -2_-3_-c_1000_-C_c_-u_-a_Host-sni.Dom Stress TLS RC4 128 with MD5 (session ticket, SNI, client auth, change virt host) + diff --git a/net/third_party/nss/ssl/ssl.h b/net/third_party/nss/ssl/ssl.h index b0e77df..0bc02f8 100644 --- a/net/third_party/nss/ssl/ssl.h +++ b/net/third_party/nss/ssl/ssl.h @@ -128,6 +128,17 @@ SSL_IMPORT PRFileDesc *SSL_ImportFD(PRFileDesc *model, PRFileDesc *fd); /* Renegotiation Info (RI) */ /* extension in ALL handshakes. */ /* default: off */ +#define SSL_ENABLE_FALSE_START 22 /* Enable SSL false start (off by */ + /* default, applies only to */ + /* clients). False start is a */ +/* mode where an SSL client will start sending application data before */ +/* verifying the server's Finished message. This means that we could end up */ +/* sending data to an imposter. However, the data will be encrypted and */ +/* only the true server can derive the session key. Thus, so long as the */ +/* cipher isn't broken this is safe. Because of this, False Start will only */ +/* occur on RSA or DH ciphersuites where the cipher's key length is >= 80 */ +/* bits. The advantage of False Start is that it saves a round trip for */ +/* client-speaks-first protocols when performing a full handshake. */ #ifdef SSL_DEPRECATED_FUNCTION /* Old deprecated function names */ diff --git a/net/third_party/nss/ssl/ssl3con.c b/net/third_party/nss/ssl/ssl3con.c index 545e51e..24dc01c 100644 --- a/net/third_party/nss/ssl/ssl3con.c +++ b/net/third_party/nss/ssl/ssl3con.c @@ -5657,7 +5657,17 @@ ssl3_RestartHandshakeAfterCertReq(sslSocket * ss, return rv; } - +PRBool +ssl3_CanFalseStart(sslSocket *ss) { + return ss->opt.enableFalseStart && + !ss->sec.isServer && + !ss->ssl3.hs.isResuming && + ss->ssl3.cwSpec && + ss->ssl3.cwSpec->cipher_def->secret_key_size >= 10 && + (ss->ssl3.hs.kea_def->exchKeyType == ssl_kea_rsa || + ss->ssl3.hs.kea_def->exchKeyType == ssl_kea_dh || + ss->ssl3.hs.kea_def->exchKeyType == ssl_kea_ecdh); +} /* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete * ssl3 Server Hello Done message. @@ -5735,6 +5745,12 @@ ssl3_HandleServerHelloDone(sslSocket *ss) ss->ssl3.hs.ws = wait_new_session_ticket; else ss->ssl3.hs.ws = wait_change_cipher; + + /* Do the handshake callback for sslv3 here. */ + if (ss->handshakeCallback != NULL && ssl3_CanFalseStart(ss)) { + (ss->handshakeCallback)(ss->fd, ss->handshakeCallbackData); + } + return SECSuccess; loser: @@ -8509,7 +8525,7 @@ xmit_loser: ss->ssl3.hs.ws = idle_handshake; /* Do the handshake callback for sslv3 here. */ - if (ss->handshakeCallback != NULL) { + if (ss->handshakeCallback != NULL && !ssl3_CanFalseStart(ss)) { (ss->handshakeCallback)(ss->fd, ss->handshakeCallbackData); } diff --git a/net/third_party/nss/ssl/ssl3gthr.c b/net/third_party/nss/ssl/ssl3gthr.c index bdd2958..28fe154 100644 --- a/net/third_party/nss/ssl/ssl3gthr.c +++ b/net/third_party/nss/ssl/ssl3gthr.c @@ -188,6 +188,7 @@ ssl3_GatherCompleteHandshake(sslSocket *ss, int flags) { SSL3Ciphertext cText; int rv; + PRBool canFalseStart = PR_FALSE; PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) ); do { @@ -207,7 +208,17 @@ ssl3_GatherCompleteHandshake(sslSocket *ss, int flags) if (rv < 0) { return ss->recvdCloseNotify ? 0 : rv; } - } while (ss->ssl3.hs.ws != idle_handshake && ss->gs.buf.len == 0); + + if (ss->opt.enableFalseStart) { + ssl_GetSSL3HandshakeLock(ss); + canFalseStart = (ss->ssl3.hs.ws == wait_change_cipher || + ss->ssl3.hs.ws == wait_new_session_ticket) && + ssl3_CanFalseStart(ss); + ssl_ReleaseSSL3HandshakeLock(ss); + } + } while (ss->ssl3.hs.ws != idle_handshake && + !canFalseStart && + ss->gs.buf.len == 0); ss->gs.readOffset = 0; ss->gs.writeOffset = ss->gs.buf.len; diff --git a/net/third_party/nss/ssl/sslimpl.h b/net/third_party/nss/ssl/sslimpl.h index 0658d2c..a800d56 100644 --- a/net/third_party/nss/ssl/sslimpl.h +++ b/net/third_party/nss/ssl/sslimpl.h @@ -338,6 +338,7 @@ typedef struct sslOptionsStr { unsigned int enableDeflate : 1; /* 19 */ unsigned int enableRenegotiation : 2; /* 20-21 */ unsigned int requireSafeNegotiation : 1; /* 22 */ + unsigned int enableFalseStart : 1; /* 23 */ } sslOptions; typedef enum { sslHandshakingUndetermined = 0, @@ -1266,6 +1267,8 @@ extern void ssl_SetAlwaysBlock(sslSocket *ss); extern SECStatus ssl_EnableNagleDelay(sslSocket *ss, PRBool enabled); +extern PRBool ssl3_CanFalseStart(sslSocket *ss); + #define SSL_LOCK_READER(ss) if (ss->recvLock) PZ_Lock(ss->recvLock) #define SSL_UNLOCK_READER(ss) if (ss->recvLock) PZ_Unlock(ss->recvLock) #define SSL_LOCK_WRITER(ss) if (ss->sendLock) PZ_Lock(ss->sendLock) diff --git a/net/third_party/nss/ssl/sslsecur.c b/net/third_party/nss/ssl/sslsecur.c index 80c2ba6..a8184478 100644 --- a/net/third_party/nss/ssl/sslsecur.c +++ b/net/third_party/nss/ssl/sslsecur.c @@ -148,6 +148,12 @@ ssl_Do1stHandshake(sslSocket *ss) ss->gs.readOffset = 0; break; } + if (ss->version >= SSL_LIBRARY_VERSION_3_0 && + (ss->ssl3.hs.ws == wait_change_cipher || + ss->ssl3.hs.ws == wait_new_session_ticket) && + ssl3_CanFalseStart(ss)) { + break; + } rv = (*ss->handshake)(ss); ++loopCount; /* This code must continue to loop on SECWouldBlock, diff --git a/net/third_party/nss/ssl/sslsock.c b/net/third_party/nss/ssl/sslsock.c index 722fe60..c4611a0 100644 --- a/net/third_party/nss/ssl/sslsock.c +++ b/net/third_party/nss/ssl/sslsock.c @@ -184,6 +184,7 @@ static sslOptions ssl_defaults = { PR_FALSE, /* enableDeflate */ 2, /* enableRenegotiation (default: requires extension) */ PR_FALSE, /* requireSafeNegotiation */ + PR_FALSE, /* enableFalseStart */ }; sslSessionIDLookupFunc ssl_sid_lookup; @@ -733,6 +734,10 @@ SSL_OptionSet(PRFileDesc *fd, PRInt32 which, PRBool on) ss->opt.requireSafeNegotiation = on; break; + case SSL_ENABLE_FALSE_START: + ss->opt.enableFalseStart = on; + break; + default: PORT_SetError(SEC_ERROR_INVALID_ARGS); rv = SECFailure; @@ -796,6 +801,7 @@ SSL_OptionGet(PRFileDesc *fd, PRInt32 which, PRBool *pOn) on = ss->opt.enableRenegotiation; break; case SSL_REQUIRE_SAFE_NEGOTIATION: on = ss->opt.requireSafeNegotiation; break; + case SSL_ENABLE_FALSE_START: on = ss->opt.enableFalseStart; break; default: PORT_SetError(SEC_ERROR_INVALID_ARGS); @@ -846,6 +852,7 @@ SSL_OptionGetDefault(PRInt32 which, PRBool *pOn) case SSL_REQUIRE_SAFE_NEGOTIATION: on = ssl_defaults.requireSafeNegotiation; break; + case SSL_ENABLE_FALSE_START: on = ssl_defaults.enableFalseStart; break; default: PORT_SetError(SEC_ERROR_INVALID_ARGS); @@ -989,6 +996,10 @@ SSL_OptionSetDefault(PRInt32 which, PRBool on) ssl_defaults.requireSafeNegotiation = on; break; + case SSL_ENABLE_FALSE_START: + ssl_defaults.enableFalseStart = on; + break; + default: PORT_SetError(SEC_ERROR_INVALID_ARGS); return SECFailure; |