OLD | NEW |
1 /* | 1 /* |
2 * SSL3 Protocol | 2 * SSL3 Protocol |
3 * | 3 * |
4 * ***** BEGIN LICENSE BLOCK ***** | 4 * ***** BEGIN LICENSE BLOCK ***** |
5 * Version: MPL 1.1/GPL 2.0/LGPL 2.1 | 5 * Version: MPL 1.1/GPL 2.0/LGPL 2.1 |
6 * | 6 * |
7 * The contents of this file are subject to the Mozilla Public License Version | 7 * The contents of this file are subject to the Mozilla Public License Version |
8 * 1.1 (the "License"); you may not use this file except in compliance with | 8 * 1.1 (the "License"); you may not use this file except in compliance with |
9 * the License. You may obtain a copy of the License at | 9 * the License. You may obtain a copy of the License at |
10 * http://www.mozilla.org/MPL/ | 10 * http://www.mozilla.org/MPL/ |
(...skipping 2303 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2314 | 2314 |
2315 /* Attempt to send the content of "in" in an SSL application_data record. | 2315 /* Attempt to send the content of "in" in an SSL application_data record. |
2316 * Returns "len" or SECFailure, never SECWouldBlock, nor SECSuccess. | 2316 * Returns "len" or SECFailure, never SECWouldBlock, nor SECSuccess. |
2317 */ | 2317 */ |
2318 int | 2318 int |
2319 ssl3_SendApplicationData(sslSocket *ss, const unsigned char *in, | 2319 ssl3_SendApplicationData(sslSocket *ss, const unsigned char *in, |
2320 PRInt32 len, PRInt32 flags) | 2320 PRInt32 len, PRInt32 flags) |
2321 { | 2321 { |
2322 PRInt32 totalSent = 0; | 2322 PRInt32 totalSent = 0; |
2323 PRInt32 discarded = 0; | 2323 PRInt32 discarded = 0; |
| 2324 PRBool isBlockCipher; |
| 2325 int recordIndex; |
2324 | 2326 |
2325 PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) ); | 2327 PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) ); |
2326 if (len < 0 || !in) { | 2328 if (len < 0 || !in) { |
2327 PORT_SetError(PR_INVALID_ARGUMENT_ERROR); | 2329 PORT_SetError(PR_INVALID_ARGUMENT_ERROR); |
2328 return SECFailure; | 2330 return SECFailure; |
2329 } | 2331 } |
2330 | 2332 |
2331 if (ss->pendingBuf.len > SSL3_PENDING_HIGH_WATER && | 2333 if (ss->pendingBuf.len > SSL3_PENDING_HIGH_WATER && |
2332 !ssl_SocketIsBlocking(ss)) { | 2334 !ssl_SocketIsBlocking(ss)) { |
2333 PORT_Assert(!ssl_SocketIsBlocking(ss)); | 2335 PORT_Assert(!ssl_SocketIsBlocking(ss)); |
2334 PORT_SetError(PR_WOULD_BLOCK_ERROR); | 2336 PORT_SetError(PR_WOULD_BLOCK_ERROR); |
2335 return SECFailure; | 2337 return SECFailure; |
2336 } | 2338 } |
2337 | 2339 |
2338 if (ss->appDataBuffered && len) { | 2340 if (ss->appDataBuffered && len) { |
2339 PORT_Assert (in[0] == (unsigned char)(ss->appDataBuffered)); | 2341 PORT_Assert (in[0] == (unsigned char)(ss->appDataBuffered)); |
2340 if (in[0] != (unsigned char)(ss->appDataBuffered)) { | 2342 if (in[0] != (unsigned char)(ss->appDataBuffered)) { |
2341 PORT_SetError(PR_INVALID_ARGUMENT_ERROR); | 2343 PORT_SetError(PR_INVALID_ARGUMENT_ERROR); |
2342 return SECFailure; | 2344 return SECFailure; |
2343 } | 2345 } |
2344 in++; | 2346 in++; |
2345 len--; | 2347 len--; |
2346 discarded = 1; | 2348 discarded = 1; |
2347 } | 2349 } |
2348 while (len > totalSent) { | 2350 |
| 2351 ssl_GetSpecReadLock(ss); |
| 2352 isBlockCipher = ss->ssl3.cwSpec->cipher_def->type == type_block; |
| 2353 ssl_ReleaseSpecReadLock(ss); |
| 2354 |
| 2355 for (recordIndex = 0; len > totalSent; recordIndex++) { |
2349 PRInt32 sent, toSend; | 2356 PRInt32 sent, toSend; |
2350 | 2357 |
2351 if (totalSent > 0) { | 2358 if (totalSent > 0) { |
2352 /* | 2359 /* |
2353 * The thread yield is intended to give the reader thread a | 2360 * The thread yield is intended to give the reader thread a |
2354 * chance to get some cycles while the writer thread is in | 2361 * chance to get some cycles while the writer thread is in |
2355 * the middle of a large application data write. (See | 2362 * the middle of a large application data write. (See |
2356 * Bugzilla bug 127740, comment #1.) | 2363 * Bugzilla bug 127740, comment #1.) |
2357 */ | 2364 */ |
2358 ssl_ReleaseXmitBufLock(ss); | 2365 ssl_ReleaseXmitBufLock(ss); |
2359 PR_Sleep(PR_INTERVAL_NO_WAIT); /* PR_Yield(); */ | 2366 PR_Sleep(PR_INTERVAL_NO_WAIT); /* PR_Yield(); */ |
2360 ssl_GetXmitBufLock(ss); | 2367 ssl_GetXmitBufLock(ss); |
2361 } | 2368 } |
2362 toSend = PR_MIN(len - totalSent, MAX_FRAGMENT_LENGTH); | 2369 toSend = PR_MIN(len - totalSent, MAX_FRAGMENT_LENGTH); |
| 2370 if (isBlockCipher && |
| 2371 ss->ssl3.cwSpec->version <= SSL_LIBRARY_VERSION_3_1_TLS) { |
| 2372 /* |
| 2373 * We assume that block ciphers are used in CBC mode and send |
| 2374 * only one byte in the first record. This effectively |
| 2375 * randomizes the IV in a backward compatible way. |
| 2376 * |
| 2377 * We get back to the MAX_FRAGMENT_LENGTH record boundary in |
| 2378 * the second record. So for a large amount of data, we send |
| 2379 * 1 |
| 2380 * MAX_FRAGMENT_LENGTH - 1 |
| 2381 * MAX_FRAGMENT_LENGTH |
| 2382 * MAX_FRAGMENT_LENGTH |
| 2383 * ... |
| 2384 */ |
| 2385 if (recordIndex == 0) { |
| 2386 toSend = 1; |
| 2387 } else if (recordIndex == 1 && |
| 2388 len - totalSent > MAX_FRAGMENT_LENGTH) { |
| 2389 toSend--; |
| 2390 } |
| 2391 } |
2363 sent = ssl3_SendRecord(ss, content_application_data, | 2392 sent = ssl3_SendRecord(ss, content_application_data, |
2364 in + totalSent, toSend, flags); | 2393 in + totalSent, toSend, flags); |
2365 if (sent < 0) { | 2394 if (sent < 0) { |
2366 if (totalSent > 0 && PR_GetError() == PR_WOULD_BLOCK_ERROR) { | 2395 if (totalSent > 0 && PR_GetError() == PR_WOULD_BLOCK_ERROR) { |
2367 PORT_Assert(ss->lastWriteBlocked); | 2396 PORT_Assert(ss->lastWriteBlocked); |
2368 break; | 2397 break; |
2369 } | 2398 } |
2370 return SECFailure; /* error code set by ssl3_SendRecord */ | 2399 return SECFailure; /* error code set by ssl3_SendRecord */ |
2371 } | 2400 } |
2372 totalSent += sent; | 2401 totalSent += sent; |
(...skipping 7555 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9928 | 9957 |
9929 ss->ssl3.initialized = PR_FALSE; | 9958 ss->ssl3.initialized = PR_FALSE; |
9930 | 9959 |
9931 if (ss->ssl3.nextProto.data) { | 9960 if (ss->ssl3.nextProto.data) { |
9932 PORT_Free(ss->ssl3.nextProto.data); | 9961 PORT_Free(ss->ssl3.nextProto.data); |
9933 ss->ssl3.nextProto.data = NULL; | 9962 ss->ssl3.nextProto.data = NULL; |
9934 } | 9963 } |
9935 } | 9964 } |
9936 | 9965 |
9937 /* End of ssl3con.c */ | 9966 /* End of ssl3con.c */ |
OLD | NEW |