/ OSX / sec / Security / SecPolicy.c
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  }