summaryrefslogtreecommitdiffstats
path: root/net/socket
diff options
context:
space:
mode:
authorjoth@chromium.org <joth@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-12-02 10:04:10 +0000
committerjoth@chromium.org <joth@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-12-02 10:04:10 +0000
commit718c967f73fbdc4193e11930e5fe3bb5ff6ab6a5 (patch)
treea96e859ea1efeec2bc25ae76bdbf317e631c0d1c /net/socket
parent9c635f24128b5638dac833499fb1fd5ee2be6375 (diff)
downloadchromium_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.cc54
-rw-r--r--net/socket/ssl_client_socket_openssl.h7
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);