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
);
1355 #if !TARGET_OS_BRIDGE
1356 CFDictionaryAddValue(options
, kSecPolicyCheckSystemTrustedCTRequired
, kCFBooleanTrue
);
1360 set_ssl_ekus(options
, server
);
1362 require(result
= SecPolicyCreate(kSecPolicyAppleSSL
,
1363 server
? kSecPolicyNameSSLServer
: kSecPolicyNameSSLClient
,
1367 CFReleaseSafe(options
);
1368 return (SecPolicyRef _Nonnull
)result
;
1371 SecPolicyRef
SecPolicyCreateApplePinned(CFStringRef policyName
, CFStringRef intermediateMarkerOID
, CFStringRef leafMarkerOID
) {
1372 CFMutableDictionaryRef options
= NULL
;
1373 SecPolicyRef result
= NULL
;
1375 if (!policyName
|| !intermediateMarkerOID
|| !leafMarkerOID
) {
1379 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1380 &kCFTypeDictionaryKeyCallBacks
,
1381 &kCFTypeDictionaryValueCallBacks
), errOut
);
1383 SecPolicyAddBasicX509Options(options
);
1385 /* Anchored to the Apple Roots */
1386 require(SecPolicyAddAppleAnchorOptions(options
, policyName
), errOut
);
1388 /* Exactly 3 certs in the chain */
1389 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1391 /* Intermediate marker OID matches input OID */
1392 if (!isAppleOid(intermediateMarkerOID
)) {
1393 secwarning("creating an Apple pinning policy with a non-Apple OID: %@", intermediateMarkerOID
);
1395 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, intermediateMarkerOID
);
1397 /* Leaf marker OID matches input OID */
1398 if (!isAppleOid(leafMarkerOID
)) {
1399 secwarning("creating an Apple pinning policy with a non-Apple OID: %@", leafMarkerOID
);
1401 add_leaf_marker_string(options
, leafMarkerOID
);
1403 /* Check revocation using any available method */
1404 add_element(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
1406 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
1407 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
1409 /* Check for weak hashes */
1410 CFDictionaryAddValue(options
, kSecPolicyCheckSystemTrustedWeakHash
, kCFBooleanTrue
);
1411 require(result
= SecPolicyCreate(kSecPolicyAppleGenericApplePinned
,
1412 policyName
, options
), errOut
);
1415 CFReleaseSafe(options
);
1420 requireUATPinning(CFStringRef service
)
1422 bool pinningRequired
= true;
1424 if (SecIsInternalRelease()) {
1425 CFStringRef setting
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("AppleServerAuthenticationNoPinning%@"), service
);
1426 require(setting
, fail
);
1427 if(isCFPreferenceInSecurityDomain(setting
)) {
1428 pinningRequired
= false;
1430 secnotice("pinningQA", "could not disable pinning: %@ not true", setting
);
1434 if (!pinningRequired
) {
1438 if(isCFPreferenceInSecurityDomain(CFSTR("AppleServerAuthenticationNoPinning"))) {
1439 pinningRequired
= false;
1441 secnotice("pinningQA", "could not disable pinning: AppleServerAuthenticationNoPinning not true");
1444 secnotice("pinningQA", "could not disable pinning: not an internal release");
1447 return pinningRequired
;
1450 SecPolicyRef
SecPolicyCreateAppleSSLPinned(CFStringRef policyName
, CFStringRef hostname
,
1451 CFStringRef intermediateMarkerOID
, CFStringRef leafMarkerOID
) {
1452 CFMutableDictionaryRef options
= NULL
, appleAnchorOptions
= NULL
;
1453 SecPolicyRef result
= NULL
;
1455 if (!policyName
|| !hostname
|| !leafMarkerOID
) {
1459 if (requireUATPinning(policyName
)) {
1460 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1461 &kCFTypeDictionaryKeyCallBacks
,
1462 &kCFTypeDictionaryValueCallBacks
), errOut
);
1464 SecPolicyAddBasicX509Options(options
);
1466 /* Anchored to the Apple Roots */
1467 require(SecPolicyAddAppleAnchorOptions(options
, policyName
), errOut
);
1469 /* Exactly 3 certs in the chain */
1470 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1472 if (intermediateMarkerOID
) {
1473 /* Intermediate marker OID matches input OID */
1474 if (!isAppleOid(intermediateMarkerOID
)) {
1475 secwarning("creating an Apple pinning policy with a non-Apple OID: %@", intermediateMarkerOID
);
1477 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, intermediateMarkerOID
);
1479 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.12"));
1482 /* Leaf marker OID matches input OID */
1483 if (!isAppleOid(leafMarkerOID
)) {
1484 secwarning("creating an Apple pinning policy with a non-Apple OID: %@", leafMarkerOID
);
1486 add_leaf_marker_string(options
, leafMarkerOID
);
1488 /* New leaf marker OID format */
1489 add_leaf_marker_value_string(options
, CFSTR("1.2.840.113635.100.6.48.1"), leafMarkerOID
);
1491 /* ServerAuth EKU is in leaf cert */
1492 add_eku_string(options
, CFSTR("1.3.6.1.5.5.7.3.1"));
1494 /* Hostname is in leaf cert */
1495 add_element(options
, kSecPolicyCheckSSLHostname
, hostname
);
1497 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
1498 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
1500 /* Check for weak hashes */
1501 CFDictionaryAddValue(options
, kSecPolicyCheckSystemTrustedWeakHash
, kCFBooleanTrue
);
1503 /* Check revocation using any available method */
1504 add_element(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
1506 require(result
= SecPolicyCreate(kSecPolicyAppleGenericAppleSSLPinned
,
1507 policyName
, options
), errOut
);
1510 result
= SecPolicyCreateSSL(true, hostname
);
1511 SecPolicySetOid(result
, kSecPolicyAppleGenericAppleSSLPinned
);
1512 SecPolicySetName(result
, policyName
);
1516 CFReleaseSafe(options
);
1517 CFReleaseSafe(appleAnchorOptions
);
1521 SecPolicyRef
SecPolicyCreateiPhoneActivation(void) {
1522 CFMutableDictionaryRef options
= NULL
;
1523 SecPolicyRef result
= NULL
;
1525 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1526 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1528 SecPolicyAddBasicCertOptions(options
);
1531 CFDictionaryAddValue(options
, kSecPolicyCheckKeyUsage
,
1533 CFDictionaryAddValue(options
, kSecPolicyCheckExtendedKeyUsage
,
1537 /* Basic X.509 policy with the additional requirements that the chain
1538 length is 3, it's anchored at the AppleCA and the leaf certificate
1539 has issuer "Apple iPhone Certification Authority" and
1540 subject "Apple iPhone Activation" for the common name. */
1541 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
1542 CFSTR("Apple iPhone Certification Authority"));
1543 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
,
1544 CFSTR("Apple iPhone Activation"));
1546 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1547 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameiPhoneActivation
), errOut
);
1549 require(result
= SecPolicyCreate(kSecPolicyAppleiPhoneActivation
,
1550 kSecPolicyNameiPhoneActivation
, options
),
1554 CFReleaseSafe(options
);
1558 SecPolicyRef
SecPolicyCreateiPhoneDeviceCertificate(void) {
1559 CFMutableDictionaryRef options
= NULL
;
1560 SecPolicyRef result
= NULL
;
1562 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1563 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1565 SecPolicyAddBasicCertOptions(options
);
1568 CFDictionaryAddValue(options
, kSecPolicyCheckKeyUsage
,
1570 CFDictionaryAddValue(options
, kSecPolicyCheckExtendedKeyUsage
,
1574 /* Basic X.509 policy with the additional requirements that the chain
1575 length is 4, it's anchored at the AppleCA and the first intermediate
1576 has the subject "Apple iPhone Device CA". */
1577 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
1578 CFSTR("Apple iPhone Device CA"));
1580 require(SecPolicyAddChainLengthOptions(options
, 4), errOut
);
1581 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameiPhoneDeviceCertificate
), errOut
);
1583 require(result
= SecPolicyCreate(kSecPolicyAppleiPhoneDeviceCertificate
,
1584 kSecPolicyNameiPhoneDeviceCertificate
, options
),
1588 CFReleaseSafe(options
);
1592 SecPolicyRef
SecPolicyCreateFactoryDeviceCertificate(void) {
1593 CFMutableDictionaryRef options
= NULL
;
1594 SecPolicyRef result
= NULL
;
1596 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1597 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1599 SecPolicyAddBasicCertOptions(options
);
1602 CFDictionaryAddValue(options
, kSecPolicyCheckKeyUsage
,
1604 CFDictionaryAddValue(options
, kSecPolicyCheckExtendedKeyUsage
,
1608 /* Basic X.509 policy with the additional requirements that the chain
1609 is anchored at the factory device certificate issuer. */
1610 require(SecPolicyAddAnchorSHA1Options(options
, kFactoryDeviceCASHA1
), errOut
);
1612 require(result
= SecPolicyCreate(kSecPolicyAppleFactoryDeviceCertificate
,
1613 kSecPolicyNameFactoryDeviceCertificate
, options
),
1617 CFReleaseSafe(options
);
1621 SecPolicyRef
SecPolicyCreateiAP(void) {
1622 CFMutableDictionaryRef options
= NULL
;
1623 SecPolicyRef result
= NULL
;
1624 CFTimeZoneRef tz
= NULL
;
1625 CFDateRef date
= NULL
;
1627 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1628 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1630 SecPolicyAddBasicCertOptions(options
);
1632 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonNamePrefix
,
1635 date
= CFDateCreateForGregorianZuluDay(NULL
, 2006, 5, 31);
1636 CFDictionaryAddValue(options
, kSecPolicyCheckNotValidBefore
, date
);
1638 require(result
= SecPolicyCreate(kSecPolicyAppleiAP
,
1639 kSecPolicyNameiAP
, options
),
1643 CFReleaseSafe(date
);
1645 CFReleaseSafe(options
);
1649 SecPolicyRef
SecPolicyCreateiTunesStoreURLBag(void) {
1650 CFMutableDictionaryRef options
= NULL
;
1651 SecPolicyRef result
= NULL
;
1654 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1655 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1657 SecPolicyAddBasicCertOptions(options
);
1659 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectOrganization
,
1660 CFSTR("Apple Inc."));
1661 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
,
1662 CFSTR("iTunes Store URL Bag"));
1664 require(SecPolicyAddChainLengthOptions(options
, 2), errOut
);
1665 require(SecPolicyAddAnchorSHA1Options(options
, kITMSCASHA1
), errOut
);
1667 require(result
= SecPolicyCreate(kSecPolicyAppleiTunesStoreURLBag
,
1668 kSecPolicyNameiTunesStoreURLBag
, options
), errOut
);
1671 CFReleaseSafe(options
);
1675 SecPolicyRef
SecPolicyCreateEAP(Boolean server
, CFArrayRef trustedServerNames
) {
1676 CFMutableDictionaryRef options
= NULL
;
1677 SecPolicyRef result
= NULL
;
1679 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1680 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1682 SecPolicyAddBasicX509Options(options
);
1684 /* Since EAP is used to setup the network we don't want evaluation
1685 using this policy to access the network. */
1686 CFDictionaryAddValue(options
, kSecPolicyCheckNoNetworkAccess
,
1689 if (trustedServerNames
) {
1690 CFDictionaryAddValue(options
, kSecPolicyCheckEAPTrustedServerNames
, trustedServerNames
);
1694 /* Check for weak hashes */
1695 CFDictionaryAddValue(options
, kSecPolicyCheckSystemTrustedWeakHash
, kCFBooleanTrue
);
1696 CFDictionaryAddValue(options
, kSecPolicyCheckSystemTrustedWeakKey
, kCFBooleanTrue
);
1699 /* We need to check for EKU per rdar://22206018 */
1700 set_ssl_ekus(options
, server
);
1702 require(result
= SecPolicyCreate(kSecPolicyAppleEAP
,
1703 server
? kSecPolicyNameEAPServer
: kSecPolicyNameEAPClient
,
1707 CFReleaseSafe(options
);
1711 SecPolicyRef
SecPolicyCreateIPSec(Boolean server
, CFStringRef hostname
) {
1712 CFMutableDictionaryRef options
= NULL
;
1713 SecPolicyRef result
= NULL
;
1715 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1716 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1718 SecPolicyAddBasicX509Options(options
);
1721 CFDictionaryAddValue(options
, kSecPolicyCheckSSLHostname
, hostname
);
1724 /* Require oidExtendedKeyUsageIPSec if Extended Keyusage Extention is
1726 /* Per <rdar://problem/6843827> Cisco VPN Certificate compatibility issue.
1727 We don't check the EKU for IPSec certs for now. If we do add eku
1728 checking back in the future, we should probably also accept the
1730 ipsecEndSystem 1.3.6.1.5.5.7.3.5
1732 ipsecTunnel 1.3.6.1.5.5.7.3.6
1733 ipsecUser 1.3.6.1.5.5.7.3.7
1735 //add_eku(options, NULL); /* eku extension is optional */
1736 //add_eku(options, &oidAnyExtendedKeyUsage);
1737 //add_eku(options, &oidExtendedKeyUsageIPSec);
1739 require(result
= SecPolicyCreate(kSecPolicyAppleIPsec
,
1740 server
? kSecPolicyNameIPSecServer
: kSecPolicyNameIPSecClient
,
1744 CFReleaseSafe(options
);
1748 SecPolicyRef
SecPolicyCreateiPhoneApplicationSigning(void) {
1749 CFMutableDictionaryRef options
= NULL
;
1750 SecPolicyRef result
= NULL
;
1752 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1753 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1755 SecPolicyAddBasicCertOptions(options
);
1757 /* Anchored to the Apple Roots */
1758 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameiPhoneApplicationSigning
), errOut
);
1761 if (SecIsInternalRelease()) {
1762 /* Allow a prod hierarchy-signed test cert */
1763 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonNameTEST
,
1764 CFSTR("Apple iPhone OS Application Signing"));
1765 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.3.1"));
1768 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
,
1769 CFSTR("Apple iPhone OS Application Signing"));
1771 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.3"));
1773 add_eku(options
, NULL
); /* eku extension is optional */
1774 add_eku(options
, &oidAnyExtendedKeyUsage
);
1775 add_eku(options
, &oidExtendedKeyUsageCodeSigning
);
1777 /* Intermediate check */
1778 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
1779 CFSTR("Apple iPhone Certification Authority"));
1781 /* Chain length check */
1782 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1784 /* Skip networked revocation checks */
1785 CFDictionaryAddValue(options
, kSecPolicyCheckNoNetworkAccess
, kCFBooleanTrue
);
1787 require(result
= SecPolicyCreate(kSecPolicyAppleiPhoneApplicationSigning
,
1788 kSecPolicyNameiPhoneApplicationSigning
, options
),
1792 CFReleaseSafe(options
);
1796 SecPolicyRef
SecPolicyCreateiPhoneVPNApplicationSigning(void) {
1797 CFMutableDictionaryRef options
= NULL
;
1798 SecPolicyRef result
= NULL
;
1800 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1801 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1803 SecPolicyAddBasicCertOptions(options
);
1805 /* Anchored to the Apple Roots */
1806 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameiPhoneVPNApplicationSigning
), errOut
);
1809 if (SecIsInternalRelease()) {
1810 /* Allow a prod hierarchy-signed test cert */
1811 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonNameTEST
,
1812 CFSTR("Apple iPhone OS Application Signing"));
1813 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.6.1"));
1816 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
,
1817 CFSTR("Apple iPhone OS Application Signing"));
1819 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.6"));
1821 add_eku(options
, NULL
); /* eku extension is optional */
1822 add_eku(options
, &oidAnyExtendedKeyUsage
);
1823 add_eku(options
, &oidExtendedKeyUsageCodeSigning
);
1825 /* Intermediate check */
1826 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
1827 CFSTR("Apple iPhone Certification Authority"));
1829 /* Chain length check */
1830 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1832 /* Skip networked revocation checks */
1833 CFDictionaryAddValue(options
, kSecPolicyCheckNoNetworkAccess
, kCFBooleanTrue
);
1835 require(result
= SecPolicyCreate(kSecPolicyAppleiPhoneVPNApplicationSigning
,
1836 kSecPolicyNameiPhoneVPNApplicationSigning
, options
),
1840 CFReleaseSafe(options
);
1844 SecPolicyRef
SecPolicyCreateiPhoneProfileApplicationSigning(void) {
1845 CFMutableDictionaryRef options
= NULL
;
1846 SecPolicyRef result
= NULL
;
1848 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1849 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1851 SecPolicyAddBasicX509Options(options
); // With expiration checking
1854 require_quiet(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameiPhoneProfileApplicationSigning
),
1858 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1860 /* Leaf has CodeSigning EKU */
1861 add_eku_string(options
, CFSTR("1.3.6.1.5.5.7.3.3"));
1863 /* On iOS, the cert in the provisioning profile may be one of:
1864 leaf OID intermediate OID
1865 iPhone Developer <ADS>.6.1.2 <ADS>.6.2.1
1866 iPhone Distribution <ADS>.6.1.4 <ADS>.6.2.1
1867 TestFlight (Prod) <ADS>.6.1.25.1 <ADS>.6.2.1
1868 TestFlight (QA) <ADS>.6.1.25.2 <ADS>.6.2.1
1870 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.1"));
1871 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.2"));
1872 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.4"));
1873 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.25.1"));
1874 if (SecIsInternalRelease()) {
1875 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.25.2"));
1878 /* Revocation via any available method */
1879 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
1881 require(result
= SecPolicyCreate(kSecPolicyAppleiPhoneProfileApplicationSigning
,
1882 kSecPolicyNameiPhoneProfileApplicationSigning
,
1886 CFReleaseSafe(options
);
1890 SecPolicyRef
SecPolicyCreateMacOSProfileApplicationSigning(void) {
1891 CFMutableDictionaryRef options
= NULL
;
1892 SecPolicyRef result
= NULL
;
1894 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1895 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1897 SecPolicyAddBasicCertOptions(options
); // Without expiration checking
1900 require_quiet(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameiPhoneProfileApplicationSigning
),
1904 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1906 /* Leaf has CodeSigning EKU */
1907 add_eku_string(options
, CFSTR("1.3.6.1.5.5.7.3.3"));
1910 /* On macOS, the cert in the provisioning profile may be one of:
1911 leaf OID intermediate OID
1912 MAS Development <ADS>.6.1.12 <ADS>.6.2.1
1913 MAS Submission <ADS>.6.1.7 <ADS>.6.2.1
1914 Developer ID <ADS>.6.1.13 <ADS>.6.2.6
1915 B&I <ADS>.6.22 None - "Apple Code Signing Certification Authority"
1917 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.12"));
1918 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.7"));
1919 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.13"));
1920 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.22"));
1922 /* Revocation via any available method */
1923 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
1925 require(result
= SecPolicyCreate(kSecPolicyAppleMacOSProfileApplicationSigning
,
1926 kSecPolicyNameMacOSProfileApplicationSigning
,
1930 CFReleaseSafe(options
);
1934 SecPolicyRef
SecPolicyCreateiPhoneProvisioningProfileSigning(void) {
1935 CFMutableDictionaryRef options
= NULL
;
1936 SecPolicyRef result
= NULL
;
1938 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1939 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1941 SecPolicyAddBasicCertOptions(options
);
1943 /* Basic X.509 policy with the additional requirements that the chain
1944 length is 3, it's anchored at the AppleCA and the leaf certificate
1945 has issuer "Apple iPhone Certification Authority" and
1946 subject "Apple iPhone OS Provisioning Profile Signing" for the common name. */
1947 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
1948 CFSTR("Apple iPhone Certification Authority"));
1949 if (SecIsInternalRelease()) {
1950 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonNameTEST
,
1951 CFSTR("Apple iPhone OS Provisioning Profile Signing"));
1954 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
,
1955 CFSTR("Apple iPhone OS Provisioning Profile Signing"));
1958 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1959 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameiPhoneProvisioningProfileSigning
), errOut
);
1961 /* Skip networked revocation checks */
1962 CFDictionaryAddValue(options
, kSecPolicyCheckNoNetworkAccess
, kCFBooleanTrue
);
1964 require(result
= SecPolicyCreate(kSecPolicyAppleiPhoneProvisioningProfileSigning
,
1965 kSecPolicyNameiPhoneProvisioningProfileSigning
, options
),
1968 /* 1.2.840.113635.100.6.2.2.1, non-critical: DER:05:00 - provisioning profile */
1971 CFReleaseSafe(options
);
1975 SecPolicyRef
SecPolicyCreateAppleTVOSApplicationSigning(void) {
1976 CFMutableDictionaryRef options
= NULL
;
1977 SecPolicyRef result
= NULL
;
1978 CFDataRef atvProdOid
= NULL
;
1979 CFDataRef atvTestOid
= NULL
;
1980 CFArrayRef oids
= NULL
;
1982 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1983 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1985 SecPolicyAddBasicCertOptions(options
);
1987 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1989 require_quiet(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameTVOSApplicationSigning
),
1992 /* Check for intermediate: Apple Worldwide Developer Relations */
1993 /* 1.2.840.113635.100.6.2.1 */
1994 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleWWDR
);
1996 add_ku(options
, kSecKeyUsageDigitalSignature
);
1998 /* Check for prod or test AppleTV Application Signing OIDs */
1999 /* Prod: 1.2.840.113635.100.6.1.24 */
2000 /* ProdQA: 1.2.840.113635.100.6.1.24.1 */
2001 add_leaf_marker(options
, &oidAppleTVOSApplicationSigningProd
);
2002 add_leaf_marker(options
, &oidAppleTVOSApplicationSigningProdQA
);
2004 /* Skip networked revocation checks */
2005 CFDictionaryAddValue(options
, kSecPolicyCheckNoNetworkAccess
, kCFBooleanTrue
);
2007 require(result
= SecPolicyCreate(kSecPolicyAppleTVOSApplicationSigning
,
2008 kSecPolicyNameTVOSApplicationSigning
, options
),
2012 CFReleaseSafe(options
);
2013 CFReleaseSafe(oids
);
2014 CFReleaseSafe(atvProdOid
);
2015 CFReleaseSafe(atvTestOid
);
2019 SecPolicyRef
SecPolicyCreateOCSPSigner(void) {
2020 CFMutableDictionaryRef options
= NULL
;
2021 SecPolicyRef result
= NULL
;
2023 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2024 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2026 SecPolicyAddBasicX509Options(options
);
2028 /* Require id-kp-OCSPSigning extendedKeyUsage to be present, not optional. */
2029 add_eku(options
, &oidExtendedKeyUsageOCSPSigning
);
2031 require(result
= SecPolicyCreate(kSecPolicyAppleOCSPSigner
,
2032 kSecPolicyNameOCSPSigner
, options
), errOut
);
2035 CFReleaseSafe(options
);
2039 SecPolicyRef
SecPolicyCreateRevocation(CFOptionFlags revocationFlags
) {
2040 CFMutableDictionaryRef options
= NULL
;
2041 SecPolicyRef result
= NULL
;
2043 require(revocationFlags
!= 0, errOut
);
2045 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2046 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2048 if (revocationFlags
& kSecRevocationCheckIfTrusted
) {
2049 CFDictionaryAddValue(options
, kSecPolicyCheckRevocationIfTrusted
, kCFBooleanTrue
);
2050 /* Set method, but allow caller to override with later checks */
2051 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
2054 if (revocationFlags
& kSecRevocationOnlineCheck
) {
2055 CFDictionaryAddValue(options
, kSecPolicyCheckRevocationOnline
, kCFBooleanTrue
);
2056 /* Set method, but allow caller to override with later checks */
2057 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
2060 if (revocationFlags
& kSecRevocationOCSPMethod
&& revocationFlags
& kSecRevocationCRLMethod
) {
2061 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
2063 else if (revocationFlags
& kSecRevocationOCSPMethod
) {
2064 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationOCSP
);
2066 else if (revocationFlags
& kSecRevocationCRLMethod
) {
2067 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationCRL
);
2070 if (revocationFlags
& kSecRevocationRequirePositiveResponse
) {
2071 CFDictionaryAddValue(options
, kSecPolicyCheckRevocationResponseRequired
, kCFBooleanTrue
);
2074 if (revocationFlags
& kSecRevocationNetworkAccessDisabled
) {
2075 CFDictionaryAddValue(options
, kSecPolicyCheckNoNetworkAccess
, kCFBooleanTrue
);
2077 /* If the caller didn't explicitly disable network access, the revocation policy
2078 * should override any other policy's network setting.
2079 * In particular, pairing a revocation policy with BasicX509 should result in
2080 * allowing network access for revocation unless explicitly disabled.
2081 * Note that SecTrustSetNetworkFetchAllowed can override even this. */
2082 CFDictionaryAddValue(options
, kSecPolicyCheckNoNetworkAccess
, kCFBooleanFalse
);
2085 /* Only flag bits 0-6 are currently defined */
2086 require(((revocationFlags
>> 7) == 0), errOut
);
2088 require(result
= SecPolicyCreate(kSecPolicyAppleRevocation
,
2089 kSecPolicyNameRevocation
, options
), errOut
);
2092 CFReleaseSafe(options
);
2096 SecPolicyRef
SecPolicyCreateSMIME(CFIndex smimeUsage
, CFStringRef email
) {
2097 CFMutableDictionaryRef options
= NULL
;
2098 SecPolicyRef result
= NULL
;
2100 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2101 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2103 if (smimeUsage
& kSecIgnoreExpirationSMIMEUsage
) {
2104 SecPolicyAddBasicCertOptions(options
);
2106 SecPolicyAddBasicX509Options(options
);
2109 /* We call add_ku for each combination of bits we are willing to allow. */
2110 if (smimeUsage
& kSecSignSMIMEUsage
) {
2111 add_ku(options
, kSecKeyUsageUnspecified
);
2112 add_ku(options
, kSecKeyUsageDigitalSignature
);
2113 add_ku(options
, kSecKeyUsageNonRepudiation
);
2115 if (smimeUsage
& kSecKeyEncryptSMIMEUsage
) {
2116 add_ku(options
, kSecKeyUsageKeyEncipherment
);
2118 if (smimeUsage
& kSecDataEncryptSMIMEUsage
) {
2119 add_ku(options
, kSecKeyUsageDataEncipherment
);
2121 if (smimeUsage
& kSecKeyExchangeDecryptSMIMEUsage
) {
2122 add_ku(options
, kSecKeyUsageKeyAgreement
| kSecKeyUsageDecipherOnly
);
2124 if (smimeUsage
& kSecKeyExchangeEncryptSMIMEUsage
) {
2125 add_ku(options
, kSecKeyUsageKeyAgreement
| kSecKeyUsageEncipherOnly
);
2127 if (smimeUsage
& kSecKeyExchangeBothSMIMEUsage
) {
2128 add_ku(options
, kSecKeyUsageKeyAgreement
| kSecKeyUsageEncipherOnly
| kSecKeyUsageDecipherOnly
);
2132 CFDictionaryAddValue(options
, kSecPolicyCheckEmail
, email
);
2135 /* RFC 3850 paragraph 4.4.4
2137 If the extended key usage extension is present in the certificate
2138 then interpersonal message S/MIME receiving agents MUST check that it
2139 contains either the emailProtection or the anyExtendedKeyUsage OID as
2140 defined in [KEYM]. S/MIME uses other than interpersonal messaging
2141 MAY require the explicit presence of the extended key usage extension
2142 or other OIDs to be present in the extension or both.
2144 add_eku(options
, NULL
); /* eku extension is optional */
2145 add_eku(options
, &oidAnyExtendedKeyUsage
);
2146 add_eku(options
, &oidExtendedKeyUsageEmailProtection
);
2148 #if !TARGET_OS_IPHONE
2149 // Check revocation on OS X
2150 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
2153 require(result
= SecPolicyCreate(kSecPolicyAppleSMIME
, kSecPolicyNameSMIME
, options
), errOut
);
2156 CFReleaseSafe(options
);
2160 SecPolicyRef
SecPolicyCreateApplePackageSigning(void) {
2161 CFMutableDictionaryRef options
= NULL
;
2162 SecPolicyRef result
= NULL
;
2164 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2165 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2167 SecPolicyAddBasicCertOptions(options
);
2169 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2170 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNamePackageSigning
), errOut
);
2172 add_ku(options
, kSecKeyUsageDigitalSignature
);
2173 add_eku(options
, &oidExtendedKeyUsageCodeSigning
);
2175 require(result
= SecPolicyCreate(kSecPolicyApplePackageSigning
,
2176 kSecPolicyNamePackageSigning
, options
),
2180 CFReleaseSafe(options
);
2185 SecPolicyRef
SecPolicyCreateAppleSWUpdateSigning(void) {
2186 CFMutableDictionaryRef options
= NULL
;
2187 SecPolicyRef result
= NULL
;
2189 * OS X rules for this policy:
2190 * -- Must have one intermediate cert
2191 * -- intermediate must have basic constraints with path length 0
2192 * -- intermediate has CSSMOID_APPLE_EKU_CODE_SIGNING EKU
2193 * -- leaf cert has either CODE_SIGNING or CODE_SIGN_DEVELOPMENT EKU (the latter of
2194 * which triggers a CSSMERR_APPLETP_CODE_SIGN_DEVELOPMENT error)
2196 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2197 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2199 SecPolicyAddBasicX509Options(options
);
2201 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2202 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameSWUpdateSigning
), errOut
);
2204 add_eku(options
, &oidAppleExtendedKeyUsageCodeSigning
);
2205 add_oid(options
, kSecPolicyCheckIntermediateEKU
, &oidAppleExtendedKeyUsageCodeSigning
);
2207 require(result
= SecPolicyCreate(kSecPolicyAppleSWUpdateSigning
,
2208 kSecPolicyNameSWUpdateSigning
, options
),
2212 CFReleaseSafe(options
);
2217 SecPolicyRef
SecPolicyCreateCodeSigning(void) {
2218 CFMutableDictionaryRef options
= NULL
;
2219 SecPolicyRef result
= NULL
;
2221 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2222 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2224 SecPolicyAddBasicX509Options(options
);
2226 /* If the key usage extension is present, we accept it having either of
2228 add_ku(options
, kSecKeyUsageDigitalSignature
);
2229 add_ku(options
, kSecKeyUsageNonRepudiation
);
2231 /* We require an extended key usage extension with the codesigning
2232 eku purpose. (The Apple codesigning eku is not accepted here
2233 since it's valid only for SecPolicyCreateAppleSWUpdateSigning.) */
2234 add_eku(options
, &oidExtendedKeyUsageCodeSigning
);
2235 #if TARGET_OS_IPHONE
2236 /* Accept the 'any' eku on iOS only to match prior behavior.
2237 This may be further restricted in future releases. */
2238 add_eku(options
, &oidAnyExtendedKeyUsage
);
2241 require(result
= SecPolicyCreate(kSecPolicyAppleCodeSigning
,
2242 kSecPolicyNameCodeSigning
, options
),
2246 CFReleaseSafe(options
);
2250 /* Explicitly leave out empty subject/subjectaltname check */
2251 SecPolicyRef
SecPolicyCreateLockdownPairing(void) {
2252 CFMutableDictionaryRef options
= NULL
;
2253 SecPolicyRef result
= NULL
;
2255 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2256 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2257 //CFDictionaryAddValue(options, kSecPolicyCheckBasicCertificateProcessing,
2258 // kCFBooleanTrue); // Happens automatically in SecPVCPathChecks
2259 CFDictionaryAddValue(options
, kSecPolicyCheckCriticalExtensions
,
2261 CFDictionaryAddValue(options
, kSecPolicyCheckIdLinkage
,
2263 CFDictionaryAddValue(options
, kSecPolicyCheckBasicConstraints
,
2265 CFDictionaryAddValue(options
, kSecPolicyCheckWeakKeySize
, kCFBooleanTrue
);
2267 require(result
= SecPolicyCreate(kSecPolicyAppleLockdownPairing
,
2268 kSecPolicyNameLockdownPairing
, options
), errOut
);
2271 CFReleaseSafe(options
);
2275 SecPolicyRef
SecPolicyCreateURLBag(void) {
2276 CFMutableDictionaryRef options
= NULL
;
2277 SecPolicyRef result
= NULL
;
2279 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2280 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2282 SecPolicyAddBasicCertOptions(options
);
2284 add_eku(options
, &oidExtendedKeyUsageCodeSigning
);
2286 require(result
= SecPolicyCreate(kSecPolicyAppleURLBag
,
2287 kSecPolicyNameURLBag
, options
), errOut
);
2290 CFReleaseSafe(options
);
2294 SecPolicyRef
SecPolicyCreateOTATasking(void)
2296 CFMutableDictionaryRef options
= NULL
;
2297 SecPolicyRef result
= NULL
;
2299 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2300 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2302 SecPolicyAddBasicX509Options(options
);
2305 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameMobileAsset
), errOut
);
2307 /* Chain length of 3 */
2308 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2310 /* Intermediate has common name "Apple iPhone Certification Authority". */
2311 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2312 CFSTR("Apple iPhone Certification Authority"));
2314 /* Leaf has common name "Asset Manifest Signing" */
2315 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
, CFSTR("OTA Task Signing"));
2317 require(result
= SecPolicyCreate(kSecPolicyAppleOTATasking
, kSecPolicyNameOTATasking
, options
),
2321 CFReleaseSafe(options
);
2325 SecPolicyRef
SecPolicyCreateMobileAsset(void)
2327 CFMutableDictionaryRef options
= NULL
;
2328 SecPolicyRef result
= NULL
;
2330 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2331 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2333 /* No expiration check */
2334 SecPolicyAddBasicCertOptions(options
);
2337 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameMobileAsset
), errOut
);
2339 /* Chain length of 3 */
2340 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2342 /* Intermediate has common name "Apple iPhone Certification Authority". */
2343 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2344 CFSTR("Apple iPhone Certification Authority"));
2346 /* Leaf has common name "Asset Manifest Signing" */
2347 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
, CFSTR("Asset Manifest Signing"));
2349 require(result
= SecPolicyCreate(kSecPolicyAppleMobileAsset
, kSecPolicyNameMobileAsset
, options
),
2353 CFReleaseSafe(options
);
2357 SecPolicyRef
SecPolicyCreateMobileAssetDevelopment(void) {
2358 CFMutableDictionaryRef options
= NULL
;
2359 SecPolicyRef result
= NULL
;
2361 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2362 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2364 /* No expiration check */
2365 SecPolicyAddBasicCertOptions(options
);
2368 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameMobileAsset
), errOut
);
2370 /* Chain length of 3 */
2371 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2373 /* Intermediate has the iPhone CA Marker extension */
2374 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.18"));
2376 /* Leaf has ProdQA Mobile Asset Marker extension */
2377 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.55.1"));
2379 require(result
= SecPolicyCreate(kSecPolicyAppleMobileAssetDevelopment
, kSecPolicyNameMobileAsset
, options
),
2383 CFReleaseSafe(options
);
2387 SecPolicyRef
SecPolicyCreateAppleIDAuthorityPolicy(void)
2389 SecPolicyRef result
= NULL
;
2390 CFMutableDictionaryRef options
= NULL
;
2391 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2392 &kCFTypeDictionaryKeyCallBacks
,
2393 &kCFTypeDictionaryValueCallBacks
), out
);
2395 //Leaf appears to be a SSL only cert, so policy should expand on that policy
2396 SecPolicyAddBasicX509Options(options
);
2398 // Apple CA anchored
2399 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameIDAuthority
), out
);
2401 // with the addition of the existence check of an extension with "Apple ID Sharing Certificate" oid (1.2.840.113635.100.4.7)
2402 // NOTE: this obviously intended to have gone into Extended Key Usage, but evidence of existing certs proves the contrary.
2403 add_leaf_marker(options
, &oidAppleExtendedKeyUsageAppleID
);
2405 // 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.
2406 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleID
);
2407 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleID2
);
2409 require(result
= SecPolicyCreate(kSecPolicyAppleIDAuthority
,
2410 kSecPolicyNameIDAuthority
, options
), out
);
2413 CFReleaseSafe(options
);
2417 SecPolicyRef
SecPolicyCreateMacAppStoreReceipt(void)
2419 SecPolicyRef result
= NULL
;
2420 CFMutableDictionaryRef options
= NULL
;
2421 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2422 &kCFTypeDictionaryKeyCallBacks
,
2423 &kCFTypeDictionaryValueCallBacks
), out
);
2425 SecPolicyAddBasicX509Options(options
);
2427 // Apple CA anchored
2428 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameMacAppStoreReceipt
), out
);
2430 // Chain length of 3
2431 require(SecPolicyAddChainLengthOptions(options
, 3), out
);
2433 // MacAppStoreReceipt policy OID
2434 add_certificate_policy_oid_string(options
, CFSTR("1.2.840.113635.100.5.6.1"));
2436 // Intermediate marker OID
2437 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.1"));
2440 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.11.1"));
2443 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
2445 require(result
= SecPolicyCreate(kSecPolicyMacAppStoreReceipt
,
2446 kSecPolicyNameMacAppStoreReceipt
, options
), out
);
2449 CFReleaseSafe(options
);
2454 static SecPolicyRef
_SecPolicyCreatePassbookCardSigner(CFStringRef cardIssuer
, CFStringRef teamIdentifier
, bool requireTeamID
)
2456 SecPolicyRef result
= NULL
;
2457 CFMutableDictionaryRef options
= NULL
;
2458 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2459 &kCFTypeDictionaryKeyCallBacks
,
2460 &kCFTypeDictionaryValueCallBacks
), out
);
2462 SecPolicyAddBasicX509Options(options
);
2463 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNamePassbookSigning
), out
);
2465 // Chain length of 3
2466 require(SecPolicyAddChainLengthOptions(options
, 3), out
);
2468 if (teamIdentifier
) {
2469 // If supplied, teamIdentifier must match subject OU field
2470 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectOrganizationalUnit
, teamIdentifier
);
2473 // If not supplied, and it was required, fail
2474 require(!requireTeamID
, out
);
2477 // Must be both push and 3rd party package signing
2478 add_leaf_marker_value(options
, &oidAppleInstallerPackagingSigningExternal
, cardIssuer
);
2480 // We should check that it also has push marker, but we don't support requiring both, only either.
2481 // add_independent_oid(options, kSecPolicyCheckLeafMarkerOid, &oidApplePushServiceClient);
2483 //WWDR Intermediate marker OID
2484 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.1"));
2486 // And Passbook signing eku
2487 add_eku(options
, &oidAppleExtendedKeyUsagePassbook
);
2489 require(result
= SecPolicyCreate(kSecPolicyApplePassbookSigning
,
2490 kSecPolicyNamePassbookSigning
, options
), out
);
2493 CFReleaseSafe(options
);
2497 SecPolicyRef
SecPolicyCreatePassbookCardSigner(CFStringRef cardIssuer
, CFStringRef teamIdentifier
)
2499 return _SecPolicyCreatePassbookCardSigner(cardIssuer
, teamIdentifier
, true);
2503 static SecPolicyRef
CreateMobileStoreSigner(Boolean forTest
)
2506 SecPolicyRef result
= NULL
;
2507 CFMutableDictionaryRef options
= NULL
;
2508 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2509 &kCFTypeDictionaryKeyCallBacks
,
2510 &kCFTypeDictionaryValueCallBacks
), errOut
);
2511 SecPolicyAddBasicX509Options(options
);
2512 require(SecPolicyAddAppleAnchorOptions(options
,
2513 ((forTest
) ? kSecPolicyNameTestMobileStore
:
2514 kSecPolicyNameMobileStore
)), errOut
);
2516 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2518 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2519 CFSTR("Apple System Integration 2 Certification Authority"));
2521 add_ku(options
, kSecKeyUsageDigitalSignature
);
2523 const DERItem
* pOID
= (forTest
) ? &oidApplePolicyMobileStoreProdQA
: &oidApplePolicyMobileStore
;
2525 add_certificate_policy_oid(options
, pOID
);
2527 require(result
= SecPolicyCreate((forTest
) ? kSecPolicyAppleTestMobileStore
: kSecPolicyAppleMobileStore
,
2528 (forTest
) ? kSecPolicyNameTestMobileStore
: kSecPolicyNameMobileStore
,
2532 CFReleaseSafe(options
);
2536 SecPolicyRef
SecPolicyCreateMobileStoreSigner(void)
2538 return CreateMobileStoreSigner(false);
2541 SecPolicyRef
SecPolicyCreateTestMobileStoreSigner(void)
2543 return CreateMobileStoreSigner(true);
2547 CF_RETURNS_RETAINED SecPolicyRef
SecPolicyCreateEscrowServiceSigner(void)
2549 SecPolicyRef result
= NULL
;
2550 CFMutableDictionaryRef options
= NULL
;
2551 CFArrayRef anArray
= NULL
;
2552 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2553 &kCFTypeDictionaryKeyCallBacks
,
2554 &kCFTypeDictionaryValueCallBacks
), errOut
);
2556 // X509, ignoring date validity
2557 SecPolicyAddBasicCertOptions(options
);
2560 add_ku(options
, kSecKeyUsageKeyEncipherment
);
2562 /* Leaf has marker OID with value that can't be pre-determined */
2563 add_element(options
, kSecPolicyCheckLeafMarkerOidWithoutValueCheck
, CFSTR("1.2.840.113635.100.6.23.1"));
2564 require(SecPolicyAddChainLengthOptions(options
, 2), errOut
);
2567 Boolean anchorAdded
= false;
2568 // Get the roots by calling the SecCertificateCopyEscrowRoots
2569 anArray
= SecCertificateCopyEscrowRoots(kSecCertificateProductionEscrowRoot
);
2570 CFIndex numRoots
= 0;
2571 if (NULL
== anArray
|| 0 == (numRoots
= CFArrayGetCount(anArray
)))
2576 for (CFIndex iCnt
= 0; iCnt
< numRoots
; iCnt
++)
2578 SecCertificateRef aCert
= (SecCertificateRef
)CFArrayGetValueAtIndex(anArray
, iCnt
);
2582 CFDataRef sha_data
= SecCertificateGetSHA1Digest(aCert
);
2583 if (NULL
!= sha_data
)
2585 const UInt8
* pSHAData
= CFDataGetBytePtr(sha_data
);
2586 if (NULL
!= pSHAData
)
2588 SecPolicyAddAnchorSHA1Options(options
, pSHAData
);
2594 CFReleaseNull(anArray
);
2602 require(result
= SecPolicyCreate(kSecPolicyAppleEscrowService
,
2603 kSecPolicyNameEscrowService
, options
), errOut
);
2606 CFReleaseSafe(anArray
);
2607 CFReleaseSafe(options
);
2611 CF_RETURNS_RETAINED SecPolicyRef
SecPolicyCreatePCSEscrowServiceSigner(void)
2613 SecPolicyRef result
= NULL
;
2614 CFMutableDictionaryRef options
= NULL
;
2615 CFArrayRef anArray
= NULL
;
2616 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2617 &kCFTypeDictionaryKeyCallBacks
,
2618 &kCFTypeDictionaryValueCallBacks
), errOut
);
2620 SecPolicyAddBasicX509Options(options
);
2623 add_ku(options
, kSecKeyUsageKeyEncipherment
);
2625 /* Leaf has marker OID with value that can't be pre-determined */
2626 add_element(options
, kSecPolicyCheckLeafMarkerOidWithoutValueCheck
, CFSTR("1.2.840.113635.100.6.23.1"));
2627 require(SecPolicyAddChainLengthOptions(options
, 2), errOut
);
2630 Boolean anchorAdded
= false;
2631 anArray
= SecCertificateCopyEscrowRoots(kSecCertificateProductionPCSEscrowRoot
);
2632 CFIndex numRoots
= 0;
2633 if (NULL
== anArray
|| 0 == (numRoots
= CFArrayGetCount(anArray
)))
2638 for (CFIndex iCnt
= 0; iCnt
< numRoots
; iCnt
++)
2640 SecCertificateRef aCert
= (SecCertificateRef
)CFArrayGetValueAtIndex(anArray
, iCnt
);
2644 CFDataRef sha_data
= SecCertificateGetSHA1Digest(aCert
);
2645 if (NULL
!= sha_data
)
2647 const UInt8
* pSHAData
= CFDataGetBytePtr(sha_data
);
2648 if (NULL
!= pSHAData
)
2650 SecPolicyAddAnchorSHA1Options(options
, pSHAData
);
2656 CFReleaseNull(anArray
);
2664 require(result
= SecPolicyCreate(kSecPolicyApplePCSEscrowService
,
2665 kSecPolicyNamePCSEscrowService
, options
), errOut
);
2668 CFReleaseSafe(anArray
);
2669 CFReleaseSafe(options
);
2673 static SecPolicyRef
CreateConfigurationProfileSigner(bool forTest
) {
2674 SecPolicyRef result
= NULL
;
2675 CFMutableDictionaryRef options
= NULL
;
2676 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2677 &kCFTypeDictionaryKeyCallBacks
,
2678 &kCFTypeDictionaryValueCallBacks
), errOut
);
2680 SecPolicyAddBasicX509Options(options
);
2681 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameProfileSigner
), errOut
);
2684 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2686 // Require the profile signing EKU
2687 const DERItem
* pOID
= (forTest
) ? &oidAppleExtendedKeyUsageQAProfileSigning
:&oidAppleExtendedKeyUsageProfileSigning
;
2688 add_eku(options
, pOID
);
2690 // Require the Apple Application Integration CA marker OID
2691 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.3"));
2693 require(result
= SecPolicyCreate((forTest
) ? kSecPolicyAppleQAProfileSigner
: kSecPolicyAppleProfileSigner
,
2694 (forTest
) ? kSecPolicyNameQAProfileSigner
: kSecPolicyNameProfileSigner
,
2698 CFReleaseSafe(options
);
2702 SecPolicyRef
SecPolicyCreateConfigurationProfileSigner(void)
2704 return CreateConfigurationProfileSigner(false);
2708 SecPolicyRef
SecPolicyCreateQAConfigurationProfileSigner(void)
2710 if (SecIsInternalRelease()) {
2711 return CreateConfigurationProfileSigner(true);
2713 return CreateConfigurationProfileSigner(false);
2717 SecPolicyRef
SecPolicyCreateOSXProvisioningProfileSigning(void)
2719 SecPolicyRef result
= NULL
;
2720 CFMutableDictionaryRef options
= NULL
;
2721 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2722 &kCFTypeDictionaryKeyCallBacks
,
2723 &kCFTypeDictionaryValueCallBacks
), errOut
);
2724 // Require valid chain from the Apple root
2725 SecPolicyAddBasicX509Options(options
);
2726 SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameOSXProvisioningProfileSigning
);
2728 // Require provisioning profile leaf marker OID (1.2.840.113635.100.4.11)
2729 add_leaf_marker(options
, &oidAppleCertExtOSXProvisioningProfileSigning
);
2731 // Require intermediate marker OID (1.2.840.113635.100.6.2.1)
2732 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleWWDR
);
2734 // Require key usage that allows signing
2735 add_ku(options
, kSecKeyUsageDigitalSignature
);
2737 // Ensure that revocation is checked (OCSP)
2738 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationOCSP
);
2740 require(result
= SecPolicyCreate(kSecPolicyAppleOSXProvisioningProfileSigning
,
2741 kSecPolicyNameOSXProvisioningProfileSigning
, options
), errOut
);
2744 CFReleaseSafe(options
);
2749 SecPolicyRef
SecPolicyCreateOTAPKISigner(void)
2751 SecPolicyRef result
= NULL
;
2752 CFMutableDictionaryRef options
= NULL
;
2753 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2754 &kCFTypeDictionaryKeyCallBacks
,
2755 &kCFTypeDictionaryValueCallBacks
), errOut
);
2756 SecPolicyAddBasicX509Options(options
);
2758 SecPolicyAddAnchorSHA1Options(options
, kApplePKISettingsAuthority
);
2759 require(SecPolicyAddChainLengthOptions(options
, 2), errOut
);
2761 require(result
= SecPolicyCreate(kSecPolicyAppleOTAPKISigner
,
2762 kSecPolicyNameOTAPKISigner
, options
), errOut
);
2765 CFReleaseSafe(options
);
2771 SecPolicyRef
SecPolicyCreateTestOTAPKISigner(void)
2773 /* Guard against use on production devices */
2774 if (!SecIsInternalRelease()) {
2775 return SecPolicyCreateOTAPKISigner();
2778 SecPolicyRef result
= NULL
;
2779 CFMutableDictionaryRef options
= NULL
;
2780 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2781 &kCFTypeDictionaryKeyCallBacks
,
2782 &kCFTypeDictionaryValueCallBacks
), errOut
);
2783 SecPolicyAddBasicX509Options(options
);
2785 SecPolicyAddAnchorSHA1Options(options
, kAppleTestPKISettingsAuthority
);
2786 require(SecPolicyAddChainLengthOptions(options
, 2), errOut
);
2788 require(result
= SecPolicyCreate(kSecPolicyAppleTestOTAPKISigner
,
2789 kSecPolicyNameTestOTAPKISigner
, options
), errOut
);
2792 CFReleaseSafe(options
);
2797 @function SecPolicyCreateAppleSMPEncryption
2798 @abstract Check for intermediate certificate 'Apple System Integration CA - G3' by name,
2799 and root certificate 'Apple Root CA - G3' by hash.
2800 Leaf cert must have Key Encipherment usage.
2801 Leaf cert must have Apple SMP Encryption marker OID (1.2.840.113635.100.6.30).
2802 Intermediate must have marker OID (1.2.840.113635.100.6.2.13).
2804 SecPolicyRef
SecPolicyCreateAppleSMPEncryption(void)
2806 SecPolicyRef result
= NULL
;
2807 CFMutableDictionaryRef options
= NULL
;
2808 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2809 &kCFTypeDictionaryKeyCallBacks
,
2810 &kCFTypeDictionaryValueCallBacks
), errOut
);
2811 SecPolicyAddBasicCertOptions(options
);
2813 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameSMPEncryption
),
2815 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2817 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2818 CFSTR("Apple System Integration CA - G3"));
2820 // Check that leaf has extension with "Apple SMP Encryption" oid (1.2.840.113635.100.6.30)
2821 add_leaf_marker(options
, &oidAppleCertExtAppleSMPEncryption
);
2823 // Check that intermediate has extension (1.2.840.113635.100.6.2.13)
2824 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleSystemIntgG3
);
2826 add_ku(options
, kSecKeyUsageKeyEncipherment
);
2828 // Ensure that revocation is checked (OCSP)
2829 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationOCSP
);
2831 require(result
= SecPolicyCreate(kSecPolicyAppleSMPEncryption
,
2832 kSecPolicyNameSMPEncryption
, options
), errOut
);
2835 CFReleaseSafe(options
);
2840 @function SecPolicyCreateTestAppleSMPEncryption
2841 @abstract Check for intermediate certificate 'Test Apple System Integration CA - ECC' by name,
2842 and root certificate 'Test Apple Root CA - ECC' by hash.
2843 Leaf cert must have Key Encipherment usage. Other checks TBD.
2845 SecPolicyRef
SecPolicyCreateTestAppleSMPEncryption(void)
2847 SecPolicyRef result
= NULL
;
2848 CFMutableDictionaryRef options
= NULL
;
2849 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2850 &kCFTypeDictionaryKeyCallBacks
,
2851 &kCFTypeDictionaryValueCallBacks
), errOut
);
2852 SecPolicyAddBasicCertOptions(options
);
2854 SecPolicyAddAnchorSHA1Options(options
, kTestAppleRootCA_ECC_SHA1
);
2855 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2857 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2858 CFSTR("Test Apple System Integration CA - ECC"));
2860 add_ku(options
, kSecKeyUsageKeyEncipherment
);
2862 // Ensure that revocation is checked (OCSP)
2863 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationOCSP
);
2865 require(result
= SecPolicyCreate(kSecPolicyAppleTestSMPEncryption
,
2866 kSecPolicyNameTestSMPEncryption
, options
), errOut
);
2869 CFReleaseSafe(options
);
2874 SecPolicyRef
SecPolicyCreateAppleIDValidationRecordSigningPolicy(void)
2876 SecPolicyRef result
= NULL
;
2877 CFMutableDictionaryRef options
= NULL
;
2878 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2879 &kCFTypeDictionaryKeyCallBacks
,
2880 &kCFTypeDictionaryValueCallBacks
), errOut
);
2882 //Leaf appears to be a SSL only cert, so policy should expand on that policy
2883 SecPolicyAddBasicX509Options(options
);
2885 // Apple CA anchored
2886 require(SecPolicyAddAppleAnchorOptions(options
,
2887 kSecPolicyNameIDValidationRecordSigning
),
2890 // Check for an extension with " Apple ID Validation Record Signing" oid (1.2.840.113635.100.6.25)
2891 add_leaf_marker(options
, &oidAppleCertExtensionAppleIDRecordValidationSigning
);
2893 // and validate that intermediate has extension
2894 // Application Integration Intermediate Certificate (1.2.840.113635.100.6.2.3)
2895 // and also validate that intermediate has extension
2896 // System Integration 2 Intermediate Certificate (1.2.840.113635.100.6.2.10)
2897 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleID
);
2898 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleSystemIntg2
);
2900 // Ensure that revocation is checked (OCSP)
2901 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationOCSP
);
2903 require(result
= SecPolicyCreate(kSecPolicyAppleIDValidationRecordSigning
,
2904 kSecPolicyNameIDValidationRecordSigning
, options
), errOut
);
2907 CFReleaseSafe(options
);
2912 @function SecPolicyCreateAppleServerAuthCommon
2913 @abstract Generic policy for server authentication Sub CAs
2915 Allows control for both if pinning is required at all and if UAT environments should be added
2916 to the trust policy.
2918 No pinning is for developer/QA that needs to use proxy to debug the protocol, while UAT
2919 environment is for QA/internal developer that have no need allow fake servers.
2921 Both the noPinning and UAT are gated on that you run on internal hardware.
2926 SecPolicyCreateAppleServerAuthCommon(CFStringRef hostname
,
2927 CFDictionaryRef __unused context
,
2928 CFStringRef policyOID
, CFStringRef service
,
2929 const DERItem
*leafMarkerOID
,
2930 const DERItem
*UATLeafMarkerOID
)
2932 CFMutableDictionaryRef appleAnchorOptions
= NULL
;
2933 CFMutableDictionaryRef options
= NULL
;
2934 SecPolicyRef result
= NULL
;
2935 CFDataRef oid
= NULL
, uatoid
= NULL
;
2937 options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0, &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
2938 require(options
, errOut
);
2940 SecPolicyAddBasicX509Options(options
);
2942 require(hostname
, errOut
);
2943 CFDictionaryAddValue(options
, kSecPolicyCheckSSLHostname
, hostname
);
2945 CFDictionaryAddValue(options
, kSecPolicyCheckBlackListedLeaf
, kCFBooleanTrue
);
2946 CFDictionaryAddValue(options
, kSecPolicyCheckGrayListedLeaf
, kCFBooleanTrue
);
2948 add_eku(options
, &oidExtendedKeyUsageServerAuth
);
2950 if (requireUATPinning(service
)) {
2953 * Require pinning to the Apple CA's.
2955 SecPolicyAddAppleAnchorOptions(options
, service
);
2957 /* old-style leaf marker OIDs */
2958 if (UATLeafMarkerOID
) {
2959 add_leaf_prod_qa_markers(options
, leafMarkerOID
, UATLeafMarkerOID
);
2961 add_leaf_marker(options
, leafMarkerOID
);
2964 /* new-style leaf marker OIDs */
2965 CFStringRef leafMarkerOIDStr
= NULL
, UATLeafMarkerOIDStr
= NULL
;
2966 leafMarkerOIDStr
= SecDERItemCopyOIDDecimalRepresentation(NULL
, leafMarkerOID
);
2967 if (UATLeafMarkerOID
) {
2968 UATLeafMarkerOIDStr
= SecDERItemCopyOIDDecimalRepresentation(NULL
, UATLeafMarkerOID
);
2971 if (leafMarkerOIDStr
&& UATLeafMarkerOIDStr
) {
2972 add_leaf_prod_qa_markers_value_string(options
,
2973 CFSTR("1.2.840.113635.100.6.48.1"), leafMarkerOIDStr
,
2974 CFSTR("1.2.840.113635.100.6.48.1"), UATLeafMarkerOIDStr
);
2975 } else if (leafMarkerOIDStr
) {
2976 add_leaf_marker_value_string(options
, CFSTR("1.2.840.113635.100.6.48.1"), leafMarkerOIDStr
);
2979 CFReleaseNull(leafMarkerOIDStr
);
2980 CFReleaseNull(UATLeafMarkerOIDStr
);
2982 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleServerAuthentication
);
2985 /* Check for weak hashes and keys */
2986 CFDictionaryAddValue(options
, kSecPolicyCheckSystemTrustedWeakHash
, kCFBooleanTrue
);
2987 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
2989 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
2991 result
= SecPolicyCreate(policyOID
, service
, options
);
2992 require(result
, errOut
);
2995 CFReleaseSafe(appleAnchorOptions
);
2996 CFReleaseSafe(options
);
2998 CFReleaseSafe(uatoid
);
3003 @function SecPolicyCreateAppleIDSService
3004 @abstract Ensure we're appropriately pinned to the IDS service (SSL + Apple restrictions)
3006 SecPolicyRef
SecPolicyCreateAppleIDSService(CFStringRef hostname
)
3008 SecPolicyRef result
= SecPolicyCreateSSL(true, hostname
);
3010 SecPolicySetOid(result
, kSecPolicyAppleIDSService
);
3011 SecPolicySetName(result
, kSecPolicyNameAppleIDSBag
);
3017 @function SecPolicyCreateAppleIDSService
3018 @abstract Ensure we're appropriately pinned to the IDS service (SSL + Apple restrictions)
3020 SecPolicyRef
SecPolicyCreateAppleIDSServiceContext(CFStringRef hostname
, CFDictionaryRef context
)
3022 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyAppleIDSServiceContext
,
3023 kSecPolicyNameAppleIDSService
,
3024 &oidAppleCertExtAppleServerAuthenticationIDSProd
,
3025 &oidAppleCertExtAppleServerAuthenticationIDSProdQA
);
3029 @function SecPolicyCreateAppleGSService
3030 @abstract Ensure we're appropriately pinned to the GS service
3032 SecPolicyRef
SecPolicyCreateAppleGSService(CFStringRef hostname
, CFDictionaryRef context
)
3034 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyAppleGSService
,
3035 kSecPolicyNameAppleGSService
,
3036 &oidAppleCertExtAppleServerAuthenticationGS
,
3041 @function SecPolicyCreateApplePushService
3042 @abstract Ensure we're appropriately pinned to the Push service (SSL + Apple restrictions)
3044 SecPolicyRef
SecPolicyCreateApplePushService(CFStringRef hostname
, CFDictionaryRef context
)
3046 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyApplePushService
,
3047 kSecPolicyNameApplePushService
,
3048 &oidAppleCertExtAppleServerAuthenticationAPNProd
,
3049 &oidAppleCertExtAppleServerAuthenticationAPNProdQA
);
3053 @function SecPolicyCreateApplePPQService
3054 @abstract Ensure we're appropriately pinned to the PPQ service (SSL + Apple restrictions)
3056 SecPolicyRef
SecPolicyCreateApplePPQService(CFStringRef hostname
, CFDictionaryRef context
)
3058 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyApplePPQService
,
3059 kSecPolicyNameApplePPQService
,
3060 &oidAppleCertExtAppleServerAuthenticationPPQProd
,
3061 &oidAppleCertExtAppleServerAuthenticationPPQProdQA
);
3065 @function SecPolicyCreateAppleAST2Service
3066 @abstract Ensure we're appropriately pinned to the AST2 Diagnostic service (SSL + Apple restrictions)
3068 SecPolicyRef
SecPolicyCreateAppleAST2Service(CFStringRef hostname
, CFDictionaryRef context
)
3070 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyAppleAST2DiagnosticsServerAuth
,
3071 kSecPolicyNameAppleAST2Service
,
3072 &oidAppleCertExtAST2DiagnosticsServerAuthProd
,
3073 &oidAppleCertExtAST2DiagnosticsServerAuthProdQA
);
3077 @function SecPolicyCreateAppleEscrowProxyService
3078 @abstract Ensure we're appropriately pinned to the iCloud Escrow Proxy service (SSL + Apple restrictions)
3080 SecPolicyRef
SecPolicyCreateAppleEscrowProxyService(CFStringRef hostname
, CFDictionaryRef context
)
3082 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyAppleEscrowProxyServerAuth
,
3083 kSecPolicyNameAppleEscrowProxyService
,
3084 &oidAppleCertExtEscrowProxyServerAuthProd
,
3085 &oidAppleCertExtEscrowProxyServerAuthProdQA
);
3088 /* subject:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA */
3089 /* SKID: C0:7A:98:68:8D:89:FB:AB:05:64:0C:11:7D:AA:7D:65:B8:CA:CC:4E */
3090 /* Not Before: May 21 04:00:00 2002 GMT, Not After : May 21 04:00:00 2022 GMT */
3091 /* Signature Algorithm: sha1WithRSAEncryption */
3092 unsigned char GeoTrust_Global_CA_sha256
[kSecPolicySHA256Size
] = {
3093 0xff, 0x85, 0x6a, 0x2d, 0x25, 0x1d, 0xcd, 0x88, 0xd3, 0x66, 0x56, 0xf4, 0x50, 0x12, 0x67, 0x98,
3094 0xcf, 0xab, 0xaa, 0xde, 0x40, 0x79, 0x9c, 0x72, 0x2d, 0xe4, 0xd2, 0xb5, 0xdb, 0x36, 0xa7, 0x3a
3097 static SecPolicyRef
SecPolicyCreateAppleGeoTrustServerAuthCommon(CFStringRef hostname
, CFStringRef policyOid
,
3098 CFStringRef policyName
,
3099 CFStringRef leafMarkerOid
,
3100 CFStringRef qaLeafMarkerOid
) {
3101 CFMutableDictionaryRef options
= NULL
;
3102 CFDataRef spkiDigest
= NULL
;
3103 SecPolicyRef result
= NULL
;
3105 require(options
= CFDictionaryCreateMutable(NULL
, 0, &kCFTypeDictionaryKeyCallBacks
,
3106 &kCFTypeDictionaryValueCallBacks
), errOut
);
3109 SecPolicyAddBasicX509Options(options
);
3111 require(hostname
, errOut
);
3112 CFDictionaryAddValue(options
, kSecPolicyCheckSSLHostname
, hostname
);
3114 add_eku(options
, &oidExtendedKeyUsageServerAuth
);
3117 if (requireUATPinning(policyName
)) {
3119 SecPolicyAddAnchorSHA256Options(options
, GeoTrust_Global_CA_sha256
);
3121 /* Issued to Apple Inc. in the US */
3122 add_element(options
, kSecPolicyCheckIntermediateCountry
, CFSTR("US"));
3123 add_element(options
, kSecPolicyCheckIntermediateOrganization
, CFSTR("Apple Inc."));
3125 require_action(SecPolicyAddChainLengthOptions(options
, 3), errOut
, CFReleaseNull(result
));
3127 /* Marker OIDs in both formats */
3128 if (qaLeafMarkerOid
) {
3129 add_leaf_prod_qa_markers_string(options
, leafMarkerOid
, qaLeafMarkerOid
);
3130 add_leaf_prod_qa_markers_value_string(options
,
3131 CFSTR("1.2.840.113635.100.6.48.1"), leafMarkerOid
,
3132 CFSTR("1.2.840.113635.100.6.48.1"), qaLeafMarkerOid
);
3134 add_leaf_marker_string(options
, leafMarkerOid
);
3135 add_leaf_marker_value_string(options
, CFSTR("1.2.840.113635.100.6.48.1"), leafMarkerOid
);
3139 /* Check for weak hashes */
3140 CFDictionaryAddValue(options
, kSecPolicyCheckSystemTrustedWeakHash
, kCFBooleanTrue
);
3141 CFDictionaryAddValue(options
, kSecPolicyCheckSystemTrustedWeakKey
, kCFBooleanTrue
);
3143 /* See <rdar://25344801> for more details */
3145 result
= SecPolicyCreate(policyOid
, policyName
, options
);
3148 CFReleaseSafe(options
);
3149 CFReleaseSafe(spkiDigest
);
3153 SecPolicyRef
SecPolicyCreateAppleCompatibilityEscrowProxyService(CFStringRef hostname
) {
3154 return SecPolicyCreateAppleGeoTrustServerAuthCommon(hostname
, kSecPolicyAppleEscrowProxyCompatibilityServerAuth
,
3155 kSecPolicyNameAppleEscrowProxyService
,
3156 CFSTR("1.2.840.113635.100.6.27.7.2"),
3157 CFSTR("1.2.840.113635.100.6.27.7.1"));
3161 @function SecPolicyCreateAppleFMiPService
3162 @abstract Ensure we're appropriately pinned to the Find My iPhone service (SSL + Apple restrictions)
3164 SecPolicyRef
SecPolicyCreateAppleFMiPService(CFStringRef hostname
, CFDictionaryRef context
)
3166 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyAppleFMiPServerAuth
,
3167 kSecPolicyNameAppleFMiPService
,
3168 &oidAppleCertExtFMiPServerAuthProd
,
3169 &oidAppleCertExtFMiPServerAuthProdQA
);
3173 /* should use verbatim copy, but since this is the deprecated way, don't care right now */
3174 static const UInt8 entrustSPKIL1C
[kSecPolicySHA256Size
] = {
3175 0x54, 0x5b, 0xf9, 0x35, 0xe9, 0xad, 0xa1, 0xda,
3176 0x11, 0x7e, 0xdc, 0x3c, 0x2a, 0xcb, 0xc5, 0x6f,
3177 0xc0, 0x28, 0x09, 0x6c, 0x0e, 0x24, 0xbe, 0x9b,
3178 0x38, 0x94, 0xbe, 0x52, 0x2d, 0x1b, 0x43, 0xde
3182 @function SecPolicyCreateApplePushServiceLegacy
3183 @abstract Ensure we're appropriately pinned to the Push service (via Entrust)
3185 SecPolicyRef
SecPolicyCreateApplePushServiceLegacy(CFStringRef hostname
)
3187 CFMutableDictionaryRef options
= NULL
;
3188 SecPolicyRef result
= NULL
;
3189 CFDataRef digest
= NULL
;
3191 digest
= CFDataCreateWithBytesNoCopy(kCFAllocatorDefault
, entrustSPKIL1C
, sizeof(entrustSPKIL1C
), kCFAllocatorNull
);
3192 require(digest
, errOut
);
3194 options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0, &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
3195 require(options
, errOut
);
3197 SecPolicyAddBasicX509Options(options
);
3199 CFDictionaryAddValue(options
, kSecPolicyCheckSSLHostname
, hostname
);
3201 CFDictionaryAddValue(options
, kSecPolicyCheckBlackListedLeaf
, kCFBooleanTrue
);
3202 CFDictionaryAddValue(options
, kSecPolicyCheckGrayListedLeaf
, kCFBooleanTrue
);
3204 CFDictionaryAddValue(options
, kSecPolicyCheckIntermediateSPKISHA256
, digest
);
3206 add_eku(options
, &oidExtendedKeyUsageServerAuth
);
3208 /* Check for weak hashes and keys */
3209 CFDictionaryAddValue(options
, kSecPolicyCheckSystemTrustedWeakHash
, kCFBooleanTrue
);
3210 CFDictionaryAddValue(options
, kSecPolicyCheckSystemTrustedWeakKey
, kCFBooleanTrue
);
3212 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
3214 result
= SecPolicyCreate(kSecPolicyAppleLegacyPushService
,
3215 kSecPolicyNameLegacyPushService
, options
);
3216 require(result
, errOut
);
3219 CFReleaseSafe(digest
);
3220 CFReleaseSafe(options
);
3225 @function SecPolicyCreateAppleMMCSService
3226 @abstract Ensure we're appropriately pinned to the IDS service (SSL + Apple restrictions)
3228 SecPolicyRef
SecPolicyCreateAppleMMCSService(CFStringRef hostname
, CFDictionaryRef context
)
3230 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyAppleMMCService
,
3231 kSecPolicyNameAppleMMCSService
,
3232 &oidAppleCertExtAppleServerAuthenticationMMCSProd
,
3233 &oidAppleCertExtAppleServerAuthenticationMMCSProdQA
);
3236 SecPolicyRef
SecPolicyCreateAppleCompatibilityMMCSService(CFStringRef hostname
) {
3237 return SecPolicyCreateAppleGeoTrustServerAuthCommon(hostname
, kSecPolicyAppleMMCSCompatibilityServerAuth
,
3238 kSecPolicyNameAppleMMCSService
,
3239 CFSTR("1.2.840.113635.100.6.27.11.2"),
3240 CFSTR("1.2.840.113635.100.6.27.11.1"));
3244 SecPolicyRef
SecPolicyCreateAppleiCloudSetupService(CFStringRef hostname
, CFDictionaryRef context
)
3246 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyAppleiCloudSetupServerAuth
,
3247 kSecPolicyNameAppleiCloudSetupService
,
3248 &oidAppleCertExtAppleServerAuthenticationiCloudSetupProd
,
3249 &oidAppleCertExtAppleServerAuthenticationiCloudSetupProdQA
);
3252 SecPolicyRef
SecPolicyCreateAppleCompatibilityiCloudSetupService(CFStringRef hostname
)
3254 return SecPolicyCreateAppleGeoTrustServerAuthCommon(hostname
, kSecPolicyAppleiCloudSetupCompatibilityServerAuth
,
3255 kSecPolicyNameAppleiCloudSetupService
,
3256 CFSTR("1.2.840.113635.100.6.27.15.2"),
3257 CFSTR("1.2.840.113635.100.6.27.15.1"));
3261 @function SecPolicyCreateAppleSSLService
3262 @abstract Ensure we're appropriately pinned to an Apple server (SSL + Apple restrictions)
3264 SecPolicyRef
SecPolicyCreateAppleSSLService(CFStringRef hostname
)
3266 // SSL server, pinned to an Apple intermediate
3267 SecPolicyRef policy
= SecPolicyCreateSSL(true, hostname
);
3268 CFMutableDictionaryRef options
= NULL
;
3269 require(policy
, errOut
);
3271 // change options for SSL policy evaluation
3272 require((options
=(CFMutableDictionaryRef
)policy
->_options
) != NULL
, errOut
);
3274 // Apple CA anchored
3275 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameServerAuthentication
), errOut
);
3277 // Check leaf for Apple Server Authentication marker oid (1.2.840.113635.100.6.27.1)
3278 add_leaf_marker(options
, &oidAppleCertExtAppleServerAuthentication
);
3280 // Check intermediate for Apple Server Authentication intermediate marker (1.2.840.113635.100.6.2.12)
3281 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleServerAuthentication
);
3283 /* Check for weak hashes */
3284 CFDictionaryAddValue(options
, kSecPolicyCheckSystemTrustedWeakHash
, kCFBooleanTrue
);
3285 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
3287 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
3289 SecPolicySetOid(policy
, kSecPolicyAppleServerAuthentication
);
3290 SecPolicySetName(policy
, kSecPolicyNameServerAuthentication
);
3295 CFReleaseSafe(options
);
3296 CFReleaseSafe(policy
);
3301 @function SecPolicyCreateApplePPQSigning
3302 @abstract Check for intermediate certificate 'Apple System Integration 2 Certification Authority' by name,
3304 Leaf cert must have Digital Signature usage.
3305 Leaf cert must have Apple PPQ Signing marker OID (1.2.840.113635.100.6.38.2).
3306 Intermediate must have marker OID (1.2.840.113635.100.6.2.10).
3308 SecPolicyRef
SecPolicyCreateApplePPQSigning(void)
3310 SecPolicyRef result
= NULL
;
3311 CFMutableDictionaryRef options
= NULL
;
3312 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3313 &kCFTypeDictionaryKeyCallBacks
,
3314 &kCFTypeDictionaryValueCallBacks
), errOut
);
3315 SecPolicyAddBasicCertOptions(options
);
3317 SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNamePPQSigning
);
3318 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3320 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
3321 CFSTR("Apple System Integration 2 Certification Authority"));
3323 // Check that leaf has extension with "Apple PPQ Signing" prod oid (1.2.840.113635.100.6.38.2)
3324 add_leaf_marker(options
, &oidAppleCertExtApplePPQSigningProd
);
3326 // Check that intermediate has extension (1.2.840.113635.100.6.2.10)
3327 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleSystemIntg2
);
3329 add_ku(options
, kSecKeyUsageDigitalSignature
);
3331 require(result
= SecPolicyCreate(kSecPolicyApplePPQSigning
,
3332 kSecPolicyNamePPQSigning
, options
), errOut
);
3335 CFReleaseSafe(options
);
3340 @function SecPolicyCreateTestApplePPQSigning
3341 @abstract Check for intermediate certificate 'Apple System Integration 2 Certification Authority' by name,
3343 Leaf cert must have Digital Signature usage.
3344 Leaf cert must have Apple PPQ Signing Test marker OID (1.2.840.113635.100.6.38.1).
3345 Intermediate must have marker OID (1.2.840.113635.100.6.2.10).
3347 SecPolicyRef
SecPolicyCreateTestApplePPQSigning(void)
3349 /* Guard against use of test policy on production devices */
3350 if (!SecIsInternalRelease()) {
3351 return SecPolicyCreateApplePPQSigning();
3354 SecPolicyRef result
= NULL
;
3355 CFMutableDictionaryRef options
= NULL
;
3356 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3357 &kCFTypeDictionaryKeyCallBacks
,
3358 &kCFTypeDictionaryValueCallBacks
), errOut
);
3359 SecPolicyAddBasicCertOptions(options
);
3361 SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameTestPPQSigning
);
3362 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3364 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
3365 CFSTR("Apple System Integration 2 Certification Authority"));
3367 // Check that leaf has extension with "Apple PPQ Signing" test oid (1.2.840.113635.100.6.38.1)
3368 add_leaf_marker(options
, &oidAppleCertExtApplePPQSigningProdQA
);
3370 // Check that intermediate has extension (1.2.840.113635.100.6.2.10)
3371 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleSystemIntg2
);
3373 add_ku(options
, kSecKeyUsageDigitalSignature
);
3375 require(result
= SecPolicyCreate(kSecPolicyAppleTestPPQSigning
,
3376 kSecPolicyNameTestPPQSigning
, options
), errOut
);
3379 CFReleaseSafe(options
);
3383 @function SecPolicyCreateAppleTimeStamping
3384 @abstract Check for RFC3161 timestamping EKU.
3386 SecPolicyRef
SecPolicyCreateAppleTimeStamping(void)
3388 SecPolicyRef result
= NULL
;
3389 CFMutableDictionaryRef options
= NULL
;
3390 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3391 &kCFTypeDictionaryKeyCallBacks
,
3392 &kCFTypeDictionaryValueCallBacks
), errOut
);
3394 SecPolicyAddBasicX509Options(options
);
3396 /* Require id-kp-timeStamping extendedKeyUsage to be present. */
3397 add_eku(options
, &oidExtendedKeyUsageTimeStamping
);
3399 require(result
= SecPolicyCreate(kSecPolicyAppleTimeStamping
,
3400 kSecPolicyNameTimeStamping
, options
), errOut
);
3403 CFReleaseSafe(options
);
3408 @function SecPolicyCreateApplePayIssuerEncryption
3409 @abstract Check for intermediate certificate 'Apple Worldwide Developer Relations CA - G2' by name,
3410 and ECC apple anchor.
3411 Leaf cert must have Key Encipherment and Key Agreement usage.
3412 Leaf cert must have Apple Pay Issuer Encryption marker OID (1.2.840.113635.100.6.39).
3414 SecPolicyRef
SecPolicyCreateApplePayIssuerEncryption(void)
3416 SecPolicyRef result
= NULL
;
3417 CFMutableDictionaryRef options
= NULL
;
3418 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3419 &kCFTypeDictionaryKeyCallBacks
,
3420 &kCFTypeDictionaryValueCallBacks
), errOut
);
3421 SecPolicyAddBasicCertOptions(options
);
3423 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNamePayIssuerEncryption
),
3425 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3427 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
3428 CFSTR("Apple Worldwide Developer Relations CA - G2"));
3430 // Check that leaf has extension with "Apple Pay Issuer Encryption" oid (1.2.840.113635.100.6.39)
3431 add_leaf_marker(options
, &oidAppleCertExtCryptoServicesExtEncryption
);
3433 add_ku(options
, kSecKeyUsageKeyEncipherment
);
3435 require(result
= SecPolicyCreate(kSecPolicyApplePayIssuerEncryption
,
3436 kSecPolicyNamePayIssuerEncryption
, options
), errOut
);
3439 CFReleaseSafe(options
);
3444 @function SecPolicyCreateAppleATVVPNProfileSigning
3445 @abstract Check for leaf marker OID 1.2.840.113635.100.6.43,
3446 intermediate marker OID 1.2.840.113635.100.6.2.10,
3447 chains to Apple Root CA, path length 3
3449 SecPolicyRef
SecPolicyCreateAppleATVVPNProfileSigning(void)
3451 SecPolicyRef result
= NULL
;
3452 CFMutableDictionaryRef options
= NULL
;
3453 CFMutableDictionaryRef appleAnchorOptions
= NULL
;
3454 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3455 &kCFTypeDictionaryKeyCallBacks
,
3456 &kCFTypeDictionaryValueCallBacks
), errOut
);
3458 SecPolicyAddBasicCertOptions(options
);
3460 // Require pinning to the Apple CAs (including test CA for internal releases)
3461 appleAnchorOptions
= CFDictionaryCreateMutableForCFTypes(NULL
);
3462 require(appleAnchorOptions
, errOut
);
3464 if (SecIsInternalRelease()) {
3465 CFDictionarySetValue(appleAnchorOptions
,
3466 kSecPolicyAppleAnchorIncludeTestRoots
, kCFBooleanTrue
);
3469 add_element(options
, kSecPolicyCheckAnchorApple
, appleAnchorOptions
);
3471 // Cert chain length 3
3472 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3474 // Check leaf for Apple ATV VPN Profile Signing OID (1.2.840.113635.100.6.43)
3475 add_leaf_marker(options
, &oidAppleCertExtATVVPNProfileSigning
);
3477 // Check intermediate for Apple System Integration 2 CA intermediate marker (1.2.840.113635.100.6.2.10)
3478 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleSystemIntg2
);
3480 // Ensure that revocation is checked (OCSP only)
3481 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationOCSP
);
3483 require(result
= SecPolicyCreate(kSecPolicyAppleATVVPNProfileSigning
,
3484 kSecPolicyNameATVVPNProfileSigning
, options
), errOut
);
3487 CFReleaseSafe(options
);
3488 CFReleaseSafe(appleAnchorOptions
);
3492 SecPolicyRef
SecPolicyCreateAppleHomeKitServerAuth(CFStringRef hostname
) {
3493 CFMutableDictionaryRef appleAnchorOptions
= NULL
;
3494 CFMutableDictionaryRef options
= NULL
;
3495 SecPolicyRef result
= NULL
;
3496 CFDataRef oid
= NULL
;
3498 options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0, &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
3499 require(options
, errOut
);
3501 SecPolicyAddBasicX509Options(options
);
3503 CFDictionaryAddValue(options
, kSecPolicyCheckSSLHostname
, hostname
);
3505 add_eku(options
, &oidExtendedKeyUsageServerAuth
);
3507 if (requireUATPinning(kSecPolicyNameAppleHomeKitService
)) {
3509 // Cert chain length 3
3510 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3512 // Apple anchors, allowing test anchors for internal release
3513 SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameAppleHomeKitService
);
3515 add_leaf_marker(options
, &oidAppleCertExtHomeKitServerAuth
);
3517 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleHomeKitServerCA
);
3520 /* Check for weak hashes */
3521 CFDictionaryAddValue(options
, kSecPolicyCheckSystemTrustedWeakHash
, kCFBooleanTrue
);
3522 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
3524 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
3526 result
= SecPolicyCreate(kSecPolicyAppleHomeKitServerAuth
,
3527 kSecPolicyNameAppleHomeKitService
, options
);
3528 require(result
, errOut
);
3531 CFReleaseSafe(appleAnchorOptions
);
3532 CFReleaseSafe(options
);
3537 SecPolicyRef
SecPolicyCreateAppleExternalDeveloper(void) {
3538 CFMutableDictionaryRef options
= NULL
;
3539 SecPolicyRef result
= NULL
;
3541 /* Create basic Apple pinned policy */
3542 require(result
= SecPolicyCreateApplePinned(kSecPolicyNameExternalDeveloper
,
3543 CFSTR("1.2.840.113635.100.6.2.1"), // WWDR Intermediate OID
3544 CFSTR("1.2.840.113635.100.6.1.2")), // "iPhone Developer" leaf OID
3547 require_action(options
= CFDictionaryCreateMutableCopy(NULL
, 0, result
->_options
), errOut
, CFReleaseNull(result
));
3549 /* Additional intermediate OIDs */
3550 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
,
3551 CFSTR("1.2.840.113635.100.6.2.6")); // "Developer ID" Intermediate OID
3553 /* Addtional leaf OIDS */
3554 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.4")); // "iPhone Distribution" leaf OID
3555 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.5")); // "Safari Developer" leaf OID
3556 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.7")); // "3rd Party Mac Developer Application" leaf OID
3557 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.8")); // "3rd Party Mac Developer Installer" leaf OID
3558 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.12")); // "Mac Developer" leaf OID
3559 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.13")); // "Developer ID Application" leaf OID
3560 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.14")); // "Developer ID Installer" leaf OID
3563 add_eku_string(options
, CFSTR("1.3.6.1.5.5.7.3.3")); // CodeSigning EKU
3564 add_eku_string(options
, CFSTR("1.2.840.113635.100.4.8")); // "Safari Developer" EKU
3565 add_eku_string(options
, CFSTR("1.2.840.113635.100.4.9")); // "3rd Party Mac Developer Installer" EKU
3566 add_eku_string(options
, CFSTR("1.2.840.113635.100.4.13")); // "Developer ID Installer" EKU
3568 CFReleaseSafe(result
->_options
);
3569 result
->_options
= CFRetainSafe(options
);
3571 SecPolicySetOid(result
, kSecPolicyAppleExternalDeveloper
);
3574 CFReleaseSafe(options
);
3578 /* This one is special because the intermediate has no marker OID */
3579 SecPolicyRef
SecPolicyCreateAppleSoftwareSigning(void) {
3580 CFMutableDictionaryRef options
= NULL
;
3581 CFDictionaryRef keySizes
= NULL
;
3582 CFNumberRef rsaSize
= NULL
, ecSize
= NULL
;
3583 SecPolicyRef result
= NULL
;
3585 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3586 &kCFTypeDictionaryKeyCallBacks
,
3587 &kCFTypeDictionaryValueCallBacks
), errOut
);
3589 SecPolicyAddBasicCertOptions(options
);
3591 /* Anchored to the Apple Roots */
3592 require_quiet(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameSoftwareSigning
),
3595 /* Exactly 3 certs in the chain */
3596 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3598 /* Intermediate Common Name matches */
3599 add_element(options
, kSecPolicyCheckIssuerCommonName
, CFSTR("Apple Code Signing Certification Authority"));
3601 /* Leaf marker OID matches */
3602 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.22"));
3604 /* Leaf has CodeSigning EKU */
3605 add_eku_string(options
, CFSTR("1.3.6.1.5.5.7.3.3"));
3607 /* Check revocation using any available method */
3608 add_element(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
3610 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
3611 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
3613 require(result
= SecPolicyCreate(kSecPolicyAppleSoftwareSigning
,
3614 kSecPolicyNameSoftwareSigning
, options
), errOut
);
3617 CFReleaseSafe(options
);
3618 CFReleaseSafe(keySizes
);
3619 CFReleaseSafe(rsaSize
);
3620 CFReleaseSafe(ecSize
);
3624 /* subject:/CN=SEP Root CA/O=Apple Inc./ST=California */
3625 /* SKID: 58:EF:D6:BE:C5:82:B0:54:CD:18:A6:84:AD:A2:F6:7B:7B:3A:7F:CF */
3626 /* Not Before: Jun 24 21:43:24 2014 GMT, Not After : Jun 24 21:43:24 2029 GMT */
3627 /* Signature Algorithm: ecdsa-with-SHA384 */
3628 const uint8_t SEPRootCA_SHA256
[kSecPolicySHA256Size
] = {
3629 0xd1, 0xdf, 0x82, 0x00, 0xf3, 0x89, 0x4e, 0xe9, 0x96, 0xf3, 0x77, 0xdf, 0x76, 0x3b, 0x0a, 0x16,
3630 0x8f, 0xd9, 0x6c, 0x58, 0xc0, 0x3e, 0xc9, 0xb0, 0x5f, 0xa5, 0x64, 0x79, 0xc0, 0xe8, 0xc9, 0xe7
3633 SecPolicyRef
SecPolicyCreateAppleUniqueDeviceCertificate(CFDataRef testRootHash
) {
3634 CFMutableDictionaryRef options
= NULL
;
3635 CFDictionaryRef keySizes
= NULL
;
3636 CFNumberRef ecSize
= NULL
;
3637 SecPolicyRef result
= NULL
;
3639 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3640 &kCFTypeDictionaryKeyCallBacks
,
3641 &kCFTypeDictionaryValueCallBacks
), errOut
);
3643 /* Device certificate should never expire */
3644 SecPolicyAddBasicCertOptions(options
);
3646 /* Anchored to the SEP Root CA. Allow alternative root for developers */
3647 require(SecPolicyAddAnchorSHA256Options(options
, SEPRootCA_SHA256
),errOut
);
3648 if (testRootHash
&& SecIsInternalRelease() && (kSecPolicySHA256Size
== CFDataGetLength(testRootHash
))) {
3649 add_element(options
, kSecPolicyCheckAnchorSHA256
, testRootHash
);
3652 /* Exactly 3 certs in the chain */
3653 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3655 /* Intermediate has marker OID with value */
3656 add_intermediate_marker_value_string(options
, CFSTR("1.2.840.113635.100.6.44"), CFSTR("ucrt"));
3658 /* Leaf has marker OID with varying value that can't be pre-determined */
3659 add_element(options
, kSecPolicyCheckLeafMarkerOidWithoutValueCheck
, CFSTR("1.2.840.113635.100.10.1"));
3661 /* RSA key sizes are disallowed. EC key sizes are P-256 or larger. */
3662 require(ecSize
= CFNumberCreateWithCFIndex(NULL
, 256), errOut
);
3663 require(keySizes
= CFDictionaryCreate(NULL
, (const void**)&kSecAttrKeyTypeEC
,
3664 (const void**)&ecSize
, 1,
3665 &kCFTypeDictionaryKeyCallBacks
,
3666 &kCFTypeDictionaryValueCallBacks
), errOut
);
3667 add_element(options
, kSecPolicyCheckKeySize
, keySizes
);
3670 require(result
= SecPolicyCreate(kSecPolicyAppleUniqueDeviceIdentifierCertificate
,
3671 kSecPolicyNameUniqueDeviceIdentifierCertificate
, options
), errOut
);
3674 CFReleaseSafe(options
);
3675 CFReleaseSafe(keySizes
);
3676 CFReleaseSafe(ecSize
);
3680 SecPolicyRef
SecPolicyCreateAppleWarsaw(void) {
3681 CFMutableDictionaryRef options
= NULL
;
3682 SecPolicyRef result
= NULL
;
3683 #if TARGET_OS_BRIDGE
3684 CFMutableDictionaryRef appleAnchorOptions
= NULL
;
3687 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3688 &kCFTypeDictionaryKeyCallBacks
,
3689 &kCFTypeDictionaryValueCallBacks
), errOut
);
3691 SecPolicyAddBasicX509Options(options
);
3693 /* Anchored to the Apple Roots. */
3694 require_quiet(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameWarsaw
),
3697 /* Exactly 3 certs in the chain */
3698 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3700 /* Intermediate marker OID matches input OID */
3701 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.14"));
3703 /* Leaf marker OID matches input OID */
3704 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.29"));
3706 /* Check revocation using any available method */
3707 add_element(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
3709 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
3710 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
3712 require(result
= SecPolicyCreate(kSecPolicyAppleWarsaw
,
3713 kSecPolicyNameWarsaw
, options
), errOut
);
3716 CFReleaseSafe(options
);
3720 SecPolicyRef
SecPolicyCreateAppleSecureIOStaticAsset(void) {
3721 CFMutableDictionaryRef options
= NULL
;
3722 SecPolicyRef result
= NULL
;
3723 #if TARGET_OS_BRIDGE
3724 CFMutableDictionaryRef appleAnchorOptions
= NULL
;
3727 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3728 &kCFTypeDictionaryKeyCallBacks
,
3729 &kCFTypeDictionaryValueCallBacks
), errOut
);
3731 /* This certificate cannot expire so that assets always load */
3732 SecPolicyAddBasicCertOptions(options
);
3734 /* Anchored to the Apple Roots. */
3735 #if TARGET_OS_BRIDGE
3736 /* On the bridge, test roots are gated in the trust and policy servers. */
3737 require_quiet(appleAnchorOptions
= CFDictionaryCreateMutableForCFTypes(NULL
), errOut
);
3738 CFDictionarySetValue(appleAnchorOptions
,
3739 kSecPolicyAppleAnchorIncludeTestRoots
, kCFBooleanTrue
);
3740 add_element(options
, kSecPolicyCheckAnchorApple
, appleAnchorOptions
);
3741 CFReleaseSafe(appleAnchorOptions
);
3743 require_quiet(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameSecureIOStaticAsset
),
3747 /* Exactly 3 certs in the chain */
3748 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3750 /* Intermediate marker OID matches ASI CA */
3751 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.10"));
3753 /* Leaf marker OID matches static IO OID */
3754 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.50"));
3756 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
3757 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
3759 require(result
= SecPolicyCreate(kSecPolicyAppleSecureIOStaticAsset
,
3760 kSecPolicyNameSecureIOStaticAsset
, options
), errOut
);
3763 CFReleaseSafe(options
);
3767 SecPolicyRef
SecPolicyCreateAppleAppTransportSecurity(void) {
3768 CFMutableDictionaryRef options
= NULL
;
3769 SecPolicyRef result
= NULL
;
3770 CFMutableSetRef disallowedHashes
= NULL
;
3772 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3773 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
3775 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
3776 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
3778 /* Hash algorithm is SHA-256 or better */
3779 require(disallowedHashes
= CFSetCreateMutable(NULL
, 5, &kCFTypeSetCallBacks
), errOut
);
3780 CFSetAddValue(disallowedHashes
, kSecSignatureDigestAlgorithmMD2
);
3781 CFSetAddValue(disallowedHashes
, kSecSignatureDigestAlgorithmMD4
);
3782 CFSetAddValue(disallowedHashes
, kSecSignatureDigestAlgorithmMD5
);
3783 CFSetAddValue(disallowedHashes
, kSecSignatureDigestAlgorithmSHA1
);
3784 CFSetAddValue(disallowedHashes
, kSecSignatureDigestAlgorithmSHA224
);
3786 add_element(options
, kSecPolicyCheckSignatureHashAlgorithms
, disallowedHashes
);
3788 require_quiet(result
= SecPolicyCreate(kSecPolicyAppleAppTransportSecurity
,
3789 kSecPolicyNameAppTransportSecurity
,
3793 CFReleaseSafe(options
);
3797 SecPolicyRef
SecPolicyCreateMobileSoftwareUpdate(void) {
3798 CFMutableDictionaryRef options
= NULL
;
3799 SecPolicyRef result
= NULL
;
3800 #if TARGET_OS_BRIDGE
3801 CFMutableDictionaryRef appleAnchorOptions
= NULL
;
3804 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3805 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
3807 /* No expiration check. */
3808 SecPolicyAddBasicCertOptions(options
);
3811 require_quiet(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameMobileSoftwareUpdate
),
3814 /* Exactly 3 certs in the chain */
3815 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3817 /* Intermediate marker OID is iPhone CA OID */
3818 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.18"));
3820 /* Leaf marker OID is either the prod MSU OID, or, on internal builds, the prodQA OID */
3821 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.57.2"));
3822 if (SecIsInternalRelease()) {
3823 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.57.1"));
3826 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
3827 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
3829 require(result
= SecPolicyCreate(kSecPolicyAppleMobileSoftwareUpdate
,
3830 kSecPolicyNameMobileSoftwareUpdate
, options
), errOut
);
3833 CFReleaseNull(options
);
3837 /* subject:/CN=Basic Attestation System Root CA/O=Apple Inc./ST=California */
3838 /* SKID: FE:D1:D1:C2:08:07:03:D5:B9:3C:34:B2:BB:FD:7C:3A:99:25:1B:8F */
3839 /* Not Before: Apr 20 00:22:09 2017 GMT, Not After : Mar 22 00:00:00 2032 GMT */
3840 /* Signature Algorithm: ecdsa-with-SHA384 */
3841 const uint8_t BASystemRootCA_SHA256
[kSecPolicySHA256Size
] = {
3842 0x10, 0xD3, 0xC8, 0x67, 0xF0, 0xAE, 0xFB, 0x24, 0x31, 0xA0, 0xA9, 0x7A, 0x88, 0x18, 0xBD, 0x64,
3843 0xF7, 0xF9, 0x0F, 0xFE, 0x11, 0x94, 0x48, 0x4F, 0xCA, 0x97, 0xF0, 0xF2, 0x9E, 0xCA, 0x00, 0x47
3846 /* subject:/CN=Basic Attestation User Root CA/O=Apple Inc./ST=California */
3847 /* SKID: 83:E5:A3:21:9E:B0:74:C3:F9:61:90:FD:97:4E:23:10:76:A4:A3:F2 */
3848 /* Not Before: Apr 19 21:41:56 2017 GMT, Not After : Mar 22 00:00:00 2032 GMT */
3849 /* Signature Algorithm: ecdsa-with-SHA384 */
3850 const uint8_t BAUserRootCA_SHA256
[kSecPolicySHA256Size
] = {
3851 0x03, 0x75, 0x1c, 0x80, 0xfc, 0xbe, 0x58, 0x19, 0xd1, 0x70, 0xd2, 0x67, 0xce, 0x1a, 0xd6, 0xd0,
3852 0x94, 0x40, 0x7c, 0x91, 0xd8, 0x73, 0xd7, 0xa6, 0x56, 0x2d, 0xe3, 0x66, 0x6d, 0x35, 0x94, 0xc6
3855 SecPolicyRef
SecPolicyCreateAppleBasicAttestationSystem(CFDataRef testRootHash
) {
3856 CFMutableDictionaryRef options
= NULL
;
3857 SecPolicyRef result
= NULL
;
3859 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3860 &kCFTypeDictionaryKeyCallBacks
,
3861 &kCFTypeDictionaryValueCallBacks
), errOut
);
3862 /* BAA certs expire */
3863 SecPolicyAddBasicX509Options(options
);
3865 /* Anchored to one of the Basic Attestation roots. Allow alternative root for developers */
3866 SecPolicyAddAnchorSHA256Options(options
, BASystemRootCA_SHA256
);
3867 if (testRootHash
&& SecIsInternalRelease() && (kSecPolicySHA256Size
== CFDataGetLength(testRootHash
))) {
3868 add_element(options
, kSecPolicyCheckAnchorSHA256
, testRootHash
);
3871 /* Exactly 3 certs in the chain */
3872 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3874 require(result
= SecPolicyCreate(kSecPolicyAppleBasicAttestationSystem
,
3875 kSecPolicyNameBasicAttestationSystem
, options
), errOut
);
3878 CFReleaseSafe(options
);
3882 SecPolicyRef
SecPolicyCreateAppleBasicAttestationUser(CFDataRef testRootHash
) {
3883 CFMutableDictionaryRef options
= NULL
;
3884 SecPolicyRef result
= NULL
;
3886 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3887 &kCFTypeDictionaryKeyCallBacks
,
3888 &kCFTypeDictionaryValueCallBacks
), errOut
);
3889 /* BAA certs expire */
3890 SecPolicyAddBasicX509Options(options
);
3892 /* Anchored to one of the Basic Attestation roots. Allow alternative root for developers */
3893 SecPolicyAddAnchorSHA256Options(options
, BAUserRootCA_SHA256
);
3894 if (testRootHash
&& SecIsInternalRelease() && (kSecPolicySHA256Size
== CFDataGetLength(testRootHash
))) {
3895 add_element(options
, kSecPolicyCheckAnchorSHA256
, testRootHash
);
3898 /* Exactly 3 certs in the chain */
3899 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3901 require(result
= SecPolicyCreate(kSecPolicyAppleBasicAttestationUser
,
3902 kSecPolicyNameBasicAttestationUser
, options
), errOut
);
3905 CFReleaseSafe(options
);
3909 SecPolicyRef
SecPolicyCreateiAPSWAuthWithExpiration(bool checkExpiration
) {
3910 CFMutableDictionaryRef options
= NULL
;
3911 SecPolicyRef result
= NULL
;
3913 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3914 &kCFTypeDictionaryKeyCallBacks
,
3915 &kCFTypeDictionaryValueCallBacks
), errOut
);
3917 /* iAP checks expiration on developement certs, but not on production certs */
3918 if (checkExpiration
) {
3919 SecPolicyAddBasicX509Options(options
);
3921 SecPolicyAddBasicCertOptions(options
);
3924 /* Exactly 2 certs in the chain */
3925 require(SecPolicyAddChainLengthOptions(options
, 2), errOut
);
3927 /* iAP SW Auth General Capabilities Extension present */
3928 add_element(options
, kSecPolicyCheckLeafMarkerOidWithoutValueCheck
, CFSTR("1.2.840.113635.100.6.59.1"));
3930 require(result
= SecPolicyCreate(kSecPolicyAppleiAPSWAuth
,
3931 kSecPolicyNameiAPSWAuth
, options
), errOut
);
3934 CFReleaseSafe(options
);
3938 SecPolicyRef
SecPolicyCreateiAPSWAuth(void) {
3939 /* By default, iAP SW Auth certs don't expire */
3940 return SecPolicyCreateiAPSWAuthWithExpiration(false);
3943 SecPolicyRef
SecPolicyCreateDemoDigitalCatalogSigning(void) {
3944 CFMutableDictionaryRef options
= NULL
;
3945 SecPolicyRef result
= NULL
;
3947 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3948 &kCFTypeDictionaryKeyCallBacks
,
3949 &kCFTypeDictionaryValueCallBacks
), errOut
);
3950 SecPolicyAddBasicX509Options(options
);
3952 /* Exactly 3 certs in the chain */
3953 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3955 /* Demo Signing Extension present in leaf */
3956 add_element(options
, kSecPolicyCheckLeafMarkerOid
, CFSTR("1.2.840.113635.100.6.60"));
3958 /* Issuer common name is "DemoUnit CA" */
3959 add_element(options
, kSecPolicyCheckIssuerCommonName
, CFSTR("DemoUnit CA"));
3961 require(result
= SecPolicyCreate(kSecPolicyAppleDemoDigitalCatalog
,
3962 kSecPolicyNameDemoDigitalCatalog
, options
), errOut
);
3965 CFReleaseSafe(options
);
3969 SecPolicyRef
SecPolicyCreateAppleAssetReceipt(void) {
3970 CFMutableDictionaryRef options
= NULL
;
3971 SecPolicyRef result
= NULL
;
3973 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3974 &kCFTypeDictionaryKeyCallBacks
,
3975 &kCFTypeDictionaryValueCallBacks
), errOut
);
3977 /* No expiration check. */
3978 SecPolicyAddBasicCertOptions(options
);
3981 require_quiet(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameAssetReceipt
), errOut
);
3983 /* Exactly 3 certs in the chain */
3984 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3986 /* Intermediate marker OID is Apple System Integration 2 CA */
3987 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.10"));
3989 /* Leaf marker OID is the Asset Receipt OID */
3990 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.61"));
3992 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
3993 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
3995 require(result
= SecPolicyCreate(kSecPolicyAppleAssetReceipt
,
3996 kSecPolicyNameAssetReceipt
, options
), errOut
);
3999 CFReleaseNull(options
);
4003 SecPolicyRef
SecPolicyCreateAppleDeveloperIDPlusTicket(void) {
4004 CFMutableDictionaryRef options
= NULL
;
4005 SecPolicyRef result
= NULL
;
4007 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
4008 &kCFTypeDictionaryKeyCallBacks
,
4009 &kCFTypeDictionaryValueCallBacks
), errOut
);
4011 /* No expiration check. */
4012 SecPolicyAddBasicCertOptions(options
);
4015 require_quiet(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameDeveloperIDPlusTicket
), errOut
);
4017 /* Exactly 3 certs in the chain */
4018 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
4020 /* Intermediate marker OID is Apple System Integration CA 4 */
4021 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.17"));
4023 /* Leaf marker OID is the Developer ID+ Ticket OID */
4024 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.30"));
4026 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
4027 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
4029 require(result
= SecPolicyCreate(kSecPolicyAppleDeveloperIDPlusTicket
,
4030 kSecPolicyNameDeveloperIDPlusTicket
, options
), errOut
);
4033 CFReleaseNull(options
);
4037 SecPolicyRef
SecPolicyCreateAppleFDRProvisioning(void) {
4038 CFMutableDictionaryRef options
= NULL
;
4039 SecPolicyRef result
= NULL
;
4041 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
4042 &kCFTypeDictionaryKeyCallBacks
,
4043 &kCFTypeDictionaryValueCallBacks
), errOut
);
4045 /* No expiration check. */
4046 SecPolicyAddBasicCertOptions(options
);
4048 require(result
= SecPolicyCreate(kSecPolicyAppleFDRProvisioning
,
4049 kSecPolicyNameFDRProvisioning
, options
), errOut
);
4051 CFReleaseNull(options
);