| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/lazy_instance.h" | 7 #include "base/lazy_instance.h" |
| 8 #include "base/logging.h" | 8 #include "base/logging.h" |
| 9 #include "base/memory/scoped_ptr.h" |
| 9 #include "base/pickle.h" | 10 #include "base/pickle.h" |
| 10 #include "base/sha1.h" | 11 #include "base/sha1.h" |
| 11 #include "base/string_tokenizer.h" | 12 #include "base/string_tokenizer.h" |
| 12 #include "base/string_util.h" | 13 #include "base/string_util.h" |
| 13 #include "base/utf_string_conversions.h" | 14 #include "base/utf_string_conversions.h" |
| 14 #include "crypto/rsa_private_key.h" | 15 #include "crypto/rsa_private_key.h" |
| 15 #include "crypto/scoped_capi_types.h" | 16 #include "crypto/scoped_capi_types.h" |
| 16 #include "net/base/asn1_util.h" | 17 #include "net/base/asn1_util.h" |
| 17 #include "net/base/cert_status_flags.h" | 18 #include "net/base/cert_status_flags.h" |
| 18 #include "net/base/cert_verify_result.h" | 19 #include "net/base/cert_verify_result.h" |
| 19 #include "net/base/ev_root_ca_metadata.h" | 20 #include "net/base/ev_root_ca_metadata.h" |
| 20 #include "net/base/net_errors.h" | 21 #include "net/base/net_errors.h" |
| 21 #include "net/base/scoped_cert_chain_context.h" | |
| 22 #include "net/base/test_root_certs.h" | 22 #include "net/base/test_root_certs.h" |
| 23 #include "net/base/x509_certificate_known_roots_win.h" | 23 #include "net/base/x509_certificate_known_roots_win.h" |
| 24 #include "net/base/x509_util_win.h" |
| 24 | 25 |
| 25 #pragma comment(lib, "crypt32.lib") | 26 #pragma comment(lib, "crypt32.lib") |
| 26 | 27 |
| 27 using base::Time; | 28 using base::Time; |
| 28 | 29 |
| 29 namespace net { | 30 namespace net { |
| 30 | 31 |
| 31 namespace { | 32 namespace { |
| 32 | 33 |
| 33 typedef crypto::ScopedCAPIHandle< | |
| 34 HCERTSTORE, | |
| 35 crypto::CAPIDestroyerWithFlags<HCERTSTORE, | |
| 36 CertCloseStore, 0> > ScopedHCERTSTORE; | |
| 37 | |
| 38 struct FreeChainEngineFunctor { | 34 struct FreeChainEngineFunctor { |
| 39 void operator()(HCERTCHAINENGINE engine) const { | 35 void operator()(HCERTCHAINENGINE engine) const { |
| 40 if (engine) | 36 if (engine) |
| 41 CertFreeCertificateChainEngine(engine); | 37 CertFreeCertificateChainEngine(engine); |
| 42 } | 38 } |
| 43 }; | 39 }; |
| 44 | 40 |
| 41 struct FreeCertContextFunctor { |
| 42 void operator()(PCCERT_CONTEXT context) const { |
| 43 if (context) |
| 44 CertFreeCertificateContext(context); |
| 45 } |
| 46 }; |
| 47 |
| 48 struct FreeCertChainContextFunctor { |
| 49 void operator()(PCCERT_CHAIN_CONTEXT chain_context) const { |
| 50 if (chain_context) |
| 51 CertFreeCertificateChain(chain_context); |
| 52 } |
| 53 }; |
| 54 |
| 45 typedef crypto::ScopedCAPIHandle<HCERTCHAINENGINE, FreeChainEngineFunctor> | 55 typedef crypto::ScopedCAPIHandle<HCERTCHAINENGINE, FreeChainEngineFunctor> |
| 46 ScopedHCERTCHAINENGINE; | 56 ScopedHCERTCHAINENGINE; |
| 47 | 57 |
| 58 typedef scoped_ptr_malloc<const CERT_CONTEXT, |
| 59 FreeCertContextFunctor> ScopedPCCERT_CONTEXT; |
| 60 |
| 61 typedef scoped_ptr_malloc<const CERT_CHAIN_CONTEXT, |
| 62 FreeCertChainContextFunctor> |
| 63 ScopedPCCERT_CHAIN_CONTEXT; |
| 64 |
| 48 //----------------------------------------------------------------------------- | 65 //----------------------------------------------------------------------------- |
| 49 | 66 |
| 50 // TODO(wtc): This is a copy of the MapSecurityError function in | 67 // TODO(wtc): This is a copy of the MapSecurityError function in |
| 51 // ssl_client_socket_win.cc. Another function that maps Windows error codes | 68 // ssl_client_socket_win.cc. Another function that maps Windows error codes |
| 52 // to our network error codes is WinInetUtil::OSErrorToNetError. We should | 69 // to our network error codes is WinInetUtil::OSErrorToNetError. We should |
| 53 // eliminate the code duplication. | 70 // eliminate the code duplication. |
| 54 int MapSecurityError(SECURITY_STATUS err) { | 71 int MapSecurityError(SECURITY_STATUS err) { |
| 55 // There are numerous security error codes, but these are the ones we thus | 72 // There are numerous security error codes, but these are the ones we thus |
| 56 // far find interesting. | 73 // far find interesting. |
| 57 switch (err) { | 74 switch (err) { |
| (...skipping 705 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 763 // corresponds to HCCE_CURRENT_USER and is is initialized as needed by | 780 // corresponds to HCCE_CURRENT_USER and is is initialized as needed by |
| 764 // crypt32. However, when testing, it is necessary to create a new | 781 // crypt32. However, when testing, it is necessary to create a new |
| 765 // HCERTCHAINENGINE and use that instead. This is because each | 782 // HCERTCHAINENGINE and use that instead. This is because each |
| 766 // HCERTCHAINENGINE maintains a cache of information about certificates | 783 // HCERTCHAINENGINE maintains a cache of information about certificates |
| 767 // encountered, and each test run may modify the trust status of a | 784 // encountered, and each test run may modify the trust status of a |
| 768 // certificate. | 785 // certificate. |
| 769 ScopedHCERTCHAINENGINE chain_engine(NULL); | 786 ScopedHCERTCHAINENGINE chain_engine(NULL); |
| 770 if (TestRootCerts::HasInstance()) | 787 if (TestRootCerts::HasInstance()) |
| 771 chain_engine.reset(TestRootCerts::GetInstance()->GetChainEngine()); | 788 chain_engine.reset(TestRootCerts::GetInstance()->GetChainEngine()); |
| 772 | 789 |
| 790 ScopedPCCERT_CONTEXT cert_list(x509_util::CreateOSCertChainForCert(this)); |
| 773 PCCERT_CHAIN_CONTEXT chain_context; | 791 PCCERT_CHAIN_CONTEXT chain_context; |
| 774 // IE passes a non-NULL pTime argument that specifies the current system | 792 // IE passes a non-NULL pTime argument that specifies the current system |
| 775 // time. IE passes CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT as the | 793 // time. IE passes CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT as the |
| 776 // chain_flags argument. | 794 // chain_flags argument. |
| 777 if (!CertGetCertificateChain( | 795 if (!CertGetCertificateChain( |
| 778 chain_engine, | 796 chain_engine, |
| 779 cert_handle_, | 797 cert_list.get(), |
| 780 NULL, // current system time | 798 NULL, // current system time |
| 781 cert_handle_->hCertStore, | 799 cert_list->hCertStore, |
| 782 &chain_para, | 800 &chain_para, |
| 783 chain_flags, | 801 chain_flags, |
| 784 NULL, // reserved | 802 NULL, // reserved |
| 785 &chain_context)) { | 803 &chain_context)) { |
| 786 return MapSecurityError(GetLastError()); | 804 return MapSecurityError(GetLastError()); |
| 787 } | 805 } |
| 806 |
| 788 if (chain_context->TrustStatus.dwErrorStatus & | 807 if (chain_context->TrustStatus.dwErrorStatus & |
| 789 CERT_TRUST_IS_NOT_VALID_FOR_USAGE) { | 808 CERT_TRUST_IS_NOT_VALID_FOR_USAGE) { |
| 790 ev_policy_oid = NULL; | 809 ev_policy_oid = NULL; |
| 791 chain_para.RequestedIssuancePolicy.Usage.cUsageIdentifier = 0; | 810 chain_para.RequestedIssuancePolicy.Usage.cUsageIdentifier = 0; |
| 792 chain_para.RequestedIssuancePolicy.Usage.rgpszUsageIdentifier = NULL; | 811 chain_para.RequestedIssuancePolicy.Usage.rgpszUsageIdentifier = NULL; |
| 793 CertFreeCertificateChain(chain_context); | 812 CertFreeCertificateChain(chain_context); |
| 794 if (!CertGetCertificateChain( | 813 if (!CertGetCertificateChain( |
| 795 chain_engine, | 814 chain_engine, |
| 796 cert_handle_, | 815 cert_list.get(), |
| 797 NULL, // current system time | 816 NULL, // current system time |
| 798 cert_handle_->hCertStore, | 817 cert_list->hCertStore, |
| 799 &chain_para, | 818 &chain_para, |
| 800 chain_flags, | 819 chain_flags, |
| 801 NULL, // reserved | 820 NULL, // reserved |
| 802 &chain_context)) { | 821 &chain_context)) { |
| 803 return MapSecurityError(GetLastError()); | 822 return MapSecurityError(GetLastError()); |
| 804 } | 823 } |
| 805 } | 824 } |
| 806 ScopedCertChainContext scoped_chain_context(chain_context); | 825 |
| 826 ScopedPCCERT_CHAIN_CONTEXT scoped_chain_context(chain_context); |
| 807 | 827 |
| 808 GetCertChainInfo(chain_context, verify_result); | 828 GetCertChainInfo(chain_context, verify_result); |
| 809 verify_result->cert_status |= MapCertChainErrorStatusToCertStatus( | 829 verify_result->cert_status |= MapCertChainErrorStatusToCertStatus( |
| 810 chain_context->TrustStatus.dwErrorStatus); | 830 chain_context->TrustStatus.dwErrorStatus); |
| 811 | 831 |
| 812 // Treat certificates signed using broken signature algorithms as invalid. | 832 // Treat certificates signed using broken signature algorithms as invalid. |
| 813 if (verify_result->has_md4) | 833 if (verify_result->has_md4) |
| 814 verify_result->cert_status |= CERT_STATUS_INVALID; | 834 verify_result->cert_status |= CERT_STATUS_INVALID; |
| 815 | 835 |
| 816 // Flag certificates signed using weak signature algorithms. | 836 // Flag certificates signed using weak signature algorithms. |
| (...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1061 if (!CertSerializeCertificateStoreElement(cert_handle, 0, &buffer[0], | 1081 if (!CertSerializeCertificateStoreElement(cert_handle, 0, &buffer[0], |
| 1062 &length)) { | 1082 &length)) { |
| 1063 return false; | 1083 return false; |
| 1064 } | 1084 } |
| 1065 | 1085 |
| 1066 return pickle->WriteData(reinterpret_cast<const char*>(&buffer[0]), | 1086 return pickle->WriteData(reinterpret_cast<const char*>(&buffer[0]), |
| 1067 length); | 1087 length); |
| 1068 } | 1088 } |
| 1069 | 1089 |
| 1070 } // namespace net | 1090 } // namespace net |
| OLD | NEW |