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>
48 #include <utilities/SecInternalReleasePriv.h>
50 #undef POLICYCHECKMACRO
51 #define POLICYCHECKMACRO(NAME, TRUSTRESULT, SUBTYPE, LEAFCHECK, PATHCHECK, LEAFONLY, CSSMERR, OSSTATUS) \
52 const CFStringRef kSecPolicyCheck##NAME = CFSTR(#NAME);
53 #include "SecPolicyChecks.list"
55 #define SEC_CONST_DECL(k,v) const CFStringRef k = CFSTR(v);
57 /********************************************************
58 ******************* Feature toggles ********************
59 ********************************************************/
60 /* Option for AnchorApple */
61 SEC_CONST_DECL (kSecPolicyAppleAnchorIncludeTestRoots
, "AnchorAppleTestRoots");
63 /* options for kSecPolicyCheckLeafMarkersProdAndQA */
64 SEC_CONST_DECL (kSecPolicyLeafMarkerProd
, "ProdMarker");
65 SEC_CONST_DECL (kSecPolicyLeafMarkerQA
, "QAMarker");
67 /* Revocation toggles */
68 SEC_CONST_DECL (kSecPolicyCheckRevocationOCSP
, "OCSP");
69 SEC_CONST_DECL (kSecPolicyCheckRevocationCRL
, "CRL");
70 SEC_CONST_DECL (kSecPolicyCheckRevocationAny
, "AnyRevocationMethod");
72 /* Public policy oids. */
73 #define POLICYMACRO(NAME, OID, ISPUBLIC, INTNAME, IN_NAME, IN_PROPERTIES, FUNCTION) \
74 const CFStringRef kSecPolicyApple##NAME = CFSTR("1.2.840.113635.100.1."#OID);
75 #include "SecPolicy.list"
76 //Some naming exceptions
77 SEC_CONST_DECL(kSecPolicyMacAppStoreReceipt
, "1.2.840.113635.100.1.19")
78 SEC_CONST_DECL(kSecPolicyAppleIDValidationRecordSigningPolicy
, "1.2.840.113635.100.1.30");
80 SEC_CONST_DECL (kSecPolicyOid
, "SecPolicyOid");
81 SEC_CONST_DECL (kSecPolicyName
, "SecPolicyName");
82 SEC_CONST_DECL (kSecPolicyClient
, "SecPolicyClient");
83 SEC_CONST_DECL (kSecPolicyRevocationFlags
, "SecPolicyRevocationFlags");
84 SEC_CONST_DECL (kSecPolicyTeamIdentifier
, "SecPolicyTeamIdentifier");
85 SEC_CONST_DECL (kSecPolicyContext
, "SecPolicyContext");
86 SEC_CONST_DECL (kSecPolicyPolicyName
, "SecPolicyPolicyName");
87 SEC_CONST_DECL (kSecPolicyIntermediateMarkerOid
, "SecPolicyIntermediateMarkerOid");
88 SEC_CONST_DECL (kSecPolicyLeafMarkerOid
, "SecPolicyLeafMarkerOid");
89 SEC_CONST_DECL (kSecPolicyRootDigest
, "SecPolicyRootDigest");
91 SEC_CONST_DECL (kSecPolicyKU_DigitalSignature
, "CE_KU_DigitalSignature");
92 SEC_CONST_DECL (kSecPolicyKU_NonRepudiation
, "CE_KU_NonRepudiation");
93 SEC_CONST_DECL (kSecPolicyKU_KeyEncipherment
, "CE_KU_KeyEncipherment");
94 SEC_CONST_DECL (kSecPolicyKU_DataEncipherment
, "CE_KU_DataEncipherment");
95 SEC_CONST_DECL (kSecPolicyKU_KeyAgreement
, "CE_KU_KeyAgreement");
96 SEC_CONST_DECL (kSecPolicyKU_KeyCertSign
, "CE_KU_KeyCertSign");
97 SEC_CONST_DECL (kSecPolicyKU_CRLSign
, "CE_KU_CRLSign");
98 SEC_CONST_DECL (kSecPolicyKU_EncipherOnly
, "CE_KU_EncipherOnly");
99 SEC_CONST_DECL (kSecPolicyKU_DecipherOnly
, "CE_KU_DecipherOnly");
101 /* Internal policy names */
103 #define __P_DO_DECLARE_(NAME, INTNAME) static CFStringRef kSecPolicyName##NAME = CFSTR(#INTNAME);
104 #define __P_DO_DECLARE_P(NAME, INTNAME) const CFStringRef kSecPolicyNameApple##NAME = CFSTR(#INTNAME);
105 #define __P_DO_DECLARE_I(NAME, INTNAME) const CFStringRef kSecPolicyName##NAME = CFSTR(#INTNAME);
106 #define POLICYMACRO(NAME, OID, ISPUBLIC, INTNAME, IN_NAME, IN_PROPERTIES, FUNCTION) \
107 __P_DO_DECLARE_##ISPUBLIC(NAME, INTNAME)
108 #include "SecPolicy.list"
109 //Some naming exceptions
110 static CFStringRef kSecPolicyNameAppleIDSBag
= CFSTR("IDSBag");
112 /* External Policy Names
113 * These correspond to the names defined in CertificatePinning.plist
114 * in security_certificates */
115 SEC_CONST_DECL (kSecPolicyNameSSLServer
, "sslServer");
116 SEC_CONST_DECL (kSecPolicyNameSSLClient
, "sslClient");
117 SEC_CONST_DECL (kSecPolicyNameEAPServer
, "eapServer");
118 SEC_CONST_DECL (kSecPolicyNameEAPClient
, "eapClient");
119 SEC_CONST_DECL (kSecPolicyNameIPSecServer
, "ipsecServer");
120 SEC_CONST_DECL (kSecPolicyNameIPSecClient
, "ipsecClient");
121 SEC_CONST_DECL (kSecPolicyNameAppleiCloudSetupService
, "iCloudSetup");
122 SEC_CONST_DECL (kSecPolicyNameAppleMMCSService
, "MMCS");
123 SEC_CONST_DECL (kSecPolicyNameAppleAST2Service
, "AST2");
124 SEC_CONST_DECL (kSecPolicyNameAppleEscrowProxyService
, "Escrow");
125 SEC_CONST_DECL (kSecPolicyNameAppleFMiPService
, "FMiP");
126 SEC_CONST_DECL (kSecPolicyNameAppleHomeKitService
, "HomeKit");
127 SEC_CONST_DECL (kSecPolicyNameAppleAIDCService
, "AIDC");
128 SEC_CONST_DECL (kSecPolicyNameAppleMapsService
, "Maps");
129 SEC_CONST_DECL (kSecPolicyNameAppleHealthProviderService
, "HealthProvider");
130 SEC_CONST_DECL (kSecPolicyNameAppleParsecService
, "Parsec");
132 #define kSecPolicySHA1Size 20
133 #define kSecPolicySHA256Size 32
134 __unused
const UInt8 kAppleCASHA1
[kSecPolicySHA1Size
] = {
135 0x61, 0x1E, 0x5B, 0x66, 0x2C, 0x59, 0x3A, 0x08, 0xFF, 0x58,
136 0xD1, 0x4A, 0xE2, 0x24, 0x52, 0xD1, 0x98, 0xDF, 0x6C, 0x60
139 __unused
static const UInt8 kAppleTESTCASHA1
[kSecPolicySHA1Size
] = {
140 0xbc, 0x30, 0x55, 0xc8, 0xc8, 0xd3, 0x48, 0x3f, 0xf4, 0x8d,
141 0xfe, 0x3d, 0x51, 0x75, 0x31, 0xc9, 0xf4, 0xd7, 0x4a, 0xf7
144 static const UInt8 kITMSCASHA1
[kSecPolicySHA1Size
] = {
145 0x1D, 0x33, 0x42, 0x46, 0x8B, 0x10, 0xBD, 0xE6, 0x45, 0xCE,
146 0x44, 0x6E, 0xBB, 0xE8, 0xF5, 0x03, 0x5D, 0xF8, 0x32, 0x22
149 static const UInt8 kFactoryDeviceCASHA1
[kSecPolicySHA1Size
] = {
150 0xef, 0x68, 0x73, 0x17, 0xa4, 0xf8, 0xf9, 0x4b, 0x7b, 0x21,
151 0xe2, 0x2f, 0x09, 0x8f, 0xfd, 0x6a, 0xae, 0xc0, 0x0d, 0x63
154 static const UInt8 kApplePKISettingsAuthority
[kSecPolicySHA1Size
] = {
155 0x1D, 0x0C, 0xBA, 0xAD, 0x17, 0xFD, 0x7E, 0x9E, 0x9F, 0xF1,
156 0xC9, 0xA2, 0x66, 0x79, 0x60, 0x00, 0x8B, 0xAE, 0x70, 0xB8
159 static const UInt8 kAppleTestPKISettingsAuthority
[kSecPolicySHA1Size
] = {
160 0xDB, 0xBA, 0x25, 0x0B, 0xD8, 0x62, 0x71, 0x87, 0x54, 0x7E,
161 0xD7, 0xEF, 0x11, 0x94, 0x7E, 0x82, 0xE6, 0xD8, 0x1C, 0x9A
164 static const UInt8 kTestAppleRootCA_ECC_SHA1
[kSecPolicySHA1Size
] = {
165 0x62, 0x0A, 0xED, 0x83, 0xD2, 0x97, 0x4A, 0x77, 0x56, 0x33,
166 0x83, 0xBE, 0xDB, 0xF9, 0xA1, 0xBD, 0x5F, 0xFE, 0x55, 0x7B
169 __unused
static const UInt8 kAppleRootCA_ECC_SHA1
[kSecPolicySHA1Size
] = {
170 0xB5, 0x2C, 0xB0, 0x2F, 0xD5, 0x67, 0xE0, 0x35, 0x9F, 0xE8,
171 0xFA, 0x4D, 0x4C, 0x41, 0x03, 0x79, 0x70, 0xFE, 0x01, 0xB0
176 /********************************************************
177 ****************** SecPolicy object ********************
178 ********************************************************/
180 static void SecPolicyDestroy(CFTypeRef cf
) {
181 SecPolicyRef policy
= (SecPolicyRef
) cf
;
182 CFRelease(policy
->_oid
);
183 CFReleaseSafe(policy
->_name
);
184 CFRelease(policy
->_options
);
187 static Boolean
SecPolicyCompare(CFTypeRef cf1
, CFTypeRef cf2
) {
188 SecPolicyRef policy1
= (SecPolicyRef
) cf1
;
189 SecPolicyRef policy2
= (SecPolicyRef
) cf2
;
190 if (policy1
->_name
&& policy2
->_name
) {
191 return CFEqual(policy1
->_oid
, policy2
->_oid
) &&
192 CFEqual(policy1
->_name
, policy2
->_name
) &&
193 CFEqual(policy1
->_options
, policy2
->_options
);
195 return CFEqual(policy1
->_oid
, policy2
->_oid
) &&
196 CFEqual(policy1
->_options
, policy2
->_options
);
200 static CFHashCode
SecPolicyHash(CFTypeRef cf
) {
201 SecPolicyRef policy
= (SecPolicyRef
) cf
;
203 return CFHash(policy
->_oid
) + CFHash(policy
->_name
) + CFHash(policy
->_options
);
205 return CFHash(policy
->_oid
) + CFHash(policy
->_options
);
209 static CFStringRef
SecPolicyCopyFormatDescription(CFTypeRef cf
, CFDictionaryRef formatOptions
) {
210 SecPolicyRef policy
= (SecPolicyRef
) cf
;
211 CFMutableStringRef desc
= CFStringCreateMutable(kCFAllocatorDefault
, 0);
212 CFStringRef typeStr
= CFCopyTypeIDDescription(CFGetTypeID(cf
));
213 CFStringAppendFormat(desc
, NULL
,
214 CFSTR("<%@: oid: %@ name: %@ options %@"), typeStr
,
215 policy
->_oid
, (policy
->_name
) ? policy
->_name
: CFSTR(""),
218 CFStringAppend(desc
, CFSTR(" >"));
223 /* SecPolicy API functions. */
224 CFGiblisWithHashFor(SecPolicy
);
226 /* AUDIT[securityd](done):
227 oid (ok) is a caller provided string, only its cf type has been checked.
228 options is a caller provided dictionary, only its cf type has been checked.
230 SecPolicyRef
SecPolicyCreate(CFStringRef oid
, CFStringRef name
, CFDictionaryRef options
) {
231 SecPolicyRef result
= NULL
;
233 require(oid
, errOut
);
234 require(options
, errOut
);
236 (SecPolicyRef
)_CFRuntimeCreateInstance(kCFAllocatorDefault
,
237 SecPolicyGetTypeID(),
238 sizeof(struct __SecPolicy
) - sizeof(CFRuntimeBase
), 0), errOut
);
243 result
->_name
= name
;
245 result
->_options
= options
;
252 static void set_ku_from_properties(SecPolicyRef policy
, CFDictionaryRef properties
);
255 SecPolicyRef
SecPolicyCreateWithProperties(CFTypeRef policyIdentifier
,
256 CFDictionaryRef properties
) {
257 // Creates a policy reference for a given policy object identifier.
258 // If policy-specific parameters can be supplied (e.g. hostname),
259 // attempt to obtain from input properties dictionary.
260 // Returns NULL if the given identifier is unsupported.
262 SecPolicyRef policy
= NULL
;
263 CFTypeRef name
= NULL
;
264 CFStringRef teamID
= NULL
;
265 Boolean client
= false;
266 CFDictionaryRef context
= NULL
;
267 CFStringRef policyName
= NULL
, intermediateMarkerOid
= NULL
, leafMarkerOid
= NULL
;
268 CFDataRef rootDigest
= NULL
;
269 require(policyIdentifier
&& (CFStringGetTypeID() == CFGetTypeID(policyIdentifier
)), errOut
);
272 name
= CFDictionaryGetValue(properties
, kSecPolicyName
);
273 teamID
= CFDictionaryGetValue(properties
, kSecPolicyTeamIdentifier
);
275 CFBooleanRef dictionaryClientValue
;
276 client
= (CFDictionaryGetValueIfPresent(properties
, kSecPolicyClient
, (const void **)&dictionaryClientValue
) &&
277 (dictionaryClientValue
!= NULL
) && CFEqual(kCFBooleanTrue
, dictionaryClientValue
));
278 context
= CFDictionaryGetValue(properties
, kSecPolicyContext
);
279 policyName
= CFDictionaryGetValue(properties
, kSecPolicyPolicyName
);
280 intermediateMarkerOid
= CFDictionaryGetValue(properties
, kSecPolicyIntermediateMarkerOid
);
281 leafMarkerOid
= CFDictionaryGetValue(properties
, kSecPolicyLeafMarkerOid
);
282 rootDigest
= CFDictionaryGetValue(properties
, kSecPolicyRootDigest
);
285 /* only the EAP policy allows a non-string name */
286 if (name
&& !isString(name
) && !CFEqual(policyIdentifier
, kSecPolicyAppleEAP
)) {
287 secerror("policy \"%@\" requires a string value for the %@ key", policyIdentifier
, kSecPolicyName
);
291 /* What follows are all the exceptional functions that do not match the macro below */
292 if (CFEqual(policyIdentifier
, kSecPolicyAppleSSL
)) {
293 policy
= SecPolicyCreateSSL(!client
, name
);
294 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleSMIME
)) {
295 policy
= SecPolicyCreateSMIME(kSecSignSMIMEUsage
| kSecAnyEncryptSMIME
, name
);
296 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleEAP
)) {
297 CFArrayRef array
= NULL
;
298 if (isString(name
)) {
299 array
= CFArrayCreate(kCFAllocatorDefault
, (const void **)&name
, 1, &kCFTypeArrayCallBacks
);
300 } else if (isArray(name
)) {
301 array
= CFArrayCreateCopy(NULL
, name
);
303 policy
= SecPolicyCreateEAP(!client
, array
);
304 CFReleaseSafe(array
);
305 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleIPsec
)) {
306 policy
= SecPolicyCreateIPSec(!client
, name
);
307 } else if (CFEqual(policyIdentifier
, kSecPolicyMacAppStoreReceipt
)) {
308 policy
= SecPolicyCreateMacAppStoreReceipt();
309 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleRevocation
)) {
310 policy
= SecPolicyCreateRevocation(kSecRevocationUseAnyAvailableMethod
);
311 } else if (CFEqual(policyIdentifier
, kSecPolicyApplePassbookSigning
)) {
312 policy
= SecPolicyCreatePassbookCardSigner(name
, teamID
);
313 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleAST2DiagnosticsServerAuth
)) {
315 policy
= SecPolicyCreateAppleAST2Service(name
, context
);
317 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier
);
319 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleEscrowProxyServerAuth
)) {
321 policy
= SecPolicyCreateAppleEscrowProxyService(name
, context
);
323 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier
);
325 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleFMiPServerAuth
)) {
327 policy
= SecPolicyCreateAppleFMiPService(name
, context
);
329 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier
);
331 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleMMCService
)) {
333 policy
= SecPolicyCreateAppleMMCSService(name
, context
);
335 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier
);
337 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleGSService
)) {
339 policy
= SecPolicyCreateAppleGSService(name
, context
);
341 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier
);
343 } else if (CFEqual(policyIdentifier
, kSecPolicyApplePPQService
)) {
345 policy
= SecPolicyCreateApplePPQService(name
, context
);
347 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier
);
349 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleGenericApplePinned
)) {
351 policy
= SecPolicyCreateApplePinned(policyName
, intermediateMarkerOid
, leafMarkerOid
);
353 secerror("policy \"%@\" requires kSecPolicyPolicyName input", policyIdentifier
);
355 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleGenericAppleSSLPinned
)) {
357 policy
= SecPolicyCreateAppleSSLPinned(policyName
, name
, intermediateMarkerOid
, leafMarkerOid
);
359 secerror("policy \"%@\" requires kSecPolicyPolicyName input", policyIdentifier
);
361 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleIDSServiceContext
)) {
363 policy
= SecPolicyCreateAppleIDSServiceContext(name
, context
);
365 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier
);
367 } else if (CFEqual(policyIdentifier
, kSecPolicyApplePushService
)) {
369 policy
= SecPolicyCreateApplePushService(name
, context
);
371 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier
);
373 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleUniqueDeviceIdentifierCertificate
)) {
374 policy
= SecPolicyCreateAppleUniqueDeviceCertificate(rootDigest
);
375 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleiCloudSetupServerAuth
)) {
377 policy
= SecPolicyCreateAppleiCloudSetupService(name
, context
);
379 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier
);
381 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleBasicAttestationSystem
)) {
382 policy
= SecPolicyCreateAppleBasicAttestationSystem(rootDigest
);
383 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleBasicAttestationUser
)) {
384 policy
= SecPolicyCreateAppleBasicAttestationUser(rootDigest
);
386 /* For a couple of common patterns we use the macro */
388 #define _P_OPTION_N name
389 #define _P_PROPERTIES_(NAME, IN_NAME, FUNCTION)
390 #define _P_PROPERTIES_Y(NAME, IN_NAME, FUNCTION) else if (CFEqual(policyIdentifier, kSecPolicyApple##NAME)) { \
391 policy = SecPolicyCreate##FUNCTION(_P_OPTION_##IN_NAME); \
394 #define POLICYMACRO(NAME, OID, ISPUBLIC, INTNAME, IN_NAME, IN_PROPERTIES, FUNCTION) \
395 _P_PROPERTIES_##IN_PROPERTIES(NAME, IN_NAME, FUNCTION)
396 #include "SecPolicy.list"
398 secerror("ERROR: policy \"%@\" is unsupported", policyIdentifier
);
406 set_ku_from_properties(policy
, properties
);
410 SecPolicySetName(policy
, policyName
);
417 CFDictionaryRef
SecPolicyCopyProperties(SecPolicyRef policyRef
) {
418 // Builds and returns a dictionary which the caller must release.
420 #pragma clang diagnostic push
421 #pragma clang diagnostic ignored "-Wnonnull"
422 // After introducing nullability annotations, policyRef is supposed to be nonnull, suppress the warning
423 if (!policyRef
) return NULL
;
424 #pragma clang diagnostic pop
425 CFMutableDictionaryRef properties
= CFDictionaryCreateMutable(NULL
, 0,
426 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
427 #pragma clang diagnostic push
428 #pragma clang diagnostic ignored "-Wnonnull"
429 // 'properties' is nonnull in reality suppress the warning
430 if (!properties
) return NULL
;
431 #pragma clang diagnostic pop
432 CFStringRef oid
= (CFStringRef
) CFRetain(policyRef
->_oid
);
433 CFTypeRef nameKey
= NULL
;
435 // Determine name key
436 if (policyRef
->_options
) {
437 if (CFDictionaryContainsKey(policyRef
->_options
, kSecPolicyCheckSSLHostname
)) {
438 nameKey
= kSecPolicyCheckSSLHostname
;
439 } else if (CFDictionaryContainsKey(policyRef
->_options
, kSecPolicyCheckEAPTrustedServerNames
)) {
440 nameKey
= kSecPolicyCheckEAPTrustedServerNames
;
441 } else if (CFDictionaryContainsKey(policyRef
->_options
, kSecPolicyCheckEmail
)) {
442 nameKey
= kSecPolicyCheckEmail
;
447 CFDictionarySetValue(properties
, (const void *)kSecPolicyOid
,
450 // Set kSecPolicyName if we have one
451 if (nameKey
&& policyRef
->_options
) {
452 CFTypeRef name
= (CFTypeRef
) CFDictionaryGetValue(policyRef
->_options
,
455 CFDictionarySetValue(properties
, (const void *)kSecPolicyName
,
460 // Set kSecPolicyClient
461 CFStringRef policyName
= (CFStringRef
) CFRetainSafe(policyRef
->_name
);
462 if (policyName
&& (CFEqual(policyName
, kSecPolicyNameSSLClient
) ||
463 CFEqual(policyName
, kSecPolicyNameIPSecClient
) ||
464 CFEqual(policyName
, kSecPolicyNameEAPClient
))) {
465 CFDictionarySetValue(properties
, (const void *)kSecPolicyClient
,
466 (const void *)kCFBooleanTrue
);
473 static void SecPolicySetOid(SecPolicyRef policy
, CFStringRef oid
) {
474 if (!policy
|| !oid
) return;
475 CFStringRef temp
= policy
->_oid
;
481 void SecPolicySetName(SecPolicyRef policy
, CFStringRef policyName
) {
482 if (!policy
|| !policyName
) return;
483 CFStringRef temp
= policy
->_name
;
484 CFRetain(policyName
);
485 policy
->_name
= policyName
;
489 CFStringRef
SecPolicyGetOidString(SecPolicyRef policy
) {
493 CFStringRef
SecPolicyGetName(SecPolicyRef policy
) {
494 return policy
->_name
;
497 CFDictionaryRef
SecPolicyGetOptions(SecPolicyRef policy
) {
498 return policy
->_options
;
501 void SecPolicySetOptionsValue(SecPolicyRef policy
, CFStringRef key
, CFTypeRef value
) {
502 if (!policy
|| !key
) return;
503 CFMutableDictionaryRef options
= (CFMutableDictionaryRef
) policy
->_options
;
505 options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
506 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
507 if (!options
) return;
508 policy
->_options
= options
;
510 CFDictionarySetValue(options
, key
, value
);
513 /* Local forward declaration */
514 static void set_ssl_ekus(CFMutableDictionaryRef options
, bool server
);
517 // this is declared as NA for iPhone in SecPolicy.h, so declare here
518 OSStatus
SecPolicySetProperties(SecPolicyRef policyRef
, CFDictionaryRef properties
);
521 OSStatus
SecPolicySetProperties(SecPolicyRef policyRef
, CFDictionaryRef properties
) {
522 // Set policy options based on the provided dictionary keys.
524 if (!(policyRef
&& properties
&& (CFDictionaryGetTypeID() == CFGetTypeID(properties
)))) {
527 CFStringRef oid
= (CFStringRef
) CFRetain(policyRef
->_oid
);
528 OSStatus result
= errSecSuccess
;
531 CFTypeRef name
= NULL
;
532 if (CFDictionaryGetValueIfPresent(properties
, (const void *)kSecPolicyName
,
533 (const void **)&name
) && name
) {
534 CFTypeID typeID
= CFGetTypeID(name
);
535 if (CFEqual(oid
, kSecPolicyAppleSSL
) ||
536 CFEqual(oid
, kSecPolicyAppleIPsec
)) {
537 if (CFStringGetTypeID() == typeID
) {
538 SecPolicySetOptionsValue(policyRef
, kSecPolicyCheckSSLHostname
, name
);
540 else result
= errSecParam
;
542 else if (CFEqual(oid
, kSecPolicyAppleEAP
)) {
543 if ((CFStringGetTypeID() == typeID
) ||
544 (CFArrayGetTypeID() == typeID
)) {
545 SecPolicySetOptionsValue(policyRef
, kSecPolicyCheckEAPTrustedServerNames
, name
);
547 else result
= errSecParam
;
549 else if (CFEqual(oid
, kSecPolicyAppleSMIME
)) {
550 if (CFStringGetTypeID() == typeID
) {
551 SecPolicySetOptionsValue(policyRef
, kSecPolicyCheckEmail
, name
);
553 else result
= errSecParam
;
558 CFTypeRef client
= NULL
;
559 if (CFDictionaryGetValueIfPresent(properties
, (const void *)kSecPolicyClient
,
560 (const void **)&client
) && client
) {
561 if (!(CFBooleanGetTypeID() == CFGetTypeID(client
))) {
562 result
= errSecParam
;
564 else if (CFEqual(client
, kCFBooleanTrue
)) {
565 if (CFEqual(oid
, kSecPolicyAppleSSL
)) {
566 SecPolicySetName(policyRef
, kSecPolicyNameSSLClient
);
567 /* Set EKU checks for clients */
568 CFMutableDictionaryRef newOptions
= CFDictionaryCreateMutableCopy(NULL
, 0, policyRef
->_options
);
569 set_ssl_ekus(newOptions
, false);
570 CFReleaseSafe(policyRef
->_options
);
571 policyRef
->_options
= newOptions
;
573 else if (CFEqual(oid
, kSecPolicyAppleIPsec
)) {
574 SecPolicySetName(policyRef
, kSecPolicyNameIPSecClient
);
576 else if (CFEqual(oid
, kSecPolicyNameEAPServer
)) {
577 SecPolicySetName(policyRef
, kSecPolicyNameEAPClient
);
578 /* Set EKU checks for clients */
579 CFMutableDictionaryRef newOptions
= CFDictionaryCreateMutableCopy(NULL
, 0, policyRef
->_options
);
580 set_ssl_ekus(newOptions
, false);
581 CFReleaseSafe(policyRef
->_options
);
582 policyRef
->_options
= newOptions
;
586 if (CFEqual(oid
, kSecPolicyAppleSSL
)) {
587 SecPolicySetName(policyRef
, kSecPolicyNameSSLServer
);
588 /* Set EKU checks for servers */
589 CFMutableDictionaryRef newOptions
= CFDictionaryCreateMutableCopy(NULL
, 0, policyRef
->_options
);
590 set_ssl_ekus(newOptions
, true);
591 CFReleaseSafe(policyRef
->_options
);
592 policyRef
->_options
= newOptions
;
594 else if (CFEqual(oid
, kSecPolicyAppleIPsec
)) {
595 SecPolicySetName(policyRef
, kSecPolicyNameIPSecServer
);
597 else if (CFEqual(oid
, kSecPolicyAppleEAP
)) {
598 SecPolicySetName(policyRef
, kSecPolicyNameEAPServer
);
599 /* Set EKU checks for servers */
600 CFMutableDictionaryRef newOptions
= CFDictionaryCreateMutableCopy(NULL
, 0, policyRef
->_options
);
601 set_ssl_ekus(newOptions
, true);
602 CFReleaseSafe(policyRef
->_options
);
603 policyRef
->_options
= newOptions
;
609 set_ku_from_properties(policyRef
, properties
);
615 static xpc_object_t
copy_xpc_policy_object(SecPolicyRef policy
);
616 static bool append_policy_to_xpc_array(SecPolicyRef policy
, xpc_object_t xpc_policies
);
617 extern xpc_object_t
copy_xpc_policies_array(CFArrayRef policies
);
618 extern OSStatus
validate_array_of_items(CFArrayRef array
, CFStringRef arrayItemType
, CFTypeID itemTypeID
, bool required
);
620 static xpc_object_t
copy_xpc_policy_object(SecPolicyRef policy
) {
621 xpc_object_t xpc_policy
= NULL
;
622 xpc_object_t data
[2] = { NULL
, NULL
};
623 if (policy
->_oid
&& (CFGetTypeID(policy
->_oid
) == CFStringGetTypeID()) &&
624 policy
->_name
&& (CFGetTypeID(policy
->_name
) == CFStringGetTypeID())) {
625 /* These should really be different elements of the xpc array. But
626 * SecPolicyCreateWithXPCObject previously checked the size via ==, which prevents
627 * us from appending new information while maintaining backward compatibility.
628 * Doing this makes the builders happy. */
629 CFMutableStringRef oidAndName
= NULL
;
630 oidAndName
= CFStringCreateMutableCopy(NULL
, 0, policy
->_oid
);
632 CFStringAppend(oidAndName
, CFSTR("++"));
633 CFStringAppend(oidAndName
, policy
->_name
);
634 data
[0] = _CFXPCCreateXPCObjectFromCFObject(oidAndName
);
635 CFReleaseNull(oidAndName
);
637 data
[0] = _CFXPCCreateXPCObjectFromCFObject(policy
->_oid
);
639 } else if (policy
->_oid
&& (CFGetTypeID(policy
->_oid
) == CFStringGetTypeID())) {
640 data
[0] = _CFXPCCreateXPCObjectFromCFObject(policy
->_oid
);
642 secerror("policy 0x%lX has no _oid", (uintptr_t)policy
);
644 if (policy
->_options
&& (CFGetTypeID(policy
->_options
) == CFDictionaryGetTypeID())) {
645 data
[1] = _CFXPCCreateXPCObjectFromCFObject(policy
->_options
);
647 secerror("policy 0x%lX has no _options", (uintptr_t)policy
);
649 xpc_policy
= xpc_array_create(data
, array_size(data
));
650 if (data
[0]) xpc_release(data
[0]);
651 if (data
[1]) xpc_release(data
[1]);
655 static bool append_policy_to_xpc_array(SecPolicyRef policy
, xpc_object_t xpc_policies
) {
659 xpc_object_t xpc_policy
= copy_xpc_policy_object(policy
);
663 xpc_array_append_value(xpc_policies
, xpc_policy
);
664 xpc_release(xpc_policy
);
668 xpc_object_t
copy_xpc_policies_array(CFArrayRef policies
) {
669 xpc_object_t xpc_policies
= xpc_array_create(NULL
, 0);
673 validate_array_of_items(policies
, CFSTR("policy"), SecPolicyGetTypeID(), true);
674 CFIndex ix
, count
= CFArrayGetCount(policies
);
675 for (ix
= 0; ix
< count
; ++ix
) {
676 SecPolicyRef policy
= (SecPolicyRef
) CFArrayGetValueAtIndex(policies
, ix
);
677 #if SECTRUST_VERBOSE_DEBUG
678 CFDictionaryRef props
= SecPolicyCopyProperties(policy
);
679 secerror("idx=%d of %d; policy=0x%lX properties=%@", (int)ix
, (int)count
, (uintptr_t)policy
, props
);
680 CFReleaseSafe(props
);
682 if (!append_policy_to_xpc_array(policy
, xpc_policies
)) {
683 xpc_release(xpc_policies
);
691 static xpc_object_t
SecPolicyCopyXPCObject(SecPolicyRef policy
, CFErrorRef
*error
) {
692 xpc_object_t xpc_policy
= NULL
;
693 xpc_object_t data
[2] = {};
694 CFMutableStringRef oidAndName
= NULL
;
695 oidAndName
= CFStringCreateMutableCopy(NULL
, 0, policy
->_oid
);
698 CFStringAppend(oidAndName
, CFSTR("++"));
699 CFStringAppend(oidAndName
, policy
->_name
);
702 require_action_quiet(data
[0] = _CFXPCCreateXPCObjectFromCFObject(oidAndName
), exit
,
703 SecError(errSecParam
, error
,
704 CFSTR("failed to create xpc_object from policy oid and name")));
706 require_action_quiet(data
[0] = _CFXPCCreateXPCObjectFromCFObject(policy
->_oid
), exit
,
707 SecError(errSecParam
, error
, CFSTR("failed to create xpc_object from policy oid")));
709 require_action_quiet(data
[1] = _CFXPCCreateXPCObjectFromCFObject(policy
->_options
), exit
,
710 SecError(errSecParam
, error
, CFSTR("failed to create xpc_object from policy options")));
711 require_action_quiet(xpc_policy
= xpc_array_create(data
, array_size(data
)), exit
,
712 SecError(errSecAllocate
, error
, CFSTR("failed to create xpc_array for policy")));
715 if (data
[0]) xpc_release(data
[0]);
716 if (data
[1]) xpc_release(data
[1]);
717 CFReleaseNull(oidAndName
);
721 static bool SecPolicyAppendToXPCArray(SecPolicyRef policy
, xpc_object_t policies
, CFErrorRef
*error
) {
725 xpc_object_t xpc_policy
= SecPolicyCopyXPCObject(policy
, error
);
729 xpc_array_append_value(policies
, xpc_policy
);
730 xpc_release(xpc_policy
);
734 xpc_object_t
SecPolicyArrayCopyXPCArray(CFArrayRef policies
, CFErrorRef
*error
) {
735 xpc_object_t xpc_policies
;
736 require_action_quiet(xpc_policies
= xpc_array_create(NULL
, 0), exit
,
737 SecError(errSecAllocate
, error
, CFSTR("failed to create xpc_array")));
738 CFIndex ix
, count
= CFArrayGetCount(policies
);
739 for (ix
= 0; ix
< count
; ++ix
) {
740 if (!SecPolicyAppendToXPCArray((SecPolicyRef
)CFArrayGetValueAtIndex(policies
, ix
), xpc_policies
, error
)) {
741 xpc_release(xpc_policies
);
749 static OSStatus
parseOidAndName(CFStringRef oidAndName
, CFStringRef
*oid
, CFStringRef
*name
) {
750 OSStatus result
= errSecSuccess
;
751 CFStringRef partial
= NULL
;
753 CFRange delimiter
= CFStringFind(oidAndName
, CFSTR("++"), 0);
754 if (delimiter
.length
!= 2) {
758 /* get first half: oid */
759 partial
= CFStringCreateWithSubstring(NULL
, oidAndName
, CFRangeMake(0, delimiter
.location
));
760 if (oid
) { *oid
= CFRetainSafe(partial
); }
761 CFReleaseNull(partial
);
763 /* get second half: name */
764 if (delimiter
.location
+ 2 >= CFStringGetLength(oidAndName
)) {
765 return errSecSuccess
; // name is optional
767 CFRange nameRange
= CFRangeMake(delimiter
.location
+2,
768 CFStringGetLength(oidAndName
) - delimiter
.location
- 2);
769 partial
= CFStringCreateWithSubstring(NULL
, oidAndName
, nameRange
);
770 if (name
) { *name
= CFRetainSafe(partial
); }
771 CFReleaseNull(partial
);
775 static SecPolicyRef
SecPolicyCreateWithXPCObject(xpc_object_t xpc_policy
, CFErrorRef
*error
) {
776 SecPolicyRef policy
= NULL
;
777 CFTypeRef oidAndName
= NULL
;
778 CFStringRef oid
= NULL
;
779 CFStringRef name
= NULL
;
780 CFTypeRef options
= NULL
;
782 require_action_quiet(xpc_policy
, exit
, SecError(errSecParam
, error
, CFSTR("policy xpc value is NULL")));
783 require_action_quiet(xpc_get_type(xpc_policy
) == XPC_TYPE_ARRAY
, exit
, SecError(errSecDecode
, error
, CFSTR("policy xpc value is not an array")));
784 require_action_quiet(xpc_array_get_count(xpc_policy
) >= 2, exit
, SecError(errSecDecode
, error
, CFSTR("policy xpc array count < 2")));
785 oidAndName
= _CFXPCCreateCFObjectFromXPCObject(xpc_array_get_value(xpc_policy
, 0));
786 require_action_quiet(isString(oidAndName
), exit
,
787 SecError(errSecParam
, error
, CFSTR("failed to convert xpc policy[0]=%@ to CFString"), oidAndName
));
788 options
= _CFXPCCreateCFObjectFromXPCObject(xpc_array_get_value(xpc_policy
, 1));
789 require_action_quiet(isDictionary(options
), exit
,
790 SecError(errSecParam
, error
, CFSTR("failed to convert xpc policy[1]=%@ to CFDictionary"), options
));
791 require_noerr_action_quiet(parseOidAndName(oidAndName
, &oid
, &name
), exit
,
792 SecError(errSecParam
, error
, CFSTR("failed to convert combined %@ to name and oid"), oidAndName
));
793 require_action_quiet(policy
= SecPolicyCreate(oid
, name
, options
), exit
,
794 SecError(errSecDecode
, error
, CFSTR("Failed to create policy")));
797 CFReleaseSafe(oidAndName
);
800 CFReleaseSafe(options
);
804 CFArrayRef
SecPolicyXPCArrayCopyArray(xpc_object_t xpc_policies
, CFErrorRef
*error
) {
805 CFMutableArrayRef policies
= NULL
;
806 require_action_quiet(xpc_get_type(xpc_policies
) == XPC_TYPE_ARRAY
, exit
,
807 SecError(errSecParam
, error
, CFSTR("policies xpc value is not an array")));
808 size_t count
= xpc_array_get_count(xpc_policies
);
809 require_action_quiet(policies
= CFArrayCreateMutable(kCFAllocatorDefault
, count
, &kCFTypeArrayCallBacks
), exit
,
810 SecError(errSecAllocate
, error
, CFSTR("failed to create CFArray of capacity %zu"), count
));
813 for (ix
= 0; ix
< count
; ++ix
) {
814 SecPolicyRef policy
= SecPolicyCreateWithXPCObject(xpc_array_get_value(xpc_policies
, ix
), error
);
819 CFArraySetValueAtIndex(policies
, ix
, policy
);
828 static SEC_CONST_DECL (kSecPolicyOptions
, "policyOptions");
830 static SecPolicyRef
SecPolicyCreateWithDictionary(CFDictionaryRef dict
) {
831 SecPolicyRef policy
= NULL
;
832 CFStringRef oid
= (CFStringRef
)CFDictionaryGetValue(dict
, kSecPolicyOid
);
833 require_quiet(isString(oid
), errOut
);
834 CFDictionaryRef options
= (CFDictionaryRef
)CFDictionaryGetValue(dict
, kSecPolicyOptions
);
835 require_quiet(isDictionary(options
), errOut
);
836 CFStringRef name
= (CFStringRef
)CFDictionaryGetValue(dict
, kSecPolicyPolicyName
);
837 policy
= SecPolicyCreate(oid
, name
, options
);
842 static void deserializePolicy(const void *value
, void *context
) {
843 CFDictionaryRef policyDict
= (CFDictionaryRef
)value
;
844 if (isDictionary(policyDict
)) {
845 CFTypeRef deserializedPolicy
= SecPolicyCreateWithDictionary(policyDict
);
846 if (deserializedPolicy
) {
847 CFArrayAppendValue((CFMutableArrayRef
)context
, deserializedPolicy
);
848 CFRelease(deserializedPolicy
);
853 CFArrayRef
SecPolicyArrayCreateDeserialized(CFArrayRef serializedPolicies
) {
854 CFMutableArrayRef result
= NULL
;
855 require_quiet(isArray(serializedPolicies
), errOut
);
856 CFIndex count
= CFArrayGetCount(serializedPolicies
);
857 result
= CFArrayCreateMutable(kCFAllocatorDefault
, count
, &kCFTypeArrayCallBacks
);
858 CFRange all_policies
= { 0, count
};
859 CFArrayApplyFunction(serializedPolicies
, all_policies
, deserializePolicy
, result
);
864 static CFDictionaryRef
SecPolicyCreateDictionary(SecPolicyRef policy
) {
865 CFMutableDictionaryRef dict
= NULL
;
866 dict
= CFDictionaryCreateMutable(NULL
, 3, &kCFTypeDictionaryKeyCallBacks
,
867 &kCFTypeDictionaryValueCallBacks
);
868 CFDictionaryAddValue(dict
, kSecPolicyOid
, policy
->_oid
);
869 CFDictionaryAddValue(dict
, kSecPolicyOptions
, policy
->_options
);
871 CFDictionaryAddValue(dict
, kSecPolicyPolicyName
, policy
->_name
);
876 static void serializePolicy(const void *value
, void *context
) {
877 SecPolicyRef policy
= (SecPolicyRef
)value
;
878 if (policy
&& SecPolicyGetTypeID() == CFGetTypeID(policy
)) {
879 CFDictionaryRef serializedPolicy
= SecPolicyCreateDictionary(policy
);
880 if (serializedPolicy
) {
881 CFArrayAppendValue((CFMutableArrayRef
)context
, serializedPolicy
);
882 CFRelease(serializedPolicy
);
887 CFArrayRef
SecPolicyArrayCreateSerialized(CFArrayRef policies
) {
888 CFMutableArrayRef result
= NULL
;
889 require_quiet(isArray(policies
), errOut
);
890 CFIndex count
= CFArrayGetCount(policies
);
891 result
= CFArrayCreateMutable(NULL
, count
, &kCFTypeArrayCallBacks
);
892 CFRange all_policies
= { 0, count
};
893 CFArrayApplyFunction(policies
, all_policies
, serializePolicy
, result
);
898 static void add_element(CFMutableDictionaryRef options
, CFStringRef key
,
900 CFTypeRef old_value
= CFDictionaryGetValue(options
, key
);
902 CFMutableArrayRef array
;
903 if (CFGetTypeID(old_value
) == CFArrayGetTypeID()) {
904 array
= (CFMutableArrayRef
)old_value
;
906 array
= CFArrayCreateMutable(kCFAllocatorDefault
, 0,
907 &kCFTypeArrayCallBacks
);
908 CFArrayAppendValue(array
, old_value
);
909 CFDictionarySetValue(options
, key
, array
);
912 CFArrayAppendValue(array
, value
);
914 CFDictionaryAddValue(options
, key
, value
);
918 static void add_eku(CFMutableDictionaryRef options
, const DERItem
*ekuOid
) {
919 CFDataRef eku
= CFDataCreate(kCFAllocatorDefault
,
920 ekuOid
? ekuOid
->data
: NULL
,
921 ekuOid
? ekuOid
->length
: 0);
923 add_element(options
, kSecPolicyCheckExtendedKeyUsage
, eku
);
928 static void add_eku_string(CFMutableDictionaryRef options
, CFStringRef ekuOid
) {
930 add_element(options
, kSecPolicyCheckExtendedKeyUsage
, ekuOid
);
934 static void set_ssl_ekus(CFMutableDictionaryRef options
, bool server
) {
935 CFDictionaryRemoveValue(options
, kSecPolicyCheckExtendedKeyUsage
);
937 /* If server and EKU ext present then EKU ext should contain one of
938 ServerAuth or ExtendedKeyUsageAny or NetscapeSGC or MicrosoftSGC.
939 else if !server and EKU ext present then EKU ext should contain one of
940 ClientAuth or ExtendedKeyUsageAny. */
942 /* We always allow certificates that specify oidAnyExtendedKeyUsage. */
943 add_eku(options
, NULL
); /* eku extension is optional */
944 add_eku(options
, &oidAnyExtendedKeyUsage
);
946 add_eku(options
, &oidExtendedKeyUsageServerAuth
);
947 add_eku(options
, &oidExtendedKeyUsageMicrosoftSGC
);
948 add_eku(options
, &oidExtendedKeyUsageNetscapeSGC
);
950 add_eku(options
, &oidExtendedKeyUsageClientAuth
);
954 static void add_ku(CFMutableDictionaryRef options
, SecKeyUsage keyUsage
) {
955 SInt32 dku
= keyUsage
;
956 CFNumberRef ku
= CFNumberCreate(kCFAllocatorDefault
, kCFNumberSInt32Type
,
959 add_element(options
, kSecPolicyCheckKeyUsage
, ku
);
965 static void set_ku_from_properties(SecPolicyRef policy
, CFDictionaryRef properties
) {
966 if (!policy
|| !properties
) {
970 CFStringRef keyNames
[] = { kSecPolicyKU_DigitalSignature
, kSecPolicyKU_NonRepudiation
, kSecPolicyKU_KeyEncipherment
, kSecPolicyKU_DataEncipherment
,
971 kSecPolicyKU_KeyAgreement
, kSecPolicyKU_KeyCertSign
, kSecPolicyKU_CRLSign
, kSecPolicyKU_EncipherOnly
, kSecPolicyKU_DecipherOnly
};
973 uint32_t keyUsageValues
[] = { kSecKeyUsageDigitalSignature
, kSecKeyUsageNonRepudiation
, kSecKeyUsageKeyEncipherment
, kSecKeyUsageDataEncipherment
,
974 kSecKeyUsageKeyAgreement
, kSecKeyUsageKeyCertSign
, kSecKeyUsageCRLSign
, kSecKeyUsageEncipherOnly
, kSecKeyUsageDecipherOnly
};
976 bool haveKeyUsage
= false;
977 CFTypeRef keyUsageBoolean
;
978 for (uint32_t i
= 0; i
< sizeof(keyNames
) / sizeof(CFStringRef
); ++i
) {
979 if (CFDictionaryGetValueIfPresent(properties
, keyNames
[i
], (const void**)&keyUsageBoolean
)) {
980 if (CFEqual(keyUsageBoolean
, kCFBooleanTrue
)) {
991 CFMutableDictionaryRef options
= (CFMutableDictionaryRef
) policy
->_options
;
993 options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
994 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
995 if (!options
) return;
996 policy
->_options
= options
;
998 CFDictionaryRemoveValue(options
, kSecPolicyCheckKeyUsage
);
1001 for (uint32_t i
= 0; i
< sizeof(keyNames
) / sizeof(CFStringRef
); ++i
) {
1002 if (CFDictionaryGetValueIfPresent(properties
, keyNames
[i
], (const void**)&keyUsageBoolean
)) {
1003 if (CFEqual(keyUsageBoolean
, kCFBooleanTrue
)) {
1004 add_ku(options
, keyUsageValues
[i
]);
1011 static void add_oid(CFMutableDictionaryRef options
, CFStringRef policy_key
, const DERItem
*oid
) {
1012 CFDataRef oid_data
= CFDataCreate(kCFAllocatorDefault
,
1013 oid
? oid
->data
: NULL
,
1014 oid
? oid
->length
: 0);
1016 add_element(options
, policy_key
, oid_data
);
1017 CFRelease(oid_data
);
1021 static void add_leaf_marker_value(CFMutableDictionaryRef options
, const DERItem
*markerOid
, CFStringRef string_value
) {
1023 CFTypeRef policyData
= NULL
;
1025 if (NULL
== string_value
) {
1026 policyData
= CFDataCreate(kCFAllocatorDefault
,
1027 markerOid
? markerOid
->data
: NULL
,
1028 markerOid
? markerOid
->length
: 0);
1030 CFStringRef oid_as_string
= SecDERItemCopyOIDDecimalRepresentation(kCFAllocatorDefault
, markerOid
);
1032 const void *key
[1] = { oid_as_string
};
1033 const void *value
[1] = { string_value
};
1034 policyData
= CFDictionaryCreate(kCFAllocatorDefault
,
1036 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
1037 CFReleaseNull(oid_as_string
);
1040 add_element(options
, kSecPolicyCheckLeafMarkerOid
, policyData
);
1042 CFReleaseNull(policyData
);
1046 static void add_leaf_marker(CFMutableDictionaryRef options
, const DERItem
*markerOid
) {
1047 add_leaf_marker_value(options
, markerOid
, NULL
);
1050 static void add_leaf_marker_value_string(CFMutableDictionaryRef options
, CFStringRef markerOid
, CFStringRef string_value
) {
1051 if (NULL
== string_value
) {
1052 add_element(options
, kSecPolicyCheckLeafMarkerOid
, markerOid
);
1054 CFDictionaryRef policyData
= NULL
;
1055 const void *key
[1] = { markerOid
};
1056 const void *value
[1] = { string_value
};
1057 policyData
= CFDictionaryCreate(kCFAllocatorDefault
,
1059 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
1060 add_element(options
, kSecPolicyCheckLeafMarkerOid
, policyData
);
1062 CFReleaseNull(policyData
);
1066 static void add_leaf_marker_string(CFMutableDictionaryRef options
, CFStringRef markerOid
) {
1067 add_leaf_marker_value_string(options
, markerOid
, NULL
);
1070 static void add_leaf_prod_qa_element(CFMutableDictionaryRef options
, CFTypeRef prodValue
, CFTypeRef qaValue
)
1072 CFMutableDictionaryRef prodAndQADictionary
= CFDictionaryCreateMutable(NULL
, 0, &kCFTypeDictionaryKeyCallBacks
,
1073 &kCFTypeDictionaryValueCallBacks
);
1074 CFDictionaryRef old_value
= CFDictionaryGetValue(options
, kSecPolicyCheckLeafMarkersProdAndQA
);
1076 CFMutableArrayRef prodArray
= NULL
, qaArray
= NULL
;
1077 CFTypeRef old_prod_value
= CFDictionaryGetValue(old_value
, kSecPolicyLeafMarkerProd
);
1078 CFTypeRef old_qa_value
= CFDictionaryGetValue(old_value
, kSecPolicyLeafMarkerQA
);
1079 if (isArray(old_prod_value
) && isArray(old_qa_value
)) {
1080 prodArray
= (CFMutableArrayRef
)CFRetainSafe(old_prod_value
);
1081 qaArray
= (CFMutableArrayRef
)CFRetainSafe(old_qa_value
);
1083 prodArray
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
1084 qaArray
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
1085 CFArrayAppendValue(prodArray
, old_prod_value
);
1086 CFArrayAppendValue(qaArray
, old_qa_value
);
1088 CFArrayAppendValue(prodArray
, prodValue
);
1089 CFArrayAppendValue(qaArray
, qaValue
);
1090 CFDictionaryAddValue(prodAndQADictionary
, kSecPolicyLeafMarkerProd
, prodArray
);
1091 CFDictionaryAddValue(prodAndQADictionary
, kSecPolicyLeafMarkerQA
, qaArray
);
1092 CFReleaseNull(prodArray
);
1093 CFReleaseNull(qaArray
);
1096 CFDictionaryAddValue(prodAndQADictionary
, kSecPolicyLeafMarkerProd
, prodValue
);
1097 CFDictionaryAddValue(prodAndQADictionary
, kSecPolicyLeafMarkerQA
, qaValue
);
1099 CFDictionarySetValue(options
, kSecPolicyCheckLeafMarkersProdAndQA
, prodAndQADictionary
);
1100 CFReleaseNull(prodAndQADictionary
);
1104 static void add_leaf_prod_qa_markers(CFMutableDictionaryRef options
, const DERItem
*prodMarkerOid
, const DERItem
*qaMarkerOid
)
1106 CFDataRef prodData
= NULL
, qaData
= NULL
;
1107 prodData
= CFDataCreate(NULL
, prodMarkerOid
? prodMarkerOid
->data
: NULL
,
1108 prodMarkerOid
? prodMarkerOid
->length
: 0);
1109 qaData
= CFDataCreate(NULL
, qaMarkerOid
? qaMarkerOid
->data
: NULL
,
1110 qaMarkerOid
? qaMarkerOid
->length
: 0);
1111 add_leaf_prod_qa_element(options
, prodData
, qaData
);
1112 CFReleaseNull(prodData
);
1113 CFReleaseNull(qaData
);
1116 static void add_leaf_prod_qa_markers_string(CFMutableDictionaryRef options
, CFStringRef prodMarkerOid
, CFStringRef qaMarkerOid
)
1118 add_leaf_prod_qa_element(options
, prodMarkerOid
, qaMarkerOid
);
1121 static void add_leaf_prod_qa_markers_value_string(CFMutableDictionaryRef options
,
1122 CFStringRef prodMarkerOid
, CFStringRef prod_value
,
1123 CFStringRef qaMarkerOid
, CFStringRef qa_value
)
1125 if (!prod_value
&& !qa_value
) {
1126 add_leaf_prod_qa_element(options
, prodMarkerOid
, qaMarkerOid
);
1128 CFDictionaryRef prodData
= NULL
, qaData
= NULL
;
1129 const void *prodKey
[1] = { prodMarkerOid
}, *qaKey
[1] = { qaMarkerOid
};
1130 const void *prodValue
[1] = { prod_value
}, *qaValue
[1] = { qa_value
};
1131 prodData
= CFDictionaryCreate(NULL
, prodKey
, prodValue
, 1, &kCFTypeDictionaryKeyCallBacks
,
1132 &kCFTypeDictionaryValueCallBacks
);
1133 qaData
= CFDictionaryCreate(NULL
, qaKey
, qaValue
, 1, &kCFTypeDictionaryKeyCallBacks
,
1134 &kCFTypeDictionaryValueCallBacks
);
1135 add_leaf_prod_qa_element(options
, prodData
, qaData
);
1136 CFReleaseNull(prodData
);
1137 CFReleaseNull(qaData
);
1141 static void add_intermediate_marker_value_string(CFMutableDictionaryRef options
, CFStringRef markerOid
, CFStringRef string_value
) {
1142 if (NULL
== string_value
) {
1143 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, markerOid
);
1145 CFDictionaryRef policyData
= NULL
;
1146 const void *key
[1] = { markerOid
};
1147 const void *value
[1] = { string_value
};
1148 policyData
= CFDictionaryCreate(kCFAllocatorDefault
,
1150 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
1151 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, policyData
);
1153 CFReleaseNull(policyData
);
1157 static void add_certificate_policy_oid(CFMutableDictionaryRef options
, const DERItem
*certificatePolicyOid
) {
1158 CFTypeRef certificatePolicyData
= NULL
;
1159 certificatePolicyData
= CFDataCreate(kCFAllocatorDefault
,
1160 certificatePolicyOid
? certificatePolicyOid
->data
: NULL
,
1161 certificatePolicyOid
? certificatePolicyOid
->length
: 0);
1162 if (certificatePolicyData
) {
1163 add_element(options
, kSecPolicyCheckCertificatePolicy
, certificatePolicyData
);
1164 CFRelease(certificatePolicyData
);
1168 static void add_certificate_policy_oid_string(CFMutableDictionaryRef options
, CFStringRef certificatePolicyOid
) {
1169 if (certificatePolicyOid
) {
1170 add_element(options
, kSecPolicyCheckCertificatePolicy
, certificatePolicyOid
);
1175 // Routines for adding dictionary entries for policies.
1178 // X.509, but missing validity requirements.
1179 static void SecPolicyAddBasicCertOptions(CFMutableDictionaryRef options
)
1181 //CFDictionaryAddValue(options, kSecPolicyCheckBasicCertificateProcessing, kCFBooleanTrue);
1182 // Happens automatically in SecPVCPathChecks
1183 CFDictionaryAddValue(options
, kSecPolicyCheckCriticalExtensions
, kCFBooleanTrue
);
1184 CFDictionaryAddValue(options
, kSecPolicyCheckIdLinkage
, kCFBooleanTrue
);
1185 CFDictionaryAddValue(options
, kSecPolicyCheckBasicConstraints
, kCFBooleanTrue
);
1186 CFDictionaryAddValue(options
, kSecPolicyCheckNonEmptySubject
, kCFBooleanTrue
);
1187 CFDictionaryAddValue(options
, kSecPolicyCheckWeakKeySize
, kCFBooleanTrue
);
1188 CFDictionaryAddValue(options
, kSecPolicyCheckWeakSignature
, kCFBooleanTrue
);
1191 static void SecPolicyAddBasicX509Options(CFMutableDictionaryRef options
)
1193 SecPolicyAddBasicCertOptions(options
);
1194 CFDictionaryAddValue(options
, kSecPolicyCheckTemporalValidity
, kCFBooleanTrue
);
1196 // Make sure that black and gray leaf checks are performed for basic X509 chain building
1197 CFDictionaryAddValue(options
, kSecPolicyCheckBlackListedLeaf
, kCFBooleanTrue
);
1198 CFDictionaryAddValue(options
, kSecPolicyCheckGrayListedLeaf
, kCFBooleanTrue
);
1201 static bool SecPolicyAddChainLengthOptions(CFMutableDictionaryRef options
, CFIndex length
)
1203 bool result
= false;
1204 CFNumberRef lengthAsCF
= NULL
;
1206 require(lengthAsCF
= CFNumberCreate(kCFAllocatorDefault
,
1207 kCFNumberCFIndexType
, &length
), errOut
);
1208 CFDictionaryAddValue(options
, kSecPolicyCheckChainLength
, lengthAsCF
);
1213 CFReleaseSafe(lengthAsCF
);
1217 static bool SecPolicyAddAnchorSHA1Options(CFMutableDictionaryRef options
,
1218 const UInt8 anchorSha1
[kSecPolicySHA1Size
])
1220 bool success
= false;
1221 CFDataRef anchorData
= NULL
;
1223 require(anchorData
= CFDataCreate(kCFAllocatorDefault
, anchorSha1
, kSecPolicySHA1Size
), errOut
);
1224 add_element(options
, kSecPolicyCheckAnchorSHA1
, anchorData
);
1229 CFReleaseSafe(anchorData
);
1233 static bool SecPolicyAddAnchorSHA256Options(CFMutableDictionaryRef options
,
1234 const UInt8 anchorSha1
[kSecPolicySHA256Size
])
1236 bool success
= false;
1237 CFDataRef anchorData
= NULL
;
1239 require(anchorData
= CFDataCreate(kCFAllocatorDefault
, anchorSha1
, kSecPolicySHA256Size
), errOut
);
1240 add_element(options
, kSecPolicyCheckAnchorSHA256
, anchorData
);
1245 CFReleaseSafe(anchorData
);
1249 static bool SecPolicyAddStrongKeySizeOptions(CFMutableDictionaryRef options
) {
1250 bool success
= false;
1251 CFDictionaryRef keySizes
= NULL
;
1252 CFNumberRef rsaSize
= NULL
, ecSize
= NULL
;
1254 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
1255 require(rsaSize
= CFNumberCreateWithCFIndex(NULL
, 2048), errOut
);
1256 require(ecSize
= CFNumberCreateWithCFIndex(NULL
, 256), errOut
);
1257 const void *keys
[] = { kSecAttrKeyTypeRSA
, kSecAttrKeyTypeEC
};
1258 const void *values
[] = { rsaSize
, ecSize
};
1259 require(keySizes
= CFDictionaryCreate(NULL
, keys
, values
, 2,
1260 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1261 add_element(options
, kSecPolicyCheckKeySize
, keySizes
);
1266 CFReleaseSafe(keySizes
);
1267 CFReleaseSafe(rsaSize
);
1268 CFReleaseSafe(ecSize
);
1272 static bool isAppleOid(CFStringRef oid
) {
1273 if (!SecCertificateIsOidString(oid
)) {
1276 if (CFStringHasPrefix(oid
, CFSTR("1.2.840.113635"))) {
1282 static bool isCFPreferenceInSecurityDomain(CFStringRef setting
) {
1283 return (CFPreferencesGetAppBooleanValue(setting
, CFSTR("com.apple.security"), NULL
));
1286 static bool SecPolicyAddAppleAnchorOptions(CFMutableDictionaryRef options
, CFStringRef __unused policyName
)
1288 CFMutableDictionaryRef appleAnchorOptions
= NULL
;
1289 appleAnchorOptions
= CFDictionaryCreateMutableForCFTypes(NULL
);
1290 if (!appleAnchorOptions
) {
1294 /* Currently no Apple Anchor options */
1295 add_element(options
, kSecPolicyCheckAnchorApple
, appleAnchorOptions
);
1296 CFReleaseSafe(appleAnchorOptions
);
1300 static bool SecPolicyAddPinningRequiredIfInfoSpecified(CFMutableDictionaryRef options
)
1302 CFBundleRef bundle
= CFBundleGetMainBundle();
1304 CFTypeRef value
= CFBundleGetValueForInfoDictionaryKey(bundle
, CFSTR("SecTrustPinningRequired"));
1305 if (isBoolean(value
) && CFBooleanGetValue(value
)) {
1306 add_element(options
, kSecPolicyCheckPinningRequired
, kCFBooleanTrue
);
1315 // MARK: Policy Creation Functions
1317 SecPolicyRef
SecPolicyCreateBasicX509(void) {
1318 CFMutableDictionaryRef options
= NULL
;
1319 SecPolicyRef result
= NULL
;
1321 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1322 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1324 SecPolicyAddBasicX509Options(options
);
1325 CFDictionaryAddValue(options
, kSecPolicyCheckNoNetworkAccess
,
1328 require(result
= SecPolicyCreate(kSecPolicyAppleX509Basic
, kSecPolicyNameX509Basic
, options
), errOut
);
1331 CFReleaseSafe(options
);
1332 return (SecPolicyRef _Nonnull
)result
;
1335 SecPolicyRef
SecPolicyCreateSSL(Boolean server
, CFStringRef hostname
) {
1336 CFMutableDictionaryRef options
= NULL
;
1337 SecPolicyRef result
= NULL
;
1339 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1340 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1342 SecPolicyAddBasicX509Options(options
);
1345 CFDictionaryAddValue(options
, kSecPolicyCheckSSLHostname
, hostname
);
1348 CFDictionaryAddValue(options
, kSecPolicyCheckBlackListedLeaf
, kCFBooleanTrue
);
1349 CFDictionaryAddValue(options
, kSecPolicyCheckGrayListedLeaf
, kCFBooleanTrue
);
1352 CFDictionaryAddValue(options
, kSecPolicyCheckSystemTrustedWeakHash
, kCFBooleanTrue
);
1353 CFDictionaryAddValue(options
, kSecPolicyCheckSystemTrustedWeakKey
, kCFBooleanTrue
);
1354 require_quiet(SecPolicyAddPinningRequiredIfInfoSpecified(options
), errOut
);
1357 set_ssl_ekus(options
, server
);
1359 require(result
= SecPolicyCreate(kSecPolicyAppleSSL
,
1360 server
? kSecPolicyNameSSLServer
: kSecPolicyNameSSLClient
,
1364 CFReleaseSafe(options
);
1365 return (SecPolicyRef _Nonnull
)result
;
1368 SecPolicyRef
SecPolicyCreateApplePinned(CFStringRef policyName
, CFStringRef intermediateMarkerOID
, CFStringRef leafMarkerOID
) {
1369 CFMutableDictionaryRef options
= NULL
;
1370 SecPolicyRef result
= NULL
;
1372 if (!policyName
|| !intermediateMarkerOID
|| !leafMarkerOID
) {
1376 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1377 &kCFTypeDictionaryKeyCallBacks
,
1378 &kCFTypeDictionaryValueCallBacks
), errOut
);
1380 SecPolicyAddBasicX509Options(options
);
1382 /* Anchored to the Apple Roots */
1383 require(SecPolicyAddAppleAnchorOptions(options
, policyName
), errOut
);
1385 /* Exactly 3 certs in the chain */
1386 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1388 /* Intermediate marker OID matches input OID */
1389 if (!isAppleOid(intermediateMarkerOID
)) {
1390 secwarning("creating an Apple pinning policy with a non-Apple OID: %@", intermediateMarkerOID
);
1392 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, intermediateMarkerOID
);
1394 /* Leaf marker OID matches input OID */
1395 if (!isAppleOid(leafMarkerOID
)) {
1396 secwarning("creating an Apple pinning policy with a non-Apple OID: %@", leafMarkerOID
);
1398 add_leaf_marker_string(options
, leafMarkerOID
);
1400 /* Check revocation using any available method */
1401 add_element(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
1403 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
1404 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
1406 /* Check for weak hashes */
1407 CFDictionaryAddValue(options
, kSecPolicyCheckSystemTrustedWeakHash
, kCFBooleanTrue
);
1408 require(result
= SecPolicyCreate(kSecPolicyAppleGenericApplePinned
,
1409 policyName
, options
), errOut
);
1412 CFReleaseSafe(options
);
1417 requireUATPinning(CFStringRef service
)
1419 bool pinningRequired
= true;
1421 if (SecIsInternalRelease()) {
1422 CFStringRef setting
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("AppleServerAuthenticationNoPinning%@"), service
);
1423 require(setting
, fail
);
1424 if(isCFPreferenceInSecurityDomain(setting
)) {
1425 pinningRequired
= false;
1427 secnotice("pinningQA", "could not disable pinning: %@ not true", setting
);
1431 if (!pinningRequired
) {
1435 if(isCFPreferenceInSecurityDomain(CFSTR("AppleServerAuthenticationNoPinning"))) {
1436 pinningRequired
= false;
1438 secnotice("pinningQA", "could not disable pinning: AppleServerAuthenticationNoPinning not true");
1441 secnotice("pinningQA", "could not disable pinning: not an internal release");
1444 return pinningRequired
;
1447 SecPolicyRef
SecPolicyCreateAppleSSLPinned(CFStringRef policyName
, CFStringRef hostname
,
1448 CFStringRef intermediateMarkerOID
, CFStringRef leafMarkerOID
) {
1449 CFMutableDictionaryRef options
= NULL
, appleAnchorOptions
= NULL
;
1450 SecPolicyRef result
= NULL
;
1452 if (!policyName
|| !hostname
|| !leafMarkerOID
) {
1456 if (requireUATPinning(policyName
)) {
1457 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1458 &kCFTypeDictionaryKeyCallBacks
,
1459 &kCFTypeDictionaryValueCallBacks
), errOut
);
1461 SecPolicyAddBasicX509Options(options
);
1463 /* Anchored to the Apple Roots */
1464 require(SecPolicyAddAppleAnchorOptions(options
, policyName
), errOut
);
1466 /* Exactly 3 certs in the chain */
1467 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1469 if (intermediateMarkerOID
) {
1470 /* Intermediate marker OID matches input OID */
1471 if (!isAppleOid(intermediateMarkerOID
)) {
1472 secwarning("creating an Apple pinning policy with a non-Apple OID: %@", intermediateMarkerOID
);
1474 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, intermediateMarkerOID
);
1476 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.12"));
1479 /* Leaf marker OID matches input OID */
1480 if (!isAppleOid(leafMarkerOID
)) {
1481 secwarning("creating an Apple pinning policy with a non-Apple OID: %@", leafMarkerOID
);
1483 add_leaf_marker_string(options
, leafMarkerOID
);
1485 /* New leaf marker OID format */
1486 add_leaf_marker_value_string(options
, CFSTR("1.2.840.113635.100.6.48.1"), leafMarkerOID
);
1488 /* ServerAuth EKU is in leaf cert */
1489 add_eku_string(options
, CFSTR("1.3.6.1.5.5.7.3.1"));
1491 /* Hostname is in leaf cert */
1492 add_element(options
, kSecPolicyCheckSSLHostname
, hostname
);
1494 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
1495 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
1497 /* Check for weak hashes */
1498 CFDictionaryAddValue(options
, kSecPolicyCheckSystemTrustedWeakHash
, kCFBooleanTrue
);
1500 /* Check revocation using any available method */
1501 add_element(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
1503 require(result
= SecPolicyCreate(kSecPolicyAppleGenericAppleSSLPinned
,
1504 policyName
, options
), errOut
);
1507 result
= SecPolicyCreateSSL(true, hostname
);
1508 SecPolicySetOid(result
, kSecPolicyAppleGenericAppleSSLPinned
);
1509 SecPolicySetName(result
, policyName
);
1513 CFReleaseSafe(options
);
1514 CFReleaseSafe(appleAnchorOptions
);
1518 SecPolicyRef
SecPolicyCreateiPhoneActivation(void) {
1519 CFMutableDictionaryRef options
= NULL
;
1520 SecPolicyRef result
= NULL
;
1522 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1523 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1525 SecPolicyAddBasicCertOptions(options
);
1528 CFDictionaryAddValue(options
, kSecPolicyCheckKeyUsage
,
1530 CFDictionaryAddValue(options
, kSecPolicyCheckExtendedKeyUsage
,
1534 /* Basic X.509 policy with the additional requirements that the chain
1535 length is 3, it's anchored at the AppleCA and the leaf certificate
1536 has issuer "Apple iPhone Certification Authority" and
1537 subject "Apple iPhone Activation" for the common name. */
1538 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
1539 CFSTR("Apple iPhone Certification Authority"));
1540 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
,
1541 CFSTR("Apple iPhone Activation"));
1543 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1544 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameiPhoneActivation
), errOut
);
1546 require(result
= SecPolicyCreate(kSecPolicyAppleiPhoneActivation
,
1547 kSecPolicyNameiPhoneActivation
, options
),
1551 CFReleaseSafe(options
);
1555 SecPolicyRef
SecPolicyCreateiPhoneDeviceCertificate(void) {
1556 CFMutableDictionaryRef options
= NULL
;
1557 SecPolicyRef result
= NULL
;
1559 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1560 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1562 SecPolicyAddBasicCertOptions(options
);
1565 CFDictionaryAddValue(options
, kSecPolicyCheckKeyUsage
,
1567 CFDictionaryAddValue(options
, kSecPolicyCheckExtendedKeyUsage
,
1571 /* Basic X.509 policy with the additional requirements that the chain
1572 length is 4, it's anchored at the AppleCA and the first intermediate
1573 has the subject "Apple iPhone Device CA". */
1574 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
1575 CFSTR("Apple iPhone Device CA"));
1577 require(SecPolicyAddChainLengthOptions(options
, 4), errOut
);
1578 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameiPhoneDeviceCertificate
), errOut
);
1580 require(result
= SecPolicyCreate(kSecPolicyAppleiPhoneDeviceCertificate
,
1581 kSecPolicyNameiPhoneDeviceCertificate
, options
),
1585 CFReleaseSafe(options
);
1589 SecPolicyRef
SecPolicyCreateFactoryDeviceCertificate(void) {
1590 CFMutableDictionaryRef options
= NULL
;
1591 SecPolicyRef result
= NULL
;
1593 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1594 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1596 SecPolicyAddBasicCertOptions(options
);
1599 CFDictionaryAddValue(options
, kSecPolicyCheckKeyUsage
,
1601 CFDictionaryAddValue(options
, kSecPolicyCheckExtendedKeyUsage
,
1605 /* Basic X.509 policy with the additional requirements that the chain
1606 is anchored at the factory device certificate issuer. */
1607 require(SecPolicyAddAnchorSHA1Options(options
, kFactoryDeviceCASHA1
), errOut
);
1609 require(result
= SecPolicyCreate(kSecPolicyAppleFactoryDeviceCertificate
,
1610 kSecPolicyNameFactoryDeviceCertificate
, options
),
1614 CFReleaseSafe(options
);
1618 SecPolicyRef
SecPolicyCreateiAP(void) {
1619 CFMutableDictionaryRef options
= NULL
;
1620 SecPolicyRef result
= NULL
;
1621 CFTimeZoneRef tz
= NULL
;
1622 CFDateRef date
= NULL
;
1624 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1625 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1627 SecPolicyAddBasicCertOptions(options
);
1629 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonNamePrefix
,
1632 date
= CFDateCreateForGregorianZuluDay(NULL
, 2006, 5, 31);
1633 CFDictionaryAddValue(options
, kSecPolicyCheckNotValidBefore
, date
);
1635 require(result
= SecPolicyCreate(kSecPolicyAppleiAP
,
1636 kSecPolicyNameiAP
, options
),
1640 CFReleaseSafe(date
);
1642 CFReleaseSafe(options
);
1646 SecPolicyRef
SecPolicyCreateiTunesStoreURLBag(void) {
1647 CFMutableDictionaryRef options
= NULL
;
1648 SecPolicyRef result
= NULL
;
1651 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1652 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1654 SecPolicyAddBasicCertOptions(options
);
1656 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectOrganization
,
1657 CFSTR("Apple Inc."));
1658 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
,
1659 CFSTR("iTunes Store URL Bag"));
1661 require(SecPolicyAddChainLengthOptions(options
, 2), errOut
);
1662 require(SecPolicyAddAnchorSHA1Options(options
, kITMSCASHA1
), errOut
);
1664 require(result
= SecPolicyCreate(kSecPolicyAppleiTunesStoreURLBag
,
1665 kSecPolicyNameiTunesStoreURLBag
, options
), errOut
);
1668 CFReleaseSafe(options
);
1672 SecPolicyRef
SecPolicyCreateEAP(Boolean server
, CFArrayRef trustedServerNames
) {
1673 CFMutableDictionaryRef options
= NULL
;
1674 SecPolicyRef result
= NULL
;
1676 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1677 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1679 SecPolicyAddBasicX509Options(options
);
1681 /* Since EAP is used to setup the network we don't want evaluation
1682 using this policy to access the network. */
1683 CFDictionaryAddValue(options
, kSecPolicyCheckNoNetworkAccess
,
1686 if (trustedServerNames
) {
1687 CFDictionaryAddValue(options
, kSecPolicyCheckEAPTrustedServerNames
, trustedServerNames
);
1691 /* Check for weak hashes */
1692 CFDictionaryAddValue(options
, kSecPolicyCheckSystemTrustedWeakHash
, kCFBooleanTrue
);
1693 CFDictionaryAddValue(options
, kSecPolicyCheckSystemTrustedWeakKey
, kCFBooleanTrue
);
1696 /* We need to check for EKU per rdar://22206018 */
1697 set_ssl_ekus(options
, server
);
1699 require(result
= SecPolicyCreate(kSecPolicyAppleEAP
,
1700 server
? kSecPolicyNameEAPServer
: kSecPolicyNameEAPClient
,
1704 CFReleaseSafe(options
);
1708 SecPolicyRef
SecPolicyCreateIPSec(Boolean server
, CFStringRef hostname
) {
1709 CFMutableDictionaryRef options
= NULL
;
1710 SecPolicyRef result
= NULL
;
1712 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1713 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1715 SecPolicyAddBasicX509Options(options
);
1718 CFDictionaryAddValue(options
, kSecPolicyCheckSSLHostname
, hostname
);
1721 /* Require oidExtendedKeyUsageIPSec if Extended Keyusage Extention is
1723 /* Per <rdar://problem/6843827> Cisco VPN Certificate compatibility issue.
1724 We don't check the EKU for IPSec certs for now. If we do add eku
1725 checking back in the future, we should probably also accept the
1727 ipsecEndSystem 1.3.6.1.5.5.7.3.5
1729 ipsecTunnel 1.3.6.1.5.5.7.3.6
1730 ipsecUser 1.3.6.1.5.5.7.3.7
1732 //add_eku(options, NULL); /* eku extension is optional */
1733 //add_eku(options, &oidAnyExtendedKeyUsage);
1734 //add_eku(options, &oidExtendedKeyUsageIPSec);
1736 require(result
= SecPolicyCreate(kSecPolicyAppleIPsec
,
1737 server
? kSecPolicyNameIPSecServer
: kSecPolicyNameIPSecClient
,
1741 CFReleaseSafe(options
);
1745 SecPolicyRef
SecPolicyCreateiPhoneApplicationSigning(void) {
1746 CFMutableDictionaryRef options
= NULL
;
1747 SecPolicyRef result
= NULL
;
1749 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1750 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1752 SecPolicyAddBasicCertOptions(options
);
1754 /* Anchored to the Apple Roots */
1755 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameiPhoneApplicationSigning
), errOut
);
1758 if (SecIsInternalRelease()) {
1759 /* Allow a prod hierarchy-signed test cert */
1760 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonNameTEST
,
1761 CFSTR("Apple iPhone OS Application Signing"));
1762 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.3.1"));
1765 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
,
1766 CFSTR("Apple iPhone OS Application Signing"));
1768 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.3"));
1770 add_eku(options
, NULL
); /* eku extension is optional */
1771 add_eku(options
, &oidAnyExtendedKeyUsage
);
1772 add_eku(options
, &oidExtendedKeyUsageCodeSigning
);
1774 /* Intermediate check */
1775 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
1776 CFSTR("Apple iPhone Certification Authority"));
1778 /* Chain length check */
1779 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1781 require(result
= SecPolicyCreate(kSecPolicyAppleiPhoneApplicationSigning
,
1782 kSecPolicyNameiPhoneApplicationSigning
, options
),
1786 CFReleaseSafe(options
);
1790 SecPolicyRef
SecPolicyCreateiPhoneVPNApplicationSigning(void) {
1791 CFMutableDictionaryRef options
= NULL
;
1792 SecPolicyRef result
= NULL
;
1794 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1795 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1797 SecPolicyAddBasicCertOptions(options
);
1799 /* Anchored to the Apple Roots */
1800 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameiPhoneVPNApplicationSigning
), errOut
);
1803 if (SecIsInternalRelease()) {
1804 /* Allow a prod hierarchy-signed test cert */
1805 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonNameTEST
,
1806 CFSTR("Apple iPhone OS Application Signing"));
1807 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.6.1"));
1810 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
,
1811 CFSTR("Apple iPhone OS Application Signing"));
1813 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.6"));
1815 add_eku(options
, NULL
); /* eku extension is optional */
1816 add_eku(options
, &oidAnyExtendedKeyUsage
);
1817 add_eku(options
, &oidExtendedKeyUsageCodeSigning
);
1819 /* Intermediate check */
1820 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
1821 CFSTR("Apple iPhone Certification Authority"));
1823 /* Chain length check */
1824 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1826 require(result
= SecPolicyCreate(kSecPolicyAppleiPhoneVPNApplicationSigning
,
1827 kSecPolicyNameiPhoneVPNApplicationSigning
, options
),
1831 CFReleaseSafe(options
);
1835 SecPolicyRef
SecPolicyCreateiPhoneProfileApplicationSigning(void) {
1836 CFMutableDictionaryRef options
= NULL
;
1837 SecPolicyRef result
= NULL
;
1839 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1840 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1842 SecPolicyAddBasicX509Options(options
); // With expiration checking
1845 require_quiet(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameiPhoneProfileApplicationSigning
),
1849 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1851 /* Leaf has CodeSigning EKU */
1852 add_eku_string(options
, CFSTR("1.3.6.1.5.5.7.3.3"));
1854 /* On iOS, the cert in the provisioning profile may be one of:
1855 leaf OID intermediate OID
1856 iPhone Developer <ADS>.6.1.2 <ADS>.6.2.1
1857 iPhone Distribution <ADS>.6.1.4 <ADS>.6.2.1
1858 TestFlight (Prod) <ADS>.6.1.25.1 <ADS>.6.2.1
1859 TestFlight (QA) <ADS>.6.1.25.2 <ADS>.6.2.1
1861 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.1"));
1862 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.2"));
1863 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.4"));
1864 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.25.1"));
1865 if (SecIsInternalRelease()) {
1866 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.25.2"));
1869 /* Revocation via any available method */
1870 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
1873 require(result
= SecPolicyCreate(kSecPolicyAppleiPhoneProfileApplicationSigning
,
1874 kSecPolicyNameiPhoneProfileApplicationSigning
,
1878 CFReleaseSafe(options
);
1882 SecPolicyRef
SecPolicyCreateMacOSProfileApplicationSigning(void) {
1883 CFMutableDictionaryRef options
= NULL
;
1884 SecPolicyRef result
= NULL
;
1886 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1887 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1889 SecPolicyAddBasicCertOptions(options
); // Without expiration checking
1892 require_quiet(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameiPhoneProfileApplicationSigning
),
1896 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1898 /* Leaf has CodeSigning EKU */
1899 add_eku_string(options
, CFSTR("1.3.6.1.5.5.7.3.3"));
1902 /* On macOS, the cert in the provisioning profile may be one of:
1903 leaf OID intermediate OID
1904 MAS Development <ADS>.6.1.12 <ADS>.6.2.1
1905 MAS Submission <ADS>.6.1.7 <ADS>.6.2.1
1906 Developer ID <ADS>.6.1.13 <ADS>.6.2.6
1907 B&I <ADS>.6.22 None - "Apple Code Signing Certification Authority"
1909 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.12"));
1910 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.7"));
1911 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.13"));
1912 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.22"));
1914 /* Revocation via any available method */
1915 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
1918 require(result
= SecPolicyCreate(kSecPolicyAppleMacOSProfileApplicationSigning
,
1919 kSecPolicyNameMacOSProfileApplicationSigning
,
1923 CFReleaseSafe(options
);
1927 SecPolicyRef
SecPolicyCreateiPhoneProvisioningProfileSigning(void) {
1928 CFMutableDictionaryRef options
= NULL
;
1929 SecPolicyRef result
= NULL
;
1931 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1932 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1934 SecPolicyAddBasicCertOptions(options
);
1936 /* Basic X.509 policy with the additional requirements that the chain
1937 length is 3, it's anchored at the AppleCA and the leaf certificate
1938 has issuer "Apple iPhone Certification Authority" and
1939 subject "Apple iPhone OS Provisioning Profile Signing" for the common name. */
1940 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
1941 CFSTR("Apple iPhone Certification Authority"));
1942 if (SecIsInternalRelease()) {
1943 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonNameTEST
,
1944 CFSTR("Apple iPhone OS Provisioning Profile Signing"));
1947 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
,
1948 CFSTR("Apple iPhone OS Provisioning Profile Signing"));
1951 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1952 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameiPhoneProvisioningProfileSigning
), errOut
);
1954 require(result
= SecPolicyCreate(kSecPolicyAppleiPhoneProvisioningProfileSigning
,
1955 kSecPolicyNameiPhoneProvisioningProfileSigning
, options
),
1958 /* 1.2.840.113635.100.6.2.2.1, non-critical: DER:05:00 - provisioning profile */
1961 CFReleaseSafe(options
);
1965 SecPolicyRef
SecPolicyCreateAppleTVOSApplicationSigning(void) {
1966 CFMutableDictionaryRef options
= NULL
;
1967 SecPolicyRef result
= NULL
;
1968 CFDataRef atvProdOid
= NULL
;
1969 CFDataRef atvTestOid
= NULL
;
1970 CFArrayRef oids
= NULL
;
1972 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1973 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1975 SecPolicyAddBasicCertOptions(options
);
1977 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1979 require_quiet(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameTVOSApplicationSigning
),
1982 /* Check for intermediate: Apple Worldwide Developer Relations */
1983 /* 1.2.840.113635.100.6.2.1 */
1984 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleWWDR
);
1986 add_ku(options
, kSecKeyUsageDigitalSignature
);
1988 /* Check for prod or test AppleTV Application Signing OIDs */
1989 /* Prod: 1.2.840.113635.100.6.1.24 */
1990 /* ProdQA: 1.2.840.113635.100.6.1.24.1 */
1991 add_leaf_marker(options
, &oidAppleTVOSApplicationSigningProd
);
1992 add_leaf_marker(options
, &oidAppleTVOSApplicationSigningProdQA
);
1994 require(result
= SecPolicyCreate(kSecPolicyAppleTVOSApplicationSigning
,
1995 kSecPolicyNameTVOSApplicationSigning
, options
),
1999 CFReleaseSafe(options
);
2000 CFReleaseSafe(oids
);
2001 CFReleaseSafe(atvProdOid
);
2002 CFReleaseSafe(atvTestOid
);
2006 SecPolicyRef
SecPolicyCreateOCSPSigner(void) {
2007 CFMutableDictionaryRef options
= NULL
;
2008 SecPolicyRef result
= NULL
;
2010 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2011 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2013 SecPolicyAddBasicX509Options(options
);
2015 /* Require id-kp-OCSPSigning extendedKeyUsage to be present, not optional. */
2016 add_eku(options
, &oidExtendedKeyUsageOCSPSigning
);
2018 require(result
= SecPolicyCreate(kSecPolicyAppleOCSPSigner
,
2019 kSecPolicyNameOCSPSigner
, options
), errOut
);
2022 CFReleaseSafe(options
);
2026 SecPolicyRef
SecPolicyCreateRevocation(CFOptionFlags revocationFlags
) {
2027 CFMutableDictionaryRef options
= NULL
;
2028 SecPolicyRef result
= NULL
;
2030 require(revocationFlags
!= 0, errOut
);
2032 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2033 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2035 if (revocationFlags
& kSecRevocationCheckIfTrusted
) {
2036 CFDictionaryAddValue(options
, kSecPolicyCheckRevocationIfTrusted
, kCFBooleanTrue
);
2037 /* Set method, but allow caller to override with later checks */
2038 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
2041 if (revocationFlags
& kSecRevocationOnlineCheck
) {
2042 CFDictionaryAddValue(options
, kSecPolicyCheckRevocationOnline
, kCFBooleanTrue
);
2043 /* Set method, but allow caller to override with later checks */
2044 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
2047 if (revocationFlags
& kSecRevocationOCSPMethod
&& revocationFlags
& kSecRevocationCRLMethod
) {
2048 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
2050 else if (revocationFlags
& kSecRevocationOCSPMethod
) {
2051 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationOCSP
);
2053 else if (revocationFlags
& kSecRevocationCRLMethod
) {
2054 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationCRL
);
2057 if (revocationFlags
& kSecRevocationRequirePositiveResponse
) {
2058 CFDictionaryAddValue(options
, kSecPolicyCheckRevocationResponseRequired
, kCFBooleanTrue
);
2061 if (revocationFlags
& kSecRevocationNetworkAccessDisabled
) {
2062 CFDictionaryAddValue(options
, kSecPolicyCheckNoNetworkAccess
, kCFBooleanTrue
);
2064 /* If the caller didn't explicitly disable network access, the revocation policy
2065 * should override any other policy's network setting.
2066 * In particular, pairing a revocation policy with BasicX509 should result in
2067 * allowing network access for revocation unless explicitly disabled.
2068 * Note that SecTrustSetNetworkFetchAllowed can override even this. */
2069 CFDictionaryAddValue(options
, kSecPolicyCheckNoNetworkAccess
, kCFBooleanFalse
);
2072 /* Only flag bits 0-6 are currently defined */
2073 require(((revocationFlags
>> 7) == 0), errOut
);
2075 require(result
= SecPolicyCreate(kSecPolicyAppleRevocation
,
2076 kSecPolicyNameRevocation
, options
), errOut
);
2079 CFReleaseSafe(options
);
2083 SecPolicyRef
SecPolicyCreateSMIME(CFIndex smimeUsage
, CFStringRef email
) {
2084 CFMutableDictionaryRef options
= NULL
;
2085 SecPolicyRef result
= NULL
;
2087 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2088 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2090 if (smimeUsage
& kSecIgnoreExpirationSMIMEUsage
) {
2091 SecPolicyAddBasicCertOptions(options
);
2093 SecPolicyAddBasicX509Options(options
);
2096 /* We call add_ku for each combination of bits we are willing to allow. */
2097 if (smimeUsage
& kSecSignSMIMEUsage
) {
2098 add_ku(options
, kSecKeyUsageUnspecified
);
2099 add_ku(options
, kSecKeyUsageDigitalSignature
);
2100 add_ku(options
, kSecKeyUsageNonRepudiation
);
2102 if (smimeUsage
& kSecKeyEncryptSMIMEUsage
) {
2103 add_ku(options
, kSecKeyUsageKeyEncipherment
);
2105 if (smimeUsage
& kSecDataEncryptSMIMEUsage
) {
2106 add_ku(options
, kSecKeyUsageDataEncipherment
);
2108 if (smimeUsage
& kSecKeyExchangeDecryptSMIMEUsage
) {
2109 add_ku(options
, kSecKeyUsageKeyAgreement
| kSecKeyUsageDecipherOnly
);
2111 if (smimeUsage
& kSecKeyExchangeEncryptSMIMEUsage
) {
2112 add_ku(options
, kSecKeyUsageKeyAgreement
| kSecKeyUsageEncipherOnly
);
2114 if (smimeUsage
& kSecKeyExchangeBothSMIMEUsage
) {
2115 add_ku(options
, kSecKeyUsageKeyAgreement
| kSecKeyUsageEncipherOnly
| kSecKeyUsageDecipherOnly
);
2119 CFDictionaryAddValue(options
, kSecPolicyCheckEmail
, email
);
2122 /* RFC 3850 paragraph 4.4.4
2124 If the extended key usage extension is present in the certificate
2125 then interpersonal message S/MIME receiving agents MUST check that it
2126 contains either the emailProtection or the anyExtendedKeyUsage OID as
2127 defined in [KEYM]. S/MIME uses other than interpersonal messaging
2128 MAY require the explicit presence of the extended key usage extension
2129 or other OIDs to be present in the extension or both.
2131 add_eku(options
, NULL
); /* eku extension is optional */
2132 add_eku(options
, &oidAnyExtendedKeyUsage
);
2133 add_eku(options
, &oidExtendedKeyUsageEmailProtection
);
2135 #if !TARGET_OS_IPHONE
2136 // Check revocation on OS X
2137 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
2140 require(result
= SecPolicyCreate(kSecPolicyAppleSMIME
, kSecPolicyNameSMIME
, options
), errOut
);
2143 CFReleaseSafe(options
);
2147 SecPolicyRef
SecPolicyCreateApplePackageSigning(void) {
2148 CFMutableDictionaryRef options
= NULL
;
2149 SecPolicyRef result
= NULL
;
2151 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2152 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2154 SecPolicyAddBasicCertOptions(options
);
2156 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2157 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNamePackageSigning
), errOut
);
2159 add_ku(options
, kSecKeyUsageDigitalSignature
);
2160 add_eku(options
, &oidExtendedKeyUsageCodeSigning
);
2162 require(result
= SecPolicyCreate(kSecPolicyApplePackageSigning
,
2163 kSecPolicyNamePackageSigning
, options
),
2167 CFReleaseSafe(options
);
2172 SecPolicyRef
SecPolicyCreateAppleSWUpdateSigning(void) {
2173 CFMutableDictionaryRef options
= NULL
;
2174 SecPolicyRef result
= NULL
;
2176 * OS X rules for this policy:
2177 * -- Must have one intermediate cert
2178 * -- intermediate must have basic constraints with path length 0
2179 * -- intermediate has CSSMOID_APPLE_EKU_CODE_SIGNING EKU
2180 * -- leaf cert has either CODE_SIGNING or CODE_SIGN_DEVELOPMENT EKU (the latter of
2181 * which triggers a CSSMERR_APPLETP_CODE_SIGN_DEVELOPMENT error)
2183 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2184 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2186 SecPolicyAddBasicX509Options(options
);
2188 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2189 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameSWUpdateSigning
), errOut
);
2191 add_eku(options
, &oidAppleExtendedKeyUsageCodeSigning
);
2192 add_oid(options
, kSecPolicyCheckIntermediateEKU
, &oidAppleExtendedKeyUsageCodeSigning
);
2194 require(result
= SecPolicyCreate(kSecPolicyAppleSWUpdateSigning
,
2195 kSecPolicyNameSWUpdateSigning
, options
),
2199 CFReleaseSafe(options
);
2204 SecPolicyRef
SecPolicyCreateCodeSigning(void) {
2205 CFMutableDictionaryRef options
= NULL
;
2206 SecPolicyRef result
= NULL
;
2208 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2209 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2211 SecPolicyAddBasicX509Options(options
);
2213 /* If the key usage extension is present, we accept it having either of
2215 add_ku(options
, kSecKeyUsageDigitalSignature
);
2216 add_ku(options
, kSecKeyUsageNonRepudiation
);
2218 /* We require an extended key usage extension with the codesigning
2219 eku purpose. (The Apple codesigning eku is not accepted here
2220 since it's valid only for SecPolicyCreateAppleSWUpdateSigning.) */
2221 add_eku(options
, &oidExtendedKeyUsageCodeSigning
);
2222 #if TARGET_OS_IPHONE
2223 /* Accept the 'any' eku on iOS only to match prior behavior.
2224 This may be further restricted in future releases. */
2225 add_eku(options
, &oidAnyExtendedKeyUsage
);
2228 require(result
= SecPolicyCreate(kSecPolicyAppleCodeSigning
,
2229 kSecPolicyNameCodeSigning
, options
),
2233 CFReleaseSafe(options
);
2237 /* Explicitly leave out empty subject/subjectaltname check */
2238 SecPolicyRef
SecPolicyCreateLockdownPairing(void) {
2239 CFMutableDictionaryRef options
= NULL
;
2240 SecPolicyRef result
= NULL
;
2242 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2243 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2244 //CFDictionaryAddValue(options, kSecPolicyCheckBasicCertificateProcessing,
2245 // kCFBooleanTrue); // Happens automatically in SecPVCPathChecks
2246 CFDictionaryAddValue(options
, kSecPolicyCheckCriticalExtensions
,
2248 CFDictionaryAddValue(options
, kSecPolicyCheckIdLinkage
,
2250 CFDictionaryAddValue(options
, kSecPolicyCheckBasicConstraints
,
2252 CFDictionaryAddValue(options
, kSecPolicyCheckWeakKeySize
, kCFBooleanTrue
);
2254 require(result
= SecPolicyCreate(kSecPolicyAppleLockdownPairing
,
2255 kSecPolicyNameLockdownPairing
, options
), errOut
);
2258 CFReleaseSafe(options
);
2262 SecPolicyRef
SecPolicyCreateURLBag(void) {
2263 CFMutableDictionaryRef options
= NULL
;
2264 SecPolicyRef result
= NULL
;
2266 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2267 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2269 SecPolicyAddBasicCertOptions(options
);
2271 add_eku(options
, &oidExtendedKeyUsageCodeSigning
);
2273 require(result
= SecPolicyCreate(kSecPolicyAppleURLBag
,
2274 kSecPolicyNameURLBag
, options
), errOut
);
2277 CFReleaseSafe(options
);
2281 SecPolicyRef
SecPolicyCreateOTATasking(void)
2283 CFMutableDictionaryRef options
= NULL
;
2284 SecPolicyRef result
= NULL
;
2286 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2287 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2289 SecPolicyAddBasicX509Options(options
);
2292 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameMobileAsset
), errOut
);
2294 /* Chain length of 3 */
2295 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2297 /* Intermediate has common name "Apple iPhone Certification Authority". */
2298 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2299 CFSTR("Apple iPhone Certification Authority"));
2301 /* Leaf has common name "Asset Manifest Signing" */
2302 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
, CFSTR("OTA Task Signing"));
2304 require(result
= SecPolicyCreate(kSecPolicyAppleOTATasking
, kSecPolicyNameOTATasking
, options
),
2308 CFReleaseSafe(options
);
2312 SecPolicyRef
SecPolicyCreateMobileAsset(void)
2314 CFMutableDictionaryRef options
= NULL
;
2315 SecPolicyRef result
= NULL
;
2317 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2318 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2320 /* No expiration check */
2321 SecPolicyAddBasicCertOptions(options
);
2324 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameMobileAsset
), errOut
);
2326 /* Chain length of 3 */
2327 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2329 /* Intermediate has common name "Apple iPhone Certification Authority". */
2330 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2331 CFSTR("Apple iPhone Certification Authority"));
2333 /* Leaf has common name "Asset Manifest Signing" */
2334 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
, CFSTR("Asset Manifest Signing"));
2336 require(result
= SecPolicyCreate(kSecPolicyAppleMobileAsset
, kSecPolicyNameMobileAsset
, options
),
2340 CFReleaseSafe(options
);
2344 SecPolicyRef
SecPolicyCreateMobileAssetDevelopment(void) {
2345 CFMutableDictionaryRef options
= NULL
;
2346 SecPolicyRef result
= NULL
;
2348 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2349 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2351 /* No expiration check */
2352 SecPolicyAddBasicCertOptions(options
);
2355 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameMobileAsset
), errOut
);
2357 /* Chain length of 3 */
2358 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2360 /* Intermediate has the iPhone CA Marker extension */
2361 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.18"));
2363 /* Leaf has ProdQA Mobile Asset Marker extension */
2364 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.55.1"));
2366 require(result
= SecPolicyCreate(kSecPolicyAppleMobileAssetDevelopment
, kSecPolicyNameMobileAsset
, options
),
2370 CFReleaseSafe(options
);
2374 SecPolicyRef
SecPolicyCreateAppleIDAuthorityPolicy(void)
2376 SecPolicyRef result
= NULL
;
2377 CFMutableDictionaryRef options
= NULL
;
2378 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2379 &kCFTypeDictionaryKeyCallBacks
,
2380 &kCFTypeDictionaryValueCallBacks
), out
);
2382 //Leaf appears to be a SSL only cert, so policy should expand on that policy
2383 SecPolicyAddBasicX509Options(options
);
2385 // Apple CA anchored
2386 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameIDAuthority
), out
);
2388 // with the addition of the existence check of an extension with "Apple ID Sharing Certificate" oid (1.2.840.113635.100.4.7)
2389 // NOTE: this obviously intended to have gone into Extended Key Usage, but evidence of existing certs proves the contrary.
2390 add_leaf_marker(options
, &oidAppleExtendedKeyUsageAppleID
);
2392 // 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.
2393 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleID
);
2394 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleID2
);
2396 require(result
= SecPolicyCreate(kSecPolicyAppleIDAuthority
,
2397 kSecPolicyNameIDAuthority
, options
), out
);
2400 CFReleaseSafe(options
);
2404 SecPolicyRef
SecPolicyCreateMacAppStoreReceipt(void)
2406 SecPolicyRef result
= NULL
;
2407 CFMutableDictionaryRef options
= NULL
;
2408 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2409 &kCFTypeDictionaryKeyCallBacks
,
2410 &kCFTypeDictionaryValueCallBacks
), out
);
2412 SecPolicyAddBasicX509Options(options
);
2414 // Apple CA anchored
2415 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameMacAppStoreReceipt
), out
);
2417 // Chain length of 3
2418 require(SecPolicyAddChainLengthOptions(options
, 3), out
);
2420 // MacAppStoreReceipt policy OID
2421 add_certificate_policy_oid_string(options
, CFSTR("1.2.840.113635.100.5.6.1"));
2423 // Intermediate marker OID
2424 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.1"));
2427 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.11.1"));
2430 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
2432 require(result
= SecPolicyCreate(kSecPolicyMacAppStoreReceipt
,
2433 kSecPolicyNameMacAppStoreReceipt
, options
), out
);
2436 CFReleaseSafe(options
);
2441 static SecPolicyRef
_SecPolicyCreatePassbookCardSigner(CFStringRef cardIssuer
, CFStringRef teamIdentifier
, bool requireTeamID
)
2443 SecPolicyRef result
= NULL
;
2444 CFMutableDictionaryRef options
= NULL
;
2445 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2446 &kCFTypeDictionaryKeyCallBacks
,
2447 &kCFTypeDictionaryValueCallBacks
), out
);
2449 SecPolicyAddBasicX509Options(options
);
2450 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNamePassbookSigning
), out
);
2452 // Chain length of 3
2453 require(SecPolicyAddChainLengthOptions(options
, 3), out
);
2455 if (teamIdentifier
) {
2456 // If supplied, teamIdentifier must match subject OU field
2457 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectOrganizationalUnit
, teamIdentifier
);
2460 // If not supplied, and it was required, fail
2461 require(!requireTeamID
, out
);
2464 // Must be both push and 3rd party package signing
2465 add_leaf_marker_value(options
, &oidAppleInstallerPackagingSigningExternal
, cardIssuer
);
2467 // We should check that it also has push marker, but we don't support requiring both, only either.
2468 // add_independent_oid(options, kSecPolicyCheckLeafMarkerOid, &oidApplePushServiceClient);
2470 //WWDR Intermediate marker OID
2471 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.1"));
2473 // And Passbook signing eku
2474 add_eku(options
, &oidAppleExtendedKeyUsagePassbook
);
2476 require(result
= SecPolicyCreate(kSecPolicyApplePassbookSigning
,
2477 kSecPolicyNamePassbookSigning
, options
), out
);
2480 CFReleaseSafe(options
);
2484 SecPolicyRef
SecPolicyCreatePassbookCardSigner(CFStringRef cardIssuer
, CFStringRef teamIdentifier
)
2486 return _SecPolicyCreatePassbookCardSigner(cardIssuer
, teamIdentifier
, true);
2490 static SecPolicyRef
CreateMobileStoreSigner(Boolean forTest
)
2493 SecPolicyRef result
= NULL
;
2494 CFMutableDictionaryRef options
= NULL
;
2495 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2496 &kCFTypeDictionaryKeyCallBacks
,
2497 &kCFTypeDictionaryValueCallBacks
), errOut
);
2498 SecPolicyAddBasicX509Options(options
);
2499 require(SecPolicyAddAppleAnchorOptions(options
,
2500 ((forTest
) ? kSecPolicyNameTestMobileStore
:
2501 kSecPolicyNameMobileStore
)), errOut
);
2503 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2505 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2506 CFSTR("Apple System Integration 2 Certification Authority"));
2508 add_ku(options
, kSecKeyUsageDigitalSignature
);
2510 const DERItem
* pOID
= (forTest
) ? &oidApplePolicyMobileStoreProdQA
: &oidApplePolicyMobileStore
;
2512 add_certificate_policy_oid(options
, pOID
);
2514 require(result
= SecPolicyCreate((forTest
) ? kSecPolicyAppleTestMobileStore
: kSecPolicyAppleMobileStore
,
2515 (forTest
) ? kSecPolicyNameTestMobileStore
: kSecPolicyNameMobileStore
,
2519 CFReleaseSafe(options
);
2523 SecPolicyRef
SecPolicyCreateMobileStoreSigner(void)
2525 return CreateMobileStoreSigner(false);
2528 SecPolicyRef
SecPolicyCreateTestMobileStoreSigner(void)
2530 return CreateMobileStoreSigner(true);
2534 CF_RETURNS_RETAINED SecPolicyRef
SecPolicyCreateEscrowServiceSigner(void)
2536 SecPolicyRef result
= NULL
;
2537 CFMutableDictionaryRef options
= NULL
;
2538 CFArrayRef anArray
= NULL
;
2539 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2540 &kCFTypeDictionaryKeyCallBacks
,
2541 &kCFTypeDictionaryValueCallBacks
), errOut
);
2543 // X509, ignoring date validity
2544 SecPolicyAddBasicCertOptions(options
);
2547 add_ku(options
, kSecKeyUsageKeyEncipherment
);
2549 /* Leaf has marker OID with value that can't be pre-determined */
2550 add_element(options
, kSecPolicyCheckLeafMarkerOidWithoutValueCheck
, CFSTR("1.2.840.113635.100.6.23.1"));
2551 require(SecPolicyAddChainLengthOptions(options
, 2), errOut
);
2554 Boolean anchorAdded
= false;
2555 // Get the roots by calling the SecCertificateCopyEscrowRoots
2556 anArray
= SecCertificateCopyEscrowRoots(kSecCertificateProductionEscrowRoot
);
2557 CFIndex numRoots
= 0;
2558 if (NULL
== anArray
|| 0 == (numRoots
= CFArrayGetCount(anArray
)))
2563 for (CFIndex iCnt
= 0; iCnt
< numRoots
; iCnt
++)
2565 SecCertificateRef aCert
= (SecCertificateRef
)CFArrayGetValueAtIndex(anArray
, iCnt
);
2569 CFDataRef sha_data
= SecCertificateGetSHA1Digest(aCert
);
2570 if (NULL
!= sha_data
)
2572 const UInt8
* pSHAData
= CFDataGetBytePtr(sha_data
);
2573 if (NULL
!= pSHAData
)
2575 SecPolicyAddAnchorSHA1Options(options
, pSHAData
);
2581 CFReleaseNull(anArray
);
2589 require(result
= SecPolicyCreate(kSecPolicyAppleEscrowService
,
2590 kSecPolicyNameEscrowService
, options
), errOut
);
2593 CFReleaseSafe(anArray
);
2594 CFReleaseSafe(options
);
2598 CF_RETURNS_RETAINED SecPolicyRef
SecPolicyCreatePCSEscrowServiceSigner(void)
2600 SecPolicyRef result
= NULL
;
2601 CFMutableDictionaryRef options
= NULL
;
2602 CFArrayRef anArray
= NULL
;
2603 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2604 &kCFTypeDictionaryKeyCallBacks
,
2605 &kCFTypeDictionaryValueCallBacks
), errOut
);
2607 SecPolicyAddBasicX509Options(options
);
2610 add_ku(options
, kSecKeyUsageKeyEncipherment
);
2612 /* Leaf has marker OID with value that can't be pre-determined */
2613 add_element(options
, kSecPolicyCheckLeafMarkerOidWithoutValueCheck
, CFSTR("1.2.840.113635.100.6.23.1"));
2614 require(SecPolicyAddChainLengthOptions(options
, 2), errOut
);
2617 Boolean anchorAdded
= false;
2618 anArray
= SecCertificateCopyEscrowRoots(kSecCertificateProductionPCSEscrowRoot
);
2619 CFIndex numRoots
= 0;
2620 if (NULL
== anArray
|| 0 == (numRoots
= CFArrayGetCount(anArray
)))
2625 for (CFIndex iCnt
= 0; iCnt
< numRoots
; iCnt
++)
2627 SecCertificateRef aCert
= (SecCertificateRef
)CFArrayGetValueAtIndex(anArray
, iCnt
);
2631 CFDataRef sha_data
= SecCertificateGetSHA1Digest(aCert
);
2632 if (NULL
!= sha_data
)
2634 const UInt8
* pSHAData
= CFDataGetBytePtr(sha_data
);
2635 if (NULL
!= pSHAData
)
2637 SecPolicyAddAnchorSHA1Options(options
, pSHAData
);
2643 CFReleaseNull(anArray
);
2651 require(result
= SecPolicyCreate(kSecPolicyApplePCSEscrowService
,
2652 kSecPolicyNamePCSEscrowService
, options
), errOut
);
2655 CFReleaseSafe(anArray
);
2656 CFReleaseSafe(options
);
2660 static SecPolicyRef
CreateConfigurationProfileSigner(bool forTest
) {
2661 SecPolicyRef result
= NULL
;
2662 CFMutableDictionaryRef options
= NULL
;
2663 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2664 &kCFTypeDictionaryKeyCallBacks
,
2665 &kCFTypeDictionaryValueCallBacks
), errOut
);
2667 SecPolicyAddBasicX509Options(options
);
2668 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameProfileSigner
), errOut
);
2671 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2673 // Require the profile signing EKU
2674 const DERItem
* pOID
= (forTest
) ? &oidAppleExtendedKeyUsageQAProfileSigning
:&oidAppleExtendedKeyUsageProfileSigning
;
2675 add_eku(options
, pOID
);
2677 // Require the Apple Application Integration CA marker OID
2678 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.3"));
2680 require(result
= SecPolicyCreate((forTest
) ? kSecPolicyAppleQAProfileSigner
: kSecPolicyAppleProfileSigner
,
2681 (forTest
) ? kSecPolicyNameQAProfileSigner
: kSecPolicyNameProfileSigner
,
2685 CFReleaseSafe(options
);
2689 SecPolicyRef
SecPolicyCreateConfigurationProfileSigner(void)
2691 return CreateConfigurationProfileSigner(false);
2695 SecPolicyRef
SecPolicyCreateQAConfigurationProfileSigner(void)
2697 if (SecIsInternalRelease()) {
2698 return CreateConfigurationProfileSigner(true);
2700 return CreateConfigurationProfileSigner(false);
2704 SecPolicyRef
SecPolicyCreateOSXProvisioningProfileSigning(void)
2706 SecPolicyRef result
= NULL
;
2707 CFMutableDictionaryRef options
= NULL
;
2708 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2709 &kCFTypeDictionaryKeyCallBacks
,
2710 &kCFTypeDictionaryValueCallBacks
), errOut
);
2711 // Require valid chain from the Apple root
2712 SecPolicyAddBasicX509Options(options
);
2713 SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameOSXProvisioningProfileSigning
);
2715 // Require provisioning profile leaf marker OID (1.2.840.113635.100.4.11)
2716 add_leaf_marker(options
, &oidAppleCertExtOSXProvisioningProfileSigning
);
2718 // Require intermediate marker OID (1.2.840.113635.100.6.2.1)
2719 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleWWDR
);
2721 // Require key usage that allows signing
2722 add_ku(options
, kSecKeyUsageDigitalSignature
);
2724 // Ensure that revocation is checked (OCSP)
2725 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationOCSP
);
2727 require(result
= SecPolicyCreate(kSecPolicyAppleOSXProvisioningProfileSigning
,
2728 kSecPolicyNameOSXProvisioningProfileSigning
, options
), errOut
);
2731 CFReleaseSafe(options
);
2736 SecPolicyRef
SecPolicyCreateOTAPKISigner(void)
2738 SecPolicyRef result
= NULL
;
2739 CFMutableDictionaryRef options
= NULL
;
2740 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2741 &kCFTypeDictionaryKeyCallBacks
,
2742 &kCFTypeDictionaryValueCallBacks
), errOut
);
2743 SecPolicyAddBasicX509Options(options
);
2745 SecPolicyAddAnchorSHA1Options(options
, kApplePKISettingsAuthority
);
2746 require(SecPolicyAddChainLengthOptions(options
, 2), errOut
);
2748 require(result
= SecPolicyCreate(kSecPolicyAppleOTAPKISigner
,
2749 kSecPolicyNameOTAPKISigner
, options
), errOut
);
2752 CFReleaseSafe(options
);
2758 SecPolicyRef
SecPolicyCreateTestOTAPKISigner(void)
2760 /* Guard against use on production devices */
2761 if (!SecIsInternalRelease()) {
2762 return SecPolicyCreateOTAPKISigner();
2765 SecPolicyRef result
= NULL
;
2766 CFMutableDictionaryRef options
= NULL
;
2767 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2768 &kCFTypeDictionaryKeyCallBacks
,
2769 &kCFTypeDictionaryValueCallBacks
), errOut
);
2770 SecPolicyAddBasicX509Options(options
);
2772 SecPolicyAddAnchorSHA1Options(options
, kAppleTestPKISettingsAuthority
);
2773 require(SecPolicyAddChainLengthOptions(options
, 2), errOut
);
2775 require(result
= SecPolicyCreate(kSecPolicyAppleTestOTAPKISigner
,
2776 kSecPolicyNameTestOTAPKISigner
, options
), errOut
);
2779 CFReleaseSafe(options
);
2784 @function SecPolicyCreateAppleSMPEncryption
2785 @abstract Check for intermediate certificate 'Apple System Integration CA - G3' by name,
2786 and root certificate 'Apple Root CA - G3' by hash.
2787 Leaf cert must have Key Encipherment usage.
2788 Leaf cert must have Apple SMP Encryption marker OID (1.2.840.113635.100.6.30).
2789 Intermediate must have marker OID (1.2.840.113635.100.6.2.13).
2791 SecPolicyRef
SecPolicyCreateAppleSMPEncryption(void)
2793 SecPolicyRef result
= NULL
;
2794 CFMutableDictionaryRef options
= NULL
;
2795 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2796 &kCFTypeDictionaryKeyCallBacks
,
2797 &kCFTypeDictionaryValueCallBacks
), errOut
);
2798 SecPolicyAddBasicCertOptions(options
);
2800 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameSMPEncryption
),
2802 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2804 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2805 CFSTR("Apple System Integration CA - G3"));
2807 // Check that leaf has extension with "Apple SMP Encryption" oid (1.2.840.113635.100.6.30)
2808 add_leaf_marker(options
, &oidAppleCertExtAppleSMPEncryption
);
2810 // Check that intermediate has extension (1.2.840.113635.100.6.2.13)
2811 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleSystemIntgG3
);
2813 add_ku(options
, kSecKeyUsageKeyEncipherment
);
2815 // Ensure that revocation is checked (OCSP)
2816 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationOCSP
);
2818 require(result
= SecPolicyCreate(kSecPolicyAppleSMPEncryption
,
2819 kSecPolicyNameSMPEncryption
, options
), errOut
);
2822 CFReleaseSafe(options
);
2827 @function SecPolicyCreateTestAppleSMPEncryption
2828 @abstract Check for intermediate certificate 'Test Apple System Integration CA - ECC' by name,
2829 and root certificate 'Test Apple Root CA - ECC' by hash.
2830 Leaf cert must have Key Encipherment usage. Other checks TBD.
2832 SecPolicyRef
SecPolicyCreateTestAppleSMPEncryption(void)
2834 SecPolicyRef result
= NULL
;
2835 CFMutableDictionaryRef options
= NULL
;
2836 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2837 &kCFTypeDictionaryKeyCallBacks
,
2838 &kCFTypeDictionaryValueCallBacks
), errOut
);
2839 SecPolicyAddBasicCertOptions(options
);
2841 SecPolicyAddAnchorSHA1Options(options
, kTestAppleRootCA_ECC_SHA1
);
2842 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2844 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2845 CFSTR("Test Apple System Integration CA - ECC"));
2847 add_ku(options
, kSecKeyUsageKeyEncipherment
);
2849 // Ensure that revocation is checked (OCSP)
2850 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationOCSP
);
2852 require(result
= SecPolicyCreate(kSecPolicyAppleTestSMPEncryption
,
2853 kSecPolicyNameTestSMPEncryption
, options
), errOut
);
2856 CFReleaseSafe(options
);
2861 SecPolicyRef
SecPolicyCreateAppleIDValidationRecordSigningPolicy(void)
2863 SecPolicyRef result
= NULL
;
2864 CFMutableDictionaryRef options
= NULL
;
2865 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2866 &kCFTypeDictionaryKeyCallBacks
,
2867 &kCFTypeDictionaryValueCallBacks
), errOut
);
2869 //Leaf appears to be a SSL only cert, so policy should expand on that policy
2870 SecPolicyAddBasicX509Options(options
);
2872 // Apple CA anchored
2873 require(SecPolicyAddAppleAnchorOptions(options
,
2874 kSecPolicyNameIDValidationRecordSigning
),
2877 // Check for an extension with " Apple ID Validation Record Signing" oid (1.2.840.113635.100.6.25)
2878 add_leaf_marker(options
, &oidAppleCertExtensionAppleIDRecordValidationSigning
);
2880 // and validate that intermediate has extension
2881 // Application Integration Intermediate Certificate (1.2.840.113635.100.6.2.3)
2882 // and also validate that intermediate has extension
2883 // System Integration 2 Intermediate Certificate (1.2.840.113635.100.6.2.10)
2884 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleID
);
2885 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleSystemIntg2
);
2887 // Ensure that revocation is checked (OCSP)
2888 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationOCSP
);
2890 require(result
= SecPolicyCreate(kSecPolicyAppleIDValidationRecordSigning
,
2891 kSecPolicyNameIDValidationRecordSigning
, options
), errOut
);
2894 CFReleaseSafe(options
);
2899 @function SecPolicyCreateAppleServerAuthCommon
2900 @abstract Generic policy for server authentication Sub CAs
2902 Allows control for both if pinning is required at all and if UAT environments should be added
2903 to the trust policy.
2905 No pinning is for developer/QA that needs to use proxy to debug the protocol, while UAT
2906 environment is for QA/internal developer that have no need allow fake servers.
2908 Both the noPinning and UAT are gated on that you run on internal hardware.
2913 SecPolicyCreateAppleServerAuthCommon(CFStringRef hostname
,
2914 CFDictionaryRef __unused context
,
2915 CFStringRef policyOID
, CFStringRef service
,
2916 const DERItem
*leafMarkerOID
,
2917 const DERItem
*UATLeafMarkerOID
)
2919 CFMutableDictionaryRef appleAnchorOptions
= NULL
;
2920 CFMutableDictionaryRef options
= NULL
;
2921 SecPolicyRef result
= NULL
;
2922 CFDataRef oid
= NULL
, uatoid
= NULL
;
2924 options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0, &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
2925 require(options
, errOut
);
2927 SecPolicyAddBasicX509Options(options
);
2929 require(hostname
, errOut
);
2930 CFDictionaryAddValue(options
, kSecPolicyCheckSSLHostname
, hostname
);
2932 CFDictionaryAddValue(options
, kSecPolicyCheckBlackListedLeaf
, kCFBooleanTrue
);
2933 CFDictionaryAddValue(options
, kSecPolicyCheckGrayListedLeaf
, kCFBooleanTrue
);
2935 add_eku(options
, &oidExtendedKeyUsageServerAuth
);
2937 if (requireUATPinning(service
)) {
2940 * Require pinning to the Apple CA's.
2942 SecPolicyAddAppleAnchorOptions(options
, service
);
2944 /* old-style leaf marker OIDs */
2945 if (UATLeafMarkerOID
) {
2946 add_leaf_prod_qa_markers(options
, leafMarkerOID
, UATLeafMarkerOID
);
2948 add_leaf_marker(options
, leafMarkerOID
);
2951 /* new-style leaf marker OIDs */
2952 CFStringRef leafMarkerOIDStr
= NULL
, UATLeafMarkerOIDStr
= NULL
;
2953 leafMarkerOIDStr
= SecDERItemCopyOIDDecimalRepresentation(NULL
, leafMarkerOID
);
2954 if (UATLeafMarkerOID
) {
2955 UATLeafMarkerOIDStr
= SecDERItemCopyOIDDecimalRepresentation(NULL
, UATLeafMarkerOID
);
2958 if (leafMarkerOIDStr
&& UATLeafMarkerOIDStr
) {
2959 add_leaf_prod_qa_markers_value_string(options
,
2960 CFSTR("1.2.840.113635.100.6.48.1"), leafMarkerOIDStr
,
2961 CFSTR("1.2.840.113635.100.6.48.1"), UATLeafMarkerOIDStr
);
2962 } else if (leafMarkerOIDStr
) {
2963 add_leaf_marker_value_string(options
, CFSTR("1.2.840.113635.100.6.48.1"), leafMarkerOIDStr
);
2966 CFReleaseNull(leafMarkerOIDStr
);
2967 CFReleaseNull(UATLeafMarkerOIDStr
);
2969 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleServerAuthentication
);
2972 /* Check for weak hashes and keys */
2973 CFDictionaryAddValue(options
, kSecPolicyCheckSystemTrustedWeakHash
, kCFBooleanTrue
);
2974 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
2976 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
2978 result
= SecPolicyCreate(policyOID
, service
, options
);
2979 require(result
, errOut
);
2982 CFReleaseSafe(appleAnchorOptions
);
2983 CFReleaseSafe(options
);
2985 CFReleaseSafe(uatoid
);
2990 @function SecPolicyCreateAppleIDSService
2991 @abstract Ensure we're appropriately pinned to the IDS service (SSL + Apple restrictions)
2993 SecPolicyRef
SecPolicyCreateAppleIDSService(CFStringRef hostname
)
2995 SecPolicyRef result
= SecPolicyCreateSSL(true, hostname
);
2997 SecPolicySetOid(result
, kSecPolicyAppleIDSService
);
2998 SecPolicySetName(result
, kSecPolicyNameAppleIDSBag
);
3004 @function SecPolicyCreateAppleIDSService
3005 @abstract Ensure we're appropriately pinned to the IDS service (SSL + Apple restrictions)
3007 SecPolicyRef
SecPolicyCreateAppleIDSServiceContext(CFStringRef hostname
, CFDictionaryRef context
)
3009 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyAppleIDSServiceContext
,
3010 kSecPolicyNameAppleIDSService
,
3011 &oidAppleCertExtAppleServerAuthenticationIDSProd
,
3012 &oidAppleCertExtAppleServerAuthenticationIDSProdQA
);
3016 @function SecPolicyCreateAppleGSService
3017 @abstract Ensure we're appropriately pinned to the GS service
3019 SecPolicyRef
SecPolicyCreateAppleGSService(CFStringRef hostname
, CFDictionaryRef context
)
3021 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyAppleGSService
,
3022 kSecPolicyNameAppleGSService
,
3023 &oidAppleCertExtAppleServerAuthenticationGS
,
3028 @function SecPolicyCreateApplePushService
3029 @abstract Ensure we're appropriately pinned to the Push service (SSL + Apple restrictions)
3031 SecPolicyRef
SecPolicyCreateApplePushService(CFStringRef hostname
, CFDictionaryRef context
)
3033 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyApplePushService
,
3034 kSecPolicyNameApplePushService
,
3035 &oidAppleCertExtAppleServerAuthenticationAPNProd
,
3036 &oidAppleCertExtAppleServerAuthenticationAPNProdQA
);
3040 @function SecPolicyCreateApplePPQService
3041 @abstract Ensure we're appropriately pinned to the PPQ service (SSL + Apple restrictions)
3043 SecPolicyRef
SecPolicyCreateApplePPQService(CFStringRef hostname
, CFDictionaryRef context
)
3045 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyApplePPQService
,
3046 kSecPolicyNameApplePPQService
,
3047 &oidAppleCertExtAppleServerAuthenticationPPQProd
,
3048 &oidAppleCertExtAppleServerAuthenticationPPQProdQA
);
3052 @function SecPolicyCreateAppleAST2Service
3053 @abstract Ensure we're appropriately pinned to the AST2 Diagnostic service (SSL + Apple restrictions)
3055 SecPolicyRef
SecPolicyCreateAppleAST2Service(CFStringRef hostname
, CFDictionaryRef context
)
3057 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyAppleAST2DiagnosticsServerAuth
,
3058 kSecPolicyNameAppleAST2Service
,
3059 &oidAppleCertExtAST2DiagnosticsServerAuthProd
,
3060 &oidAppleCertExtAST2DiagnosticsServerAuthProdQA
);
3064 @function SecPolicyCreateAppleEscrowProxyService
3065 @abstract Ensure we're appropriately pinned to the iCloud Escrow Proxy service (SSL + Apple restrictions)
3067 SecPolicyRef
SecPolicyCreateAppleEscrowProxyService(CFStringRef hostname
, CFDictionaryRef context
)
3069 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyAppleEscrowProxyServerAuth
,
3070 kSecPolicyNameAppleEscrowProxyService
,
3071 &oidAppleCertExtEscrowProxyServerAuthProd
,
3072 &oidAppleCertExtEscrowProxyServerAuthProdQA
);
3075 /* subject:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA */
3076 /* SKID: C0:7A:98:68:8D:89:FB:AB:05:64:0C:11:7D:AA:7D:65:B8:CA:CC:4E */
3077 /* Not Before: May 21 04:00:00 2002 GMT, Not After : May 21 04:00:00 2022 GMT */
3078 /* Signature Algorithm: sha1WithRSAEncryption */
3079 unsigned char GeoTrust_Global_CA_sha256
[kSecPolicySHA256Size
] = {
3080 0xff, 0x85, 0x6a, 0x2d, 0x25, 0x1d, 0xcd, 0x88, 0xd3, 0x66, 0x56, 0xf4, 0x50, 0x12, 0x67, 0x98,
3081 0xcf, 0xab, 0xaa, 0xde, 0x40, 0x79, 0x9c, 0x72, 0x2d, 0xe4, 0xd2, 0xb5, 0xdb, 0x36, 0xa7, 0x3a
3084 static SecPolicyRef
SecPolicyCreateAppleGeoTrustServerAuthCommon(CFStringRef hostname
, CFStringRef policyOid
,
3085 CFStringRef policyName
,
3086 CFStringRef leafMarkerOid
,
3087 CFStringRef qaLeafMarkerOid
) {
3088 CFMutableDictionaryRef options
= NULL
;
3089 CFDataRef spkiDigest
= NULL
;
3090 SecPolicyRef result
= NULL
;
3092 require(options
= CFDictionaryCreateMutable(NULL
, 0, &kCFTypeDictionaryKeyCallBacks
,
3093 &kCFTypeDictionaryValueCallBacks
), errOut
);
3096 SecPolicyAddBasicX509Options(options
);
3098 require(hostname
, errOut
);
3099 CFDictionaryAddValue(options
, kSecPolicyCheckSSLHostname
, hostname
);
3101 add_eku(options
, &oidExtendedKeyUsageServerAuth
);
3104 if (requireUATPinning(policyName
)) {
3106 SecPolicyAddAnchorSHA256Options(options
, GeoTrust_Global_CA_sha256
);
3108 /* Issued to Apple Inc. in the US */
3109 add_element(options
, kSecPolicyCheckIntermediateCountry
, CFSTR("US"));
3110 add_element(options
, kSecPolicyCheckIntermediateOrganization
, CFSTR("Apple Inc."));
3112 require_action(SecPolicyAddChainLengthOptions(options
, 3), errOut
, CFReleaseNull(result
));
3114 /* Marker OIDs in both formats */
3115 if (qaLeafMarkerOid
) {
3116 add_leaf_prod_qa_markers_string(options
, leafMarkerOid
, qaLeafMarkerOid
);
3117 add_leaf_prod_qa_markers_value_string(options
,
3118 CFSTR("1.2.840.113635.100.6.48.1"), leafMarkerOid
,
3119 CFSTR("1.2.840.113635.100.6.48.1"), qaLeafMarkerOid
);
3121 add_leaf_marker_string(options
, leafMarkerOid
);
3122 add_leaf_marker_value_string(options
, CFSTR("1.2.840.113635.100.6.48.1"), leafMarkerOid
);
3126 /* Check for weak hashes */
3127 CFDictionaryAddValue(options
, kSecPolicyCheckSystemTrustedWeakHash
, kCFBooleanTrue
);
3128 CFDictionaryAddValue(options
, kSecPolicyCheckSystemTrustedWeakKey
, kCFBooleanTrue
);
3130 /* See <rdar://25344801> for more details */
3132 result
= SecPolicyCreate(policyOid
, policyName
, options
);
3135 CFReleaseSafe(options
);
3136 CFReleaseSafe(spkiDigest
);
3140 SecPolicyRef
SecPolicyCreateAppleCompatibilityEscrowProxyService(CFStringRef hostname
) {
3141 return SecPolicyCreateAppleGeoTrustServerAuthCommon(hostname
, kSecPolicyAppleEscrowProxyCompatibilityServerAuth
,
3142 kSecPolicyNameAppleEscrowProxyService
,
3143 CFSTR("1.2.840.113635.100.6.27.7.2"),
3144 CFSTR("1.2.840.113635.100.6.27.7.1"));
3148 @function SecPolicyCreateAppleFMiPService
3149 @abstract Ensure we're appropriately pinned to the Find My iPhone service (SSL + Apple restrictions)
3151 SecPolicyRef
SecPolicyCreateAppleFMiPService(CFStringRef hostname
, CFDictionaryRef context
)
3153 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyAppleFMiPServerAuth
,
3154 kSecPolicyNameAppleFMiPService
,
3155 &oidAppleCertExtFMiPServerAuthProd
,
3156 &oidAppleCertExtFMiPServerAuthProdQA
);
3160 /* should use verbatim copy, but since this is the deprecated way, don't care right now */
3161 static const UInt8 entrustSPKIL1C
[kSecPolicySHA256Size
] = {
3162 0x54, 0x5b, 0xf9, 0x35, 0xe9, 0xad, 0xa1, 0xda,
3163 0x11, 0x7e, 0xdc, 0x3c, 0x2a, 0xcb, 0xc5, 0x6f,
3164 0xc0, 0x28, 0x09, 0x6c, 0x0e, 0x24, 0xbe, 0x9b,
3165 0x38, 0x94, 0xbe, 0x52, 0x2d, 0x1b, 0x43, 0xde
3169 @function SecPolicyCreateApplePushServiceLegacy
3170 @abstract Ensure we're appropriately pinned to the Push service (via Entrust)
3172 SecPolicyRef
SecPolicyCreateApplePushServiceLegacy(CFStringRef hostname
)
3174 CFMutableDictionaryRef options
= NULL
;
3175 SecPolicyRef result
= NULL
;
3176 CFDataRef digest
= NULL
;
3178 digest
= CFDataCreateWithBytesNoCopy(kCFAllocatorDefault
, entrustSPKIL1C
, sizeof(entrustSPKIL1C
), kCFAllocatorNull
);
3179 require(digest
, errOut
);
3181 options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0, &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
3182 require(options
, errOut
);
3184 SecPolicyAddBasicX509Options(options
);
3186 CFDictionaryAddValue(options
, kSecPolicyCheckSSLHostname
, hostname
);
3188 CFDictionaryAddValue(options
, kSecPolicyCheckBlackListedLeaf
, kCFBooleanTrue
);
3189 CFDictionaryAddValue(options
, kSecPolicyCheckGrayListedLeaf
, kCFBooleanTrue
);
3191 CFDictionaryAddValue(options
, kSecPolicyCheckIntermediateSPKISHA256
, digest
);
3193 add_eku(options
, &oidExtendedKeyUsageServerAuth
);
3195 /* Check for weak hashes and keys */
3196 CFDictionaryAddValue(options
, kSecPolicyCheckSystemTrustedWeakHash
, kCFBooleanTrue
);
3197 CFDictionaryAddValue(options
, kSecPolicyCheckSystemTrustedWeakKey
, kCFBooleanTrue
);
3199 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
3201 result
= SecPolicyCreate(kSecPolicyAppleLegacyPushService
,
3202 kSecPolicyNameLegacyPushService
, options
);
3203 require(result
, errOut
);
3206 CFReleaseSafe(digest
);
3207 CFReleaseSafe(options
);
3212 @function SecPolicyCreateAppleMMCSService
3213 @abstract Ensure we're appropriately pinned to the IDS service (SSL + Apple restrictions)
3215 SecPolicyRef
SecPolicyCreateAppleMMCSService(CFStringRef hostname
, CFDictionaryRef context
)
3217 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyAppleMMCService
,
3218 kSecPolicyNameAppleMMCSService
,
3219 &oidAppleCertExtAppleServerAuthenticationMMCSProd
,
3220 &oidAppleCertExtAppleServerAuthenticationMMCSProdQA
);
3223 SecPolicyRef
SecPolicyCreateAppleCompatibilityMMCSService(CFStringRef hostname
) {
3224 return SecPolicyCreateAppleGeoTrustServerAuthCommon(hostname
, kSecPolicyAppleMMCSCompatibilityServerAuth
,
3225 kSecPolicyNameAppleMMCSService
,
3226 CFSTR("1.2.840.113635.100.6.27.11.2"),
3227 CFSTR("1.2.840.113635.100.6.27.11.1"));
3231 SecPolicyRef
SecPolicyCreateAppleiCloudSetupService(CFStringRef hostname
, CFDictionaryRef context
)
3233 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyAppleiCloudSetupServerAuth
,
3234 kSecPolicyNameAppleiCloudSetupService
,
3235 &oidAppleCertExtAppleServerAuthenticationiCloudSetupProd
,
3236 &oidAppleCertExtAppleServerAuthenticationiCloudSetupProdQA
);
3239 SecPolicyRef
SecPolicyCreateAppleCompatibilityiCloudSetupService(CFStringRef hostname
)
3241 return SecPolicyCreateAppleGeoTrustServerAuthCommon(hostname
, kSecPolicyAppleiCloudSetupCompatibilityServerAuth
,
3242 kSecPolicyNameAppleiCloudSetupService
,
3243 CFSTR("1.2.840.113635.100.6.27.15.2"),
3244 CFSTR("1.2.840.113635.100.6.27.15.1"));
3248 @function SecPolicyCreateAppleSSLService
3249 @abstract Ensure we're appropriately pinned to an Apple server (SSL + Apple restrictions)
3251 SecPolicyRef
SecPolicyCreateAppleSSLService(CFStringRef hostname
)
3253 // SSL server, pinned to an Apple intermediate
3254 SecPolicyRef policy
= SecPolicyCreateSSL(true, hostname
);
3255 CFMutableDictionaryRef options
= NULL
;
3256 require(policy
, errOut
);
3258 // change options for SSL policy evaluation
3259 require((options
=(CFMutableDictionaryRef
)policy
->_options
) != NULL
, errOut
);
3261 // Apple CA anchored
3262 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameServerAuthentication
), errOut
);
3264 // Check leaf for Apple Server Authentication marker oid (1.2.840.113635.100.6.27.1)
3265 add_leaf_marker(options
, &oidAppleCertExtAppleServerAuthentication
);
3267 // Check intermediate for Apple Server Authentication intermediate marker (1.2.840.113635.100.6.2.12)
3268 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleServerAuthentication
);
3270 /* Check for weak hashes */
3271 CFDictionaryAddValue(options
, kSecPolicyCheckSystemTrustedWeakHash
, kCFBooleanTrue
);
3272 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
3274 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
3276 SecPolicySetOid(policy
, kSecPolicyAppleServerAuthentication
);
3277 SecPolicySetName(policy
, kSecPolicyNameServerAuthentication
);
3282 CFReleaseSafe(options
);
3283 CFReleaseSafe(policy
);
3288 @function SecPolicyCreateApplePPQSigning
3289 @abstract Check for intermediate certificate 'Apple System Integration 2 Certification Authority' by name,
3291 Leaf cert must have Digital Signature usage.
3292 Leaf cert must have Apple PPQ Signing marker OID (1.2.840.113635.100.6.38.2).
3293 Intermediate must have marker OID (1.2.840.113635.100.6.2.10).
3295 SecPolicyRef
SecPolicyCreateApplePPQSigning(void)
3297 SecPolicyRef result
= NULL
;
3298 CFMutableDictionaryRef options
= NULL
;
3299 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3300 &kCFTypeDictionaryKeyCallBacks
,
3301 &kCFTypeDictionaryValueCallBacks
), errOut
);
3302 SecPolicyAddBasicCertOptions(options
);
3304 SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNamePPQSigning
);
3305 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3307 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
3308 CFSTR("Apple System Integration 2 Certification Authority"));
3310 // Check that leaf has extension with "Apple PPQ Signing" prod oid (1.2.840.113635.100.6.38.2)
3311 add_leaf_marker(options
, &oidAppleCertExtApplePPQSigningProd
);
3313 // Check that intermediate has extension (1.2.840.113635.100.6.2.10)
3314 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleSystemIntg2
);
3316 add_ku(options
, kSecKeyUsageDigitalSignature
);
3318 require(result
= SecPolicyCreate(kSecPolicyApplePPQSigning
,
3319 kSecPolicyNamePPQSigning
, options
), errOut
);
3322 CFReleaseSafe(options
);
3327 @function SecPolicyCreateTestApplePPQSigning
3328 @abstract Check for intermediate certificate 'Apple System Integration 2 Certification Authority' by name,
3330 Leaf cert must have Digital Signature usage.
3331 Leaf cert must have Apple PPQ Signing Test marker OID (1.2.840.113635.100.6.38.1).
3332 Intermediate must have marker OID (1.2.840.113635.100.6.2.10).
3334 SecPolicyRef
SecPolicyCreateTestApplePPQSigning(void)
3336 /* Guard against use of test policy on production devices */
3337 if (!SecIsInternalRelease()) {
3338 return SecPolicyCreateApplePPQSigning();
3341 SecPolicyRef result
= NULL
;
3342 CFMutableDictionaryRef options
= NULL
;
3343 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3344 &kCFTypeDictionaryKeyCallBacks
,
3345 &kCFTypeDictionaryValueCallBacks
), errOut
);
3346 SecPolicyAddBasicCertOptions(options
);
3348 SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameTestPPQSigning
);
3349 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3351 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
3352 CFSTR("Apple System Integration 2 Certification Authority"));
3354 // Check that leaf has extension with "Apple PPQ Signing" test oid (1.2.840.113635.100.6.38.1)
3355 add_leaf_marker(options
, &oidAppleCertExtApplePPQSigningProdQA
);
3357 // Check that intermediate has extension (1.2.840.113635.100.6.2.10)
3358 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleSystemIntg2
);
3360 add_ku(options
, kSecKeyUsageDigitalSignature
);
3362 require(result
= SecPolicyCreate(kSecPolicyAppleTestPPQSigning
,
3363 kSecPolicyNameTestPPQSigning
, options
), errOut
);
3366 CFReleaseSafe(options
);
3370 @function SecPolicyCreateAppleTimeStamping
3371 @abstract Check for RFC3161 timestamping EKU.
3373 SecPolicyRef
SecPolicyCreateAppleTimeStamping(void)
3375 SecPolicyRef result
= NULL
;
3376 CFMutableDictionaryRef options
= NULL
;
3377 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3378 &kCFTypeDictionaryKeyCallBacks
,
3379 &kCFTypeDictionaryValueCallBacks
), errOut
);
3381 SecPolicyAddBasicX509Options(options
);
3383 /* Require id-kp-timeStamping extendedKeyUsage to be present. */
3384 add_eku(options
, &oidExtendedKeyUsageTimeStamping
);
3386 require(result
= SecPolicyCreate(kSecPolicyAppleTimeStamping
,
3387 kSecPolicyNameTimeStamping
, options
), errOut
);
3390 CFReleaseSafe(options
);
3395 @function SecPolicyCreateApplePayIssuerEncryption
3396 @abstract Check for intermediate certificate 'Apple Worldwide Developer Relations CA - G2' by name,
3397 and ECC apple anchor.
3398 Leaf cert must have Key Encipherment and Key Agreement usage.
3399 Leaf cert must have Apple Pay Issuer Encryption marker OID (1.2.840.113635.100.6.39).
3401 SecPolicyRef
SecPolicyCreateApplePayIssuerEncryption(void)
3403 SecPolicyRef result
= NULL
;
3404 CFMutableDictionaryRef options
= NULL
;
3405 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3406 &kCFTypeDictionaryKeyCallBacks
,
3407 &kCFTypeDictionaryValueCallBacks
), errOut
);
3408 SecPolicyAddBasicCertOptions(options
);
3410 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNamePayIssuerEncryption
),
3412 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3414 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
3415 CFSTR("Apple Worldwide Developer Relations CA - G2"));
3417 // Check that leaf has extension with "Apple Pay Issuer Encryption" oid (1.2.840.113635.100.6.39)
3418 add_leaf_marker(options
, &oidAppleCertExtCryptoServicesExtEncryption
);
3420 add_ku(options
, kSecKeyUsageKeyEncipherment
);
3422 require(result
= SecPolicyCreate(kSecPolicyApplePayIssuerEncryption
,
3423 kSecPolicyNamePayIssuerEncryption
, options
), errOut
);
3426 CFReleaseSafe(options
);
3431 @function SecPolicyCreateAppleATVVPNProfileSigning
3432 @abstract Check for leaf marker OID 1.2.840.113635.100.6.43,
3433 intermediate marker OID 1.2.840.113635.100.6.2.10,
3434 chains to Apple Root CA, path length 3
3436 SecPolicyRef
SecPolicyCreateAppleATVVPNProfileSigning(void)
3438 SecPolicyRef result
= NULL
;
3439 CFMutableDictionaryRef options
= NULL
;
3440 CFMutableDictionaryRef appleAnchorOptions
= NULL
;
3441 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3442 &kCFTypeDictionaryKeyCallBacks
,
3443 &kCFTypeDictionaryValueCallBacks
), errOut
);
3445 SecPolicyAddBasicCertOptions(options
);
3447 // Require pinning to the Apple CAs (including test CA for internal releases)
3448 appleAnchorOptions
= CFDictionaryCreateMutableForCFTypes(NULL
);
3449 require(appleAnchorOptions
, errOut
);
3451 if (SecIsInternalRelease()) {
3452 CFDictionarySetValue(appleAnchorOptions
,
3453 kSecPolicyAppleAnchorIncludeTestRoots
, kCFBooleanTrue
);
3456 add_element(options
, kSecPolicyCheckAnchorApple
, appleAnchorOptions
);
3458 // Cert chain length 3
3459 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3461 // Check leaf for Apple ATV VPN Profile Signing OID (1.2.840.113635.100.6.43)
3462 add_leaf_marker(options
, &oidAppleCertExtATVVPNProfileSigning
);
3464 // Check intermediate for Apple System Integration 2 CA intermediate marker (1.2.840.113635.100.6.2.10)
3465 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleSystemIntg2
);
3467 // Ensure that revocation is checked (OCSP only)
3468 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationOCSP
);
3470 require(result
= SecPolicyCreate(kSecPolicyAppleATVVPNProfileSigning
,
3471 kSecPolicyNameATVVPNProfileSigning
, options
), errOut
);
3474 CFReleaseSafe(options
);
3475 CFReleaseSafe(appleAnchorOptions
);
3479 SecPolicyRef
SecPolicyCreateAppleHomeKitServerAuth(CFStringRef hostname
) {
3480 CFMutableDictionaryRef appleAnchorOptions
= NULL
;
3481 CFMutableDictionaryRef options
= NULL
;
3482 SecPolicyRef result
= NULL
;
3483 CFDataRef oid
= NULL
;
3485 options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0, &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
3486 require(options
, errOut
);
3488 SecPolicyAddBasicX509Options(options
);
3490 CFDictionaryAddValue(options
, kSecPolicyCheckSSLHostname
, hostname
);
3492 add_eku(options
, &oidExtendedKeyUsageServerAuth
);
3494 if (requireUATPinning(kSecPolicyNameAppleHomeKitService
)) {
3496 // Cert chain length 3
3497 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3499 // Apple anchors, allowing test anchors for internal release
3500 SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameAppleHomeKitService
);
3502 add_leaf_marker(options
, &oidAppleCertExtHomeKitServerAuth
);
3504 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleHomeKitServerCA
);
3507 /* Check for weak hashes */
3508 CFDictionaryAddValue(options
, kSecPolicyCheckSystemTrustedWeakHash
, kCFBooleanTrue
);
3509 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
3511 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
3513 result
= SecPolicyCreate(kSecPolicyAppleHomeKitServerAuth
,
3514 kSecPolicyNameAppleHomeKitService
, options
);
3515 require(result
, errOut
);
3518 CFReleaseSafe(appleAnchorOptions
);
3519 CFReleaseSafe(options
);
3524 SecPolicyRef
SecPolicyCreateAppleExternalDeveloper(void) {
3525 CFMutableDictionaryRef options
= NULL
;
3526 SecPolicyRef result
= NULL
;
3528 /* Create basic Apple pinned policy */
3529 require(result
= SecPolicyCreateApplePinned(kSecPolicyNameExternalDeveloper
,
3530 CFSTR("1.2.840.113635.100.6.2.1"), // WWDR Intermediate OID
3531 CFSTR("1.2.840.113635.100.6.1.2")), // "iPhone Developer" leaf OID
3534 require_action(options
= CFDictionaryCreateMutableCopy(NULL
, 0, result
->_options
), errOut
, CFReleaseNull(result
));
3536 /* Additional intermediate OIDs */
3537 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
,
3538 CFSTR("1.2.840.113635.100.6.2.6")); // "Developer ID" Intermediate OID
3540 /* Addtional leaf OIDS */
3541 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.4")); // "iPhone Distribution" leaf OID
3542 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.5")); // "Safari Developer" leaf OID
3543 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.7")); // "3rd Party Mac Developer Application" leaf OID
3544 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.8")); // "3rd Party Mac Developer Installer" leaf OID
3545 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.12")); // "Mac Developer" leaf OID
3546 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.13")); // "Developer ID Application" leaf OID
3547 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.14")); // "Developer ID Installer" leaf OID
3550 add_eku_string(options
, CFSTR("1.3.6.1.5.5.7.3.3")); // CodeSigning EKU
3551 add_eku_string(options
, CFSTR("1.2.840.113635.100.4.8")); // "Safari Developer" EKU
3552 add_eku_string(options
, CFSTR("1.2.840.113635.100.4.9")); // "3rd Party Mac Developer Installer" EKU
3553 add_eku_string(options
, CFSTR("1.2.840.113635.100.4.13")); // "Developer ID Installer" EKU
3555 CFReleaseSafe(result
->_options
);
3556 result
->_options
= CFRetainSafe(options
);
3558 SecPolicySetOid(result
, kSecPolicyAppleExternalDeveloper
);
3561 CFReleaseSafe(options
);
3565 /* This one is special because the intermediate has no marker OID */
3566 SecPolicyRef
SecPolicyCreateAppleSoftwareSigning(void) {
3567 CFMutableDictionaryRef options
= NULL
;
3568 CFDictionaryRef keySizes
= NULL
;
3569 CFNumberRef rsaSize
= NULL
, ecSize
= NULL
;
3570 SecPolicyRef result
= NULL
;
3572 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3573 &kCFTypeDictionaryKeyCallBacks
,
3574 &kCFTypeDictionaryValueCallBacks
), errOut
);
3576 SecPolicyAddBasicCertOptions(options
);
3578 /* Anchored to the Apple Roots */
3579 require_quiet(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameSoftwareSigning
),
3582 /* Exactly 3 certs in the chain */
3583 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3585 /* Intermediate Common Name matches */
3586 add_element(options
, kSecPolicyCheckIssuerCommonName
, CFSTR("Apple Code Signing Certification Authority"));
3588 /* Leaf marker OID matches */
3589 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.22"));
3591 /* Leaf has CodeSigning EKU */
3592 add_eku_string(options
, CFSTR("1.3.6.1.5.5.7.3.3"));
3594 /* Check revocation using any available method */
3595 add_element(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
3597 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
3598 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
3600 require(result
= SecPolicyCreate(kSecPolicyAppleSoftwareSigning
,
3601 kSecPolicyNameSoftwareSigning
, options
), errOut
);
3604 CFReleaseSafe(options
);
3605 CFReleaseSafe(keySizes
);
3606 CFReleaseSafe(rsaSize
);
3607 CFReleaseSafe(ecSize
);
3611 /* subject:/CN=SEP Root CA/O=Apple Inc./ST=California */
3612 /* SKID: 58:EF:D6:BE:C5:82:B0:54:CD:18:A6:84:AD:A2:F6:7B:7B:3A:7F:CF */
3613 /* Not Before: Jun 24 21:43:24 2014 GMT, Not After : Jun 24 21:43:24 2029 GMT */
3614 /* Signature Algorithm: ecdsa-with-SHA384 */
3615 const uint8_t SEPRootCA_SHA256
[kSecPolicySHA256Size
] = {
3616 0xd1, 0xdf, 0x82, 0x00, 0xf3, 0x89, 0x4e, 0xe9, 0x96, 0xf3, 0x77, 0xdf, 0x76, 0x3b, 0x0a, 0x16,
3617 0x8f, 0xd9, 0x6c, 0x58, 0xc0, 0x3e, 0xc9, 0xb0, 0x5f, 0xa5, 0x64, 0x79, 0xc0, 0xe8, 0xc9, 0xe7
3620 SecPolicyRef
SecPolicyCreateAppleUniqueDeviceCertificate(CFDataRef testRootHash
) {
3621 CFMutableDictionaryRef options
= NULL
;
3622 CFDictionaryRef keySizes
= NULL
;
3623 CFNumberRef ecSize
= NULL
;
3624 SecPolicyRef result
= NULL
;
3626 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3627 &kCFTypeDictionaryKeyCallBacks
,
3628 &kCFTypeDictionaryValueCallBacks
), errOut
);
3630 /* Device certificate should never expire */
3631 SecPolicyAddBasicCertOptions(options
);
3633 /* Anchored to the SEP Root CA. Allow alternative root for developers */
3634 require(SecPolicyAddAnchorSHA256Options(options
, SEPRootCA_SHA256
),errOut
);
3635 if (testRootHash
&& SecIsInternalRelease() && (kSecPolicySHA256Size
== CFDataGetLength(testRootHash
))) {
3636 add_element(options
, kSecPolicyCheckAnchorSHA256
, testRootHash
);
3639 /* Exactly 3 certs in the chain */
3640 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3642 /* Intermediate has marker OID with value */
3643 add_intermediate_marker_value_string(options
, CFSTR("1.2.840.113635.100.6.44"), CFSTR("ucrt"));
3645 /* Leaf has marker OID with varying value that can't be pre-determined */
3646 add_element(options
, kSecPolicyCheckLeafMarkerOidWithoutValueCheck
, CFSTR("1.2.840.113635.100.10.1"));
3648 /* RSA key sizes are disallowed. EC key sizes are P-256 or larger. */
3649 require(ecSize
= CFNumberCreateWithCFIndex(NULL
, 256), errOut
);
3650 require(keySizes
= CFDictionaryCreate(NULL
, (const void**)&kSecAttrKeyTypeEC
,
3651 (const void**)&ecSize
, 1,
3652 &kCFTypeDictionaryKeyCallBacks
,
3653 &kCFTypeDictionaryValueCallBacks
), errOut
);
3654 add_element(options
, kSecPolicyCheckKeySize
, keySizes
);
3657 require(result
= SecPolicyCreate(kSecPolicyAppleUniqueDeviceIdentifierCertificate
,
3658 kSecPolicyNameUniqueDeviceIdentifierCertificate
, options
), errOut
);
3661 CFReleaseSafe(options
);
3662 CFReleaseSafe(keySizes
);
3663 CFReleaseSafe(ecSize
);
3667 SecPolicyRef
SecPolicyCreateAppleWarsaw(void) {
3668 CFMutableDictionaryRef options
= NULL
;
3669 SecPolicyRef result
= NULL
;
3670 #if TARGET_OS_BRIDGE
3671 CFMutableDictionaryRef appleAnchorOptions
= NULL
;
3674 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3675 &kCFTypeDictionaryKeyCallBacks
,
3676 &kCFTypeDictionaryValueCallBacks
), errOut
);
3678 SecPolicyAddBasicX509Options(options
);
3680 /* Anchored to the Apple Roots. */
3681 require_quiet(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameWarsaw
),
3684 /* Exactly 3 certs in the chain */
3685 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3687 /* Intermediate marker OID matches input OID */
3688 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.14"));
3690 /* Leaf marker OID matches input OID */
3691 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.29"));
3693 /* Check revocation using any available method */
3694 add_element(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
3696 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
3697 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
3699 require(result
= SecPolicyCreate(kSecPolicyAppleWarsaw
,
3700 kSecPolicyNameWarsaw
, options
), errOut
);
3703 CFReleaseSafe(options
);
3707 SecPolicyRef
SecPolicyCreateAppleSecureIOStaticAsset(void) {
3708 CFMutableDictionaryRef options
= NULL
;
3709 SecPolicyRef result
= NULL
;
3710 #if TARGET_OS_BRIDGE
3711 CFMutableDictionaryRef appleAnchorOptions
= NULL
;
3714 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3715 &kCFTypeDictionaryKeyCallBacks
,
3716 &kCFTypeDictionaryValueCallBacks
), errOut
);
3718 /* This certificate cannot expire so that assets always load */
3719 SecPolicyAddBasicCertOptions(options
);
3721 /* Anchored to the Apple Roots. */
3722 #if TARGET_OS_BRIDGE
3723 /* On the bridge, test roots are gated in the trust and policy servers. */
3724 require_quiet(appleAnchorOptions
= CFDictionaryCreateMutableForCFTypes(NULL
), errOut
);
3725 CFDictionarySetValue(appleAnchorOptions
,
3726 kSecPolicyAppleAnchorIncludeTestRoots
, kCFBooleanTrue
);
3727 add_element(options
, kSecPolicyCheckAnchorApple
, appleAnchorOptions
);
3728 CFReleaseSafe(appleAnchorOptions
);
3730 require_quiet(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameSecureIOStaticAsset
),
3734 /* Exactly 3 certs in the chain */
3735 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3737 /* Intermediate marker OID matches ASI CA */
3738 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.10"));
3740 /* Leaf marker OID matches static IO OID */
3741 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.50"));
3743 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
3744 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
3746 require(result
= SecPolicyCreate(kSecPolicyAppleSecureIOStaticAsset
,
3747 kSecPolicyNameSecureIOStaticAsset
, options
), errOut
);
3750 CFReleaseSafe(options
);
3754 SecPolicyRef
SecPolicyCreateAppleAppTransportSecurity(void) {
3755 CFMutableDictionaryRef options
= NULL
;
3756 SecPolicyRef result
= NULL
;
3757 CFMutableSetRef disallowedHashes
= NULL
;
3759 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3760 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
3762 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
3763 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
3765 /* Hash algorithm is SHA-256 or better */
3766 require(disallowedHashes
= CFSetCreateMutable(NULL
, 5, &kCFTypeSetCallBacks
), errOut
);
3767 CFSetAddValue(disallowedHashes
, kSecSignatureDigestAlgorithmMD2
);
3768 CFSetAddValue(disallowedHashes
, kSecSignatureDigestAlgorithmMD4
);
3769 CFSetAddValue(disallowedHashes
, kSecSignatureDigestAlgorithmMD5
);
3770 CFSetAddValue(disallowedHashes
, kSecSignatureDigestAlgorithmSHA1
);
3771 CFSetAddValue(disallowedHashes
, kSecSignatureDigestAlgorithmSHA224
);
3773 add_element(options
, kSecPolicyCheckSignatureHashAlgorithms
, disallowedHashes
);
3775 require_quiet(result
= SecPolicyCreate(kSecPolicyAppleAppTransportSecurity
,
3776 kSecPolicyNameAppTransportSecurity
,
3780 CFReleaseSafe(options
);
3784 SecPolicyRef
SecPolicyCreateMobileSoftwareUpdate(void) {
3785 CFMutableDictionaryRef options
= NULL
;
3786 SecPolicyRef result
= NULL
;
3787 #if TARGET_OS_BRIDGE
3788 CFMutableDictionaryRef appleAnchorOptions
= NULL
;
3791 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3792 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
3794 /* No expiration check. */
3795 SecPolicyAddBasicCertOptions(options
);
3798 require_quiet(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameMobileSoftwareUpdate
),
3801 /* Exactly 3 certs in the chain */
3802 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3804 /* Intermediate marker OID is iPhone CA OID */
3805 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.18"));
3807 /* Leaf marker OID is either the prod MSU OID, or, on internal builds, the prodQA OID */
3808 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.57.2"));
3809 if (SecIsInternalRelease()) {
3810 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.57.1"));
3813 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
3814 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
3816 require(result
= SecPolicyCreate(kSecPolicyAppleMobileSoftwareUpdate
,
3817 kSecPolicyNameMobileSoftwareUpdate
, options
), errOut
);
3820 CFReleaseNull(options
);
3824 /* subject:/CN=Basic Attestation System Root CA/O=Apple Inc./ST=California */
3825 /* SKID: FE:D1:D1:C2:08:07:03:D5:B9:3C:34:B2:BB:FD:7C:3A:99:25:1B:8F */
3826 /* Not Before: Apr 20 00:22:09 2017 GMT, Not After : Mar 22 00:00:00 2032 GMT */
3827 /* Signature Algorithm: ecdsa-with-SHA384 */
3828 const uint8_t BASystemRootCA_SHA256
[kSecPolicySHA256Size
] = {
3829 0x29, 0x75, 0x9b, 0x53, 0x8a, 0xd1, 0xcb, 0x4f, 0x3b, 0xa5, 0x20, 0x4d, 0x60, 0x4b, 0x25, 0x81,
3830 0x8d, 0x18, 0x9f, 0x62, 0xe3, 0x94, 0x2d, 0x99, 0x52, 0x54, 0x22, 0x5a, 0xe5, 0x7f, 0x42, 0xca
3833 /* subject:/CN=Basic Attestation User Root CA/O=Apple Inc./ST=California */
3834 /* SKID: 83:E5:A3:21:9E:B0:74:C3:F9:61:90:FD:97:4E:23:10:76:A4:A3:F2 */
3835 /* Not Before: Apr 19 21:41:56 2017 GMT, Not After : Mar 22 00:00:00 2032 GMT */
3836 /* Signature Algorithm: ecdsa-with-SHA384 */
3837 const uint8_t BAUserRootCA_SHA256
[kSecPolicySHA256Size
] = {
3838 0x03, 0x75, 0x1c, 0x80, 0xfc, 0xbe, 0x58, 0x19, 0xd1, 0x70, 0xd2, 0x67, 0xce, 0x1a, 0xd6, 0xd0,
3839 0x94, 0x40, 0x7c, 0x91, 0xd8, 0x73, 0xd7, 0xa6, 0x56, 0x2d, 0xe3, 0x66, 0x6d, 0x35, 0x94, 0xc6
3842 SecPolicyRef
SecPolicyCreateAppleBasicAttestationSystem(CFDataRef testRootHash
) {
3843 CFMutableDictionaryRef options
= NULL
;
3844 SecPolicyRef result
= NULL
;
3846 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3847 &kCFTypeDictionaryKeyCallBacks
,
3848 &kCFTypeDictionaryValueCallBacks
), errOut
);
3849 /* BAA certs expire */
3850 SecPolicyAddBasicX509Options(options
);
3852 /* Anchored to one of the Basic Attestation roots. Allow alternative root for developers */
3853 SecPolicyAddAnchorSHA256Options(options
, BASystemRootCA_SHA256
);
3854 if (testRootHash
&& SecIsInternalRelease() && (kSecPolicySHA256Size
== CFDataGetLength(testRootHash
))) {
3855 add_element(options
, kSecPolicyCheckAnchorSHA256
, testRootHash
);
3858 /* Exactly 3 certs in the chain */
3859 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3861 require(result
= SecPolicyCreate(kSecPolicyAppleBasicAttestationSystem
,
3862 kSecPolicyNameBasicAttestationSystem
, options
), errOut
);
3865 CFReleaseSafe(options
);
3869 SecPolicyRef
SecPolicyCreateAppleBasicAttestationUser(CFDataRef testRootHash
) {
3870 CFMutableDictionaryRef options
= NULL
;
3871 SecPolicyRef result
= NULL
;
3873 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3874 &kCFTypeDictionaryKeyCallBacks
,
3875 &kCFTypeDictionaryValueCallBacks
), errOut
);
3876 /* BAA certs expire */
3877 SecPolicyAddBasicX509Options(options
);
3879 /* Anchored to one of the Basic Attestation roots. Allow alternative root for developers */
3880 SecPolicyAddAnchorSHA256Options(options
, BAUserRootCA_SHA256
);
3881 if (testRootHash
&& SecIsInternalRelease() && (kSecPolicySHA256Size
== CFDataGetLength(testRootHash
))) {
3882 add_element(options
, kSecPolicyCheckAnchorSHA256
, testRootHash
);
3885 /* Exactly 3 certs in the chain */
3886 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3888 require(result
= SecPolicyCreate(kSecPolicyAppleBasicAttestationUser
,
3889 kSecPolicyNameBasicAttestationUser
, options
), errOut
);
3892 CFReleaseSafe(options
);
3896 SecPolicyRef
SecPolicyCreateDemoDigitalCatalogSigning(void) {
3897 CFMutableDictionaryRef options
= NULL
;
3898 SecPolicyRef result
= NULL
;
3900 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3901 &kCFTypeDictionaryKeyCallBacks
,
3902 &kCFTypeDictionaryValueCallBacks
), errOut
);
3903 SecPolicyAddBasicX509Options(options
);
3905 /* Exactly 3 certs in the chain */
3906 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3908 /* Demo Signing Extension present in leaf */
3909 add_element(options
, kSecPolicyCheckLeafMarkerOid
, CFSTR("1.2.840.113635.100.6.60"));
3911 /* Issuer common name is "DemoUnit CA" */
3912 add_element(options
, kSecPolicyCheckIssuerCommonName
, CFSTR("DemoUnit CA"));
3914 require(result
= SecPolicyCreate(kSecPolicyAppleDemoDigitalCatalog
,
3915 kSecPolicyNameDemoDigitalCatalog
, options
), errOut
);
3918 CFReleaseSafe(options
);