]> git.saurik.com Git - apple/security.git/blob - OSX/sec/Security/SecPolicy.c
Security-59306.80.4.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 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
2614 &kCFTypeDictionaryKeyCallBacks,
2615 &kCFTypeDictionaryValueCallBacks), errOut);
2616
2617 // X509, ignoring date validity
2618 SecPolicyAddBasicCertOptions(options);
2619
2620 add_ku(options, kSecKeyUsageKeyEncipherment);
2621
2622 /* Leaf has marker OID with value that can't be pre-determined */
2623 add_element(options, kSecPolicyCheckLeafMarkerOidWithoutValueCheck, CFSTR("1.2.840.113635.100.6.23.1"));
2624 require(SecPolicyAddChainLengthOptions(options, 2), errOut);
2625
2626 require(result = SecPolicyCreate(kSecPolicyAppleEscrowService,
2627 kSecPolicyNameEscrowService, options), errOut);
2628
2629 errOut:
2630 CFReleaseSafe(options);
2631 return result;
2632 }
2633
2634 CF_RETURNS_RETAINED SecPolicyRef SecPolicyCreatePCSEscrowServiceSigner(void)
2635 {
2636 SecPolicyRef result = NULL;
2637 CFMutableDictionaryRef options = NULL;
2638 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
2639 &kCFTypeDictionaryKeyCallBacks,
2640 &kCFTypeDictionaryValueCallBacks), errOut);
2641
2642 SecPolicyAddBasicX509Options(options);
2643 add_ku(options, kSecKeyUsageKeyEncipherment);
2644
2645 /* Leaf has marker OID with value that can't be pre-determined */
2646 add_element(options, kSecPolicyCheckLeafMarkerOidWithoutValueCheck, CFSTR("1.2.840.113635.100.6.23.1"));
2647 require(SecPolicyAddChainLengthOptions(options, 2), errOut);
2648
2649 require(result = SecPolicyCreate(kSecPolicyApplePCSEscrowService,
2650 kSecPolicyNamePCSEscrowService, options), errOut);
2651
2652 errOut:
2653 CFReleaseSafe(options);
2654 return result;
2655 }
2656
2657 static SecPolicyRef CreateConfigurationProfileSigner(bool forTest) {
2658 SecPolicyRef result = NULL;
2659 CFMutableDictionaryRef options = NULL;
2660 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
2661 &kCFTypeDictionaryKeyCallBacks,
2662 &kCFTypeDictionaryValueCallBacks), errOut);
2663
2664 SecPolicyAddBasicX509Options(options);
2665 require(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameProfileSigner), errOut);
2666
2667 //Chain length 3
2668 require(SecPolicyAddChainLengthOptions(options, 3), errOut);
2669
2670 // Require the profile signing EKU
2671 const DERItem* pOID = (forTest) ? &oidAppleExtendedKeyUsageQAProfileSigning :&oidAppleExtendedKeyUsageProfileSigning;
2672 add_eku(options, pOID);
2673
2674 // Require the Apple Application Integration CA marker OID
2675 add_element(options, kSecPolicyCheckIntermediateMarkerOid, CFSTR("1.2.840.113635.100.6.2.3"));
2676
2677 require(result = SecPolicyCreate((forTest) ? kSecPolicyAppleQAProfileSigner: kSecPolicyAppleProfileSigner,
2678 (forTest) ? kSecPolicyNameQAProfileSigner : kSecPolicyNameProfileSigner,
2679 options), errOut);
2680
2681 errOut:
2682 CFReleaseSafe(options);
2683 return result;
2684 }
2685
2686 SecPolicyRef SecPolicyCreateConfigurationProfileSigner(void)
2687 {
2688 return CreateConfigurationProfileSigner(false);
2689 }
2690
2691
2692 SecPolicyRef SecPolicyCreateQAConfigurationProfileSigner(void)
2693 {
2694 if (SecIsInternalRelease()) {
2695 return CreateConfigurationProfileSigner(true);
2696 } else {
2697 return CreateConfigurationProfileSigner(false);
2698 }
2699 }
2700
2701 SecPolicyRef SecPolicyCreateOSXProvisioningProfileSigning(void)
2702 {
2703 SecPolicyRef result = NULL;
2704 CFMutableDictionaryRef options = NULL;
2705 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
2706 &kCFTypeDictionaryKeyCallBacks,
2707 &kCFTypeDictionaryValueCallBacks), errOut);
2708 // Require valid chain from the Apple root
2709 SecPolicyAddBasicX509Options(options);
2710 SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameOSXProvisioningProfileSigning);
2711
2712 // Require provisioning profile leaf marker OID (1.2.840.113635.100.4.11)
2713 add_leaf_marker(options, &oidAppleCertExtOSXProvisioningProfileSigning);
2714
2715 // Require intermediate marker OID (1.2.840.113635.100.6.2.1)
2716 add_oid(options, kSecPolicyCheckIntermediateMarkerOid, &oidAppleIntmMarkerAppleWWDR);
2717
2718 // Require key usage that allows signing
2719 add_ku(options, kSecKeyUsageDigitalSignature);
2720
2721 // Ensure that revocation is checked (OCSP)
2722 CFDictionaryAddValue(options, kSecPolicyCheckRevocation, kSecPolicyCheckRevocationOCSP);
2723
2724 require(result = SecPolicyCreate(kSecPolicyAppleOSXProvisioningProfileSigning,
2725 kSecPolicyNameOSXProvisioningProfileSigning, options), errOut);
2726
2727 errOut:
2728 CFReleaseSafe(options);
2729 return result;
2730 }
2731
2732
2733 SecPolicyRef SecPolicyCreateOTAPKISigner(void)
2734 {
2735 SecPolicyRef result = NULL;
2736 CFMutableDictionaryRef options = NULL;
2737 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
2738 &kCFTypeDictionaryKeyCallBacks,
2739 &kCFTypeDictionaryValueCallBacks), errOut);
2740 SecPolicyAddBasicX509Options(options);
2741
2742 SecPolicyAddAnchorSHA1Options(options, kApplePKISettingsAuthority);
2743 require(SecPolicyAddChainLengthOptions(options, 2), errOut);
2744
2745 require(result = SecPolicyCreate(kSecPolicyAppleOTAPKISigner,
2746 kSecPolicyNameOTAPKISigner, options), errOut);
2747
2748 errOut:
2749 CFReleaseSafe(options);
2750 return result;
2751
2752 }
2753
2754
2755 SecPolicyRef SecPolicyCreateTestOTAPKISigner(void)
2756 {
2757 /* Guard against use on production devices */
2758 if (!SecIsInternalRelease()) {
2759 return SecPolicyCreateOTAPKISigner();
2760 }
2761
2762 SecPolicyRef result = NULL;
2763 CFMutableDictionaryRef options = NULL;
2764 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
2765 &kCFTypeDictionaryKeyCallBacks,
2766 &kCFTypeDictionaryValueCallBacks), errOut);
2767 SecPolicyAddBasicX509Options(options);
2768
2769 SecPolicyAddAnchorSHA1Options(options, kAppleTestPKISettingsAuthority);
2770 require(SecPolicyAddChainLengthOptions(options, 2), errOut);
2771
2772 require(result = SecPolicyCreate(kSecPolicyAppleTestOTAPKISigner,
2773 kSecPolicyNameTestOTAPKISigner, options), errOut);
2774
2775 errOut:
2776 CFReleaseSafe(options);
2777 return result;
2778 }
2779
2780 /*!
2781 @function SecPolicyCreateAppleSMPEncryption
2782 @abstract Check for intermediate certificate 'Apple System Integration CA - G3' by name,
2783 and root certificate 'Apple Root CA - G3' by hash.
2784 Leaf cert must have Key Encipherment usage.
2785 Leaf cert must have Apple SMP Encryption marker OID (1.2.840.113635.100.6.30).
2786 Intermediate must have marker OID (1.2.840.113635.100.6.2.13).
2787 */
2788 SecPolicyRef SecPolicyCreateAppleSMPEncryption(void)
2789 {
2790 SecPolicyRef result = NULL;
2791 CFMutableDictionaryRef options = NULL;
2792 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
2793 &kCFTypeDictionaryKeyCallBacks,
2794 &kCFTypeDictionaryValueCallBacks), errOut);
2795 SecPolicyAddBasicCertOptions(options);
2796
2797 require(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameSMPEncryption),
2798 errOut);
2799 require(SecPolicyAddChainLengthOptions(options, 3), errOut);
2800
2801 CFDictionaryAddValue(options, kSecPolicyCheckIssuerCommonName,
2802 CFSTR("Apple System Integration CA - G3"));
2803
2804 // Check that leaf has extension with "Apple SMP Encryption" oid (1.2.840.113635.100.6.30)
2805 add_leaf_marker(options, &oidAppleCertExtAppleSMPEncryption);
2806
2807 // Check that intermediate has extension (1.2.840.113635.100.6.2.13)
2808 add_oid(options, kSecPolicyCheckIntermediateMarkerOid, &oidAppleIntmMarkerAppleSystemIntgG3);
2809
2810 add_ku(options, kSecKeyUsageKeyEncipherment);
2811
2812 // Ensure that revocation is checked (OCSP)
2813 CFDictionaryAddValue(options, kSecPolicyCheckRevocation, kSecPolicyCheckRevocationOCSP);
2814
2815 require(result = SecPolicyCreate(kSecPolicyAppleSMPEncryption,
2816 kSecPolicyNameSMPEncryption, options), errOut);
2817
2818 errOut:
2819 CFReleaseSafe(options);
2820 return result;
2821 }
2822
2823 /*!
2824 @function SecPolicyCreateTestAppleSMPEncryption
2825 @abstract Check for intermediate certificate 'Test Apple System Integration CA - ECC' by name,
2826 and root certificate 'Test Apple Root CA - ECC' by hash.
2827 Leaf cert must have Key Encipherment usage. Other checks TBD.
2828 */
2829 SecPolicyRef SecPolicyCreateTestAppleSMPEncryption(void)
2830 {
2831 SecPolicyRef result = NULL;
2832 CFMutableDictionaryRef options = NULL;
2833 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
2834 &kCFTypeDictionaryKeyCallBacks,
2835 &kCFTypeDictionaryValueCallBacks), errOut);
2836 SecPolicyAddBasicCertOptions(options);
2837
2838 SecPolicyAddAnchorSHA1Options(options, kTestAppleRootCA_ECC_SHA1);
2839 require(SecPolicyAddChainLengthOptions(options, 3), errOut);
2840
2841 CFDictionaryAddValue(options, kSecPolicyCheckIssuerCommonName,
2842 CFSTR("Test Apple System Integration CA - ECC"));
2843
2844 add_ku(options, kSecKeyUsageKeyEncipherment);
2845
2846 // Ensure that revocation is checked (OCSP)
2847 CFDictionaryAddValue(options, kSecPolicyCheckRevocation, kSecPolicyCheckRevocationOCSP);
2848
2849 require(result = SecPolicyCreate(kSecPolicyAppleTestSMPEncryption,
2850 kSecPolicyNameTestSMPEncryption, options), errOut);
2851
2852 errOut:
2853 CFReleaseSafe(options);
2854 return result;
2855 }
2856
2857
2858 SecPolicyRef SecPolicyCreateAppleIDValidationRecordSigningPolicy(void)
2859 {
2860 SecPolicyRef result = NULL;
2861 CFMutableDictionaryRef options = NULL;
2862 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
2863 &kCFTypeDictionaryKeyCallBacks,
2864 &kCFTypeDictionaryValueCallBacks), errOut);
2865
2866 //Leaf appears to be a SSL only cert, so policy should expand on that policy
2867 SecPolicyAddBasicX509Options(options);
2868
2869 // Apple CA anchored
2870 require(SecPolicyAddAppleAnchorOptions(options,
2871 kSecPolicyNameIDValidationRecordSigning),
2872 errOut);
2873
2874 // Check for an extension with " Apple ID Validation Record Signing" oid (1.2.840.113635.100.6.25)
2875 add_leaf_marker(options, &oidAppleCertExtensionAppleIDRecordValidationSigning);
2876
2877 // and validate that intermediate has extension
2878 // Application Integration Intermediate Certificate (1.2.840.113635.100.6.2.3)
2879 // and also validate that intermediate has extension
2880 // System Integration 2 Intermediate Certificate (1.2.840.113635.100.6.2.10)
2881 add_oid(options, kSecPolicyCheckIntermediateMarkerOid, &oidAppleIntmMarkerAppleID);
2882 add_oid(options, kSecPolicyCheckIntermediateMarkerOid, &oidAppleIntmMarkerAppleSystemIntg2);
2883
2884 // Ensure that revocation is checked (OCSP)
2885 CFDictionaryAddValue(options, kSecPolicyCheckRevocation, kSecPolicyCheckRevocationOCSP);
2886
2887 require(result = SecPolicyCreate(kSecPolicyAppleIDValidationRecordSigning,
2888 kSecPolicyNameIDValidationRecordSigning, options), errOut);
2889
2890 errOut:
2891 CFReleaseSafe(options);
2892 return result;
2893 }
2894
2895 /*!
2896 @function SecPolicyCreateAppleServerAuthCommon
2897 @abstract Generic policy for server authentication Sub CAs
2898
2899 Allows control for both if pinning is required at all and if UAT environments should be added
2900 to the trust policy.
2901
2902 No pinning is for developer/QA that needs to use proxy to debug the protocol, while UAT
2903 environment is for QA/internal developer that have no need allow fake servers.
2904
2905 Both the noPinning and UAT are gated on that you run on internal hardware.
2906
2907 */
2908
2909 static SecPolicyRef
2910 SecPolicyCreateAppleServerAuthCommon(CFStringRef hostname,
2911 CFDictionaryRef __unused context,
2912 CFStringRef policyOID, CFStringRef service,
2913 const DERItem *leafMarkerOID,
2914 const DERItem *UATLeafMarkerOID)
2915 {
2916 CFMutableDictionaryRef appleAnchorOptions = NULL;
2917 CFMutableDictionaryRef options = NULL;
2918 SecPolicyRef result = NULL;
2919 CFDataRef oid = NULL, uatoid = NULL;
2920
2921 options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
2922 require(options, errOut);
2923
2924 SecPolicyAddBasicX509Options(options);
2925
2926 require(hostname, errOut);
2927 CFDictionaryAddValue(options, kSecPolicyCheckSSLHostname, hostname);
2928
2929 CFDictionaryAddValue(options, kSecPolicyCheckBlackListedLeaf, kCFBooleanTrue);
2930 CFDictionaryAddValue(options, kSecPolicyCheckGrayListedLeaf, kCFBooleanTrue);
2931
2932 add_eku(options, &oidExtendedKeyUsageServerAuth);
2933
2934 if (requireUATPinning(service)) {
2935
2936 /*
2937 * Require pinning to the Apple CA's.
2938 */
2939 SecPolicyAddAppleAnchorOptions(options, service);
2940
2941 /* old-style leaf marker OIDs */
2942 if (UATLeafMarkerOID) {
2943 add_leaf_prod_qa_markers(options, leafMarkerOID, UATLeafMarkerOID);
2944 } else {
2945 add_leaf_marker(options, leafMarkerOID);
2946 }
2947
2948 /* new-style leaf marker OIDs */
2949 CFStringRef leafMarkerOIDStr = NULL, UATLeafMarkerOIDStr = NULL;
2950 leafMarkerOIDStr = SecDERItemCopyOIDDecimalRepresentation(NULL, leafMarkerOID);
2951 if (UATLeafMarkerOID) {
2952 UATLeafMarkerOIDStr = SecDERItemCopyOIDDecimalRepresentation(NULL, UATLeafMarkerOID);
2953 }
2954
2955 if (leafMarkerOIDStr && UATLeafMarkerOIDStr) {
2956 add_leaf_prod_qa_markers_value_string(options,
2957 CFSTR("1.2.840.113635.100.6.48.1"), leafMarkerOIDStr,
2958 CFSTR("1.2.840.113635.100.6.48.1"), UATLeafMarkerOIDStr);
2959 } else if (leafMarkerOIDStr) {
2960 add_leaf_marker_value_string(options, CFSTR("1.2.840.113635.100.6.48.1"), leafMarkerOIDStr);
2961 }
2962
2963 CFReleaseNull(leafMarkerOIDStr);
2964 CFReleaseNull(UATLeafMarkerOIDStr);
2965
2966 add_oid(options, kSecPolicyCheckIntermediateMarkerOid, &oidAppleIntmMarkerAppleServerAuthentication);
2967 }
2968
2969 /* Check for weak hashes and keys */
2970 require(SecPolicyRemoveWeakHashOptions(options), errOut);
2971 require(SecPolicyAddStrongKeySizeOptions(options), errOut);
2972
2973 CFDictionaryAddValue(options, kSecPolicyCheckRevocation, kSecPolicyCheckRevocationAny);
2974
2975 result = SecPolicyCreate(policyOID, service, options);
2976 require(result, errOut);
2977
2978 errOut:
2979 CFReleaseSafe(appleAnchorOptions);
2980 CFReleaseSafe(options);
2981 CFReleaseSafe(oid);
2982 CFReleaseSafe(uatoid);
2983 return result;
2984 }
2985
2986 /*!
2987 @function SecPolicyCreateAppleIDSService
2988 @abstract Ensure we're appropriately pinned to the IDS service (SSL + Apple restrictions)
2989 */
2990 SecPolicyRef SecPolicyCreateAppleIDSService(CFStringRef hostname)
2991 {
2992 SecPolicyRef result = SecPolicyCreateSSL(true, hostname);
2993
2994 SecPolicySetOid(result, kSecPolicyAppleIDSService);
2995 SecPolicySetName(result, kSecPolicyNameAppleIDSBag);
2996
2997 return result;
2998 }
2999
3000 /*!
3001 @function SecPolicyCreateAppleIDSService
3002 @abstract Ensure we're appropriately pinned to the IDS service (SSL + Apple restrictions)
3003 */
3004 SecPolicyRef SecPolicyCreateAppleIDSServiceContext(CFStringRef hostname, CFDictionaryRef context)
3005 {
3006 return SecPolicyCreateAppleServerAuthCommon(hostname, context, kSecPolicyAppleIDSServiceContext,
3007 kSecPolicyNameAppleIDSService,
3008 &oidAppleCertExtAppleServerAuthenticationIDSProd,
3009 &oidAppleCertExtAppleServerAuthenticationIDSProdQA);
3010 }
3011
3012 /*!
3013 @function SecPolicyCreateAppleGSService
3014 @abstract Ensure we're appropriately pinned to the GS service
3015 */
3016 SecPolicyRef SecPolicyCreateAppleGSService(CFStringRef hostname, CFDictionaryRef context)
3017 {
3018 return SecPolicyCreateAppleServerAuthCommon(hostname, context, kSecPolicyAppleGSService,
3019 kSecPolicyNameAppleGSService,
3020 &oidAppleCertExtAppleServerAuthenticationGS,
3021 NULL);
3022 }
3023
3024 /*!
3025 @function SecPolicyCreateApplePushService
3026 @abstract Ensure we're appropriately pinned to the Push service (SSL + Apple restrictions)
3027 */
3028 SecPolicyRef SecPolicyCreateApplePushService(CFStringRef hostname, CFDictionaryRef context)
3029 {
3030 return SecPolicyCreateAppleServerAuthCommon(hostname, context, kSecPolicyApplePushService,
3031 kSecPolicyNameApplePushService,
3032 &oidAppleCertExtAppleServerAuthenticationAPNProd,
3033 &oidAppleCertExtAppleServerAuthenticationAPNProdQA);
3034 }
3035
3036 /*!
3037 @function SecPolicyCreateApplePPQService
3038 @abstract Ensure we're appropriately pinned to the PPQ service (SSL + Apple restrictions)
3039 */
3040 SecPolicyRef SecPolicyCreateApplePPQService(CFStringRef hostname, CFDictionaryRef context)
3041 {
3042 return SecPolicyCreateAppleServerAuthCommon(hostname, context, kSecPolicyApplePPQService,
3043 kSecPolicyNameApplePPQService,
3044 &oidAppleCertExtAppleServerAuthenticationPPQProd ,
3045 &oidAppleCertExtAppleServerAuthenticationPPQProdQA);
3046 }
3047
3048 /*!
3049 @function SecPolicyCreateAppleAST2Service
3050 @abstract Ensure we're appropriately pinned to the AST2 Diagnostic service (SSL + Apple restrictions)
3051 */
3052 SecPolicyRef SecPolicyCreateAppleAST2Service(CFStringRef hostname, CFDictionaryRef context)
3053 {
3054 return SecPolicyCreateAppleServerAuthCommon(hostname, context, kSecPolicyAppleAST2DiagnosticsServerAuth,
3055 kSecPolicyNameAppleAST2Service,
3056 &oidAppleCertExtAST2DiagnosticsServerAuthProd,
3057 &oidAppleCertExtAST2DiagnosticsServerAuthProdQA);
3058 }
3059
3060 /*!
3061 @function SecPolicyCreateAppleEscrowProxyService
3062 @abstract Ensure we're appropriately pinned to the iCloud Escrow Proxy service (SSL + Apple restrictions)
3063 */
3064 SecPolicyRef SecPolicyCreateAppleEscrowProxyService(CFStringRef hostname, CFDictionaryRef context)
3065 {
3066 return SecPolicyCreateAppleServerAuthCommon(hostname, context, kSecPolicyAppleEscrowProxyServerAuth,
3067 kSecPolicyNameAppleEscrowProxyService,
3068 &oidAppleCertExtEscrowProxyServerAuthProd,
3069 &oidAppleCertExtEscrowProxyServerAuthProdQA);
3070 }
3071
3072 /* subject:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA */
3073 /* SKID: C0:7A:98:68:8D:89:FB:AB:05:64:0C:11:7D:AA:7D:65:B8:CA:CC:4E */
3074 /* Not Before: May 21 04:00:00 2002 GMT, Not After : May 21 04:00:00 2022 GMT */
3075 /* Signature Algorithm: sha1WithRSAEncryption */
3076 unsigned char GeoTrust_Global_CA_sha256[kSecPolicySHA256Size] = {
3077 0xff, 0x85, 0x6a, 0x2d, 0x25, 0x1d, 0xcd, 0x88, 0xd3, 0x66, 0x56, 0xf4, 0x50, 0x12, 0x67, 0x98,
3078 0xcf, 0xab, 0xaa, 0xde, 0x40, 0x79, 0x9c, 0x72, 0x2d, 0xe4, 0xd2, 0xb5, 0xdb, 0x36, 0xa7, 0x3a
3079 };
3080
3081 static SecPolicyRef SecPolicyCreateAppleGeoTrustServerAuthCommon(CFStringRef hostname, CFStringRef policyOid,
3082 CFStringRef policyName,
3083 CFStringRef leafMarkerOid,
3084 CFStringRef qaLeafMarkerOid) {
3085 CFMutableDictionaryRef options = NULL;
3086 CFDataRef spkiDigest = NULL;
3087 SecPolicyRef result = NULL;
3088
3089 require(options = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks,
3090 &kCFTypeDictionaryValueCallBacks), errOut);
3091
3092 /* basic SSL */
3093 SecPolicyAddBasicX509Options(options);
3094
3095 require(hostname, errOut);
3096 CFDictionaryAddValue(options, kSecPolicyCheckSSLHostname, hostname);
3097
3098 add_eku(options, &oidExtendedKeyUsageServerAuth);
3099
3100 /* pinning */
3101 if (requireUATPinning(policyName)) {
3102 /* GeoTrust root */
3103 SecPolicyAddAnchorSHA256Options(options, GeoTrust_Global_CA_sha256);
3104
3105 /* Issued to Apple Inc. in the US */
3106 add_element(options, kSecPolicyCheckIntermediateCountry, CFSTR("US"));
3107 add_element(options, kSecPolicyCheckIntermediateOrganization, CFSTR("Apple Inc."));
3108
3109 require_action(SecPolicyAddChainLengthOptions(options, 3), errOut, CFReleaseNull(result));
3110
3111 /* Marker OIDs in both formats */
3112 if (qaLeafMarkerOid) {
3113 add_leaf_prod_qa_markers_string(options, leafMarkerOid, qaLeafMarkerOid);
3114 add_leaf_prod_qa_markers_value_string(options,
3115 CFSTR("1.2.840.113635.100.6.48.1"), leafMarkerOid,
3116 CFSTR("1.2.840.113635.100.6.48.1"), qaLeafMarkerOid);
3117 } else {
3118 add_leaf_marker_string(options, leafMarkerOid);
3119 add_leaf_marker_value_string(options, CFSTR("1.2.840.113635.100.6.48.1"), leafMarkerOid);
3120 }
3121 }
3122
3123 /* Check for weak hashes */
3124 require(SecPolicyRemoveWeakHashOptions(options), errOut);
3125 require(SecPolicyAddStrongKeySizeOptions(options), errOut);
3126
3127 /* See <rdar://25344801> for more details */
3128
3129 result = SecPolicyCreate(policyOid, policyName, options);
3130
3131 errOut:
3132 CFReleaseSafe(options);
3133 CFReleaseSafe(spkiDigest);
3134 return result;
3135 }
3136
3137 SecPolicyRef SecPolicyCreateAppleCompatibilityEscrowProxyService(CFStringRef hostname) {
3138 return SecPolicyCreateAppleGeoTrustServerAuthCommon(hostname, kSecPolicyAppleEscrowProxyCompatibilityServerAuth,
3139 kSecPolicyNameAppleEscrowProxyService,
3140 CFSTR("1.2.840.113635.100.6.27.7.2"),
3141 CFSTR("1.2.840.113635.100.6.27.7.1"));
3142 }
3143
3144 /*!
3145 @function SecPolicyCreateAppleFMiPService
3146 @abstract Ensure we're appropriately pinned to the Find My iPhone service (SSL + Apple restrictions)
3147 */
3148 SecPolicyRef SecPolicyCreateAppleFMiPService(CFStringRef hostname, CFDictionaryRef context)
3149 {
3150 return SecPolicyCreateAppleServerAuthCommon(hostname, context, kSecPolicyAppleFMiPServerAuth,
3151 kSecPolicyNameAppleFMiPService,
3152 &oidAppleCertExtFMiPServerAuthProd,
3153 &oidAppleCertExtFMiPServerAuthProdQA);
3154 }
3155
3156
3157 /* should use verbatim copy, but since this is the deprecated way, don't care right now */
3158 static const UInt8 entrustSPKIL1C[kSecPolicySHA256Size] = {
3159 0x54, 0x5b, 0xf9, 0x35, 0xe9, 0xad, 0xa1, 0xda,
3160 0x11, 0x7e, 0xdc, 0x3c, 0x2a, 0xcb, 0xc5, 0x6f,
3161 0xc0, 0x28, 0x09, 0x6c, 0x0e, 0x24, 0xbe, 0x9b,
3162 0x38, 0x94, 0xbe, 0x52, 0x2d, 0x1b, 0x43, 0xde
3163 };
3164
3165 /*!
3166 @function SecPolicyCreateApplePushServiceLegacy
3167 @abstract Ensure we're appropriately pinned to the Push service (via Entrust)
3168 */
3169 SecPolicyRef SecPolicyCreateApplePushServiceLegacy(CFStringRef hostname)
3170 {
3171 CFMutableDictionaryRef options = NULL;
3172 SecPolicyRef result = NULL;
3173 CFDataRef digest = NULL;
3174
3175 digest = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, entrustSPKIL1C, sizeof(entrustSPKIL1C), kCFAllocatorNull);
3176 require(digest, errOut);
3177
3178 options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
3179 require(options, errOut);
3180
3181 SecPolicyAddBasicX509Options(options);
3182
3183 CFDictionaryAddValue(options, kSecPolicyCheckSSLHostname, hostname);
3184
3185 CFDictionaryAddValue(options, kSecPolicyCheckBlackListedLeaf, kCFBooleanTrue);
3186 CFDictionaryAddValue(options, kSecPolicyCheckGrayListedLeaf, kCFBooleanTrue);
3187
3188 CFDictionaryAddValue(options, kSecPolicyCheckIntermediateSPKISHA256, digest);
3189
3190 add_eku(options, &oidExtendedKeyUsageServerAuth);
3191
3192 /* Check for weak hashes and keys */
3193 require(SecPolicyRemoveWeakHashOptions(options), errOut);
3194 require(SecPolicyAddStrongKeySizeOptions(options), errOut);
3195
3196 CFDictionaryAddValue(options, kSecPolicyCheckRevocation, kSecPolicyCheckRevocationAny);
3197
3198 result = SecPolicyCreate(kSecPolicyAppleLegacyPushService,
3199 kSecPolicyNameLegacyPushService, options);
3200 require(result, errOut);
3201
3202 errOut:
3203 CFReleaseSafe(digest);
3204 CFReleaseSafe(options);
3205 return result;
3206 }
3207
3208 /*!
3209 @function SecPolicyCreateAppleMMCSService
3210 @abstract Ensure we're appropriately pinned to the IDS service (SSL + Apple restrictions)
3211 */
3212 SecPolicyRef SecPolicyCreateAppleMMCSService(CFStringRef hostname, CFDictionaryRef context)
3213 {
3214 return SecPolicyCreateAppleServerAuthCommon(hostname, context, kSecPolicyAppleMMCService,
3215 kSecPolicyNameAppleMMCSService,
3216 &oidAppleCertExtAppleServerAuthenticationMMCSProd,
3217 &oidAppleCertExtAppleServerAuthenticationMMCSProdQA);
3218 }
3219
3220 SecPolicyRef SecPolicyCreateAppleCompatibilityMMCSService(CFStringRef hostname) {
3221 return SecPolicyCreateAppleGeoTrustServerAuthCommon(hostname, kSecPolicyAppleMMCSCompatibilityServerAuth,
3222 kSecPolicyNameAppleMMCSService,
3223 CFSTR("1.2.840.113635.100.6.27.11.2"),
3224 CFSTR("1.2.840.113635.100.6.27.11.1"));
3225 }
3226
3227
3228 SecPolicyRef SecPolicyCreateAppleiCloudSetupService(CFStringRef hostname, CFDictionaryRef context)
3229 {
3230 return SecPolicyCreateAppleServerAuthCommon(hostname, context, kSecPolicyAppleiCloudSetupServerAuth,
3231 kSecPolicyNameAppleiCloudSetupService,
3232 &oidAppleCertExtAppleServerAuthenticationiCloudSetupProd,
3233 &oidAppleCertExtAppleServerAuthenticationiCloudSetupProdQA);
3234 }
3235
3236 SecPolicyRef SecPolicyCreateAppleCompatibilityiCloudSetupService(CFStringRef hostname)
3237 {
3238 return SecPolicyCreateAppleGeoTrustServerAuthCommon(hostname, kSecPolicyAppleiCloudSetupCompatibilityServerAuth,
3239 kSecPolicyNameAppleiCloudSetupService,
3240 CFSTR("1.2.840.113635.100.6.27.15.2"),
3241 CFSTR("1.2.840.113635.100.6.27.15.1"));
3242 }
3243
3244 /*!
3245 @function SecPolicyCreateAppleSSLService
3246 @abstract Ensure we're appropriately pinned to an Apple server (SSL + Apple restrictions)
3247 */
3248 SecPolicyRef SecPolicyCreateAppleSSLService(CFStringRef hostname)
3249 {
3250 // SSL server, pinned to an Apple intermediate
3251 SecPolicyRef policy = SecPolicyCreateSSL(true, hostname);
3252 CFMutableDictionaryRef options = NULL;
3253 require(policy, errOut);
3254
3255 // change options for SSL policy evaluation
3256 require((options=(CFMutableDictionaryRef)policy->_options) != NULL, errOut);
3257
3258 // Apple CA anchored
3259 require(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameServerAuthentication), errOut);
3260
3261 // Check leaf for Apple Server Authentication marker oid (1.2.840.113635.100.6.27.1)
3262 add_leaf_marker(options, &oidAppleCertExtAppleServerAuthentication);
3263
3264 // Check intermediate for Apple Server Authentication intermediate marker (1.2.840.113635.100.6.2.12)
3265 add_oid(options, kSecPolicyCheckIntermediateMarkerOid, &oidAppleIntmMarkerAppleServerAuthentication);
3266
3267 /* Check for weak hashes */
3268 require(SecPolicyRemoveWeakHashOptions(options), errOut);
3269
3270 CFDictionaryAddValue(options, kSecPolicyCheckRevocation, kSecPolicyCheckRevocationAny);
3271
3272 SecPolicySetOid(policy, kSecPolicyAppleServerAuthentication);
3273 SecPolicySetName(policy, kSecPolicyNameServerAuthentication);
3274
3275 return policy;
3276
3277 errOut:
3278 CFReleaseSafe(options);
3279 CFReleaseSafe(policy);
3280 return NULL;
3281 }
3282
3283 /*!
3284 @function SecPolicyCreateApplePPQSigning
3285 @abstract Check for intermediate certificate 'Apple System Integration 2 Certification Authority' by name,
3286 and apple anchor.
3287 Leaf cert must have Digital Signature usage.
3288 Leaf cert must have Apple PPQ Signing marker OID (1.2.840.113635.100.6.38.2).
3289 Intermediate must have marker OID (1.2.840.113635.100.6.2.10).
3290 */
3291 SecPolicyRef SecPolicyCreateApplePPQSigning(void)
3292 {
3293 SecPolicyRef result = NULL;
3294 CFMutableDictionaryRef options = NULL;
3295 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
3296 &kCFTypeDictionaryKeyCallBacks,
3297 &kCFTypeDictionaryValueCallBacks), errOut);
3298 SecPolicyAddBasicCertOptions(options);
3299
3300 SecPolicyAddAppleAnchorOptions(options, kSecPolicyNamePPQSigning);
3301 require(SecPolicyAddChainLengthOptions(options, 3), errOut);
3302
3303 CFDictionaryAddValue(options, kSecPolicyCheckIssuerCommonName,
3304 CFSTR("Apple System Integration 2 Certification Authority"));
3305
3306 // Check that leaf has extension with "Apple PPQ Signing" prod oid (1.2.840.113635.100.6.38.2)
3307 add_leaf_marker(options, &oidAppleCertExtApplePPQSigningProd);
3308
3309 // Check that intermediate has extension (1.2.840.113635.100.6.2.10)
3310 add_oid(options, kSecPolicyCheckIntermediateMarkerOid, &oidAppleIntmMarkerAppleSystemIntg2);
3311
3312 add_ku(options, kSecKeyUsageDigitalSignature);
3313
3314 require(result = SecPolicyCreate(kSecPolicyApplePPQSigning,
3315 kSecPolicyNamePPQSigning, options), errOut);
3316
3317 errOut:
3318 CFReleaseSafe(options);
3319 return result;
3320 }
3321
3322 /*!
3323 @function SecPolicyCreateTestApplePPQSigning
3324 @abstract Check for intermediate certificate 'Apple System Integration 2 Certification Authority' by name,
3325 and apple anchor.
3326 Leaf cert must have Digital Signature usage.
3327 Leaf cert must have Apple PPQ Signing Test marker OID (1.2.840.113635.100.6.38.1).
3328 Intermediate must have marker OID (1.2.840.113635.100.6.2.10).
3329 */
3330 SecPolicyRef SecPolicyCreateTestApplePPQSigning(void)
3331 {
3332 /* Guard against use of test policy on production devices */
3333 if (!SecIsInternalRelease()) {
3334 return SecPolicyCreateApplePPQSigning();
3335 }
3336
3337 SecPolicyRef result = NULL;
3338 CFMutableDictionaryRef options = NULL;
3339 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
3340 &kCFTypeDictionaryKeyCallBacks,
3341 &kCFTypeDictionaryValueCallBacks), errOut);
3342 SecPolicyAddBasicCertOptions(options);
3343
3344 SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameTestPPQSigning);
3345 require(SecPolicyAddChainLengthOptions(options, 3), errOut);
3346
3347 CFDictionaryAddValue(options, kSecPolicyCheckIssuerCommonName,
3348 CFSTR("Apple System Integration 2 Certification Authority"));
3349
3350 // Check that leaf has extension with "Apple PPQ Signing" test oid (1.2.840.113635.100.6.38.1)
3351 add_leaf_marker(options, &oidAppleCertExtApplePPQSigningProdQA);
3352
3353 // Check that intermediate has extension (1.2.840.113635.100.6.2.10)
3354 add_oid(options, kSecPolicyCheckIntermediateMarkerOid, &oidAppleIntmMarkerAppleSystemIntg2);
3355
3356 add_ku(options, kSecKeyUsageDigitalSignature);
3357
3358 require(result = SecPolicyCreate(kSecPolicyAppleTestPPQSigning,
3359 kSecPolicyNameTestPPQSigning, options), errOut);
3360
3361 errOut:
3362 CFReleaseSafe(options);
3363 return result;
3364 }
3365 /*!
3366 @function SecPolicyCreateAppleTimeStamping
3367 @abstract Check for RFC3161 timestamping EKU.
3368 */
3369 SecPolicyRef SecPolicyCreateAppleTimeStamping(void)
3370 {
3371 SecPolicyRef result = NULL;
3372 CFMutableDictionaryRef options = NULL;
3373 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
3374 &kCFTypeDictionaryKeyCallBacks,
3375 &kCFTypeDictionaryValueCallBacks), errOut);
3376
3377 SecPolicyAddBasicX509Options(options);
3378
3379 /* Require id-kp-timeStamping extendedKeyUsage to be present. */
3380 add_eku(options, &oidExtendedKeyUsageTimeStamping);
3381
3382 require(result = SecPolicyCreate(kSecPolicyAppleTimeStamping,
3383 kSecPolicyNameTimeStamping, options), errOut);
3384
3385 errOut:
3386 CFReleaseSafe(options);
3387 return result;
3388 }
3389
3390 /*!
3391 @function SecPolicyCreateApplePayIssuerEncryption
3392 @abstract Check for intermediate certificate 'Apple Worldwide Developer Relations CA - G2' by name,
3393 and ECC apple anchor.
3394 Leaf cert must have Key Encipherment and Key Agreement usage.
3395 Leaf cert must have Apple Pay Issuer Encryption marker OID (1.2.840.113635.100.6.39).
3396 */
3397 SecPolicyRef SecPolicyCreateApplePayIssuerEncryption(void)
3398 {
3399 SecPolicyRef result = NULL;
3400 CFMutableDictionaryRef options = NULL;
3401 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
3402 &kCFTypeDictionaryKeyCallBacks,
3403 &kCFTypeDictionaryValueCallBacks), errOut);
3404 SecPolicyAddBasicCertOptions(options);
3405
3406 require(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNamePayIssuerEncryption),
3407 errOut);
3408 require(SecPolicyAddChainLengthOptions(options, 3), errOut);
3409
3410 CFDictionaryAddValue(options, kSecPolicyCheckIssuerCommonName,
3411 CFSTR("Apple Worldwide Developer Relations CA - G2"));
3412
3413 // Check that leaf has extension with "Apple Pay Issuer Encryption" oid (1.2.840.113635.100.6.39)
3414 add_leaf_marker(options, &oidAppleCertExtCryptoServicesExtEncryption);
3415
3416 add_ku(options, kSecKeyUsageKeyEncipherment);
3417
3418 require(result = SecPolicyCreate(kSecPolicyApplePayIssuerEncryption,
3419 kSecPolicyNamePayIssuerEncryption, options), errOut);
3420
3421 errOut:
3422 CFReleaseSafe(options);
3423 return result;
3424 }
3425
3426 /*!
3427 @function SecPolicyCreateAppleATVVPNProfileSigning
3428 @abstract Check for leaf marker OID 1.2.840.113635.100.6.43,
3429 intermediate marker OID 1.2.840.113635.100.6.2.10,
3430 chains to Apple Root CA, path length 3
3431 */
3432 SecPolicyRef SecPolicyCreateAppleATVVPNProfileSigning(void)
3433 {
3434 SecPolicyRef result = NULL;
3435 CFMutableDictionaryRef options = NULL;
3436 CFMutableDictionaryRef appleAnchorOptions = NULL;
3437 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
3438 &kCFTypeDictionaryKeyCallBacks,
3439 &kCFTypeDictionaryValueCallBacks), errOut);
3440
3441 SecPolicyAddBasicCertOptions(options);
3442
3443 // Require pinning to the Apple CAs (including test CA for internal releases)
3444 appleAnchorOptions = CFDictionaryCreateMutableForCFTypes(NULL);
3445 require(appleAnchorOptions, errOut);
3446
3447 if (SecIsInternalRelease()) {
3448 CFDictionarySetValue(appleAnchorOptions,
3449 kSecPolicyAppleAnchorIncludeTestRoots, kCFBooleanTrue);
3450 }
3451
3452 add_element(options, kSecPolicyCheckAnchorApple, appleAnchorOptions);
3453
3454 // Cert chain length 3
3455 require(SecPolicyAddChainLengthOptions(options, 3), errOut);
3456
3457 // Check leaf for Apple ATV VPN Profile Signing OID (1.2.840.113635.100.6.43)
3458 add_leaf_marker(options, &oidAppleCertExtATVVPNProfileSigning);
3459
3460 // Check intermediate for Apple System Integration 2 CA intermediate marker (1.2.840.113635.100.6.2.10)
3461 add_oid(options, kSecPolicyCheckIntermediateMarkerOid, &oidAppleIntmMarkerAppleSystemIntg2);
3462
3463 // Ensure that revocation is checked (OCSP only)
3464 CFDictionaryAddValue(options, kSecPolicyCheckRevocation, kSecPolicyCheckRevocationOCSP);
3465
3466 require(result = SecPolicyCreate(kSecPolicyAppleATVVPNProfileSigning,
3467 kSecPolicyNameATVVPNProfileSigning, options), errOut);
3468
3469 errOut:
3470 CFReleaseSafe(options);
3471 CFReleaseSafe(appleAnchorOptions);
3472 return result;
3473 }
3474
3475 SecPolicyRef SecPolicyCreateAppleHomeKitServerAuth(CFStringRef hostname) {
3476 CFMutableDictionaryRef appleAnchorOptions = NULL;
3477 CFMutableDictionaryRef options = NULL;
3478 SecPolicyRef result = NULL;
3479 CFDataRef oid = NULL;
3480
3481 options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
3482 require(options, errOut);
3483
3484 SecPolicyAddBasicX509Options(options);
3485
3486 CFDictionaryAddValue(options, kSecPolicyCheckSSLHostname, hostname);
3487
3488 add_eku(options, &oidExtendedKeyUsageServerAuth);
3489
3490 if (requireUATPinning(kSecPolicyNameAppleHomeKitService)) {
3491
3492 // Cert chain length 3
3493 require(SecPolicyAddChainLengthOptions(options, 3), errOut);
3494
3495 // Apple anchors, allowing test anchors for internal release
3496 SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameAppleHomeKitService);
3497
3498 add_leaf_marker(options, &oidAppleCertExtHomeKitServerAuth);
3499
3500 add_oid(options, kSecPolicyCheckIntermediateMarkerOid, &oidAppleIntmMarkerAppleHomeKitServerCA);
3501 }
3502
3503 /* Check for weak hashes */
3504 require(SecPolicyRemoveWeakHashOptions(options), errOut);
3505 require(SecPolicyAddStrongKeySizeOptions(options), errOut);
3506
3507 CFDictionaryAddValue(options, kSecPolicyCheckRevocation, kSecPolicyCheckRevocationAny);
3508
3509 result = SecPolicyCreate(kSecPolicyAppleHomeKitServerAuth,
3510 kSecPolicyNameAppleHomeKitService, options);
3511 require(result, errOut);
3512
3513 errOut:
3514 CFReleaseSafe(appleAnchorOptions);
3515 CFReleaseSafe(options);
3516 CFReleaseSafe(oid);
3517 return result;
3518 }
3519
3520 SecPolicyRef SecPolicyCreateAppleExternalDeveloper(void) {
3521 CFMutableDictionaryRef options = NULL;
3522 SecPolicyRef result = NULL;
3523
3524 /* Create basic Apple pinned policy */
3525 require(result = SecPolicyCreateApplePinned(kSecPolicyNameExternalDeveloper,
3526 CFSTR("1.2.840.113635.100.6.2.1"), // WWDR Intermediate OID
3527 CFSTR("1.2.840.113635.100.6.1.2")), // "iPhone Developer" leaf OID
3528 errOut);
3529
3530 require_action(options = CFDictionaryCreateMutableCopy(NULL, 0, result->_options), errOut, CFReleaseNull(result));
3531
3532 /* Additional intermediate OIDs */
3533 add_element(options, kSecPolicyCheckIntermediateMarkerOid,
3534 CFSTR("1.2.840.113635.100.6.2.6")); // "Developer ID" Intermediate OID
3535
3536 /* Addtional leaf OIDS */
3537 add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.6.1.4")); // "iPhone Distribution" leaf OID
3538 add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.6.1.5")); // "Safari Developer" leaf OID
3539 add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.6.1.7")); // "3rd Party Mac Developer Application" leaf OID
3540 add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.6.1.8")); // "3rd Party Mac Developer Installer" leaf OID
3541 add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.6.1.12")); // "Mac Developer" leaf OID
3542 add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.6.1.13")); // "Developer ID Application" leaf OID
3543 add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.6.1.14")); // "Developer ID Installer" leaf OID
3544
3545 /* Restrict EKUs */
3546 add_eku_string(options, CFSTR("1.3.6.1.5.5.7.3.3")); // CodeSigning EKU
3547 add_eku_string(options, CFSTR("1.2.840.113635.100.4.8")); // "Safari Developer" EKU
3548 add_eku_string(options, CFSTR("1.2.840.113635.100.4.9")); // "3rd Party Mac Developer Installer" EKU
3549 add_eku_string(options, CFSTR("1.2.840.113635.100.4.13")); // "Developer ID Installer" EKU
3550
3551 CFReleaseSafe(result->_options);
3552 result->_options = CFRetainSafe(options);
3553
3554 SecPolicySetOid(result, kSecPolicyAppleExternalDeveloper);
3555
3556 errOut:
3557 CFReleaseSafe(options);
3558 return result;
3559 }
3560
3561 /* This one is special because the intermediate has no marker OID */
3562 SecPolicyRef SecPolicyCreateAppleSoftwareSigning(void) {
3563 CFMutableDictionaryRef options = NULL;
3564 CFDictionaryRef keySizes = NULL;
3565 CFNumberRef rsaSize = NULL, ecSize = NULL;
3566 SecPolicyRef result = NULL;
3567
3568 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
3569 &kCFTypeDictionaryKeyCallBacks,
3570 &kCFTypeDictionaryValueCallBacks), errOut);
3571
3572 SecPolicyAddBasicCertOptions(options);
3573
3574 /* Anchored to the Apple Roots */
3575 require_quiet(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameSoftwareSigning),
3576 errOut);
3577
3578 /* Exactly 3 certs in the chain */
3579 require(SecPolicyAddChainLengthOptions(options, 3), errOut);
3580
3581 /* Intermediate Common Name matches */
3582 add_element(options, kSecPolicyCheckIssuerCommonName, CFSTR("Apple Code Signing Certification Authority"));
3583
3584 /* Leaf marker OID matches */
3585 add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.6.22"));
3586
3587 /* Leaf has CodeSigning EKU */
3588 add_eku_string(options, CFSTR("1.3.6.1.5.5.7.3.3"));
3589
3590 /* Check revocation using any available method */
3591 add_element(options, kSecPolicyCheckRevocation, kSecPolicyCheckRevocationAny);
3592
3593 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
3594 require(SecPolicyAddStrongKeySizeOptions(options), errOut);
3595
3596 require(result = SecPolicyCreate(kSecPolicyAppleSoftwareSigning,
3597 kSecPolicyNameSoftwareSigning, options), errOut);
3598
3599 errOut:
3600 CFReleaseSafe(options);
3601 CFReleaseSafe(keySizes);
3602 CFReleaseSafe(rsaSize);
3603 CFReleaseSafe(ecSize);
3604 return result;
3605 }
3606
3607 /* subject:/CN=SEP Root CA/O=Apple Inc./ST=California */
3608 /* SKID: 58:EF:D6:BE:C5:82:B0:54:CD:18:A6:84:AD:A2:F6:7B:7B:3A:7F:CF */
3609 /* Not Before: Jun 24 21:43:24 2014 GMT, Not After : Jun 24 21:43:24 2029 GMT */
3610 /* Signature Algorithm: ecdsa-with-SHA384 */
3611 const uint8_t SEPRootCA_SHA256[kSecPolicySHA256Size] = {
3612 0xd1, 0xdf, 0x82, 0x00, 0xf3, 0x89, 0x4e, 0xe9, 0x96, 0xf3, 0x77, 0xdf, 0x76, 0x3b, 0x0a, 0x16,
3613 0x8f, 0xd9, 0x6c, 0x58, 0xc0, 0x3e, 0xc9, 0xb0, 0x5f, 0xa5, 0x64, 0x79, 0xc0, 0xe8, 0xc9, 0xe7
3614 };
3615
3616 SecPolicyRef SecPolicyCreateAppleUniqueDeviceCertificate(CFDataRef testRootHash) {
3617 CFMutableDictionaryRef options = NULL;
3618 CFDictionaryRef keySizes = NULL;
3619 CFNumberRef ecSize = NULL;
3620 SecPolicyRef result = NULL;
3621
3622 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
3623 &kCFTypeDictionaryKeyCallBacks,
3624 &kCFTypeDictionaryValueCallBacks), errOut);
3625
3626 /* Device certificate should never expire */
3627 SecPolicyAddBasicCertOptions(options);
3628
3629 /* Anchored to the SEP Root CA. Allow alternative root for developers */
3630 require(SecPolicyAddAnchorSHA256Options(options, SEPRootCA_SHA256),errOut);
3631 if (testRootHash && SecIsInternalRelease() && (kSecPolicySHA256Size == CFDataGetLength(testRootHash))) {
3632 add_element(options, kSecPolicyCheckAnchorSHA256, testRootHash);
3633 }
3634
3635 /* Exactly 3 certs in the chain */
3636 require(SecPolicyAddChainLengthOptions(options, 3), errOut);
3637
3638 /* Intermediate has marker OID with value */
3639 add_intermediate_marker_value_string(options, CFSTR("1.2.840.113635.100.6.44"), CFSTR("ucrt"));
3640
3641 /* Leaf has marker OID with varying value that can't be pre-determined */
3642 add_element(options, kSecPolicyCheckLeafMarkerOidWithoutValueCheck, CFSTR("1.2.840.113635.100.10.1"));
3643
3644 /* RSA key sizes are disallowed. EC key sizes are P-256 or larger. */
3645 require(ecSize = CFNumberCreateWithCFIndex(NULL, 256), errOut);
3646 require(keySizes = CFDictionaryCreate(NULL, (const void**)&kSecAttrKeyTypeEC,
3647 (const void**)&ecSize, 1,
3648 &kCFTypeDictionaryKeyCallBacks,
3649 &kCFTypeDictionaryValueCallBacks), errOut);
3650 add_element(options, kSecPolicyCheckKeySize, keySizes);
3651
3652
3653 require(result = SecPolicyCreate(kSecPolicyAppleUniqueDeviceIdentifierCertificate,
3654 kSecPolicyNameUniqueDeviceIdentifierCertificate, options), errOut);
3655
3656 errOut:
3657 CFReleaseSafe(options);
3658 CFReleaseSafe(keySizes);
3659 CFReleaseSafe(ecSize);
3660 return result;
3661 }
3662
3663 SecPolicyRef SecPolicyCreateAppleWarsaw(void) {
3664 CFMutableDictionaryRef options = NULL;
3665 SecPolicyRef result = NULL;
3666 #if TARGET_OS_BRIDGE
3667 CFMutableDictionaryRef appleAnchorOptions = NULL;
3668 #endif
3669
3670 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
3671 &kCFTypeDictionaryKeyCallBacks,
3672 &kCFTypeDictionaryValueCallBacks), errOut);
3673
3674 SecPolicyAddBasicX509Options(options);
3675
3676 /* Anchored to the Apple Roots. */
3677 require_quiet(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameWarsaw),
3678 errOut);
3679
3680 /* Exactly 3 certs in the chain */
3681 require(SecPolicyAddChainLengthOptions(options, 3), errOut);
3682
3683 /* Intermediate marker OID matches input OID */
3684 add_element(options, kSecPolicyCheckIntermediateMarkerOid, CFSTR("1.2.840.113635.100.6.2.14"));
3685
3686 /* Leaf marker OID matches input OID */
3687 add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.6.29"));
3688
3689 /* Check revocation using any available method */
3690 add_element(options, kSecPolicyCheckRevocation, kSecPolicyCheckRevocationAny);
3691
3692 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
3693 require(SecPolicyAddStrongKeySizeOptions(options), errOut);
3694
3695 require(result = SecPolicyCreate(kSecPolicyAppleWarsaw,
3696 kSecPolicyNameWarsaw, options), errOut);
3697
3698 errOut:
3699 CFReleaseSafe(options);
3700 return result;
3701 }
3702
3703 SecPolicyRef SecPolicyCreateAppleSecureIOStaticAsset(void) {
3704 CFMutableDictionaryRef options = NULL;
3705 SecPolicyRef result = NULL;
3706 #if TARGET_OS_BRIDGE
3707 CFMutableDictionaryRef appleAnchorOptions = NULL;
3708 #endif
3709
3710 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
3711 &kCFTypeDictionaryKeyCallBacks,
3712 &kCFTypeDictionaryValueCallBacks), errOut);
3713
3714 /* This certificate cannot expire so that assets always load */
3715 SecPolicyAddBasicCertOptions(options);
3716
3717 /* Anchored to the Apple Roots. */
3718 #if TARGET_OS_BRIDGE
3719 /* On the bridge, test roots are gated in the trust and policy servers. */
3720 require_quiet(appleAnchorOptions = CFDictionaryCreateMutableForCFTypes(NULL), errOut);
3721 CFDictionarySetValue(appleAnchorOptions,
3722 kSecPolicyAppleAnchorIncludeTestRoots, kCFBooleanTrue);
3723 add_element(options, kSecPolicyCheckAnchorApple, appleAnchorOptions);
3724 CFReleaseSafe(appleAnchorOptions);
3725 #else
3726 require_quiet(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameSecureIOStaticAsset),
3727 errOut);
3728 #endif
3729
3730 /* Exactly 3 certs in the chain */
3731 require(SecPolicyAddChainLengthOptions(options, 3), errOut);
3732
3733 /* Intermediate marker OID matches ASI CA */
3734 add_element(options, kSecPolicyCheckIntermediateMarkerOid, CFSTR("1.2.840.113635.100.6.2.10"));
3735
3736 /* Leaf marker OID matches static IO OID */
3737 add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.6.50"));
3738
3739 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
3740 require(SecPolicyAddStrongKeySizeOptions(options), errOut);
3741
3742 require(result = SecPolicyCreate(kSecPolicyAppleSecureIOStaticAsset,
3743 kSecPolicyNameSecureIOStaticAsset, options), errOut);
3744
3745 errOut:
3746 CFReleaseSafe(options);
3747 return result;
3748 }
3749
3750 SecPolicyRef SecPolicyCreateAppleAppTransportSecurity(void) {
3751 CFMutableDictionaryRef options = NULL;
3752 SecPolicyRef result = NULL;
3753 CFMutableArrayRef disallowedHashes = NULL;
3754
3755 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
3756 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut);
3757
3758 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
3759 require(SecPolicyAddStrongKeySizeOptions(options), errOut);
3760
3761 /* Hash algorithm is SHA-256 or better */
3762 require(disallowedHashes = CFArrayCreateMutable(NULL, 5, &kCFTypeArrayCallBacks), errOut);
3763 CFArrayAppendValue(disallowedHashes, kSecSignatureDigestAlgorithmMD2);
3764 CFArrayAppendValue(disallowedHashes, kSecSignatureDigestAlgorithmMD4);
3765 CFArrayAppendValue(disallowedHashes, kSecSignatureDigestAlgorithmMD5);
3766 CFArrayAppendValue(disallowedHashes, kSecSignatureDigestAlgorithmSHA1);
3767 CFArrayAppendValue(disallowedHashes, kSecSignatureDigestAlgorithmSHA224);
3768
3769 add_element(options, kSecPolicyCheckSignatureHashAlgorithms, disallowedHashes);
3770
3771 require_quiet(result = SecPolicyCreate(kSecPolicyAppleAppTransportSecurity,
3772 kSecPolicyNameAppTransportSecurity,
3773 options), errOut);
3774
3775 errOut:
3776 CFReleaseSafe(options);
3777 return result;
3778 }
3779
3780 SecPolicyRef SecPolicyCreateMobileSoftwareUpdate(void) {
3781 CFMutableDictionaryRef options = NULL;
3782 SecPolicyRef result = NULL;
3783 #if TARGET_OS_BRIDGE
3784 CFMutableDictionaryRef appleAnchorOptions = NULL;
3785 #endif
3786
3787 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
3788 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut);
3789
3790 /* No expiration check. */
3791 SecPolicyAddBasicCertOptions(options);
3792
3793 /* Apple Anchor */
3794 require_quiet(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameMobileSoftwareUpdate),
3795 errOut);
3796
3797 /* Exactly 3 certs in the chain */
3798 require(SecPolicyAddChainLengthOptions(options, 3), errOut);
3799
3800 /* Intermediate marker OID is iPhone CA OID */
3801 add_element(options, kSecPolicyCheckIntermediateMarkerOid, CFSTR("1.2.840.113635.100.6.2.18"));
3802
3803 /* Leaf marker OID is either the prod MSU OID, or, on internal builds, the prodQA OID */
3804 add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.6.57.2"));
3805 if (SecIsInternalRelease()) {
3806 add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.6.57.1"));
3807 }
3808
3809 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
3810 require(SecPolicyAddStrongKeySizeOptions(options), errOut);
3811
3812 require(result = SecPolicyCreate(kSecPolicyAppleMobileSoftwareUpdate,
3813 kSecPolicyNameMobileSoftwareUpdate, options), errOut);
3814
3815 errOut:
3816 CFReleaseNull(options);
3817 return result;
3818 }
3819
3820 /* subject:/CN=Basic Attestation System Root CA/O=Apple Inc./ST=California */
3821 /* SKID: FE:D1:D1:C2:08:07:03:D5:B9:3C:34:B2:BB:FD:7C:3A:99:25:1B:8F */
3822 /* Not Before: Apr 20 00:22:09 2017 GMT, Not After : Mar 22 00:00:00 2032 GMT */
3823 /* Signature Algorithm: ecdsa-with-SHA384 */
3824 const uint8_t BASystemRootCA_SHA256[kSecPolicySHA256Size] = {
3825 0x10, 0xD3, 0xC8, 0x67, 0xF0, 0xAE, 0xFB, 0x24, 0x31, 0xA0, 0xA9, 0x7A, 0x88, 0x18, 0xBD, 0x64,
3826 0xF7, 0xF9, 0x0F, 0xFE, 0x11, 0x94, 0x48, 0x4F, 0xCA, 0x97, 0xF0, 0xF2, 0x9E, 0xCA, 0x00, 0x47
3827 };
3828
3829 /* subject:/CN=Basic Attestation User Root CA/O=Apple Inc./ST=California */
3830 /* SKID: 83:E5:A3:21:9E:B0:74:C3:F9:61:90:FD:97:4E:23:10:76:A4:A3:F2 */
3831 /* Not Before: Apr 19 21:41:56 2017 GMT, Not After : Mar 22 00:00:00 2032 GMT */
3832 /* Signature Algorithm: ecdsa-with-SHA384 */
3833 const uint8_t BAUserRootCA_SHA256[kSecPolicySHA256Size] = {
3834 0x03, 0x75, 0x1c, 0x80, 0xfc, 0xbe, 0x58, 0x19, 0xd1, 0x70, 0xd2, 0x67, 0xce, 0x1a, 0xd6, 0xd0,
3835 0x94, 0x40, 0x7c, 0x91, 0xd8, 0x73, 0xd7, 0xa6, 0x56, 0x2d, 0xe3, 0x66, 0x6d, 0x35, 0x94, 0xc6
3836 };
3837
3838 SecPolicyRef SecPolicyCreateAppleBasicAttestationSystem(CFDataRef testRootHash) {
3839 CFMutableDictionaryRef options = NULL;
3840 SecPolicyRef result = NULL;
3841
3842 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
3843 &kCFTypeDictionaryKeyCallBacks,
3844 &kCFTypeDictionaryValueCallBacks), errOut);
3845 /* BAA certs expire */
3846 SecPolicyAddBasicX509Options(options);
3847
3848 /* Anchored to one of the Basic Attestation roots. Allow alternative root for developers */
3849 SecPolicyAddAnchorSHA256Options(options, BASystemRootCA_SHA256);
3850 if (testRootHash && SecIsInternalRelease() && (kSecPolicySHA256Size == CFDataGetLength(testRootHash))) {
3851 add_element(options, kSecPolicyCheckAnchorSHA256, testRootHash);
3852 }
3853
3854 /* Exactly 3 certs in the chain */
3855 require(SecPolicyAddChainLengthOptions(options, 3), errOut);
3856
3857 require(result = SecPolicyCreate(kSecPolicyAppleBasicAttestationSystem,
3858 kSecPolicyNameBasicAttestationSystem, options), errOut);
3859
3860 errOut:
3861 CFReleaseSafe(options);
3862 return result;
3863 }
3864
3865 SecPolicyRef SecPolicyCreateAppleBasicAttestationUser(CFDataRef testRootHash) {
3866 CFMutableDictionaryRef options = NULL;
3867 SecPolicyRef result = NULL;
3868
3869 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
3870 &kCFTypeDictionaryKeyCallBacks,
3871 &kCFTypeDictionaryValueCallBacks), errOut);
3872 /* BAA certs expire */
3873 SecPolicyAddBasicX509Options(options);
3874
3875 /* Anchored to one of the Basic Attestation roots. Allow alternative root for developers */
3876 SecPolicyAddAnchorSHA256Options(options, BAUserRootCA_SHA256);
3877 if (testRootHash && SecIsInternalRelease() && (kSecPolicySHA256Size == CFDataGetLength(testRootHash))) {
3878 add_element(options, kSecPolicyCheckAnchorSHA256, testRootHash);
3879 }
3880
3881 /* Exactly 3 certs in the chain */
3882 require(SecPolicyAddChainLengthOptions(options, 3), errOut);
3883
3884 require(result = SecPolicyCreate(kSecPolicyAppleBasicAttestationUser,
3885 kSecPolicyNameBasicAttestationUser, options), errOut);
3886
3887 errOut:
3888 CFReleaseSafe(options);
3889 return result;
3890 }
3891
3892 SecPolicyRef SecPolicyCreateiAPSWAuthWithExpiration(bool checkExpiration) {
3893 CFMutableDictionaryRef options = NULL;
3894 SecPolicyRef result = NULL;
3895
3896 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
3897 &kCFTypeDictionaryKeyCallBacks,
3898 &kCFTypeDictionaryValueCallBacks), errOut);
3899
3900 /* iAP checks expiration on developement certs, but not on production certs */
3901 if (checkExpiration) {
3902 SecPolicyAddBasicX509Options(options);
3903 } else {
3904 SecPolicyAddBasicCertOptions(options);
3905 }
3906
3907 /* Exactly 2 certs in the chain */
3908 require(SecPolicyAddChainLengthOptions(options, 2), errOut);
3909
3910 /* iAP SW Auth General Capabilities Extension present */
3911 add_element(options, kSecPolicyCheckLeafMarkerOidWithoutValueCheck, CFSTR("1.2.840.113635.100.6.59.1"));
3912
3913 require(result = SecPolicyCreate(kSecPolicyAppleiAPSWAuth,
3914 kSecPolicyNameiAPSWAuth, options), errOut);
3915
3916 errOut:
3917 CFReleaseSafe(options);
3918 return result;
3919 }
3920
3921 SecPolicyRef SecPolicyCreateiAPSWAuth(void) {
3922 /* By default, iAP SW Auth certs don't expire */
3923 return SecPolicyCreateiAPSWAuthWithExpiration(false);
3924 }
3925
3926 SecPolicyRef SecPolicyCreateDemoDigitalCatalogSigning(void) {
3927 CFMutableDictionaryRef options = NULL;
3928 SecPolicyRef result = NULL;
3929
3930 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
3931 &kCFTypeDictionaryKeyCallBacks,
3932 &kCFTypeDictionaryValueCallBacks), errOut);
3933 SecPolicyAddBasicX509Options(options);
3934
3935 /* Exactly 3 certs in the chain */
3936 require(SecPolicyAddChainLengthOptions(options, 3), errOut);
3937
3938 /* Demo Signing Extension present in leaf */
3939 add_element(options, kSecPolicyCheckLeafMarkerOid, CFSTR("1.2.840.113635.100.6.60"));
3940
3941 /* Issuer common name is "DemoUnit CA" */
3942 add_element(options, kSecPolicyCheckIssuerCommonName, CFSTR("DemoUnit CA"));
3943
3944 require(result = SecPolicyCreate(kSecPolicyAppleDemoDigitalCatalog,
3945 kSecPolicyNameDemoDigitalCatalog, options), errOut);
3946
3947 errOut:
3948 CFReleaseSafe(options);
3949 return result;
3950 }
3951
3952 SecPolicyRef SecPolicyCreateAppleAssetReceipt(void) {
3953 CFMutableDictionaryRef options = NULL;
3954 SecPolicyRef result = NULL;
3955
3956 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
3957 &kCFTypeDictionaryKeyCallBacks,
3958 &kCFTypeDictionaryValueCallBacks), errOut);
3959
3960 /* No expiration check. */
3961 SecPolicyAddBasicCertOptions(options);
3962
3963 /* Apple Anchor */
3964 require_quiet(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameAssetReceipt), errOut);
3965
3966 /* Exactly 3 certs in the chain */
3967 require(SecPolicyAddChainLengthOptions(options, 3), errOut);
3968
3969 /* Intermediate marker OID is Apple System Integration 2 CA */
3970 add_element(options, kSecPolicyCheckIntermediateMarkerOid, CFSTR("1.2.840.113635.100.6.2.10"));
3971
3972 /* Leaf marker OID is the Asset Receipt OID */
3973 add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.6.61"));
3974
3975 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
3976 require(SecPolicyAddStrongKeySizeOptions(options), errOut);
3977
3978 require(result = SecPolicyCreate(kSecPolicyAppleAssetReceipt,
3979 kSecPolicyNameAssetReceipt, options), errOut);
3980
3981 errOut:
3982 CFReleaseNull(options);
3983 return result;
3984 }
3985
3986 SecPolicyRef SecPolicyCreateAppleDeveloperIDPlusTicket(void) {
3987 CFMutableDictionaryRef options = NULL;
3988 SecPolicyRef result = NULL;
3989
3990 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
3991 &kCFTypeDictionaryKeyCallBacks,
3992 &kCFTypeDictionaryValueCallBacks), errOut);
3993
3994 /* No expiration check. */
3995 SecPolicyAddBasicCertOptions(options);
3996
3997 /* Apple Anchor */
3998 require_quiet(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameDeveloperIDPlusTicket), errOut);
3999
4000 /* Exactly 3 certs in the chain */
4001 require(SecPolicyAddChainLengthOptions(options, 3), errOut);
4002
4003 /* Intermediate marker OID is Apple System Integration CA 4 */
4004 add_element(options, kSecPolicyCheckIntermediateMarkerOid, CFSTR("1.2.840.113635.100.6.2.17"));
4005
4006 /* Leaf marker OID is the Developer ID+ Ticket OID */
4007 add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.6.1.30"));
4008
4009 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
4010 require(SecPolicyAddStrongKeySizeOptions(options), errOut);
4011
4012 require(result = SecPolicyCreate(kSecPolicyAppleDeveloperIDPlusTicket,
4013 kSecPolicyNameDeveloperIDPlusTicket, options), errOut);
4014
4015 errOut:
4016 CFReleaseNull(options);
4017 return result;
4018 }
4019
4020 SecPolicyRef SecPolicyCreateAppleFDRProvisioning(void) {
4021 CFMutableDictionaryRef options = NULL;
4022 SecPolicyRef result = NULL;
4023
4024 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
4025 &kCFTypeDictionaryKeyCallBacks,
4026 &kCFTypeDictionaryValueCallBacks), errOut);
4027
4028 /* No expiration check. */
4029 SecPolicyAddBasicCertOptions(options);
4030
4031 require(result = SecPolicyCreate(kSecPolicyAppleFDRProvisioning,
4032 kSecPolicyNameFDRProvisioning, options), errOut);
4033 errOut:
4034 CFReleaseNull(options);
4035 return result;
4036 }
4037
4038 /* subject:/CN=Component Root CA/O=Apple Inc./ST=California */
4039 /* SKID: 90:D1:56:A9:3E:B4:EE:8C:D0:10:4B:9F:17:1C:5B:55:F2:12:F6:4C */
4040 /* Not Before: Dec 19 19:31:54 2018 GMT, Not After : Dec 16 00:00:00 2043 GMT */
4041 /* Signature Algorithm: ecdsa-with-SHA384 */
4042 const uint8_t ComponentRootCA_SHA256[kSecPolicySHA256Size] = {
4043 0x2f, 0x71, 0x9d, 0xbf, 0x3c, 0xcd, 0xe7, 0xc2, 0xb2, 0x59, 0x3f, 0x32, 0x1f, 0x90, 0xf3, 0x42,
4044 0x42, 0xaa, 0x84, 0xa1, 0xb2, 0x0d, 0xca, 0xcc, 0x10, 0xc0, 0x5b, 0x26, 0xd6, 0x23, 0xb8, 0x47,
4045 };
4046 SecPolicyRef SecPolicyCreateAppleComponentCertificate(CFDataRef testRootHash) {
4047 CFMutableDictionaryRef options = NULL;
4048 SecPolicyRef result = NULL;
4049
4050 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
4051 &kCFTypeDictionaryKeyCallBacks,
4052 &kCFTypeDictionaryValueCallBacks), errOut);
4053
4054 /* Component certificates don't expire */
4055 SecPolicyAddBasicCertOptions(options);
4056
4057 /* Anchored to one of the Component roots. Allow alternative root for developers */
4058 SecPolicyAddAnchorSHA256Options(options, ComponentRootCA_SHA256);
4059 if (testRootHash && SecIsInternalRelease() && (kSecPolicySHA256Size == CFDataGetLength(testRootHash))) {
4060 add_element(options, kSecPolicyCheckAnchorSHA256, testRootHash);
4061 }
4062
4063 /* Exactly 3 certs in the chain */
4064 require(SecPolicyAddChainLengthOptions(options, 3), errOut);
4065
4066 /* Leaf and intermediate must contain Component Type OID */
4067 add_element(options, kSecPolicyCheckLeafMarkerOidWithoutValueCheck, CFSTR("1.2.840.113635.100.11.1"));
4068 add_element(options, kSecPolicyCheckIntermediateMarkerOidWithoutValueCheck, CFSTR("1.2.840.113635.100.11.1"));
4069
4070 require(result = SecPolicyCreate(kSecPolicyAppleComponentCertificate,
4071 kSecPolicyNameComponentCertificate, options), errOut);
4072 errOut:
4073 CFReleaseNull(options);
4074 return result;
4075 }
4076
4077 SecPolicyRef SecPolicyCreateAppleKeyTransparency(CFStringRef applicationId) {
4078 CFMutableDictionaryRef options = NULL;
4079 SecPolicyRef result = NULL;
4080
4081 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
4082 &kCFTypeDictionaryKeyCallBacks,
4083 &kCFTypeDictionaryValueCallBacks), errOut);
4084
4085 /* KT signing certs don't expire */
4086 SecPolicyAddBasicCertOptions(options);
4087
4088 /* Apple Anchor */
4089 require_quiet(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameKeyTransparency), errOut);
4090
4091 /* Exactly 3 certs in the chain */
4092 require(SecPolicyAddChainLengthOptions(options, 3), errOut);
4093
4094 /* Intermediate marker OID matches AAI CA 5 */
4095 add_element(options, kSecPolicyCheckIntermediateMarkerOid, CFSTR("1.2.840.113635.100.6.2.3"));
4096
4097 /* Leaf marker extension matches input applicationId */
4098 add_leaf_marker_value_string(options, CFSTR("1.2.840.113635.100.12.4"), applicationId);
4099
4100 /* Check revocation using any available method */
4101 add_element(options, kSecPolicyCheckRevocation, kSecPolicyCheckRevocationAny);
4102
4103 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
4104 require(SecPolicyAddStrongKeySizeOptions(options), errOut);
4105
4106 /* Check for weak hashes */
4107 require(SecPolicyRemoveWeakHashOptions(options), errOut);
4108
4109 /* Future CT requirement */
4110
4111 require(result = SecPolicyCreate(kSecPolicyAppleKeyTransparency,
4112 kSecPolicyNameKeyTransparency, options), errOut);
4113 errOut:
4114 CFReleaseNull(options);
4115 return result;
4116 }