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

Side by Side Diff: net/third_party/nss/ssl/ssl3con.c

Issue 23621040: Make SSL False Start work with asynchronous certificate validation (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Update the patch file Created 7 years, 2 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/ssl/ssl.h ('k') | net/third_party/nss/ssl/ssl3gthr.c » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* 2 /*
3 * SSL3 Protocol 3 * SSL3 Protocol
4 * 4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public 5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this 6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 7 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
8 8
9 /* TODO(ekr): Implement HelloVerifyRequest on server side. OK for now. */ 9 /* TODO(ekr): Implement HelloVerifyRequest on server side. OK for now. */
10 10
(...skipping 2872 matching lines...) Expand 10 before | Expand all | Expand 10 after
2883 PRInt32 flags) 2883 PRInt32 flags)
2884 { 2884 {
2885 sslBuffer * wrBuf = &ss->sec.writeBuf; 2885 sslBuffer * wrBuf = &ss->sec.writeBuf;
2886 SECStatus rv; 2886 SECStatus rv;
2887 PRInt32 totalSent = 0; 2887 PRInt32 totalSent = 0;
2888 PRBool capRecordVersion; 2888 PRBool capRecordVersion;
2889 2889
2890 SSL_TRC(3, ("%d: SSL3[%d] SendRecord type: %s nIn=%d", 2890 SSL_TRC(3, ("%d: SSL3[%d] SendRecord type: %s nIn=%d",
2891 SSL_GETPID(), ss->fd, ssl3_DecodeContentType(type), 2891 SSL_GETPID(), ss->fd, ssl3_DecodeContentType(type),
2892 nIn)); 2892 nIn));
2893 PRINT_BUF(3, (ss, "Send record (plain text)", pIn, nIn)); 2893 PRINT_BUF(50, (ss, "Send record (plain text)", pIn, nIn));
2894 2894
2895 PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) ); 2895 PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) );
2896 2896
2897 capRecordVersion = ((flags & ssl_SEND_FLAG_CAP_RECORD_VERSION) != 0); 2897 capRecordVersion = ((flags & ssl_SEND_FLAG_CAP_RECORD_VERSION) != 0);
2898 2898
2899 if (capRecordVersion) { 2899 if (capRecordVersion) {
2900 /* ssl_SEND_FLAG_CAP_RECORD_VERSION can only be used with the 2900 /* ssl_SEND_FLAG_CAP_RECORD_VERSION can only be used with the
2901 * TLS initial ClientHello. */ 2901 * TLS initial ClientHello. */
2902 PORT_Assert(!IS_DTLS(ss)); 2902 PORT_Assert(!IS_DTLS(ss));
2903 PORT_Assert(!ss->firstHsDone); 2903 PORT_Assert(!ss->firstHsDone);
(...skipping 4433 matching lines...) Expand 10 before | Expand all | Expand 10 after
7337 } 7337 }
7338 if (certChain) { 7338 if (certChain) {
7339 CERT_DestroyCertificateList(certChain); 7339 CERT_DestroyCertificateList(certChain);
7340 } 7340 }
7341 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); 7341 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
7342 rv = SECFailure; 7342 rv = SECFailure;
7343 } 7343 }
7344 return rv; 7344 return rv;
7345 } 7345 }
7346 7346
7347 PRBool 7347 static SECStatus
7348 ssl3_CanFalseStart(sslSocket *ss) { 7348 ssl3_CheckFalseStart(sslSocket *ss)
7349 PRBool rv; 7349 {
7350 SECStatus rv;
7351 PRBool maybeFalseStart = PR_TRUE;
7350 7352
7351 PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) ); 7353 PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
7354 PORT_Assert( !ss->ssl3.hs.authCertificatePending );
7352 7355
7353 /* XXX: does not take into account whether we are waiting for 7356 /* An attacker can control the selected ciphersuite so we only wish to
7354 * SSL_AuthCertificateComplete or SSL_RestartHandshakeAfterCertReq. If/when 7357 * do False Start in the case that the selected ciphersuite is
7355 * that is done, this function could return different results each time it 7358 * sufficiently strong that the attack can gain no advantage.
7356 * would be called. 7359 * Therefore we always require an 80-bit cipher. */
7357 */
7358 7360
7359 ssl_GetSpecReadLock(ss); 7361 ssl_GetSpecReadLock(ss);
7360 rv = ss->opt.enableFalseStart && 7362 if (ss->ssl3.cwSpec->cipher_def->secret_key_size < 10) {
7361 » !ss->sec.isServer && 7363 » ss->ssl3.hs.canFalseStart = PR_FALSE;
7362 » !ss->ssl3.hs.isResuming && 7364 » maybeFalseStart = PR_FALSE;
7363 » ss->ssl3.cwSpec && 7365 }
7366 ssl_ReleaseSpecReadLock(ss);
7367 if (!maybeFalseStart) {
7368 » return SECSuccess;
7369 }
7364 7370
7365 » /* An attacker can control the selected ciphersuite so we only wish to 7371 if (!ss->canFalseStartCallback) {
7366 » * do False Start in the case that the selected ciphersuite is 7372 » rv = SSL_DefaultCanFalseStart(ss->fd, &ss->ssl3.hs.canFalseStart);
7367 » * sufficiently strong that the attack can gain no advantage. 7373 } else {
7368 » * Therefore we require an 80-bit cipher and a forward-secret key 7374 » rv = (ss->canFalseStartCallback)(ss->fd,
7369 » * exchange. */ 7375 » » » » » ss->canFalseStartCallbackData,
7370 » ss->ssl3.cwSpec->cipher_def->secret_key_size >= 10 && 7376 » » » » » &ss->ssl3.hs.canFalseStart);
7371 » (ss->ssl3.hs.kea_def->kea == kea_dhe_dss || 7377 }
7372 » ss->ssl3.hs.kea_def->kea == kea_dhe_rsa || 7378
7373 » ss->ssl3.hs.kea_def->kea == kea_ecdhe_ecdsa || 7379 if (rv != SECSuccess) {
7374 » ss->ssl3.hs.kea_def->kea == kea_ecdhe_rsa); 7380 » ss->ssl3.hs.canFalseStart = PR_FALSE;
7375 ssl_ReleaseSpecReadLock(ss); 7381 }
7382
7376 return rv; 7383 return rv;
7377 } 7384 }
7378 7385
7379 static SECStatus ssl3_SendClientSecondRound(sslSocket *ss); 7386 static SECStatus ssl3_SendClientSecondRound(sslSocket *ss);
7380 7387
7381 /* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete 7388 /* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete
7382 * ssl3 Server Hello Done message. 7389 * ssl3 Server Hello Done message.
7383 * Caller must hold Handshake and RecvBuf locks. 7390 * Caller must hold Handshake and RecvBuf locks.
7384 */ 7391 */
7385 static SECStatus 7392 static SECStatus
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
7493 if (rv != SECSuccess) { 7500 if (rv != SECSuccess) {
7494 goto loser; /* err is set. */ 7501 goto loser; /* err is set. */
7495 } 7502 }
7496 } 7503 }
7497 7504
7498 rv = ssl3_SendChangeCipherSpecs(ss); 7505 rv = ssl3_SendChangeCipherSpecs(ss);
7499 if (rv != SECSuccess) { 7506 if (rv != SECSuccess) {
7500 goto loser; /* err code was set. */ 7507 goto loser; /* err code was set. */
7501 } 7508 }
7502 7509
7503 /* XXX: If the server's certificate hasn't been authenticated by this 7510 /* This must be done after we've set ss->ssl3.cwSpec in
7504 * point, then we may be leaking this NPN message to an attacker. 7511 * ssl3_SendChangeCipherSpecs because SSL_GetChannelInfo uses information
7512 * from cwSpec. This must be done before we call ssl3_CheckFalseStart
7513 * because the false start callback (if any) may need the information from
7514 * the functions that depend on this being set.
7505 */ 7515 */
7516 ss->enoughFirstHsDone = PR_TRUE;
7517
7506 if (!ss->firstHsDone) { 7518 if (!ss->firstHsDone) {
7519 /* XXX: If the server's certificate hasn't been authenticated by this
7520 * point, then we may be leaking this NPN message to an attacker.
7521 */
7507 rv = ssl3_SendNextProto(ss); 7522 rv = ssl3_SendNextProto(ss);
7508 if (rv != SECSuccess) { 7523 if (rv != SECSuccess) {
7509 goto loser; /* err code was set. */ 7524 goto loser; /* err code was set. */
7510 } 7525 }
7511 } 7526 }
7527
7512 rv = ssl3_SendEncryptedExtensions(ss); 7528 rv = ssl3_SendEncryptedExtensions(ss);
7513 if (rv != SECSuccess) { 7529 if (rv != SECSuccess) {
7514 goto loser; /* err code was set. */ 7530 goto loser; /* err code was set. */
7515 } 7531 }
7516 7532
7533 if (!ss->firstHsDone) {
7534 if (ss->opt.enableFalseStart) {
7535 if (!ss->ssl3.hs.authCertificatePending) {
7536 /* When we fix bug 589047, we will need to know whether we are
7537 * false starting before we try to flush the client second
7538 * round to the network. With that in mind, we purposefully
7539 * call ssl3_CheckFalseStart before calling ssl3_SendFinished,
7540 * which includes a call to ssl3_FlushHandshake, so that
7541 * no application develops a reliance on such flushing being
7542 * done before its false start callback is called.
7543 */
7544 ssl_ReleaseXmitBufLock(ss);
7545 rv = ssl3_CheckFalseStart(ss);
7546 ssl_GetXmitBufLock(ss);
7547 if (rv != SECSuccess) {
7548 goto loser;
7549 }
7550 } else {
7551 /* The certificate authentication and the server's Finished
7552 * message are racing each other. If the certificate
7553 * authentication wins, then we will try to false start in
7554 * ssl3_AuthCertificateComplete.
7555 */
7556 SSL_TRC(3, ("%d: SSL3[%p]: deferring false start check because"
7557 " certificate authentication is still pending.",
7558 SSL_GETPID(), ss->fd));
7559 }
7560 }
7561 }
7562
7517 rv = ssl3_SendFinished(ss, 0); 7563 rv = ssl3_SendFinished(ss, 0);
7518 if (rv != SECSuccess) { 7564 if (rv != SECSuccess) {
7519 goto loser; /* err code was set. */ 7565 goto loser; /* err code was set. */
7520 } 7566 }
7521 7567
7522 ssl_ReleaseXmitBufLock(ss); /*******************************/ 7568 ssl_ReleaseXmitBufLock(ss); /*******************************/
7523 7569
7524 if (ssl3_ExtensionNegotiated(ss, ssl_session_ticket_xtn)) 7570 if (ssl3_ExtensionNegotiated(ss, ssl_session_ticket_xtn))
7525 ss->ssl3.hs.ws = wait_new_session_ticket; 7571 ss->ssl3.hs.ws = wait_new_session_ticket;
7526 else 7572 else
7527 ss->ssl3.hs.ws = wait_change_cipher; 7573 ss->ssl3.hs.ws = wait_change_cipher;
7528 7574
7529 /* Do the handshake callback for sslv3 here, if we can false start. */ 7575 if (ss->handshakeCallback &&
7530 if (ss->handshakeCallback != NULL && ssl3_CanFalseStart(ss)) { 7576 » (ss->ssl3.hs.canFalseStart && !ss->canFalseStartCallback)) {
7577 » /* Call the handshake callback here for backwards compatibility with
7578 » * applications that were using false start before
7579 » * canFalseStartCallback was added. Note that we do this after calling
7580 » * ssl3_SendFinished, which includes a call to ssl3_FlushHandshake,
7581 » * just in case the application is relying on having the handshake
7582 » * messages flushed to the network before its handshake callback is
7583 » * called.
7584 » */
7531 (ss->handshakeCallback)(ss->fd, ss->handshakeCallbackData); 7585 (ss->handshakeCallback)(ss->fd, ss->handshakeCallbackData);
7532 } 7586 }
7533 7587
7534 return SECSuccess; 7588 return SECSuccess;
7535 7589
7536 loser: 7590 loser:
7537 ssl_ReleaseXmitBufLock(ss); 7591 ssl_ReleaseXmitBufLock(ss);
7538 return rv; 7592 return rv;
7539 } 7593 }
7540 7594
(...skipping 2599 matching lines...) Expand 10 before | Expand all | Expand 10 after
10140 10194
10141 if (rv == SECWouldBlock) { 10195 if (rv == SECWouldBlock) {
10142 if (ss->sec.isServer) { 10196 if (ss->sec.isServer) {
10143 errCode = SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SERVERS; 10197 errCode = SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SERVERS;
10144 rv = SECFailure; 10198 rv = SECFailure;
10145 goto loser; 10199 goto loser;
10146 } 10200 }
10147 10201
10148 ss->ssl3.hs.authCertificatePending = PR_TRUE; 10202 ss->ssl3.hs.authCertificatePending = PR_TRUE;
10149 rv = SECSuccess; 10203 rv = SECSuccess;
10150
10151 /* XXX: Async cert validation and False Start don't work together
10152 * safely yet; if we leave False Start enabled, we may end up false
10153 * starting (sending application data) before we
10154 * SSL_AuthCertificateComplete has been called.
10155 */
10156 ss->opt.enableFalseStart = PR_FALSE;
10157 } 10204 }
10158 10205
10159 if (rv != SECSuccess) { 10206 if (rv != SECSuccess) {
10160 ssl3_SendAlertForCertError(ss, errCode); 10207 ssl3_SendAlertForCertError(ss, errCode);
10161 goto loser; 10208 goto loser;
10162 } 10209 }
10163 } 10210 }
10164 10211
10165 ss->sec.ci.sid->peerCert = CERT_DupCertificate(ss->sec.peerCert); 10212 ss->sec.ci.sid->peerCert = CERT_DupCertificate(ss->sec.peerCert);
10166 ssl3_CopyPeerCertsToSID(ss->ssl3.peerCertChain, ss->sec.ci.sid); 10213 ssl3_CopyPeerCertsToSID(ss->ssl3.peerCertChain, ss->sec.ci.sid);
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
10271 10318
10272 ss->ssl3.hs.authCertificatePending = PR_FALSE; 10319 ss->ssl3.hs.authCertificatePending = PR_FALSE;
10273 10320
10274 if (error != 0) { 10321 if (error != 0) {
10275 ss->ssl3.hs.restartTarget = ssl3_AlwaysFail; 10322 ss->ssl3.hs.restartTarget = ssl3_AlwaysFail;
10276 ssl3_SendAlertForCertError(ss, error); 10323 ssl3_SendAlertForCertError(ss, error);
10277 rv = SECSuccess; 10324 rv = SECSuccess;
10278 } else if (ss->ssl3.hs.restartTarget != NULL) { 10325 } else if (ss->ssl3.hs.restartTarget != NULL) {
10279 sslRestartTarget target = ss->ssl3.hs.restartTarget; 10326 sslRestartTarget target = ss->ssl3.hs.restartTarget;
10280 ss->ssl3.hs.restartTarget = NULL; 10327 ss->ssl3.hs.restartTarget = NULL;
10328
10329 if (target == ssl3_FinishHandshake) {
10330 SSL_TRC(3,("%d: SSL3[%p]: certificate authentication lost the race"
10331 " with peer's finished message", SSL_GETPID(), ss->fd));
10332 }
10333
10281 rv = target(ss); 10334 rv = target(ss);
10282 /* Even if we blocked here, we have accomplished enough to claim 10335 /* Even if we blocked here, we have accomplished enough to claim
10283 * success. Any remaining work will be taken care of by subsequent 10336 * success. Any remaining work will be taken care of by subsequent
10284 * calls to SSL_ForceHandshake/PR_Send/PR_Read/etc. 10337 * calls to SSL_ForceHandshake/PR_Send/PR_Read/etc.
10285 */ 10338 */
10286 if (rv == SECWouldBlock) { 10339 if (rv == SECWouldBlock) {
10287 rv = SECSuccess; 10340 rv = SECSuccess;
10288 } 10341 }
10289 } else { 10342 } else {
10290 » rv = SECSuccess; 10343 » SSL_TRC(3, ("%d: SSL3[%p]: certificate authentication won the race"
10344 » " with peer's finished message", SSL_GETPID(), ss->fd));
10345
10346 » PORT_Assert(!ss->firstHsDone);
10347 » PORT_Assert(!ss->sec.isServer);
10348 » PORT_Assert(!ss->ssl3.hs.isResuming);
10349 » PORT_Assert(ss->ssl3.hs.ws == wait_change_cipher ||
10350 » » ss->ssl3.hs.ws == wait_finished ||» »
10351 » » ss->ssl3.hs.ws == wait_new_session_ticket);
10352
10353 » /* ssl3_SendClientSecondRound deferred the false start check because
10354 » * certificate authentication was pending, so we have to do it now.
10355 » */
10356 » if (ss->opt.enableFalseStart &&
10357 » !ss->firstHsDone &&
10358 » !ss->sec.isServer &&
10359 » !ss->ssl3.hs.isResuming &&
10360 » (ss->ssl3.hs.ws == wait_change_cipher ||
10361 » ss->ssl3.hs.ws == wait_finished ||»»
10362 » ss->ssl3.hs.ws == wait_new_session_ticket)) {
10363 » rv = ssl3_CheckFalseStart(ss);
10364 » if (rv == SECSuccess &&
10365 » » ss->handshakeCallback &&
10366 » » (ss->ssl3.hs.canFalseStart && !ss->canFalseStartCallback)) {
10367 » » /* Call the handshake callback here for backwards compatibility
10368 » » * with applications that were using false start before
10369 » » * canFalseStartCallback was added.
10370 » » */
10371 » » (ss->handshakeCallback)(ss->fd, ss->handshakeCallbackData);
10372 » }
10373 » } else {
10374 » rv = SECSuccess;
10375 » }
10291 } 10376 }
10292 10377
10293 done: 10378 done:
10294 ssl_ReleaseSSL3HandshakeLock(ss); 10379 ssl_ReleaseSSL3HandshakeLock(ss);
10295 ssl_ReleaseRecvBufLock(ss); 10380 ssl_ReleaseRecvBufLock(ss);
10296 10381
10297 return rv; 10382 return rv;
10298 } 10383 }
10299 10384
10300 static SECStatus 10385 static SECStatus
(...skipping 675 matching lines...) Expand 10 before | Expand all | Expand 10 after
10976 return SECWouldBlock; 11061 return SECWouldBlock;
10977 } 11062 }
10978 11063
10979 rv = ssl3_FinishHandshake(ss); 11064 rv = ssl3_FinishHandshake(ss);
10980 return rv; 11065 return rv;
10981 } 11066 }
10982 11067
10983 SECStatus 11068 SECStatus
10984 ssl3_FinishHandshake(sslSocket * ss) 11069 ssl3_FinishHandshake(sslSocket * ss)
10985 { 11070 {
11071 PRBool falseStarted;
11072
10986 PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) ); 11073 PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
10987 PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) ); 11074 PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
10988 PORT_Assert( ss->ssl3.hs.restartTarget == NULL ); 11075 PORT_Assert( ss->ssl3.hs.restartTarget == NULL );
10989 11076
10990 /* The first handshake is now completed. */ 11077 /* The first handshake is now completed. */
10991 ss->handshake = NULL; 11078 ss->handshake = NULL;
10992 ss->firstHsDone = PR_TRUE; 11079 ss->firstHsDone = PR_TRUE;
11080 ss->enoughFirstHsDone = PR_TRUE;
10993 11081
10994 if (ss->ssl3.hs.cacheSID) { 11082 if (ss->ssl3.hs.cacheSID) {
10995 (*ss->sec.cache)(ss->sec.ci.sid); 11083 (*ss->sec.cache)(ss->sec.ci.sid);
10996 ss->ssl3.hs.cacheSID = PR_FALSE; 11084 ss->ssl3.hs.cacheSID = PR_FALSE;
10997 } 11085 }
10998 11086
10999 ss->ssl3.hs.ws = idle_handshake; 11087 ss->ssl3.hs.ws = idle_handshake;
11088 falseStarted = ss->ssl3.hs.canFalseStart;
11089 ss->ssl3.hs.canFalseStart = PR_FALSE; /* False Start phase is complete */
11000 11090
11001 /* Do the handshake callback for sslv3 here, if we cannot false start. */ 11091 /* Call the handshake callback for sslv3 here, unless we called it already
11002 if (ss->handshakeCallback != NULL && !ssl3_CanFalseStart(ss)) { 11092 * for the case where false start was done without a canFalseStartCallback.
11093 */
11094 if (ss->handshakeCallback &&
11095 » !(falseStarted && !ss->canFalseStartCallback)) {
11003 (ss->handshakeCallback)(ss->fd, ss->handshakeCallbackData); 11096 (ss->handshakeCallback)(ss->fd, ss->handshakeCallbackData);
11004 } 11097 }
11005 11098
11006 return SECSuccess; 11099 return SECSuccess;
11007 } 11100 }
11008 11101
11009 /* Called from ssl3_HandleHandshake() when it has gathered a complete ssl3 11102 /* Called from ssl3_HandleHandshake() when it has gathered a complete ssl3
11010 * hanshake message. 11103 * hanshake message.
11011 * Caller must hold Handshake and RecvBuf locks. 11104 * Caller must hold Handshake and RecvBuf locks.
11012 */ 11105 */
(...skipping 1457 matching lines...) Expand 10 before | Expand all | Expand 10 after
12470 PORT_Free(ss->ssl3.hs.recvdFragments.buf); 12563 PORT_Free(ss->ssl3.hs.recvdFragments.buf);
12471 } 12564 }
12472 } 12565 }
12473 12566
12474 ss->ssl3.initialized = PR_FALSE; 12567 ss->ssl3.initialized = PR_FALSE;
12475 12568
12476 SECITEM_FreeItem(&ss->ssl3.nextProto, PR_FALSE); 12569 SECITEM_FreeItem(&ss->ssl3.nextProto, PR_FALSE);
12477 } 12570 }
12478 12571
12479 /* End of ssl3con.c */ 12572 /* End of ssl3con.c */
OLDNEW
« no previous file with comments | « net/third_party/nss/ssl/ssl.h ('k') | net/third_party/nss/ssl/ssl3gthr.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698