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