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 |