diff options
author | joth@chromium.org <joth@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-12-02 10:04:10 +0000 |
---|---|---|
committer | joth@chromium.org <joth@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-12-02 10:04:10 +0000 |
commit | 718c967f73fbdc4193e11930e5fe3bb5ff6ab6a5 (patch) | |
tree | a96e859ea1efeec2bc25ae76bdbf317e631c0d1c /net/socket | |
parent | 9c635f24128b5638dac833499fb1fd5ee2be6375 (diff) | |
download | chromium_src-718c967f73fbdc4193e11930e5fe3bb5ff6ab6a5.zip chromium_src-718c967f73fbdc4193e11930e5fe3bb5ff6ab6a5.tar.gz chromium_src-718c967f73fbdc4193e11930e5fe3bb5ff6ab6a5.tar.bz2 |
Fixes the remaining unit tests failures for OpenSSL:
- implements basic client certificate support in ssl socket
- adds special-case IP address support to allow SSL connections to the test server (iff there is a trusted certificate in the store with 127.0.0.1 in its name)
- enables the test server for loading the temporary cert
- implements the DES encryptor (removed TODO about refactoring the file layout as it's already covered by a TODO in the .h file)
- disabled KeygenHandler tests, as this is not implemented for openssl
- disables the (firefox) importer unittests.
BUG=None
TEST=net_unittests now run green
Review URL: http://codereview.chromium.org/5195001
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@67990 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/socket')
-rw-r--r-- | net/socket/ssl_client_socket_openssl.cc | 54 | ||||
-rw-r--r-- | net/socket/ssl_client_socket_openssl.h | 7 |
2 files changed, 57 insertions, 4 deletions
diff --git a/net/socket/ssl_client_socket_openssl.cc b/net/socket/ssl_client_socket_openssl.cc index da40011..7fe7712 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); diff --git a/net/socket/ssl_client_socket_openssl.h b/net/socket/ssl_client_socket_openssl.h index e7bfe3c..99e92f2 100644 --- a/net/socket/ssl_client_socket_openssl.h +++ b/net/socket/ssl_client_socket_openssl.h @@ -15,7 +15,9 @@ #include "net/socket/client_socket_handle.h" typedef struct bio_st BIO; +typedef struct evp_pkey_st EVP_PKEY; typedef struct ssl_st SSL; +typedef struct x509_st X509; namespace net { @@ -38,6 +40,10 @@ class SSLClientSocketOpenSSL : public SSLClientSocket { const HostPortPair& host_and_port() const { return host_and_port_; } + // Callback from the SSL layer that indicates the remote server is requesting + // a certificate for this client. + int ClientCertRequestCallback(SSL* ssl, X509** x509, EVP_PKEY** pkey); + // SSLClientSocket methods: virtual void GetSSLInfo(SSLInfo* ssl_info); virtual void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info); @@ -71,7 +77,6 @@ class SSLClientSocketOpenSSL : public SSLClientSocket { int DoVerifyCert(int result); int DoVerifyCertComplete(int result); void DoConnectCallback(int result); - void InvalidateSessionIfBadCertificate(); X509Certificate* UpdateServerCert(); void OnHandshakeIOComplete(int result); |