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

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

Issue 27254004: Make SSL False Start work with asynchronous certificate validation (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Resolve merge conflict in ssl3_SendClientSecondRound 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
OLDNEW
1 /* 1 /*
2 * Gather (Read) entire SSL3 records from socket into buffer. 2 * Gather (Read) entire SSL3 records from socket into buffer.
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 7
8 #include "cert.h" 8 #include "cert.h"
9 #include "ssl.h" 9 #include "ssl.h"
10 #include "sslimpl.h" 10 #include "sslimpl.h"
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after
268 * and from SSL_ForceHandshake in sslsecur.c 268 * and from SSL_ForceHandshake in sslsecur.c
269 * and from ssl3_GatherAppDataRecord below (<- DoRecv in sslsecur.c). 269 * and from ssl3_GatherAppDataRecord below (<- DoRecv in sslsecur.c).
270 * 270 *
271 * Caller must hold the recv buf lock. 271 * Caller must hold the recv buf lock.
272 */ 272 */
273 int 273 int
274 ssl3_GatherCompleteHandshake(sslSocket *ss, int flags) 274 ssl3_GatherCompleteHandshake(sslSocket *ss, int flags)
275 { 275 {
276 SSL3Ciphertext cText; 276 SSL3Ciphertext cText;
277 int rv; 277 int rv;
278 PRBool canFalseStart = PR_FALSE;
279 278
280 SSL_TRC(30, ("ssl3_GatherCompleteHandshake")); 279 SSL_TRC(30, ("ssl3_GatherCompleteHandshake"));
281 280
282 PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) ); 281 PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
282
283 ssl_GetSSL3HandshakeLock(ss);
284
283 do { 285 do {
284 PRBool handleRecordNow = PR_FALSE; 286 PRBool handleRecordNow = PR_FALSE;
285 287
286 ssl_GetSSL3HandshakeLock(ss);
287
288 /* Without this, we may end up wrongly reporting 288 /* Without this, we may end up wrongly reporting
289 * SSL_ERROR_RX_UNEXPECTED_* errors if we receive any records from the 289 * SSL_ERROR_RX_UNEXPECTED_* errors if we receive any records from the
290 * peer while we are waiting to be restarted. 290 * peer while we are waiting to be restarted.
291 */ 291 */
292 if (ss->ssl3.hs.restartTarget) { 292 if (ss->ssl3.hs.restartTarget) {
293 ssl_ReleaseSSL3HandshakeLock(ss);
294 PORT_SetError(PR_WOULD_BLOCK_ERROR); 293 PORT_SetError(PR_WOULD_BLOCK_ERROR);
295 » return (int) SECFailure; 294 » rv = (int) SECFailure;
295 » goto done;
296 } 296 }
297 297
298 /* Treat an empty msgState like a NULL msgState. (Most of the time 298 /* Treat an empty msgState like a NULL msgState. (Most of the time
299 * when ssl3_HandleHandshake returns SECWouldBlock, it leaves 299 * when ssl3_HandleHandshake returns SECWouldBlock, it leaves
300 * behind a non-NULL but zero-length msgState). 300 * behind a non-NULL but zero-length msgState).
301 * Test: async_cert_restart_server_sends_hello_request_first_in_separate _record 301 * Test: async_cert_restart_server_sends_hello_request_first_in_separate _record
302 */ 302 */
303 if (ss->ssl3.hs.msgState.buf) { 303 if (ss->ssl3.hs.msgState.buf) {
304 if (ss->ssl3.hs.msgState.len == 0) { 304 if (ss->ssl3.hs.msgState.len == 0) {
305 ss->ssl3.hs.msgState.buf = NULL; 305 ss->ssl3.hs.msgState.buf = NULL;
306 } else { 306 } else {
307 handleRecordNow = PR_TRUE; 307 handleRecordNow = PR_TRUE;
308 } 308 }
309 } 309 }
310 310
311 ssl_ReleaseSSL3HandshakeLock(ss);
312
313 if (handleRecordNow) { 311 if (handleRecordNow) {
314 /* ssl3_HandleHandshake previously returned SECWouldBlock and the 312 /* ssl3_HandleHandshake previously returned SECWouldBlock and the
315 * as-yet-unprocessed plaintext of that previous handshake record. 313 * as-yet-unprocessed plaintext of that previous handshake record.
316 * We need to process it now before we overwrite it with the next 314 * We need to process it now before we overwrite it with the next
317 * handshake record. 315 * handshake record.
318 */ 316 */
319 rv = ssl3_HandleRecord(ss, NULL, &ss->gs.buf); 317 rv = ssl3_HandleRecord(ss, NULL, &ss->gs.buf);
320 } else { 318 } else {
321 /* bring in the next sslv3 record. */ 319 /* bring in the next sslv3 record. */
322 if (!IS_DTLS(ss)) { 320 if (!IS_DTLS(ss)) {
323 rv = ssl3_GatherData(ss, &ss->gs, flags); 321 rv = ssl3_GatherData(ss, &ss->gs, flags);
324 } else { 322 } else {
325 rv = dtls_GatherData(ss, &ss->gs, flags); 323 rv = dtls_GatherData(ss, &ss->gs, flags);
wtc 2013/10/17 15:28:14 I agree we should be holding the SSL3HandshakeLock
326 324
327 /* If we got a would block error, that means that no data was 325 /* If we got a would block error, that means that no data was
328 * available, so we check the timer to see if it's time to 326 * available, so we check the timer to see if it's time to
329 * retransmit */ 327 * retransmit */
330 if (rv == SECFailure && 328 if (rv == SECFailure &&
331 (PORT_GetError() == PR_WOULD_BLOCK_ERROR)) { 329 (PORT_GetError() == PR_WOULD_BLOCK_ERROR)) {
332 ssl_GetSSL3HandshakeLock(ss);
333 dtls_CheckTimer(ss); 330 dtls_CheckTimer(ss);
334 ssl_ReleaseSSL3HandshakeLock(ss);
335 /* Restore the error in case something succeeded */ 331 /* Restore the error in case something succeeded */
336 PORT_SetError(PR_WOULD_BLOCK_ERROR); 332 PORT_SetError(PR_WOULD_BLOCK_ERROR);
337 } 333 }
338 } 334 }
339 335
336 PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
wtc 2013/10/17 00:10:53 Is this assertion necessary? We already checked th
briansmith 2013/10/17 01:42:40 Done.
337
340 if (rv <= 0) { 338 if (rv <= 0) {
341 » » return rv; 339 » » goto done;
342 } 340 }
343 341
344 /* decipher it, and handle it if it's a handshake. 342 /* decipher it, and handle it if it's a handshake.
345 * If it's application data, ss->gs.buf will not be empty upon retur n. 343 * If it's application data, ss->gs.buf will not be empty upon retur n.
346 * If it's a change cipher spec, alert, or handshake message, 344 * If it's a change cipher spec, alert, or handshake message,
347 * ss->gs.buf.len will be 0 when ssl3_HandleRecord returns SECSucces s. 345 * ss->gs.buf.len will be 0 when ssl3_HandleRecord returns SECSucces s.
348 */ 346 */
349 cText.type = (SSL3ContentType)ss->gs.hdr[0]; 347 cText.type = (SSL3ContentType)ss->gs.hdr[0];
350 cText.version = (ss->gs.hdr[1] << 8) | ss->gs.hdr[2]; 348 cText.version = (ss->gs.hdr[1] << 8) | ss->gs.hdr[2];
351 349
352 if (IS_DTLS(ss)) { 350 if (IS_DTLS(ss)) {
353 int i; 351 int i;
354 352
355 cText.version = dtls_DTLSVersionToTLSVersion(cText.version); 353 cText.version = dtls_DTLSVersionToTLSVersion(cText.version);
356 /* DTLS sequence number */ 354 /* DTLS sequence number */
357 cText.seq_num.high = 0; cText.seq_num.low = 0; 355 cText.seq_num.high = 0; cText.seq_num.low = 0;
358 for (i = 0; i < 4; i++) { 356 for (i = 0; i < 4; i++) {
359 cText.seq_num.high <<= 8; cText.seq_num.low <<= 8; 357 cText.seq_num.high <<= 8; cText.seq_num.low <<= 8;
360 cText.seq_num.high |= ss->gs.hdr[3 + i]; 358 cText.seq_num.high |= ss->gs.hdr[3 + i];
361 cText.seq_num.low |= ss->gs.hdr[7 + i]; 359 cText.seq_num.low |= ss->gs.hdr[7 + i];
362 } 360 }
363 } 361 }
364 362
365 cText.buf = &ss->gs.inbuf; 363 cText.buf = &ss->gs.inbuf;
366 rv = ssl3_HandleRecord(ss, &cText, &ss->gs.buf); 364 rv = ssl3_HandleRecord(ss, &cText, &ss->gs.buf);
365
366 PORT_Assert(rv < 0 || ss->gs.buf.len == 0 ||
367 cText.type == content_application_data);
wtc 2013/10/17 00:10:53 Can you explain this assertion with a comment?
briansmith 2013/10/17 01:42:40 Done.
briansmith 2013/10/25 19:17:14 Making this clearer, and fixing the locking accord
367 } 368 }
368 if (rv < 0) { 369 if (rv < 0) {
369 » return ss->recvdCloseNotify ? 0 : rv; 370 » rv = ss->recvdCloseNotify ? 0 : rv;
370 » } 371 » goto done;
371
372 » /* If we kicked off a false start in ssl3_HandleServerHelloDone, break
373 » * out of this loop early without finishing the handshake.
374 » */
375 » if (ss->opt.enableFalseStart) {
376 » ssl_GetSSL3HandshakeLock(ss);
377 » canFalseStart = (ss->ssl3.hs.ws == wait_change_cipher ||
378 » » » ss->ssl3.hs.ws == wait_new_session_ticket) &&
wtc 2013/10/17 00:10:53 Note that ss->ssl3.hs.ws == wait_finished is not p
briansmith 2013/10/17 01:44:46 The false start code, before this patch, was incon
briansmith 2013/10/24 20:57:04 I found a reason why we should probably care about
379 » » ssl3_CanFalseStart(ss);
380 » ssl_ReleaseSSL3HandshakeLock(ss);
381 } 372 }
382 } while (ss->ssl3.hs.ws != idle_handshake && 373 } while (ss->ssl3.hs.ws != idle_handshake &&
383 !canFalseStart && 374 !ss->ssl3.hs.canFalseStart &&
384 ss->gs.buf.len == 0); 375 ss->gs.buf.len == 0);
385 376
386 ss->gs.readOffset = 0; 377 ss->gs.readOffset = 0;
387 ss->gs.writeOffset = ss->gs.buf.len; 378 ss->gs.writeOffset = ss->gs.buf.len;
388 return 1; 379 rv = 1;
380
381 done:
382 ssl_ReleaseSSL3HandshakeLock(ss);
383 return rv;
389 } 384 }
390 385
391 /* Repeatedly gather in a record and when complete, Handle that record. 386 /* Repeatedly gather in a record and when complete, Handle that record.
392 * Repeat this until some application data is received. 387 * Repeat this until some application data is received.
393 * 388 *
394 * Returns 1 when application data is available. 389 * Returns 1 when application data is available.
395 * Returns 0 if ssl3_GatherData hits EOF. 390 * Returns 0 if ssl3_GatherData hits EOF.
396 * Returns -1 on read error, or PR_WOULD_BLOCK_ERROR, or handleRecord error. 391 * Returns -1 on read error, or PR_WOULD_BLOCK_ERROR, or handleRecord error.
397 * Returns -2 on SECWouldBlock return from ssl3_HandleRecord. 392 * Returns -2 on SECWouldBlock return from ssl3_HandleRecord.
398 * 393 *
399 * Called from DoRecv in sslsecur.c 394 * Called from DoRecv in sslsecur.c
400 * Caller must hold the recv buf lock. 395 * Caller must hold the recv buf lock.
401 */ 396 */
402 int 397 int
403 ssl3_GatherAppDataRecord(sslSocket *ss, int flags) 398 ssl3_GatherAppDataRecord(sslSocket *ss, int flags)
404 { 399 {
405 int rv; 400 int rv;
406 401
407 PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) ); 402 PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
403 PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
404
408 do { 405 do {
409 rv = ssl3_GatherCompleteHandshake(ss, flags); 406 rv = ssl3_GatherCompleteHandshake(ss, flags);
410 } while (rv > 0 && ss->gs.buf.len == 0); 407 } while (rv > 0 && ss->gs.buf.len == 0);
411 408
412 return rv; 409 return rv;
413 } 410 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698