1/* 2 * Copyright (c) 2005,2011,2014 Apple Inc. All Rights Reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23 24/* 25 * TrustSettings.h - class to manage trusted certs. 26 */ 27 28#ifndef _TRUST_SETTINGS_H_ 29#define _TRUST_SETTINGS_H_ 30 31#include "SecTrust.h" 32#include <security_keychain/StorageManager.h> 33#include <security_keychain/SecTrustSettings.h> 34 35/* 36 * Clarification of the bool arguments to our main constructor. 37 */ 38#define CREATE_YES true 39#define CREATE_NO false 40#define TRIM_YES true 41#define TRIM_NO false 42 43namespace Security 44{ 45 46namespace KeychainCore 47{ 48 49/* 50 * Additional values for the SecTrustSettingsDomain enum. 51 */ 52enum { 53 /* 54 * This indicates a TrustSettings that exists only in memory; it 55 * can't be written to disk. 56 */ 57 kSecTrustSettingsDomainMemory = 100 58}; 59 60class TrustSettings 61{ 62private: 63 TrustSettings(SecTrustSettingsDomain domain); 64 65public: 66 67 /* 68 * Normal constructor, from disk. 69 * If create is true, the absence of an on-disk TrustSettings file 70 * results in the creation of a new empty TrustSettings. If create is 71 * false and no on-disk TrustSettings exists, errSecItemNotFound is 72 * thrown. 73 * If trim is true, the components of the on-disk TrustSettings not 74 * needed for cert evaluation are discarded. This is for TrustSettings 75 * that will be cached in memory long-term. 76 */ 77 static OSStatus CreateTrustSettings( 78 SecTrustSettingsDomain domain, 79 bool create, 80 bool trim, 81 TrustSettings*& ts); 82 83 /* 84 * Create from external data, obtained by createExternal(). 85 * If externalData is NULL, we'll create an empty mTrustDict. 86 */ 87 static OSStatus CreateTrustSettings( 88 SecTrustSettingsDomain domain, 89 CFDataRef externalData, 90 TrustSettings*& ts); 91 92 ~TrustSettings(); 93 94 /* 95 * Evaluate specified cert. Returns true if we found a matching 96 * record for the cert. 97 */ 98 bool evaluateCert( 99 CFStringRef certHashStr, 100 const CSSM_OID *policyOID, /* optional */ 101 const char *policyString, /* optional */ 102 SecTrustSettingsKeyUsage keyUsage, /* optional */ 103 bool isRootCert, /* for checking default setting */ 104 CSSM_RETURN **allowedErrors, /* mallocd and RETURNED */ 105 uint32 *numAllowedErrors, /* RETURNED */ 106 SecTrustSettingsResult *resultType, /* RETURNED */ 107 bool *foundAnyEntry); /* RETURNED - there is SOME entry for 108 * this cert */ 109 110 /* 111 * Only certs with a SecTrustSettingsResult of kSecTrustSettingsResultTrustRoot 112 * or kSecTrustSettingsResultTrustAsRoot will be returned. 113 */ 114 void findQualifiedCerts( 115 StorageManager::KeychainList &keychains, 116 /* 117 * If findAll is true, all certs are returned and the subsequent 118 * qualifiers are ignored 119 */ 120 bool findAll, 121 /* if true, only return root (self-signed) certs */ 122 bool onlyRoots, 123 const CSSM_OID *policyOID, /* optional */ 124 const char *policyString, /* optional */ 125 SecTrustSettingsKeyUsage keyUsage, /* optional */ 126 CFMutableArrayRef certArray); /* certs appended here */ 127 128 /* 129 * Find all certs in specified keychain list which have entries in this trust record. 130 * Certs already in the array are not added. 131 */ 132 void findCerts( 133 StorageManager::KeychainList &keychains, 134 CFMutableArrayRef certArray); 135 136 /* 137 * Obtain trust settings for the specified cert. Returned settings array 138 * is in the public API form; caller must release. Returns NULL 139 * (does not throw) if the cert is not present in this TrustRecord. 140 * The certRef argument can be kSecTrustSettingsDefaultRootCertSetting. 141 */ 142 CFArrayRef copyTrustSettings( 143 SecCertificateRef certRef); 144 145 /* 146 * Obtain the mod date for the specified cert's trust settings. 147 * Returns NULL (does not throw) if the cert is not present in this 148 * TrustRecord. 149 * The certRef argument can be kSecTrustSettingsDefaultRootCertSetting. 150 */ 151 CFDateRef copyModDate( 152 SecCertificateRef certRef); 153 154 /* 155 * Modify cert's trust settings, or add a new cert to the record. 156 * The certRef argument can be kSecTrustSettingsDefaultRootCertSetting. 157 */ 158 void setTrustSettings( 159 SecCertificateRef certRef, 160 CFTypeRef trustSettingsDictOrArray); 161 162 /* 163 * Delete a certificate's trust settings. 164 * Throws errSecItemNotFound if there currently are no settings. 165 * The certRef argument can be kSecTrustSettingsDefaultRootCertSetting. 166 */ 167 void deleteTrustSettings( 168 SecCertificateRef certRef); 169 170 /* 171 * Flush property list data out to disk if dirty. 172 */ 173 void flushToDisk(); 174 175 /* 176 * Obtain external representation of TrustSettings data. 177 */ 178 CFDataRef createExternal(); 179 180private: 181 /* common code to init mPropList from raw data */ 182 void initFromData( 183 CFDataRef trustSettingsData); 184 185 /* 186 * Find a given cert's entry in mTrustDict. 187 * Returned dictionary is not refcounted. 188 */ 189 CFDictionaryRef findDictionaryForCert( 190 SecCertificateRef certRef); 191 192 /* 193 * Find entry in mTrustDict given cert hash string. 194 */ 195 CFDictionaryRef findDictionaryForCertHash( 196 CFStringRef certHashStr); 197 198 /* 199 * Validate incoming API-style trust settings, which may be NULL, a 200 * dictionary, or an array of dictionaries. We return a deep-copied, 201 * refcounted CFArray, in internal format, in any case as long as the 202 * incoming parameter is good. 203 */ 204 CFArrayRef validateApiTrustSettings( 205 CFTypeRef trustSettingsDictOrArray, 206 Boolean isSelfSigned); 207 208 /* 209 * Validate an usage constraint array from disk as part of our mPropDict 210 * array. Returns true if OK, else returns false. 211 */ 212 bool validateTrustSettingsArray( 213 CFArrayRef trustSettings); 214 215 /* 216 * Obtain issuer and serial number for specified cert, both 217 * returned as CFDataRefs owned by caller. 218 */ 219 void copyIssuerAndSerial( 220 SecCertificateRef cert, 221 CFDataRef *issuer, /* optional, RETURNED */ 222 CFDataRef *serial); /* RETURNED */ 223 224 /* 225 * Validate mPropDict after it's read from disk. Allows subsequent use of 226 * mPropDict and mTrustDict to proceed with relative impunity. 227 * If trim is true, we remove fields in the per-cert dictionaries which 228 * are not needed for cert evaluation. We also release the top-level 229 * mPropList, which serves as a "this is trimmed" indicator if NULL. 230 */ 231 void validatePropList(bool trim); 232 233 /* fatal error abort */ 234 void abort( 235 const char *why, 236 OSStatus err); 237 238 /* the overall parsed TrustSettings - may be NULL if this is trimmed */ 239 CFMutableDictionaryRef mPropList; 240 241 /* and the main thing we work with, the dictionary of per-cert trust settings */ 242 CFMutableDictionaryRef mTrustDict; 243 244 /* version number of mPropDict */ 245 SInt32 mDictVersion; 246 247 SecTrustSettingsDomain mDomain; 248 bool mDirty; /* we've changed mPropDict since creation */ 249}; 250 251} /* end namespace KeychainCore */ 252 253} /* end namespace Security */ 254 255#endif /* _TRUST_SETTINGS_H_ */ 256 257