]> git.saurik.com Git - apple/security.git/blob - OSX/sec/Security/SecPolicy.c
Security-58286.230.21.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 #if !TARGET_OS_BRIDGE
1356 CFDictionaryAddValue(options, kSecPolicyCheckSystemTrustedCTRequired, kCFBooleanTrue);
1357 #endif
1358 }
1359
1360 set_ssl_ekus(options, server);
1361
1362 require(result = SecPolicyCreate(kSecPolicyAppleSSL,
1363 server ? kSecPolicyNameSSLServer : kSecPolicyNameSSLClient,
1364 options), errOut);
1365
1366 errOut:
1367 CFReleaseSafe(options);
1368 return (SecPolicyRef _Nonnull)result;
1369 }
1370
1371 SecPolicyRef SecPolicyCreateApplePinned(CFStringRef policyName, CFStringRef intermediateMarkerOID, CFStringRef leafMarkerOID) {
1372 CFMutableDictionaryRef options = NULL;
1373 SecPolicyRef result = NULL;
1374
1375 if (!policyName || !intermediateMarkerOID || !leafMarkerOID) {
1376 goto errOut;
1377 }
1378
1379 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
1380 &kCFTypeDictionaryKeyCallBacks,
1381 &kCFTypeDictionaryValueCallBacks), errOut);
1382
1383 SecPolicyAddBasicX509Options(options);
1384
1385 /* Anchored to the Apple Roots */
1386 require(SecPolicyAddAppleAnchorOptions(options, policyName), errOut);
1387
1388 /* Exactly 3 certs in the chain */
1389 require(SecPolicyAddChainLengthOptions(options, 3), errOut);
1390
1391 /* Intermediate marker OID matches input OID */
1392 if (!isAppleOid(intermediateMarkerOID)) {
1393 secwarning("creating an Apple pinning policy with a non-Apple OID: %@", intermediateMarkerOID);
1394 }
1395 add_element(options, kSecPolicyCheckIntermediateMarkerOid, intermediateMarkerOID);
1396
1397 /* Leaf marker OID matches input OID */
1398 if (!isAppleOid(leafMarkerOID)) {
1399 secwarning("creating an Apple pinning policy with a non-Apple OID: %@", leafMarkerOID);
1400 }
1401 add_leaf_marker_string(options, leafMarkerOID);
1402
1403 /* Check revocation using any available method */
1404 add_element(options, kSecPolicyCheckRevocation, kSecPolicyCheckRevocationAny);
1405
1406 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
1407 require(SecPolicyAddStrongKeySizeOptions(options), errOut);
1408
1409 /* Check for weak hashes */
1410 CFDictionaryAddValue(options, kSecPolicyCheckSystemTrustedWeakHash, kCFBooleanTrue);
1411 require(result = SecPolicyCreate(kSecPolicyAppleGenericApplePinned,
1412 policyName, options), errOut);
1413
1414 errOut:
1415 CFReleaseSafe(options);
1416 return result;
1417 }
1418
1419 static bool
1420 requireUATPinning(CFStringRef service)
1421 {
1422 bool pinningRequired = true;
1423
1424 if (SecIsInternalRelease()) {
1425 CFStringRef setting = CFStringCreateWithFormat(NULL, NULL, CFSTR("AppleServerAuthenticationNoPinning%@"), service);
1426 require(setting, fail);
1427 if(isCFPreferenceInSecurityDomain(setting)) {
1428 pinningRequired = false;
1429 } else {
1430 secnotice("pinningQA", "could not disable pinning: %@ not true", setting);
1431 }
1432 CFRelease(setting);
1433
1434 if (!pinningRequired) {
1435 goto fail;
1436 }
1437
1438 if(isCFPreferenceInSecurityDomain(CFSTR("AppleServerAuthenticationNoPinning"))) {
1439 pinningRequired = false;
1440 } else {
1441 secnotice("pinningQA", "could not disable pinning: AppleServerAuthenticationNoPinning not true");
1442 }
1443 } else {
1444 secnotice("pinningQA", "could not disable pinning: not an internal release");
1445 }
1446 fail:
1447 return pinningRequired;
1448 }
1449
1450 SecPolicyRef SecPolicyCreateAppleSSLPinned(CFStringRef policyName, CFStringRef hostname,
1451 CFStringRef intermediateMarkerOID, CFStringRef leafMarkerOID) {
1452 CFMutableDictionaryRef options = NULL, appleAnchorOptions = NULL;
1453 SecPolicyRef result = NULL;
1454
1455 if (!policyName || !hostname || !leafMarkerOID) {
1456 goto errOut;
1457 }
1458
1459 if (requireUATPinning(policyName)) {
1460 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
1461 &kCFTypeDictionaryKeyCallBacks,
1462 &kCFTypeDictionaryValueCallBacks), errOut);
1463
1464 SecPolicyAddBasicX509Options(options);
1465
1466 /* Anchored to the Apple Roots */
1467 require(SecPolicyAddAppleAnchorOptions(options, policyName), errOut);
1468
1469 /* Exactly 3 certs in the chain */
1470 require(SecPolicyAddChainLengthOptions(options, 3), errOut);
1471
1472 if (intermediateMarkerOID) {
1473 /* Intermediate marker OID matches input OID */
1474 if (!isAppleOid(intermediateMarkerOID)) {
1475 secwarning("creating an Apple pinning policy with a non-Apple OID: %@", intermediateMarkerOID);
1476 }
1477 add_element(options, kSecPolicyCheckIntermediateMarkerOid, intermediateMarkerOID);
1478 } else {
1479 add_element(options, kSecPolicyCheckIntermediateMarkerOid, CFSTR("1.2.840.113635.100.6.2.12"));
1480 }
1481
1482 /* Leaf marker OID matches input OID */
1483 if (!isAppleOid(leafMarkerOID)) {
1484 secwarning("creating an Apple pinning policy with a non-Apple OID: %@", leafMarkerOID);
1485 }
1486 add_leaf_marker_string(options, leafMarkerOID);
1487
1488 /* New leaf marker OID format */
1489 add_leaf_marker_value_string(options, CFSTR("1.2.840.113635.100.6.48.1"), leafMarkerOID);
1490
1491 /* ServerAuth EKU is in leaf cert */
1492 add_eku_string(options, CFSTR("1.3.6.1.5.5.7.3.1"));
1493
1494 /* Hostname is in leaf cert */
1495 add_element(options, kSecPolicyCheckSSLHostname, hostname);
1496
1497 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
1498 require(SecPolicyAddStrongKeySizeOptions(options), errOut);
1499
1500 /* Check for weak hashes */
1501 CFDictionaryAddValue(options, kSecPolicyCheckSystemTrustedWeakHash, kCFBooleanTrue);
1502
1503 /* Check revocation using any available method */
1504 add_element(options, kSecPolicyCheckRevocation, kSecPolicyCheckRevocationAny);
1505
1506 require(result = SecPolicyCreate(kSecPolicyAppleGenericAppleSSLPinned,
1507 policyName, options), errOut);
1508
1509 } else {
1510 result = SecPolicyCreateSSL(true, hostname);
1511 SecPolicySetOid(result, kSecPolicyAppleGenericAppleSSLPinned);
1512 SecPolicySetName(result, policyName);
1513 }
1514
1515 errOut:
1516 CFReleaseSafe(options);
1517 CFReleaseSafe(appleAnchorOptions);
1518 return result;
1519 }
1520
1521 SecPolicyRef SecPolicyCreateiPhoneActivation(void) {
1522 CFMutableDictionaryRef options = NULL;
1523 SecPolicyRef result = NULL;
1524
1525 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
1526 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut);
1527
1528 SecPolicyAddBasicCertOptions(options);
1529
1530 #if 0
1531 CFDictionaryAddValue(options, kSecPolicyCheckKeyUsage,
1532 kCFBooleanTrue);
1533 CFDictionaryAddValue(options, kSecPolicyCheckExtendedKeyUsage,
1534 kCFBooleanTrue);
1535 #endif
1536
1537 /* Basic X.509 policy with the additional requirements that the chain
1538 length is 3, it's anchored at the AppleCA and the leaf certificate
1539 has issuer "Apple iPhone Certification Authority" and
1540 subject "Apple iPhone Activation" for the common name. */
1541 CFDictionaryAddValue(options, kSecPolicyCheckIssuerCommonName,
1542 CFSTR("Apple iPhone Certification Authority"));
1543 CFDictionaryAddValue(options, kSecPolicyCheckSubjectCommonName,
1544 CFSTR("Apple iPhone Activation"));
1545
1546 require(SecPolicyAddChainLengthOptions(options, 3), errOut);
1547 require(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameiPhoneActivation), errOut);
1548
1549 require(result = SecPolicyCreate(kSecPolicyAppleiPhoneActivation,
1550 kSecPolicyNameiPhoneActivation, options),
1551 errOut);
1552
1553 errOut:
1554 CFReleaseSafe(options);
1555 return result;
1556 }
1557
1558 SecPolicyRef SecPolicyCreateiPhoneDeviceCertificate(void) {
1559 CFMutableDictionaryRef options = NULL;
1560 SecPolicyRef result = NULL;
1561
1562 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
1563 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut);
1564
1565 SecPolicyAddBasicCertOptions(options);
1566
1567 #if 0
1568 CFDictionaryAddValue(options, kSecPolicyCheckKeyUsage,
1569 kCFBooleanTrue);
1570 CFDictionaryAddValue(options, kSecPolicyCheckExtendedKeyUsage,
1571 kCFBooleanTrue);
1572 #endif
1573
1574 /* Basic X.509 policy with the additional requirements that the chain
1575 length is 4, it's anchored at the AppleCA and the first intermediate
1576 has the subject "Apple iPhone Device CA". */
1577 CFDictionaryAddValue(options, kSecPolicyCheckIssuerCommonName,
1578 CFSTR("Apple iPhone Device CA"));
1579
1580 require(SecPolicyAddChainLengthOptions(options, 4), errOut);
1581 require(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameiPhoneDeviceCertificate), errOut);
1582
1583 require(result = SecPolicyCreate(kSecPolicyAppleiPhoneDeviceCertificate,
1584 kSecPolicyNameiPhoneDeviceCertificate, options),
1585 errOut);
1586
1587 errOut:
1588 CFReleaseSafe(options);
1589 return result;
1590 }
1591
1592 SecPolicyRef SecPolicyCreateFactoryDeviceCertificate(void) {
1593 CFMutableDictionaryRef options = NULL;
1594 SecPolicyRef result = NULL;
1595
1596 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
1597 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut);
1598
1599 SecPolicyAddBasicCertOptions(options);
1600
1601 #if 0
1602 CFDictionaryAddValue(options, kSecPolicyCheckKeyUsage,
1603 kCFBooleanTrue);
1604 CFDictionaryAddValue(options, kSecPolicyCheckExtendedKeyUsage,
1605 kCFBooleanTrue);
1606 #endif
1607
1608 /* Basic X.509 policy with the additional requirements that the chain
1609 is anchored at the factory device certificate issuer. */
1610 require(SecPolicyAddAnchorSHA1Options(options, kFactoryDeviceCASHA1), errOut);
1611
1612 require(result = SecPolicyCreate(kSecPolicyAppleFactoryDeviceCertificate,
1613 kSecPolicyNameFactoryDeviceCertificate, options),
1614 errOut);
1615
1616 errOut:
1617 CFReleaseSafe(options);
1618 return result;
1619 }
1620
1621 SecPolicyRef SecPolicyCreateiAP(void) {
1622 CFMutableDictionaryRef options = NULL;
1623 SecPolicyRef result = NULL;
1624 CFTimeZoneRef tz = NULL;
1625 CFDateRef date = NULL;
1626
1627 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
1628 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut);
1629
1630 SecPolicyAddBasicCertOptions(options);
1631
1632 CFDictionaryAddValue(options, kSecPolicyCheckSubjectCommonNamePrefix,
1633 CFSTR("IPA_"));
1634
1635 date = CFDateCreateForGregorianZuluDay(NULL, 2006, 5, 31);
1636 CFDictionaryAddValue(options, kSecPolicyCheckNotValidBefore, date);
1637
1638 require(result = SecPolicyCreate(kSecPolicyAppleiAP,
1639 kSecPolicyNameiAP, options),
1640 errOut);
1641
1642 errOut:
1643 CFReleaseSafe(date);
1644 CFReleaseSafe(tz);
1645 CFReleaseSafe(options);
1646 return result;
1647 }
1648
1649 SecPolicyRef SecPolicyCreateiTunesStoreURLBag(void) {
1650 CFMutableDictionaryRef options = NULL;
1651 SecPolicyRef result = NULL;
1652
1653
1654 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
1655 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut);
1656
1657 SecPolicyAddBasicCertOptions(options);
1658
1659 CFDictionaryAddValue(options, kSecPolicyCheckSubjectOrganization,
1660 CFSTR("Apple Inc."));
1661 CFDictionaryAddValue(options, kSecPolicyCheckSubjectCommonName,
1662 CFSTR("iTunes Store URL Bag"));
1663
1664 require(SecPolicyAddChainLengthOptions(options, 2), errOut);
1665 require(SecPolicyAddAnchorSHA1Options(options, kITMSCASHA1), errOut);
1666
1667 require(result = SecPolicyCreate(kSecPolicyAppleiTunesStoreURLBag,
1668 kSecPolicyNameiTunesStoreURLBag, options), errOut);
1669
1670 errOut:
1671 CFReleaseSafe(options);
1672 return result;
1673 }
1674
1675 SecPolicyRef SecPolicyCreateEAP(Boolean server, CFArrayRef trustedServerNames) {
1676 CFMutableDictionaryRef options = NULL;
1677 SecPolicyRef result = NULL;
1678
1679 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
1680 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut);
1681
1682 SecPolicyAddBasicX509Options(options);
1683
1684 /* Since EAP is used to setup the network we don't want evaluation
1685 using this policy to access the network. */
1686 CFDictionaryAddValue(options, kSecPolicyCheckNoNetworkAccess,
1687 kCFBooleanTrue);
1688
1689 if (trustedServerNames) {
1690 CFDictionaryAddValue(options, kSecPolicyCheckEAPTrustedServerNames, trustedServerNames);
1691 }
1692
1693 if (server) {
1694 /* Check for weak hashes */
1695 CFDictionaryAddValue(options, kSecPolicyCheckSystemTrustedWeakHash, kCFBooleanTrue);
1696 CFDictionaryAddValue(options, kSecPolicyCheckSystemTrustedWeakKey, kCFBooleanTrue);
1697 }
1698
1699 /* We need to check for EKU per rdar://22206018 */
1700 set_ssl_ekus(options, server);
1701
1702 require(result = SecPolicyCreate(kSecPolicyAppleEAP,
1703 server ? kSecPolicyNameEAPServer : kSecPolicyNameEAPClient,
1704 options), errOut);
1705
1706 errOut:
1707 CFReleaseSafe(options);
1708 return result;
1709 }
1710
1711 SecPolicyRef SecPolicyCreateIPSec(Boolean server, CFStringRef hostname) {
1712 CFMutableDictionaryRef options = NULL;
1713 SecPolicyRef result = NULL;
1714
1715 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
1716 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut);
1717
1718 SecPolicyAddBasicX509Options(options);
1719
1720 if (hostname) {
1721 CFDictionaryAddValue(options, kSecPolicyCheckSSLHostname, hostname);
1722 }
1723
1724 /* Require oidExtendedKeyUsageIPSec if Extended Keyusage Extention is
1725 present. */
1726 /* Per <rdar://problem/6843827> Cisco VPN Certificate compatibility issue.
1727 We don't check the EKU for IPSec certs for now. If we do add eku
1728 checking back in the future, we should probably also accept the
1729 following EKUs:
1730 ipsecEndSystem 1.3.6.1.5.5.7.3.5
1731 and possibly even
1732 ipsecTunnel 1.3.6.1.5.5.7.3.6
1733 ipsecUser 1.3.6.1.5.5.7.3.7
1734 */
1735 //add_eku(options, NULL); /* eku extension is optional */
1736 //add_eku(options, &oidAnyExtendedKeyUsage);
1737 //add_eku(options, &oidExtendedKeyUsageIPSec);
1738
1739 require(result = SecPolicyCreate(kSecPolicyAppleIPsec,
1740 server ? kSecPolicyNameIPSecServer : kSecPolicyNameIPSecClient,
1741 options), errOut);
1742
1743 errOut:
1744 CFReleaseSafe(options);
1745 return result;
1746 }
1747
1748 SecPolicyRef SecPolicyCreateiPhoneApplicationSigning(void) {
1749 CFMutableDictionaryRef options = NULL;
1750 SecPolicyRef result = NULL;
1751
1752 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
1753 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut);
1754
1755 SecPolicyAddBasicCertOptions(options);
1756
1757 /* Anchored to the Apple Roots */
1758 require(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameiPhoneApplicationSigning), errOut);
1759
1760 /* Leaf checks */
1761 if (SecIsInternalRelease()) {
1762 /* Allow a prod hierarchy-signed test cert */
1763 CFDictionaryAddValue(options, kSecPolicyCheckSubjectCommonNameTEST,
1764 CFSTR("Apple iPhone OS Application Signing"));
1765 add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.6.1.3.1"));
1766 }
1767 else {
1768 CFDictionaryAddValue(options, kSecPolicyCheckSubjectCommonName,
1769 CFSTR("Apple iPhone OS Application Signing"));
1770 }
1771 add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.6.1.3"));
1772
1773 add_eku(options, NULL); /* eku extension is optional */
1774 add_eku(options, &oidAnyExtendedKeyUsage);
1775 add_eku(options, &oidExtendedKeyUsageCodeSigning);
1776
1777 /* Intermediate check */
1778 CFDictionaryAddValue(options, kSecPolicyCheckIssuerCommonName,
1779 CFSTR("Apple iPhone Certification Authority"));
1780
1781 /* Chain length check */
1782 require(SecPolicyAddChainLengthOptions(options, 3), errOut);
1783
1784 /* Skip networked revocation checks */
1785 CFDictionaryAddValue(options, kSecPolicyCheckNoNetworkAccess, kCFBooleanTrue);
1786
1787 require(result = SecPolicyCreate(kSecPolicyAppleiPhoneApplicationSigning,
1788 kSecPolicyNameiPhoneApplicationSigning, options),
1789 errOut);
1790
1791 errOut:
1792 CFReleaseSafe(options);
1793 return result;
1794 }
1795
1796 SecPolicyRef SecPolicyCreateiPhoneVPNApplicationSigning(void) {
1797 CFMutableDictionaryRef options = NULL;
1798 SecPolicyRef result = NULL;
1799
1800 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
1801 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut);
1802
1803 SecPolicyAddBasicCertOptions(options);
1804
1805 /* Anchored to the Apple Roots */
1806 require(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameiPhoneVPNApplicationSigning), errOut);
1807
1808 /* Leaf checks */
1809 if (SecIsInternalRelease()) {
1810 /* Allow a prod hierarchy-signed test cert */
1811 CFDictionaryAddValue(options, kSecPolicyCheckSubjectCommonNameTEST,
1812 CFSTR("Apple iPhone OS Application Signing"));
1813 add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.6.1.6.1"));
1814 }
1815 else {
1816 CFDictionaryAddValue(options, kSecPolicyCheckSubjectCommonName,
1817 CFSTR("Apple iPhone OS Application Signing"));
1818 }
1819 add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.6.1.6"));
1820
1821 add_eku(options, NULL); /* eku extension is optional */
1822 add_eku(options, &oidAnyExtendedKeyUsage);
1823 add_eku(options, &oidExtendedKeyUsageCodeSigning);
1824
1825 /* Intermediate check */
1826 CFDictionaryAddValue(options, kSecPolicyCheckIssuerCommonName,
1827 CFSTR("Apple iPhone Certification Authority"));
1828
1829 /* Chain length check */
1830 require(SecPolicyAddChainLengthOptions(options, 3), errOut);
1831
1832 /* Skip networked revocation checks */
1833 CFDictionaryAddValue(options, kSecPolicyCheckNoNetworkAccess, kCFBooleanTrue);
1834
1835 require(result = SecPolicyCreate(kSecPolicyAppleiPhoneVPNApplicationSigning,
1836 kSecPolicyNameiPhoneVPNApplicationSigning, options),
1837 errOut);
1838
1839 errOut:
1840 CFReleaseSafe(options);
1841 return result;
1842 }
1843
1844 SecPolicyRef SecPolicyCreateiPhoneProfileApplicationSigning(void) {
1845 CFMutableDictionaryRef options = NULL;
1846 SecPolicyRef result = NULL;
1847
1848 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
1849 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut);
1850
1851 SecPolicyAddBasicX509Options(options); // With expiration checking
1852
1853 /* Apple Anchor */
1854 require_quiet(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameiPhoneProfileApplicationSigning),
1855 errOut);
1856
1857 /* Chain Len: 3 */
1858 require(SecPolicyAddChainLengthOptions(options, 3), errOut);
1859
1860 /* Leaf has CodeSigning EKU */
1861 add_eku_string(options, CFSTR("1.3.6.1.5.5.7.3.3"));
1862
1863 /* On iOS, the cert in the provisioning profile may be one of:
1864 leaf OID intermediate OID
1865 iPhone Developer <ADS>.6.1.2 <ADS>.6.2.1
1866 iPhone Distribution <ADS>.6.1.4 <ADS>.6.2.1
1867 TestFlight (Prod) <ADS>.6.1.25.1 <ADS>.6.2.1
1868 TestFlight (QA) <ADS>.6.1.25.2 <ADS>.6.2.1
1869 */
1870 add_element(options, kSecPolicyCheckIntermediateMarkerOid, CFSTR("1.2.840.113635.100.6.2.1"));
1871 add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.6.1.2"));
1872 add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.6.1.4"));
1873 add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.6.1.25.1"));
1874 if (SecIsInternalRelease()) {
1875 add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.6.1.25.2"));
1876 }
1877
1878 /* Revocation via any available method */
1879 CFDictionaryAddValue(options, kSecPolicyCheckRevocation, kSecPolicyCheckRevocationAny);
1880
1881 require(result = SecPolicyCreate(kSecPolicyAppleiPhoneProfileApplicationSigning,
1882 kSecPolicyNameiPhoneProfileApplicationSigning,
1883 options), errOut);
1884
1885 errOut:
1886 CFReleaseSafe(options);
1887 return result;
1888 }
1889
1890 SecPolicyRef SecPolicyCreateMacOSProfileApplicationSigning(void) {
1891 CFMutableDictionaryRef options = NULL;
1892 SecPolicyRef result = NULL;
1893
1894 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
1895 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut);
1896
1897 SecPolicyAddBasicCertOptions(options); // Without expiration checking
1898
1899 /* Apple Anchor */
1900 require_quiet(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameiPhoneProfileApplicationSigning),
1901 errOut);
1902
1903 /* Chain Len: 3 */
1904 require(SecPolicyAddChainLengthOptions(options, 3), errOut);
1905
1906 /* Leaf has CodeSigning EKU */
1907 add_eku_string(options, CFSTR("1.3.6.1.5.5.7.3.3"));
1908
1909
1910 /* On macOS, the cert in the provisioning profile may be one of:
1911 leaf OID intermediate OID
1912 MAS Development <ADS>.6.1.12 <ADS>.6.2.1
1913 MAS Submission <ADS>.6.1.7 <ADS>.6.2.1
1914 Developer ID <ADS>.6.1.13 <ADS>.6.2.6
1915 B&I <ADS>.6.22 None - "Apple Code Signing Certification Authority"
1916 */
1917 add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.6.1.12"));
1918 add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.6.1.7"));
1919 add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.6.1.13"));
1920 add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.6.22"));
1921
1922 /* Revocation via any available method */
1923 CFDictionaryAddValue(options, kSecPolicyCheckRevocation, kSecPolicyCheckRevocationAny);
1924
1925 require(result = SecPolicyCreate(kSecPolicyAppleMacOSProfileApplicationSigning,
1926 kSecPolicyNameMacOSProfileApplicationSigning,
1927 options), errOut);
1928
1929 errOut:
1930 CFReleaseSafe(options);
1931 return result;
1932 }
1933
1934 SecPolicyRef SecPolicyCreateiPhoneProvisioningProfileSigning(void) {
1935 CFMutableDictionaryRef options = NULL;
1936 SecPolicyRef result = NULL;
1937
1938 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
1939 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut);
1940
1941 SecPolicyAddBasicCertOptions(options);
1942
1943 /* Basic X.509 policy with the additional requirements that the chain
1944 length is 3, it's anchored at the AppleCA and the leaf certificate
1945 has issuer "Apple iPhone Certification Authority" and
1946 subject "Apple iPhone OS Provisioning Profile Signing" for the common name. */
1947 CFDictionaryAddValue(options, kSecPolicyCheckIssuerCommonName,
1948 CFSTR("Apple iPhone Certification Authority"));
1949 if (SecIsInternalRelease()) {
1950 CFDictionaryAddValue(options, kSecPolicyCheckSubjectCommonNameTEST,
1951 CFSTR("Apple iPhone OS Provisioning Profile Signing"));
1952 }
1953 else {
1954 CFDictionaryAddValue(options, kSecPolicyCheckSubjectCommonName,
1955 CFSTR("Apple iPhone OS Provisioning Profile Signing"));
1956 }
1957
1958 require(SecPolicyAddChainLengthOptions(options, 3), errOut);
1959 require(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameiPhoneProvisioningProfileSigning), errOut);
1960
1961 /* Skip networked revocation checks */
1962 CFDictionaryAddValue(options, kSecPolicyCheckNoNetworkAccess, kCFBooleanTrue);
1963
1964 require(result = SecPolicyCreate(kSecPolicyAppleiPhoneProvisioningProfileSigning,
1965 kSecPolicyNameiPhoneProvisioningProfileSigning, options),
1966 errOut);
1967
1968 /* 1.2.840.113635.100.6.2.2.1, non-critical: DER:05:00 - provisioning profile */
1969
1970 errOut:
1971 CFReleaseSafe(options);
1972 return result;
1973 }
1974
1975 SecPolicyRef SecPolicyCreateAppleTVOSApplicationSigning(void) {
1976 CFMutableDictionaryRef options = NULL;
1977 SecPolicyRef result = NULL;
1978 CFDataRef atvProdOid = NULL;
1979 CFDataRef atvTestOid = NULL;
1980 CFArrayRef oids = NULL;
1981
1982 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
1983 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut);
1984
1985 SecPolicyAddBasicCertOptions(options);
1986
1987 require(SecPolicyAddChainLengthOptions(options, 3), errOut);
1988
1989 require_quiet(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameTVOSApplicationSigning),
1990 errOut);
1991
1992 /* Check for intermediate: Apple Worldwide Developer Relations */
1993 /* 1.2.840.113635.100.6.2.1 */
1994 add_oid(options, kSecPolicyCheckIntermediateMarkerOid, &oidAppleIntmMarkerAppleWWDR);
1995
1996 add_ku(options, kSecKeyUsageDigitalSignature);
1997
1998 /* Check for prod or test AppleTV Application Signing OIDs */
1999 /* Prod: 1.2.840.113635.100.6.1.24 */
2000 /* ProdQA: 1.2.840.113635.100.6.1.24.1 */
2001 add_leaf_marker(options, &oidAppleTVOSApplicationSigningProd);
2002 add_leaf_marker(options, &oidAppleTVOSApplicationSigningProdQA);
2003
2004 /* Skip networked revocation checks */
2005 CFDictionaryAddValue(options, kSecPolicyCheckNoNetworkAccess, kCFBooleanTrue);
2006
2007 require(result = SecPolicyCreate(kSecPolicyAppleTVOSApplicationSigning,
2008 kSecPolicyNameTVOSApplicationSigning, options),
2009 errOut);
2010
2011 errOut:
2012 CFReleaseSafe(options);
2013 CFReleaseSafe(oids);
2014 CFReleaseSafe(atvProdOid);
2015 CFReleaseSafe(atvTestOid);
2016 return result;
2017 }
2018
2019 SecPolicyRef SecPolicyCreateOCSPSigner(void) {
2020 CFMutableDictionaryRef options = NULL;
2021 SecPolicyRef result = NULL;
2022
2023 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
2024 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut);
2025
2026 SecPolicyAddBasicX509Options(options);
2027
2028 /* Require id-kp-OCSPSigning extendedKeyUsage to be present, not optional. */
2029 add_eku(options, &oidExtendedKeyUsageOCSPSigning);
2030
2031 require(result = SecPolicyCreate(kSecPolicyAppleOCSPSigner,
2032 kSecPolicyNameOCSPSigner, options), errOut);
2033
2034 errOut:
2035 CFReleaseSafe(options);
2036 return result;
2037 }
2038
2039 SecPolicyRef SecPolicyCreateRevocation(CFOptionFlags revocationFlags) {
2040 CFMutableDictionaryRef options = NULL;
2041 SecPolicyRef result = NULL;
2042
2043 require(revocationFlags != 0, errOut);
2044
2045 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
2046 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut);
2047
2048 if (revocationFlags & kSecRevocationCheckIfTrusted) {
2049 CFDictionaryAddValue(options, kSecPolicyCheckRevocationIfTrusted, kCFBooleanTrue);
2050 /* Set method, but allow caller to override with later checks */
2051 CFDictionaryAddValue(options, kSecPolicyCheckRevocation, kSecPolicyCheckRevocationAny);
2052 }
2053
2054 if (revocationFlags & kSecRevocationOnlineCheck) {
2055 CFDictionaryAddValue(options, kSecPolicyCheckRevocationOnline, kCFBooleanTrue);
2056 /* Set method, but allow caller to override with later checks */
2057 CFDictionaryAddValue(options, kSecPolicyCheckRevocation, kSecPolicyCheckRevocationAny);
2058 }
2059
2060 if (revocationFlags & kSecRevocationOCSPMethod && revocationFlags & kSecRevocationCRLMethod) {
2061 CFDictionaryAddValue(options, kSecPolicyCheckRevocation, kSecPolicyCheckRevocationAny);
2062 }
2063 else if (revocationFlags & kSecRevocationOCSPMethod) {
2064 CFDictionaryAddValue(options, kSecPolicyCheckRevocation, kSecPolicyCheckRevocationOCSP);
2065 }
2066 else if (revocationFlags & kSecRevocationCRLMethod) {
2067 CFDictionaryAddValue(options, kSecPolicyCheckRevocation, kSecPolicyCheckRevocationCRL);
2068 }
2069
2070 if (revocationFlags & kSecRevocationRequirePositiveResponse) {
2071 CFDictionaryAddValue(options, kSecPolicyCheckRevocationResponseRequired, kCFBooleanTrue);
2072 }
2073
2074 if (revocationFlags & kSecRevocationNetworkAccessDisabled) {
2075 CFDictionaryAddValue(options, kSecPolicyCheckNoNetworkAccess, kCFBooleanTrue);
2076 } else {
2077 /* If the caller didn't explicitly disable network access, the revocation policy
2078 * should override any other policy's network setting.
2079 * In particular, pairing a revocation policy with BasicX509 should result in
2080 * allowing network access for revocation unless explicitly disabled.
2081 * Note that SecTrustSetNetworkFetchAllowed can override even this. */
2082 CFDictionaryAddValue(options, kSecPolicyCheckNoNetworkAccess, kCFBooleanFalse);
2083 }
2084
2085 /* Only flag bits 0-6 are currently defined */
2086 require(((revocationFlags >> 7) == 0), errOut);
2087
2088 require(result = SecPolicyCreate(kSecPolicyAppleRevocation,
2089 kSecPolicyNameRevocation, options), errOut);
2090
2091 errOut:
2092 CFReleaseSafe(options);
2093 return result;
2094 }
2095
2096 SecPolicyRef SecPolicyCreateSMIME(CFIndex smimeUsage, CFStringRef email) {
2097 CFMutableDictionaryRef options = NULL;
2098 SecPolicyRef result = NULL;
2099
2100 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
2101 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut);
2102
2103 if (smimeUsage & kSecIgnoreExpirationSMIMEUsage) {
2104 SecPolicyAddBasicCertOptions(options);
2105 } else {
2106 SecPolicyAddBasicX509Options(options);
2107 }
2108
2109 /* We call add_ku for each combination of bits we are willing to allow. */
2110 if (smimeUsage & kSecSignSMIMEUsage) {
2111 add_ku(options, kSecKeyUsageUnspecified);
2112 add_ku(options, kSecKeyUsageDigitalSignature);
2113 add_ku(options, kSecKeyUsageNonRepudiation);
2114 }
2115 if (smimeUsage & kSecKeyEncryptSMIMEUsage) {
2116 add_ku(options, kSecKeyUsageKeyEncipherment);
2117 }
2118 if (smimeUsage & kSecDataEncryptSMIMEUsage) {
2119 add_ku(options, kSecKeyUsageDataEncipherment);
2120 }
2121 if (smimeUsage & kSecKeyExchangeDecryptSMIMEUsage) {
2122 add_ku(options, kSecKeyUsageKeyAgreement | kSecKeyUsageDecipherOnly);
2123 }
2124 if (smimeUsage & kSecKeyExchangeEncryptSMIMEUsage) {
2125 add_ku(options, kSecKeyUsageKeyAgreement | kSecKeyUsageEncipherOnly);
2126 }
2127 if (smimeUsage & kSecKeyExchangeBothSMIMEUsage) {
2128 add_ku(options, kSecKeyUsageKeyAgreement | kSecKeyUsageEncipherOnly | kSecKeyUsageDecipherOnly);
2129 }
2130
2131 if (email) {
2132 CFDictionaryAddValue(options, kSecPolicyCheckEmail, email);
2133 }
2134
2135 /* RFC 3850 paragraph 4.4.4
2136
2137 If the extended key usage extension is present in the certificate
2138 then interpersonal message S/MIME receiving agents MUST check that it
2139 contains either the emailProtection or the anyExtendedKeyUsage OID as
2140 defined in [KEYM]. S/MIME uses other than interpersonal messaging
2141 MAY require the explicit presence of the extended key usage extension
2142 or other OIDs to be present in the extension or both.
2143 */
2144 add_eku(options, NULL); /* eku extension is optional */
2145 add_eku(options, &oidAnyExtendedKeyUsage);
2146 add_eku(options, &oidExtendedKeyUsageEmailProtection);
2147
2148 #if !TARGET_OS_IPHONE
2149 // Check revocation on OS X
2150 CFDictionaryAddValue(options, kSecPolicyCheckRevocation, kSecPolicyCheckRevocationAny);
2151 #endif
2152
2153 require(result = SecPolicyCreate(kSecPolicyAppleSMIME, kSecPolicyNameSMIME, options), errOut);
2154
2155 errOut:
2156 CFReleaseSafe(options);
2157 return result;
2158 }
2159
2160 SecPolicyRef SecPolicyCreateApplePackageSigning(void) {
2161 CFMutableDictionaryRef options = NULL;
2162 SecPolicyRef result = NULL;
2163
2164 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
2165 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut);
2166
2167 SecPolicyAddBasicCertOptions(options);
2168
2169 require(SecPolicyAddChainLengthOptions(options, 3), errOut);
2170 require(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNamePackageSigning), errOut);
2171
2172 add_ku(options, kSecKeyUsageDigitalSignature);
2173 add_eku(options, &oidExtendedKeyUsageCodeSigning);
2174
2175 require(result = SecPolicyCreate(kSecPolicyApplePackageSigning,
2176 kSecPolicyNamePackageSigning, options),
2177 errOut);
2178
2179 errOut:
2180 CFReleaseSafe(options);
2181 return result;
2182
2183 }
2184
2185 SecPolicyRef SecPolicyCreateAppleSWUpdateSigning(void) {
2186 CFMutableDictionaryRef options = NULL;
2187 SecPolicyRef result = NULL;
2188 /*
2189 * OS X rules for this policy:
2190 * -- Must have one intermediate cert
2191 * -- intermediate must have basic constraints with path length 0
2192 * -- intermediate has CSSMOID_APPLE_EKU_CODE_SIGNING EKU
2193 * -- leaf cert has either CODE_SIGNING or CODE_SIGN_DEVELOPMENT EKU (the latter of
2194 * which triggers a CSSMERR_APPLETP_CODE_SIGN_DEVELOPMENT error)
2195 */
2196 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
2197 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut);
2198
2199 SecPolicyAddBasicX509Options(options);
2200
2201 require(SecPolicyAddChainLengthOptions(options, 3), errOut);
2202 require(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameSWUpdateSigning), errOut);
2203
2204 add_eku(options, &oidAppleExtendedKeyUsageCodeSigning);
2205 add_oid(options, kSecPolicyCheckIntermediateEKU, &oidAppleExtendedKeyUsageCodeSigning);
2206
2207 require(result = SecPolicyCreate(kSecPolicyAppleSWUpdateSigning,
2208 kSecPolicyNameSWUpdateSigning, options),
2209 errOut);
2210
2211 errOut:
2212 CFReleaseSafe(options);
2213 return result;
2214
2215 }
2216
2217 SecPolicyRef SecPolicyCreateCodeSigning(void) {
2218 CFMutableDictionaryRef options = NULL;
2219 SecPolicyRef result = NULL;
2220
2221 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
2222 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut);
2223
2224 SecPolicyAddBasicX509Options(options);
2225
2226 /* If the key usage extension is present, we accept it having either of
2227 these values. */
2228 add_ku(options, kSecKeyUsageDigitalSignature);
2229 add_ku(options, kSecKeyUsageNonRepudiation);
2230
2231 /* We require an extended key usage extension with the codesigning
2232 eku purpose. (The Apple codesigning eku is not accepted here
2233 since it's valid only for SecPolicyCreateAppleSWUpdateSigning.) */
2234 add_eku(options, &oidExtendedKeyUsageCodeSigning);
2235 #if TARGET_OS_IPHONE
2236 /* Accept the 'any' eku on iOS only to match prior behavior.
2237 This may be further restricted in future releases. */
2238 add_eku(options, &oidAnyExtendedKeyUsage);
2239 #endif
2240
2241 require(result = SecPolicyCreate(kSecPolicyAppleCodeSigning,
2242 kSecPolicyNameCodeSigning, options),
2243 errOut);
2244
2245 errOut:
2246 CFReleaseSafe(options);
2247 return result;
2248 }
2249
2250 /* Explicitly leave out empty subject/subjectaltname check */
2251 SecPolicyRef SecPolicyCreateLockdownPairing(void) {
2252 CFMutableDictionaryRef options = NULL;
2253 SecPolicyRef result = NULL;
2254
2255 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
2256 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut);
2257 //CFDictionaryAddValue(options, kSecPolicyCheckBasicCertificateProcessing,
2258 // kCFBooleanTrue); // Happens automatically in SecPVCPathChecks
2259 CFDictionaryAddValue(options, kSecPolicyCheckCriticalExtensions,
2260 kCFBooleanTrue);
2261 CFDictionaryAddValue(options, kSecPolicyCheckIdLinkage,
2262 kCFBooleanTrue);
2263 CFDictionaryAddValue(options, kSecPolicyCheckBasicConstraints,
2264 kCFBooleanTrue);
2265 CFDictionaryAddValue(options, kSecPolicyCheckWeakKeySize, kCFBooleanTrue);
2266
2267 require(result = SecPolicyCreate(kSecPolicyAppleLockdownPairing,
2268 kSecPolicyNameLockdownPairing, options), errOut);
2269
2270 errOut:
2271 CFReleaseSafe(options);
2272 return result;
2273 }
2274
2275 SecPolicyRef SecPolicyCreateURLBag(void) {
2276 CFMutableDictionaryRef options = NULL;
2277 SecPolicyRef result = NULL;
2278
2279 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
2280 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut);
2281
2282 SecPolicyAddBasicCertOptions(options);
2283
2284 add_eku(options, &oidExtendedKeyUsageCodeSigning);
2285
2286 require(result = SecPolicyCreate(kSecPolicyAppleURLBag,
2287 kSecPolicyNameURLBag, options), errOut);
2288
2289 errOut:
2290 CFReleaseSafe(options);
2291 return result;
2292 }
2293
2294 SecPolicyRef SecPolicyCreateOTATasking(void)
2295 {
2296 CFMutableDictionaryRef options = NULL;
2297 SecPolicyRef result = NULL;
2298
2299 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
2300 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut);
2301
2302 SecPolicyAddBasicX509Options(options);
2303
2304 /* Apple Anchor */
2305 require(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameMobileAsset), errOut);
2306
2307 /* Chain length of 3 */
2308 require(SecPolicyAddChainLengthOptions(options, 3), errOut);
2309
2310 /* Intermediate has common name "Apple iPhone Certification Authority". */
2311 CFDictionaryAddValue(options, kSecPolicyCheckIssuerCommonName,
2312 CFSTR("Apple iPhone Certification Authority"));
2313
2314 /* Leaf has common name "Asset Manifest Signing" */
2315 CFDictionaryAddValue(options, kSecPolicyCheckSubjectCommonName, CFSTR("OTA Task Signing"));
2316
2317 require(result = SecPolicyCreate(kSecPolicyAppleOTATasking, kSecPolicyNameOTATasking, options),
2318 errOut);
2319
2320 errOut:
2321 CFReleaseSafe(options);
2322 return result;
2323 }
2324
2325 SecPolicyRef SecPolicyCreateMobileAsset(void)
2326 {
2327 CFMutableDictionaryRef options = NULL;
2328 SecPolicyRef result = NULL;
2329
2330 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
2331 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut);
2332
2333 /* No expiration check */
2334 SecPolicyAddBasicCertOptions(options);
2335
2336 /* Apple Anchor */
2337 require(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameMobileAsset), errOut);
2338
2339 /* Chain length of 3 */
2340 require(SecPolicyAddChainLengthOptions(options, 3), errOut);
2341
2342 /* Intermediate has common name "Apple iPhone Certification Authority". */
2343 CFDictionaryAddValue(options, kSecPolicyCheckIssuerCommonName,
2344 CFSTR("Apple iPhone Certification Authority"));
2345
2346 /* Leaf has common name "Asset Manifest Signing" */
2347 CFDictionaryAddValue(options, kSecPolicyCheckSubjectCommonName, CFSTR("Asset Manifest Signing"));
2348
2349 require(result = SecPolicyCreate(kSecPolicyAppleMobileAsset, kSecPolicyNameMobileAsset, options),
2350 errOut);
2351
2352 errOut:
2353 CFReleaseSafe(options);
2354 return result;
2355 }
2356
2357 SecPolicyRef SecPolicyCreateMobileAssetDevelopment(void) {
2358 CFMutableDictionaryRef options = NULL;
2359 SecPolicyRef result = NULL;
2360
2361 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
2362 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut);
2363
2364 /* No expiration check */
2365 SecPolicyAddBasicCertOptions(options);
2366
2367 /* Apple Anchor */
2368 require(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameMobileAsset), errOut);
2369
2370 /* Chain length of 3 */
2371 require(SecPolicyAddChainLengthOptions(options, 3), errOut);
2372
2373 /* Intermediate has the iPhone CA Marker extension */
2374 add_element(options, kSecPolicyCheckIntermediateMarkerOid, CFSTR("1.2.840.113635.100.6.2.18"));
2375
2376 /* Leaf has ProdQA Mobile Asset Marker extension */
2377 add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.6.55.1"));
2378
2379 require(result = SecPolicyCreate(kSecPolicyAppleMobileAssetDevelopment, kSecPolicyNameMobileAsset, options),
2380 errOut);
2381
2382 errOut:
2383 CFReleaseSafe(options);
2384 return result;
2385 }
2386
2387 SecPolicyRef SecPolicyCreateAppleIDAuthorityPolicy(void)
2388 {
2389 SecPolicyRef result = NULL;
2390 CFMutableDictionaryRef options = NULL;
2391 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
2392 &kCFTypeDictionaryKeyCallBacks,
2393 &kCFTypeDictionaryValueCallBacks), out);
2394
2395 //Leaf appears to be a SSL only cert, so policy should expand on that policy
2396 SecPolicyAddBasicX509Options(options);
2397
2398 // Apple CA anchored
2399 require(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameIDAuthority), out);
2400
2401 // with the addition of the existence check of an extension with "Apple ID Sharing Certificate" oid (1.2.840.113635.100.4.7)
2402 // NOTE: this obviously intended to have gone into Extended Key Usage, but evidence of existing certs proves the contrary.
2403 add_leaf_marker(options, &oidAppleExtendedKeyUsageAppleID);
2404
2405 // 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.
2406 add_oid(options, kSecPolicyCheckIntermediateMarkerOid, &oidAppleIntmMarkerAppleID);
2407 add_oid(options, kSecPolicyCheckIntermediateMarkerOid, &oidAppleIntmMarkerAppleID2);
2408
2409 require(result = SecPolicyCreate(kSecPolicyAppleIDAuthority,
2410 kSecPolicyNameIDAuthority, options), out);
2411
2412 out:
2413 CFReleaseSafe(options);
2414 return result;
2415 }
2416
2417 SecPolicyRef SecPolicyCreateMacAppStoreReceipt(void)
2418 {
2419 SecPolicyRef result = NULL;
2420 CFMutableDictionaryRef options = NULL;
2421 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
2422 &kCFTypeDictionaryKeyCallBacks,
2423 &kCFTypeDictionaryValueCallBacks), out);
2424
2425 SecPolicyAddBasicX509Options(options);
2426
2427 // Apple CA anchored
2428 require(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameMacAppStoreReceipt), out);
2429
2430 // Chain length of 3
2431 require(SecPolicyAddChainLengthOptions(options, 3), out);
2432
2433 // MacAppStoreReceipt policy OID
2434 add_certificate_policy_oid_string(options, CFSTR("1.2.840.113635.100.5.6.1"));
2435
2436 // Intermediate marker OID
2437 add_element(options, kSecPolicyCheckIntermediateMarkerOid, CFSTR("1.2.840.113635.100.6.2.1"));
2438
2439 // Leaf marker OID
2440 add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.6.11.1"));
2441
2442 // Check revocation
2443 CFDictionaryAddValue(options, kSecPolicyCheckRevocation, kSecPolicyCheckRevocationAny);
2444
2445 require(result = SecPolicyCreate(kSecPolicyMacAppStoreReceipt,
2446 kSecPolicyNameMacAppStoreReceipt, options), out);
2447
2448 out:
2449 CFReleaseSafe(options);
2450 return result;
2451
2452 }
2453
2454 static SecPolicyRef _SecPolicyCreatePassbookCardSigner(CFStringRef cardIssuer, CFStringRef teamIdentifier, bool requireTeamID)
2455 {
2456 SecPolicyRef result = NULL;
2457 CFMutableDictionaryRef options = NULL;
2458 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
2459 &kCFTypeDictionaryKeyCallBacks,
2460 &kCFTypeDictionaryValueCallBacks), out);
2461
2462 SecPolicyAddBasicX509Options(options);
2463 require(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNamePassbookSigning), out);
2464
2465 // Chain length of 3
2466 require(SecPolicyAddChainLengthOptions(options, 3), out);
2467
2468 if (teamIdentifier) {
2469 // If supplied, teamIdentifier must match subject OU field
2470 CFDictionaryAddValue(options, kSecPolicyCheckSubjectOrganizationalUnit, teamIdentifier);
2471 }
2472 else {
2473 // If not supplied, and it was required, fail
2474 require(!requireTeamID, out);
2475 }
2476
2477 // Must be both push and 3rd party package signing
2478 add_leaf_marker_value(options, &oidAppleInstallerPackagingSigningExternal, cardIssuer);
2479
2480 // We should check that it also has push marker, but we don't support requiring both, only either.
2481 // add_independent_oid(options, kSecPolicyCheckLeafMarkerOid, &oidApplePushServiceClient);
2482
2483 //WWDR Intermediate marker OID
2484 add_element(options, kSecPolicyCheckIntermediateMarkerOid, CFSTR("1.2.840.113635.100.6.2.1"));
2485
2486 // And Passbook signing eku
2487 add_eku(options, &oidAppleExtendedKeyUsagePassbook);
2488
2489 require(result = SecPolicyCreate(kSecPolicyApplePassbookSigning,
2490 kSecPolicyNamePassbookSigning, options), out);
2491
2492 out:
2493 CFReleaseSafe(options);
2494 return result;
2495 }
2496
2497 SecPolicyRef SecPolicyCreatePassbookCardSigner(CFStringRef cardIssuer, CFStringRef teamIdentifier)
2498 {
2499 return _SecPolicyCreatePassbookCardSigner(cardIssuer, teamIdentifier, true);
2500 }
2501
2502
2503 static SecPolicyRef CreateMobileStoreSigner(Boolean forTest)
2504 {
2505
2506 SecPolicyRef result = NULL;
2507 CFMutableDictionaryRef options = NULL;
2508 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
2509 &kCFTypeDictionaryKeyCallBacks,
2510 &kCFTypeDictionaryValueCallBacks), errOut);
2511 SecPolicyAddBasicX509Options(options);
2512 require(SecPolicyAddAppleAnchorOptions(options,
2513 ((forTest) ? kSecPolicyNameTestMobileStore :
2514 kSecPolicyNameMobileStore)), errOut);
2515
2516 require(SecPolicyAddChainLengthOptions(options, 3), errOut);
2517
2518 CFDictionaryAddValue(options, kSecPolicyCheckIssuerCommonName,
2519 CFSTR("Apple System Integration 2 Certification Authority"));
2520
2521 add_ku(options, kSecKeyUsageDigitalSignature);
2522
2523 const DERItem* pOID = (forTest) ? &oidApplePolicyMobileStoreProdQA : &oidApplePolicyMobileStore;
2524
2525 add_certificate_policy_oid(options, pOID);
2526
2527 require(result = SecPolicyCreate((forTest) ? kSecPolicyAppleTestMobileStore : kSecPolicyAppleMobileStore,
2528 (forTest) ? kSecPolicyNameTestMobileStore : kSecPolicyNameMobileStore,
2529 options), errOut);
2530
2531 errOut:
2532 CFReleaseSafe(options);
2533 return result;
2534 }
2535
2536 SecPolicyRef SecPolicyCreateMobileStoreSigner(void)
2537 {
2538 return CreateMobileStoreSigner(false);
2539 }
2540
2541 SecPolicyRef SecPolicyCreateTestMobileStoreSigner(void)
2542 {
2543 return CreateMobileStoreSigner(true);
2544 }
2545
2546
2547 CF_RETURNS_RETAINED SecPolicyRef SecPolicyCreateEscrowServiceSigner(void)
2548 {
2549 SecPolicyRef result = NULL;
2550 CFMutableDictionaryRef options = NULL;
2551 CFArrayRef anArray = NULL;
2552 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
2553 &kCFTypeDictionaryKeyCallBacks,
2554 &kCFTypeDictionaryValueCallBacks), errOut);
2555
2556 // X509, ignoring date validity
2557 SecPolicyAddBasicCertOptions(options);
2558
2559
2560 add_ku(options, kSecKeyUsageKeyEncipherment);
2561
2562 /* Leaf has marker OID with value that can't be pre-determined */
2563 add_element(options, kSecPolicyCheckLeafMarkerOidWithoutValueCheck, CFSTR("1.2.840.113635.100.6.23.1"));
2564 require(SecPolicyAddChainLengthOptions(options, 2), errOut);
2565
2566
2567 Boolean anchorAdded = false;
2568 // Get the roots by calling the SecCertificateCopyEscrowRoots
2569 anArray = SecCertificateCopyEscrowRoots(kSecCertificateProductionEscrowRoot);
2570 CFIndex numRoots = 0;
2571 if (NULL == anArray || 0 == (numRoots = CFArrayGetCount(anArray)))
2572 {
2573 goto errOut;
2574 }
2575
2576 for (CFIndex iCnt = 0; iCnt < numRoots; iCnt++)
2577 {
2578 SecCertificateRef aCert = (SecCertificateRef)CFArrayGetValueAtIndex(anArray, iCnt);
2579
2580 if (NULL != aCert)
2581 {
2582 CFDataRef sha_data = SecCertificateGetSHA1Digest(aCert);
2583 if (NULL != sha_data)
2584 {
2585 const UInt8* pSHAData = CFDataGetBytePtr(sha_data);
2586 if (NULL != pSHAData)
2587 {
2588 SecPolicyAddAnchorSHA1Options(options, pSHAData);
2589 anchorAdded = true;
2590 }
2591 }
2592 }
2593 }
2594 CFReleaseNull(anArray);
2595
2596 if (!anchorAdded)
2597 {
2598 goto errOut;
2599 }
2600
2601
2602 require(result = SecPolicyCreate(kSecPolicyAppleEscrowService,
2603 kSecPolicyNameEscrowService, options), errOut);
2604
2605 errOut:
2606 CFReleaseSafe(anArray);
2607 CFReleaseSafe(options);
2608 return result;
2609 }
2610
2611 CF_RETURNS_RETAINED SecPolicyRef SecPolicyCreatePCSEscrowServiceSigner(void)
2612 {
2613 SecPolicyRef result = NULL;
2614 CFMutableDictionaryRef options = NULL;
2615 CFArrayRef anArray = NULL;
2616 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
2617 &kCFTypeDictionaryKeyCallBacks,
2618 &kCFTypeDictionaryValueCallBacks), errOut);
2619
2620 SecPolicyAddBasicX509Options(options);
2621
2622
2623 add_ku(options, kSecKeyUsageKeyEncipherment);
2624
2625 /* Leaf has marker OID with value that can't be pre-determined */
2626 add_element(options, kSecPolicyCheckLeafMarkerOidWithoutValueCheck, CFSTR("1.2.840.113635.100.6.23.1"));
2627 require(SecPolicyAddChainLengthOptions(options, 2), errOut);
2628
2629
2630 Boolean anchorAdded = false;
2631 anArray = SecCertificateCopyEscrowRoots(kSecCertificateProductionPCSEscrowRoot);
2632 CFIndex numRoots = 0;
2633 if (NULL == anArray || 0 == (numRoots = CFArrayGetCount(anArray)))
2634 {
2635 goto errOut;
2636 }
2637
2638 for (CFIndex iCnt = 0; iCnt < numRoots; iCnt++)
2639 {
2640 SecCertificateRef aCert = (SecCertificateRef)CFArrayGetValueAtIndex(anArray, iCnt);
2641
2642 if (NULL != aCert)
2643 {
2644 CFDataRef sha_data = SecCertificateGetSHA1Digest(aCert);
2645 if (NULL != sha_data)
2646 {
2647 const UInt8* pSHAData = CFDataGetBytePtr(sha_data);
2648 if (NULL != pSHAData)
2649 {
2650 SecPolicyAddAnchorSHA1Options(options, pSHAData);
2651 anchorAdded = true;
2652 }
2653 }
2654 }
2655 }
2656 CFReleaseNull(anArray);
2657
2658 if (!anchorAdded)
2659 {
2660 goto errOut;
2661 }
2662
2663
2664 require(result = SecPolicyCreate(kSecPolicyApplePCSEscrowService,
2665 kSecPolicyNamePCSEscrowService, options), errOut);
2666
2667 errOut:
2668 CFReleaseSafe(anArray);
2669 CFReleaseSafe(options);
2670 return result;
2671 }
2672
2673 static SecPolicyRef CreateConfigurationProfileSigner(bool forTest) {
2674 SecPolicyRef result = NULL;
2675 CFMutableDictionaryRef options = NULL;
2676 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
2677 &kCFTypeDictionaryKeyCallBacks,
2678 &kCFTypeDictionaryValueCallBacks), errOut);
2679
2680 SecPolicyAddBasicX509Options(options);
2681 require(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameProfileSigner), errOut);
2682
2683 //Chain length 3
2684 require(SecPolicyAddChainLengthOptions(options, 3), errOut);
2685
2686 // Require the profile signing EKU
2687 const DERItem* pOID = (forTest) ? &oidAppleExtendedKeyUsageQAProfileSigning :&oidAppleExtendedKeyUsageProfileSigning;
2688 add_eku(options, pOID);
2689
2690 // Require the Apple Application Integration CA marker OID
2691 add_element(options, kSecPolicyCheckIntermediateMarkerOid, CFSTR("1.2.840.113635.100.6.2.3"));
2692
2693 require(result = SecPolicyCreate((forTest) ? kSecPolicyAppleQAProfileSigner: kSecPolicyAppleProfileSigner,
2694 (forTest) ? kSecPolicyNameQAProfileSigner : kSecPolicyNameProfileSigner,
2695 options), errOut);
2696
2697 errOut:
2698 CFReleaseSafe(options);
2699 return result;
2700 }
2701
2702 SecPolicyRef SecPolicyCreateConfigurationProfileSigner(void)
2703 {
2704 return CreateConfigurationProfileSigner(false);
2705 }
2706
2707
2708 SecPolicyRef SecPolicyCreateQAConfigurationProfileSigner(void)
2709 {
2710 if (SecIsInternalRelease()) {
2711 return CreateConfigurationProfileSigner(true);
2712 } else {
2713 return CreateConfigurationProfileSigner(false);
2714 }
2715 }
2716
2717 SecPolicyRef SecPolicyCreateOSXProvisioningProfileSigning(void)
2718 {
2719 SecPolicyRef result = NULL;
2720 CFMutableDictionaryRef options = NULL;
2721 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
2722 &kCFTypeDictionaryKeyCallBacks,
2723 &kCFTypeDictionaryValueCallBacks), errOut);
2724 // Require valid chain from the Apple root
2725 SecPolicyAddBasicX509Options(options);
2726 SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameOSXProvisioningProfileSigning);
2727
2728 // Require provisioning profile leaf marker OID (1.2.840.113635.100.4.11)
2729 add_leaf_marker(options, &oidAppleCertExtOSXProvisioningProfileSigning);
2730
2731 // Require intermediate marker OID (1.2.840.113635.100.6.2.1)
2732 add_oid(options, kSecPolicyCheckIntermediateMarkerOid, &oidAppleIntmMarkerAppleWWDR);
2733
2734 // Require key usage that allows signing
2735 add_ku(options, kSecKeyUsageDigitalSignature);
2736
2737 // Ensure that revocation is checked (OCSP)
2738 CFDictionaryAddValue(options, kSecPolicyCheckRevocation, kSecPolicyCheckRevocationOCSP);
2739
2740 require(result = SecPolicyCreate(kSecPolicyAppleOSXProvisioningProfileSigning,
2741 kSecPolicyNameOSXProvisioningProfileSigning, options), errOut);
2742
2743 errOut:
2744 CFReleaseSafe(options);
2745 return result;
2746 }
2747
2748
2749 SecPolicyRef SecPolicyCreateOTAPKISigner(void)
2750 {
2751 SecPolicyRef result = NULL;
2752 CFMutableDictionaryRef options = NULL;
2753 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
2754 &kCFTypeDictionaryKeyCallBacks,
2755 &kCFTypeDictionaryValueCallBacks), errOut);
2756 SecPolicyAddBasicX509Options(options);
2757
2758 SecPolicyAddAnchorSHA1Options(options, kApplePKISettingsAuthority);
2759 require(SecPolicyAddChainLengthOptions(options, 2), errOut);
2760
2761 require(result = SecPolicyCreate(kSecPolicyAppleOTAPKISigner,
2762 kSecPolicyNameOTAPKISigner, options), errOut);
2763
2764 errOut:
2765 CFReleaseSafe(options);
2766 return result;
2767
2768 }
2769
2770
2771 SecPolicyRef SecPolicyCreateTestOTAPKISigner(void)
2772 {
2773 /* Guard against use on production devices */
2774 if (!SecIsInternalRelease()) {
2775 return SecPolicyCreateOTAPKISigner();
2776 }
2777
2778 SecPolicyRef result = NULL;
2779 CFMutableDictionaryRef options = NULL;
2780 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
2781 &kCFTypeDictionaryKeyCallBacks,
2782 &kCFTypeDictionaryValueCallBacks), errOut);
2783 SecPolicyAddBasicX509Options(options);
2784
2785 SecPolicyAddAnchorSHA1Options(options, kAppleTestPKISettingsAuthority);
2786 require(SecPolicyAddChainLengthOptions(options, 2), errOut);
2787
2788 require(result = SecPolicyCreate(kSecPolicyAppleTestOTAPKISigner,
2789 kSecPolicyNameTestOTAPKISigner, options), errOut);
2790
2791 errOut:
2792 CFReleaseSafe(options);
2793 return result;
2794 }
2795
2796 /*!
2797 @function SecPolicyCreateAppleSMPEncryption
2798 @abstract Check for intermediate certificate 'Apple System Integration CA - G3' by name,
2799 and root certificate 'Apple Root CA - G3' by hash.
2800 Leaf cert must have Key Encipherment usage.
2801 Leaf cert must have Apple SMP Encryption marker OID (1.2.840.113635.100.6.30).
2802 Intermediate must have marker OID (1.2.840.113635.100.6.2.13).
2803 */
2804 SecPolicyRef SecPolicyCreateAppleSMPEncryption(void)
2805 {
2806 SecPolicyRef result = NULL;
2807 CFMutableDictionaryRef options = NULL;
2808 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
2809 &kCFTypeDictionaryKeyCallBacks,
2810 &kCFTypeDictionaryValueCallBacks), errOut);
2811 SecPolicyAddBasicCertOptions(options);
2812
2813 require(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameSMPEncryption),
2814 errOut);
2815 require(SecPolicyAddChainLengthOptions(options, 3), errOut);
2816
2817 CFDictionaryAddValue(options, kSecPolicyCheckIssuerCommonName,
2818 CFSTR("Apple System Integration CA - G3"));
2819
2820 // Check that leaf has extension with "Apple SMP Encryption" oid (1.2.840.113635.100.6.30)
2821 add_leaf_marker(options, &oidAppleCertExtAppleSMPEncryption);
2822
2823 // Check that intermediate has extension (1.2.840.113635.100.6.2.13)
2824 add_oid(options, kSecPolicyCheckIntermediateMarkerOid, &oidAppleIntmMarkerAppleSystemIntgG3);
2825
2826 add_ku(options, kSecKeyUsageKeyEncipherment);
2827
2828 // Ensure that revocation is checked (OCSP)
2829 CFDictionaryAddValue(options, kSecPolicyCheckRevocation, kSecPolicyCheckRevocationOCSP);
2830
2831 require(result = SecPolicyCreate(kSecPolicyAppleSMPEncryption,
2832 kSecPolicyNameSMPEncryption, options), errOut);
2833
2834 errOut:
2835 CFReleaseSafe(options);
2836 return result;
2837 }
2838
2839 /*!
2840 @function SecPolicyCreateTestAppleSMPEncryption
2841 @abstract Check for intermediate certificate 'Test Apple System Integration CA - ECC' by name,
2842 and root certificate 'Test Apple Root CA - ECC' by hash.
2843 Leaf cert must have Key Encipherment usage. Other checks TBD.
2844 */
2845 SecPolicyRef SecPolicyCreateTestAppleSMPEncryption(void)
2846 {
2847 SecPolicyRef result = NULL;
2848 CFMutableDictionaryRef options = NULL;
2849 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
2850 &kCFTypeDictionaryKeyCallBacks,
2851 &kCFTypeDictionaryValueCallBacks), errOut);
2852 SecPolicyAddBasicCertOptions(options);
2853
2854 SecPolicyAddAnchorSHA1Options(options, kTestAppleRootCA_ECC_SHA1);
2855 require(SecPolicyAddChainLengthOptions(options, 3), errOut);
2856
2857 CFDictionaryAddValue(options, kSecPolicyCheckIssuerCommonName,
2858 CFSTR("Test Apple System Integration CA - ECC"));
2859
2860 add_ku(options, kSecKeyUsageKeyEncipherment);
2861
2862 // Ensure that revocation is checked (OCSP)
2863 CFDictionaryAddValue(options, kSecPolicyCheckRevocation, kSecPolicyCheckRevocationOCSP);
2864
2865 require(result = SecPolicyCreate(kSecPolicyAppleTestSMPEncryption,
2866 kSecPolicyNameTestSMPEncryption, options), errOut);
2867
2868 errOut:
2869 CFReleaseSafe(options);
2870 return result;
2871 }
2872
2873
2874 SecPolicyRef SecPolicyCreateAppleIDValidationRecordSigningPolicy(void)
2875 {
2876 SecPolicyRef result = NULL;
2877 CFMutableDictionaryRef options = NULL;
2878 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
2879 &kCFTypeDictionaryKeyCallBacks,
2880 &kCFTypeDictionaryValueCallBacks), errOut);
2881
2882 //Leaf appears to be a SSL only cert, so policy should expand on that policy
2883 SecPolicyAddBasicX509Options(options);
2884
2885 // Apple CA anchored
2886 require(SecPolicyAddAppleAnchorOptions(options,
2887 kSecPolicyNameIDValidationRecordSigning),
2888 errOut);
2889
2890 // Check for an extension with " Apple ID Validation Record Signing" oid (1.2.840.113635.100.6.25)
2891 add_leaf_marker(options, &oidAppleCertExtensionAppleIDRecordValidationSigning);
2892
2893 // and validate that intermediate has extension
2894 // Application Integration Intermediate Certificate (1.2.840.113635.100.6.2.3)
2895 // and also validate that intermediate has extension
2896 // System Integration 2 Intermediate Certificate (1.2.840.113635.100.6.2.10)
2897 add_oid(options, kSecPolicyCheckIntermediateMarkerOid, &oidAppleIntmMarkerAppleID);
2898 add_oid(options, kSecPolicyCheckIntermediateMarkerOid, &oidAppleIntmMarkerAppleSystemIntg2);
2899
2900 // Ensure that revocation is checked (OCSP)
2901 CFDictionaryAddValue(options, kSecPolicyCheckRevocation, kSecPolicyCheckRevocationOCSP);
2902
2903 require(result = SecPolicyCreate(kSecPolicyAppleIDValidationRecordSigning,
2904 kSecPolicyNameIDValidationRecordSigning, options), errOut);
2905
2906 errOut:
2907 CFReleaseSafe(options);
2908 return result;
2909 }
2910
2911 /*!
2912 @function SecPolicyCreateAppleServerAuthCommon
2913 @abstract Generic policy for server authentication Sub CAs
2914
2915 Allows control for both if pinning is required at all and if UAT environments should be added
2916 to the trust policy.
2917
2918 No pinning is for developer/QA that needs to use proxy to debug the protocol, while UAT
2919 environment is for QA/internal developer that have no need allow fake servers.
2920
2921 Both the noPinning and UAT are gated on that you run on internal hardware.
2922
2923 */
2924
2925 static SecPolicyRef
2926 SecPolicyCreateAppleServerAuthCommon(CFStringRef hostname,
2927 CFDictionaryRef __unused context,
2928 CFStringRef policyOID, CFStringRef service,
2929 const DERItem *leafMarkerOID,
2930 const DERItem *UATLeafMarkerOID)
2931 {
2932 CFMutableDictionaryRef appleAnchorOptions = NULL;
2933 CFMutableDictionaryRef options = NULL;
2934 SecPolicyRef result = NULL;
2935 CFDataRef oid = NULL, uatoid = NULL;
2936
2937 options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
2938 require(options, errOut);
2939
2940 SecPolicyAddBasicX509Options(options);
2941
2942 require(hostname, errOut);
2943 CFDictionaryAddValue(options, kSecPolicyCheckSSLHostname, hostname);
2944
2945 CFDictionaryAddValue(options, kSecPolicyCheckBlackListedLeaf, kCFBooleanTrue);
2946 CFDictionaryAddValue(options, kSecPolicyCheckGrayListedLeaf, kCFBooleanTrue);
2947
2948 add_eku(options, &oidExtendedKeyUsageServerAuth);
2949
2950 if (requireUATPinning(service)) {
2951
2952 /*
2953 * Require pinning to the Apple CA's.
2954 */
2955 SecPolicyAddAppleAnchorOptions(options, service);
2956
2957 /* old-style leaf marker OIDs */
2958 if (UATLeafMarkerOID) {
2959 add_leaf_prod_qa_markers(options, leafMarkerOID, UATLeafMarkerOID);
2960 } else {
2961 add_leaf_marker(options, leafMarkerOID);
2962 }
2963
2964 /* new-style leaf marker OIDs */
2965 CFStringRef leafMarkerOIDStr = NULL, UATLeafMarkerOIDStr = NULL;
2966 leafMarkerOIDStr = SecDERItemCopyOIDDecimalRepresentation(NULL, leafMarkerOID);
2967 if (UATLeafMarkerOID) {
2968 UATLeafMarkerOIDStr = SecDERItemCopyOIDDecimalRepresentation(NULL, UATLeafMarkerOID);
2969 }
2970
2971 if (leafMarkerOIDStr && UATLeafMarkerOIDStr) {
2972 add_leaf_prod_qa_markers_value_string(options,
2973 CFSTR("1.2.840.113635.100.6.48.1"), leafMarkerOIDStr,
2974 CFSTR("1.2.840.113635.100.6.48.1"), UATLeafMarkerOIDStr);
2975 } else if (leafMarkerOIDStr) {
2976 add_leaf_marker_value_string(options, CFSTR("1.2.840.113635.100.6.48.1"), leafMarkerOIDStr);
2977 }
2978
2979 CFReleaseNull(leafMarkerOIDStr);
2980 CFReleaseNull(UATLeafMarkerOIDStr);
2981
2982 add_oid(options, kSecPolicyCheckIntermediateMarkerOid, &oidAppleIntmMarkerAppleServerAuthentication);
2983 }
2984
2985 /* Check for weak hashes and keys */
2986 CFDictionaryAddValue(options, kSecPolicyCheckSystemTrustedWeakHash, kCFBooleanTrue);
2987 require(SecPolicyAddStrongKeySizeOptions(options), errOut);
2988
2989 CFDictionaryAddValue(options, kSecPolicyCheckRevocation, kSecPolicyCheckRevocationAny);
2990
2991 result = SecPolicyCreate(policyOID, service, options);
2992 require(result, errOut);
2993
2994 errOut:
2995 CFReleaseSafe(appleAnchorOptions);
2996 CFReleaseSafe(options);
2997 CFReleaseSafe(oid);
2998 CFReleaseSafe(uatoid);
2999 return result;
3000 }
3001
3002 /*!
3003 @function SecPolicyCreateAppleIDSService
3004 @abstract Ensure we're appropriately pinned to the IDS service (SSL + Apple restrictions)
3005 */
3006 SecPolicyRef SecPolicyCreateAppleIDSService(CFStringRef hostname)
3007 {
3008 SecPolicyRef result = SecPolicyCreateSSL(true, hostname);
3009
3010 SecPolicySetOid(result, kSecPolicyAppleIDSService);
3011 SecPolicySetName(result, kSecPolicyNameAppleIDSBag);
3012
3013 return result;
3014 }
3015
3016 /*!
3017 @function SecPolicyCreateAppleIDSService
3018 @abstract Ensure we're appropriately pinned to the IDS service (SSL + Apple restrictions)
3019 */
3020 SecPolicyRef SecPolicyCreateAppleIDSServiceContext(CFStringRef hostname, CFDictionaryRef context)
3021 {
3022 return SecPolicyCreateAppleServerAuthCommon(hostname, context, kSecPolicyAppleIDSServiceContext,
3023 kSecPolicyNameAppleIDSService,
3024 &oidAppleCertExtAppleServerAuthenticationIDSProd,
3025 &oidAppleCertExtAppleServerAuthenticationIDSProdQA);
3026 }
3027
3028 /*!
3029 @function SecPolicyCreateAppleGSService
3030 @abstract Ensure we're appropriately pinned to the GS service
3031 */
3032 SecPolicyRef SecPolicyCreateAppleGSService(CFStringRef hostname, CFDictionaryRef context)
3033 {
3034 return SecPolicyCreateAppleServerAuthCommon(hostname, context, kSecPolicyAppleGSService,
3035 kSecPolicyNameAppleGSService,
3036 &oidAppleCertExtAppleServerAuthenticationGS,
3037 NULL);
3038 }
3039
3040 /*!
3041 @function SecPolicyCreateApplePushService
3042 @abstract Ensure we're appropriately pinned to the Push service (SSL + Apple restrictions)
3043 */
3044 SecPolicyRef SecPolicyCreateApplePushService(CFStringRef hostname, CFDictionaryRef context)
3045 {
3046 return SecPolicyCreateAppleServerAuthCommon(hostname, context, kSecPolicyApplePushService,
3047 kSecPolicyNameApplePushService,
3048 &oidAppleCertExtAppleServerAuthenticationAPNProd,
3049 &oidAppleCertExtAppleServerAuthenticationAPNProdQA);
3050 }
3051
3052 /*!
3053 @function SecPolicyCreateApplePPQService
3054 @abstract Ensure we're appropriately pinned to the PPQ service (SSL + Apple restrictions)
3055 */
3056 SecPolicyRef SecPolicyCreateApplePPQService(CFStringRef hostname, CFDictionaryRef context)
3057 {
3058 return SecPolicyCreateAppleServerAuthCommon(hostname, context, kSecPolicyApplePPQService,
3059 kSecPolicyNameApplePPQService,
3060 &oidAppleCertExtAppleServerAuthenticationPPQProd ,
3061 &oidAppleCertExtAppleServerAuthenticationPPQProdQA);
3062 }
3063
3064 /*!
3065 @function SecPolicyCreateAppleAST2Service
3066 @abstract Ensure we're appropriately pinned to the AST2 Diagnostic service (SSL + Apple restrictions)
3067 */
3068 SecPolicyRef SecPolicyCreateAppleAST2Service(CFStringRef hostname, CFDictionaryRef context)
3069 {
3070 return SecPolicyCreateAppleServerAuthCommon(hostname, context, kSecPolicyAppleAST2DiagnosticsServerAuth,
3071 kSecPolicyNameAppleAST2Service,
3072 &oidAppleCertExtAST2DiagnosticsServerAuthProd,
3073 &oidAppleCertExtAST2DiagnosticsServerAuthProdQA);
3074 }
3075
3076 /*!
3077 @function SecPolicyCreateAppleEscrowProxyService
3078 @abstract Ensure we're appropriately pinned to the iCloud Escrow Proxy service (SSL + Apple restrictions)
3079 */
3080 SecPolicyRef SecPolicyCreateAppleEscrowProxyService(CFStringRef hostname, CFDictionaryRef context)
3081 {
3082 return SecPolicyCreateAppleServerAuthCommon(hostname, context, kSecPolicyAppleEscrowProxyServerAuth,
3083 kSecPolicyNameAppleEscrowProxyService,
3084 &oidAppleCertExtEscrowProxyServerAuthProd,
3085 &oidAppleCertExtEscrowProxyServerAuthProdQA);
3086 }
3087
3088 /* subject:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA */
3089 /* SKID: C0:7A:98:68:8D:89:FB:AB:05:64:0C:11:7D:AA:7D:65:B8:CA:CC:4E */
3090 /* Not Before: May 21 04:00:00 2002 GMT, Not After : May 21 04:00:00 2022 GMT */
3091 /* Signature Algorithm: sha1WithRSAEncryption */
3092 unsigned char GeoTrust_Global_CA_sha256[kSecPolicySHA256Size] = {
3093 0xff, 0x85, 0x6a, 0x2d, 0x25, 0x1d, 0xcd, 0x88, 0xd3, 0x66, 0x56, 0xf4, 0x50, 0x12, 0x67, 0x98,
3094 0xcf, 0xab, 0xaa, 0xde, 0x40, 0x79, 0x9c, 0x72, 0x2d, 0xe4, 0xd2, 0xb5, 0xdb, 0x36, 0xa7, 0x3a
3095 };
3096
3097 static SecPolicyRef SecPolicyCreateAppleGeoTrustServerAuthCommon(CFStringRef hostname, CFStringRef policyOid,
3098 CFStringRef policyName,
3099 CFStringRef leafMarkerOid,
3100 CFStringRef qaLeafMarkerOid) {
3101 CFMutableDictionaryRef options = NULL;
3102 CFDataRef spkiDigest = NULL;
3103 SecPolicyRef result = NULL;
3104
3105 require(options = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks,
3106 &kCFTypeDictionaryValueCallBacks), errOut);
3107
3108 /* basic SSL */
3109 SecPolicyAddBasicX509Options(options);
3110
3111 require(hostname, errOut);
3112 CFDictionaryAddValue(options, kSecPolicyCheckSSLHostname, hostname);
3113
3114 add_eku(options, &oidExtendedKeyUsageServerAuth);
3115
3116 /* pinning */
3117 if (requireUATPinning(policyName)) {
3118 /* GeoTrust root */
3119 SecPolicyAddAnchorSHA256Options(options, GeoTrust_Global_CA_sha256);
3120
3121 /* Issued to Apple Inc. in the US */
3122 add_element(options, kSecPolicyCheckIntermediateCountry, CFSTR("US"));
3123 add_element(options, kSecPolicyCheckIntermediateOrganization, CFSTR("Apple Inc."));
3124
3125 require_action(SecPolicyAddChainLengthOptions(options, 3), errOut, CFReleaseNull(result));
3126
3127 /* Marker OIDs in both formats */
3128 if (qaLeafMarkerOid) {
3129 add_leaf_prod_qa_markers_string(options, leafMarkerOid, qaLeafMarkerOid);
3130 add_leaf_prod_qa_markers_value_string(options,
3131 CFSTR("1.2.840.113635.100.6.48.1"), leafMarkerOid,
3132 CFSTR("1.2.840.113635.100.6.48.1"), qaLeafMarkerOid);
3133 } else {
3134 add_leaf_marker_string(options, leafMarkerOid);
3135 add_leaf_marker_value_string(options, CFSTR("1.2.840.113635.100.6.48.1"), leafMarkerOid);
3136 }
3137 }
3138
3139 /* Check for weak hashes */
3140 CFDictionaryAddValue(options, kSecPolicyCheckSystemTrustedWeakHash, kCFBooleanTrue);
3141 CFDictionaryAddValue(options, kSecPolicyCheckSystemTrustedWeakKey, kCFBooleanTrue);
3142
3143 /* See <rdar://25344801> for more details */
3144
3145 result = SecPolicyCreate(policyOid, policyName, options);
3146
3147 errOut:
3148 CFReleaseSafe(options);
3149 CFReleaseSafe(spkiDigest);
3150 return result;
3151 }
3152
3153 SecPolicyRef SecPolicyCreateAppleCompatibilityEscrowProxyService(CFStringRef hostname) {
3154 return SecPolicyCreateAppleGeoTrustServerAuthCommon(hostname, kSecPolicyAppleEscrowProxyCompatibilityServerAuth,
3155 kSecPolicyNameAppleEscrowProxyService,
3156 CFSTR("1.2.840.113635.100.6.27.7.2"),
3157 CFSTR("1.2.840.113635.100.6.27.7.1"));
3158 }
3159
3160 /*!
3161 @function SecPolicyCreateAppleFMiPService
3162 @abstract Ensure we're appropriately pinned to the Find My iPhone service (SSL + Apple restrictions)
3163 */
3164 SecPolicyRef SecPolicyCreateAppleFMiPService(CFStringRef hostname, CFDictionaryRef context)
3165 {
3166 return SecPolicyCreateAppleServerAuthCommon(hostname, context, kSecPolicyAppleFMiPServerAuth,
3167 kSecPolicyNameAppleFMiPService,
3168 &oidAppleCertExtFMiPServerAuthProd,
3169 &oidAppleCertExtFMiPServerAuthProdQA);
3170 }
3171
3172
3173 /* should use verbatim copy, but since this is the deprecated way, don't care right now */
3174 static const UInt8 entrustSPKIL1C[kSecPolicySHA256Size] = {
3175 0x54, 0x5b, 0xf9, 0x35, 0xe9, 0xad, 0xa1, 0xda,
3176 0x11, 0x7e, 0xdc, 0x3c, 0x2a, 0xcb, 0xc5, 0x6f,
3177 0xc0, 0x28, 0x09, 0x6c, 0x0e, 0x24, 0xbe, 0x9b,
3178 0x38, 0x94, 0xbe, 0x52, 0x2d, 0x1b, 0x43, 0xde
3179 };
3180
3181 /*!
3182 @function SecPolicyCreateApplePushServiceLegacy
3183 @abstract Ensure we're appropriately pinned to the Push service (via Entrust)
3184 */
3185 SecPolicyRef SecPolicyCreateApplePushServiceLegacy(CFStringRef hostname)
3186 {
3187 CFMutableDictionaryRef options = NULL;
3188 SecPolicyRef result = NULL;
3189 CFDataRef digest = NULL;
3190
3191 digest = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, entrustSPKIL1C, sizeof(entrustSPKIL1C), kCFAllocatorNull);
3192 require(digest, errOut);
3193
3194 options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
3195 require(options, errOut);
3196
3197 SecPolicyAddBasicX509Options(options);
3198
3199 CFDictionaryAddValue(options, kSecPolicyCheckSSLHostname, hostname);
3200
3201 CFDictionaryAddValue(options, kSecPolicyCheckBlackListedLeaf, kCFBooleanTrue);
3202 CFDictionaryAddValue(options, kSecPolicyCheckGrayListedLeaf, kCFBooleanTrue);
3203
3204 CFDictionaryAddValue(options, kSecPolicyCheckIntermediateSPKISHA256, digest);
3205
3206 add_eku(options, &oidExtendedKeyUsageServerAuth);
3207
3208 /* Check for weak hashes and keys */
3209 CFDictionaryAddValue(options, kSecPolicyCheckSystemTrustedWeakHash, kCFBooleanTrue);
3210 CFDictionaryAddValue(options, kSecPolicyCheckSystemTrustedWeakKey, kCFBooleanTrue);
3211
3212 CFDictionaryAddValue(options, kSecPolicyCheckRevocation, kSecPolicyCheckRevocationAny);
3213
3214 result = SecPolicyCreate(kSecPolicyAppleLegacyPushService,
3215 kSecPolicyNameLegacyPushService, options);
3216 require(result, errOut);
3217
3218 errOut:
3219 CFReleaseSafe(digest);
3220 CFReleaseSafe(options);
3221 return result;
3222 }
3223
3224 /*!
3225 @function SecPolicyCreateAppleMMCSService
3226 @abstract Ensure we're appropriately pinned to the IDS service (SSL + Apple restrictions)
3227 */
3228 SecPolicyRef SecPolicyCreateAppleMMCSService(CFStringRef hostname, CFDictionaryRef context)
3229 {
3230 return SecPolicyCreateAppleServerAuthCommon(hostname, context, kSecPolicyAppleMMCService,
3231 kSecPolicyNameAppleMMCSService,
3232 &oidAppleCertExtAppleServerAuthenticationMMCSProd,
3233 &oidAppleCertExtAppleServerAuthenticationMMCSProdQA);
3234 }
3235
3236 SecPolicyRef SecPolicyCreateAppleCompatibilityMMCSService(CFStringRef hostname) {
3237 return SecPolicyCreateAppleGeoTrustServerAuthCommon(hostname, kSecPolicyAppleMMCSCompatibilityServerAuth,
3238 kSecPolicyNameAppleMMCSService,
3239 CFSTR("1.2.840.113635.100.6.27.11.2"),
3240 CFSTR("1.2.840.113635.100.6.27.11.1"));
3241 }
3242
3243
3244 SecPolicyRef SecPolicyCreateAppleiCloudSetupService(CFStringRef hostname, CFDictionaryRef context)
3245 {
3246 return SecPolicyCreateAppleServerAuthCommon(hostname, context, kSecPolicyAppleiCloudSetupServerAuth,
3247 kSecPolicyNameAppleiCloudSetupService,
3248 &oidAppleCertExtAppleServerAuthenticationiCloudSetupProd,
3249 &oidAppleCertExtAppleServerAuthenticationiCloudSetupProdQA);
3250 }
3251
3252 SecPolicyRef SecPolicyCreateAppleCompatibilityiCloudSetupService(CFStringRef hostname)
3253 {
3254 return SecPolicyCreateAppleGeoTrustServerAuthCommon(hostname, kSecPolicyAppleiCloudSetupCompatibilityServerAuth,
3255 kSecPolicyNameAppleiCloudSetupService,
3256 CFSTR("1.2.840.113635.100.6.27.15.2"),
3257 CFSTR("1.2.840.113635.100.6.27.15.1"));
3258 }
3259
3260 /*!
3261 @function SecPolicyCreateAppleSSLService
3262 @abstract Ensure we're appropriately pinned to an Apple server (SSL + Apple restrictions)
3263 */
3264 SecPolicyRef SecPolicyCreateAppleSSLService(CFStringRef hostname)
3265 {
3266 // SSL server, pinned to an Apple intermediate
3267 SecPolicyRef policy = SecPolicyCreateSSL(true, hostname);
3268 CFMutableDictionaryRef options = NULL;
3269 require(policy, errOut);
3270
3271 // change options for SSL policy evaluation
3272 require((options=(CFMutableDictionaryRef)policy->_options) != NULL, errOut);
3273
3274 // Apple CA anchored
3275 require(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameServerAuthentication), errOut);
3276
3277 // Check leaf for Apple Server Authentication marker oid (1.2.840.113635.100.6.27.1)
3278 add_leaf_marker(options, &oidAppleCertExtAppleServerAuthentication);
3279
3280 // Check intermediate for Apple Server Authentication intermediate marker (1.2.840.113635.100.6.2.12)
3281 add_oid(options, kSecPolicyCheckIntermediateMarkerOid, &oidAppleIntmMarkerAppleServerAuthentication);
3282
3283 /* Check for weak hashes */
3284 CFDictionaryAddValue(options, kSecPolicyCheckSystemTrustedWeakHash, kCFBooleanTrue);
3285 require(SecPolicyAddStrongKeySizeOptions(options), errOut);
3286
3287 CFDictionaryAddValue(options, kSecPolicyCheckRevocation, kSecPolicyCheckRevocationAny);
3288
3289 SecPolicySetOid(policy, kSecPolicyAppleServerAuthentication);
3290 SecPolicySetName(policy, kSecPolicyNameServerAuthentication);
3291
3292 return policy;
3293
3294 errOut:
3295 CFReleaseSafe(options);
3296 CFReleaseSafe(policy);
3297 return NULL;
3298 }
3299
3300 /*!
3301 @function SecPolicyCreateApplePPQSigning
3302 @abstract Check for intermediate certificate 'Apple System Integration 2 Certification Authority' by name,
3303 and apple anchor.
3304 Leaf cert must have Digital Signature usage.
3305 Leaf cert must have Apple PPQ Signing marker OID (1.2.840.113635.100.6.38.2).
3306 Intermediate must have marker OID (1.2.840.113635.100.6.2.10).
3307 */
3308 SecPolicyRef SecPolicyCreateApplePPQSigning(void)
3309 {
3310 SecPolicyRef result = NULL;
3311 CFMutableDictionaryRef options = NULL;
3312 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
3313 &kCFTypeDictionaryKeyCallBacks,
3314 &kCFTypeDictionaryValueCallBacks), errOut);
3315 SecPolicyAddBasicCertOptions(options);
3316
3317 SecPolicyAddAppleAnchorOptions(options, kSecPolicyNamePPQSigning);
3318 require(SecPolicyAddChainLengthOptions(options, 3), errOut);
3319
3320 CFDictionaryAddValue(options, kSecPolicyCheckIssuerCommonName,
3321 CFSTR("Apple System Integration 2 Certification Authority"));
3322
3323 // Check that leaf has extension with "Apple PPQ Signing" prod oid (1.2.840.113635.100.6.38.2)
3324 add_leaf_marker(options, &oidAppleCertExtApplePPQSigningProd);
3325
3326 // Check that intermediate has extension (1.2.840.113635.100.6.2.10)
3327 add_oid(options, kSecPolicyCheckIntermediateMarkerOid, &oidAppleIntmMarkerAppleSystemIntg2);
3328
3329 add_ku(options, kSecKeyUsageDigitalSignature);
3330
3331 require(result = SecPolicyCreate(kSecPolicyApplePPQSigning,
3332 kSecPolicyNamePPQSigning, options), errOut);
3333
3334 errOut:
3335 CFReleaseSafe(options);
3336 return result;
3337 }
3338
3339 /*!
3340 @function SecPolicyCreateTestApplePPQSigning
3341 @abstract Check for intermediate certificate 'Apple System Integration 2 Certification Authority' by name,
3342 and apple anchor.
3343 Leaf cert must have Digital Signature usage.
3344 Leaf cert must have Apple PPQ Signing Test marker OID (1.2.840.113635.100.6.38.1).
3345 Intermediate must have marker OID (1.2.840.113635.100.6.2.10).
3346 */
3347 SecPolicyRef SecPolicyCreateTestApplePPQSigning(void)
3348 {
3349 /* Guard against use of test policy on production devices */
3350 if (!SecIsInternalRelease()) {
3351 return SecPolicyCreateApplePPQSigning();
3352 }
3353
3354 SecPolicyRef result = NULL;
3355 CFMutableDictionaryRef options = NULL;
3356 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
3357 &kCFTypeDictionaryKeyCallBacks,
3358 &kCFTypeDictionaryValueCallBacks), errOut);
3359 SecPolicyAddBasicCertOptions(options);
3360
3361 SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameTestPPQSigning);
3362 require(SecPolicyAddChainLengthOptions(options, 3), errOut);
3363
3364 CFDictionaryAddValue(options, kSecPolicyCheckIssuerCommonName,
3365 CFSTR("Apple System Integration 2 Certification Authority"));
3366
3367 // Check that leaf has extension with "Apple PPQ Signing" test oid (1.2.840.113635.100.6.38.1)
3368 add_leaf_marker(options, &oidAppleCertExtApplePPQSigningProdQA);
3369
3370 // Check that intermediate has extension (1.2.840.113635.100.6.2.10)
3371 add_oid(options, kSecPolicyCheckIntermediateMarkerOid, &oidAppleIntmMarkerAppleSystemIntg2);
3372
3373 add_ku(options, kSecKeyUsageDigitalSignature);
3374
3375 require(result = SecPolicyCreate(kSecPolicyAppleTestPPQSigning,
3376 kSecPolicyNameTestPPQSigning, options), errOut);
3377
3378 errOut:
3379 CFReleaseSafe(options);
3380 return result;
3381 }
3382 /*!
3383 @function SecPolicyCreateAppleTimeStamping
3384 @abstract Check for RFC3161 timestamping EKU.
3385 */
3386 SecPolicyRef SecPolicyCreateAppleTimeStamping(void)
3387 {
3388 SecPolicyRef result = NULL;
3389 CFMutableDictionaryRef options = NULL;
3390 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
3391 &kCFTypeDictionaryKeyCallBacks,
3392 &kCFTypeDictionaryValueCallBacks), errOut);
3393
3394 SecPolicyAddBasicX509Options(options);
3395
3396 /* Require id-kp-timeStamping extendedKeyUsage to be present. */
3397 add_eku(options, &oidExtendedKeyUsageTimeStamping);
3398
3399 require(result = SecPolicyCreate(kSecPolicyAppleTimeStamping,
3400 kSecPolicyNameTimeStamping, options), errOut);
3401
3402 errOut:
3403 CFReleaseSafe(options);
3404 return result;
3405 }
3406
3407 /*!
3408 @function SecPolicyCreateApplePayIssuerEncryption
3409 @abstract Check for intermediate certificate 'Apple Worldwide Developer Relations CA - G2' by name,
3410 and ECC apple anchor.
3411 Leaf cert must have Key Encipherment and Key Agreement usage.
3412 Leaf cert must have Apple Pay Issuer Encryption marker OID (1.2.840.113635.100.6.39).
3413 */
3414 SecPolicyRef SecPolicyCreateApplePayIssuerEncryption(void)
3415 {
3416 SecPolicyRef result = NULL;
3417 CFMutableDictionaryRef options = NULL;
3418 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
3419 &kCFTypeDictionaryKeyCallBacks,
3420 &kCFTypeDictionaryValueCallBacks), errOut);
3421 SecPolicyAddBasicCertOptions(options);
3422
3423 require(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNamePayIssuerEncryption),
3424 errOut);
3425 require(SecPolicyAddChainLengthOptions(options, 3), errOut);
3426
3427 CFDictionaryAddValue(options, kSecPolicyCheckIssuerCommonName,
3428 CFSTR("Apple Worldwide Developer Relations CA - G2"));
3429
3430 // Check that leaf has extension with "Apple Pay Issuer Encryption" oid (1.2.840.113635.100.6.39)
3431 add_leaf_marker(options, &oidAppleCertExtCryptoServicesExtEncryption);
3432
3433 add_ku(options, kSecKeyUsageKeyEncipherment);
3434
3435 require(result = SecPolicyCreate(kSecPolicyApplePayIssuerEncryption,
3436 kSecPolicyNamePayIssuerEncryption, options), errOut);
3437
3438 errOut:
3439 CFReleaseSafe(options);
3440 return result;
3441 }
3442
3443 /*!
3444 @function SecPolicyCreateAppleATVVPNProfileSigning
3445 @abstract Check for leaf marker OID 1.2.840.113635.100.6.43,
3446 intermediate marker OID 1.2.840.113635.100.6.2.10,
3447 chains to Apple Root CA, path length 3
3448 */
3449 SecPolicyRef SecPolicyCreateAppleATVVPNProfileSigning(void)
3450 {
3451 SecPolicyRef result = NULL;
3452 CFMutableDictionaryRef options = NULL;
3453 CFMutableDictionaryRef appleAnchorOptions = NULL;
3454 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
3455 &kCFTypeDictionaryKeyCallBacks,
3456 &kCFTypeDictionaryValueCallBacks), errOut);
3457
3458 SecPolicyAddBasicCertOptions(options);
3459
3460 // Require pinning to the Apple CAs (including test CA for internal releases)
3461 appleAnchorOptions = CFDictionaryCreateMutableForCFTypes(NULL);
3462 require(appleAnchorOptions, errOut);
3463
3464 if (SecIsInternalRelease()) {
3465 CFDictionarySetValue(appleAnchorOptions,
3466 kSecPolicyAppleAnchorIncludeTestRoots, kCFBooleanTrue);
3467 }
3468
3469 add_element(options, kSecPolicyCheckAnchorApple, appleAnchorOptions);
3470
3471 // Cert chain length 3
3472 require(SecPolicyAddChainLengthOptions(options, 3), errOut);
3473
3474 // Check leaf for Apple ATV VPN Profile Signing OID (1.2.840.113635.100.6.43)
3475 add_leaf_marker(options, &oidAppleCertExtATVVPNProfileSigning);
3476
3477 // Check intermediate for Apple System Integration 2 CA intermediate marker (1.2.840.113635.100.6.2.10)
3478 add_oid(options, kSecPolicyCheckIntermediateMarkerOid, &oidAppleIntmMarkerAppleSystemIntg2);
3479
3480 // Ensure that revocation is checked (OCSP only)
3481 CFDictionaryAddValue(options, kSecPolicyCheckRevocation, kSecPolicyCheckRevocationOCSP);
3482
3483 require(result = SecPolicyCreate(kSecPolicyAppleATVVPNProfileSigning,
3484 kSecPolicyNameATVVPNProfileSigning, options), errOut);
3485
3486 errOut:
3487 CFReleaseSafe(options);
3488 CFReleaseSafe(appleAnchorOptions);
3489 return result;
3490 }
3491
3492 SecPolicyRef SecPolicyCreateAppleHomeKitServerAuth(CFStringRef hostname) {
3493 CFMutableDictionaryRef appleAnchorOptions = NULL;
3494 CFMutableDictionaryRef options = NULL;
3495 SecPolicyRef result = NULL;
3496 CFDataRef oid = NULL;
3497
3498 options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
3499 require(options, errOut);
3500
3501 SecPolicyAddBasicX509Options(options);
3502
3503 CFDictionaryAddValue(options, kSecPolicyCheckSSLHostname, hostname);
3504
3505 add_eku(options, &oidExtendedKeyUsageServerAuth);
3506
3507 if (requireUATPinning(kSecPolicyNameAppleHomeKitService)) {
3508
3509 // Cert chain length 3
3510 require(SecPolicyAddChainLengthOptions(options, 3), errOut);
3511
3512 // Apple anchors, allowing test anchors for internal release
3513 SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameAppleHomeKitService);
3514
3515 add_leaf_marker(options, &oidAppleCertExtHomeKitServerAuth);
3516
3517 add_oid(options, kSecPolicyCheckIntermediateMarkerOid, &oidAppleIntmMarkerAppleHomeKitServerCA);
3518 }
3519
3520 /* Check for weak hashes */
3521 CFDictionaryAddValue(options, kSecPolicyCheckSystemTrustedWeakHash, kCFBooleanTrue);
3522 require(SecPolicyAddStrongKeySizeOptions(options), errOut);
3523
3524 CFDictionaryAddValue(options, kSecPolicyCheckRevocation, kSecPolicyCheckRevocationAny);
3525
3526 result = SecPolicyCreate(kSecPolicyAppleHomeKitServerAuth,
3527 kSecPolicyNameAppleHomeKitService, options);
3528 require(result, errOut);
3529
3530 errOut:
3531 CFReleaseSafe(appleAnchorOptions);
3532 CFReleaseSafe(options);
3533 CFReleaseSafe(oid);
3534 return result;
3535 }
3536
3537 SecPolicyRef SecPolicyCreateAppleExternalDeveloper(void) {
3538 CFMutableDictionaryRef options = NULL;
3539 SecPolicyRef result = NULL;
3540
3541 /* Create basic Apple pinned policy */
3542 require(result = SecPolicyCreateApplePinned(kSecPolicyNameExternalDeveloper,
3543 CFSTR("1.2.840.113635.100.6.2.1"), // WWDR Intermediate OID
3544 CFSTR("1.2.840.113635.100.6.1.2")), // "iPhone Developer" leaf OID
3545 errOut);
3546
3547 require_action(options = CFDictionaryCreateMutableCopy(NULL, 0, result->_options), errOut, CFReleaseNull(result));
3548
3549 /* Additional intermediate OIDs */
3550 add_element(options, kSecPolicyCheckIntermediateMarkerOid,
3551 CFSTR("1.2.840.113635.100.6.2.6")); // "Developer ID" Intermediate OID
3552
3553 /* Addtional leaf OIDS */
3554 add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.6.1.4")); // "iPhone Distribution" leaf OID
3555 add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.6.1.5")); // "Safari Developer" leaf OID
3556 add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.6.1.7")); // "3rd Party Mac Developer Application" leaf OID
3557 add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.6.1.8")); // "3rd Party Mac Developer Installer" leaf OID
3558 add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.6.1.12")); // "Mac Developer" leaf OID
3559 add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.6.1.13")); // "Developer ID Application" leaf OID
3560 add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.6.1.14")); // "Developer ID Installer" leaf OID
3561
3562 /* Restrict EKUs */
3563 add_eku_string(options, CFSTR("1.3.6.1.5.5.7.3.3")); // CodeSigning EKU
3564 add_eku_string(options, CFSTR("1.2.840.113635.100.4.8")); // "Safari Developer" EKU
3565 add_eku_string(options, CFSTR("1.2.840.113635.100.4.9")); // "3rd Party Mac Developer Installer" EKU
3566 add_eku_string(options, CFSTR("1.2.840.113635.100.4.13")); // "Developer ID Installer" EKU
3567
3568 CFReleaseSafe(result->_options);
3569 result->_options = CFRetainSafe(options);
3570
3571 SecPolicySetOid(result, kSecPolicyAppleExternalDeveloper);
3572
3573 errOut:
3574 CFReleaseSafe(options);
3575 return result;
3576 }
3577
3578 /* This one is special because the intermediate has no marker OID */
3579 SecPolicyRef SecPolicyCreateAppleSoftwareSigning(void) {
3580 CFMutableDictionaryRef options = NULL;
3581 CFDictionaryRef keySizes = NULL;
3582 CFNumberRef rsaSize = NULL, ecSize = NULL;
3583 SecPolicyRef result = NULL;
3584
3585 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
3586 &kCFTypeDictionaryKeyCallBacks,
3587 &kCFTypeDictionaryValueCallBacks), errOut);
3588
3589 SecPolicyAddBasicCertOptions(options);
3590
3591 /* Anchored to the Apple Roots */
3592 require_quiet(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameSoftwareSigning),
3593 errOut);
3594
3595 /* Exactly 3 certs in the chain */
3596 require(SecPolicyAddChainLengthOptions(options, 3), errOut);
3597
3598 /* Intermediate Common Name matches */
3599 add_element(options, kSecPolicyCheckIssuerCommonName, CFSTR("Apple Code Signing Certification Authority"));
3600
3601 /* Leaf marker OID matches */
3602 add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.6.22"));
3603
3604 /* Leaf has CodeSigning EKU */
3605 add_eku_string(options, CFSTR("1.3.6.1.5.5.7.3.3"));
3606
3607 /* Check revocation using any available method */
3608 add_element(options, kSecPolicyCheckRevocation, kSecPolicyCheckRevocationAny);
3609
3610 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
3611 require(SecPolicyAddStrongKeySizeOptions(options), errOut);
3612
3613 require(result = SecPolicyCreate(kSecPolicyAppleSoftwareSigning,
3614 kSecPolicyNameSoftwareSigning, options), errOut);
3615
3616 errOut:
3617 CFReleaseSafe(options);
3618 CFReleaseSafe(keySizes);
3619 CFReleaseSafe(rsaSize);
3620 CFReleaseSafe(ecSize);
3621 return result;
3622 }
3623
3624 /* subject:/CN=SEP Root CA/O=Apple Inc./ST=California */
3625 /* SKID: 58:EF:D6:BE:C5:82:B0:54:CD:18:A6:84:AD:A2:F6:7B:7B:3A:7F:CF */
3626 /* Not Before: Jun 24 21:43:24 2014 GMT, Not After : Jun 24 21:43:24 2029 GMT */
3627 /* Signature Algorithm: ecdsa-with-SHA384 */
3628 const uint8_t SEPRootCA_SHA256[kSecPolicySHA256Size] = {
3629 0xd1, 0xdf, 0x82, 0x00, 0xf3, 0x89, 0x4e, 0xe9, 0x96, 0xf3, 0x77, 0xdf, 0x76, 0x3b, 0x0a, 0x16,
3630 0x8f, 0xd9, 0x6c, 0x58, 0xc0, 0x3e, 0xc9, 0xb0, 0x5f, 0xa5, 0x64, 0x79, 0xc0, 0xe8, 0xc9, 0xe7
3631 };
3632
3633 SecPolicyRef SecPolicyCreateAppleUniqueDeviceCertificate(CFDataRef testRootHash) {
3634 CFMutableDictionaryRef options = NULL;
3635 CFDictionaryRef keySizes = NULL;
3636 CFNumberRef ecSize = NULL;
3637 SecPolicyRef result = NULL;
3638
3639 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
3640 &kCFTypeDictionaryKeyCallBacks,
3641 &kCFTypeDictionaryValueCallBacks), errOut);
3642
3643 /* Device certificate should never expire */
3644 SecPolicyAddBasicCertOptions(options);
3645
3646 /* Anchored to the SEP Root CA. Allow alternative root for developers */
3647 require(SecPolicyAddAnchorSHA256Options(options, SEPRootCA_SHA256),errOut);
3648 if (testRootHash && SecIsInternalRelease() && (kSecPolicySHA256Size == CFDataGetLength(testRootHash))) {
3649 add_element(options, kSecPolicyCheckAnchorSHA256, testRootHash);
3650 }
3651
3652 /* Exactly 3 certs in the chain */
3653 require(SecPolicyAddChainLengthOptions(options, 3), errOut);
3654
3655 /* Intermediate has marker OID with value */
3656 add_intermediate_marker_value_string(options, CFSTR("1.2.840.113635.100.6.44"), CFSTR("ucrt"));
3657
3658 /* Leaf has marker OID with varying value that can't be pre-determined */
3659 add_element(options, kSecPolicyCheckLeafMarkerOidWithoutValueCheck, CFSTR("1.2.840.113635.100.10.1"));
3660
3661 /* RSA key sizes are disallowed. EC key sizes are P-256 or larger. */
3662 require(ecSize = CFNumberCreateWithCFIndex(NULL, 256), errOut);
3663 require(keySizes = CFDictionaryCreate(NULL, (const void**)&kSecAttrKeyTypeEC,
3664 (const void**)&ecSize, 1,
3665 &kCFTypeDictionaryKeyCallBacks,
3666 &kCFTypeDictionaryValueCallBacks), errOut);
3667 add_element(options, kSecPolicyCheckKeySize, keySizes);
3668
3669
3670 require(result = SecPolicyCreate(kSecPolicyAppleUniqueDeviceIdentifierCertificate,
3671 kSecPolicyNameUniqueDeviceIdentifierCertificate, options), errOut);
3672
3673 errOut:
3674 CFReleaseSafe(options);
3675 CFReleaseSafe(keySizes);
3676 CFReleaseSafe(ecSize);
3677 return result;
3678 }
3679
3680 SecPolicyRef SecPolicyCreateAppleWarsaw(void) {
3681 CFMutableDictionaryRef options = NULL;
3682 SecPolicyRef result = NULL;
3683 #if TARGET_OS_BRIDGE
3684 CFMutableDictionaryRef appleAnchorOptions = NULL;
3685 #endif
3686
3687 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
3688 &kCFTypeDictionaryKeyCallBacks,
3689 &kCFTypeDictionaryValueCallBacks), errOut);
3690
3691 SecPolicyAddBasicX509Options(options);
3692
3693 /* Anchored to the Apple Roots. */
3694 require_quiet(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameWarsaw),
3695 errOut);
3696
3697 /* Exactly 3 certs in the chain */
3698 require(SecPolicyAddChainLengthOptions(options, 3), errOut);
3699
3700 /* Intermediate marker OID matches input OID */
3701 add_element(options, kSecPolicyCheckIntermediateMarkerOid, CFSTR("1.2.840.113635.100.6.2.14"));
3702
3703 /* Leaf marker OID matches input OID */
3704 add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.6.29"));
3705
3706 /* Check revocation using any available method */
3707 add_element(options, kSecPolicyCheckRevocation, kSecPolicyCheckRevocationAny);
3708
3709 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
3710 require(SecPolicyAddStrongKeySizeOptions(options), errOut);
3711
3712 require(result = SecPolicyCreate(kSecPolicyAppleWarsaw,
3713 kSecPolicyNameWarsaw, options), errOut);
3714
3715 errOut:
3716 CFReleaseSafe(options);
3717 return result;
3718 }
3719
3720 SecPolicyRef SecPolicyCreateAppleSecureIOStaticAsset(void) {
3721 CFMutableDictionaryRef options = NULL;
3722 SecPolicyRef result = NULL;
3723 #if TARGET_OS_BRIDGE
3724 CFMutableDictionaryRef appleAnchorOptions = NULL;
3725 #endif
3726
3727 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
3728 &kCFTypeDictionaryKeyCallBacks,
3729 &kCFTypeDictionaryValueCallBacks), errOut);
3730
3731 /* This certificate cannot expire so that assets always load */
3732 SecPolicyAddBasicCertOptions(options);
3733
3734 /* Anchored to the Apple Roots. */
3735 #if TARGET_OS_BRIDGE
3736 /* On the bridge, test roots are gated in the trust and policy servers. */
3737 require_quiet(appleAnchorOptions = CFDictionaryCreateMutableForCFTypes(NULL), errOut);
3738 CFDictionarySetValue(appleAnchorOptions,
3739 kSecPolicyAppleAnchorIncludeTestRoots, kCFBooleanTrue);
3740 add_element(options, kSecPolicyCheckAnchorApple, appleAnchorOptions);
3741 CFReleaseSafe(appleAnchorOptions);
3742 #else
3743 require_quiet(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameSecureIOStaticAsset),
3744 errOut);
3745 #endif
3746
3747 /* Exactly 3 certs in the chain */
3748 require(SecPolicyAddChainLengthOptions(options, 3), errOut);
3749
3750 /* Intermediate marker OID matches ASI CA */
3751 add_element(options, kSecPolicyCheckIntermediateMarkerOid, CFSTR("1.2.840.113635.100.6.2.10"));
3752
3753 /* Leaf marker OID matches static IO OID */
3754 add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.6.50"));
3755
3756 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
3757 require(SecPolicyAddStrongKeySizeOptions(options), errOut);
3758
3759 require(result = SecPolicyCreate(kSecPolicyAppleSecureIOStaticAsset,
3760 kSecPolicyNameSecureIOStaticAsset, options), errOut);
3761
3762 errOut:
3763 CFReleaseSafe(options);
3764 return result;
3765 }
3766
3767 SecPolicyRef SecPolicyCreateAppleAppTransportSecurity(void) {
3768 CFMutableDictionaryRef options = NULL;
3769 SecPolicyRef result = NULL;
3770 CFMutableSetRef disallowedHashes = NULL;
3771
3772 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
3773 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut);
3774
3775 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
3776 require(SecPolicyAddStrongKeySizeOptions(options), errOut);
3777
3778 /* Hash algorithm is SHA-256 or better */
3779 require(disallowedHashes = CFSetCreateMutable(NULL, 5, &kCFTypeSetCallBacks), errOut);
3780 CFSetAddValue(disallowedHashes, kSecSignatureDigestAlgorithmMD2);
3781 CFSetAddValue(disallowedHashes, kSecSignatureDigestAlgorithmMD4);
3782 CFSetAddValue(disallowedHashes, kSecSignatureDigestAlgorithmMD5);
3783 CFSetAddValue(disallowedHashes, kSecSignatureDigestAlgorithmSHA1);
3784 CFSetAddValue(disallowedHashes, kSecSignatureDigestAlgorithmSHA224);
3785
3786 add_element(options, kSecPolicyCheckSignatureHashAlgorithms, disallowedHashes);
3787
3788 require_quiet(result = SecPolicyCreate(kSecPolicyAppleAppTransportSecurity,
3789 kSecPolicyNameAppTransportSecurity,
3790 options), errOut);
3791
3792 errOut:
3793 CFReleaseSafe(options);
3794 return result;
3795 }
3796
3797 SecPolicyRef SecPolicyCreateMobileSoftwareUpdate(void) {
3798 CFMutableDictionaryRef options = NULL;
3799 SecPolicyRef result = NULL;
3800 #if TARGET_OS_BRIDGE
3801 CFMutableDictionaryRef appleAnchorOptions = NULL;
3802 #endif
3803
3804 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
3805 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut);
3806
3807 /* No expiration check. */
3808 SecPolicyAddBasicCertOptions(options);
3809
3810 /* Apple Anchor */
3811 require_quiet(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameMobileSoftwareUpdate),
3812 errOut);
3813
3814 /* Exactly 3 certs in the chain */
3815 require(SecPolicyAddChainLengthOptions(options, 3), errOut);
3816
3817 /* Intermediate marker OID is iPhone CA OID */
3818 add_element(options, kSecPolicyCheckIntermediateMarkerOid, CFSTR("1.2.840.113635.100.6.2.18"));
3819
3820 /* Leaf marker OID is either the prod MSU OID, or, on internal builds, the prodQA OID */
3821 add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.6.57.2"));
3822 if (SecIsInternalRelease()) {
3823 add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.6.57.1"));
3824 }
3825
3826 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
3827 require(SecPolicyAddStrongKeySizeOptions(options), errOut);
3828
3829 require(result = SecPolicyCreate(kSecPolicyAppleMobileSoftwareUpdate,
3830 kSecPolicyNameMobileSoftwareUpdate, options), errOut);
3831
3832 errOut:
3833 CFReleaseNull(options);
3834 return result;
3835 }
3836
3837 /* subject:/CN=Basic Attestation System Root CA/O=Apple Inc./ST=California */
3838 /* SKID: FE:D1:D1:C2:08:07:03:D5:B9:3C:34:B2:BB:FD:7C:3A:99:25:1B:8F */
3839 /* Not Before: Apr 20 00:22:09 2017 GMT, Not After : Mar 22 00:00:00 2032 GMT */
3840 /* Signature Algorithm: ecdsa-with-SHA384 */
3841 const uint8_t BASystemRootCA_SHA256[kSecPolicySHA256Size] = {
3842 0x10, 0xD3, 0xC8, 0x67, 0xF0, 0xAE, 0xFB, 0x24, 0x31, 0xA0, 0xA9, 0x7A, 0x88, 0x18, 0xBD, 0x64,
3843 0xF7, 0xF9, 0x0F, 0xFE, 0x11, 0x94, 0x48, 0x4F, 0xCA, 0x97, 0xF0, 0xF2, 0x9E, 0xCA, 0x00, 0x47
3844 };
3845
3846 /* subject:/CN=Basic Attestation User Root CA/O=Apple Inc./ST=California */
3847 /* SKID: 83:E5:A3:21:9E:B0:74:C3:F9:61:90:FD:97:4E:23:10:76:A4:A3:F2 */
3848 /* Not Before: Apr 19 21:41:56 2017 GMT, Not After : Mar 22 00:00:00 2032 GMT */
3849 /* Signature Algorithm: ecdsa-with-SHA384 */
3850 const uint8_t BAUserRootCA_SHA256[kSecPolicySHA256Size] = {
3851 0x03, 0x75, 0x1c, 0x80, 0xfc, 0xbe, 0x58, 0x19, 0xd1, 0x70, 0xd2, 0x67, 0xce, 0x1a, 0xd6, 0xd0,
3852 0x94, 0x40, 0x7c, 0x91, 0xd8, 0x73, 0xd7, 0xa6, 0x56, 0x2d, 0xe3, 0x66, 0x6d, 0x35, 0x94, 0xc6
3853 };
3854
3855 SecPolicyRef SecPolicyCreateAppleBasicAttestationSystem(CFDataRef testRootHash) {
3856 CFMutableDictionaryRef options = NULL;
3857 SecPolicyRef result = NULL;
3858
3859 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
3860 &kCFTypeDictionaryKeyCallBacks,
3861 &kCFTypeDictionaryValueCallBacks), errOut);
3862 /* BAA certs expire */
3863 SecPolicyAddBasicX509Options(options);
3864
3865 /* Anchored to one of the Basic Attestation roots. Allow alternative root for developers */
3866 SecPolicyAddAnchorSHA256Options(options, BASystemRootCA_SHA256);
3867 if (testRootHash && SecIsInternalRelease() && (kSecPolicySHA256Size == CFDataGetLength(testRootHash))) {
3868 add_element(options, kSecPolicyCheckAnchorSHA256, testRootHash);
3869 }
3870
3871 /* Exactly 3 certs in the chain */
3872 require(SecPolicyAddChainLengthOptions(options, 3), errOut);
3873
3874 require(result = SecPolicyCreate(kSecPolicyAppleBasicAttestationSystem,
3875 kSecPolicyNameBasicAttestationSystem, options), errOut);
3876
3877 errOut:
3878 CFReleaseSafe(options);
3879 return result;
3880 }
3881
3882 SecPolicyRef SecPolicyCreateAppleBasicAttestationUser(CFDataRef testRootHash) {
3883 CFMutableDictionaryRef options = NULL;
3884 SecPolicyRef result = NULL;
3885
3886 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
3887 &kCFTypeDictionaryKeyCallBacks,
3888 &kCFTypeDictionaryValueCallBacks), errOut);
3889 /* BAA certs expire */
3890 SecPolicyAddBasicX509Options(options);
3891
3892 /* Anchored to one of the Basic Attestation roots. Allow alternative root for developers */
3893 SecPolicyAddAnchorSHA256Options(options, BAUserRootCA_SHA256);
3894 if (testRootHash && SecIsInternalRelease() && (kSecPolicySHA256Size == CFDataGetLength(testRootHash))) {
3895 add_element(options, kSecPolicyCheckAnchorSHA256, testRootHash);
3896 }
3897
3898 /* Exactly 3 certs in the chain */
3899 require(SecPolicyAddChainLengthOptions(options, 3), errOut);
3900
3901 require(result = SecPolicyCreate(kSecPolicyAppleBasicAttestationUser,
3902 kSecPolicyNameBasicAttestationUser, options), errOut);
3903
3904 errOut:
3905 CFReleaseSafe(options);
3906 return result;
3907 }
3908
3909 SecPolicyRef SecPolicyCreateiAPSWAuthWithExpiration(bool checkExpiration) {
3910 CFMutableDictionaryRef options = NULL;
3911 SecPolicyRef result = NULL;
3912
3913 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
3914 &kCFTypeDictionaryKeyCallBacks,
3915 &kCFTypeDictionaryValueCallBacks), errOut);
3916
3917 /* iAP checks expiration on developement certs, but not on production certs */
3918 if (checkExpiration) {
3919 SecPolicyAddBasicX509Options(options);
3920 } else {
3921 SecPolicyAddBasicCertOptions(options);
3922 }
3923
3924 /* Exactly 2 certs in the chain */
3925 require(SecPolicyAddChainLengthOptions(options, 2), errOut);
3926
3927 /* iAP SW Auth General Capabilities Extension present */
3928 add_element(options, kSecPolicyCheckLeafMarkerOidWithoutValueCheck, CFSTR("1.2.840.113635.100.6.59.1"));
3929
3930 require(result = SecPolicyCreate(kSecPolicyAppleiAPSWAuth,
3931 kSecPolicyNameiAPSWAuth, options), errOut);
3932
3933 errOut:
3934 CFReleaseSafe(options);
3935 return result;
3936 }
3937
3938 SecPolicyRef SecPolicyCreateiAPSWAuth(void) {
3939 /* By default, iAP SW Auth certs don't expire */
3940 return SecPolicyCreateiAPSWAuthWithExpiration(false);
3941 }
3942
3943 SecPolicyRef SecPolicyCreateDemoDigitalCatalogSigning(void) {
3944 CFMutableDictionaryRef options = NULL;
3945 SecPolicyRef result = NULL;
3946
3947 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
3948 &kCFTypeDictionaryKeyCallBacks,
3949 &kCFTypeDictionaryValueCallBacks), errOut);
3950 SecPolicyAddBasicX509Options(options);
3951
3952 /* Exactly 3 certs in the chain */
3953 require(SecPolicyAddChainLengthOptions(options, 3), errOut);
3954
3955 /* Demo Signing Extension present in leaf */
3956 add_element(options, kSecPolicyCheckLeafMarkerOid, CFSTR("1.2.840.113635.100.6.60"));
3957
3958 /* Issuer common name is "DemoUnit CA" */
3959 add_element(options, kSecPolicyCheckIssuerCommonName, CFSTR("DemoUnit CA"));
3960
3961 require(result = SecPolicyCreate(kSecPolicyAppleDemoDigitalCatalog,
3962 kSecPolicyNameDemoDigitalCatalog, options), errOut);
3963
3964 errOut:
3965 CFReleaseSafe(options);
3966 return result;
3967 }
3968
3969 SecPolicyRef SecPolicyCreateAppleAssetReceipt(void) {
3970 CFMutableDictionaryRef options = NULL;
3971 SecPolicyRef result = NULL;
3972
3973 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
3974 &kCFTypeDictionaryKeyCallBacks,
3975 &kCFTypeDictionaryValueCallBacks), errOut);
3976
3977 /* No expiration check. */
3978 SecPolicyAddBasicCertOptions(options);
3979
3980 /* Apple Anchor */
3981 require_quiet(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameAssetReceipt), errOut);
3982
3983 /* Exactly 3 certs in the chain */
3984 require(SecPolicyAddChainLengthOptions(options, 3), errOut);
3985
3986 /* Intermediate marker OID is Apple System Integration 2 CA */
3987 add_element(options, kSecPolicyCheckIntermediateMarkerOid, CFSTR("1.2.840.113635.100.6.2.10"));
3988
3989 /* Leaf marker OID is the Asset Receipt OID */
3990 add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.6.61"));
3991
3992 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
3993 require(SecPolicyAddStrongKeySizeOptions(options), errOut);
3994
3995 require(result = SecPolicyCreate(kSecPolicyAppleAssetReceipt,
3996 kSecPolicyNameAssetReceipt, options), errOut);
3997
3998 errOut:
3999 CFReleaseNull(options);
4000 return result;
4001 }
4002
4003 SecPolicyRef SecPolicyCreateAppleDeveloperIDPlusTicket(void) {
4004 CFMutableDictionaryRef options = NULL;
4005 SecPolicyRef result = NULL;
4006
4007 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
4008 &kCFTypeDictionaryKeyCallBacks,
4009 &kCFTypeDictionaryValueCallBacks), errOut);
4010
4011 /* No expiration check. */
4012 SecPolicyAddBasicCertOptions(options);
4013
4014 /* Apple Anchor */
4015 require_quiet(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameDeveloperIDPlusTicket), errOut);
4016
4017 /* Exactly 3 certs in the chain */
4018 require(SecPolicyAddChainLengthOptions(options, 3), errOut);
4019
4020 /* Intermediate marker OID is Apple System Integration CA 4 */
4021 add_element(options, kSecPolicyCheckIntermediateMarkerOid, CFSTR("1.2.840.113635.100.6.2.17"));
4022
4023 /* Leaf marker OID is the Developer ID+ Ticket OID */
4024 add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.6.1.30"));
4025
4026 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
4027 require(SecPolicyAddStrongKeySizeOptions(options), errOut);
4028
4029 require(result = SecPolicyCreate(kSecPolicyAppleDeveloperIDPlusTicket,
4030 kSecPolicyNameDeveloperIDPlusTicket, options), errOut);
4031
4032 errOut:
4033 CFReleaseNull(options);
4034 return result;
4035 }
4036
4037 SecPolicyRef SecPolicyCreateAppleFDRProvisioning(void) {
4038 CFMutableDictionaryRef options = NULL;
4039 SecPolicyRef result = NULL;
4040
4041 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
4042 &kCFTypeDictionaryKeyCallBacks,
4043 &kCFTypeDictionaryValueCallBacks), errOut);
4044
4045 /* No expiration check. */
4046 SecPolicyAddBasicCertOptions(options);
4047
4048 require(result = SecPolicyCreate(kSecPolicyAppleFDRProvisioning,
4049 kSecPolicyNameFDRProvisioning, options), errOut);
4050 errOut:
4051 CFReleaseNull(options);
4052 return result;
4053 }