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