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