diff options
author | wtc@chromium.org <wtc@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-01-29 03:49:49 +0000 |
---|---|---|
committer | wtc@chromium.org <wtc@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-01-29 03:49:49 +0000 |
commit | 931945aa9d1a72f61eb37d3f75eb13a542d4fc2e (patch) | |
tree | f0ff0f2bb66f1dadff926ae7bb3dd270692ae146 /net/base/x509_certificate_win.cc | |
parent | c5addfbb9cb0518d8346cc9b827c2a5e8c32957d (diff) | |
download | chromium_src-931945aa9d1a72f61eb37d3f75eb13a542d4fc2e.zip chromium_src-931945aa9d1a72f61eb37d3f75eb13a542d4fc2e.tar.gz chromium_src-931945aa9d1a72f61eb37d3f75eb13a542d4fc2e.tar.bz2 |
Reverting 8864.
Revert r8864. It broke the build url_request_intercept_job.cc.
Review URL: http://codereview.chromium.org/19462
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@8868 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/base/x509_certificate_win.cc')
-rw-r--r-- | net/base/x509_certificate_win.cc | 114 |
1 files changed, 75 insertions, 39 deletions
diff --git a/net/base/x509_certificate_win.cc b/net/base/x509_certificate_win.cc index 57ce947..4e7c4ba 100644 --- a/net/base/x509_certificate_win.cc +++ b/net/base/x509_certificate_win.cc @@ -4,6 +4,7 @@ #include "net/base/x509_certificate.h" +#include "base/histogram.h" #include "base/logging.h" #include "base/pickle.h" #include "base/string_tokenizer.h" @@ -20,6 +21,23 @@ namespace net { namespace { +// Calculates the SHA-1 fingerprint of the certificate. Returns an empty +// (all zero) fingerprint on failure. +X509Certificate::Fingerprint CalculateFingerprint(PCCERT_CONTEXT cert) { + DCHECK(NULL != cert->pbCertEncoded); + DCHECK(0 != cert->cbCertEncoded); + + BOOL rv; + X509Certificate::Fingerprint sha1; + DWORD sha1_size = sizeof(sha1.data); + rv = CryptHashCertificate(NULL, CALG_SHA1, 0, cert->pbCertEncoded, + cert->cbCertEncoded, sha1.data, &sha1_size); + DCHECK(rv && sha1_size == sizeof(sha1.data)); + if (!rv) + memset(sha1.data, 0, sizeof(sha1.data)); + return sha1; +} + // Wrappers of malloc and free for CRYPT_DECODE_PARA, which requires the // WINAPI calling convention. void* WINAPI MyCryptAlloc(size_t size) { @@ -237,6 +255,39 @@ void X509Certificate::Initialize() { } // static +X509Certificate* X509Certificate::CreateFromHandle(OSCertHandle cert_handle) { + DCHECK(cert_handle); + + // Check if we already have this certificate in memory. + X509Certificate::Cache* cache = X509Certificate::Cache::GetInstance(); + X509Certificate* cert = cache->Find(CalculateFingerprint(cert_handle)); + if (cert) { + // We've found a certificate with the same fingerprint in our cache. We own + // the |cert_handle|, which makes it our job to free it. + CertFreeCertificateContext(cert_handle); + DHISTOGRAM_COUNTS(L"X509CertificateReuseCount", 1); + return cert; + } + // Otherwise, allocate a new object. + return new X509Certificate(cert_handle); +} + +// static +X509Certificate* X509Certificate::CreateFromBytes(const char* data, + int length) { + OSCertHandle cert_handle = NULL; + if (!CertAddEncodedCertificateToStore( + NULL, // the cert won't be persisted in any cert store + X509_ASN_ENCODING, + reinterpret_cast<const BYTE*>(data), length, + CERT_STORE_ADD_USE_EXISTING, + &cert_handle)) + return NULL; + + return CreateFromHandle(cert_handle); +} + +// static X509Certificate* X509Certificate::CreateFromPickle(const Pickle& pickle, void** pickle_iter) { const char* data; @@ -252,7 +303,22 @@ X509Certificate* X509Certificate::CreateFromPickle(const Pickle& pickle, NULL, reinterpret_cast<const void **>(&cert_handle))) return NULL; - return CreateFromHandle(cert_handle, SOURCE_LONE_CERT_IMPORT); + return CreateFromHandle(cert_handle); +} + +X509Certificate::X509Certificate(OSCertHandle cert_handle) + : cert_handle_(cert_handle) { + Initialize(); +} + +X509Certificate::X509Certificate(std::string subject, std::string issuer, + Time start_date, Time expiration_date) + : subject_(subject), + issuer_(issuer), + valid_start_(start_date), + valid_expiry_(expiration_date), + cert_handle_(NULL) { + memset(fingerprint_.data, 0, sizeof(fingerprint_.data)); } void X509Certificate::Persist(Pickle* pickle) { @@ -271,6 +337,13 @@ void X509Certificate::Persist(Pickle* pickle) { pickle->TrimWriteData(length); } +X509Certificate::~X509Certificate() { + // We might not be in the cache, but it is safe to remove ourselves anyway. + X509Certificate::Cache::GetInstance()->Remove(this); + if (cert_handle_) + CertFreeCertificateContext(cert_handle_); +} + void X509Certificate::GetDNSNames(std::vector<std::string>* dns_names) const { dns_names->clear(); scoped_ptr_malloc<CERT_ALT_NAME_INFO> alt_name_info; @@ -333,7 +406,7 @@ bool X509Certificate::IsEV(int cert_status) const { // Look up the EV policy OID of the root CA. PCCERT_CONTEXT root_cert = element[num_elements - 1]->pCertContext; - Fingerprint fingerprint = CalculateFingerprint(root_cert); + X509Certificate::Fingerprint fingerprint = CalculateFingerprint(root_cert); std::string ev_policy_oid; if (!metadata->GetPolicyOID(fingerprint, &ev_policy_oid)) return false; @@ -349,42 +422,5 @@ bool X509Certificate::IsEV(int cert_status) const { return ContainsPolicy(policies_info.get(), ev_policy_oid.c_str()); } -// static -X509Certificate::OSCertHandle X509Certificate::CreateOSCertHandleFromBytes( - const char* data, int length) { - OSCertHandle cert_handle = NULL; - if (!CertAddEncodedCertificateToStore( - NULL, // the cert won't be persisted in any cert store - X509_ASN_ENCODING, - reinterpret_cast<const BYTE*>(data), length, - CERT_STORE_ADD_USE_EXISTING, - &cert_handle)) - return NULL; - - return cert_handle; -} - -// static -void X509Certificate::FreeOSCertHandle(OSCertHandle cert_handle) { - CertFreeCertificateContext(cert_handle); -} - -// static -X509Certificate::Fingerprint X509Certificate::CalculateFingerprint( - OSCertHandle cert) { - DCHECK(NULL != cert->pbCertEncoded); - DCHECK(0 != cert->cbCertEncoded); - - BOOL rv; - Fingerprint sha1; - DWORD sha1_size = sizeof(sha1.data); - rv = CryptHashCertificate(NULL, CALG_SHA1, 0, cert->pbCertEncoded, - cert->cbCertEncoded, sha1.data, &sha1_size); - DCHECK(rv && sha1_size == sizeof(sha1.data)); - if (!rv) - memset(sha1.data, 0, sizeof(sha1.data)); - return sha1; -} - } // namespace net |