actually validate the chain before adding
This commit is contained in:
		
					parent
					
						
							
								f644ba56a3
							
						
					
				
			
			
				commit
				
					
						80212c0ab4
					
				
			
		
					 1 changed files with 110 additions and 25 deletions
				
			
		| 
						 | 
					@ -12,31 +12,13 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace certificate_trust {
 | 
					namespace certificate_trust {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void ShowCertificateTrust(atom::NativeWindow* parent_window,
 | 
					BOOL AddCertificateAndRefresh(
 | 
				
			||||||
                          const scoped_refptr<net::X509Certificate>& cert,
 | 
					    const HCERTSTORE certStore,
 | 
				
			||||||
                          const std::string& message,
 | 
					    const PCCERT_CONTEXT certContext,
 | 
				
			||||||
                          const ShowTrustCallback& callback) {
 | 
					    const scoped_refptr<net::X509Certificate>& cert) {
 | 
				
			||||||
    // opening the Trusted Root Certificate store for the current user
 | 
					 | 
				
			||||||
    auto hCertStore = 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;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    auto pCertContext = cert->CreateOSCertChainForCert();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // This is a blocking call which displays a prompt to the user to confirm
 | 
					 | 
				
			||||||
    // they trust this certificate
 | 
					 | 
				
			||||||
    auto result = CertAddCertificateContextToStore(
 | 
					    auto result = CertAddCertificateContextToStore(
 | 
				
			||||||
        hCertStore,
 | 
					        certStore,
 | 
				
			||||||
        pCertContext,
 | 
					        certContext,
 | 
				
			||||||
        CERT_STORE_ADD_REPLACE_EXISTING,
 | 
					        CERT_STORE_ADD_REPLACE_EXISTING,
 | 
				
			||||||
        NULL);
 | 
					        NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -47,7 +29,110 @@ void ShowCertificateTrust(atom::NativeWindow* parent_window,
 | 
				
			||||||
        cert_db->NotifyObserversCertDBChanged(cert.get());
 | 
					        cert_db->NotifyObserversCertDBChanged(cert.get());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
 | 
					    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<net::X509Certificate>& cert) {
 | 
				
			||||||
 | 
					    auto rootCertStore = CertOpenStore(
 | 
				
			||||||
 | 
					        CERT_STORE_PROV_SYSTEM,
 | 
				
			||||||
 | 
					        0,
 | 
				
			||||||
 | 
					        NULL,
 | 
				
			||||||
 | 
					        CERT_SYSTEM_STORE_CURRENT_USER,
 | 
				
			||||||
 | 
					        L"Root");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (rootCertStore == NULL) {
 | 
				
			||||||
 | 
					        // could not resolve the certificate store, giving up
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    auto result = AddCertificateAndRefresh(rootCertStore, certContext, cert);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    CertCloseStore(rootCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return result;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Add the provided certificate to the Personal
 | 
				
			||||||
 | 
					// certificate store for the current user.
 | 
				
			||||||
 | 
					BOOL AddToPersonalStore(const PCCERT_CONTEXT certContext,
 | 
				
			||||||
 | 
					                        const scoped_refptr<net::X509Certificate>& 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;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    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<net::X509Certificate>& 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);
 | 
					    CertFreeCertificateContext(pCertContext);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue