2 * Copyright (c) 2007-2017 Apple Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
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
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.
21 * @APPLE_LICENSE_HEADER_END@
25 * SecPolicy.c - Implementation of various X.509 certificate trust policies
28 #include <Security/SecPolicyInternal.h>
29 #include <Security/SecPolicyPriv.h>
30 #include <AssertMacros.h>
32 #include <utilities/debugging.h>
33 #include <Security/SecInternal.h>
34 #include <CoreFoundation/CFDictionary.h>
35 #include <CoreFoundation/CFNumber.h>
36 #include <CoreFoundation/CFRuntime.h>
37 #include <CoreFoundation/CFString.h>
38 #include <CoreFoundation/CFTimeZone.h>
39 #include <Security/SecCertificateInternal.h>
40 #include <Security/SecCertificatePriv.h>
41 #include <Security/SecItem.h>
42 #include <libDER/oids.h>
43 #include <utilities/SecCFError.h>
44 #include <utilities/SecCFWrappers.h>
45 #include <utilities/array_size.h>
46 #include <ipc/securityd_client.h>
47 #include <os/variant_private.h>
48 #include <MobileGestalt.h>
50 #include <utilities/SecInternalReleasePriv.h>
52 #include <Security/SecBase64.h>
54 #undef POLICYCHECKMACRO
55 #define POLICYCHECKMACRO(NAME, TRUSTRESULT, SUBTYPE, LEAFCHECK, PATHCHECK, LEAFONLY, CSSMERR, OSSTATUS) \
56 const CFStringRef kSecPolicyCheck##NAME = CFSTR(#NAME);
57 #include "SecPolicyChecks.list"
59 #define SEC_CONST_DECL(k,v) const CFStringRef k = CFSTR(v);
61 /********************************************************
62 ******************* Feature toggles ********************
63 ********************************************************/
64 /* Option for AnchorApple */
65 SEC_CONST_DECL (kSecPolicyAppleAnchorIncludeTestRoots
, "AnchorAppleTestRoots");
67 /* options for kSecPolicyCheckLeafMarkersProdAndQA */
68 SEC_CONST_DECL (kSecPolicyLeafMarkerProd
, "ProdMarker");
69 SEC_CONST_DECL (kSecPolicyLeafMarkerQA
, "QAMarker");
71 /* Revocation toggles */
72 SEC_CONST_DECL (kSecPolicyCheckRevocationOCSP
, "OCSP");
73 SEC_CONST_DECL (kSecPolicyCheckRevocationCRL
, "CRL");
74 SEC_CONST_DECL (kSecPolicyCheckRevocationAny
, "AnyRevocationMethod");
76 /* Public policy oids. */
77 #define POLICYMACRO(NAME, OID, ISPUBLIC, INTNAME, IN_NAME, IN_PROPERTIES, FUNCTION) \
78 const CFStringRef kSecPolicyApple##NAME = CFSTR("1.2.840.113635.100.1."#OID);
79 #include "SecPolicy.list"
80 //Some naming exceptions
81 SEC_CONST_DECL(kSecPolicyMacAppStoreReceipt
, "1.2.840.113635.100.1.19")
83 SEC_CONST_DECL (kSecPolicyOid
, "SecPolicyOid");
84 SEC_CONST_DECL (kSecPolicyName
, "SecPolicyName");
85 SEC_CONST_DECL (kSecPolicyClient
, "SecPolicyClient");
86 SEC_CONST_DECL (kSecPolicyRevocationFlags
, "SecPolicyRevocationFlags");
87 SEC_CONST_DECL (kSecPolicyTeamIdentifier
, "SecPolicyTeamIdentifier");
88 SEC_CONST_DECL (kSecPolicyContext
, "SecPolicyContext");
89 SEC_CONST_DECL (kSecPolicyPolicyName
, "SecPolicyPolicyName");
90 SEC_CONST_DECL (kSecPolicyIntermediateMarkerOid
, "SecPolicyIntermediateMarkerOid");
91 SEC_CONST_DECL (kSecPolicyLeafMarkerOid
, "SecPolicyLeafMarkerOid");
92 SEC_CONST_DECL (kSecPolicyRootDigest
, "SecPolicyRootDigest");
94 SEC_CONST_DECL (kSecPolicyKU_DigitalSignature
, "CE_KU_DigitalSignature");
95 SEC_CONST_DECL (kSecPolicyKU_NonRepudiation
, "CE_KU_NonRepudiation");
96 SEC_CONST_DECL (kSecPolicyKU_KeyEncipherment
, "CE_KU_KeyEncipherment");
97 SEC_CONST_DECL (kSecPolicyKU_DataEncipherment
, "CE_KU_DataEncipherment");
98 SEC_CONST_DECL (kSecPolicyKU_KeyAgreement
, "CE_KU_KeyAgreement");
99 SEC_CONST_DECL (kSecPolicyKU_KeyCertSign
, "CE_KU_KeyCertSign");
100 SEC_CONST_DECL (kSecPolicyKU_CRLSign
, "CE_KU_CRLSign");
101 SEC_CONST_DECL (kSecPolicyKU_EncipherOnly
, "CE_KU_EncipherOnly");
102 SEC_CONST_DECL (kSecPolicyKU_DecipherOnly
, "CE_KU_DecipherOnly");
104 /* Internal policy names */
106 #define __P_DO_DECLARE_(NAME, INTNAME) static CFStringRef kSecPolicyName##NAME = CFSTR(#INTNAME);
107 #define __P_DO_DECLARE_E(NAME, INTNAME) static CFStringRef kSecPolicyName##NAME = CFSTR(#INTNAME);
108 #define __P_DO_DECLARE_P(NAME, INTNAME) const CFStringRef kSecPolicyNameApple##NAME = CFSTR(#INTNAME);
109 #define __P_DO_DECLARE_I(NAME, INTNAME) const CFStringRef kSecPolicyName##NAME = CFSTR(#INTNAME);
110 #define POLICYMACRO(NAME, OID, ISPUBLIC, INTNAME, IN_NAME, IN_PROPERTIES, FUNCTION) \
111 __P_DO_DECLARE_##ISPUBLIC(NAME, INTNAME)
112 #include "SecPolicy.list"
113 //Some naming exceptions
114 static CFStringRef kSecPolicyNameAppleIDSBag
= CFSTR("IDSBag");
116 /* External Policy Names
117 * These correspond to the names defined in CertificatePinning.plist
118 * in security_certificates */
119 SEC_CONST_DECL (kSecPolicyNameSSLServer
, "sslServer");
120 SEC_CONST_DECL (kSecPolicyNameSSLClient
, "sslClient");
121 SEC_CONST_DECL (kSecPolicyNameEAPServer
, "eapServer");
122 SEC_CONST_DECL (kSecPolicyNameEAPClient
, "eapClient");
123 SEC_CONST_DECL (kSecPolicyNameIPSecServer
, "ipsecServer");
124 SEC_CONST_DECL (kSecPolicyNameIPSecClient
, "ipsecClient");
125 SEC_CONST_DECL (kSecPolicyNameAppleiCloudSetupService
, "iCloudSetup");
126 SEC_CONST_DECL (kSecPolicyNameAppleMMCSService
, "MMCS");
127 SEC_CONST_DECL (kSecPolicyNameAppleAST2Service
, "AST2");
128 SEC_CONST_DECL (kSecPolicyNameAppleEscrowProxyService
, "Escrow");
129 SEC_CONST_DECL (kSecPolicyNameAppleFMiPService
, "FMiP");
130 SEC_CONST_DECL (kSecPolicyNameAppleHomeKitService
, "HomeKit");
131 SEC_CONST_DECL (kSecPolicyNameAppleAIDCService
, "AIDC");
132 SEC_CONST_DECL (kSecPolicyNameAppleMapsService
, "Maps");
133 SEC_CONST_DECL (kSecPolicyNameAppleHealthProviderService
, "HealthProvider");
134 SEC_CONST_DECL (kSecPolicyNameAppleParsecService
, "Parsec");
135 SEC_CONST_DECL (kSecPolicyNameAppleAMPService
, "AMP");
136 SEC_CONST_DECL (kSecPolicyNameAppleSiriService
, "Siri");
137 SEC_CONST_DECL (kSecPolicyNameAppleHomeAppClipUploadService
, "HomeAppClipUploadService");
138 SEC_CONST_DECL (kSecPolicyNameAppleUpdatesService
, "Updates");
139 SEC_CONST_DECL (kSecPolicyNameApplePushCertPortal
, "PushCertPortal");
141 #define kSecPolicySHA256Size CC_SHA256_DIGEST_LENGTH
145 /********************************************************
146 ****************** SecPolicy object ********************
147 ********************************************************/
149 static void SecPolicyDestroy(CFTypeRef cf
) {
150 SecPolicyRef policy
= (SecPolicyRef
) cf
;
151 CFRelease(policy
->_oid
);
152 CFReleaseSafe(policy
->_name
);
153 CFRelease(policy
->_options
);
156 static Boolean
SecPolicyCompare(CFTypeRef cf1
, CFTypeRef cf2
) {
157 SecPolicyRef policy1
= (SecPolicyRef
) cf1
;
158 SecPolicyRef policy2
= (SecPolicyRef
) cf2
;
159 if (policy1
->_name
&& policy2
->_name
) {
160 return CFEqual(policy1
->_oid
, policy2
->_oid
) &&
161 CFEqual(policy1
->_name
, policy2
->_name
) &&
162 CFEqual(policy1
->_options
, policy2
->_options
);
164 return CFEqual(policy1
->_oid
, policy2
->_oid
) &&
165 CFEqual(policy1
->_options
, policy2
->_options
);
169 static CFHashCode
SecPolicyHash(CFTypeRef cf
) {
170 SecPolicyRef policy
= (SecPolicyRef
) cf
;
172 return CFHash(policy
->_oid
) + CFHash(policy
->_name
) + CFHash(policy
->_options
);
174 return CFHash(policy
->_oid
) + CFHash(policy
->_options
);
178 static CFStringRef
SecPolicyCopyFormatDescription(CFTypeRef cf
, CFDictionaryRef formatOptions
) {
179 SecPolicyRef policy
= (SecPolicyRef
) cf
;
180 CFMutableStringRef desc
= CFStringCreateMutable(kCFAllocatorDefault
, 0);
181 CFStringRef typeStr
= CFCopyTypeIDDescription(CFGetTypeID(cf
));
182 CFStringAppendFormat(desc
, NULL
,
183 CFSTR("<%@: oid: %@ name: %@ options %@"), typeStr
,
184 policy
->_oid
, (policy
->_name
) ? policy
->_name
: CFSTR(""),
187 CFStringAppend(desc
, CFSTR(" >"));
192 /* SecPolicy API functions. */
193 CFGiblisWithHashFor(SecPolicy
);
195 /* AUDIT[securityd](done):
196 oid (ok) is a caller provided string, only its cf type has been checked.
197 options is a caller provided dictionary, only its cf type has been checked.
199 SecPolicyRef
SecPolicyCreate(CFStringRef oid
, CFStringRef name
, CFDictionaryRef options
) {
200 SecPolicyRef result
= NULL
;
202 require(oid
, errOut
);
203 require(options
, errOut
);
205 (SecPolicyRef
)_CFRuntimeCreateInstance(kCFAllocatorDefault
,
206 SecPolicyGetTypeID(),
207 sizeof(struct __SecPolicy
) - sizeof(CFRuntimeBase
), 0), errOut
);
212 result
->_name
= name
;
214 result
->_options
= options
;
221 static void set_ku_from_properties(SecPolicyRef policy
, CFDictionaryRef properties
);
224 SecPolicyRef
SecPolicyCreateWithProperties(CFTypeRef policyIdentifier
,
225 CFDictionaryRef properties
) {
226 // Creates a policy reference for a given policy object identifier.
227 // If policy-specific parameters can be supplied (e.g. hostname),
228 // attempt to obtain from input properties dictionary.
229 // Returns NULL if the given identifier is unsupported.
231 SecPolicyRef policy
= NULL
;
232 CFTypeRef name
= NULL
;
233 CFStringRef teamID
= NULL
;
234 Boolean client
= false;
235 CFDictionaryRef context
= NULL
;
236 CFStringRef policyName
= NULL
, intermediateMarkerOid
= NULL
, leafMarkerOid
= NULL
;
237 CFDataRef rootDigest
= NULL
;
238 require(policyIdentifier
&& (CFStringGetTypeID() == CFGetTypeID(policyIdentifier
)), errOut
);
241 name
= CFDictionaryGetValue(properties
, kSecPolicyName
);
242 teamID
= CFDictionaryGetValue(properties
, kSecPolicyTeamIdentifier
);
244 CFBooleanRef dictionaryClientValue
;
245 client
= (CFDictionaryGetValueIfPresent(properties
, kSecPolicyClient
, (const void **)&dictionaryClientValue
) &&
246 (dictionaryClientValue
!= NULL
) && CFEqual(kCFBooleanTrue
, dictionaryClientValue
));
247 context
= CFDictionaryGetValue(properties
, kSecPolicyContext
);
248 policyName
= CFDictionaryGetValue(properties
, kSecPolicyPolicyName
);
249 intermediateMarkerOid
= CFDictionaryGetValue(properties
, kSecPolicyIntermediateMarkerOid
);
250 leafMarkerOid
= CFDictionaryGetValue(properties
, kSecPolicyLeafMarkerOid
);
251 rootDigest
= CFDictionaryGetValue(properties
, kSecPolicyRootDigest
);
254 /* only the EAP policy allows a non-string name */
255 if (name
&& !isString(name
) && !CFEqual(policyIdentifier
, kSecPolicyAppleEAP
)) {
256 secerror("policy \"%@\" requires a string value for the %@ key", policyIdentifier
, kSecPolicyName
);
260 /* What follows are all the exceptional functions that do not match the macro below */
261 if (CFEqual(policyIdentifier
, kSecPolicyAppleSSL
)) {
262 policy
= SecPolicyCreateSSL(!client
, name
);
263 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleSMIME
)) {
264 policy
= SecPolicyCreateSMIME(kSecSignSMIMEUsage
| kSecAnyEncryptSMIME
, name
);
265 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleEAP
)) {
266 CFArrayRef array
= NULL
;
267 if (isString(name
)) {
268 array
= CFArrayCreate(kCFAllocatorDefault
, (const void **)&name
, 1, &kCFTypeArrayCallBacks
);
269 } else if (isArray(name
)) {
270 array
= CFArrayCreateCopy(NULL
, name
);
272 policy
= SecPolicyCreateEAP(!client
, array
);
273 CFReleaseSafe(array
);
274 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleIPsec
)) {
275 policy
= SecPolicyCreateIPSec(!client
, name
);
276 } else if (CFEqual(policyIdentifier
, kSecPolicyMacAppStoreReceipt
)) {
277 policy
= SecPolicyCreateMacAppStoreReceipt();
278 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleRevocation
)) {
279 policy
= SecPolicyCreateRevocation(kSecRevocationUseAnyAvailableMethod
);
280 } else if (CFEqual(policyIdentifier
, kSecPolicyApplePassbookSigning
)) {
281 policy
= SecPolicyCreatePassbookCardSigner(name
, teamID
);
282 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleAST2DiagnosticsServerAuth
)) {
284 policy
= SecPolicyCreateAppleAST2Service(name
, context
);
286 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier
);
288 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleEscrowProxyServerAuth
)) {
290 policy
= SecPolicyCreateAppleEscrowProxyService(name
, context
);
292 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier
);
294 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleFMiPServerAuth
)) {
296 policy
= SecPolicyCreateAppleFMiPService(name
, context
);
298 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier
);
300 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleMMCService
)) {
302 policy
= SecPolicyCreateAppleMMCSService(name
, context
);
304 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier
);
306 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleGSService
)) {
308 policy
= SecPolicyCreateAppleGSService(name
, context
);
310 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier
);
312 } else if (CFEqual(policyIdentifier
, kSecPolicyApplePPQService
)) {
314 policy
= SecPolicyCreateApplePPQService(name
, context
);
316 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier
);
318 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleGenericApplePinned
)) {
320 policy
= SecPolicyCreateApplePinned(policyName
, intermediateMarkerOid
, leafMarkerOid
);
322 secerror("policy \"%@\" requires kSecPolicyPolicyName input", policyIdentifier
);
324 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleGenericAppleSSLPinned
)) {
326 policy
= SecPolicyCreateAppleSSLPinned(policyName
, name
, intermediateMarkerOid
, leafMarkerOid
);
328 secerror("policy \"%@\" requires kSecPolicyPolicyName input", policyIdentifier
);
330 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleIDSServiceContext
)) {
332 policy
= SecPolicyCreateAppleIDSServiceContext(name
, context
);
334 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier
);
336 } else if (CFEqual(policyIdentifier
, kSecPolicyApplePushService
)) {
338 policy
= SecPolicyCreateApplePushService(name
, context
);
340 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier
);
342 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleUniqueDeviceIdentifierCertificate
)) {
343 policy
= SecPolicyCreateAppleUniqueDeviceCertificate(rootDigest
);
344 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleiCloudSetupServerAuth
)) {
346 policy
= SecPolicyCreateAppleiCloudSetupService(name
, context
);
348 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier
);
350 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleBasicAttestationSystem
)) {
351 policy
= SecPolicyCreateAppleBasicAttestationSystem(rootDigest
);
352 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleBasicAttestationUser
)) {
353 policy
= SecPolicyCreateAppleBasicAttestationUser(rootDigest
);
354 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleComponentCertificate
)) {
355 policy
= SecPolicyCreateAppleComponentCertificate(rootDigest
);
356 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleAggregateMetricTransparency
)) {
357 policy
= SecPolicyCreateAggregateMetricTransparency(!client
);
359 /* For a couple of common patterns we use the macro, but some of the
360 * policies are deprecated (or not yet available), so we need to ignore the warning. */
361 #pragma clang diagnostic push
362 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
363 #pragma clang diagnostic ignored "-Wunguarded-availability"
365 #define _P_OPTION_N name
366 #define _P_PROPERTIES_(NAME, IN_NAME, FUNCTION)
367 #define _P_PROPERTIES_Y(NAME, IN_NAME, FUNCTION) else if (CFEqual(policyIdentifier, kSecPolicyApple##NAME)) { \
368 policy = SecPolicyCreate##FUNCTION(_P_OPTION_##IN_NAME); \
371 #define POLICYMACRO(NAME, OID, ISPUBLIC, INTNAME, IN_NAME, IN_PROPERTIES, FUNCTION) \
372 _P_PROPERTIES_##IN_PROPERTIES(NAME, IN_NAME, FUNCTION)
373 #include "SecPolicy.list"
375 secerror("ERROR: policy \"%@\" is unsupported", policyIdentifier
);
377 #pragma clang diagnostic pop // ignored "-Wdeprecated-declarations"
384 set_ku_from_properties(policy
, properties
);
388 SecPolicySetName(policy
, policyName
);
395 CFDictionaryRef
SecPolicyCopyProperties(SecPolicyRef policyRef
) {
396 // Builds and returns a dictionary which the caller must release.
398 #pragma clang diagnostic push
399 #pragma clang diagnostic ignored "-Wnonnull"
400 // After introducing nullability annotations, policyRef is supposed to be nonnull, suppress the warning
401 if (!policyRef
) return NULL
;
402 #pragma clang diagnostic pop
403 CFMutableDictionaryRef properties
= CFDictionaryCreateMutable(NULL
, 0,
404 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
405 #pragma clang diagnostic push
406 #pragma clang diagnostic ignored "-Wnonnull"
407 // 'properties' is nonnull in reality suppress the warning
408 if (!properties
) return NULL
;
409 #pragma clang diagnostic pop
410 CFStringRef oid
= (CFStringRef
) CFRetain(policyRef
->_oid
);
411 CFTypeRef nameKey
= NULL
;
413 // Determine name key
414 if (policyRef
->_options
) {
415 if (CFDictionaryContainsKey(policyRef
->_options
, kSecPolicyCheckSSLHostname
)) {
416 nameKey
= kSecPolicyCheckSSLHostname
;
417 } else if (CFDictionaryContainsKey(policyRef
->_options
, kSecPolicyCheckEAPTrustedServerNames
)) {
418 nameKey
= kSecPolicyCheckEAPTrustedServerNames
;
419 } else if (CFDictionaryContainsKey(policyRef
->_options
, kSecPolicyCheckEmail
)) {
420 nameKey
= kSecPolicyCheckEmail
;
425 CFDictionarySetValue(properties
, (const void *)kSecPolicyOid
,
428 // Set kSecPolicyName if we have one
429 if (nameKey
&& policyRef
->_options
) {
430 CFTypeRef name
= (CFTypeRef
) CFDictionaryGetValue(policyRef
->_options
,
433 CFDictionarySetValue(properties
, (const void *)kSecPolicyName
,
438 // Set kSecPolicyClient
439 CFStringRef policyName
= (CFStringRef
) CFRetainSafe(policyRef
->_name
);
440 if (policyName
&& (CFEqual(policyName
, kSecPolicyNameSSLClient
) ||
441 CFEqual(policyName
, kSecPolicyNameIPSecClient
) ||
442 CFEqual(policyName
, kSecPolicyNameEAPClient
))) {
443 CFDictionarySetValue(properties
, (const void *)kSecPolicyClient
,
444 (const void *)kCFBooleanTrue
);
451 static void SecPolicySetOid(SecPolicyRef policy
, CFStringRef oid
) {
452 if (!policy
|| !oid
) return;
453 CFStringRef temp
= policy
->_oid
;
459 void SecPolicySetName(SecPolicyRef policy
, CFStringRef policyName
) {
460 if (!policy
|| !policyName
) return;
461 CFStringRef temp
= policy
->_name
;
462 CFRetain(policyName
);
463 policy
->_name
= policyName
;
467 CFStringRef
SecPolicyGetOidString(SecPolicyRef policy
) {
471 CFStringRef
SecPolicyGetName(SecPolicyRef policy
) {
472 return policy
->_name
;
475 CFDictionaryRef
SecPolicyGetOptions(SecPolicyRef policy
) {
476 return policy
->_options
;
479 void SecPolicySetOptionsValue(SecPolicyRef policy
, CFStringRef key
, CFTypeRef value
) {
480 if (!policy
|| !key
) return;
481 CFMutableDictionaryRef options
= (CFMutableDictionaryRef
) policy
->_options
;
483 options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
484 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
485 if (!options
) return;
486 policy
->_options
= options
;
488 CFDictionarySetValue(options
, key
, value
);
491 /* Local forward declaration */
492 static void set_ssl_ekus(CFMutableDictionaryRef options
, bool server
);
495 // this is declared as NA for iPhone in SecPolicy.h, so declare here
496 OSStatus
SecPolicySetProperties(SecPolicyRef policyRef
, CFDictionaryRef properties
);
499 OSStatus
SecPolicySetProperties(SecPolicyRef policyRef
, CFDictionaryRef properties
) {
500 // Set policy options based on the provided dictionary keys.
502 if (!(policyRef
&& properties
&& (CFDictionaryGetTypeID() == CFGetTypeID(properties
)))) {
505 CFStringRef oid
= (CFStringRef
) CFRetain(policyRef
->_oid
);
506 OSStatus result
= errSecSuccess
;
509 CFTypeRef name
= NULL
;
510 if (CFDictionaryGetValueIfPresent(properties
, (const void *)kSecPolicyName
,
511 (const void **)&name
) && name
) {
512 CFTypeID typeID
= CFGetTypeID(name
);
513 if (CFEqual(oid
, kSecPolicyAppleSSL
) ||
514 CFEqual(oid
, kSecPolicyAppleIPsec
)) {
515 if (CFStringGetTypeID() == typeID
) {
516 SecPolicySetOptionsValue(policyRef
, kSecPolicyCheckSSLHostname
, name
);
518 else result
= errSecParam
;
520 else if (CFEqual(oid
, kSecPolicyAppleEAP
)) {
521 if ((CFStringGetTypeID() == typeID
) ||
522 (CFArrayGetTypeID() == typeID
)) {
523 SecPolicySetOptionsValue(policyRef
, kSecPolicyCheckEAPTrustedServerNames
, name
);
525 else result
= errSecParam
;
527 else if (CFEqual(oid
, kSecPolicyAppleSMIME
)) {
528 if (CFStringGetTypeID() == typeID
) {
529 SecPolicySetOptionsValue(policyRef
, kSecPolicyCheckEmail
, name
);
531 else result
= errSecParam
;
536 CFTypeRef client
= NULL
;
537 if (CFDictionaryGetValueIfPresent(properties
, (const void *)kSecPolicyClient
,
538 (const void **)&client
) && client
) {
539 if (!(CFBooleanGetTypeID() == CFGetTypeID(client
))) {
540 result
= errSecParam
;
542 else if (CFEqual(client
, kCFBooleanTrue
)) {
543 if (CFEqual(oid
, kSecPolicyAppleSSL
)) {
544 SecPolicySetName(policyRef
, kSecPolicyNameSSLClient
);
545 /* Set EKU checks for clients */
546 CFMutableDictionaryRef newOptions
= CFDictionaryCreateMutableCopy(NULL
, 0, policyRef
->_options
);
547 set_ssl_ekus(newOptions
, false);
548 CFReleaseSafe(policyRef
->_options
);
549 policyRef
->_options
= newOptions
;
551 else if (CFEqual(oid
, kSecPolicyAppleIPsec
)) {
552 SecPolicySetName(policyRef
, kSecPolicyNameIPSecClient
);
554 else if (CFEqual(oid
, kSecPolicyNameEAPServer
)) {
555 SecPolicySetName(policyRef
, kSecPolicyNameEAPClient
);
556 /* Set EKU checks for clients */
557 CFMutableDictionaryRef newOptions
= CFDictionaryCreateMutableCopy(NULL
, 0, policyRef
->_options
);
558 set_ssl_ekus(newOptions
, false);
559 CFReleaseSafe(policyRef
->_options
);
560 policyRef
->_options
= newOptions
;
564 if (CFEqual(oid
, kSecPolicyAppleSSL
)) {
565 SecPolicySetName(policyRef
, kSecPolicyNameSSLServer
);
566 /* Set EKU checks for servers */
567 CFMutableDictionaryRef newOptions
= CFDictionaryCreateMutableCopy(NULL
, 0, policyRef
->_options
);
568 set_ssl_ekus(newOptions
, true);
569 CFReleaseSafe(policyRef
->_options
);
570 policyRef
->_options
= newOptions
;
572 else if (CFEqual(oid
, kSecPolicyAppleIPsec
)) {
573 SecPolicySetName(policyRef
, kSecPolicyNameIPSecServer
);
575 else if (CFEqual(oid
, kSecPolicyAppleEAP
)) {
576 SecPolicySetName(policyRef
, kSecPolicyNameEAPServer
);
577 /* Set EKU checks for servers */
578 CFMutableDictionaryRef newOptions
= CFDictionaryCreateMutableCopy(NULL
, 0, policyRef
->_options
);
579 set_ssl_ekus(newOptions
, true);
580 CFReleaseSafe(policyRef
->_options
);
581 policyRef
->_options
= newOptions
;
587 set_ku_from_properties(policyRef
, properties
);
593 static xpc_object_t
copy_xpc_policy_object(SecPolicyRef policy
);
594 static bool append_policy_to_xpc_array(SecPolicyRef policy
, xpc_object_t xpc_policies
);
595 extern xpc_object_t
copy_xpc_policies_array(CFArrayRef policies
);
596 extern OSStatus
validate_array_of_items(CFArrayRef array
, CFStringRef arrayItemType
, CFTypeID itemTypeID
, bool required
);
598 static xpc_object_t
copy_xpc_policy_object(SecPolicyRef policy
) {
599 xpc_object_t xpc_policy
= NULL
;
600 xpc_object_t data
[2] = { NULL
, NULL
};
601 if (policy
->_oid
&& (CFGetTypeID(policy
->_oid
) == CFStringGetTypeID()) &&
602 policy
->_name
&& (CFGetTypeID(policy
->_name
) == CFStringGetTypeID())) {
603 /* These should really be different elements of the xpc array. But
604 * SecPolicyCreateWithXPCObject previously checked the size via ==, which prevents
605 * us from appending new information while maintaining backward compatibility.
606 * Doing this makes the builders happy. */
607 CFMutableStringRef oidAndName
= NULL
;
608 oidAndName
= CFStringCreateMutableCopy(NULL
, 0, policy
->_oid
);
610 CFStringAppend(oidAndName
, CFSTR("++"));
611 CFStringAppend(oidAndName
, policy
->_name
);
612 data
[0] = _CFXPCCreateXPCObjectFromCFObject(oidAndName
);
613 CFReleaseNull(oidAndName
);
615 data
[0] = _CFXPCCreateXPCObjectFromCFObject(policy
->_oid
);
617 } else if (policy
->_oid
&& (CFGetTypeID(policy
->_oid
) == CFStringGetTypeID())) {
618 data
[0] = _CFXPCCreateXPCObjectFromCFObject(policy
->_oid
);
620 secerror("policy 0x%lX has no _oid", (uintptr_t)policy
);
622 if (policy
->_options
&& (CFGetTypeID(policy
->_options
) == CFDictionaryGetTypeID())) {
623 data
[1] = _CFXPCCreateXPCObjectFromCFObject(policy
->_options
);
625 secerror("policy 0x%lX has no _options", (uintptr_t)policy
);
627 xpc_policy
= xpc_array_create(data
, array_size(data
));
628 if (data
[0]) xpc_release(data
[0]);
629 if (data
[1]) xpc_release(data
[1]);
633 static bool append_policy_to_xpc_array(SecPolicyRef policy
, xpc_object_t xpc_policies
) {
637 xpc_object_t xpc_policy
= copy_xpc_policy_object(policy
);
641 xpc_array_append_value(xpc_policies
, xpc_policy
);
642 xpc_release(xpc_policy
);
646 xpc_object_t
copy_xpc_policies_array(CFArrayRef policies
) {
647 xpc_object_t xpc_policies
= xpc_array_create(NULL
, 0);
651 validate_array_of_items(policies
, CFSTR("policy"), SecPolicyGetTypeID(), true);
652 CFIndex ix
, count
= CFArrayGetCount(policies
);
653 for (ix
= 0; ix
< count
; ++ix
) {
654 SecPolicyRef policy
= (SecPolicyRef
) CFArrayGetValueAtIndex(policies
, ix
);
655 #if SECTRUST_VERBOSE_DEBUG
656 CFDictionaryRef props
= SecPolicyCopyProperties(policy
);
657 secerror("idx=%d of %d; policy=0x%lX properties=%@", (int)ix
, (int)count
, (uintptr_t)policy
, props
);
658 CFReleaseSafe(props
);
660 if (!append_policy_to_xpc_array(policy
, xpc_policies
)) {
661 xpc_release(xpc_policies
);
669 static xpc_object_t
SecPolicyCopyXPCObject(SecPolicyRef policy
, CFErrorRef
*error
) {
670 xpc_object_t xpc_policy
= NULL
;
671 xpc_object_t data
[2] = {};
672 CFMutableStringRef oidAndName
= NULL
;
673 oidAndName
= CFStringCreateMutableCopy(NULL
, 0, policy
->_oid
);
676 CFStringAppend(oidAndName
, CFSTR("++"));
677 CFStringAppend(oidAndName
, policy
->_name
);
680 require_action_quiet(data
[0] = _CFXPCCreateXPCObjectFromCFObject(oidAndName
), exit
,
681 SecError(errSecParam
, error
,
682 CFSTR("failed to create xpc_object from policy oid and name")));
684 require_action_quiet(data
[0] = _CFXPCCreateXPCObjectFromCFObject(policy
->_oid
), exit
,
685 SecError(errSecParam
, error
, CFSTR("failed to create xpc_object from policy oid")));
687 require_action_quiet(data
[1] = _CFXPCCreateXPCObjectFromCFObject(policy
->_options
), exit
,
688 SecError(errSecParam
, error
, CFSTR("failed to create xpc_object from policy options")));
689 require_action_quiet(xpc_policy
= xpc_array_create(data
, array_size(data
)), exit
,
690 SecError(errSecAllocate
, error
, CFSTR("failed to create xpc_array for policy")));
693 if (data
[0]) xpc_release(data
[0]);
694 if (data
[1]) xpc_release(data
[1]);
695 CFReleaseNull(oidAndName
);
699 static bool SecPolicyAppendToXPCArray(SecPolicyRef policy
, xpc_object_t policies
, CFErrorRef
*error
) {
703 xpc_object_t xpc_policy
= SecPolicyCopyXPCObject(policy
, error
);
707 xpc_array_append_value(policies
, xpc_policy
);
708 xpc_release(xpc_policy
);
712 xpc_object_t
SecPolicyArrayCopyXPCArray(CFArrayRef policies
, CFErrorRef
*error
) {
713 xpc_object_t xpc_policies
;
714 require_action_quiet(xpc_policies
= xpc_array_create(NULL
, 0), exit
,
715 SecError(errSecAllocate
, error
, CFSTR("failed to create xpc_array")));
716 CFIndex ix
, count
= CFArrayGetCount(policies
);
717 for (ix
= 0; ix
< count
; ++ix
) {
718 if (!SecPolicyAppendToXPCArray((SecPolicyRef
)CFArrayGetValueAtIndex(policies
, ix
), xpc_policies
, error
)) {
719 xpc_release(xpc_policies
);
727 static OSStatus
parseOidAndName(CFStringRef oidAndName
, CFStringRef
*oid
, CFStringRef
*name
) {
728 OSStatus result
= errSecSuccess
;
729 CFStringRef partial
= NULL
;
731 CFRange delimiter
= CFStringFind(oidAndName
, CFSTR("++"), 0);
732 if (delimiter
.length
!= 2) {
736 /* get first half: oid */
737 partial
= CFStringCreateWithSubstring(NULL
, oidAndName
, CFRangeMake(0, delimiter
.location
));
738 if (oid
) { *oid
= CFRetainSafe(partial
); }
739 CFReleaseNull(partial
);
741 /* get second half: name */
742 if (delimiter
.location
+ 2 >= CFStringGetLength(oidAndName
)) {
743 return errSecSuccess
; // name is optional
745 CFRange nameRange
= CFRangeMake(delimiter
.location
+2,
746 CFStringGetLength(oidAndName
) - delimiter
.location
- 2);
747 partial
= CFStringCreateWithSubstring(NULL
, oidAndName
, nameRange
);
748 if (name
) { *name
= CFRetainSafe(partial
); }
749 CFReleaseNull(partial
);
753 static SecPolicyRef
SecPolicyCreateWithXPCObject(xpc_object_t xpc_policy
, CFErrorRef
*error
) {
754 SecPolicyRef policy
= NULL
;
755 CFTypeRef oidAndName
= NULL
;
756 CFStringRef oid
= NULL
;
757 CFStringRef name
= NULL
;
758 CFTypeRef options
= NULL
;
760 require_action_quiet(xpc_policy
, exit
, SecError(errSecParam
, error
, CFSTR("policy xpc value is NULL")));
761 require_action_quiet(xpc_get_type(xpc_policy
) == XPC_TYPE_ARRAY
, exit
, SecError(errSecDecode
, error
, CFSTR("policy xpc value is not an array")));
762 require_action_quiet(xpc_array_get_count(xpc_policy
) >= 2, exit
, SecError(errSecDecode
, error
, CFSTR("policy xpc array count < 2")));
763 oidAndName
= _CFXPCCreateCFObjectFromXPCObject(xpc_array_get_value(xpc_policy
, 0));
764 require_action_quiet(isString(oidAndName
), exit
,
765 SecError(errSecParam
, error
, CFSTR("failed to convert xpc policy[0]=%@ to CFString"), oidAndName
));
766 options
= _CFXPCCreateCFObjectFromXPCObject(xpc_array_get_value(xpc_policy
, 1));
767 require_action_quiet(isDictionary(options
), exit
,
768 SecError(errSecParam
, error
, CFSTR("failed to convert xpc policy[1]=%@ to CFDictionary"), options
));
769 require_noerr_action_quiet(parseOidAndName(oidAndName
, &oid
, &name
), exit
,
770 SecError(errSecParam
, error
, CFSTR("failed to convert combined %@ to name and oid"), oidAndName
));
771 require_action_quiet(policy
= SecPolicyCreate(oid
, name
, options
), exit
,
772 SecError(errSecDecode
, error
, CFSTR("Failed to create policy")));
775 CFReleaseSafe(oidAndName
);
778 CFReleaseSafe(options
);
782 CFArrayRef
SecPolicyXPCArrayCopyArray(xpc_object_t xpc_policies
, CFErrorRef
*error
) {
783 CFMutableArrayRef policies
= NULL
;
784 require_action_quiet(xpc_get_type(xpc_policies
) == XPC_TYPE_ARRAY
, exit
,
785 SecError(errSecParam
, error
, CFSTR("policies xpc value is not an array")));
786 size_t count
= xpc_array_get_count(xpc_policies
);
787 require_action_quiet(policies
= CFArrayCreateMutable(kCFAllocatorDefault
, count
, &kCFTypeArrayCallBacks
), exit
,
788 SecError(errSecAllocate
, error
, CFSTR("failed to create CFArray of capacity %zu"), count
));
791 for (ix
= 0; ix
< count
; ++ix
) {
792 SecPolicyRef policy
= SecPolicyCreateWithXPCObject(xpc_array_get_value(xpc_policies
, ix
), error
);
797 CFArraySetValueAtIndex(policies
, ix
, policy
);
806 static SEC_CONST_DECL (kSecPolicyOptions
, "policyOptions");
808 static SecPolicyRef
SecPolicyCreateWithDictionary(CFDictionaryRef dict
) {
809 SecPolicyRef policy
= NULL
;
810 CFStringRef oid
= (CFStringRef
)CFDictionaryGetValue(dict
, kSecPolicyOid
);
811 require_quiet(isString(oid
), errOut
);
812 CFDictionaryRef options
= (CFDictionaryRef
)CFDictionaryGetValue(dict
, kSecPolicyOptions
);
813 require_quiet(isDictionary(options
), errOut
);
814 CFStringRef name
= (CFStringRef
)CFDictionaryGetValue(dict
, kSecPolicyPolicyName
);
815 policy
= SecPolicyCreate(oid
, name
, options
);
820 static void deserializePolicy(const void *value
, void *context
) {
821 CFDictionaryRef policyDict
= (CFDictionaryRef
)value
;
822 if (isDictionary(policyDict
)) {
823 CFTypeRef deserializedPolicy
= SecPolicyCreateWithDictionary(policyDict
);
824 if (deserializedPolicy
) {
825 CFArrayAppendValue((CFMutableArrayRef
)context
, deserializedPolicy
);
826 CFRelease(deserializedPolicy
);
831 CFArrayRef
SecPolicyArrayCreateDeserialized(CFArrayRef serializedPolicies
) {
832 CFMutableArrayRef result
= NULL
;
833 require_quiet(isArray(serializedPolicies
), errOut
);
834 CFIndex count
= CFArrayGetCount(serializedPolicies
);
835 result
= CFArrayCreateMutable(kCFAllocatorDefault
, count
, &kCFTypeArrayCallBacks
);
836 CFRange all_policies
= { 0, count
};
837 CFArrayApplyFunction(serializedPolicies
, all_policies
, deserializePolicy
, result
);
842 static CFDictionaryRef
SecPolicyCreateDictionary(SecPolicyRef policy
) {
843 CFMutableDictionaryRef dict
= NULL
;
844 dict
= CFDictionaryCreateMutable(NULL
, 3, &kCFTypeDictionaryKeyCallBacks
,
845 &kCFTypeDictionaryValueCallBacks
);
846 CFDictionaryAddValue(dict
, kSecPolicyOid
, policy
->_oid
);
847 CFDictionaryAddValue(dict
, kSecPolicyOptions
, policy
->_options
);
849 CFDictionaryAddValue(dict
, kSecPolicyPolicyName
, policy
->_name
);
854 static void serializePolicy(const void *value
, void *context
) {
855 SecPolicyRef policy
= (SecPolicyRef
)value
;
856 if (policy
&& SecPolicyGetTypeID() == CFGetTypeID(policy
)) {
857 CFDictionaryRef serializedPolicy
= SecPolicyCreateDictionary(policy
);
858 if (serializedPolicy
) {
859 CFArrayAppendValue((CFMutableArrayRef
)context
, serializedPolicy
);
860 CFRelease(serializedPolicy
);
865 CFArrayRef
SecPolicyArrayCreateSerialized(CFArrayRef policies
) {
866 CFMutableArrayRef result
= NULL
;
867 require_quiet(isArray(policies
), errOut
);
868 CFIndex count
= CFArrayGetCount(policies
);
869 result
= CFArrayCreateMutable(NULL
, count
, &kCFTypeArrayCallBacks
);
870 CFRange all_policies
= { 0, count
};
871 CFArrayApplyFunction(policies
, all_policies
, serializePolicy
, result
);
876 static void add_element(CFMutableDictionaryRef options
, CFStringRef key
,
878 CFTypeRef old_value
= CFDictionaryGetValue(options
, key
);
880 CFMutableArrayRef array
;
881 if (CFGetTypeID(old_value
) == CFArrayGetTypeID()) {
882 array
= (CFMutableArrayRef
)old_value
;
884 array
= CFArrayCreateMutable(kCFAllocatorDefault
, 0,
885 &kCFTypeArrayCallBacks
);
886 CFArrayAppendValue(array
, old_value
);
887 CFDictionarySetValue(options
, key
, array
);
890 CFArrayAppendValue(array
, value
);
892 CFDictionaryAddValue(options
, key
, value
);
896 static void add_eku(CFMutableDictionaryRef options
, const DERItem
*ekuOid
) {
897 CFDataRef eku
= CFDataCreate(kCFAllocatorDefault
,
898 ekuOid
? ekuOid
->data
: NULL
,
899 ekuOid
? ekuOid
->length
: 0);
901 add_element(options
, kSecPolicyCheckExtendedKeyUsage
, eku
);
906 static void add_eku_string(CFMutableDictionaryRef options
, CFStringRef ekuOid
) {
908 add_element(options
, kSecPolicyCheckExtendedKeyUsage
, ekuOid
);
912 static void set_ssl_ekus(CFMutableDictionaryRef options
, bool server
) {
913 CFDictionaryRemoveValue(options
, kSecPolicyCheckExtendedKeyUsage
);
915 /* If server and EKU ext present then EKU ext should contain one of
916 ServerAuth or ExtendedKeyUsageAny or NetscapeSGC or MicrosoftSGC.
917 else if !server and EKU ext present then EKU ext should contain one of
918 ClientAuth or ExtendedKeyUsageAny. */
920 /* We always allow certificates that specify oidAnyExtendedKeyUsage. */
921 add_eku(options
, NULL
); /* eku extension is optional */
922 add_eku(options
, &oidAnyExtendedKeyUsage
);
924 add_eku(options
, &oidExtendedKeyUsageServerAuth
);
925 add_eku(options
, &oidExtendedKeyUsageMicrosoftSGC
);
926 add_eku(options
, &oidExtendedKeyUsageNetscapeSGC
);
928 add_eku(options
, &oidExtendedKeyUsageClientAuth
);
932 static void add_ku(CFMutableDictionaryRef options
, SecKeyUsage keyUsage
) {
933 SInt32 dku
= keyUsage
;
934 CFNumberRef ku
= CFNumberCreate(kCFAllocatorDefault
, kCFNumberSInt32Type
,
937 add_element(options
, kSecPolicyCheckKeyUsage
, ku
);
943 static void set_ku_from_properties(SecPolicyRef policy
, CFDictionaryRef properties
) {
944 if (!policy
|| !properties
) {
948 CFStringRef keyNames
[] = { kSecPolicyKU_DigitalSignature
, kSecPolicyKU_NonRepudiation
, kSecPolicyKU_KeyEncipherment
, kSecPolicyKU_DataEncipherment
,
949 kSecPolicyKU_KeyAgreement
, kSecPolicyKU_KeyCertSign
, kSecPolicyKU_CRLSign
, kSecPolicyKU_EncipherOnly
, kSecPolicyKU_DecipherOnly
};
951 uint32_t keyUsageValues
[] = { kSecKeyUsageDigitalSignature
, kSecKeyUsageNonRepudiation
, kSecKeyUsageKeyEncipherment
, kSecKeyUsageDataEncipherment
,
952 kSecKeyUsageKeyAgreement
, kSecKeyUsageKeyCertSign
, kSecKeyUsageCRLSign
, kSecKeyUsageEncipherOnly
, kSecKeyUsageDecipherOnly
};
954 bool haveKeyUsage
= false;
955 CFTypeRef keyUsageBoolean
;
956 for (uint32_t i
= 0; i
< sizeof(keyNames
) / sizeof(CFStringRef
); ++i
) {
957 if (CFDictionaryGetValueIfPresent(properties
, keyNames
[i
], (const void**)&keyUsageBoolean
)) {
958 if (CFEqual(keyUsageBoolean
, kCFBooleanTrue
)) {
969 CFMutableDictionaryRef options
= (CFMutableDictionaryRef
) policy
->_options
;
971 options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
972 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
973 if (!options
) return;
974 policy
->_options
= options
;
976 CFDictionaryRemoveValue(options
, kSecPolicyCheckKeyUsage
);
979 for (uint32_t i
= 0; i
< sizeof(keyNames
) / sizeof(CFStringRef
); ++i
) {
980 if (CFDictionaryGetValueIfPresent(properties
, keyNames
[i
], (const void**)&keyUsageBoolean
)) {
981 if (CFEqual(keyUsageBoolean
, kCFBooleanTrue
)) {
982 add_ku(options
, keyUsageValues
[i
]);
989 static void add_oid(CFMutableDictionaryRef options
, CFStringRef policy_key
, const DERItem
*oid
) {
990 CFDataRef oid_data
= CFDataCreate(kCFAllocatorDefault
,
991 oid
? oid
->data
: NULL
,
992 oid
? oid
->length
: 0);
994 add_element(options
, policy_key
, oid_data
);
999 static void add_leaf_marker_value(CFMutableDictionaryRef options
, const DERItem
*markerOid
, CFStringRef string_value
) {
1001 CFTypeRef policyData
= NULL
;
1003 if (NULL
== string_value
) {
1004 policyData
= CFDataCreate(kCFAllocatorDefault
,
1005 markerOid
? markerOid
->data
: NULL
,
1006 markerOid
? markerOid
->length
: 0);
1008 CFStringRef oid_as_string
= SecDERItemCopyOIDDecimalRepresentation(kCFAllocatorDefault
, markerOid
);
1010 const void *key
[1] = { oid_as_string
};
1011 const void *value
[1] = { string_value
};
1012 policyData
= CFDictionaryCreate(kCFAllocatorDefault
,
1014 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
1015 CFReleaseNull(oid_as_string
);
1018 add_element(options
, kSecPolicyCheckLeafMarkerOid
, policyData
);
1020 CFReleaseNull(policyData
);
1024 static void add_leaf_marker(CFMutableDictionaryRef options
, const DERItem
*markerOid
) {
1025 add_leaf_marker_value(options
, markerOid
, NULL
);
1028 static void add_leaf_marker_value_string(CFMutableDictionaryRef options
, CFStringRef markerOid
, CFStringRef string_value
) {
1029 if (NULL
== string_value
) {
1030 add_element(options
, kSecPolicyCheckLeafMarkerOid
, markerOid
);
1032 CFDictionaryRef policyData
= NULL
;
1033 const void *key
[1] = { markerOid
};
1034 const void *value
[1] = { string_value
};
1035 policyData
= CFDictionaryCreate(kCFAllocatorDefault
,
1037 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
1038 add_element(options
, kSecPolicyCheckLeafMarkerOid
, policyData
);
1040 CFReleaseNull(policyData
);
1044 static void add_leaf_marker_string(CFMutableDictionaryRef options
, CFStringRef markerOid
) {
1045 add_leaf_marker_value_string(options
, markerOid
, NULL
);
1048 static void add_leaf_prod_qa_element(CFMutableDictionaryRef options
, CFTypeRef prodValue
, CFTypeRef qaValue
)
1050 CFMutableDictionaryRef prodAndQADictionary
= CFDictionaryCreateMutable(NULL
, 0, &kCFTypeDictionaryKeyCallBacks
,
1051 &kCFTypeDictionaryValueCallBacks
);
1052 CFDictionaryRef old_value
= CFDictionaryGetValue(options
, kSecPolicyCheckLeafMarkersProdAndQA
);
1054 CFMutableArrayRef prodArray
= NULL
, qaArray
= NULL
;
1055 CFTypeRef old_prod_value
= CFDictionaryGetValue(old_value
, kSecPolicyLeafMarkerProd
);
1056 CFTypeRef old_qa_value
= CFDictionaryGetValue(old_value
, kSecPolicyLeafMarkerQA
);
1057 if (isArray(old_prod_value
) && isArray(old_qa_value
)) {
1058 prodArray
= (CFMutableArrayRef
)CFRetainSafe(old_prod_value
);
1059 qaArray
= (CFMutableArrayRef
)CFRetainSafe(old_qa_value
);
1061 prodArray
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
1062 qaArray
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
1063 CFArrayAppendValue(prodArray
, old_prod_value
);
1064 CFArrayAppendValue(qaArray
, old_qa_value
);
1066 CFArrayAppendValue(prodArray
, prodValue
);
1067 CFArrayAppendValue(qaArray
, qaValue
);
1068 CFDictionaryAddValue(prodAndQADictionary
, kSecPolicyLeafMarkerProd
, prodArray
);
1069 CFDictionaryAddValue(prodAndQADictionary
, kSecPolicyLeafMarkerQA
, qaArray
);
1070 CFReleaseNull(prodArray
);
1071 CFReleaseNull(qaArray
);
1074 CFDictionaryAddValue(prodAndQADictionary
, kSecPolicyLeafMarkerProd
, prodValue
);
1075 CFDictionaryAddValue(prodAndQADictionary
, kSecPolicyLeafMarkerQA
, qaValue
);
1077 CFDictionarySetValue(options
, kSecPolicyCheckLeafMarkersProdAndQA
, prodAndQADictionary
);
1078 CFReleaseNull(prodAndQADictionary
);
1082 static void add_leaf_prod_qa_markers(CFMutableDictionaryRef options
, const DERItem
*prodMarkerOid
, const DERItem
*qaMarkerOid
)
1084 CFDataRef prodData
= NULL
, qaData
= NULL
;
1085 prodData
= CFDataCreate(NULL
, prodMarkerOid
? prodMarkerOid
->data
: NULL
,
1086 prodMarkerOid
? prodMarkerOid
->length
: 0);
1087 qaData
= CFDataCreate(NULL
, qaMarkerOid
? qaMarkerOid
->data
: NULL
,
1088 qaMarkerOid
? qaMarkerOid
->length
: 0);
1089 add_leaf_prod_qa_element(options
, prodData
, qaData
);
1090 CFReleaseNull(prodData
);
1091 CFReleaseNull(qaData
);
1094 static void add_leaf_prod_qa_markers_string(CFMutableDictionaryRef options
, CFStringRef prodMarkerOid
, CFStringRef qaMarkerOid
)
1096 add_leaf_prod_qa_element(options
, prodMarkerOid
, qaMarkerOid
);
1099 static void add_leaf_prod_qa_markers_value_string(CFMutableDictionaryRef options
,
1100 CFStringRef prodMarkerOid
, CFStringRef prod_value
,
1101 CFStringRef qaMarkerOid
, CFStringRef qa_value
)
1103 if (!prod_value
&& !qa_value
) {
1104 add_leaf_prod_qa_element(options
, prodMarkerOid
, qaMarkerOid
);
1106 CFDictionaryRef prodData
= NULL
, qaData
= NULL
;
1107 const void *prodKey
[1] = { prodMarkerOid
}, *qaKey
[1] = { qaMarkerOid
};
1108 const void *prodValue
[1] = { prod_value
}, *qaValue
[1] = { qa_value
};
1109 prodData
= CFDictionaryCreate(NULL
, prodKey
, prodValue
, 1, &kCFTypeDictionaryKeyCallBacks
,
1110 &kCFTypeDictionaryValueCallBacks
);
1111 qaData
= CFDictionaryCreate(NULL
, qaKey
, qaValue
, 1, &kCFTypeDictionaryKeyCallBacks
,
1112 &kCFTypeDictionaryValueCallBacks
);
1113 add_leaf_prod_qa_element(options
, prodData
, qaData
);
1114 CFReleaseNull(prodData
);
1115 CFReleaseNull(qaData
);
1119 static void add_intermediate_marker_value_string(CFMutableDictionaryRef options
, CFStringRef markerOid
, CFStringRef string_value
) {
1120 if (NULL
== string_value
) {
1121 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, markerOid
);
1123 CFDictionaryRef policyData
= NULL
;
1124 const void *key
[1] = { markerOid
};
1125 const void *value
[1] = { string_value
};
1126 policyData
= CFDictionaryCreate(kCFAllocatorDefault
,
1128 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
1129 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, policyData
);
1131 CFReleaseNull(policyData
);
1135 static void add_certificate_policy_oid(CFMutableDictionaryRef options
, const DERItem
*certificatePolicyOid
) {
1136 CFTypeRef certificatePolicyData
= NULL
;
1137 certificatePolicyData
= CFDataCreate(kCFAllocatorDefault
,
1138 certificatePolicyOid
? certificatePolicyOid
->data
: NULL
,
1139 certificatePolicyOid
? certificatePolicyOid
->length
: 0);
1140 if (certificatePolicyData
) {
1141 add_element(options
, kSecPolicyCheckCertificatePolicy
, certificatePolicyData
);
1142 CFRelease(certificatePolicyData
);
1146 static void add_certificate_policy_oid_string(CFMutableDictionaryRef options
, CFStringRef certificatePolicyOid
) {
1147 if (certificatePolicyOid
) {
1148 add_element(options
, kSecPolicyCheckCertificatePolicy
, certificatePolicyOid
);
1153 // Routines for adding dictionary entries for policies.
1156 // X.509, but missing validity requirements.
1157 static void SecPolicyAddBasicCertOptions(CFMutableDictionaryRef options
)
1159 //CFDictionaryAddValue(options, kSecPolicyCheckBasicCertificateProcessing, kCFBooleanTrue);
1160 // Happens automatically in SecPVCPathChecks
1161 CFDictionaryAddValue(options
, kSecPolicyCheckCriticalExtensions
, kCFBooleanTrue
);
1162 CFDictionaryAddValue(options
, kSecPolicyCheckIdLinkage
, kCFBooleanTrue
);
1163 CFDictionaryAddValue(options
, kSecPolicyCheckBasicConstraints
, kCFBooleanTrue
);
1164 CFDictionaryAddValue(options
, kSecPolicyCheckNonEmptySubject
, kCFBooleanTrue
);
1165 CFDictionaryAddValue(options
, kSecPolicyCheckWeakKeySize
, kCFBooleanTrue
);
1166 CFDictionaryAddValue(options
, kSecPolicyCheckWeakSignature
, kCFBooleanTrue
);
1169 static void SecPolicyAddBasicX509Options(CFMutableDictionaryRef options
)
1171 SecPolicyAddBasicCertOptions(options
);
1172 CFDictionaryAddValue(options
, kSecPolicyCheckTemporalValidity
, kCFBooleanTrue
);
1174 // Make sure that black and gray leaf checks are performed for basic X509 chain building
1175 CFDictionaryAddValue(options
, kSecPolicyCheckBlackListedLeaf
, kCFBooleanTrue
);
1176 CFDictionaryAddValue(options
, kSecPolicyCheckGrayListedLeaf
, kCFBooleanTrue
);
1179 static bool SecPolicyAddChainLengthOptions(CFMutableDictionaryRef options
, CFIndex length
)
1181 bool result
= false;
1182 CFNumberRef lengthAsCF
= NULL
;
1184 require(lengthAsCF
= CFNumberCreate(kCFAllocatorDefault
,
1185 kCFNumberCFIndexType
, &length
), errOut
);
1186 CFDictionaryAddValue(options
, kSecPolicyCheckChainLength
, lengthAsCF
);
1191 CFReleaseSafe(lengthAsCF
);
1195 static bool SecPolicyAddAnchorSHA256Options(CFMutableDictionaryRef options
,
1196 const UInt8 anchorSha256
[kSecPolicySHA256Size
])
1198 bool success
= false;
1199 CFDataRef anchorData
= NULL
;
1201 require(anchorData
= CFDataCreate(kCFAllocatorDefault
, anchorSha256
, kSecPolicySHA256Size
), errOut
);
1202 add_element(options
, kSecPolicyCheckAnchorSHA256
, anchorData
);
1207 CFReleaseSafe(anchorData
);
1211 static bool SecPolicyAddStrongKeySizeOptions(CFMutableDictionaryRef options
) {
1212 bool success
= false;
1213 CFDictionaryRef keySizes
= NULL
;
1214 CFNumberRef rsaSize
= NULL
, ecSize
= NULL
;
1216 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
1217 require(rsaSize
= CFNumberCreateWithCFIndex(NULL
, 2048), errOut
);
1218 require(ecSize
= CFNumberCreateWithCFIndex(NULL
, 256), errOut
);
1219 const void *keys
[] = { kSecAttrKeyTypeRSA
, kSecAttrKeyTypeEC
};
1220 const void *values
[] = { rsaSize
, ecSize
};
1221 require(keySizes
= CFDictionaryCreate(NULL
, keys
, values
, 2,
1222 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1223 add_element(options
, kSecPolicyCheckKeySize
, keySizes
);
1228 CFReleaseSafe(keySizes
);
1229 CFReleaseSafe(rsaSize
);
1230 CFReleaseSafe(ecSize
);
1234 static bool SecPolicyRemoveWeakHashOptions(CFMutableDictionaryRef options
) {
1235 CFMutableArrayRef disallowedHashes
= CFArrayCreateMutable(NULL
, 5, &kCFTypeArrayCallBacks
);
1236 if (!disallowedHashes
) {
1239 CFArrayAppendValue(disallowedHashes
, kSecSignatureDigestAlgorithmMD2
);
1240 CFArrayAppendValue(disallowedHashes
, kSecSignatureDigestAlgorithmMD4
);
1241 CFArrayAppendValue(disallowedHashes
, kSecSignatureDigestAlgorithmMD5
);
1242 CFArrayAppendValue(disallowedHashes
, kSecSignatureDigestAlgorithmSHA1
);
1244 add_element(options
, kSecPolicyCheckSignatureHashAlgorithms
, disallowedHashes
);
1245 CFReleaseNull(disallowedHashes
);
1249 static bool isAppleOid(CFStringRef oid
) {
1250 if (!SecCertificateIsOidString(oid
)) {
1253 if (CFStringHasPrefix(oid
, CFSTR("1.2.840.113635"))) {
1259 static bool isCFPreferenceInSecurityDomain(CFStringRef setting
) {
1260 return (CFPreferencesGetAppBooleanValue(setting
, CFSTR("com.apple.security"), NULL
));
1263 static bool SecPolicyAddAppleAnchorOptions(CFMutableDictionaryRef options
, CFStringRef __unused policyName
)
1265 CFMutableDictionaryRef appleAnchorOptions
= NULL
;
1266 appleAnchorOptions
= CFDictionaryCreateMutableForCFTypes(NULL
);
1267 if (!appleAnchorOptions
) {
1271 /* Currently no Apple Anchor options */
1272 add_element(options
, kSecPolicyCheckAnchorApple
, appleAnchorOptions
);
1273 CFReleaseSafe(appleAnchorOptions
);
1277 CFDataRef
CreateCFDataFromBase64CFString(CFStringRef base64string
)
1279 __block CFDataRef cfData
= NULL
;
1281 require_quiet(base64string
, errOut
);
1283 CFStringPerformWithCStringAndLength(base64string
, ^(const char *base64string_buf
, size_t base64string_buf_length
) {
1286 require_quiet(base64string_buf
!= NULL
, errOut
);
1287 require_quiet(base64string_buf_length
!= 0, errOut
);
1289 size_t expected_data_length
= SecBase64Decode(base64string_buf
, base64string_buf_length
, NULL
, 0);
1290 require_quiet(expected_data_length
!= 0, errOut
);
1292 data
= malloc(expected_data_length
);
1293 require(data
!= NULL
, errOut
);
1295 size_t actual_data_length
= SecBase64Decode(base64string_buf
, base64string_buf_length
, data
, expected_data_length
);
1296 require_quiet(actual_data_length
!= 0, errOut
);
1298 cfData
= CFDataCreate(kCFAllocatorDefault
, (const uint8_t *)data
, actual_data_length
);
1309 static CFStringRef
CopyParentDomainNameFromHostName(CFStringRef hostName
)
1311 CFStringRef parentDomainName
= NULL
;
1313 require_quiet(hostName
, errOut
);
1315 CFIndex hostNameLength
= CFStringGetLength(hostName
);
1316 require_quiet(hostNameLength
!= 0, errOut
);
1318 CFRange nextLabel
= CFStringFind(hostName
, CFSTR("."), 0);
1319 require_quiet(nextLabel
.location
!= kCFNotFound
&& nextLabel
.location
< (hostNameLength
- 1), errOut
);
1321 CFRange parentDomainNameRange
= CFRangeMake(nextLabel
.location
+ 1, hostNameLength
- nextLabel
.location
- 1);
1322 parentDomainName
= CFStringCreateWithSubstring(NULL
, hostName
, parentDomainNameRange
);
1325 return parentDomainName
;
1328 CFArrayRef
parseNSPinnedDomains(CFDictionaryRef nsPinnedDomainsDict
, CFStringRef hostName
, CFStringRef nsPinnedIdentityType
)
1330 CFMutableArrayRef targetSPKISHA256
= CFArrayCreateMutable(kCFAllocatorDefault
, 0, &kCFTypeArrayCallBacks
);
1332 __block
bool hostNamePinned
= false;
1334 // Strip the trailing dot if any.
1335 CFIndex hostNameLength
= CFStringGetLength(hostName
);
1336 if (hostNameLength
> 0 && '.' == CFStringGetCharacterAtIndex(hostName
, hostNameLength
- 1)) {
1337 hostName
= CFStringCreateWithSubstring(NULL
, hostName
, CFRangeMake(0, hostNameLength
- 1));
1338 require_quiet(hostName
, errOut
);
1340 CFRetainSafe(hostName
);
1343 CFDictionaryForEach(nsPinnedDomainsDict
, ^(const void *key
, const void *value
) {
1344 CFStringRef parentDomainName
= NULL
;
1346 require_quiet(isString(key
), errOutNSPinnedDomainsDict
);
1347 require_quiet(isDictionary(value
), errOutNSPinnedDomainsDict
);
1349 // Match one of the pinned domains to the current endpoint's hostname.
1350 CFStringRef domainName
= (CFStringRef
)key
;
1351 bool hostNameMatched
= (CFStringCompare(domainName
, hostName
, kCFCompareCaseInsensitive
) == kCFCompareEqualTo
);
1353 // Match one of the pinned domains to the current endpoint's parent domain if allowed.
1354 if (hostNameMatched
== false) {
1355 CFTypeRef nsIncludesSubdomains
= CFDictionaryGetValue(value
, CFSTR("NSIncludesSubdomains"));
1356 require_quiet(nsIncludesSubdomains
== kCFBooleanTrue
, errOutNSPinnedDomainsDict
);
1358 parentDomainName
= CopyParentDomainNameFromHostName(hostName
);
1359 require_quiet(parentDomainName
!= NULL
, errOutNSPinnedDomainsDict
);
1361 hostNameMatched
= (CFStringCompare(domainName
, parentDomainName
, kCFCompareCaseInsensitive
) == kCFCompareEqualTo
);
1363 require_quiet(hostNameMatched
, errOutNSPinnedDomainsDict
);
1365 CFTypeRef nsPinnedIdentities
= CFDictionaryGetValue(value
, nsPinnedIdentityType
);
1366 require_quiet(nsPinnedIdentities
, errOutNSPinnedDomainsDict
);
1367 hostNamePinned
= true;
1369 require_quiet(isArray(nsPinnedIdentities
), errOutNSPinnedDomainsDict
);
1370 CFArrayForEach(nsPinnedIdentities
, ^(const void *v
) {
1371 CFDataRef spkiSHA256
= NULL
;
1373 require_quiet(isDictionary(v
), errOutNSPinnedIdentities
);
1375 CFTypeRef spkiSHA256base64
= CFDictionaryGetValue(v
, CFSTR("SPKI-SHA256-BASE64"));
1376 require_quiet(isString(spkiSHA256base64
), errOutNSPinnedIdentities
);
1378 spkiSHA256
= CreateCFDataFromBase64CFString(spkiSHA256base64
);
1379 require_quiet(spkiSHA256
, errOutNSPinnedIdentities
);
1381 CFArrayAppendValue(targetSPKISHA256
, spkiSHA256
);
1383 errOutNSPinnedIdentities
:
1384 CFReleaseSafe(spkiSHA256
);
1387 errOutNSPinnedDomainsDict
:
1388 CFReleaseSafe(parentDomainName
);
1393 CFReleaseSafe(hostName
);
1394 if (hostNamePinned
== false) {
1395 CFReleaseNull(targetSPKISHA256
);
1397 return targetSPKISHA256
;
1400 static CFArrayRef
getNSPinnedIdentitiesForHostName(CFStringRef hostName
, CFStringRef nsPinnedIdentityType
)
1402 CFMutableArrayRef targetSPKISHA256
= NULL
;
1404 static CFDictionaryRef nsPinnedDomainsDict
= NULL
;
1405 static dispatch_once_t onceToken
;
1406 dispatch_once(&onceToken
, ^{
1407 CFBundleRef bundle
= CFBundleGetMainBundle();
1408 require(bundle
, initializationIncomplete
);
1410 CFTypeRef nsAppTransportSecurityDict
= CFBundleGetValueForInfoDictionaryKey(bundle
, CFSTR("NSAppTransportSecurity"));
1411 require_quiet(isDictionary(nsAppTransportSecurityDict
), initializationIncomplete
);
1413 nsPinnedDomainsDict
= CFDictionaryGetValue(nsAppTransportSecurityDict
, CFSTR("NSPinnedDomains"));
1414 require(isDictionary(nsPinnedDomainsDict
), initializationIncomplete
);
1417 initializationIncomplete
:
1418 nsPinnedDomainsDict
= NULL
;
1420 // To proceed, this or a previous call must have found NSPinnedDomains in the info dictionary.
1421 require_quiet(nsPinnedDomainsDict
, errOut
);
1423 targetSPKISHA256
= (CFMutableArrayRef
)parseNSPinnedDomains(nsPinnedDomainsDict
, hostName
, nsPinnedIdentityType
);
1425 // Return NULL if the hostname (or its parent domain name) is not among the pinned domains.
1426 // Otherwise return an array of zero or more SPKI SHA256 identities.
1428 return targetSPKISHA256
;
1431 static void SecPolicyAddATSpinningIfInfoSpecified(CFMutableDictionaryRef options
)
1433 CFStringRef hostname
= CFDictionaryGetValue(options
, kSecPolicyCheckSSLHostname
);
1434 require_quiet(isString(hostname
), errOut
);
1436 CFArrayRef leafSPKISHA256
= getNSPinnedIdentitiesForHostName(hostname
, CFSTR("NSPinnedLeafIdentities"));
1437 if (leafSPKISHA256
) {
1438 add_element(options
, kSecPolicyCheckLeafSPKISHA256
, leafSPKISHA256
);
1441 CFArrayRef caSPKISHA256
= getNSPinnedIdentitiesForHostName(hostname
, CFSTR("NSPinnedCAIdentities"));
1443 add_element(options
, kSecPolicyCheckCAspkiSHA256
, caSPKISHA256
);
1450 void SecPolicyReconcilePinningRequiredIfInfoSpecified(CFMutableDictionaryRef options
)
1452 bool hasPinningRequiredKey
= false;
1453 CFArrayRef leafSPKISHA256
= NULL
;
1454 CFArrayRef caSPKISHA256
= NULL
;
1456 hasPinningRequiredKey
= CFDictionaryContainsKey(options
, kSecPolicyCheckPinningRequired
);
1457 require_quiet(hasPinningRequiredKey
, errOut
);
1459 // A non-NULL, empty, leafSPKISHA256 array allows all leaves and thus excludes this hostname from pinning.
1460 leafSPKISHA256
= CFDictionaryGetValue(options
, kSecPolicyCheckLeafSPKISHA256
);
1461 caSPKISHA256
= CFDictionaryGetValue(options
, kSecPolicyCheckCAspkiSHA256
);
1462 if (isArray(leafSPKISHA256
) && CFArrayGetCount(leafSPKISHA256
) == 0 &&
1463 isArray(caSPKISHA256
) && CFArrayGetCount(caSPKISHA256
) == 0) {
1464 CFDictionaryRemoveValue(options
, kSecPolicyCheckPinningRequired
);
1467 // kSecPolicyCheckPinningRequired and (kSecPolicyCheckLeafSPKISHA256, kSecPolicyCheckCAspkiSHA256) are mutually exclusive.
1468 CFDictionaryRemoveValue(options
, kSecPolicyCheckLeafSPKISHA256
);
1469 CFDictionaryRemoveValue(options
, kSecPolicyCheckCAspkiSHA256
);
1475 static bool SecPolicyAddPinningRequiredIfInfoSpecified(CFMutableDictionaryRef options
)
1477 static bool result
= false;
1478 static bool hasPinningRequiredKey
= false;
1479 static dispatch_once_t onceToken
;
1480 dispatch_once(&onceToken
, ^{
1481 CFBundleRef bundle
= CFBundleGetMainBundle();
1483 CFTypeRef value
= CFBundleGetValueForInfoDictionaryKey(bundle
, CFSTR("SecTrustPinningRequired"));
1484 if (isBoolean(value
) && CFBooleanGetValue(value
)) {
1485 hasPinningRequiredKey
= true;
1490 if (result
&& hasPinningRequiredKey
) {
1491 add_element(options
, kSecPolicyCheckPinningRequired
, kCFBooleanTrue
);
1497 // MARK: Policy Creation Functions
1499 SecPolicyRef
SecPolicyCreateBasicX509(void) {
1500 CFMutableDictionaryRef options
= NULL
;
1501 SecPolicyRef result
= NULL
;
1503 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1504 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1506 SecPolicyAddBasicX509Options(options
);
1507 CFDictionaryAddValue(options
, kSecPolicyCheckNoNetworkAccess
,
1510 require(result
= SecPolicyCreate(kSecPolicyAppleX509Basic
, kSecPolicyNameX509Basic
, options
), errOut
);
1513 CFReleaseSafe(options
);
1514 return (SecPolicyRef _Nonnull
)result
;
1517 SecPolicyRef
SecPolicyCreateSSL(Boolean server
, CFStringRef hostname
) {
1518 CFMutableDictionaryRef options
= NULL
;
1519 SecPolicyRef result
= NULL
;
1521 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1522 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1524 SecPolicyAddBasicX509Options(options
);
1527 CFDictionaryAddValue(options
, kSecPolicyCheckSSLHostname
, hostname
);
1530 CFDictionaryAddValue(options
, kSecPolicyCheckBlackListedLeaf
, kCFBooleanTrue
);
1531 CFDictionaryAddValue(options
, kSecPolicyCheckGrayListedLeaf
, kCFBooleanTrue
);
1534 require_quiet(SecPolicyRemoveWeakHashOptions(options
), errOut
);
1535 require_quiet(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
1536 require_quiet(SecPolicyAddPinningRequiredIfInfoSpecified(options
), errOut
);
1537 SecPolicyAddATSpinningIfInfoSpecified(options
);
1538 SecPolicyReconcilePinningRequiredIfInfoSpecified(options
);
1539 CFDictionaryAddValue(options
, kSecPolicyCheckValidityPeriodMaximums
, kCFBooleanTrue
);
1540 CFDictionaryAddValue(options
, kSecPolicyCheckServerAuthEKU
, kCFBooleanTrue
); // enforces stricter EKU rules than set_ssl_ekus below for certain anchor types
1541 #if !TARGET_OS_BRIDGE
1542 CFDictionaryAddValue(options
, kSecPolicyCheckSystemTrustedCTRequired
, kCFBooleanTrue
);
1546 set_ssl_ekus(options
, server
);
1548 require(result
= SecPolicyCreate(kSecPolicyAppleSSL
,
1549 server
? kSecPolicyNameSSLServer
: kSecPolicyNameSSLClient
,
1553 CFReleaseSafe(options
);
1554 return (SecPolicyRef _Nonnull
)result
;
1557 SecPolicyRef
SecPolicyCreateLegacySSL(Boolean server
, CFStringRef hostname
) {
1558 CFMutableDictionaryRef options
= NULL
;
1559 SecPolicyRef result
= NULL
;
1561 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1562 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1564 SecPolicyAddBasicX509Options(options
);
1567 CFDictionaryAddValue(options
, kSecPolicyCheckSSLHostname
, hostname
);
1570 CFDictionaryAddValue(options
, kSecPolicyCheckBlackListedLeaf
, kCFBooleanTrue
);
1571 CFDictionaryAddValue(options
, kSecPolicyCheckGrayListedLeaf
, kCFBooleanTrue
);
1574 // fewer requirements than the standard SSL policy
1575 require_quiet(SecPolicyAddPinningRequiredIfInfoSpecified(options
), errOut
);
1576 SecPolicyAddATSpinningIfInfoSpecified(options
);
1577 SecPolicyReconcilePinningRequiredIfInfoSpecified(options
);
1578 CFDictionaryAddValue(options
, kSecPolicyCheckValidityPeriodMaximums
, kCFBooleanTrue
);
1579 #if !TARGET_OS_BRIDGE
1580 CFDictionaryAddValue(options
, kSecPolicyCheckSystemTrustedCTRequired
, kCFBooleanTrue
);
1584 set_ssl_ekus(options
, server
);
1586 require(result
= SecPolicyCreate(kSecPolicyAppleLegacySSL
, kSecPolicyNameLegacySSL
, options
), errOut
);
1589 CFReleaseSafe(options
);
1590 return (SecPolicyRef _Nonnull
)result
;
1593 SecPolicyRef
SecPolicyCreateApplePinned(CFStringRef policyName
, CFStringRef intermediateMarkerOID
, CFStringRef leafMarkerOID
) {
1594 CFMutableDictionaryRef options
= NULL
;
1595 SecPolicyRef result
= NULL
;
1597 if (!policyName
|| !intermediateMarkerOID
|| !leafMarkerOID
) {
1601 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1602 &kCFTypeDictionaryKeyCallBacks
,
1603 &kCFTypeDictionaryValueCallBacks
), errOut
);
1605 SecPolicyAddBasicX509Options(options
);
1607 /* Anchored to the Apple Roots */
1608 require(SecPolicyAddAppleAnchorOptions(options
, policyName
), errOut
);
1610 /* Exactly 3 certs in the chain */
1611 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1613 /* Intermediate marker OID matches input OID */
1614 if (!isAppleOid(intermediateMarkerOID
)) {
1615 secwarning("creating an Apple pinning policy with a non-Apple OID: %@", intermediateMarkerOID
);
1617 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, intermediateMarkerOID
);
1619 /* Leaf marker OID matches input OID */
1620 if (!isAppleOid(leafMarkerOID
)) {
1621 secwarning("creating an Apple pinning policy with a non-Apple OID: %@", leafMarkerOID
);
1623 add_leaf_marker_string(options
, leafMarkerOID
);
1625 /* Check revocation using any available method */
1626 add_element(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
1628 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
1629 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
1631 /* Check for weak hashes */
1632 // require(SecPolicyRemoveWeakHashOptions(options), errOut); // the current WWDR CA cert is signed with SHA1
1633 require(result
= SecPolicyCreate(kSecPolicyAppleGenericApplePinned
,
1634 policyName
, options
), errOut
);
1637 CFReleaseSafe(options
);
1642 requireUATPinning(CFStringRef service
)
1644 bool pinningRequired
= true;
1646 if (SecIsInternalRelease()) {
1647 CFStringRef setting
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("AppleServerAuthenticationNoPinning%@"), service
);
1648 require(setting
, fail
);
1649 if(isCFPreferenceInSecurityDomain(setting
)) {
1650 pinningRequired
= false;
1652 secnotice("pinningQA", "could not disable pinning: %@ not true", setting
);
1656 if (!pinningRequired
) {
1660 if(isCFPreferenceInSecurityDomain(CFSTR("AppleServerAuthenticationNoPinning"))) {
1661 pinningRequired
= false;
1663 secnotice("pinningQA", "could not disable pinning: AppleServerAuthenticationNoPinning not true");
1666 secnotice("pinningQA", "could not disable pinning: not an internal release");
1669 return pinningRequired
;
1672 SecPolicyRef
SecPolicyCreateAppleSSLPinned(CFStringRef policyName
, CFStringRef hostname
,
1673 CFStringRef intermediateMarkerOID
, CFStringRef leafMarkerOID
) {
1674 CFMutableDictionaryRef options
= NULL
;
1675 SecPolicyRef result
= NULL
;
1677 if (!policyName
|| !hostname
|| !leafMarkerOID
) {
1681 if (requireUATPinning(policyName
)) {
1682 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1683 &kCFTypeDictionaryKeyCallBacks
,
1684 &kCFTypeDictionaryValueCallBacks
), errOut
);
1686 SecPolicyAddBasicX509Options(options
);
1688 /* Anchored to the Apple Roots */
1689 require(SecPolicyAddAppleAnchorOptions(options
, policyName
), errOut
);
1691 /* Exactly 3 certs in the chain */
1692 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1694 if (intermediateMarkerOID
) {
1695 /* Intermediate marker OID matches input OID */
1696 if (!isAppleOid(intermediateMarkerOID
)) {
1697 secwarning("creating an Apple pinning policy with a non-Apple OID: %@", intermediateMarkerOID
);
1699 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, intermediateMarkerOID
);
1701 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.12"));
1704 /* Leaf marker OID matches input OID */
1705 if (!isAppleOid(leafMarkerOID
)) {
1706 secwarning("creating an Apple pinning policy with a non-Apple OID: %@", leafMarkerOID
);
1708 add_leaf_marker_string(options
, leafMarkerOID
);
1710 /* New leaf marker OID format */
1711 add_leaf_marker_value_string(options
, CFSTR("1.2.840.113635.100.6.48.1"), leafMarkerOID
);
1713 /* ServerAuth EKU is in leaf cert */
1714 add_eku_string(options
, CFSTR("1.3.6.1.5.5.7.3.1"));
1716 /* Hostname is in leaf cert */
1717 add_element(options
, kSecPolicyCheckSSLHostname
, hostname
);
1719 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
1720 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
1722 /* Check for weak hashes */
1723 require(SecPolicyRemoveWeakHashOptions(options
), errOut
);
1725 /* Check revocation using any available method */
1726 add_element(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
1728 require(result
= SecPolicyCreate(kSecPolicyAppleGenericAppleSSLPinned
,
1729 policyName
, options
), errOut
);
1732 result
= SecPolicyCreateSSL(true, hostname
);
1733 SecPolicySetOid(result
, kSecPolicyAppleGenericAppleSSLPinned
);
1734 SecPolicySetName(result
, policyName
);
1738 CFReleaseSafe(options
);
1742 SecPolicyRef
SecPolicyCreateiPhoneActivation(void) {
1743 CFMutableDictionaryRef options
= NULL
;
1744 SecPolicyRef result
= NULL
;
1746 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1747 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1749 SecPolicyAddBasicCertOptions(options
);
1752 CFDictionaryAddValue(options
, kSecPolicyCheckKeyUsage
,
1754 CFDictionaryAddValue(options
, kSecPolicyCheckExtendedKeyUsage
,
1758 /* Basic X.509 policy with the additional requirements that the chain
1759 length is 3, it's anchored at the AppleCA and the leaf certificate
1760 has issuer "Apple iPhone Certification Authority" and
1761 subject "Apple iPhone Activation" for the common name. */
1762 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
1763 CFSTR("Apple iPhone Certification Authority"));
1764 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
,
1765 CFSTR("Apple iPhone Activation"));
1767 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1768 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameiPhoneActivation
), errOut
);
1770 require(result
= SecPolicyCreate(kSecPolicyAppleiPhoneActivation
,
1771 kSecPolicyNameiPhoneActivation
, options
),
1775 CFReleaseSafe(options
);
1779 SecPolicyRef
SecPolicyCreateiPhoneDeviceCertificate(void) {
1780 CFMutableDictionaryRef options
= NULL
;
1781 SecPolicyRef result
= NULL
;
1783 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1784 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1786 SecPolicyAddBasicCertOptions(options
);
1789 CFDictionaryAddValue(options
, kSecPolicyCheckKeyUsage
,
1791 CFDictionaryAddValue(options
, kSecPolicyCheckExtendedKeyUsage
,
1795 /* Basic X.509 policy with the additional requirements that the chain
1796 length is 4, it's anchored at the AppleCA and the first intermediate
1797 has the subject "Apple iPhone Device CA". */
1798 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
1799 CFSTR("Apple iPhone Device CA"));
1801 require(SecPolicyAddChainLengthOptions(options
, 4), errOut
);
1802 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameiPhoneDeviceCertificate
), errOut
);
1804 require(result
= SecPolicyCreate(kSecPolicyAppleiPhoneDeviceCertificate
,
1805 kSecPolicyNameiPhoneDeviceCertificate
, options
),
1809 CFReleaseSafe(options
);
1813 /* subject:/C=US/O=Apple Inc./OU=Apple iPhone/CN=[TEST] Apple iPhone Device CA */
1814 /* issuer :/C=US/O=Apple Inc./OU=Apple Certification Authority/CN=[TEST] Apple iPhone Certification Authority */
1815 const uint8_t kFactoryDeviceCASHA256
[CC_SHA256_DIGEST_LENGTH
] = {
1816 0x7b, 0x8e, 0xc8, 0x78, 0xff, 0x3a, 0xcf, 0x61, 0xdd, 0xe6, 0x53, 0x77, 0x2b, 0xe7, 0x32, 0xc5,
1817 0x97, 0xf4, 0x6b, 0x9c, 0xa6, 0x00, 0xc5, 0x2c, 0xc1, 0x25, 0x85, 0x02, 0x03, 0x06, 0x97, 0x96
1820 SecPolicyRef
SecPolicyCreateFactoryDeviceCertificate(void) {
1821 CFMutableDictionaryRef options
= NULL
;
1822 SecPolicyRef result
= NULL
;
1824 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1825 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1827 SecPolicyAddBasicCertOptions(options
);
1829 /* Basic X.509 policy with the additional requirements that the chain
1830 is anchored at the factory device certificate issuer. */
1831 require(SecPolicyAddAnchorSHA256Options(options
, kFactoryDeviceCASHA256
), errOut
);
1833 require(result
= SecPolicyCreate(kSecPolicyAppleFactoryDeviceCertificate
,
1834 kSecPolicyNameFactoryDeviceCertificate
, options
),
1838 CFReleaseSafe(options
);
1842 SecPolicyRef
SecPolicyCreateiAP(void) {
1843 CFMutableDictionaryRef options
= NULL
;
1844 SecPolicyRef result
= NULL
;
1845 CFTimeZoneRef tz
= NULL
;
1846 CFDateRef date
= NULL
;
1848 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1849 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1851 SecPolicyAddBasicCertOptions(options
);
1853 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonNamePrefix
,
1856 date
= CFDateCreateForGregorianZuluDay(NULL
, 2006, 5, 31);
1857 CFDictionaryAddValue(options
, kSecPolicyCheckNotValidBefore
, date
);
1859 require(result
= SecPolicyCreate(kSecPolicyAppleiAP
,
1860 kSecPolicyNameiAP
, options
),
1864 CFReleaseSafe(date
);
1866 CFReleaseSafe(options
);
1870 /* subject:/O=Apple Inc./OU=iTunes Store/CN=iTunes Store Root/C=US/ST=California/L=Cupertino */
1871 /* issuer :/O=Apple Inc./OU=iTunes Store/CN=iTunes Store Root/C=US/ST=California/L=Cupertino */
1872 const uint8_t kITMS_CA_SHA256
[CC_SHA256_DIGEST_LENGTH
] = {
1873 0xa1, 0xdc, 0x36, 0x23, 0x84, 0xb4, 0xba, 0x0f, 0xaf, 0xea, 0x2a, 0xd4, 0xac, 0xc4, 0x86, 0x8f,
1874 0xfb, 0xae, 0x57, 0x21, 0x4d, 0x20, 0x88, 0xc8, 0x82, 0xe7, 0x65, 0x13, 0x47, 0xab, 0x81, 0xd7
1877 SecPolicyRef
SecPolicyCreateiTunesStoreURLBag(void) {
1878 CFMutableDictionaryRef options
= NULL
;
1879 SecPolicyRef result
= NULL
;
1882 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1883 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1885 SecPolicyAddBasicCertOptions(options
);
1887 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectOrganization
,
1888 CFSTR("Apple Inc."));
1889 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
,
1890 CFSTR("iTunes Store URL Bag"));
1892 require(SecPolicyAddChainLengthOptions(options
, 2), errOut
);
1893 require(SecPolicyAddAnchorSHA256Options(options
, kITMS_CA_SHA256
), errOut
);
1895 require(result
= SecPolicyCreate(kSecPolicyAppleiTunesStoreURLBag
,
1896 kSecPolicyNameiTunesStoreURLBag
, options
), errOut
);
1899 CFReleaseSafe(options
);
1903 SecPolicyRef
SecPolicyCreateEAP(Boolean server
, CFArrayRef trustedServerNames
) {
1904 CFMutableDictionaryRef options
= NULL
;
1905 SecPolicyRef result
= NULL
;
1907 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1908 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1910 SecPolicyAddBasicX509Options(options
);
1912 /* Since EAP is used to setup the network we don't want evaluation
1913 using this policy to access the network. */
1914 CFDictionaryAddValue(options
, kSecPolicyCheckNoNetworkAccess
,
1917 if (trustedServerNames
) {
1918 CFDictionaryAddValue(options
, kSecPolicyCheckEAPTrustedServerNames
, trustedServerNames
);
1922 /* Check for weak hashes and keys, but only on system-trusted roots, because enterprise
1923 * PKIs are the absolute worst. */
1924 CFDictionaryAddValue(options
, kSecPolicyCheckSystemTrustedWeakHash
, kCFBooleanTrue
);
1925 CFDictionaryAddValue(options
, kSecPolicyCheckSystemTrustedWeakKey
, kCFBooleanTrue
);
1928 /* We need to check for EKU per rdar://22206018 */
1929 set_ssl_ekus(options
, server
);
1931 require(result
= SecPolicyCreate(kSecPolicyAppleEAP
,
1932 server
? kSecPolicyNameEAPServer
: kSecPolicyNameEAPClient
,
1936 CFReleaseSafe(options
);
1940 SecPolicyRef
SecPolicyCreateIPSec(Boolean server
, CFStringRef hostname
) {
1941 CFMutableDictionaryRef options
= NULL
;
1942 SecPolicyRef result
= NULL
;
1944 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1945 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1947 SecPolicyAddBasicX509Options(options
);
1950 CFDictionaryAddValue(options
, kSecPolicyCheckSSLHostname
, hostname
);
1953 /* Require oidExtendedKeyUsageIPSec if Extended Keyusage Extention is
1955 /* Per <rdar://problem/6843827> Cisco VPN Certificate compatibility issue.
1956 We don't check the EKU for IPSec certs for now. If we do add eku
1957 checking back in the future, we should probably also accept the
1959 ipsecEndSystem 1.3.6.1.5.5.7.3.5
1961 ipsecTunnel 1.3.6.1.5.5.7.3.6
1962 ipsecUser 1.3.6.1.5.5.7.3.7
1964 //add_eku(options, NULL); /* eku extension is optional */
1965 //add_eku(options, &oidAnyExtendedKeyUsage);
1966 //add_eku(options, &oidExtendedKeyUsageIPSec);
1968 require(result
= SecPolicyCreate(kSecPolicyAppleIPsec
,
1969 server
? kSecPolicyNameIPSecServer
: kSecPolicyNameIPSecClient
,
1973 CFReleaseSafe(options
);
1977 SecPolicyRef
SecPolicyCreateiPhoneApplicationSigning(void) {
1978 CFMutableDictionaryRef options
= NULL
;
1979 SecPolicyRef result
= NULL
;
1981 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1982 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1984 SecPolicyAddBasicCertOptions(options
);
1986 /* Anchored to the Apple Roots */
1987 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameiPhoneApplicationSigning
), errOut
);
1990 if (SecIsInternalRelease()) {
1991 /* Allow a prod hierarchy-signed test cert */
1992 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonNameTEST
,
1993 CFSTR("Apple iPhone OS Application Signing"));
1994 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.3.1"));
1997 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
,
1998 CFSTR("Apple iPhone OS Application Signing"));
2000 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.3"));
2002 add_eku(options
, NULL
); /* eku extension is optional */
2003 add_eku(options
, &oidAnyExtendedKeyUsage
);
2004 add_eku(options
, &oidExtendedKeyUsageCodeSigning
);
2006 /* Intermediate check */
2007 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2008 CFSTR("Apple iPhone Certification Authority"));
2010 /* Chain length check */
2011 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2013 /* Skip networked revocation checks */
2014 CFDictionaryAddValue(options
, kSecPolicyCheckNoNetworkAccess
, kCFBooleanTrue
);
2016 require(result
= SecPolicyCreate(kSecPolicyAppleiPhoneApplicationSigning
,
2017 kSecPolicyNameiPhoneApplicationSigning
, options
),
2021 CFReleaseSafe(options
);
2025 SecPolicyRef
SecPolicyCreateiPhoneVPNApplicationSigning(void) {
2026 CFMutableDictionaryRef options
= NULL
;
2027 SecPolicyRef result
= NULL
;
2029 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2030 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2032 SecPolicyAddBasicCertOptions(options
);
2034 /* Anchored to the Apple Roots */
2035 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameiPhoneVPNApplicationSigning
), errOut
);
2038 if (SecIsInternalRelease()) {
2039 /* Allow a prod hierarchy-signed test cert */
2040 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonNameTEST
,
2041 CFSTR("Apple iPhone OS Application Signing"));
2042 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.6.1"));
2045 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
,
2046 CFSTR("Apple iPhone OS Application Signing"));
2048 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.6"));
2050 add_eku(options
, NULL
); /* eku extension is optional */
2051 add_eku(options
, &oidAnyExtendedKeyUsage
);
2052 add_eku(options
, &oidExtendedKeyUsageCodeSigning
);
2054 /* Intermediate check */
2055 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2056 CFSTR("Apple iPhone Certification Authority"));
2058 /* Chain length check */
2059 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2061 /* Skip networked revocation checks */
2062 CFDictionaryAddValue(options
, kSecPolicyCheckNoNetworkAccess
, kCFBooleanTrue
);
2064 require(result
= SecPolicyCreate(kSecPolicyAppleiPhoneVPNApplicationSigning
,
2065 kSecPolicyNameiPhoneVPNApplicationSigning
, options
),
2069 CFReleaseSafe(options
);
2073 SecPolicyRef
SecPolicyCreateiPhoneProfileApplicationSigning(void) {
2074 CFMutableDictionaryRef options
= NULL
;
2075 SecPolicyRef result
= NULL
;
2077 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2078 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2080 SecPolicyAddBasicX509Options(options
); // With expiration checking
2083 require_quiet(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameiPhoneProfileApplicationSigning
),
2087 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2089 /* Leaf has CodeSigning EKU */
2090 add_eku_string(options
, CFSTR("1.3.6.1.5.5.7.3.3"));
2092 /* On iOS, the cert in the provisioning profile may be one of:
2093 leaf OID intermediate OID
2094 iPhone Developer <ADS>.6.1.2 <ADS>.6.2.1
2095 iPhone Distribution <ADS>.6.1.4 <ADS>.6.2.1
2096 TestFlight (Prod) <ADS>.6.1.25.1 <ADS>.6.2.1
2097 TestFlight (QA) <ADS>.6.1.25.2 <ADS>.6.2.1
2099 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.1"));
2100 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.2"));
2101 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.4"));
2102 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.25.1"));
2103 if (SecIsInternalRelease()) {
2104 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.25.2"));
2107 /* Revocation via any available method */
2108 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
2110 require(result
= SecPolicyCreate(kSecPolicyAppleiPhoneProfileApplicationSigning
,
2111 kSecPolicyNameiPhoneProfileApplicationSigning
,
2115 CFReleaseSafe(options
);
2119 SecPolicyRef
SecPolicyCreateMacOSProfileApplicationSigning(void) {
2120 CFMutableDictionaryRef options
= NULL
;
2121 SecPolicyRef result
= NULL
;
2123 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2124 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2126 SecPolicyAddBasicCertOptions(options
); // Without expiration checking
2129 require_quiet(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameiPhoneProfileApplicationSigning
),
2133 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2135 /* Leaf has CodeSigning EKU */
2136 add_eku_string(options
, CFSTR("1.3.6.1.5.5.7.3.3"));
2139 /* On macOS, the cert in the provisioning profile may be one of:
2140 leaf OID intermediate OID
2141 MAS Development <ADS>.6.1.12 <ADS>.6.2.1
2142 MAS Submission <ADS>.6.1.7 <ADS>.6.2.1
2143 Developer ID <ADS>.6.1.13 <ADS>.6.2.6
2144 B&I <ADS>.6.22 None - "Apple Code Signing Certification Authority"
2146 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.12"));
2147 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.7"));
2148 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.13"));
2149 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.22"));
2151 /* Revocation via any available method */
2152 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
2154 require(result
= SecPolicyCreate(kSecPolicyAppleMacOSProfileApplicationSigning
,
2155 kSecPolicyNameMacOSProfileApplicationSigning
,
2159 CFReleaseSafe(options
);
2163 SecPolicyRef
SecPolicyCreateiPhoneProvisioningProfileSigning(void) {
2164 CFMutableDictionaryRef options
= NULL
;
2165 SecPolicyRef result
= NULL
;
2167 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2168 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2170 SecPolicyAddBasicCertOptions(options
);
2172 /* Basic X.509 policy with the additional requirements that the chain
2173 length is 3, it's anchored at the AppleCA and the leaf certificate
2174 has issuer "Apple iPhone Certification Authority" and
2175 subject "Apple iPhone OS Provisioning Profile Signing" for the common name. */
2176 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2177 CFSTR("Apple iPhone Certification Authority"));
2178 if (SecIsInternalRelease()) {
2179 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonNameTEST
,
2180 CFSTR("Apple iPhone OS Provisioning Profile Signing"));
2183 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
,
2184 CFSTR("Apple iPhone OS Provisioning Profile Signing"));
2187 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2188 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameiPhoneProvisioningProfileSigning
), errOut
);
2190 /* Skip networked revocation checks */
2191 CFDictionaryAddValue(options
, kSecPolicyCheckNoNetworkAccess
, kCFBooleanTrue
);
2193 require(result
= SecPolicyCreate(kSecPolicyAppleiPhoneProvisioningProfileSigning
,
2194 kSecPolicyNameiPhoneProvisioningProfileSigning
, options
),
2197 /* 1.2.840.113635.100.6.2.2.1, non-critical: DER:05:00 - provisioning profile */
2200 CFReleaseSafe(options
);
2204 SecPolicyRef
SecPolicyCreateAppleTVOSApplicationSigning(void) {
2205 CFMutableDictionaryRef options
= NULL
;
2206 SecPolicyRef result
= NULL
;
2207 CFDataRef atvProdOid
= NULL
;
2208 CFDataRef atvTestOid
= NULL
;
2209 CFArrayRef oids
= NULL
;
2211 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2212 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2214 SecPolicyAddBasicCertOptions(options
);
2216 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2218 require_quiet(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameTVOSApplicationSigning
),
2221 /* Check for intermediate: Apple Worldwide Developer Relations */
2222 /* 1.2.840.113635.100.6.2.1 */
2223 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleWWDR
);
2225 add_ku(options
, kSecKeyUsageDigitalSignature
);
2227 /* Check for prod or test AppleTV Application Signing OIDs */
2228 /* Prod: 1.2.840.113635.100.6.1.24 */
2229 /* ProdQA: 1.2.840.113635.100.6.1.24.1 */
2230 add_leaf_marker(options
, &oidAppleTVOSApplicationSigningProd
);
2231 add_leaf_marker(options
, &oidAppleTVOSApplicationSigningProdQA
);
2233 /* Skip networked revocation checks */
2234 CFDictionaryAddValue(options
, kSecPolicyCheckNoNetworkAccess
, kCFBooleanTrue
);
2236 require(result
= SecPolicyCreate(kSecPolicyAppleTVOSApplicationSigning
,
2237 kSecPolicyNameTVOSApplicationSigning
, options
),
2241 CFReleaseSafe(options
);
2242 CFReleaseSafe(oids
);
2243 CFReleaseSafe(atvProdOid
);
2244 CFReleaseSafe(atvTestOid
);
2248 SecPolicyRef
SecPolicyCreateOCSPSigner(void) {
2249 CFMutableDictionaryRef options
= NULL
;
2250 SecPolicyRef result
= NULL
;
2252 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2253 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2255 SecPolicyAddBasicX509Options(options
);
2257 /* Require id-kp-OCSPSigning extendedKeyUsage to be present, not optional. */
2258 add_eku(options
, &oidExtendedKeyUsageOCSPSigning
);
2260 /* Check for digitalSignature KU and CA:FALSE. See <rdar://problem/65354714> */
2261 add_ku(options
, kSecKeyUsageDigitalSignature
);
2262 CFDictionarySetValue(options
, kSecPolicyCheckNotCA
, kCFBooleanTrue
);
2264 require(result
= SecPolicyCreate(kSecPolicyAppleOCSPSigner
,
2265 kSecPolicyNameOCSPSigner
, options
), errOut
);
2268 CFReleaseSafe(options
);
2272 SecPolicyRef
SecPolicyCreateRevocation(CFOptionFlags revocationFlags
) {
2273 CFMutableDictionaryRef options
= NULL
;
2274 SecPolicyRef result
= NULL
;
2276 require(revocationFlags
!= 0, errOut
);
2278 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2279 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2281 if (revocationFlags
& kSecRevocationCheckIfTrusted
) {
2282 CFDictionaryAddValue(options
, kSecPolicyCheckRevocationIfTrusted
, kCFBooleanTrue
);
2283 /* Set method, but allow caller to override with later checks */
2284 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
2287 if (revocationFlags
& kSecRevocationOnlineCheck
) {
2288 CFDictionaryAddValue(options
, kSecPolicyCheckRevocationOnline
, kCFBooleanTrue
);
2289 /* Set method, but allow caller to override with later checks */
2290 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
2293 if (revocationFlags
& kSecRevocationOCSPMethod
&& revocationFlags
& kSecRevocationCRLMethod
) {
2294 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
2296 else if (revocationFlags
& kSecRevocationOCSPMethod
) {
2297 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationOCSP
);
2299 else if (revocationFlags
& kSecRevocationCRLMethod
) {
2300 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationCRL
);
2303 if (revocationFlags
& kSecRevocationRequirePositiveResponse
) {
2304 CFDictionaryAddValue(options
, kSecPolicyCheckRevocationResponseRequired
, kCFBooleanTrue
);
2307 if (revocationFlags
& kSecRevocationNetworkAccessDisabled
) {
2308 CFDictionaryAddValue(options
, kSecPolicyCheckNoNetworkAccess
, kCFBooleanTrue
);
2310 /* If the caller didn't explicitly disable network access, the revocation policy
2311 * should override any other policy's network setting.
2312 * In particular, pairing a revocation policy with BasicX509 should result in
2313 * allowing network access for revocation unless explicitly disabled.
2314 * Note that SecTrustSetNetworkFetchAllowed can override even this. */
2315 CFDictionaryAddValue(options
, kSecPolicyCheckNoNetworkAccess
, kCFBooleanFalse
);
2318 /* Only flag bits 0-6 are currently defined */
2319 require(((revocationFlags
>> 7) == 0), errOut
);
2321 require(result
= SecPolicyCreate(kSecPolicyAppleRevocation
,
2322 kSecPolicyNameRevocation
, options
), errOut
);
2325 CFReleaseSafe(options
);
2329 SecPolicyRef
SecPolicyCreateSMIME(CFIndex smimeUsage
, CFStringRef email
) {
2330 CFMutableDictionaryRef options
= NULL
;
2331 SecPolicyRef result
= NULL
;
2333 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2334 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2336 if (smimeUsage
& kSecIgnoreExpirationSMIMEUsage
) {
2337 SecPolicyAddBasicCertOptions(options
);
2339 SecPolicyAddBasicX509Options(options
);
2342 /* We call add_ku for each combination of bits we are willing to allow. */
2343 if (smimeUsage
& kSecSignSMIMEUsage
) {
2344 add_ku(options
, kSecKeyUsageUnspecified
);
2345 add_ku(options
, kSecKeyUsageDigitalSignature
);
2347 if (smimeUsage
& kSecKeyEncryptSMIMEUsage
) {
2348 add_ku(options
, kSecKeyUsageKeyEncipherment
);
2350 if (smimeUsage
& kSecDataEncryptSMIMEUsage
) {
2351 add_ku(options
, kSecKeyUsageDataEncipherment
);
2353 if (smimeUsage
& kSecKeyExchangeDecryptSMIMEUsage
||
2354 smimeUsage
& kSecKeyExchangeEncryptSMIMEUsage
||
2355 smimeUsage
& kSecKeyExchangeBothSMIMEUsage
) {
2356 /* <rdar://57130017> */
2357 add_ku(options
, kSecKeyUsageKeyAgreement
);
2361 CFDictionaryAddValue(options
, kSecPolicyCheckEmail
, email
);
2364 add_eku(options
, NULL
); /* eku extension is optional */
2365 add_eku(options
, &oidExtendedKeyUsageEmailProtection
);
2367 #if !TARGET_OS_IPHONE
2368 // Check revocation on OS X
2369 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
2372 require(result
= SecPolicyCreate(kSecPolicyAppleSMIME
, kSecPolicyNameSMIME
, options
), errOut
);
2375 CFReleaseSafe(options
);
2379 SecPolicyRef
SecPolicyCreateApplePackageSigning(void) {
2380 CFMutableDictionaryRef options
= NULL
;
2381 SecPolicyRef result
= NULL
;
2383 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2384 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2386 SecPolicyAddBasicCertOptions(options
);
2388 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2389 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNamePackageSigning
), errOut
);
2391 add_ku(options
, kSecKeyUsageDigitalSignature
);
2392 add_eku(options
, &oidExtendedKeyUsageCodeSigning
);
2394 require(result
= SecPolicyCreate(kSecPolicyApplePackageSigning
,
2395 kSecPolicyNamePackageSigning
, options
),
2399 CFReleaseSafe(options
);
2404 SecPolicyRef
SecPolicyCreateAppleSWUpdateSigning(void) {
2405 CFMutableDictionaryRef options
= NULL
;
2406 SecPolicyRef result
= NULL
;
2408 * OS X rules for this policy:
2409 * -- Must have one intermediate cert
2410 * -- intermediate must have basic constraints with path length 0
2411 * -- intermediate has CSSMOID_APPLE_EKU_CODE_SIGNING EKU
2412 * -- leaf cert has either CODE_SIGNING or CODE_SIGN_DEVELOPMENT EKU (the latter of
2413 * which triggers a CSSMERR_APPLETP_CODE_SIGN_DEVELOPMENT error)
2415 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2416 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2418 SecPolicyAddBasicX509Options(options
);
2420 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2421 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameSWUpdateSigning
), errOut
);
2423 add_eku(options
, &oidAppleExtendedKeyUsageCodeSigning
);
2424 add_oid(options
, kSecPolicyCheckIntermediateEKU
, &oidAppleExtendedKeyUsageCodeSigning
);
2426 require(result
= SecPolicyCreate(kSecPolicyAppleSWUpdateSigning
,
2427 kSecPolicyNameSWUpdateSigning
, options
),
2431 CFReleaseSafe(options
);
2436 SecPolicyRef
SecPolicyCreateCodeSigning(void) {
2437 CFMutableDictionaryRef options
= NULL
;
2438 SecPolicyRef result
= NULL
;
2440 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2441 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2443 SecPolicyAddBasicX509Options(options
);
2445 /* If the key usage extension is present, we accept it having either of
2447 add_ku(options
, kSecKeyUsageDigitalSignature
);
2448 add_ku(options
, kSecKeyUsageNonRepudiation
);
2450 /* We require an extended key usage extension with the codesigning
2451 eku purpose. (The Apple codesigning eku is not accepted here
2452 since it's valid only for SecPolicyCreateAppleSWUpdateSigning.) */
2453 add_eku(options
, &oidExtendedKeyUsageCodeSigning
);
2454 #if TARGET_OS_IPHONE
2455 /* Accept the 'any' eku on iOS only to match prior behavior.
2456 This may be further restricted in future releases. */
2457 add_eku(options
, &oidAnyExtendedKeyUsage
);
2460 require(result
= SecPolicyCreate(kSecPolicyAppleCodeSigning
,
2461 kSecPolicyNameCodeSigning
, options
),
2465 CFReleaseSafe(options
);
2469 /* Explicitly leave out empty subject/subjectaltname check */
2470 SecPolicyRef
SecPolicyCreateLockdownPairing(void) {
2471 CFMutableDictionaryRef options
= NULL
;
2472 SecPolicyRef result
= NULL
;
2474 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2475 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2476 //CFDictionaryAddValue(options, kSecPolicyCheckBasicCertificateProcessing,
2477 // kCFBooleanTrue); // Happens automatically in SecPVCPathChecks
2478 CFDictionaryAddValue(options
, kSecPolicyCheckCriticalExtensions
,
2480 CFDictionaryAddValue(options
, kSecPolicyCheckIdLinkage
,
2482 CFDictionaryAddValue(options
, kSecPolicyCheckBasicConstraints
,
2484 CFDictionaryAddValue(options
, kSecPolicyCheckWeakKeySize
, kCFBooleanTrue
);
2486 require(result
= SecPolicyCreate(kSecPolicyAppleLockdownPairing
,
2487 kSecPolicyNameLockdownPairing
, options
), errOut
);
2490 CFReleaseSafe(options
);
2494 SecPolicyRef
SecPolicyCreateURLBag(void) {
2495 CFMutableDictionaryRef options
= NULL
;
2496 SecPolicyRef result
= NULL
;
2498 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2499 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2501 SecPolicyAddBasicCertOptions(options
);
2503 add_eku(options
, &oidExtendedKeyUsageCodeSigning
);
2505 require(result
= SecPolicyCreate(kSecPolicyAppleURLBag
,
2506 kSecPolicyNameURLBag
, options
), errOut
);
2509 CFReleaseSafe(options
);
2513 SecPolicyRef
SecPolicyCreateOTATasking(void)
2515 CFMutableDictionaryRef options
= NULL
;
2516 SecPolicyRef result
= NULL
;
2518 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2519 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2521 SecPolicyAddBasicX509Options(options
);
2524 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameMobileAsset
), errOut
);
2526 /* Chain length of 3 */
2527 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2529 /* Intermediate has common name "Apple iPhone Certification Authority". */
2530 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2531 CFSTR("Apple iPhone Certification Authority"));
2533 /* Leaf has common name "Asset Manifest Signing" */
2534 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
, CFSTR("OTA Task Signing"));
2536 require(result
= SecPolicyCreate(kSecPolicyAppleOTATasking
, kSecPolicyNameOTATasking
, options
),
2540 CFReleaseSafe(options
);
2544 SecPolicyRef
SecPolicyCreateMobileAsset(void)
2546 CFMutableDictionaryRef options
= NULL
;
2547 SecPolicyRef result
= NULL
;
2549 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2550 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2552 /* No expiration check */
2553 SecPolicyAddBasicCertOptions(options
);
2556 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameMobileAsset
), errOut
);
2558 /* Chain length of 3 */
2559 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2561 /* Intermediate has common name "Apple iPhone Certification Authority". */
2562 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2563 CFSTR("Apple iPhone Certification Authority"));
2565 /* Leaf has common name "Asset Manifest Signing" */
2566 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
, CFSTR("Asset Manifest Signing"));
2568 require(result
= SecPolicyCreate(kSecPolicyAppleMobileAsset
, kSecPolicyNameMobileAsset
, options
),
2572 CFReleaseSafe(options
);
2576 SecPolicyRef
SecPolicyCreateMobileAssetDevelopment(void) {
2577 CFMutableDictionaryRef options
= NULL
;
2578 SecPolicyRef result
= NULL
;
2580 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2581 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2583 /* No expiration check */
2584 SecPolicyAddBasicCertOptions(options
);
2587 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameMobileAsset
), errOut
);
2589 /* Chain length of 3 */
2590 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2592 /* Intermediate has the iPhone CA Marker extension */
2593 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.18"));
2595 /* Leaf has ProdQA Mobile Asset Marker extension */
2596 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.55.1"));
2598 require(result
= SecPolicyCreate(kSecPolicyAppleMobileAssetDevelopment
, kSecPolicyNameMobileAsset
, options
),
2602 CFReleaseSafe(options
);
2606 SecPolicyRef
SecPolicyCreateAppleIDAuthorityPolicy(void)
2608 SecPolicyRef result
= NULL
;
2609 CFMutableDictionaryRef options
= NULL
;
2610 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2611 &kCFTypeDictionaryKeyCallBacks
,
2612 &kCFTypeDictionaryValueCallBacks
), out
);
2614 //Leaf appears to be a SSL only cert, so policy should expand on that policy
2615 SecPolicyAddBasicX509Options(options
);
2617 // Apple CA anchored
2618 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameIDAuthority
), out
);
2620 // with the addition of the existence check of an extension with "Apple ID Sharing Certificate" oid (1.2.840.113635.100.4.7)
2621 // NOTE: this obviously intended to have gone into Extended Key Usage, but evidence of existing certs proves the contrary.
2622 add_leaf_marker(options
, &oidAppleExtendedKeyUsageAppleID
);
2624 // 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.
2625 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleID
);
2626 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleID2
);
2628 require(result
= SecPolicyCreate(kSecPolicyAppleIDAuthority
,
2629 kSecPolicyNameIDAuthority
, options
), out
);
2632 CFReleaseSafe(options
);
2636 SecPolicyRef
SecPolicyCreateMacAppStoreReceipt(void)
2638 SecPolicyRef result
= NULL
;
2639 CFMutableDictionaryRef options
= NULL
;
2640 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2641 &kCFTypeDictionaryKeyCallBacks
,
2642 &kCFTypeDictionaryValueCallBacks
), out
);
2644 SecPolicyAddBasicX509Options(options
);
2646 // Apple CA anchored
2647 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameMacAppStoreReceipt
), out
);
2649 // Chain length of 3
2650 require(SecPolicyAddChainLengthOptions(options
, 3), out
);
2652 // MacAppStoreReceipt policy OID
2653 add_certificate_policy_oid_string(options
, CFSTR("1.2.840.113635.100.5.6.1"));
2655 // Intermediate marker OID
2656 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.1"));
2659 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.11.1"));
2662 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
2664 require(result
= SecPolicyCreate(kSecPolicyMacAppStoreReceipt
,
2665 kSecPolicyNameMacAppStoreReceipt
, options
), out
);
2668 CFReleaseSafe(options
);
2673 static SecPolicyRef
_SecPolicyCreatePassbookCardSigner(CFStringRef cardIssuer
, CFStringRef teamIdentifier
, bool requireTeamID
)
2675 SecPolicyRef result
= NULL
;
2676 CFMutableDictionaryRef options
= NULL
;
2677 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2678 &kCFTypeDictionaryKeyCallBacks
,
2679 &kCFTypeDictionaryValueCallBacks
), out
);
2681 SecPolicyAddBasicX509Options(options
);
2682 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNamePassbookSigning
), out
);
2684 // Chain length of 3
2685 require(SecPolicyAddChainLengthOptions(options
, 3), out
);
2687 if (teamIdentifier
) {
2688 // If supplied, teamIdentifier must match subject OU field
2689 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectOrganizationalUnit
, teamIdentifier
);
2692 // If not supplied, and it was required, fail
2693 require(!requireTeamID
, out
);
2696 // Must be both push and 3rd party package signing
2697 add_leaf_marker_value(options
, &oidAppleInstallerPackagingSigningExternal
, cardIssuer
);
2699 // We should check that it also has push marker, but we don't support requiring both, only either.
2700 // add_independent_oid(options, kSecPolicyCheckLeafMarkerOid, &oidApplePushServiceClient);
2702 //WWDR Intermediate marker OID
2703 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.1"));
2705 // And Passbook signing eku
2706 add_eku(options
, &oidAppleExtendedKeyUsagePassbook
);
2708 require(result
= SecPolicyCreate(kSecPolicyApplePassbookSigning
,
2709 kSecPolicyNamePassbookSigning
, options
), out
);
2712 CFReleaseSafe(options
);
2716 SecPolicyRef
SecPolicyCreatePassbookCardSigner(CFStringRef cardIssuer
, CFStringRef teamIdentifier
)
2718 return _SecPolicyCreatePassbookCardSigner(cardIssuer
, teamIdentifier
, true);
2722 static SecPolicyRef
CreateMobileStoreSigner(Boolean forTest
)
2725 SecPolicyRef result
= NULL
;
2726 CFMutableDictionaryRef options
= NULL
;
2727 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2728 &kCFTypeDictionaryKeyCallBacks
,
2729 &kCFTypeDictionaryValueCallBacks
), errOut
);
2730 SecPolicyAddBasicX509Options(options
);
2731 require(SecPolicyAddAppleAnchorOptions(options
,
2732 ((forTest
) ? kSecPolicyNameTestMobileStore
:
2733 kSecPolicyNameMobileStore
)), errOut
);
2735 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2737 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2738 CFSTR("Apple System Integration 2 Certification Authority"));
2740 add_ku(options
, kSecKeyUsageDigitalSignature
);
2742 const DERItem
* pOID
= (forTest
) ? &oidApplePolicyMobileStoreProdQA
: &oidApplePolicyMobileStore
;
2744 add_certificate_policy_oid(options
, pOID
);
2746 require(result
= SecPolicyCreate((forTest
) ? kSecPolicyAppleTestMobileStore
: kSecPolicyAppleMobileStore
,
2747 (forTest
) ? kSecPolicyNameTestMobileStore
: kSecPolicyNameMobileStore
,
2751 CFReleaseSafe(options
);
2755 SecPolicyRef
SecPolicyCreateMobileStoreSigner(void)
2757 return CreateMobileStoreSigner(false);
2760 SecPolicyRef
SecPolicyCreateTestMobileStoreSigner(void)
2762 return CreateMobileStoreSigner(true);
2766 CF_RETURNS_RETAINED SecPolicyRef
SecPolicyCreateEscrowServiceSigner(void)
2768 SecPolicyRef result
= NULL
;
2769 CFMutableDictionaryRef options
= NULL
;
2770 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2771 &kCFTypeDictionaryKeyCallBacks
,
2772 &kCFTypeDictionaryValueCallBacks
), errOut
);
2774 // X509, ignoring date validity
2775 SecPolicyAddBasicCertOptions(options
);
2777 add_ku(options
, kSecKeyUsageKeyEncipherment
);
2779 /* Leaf has marker OID with value that can't be pre-determined */
2780 add_element(options
, kSecPolicyCheckLeafMarkerOidWithoutValueCheck
, CFSTR("1.2.840.113635.100.6.23.1"));
2781 require(SecPolicyAddChainLengthOptions(options
, 2), errOut
);
2783 require(result
= SecPolicyCreate(kSecPolicyAppleEscrowService
,
2784 kSecPolicyNameEscrowService
, options
), errOut
);
2787 CFReleaseSafe(options
);
2791 CF_RETURNS_RETAINED SecPolicyRef
SecPolicyCreatePCSEscrowServiceSigner(void)
2793 SecPolicyRef result
= NULL
;
2794 CFMutableDictionaryRef options
= NULL
;
2795 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2796 &kCFTypeDictionaryKeyCallBacks
,
2797 &kCFTypeDictionaryValueCallBacks
), errOut
);
2799 SecPolicyAddBasicX509Options(options
);
2800 add_ku(options
, kSecKeyUsageKeyEncipherment
);
2802 /* Leaf has marker OID with value that can't be pre-determined */
2803 add_element(options
, kSecPolicyCheckLeafMarkerOidWithoutValueCheck
, CFSTR("1.2.840.113635.100.6.23.1"));
2804 require(SecPolicyAddChainLengthOptions(options
, 2), errOut
);
2806 require(result
= SecPolicyCreate(kSecPolicyApplePCSEscrowService
,
2807 kSecPolicyNamePCSEscrowService
, options
), errOut
);
2810 CFReleaseSafe(options
);
2814 static SecPolicyRef
CreateConfigurationProfileSigner(bool forTest
) {
2815 SecPolicyRef result
= NULL
;
2816 CFMutableDictionaryRef options
= NULL
;
2817 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2818 &kCFTypeDictionaryKeyCallBacks
,
2819 &kCFTypeDictionaryValueCallBacks
), errOut
);
2821 SecPolicyAddBasicX509Options(options
);
2822 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameProfileSigner
), errOut
);
2825 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2827 // Require the profile signing EKU
2828 const DERItem
* pOID
= (forTest
) ? &oidAppleExtendedKeyUsageQAProfileSigning
:&oidAppleExtendedKeyUsageProfileSigning
;
2829 add_eku(options
, pOID
);
2831 // Require the Apple Application Integration CA marker OID
2832 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.3"));
2834 require(result
= SecPolicyCreate((forTest
) ? kSecPolicyAppleQAProfileSigner
: kSecPolicyAppleProfileSigner
,
2835 (forTest
) ? kSecPolicyNameQAProfileSigner
: kSecPolicyNameProfileSigner
,
2839 CFReleaseSafe(options
);
2843 SecPolicyRef
SecPolicyCreateConfigurationProfileSigner(void)
2845 return CreateConfigurationProfileSigner(false);
2848 SecPolicyRef
SecPolicyCreateQAConfigurationProfileSigner(void)
2850 CFStringRef releaseType
= MGCopyAnswer(kMGQReleaseType
, NULL
);
2851 SecPolicyRef result
= NULL
;
2852 if (releaseType
== NULL
) {
2853 // customer variants do not trust the QA signer
2854 result
= CreateConfigurationProfileSigner(false);
2856 // all other variants (beta, carrier, internal, etc) allow the QA signer
2857 result
= CreateConfigurationProfileSigner(true);
2859 CFReleaseNull(releaseType
);
2863 SecPolicyRef
SecPolicyCreateOSXProvisioningProfileSigning(void)
2865 SecPolicyRef result
= NULL
;
2866 CFMutableDictionaryRef options
= NULL
;
2867 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2868 &kCFTypeDictionaryKeyCallBacks
,
2869 &kCFTypeDictionaryValueCallBacks
), errOut
);
2870 // Require valid chain from the Apple root
2871 SecPolicyAddBasicX509Options(options
);
2872 SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameOSXProvisioningProfileSigning
);
2874 // Require provisioning profile leaf marker OID (1.2.840.113635.100.4.11)
2875 add_leaf_marker(options
, &oidAppleCertExtOSXProvisioningProfileSigning
);
2877 // Require intermediate marker OID (1.2.840.113635.100.6.2.1)
2878 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleWWDR
);
2880 // Require key usage that allows signing
2881 add_ku(options
, kSecKeyUsageDigitalSignature
);
2883 // Ensure that revocation is checked (OCSP)
2884 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationOCSP
);
2886 require(result
= SecPolicyCreate(kSecPolicyAppleOSXProvisioningProfileSigning
,
2887 kSecPolicyNameOSXProvisioningProfileSigning
, options
), errOut
);
2890 CFReleaseSafe(options
);
2895 @function SecPolicyCreateAppleSMPEncryption
2896 @abstract Check for intermediate certificate 'Apple System Integration CA - G3' by name,
2897 and root certificate 'Apple Root CA - G3' by hash.
2898 Leaf cert must have Key Encipherment usage.
2899 Leaf cert must have Apple SMP Encryption marker OID (1.2.840.113635.100.6.30).
2900 Intermediate must have marker OID (1.2.840.113635.100.6.2.13).
2902 SecPolicyRef
SecPolicyCreateAppleSMPEncryption(void)
2904 SecPolicyRef result
= NULL
;
2905 CFMutableDictionaryRef options
= NULL
;
2906 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2907 &kCFTypeDictionaryKeyCallBacks
,
2908 &kCFTypeDictionaryValueCallBacks
), errOut
);
2909 SecPolicyAddBasicCertOptions(options
);
2911 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameSMPEncryption
),
2913 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2915 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2916 CFSTR("Apple System Integration CA - G3"));
2918 // Check that leaf has extension with "Apple SMP Encryption" oid (1.2.840.113635.100.6.30)
2919 add_leaf_marker(options
, &oidAppleCertExtAppleSMPEncryption
);
2921 // Check that intermediate has extension (1.2.840.113635.100.6.2.13)
2922 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleSystemIntgG3
);
2924 add_ku(options
, kSecKeyUsageKeyEncipherment
);
2926 // Ensure that revocation is checked (OCSP)
2927 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationOCSP
);
2929 require(result
= SecPolicyCreate(kSecPolicyAppleSMPEncryption
,
2930 kSecPolicyNameSMPEncryption
, options
), errOut
);
2933 CFReleaseSafe(options
);
2937 /* subject:/CN=Test Apple Root CA - ECC/OU=Certification Authority/O=Apple Inc./C=US */
2938 /* issuer :/CN=Test Apple Root CA - ECC/OU=Certification Authority/O=Apple Inc./C=US */
2939 const uint8_t kTestAppleRootCA_ECC_SHA256
[CC_SHA256_DIGEST_LENGTH
] = {
2940 0xe8, 0x6a, 0xd6, 0x5c, 0x74, 0x60, 0x21, 0x14, 0x47, 0xc6, 0x6a, 0xd7, 0x5f, 0xf8, 0x06, 0x7b,
2941 0xec, 0xb5, 0x52, 0x7e, 0x4e, 0xa1, 0xac, 0x48, 0xcf, 0x3c, 0x53, 0x8f, 0x4d, 0x2b, 0x20, 0xa9
2945 @function SecPolicyCreateTestAppleSMPEncryption
2946 @abstract Check for intermediate certificate 'Test Apple System Integration CA - ECC' by name,
2947 and root certificate 'Test Apple Root CA - ECC' by hash.
2948 Leaf cert must have Key Encipherment usage. Other checks TBD.
2950 SecPolicyRef
SecPolicyCreateTestAppleSMPEncryption(void)
2952 SecPolicyRef result
= NULL
;
2953 CFMutableDictionaryRef options
= NULL
;
2954 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2955 &kCFTypeDictionaryKeyCallBacks
,
2956 &kCFTypeDictionaryValueCallBacks
), errOut
);
2957 SecPolicyAddBasicCertOptions(options
);
2959 SecPolicyAddAnchorSHA256Options(options
, kTestAppleRootCA_ECC_SHA256
);
2960 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2962 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2963 CFSTR("Test Apple System Integration CA - ECC"));
2965 add_ku(options
, kSecKeyUsageKeyEncipherment
);
2967 // Ensure that revocation is checked (OCSP)
2968 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationOCSP
);
2970 require(result
= SecPolicyCreate(kSecPolicyAppleTestSMPEncryption
,
2971 kSecPolicyNameTestSMPEncryption
, options
), errOut
);
2974 CFReleaseSafe(options
);
2979 SecPolicyRef
SecPolicyCreateAppleIDValidationRecordSigningPolicy(void)
2981 SecPolicyRef result
= NULL
;
2982 CFMutableDictionaryRef options
= NULL
;
2983 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2984 &kCFTypeDictionaryKeyCallBacks
,
2985 &kCFTypeDictionaryValueCallBacks
), errOut
);
2987 //Leaf appears to be a SSL only cert, so policy should expand on that policy
2988 SecPolicyAddBasicX509Options(options
);
2990 // Apple CA anchored
2991 require(SecPolicyAddAppleAnchorOptions(options
,
2992 kSecPolicyNameIDValidationRecordSigning
),
2995 // Check for an extension with " Apple ID Validation Record Signing" oid (1.2.840.113635.100.6.25)
2996 add_leaf_marker(options
, &oidAppleCertExtensionAppleIDRecordValidationSigning
);
2998 // and validate that intermediate has extension
2999 // Application Integration Intermediate Certificate (1.2.840.113635.100.6.2.3)
3000 // and also validate that intermediate has extension
3001 // System Integration 2 Intermediate Certificate (1.2.840.113635.100.6.2.10)
3002 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleID
);
3003 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleSystemIntg2
);
3005 // Ensure that revocation is checked (OCSP)
3006 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationOCSP
);
3008 require(result
= SecPolicyCreate(kSecPolicyAppleIDValidationRecordSigning
,
3009 kSecPolicyNameIDValidationRecordSigning
, options
), errOut
);
3012 CFReleaseSafe(options
);
3017 @function SecPolicyCreateAppleServerAuthCommon
3018 @abstract Generic policy for server authentication Sub CAs
3020 Allows control for both if pinning is required at all and if UAT environments should be added
3021 to the trust policy.
3023 No pinning is for developer/QA that needs to use proxy to debug the protocol, while UAT
3024 environment is for QA/internal developer that have no need allow fake servers.
3026 Both the noPinning and UAT are gated on that you run on internal hardware.
3031 SecPolicyCreateAppleServerAuthCommon(CFStringRef hostname
,
3032 CFDictionaryRef __unused context
,
3033 CFStringRef policyOID
, CFStringRef service
,
3034 const DERItem
*leafMarkerOID
,
3035 const DERItem
*UATLeafMarkerOID
)
3037 CFMutableDictionaryRef options
= NULL
;
3038 SecPolicyRef result
= NULL
;
3039 CFDataRef oid
= NULL
, uatoid
= NULL
;
3041 options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0, &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
3042 require(options
, errOut
);
3044 SecPolicyAddBasicX509Options(options
);
3046 require(hostname
, errOut
);
3047 CFDictionaryAddValue(options
, kSecPolicyCheckSSLHostname
, hostname
);
3049 CFDictionaryAddValue(options
, kSecPolicyCheckBlackListedLeaf
, kCFBooleanTrue
);
3050 CFDictionaryAddValue(options
, kSecPolicyCheckGrayListedLeaf
, kCFBooleanTrue
);
3052 add_eku(options
, &oidExtendedKeyUsageServerAuth
);
3054 if (requireUATPinning(service
)) {
3057 * Require pinning to the Apple CA's.
3059 SecPolicyAddAppleAnchorOptions(options
, service
);
3061 /* old-style leaf marker OIDs */
3062 if (UATLeafMarkerOID
) {
3063 add_leaf_prod_qa_markers(options
, leafMarkerOID
, UATLeafMarkerOID
);
3065 add_leaf_marker(options
, leafMarkerOID
);
3068 /* new-style leaf marker OIDs */
3069 CFStringRef leafMarkerOIDStr
= NULL
, UATLeafMarkerOIDStr
= NULL
;
3070 leafMarkerOIDStr
= SecDERItemCopyOIDDecimalRepresentation(NULL
, leafMarkerOID
);
3071 if (UATLeafMarkerOID
) {
3072 UATLeafMarkerOIDStr
= SecDERItemCopyOIDDecimalRepresentation(NULL
, UATLeafMarkerOID
);
3075 if (leafMarkerOIDStr
&& UATLeafMarkerOIDStr
) {
3076 add_leaf_prod_qa_markers_value_string(options
,
3077 CFSTR("1.2.840.113635.100.6.48.1"), leafMarkerOIDStr
,
3078 CFSTR("1.2.840.113635.100.6.48.1"), UATLeafMarkerOIDStr
);
3079 } else if (leafMarkerOIDStr
) {
3080 add_leaf_marker_value_string(options
, CFSTR("1.2.840.113635.100.6.48.1"), leafMarkerOIDStr
);
3083 CFReleaseNull(leafMarkerOIDStr
);
3084 CFReleaseNull(UATLeafMarkerOIDStr
);
3086 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleServerAuthentication
);
3089 /* Check for weak hashes and keys */
3090 require(SecPolicyRemoveWeakHashOptions(options
), errOut
);
3091 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
3093 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
3095 result
= SecPolicyCreate(policyOID
, service
, options
);
3096 require(result
, errOut
);
3099 CFReleaseSafe(options
);
3101 CFReleaseSafe(uatoid
);
3106 @function SecPolicyCreateAppleIDSService
3107 @abstract Ensure we're appropriately pinned to the IDS service (SSL + Apple restrictions)
3109 SecPolicyRef
SecPolicyCreateAppleIDSService(CFStringRef hostname
)
3111 return SecPolicyCreateAppleServerAuthCommon(hostname
, NULL
, kSecPolicyAppleIDSService
,
3112 kSecPolicyNameAppleIDSBag
,
3113 &oidAppleCertExtAppleServerAuthenticationIDSProd
,
3114 &oidAppleCertExtAppleServerAuthenticationIDSProdQA
);
3118 @function SecPolicyCreateAppleIDSService
3119 @abstract Ensure we're appropriately pinned to the IDS service (SSL + Apple restrictions)
3121 SecPolicyRef
SecPolicyCreateAppleIDSServiceContext(CFStringRef hostname
, CFDictionaryRef context
)
3123 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyAppleIDSServiceContext
,
3124 kSecPolicyNameAppleIDSService
,
3125 &oidAppleCertExtAppleServerAuthenticationIDSProd
,
3126 &oidAppleCertExtAppleServerAuthenticationIDSProdQA
);
3130 @function SecPolicyCreateAppleGSService
3131 @abstract Ensure we're appropriately pinned to the GS service
3133 SecPolicyRef
SecPolicyCreateAppleGSService(CFStringRef hostname
, CFDictionaryRef context
)
3135 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyAppleGSService
,
3136 kSecPolicyNameAppleGSService
,
3137 &oidAppleCertExtAppleServerAuthenticationGS
,
3142 @function SecPolicyCreateApplePushService
3143 @abstract Ensure we're appropriately pinned to the Push service (SSL + Apple restrictions)
3145 SecPolicyRef
SecPolicyCreateApplePushService(CFStringRef hostname
, CFDictionaryRef context
)
3147 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyApplePushService
,
3148 kSecPolicyNameApplePushService
,
3149 &oidAppleCertExtAppleServerAuthenticationAPNProd
,
3150 &oidAppleCertExtAppleServerAuthenticationAPNProdQA
);
3154 @function SecPolicyCreateApplePPQService
3155 @abstract Ensure we're appropriately pinned to the PPQ service (SSL + Apple restrictions)
3157 SecPolicyRef
SecPolicyCreateApplePPQService(CFStringRef hostname
, CFDictionaryRef context
)
3159 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyApplePPQService
,
3160 kSecPolicyNameApplePPQService
,
3161 &oidAppleCertExtAppleServerAuthenticationPPQProd
,
3162 &oidAppleCertExtAppleServerAuthenticationPPQProdQA
);
3166 @function SecPolicyCreateAppleAST2Service
3167 @abstract Ensure we're appropriately pinned to the AST2 Diagnostic service (SSL + Apple restrictions)
3169 SecPolicyRef
SecPolicyCreateAppleAST2Service(CFStringRef hostname
, CFDictionaryRef context
)
3171 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyAppleAST2DiagnosticsServerAuth
,
3172 kSecPolicyNameAppleAST2Service
,
3173 &oidAppleCertExtAST2DiagnosticsServerAuthProd
,
3174 &oidAppleCertExtAST2DiagnosticsServerAuthProdQA
);
3178 @function SecPolicyCreateAppleEscrowProxyService
3179 @abstract Ensure we're appropriately pinned to the iCloud Escrow Proxy service (SSL + Apple restrictions)
3181 SecPolicyRef
SecPolicyCreateAppleEscrowProxyService(CFStringRef hostname
, CFDictionaryRef context
)
3183 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyAppleEscrowProxyServerAuth
,
3184 kSecPolicyNameAppleEscrowProxyService
,
3185 &oidAppleCertExtEscrowProxyServerAuthProd
,
3186 &oidAppleCertExtEscrowProxyServerAuthProdQA
);
3189 /* subject:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA */
3190 /* SKID: C0:7A:98:68:8D:89:FB:AB:05:64:0C:11:7D:AA:7D:65:B8:CA:CC:4E */
3191 /* Not Before: May 21 04:00:00 2002 GMT, Not After : May 21 04:00:00 2022 GMT */
3192 /* Signature Algorithm: sha1WithRSAEncryption */
3193 unsigned char GeoTrust_Global_CA_sha256
[kSecPolicySHA256Size
] = {
3194 0xff, 0x85, 0x6a, 0x2d, 0x25, 0x1d, 0xcd, 0x88, 0xd3, 0x66, 0x56, 0xf4, 0x50, 0x12, 0x67, 0x98,
3195 0xcf, 0xab, 0xaa, 0xde, 0x40, 0x79, 0x9c, 0x72, 0x2d, 0xe4, 0xd2, 0xb5, 0xdb, 0x36, 0xa7, 0x3a
3198 static SecPolicyRef
SecPolicyCreateAppleGeoTrustServerAuthCommon(CFStringRef hostname
, CFStringRef policyOid
,
3199 CFStringRef policyName
,
3200 CFStringRef leafMarkerOid
,
3201 CFStringRef qaLeafMarkerOid
) {
3202 CFMutableDictionaryRef options
= NULL
;
3203 CFDataRef spkiDigest
= NULL
;
3204 SecPolicyRef result
= NULL
;
3206 require(options
= CFDictionaryCreateMutable(NULL
, 0, &kCFTypeDictionaryKeyCallBacks
,
3207 &kCFTypeDictionaryValueCallBacks
), errOut
);
3210 SecPolicyAddBasicX509Options(options
);
3212 require(hostname
, errOut
);
3213 CFDictionaryAddValue(options
, kSecPolicyCheckSSLHostname
, hostname
);
3215 add_eku(options
, &oidExtendedKeyUsageServerAuth
);
3218 if (requireUATPinning(policyName
)) {
3220 SecPolicyAddAnchorSHA256Options(options
, GeoTrust_Global_CA_sha256
);
3222 /* Issued to Apple Inc. in the US */
3223 add_element(options
, kSecPolicyCheckIntermediateCountry
, CFSTR("US"));
3224 add_element(options
, kSecPolicyCheckIntermediateOrganization
, CFSTR("Apple Inc."));
3226 require_action(SecPolicyAddChainLengthOptions(options
, 3), errOut
, CFReleaseNull(result
));
3228 /* Marker OIDs in both formats */
3229 if (qaLeafMarkerOid
) {
3230 add_leaf_prod_qa_markers_string(options
, leafMarkerOid
, qaLeafMarkerOid
);
3231 add_leaf_prod_qa_markers_value_string(options
,
3232 CFSTR("1.2.840.113635.100.6.48.1"), leafMarkerOid
,
3233 CFSTR("1.2.840.113635.100.6.48.1"), qaLeafMarkerOid
);
3235 add_leaf_marker_string(options
, leafMarkerOid
);
3236 add_leaf_marker_value_string(options
, CFSTR("1.2.840.113635.100.6.48.1"), leafMarkerOid
);
3240 /* Check for weak hashes */
3241 require(SecPolicyRemoveWeakHashOptions(options
), errOut
);
3242 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
3244 /* See <rdar://25344801> for more details */
3246 result
= SecPolicyCreate(policyOid
, policyName
, options
);
3249 CFReleaseSafe(options
);
3250 CFReleaseSafe(spkiDigest
);
3254 SecPolicyRef
SecPolicyCreateAppleCompatibilityEscrowProxyService(CFStringRef hostname
) {
3255 return SecPolicyCreateAppleGeoTrustServerAuthCommon(hostname
, kSecPolicyAppleEscrowProxyCompatibilityServerAuth
,
3256 kSecPolicyNameAppleEscrowProxyService
,
3257 CFSTR("1.2.840.113635.100.6.27.7.2"),
3258 CFSTR("1.2.840.113635.100.6.27.7.1"));
3262 @function SecPolicyCreateAppleFMiPService
3263 @abstract Ensure we're appropriately pinned to the Find My iPhone service (SSL + Apple restrictions)
3265 SecPolicyRef
SecPolicyCreateAppleFMiPService(CFStringRef hostname
, CFDictionaryRef context
)
3267 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyAppleFMiPServerAuth
,
3268 kSecPolicyNameAppleFMiPService
,
3269 &oidAppleCertExtFMiPServerAuthProd
,
3270 &oidAppleCertExtFMiPServerAuthProdQA
);
3274 /* should use verbatim copy, but since this is the deprecated way, don't care right now */
3275 static const UInt8 entrustSPKIL1C
[kSecPolicySHA256Size
] = {
3276 0x54, 0x5b, 0xf9, 0x35, 0xe9, 0xad, 0xa1, 0xda,
3277 0x11, 0x7e, 0xdc, 0x3c, 0x2a, 0xcb, 0xc5, 0x6f,
3278 0xc0, 0x28, 0x09, 0x6c, 0x0e, 0x24, 0xbe, 0x9b,
3279 0x38, 0x94, 0xbe, 0x52, 0x2d, 0x1b, 0x43, 0xde
3283 @function SecPolicyCreateApplePushServiceLegacy
3284 @abstract Ensure we're appropriately pinned to the Push service (via Entrust)
3286 SecPolicyRef
SecPolicyCreateApplePushServiceLegacy(CFStringRef hostname
)
3288 CFMutableDictionaryRef options
= NULL
;
3289 SecPolicyRef result
= NULL
;
3290 CFDataRef digest
= NULL
;
3292 digest
= CFDataCreateWithBytesNoCopy(kCFAllocatorDefault
, entrustSPKIL1C
, sizeof(entrustSPKIL1C
), kCFAllocatorNull
);
3293 require(digest
, errOut
);
3295 options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0, &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
3296 require(options
, errOut
);
3298 SecPolicyAddBasicX509Options(options
);
3300 CFDictionaryAddValue(options
, kSecPolicyCheckSSLHostname
, hostname
);
3302 CFDictionaryAddValue(options
, kSecPolicyCheckBlackListedLeaf
, kCFBooleanTrue
);
3303 CFDictionaryAddValue(options
, kSecPolicyCheckGrayListedLeaf
, kCFBooleanTrue
);
3305 CFDictionaryAddValue(options
, kSecPolicyCheckIntermediateSPKISHA256
, digest
);
3307 add_eku(options
, &oidExtendedKeyUsageServerAuth
);
3309 /* Check for weak hashes and keys */
3310 require(SecPolicyRemoveWeakHashOptions(options
), errOut
);
3311 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
3313 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
3315 result
= SecPolicyCreate(kSecPolicyAppleLegacyPushService
,
3316 kSecPolicyNameLegacyPushService
, options
);
3317 require(result
, errOut
);
3320 CFReleaseSafe(digest
);
3321 CFReleaseSafe(options
);
3326 @function SecPolicyCreateAppleMMCSService
3327 @abstract Ensure we're appropriately pinned to the IDS service (SSL + Apple restrictions)
3329 SecPolicyRef
SecPolicyCreateAppleMMCSService(CFStringRef hostname
, CFDictionaryRef context
)
3331 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyAppleMMCService
,
3332 kSecPolicyNameAppleMMCSService
,
3333 &oidAppleCertExtAppleServerAuthenticationMMCSProd
,
3334 &oidAppleCertExtAppleServerAuthenticationMMCSProdQA
);
3337 SecPolicyRef
SecPolicyCreateAppleCompatibilityMMCSService(CFStringRef hostname
) {
3338 return SecPolicyCreateAppleGeoTrustServerAuthCommon(hostname
, kSecPolicyAppleMMCSCompatibilityServerAuth
,
3339 kSecPolicyNameAppleMMCSService
,
3340 CFSTR("1.2.840.113635.100.6.27.11.2"),
3341 CFSTR("1.2.840.113635.100.6.27.11.1"));
3345 SecPolicyRef
SecPolicyCreateAppleiCloudSetupService(CFStringRef hostname
, CFDictionaryRef context
)
3347 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyAppleiCloudSetupServerAuth
,
3348 kSecPolicyNameAppleiCloudSetupService
,
3349 &oidAppleCertExtAppleServerAuthenticationiCloudSetupProd
,
3350 &oidAppleCertExtAppleServerAuthenticationiCloudSetupProdQA
);
3353 SecPolicyRef
SecPolicyCreateAppleCompatibilityiCloudSetupService(CFStringRef hostname
)
3355 return SecPolicyCreateAppleGeoTrustServerAuthCommon(hostname
, kSecPolicyAppleiCloudSetupCompatibilityServerAuth
,
3356 kSecPolicyNameAppleiCloudSetupService
,
3357 CFSTR("1.2.840.113635.100.6.27.15.2"),
3358 CFSTR("1.2.840.113635.100.6.27.15.1"));
3362 @function SecPolicyCreateAppleSSLService
3363 @abstract Ensure we're appropriately pinned to an Apple server (SSL + Apple restrictions)
3365 SecPolicyRef
SecPolicyCreateAppleSSLService(CFStringRef hostname
)
3367 // SSL server, pinned to an Apple intermediate
3368 SecPolicyRef policy
= SecPolicyCreateSSL(true, hostname
);
3369 CFMutableDictionaryRef options
= NULL
;
3370 require(policy
, errOut
);
3372 // change options for SSL policy evaluation
3373 require((options
=(CFMutableDictionaryRef
)policy
->_options
) != NULL
, errOut
);
3375 // Apple CA anchored
3376 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameServerAuthentication
), errOut
);
3378 // Check leaf for Apple Server Authentication marker oid (1.2.840.113635.100.6.27.1)
3379 add_leaf_marker(options
, &oidAppleCertExtAppleServerAuthentication
);
3381 // Check intermediate for Apple Server Authentication intermediate marker (1.2.840.113635.100.6.2.12)
3382 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleServerAuthentication
);
3384 /* Check for weak hashes */
3385 require(SecPolicyRemoveWeakHashOptions(options
), errOut
);
3387 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
3389 SecPolicySetOid(policy
, kSecPolicyAppleServerAuthentication
);
3390 SecPolicySetName(policy
, kSecPolicyNameServerAuthentication
);
3395 CFReleaseSafe(options
);
3396 CFReleaseSafe(policy
);
3401 @function SecPolicyCreateApplePPQSigning
3402 @abstract Check for intermediate certificate 'Apple System Integration 2 Certification Authority' by name,
3404 Leaf cert must have Digital Signature usage.
3405 Leaf cert must have Apple PPQ Signing marker OID (1.2.840.113635.100.6.38.2).
3406 Intermediate must have marker OID (1.2.840.113635.100.6.2.10).
3408 SecPolicyRef
SecPolicyCreateApplePPQSigning(void)
3410 SecPolicyRef result
= NULL
;
3411 CFMutableDictionaryRef options
= NULL
;
3412 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3413 &kCFTypeDictionaryKeyCallBacks
,
3414 &kCFTypeDictionaryValueCallBacks
), errOut
);
3415 SecPolicyAddBasicCertOptions(options
);
3417 SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNamePPQSigning
);
3418 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3420 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
3421 CFSTR("Apple System Integration 2 Certification Authority"));
3423 // Check that leaf has extension with "Apple PPQ Signing" prod oid (1.2.840.113635.100.6.38.2)
3424 add_leaf_marker(options
, &oidAppleCertExtApplePPQSigningProd
);
3426 // Check that intermediate has extension (1.2.840.113635.100.6.2.10)
3427 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleSystemIntg2
);
3429 add_ku(options
, kSecKeyUsageDigitalSignature
);
3431 require(result
= SecPolicyCreate(kSecPolicyApplePPQSigning
,
3432 kSecPolicyNamePPQSigning
, options
), errOut
);
3435 CFReleaseSafe(options
);
3440 @function SecPolicyCreateTestApplePPQSigning
3441 @abstract Check for intermediate certificate 'Apple System Integration 2 Certification Authority' by name,
3443 Leaf cert must have Digital Signature usage.
3444 Leaf cert must have Apple PPQ Signing Test marker OID (1.2.840.113635.100.6.38.1).
3445 Intermediate must have marker OID (1.2.840.113635.100.6.2.10).
3447 SecPolicyRef
SecPolicyCreateTestApplePPQSigning(void)
3449 /* Guard against use of test policy on production devices */
3450 if (!SecIsInternalRelease()) {
3451 return SecPolicyCreateApplePPQSigning();
3454 SecPolicyRef result
= NULL
;
3455 CFMutableDictionaryRef options
= NULL
;
3456 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3457 &kCFTypeDictionaryKeyCallBacks
,
3458 &kCFTypeDictionaryValueCallBacks
), errOut
);
3459 SecPolicyAddBasicCertOptions(options
);
3461 SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameTestPPQSigning
);
3462 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3464 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
3465 CFSTR("Apple System Integration 2 Certification Authority"));
3467 // Check that leaf has extension with "Apple PPQ Signing" test oid (1.2.840.113635.100.6.38.1)
3468 add_leaf_marker(options
, &oidAppleCertExtApplePPQSigningProdQA
);
3470 // Check that intermediate has extension (1.2.840.113635.100.6.2.10)
3471 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleSystemIntg2
);
3473 add_ku(options
, kSecKeyUsageDigitalSignature
);
3475 require(result
= SecPolicyCreate(kSecPolicyAppleTestPPQSigning
,
3476 kSecPolicyNameTestPPQSigning
, options
), errOut
);
3479 CFReleaseSafe(options
);
3483 @function SecPolicyCreateAppleTimeStamping
3484 @abstract Check for RFC3161 timestamping EKU.
3486 SecPolicyRef
SecPolicyCreateAppleTimeStamping(void)
3488 SecPolicyRef result
= NULL
;
3489 CFMutableDictionaryRef options
= NULL
;
3490 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3491 &kCFTypeDictionaryKeyCallBacks
,
3492 &kCFTypeDictionaryValueCallBacks
), errOut
);
3494 SecPolicyAddBasicX509Options(options
);
3496 /* Require id-kp-timeStamping extendedKeyUsage to be present. */
3497 add_eku(options
, &oidExtendedKeyUsageTimeStamping
);
3499 require(result
= SecPolicyCreate(kSecPolicyAppleTimeStamping
,
3500 kSecPolicyNameTimeStamping
, options
), errOut
);
3503 CFReleaseSafe(options
);
3508 @function SecPolicyCreateApplePayIssuerEncryption
3509 @abstract Check for intermediate certificate 'Apple Worldwide Developer Relations CA - G2' by name,
3510 and ECC apple anchor.
3511 Leaf cert must have Key Encipherment and Key Agreement usage.
3512 Leaf cert must have Apple Pay Issuer Encryption marker OID (1.2.840.113635.100.6.39).
3514 SecPolicyRef
SecPolicyCreateApplePayIssuerEncryption(void)
3516 SecPolicyRef result
= NULL
;
3517 CFMutableDictionaryRef options
= NULL
;
3518 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3519 &kCFTypeDictionaryKeyCallBacks
,
3520 &kCFTypeDictionaryValueCallBacks
), errOut
);
3521 SecPolicyAddBasicCertOptions(options
);
3523 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNamePayIssuerEncryption
),
3525 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3527 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
3528 CFSTR("Apple Worldwide Developer Relations CA - G2"));
3530 // Check that leaf has extension with "Apple Pay Issuer Encryption" oid (1.2.840.113635.100.6.39)
3531 add_leaf_marker(options
, &oidAppleCertExtCryptoServicesExtEncryption
);
3533 add_ku(options
, kSecKeyUsageKeyEncipherment
);
3535 require(result
= SecPolicyCreate(kSecPolicyApplePayIssuerEncryption
,
3536 kSecPolicyNamePayIssuerEncryption
, options
), errOut
);
3539 CFReleaseSafe(options
);
3544 @function SecPolicyCreateAppleATVVPNProfileSigning
3545 @abstract Check for leaf marker OID 1.2.840.113635.100.6.43,
3546 intermediate marker OID 1.2.840.113635.100.6.2.10,
3547 chains to Apple Root CA, path length 3
3549 SecPolicyRef
SecPolicyCreateAppleATVVPNProfileSigning(void)
3551 SecPolicyRef result
= NULL
;
3552 CFMutableDictionaryRef options
= NULL
;
3553 CFMutableDictionaryRef appleAnchorOptions
= NULL
;
3554 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3555 &kCFTypeDictionaryKeyCallBacks
,
3556 &kCFTypeDictionaryValueCallBacks
), errOut
);
3558 SecPolicyAddBasicCertOptions(options
);
3560 // Require pinning to the Apple CAs (including test CA for internal releases)
3561 appleAnchorOptions
= CFDictionaryCreateMutableForCFTypes(NULL
);
3562 require(appleAnchorOptions
, errOut
);
3564 if (SecIsInternalRelease()) {
3565 CFDictionarySetValue(appleAnchorOptions
,
3566 kSecPolicyAppleAnchorIncludeTestRoots
, kCFBooleanTrue
);
3569 add_element(options
, kSecPolicyCheckAnchorApple
, appleAnchorOptions
);
3571 // Cert chain length 3
3572 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3574 // Check leaf for Apple ATV VPN Profile Signing OID (1.2.840.113635.100.6.43)
3575 add_leaf_marker(options
, &oidAppleCertExtATVVPNProfileSigning
);
3577 // Check intermediate for Apple System Integration 2 CA intermediate marker (1.2.840.113635.100.6.2.10)
3578 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleSystemIntg2
);
3580 // Ensure that revocation is checked (OCSP only)
3581 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationOCSP
);
3583 require(result
= SecPolicyCreate(kSecPolicyAppleATVVPNProfileSigning
,
3584 kSecPolicyNameATVVPNProfileSigning
, options
), errOut
);
3587 CFReleaseSafe(options
);
3588 CFReleaseSafe(appleAnchorOptions
);
3592 SecPolicyRef
SecPolicyCreateAppleHomeKitServerAuth(CFStringRef hostname
) {
3593 CFMutableDictionaryRef options
= NULL
;
3594 SecPolicyRef result
= NULL
;
3595 CFDataRef oid
= NULL
;
3597 options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0, &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
3598 require(options
, errOut
);
3600 SecPolicyAddBasicX509Options(options
);
3602 CFDictionaryAddValue(options
, kSecPolicyCheckSSLHostname
, hostname
);
3604 add_eku(options
, &oidExtendedKeyUsageServerAuth
);
3606 if (requireUATPinning(kSecPolicyNameAppleHomeKitService
)) {
3608 // Cert chain length 3
3609 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3611 // Apple anchors, allowing test anchors for internal release
3612 SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameAppleHomeKitService
);
3614 add_leaf_marker(options
, &oidAppleCertExtHomeKitServerAuth
);
3616 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleHomeKitServerCA
);
3619 /* Check for weak hashes */
3620 require(SecPolicyRemoveWeakHashOptions(options
), errOut
);
3621 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
3623 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
3625 result
= SecPolicyCreate(kSecPolicyAppleHomeKitServerAuth
,
3626 kSecPolicyNameAppleHomeKitService
, options
);
3627 require(result
, errOut
);
3630 CFReleaseSafe(options
);
3635 SecPolicyRef
SecPolicyCreateAppleExternalDeveloper(void) {
3636 CFMutableDictionaryRef options
= NULL
;
3637 SecPolicyRef result
= NULL
;
3639 /* Create basic Apple pinned policy */
3640 require(result
= SecPolicyCreateApplePinned(kSecPolicyNameExternalDeveloper
,
3641 CFSTR("1.2.840.113635.100.6.2.1"), // WWDR Intermediate OID
3642 CFSTR("1.2.840.113635.100.6.1.2")), // "iPhone Developer" leaf OID
3645 require_action(options
= CFDictionaryCreateMutableCopy(NULL
, 0, result
->_options
), errOut
, CFReleaseNull(result
));
3647 /* Additional intermediate OIDs */
3648 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
,
3649 CFSTR("1.2.840.113635.100.6.2.6")); // "Developer ID" Intermediate OID
3651 /* Addtional leaf OIDS */
3652 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.4")); // "iPhone Distribution" leaf OID
3653 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.5")); // "Safari Developer" leaf OID
3654 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.7")); // "3rd Party Mac Developer Application" leaf OID
3655 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.8")); // "3rd Party Mac Developer Installer" leaf OID
3656 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.12")); // "Mac Developer" leaf OID
3657 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.13")); // "Developer ID Application" leaf OID
3658 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.14")); // "Developer ID Installer" leaf OID
3661 add_eku_string(options
, CFSTR("1.3.6.1.5.5.7.3.3")); // CodeSigning EKU
3662 add_eku_string(options
, CFSTR("1.2.840.113635.100.4.8")); // "Safari Developer" EKU
3663 add_eku_string(options
, CFSTR("1.2.840.113635.100.4.9")); // "3rd Party Mac Developer Installer" EKU
3664 add_eku_string(options
, CFSTR("1.2.840.113635.100.4.13")); // "Developer ID Installer" EKU
3666 CFReleaseSafe(result
->_options
);
3667 result
->_options
= CFRetainSafe(options
);
3669 SecPolicySetOid(result
, kSecPolicyAppleExternalDeveloper
);
3672 CFReleaseSafe(options
);
3676 /* This one is special because the intermediate has no marker OID */
3677 SecPolicyRef
SecPolicyCreateAppleSoftwareSigning(void) {
3678 CFMutableDictionaryRef options
= NULL
;
3679 SecPolicyRef result
= NULL
;
3681 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3682 &kCFTypeDictionaryKeyCallBacks
,
3683 &kCFTypeDictionaryValueCallBacks
), errOut
);
3685 SecPolicyAddBasicCertOptions(options
);
3687 /* Anchored to the Apple Roots */
3688 require_quiet(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameSoftwareSigning
),
3691 /* Exactly 3 certs in the chain */
3692 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3694 /* Intermediate Common Name matches */
3695 add_element(options
, kSecPolicyCheckIssuerCommonName
, CFSTR("Apple Code Signing Certification Authority"));
3697 /* Leaf marker OID matches */
3698 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.22"));
3700 /* Leaf has CodeSigning EKU */
3701 add_eku_string(options
, CFSTR("1.3.6.1.5.5.7.3.3"));
3703 /* Check revocation using any available method */
3704 add_element(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
3706 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
3707 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
3709 require(result
= SecPolicyCreate(kSecPolicyAppleSoftwareSigning
,
3710 kSecPolicyNameSoftwareSigning
, options
), errOut
);
3713 CFReleaseSafe(options
);
3717 /* subject:/CN=SEP Root CA/O=Apple Inc./ST=California */
3718 /* SKID: 58:EF:D6:BE:C5:82:B0:54:CD:18:A6:84:AD:A2:F6:7B:7B:3A:7F:CF */
3719 /* Not Before: Jun 24 21:43:24 2014 GMT, Not After : Jun 24 21:43:24 2029 GMT */
3720 /* Signature Algorithm: ecdsa-with-SHA384 */
3721 const uint8_t SEPRootCA_SHA256
[kSecPolicySHA256Size
] = {
3722 0xd1, 0xdf, 0x82, 0x00, 0xf3, 0x89, 0x4e, 0xe9, 0x96, 0xf3, 0x77, 0xdf, 0x76, 0x3b, 0x0a, 0x16,
3723 0x8f, 0xd9, 0x6c, 0x58, 0xc0, 0x3e, 0xc9, 0xb0, 0x5f, 0xa5, 0x64, 0x79, 0xc0, 0xe8, 0xc9, 0xe7
3726 SecPolicyRef
SecPolicyCreateAppleUniqueDeviceCertificate(CFDataRef testRootHash
) {
3727 CFMutableDictionaryRef options
= NULL
;
3728 CFDictionaryRef keySizes
= NULL
;
3729 CFNumberRef ecSize
= NULL
;
3730 SecPolicyRef result
= NULL
;
3732 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3733 &kCFTypeDictionaryKeyCallBacks
,
3734 &kCFTypeDictionaryValueCallBacks
), errOut
);
3736 /* Device certificate should never expire */
3737 SecPolicyAddBasicCertOptions(options
);
3739 /* Anchored to the SEP Root CA. Allow alternative root for developers */
3740 require(SecPolicyAddAnchorSHA256Options(options
, SEPRootCA_SHA256
),errOut
);
3741 if (testRootHash
&& SecIsInternalRelease() && (kSecPolicySHA256Size
== CFDataGetLength(testRootHash
))) {
3742 add_element(options
, kSecPolicyCheckAnchorSHA256
, testRootHash
);
3745 /* Exactly 3 certs in the chain */
3746 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3748 /* Intermediate has marker OID with value */
3749 add_intermediate_marker_value_string(options
, CFSTR("1.2.840.113635.100.6.44"), CFSTR("ucrt"));
3751 /* Leaf has marker OID with varying value that can't be pre-determined */
3752 add_element(options
, kSecPolicyCheckLeafMarkerOidWithoutValueCheck
, CFSTR("1.2.840.113635.100.10.1"));
3754 /* RSA key sizes are disallowed. EC key sizes are P-256 or larger. */
3755 require(ecSize
= CFNumberCreateWithCFIndex(NULL
, 256), errOut
);
3756 require(keySizes
= CFDictionaryCreate(NULL
, (const void**)&kSecAttrKeyTypeEC
,
3757 (const void**)&ecSize
, 1,
3758 &kCFTypeDictionaryKeyCallBacks
,
3759 &kCFTypeDictionaryValueCallBacks
), errOut
);
3760 add_element(options
, kSecPolicyCheckKeySize
, keySizes
);
3763 require(result
= SecPolicyCreate(kSecPolicyAppleUniqueDeviceIdentifierCertificate
,
3764 kSecPolicyNameUniqueDeviceIdentifierCertificate
, options
), errOut
);
3767 CFReleaseSafe(options
);
3768 CFReleaseSafe(keySizes
);
3769 CFReleaseSafe(ecSize
);
3773 SecPolicyRef
SecPolicyCreateAppleWarsaw(void) {
3774 CFMutableDictionaryRef options
= NULL
;
3775 SecPolicyRef result
= NULL
;
3777 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3778 &kCFTypeDictionaryKeyCallBacks
,
3779 &kCFTypeDictionaryValueCallBacks
), errOut
);
3781 SecPolicyAddBasicX509Options(options
);
3783 /* Anchored to the Apple Roots. */
3784 require_quiet(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameWarsaw
),
3787 /* Exactly 3 certs in the chain */
3788 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3790 /* Intermediate marker OID matches input OID */
3791 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.14"));
3793 /* Leaf marker OID matches input OID */
3794 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.29"));
3796 /* Check revocation using any available method */
3797 add_element(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
3799 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
3800 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
3802 require(result
= SecPolicyCreate(kSecPolicyAppleWarsaw
,
3803 kSecPolicyNameWarsaw
, options
), errOut
);
3806 CFReleaseSafe(options
);
3810 SecPolicyRef
SecPolicyCreateAppleSecureIOStaticAsset(void) {
3811 CFMutableDictionaryRef options
= NULL
;
3812 SecPolicyRef result
= NULL
;
3813 #if TARGET_OS_BRIDGE
3814 CFMutableDictionaryRef appleAnchorOptions
= NULL
;
3817 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3818 &kCFTypeDictionaryKeyCallBacks
,
3819 &kCFTypeDictionaryValueCallBacks
), errOut
);
3821 /* This certificate cannot expire so that assets always load */
3822 SecPolicyAddBasicCertOptions(options
);
3824 /* Anchored to the Apple Roots. */
3825 #if TARGET_OS_BRIDGE
3826 /* On the bridge, test roots are gated in the trust and policy servers. */
3827 require_quiet(appleAnchorOptions
= CFDictionaryCreateMutableForCFTypes(NULL
), errOut
);
3828 CFDictionarySetValue(appleAnchorOptions
,
3829 kSecPolicyAppleAnchorIncludeTestRoots
, kCFBooleanTrue
);
3830 add_element(options
, kSecPolicyCheckAnchorApple
, appleAnchorOptions
);
3831 CFReleaseSafe(appleAnchorOptions
);
3833 require_quiet(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameSecureIOStaticAsset
),
3837 /* Exactly 3 certs in the chain */
3838 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3840 /* Intermediate marker OID matches ASI CA */
3841 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.10"));
3843 /* Leaf marker OID matches static IO OID */
3844 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.50"));
3846 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
3847 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
3849 require(result
= SecPolicyCreate(kSecPolicyAppleSecureIOStaticAsset
,
3850 kSecPolicyNameSecureIOStaticAsset
, options
), errOut
);
3853 CFReleaseSafe(options
);
3857 SecPolicyRef
SecPolicyCreateAppleAppTransportSecurity(void) {
3858 CFMutableDictionaryRef options
= NULL
;
3859 SecPolicyRef result
= NULL
;
3860 CFMutableArrayRef disallowedHashes
= NULL
;
3862 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3863 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
3865 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
3866 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
3868 /* Hash algorithm is SHA-256 or better */
3869 require(disallowedHashes
= CFArrayCreateMutable(NULL
, 5, &kCFTypeArrayCallBacks
), errOut
);
3870 CFArrayAppendValue(disallowedHashes
, kSecSignatureDigestAlgorithmMD2
);
3871 CFArrayAppendValue(disallowedHashes
, kSecSignatureDigestAlgorithmMD4
);
3872 CFArrayAppendValue(disallowedHashes
, kSecSignatureDigestAlgorithmMD5
);
3873 CFArrayAppendValue(disallowedHashes
, kSecSignatureDigestAlgorithmSHA1
);
3874 CFArrayAppendValue(disallowedHashes
, kSecSignatureDigestAlgorithmSHA224
);
3876 add_element(options
, kSecPolicyCheckSignatureHashAlgorithms
, disallowedHashes
);
3878 require_quiet(result
= SecPolicyCreate(kSecPolicyAppleAppTransportSecurity
,
3879 kSecPolicyNameAppTransportSecurity
,
3883 CFReleaseSafe(options
);
3887 SecPolicyRef
SecPolicyCreateMobileSoftwareUpdate(void) {
3888 CFMutableDictionaryRef options
= NULL
;
3889 SecPolicyRef result
= NULL
;
3891 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3892 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
3894 /* No expiration check. */
3895 SecPolicyAddBasicCertOptions(options
);
3898 require_quiet(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameMobileSoftwareUpdate
),
3901 /* Exactly 3 certs in the chain */
3902 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3904 /* Intermediate marker OID is iPhone CA OID */
3905 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.18"));
3907 /* Leaf marker OID is either the prod MSU OID, or, on internal builds, the prodQA OID */
3908 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.57.2"));
3909 if (SecIsInternalRelease()) {
3910 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.57.1"));
3913 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
3914 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
3916 require(result
= SecPolicyCreate(kSecPolicyAppleMobileSoftwareUpdate
,
3917 kSecPolicyNameMobileSoftwareUpdate
, options
), errOut
);
3920 CFReleaseNull(options
);
3924 /* subject:/CN=Basic Attestation System Root CA/O=Apple Inc./ST=California */
3925 /* SKID: FE:D1:D1:C2:08:07:03:D5:B9:3C:34:B2:BB:FD:7C:3A:99:25:1B:8F */
3926 /* Not Before: Apr 20 00:22:09 2017 GMT, Not After : Mar 22 00:00:00 2032 GMT */
3927 /* Signature Algorithm: ecdsa-with-SHA384 */
3928 const uint8_t BASystemRootCA_SHA256
[kSecPolicySHA256Size
] = {
3929 0x10, 0xD3, 0xC8, 0x67, 0xF0, 0xAE, 0xFB, 0x24, 0x31, 0xA0, 0xA9, 0x7A, 0x88, 0x18, 0xBD, 0x64,
3930 0xF7, 0xF9, 0x0F, 0xFE, 0x11, 0x94, 0x48, 0x4F, 0xCA, 0x97, 0xF0, 0xF2, 0x9E, 0xCA, 0x00, 0x47
3933 /* subject:/CN=Basic Attestation User Root CA/O=Apple Inc./ST=California */
3934 /* SKID: 83:E5:A3:21:9E:B0:74:C3:F9:61:90:FD:97:4E:23:10:76:A4:A3:F2 */
3935 /* Not Before: Apr 19 21:41:56 2017 GMT, Not After : Mar 22 00:00:00 2032 GMT */
3936 /* Signature Algorithm: ecdsa-with-SHA384 */
3937 const uint8_t BAUserRootCA_SHA256
[kSecPolicySHA256Size
] = {
3938 0x03, 0x75, 0x1c, 0x80, 0xfc, 0xbe, 0x58, 0x19, 0xd1, 0x70, 0xd2, 0x67, 0xce, 0x1a, 0xd6, 0xd0,
3939 0x94, 0x40, 0x7c, 0x91, 0xd8, 0x73, 0xd7, 0xa6, 0x56, 0x2d, 0xe3, 0x66, 0x6d, 0x35, 0x94, 0xc6
3942 SecPolicyRef
SecPolicyCreateAppleBasicAttestationSystem(CFDataRef testRootHash
) {
3943 CFMutableDictionaryRef options
= NULL
;
3944 SecPolicyRef result
= NULL
;
3946 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3947 &kCFTypeDictionaryKeyCallBacks
,
3948 &kCFTypeDictionaryValueCallBacks
), errOut
);
3949 /* BAA certs expire */
3950 SecPolicyAddBasicX509Options(options
);
3952 /* Anchored to one of the Basic Attestation roots. Allow alternative root for developers */
3953 SecPolicyAddAnchorSHA256Options(options
, BASystemRootCA_SHA256
);
3954 if (testRootHash
&& SecIsInternalRelease() && (kSecPolicySHA256Size
== CFDataGetLength(testRootHash
))) {
3955 add_element(options
, kSecPolicyCheckAnchorSHA256
, testRootHash
);
3958 /* Exactly 3 certs in the chain */
3959 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3961 require(result
= SecPolicyCreate(kSecPolicyAppleBasicAttestationSystem
,
3962 kSecPolicyNameBasicAttestationSystem
, options
), errOut
);
3965 CFReleaseSafe(options
);
3969 SecPolicyRef
SecPolicyCreateAppleBasicAttestationUser(CFDataRef testRootHash
) {
3970 CFMutableDictionaryRef options
= NULL
;
3971 SecPolicyRef result
= NULL
;
3973 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3974 &kCFTypeDictionaryKeyCallBacks
,
3975 &kCFTypeDictionaryValueCallBacks
), errOut
);
3976 /* BAA certs expire */
3977 SecPolicyAddBasicX509Options(options
);
3979 /* Anchored to one of the Basic Attestation roots. Allow alternative root for developers */
3980 SecPolicyAddAnchorSHA256Options(options
, BAUserRootCA_SHA256
);
3981 if (testRootHash
&& SecIsInternalRelease() && (kSecPolicySHA256Size
== CFDataGetLength(testRootHash
))) {
3982 add_element(options
, kSecPolicyCheckAnchorSHA256
, testRootHash
);
3985 /* Exactly 3 certs in the chain */
3986 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3988 require(result
= SecPolicyCreate(kSecPolicyAppleBasicAttestationUser
,
3989 kSecPolicyNameBasicAttestationUser
, options
), errOut
);
3992 CFReleaseSafe(options
);
3996 SecPolicyRef
SecPolicyCreateiAPSWAuthWithExpiration(bool checkExpiration
) {
3997 CFMutableDictionaryRef options
= NULL
;
3998 SecPolicyRef result
= NULL
;
4000 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
4001 &kCFTypeDictionaryKeyCallBacks
,
4002 &kCFTypeDictionaryValueCallBacks
), errOut
);
4004 /* iAP checks expiration on developement certs, but not on production certs */
4005 if (checkExpiration
) {
4006 SecPolicyAddBasicX509Options(options
);
4008 SecPolicyAddBasicCertOptions(options
);
4011 /* Exactly 2 certs in the chain */
4012 require(SecPolicyAddChainLengthOptions(options
, 2), errOut
);
4014 /* iAP SW Auth General Capabilities Extension present */
4015 add_element(options
, kSecPolicyCheckLeafMarkerOidWithoutValueCheck
, CFSTR("1.2.840.113635.100.6.59.1"));
4017 require(result
= SecPolicyCreate(kSecPolicyAppleiAPSWAuth
,
4018 kSecPolicyNameiAPSWAuth
, options
), errOut
);
4021 CFReleaseSafe(options
);
4025 SecPolicyRef
SecPolicyCreateiAPSWAuth(void) {
4026 /* By default, iAP SW Auth certs don't expire */
4027 return SecPolicyCreateiAPSWAuthWithExpiration(false);
4030 SecPolicyRef
SecPolicyCreateDemoDigitalCatalogSigning(void) {
4031 CFMutableDictionaryRef options
= NULL
;
4032 SecPolicyRef result
= NULL
;
4034 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
4035 &kCFTypeDictionaryKeyCallBacks
,
4036 &kCFTypeDictionaryValueCallBacks
), errOut
);
4037 SecPolicyAddBasicX509Options(options
);
4039 /* Exactly 3 certs in the chain */
4040 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
4042 /* Demo Signing Extension present in leaf */
4043 add_element(options
, kSecPolicyCheckLeafMarkerOid
, CFSTR("1.2.840.113635.100.6.60"));
4045 /* Issuer common name is "DemoUnit CA" */
4046 add_element(options
, kSecPolicyCheckIssuerCommonName
, CFSTR("DemoUnit CA"));
4048 require(result
= SecPolicyCreate(kSecPolicyAppleDemoDigitalCatalog
,
4049 kSecPolicyNameDemoDigitalCatalog
, options
), errOut
);
4052 CFReleaseSafe(options
);
4056 SecPolicyRef
SecPolicyCreateAppleAssetReceipt(void) {
4057 CFMutableDictionaryRef options
= NULL
;
4058 SecPolicyRef result
= NULL
;
4060 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
4061 &kCFTypeDictionaryKeyCallBacks
,
4062 &kCFTypeDictionaryValueCallBacks
), errOut
);
4064 /* No expiration check. */
4065 SecPolicyAddBasicCertOptions(options
);
4068 require_quiet(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameAssetReceipt
), errOut
);
4070 /* Exactly 3 certs in the chain */
4071 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
4073 /* Intermediate marker OID is Apple System Integration 2 CA */
4074 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.10"));
4076 /* Leaf marker OID is the Asset Receipt OID */
4077 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.61"));
4079 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
4080 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
4082 require(result
= SecPolicyCreate(kSecPolicyAppleAssetReceipt
,
4083 kSecPolicyNameAssetReceipt
, options
), errOut
);
4086 CFReleaseNull(options
);
4090 SecPolicyRef
SecPolicyCreateAppleDeveloperIDPlusTicket(void) {
4091 CFMutableDictionaryRef options
= NULL
;
4092 SecPolicyRef result
= NULL
;
4094 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
4095 &kCFTypeDictionaryKeyCallBacks
,
4096 &kCFTypeDictionaryValueCallBacks
), errOut
);
4098 /* No expiration check. */
4099 SecPolicyAddBasicCertOptions(options
);
4102 require_quiet(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameDeveloperIDPlusTicket
), errOut
);
4104 /* Exactly 3 certs in the chain */
4105 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
4107 /* Intermediate marker OID is Apple System Integration CA 4 */
4108 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.17"));
4110 /* Leaf marker OID is the Developer ID+ Ticket OID */
4111 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.30"));
4113 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
4114 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
4116 require(result
= SecPolicyCreate(kSecPolicyAppleDeveloperIDPlusTicket
,
4117 kSecPolicyNameDeveloperIDPlusTicket
, options
), errOut
);
4120 CFReleaseNull(options
);
4124 SecPolicyRef
SecPolicyCreateAppleFDRProvisioning(void) {
4125 CFMutableDictionaryRef options
= NULL
;
4126 SecPolicyRef result
= NULL
;
4128 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
4129 &kCFTypeDictionaryKeyCallBacks
,
4130 &kCFTypeDictionaryValueCallBacks
), errOut
);
4132 /* No expiration check. */
4133 SecPolicyAddBasicCertOptions(options
);
4135 require(result
= SecPolicyCreate(kSecPolicyAppleFDRProvisioning
,
4136 kSecPolicyNameFDRProvisioning
, options
), errOut
);
4138 CFReleaseNull(options
);
4142 /* subject:/CN=Component Root CA/O=Apple Inc./ST=California */
4143 /* SKID: 90:D1:56:A9:3E:B4:EE:8C:D0:10:4B:9F:17:1C:5B:55:F2:12:F6:4C */
4144 /* Not Before: Dec 19 19:31:54 2018 GMT, Not After : Dec 16 00:00:00 2043 GMT */
4145 /* Signature Algorithm: ecdsa-with-SHA384 */
4146 const uint8_t ComponentRootCA_SHA256
[kSecPolicySHA256Size
] = {
4147 0x2f, 0x71, 0x9d, 0xbf, 0x3c, 0xcd, 0xe7, 0xc2, 0xb2, 0x59, 0x3f, 0x32, 0x1f, 0x90, 0xf3, 0x42,
4148 0x42, 0xaa, 0x84, 0xa1, 0xb2, 0x0d, 0xca, 0xcc, 0x10, 0xc0, 0x5b, 0x26, 0xd6, 0x23, 0xb8, 0x47,
4150 SecPolicyRef
SecPolicyCreateAppleComponentCertificate(CFDataRef testRootHash
) {
4151 CFMutableDictionaryRef options
= NULL
;
4152 SecPolicyRef result
= NULL
;
4154 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
4155 &kCFTypeDictionaryKeyCallBacks
,
4156 &kCFTypeDictionaryValueCallBacks
), errOut
);
4158 /* Component certificates don't expire */
4159 SecPolicyAddBasicCertOptions(options
);
4161 /* Anchored to one of the Component roots. Allow alternative root for developers */
4162 SecPolicyAddAnchorSHA256Options(options
, ComponentRootCA_SHA256
);
4163 if (testRootHash
&& SecIsInternalRelease() && (kSecPolicySHA256Size
== CFDataGetLength(testRootHash
))) {
4164 add_element(options
, kSecPolicyCheckAnchorSHA256
, testRootHash
);
4167 /* Exactly 3 certs in the chain */
4168 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
4170 /* Leaf and intermediate must contain Component Type OID */
4171 add_element(options
, kSecPolicyCheckLeafMarkerOidWithoutValueCheck
, CFSTR("1.2.840.113635.100.11.1"));
4172 add_element(options
, kSecPolicyCheckIntermediateMarkerOidWithoutValueCheck
, CFSTR("1.2.840.113635.100.11.1"));
4174 require(result
= SecPolicyCreate(kSecPolicyAppleComponentCertificate
,
4175 kSecPolicyNameComponentCertificate
, options
), errOut
);
4177 CFReleaseNull(options
);
4181 SecPolicyRef
SecPolicyCreateAppleKeyTransparency(CFStringRef applicationId
) {
4182 CFMutableDictionaryRef options
= NULL
;
4183 SecPolicyRef result
= NULL
;
4185 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
4186 &kCFTypeDictionaryKeyCallBacks
,
4187 &kCFTypeDictionaryValueCallBacks
), errOut
);
4189 /* KT signing certs don't expire */
4190 SecPolicyAddBasicCertOptions(options
);
4193 require_quiet(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameKeyTransparency
), errOut
);
4195 /* Exactly 3 certs in the chain */
4196 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
4198 /* Intermediate marker OID matches AAI CA 5 */
4199 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.3"));
4201 /* Leaf marker extension matches input applicationId */
4202 add_leaf_marker_value_string(options
, CFSTR("1.2.840.113635.100.12.4"), applicationId
);
4204 /* Check revocation using any available method */
4205 add_element(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
4207 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
4208 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
4210 /* Check for weak hashes */
4211 require(SecPolicyRemoveWeakHashOptions(options
), errOut
);
4213 /* Future CT requirement */
4215 require(result
= SecPolicyCreate(kSecPolicyAppleKeyTransparency
,
4216 kSecPolicyNameKeyTransparency
, options
), errOut
);
4218 CFReleaseNull(options
);
4222 SecPolicyRef
SecPolicyCreateAlisha(void) {
4223 CFMutableDictionaryRef options
= NULL
;
4224 SecPolicyRef result
= NULL
;
4225 CFDictionaryRef keySizes
= NULL
;
4226 CFNumberRef ecSize
= NULL
;
4228 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
4229 &kCFTypeDictionaryKeyCallBacks
,
4230 &kCFTypeDictionaryValueCallBacks
), errOut
);
4232 /* Alisha certs don't expire */
4233 SecPolicyAddBasicCertOptions(options
);
4235 /* RSA key sizes are disallowed. EC key sizes are P-256 or larger. */
4236 require(ecSize
= CFNumberCreateWithCFIndex(NULL
, 256), errOut
);
4237 require(keySizes
= CFDictionaryCreate(NULL
, (const void**)&kSecAttrKeyTypeEC
,
4238 (const void**)&ecSize
, 1,
4239 &kCFTypeDictionaryKeyCallBacks
,
4240 &kCFTypeDictionaryValueCallBacks
), errOut
);
4241 add_element(options
, kSecPolicyCheckKeySize
, keySizes
);
4243 /* Check for weak hashes */
4244 require(SecPolicyRemoveWeakHashOptions(options
), errOut
);
4246 require(result
= SecPolicyCreate(kSecPolicyAppleAlisha
,
4247 kSecPolicyNameAlisha
, options
), errOut
);
4249 CFReleaseNull(options
);
4250 CFReleaseNull(keySizes
);
4251 CFReleaseNull(ecSize
);
4255 SecPolicyRef
SecPolicyCreateMeasuredBootPolicySigning(void) {
4256 CFMutableDictionaryRef options
= NULL
;
4257 SecPolicyRef result
= NULL
;
4259 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
4260 &kCFTypeDictionaryKeyCallBacks
,
4261 &kCFTypeDictionaryValueCallBacks
), errOut
);
4263 /* No expiration check. */
4264 SecPolicyAddBasicCertOptions(options
);
4266 /* Exactly 3 certs in the chain */
4267 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
4269 /* Corporate Signing subCA */
4270 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.24.17"));
4272 /* Measured Boot Policy Signing Leaf OID */
4273 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.26.6.1"));
4275 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
4276 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
4278 require(result
= SecPolicyCreate(kSecPolicyAppleMeasuredBootPolicySigning
,
4279 kSecPolicyNameMeasuredBootPolicySigning
, options
), errOut
);
4282 CFReleaseSafe(options
);
4286 /* subject:/CN=Apple External EC Root/O=Apple Inc./C=US */
4287 /* SKID: 3F:A4:C0:94:20:70:CB:3B:DD:A8:54:E6:14:1E:29:CC:4D:14:38:53 */
4288 /* Not Before: Jan 23 00:46:48 2020 GMT, Not After : Jan 18 00:00:00 2045 GMT */
4289 /* Signature Algorithm: ecdsa-with-SHA384 */
4290 const uint8_t AppleExternalECRoot_SHA256
[kSecPolicySHA256Size
] = {
4291 0x72, 0x56, 0x6e, 0x6f, 0x66, 0x30, 0x0c, 0xfd, 0x24, 0xe5, 0xe6, 0x85, 0xa2, 0xf1, 0x5a, 0x74,
4292 0x9d, 0xe0, 0x4b, 0xb0, 0x38, 0x50, 0x77, 0x91, 0x96, 0x63, 0x6e, 0x07, 0x23, 0x0f, 0x91, 0x1e
4294 /* subject:/CN=Test Apple External EC Root/O=Apple Inc./C=US */
4295 /* SKID: 07:6B:07:47:33:E4:96:B4:FC:6F:FA:32:2C:8E:BE:70:C2:8F:80:3C */
4296 /* Not Before: Nov 5 18:00:46 2019 GMT, Not After : Oct 29 18:00:46 2044 GMT */
4297 /* Signature Algorithm: ecdsa-with-SHA384 */
4298 const uint8_t TestAppleExternalECRoot_SHA256
[kSecPolicySHA256Size
] = {
4299 0xf3, 0x98, 0x39, 0xdc, 0x6a, 0x64, 0xf6, 0xe3, 0xa0, 0xdc, 0x97, 0xd7, 0x83, 0x61, 0x6b, 0x84,
4300 0x9f, 0xdf, 0xa1, 0x70, 0x54, 0x59, 0xae, 0x96, 0x0f, 0x41, 0xe1, 0x16, 0xa3, 0xb4, 0x8b, 0xb5
4302 SecPolicyRef
SecPolicyCreateApplePayQRCodeEncryption(void) {
4303 CFMutableDictionaryRef options
= NULL
;
4304 SecPolicyRef result
= NULL
;
4306 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
4307 &kCFTypeDictionaryKeyCallBacks
,
4308 &kCFTypeDictionaryValueCallBacks
), errOut
);
4310 /* Check expiration */
4311 SecPolicyAddBasicX509Options(options
);
4313 /* Exactly 3 certs in the chain */
4314 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
4316 /* Apple External EC CA 1 - G1 */
4317 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.22"));
4319 /* ApplePay QR Code Encryption */
4320 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.13.3"));
4322 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
4323 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
4325 require(SecPolicyAddAnchorSHA256Options(options
, AppleExternalECRoot_SHA256
),errOut
);
4326 if (SecIsInternalRelease()) {
4327 require(SecPolicyAddAnchorSHA256Options(options
, TestAppleExternalECRoot_SHA256
),errOut
);
4330 /* Check revocation using any available method */
4331 add_element(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
4333 require(result
= SecPolicyCreate(kSecPolicyApplePayQRCodeEncryption
,
4334 kSecPolicyNamePayQRCodeEncryption
, options
), errOut
);
4337 CFReleaseSafe(options
);
4341 SecPolicyRef
SecPolicyCreateApplePayQRCodeSigning(void) {
4342 CFMutableDictionaryRef options
= NULL
;
4343 SecPolicyRef result
= NULL
;
4345 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
4346 &kCFTypeDictionaryKeyCallBacks
,
4347 &kCFTypeDictionaryValueCallBacks
), errOut
);
4349 /* Check expiration */
4350 SecPolicyAddBasicX509Options(options
);
4352 /* Exactly 3 certs in the chain */
4353 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
4355 /* Apple External EC CA 1 - G1 */
4356 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.22"));
4358 /* ApplePay QR Code Signing */
4359 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.12.12"));
4361 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
4362 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
4364 require(SecPolicyAddAnchorSHA256Options(options
, AppleExternalECRoot_SHA256
),errOut
);
4365 if (SecIsInternalRelease()) {
4366 require(SecPolicyAddAnchorSHA256Options(options
, TestAppleExternalECRoot_SHA256
),errOut
);
4369 /* Check revocation using any available method */
4370 add_element(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
4372 require(result
= SecPolicyCreate(kSecPolicyApplePayQRCodeSigning
,
4373 kSecPolicyNamePayQRCodeSigning
, options
), errOut
);
4376 CFReleaseSafe(options
);
4380 SecPolicyRef
SecPolicyCreateAppleAccessoryUpdateSigning(void) {
4381 CFMutableDictionaryRef options
= NULL
;
4382 SecPolicyRef result
= NULL
;
4384 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
4385 &kCFTypeDictionaryKeyCallBacks
,
4386 &kCFTypeDictionaryValueCallBacks
), errOut
);
4388 /* No expiration check */
4389 SecPolicyAddBasicCertOptions(options
);
4391 /* Exactly 3 certs in the chain */
4392 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
4395 require_quiet(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameAccessoryUpdateSigning
), errOut
);
4397 /* Apple External EC CA 1 - G1 */
4398 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.17"));
4400 /* Accessory Manufacturer Firmware Signing Prod */
4401 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.12.9"));
4402 if (isCFPreferenceInSecurityDomain(CFSTR("AllowAccessoryUpdateSigningBeta"))) {
4403 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.12.10")); // ProdQA
4406 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
4407 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
4409 /* Check revocation using any available method */
4410 add_element(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
4412 require(result
= SecPolicyCreate(kSecPolicyAppleAccessoryUpdateSigning
,
4413 kSecPolicyNameAccessoryUpdateSigning
, options
), errOut
);
4416 CFReleaseSafe(options
);
4420 CF_RETURNS_RETAINED SecPolicyRef
SecPolicyCreateEscrowServiceIdKeySigning(void)
4422 SecPolicyRef result
= NULL
;
4423 CFMutableDictionaryRef options
= NULL
;
4424 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
4425 &kCFTypeDictionaryKeyCallBacks
,
4426 &kCFTypeDictionaryValueCallBacks
), errOut
);
4428 // X509, ignoring date validity
4429 SecPolicyAddBasicCertOptions(options
);
4431 add_ku(options
, kSecKeyUsageDigitalSignature
);
4433 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
,
4434 CFSTR("Escrow Service ID Key"));
4436 /* Exactly 2 certs in the chain */
4437 require(SecPolicyAddChainLengthOptions(options
, 2), errOut
);
4439 require(result
= SecPolicyCreate(kSecPolicyAppleEscrowServiceIdKeySigning
,
4440 kSecPolicyNameEscrowServiceIdKeySigning
, options
), errOut
);
4443 CFReleaseSafe(options
);
4447 CF_RETURNS_RETAINED SecPolicyRef
SecPolicyCreatePCSEscrowServiceIdKeySigning(void)
4449 SecPolicyRef result
= NULL
;
4450 CFMutableDictionaryRef options
= NULL
;
4451 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
4452 &kCFTypeDictionaryKeyCallBacks
,
4453 &kCFTypeDictionaryValueCallBacks
), errOut
);
4455 SecPolicyAddBasicX509Options(options
);
4456 add_ku(options
, kSecKeyUsageDigitalSignature
);
4458 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
,
4459 CFSTR("Effaceable Service ID Key"));
4461 /* Exactly 2 certs in the chain */
4462 require(SecPolicyAddChainLengthOptions(options
, 2), errOut
);
4464 require(result
= SecPolicyCreate(kSecPolicyApplePCSEscrowServiceIdKeySigning
,
4465 kSecPolicyNamePCSEscrowServiceIdKeySigning
, options
), errOut
);
4468 CFReleaseSafe(options
);
4472 SecPolicyRef
SecPolicyCreateAggregateMetricTransparency(bool facilitator
)
4474 CFMutableDictionaryRef options
= NULL
;
4475 SecPolicyRef result
= NULL
;
4477 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
4478 &kCFTypeDictionaryKeyCallBacks
,
4479 &kCFTypeDictionaryValueCallBacks
), errOut
);
4481 SecPolicyAddBasicX509Options(options
);
4483 /* Anchored to the Apple Roots */
4484 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameAggregateMetricTransparency
), errOut
);
4486 /* Exactly 3 certs in the chain */
4487 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
4489 /* Intermediate marker OID matches AAICA 6 */
4490 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.26"));
4492 /* Leaf marker OID matches expected OID for either Facilitator or Partner */
4494 add_element(options
, kSecPolicyCheckLeafMarkerOidWithoutValueCheck
, CFSTR("1.2.840.113635.100.12.17"));
4496 add_element(options
, kSecPolicyCheckLeafMarkerOidWithoutValueCheck
, CFSTR("1.2.840.113635.100.12.18"));
4499 /* Check revocation using any available method */
4500 add_element(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
4502 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
4503 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
4506 if (!SecIsInternalRelease() || !isCFPreferenceInSecurityDomain(CFSTR("disableAggregateMetricsCTCheck"))) {
4507 add_element(options
, kSecPolicyCheckCTRequired
, kCFBooleanTrue
);
4510 /* Check for weak hashes */
4511 // require(SecPolicyRemoveWeakHashOptions(options), errOut); // the current WWDR CA cert is signed with SHA1
4512 require(result
= SecPolicyCreate(kSecPolicyAppleAggregateMetricTransparency
,
4513 kSecPolicyNameAggregateMetricTransparency
, options
), errOut
);
4516 CFReleaseSafe(options
);