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

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: Disable browser unittests 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 } // namespace 213 } // namespace
206 214
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
318 ssl_info->connection_status |= SSL_CONNECTION_NO_RENEGOTIATION_EXTENSION; 326 ssl_info->connection_status |= SSL_CONNECTION_NO_RENEGOTIATION_EXTENSION;
319 UMA_HISTOGRAM_ENUMERATION("Net.RenegotiationExtensionSupported", 327 UMA_HISTOGRAM_ENUMERATION("Net.RenegotiationExtensionSupported",
320 (int)peer_supports_renego_ext, 2); 328 (int)peer_supports_renego_ext, 2);
321 329
322 if (ssl_config_.ssl3_fallback) 330 if (ssl_config_.ssl3_fallback)
323 ssl_info->connection_status |= SSL_CONNECTION_SSL3_FALLBACK; 331 ssl_info->connection_status |= SSL_CONNECTION_SSL3_FALLBACK;
324 } 332 }
325 333
326 void SSLClientSocketOpenSSL::GetSSLCertRequestInfo( 334 void SSLClientSocketOpenSSL::GetSSLCertRequestInfo(
327 SSLCertRequestInfo* cert_request_info) { 335 SSLCertRequestInfo* cert_request_info) {
328 NOTREACHED(); 336 cert_request_info->host_and_port = host_and_port_.ToString();
337 cert_request_info->client_certs = client_certs_;
329 } 338 }
330 339
331 SSLClientSocket::NextProtoStatus SSLClientSocketOpenSSL::GetNextProto( 340 SSLClientSocket::NextProtoStatus SSLClientSocketOpenSSL::GetNextProto(
332 std::string* proto) { 341 std::string* proto) {
333 proto->clear(); 342 proto->clear();
334 return kNextProtoUnsupported; 343 return kNextProtoUnsupported;
335 } 344 }
336 345
337 void SSLClientSocketOpenSSL::DoReadCallback(int rv) { 346 void SSLClientSocketOpenSSL::DoReadCallback(int rv) {
338 // Since Run may result in Read being called, clear |user_read_callback_| 347 // Since Run may result in Read being called, clear |user_read_callback_|
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
455 } while ((rv != ERR_IO_PENDING || network_moved) && 464 } while ((rv != ERR_IO_PENDING || network_moved) &&
456 next_handshake_state_ != STATE_NONE); 465 next_handshake_state_ != STATE_NONE);
457 return rv; 466 return rv;
458 } 467 }
459 468
460 int SSLClientSocketOpenSSL::DoHandshake() { 469 int SSLClientSocketOpenSSL::DoHandshake() {
461 base::OpenSSLErrStackTracer err_tracer(FROM_HERE); 470 base::OpenSSLErrStackTracer err_tracer(FROM_HERE);
462 int net_error = net::OK; 471 int net_error = net::OK;
463 int rv = SSL_do_handshake(ssl_); 472 int rv = SSL_do_handshake(ssl_);
464 473
465 if (rv == 1) { 474 if (client_auth_cert_needed_) {
475 net_error = ERR_SSL_CLIENT_AUTH_CERT_NEEDED;
476 // If the handshake already succeeded (because the server requests but
477 // doesn't require a client cert), we need to invalidate the SSL session
478 // so that we won't try to resume the non-client-authenticated session in
479 // the next handshake. This will cause the server to ask for a client
480 // cert again.
481 if (rv == 1) {
482 // Remove from session cache but don't clear this connection.
483 SSL_SESSION* session = SSL_get_session(ssl_);
484 if (session) {
485 int rv = SSL_CTX_remove_session(SSL_get_SSL_CTX(ssl_), session);
486 LOG_IF(WARNING, !rv) << "Couldn't invalidate SSL session: " << session;
487 }
488 }
489 } else if (rv == 1) {
466 if (trying_cached_session_ && logging::DEBUG_MODE) { 490 if (trying_cached_session_ && logging::DEBUG_MODE) {
467 DVLOG(2) << "Result of session reuse for " << host_and_port_.ToString() 491 DVLOG(2) << "Result of session reuse for " << host_and_port_.ToString()
468 << " is: " << (SSL_session_reused(ssl_) ? "Success" : "Fail"); 492 << " is: " << (SSL_session_reused(ssl_) ? "Success" : "Fail");
469 } 493 }
470
471 // SSL handshake is completed. Let's verify the certificate. 494 // SSL handshake is completed. Let's verify the certificate.
472 const bool got_cert = !!UpdateServerCert(); 495 const bool got_cert = !!UpdateServerCert();
473 DCHECK(got_cert); 496 DCHECK(got_cert);
474 GotoState(STATE_VERIFY_CERT); 497 GotoState(STATE_VERIFY_CERT);
475 } else { 498 } else {
476 int ssl_error = SSL_get_error(ssl_, rv); 499 int ssl_error = SSL_get_error(ssl_, rv);
477 net_error = MapOpenSSLError(ssl_error); 500 net_error = MapOpenSSLError(ssl_error);
478 501
479 // If not done, stay in this state 502 // If not done, stay in this state
480 if (net_error == ERR_IO_PENDING) { 503 if (net_error == ERR_IO_PENDING) {
481 GotoState(STATE_HANDSHAKE); 504 GotoState(STATE_HANDSHAKE);
482 } else { 505 } else {
483 LOG(ERROR) << "handshake failed; returned " << rv 506 LOG(ERROR) << "handshake failed; returned " << rv
484 << ", SSL error code " << ssl_error 507 << ", SSL error code " << ssl_error
485 << ", net_error " << net_error; 508 << ", net_error " << net_error;
486 } 509 }
487 } 510 }
488 return net_error; 511 return net_error;
489 } 512 }
490 513
514 int SSLClientSocketOpenSSL::ClientCertRequestCallback(SSL* ssl,
515 X509** x509,
516 EVP_PKEY** pkey) {
517 DVLOG(3) << "OpenSSL ClientCertRequestCallback called";
518 DCHECK(ssl == ssl_);
519 DCHECK(*x509 == NULL);
520 DCHECK(*pkey == NULL);
521
522 if (!ssl_config_.send_client_cert) {
523 client_auth_cert_needed_ = true;
524 return -1; // Suspends handshake.
525 }
526
527 // Second pass: a client certificate should have been selected.
528 if (ssl_config_.client_cert) {
529 // TODO(joth): Need a way to acquire the private key for the client cert.
530 NOTIMPLEMENTED();
bulach 2010/12/01 18:01:33 provided the second part is correct, it may be cle
joth 2010/12/02 17:12:01 Done.
531 EVP_PKEY* privkey = NULL;
532 if (privkey) {
533 // TODO(joth): (copied from NSS) We should wait for server certificate
534 // verification before sending our credentials. See http://crbug.com/13934
535 *x509 = X509Certificate::DupOSCertHandle(
536 ssl_config_.client_cert->os_cert_handle());
537 *pkey = privkey;
538 return 1;
539 }
540 LOG(WARNING) << "Client cert found without private key";
541 }
542 // Send no client certificate.
543 return 0;
544 }
545
491 int SSLClientSocketOpenSSL::DoVerifyCert(int result) { 546 int SSLClientSocketOpenSSL::DoVerifyCert(int result) {
492 DCHECK(server_cert_); 547 DCHECK(server_cert_);
493 GotoState(STATE_VERIFY_CERT_COMPLETE); 548 GotoState(STATE_VERIFY_CERT_COMPLETE);
494 int flags = 0; 549 int flags = 0;
495 550
496 if (ssl_config_.rev_checking_enabled) 551 if (ssl_config_.rev_checking_enabled)
497 flags |= X509Certificate::VERIFY_REV_CHECKING_ENABLED; 552 flags |= X509Certificate::VERIFY_REV_CHECKING_ENABLED;
498 if (ssl_config_.verify_ev_cert) 553 if (ssl_config_.verify_ev_cert)
499 flags |= X509Certificate::VERIFY_EV_CERT; 554 flags |= X509Certificate::VERIFY_EV_CERT;
500 verifier_.reset(new CertVerifier); 555 verifier_.reset(new CertVerifier);
(...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after
865 int rv = SSL_write(ssl_, user_write_buf_->data(), user_write_buf_len_); 920 int rv = SSL_write(ssl_, user_write_buf_->data(), user_write_buf_len_);
866 921
867 if (rv >= 0) 922 if (rv >= 0)
868 return rv; 923 return rv;
869 924
870 int err = SSL_get_error(ssl_, rv); 925 int err = SSL_get_error(ssl_, rv);
871 return MapOpenSSLError(err); 926 return MapOpenSSLError(err);
872 } 927 }
873 928
874 } // namespace net 929 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698