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 |