Chromium Code Reviews| 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); |