Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(893)

Unified Diff: net/base/x509_certificate_win.cc

Issue 2944008: Refactor X509Certificate caching to cache the OS handle, rather than the X509Certificate (Closed)
Patch Set: Rebase to trunk after splitting out 4645001 Created 9 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: net/base/x509_certificate_win.cc
diff --git a/net/base/x509_certificate_win.cc b/net/base/x509_certificate_win.cc
index 566a5cfa47ffca4473f736dec6e943f1dbcab0b8..ca72f563f360a40f79a60fef82d4050d30e7a337 100644
--- a/net/base/x509_certificate_win.cc
+++ b/net/base/x509_certificate_win.cc
@@ -536,9 +536,7 @@ X509Certificate* X509Certificate::CreateSelfSigned(
DCHECK(cert_handle) << "Failed to create self-signed certificate: "
<< logging::GetLastSystemErrorCode();
- X509Certificate* cert = CreateFromHandle(cert_handle,
- SOURCE_LONE_CERT_IMPORT,
- OSCertHandles());
+ X509Certificate* cert = CreateFromHandle(cert_handle, OSCertHandles());
FreeOSCertHandle(cert_handle);
return cert;
}
@@ -594,6 +592,46 @@ HCERTSTORE X509Certificate::cert_store() {
return g_cert_store.Get().cert_store();
}
+X509Certificate::OSCertListHandle
+X509Certificate::CreateOSCertListHandle() const {
+ // Create a temporary certificate store to hold |cert_handle_| and any
+ // associated intermediates. The store will be referenced in the returned
+ // OSCertListHandle, and will not be freed until the OSCertListHandle is
+ // freed.
+ OSCertListHandle cert_list = NULL;
+ DWORD flags = CERT_STORE_DEFER_CLOSE_UNTIL_LAST_FREE_FLAG;
+ HCERTSTORE store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0,
+ NULL, flags, NULL);
+
+ if (store) {
+ // NOTE: This preserves all of the properties of |cert_handle_| except for
+ // CERT_KEY_PROV_HANDLE_PROP_ID and CERT_KEY_CONTEXT_PROP_ID - the two
+ // properties that hold access to already-opened private keys. If a handle
+ // has already been unlocked (eg: PIN prompt), then the first time that
+ // the identity is used for client auth, it may prompt the user again.
+ BOOL ok = CertAddCertificateContextToStore(store, cert_handle_,
+ CERT_STORE_ADD_ALWAYS,
+ &cert_list);
+ if (ok && cert_list) {
+ for (size_t i = 0; ok && i < intermediate_ca_certs_.size(); ++i) {
+ ok = CertAddCertificateContextToStore(store, intermediate_ca_certs_[i],
+ CERT_STORE_ADD_ALWAYS, NULL);
+ }
+ }
+
+ // If |cert_list| points to a valid certificate, this will not actually
+ // close and free |store| until |cert_list| is freed.
+ CertCloseStore(store, 0);
+
+ if (!ok) {
+ FreeOSCertListHandle(cert_list);
+ return NULL;
+ }
+ }
+
+ return cert_list;
+}
+
int X509Certificate::Verify(const std::string& hostname,
int flags,
CertVerifyResult* verify_result) const {
@@ -662,21 +700,25 @@ int X509Certificate::Verify(const std::string& hostname,
if (TestRootCerts::HasInstance())
chain_engine.reset(TestRootCerts::GetInstance()->GetChainEngine());
+ OSCertListHandle cert_list = CreateOSCertListHandle();
PCCERT_CHAIN_CONTEXT chain_context;
// IE passes a non-NULL pTime argument that specifies the current system
// time. IE passes CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT as the
// chain_flags argument.
if (!CertGetCertificateChain(
chain_engine,
- cert_handle_,
+ cert_list,
NULL, // current system time
- cert_handle_->hCertStore,
+ cert_list->hCertStore,
&chain_para,
chain_flags,
NULL, // reserved
&chain_context)) {
+ FreeOSCertListHandle(cert_list);
return MapSecurityError(GetLastError());
}
+ FreeOSCertListHandle(cert_list);
+
if (chain_context->TrustStatus.dwErrorStatus &
CERT_TRUST_IS_NOT_VALID_FOR_USAGE) {
ev_policy_oid = NULL;
@@ -911,6 +953,11 @@ void X509Certificate::FreeOSCertHandle(OSCertHandle cert_handle) {
}
// static
+void X509Certificate::FreeOSCertListHandle(OSCertListHandle cert_list) {
+ CertFreeCertificateContext(cert_list);
+}
+
+// static
SHA1Fingerprint X509Certificate::CalculateFingerprint(
OSCertHandle cert) {
DCHECK(NULL != cert->pbCertEncoded);

Powered by Google App Engine
This is Rietveld 408576698