1 // 2 // CoreTrust.h 3 // CoreTrust 4 // 5 // Copyright © 2017-2020 Apple Inc. All rights reserved. 6 // 7 8 #ifndef _CORETRUST_EVALUATE_H_ 9 #define _CORETRUST_EVALUATE_H_ 10 11 #if !defined(EFI) || !EFI 12 #include <stddef.h> 13 #include <stdint.h> 14 #include <stdbool.h> 15 #else // EFI 16 // This requires $(SDKROOT)/usr/local/efi/include/Platform to be in your header 17 // search path. 18 #include <Apple/Common/Library/Include/EfiCompatibility.h> 19 #endif // EFI 20 21 #if EFI 22 #if defined(__cplusplus) 23 #define __BEGIN_DECLS extern "C" { 24 #define __END_DECLS } 25 #else 26 #define __BEGIN_DECLS 27 #define __END_DECLS 28 #endif 29 #else // !EFI 30 #include <sys/cdefs.h> 31 #endif // !EFI 32 33 __BEGIN_DECLS 34 35 #if !EFI 36 typedef uint8_t CT_uint8_t; 37 typedef uint32_t CT_uint32_t; 38 typedef uint64_t CT_uint64_t; 39 typedef size_t CT_size_t; 40 typedef int CT_int; 41 typedef bool CT_bool; 42 #else 43 typedef UINT8 CT_uint8_t; 44 typedef UINT32 CT_uint32_t; 45 typedef INT32 CT_int; 46 typedef UINT64 CT_uint64_t; 47 typedef size_t CT_size_t; 48 typedef BOOLEAN CT_bool; 49 #endif 50 51 typedef struct x509_octet_string { 52 const CT_uint8_t *data; 53 CT_size_t length; 54 } CTAsn1Item; 55 56 extern const CTAsn1Item CTOidItemAppleDeviceAttestationNonce; // 1.2.840.113635.100.8.2 57 extern const CTAsn1Item CTOidItemAppleDeviceAttestationHardwareProperties; // 1.2.840.113635.100.8.4 58 extern const CTAsn1Item CTOidItemAppleDeviceAttestationKeyUsageProperties; // 1.2.840.113635.100.8.5 59 extern const CTAsn1Item CTOidItemAppleDeviceAttestationDeviceOSInformation; // 1.2.840.113635.100.8.7 60 61 CT_int CTParseCertificateSet( 62 const CT_uint8_t *der, const CT_uint8_t *der_end, // Input: binary representation of concatenated DER-encoded certs 63 CTAsn1Item *certStorage, CT_size_t certStorageLen, // Output: An array of certStorageLen CTAsn1Items that will be populated with the 64 // CTAsn1Item for each parsed cert (in the same order as input) 65 CT_size_t *numParsedCerts); // Output: number of successfully parsed certs 66 67 CT_int CTParseExtensionValue( 68 const CT_uint8_t *certData, CT_size_t certLen, // Input: binary representation of DER-encoded cert 69 const CT_uint8_t *extensionOidData, CT_size_t extensionOidLen, // Input: extension OID to return value 70 const CT_uint8_t **extensionValueData, CT_size_t *extensionValueLen); // Output: points to the extension value 71 72 CT_int CTEvaluateSavageCerts( 73 const CT_uint8_t *certsData, CT_size_t certsLen, 74 const CT_uint8_t *rootKeyData, CT_size_t rootKeyLen, 75 const CT_uint8_t **leafKeyData, CT_size_t *leafKeyLen, 76 CT_bool *isProdCert); 77 78 CT_int CTEvaluateSavageCertsWithUID( 79 const CT_uint8_t *certsData, CT_size_t certsLen, 80 const CT_uint8_t *rootKeyData, CT_size_t rootKeyLen, 81 const CT_uint8_t **leafKeyData, CT_size_t *leafKeyLen, // Output: points to the leaf key data in the input certsData 82 CT_uint8_t *UIDData, CT_size_t UIDLen, // Output: a pre-allocated buffer of UIDLen 83 CT_bool *isProdCert); 84 85 CT_int CTEvaluateYonkersCerts( 86 const CT_uint8_t *certsData, CT_size_t certsLen, 87 const CT_uint8_t *rootKeyData, CT_size_t rootKeyLen, 88 const CT_uint8_t **leafKeyData, CT_size_t *leafKeyLen, // Output: points to the leaf key data in the input certsData 89 CT_uint8_t *UIDData, CT_size_t UIDLen, // Output: a pre-allocated buffer of UIDLen 90 CT_bool *isProdCert); 91 92 CT_int CTEvaluateAcrt( 93 const CT_uint8_t *certsData, CT_size_t certsLen, // Input: binary representation of at most 3 concatenated certs 94 // with leaf first (root may be omitted) 95 const CT_uint8_t **leafKeyData, CT_size_t *leafKeyLen); // Output: points to the leaf key data in the input certsData 96 97 CT_int CTEvaluateUcrt( 98 const CT_uint8_t *certsData, CT_size_t certsLen, // Input: binary representation of exactly 3 concatenated 99 // DER-encoded certs, with leaf first 100 const CT_uint8_t **leafKeyData, CT_size_t *leafKeyLen); // Output: points to the leaf key data in the input certsData) 101 102 CT_int CTEvaluateUcrtTestRoot( 103 const CT_uint8_t *certsData, CT_size_t certsLen, // Input: binary representation of exactly 3 concatenated 104 // DER-encoded certs, with leaf first 105 const CT_uint8_t *rootKeyData, CT_size_t rootKeyLen, // Input: Root public key, if not specified production root will be used 106 const CT_uint8_t **leafKeyData, CT_size_t *leafKeyLen); // Output: points to the leaf key data in the input certsData) 107 108 CT_int CTEvaluateBAASystem( 109 const CT_uint8_t *certsData, CT_size_t certsLen, // Input: binary representation of exactly 3 concatenated 110 // DER-encoded certs, with leaf first 111 const CT_uint8_t **leafKeyData, CT_size_t *leafKeyLen); // Output: points to the leaf key data in the input certsData 112 113 typedef struct baa_identity { 114 CT_uint32_t chipId; 115 CT_uint64_t ecid; 116 CT_bool productionStatus; 117 CT_bool securityMode; 118 CT_uint8_t securityDomain; 119 CTAsn1Item img4; 120 } CTBAAIdentity; 121 122 CT_int CTEvaluateBAASystemWithId( 123 const CT_uint8_t *certsData, CT_size_t certsLen, // Input: binary representation of exactly 3 concatenated 124 // DER-encoded certs, with leaf first 125 const CT_uint8_t **leafKeyData, CT_size_t *leafKeyLen, // Output: points to the leaf key data in the input certsData 126 CTBAAIdentity *identity); // Output from identity field in leaf certificate 127 128 CT_int CTEvaluateBAASystemTestRoot( 129 const CT_uint8_t *certsData, CT_size_t certsLen, // Input: binary representation of exactly 3 concatenated 130 // DER-encoded certs, with leaf first 131 const CT_uint8_t *rootKeyData, CT_size_t rootKeyLen, // Input: Root public key, if not specified production root will be used 132 const CT_uint8_t **leafKeyData, CT_size_t *leafKeyLen, // Output: points to the leaf key data in the input certsData 133 CTBAAIdentity *identity); // Output from identity field in leaf certificate 134 135 CT_int CTEvaluateBAAUser( 136 const CT_uint8_t *certsData, CT_size_t certsLen, // Input: binary representation of exactly 3 concatenated 137 // DER-encoded certs, with leaf first 138 const CT_uint8_t **leafKeyData, CT_size_t *leafKeyLen, // Output: points to the leaf key data in the input certsData 139 CTBAAIdentity *identity); // Output from identity field in leaf certificate 140 141 CT_int CTEvaluateBAAUserTestRoot( 142 const CT_uint8_t *certsData, CT_size_t certsLen, // Input: binary representation of exactly 3 concatenated 143 // DER-encoded certs, with leaf first 144 const CT_uint8_t *rootKeyData, CT_size_t rootKeyLen, // Input: Root public key, if not specified production root will be used 145 const CT_uint8_t **leafKeyData, CT_size_t *leafKeyLen, // Output: points to the leaf key data in the input certsData 146 CTBAAIdentity *identity); // Output from identity field in leaf certificate 147 148 CT_int CTEvaluateBAAAccessory( 149 const CT_uint8_t *certsData, CT_size_t certsLen, // Input: binary representation of 2-4 concatenated 150 // DER-encoded certs, with leaf first 151 const CT_uint8_t *rootKeyData, CT_size_t rootKeyLen, // Input: Root public key, if not specified 152 // production root will be used 153 const CT_uint8_t **leafKeyData, CT_size_t *leafKeyLen, // Output: points to the leaf key data in the input certsData 154 const CT_uint8_t **propertiesData, CT_size_t *propertiesLen); // Output: points to the Apple Accessory Properties extension value 155 156 CT_int CTEvaluateSatori( 157 const CT_uint8_t *certsData, CT_size_t certsLen, // Input: binary (DER) representation of 3 concatenated certs 158 // with leaf first 159 CT_bool allowTestRoot, // Input: whether to allow the Test Apple Roots 160 const CT_uint8_t **leafKeyData, CT_size_t *leafKeyLen); // Output: points to the leaf key data in the input certsData 161 162 CT_int CTEvaluatePragueSignatureCMS( 163 const CT_uint8_t *cmsData, CT_size_t cmsLen, // Input: CMS signature blob 164 const CT_uint8_t *detachedData, CT_size_t detachedDataLen, // Input: data signed by CMS blob 165 CT_bool allowTestRoot, // Input: permit use of test hierarchy 166 const CT_uint8_t **leafKeyData, CT_size_t *leafKeyLen); // Output: points to leaf key data in input cmsData 167 168 CT_int CTEvaluateKDLSignatureCMS( 169 const CT_uint8_t *cmsData, CT_size_t cmsLen, // Input: CMS signature blob 170 const CT_uint8_t *detachedData, CT_size_t detachedDataLen, // Input: data signed by CMS blob 171 CT_bool allowTestRoot, // Input: permit use of test hierarchy 172 const CT_uint8_t **leafKeyData, CT_size_t *leafKeyLen); // Output: points to leaf key data in input cmsData 173 174 typedef CT_uint64_t CoreTrustPolicyFlags; 175 enum { 176 CORETRUST_POLICY_BASIC = 0, 177 CORETRUST_POLICY_SAVAGE_DEV = 1 << 0, 178 CORETRUST_POLICY_SAVAGE_PROD = 1 << 1, 179 CORETRUST_POLICY_MFI_AUTHV3 = 1 << 2, 180 CORETRUST_POLICY_MAC_PLATFORM = 1 << 3, 181 CORETRUST_POLICY_MAC_DEVELOPER = 1 << 4, 182 CORETRUST_POLICY_DEVELOPER_ID = 1 << 5, 183 CORETRUST_POLICY_MAC_APP_STORE = 1 << 6, 184 CORETRUST_POLICY_IPHONE_DEVELOPER = 1 << 7, 185 CORETRUST_POLICY_IPHONE_APP_PROD = 1 << 8, 186 CORETRUST_POLICY_IPHONE_APP_DEV = 1 << 9, 187 CORETRUST_POLICY_IPHONE_VPN_PROD = 1 << 10, 188 CORETRUST_POLICY_IPHONE_VPN_DEV = 1 << 11, 189 CORETRUST_POLICY_TVOS_APP_PROD = 1 << 12, 190 CORETRUST_POLICY_TVOS_APP_DEV = 1 << 13, 191 CORETRUST_POLICY_TEST_FLIGHT_PROD = 1 << 14, 192 CORETRUST_POLICY_TEST_FLIGHT_DEV = 1 << 15, 193 CORETRUST_POLICY_IPHONE_DISTRIBUTION = 1 << 16, 194 CORETRUST_POLICY_MAC_SUBMISSION = 1 << 17, 195 CORETRUST_POLICY_YONKERS_DEV = 1 << 18, 196 CORETRUST_POLICY_YONKERS_PROD = 1 << 19, 197 CORETRUST_POLICY_MAC_PLATFORM_G2 = 1 << 20, 198 CORETRUST_POLICY_ACRT = 1 << 21, 199 CORETRUST_POLICY_SATORI = 1 << 22, 200 CORETRUST_POLICY_BAA = 1 << 23, 201 CORETRUST_POLICY_UCRT = 1 << 24, 202 CORETRUST_POLICY_PRAGUE = 1 << 25, 203 CORETRUST_POLICY_KDL = 1 << 26, 204 CORETRUST_POLICY_MFI_AUTHV2 = 1 << 27, 205 CORETRUST_POLICY_MFI_SW_AUTH_PROD = 1 << 28, 206 CORETRUST_POLICY_MFI_SW_AUTH_DEV = 1 << 29, 207 CORETRUST_POLICY_COMPONENT = 1 << 30, 208 CORETRUST_POLICY_IMG4 = 1ULL << 31, 209 CORETRUST_POLICY_SERVER_AUTH = 1ULL << 32, 210 CORETRUST_POLICY_SERVER_AUTH_STRING = 1ULL << 33, 211 CORETRUST_POLICY_MFI_AUTHV4_ACCESSORY = 1ULL << 34, 212 CORETRUST_POLICY_MFI_AUTHV4_ATTESTATION = 1ULL << 35, 213 CORETRUST_POLICY_MFI_AUTHV4_PROVISIONING = 1ULL << 36, 214 CORETRUST_POLICY_WWDR_CLOUD_MANAGED = 1ULL << 37, 215 CORETRUST_POLICY_HAVEN = 1ULL << 38, 216 CORETRUST_POLICY_PROVISIONING_PROFILE = 1ULL << 39, 217 }; 218 219 typedef CT_uint32_t CoreTrustDigestType; 220 enum { 221 CORETRUST_DIGEST_TYPE_SHA1 = 1, 222 CORETRUST_DIGEST_TYPE_SHA224 = 2, 223 CORETRUST_DIGEST_TYPE_SHA256 = 4, 224 CORETRUST_DIGEST_TYPE_SHA384 = 8, 225 CORETRUST_DIGEST_TYPE_SHA512 = 16 226 }; 227 228 CT_int CTEvaluateAMFICodeSignatureCMS( 229 const CT_uint8_t *cmsData, CT_size_t cmsLen, // Input: CMS blob 230 const CT_uint8_t *detachedData, CT_size_t detachedDataLen, // Input: data signed by CMS blob 231 CT_bool allow_test_hierarchy, // Input: permit use of test hierarchy 232 const CT_uint8_t **leafCert, CT_size_t *leafCertLen, // Output: signing certificate 233 CoreTrustPolicyFlags *policyFlags, // Output: policy met by signing certificate 234 CoreTrustDigestType *cmsDigestType, // Output: digest used to sign the CMS blob 235 CoreTrustDigestType *hashAgilityDigestType, // Output: highest strength digest type 236 // from hash agility attribute 237 const CT_uint8_t **digestData, CT_size_t *digestLen); // Output: pointer to hash agility value 238 // in CMS blob (with digest type above) 239 240 /* Returns non-zero if there's a standards-based problem with the CMS or certificates. 241 * Policy matching of the certificates is only reflected in the policyFlags output. Namely, if the only problem is that 242 * the certificates don't match a policy, the returned integer will be 0 (success) and the policyFlags will be 0 (no matching policies). 243 * Some notes about hash agility outputs: 244 * - hashAgilityDigestType is only non-zero for HashAgilityV2 245 * - If hashAgilityDigestType is non-zero, digestData/Len provides the digest value 246 * - If hashAgilityDigestType is zero, digestData/Len provides the content of the HashAgilityV1 attribute (if present) 247 * - If neither HashAgilityV1 nor HashAgilityV2 attributes are found, these outputs will all be NULL. 248 */ 249 250 int CTEvaluateAMFICodeSignatureCMSPubKey( 251 const CT_uint8_t *cmsData, CT_size_t cmsLen, // Input: CMS blob 252 const CT_uint8_t *detachedData, CT_size_t detachedDataLen, // Input: data signed by CMS blob 253 const CT_uint8_t *anchorPublicKey, CT_size_t anchorPublicKeyLen, // Input: anchor public key for self-signed cert 254 CoreTrustDigestType *cmsDigestType, // Output: digest used to sign the CMS blob 255 CoreTrustDigestType *hashAgilityDigestType, // Output: highest strength digest type 256 // from hash agility attribute 257 const CT_uint8_t **digestData, CT_size_t *digestLen); // Output: pointer to hash agility value 258 // in CMS blob (with digest type above) 259 260 CT_int CTParseAccessoryCerts( 261 const CT_uint8_t *certsData, CT_size_t certsLen, // Input: CMS or binary representation of DER-encoded certs 262 const CT_uint8_t **leafCertData, CT_size_t *leafCertLen, // Output: points to leaf cert data in input certsData 263 const CT_uint8_t **subCACertData, CT_size_t *subCACertLen, // Output: points to subCA cert(s) data in input 264 // certsData, if present. Is set to NULL if only 265 // one cert present in input. 266 CoreTrustPolicyFlags *flags); // Output: policy flags set by this leaf 267 268 269 CT_int CTEvaluateAccessoryCert( 270 const CT_uint8_t *leafCertData, CT_size_t leafCertLen, // Input: binary representation of DER-encoded leaf cert 271 const CT_uint8_t *subCACertData, CT_size_t subCACertLen, // Input: (optional) binary representation of DER-encoded subCA cert(s) 272 const CT_uint8_t *anchorCertData, CT_size_t anchorCertLen, // Input: binary representation of DER-encoded anchor cert 273 CoreTrustPolicyFlags policy, // Input: policy to use when evaluating chain 274 const CT_uint8_t **leafKeyData, CT_size_t *leafKeyLen, // Output: points to the leaf key data in the input leafCertData 275 const CT_uint8_t **extensionValueData, CT_size_t *extensionValueLen); // Output: points to the extension value in the input leafCertData 276 277 /* Which extension value is returned is based on which policy the cert was verified against: 278 * - For MFI AuthV3, this is the value of the extension with OID 1.2.840.113635.100.6.36 279 * - For SW Auth, this is the value of the extension with OID 1.2.840.113635.100.6.59.1 (GeneralCapabilities extension) 280 * - For Component certs, this si the value of the extension with OID 1.2.840.113635.100.11.1 (Component Type) 281 * - For MFi AuthV4, this is the value of the extension with OID 1.2.840.113635.100.6.71.1 (Apple Accessory Properties extension) 282 * 283 * The following CoreTrustPolicyFlags are accepted: 284 * - CORETRUST_POLICY_BASIC 285 * - CORETRUST_POLICY_MFI_AUTHV2 286 * - CORETRUST_POLICY_MFI_AUTHV3 287 * - CORETRUST_POLICY_MFI_SW_AUTH_DEV 288 * - CORETRUST_POLICY_MFI_SW_AUTH_PROD 289 * - CORETRUST_POLICY_COMPONENT 290 * - CORETRUST_POLICY_MFI_AUTHV4_ACCESSORY 291 * - CORETRUST_POLICY_MFI_AUTHV4_ATTESTATION 292 * - CORETRUST_POLICY_MFI_AUTHV4_PROVISIONING 293 */ 294 295 CT_int CTEvaluateAppleSSL( 296 const CT_uint8_t *certsData, CT_size_t certsLen, // Input: binary representation of up to 3 concatenated 297 // DER-encoded certificates, with leaf first 298 const CT_uint8_t *hostnameData, CT_size_t hostnameLen, // Input: The hostname of the TLS server being connected to 299 CT_uint64_t leafMarker, // Input: The last decimal of the marker OID for this project 300 // (e.g. 32 for 1.2.840.113635.100.6.27.32 301 CT_bool allowTestRoots); // Input: permit use of test hierarchy 302 303 CT_int CTEvaluateAppleSSLWithOptionalTemporalCheck( 304 const CT_uint8_t *certsData, CT_size_t certsLen, 305 const CT_uint8_t *hostnameData, CT_size_t hostnameLen, 306 CT_uint64_t leafMarker, 307 CT_bool allowTestRoots, 308 CT_bool checkTemporalValidity); 309 310 int CTEvaluateProvisioningProfile( 311 const CT_uint8_t *provisioningProfileData, CT_size_t provisioningProfileLen, 312 CT_bool allowTestRoots, 313 const CT_uint8_t **contentData, CT_size_t *contentLen); 314 315 __END_DECLS 316 317 #endif /* _CORETRUST_EVALUATE_H_ */ 318