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

Side by Side Diff: net/cert/known_roots_mac.cc

Issue 2833623002: Extract IsKnownRoot() functionality for testing if a certificate is a (Closed)
Patch Set: remove another unused header Created 3 years, 8 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
« no previous file with comments | « net/cert/known_roots_mac.h ('k') | net/cert/known_roots_nss.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2017 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2017 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/cert/internal/system_trust_store.h" 5 #include "net/cert/known_roots_mac.h"
6 6
7 #if defined(USE_NSS_CERTS)
8 #include <cert.h>
9 #include <pk11pub.h>
10 #elif defined(OS_MACOSX) && !defined(OS_IOS)
11 #include <Security/Security.h> 7 #include <Security/Security.h>
12 #endif
13 8
14 #include "base/memory/ptr_util.h" 9 #include <set>
15 #include "net/cert/internal/trust_store_collection.h"
16 #include "net/cert/internal/trust_store_in_memory.h"
17 10
18 #if defined(USE_NSS_CERTS) 11 #include "base/lazy_instance.h"
19 #include "crypto/nss_util.h" 12 #include "crypto/mac_security_services_lock.h"
20 #include "net/cert/internal/cert_issuer_source_nss.h" 13 #include "net/cert/x509_util_mac.h"
21 #include "net/cert/internal/trust_store_nss.h" 14
22 #include "net/cert/scoped_nss_types.h" 15 using base::ScopedCFTypeRef;
23 #elif defined(OS_MACOSX) && !defined(OS_IOS)
24 #include "net/cert/internal/trust_store_mac.h"
25 #endif
26 16
27 namespace net { 17 namespace net {
28 18
29 namespace { 19 namespace {
30 20
31 // Abstract implementation of SystemTrustStore to be used as a base class. 21 // Helper class for managing the set of OS X Known Roots. This is only safe
32 // Handles the addition of additional trust anchors. 22 // to initialize while the crypto::GetMacSecurityServicesLock() is held, due
33 class BaseSystemTrustStore : public SystemTrustStore { 23 // to calling into Security.framework functions; however, once initialized,
24 // it can be called at any time.
25 // In practice, due to lazy initialization, it's best to just always guard
26 // accesses with the lock.
27 class OSXKnownRootHelper {
34 public: 28 public:
35 BaseSystemTrustStore() { 29 bool IsKnownRoot(SecCertificateRef cert) {
36 trust_store_.AddTrustStore(&additional_trust_store_); 30 // If there are no known roots, then an API failure occurred. For safety,
31 // assume that all certificates are issued by known roots.
32 if (known_roots_.empty())
33 return true;
34
35 SHA256HashValue hash = x509_util::CalculateFingerprint256(cert);
36 return known_roots_.find(hash) != known_roots_.end();
37 } 37 }
38 38
39 void AddTrustAnchor(const scoped_refptr<TrustAnchor>& trust_anchor) override { 39 private:
40 additional_trust_store_.AddTrustAnchor(trust_anchor); 40 friend struct base::LazyInstanceTraitsBase<OSXKnownRootHelper>;
41
42 OSXKnownRootHelper() {
43 crypto::GetMacSecurityServicesLock().AssertAcquired();
44
45 CFArrayRef cert_array = NULL;
46 OSStatus rv = SecTrustSettingsCopyCertificates(
47 kSecTrustSettingsDomainSystem, &cert_array);
48 if (rv != noErr) {
49 LOG(ERROR) << "Unable to determine trusted roots; assuming all roots are "
50 << "trusted! Error " << rv;
51 return;
52 }
53 base::ScopedCFTypeRef<CFArrayRef> scoped_array(cert_array);
54 for (CFIndex i = 0, size = CFArrayGetCount(cert_array); i < size; ++i) {
55 SecCertificateRef cert = reinterpret_cast<SecCertificateRef>(
56 const_cast<void*>(CFArrayGetValueAtIndex(cert_array, i)));
57 known_roots_.insert(x509_util::CalculateFingerprint256(cert));
58 }
41 } 59 }
42 60
43 TrustStore* GetTrustStore() override { return &trust_store_; } 61 ~OSXKnownRootHelper() {}
44 62
45 CertIssuerSource* GetCertIssuerSource() override { return nullptr; } 63 std::set<SHA256HashValue, SHA256HashValueLessThan> known_roots_;
64 };
46 65
47 bool IsAdditionalTrustAnchor( 66 base::LazyInstance<OSXKnownRootHelper>::Leaky g_known_roots =
48 const scoped_refptr<TrustAnchor>& trust_anchor) const override { 67 LAZY_INSTANCE_INITIALIZER;
49 return additional_trust_store_.Contains(trust_anchor.get());
50 }
51
52 protected:
53 TrustStoreCollection trust_store_;
54 TrustStoreInMemory additional_trust_store_;
55 };
56 68
57 } // namespace 69 } // namespace
58 70
59 #if defined(USE_NSS_CERTS) 71 bool IsKnownRoot(SecCertificateRef cert) {
60 namespace { 72 return g_known_roots.Get().IsKnownRoot(cert);
61
62 class SystemTrustStoreNSS : public BaseSystemTrustStore {
63 public:
64 explicit SystemTrustStoreNSS() : trust_store_nss_(trustSSL) {
65 trust_store_.AddTrustStore(&trust_store_nss_);
66 }
67
68 CertIssuerSource* GetCertIssuerSource() override {
69 return &cert_issuer_source_nss_;
70 }
71
72 bool UsesSystemTrustStore() const override { return true; }
73
74 // IsKnownRoot returns true if the given trust anchor is a standard one (as
75 // opposed to a user-installed root)
76 bool IsKnownRoot(
77 const scoped_refptr<TrustAnchor>& trust_anchor) const override {
78 // TODO(eroman): Based on how the TrustAnchors are created by this
79 // integration, there will always be an associated certificate. However this
80 // contradicts the API for TrustAnchor that states it is optional.
81 DCHECK(trust_anchor->cert());
82
83 // TODO(eroman): The overall approach of IsKnownRoot() is inefficient -- it
84 // requires searching for the trust anchor by DER in NSS, however path
85 // building already had a handle to it.
86 SECItem der_cert;
87 der_cert.data =
88 const_cast<uint8_t*>(trust_anchor->cert()->der_cert().UnsafeData());
89 der_cert.len = trust_anchor->cert()->der_cert().Length();
90 der_cert.type = siDERCertBuffer;
91 ScopedCERTCertificate nss_cert(
92 CERT_FindCertByDERCert(CERT_GetDefaultCertDB(), &der_cert));
93 if (!nss_cert)
94 return false;
95
96 return IsKnownRoot(nss_cert.get());
97 }
98
99 private:
100 // TODO(eroman): This function was copied verbatim from
101 // cert_verify_proc_nss.cc
102 //
103 // IsKnownRoot returns true if the given certificate is one that we believe
104 // is a standard (as opposed to user-installed) root.
105 bool IsKnownRoot(CERTCertificate* root) const {
106 if (!root || !root->slot)
107 return false;
108
109 // This magic name is taken from
110 // http://bonsai.mozilla.org/cvsblame.cgi?file=mozilla/security/nss/lib/ckfw /builtins/constants.c&rev=1.13&mark=86,89#79
111 return 0 == strcmp(PK11_GetSlotName(root->slot), "NSS Builtin Objects");
112 }
113
114 TrustStoreNSS trust_store_nss_;
115 CertIssuerSourceNSS cert_issuer_source_nss_;
116 };
117
118 } // namespace
119
120 std::unique_ptr<SystemTrustStore> CreateSslSystemTrustStore() {
121 return base::MakeUnique<SystemTrustStoreNSS>();
122 } 73 }
123 74
124 #elif defined(OS_MACOSX) && !defined(OS_IOS) 75 void InitializeKnownRoots() {
125 76 base::AutoLock lock(crypto::GetMacSecurityServicesLock());
126 class SystemTrustStoreMac : public BaseSystemTrustStore { 77 g_known_roots.Get();
127 public:
128 explicit SystemTrustStoreMac() : trust_store_mac_(kSecPolicyAppleSSL) {
129 trust_store_.AddTrustStore(&trust_store_mac_);
130 }
131
132 CertIssuerSource* GetCertIssuerSource() override {
133 // TODO(eroman): Should this return something?
134 return nullptr;
135 }
136
137 bool UsesSystemTrustStore() const override { return true; }
138
139 // IsKnownRoot returns true if the given trust anchor is a standard one (as
140 // opposed to a user-installed root)
141 bool IsKnownRoot(
142 const scoped_refptr<TrustAnchor>& trust_anchor) const override {
143 // TODO(eroman): Implement.
144 return false;
145 }
146
147 private:
148 TrustStoreMac trust_store_mac_;
149 };
150
151 std::unique_ptr<SystemTrustStore> CreateSslSystemTrustStore() {
152 return base::MakeUnique<SystemTrustStoreMac>();
153 } 78 }
154 #else
155
156 class DummySystemTrustStore : public BaseSystemTrustStore {
157 public:
158 bool UsesSystemTrustStore() const override { return false; }
159
160 bool IsKnownRoot(
161 const scoped_refptr<TrustAnchor>& trust_anchor) const override {
162 return false;
163 }
164 };
165
166 std::unique_ptr<SystemTrustStore> CreateSslSystemTrustStore() {
167 return base::MakeUnique<DummySystemTrustStore>();
168 }
169 #endif
170 79
171 } // namespace net 80 } // namespace net
OLDNEW
« no previous file with comments | « net/cert/known_roots_mac.h ('k') | net/cert/known_roots_nss.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698