summaryrefslogtreecommitdiffstats
path: root/net/base/x509_certificate_mac.cc
diff options
context:
space:
mode:
authorwtc@chromium.org <wtc@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-01-29 03:25:04 +0000
committerwtc@chromium.org <wtc@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-01-29 03:25:04 +0000
commit09a1bd76e3fd08b2ba0035af7ee2f0b60661174b (patch)
tree825db69ff522a1bacecf9b58eef87b01747509c8 /net/base/x509_certificate_mac.cc
parent507bdd1707edb7a90971f90e9b7e654c96cbb810 (diff)
downloadchromium_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.cc121
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