| 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);
|
|
|
|
|