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