• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1Index: net/third_party/nss/ssl/ssl.h
2===================================================================
3--- net/third_party/nss/ssl/ssl.h	(revision 227672)
4+++ net/third_party/nss/ssl/ssl.h	(working copy)
5@@ -121,14 +121,17 @@
6 #define SSL_ENABLE_FALSE_START         22 /* Enable SSL false start (off by */
7                                           /* default, applies only to       */
8                                           /* clients). False start is a     */
9-/* mode where an SSL client will start sending application data before      */
10-/* verifying the server's Finished message. This means that we could end up */
11-/* sending data to an imposter. However, the data will be encrypted and     */
12-/* only the true server can derive the session key. Thus, so long as the    */
13-/* cipher isn't broken this is safe. Because of this, False Start will only */
14-/* occur on RSA or DH ciphersuites where the cipher's key length is >= 80   */
15-/* bits. The advantage of False Start is that it saves a round trip for     */
16-/* client-speaks-first protocols when performing a full handshake.          */
17+/* mode where an SSL client will start sending application data before
18+ * verifying the server's Finished message. This means that we could end up
19+ * sending data to an imposter. However, the data will be encrypted and
20+ * only the true server can derive the session key. Thus, so long as the
21+ * cipher isn't broken this is safe. The advantage of false start is that
22+ * it saves a round trip for client-speaks-first protocols when performing a
23+ * full handshake.
24+ *
25+ * In addition to enabling this option, the application must register a
26+ * callback using the SSL_SetCanFalseStartCallback function.
27+ */
28
29 /* For SSL 3.0 and TLS 1.0, by default we prevent chosen plaintext attacks
30  * on SSL CBC mode cipher suites (see RFC 4346 Section F.3) by splitting
31@@ -741,14 +744,45 @@
32 SSL_IMPORT SECStatus SSL_InheritMPServerSIDCache(const char * envString);
33
34 /*
35-** Set the callback on a particular socket that gets called when we finish
36-** performing a handshake.
37+** Set the callback that gets called when a TLS handshake is complete. The
38+** handshake callback is called after verifying the peer's Finished message and
39+** before processing incoming application data.
40+**
41+** For the initial handshake: If the handshake false started (see
42+** SSL_ENABLE_FALSE_START), then application data may already have been sent
43+** before the handshake callback is called. If we did not false start then the
44+** callback will get called before any application data is sent.
45 */
46 typedef void (PR_CALLBACK *SSLHandshakeCallback)(PRFileDesc *fd,
47                                                  void *client_data);
48 SSL_IMPORT SECStatus SSL_HandshakeCallback(PRFileDesc *fd,
49 			          SSLHandshakeCallback cb, void *client_data);
50
51+/* Applications that wish to enable TLS false start must set this callback
52+** function. NSS will invoke the functon to determine if a particular
53+** connection should use false start or not. SECSuccess indicates that the
54+** callback completed successfully, and if so *canFalseStart indicates if false
55+** start can be used. If the callback does not return SECSuccess then the
56+** handshake will be canceled. NSS's recommended criteria can be evaluated by
57+** calling SSL_RecommendedCanFalseStart.
58+**
59+** If no false start callback is registered then false start will never be
60+** done, even if the SSL_ENABLE_FALSE_START option is enabled.
61+**/
62+typedef SECStatus (PR_CALLBACK *SSLCanFalseStartCallback)(
63+    PRFileDesc *fd, void *arg, PRBool *canFalseStart);
64+
65+SSL_IMPORT SECStatus SSL_SetCanFalseStartCallback(
66+    PRFileDesc *fd, SSLCanFalseStartCallback callback, void *arg);
67+
68+/* This function sets *canFalseStart according to the recommended criteria for
69+** false start. These criteria may change from release to release and may depend
70+** on which handshake features have been negotiated and/or properties of the
71+** certifciates/keys used on the connection.
72+*/
73+SSL_IMPORT SECStatus SSL_RecommendedCanFalseStart(PRFileDesc *fd,
74+                                                  PRBool *canFalseStart);
75+
76 /*
77 ** For the server, request a new handshake.  For the client, begin a new
78 ** handshake.  If flushCache is non-zero, the SSL3 cache entry will be
79Index: net/third_party/nss/ssl/ssl3con.c
80===================================================================
81--- net/third_party/nss/ssl/ssl3con.c	(revision 227672)
82+++ net/third_party/nss/ssl/ssl3con.c	(working copy)
83@@ -2890,7 +2890,7 @@
84     SSL_TRC(3, ("%d: SSL3[%d] SendRecord type: %s nIn=%d",
85 		SSL_GETPID(), ss->fd, ssl3_DecodeContentType(type),
86 		nIn));
87-    PRINT_BUF(3, (ss, "Send record (plain text)", pIn, nIn));
88+    PRINT_BUF(50, (ss, "Send record (plain text)", pIn, nIn));
89
90     PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) );
91
92@@ -7344,36 +7344,72 @@
93     return rv;
94 }
95
96+static SECStatus
97+ssl3_CheckFalseStart(sslSocket *ss)
98+{
99+    PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
100+    PORT_Assert( !ss->ssl3.hs.authCertificatePending );
101+    PORT_Assert( !ss->ssl3.hs.canFalseStart );
102+
103+    if (!ss->canFalseStartCallback) {
104+	SSL_TRC(3, ("%d: SSL[%d]: no false start callback so no false start",
105+		    SSL_GETPID(), ss->fd));
106+    } else {
107+	PRBool maybeFalseStart;
108+	SECStatus rv;
109+
110+	/* An attacker can control the selected ciphersuite so we only wish to
111+	 * do False Start in the case that the selected ciphersuite is
112+	 * sufficiently strong that the attack can gain no advantage.
113+	 * Therefore we always require an 80-bit cipher. */
114+        ssl_GetSpecReadLock(ss);
115+        maybeFalseStart = ss->ssl3.cwSpec->cipher_def->secret_key_size >= 10;
116+        ssl_ReleaseSpecReadLock(ss);
117+
118+	if (!maybeFalseStart) {
119+	    SSL_TRC(3, ("%d: SSL[%d]: no false start due to weak cipher",
120+			SSL_GETPID(), ss->fd));
121+	} else {
122+	    rv = (ss->canFalseStartCallback)(ss->fd,
123+					     ss->canFalseStartCallbackData,
124+					     &ss->ssl3.hs.canFalseStart);
125+	    if (rv == SECSuccess) {
126+		SSL_TRC(3, ("%d: SSL[%d]: false start callback returned %s",
127+			    SSL_GETPID(), ss->fd,
128+			    ss->ssl3.hs.canFalseStart ? "TRUE" : "FALSE"));
129+	    } else {
130+		SSL_TRC(3, ("%d: SSL[%d]: false start callback failed (%s)",
131+			    SSL_GETPID(), ss->fd,
132+			    PR_ErrorToName(PR_GetError())));
133+	    }
134+	    return rv;
135+	}
136+    }
137+
138+    ss->ssl3.hs.canFalseStart = PR_FALSE;
139+    return SECSuccess;
140+}
141+
142 PRBool
143-ssl3_CanFalseStart(sslSocket *ss) {
144-    PRBool rv;
145+ssl3_WaitingForStartOfServerSecondRound(sslSocket *ss)
146+{
147+    PRBool result;
148
149     PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
150
151-    /* XXX: does not take into account whether we are waiting for
152-     * SSL_AuthCertificateComplete or SSL_RestartHandshakeAfterCertReq. If/when
153-     * that is done, this function could return different results each time it
154-     * would be called.
155-     */
156+    switch (ss->ssl3.hs.ws) {
157+    case wait_new_session_ticket:
158+        result = PR_TRUE;
159+        break;
160+    case wait_change_cipher:
161+        result = !ssl3_ExtensionNegotiated(ss, ssl_session_ticket_xtn);
162+        break;
163+    default:
164+        result = PR_FALSE;
165+        break;
166+    }
167
168-    ssl_GetSpecReadLock(ss);
169-    rv = ss->opt.enableFalseStart &&
170-	 !ss->sec.isServer &&
171-	 !ss->ssl3.hs.isResuming &&
172-	 ss->ssl3.cwSpec &&
173-
174-	 /* An attacker can control the selected ciphersuite so we only wish to
175-	  * do False Start in the case that the selected ciphersuite is
176-	  * sufficiently strong that the attack can gain no advantage.
177-	  * Therefore we require an 80-bit cipher and a forward-secret key
178-	  * exchange. */
179-	 ss->ssl3.cwSpec->cipher_def->secret_key_size >= 10 &&
180-	(ss->ssl3.hs.kea_def->kea == kea_dhe_dss ||
181-	 ss->ssl3.hs.kea_def->kea == kea_dhe_rsa ||
182-	 ss->ssl3.hs.kea_def->kea == kea_ecdhe_ecdsa ||
183-	 ss->ssl3.hs.kea_def->kea == kea_ecdhe_rsa);
184-    ssl_ReleaseSpecReadLock(ss);
185-    return rv;
186+    return result;
187 }
188
189 static SECStatus ssl3_SendClientSecondRound(sslSocket *ss);
190@@ -7463,6 +7499,9 @@
191     }
192     if (ss->ssl3.hs.authCertificatePending &&
193 	(sendClientCert || ss->ssl3.sendEmptyCert || ss->firstHsDone)) {
194+	SSL_TRC(3, ("%d: SSL3[%p]: deferring ssl3_SendClientSecondRound because"
195+		    " certificate authentication is still pending.",
196+		    SSL_GETPID(), ss->fd));
197 	ss->ssl3.hs.restartTarget = ssl3_SendClientSecondRound;
198 	return SECWouldBlock;
199     }
200@@ -7500,20 +7539,59 @@
201 	goto loser;	/* err code was set. */
202     }
203
204-    /* XXX: If the server's certificate hasn't been authenticated by this
205-     * point, then we may be leaking this NPN message to an attacker.
206+    /* This must be done after we've set ss->ssl3.cwSpec in
207+     * ssl3_SendChangeCipherSpecs because SSL_GetChannelInfo uses information
208+     * from cwSpec. This must be done before we call ssl3_CheckFalseStart
209+     * because the false start callback (if any) may need the information from
210+     * the functions that depend on this being set.
211      */
212+    ss->enoughFirstHsDone = PR_TRUE;
213+
214     if (!ss->firstHsDone) {
215+	/* XXX: If the server's certificate hasn't been authenticated by this
216+	 * point, then we may be leaking this NPN message to an attacker.
217+	 */
218 	rv = ssl3_SendNextProto(ss);
219 	if (rv != SECSuccess) {
220 	    goto loser;	/* err code was set. */
221 	}
222     }
223+
224     rv = ssl3_SendEncryptedExtensions(ss);
225     if (rv != SECSuccess) {
226 	goto loser; /* err code was set. */
227     }
228
229+    if (!ss->firstHsDone) {
230+	if (ss->opt.enableFalseStart) {
231+	    if (!ss->ssl3.hs.authCertificatePending) {
232+		/* When we fix bug 589047, we will need to know whether we are
233+		 * false starting before we try to flush the client second
234+		 * round to the network. With that in mind, we purposefully
235+		 * call ssl3_CheckFalseStart before calling ssl3_SendFinished,
236+		 * which includes a call to ssl3_FlushHandshake, so that
237+		 * no application develops a reliance on such flushing being
238+		 * done before its false start callback is called.
239+		 */
240+		ssl_ReleaseXmitBufLock(ss);
241+		rv = ssl3_CheckFalseStart(ss);
242+		ssl_GetXmitBufLock(ss);
243+		if (rv != SECSuccess) {
244+		    goto loser;
245+		}
246+	    } else {
247+		/* The certificate authentication and the server's Finished
248+		 * message are racing each other. If the certificate
249+		 * authentication wins, then we will try to false start in
250+		 * ssl3_AuthCertificateComplete.
251+		 */
252+		SSL_TRC(3, ("%d: SSL3[%p]: deferring false start check because"
253+			    " certificate authentication is still pending.",
254+			    SSL_GETPID(), ss->fd));
255+	    }
256+	}
257+    }
258+
259     rv = ssl3_SendFinished(ss, 0);
260     if (rv != SECSuccess) {
261 	goto loser;	/* err code was set. */
262@@ -7526,10 +7604,7 @@
263     else
264 	ss->ssl3.hs.ws = wait_change_cipher;
265
266-    /* Do the handshake callback for sslv3 here, if we can false start. */
267-    if (ss->handshakeCallback != NULL && ssl3_CanFalseStart(ss)) {
268-	(ss->handshakeCallback)(ss->fd, ss->handshakeCallbackData);
269-    }
270+    PORT_Assert(ssl3_WaitingForStartOfServerSecondRound(ss));
271
272     return SECSuccess;
273
274@@ -10147,13 +10222,6 @@
275
276 	    ss->ssl3.hs.authCertificatePending = PR_TRUE;
277 	    rv = SECSuccess;
278-
279-	    /* XXX: Async cert validation and False Start don't work together
280-	     * safely yet; if we leave False Start enabled, we may end up false
281-	     * starting (sending application data) before we
282-	     * SSL_AuthCertificateComplete has been called.
283-	     */
284-	    ss->opt.enableFalseStart = PR_FALSE;
285 	}
286
287 	if (rv != SECSuccess) {
288@@ -10278,6 +10346,12 @@
289     } else if (ss->ssl3.hs.restartTarget != NULL) {
290 	sslRestartTarget target = ss->ssl3.hs.restartTarget;
291 	ss->ssl3.hs.restartTarget = NULL;
292+
293+	if (target == ssl3_FinishHandshake) {
294+	    SSL_TRC(3,("%d: SSL3[%p]: certificate authentication lost the race"
295+		       " with peer's finished message", SSL_GETPID(), ss->fd));
296+	}
297+
298 	rv = target(ss);
299 	/* Even if we blocked here, we have accomplished enough to claim
300 	 * success. Any remaining work will be taken care of by subsequent
301@@ -10287,7 +10361,27 @@
302 	    rv = SECSuccess;
303 	}
304     } else {
305-	rv = SECSuccess;
306+	SSL_TRC(3, ("%d: SSL3[%p]: certificate authentication won the race with"
307+        	    " peer's finished message", SSL_GETPID(), ss->fd));
308+
309+	PORT_Assert(!ss->firstHsDone);
310+	PORT_Assert(!ss->sec.isServer);
311+	PORT_Assert(!ss->ssl3.hs.isResuming);
312+	PORT_Assert(ss->ssl3.hs.ws != idle_handshake);
313+
314+	if (ss->opt.enableFalseStart &&
315+	    !ss->firstHsDone &&
316+	    !ss->sec.isServer &&
317+	    !ss->ssl3.hs.isResuming &&
318+	    ssl3_WaitingForStartOfServerSecondRound(ss)) {
319+	    /* ssl3_SendClientSecondRound deferred the false start check because
320+	     * certificate authentication was pending, so we do it now if we still
321+	     * haven't received any of the server's second round yet.
322+	     */
323+	    rv = ssl3_CheckFalseStart(ss);
324+	} else {
325+	    rv = SECSuccess;
326+	}
327     }
328
329 done:
330@@ -10913,9 +11007,6 @@
331         return rv;
332     }
333
334-    ss->gs.writeOffset = 0;
335-    ss->gs.readOffset  = 0;
336-
337     if (ss->ssl3.hs.kea_def->kea == kea_ecdhe_rsa) {
338 	effectiveExchKeyType = kt_rsa;
339     } else {
340@@ -10980,6 +11071,9 @@
341     return rv;
342 }
343
344+/* The return type is SECStatus instead of void because this function needs
345+ * to have type sslRestartTarget.
346+ */
347 SECStatus
348 ssl3_FinishHandshake(sslSocket * ss)
349 {
350@@ -10989,19 +11083,16 @@
351
352     /* The first handshake is now completed. */
353     ss->handshake           = NULL;
354-    ss->firstHsDone         = PR_TRUE;
355
356     if (ss->ssl3.hs.cacheSID) {
357 	(*ss->sec.cache)(ss->sec.ci.sid);
358 	ss->ssl3.hs.cacheSID = PR_FALSE;
359     }
360
361+    ss->ssl3.hs.canFalseStart = PR_FALSE; /* False Start phase is complete */
362     ss->ssl3.hs.ws = idle_handshake;
363
364-    /* Do the handshake callback for sslv3 here, if we cannot false start. */
365-    if (ss->handshakeCallback != NULL && !ssl3_CanFalseStart(ss)) {
366-	(ss->handshakeCallback)(ss->fd, ss->handshakeCallbackData);
367-    }
368+    ssl_FinishHandshake(ss);
369
370     return SECSuccess;
371 }
372@@ -11966,7 +12057,6 @@
373
374     ssl_ReleaseSSL3HandshakeLock(ss);
375     return rv;
376-
377 }
378
379 /*
380Index: net/third_party/nss/ssl/ssl3gthr.c
381===================================================================
382--- net/third_party/nss/ssl/ssl3gthr.c	(revision 227672)
383+++ net/third_party/nss/ssl/ssl3gthr.c	(working copy)
384@@ -275,11 +275,17 @@
385 {
386     SSL3Ciphertext cText;
387     int            rv;
388-    PRBool         canFalseStart = PR_FALSE;
389+    PRBool         keepGoing = PR_TRUE;
390
391     SSL_TRC(30, ("ssl3_GatherCompleteHandshake"));
392
393+    /* ssl3_HandleRecord may end up eventually calling ssl_FinishHandshake,
394+     * which requires the 1stHandshakeLock, which must be acquired before the
395+     * RecvBufLock.
396+     */
397+    PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
398     PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
399+
400     do {
401 	PRBool handleRecordNow = PR_FALSE;
402
403@@ -364,24 +370,52 @@
404
405 	    cText.buf     = &ss->gs.inbuf;
406 	    rv = ssl3_HandleRecord(ss, &cText, &ss->gs.buf);
407+
408+	    if (rv == (int) SECSuccess && ss->gs.buf.len > 0) {
409+		/* We have application data to return to the application. This
410+		 * prioritizes returning application data to the application over
411+		 * completing any renegotiation handshake we may be doing.
412+		 */
413+		PORT_Assert(ss->firstHsDone);
414+		PORT_Assert(cText.type == content_application_data);
415+		break;
416+	    }
417 	}
418 	if (rv < 0) {
419 	    return ss->recvdCloseNotify ? 0 : rv;
420 	}
421
422-	/* If we kicked off a false start in ssl3_HandleServerHelloDone, break
423-	 * out of this loop early without finishing the handshake.
424-	 */
425-	if (ss->opt.enableFalseStart) {
426-	    ssl_GetSSL3HandshakeLock(ss);
427-	    canFalseStart = (ss->ssl3.hs.ws == wait_change_cipher ||
428-			     ss->ssl3.hs.ws == wait_new_session_ticket) &&
429-		            ssl3_CanFalseStart(ss);
430-	    ssl_ReleaseSSL3HandshakeLock(ss);
431+	PORT_Assert(keepGoing);
432+	ssl_GetSSL3HandshakeLock(ss);
433+	if (ss->ssl3.hs.ws == idle_handshake) {
434+	    /* We are done with the current handshake so stop trying to
435+	     * handshake. Note that it would be safe to test ss->firstHsDone
436+	     * instead of ss->ssl3.hs.ws. By testing ss->ssl3.hs.ws instead,
437+	     * we prioritize completing a renegotiation handshake over sending
438+	     * application data.
439+	     */
440+	    PORT_Assert(ss->firstHsDone);
441+	    PORT_Assert(!ss->ssl3.hs.canFalseStart);
442+	    keepGoing = PR_FALSE;
443+	} else if (ss->ssl3.hs.canFalseStart) {
444+	    /* Prioritize sending application data over trying to complete
445+	     * the handshake if we're false starting.
446+	     *
447+	     * If we were to do this check at the beginning of the loop instead
448+	     * of here, then this function would become be a no-op after
449+	     * receiving the ServerHelloDone in the false start case, and we
450+	     * would never complete the handshake.
451+	     */
452+	    PORT_Assert(!ss->firstHsDone);
453+
454+	    if (ssl3_WaitingForStartOfServerSecondRound(ss)) {
455+		keepGoing = PR_FALSE;
456+	    } else {
457+		ss->ssl3.hs.canFalseStart = PR_FALSE;
458+	    }
459 	}
460-    } while (ss->ssl3.hs.ws != idle_handshake &&
461-             !canFalseStart &&
462-             ss->gs.buf.len == 0);
463+	ssl_ReleaseSSL3HandshakeLock(ss);
464+    } while (keepGoing);
465
466     ss->gs.readOffset = 0;
467     ss->gs.writeOffset = ss->gs.buf.len;
468@@ -404,7 +438,10 @@
469 {
470     int            rv;
471
472+    /* ssl3_GatherCompleteHandshake requires both of these locks. */
473+    PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
474     PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
475+
476     do {
477 	rv = ssl3_GatherCompleteHandshake(ss, flags);
478     } while (rv > 0 && ss->gs.buf.len == 0);
479Index: net/third_party/nss/ssl/sslauth.c
480===================================================================
481--- net/third_party/nss/ssl/sslauth.c	(revision 227672)
482+++ net/third_party/nss/ssl/sslauth.c	(working copy)
483@@ -100,7 +100,6 @@
484     sslSocket *ss;
485     const char *cipherName;
486     PRBool isDes = PR_FALSE;
487-    PRBool enoughFirstHsDone = PR_FALSE;
488
489     ss = ssl_FindSocket(fd);
490     if (!ss) {
491@@ -118,14 +117,7 @@
492 	*op = SSL_SECURITY_STATUS_OFF;
493     }
494
495-    if (ss->firstHsDone) {
496-	enoughFirstHsDone = PR_TRUE;
497-    } else if (ss->version >= SSL_LIBRARY_VERSION_3_0 &&
498-	       ssl3_CanFalseStart(ss)) {
499-	enoughFirstHsDone = PR_TRUE;
500-    }
501-
502-    if (ss->opt.useSecurity && enoughFirstHsDone) {
503+    if (ss->opt.useSecurity && ss->enoughFirstHsDone) {
504 	if (ss->version < SSL_LIBRARY_VERSION_3_0) {
505 	    cipherName = ssl_cipherName[ss->sec.cipherType];
506 	} else {
507Index: net/third_party/nss/ssl/sslimpl.h
508===================================================================
509--- net/third_party/nss/ssl/sslimpl.h	(revision 227672)
510+++ net/third_party/nss/ssl/sslimpl.h	(working copy)
511@@ -881,6 +881,8 @@
512     /* Shared state between ssl3_HandleFinished and ssl3_FinishHandshake */
513     PRBool                cacheSID;
514
515+    PRBool                canFalseStart;   /* Can/did we False Start */
516+
517     /* clientSigAndHash contains the contents of the signature_algorithms
518      * extension (if any) from the client. This is only valid for TLS 1.2
519      * or later. */
520@@ -1162,6 +1164,10 @@
521     unsigned long    clientAuthRequested;
522     unsigned long    delayDisabled;       /* Nagle delay disabled */
523     unsigned long    firstHsDone;         /* first handshake is complete. */
524+    unsigned long    enoughFirstHsDone;   /* enough of the first handshake is
525+					   * done for callbacks to be able to
526+					   * retrieve channel security
527+					   * parameters from the SSL socket. */
528     unsigned long    handshakeBegun;
529     unsigned long    lastWriteBlocked;
530     unsigned long    recvdCloseNotify;    /* received SSL EOF. */
531@@ -1210,6 +1216,8 @@
532     void                     *badCertArg;
533     SSLHandshakeCallback      handshakeCallback;
534     void                     *handshakeCallbackData;
535+    SSLCanFalseStartCallback  canFalseStartCallback;
536+    void                     *canFalseStartCallbackData;
537     void                     *pkcs11PinArg;
538     SSLNextProtoCallback      nextProtoCallback;
539     void                     *nextProtoArg;
540@@ -1423,7 +1431,19 @@
541
542 extern SECStatus ssl_EnableNagleDelay(sslSocket *ss, PRBool enabled);
543
544-extern PRBool    ssl3_CanFalseStart(sslSocket *ss);
545+extern void      ssl_FinishHandshake(sslSocket *ss);
546+
547+/* Returns PR_TRUE if we are still waiting for the server to respond to our
548+ * client second round. Once we've received any part of the server's second
549+ * round then we don't bother trying to false start since it is almost always
550+ * the case that the NewSessionTicket, ChangeCipherSoec, and Finished messages
551+ * were sent in the same packet and we want to process them all at the same
552+ * time. If we were to try to false start in the middle of the server's second
553+ * round, then we would increase the number of I/O operations
554+ * (SSL_ForceHandshake/PR_Recv/PR_Send/etc.) needed to finish the handshake.
555+ */
556+extern PRBool    ssl3_WaitingForStartOfServerSecondRound(sslSocket *ss);
557+
558 extern SECStatus
559 ssl3_CompressMACEncryptRecord(ssl3CipherSpec *   cwSpec,
560 		              PRBool             isServer,
561Index: net/third_party/nss/ssl/sslinfo.c
562===================================================================
563--- net/third_party/nss/ssl/sslinfo.c	(revision 227672)
564+++ net/third_party/nss/ssl/sslinfo.c	(working copy)
565@@ -26,7 +26,6 @@
566     sslSocket *      ss;
567     SSLChannelInfo   inf;
568     sslSessionID *   sid;
569-    PRBool           enoughFirstHsDone = PR_FALSE;
570
571     if (!info || len < sizeof inf.length) {
572 	PORT_SetError(SEC_ERROR_INVALID_ARGS);
573@@ -43,14 +42,7 @@
574     memset(&inf, 0, sizeof inf);
575     inf.length = PR_MIN(sizeof inf, len);
576
577-    if (ss->firstHsDone) {
578-	enoughFirstHsDone = PR_TRUE;
579-    } else if (ss->version >= SSL_LIBRARY_VERSION_3_0 &&
580-	       ssl3_CanFalseStart(ss)) {
581-	enoughFirstHsDone = PR_TRUE;
582-    }
583-
584-    if (ss->opt.useSecurity && enoughFirstHsDone) {
585+    if (ss->opt.useSecurity && ss->enoughFirstHsDone) {
586         sid = ss->sec.ci.sid;
587 	inf.protocolVersion  = ss->version;
588 	inf.authKeyBits      = ss->sec.authKeyBits;
589Index: net/third_party/nss/ssl/sslsecur.c
590===================================================================
591--- net/third_party/nss/ssl/sslsecur.c	(revision 227672)
592+++ net/third_party/nss/ssl/sslsecur.c	(working copy)
593@@ -97,23 +97,13 @@
594 	    ss->securityHandshake = 0;
595 	}
596 	if (ss->handshake == 0) {
597-	    ssl_GetRecvBufLock(ss);
598-	    ss->gs.recordLen = 0;
599-	    ssl_ReleaseRecvBufLock(ss);
600-
601-	    SSL_TRC(3, ("%d: SSL[%d]: handshake is completed",
602-			SSL_GETPID(), ss->fd));
603-            /* call handshake callback for ssl v2 */
604-	    /* for v3 this is done in ssl3_HandleFinished() */
605-	    if ((ss->handshakeCallback != NULL) && /* has callback */
606-		(!ss->firstHsDone) &&              /* only first time */
607-		(ss->version < SSL_LIBRARY_VERSION_3_0)) {  /* not ssl3 */
608-		ss->firstHsDone     = PR_TRUE;
609-		(ss->handshakeCallback)(ss->fd, ss->handshakeCallbackData);
610+	    /* for v3 this is done in ssl3_FinishHandshake */
611+	    if (!ss->firstHsDone && ss->version < SSL_LIBRARY_VERSION_3_0) {
612+		ssl_GetRecvBufLock(ss);
613+		ss->gs.recordLen = 0;
614+		ssl_FinishHandshake(ss);
615+		ssl_ReleaseRecvBufLock(ss);
616 	    }
617-	    ss->firstHsDone         = PR_TRUE;
618-	    ss->gs.writeOffset = 0;
619-	    ss->gs.readOffset  = 0;
620 	    break;
621 	}
622 	rv = (*ss->handshake)(ss);
623@@ -134,6 +124,24 @@
624     return rv;
625 }
626
627+void
628+ssl_FinishHandshake(sslSocket *ss)
629+{
630+    PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
631+    PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
632+
633+    SSL_TRC(3, ("%d: SSL[%d]: handshake is completed", SSL_GETPID(), ss->fd));
634+
635+    ss->firstHsDone = PR_TRUE;
636+    ss->enoughFirstHsDone = PR_TRUE;
637+    ss->gs.writeOffset = 0;
638+    ss->gs.readOffset  = 0;
639+
640+    if (ss->handshakeCallback) {
641+	(ss->handshakeCallback)(ss->fd, ss->handshakeCallbackData);
642+    }
643+}
644+
645 /*
646  * Handshake function that blocks.  Used to force a
647  * retry on a connection on the next read/write.
648@@ -206,6 +214,7 @@
649     ssl_Get1stHandshakeLock(ss);
650
651     ss->firstHsDone = PR_FALSE;
652+    ss->enoughFirstHsDone = PR_FALSE;
653     if ( asServer ) {
654 	ss->handshake = ssl2_BeginServerHandshake;
655 	ss->handshaking = sslHandshakingAsServer;
656@@ -221,6 +230,8 @@
657     ssl_ReleaseRecvBufLock(ss);
658
659     ssl_GetSSL3HandshakeLock(ss);
660+    ss->ssl3.hs.canFalseStart = PR_FALSE;
661+    ss->ssl3.hs.restartTarget = NULL;
662
663     /*
664     ** Blow away old security state and get a fresh setup.
665@@ -331,6 +342,71 @@
666     return SECSuccess;
667 }
668
669+/* Register an application callback to be called when false start may happen.
670+** Acquires and releases HandshakeLock.
671+*/
672+SECStatus
673+SSL_SetCanFalseStartCallback(PRFileDesc *fd, SSLCanFalseStartCallback cb,
674+			     void *arg)
675+{
676+    sslSocket *ss;
677+
678+    ss = ssl_FindSocket(fd);
679+    if (!ss) {
680+	SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetCanFalseStartCallback",
681+		 SSL_GETPID(), fd));
682+	return SECFailure;
683+    }
684+
685+    if (!ss->opt.useSecurity) {
686+	PORT_SetError(SEC_ERROR_INVALID_ARGS);
687+	return SECFailure;
688+    }
689+
690+    ssl_Get1stHandshakeLock(ss);
691+    ssl_GetSSL3HandshakeLock(ss);
692+
693+    ss->canFalseStartCallback     = cb;
694+    ss->canFalseStartCallbackData = arg;
695+
696+    ssl_ReleaseSSL3HandshakeLock(ss);
697+    ssl_Release1stHandshakeLock(ss);
698+
699+    return SECSuccess;
700+}
701+
702+SECStatus
703+SSL_RecommendedCanFalseStart(PRFileDesc *fd, PRBool *canFalseStart)
704+{
705+    sslSocket *ss;
706+
707+    *canFalseStart = PR_FALSE;
708+    ss = ssl_FindSocket(fd);
709+    if (!ss) {
710+	SSL_DBG(("%d: SSL[%d]: bad socket in SSL_RecommendedCanFalseStart",
711+		 SSL_GETPID(), fd));
712+	return SECFailure;
713+    }
714+
715+    if (!ss->ssl3.initialized) {
716+	PORT_SetError(SEC_ERROR_INVALID_ARGS);
717+	return SECFailure;
718+    }
719+
720+    if (ss->version < SSL_LIBRARY_VERSION_3_0) {
721+	PORT_SetError(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SSL2);
722+	return SECFailure;
723+    }
724+
725+    /* Require a forward-secret key exchange. */
726+    *canFalseStart = ss->ssl3.hs.kea_def->kea == kea_dhe_dss ||
727+		     ss->ssl3.hs.kea_def->kea == kea_dhe_rsa ||
728+		     ss->ssl3.hs.kea_def->kea == kea_ecdhe_ecdsa ||
729+		     ss->ssl3.hs.kea_def->kea == kea_ecdhe_rsa;
730+
731+    return SECSuccess;
732+}
733+
734 /* Try to make progress on an SSL handshake by attempting to read the
735 ** next handshake from the peer, and sending any responses.
736 ** For non-blocking sockets, returns PR_ERROR_WOULD_BLOCK  if it cannot
737@@ -524,6 +600,9 @@
738     int              amount;
739     int              available;
740
741+    /* ssl3_GatherAppDataRecord may call ssl_FinishHandshake, which needs the
742+     * 1stHandshakeLock. */
743+    ssl_Get1stHandshakeLock(ss);
744     ssl_GetRecvBufLock(ss);
745
746     available = ss->gs.writeOffset - ss->gs.readOffset;
747@@ -590,6 +669,7 @@
748
749 done:
750     ssl_ReleaseRecvBufLock(ss);
751+    ssl_Release1stHandshakeLock(ss);
752     return rv;
753 }
754
755@@ -1156,7 +1236,8 @@
756 int
757 ssl_SecureSend(sslSocket *ss, const unsigned char *buf, int len, int flags)
758 {
759-    int              rv		= 0;
760+    int rv = 0;
761+    PRBool falseStart = PR_FALSE;
762
763     SSL_TRC(2, ("%d: SSL[%d]: SecureSend: sending %d bytes",
764 		SSL_GETPID(), ss->fd, len));
765@@ -1191,19 +1272,14 @@
766     	ss->writerThread = PR_GetCurrentThread();
767     /* If any of these is non-zero, the initial handshake is not done. */
768     if (!ss->firstHsDone) {
769-	PRBool canFalseStart = PR_FALSE;
770 	ssl_Get1stHandshakeLock(ss);
771-	if (ss->version >= SSL_LIBRARY_VERSION_3_0) {
772+	if (ss->opt.enableFalseStart &&
773+	    ss->version >= SSL_LIBRARY_VERSION_3_0) {
774 	    ssl_GetSSL3HandshakeLock(ss);
775-	    if ((ss->ssl3.hs.ws == wait_change_cipher ||
776-		ss->ssl3.hs.ws == wait_finished ||
777-		ss->ssl3.hs.ws == wait_new_session_ticket) &&
778-		ssl3_CanFalseStart(ss)) {
779-		canFalseStart = PR_TRUE;
780-	    }
781+	    falseStart = ss->ssl3.hs.canFalseStart;
782 	    ssl_ReleaseSSL3HandshakeLock(ss);
783 	}
784-	if (!canFalseStart &&
785+	if (!falseStart &&
786 	    (ss->handshake || ss->nextHandshake || ss->securityHandshake)) {
787 	    rv = ssl_Do1stHandshake(ss);
788 	}
789@@ -1228,6 +1304,17 @@
790 	goto done;
791     }
792
793+    if (!ss->firstHsDone) {
794+	PORT_Assert(ss->version >= SSL_LIBRARY_VERSION_3_0);
795+#ifdef DEBUG
796+	ssl_GetSSL3HandshakeLock(ss);
797+	PORT_Assert(ss->ssl3.hs.canFalseStart);
798+	ssl_ReleaseSSL3HandshakeLock(ss);
799+#endif
800+	SSL_TRC(3, ("%d: SSL[%d]: SecureSend: sending data due to false start",
801+		    SSL_GETPID(), ss->fd));
802+    }
803+
804     /* Send out the data using one of these functions:
805      *	ssl2_SendClear, ssl2_SendStream, ssl2_SendBlock,
806      *  ssl3_SendApplicationData
807Index: net/third_party/nss/ssl/sslsock.c
808===================================================================
809--- net/third_party/nss/ssl/sslsock.c	(revision 227672)
810+++ net/third_party/nss/ssl/sslsock.c	(working copy)
811@@ -366,6 +366,8 @@
812 	    ss->badCertArg            = os->badCertArg;
813 	    ss->handshakeCallback     = os->handshakeCallback;
814 	    ss->handshakeCallbackData = os->handshakeCallbackData;
815+	    ss->canFalseStartCallback = os->canFalseStartCallback;
816+	    ss->canFalseStartCallbackData = os->canFalseStartCallbackData;
817 	    ss->pkcs11PinArg          = os->pkcs11PinArg;
818 	    ss->getChannelID          = os->getChannelID;
819 	    ss->getChannelIDArg       = os->getChannelIDArg;
820@@ -2457,10 +2459,14 @@
821 	    } else if (new_flags & PR_POLL_WRITE) {
822 		    /* The caller is trying to write, but the handshake is
823 		    ** blocked waiting for data to read, and the first
824-		    ** handshake has been sent.  so do NOT to poll on write.
825+		    ** handshake has been sent.  So do NOT to poll on write
826+		    ** unless we did false start.
827 		    */
828-		    new_flags ^=  PR_POLL_WRITE;   /* don't select on write. */
829-		    new_flags |=  PR_POLL_READ;	   /* do    select on read. */
830+		    if (!(ss->version >= SSL_LIBRARY_VERSION_3_0 &&
831+			ss->ssl3.hs.canFalseStart)) {
832+			new_flags ^= PR_POLL_WRITE; /* don't select on write. */
833+		    }
834+		    new_flags |= PR_POLL_READ;      /* do    select on read. */
835 	    }
836 	}
837     } else if ((new_flags & PR_POLL_READ) && (SSL_DataPending(fd) > 0)) {
838