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