Chromium Code Reviews| 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 1896 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1907 if (mac_def->mac == mac_null) { | 1907 if (mac_def->mac == mac_null) { |
| 1908 *outLength = 0; | 1908 *outLength = 0; |
| 1909 return SECSuccess; | 1909 return SECSuccess; |
| 1910 } | 1910 } |
| 1911 if (! spec->bypassCiphers) { | 1911 if (! spec->bypassCiphers) { |
| 1912 PK11Context *mac_context = | 1912 PK11Context *mac_context = |
| 1913 (useServerMacKey ? spec->server.write_mac_context | 1913 (useServerMacKey ? spec->server.write_mac_context |
| 1914 : spec->client.write_mac_context); | 1914 : spec->client.write_mac_context); |
| 1915 rv = PK11_DigestBegin(mac_context); | 1915 rv = PK11_DigestBegin(mac_context); |
| 1916 rv |= PK11_DigestOp(mac_context, temp, tempLen); | 1916 rv |= PK11_DigestOp(mac_context, temp, tempLen); |
| 1917 » rv |= PK11_DigestOp(mac_context, input, inputLength); | 1917 » if (inputLength > 0) { |
| 1918 » rv |= PK11_DigestOp(mac_context, input, inputLength); | |
| 1919 » } | |
|
wtc
2011/06/23 23:58:33
It may be safe to pass inputLength=0 to PK11_Diges
agl
2011/06/24 18:50:18
Done
| |
| 1918 rv |= PK11_DigestFinal(mac_context, outbuf, outLength, spec->mac_size); | 1920 rv |= PK11_DigestFinal(mac_context, outbuf, outLength, spec->mac_size); |
| 1919 } else { | 1921 } else { |
| 1920 /* bypass version */ | 1922 /* bypass version */ |
| 1921 const SECHashObject *hashObj = NULL; | 1923 const SECHashObject *hashObj = NULL; |
| 1922 unsigned int pad_bytes = 0; | 1924 unsigned int pad_bytes = 0; |
| 1923 PRUint64 write_mac_context[MAX_MAC_CONTEXT_LLONGS]; | 1925 PRUint64 write_mac_context[MAX_MAC_CONTEXT_LLONGS]; |
| 1924 | 1926 |
| 1925 switch (mac_def->mac) { | 1927 switch (mac_def->mac) { |
| 1926 case ssl_mac_null: | 1928 case ssl_mac_null: |
| 1927 *outLength = 0; | 1929 *outLength = 0; |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2060 | 2062 |
| 2061 ssl_GetSpecReadLock(ss); /********************************/ | 2063 ssl_GetSpecReadLock(ss); /********************************/ |
| 2062 | 2064 |
| 2063 cwSpec = ss->ssl3.cwSpec; | 2065 cwSpec = ss->ssl3.cwSpec; |
| 2064 cipher_def = cwSpec->cipher_def; | 2066 cipher_def = cwSpec->cipher_def; |
| 2065 | 2067 |
| 2066 if (cwSpec->compressor) { | 2068 if (cwSpec->compressor) { |
| 2067 int outlen; | 2069 int outlen; |
| 2068 rv = cwSpec->compressor( | 2070 rv = cwSpec->compressor( |
| 2069 cwSpec->compressContext, wrBuf->buf + SSL3_RECORD_HEADER_LENGTH, | 2071 cwSpec->compressContext, wrBuf->buf + SSL3_RECORD_HEADER_LENGTH, |
| 2070 &outlen, wrBuf->space - SSL3_RECORD_HEADER_LENGTH, pIn, contentLen); | 2072 &outlen, wrBuf->space - SSL3_RECORD_HEADER_LENGTH, pIn, contentLen); |
|
wtc
2011/06/23 23:58:33
Please confirm that it is fine to pass pIn=NULL an
agl
2011/06/24 18:50:18
Done.
| |
| 2071 if (rv != SECSuccess) | 2073 if (rv != SECSuccess) |
| 2072 return rv; | 2074 return rv; |
| 2073 pIn = wrBuf->buf + SSL3_RECORD_HEADER_LENGTH; | 2075 pIn = wrBuf->buf + SSL3_RECORD_HEADER_LENGTH; |
| 2074 contentLen = outlen; | 2076 contentLen = outlen; |
| 2075 } | 2077 } |
| 2076 | 2078 |
| 2077 /* | 2079 /* |
| 2078 * Add the MAC | 2080 * Add the MAC |
| 2079 */ | 2081 */ |
| 2080 rv = ssl3_ComputeRecordMAC( cwSpec, (PRBool)(ss->sec.isServer), | 2082 rv = ssl3_ComputeRecordMAC( cwSpec, (PRBool)(ss->sec.isServer), |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2222 return SECFailure; /* ssl3_InitState has set the error code. */ | 2224 return SECFailure; /* ssl3_InitState has set the error code. */ |
| 2223 } | 2225 } |
| 2224 } | 2226 } |
| 2225 | 2227 |
| 2226 /* check for Token Presence */ | 2228 /* check for Token Presence */ |
| 2227 if (!ssl3_ClientAuthTokenPresent(ss->sec.ci.sid)) { | 2229 if (!ssl3_ClientAuthTokenPresent(ss->sec.ci.sid)) { |
| 2228 PORT_SetError(SSL_ERROR_TOKEN_INSERTION_REMOVAL); | 2230 PORT_SetError(SSL_ERROR_TOKEN_INSERTION_REMOVAL); |
| 2229 return SECFailure; | 2231 return SECFailure; |
| 2230 } | 2232 } |
| 2231 | 2233 |
| 2232 while (nIn > 0) { | 2234 do { |
| 2233 PRUint32 contentLen = PR_MIN(nIn, MAX_FRAGMENT_LENGTH); | 2235 PRUint32 contentLen = PR_MIN(nIn, MAX_FRAGMENT_LENGTH); |
| 2234 | 2236 |
| 2235 if (wrBuf->space < contentLen + SSL3_BUFFER_FUDGE) { | 2237 if (wrBuf->space < contentLen + SSL3_BUFFER_FUDGE) { |
| 2236 PRInt32 newSpace = PR_MAX(wrBuf->space * 2, contentLen); | 2238 PRInt32 newSpace = PR_MAX(wrBuf->space * 2, contentLen); |
| 2237 newSpace = PR_MIN(newSpace, MAX_FRAGMENT_LENGTH); | 2239 newSpace = PR_MIN(newSpace, MAX_FRAGMENT_LENGTH); |
| 2238 newSpace += SSL3_BUFFER_FUDGE; | 2240 newSpace += SSL3_BUFFER_FUDGE; |
| 2239 rv = sslBuffer_Grow(wrBuf, newSpace); | 2241 rv = sslBuffer_Grow(wrBuf, newSpace); |
| 2240 if (rv != SECSuccess) { | 2242 if (rv != SECSuccess) { |
| 2241 SSL_DBG(("%d: SSL3[%d]: SendRecord, tried to get %d bytes", | 2243 SSL_DBG(("%d: SSL3[%d]: SendRecord, tried to get %d bytes", |
| 2242 SSL_GETPID(), ss->fd, newSpace)); | 2244 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. | 2301 * append it to the buffer of previously unsent ciphertext. |
| 2300 */ | 2302 */ |
| 2301 rv = ssl_SaveWriteData(ss, wrBuf->buf + sent, wrBuf->len); | 2303 rv = ssl_SaveWriteData(ss, wrBuf->buf + sent, wrBuf->len); |
| 2302 if (rv != SECSuccess) { | 2304 if (rv != SECSuccess) { |
| 2303 /* presumably a memory error, SEC_ERROR_NO_MEMORY */ | 2305 /* presumably a memory error, SEC_ERROR_NO_MEMORY */ |
| 2304 return SECFailure; | 2306 return SECFailure; |
| 2305 } | 2307 } |
| 2306 } | 2308 } |
| 2307 } | 2309 } |
| 2308 totalSent += contentLen; | 2310 totalSent += contentLen; |
| 2309 } | 2311 } while (nIn > 0); |
| 2310 return totalSent; | 2312 return totalSent; |
| 2311 } | 2313 } |
| 2312 | 2314 |
| 2313 #define SSL3_PENDING_HIGH_WATER 1024 | 2315 #define SSL3_PENDING_HIGH_WATER 1024 |
| 2314 | 2316 |
| 2315 /* Attempt to send the content of "in" in an SSL application_data record. | 2317 /* Attempt to send the content of "in" in an SSL application_data record. |
| 2316 * Returns "len" or SECFailure, never SECWouldBlock, nor SECSuccess. | 2318 * Returns "len" or SECFailure, never SECWouldBlock, nor SECSuccess. |
| 2317 */ | 2319 */ |
| 2318 int | 2320 int |
| 2319 ssl3_SendApplicationData(sslSocket *ss, const unsigned char *in, | 2321 ssl3_SendApplicationData(sslSocket *ss, const unsigned char *in, |
| 2320 PRInt32 len, PRInt32 flags) | 2322 PRInt32 len, PRInt32 flags) |
| 2321 { | 2323 { |
| 2322 PRInt32 totalSent = 0; | 2324 PRInt32 totalSent = 0; |
| 2323 PRInt32 discarded = 0; | 2325 PRInt32 discarded = 0; |
| 2326 PRBool is_block_cipher; | |
|
wtc
2011/06/23 23:58:33
Nit: name the variable isBlockCipher.
agl
2011/06/24 18:50:18
Done.
| |
| 2324 | 2327 |
| 2325 PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) ); | 2328 PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) ); |
| 2326 if (len < 0 || !in) { | 2329 if (len < 0 || !in) { |
| 2327 PORT_SetError(PR_INVALID_ARGUMENT_ERROR); | 2330 PORT_SetError(PR_INVALID_ARGUMENT_ERROR); |
| 2328 return SECFailure; | 2331 return SECFailure; |
| 2329 } | 2332 } |
| 2330 | 2333 |
| 2331 if (ss->pendingBuf.len > SSL3_PENDING_HIGH_WATER && | 2334 if (ss->pendingBuf.len > SSL3_PENDING_HIGH_WATER && |
| 2332 !ssl_SocketIsBlocking(ss)) { | 2335 !ssl_SocketIsBlocking(ss)) { |
| 2333 PORT_Assert(!ssl_SocketIsBlocking(ss)); | 2336 PORT_Assert(!ssl_SocketIsBlocking(ss)); |
| 2334 PORT_SetError(PR_WOULD_BLOCK_ERROR); | 2337 PORT_SetError(PR_WOULD_BLOCK_ERROR); |
| 2335 return SECFailure; | 2338 return SECFailure; |
| 2336 } | 2339 } |
| 2337 | 2340 |
| 2338 if (ss->appDataBuffered && len) { | 2341 if (ss->appDataBuffered && len) { |
| 2339 PORT_Assert (in[0] == (unsigned char)(ss->appDataBuffered)); | 2342 PORT_Assert (in[0] == (unsigned char)(ss->appDataBuffered)); |
| 2340 if (in[0] != (unsigned char)(ss->appDataBuffered)) { | 2343 if (in[0] != (unsigned char)(ss->appDataBuffered)) { |
| 2341 PORT_SetError(PR_INVALID_ARGUMENT_ERROR); | 2344 PORT_SetError(PR_INVALID_ARGUMENT_ERROR); |
| 2342 return SECFailure; | 2345 return SECFailure; |
| 2343 } | 2346 } |
| 2344 in++; | 2347 in++; |
| 2345 len--; | 2348 len--; |
| 2346 discarded = 1; | 2349 discarded = 1; |
| 2347 } | 2350 } |
| 2351 | |
| 2352 ssl_GetSpecReadLock(ss); | |
| 2353 is_block_cipher = ss->ssl3.cwSpec->cipher_def->type == type_block; | |
| 2354 ssl_ReleaseSpecReadLock(ss); | |
| 2355 | |
| 2356 if (is_block_cipher) { | |
|
wtc
2011/06/23 23:58:33
We should also test if len > 0.
agl
2011/06/24 18:50:18
Done.
| |
| 2357 // We assume that block ciphers are used in CBC mode and prepend an | |
| 2358 // empty record. This effectively randomizes the IV in a backwards | |
| 2359 // compatible way. | |
| 2360 PRInt32 sent = ssl3_SendRecord(ss, content_application_data, | |
| 2361 NULL, 0 /* no payload */, flags); | |
| 2362 if (sent < 0) { | |
| 2363 return SECFailure; /* error code set by ssl3_SendRecord */ | |
| 2364 } | |
|
wtc
2011/06/23 23:58:33
I think we also need to duplicate the code from li
agl
2011/06/24 18:50:18
I didn't do this. Here's my reasoning:
The code i
| |
| 2365 } | |
| 2366 | |
| 2348 while (len > totalSent) { | 2367 while (len > totalSent) { |
| 2349 PRInt32 sent, toSend; | 2368 PRInt32 sent, toSend; |
| 2350 | 2369 |
| 2351 if (totalSent > 0) { | 2370 if (totalSent > 0) { |
| 2352 /* | 2371 /* |
| 2353 * The thread yield is intended to give the reader thread a | 2372 * The thread yield is intended to give the reader thread a |
| 2354 * chance to get some cycles while the writer thread is in | 2373 * chance to get some cycles while the writer thread is in |
| 2355 * the middle of a large application data write. (See | 2374 * the middle of a large application data write. (See |
| 2356 * Bugzilla bug 127740, comment #1.) | 2375 * Bugzilla bug 127740, comment #1.) |
| 2357 */ | 2376 */ |
| (...skipping 7491 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 9849 | 9868 |
| 9850 ss->ssl3.initialized = PR_FALSE; | 9869 ss->ssl3.initialized = PR_FALSE; |
| 9851 | 9870 |
| 9852 if (ss->ssl3.nextProto.data) { | 9871 if (ss->ssl3.nextProto.data) { |
| 9853 PORT_Free(ss->ssl3.nextProto.data); | 9872 PORT_Free(ss->ssl3.nextProto.data); |
| 9854 ss->ssl3.nextProto.data = NULL; | 9873 ss->ssl3.nextProto.data = NULL; |
| 9855 } | 9874 } |
| 9856 } | 9875 } |
| 9857 | 9876 |
| 9858 /* End of ssl3con.c */ | 9877 /* End of ssl3con.c */ |
| OLD | NEW |