SecPolicy.c
1 /* 2 * Copyright (c) 2007-2017 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 * SecPolicy.c - Implementation of various X.509 certificate trust policies 26 */ 27 28 #include <Security/SecPolicyInternal.h> 29 #include <Security/SecPolicyPriv.h> 30 #include <AssertMacros.h> 31 #include <pthread.h> 32 #include <utilities/debugging.h> 33 #include <Security/SecInternal.h> 34 #include <CoreFoundation/CFDictionary.h> 35 #include <CoreFoundation/CFNumber.h> 36 #include <CoreFoundation/CFRuntime.h> 37 #include <CoreFoundation/CFString.h> 38 #include <CoreFoundation/CFTimeZone.h> 39 #include <Security/SecCertificateInternal.h> 40 #include <Security/SecCertificatePriv.h> 41 #include <Security/SecItem.h> 42 #include <libDER/oids.h> 43 #include <utilities/SecCFError.h> 44 #include <utilities/SecCFWrappers.h> 45 #include <utilities/array_size.h> 46 #include <ipc/securityd_client.h> 47 #include <os/variant_private.h> 48 #include <MobileGestalt.h> 49 #ifdef DARLING 50 #include <libDER/oidsPriv.h> 51 #endif 52 53 #include <utilities/SecInternalReleasePriv.h> 54 55 #include <Security/SecBase64.h> 56 57 #undef POLICYCHECKMACRO 58 #define POLICYCHECKMACRO(NAME, TRUSTRESULT, SUBTYPE, LEAFCHECK, PATHCHECK, LEAFONLY, CSSMERR, OSSTATUS) \ 59 const CFStringRef kSecPolicyCheck##NAME = CFSTR(#NAME); 60 #include "SecPolicyChecks.list" 61 62 #define SEC_CONST_DECL(k,v) const CFStringRef k = CFSTR(v); 63 64 /******************************************************** 65 ******************* Feature toggles ******************** 66 ********************************************************/ 67 /* Option for AnchorApple */ 68 SEC_CONST_DECL (kSecPolicyAppleAnchorIncludeTestRoots, "AnchorAppleTestRoots"); 69 70 /* options for kSecPolicyCheckLeafMarkersProdAndQA */ 71 SEC_CONST_DECL (kSecPolicyLeafMarkerProd, "ProdMarker"); 72 SEC_CONST_DECL (kSecPolicyLeafMarkerQA, "QAMarker"); 73 74 /* Revocation toggles */ 75 SEC_CONST_DECL (kSecPolicyCheckRevocationOCSP, "OCSP"); 76 SEC_CONST_DECL (kSecPolicyCheckRevocationCRL, "CRL"); 77 SEC_CONST_DECL (kSecPolicyCheckRevocationAny, "AnyRevocationMethod"); 78 79 /* Public policy oids. */ 80 #define POLICYMACRO(NAME, OID, ISPUBLIC, INTNAME, IN_NAME, IN_PROPERTIES, FUNCTION) \ 81 const CFStringRef kSecPolicyApple##NAME = CFSTR("1.2.840.113635.100.1."#OID); 82 #include "SecPolicy.list" 83 //Some naming exceptions 84 SEC_CONST_DECL(kSecPolicyMacAppStoreReceipt, "1.2.840.113635.100.1.19") 85 86 SEC_CONST_DECL (kSecPolicyOid, "SecPolicyOid"); 87 SEC_CONST_DECL (kSecPolicyName, "SecPolicyName"); 88 SEC_CONST_DECL (kSecPolicyClient, "SecPolicyClient"); 89 SEC_CONST_DECL (kSecPolicyRevocationFlags, "SecPolicyRevocationFlags"); 90 SEC_CONST_DECL (kSecPolicyTeamIdentifier, "SecPolicyTeamIdentifier"); 91 SEC_CONST_DECL (kSecPolicyContext, "SecPolicyContext"); 92 SEC_CONST_DECL (kSecPolicyPolicyName, "SecPolicyPolicyName"); 93 SEC_CONST_DECL (kSecPolicyIntermediateMarkerOid, "SecPolicyIntermediateMarkerOid"); 94 SEC_CONST_DECL (kSecPolicyLeafMarkerOid, "SecPolicyLeafMarkerOid"); 95 SEC_CONST_DECL (kSecPolicyRootDigest, "SecPolicyRootDigest"); 96 97 SEC_CONST_DECL (kSecPolicyKU_DigitalSignature, "CE_KU_DigitalSignature"); 98 SEC_CONST_DECL (kSecPolicyKU_NonRepudiation, "CE_KU_NonRepudiation"); 99 SEC_CONST_DECL (kSecPolicyKU_KeyEncipherment, "CE_KU_KeyEncipherment"); 100 SEC_CONST_DECL (kSecPolicyKU_DataEncipherment, "CE_KU_DataEncipherment"); 101 SEC_CONST_DECL (kSecPolicyKU_KeyAgreement, "CE_KU_KeyAgreement"); 102 SEC_CONST_DECL (kSecPolicyKU_KeyCertSign, "CE_KU_KeyCertSign"); 103 SEC_CONST_DECL (kSecPolicyKU_CRLSign, "CE_KU_CRLSign"); 104 SEC_CONST_DECL (kSecPolicyKU_EncipherOnly, "CE_KU_EncipherOnly"); 105 SEC_CONST_DECL (kSecPolicyKU_DecipherOnly, "CE_KU_DecipherOnly"); 106 107 /* Internal policy names */ 108 #undef POLICYMACRO 109 #define __P_DO_DECLARE_(NAME, INTNAME) static CFStringRef kSecPolicyName##NAME = CFSTR(#INTNAME); 110 #define __P_DO_DECLARE_E(NAME, INTNAME) static CFStringRef kSecPolicyName##NAME = CFSTR(#INTNAME); 111 #define __P_DO_DECLARE_P(NAME, INTNAME) const CFStringRef kSecPolicyNameApple##NAME = CFSTR(#INTNAME); 112 #define __P_DO_DECLARE_I(NAME, INTNAME) const CFStringRef kSecPolicyName##NAME = CFSTR(#INTNAME); 113 #define POLICYMACRO(NAME, OID, ISPUBLIC, INTNAME, IN_NAME, IN_PROPERTIES, FUNCTION) \ 114 __P_DO_DECLARE_##ISPUBLIC(NAME, INTNAME) 115 #include "SecPolicy.list" 116 //Some naming exceptions 117 static CFStringRef kSecPolicyNameAppleIDSBag = CFSTR("IDSBag"); 118 119 /* External Policy Names 120 * These correspond to the names defined in CertificatePinning.plist 121 * in security_certificates */ 122 SEC_CONST_DECL (kSecPolicyNameSSLServer, "sslServer"); 123 SEC_CONST_DECL (kSecPolicyNameSSLClient, "sslClient"); 124 SEC_CONST_DECL (kSecPolicyNameEAPServer, "eapServer"); 125 SEC_CONST_DECL (kSecPolicyNameEAPClient, "eapClient"); 126 SEC_CONST_DECL (kSecPolicyNameIPSecServer, "ipsecServer"); 127 SEC_CONST_DECL (kSecPolicyNameIPSecClient, "ipsecClient"); 128 SEC_CONST_DECL (kSecPolicyNameAppleiCloudSetupService, "iCloudSetup"); 129 SEC_CONST_DECL (kSecPolicyNameAppleMMCSService, "MMCS"); 130 SEC_CONST_DECL (kSecPolicyNameAppleAST2Service, "AST2"); 131 SEC_CONST_DECL (kSecPolicyNameAppleEscrowProxyService, "Escrow"); 132 SEC_CONST_DECL (kSecPolicyNameAppleFMiPService, "FMiP"); 133 SEC_CONST_DECL (kSecPolicyNameAppleHomeKitService, "HomeKit"); 134 SEC_CONST_DECL (kSecPolicyNameAppleAIDCService, "AIDC"); 135 SEC_CONST_DECL (kSecPolicyNameAppleMapsService, "Maps"); 136 SEC_CONST_DECL (kSecPolicyNameAppleHealthProviderService, "HealthProvider"); 137 SEC_CONST_DECL (kSecPolicyNameAppleParsecService, "Parsec"); 138 SEC_CONST_DECL (kSecPolicyNameAppleAMPService, "AMP"); 139 SEC_CONST_DECL (kSecPolicyNameAppleSiriService, "Siri"); 140 SEC_CONST_DECL (kSecPolicyNameAppleHomeAppClipUploadService, "HomeAppClipUploadService"); 141 SEC_CONST_DECL (kSecPolicyNameAppleUpdatesService, "Updates"); 142 SEC_CONST_DECL (kSecPolicyNameApplePushCertPortal, "PushCertPortal"); 143 144 #define kSecPolicySHA256Size CC_SHA256_DIGEST_LENGTH 145 146 // MARK: - 147 // MARK: SecPolicy 148 /******************************************************** 149 ****************** SecPolicy object ******************** 150 ********************************************************/ 151 152 static void SecPolicyDestroy(CFTypeRef cf) { 153 SecPolicyRef policy = (SecPolicyRef) cf; 154 CFRelease(policy->_oid); 155 CFReleaseSafe(policy->_name); 156 CFRelease(policy->_options); 157 } 158 159 static Boolean SecPolicyCompare(CFTypeRef cf1, CFTypeRef cf2) { 160 SecPolicyRef policy1 = (SecPolicyRef) cf1; 161 SecPolicyRef policy2 = (SecPolicyRef) cf2; 162 if (policy1->_name && policy2->_name) { 163 return CFEqual(policy1->_oid, policy2->_oid) && 164 CFEqual(policy1->_name, policy2->_name) && 165 CFEqual(policy1->_options, policy2->_options); 166 } else { 167 return CFEqual(policy1->_oid, policy2->_oid) && 168 CFEqual(policy1->_options, policy2->_options); 169 } 170 } 171 172 static CFHashCode SecPolicyHash(CFTypeRef cf) { 173 SecPolicyRef policy = (SecPolicyRef) cf; 174 if (policy->_name) { 175 return CFHash(policy->_oid) + CFHash(policy->_name) + CFHash(policy->_options); 176 } else { 177 return CFHash(policy->_oid) + CFHash(policy->_options); 178 } 179 } 180 181 static CFStringRef SecPolicyCopyFormatDescription(CFTypeRef cf, CFDictionaryRef formatOptions) { 182 SecPolicyRef policy = (SecPolicyRef) cf; 183 CFMutableStringRef desc = CFStringCreateMutable(kCFAllocatorDefault, 0); 184 CFStringRef typeStr = CFCopyTypeIDDescription(CFGetTypeID(cf)); 185 CFStringAppendFormat(desc, NULL, 186 CFSTR("<%@: oid: %@ name: %@ options %@"), typeStr, 187 policy->_oid, (policy->_name) ? policy->_name : CFSTR(""), 188 policy->_options); 189 CFRelease(typeStr); 190 CFStringAppend(desc, CFSTR(" >")); 191 192 return desc; 193 } 194 195 /* SecPolicy API functions. */ 196 CFGiblisWithHashFor(SecPolicy); 197 198 /* AUDIT[securityd](done): 199 oid (ok) is a caller provided string, only its cf type has been checked. 200 options is a caller provided dictionary, only its cf type has been checked. 201 */ 202 SecPolicyRef SecPolicyCreate(CFStringRef oid, CFStringRef name, CFDictionaryRef options) { 203 SecPolicyRef result = NULL; 204 205 require(oid, errOut); 206 require(options, errOut); 207 require(result = 208 (SecPolicyRef)_CFRuntimeCreateInstance(kCFAllocatorDefault, 209 SecPolicyGetTypeID(), 210 sizeof(struct __SecPolicy) - sizeof(CFRuntimeBase), 0), errOut); 211 212 CFRetain(oid); 213 result->_oid = oid; 214 CFRetainSafe(name); 215 result->_name = name; 216 CFRetain(options); 217 result->_options = options; 218 219 errOut: 220 return result; 221 } 222 223 #if TARGET_OS_OSX 224 static void set_ku_from_properties(SecPolicyRef policy, CFDictionaryRef properties); 225 #endif 226 227 SecPolicyRef SecPolicyCreateWithProperties(CFTypeRef policyIdentifier, 228 CFDictionaryRef properties) { 229 // Creates a policy reference for a given policy object identifier. 230 // If policy-specific parameters can be supplied (e.g. hostname), 231 // attempt to obtain from input properties dictionary. 232 // Returns NULL if the given identifier is unsupported. 233 234 SecPolicyRef policy = NULL; 235 CFTypeRef name = NULL; 236 CFStringRef teamID = NULL; 237 Boolean client = false; 238 CFDictionaryRef context = NULL; 239 CFStringRef policyName = NULL, intermediateMarkerOid = NULL, leafMarkerOid = NULL; 240 CFDataRef rootDigest = NULL; 241 require(policyIdentifier && (CFStringGetTypeID() == CFGetTypeID(policyIdentifier)), errOut); 242 243 if (properties) { 244 name = CFDictionaryGetValue(properties, kSecPolicyName); 245 teamID = CFDictionaryGetValue(properties, kSecPolicyTeamIdentifier); 246 247 CFBooleanRef dictionaryClientValue; 248 client = (CFDictionaryGetValueIfPresent(properties, kSecPolicyClient, (const void **)&dictionaryClientValue) && 249 (dictionaryClientValue != NULL) && CFEqual(kCFBooleanTrue, dictionaryClientValue)); 250 context = CFDictionaryGetValue(properties, kSecPolicyContext); 251 policyName = CFDictionaryGetValue(properties, kSecPolicyPolicyName); 252 intermediateMarkerOid = CFDictionaryGetValue(properties, kSecPolicyIntermediateMarkerOid); 253 leafMarkerOid = CFDictionaryGetValue(properties, kSecPolicyLeafMarkerOid); 254 rootDigest = CFDictionaryGetValue(properties, kSecPolicyRootDigest); 255 } 256 257 /* only the EAP policy allows a non-string name */ 258 if (name && !isString(name) && !CFEqual(policyIdentifier, kSecPolicyAppleEAP)) { 259 secerror("policy \"%@\" requires a string value for the %@ key", policyIdentifier, kSecPolicyName); 260 goto errOut; 261 } 262 263 /* What follows are all the exceptional functions that do not match the macro below */ 264 if (CFEqual(policyIdentifier, kSecPolicyAppleSSL)) { 265 policy = SecPolicyCreateSSL(!client, name); 266 } else if (CFEqual(policyIdentifier, kSecPolicyAppleSMIME)) { 267 policy = SecPolicyCreateSMIME(kSecSignSMIMEUsage | kSecAnyEncryptSMIME, name); 268 } else if (CFEqual(policyIdentifier, kSecPolicyAppleEAP)) { 269 CFArrayRef array = NULL; 270 if (isString(name)) { 271 array = CFArrayCreate(kCFAllocatorDefault, (const void **)&name, 1, &kCFTypeArrayCallBacks); 272 } else if (isArray(name)) { 273 array = CFArrayCreateCopy(NULL, name); 274 } 275 policy = SecPolicyCreateEAP(!client, array); 276 CFReleaseSafe(array); 277 } else if (CFEqual(policyIdentifier, kSecPolicyAppleIPsec)) { 278 policy = SecPolicyCreateIPSec(!client, name); 279 } else if (CFEqual(policyIdentifier, kSecPolicyMacAppStoreReceipt)) { 280 policy = SecPolicyCreateMacAppStoreReceipt(); 281 } else if (CFEqual(policyIdentifier, kSecPolicyAppleRevocation)) { 282 policy = SecPolicyCreateRevocation(kSecRevocationUseAnyAvailableMethod); 283 } else if (CFEqual(policyIdentifier, kSecPolicyApplePassbookSigning)) { 284 policy = SecPolicyCreatePassbookCardSigner(name, teamID); 285 } else if (CFEqual(policyIdentifier, kSecPolicyAppleAST2DiagnosticsServerAuth)) { 286 if (name) { 287 policy = SecPolicyCreateAppleAST2Service(name, context); 288 } else { 289 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier); 290 } 291 } else if (CFEqual(policyIdentifier, kSecPolicyAppleEscrowProxyServerAuth)) { 292 if (name) { 293 policy = SecPolicyCreateAppleEscrowProxyService(name, context); 294 } else { 295 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier); 296 } 297 } else if (CFEqual(policyIdentifier, kSecPolicyAppleFMiPServerAuth)) { 298 if (name) { 299 policy = SecPolicyCreateAppleFMiPService(name, context); 300 } else { 301 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier); 302 } 303 } else if (CFEqual(policyIdentifier, kSecPolicyAppleMMCService)) { 304 if (name) { 305 policy = SecPolicyCreateAppleMMCSService(name, context); 306 } else { 307 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier); 308 } 309 } else if (CFEqual(policyIdentifier, kSecPolicyAppleGSService)) { 310 if (name) { 311 policy = SecPolicyCreateAppleGSService(name, context); 312 } else { 313 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier); 314 } 315 } else if (CFEqual(policyIdentifier, kSecPolicyApplePPQService)) { 316 if (name) { 317 policy = SecPolicyCreateApplePPQService(name, context); 318 } else { 319 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier); 320 } 321 } else if (CFEqual(policyIdentifier, kSecPolicyAppleGenericApplePinned)) { 322 if (policyName) { 323 policy = SecPolicyCreateApplePinned(policyName, intermediateMarkerOid, leafMarkerOid); 324 } else { 325 secerror("policy \"%@\" requires kSecPolicyPolicyName input", policyIdentifier); 326 } 327 } else if (CFEqual(policyIdentifier, kSecPolicyAppleGenericAppleSSLPinned)) { 328 if (policyName) { 329 policy = SecPolicyCreateAppleSSLPinned(policyName, name, intermediateMarkerOid, leafMarkerOid); 330 } else { 331 secerror("policy \"%@\" requires kSecPolicyPolicyName input", policyIdentifier); 332 } 333 } else if (CFEqual(policyIdentifier, kSecPolicyAppleIDSServiceContext)) { 334 if (name) { 335 policy = SecPolicyCreateAppleIDSServiceContext(name, context); 336 } else { 337 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier); 338 } 339 } else if (CFEqual(policyIdentifier, kSecPolicyApplePushService)) { 340 if (name) { 341 policy = SecPolicyCreateApplePushService(name, context); 342 } else { 343 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier); 344 } 345 } else if (CFEqual(policyIdentifier, kSecPolicyAppleUniqueDeviceIdentifierCertificate)) { 346 policy = SecPolicyCreateAppleUniqueDeviceCertificate(rootDigest); 347 } else if (CFEqual(policyIdentifier, kSecPolicyAppleiCloudSetupServerAuth)) { 348 if (name) { 349 policy = SecPolicyCreateAppleiCloudSetupService(name, context); 350 } else { 351 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier); 352 } 353 } else if (CFEqual(policyIdentifier, kSecPolicyAppleBasicAttestationSystem)) { 354 policy = SecPolicyCreateAppleBasicAttestationSystem(rootDigest); 355 } else if (CFEqual(policyIdentifier, kSecPolicyAppleBasicAttestationUser)) { 356 policy = SecPolicyCreateAppleBasicAttestationUser(rootDigest); 357 } else if (CFEqual(policyIdentifier, kSecPolicyAppleComponentCertificate)) { 358 policy = SecPolicyCreateAppleComponentCertificate(rootDigest); 359 } else if (CFEqual(policyIdentifier, kSecPolicyAppleAggregateMetricTransparency)) { 360 policy = SecPolicyCreateAggregateMetricTransparency(!client); 361 } else if (CFEqual(policyIdentifier, kSecPolicyAppleAggregateMetricEncryption)) { 362 policy = SecPolicyCreateAggregateMetricEncryption(!client); 363 } else if (CFEqual(policyIdentifier, kSecPolicyApplePayModelSigning)) { 364 policy = SecPolicyCreateApplePayModelSigning(true); 365 } 366 /* For a couple of common patterns we use the macro, but some of the 367 * policies are deprecated (or not yet available), so we need to ignore the warning. */ 368 #pragma clang diagnostic push 369 #pragma clang diagnostic ignored "-Wdeprecated-declarations" 370 #pragma clang diagnostic ignored "-Wunguarded-availability" 371 #define _P_OPTION_ 372 #define _P_OPTION_N name 373 #define _P_PROPERTIES_(NAME, IN_NAME, FUNCTION) 374 #define _P_PROPERTIES_Y(NAME, IN_NAME, FUNCTION) else if (CFEqual(policyIdentifier, kSecPolicyApple##NAME)) { \ 375 policy = SecPolicyCreate##FUNCTION(_P_OPTION_##IN_NAME); \ 376 } 377 #undef POLICYMACRO 378 #define POLICYMACRO(NAME, OID, ISPUBLIC, INTNAME, IN_NAME, IN_PROPERTIES, FUNCTION) \ 379 _P_PROPERTIES_##IN_PROPERTIES(NAME, IN_NAME, FUNCTION) 380 #include "SecPolicy.list" 381 else { 382 secerror("ERROR: policy \"%@\" is unsupported", policyIdentifier); 383 } 384 #pragma clang diagnostic pop // ignored "-Wdeprecated-declarations" 385 386 if (!policy) { 387 return NULL; 388 } 389 390 #if TARGET_OS_OSX 391 set_ku_from_properties(policy, properties); 392 #endif 393 394 if (policyName) { 395 SecPolicySetName(policy, policyName); 396 } 397 398 errOut: 399 return policy; 400 } 401 402 CFDictionaryRef SecPolicyCopyProperties(SecPolicyRef policyRef) { 403 // Builds and returns a dictionary which the caller must release. 404 405 #pragma clang diagnostic push 406 #pragma clang diagnostic ignored "-Wnonnull" 407 // After introducing nullability annotations, policyRef is supposed to be nonnull, suppress the warning 408 if (!policyRef) return NULL; 409 #pragma clang diagnostic pop 410 CFMutableDictionaryRef properties = CFDictionaryCreateMutable(NULL, 0, 411 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); 412 #pragma clang diagnostic push 413 #pragma clang diagnostic ignored "-Wnonnull" 414 // 'properties' is nonnull in reality suppress the warning 415 if (!properties) return NULL; 416 #pragma clang diagnostic pop 417 CFStringRef oid = (CFStringRef) CFRetain(policyRef->_oid); 418 CFTypeRef nameKey = NULL; 419 420 // Determine name key 421 if (policyRef->_options) { 422 if (CFDictionaryContainsKey(policyRef->_options, kSecPolicyCheckSSLHostname)) { 423 nameKey = kSecPolicyCheckSSLHostname; 424 } else if (CFDictionaryContainsKey(policyRef->_options, kSecPolicyCheckEAPTrustedServerNames)) { 425 nameKey = kSecPolicyCheckEAPTrustedServerNames; 426 } else if (CFDictionaryContainsKey(policyRef->_options, kSecPolicyCheckEmail)) { 427 nameKey = kSecPolicyCheckEmail; 428 } 429 } 430 431 // Set kSecPolicyOid 432 CFDictionarySetValue(properties, (const void *)kSecPolicyOid, 433 (const void *)oid); 434 435 // Set kSecPolicyName if we have one 436 if (nameKey && policyRef->_options) { 437 CFTypeRef name = (CFTypeRef) CFDictionaryGetValue(policyRef->_options, 438 nameKey); 439 if (name) { 440 CFDictionarySetValue(properties, (const void *)kSecPolicyName, 441 (const void *)name); 442 } 443 } 444 445 // Set kSecPolicyClient 446 CFStringRef policyName = (CFStringRef) CFRetainSafe(policyRef->_name); 447 if (policyName && (CFEqual(policyName, kSecPolicyNameSSLClient) || 448 CFEqual(policyName, kSecPolicyNameIPSecClient) || 449 CFEqual(policyName, kSecPolicyNameEAPClient))) { 450 CFDictionarySetValue(properties, (const void *)kSecPolicyClient, 451 (const void *)kCFBooleanTrue); 452 } 453 454 CFRelease(oid); 455 return properties; 456 } 457 458 static void SecPolicySetOid(SecPolicyRef policy, CFStringRef oid) { 459 if (!policy || !oid) return; 460 CFStringRef temp = policy->_oid; 461 CFRetain(oid); 462 policy->_oid = oid; 463 CFReleaseSafe(temp); 464 } 465 466 void SecPolicySetName(SecPolicyRef policy, CFStringRef policyName) { 467 if (!policy || !policyName) return; 468 CFStringRef temp = policy->_name; 469 CFRetain(policyName); 470 policy->_name= policyName; 471 CFReleaseSafe(temp); 472 } 473 474 CFStringRef SecPolicyGetOidString(SecPolicyRef policy) { 475 return policy->_oid; 476 } 477 478 CFStringRef SecPolicyGetName(SecPolicyRef policy) { 479 return policy->_name; 480 } 481 482 CFDictionaryRef SecPolicyGetOptions(SecPolicyRef policy) { 483 return policy->_options; 484 } 485 486 void SecPolicySetOptionsValue(SecPolicyRef policy, CFStringRef key, CFTypeRef value) { 487 if (!policy || !key) return; 488 CFMutableDictionaryRef options = (CFMutableDictionaryRef) policy->_options; 489 if (!options) { 490 options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, 491 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); 492 if (!options) return; 493 policy->_options = options; 494 } 495 CFDictionarySetValue(options, key, value); 496 } 497 498 /* Local forward declaration */ 499 static void set_ssl_ekus(CFMutableDictionaryRef options, bool server); 500 501 #if TARGET_OS_IPHONE 502 // this is declared as NA for iPhone in SecPolicy.h, so declare here 503 OSStatus SecPolicySetProperties(SecPolicyRef policyRef, CFDictionaryRef properties); 504 #endif 505 506 OSStatus SecPolicySetProperties(SecPolicyRef policyRef, CFDictionaryRef properties) { 507 // Set policy options based on the provided dictionary keys. 508 509 if (!(policyRef && properties && (CFDictionaryGetTypeID() == CFGetTypeID(properties)))) { 510 return errSecParam; 511 } 512 CFStringRef oid = (CFStringRef) CFRetain(policyRef->_oid); 513 OSStatus result = errSecSuccess; 514 515 // kSecPolicyName 516 CFTypeRef name = NULL; 517 if (CFDictionaryGetValueIfPresent(properties, (const void *)kSecPolicyName, 518 (const void **)&name) && name) { 519 CFTypeID typeID = CFGetTypeID(name); 520 if (CFEqual(oid, kSecPolicyAppleSSL) || 521 CFEqual(oid, kSecPolicyAppleIPsec)) { 522 if (CFStringGetTypeID() == typeID) { 523 SecPolicySetOptionsValue(policyRef, kSecPolicyCheckSSLHostname, name); 524 } 525 else result = errSecParam; 526 } 527 else if (CFEqual(oid, kSecPolicyAppleEAP)) { 528 if ((CFStringGetTypeID() == typeID) || 529 (CFArrayGetTypeID() == typeID)) { 530 SecPolicySetOptionsValue(policyRef, kSecPolicyCheckEAPTrustedServerNames, name); 531 } 532 else result = errSecParam; 533 } 534 else if (CFEqual(oid, kSecPolicyAppleSMIME)) { 535 if (CFStringGetTypeID() == typeID) { 536 SecPolicySetOptionsValue(policyRef, kSecPolicyCheckEmail, name); 537 } 538 else result = errSecParam; 539 } 540 } 541 542 // kSecPolicyClient 543 CFTypeRef client = NULL; 544 if (CFDictionaryGetValueIfPresent(properties, (const void *)kSecPolicyClient, 545 (const void **)&client) && client) { 546 if (!(CFBooleanGetTypeID() == CFGetTypeID(client))) { 547 result = errSecParam; 548 } 549 else if (CFEqual(client, kCFBooleanTrue)) { 550 if (CFEqual(oid, kSecPolicyAppleSSL)) { 551 SecPolicySetName(policyRef, kSecPolicyNameSSLClient); 552 /* Set EKU checks for clients */ 553 CFMutableDictionaryRef newOptions = CFDictionaryCreateMutableCopy(NULL, 0, policyRef->_options); 554 set_ssl_ekus(newOptions, false); 555 CFReleaseSafe(policyRef->_options); 556 policyRef->_options = newOptions; 557 } 558 else if (CFEqual(oid, kSecPolicyAppleIPsec)) { 559 SecPolicySetName(policyRef, kSecPolicyNameIPSecClient); 560 } 561 else if (CFEqual(oid, kSecPolicyNameEAPServer)) { 562 SecPolicySetName(policyRef, kSecPolicyNameEAPClient); 563 /* Set EKU checks for clients */ 564 CFMutableDictionaryRef newOptions = CFDictionaryCreateMutableCopy(NULL, 0, policyRef->_options); 565 set_ssl_ekus(newOptions, false); 566 CFReleaseSafe(policyRef->_options); 567 policyRef->_options = newOptions; 568 } 569 } 570 else { 571 if (CFEqual(oid, kSecPolicyAppleSSL)) { 572 SecPolicySetName(policyRef, kSecPolicyNameSSLServer); 573 /* Set EKU checks for servers */ 574 CFMutableDictionaryRef newOptions = CFDictionaryCreateMutableCopy(NULL, 0, policyRef->_options); 575 set_ssl_ekus(newOptions, true); 576 CFReleaseSafe(policyRef->_options); 577 policyRef->_options = newOptions; 578 } 579 else if (CFEqual(oid, kSecPolicyAppleIPsec)) { 580 SecPolicySetName(policyRef, kSecPolicyNameIPSecServer); 581 } 582 else if (CFEqual(oid, kSecPolicyAppleEAP)) { 583 SecPolicySetName(policyRef, kSecPolicyNameEAPServer); 584 /* Set EKU checks for servers */ 585 CFMutableDictionaryRef newOptions = CFDictionaryCreateMutableCopy(NULL, 0, policyRef->_options); 586 set_ssl_ekus(newOptions, true); 587 CFReleaseSafe(policyRef->_options); 588 policyRef->_options = newOptions; 589 } 590 } 591 } 592 593 #if TARGET_OS_OSX 594 set_ku_from_properties(policyRef, properties); 595 #endif 596 CFRelease(oid); 597 return result; 598 } 599 600 static xpc_object_t copy_xpc_policy_object(SecPolicyRef policy); 601 static bool append_policy_to_xpc_array(SecPolicyRef policy, xpc_object_t xpc_policies); 602 extern xpc_object_t copy_xpc_policies_array(CFArrayRef policies); 603 extern OSStatus validate_array_of_items(CFArrayRef array, CFStringRef arrayItemType, CFTypeID itemTypeID, bool required); 604 605 static xpc_object_t copy_xpc_policy_object(SecPolicyRef policy) { 606 xpc_object_t xpc_policy = NULL; 607 xpc_object_t data[2] = { NULL, NULL }; 608 if (policy->_oid && (CFGetTypeID(policy->_oid) == CFStringGetTypeID()) && 609 policy->_name && (CFGetTypeID(policy->_name) == CFStringGetTypeID())) { 610 /* These should really be different elements of the xpc array. But 611 * SecPolicyCreateWithXPCObject previously checked the size via ==, which prevents 612 * us from appending new information while maintaining backward compatibility. 613 * Doing this makes the builders happy. */ 614 CFMutableStringRef oidAndName = NULL; 615 oidAndName = CFStringCreateMutableCopy(NULL, 0, policy->_oid); 616 if (oidAndName) { 617 CFStringAppend(oidAndName, CFSTR("++")); 618 CFStringAppend(oidAndName, policy->_name); 619 data[0] = _CFXPCCreateXPCObjectFromCFObject(oidAndName); 620 CFReleaseNull(oidAndName); 621 } else { 622 data[0] = _CFXPCCreateXPCObjectFromCFObject(policy->_oid); 623 } 624 } else if (policy->_oid && (CFGetTypeID(policy->_oid) == CFStringGetTypeID())) { 625 data[0] = _CFXPCCreateXPCObjectFromCFObject(policy->_oid); 626 } else { 627 secerror("policy 0x%lX has no _oid", (uintptr_t)policy); 628 } 629 if (policy->_options && (CFGetTypeID(policy->_options) == CFDictionaryGetTypeID())) { 630 data[1] = _CFXPCCreateXPCObjectFromCFObject(policy->_options); 631 } else { 632 secerror("policy 0x%lX has no _options", (uintptr_t)policy); 633 } 634 xpc_policy = xpc_array_create(data, array_size(data)); 635 if (data[0]) xpc_release(data[0]); 636 if (data[1]) xpc_release(data[1]); 637 return xpc_policy; 638 } 639 640 static bool append_policy_to_xpc_array(SecPolicyRef policy, xpc_object_t xpc_policies) { 641 if (!policy) { 642 return true; // NOOP 643 } 644 xpc_object_t xpc_policy = copy_xpc_policy_object(policy); 645 if (!xpc_policy) { 646 return false; 647 } 648 xpc_array_append_value(xpc_policies, xpc_policy); 649 xpc_release(xpc_policy); 650 return true; 651 } 652 653 xpc_object_t copy_xpc_policies_array(CFArrayRef policies) { 654 xpc_object_t xpc_policies = xpc_array_create(NULL, 0); 655 if (!xpc_policies) { 656 return NULL; 657 } 658 validate_array_of_items(policies, CFSTR("policy"), SecPolicyGetTypeID(), true); 659 CFIndex ix, count = CFArrayGetCount(policies); 660 for (ix = 0; ix < count; ++ix) { 661 SecPolicyRef policy = (SecPolicyRef) CFArrayGetValueAtIndex(policies, ix); 662 #if SECTRUST_VERBOSE_DEBUG 663 CFDictionaryRef props = SecPolicyCopyProperties(policy); 664 secerror("idx=%d of %d; policy=0x%lX properties=%@", (int)ix, (int)count, (uintptr_t)policy, props); 665 CFReleaseSafe(props); 666 #endif 667 if (!append_policy_to_xpc_array(policy, xpc_policies)) { 668 xpc_release(xpc_policies); 669 xpc_policies = NULL; 670 break; 671 } 672 } 673 return xpc_policies; 674 } 675 676 static xpc_object_t SecPolicyCopyXPCObject(SecPolicyRef policy, CFErrorRef *error) { 677 xpc_object_t xpc_policy = NULL; 678 xpc_object_t data[2] = {}; 679 CFMutableStringRef oidAndName = NULL; 680 oidAndName = CFStringCreateMutableCopy(NULL, 0, policy->_oid); 681 if (oidAndName) { 682 if (policy->_name) { 683 CFStringAppend(oidAndName, CFSTR("++")); 684 CFStringAppend(oidAndName, policy->_name); 685 } 686 687 require_action_quiet(data[0] = _CFXPCCreateXPCObjectFromCFObject(oidAndName), exit, 688 SecError(errSecParam, error, 689 CFSTR("failed to create xpc_object from policy oid and name"))); 690 } else { 691 require_action_quiet(data[0] = _CFXPCCreateXPCObjectFromCFObject(policy->_oid), exit, 692 SecError(errSecParam, error, CFSTR("failed to create xpc_object from policy oid"))); 693 } 694 require_action_quiet(data[1] = _CFXPCCreateXPCObjectFromCFObject(policy->_options), exit, 695 SecError(errSecParam, error, CFSTR("failed to create xpc_object from policy options"))); 696 require_action_quiet(xpc_policy = xpc_array_create(data, array_size(data)), exit, 697 SecError(errSecAllocate, error, CFSTR("failed to create xpc_array for policy"))); 698 699 exit: 700 if (data[0]) xpc_release(data[0]); 701 if (data[1]) xpc_release(data[1]); 702 CFReleaseNull(oidAndName); 703 return xpc_policy; 704 } 705 706 static bool SecPolicyAppendToXPCArray(SecPolicyRef policy, xpc_object_t policies, CFErrorRef *error) { 707 if (!policy) 708 return true; // NOOP 709 710 xpc_object_t xpc_policy = SecPolicyCopyXPCObject(policy, error); 711 if (!xpc_policy) 712 return false; 713 714 xpc_array_append_value(policies, xpc_policy); 715 xpc_release(xpc_policy); 716 return true; 717 } 718 719 xpc_object_t SecPolicyArrayCopyXPCArray(CFArrayRef policies, CFErrorRef *error) { 720 xpc_object_t xpc_policies; 721 require_action_quiet(xpc_policies = xpc_array_create(NULL, 0), exit, 722 SecError(errSecAllocate, error, CFSTR("failed to create xpc_array"))); 723 CFIndex ix, count = CFArrayGetCount(policies); 724 for (ix = 0; ix < count; ++ix) { 725 if (!SecPolicyAppendToXPCArray((SecPolicyRef)CFArrayGetValueAtIndex(policies, ix), xpc_policies, error)) { 726 xpc_release(xpc_policies); 727 return NULL; 728 } 729 } 730 exit: 731 return xpc_policies; 732 } 733 734 static OSStatus parseOidAndName(CFStringRef oidAndName, CFStringRef *oid, CFStringRef *name) { 735 OSStatus result = errSecSuccess; 736 CFStringRef partial = NULL; 737 738 CFRange delimiter = CFStringFind(oidAndName, CFSTR("++"), 0); 739 if (delimiter.length != 2) { 740 return errSecParam; 741 } 742 743 /* get first half: oid */ 744 partial = CFStringCreateWithSubstring(NULL, oidAndName, CFRangeMake(0, delimiter.location)); 745 if (oid) { *oid = CFRetainSafe(partial); } 746 CFReleaseNull(partial); 747 748 /* get second half: name */ 749 if (delimiter.location + 2 >= CFStringGetLength(oidAndName)) { 750 return errSecSuccess; // name is optional 751 } 752 CFRange nameRange = CFRangeMake(delimiter.location+2, 753 CFStringGetLength(oidAndName) - delimiter.location - 2); 754 partial = CFStringCreateWithSubstring(NULL, oidAndName, nameRange); 755 if (name) { *name = CFRetainSafe(partial); } 756 CFReleaseNull(partial); 757 return result; 758 } 759 760 static SecPolicyRef SecPolicyCreateWithXPCObject(xpc_object_t xpc_policy, CFErrorRef *error) { 761 SecPolicyRef policy = NULL; 762 CFTypeRef oidAndName = NULL; 763 CFStringRef oid = NULL; 764 CFStringRef name = NULL; 765 CFTypeRef options = NULL; 766 767 require_action_quiet(xpc_policy, exit, SecError(errSecParam, error, CFSTR("policy xpc value is NULL"))); 768 require_action_quiet(xpc_get_type(xpc_policy) == XPC_TYPE_ARRAY, exit, SecError(errSecDecode, error, CFSTR("policy xpc value is not an array"))); 769 require_action_quiet(xpc_array_get_count(xpc_policy) >= 2, exit, SecError(errSecDecode, error, CFSTR("policy xpc array count < 2"))); 770 oidAndName = _CFXPCCreateCFObjectFromXPCObject(xpc_array_get_value(xpc_policy, 0)); 771 require_action_quiet(isString(oidAndName), exit, 772 SecError(errSecParam, error, CFSTR("failed to convert xpc policy[0]=%@ to CFString"), oidAndName)); 773 options = _CFXPCCreateCFObjectFromXPCObject(xpc_array_get_value(xpc_policy, 1)); 774 require_action_quiet(isDictionary(options), exit, 775 SecError(errSecParam, error, CFSTR("failed to convert xpc policy[1]=%@ to CFDictionary"), options)); 776 require_noerr_action_quiet(parseOidAndName(oidAndName, &oid, &name), exit, 777 SecError(errSecParam, error, CFSTR("failed to convert combined %@ to name and oid"), oidAndName)); 778 require_action_quiet(policy = SecPolicyCreate(oid, name, options), exit, 779 SecError(errSecDecode, error, CFSTR("Failed to create policy"))); 780 781 exit: 782 CFReleaseSafe(oidAndName); 783 CFReleaseSafe(oid); 784 CFReleaseSafe(name); 785 CFReleaseSafe(options); 786 return policy; 787 } 788 789 CFArrayRef SecPolicyXPCArrayCopyArray(xpc_object_t xpc_policies, CFErrorRef *error) { 790 CFMutableArrayRef policies = NULL; 791 require_action_quiet(xpc_get_type(xpc_policies) == XPC_TYPE_ARRAY, exit, 792 SecError(errSecParam, error, CFSTR("policies xpc value is not an array"))); 793 size_t count = xpc_array_get_count(xpc_policies); 794 require_action_quiet(policies = CFArrayCreateMutable(kCFAllocatorDefault, count, &kCFTypeArrayCallBacks), exit, 795 SecError(errSecAllocate, error, CFSTR("failed to create CFArray of capacity %zu"), count)); 796 797 size_t ix; 798 for (ix = 0; ix < count; ++ix) { 799 SecPolicyRef policy = SecPolicyCreateWithXPCObject(xpc_array_get_value(xpc_policies, ix), error); 800 if (!policy) { 801 CFRelease(policies); 802 return NULL; 803 } 804 CFArraySetValueAtIndex(policies, ix, policy); 805 CFRelease(policy); 806 } 807 808 exit: 809 return policies; 810 811 } 812 813 static SEC_CONST_DECL (kSecPolicyOptions, "policyOptions"); 814 815 static SecPolicyRef SecPolicyCreateWithDictionary(CFDictionaryRef dict) { 816 SecPolicyRef policy = NULL; 817 CFStringRef oid = (CFStringRef)CFDictionaryGetValue(dict, kSecPolicyOid); 818 require_quiet(isString(oid), errOut); 819 CFDictionaryRef options = (CFDictionaryRef)CFDictionaryGetValue(dict, kSecPolicyOptions); 820 require_quiet(isDictionary(options), errOut); 821 CFStringRef name = (CFStringRef)CFDictionaryGetValue(dict, kSecPolicyPolicyName); 822 policy = SecPolicyCreate(oid, name, options); 823 errOut: 824 return policy; 825 } 826 827 static void deserializePolicy(const void *value, void *context) { 828 CFDictionaryRef policyDict = (CFDictionaryRef)value; 829 if (isDictionary(policyDict)) { 830 CFTypeRef deserializedPolicy = SecPolicyCreateWithDictionary(policyDict); 831 if (deserializedPolicy) { 832 CFArrayAppendValue((CFMutableArrayRef)context, deserializedPolicy); 833 CFRelease(deserializedPolicy); 834 } 835 } 836 } 837 838 CFArrayRef SecPolicyArrayCreateDeserialized(CFArrayRef serializedPolicies) { 839 CFMutableArrayRef result = NULL; 840 require_quiet(isArray(serializedPolicies), errOut); 841 CFIndex count = CFArrayGetCount(serializedPolicies); 842 result = CFArrayCreateMutable(kCFAllocatorDefault, count, &kCFTypeArrayCallBacks); 843 CFRange all_policies = { 0, count }; 844 CFArrayApplyFunction(serializedPolicies, all_policies, deserializePolicy, result); 845 errOut: 846 return result; 847 } 848 849 static CFDictionaryRef SecPolicyCreateDictionary(SecPolicyRef policy) { 850 CFMutableDictionaryRef dict = NULL; 851 dict = CFDictionaryCreateMutable(NULL, 3, &kCFTypeDictionaryKeyCallBacks, 852 &kCFTypeDictionaryValueCallBacks); 853 CFDictionaryAddValue(dict, kSecPolicyOid, policy->_oid); 854 CFDictionaryAddValue(dict, kSecPolicyOptions, policy->_options); 855 if (policy->_name) { 856 CFDictionaryAddValue(dict, kSecPolicyPolicyName, policy->_name); 857 } 858 return dict; 859 } 860 861 static void serializePolicy(const void *value, void *context) { 862 SecPolicyRef policy = (SecPolicyRef)value; 863 if (policy && SecPolicyGetTypeID() == CFGetTypeID(policy)) { 864 CFDictionaryRef serializedPolicy = SecPolicyCreateDictionary(policy); 865 if (serializedPolicy) { 866 CFArrayAppendValue((CFMutableArrayRef)context, serializedPolicy); 867 CFRelease(serializedPolicy); 868 } 869 } 870 } 871 872 CFArrayRef SecPolicyArrayCreateSerialized(CFArrayRef policies) { 873 CFMutableArrayRef result = NULL; 874 require_quiet(isArray(policies), errOut); 875 CFIndex count = CFArrayGetCount(policies); 876 result = CFArrayCreateMutable(NULL, count, &kCFTypeArrayCallBacks); 877 CFRange all_policies = { 0, count}; 878 CFArrayApplyFunction(policies, all_policies, serializePolicy, result); 879 errOut: 880 return result; 881 } 882 883 static void add_element(CFMutableDictionaryRef options, CFStringRef key, 884 CFTypeRef value) { 885 CFTypeRef old_value = CFDictionaryGetValue(options, key); 886 if (old_value) { 887 CFMutableArrayRef array; 888 if (CFGetTypeID(old_value) == CFArrayGetTypeID()) { 889 array = (CFMutableArrayRef)old_value; 890 } else { 891 array = CFArrayCreateMutable(kCFAllocatorDefault, 0, 892 &kCFTypeArrayCallBacks); 893 CFArrayAppendValue(array, old_value); 894 CFDictionarySetValue(options, key, array); 895 CFRelease(array); 896 } 897 CFArrayAppendValue(array, value); 898 } else { 899 CFDictionaryAddValue(options, key, value); 900 } 901 } 902 903 static void add_eku(CFMutableDictionaryRef options, const DERItem *ekuOid) { 904 CFDataRef eku = CFDataCreate(kCFAllocatorDefault, 905 ekuOid ? ekuOid->data : NULL, 906 ekuOid ? ekuOid->length : 0); 907 if (eku) { 908 add_element(options, kSecPolicyCheckExtendedKeyUsage, eku); 909 CFRelease(eku); 910 } 911 } 912 913 static void add_eku_string(CFMutableDictionaryRef options, CFStringRef ekuOid) { 914 if (ekuOid) { 915 add_element(options, kSecPolicyCheckExtendedKeyUsage, ekuOid); 916 } 917 } 918 919 static void set_ssl_ekus(CFMutableDictionaryRef options, bool server) { 920 CFDictionaryRemoveValue(options, kSecPolicyCheckExtendedKeyUsage); 921 922 /* If server and EKU ext present then EKU ext should contain one of 923 ServerAuth or ExtendedKeyUsageAny or NetscapeSGC or MicrosoftSGC. 924 else if !server and EKU ext present then EKU ext should contain one of 925 ClientAuth or ExtendedKeyUsageAny. */ 926 927 /* We always allow certificates that specify oidAnyExtendedKeyUsage. */ 928 add_eku(options, NULL); /* eku extension is optional */ 929 add_eku(options, &oidAnyExtendedKeyUsage); 930 if (server) { 931 add_eku(options, &oidExtendedKeyUsageServerAuth); 932 add_eku(options, &oidExtendedKeyUsageMicrosoftSGC); 933 add_eku(options, &oidExtendedKeyUsageNetscapeSGC); 934 } else { 935 add_eku(options, &oidExtendedKeyUsageClientAuth); 936 } 937 } 938 939 static void add_ku(CFMutableDictionaryRef options, SecKeyUsage keyUsage) { 940 SInt32 dku = keyUsage; 941 CFNumberRef ku = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, 942 &dku); 943 if (ku) { 944 add_element(options, kSecPolicyCheckKeyUsage, ku); 945 CFRelease(ku); 946 } 947 } 948 949 static void add_ku_report(CFMutableDictionaryRef options, SecKeyUsage keyUsage) { 950 SInt32 dku = keyUsage; 951 CFNumberRef ku = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, 952 &dku); 953 if (ku) { 954 add_element(options, kSecPolicyCheckKeyUsageReportOnly, ku); 955 CFRelease(ku); 956 } 957 } 958 959 #if TARGET_OS_OSX 960 static void set_ku_from_properties(SecPolicyRef policy, CFDictionaryRef properties) { 961 if (!policy || !properties) { 962 return; 963 } 964 965 CFStringRef keyNames[] = { kSecPolicyKU_DigitalSignature, kSecPolicyKU_NonRepudiation, kSecPolicyKU_KeyEncipherment, kSecPolicyKU_DataEncipherment, 966 kSecPolicyKU_KeyAgreement, kSecPolicyKU_KeyCertSign, kSecPolicyKU_CRLSign, kSecPolicyKU_EncipherOnly, kSecPolicyKU_DecipherOnly }; 967 968 uint32_t keyUsageValues[] = { kSecKeyUsageDigitalSignature, kSecKeyUsageNonRepudiation, kSecKeyUsageKeyEncipherment, kSecKeyUsageDataEncipherment, 969 kSecKeyUsageKeyAgreement, kSecKeyUsageKeyCertSign, kSecKeyUsageCRLSign, kSecKeyUsageEncipherOnly, kSecKeyUsageDecipherOnly }; 970 971 bool haveKeyUsage = false; 972 CFTypeRef keyUsageBoolean; 973 for (uint32_t i = 0; i < sizeof(keyNames) / sizeof(CFStringRef); ++i) { 974 if (CFDictionaryGetValueIfPresent(properties, keyNames[i], (const void**)&keyUsageBoolean)) { 975 if (CFEqual(keyUsageBoolean, kCFBooleanTrue)) { 976 haveKeyUsage = true; 977 break; 978 } 979 } 980 } 981 982 if (!haveKeyUsage) { 983 return; 984 } 985 986 CFMutableDictionaryRef options = (CFMutableDictionaryRef) policy->_options; 987 if (!options) { 988 options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, 989 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); 990 if (!options) return; 991 policy->_options = options; 992 } else { 993 CFDictionaryRemoveValue(options, kSecPolicyCheckKeyUsage); 994 } 995 996 for (uint32_t i = 0; i < sizeof(keyNames) / sizeof(CFStringRef); ++i) { 997 if (CFDictionaryGetValueIfPresent(properties, keyNames[i], (const void**)&keyUsageBoolean)) { 998 if (CFEqual(keyUsageBoolean, kCFBooleanTrue)) { 999 add_ku(options, keyUsageValues[i]); 1000 } 1001 } 1002 } 1003 } 1004 #endif 1005 1006 static void add_oid(CFMutableDictionaryRef options, CFStringRef policy_key, const DERItem *oid) { 1007 CFDataRef oid_data = CFDataCreate(kCFAllocatorDefault, 1008 oid ? oid->data : NULL, 1009 oid ? oid->length : 0); 1010 if (oid_data) { 1011 add_element(options, policy_key, oid_data); 1012 CFRelease(oid_data); 1013 } 1014 } 1015 1016 static void add_leaf_marker_value(CFMutableDictionaryRef options, const DERItem *markerOid, CFStringRef string_value) { 1017 1018 CFTypeRef policyData = NULL; 1019 1020 if (NULL == string_value) { 1021 policyData = CFDataCreate(kCFAllocatorDefault, 1022 markerOid ? markerOid->data : NULL, 1023 markerOid ? markerOid->length : 0); 1024 } else { 1025 CFStringRef oid_as_string = SecDERItemCopyOIDDecimalRepresentation(kCFAllocatorDefault, markerOid); 1026 1027 const void *key[1] = { oid_as_string }; 1028 const void *value[1] = { string_value }; 1029 policyData = CFDictionaryCreate(kCFAllocatorDefault, 1030 key, value, 1, 1031 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); 1032 CFReleaseNull(oid_as_string); 1033 } 1034 1035 add_element(options, kSecPolicyCheckLeafMarkerOid, policyData); 1036 1037 CFReleaseNull(policyData); 1038 1039 } 1040 1041 static void add_leaf_marker(CFMutableDictionaryRef options, const DERItem *markerOid) { 1042 add_leaf_marker_value(options, markerOid, NULL); 1043 } 1044 1045 static void add_leaf_marker_value_string(CFMutableDictionaryRef options, CFStringRef markerOid, CFStringRef string_value) { 1046 if (NULL == string_value) { 1047 add_element(options, kSecPolicyCheckLeafMarkerOid, markerOid); 1048 } else { 1049 CFDictionaryRef policyData = NULL; 1050 const void *key[1] = { markerOid }; 1051 const void *value[1] = { string_value }; 1052 policyData = CFDictionaryCreate(kCFAllocatorDefault, 1053 key, value, 1, 1054 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); 1055 add_element(options, kSecPolicyCheckLeafMarkerOid, policyData); 1056 1057 CFReleaseNull(policyData); 1058 } 1059 } 1060 1061 static void add_leaf_marker_string(CFMutableDictionaryRef options, CFStringRef markerOid) { 1062 add_leaf_marker_value_string(options, markerOid, NULL); 1063 } 1064 1065 static void add_leaf_prod_qa_element(CFMutableDictionaryRef options, CFTypeRef prodValue, CFTypeRef qaValue) 1066 { 1067 CFMutableDictionaryRef prodAndQADictionary = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, 1068 &kCFTypeDictionaryValueCallBacks); 1069 CFDictionaryRef old_value = CFDictionaryGetValue(options, kSecPolicyCheckLeafMarkersProdAndQA); 1070 if (old_value) { 1071 CFMutableArrayRef prodArray = NULL, qaArray = NULL; 1072 CFTypeRef old_prod_value = CFDictionaryGetValue(old_value, kSecPolicyLeafMarkerProd); 1073 CFTypeRef old_qa_value = CFDictionaryGetValue(old_value, kSecPolicyLeafMarkerQA); 1074 if (isArray(old_prod_value) && isArray(old_qa_value)) { 1075 prodArray = (CFMutableArrayRef)CFRetainSafe(old_prod_value); 1076 qaArray = (CFMutableArrayRef)CFRetainSafe(old_qa_value); 1077 } else { 1078 prodArray = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); 1079 qaArray = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); 1080 CFArrayAppendValue(prodArray, old_prod_value); 1081 CFArrayAppendValue(qaArray, old_qa_value); 1082 } 1083 CFArrayAppendValue(prodArray, prodValue); 1084 CFArrayAppendValue(qaArray, qaValue); 1085 CFDictionaryAddValue(prodAndQADictionary, kSecPolicyLeafMarkerProd, prodArray); 1086 CFDictionaryAddValue(prodAndQADictionary, kSecPolicyLeafMarkerQA, qaArray); 1087 CFReleaseNull(prodArray); 1088 CFReleaseNull(qaArray); 1089 1090 } else { 1091 CFDictionaryAddValue(prodAndQADictionary, kSecPolicyLeafMarkerProd, prodValue); 1092 CFDictionaryAddValue(prodAndQADictionary, kSecPolicyLeafMarkerQA, qaValue); 1093 } 1094 CFDictionarySetValue(options, kSecPolicyCheckLeafMarkersProdAndQA, prodAndQADictionary); 1095 CFReleaseNull(prodAndQADictionary); 1096 1097 } 1098 1099 static void add_leaf_prod_qa_markers(CFMutableDictionaryRef options, const DERItem *prodMarkerOid, const DERItem *qaMarkerOid) 1100 { 1101 CFDataRef prodData = NULL, qaData = NULL; 1102 prodData = CFDataCreate(NULL, prodMarkerOid ? prodMarkerOid->data : NULL, 1103 prodMarkerOid ? prodMarkerOid->length : 0); 1104 qaData = CFDataCreate(NULL, qaMarkerOid ? qaMarkerOid->data : NULL, 1105 qaMarkerOid ? qaMarkerOid->length : 0); 1106 add_leaf_prod_qa_element(options, prodData, qaData); 1107 CFReleaseNull(prodData); 1108 CFReleaseNull(qaData); 1109 } 1110 1111 static void add_leaf_prod_qa_markers_string(CFMutableDictionaryRef options, CFStringRef prodMarkerOid, CFStringRef qaMarkerOid) 1112 { 1113 add_leaf_prod_qa_element(options, prodMarkerOid, qaMarkerOid); 1114 } 1115 1116 static void add_leaf_prod_qa_markers_value_string(CFMutableDictionaryRef options, 1117 CFStringRef prodMarkerOid, CFStringRef prod_value, 1118 CFStringRef qaMarkerOid, CFStringRef qa_value) 1119 { 1120 if (!prod_value && !qa_value) { 1121 add_leaf_prod_qa_element(options, prodMarkerOid, qaMarkerOid); 1122 } else { 1123 CFDictionaryRef prodData = NULL, qaData = NULL; 1124 const void *prodKey[1] = { prodMarkerOid }, *qaKey[1] = { qaMarkerOid }; 1125 const void *prodValue[1] = { prod_value }, *qaValue[1] = { qa_value }; 1126 prodData = CFDictionaryCreate(NULL, prodKey, prodValue, 1, &kCFTypeDictionaryKeyCallBacks, 1127 &kCFTypeDictionaryValueCallBacks); 1128 qaData = CFDictionaryCreate(NULL, qaKey, qaValue, 1, &kCFTypeDictionaryKeyCallBacks, 1129 &kCFTypeDictionaryValueCallBacks); 1130 add_leaf_prod_qa_element(options, prodData, qaData); 1131 CFReleaseNull(prodData); 1132 CFReleaseNull(qaData); 1133 } 1134 } 1135 1136 static void add_intermediate_marker_value_string(CFMutableDictionaryRef options, CFStringRef markerOid, CFStringRef string_value) { 1137 if (NULL == string_value) { 1138 add_element(options, kSecPolicyCheckIntermediateMarkerOid, markerOid); 1139 } else { 1140 CFDictionaryRef policyData = NULL; 1141 const void *key[1] = { markerOid }; 1142 const void *value[1] = { string_value }; 1143 policyData = CFDictionaryCreate(kCFAllocatorDefault, 1144 key, value, 1, 1145 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); 1146 add_element(options, kSecPolicyCheckIntermediateMarkerOid, policyData); 1147 1148 CFReleaseNull(policyData); 1149 } 1150 } 1151 1152 static void add_certificate_policy_oid(CFMutableDictionaryRef options, const DERItem *certificatePolicyOid) { 1153 CFTypeRef certificatePolicyData = NULL; 1154 certificatePolicyData = CFDataCreate(kCFAllocatorDefault, 1155 certificatePolicyOid ? certificatePolicyOid->data : NULL, 1156 certificatePolicyOid ? certificatePolicyOid->length : 0); 1157 if (certificatePolicyData) { 1158 add_element(options, kSecPolicyCheckCertificatePolicy, certificatePolicyData); 1159 CFRelease(certificatePolicyData); 1160 } 1161 } 1162 1163 static void add_certificate_policy_oid_string(CFMutableDictionaryRef options, CFStringRef certificatePolicyOid) { 1164 if (certificatePolicyOid) { 1165 add_element(options, kSecPolicyCheckCertificatePolicy, certificatePolicyOid); 1166 } 1167 } 1168 1169 // 1170 // Routines for adding dictionary entries for policies. 1171 // 1172 1173 // X.509, but missing validity requirements. 1174 static void SecPolicyAddBasicCertOptions(CFMutableDictionaryRef options) 1175 { 1176 //CFDictionaryAddValue(options, kSecPolicyCheckBasicCertificateProcessing, kCFBooleanTrue); 1177 // Happens automatically in SecPVCPathChecks 1178 CFDictionaryAddValue(options, kSecPolicyCheckCriticalExtensions, kCFBooleanTrue); 1179 CFDictionaryAddValue(options, kSecPolicyCheckIdLinkage, kCFBooleanTrue); 1180 CFDictionaryAddValue(options, kSecPolicyCheckBasicConstraints, kCFBooleanTrue); 1181 CFDictionaryAddValue(options, kSecPolicyCheckNonEmptySubject, kCFBooleanTrue); 1182 CFDictionaryAddValue(options, kSecPolicyCheckWeakKeySize, kCFBooleanTrue); 1183 CFDictionaryAddValue(options, kSecPolicyCheckWeakSignature, kCFBooleanTrue); 1184 } 1185 1186 static void SecPolicyAddBasicX509Options(CFMutableDictionaryRef options) 1187 { 1188 SecPolicyAddBasicCertOptions(options); 1189 CFDictionaryAddValue(options, kSecPolicyCheckTemporalValidity, kCFBooleanTrue); 1190 1191 // Make sure that black and gray leaf checks are performed for basic X509 chain building 1192 CFDictionaryAddValue(options, kSecPolicyCheckBlackListedLeaf, kCFBooleanTrue); 1193 CFDictionaryAddValue(options, kSecPolicyCheckGrayListedLeaf, kCFBooleanTrue); 1194 } 1195 1196 static bool SecPolicyAddChainLengthOptions(CFMutableDictionaryRef options, CFIndex length) 1197 { 1198 bool result = false; 1199 CFNumberRef lengthAsCF = NULL; 1200 1201 require(lengthAsCF = CFNumberCreate(kCFAllocatorDefault, 1202 kCFNumberCFIndexType, &length), errOut); 1203 CFDictionaryAddValue(options, kSecPolicyCheckChainLength, lengthAsCF); 1204 1205 result = true; 1206 1207 errOut: 1208 CFReleaseSafe(lengthAsCF); 1209 return result; 1210 } 1211 1212 static bool SecPolicyAddAnchorSHA256Options(CFMutableDictionaryRef options, 1213 const UInt8 anchorSha256[kSecPolicySHA256Size]) 1214 { 1215 bool success = false; 1216 CFDataRef anchorData = NULL; 1217 1218 require(anchorData = CFDataCreate(kCFAllocatorDefault, anchorSha256, kSecPolicySHA256Size), errOut); 1219 add_element(options, kSecPolicyCheckAnchorSHA256, anchorData); 1220 1221 success = true; 1222 1223 errOut: 1224 CFReleaseSafe(anchorData); 1225 return success; 1226 } 1227 1228 static bool SecPolicyAddStrongKeySizeOptions(CFMutableDictionaryRef options) { 1229 bool success = false; 1230 CFDictionaryRef keySizes = NULL; 1231 CFNumberRef rsaSize = NULL, ecSize = NULL; 1232 1233 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */ 1234 require(rsaSize = CFNumberCreateWithCFIndex(NULL, 2048), errOut); 1235 require(ecSize = CFNumberCreateWithCFIndex(NULL, 256), errOut); 1236 const void *keys[] = { kSecAttrKeyTypeRSA, kSecAttrKeyTypeEC }; 1237 const void *values[] = { rsaSize, ecSize }; 1238 require(keySizes = CFDictionaryCreate(NULL, keys, values, 2, 1239 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut); 1240 add_element(options, kSecPolicyCheckKeySize, keySizes); 1241 1242 success = true; 1243 1244 errOut: 1245 CFReleaseSafe(keySizes); 1246 CFReleaseSafe(rsaSize); 1247 CFReleaseSafe(ecSize); 1248 return success; 1249 } 1250 1251 static bool SecPolicyRemoveWeakHashOptions(CFMutableDictionaryRef options) { 1252 CFMutableArrayRef disallowedHashes = CFArrayCreateMutable(NULL, 5, &kCFTypeArrayCallBacks); 1253 if (!disallowedHashes) { 1254 return false; 1255 } 1256 CFArrayAppendValue(disallowedHashes, kSecSignatureDigestAlgorithmMD2); 1257 CFArrayAppendValue(disallowedHashes, kSecSignatureDigestAlgorithmMD4); 1258 CFArrayAppendValue(disallowedHashes, kSecSignatureDigestAlgorithmMD5); 1259 CFArrayAppendValue(disallowedHashes, kSecSignatureDigestAlgorithmSHA1); 1260 1261 add_element(options, kSecPolicyCheckSignatureHashAlgorithms, disallowedHashes); 1262 CFReleaseNull(disallowedHashes); 1263 return true; 1264 } 1265 1266 static bool isAppleOid(CFStringRef oid) { 1267 if (!SecCertificateIsOidString(oid)) { 1268 return false; 1269 } 1270 if (CFStringHasPrefix(oid, CFSTR("1.2.840.113635"))) { 1271 return true; 1272 } 1273 return false; 1274 } 1275 1276 static bool isCFPreferenceInSecurityDomain(CFStringRef setting) { 1277 return (CFPreferencesGetAppBooleanValue(setting, CFSTR("com.apple.security"), NULL)); 1278 } 1279 1280 static bool SecPolicyAddAppleAnchorOptions(CFMutableDictionaryRef options, CFStringRef __unused policyName) 1281 { 1282 CFMutableDictionaryRef appleAnchorOptions = NULL; 1283 appleAnchorOptions = CFDictionaryCreateMutableForCFTypes(NULL); 1284 if (!appleAnchorOptions) { 1285 return false; 1286 } 1287 1288 /* Currently no Apple Anchor options */ 1289 add_element(options, kSecPolicyCheckAnchorApple, appleAnchorOptions); 1290 CFReleaseSafe(appleAnchorOptions); 1291 return true; 1292 } 1293 1294 CFDataRef CreateCFDataFromBase64CFString(CFStringRef base64string) 1295 { 1296 __block CFDataRef cfData = NULL; 1297 1298 require_quiet(base64string, errOut); 1299 1300 CFStringPerformWithCStringAndLength(base64string, ^(const char *base64string_buf, size_t base64string_buf_length) { 1301 void *data = NULL; 1302 1303 require_quiet(base64string_buf != NULL, errOut); 1304 require_quiet(base64string_buf_length != 0, errOut); 1305 1306 size_t expected_data_length = SecBase64Decode(base64string_buf, base64string_buf_length, NULL, 0); 1307 require_quiet(expected_data_length != 0, errOut); 1308 1309 data = malloc(expected_data_length); 1310 require(data != NULL, errOut); 1311 1312 size_t actual_data_length = SecBase64Decode(base64string_buf, base64string_buf_length, data, expected_data_length); 1313 require_quiet(actual_data_length != 0, errOut); 1314 1315 cfData = CFDataCreate(kCFAllocatorDefault, (const uint8_t *)data, actual_data_length); 1316 1317 errOut: 1318 free(data); 1319 return; 1320 }); 1321 1322 errOut: 1323 return cfData; 1324 } 1325 1326 static CFStringRef CopyParentDomainNameFromHostName(CFStringRef hostName) 1327 { 1328 CFStringRef parentDomainName = NULL; 1329 1330 require_quiet(hostName, errOut); 1331 1332 CFIndex hostNameLength = CFStringGetLength(hostName); 1333 require_quiet(hostNameLength != 0, errOut); 1334 1335 CFRange nextLabel = CFStringFind(hostName, CFSTR("."), 0); 1336 require_quiet(nextLabel.location != kCFNotFound && nextLabel.location < (hostNameLength - 1), errOut); 1337 1338 CFRange parentDomainNameRange = CFRangeMake(nextLabel.location + 1, hostNameLength - nextLabel.location - 1); 1339 parentDomainName = CFStringCreateWithSubstring(NULL, hostName, parentDomainNameRange); 1340 1341 errOut: 1342 return parentDomainName; 1343 } 1344 1345 CFArrayRef parseNSPinnedDomains(CFDictionaryRef nsPinnedDomainsDict, CFStringRef hostName, CFStringRef nsPinnedIdentityType) 1346 { 1347 CFMutableArrayRef targetSPKISHA256 = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); 1348 1349 __block bool hostNamePinned = false; 1350 1351 // Strip the trailing dot if any. 1352 CFIndex hostNameLength = CFStringGetLength(hostName); 1353 if (hostNameLength > 0 && '.' == CFStringGetCharacterAtIndex(hostName, hostNameLength - 1)) { 1354 hostName = CFStringCreateWithSubstring(NULL, hostName, CFRangeMake(0, hostNameLength - 1)); 1355 require_quiet(hostName, errOut); 1356 } else { 1357 CFRetainSafe(hostName); 1358 } 1359 1360 CFDictionaryForEach(nsPinnedDomainsDict, ^(const void *key, const void *value) { 1361 CFStringRef parentDomainName = NULL; 1362 1363 require_quiet(isString(key), errOutNSPinnedDomainsDict); 1364 require_quiet(isDictionary(value), errOutNSPinnedDomainsDict); 1365 1366 // Match one of the pinned domains to the current endpoint's hostname. 1367 CFStringRef domainName = (CFStringRef)key; 1368 bool hostNameMatched = (CFStringCompare(domainName, hostName, kCFCompareCaseInsensitive) == kCFCompareEqualTo); 1369 1370 // Match one of the pinned domains to the current endpoint's parent domain if allowed. 1371 if (hostNameMatched == false) { 1372 CFTypeRef nsIncludesSubdomains = CFDictionaryGetValue(value, CFSTR("NSIncludesSubdomains")); 1373 require_quiet(nsIncludesSubdomains == kCFBooleanTrue, errOutNSPinnedDomainsDict); 1374 1375 parentDomainName = CopyParentDomainNameFromHostName(hostName); 1376 require_quiet(parentDomainName != NULL, errOutNSPinnedDomainsDict); 1377 1378 hostNameMatched = (CFStringCompare(domainName, parentDomainName, kCFCompareCaseInsensitive) == kCFCompareEqualTo); 1379 } 1380 require_quiet(hostNameMatched, errOutNSPinnedDomainsDict); 1381 1382 CFTypeRef nsPinnedIdentities = CFDictionaryGetValue(value, nsPinnedIdentityType); 1383 require_quiet(nsPinnedIdentities, errOutNSPinnedDomainsDict); 1384 hostNamePinned = true; 1385 1386 require_quiet(isArray(nsPinnedIdentities), errOutNSPinnedDomainsDict); 1387 CFArrayForEach(nsPinnedIdentities, ^(const void *v) { 1388 CFDataRef spkiSHA256 = NULL; 1389 1390 require_quiet(isDictionary(v), errOutNSPinnedIdentities); 1391 1392 CFTypeRef spkiSHA256base64 = CFDictionaryGetValue(v, CFSTR("SPKI-SHA256-BASE64")); 1393 require_quiet(isString(spkiSHA256base64), errOutNSPinnedIdentities); 1394 1395 spkiSHA256 = CreateCFDataFromBase64CFString(spkiSHA256base64); 1396 require_quiet(spkiSHA256, errOutNSPinnedIdentities); 1397 1398 CFArrayAppendValue(targetSPKISHA256, spkiSHA256); 1399 1400 errOutNSPinnedIdentities: 1401 CFReleaseSafe(spkiSHA256); 1402 }); 1403 1404 errOutNSPinnedDomainsDict: 1405 CFReleaseSafe(parentDomainName); 1406 return; 1407 }); 1408 1409 errOut: 1410 CFReleaseSafe(hostName); 1411 if (hostNamePinned == false) { 1412 CFReleaseNull(targetSPKISHA256); 1413 } 1414 return targetSPKISHA256; 1415 } 1416 1417 static CFArrayRef getNSPinnedIdentitiesForHostName(CFStringRef hostName, CFStringRef nsPinnedIdentityType) 1418 { 1419 CFMutableArrayRef targetSPKISHA256 = NULL; 1420 1421 static CFDictionaryRef nsPinnedDomainsDict = NULL; 1422 static dispatch_once_t onceToken; 1423 dispatch_once(&onceToken, ^{ 1424 CFBundleRef bundle = CFBundleGetMainBundle(); 1425 require(bundle, initializationIncomplete); 1426 1427 CFTypeRef nsAppTransportSecurityDict = CFBundleGetValueForInfoDictionaryKey(bundle, CFSTR("NSAppTransportSecurity")); 1428 require_quiet(isDictionary(nsAppTransportSecurityDict), initializationIncomplete); 1429 1430 nsPinnedDomainsDict = CFDictionaryGetValue(nsAppTransportSecurityDict, CFSTR("NSPinnedDomains")); 1431 require(isDictionary(nsPinnedDomainsDict), initializationIncomplete); 1432 return; 1433 1434 initializationIncomplete: 1435 nsPinnedDomainsDict = NULL; 1436 }); 1437 // To proceed, this or a previous call must have found NSPinnedDomains in the info dictionary. 1438 require_quiet(nsPinnedDomainsDict, errOut); 1439 1440 targetSPKISHA256 = (CFMutableArrayRef)parseNSPinnedDomains(nsPinnedDomainsDict, hostName, nsPinnedIdentityType); 1441 1442 // Return NULL if the hostname (or its parent domain name) is not among the pinned domains. 1443 // Otherwise return an array of zero or more SPKI SHA256 identities. 1444 errOut: 1445 return targetSPKISHA256; 1446 } 1447 1448 static void SecPolicyAddATSpinningIfInfoSpecified(CFMutableDictionaryRef options) 1449 { 1450 CFStringRef hostname = CFDictionaryGetValue(options, kSecPolicyCheckSSLHostname); 1451 require_quiet(isString(hostname), errOut); 1452 1453 CFArrayRef leafSPKISHA256 = getNSPinnedIdentitiesForHostName(hostname, CFSTR("NSPinnedLeafIdentities")); 1454 if (leafSPKISHA256) { 1455 add_element(options, kSecPolicyCheckLeafSPKISHA256, leafSPKISHA256); 1456 } 1457 1458 CFArrayRef caSPKISHA256 = getNSPinnedIdentitiesForHostName(hostname, CFSTR("NSPinnedCAIdentities")); 1459 if (caSPKISHA256) { 1460 add_element(options, kSecPolicyCheckCAspkiSHA256, caSPKISHA256); 1461 } 1462 1463 errOut: 1464 return; 1465 } 1466 1467 void SecPolicyReconcilePinningRequiredIfInfoSpecified(CFMutableDictionaryRef options) 1468 { 1469 bool hasPinningRequiredKey = false; 1470 CFArrayRef leafSPKISHA256 = NULL; 1471 CFArrayRef caSPKISHA256 = NULL; 1472 1473 hasPinningRequiredKey = CFDictionaryContainsKey(options, kSecPolicyCheckPinningRequired); 1474 require_quiet(hasPinningRequiredKey, errOut); 1475 1476 // A non-NULL, empty, leafSPKISHA256 array allows all leaves and thus excludes this hostname from pinning. 1477 leafSPKISHA256 = CFDictionaryGetValue(options, kSecPolicyCheckLeafSPKISHA256); 1478 caSPKISHA256 = CFDictionaryGetValue(options, kSecPolicyCheckCAspkiSHA256); 1479 if (isArray(leafSPKISHA256) && CFArrayGetCount(leafSPKISHA256) == 0 && 1480 isArray(caSPKISHA256) && CFArrayGetCount(caSPKISHA256) == 0) { 1481 CFDictionaryRemoveValue(options, kSecPolicyCheckPinningRequired); 1482 } 1483 1484 // kSecPolicyCheckPinningRequired and (kSecPolicyCheckLeafSPKISHA256, kSecPolicyCheckCAspkiSHA256) are mutually exclusive. 1485 CFDictionaryRemoveValue(options, kSecPolicyCheckLeafSPKISHA256); 1486 CFDictionaryRemoveValue(options, kSecPolicyCheckCAspkiSHA256); 1487 1488 errOut: 1489 return; 1490 } 1491 1492 static bool SecPolicyAddPinningRequiredIfInfoSpecified(CFMutableDictionaryRef options) 1493 { 1494 static bool result = false; 1495 static bool hasPinningRequiredKey = false; 1496 static dispatch_once_t onceToken; 1497 dispatch_once(&onceToken, ^{ 1498 CFBundleRef bundle = CFBundleGetMainBundle(); 1499 if (bundle) { 1500 CFTypeRef value = CFBundleGetValueForInfoDictionaryKey(bundle, CFSTR("SecTrustPinningRequired")); 1501 if (isBoolean(value) && CFBooleanGetValue(value)) { 1502 hasPinningRequiredKey = true; 1503 } 1504 result = true; 1505 } 1506 }); 1507 if (result && hasPinningRequiredKey) { 1508 add_element(options, kSecPolicyCheckPinningRequired, kCFBooleanTrue); 1509 } 1510 return result; 1511 } 1512 1513 void SecPolicySetSHA256Pins(SecPolicyRef policy, CFArrayRef _Nullable leafSPKISHA256, CFArrayRef _Nullable caSPKISHA256) 1514 { 1515 if (!policy) { 1516 return; 1517 } 1518 CFMutableDictionaryRef options = (CFMutableDictionaryRef) policy->_options; 1519 if (!options) { 1520 options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, 1521 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); 1522 if (!options) return; 1523 policy->_options = options; 1524 } 1525 1526 if (leafSPKISHA256) { 1527 CFDictionaryRemoveValue(options, kSecPolicyCheckLeafSPKISHA256); 1528 add_element(options, kSecPolicyCheckLeafSPKISHA256, leafSPKISHA256); 1529 } else { 1530 CFDictionaryRemoveValue(options, kSecPolicyCheckLeafSPKISHA256); 1531 } 1532 1533 if (caSPKISHA256) { 1534 CFDictionaryRemoveValue(options, kSecPolicyCheckCAspkiSHA256); 1535 add_element(options, kSecPolicyCheckCAspkiSHA256, caSPKISHA256); 1536 } else { 1537 CFDictionaryRemoveValue(options, kSecPolicyCheckCAspkiSHA256); 1538 } 1539 } 1540 1541 // 1542 // MARK: Policy Creation Functions 1543 // 1544 SecPolicyRef SecPolicyCreateBasicX509(void) { 1545 CFMutableDictionaryRef options = NULL; 1546 SecPolicyRef result = NULL; 1547 1548 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, 1549 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut); 1550 1551 SecPolicyAddBasicX509Options(options); 1552 CFDictionaryAddValue(options, kSecPolicyCheckNoNetworkAccess, 1553 kCFBooleanTrue); 1554 1555 require(result = SecPolicyCreate(kSecPolicyAppleX509Basic, kSecPolicyNameX509Basic, options), errOut); 1556 1557 errOut: 1558 CFReleaseSafe(options); 1559 return (SecPolicyRef _Nonnull)result; 1560 } 1561 1562 SecPolicyRef SecPolicyCreateSSLWithKeyUsage(Boolean server, CFStringRef hostname, uint32_t keyUsage) { 1563 CFMutableDictionaryRef options = NULL; 1564 SecPolicyRef result = NULL; 1565 1566 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, 1567 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut); 1568 1569 SecPolicyAddBasicX509Options(options); 1570 1571 if (hostname) { 1572 CFDictionaryAddValue(options, kSecPolicyCheckSSLHostname, hostname); 1573 } 1574 1575 CFDictionaryAddValue(options, kSecPolicyCheckBlackListedLeaf, kCFBooleanTrue); 1576 CFDictionaryAddValue(options, kSecPolicyCheckGrayListedLeaf, kCFBooleanTrue); 1577 1578 if (server) { 1579 require_quiet(SecPolicyRemoveWeakHashOptions(options), errOut); 1580 require_quiet(SecPolicyAddStrongKeySizeOptions(options), errOut); 1581 require_quiet(SecPolicyAddPinningRequiredIfInfoSpecified(options), errOut); 1582 SecPolicyAddATSpinningIfInfoSpecified(options); 1583 SecPolicyReconcilePinningRequiredIfInfoSpecified(options); 1584 CFDictionaryAddValue(options, kSecPolicyCheckValidityPeriodMaximums, kCFBooleanTrue); 1585 CFDictionaryAddValue(options, kSecPolicyCheckServerAuthEKU, kCFBooleanTrue); // enforces stricter EKU rules than set_ssl_ekus below for certain anchor types 1586 #if !TARGET_OS_BRIDGE 1587 CFDictionaryAddValue(options, kSecPolicyCheckSystemTrustedCTRequired, kCFBooleanTrue); 1588 #endif 1589 } 1590 1591 if (keyUsage) { 1592 add_ku_report(options, keyUsage); 1593 } 1594 1595 set_ssl_ekus(options, server); 1596 1597 require(result = SecPolicyCreate(kSecPolicyAppleSSL, 1598 server ? kSecPolicyNameSSLServer : kSecPolicyNameSSLClient, 1599 options), errOut); 1600 1601 errOut: 1602 CFReleaseSafe(options); 1603 return (SecPolicyRef _Nonnull)result; 1604 } 1605 1606 SecPolicyRef SecPolicyCreateSSL(Boolean server, CFStringRef hostname) { 1607 return SecPolicyCreateSSLWithKeyUsage(server, hostname, kSecKeyUsageUnspecified); 1608 } 1609 1610 SecPolicyRef SecPolicyCreateLegacySSL(Boolean server, CFStringRef hostname) { 1611 CFMutableDictionaryRef options = NULL; 1612 SecPolicyRef result = NULL; 1613 1614 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, 1615 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut); 1616 1617 SecPolicyAddBasicX509Options(options); 1618 1619 if (hostname) { 1620 CFDictionaryAddValue(options, kSecPolicyCheckSSLHostname, hostname); 1621 } 1622 1623 CFDictionaryAddValue(options, kSecPolicyCheckBlackListedLeaf, kCFBooleanTrue); 1624 CFDictionaryAddValue(options, kSecPolicyCheckGrayListedLeaf, kCFBooleanTrue); 1625 1626 if (server) { 1627 // fewer requirements than the standard SSL policy 1628 require_quiet(SecPolicyAddPinningRequiredIfInfoSpecified(options), errOut); 1629 SecPolicyAddATSpinningIfInfoSpecified(options); 1630 SecPolicyReconcilePinningRequiredIfInfoSpecified(options); 1631 CFDictionaryAddValue(options, kSecPolicyCheckValidityPeriodMaximums, kCFBooleanTrue); 1632 #if !TARGET_OS_BRIDGE 1633 CFDictionaryAddValue(options, kSecPolicyCheckSystemTrustedCTRequired, kCFBooleanTrue); 1634 #endif 1635 } 1636 1637 set_ssl_ekus(options, server); 1638 1639 require(result = SecPolicyCreate(kSecPolicyAppleLegacySSL, kSecPolicyNameLegacySSL, options), errOut); 1640 1641 errOut: 1642 CFReleaseSafe(options); 1643 return (SecPolicyRef _Nonnull)result; 1644 } 1645 1646 SecPolicyRef SecPolicyCreateApplePinned(CFStringRef policyName, CFStringRef intermediateMarkerOID, CFStringRef leafMarkerOID) { 1647 CFMutableDictionaryRef options = NULL; 1648 SecPolicyRef result = NULL; 1649 1650 if (!policyName || !intermediateMarkerOID || !leafMarkerOID) { 1651 goto errOut; 1652 } 1653 1654 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, 1655 &kCFTypeDictionaryKeyCallBacks, 1656 &kCFTypeDictionaryValueCallBacks), errOut); 1657 1658 SecPolicyAddBasicX509Options(options); 1659 1660 /* Anchored to the Apple Roots */ 1661 require(SecPolicyAddAppleAnchorOptions(options, policyName), errOut); 1662 1663 /* Exactly 3 certs in the chain */ 1664 require(SecPolicyAddChainLengthOptions(options, 3), errOut); 1665 1666 /* Intermediate marker OID matches input OID */ 1667 if (!isAppleOid(intermediateMarkerOID)) { 1668 secwarning("creating an Apple pinning policy with a non-Apple OID: %@", intermediateMarkerOID); 1669 } 1670 add_element(options, kSecPolicyCheckIntermediateMarkerOid, intermediateMarkerOID); 1671 1672 /* Leaf marker OID matches input OID */ 1673 if (!isAppleOid(leafMarkerOID)) { 1674 secwarning("creating an Apple pinning policy with a non-Apple OID: %@", leafMarkerOID); 1675 } 1676 add_leaf_marker_string(options, leafMarkerOID); 1677 1678 /* Check revocation using any available method */ 1679 add_element(options, kSecPolicyCheckRevocation, kSecPolicyCheckRevocationAny); 1680 1681 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */ 1682 require(SecPolicyAddStrongKeySizeOptions(options), errOut); 1683 1684 /* Check for weak hashes */ 1685 // require(SecPolicyRemoveWeakHashOptions(options), errOut); // the current WWDR CA cert is signed with SHA1 1686 require(result = SecPolicyCreate(kSecPolicyAppleGenericApplePinned, 1687 policyName, options), errOut); 1688 1689 errOut: 1690 CFReleaseSafe(options); 1691 return result; 1692 } 1693 1694 static bool 1695 requireUATPinning(CFStringRef service) 1696 { 1697 bool pinningRequired = true; 1698 1699 if (SecIsInternalRelease()) { 1700 CFStringRef setting = CFStringCreateWithFormat(NULL, NULL, CFSTR("AppleServerAuthenticationNoPinning%@"), service); 1701 require(setting, fail); 1702 if(isCFPreferenceInSecurityDomain(setting)) { 1703 pinningRequired = false; 1704 } else { 1705 secnotice("pinningQA", "could not disable pinning: %@ not true", setting); 1706 } 1707 CFRelease(setting); 1708 1709 if (!pinningRequired) { 1710 goto fail; 1711 } 1712 1713 if(isCFPreferenceInSecurityDomain(CFSTR("AppleServerAuthenticationNoPinning"))) { 1714 pinningRequired = false; 1715 } else { 1716 secnotice("pinningQA", "could not disable pinning: AppleServerAuthenticationNoPinning not true"); 1717 } 1718 } else { 1719 secnotice("pinningQA", "could not disable pinning: not an internal release"); 1720 } 1721 fail: 1722 return pinningRequired; 1723 } 1724 1725 SecPolicyRef SecPolicyCreateAppleSSLPinned(CFStringRef policyName, CFStringRef hostname, 1726 CFStringRef intermediateMarkerOID, CFStringRef leafMarkerOID) { 1727 CFMutableDictionaryRef options = NULL; 1728 SecPolicyRef result = NULL; 1729 1730 if (!policyName || !hostname || !leafMarkerOID) { 1731 goto errOut; 1732 } 1733 1734 if (requireUATPinning(policyName)) { 1735 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, 1736 &kCFTypeDictionaryKeyCallBacks, 1737 &kCFTypeDictionaryValueCallBacks), errOut); 1738 1739 SecPolicyAddBasicX509Options(options); 1740 1741 /* Anchored to the Apple Roots */ 1742 require(SecPolicyAddAppleAnchorOptions(options, policyName), errOut); 1743 1744 /* Exactly 3 certs in the chain */ 1745 require(SecPolicyAddChainLengthOptions(options, 3), errOut); 1746 1747 if (intermediateMarkerOID) { 1748 /* Intermediate marker OID matches input OID */ 1749 if (!isAppleOid(intermediateMarkerOID)) { 1750 secwarning("creating an Apple pinning policy with a non-Apple OID: %@", intermediateMarkerOID); 1751 } 1752 add_element(options, kSecPolicyCheckIntermediateMarkerOid, intermediateMarkerOID); 1753 } else { 1754 add_element(options, kSecPolicyCheckIntermediateMarkerOid, CFSTR("1.2.840.113635.100.6.2.12")); 1755 } 1756 1757 /* Leaf marker OID matches input OID */ 1758 if (!isAppleOid(leafMarkerOID)) { 1759 secwarning("creating an Apple pinning policy with a non-Apple OID: %@", leafMarkerOID); 1760 } 1761 add_leaf_marker_string(options, leafMarkerOID); 1762 1763 /* New leaf marker OID format */ 1764 add_leaf_marker_value_string(options, CFSTR("1.2.840.113635.100.6.48.1"), leafMarkerOID); 1765 1766 /* ServerAuth EKU is in leaf cert */ 1767 add_eku_string(options, CFSTR("1.3.6.1.5.5.7.3.1")); 1768 1769 /* Hostname is in leaf cert */ 1770 add_element(options, kSecPolicyCheckSSLHostname, hostname); 1771 1772 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */ 1773 require(SecPolicyAddStrongKeySizeOptions(options), errOut); 1774 1775 /* Check for weak hashes */ 1776 require(SecPolicyRemoveWeakHashOptions(options), errOut); 1777 1778 /* Check revocation using any available method */ 1779 add_element(options, kSecPolicyCheckRevocation, kSecPolicyCheckRevocationAny); 1780 1781 require(result = SecPolicyCreate(kSecPolicyAppleGenericAppleSSLPinned, 1782 policyName, options), errOut); 1783 1784 } else { 1785 result = SecPolicyCreateSSL(true, hostname); 1786 SecPolicySetOid(result, kSecPolicyAppleGenericAppleSSLPinned); 1787 SecPolicySetName(result, policyName); 1788 } 1789 1790 errOut: 1791 CFReleaseSafe(options); 1792 return result; 1793 } 1794 1795 SecPolicyRef SecPolicyCreateiPhoneActivation(void) { 1796 CFMutableDictionaryRef options = NULL; 1797 SecPolicyRef result = NULL; 1798 1799 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, 1800 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut); 1801 1802 SecPolicyAddBasicCertOptions(options); 1803 1804 #if 0 1805 CFDictionaryAddValue(options, kSecPolicyCheckKeyUsage, 1806 kCFBooleanTrue); 1807 CFDictionaryAddValue(options, kSecPolicyCheckExtendedKeyUsage, 1808 kCFBooleanTrue); 1809 #endif 1810 1811 /* Basic X.509 policy with the additional requirements that the chain 1812 length is 3, it's anchored at the AppleCA and the leaf certificate 1813 has issuer "Apple iPhone Certification Authority" and 1814 subject "Apple iPhone Activation" for the common name. */ 1815 CFDictionaryAddValue(options, kSecPolicyCheckIssuerCommonName, 1816 CFSTR("Apple iPhone Certification Authority")); 1817 CFDictionaryAddValue(options, kSecPolicyCheckSubjectCommonName, 1818 CFSTR("Apple iPhone Activation")); 1819 1820 require(SecPolicyAddChainLengthOptions(options, 3), errOut); 1821 require(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameiPhoneActivation), errOut); 1822 1823 require(result = SecPolicyCreate(kSecPolicyAppleiPhoneActivation, 1824 kSecPolicyNameiPhoneActivation, options), 1825 errOut); 1826 1827 errOut: 1828 CFReleaseSafe(options); 1829 return result; 1830 } 1831 1832 SecPolicyRef SecPolicyCreateiPhoneDeviceCertificate(void) { 1833 CFMutableDictionaryRef options = NULL; 1834 SecPolicyRef result = NULL; 1835 1836 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, 1837 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut); 1838 1839 SecPolicyAddBasicCertOptions(options); 1840 1841 #if 0 1842 CFDictionaryAddValue(options, kSecPolicyCheckKeyUsage, 1843 kCFBooleanTrue); 1844 CFDictionaryAddValue(options, kSecPolicyCheckExtendedKeyUsage, 1845 kCFBooleanTrue); 1846 #endif 1847 1848 /* Basic X.509 policy with the additional requirements that the chain 1849 length is 4, it's anchored at the AppleCA and the first intermediate 1850 has the subject "Apple iPhone Device CA". */ 1851 CFDictionaryAddValue(options, kSecPolicyCheckIssuerCommonName, 1852 CFSTR("Apple iPhone Device CA")); 1853 1854 require(SecPolicyAddChainLengthOptions(options, 4), errOut); 1855 require(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameiPhoneDeviceCertificate), errOut); 1856 1857 require(result = SecPolicyCreate(kSecPolicyAppleiPhoneDeviceCertificate, 1858 kSecPolicyNameiPhoneDeviceCertificate, options), 1859 errOut); 1860 1861 errOut: 1862 CFReleaseSafe(options); 1863 return result; 1864 } 1865 1866 /* subject:/C=US/O=Apple Inc./OU=Apple iPhone/CN=[TEST] Apple iPhone Device CA */ 1867 /* issuer :/C=US/O=Apple Inc./OU=Apple Certification Authority/CN=[TEST] Apple iPhone Certification Authority */ 1868 const uint8_t kFactoryDeviceCASHA256[CC_SHA256_DIGEST_LENGTH] = { 1869 0x7b, 0x8e, 0xc8, 0x78, 0xff, 0x3a, 0xcf, 0x61, 0xdd, 0xe6, 0x53, 0x77, 0x2b, 0xe7, 0x32, 0xc5, 1870 0x97, 0xf4, 0x6b, 0x9c, 0xa6, 0x00, 0xc5, 0x2c, 0xc1, 0x25, 0x85, 0x02, 0x03, 0x06, 0x97, 0x96 1871 }; 1872 1873 SecPolicyRef SecPolicyCreateFactoryDeviceCertificate(void) { 1874 CFMutableDictionaryRef options = NULL; 1875 SecPolicyRef result = NULL; 1876 1877 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, 1878 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut); 1879 1880 SecPolicyAddBasicCertOptions(options); 1881 1882 /* Basic X.509 policy with the additional requirements that the chain 1883 is anchored at the factory device certificate issuer. */ 1884 require(SecPolicyAddAnchorSHA256Options(options, kFactoryDeviceCASHA256), errOut); 1885 1886 require(result = SecPolicyCreate(kSecPolicyAppleFactoryDeviceCertificate, 1887 kSecPolicyNameFactoryDeviceCertificate, options), 1888 errOut); 1889 1890 errOut: 1891 CFReleaseSafe(options); 1892 return result; 1893 } 1894 1895 SecPolicyRef SecPolicyCreateiAP(void) { 1896 CFMutableDictionaryRef options = NULL; 1897 SecPolicyRef result = NULL; 1898 CFTimeZoneRef tz = NULL; 1899 CFDateRef date = NULL; 1900 1901 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, 1902 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut); 1903 1904 SecPolicyAddBasicCertOptions(options); 1905 1906 CFDictionaryAddValue(options, kSecPolicyCheckSubjectCommonNamePrefix, 1907 CFSTR("IPA_")); 1908 1909 date = CFDateCreateForGregorianZuluDay(NULL, 2006, 5, 31); 1910 CFDictionaryAddValue(options, kSecPolicyCheckNotValidBefore, date); 1911 1912 require(result = SecPolicyCreate(kSecPolicyAppleiAP, 1913 kSecPolicyNameiAP, options), 1914 errOut); 1915 1916 errOut: 1917 CFReleaseSafe(date); 1918 CFReleaseSafe(tz); 1919 CFReleaseSafe(options); 1920 return result; 1921 } 1922 1923 /* subject:/O=Apple Inc./OU=iTunes Store/CN=iTunes Store Root/C=US/ST=California/L=Cupertino */ 1924 /* issuer :/O=Apple Inc./OU=iTunes Store/CN=iTunes Store Root/C=US/ST=California/L=Cupertino */ 1925 const uint8_t kITMS_CA_SHA256[CC_SHA256_DIGEST_LENGTH] = { 1926 0xa1, 0xdc, 0x36, 0x23, 0x84, 0xb4, 0xba, 0x0f, 0xaf, 0xea, 0x2a, 0xd4, 0xac, 0xc4, 0x86, 0x8f, 1927 0xfb, 0xae, 0x57, 0x21, 0x4d, 0x20, 0x88, 0xc8, 0x82, 0xe7, 0x65, 0x13, 0x47, 0xab, 0x81, 0xd7 1928 }; 1929 1930 SecPolicyRef SecPolicyCreateiTunesStoreURLBag(void) { 1931 CFMutableDictionaryRef options = NULL; 1932 SecPolicyRef result = NULL; 1933 1934 1935 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, 1936 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut); 1937 1938 SecPolicyAddBasicCertOptions(options); 1939 1940 CFDictionaryAddValue(options, kSecPolicyCheckSubjectOrganization, 1941 CFSTR("Apple Inc.")); 1942 CFDictionaryAddValue(options, kSecPolicyCheckSubjectCommonName, 1943 CFSTR("iTunes Store URL Bag")); 1944 1945 require(SecPolicyAddChainLengthOptions(options, 2), errOut); 1946 require(SecPolicyAddAnchorSHA256Options(options, kITMS_CA_SHA256), errOut); 1947 1948 require(result = SecPolicyCreate(kSecPolicyAppleiTunesStoreURLBag, 1949 kSecPolicyNameiTunesStoreURLBag, options), errOut); 1950 1951 errOut: 1952 CFReleaseSafe(options); 1953 return result; 1954 } 1955 1956 SecPolicyRef SecPolicyCreateEAP(Boolean server, CFArrayRef trustedServerNames) { 1957 CFMutableDictionaryRef options = NULL; 1958 SecPolicyRef result = NULL; 1959 1960 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, 1961 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut); 1962 1963 SecPolicyAddBasicX509Options(options); 1964 1965 /* Since EAP is used to setup the network we don't want evaluation 1966 using this policy to access the network. */ 1967 CFDictionaryAddValue(options, kSecPolicyCheckNoNetworkAccess, 1968 kCFBooleanTrue); 1969 1970 if (trustedServerNames) { 1971 CFDictionaryAddValue(options, kSecPolicyCheckEAPTrustedServerNames, trustedServerNames); 1972 } 1973 1974 if (server) { 1975 /* Check for weak hashes and keys, but only on system-trusted roots, because enterprise 1976 * PKIs are the absolute worst. */ 1977 CFDictionaryAddValue(options, kSecPolicyCheckSystemTrustedWeakHash, kCFBooleanTrue); 1978 CFDictionaryAddValue(options, kSecPolicyCheckSystemTrustedWeakKey, kCFBooleanTrue); 1979 } 1980 1981 /* We need to check for EKU per rdar://22206018 */ 1982 set_ssl_ekus(options, server); 1983 1984 require(result = SecPolicyCreate(kSecPolicyAppleEAP, 1985 server ? kSecPolicyNameEAPServer : kSecPolicyNameEAPClient, 1986 options), errOut); 1987 1988 errOut: 1989 CFReleaseSafe(options); 1990 return result; 1991 } 1992 1993 SecPolicyRef SecPolicyCreateIPSec(Boolean server, CFStringRef hostname) { 1994 CFMutableDictionaryRef options = NULL; 1995 SecPolicyRef result = NULL; 1996 1997 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, 1998 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut); 1999 2000 SecPolicyAddBasicX509Options(options); 2001 2002 if (hostname) { 2003 CFDictionaryAddValue(options, kSecPolicyCheckSSLHostname, hostname); 2004 } 2005 2006 /* Require oidExtendedKeyUsageIPSec if Extended Keyusage Extention is 2007 present. */ 2008 /* Per <rdar://problem/6843827> Cisco VPN Certificate compatibility issue. 2009 We don't check the EKU for IPSec certs for now. If we do add eku 2010 checking back in the future, we should probably also accept the 2011 following EKUs: 2012 ipsecEndSystem 1.3.6.1.5.5.7.3.5 2013 and possibly even 2014 ipsecTunnel 1.3.6.1.5.5.7.3.6 2015 ipsecUser 1.3.6.1.5.5.7.3.7 2016 */ 2017 //add_eku(options, NULL); /* eku extension is optional */ 2018 //add_eku(options, &oidAnyExtendedKeyUsage); 2019 //add_eku(options, &oidExtendedKeyUsageIPSec); 2020 2021 require(result = SecPolicyCreate(kSecPolicyAppleIPsec, 2022 server ? kSecPolicyNameIPSecServer : kSecPolicyNameIPSecClient, 2023 options), errOut); 2024 2025 errOut: 2026 CFReleaseSafe(options); 2027 return result; 2028 } 2029 2030 SecPolicyRef SecPolicyCreateiPhoneApplicationSigning(void) { 2031 CFMutableDictionaryRef options = NULL; 2032 SecPolicyRef result = NULL; 2033 2034 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, 2035 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut); 2036 2037 SecPolicyAddBasicCertOptions(options); 2038 2039 /* Anchored to the Apple Roots */ 2040 require(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameiPhoneApplicationSigning), errOut); 2041 2042 /* Leaf checks */ 2043 if (SecIsInternalRelease()) { 2044 /* Allow a prod hierarchy-signed test cert */ 2045 CFDictionaryAddValue(options, kSecPolicyCheckSubjectCommonNameTEST, 2046 CFSTR("Apple iPhone OS Application Signing")); 2047 add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.6.1.3.1")); 2048 } 2049 else { 2050 CFDictionaryAddValue(options, kSecPolicyCheckSubjectCommonName, 2051 CFSTR("Apple iPhone OS Application Signing")); 2052 } 2053 add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.6.1.3")); 2054 2055 add_eku(options, NULL); /* eku extension is optional */ 2056 add_eku(options, &oidAnyExtendedKeyUsage); 2057 add_eku(options, &oidExtendedKeyUsageCodeSigning); 2058 2059 /* Intermediate check */ 2060 CFDictionaryAddValue(options, kSecPolicyCheckIssuerCommonName, 2061 CFSTR("Apple iPhone Certification Authority")); 2062 2063 /* Chain length check */ 2064 require(SecPolicyAddChainLengthOptions(options, 3), errOut); 2065 2066 /* Skip networked revocation checks */ 2067 CFDictionaryAddValue(options, kSecPolicyCheckNoNetworkAccess, kCFBooleanTrue); 2068 2069 require(result = SecPolicyCreate(kSecPolicyAppleiPhoneApplicationSigning, 2070 kSecPolicyNameiPhoneApplicationSigning, options), 2071 errOut); 2072 2073 errOut: 2074 CFReleaseSafe(options); 2075 return result; 2076 } 2077 2078 SecPolicyRef SecPolicyCreateiPhoneVPNApplicationSigning(void) { 2079 CFMutableDictionaryRef options = NULL; 2080 SecPolicyRef result = NULL; 2081 2082 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, 2083 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut); 2084 2085 SecPolicyAddBasicCertOptions(options); 2086 2087 /* Anchored to the Apple Roots */ 2088 require(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameiPhoneVPNApplicationSigning), errOut); 2089 2090 /* Leaf checks */ 2091 if (SecIsInternalRelease()) { 2092 /* Allow a prod hierarchy-signed test cert */ 2093 CFDictionaryAddValue(options, kSecPolicyCheckSubjectCommonNameTEST, 2094 CFSTR("Apple iPhone OS Application Signing")); 2095 add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.6.1.6.1")); 2096 } 2097 else { 2098 CFDictionaryAddValue(options, kSecPolicyCheckSubjectCommonName, 2099 CFSTR("Apple iPhone OS Application Signing")); 2100 } 2101 add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.6.1.6")); 2102 2103 add_eku(options, NULL); /* eku extension is optional */ 2104 add_eku(options, &oidAnyExtendedKeyUsage); 2105 add_eku(options, &oidExtendedKeyUsageCodeSigning); 2106 2107 /* Intermediate check */ 2108 CFDictionaryAddValue(options, kSecPolicyCheckIssuerCommonName, 2109 CFSTR("Apple iPhone Certification Authority")); 2110 2111 /* Chain length check */ 2112 require(SecPolicyAddChainLengthOptions(options, 3), errOut); 2113 2114 /* Skip networked revocation checks */ 2115 CFDictionaryAddValue(options, kSecPolicyCheckNoNetworkAccess, kCFBooleanTrue); 2116 2117 require(result = SecPolicyCreate(kSecPolicyAppleiPhoneVPNApplicationSigning, 2118 kSecPolicyNameiPhoneVPNApplicationSigning, options), 2119 errOut); 2120 2121 errOut: 2122 CFReleaseSafe(options); 2123 return result; 2124 } 2125 2126 SecPolicyRef SecPolicyCreateiPhoneProfileApplicationSigning(void) { 2127 CFMutableDictionaryRef options = NULL; 2128 SecPolicyRef result = NULL; 2129 2130 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, 2131 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut); 2132 2133 SecPolicyAddBasicX509Options(options); // With expiration checking 2134 2135 /* Apple Anchor */ 2136 require_quiet(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameiPhoneProfileApplicationSigning), 2137 errOut); 2138 2139 /* Chain Len: 3 */ 2140 require(SecPolicyAddChainLengthOptions(options, 3), errOut); 2141 2142 /* Leaf has CodeSigning EKU */ 2143 add_eku_string(options, CFSTR("1.3.6.1.5.5.7.3.3")); 2144 2145 /* On iOS, the cert in the provisioning profile may be one of: 2146 leaf OID intermediate OID 2147 iPhone Developer <ADS>.6.1.2 <ADS>.6.2.1 2148 iPhone Distribution <ADS>.6.1.4 <ADS>.6.2.1 2149 TestFlight (Prod) <ADS>.6.1.25.1 <ADS>.6.2.1 2150 TestFlight (QA) <ADS>.6.1.25.2 <ADS>.6.2.1 2151 */ 2152 add_element(options, kSecPolicyCheckIntermediateMarkerOid, CFSTR("1.2.840.113635.100.6.2.1")); 2153 add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.6.1.2")); 2154 add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.6.1.4")); 2155 add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.6.1.25.1")); 2156 if (SecIsInternalRelease()) { 2157 add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.6.1.25.2")); 2158 } 2159 2160 /* Revocation via any available method */ 2161 CFDictionaryAddValue(options, kSecPolicyCheckRevocation, kSecPolicyCheckRevocationAny); 2162 2163 require(result = SecPolicyCreate(kSecPolicyAppleiPhoneProfileApplicationSigning, 2164 kSecPolicyNameiPhoneProfileApplicationSigning, 2165 options), errOut); 2166 2167 errOut: 2168 CFReleaseSafe(options); 2169 return result; 2170 } 2171 2172 SecPolicyRef SecPolicyCreateMacOSProfileApplicationSigning(void) { 2173 CFMutableDictionaryRef options = NULL; 2174 SecPolicyRef result = NULL; 2175 2176 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, 2177 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut); 2178 2179 SecPolicyAddBasicCertOptions(options); // Without expiration checking 2180 2181 /* Apple Anchor */ 2182 require_quiet(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameiPhoneProfileApplicationSigning), 2183 errOut); 2184 2185 /* Chain Len: 3 */ 2186 require(SecPolicyAddChainLengthOptions(options, 3), errOut); 2187 2188 /* Leaf has CodeSigning EKU */ 2189 add_eku_string(options, CFSTR("1.3.6.1.5.5.7.3.3")); 2190 2191 2192 /* On macOS, the cert in the provisioning profile may be one of: 2193 leaf OID intermediate OID 2194 MAS Development <ADS>.6.1.12 <ADS>.6.2.1 2195 MAS Submission <ADS>.6.1.7 <ADS>.6.2.1 2196 Developer ID <ADS>.6.1.13 <ADS>.6.2.6 2197 B&I <ADS>.6.22 None - "Apple Code Signing Certification Authority" 2198 */ 2199 add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.6.1.12")); 2200 add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.6.1.7")); 2201 add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.6.1.13")); 2202 add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.6.22")); 2203 2204 /* Revocation via any available method */ 2205 CFDictionaryAddValue(options, kSecPolicyCheckRevocation, kSecPolicyCheckRevocationAny); 2206 2207 require(result = SecPolicyCreate(kSecPolicyAppleMacOSProfileApplicationSigning, 2208 kSecPolicyNameMacOSProfileApplicationSigning, 2209 options), errOut); 2210 2211 errOut: 2212 CFReleaseSafe(options); 2213 return result; 2214 } 2215 2216 SecPolicyRef SecPolicyCreateiPhoneProvisioningProfileSigning(void) { 2217 CFMutableDictionaryRef options = NULL; 2218 SecPolicyRef result = NULL; 2219 2220 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, 2221 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut); 2222 2223 SecPolicyAddBasicCertOptions(options); 2224 2225 /* Basic X.509 policy with the additional requirements that the chain 2226 length is 3, it's anchored at the AppleCA and the leaf certificate 2227 has issuer "Apple iPhone Certification Authority" and 2228 subject "Apple iPhone OS Provisioning Profile Signing" for the common name. */ 2229 CFDictionaryAddValue(options, kSecPolicyCheckIssuerCommonName, 2230 CFSTR("Apple iPhone Certification Authority")); 2231 if (SecIsInternalRelease()) { 2232 CFDictionaryAddValue(options, kSecPolicyCheckSubjectCommonNameTEST, 2233 CFSTR("Apple iPhone OS Provisioning Profile Signing")); 2234 } 2235 else { 2236 CFDictionaryAddValue(options, kSecPolicyCheckSubjectCommonName, 2237 CFSTR("Apple iPhone OS Provisioning Profile Signing")); 2238 } 2239 2240 require(SecPolicyAddChainLengthOptions(options, 3), errOut); 2241 require(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameiPhoneProvisioningProfileSigning), errOut); 2242 2243 /* Skip networked revocation checks */ 2244 CFDictionaryAddValue(options, kSecPolicyCheckNoNetworkAccess, kCFBooleanTrue); 2245 2246 require(result = SecPolicyCreate(kSecPolicyAppleiPhoneProvisioningProfileSigning, 2247 kSecPolicyNameiPhoneProvisioningProfileSigning, options), 2248 errOut); 2249 2250 /* 1.2.840.113635.100.6.2.2.1, non-critical: DER:05:00 - provisioning profile */ 2251 2252 errOut: 2253 CFReleaseSafe(options); 2254 return result; 2255 } 2256 2257 SecPolicyRef SecPolicyCreateAppleTVOSApplicationSigning(void) { 2258 CFMutableDictionaryRef options = NULL; 2259 SecPolicyRef result = NULL; 2260 CFDataRef atvProdOid = NULL; 2261 CFDataRef atvTestOid = NULL; 2262 CFArrayRef oids = NULL; 2263 2264 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, 2265 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut); 2266 2267 SecPolicyAddBasicCertOptions(options); 2268 2269 require(SecPolicyAddChainLengthOptions(options, 3), errOut); 2270 2271 require_quiet(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameTVOSApplicationSigning), 2272 errOut); 2273 2274 /* Check for intermediate: Apple Worldwide Developer Relations */ 2275 /* 1.2.840.113635.100.6.2.1 */ 2276 add_oid(options, kSecPolicyCheckIntermediateMarkerOid, &oidAppleIntmMarkerAppleWWDR); 2277 2278 add_ku(options, kSecKeyUsageDigitalSignature); 2279 2280 /* Check for prod or test AppleTV Application Signing OIDs */ 2281 /* Prod: 1.2.840.113635.100.6.1.24 */ 2282 /* ProdQA: 1.2.840.113635.100.6.1.24.1 */ 2283 add_leaf_marker(options, &oidAppleTVOSApplicationSigningProd); 2284 add_leaf_marker(options, &oidAppleTVOSApplicationSigningProdQA); 2285 2286 /* Skip networked revocation checks */ 2287 CFDictionaryAddValue(options, kSecPolicyCheckNoNetworkAccess, kCFBooleanTrue); 2288 2289 require(result = SecPolicyCreate(kSecPolicyAppleTVOSApplicationSigning, 2290 kSecPolicyNameTVOSApplicationSigning, options), 2291 errOut); 2292 2293 errOut: 2294 CFReleaseSafe(options); 2295 CFReleaseSafe(oids); 2296 CFReleaseSafe(atvProdOid); 2297 CFReleaseSafe(atvTestOid); 2298 return result; 2299 } 2300 2301 SecPolicyRef SecPolicyCreateOCSPSigner(void) { 2302 CFMutableDictionaryRef options = NULL; 2303 SecPolicyRef result = NULL; 2304 2305 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, 2306 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut); 2307 2308 SecPolicyAddBasicX509Options(options); 2309 2310 /* Require id-kp-OCSPSigning extendedKeyUsage to be present, not optional. */ 2311 add_eku(options, &oidExtendedKeyUsageOCSPSigning); 2312 2313 /* Check for digitalSignature KU and CA:FALSE. See <rdar://problem/65354714> */ 2314 add_ku(options, kSecKeyUsageDigitalSignature); 2315 CFDictionarySetValue(options, kSecPolicyCheckNotCA, kCFBooleanTrue); 2316 2317 require(result = SecPolicyCreate(kSecPolicyAppleOCSPSigner, 2318 kSecPolicyNameOCSPSigner, options), errOut); 2319 2320 errOut: 2321 CFReleaseSafe(options); 2322 return result; 2323 } 2324 2325 SecPolicyRef SecPolicyCreateRevocation(CFOptionFlags revocationFlags) { 2326 CFMutableDictionaryRef options = NULL; 2327 SecPolicyRef result = NULL; 2328 2329 require(revocationFlags != 0, errOut); 2330 2331 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, 2332 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut); 2333 2334 if (revocationFlags & kSecRevocationCheckIfTrusted) { 2335 CFDictionaryAddValue(options, kSecPolicyCheckRevocationIfTrusted, kCFBooleanTrue); 2336 /* Set method, but allow caller to override with later checks */ 2337 CFDictionaryAddValue(options, kSecPolicyCheckRevocation, kSecPolicyCheckRevocationAny); 2338 } 2339 2340 if (revocationFlags & kSecRevocationOnlineCheck) { 2341 CFDictionaryAddValue(options, kSecPolicyCheckRevocationOnline, kCFBooleanTrue); 2342 /* Set method, but allow caller to override with later checks */ 2343 CFDictionaryAddValue(options, kSecPolicyCheckRevocation, kSecPolicyCheckRevocationAny); 2344 } 2345 2346 if (revocationFlags & kSecRevocationOCSPMethod && revocationFlags & kSecRevocationCRLMethod) { 2347 CFDictionaryAddValue(options, kSecPolicyCheckRevocation, kSecPolicyCheckRevocationAny); 2348 } 2349 else if (revocationFlags & kSecRevocationOCSPMethod) { 2350 CFDictionaryAddValue(options, kSecPolicyCheckRevocation, kSecPolicyCheckRevocationOCSP); 2351 } 2352 else if (revocationFlags & kSecRevocationCRLMethod) { 2353 CFDictionaryAddValue(options, kSecPolicyCheckRevocation, kSecPolicyCheckRevocationCRL); 2354 } 2355 2356 if (revocationFlags & kSecRevocationRequirePositiveResponse) { 2357 CFDictionaryAddValue(options, kSecPolicyCheckRevocationResponseRequired, kCFBooleanTrue); 2358 } 2359 2360 if (revocationFlags & kSecRevocationNetworkAccessDisabled) { 2361 CFDictionaryAddValue(options, kSecPolicyCheckNoNetworkAccess, kCFBooleanTrue); 2362 } else { 2363 /* If the caller didn't explicitly disable network access, the revocation policy 2364 * should override any other policy's network setting. 2365 * In particular, pairing a revocation policy with BasicX509 should result in 2366 * allowing network access for revocation unless explicitly disabled. 2367 * Note that SecTrustSetNetworkFetchAllowed can override even this. */ 2368 CFDictionaryAddValue(options, kSecPolicyCheckNoNetworkAccess, kCFBooleanFalse); 2369 } 2370 2371 /* Only flag bits 0-6 are currently defined */ 2372 require(((revocationFlags >> 7) == 0), errOut); 2373 2374 require(result = SecPolicyCreate(kSecPolicyAppleRevocation, 2375 kSecPolicyNameRevocation, options), errOut); 2376 2377 errOut: 2378 CFReleaseSafe(options); 2379 return result; 2380 } 2381 2382 SecPolicyRef SecPolicyCreateSMIME(CFIndex smimeUsage, CFStringRef email) { 2383 CFMutableDictionaryRef options = NULL; 2384 SecPolicyRef result = NULL; 2385 2386 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, 2387 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut); 2388 2389 if (smimeUsage & kSecIgnoreExpirationSMIMEUsage) { 2390 SecPolicyAddBasicCertOptions(options); 2391 } else { 2392 SecPolicyAddBasicX509Options(options); 2393 } 2394 2395 /* We call add_ku for each combination of bits we are willing to allow. */ 2396 if (smimeUsage & kSecSignSMIMEUsage) { 2397 add_ku(options, kSecKeyUsageUnspecified); 2398 add_ku(options, kSecKeyUsageDigitalSignature); 2399 } 2400 if (smimeUsage & kSecKeyEncryptSMIMEUsage) { 2401 add_ku(options, kSecKeyUsageKeyEncipherment); 2402 } 2403 if (smimeUsage & kSecDataEncryptSMIMEUsage) { 2404 add_ku(options, kSecKeyUsageDataEncipherment); 2405 } 2406 if (smimeUsage & kSecKeyExchangeDecryptSMIMEUsage || 2407 smimeUsage & kSecKeyExchangeEncryptSMIMEUsage || 2408 smimeUsage & kSecKeyExchangeBothSMIMEUsage) { 2409 /* <rdar://57130017> */ 2410 add_ku(options, kSecKeyUsageKeyAgreement); 2411 } 2412 2413 if (email) { 2414 CFDictionaryAddValue(options, kSecPolicyCheckEmail, email); 2415 } 2416 2417 add_eku(options, NULL); /* eku extension is optional */ 2418 add_eku(options, &oidExtendedKeyUsageEmailProtection); 2419 2420 #if !TARGET_OS_IPHONE 2421 // Check revocation on OS X 2422 CFDictionaryAddValue(options, kSecPolicyCheckRevocation, kSecPolicyCheckRevocationAny); 2423 #endif 2424 2425 require(result = SecPolicyCreate(kSecPolicyAppleSMIME, kSecPolicyNameSMIME, options), errOut); 2426 2427 errOut: 2428 CFReleaseSafe(options); 2429 return result; 2430 } 2431 2432 SecPolicyRef SecPolicyCreateApplePackageSigning(void) { 2433 CFMutableDictionaryRef options = NULL; 2434 SecPolicyRef result = NULL; 2435 2436 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, 2437 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut); 2438 2439 SecPolicyAddBasicCertOptions(options); 2440 2441 require(SecPolicyAddChainLengthOptions(options, 3), errOut); 2442 require(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNamePackageSigning), errOut); 2443 2444 add_ku(options, kSecKeyUsageDigitalSignature); 2445 add_eku(options, &oidExtendedKeyUsageCodeSigning); 2446 2447 require(result = SecPolicyCreate(kSecPolicyApplePackageSigning, 2448 kSecPolicyNamePackageSigning, options), 2449 errOut); 2450 2451 errOut: 2452 CFReleaseSafe(options); 2453 return result; 2454 2455 } 2456 2457 SecPolicyRef SecPolicyCreateAppleSWUpdateSigning(void) { 2458 CFMutableDictionaryRef options = NULL; 2459 SecPolicyRef result = NULL; 2460 /* 2461 * OS X rules for this policy: 2462 * -- Must have one intermediate cert 2463 * -- intermediate must have basic constraints with path length 0 2464 * -- intermediate has CSSMOID_APPLE_EKU_CODE_SIGNING EKU 2465 * -- leaf cert has either CODE_SIGNING or CODE_SIGN_DEVELOPMENT EKU (the latter of 2466 * which triggers a CSSMERR_APPLETP_CODE_SIGN_DEVELOPMENT error) 2467 */ 2468 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, 2469 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut); 2470 2471 SecPolicyAddBasicX509Options(options); 2472 2473 require(SecPolicyAddChainLengthOptions(options, 3), errOut); 2474 require(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameSWUpdateSigning), errOut); 2475 2476 add_eku(options, &oidAppleExtendedKeyUsageCodeSigning); 2477 add_oid(options, kSecPolicyCheckIntermediateEKU, &oidAppleExtendedKeyUsageCodeSigning); 2478 2479 require(result = SecPolicyCreate(kSecPolicyAppleSWUpdateSigning, 2480 kSecPolicyNameSWUpdateSigning, options), 2481 errOut); 2482 2483 errOut: 2484 CFReleaseSafe(options); 2485 return result; 2486 2487 } 2488 2489 SecPolicyRef SecPolicyCreateCodeSigning(void) { 2490 CFMutableDictionaryRef options = NULL; 2491 SecPolicyRef result = NULL; 2492 2493 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, 2494 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut); 2495 2496 SecPolicyAddBasicX509Options(options); 2497 2498 /* If the key usage extension is present, we accept it having either of 2499 these values. */ 2500 add_ku(options, kSecKeyUsageDigitalSignature); 2501 add_ku(options, kSecKeyUsageNonRepudiation); 2502 2503 /* We require an extended key usage extension with the codesigning 2504 eku purpose. (The Apple codesigning eku is not accepted here 2505 since it's valid only for SecPolicyCreateAppleSWUpdateSigning.) */ 2506 add_eku(options, &oidExtendedKeyUsageCodeSigning); 2507 #if TARGET_OS_IPHONE 2508 /* Accept the 'any' eku on iOS only to match prior behavior. 2509 This may be further restricted in future releases. */ 2510 add_eku(options, &oidAnyExtendedKeyUsage); 2511 #endif 2512 2513 require(result = SecPolicyCreate(kSecPolicyAppleCodeSigning, 2514 kSecPolicyNameCodeSigning, options), 2515 errOut); 2516 2517 errOut: 2518 CFReleaseSafe(options); 2519 return result; 2520 } 2521 2522 /* Explicitly leave out empty subject/subjectaltname check */ 2523 SecPolicyRef SecPolicyCreateLockdownPairing(void) { 2524 CFMutableDictionaryRef options = NULL; 2525 SecPolicyRef result = NULL; 2526 2527 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, 2528 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut); 2529 //CFDictionaryAddValue(options, kSecPolicyCheckBasicCertificateProcessing, 2530 // kCFBooleanTrue); // Happens automatically in SecPVCPathChecks 2531 CFDictionaryAddValue(options, kSecPolicyCheckCriticalExtensions, 2532 kCFBooleanTrue); 2533 CFDictionaryAddValue(options, kSecPolicyCheckIdLinkage, 2534 kCFBooleanTrue); 2535 CFDictionaryAddValue(options, kSecPolicyCheckBasicConstraints, 2536 kCFBooleanTrue); 2537 CFDictionaryAddValue(options, kSecPolicyCheckWeakKeySize, kCFBooleanTrue); 2538 2539 require(result = SecPolicyCreate(kSecPolicyAppleLockdownPairing, 2540 kSecPolicyNameLockdownPairing, options), errOut); 2541 2542 errOut: 2543 CFReleaseSafe(options); 2544 return result; 2545 } 2546 2547 SecPolicyRef SecPolicyCreateURLBag(void) { 2548 CFMutableDictionaryRef options = NULL; 2549 SecPolicyRef result = NULL; 2550 2551 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, 2552 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut); 2553 2554 SecPolicyAddBasicCertOptions(options); 2555 2556 add_eku(options, &oidExtendedKeyUsageCodeSigning); 2557 2558 require(result = SecPolicyCreate(kSecPolicyAppleURLBag, 2559 kSecPolicyNameURLBag, options), errOut); 2560 2561 errOut: 2562 CFReleaseSafe(options); 2563 return result; 2564 } 2565 2566 SecPolicyRef SecPolicyCreateOTATasking(void) 2567 { 2568 CFMutableDictionaryRef options = NULL; 2569 SecPolicyRef result = NULL; 2570 2571 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, 2572 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut); 2573 2574 SecPolicyAddBasicX509Options(options); 2575 2576 /* Apple Anchor */ 2577 require(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameMobileAsset), errOut); 2578 2579 /* Chain length of 3 */ 2580 require(SecPolicyAddChainLengthOptions(options, 3), errOut); 2581 2582 /* Intermediate has common name "Apple iPhone Certification Authority". */ 2583 CFDictionaryAddValue(options, kSecPolicyCheckIssuerCommonName, 2584 CFSTR("Apple iPhone Certification Authority")); 2585 2586 /* Leaf has common name "Asset Manifest Signing" */ 2587 CFDictionaryAddValue(options, kSecPolicyCheckSubjectCommonName, CFSTR("OTA Task Signing")); 2588 2589 require(result = SecPolicyCreate(kSecPolicyAppleOTATasking, kSecPolicyNameOTATasking, options), 2590 errOut); 2591 2592 errOut: 2593 CFReleaseSafe(options); 2594 return result; 2595 } 2596 2597 SecPolicyRef SecPolicyCreateMobileAsset(void) 2598 { 2599 CFMutableDictionaryRef options = NULL; 2600 SecPolicyRef result = NULL; 2601 2602 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, 2603 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut); 2604 2605 /* No expiration check */ 2606 SecPolicyAddBasicCertOptions(options); 2607 2608 /* Apple Anchor */ 2609 require(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameMobileAsset), errOut); 2610 2611 /* Chain length of 3 */ 2612 require(SecPolicyAddChainLengthOptions(options, 3), errOut); 2613 2614 /* Intermediate has common name "Apple iPhone Certification Authority". */ 2615 CFDictionaryAddValue(options, kSecPolicyCheckIssuerCommonName, 2616 CFSTR("Apple iPhone Certification Authority")); 2617 2618 /* Leaf has common name "Asset Manifest Signing" */ 2619 CFDictionaryAddValue(options, kSecPolicyCheckSubjectCommonName, CFSTR("Asset Manifest Signing")); 2620 2621 require(result = SecPolicyCreate(kSecPolicyAppleMobileAsset, kSecPolicyNameMobileAsset, options), 2622 errOut); 2623 2624 errOut: 2625 CFReleaseSafe(options); 2626 return result; 2627 } 2628 2629 SecPolicyRef SecPolicyCreateMobileAssetDevelopment(void) { 2630 CFMutableDictionaryRef options = NULL; 2631 SecPolicyRef result = NULL; 2632 2633 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, 2634 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut); 2635 2636 /* No expiration check */ 2637 SecPolicyAddBasicCertOptions(options); 2638 2639 /* Apple Anchor */ 2640 require(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameMobileAsset), errOut); 2641 2642 /* Chain length of 3 */ 2643 require(SecPolicyAddChainLengthOptions(options, 3), errOut); 2644 2645 /* Intermediate has the iPhone CA Marker extension */ 2646 add_element(options, kSecPolicyCheckIntermediateMarkerOid, CFSTR("1.2.840.113635.100.6.2.18")); 2647 2648 /* Leaf has ProdQA Mobile Asset Marker extension */ 2649 add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.6.55.1")); 2650 2651 require(result = SecPolicyCreate(kSecPolicyAppleMobileAssetDevelopment, kSecPolicyNameMobileAsset, options), 2652 errOut); 2653 2654 errOut: 2655 CFReleaseSafe(options); 2656 return result; 2657 } 2658 2659 SecPolicyRef SecPolicyCreateAppleIDAuthorityPolicy(void) 2660 { 2661 SecPolicyRef result = NULL; 2662 CFMutableDictionaryRef options = NULL; 2663 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, 2664 &kCFTypeDictionaryKeyCallBacks, 2665 &kCFTypeDictionaryValueCallBacks), out); 2666 2667 //Leaf appears to be a SSL only cert, so policy should expand on that policy 2668 SecPolicyAddBasicX509Options(options); 2669 2670 // Apple CA anchored 2671 require(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameIDAuthority), out); 2672 2673 // with the addition of the existence check of an extension with "Apple ID Sharing Certificate" oid (1.2.840.113635.100.4.7) 2674 // NOTE: this obviously intended to have gone into Extended Key Usage, but evidence of existing certs proves the contrary. 2675 add_leaf_marker(options, &oidAppleExtendedKeyUsageAppleID); 2676 2677 // and validate that intermediate has extension with CSSMOID_APPLE_EXTENSION_AAI_INTERMEDIATE oid (1.2.840.113635.100.6.2.3) and goes back to the Apple Root CA. 2678 add_oid(options, kSecPolicyCheckIntermediateMarkerOid, &oidAppleIntmMarkerAppleID); 2679 add_oid(options, kSecPolicyCheckIntermediateMarkerOid, &oidAppleIntmMarkerAppleID2); 2680 2681 require(result = SecPolicyCreate(kSecPolicyAppleIDAuthority, 2682 kSecPolicyNameIDAuthority, options), out); 2683 2684 out: 2685 CFReleaseSafe(options); 2686 return result; 2687 } 2688 2689 SecPolicyRef SecPolicyCreateMacAppStoreReceipt(void) 2690 { 2691 SecPolicyRef result = NULL; 2692 CFMutableDictionaryRef options = NULL; 2693 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, 2694 &kCFTypeDictionaryKeyCallBacks, 2695 &kCFTypeDictionaryValueCallBacks), out); 2696 2697 SecPolicyAddBasicX509Options(options); 2698 2699 // Apple CA anchored 2700 require(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameMacAppStoreReceipt), out); 2701 2702 // Chain length of 3 2703 require(SecPolicyAddChainLengthOptions(options, 3), out); 2704 2705 // MacAppStoreReceipt policy OID 2706 add_certificate_policy_oid_string(options, CFSTR("1.2.840.113635.100.5.6.1")); 2707 2708 // Intermediate marker OID 2709 add_element(options, kSecPolicyCheckIntermediateMarkerOid, CFSTR("1.2.840.113635.100.6.2.1")); 2710 2711 // Leaf marker OID 2712 add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.6.11.1")); 2713 2714 // Check revocation 2715 CFDictionaryAddValue(options, kSecPolicyCheckRevocation, kSecPolicyCheckRevocationAny); 2716 2717 require(result = SecPolicyCreate(kSecPolicyMacAppStoreReceipt, 2718 kSecPolicyNameMacAppStoreReceipt, options), out); 2719 2720 out: 2721 CFReleaseSafe(options); 2722 return result; 2723 2724 } 2725 2726 static SecPolicyRef _SecPolicyCreatePassbookCardSigner(CFStringRef cardIssuer, CFStringRef teamIdentifier, bool requireTeamID) 2727 { 2728 SecPolicyRef result = NULL; 2729 CFMutableDictionaryRef options = NULL; 2730 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, 2731 &kCFTypeDictionaryKeyCallBacks, 2732 &kCFTypeDictionaryValueCallBacks), out); 2733 2734 SecPolicyAddBasicX509Options(options); 2735 require(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNamePassbookSigning), out); 2736 2737 // Chain length of 3 2738 require(SecPolicyAddChainLengthOptions(options, 3), out); 2739 2740 if (teamIdentifier) { 2741 // If supplied, teamIdentifier must match subject OU field 2742 CFDictionaryAddValue(options, kSecPolicyCheckSubjectOrganizationalUnit, teamIdentifier); 2743 } 2744 else { 2745 // If not supplied, and it was required, fail 2746 require(!requireTeamID, out); 2747 } 2748 2749 // Must be both push and 3rd party package signing 2750 add_leaf_marker_value(options, &oidAppleInstallerPackagingSigningExternal, cardIssuer); 2751 2752 // We should check that it also has push marker, but we don't support requiring both, only either. 2753 // add_independent_oid(options, kSecPolicyCheckLeafMarkerOid, &oidApplePushServiceClient); 2754 2755 //WWDR Intermediate marker OID 2756 add_element(options, kSecPolicyCheckIntermediateMarkerOid, CFSTR("1.2.840.113635.100.6.2.1")); 2757 2758 // And Passbook signing eku 2759 add_eku(options, &oidAppleExtendedKeyUsagePassbook); 2760 2761 require(result = SecPolicyCreate(kSecPolicyApplePassbookSigning, 2762 kSecPolicyNamePassbookSigning, options), out); 2763 2764 out: 2765 CFReleaseSafe(options); 2766 return result; 2767 } 2768 2769 SecPolicyRef SecPolicyCreatePassbookCardSigner(CFStringRef cardIssuer, CFStringRef teamIdentifier) 2770 { 2771 return _SecPolicyCreatePassbookCardSigner(cardIssuer, teamIdentifier, true); 2772 } 2773 2774 2775 static SecPolicyRef CreateMobileStoreSigner(Boolean forTest) 2776 { 2777 2778 SecPolicyRef result = NULL; 2779 CFMutableDictionaryRef options = NULL; 2780 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, 2781 &kCFTypeDictionaryKeyCallBacks, 2782 &kCFTypeDictionaryValueCallBacks), errOut); 2783 SecPolicyAddBasicX509Options(options); 2784 require(SecPolicyAddAppleAnchorOptions(options, 2785 ((forTest) ? kSecPolicyNameTestMobileStore : 2786 kSecPolicyNameMobileStore)), errOut); 2787 2788 require(SecPolicyAddChainLengthOptions(options, 3), errOut); 2789 2790 CFDictionaryAddValue(options, kSecPolicyCheckIssuerCommonName, 2791 CFSTR("Apple System Integration 2 Certification Authority")); 2792 2793 add_ku(options, kSecKeyUsageDigitalSignature); 2794 2795 const DERItem* pOID = (forTest) ? &oidApplePolicyMobileStoreProdQA : &oidApplePolicyMobileStore; 2796 2797 add_certificate_policy_oid(options, pOID); 2798 2799 require(result = SecPolicyCreate((forTest) ? kSecPolicyAppleTestMobileStore : kSecPolicyAppleMobileStore, 2800 (forTest) ? kSecPolicyNameTestMobileStore : kSecPolicyNameMobileStore, 2801 options), errOut); 2802 2803 errOut: 2804 CFReleaseSafe(options); 2805 return result; 2806 } 2807 2808 SecPolicyRef SecPolicyCreateMobileStoreSigner(void) 2809 { 2810 return CreateMobileStoreSigner(false); 2811 } 2812 2813 SecPolicyRef SecPolicyCreateTestMobileStoreSigner(void) 2814 { 2815 return CreateMobileStoreSigner(true); 2816 } 2817 2818 2819 CF_RETURNS_RETAINED SecPolicyRef SecPolicyCreateEscrowServiceSigner(void) 2820 { 2821 SecPolicyRef result = NULL; 2822 CFMutableDictionaryRef options = NULL; 2823 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, 2824 &kCFTypeDictionaryKeyCallBacks, 2825 &kCFTypeDictionaryValueCallBacks), errOut); 2826 2827 // X509, ignoring date validity 2828 SecPolicyAddBasicCertOptions(options); 2829 2830 add_ku(options, kSecKeyUsageKeyEncipherment); 2831 2832 /* Leaf has marker OID with value that can't be pre-determined */ 2833 add_element(options, kSecPolicyCheckLeafMarkerOidWithoutValueCheck, CFSTR("1.2.840.113635.100.6.23.1")); 2834 require(SecPolicyAddChainLengthOptions(options, 2), errOut); 2835 2836 require(result = SecPolicyCreate(kSecPolicyAppleEscrowService, 2837 kSecPolicyNameEscrowService, options), errOut); 2838 2839 errOut: 2840 CFReleaseSafe(options); 2841 return result; 2842 } 2843 2844 CF_RETURNS_RETAINED SecPolicyRef SecPolicyCreatePCSEscrowServiceSigner(void) 2845 { 2846 SecPolicyRef result = NULL; 2847 CFMutableDictionaryRef options = NULL; 2848 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, 2849 &kCFTypeDictionaryKeyCallBacks, 2850 &kCFTypeDictionaryValueCallBacks), errOut); 2851 2852 SecPolicyAddBasicX509Options(options); 2853 add_ku(options, kSecKeyUsageKeyEncipherment); 2854 2855 /* Leaf has marker OID with value that can't be pre-determined */ 2856 add_element(options, kSecPolicyCheckLeafMarkerOidWithoutValueCheck, CFSTR("1.2.840.113635.100.6.23.1")); 2857 require(SecPolicyAddChainLengthOptions(options, 2), errOut); 2858 2859 require(result = SecPolicyCreate(kSecPolicyApplePCSEscrowService, 2860 kSecPolicyNamePCSEscrowService, options), errOut); 2861 2862 errOut: 2863 CFReleaseSafe(options); 2864 return result; 2865 } 2866 2867 SecPolicyRef SecPolicyCreateConfigurationProfileSigner(void) 2868 { 2869 SecPolicyRef result = NULL; 2870 CFMutableDictionaryRef options = NULL; 2871 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, 2872 &kCFTypeDictionaryKeyCallBacks, 2873 &kCFTypeDictionaryValueCallBacks), errOut); 2874 2875 SecPolicyAddBasicX509Options(options); 2876 require(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameProfileSigner), errOut); 2877 2878 //Chain length 3 2879 require(SecPolicyAddChainLengthOptions(options, 3), errOut); 2880 2881 // Require the profile signing EKU 2882 add_eku(options, &oidAppleExtendedKeyUsageProfileSigning); 2883 2884 CFStringRef releaseType = MGCopyAnswer(kMGQReleaseType, NULL); 2885 if (releaseType != NULL) { 2886 // all non-GM variants (beta, carrier, internal, etc) allow the QA signer as well 2887 add_eku(options, &oidAppleExtendedKeyUsageQAProfileSigning); 2888 } 2889 CFReleaseNull(releaseType); 2890 2891 // Require the Apple Application Integration CA marker OID 2892 add_element(options, kSecPolicyCheckIntermediateMarkerOid, CFSTR("1.2.840.113635.100.6.2.3")); 2893 2894 require(result = SecPolicyCreate(kSecPolicyAppleProfileSigner, 2895 kSecPolicyNameProfileSigner, 2896 options), errOut); 2897 2898 errOut: 2899 CFReleaseSafe(options); 2900 return result; 2901 } 2902 2903 SecPolicyRef SecPolicyCreateQAConfigurationProfileSigner(void) 2904 { 2905 return SecPolicyCreateConfigurationProfileSigner(); 2906 } 2907 2908 SecPolicyRef SecPolicyCreateOSXProvisioningProfileSigning(void) 2909 { 2910 SecPolicyRef result = NULL; 2911 CFMutableDictionaryRef options = NULL; 2912 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, 2913 &kCFTypeDictionaryKeyCallBacks, 2914 &kCFTypeDictionaryValueCallBacks), errOut); 2915 // Require valid chain from the Apple root 2916 SecPolicyAddBasicX509Options(options); 2917 SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameOSXProvisioningProfileSigning); 2918 2919 // Require provisioning profile leaf marker OID (1.2.840.113635.100.4.11) 2920 add_leaf_marker(options, &oidAppleCertExtOSXProvisioningProfileSigning); 2921 2922 // Require intermediate marker OID (1.2.840.113635.100.6.2.1) 2923 add_oid(options, kSecPolicyCheckIntermediateMarkerOid, &oidAppleIntmMarkerAppleWWDR); 2924 2925 // Require key usage that allows signing 2926 add_ku(options, kSecKeyUsageDigitalSignature); 2927 2928 // Ensure that revocation is checked (OCSP) 2929 CFDictionaryAddValue(options, kSecPolicyCheckRevocation, kSecPolicyCheckRevocationOCSP); 2930 2931 require(result = SecPolicyCreate(kSecPolicyAppleOSXProvisioningProfileSigning, 2932 kSecPolicyNameOSXProvisioningProfileSigning, options), errOut); 2933 2934 errOut: 2935 CFReleaseSafe(options); 2936 return result; 2937 } 2938 2939 /*! 2940 @function SecPolicyCreateAppleSMPEncryption 2941 @abstract Check for intermediate certificate 'Apple System Integration CA - G3' by name, 2942 and root certificate 'Apple Root CA - G3' by hash. 2943 Leaf cert must have Key Encipherment usage. 2944 Leaf cert must have Apple SMP Encryption marker OID (1.2.840.113635.100.6.30). 2945 Intermediate must have marker OID (1.2.840.113635.100.6.2.13). 2946 */ 2947 SecPolicyRef SecPolicyCreateAppleSMPEncryption(void) 2948 { 2949 SecPolicyRef result = NULL; 2950 CFMutableDictionaryRef options = NULL; 2951 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, 2952 &kCFTypeDictionaryKeyCallBacks, 2953 &kCFTypeDictionaryValueCallBacks), errOut); 2954 SecPolicyAddBasicCertOptions(options); 2955 2956 require(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameSMPEncryption), 2957 errOut); 2958 require(SecPolicyAddChainLengthOptions(options, 3), errOut); 2959 2960 CFDictionaryAddValue(options, kSecPolicyCheckIssuerCommonName, 2961 CFSTR("Apple System Integration CA - G3")); 2962 2963 // Check that leaf has extension with "Apple SMP Encryption" oid (1.2.840.113635.100.6.30) 2964 add_leaf_marker(options, &oidAppleCertExtAppleSMPEncryption); 2965 2966 // Check that intermediate has extension (1.2.840.113635.100.6.2.13) 2967 add_oid(options, kSecPolicyCheckIntermediateMarkerOid, &oidAppleIntmMarkerAppleSystemIntgG3); 2968 2969 add_ku(options, kSecKeyUsageKeyEncipherment); 2970 2971 // Ensure that revocation is checked (OCSP) 2972 CFDictionaryAddValue(options, kSecPolicyCheckRevocation, kSecPolicyCheckRevocationOCSP); 2973 2974 require(result = SecPolicyCreate(kSecPolicyAppleSMPEncryption, 2975 kSecPolicyNameSMPEncryption, options), errOut); 2976 2977 errOut: 2978 CFReleaseSafe(options); 2979 return result; 2980 } 2981 2982 /* subject:/CN=Test Apple Root CA - ECC/OU=Certification Authority/O=Apple Inc./C=US */ 2983 /* issuer :/CN=Test Apple Root CA - ECC/OU=Certification Authority/O=Apple Inc./C=US */ 2984 const uint8_t kTestAppleRootCA_ECC_SHA256[CC_SHA256_DIGEST_LENGTH] = { 2985 0xe8, 0x6a, 0xd6, 0x5c, 0x74, 0x60, 0x21, 0x14, 0x47, 0xc6, 0x6a, 0xd7, 0x5f, 0xf8, 0x06, 0x7b, 2986 0xec, 0xb5, 0x52, 0x7e, 0x4e, 0xa1, 0xac, 0x48, 0xcf, 0x3c, 0x53, 0x8f, 0x4d, 0x2b, 0x20, 0xa9 2987 }; 2988 2989 /*! 2990 @function SecPolicyCreateTestAppleSMPEncryption 2991 @abstract Check for intermediate certificate 'Test Apple System Integration CA - ECC' by name, 2992 and root certificate 'Test Apple Root CA - ECC' by hash. 2993 Leaf cert must have Key Encipherment usage. Other checks TBD. 2994 */ 2995 SecPolicyRef SecPolicyCreateTestAppleSMPEncryption(void) 2996 { 2997 SecPolicyRef result = NULL; 2998 CFMutableDictionaryRef options = NULL; 2999 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, 3000 &kCFTypeDictionaryKeyCallBacks, 3001 &kCFTypeDictionaryValueCallBacks), errOut); 3002 SecPolicyAddBasicCertOptions(options); 3003 3004 SecPolicyAddAnchorSHA256Options(options, kTestAppleRootCA_ECC_SHA256); 3005 require(SecPolicyAddChainLengthOptions(options, 3), errOut); 3006 3007 CFDictionaryAddValue(options, kSecPolicyCheckIssuerCommonName, 3008 CFSTR("Test Apple System Integration CA - ECC")); 3009 3010 add_ku(options, kSecKeyUsageKeyEncipherment); 3011 3012 // Ensure that revocation is checked (OCSP) 3013 CFDictionaryAddValue(options, kSecPolicyCheckRevocation, kSecPolicyCheckRevocationOCSP); 3014 3015 require(result = SecPolicyCreate(kSecPolicyAppleTestSMPEncryption, 3016 kSecPolicyNameTestSMPEncryption, options), errOut); 3017 3018 errOut: 3019 CFReleaseSafe(options); 3020 return result; 3021 } 3022 3023 3024 SecPolicyRef SecPolicyCreateAppleIDValidationRecordSigningPolicy(void) 3025 { 3026 SecPolicyRef result = NULL; 3027 CFMutableDictionaryRef options = NULL; 3028 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, 3029 &kCFTypeDictionaryKeyCallBacks, 3030 &kCFTypeDictionaryValueCallBacks), errOut); 3031 3032 //Leaf appears to be a SSL only cert, so policy should expand on that policy 3033 SecPolicyAddBasicX509Options(options); 3034 3035 // Apple CA anchored 3036 require(SecPolicyAddAppleAnchorOptions(options, 3037 kSecPolicyNameIDValidationRecordSigning), 3038 errOut); 3039 3040 // Check for an extension with " Apple ID Validation Record Signing" oid (1.2.840.113635.100.6.25) 3041 add_leaf_marker(options, &oidAppleCertExtensionAppleIDRecordValidationSigning); 3042 3043 // and validate that intermediate has extension 3044 // Application Integration Intermediate Certificate (1.2.840.113635.100.6.2.3) 3045 // and also validate that intermediate has extension 3046 // System Integration 2 Intermediate Certificate (1.2.840.113635.100.6.2.10) 3047 add_oid(options, kSecPolicyCheckIntermediateMarkerOid, &oidAppleIntmMarkerAppleID); 3048 add_oid(options, kSecPolicyCheckIntermediateMarkerOid, &oidAppleIntmMarkerAppleSystemIntg2); 3049 3050 // Ensure that revocation is checked (OCSP) 3051 CFDictionaryAddValue(options, kSecPolicyCheckRevocation, kSecPolicyCheckRevocationOCSP); 3052 3053 require(result = SecPolicyCreate(kSecPolicyAppleIDValidationRecordSigning, 3054 kSecPolicyNameIDValidationRecordSigning, options), errOut); 3055 3056 errOut: 3057 CFReleaseSafe(options); 3058 return result; 3059 } 3060 3061 /*! 3062 @function SecPolicyCreateAppleServerAuthCommon 3063 @abstract Generic policy for server authentication Sub CAs 3064 3065 Allows control for both if pinning is required at all and if UAT environments should be added 3066 to the trust policy. 3067 3068 No pinning is for developer/QA that needs to use proxy to debug the protocol, while UAT 3069 environment is for QA/internal developer that have no need allow fake servers. 3070 3071 Both the noPinning and UAT are gated on that you run on internal hardware. 3072 3073 */ 3074 3075 static SecPolicyRef 3076 SecPolicyCreateAppleServerAuthCommon(CFStringRef hostname, 3077 CFDictionaryRef __unused context, 3078 CFStringRef policyOID, CFStringRef service, 3079 const DERItem *leafMarkerOID, 3080 const DERItem *UATLeafMarkerOID) 3081 { 3082 CFMutableDictionaryRef options = NULL; 3083 SecPolicyRef result = NULL; 3084 CFDataRef oid = NULL, uatoid = NULL; 3085 3086 options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); 3087 require(options, errOut); 3088 3089 SecPolicyAddBasicX509Options(options); 3090 3091 require(hostname, errOut); 3092 CFDictionaryAddValue(options, kSecPolicyCheckSSLHostname, hostname); 3093 3094 CFDictionaryAddValue(options, kSecPolicyCheckBlackListedLeaf, kCFBooleanTrue); 3095 CFDictionaryAddValue(options, kSecPolicyCheckGrayListedLeaf, kCFBooleanTrue); 3096 3097 add_eku(options, &oidExtendedKeyUsageServerAuth); 3098 3099 if (requireUATPinning(service)) { 3100 3101 /* 3102 * Require pinning to the Apple CA's. 3103 */ 3104 SecPolicyAddAppleAnchorOptions(options, service); 3105 3106 /* old-style leaf marker OIDs */ 3107 if (UATLeafMarkerOID) { 3108 add_leaf_prod_qa_markers(options, leafMarkerOID, UATLeafMarkerOID); 3109 } else { 3110 add_leaf_marker(options, leafMarkerOID); 3111 } 3112 3113 /* new-style leaf marker OIDs */ 3114 CFStringRef leafMarkerOIDStr = NULL, UATLeafMarkerOIDStr = NULL; 3115 leafMarkerOIDStr = SecDERItemCopyOIDDecimalRepresentation(NULL, leafMarkerOID); 3116 if (UATLeafMarkerOID) { 3117 UATLeafMarkerOIDStr = SecDERItemCopyOIDDecimalRepresentation(NULL, UATLeafMarkerOID); 3118 } 3119 3120 if (leafMarkerOIDStr && UATLeafMarkerOIDStr) { 3121 add_leaf_prod_qa_markers_value_string(options, 3122 CFSTR("1.2.840.113635.100.6.48.1"), leafMarkerOIDStr, 3123 CFSTR("1.2.840.113635.100.6.48.1"), UATLeafMarkerOIDStr); 3124 } else if (leafMarkerOIDStr) { 3125 add_leaf_marker_value_string(options, CFSTR("1.2.840.113635.100.6.48.1"), leafMarkerOIDStr); 3126 } 3127 3128 CFReleaseNull(leafMarkerOIDStr); 3129 CFReleaseNull(UATLeafMarkerOIDStr); 3130 3131 add_oid(options, kSecPolicyCheckIntermediateMarkerOid, &oidAppleIntmMarkerAppleServerAuthentication); 3132 } 3133 3134 /* Check for weak hashes and keys */ 3135 require(SecPolicyRemoveWeakHashOptions(options), errOut); 3136 require(SecPolicyAddStrongKeySizeOptions(options), errOut); 3137 3138 CFDictionaryAddValue(options, kSecPolicyCheckRevocation, kSecPolicyCheckRevocationAny); 3139 3140 result = SecPolicyCreate(policyOID, service, options); 3141 require(result, errOut); 3142 3143 errOut: 3144 CFReleaseSafe(options); 3145 CFReleaseSafe(oid); 3146 CFReleaseSafe(uatoid); 3147 return result; 3148 } 3149 3150 /*! 3151 @function SecPolicyCreateAppleIDSService 3152 @abstract Ensure we're appropriately pinned to the IDS service (SSL + Apple restrictions) 3153 */ 3154 SecPolicyRef SecPolicyCreateAppleIDSService(CFStringRef hostname) 3155 { 3156 return SecPolicyCreateAppleServerAuthCommon(hostname, NULL, kSecPolicyAppleIDSService, 3157 kSecPolicyNameAppleIDSBag, 3158 &oidAppleCertExtAppleServerAuthenticationIDSProd, 3159 &oidAppleCertExtAppleServerAuthenticationIDSProdQA); 3160 } 3161 3162 /*! 3163 @function SecPolicyCreateAppleIDSService 3164 @abstract Ensure we're appropriately pinned to the IDS service (SSL + Apple restrictions) 3165 */ 3166 SecPolicyRef SecPolicyCreateAppleIDSServiceContext(CFStringRef hostname, CFDictionaryRef context) 3167 { 3168 return SecPolicyCreateAppleServerAuthCommon(hostname, context, kSecPolicyAppleIDSServiceContext, 3169 kSecPolicyNameAppleIDSService, 3170 &oidAppleCertExtAppleServerAuthenticationIDSProd, 3171 &oidAppleCertExtAppleServerAuthenticationIDSProdQA); 3172 } 3173 3174 /*! 3175 @function SecPolicyCreateAppleGSService 3176 @abstract Ensure we're appropriately pinned to the GS service 3177 */ 3178 SecPolicyRef SecPolicyCreateAppleGSService(CFStringRef hostname, CFDictionaryRef context) 3179 { 3180 return SecPolicyCreateAppleServerAuthCommon(hostname, context, kSecPolicyAppleGSService, 3181 kSecPolicyNameAppleGSService, 3182 &oidAppleCertExtAppleServerAuthenticationGS, 3183 NULL); 3184 } 3185 3186 /*! 3187 @function SecPolicyCreateApplePushService 3188 @abstract Ensure we're appropriately pinned to the Push service (SSL + Apple restrictions) 3189 */ 3190 SecPolicyRef SecPolicyCreateApplePushService(CFStringRef hostname, CFDictionaryRef context) 3191 { 3192 return SecPolicyCreateAppleServerAuthCommon(hostname, context, kSecPolicyApplePushService, 3193 kSecPolicyNameApplePushService, 3194 &oidAppleCertExtAppleServerAuthenticationAPNProd, 3195 &oidAppleCertExtAppleServerAuthenticationAPNProdQA); 3196 } 3197 3198 /*! 3199 @function SecPolicyCreateApplePPQService 3200 @abstract Ensure we're appropriately pinned to the PPQ service (SSL + Apple restrictions) 3201 */ 3202 SecPolicyRef SecPolicyCreateApplePPQService(CFStringRef hostname, CFDictionaryRef context) 3203 { 3204 return SecPolicyCreateAppleServerAuthCommon(hostname, context, kSecPolicyApplePPQService, 3205 kSecPolicyNameApplePPQService, 3206 &oidAppleCertExtAppleServerAuthenticationPPQProd , 3207 &oidAppleCertExtAppleServerAuthenticationPPQProdQA); 3208 } 3209 3210 /*! 3211 @function SecPolicyCreateAppleAST2Service 3212 @abstract Ensure we're appropriately pinned to the AST2 Diagnostic service (SSL + Apple restrictions) 3213 */ 3214 SecPolicyRef SecPolicyCreateAppleAST2Service(CFStringRef hostname, CFDictionaryRef context) 3215 { 3216 return SecPolicyCreateAppleServerAuthCommon(hostname, context, kSecPolicyAppleAST2DiagnosticsServerAuth, 3217 kSecPolicyNameAppleAST2Service, 3218 &oidAppleCertExtAST2DiagnosticsServerAuthProd, 3219 &oidAppleCertExtAST2DiagnosticsServerAuthProdQA); 3220 } 3221 3222 /*! 3223 @function SecPolicyCreateAppleEscrowProxyService 3224 @abstract Ensure we're appropriately pinned to the iCloud Escrow Proxy service (SSL + Apple restrictions) 3225 */ 3226 SecPolicyRef SecPolicyCreateAppleEscrowProxyService(CFStringRef hostname, CFDictionaryRef context) 3227 { 3228 return SecPolicyCreateAppleServerAuthCommon(hostname, context, kSecPolicyAppleEscrowProxyServerAuth, 3229 kSecPolicyNameAppleEscrowProxyService, 3230 &oidAppleCertExtEscrowProxyServerAuthProd, 3231 &oidAppleCertExtEscrowProxyServerAuthProdQA); 3232 } 3233 3234 /* subject:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA */ 3235 /* SKID: C0:7A:98:68:8D:89:FB:AB:05:64:0C:11:7D:AA:7D:65:B8:CA:CC:4E */ 3236 /* Not Before: May 21 04:00:00 2002 GMT, Not After : May 21 04:00:00 2022 GMT */ 3237 /* Signature Algorithm: sha1WithRSAEncryption */ 3238 unsigned char GeoTrust_Global_CA_sha256[kSecPolicySHA256Size] = { 3239 0xff, 0x85, 0x6a, 0x2d, 0x25, 0x1d, 0xcd, 0x88, 0xd3, 0x66, 0x56, 0xf4, 0x50, 0x12, 0x67, 0x98, 3240 0xcf, 0xab, 0xaa, 0xde, 0x40, 0x79, 0x9c, 0x72, 0x2d, 0xe4, 0xd2, 0xb5, 0xdb, 0x36, 0xa7, 0x3a 3241 }; 3242 3243 static SecPolicyRef SecPolicyCreateAppleGeoTrustServerAuthCommon(CFStringRef hostname, CFStringRef policyOid, 3244 CFStringRef policyName, 3245 CFStringRef leafMarkerOid, 3246 CFStringRef qaLeafMarkerOid) { 3247 CFMutableDictionaryRef options = NULL; 3248 CFDataRef spkiDigest = NULL; 3249 SecPolicyRef result = NULL; 3250 3251 require(options = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, 3252 &kCFTypeDictionaryValueCallBacks), errOut); 3253 3254 /* basic SSL */ 3255 SecPolicyAddBasicX509Options(options); 3256 3257 require(hostname, errOut); 3258 CFDictionaryAddValue(options, kSecPolicyCheckSSLHostname, hostname); 3259 3260 add_eku(options, &oidExtendedKeyUsageServerAuth); 3261 3262 /* pinning */ 3263 if (requireUATPinning(policyName)) { 3264 /* GeoTrust root */ 3265 SecPolicyAddAnchorSHA256Options(options, GeoTrust_Global_CA_sha256); 3266 3267 /* Issued to Apple Inc. in the US */ 3268 add_element(options, kSecPolicyCheckIntermediateCountry, CFSTR("US")); 3269 add_element(options, kSecPolicyCheckIntermediateOrganization, CFSTR("Apple Inc.")); 3270 3271 require_action(SecPolicyAddChainLengthOptions(options, 3), errOut, CFReleaseNull(result)); 3272 3273 /* Marker OIDs in both formats */ 3274 if (qaLeafMarkerOid) { 3275 add_leaf_prod_qa_markers_string(options, leafMarkerOid, qaLeafMarkerOid); 3276 add_leaf_prod_qa_markers_value_string(options, 3277 CFSTR("1.2.840.113635.100.6.48.1"), leafMarkerOid, 3278 CFSTR("1.2.840.113635.100.6.48.1"), qaLeafMarkerOid); 3279 } else { 3280 add_leaf_marker_string(options, leafMarkerOid); 3281 add_leaf_marker_value_string(options, CFSTR("1.2.840.113635.100.6.48.1"), leafMarkerOid); 3282 } 3283 } 3284 3285 /* Check for weak hashes */ 3286 require(SecPolicyRemoveWeakHashOptions(options), errOut); 3287 require(SecPolicyAddStrongKeySizeOptions(options), errOut); 3288 3289 /* See <rdar://25344801> for more details */ 3290 3291 result = SecPolicyCreate(policyOid, policyName, options); 3292 3293 errOut: 3294 CFReleaseSafe(options); 3295 CFReleaseSafe(spkiDigest); 3296 return result; 3297 } 3298 3299 SecPolicyRef SecPolicyCreateAppleCompatibilityEscrowProxyService(CFStringRef hostname) { 3300 return SecPolicyCreateAppleGeoTrustServerAuthCommon(hostname, kSecPolicyAppleEscrowProxyCompatibilityServerAuth, 3301 kSecPolicyNameAppleEscrowProxyService, 3302 CFSTR("1.2.840.113635.100.6.27.7.2"), 3303 CFSTR("1.2.840.113635.100.6.27.7.1")); 3304 } 3305 3306 /*! 3307 @function SecPolicyCreateAppleFMiPService 3308 @abstract Ensure we're appropriately pinned to the Find My iPhone service (SSL + Apple restrictions) 3309 */ 3310 SecPolicyRef SecPolicyCreateAppleFMiPService(CFStringRef hostname, CFDictionaryRef context) 3311 { 3312 return SecPolicyCreateAppleServerAuthCommon(hostname, context, kSecPolicyAppleFMiPServerAuth, 3313 kSecPolicyNameAppleFMiPService, 3314 &oidAppleCertExtFMiPServerAuthProd, 3315 &oidAppleCertExtFMiPServerAuthProdQA); 3316 } 3317 3318 3319 /* should use verbatim copy, but since this is the deprecated way, don't care right now */ 3320 static const UInt8 entrustSPKIL1C[kSecPolicySHA256Size] = { 3321 0x54, 0x5b, 0xf9, 0x35, 0xe9, 0xad, 0xa1, 0xda, 3322 0x11, 0x7e, 0xdc, 0x3c, 0x2a, 0xcb, 0xc5, 0x6f, 3323 0xc0, 0x28, 0x09, 0x6c, 0x0e, 0x24, 0xbe, 0x9b, 3324 0x38, 0x94, 0xbe, 0x52, 0x2d, 0x1b, 0x43, 0xde 3325 }; 3326 3327 /*! 3328 @function SecPolicyCreateApplePushServiceLegacy 3329 @abstract Ensure we're appropriately pinned to the Push service (via Entrust) 3330 */ 3331 SecPolicyRef SecPolicyCreateApplePushServiceLegacy(CFStringRef hostname) 3332 { 3333 CFMutableDictionaryRef options = NULL; 3334 SecPolicyRef result = NULL; 3335 CFDataRef digest = NULL; 3336 3337 digest = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, entrustSPKIL1C, sizeof(entrustSPKIL1C), kCFAllocatorNull); 3338 require(digest, errOut); 3339 3340 options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); 3341 require(options, errOut); 3342 3343 SecPolicyAddBasicX509Options(options); 3344 3345 CFDictionaryAddValue(options, kSecPolicyCheckSSLHostname, hostname); 3346 3347 CFDictionaryAddValue(options, kSecPolicyCheckBlackListedLeaf, kCFBooleanTrue); 3348 CFDictionaryAddValue(options, kSecPolicyCheckGrayListedLeaf, kCFBooleanTrue); 3349 3350 CFDictionaryAddValue(options, kSecPolicyCheckIntermediateSPKISHA256, digest); 3351 3352 add_eku(options, &oidExtendedKeyUsageServerAuth); 3353 3354 /* Check for weak hashes and keys */ 3355 require(SecPolicyRemoveWeakHashOptions(options), errOut); 3356 require(SecPolicyAddStrongKeySizeOptions(options), errOut); 3357 3358 CFDictionaryAddValue(options, kSecPolicyCheckRevocation, kSecPolicyCheckRevocationAny); 3359 3360 result = SecPolicyCreate(kSecPolicyAppleLegacyPushService, 3361 kSecPolicyNameLegacyPushService, options); 3362 require(result, errOut); 3363 3364 errOut: 3365 CFReleaseSafe(digest); 3366 CFReleaseSafe(options); 3367 return result; 3368 } 3369 3370 /*! 3371 @function SecPolicyCreateAppleMMCSService 3372 @abstract Ensure we're appropriately pinned to the IDS service (SSL + Apple restrictions) 3373 */ 3374 SecPolicyRef SecPolicyCreateAppleMMCSService(CFStringRef hostname, CFDictionaryRef context) 3375 { 3376 return SecPolicyCreateAppleServerAuthCommon(hostname, context, kSecPolicyAppleMMCService, 3377 kSecPolicyNameAppleMMCSService, 3378 &oidAppleCertExtAppleServerAuthenticationMMCSProd, 3379 &oidAppleCertExtAppleServerAuthenticationMMCSProdQA); 3380 } 3381 3382 SecPolicyRef SecPolicyCreateAppleCompatibilityMMCSService(CFStringRef hostname) { 3383 return SecPolicyCreateAppleGeoTrustServerAuthCommon(hostname, kSecPolicyAppleMMCSCompatibilityServerAuth, 3384 kSecPolicyNameAppleMMCSService, 3385 CFSTR("1.2.840.113635.100.6.27.11.2"), 3386 CFSTR("1.2.840.113635.100.6.27.11.1")); 3387 } 3388 3389 3390 SecPolicyRef SecPolicyCreateAppleiCloudSetupService(CFStringRef hostname, CFDictionaryRef context) 3391 { 3392 return SecPolicyCreateAppleServerAuthCommon(hostname, context, kSecPolicyAppleiCloudSetupServerAuth, 3393 kSecPolicyNameAppleiCloudSetupService, 3394 &oidAppleCertExtAppleServerAuthenticationiCloudSetupProd, 3395 &oidAppleCertExtAppleServerAuthenticationiCloudSetupProdQA); 3396 } 3397 3398 SecPolicyRef SecPolicyCreateAppleCompatibilityiCloudSetupService(CFStringRef hostname) 3399 { 3400 return SecPolicyCreateAppleGeoTrustServerAuthCommon(hostname, kSecPolicyAppleiCloudSetupCompatibilityServerAuth, 3401 kSecPolicyNameAppleiCloudSetupService, 3402 CFSTR("1.2.840.113635.100.6.27.15.2"), 3403 CFSTR("1.2.840.113635.100.6.27.15.1")); 3404 } 3405 3406 /*! 3407 @function SecPolicyCreateAppleSSLService 3408 @abstract Ensure we're appropriately pinned to an Apple server (SSL + Apple restrictions) 3409 */ 3410 SecPolicyRef SecPolicyCreateAppleSSLService(CFStringRef hostname) 3411 { 3412 // SSL server, pinned to an Apple intermediate 3413 SecPolicyRef policy = SecPolicyCreateSSL(true, hostname); 3414 CFMutableDictionaryRef options = NULL; 3415 require(policy, errOut); 3416 3417 // change options for SSL policy evaluation 3418 require((options=(CFMutableDictionaryRef)policy->_options) != NULL, errOut); 3419 3420 // Apple CA anchored 3421 require(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameServerAuthentication), errOut); 3422 3423 // Check leaf for Apple Server Authentication marker oid (1.2.840.113635.100.6.27.1) 3424 add_leaf_marker(options, &oidAppleCertExtAppleServerAuthentication); 3425 3426 // Check intermediate for Apple Server Authentication intermediate marker (1.2.840.113635.100.6.2.12) 3427 add_oid(options, kSecPolicyCheckIntermediateMarkerOid, &oidAppleIntmMarkerAppleServerAuthentication); 3428 3429 /* Check for weak hashes */ 3430 require(SecPolicyRemoveWeakHashOptions(options), errOut); 3431 3432 CFDictionaryAddValue(options, kSecPolicyCheckRevocation, kSecPolicyCheckRevocationAny); 3433 3434 SecPolicySetOid(policy, kSecPolicyAppleServerAuthentication); 3435 SecPolicySetName(policy, kSecPolicyNameServerAuthentication); 3436 3437 return policy; 3438 3439 errOut: 3440 CFReleaseSafe(options); 3441 CFReleaseSafe(policy); 3442 return NULL; 3443 } 3444 3445 /*! 3446 @function SecPolicyCreateApplePPQSigning 3447 @abstract Check for intermediate certificate 'Apple System Integration 2 Certification Authority' by name, 3448 and apple anchor. 3449 Leaf cert must have Digital Signature usage. 3450 Leaf cert must have Apple PPQ Signing marker OID (1.2.840.113635.100.6.38.2). 3451 Intermediate must have marker OID (1.2.840.113635.100.6.2.10). 3452 */ 3453 SecPolicyRef SecPolicyCreateApplePPQSigning(void) 3454 { 3455 SecPolicyRef result = NULL; 3456 CFMutableDictionaryRef options = NULL; 3457 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, 3458 &kCFTypeDictionaryKeyCallBacks, 3459 &kCFTypeDictionaryValueCallBacks), errOut); 3460 SecPolicyAddBasicCertOptions(options); 3461 3462 SecPolicyAddAppleAnchorOptions(options, kSecPolicyNamePPQSigning); 3463 require(SecPolicyAddChainLengthOptions(options, 3), errOut); 3464 3465 CFDictionaryAddValue(options, kSecPolicyCheckIssuerCommonName, 3466 CFSTR("Apple System Integration 2 Certification Authority")); 3467 3468 // Check that leaf has extension with "Apple PPQ Signing" prod oid (1.2.840.113635.100.6.38.2) 3469 add_leaf_marker(options, &oidAppleCertExtApplePPQSigningProd); 3470 3471 // Check that intermediate has extension (1.2.840.113635.100.6.2.10) 3472 add_oid(options, kSecPolicyCheckIntermediateMarkerOid, &oidAppleIntmMarkerAppleSystemIntg2); 3473 3474 add_ku(options, kSecKeyUsageDigitalSignature); 3475 3476 require(result = SecPolicyCreate(kSecPolicyApplePPQSigning, 3477 kSecPolicyNamePPQSigning, options), errOut); 3478 3479 errOut: 3480 CFReleaseSafe(options); 3481 return result; 3482 } 3483 3484 /*! 3485 @function SecPolicyCreateTestApplePPQSigning 3486 @abstract Check for intermediate certificate 'Apple System Integration 2 Certification Authority' by name, 3487 and apple anchor. 3488 Leaf cert must have Digital Signature usage. 3489 Leaf cert must have Apple PPQ Signing Test marker OID (1.2.840.113635.100.6.38.1). 3490 Intermediate must have marker OID (1.2.840.113635.100.6.2.10). 3491 */ 3492 SecPolicyRef SecPolicyCreateTestApplePPQSigning(void) 3493 { 3494 /* Guard against use of test policy on production devices */ 3495 if (!SecIsInternalRelease()) { 3496 return SecPolicyCreateApplePPQSigning(); 3497 } 3498 3499 SecPolicyRef result = NULL; 3500 CFMutableDictionaryRef options = NULL; 3501 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, 3502 &kCFTypeDictionaryKeyCallBacks, 3503 &kCFTypeDictionaryValueCallBacks), errOut); 3504 SecPolicyAddBasicCertOptions(options); 3505 3506 SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameTestPPQSigning); 3507 require(SecPolicyAddChainLengthOptions(options, 3), errOut); 3508 3509 CFDictionaryAddValue(options, kSecPolicyCheckIssuerCommonName, 3510 CFSTR("Apple System Integration 2 Certification Authority")); 3511 3512 // Check that leaf has extension with "Apple PPQ Signing" test oid (1.2.840.113635.100.6.38.1) 3513 add_leaf_marker(options, &oidAppleCertExtApplePPQSigningProdQA); 3514 3515 // Check that intermediate has extension (1.2.840.113635.100.6.2.10) 3516 add_oid(options, kSecPolicyCheckIntermediateMarkerOid, &oidAppleIntmMarkerAppleSystemIntg2); 3517 3518 add_ku(options, kSecKeyUsageDigitalSignature); 3519 3520 require(result = SecPolicyCreate(kSecPolicyAppleTestPPQSigning, 3521 kSecPolicyNameTestPPQSigning, options), errOut); 3522 3523 errOut: 3524 CFReleaseSafe(options); 3525 return result; 3526 } 3527 /*! 3528 @function SecPolicyCreateAppleTimeStamping 3529 @abstract Check for RFC3161 timestamping EKU. 3530 */ 3531 SecPolicyRef SecPolicyCreateAppleTimeStamping(void) 3532 { 3533 SecPolicyRef result = NULL; 3534 CFMutableDictionaryRef options = NULL; 3535 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, 3536 &kCFTypeDictionaryKeyCallBacks, 3537 &kCFTypeDictionaryValueCallBacks), errOut); 3538 3539 SecPolicyAddBasicX509Options(options); 3540 3541 /* Require id-kp-timeStamping extendedKeyUsage to be present. */ 3542 add_eku(options, &oidExtendedKeyUsageTimeStamping); 3543 3544 require(result = SecPolicyCreate(kSecPolicyAppleTimeStamping, 3545 kSecPolicyNameTimeStamping, options), errOut); 3546 3547 errOut: 3548 CFReleaseSafe(options); 3549 return result; 3550 } 3551 3552 /*! 3553 @function SecPolicyCreateApplePayIssuerEncryption 3554 @abstract Check for intermediate certificate 'Apple Worldwide Developer Relations CA - G2' by name, 3555 and ECC apple anchor. 3556 Leaf cert must have Key Encipherment and Key Agreement usage. 3557 Leaf cert must have Apple Pay Issuer Encryption marker OID (1.2.840.113635.100.6.39). 3558 */ 3559 SecPolicyRef SecPolicyCreateApplePayIssuerEncryption(void) 3560 { 3561 SecPolicyRef result = NULL; 3562 CFMutableDictionaryRef options = NULL; 3563 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, 3564 &kCFTypeDictionaryKeyCallBacks, 3565 &kCFTypeDictionaryValueCallBacks), errOut); 3566 SecPolicyAddBasicCertOptions(options); 3567 3568 require(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNamePayIssuerEncryption), 3569 errOut); 3570 require(SecPolicyAddChainLengthOptions(options, 3), errOut); 3571 3572 CFDictionaryAddValue(options, kSecPolicyCheckIssuerCommonName, 3573 CFSTR("Apple Worldwide Developer Relations CA - G2")); 3574 3575 // Check that leaf has extension with "Apple Pay Issuer Encryption" oid (1.2.840.113635.100.6.39) 3576 add_leaf_marker(options, &oidAppleCertExtCryptoServicesExtEncryption); 3577 3578 add_ku(options, kSecKeyUsageKeyEncipherment); 3579 3580 require(result = SecPolicyCreate(kSecPolicyApplePayIssuerEncryption, 3581 kSecPolicyNamePayIssuerEncryption, options), errOut); 3582 3583 errOut: 3584 CFReleaseSafe(options); 3585 return result; 3586 } 3587 3588 /*! 3589 @function SecPolicyCreateAppleATVVPNProfileSigning 3590 @abstract Check for leaf marker OID 1.2.840.113635.100.6.43, 3591 intermediate marker OID 1.2.840.113635.100.6.2.10, 3592 chains to Apple Root CA, path length 3 3593 */ 3594 SecPolicyRef SecPolicyCreateAppleATVVPNProfileSigning(void) 3595 { 3596 SecPolicyRef result = NULL; 3597 CFMutableDictionaryRef options = NULL; 3598 CFMutableDictionaryRef appleAnchorOptions = NULL; 3599 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, 3600 &kCFTypeDictionaryKeyCallBacks, 3601 &kCFTypeDictionaryValueCallBacks), errOut); 3602 3603 SecPolicyAddBasicCertOptions(options); 3604 3605 // Require pinning to the Apple CAs (including test CA for internal releases) 3606 appleAnchorOptions = CFDictionaryCreateMutableForCFTypes(NULL); 3607 require(appleAnchorOptions, errOut); 3608 3609 if (SecIsInternalRelease()) { 3610 CFDictionarySetValue(appleAnchorOptions, 3611 kSecPolicyAppleAnchorIncludeTestRoots, kCFBooleanTrue); 3612 } 3613 3614 add_element(options, kSecPolicyCheckAnchorApple, appleAnchorOptions); 3615 3616 // Cert chain length 3 3617 require(SecPolicyAddChainLengthOptions(options, 3), errOut); 3618 3619 // Check leaf for Apple ATV VPN Profile Signing OID (1.2.840.113635.100.6.43) 3620 add_leaf_marker(options, &oidAppleCertExtATVVPNProfileSigning); 3621 3622 // Check intermediate for Apple System Integration 2 CA intermediate marker (1.2.840.113635.100.6.2.10) 3623 add_oid(options, kSecPolicyCheckIntermediateMarkerOid, &oidAppleIntmMarkerAppleSystemIntg2); 3624 3625 // Ensure that revocation is checked (OCSP only) 3626 CFDictionaryAddValue(options, kSecPolicyCheckRevocation, kSecPolicyCheckRevocationOCSP); 3627 3628 require(result = SecPolicyCreate(kSecPolicyAppleATVVPNProfileSigning, 3629 kSecPolicyNameATVVPNProfileSigning, options), errOut); 3630 3631 errOut: 3632 CFReleaseSafe(options); 3633 CFReleaseSafe(appleAnchorOptions); 3634 return result; 3635 } 3636 3637 SecPolicyRef SecPolicyCreateAppleHomeKitServerAuth(CFStringRef hostname) { 3638 CFMutableDictionaryRef options = NULL; 3639 SecPolicyRef result = NULL; 3640 CFDataRef oid = NULL; 3641 3642 options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); 3643 require(options, errOut); 3644 3645 SecPolicyAddBasicX509Options(options); 3646 3647 CFDictionaryAddValue(options, kSecPolicyCheckSSLHostname, hostname); 3648 3649 add_eku(options, &oidExtendedKeyUsageServerAuth); 3650 3651 if (requireUATPinning(kSecPolicyNameAppleHomeKitService)) { 3652 3653 // Cert chain length 3 3654 require(SecPolicyAddChainLengthOptions(options, 3), errOut); 3655 3656 // Apple anchors, allowing test anchors for internal release 3657 SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameAppleHomeKitService); 3658 3659 add_leaf_marker(options, &oidAppleCertExtHomeKitServerAuth); 3660 3661 add_oid(options, kSecPolicyCheckIntermediateMarkerOid, &oidAppleIntmMarkerAppleHomeKitServerCA); 3662 } 3663 3664 /* Check for weak hashes */ 3665 require(SecPolicyRemoveWeakHashOptions(options), errOut); 3666 require(SecPolicyAddStrongKeySizeOptions(options), errOut); 3667 3668 CFDictionaryAddValue(options, kSecPolicyCheckRevocation, kSecPolicyCheckRevocationAny); 3669 3670 result = SecPolicyCreate(kSecPolicyAppleHomeKitServerAuth, 3671 kSecPolicyNameAppleHomeKitService, options); 3672 require(result, errOut); 3673 3674 errOut: 3675 CFReleaseSafe(options); 3676 CFReleaseSafe(oid); 3677 return result; 3678 } 3679 3680 SecPolicyRef SecPolicyCreateAppleExternalDeveloper(void) { 3681 CFMutableDictionaryRef options = NULL; 3682 SecPolicyRef result = NULL; 3683 3684 /* Create basic Apple pinned policy */ 3685 require(result = SecPolicyCreateApplePinned(kSecPolicyNameExternalDeveloper, 3686 CFSTR("1.2.840.113635.100.6.2.1"), // WWDR Intermediate OID 3687 CFSTR("1.2.840.113635.100.6.1.2")), // "iPhone Developer" leaf OID 3688 errOut); 3689 3690 require_action(options = CFDictionaryCreateMutableCopy(NULL, 0, result->_options), errOut, CFReleaseNull(result)); 3691 3692 /* Additional intermediate OIDs */ 3693 add_element(options, kSecPolicyCheckIntermediateMarkerOid, 3694 CFSTR("1.2.840.113635.100.6.2.6")); // "Developer ID" Intermediate OID 3695 3696 /* Addtional leaf OIDS */ 3697 add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.6.1.4")); // "iPhone Distribution" leaf OID 3698 add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.6.1.5")); // "Safari Developer" leaf OID 3699 add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.6.1.7")); // "3rd Party Mac Developer Application" leaf OID 3700 add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.6.1.8")); // "3rd Party Mac Developer Installer" leaf OID 3701 add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.6.1.12")); // "Mac Developer" leaf OID 3702 add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.6.1.13")); // "Developer ID Application" leaf OID 3703 add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.6.1.14")); // "Developer ID Installer" leaf OID 3704 3705 /* Restrict EKUs */ 3706 add_eku_string(options, CFSTR("1.3.6.1.5.5.7.3.3")); // CodeSigning EKU 3707 add_eku_string(options, CFSTR("1.2.840.113635.100.4.8")); // "Safari Developer" EKU 3708 add_eku_string(options, CFSTR("1.2.840.113635.100.4.9")); // "3rd Party Mac Developer Installer" EKU 3709 add_eku_string(options, CFSTR("1.2.840.113635.100.4.13")); // "Developer ID Installer" EKU 3710 3711 CFReleaseSafe(result->_options); 3712 result->_options = CFRetainSafe(options); 3713 3714 SecPolicySetOid(result, kSecPolicyAppleExternalDeveloper); 3715 3716 errOut: 3717 CFReleaseSafe(options); 3718 return result; 3719 } 3720 3721 /* This one is special because the intermediate has no marker OID */ 3722 SecPolicyRef SecPolicyCreateAppleSoftwareSigning(void) { 3723 CFMutableDictionaryRef options = NULL; 3724 SecPolicyRef result = NULL; 3725 3726 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, 3727 &kCFTypeDictionaryKeyCallBacks, 3728 &kCFTypeDictionaryValueCallBacks), errOut); 3729 3730 SecPolicyAddBasicCertOptions(options); 3731 3732 /* Anchored to the Apple Roots */ 3733 require_quiet(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameSoftwareSigning), 3734 errOut); 3735 3736 /* Exactly 3 certs in the chain */ 3737 require(SecPolicyAddChainLengthOptions(options, 3), errOut); 3738 3739 /* Intermediate Common Name matches */ 3740 add_element(options, kSecPolicyCheckIssuerCommonName, CFSTR("Apple Code Signing Certification Authority")); 3741 3742 /* Leaf marker OID matches */ 3743 add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.6.22")); 3744 3745 /* Leaf has CodeSigning EKU */ 3746 add_eku_string(options, CFSTR("1.3.6.1.5.5.7.3.3")); 3747 3748 /* Check revocation using any available method */ 3749 add_element(options, kSecPolicyCheckRevocation, kSecPolicyCheckRevocationAny); 3750 3751 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */ 3752 require(SecPolicyAddStrongKeySizeOptions(options), errOut); 3753 3754 require(result = SecPolicyCreate(kSecPolicyAppleSoftwareSigning, 3755 kSecPolicyNameSoftwareSigning, options), errOut); 3756 3757 errOut: 3758 CFReleaseSafe(options); 3759 return result; 3760 } 3761 3762 /* subject:/CN=SEP Root CA/O=Apple Inc./ST=California */ 3763 /* SKID: 58:EF:D6:BE:C5:82:B0:54:CD:18:A6:84:AD:A2:F6:7B:7B:3A:7F:CF */ 3764 /* Not Before: Jun 24 21:43:24 2014 GMT, Not After : Jun 24 21:43:24 2029 GMT */ 3765 /* Signature Algorithm: ecdsa-with-SHA384 */ 3766 const uint8_t SEPRootCA_SHA256[kSecPolicySHA256Size] = { 3767 0xd1, 0xdf, 0x82, 0x00, 0xf3, 0x89, 0x4e, 0xe9, 0x96, 0xf3, 0x77, 0xdf, 0x76, 0x3b, 0x0a, 0x16, 3768 0x8f, 0xd9, 0x6c, 0x58, 0xc0, 0x3e, 0xc9, 0xb0, 0x5f, 0xa5, 0x64, 0x79, 0xc0, 0xe8, 0xc9, 0xe7 3769 }; 3770 3771 SecPolicyRef SecPolicyCreateAppleUniqueDeviceCertificate(CFDataRef testRootHash) { 3772 CFMutableDictionaryRef options = NULL; 3773 CFDictionaryRef keySizes = NULL; 3774 CFNumberRef ecSize = NULL; 3775 SecPolicyRef result = NULL; 3776 3777 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, 3778 &kCFTypeDictionaryKeyCallBacks, 3779 &kCFTypeDictionaryValueCallBacks), errOut); 3780 3781 /* Device certificate should never expire */ 3782 SecPolicyAddBasicCertOptions(options); 3783 3784 /* Anchored to the SEP Root CA. Allow alternative root for developers */ 3785 require(SecPolicyAddAnchorSHA256Options(options, SEPRootCA_SHA256),errOut); 3786 if (testRootHash && SecIsInternalRelease() && (kSecPolicySHA256Size == CFDataGetLength(testRootHash))) { 3787 add_element(options, kSecPolicyCheckAnchorSHA256, testRootHash); 3788 } 3789 3790 /* Exactly 3 certs in the chain */ 3791 require(SecPolicyAddChainLengthOptions(options, 3), errOut); 3792 3793 /* Intermediate has marker OID with value */ 3794 add_intermediate_marker_value_string(options, CFSTR("1.2.840.113635.100.6.44"), CFSTR("ucrt")); 3795 3796 /* Leaf has marker OID with varying value that can't be pre-determined */ 3797 add_element(options, kSecPolicyCheckLeafMarkerOidWithoutValueCheck, CFSTR("1.2.840.113635.100.10.1")); 3798 3799 /* RSA key sizes are disallowed. EC key sizes are P-256 or larger. */ 3800 require(ecSize = CFNumberCreateWithCFIndex(NULL, 256), errOut); 3801 require(keySizes = CFDictionaryCreate(NULL, (const void**)&kSecAttrKeyTypeEC, 3802 (const void**)&ecSize, 1, 3803 &kCFTypeDictionaryKeyCallBacks, 3804 &kCFTypeDictionaryValueCallBacks), errOut); 3805 add_element(options, kSecPolicyCheckKeySize, keySizes); 3806 3807 3808 require(result = SecPolicyCreate(kSecPolicyAppleUniqueDeviceIdentifierCertificate, 3809 kSecPolicyNameUniqueDeviceIdentifierCertificate, options), errOut); 3810 3811 errOut: 3812 CFReleaseSafe(options); 3813 CFReleaseSafe(keySizes); 3814 CFReleaseSafe(ecSize); 3815 return result; 3816 } 3817 3818 SecPolicyRef SecPolicyCreateAppleWarsaw(void) { 3819 CFMutableDictionaryRef options = NULL; 3820 SecPolicyRef result = NULL; 3821 3822 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, 3823 &kCFTypeDictionaryKeyCallBacks, 3824 &kCFTypeDictionaryValueCallBacks), errOut); 3825 3826 SecPolicyAddBasicX509Options(options); 3827 3828 /* Anchored to the Apple Roots. */ 3829 require_quiet(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameWarsaw), 3830 errOut); 3831 3832 /* Exactly 3 certs in the chain */ 3833 require(SecPolicyAddChainLengthOptions(options, 3), errOut); 3834 3835 /* Intermediate marker OID matches input OID */ 3836 add_element(options, kSecPolicyCheckIntermediateMarkerOid, CFSTR("1.2.840.113635.100.6.2.14")); 3837 3838 /* Leaf marker OID matches input OID */ 3839 add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.6.29")); 3840 3841 /* Check revocation using any available method */ 3842 add_element(options, kSecPolicyCheckRevocation, kSecPolicyCheckRevocationAny); 3843 3844 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */ 3845 require(SecPolicyAddStrongKeySizeOptions(options), errOut); 3846 3847 require(result = SecPolicyCreate(kSecPolicyAppleWarsaw, 3848 kSecPolicyNameWarsaw, options), errOut); 3849 3850 errOut: 3851 CFReleaseSafe(options); 3852 return result; 3853 } 3854 3855 SecPolicyRef SecPolicyCreateAppleSecureIOStaticAsset(void) { 3856 CFMutableDictionaryRef options = NULL; 3857 SecPolicyRef result = NULL; 3858 #if TARGET_OS_BRIDGE 3859 CFMutableDictionaryRef appleAnchorOptions = NULL; 3860 #endif 3861 3862 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, 3863 &kCFTypeDictionaryKeyCallBacks, 3864 &kCFTypeDictionaryValueCallBacks), errOut); 3865 3866 /* This certificate cannot expire so that assets always load */ 3867 SecPolicyAddBasicCertOptions(options); 3868 3869 /* Anchored to the Apple Roots. */ 3870 #if TARGET_OS_BRIDGE 3871 /* On the bridge, test roots are gated in the trust and policy servers. */ 3872 require_quiet(appleAnchorOptions = CFDictionaryCreateMutableForCFTypes(NULL), errOut); 3873 CFDictionarySetValue(appleAnchorOptions, 3874 kSecPolicyAppleAnchorIncludeTestRoots, kCFBooleanTrue); 3875 add_element(options, kSecPolicyCheckAnchorApple, appleAnchorOptions); 3876 CFReleaseSafe(appleAnchorOptions); 3877 #else 3878 require_quiet(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameSecureIOStaticAsset), 3879 errOut); 3880 #endif 3881 3882 /* Exactly 3 certs in the chain */ 3883 require(SecPolicyAddChainLengthOptions(options, 3), errOut); 3884 3885 /* Intermediate marker OID matches ASI CA */ 3886 add_element(options, kSecPolicyCheckIntermediateMarkerOid, CFSTR("1.2.840.113635.100.6.2.10")); 3887 3888 /* Leaf marker OID matches static IO OID */ 3889 add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.6.50")); 3890 3891 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */ 3892 require(SecPolicyAddStrongKeySizeOptions(options), errOut); 3893 3894 require(result = SecPolicyCreate(kSecPolicyAppleSecureIOStaticAsset, 3895 kSecPolicyNameSecureIOStaticAsset, options), errOut); 3896 3897 errOut: 3898 CFReleaseSafe(options); 3899 return result; 3900 } 3901 3902 SecPolicyRef SecPolicyCreateAppleAppTransportSecurity(void) { 3903 CFMutableDictionaryRef options = NULL; 3904 SecPolicyRef result = NULL; 3905 CFMutableArrayRef disallowedHashes = NULL; 3906 3907 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, 3908 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut); 3909 3910 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */ 3911 require(SecPolicyAddStrongKeySizeOptions(options), errOut); 3912 3913 /* Hash algorithm is SHA-256 or better */ 3914 require(disallowedHashes = CFArrayCreateMutable(NULL, 5, &kCFTypeArrayCallBacks), errOut); 3915 CFArrayAppendValue(disallowedHashes, kSecSignatureDigestAlgorithmMD2); 3916 CFArrayAppendValue(disallowedHashes, kSecSignatureDigestAlgorithmMD4); 3917 CFArrayAppendValue(disallowedHashes, kSecSignatureDigestAlgorithmMD5); 3918 CFArrayAppendValue(disallowedHashes, kSecSignatureDigestAlgorithmSHA1); 3919 CFArrayAppendValue(disallowedHashes, kSecSignatureDigestAlgorithmSHA224); 3920 3921 add_element(options, kSecPolicyCheckSignatureHashAlgorithms, disallowedHashes); 3922 3923 require_quiet(result = SecPolicyCreate(kSecPolicyAppleAppTransportSecurity, 3924 kSecPolicyNameAppTransportSecurity, 3925 options), errOut); 3926 3927 errOut: 3928 CFReleaseSafe(options); 3929 return result; 3930 } 3931 3932 SecPolicyRef SecPolicyCreateMobileSoftwareUpdate(void) { 3933 CFMutableDictionaryRef options = NULL; 3934 SecPolicyRef result = NULL; 3935 3936 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, 3937 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut); 3938 3939 /* No expiration check. */ 3940 SecPolicyAddBasicCertOptions(options); 3941 3942 /* Apple Anchor */ 3943 require_quiet(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameMobileSoftwareUpdate), 3944 errOut); 3945 3946 /* Exactly 3 certs in the chain */ 3947 require(SecPolicyAddChainLengthOptions(options, 3), errOut); 3948 3949 /* Intermediate marker OID is iPhone CA OID */ 3950 add_element(options, kSecPolicyCheckIntermediateMarkerOid, CFSTR("1.2.840.113635.100.6.2.18")); 3951 3952 /* Leaf marker OID is either the prod MSU OID, or, on internal builds, the prodQA OID */ 3953 add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.6.57.2")); 3954 if (SecIsInternalRelease()) { 3955 add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.6.57.1")); 3956 } 3957 3958 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */ 3959 require(SecPolicyAddStrongKeySizeOptions(options), errOut); 3960 3961 require(result = SecPolicyCreate(kSecPolicyAppleMobileSoftwareUpdate, 3962 kSecPolicyNameMobileSoftwareUpdate, options), errOut); 3963 3964 errOut: 3965 CFReleaseNull(options); 3966 return result; 3967 } 3968 3969 /* subject:/CN=Basic Attestation System Root CA/O=Apple Inc./ST=California */ 3970 /* SKID: FE:D1:D1:C2:08:07:03:D5:B9:3C:34:B2:BB:FD:7C:3A:99:25:1B:8F */ 3971 /* Not Before: Apr 20 00:22:09 2017 GMT, Not After : Mar 22 00:00:00 2032 GMT */ 3972 /* Signature Algorithm: ecdsa-with-SHA384 */ 3973 const uint8_t BASystemRootCA_SHA256[kSecPolicySHA256Size] = { 3974 0x10, 0xD3, 0xC8, 0x67, 0xF0, 0xAE, 0xFB, 0x24, 0x31, 0xA0, 0xA9, 0x7A, 0x88, 0x18, 0xBD, 0x64, 3975 0xF7, 0xF9, 0x0F, 0xFE, 0x11, 0x94, 0x48, 0x4F, 0xCA, 0x97, 0xF0, 0xF2, 0x9E, 0xCA, 0x00, 0x47 3976 }; 3977 3978 /* subject:/CN=Basic Attestation User Root CA/O=Apple Inc./ST=California */ 3979 /* SKID: 83:E5:A3:21:9E:B0:74:C3:F9:61:90:FD:97:4E:23:10:76:A4:A3:F2 */ 3980 /* Not Before: Apr 19 21:41:56 2017 GMT, Not After : Mar 22 00:00:00 2032 GMT */ 3981 /* Signature Algorithm: ecdsa-with-SHA384 */ 3982 const uint8_t BAUserRootCA_SHA256[kSecPolicySHA256Size] = { 3983 0x03, 0x75, 0x1c, 0x80, 0xfc, 0xbe, 0x58, 0x19, 0xd1, 0x70, 0xd2, 0x67, 0xce, 0x1a, 0xd6, 0xd0, 3984 0x94, 0x40, 0x7c, 0x91, 0xd8, 0x73, 0xd7, 0xa6, 0x56, 0x2d, 0xe3, 0x66, 0x6d, 0x35, 0x94, 0xc6 3985 }; 3986 3987 SecPolicyRef SecPolicyCreateAppleBasicAttestationSystem(CFDataRef testRootHash) { 3988 CFMutableDictionaryRef options = NULL; 3989 SecPolicyRef result = NULL; 3990 3991 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, 3992 &kCFTypeDictionaryKeyCallBacks, 3993 &kCFTypeDictionaryValueCallBacks), errOut); 3994 /* BAA certs expire */ 3995 SecPolicyAddBasicX509Options(options); 3996 3997 /* Anchored to one of the Basic Attestation roots. Allow alternative root for developers */ 3998 SecPolicyAddAnchorSHA256Options(options, BASystemRootCA_SHA256); 3999 if (testRootHash && SecIsInternalRelease() && (kSecPolicySHA256Size == CFDataGetLength(testRootHash))) { 4000 add_element(options, kSecPolicyCheckAnchorSHA256, testRootHash); 4001 } 4002 4003 /* Exactly 3 certs in the chain */ 4004 require(SecPolicyAddChainLengthOptions(options, 3), errOut); 4005 4006 require(result = SecPolicyCreate(kSecPolicyAppleBasicAttestationSystem, 4007 kSecPolicyNameBasicAttestationSystem, options), errOut); 4008 4009 errOut: 4010 CFReleaseSafe(options); 4011 return result; 4012 } 4013 4014 SecPolicyRef SecPolicyCreateAppleBasicAttestationUser(CFDataRef testRootHash) { 4015 CFMutableDictionaryRef options = NULL; 4016 SecPolicyRef result = NULL; 4017 4018 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, 4019 &kCFTypeDictionaryKeyCallBacks, 4020 &kCFTypeDictionaryValueCallBacks), errOut); 4021 /* BAA certs expire */ 4022 SecPolicyAddBasicX509Options(options); 4023 4024 /* Anchored to one of the Basic Attestation roots. Allow alternative root for developers */ 4025 SecPolicyAddAnchorSHA256Options(options, BAUserRootCA_SHA256); 4026 if (testRootHash && SecIsInternalRelease() && (kSecPolicySHA256Size == CFDataGetLength(testRootHash))) { 4027 add_element(options, kSecPolicyCheckAnchorSHA256, testRootHash); 4028 } 4029 4030 /* Exactly 3 certs in the chain */ 4031 require(SecPolicyAddChainLengthOptions(options, 3), errOut); 4032 4033 require(result = SecPolicyCreate(kSecPolicyAppleBasicAttestationUser, 4034 kSecPolicyNameBasicAttestationUser, options), errOut); 4035 4036 errOut: 4037 CFReleaseSafe(options); 4038 return result; 4039 } 4040 4041 SecPolicyRef SecPolicyCreateiAPSWAuthWithExpiration(bool checkExpiration) { 4042 CFMutableDictionaryRef options = NULL; 4043 SecPolicyRef result = NULL; 4044 4045 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, 4046 &kCFTypeDictionaryKeyCallBacks, 4047 &kCFTypeDictionaryValueCallBacks), errOut); 4048 4049 /* iAP checks expiration on developement certs, but not on production certs */ 4050 if (checkExpiration) { 4051 SecPolicyAddBasicX509Options(options); 4052 } else { 4053 SecPolicyAddBasicCertOptions(options); 4054 } 4055 4056 /* Exactly 2 certs in the chain */ 4057 require(SecPolicyAddChainLengthOptions(options, 2), errOut); 4058 4059 /* iAP SW Auth General Capabilities Extension present */ 4060 add_element(options, kSecPolicyCheckLeafMarkerOidWithoutValueCheck, CFSTR("1.2.840.113635.100.6.59.1")); 4061 4062 require(result = SecPolicyCreate(kSecPolicyAppleiAPSWAuth, 4063 kSecPolicyNameiAPSWAuth, options), errOut); 4064 4065 errOut: 4066 CFReleaseSafe(options); 4067 return result; 4068 } 4069 4070 SecPolicyRef SecPolicyCreateiAPSWAuth(void) { 4071 /* By default, iAP SW Auth certs don't expire */ 4072 return SecPolicyCreateiAPSWAuthWithExpiration(false); 4073 } 4074 4075 SecPolicyRef SecPolicyCreateDemoDigitalCatalogSigning(void) { 4076 CFMutableDictionaryRef options = NULL; 4077 SecPolicyRef result = NULL; 4078 4079 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, 4080 &kCFTypeDictionaryKeyCallBacks, 4081 &kCFTypeDictionaryValueCallBacks), errOut); 4082 SecPolicyAddBasicX509Options(options); 4083 4084 /* Exactly 3 certs in the chain */ 4085 require(SecPolicyAddChainLengthOptions(options, 3), errOut); 4086 4087 /* Demo Signing Extension present in leaf */ 4088 add_element(options, kSecPolicyCheckLeafMarkerOid, CFSTR("1.2.840.113635.100.6.60")); 4089 4090 /* Issuer common name is "DemoUnit CA" */ 4091 add_element(options, kSecPolicyCheckIssuerCommonName, CFSTR("DemoUnit CA")); 4092 4093 require(result = SecPolicyCreate(kSecPolicyAppleDemoDigitalCatalog, 4094 kSecPolicyNameDemoDigitalCatalog, options), errOut); 4095 4096 errOut: 4097 CFReleaseSafe(options); 4098 return result; 4099 } 4100 4101 SecPolicyRef SecPolicyCreateAppleAssetReceipt(void) { 4102 CFMutableDictionaryRef options = NULL; 4103 SecPolicyRef result = NULL; 4104 4105 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, 4106 &kCFTypeDictionaryKeyCallBacks, 4107 &kCFTypeDictionaryValueCallBacks), errOut); 4108 4109 /* No expiration check. */ 4110 SecPolicyAddBasicCertOptions(options); 4111 4112 /* Apple Anchor */ 4113 require_quiet(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameAssetReceipt), errOut); 4114 4115 /* Exactly 3 certs in the chain */ 4116 require(SecPolicyAddChainLengthOptions(options, 3), errOut); 4117 4118 /* Intermediate marker OID is Apple System Integration 2 CA */ 4119 add_element(options, kSecPolicyCheckIntermediateMarkerOid, CFSTR("1.2.840.113635.100.6.2.10")); 4120 4121 /* Leaf marker OID is the Asset Receipt OID */ 4122 add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.6.61")); 4123 4124 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */ 4125 require(SecPolicyAddStrongKeySizeOptions(options), errOut); 4126 4127 require(result = SecPolicyCreate(kSecPolicyAppleAssetReceipt, 4128 kSecPolicyNameAssetReceipt, options), errOut); 4129 4130 errOut: 4131 CFReleaseNull(options); 4132 return result; 4133 } 4134 4135 SecPolicyRef SecPolicyCreateAppleDeveloperIDPlusTicket(void) { 4136 CFMutableDictionaryRef options = NULL; 4137 SecPolicyRef result = NULL; 4138 4139 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, 4140 &kCFTypeDictionaryKeyCallBacks, 4141 &kCFTypeDictionaryValueCallBacks), errOut); 4142 4143 /* No expiration check. */ 4144 SecPolicyAddBasicCertOptions(options); 4145 4146 /* Apple Anchor */ 4147 require_quiet(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameDeveloperIDPlusTicket), errOut); 4148 4149 /* Exactly 3 certs in the chain */ 4150 require(SecPolicyAddChainLengthOptions(options, 3), errOut); 4151 4152 /* Intermediate marker OID is Apple System Integration CA 4 */ 4153 add_element(options, kSecPolicyCheckIntermediateMarkerOid, CFSTR("1.2.840.113635.100.6.2.17")); 4154 4155 /* Leaf marker OID is the Developer ID+ Ticket OID */ 4156 add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.6.1.30")); 4157 4158 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */ 4159 require(SecPolicyAddStrongKeySizeOptions(options), errOut); 4160 4161 require(result = SecPolicyCreate(kSecPolicyAppleDeveloperIDPlusTicket, 4162 kSecPolicyNameDeveloperIDPlusTicket, options), errOut); 4163 4164 errOut: 4165 CFReleaseNull(options); 4166 return result; 4167 } 4168 4169 SecPolicyRef SecPolicyCreateAppleFDRProvisioning(void) { 4170 CFMutableDictionaryRef options = NULL; 4171 SecPolicyRef result = NULL; 4172 4173 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, 4174 &kCFTypeDictionaryKeyCallBacks, 4175 &kCFTypeDictionaryValueCallBacks), errOut); 4176 4177 /* No expiration check. */ 4178 SecPolicyAddBasicCertOptions(options); 4179 4180 require(result = SecPolicyCreate(kSecPolicyAppleFDRProvisioning, 4181 kSecPolicyNameFDRProvisioning, options), errOut); 4182 errOut: 4183 CFReleaseNull(options); 4184 return result; 4185 } 4186 4187 /* subject:/CN=Component Root CA/O=Apple Inc./ST=California */ 4188 /* SKID: 90:D1:56:A9:3E:B4:EE:8C:D0:10:4B:9F:17:1C:5B:55:F2:12:F6:4C */ 4189 /* Not Before: Dec 19 19:31:54 2018 GMT, Not After : Dec 16 00:00:00 2043 GMT */ 4190 /* Signature Algorithm: ecdsa-with-SHA384 */ 4191 const uint8_t ComponentRootCA_SHA256[kSecPolicySHA256Size] = { 4192 0x2f, 0x71, 0x9d, 0xbf, 0x3c, 0xcd, 0xe7, 0xc2, 0xb2, 0x59, 0x3f, 0x32, 0x1f, 0x90, 0xf3, 0x42, 4193 0x42, 0xaa, 0x84, 0xa1, 0xb2, 0x0d, 0xca, 0xcc, 0x10, 0xc0, 0x5b, 0x26, 0xd6, 0x23, 0xb8, 0x47, 4194 }; 4195 SecPolicyRef SecPolicyCreateAppleComponentCertificate(CFDataRef testRootHash) { 4196 CFMutableDictionaryRef options = NULL; 4197 SecPolicyRef result = NULL; 4198 4199 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, 4200 &kCFTypeDictionaryKeyCallBacks, 4201 &kCFTypeDictionaryValueCallBacks), errOut); 4202 4203 /* Component certificates don't expire */ 4204 SecPolicyAddBasicCertOptions(options); 4205 4206 /* Anchored to one of the Component roots. Allow alternative root for developers */ 4207 SecPolicyAddAnchorSHA256Options(options, ComponentRootCA_SHA256); 4208 if (testRootHash && SecIsInternalRelease() && (kSecPolicySHA256Size == CFDataGetLength(testRootHash))) { 4209 add_element(options, kSecPolicyCheckAnchorSHA256, testRootHash); 4210 } 4211 4212 /* Exactly 3 certs in the chain */ 4213 require(SecPolicyAddChainLengthOptions(options, 3), errOut); 4214 4215 /* Leaf and intermediate must contain Component Type OID */ 4216 add_element(options, kSecPolicyCheckLeafMarkerOidWithoutValueCheck, CFSTR("1.2.840.113635.100.11.1")); 4217 add_element(options, kSecPolicyCheckIntermediateMarkerOidWithoutValueCheck, CFSTR("1.2.840.113635.100.11.1")); 4218 4219 require(result = SecPolicyCreate(kSecPolicyAppleComponentCertificate, 4220 kSecPolicyNameComponentCertificate, options), errOut); 4221 errOut: 4222 CFReleaseNull(options); 4223 return result; 4224 } 4225 4226 SecPolicyRef SecPolicyCreateAppleKeyTransparency(CFStringRef applicationId) { 4227 CFMutableDictionaryRef options = NULL; 4228 SecPolicyRef result = NULL; 4229 4230 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, 4231 &kCFTypeDictionaryKeyCallBacks, 4232 &kCFTypeDictionaryValueCallBacks), errOut); 4233 4234 /* KT signing certs don't expire */ 4235 SecPolicyAddBasicCertOptions(options); 4236 4237 /* Apple Anchor */ 4238 require_quiet(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameKeyTransparency), errOut); 4239 4240 /* Exactly 3 certs in the chain */ 4241 require(SecPolicyAddChainLengthOptions(options, 3), errOut); 4242 4243 /* Intermediate marker OID matches AAI CA 5 */ 4244 add_element(options, kSecPolicyCheckIntermediateMarkerOid, CFSTR("1.2.840.113635.100.6.2.3")); 4245 4246 /* Leaf marker extension matches input applicationId */ 4247 add_leaf_marker_value_string(options, CFSTR("1.2.840.113635.100.12.4"), applicationId); 4248 4249 /* Check revocation using any available method */ 4250 add_element(options, kSecPolicyCheckRevocation, kSecPolicyCheckRevocationAny); 4251 4252 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */ 4253 require(SecPolicyAddStrongKeySizeOptions(options), errOut); 4254 4255 /* Check for weak hashes */ 4256 require(SecPolicyRemoveWeakHashOptions(options), errOut); 4257 4258 /* Future CT requirement */ 4259 4260 require(result = SecPolicyCreate(kSecPolicyAppleKeyTransparency, 4261 kSecPolicyNameKeyTransparency, options), errOut); 4262 errOut: 4263 CFReleaseNull(options); 4264 return result; 4265 } 4266 4267 SecPolicyRef SecPolicyCreateAlisha(void) { 4268 CFMutableDictionaryRef options = NULL; 4269 SecPolicyRef result = NULL; 4270 CFDictionaryRef keySizes = NULL; 4271 CFNumberRef ecSize = NULL; 4272 4273 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, 4274 &kCFTypeDictionaryKeyCallBacks, 4275 &kCFTypeDictionaryValueCallBacks), errOut); 4276 4277 /* Alisha certs don't expire */ 4278 SecPolicyAddBasicCertOptions(options); 4279 4280 /* RSA key sizes are disallowed. EC key sizes are P-256 or larger. */ 4281 require(ecSize = CFNumberCreateWithCFIndex(NULL, 256), errOut); 4282 require(keySizes = CFDictionaryCreate(NULL, (const void**)&kSecAttrKeyTypeEC, 4283 (const void**)&ecSize, 1, 4284 &kCFTypeDictionaryKeyCallBacks, 4285 &kCFTypeDictionaryValueCallBacks), errOut); 4286 add_element(options, kSecPolicyCheckKeySize, keySizes); 4287 4288 /* Check for weak hashes */ 4289 require(SecPolicyRemoveWeakHashOptions(options), errOut); 4290 4291 require(result = SecPolicyCreate(kSecPolicyAppleAlisha, 4292 kSecPolicyNameAlisha, options), errOut); 4293 errOut: 4294 CFReleaseNull(options); 4295 CFReleaseNull(keySizes); 4296 CFReleaseNull(ecSize); 4297 return result; 4298 } 4299 4300 SecPolicyRef SecPolicyCreateMeasuredBootPolicySigning(void) { 4301 CFMutableDictionaryRef options = NULL; 4302 SecPolicyRef result = NULL; 4303 4304 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, 4305 &kCFTypeDictionaryKeyCallBacks, 4306 &kCFTypeDictionaryValueCallBacks), errOut); 4307 4308 /* No expiration check. */ 4309 SecPolicyAddBasicCertOptions(options); 4310 4311 /* Exactly 3 certs in the chain */ 4312 require(SecPolicyAddChainLengthOptions(options, 3), errOut); 4313 4314 /* Corporate Signing subCA */ 4315 add_element(options, kSecPolicyCheckIntermediateMarkerOid, CFSTR("1.2.840.113635.100.6.24.17")); 4316 4317 /* Measured Boot Policy Signing Leaf OID */ 4318 add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.6.26.6.1")); 4319 4320 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */ 4321 require(SecPolicyAddStrongKeySizeOptions(options), errOut); 4322 4323 require(result = SecPolicyCreate(kSecPolicyAppleMeasuredBootPolicySigning, 4324 kSecPolicyNameMeasuredBootPolicySigning, options), errOut); 4325 4326 errOut: 4327 CFReleaseSafe(options); 4328 return result; 4329 } 4330 4331 /* subject:/CN=Apple External EC Root/O=Apple Inc./C=US */ 4332 /* SKID: 3F:A4:C0:94:20:70:CB:3B:DD:A8:54:E6:14:1E:29:CC:4D:14:38:53 */ 4333 /* Not Before: Jan 23 00:46:48 2020 GMT, Not After : Jan 18 00:00:00 2045 GMT */ 4334 /* Signature Algorithm: ecdsa-with-SHA384 */ 4335 const uint8_t AppleExternalECRoot_SHA256[kSecPolicySHA256Size] = { 4336 0x72, 0x56, 0x6e, 0x6f, 0x66, 0x30, 0x0c, 0xfd, 0x24, 0xe5, 0xe6, 0x85, 0xa2, 0xf1, 0x5a, 0x74, 4337 0x9d, 0xe0, 0x4b, 0xb0, 0x38, 0x50, 0x77, 0x91, 0x96, 0x63, 0x6e, 0x07, 0x23, 0x0f, 0x91, 0x1e 4338 }; 4339 /* subject:/CN=Test Apple External EC Root/O=Apple Inc./C=US */ 4340 /* SKID: 07:6B:07:47:33:E4:96:B4:FC:6F:FA:32:2C:8E:BE:70:C2:8F:80:3C */ 4341 /* Not Before: Nov 5 18:00:46 2019 GMT, Not After : Oct 29 18:00:46 2044 GMT */ 4342 /* Signature Algorithm: ecdsa-with-SHA384 */ 4343 const uint8_t TestAppleExternalECRoot_SHA256[kSecPolicySHA256Size] = { 4344 0xf3, 0x98, 0x39, 0xdc, 0x6a, 0x64, 0xf6, 0xe3, 0xa0, 0xdc, 0x97, 0xd7, 0x83, 0x61, 0x6b, 0x84, 4345 0x9f, 0xdf, 0xa1, 0x70, 0x54, 0x59, 0xae, 0x96, 0x0f, 0x41, 0xe1, 0x16, 0xa3, 0xb4, 0x8b, 0xb5 4346 }; 4347 SecPolicyRef SecPolicyCreateApplePayQRCodeEncryption(void) { 4348 CFMutableDictionaryRef options = NULL; 4349 SecPolicyRef result = NULL; 4350 4351 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, 4352 &kCFTypeDictionaryKeyCallBacks, 4353 &kCFTypeDictionaryValueCallBacks), errOut); 4354 4355 /* Check expiration */ 4356 SecPolicyAddBasicX509Options(options); 4357 4358 /* Exactly 3 certs in the chain */ 4359 require(SecPolicyAddChainLengthOptions(options, 3), errOut); 4360 4361 /* Apple External EC CA 1 - G1 */ 4362 add_element(options, kSecPolicyCheckIntermediateMarkerOid, CFSTR("1.2.840.113635.100.6.2.22")); 4363 4364 /* ApplePay QR Code Encryption */ 4365 add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.13.3")); 4366 4367 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */ 4368 require(SecPolicyAddStrongKeySizeOptions(options), errOut); 4369 4370 require(SecPolicyAddAnchorSHA256Options(options, AppleExternalECRoot_SHA256),errOut); 4371 if (SecIsInternalRelease()) { 4372 require(SecPolicyAddAnchorSHA256Options(options, TestAppleExternalECRoot_SHA256),errOut); 4373 } 4374 4375 /* Check revocation using any available method */ 4376 add_element(options, kSecPolicyCheckRevocation, kSecPolicyCheckRevocationAny); 4377 4378 require(result = SecPolicyCreate(kSecPolicyApplePayQRCodeEncryption, 4379 kSecPolicyNamePayQRCodeEncryption, options), errOut); 4380 4381 errOut: 4382 CFReleaseSafe(options); 4383 return result; 4384 } 4385 4386 SecPolicyRef SecPolicyCreateApplePayQRCodeSigning(void) { 4387 CFMutableDictionaryRef options = NULL; 4388 SecPolicyRef result = NULL; 4389 4390 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, 4391 &kCFTypeDictionaryKeyCallBacks, 4392 &kCFTypeDictionaryValueCallBacks), errOut); 4393 4394 /* Check expiration */ 4395 SecPolicyAddBasicX509Options(options); 4396 4397 /* Exactly 3 certs in the chain */ 4398 require(SecPolicyAddChainLengthOptions(options, 3), errOut); 4399 4400 /* Apple External EC CA 1 - G1 */ 4401 add_element(options, kSecPolicyCheckIntermediateMarkerOid, CFSTR("1.2.840.113635.100.6.2.22")); 4402 4403 /* ApplePay QR Code Signing */ 4404 add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.12.12")); 4405 4406 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */ 4407 require(SecPolicyAddStrongKeySizeOptions(options), errOut); 4408 4409 require(SecPolicyAddAnchorSHA256Options(options, AppleExternalECRoot_SHA256),errOut); 4410 if (SecIsInternalRelease()) { 4411 require(SecPolicyAddAnchorSHA256Options(options, TestAppleExternalECRoot_SHA256),errOut); 4412 } 4413 4414 /* Check revocation using any available method */ 4415 add_element(options, kSecPolicyCheckRevocation, kSecPolicyCheckRevocationAny); 4416 4417 require(result = SecPolicyCreate(kSecPolicyApplePayQRCodeSigning, 4418 kSecPolicyNamePayQRCodeSigning, options), errOut); 4419 4420 errOut: 4421 CFReleaseSafe(options); 4422 return result; 4423 } 4424 4425 SecPolicyRef SecPolicyCreateAppleAccessoryUpdateSigning(void) { 4426 CFMutableDictionaryRef options = NULL; 4427 SecPolicyRef result = NULL; 4428 4429 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, 4430 &kCFTypeDictionaryKeyCallBacks, 4431 &kCFTypeDictionaryValueCallBacks), errOut); 4432 4433 /* No expiration check */ 4434 SecPolicyAddBasicCertOptions(options); 4435 4436 /* Exactly 3 certs in the chain */ 4437 require(SecPolicyAddChainLengthOptions(options, 3), errOut); 4438 4439 /* Apple Anchor */ 4440 require_quiet(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameAccessoryUpdateSigning), errOut); 4441 4442 /* Apple External EC CA 1 - G1 */ 4443 add_element(options, kSecPolicyCheckIntermediateMarkerOid, CFSTR("1.2.840.113635.100.6.2.17")); 4444 4445 /* Accessory Manufacturer Firmware Signing Prod */ 4446 add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.12.9")); 4447 if (isCFPreferenceInSecurityDomain(CFSTR("AllowAccessoryUpdateSigningBeta"))) { 4448 add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.12.10")); // ProdQA 4449 } 4450 4451 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */ 4452 require(SecPolicyAddStrongKeySizeOptions(options), errOut); 4453 4454 /* Check revocation using any available method */ 4455 add_element(options, kSecPolicyCheckRevocation, kSecPolicyCheckRevocationAny); 4456 4457 require(result = SecPolicyCreate(kSecPolicyAppleAccessoryUpdateSigning, 4458 kSecPolicyNameAccessoryUpdateSigning, options), errOut); 4459 4460 errOut: 4461 CFReleaseSafe(options); 4462 return result; 4463 } 4464 4465 CF_RETURNS_RETAINED SecPolicyRef SecPolicyCreateEscrowServiceIdKeySigning(void) 4466 { 4467 SecPolicyRef result = NULL; 4468 CFMutableDictionaryRef options = NULL; 4469 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, 4470 &kCFTypeDictionaryKeyCallBacks, 4471 &kCFTypeDictionaryValueCallBacks), errOut); 4472 4473 // X509, ignoring date validity 4474 SecPolicyAddBasicCertOptions(options); 4475 4476 add_ku(options, kSecKeyUsageDigitalSignature); 4477 4478 CFDictionaryAddValue(options, kSecPolicyCheckSubjectCommonName, 4479 CFSTR("Escrow Service ID Key")); 4480 4481 /* Exactly 2 certs in the chain */ 4482 require(SecPolicyAddChainLengthOptions(options, 2), errOut); 4483 4484 require(result = SecPolicyCreate(kSecPolicyAppleEscrowServiceIdKeySigning, 4485 kSecPolicyNameEscrowServiceIdKeySigning, options), errOut); 4486 4487 errOut: 4488 CFReleaseSafe(options); 4489 return result; 4490 } 4491 4492 CF_RETURNS_RETAINED SecPolicyRef SecPolicyCreatePCSEscrowServiceIdKeySigning(void) 4493 { 4494 SecPolicyRef result = NULL; 4495 CFMutableDictionaryRef options = NULL; 4496 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, 4497 &kCFTypeDictionaryKeyCallBacks, 4498 &kCFTypeDictionaryValueCallBacks), errOut); 4499 4500 SecPolicyAddBasicX509Options(options); 4501 add_ku(options, kSecKeyUsageDigitalSignature); 4502 4503 CFDictionaryAddValue(options, kSecPolicyCheckSubjectCommonName, 4504 CFSTR("Effaceable Service ID Key")); 4505 4506 /* Exactly 2 certs in the chain */ 4507 require(SecPolicyAddChainLengthOptions(options, 2), errOut); 4508 4509 require(result = SecPolicyCreate(kSecPolicyApplePCSEscrowServiceIdKeySigning, 4510 kSecPolicyNamePCSEscrowServiceIdKeySigning, options), errOut); 4511 4512 errOut: 4513 CFReleaseSafe(options); 4514 return result; 4515 } 4516 4517 SecPolicyRef SecPolicyCreateAggregateMetricTransparency(bool facilitator) 4518 { 4519 CFMutableDictionaryRef options = NULL; 4520 SecPolicyRef result = NULL; 4521 4522 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, 4523 &kCFTypeDictionaryKeyCallBacks, 4524 &kCFTypeDictionaryValueCallBacks), errOut); 4525 4526 SecPolicyAddBasicX509Options(options); 4527 4528 /* Anchored to the Apple Roots */ 4529 require(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameAggregateMetricTransparency), errOut); 4530 4531 /* Exactly 3 certs in the chain */ 4532 require(SecPolicyAddChainLengthOptions(options, 3), errOut); 4533 4534 /* Intermediate marker OID matches AAICA 6 */ 4535 add_element(options, kSecPolicyCheckIntermediateMarkerOid, CFSTR("1.2.840.113635.100.6.2.26")); 4536 4537 /* Leaf marker OID matches expected OID for either Facilitator or Partner */ 4538 if (facilitator) { 4539 add_element(options, kSecPolicyCheckLeafMarkerOidWithoutValueCheck, CFSTR("1.2.840.113635.100.12.17")); 4540 } else { 4541 add_element(options, kSecPolicyCheckLeafMarkerOidWithoutValueCheck, CFSTR("1.2.840.113635.100.12.18")); 4542 } 4543 4544 /* Check revocation using any available method */ 4545 add_element(options, kSecPolicyCheckRevocation, kSecPolicyCheckRevocationAny); 4546 4547 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */ 4548 require(SecPolicyAddStrongKeySizeOptions(options), errOut); 4549 4550 /* Require CT */ 4551 if (!SecIsInternalRelease() || !isCFPreferenceInSecurityDomain(CFSTR("disableAggregateMetricsCTCheck"))) { 4552 add_element(options, kSecPolicyCheckCTRequired, kCFBooleanTrue); 4553 } 4554 4555 /* Check for weak hashes */ 4556 // require(SecPolicyRemoveWeakHashOptions(options), errOut); // the current WWDR CA cert is signed with SHA1 4557 require(result = SecPolicyCreate(kSecPolicyAppleAggregateMetricTransparency, 4558 kSecPolicyNameAggregateMetricTransparency, options), errOut); 4559 4560 errOut: 4561 CFReleaseSafe(options); 4562 return result; 4563 } 4564 4565 SecPolicyRef SecPolicyCreateAggregateMetricEncryption(bool facilitator) 4566 { 4567 CFMutableDictionaryRef options = NULL; 4568 SecPolicyRef result = NULL; 4569 4570 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, 4571 &kCFTypeDictionaryKeyCallBacks, 4572 &kCFTypeDictionaryValueCallBacks), errOut); 4573 4574 SecPolicyAddBasicX509Options(options); 4575 4576 /* Anchored to the Apple Roots */ 4577 require(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameAggregateMetricEncryption), errOut); 4578 4579 /* Exactly 3 certs in the chain */ 4580 require(SecPolicyAddChainLengthOptions(options, 3), errOut); 4581 4582 /* Intermediate marker OID matches AAICA 6 */ 4583 add_element(options, kSecPolicyCheckIntermediateMarkerOid, CFSTR("1.2.840.113635.100.6.2.26")); 4584 4585 /* Leaf marker OID matches expected OID for either Facilitator or Partner */ 4586 if (facilitator) { 4587 add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.15.2")); 4588 } else { 4589 add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.15.3")); 4590 } 4591 4592 /* Check revocation using any available method */ 4593 add_element(options, kSecPolicyCheckRevocation, kSecPolicyCheckRevocationAny); 4594 4595 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */ 4596 require(SecPolicyAddStrongKeySizeOptions(options), errOut); 4597 4598 /* Require CT */ 4599 if (!SecIsInternalRelease() || !isCFPreferenceInSecurityDomain(CFSTR("disableAggregateMetricsCTCheck"))) { 4600 add_element(options, kSecPolicyCheckNonTlsCTRequired, kCFBooleanTrue); 4601 } 4602 4603 require(result = SecPolicyCreate(kSecPolicyAppleAggregateMetricEncryption, 4604 kSecPolicyNameAggregateMetricEncryption, options), errOut); 4605 4606 errOut: 4607 CFReleaseSafe(options); 4608 return result; 4609 } 4610 4611 SecPolicyRef SecPolicyCreateApplePayModelSigning(bool checkExpiration) { 4612 CFMutableDictionaryRef options = NULL; 4613 SecPolicyRef result = NULL; 4614 4615 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, 4616 &kCFTypeDictionaryKeyCallBacks, 4617 &kCFTypeDictionaryValueCallBacks), errOut); 4618 4619 if (checkExpiration) { 4620 SecPolicyAddBasicX509Options(options); 4621 } else { 4622 SecPolicyAddBasicCertOptions(options); 4623 } 4624 4625 /* Anchored to the Apple Roots */ 4626 require(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNamePayModelSigning), errOut); 4627 4628 /* Exactly 3 certs in the chain */ 4629 require(SecPolicyAddChainLengthOptions(options, 3), errOut); 4630 4631 /* Intermediate marker OID is Apple System Integration CA 4 */ 4632 add_element(options, kSecPolicyCheckIntermediateMarkerOid, CFSTR("1.2.840.113635.100.6.2.17")); 4633 4634 /* Leaf marker OID for ApplePay Model Signing */ 4635 add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.12.20")); 4636 4637 /* Check revocation using any available method */ 4638 add_element(options, kSecPolicyCheckRevocation, kSecPolicyCheckRevocationAny); 4639 4640 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */ 4641 require(SecPolicyAddStrongKeySizeOptions(options), errOut); 4642 4643 require(result = SecPolicyCreate(kSecPolicyApplePayModelSigning, 4644 kSecPolicyNamePayModelSigning, options), errOut); 4645 4646 errOut: 4647 CFReleaseSafe(options); 4648 return result; 4649 }