OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // OpenSSL binding for SSLClientSocket. The class layout and general principle | 5 // OpenSSL binding for SSLClientSocket. The class layout and general principle |
6 // of operation is derived from SSLClientSocketNSS. | 6 // of operation is derived from SSLClientSocketNSS. |
7 | 7 |
8 #include "net/socket/ssl_client_socket_openssl.h" | 8 #include "net/socket/ssl_client_socket_openssl.h" |
9 | 9 |
10 #include <openssl/ssl.h> | 10 #include <openssl/ssl.h> |
(...skipping 25 matching lines...) Expand all Loading... |
36 #define GotoState(s) do { DVLOG(2) << (void *)this << " " << __FUNCTION__ << \ | 36 #define GotoState(s) do { DVLOG(2) << (void *)this << " " << __FUNCTION__ << \ |
37 " jump to state " << s; \ | 37 " jump to state " << s; \ |
38 next_handshake_state_ = s; } while (0) | 38 next_handshake_state_ = s; } while (0) |
39 #else | 39 #else |
40 #define GotoState(s) next_handshake_state_ = s | 40 #define GotoState(s) next_handshake_state_ = s |
41 #endif | 41 #endif |
42 | 42 |
43 const int kSessionCacheTimeoutSeconds = 60 * 60; | 43 const int kSessionCacheTimeoutSeconds = 60 * 60; |
44 const size_t kSessionCacheMaxEntires = 1024; | 44 const size_t kSessionCacheMaxEntires = 1024; |
45 | 45 |
| 46 // This constant can be any non-negative/non-zero value (eg: it does not |
| 47 // overlap with any value of the net::Error range, including net::OK). |
| 48 const int kNoPendingReadResult = 1; |
| 49 |
46 // If a client doesn't have a list of protocols that it supports, but | 50 // If a client doesn't have a list of protocols that it supports, but |
47 // the server supports NPN, choosing "http/1.1" is the best answer. | 51 // the server supports NPN, choosing "http/1.1" is the best answer. |
48 const char kDefaultSupportedNPNProtocol[] = "http/1.1"; | 52 const char kDefaultSupportedNPNProtocol[] = "http/1.1"; |
49 | 53 |
50 #if OPENSSL_VERSION_NUMBER < 0x1000103fL | 54 #if OPENSSL_VERSION_NUMBER < 0x1000103fL |
51 // This method doesn't seem to have made it into the OpenSSL headers. | 55 // This method doesn't seem to have made it into the OpenSSL headers. |
52 unsigned long SSL_CIPHER_get_id(const SSL_CIPHER* cipher) { return cipher->id; } | 56 unsigned long SSL_CIPHER_get_id(const SSL_CIPHER* cipher) { return cipher->id; } |
53 #endif | 57 #endif |
54 | 58 |
55 // Used for encoding the |connection_status| field of an SSLInfo object. | 59 // Used for encoding the |connection_status| field of an SSLInfo object. |
(...skipping 362 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
418 } | 422 } |
419 | 423 |
420 SSLClientSocketOpenSSL::SSLClientSocketOpenSSL( | 424 SSLClientSocketOpenSSL::SSLClientSocketOpenSSL( |
421 ClientSocketHandle* transport_socket, | 425 ClientSocketHandle* transport_socket, |
422 const HostPortPair& host_and_port, | 426 const HostPortPair& host_and_port, |
423 const SSLConfig& ssl_config, | 427 const SSLConfig& ssl_config, |
424 const SSLClientSocketContext& context) | 428 const SSLClientSocketContext& context) |
425 : transport_send_busy_(false), | 429 : transport_send_busy_(false), |
426 transport_recv_busy_(false), | 430 transport_recv_busy_(false), |
427 transport_recv_eof_(false), | 431 transport_recv_eof_(false), |
| 432 pending_read_error_(kNoPendingReadResult), |
428 completed_handshake_(false), | 433 completed_handshake_(false), |
429 client_auth_cert_needed_(false), | 434 client_auth_cert_needed_(false), |
430 cert_verifier_(context.cert_verifier), | 435 cert_verifier_(context.cert_verifier), |
431 ssl_(NULL), | 436 ssl_(NULL), |
432 transport_bio_(NULL), | 437 transport_bio_(NULL), |
433 transport_(transport_socket), | 438 transport_(transport_socket), |
434 host_and_port_(host_and_port), | 439 host_and_port_(host_and_port), |
435 ssl_config_(ssl_config), | 440 ssl_config_(ssl_config), |
436 ssl_session_cache_shard_(context.ssl_session_cache_shard), | 441 ssl_session_cache_shard_(context.ssl_session_cache_shard), |
437 trying_cached_session_(false), | 442 trying_cached_session_(false), |
(...skipping 895 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1333 bool SSLClientSocketOpenSSL::SetReceiveBufferSize(int32 size) { | 1338 bool SSLClientSocketOpenSSL::SetReceiveBufferSize(int32 size) { |
1334 return transport_->socket()->SetReceiveBufferSize(size); | 1339 return transport_->socket()->SetReceiveBufferSize(size); |
1335 } | 1340 } |
1336 | 1341 |
1337 bool SSLClientSocketOpenSSL::SetSendBufferSize(int32 size) { | 1342 bool SSLClientSocketOpenSSL::SetSendBufferSize(int32 size) { |
1338 return transport_->socket()->SetSendBufferSize(size); | 1343 return transport_->socket()->SetSendBufferSize(size); |
1339 } | 1344 } |
1340 | 1345 |
1341 int SSLClientSocketOpenSSL::DoPayloadRead() { | 1346 int SSLClientSocketOpenSSL::DoPayloadRead() { |
1342 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); | 1347 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); |
1343 int rv = SSL_read(ssl_, user_read_buf_->data(), user_read_buf_len_); | 1348 |
1344 // We don't need to invalidate the non-client-authenticated SSL session | 1349 int rv; |
1345 // because the server will renegotiate anyway. | 1350 if (pending_read_error_ != kNoPendingReadResult) { |
1346 if (client_auth_cert_needed_) | 1351 rv = pending_read_error_; |
1347 return ERR_SSL_CLIENT_AUTH_CERT_NEEDED; | 1352 pending_read_error_ = kNoPendingReadResult; |
| 1353 if (rv == 0) { |
| 1354 net_log_.AddByteTransferEvent(NetLog::TYPE_SSL_SOCKET_BYTES_RECEIVED, |
| 1355 rv, user_read_buf_->data()); |
| 1356 } |
| 1357 return rv; |
| 1358 } |
| 1359 |
| 1360 int total_bytes_read = 0; |
| 1361 do { |
| 1362 rv = SSL_read(ssl_, user_read_buf_->data() + total_bytes_read, |
| 1363 user_read_buf_len_ - total_bytes_read); |
| 1364 if (rv > 0) |
| 1365 total_bytes_read += rv; |
| 1366 } while (total_bytes_read < user_read_buf_len_ && rv > 0); |
| 1367 |
| 1368 if (total_bytes_read == user_read_buf_len_) { |
| 1369 rv = total_bytes_read; |
| 1370 } else { |
| 1371 // Otherwise, an error occurred (rv <= 0). The error needs to be handled |
| 1372 // immediately, while the OpenSSL errors are still available in |
| 1373 // thread-local storage. However, the handled/remapped error code should |
| 1374 // only be returned if no application data was already read; if it was, the |
| 1375 // error code should be deferred until the next call of DoPayloadRead. |
| 1376 // |
| 1377 // If no data was read, |*next_result| will point to the return value of |
| 1378 // this function. If at least some data was read, |*next_result| will point |
| 1379 // to |pending_read_error_|, to be returned in a future call to |
| 1380 // DoPayloadRead() (e.g.: after the current data is handled). |
| 1381 int *next_result = &rv; |
| 1382 if (total_bytes_read > 0) { |
| 1383 pending_read_error_ = rv; |
| 1384 rv = total_bytes_read; |
| 1385 next_result = &pending_read_error_; |
| 1386 } |
| 1387 |
| 1388 if (client_auth_cert_needed_) { |
| 1389 *next_result = ERR_SSL_CLIENT_AUTH_CERT_NEEDED; |
| 1390 } else if (*next_result < 0) { |
| 1391 int err = SSL_get_error(ssl_, *next_result); |
| 1392 *next_result = MapOpenSSLError(err, err_tracer); |
| 1393 if (rv > 0 && *next_result == ERR_IO_PENDING) { |
| 1394 // If at least some data was read from SSL_read(), do not treat |
| 1395 // insufficient data as an error to return in the next call to |
| 1396 // DoPayloadRead() - instead, let the call fall through to check |
| 1397 // SSL_read() again. This is because DoTransportIO() may complete |
| 1398 // in between the next call to DoPayloadRead(), and thus it is |
| 1399 // important to check SSL_read() on subsequent invocations to see |
| 1400 // if a complete record may now be read. |
| 1401 *next_result = kNoPendingReadResult; |
| 1402 } |
| 1403 } |
| 1404 } |
1348 | 1405 |
1349 if (rv >= 0) { | 1406 if (rv >= 0) { |
1350 net_log_.AddByteTransferEvent(NetLog::TYPE_SSL_SOCKET_BYTES_RECEIVED, rv, | 1407 net_log_.AddByteTransferEvent(NetLog::TYPE_SSL_SOCKET_BYTES_RECEIVED, rv, |
1351 user_read_buf_->data()); | 1408 user_read_buf_->data()); |
1352 return rv; | |
1353 } | 1409 } |
1354 | 1410 return rv; |
1355 int err = SSL_get_error(ssl_, rv); | |
1356 return MapOpenSSLError(err, err_tracer); | |
1357 } | 1411 } |
1358 | 1412 |
1359 int SSLClientSocketOpenSSL::DoPayloadWrite() { | 1413 int SSLClientSocketOpenSSL::DoPayloadWrite() { |
1360 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); | 1414 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); |
1361 int rv = SSL_write(ssl_, user_write_buf_->data(), user_write_buf_len_); | 1415 int rv = SSL_write(ssl_, user_write_buf_->data(), user_write_buf_len_); |
1362 | 1416 |
1363 if (rv >= 0) { | 1417 if (rv >= 0) { |
1364 net_log_.AddByteTransferEvent(NetLog::TYPE_SSL_SOCKET_BYTES_SENT, rv, | 1418 net_log_.AddByteTransferEvent(NetLog::TYPE_SSL_SOCKET_BYTES_SENT, rv, |
1365 user_write_buf_->data()); | 1419 user_write_buf_->data()); |
1366 return rv; | 1420 return rv; |
1367 } | 1421 } |
1368 | 1422 |
1369 int err = SSL_get_error(ssl_, rv); | 1423 int err = SSL_get_error(ssl_, rv); |
1370 return MapOpenSSLError(err, err_tracer); | 1424 return MapOpenSSLError(err, err_tracer); |
1371 } | 1425 } |
1372 | 1426 |
1373 } // namespace net | 1427 } // namespace net |
OLD | NEW |