Index: net/base/x509_certificate_win.cc |
diff --git a/net/base/x509_certificate_win.cc b/net/base/x509_certificate_win.cc |
index 9e018fdde6564e76aee70b28754af7936de735b8..0d90eefa7c71e4dd21d3f7576e0a85c545e03f48 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/crypto/scoped_capi_types.h" |
#include "base/logging.h" |
#include "base/pickle.h" |
#include "base/string_tokenizer.h" |
@@ -14,6 +15,7 @@ |
#include "net/base/ev_root_ca_metadata.h" |
#include "net/base/net_errors.h" |
#include "net/base/scoped_cert_chain_context.h" |
+#include "net/base/test_root_certs.h" |
#pragma comment(lib, "crypt32.lib") |
@@ -23,6 +25,11 @@ namespace net { |
namespace { |
+typedef base::ScopedCAPIHandle< |
+ HCERTSTORE, |
+ base::CAPIDestroyerWithFlags<HCERTSTORE, |
+ CertCloseStore, 0> > ScopedHCERTSTORE; |
+ |
//----------------------------------------------------------------------------- |
// TODO(wtc): This is a copy of the MapSecurityError function in |
@@ -605,6 +612,36 @@ int X509Certificate::Verify(const std::string& hostname, |
} |
} |
+ // Temporary roots may not exist in any system store, and therefore may not |
+ // be available for certificate chain building. Create a certificate store |
+ // collection containing both the certificate chain (the cert_handle's |
+ // HCERTSTORE) and the temporary root's HCERTSTORE, so that Windows will |
+ // search both. |
bulach
2010/11/17 17:17:30
similarly here.
my (ignorable) suggestion both her
|
+ TestRootCerts* temporary_roots = TestRootCerts::GetInstance(); |
+ HCERTSTORE collection_store = temporary_roots->IsEmpty() ? |
+ NULL : CertOpenStore(CERT_STORE_PROV_COLLECTION, 0, NULL, 0, NULL); |
+ if (collection_store) { |
+ // Add the temporary roots with priority 0, so that certificates from the |
+ // temporary roots will be of a higher priority for chain building. If |
+ // they were a lower priority, it's possible a different root certificate |
+ // than the one in the temporary roots will be used, which would cause |
+ // the detection logic in FixTestRootTrust() to fail. |
+ BOOL ok = CertAddStoreToCollection(collection_store, |
+ temporary_roots->temporary_roots(), |
+ 0, 0); |
+ if (ok) |
+ ok = CertAddStoreToCollection(collection_store, |
+ cert_handle_->hCertStore, 0, 1); |
+ if (!ok) { |
+ PLOG(ERROR) << "Unable to create temporary linked certificate store"; |
+ CertCloseStore(collection_store, 0); |
+ collection_store = NULL; |
+ } |
+ } |
+ ScopedHCERTSTORE scoped_collection_store(collection_store); |
+ HCERTSTORE intermediates_store = collection_store ? |
+ collection_store : cert_handle_->hCertStore; |
+ |
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 |
@@ -613,7 +650,7 @@ int X509Certificate::Verify(const std::string& hostname, |
NULL, // default chain engine, HCCE_CURRENT_USER |
cert_handle_, |
NULL, // current system time |
- cert_handle_->hCertStore, // search this store |
+ intermediates_store, |
&chain_para, |
chain_flags, |
NULL, // reserved |
@@ -630,7 +667,7 @@ int X509Certificate::Verify(const std::string& hostname, |
NULL, // default chain engine, HCCE_CURRENT_USER |
cert_handle_, |
NULL, // current system time |
- cert_handle_->hCertStore, // search this store |
+ intermediates_store, |
&chain_para, |
chain_flags, |
NULL, // reserved |
@@ -640,8 +677,11 @@ int X509Certificate::Verify(const std::string& hostname, |
} |
ScopedCertChainContext scoped_chain_context(chain_context); |
- GetCertChainInfo(chain_context, verify_result); |
+ TestRootCerts* root_certs = TestRootCerts::GetInstance(); |
+ root_certs->UpdateChainContext( |
+ const_cast<PCERT_CHAIN_CONTEXT>(chain_context)); |
+ GetCertChainInfo(chain_context, verify_result); |
verify_result->cert_status |= MapCertChainErrorStatusToCertStatus( |
chain_context->TrustStatus.dwErrorStatus); |