Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(731)

Side by Side Diff: net/socket/ssl_client_socket_openssl.cc

Issue 401153002: Switch to BoringSSL. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase across DEPS change Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « net/socket/openssl_ssl_util.cc ('k') | net/socket/ssl_server_socket_openssl.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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;
291 292
292 if (!chain) 293 if (!chain)
293 return; 294 return;
294 295
295 // sk_X509_dup does not increase reference count on the certs in the stack. 296 // sk_X509_dup does not increase reference count on the certs in the stack.
296 openssl_chain_.reset(sk_X509_dup(chain)); 297 openssl_chain_.reset(sk_X509_dup(chain));
297 298
298 std::vector<base::StringPiece> der_chain; 299 std::vector<base::StringPiece> der_chain;
299 for (int i = 0; i < sk_X509_num(openssl_chain_.get()); ++i) { 300 for (size_t i = 0; i < sk_X509_num(openssl_chain_.get()); ++i) {
300 X509* x = sk_X509_value(openssl_chain_.get(), i); 301 X509* x = sk_X509_value(openssl_chain_.get(), i);
301 302
302 // Increase the reference count for the certs in openssl_chain_. 303 // Increase the reference count for the certs in openssl_chain_.
303 CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509); 304 CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509);
304 305
305 unsigned char* cert_data = NULL; 306 unsigned char* cert_data = NULL;
306 int cert_data_length = i2d_X509(x, &cert_data); 307 int cert_data_length = i2d_X509(x, &cert_data);
307 if (cert_data_length && cert_data) 308 if (cert_data_length && cert_data)
308 der_chain.push_back(base::StringPiece(reinterpret_cast<char*>(cert_data), 309 der_chain.push_back(base::StringPiece(reinterpret_cast<char*>(cert_data),
309 cert_data_length)); 310 cert_data_length));
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « net/socket/openssl_ssl_util.cc ('k') | net/socket/ssl_server_socket_openssl.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698