Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(36)

Side by Side Diff: net/third_party/nss/patches/canfalsestart.patch

Issue 111853013: Update net/third_party/nss to NSS 3.15.4. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Update the comment in sslenum.c for the two CHACHA20 cipher suites Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « net/third_party/nss/patches/cachelocks.patch ('k') | net/third_party/nss/patches/cbc.patch » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 Index: 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 depen d
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
79 Index: 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 sti ll
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 /*
380 Index: 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 ove r
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);
479 Index: 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 {
507 Index: 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,
561 Index: 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;
589 Index: 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
807 Index: 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)) {
OLDNEW
« no previous file with comments | « net/third_party/nss/patches/cachelocks.patch ('k') | net/third_party/nss/patches/cbc.patch » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698