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