From: Brendan Forster Date: Thu, 27 Apr 2017 04:44:58 +0000 (+1000) Subject: actually validate the chain before adding X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=80212c0ab425a54ee7ac3f12d0c6c27c24c71000;p=platform%2Fframework%2Fweb%2Fcrosswalk-tizen.git actually validate the chain before adding --- diff --git a/atom/browser/ui/certificate_trust_win.cc b/atom/browser/ui/certificate_trust_win.cc index 49d74367a..892441cec 100644 --- a/atom/browser/ui/certificate_trust_win.cc +++ b/atom/browser/ui/certificate_trust_win.cc @@ -12,42 +12,127 @@ namespace certificate_trust { -void ShowCertificateTrust(atom::NativeWindow* parent_window, - const scoped_refptr& cert, - const std::string& message, - const ShowTrustCallback& callback) { - // opening the Trusted Root Certificate store for the current user - auto hCertStore = CertOpenStore( +BOOL AddCertificateAndRefresh( + const HCERTSTORE certStore, + const PCCERT_CONTEXT certContext, + const scoped_refptr& cert) { + auto result = CertAddCertificateContextToStore( + certStore, + certContext, + CERT_STORE_ADD_REPLACE_EXISTING, + NULL); + + if (result) { + auto cert_db = net::CertDatabase::GetInstance(); + // Force Chromium to reload the certificate since it might be trusted + // now. + cert_db->NotifyObserversCertDBChanged(cert.get()); + } + + return result; +} + + +// Add the provided certificate to the Trusted Root +// Certificate Authorities store for the current user. +// +// This requires prompting the user to confirm they +// trust the certificate. +BOOL AddToTrustedRootStore(const PCCERT_CONTEXT certContext, + const scoped_refptr& cert) { + auto rootCertStore = CertOpenStore( CERT_STORE_PROV_SYSTEM, 0, NULL, CERT_SYSTEM_STORE_CURRENT_USER, - // installing into Trusted Root Certificate Authorities, not Personal L"Root"); - if (hCertStore == NULL) { - callback.Run(); - return; + if (rootCertStore == NULL) { + // could not resolve the certificate store, giving up + return false; } - auto pCertContext = cert->CreateOSCertChainForCert(); + auto result = AddCertificateAndRefresh(rootCertStore, certContext, cert); - // This is a blocking call which displays a prompt to the user to confirm - // they trust this certificate - auto result = CertAddCertificateContextToStore( - hCertStore, - pCertContext, - CERT_STORE_ADD_REPLACE_EXISTING, - NULL); + CertCloseStore(rootCertStore, CERT_CLOSE_STORE_FORCE_FLAG); - if (result) { - auto cert_db = net::CertDatabase::GetInstance(); - // Force Chromium to reload the certificate since it might be trusted - // now. - cert_db->NotifyObserversCertDBChanged(cert.get()); + return result; +} + +// Add the provided certificate to the Personal +// certificate store for the current user. +BOOL AddToPersonalStore(const PCCERT_CONTEXT certContext, + const scoped_refptr& cert) { + auto userCertStore = CertOpenStore( + CERT_STORE_PROV_SYSTEM, + 0, + NULL, + CERT_SYSTEM_STORE_CURRENT_USER, + L"My"); + + if (userCertStore == NULL) { + // could not resolve the certificate store, giving up + return false; } - CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG); + auto result = AddCertificateAndRefresh(userCertStore, certContext, cert); + + CertCloseStore(userCertStore, CERT_CLOSE_STORE_FORCE_FLAG); + + return result; +} + +CERT_CHAIN_PARA GetCertificateChainParameters() { + CERT_ENHKEY_USAGE enhkeyUsage; + enhkeyUsage.cUsageIdentifier = 0; + enhkeyUsage.rgpszUsageIdentifier = NULL; + + CERT_USAGE_MATCH CertUsage; + // ensure the rules are applied to the entire chain + CertUsage.dwType = USAGE_MATCH_TYPE_AND; + CertUsage.Usage = enhkeyUsage; + + CERT_CHAIN_PARA params = { sizeof(CERT_CHAIN_PARA) }; + params.RequestedUsage = CertUsage; + + return params; +} + +void ShowCertificateTrust(atom::NativeWindow* parent_window, + const scoped_refptr& cert, + const std::string& message, + const ShowTrustCallback& callback) { + PCCERT_CHAIN_CONTEXT chainContext; + + auto pCertContext = cert->CreateOSCertChainForCert(); + + auto params = GetCertificateChainParameters(); + + if (CertGetCertificateChain(NULL, + pCertContext, + NULL, + NULL, + ¶ms, + NULL, + NULL, + &chainContext)) { + switch (chainContext->TrustStatus.dwErrorStatus) { + case CERT_TRUST_NO_ERROR: + AddToPersonalStore(pCertContext, cert); + break; + + case CERT_TRUST_IS_UNTRUSTED_ROOT: + case CERT_TRUST_IS_SELF_SIGNED: + AddToTrustedRootStore(pCertContext, cert); + break; + + default: + // we can't handle other scenarios, giving up + break; + } + + CertFreeCertificateChain(chainContext); + } CertFreeCertificateContext(pCertContext);