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

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

Issue 5195001: Fixes the remaining net_unittests for OpenSSL, with the exceptions (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Clarify comment Created 10 years 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
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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>
11 #include <openssl/err.h> 11 #include <openssl/err.h>
12 12
13 #include "base/lock.h" 13 #include "base/lock.h"
14 #include "base/metrics/histogram.h" 14 #include "base/metrics/histogram.h"
15 #include "base/openssl_util.h" 15 #include "base/openssl_util.h"
16 #include "base/singleton.h" 16 #include "base/singleton.h"
17 #include "net/base/cert_verifier.h" 17 #include "net/base/cert_verifier.h"
18 #include "net/base/net_errors.h" 18 #include "net/base/net_errors.h"
19 #include "net/base/ssl_cert_request_info.h"
19 #include "net/base/ssl_connection_status_flags.h" 20 #include "net/base/ssl_connection_status_flags.h"
20 #include "net/base/ssl_info.h" 21 #include "net/base/ssl_info.h"
21 22
22 namespace net { 23 namespace net {
23 24
24 namespace { 25 namespace {
25 26
26 // Enable this to see logging for state machine state transitions. 27 // Enable this to see logging for state machine state transitions.
27 #if 0 28 #if 0
28 #define GotoState(s) do { DVLOG(2) << (void *)this << " " << __FUNCTION__ << \ 29 #define GotoState(s) do { DVLOG(2) << (void *)this << " " << __FUNCTION__ << \
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
166 base::EnsureOpenSSLInit(); 167 base::EnsureOpenSSLInit();
167 ssl_socket_data_index_ = SSL_get_ex_new_index(0, 0, 0, 0, 0); 168 ssl_socket_data_index_ = SSL_get_ex_new_index(0, 0, 0, 0, 0);
168 DCHECK_NE(ssl_socket_data_index_, -1); 169 DCHECK_NE(ssl_socket_data_index_, -1);
169 ssl_ctx_.reset(SSL_CTX_new(SSLv23_client_method())); 170 ssl_ctx_.reset(SSL_CTX_new(SSLv23_client_method()));
170 SSL_CTX_set_cert_verify_callback(ssl_ctx_.get(), NoOpVerifyCallback, NULL); 171 SSL_CTX_set_cert_verify_callback(ssl_ctx_.get(), NoOpVerifyCallback, NULL);
171 SSL_CTX_set_session_cache_mode(ssl_ctx_.get(), SSL_SESS_CACHE_CLIENT); 172 SSL_CTX_set_session_cache_mode(ssl_ctx_.get(), SSL_SESS_CACHE_CLIENT);
172 SSL_CTX_sess_set_new_cb(ssl_ctx_.get(), NewSessionCallbackStatic); 173 SSL_CTX_sess_set_new_cb(ssl_ctx_.get(), NewSessionCallbackStatic);
173 SSL_CTX_sess_set_remove_cb(ssl_ctx_.get(), RemoveSessionCallbackStatic); 174 SSL_CTX_sess_set_remove_cb(ssl_ctx_.get(), RemoveSessionCallbackStatic);
174 SSL_CTX_set_timeout(ssl_ctx_.get(), kSessionCacheTimeoutSeconds); 175 SSL_CTX_set_timeout(ssl_ctx_.get(), kSessionCacheTimeoutSeconds);
175 SSL_CTX_sess_set_cache_size(ssl_ctx_.get(), kSessionCacheMaxEntires); 176 SSL_CTX_sess_set_cache_size(ssl_ctx_.get(), kSessionCacheMaxEntires);
177 SSL_CTX_set_client_cert_cb(ssl_ctx_.get(), ClientCertCallback);
176 } 178 }
177 179
178 static int NewSessionCallbackStatic(SSL* ssl, SSL_SESSION* session) { 180 static int NewSessionCallbackStatic(SSL* ssl, SSL_SESSION* session) {
179 return Get()->NewSessionCallback(ssl, session); 181 return Get()->NewSessionCallback(ssl, session);
180 } 182 }
181 183
182 int NewSessionCallback(SSL* ssl, SSL_SESSION* session) { 184 int NewSessionCallback(SSL* ssl, SSL_SESSION* session) {
183 SSLClientSocketOpenSSL* socket = GetClientSocketFromSSL(ssl); 185 SSLClientSocketOpenSSL* socket = GetClientSocketFromSSL(ssl);
184 session_cache_.OnSessionAdded(socket->host_and_port(), session); 186 session_cache_.OnSessionAdded(socket->host_and_port(), session);
185 return 1; // 1 => We took ownership of |session|. 187 return 1; // 1 => We took ownership of |session|.
186 } 188 }
187 189
188 static void RemoveSessionCallbackStatic(SSL_CTX* ctx, SSL_SESSION* session) { 190 static void RemoveSessionCallbackStatic(SSL_CTX* ctx, SSL_SESSION* session) {
189 return Get()->RemoveSessionCallback(ctx, session); 191 return Get()->RemoveSessionCallback(ctx, session);
190 } 192 }
191 193
192 void RemoveSessionCallback(SSL_CTX* ctx, SSL_SESSION* session) { 194 void RemoveSessionCallback(SSL_CTX* ctx, SSL_SESSION* session) {
193 DCHECK(ctx == ssl_ctx()); 195 DCHECK(ctx == ssl_ctx());
194 session_cache_.OnSessionRemoved(session); 196 session_cache_.OnSessionRemoved(session);
195 } 197 }
196 198
199 static int ClientCertCallback(SSL* ssl, X509** x509, EVP_PKEY** pkey) {
200 SSLClientSocketOpenSSL* socket = Get()->GetClientSocketFromSSL(ssl);
201 CHECK(socket);
202 return socket->ClientCertRequestCallback(ssl, x509, pkey);
203 }
204
197 // This is the index used with SSL_get_ex_data to retrieve the owner 205 // This is the index used with SSL_get_ex_data to retrieve the owner
198 // SSLClientSocketOpenSSL object from an SSL instance. 206 // SSLClientSocketOpenSSL object from an SSL instance.
199 int ssl_socket_data_index_; 207 int ssl_socket_data_index_;
200 208
201 base::ScopedOpenSSL<SSL_CTX, SSL_CTX_free> ssl_ctx_; 209 base::ScopedOpenSSL<SSL_CTX, SSL_CTX_free> ssl_ctx_;
202 SSLSessionCache session_cache_; 210 SSLSessionCache session_cache_;
203 }; 211 };
204 212
205 // Utility to construct the appropriate set & clear masks for use the OpenSSL 213 // Utility to construct the appropriate set & clear masks for use the OpenSSL
206 // options and mode configuration functions. (SSL_set_options etc) 214 // options and mode configuration functions. (SSL_set_options etc)
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
349 ssl_info->connection_status |= SSL_CONNECTION_NO_RENEGOTIATION_EXTENSION; 357 ssl_info->connection_status |= SSL_CONNECTION_NO_RENEGOTIATION_EXTENSION;
350 UMA_HISTOGRAM_ENUMERATION("Net.RenegotiationExtensionSupported", 358 UMA_HISTOGRAM_ENUMERATION("Net.RenegotiationExtensionSupported",
351 (int)peer_supports_renego_ext, 2); 359 (int)peer_supports_renego_ext, 2);
352 360
353 if (ssl_config_.ssl3_fallback) 361 if (ssl_config_.ssl3_fallback)
354 ssl_info->connection_status |= SSL_CONNECTION_SSL3_FALLBACK; 362 ssl_info->connection_status |= SSL_CONNECTION_SSL3_FALLBACK;
355 } 363 }
356 364
357 void SSLClientSocketOpenSSL::GetSSLCertRequestInfo( 365 void SSLClientSocketOpenSSL::GetSSLCertRequestInfo(
358 SSLCertRequestInfo* cert_request_info) { 366 SSLCertRequestInfo* cert_request_info) {
359 NOTREACHED(); 367 cert_request_info->host_and_port = host_and_port_.ToString();
368 cert_request_info->client_certs = client_certs_;
360 } 369 }
361 370
362 SSLClientSocket::NextProtoStatus SSLClientSocketOpenSSL::GetNextProto( 371 SSLClientSocket::NextProtoStatus SSLClientSocketOpenSSL::GetNextProto(
363 std::string* proto) { 372 std::string* proto) {
364 proto->clear(); 373 proto->clear();
365 return kNextProtoUnsupported; 374 return kNextProtoUnsupported;
366 } 375 }
367 376
368 void SSLClientSocketOpenSSL::DoReadCallback(int rv) { 377 void SSLClientSocketOpenSSL::DoReadCallback(int rv) {
369 // Since Run may result in Read being called, clear |user_read_callback_| 378 // Since Run may result in Read being called, clear |user_read_callback_|
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
486 } while ((rv != ERR_IO_PENDING || network_moved) && 495 } while ((rv != ERR_IO_PENDING || network_moved) &&
487 next_handshake_state_ != STATE_NONE); 496 next_handshake_state_ != STATE_NONE);
488 return rv; 497 return rv;
489 } 498 }
490 499
491 int SSLClientSocketOpenSSL::DoHandshake() { 500 int SSLClientSocketOpenSSL::DoHandshake() {
492 base::OpenSSLErrStackTracer err_tracer(FROM_HERE); 501 base::OpenSSLErrStackTracer err_tracer(FROM_HERE);
493 int net_error = net::OK; 502 int net_error = net::OK;
494 int rv = SSL_do_handshake(ssl_); 503 int rv = SSL_do_handshake(ssl_);
495 504
496 if (rv == 1) { 505 if (client_auth_cert_needed_) {
506 net_error = ERR_SSL_CLIENT_AUTH_CERT_NEEDED;
507 // If the handshake already succeeded (because the server requests but
508 // doesn't require a client cert), we need to invalidate the SSL session
509 // so that we won't try to resume the non-client-authenticated session in
510 // the next handshake. This will cause the server to ask for a client
511 // cert again.
512 if (rv == 1) {
513 // Remove from session cache but don't clear this connection.
514 SSL_SESSION* session = SSL_get_session(ssl_);
515 if (session) {
516 int rv = SSL_CTX_remove_session(SSL_get_SSL_CTX(ssl_), session);
517 LOG_IF(WARNING, !rv) << "Couldn't invalidate SSL session: " << session;
518 }
519 }
520 } else if (rv == 1) {
497 if (trying_cached_session_ && logging::DEBUG_MODE) { 521 if (trying_cached_session_ && logging::DEBUG_MODE) {
498 DVLOG(2) << "Result of session reuse for " << host_and_port_.ToString() 522 DVLOG(2) << "Result of session reuse for " << host_and_port_.ToString()
499 << " is: " << (SSL_session_reused(ssl_) ? "Success" : "Fail"); 523 << " is: " << (SSL_session_reused(ssl_) ? "Success" : "Fail");
500 } 524 }
501
502 // SSL handshake is completed. Let's verify the certificate. 525 // SSL handshake is completed. Let's verify the certificate.
503 const bool got_cert = !!UpdateServerCert(); 526 const bool got_cert = !!UpdateServerCert();
504 DCHECK(got_cert); 527 DCHECK(got_cert);
505 GotoState(STATE_VERIFY_CERT); 528 GotoState(STATE_VERIFY_CERT);
506 } else { 529 } else {
507 int ssl_error = SSL_get_error(ssl_, rv); 530 int ssl_error = SSL_get_error(ssl_, rv);
508 net_error = MapOpenSSLError(ssl_error); 531 net_error = MapOpenSSLError(ssl_error);
509 532
510 // If not done, stay in this state 533 // If not done, stay in this state
511 if (net_error == ERR_IO_PENDING) { 534 if (net_error == ERR_IO_PENDING) {
512 GotoState(STATE_HANDSHAKE); 535 GotoState(STATE_HANDSHAKE);
513 } else { 536 } else {
514 LOG(ERROR) << "handshake failed; returned " << rv 537 LOG(ERROR) << "handshake failed; returned " << rv
515 << ", SSL error code " << ssl_error 538 << ", SSL error code " << ssl_error
516 << ", net_error " << net_error; 539 << ", net_error " << net_error;
517 } 540 }
518 } 541 }
519 return net_error; 542 return net_error;
520 } 543 }
521 544
545 int SSLClientSocketOpenSSL::ClientCertRequestCallback(SSL* ssl,
546 X509** x509,
547 EVP_PKEY** pkey) {
548 DVLOG(3) << "OpenSSL ClientCertRequestCallback called";
549 DCHECK(ssl == ssl_);
550 DCHECK(*x509 == NULL);
551 DCHECK(*pkey == NULL);
552
553 if (!ssl_config_.send_client_cert) {
554 client_auth_cert_needed_ = true;
555 return -1; // Suspends handshake.
556 }
557
558 // Second pass: a client certificate should have been selected.
559 if (ssl_config_.client_cert) {
560 // TODO(joth): We need a way to lookup the private key this
561 // certificate. See http://crbug.com/64951 and example code in
562 // http://codereview.chromium.org/5195001/diff/6001/net/socket/ssl_client_so cket_openssl.cc
563 NOTIMPLEMENTED();
564 }
565
566 // Send no client certificate.
567 return 0;
568 }
569
522 int SSLClientSocketOpenSSL::DoVerifyCert(int result) { 570 int SSLClientSocketOpenSSL::DoVerifyCert(int result) {
523 DCHECK(server_cert_); 571 DCHECK(server_cert_);
524 GotoState(STATE_VERIFY_CERT_COMPLETE); 572 GotoState(STATE_VERIFY_CERT_COMPLETE);
525 int flags = 0; 573 int flags = 0;
526 574
527 if (ssl_config_.rev_checking_enabled) 575 if (ssl_config_.rev_checking_enabled)
528 flags |= X509Certificate::VERIFY_REV_CHECKING_ENABLED; 576 flags |= X509Certificate::VERIFY_REV_CHECKING_ENABLED;
529 if (ssl_config_.verify_ev_cert) 577 if (ssl_config_.verify_ev_cert)
530 flags |= X509Certificate::VERIFY_EV_CERT; 578 flags |= X509Certificate::VERIFY_EV_CERT;
531 verifier_.reset(new CertVerifier); 579 verifier_.reset(new CertVerifier);
(...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after
896 int rv = SSL_write(ssl_, user_write_buf_->data(), user_write_buf_len_); 944 int rv = SSL_write(ssl_, user_write_buf_->data(), user_write_buf_len_);
897 945
898 if (rv >= 0) 946 if (rv >= 0)
899 return rv; 947 return rv;
900 948
901 int err = SSL_get_error(ssl_, rv); 949 int err = SSL_get_error(ssl_, rv);
902 return MapOpenSSLError(err); 950 return MapOpenSSLError(err);
903 } 951 }
904 952
905 } // namespace net 953 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698