Index: net/base/x509_certificate_win.cc |
diff --git a/net/base/x509_certificate_win.cc b/net/base/x509_certificate_win.cc |
index 71aa545d4e6780db05fa58bffe934d9b6b7d51a9..509c6c921b2863b157f0ff5e294cd69a63716430 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/lazy_instance.h" |
#include "base/logging.h" |
#include "base/pickle.h" |
@@ -15,6 +16,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") |
@@ -24,6 +26,21 @@ namespace net { |
namespace { |
+typedef base::ScopedCAPIHandle< |
+ HCERTSTORE, |
+ base::CAPIDestroyerWithFlags<HCERTSTORE, |
+ CertCloseStore, 0> > ScopedHCERTSTORE; |
+ |
+struct FreeChainEngineFunctor { |
+ void operator()(HCERTCHAINENGINE engine) const { |
+ if (engine) |
+ CertFreeCertificateChainEngine(engine); |
+ } |
+}; |
+ |
+typedef base::ScopedCAPIHandle<HCERTCHAINENGINE, FreeChainEngineFunctor> |
+ ScopedHCERTCHAINENGINE; |
+ |
//----------------------------------------------------------------------------- |
// TODO(wtc): This is a copy of the MapSecurityError function in |
@@ -609,15 +626,26 @@ int X509Certificate::Verify(const std::string& hostname, |
} |
} |
+ // For non-test scenarios, use the default HCERTCHAINENGINE, NULL, which |
+ // corresponds to HCCE_CURRENT_USER and is is initialized as needed by |
+ // crypt32. However, when testing, it is necessary to create a new |
+ // HCERTCHAINENGINE and use that instead. This is because each |
+ // HCERTCHAINENGINE maintains a cache of information about certificates |
+ // encountered, and each test run may modify the trust status of a |
+ // certificate. |
+ ScopedHCERTCHAINENGINE chain_engine(NULL); |
+ if (TestRootCerts::HasInstance()) |
+ chain_engine.reset(TestRootCerts::GetInstance()->GetChainEngine()); |
+ |
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( |
- NULL, // default chain engine, HCCE_CURRENT_USER |
+ chain_engine, |
cert_handle_, |
NULL, // current system time |
- cert_handle_->hCertStore, // search this store |
+ cert_handle_->hCertStore, |
&chain_para, |
chain_flags, |
NULL, // reserved |
@@ -631,10 +659,10 @@ int X509Certificate::Verify(const std::string& hostname, |
chain_para.RequestedIssuancePolicy.Usage.rgpszUsageIdentifier = NULL; |
CertFreeCertificateChain(chain_context); |
if (!CertGetCertificateChain( |
- NULL, // default chain engine, HCCE_CURRENT_USER |
+ chain_engine, |
cert_handle_, |
NULL, // current system time |
- cert_handle_->hCertStore, // search this store |
+ cert_handle_->hCertStore, |
&chain_para, |
chain_flags, |
NULL, // reserved |
@@ -645,7 +673,6 @@ int X509Certificate::Verify(const std::string& hostname, |
ScopedCertChainContext scoped_chain_context(chain_context); |
GetCertChainInfo(chain_context, verify_result); |
- |
verify_result->cert_status |= MapCertChainErrorStatusToCertStatus( |
chain_context->TrustStatus.dwErrorStatus); |