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 /* Skip networked revocation checks */
1782 CFDictionaryAddValue(options
, kSecPolicyCheckNoNetworkAccess
, kCFBooleanTrue
);
1784 require(result
= SecPolicyCreate(kSecPolicyAppleiPhoneApplicationSigning
,
1785 kSecPolicyNameiPhoneApplicationSigning
, options
),
1789 CFReleaseSafe(options
);
1793 SecPolicyRef
SecPolicyCreateiPhoneVPNApplicationSigning(void) {
1794 CFMutableDictionaryRef options
= NULL
;
1795 SecPolicyRef result
= NULL
;
1797 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1798 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1800 SecPolicyAddBasicCertOptions(options
);
1802 /* Anchored to the Apple Roots */
1803 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameiPhoneVPNApplicationSigning
), errOut
);
1806 if (SecIsInternalRelease()) {
1807 /* Allow a prod hierarchy-signed test cert */
1808 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonNameTEST
,
1809 CFSTR("Apple iPhone OS Application Signing"));
1810 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.6.1"));
1813 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
,
1814 CFSTR("Apple iPhone OS Application Signing"));
1816 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.6"));
1818 add_eku(options
, NULL
); /* eku extension is optional */
1819 add_eku(options
, &oidAnyExtendedKeyUsage
);
1820 add_eku(options
, &oidExtendedKeyUsageCodeSigning
);
1822 /* Intermediate check */
1823 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
1824 CFSTR("Apple iPhone Certification Authority"));
1826 /* Chain length check */
1827 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1829 /* Skip networked revocation checks */
1830 CFDictionaryAddValue(options
, kSecPolicyCheckNoNetworkAccess
, kCFBooleanTrue
);
1832 require(result
= SecPolicyCreate(kSecPolicyAppleiPhoneVPNApplicationSigning
,
1833 kSecPolicyNameiPhoneVPNApplicationSigning
, options
),
1837 CFReleaseSafe(options
);
1841 SecPolicyRef
SecPolicyCreateiPhoneProfileApplicationSigning(void) {
1842 CFMutableDictionaryRef options
= NULL
;
1843 SecPolicyRef result
= NULL
;
1845 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1846 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1848 SecPolicyAddBasicX509Options(options
); // With expiration checking
1851 require_quiet(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameiPhoneProfileApplicationSigning
),
1855 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1857 /* Leaf has CodeSigning EKU */
1858 add_eku_string(options
, CFSTR("1.3.6.1.5.5.7.3.3"));
1860 /* On iOS, the cert in the provisioning profile may be one of:
1861 leaf OID intermediate OID
1862 iPhone Developer <ADS>.6.1.2 <ADS>.6.2.1
1863 iPhone Distribution <ADS>.6.1.4 <ADS>.6.2.1
1864 TestFlight (Prod) <ADS>.6.1.25.1 <ADS>.6.2.1
1865 TestFlight (QA) <ADS>.6.1.25.2 <ADS>.6.2.1
1867 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.1"));
1868 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.2"));
1869 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.4"));
1870 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.25.1"));
1871 if (SecIsInternalRelease()) {
1872 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.25.2"));
1875 /* Revocation via any available method */
1876 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
1878 require(result
= SecPolicyCreate(kSecPolicyAppleiPhoneProfileApplicationSigning
,
1879 kSecPolicyNameiPhoneProfileApplicationSigning
,
1883 CFReleaseSafe(options
);
1887 SecPolicyRef
SecPolicyCreateMacOSProfileApplicationSigning(void) {
1888 CFMutableDictionaryRef options
= NULL
;
1889 SecPolicyRef result
= NULL
;
1891 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1892 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1894 SecPolicyAddBasicCertOptions(options
); // Without expiration checking
1897 require_quiet(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameiPhoneProfileApplicationSigning
),
1901 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1903 /* Leaf has CodeSigning EKU */
1904 add_eku_string(options
, CFSTR("1.3.6.1.5.5.7.3.3"));
1907 /* On macOS, the cert in the provisioning profile may be one of:
1908 leaf OID intermediate OID
1909 MAS Development <ADS>.6.1.12 <ADS>.6.2.1
1910 MAS Submission <ADS>.6.1.7 <ADS>.6.2.1
1911 Developer ID <ADS>.6.1.13 <ADS>.6.2.6
1912 B&I <ADS>.6.22 None - "Apple Code Signing Certification Authority"
1914 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.12"));
1915 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.7"));
1916 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.13"));
1917 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.22"));
1919 /* Revocation via any available method */
1920 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
1922 require(result
= SecPolicyCreate(kSecPolicyAppleMacOSProfileApplicationSigning
,
1923 kSecPolicyNameMacOSProfileApplicationSigning
,
1927 CFReleaseSafe(options
);
1931 SecPolicyRef
SecPolicyCreateiPhoneProvisioningProfileSigning(void) {
1932 CFMutableDictionaryRef options
= NULL
;
1933 SecPolicyRef result
= NULL
;
1935 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1936 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1938 SecPolicyAddBasicCertOptions(options
);
1940 /* Basic X.509 policy with the additional requirements that the chain
1941 length is 3, it's anchored at the AppleCA and the leaf certificate
1942 has issuer "Apple iPhone Certification Authority" and
1943 subject "Apple iPhone OS Provisioning Profile Signing" for the common name. */
1944 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
1945 CFSTR("Apple iPhone Certification Authority"));
1946 if (SecIsInternalRelease()) {
1947 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonNameTEST
,
1948 CFSTR("Apple iPhone OS Provisioning Profile Signing"));
1951 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
,
1952 CFSTR("Apple iPhone OS Provisioning Profile Signing"));
1955 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1956 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameiPhoneProvisioningProfileSigning
), errOut
);
1958 /* Skip networked revocation checks */
1959 CFDictionaryAddValue(options
, kSecPolicyCheckNoNetworkAccess
, kCFBooleanTrue
);
1961 require(result
= SecPolicyCreate(kSecPolicyAppleiPhoneProvisioningProfileSigning
,
1962 kSecPolicyNameiPhoneProvisioningProfileSigning
, options
),
1965 /* 1.2.840.113635.100.6.2.2.1, non-critical: DER:05:00 - provisioning profile */
1968 CFReleaseSafe(options
);
1972 SecPolicyRef
SecPolicyCreateAppleTVOSApplicationSigning(void) {
1973 CFMutableDictionaryRef options
= NULL
;
1974 SecPolicyRef result
= NULL
;
1975 CFDataRef atvProdOid
= NULL
;
1976 CFDataRef atvTestOid
= NULL
;
1977 CFArrayRef oids
= NULL
;
1979 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1980 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1982 SecPolicyAddBasicCertOptions(options
);
1984 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1986 require_quiet(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameTVOSApplicationSigning
),
1989 /* Check for intermediate: Apple Worldwide Developer Relations */
1990 /* 1.2.840.113635.100.6.2.1 */
1991 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleWWDR
);
1993 add_ku(options
, kSecKeyUsageDigitalSignature
);
1995 /* Check for prod or test AppleTV Application Signing OIDs */
1996 /* Prod: 1.2.840.113635.100.6.1.24 */
1997 /* ProdQA: 1.2.840.113635.100.6.1.24.1 */
1998 add_leaf_marker(options
, &oidAppleTVOSApplicationSigningProd
);
1999 add_leaf_marker(options
, &oidAppleTVOSApplicationSigningProdQA
);
2001 /* Skip networked revocation checks */
2002 CFDictionaryAddValue(options
, kSecPolicyCheckNoNetworkAccess
, kCFBooleanTrue
);
2004 require(result
= SecPolicyCreate(kSecPolicyAppleTVOSApplicationSigning
,
2005 kSecPolicyNameTVOSApplicationSigning
, options
),
2009 CFReleaseSafe(options
);
2010 CFReleaseSafe(oids
);
2011 CFReleaseSafe(atvProdOid
);
2012 CFReleaseSafe(atvTestOid
);
2016 SecPolicyRef
SecPolicyCreateOCSPSigner(void) {
2017 CFMutableDictionaryRef options
= NULL
;
2018 SecPolicyRef result
= NULL
;
2020 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2021 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2023 SecPolicyAddBasicX509Options(options
);
2025 /* Require id-kp-OCSPSigning extendedKeyUsage to be present, not optional. */
2026 add_eku(options
, &oidExtendedKeyUsageOCSPSigning
);
2028 require(result
= SecPolicyCreate(kSecPolicyAppleOCSPSigner
,
2029 kSecPolicyNameOCSPSigner
, options
), errOut
);
2032 CFReleaseSafe(options
);
2036 SecPolicyRef
SecPolicyCreateRevocation(CFOptionFlags revocationFlags
) {
2037 CFMutableDictionaryRef options
= NULL
;
2038 SecPolicyRef result
= NULL
;
2040 require(revocationFlags
!= 0, errOut
);
2042 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2043 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2045 if (revocationFlags
& kSecRevocationCheckIfTrusted
) {
2046 CFDictionaryAddValue(options
, kSecPolicyCheckRevocationIfTrusted
, kCFBooleanTrue
);
2047 /* Set method, but allow caller to override with later checks */
2048 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
2051 if (revocationFlags
& kSecRevocationOnlineCheck
) {
2052 CFDictionaryAddValue(options
, kSecPolicyCheckRevocationOnline
, kCFBooleanTrue
);
2053 /* Set method, but allow caller to override with later checks */
2054 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
2057 if (revocationFlags
& kSecRevocationOCSPMethod
&& revocationFlags
& kSecRevocationCRLMethod
) {
2058 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
2060 else if (revocationFlags
& kSecRevocationOCSPMethod
) {
2061 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationOCSP
);
2063 else if (revocationFlags
& kSecRevocationCRLMethod
) {
2064 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationCRL
);
2067 if (revocationFlags
& kSecRevocationRequirePositiveResponse
) {
2068 CFDictionaryAddValue(options
, kSecPolicyCheckRevocationResponseRequired
, kCFBooleanTrue
);
2071 if (revocationFlags
& kSecRevocationNetworkAccessDisabled
) {
2072 CFDictionaryAddValue(options
, kSecPolicyCheckNoNetworkAccess
, kCFBooleanTrue
);
2074 /* If the caller didn't explicitly disable network access, the revocation policy
2075 * should override any other policy's network setting.
2076 * In particular, pairing a revocation policy with BasicX509 should result in
2077 * allowing network access for revocation unless explicitly disabled.
2078 * Note that SecTrustSetNetworkFetchAllowed can override even this. */
2079 CFDictionaryAddValue(options
, kSecPolicyCheckNoNetworkAccess
, kCFBooleanFalse
);
2082 /* Only flag bits 0-6 are currently defined */
2083 require(((revocationFlags
>> 7) == 0), errOut
);
2085 require(result
= SecPolicyCreate(kSecPolicyAppleRevocation
,
2086 kSecPolicyNameRevocation
, options
), errOut
);
2089 CFReleaseSafe(options
);
2093 SecPolicyRef
SecPolicyCreateSMIME(CFIndex smimeUsage
, CFStringRef email
) {
2094 CFMutableDictionaryRef options
= NULL
;
2095 SecPolicyRef result
= NULL
;
2097 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2098 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2100 if (smimeUsage
& kSecIgnoreExpirationSMIMEUsage
) {
2101 SecPolicyAddBasicCertOptions(options
);
2103 SecPolicyAddBasicX509Options(options
);
2106 /* We call add_ku for each combination of bits we are willing to allow. */
2107 if (smimeUsage
& kSecSignSMIMEUsage
) {
2108 add_ku(options
, kSecKeyUsageUnspecified
);
2109 add_ku(options
, kSecKeyUsageDigitalSignature
);
2110 add_ku(options
, kSecKeyUsageNonRepudiation
);
2112 if (smimeUsage
& kSecKeyEncryptSMIMEUsage
) {
2113 add_ku(options
, kSecKeyUsageKeyEncipherment
);
2115 if (smimeUsage
& kSecDataEncryptSMIMEUsage
) {
2116 add_ku(options
, kSecKeyUsageDataEncipherment
);
2118 if (smimeUsage
& kSecKeyExchangeDecryptSMIMEUsage
) {
2119 add_ku(options
, kSecKeyUsageKeyAgreement
| kSecKeyUsageDecipherOnly
);
2121 if (smimeUsage
& kSecKeyExchangeEncryptSMIMEUsage
) {
2122 add_ku(options
, kSecKeyUsageKeyAgreement
| kSecKeyUsageEncipherOnly
);
2124 if (smimeUsage
& kSecKeyExchangeBothSMIMEUsage
) {
2125 add_ku(options
, kSecKeyUsageKeyAgreement
| kSecKeyUsageEncipherOnly
| kSecKeyUsageDecipherOnly
);
2129 CFDictionaryAddValue(options
, kSecPolicyCheckEmail
, email
);
2132 /* RFC 3850 paragraph 4.4.4
2134 If the extended key usage extension is present in the certificate
2135 then interpersonal message S/MIME receiving agents MUST check that it
2136 contains either the emailProtection or the anyExtendedKeyUsage OID as
2137 defined in [KEYM]. S/MIME uses other than interpersonal messaging
2138 MAY require the explicit presence of the extended key usage extension
2139 or other OIDs to be present in the extension or both.
2141 add_eku(options
, NULL
); /* eku extension is optional */
2142 add_eku(options
, &oidAnyExtendedKeyUsage
);
2143 add_eku(options
, &oidExtendedKeyUsageEmailProtection
);
2145 #if !TARGET_OS_IPHONE
2146 // Check revocation on OS X
2147 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
2150 require(result
= SecPolicyCreate(kSecPolicyAppleSMIME
, kSecPolicyNameSMIME
, options
), errOut
);
2153 CFReleaseSafe(options
);
2157 SecPolicyRef
SecPolicyCreateApplePackageSigning(void) {
2158 CFMutableDictionaryRef options
= NULL
;
2159 SecPolicyRef result
= NULL
;
2161 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2162 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2164 SecPolicyAddBasicCertOptions(options
);
2166 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2167 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNamePackageSigning
), errOut
);
2169 add_ku(options
, kSecKeyUsageDigitalSignature
);
2170 add_eku(options
, &oidExtendedKeyUsageCodeSigning
);
2172 require(result
= SecPolicyCreate(kSecPolicyApplePackageSigning
,
2173 kSecPolicyNamePackageSigning
, options
),
2177 CFReleaseSafe(options
);
2182 SecPolicyRef
SecPolicyCreateAppleSWUpdateSigning(void) {
2183 CFMutableDictionaryRef options
= NULL
;
2184 SecPolicyRef result
= NULL
;
2186 * OS X rules for this policy:
2187 * -- Must have one intermediate cert
2188 * -- intermediate must have basic constraints with path length 0
2189 * -- intermediate has CSSMOID_APPLE_EKU_CODE_SIGNING EKU
2190 * -- leaf cert has either CODE_SIGNING or CODE_SIGN_DEVELOPMENT EKU (the latter of
2191 * which triggers a CSSMERR_APPLETP_CODE_SIGN_DEVELOPMENT error)
2193 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2194 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2196 SecPolicyAddBasicX509Options(options
);
2198 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2199 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameSWUpdateSigning
), errOut
);
2201 add_eku(options
, &oidAppleExtendedKeyUsageCodeSigning
);
2202 add_oid(options
, kSecPolicyCheckIntermediateEKU
, &oidAppleExtendedKeyUsageCodeSigning
);
2204 require(result
= SecPolicyCreate(kSecPolicyAppleSWUpdateSigning
,
2205 kSecPolicyNameSWUpdateSigning
, options
),
2209 CFReleaseSafe(options
);
2214 SecPolicyRef
SecPolicyCreateCodeSigning(void) {
2215 CFMutableDictionaryRef options
= NULL
;
2216 SecPolicyRef result
= NULL
;
2218 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2219 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2221 SecPolicyAddBasicX509Options(options
);
2223 /* If the key usage extension is present, we accept it having either of
2225 add_ku(options
, kSecKeyUsageDigitalSignature
);
2226 add_ku(options
, kSecKeyUsageNonRepudiation
);
2228 /* We require an extended key usage extension with the codesigning
2229 eku purpose. (The Apple codesigning eku is not accepted here
2230 since it's valid only for SecPolicyCreateAppleSWUpdateSigning.) */
2231 add_eku(options
, &oidExtendedKeyUsageCodeSigning
);
2232 #if TARGET_OS_IPHONE
2233 /* Accept the 'any' eku on iOS only to match prior behavior.
2234 This may be further restricted in future releases. */
2235 add_eku(options
, &oidAnyExtendedKeyUsage
);
2238 require(result
= SecPolicyCreate(kSecPolicyAppleCodeSigning
,
2239 kSecPolicyNameCodeSigning
, options
),
2243 CFReleaseSafe(options
);
2247 /* Explicitly leave out empty subject/subjectaltname check */
2248 SecPolicyRef
SecPolicyCreateLockdownPairing(void) {
2249 CFMutableDictionaryRef options
= NULL
;
2250 SecPolicyRef result
= NULL
;
2252 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2253 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2254 //CFDictionaryAddValue(options, kSecPolicyCheckBasicCertificateProcessing,
2255 // kCFBooleanTrue); // Happens automatically in SecPVCPathChecks
2256 CFDictionaryAddValue(options
, kSecPolicyCheckCriticalExtensions
,
2258 CFDictionaryAddValue(options
, kSecPolicyCheckIdLinkage
,
2260 CFDictionaryAddValue(options
, kSecPolicyCheckBasicConstraints
,
2262 CFDictionaryAddValue(options
, kSecPolicyCheckWeakKeySize
, kCFBooleanTrue
);
2264 require(result
= SecPolicyCreate(kSecPolicyAppleLockdownPairing
,
2265 kSecPolicyNameLockdownPairing
, options
), errOut
);
2268 CFReleaseSafe(options
);
2272 SecPolicyRef
SecPolicyCreateURLBag(void) {
2273 CFMutableDictionaryRef options
= NULL
;
2274 SecPolicyRef result
= NULL
;
2276 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2277 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2279 SecPolicyAddBasicCertOptions(options
);
2281 add_eku(options
, &oidExtendedKeyUsageCodeSigning
);
2283 require(result
= SecPolicyCreate(kSecPolicyAppleURLBag
,
2284 kSecPolicyNameURLBag
, options
), errOut
);
2287 CFReleaseSafe(options
);
2291 SecPolicyRef
SecPolicyCreateOTATasking(void)
2293 CFMutableDictionaryRef options
= NULL
;
2294 SecPolicyRef result
= NULL
;
2296 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2297 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2299 SecPolicyAddBasicX509Options(options
);
2302 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameMobileAsset
), errOut
);
2304 /* Chain length of 3 */
2305 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2307 /* Intermediate has common name "Apple iPhone Certification Authority". */
2308 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2309 CFSTR("Apple iPhone Certification Authority"));
2311 /* Leaf has common name "Asset Manifest Signing" */
2312 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
, CFSTR("OTA Task Signing"));
2314 require(result
= SecPolicyCreate(kSecPolicyAppleOTATasking
, kSecPolicyNameOTATasking
, options
),
2318 CFReleaseSafe(options
);
2322 SecPolicyRef
SecPolicyCreateMobileAsset(void)
2324 CFMutableDictionaryRef options
= NULL
;
2325 SecPolicyRef result
= NULL
;
2327 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2328 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2330 /* No expiration check */
2331 SecPolicyAddBasicCertOptions(options
);
2334 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameMobileAsset
), errOut
);
2336 /* Chain length of 3 */
2337 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2339 /* Intermediate has common name "Apple iPhone Certification Authority". */
2340 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2341 CFSTR("Apple iPhone Certification Authority"));
2343 /* Leaf has common name "Asset Manifest Signing" */
2344 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
, CFSTR("Asset Manifest Signing"));
2346 require(result
= SecPolicyCreate(kSecPolicyAppleMobileAsset
, kSecPolicyNameMobileAsset
, options
),
2350 CFReleaseSafe(options
);
2354 SecPolicyRef
SecPolicyCreateMobileAssetDevelopment(void) {
2355 CFMutableDictionaryRef options
= NULL
;
2356 SecPolicyRef result
= NULL
;
2358 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2359 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2361 /* No expiration check */
2362 SecPolicyAddBasicCertOptions(options
);
2365 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameMobileAsset
), errOut
);
2367 /* Chain length of 3 */
2368 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2370 /* Intermediate has the iPhone CA Marker extension */
2371 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.18"));
2373 /* Leaf has ProdQA Mobile Asset Marker extension */
2374 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.55.1"));
2376 require(result
= SecPolicyCreate(kSecPolicyAppleMobileAssetDevelopment
, kSecPolicyNameMobileAsset
, options
),
2380 CFReleaseSafe(options
);
2384 SecPolicyRef
SecPolicyCreateAppleIDAuthorityPolicy(void)
2386 SecPolicyRef result
= NULL
;
2387 CFMutableDictionaryRef options
= NULL
;
2388 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2389 &kCFTypeDictionaryKeyCallBacks
,
2390 &kCFTypeDictionaryValueCallBacks
), out
);
2392 //Leaf appears to be a SSL only cert, so policy should expand on that policy
2393 SecPolicyAddBasicX509Options(options
);
2395 // Apple CA anchored
2396 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameIDAuthority
), out
);
2398 // with the addition of the existence check of an extension with "Apple ID Sharing Certificate" oid (1.2.840.113635.100.4.7)
2399 // NOTE: this obviously intended to have gone into Extended Key Usage, but evidence of existing certs proves the contrary.
2400 add_leaf_marker(options
, &oidAppleExtendedKeyUsageAppleID
);
2402 // 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.
2403 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleID
);
2404 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleID2
);
2406 require(result
= SecPolicyCreate(kSecPolicyAppleIDAuthority
,
2407 kSecPolicyNameIDAuthority
, options
), out
);
2410 CFReleaseSafe(options
);
2414 SecPolicyRef
SecPolicyCreateMacAppStoreReceipt(void)
2416 SecPolicyRef result
= NULL
;
2417 CFMutableDictionaryRef options
= NULL
;
2418 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2419 &kCFTypeDictionaryKeyCallBacks
,
2420 &kCFTypeDictionaryValueCallBacks
), out
);
2422 SecPolicyAddBasicX509Options(options
);
2424 // Apple CA anchored
2425 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameMacAppStoreReceipt
), out
);
2427 // Chain length of 3
2428 require(SecPolicyAddChainLengthOptions(options
, 3), out
);
2430 // MacAppStoreReceipt policy OID
2431 add_certificate_policy_oid_string(options
, CFSTR("1.2.840.113635.100.5.6.1"));
2433 // Intermediate marker OID
2434 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.1"));
2437 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.11.1"));
2440 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
2442 require(result
= SecPolicyCreate(kSecPolicyMacAppStoreReceipt
,
2443 kSecPolicyNameMacAppStoreReceipt
, options
), out
);
2446 CFReleaseSafe(options
);
2451 static SecPolicyRef
_SecPolicyCreatePassbookCardSigner(CFStringRef cardIssuer
, CFStringRef teamIdentifier
, bool requireTeamID
)
2453 SecPolicyRef result
= NULL
;
2454 CFMutableDictionaryRef options
= NULL
;
2455 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2456 &kCFTypeDictionaryKeyCallBacks
,
2457 &kCFTypeDictionaryValueCallBacks
), out
);
2459 SecPolicyAddBasicX509Options(options
);
2460 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNamePassbookSigning
), out
);
2462 // Chain length of 3
2463 require(SecPolicyAddChainLengthOptions(options
, 3), out
);
2465 if (teamIdentifier
) {
2466 // If supplied, teamIdentifier must match subject OU field
2467 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectOrganizationalUnit
, teamIdentifier
);
2470 // If not supplied, and it was required, fail
2471 require(!requireTeamID
, out
);
2474 // Must be both push and 3rd party package signing
2475 add_leaf_marker_value(options
, &oidAppleInstallerPackagingSigningExternal
, cardIssuer
);
2477 // We should check that it also has push marker, but we don't support requiring both, only either.
2478 // add_independent_oid(options, kSecPolicyCheckLeafMarkerOid, &oidApplePushServiceClient);
2480 //WWDR Intermediate marker OID
2481 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.1"));
2483 // And Passbook signing eku
2484 add_eku(options
, &oidAppleExtendedKeyUsagePassbook
);
2486 require(result
= SecPolicyCreate(kSecPolicyApplePassbookSigning
,
2487 kSecPolicyNamePassbookSigning
, options
), out
);
2490 CFReleaseSafe(options
);
2494 SecPolicyRef
SecPolicyCreatePassbookCardSigner(CFStringRef cardIssuer
, CFStringRef teamIdentifier
)
2496 return _SecPolicyCreatePassbookCardSigner(cardIssuer
, teamIdentifier
, true);
2500 static SecPolicyRef
CreateMobileStoreSigner(Boolean forTest
)
2503 SecPolicyRef result
= NULL
;
2504 CFMutableDictionaryRef options
= NULL
;
2505 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2506 &kCFTypeDictionaryKeyCallBacks
,
2507 &kCFTypeDictionaryValueCallBacks
), errOut
);
2508 SecPolicyAddBasicX509Options(options
);
2509 require(SecPolicyAddAppleAnchorOptions(options
,
2510 ((forTest
) ? kSecPolicyNameTestMobileStore
:
2511 kSecPolicyNameMobileStore
)), errOut
);
2513 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2515 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2516 CFSTR("Apple System Integration 2 Certification Authority"));
2518 add_ku(options
, kSecKeyUsageDigitalSignature
);
2520 const DERItem
* pOID
= (forTest
) ? &oidApplePolicyMobileStoreProdQA
: &oidApplePolicyMobileStore
;
2522 add_certificate_policy_oid(options
, pOID
);
2524 require(result
= SecPolicyCreate((forTest
) ? kSecPolicyAppleTestMobileStore
: kSecPolicyAppleMobileStore
,
2525 (forTest
) ? kSecPolicyNameTestMobileStore
: kSecPolicyNameMobileStore
,
2529 CFReleaseSafe(options
);
2533 SecPolicyRef
SecPolicyCreateMobileStoreSigner(void)
2535 return CreateMobileStoreSigner(false);
2538 SecPolicyRef
SecPolicyCreateTestMobileStoreSigner(void)
2540 return CreateMobileStoreSigner(true);
2544 CF_RETURNS_RETAINED SecPolicyRef
SecPolicyCreateEscrowServiceSigner(void)
2546 SecPolicyRef result
= NULL
;
2547 CFMutableDictionaryRef options
= NULL
;
2548 CFArrayRef anArray
= NULL
;
2549 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2550 &kCFTypeDictionaryKeyCallBacks
,
2551 &kCFTypeDictionaryValueCallBacks
), errOut
);
2553 // X509, ignoring date validity
2554 SecPolicyAddBasicCertOptions(options
);
2557 add_ku(options
, kSecKeyUsageKeyEncipherment
);
2559 /* Leaf has marker OID with value that can't be pre-determined */
2560 add_element(options
, kSecPolicyCheckLeafMarkerOidWithoutValueCheck
, CFSTR("1.2.840.113635.100.6.23.1"));
2561 require(SecPolicyAddChainLengthOptions(options
, 2), errOut
);
2564 Boolean anchorAdded
= false;
2565 // Get the roots by calling the SecCertificateCopyEscrowRoots
2566 anArray
= SecCertificateCopyEscrowRoots(kSecCertificateProductionEscrowRoot
);
2567 CFIndex numRoots
= 0;
2568 if (NULL
== anArray
|| 0 == (numRoots
= CFArrayGetCount(anArray
)))
2573 for (CFIndex iCnt
= 0; iCnt
< numRoots
; iCnt
++)
2575 SecCertificateRef aCert
= (SecCertificateRef
)CFArrayGetValueAtIndex(anArray
, iCnt
);
2579 CFDataRef sha_data
= SecCertificateGetSHA1Digest(aCert
);
2580 if (NULL
!= sha_data
)
2582 const UInt8
* pSHAData
= CFDataGetBytePtr(sha_data
);
2583 if (NULL
!= pSHAData
)
2585 SecPolicyAddAnchorSHA1Options(options
, pSHAData
);
2591 CFReleaseNull(anArray
);
2599 require(result
= SecPolicyCreate(kSecPolicyAppleEscrowService
,
2600 kSecPolicyNameEscrowService
, options
), errOut
);
2603 CFReleaseSafe(anArray
);
2604 CFReleaseSafe(options
);
2608 CF_RETURNS_RETAINED SecPolicyRef
SecPolicyCreatePCSEscrowServiceSigner(void)
2610 SecPolicyRef result
= NULL
;
2611 CFMutableDictionaryRef options
= NULL
;
2612 CFArrayRef anArray
= NULL
;
2613 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2614 &kCFTypeDictionaryKeyCallBacks
,
2615 &kCFTypeDictionaryValueCallBacks
), errOut
);
2617 SecPolicyAddBasicX509Options(options
);
2620 add_ku(options
, kSecKeyUsageKeyEncipherment
);
2622 /* Leaf has marker OID with value that can't be pre-determined */
2623 add_element(options
, kSecPolicyCheckLeafMarkerOidWithoutValueCheck
, CFSTR("1.2.840.113635.100.6.23.1"));
2624 require(SecPolicyAddChainLengthOptions(options
, 2), errOut
);
2627 Boolean anchorAdded
= false;
2628 anArray
= SecCertificateCopyEscrowRoots(kSecCertificateProductionPCSEscrowRoot
);
2629 CFIndex numRoots
= 0;
2630 if (NULL
== anArray
|| 0 == (numRoots
= CFArrayGetCount(anArray
)))
2635 for (CFIndex iCnt
= 0; iCnt
< numRoots
; iCnt
++)
2637 SecCertificateRef aCert
= (SecCertificateRef
)CFArrayGetValueAtIndex(anArray
, iCnt
);
2641 CFDataRef sha_data
= SecCertificateGetSHA1Digest(aCert
);
2642 if (NULL
!= sha_data
)
2644 const UInt8
* pSHAData
= CFDataGetBytePtr(sha_data
);
2645 if (NULL
!= pSHAData
)
2647 SecPolicyAddAnchorSHA1Options(options
, pSHAData
);
2653 CFReleaseNull(anArray
);
2661 require(result
= SecPolicyCreate(kSecPolicyApplePCSEscrowService
,
2662 kSecPolicyNamePCSEscrowService
, options
), errOut
);
2665 CFReleaseSafe(anArray
);
2666 CFReleaseSafe(options
);
2670 static SecPolicyRef
CreateConfigurationProfileSigner(bool forTest
) {
2671 SecPolicyRef result
= NULL
;
2672 CFMutableDictionaryRef options
= NULL
;
2673 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2674 &kCFTypeDictionaryKeyCallBacks
,
2675 &kCFTypeDictionaryValueCallBacks
), errOut
);
2677 SecPolicyAddBasicX509Options(options
);
2678 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameProfileSigner
), errOut
);
2681 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2683 // Require the profile signing EKU
2684 const DERItem
* pOID
= (forTest
) ? &oidAppleExtendedKeyUsageQAProfileSigning
:&oidAppleExtendedKeyUsageProfileSigning
;
2685 add_eku(options
, pOID
);
2687 // Require the Apple Application Integration CA marker OID
2688 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.3"));
2690 require(result
= SecPolicyCreate((forTest
) ? kSecPolicyAppleQAProfileSigner
: kSecPolicyAppleProfileSigner
,
2691 (forTest
) ? kSecPolicyNameQAProfileSigner
: kSecPolicyNameProfileSigner
,
2695 CFReleaseSafe(options
);
2699 SecPolicyRef
SecPolicyCreateConfigurationProfileSigner(void)
2701 return CreateConfigurationProfileSigner(false);
2705 SecPolicyRef
SecPolicyCreateQAConfigurationProfileSigner(void)
2707 if (SecIsInternalRelease()) {
2708 return CreateConfigurationProfileSigner(true);
2710 return CreateConfigurationProfileSigner(false);
2714 SecPolicyRef
SecPolicyCreateOSXProvisioningProfileSigning(void)
2716 SecPolicyRef result
= NULL
;
2717 CFMutableDictionaryRef options
= NULL
;
2718 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2719 &kCFTypeDictionaryKeyCallBacks
,
2720 &kCFTypeDictionaryValueCallBacks
), errOut
);
2721 // Require valid chain from the Apple root
2722 SecPolicyAddBasicX509Options(options
);
2723 SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameOSXProvisioningProfileSigning
);
2725 // Require provisioning profile leaf marker OID (1.2.840.113635.100.4.11)
2726 add_leaf_marker(options
, &oidAppleCertExtOSXProvisioningProfileSigning
);
2728 // Require intermediate marker OID (1.2.840.113635.100.6.2.1)
2729 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleWWDR
);
2731 // Require key usage that allows signing
2732 add_ku(options
, kSecKeyUsageDigitalSignature
);
2734 // Ensure that revocation is checked (OCSP)
2735 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationOCSP
);
2737 require(result
= SecPolicyCreate(kSecPolicyAppleOSXProvisioningProfileSigning
,
2738 kSecPolicyNameOSXProvisioningProfileSigning
, options
), errOut
);
2741 CFReleaseSafe(options
);
2746 SecPolicyRef
SecPolicyCreateOTAPKISigner(void)
2748 SecPolicyRef result
= NULL
;
2749 CFMutableDictionaryRef options
= NULL
;
2750 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2751 &kCFTypeDictionaryKeyCallBacks
,
2752 &kCFTypeDictionaryValueCallBacks
), errOut
);
2753 SecPolicyAddBasicX509Options(options
);
2755 SecPolicyAddAnchorSHA1Options(options
, kApplePKISettingsAuthority
);
2756 require(SecPolicyAddChainLengthOptions(options
, 2), errOut
);
2758 require(result
= SecPolicyCreate(kSecPolicyAppleOTAPKISigner
,
2759 kSecPolicyNameOTAPKISigner
, options
), errOut
);
2762 CFReleaseSafe(options
);
2768 SecPolicyRef
SecPolicyCreateTestOTAPKISigner(void)
2770 /* Guard against use on production devices */
2771 if (!SecIsInternalRelease()) {
2772 return SecPolicyCreateOTAPKISigner();
2775 SecPolicyRef result
= NULL
;
2776 CFMutableDictionaryRef options
= NULL
;
2777 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2778 &kCFTypeDictionaryKeyCallBacks
,
2779 &kCFTypeDictionaryValueCallBacks
), errOut
);
2780 SecPolicyAddBasicX509Options(options
);
2782 SecPolicyAddAnchorSHA1Options(options
, kAppleTestPKISettingsAuthority
);
2783 require(SecPolicyAddChainLengthOptions(options
, 2), errOut
);
2785 require(result
= SecPolicyCreate(kSecPolicyAppleTestOTAPKISigner
,
2786 kSecPolicyNameTestOTAPKISigner
, options
), errOut
);
2789 CFReleaseSafe(options
);
2794 @function SecPolicyCreateAppleSMPEncryption
2795 @abstract Check for intermediate certificate 'Apple System Integration CA - G3' by name,
2796 and root certificate 'Apple Root CA - G3' by hash.
2797 Leaf cert must have Key Encipherment usage.
2798 Leaf cert must have Apple SMP Encryption marker OID (1.2.840.113635.100.6.30).
2799 Intermediate must have marker OID (1.2.840.113635.100.6.2.13).
2801 SecPolicyRef
SecPolicyCreateAppleSMPEncryption(void)
2803 SecPolicyRef result
= NULL
;
2804 CFMutableDictionaryRef options
= NULL
;
2805 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2806 &kCFTypeDictionaryKeyCallBacks
,
2807 &kCFTypeDictionaryValueCallBacks
), errOut
);
2808 SecPolicyAddBasicCertOptions(options
);
2810 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameSMPEncryption
),
2812 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2814 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2815 CFSTR("Apple System Integration CA - G3"));
2817 // Check that leaf has extension with "Apple SMP Encryption" oid (1.2.840.113635.100.6.30)
2818 add_leaf_marker(options
, &oidAppleCertExtAppleSMPEncryption
);
2820 // Check that intermediate has extension (1.2.840.113635.100.6.2.13)
2821 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleSystemIntgG3
);
2823 add_ku(options
, kSecKeyUsageKeyEncipherment
);
2825 // Ensure that revocation is checked (OCSP)
2826 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationOCSP
);
2828 require(result
= SecPolicyCreate(kSecPolicyAppleSMPEncryption
,
2829 kSecPolicyNameSMPEncryption
, options
), errOut
);
2832 CFReleaseSafe(options
);
2837 @function SecPolicyCreateTestAppleSMPEncryption
2838 @abstract Check for intermediate certificate 'Test Apple System Integration CA - ECC' by name,
2839 and root certificate 'Test Apple Root CA - ECC' by hash.
2840 Leaf cert must have Key Encipherment usage. Other checks TBD.
2842 SecPolicyRef
SecPolicyCreateTestAppleSMPEncryption(void)
2844 SecPolicyRef result
= NULL
;
2845 CFMutableDictionaryRef options
= NULL
;
2846 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2847 &kCFTypeDictionaryKeyCallBacks
,
2848 &kCFTypeDictionaryValueCallBacks
), errOut
);
2849 SecPolicyAddBasicCertOptions(options
);
2851 SecPolicyAddAnchorSHA1Options(options
, kTestAppleRootCA_ECC_SHA1
);
2852 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2854 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2855 CFSTR("Test Apple System Integration CA - ECC"));
2857 add_ku(options
, kSecKeyUsageKeyEncipherment
);
2859 // Ensure that revocation is checked (OCSP)
2860 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationOCSP
);
2862 require(result
= SecPolicyCreate(kSecPolicyAppleTestSMPEncryption
,
2863 kSecPolicyNameTestSMPEncryption
, options
), errOut
);
2866 CFReleaseSafe(options
);
2871 SecPolicyRef
SecPolicyCreateAppleIDValidationRecordSigningPolicy(void)
2873 SecPolicyRef result
= NULL
;
2874 CFMutableDictionaryRef options
= NULL
;
2875 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2876 &kCFTypeDictionaryKeyCallBacks
,
2877 &kCFTypeDictionaryValueCallBacks
), errOut
);
2879 //Leaf appears to be a SSL only cert, so policy should expand on that policy
2880 SecPolicyAddBasicX509Options(options
);
2882 // Apple CA anchored
2883 require(SecPolicyAddAppleAnchorOptions(options
,
2884 kSecPolicyNameIDValidationRecordSigning
),
2887 // Check for an extension with " Apple ID Validation Record Signing" oid (1.2.840.113635.100.6.25)
2888 add_leaf_marker(options
, &oidAppleCertExtensionAppleIDRecordValidationSigning
);
2890 // and validate that intermediate has extension
2891 // Application Integration Intermediate Certificate (1.2.840.113635.100.6.2.3)
2892 // and also validate that intermediate has extension
2893 // System Integration 2 Intermediate Certificate (1.2.840.113635.100.6.2.10)
2894 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleID
);
2895 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleSystemIntg2
);
2897 // Ensure that revocation is checked (OCSP)
2898 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationOCSP
);
2900 require(result
= SecPolicyCreate(kSecPolicyAppleIDValidationRecordSigning
,
2901 kSecPolicyNameIDValidationRecordSigning
, options
), errOut
);
2904 CFReleaseSafe(options
);
2909 @function SecPolicyCreateAppleServerAuthCommon
2910 @abstract Generic policy for server authentication Sub CAs
2912 Allows control for both if pinning is required at all and if UAT environments should be added
2913 to the trust policy.
2915 No pinning is for developer/QA that needs to use proxy to debug the protocol, while UAT
2916 environment is for QA/internal developer that have no need allow fake servers.
2918 Both the noPinning and UAT are gated on that you run on internal hardware.
2923 SecPolicyCreateAppleServerAuthCommon(CFStringRef hostname
,
2924 CFDictionaryRef __unused context
,
2925 CFStringRef policyOID
, CFStringRef service
,
2926 const DERItem
*leafMarkerOID
,
2927 const DERItem
*UATLeafMarkerOID
)
2929 CFMutableDictionaryRef appleAnchorOptions
= NULL
;
2930 CFMutableDictionaryRef options
= NULL
;
2931 SecPolicyRef result
= NULL
;
2932 CFDataRef oid
= NULL
, uatoid
= NULL
;
2934 options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0, &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
2935 require(options
, errOut
);
2937 SecPolicyAddBasicX509Options(options
);
2939 require(hostname
, errOut
);
2940 CFDictionaryAddValue(options
, kSecPolicyCheckSSLHostname
, hostname
);
2942 CFDictionaryAddValue(options
, kSecPolicyCheckBlackListedLeaf
, kCFBooleanTrue
);
2943 CFDictionaryAddValue(options
, kSecPolicyCheckGrayListedLeaf
, kCFBooleanTrue
);
2945 add_eku(options
, &oidExtendedKeyUsageServerAuth
);
2947 if (requireUATPinning(service
)) {
2950 * Require pinning to the Apple CA's.
2952 SecPolicyAddAppleAnchorOptions(options
, service
);
2954 /* old-style leaf marker OIDs */
2955 if (UATLeafMarkerOID
) {
2956 add_leaf_prod_qa_markers(options
, leafMarkerOID
, UATLeafMarkerOID
);
2958 add_leaf_marker(options
, leafMarkerOID
);
2961 /* new-style leaf marker OIDs */
2962 CFStringRef leafMarkerOIDStr
= NULL
, UATLeafMarkerOIDStr
= NULL
;
2963 leafMarkerOIDStr
= SecDERItemCopyOIDDecimalRepresentation(NULL
, leafMarkerOID
);
2964 if (UATLeafMarkerOID
) {
2965 UATLeafMarkerOIDStr
= SecDERItemCopyOIDDecimalRepresentation(NULL
, UATLeafMarkerOID
);
2968 if (leafMarkerOIDStr
&& UATLeafMarkerOIDStr
) {
2969 add_leaf_prod_qa_markers_value_string(options
,
2970 CFSTR("1.2.840.113635.100.6.48.1"), leafMarkerOIDStr
,
2971 CFSTR("1.2.840.113635.100.6.48.1"), UATLeafMarkerOIDStr
);
2972 } else if (leafMarkerOIDStr
) {
2973 add_leaf_marker_value_string(options
, CFSTR("1.2.840.113635.100.6.48.1"), leafMarkerOIDStr
);
2976 CFReleaseNull(leafMarkerOIDStr
);
2977 CFReleaseNull(UATLeafMarkerOIDStr
);
2979 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleServerAuthentication
);
2982 /* Check for weak hashes and keys */
2983 CFDictionaryAddValue(options
, kSecPolicyCheckSystemTrustedWeakHash
, kCFBooleanTrue
);
2984 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
2986 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
2988 result
= SecPolicyCreate(policyOID
, service
, options
);
2989 require(result
, errOut
);
2992 CFReleaseSafe(appleAnchorOptions
);
2993 CFReleaseSafe(options
);
2995 CFReleaseSafe(uatoid
);
3000 @function SecPolicyCreateAppleIDSService
3001 @abstract Ensure we're appropriately pinned to the IDS service (SSL + Apple restrictions)
3003 SecPolicyRef
SecPolicyCreateAppleIDSService(CFStringRef hostname
)
3005 SecPolicyRef result
= SecPolicyCreateSSL(true, hostname
);
3007 SecPolicySetOid(result
, kSecPolicyAppleIDSService
);
3008 SecPolicySetName(result
, kSecPolicyNameAppleIDSBag
);
3014 @function SecPolicyCreateAppleIDSService
3015 @abstract Ensure we're appropriately pinned to the IDS service (SSL + Apple restrictions)
3017 SecPolicyRef
SecPolicyCreateAppleIDSServiceContext(CFStringRef hostname
, CFDictionaryRef context
)
3019 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyAppleIDSServiceContext
,
3020 kSecPolicyNameAppleIDSService
,
3021 &oidAppleCertExtAppleServerAuthenticationIDSProd
,
3022 &oidAppleCertExtAppleServerAuthenticationIDSProdQA
);
3026 @function SecPolicyCreateAppleGSService
3027 @abstract Ensure we're appropriately pinned to the GS service
3029 SecPolicyRef
SecPolicyCreateAppleGSService(CFStringRef hostname
, CFDictionaryRef context
)
3031 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyAppleGSService
,
3032 kSecPolicyNameAppleGSService
,
3033 &oidAppleCertExtAppleServerAuthenticationGS
,
3038 @function SecPolicyCreateApplePushService
3039 @abstract Ensure we're appropriately pinned to the Push service (SSL + Apple restrictions)
3041 SecPolicyRef
SecPolicyCreateApplePushService(CFStringRef hostname
, CFDictionaryRef context
)
3043 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyApplePushService
,
3044 kSecPolicyNameApplePushService
,
3045 &oidAppleCertExtAppleServerAuthenticationAPNProd
,
3046 &oidAppleCertExtAppleServerAuthenticationAPNProdQA
);
3050 @function SecPolicyCreateApplePPQService
3051 @abstract Ensure we're appropriately pinned to the PPQ service (SSL + Apple restrictions)
3053 SecPolicyRef
SecPolicyCreateApplePPQService(CFStringRef hostname
, CFDictionaryRef context
)
3055 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyApplePPQService
,
3056 kSecPolicyNameApplePPQService
,
3057 &oidAppleCertExtAppleServerAuthenticationPPQProd
,
3058 &oidAppleCertExtAppleServerAuthenticationPPQProdQA
);
3062 @function SecPolicyCreateAppleAST2Service
3063 @abstract Ensure we're appropriately pinned to the AST2 Diagnostic service (SSL + Apple restrictions)
3065 SecPolicyRef
SecPolicyCreateAppleAST2Service(CFStringRef hostname
, CFDictionaryRef context
)
3067 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyAppleAST2DiagnosticsServerAuth
,
3068 kSecPolicyNameAppleAST2Service
,
3069 &oidAppleCertExtAST2DiagnosticsServerAuthProd
,
3070 &oidAppleCertExtAST2DiagnosticsServerAuthProdQA
);
3074 @function SecPolicyCreateAppleEscrowProxyService
3075 @abstract Ensure we're appropriately pinned to the iCloud Escrow Proxy service (SSL + Apple restrictions)
3077 SecPolicyRef
SecPolicyCreateAppleEscrowProxyService(CFStringRef hostname
, CFDictionaryRef context
)
3079 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyAppleEscrowProxyServerAuth
,
3080 kSecPolicyNameAppleEscrowProxyService
,
3081 &oidAppleCertExtEscrowProxyServerAuthProd
,
3082 &oidAppleCertExtEscrowProxyServerAuthProdQA
);
3085 /* subject:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA */
3086 /* SKID: C0:7A:98:68:8D:89:FB:AB:05:64:0C:11:7D:AA:7D:65:B8:CA:CC:4E */
3087 /* Not Before: May 21 04:00:00 2002 GMT, Not After : May 21 04:00:00 2022 GMT */
3088 /* Signature Algorithm: sha1WithRSAEncryption */
3089 unsigned char GeoTrust_Global_CA_sha256
[kSecPolicySHA256Size
] = {
3090 0xff, 0x85, 0x6a, 0x2d, 0x25, 0x1d, 0xcd, 0x88, 0xd3, 0x66, 0x56, 0xf4, 0x50, 0x12, 0x67, 0x98,
3091 0xcf, 0xab, 0xaa, 0xde, 0x40, 0x79, 0x9c, 0x72, 0x2d, 0xe4, 0xd2, 0xb5, 0xdb, 0x36, 0xa7, 0x3a
3094 static SecPolicyRef
SecPolicyCreateAppleGeoTrustServerAuthCommon(CFStringRef hostname
, CFStringRef policyOid
,
3095 CFStringRef policyName
,
3096 CFStringRef leafMarkerOid
,
3097 CFStringRef qaLeafMarkerOid
) {
3098 CFMutableDictionaryRef options
= NULL
;
3099 CFDataRef spkiDigest
= NULL
;
3100 SecPolicyRef result
= NULL
;
3102 require(options
= CFDictionaryCreateMutable(NULL
, 0, &kCFTypeDictionaryKeyCallBacks
,
3103 &kCFTypeDictionaryValueCallBacks
), errOut
);
3106 SecPolicyAddBasicX509Options(options
);
3108 require(hostname
, errOut
);
3109 CFDictionaryAddValue(options
, kSecPolicyCheckSSLHostname
, hostname
);
3111 add_eku(options
, &oidExtendedKeyUsageServerAuth
);
3114 if (requireUATPinning(policyName
)) {
3116 SecPolicyAddAnchorSHA256Options(options
, GeoTrust_Global_CA_sha256
);
3118 /* Issued to Apple Inc. in the US */
3119 add_element(options
, kSecPolicyCheckIntermediateCountry
, CFSTR("US"));
3120 add_element(options
, kSecPolicyCheckIntermediateOrganization
, CFSTR("Apple Inc."));
3122 require_action(SecPolicyAddChainLengthOptions(options
, 3), errOut
, CFReleaseNull(result
));
3124 /* Marker OIDs in both formats */
3125 if (qaLeafMarkerOid
) {
3126 add_leaf_prod_qa_markers_string(options
, leafMarkerOid
, qaLeafMarkerOid
);
3127 add_leaf_prod_qa_markers_value_string(options
,
3128 CFSTR("1.2.840.113635.100.6.48.1"), leafMarkerOid
,
3129 CFSTR("1.2.840.113635.100.6.48.1"), qaLeafMarkerOid
);
3131 add_leaf_marker_string(options
, leafMarkerOid
);
3132 add_leaf_marker_value_string(options
, CFSTR("1.2.840.113635.100.6.48.1"), leafMarkerOid
);
3136 /* Check for weak hashes */
3137 CFDictionaryAddValue(options
, kSecPolicyCheckSystemTrustedWeakHash
, kCFBooleanTrue
);
3138 CFDictionaryAddValue(options
, kSecPolicyCheckSystemTrustedWeakKey
, kCFBooleanTrue
);
3140 /* See <rdar://25344801> for more details */
3142 result
= SecPolicyCreate(policyOid
, policyName
, options
);
3145 CFReleaseSafe(options
);
3146 CFReleaseSafe(spkiDigest
);
3150 SecPolicyRef
SecPolicyCreateAppleCompatibilityEscrowProxyService(CFStringRef hostname
) {
3151 return SecPolicyCreateAppleGeoTrustServerAuthCommon(hostname
, kSecPolicyAppleEscrowProxyCompatibilityServerAuth
,
3152 kSecPolicyNameAppleEscrowProxyService
,
3153 CFSTR("1.2.840.113635.100.6.27.7.2"),
3154 CFSTR("1.2.840.113635.100.6.27.7.1"));
3158 @function SecPolicyCreateAppleFMiPService
3159 @abstract Ensure we're appropriately pinned to the Find My iPhone service (SSL + Apple restrictions)
3161 SecPolicyRef
SecPolicyCreateAppleFMiPService(CFStringRef hostname
, CFDictionaryRef context
)
3163 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyAppleFMiPServerAuth
,
3164 kSecPolicyNameAppleFMiPService
,
3165 &oidAppleCertExtFMiPServerAuthProd
,
3166 &oidAppleCertExtFMiPServerAuthProdQA
);
3170 /* should use verbatim copy, but since this is the deprecated way, don't care right now */
3171 static const UInt8 entrustSPKIL1C
[kSecPolicySHA256Size
] = {
3172 0x54, 0x5b, 0xf9, 0x35, 0xe9, 0xad, 0xa1, 0xda,
3173 0x11, 0x7e, 0xdc, 0x3c, 0x2a, 0xcb, 0xc5, 0x6f,
3174 0xc0, 0x28, 0x09, 0x6c, 0x0e, 0x24, 0xbe, 0x9b,
3175 0x38, 0x94, 0xbe, 0x52, 0x2d, 0x1b, 0x43, 0xde
3179 @function SecPolicyCreateApplePushServiceLegacy
3180 @abstract Ensure we're appropriately pinned to the Push service (via Entrust)
3182 SecPolicyRef
SecPolicyCreateApplePushServiceLegacy(CFStringRef hostname
)
3184 CFMutableDictionaryRef options
= NULL
;
3185 SecPolicyRef result
= NULL
;
3186 CFDataRef digest
= NULL
;
3188 digest
= CFDataCreateWithBytesNoCopy(kCFAllocatorDefault
, entrustSPKIL1C
, sizeof(entrustSPKIL1C
), kCFAllocatorNull
);
3189 require(digest
, errOut
);
3191 options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0, &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
3192 require(options
, errOut
);
3194 SecPolicyAddBasicX509Options(options
);
3196 CFDictionaryAddValue(options
, kSecPolicyCheckSSLHostname
, hostname
);
3198 CFDictionaryAddValue(options
, kSecPolicyCheckBlackListedLeaf
, kCFBooleanTrue
);
3199 CFDictionaryAddValue(options
, kSecPolicyCheckGrayListedLeaf
, kCFBooleanTrue
);
3201 CFDictionaryAddValue(options
, kSecPolicyCheckIntermediateSPKISHA256
, digest
);
3203 add_eku(options
, &oidExtendedKeyUsageServerAuth
);
3205 /* Check for weak hashes and keys */
3206 CFDictionaryAddValue(options
, kSecPolicyCheckSystemTrustedWeakHash
, kCFBooleanTrue
);
3207 CFDictionaryAddValue(options
, kSecPolicyCheckSystemTrustedWeakKey
, kCFBooleanTrue
);
3209 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
3211 result
= SecPolicyCreate(kSecPolicyAppleLegacyPushService
,
3212 kSecPolicyNameLegacyPushService
, options
);
3213 require(result
, errOut
);
3216 CFReleaseSafe(digest
);
3217 CFReleaseSafe(options
);
3222 @function SecPolicyCreateAppleMMCSService
3223 @abstract Ensure we're appropriately pinned to the IDS service (SSL + Apple restrictions)
3225 SecPolicyRef
SecPolicyCreateAppleMMCSService(CFStringRef hostname
, CFDictionaryRef context
)
3227 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyAppleMMCService
,
3228 kSecPolicyNameAppleMMCSService
,
3229 &oidAppleCertExtAppleServerAuthenticationMMCSProd
,
3230 &oidAppleCertExtAppleServerAuthenticationMMCSProdQA
);
3233 SecPolicyRef
SecPolicyCreateAppleCompatibilityMMCSService(CFStringRef hostname
) {
3234 return SecPolicyCreateAppleGeoTrustServerAuthCommon(hostname
, kSecPolicyAppleMMCSCompatibilityServerAuth
,
3235 kSecPolicyNameAppleMMCSService
,
3236 CFSTR("1.2.840.113635.100.6.27.11.2"),
3237 CFSTR("1.2.840.113635.100.6.27.11.1"));
3241 SecPolicyRef
SecPolicyCreateAppleiCloudSetupService(CFStringRef hostname
, CFDictionaryRef context
)
3243 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyAppleiCloudSetupServerAuth
,
3244 kSecPolicyNameAppleiCloudSetupService
,
3245 &oidAppleCertExtAppleServerAuthenticationiCloudSetupProd
,
3246 &oidAppleCertExtAppleServerAuthenticationiCloudSetupProdQA
);
3249 SecPolicyRef
SecPolicyCreateAppleCompatibilityiCloudSetupService(CFStringRef hostname
)
3251 return SecPolicyCreateAppleGeoTrustServerAuthCommon(hostname
, kSecPolicyAppleiCloudSetupCompatibilityServerAuth
,
3252 kSecPolicyNameAppleiCloudSetupService
,
3253 CFSTR("1.2.840.113635.100.6.27.15.2"),
3254 CFSTR("1.2.840.113635.100.6.27.15.1"));
3258 @function SecPolicyCreateAppleSSLService
3259 @abstract Ensure we're appropriately pinned to an Apple server (SSL + Apple restrictions)
3261 SecPolicyRef
SecPolicyCreateAppleSSLService(CFStringRef hostname
)
3263 // SSL server, pinned to an Apple intermediate
3264 SecPolicyRef policy
= SecPolicyCreateSSL(true, hostname
);
3265 CFMutableDictionaryRef options
= NULL
;
3266 require(policy
, errOut
);
3268 // change options for SSL policy evaluation
3269 require((options
=(CFMutableDictionaryRef
)policy
->_options
) != NULL
, errOut
);
3271 // Apple CA anchored
3272 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameServerAuthentication
), errOut
);
3274 // Check leaf for Apple Server Authentication marker oid (1.2.840.113635.100.6.27.1)
3275 add_leaf_marker(options
, &oidAppleCertExtAppleServerAuthentication
);
3277 // Check intermediate for Apple Server Authentication intermediate marker (1.2.840.113635.100.6.2.12)
3278 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleServerAuthentication
);
3280 /* Check for weak hashes */
3281 CFDictionaryAddValue(options
, kSecPolicyCheckSystemTrustedWeakHash
, kCFBooleanTrue
);
3282 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
3284 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
3286 SecPolicySetOid(policy
, kSecPolicyAppleServerAuthentication
);
3287 SecPolicySetName(policy
, kSecPolicyNameServerAuthentication
);
3292 CFReleaseSafe(options
);
3293 CFReleaseSafe(policy
);
3298 @function SecPolicyCreateApplePPQSigning
3299 @abstract Check for intermediate certificate 'Apple System Integration 2 Certification Authority' by name,
3301 Leaf cert must have Digital Signature usage.
3302 Leaf cert must have Apple PPQ Signing marker OID (1.2.840.113635.100.6.38.2).
3303 Intermediate must have marker OID (1.2.840.113635.100.6.2.10).
3305 SecPolicyRef
SecPolicyCreateApplePPQSigning(void)
3307 SecPolicyRef result
= NULL
;
3308 CFMutableDictionaryRef options
= NULL
;
3309 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3310 &kCFTypeDictionaryKeyCallBacks
,
3311 &kCFTypeDictionaryValueCallBacks
), errOut
);
3312 SecPolicyAddBasicCertOptions(options
);
3314 SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNamePPQSigning
);
3315 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3317 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
3318 CFSTR("Apple System Integration 2 Certification Authority"));
3320 // Check that leaf has extension with "Apple PPQ Signing" prod oid (1.2.840.113635.100.6.38.2)
3321 add_leaf_marker(options
, &oidAppleCertExtApplePPQSigningProd
);
3323 // Check that intermediate has extension (1.2.840.113635.100.6.2.10)
3324 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleSystemIntg2
);
3326 add_ku(options
, kSecKeyUsageDigitalSignature
);
3328 require(result
= SecPolicyCreate(kSecPolicyApplePPQSigning
,
3329 kSecPolicyNamePPQSigning
, options
), errOut
);
3332 CFReleaseSafe(options
);
3337 @function SecPolicyCreateTestApplePPQSigning
3338 @abstract Check for intermediate certificate 'Apple System Integration 2 Certification Authority' by name,
3340 Leaf cert must have Digital Signature usage.
3341 Leaf cert must have Apple PPQ Signing Test marker OID (1.2.840.113635.100.6.38.1).
3342 Intermediate must have marker OID (1.2.840.113635.100.6.2.10).
3344 SecPolicyRef
SecPolicyCreateTestApplePPQSigning(void)
3346 /* Guard against use of test policy on production devices */
3347 if (!SecIsInternalRelease()) {
3348 return SecPolicyCreateApplePPQSigning();
3351 SecPolicyRef result
= NULL
;
3352 CFMutableDictionaryRef options
= NULL
;
3353 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3354 &kCFTypeDictionaryKeyCallBacks
,
3355 &kCFTypeDictionaryValueCallBacks
), errOut
);
3356 SecPolicyAddBasicCertOptions(options
);
3358 SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameTestPPQSigning
);
3359 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3361 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
3362 CFSTR("Apple System Integration 2 Certification Authority"));
3364 // Check that leaf has extension with "Apple PPQ Signing" test oid (1.2.840.113635.100.6.38.1)
3365 add_leaf_marker(options
, &oidAppleCertExtApplePPQSigningProdQA
);
3367 // Check that intermediate has extension (1.2.840.113635.100.6.2.10)
3368 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleSystemIntg2
);
3370 add_ku(options
, kSecKeyUsageDigitalSignature
);
3372 require(result
= SecPolicyCreate(kSecPolicyAppleTestPPQSigning
,
3373 kSecPolicyNameTestPPQSigning
, options
), errOut
);
3376 CFReleaseSafe(options
);
3380 @function SecPolicyCreateAppleTimeStamping
3381 @abstract Check for RFC3161 timestamping EKU.
3383 SecPolicyRef
SecPolicyCreateAppleTimeStamping(void)
3385 SecPolicyRef result
= NULL
;
3386 CFMutableDictionaryRef options
= NULL
;
3387 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3388 &kCFTypeDictionaryKeyCallBacks
,
3389 &kCFTypeDictionaryValueCallBacks
), errOut
);
3391 SecPolicyAddBasicX509Options(options
);
3393 /* Require id-kp-timeStamping extendedKeyUsage to be present. */
3394 add_eku(options
, &oidExtendedKeyUsageTimeStamping
);
3396 require(result
= SecPolicyCreate(kSecPolicyAppleTimeStamping
,
3397 kSecPolicyNameTimeStamping
, options
), errOut
);
3400 CFReleaseSafe(options
);
3405 @function SecPolicyCreateApplePayIssuerEncryption
3406 @abstract Check for intermediate certificate 'Apple Worldwide Developer Relations CA - G2' by name,
3407 and ECC apple anchor.
3408 Leaf cert must have Key Encipherment and Key Agreement usage.
3409 Leaf cert must have Apple Pay Issuer Encryption marker OID (1.2.840.113635.100.6.39).
3411 SecPolicyRef
SecPolicyCreateApplePayIssuerEncryption(void)
3413 SecPolicyRef result
= NULL
;
3414 CFMutableDictionaryRef options
= NULL
;
3415 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3416 &kCFTypeDictionaryKeyCallBacks
,
3417 &kCFTypeDictionaryValueCallBacks
), errOut
);
3418 SecPolicyAddBasicCertOptions(options
);
3420 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNamePayIssuerEncryption
),
3422 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3424 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
3425 CFSTR("Apple Worldwide Developer Relations CA - G2"));
3427 // Check that leaf has extension with "Apple Pay Issuer Encryption" oid (1.2.840.113635.100.6.39)
3428 add_leaf_marker(options
, &oidAppleCertExtCryptoServicesExtEncryption
);
3430 add_ku(options
, kSecKeyUsageKeyEncipherment
);
3432 require(result
= SecPolicyCreate(kSecPolicyApplePayIssuerEncryption
,
3433 kSecPolicyNamePayIssuerEncryption
, options
), errOut
);
3436 CFReleaseSafe(options
);
3441 @function SecPolicyCreateAppleATVVPNProfileSigning
3442 @abstract Check for leaf marker OID 1.2.840.113635.100.6.43,
3443 intermediate marker OID 1.2.840.113635.100.6.2.10,
3444 chains to Apple Root CA, path length 3
3446 SecPolicyRef
SecPolicyCreateAppleATVVPNProfileSigning(void)
3448 SecPolicyRef result
= NULL
;
3449 CFMutableDictionaryRef options
= NULL
;
3450 CFMutableDictionaryRef appleAnchorOptions
= NULL
;
3451 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3452 &kCFTypeDictionaryKeyCallBacks
,
3453 &kCFTypeDictionaryValueCallBacks
), errOut
);
3455 SecPolicyAddBasicCertOptions(options
);
3457 // Require pinning to the Apple CAs (including test CA for internal releases)
3458 appleAnchorOptions
= CFDictionaryCreateMutableForCFTypes(NULL
);
3459 require(appleAnchorOptions
, errOut
);
3461 if (SecIsInternalRelease()) {
3462 CFDictionarySetValue(appleAnchorOptions
,
3463 kSecPolicyAppleAnchorIncludeTestRoots
, kCFBooleanTrue
);
3466 add_element(options
, kSecPolicyCheckAnchorApple
, appleAnchorOptions
);
3468 // Cert chain length 3
3469 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3471 // Check leaf for Apple ATV VPN Profile Signing OID (1.2.840.113635.100.6.43)
3472 add_leaf_marker(options
, &oidAppleCertExtATVVPNProfileSigning
);
3474 // Check intermediate for Apple System Integration 2 CA intermediate marker (1.2.840.113635.100.6.2.10)
3475 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleSystemIntg2
);
3477 // Ensure that revocation is checked (OCSP only)
3478 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationOCSP
);
3480 require(result
= SecPolicyCreate(kSecPolicyAppleATVVPNProfileSigning
,
3481 kSecPolicyNameATVVPNProfileSigning
, options
), errOut
);
3484 CFReleaseSafe(options
);
3485 CFReleaseSafe(appleAnchorOptions
);
3489 SecPolicyRef
SecPolicyCreateAppleHomeKitServerAuth(CFStringRef hostname
) {
3490 CFMutableDictionaryRef appleAnchorOptions
= NULL
;
3491 CFMutableDictionaryRef options
= NULL
;
3492 SecPolicyRef result
= NULL
;
3493 CFDataRef oid
= NULL
;
3495 options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0, &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
3496 require(options
, errOut
);
3498 SecPolicyAddBasicX509Options(options
);
3500 CFDictionaryAddValue(options
, kSecPolicyCheckSSLHostname
, hostname
);
3502 add_eku(options
, &oidExtendedKeyUsageServerAuth
);
3504 if (requireUATPinning(kSecPolicyNameAppleHomeKitService
)) {
3506 // Cert chain length 3
3507 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3509 // Apple anchors, allowing test anchors for internal release
3510 SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameAppleHomeKitService
);
3512 add_leaf_marker(options
, &oidAppleCertExtHomeKitServerAuth
);
3514 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleHomeKitServerCA
);
3517 /* Check for weak hashes */
3518 CFDictionaryAddValue(options
, kSecPolicyCheckSystemTrustedWeakHash
, kCFBooleanTrue
);
3519 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
3521 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
3523 result
= SecPolicyCreate(kSecPolicyAppleHomeKitServerAuth
,
3524 kSecPolicyNameAppleHomeKitService
, options
);
3525 require(result
, errOut
);
3528 CFReleaseSafe(appleAnchorOptions
);
3529 CFReleaseSafe(options
);
3534 SecPolicyRef
SecPolicyCreateAppleExternalDeveloper(void) {
3535 CFMutableDictionaryRef options
= NULL
;
3536 SecPolicyRef result
= NULL
;
3538 /* Create basic Apple pinned policy */
3539 require(result
= SecPolicyCreateApplePinned(kSecPolicyNameExternalDeveloper
,
3540 CFSTR("1.2.840.113635.100.6.2.1"), // WWDR Intermediate OID
3541 CFSTR("1.2.840.113635.100.6.1.2")), // "iPhone Developer" leaf OID
3544 require_action(options
= CFDictionaryCreateMutableCopy(NULL
, 0, result
->_options
), errOut
, CFReleaseNull(result
));
3546 /* Additional intermediate OIDs */
3547 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
,
3548 CFSTR("1.2.840.113635.100.6.2.6")); // "Developer ID" Intermediate OID
3550 /* Addtional leaf OIDS */
3551 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.4")); // "iPhone Distribution" leaf OID
3552 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.5")); // "Safari Developer" leaf OID
3553 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.7")); // "3rd Party Mac Developer Application" leaf OID
3554 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.8")); // "3rd Party Mac Developer Installer" leaf OID
3555 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.12")); // "Mac Developer" leaf OID
3556 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.13")); // "Developer ID Application" leaf OID
3557 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.14")); // "Developer ID Installer" leaf OID
3560 add_eku_string(options
, CFSTR("1.3.6.1.5.5.7.3.3")); // CodeSigning EKU
3561 add_eku_string(options
, CFSTR("1.2.840.113635.100.4.8")); // "Safari Developer" EKU
3562 add_eku_string(options
, CFSTR("1.2.840.113635.100.4.9")); // "3rd Party Mac Developer Installer" EKU
3563 add_eku_string(options
, CFSTR("1.2.840.113635.100.4.13")); // "Developer ID Installer" EKU
3565 CFReleaseSafe(result
->_options
);
3566 result
->_options
= CFRetainSafe(options
);
3568 SecPolicySetOid(result
, kSecPolicyAppleExternalDeveloper
);
3571 CFReleaseSafe(options
);
3575 /* This one is special because the intermediate has no marker OID */
3576 SecPolicyRef
SecPolicyCreateAppleSoftwareSigning(void) {
3577 CFMutableDictionaryRef options
= NULL
;
3578 CFDictionaryRef keySizes
= NULL
;
3579 CFNumberRef rsaSize
= NULL
, ecSize
= NULL
;
3580 SecPolicyRef result
= NULL
;
3582 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3583 &kCFTypeDictionaryKeyCallBacks
,
3584 &kCFTypeDictionaryValueCallBacks
), errOut
);
3586 SecPolicyAddBasicCertOptions(options
);
3588 /* Anchored to the Apple Roots */
3589 require_quiet(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameSoftwareSigning
),
3592 /* Exactly 3 certs in the chain */
3593 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3595 /* Intermediate Common Name matches */
3596 add_element(options
, kSecPolicyCheckIssuerCommonName
, CFSTR("Apple Code Signing Certification Authority"));
3598 /* Leaf marker OID matches */
3599 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.22"));
3601 /* Leaf has CodeSigning EKU */
3602 add_eku_string(options
, CFSTR("1.3.6.1.5.5.7.3.3"));
3604 /* Check revocation using any available method */
3605 add_element(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
3607 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
3608 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
3610 require(result
= SecPolicyCreate(kSecPolicyAppleSoftwareSigning
,
3611 kSecPolicyNameSoftwareSigning
, options
), errOut
);
3614 CFReleaseSafe(options
);
3615 CFReleaseSafe(keySizes
);
3616 CFReleaseSafe(rsaSize
);
3617 CFReleaseSafe(ecSize
);
3621 /* subject:/CN=SEP Root CA/O=Apple Inc./ST=California */
3622 /* SKID: 58:EF:D6:BE:C5:82:B0:54:CD:18:A6:84:AD:A2:F6:7B:7B:3A:7F:CF */
3623 /* Not Before: Jun 24 21:43:24 2014 GMT, Not After : Jun 24 21:43:24 2029 GMT */
3624 /* Signature Algorithm: ecdsa-with-SHA384 */
3625 const uint8_t SEPRootCA_SHA256
[kSecPolicySHA256Size
] = {
3626 0xd1, 0xdf, 0x82, 0x00, 0xf3, 0x89, 0x4e, 0xe9, 0x96, 0xf3, 0x77, 0xdf, 0x76, 0x3b, 0x0a, 0x16,
3627 0x8f, 0xd9, 0x6c, 0x58, 0xc0, 0x3e, 0xc9, 0xb0, 0x5f, 0xa5, 0x64, 0x79, 0xc0, 0xe8, 0xc9, 0xe7
3630 SecPolicyRef
SecPolicyCreateAppleUniqueDeviceCertificate(CFDataRef testRootHash
) {
3631 CFMutableDictionaryRef options
= NULL
;
3632 CFDictionaryRef keySizes
= NULL
;
3633 CFNumberRef ecSize
= NULL
;
3634 SecPolicyRef result
= NULL
;
3636 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3637 &kCFTypeDictionaryKeyCallBacks
,
3638 &kCFTypeDictionaryValueCallBacks
), errOut
);
3640 /* Device certificate should never expire */
3641 SecPolicyAddBasicCertOptions(options
);
3643 /* Anchored to the SEP Root CA. Allow alternative root for developers */
3644 require(SecPolicyAddAnchorSHA256Options(options
, SEPRootCA_SHA256
),errOut
);
3645 if (testRootHash
&& SecIsInternalRelease() && (kSecPolicySHA256Size
== CFDataGetLength(testRootHash
))) {
3646 add_element(options
, kSecPolicyCheckAnchorSHA256
, testRootHash
);
3649 /* Exactly 3 certs in the chain */
3650 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3652 /* Intermediate has marker OID with value */
3653 add_intermediate_marker_value_string(options
, CFSTR("1.2.840.113635.100.6.44"), CFSTR("ucrt"));
3655 /* Leaf has marker OID with varying value that can't be pre-determined */
3656 add_element(options
, kSecPolicyCheckLeafMarkerOidWithoutValueCheck
, CFSTR("1.2.840.113635.100.10.1"));
3658 /* RSA key sizes are disallowed. EC key sizes are P-256 or larger. */
3659 require(ecSize
= CFNumberCreateWithCFIndex(NULL
, 256), errOut
);
3660 require(keySizes
= CFDictionaryCreate(NULL
, (const void**)&kSecAttrKeyTypeEC
,
3661 (const void**)&ecSize
, 1,
3662 &kCFTypeDictionaryKeyCallBacks
,
3663 &kCFTypeDictionaryValueCallBacks
), errOut
);
3664 add_element(options
, kSecPolicyCheckKeySize
, keySizes
);
3667 require(result
= SecPolicyCreate(kSecPolicyAppleUniqueDeviceIdentifierCertificate
,
3668 kSecPolicyNameUniqueDeviceIdentifierCertificate
, options
), errOut
);
3671 CFReleaseSafe(options
);
3672 CFReleaseSafe(keySizes
);
3673 CFReleaseSafe(ecSize
);
3677 SecPolicyRef
SecPolicyCreateAppleWarsaw(void) {
3678 CFMutableDictionaryRef options
= NULL
;
3679 SecPolicyRef result
= NULL
;
3680 #if TARGET_OS_BRIDGE
3681 CFMutableDictionaryRef appleAnchorOptions
= NULL
;
3684 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3685 &kCFTypeDictionaryKeyCallBacks
,
3686 &kCFTypeDictionaryValueCallBacks
), errOut
);
3688 SecPolicyAddBasicX509Options(options
);
3690 /* Anchored to the Apple Roots. */
3691 require_quiet(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameWarsaw
),
3694 /* Exactly 3 certs in the chain */
3695 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3697 /* Intermediate marker OID matches input OID */
3698 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.14"));
3700 /* Leaf marker OID matches input OID */
3701 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.29"));
3703 /* Check revocation using any available method */
3704 add_element(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
3706 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
3707 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
3709 require(result
= SecPolicyCreate(kSecPolicyAppleWarsaw
,
3710 kSecPolicyNameWarsaw
, options
), errOut
);
3713 CFReleaseSafe(options
);
3717 SecPolicyRef
SecPolicyCreateAppleSecureIOStaticAsset(void) {
3718 CFMutableDictionaryRef options
= NULL
;
3719 SecPolicyRef result
= NULL
;
3720 #if TARGET_OS_BRIDGE
3721 CFMutableDictionaryRef appleAnchorOptions
= NULL
;
3724 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3725 &kCFTypeDictionaryKeyCallBacks
,
3726 &kCFTypeDictionaryValueCallBacks
), errOut
);
3728 /* This certificate cannot expire so that assets always load */
3729 SecPolicyAddBasicCertOptions(options
);
3731 /* Anchored to the Apple Roots. */
3732 #if TARGET_OS_BRIDGE
3733 /* On the bridge, test roots are gated in the trust and policy servers. */
3734 require_quiet(appleAnchorOptions
= CFDictionaryCreateMutableForCFTypes(NULL
), errOut
);
3735 CFDictionarySetValue(appleAnchorOptions
,
3736 kSecPolicyAppleAnchorIncludeTestRoots
, kCFBooleanTrue
);
3737 add_element(options
, kSecPolicyCheckAnchorApple
, appleAnchorOptions
);
3738 CFReleaseSafe(appleAnchorOptions
);
3740 require_quiet(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameSecureIOStaticAsset
),
3744 /* Exactly 3 certs in the chain */
3745 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3747 /* Intermediate marker OID matches ASI CA */
3748 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.10"));
3750 /* Leaf marker OID matches static IO OID */
3751 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.50"));
3753 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
3754 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
3756 require(result
= SecPolicyCreate(kSecPolicyAppleSecureIOStaticAsset
,
3757 kSecPolicyNameSecureIOStaticAsset
, options
), errOut
);
3760 CFReleaseSafe(options
);
3764 SecPolicyRef
SecPolicyCreateAppleAppTransportSecurity(void) {
3765 CFMutableDictionaryRef options
= NULL
;
3766 SecPolicyRef result
= NULL
;
3767 CFMutableSetRef disallowedHashes
= NULL
;
3769 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3770 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
3772 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
3773 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
3775 /* Hash algorithm is SHA-256 or better */
3776 require(disallowedHashes
= CFSetCreateMutable(NULL
, 5, &kCFTypeSetCallBacks
), errOut
);
3777 CFSetAddValue(disallowedHashes
, kSecSignatureDigestAlgorithmMD2
);
3778 CFSetAddValue(disallowedHashes
, kSecSignatureDigestAlgorithmMD4
);
3779 CFSetAddValue(disallowedHashes
, kSecSignatureDigestAlgorithmMD5
);
3780 CFSetAddValue(disallowedHashes
, kSecSignatureDigestAlgorithmSHA1
);
3781 CFSetAddValue(disallowedHashes
, kSecSignatureDigestAlgorithmSHA224
);
3783 add_element(options
, kSecPolicyCheckSignatureHashAlgorithms
, disallowedHashes
);
3785 require_quiet(result
= SecPolicyCreate(kSecPolicyAppleAppTransportSecurity
,
3786 kSecPolicyNameAppTransportSecurity
,
3790 CFReleaseSafe(options
);
3794 SecPolicyRef
SecPolicyCreateMobileSoftwareUpdate(void) {
3795 CFMutableDictionaryRef options
= NULL
;
3796 SecPolicyRef result
= NULL
;
3797 #if TARGET_OS_BRIDGE
3798 CFMutableDictionaryRef appleAnchorOptions
= NULL
;
3801 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3802 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
3804 /* No expiration check. */
3805 SecPolicyAddBasicCertOptions(options
);
3808 require_quiet(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameMobileSoftwareUpdate
),
3811 /* Exactly 3 certs in the chain */
3812 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3814 /* Intermediate marker OID is iPhone CA OID */
3815 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.18"));
3817 /* Leaf marker OID is either the prod MSU OID, or, on internal builds, the prodQA OID */
3818 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.57.2"));
3819 if (SecIsInternalRelease()) {
3820 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.57.1"));
3823 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
3824 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
3826 require(result
= SecPolicyCreate(kSecPolicyAppleMobileSoftwareUpdate
,
3827 kSecPolicyNameMobileSoftwareUpdate
, options
), errOut
);
3830 CFReleaseNull(options
);
3834 /* subject:/CN=Basic Attestation System Root CA/O=Apple Inc./ST=California */
3835 /* SKID: FE:D1:D1:C2:08:07:03:D5:B9:3C:34:B2:BB:FD:7C:3A:99:25:1B:8F */
3836 /* Not Before: Apr 20 00:22:09 2017 GMT, Not After : Mar 22 00:00:00 2032 GMT */
3837 /* Signature Algorithm: ecdsa-with-SHA384 */
3838 const uint8_t BASystemRootCA_SHA256
[kSecPolicySHA256Size
] = {
3839 0x10, 0xD3, 0xC8, 0x67, 0xF0, 0xAE, 0xFB, 0x24, 0x31, 0xA0, 0xA9, 0x7A, 0x88, 0x18, 0xBD, 0x64,
3840 0xF7, 0xF9, 0x0F, 0xFE, 0x11, 0x94, 0x48, 0x4F, 0xCA, 0x97, 0xF0, 0xF2, 0x9E, 0xCA, 0x00, 0x47
3843 /* subject:/CN=Basic Attestation User Root CA/O=Apple Inc./ST=California */
3844 /* SKID: 83:E5:A3:21:9E:B0:74:C3:F9:61:90:FD:97:4E:23:10:76:A4:A3:F2 */
3845 /* Not Before: Apr 19 21:41:56 2017 GMT, Not After : Mar 22 00:00:00 2032 GMT */
3846 /* Signature Algorithm: ecdsa-with-SHA384 */
3847 const uint8_t BAUserRootCA_SHA256
[kSecPolicySHA256Size
] = {
3848 0x03, 0x75, 0x1c, 0x80, 0xfc, 0xbe, 0x58, 0x19, 0xd1, 0x70, 0xd2, 0x67, 0xce, 0x1a, 0xd6, 0xd0,
3849 0x94, 0x40, 0x7c, 0x91, 0xd8, 0x73, 0xd7, 0xa6, 0x56, 0x2d, 0xe3, 0x66, 0x6d, 0x35, 0x94, 0xc6
3852 SecPolicyRef
SecPolicyCreateAppleBasicAttestationSystem(CFDataRef testRootHash
) {
3853 CFMutableDictionaryRef options
= NULL
;
3854 SecPolicyRef result
= NULL
;
3856 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3857 &kCFTypeDictionaryKeyCallBacks
,
3858 &kCFTypeDictionaryValueCallBacks
), errOut
);
3859 /* BAA certs expire */
3860 SecPolicyAddBasicX509Options(options
);
3862 /* Anchored to one of the Basic Attestation roots. Allow alternative root for developers */
3863 SecPolicyAddAnchorSHA256Options(options
, BASystemRootCA_SHA256
);
3864 if (testRootHash
&& SecIsInternalRelease() && (kSecPolicySHA256Size
== CFDataGetLength(testRootHash
))) {
3865 add_element(options
, kSecPolicyCheckAnchorSHA256
, testRootHash
);
3868 /* Exactly 3 certs in the chain */
3869 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3871 require(result
= SecPolicyCreate(kSecPolicyAppleBasicAttestationSystem
,
3872 kSecPolicyNameBasicAttestationSystem
, options
), errOut
);
3875 CFReleaseSafe(options
);
3879 SecPolicyRef
SecPolicyCreateAppleBasicAttestationUser(CFDataRef testRootHash
) {
3880 CFMutableDictionaryRef options
= NULL
;
3881 SecPolicyRef result
= NULL
;
3883 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3884 &kCFTypeDictionaryKeyCallBacks
,
3885 &kCFTypeDictionaryValueCallBacks
), errOut
);
3886 /* BAA certs expire */
3887 SecPolicyAddBasicX509Options(options
);
3889 /* Anchored to one of the Basic Attestation roots. Allow alternative root for developers */
3890 SecPolicyAddAnchorSHA256Options(options
, BAUserRootCA_SHA256
);
3891 if (testRootHash
&& SecIsInternalRelease() && (kSecPolicySHA256Size
== CFDataGetLength(testRootHash
))) {
3892 add_element(options
, kSecPolicyCheckAnchorSHA256
, testRootHash
);
3895 /* Exactly 3 certs in the chain */
3896 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3898 require(result
= SecPolicyCreate(kSecPolicyAppleBasicAttestationUser
,
3899 kSecPolicyNameBasicAttestationUser
, options
), errOut
);
3902 CFReleaseSafe(options
);
3906 SecPolicyRef
SecPolicyCreateiAPSWAuthWithExpiration(bool checkExpiration
) {
3907 CFMutableDictionaryRef options
= NULL
;
3908 SecPolicyRef result
= NULL
;
3910 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3911 &kCFTypeDictionaryKeyCallBacks
,
3912 &kCFTypeDictionaryValueCallBacks
), errOut
);
3914 /* iAP checks expiration on developement certs, but not on production certs */
3915 if (checkExpiration
) {
3916 SecPolicyAddBasicX509Options(options
);
3918 SecPolicyAddBasicCertOptions(options
);
3921 /* Exactly 2 certs in the chain */
3922 require(SecPolicyAddChainLengthOptions(options
, 2), errOut
);
3924 /* iAP SW Auth General Capabilities Extension present */
3925 add_element(options
, kSecPolicyCheckLeafMarkerOidWithoutValueCheck
, CFSTR("1.2.840.113635.100.6.59.1"));
3927 require(result
= SecPolicyCreate(kSecPolicyAppleiAPSWAuth
,
3928 kSecPolicyNameiAPSWAuth
, options
), errOut
);
3931 CFReleaseSafe(options
);
3935 SecPolicyRef
SecPolicyCreateiAPSWAuth(void) {
3936 /* By default, iAP SW Auth certs don't expire */
3937 return SecPolicyCreateiAPSWAuthWithExpiration(false);
3940 SecPolicyRef
SecPolicyCreateDemoDigitalCatalogSigning(void) {
3941 CFMutableDictionaryRef options
= NULL
;
3942 SecPolicyRef result
= NULL
;
3944 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3945 &kCFTypeDictionaryKeyCallBacks
,
3946 &kCFTypeDictionaryValueCallBacks
), errOut
);
3947 SecPolicyAddBasicX509Options(options
);
3949 /* Exactly 3 certs in the chain */
3950 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3952 /* Demo Signing Extension present in leaf */
3953 add_element(options
, kSecPolicyCheckLeafMarkerOid
, CFSTR("1.2.840.113635.100.6.60"));
3955 /* Issuer common name is "DemoUnit CA" */
3956 add_element(options
, kSecPolicyCheckIssuerCommonName
, CFSTR("DemoUnit CA"));
3958 require(result
= SecPolicyCreate(kSecPolicyAppleDemoDigitalCatalog
,
3959 kSecPolicyNameDemoDigitalCatalog
, options
), errOut
);
3962 CFReleaseSafe(options
);
3966 SecPolicyRef
SecPolicyCreateAppleAssetReceipt(void) {
3967 CFMutableDictionaryRef options
= NULL
;
3968 SecPolicyRef result
= NULL
;
3970 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3971 &kCFTypeDictionaryKeyCallBacks
,
3972 &kCFTypeDictionaryValueCallBacks
), errOut
);
3974 /* No expiration check. */
3975 SecPolicyAddBasicCertOptions(options
);
3978 require_quiet(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameAssetReceipt
), errOut
);
3980 /* Exactly 3 certs in the chain */
3981 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3983 /* Intermediate marker OID is Apple System Integration 2 CA */
3984 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.10"));
3986 /* Leaf marker OID is the Asset Receipt OID */
3987 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.61"));
3989 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
3990 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
3992 require(result
= SecPolicyCreate(kSecPolicyAppleAssetReceipt
,
3993 kSecPolicyNameAssetReceipt
, options
), errOut
);
3996 CFReleaseNull(options
);
4000 SecPolicyRef
SecPolicyCreateAppleDeveloperIDPlusTicket(void) {
4001 CFMutableDictionaryRef options
= NULL
;
4002 SecPolicyRef result
= NULL
;
4004 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
4005 &kCFTypeDictionaryKeyCallBacks
,
4006 &kCFTypeDictionaryValueCallBacks
), errOut
);
4008 /* No expiration check. */
4009 SecPolicyAddBasicCertOptions(options
);
4012 require_quiet(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameDeveloperIDPlusTicket
), errOut
);
4014 /* Exactly 3 certs in the chain */
4015 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
4017 /* Intermediate marker OID is Apple System Integration CA 4 */
4018 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.17"));
4020 /* Leaf marker OID is the Developer ID+ Ticket OID */
4021 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.30"));
4023 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
4024 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
4026 require(result
= SecPolicyCreate(kSecPolicyAppleDeveloperIDPlusTicket
,
4027 kSecPolicyNameDeveloperIDPlusTicket
, options
), errOut
);
4030 CFReleaseNull(options
);
4034 SecPolicyRef
SecPolicyCreateAppleFDRProvisioning(void) {
4035 CFMutableDictionaryRef options
= NULL
;
4036 SecPolicyRef result
= NULL
;
4038 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
4039 &kCFTypeDictionaryKeyCallBacks
,
4040 &kCFTypeDictionaryValueCallBacks
), errOut
);
4042 /* No expiration check. */
4043 SecPolicyAddBasicCertOptions(options
);
4045 require(result
= SecPolicyCreate(kSecPolicyAppleFDRProvisioning
,
4046 kSecPolicyNameFDRProvisioning
, options
), errOut
);
4048 CFReleaseNull(options
);