• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2017 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef NET_CERT_INTERNAL_TRUST_STORE_MAC_H_
6 #define NET_CERT_INTERNAL_TRUST_STORE_MAC_H_
7 
8 #include <CoreFoundation/CoreFoundation.h>
9 
10 #include "base/gtest_prod_util.h"
11 #include "base/mac/scoped_cftyperef.h"
12 #include "net/base/net_export.h"
13 #include "net/cert/pki/trust_store.h"
14 
15 namespace net {
16 
17 // TrustStoreMac is an implementation of TrustStore which uses macOS keychain
18 // to find trust anchors for path building. Trust state is cached, so a single
19 // TrustStoreMac instance should be created and used for all verifications of a
20 // given policy.
21 // TrustStoreMac objects are threadsafe and methods may be called from multiple
22 // threads simultaneously. It is the owner's responsibility to ensure the
23 // TrustStoreMac object outlives any threads accessing it.
24 class NET_EXPORT TrustStoreMac : public TrustStore {
25  public:
26   // Bits representing different conditions encountered while evaluating
27   // the trustSettings returned by SecTrustSettingsCopyTrustSettings.
28   enum TrustDebugInfo {
29     // The trustSettings array was empty.
30     TRUST_SETTINGS_ARRAY_EMPTY = 1 << 0,
31 
32     // One of the trustSettings dictionaries was empty.
33     TRUST_SETTINGS_DICT_EMPTY = 1 << 1,
34 
35     // One of the trustSettings dictionaries contained an unknown key.
36     TRUST_SETTINGS_DICT_UNKNOWN_KEY = 1 << 2,
37 
38     // One of the trustSettings dictionaries contained a
39     // kSecTrustSettingsPolicy key.
40     TRUST_SETTINGS_DICT_CONTAINS_POLICY = 1 << 3,
41 
42     // One of the trustSettings dictionaries contained a
43     // kSecTrustSettingsPolicy key with a value that was not a SecPolicyRef.
44     TRUST_SETTINGS_DICT_INVALID_POLICY_TYPE = 1 << 4,
45 
46     // One of the trustSettings dictionaries contained a
47     // kSecTrustSettingsApplication key.
48     TRUST_SETTINGS_DICT_CONTAINS_APPLICATION = 1 << 5,
49 
50     // One of the trustSettings dictionaries contained a
51     // kSecTrustSettingsPolicyString key.
52     TRUST_SETTINGS_DICT_CONTAINS_POLICY_STRING = 1 << 6,
53 
54     // One of the trustSettings dictionaries contained a
55     // kSecTrustSettingsKeyUsage key.
56     TRUST_SETTINGS_DICT_CONTAINS_KEY_USAGE = 1 << 7,
57 
58     // One of the trustSettings dictionaries contained a
59     // kSecTrustSettingsResult key.
60     TRUST_SETTINGS_DICT_CONTAINS_RESULT = 1 << 8,
61 
62     // One of the trustSettings dictionaries contained a
63     // kSecTrustSettingsResult key with a value that was not a CFNumber or
64     // could not be represented by a signed int.
65     TRUST_SETTINGS_DICT_INVALID_RESULT_TYPE = 1 << 9,
66 
67     // One of the trustSettings dictionaries contained a
68     // kSecTrustSettingsAllowedError key.
69     TRUST_SETTINGS_DICT_CONTAINS_ALLOWED_ERROR = 1 << 10,
70 
71     // SecTrustSettingsCopyTrustSettings returned a value other than
72     // errSecSuccess or errSecItemNotFound.
73     COPY_TRUST_SETTINGS_ERROR = 1 << 11,
74   };
75 
76   // NOTE: When updating this enum, also update ParamToTrustImplType in
77   // system_trust_store.cc
78   enum class TrustImplType {
79     // Values 1 and 3 were used for implementation strategies that have since
80     // been removed.
81     kUnknown = 0,
82     kSimple = 2,
83     kDomainCacheFullCerts = 4,
84     kKeychainCacheFullCerts = 5,
85   };
86 
87   class ResultDebugData : public base::SupportsUserData::Data {
88    public:
89     static const ResultDebugData* Get(const base::SupportsUserData* debug_data);
90     static ResultDebugData* GetOrCreate(base::SupportsUserData* debug_data);
91 
92     void UpdateTrustDebugInfo(int trust_debug_info, TrustImplType impl_type);
93 
94     // base::SupportsUserData::Data implementation:
95     std::unique_ptr<Data> Clone() override;
96 
97     // Returns a bitfield of TrustDebugInfo flags. If multiple GetTrust calls
98     // were done with the same SupportsUserData object, this will return the
99     // union of all the TrustDebugInfo flags.
combined_trust_debug_info()100     int combined_trust_debug_info() const { return combined_trust_debug_info_; }
101 
102     // Returns an enum representing which trust implementation was used.
trust_impl()103     TrustImplType trust_impl() const { return trust_impl_; }
104 
105    private:
106     int combined_trust_debug_info_ = 0;
107 
108     TrustImplType trust_impl_ = TrustImplType::kUnknown;
109   };
110 
111   // Creates a TrustStoreMac which will find anchors that are trusted for
112   // |policy_oid|. For list of possible policy values, see:
113   // https://developer.apple.com/reference/security/1667150-certificate_key_and_trust_servic/1670151-standard_policies_for_specific_c?language=objc
114   // |impl| selects which internal implementation is used for checking trust
115   // settings.
116   TrustStoreMac(CFStringRef policy_oid, TrustImplType impl);
117 
118   TrustStoreMac(const TrustStoreMac&) = delete;
119   TrustStoreMac& operator=(const TrustStoreMac&) = delete;
120 
121   ~TrustStoreMac() override;
122 
123   // Initializes the trust cache, if it isn't already initialized.
124   void InitializeTrustCache() const;
125 
126   // TrustStore implementation:
127   void SyncGetIssuersOf(const ParsedCertificate* cert,
128                         ParsedCertificateList* issuers) override;
129   CertificateTrust GetTrust(const ParsedCertificate* cert,
130                             base::SupportsUserData* debug_data) override;
131 
132  private:
133   class TrustImpl;
134   class TrustImplDomainCacheFullCerts;
135   class TrustImplKeychainCacheFullCerts;
136   class TrustImplNoCache;
137 
138   // Finds certificates in the OS keychains whose Subject matches |name_data|.
139   // The result is an array of CRYPTO_BUFFERs containing the DER certificate
140   // data.
141   static std::vector<bssl::UniquePtr<CRYPTO_BUFFER>>
142   FindMatchingCertificatesForMacNormalizedSubject(CFDataRef name_data);
143 
144   // Returns the OS-normalized issuer of |cert|.
145   // macOS internally uses a normalized form of subject/issuer names for
146   // comparing, roughly similar to RFC3280's normalization scheme. The
147   // normalized form is used for any database lookups and comparisons.
148   static base::ScopedCFTypeRef<CFDataRef> GetMacNormalizedIssuer(
149       const ParsedCertificate* cert);
150 
151   std::unique_ptr<TrustImpl> trust_cache_;
152 };
153 
154 }  // namespace net
155 
156 #endif  // NET_CERT_INTERNAL_TRUST_STORE_MAC_H_
157