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