OLD | NEW |
---|---|
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 /* $Id: ssl3con.c,v 1.192 2012/09/28 05:10:25 wtc%google.com Exp $ */ | 8 /* $Id: ssl3con.c,v 1.192 2012/09/28 05:10:25 wtc%google.com Exp $ */ |
9 | 9 |
10 /* TODO(ekr): Implement HelloVerifyRequest on server side. OK for now. */ | 10 /* TODO(ekr): Implement HelloVerifyRequest on server side. OK for now. */ |
(...skipping 2398 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2409 SECStatus rv; | 2409 SECStatus rv; |
2410 PRInt32 totalSent = 0; | 2410 PRInt32 totalSent = 0; |
2411 PRBool capRecordVersion; | 2411 PRBool capRecordVersion; |
2412 | 2412 |
2413 SSL_TRC(3, ("%d: SSL3[%d] SendRecord type: %s nIn=%d", | 2413 SSL_TRC(3, ("%d: SSL3[%d] SendRecord type: %s nIn=%d", |
2414 SSL_GETPID(), ss->fd, ssl3_DecodeContentType(type), | 2414 SSL_GETPID(), ss->fd, ssl3_DecodeContentType(type), |
2415 nIn)); | 2415 nIn)); |
2416 PRINT_BUF(3, (ss, "Send record (plain text)", pIn, nIn)); | 2416 PRINT_BUF(3, (ss, "Send record (plain text)", pIn, nIn)); |
2417 | 2417 |
2418 PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) ); | 2418 PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) ); |
2419 PORT_Assert( wrBuf->len == 0 ); | |
2419 | 2420 |
2420 capRecordVersion = ((flags & ssl_SEND_FLAG_CAP_RECORD_VERSION) != 0); | 2421 capRecordVersion = ((flags & ssl_SEND_FLAG_CAP_RECORD_VERSION) != 0); |
2421 | 2422 |
2422 if (capRecordVersion) { | 2423 if (capRecordVersion) { |
2423 /* ssl_SEND_FLAG_CAP_RECORD_VERSION can only be used with the | 2424 /* ssl_SEND_FLAG_CAP_RECORD_VERSION can only be used with the |
2424 * TLS initial ClientHello. */ | 2425 * TLS initial ClientHello. */ |
2425 PORT_Assert(!IS_DTLS(ss)); | 2426 PORT_Assert(!IS_DTLS(ss)); |
2426 PORT_Assert(!ss->firstHsDone); | 2427 PORT_Assert(!ss->firstHsDone); |
2427 PORT_Assert(type == content_handshake); | 2428 PORT_Assert(type == content_handshake); |
2428 PORT_Assert(ss->ssl3.hs.ws == wait_server_hello); | 2429 PORT_Assert(ss->ssl3.hs.ws == wait_server_hello); |
(...skipping 13 matching lines...) Expand all Loading... | |
2442 | 2443 |
2443 /* check for Token Presence */ | 2444 /* check for Token Presence */ |
2444 if (!ssl3_ClientAuthTokenPresent(ss->sec.ci.sid)) { | 2445 if (!ssl3_ClientAuthTokenPresent(ss->sec.ci.sid)) { |
2445 PORT_SetError(SSL_ERROR_TOKEN_INSERTION_REMOVAL); | 2446 PORT_SetError(SSL_ERROR_TOKEN_INSERTION_REMOVAL); |
2446 return SECFailure; | 2447 return SECFailure; |
2447 } | 2448 } |
2448 | 2449 |
2449 while (nIn > 0) { | 2450 while (nIn > 0) { |
2450 PRUint32 contentLen = PR_MIN(nIn, MAX_FRAGMENT_LENGTH); | 2451 PRUint32 contentLen = PR_MIN(nIn, MAX_FRAGMENT_LENGTH); |
2451 unsigned int spaceNeeded; | 2452 unsigned int spaceNeeded; |
2452 » unsigned int numRecords; | 2453 » unsigned int numRecords = 1; |
2453 | 2454 |
2454 ssl_GetSpecReadLock(ss); /********************************/ | 2455 ssl_GetSpecReadLock(ss); /********************************/ |
2455 | 2456 |
2456 if (nIn > 1 && ss->opt.cbcRandomIV && | 2457 if (nIn > 1 && ss->opt.cbcRandomIV && |
2457 ss->ssl3.cwSpec->version < SSL_LIBRARY_VERSION_TLS_1_1 && | 2458 ss->ssl3.cwSpec->version < SSL_LIBRARY_VERSION_TLS_1_1 && |
2458 type == content_application_data && | 2459 type == content_application_data && |
2459 ss->ssl3.cwSpec->cipher_def->type == type_block /* CBC mode */) { | 2460 ss->ssl3.cwSpec->cipher_def->type == type_block /* CBC mode */) { |
2460 /* We will split the first byte of the record into its own record, | 2461 /* We will split the first byte of the record into its own record, |
2461 * as explained in the documentation for SSL_CBC_RANDOM_IV in ssl.h | 2462 * as explained in the documentation for SSL_CBC_RANDOM_IV in ssl.h |
2462 */ | 2463 */ |
2463 numRecords = 2; | 2464 numRecords = 2; |
2464 » } else { | 2465 » } |
2465 » numRecords = 1; | 2466 » if (nIn > 1 && ss->opt.cbcRandomIV && |
agl
2013/03/15 12:35:21
Unlike the CBC case, we only need to split RC4 rec
wtc
2013/03/16 01:15:38
This code only splits the first RC4 application da
| |
2467 » type == content_application_data && | |
2468 » ss->ssl3.cwSpec->cipher_def->calg == ssl_calg_rc4) { | |
2469 » /* Adjust these parameters. */ | |
2470 » enum { | |
2471 » » BIASED_RC4_BYTES = 256, | |
2472 » » MIN_RECORD_SIZE = 1 + MD5_LENGTH, | |
2473 » » MAX_SPLIT_RECORDS = | |
2474 » » (BIASED_RC4_BYTES + MIN_RECORD_SIZE - 1) / MIN_RECORD_SIZE | |
wtc
2013/03/15 03:58:18
Here I calculate a crude estimate of how many one-
agl
2013/03/15 12:35:21
A couple of ideas for tuning:
Obviously the MAC m
wtc
2013/03/16 01:15:38
Done. With Google sites we also get NextProtocol a
| |
2475 » }; | |
2476 | |
2477 » numRecords = PR_MIN(nIn, MAX_SPLIT_RECORDS); | |
2478 » /* Split only the first application data record. | |
2479 » * NOTE: turning off ss->opt.cbcRandomIV is a hack. We should | |
2480 » * add a new boolean field to |ss|. | |
2481 » */ | |
2482 » ss->opt.cbcRandomIV = PR_FALSE; | |
2466 } | 2483 } |
2467 | 2484 |
2468 spaceNeeded = contentLen + (numRecords * SSL3_BUFFER_FUDGE); | 2485 spaceNeeded = contentLen + (numRecords * SSL3_BUFFER_FUDGE); |
2469 if (ss->ssl3.cwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_1 && | 2486 if (ss->ssl3.cwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_1 && |
2470 ss->ssl3.cwSpec->cipher_def->type == type_block) { | 2487 ss->ssl3.cwSpec->cipher_def->type == type_block) { |
2471 spaceNeeded += ss->ssl3.cwSpec->cipher_def->iv_size; | 2488 spaceNeeded += ss->ssl3.cwSpec->cipher_def->iv_size; |
2472 } | 2489 } |
2473 if (spaceNeeded > wrBuf->space) { | 2490 if (spaceNeeded > wrBuf->space) { |
2474 rv = sslBuffer_Grow(wrBuf, spaceNeeded); | 2491 rv = sslBuffer_Grow(wrBuf, spaceNeeded); |
2475 if (rv != SECSuccess) { | 2492 if (rv != SECSuccess) { |
2476 SSL_DBG(("%d: SSL3[%d]: SendRecord, tried to get %d bytes", | 2493 SSL_DBG(("%d: SSL3[%d]: SendRecord, tried to get %d bytes", |
2477 SSL_GETPID(), ss->fd, spaceNeeded)); | 2494 SSL_GETPID(), ss->fd, spaceNeeded)); |
2478 goto spec_locked_loser; /* sslBuffer_Grow set error code. */ | 2495 goto spec_locked_loser; /* sslBuffer_Grow set error code. */ |
2479 } | 2496 } |
2480 } | 2497 } |
2481 | 2498 |
2482 » if (numRecords == 2) { | 2499 » if (numRecords > 1) { |
2483 » sslBuffer secondRecord; | 2500 » sslBuffer recordBuf; |
2501 » unsigned int i; | |
2484 | 2502 |
2485 » rv = ssl3_CompressMACEncryptRecord(ss->ssl3.cwSpec, | 2503 » for (i = 0; i < numRecords; i++) { |
2486 » » » » » ss->sec.isServer, IS_DTLS(ss), | 2504 » » recordBuf.buf = wrBuf->buf + wrBuf->len; |
2487 » » » » » capRecordVersion, type, pIn, | 2505 » » recordBuf.len = 0; |
2488 » » » » » 1, wrBuf); | 2506 » » recordBuf.space = wrBuf->space - wrBuf->len; |
2489 » if (rv != SECSuccess) | |
2490 » goto spec_locked_loser; | |
2491 | 2507 |
2492 » PRINT_BUF(50, (ss, "send (encrypted) record data [1/2]:", | 2508 » » rv = ssl3_CompressMACEncryptRecord(ss->ssl3.cwSpec, |
2493 » wrBuf->buf, wrBuf->len)); | 2509 » » » » » » ss->sec.isServer, |
2510 » » » » » » IS_DTLS(ss), | |
2511 » » » » » » capRecordVersion, type, | |
2512 » » » » » » pIn + i, | |
2513 » » » » » » (i != numRecords - 1) ? | |
2514 » » » » » » 1 : contentLen - i, | |
2515 » » » » » » &recordBuf); | |
2516 » » if (rv != SECSuccess) | |
2517 » » break; | |
2494 | 2518 |
2495 » secondRecord.buf = wrBuf->buf + wrBuf->len; | 2519 » » PRINT_BUF(50, (ss, "send (encrypted) record data:", |
2496 » secondRecord.len = 0; | 2520 » » » recordBuf.buf, recordBuf.len)); |
2497 » secondRecord.space = wrBuf->space - wrBuf->len; | 2521 » » wrBuf->len += recordBuf.len; |
2498 | |
2499 » rv = ssl3_CompressMACEncryptRecord(ss->ssl3.cwSpec, | |
2500 » ss->sec.isServer, IS_DTLS(ss), | |
2501 » » » » » capRecordVersion, type, | |
2502 » » » » » pIn + 1, contentLen - 1, | |
2503 » &secondRecord); | |
2504 » if (rv == SECSuccess) { | |
2505 » PRINT_BUF(50, (ss, "send (encrypted) record data [2/2]:", | |
2506 » secondRecord.buf, secondRecord.len)); | |
2507 » wrBuf->len += secondRecord.len; | |
2508 } | 2522 } |
wtc
2013/03/15 03:58:18
I generalized this code to be able to split the ap
| |
2509 } else { | 2523 } else { |
2510 if (!IS_DTLS(ss)) { | 2524 if (!IS_DTLS(ss)) { |
2511 rv = ssl3_CompressMACEncryptRecord(ss->ssl3.cwSpec, | 2525 rv = ssl3_CompressMACEncryptRecord(ss->ssl3.cwSpec, |
2512 ss->sec.isServer, | 2526 ss->sec.isServer, |
2513 IS_DTLS(ss), | 2527 IS_DTLS(ss), |
2514 capRecordVersion, | 2528 capRecordVersion, |
2515 type, pIn, | 2529 type, pIn, |
2516 contentLen, wrBuf); | 2530 contentLen, wrBuf); |
2517 } else { | 2531 } else { |
2518 rv = dtls_CompressMACEncryptRecord(ss, epoch, | 2532 rv = dtls_CompressMACEncryptRecord(ss, epoch, |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2584 return SECFailure; | 2598 return SECFailure; |
2585 } | 2599 } |
2586 /* now take all the remaining unsent new ciphertext and | 2600 /* now take all the remaining unsent new ciphertext and |
2587 * append it to the buffer of previously unsent ciphertext. | 2601 * append it to the buffer of previously unsent ciphertext. |
2588 */ | 2602 */ |
2589 rv = ssl_SaveWriteData(ss, wrBuf->buf + sent, wrBuf->len); | 2603 rv = ssl_SaveWriteData(ss, wrBuf->buf + sent, wrBuf->len); |
2590 if (rv != SECSuccess) { | 2604 if (rv != SECSuccess) { |
2591 /* presumably a memory error, SEC_ERROR_NO_MEMORY */ | 2605 /* presumably a memory error, SEC_ERROR_NO_MEMORY */ |
2592 return SECFailure; | 2606 return SECFailure; |
2593 } | 2607 } |
2608 wrBuf->len = 0; /* All cipher text is saved away. */ | |
2594 } | 2609 } |
2595 } | 2610 } |
2596 totalSent += contentLen; | 2611 totalSent += contentLen; |
2597 } | 2612 } |
2598 return totalSent; | 2613 return totalSent; |
2599 } | 2614 } |
2600 | 2615 |
2601 #define SSL3_PENDING_HIGH_WATER 1024 | 2616 #define SSL3_PENDING_HIGH_WATER 1024 |
2602 | 2617 |
2603 /* Attempt to send the content of "in" in an SSL application_data record. | 2618 /* Attempt to send the content of "in" in an SSL application_data record. |
(...skipping 10 matching lines...) Expand all Loading... | |
2614 /* These flags for internal use only */ | 2629 /* These flags for internal use only */ |
2615 PORT_Assert(!(flags & (ssl_SEND_FLAG_USE_EPOCH | | 2630 PORT_Assert(!(flags & (ssl_SEND_FLAG_USE_EPOCH | |
2616 ssl_SEND_FLAG_NO_RETRANSMIT))); | 2631 ssl_SEND_FLAG_NO_RETRANSMIT))); |
2617 if (len < 0 || !in) { | 2632 if (len < 0 || !in) { |
2618 PORT_SetError(PR_INVALID_ARGUMENT_ERROR); | 2633 PORT_SetError(PR_INVALID_ARGUMENT_ERROR); |
2619 return SECFailure; | 2634 return SECFailure; |
2620 } | 2635 } |
2621 | 2636 |
2622 if (ss->pendingBuf.len > SSL3_PENDING_HIGH_WATER && | 2637 if (ss->pendingBuf.len > SSL3_PENDING_HIGH_WATER && |
2623 !ssl_SocketIsBlocking(ss)) { | 2638 !ssl_SocketIsBlocking(ss)) { |
2624 PORT_Assert(!ssl_SocketIsBlocking(ss)); | |
2625 PORT_SetError(PR_WOULD_BLOCK_ERROR); | 2639 PORT_SetError(PR_WOULD_BLOCK_ERROR); |
2626 return SECFailure; | 2640 return SECFailure; |
2627 } | 2641 } |
2628 | 2642 |
2629 if (ss->appDataBuffered && len) { | 2643 if (ss->appDataBuffered && len) { |
2630 PORT_Assert (in[0] == (unsigned char)(ss->appDataBuffered)); | 2644 PORT_Assert (in[0] == (unsigned char)(ss->appDataBuffered)); |
2631 if (in[0] != (unsigned char)(ss->appDataBuffered)) { | 2645 if (in[0] != (unsigned char)(ss->appDataBuffered)) { |
2632 PORT_SetError(PR_INVALID_ARGUMENT_ERROR); | 2646 PORT_SetError(PR_INVALID_ARGUMENT_ERROR); |
2633 return SECFailure; | 2647 return SECFailure; |
2634 } | 2648 } |
(...skipping 8631 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
11266 PORT_Free(ss->ssl3.hs.recvdFragments.buf); | 11280 PORT_Free(ss->ssl3.hs.recvdFragments.buf); |
11267 } | 11281 } |
11268 } | 11282 } |
11269 | 11283 |
11270 ss->ssl3.initialized = PR_FALSE; | 11284 ss->ssl3.initialized = PR_FALSE; |
11271 | 11285 |
11272 SECITEM_FreeItem(&ss->ssl3.nextProto, PR_FALSE); | 11286 SECITEM_FreeItem(&ss->ssl3.nextProto, PR_FALSE); |
11273 } | 11287 } |
11274 | 11288 |
11275 /* End of ssl3con.c */ | 11289 /* End of ssl3con.c */ |
OLD | NEW |