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