summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/chrome_tests.gypi6
-rw-r--r--net/base/keygen_handler_openssl.cc4
-rw-r--r--net/base/keygen_handler_unittest.cc16
-rw-r--r--net/base/x509_certificate_openssl.cc25
-rw-r--r--net/base/x509_openssl_util.cc12
-rw-r--r--net/base/x509_openssl_util_unittest.cc3
-rw-r--r--net/http/des.cc15
-rw-r--r--net/socket/ssl_client_socket_openssl.cc54
-rw-r--r--net/socket/ssl_client_socket_openssl.h7
-rw-r--r--net/test/test_server.cc2
-rw-r--r--net/test/test_server.h4
11 files changed, 120 insertions, 28 deletions
diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi
index 24a4161..2904701 100644
--- a/chrome/chrome_tests.gypi
+++ b/chrome/chrome_tests.gypi
@@ -1891,6 +1891,12 @@
['exclude', '^../views/'],
],
}],
+ ['use_openssl==1', {
+ 'sources/': [
+ # OpenSSL build does not support firefox importer. See http://crbug.com/64926
+ ['exclude', '^browser/importer/'],
+ ],
+ }],
],
},
{
diff --git a/net/base/keygen_handler_openssl.cc b/net/base/keygen_handler_openssl.cc
index 0f5d874..ecbd683 100644
--- a/net/base/keygen_handler_openssl.cc
+++ b/net/base/keygen_handler_openssl.cc
@@ -4,15 +4,15 @@
#include "net/base/keygen_handler.h"
-#if defined(USE_OPENSSL)
+#include "base/logging.h"
namespace net {
std::string KeygenHandler::GenKeyAndSignChallenge() {
// TODO(bulach): implement me.
+ NOTIMPLEMENTED();
return "";
}
} // namespace net
-#endif // USE_OPENSSL
diff --git a/net/base/keygen_handler_unittest.cc b/net/base/keygen_handler_unittest.cc
index d3bf4f5..408eb76 100644
--- a/net/base/keygen_handler_unittest.cc
+++ b/net/base/keygen_handler_unittest.cc
@@ -73,7 +73,13 @@ void AssertValidSignedPublicKeyAndChallenge(const std::string& result,
// openssl asn1parse -inform DER
}
-TEST_F(KeygenHandlerTest, SmokeTest) {
+// Keygen not yet implemented for OpenSSL: http://crbug.com/64917
+#if defined(USE_OPENSSL)
+#define MAYBE_SmokeTest FAILS_SmokeTest
+#else
+#define MAYBE_SmokeTest SmokeTest
+#endif
+TEST_F(KeygenHandlerTest, MAYBE_SmokeTest) {
KeygenHandler handler(768, "some challenge", GURL("http://www.example.com"));
handler.set_stores_key(false); // Don't leave the key-pair behind
std::string result = handler.GenKeyAndSignChallenge();
@@ -117,9 +123,15 @@ class ConcurrencyTestTask : public Task {
std::string* result_;
};
+// Keygen not yet implemented for OpenSSL: http://crbug.com/64917
+#if defined(USE_OPENSSL)
+#define MAYBE_ConcurrencyTest FAILS_ConcurrencyTest
+#else
+#define MAYBE_ConcurrencyTest ConcurrencyTest
+#endif
// We asynchronously generate the keys so as not to hang up the IO thread. This
// test tries to catch concurrency problems in the keygen implementation.
-TEST_F(KeygenHandlerTest, ConcurrencyTest) {
+TEST_F(KeygenHandlerTest, MAYBE_ConcurrencyTest) {
const int NUM_HANDLERS = 5;
base::WaitableEvent* events[NUM_HANDLERS] = { NULL };
std::string results[NUM_HANDLERS];
diff --git a/net/base/x509_certificate_openssl.cc b/net/base/x509_certificate_openssl.cc
index d2c7653..abddd97 100644
--- a/net/base/x509_certificate_openssl.cc
+++ b/net/base/x509_certificate_openssl.cc
@@ -425,19 +425,22 @@ int X509Certificate::Verify(const std::string& hostname,
cert_handle_, intermediates.get());
CHECK_EQ(1, rv);
- if (X509_verify_cert(ctx.get()) == 1) {
- return OK;
+ if (X509_verify_cert(ctx.get()) != 1) {
+ int x509_error = X509_STORE_CTX_get_error(ctx.get());
+ int cert_status = MapCertErrorToCertStatus(x509_error);
+ LOG(ERROR) << "X509 Verification error "
+ << X509_verify_cert_error_string(x509_error)
+ << " : " << x509_error
+ << " : " << X509_STORE_CTX_get_error_depth(ctx.get())
+ << " : " << cert_status;
+ verify_result->cert_status |= cert_status;
+ return MapCertStatusToNetError(verify_result->cert_status);
}
- int x509_error = X509_STORE_CTX_get_error(ctx.get());
- int cert_status = MapCertErrorToCertStatus(x509_error);
- LOG(ERROR) << "X509 Verification error "
- << X509_verify_cert_error_string(x509_error)
- << " : " << x509_error
- << " : " << X509_STORE_CTX_get_error_depth(ctx.get())
- << " : " << cert_status;
- verify_result->cert_status |= cert_status;
- return MapCertStatusToNetError(verify_result->cert_status);
+ if (IsCertStatusError(verify_result->cert_status))
+ return MapCertStatusToNetError(verify_result->cert_status);
+
+ return OK;
}
// static
diff --git a/net/base/x509_openssl_util.cc b/net/base/x509_openssl_util.cc
index 9e44c4b..0bb4002 100644
--- a/net/base/x509_openssl_util.cc
+++ b/net/base/x509_openssl_util.cc
@@ -149,9 +149,17 @@ bool VerifyHostname(const std::string& hostname,
}
DCHECK(!reference_name.empty());
- // TODO(joth): Add IP address support. See http://crbug.com/62973
if (found_ip6_chars || !found_alpha) {
- NOTIMPLEMENTED() << hostname;
+ // For now we just do simple localhost IP address support, primarily as
+ // it's needed by the test server. TODO(joth): Replace this with full IP
+ // address support. See http://crbug.com/62973
+ if (hostname == "127.0.0.1" &&
+ std::find(cert_names.begin(), cert_names.end(), hostname)
+ != cert_names.end()) {
+ DVLOG(1) << "Allowing localhost IP certificate: " << hostname;
+ return true;
+ }
+ NOTIMPLEMENTED() << hostname; // See comment above.
return false;
}
diff --git a/net/base/x509_openssl_util_unittest.cc b/net/base/x509_openssl_util_unittest.cc
index 50589ad..4727d4c 100644
--- a/net/base/x509_openssl_util_unittest.cc
+++ b/net/base/x509_openssl_util_unittest.cc
@@ -60,7 +60,8 @@ CertificateNameVerifyTestData kNameVerifyTestData[] = {
{ false, "baz2.example.net", "baz*.example.net" },
{ false, "bar.*.example.net", "bar.*.example.net" },
{ false, "bar.f*o.example.net", "bar.f*o.example.net" },
- // IP addresses currently not supported.
+ // IP addresses currently not supported, except for the localhost.
+ { true, "127.0.0.1", "127.0.0.1" },
{ false, "192.168.1.1", "192.168.1.1" },
{ false, "FEDC:BA98:7654:3210:FEDC:BA98:7654:3210",
"FEDC:BA98:7654:3210:FEDC:BA98:7654:3210" },
diff --git a/net/http/des.cc b/net/http/des.cc
index 11d7a26..30706e9 100644
--- a/net/http/des.cc
+++ b/net/http/des.cc
@@ -6,7 +6,10 @@
#include "base/logging.h"
-#if defined(USE_NSS)
+#if defined(USE_OPENSSL)
+#include <openssl/des.h>
+#include "base/openssl_util.h"
+#elif defined(USE_NSS)
#include <nss.h>
#include <pk11pub.h>
#include "base/nss_util.h"
@@ -87,8 +90,14 @@ void DESMakeKey(const uint8* raw, uint8* key) {
#if defined(USE_OPENSSL)
void DESEncrypt(const uint8* key, const uint8* src, uint8* hash) {
- // TODO(joth): When implementing consider splitting up this file by platform.
- NOTIMPLEMENTED();
+ base::EnsureOpenSSLInit();
+
+ DES_key_schedule ks;
+ DES_set_key_unchecked(
+ reinterpret_cast<const_DES_cblock*>(const_cast<uint8*>(key)), &ks);
+
+ DES_ecb_encrypt(reinterpret_cast<const_DES_cblock*>(const_cast<uint8*>(src)),
+ reinterpret_cast<DES_cblock*>(hash), &ks, DES_ENCRYPT);
}
#elif defined(USE_NSS)
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);
diff --git a/net/test/test_server.cc b/net/test/test_server.cc
index 0eaf8b5..d2d3fde 100644
--- a/net/test/test_server.cc
+++ b/net/test/test_server.cc
@@ -314,7 +314,7 @@ FilePath TestServer::GetRootCertificatePath() {
}
bool TestServer::LoadTestRootCert() {
-#if defined(USE_NSS)
+#if defined(USE_OPENSSL) || defined(USE_NSS)
if (cert_)
return true;
diff --git a/net/test/test_server.h b/net/test/test_server.h
index 00a8fc9..1ae0a50 100644
--- a/net/test/test_server.h
+++ b/net/test/test_server.h
@@ -22,7 +22,7 @@
#include "base/scoped_handle_win.h"
#endif
-#if defined(USE_NSS)
+#if defined(USE_OPENSSL) || defined(USE_NSS)
#include "base/ref_counted.h"
#include "net/base/x509_certificate.h"
#endif
@@ -200,7 +200,7 @@ class TestServer {
// If |type_| is TYPE_HTTPS, the TLS settings to use for the test server.
HTTPSOptions https_options_;
-#if defined(USE_NSS)
+#if defined(USE_OPENSSL) || defined(USE_NSS)
scoped_refptr<X509Certificate> cert_;
#endif