summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/base/cert_test_util.cc22
-rw-r--r--net/base/openssl_util.cc86
-rw-r--r--net/base/openssl_util.h59
-rw-r--r--net/base/x509_certificate.h7
-rw-r--r--net/base/x509_certificate_openssl.cc36
-rw-r--r--net/net.gyp4
-rw-r--r--net/socket/ssl_client_socket_openssl.cc34
7 files changed, 71 insertions, 177 deletions
diff --git a/net/base/cert_test_util.cc b/net/base/cert_test_util.cc
index 1042d50..d5c678e 100644
--- a/net/base/cert_test_util.cc
+++ b/net/base/cert_test_util.cc
@@ -8,8 +8,9 @@
#if defined(USE_OPENSSL)
#include <openssl/err.h>
+#include <openssl/ssl.h>
#include <openssl/x509v3.h>
-#include "net/base/openssl_util.h"
+#include "base/openssl_util.h"
#elif defined(USE_NSS)
#include <cert.h>
#include "base/nss_util.h"
@@ -27,15 +28,11 @@ namespace net {
#if defined(USE_OPENSSL)
X509Certificate* AddTemporaryRootCertToStore(X509* x509_cert) {
- OpenSSLInitSingleton* openssl_init = GetOpenSSLInitSingleton();
-
- if (!X509_STORE_add_cert(openssl_init->x509_store(), x509_cert)) {
+ if (!X509_STORE_add_cert(X509Certificate::cert_store(), x509_cert)) {
unsigned long error_code = ERR_get_error();
if (ERR_GET_LIB(error_code) != ERR_LIB_X509 ||
ERR_GET_REASON(error_code) != X509_R_CERT_ALREADY_IN_HASH_TABLE) {
- do {
- LOG(ERROR) << "X509_STORE_add_cert error: " << error_code;
- } while ((error_code = ERR_get_error()) != 0);
+ base::ClearOpenSSLERRStack();
return NULL;
}
}
@@ -45,7 +42,7 @@ X509Certificate* AddTemporaryRootCertToStore(X509* x509_cert) {
}
X509Certificate* LoadTemporaryRootCert(const FilePath& filename) {
- EnsureOpenSSLInit();
+ base::EnsureOpenSSLInit();
std::string rawcert;
if (!file_util::ReadFileToString(filename, &rawcert)) {
@@ -53,7 +50,7 @@ X509Certificate* LoadTemporaryRootCert(const FilePath& filename) {
return NULL;
}
- ScopedSSL<BIO, BIO_free_all> cert_bio(
+ base::ScopedOpenSSL<BIO, BIO_free_all> cert_bio(
BIO_new_mem_buf(const_cast<char*>(rawcert.c_str()),
rawcert.length()));
if (!cert_bio.get()) {
@@ -61,8 +58,8 @@ X509Certificate* LoadTemporaryRootCert(const FilePath& filename) {
return NULL;
}
- ScopedSSL<X509, X509_free> pem_cert(PEM_read_bio_X509(cert_bio.get(),
- NULL, NULL, NULL));
+ base::ScopedOpenSSL<X509, X509_free> pem_cert(PEM_read_bio_X509(
+ cert_bio.get(), NULL, NULL, NULL));
if (pem_cert.get())
return AddTemporaryRootCertToStore(pem_cert.get());
@@ -70,7 +67,8 @@ X509Certificate* LoadTemporaryRootCert(const FilePath& filename) {
const unsigned char* der_data =
reinterpret_cast<const unsigned char*>(rawcert.c_str());
int der_length = rawcert.length();
- ScopedSSL<X509, X509_free> der_cert(d2i_X509(NULL, &der_data, der_length));
+ base::ScopedOpenSSL<X509, X509_free> der_cert(d2i_X509(
+ NULL, &der_data, der_length));
if (der_cert.get())
return AddTemporaryRootCertToStore(der_cert.get());
diff --git a/net/base/openssl_util.cc b/net/base/openssl_util.cc
deleted file mode 100644
index 51797ac..0000000
--- a/net/base/openssl_util.cc
+++ /dev/null
@@ -1,86 +0,0 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "net/base/openssl_util.h"
-
-#include <openssl/err.h>
-
-#include "base/logging.h"
-#include "base/platform_thread.h"
-
-namespace net {
-
-namespace {
-
-// We do certificate verification after handshake, so we disable the default
-// by registering a no-op verify function.
-int NoOpVerifyCallback(X509_STORE_CTX*, void *) {
- DVLOG(3) << "skipping cert verify";
- return 1;
-}
-
-unsigned long CurrentThreadId() {
- return static_cast<unsigned long>(PlatformThread::CurrentId());
-}
-
-SSL_CTX* CreateSSL_CTX() {
- SSL_load_error_strings();
- SSL_library_init();
- OpenSSL_add_all_algorithms();
- return SSL_CTX_new(SSLv23_client_method());
-}
-
-} // namespace
-
-OpenSSLInitSingleton::OpenSSLInitSingleton()
- : ssl_ctx_(CreateSSL_CTX()),
- store_(X509_STORE_new()) {
- CHECK(ssl_ctx_.get());
- CHECK(store_.get());
-
- SSL_CTX_set_cert_verify_callback(ssl_ctx_.get(), NoOpVerifyCallback, NULL);
- X509_STORE_set_default_paths(store_.get());
- // TODO(bulach): Enable CRL (see X509_STORE_set_flags(X509_V_FLAG_CRL_CHECK)).
- int num_locks = CRYPTO_num_locks();
- for (int i = 0; i < num_locks; ++i)
- locks_.push_back(new Lock());
- CRYPTO_set_locking_callback(LockingCallback);
- CRYPTO_set_id_callback(CurrentThreadId);
-}
-
-OpenSSLInitSingleton::~OpenSSLInitSingleton() {
- CRYPTO_set_locking_callback(NULL);
- EVP_cleanup();
- ERR_free_strings();
-}
-
-OpenSSLInitSingleton* GetOpenSSLInitSingleton() {
- return Singleton<OpenSSLInitSingleton>::get();
-}
-
-void EnsureOpenSSLInit() {
- Singleton<OpenSSLInitSingleton>::get();
-}
-
-// static
-void OpenSSLInitSingleton::LockingCallback(int mode,
- int n,
- const char* file,
- int line) {
- GetOpenSSLInitSingleton()->OnLockingCallback(mode, n, file, line);
-}
-
-void OpenSSLInitSingleton::OnLockingCallback(int mode,
- int n,
- const char* file,
- int line) {
- CHECK_LT(static_cast<size_t>(n), locks_.size());
- if (mode & CRYPTO_LOCK)
- locks_[n]->Acquire();
- else
- locks_[n]->Release();
-}
-
-} // namespace net
-
diff --git a/net/base/openssl_util.h b/net/base/openssl_util.h
deleted file mode 100644
index d4603c6..0000000
--- a/net/base/openssl_util.h
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <openssl/ssl.h>
-
-#include "base/lock.h"
-#include "base/scoped_vector.h"
-#include "base/singleton.h"
-
-namespace net {
-
-// A helper class that takes care of destroying OpenSSL objects when it goes out
-// of scope.
-template <typename T, void (*destructor)(T*)>
-class ScopedSSL {
- public:
- explicit ScopedSSL(T* ptr_) : ptr_(ptr_) { }
- ~ScopedSSL() { if (ptr_) (*destructor)(ptr_); }
-
- T* get() const { return ptr_; }
-
- private:
- T* ptr_;
-};
-
-// Singleton for initializing / cleaning up OpenSSL and holding a X509 store.
-// Access it via GetOpenSSLInitSingleton().
-class OpenSSLInitSingleton {
- public:
- SSL_CTX* ssl_ctx() const { return ssl_ctx_.get(); }
- X509_STORE* x509_store() const { return store_.get(); }
-
- private:
- friend struct DefaultSingletonTraits<OpenSSLInitSingleton>;
- OpenSSLInitSingleton();
- ~OpenSSLInitSingleton();
-
- static void LockingCallback(int mode, int n, const char* file, int line);
- void OnLockingCallback(int mode, int n, const char* file, int line);
-
- ScopedSSL<SSL_CTX, SSL_CTX_free> ssl_ctx_;
- ScopedSSL<X509_STORE, X509_STORE_free> store_;
- // These locks are used and managed by OpenSSL via LockingCallback().
- ScopedVector<Lock> locks_;
-
- DISALLOW_COPY_AND_ASSIGN(OpenSSLInitSingleton);
-};
-
-OpenSSLInitSingleton* GetOpenSSLInitSingleton();
-
-// Initialize OpenSSL if it isn't already initialized. This must be called
-// before any other OpenSSL functions (except GetOpenSSLInitSingleton above).
-// This function is thread-safe, and OpenSSL will only ever be initialized once.
-// OpenSSL will be properly shut down on program exit.
-void EnsureOpenSSLInit();
-
-} // namespace net
-
diff --git a/net/base/x509_certificate.h b/net/base/x509_certificate.h
index 2a7e6d7..1866a17 100644
--- a/net/base/x509_certificate.h
+++ b/net/base/x509_certificate.h
@@ -26,6 +26,7 @@
#elif defined(USE_OPENSSL)
// Forward declaration; real one in <x509.h>
struct x509_st;
+typedef struct x509_store_st X509_STORE;
#elif defined(USE_NSS)
// Forward declaration; real one in <cert.h>
struct CERTCertificateStr;
@@ -234,6 +235,12 @@ class X509Certificate : public base::RefCountedThreadSafe<X509Certificate> {
static HCERTSTORE cert_store();
#endif
+#if defined(USE_OPENSSL)
+ // Returns a handle to a global, in-memory certificate store. We
+ // use it for test code, e.g. importing the test server's certificate.
+ static X509_STORE* cert_store();
+#endif
+
// Verifies the certificate against the given hostname. Returns OK if
// successful or an error code upon failure.
//
diff --git a/net/base/x509_certificate_openssl.cc b/net/base/x509_certificate_openssl.cc
index 512de14..2be38dd 100644
--- a/net/base/x509_certificate_openssl.cc
+++ b/net/base/x509_certificate_openssl.cc
@@ -13,13 +13,13 @@
#include <openssl/ssl.h>
#include <openssl/x509v3.h>
+#include "base/openssl_util.h"
#include "base/pickle.h"
#include "base/singleton.h"
#include "base/string_number_conversions.h"
#include "net/base/cert_status_flags.h"
#include "net/base/cert_verify_result.h"
#include "net/base/net_errors.h"
-#include "net/base/openssl_util.h"
#include "net/base/x509_openssl_util.h"
namespace net {
@@ -31,8 +31,9 @@ namespace {
void CreateOSCertHandlesFromPKCS7Bytes(
const char* data, int length,
X509Certificate::OSCertHandles* handles) {
+ base::EnsureOpenSSLInit();
const unsigned char* der_data = reinterpret_cast<const unsigned char*>(data);
- ScopedSSL<PKCS7, PKCS7_free> pkcs7_cert(
+ base::ScopedOpenSSL<PKCS7, PKCS7_free> pkcs7_cert(
d2i_PKCS7(NULL, &der_data, length));
if (!pkcs7_cert.get())
return;
@@ -98,7 +99,7 @@ void ParseSubjectAltNames(X509Certificate::OSCertHandle cert,
if (!alt_name_ext)
return;
- ScopedSSL<GENERAL_NAMES, GENERAL_NAMES_free> alt_names(
+ base::ScopedOpenSSL<GENERAL_NAMES, GENERAL_NAMES_free> alt_names(
reinterpret_cast<GENERAL_NAMES*>(X509V3_EXT_d2i(alt_name_ext)));
if (!alt_names.get())
return;
@@ -206,16 +207,22 @@ void DERCache_free(void* parent, void* ptr, CRYPTO_EX_DATA* ad, int idx,
class X509InitSingleton {
public:
int der_cache_ex_index() const { return der_cache_ex_index_; }
+ X509_STORE* store() const { return store_.get(); }
private:
friend struct DefaultSingletonTraits<X509InitSingleton>;
- X509InitSingleton() {
- der_cache_ex_index_ = X509_get_ex_new_index(0, 0, 0, 0, DERCache_free);
+ X509InitSingleton()
+ : der_cache_ex_index_((base::EnsureOpenSSLInit(),
+ X509_get_ex_new_index(0, 0, 0, 0,
+ DERCache_free))),
+ store_(X509_STORE_new()) {
DCHECK_NE(der_cache_ex_index_, -1);
+ X509_STORE_set_default_paths(store_.get());
+ // TODO(joth): Enable CRL (see X509_STORE_set_flags(X509_V_FLAG_CRL_CHECK)).
}
- ~X509InitSingleton() {}
int der_cache_ex_index_;
+ base::ScopedOpenSSL<X509_STORE, X509_STORE_free> store_;
DISALLOW_COPY_AND_ASSIGN(X509InitSingleton);
};
@@ -290,6 +297,7 @@ void X509Certificate::FreeOSCertHandle(OSCertHandle cert_handle) {
}
void X509Certificate::Initialize() {
+ base::EnsureOpenSSLInit();
fingerprint_ = CalculateFingerprint(cert_handle_);
ParsePrincipal(cert_handle_, X509_get_subject_name(cert_handle_), &subject_);
ParsePrincipal(cert_handle_, X509_get_issuer_name(cert_handle_), &issuer_);
@@ -311,6 +319,7 @@ X509Certificate::OSCertHandle X509Certificate::CreateOSCertHandleFromBytes(
const char* data, int length) {
if (length < 0)
return NULL;
+ base::EnsureOpenSSLInit();
const unsigned char* d2i_data =
reinterpret_cast<const unsigned char*>(data);
// Don't cache this data via SetDERCache as this wire format may be not be
@@ -346,6 +355,7 @@ X509Certificate::OSCertHandles X509Certificate::CreateOSCertHandlesFromBytes(
return results;
}
+// static
X509Certificate* X509Certificate::CreateFromPickle(const Pickle& pickle,
void** pickle_iter) {
const char* data;
@@ -374,6 +384,11 @@ void X509Certificate::GetDNSNames(std::vector<std::string>* dns_names) const {
dns_names->push_back(subject_.common_name);
}
+// static
+X509_STORE* X509Certificate::cert_store() {
+ return Singleton<X509InitSingleton>::get()->store();
+}
+
int X509Certificate::Verify(const std::string& hostname,
int flags,
CertVerifyResult* verify_result) const {
@@ -387,9 +402,11 @@ int X509Certificate::Verify(const std::string& hostname,
if (!x509_openssl_util::VerifyHostname(hostname, cert_names))
verify_result->cert_status |= CERT_STATUS_COMMON_NAME_INVALID;
- ScopedSSL<X509_STORE_CTX, X509_STORE_CTX_free> ctx(X509_STORE_CTX_new());
+ base::ScopedOpenSSL<X509_STORE_CTX, X509_STORE_CTX_free> ctx(
+ X509_STORE_CTX_new());
- ScopedSSL<STACK_OF(X509), sk_X509_free_fn> intermediates(sk_X509_new_null());
+ base::ScopedOpenSSL<STACK_OF(X509), sk_X509_free_fn> intermediates(
+ sk_X509_new_null());
if (!intermediates.get())
return ERR_OUT_OF_MEMORY;
@@ -398,8 +415,7 @@ int X509Certificate::Verify(const std::string& hostname,
if (!sk_X509_push(intermediates.get(), *it))
return ERR_OUT_OF_MEMORY;
}
- int rv = X509_STORE_CTX_init(ctx.get(),
- GetOpenSSLInitSingleton()->x509_store(),
+ int rv = X509_STORE_CTX_init(ctx.get(), cert_store(),
cert_handle_, intermediates.get());
CHECK_EQ(1, rv);
diff --git a/net/net.gyp b/net/net.gyp
index 1d73dd1..b9e3776 100644
--- a/net/net.gyp
+++ b/net/net.gyp
@@ -142,8 +142,6 @@
'base/network_config_watcher_mac.h',
'base/nss_memio.c',
'base/nss_memio.h',
- 'base/openssl_util.cc',
- 'base/openssl_util.h',
'base/pem_tokenizer.cc',
'base/pem_tokenizer.h',
'base/platform_mime_util.h',
@@ -287,8 +285,6 @@
'sources!': [
'base/cert_database_openssl.cc',
'base/keygen_handler_openssl.cc',
- 'base/openssl_util.cc',
- 'base/openssl_util.h',
'base/x509_certificate_openssl.cc',
'base/x509_openssl_util.cc',
'base/x509_openssl_util.h',
diff --git a/net/socket/ssl_client_socket_openssl.cc b/net/socket/ssl_client_socket_openssl.cc
index 3f01db2..62f3dbb 100644
--- a/net/socket/ssl_client_socket_openssl.cc
+++ b/net/socket/ssl_client_socket_openssl.cc
@@ -10,10 +10,10 @@
#include <openssl/ssl.h>
#include <openssl/err.h>
-#include "net/base/cert_verifier.h"
#include "base/metrics/histogram.h"
+#include "base/openssl_util.h"
+#include "net/base/cert_verifier.h"
#include "net/base/net_errors.h"
-#include "net/base/openssl_util.h"
#include "net/base/ssl_connection_status_flags.h"
#include "net/base/ssl_info.h"
@@ -58,6 +58,29 @@ int MapOpenSSLError(int err) {
}
}
+// We do certificate verification after handshake, so we disable the default
+// by registering a no-op verify function.
+int NoOpVerifyCallback(X509_STORE_CTX*, void *) {
+ DVLOG(3) << "skipping cert verify";
+ return 1;
+}
+
+struct SSLContextSingletonTraits : public DefaultSingletonTraits<SSL_CTX> {
+ static SSL_CTX* New() {
+ base::EnsureOpenSSLInit();
+ SSL_CTX* self = SSL_CTX_new(SSLv23_client_method());
+ SSL_CTX_set_cert_verify_callback(self, NoOpVerifyCallback, NULL);
+ return self;
+ }
+ static void Delete(SSL_CTX* self) {
+ SSL_CTX_free(self);
+ }
+};
+
+SSL_CTX* GetSSLContext() {
+ return Singleton<SSL_CTX, SSLContextSingletonTraits>::get();
+}
+
} // namespace
SSLClientSocketOpenSSL::SSLClientSocketOpenSSL(
@@ -93,7 +116,7 @@ bool SSLClientSocketOpenSSL::Init() {
DCHECK(!ssl_);
DCHECK(!transport_bio_);
- ssl_ = SSL_new(GetOpenSSLInitSingleton()->ssl_ctx());
+ ssl_ = SSL_new(GetSSLContext());
if (!ssl_) {
MaybeLogSSLError();
return false;
@@ -394,8 +417,7 @@ void SSLClientSocketOpenSSL::InvalidateSessionIfBadCertificate() {
// see SSL_CTX_set_session_cache_mode(SSL_SESS_CACHE_CLIENT).
SSL_SESSION* session = SSL_get_session(ssl_);
LOG_IF(ERROR, session) << "Connection has a session?? " << session;
- int rv = SSL_CTX_remove_session(GetOpenSSLInitSingleton()->ssl_ctx(),
- session);
+ int rv = SSL_CTX_remove_session(GetSSLContext(), session);
LOG_IF(ERROR, rv) << "Session was cached?? " << rv;
}
}
@@ -404,7 +426,7 @@ X509Certificate* SSLClientSocketOpenSSL::UpdateServerCert() {
if (server_cert_)
return server_cert_;
- ScopedSSL<X509, X509_free> cert(SSL_get_peer_certificate(ssl_));
+ base::ScopedOpenSSL<X509, X509_free> cert(SSL_get_peer_certificate(ssl_));
if (!cert.get()) {
LOG(WARNING) << "SSL_get_peer_certificate returned NULL";
return NULL;