diff options
author | wtc@chromium.org <wtc@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-01-29 03:25:04 +0000 |
---|---|---|
committer | wtc@chromium.org <wtc@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-01-29 03:25:04 +0000 |
commit | 09a1bd76e3fd08b2ba0035af7ee2f0b60661174b (patch) | |
tree | 825db69ff522a1bacecf9b58eef87b01747509c8 /net/base/x509_certificate_mac.cc | |
parent | 507bdd1707edb7a90971f90e9b7e654c96cbb810 (diff) | |
download | chromium_src-09a1bd76e3fd08b2ba0035af7ee2f0b60661174b.zip chromium_src-09a1bd76e3fd08b2ba0035af7ee2f0b60661174b.tar.gz chromium_src-09a1bd76e3fd08b2ba0035af7ee2f0b60661174b.tar.bz2 |
Work around our not caching the intermediate CA
certificates by passing the source of each OSCertHandle to
CreateFromHandle and the X509Certificate constructor. If
the OSCertHandle comes from the network layer, we know it
has a complete certificate chain and therefore prefer it to
an OSCertHandle that comes from the HTTP cache, which
doesn't have the intermediate CA certificates. A
certificate from the network layer can kick out a
certificate from the HTTP cache in our certificate cache.
This workaround seems good enough to fix all the known
symptoms of not caching the intermediate CA certificates.
Move the common code in x509_certificate_<os>.cc to
x509_certificate.cc.
R=eroman
BUG=3154,7065
Review URL: http://codereview.chromium.org/18836
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@8864 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/base/x509_certificate_mac.cc')
-rw-r--r-- | net/base/x509_certificate_mac.cc | 121 |
1 files changed, 42 insertions, 79 deletions
diff --git a/net/base/x509_certificate_mac.cc b/net/base/x509_certificate_mac.cc index 11191bd..ac60645 100644 --- a/net/base/x509_certificate_mac.cc +++ b/net/base/x509_certificate_mac.cc @@ -7,7 +7,6 @@ #include <CommonCrypto/CommonDigest.h> #include <time.h> -#include "base/histogram.h" #include "base/logging.h" #include "base/pickle.h" #include "net/base/cert_status_flags.h" @@ -19,26 +18,6 @@ namespace net { namespace { -// Calculates the SHA-1 fingerprint of the certificate. Returns an empty -// (all zero) fingerprint on failure. -X509Certificate::Fingerprint CalculateFingerprint( - X509Certificate::OSCertHandle cert) { - X509Certificate::Fingerprint sha1; - memset(sha1.data, 0, sizeof(sha1.data)); - - CSSM_DATA cert_data; - OSStatus status = SecCertificateGetData(cert, &cert_data); - if (status) - return sha1; - - DCHECK(NULL != cert_data.Data); - DCHECK(0 != cert_data.Length); - - CC_SHA1(cert_data.Data, cert_data.Length, sha1.data); - - return sha1; -} - inline bool CSSMOIDEqual(const CSSM_OID* oid1, const CSSM_OID* oid2) { return oid1->Length == oid2->Length && (memcmp(oid1->Data, oid2->Data, oid1->Length) == 0); @@ -242,42 +221,6 @@ 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. - CFRelease(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) { - CSSM_DATA cert_data; - cert_data.Data = const_cast<uint8*>(reinterpret_cast<const uint8*>(data)); - cert_data.Length = length; - - OSCertHandle cert_handle = NULL; - OSStatus status = SecCertificateCreateFromData(&cert_data, - CSSM_CERT_X_509v3, - CSSM_CERT_ENCODING_BER, - &cert_handle); - if (status) - return NULL; - - return CreateFromHandle(cert_handle); -} - -// static X509Certificate* X509Certificate::CreateFromPickle(const Pickle& pickle, void** pickle_iter) { const char* data; @@ -288,21 +231,6 @@ X509Certificate* X509Certificate::CreateFromPickle(const Pickle& pickle, return CreateFromBytes(data, length); } -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) { CSSM_DATA cert_data; OSStatus status = SecCertificateGetData(cert_handle_, &cert_data); @@ -314,13 +242,6 @@ void X509Certificate::Persist(Pickle* pickle) { pickle->WriteData(reinterpret_cast<char*>(cert_data.Data), cert_data.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_) - CFRelease(cert_handle_); -} - void X509Certificate::GetDNSNames(std::vector<std::string>* dns_names) const { dns_names->clear(); @@ -345,4 +266,46 @@ bool X509Certificate::IsEV(int cert_status) const { return false; } +// static +X509Certificate::OSCertHandle X509Certificate::CreateOSCertHandleFromBytes( + const char* data, int length) { + CSSM_DATA cert_data; + cert_data.Data = const_cast<uint8*>(reinterpret_cast<const uint8*>(data)); + cert_data.Length = length; + + OSCertHandle cert_handle = NULL; + OSStatus status = SecCertificateCreateFromData(&cert_data, + CSSM_CERT_X_509v3, + CSSM_CERT_ENCODING_BER, + &cert_handle); + if (status) + return NULL; + + return cert_handle; +} + +// static +void X509Certificate::FreeOSCertHandle(OSCertHandle cert_handle) { + CFRelease(cert_handle); +} + +// static +X509Certificate::Fingerprint X509Certificate::CalculateFingerprint( + OSCertHandle cert) { + Fingerprint sha1; + memset(sha1.data, 0, sizeof(sha1.data)); + + CSSM_DATA cert_data; + OSStatus status = SecCertificateGetData(cert, &cert_data); + if (status) + return sha1; + + DCHECK(NULL != cert_data.Data); + DCHECK(0 != cert_data.Length); + + CC_SHA1(cert_data.Data, cert_data.Length, sha1.data); + + return sha1; +} + } // namespace net |