diff options
author | bulach@chromium.org <bulach@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-10-27 14:31:52 +0000 |
---|---|---|
committer | bulach@chromium.org <bulach@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-10-27 14:31:52 +0000 |
commit | 87f26d5e783ca0ea0780471cddbfbd8b895c83ec (patch) | |
tree | f20d74325d8fd433a936d73ca75d5c47d1c99dd3 /net | |
parent | 4ada70dab410c697c4f501a99e7210e1b897d30c (diff) | |
download | chromium_src-87f26d5e783ca0ea0780471cddbfbd8b895c83ec.zip chromium_src-87f26d5e783ca0ea0780471cddbfbd8b895c83ec.tar.gz chromium_src-87f26d5e783ca0ea0780471cddbfbd8b895c83ec.tar.bz2 |
Fixes net_unittests for OpenSSL.
IntermediateCARequireExplicitPolicy uses a DER-encoded (rather than PEM) certificate.
HTTPSRequestTest.HTTPSExpiredTest however uses a PEM certificate, so we need to try
both formats in LoadTemporaryRootCert().
BUG=none
TEST=X509CertificateTest.IntermediateCARequireExplicitPolicy
Review URL: http://codereview.chromium.org/4047002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@64068 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net')
-rw-r--r-- | net/base/cert_test_util.cc | 56 | ||||
-rw-r--r-- | net/base/openssl_util.cc | 4 | ||||
-rw-r--r-- | net/base/openssl_util.h | 8 |
3 files changed, 45 insertions, 23 deletions
diff --git a/net/base/cert_test_util.cc b/net/base/cert_test_util.cc index cb7f9a8..1042d50 100644 --- a/net/base/cert_test_util.cc +++ b/net/base/cert_test_util.cc @@ -26,9 +26,27 @@ namespace net { #if defined(USE_OPENSSL) -X509Certificate* LoadTemporaryRootCert(const FilePath& filename) { +X509Certificate* AddTemporaryRootCertToStore(X509* x509_cert) { OpenSSLInitSingleton* openssl_init = GetOpenSSLInitSingleton(); + if (!X509_STORE_add_cert(openssl_init->x509_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); + return NULL; + } + } + return X509Certificate::CreateFromHandle( + x509_cert, X509Certificate::SOURCE_LONE_CERT_IMPORT, + X509Certificate::OSCertHandles()); +} + +X509Certificate* LoadTemporaryRootCert(const FilePath& filename) { + EnsureOpenSSLInit(); + std::string rawcert; if (!file_util::ReadFileToString(filename, &rawcert)) { LOG(ERROR) << "Can't load certificate " << filename.value(); @@ -43,27 +61,21 @@ X509Certificate* LoadTemporaryRootCert(const FilePath& filename) { return NULL; } - ScopedSSL<X509, X509_free> x509_cert(PEM_read_bio_X509(cert_bio.get(), - NULL, NULL, NULL)); - if (!x509_cert.get()) { - LOG(ERROR) << "Can't parse certificate " << filename.value(); - return NULL; - } - - if (!X509_STORE_add_cert(openssl_init->x509_store(), x509_cert.get())) { - 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); - return NULL; - } - } - - return X509Certificate::CreateFromHandle( - x509_cert.get(), X509Certificate::SOURCE_LONE_CERT_IMPORT, - X509Certificate::OSCertHandles()); + ScopedSSL<X509, X509_free> pem_cert(PEM_read_bio_X509(cert_bio.get(), + NULL, NULL, NULL)); + if (pem_cert.get()) + return AddTemporaryRootCertToStore(pem_cert.get()); + + // File does not contain PEM data, let's try DER. + 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)); + if (der_cert.get()) + return AddTemporaryRootCertToStore(der_cert.get()); + + LOG(ERROR) << "Can't parse certificate " << filename.value(); + return NULL; } #elif defined(USE_NSS) X509Certificate* LoadTemporaryRootCert(const FilePath& filename) { diff --git a/net/base/openssl_util.cc b/net/base/openssl_util.cc index fcdc3a1..51797ac 100644 --- a/net/base/openssl_util.cc +++ b/net/base/openssl_util.cc @@ -59,6 +59,10 @@ OpenSSLInitSingleton* GetOpenSSLInitSingleton() { return Singleton<OpenSSLInitSingleton>::get(); } +void EnsureOpenSSLInit() { + Singleton<OpenSSLInitSingleton>::get(); +} + // static void OpenSSLInitSingleton::LockingCallback(int mode, int n, diff --git a/net/base/openssl_util.h b/net/base/openssl_util.h index 4218a89..d4603c6 100644 --- a/net/base/openssl_util.h +++ b/net/base/openssl_util.h @@ -25,7 +25,7 @@ class ScopedSSL { }; // Singleton for initializing / cleaning up OpenSSL and holding a X509 store. -// Access it via EnsureOpenSSLInit(). +// Access it via GetOpenSSLInitSingleton(). class OpenSSLInitSingleton { public: SSL_CTX* ssl_ctx() const { return ssl_ctx_.get(); } @@ -49,5 +49,11 @@ class 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 |