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 2211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2222 return SECFailure; /* ssl3_InitState has set the error code. */ | 2222 return SECFailure; /* ssl3_InitState has set the error code. */ |
2223 } | 2223 } |
2224 } | 2224 } |
2225 | 2225 |
2226 /* check for Token Presence */ | 2226 /* check for Token Presence */ |
2227 if (!ssl3_ClientAuthTokenPresent(ss->sec.ci.sid)) { | 2227 if (!ssl3_ClientAuthTokenPresent(ss->sec.ci.sid)) { |
2228 PORT_SetError(SSL_ERROR_TOKEN_INSERTION_REMOVAL); | 2228 PORT_SetError(SSL_ERROR_TOKEN_INSERTION_REMOVAL); |
2229 return SECFailure; | 2229 return SECFailure; |
2230 } | 2230 } |
2231 | 2231 |
2232 do { | 2232 while (nIn > 0) { |
2233 PRUint32 contentLen = PR_MIN(nIn, MAX_FRAGMENT_LENGTH); | 2233 PRUint32 contentLen = PR_MIN(nIn, MAX_FRAGMENT_LENGTH); |
2234 | 2234 |
2235 if (wrBuf->space < contentLen + SSL3_BUFFER_FUDGE) { | 2235 if (wrBuf->space < contentLen + SSL3_BUFFER_FUDGE) { |
2236 PRInt32 newSpace = PR_MAX(wrBuf->space * 2, contentLen); | 2236 PRInt32 newSpace = PR_MAX(wrBuf->space * 2, contentLen); |
2237 newSpace = PR_MIN(newSpace, MAX_FRAGMENT_LENGTH); | 2237 newSpace = PR_MIN(newSpace, MAX_FRAGMENT_LENGTH); |
2238 newSpace += SSL3_BUFFER_FUDGE; | 2238 newSpace += SSL3_BUFFER_FUDGE; |
2239 rv = sslBuffer_Grow(wrBuf, newSpace); | 2239 rv = sslBuffer_Grow(wrBuf, newSpace); |
2240 if (rv != SECSuccess) { | 2240 if (rv != SECSuccess) { |
2241 SSL_DBG(("%d: SSL3[%d]: SendRecord, tried to get %d bytes", | 2241 SSL_DBG(("%d: SSL3[%d]: SendRecord, tried to get %d bytes", |
2242 SSL_GETPID(), ss->fd, newSpace)); | 2242 SSL_GETPID(), ss->fd, newSpace)); |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2299 * append it to the buffer of previously unsent ciphertext. | 2299 * append it to the buffer of previously unsent ciphertext. |
2300 */ | 2300 */ |
2301 rv = ssl_SaveWriteData(ss, wrBuf->buf + sent, wrBuf->len); | 2301 rv = ssl_SaveWriteData(ss, wrBuf->buf + sent, wrBuf->len); |
2302 if (rv != SECSuccess) { | 2302 if (rv != SECSuccess) { |
2303 /* presumably a memory error, SEC_ERROR_NO_MEMORY */ | 2303 /* presumably a memory error, SEC_ERROR_NO_MEMORY */ |
2304 return SECFailure; | 2304 return SECFailure; |
2305 } | 2305 } |
2306 } | 2306 } |
2307 } | 2307 } |
2308 totalSent += contentLen; | 2308 totalSent += contentLen; |
2309 } while (nIn > 0); | 2309 } |
2310 return totalSent; | 2310 return totalSent; |
2311 } | 2311 } |
2312 | 2312 |
2313 #define SSL3_PENDING_HIGH_WATER 1024 | 2313 #define SSL3_PENDING_HIGH_WATER 1024 |
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 | 2324 |
2326 PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) ); | 2325 PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) ); |
2327 if (len < 0 || !in) { | 2326 if (len < 0 || !in) { |
2328 PORT_SetError(PR_INVALID_ARGUMENT_ERROR); | 2327 PORT_SetError(PR_INVALID_ARGUMENT_ERROR); |
2329 return SECFailure; | 2328 return SECFailure; |
2330 } | 2329 } |
2331 | 2330 |
2332 if (ss->pendingBuf.len > SSL3_PENDING_HIGH_WATER && | 2331 if (ss->pendingBuf.len > SSL3_PENDING_HIGH_WATER && |
2333 !ssl_SocketIsBlocking(ss)) { | 2332 !ssl_SocketIsBlocking(ss)) { |
2334 PORT_Assert(!ssl_SocketIsBlocking(ss)); | 2333 PORT_Assert(!ssl_SocketIsBlocking(ss)); |
2335 PORT_SetError(PR_WOULD_BLOCK_ERROR); | 2334 PORT_SetError(PR_WOULD_BLOCK_ERROR); |
2336 return SECFailure; | 2335 return SECFailure; |
2337 } | 2336 } |
2338 | 2337 |
2339 if (ss->appDataBuffered && len) { | 2338 if (ss->appDataBuffered && len) { |
2340 PORT_Assert (in[0] == (unsigned char)(ss->appDataBuffered)); | 2339 PORT_Assert (in[0] == (unsigned char)(ss->appDataBuffered)); |
2341 if (in[0] != (unsigned char)(ss->appDataBuffered)) { | 2340 if (in[0] != (unsigned char)(ss->appDataBuffered)) { |
2342 PORT_SetError(PR_INVALID_ARGUMENT_ERROR); | 2341 PORT_SetError(PR_INVALID_ARGUMENT_ERROR); |
2343 return SECFailure; | 2342 return SECFailure; |
2344 } | 2343 } |
2345 in++; | 2344 in++; |
2346 len--; | 2345 len--; |
2347 discarded = 1; | 2346 discarded = 1; |
2348 } | 2347 } |
2349 | |
2350 ssl_GetSpecReadLock(ss); | |
2351 isBlockCipher = ss->ssl3.cwSpec->cipher_def->type == type_block; | |
2352 ssl_ReleaseSpecReadLock(ss); | |
2353 | |
2354 if (isBlockCipher && len > 0) { | |
2355 // We assume that block ciphers are used in CBC mode and prepend an | |
2356 // empty record. This effectively randomizes the IV in a backwards | |
2357 // compatible way. | |
2358 PRInt32 sent = ssl3_SendRecord(ss, content_application_data, | |
2359 in, 0 /* no payload */, flags); | |
2360 if (sent < 0) { | |
2361 return SECFailure; /* error code set by ssl3_SendRecord */ | |
2362 } | |
2363 if (ss->pendingBuf.len) { | |
2364 /* must be a non-blocking socket */ | |
2365 PORT_Assert(!ssl_SocketIsBlocking(ss)); | |
2366 PORT_Assert(ss->lastWriteBlocked); | |
2367 return SECFailure; | |
2368 } | |
2369 } | |
2370 | |
2371 while (len > totalSent) { | 2348 while (len > totalSent) { |
2372 PRInt32 sent, toSend; | 2349 PRInt32 sent, toSend; |
2373 | 2350 |
2374 if (totalSent > 0) { | 2351 if (totalSent > 0) { |
2375 /* | 2352 /* |
2376 * The thread yield is intended to give the reader thread a | 2353 * The thread yield is intended to give the reader thread a |
2377 * chance to get some cycles while the writer thread is in | 2354 * chance to get some cycles while the writer thread is in |
2378 * the middle of a large application data write. (See | 2355 * the middle of a large application data write. (See |
2379 * Bugzilla bug 127740, comment #1.) | 2356 * Bugzilla bug 127740, comment #1.) |
2380 */ | 2357 */ |
(...skipping 12 matching lines...) Expand all Loading... |
2393 return SECFailure; /* error code set by ssl3_SendRecord */ | 2370 return SECFailure; /* error code set by ssl3_SendRecord */ |
2394 } | 2371 } |
2395 totalSent += sent; | 2372 totalSent += sent; |
2396 if (ss->pendingBuf.len) { | 2373 if (ss->pendingBuf.len) { |
2397 /* must be a non-blocking socket */ | 2374 /* must be a non-blocking socket */ |
2398 PORT_Assert(!ssl_SocketIsBlocking(ss)); | 2375 PORT_Assert(!ssl_SocketIsBlocking(ss)); |
2399 PORT_Assert(ss->lastWriteBlocked); | 2376 PORT_Assert(ss->lastWriteBlocked); |
2400 break; | 2377 break; |
2401 } | 2378 } |
2402 } | 2379 } |
2403 | |
2404 if (ss->pendingBuf.len) { | 2380 if (ss->pendingBuf.len) { |
2405 /* Must be non-blocking. */ | 2381 /* Must be non-blocking. */ |
2406 PORT_Assert(!ssl_SocketIsBlocking(ss)); | 2382 PORT_Assert(!ssl_SocketIsBlocking(ss)); |
2407 if (totalSent > 0) { | 2383 if (totalSent > 0) { |
2408 ss->appDataBuffered = 0x100 | in[totalSent - 1]; | 2384 ss->appDataBuffered = 0x100 | in[totalSent - 1]; |
2409 } | 2385 } |
2410 | 2386 |
2411 totalSent = totalSent + discarded - 1; | 2387 totalSent = totalSent + discarded - 1; |
2412 if (totalSent <= 0) { | 2388 if (totalSent <= 0) { |
2413 PORT_SetError(PR_WOULD_BLOCK_ERROR); | 2389 PORT_SetError(PR_WOULD_BLOCK_ERROR); |
(...skipping 7538 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9952 | 9928 |
9953 ss->ssl3.initialized = PR_FALSE; | 9929 ss->ssl3.initialized = PR_FALSE; |
9954 | 9930 |
9955 if (ss->ssl3.nextProto.data) { | 9931 if (ss->ssl3.nextProto.data) { |
9956 PORT_Free(ss->ssl3.nextProto.data); | 9932 PORT_Free(ss->ssl3.nextProto.data); |
9957 ss->ssl3.nextProto.data = NULL; | 9933 ss->ssl3.nextProto.data = NULL; |
9958 } | 9934 } |
9959 } | 9935 } |
9960 | 9936 |
9961 /* End of ssl3con.c */ | 9937 /* End of ssl3con.c */ |
OLD | NEW |