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

Unified Diff: net/base/x509_certificate_win.cc

Issue 7324039: Ensure X509Certificate::OSCertHandles are safe to be used on both UI and IO threads on Win (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 9 years, 5 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 8442fdbcd7e10ebdc686835ccdecab8fda4169ef..064ac606c91921ff8ba49284702a1887316d044d 100644
--- a/net/base/x509_certificate_win.cc
+++ b/net/base/x509_certificate_win.cc
@@ -630,6 +630,46 @@ void X509Certificate::GetDNSNames(std::vector<std::string>* dns_names) const {
dns_names->push_back(subject_.common_name);
}
+X509Certificate::OSCertListHandle
+X509Certificate::CreateOSCertListHandle() const {
+ // Create a temporary certificate store to hold |cert_handle_| and any
wtc 2011/10/04 00:26:34 temporary => in-memory
+ // associated intermediates. The store will be referenced in the returned
wtc 2011/10/04 00:26:34 intermediates => intermediate certificates
+ // 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.
wtc 2011/10/04 00:26:34 Nit: identity => certificate handle? Do we ever u
Ryan Sleevi 2011/10/04 03:38:07 Now that certificate prompting has been moved into
wtc 2011/10/04 18:00:51 You can keep this comment. I asked the question t
+ 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::VerifyInternal(const std::string& hostname,
int flags,
CertVerifyResult* verify_result) const {
@@ -696,21 +736,24 @@ int X509Certificate::VerifyInternal(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);
wtc 2011/10/04 00:26:34 Do we have a scoped type for PCCERTCONTEXT? We co
return MapSecurityError(GetLastError());
}
+
if (chain_context->TrustStatus.dwErrorStatus &
CERT_TRUST_IS_NOT_VALID_FOR_USAGE) {
ev_policy_oid = NULL;
@@ -719,16 +762,19 @@ int X509Certificate::VerifyInternal(const std::string& hostname,
CertFreeCertificateChain(chain_context);
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);
+
ScopedCertChainContext scoped_chain_context(chain_context);
GetCertChainInfo(chain_context, verify_result);
@@ -940,6 +986,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);
« net/base/x509_certificate_openssl.cc ('K') | « net/base/x509_certificate_openssl.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698