Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(218)

Side by Side Diff: net/base/x509_certificate_win.cc

Issue 2944008: Refactor X509Certificate caching to cache the OS handle, rather than the X509Certificate (Closed)
Patch Set: Rebase to trunk after splitting out 4645001 Created 9 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/base/x509_certificate.h" 5 #include "net/base/x509_certificate.h"
6 6
7 #include "base/crypto/rsa_private_key.h" 7 #include "base/crypto/rsa_private_key.h"
8 #include "base/crypto/scoped_capi_types.h" 8 #include "base/crypto/scoped_capi_types.h"
9 #include "base/lazy_instance.h" 9 #include "base/lazy_instance.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 518 matching lines...) Expand 10 before | Expand all | Expand 10 after
529 system_time.wSecond = exploded.second; 529 system_time.wSecond = exploded.second;
530 system_time.wMilliseconds = exploded.millisecond; 530 system_time.wMilliseconds = exploded.millisecond;
531 531
532 PCCERT_CONTEXT cert_handle = 532 PCCERT_CONTEXT cert_handle =
533 CertCreateSelfSignCertificate(key->provider(), &subject_name, 533 CertCreateSelfSignCertificate(key->provider(), &subject_name,
534 CERT_CREATE_SELFSIGN_NO_KEY_INFO, 534 CERT_CREATE_SELFSIGN_NO_KEY_INFO,
535 NULL, &sign_algo, 0, &system_time, 0); 535 NULL, &sign_algo, 0, &system_time, 0);
536 DCHECK(cert_handle) << "Failed to create self-signed certificate: " 536 DCHECK(cert_handle) << "Failed to create self-signed certificate: "
537 << logging::GetLastSystemErrorCode(); 537 << logging::GetLastSystemErrorCode();
538 538
539 X509Certificate* cert = CreateFromHandle(cert_handle, 539 X509Certificate* cert = CreateFromHandle(cert_handle, OSCertHandles());
540 SOURCE_LONE_CERT_IMPORT,
541 OSCertHandles());
542 FreeOSCertHandle(cert_handle); 540 FreeOSCertHandle(cert_handle);
543 return cert; 541 return cert;
544 } 542 }
545 543
546 void X509Certificate::GetDNSNames(std::vector<std::string>* dns_names) const { 544 void X509Certificate::GetDNSNames(std::vector<std::string>* dns_names) const {
547 dns_names->clear(); 545 dns_names->clear();
548 if (cert_handle_) { 546 if (cert_handle_) {
549 scoped_ptr_malloc<CERT_ALT_NAME_INFO> alt_name_info; 547 scoped_ptr_malloc<CERT_ALT_NAME_INFO> alt_name_info;
550 GetCertSubjectAltName(cert_handle_, &alt_name_info); 548 GetCertSubjectAltName(cert_handle_, &alt_name_info);
551 CERT_ALT_NAME_INFO* alt_name = alt_name_info.get(); 549 CERT_ALT_NAME_INFO* alt_name = alt_name_info.get();
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
587 }; 585 };
588 586
589 static base::LazyInstance<GlobalCertStore> g_cert_store( 587 static base::LazyInstance<GlobalCertStore> g_cert_store(
590 base::LINKER_INITIALIZED); 588 base::LINKER_INITIALIZED);
591 589
592 // static 590 // static
593 HCERTSTORE X509Certificate::cert_store() { 591 HCERTSTORE X509Certificate::cert_store() {
594 return g_cert_store.Get().cert_store(); 592 return g_cert_store.Get().cert_store();
595 } 593 }
596 594
595 X509Certificate::OSCertListHandle
596 X509Certificate::CreateOSCertListHandle() const {
597 // Create a temporary certificate store to hold |cert_handle_| and any
598 // associated intermediates. The store will be referenced in the returned
599 // OSCertListHandle, and will not be freed until the OSCertListHandle is
600 // freed.
601 OSCertListHandle cert_list = NULL;
602 DWORD flags = CERT_STORE_DEFER_CLOSE_UNTIL_LAST_FREE_FLAG;
603 HCERTSTORE store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0,
604 NULL, flags, NULL);
605
606 if (store) {
607 // NOTE: This preserves all of the properties of |cert_handle_| except for
608 // CERT_KEY_PROV_HANDLE_PROP_ID and CERT_KEY_CONTEXT_PROP_ID - the two
609 // properties that hold access to already-opened private keys. If a handle
610 // has already been unlocked (eg: PIN prompt), then the first time that
611 // the identity is used for client auth, it may prompt the user again.
612 BOOL ok = CertAddCertificateContextToStore(store, cert_handle_,
613 CERT_STORE_ADD_ALWAYS,
614 &cert_list);
615 if (ok && cert_list) {
616 for (size_t i = 0; ok && i < intermediate_ca_certs_.size(); ++i) {
617 ok = CertAddCertificateContextToStore(store, intermediate_ca_certs_[i],
618 CERT_STORE_ADD_ALWAYS, NULL);
619 }
620 }
621
622 // If |cert_list| points to a valid certificate, this will not actually
623 // close and free |store| until |cert_list| is freed.
624 CertCloseStore(store, 0);
625
626 if (!ok) {
627 FreeOSCertListHandle(cert_list);
628 return NULL;
629 }
630 }
631
632 return cert_list;
633 }
634
597 int X509Certificate::Verify(const std::string& hostname, 635 int X509Certificate::Verify(const std::string& hostname,
598 int flags, 636 int flags,
599 CertVerifyResult* verify_result) const { 637 CertVerifyResult* verify_result) const {
600 verify_result->Reset(); 638 verify_result->Reset();
601 if (!cert_handle_) 639 if (!cert_handle_)
602 return ERR_UNEXPECTED; 640 return ERR_UNEXPECTED;
603 641
604 // Build and validate certificate chain. 642 // Build and validate certificate chain.
605 643
606 CERT_CHAIN_PARA chain_para; 644 CERT_CHAIN_PARA chain_para;
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
655 // corresponds to HCCE_CURRENT_USER and is is initialized as needed by 693 // corresponds to HCCE_CURRENT_USER and is is initialized as needed by
656 // crypt32. However, when testing, it is necessary to create a new 694 // crypt32. However, when testing, it is necessary to create a new
657 // HCERTCHAINENGINE and use that instead. This is because each 695 // HCERTCHAINENGINE and use that instead. This is because each
658 // HCERTCHAINENGINE maintains a cache of information about certificates 696 // HCERTCHAINENGINE maintains a cache of information about certificates
659 // encountered, and each test run may modify the trust status of a 697 // encountered, and each test run may modify the trust status of a
660 // certificate. 698 // certificate.
661 ScopedHCERTCHAINENGINE chain_engine(NULL); 699 ScopedHCERTCHAINENGINE chain_engine(NULL);
662 if (TestRootCerts::HasInstance()) 700 if (TestRootCerts::HasInstance())
663 chain_engine.reset(TestRootCerts::GetInstance()->GetChainEngine()); 701 chain_engine.reset(TestRootCerts::GetInstance()->GetChainEngine());
664 702
703 OSCertListHandle cert_list = CreateOSCertListHandle();
665 PCCERT_CHAIN_CONTEXT chain_context; 704 PCCERT_CHAIN_CONTEXT chain_context;
666 // IE passes a non-NULL pTime argument that specifies the current system 705 // IE passes a non-NULL pTime argument that specifies the current system
667 // time. IE passes CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT as the 706 // time. IE passes CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT as the
668 // chain_flags argument. 707 // chain_flags argument.
669 if (!CertGetCertificateChain( 708 if (!CertGetCertificateChain(
670 chain_engine, 709 chain_engine,
671 cert_handle_, 710 cert_list,
672 NULL, // current system time 711 NULL, // current system time
673 cert_handle_->hCertStore, 712 cert_list->hCertStore,
674 &chain_para, 713 &chain_para,
675 chain_flags, 714 chain_flags,
676 NULL, // reserved 715 NULL, // reserved
677 &chain_context)) { 716 &chain_context)) {
717 FreeOSCertListHandle(cert_list);
678 return MapSecurityError(GetLastError()); 718 return MapSecurityError(GetLastError());
679 } 719 }
720 FreeOSCertListHandle(cert_list);
721
680 if (chain_context->TrustStatus.dwErrorStatus & 722 if (chain_context->TrustStatus.dwErrorStatus &
681 CERT_TRUST_IS_NOT_VALID_FOR_USAGE) { 723 CERT_TRUST_IS_NOT_VALID_FOR_USAGE) {
682 ev_policy_oid = NULL; 724 ev_policy_oid = NULL;
683 chain_para.RequestedIssuancePolicy.Usage.cUsageIdentifier = 0; 725 chain_para.RequestedIssuancePolicy.Usage.cUsageIdentifier = 0;
684 chain_para.RequestedIssuancePolicy.Usage.rgpszUsageIdentifier = NULL; 726 chain_para.RequestedIssuancePolicy.Usage.rgpszUsageIdentifier = NULL;
685 CertFreeCertificateChain(chain_context); 727 CertFreeCertificateChain(chain_context);
686 if (!CertGetCertificateChain( 728 if (!CertGetCertificateChain(
687 chain_engine, 729 chain_engine,
688 cert_handle_, 730 cert_handle_,
689 NULL, // current system time 731 NULL, // current system time
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after
904 OSCertHandle cert_handle) { 946 OSCertHandle cert_handle) {
905 return CertDuplicateCertificateContext(cert_handle); 947 return CertDuplicateCertificateContext(cert_handle);
906 } 948 }
907 949
908 // static 950 // static
909 void X509Certificate::FreeOSCertHandle(OSCertHandle cert_handle) { 951 void X509Certificate::FreeOSCertHandle(OSCertHandle cert_handle) {
910 CertFreeCertificateContext(cert_handle); 952 CertFreeCertificateContext(cert_handle);
911 } 953 }
912 954
913 // static 955 // static
956 void X509Certificate::FreeOSCertListHandle(OSCertListHandle cert_list) {
957 CertFreeCertificateContext(cert_list);
958 }
959
960 // static
914 SHA1Fingerprint X509Certificate::CalculateFingerprint( 961 SHA1Fingerprint X509Certificate::CalculateFingerprint(
915 OSCertHandle cert) { 962 OSCertHandle cert) {
916 DCHECK(NULL != cert->pbCertEncoded); 963 DCHECK(NULL != cert->pbCertEncoded);
917 DCHECK(0 != cert->cbCertEncoded); 964 DCHECK(0 != cert->cbCertEncoded);
918 965
919 BOOL rv; 966 BOOL rv;
920 SHA1Fingerprint sha1; 967 SHA1Fingerprint sha1;
921 DWORD sha1_size = sizeof(sha1.data); 968 DWORD sha1_size = sizeof(sha1.data);
922 rv = CryptHashCertificate(NULL, CALG_SHA1, 0, cert->pbCertEncoded, 969 rv = CryptHashCertificate(NULL, CALG_SHA1, 0, cert->pbCertEncoded,
923 cert->cbCertEncoded, sha1.data, &sha1_size); 970 cert->cbCertEncoded, sha1.data, &sha1_size);
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
962 &length)) 1009 &length))
963 return false; 1010 return false;
964 1011
965 return pickle->WriteData(reinterpret_cast<const char*>(&buffer[0]), 1012 return pickle->WriteData(reinterpret_cast<const char*>(&buffer[0]),
966 length); 1013 length);
967 } 1014 }
968 1015
969 1016
970 1017
971 } // namespace net 1018 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698