OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |