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 <errno.h> |
10 #include <openssl/err.h> | 11 #include <openssl/err.h> |
11 #include <openssl/opensslv.h> | |
12 #include <openssl/ssl.h> | 12 #include <openssl/ssl.h> |
13 | 13 |
14 #include "base/bind.h" | 14 #include "base/bind.h" |
15 #include "base/callback_helpers.h" | 15 #include "base/callback_helpers.h" |
16 #include "base/memory/singleton.h" | 16 #include "base/memory/singleton.h" |
17 #include "base/metrics/histogram.h" | 17 #include "base/metrics/histogram.h" |
18 #include "base/synchronization/lock.h" | 18 #include "base/synchronization/lock.h" |
19 #include "crypto/ec_private_key.h" | 19 #include "crypto/ec_private_key.h" |
20 #include "crypto/openssl_util.h" | 20 #include "crypto/openssl_util.h" |
21 #include "crypto/scoped_openssl_types.h" | 21 #include "crypto/scoped_openssl_types.h" |
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
241 SSLClientSocketOpenSSL::PeerCertificateChain::operator=( | 241 SSLClientSocketOpenSSL::PeerCertificateChain::operator=( |
242 const PeerCertificateChain& other) { | 242 const PeerCertificateChain& other) { |
243 if (this == &other) | 243 if (this == &other) |
244 return *this; | 244 return *this; |
245 | 245 |
246 // os_chain_ is reference counted by scoped_refptr; | 246 // os_chain_ is reference counted by scoped_refptr; |
247 os_chain_ = other.os_chain_; | 247 os_chain_ = other.os_chain_; |
248 | 248 |
249 // Must increase the reference count manually for sk_X509_dup | 249 // Must increase the reference count manually for sk_X509_dup |
250 openssl_chain_.reset(sk_X509_dup(other.openssl_chain_.get())); | 250 openssl_chain_.reset(sk_X509_dup(other.openssl_chain_.get())); |
251 for (int i = 0; i < sk_X509_num(openssl_chain_.get()); ++i) { | 251 for (size_t i = 0; i < sk_X509_num(openssl_chain_.get()); ++i) { |
252 X509* x = sk_X509_value(openssl_chain_.get(), i); | 252 X509* x = sk_X509_value(openssl_chain_.get(), i); |
253 CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509); | 253 CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509); |
254 } | 254 } |
255 return *this; | 255 return *this; |
256 } | 256 } |
257 | 257 |
258 #if defined(USE_OPENSSL_CERTS) | 258 #if defined(USE_OPENSSL_CERTS) |
259 // When OSCertHandle is typedef'ed to X509, this implementation does a short cut | 259 // When OSCertHandle is typedef'ed to X509, this implementation does a short cut |
260 // to avoid converting back and forth between der and X509 struct. | 260 // to avoid converting back and forth between der and X509 struct. |
261 void SSLClientSocketOpenSSL::PeerCertificateChain::Reset( | 261 void SSLClientSocketOpenSSL::PeerCertificateChain::Reset( |
262 STACK_OF(X509)* chain) { | 262 STACK_OF(X509)* chain) { |
263 openssl_chain_.reset(NULL); | 263 openssl_chain_.reset(NULL); |
264 os_chain_ = NULL; | 264 os_chain_ = NULL; |
265 | 265 |
266 if (!chain) | 266 if (!chain) |
267 return; | 267 return; |
268 | 268 |
269 X509Certificate::OSCertHandles intermediates; | 269 X509Certificate::OSCertHandles intermediates; |
270 for (int i = 1; i < sk_X509_num(chain); ++i) | 270 for (size_t i = 1; i < sk_X509_num(chain); ++i) |
271 intermediates.push_back(sk_X509_value(chain, i)); | 271 intermediates.push_back(sk_X509_value(chain, i)); |
272 | 272 |
273 os_chain_ = | 273 os_chain_ = |
274 X509Certificate::CreateFromHandle(sk_X509_value(chain, 0), intermediates); | 274 X509Certificate::CreateFromHandle(sk_X509_value(chain, 0), intermediates); |
275 | 275 |
276 // sk_X509_dup does not increase reference count on the certs in the stack. | 276 // sk_X509_dup does not increase reference count on the certs in the stack. |
277 openssl_chain_.reset(sk_X509_dup(chain)); | 277 openssl_chain_.reset(sk_X509_dup(chain)); |
278 | 278 |
279 std::vector<base::StringPiece> der_chain; | 279 std::vector<base::StringPiece> der_chain; |
280 for (int i = 0; i < sk_X509_num(openssl_chain_.get()); ++i) { | 280 for (size_t i = 0; i < sk_X509_num(openssl_chain_.get()); ++i) { |
281 X509* x = sk_X509_value(openssl_chain_.get(), i); | 281 X509* x = sk_X509_value(openssl_chain_.get(), i); |
282 // Increase the reference count for the certs in openssl_chain_. | 282 // Increase the reference count for the certs in openssl_chain_. |
283 CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509); | 283 CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509); |
284 } | 284 } |
285 } | 285 } |
286 #else // !defined(USE_OPENSSL_CERTS) | 286 #else // !defined(USE_OPENSSL_CERTS) |
287 void SSLClientSocketOpenSSL::PeerCertificateChain::Reset( | 287 void SSLClientSocketOpenSSL::PeerCertificateChain::Reset( |
288 STACK_OF(X509)* chain) { | 288 STACK_OF(X509)* chain) { |
289 openssl_chain_.reset(NULL); | 289 openssl_chain_.reset(NULL); |
290 os_chain_ = NULL; | 290 os_chain_ = NULL; |
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
500 | 500 |
501 bool SSLClientSocketOpenSSL::IsConnectedAndIdle() const { | 501 bool SSLClientSocketOpenSSL::IsConnectedAndIdle() const { |
502 // If the handshake has not yet completed. | 502 // If the handshake has not yet completed. |
503 if (!completed_handshake_) | 503 if (!completed_handshake_) |
504 return false; | 504 return false; |
505 // If an asynchronous operation is still pending. | 505 // If an asynchronous operation is still pending. |
506 if (user_read_buf_.get() || user_write_buf_.get()) | 506 if (user_read_buf_.get() || user_write_buf_.get()) |
507 return false; | 507 return false; |
508 // If there is data waiting to be sent, or data read from the network that | 508 // If there is data waiting to be sent, or data read from the network that |
509 // has not yet been consumed. | 509 // has not yet been consumed. |
510 if (BIO_ctrl_pending(transport_bio_) > 0 || | 510 if (BIO_pending(transport_bio_) > 0 || |
511 BIO_ctrl_wpending(transport_bio_) > 0) { | 511 BIO_wpending(transport_bio_) > 0) { |
512 return false; | 512 return false; |
513 } | 513 } |
514 | 514 |
515 return transport_->socket()->IsConnectedAndIdle(); | 515 return transport_->socket()->IsConnectedAndIdle(); |
516 } | 516 } |
517 | 517 |
518 int SSLClientSocketOpenSSL::GetPeerAddress(IPEndPoint* addressList) const { | 518 int SSLClientSocketOpenSSL::GetPeerAddress(IPEndPoint* addressList) const { |
519 return transport_->socket()->GetPeerAddress(addressList); | 519 return transport_->socket()->GetPeerAddress(addressList); |
520 } | 520 } |
521 | 521 |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
571 ssl_info->channel_id_sent = WasChannelIDSent(); | 571 ssl_info->channel_id_sent = WasChannelIDSent(); |
572 | 572 |
573 RecordChannelIDSupport(server_bound_cert_service_, | 573 RecordChannelIDSupport(server_bound_cert_service_, |
574 channel_id_xtn_negotiated_, | 574 channel_id_xtn_negotiated_, |
575 ssl_config_.channel_id_enabled, | 575 ssl_config_.channel_id_enabled, |
576 crypto::ECPrivateKey::IsSupported()); | 576 crypto::ECPrivateKey::IsSupported()); |
577 | 577 |
578 const SSL_CIPHER* cipher = SSL_get_current_cipher(ssl_); | 578 const SSL_CIPHER* cipher = SSL_get_current_cipher(ssl_); |
579 CHECK(cipher); | 579 CHECK(cipher); |
580 ssl_info->security_bits = SSL_CIPHER_get_bits(cipher, NULL); | 580 ssl_info->security_bits = SSL_CIPHER_get_bits(cipher, NULL); |
581 const COMP_METHOD* compression = SSL_get_current_compression(ssl_); | |
582 | 581 |
583 ssl_info->connection_status = EncodeSSLConnectionStatus( | 582 ssl_info->connection_status = EncodeSSLConnectionStatus( |
584 SSL_CIPHER_get_id(cipher), | 583 SSL_CIPHER_get_id(cipher), 0 /* no compression */, |
585 compression ? compression->type : 0, | |
586 GetNetSSLVersion(ssl_)); | 584 GetNetSSLVersion(ssl_)); |
587 | 585 |
588 bool peer_supports_renego_ext = !!SSL_get_secure_renegotiation_support(ssl_); | 586 bool peer_supports_renego_ext = !!SSL_get_secure_renegotiation_support(ssl_); |
589 if (!peer_supports_renego_ext) | 587 if (!peer_supports_renego_ext) |
590 ssl_info->connection_status |= SSL_CONNECTION_NO_RENEGOTIATION_EXTENSION; | 588 ssl_info->connection_status |= SSL_CONNECTION_NO_RENEGOTIATION_EXTENSION; |
591 UMA_HISTOGRAM_ENUMERATION("Net.RenegotiationExtensionSupported", | 589 UMA_HISTOGRAM_ENUMERATION("Net.RenegotiationExtensionSupported", |
592 implicit_cast<int>(peer_supports_renego_ext), 2); | 590 implicit_cast<int>(peer_supports_renego_ext), 2); |
593 | 591 |
594 if (ssl_config_.version_fallback) | 592 if (ssl_config_.version_fallback) |
595 ssl_info->connection_status |= SSL_CONNECTION_VERSION_FALLBACK; | 593 ssl_info->connection_status |= SSL_CONNECTION_VERSION_FALLBACK; |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
725 STACK_OF(SSL_CIPHER)* ciphers = SSL_get_ciphers(ssl_); | 723 STACK_OF(SSL_CIPHER)* ciphers = SSL_get_ciphers(ssl_); |
726 DCHECK(ciphers); | 724 DCHECK(ciphers); |
727 // See SSLConfig::disabled_cipher_suites for description of the suites | 725 // See SSLConfig::disabled_cipher_suites for description of the suites |
728 // disabled by default. Note that !SHA256 and !SHA384 only remove HMAC-SHA256 | 726 // disabled by default. Note that !SHA256 and !SHA384 only remove HMAC-SHA256 |
729 // and HMAC-SHA384 cipher suites, not GCM cipher suites with SHA256 or SHA384 | 727 // and HMAC-SHA384 cipher suites, not GCM cipher suites with SHA256 or SHA384 |
730 // as the handshake hash. | 728 // as the handshake hash. |
731 std::string command("DEFAULT:!NULL:!aNULL:!IDEA:!FZA:!SRP:!SHA256:!SHA384:" | 729 std::string command("DEFAULT:!NULL:!aNULL:!IDEA:!FZA:!SRP:!SHA256:!SHA384:" |
732 "!aECDH:!AESGCM+AES256"); | 730 "!aECDH:!AESGCM+AES256"); |
733 // Walk through all the installed ciphers, seeing if any need to be | 731 // Walk through all the installed ciphers, seeing if any need to be |
734 // appended to the cipher removal |command|. | 732 // appended to the cipher removal |command|. |
735 for (int i = 0; i < sk_SSL_CIPHER_num(ciphers); ++i) { | 733 for (size_t i = 0; i < sk_SSL_CIPHER_num(ciphers); ++i) { |
736 const SSL_CIPHER* cipher = sk_SSL_CIPHER_value(ciphers, i); | 734 const SSL_CIPHER* cipher = sk_SSL_CIPHER_value(ciphers, i); |
737 const uint16 id = SSL_CIPHER_get_id(cipher); | 735 const uint16 id = SSL_CIPHER_get_id(cipher); |
738 // Remove any ciphers with a strength of less than 80 bits. Note the NSS | 736 // Remove any ciphers with a strength of less than 80 bits. Note the NSS |
739 // implementation uses "effective" bits here but OpenSSL does not provide | 737 // implementation uses "effective" bits here but OpenSSL does not provide |
740 // this detail. This only impacts Triple DES: reports 112 vs. 168 bits, | 738 // this detail. This only impacts Triple DES: reports 112 vs. 168 bits, |
741 // both of which are greater than 80 anyway. | 739 // both of which are greater than 80 anyway. |
742 bool disable = SSL_CIPHER_get_bits(cipher, NULL) < 80; | 740 bool disable = SSL_CIPHER_get_bits(cipher, NULL) < 80; |
743 if (!disable) { | 741 if (!disable) { |
744 disable = std::find(ssl_config_.disabled_cipher_suites.begin(), | 742 disable = std::find(ssl_config_.disabled_cipher_suites.begin(), |
745 ssl_config_.disabled_cipher_suites.end(), id) != | 743 ssl_config_.disabled_cipher_suites.end(), id) != |
(...skipping 453 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1199 int err = SSL_get_error(ssl_, rv); | 1197 int err = SSL_get_error(ssl_, rv); |
1200 return MapOpenSSLError(err, err_tracer); | 1198 return MapOpenSSLError(err, err_tracer); |
1201 } | 1199 } |
1202 | 1200 |
1203 int SSLClientSocketOpenSSL::BufferSend(void) { | 1201 int SSLClientSocketOpenSSL::BufferSend(void) { |
1204 if (transport_send_busy_) | 1202 if (transport_send_busy_) |
1205 return ERR_IO_PENDING; | 1203 return ERR_IO_PENDING; |
1206 | 1204 |
1207 if (!send_buffer_.get()) { | 1205 if (!send_buffer_.get()) { |
1208 // Get a fresh send buffer out of the send BIO. | 1206 // Get a fresh send buffer out of the send BIO. |
1209 size_t max_read = BIO_ctrl_pending(transport_bio_); | 1207 size_t max_read = BIO_pending(transport_bio_); |
1210 if (!max_read) | 1208 if (!max_read) |
1211 return 0; // Nothing pending in the OpenSSL write BIO. | 1209 return 0; // Nothing pending in the OpenSSL write BIO. |
1212 send_buffer_ = new DrainableIOBuffer(new IOBuffer(max_read), max_read); | 1210 send_buffer_ = new DrainableIOBuffer(new IOBuffer(max_read), max_read); |
1213 int read_bytes = BIO_read(transport_bio_, send_buffer_->data(), max_read); | 1211 int read_bytes = BIO_read(transport_bio_, send_buffer_->data(), max_read); |
1214 DCHECK_GT(read_bytes, 0); | 1212 DCHECK_GT(read_bytes, 0); |
1215 CHECK_EQ(static_cast<int>(max_read), read_bytes); | 1213 CHECK_EQ(static_cast<int>(max_read), read_bytes); |
1216 } | 1214 } |
1217 | 1215 |
1218 int rv = transport_->socket()->Write( | 1216 int rv = transport_->socket()->Write( |
1219 send_buffer_.get(), | 1217 send_buffer_.get(), |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1322 EVP_PKEY** pkey) { | 1320 EVP_PKEY** pkey) { |
1323 DVLOG(3) << "OpenSSL ClientCertRequestCallback called"; | 1321 DVLOG(3) << "OpenSSL ClientCertRequestCallback called"; |
1324 DCHECK(ssl == ssl_); | 1322 DCHECK(ssl == ssl_); |
1325 DCHECK(*x509 == NULL); | 1323 DCHECK(*x509 == NULL); |
1326 DCHECK(*pkey == NULL); | 1324 DCHECK(*pkey == NULL); |
1327 if (!ssl_config_.send_client_cert) { | 1325 if (!ssl_config_.send_client_cert) { |
1328 // First pass: we know that a client certificate is needed, but we do not | 1326 // First pass: we know that a client certificate is needed, but we do not |
1329 // have one at hand. | 1327 // have one at hand. |
1330 client_auth_cert_needed_ = true; | 1328 client_auth_cert_needed_ = true; |
1331 STACK_OF(X509_NAME) *authorities = SSL_get_client_CA_list(ssl); | 1329 STACK_OF(X509_NAME) *authorities = SSL_get_client_CA_list(ssl); |
1332 for (int i = 0; i < sk_X509_NAME_num(authorities); i++) { | 1330 for (size_t i = 0; i < sk_X509_NAME_num(authorities); i++) { |
1333 X509_NAME *ca_name = (X509_NAME *)sk_X509_NAME_value(authorities, i); | 1331 X509_NAME *ca_name = (X509_NAME *)sk_X509_NAME_value(authorities, i); |
1334 unsigned char* str = NULL; | 1332 unsigned char* str = NULL; |
1335 int length = i2d_X509_NAME(ca_name, &str); | 1333 int length = i2d_X509_NAME(ca_name, &str); |
1336 cert_authorities_.push_back(std::string( | 1334 cert_authorities_.push_back(std::string( |
1337 reinterpret_cast<const char*>(str), | 1335 reinterpret_cast<const char*>(str), |
1338 static_cast<size_t>(length))); | 1336 static_cast<size_t>(length))); |
1339 OPENSSL_free(str); | 1337 OPENSSL_free(str); |
1340 } | 1338 } |
1341 | 1339 |
1342 const unsigned char* client_cert_types; | 1340 const unsigned char* client_cert_types; |
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1507 return socket->MaybeReplayTransportError( | 1505 return socket->MaybeReplayTransportError( |
1508 bio, cmd, argp, argi, argl, retvalue); | 1506 bio, cmd, argp, argi, argl, retvalue); |
1509 } | 1507 } |
1510 | 1508 |
1511 scoped_refptr<X509Certificate> | 1509 scoped_refptr<X509Certificate> |
1512 SSLClientSocketOpenSSL::GetUnverifiedServerCertificateChain() const { | 1510 SSLClientSocketOpenSSL::GetUnverifiedServerCertificateChain() const { |
1513 return server_cert_; | 1511 return server_cert_; |
1514 } | 1512 } |
1515 | 1513 |
1516 } // namespace net | 1514 } // namespace net |
OLD | NEW |