diff options
author | rsleevi@chromium.org <rsleevi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-12-16 00:01:37 +0000 |
---|---|---|
committer | rsleevi@chromium.org <rsleevi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-12-16 00:01:37 +0000 |
commit | 32765f80889421c6161a7b9e73bc1ee722db6892 (patch) | |
tree | bba0f974c84f9859da5b62bc233d00955e63c032 /net/base/cert_test_util.cc | |
parent | 235478be87f59f3962eda9d8f3fba04e8a5096e4 (diff) | |
download | chromium_src-32765f80889421c6161a7b9e73bc1ee722db6892.zip chromium_src-32765f80889421c6161a7b9e73bc1ee722db6892.tar.gz chromium_src-32765f80889421c6161a7b9e73bc1ee722db6892.tar.bz2 |
Add support for temporarily trusting a certificate for the duration of unit tests on Windows, rather than requiring the machine to be pre-configured out-of-band.
Given the lack of a Microsoft-provided high-level API to supply application-level trusts to the verification routines, this implements a workaround that intercepts attempts to open the trusted system root store and injects the test certificates directly. This allows the unit tests to work without requiring that the Test CA be added to the machine's Trusted Certificates store.
While doing so, clean up the interface to adding/removing trusted test certificates, so as to support more than one trusted certificate if necessary.
BUG=8470
TEST=To follow
Review URL: http://codereview.chromium.org/4646001
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@69351 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/base/cert_test_util.cc')
-rw-r--r-- | net/base/cert_test_util.cc | 156 |
1 files changed, 20 insertions, 136 deletions
diff --git a/net/base/cert_test_util.cc b/net/base/cert_test_util.cc index df00b9d..fb0c0f8 100644 --- a/net/base/cert_test_util.cc +++ b/net/base/cert_test_util.cc @@ -4,153 +4,37 @@ #include "net/base/cert_test_util.h" -#include "build/build_config.h" - -#if defined(USE_OPENSSL) -#include <openssl/err.h> -#include <openssl/ssl.h> -#include <openssl/x509v3.h> -#include "base/openssl_util.h" -#elif defined(USE_NSS) -#include <cert.h> -#include "base/nss_util.h" -#elif defined(OS_MACOSX) -#include <Security/Security.h> -#include "base/mac/scoped_cftyperef.h" -#endif - +#include "base/file_path.h" #include "base/file_util.h" -#include "base/logging.h" #include "base/path_service.h" #include "net/base/x509_certificate.h" namespace net { -#if defined(USE_OPENSSL) -X509Certificate* AddTemporaryRootCertToStore(X509* 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) { - base::ClearOpenSSLERRStack(FROM_HERE); - return NULL; - } - } - return X509Certificate::CreateFromHandle( - x509_cert, X509Certificate::SOURCE_LONE_CERT_IMPORT, - X509Certificate::OSCertHandles()); -} - -X509Certificate* LoadTemporaryRootCert(const FilePath& filename) { - base::EnsureOpenSSLInit(); - - std::string rawcert; - if (!file_util::ReadFileToString(filename, &rawcert)) { - LOG(ERROR) << "Can't load certificate " << filename.value(); - return NULL; - } - - base::ScopedOpenSSL<BIO, BIO_free_all> cert_bio( - BIO_new_mem_buf(const_cast<char*>(rawcert.c_str()), - rawcert.length())); - if (!cert_bio.get()) { - LOG(ERROR) << "Can't create read-only BIO " << filename.value(); - return 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()); - - // 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(); - base::ScopedOpenSSL<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; +FilePath GetTestCertsDirectory() { + FilePath certs_dir; + PathService::Get(base::DIR_SOURCE_ROOT, &certs_dir); + certs_dir = certs_dir.AppendASCII("net"); + certs_dir = certs_dir.AppendASCII("data"); + certs_dir = certs_dir.AppendASCII("ssl"); + certs_dir = certs_dir.AppendASCII("certificates"); + return certs_dir; } -#elif defined(USE_NSS) -X509Certificate* LoadTemporaryRootCert(const FilePath& filename) { - base::EnsureNSSInit(); - std::string rawcert; - if (!file_util::ReadFileToString(filename, &rawcert)) { - LOG(ERROR) << "Can't load certificate " << filename.value(); +scoped_refptr<X509Certificate> ImportCertFromFile( + const FilePath& certs_dir, + const std::string& cert_file) { + FilePath cert_path = certs_dir.AppendASCII(cert_file); + std::string cert_data; + if (!file_util::ReadFileToString(cert_path, &cert_data)) return NULL; - } - CERTCertificate *cert; - cert = CERT_DecodeCertFromPackage(const_cast<char *>(rawcert.c_str()), - rawcert.length()); - if (!cert) { - LOG(ERROR) << "Can't convert certificate " << filename.value(); + CertificateList certs_in_file = + X509Certificate::CreateCertificateListFromBytes( + cert_data.data(), cert_data.size(), X509Certificate::FORMAT_AUTO); + if (certs_in_file.empty()) return NULL; - } - - // TODO(port): remove this const_cast after NSS 3.12.3 is released - CERTCertTrust trust; - int rv = CERT_DecodeTrustString(&trust, const_cast<char *>("TCu,Cu,Tu")); - if (rv != SECSuccess) { - LOG(ERROR) << "Can't decode trust string"; - CERT_DestroyCertificate(cert); - return NULL; - } - - rv = CERT_ChangeCertTrust(CERT_GetDefaultCertDB(), cert, &trust); - if (rv != SECSuccess) { - LOG(ERROR) << "Can't change trust for certificate " << filename.value(); - CERT_DestroyCertificate(cert); - return NULL; - } - - X509Certificate* result = X509Certificate::CreateFromHandle( - cert, - X509Certificate::SOURCE_LONE_CERT_IMPORT, - X509Certificate::OSCertHandles()); - CERT_DestroyCertificate(cert); - return result; -} -#endif - -#if defined(OS_MACOSX) -X509Certificate* LoadTemporaryRootCert(const FilePath& filename) { - std::string rawcert; - if (!file_util::ReadFileToString(filename, &rawcert)) { - LOG(ERROR) << "Can't load certificate " << filename.value(); - return NULL; - } - - CFDataRef pem = CFDataCreate(kCFAllocatorDefault, - reinterpret_cast<const UInt8*>(rawcert.data()), - static_cast<CFIndex>(rawcert.size())); - if (!pem) - return NULL; - base::mac::ScopedCFTypeRef<CFDataRef> scoped_pem(pem); - - SecExternalFormat input_format = kSecFormatUnknown; - SecExternalItemType item_type = kSecItemTypeUnknown; - CFArrayRef cert_array = NULL; - if (SecKeychainItemImport(pem, NULL, &input_format, &item_type, 0, NULL, NULL, - &cert_array)) - return NULL; - base::mac::ScopedCFTypeRef<CFArrayRef> scoped_cert_array(cert_array); - - if (!CFArrayGetCount(cert_array)) - return NULL; - - SecCertificateRef cert_ref = static_cast<SecCertificateRef>( - const_cast<void*>(CFArrayGetValueAtIndex(cert_array, 0))); - - return X509Certificate::CreateFromHandle(cert_ref, - X509Certificate::SOURCE_LONE_CERT_IMPORT, - X509Certificate::OSCertHandles()); + return certs_in_file[0]; } -#endif } // namespace net |