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

Unified 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, 1 month 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 side-by-side diff with in-line comments
Download patch
Index: net/socket/ssl_client_socket_openssl.cc
diff --git a/net/socket/ssl_client_socket_openssl.cc b/net/socket/ssl_client_socket_openssl.cc
index da400110e27159921873fc6009a09864c4380068..7fe771235dd7a7e3cd2a270fab7c639462ef5df0 100644
--- a/net/socket/ssl_client_socket_openssl.cc
+++ b/net/socket/ssl_client_socket_openssl.cc
@@ -16,6 +16,7 @@
#include "base/singleton.h"
#include "net/base/cert_verifier.h"
#include "net/base/net_errors.h"
+#include "net/base/ssl_cert_request_info.h"
#include "net/base/ssl_connection_status_flags.h"
#include "net/base/ssl_info.h"
@@ -173,6 +174,7 @@ class SSLContext {
SSL_CTX_sess_set_remove_cb(ssl_ctx_.get(), RemoveSessionCallbackStatic);
SSL_CTX_set_timeout(ssl_ctx_.get(), kSessionCacheTimeoutSeconds);
SSL_CTX_sess_set_cache_size(ssl_ctx_.get(), kSessionCacheMaxEntires);
+ SSL_CTX_set_client_cert_cb(ssl_ctx_.get(), ClientCertCallback);
}
static int NewSessionCallbackStatic(SSL* ssl, SSL_SESSION* session) {
@@ -194,6 +196,12 @@ class SSLContext {
session_cache_.OnSessionRemoved(session);
}
+ static int ClientCertCallback(SSL* ssl, X509** x509, EVP_PKEY** pkey) {
+ SSLClientSocketOpenSSL* socket = Get()->GetClientSocketFromSSL(ssl);
+ CHECK(socket);
+ return socket->ClientCertRequestCallback(ssl, x509, pkey);
+ }
+
// This is the index used with SSL_get_ex_data to retrieve the owner
// SSLClientSocketOpenSSL object from an SSL instance.
int ssl_socket_data_index_;
@@ -356,7 +364,8 @@ void SSLClientSocketOpenSSL::GetSSLInfo(SSLInfo* ssl_info) {
void SSLClientSocketOpenSSL::GetSSLCertRequestInfo(
SSLCertRequestInfo* cert_request_info) {
- NOTREACHED();
+ cert_request_info->host_and_port = host_and_port_.ToString();
+ cert_request_info->client_certs = client_certs_;
}
SSLClientSocket::NextProtoStatus SSLClientSocketOpenSSL::GetNextProto(
@@ -493,12 +502,26 @@ int SSLClientSocketOpenSSL::DoHandshake() {
int net_error = net::OK;
int rv = SSL_do_handshake(ssl_);
- if (rv == 1) {
+ if (client_auth_cert_needed_) {
+ net_error = ERR_SSL_CLIENT_AUTH_CERT_NEEDED;
+ // If the handshake already succeeded (because the server requests but
+ // doesn't require a client cert), we need to invalidate the SSL session
+ // so that we won't try to resume the non-client-authenticated session in
+ // the next handshake. This will cause the server to ask for a client
+ // cert again.
+ if (rv == 1) {
+ // Remove from session cache but don't clear this connection.
+ SSL_SESSION* session = SSL_get_session(ssl_);
+ if (session) {
+ int rv = SSL_CTX_remove_session(SSL_get_SSL_CTX(ssl_), session);
+ LOG_IF(WARNING, !rv) << "Couldn't invalidate SSL session: " << session;
+ }
+ }
+ } else if (rv == 1) {
if (trying_cached_session_ && logging::DEBUG_MODE) {
DVLOG(2) << "Result of session reuse for " << host_and_port_.ToString()
<< " is: " << (SSL_session_reused(ssl_) ? "Success" : "Fail");
}
-
// SSL handshake is completed. Let's verify the certificate.
const bool got_cert = !!UpdateServerCert();
DCHECK(got_cert);
@@ -519,6 +542,31 @@ int SSLClientSocketOpenSSL::DoHandshake() {
return net_error;
}
+int SSLClientSocketOpenSSL::ClientCertRequestCallback(SSL* ssl,
+ X509** x509,
+ EVP_PKEY** pkey) {
+ DVLOG(3) << "OpenSSL ClientCertRequestCallback called";
+ DCHECK(ssl == ssl_);
+ DCHECK(*x509 == NULL);
+ DCHECK(*pkey == NULL);
+
+ if (!ssl_config_.send_client_cert) {
+ client_auth_cert_needed_ = true;
+ return -1; // Suspends handshake.
+ }
+
+ // Second pass: a client certificate should have been selected.
+ if (ssl_config_.client_cert) {
+ // TODO(joth): We need a way to lookup the private key this
+ // certificate. See http://crbug.com/64951 and example code in
+ // http://codereview.chromium.org/5195001/diff/6001/net/socket/ssl_client_socket_openssl.cc
+ NOTIMPLEMENTED();
+ }
+
+ // Send no client certificate.
+ return 0;
+}
+
int SSLClientSocketOpenSSL::DoVerifyCert(int result) {
DCHECK(server_cert_);
GotoState(STATE_VERIFY_CERT_COMPLETE);

Powered by Google App Engine
This is Rietveld 408576698