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 8442fdbcd7e10ebdc686835ccdecab8fda4169ef..064ac606c91921ff8ba49284702a1887316d044d 100644 |
| --- a/net/base/x509_certificate_win.cc |
| +++ b/net/base/x509_certificate_win.cc |
| @@ -630,6 +630,46 @@ void X509Certificate::GetDNSNames(std::vector<std::string>* dns_names) const { |
| dns_names->push_back(subject_.common_name); |
| } |
| +X509Certificate::OSCertListHandle |
| +X509Certificate::CreateOSCertListHandle() const { |
| + // Create a temporary certificate store to hold |cert_handle_| and any |
|
wtc
2011/10/04 00:26:34
temporary => in-memory
|
| + // associated intermediates. The store will be referenced in the returned |
|
wtc
2011/10/04 00:26:34
intermediates => intermediate certificates
|
| + // OSCertListHandle, and will not be freed until the OSCertListHandle is |
| + // freed. |
| + OSCertListHandle cert_list = NULL; |
| + DWORD flags = CERT_STORE_DEFER_CLOSE_UNTIL_LAST_FREE_FLAG; |
| + HCERTSTORE store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, |
| + NULL, flags, NULL); |
| + |
| + if (store) { |
| + // NOTE: This preserves all of the properties of |cert_handle_| except for |
| + // CERT_KEY_PROV_HANDLE_PROP_ID and CERT_KEY_CONTEXT_PROP_ID - the two |
| + // properties that hold access to already-opened private keys. If a handle |
| + // has already been unlocked (eg: PIN prompt), then the first time that |
| + // the identity is used for client auth, it may prompt the user again. |
|
wtc
2011/10/04 00:26:34
Nit: identity => certificate handle?
Do we ever u
Ryan Sleevi
2011/10/04 03:38:07
Now that certificate prompting has been moved into
wtc
2011/10/04 18:00:51
You can keep this comment. I asked the question t
|
| + BOOL ok = CertAddCertificateContextToStore(store, cert_handle_, |
| + CERT_STORE_ADD_ALWAYS, |
| + &cert_list); |
| + if (ok && cert_list) { |
| + for (size_t i = 0; ok && i < intermediate_ca_certs_.size(); ++i) { |
| + ok = CertAddCertificateContextToStore(store, intermediate_ca_certs_[i], |
| + CERT_STORE_ADD_ALWAYS, NULL); |
| + } |
| + } |
| + |
| + // If |cert_list| points to a valid certificate, this will not actually |
| + // close and free |store| until |cert_list| is freed. |
| + CertCloseStore(store, 0); |
| + |
| + if (!ok) { |
| + FreeOSCertListHandle(cert_list); |
| + return NULL; |
| + } |
| + } |
| + |
| + return cert_list; |
| +} |
| + |
| int X509Certificate::VerifyInternal(const std::string& hostname, |
| int flags, |
| CertVerifyResult* verify_result) const { |
| @@ -696,21 +736,24 @@ int X509Certificate::VerifyInternal(const std::string& hostname, |
| if (TestRootCerts::HasInstance()) |
| chain_engine.reset(TestRootCerts::GetInstance()->GetChainEngine()); |
| + OSCertListHandle cert_list = CreateOSCertListHandle(); |
| 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( |
| chain_engine, |
| - cert_handle_, |
| + cert_list, |
| NULL, // current system time |
| - cert_handle_->hCertStore, |
| + cert_list->hCertStore, |
| &chain_para, |
| chain_flags, |
| NULL, // reserved |
| &chain_context)) { |
| + FreeOSCertListHandle(cert_list); |
|
wtc
2011/10/04 00:26:34
Do we have a scoped type for PCCERTCONTEXT? We co
|
| return MapSecurityError(GetLastError()); |
| } |
| + |
| if (chain_context->TrustStatus.dwErrorStatus & |
| CERT_TRUST_IS_NOT_VALID_FOR_USAGE) { |
| ev_policy_oid = NULL; |
| @@ -719,16 +762,19 @@ int X509Certificate::VerifyInternal(const std::string& hostname, |
| CertFreeCertificateChain(chain_context); |
| if (!CertGetCertificateChain( |
| chain_engine, |
| - cert_handle_, |
| + cert_list, |
| NULL, // current system time |
| - cert_handle_->hCertStore, |
| + cert_list->hCertStore, |
| &chain_para, |
| chain_flags, |
| NULL, // reserved |
| &chain_context)) { |
| + FreeOSCertListHandle(cert_list); |
| return MapSecurityError(GetLastError()); |
| } |
| } |
| + FreeOSCertListHandle(cert_list); |
| + |
| ScopedCertChainContext scoped_chain_context(chain_context); |
| GetCertChainInfo(chain_context, verify_result); |
| @@ -940,6 +986,11 @@ void X509Certificate::FreeOSCertHandle(OSCertHandle cert_handle) { |
| } |
| // static |
| +void X509Certificate::FreeOSCertListHandle(OSCertListHandle cert_list) { |
| + CertFreeCertificateContext(cert_list); |
| +} |
| + |
| +// static |
| SHA1Fingerprint X509Certificate::CalculateFingerprint( |
| OSCertHandle cert) { |
| DCHECK(NULL != cert->pbCertEncoded); |