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