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