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

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

Issue 27254004: Make SSL False Start work with asynchronous certificate validation (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: What was checked in to NSS upstream Created 7 years, 1 month 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
OLDNEW
1 /* 1 /*
2 * Various SSL functions. 2 * Various SSL functions.
3 * 3 *
4 * This Source Code Form is subject to the terms of the Mozilla Public 4 * This Source Code Form is subject to the terms of the Mozilla Public
5 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * License, v. 2.0. If a copy of the MPL was not distributed with this
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "cert.h" 7 #include "cert.h"
8 #include "secitem.h" 8 #include "secitem.h"
9 #include "keyhi.h" 9 #include "keyhi.h"
10 #include "ssl.h" 10 #include "ssl.h"
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
90 /* Previous handshake finished. Switch to next one */ 90 /* Previous handshake finished. Switch to next one */
91 ss->handshake = ss->nextHandshake; 91 ss->handshake = ss->nextHandshake;
92 ss->nextHandshake = 0; 92 ss->nextHandshake = 0;
93 } 93 }
94 if (ss->handshake == 0) { 94 if (ss->handshake == 0) {
95 /* Previous handshake finished. Switch to security handshake */ 95 /* Previous handshake finished. Switch to security handshake */
96 ss->handshake = ss->securityHandshake; 96 ss->handshake = ss->securityHandshake;
97 ss->securityHandshake = 0; 97 ss->securityHandshake = 0;
98 } 98 }
99 if (ss->handshake == 0) { 99 if (ss->handshake == 0) {
100 » ssl_GetRecvBufLock(ss); 100 » /* for v3 this is done in ssl3_FinishHandshake */
101 » ss->gs.recordLen = 0; 101 » if (!ss->firstHsDone && ss->version < SSL_LIBRARY_VERSION_3_0) {
102 » ssl_ReleaseRecvBufLock(ss); 102 » » ssl_GetRecvBufLock(ss);
103 103 » » ss->gs.recordLen = 0;
104 » SSL_TRC(3, ("%d: SSL[%d]: handshake is completed", 104 » » ssl_FinishHandshake(ss);
105 » » » SSL_GETPID(), ss->fd)); 105 » » ssl_ReleaseRecvBufLock(ss);
106 /* call handshake callback for ssl v2 */
107 » /* for v3 this is done in ssl3_HandleFinished() */
108 » if ((ss->handshakeCallback != NULL) && /* has callback */
109 » » (!ss->firstHsDone) && /* only first time */
110 » » (ss->version < SSL_LIBRARY_VERSION_3_0)) { /* not ssl3 */
111 » » ss->firstHsDone = PR_TRUE;
112 » » (ss->handshakeCallback)(ss->fd, ss->handshakeCallbackData);
113 } 106 }
114 ss->firstHsDone = PR_TRUE;
115 ss->gs.writeOffset = 0;
116 ss->gs.readOffset = 0;
117 break; 107 break;
118 } 108 }
119 rv = (*ss->handshake)(ss); 109 rv = (*ss->handshake)(ss);
120 ++loopCount; 110 ++loopCount;
121 /* This code must continue to loop on SECWouldBlock, 111 /* This code must continue to loop on SECWouldBlock,
122 * or any positive value. See XXX_1 comments. 112 * or any positive value. See XXX_1 comments.
123 */ 113 */
124 } while (rv != SECFailure); /* was (rv >= 0); XXX_1 */ 114 } while (rv != SECFailure); /* was (rv >= 0); XXX_1 */
125 115
126 PORT_Assert(ss->opt.noLocks || !ssl_HaveRecvBufLock(ss)); 116 PORT_Assert(ss->opt.noLocks || !ssl_HaveRecvBufLock(ss));
127 PORT_Assert(ss->opt.noLocks || !ssl_HaveXmitBufLock(ss)); 117 PORT_Assert(ss->opt.noLocks || !ssl_HaveXmitBufLock(ss));
128 PORT_Assert(ss->opt.noLocks || !ssl_HaveSSL3HandshakeLock(ss)); 118 PORT_Assert(ss->opt.noLocks || !ssl_HaveSSL3HandshakeLock(ss));
129 119
130 if (rv == SECWouldBlock) { 120 if (rv == SECWouldBlock) {
131 PORT_SetError(PR_WOULD_BLOCK_ERROR); 121 PORT_SetError(PR_WOULD_BLOCK_ERROR);
132 rv = SECFailure; 122 rv = SECFailure;
133 } 123 }
134 return rv; 124 return rv;
135 } 125 }
136 126
127 void
128 ssl_FinishHandshake(sslSocket *ss)
129 {
130 PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
131 PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
132
133 SSL_TRC(3, ("%d: SSL[%d]: handshake is completed", SSL_GETPID(), ss->fd));
134
135 ss->firstHsDone = PR_TRUE;
136 ss->enoughFirstHsDone = PR_TRUE;
137 ss->gs.writeOffset = 0;
138 ss->gs.readOffset = 0;
139
140 if (ss->handshakeCallback) {
141 (ss->handshakeCallback)(ss->fd, ss->handshakeCallbackData);
142 }
143 }
144
137 /* 145 /*
138 * Handshake function that blocks. Used to force a 146 * Handshake function that blocks. Used to force a
139 * retry on a connection on the next read/write. 147 * retry on a connection on the next read/write.
140 */ 148 */
141 static SECStatus 149 static SECStatus
142 ssl3_AlwaysBlock(sslSocket *ss) 150 ssl3_AlwaysBlock(sslSocket *ss)
143 { 151 {
144 PORT_SetError(PR_WOULD_BLOCK_ERROR); /* perhaps redundant. */ 152 PORT_SetError(PR_WOULD_BLOCK_ERROR); /* perhaps redundant. */
145 return SECWouldBlock; 153 return SECWouldBlock;
146 } 154 }
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
199 if (!ss->opt.useSecurity) 207 if (!ss->opt.useSecurity)
200 return SECSuccess; 208 return SECSuccess;
201 209
202 SSL_LOCK_READER(ss); 210 SSL_LOCK_READER(ss);
203 SSL_LOCK_WRITER(ss); 211 SSL_LOCK_WRITER(ss);
204 212
205 /* Reset handshake state */ 213 /* Reset handshake state */
206 ssl_Get1stHandshakeLock(ss); 214 ssl_Get1stHandshakeLock(ss);
207 215
208 ss->firstHsDone = PR_FALSE; 216 ss->firstHsDone = PR_FALSE;
217 ss->enoughFirstHsDone = PR_FALSE;
209 if ( asServer ) { 218 if ( asServer ) {
210 ss->handshake = ssl2_BeginServerHandshake; 219 ss->handshake = ssl2_BeginServerHandshake;
211 ss->handshaking = sslHandshakingAsServer; 220 ss->handshaking = sslHandshakingAsServer;
212 } else { 221 } else {
213 ss->handshake = ssl2_BeginClientHandshake; 222 ss->handshake = ssl2_BeginClientHandshake;
214 ss->handshaking = sslHandshakingAsClient; 223 ss->handshaking = sslHandshakingAsClient;
215 } 224 }
216 ss->nextHandshake = 0; 225 ss->nextHandshake = 0;
217 ss->securityHandshake = 0; 226 ss->securityHandshake = 0;
218 227
219 ssl_GetRecvBufLock(ss); 228 ssl_GetRecvBufLock(ss);
220 status = ssl_InitGather(&ss->gs); 229 status = ssl_InitGather(&ss->gs);
221 ssl_ReleaseRecvBufLock(ss); 230 ssl_ReleaseRecvBufLock(ss);
222 231
223 ssl_GetSSL3HandshakeLock(ss); 232 ssl_GetSSL3HandshakeLock(ss);
233 ss->ssl3.hs.canFalseStart = PR_FALSE;
234 ss->ssl3.hs.restartTarget = NULL;
224 235
225 /* 236 /*
226 ** Blow away old security state and get a fresh setup. 237 ** Blow away old security state and get a fresh setup.
227 */ 238 */
228 ssl_GetXmitBufLock(ss); 239 ssl_GetXmitBufLock(ss);
229 ssl_ResetSecurityInfo(&ss->sec, PR_TRUE); 240 ssl_ResetSecurityInfo(&ss->sec, PR_TRUE);
230 status = ssl_CreateSecurityInfo(ss); 241 status = ssl_CreateSecurityInfo(ss);
231 ssl_ReleaseXmitBufLock(ss); 242 ssl_ReleaseXmitBufLock(ss);
232 243
233 ssl_ReleaseSSL3HandshakeLock(ss); 244 ssl_ReleaseSSL3HandshakeLock(ss);
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
324 335
325 ss->handshakeCallback = cb; 336 ss->handshakeCallback = cb;
326 ss->handshakeCallbackData = client_data; 337 ss->handshakeCallbackData = client_data;
327 338
328 ssl_ReleaseSSL3HandshakeLock(ss); 339 ssl_ReleaseSSL3HandshakeLock(ss);
329 ssl_Release1stHandshakeLock(ss); 340 ssl_Release1stHandshakeLock(ss);
330 341
331 return SECSuccess; 342 return SECSuccess;
332 } 343 }
333 344
345 /* Register an application callback to be called when false start may happen.
346 ** Acquires and releases HandshakeLock.
347 */
348 SECStatus
349 SSL_SetCanFalseStartCallback(PRFileDesc *fd, SSLCanFalseStartCallback cb,
350 void *arg)
351 {
352 sslSocket *ss;
353
354 ss = ssl_FindSocket(fd);
355 if (!ss) {
356 SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetCanFalseStartCallback",
357 SSL_GETPID(), fd));
358 return SECFailure;
359 }
360
361 if (!ss->opt.useSecurity) {
362 PORT_SetError(SEC_ERROR_INVALID_ARGS);
363 return SECFailure;
364 }
365
366 ssl_Get1stHandshakeLock(ss);
367 ssl_GetSSL3HandshakeLock(ss);
368
369 ss->canFalseStartCallback = cb;
370 ss->canFalseStartCallbackData = arg;
371
372 ssl_ReleaseSSL3HandshakeLock(ss);
373 ssl_Release1stHandshakeLock(ss);
374
375 return SECSuccess;
376 }
377
378 SECStatus
379 SSL_RecommendedCanFalseStart(PRFileDesc *fd, PRBool *canFalseStart)
380 {
381 sslSocket *ss;
382
383 *canFalseStart = PR_FALSE;
384 ss = ssl_FindSocket(fd);
385 if (!ss) {
386 SSL_DBG(("%d: SSL[%d]: bad socket in SSL_RecommendedCanFalseStart",
387 SSL_GETPID(), fd));
388 return SECFailure;
389 }
390
391 if (!ss->ssl3.initialized) {
392 PORT_SetError(SEC_ERROR_INVALID_ARGS);
393 return SECFailure;
394 }
395
396 if (ss->version < SSL_LIBRARY_VERSION_3_0) {
397 PORT_SetError(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SSL2);
398 return SECFailure;
399 }
400
401 /* Require a forward-secret key exchange. */
402 *canFalseStart = ss->ssl3.hs.kea_def->kea == kea_dhe_dss ||
403 ss->ssl3.hs.kea_def->kea == kea_dhe_rsa ||
404 ss->ssl3.hs.kea_def->kea == kea_ecdhe_ecdsa ||
405 ss->ssl3.hs.kea_def->kea == kea_ecdhe_rsa;
406
407 return SECSuccess;
408 }
409
334 /* Try to make progress on an SSL handshake by attempting to read the 410 /* Try to make progress on an SSL handshake by attempting to read the
335 ** next handshake from the peer, and sending any responses. 411 ** next handshake from the peer, and sending any responses.
336 ** For non-blocking sockets, returns PR_ERROR_WOULD_BLOCK if it cannot 412 ** For non-blocking sockets, returns PR_ERROR_WOULD_BLOCK if it cannot
337 ** read the next handshake from the underlying socket. 413 ** read the next handshake from the underlying socket.
338 ** For SSLv2, returns when handshake is complete or fatal error occurs. 414 ** For SSLv2, returns when handshake is complete or fatal error occurs.
339 ** For SSLv3, returns when handshake is complete, or application data has 415 ** For SSLv3, returns when handshake is complete, or application data has
340 ** arrived that must be taken by application before handshake can continue, 416 ** arrived that must be taken by application before handshake can continue,
341 ** or a fatal error occurs. 417 ** or a fatal error occurs.
342 ** Application should use handshake completion callback to tell which. 418 ** Application should use handshake completion callback to tell which.
343 */ 419 */
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
517 ** This code is similar to, and easily confused with, 593 ** This code is similar to, and easily confused with,
518 ** ssl_GatherRecord1stHandshake() in sslcon.c 594 ** ssl_GatherRecord1stHandshake() in sslcon.c
519 */ 595 */
520 static int 596 static int
521 DoRecv(sslSocket *ss, unsigned char *out, int len, int flags) 597 DoRecv(sslSocket *ss, unsigned char *out, int len, int flags)
522 { 598 {
523 int rv; 599 int rv;
524 int amount; 600 int amount;
525 int available; 601 int available;
526 602
603 /* ssl3_GatherAppDataRecord may call ssl_FinishHandshake, which needs the
604 * 1stHandshakeLock. */
605 ssl_Get1stHandshakeLock(ss);
527 ssl_GetRecvBufLock(ss); 606 ssl_GetRecvBufLock(ss);
528 607
529 available = ss->gs.writeOffset - ss->gs.readOffset; 608 available = ss->gs.writeOffset - ss->gs.readOffset;
530 if (available == 0) { 609 if (available == 0) {
531 /* Get some more data */ 610 /* Get some more data */
532 if (ss->version >= SSL_LIBRARY_VERSION_3_0) { 611 if (ss->version >= SSL_LIBRARY_VERSION_3_0) {
533 /* Wait for application data to arrive. */ 612 /* Wait for application data to arrive. */
534 rv = ssl3_GatherAppDataRecord(ss, 0); 613 rv = ssl3_GatherAppDataRecord(ss, 0);
535 } else { 614 } else {
536 /* See if we have a complete record */ 615 /* See if we have a complete record */
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
583 } 662 }
584 PORT_Assert(ss->gs.readOffset <= ss->gs.writeOffset); 663 PORT_Assert(ss->gs.readOffset <= ss->gs.writeOffset);
585 rv = amount; 664 rv = amount;
586 665
587 SSL_TRC(30, ("%d: SSL[%d]: amount=%d available=%d", 666 SSL_TRC(30, ("%d: SSL[%d]: amount=%d available=%d",
588 SSL_GETPID(), ss->fd, amount, available)); 667 SSL_GETPID(), ss->fd, amount, available));
589 PRINT_BUF(4, (ss, "DoRecv receiving plaintext:", out, amount)); 668 PRINT_BUF(4, (ss, "DoRecv receiving plaintext:", out, amount));
590 669
591 done: 670 done:
592 ssl_ReleaseRecvBufLock(ss); 671 ssl_ReleaseRecvBufLock(ss);
672 ssl_Release1stHandshakeLock(ss);
593 return rv; 673 return rv;
594 } 674 }
595 675
596 /************************************************************************/ 676 /************************************************************************/
597 677
598 /* 678 /*
599 ** Return SSLKEAType derived from cert's Public Key algorithm info. 679 ** Return SSLKEAType derived from cert's Public Key algorithm info.
600 */ 680 */
601 SSLKEAType 681 SSLKEAType
602 NSS_FindCertKEAType(CERTCertificate * cert) 682 NSS_FindCertKEAType(CERTCertificate * cert)
(...skipping 546 matching lines...) Expand 10 before | Expand all | Expand 10 after
1149 int 1229 int
1150 ssl_SecureRead(sslSocket *ss, unsigned char *buf, int len) 1230 ssl_SecureRead(sslSocket *ss, unsigned char *buf, int len)
1151 { 1231 {
1152 return ssl_SecureRecv(ss, buf, len, 0); 1232 return ssl_SecureRecv(ss, buf, len, 0);
1153 } 1233 }
1154 1234
1155 /* Caller holds the SSL Socket's write lock. SSL_LOCK_WRITER(ss) */ 1235 /* Caller holds the SSL Socket's write lock. SSL_LOCK_WRITER(ss) */
1156 int 1236 int
1157 ssl_SecureSend(sslSocket *ss, const unsigned char *buf, int len, int flags) 1237 ssl_SecureSend(sslSocket *ss, const unsigned char *buf, int len, int flags)
1158 { 1238 {
1159 int rv»» = 0; 1239 int rv = 0;
1240 PRBool falseStart = PR_FALSE;
1160 1241
1161 SSL_TRC(2, ("%d: SSL[%d]: SecureSend: sending %d bytes", 1242 SSL_TRC(2, ("%d: SSL[%d]: SecureSend: sending %d bytes",
1162 SSL_GETPID(), ss->fd, len)); 1243 SSL_GETPID(), ss->fd, len));
1163 1244
1164 if (ss->shutdownHow & ssl_SHUTDOWN_SEND) { 1245 if (ss->shutdownHow & ssl_SHUTDOWN_SEND) {
1165 PORT_SetError(PR_SOCKET_SHUTDOWN_ERROR); 1246 PORT_SetError(PR_SOCKET_SHUTDOWN_ERROR);
1166 rv = PR_FAILURE; 1247 rv = PR_FAILURE;
1167 goto done; 1248 goto done;
1168 } 1249 }
1169 if (flags) { 1250 if (flags) {
(...skipping 14 matching lines...) Expand all
1184 } 1265 }
1185 ssl_ReleaseXmitBufLock(ss); 1266 ssl_ReleaseXmitBufLock(ss);
1186 if (rv < 0) { 1267 if (rv < 0) {
1187 goto done; 1268 goto done;
1188 } 1269 }
1189 1270
1190 if (len > 0) 1271 if (len > 0)
1191 ss->writerThread = PR_GetCurrentThread(); 1272 ss->writerThread = PR_GetCurrentThread();
1192 /* If any of these is non-zero, the initial handshake is not done. */ 1273 /* If any of these is non-zero, the initial handshake is not done. */
1193 if (!ss->firstHsDone) { 1274 if (!ss->firstHsDone) {
1194 PRBool canFalseStart = PR_FALSE;
1195 ssl_Get1stHandshakeLock(ss); 1275 ssl_Get1stHandshakeLock(ss);
1196 » if (ss->version >= SSL_LIBRARY_VERSION_3_0) { 1276 » if (ss->opt.enableFalseStart &&
1277 » ss->version >= SSL_LIBRARY_VERSION_3_0) {
1197 ssl_GetSSL3HandshakeLock(ss); 1278 ssl_GetSSL3HandshakeLock(ss);
1198 » if ((ss->ssl3.hs.ws == wait_change_cipher || 1279 » falseStart = ss->ssl3.hs.canFalseStart;
1199 » » ss->ssl3.hs.ws == wait_finished ||
1200 » » ss->ssl3.hs.ws == wait_new_session_ticket) &&
1201 » » ssl3_CanFalseStart(ss)) {
1202 » » canFalseStart = PR_TRUE;
1203 » }
1204 ssl_ReleaseSSL3HandshakeLock(ss); 1280 ssl_ReleaseSSL3HandshakeLock(ss);
1205 } 1281 }
1206 » if (!canFalseStart && 1282 » if (!falseStart &&
1207 (ss->handshake || ss->nextHandshake || ss->securityHandshake)) { 1283 (ss->handshake || ss->nextHandshake || ss->securityHandshake)) {
1208 rv = ssl_Do1stHandshake(ss); 1284 rv = ssl_Do1stHandshake(ss);
1209 } 1285 }
1210 ssl_Release1stHandshakeLock(ss); 1286 ssl_Release1stHandshakeLock(ss);
1211 } 1287 }
1212 if (rv < 0) { 1288 if (rv < 0) {
1213 ss->writerThread = NULL; 1289 ss->writerThread = NULL;
1214 goto done; 1290 goto done;
1215 } 1291 }
1216 1292
1217 /* Check for zero length writes after we do housekeeping so we make forward 1293 /* Check for zero length writes after we do housekeeping so we make forward
1218 * progress. 1294 * progress.
1219 */ 1295 */
1220 if (len == 0) { 1296 if (len == 0) {
1221 rv = 0; 1297 rv = 0;
1222 goto done; 1298 goto done;
1223 } 1299 }
1224 PORT_Assert(buf != NULL); 1300 PORT_Assert(buf != NULL);
1225 if (!buf) { 1301 if (!buf) {
1226 PORT_SetError(PR_INVALID_ARGUMENT_ERROR); 1302 PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
1227 rv = PR_FAILURE; 1303 rv = PR_FAILURE;
1228 goto done; 1304 goto done;
1229 } 1305 }
1230 1306
1307 if (!ss->firstHsDone) {
1308 PORT_Assert(ss->version >= SSL_LIBRARY_VERSION_3_0);
1309 #ifdef DEBUG
1310 ssl_GetSSL3HandshakeLock(ss);
1311 PORT_Assert(ss->ssl3.hs.canFalseStart);
1312 ssl_ReleaseSSL3HandshakeLock(ss);
1313 #endif
1314 SSL_TRC(3, ("%d: SSL[%d]: SecureSend: sending data due to false start",
1315 SSL_GETPID(), ss->fd));
1316 }
1317
1231 /* Send out the data using one of these functions: 1318 /* Send out the data using one of these functions:
1232 * ssl2_SendClear, ssl2_SendStream, ssl2_SendBlock, 1319 * ssl2_SendClear, ssl2_SendStream, ssl2_SendBlock,
1233 * ssl3_SendApplicationData 1320 * ssl3_SendApplicationData
1234 */ 1321 */
1235 ssl_GetXmitBufLock(ss); 1322 ssl_GetXmitBufLock(ss);
1236 rv = (*ss->sec.send)(ss, buf, len, flags); 1323 rv = (*ss->sec.send)(ss, buf, len, flags);
1237 ssl_ReleaseXmitBufLock(ss); 1324 ssl_ReleaseXmitBufLock(ss);
1238 ss->writerThread = NULL; 1325 ss->writerThread = NULL;
1239 done: 1326 done:
1240 if (rv < 0) { 1327 if (rv < 0) {
(...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after
1589 if (!ss) { 1676 if (!ss) {
1590 SSL_DBG(("%d: SSL[%d]: bad socket in SNISocketConfigHook", 1677 SSL_DBG(("%d: SSL[%d]: bad socket in SNISocketConfigHook",
1591 SSL_GETPID(), fd)); 1678 SSL_GETPID(), fd));
1592 return SECFailure; 1679 return SECFailure;
1593 } 1680 }
1594 1681
1595 ss->sniSocketConfig = func; 1682 ss->sniSocketConfig = func;
1596 ss->sniSocketConfigArg = arg; 1683 ss->sniSocketConfigArg = arg;
1597 return SECSuccess; 1684 return SECSuccess;
1598 } 1685 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698