1 Index: net/third_party/nss/ssl/ssl.h
2 ===================================================================
3 --- net/third_party/nss/ssl/ssl.h (revision 227363)
4 +++ net/third_party/nss/ssl/ssl.h (working copy)
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
25 + * See SSL_DefaultCanFalseStart for the default criteria that NSS uses to
26 + * determine whether to false start or not. See SSL_SetCanFalseStartCallback
27 + * for how to change that criteria. In addition to those criteria, false start
28 + * will only be done when the server selects a cipher suite with an effective
29 + * key length of 80 bits or more (including RC4-128). Also, see
30 + * SSL_HandshakeCallback for a description on how false start affects when the
31 + * handshake callback gets called.
34 /* For SSL 3.0 and TLS 1.0, by default we prevent chosen plaintext attacks
35 * on SSL CBC mode cipher suites (see RFC 4346 Section F.3) by splitting
37 SSL_IMPORT SECStatus SSL_InheritMPServerSIDCache(const char * envString);
40 -** Set the callback on a particular socket that gets called when we finish
41 -** performing a handshake.
42 +** Set the callback that normally gets called when the TLS handshake
43 +** is complete. If false start is not enabled, then the handshake callback is
44 +** called after verifying the peer's Finished message and before sending
45 +** outgoing application data and before processing incoming application data.
47 +** If false start is enabled and there is a custom CanFalseStartCallback
48 +** callback set, then the handshake callback gets called after the peer's
49 +** Finished message has been verified, which may be after application data is
52 +** If false start is enabled and there is not a custom CanFalseStartCallback
53 +** callback established with SSL_SetCanFalseStartCallback then the handshake
54 +** callback gets called before any application data is sent, which may be
55 +** before the peer's Finished message has been verified.
57 typedef void (PR_CALLBACK *SSLHandshakeCallback)(PRFileDesc *fd,
59 SSL_IMPORT SECStatus SSL_HandshakeCallback(PRFileDesc *fd,
60 SSLHandshakeCallback cb, void *client_data);
62 +/* Applications that wish to customize TLS false start should set this callback
63 +** function. NSS will invoke the functon to determine if a particular
64 +** connection should use false start or not. SECSuccess indicates that the
65 +** callback completed successfully, and if so *canFalseStart indicates if false
66 +** start can be used. If the callback does not return SECSuccess then the
67 +** handshake will be canceled.
69 +** Applications that do not set the callback will use an internal set of
70 +** criteria to determine if the connection should false start. If
71 +** the callback is set false start will never be used without invoking the
72 +** callback function, but some connections (e.g. resumed connections) will
73 +** never use false start and therefore will not invoke the callback.
75 +** NSS's internal criteria for this connection can be evaluated by calling
76 +** SSL_DefaultCanFalseStart() from the custom callback.
78 +** See the description of SSL_HandshakeCallback for important information on
79 +** how registering a custom false start callback affects when the handshake
80 +** callback gets called.
82 +typedef SECStatus (PR_CALLBACK *SSLCanFalseStartCallback)(
83 + PRFileDesc *fd, void *arg, PRBool *canFalseStart);
85 +SSL_IMPORT SECStatus SSL_SetCanFalseStartCallback(
86 + PRFileDesc *fd, SSLCanFalseStartCallback callback, void *arg);
88 +/* A utility function that can be called from a custom CanFalseStartCallback
89 +** function to determine what NSS would have done for this connection if the
90 +** custom callback was not implemented.
92 +SSL_IMPORT SECStatus SSL_DefaultCanFalseStart(PRFileDesc *fd,
93 + PRBool *canFalseStart);
96 ** For the server, request a new handshake. For the client, begin a new
97 ** handshake. If flushCache is non-zero, the SSL3 cache entry will be
98 Index: net/third_party/nss/ssl/ssl3gthr.c
99 ===================================================================
100 --- net/third_party/nss/ssl/ssl3gthr.c (revision 227363)
101 +++ net/third_party/nss/ssl/ssl3gthr.c (working copy)
104 if (ss->opt.enableFalseStart) {
105 ssl_GetSSL3HandshakeLock(ss);
106 - canFalseStart = (ss->ssl3.hs.ws == wait_change_cipher ||
107 - ss->ssl3.hs.ws == wait_new_session_ticket) &&
108 - ssl3_CanFalseStart(ss);
109 + canFalseStart = ss->ssl3.hs.canFalseStart;
110 ssl_ReleaseSSL3HandshakeLock(ss);
112 } while (ss->ssl3.hs.ws != idle_handshake &&
113 Index: net/third_party/nss/ssl/sslinfo.c
114 ===================================================================
115 --- net/third_party/nss/ssl/sslinfo.c (revision 227363)
116 +++ net/third_party/nss/ssl/sslinfo.c (working copy)
121 - PRBool enoughFirstHsDone = PR_FALSE;
123 if (!info || len < sizeof inf.length) {
124 PORT_SetError(SEC_ERROR_INVALID_ARGS);
126 memset(&inf, 0, sizeof inf);
127 inf.length = PR_MIN(sizeof inf, len);
129 - if (ss->firstHsDone) {
130 - enoughFirstHsDone = PR_TRUE;
131 - } else if (ss->version >= SSL_LIBRARY_VERSION_3_0 &&
132 - ssl3_CanFalseStart(ss)) {
133 - enoughFirstHsDone = PR_TRUE;
136 - if (ss->opt.useSecurity && enoughFirstHsDone) {
137 + if (ss->opt.useSecurity && ss->enoughFirstHsDone) {
138 sid = ss->sec.ci.sid;
139 inf.protocolVersion = ss->version;
140 inf.authKeyBits = ss->sec.authKeyBits;
141 Index: net/third_party/nss/ssl/sslauth.c
142 ===================================================================
143 --- net/third_party/nss/ssl/sslauth.c (revision 227363)
144 +++ net/third_party/nss/ssl/sslauth.c (working copy)
147 const char *cipherName;
148 PRBool isDes = PR_FALSE;
149 - PRBool enoughFirstHsDone = PR_FALSE;
151 ss = ssl_FindSocket(fd);
154 *op = SSL_SECURITY_STATUS_OFF;
157 - if (ss->firstHsDone) {
158 - enoughFirstHsDone = PR_TRUE;
159 - } else if (ss->version >= SSL_LIBRARY_VERSION_3_0 &&
160 - ssl3_CanFalseStart(ss)) {
161 - enoughFirstHsDone = PR_TRUE;
164 - if (ss->opt.useSecurity && enoughFirstHsDone) {
165 + if (ss->opt.useSecurity && ss->enoughFirstHsDone) {
166 if (ss->version < SSL_LIBRARY_VERSION_3_0) {
167 cipherName = ssl_cipherName[ss->sec.cipherType];
169 Index: net/third_party/nss/ssl/sslimpl.h
170 ===================================================================
171 --- net/third_party/nss/ssl/sslimpl.h (revision 227363)
172 +++ net/third_party/nss/ssl/sslimpl.h (working copy)
174 /* Shared state between ssl3_HandleFinished and ssl3_FinishHandshake */
177 + PRBool canFalseStart; /* Can/did we False Start */
179 /* clientSigAndHash contains the contents of the signature_algorithms
180 * extension (if any) from the client. This is only valid for TLS 1.2
182 @@ -1162,6 +1164,10 @@
183 unsigned long clientAuthRequested;
184 unsigned long delayDisabled; /* Nagle delay disabled */
185 unsigned long firstHsDone; /* first handshake is complete. */
186 + unsigned long enoughFirstHsDone; /* enough of the first handshake is
187 + * done for callbacks to be able to
188 + * retrieve channel security
189 + * parameters from the SSL socket. */
190 unsigned long handshakeBegun;
191 unsigned long lastWriteBlocked;
192 unsigned long recvdCloseNotify; /* received SSL EOF. */
193 @@ -1210,6 +1216,8 @@
195 SSLHandshakeCallback handshakeCallback;
196 void *handshakeCallbackData;
197 + SSLCanFalseStartCallback canFalseStartCallback;
198 + void *canFalseStartCallbackData;
200 SSLNextProtoCallback nextProtoCallback;
202 @@ -1423,7 +1431,6 @@
204 extern SECStatus ssl_EnableNagleDelay(sslSocket *ss, PRBool enabled);
206 -extern PRBool ssl3_CanFalseStart(sslSocket *ss);
208 ssl3_CompressMACEncryptRecord(ssl3CipherSpec * cwSpec,
210 Index: net/third_party/nss/ssl/sslsecur.c
211 ===================================================================
212 --- net/third_party/nss/ssl/sslsecur.c (revision 227363)
213 +++ net/third_party/nss/ssl/sslsecur.c (working copy)
215 if (ss->handshake == 0) {
216 ssl_GetRecvBufLock(ss);
217 ss->gs.recordLen = 0;
218 + ss->gs.writeOffset = 0;
219 + ss->gs.readOffset = 0;
220 ssl_ReleaseRecvBufLock(ss);
222 SSL_TRC(3, ("%d: SSL[%d]: handshake is completed",
223 SSL_GETPID(), ss->fd));
224 - /* call handshake callback for ssl v2 */
225 - /* for v3 this is done in ssl3_HandleFinished() */
226 - if ((ss->handshakeCallback != NULL) && /* has callback */
227 - (!ss->firstHsDone) && /* only first time */
228 - (ss->version < SSL_LIBRARY_VERSION_3_0)) { /* not ssl3 */
229 - ss->firstHsDone = PR_TRUE;
230 - (ss->handshakeCallback)(ss->fd, ss->handshakeCallbackData);
232 - ss->firstHsDone = PR_TRUE;
233 - ss->gs.writeOffset = 0;
234 - ss->gs.readOffset = 0;
237 rv = (*ss->handshake)(ss);
239 ssl_Get1stHandshakeLock(ss);
241 ss->firstHsDone = PR_FALSE;
242 + ss->enoughFirstHsDone = PR_FALSE;
244 ss->handshake = ssl2_BeginServerHandshake;
245 ss->handshaking = sslHandshakingAsServer;
247 ssl_ReleaseRecvBufLock(ss);
249 ssl_GetSSL3HandshakeLock(ss);
250 + ss->ssl3.hs.canFalseStart = PR_FALSE;
251 + ss->ssl3.hs.restartTarget = NULL;
254 ** Blow away old security state and get a fresh setup.
257 /* SSL v2 protocol does not support subsequent handshakes. */
258 if (ss->version < SSL_LIBRARY_VERSION_3_0) {
259 - PORT_SetError(SEC_ERROR_INVALID_ARGS);
260 + PORT_SetError(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SSL2);
263 ssl_GetSSL3HandshakeLock(ss);
268 +/* Register an application callback to be called when false start may happen.
269 +** Acquires and releases HandshakeLock.
272 +SSL_SetCanFalseStartCallback(PRFileDesc *fd, SSLCanFalseStartCallback cb,
277 + ss = ssl_FindSocket(fd);
279 + SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetCanFalseStartCallback",
280 + SSL_GETPID(), fd));
284 + if (!ss->opt.useSecurity) {
285 + PORT_SetError(SEC_ERROR_INVALID_ARGS);
289 + ssl_Get1stHandshakeLock(ss);
290 + ssl_GetSSL3HandshakeLock(ss);
292 + ss->canFalseStartCallback = cb;
293 + ss->canFalseStartCallbackData = client_data;
295 + ssl_ReleaseSSL3HandshakeLock(ss);
296 + ssl_Release1stHandshakeLock(ss);
301 +/* A utility function that can be called from a custom SSLCanFalseStartCallback
302 +** function to determine what NSS would have done for this connection if the
303 +** custom callback was not implemented.
306 +SSL_DefaultCanFalseStart(PRFileDesc *fd, PRBool *canFalseStart)
310 + *canFalseStart = PR_FALSE;
311 + ss = ssl_FindSocket(fd);
313 + SSL_DBG(("%d: SSL[%d]: bad socket in SSL_DefaultCanFalseStart",
314 + SSL_GETPID(), fd));
318 + if (!ss->ssl3.initialized) {
319 + PORT_SetError(SEC_ERROR_INVALID_ARGS);
323 + if (ss->version < SSL_LIBRARY_VERSION_3_0) {
324 + PORT_SetError(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SSL2);
328 + /* Require a forward-secret key exchange. */
329 + *canFalseStart = ss->ssl3.hs.kea_def->kea == kea_dhe_dss ||
330 + ss->ssl3.hs.kea_def->kea == kea_dhe_rsa ||
331 + ss->ssl3.hs.kea_def->kea == kea_ecdhe_ecdsa ||
332 + ss->ssl3.hs.kea_def->kea == kea_ecdhe_rsa;
337 /* Try to make progress on an SSL handshake by attempting to read the
338 ** next handshake from the peer, and sending any responses.
339 ** For non-blocking sockets, returns PR_ERROR_WOULD_BLOCK if it cannot
340 @@ -1195,12 +1258,7 @@
341 ssl_Get1stHandshakeLock(ss);
342 if (ss->version >= SSL_LIBRARY_VERSION_3_0) {
343 ssl_GetSSL3HandshakeLock(ss);
344 - if ((ss->ssl3.hs.ws == wait_change_cipher ||
345 - ss->ssl3.hs.ws == wait_finished ||
346 - ss->ssl3.hs.ws == wait_new_session_ticket) &&
347 - ssl3_CanFalseStart(ss)) {
348 - canFalseStart = PR_TRUE;
350 + canFalseStart = ss->ssl3.hs.canFalseStart;
351 ssl_ReleaseSSL3HandshakeLock(ss);
353 if (!canFalseStart &&
354 Index: net/third_party/nss/ssl/sslsock.c
355 ===================================================================
356 --- net/third_party/nss/ssl/sslsock.c (revision 227363)
357 +++ net/third_party/nss/ssl/sslsock.c (working copy)
358 @@ -2457,10 +2457,14 @@
359 } else if (new_flags & PR_POLL_WRITE) {
360 /* The caller is trying to write, but the handshake is
361 ** blocked waiting for data to read, and the first
362 - ** handshake has been sent. so do NOT to poll on write.
363 + ** handshake has been sent. So do NOT to poll on write
364 + ** unless we did false start.
366 - new_flags ^= PR_POLL_WRITE; /* don't select on write. */
367 - new_flags |= PR_POLL_READ; /* do select on read. */
368 + if (!(ss->version >= SSL_LIBRARY_VERSION_3_0 &&
369 + ss->ssl3.hs.canFalseStart)) {
370 + new_flags ^= PR_POLL_WRITE; /* don't select on write. */
372 + new_flags |= PR_POLL_READ; /* do select on read. */
375 } else if ((new_flags & PR_POLL_READ) && (SSL_DataPending(fd) > 0)) {
376 Index: net/third_party/nss/ssl/ssl3con.c
377 ===================================================================
378 --- net/third_party/nss/ssl/ssl3con.c (revision 227363)
379 +++ net/third_party/nss/ssl/ssl3con.c (working copy)
380 @@ -2890,7 +2890,7 @@
381 SSL_TRC(3, ("%d: SSL3[%d] SendRecord type: %s nIn=%d",
382 SSL_GETPID(), ss->fd, ssl3_DecodeContentType(type),
384 - PRINT_BUF(3, (ss, "Send record (plain text)", pIn, nIn));
385 + PRINT_BUF(50, (ss, "Send record (plain text)", pIn, nIn));
387 PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) );
389 @@ -7344,35 +7344,42 @@
394 -ssl3_CanFalseStart(sslSocket *ss) {
397 +ssl3_CheckFalseStart(sslSocket *ss)
400 + PRBool maybeFalseStart = PR_TRUE;
402 PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
403 + PORT_Assert( !ss->ssl3.hs.authCertificatePending );
405 - /* XXX: does not take into account whether we are waiting for
406 - * SSL_AuthCertificateComplete or SSL_RestartHandshakeAfterCertReq. If/when
407 - * that is done, this function could return different results each time it
410 + /* An attacker can control the selected ciphersuite so we only wish to
411 + * do False Start in the case that the selected ciphersuite is
412 + * sufficiently strong that the attack can gain no advantage.
413 + * Therefore we always require an 80-bit cipher. */
415 ssl_GetSpecReadLock(ss);
416 - rv = ss->opt.enableFalseStart &&
417 - !ss->sec.isServer &&
418 - !ss->ssl3.hs.isResuming &&
420 + if (ss->ssl3.cwSpec->cipher_def->secret_key_size < 10) {
421 + ss->ssl3.hs.canFalseStart = PR_FALSE;
422 + maybeFalseStart = PR_FALSE;
424 + ssl_ReleaseSpecReadLock(ss);
425 + if (!maybeFalseStart) {
429 - /* An attacker can control the selected ciphersuite so we only wish to
430 - * do False Start in the case that the selected ciphersuite is
431 - * sufficiently strong that the attack can gain no advantage.
432 - * Therefore we require an 80-bit cipher and a forward-secret key
434 - ss->ssl3.cwSpec->cipher_def->secret_key_size >= 10 &&
435 - (ss->ssl3.hs.kea_def->kea == kea_dhe_dss ||
436 - ss->ssl3.hs.kea_def->kea == kea_dhe_rsa ||
437 - ss->ssl3.hs.kea_def->kea == kea_ecdhe_ecdsa ||
438 - ss->ssl3.hs.kea_def->kea == kea_ecdhe_rsa);
439 - ssl_ReleaseSpecReadLock(ss);
440 + if (!ss->canFalseStartCallback) {
441 + rv = SSL_DefaultCanFalseStart(ss->fd, &ss->ssl3.hs.canFalseStart);
443 + rv = (ss->canFalseStartCallback)(ss->fd,
444 + ss->canFalseStartCallbackData,
445 + &ss->ssl3.hs.canFalseStart);
448 + if (rv != SECSuccess) {
449 + ss->ssl3.hs.canFalseStart = PR_FALSE;
455 @@ -7500,20 +7507,59 @@
456 goto loser; /* err code was set. */
459 - /* XXX: If the server's certificate hasn't been authenticated by this
460 - * point, then we may be leaking this NPN message to an attacker.
461 + /* This must be done after we've set ss->ssl3.cwSpec in
462 + * ssl3_SendChangeCipherSpecs because SSL_GetChannelInfo uses information
463 + * from cwSpec. This must be done before we call ssl3_CheckFalseStart
464 + * because the false start callback (if any) may need the information from
465 + * the functions that depend on this being set.
467 + ss->enoughFirstHsDone = PR_TRUE;
469 if (!ss->firstHsDone) {
470 + /* XXX: If the server's certificate hasn't been authenticated by this
471 + * point, then we may be leaking this NPN message to an attacker.
473 rv = ssl3_SendNextProto(ss);
474 if (rv != SECSuccess) {
475 goto loser; /* err code was set. */
479 rv = ssl3_SendEncryptedExtensions(ss);
480 if (rv != SECSuccess) {
481 goto loser; /* err code was set. */
484 + if (!ss->firstHsDone) {
485 + if (ss->opt.enableFalseStart) {
486 + if (!ss->ssl3.hs.authCertificatePending) {
487 + /* When we fix bug 589047, we will need to know whether we are
488 + * false starting before we try to flush the client second
489 + * round to the network. With that in mind, we purposefully
490 + * call ssl3_CheckFalseStart before calling ssl3_SendFinished,
491 + * which includes a call to ssl3_FlushHandshake, so that
492 + * no application develops a reliance on such flushing being
493 + * done before its false start callback is called.
495 + ssl_ReleaseXmitBufLock(ss);
496 + rv = ssl3_CheckFalseStart(ss);
497 + ssl_GetXmitBufLock(ss);
498 + if (rv != SECSuccess) {
502 + /* The certificate authentication and the server's Finished
503 + * message are racing each other. If the certificate
504 + * authentication wins, then we will try to false start in
505 + * ssl3_AuthCertificateComplete.
507 + SSL_TRC(3, ("%d: SSL3[%p]: deferring false start check because"
508 + " certificate authentication is still pending.",
509 + SSL_GETPID(), ss->fd));
514 rv = ssl3_SendFinished(ss, 0);
515 if (rv != SECSuccess) {
516 goto loser; /* err code was set. */
517 @@ -7526,8 +7572,16 @@
519 ss->ssl3.hs.ws = wait_change_cipher;
521 - /* Do the handshake callback for sslv3 here, if we can false start. */
522 - if (ss->handshakeCallback != NULL && ssl3_CanFalseStart(ss)) {
523 + if (ss->handshakeCallback &&
524 + (ss->ssl3.hs.canFalseStart && !ss->canFalseStartCallback)) {
525 + /* Call the handshake callback here for backwards compatibility with
526 + * applications that were using false start before
527 + * canFalseStartCallback was added. Note that we do this after calling
528 + * ssl3_SendFinished, which includes a call to ssl3_FlushHandshake,
529 + * just in case the application is relying on having the handshake
530 + * messages flushed to the network before its handshake callback is
533 (ss->handshakeCallback)(ss->fd, ss->handshakeCallbackData);
536 @@ -10147,13 +10201,6 @@
538 ss->ssl3.hs.authCertificatePending = PR_TRUE;
541 - /* XXX: Async cert validation and False Start don't work together
542 - * safely yet; if we leave False Start enabled, we may end up false
543 - * starting (sending application data) before we
544 - * SSL_AuthCertificateComplete has been called.
546 - ss->opt.enableFalseStart = PR_FALSE;
549 if (rv != SECSuccess) {
550 @@ -10278,6 +10325,12 @@
551 } else if (ss->ssl3.hs.restartTarget != NULL) {
552 sslRestartTarget target = ss->ssl3.hs.restartTarget;
553 ss->ssl3.hs.restartTarget = NULL;
555 + if (target == ssl3_FinishHandshake) {
556 + SSL_TRC(3,("%d: SSL3[%p]: certificate authentication lost the race"
557 + " with peer's finished message", SSL_GETPID(), ss->fd));
561 /* Even if we blocked here, we have accomplished enough to claim
562 * success. Any remaining work will be taken care of by subsequent
563 @@ -10287,7 +10340,39 @@
568 + SSL_TRC(3, ("%d: SSL3[%p]: certificate authentication won the race"
569 + " with peer's finished message", SSL_GETPID(), ss->fd));
571 + PORT_Assert(!ss->firstHsDone);
572 + PORT_Assert(!ss->sec.isServer);
573 + PORT_Assert(!ss->ssl3.hs.isResuming);
574 + PORT_Assert(ss->ssl3.hs.ws == wait_change_cipher ||
575 + ss->ssl3.hs.ws == wait_finished ||
576 + ss->ssl3.hs.ws == wait_new_session_ticket);
578 + /* ssl3_SendClientSecondRound deferred the false start check because
579 + * certificate authentication was pending, so we have to do it now.
581 + if (ss->opt.enableFalseStart &&
582 + !ss->firstHsDone &&
583 + !ss->sec.isServer &&
584 + !ss->ssl3.hs.isResuming &&
585 + (ss->ssl3.hs.ws == wait_change_cipher ||
586 + ss->ssl3.hs.ws == wait_finished ||
587 + ss->ssl3.hs.ws == wait_new_session_ticket)) {
588 + rv = ssl3_CheckFalseStart(ss);
589 + if (rv == SECSuccess &&
590 + ss->handshakeCallback &&
591 + (ss->ssl3.hs.canFalseStart && !ss->canFalseStartCallback)) {
592 + /* Call the handshake callback here for backwards compatibility
593 + * with applications that were using false start before
594 + * canFalseStartCallback was added.
596 + (ss->handshakeCallback)(ss->fd, ss->handshakeCallbackData);
604 @@ -10983,6 +11068,8 @@
606 ssl3_FinishHandshake(sslSocket * ss)
608 + PRBool falseStarted;
610 PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
611 PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
612 PORT_Assert( ss->ssl3.hs.restartTarget == NULL );
613 @@ -10990,6 +11077,7 @@
614 /* The first handshake is now completed. */
615 ss->handshake = NULL;
616 ss->firstHsDone = PR_TRUE;
617 + ss->enoughFirstHsDone = PR_TRUE;
619 if (ss->ssl3.hs.cacheSID) {
620 (*ss->sec.cache)(ss->sec.ci.sid);
621 @@ -10997,9 +11085,14 @@
624 ss->ssl3.hs.ws = idle_handshake;
625 + falseStarted = ss->ssl3.hs.canFalseStart;
626 + ss->ssl3.hs.canFalseStart = PR_FALSE; /* False Start phase is complete */
628 - /* Do the handshake callback for sslv3 here, if we cannot false start. */
629 - if (ss->handshakeCallback != NULL && !ssl3_CanFalseStart(ss)) {
630 + /* Call the handshake callback for sslv3 here, unless we called it already
631 + * for the case where false start was done without a canFalseStartCallback.
633 + if (ss->handshakeCallback &&
634 + !(falseStarted && !ss->canFalseStartCallback)) {
635 (ss->handshakeCallback)(ss->fd, ss->handshakeCallbackData);