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