OLD | NEW |
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 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
318 | 318 |
319 if (handleRecordNow) { | 319 if (handleRecordNow) { |
320 /* ssl3_HandleHandshake previously returned SECWouldBlock and the | 320 /* ssl3_HandleHandshake previously returned SECWouldBlock and the |
321 * as-yet-unprocessed plaintext of that previous handshake record. | 321 * as-yet-unprocessed plaintext of that previous handshake record. |
322 * We need to process it now before we overwrite it with the next | 322 * We need to process it now before we overwrite it with the next |
323 * handshake record. | 323 * handshake record. |
324 */ | 324 */ |
325 rv = ssl3_HandleRecord(ss, NULL, &ss->gs.buf); | 325 rv = ssl3_HandleRecord(ss, NULL, &ss->gs.buf); |
326 } else { | 326 } else { |
327 /* bring in the next sslv3 record. */ | 327 /* bring in the next sslv3 record. */ |
| 328 if (ss->recvdCloseNotify) { |
| 329 /* RFC 5246 Section 7.2.1: |
| 330 * Any data received after a closure alert is ignored. |
| 331 */ |
| 332 return 0; |
| 333 } |
328 if (!IS_DTLS(ss)) { | 334 if (!IS_DTLS(ss)) { |
329 rv = ssl3_GatherData(ss, &ss->gs, flags); | 335 rv = ssl3_GatherData(ss, &ss->gs, flags); |
330 } else { | 336 } else { |
331 rv = dtls_GatherData(ss, &ss->gs, flags); | 337 rv = dtls_GatherData(ss, &ss->gs, flags); |
332 | 338 |
333 /* If we got a would block error, that means that no data was | 339 /* If we got a would block error, that means that no data was |
334 * available, so we check the timer to see if it's time to | 340 * available, so we check the timer to see if it's time to |
335 * retransmit */ | 341 * retransmit */ |
336 if (rv == SECFailure && | 342 if (rv == SECFailure && |
337 (PORT_GetError() == PR_WOULD_BLOCK_ERROR)) { | 343 (PORT_GetError() == PR_WOULD_BLOCK_ERROR)) { |
(...skipping 25 matching lines...) Expand all Loading... |
363 cText.seq_num.high = 0; cText.seq_num.low = 0; | 369 cText.seq_num.high = 0; cText.seq_num.low = 0; |
364 for (i = 0; i < 4; i++) { | 370 for (i = 0; i < 4; i++) { |
365 cText.seq_num.high <<= 8; cText.seq_num.low <<= 8; | 371 cText.seq_num.high <<= 8; cText.seq_num.low <<= 8; |
366 cText.seq_num.high |= ss->gs.hdr[3 + i]; | 372 cText.seq_num.high |= ss->gs.hdr[3 + i]; |
367 cText.seq_num.low |= ss->gs.hdr[7 + i]; | 373 cText.seq_num.low |= ss->gs.hdr[7 + i]; |
368 } | 374 } |
369 } | 375 } |
370 | 376 |
371 cText.buf = &ss->gs.inbuf; | 377 cText.buf = &ss->gs.inbuf; |
372 rv = ssl3_HandleRecord(ss, &cText, &ss->gs.buf); | 378 rv = ssl3_HandleRecord(ss, &cText, &ss->gs.buf); |
373 | |
374 if (rv == (int) SECSuccess && ss->gs.buf.len > 0) { | |
375 /* We have application data to return to the application. This | |
376 * prioritizes returning application data to the application ove
r | |
377 * completing any renegotiation handshake we may be doing. | |
378 */ | |
379 PORT_Assert(ss->firstHsDone); | |
380 PORT_Assert(cText.type == content_application_data); | |
381 break; | |
382 } | |
383 } | 379 } |
384 if (rv < 0) { | 380 if (rv < 0) { |
385 return ss->recvdCloseNotify ? 0 : rv; | 381 return ss->recvdCloseNotify ? 0 : rv; |
386 } | 382 } |
| 383 if (ss->gs.buf.len > 0) { |
| 384 /* We have application data to return to the application. This |
| 385 * prioritizes returning application data to the application over |
| 386 * completing any renegotiation handshake we may be doing. |
| 387 */ |
| 388 PORT_Assert(ss->firstHsDone); |
| 389 PORT_Assert(cText.type == content_application_data); |
| 390 break; |
| 391 } |
387 | 392 |
388 PORT_Assert(keepGoing); | 393 PORT_Assert(keepGoing); |
389 ssl_GetSSL3HandshakeLock(ss); | 394 ssl_GetSSL3HandshakeLock(ss); |
390 if (ss->ssl3.hs.ws == idle_handshake) { | 395 if (ss->ssl3.hs.ws == idle_handshake) { |
391 /* We are done with the current handshake so stop trying to | 396 /* We are done with the current handshake so stop trying to |
392 * handshake. Note that it would be safe to test ss->firstHsDone | 397 * handshake. Note that it would be safe to test ss->firstHsDone |
393 * instead of ss->ssl3.hs.ws. By testing ss->ssl3.hs.ws instead, | 398 * instead of ss->ssl3.hs.ws. By testing ss->ssl3.hs.ws instead, |
394 * we prioritize completing a renegotiation handshake over sending | 399 * we prioritize completing a renegotiation handshake over sending |
395 * application data. | 400 * application data. |
396 */ | 401 */ |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
441 /* ssl3_GatherCompleteHandshake requires both of these locks. */ | 446 /* ssl3_GatherCompleteHandshake requires both of these locks. */ |
442 PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); | 447 PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); |
443 PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) ); | 448 PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) ); |
444 | 449 |
445 do { | 450 do { |
446 rv = ssl3_GatherCompleteHandshake(ss, flags); | 451 rv = ssl3_GatherCompleteHandshake(ss, flags); |
447 } while (rv > 0 && ss->gs.buf.len == 0); | 452 } while (rv > 0 && ss->gs.buf.len == 0); |
448 | 453 |
449 return rv; | 454 return rv; |
450 } | 455 } |
OLD | NEW |