@@ -0,0 +1,572 @@
+diff -r 05ffc38de8b4 nss/lib/ssl/ssl.def
+--- a/nss/lib/ssl/ssl.def Thu Jun 27 19:58:08 2013 +0200
++++ b/nss/lib/ssl/ssl.def Tue Jul 23 15:26:39 2013 +0300
+@@ -163,3 +163,10 @@
+ ;+ local:
+ ;+*;
+ ;+};
++;+NSS_3.15.2 { # NSS 3.15.2 release
++;+ global:
++SSL_SetCanFalseStartCallback;
++SSL_DefaultCanFalseStart;
++;+ local:
++;+*;
++;+};
+diff -r 05ffc38de8b4 nss/lib/ssl/ssl.h
+--- a/nss/lib/ssl/ssl.h Thu Jun 27 19:58:08 2013 +0200
++++ b/nss/lib/ssl/ssl.h Tue Jul 23 15:26:39 2013 +0300
+@@ -121,14 +121,22 @@
+ #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. */
++/* 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. The advantage of false start is that
++ * it saves a round trip for client-speaks-first protocols when performing a
++ * full handshake.
++ *
++ * See SSL_DefaultCanFalseStart for the default criteria that NSS uses to
++ * determine whether to false start or not. See SSL_SetCanFalseStartCallback
++ * for how to change that criteria. In addition to those criteria, false start
++ * will only be done when the server selects a cipher suite with an effective
++ * key length of 80 bits or more (including RC4-128). Also, see
++ * SSL_HandshakeCallback for a description on how false start affects when the
++ * handshake callback gets called.
++ */
+
+ /* For SSL 3.0 and TLS 1.0, by default we prevent chosen plaintext attacks
+ * on SSL CBC mode cipher suites (see RFC 4346 Section F.3) by splitting
+@@ -653,14 +661,59 @@
+ SSL_IMPORT SECStatus SSL_InheritMPServerSIDCache(const char * envString);
+
+ /*
+-** Set the callback on a particular socket that gets called when we finish
+-** performing a handshake.
++** Set the callback that normally gets called when the TLS handshake
++** is complete. If false start is not enabled, then the handshake callback is
++** called after verifying the peer's Finished message and before sending
++** outgoing application data and before processing incoming application data.
++**
++** If false start is enabled and there is a custom CanFalseStartCallback
++** callback set, then the handshake callback gets called after the peer's
++** Finished message has been verified, which may be after application data is
++** sent.
++**
++** If false start is enabled and there is not a custom CanFalseStartCallback
++** callback established with SSL_SetCanFalseStartCallback then the handshake
++** callback gets called before any application data is sent, which may be
++** before the peer's Finished message has been verified.
+ */
+ typedef void (PR_CALLBACK *SSLHandshakeCallback)(PRFileDesc *fd,
+ void *client_data);
+ SSL_IMPORT SECStatus SSL_HandshakeCallback(PRFileDesc *fd,
+ SSLHandshakeCallback cb, void *client_data);
+
++/* Applications that wish to customize TLS false start should set this callback
++** function. NSS will invoke the functon to determine if a particular
++** connection should use false start or not. SECSuccess indicates that the
++** callback completed successfully, and if so *canFalseStart indicates if false
++** start can be used. If the callback does not return SECSuccess then the
++** handshake will be canceled.
++**
++** Applications that do not set the callback will use an internal set of
++** criteria to determine if the connection should false start. If
++** the callback is set false start will never be used without invoking the
++** callback function, but some connections (e.g. resumed connections) will
++** never use false start and therefore will not invoke the callback.
++**
++** NSS's internal criteria for this connection can be evaluated by calling
++** SSL_DefaultCanFalseStart() from the custom callback.
++**
++** See the description of SSL_HandshakeCallback for important information on
++** how registering a custom false start callback affects when the handshake
++** callback gets called.
++**/
++typedef SECStatus (PR_CALLBACK *SSLCanFalseStartCallback)(
++ PRFileDesc *fd, void *arg, PRBool *canFalseStart);
++
++SSL_IMPORT SECStatus SSL_SetCanFalseStartCallback(
++ PRFileDesc *fd, SSLCanFalseStartCallback callback, void *arg);
++
++/* A utility function that can be called from a custom CanFalseStartCallback
++** function to determine what NSS would have done for this connection if the
++** custom callback was not implemented.
++**/
++SSL_IMPORT SECStatus SSL_DefaultCanFalseStart(PRFileDesc *fd,
++ PRBool *canFalseStart);
++
+ /*
+ ** For the server, request a new handshake. For the client, begin a new
+ ** handshake. If flushCache is non-zero, the SSL3 cache entry will be
+diff -r 05ffc38de8b4 nss/lib/ssl/ssl3con.c
+--- a/nss/lib/ssl/ssl3con.c Thu Jun 27 19:58:08 2013 +0200
++++ b/nss/lib/ssl/ssl3con.c Tue Jul 23 15:26:39 2013 +0300
+@@ -6669,35 +6669,51 @@
+ return rv;
+ }
+
+-PRBool
+-ssl3_CanFalseStart(sslSocket *ss) {
+- PRBool rv;
++static SECStatus
++ssl3_CheckFalseStart(sslSocket *ss)
++{
++ SECStatus rv;
++ PRBool maybeFalseStart = PR_TRUE;
+
+ PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
+-
+- /* XXX: does not take into account whether we are waiting for
+- * SSL_AuthCertificateComplete or SSL_RestartHandshakeAfterCertReq. If/when
+- * that is done, this function could return different results each time it
+- * would be called.
+- */
++ PORT_Assert( !ss->ssl3.hs.authCertificatePending );
++
++ /* An attacker can control the selected ciphersuite so we only wish to
++ * do False Start in the case that the selected ciphersuite is
++ * sufficiently strong that the attack can gain no advantage.
++ * Therefore we always require an 80-bit cipher. */
+
+ ssl_GetSpecReadLock(ss);
+- rv = ss->opt.enableFalseStart &&
+- !ss->sec.isServer &&
+- !ss->ssl3.hs.isResuming &&
+- ss->ssl3.cwSpec &&
+-
+- /* An attacker can control the selected ciphersuite so we only wish to
+- * do False Start in the case that the selected ciphersuite is
+- * sufficiently strong that the attack can gain no advantage.
+- * Therefore we require an 80-bit cipher and a forward-secret key
+- * exchange. */
+- ss->ssl3.cwSpec->cipher_def->secret_key_size >= 10 &&
+- (ss->ssl3.hs.kea_def->kea == kea_dhe_dss ||
+- ss->ssl3.hs.kea_def->kea == kea_dhe_rsa ||
+- ss->ssl3.hs.kea_def->kea == kea_ecdhe_ecdsa ||
+- ss->ssl3.hs.kea_def->kea == kea_ecdhe_rsa);
++ if (ss->ssl3.cwSpec->cipher_def->secret_key_size < 10) {
++ ss->ssl3.hs.canFalseStart = PR_FALSE;
++ maybeFalseStart = PR_FALSE;
++ }
+ ssl_ReleaseSpecReadLock(ss);
++ if (!maybeFalseStart) {
++ return SECSuccess;
++ }
++
++ if (!ss->canFalseStartCallback) {
++ rv = SSL_DefaultCanFalseStart(ss->fd, &ss->ssl3.hs.canFalseStart);
++
++ if (rv == SECSuccess &&
++ ss->ssl3.hs.canFalseStart && ss->handshakeCallback) {
++ /* Call the handshake callback here for backwards compatibility
++ * with applications that were using false start before
++ * canFalseStartCallback was added.
++ */
++ (ss->handshakeCallback)(ss->fd, ss->handshakeCallbackData);
++ }
++ } else {
++ rv = (ss->canFalseStartCallback)(ss->fd,
++ ss->canFalseStartCallbackData,
++ &ss->ssl3.hs.canFalseStart);
++ }
++
++ if (rv != SECSuccess) {
++ ss->ssl3.hs.canFalseStart = PR_FALSE;
++ }
++
+ return rv;
+ }
+
+@@ -6727,6 +6743,7 @@
+ return SECFailure;
+ }
+
++ ss->enoughFirstHsDone = PR_TRUE;
+ rv = ssl3_SendClientSecondRound(ss);
+
+ return rv;
+@@ -6825,6 +6842,23 @@
+ if (rv != SECSuccess) {
|