2 * Copyright (c) 2007-2017 Apple Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
25 * SecPolicy.c - Implementation of various X.509 certificate trust policies
28 #include <Security/SecPolicyInternal.h>
29 #include <Security/SecPolicyPriv.h>
30 #include <AssertMacros.h>
32 #include <utilities/debugging.h>
33 #include <Security/SecInternal.h>
34 #include <CoreFoundation/CFDictionary.h>
35 #include <CoreFoundation/CFNumber.h>
36 #include <CoreFoundation/CFRuntime.h>
37 #include <CoreFoundation/CFString.h>
38 #include <CoreFoundation/CFTimeZone.h>
39 #include <Security/SecCertificateInternal.h>
40 #include <Security/SecCertificatePriv.h>
41 #include <Security/SecItem.h>
42 #include <libDER/oids.h>
43 #include <utilities/SecCFError.h>
44 #include <utilities/SecCFWrappers.h>
45 #include <utilities/array_size.h>
46 #include <ipc/securityd_client.h>
48 #include <utilities/SecInternalReleasePriv.h>
50 #undef POLICYCHECKMACRO
51 #define POLICYCHECKMACRO(NAME, TRUSTRESULT, SUBTYPE, LEAFCHECK, PATHCHECK, LEAFONLY, CSSMERR, OSSTATUS) \
52 const CFStringRef kSecPolicyCheck##NAME = CFSTR(#NAME);
53 #include "SecPolicyChecks.list"
55 #define SEC_CONST_DECL(k,v) const CFStringRef k = CFSTR(v);
57 /********************************************************
58 ******************* Feature toggles ********************
59 ********************************************************/
60 /* Option for AnchorApple */
61 SEC_CONST_DECL (kSecPolicyAppleAnchorIncludeTestRoots
, "AnchorAppleTestRoots");
63 /* options for kSecPolicyCheckLeafMarkersProdAndQA */
64 SEC_CONST_DECL (kSecPolicyLeafMarkerProd
, "ProdMarker");
65 SEC_CONST_DECL (kSecPolicyLeafMarkerQA
, "QAMarker");
67 /* Revocation toggles */
68 SEC_CONST_DECL (kSecPolicyCheckRevocationOCSP
, "OCSP");
69 SEC_CONST_DECL (kSecPolicyCheckRevocationCRL
, "CRL");
70 SEC_CONST_DECL (kSecPolicyCheckRevocationAny
, "AnyRevocationMethod");
72 /* Public policy oids. */
73 #define POLICYMACRO(NAME, OID, ISPUBLIC, INTNAME, IN_NAME, IN_PROPERTIES, FUNCTION) \
74 const CFStringRef kSecPolicyApple##NAME = CFSTR("1.2.840.113635.100.1."#OID);
75 #include "SecPolicy.list"
76 //Some naming exceptions
77 SEC_CONST_DECL(kSecPolicyMacAppStoreReceipt
, "1.2.840.113635.100.1.19")
78 SEC_CONST_DECL(kSecPolicyAppleIDValidationRecordSigningPolicy
, "1.2.840.113635.100.1.30");
80 SEC_CONST_DECL (kSecPolicyOid
, "SecPolicyOid");
81 SEC_CONST_DECL (kSecPolicyName
, "SecPolicyName");
82 SEC_CONST_DECL (kSecPolicyClient
, "SecPolicyClient");
83 SEC_CONST_DECL (kSecPolicyRevocationFlags
, "SecPolicyRevocationFlags");
84 SEC_CONST_DECL (kSecPolicyTeamIdentifier
, "SecPolicyTeamIdentifier");
85 SEC_CONST_DECL (kSecPolicyContext
, "SecPolicyContext");
86 SEC_CONST_DECL (kSecPolicyPolicyName
, "SecPolicyPolicyName");
87 SEC_CONST_DECL (kSecPolicyIntermediateMarkerOid
, "SecPolicyIntermediateMarkerOid");
88 SEC_CONST_DECL (kSecPolicyLeafMarkerOid
, "SecPolicyLeafMarkerOid");
89 SEC_CONST_DECL (kSecPolicyRootDigest
, "SecPolicyRootDigest");
91 SEC_CONST_DECL (kSecPolicyKU_DigitalSignature
, "CE_KU_DigitalSignature");
92 SEC_CONST_DECL (kSecPolicyKU_NonRepudiation
, "CE_KU_NonRepudiation");
93 SEC_CONST_DECL (kSecPolicyKU_KeyEncipherment
, "CE_KU_KeyEncipherment");
94 SEC_CONST_DECL (kSecPolicyKU_DataEncipherment
, "CE_KU_DataEncipherment");
95 SEC_CONST_DECL (kSecPolicyKU_KeyAgreement
, "CE_KU_KeyAgreement");
96 SEC_CONST_DECL (kSecPolicyKU_KeyCertSign
, "CE_KU_KeyCertSign");
97 SEC_CONST_DECL (kSecPolicyKU_CRLSign
, "CE_KU_CRLSign");
98 SEC_CONST_DECL (kSecPolicyKU_EncipherOnly
, "CE_KU_EncipherOnly");
99 SEC_CONST_DECL (kSecPolicyKU_DecipherOnly
, "CE_KU_DecipherOnly");
101 /* Internal policy names */
103 #define __P_DO_DECLARE_(NAME, INTNAME) static CFStringRef kSecPolicyName##NAME = CFSTR(#INTNAME);
104 #define __P_DO_DECLARE_P(NAME, INTNAME) const CFStringRef kSecPolicyNameApple##NAME = CFSTR(#INTNAME);
105 #define __P_DO_DECLARE_I(NAME, INTNAME) const CFStringRef kSecPolicyName##NAME = CFSTR(#INTNAME);
106 #define POLICYMACRO(NAME, OID, ISPUBLIC, INTNAME, IN_NAME, IN_PROPERTIES, FUNCTION) \
107 __P_DO_DECLARE_##ISPUBLIC(NAME, INTNAME)
108 #include "SecPolicy.list"
109 //Some naming exceptions
110 static CFStringRef kSecPolicyNameAppleIDSBag
= CFSTR("IDSBag");
112 /* External Policy Names
113 * These correspond to the names defined in CertificatePinning.plist
114 * in security_certificates */
115 SEC_CONST_DECL (kSecPolicyNameSSLServer
, "sslServer");
116 SEC_CONST_DECL (kSecPolicyNameSSLClient
, "sslClient");
117 SEC_CONST_DECL (kSecPolicyNameEAPServer
, "eapServer");
118 SEC_CONST_DECL (kSecPolicyNameEAPClient
, "eapClient");
119 SEC_CONST_DECL (kSecPolicyNameIPSecServer
, "ipsecServer");
120 SEC_CONST_DECL (kSecPolicyNameIPSecClient
, "ipsecClient");
121 SEC_CONST_DECL (kSecPolicyNameAppleiCloudSetupService
, "iCloudSetup");
122 SEC_CONST_DECL (kSecPolicyNameAppleMMCSService
, "MMCS");
123 SEC_CONST_DECL (kSecPolicyNameAppleAST2Service
, "AST2");
124 SEC_CONST_DECL (kSecPolicyNameAppleEscrowProxyService
, "Escrow");
125 SEC_CONST_DECL (kSecPolicyNameAppleFMiPService
, "FMiP");
126 SEC_CONST_DECL (kSecPolicyNameAppleHomeKitService
, "HomeKit");
127 SEC_CONST_DECL (kSecPolicyNameAppleAIDCService
, "AIDC");
128 SEC_CONST_DECL (kSecPolicyNameAppleMapsService
, "Maps");
129 SEC_CONST_DECL (kSecPolicyNameAppleHealthProviderService
, "HealthProvider");
130 SEC_CONST_DECL (kSecPolicyNameAppleParsecService
, "Parsec");
132 #define kSecPolicySHA1Size 20
133 #define kSecPolicySHA256Size 32
134 __unused
const UInt8 kAppleCASHA1
[kSecPolicySHA1Size
] = {
135 0x61, 0x1E, 0x5B, 0x66, 0x2C, 0x59, 0x3A, 0x08, 0xFF, 0x58,
136 0xD1, 0x4A, 0xE2, 0x24, 0x52, 0xD1, 0x98, 0xDF, 0x6C, 0x60
139 __unused
static const UInt8 kAppleTESTCASHA1
[kSecPolicySHA1Size
] = {
140 0xbc, 0x30, 0x55, 0xc8, 0xc8, 0xd3, 0x48, 0x3f, 0xf4, 0x8d,
141 0xfe, 0x3d, 0x51, 0x75, 0x31, 0xc9, 0xf4, 0xd7, 0x4a, 0xf7
144 static const UInt8 kITMSCASHA1
[kSecPolicySHA1Size
] = {
145 0x1D, 0x33, 0x42, 0x46, 0x8B, 0x10, 0xBD, 0xE6, 0x45, 0xCE,
146 0x44, 0x6E, 0xBB, 0xE8, 0xF5, 0x03, 0x5D, 0xF8, 0x32, 0x22
149 static const UInt8 kFactoryDeviceCASHA1
[kSecPolicySHA1Size
] = {
150 0xef, 0x68, 0x73, 0x17, 0xa4, 0xf8, 0xf9, 0x4b, 0x7b, 0x21,
151 0xe2, 0x2f, 0x09, 0x8f, 0xfd, 0x6a, 0xae, 0xc0, 0x0d, 0x63
154 static const UInt8 kApplePKISettingsAuthority
[kSecPolicySHA1Size
] = {
155 0x1D, 0x0C, 0xBA, 0xAD, 0x17, 0xFD, 0x7E, 0x9E, 0x9F, 0xF1,
156 0xC9, 0xA2, 0x66, 0x79, 0x60, 0x00, 0x8B, 0xAE, 0x70, 0xB8
159 static const UInt8 kAppleTestPKISettingsAuthority
[kSecPolicySHA1Size
] = {
160 0xDB, 0xBA, 0x25, 0x0B, 0xD8, 0x62, 0x71, 0x87, 0x54, 0x7E,
161 0xD7, 0xEF, 0x11, 0x94, 0x7E, 0x82, 0xE6, 0xD8, 0x1C, 0x9A
164 static const UInt8 kTestAppleRootCA_ECC_SHA1
[kSecPolicySHA1Size
] = {
165 0x62, 0x0A, 0xED, 0x83, 0xD2, 0x97, 0x4A, 0x77, 0x56, 0x33,
166 0x83, 0xBE, 0xDB, 0xF9, 0xA1, 0xBD, 0x5F, 0xFE, 0x55, 0x7B
169 __unused
static const UInt8 kAppleRootCA_ECC_SHA1
[kSecPolicySHA1Size
] = {
170 0xB5, 0x2C, 0xB0, 0x2F, 0xD5, 0x67, 0xE0, 0x35, 0x9F, 0xE8,
171 0xFA, 0x4D, 0x4C, 0x41, 0x03, 0x79, 0x70, 0xFE, 0x01, 0xB0
176 /********************************************************
177 ****************** SecPolicy object ********************
178 ********************************************************/
180 static void SecPolicyDestroy(CFTypeRef cf
) {
181 SecPolicyRef policy
= (SecPolicyRef
) cf
;
182 CFRelease(policy
->_oid
);
183 CFReleaseSafe(policy
->_name
);
184 CFRelease(policy
->_options
);
187 static Boolean
SecPolicyCompare(CFTypeRef cf1
, CFTypeRef cf2
) {
188 SecPolicyRef policy1
= (SecPolicyRef
) cf1
;
189 SecPolicyRef policy2
= (SecPolicyRef
) cf2
;
190 if (policy1
->_name
&& policy2
->_name
) {
191 return CFEqual(policy1
->_oid
, policy2
->_oid
) &&
192 CFEqual(policy1
->_name
, policy2
->_name
) &&
193 CFEqual(policy1
->_options
, policy2
->_options
);
195 return CFEqual(policy1
->_oid
, policy2
->_oid
) &&
196 CFEqual(policy1
->_options
, policy2
->_options
);
200 static CFHashCode
SecPolicyHash(CFTypeRef cf
) {
201 SecPolicyRef policy
= (SecPolicyRef
) cf
;
203 return CFHash(policy
->_oid
) + CFHash(policy
->_name
) + CFHash(policy
->_options
);
205 return CFHash(policy
->_oid
) + CFHash(policy
->_options
);
209 static CFStringRef
SecPolicyCopyFormatDescription(CFTypeRef cf
, CFDictionaryRef formatOptions
) {
210 SecPolicyRef policy
= (SecPolicyRef
) cf
;
211 CFMutableStringRef desc
= CFStringCreateMutable(kCFAllocatorDefault
, 0);
212 CFStringRef typeStr
= CFCopyTypeIDDescription(CFGetTypeID(cf
));
213 CFStringAppendFormat(desc
, NULL
,
214 CFSTR("<%@: oid: %@ name: %@ options %@"), typeStr
,
215 policy
->_oid
, (policy
->_name
) ? policy
->_name
: CFSTR(""),
218 CFStringAppend(desc
, CFSTR(" >"));
223 /* SecPolicy API functions. */
224 CFGiblisWithHashFor(SecPolicy
);
226 /* AUDIT[securityd](done):
227 oid (ok) is a caller provided string, only its cf type has been checked.
228 options is a caller provided dictionary, only its cf type has been checked.
230 SecPolicyRef
SecPolicyCreate(CFStringRef oid
, CFStringRef name
, CFDictionaryRef options
) {
231 SecPolicyRef result
= NULL
;
233 require(oid
, errOut
);
234 require(options
, errOut
);
236 (SecPolicyRef
)_CFRuntimeCreateInstance(kCFAllocatorDefault
,
237 SecPolicyGetTypeID(),
238 sizeof(struct __SecPolicy
) - sizeof(CFRuntimeBase
), 0), errOut
);
243 result
->_name
= name
;
245 result
->_options
= options
;
252 static void set_ku_from_properties(SecPolicyRef policy
, CFDictionaryRef properties
);
255 SecPolicyRef
SecPolicyCreateWithProperties(CFTypeRef policyIdentifier
,
256 CFDictionaryRef properties
) {
257 // Creates a policy reference for a given policy object identifier.
258 // If policy-specific parameters can be supplied (e.g. hostname),
259 // attempt to obtain from input properties dictionary.
260 // Returns NULL if the given identifier is unsupported.
262 SecPolicyRef policy
= NULL
;
263 CFTypeRef name
= NULL
;
264 CFStringRef teamID
= NULL
;
265 Boolean client
= false;
266 CFDictionaryRef context
= NULL
;
267 CFStringRef policyName
= NULL
, intermediateMarkerOid
= NULL
, leafMarkerOid
= NULL
;
268 CFDataRef rootDigest
= NULL
;
269 require(policyIdentifier
&& (CFStringGetTypeID() == CFGetTypeID(policyIdentifier
)), errOut
);
272 name
= CFDictionaryGetValue(properties
, kSecPolicyName
);
273 teamID
= CFDictionaryGetValue(properties
, kSecPolicyTeamIdentifier
);
275 CFBooleanRef dictionaryClientValue
;
276 client
= (CFDictionaryGetValueIfPresent(properties
, kSecPolicyClient
, (const void **)&dictionaryClientValue
) &&
277 (dictionaryClientValue
!= NULL
) && CFEqual(kCFBooleanTrue
, dictionaryClientValue
));
278 context
= CFDictionaryGetValue(properties
, kSecPolicyContext
);
279 policyName
= CFDictionaryGetValue(properties
, kSecPolicyPolicyName
);
280 intermediateMarkerOid
= CFDictionaryGetValue(properties
, kSecPolicyIntermediateMarkerOid
);
281 leafMarkerOid
= CFDictionaryGetValue(properties
, kSecPolicyLeafMarkerOid
);
282 rootDigest
= CFDictionaryGetValue(properties
, kSecPolicyRootDigest
);
285 /* only the EAP policy allows a non-string name */
286 if (name
&& !isString(name
) && !CFEqual(policyIdentifier
, kSecPolicyAppleEAP
)) {
287 secerror("policy \"%@\" requires a string value for the %@ key", policyIdentifier
, kSecPolicyName
);
291 /* What follows are all the exceptional functions that do not match the macro below */
292 if (CFEqual(policyIdentifier
, kSecPolicyAppleSSL
)) {
293 policy
= SecPolicyCreateSSL(!client
, name
);
294 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleSMIME
)) {
295 policy
= SecPolicyCreateSMIME(kSecSignSMIMEUsage
| kSecAnyEncryptSMIME
, name
);
296 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleEAP
)) {
297 CFArrayRef array
= NULL
;
298 if (isString(name
)) {
299 array
= CFArrayCreate(kCFAllocatorDefault
, (const void **)&name
, 1, &kCFTypeArrayCallBacks
);
300 } else if (isArray(name
)) {
301 array
= CFArrayCreateCopy(NULL
, name
);
303 policy
= SecPolicyCreateEAP(!client
, array
);
304 CFReleaseSafe(array
);
305 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleIPsec
)) {
306 policy
= SecPolicyCreateIPSec(!client
, name
);
307 } else if (CFEqual(policyIdentifier
, kSecPolicyMacAppStoreReceipt
)) {
308 policy
= SecPolicyCreateMacAppStoreReceipt();
309 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleRevocation
)) {
310 policy
= SecPolicyCreateRevocation(kSecRevocationUseAnyAvailableMethod
);
311 } else if (CFEqual(policyIdentifier
, kSecPolicyApplePassbookSigning
)) {
312 policy
= SecPolicyCreatePassbookCardSigner(name
, teamID
);
313 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleAST2DiagnosticsServerAuth
)) {
315 policy
= SecPolicyCreateAppleAST2Service(name
, context
);
317 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier
);
319 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleEscrowProxyServerAuth
)) {
321 policy
= SecPolicyCreateAppleEscrowProxyService(name
, context
);
323 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier
);
325 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleFMiPServerAuth
)) {
327 policy
= SecPolicyCreateAppleFMiPService(name
, context
);
329 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier
);
331 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleMMCService
)) {
333 policy
= SecPolicyCreateAppleMMCSService(name
, context
);
335 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier
);
337 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleGSService
)) {
339 policy
= SecPolicyCreateAppleGSService(name
, context
);
341 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier
);
343 } else if (CFEqual(policyIdentifier
, kSecPolicyApplePPQService
)) {
345 policy
= SecPolicyCreateApplePPQService(name
, context
);
347 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier
);
349 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleGenericApplePinned
)) {
351 policy
= SecPolicyCreateApplePinned(policyName
, intermediateMarkerOid
, leafMarkerOid
);
353 secerror("policy \"%@\" requires kSecPolicyPolicyName input", policyIdentifier
);
355 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleGenericAppleSSLPinned
)) {
357 policy
= SecPolicyCreateAppleSSLPinned(policyName
, name
, intermediateMarkerOid
, leafMarkerOid
);
359 secerror("policy \"%@\" requires kSecPolicyPolicyName input", policyIdentifier
);
361 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleIDSServiceContext
)) {
363 policy
= SecPolicyCreateAppleIDSServiceContext(name
, context
);
365 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier
);
367 } else if (CFEqual(policyIdentifier
, kSecPolicyApplePushService
)) {
369 policy
= SecPolicyCreateApplePushService(name
, context
);
371 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier
);
373 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleUniqueDeviceIdentifierCertificate
)) {
374 policy
= SecPolicyCreateAppleUniqueDeviceCertificate(rootDigest
);
375 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleiCloudSetupServerAuth
)) {
377 policy
= SecPolicyCreateAppleiCloudSetupService(name
, context
);
379 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier
);
381 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleBasicAttestationSystem
)) {
382 policy
= SecPolicyCreateAppleBasicAttestationSystem(rootDigest
);
383 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleBasicAttestationUser
)) {
384 policy
= SecPolicyCreateAppleBasicAttestationUser(rootDigest
);
386 /* For a couple of common patterns we use the macro */
388 #define _P_OPTION_N name
389 #define _P_PROPERTIES_(NAME, IN_NAME, FUNCTION)
390 #define _P_PROPERTIES_Y(NAME, IN_NAME, FUNCTION) else if (CFEqual(policyIdentifier, kSecPolicyApple##NAME)) { \
391 policy = SecPolicyCreate##FUNCTION(_P_OPTION_##IN_NAME); \
394 #define POLICYMACRO(NAME, OID, ISPUBLIC, INTNAME, IN_NAME, IN_PROPERTIES, FUNCTION) \
395 _P_PROPERTIES_##IN_PROPERTIES(NAME, IN_NAME, FUNCTION)
396 #include "SecPolicy.list"
398 secerror("ERROR: policy \"%@\" is unsupported", policyIdentifier
);
406 set_ku_from_properties(policy
, properties
);
410 SecPolicySetName(policy
, policyName
);
417 CFDictionaryRef
SecPolicyCopyProperties(SecPolicyRef policyRef
) {
418 // Builds and returns a dictionary which the caller must release.
420 #pragma clang diagnostic push
421 #pragma clang diagnostic ignored "-Wnonnull"
422 // After introducing nullability annotations, policyRef is supposed to be nonnull, suppress the warning
423 if (!policyRef
) return NULL
;
424 #pragma clang diagnostic pop
425 CFMutableDictionaryRef properties
= CFDictionaryCreateMutable(NULL
, 0,
426 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
427 #pragma clang diagnostic push
428 #pragma clang diagnostic ignored "-Wnonnull"
429 // 'properties' is nonnull in reality suppress the warning
430 if (!properties
) return NULL
;
431 #pragma clang diagnostic pop
432 CFStringRef oid
= (CFStringRef
) CFRetain(policyRef
->_oid
);
433 CFTypeRef nameKey
= NULL
;
435 // Determine name key
436 if (policyRef
->_options
) {
437 if (CFDictionaryContainsKey(policyRef
->_options
, kSecPolicyCheckSSLHostname
)) {
438 nameKey
= kSecPolicyCheckSSLHostname
;
439 } else if (CFDictionaryContainsKey(policyRef
->_options
, kSecPolicyCheckEAPTrustedServerNames
)) {
440 nameKey
= kSecPolicyCheckEAPTrustedServerNames
;
441 } else if (CFDictionaryContainsKey(policyRef
->_options
, kSecPolicyCheckEmail
)) {
442 nameKey
= kSecPolicyCheckEmail
;
447 CFDictionarySetValue(properties
, (const void *)kSecPolicyOid
,
450 // Set kSecPolicyName if we have one
451 if (nameKey
&& policyRef
->_options
) {
452 CFTypeRef name
= (CFTypeRef
) CFDictionaryGetValue(policyRef
->_options
,
455 CFDictionarySetValue(properties
, (const void *)kSecPolicyName
,
460 // Set kSecPolicyClient
461 CFStringRef policyName
= (CFStringRef
) CFRetainSafe(policyRef
->_name
);
462 if (policyName
&& (CFEqual(policyName
, kSecPolicyNameSSLClient
) ||
463 CFEqual(policyName
, kSecPolicyNameIPSecClient
) ||
464 CFEqual(policyName
, kSecPolicyNameEAPClient
))) {
465 CFDictionarySetValue(properties
, (const void *)kSecPolicyClient
,
466 (const void *)kCFBooleanTrue
);
473 static void SecPolicySetOid(SecPolicyRef policy
, CFStringRef oid
) {
474 if (!policy
|| !oid
) return;
475 CFStringRef temp
= policy
->_oid
;
481 void SecPolicySetName(SecPolicyRef policy
, CFStringRef policyName
) {
482 if (!policy
|| !policyName
) return;
483 CFStringRef temp
= policy
->_name
;
484 CFRetain(policyName
);
485 policy
->_name
= policyName
;
489 CFStringRef
SecPolicyGetOidString(SecPolicyRef policy
) {
493 CFStringRef
SecPolicyGetName(SecPolicyRef policy
) {
494 return policy
->_name
;
497 CFDictionaryRef
SecPolicyGetOptions(SecPolicyRef policy
) {
498 return policy
->_options
;
501 void SecPolicySetOptionsValue(SecPolicyRef policy
, CFStringRef key
, CFTypeRef value
) {
502 if (!policy
|| !key
) return;
503 CFMutableDictionaryRef options
= (CFMutableDictionaryRef
) policy
->_options
;
505 options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
506 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
507 if (!options
) return;
508 policy
->_options
= options
;
510 CFDictionarySetValue(options
, key
, value
);
513 /* Local forward declaration */
514 static void set_ssl_ekus(CFMutableDictionaryRef options
, bool server
);
517 // this is declared as NA for iPhone in SecPolicy.h, so declare here
518 OSStatus
SecPolicySetProperties(SecPolicyRef policyRef
, CFDictionaryRef properties
);
521 OSStatus
SecPolicySetProperties(SecPolicyRef policyRef
, CFDictionaryRef properties
) {
522 // Set policy options based on the provided dictionary keys.
524 if (!(policyRef
&& properties
&& (CFDictionaryGetTypeID() == CFGetTypeID(properties
)))) {
527 CFStringRef oid
= (CFStringRef
) CFRetain(policyRef
->_oid
);
528 OSStatus result
= errSecSuccess
;
531 CFTypeRef name
= NULL
;
532 if (CFDictionaryGetValueIfPresent(properties
, (const void *)kSecPolicyName
,
533 (const void **)&name
) && name
) {
534 CFTypeID typeID
= CFGetTypeID(name
);
535 if (CFEqual(oid
, kSecPolicyAppleSSL
) ||
536 CFEqual(oid
, kSecPolicyAppleIPsec
)) {
537 if (CFStringGetTypeID() == typeID
) {
538 SecPolicySetOptionsValue(policyRef
, kSecPolicyCheckSSLHostname
, name
);
540 else result
= errSecParam
;
542 else if (CFEqual(oid
, kSecPolicyAppleEAP
)) {
543 if ((CFStringGetTypeID() == typeID
) ||
544 (CFArrayGetTypeID() == typeID
)) {
545 SecPolicySetOptionsValue(policyRef
, kSecPolicyCheckEAPTrustedServerNames
, name
);
547 else result
= errSecParam
;
549 else if (CFEqual(oid
, kSecPolicyAppleSMIME
)) {
550 if (CFStringGetTypeID() == typeID
) {
551 SecPolicySetOptionsValue(policyRef
, kSecPolicyCheckEmail
, name
);
553 else result
= errSecParam
;
558 CFTypeRef client
= NULL
;
559 if (CFDictionaryGetValueIfPresent(properties
, (const void *)kSecPolicyClient
,
560 (const void **)&client
) && client
) {
561 if (!(CFBooleanGetTypeID() == CFGetTypeID(client
))) {
562 result
= errSecParam
;
564 else if (CFEqual(client
, kCFBooleanTrue
)) {
565 if (CFEqual(oid
, kSecPolicyAppleSSL
)) {
566 SecPolicySetName(policyRef
, kSecPolicyNameSSLClient
);
567 /* Set EKU checks for clients */
568 CFMutableDictionaryRef newOptions
= CFDictionaryCreateMutableCopy(NULL
, 0, policyRef
->_options
);
569 set_ssl_ekus(newOptions
, false);
570 CFReleaseSafe(policyRef
->_options
);
571 policyRef
->_options
= newOptions
;
573 else if (CFEqual(oid
, kSecPolicyAppleIPsec
)) {
574 SecPolicySetName(policyRef
, kSecPolicyNameIPSecClient
);
576 else if (CFEqual(oid
, kSecPolicyNameEAPServer
)) {
577 SecPolicySetName(policyRef
, kSecPolicyNameEAPClient
);
578 /* Set EKU checks for clients */
579 CFMutableDictionaryRef newOptions
= CFDictionaryCreateMutableCopy(NULL
, 0, policyRef
->_options
);
580 set_ssl_ekus(newOptions
, false);
581 CFReleaseSafe(policyRef
->_options
);
582 policyRef
->_options
= newOptions
;
586 if (CFEqual(oid
, kSecPolicyAppleSSL
)) {
587 SecPolicySetName(policyRef
, kSecPolicyNameSSLServer
);
588 /* Set EKU checks for servers */
589 CFMutableDictionaryRef newOptions
= CFDictionaryCreateMutableCopy(NULL
, 0, policyRef
->_options
);
590 set_ssl_ekus(newOptions
, true);
591 CFReleaseSafe(policyRef
->_options
);
592 policyRef
->_options
= newOptions
;
594 else if (CFEqual(oid
, kSecPolicyAppleIPsec
)) {
595 SecPolicySetName(policyRef
, kSecPolicyNameIPSecServer
);
597 else if (CFEqual(oid
, kSecPolicyAppleEAP
)) {
598 SecPolicySetName(policyRef
, kSecPolicyNameEAPServer
);
599 /* Set EKU checks for servers */
600 CFMutableDictionaryRef newOptions
= CFDictionaryCreateMutableCopy(NULL
, 0, policyRef
->_options
);
601 set_ssl_ekus(newOptions
, true);
602 CFReleaseSafe(policyRef
->_options
);
603 policyRef
->_options
= newOptions
;
609 set_ku_from_properties(policyRef
, properties
);
615 static xpc_object_t
copy_xpc_policy_object(SecPolicyRef policy
);
616 static bool append_policy_to_xpc_array(SecPolicyRef policy
, xpc_object_t xpc_policies
);
617 extern xpc_object_t
copy_xpc_policies_array(CFArrayRef policies
);
618 extern OSStatus
validate_array_of_items(CFArrayRef array
, CFStringRef arrayItemType
, CFTypeID itemTypeID
, bool required
);
620 static xpc_object_t
copy_xpc_policy_object(SecPolicyRef policy
) {
621 xpc_object_t xpc_policy
= NULL
;
622 xpc_object_t data
[2] = { NULL
, NULL
};
623 if (policy
->_oid
&& (CFGetTypeID(policy
->_oid
) == CFStringGetTypeID()) &&
624 policy
->_name
&& (CFGetTypeID(policy
->_name
) == CFStringGetTypeID())) {
625 /* These should really be different elements of the xpc array. But
626 * SecPolicyCreateWithXPCObject previously checked the size via ==, which prevents
627 * us from appending new information while maintaining backward compatibility.
628 * Doing this makes the builders happy. */
629 CFMutableStringRef oidAndName
= NULL
;
630 oidAndName
= CFStringCreateMutableCopy(NULL
, 0, policy
->_oid
);
632 CFStringAppend(oidAndName
, CFSTR("++"));
633 CFStringAppend(oidAndName
, policy
->_name
);
634 data
[0] = _CFXPCCreateXPCObjectFromCFObject(oidAndName
);
635 CFReleaseNull(oidAndName
);
637 data
[0] = _CFXPCCreateXPCObjectFromCFObject(policy
->_oid
);
639 } else if (policy
->_oid
&& (CFGetTypeID(policy
->_oid
) == CFStringGetTypeID())) {
640 data
[0] = _CFXPCCreateXPCObjectFromCFObject(policy
->_oid
);
642 secerror("policy 0x%lX has no _oid", (uintptr_t)policy
);
644 if (policy
->_options
&& (CFGetTypeID(policy
->_options
) == CFDictionaryGetTypeID())) {
645 data
[1] = _CFXPCCreateXPCObjectFromCFObject(policy
->_options
);
647 secerror("policy 0x%lX has no _options", (uintptr_t)policy
);
649 xpc_policy
= xpc_array_create(data
, array_size(data
));
650 if (data
[0]) xpc_release(data
[0]);
651 if (data
[1]) xpc_release(data
[1]);
655 static bool append_policy_to_xpc_array(SecPolicyRef policy
, xpc_object_t xpc_policies
) {
659 xpc_object_t xpc_policy
= copy_xpc_policy_object(policy
);
663 xpc_array_append_value(xpc_policies
, xpc_policy
);
664 xpc_release(xpc_policy
);
668 xpc_object_t
copy_xpc_policies_array(CFArrayRef policies
) {
669 xpc_object_t xpc_policies
= xpc_array_create(NULL
, 0);
673 validate_array_of_items(policies
, CFSTR("policy"), SecPolicyGetTypeID(), true);
674 CFIndex ix
, count
= CFArrayGetCount(policies
);
675 for (ix
= 0; ix
< count
; ++ix
) {
676 SecPolicyRef policy
= (SecPolicyRef
) CFArrayGetValueAtIndex(policies
, ix
);
677 #if SECTRUST_VERBOSE_DEBUG
678 CFDictionaryRef props
= SecPolicyCopyProperties(policy
);
679 secerror("idx=%d of %d; policy=0x%lX properties=%@", (int)ix
, (int)count
, (uintptr_t)policy
, props
);
680 CFReleaseSafe(props
);
682 if (!append_policy_to_xpc_array(policy
, xpc_policies
)) {
683 xpc_release(xpc_policies
);
691 static xpc_object_t
SecPolicyCopyXPCObject(SecPolicyRef policy
, CFErrorRef
*error
) {
692 xpc_object_t xpc_policy
= NULL
;
693 xpc_object_t data
[2] = {};
694 CFMutableStringRef oidAndName
= NULL
;
695 oidAndName
= CFStringCreateMutableCopy(NULL
, 0, policy
->_oid
);
698 CFStringAppend(oidAndName
, CFSTR("++"));
699 CFStringAppend(oidAndName
, policy
->_name
);
702 require_action_quiet(data
[0] = _CFXPCCreateXPCObjectFromCFObject(oidAndName
), exit
,
703 SecError(errSecParam
, error
,
704 CFSTR("failed to create xpc_object from policy oid and name")));
706 require_action_quiet(data
[0] = _CFXPCCreateXPCObjectFromCFObject(policy
->_oid
), exit
,
707 SecError(errSecParam
, error
, CFSTR("failed to create xpc_object from policy oid")));
709 require_action_quiet(data
[1] = _CFXPCCreateXPCObjectFromCFObject(policy
->_options
), exit
,
710 SecError(errSecParam
, error
, CFSTR("failed to create xpc_object from policy options")));
711 require_action_quiet(xpc_policy
= xpc_array_create(data
, array_size(data
)), exit
,
712 SecError(errSecAllocate
, error
, CFSTR("failed to create xpc_array for policy")));
715 if (data
[0]) xpc_release(data
[0]);
716 if (data
[1]) xpc_release(data
[1]);
717 CFReleaseNull(oidAndName
);
721 static bool SecPolicyAppendToXPCArray(SecPolicyRef policy
, xpc_object_t policies
, CFErrorRef
*error
) {
725 xpc_object_t xpc_policy
= SecPolicyCopyXPCObject(policy
, error
);
729 xpc_array_append_value(policies
, xpc_policy
);
730 xpc_release(xpc_policy
);
734 xpc_object_t
SecPolicyArrayCopyXPCArray(CFArrayRef policies
, CFErrorRef
*error
) {
735 xpc_object_t xpc_policies
;
736 require_action_quiet(xpc_policies
= xpc_array_create(NULL
, 0), exit
,
737 SecError(errSecAllocate
, error
, CFSTR("failed to create xpc_array")));
738 CFIndex ix
, count
= CFArrayGetCount(policies
);
739 for (ix
= 0; ix
< count
; ++ix
) {
740 if (!SecPolicyAppendToXPCArray((SecPolicyRef
)CFArrayGetValueAtIndex(policies
, ix
), xpc_policies
, error
)) {
741 xpc_release(xpc_policies
);
749 static OSStatus
parseOidAndName(CFStringRef oidAndName
, CFStringRef
*oid
, CFStringRef
*name
) {
750 OSStatus result
= errSecSuccess
;
751 CFStringRef partial
= NULL
;
753 CFRange delimiter
= CFStringFind(oidAndName
, CFSTR("++"), 0);
754 if (delimiter
.length
!= 2) {
758 /* get first half: oid */
759 partial
= CFStringCreateWithSubstring(NULL
, oidAndName
, CFRangeMake(0, delimiter
.location
));
760 if (oid
) { *oid
= CFRetainSafe(partial
); }
761 CFReleaseNull(partial
);
763 /* get second half: name */
764 if (delimiter
.location
+ 2 >= CFStringGetLength(oidAndName
)) {
765 return errSecSuccess
; // name is optional
767 CFRange nameRange
= CFRangeMake(delimiter
.location
+2,
768 CFStringGetLength(oidAndName
) - delimiter
.location
- 2);
769 partial
= CFStringCreateWithSubstring(NULL
, oidAndName
, nameRange
);
770 if (name
) { *name
= CFRetainSafe(partial
); }
771 CFReleaseNull(partial
);
775 static SecPolicyRef
SecPolicyCreateWithXPCObject(xpc_object_t xpc_policy
, CFErrorRef
*error
) {
776 SecPolicyRef policy
= NULL
;
777 CFTypeRef oidAndName
= NULL
;
778 CFStringRef oid
= NULL
;
779 CFStringRef name
= NULL
;
780 CFTypeRef options
= NULL
;
782 require_action_quiet(xpc_policy
, exit
, SecError(errSecParam
, error
, CFSTR("policy xpc value is NULL")));
783 require_action_quiet(xpc_get_type(xpc_policy
) == XPC_TYPE_ARRAY
, exit
, SecError(errSecDecode
, error
, CFSTR("policy xpc value is not an array")));
784 require_action_quiet(xpc_array_get_count(xpc_policy
) >= 2, exit
, SecError(errSecDecode
, error
, CFSTR("policy xpc array count < 2")));
785 oidAndName
= _CFXPCCreateCFObjectFromXPCObject(xpc_array_get_value(xpc_policy
, 0));
786 require_action_quiet(isString(oidAndName
), exit
,
787 SecError(errSecParam
, error
, CFSTR("failed to convert xpc policy[0]=%@ to CFString"), oidAndName
));
788 options
= _CFXPCCreateCFObjectFromXPCObject(xpc_array_get_value(xpc_policy
, 1));
789 require_action_quiet(isDictionary(options
), exit
,
790 SecError(errSecParam
, error
, CFSTR("failed to convert xpc policy[1]=%@ to CFDictionary"), options
));
791 require_noerr_action_quiet(parseOidAndName(oidAndName
, &oid
, &name
), exit
,
792 SecError(errSecParam
, error
, CFSTR("failed to convert combined %@ to name and oid"), oidAndName
));
793 require_action_quiet(policy
= SecPolicyCreate(oid
, name
, options
), exit
,
794 SecError(errSecDecode
, error
, CFSTR("Failed to create policy")));
797 CFReleaseSafe(oidAndName
);
800 CFReleaseSafe(options
);
804 CFArrayRef
SecPolicyXPCArrayCopyArray(xpc_object_t xpc_policies
, CFErrorRef
*error
) {
805 CFMutableArrayRef policies
= NULL
;
806 require_action_quiet(xpc_get_type(xpc_policies
) == XPC_TYPE_ARRAY
, exit
,
807 SecError(errSecParam
, error
, CFSTR("policies xpc value is not an array")));
808 size_t count
= xpc_array_get_count(xpc_policies
);
809 require_action_quiet(policies
= CFArrayCreateMutable(kCFAllocatorDefault
, count
, &kCFTypeArrayCallBacks
), exit
,
810 SecError(errSecAllocate
, error
, CFSTR("failed to create CFArray of capacity %zu"), count
));
813 for (ix
= 0; ix
< count
; ++ix
) {
814 SecPolicyRef policy
= SecPolicyCreateWithXPCObject(xpc_array_get_value(xpc_policies
, ix
), error
);
819 CFArraySetValueAtIndex(policies
, ix
, policy
);
828 static SEC_CONST_DECL (kSecPolicyOptions
, "policyOptions");
830 static SecPolicyRef
SecPolicyCreateWithDictionary(CFDictionaryRef dict
) {
831 SecPolicyRef policy
= NULL
;
832 CFStringRef oid
= (CFStringRef
)CFDictionaryGetValue(dict
, kSecPolicyOid
);
833 require_quiet(isString(oid
), errOut
);
834 CFDictionaryRef options
= (CFDictionaryRef
)CFDictionaryGetValue(dict
, kSecPolicyOptions
);
835 require_quiet(isDictionary(options
), errOut
);
836 CFStringRef name
= (CFStringRef
)CFDictionaryGetValue(dict
, kSecPolicyPolicyName
);
837 policy
= SecPolicyCreate(oid
, name
, options
);
842 static void deserializePolicy(const void *value
, void *context
) {
843 CFDictionaryRef policyDict
= (CFDictionaryRef
)value
;
844 if (isDictionary(policyDict
)) {
845 CFTypeRef deserializedPolicy
= SecPolicyCreateWithDictionary(policyDict
);
846 if (deserializedPolicy
) {
847 CFArrayAppendValue((CFMutableArrayRef
)context
, deserializedPolicy
);
848 CFRelease(deserializedPolicy
);
853 CFArrayRef
SecPolicyArrayCreateDeserialized(CFArrayRef serializedPolicies
) {
854 CFMutableArrayRef result
= NULL
;
855 require_quiet(isArray(serializedPolicies
), errOut
);
856 CFIndex count
= CFArrayGetCount(serializedPolicies
);
857 result
= CFArrayCreateMutable(kCFAllocatorDefault
, count
, &kCFTypeArrayCallBacks
);
858 CFRange all_policies
= { 0, count
};
859 CFArrayApplyFunction(serializedPolicies
, all_policies
, deserializePolicy
, result
);
864 static CFDictionaryRef
SecPolicyCreateDictionary(SecPolicyRef policy
) {
865 CFMutableDictionaryRef dict
= NULL
;
866 dict
= CFDictionaryCreateMutable(NULL
, 3, &kCFTypeDictionaryKeyCallBacks
,
867 &kCFTypeDictionaryValueCallBacks
);
868 CFDictionaryAddValue(dict
, kSecPolicyOid
, policy
->_oid
);
869 CFDictionaryAddValue(dict
, kSecPolicyOptions
, policy
->_options
);
871 CFDictionaryAddValue(dict
, kSecPolicyPolicyName
, policy
->_name
);
876 static void serializePolicy(const void *value
, void *context
) {
877 SecPolicyRef policy
= (SecPolicyRef
)value
;
878 if (policy
&& SecPolicyGetTypeID() == CFGetTypeID(policy
)) {
879 CFDictionaryRef serializedPolicy
= SecPolicyCreateDictionary(policy
);
880 if (serializedPolicy
) {
881 CFArrayAppendValue((CFMutableArrayRef
)context
, serializedPolicy
);
882 CFRelease(serializedPolicy
);
887 CFArrayRef
SecPolicyArrayCreateSerialized(CFArrayRef policies
) {
888 CFMutableArrayRef result
= NULL
;
889 require_quiet(isArray(policies
), errOut
);
890 CFIndex count
= CFArrayGetCount(policies
);
891 result
= CFArrayCreateMutable(NULL
, count
, &kCFTypeArrayCallBacks
);
892 CFRange all_policies
= { 0, count
};
893 CFArrayApplyFunction(policies
, all_policies
, serializePolicy
, result
);
898 static void add_element(CFMutableDictionaryRef options
, CFStringRef key
,
900 CFTypeRef old_value
= CFDictionaryGetValue(options
, key
);
902 CFMutableArrayRef array
;
903 if (CFGetTypeID(old_value
) == CFArrayGetTypeID()) {
904 array
= (CFMutableArrayRef
)old_value
;
906 array
= CFArrayCreateMutable(kCFAllocatorDefault
, 0,
907 &kCFTypeArrayCallBacks
);
908 CFArrayAppendValue(array
, old_value
);
909 CFDictionarySetValue(options
, key
, array
);
912 CFArrayAppendValue(array
, value
);
914 CFDictionaryAddValue(options
, key
, value
);
918 static void add_eku(CFMutableDictionaryRef options
, const DERItem
*ekuOid
) {
919 CFDataRef eku
= CFDataCreate(kCFAllocatorDefault
,
920 ekuOid
? ekuOid
->data
: NULL
,
921 ekuOid
? ekuOid
->length
: 0);
923 add_element(options
, kSecPolicyCheckExtendedKeyUsage
, eku
);
928 static void add_eku_string(CFMutableDictionaryRef options
, CFStringRef ekuOid
) {
930 add_element(options
, kSecPolicyCheckExtendedKeyUsage
, ekuOid
);
934 static void set_ssl_ekus(CFMutableDictionaryRef options
, bool server
) {
935 CFDictionaryRemoveValue(options
, kSecPolicyCheckExtendedKeyUsage
);
937 /* If server and EKU ext present then EKU ext should contain one of
938 ServerAuth or ExtendedKeyUsageAny or NetscapeSGC or MicrosoftSGC.
939 else if !server and EKU ext present then EKU ext should contain one of
940 ClientAuth or ExtendedKeyUsageAny. */
942 /* We always allow certificates that specify oidAnyExtendedKeyUsage. */
943 add_eku(options
, NULL
); /* eku extension is optional */
944 add_eku(options
, &oidAnyExtendedKeyUsage
);
946 add_eku(options
, &oidExtendedKeyUsageServerAuth
);
947 add_eku(options
, &oidExtendedKeyUsageMicrosoftSGC
);
948 add_eku(options
, &oidExtendedKeyUsageNetscapeSGC
);
950 add_eku(options
, &oidExtendedKeyUsageClientAuth
);
954 static void add_ku(CFMutableDictionaryRef options
, SecKeyUsage keyUsage
) {
955 SInt32 dku
= keyUsage
;
956 CFNumberRef ku
= CFNumberCreate(kCFAllocatorDefault
, kCFNumberSInt32Type
,
959 add_element(options
, kSecPolicyCheckKeyUsage
, ku
);
965 static void set_ku_from_properties(SecPolicyRef policy
, CFDictionaryRef properties
) {
966 if (!policy
|| !properties
) {
970 CFStringRef keyNames
[] = { kSecPolicyKU_DigitalSignature
, kSecPolicyKU_NonRepudiation
, kSecPolicyKU_KeyEncipherment
, kSecPolicyKU_DataEncipherment
,
971 kSecPolicyKU_KeyAgreement
, kSecPolicyKU_KeyCertSign
, kSecPolicyKU_CRLSign
, kSecPolicyKU_EncipherOnly
, kSecPolicyKU_DecipherOnly
};
973 uint32_t keyUsageValues
[] = { kSecKeyUsageDigitalSignature
, kSecKeyUsageNonRepudiation
, kSecKeyUsageKeyEncipherment
, kSecKeyUsageDataEncipherment
,
974 kSecKeyUsageKeyAgreement
, kSecKeyUsageKeyCertSign
, kSecKeyUsageCRLSign
, kSecKeyUsageEncipherOnly
, kSecKeyUsageDecipherOnly
};
976 bool haveKeyUsage
= false;
977 CFTypeRef keyUsageBoolean
;
978 for (uint32_t i
= 0; i
< sizeof(keyNames
) / sizeof(CFStringRef
); ++i
) {
979 if (CFDictionaryGetValueIfPresent(properties
, keyNames
[i
], (const void**)&keyUsageBoolean
)) {
980 if (CFEqual(keyUsageBoolean
, kCFBooleanTrue
)) {
991 CFMutableDictionaryRef options
= (CFMutableDictionaryRef
) policy
->_options
;
993 options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
994 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
995 if (!options
) return;
996 policy
->_options
= options
;
998 CFDictionaryRemoveValue(options
, kSecPolicyCheckKeyUsage
);
1001 for (uint32_t i
= 0; i
< sizeof(keyNames
) / sizeof(CFStringRef
); ++i
) {
1002 if (CFDictionaryGetValueIfPresent(properties
, keyNames
[i
], (const void**)&keyUsageBoolean
)) {
1003 if (CFEqual(keyUsageBoolean
, kCFBooleanTrue
)) {
1004 add_ku(options
, keyUsageValues
[i
]);
1011 static void add_oid(CFMutableDictionaryRef options
, CFStringRef policy_key
, const DERItem
*oid
) {
1012 CFDataRef oid_data
= CFDataCreate(kCFAllocatorDefault
,
1013 oid
? oid
->data
: NULL
,
1014 oid
? oid
->length
: 0);
1016 add_element(options
, policy_key
, oid_data
);
1017 CFRelease(oid_data
);
1021 static void add_leaf_marker_value(CFMutableDictionaryRef options
, const DERItem
*markerOid
, CFStringRef string_value
) {
1023 CFTypeRef policyData
= NULL
;
1025 if (NULL
== string_value
) {
1026 policyData
= CFDataCreate(kCFAllocatorDefault
,
1027 markerOid
? markerOid
->data
: NULL
,
1028 markerOid
? markerOid
->length
: 0);
1030 CFStringRef oid_as_string
= SecDERItemCopyOIDDecimalRepresentation(kCFAllocatorDefault
, markerOid
);
1032 const void *key
[1] = { oid_as_string
};
1033 const void *value
[1] = { string_value
};
1034 policyData
= CFDictionaryCreate(kCFAllocatorDefault
,
1036 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
1037 CFReleaseNull(oid_as_string
);
1040 add_element(options
, kSecPolicyCheckLeafMarkerOid
, policyData
);
1042 CFReleaseNull(policyData
);
1046 static void add_leaf_marker(CFMutableDictionaryRef options
, const DERItem
*markerOid
) {
1047 add_leaf_marker_value(options
, markerOid
, NULL
);
1050 static void add_leaf_marker_value_string(CFMutableDictionaryRef options
, CFStringRef markerOid
, CFStringRef string_value
) {
1051 if (NULL
== string_value
) {
1052 add_element(options
, kSecPolicyCheckLeafMarkerOid
, markerOid
);
1054 CFDictionaryRef policyData
= NULL
;
1055 const void *key
[1] = { markerOid
};
1056 const void *value
[1] = { string_value
};
1057 policyData
= CFDictionaryCreate(kCFAllocatorDefault
,
1059 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
1060 add_element(options
, kSecPolicyCheckLeafMarkerOid
, policyData
);
1062 CFReleaseNull(policyData
);
1066 static void add_leaf_marker_string(CFMutableDictionaryRef options
, CFStringRef markerOid
) {
1067 add_leaf_marker_value_string(options
, markerOid
, NULL
);
1070 static void add_leaf_prod_qa_element(CFMutableDictionaryRef options
, CFTypeRef prodValue
, CFTypeRef qaValue
)
1072 CFMutableDictionaryRef prodAndQADictionary
= CFDictionaryCreateMutable(NULL
, 0, &kCFTypeDictionaryKeyCallBacks
,
1073 &kCFTypeDictionaryValueCallBacks
);
1074 CFDictionaryRef old_value
= CFDictionaryGetValue(options
, kSecPolicyCheckLeafMarkersProdAndQA
);
1076 CFMutableArrayRef prodArray
= NULL
, qaArray
= NULL
;
1077 CFTypeRef old_prod_value
= CFDictionaryGetValue(old_value
, kSecPolicyLeafMarkerProd
);
1078 CFTypeRef old_qa_value
= CFDictionaryGetValue(old_value
, kSecPolicyLeafMarkerQA
);
1079 if (isArray(old_prod_value
) && isArray(old_qa_value
)) {
1080 prodArray
= (CFMutableArrayRef
)CFRetainSafe(old_prod_value
);
1081 qaArray
= (CFMutableArrayRef
)CFRetainSafe(old_qa_value
);
1083 prodArray
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
1084 qaArray
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
1085 CFArrayAppendValue(prodArray
, old_prod_value
);
1086 CFArrayAppendValue(qaArray
, old_qa_value
);
1088 CFArrayAppendValue(prodArray
, prodValue
);
1089 CFArrayAppendValue(qaArray
, qaValue
);
1090 CFDictionaryAddValue(prodAndQADictionary
, kSecPolicyLeafMarkerProd
, prodArray
);
1091 CFDictionaryAddValue(prodAndQADictionary
, kSecPolicyLeafMarkerQA
, qaArray
);
1092 CFReleaseNull(prodArray
);
1093 CFReleaseNull(qaArray
);
1096 CFDictionaryAddValue(prodAndQADictionary
, kSecPolicyLeafMarkerProd
, prodValue
);
1097 CFDictionaryAddValue(prodAndQADictionary
, kSecPolicyLeafMarkerQA
, qaValue
);
1099 CFDictionarySetValue(options
, kSecPolicyCheckLeafMarkersProdAndQA
, prodAndQADictionary
);
1100 CFReleaseNull(prodAndQADictionary
);
1104 static void add_leaf_prod_qa_markers(CFMutableDictionaryRef options
, const DERItem
*prodMarkerOid
, const DERItem
*qaMarkerOid
)
1106 CFDataRef prodData
= NULL
, qaData
= NULL
;
1107 prodData
= CFDataCreate(NULL
, prodMarkerOid
? prodMarkerOid
->data
: NULL
,
1108 prodMarkerOid
? prodMarkerOid
->length
: 0);
1109 qaData
= CFDataCreate(NULL
, qaMarkerOid
? qaMarkerOid
->data
: NULL
,
1110 qaMarkerOid
? qaMarkerOid
->length
: 0);
1111 add_leaf_prod_qa_element(options
, prodData
, qaData
);
1112 CFReleaseNull(prodData
);
1113 CFReleaseNull(qaData
);
1116 static void add_leaf_prod_qa_markers_string(CFMutableDictionaryRef options
, CFStringRef prodMarkerOid
, CFStringRef qaMarkerOid
)
1118 add_leaf_prod_qa_element(options
, prodMarkerOid
, qaMarkerOid
);
1121 static void add_leaf_prod_qa_markers_value_string(CFMutableDictionaryRef options
,
1122 CFStringRef prodMarkerOid
, CFStringRef prod_value
,
1123 CFStringRef qaMarkerOid
, CFStringRef qa_value
)
1125 if (!prod_value
&& !qa_value
) {
1126 add_leaf_prod_qa_element(options
, prodMarkerOid
, qaMarkerOid
);
1128 CFDictionaryRef prodData
= NULL
, qaData
= NULL
;
1129 const void *prodKey
[1] = { prodMarkerOid
}, *qaKey
[1] = { qaMarkerOid
};
1130 const void *prodValue
[1] = { prod_value
}, *qaValue
[1] = { qa_value
};
1131 prodData
= CFDictionaryCreate(NULL
, prodKey
, prodValue
, 1, &kCFTypeDictionaryKeyCallBacks
,
1132 &kCFTypeDictionaryValueCallBacks
);
1133 qaData
= CFDictionaryCreate(NULL
, qaKey
, qaValue
, 1, &kCFTypeDictionaryKeyCallBacks
,
1134 &kCFTypeDictionaryValueCallBacks
);
1135 add_leaf_prod_qa_element(options
, prodData
, qaData
);
1136 CFReleaseNull(prodData
);
1137 CFReleaseNull(qaData
);
1141 static void add_intermediate_marker_value_string(CFMutableDictionaryRef options
, CFStringRef markerOid
, CFStringRef string_value
) {
1142 if (NULL
== string_value
) {
1143 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, markerOid
);
1145 CFDictionaryRef policyData
= NULL
;
1146 const void *key
[1] = { markerOid
};
1147 const void *value
[1] = { string_value
};
1148 policyData
= CFDictionaryCreate(kCFAllocatorDefault
,
1150 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
1151 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, policyData
);
1153 CFReleaseNull(policyData
);
1157 static void add_certificate_policy_oid(CFMutableDictionaryRef options
, const DERItem
*certificatePolicyOid
) {
1158 CFTypeRef certificatePolicyData
= NULL
;
1159 certificatePolicyData
= CFDataCreate(kCFAllocatorDefault
,
1160 certificatePolicyOid
? certificatePolicyOid
->data
: NULL
,
1161 certificatePolicyOid
? certificatePolicyOid
->length
: 0);
1162 if (certificatePolicyData
) {
1163 add_element(options
, kSecPolicyCheckCertificatePolicy
, certificatePolicyData
);
1164 CFRelease(certificatePolicyData
);
1168 static void add_certificate_policy_oid_string(CFMutableDictionaryRef options
, CFStringRef certificatePolicyOid
) {
1169 if (certificatePolicyOid
) {
1170 add_element(options
, kSecPolicyCheckCertificatePolicy
, certificatePolicyOid
);
1175 // Routines for adding dictionary entries for policies.
1178 // X.509, but missing validity requirements.
1179 static void SecPolicyAddBasicCertOptions(CFMutableDictionaryRef options
)
1181 //CFDictionaryAddValue(options, kSecPolicyCheckBasicCertificateProcessing, kCFBooleanTrue);
1182 // Happens automatically in SecPVCPathChecks
1183 CFDictionaryAddValue(options
, kSecPolicyCheckCriticalExtensions
, kCFBooleanTrue
);
1184 CFDictionaryAddValue(options
, kSecPolicyCheckIdLinkage
, kCFBooleanTrue
);
1185 CFDictionaryAddValue(options
, kSecPolicyCheckBasicConstraints
, kCFBooleanTrue
);
1186 CFDictionaryAddValue(options
, kSecPolicyCheckNonEmptySubject
, kCFBooleanTrue
);
1187 CFDictionaryAddValue(options
, kSecPolicyCheckWeakKeySize
, kCFBooleanTrue
);
1188 CFDictionaryAddValue(options
, kSecPolicyCheckWeakSignature
, kCFBooleanTrue
);
1191 static void SecPolicyAddBasicX509Options(CFMutableDictionaryRef options
)
1193 SecPolicyAddBasicCertOptions(options
);
1194 CFDictionaryAddValue(options
, kSecPolicyCheckTemporalValidity
, kCFBooleanTrue
);
1196 // Make sure that black and gray leaf checks are performed for basic X509 chain building
1197 CFDictionaryAddValue(options
, kSecPolicyCheckBlackListedLeaf
, kCFBooleanTrue
);
1198 CFDictionaryAddValue(options
, kSecPolicyCheckGrayListedLeaf
, kCFBooleanTrue
);
1201 static bool SecPolicyAddChainLengthOptions(CFMutableDictionaryRef options
, CFIndex length
)
1203 bool result
= false;
1204 CFNumberRef lengthAsCF
= NULL
;
1206 require(lengthAsCF
= CFNumberCreate(kCFAllocatorDefault
,
1207 kCFNumberCFIndexType
, &length
), errOut
);
1208 CFDictionaryAddValue(options
, kSecPolicyCheckChainLength
, lengthAsCF
);
1213 CFReleaseSafe(lengthAsCF
);
1217 static bool SecPolicyAddAnchorSHA1Options(CFMutableDictionaryRef options
,
1218 const UInt8 anchorSha1
[kSecPolicySHA1Size
])
1220 bool success
= false;
1221 CFDataRef anchorData
= NULL
;
1223 require(anchorData
= CFDataCreate(kCFAllocatorDefault
, anchorSha1
, kSecPolicySHA1Size
), errOut
);
1224 add_element(options
, kSecPolicyCheckAnchorSHA1
, anchorData
);
1229 CFReleaseSafe(anchorData
);
1233 static bool SecPolicyAddAnchorSHA256Options(CFMutableDictionaryRef options
,
1234 const UInt8 anchorSha1
[kSecPolicySHA256Size
])
1236 bool success
= false;
1237 CFDataRef anchorData
= NULL
;
1239 require(anchorData
= CFDataCreate(kCFAllocatorDefault
, anchorSha1
, kSecPolicySHA256Size
), errOut
);
1240 add_element(options
, kSecPolicyCheckAnchorSHA256
, anchorData
);
1245 CFReleaseSafe(anchorData
);
1249 static bool SecPolicyAddStrongKeySizeOptions(CFMutableDictionaryRef options
) {
1250 bool success
= false;
1251 CFDictionaryRef keySizes
= NULL
;
1252 CFNumberRef rsaSize
= NULL
, ecSize
= NULL
;
1254 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
1255 require(rsaSize
= CFNumberCreateWithCFIndex(NULL
, 2048), errOut
);
1256 require(ecSize
= CFNumberCreateWithCFIndex(NULL
, 256), errOut
);
1257 const void *keys
[] = { kSecAttrKeyTypeRSA
, kSecAttrKeyTypeEC
};
1258 const void *values
[] = { rsaSize
, ecSize
};
1259 require(keySizes
= CFDictionaryCreate(NULL
, keys
, values
, 2,
1260 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1261 add_element(options
, kSecPolicyCheckKeySize
, keySizes
);
1266 CFReleaseSafe(keySizes
);
1267 CFReleaseSafe(rsaSize
);
1268 CFReleaseSafe(ecSize
);
1272 static bool isAppleOid(CFStringRef oid
) {
1273 if (!SecCertificateIsOidString(oid
)) {
1276 if (CFStringHasPrefix(oid
, CFSTR("1.2.840.113635"))) {
1282 static bool isCFPreferenceInSecurityDomain(CFStringRef setting
) {
1283 return (CFPreferencesGetAppBooleanValue(setting
, CFSTR("com.apple.security"), NULL
));
1286 static bool SecPolicyAddAppleAnchorOptions(CFMutableDictionaryRef options
, CFStringRef __unused policyName
)
1288 CFMutableDictionaryRef appleAnchorOptions
= NULL
;
1289 appleAnchorOptions
= CFDictionaryCreateMutableForCFTypes(NULL
);
1290 if (!appleAnchorOptions
) {
1294 /* Currently no Apple Anchor options */
1295 add_element(options
, kSecPolicyCheckAnchorApple
, appleAnchorOptions
);
1296 CFReleaseSafe(appleAnchorOptions
);
1300 static bool SecPolicyAddPinningRequiredIfInfoSpecified(CFMutableDictionaryRef options
)
1302 CFBundleRef bundle
= CFBundleGetMainBundle();
1304 CFTypeRef value
= CFBundleGetValueForInfoDictionaryKey(bundle
, CFSTR("SecTrustPinningRequired"));
1305 if (isBoolean(value
) && CFBooleanGetValue(value
)) {
1306 add_element(options
, kSecPolicyCheckPinningRequired
, kCFBooleanTrue
);
1315 // MARK: Policy Creation Functions
1317 SecPolicyRef
SecPolicyCreateBasicX509(void) {
1318 CFMutableDictionaryRef options
= NULL
;
1319 SecPolicyRef result
= NULL
;
1321 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1322 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1324 SecPolicyAddBasicX509Options(options
);
1325 CFDictionaryAddValue(options
, kSecPolicyCheckNoNetworkAccess
,
1328 require(result
= SecPolicyCreate(kSecPolicyAppleX509Basic
, kSecPolicyNameX509Basic
, options
), errOut
);
1331 CFReleaseSafe(options
);
1332 return (SecPolicyRef _Nonnull
)result
;
1335 SecPolicyRef
SecPolicyCreateSSL(Boolean server
, CFStringRef hostname
) {
1336 CFMutableDictionaryRef options
= NULL
;
1337 SecPolicyRef result
= NULL
;
1339 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1340 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1342 SecPolicyAddBasicX509Options(options
);
1345 CFDictionaryAddValue(options
, kSecPolicyCheckSSLHostname
, hostname
);
1348 CFDictionaryAddValue(options
, kSecPolicyCheckBlackListedLeaf
, kCFBooleanTrue
);
1349 CFDictionaryAddValue(options
, kSecPolicyCheckGrayListedLeaf
, kCFBooleanTrue
);
1352 CFDictionaryAddValue(options
, kSecPolicyCheckSystemTrustedWeakHash
, kCFBooleanTrue
);
1353 CFDictionaryAddValue(options
, kSecPolicyCheckSystemTrustedWeakKey
, kCFBooleanTrue
);
1354 require_quiet(SecPolicyAddPinningRequiredIfInfoSpecified(options
), errOut
);
1357 set_ssl_ekus(options
, server
);
1359 require(result
= SecPolicyCreate(kSecPolicyAppleSSL
,
1360 server
? kSecPolicyNameSSLServer
: kSecPolicyNameSSLClient
,
1364 CFReleaseSafe(options
);
1365 return (SecPolicyRef _Nonnull
)result
;
1368 SecPolicyRef
SecPolicyCreateApplePinned(CFStringRef policyName
, CFStringRef intermediateMarkerOID
, CFStringRef leafMarkerOID
) {
1369 CFMutableDictionaryRef options
= NULL
;
1370 SecPolicyRef result
= NULL
;
1372 if (!policyName
|| !intermediateMarkerOID
|| !leafMarkerOID
) {
1376 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1377 &kCFTypeDictionaryKeyCallBacks
,
1378 &kCFTypeDictionaryValueCallBacks
), errOut
);
1380 SecPolicyAddBasicX509Options(options
);
1382 /* Anchored to the Apple Roots */
1383 require(SecPolicyAddAppleAnchorOptions(options
, policyName
), errOut
);
1385 /* Exactly 3 certs in the chain */
1386 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1388 /* Intermediate marker OID matches input OID */
1389 if (!isAppleOid(intermediateMarkerOID
)) {
1390 secwarning("creating an Apple pinning policy with a non-Apple OID: %@", intermediateMarkerOID
);
1392 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, intermediateMarkerOID
);
1394 /* Leaf marker OID matches input OID */
1395 if (!isAppleOid(leafMarkerOID
)) {
1396 secwarning("creating an Apple pinning policy with a non-Apple OID: %@", leafMarkerOID
);
1398 add_leaf_marker_string(options
, leafMarkerOID
);
1400 /* Check revocation using any available method */
1401 add_element(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
1403 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
1404 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
1406 /* Check for weak hashes */
1407 CFDictionaryAddValue(options
, kSecPolicyCheckSystemTrustedWeakHash
, kCFBooleanTrue
);
1408 require(result
= SecPolicyCreate(kSecPolicyAppleGenericApplePinned
,
1409 policyName
, options
), errOut
);
1412 CFReleaseSafe(options
);
1417 requireUATPinning(CFStringRef service
)
1419 bool pinningRequired
= true;
1421 if (SecIsInternalRelease()) {
1422 CFStringRef setting
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("AppleServerAuthenticationNoPinning%@"), service
);
1423 require(setting
, fail
);
1424 if(isCFPreferenceInSecurityDomain(setting
)) {
1425 pinningRequired
= false;
1427 secnotice("pinningQA", "could not disable pinning: %@ not true", setting
);
1431 if (!pinningRequired
) {
1435 if(isCFPreferenceInSecurityDomain(CFSTR("AppleServerAuthenticationNoPinning"))) {
1436 pinningRequired
= false;
1438 secnotice("pinningQA", "could not disable pinning: AppleServerAuthenticationNoPinning not true");
1441 secnotice("pinningQA", "could not disable pinning: not an internal release");
1444 return pinningRequired
;
1447 SecPolicyRef
SecPolicyCreateAppleSSLPinned(CFStringRef policyName
, CFStringRef hostname
,
1448 CFStringRef intermediateMarkerOID
, CFStringRef leafMarkerOID
) {
1449 CFMutableDictionaryRef options
= NULL
, appleAnchorOptions
= NULL
;
1450 SecPolicyRef result
= NULL
;
1452 if (!policyName
|| !hostname
|| !leafMarkerOID
) {
1456 if (requireUATPinning(policyName
)) {
1457 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1458 &kCFTypeDictionaryKeyCallBacks
,
1459 &kCFTypeDictionaryValueCallBacks
), errOut
);
1461 SecPolicyAddBasicX509Options(options
);
1463 /* Anchored to the Apple Roots */
1464 require(SecPolicyAddAppleAnchorOptions(options
, policyName
), errOut
);
1466 /* Exactly 3 certs in the chain */
1467 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1469 if (intermediateMarkerOID
) {
1470 /* Intermediate marker OID matches input OID */
1471 if (!isAppleOid(intermediateMarkerOID
)) {
1472 secwarning("creating an Apple pinning policy with a non-Apple OID: %@", intermediateMarkerOID
);
1474 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, intermediateMarkerOID
);
1476 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.12"));
1479 /* Leaf marker OID matches input OID */
1480 if (!isAppleOid(leafMarkerOID
)) {
1481 secwarning("creating an Apple pinning policy with a non-Apple OID: %@", leafMarkerOID
);
1483 add_leaf_marker_string(options
, leafMarkerOID
);
1485 /* New leaf marker OID format */
1486 add_leaf_marker_value_string(options
, CFSTR("1.2.840.113635.100.6.48.1"), leafMarkerOID
);
1488 /* ServerAuth EKU is in leaf cert */
1489 add_eku_string(options
, CFSTR("1.3.6.1.5.5.7.3.1"));
1491 /* Hostname is in leaf cert */
1492 add_element(options
, kSecPolicyCheckSSLHostname
, hostname
);
1494 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
1495 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
1497 /* Check for weak hashes */
1498 CFDictionaryAddValue(options
, kSecPolicyCheckSystemTrustedWeakHash
, kCFBooleanTrue
);
1500 /* Check revocation using any available method */
1501 add_element(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
1503 require(result
= SecPolicyCreate(kSecPolicyAppleGenericAppleSSLPinned
,
1504 policyName
, options
), errOut
);
1507 result
= SecPolicyCreateSSL(true, hostname
);
1508 SecPolicySetOid(result
, kSecPolicyAppleGenericAppleSSLPinned
);
1509 SecPolicySetName(result
, policyName
);
1513 CFReleaseSafe(options
);
1514 CFReleaseSafe(appleAnchorOptions
);
1518 SecPolicyRef
SecPolicyCreateiPhoneActivation(void) {
1519 CFMutableDictionaryRef options
= NULL
;
1520 SecPolicyRef result
= NULL
;
1522 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1523 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1525 SecPolicyAddBasicCertOptions(options
);
1528 CFDictionaryAddValue(options
, kSecPolicyCheckKeyUsage
,
1530 CFDictionaryAddValue(options
, kSecPolicyCheckExtendedKeyUsage
,
1534 /* Basic X.509 policy with the additional requirements that the chain
1535 length is 3, it's anchored at the AppleCA and the leaf certificate
1536 has issuer "Apple iPhone Certification Authority" and
1537 subject "Apple iPhone Activation" for the common name. */
1538 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
1539 CFSTR("Apple iPhone Certification Authority"));
1540 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
,
1541 CFSTR("Apple iPhone Activation"));
1543 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1544 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameiPhoneActivation
), errOut
);
1546 require(result
= SecPolicyCreate(kSecPolicyAppleiPhoneActivation
,
1547 kSecPolicyNameiPhoneActivation
, options
),
1551 CFReleaseSafe(options
);
1555 SecPolicyRef
SecPolicyCreateiPhoneDeviceCertificate(void) {
1556 CFMutableDictionaryRef options
= NULL
;
1557 SecPolicyRef result
= NULL
;
1559 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1560 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1562 SecPolicyAddBasicCertOptions(options
);
1565 CFDictionaryAddValue(options
, kSecPolicyCheckKeyUsage
,
1567 CFDictionaryAddValue(options
, kSecPolicyCheckExtendedKeyUsage
,
1571 /* Basic X.509 policy with the additional requirements that the chain
1572 length is 4, it's anchored at the AppleCA and the first intermediate
1573 has the subject "Apple iPhone Device CA". */
1574 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
1575 CFSTR("Apple iPhone Device CA"));
1577 require(SecPolicyAddChainLengthOptions(options
, 4), errOut
);
1578 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameiPhoneDeviceCertificate
), errOut
);
1580 require(result
= SecPolicyCreate(kSecPolicyAppleiPhoneDeviceCertificate
,
1581 kSecPolicyNameiPhoneDeviceCertificate
, options
),
1585 CFReleaseSafe(options
);
1589 SecPolicyRef
SecPolicyCreateFactoryDeviceCertificate(void) {
1590 CFMutableDictionaryRef options
= NULL
;
1591 SecPolicyRef result
= NULL
;
1593 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1594 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1596 SecPolicyAddBasicCertOptions(options
);
1599 CFDictionaryAddValue(options
, kSecPolicyCheckKeyUsage
,
1601 CFDictionaryAddValue(options
, kSecPolicyCheckExtendedKeyUsage
,
1605 /* Basic X.509 policy with the additional requirements that the chain
1606 is anchored at the factory device certificate issuer. */
1607 require(SecPolicyAddAnchorSHA1Options(options
, kFactoryDeviceCASHA1
), errOut
);
1609 require(result
= SecPolicyCreate(kSecPolicyAppleFactoryDeviceCertificate
,
1610 kSecPolicyNameFactoryDeviceCertificate
, options
),
1614 CFReleaseSafe(options
);
1618 SecPolicyRef
SecPolicyCreateiAP(void) {
1619 CFMutableDictionaryRef options
= NULL
;
1620 SecPolicyRef result
= NULL
;
1621 CFTimeZoneRef tz
= NULL
;
1622 CFDateRef date
= NULL
;
1624 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1625 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1627 SecPolicyAddBasicCertOptions(options
);
1629 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonNamePrefix
,
1632 date
= CFDateCreateForGregorianZuluDay(NULL
, 2006, 5, 31);
1633 CFDictionaryAddValue(options
, kSecPolicyCheckNotValidBefore
, date
);
1635 require(result
= SecPolicyCreate(kSecPolicyAppleiAP
,
1636 kSecPolicyNameiAP
, options
),
1640 CFReleaseSafe(date
);
1642 CFReleaseSafe(options
);
1646 SecPolicyRef
SecPolicyCreateiTunesStoreURLBag(void) {
1647 CFMutableDictionaryRef options
= NULL
;
1648 SecPolicyRef result
= NULL
;
1651 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1652 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1654 SecPolicyAddBasicCertOptions(options
);
1656 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectOrganization
,
1657 CFSTR("Apple Inc."));
1658 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
,
1659 CFSTR("iTunes Store URL Bag"));
1661 require(SecPolicyAddChainLengthOptions(options
, 2), errOut
);
1662 require(SecPolicyAddAnchorSHA1Options(options
, kITMSCASHA1
), errOut
);
1664 require(result
= SecPolicyCreate(kSecPolicyAppleiTunesStoreURLBag
,
1665 kSecPolicyNameiTunesStoreURLBag
, options
), errOut
);
1668 CFReleaseSafe(options
);
1672 SecPolicyRef
SecPolicyCreateEAP(Boolean server
, CFArrayRef trustedServerNames
) {
1673 CFMutableDictionaryRef options
= NULL
;
1674 SecPolicyRef result
= NULL
;
1676 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1677 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1679 SecPolicyAddBasicX509Options(options
);
1681 /* Since EAP is used to setup the network we don't want evaluation
1682 using this policy to access the network. */
1683 CFDictionaryAddValue(options
, kSecPolicyCheckNoNetworkAccess
,
1686 if (trustedServerNames
) {
1687 CFDictionaryAddValue(options
, kSecPolicyCheckEAPTrustedServerNames
, trustedServerNames
);
1691 /* Check for weak hashes */
1692 CFDictionaryAddValue(options
, kSecPolicyCheckSystemTrustedWeakHash
, kCFBooleanTrue
);
1693 CFDictionaryAddValue(options
, kSecPolicyCheckSystemTrustedWeakKey
, kCFBooleanTrue
);
1696 /* We need to check for EKU per rdar://22206018 */
1697 set_ssl_ekus(options
, server
);
1699 require(result
= SecPolicyCreate(kSecPolicyAppleEAP
,
1700 server
? kSecPolicyNameEAPServer
: kSecPolicyNameEAPClient
,
1704 CFReleaseSafe(options
);
1708 SecPolicyRef
SecPolicyCreateIPSec(Boolean server
, CFStringRef hostname
) {
1709 CFMutableDictionaryRef options
= NULL
;
1710 SecPolicyRef result
= NULL
;
1712 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1713 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1715 SecPolicyAddBasicX509Options(options
);
1718 CFDictionaryAddValue(options
, kSecPolicyCheckSSLHostname
, hostname
);
1721 /* Require oidExtendedKeyUsageIPSec if Extended Keyusage Extention is
1723 /* Per <rdar://problem/6843827> Cisco VPN Certificate compatibility issue.
1724 We don't check the EKU for IPSec certs for now. If we do add eku
1725 checking back in the future, we should probably also accept the
1727 ipsecEndSystem 1.3.6.1.5.5.7.3.5
1729 ipsecTunnel 1.3.6.1.5.5.7.3.6
1730 ipsecUser 1.3.6.1.5.5.7.3.7
1732 //add_eku(options, NULL); /* eku extension is optional */
1733 //add_eku(options, &oidAnyExtendedKeyUsage);
1734 //add_eku(options, &oidExtendedKeyUsageIPSec);
1736 require(result
= SecPolicyCreate(kSecPolicyAppleIPsec
,
1737 server
? kSecPolicyNameIPSecServer
: kSecPolicyNameIPSecClient
,
1741 CFReleaseSafe(options
);
1745 SecPolicyRef
SecPolicyCreateiPhoneApplicationSigning(void) {
1746 CFMutableDictionaryRef options
= NULL
;
1747 SecPolicyRef result
= NULL
;
1749 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1750 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1752 SecPolicyAddBasicCertOptions(options
);
1754 /* Anchored to the Apple Roots */
1755 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameiPhoneApplicationSigning
), errOut
);
1758 if (SecIsInternalRelease()) {
1759 /* Allow a prod hierarchy-signed test cert */
1760 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonNameTEST
,
1761 CFSTR("Apple iPhone OS Application Signing"));
1762 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.3.1"));
1765 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
,
1766 CFSTR("Apple iPhone OS Application Signing"));
1768 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.3"));
1770 add_eku(options
, NULL
); /* eku extension is optional */
1771 add_eku(options
, &oidAnyExtendedKeyUsage
);
1772 add_eku(options
, &oidExtendedKeyUsageCodeSigning
);
1774 /* Intermediate check */
1775 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
1776 CFSTR("Apple iPhone Certification Authority"));
1778 /* Chain length check */
1779 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1781 require(result
= SecPolicyCreate(kSecPolicyAppleiPhoneApplicationSigning
,
1782 kSecPolicyNameiPhoneApplicationSigning
, options
),
1786 CFReleaseSafe(options
);
1790 SecPolicyRef
SecPolicyCreateiPhoneVPNApplicationSigning(void) {
1791 CFMutableDictionaryRef options
= NULL
;
1792 SecPolicyRef result
= NULL
;
1794 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1795 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1797 SecPolicyAddBasicCertOptions(options
);
1799 /* Anchored to the Apple Roots */
1800 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameiPhoneVPNApplicationSigning
), errOut
);
1803 if (SecIsInternalRelease()) {
1804 /* Allow a prod hierarchy-signed test cert */
1805 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonNameTEST
,
1806 CFSTR("Apple iPhone OS Application Signing"));
1807 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.6.1"));
1810 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
,
1811 CFSTR("Apple iPhone OS Application Signing"));
1813 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.6"));
1815 add_eku(options
, NULL
); /* eku extension is optional */
1816 add_eku(options
, &oidAnyExtendedKeyUsage
);
1817 add_eku(options
, &oidExtendedKeyUsageCodeSigning
);
1819 /* Intermediate check */
1820 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
1821 CFSTR("Apple iPhone Certification Authority"));
1823 /* Chain length check */
1824 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1826 require(result
= SecPolicyCreate(kSecPolicyAppleiPhoneVPNApplicationSigning
,
1827 kSecPolicyNameiPhoneVPNApplicationSigning
, options
),
1831 CFReleaseSafe(options
);
1835 SecPolicyRef
SecPolicyCreateiPhoneProfileApplicationSigning(void) {
1836 CFMutableDictionaryRef options
= NULL
;
1837 SecPolicyRef result
= NULL
;
1839 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1840 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1842 SecPolicyAddBasicX509Options(options
); // With expiration checking
1845 require_quiet(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameiPhoneProfileApplicationSigning
),
1849 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1851 /* Leaf has CodeSigning EKU */
1852 add_eku_string(options
, CFSTR("1.3.6.1.5.5.7.3.3"));
1854 /* On iOS, the cert in the provisioning profile may be one of:
1855 leaf OID intermediate OID
1856 iPhone Developer <ADS>.6.1.2 <ADS>.6.2.1
1857 iPhone Distribution <ADS>.6.1.4 <ADS>.6.2.1
1858 TestFlight (Prod) <ADS>.6.1.25.1 <ADS>.6.2.1
1859 TestFlight (QA) <ADS>.6.1.25.2 <ADS>.6.2.1
1861 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.1"));
1862 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.2"));
1863 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.4"));
1864 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.25.1"));
1865 if (SecIsInternalRelease()) {
1866 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.25.2"));
1869 /* Revocation via any available method */
1870 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
1873 require(result
= SecPolicyCreate(kSecPolicyAppleiPhoneProfileApplicationSigning
,
1874 kSecPolicyNameiPhoneProfileApplicationSigning
,
1878 CFReleaseSafe(options
);
1882 SecPolicyRef
SecPolicyCreateMacOSProfileApplicationSigning(void) {
1883 CFMutableDictionaryRef options
= NULL
;
1884 SecPolicyRef result
= NULL
;
1886 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1887 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1889 SecPolicyAddBasicCertOptions(options
); // Without expiration checking
1892 require_quiet(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameiPhoneProfileApplicationSigning
),
1896 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1898 /* Leaf has CodeSigning EKU */
1899 add_eku_string(options
, CFSTR("1.3.6.1.5.5.7.3.3"));
1902 /* On macOS, the cert in the provisioning profile may be one of:
1903 leaf OID intermediate OID
1904 MAS Development <ADS>.6.1.12 <ADS>.6.2.1
1905 MAS Submission <ADS>.6.1.7 <ADS>.6.2.1
1906 Developer ID <ADS>.6.1.13 <ADS>.6.2.6
1907 B&I <ADS>.6.22 None - "Apple Code Signing Certification Authority"
1909 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.12"));
1910 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.7"));
1911 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.13"));
1912 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.22"));
1914 /* Revocation via any available method */
1915 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
1918 require(result
= SecPolicyCreate(kSecPolicyAppleMacOSProfileApplicationSigning
,
1919 kSecPolicyNameMacOSProfileApplicationSigning
,
1923 CFReleaseSafe(options
);
1927 SecPolicyRef
SecPolicyCreateiPhoneProvisioningProfileSigning(void) {
1928 CFMutableDictionaryRef options
= NULL
;
1929 SecPolicyRef result
= NULL
;
1931 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1932 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1934 SecPolicyAddBasicCertOptions(options
);
1936 /* Basic X.509 policy with the additional requirements that the chain
1937 length is 3, it's anchored at the AppleCA and the leaf certificate
1938 has issuer "Apple iPhone Certification Authority" and
1939 subject "Apple iPhone OS Provisioning Profile Signing" for the common name. */
1940 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
1941 CFSTR("Apple iPhone Certification Authority"));
1942 if (SecIsInternalRelease()) {
1943 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonNameTEST
,
1944 CFSTR("Apple iPhone OS Provisioning Profile Signing"));
1947 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
,
1948 CFSTR("Apple iPhone OS Provisioning Profile Signing"));
1951 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1952 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameiPhoneProvisioningProfileSigning
), errOut
);
1954 require(result
= SecPolicyCreate(kSecPolicyAppleiPhoneProvisioningProfileSigning
,
1955 kSecPolicyNameiPhoneProvisioningProfileSigning
, options
),
1958 /* 1.2.840.113635.100.6.2.2.1, non-critical: DER:05:00 - provisioning profile */
1961 CFReleaseSafe(options
);
1965 SecPolicyRef
SecPolicyCreateAppleTVOSApplicationSigning(void) {
1966 CFMutableDictionaryRef options
= NULL
;
1967 SecPolicyRef result
= NULL
;
1968 CFDataRef atvProdOid
= NULL
;
1969 CFDataRef atvTestOid
= NULL
;
1970 CFArrayRef oids
= NULL
;
1972 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1973 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1975 SecPolicyAddBasicCertOptions(options
);
1977 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1979 require_quiet(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameTVOSApplicationSigning
),
1982 /* Check for intermediate: Apple Worldwide Developer Relations */
1983 /* 1.2.840.113635.100.6.2.1 */
1984 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleWWDR
);
1986 add_ku(options
, kSecKeyUsageDigitalSignature
);
1988 /* Check for prod or test AppleTV Application Signing OIDs */
1989 /* Prod: 1.2.840.113635.100.6.1.24 */
1990 /* ProdQA: 1.2.840.113635.100.6.1.24.1 */
1991 add_leaf_marker(options
, &oidAppleTVOSApplicationSigningProd
);
1992 add_leaf_marker(options
, &oidAppleTVOSApplicationSigningProdQA
);
1994 require(result
= SecPolicyCreate(kSecPolicyAppleTVOSApplicationSigning
,
1995 kSecPolicyNameTVOSApplicationSigning
, options
),
1999 CFReleaseSafe(options
);
2000 CFReleaseSafe(oids
);
2001 CFReleaseSafe(atvProdOid
);
2002 CFReleaseSafe(atvTestOid
);
2006 SecPolicyRef
SecPolicyCreateOCSPSigner(void) {
2007 CFMutableDictionaryRef options
= NULL
;
2008 SecPolicyRef result
= NULL
;
2010 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2011 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2013 SecPolicyAddBasicX509Options(options
);
2015 /* Require id-kp-OCSPSigning extendedKeyUsage to be present, not optional. */
2016 add_eku(options
, &oidExtendedKeyUsageOCSPSigning
);
2018 require(result
= SecPolicyCreate(kSecPolicyAppleOCSPSigner
,
2019 kSecPolicyNameOCSPSigner
, options
), errOut
);
2022 CFReleaseSafe(options
);
2026 SecPolicyRef
SecPolicyCreateRevocation(CFOptionFlags revocationFlags
) {
2027 CFMutableDictionaryRef options
= NULL
;
2028 SecPolicyRef result
= NULL
;
2030 require(revocationFlags
!= 0, errOut
);
2032 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2033 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2035 if (revocationFlags
& kSecRevocationOCSPMethod
&& revocationFlags
& kSecRevocationCRLMethod
) {
2036 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
2038 else if (revocationFlags
& kSecRevocationOCSPMethod
) {
2039 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationOCSP
);
2041 else if (revocationFlags
& kSecRevocationCRLMethod
) {
2042 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationCRL
);
2045 if (revocationFlags
& kSecRevocationRequirePositiveResponse
) {
2046 CFDictionaryAddValue(options
, kSecPolicyCheckRevocationResponseRequired
, kCFBooleanTrue
);
2049 if (revocationFlags
& kSecRevocationNetworkAccessDisabled
) {
2050 CFDictionaryAddValue(options
, kSecPolicyCheckNoNetworkAccess
, kCFBooleanTrue
);
2052 /* If the caller didn't explicitly disable network access, the revocation policy
2053 * should override any other policy's network setting.
2054 * In particular, pairing a revocation policy with BasicX509 should result in
2055 * allowing network access for revocation unless explicitly disabled.
2056 * Note that SecTrustSetNetworkFetchAllowed can override even this. */
2057 CFDictionaryAddValue(options
, kSecPolicyCheckNoNetworkAccess
, kCFBooleanFalse
);
2060 if (revocationFlags
& kSecRevocationOnlineCheck
) {
2061 CFDictionaryAddValue(options
, kSecPolicyCheckRevocationOnline
, kCFBooleanTrue
);
2064 /* Only flag bits 0-5 are currently defined */
2065 require(((revocationFlags
>> 6) == 0), errOut
);
2067 require(result
= SecPolicyCreate(kSecPolicyAppleRevocation
,
2068 kSecPolicyNameRevocation
, options
), errOut
);
2071 CFReleaseSafe(options
);
2075 SecPolicyRef
SecPolicyCreateSMIME(CFIndex smimeUsage
, CFStringRef email
) {
2076 CFMutableDictionaryRef options
= NULL
;
2077 SecPolicyRef result
= NULL
;
2079 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2080 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2082 if (smimeUsage
& kSecIgnoreExpirationSMIMEUsage
) {
2083 SecPolicyAddBasicCertOptions(options
);
2085 SecPolicyAddBasicX509Options(options
);
2088 /* We call add_ku for each combination of bits we are willing to allow. */
2089 if (smimeUsage
& kSecSignSMIMEUsage
) {
2090 add_ku(options
, kSecKeyUsageUnspecified
);
2091 add_ku(options
, kSecKeyUsageDigitalSignature
);
2092 add_ku(options
, kSecKeyUsageNonRepudiation
);
2094 if (smimeUsage
& kSecKeyEncryptSMIMEUsage
) {
2095 add_ku(options
, kSecKeyUsageKeyEncipherment
);
2097 if (smimeUsage
& kSecDataEncryptSMIMEUsage
) {
2098 add_ku(options
, kSecKeyUsageDataEncipherment
);
2100 if (smimeUsage
& kSecKeyExchangeDecryptSMIMEUsage
) {
2101 add_ku(options
, kSecKeyUsageKeyAgreement
| kSecKeyUsageDecipherOnly
);
2103 if (smimeUsage
& kSecKeyExchangeEncryptSMIMEUsage
) {
2104 add_ku(options
, kSecKeyUsageKeyAgreement
| kSecKeyUsageEncipherOnly
);
2106 if (smimeUsage
& kSecKeyExchangeBothSMIMEUsage
) {
2107 add_ku(options
, kSecKeyUsageKeyAgreement
| kSecKeyUsageEncipherOnly
| kSecKeyUsageDecipherOnly
);
2111 CFDictionaryAddValue(options
, kSecPolicyCheckEmail
, email
);
2114 /* RFC 3850 paragraph 4.4.4
2116 If the extended key usage extension is present in the certificate
2117 then interpersonal message S/MIME receiving agents MUST check that it
2118 contains either the emailProtection or the anyExtendedKeyUsage OID as
2119 defined in [KEYM]. S/MIME uses other than interpersonal messaging
2120 MAY require the explicit presence of the extended key usage extension
2121 or other OIDs to be present in the extension or both.
2123 add_eku(options
, NULL
); /* eku extension is optional */
2124 add_eku(options
, &oidAnyExtendedKeyUsage
);
2125 add_eku(options
, &oidExtendedKeyUsageEmailProtection
);
2127 #if !TARGET_OS_IPHONE
2128 // Check revocation on OS X
2129 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
2132 require(result
= SecPolicyCreate(kSecPolicyAppleSMIME
, kSecPolicyNameSMIME
, options
), errOut
);
2135 CFReleaseSafe(options
);
2139 SecPolicyRef
SecPolicyCreateApplePackageSigning(void) {
2140 CFMutableDictionaryRef options
= NULL
;
2141 SecPolicyRef result
= NULL
;
2143 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2144 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2146 SecPolicyAddBasicCertOptions(options
);
2148 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2149 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNamePackageSigning
), errOut
);
2151 add_ku(options
, kSecKeyUsageDigitalSignature
);
2152 add_eku(options
, &oidExtendedKeyUsageCodeSigning
);
2154 require(result
= SecPolicyCreate(kSecPolicyApplePackageSigning
,
2155 kSecPolicyNamePackageSigning
, options
),
2159 CFReleaseSafe(options
);
2164 SecPolicyRef
SecPolicyCreateAppleSWUpdateSigning(void) {
2165 CFMutableDictionaryRef options
= NULL
;
2166 SecPolicyRef result
= NULL
;
2168 * OS X rules for this policy:
2169 * -- Must have one intermediate cert
2170 * -- intermediate must have basic constraints with path length 0
2171 * -- intermediate has CSSMOID_APPLE_EKU_CODE_SIGNING EKU
2172 * -- leaf cert has either CODE_SIGNING or CODE_SIGN_DEVELOPMENT EKU (the latter of
2173 * which triggers a CSSMERR_APPLETP_CODE_SIGN_DEVELOPMENT error)
2175 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2176 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2178 SecPolicyAddBasicX509Options(options
);
2180 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2181 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameSWUpdateSigning
), errOut
);
2183 add_eku(options
, &oidAppleExtendedKeyUsageCodeSigning
);
2184 add_oid(options
, kSecPolicyCheckIntermediateEKU
, &oidAppleExtendedKeyUsageCodeSigning
);
2186 require(result
= SecPolicyCreate(kSecPolicyAppleSWUpdateSigning
,
2187 kSecPolicyNameSWUpdateSigning
, options
),
2191 CFReleaseSafe(options
);
2196 SecPolicyRef
SecPolicyCreateCodeSigning(void) {
2197 CFMutableDictionaryRef options
= NULL
;
2198 SecPolicyRef result
= NULL
;
2200 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2201 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2203 SecPolicyAddBasicX509Options(options
);
2205 /* If the key usage extension is present, we accept it having either of
2207 add_ku(options
, kSecKeyUsageDigitalSignature
);
2208 add_ku(options
, kSecKeyUsageNonRepudiation
);
2210 /* We require an extended key usage extension with the codesigning
2211 eku purpose. (The Apple codesigning eku is not accepted here
2212 since it's valid only for SecPolicyCreateAppleSWUpdateSigning.) */
2213 add_eku(options
, &oidExtendedKeyUsageCodeSigning
);
2214 #if TARGET_OS_IPHONE
2215 /* Accept the 'any' eku on iOS only to match prior behavior.
2216 This may be further restricted in future releases. */
2217 add_eku(options
, &oidAnyExtendedKeyUsage
);
2220 require(result
= SecPolicyCreate(kSecPolicyAppleCodeSigning
,
2221 kSecPolicyNameCodeSigning
, options
),
2225 CFReleaseSafe(options
);
2229 /* Explicitly leave out empty subject/subjectaltname check */
2230 SecPolicyRef
SecPolicyCreateLockdownPairing(void) {
2231 CFMutableDictionaryRef options
= NULL
;
2232 SecPolicyRef result
= NULL
;
2234 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2235 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2236 //CFDictionaryAddValue(options, kSecPolicyCheckBasicCertificateProcessing,
2237 // kCFBooleanTrue); // Happens automatically in SecPVCPathChecks
2238 CFDictionaryAddValue(options
, kSecPolicyCheckCriticalExtensions
,
2240 CFDictionaryAddValue(options
, kSecPolicyCheckIdLinkage
,
2242 CFDictionaryAddValue(options
, kSecPolicyCheckBasicConstraints
,
2244 CFDictionaryAddValue(options
, kSecPolicyCheckWeakKeySize
, kCFBooleanTrue
);
2246 require(result
= SecPolicyCreate(kSecPolicyAppleLockdownPairing
,
2247 kSecPolicyNameLockdownPairing
, options
), errOut
);
2250 CFReleaseSafe(options
);
2254 SecPolicyRef
SecPolicyCreateURLBag(void) {
2255 CFMutableDictionaryRef options
= NULL
;
2256 SecPolicyRef result
= NULL
;
2258 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2259 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2261 SecPolicyAddBasicCertOptions(options
);
2263 add_eku(options
, &oidExtendedKeyUsageCodeSigning
);
2265 require(result
= SecPolicyCreate(kSecPolicyAppleURLBag
,
2266 kSecPolicyNameURLBag
, options
), errOut
);
2269 CFReleaseSafe(options
);
2273 SecPolicyRef
SecPolicyCreateOTATasking(void)
2275 CFMutableDictionaryRef options
= NULL
;
2276 SecPolicyRef result
= NULL
;
2278 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2279 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2281 SecPolicyAddBasicX509Options(options
);
2284 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameMobileAsset
), errOut
);
2286 /* Chain length of 3 */
2287 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2289 /* Intermediate has common name "Apple iPhone Certification Authority". */
2290 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2291 CFSTR("Apple iPhone Certification Authority"));
2293 /* Leaf has common name "Asset Manifest Signing" */
2294 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
, CFSTR("OTA Task Signing"));
2296 require(result
= SecPolicyCreate(kSecPolicyAppleOTATasking
, kSecPolicyNameOTATasking
, options
),
2300 CFReleaseSafe(options
);
2304 SecPolicyRef
SecPolicyCreateMobileAsset(void)
2306 CFMutableDictionaryRef options
= NULL
;
2307 SecPolicyRef result
= NULL
;
2309 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2310 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2312 /* No expiration check */
2313 SecPolicyAddBasicCertOptions(options
);
2316 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameMobileAsset
), errOut
);
2318 /* Chain length of 3 */
2319 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2321 /* Intermediate has common name "Apple iPhone Certification Authority". */
2322 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2323 CFSTR("Apple iPhone Certification Authority"));
2325 /* Leaf has common name "Asset Manifest Signing" */
2326 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
, CFSTR("Asset Manifest Signing"));
2328 require(result
= SecPolicyCreate(kSecPolicyAppleMobileAsset
, kSecPolicyNameMobileAsset
, options
),
2332 CFReleaseSafe(options
);
2336 SecPolicyRef
SecPolicyCreateMobileAssetDevelopment(void) {
2337 CFMutableDictionaryRef options
= NULL
;
2338 SecPolicyRef result
= NULL
;
2340 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2341 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2343 /* No expiration check */
2344 SecPolicyAddBasicCertOptions(options
);
2347 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameMobileAsset
), errOut
);
2349 /* Chain length of 3 */
2350 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2352 /* Intermediate has the iPhone CA Marker extension */
2353 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.18"));
2355 /* Leaf has ProdQA Mobile Asset Marker extension */
2356 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.55.1"));
2358 require(result
= SecPolicyCreate(kSecPolicyAppleMobileAssetDevelopment
, kSecPolicyNameMobileAsset
, options
),
2362 CFReleaseSafe(options
);
2366 SecPolicyRef
SecPolicyCreateAppleIDAuthorityPolicy(void)
2368 SecPolicyRef result
= NULL
;
2369 CFMutableDictionaryRef options
= NULL
;
2370 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2371 &kCFTypeDictionaryKeyCallBacks
,
2372 &kCFTypeDictionaryValueCallBacks
), out
);
2374 //Leaf appears to be a SSL only cert, so policy should expand on that policy
2375 SecPolicyAddBasicX509Options(options
);
2377 // Apple CA anchored
2378 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameIDAuthority
), out
);
2380 // with the addition of the existence check of an extension with "Apple ID Sharing Certificate" oid (1.2.840.113635.100.4.7)
2381 // NOTE: this obviously intended to have gone into Extended Key Usage, but evidence of existing certs proves the contrary.
2382 add_leaf_marker(options
, &oidAppleExtendedKeyUsageAppleID
);
2384 // and validate that intermediate has extension with CSSMOID_APPLE_EXTENSION_AAI_INTERMEDIATE oid (1.2.840.113635.100.6.2.3) and goes back to the Apple Root CA.
2385 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleID
);
2386 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleID2
);
2388 require(result
= SecPolicyCreate(kSecPolicyAppleIDAuthority
,
2389 kSecPolicyNameIDAuthority
, options
), out
);
2392 CFReleaseSafe(options
);
2396 SecPolicyRef
SecPolicyCreateMacAppStoreReceipt(void)
2398 SecPolicyRef result
= NULL
;
2399 CFMutableDictionaryRef options
= NULL
;
2400 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2401 &kCFTypeDictionaryKeyCallBacks
,
2402 &kCFTypeDictionaryValueCallBacks
), out
);
2404 SecPolicyAddBasicX509Options(options
);
2406 // Apple CA anchored
2407 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameMacAppStoreReceipt
), out
);
2409 // Chain length of 3
2410 require(SecPolicyAddChainLengthOptions(options
, 3), out
);
2412 // MacAppStoreReceipt policy OID
2413 add_certificate_policy_oid_string(options
, CFSTR("1.2.840.113635.100.5.6.1"));
2415 // Intermediate marker OID
2416 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.1"));
2419 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.11.1"));
2422 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
2424 require(result
= SecPolicyCreate(kSecPolicyMacAppStoreReceipt
,
2425 kSecPolicyNameMacAppStoreReceipt
, options
), out
);
2428 CFReleaseSafe(options
);
2433 static SecPolicyRef
_SecPolicyCreatePassbookCardSigner(CFStringRef cardIssuer
, CFStringRef teamIdentifier
, bool requireTeamID
)
2435 SecPolicyRef result
= NULL
;
2436 CFMutableDictionaryRef options
= NULL
;
2437 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2438 &kCFTypeDictionaryKeyCallBacks
,
2439 &kCFTypeDictionaryValueCallBacks
), out
);
2441 SecPolicyAddBasicX509Options(options
);
2442 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNamePassbookSigning
), out
);
2444 // Chain length of 3
2445 require(SecPolicyAddChainLengthOptions(options
, 3), out
);
2447 if (teamIdentifier
) {
2448 // If supplied, teamIdentifier must match subject OU field
2449 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectOrganizationalUnit
, teamIdentifier
);
2452 // If not supplied, and it was required, fail
2453 require(!requireTeamID
, out
);
2456 // Must be both push and 3rd party package signing
2457 add_leaf_marker_value(options
, &oidAppleInstallerPackagingSigningExternal
, cardIssuer
);
2459 // We should check that it also has push marker, but we don't support requiring both, only either.
2460 // add_independent_oid(options, kSecPolicyCheckLeafMarkerOid, &oidApplePushServiceClient);
2462 //WWDR Intermediate marker OID
2463 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.1"));
2465 // And Passbook signing eku
2466 add_eku(options
, &oidAppleExtendedKeyUsagePassbook
);
2468 require(result
= SecPolicyCreate(kSecPolicyApplePassbookSigning
,
2469 kSecPolicyNamePassbookSigning
, options
), out
);
2472 CFReleaseSafe(options
);
2476 SecPolicyRef
SecPolicyCreatePassbookCardSigner(CFStringRef cardIssuer
, CFStringRef teamIdentifier
)
2478 return _SecPolicyCreatePassbookCardSigner(cardIssuer
, teamIdentifier
, true);
2482 static SecPolicyRef
CreateMobileStoreSigner(Boolean forTest
)
2485 SecPolicyRef result
= NULL
;
2486 CFMutableDictionaryRef options
= NULL
;
2487 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2488 &kCFTypeDictionaryKeyCallBacks
,
2489 &kCFTypeDictionaryValueCallBacks
), errOut
);
2490 SecPolicyAddBasicX509Options(options
);
2491 require(SecPolicyAddAppleAnchorOptions(options
,
2492 ((forTest
) ? kSecPolicyNameTestMobileStore
:
2493 kSecPolicyNameMobileStore
)), errOut
);
2495 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2497 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2498 CFSTR("Apple System Integration 2 Certification Authority"));
2500 add_ku(options
, kSecKeyUsageDigitalSignature
);
2502 const DERItem
* pOID
= (forTest
) ? &oidApplePolicyMobileStoreProdQA
: &oidApplePolicyMobileStore
;
2504 add_certificate_policy_oid(options
, pOID
);
2506 require(result
= SecPolicyCreate((forTest
) ? kSecPolicyAppleTestMobileStore
: kSecPolicyAppleMobileStore
,
2507 (forTest
) ? kSecPolicyNameTestMobileStore
: kSecPolicyNameMobileStore
,
2511 CFReleaseSafe(options
);
2515 SecPolicyRef
SecPolicyCreateMobileStoreSigner(void)
2517 return CreateMobileStoreSigner(false);
2520 SecPolicyRef
SecPolicyCreateTestMobileStoreSigner(void)
2522 return CreateMobileStoreSigner(true);
2526 CF_RETURNS_RETAINED SecPolicyRef
SecPolicyCreateEscrowServiceSigner(void)
2528 SecPolicyRef result
= NULL
;
2529 CFMutableDictionaryRef options
= NULL
;
2530 CFArrayRef anArray
= NULL
;
2531 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2532 &kCFTypeDictionaryKeyCallBacks
,
2533 &kCFTypeDictionaryValueCallBacks
), errOut
);
2535 // X509, ignoring date validity
2536 SecPolicyAddBasicCertOptions(options
);
2539 add_ku(options
, kSecKeyUsageKeyEncipherment
);
2541 /* Leaf has marker OID with value that can't be pre-determined */
2542 add_element(options
, kSecPolicyCheckLeafMarkerOidWithoutValueCheck
, CFSTR("1.2.840.113635.100.6.23.1"));
2543 require(SecPolicyAddChainLengthOptions(options
, 2), errOut
);
2546 Boolean anchorAdded
= false;
2547 // Get the roots by calling the SecCertificateCopyEscrowRoots
2548 anArray
= SecCertificateCopyEscrowRoots(kSecCertificateProductionEscrowRoot
);
2549 CFIndex numRoots
= 0;
2550 if (NULL
== anArray
|| 0 == (numRoots
= CFArrayGetCount(anArray
)))
2555 for (CFIndex iCnt
= 0; iCnt
< numRoots
; iCnt
++)
2557 SecCertificateRef aCert
= (SecCertificateRef
)CFArrayGetValueAtIndex(anArray
, iCnt
);
2561 CFDataRef sha_data
= SecCertificateGetSHA1Digest(aCert
);
2562 if (NULL
!= sha_data
)
2564 const UInt8
* pSHAData
= CFDataGetBytePtr(sha_data
);
2565 if (NULL
!= pSHAData
)
2567 SecPolicyAddAnchorSHA1Options(options
, pSHAData
);
2573 CFReleaseNull(anArray
);
2581 require(result
= SecPolicyCreate(kSecPolicyAppleEscrowService
,
2582 kSecPolicyNameEscrowService
, options
), errOut
);
2585 CFReleaseSafe(anArray
);
2586 CFReleaseSafe(options
);
2590 CF_RETURNS_RETAINED SecPolicyRef
SecPolicyCreatePCSEscrowServiceSigner(void)
2592 SecPolicyRef result
= NULL
;
2593 CFMutableDictionaryRef options
= NULL
;
2594 CFArrayRef anArray
= NULL
;
2595 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2596 &kCFTypeDictionaryKeyCallBacks
,
2597 &kCFTypeDictionaryValueCallBacks
), errOut
);
2599 SecPolicyAddBasicX509Options(options
);
2602 add_ku(options
, kSecKeyUsageKeyEncipherment
);
2604 /* Leaf has marker OID with value that can't be pre-determined */
2605 add_element(options
, kSecPolicyCheckLeafMarkerOidWithoutValueCheck
, CFSTR("1.2.840.113635.100.6.23.1"));
2606 require(SecPolicyAddChainLengthOptions(options
, 2), errOut
);
2609 Boolean anchorAdded
= false;
2610 anArray
= SecCertificateCopyEscrowRoots(kSecCertificateProductionPCSEscrowRoot
);
2611 CFIndex numRoots
= 0;
2612 if (NULL
== anArray
|| 0 == (numRoots
= CFArrayGetCount(anArray
)))
2617 for (CFIndex iCnt
= 0; iCnt
< numRoots
; iCnt
++)
2619 SecCertificateRef aCert
= (SecCertificateRef
)CFArrayGetValueAtIndex(anArray
, iCnt
);
2623 CFDataRef sha_data
= SecCertificateGetSHA1Digest(aCert
);
2624 if (NULL
!= sha_data
)
2626 const UInt8
* pSHAData
= CFDataGetBytePtr(sha_data
);
2627 if (NULL
!= pSHAData
)
2629 SecPolicyAddAnchorSHA1Options(options
, pSHAData
);
2635 CFReleaseNull(anArray
);
2643 require(result
= SecPolicyCreate(kSecPolicyApplePCSEscrowService
,
2644 kSecPolicyNamePCSEscrowService
, options
), errOut
);
2647 CFReleaseSafe(anArray
);
2648 CFReleaseSafe(options
);
2652 static SecPolicyRef
CreateConfigurationProfileSigner(bool forTest
) {
2653 SecPolicyRef result
= NULL
;
2654 CFMutableDictionaryRef options
= NULL
;
2655 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2656 &kCFTypeDictionaryKeyCallBacks
,
2657 &kCFTypeDictionaryValueCallBacks
), errOut
);
2659 SecPolicyAddBasicX509Options(options
);
2660 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameProfileSigner
), errOut
);
2663 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2665 // Require the profile signing EKU
2666 const DERItem
* pOID
= (forTest
) ? &oidAppleExtendedKeyUsageQAProfileSigning
:&oidAppleExtendedKeyUsageProfileSigning
;
2667 add_eku(options
, pOID
);
2669 // Require the Apple Application Integration CA marker OID
2670 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.3"));
2672 require(result
= SecPolicyCreate((forTest
) ? kSecPolicyAppleQAProfileSigner
: kSecPolicyAppleProfileSigner
,
2673 (forTest
) ? kSecPolicyNameQAProfileSigner
: kSecPolicyNameProfileSigner
,
2677 CFReleaseSafe(options
);
2681 SecPolicyRef
SecPolicyCreateConfigurationProfileSigner(void)
2683 return CreateConfigurationProfileSigner(false);
2687 SecPolicyRef
SecPolicyCreateQAConfigurationProfileSigner(void)
2689 if (SecIsInternalRelease()) {
2690 return CreateConfigurationProfileSigner(true);
2692 return CreateConfigurationProfileSigner(false);
2696 SecPolicyRef
SecPolicyCreateOSXProvisioningProfileSigning(void)
2698 SecPolicyRef result
= NULL
;
2699 CFMutableDictionaryRef options
= NULL
;
2700 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2701 &kCFTypeDictionaryKeyCallBacks
,
2702 &kCFTypeDictionaryValueCallBacks
), errOut
);
2703 // Require valid chain from the Apple root
2704 SecPolicyAddBasicX509Options(options
);
2705 SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameOSXProvisioningProfileSigning
);
2707 // Require provisioning profile leaf marker OID (1.2.840.113635.100.4.11)
2708 add_leaf_marker(options
, &oidAppleCertExtOSXProvisioningProfileSigning
);
2710 // Require intermediate marker OID (1.2.840.113635.100.6.2.1)
2711 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleWWDR
);
2713 // Require key usage that allows signing
2714 add_ku(options
, kSecKeyUsageDigitalSignature
);
2716 // Ensure that revocation is checked (OCSP)
2717 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationOCSP
);
2719 require(result
= SecPolicyCreate(kSecPolicyAppleOSXProvisioningProfileSigning
,
2720 kSecPolicyNameOSXProvisioningProfileSigning
, options
), errOut
);
2723 CFReleaseSafe(options
);
2728 SecPolicyRef
SecPolicyCreateOTAPKISigner(void)
2730 SecPolicyRef result
= NULL
;
2731 CFMutableDictionaryRef options
= NULL
;
2732 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2733 &kCFTypeDictionaryKeyCallBacks
,
2734 &kCFTypeDictionaryValueCallBacks
), errOut
);
2735 SecPolicyAddBasicX509Options(options
);
2737 SecPolicyAddAnchorSHA1Options(options
, kApplePKISettingsAuthority
);
2738 require(SecPolicyAddChainLengthOptions(options
, 2), errOut
);
2740 require(result
= SecPolicyCreate(kSecPolicyAppleOTAPKISigner
,
2741 kSecPolicyNameOTAPKISigner
, options
), errOut
);
2744 CFReleaseSafe(options
);
2750 SecPolicyRef
SecPolicyCreateTestOTAPKISigner(void)
2752 /* Guard against use on production devices */
2753 if (!SecIsInternalRelease()) {
2754 return SecPolicyCreateOTAPKISigner();
2757 SecPolicyRef result
= NULL
;
2758 CFMutableDictionaryRef options
= NULL
;
2759 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2760 &kCFTypeDictionaryKeyCallBacks
,
2761 &kCFTypeDictionaryValueCallBacks
), errOut
);
2762 SecPolicyAddBasicX509Options(options
);
2764 SecPolicyAddAnchorSHA1Options(options
, kAppleTestPKISettingsAuthority
);
2765 require(SecPolicyAddChainLengthOptions(options
, 2), errOut
);
2767 require(result
= SecPolicyCreate(kSecPolicyAppleTestOTAPKISigner
,
2768 kSecPolicyNameTestOTAPKISigner
, options
), errOut
);
2771 CFReleaseSafe(options
);
2776 @function SecPolicyCreateAppleSMPEncryption
2777 @abstract Check for intermediate certificate 'Apple System Integration CA - G3' by name,
2778 and root certificate 'Apple Root CA - G3' by hash.
2779 Leaf cert must have Key Encipherment usage.
2780 Leaf cert must have Apple SMP Encryption marker OID (1.2.840.113635.100.6.30).
2781 Intermediate must have marker OID (1.2.840.113635.100.6.2.13).
2783 SecPolicyRef
SecPolicyCreateAppleSMPEncryption(void)
2785 SecPolicyRef result
= NULL
;
2786 CFMutableDictionaryRef options
= NULL
;
2787 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2788 &kCFTypeDictionaryKeyCallBacks
,
2789 &kCFTypeDictionaryValueCallBacks
), errOut
);
2790 SecPolicyAddBasicCertOptions(options
);
2792 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameSMPEncryption
),
2794 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2796 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2797 CFSTR("Apple System Integration CA - G3"));
2799 // Check that leaf has extension with "Apple SMP Encryption" oid (1.2.840.113635.100.6.30)
2800 add_leaf_marker(options
, &oidAppleCertExtAppleSMPEncryption
);
2802 // Check that intermediate has extension (1.2.840.113635.100.6.2.13)
2803 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleSystemIntgG3
);
2805 add_ku(options
, kSecKeyUsageKeyEncipherment
);
2807 // Ensure that revocation is checked (OCSP)
2808 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationOCSP
);
2810 require(result
= SecPolicyCreate(kSecPolicyAppleSMPEncryption
,
2811 kSecPolicyNameSMPEncryption
, options
), errOut
);
2814 CFReleaseSafe(options
);
2819 @function SecPolicyCreateTestAppleSMPEncryption
2820 @abstract Check for intermediate certificate 'Test Apple System Integration CA - ECC' by name,
2821 and root certificate 'Test Apple Root CA - ECC' by hash.
2822 Leaf cert must have Key Encipherment usage. Other checks TBD.
2824 SecPolicyRef
SecPolicyCreateTestAppleSMPEncryption(void)
2826 SecPolicyRef result
= NULL
;
2827 CFMutableDictionaryRef options
= NULL
;
2828 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2829 &kCFTypeDictionaryKeyCallBacks
,
2830 &kCFTypeDictionaryValueCallBacks
), errOut
);
2831 SecPolicyAddBasicCertOptions(options
);
2833 SecPolicyAddAnchorSHA1Options(options
, kTestAppleRootCA_ECC_SHA1
);
2834 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2836 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2837 CFSTR("Test Apple System Integration CA - ECC"));
2839 add_ku(options
, kSecKeyUsageKeyEncipherment
);
2841 // Ensure that revocation is checked (OCSP)
2842 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationOCSP
);
2844 require(result
= SecPolicyCreate(kSecPolicyAppleTestSMPEncryption
,
2845 kSecPolicyNameTestSMPEncryption
, options
), errOut
);
2848 CFReleaseSafe(options
);
2853 SecPolicyRef
SecPolicyCreateAppleIDValidationRecordSigningPolicy(void)
2855 SecPolicyRef result
= NULL
;
2856 CFMutableDictionaryRef options
= NULL
;
2857 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2858 &kCFTypeDictionaryKeyCallBacks
,
2859 &kCFTypeDictionaryValueCallBacks
), errOut
);
2861 //Leaf appears to be a SSL only cert, so policy should expand on that policy
2862 SecPolicyAddBasicX509Options(options
);
2864 // Apple CA anchored
2865 require(SecPolicyAddAppleAnchorOptions(options
,
2866 kSecPolicyNameIDValidationRecordSigning
),
2869 // Check for an extension with " Apple ID Validation Record Signing" oid (1.2.840.113635.100.6.25)
2870 add_leaf_marker(options
, &oidAppleCertExtensionAppleIDRecordValidationSigning
);
2872 // and validate that intermediate has extension
2873 // Application Integration Intermediate Certificate (1.2.840.113635.100.6.2.3)
2874 // and also validate that intermediate has extension
2875 // System Integration 2 Intermediate Certificate (1.2.840.113635.100.6.2.10)
2876 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleID
);
2877 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleSystemIntg2
);
2879 // Ensure that revocation is checked (OCSP)
2880 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationOCSP
);
2882 require(result
= SecPolicyCreate(kSecPolicyAppleIDValidationRecordSigning
,
2883 kSecPolicyNameIDValidationRecordSigning
, options
), errOut
);
2886 CFReleaseSafe(options
);
2891 @function SecPolicyCreateAppleServerAuthCommon
2892 @abstract Generic policy for server authentication Sub CAs
2894 Allows control for both if pinning is required at all and if UAT environments should be added
2895 to the trust policy.
2897 No pinning is for developer/QA that needs to use proxy to debug the protocol, while UAT
2898 environment is for QA/internal developer that have no need allow fake servers.
2900 Both the noPinning and UAT are gated on that you run on internal hardware.
2905 SecPolicyCreateAppleServerAuthCommon(CFStringRef hostname
,
2906 CFDictionaryRef __unused context
,
2907 CFStringRef policyOID
, CFStringRef service
,
2908 const DERItem
*leafMarkerOID
,
2909 const DERItem
*UATLeafMarkerOID
)
2911 CFMutableDictionaryRef appleAnchorOptions
= NULL
;
2912 CFMutableDictionaryRef options
= NULL
;
2913 SecPolicyRef result
= NULL
;
2914 CFDataRef oid
= NULL
, uatoid
= NULL
;
2916 options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0, &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
2917 require(options
, errOut
);
2919 SecPolicyAddBasicX509Options(options
);
2921 require(hostname
, errOut
);
2922 CFDictionaryAddValue(options
, kSecPolicyCheckSSLHostname
, hostname
);
2924 CFDictionaryAddValue(options
, kSecPolicyCheckBlackListedLeaf
, kCFBooleanTrue
);
2925 CFDictionaryAddValue(options
, kSecPolicyCheckGrayListedLeaf
, kCFBooleanTrue
);
2927 add_eku(options
, &oidExtendedKeyUsageServerAuth
);
2929 if (requireUATPinning(service
)) {
2932 * Require pinning to the Apple CA's.
2934 SecPolicyAddAppleAnchorOptions(options
, service
);
2936 /* old-style leaf marker OIDs */
2937 if (UATLeafMarkerOID
) {
2938 add_leaf_prod_qa_markers(options
, leafMarkerOID
, UATLeafMarkerOID
);
2940 add_leaf_marker(options
, leafMarkerOID
);
2943 /* new-style leaf marker OIDs */
2944 CFStringRef leafMarkerOIDStr
= NULL
, UATLeafMarkerOIDStr
= NULL
;
2945 leafMarkerOIDStr
= SecDERItemCopyOIDDecimalRepresentation(NULL
, leafMarkerOID
);
2946 if (UATLeafMarkerOID
) {
2947 UATLeafMarkerOIDStr
= SecDERItemCopyOIDDecimalRepresentation(NULL
, UATLeafMarkerOID
);
2950 if (leafMarkerOIDStr
&& UATLeafMarkerOIDStr
) {
2951 add_leaf_prod_qa_markers_value_string(options
,
2952 CFSTR("1.2.840.113635.100.6.48.1"), leafMarkerOIDStr
,
2953 CFSTR("1.2.840.113635.100.6.48.1"), UATLeafMarkerOIDStr
);
2954 } else if (leafMarkerOIDStr
) {
2955 add_leaf_marker_value_string(options
, CFSTR("1.2.840.113635.100.6.48.1"), leafMarkerOIDStr
);
2958 CFReleaseNull(leafMarkerOIDStr
);
2959 CFReleaseNull(UATLeafMarkerOIDStr
);
2961 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleServerAuthentication
);
2964 /* Check for weak hashes and keys */
2965 CFDictionaryAddValue(options
, kSecPolicyCheckSystemTrustedWeakHash
, kCFBooleanTrue
);
2966 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
2968 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
2970 result
= SecPolicyCreate(policyOID
, service
, options
);
2971 require(result
, errOut
);
2974 CFReleaseSafe(appleAnchorOptions
);
2975 CFReleaseSafe(options
);
2977 CFReleaseSafe(uatoid
);
2982 @function SecPolicyCreateAppleIDSService
2983 @abstract Ensure we're appropriately pinned to the IDS service (SSL + Apple restrictions)
2985 SecPolicyRef
SecPolicyCreateAppleIDSService(CFStringRef hostname
)
2987 SecPolicyRef result
= SecPolicyCreateSSL(true, hostname
);
2989 SecPolicySetOid(result
, kSecPolicyAppleIDSService
);
2990 SecPolicySetName(result
, kSecPolicyNameAppleIDSBag
);
2996 @function SecPolicyCreateAppleIDSService
2997 @abstract Ensure we're appropriately pinned to the IDS service (SSL + Apple restrictions)
2999 SecPolicyRef
SecPolicyCreateAppleIDSServiceContext(CFStringRef hostname
, CFDictionaryRef context
)
3001 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyAppleIDSServiceContext
,
3002 kSecPolicyNameAppleIDSService
,
3003 &oidAppleCertExtAppleServerAuthenticationIDSProd
,
3004 &oidAppleCertExtAppleServerAuthenticationIDSProdQA
);
3008 @function SecPolicyCreateAppleGSService
3009 @abstract Ensure we're appropriately pinned to the GS service
3011 SecPolicyRef
SecPolicyCreateAppleGSService(CFStringRef hostname
, CFDictionaryRef context
)
3013 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyAppleGSService
,
3014 kSecPolicyNameAppleGSService
,
3015 &oidAppleCertExtAppleServerAuthenticationGS
,
3020 @function SecPolicyCreateApplePushService
3021 @abstract Ensure we're appropriately pinned to the Push service (SSL + Apple restrictions)
3023 SecPolicyRef
SecPolicyCreateApplePushService(CFStringRef hostname
, CFDictionaryRef context
)
3025 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyApplePushService
,
3026 kSecPolicyNameApplePushService
,
3027 &oidAppleCertExtAppleServerAuthenticationAPNProd
,
3028 &oidAppleCertExtAppleServerAuthenticationAPNProdQA
);
3032 @function SecPolicyCreateApplePPQService
3033 @abstract Ensure we're appropriately pinned to the PPQ service (SSL + Apple restrictions)
3035 SecPolicyRef
SecPolicyCreateApplePPQService(CFStringRef hostname
, CFDictionaryRef context
)
3037 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyApplePPQService
,
3038 kSecPolicyNameApplePPQService
,
3039 &oidAppleCertExtAppleServerAuthenticationPPQProd
,
3040 &oidAppleCertExtAppleServerAuthenticationPPQProdQA
);
3044 @function SecPolicyCreateAppleAST2Service
3045 @abstract Ensure we're appropriately pinned to the AST2 Diagnostic service (SSL + Apple restrictions)
3047 SecPolicyRef
SecPolicyCreateAppleAST2Service(CFStringRef hostname
, CFDictionaryRef context
)
3049 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyAppleAST2DiagnosticsServerAuth
,
3050 kSecPolicyNameAppleAST2Service
,
3051 &oidAppleCertExtAST2DiagnosticsServerAuthProd
,
3052 &oidAppleCertExtAST2DiagnosticsServerAuthProdQA
);
3056 @function SecPolicyCreateAppleEscrowProxyService
3057 @abstract Ensure we're appropriately pinned to the iCloud Escrow Proxy service (SSL + Apple restrictions)
3059 SecPolicyRef
SecPolicyCreateAppleEscrowProxyService(CFStringRef hostname
, CFDictionaryRef context
)
3061 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyAppleEscrowProxyServerAuth
,
3062 kSecPolicyNameAppleEscrowProxyService
,
3063 &oidAppleCertExtEscrowProxyServerAuthProd
,
3064 &oidAppleCertExtEscrowProxyServerAuthProdQA
);
3067 /* subject:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA */
3068 /* SKID: C0:7A:98:68:8D:89:FB:AB:05:64:0C:11:7D:AA:7D:65:B8:CA:CC:4E */
3069 /* Not Before: May 21 04:00:00 2002 GMT, Not After : May 21 04:00:00 2022 GMT */
3070 /* Signature Algorithm: sha1WithRSAEncryption */
3071 unsigned char GeoTrust_Global_CA_sha256
[kSecPolicySHA256Size
] = {
3072 0xff, 0x85, 0x6a, 0x2d, 0x25, 0x1d, 0xcd, 0x88, 0xd3, 0x66, 0x56, 0xf4, 0x50, 0x12, 0x67, 0x98,
3073 0xcf, 0xab, 0xaa, 0xde, 0x40, 0x79, 0x9c, 0x72, 0x2d, 0xe4, 0xd2, 0xb5, 0xdb, 0x36, 0xa7, 0x3a
3076 static SecPolicyRef
SecPolicyCreateAppleGeoTrustServerAuthCommon(CFStringRef hostname
, CFStringRef policyOid
,
3077 CFStringRef policyName
,
3078 CFStringRef leafMarkerOid
,
3079 CFStringRef qaLeafMarkerOid
) {
3080 CFMutableDictionaryRef options
= NULL
;
3081 CFDataRef spkiDigest
= NULL
;
3082 SecPolicyRef result
= NULL
;
3084 require(options
= CFDictionaryCreateMutable(NULL
, 0, &kCFTypeDictionaryKeyCallBacks
,
3085 &kCFTypeDictionaryValueCallBacks
), errOut
);
3088 SecPolicyAddBasicX509Options(options
);
3090 require(hostname
, errOut
);
3091 CFDictionaryAddValue(options
, kSecPolicyCheckSSLHostname
, hostname
);
3093 add_eku(options
, &oidExtendedKeyUsageServerAuth
);
3096 if (requireUATPinning(policyName
)) {
3098 SecPolicyAddAnchorSHA256Options(options
, GeoTrust_Global_CA_sha256
);
3100 /* Issued to Apple Inc. in the US */
3101 add_element(options
, kSecPolicyCheckIntermediateCountry
, CFSTR("US"));
3102 add_element(options
, kSecPolicyCheckIntermediateOrganization
, CFSTR("Apple Inc."));
3104 require_action(SecPolicyAddChainLengthOptions(options
, 3), errOut
, CFReleaseNull(result
));
3106 /* Marker OIDs in both formats */
3107 if (qaLeafMarkerOid
) {
3108 add_leaf_prod_qa_markers_string(options
, leafMarkerOid
, qaLeafMarkerOid
);
3109 add_leaf_prod_qa_markers_value_string(options
,
3110 CFSTR("1.2.840.113635.100.6.48.1"), leafMarkerOid
,
3111 CFSTR("1.2.840.113635.100.6.48.1"), qaLeafMarkerOid
);
3113 add_leaf_marker_string(options
, leafMarkerOid
);
3114 add_leaf_marker_value_string(options
, CFSTR("1.2.840.113635.100.6.48.1"), leafMarkerOid
);
3118 /* Check for weak hashes */
3119 CFDictionaryAddValue(options
, kSecPolicyCheckSystemTrustedWeakHash
, kCFBooleanTrue
);
3120 CFDictionaryAddValue(options
, kSecPolicyCheckSystemTrustedWeakKey
, kCFBooleanTrue
);
3122 /* See <rdar://25344801> for more details */
3124 result
= SecPolicyCreate(policyOid
, policyName
, options
);
3127 CFReleaseSafe(options
);
3128 CFReleaseSafe(spkiDigest
);
3132 SecPolicyRef
SecPolicyCreateAppleCompatibilityEscrowProxyService(CFStringRef hostname
) {
3133 return SecPolicyCreateAppleGeoTrustServerAuthCommon(hostname
, kSecPolicyAppleEscrowProxyCompatibilityServerAuth
,
3134 kSecPolicyNameAppleEscrowProxyService
,
3135 CFSTR("1.2.840.113635.100.6.27.7.2"),
3136 CFSTR("1.2.840.113635.100.6.27.7.1"));
3140 @function SecPolicyCreateAppleFMiPService
3141 @abstract Ensure we're appropriately pinned to the Find My iPhone service (SSL + Apple restrictions)
3143 SecPolicyRef
SecPolicyCreateAppleFMiPService(CFStringRef hostname
, CFDictionaryRef context
)
3145 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyAppleFMiPServerAuth
,
3146 kSecPolicyNameAppleFMiPService
,
3147 &oidAppleCertExtFMiPServerAuthProd
,
3148 &oidAppleCertExtFMiPServerAuthProdQA
);
3152 /* should use verbatim copy, but since this is the deprecated way, don't care right now */
3153 static const UInt8 entrustSPKIL1C
[kSecPolicySHA256Size
] = {
3154 0x54, 0x5b, 0xf9, 0x35, 0xe9, 0xad, 0xa1, 0xda,
3155 0x11, 0x7e, 0xdc, 0x3c, 0x2a, 0xcb, 0xc5, 0x6f,
3156 0xc0, 0x28, 0x09, 0x6c, 0x0e, 0x24, 0xbe, 0x9b,
3157 0x38, 0x94, 0xbe, 0x52, 0x2d, 0x1b, 0x43, 0xde
3161 @function SecPolicyCreateApplePushServiceLegacy
3162 @abstract Ensure we're appropriately pinned to the Push service (via Entrust)
3164 SecPolicyRef
SecPolicyCreateApplePushServiceLegacy(CFStringRef hostname
)
3166 CFMutableDictionaryRef options
= NULL
;
3167 SecPolicyRef result
= NULL
;
3168 CFDataRef digest
= NULL
;
3170 digest
= CFDataCreateWithBytesNoCopy(kCFAllocatorDefault
, entrustSPKIL1C
, sizeof(entrustSPKIL1C
), kCFAllocatorNull
);
3171 require(digest
, errOut
);
3173 options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0, &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
3174 require(options
, errOut
);
3176 SecPolicyAddBasicX509Options(options
);
3178 CFDictionaryAddValue(options
, kSecPolicyCheckSSLHostname
, hostname
);
3180 CFDictionaryAddValue(options
, kSecPolicyCheckBlackListedLeaf
, kCFBooleanTrue
);
3181 CFDictionaryAddValue(options
, kSecPolicyCheckGrayListedLeaf
, kCFBooleanTrue
);
3183 CFDictionaryAddValue(options
, kSecPolicyCheckIntermediateSPKISHA256
, digest
);
3185 add_eku(options
, &oidExtendedKeyUsageServerAuth
);
3187 /* Check for weak hashes and keys */
3188 CFDictionaryAddValue(options
, kSecPolicyCheckSystemTrustedWeakHash
, kCFBooleanTrue
);
3189 CFDictionaryAddValue(options
, kSecPolicyCheckSystemTrustedWeakKey
, kCFBooleanTrue
);
3191 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
3193 result
= SecPolicyCreate(kSecPolicyAppleLegacyPushService
,
3194 kSecPolicyNameLegacyPushService
, options
);
3195 require(result
, errOut
);
3198 CFReleaseSafe(digest
);
3199 CFReleaseSafe(options
);
3204 @function SecPolicyCreateAppleMMCSService
3205 @abstract Ensure we're appropriately pinned to the IDS service (SSL + Apple restrictions)
3207 SecPolicyRef
SecPolicyCreateAppleMMCSService(CFStringRef hostname
, CFDictionaryRef context
)
3209 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyAppleMMCService
,
3210 kSecPolicyNameAppleMMCSService
,
3211 &oidAppleCertExtAppleServerAuthenticationMMCSProd
,
3212 &oidAppleCertExtAppleServerAuthenticationMMCSProdQA
);
3215 SecPolicyRef
SecPolicyCreateAppleCompatibilityMMCSService(CFStringRef hostname
) {
3216 return SecPolicyCreateAppleGeoTrustServerAuthCommon(hostname
, kSecPolicyAppleMMCSCompatibilityServerAuth
,
3217 kSecPolicyNameAppleMMCSService
,
3218 CFSTR("1.2.840.113635.100.6.27.11.2"),
3219 CFSTR("1.2.840.113635.100.6.27.11.1"));
3223 SecPolicyRef
SecPolicyCreateAppleiCloudSetupService(CFStringRef hostname
, CFDictionaryRef context
)
3225 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyAppleiCloudSetupServerAuth
,
3226 kSecPolicyNameAppleiCloudSetupService
,
3227 &oidAppleCertExtAppleServerAuthenticationiCloudSetupProd
,
3228 &oidAppleCertExtAppleServerAuthenticationiCloudSetupProdQA
);
3231 SecPolicyRef
SecPolicyCreateAppleCompatibilityiCloudSetupService(CFStringRef hostname
)
3233 return SecPolicyCreateAppleGeoTrustServerAuthCommon(hostname
, kSecPolicyAppleiCloudSetupCompatibilityServerAuth
,
3234 kSecPolicyNameAppleiCloudSetupService
,
3235 CFSTR("1.2.840.113635.100.6.27.15.2"),
3236 CFSTR("1.2.840.113635.100.6.27.15.1"));
3240 @function SecPolicyCreateAppleSSLService
3241 @abstract Ensure we're appropriately pinned to an Apple server (SSL + Apple restrictions)
3243 SecPolicyRef
SecPolicyCreateAppleSSLService(CFStringRef hostname
)
3245 // SSL server, pinned to an Apple intermediate
3246 SecPolicyRef policy
= SecPolicyCreateSSL(true, hostname
);
3247 CFMutableDictionaryRef options
= NULL
;
3248 require(policy
, errOut
);
3250 // change options for SSL policy evaluation
3251 require((options
=(CFMutableDictionaryRef
)policy
->_options
) != NULL
, errOut
);
3253 // Apple CA anchored
3254 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameServerAuthentication
), errOut
);
3256 // Check leaf for Apple Server Authentication marker oid (1.2.840.113635.100.6.27.1)
3257 add_leaf_marker(options
, &oidAppleCertExtAppleServerAuthentication
);
3259 // Check intermediate for Apple Server Authentication intermediate marker (1.2.840.113635.100.6.2.12)
3260 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleServerAuthentication
);
3262 /* Check for weak hashes */
3263 CFDictionaryAddValue(options
, kSecPolicyCheckSystemTrustedWeakHash
, kCFBooleanTrue
);
3264 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
3266 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
3268 SecPolicySetOid(policy
, kSecPolicyAppleServerAuthentication
);
3269 SecPolicySetName(policy
, kSecPolicyNameServerAuthentication
);
3274 CFReleaseSafe(options
);
3275 CFReleaseSafe(policy
);
3280 @function SecPolicyCreateApplePPQSigning
3281 @abstract Check for intermediate certificate 'Apple System Integration 2 Certification Authority' by name,
3283 Leaf cert must have Digital Signature usage.
3284 Leaf cert must have Apple PPQ Signing marker OID (1.2.840.113635.100.6.38.2).
3285 Intermediate must have marker OID (1.2.840.113635.100.6.2.10).
3287 SecPolicyRef
SecPolicyCreateApplePPQSigning(void)
3289 SecPolicyRef result
= NULL
;
3290 CFMutableDictionaryRef options
= NULL
;
3291 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3292 &kCFTypeDictionaryKeyCallBacks
,
3293 &kCFTypeDictionaryValueCallBacks
), errOut
);
3294 SecPolicyAddBasicCertOptions(options
);
3296 SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNamePPQSigning
);
3297 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3299 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
3300 CFSTR("Apple System Integration 2 Certification Authority"));
3302 // Check that leaf has extension with "Apple PPQ Signing" prod oid (1.2.840.113635.100.6.38.2)
3303 add_leaf_marker(options
, &oidAppleCertExtApplePPQSigningProd
);
3305 // Check that intermediate has extension (1.2.840.113635.100.6.2.10)
3306 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleSystemIntg2
);
3308 add_ku(options
, kSecKeyUsageDigitalSignature
);
3310 require(result
= SecPolicyCreate(kSecPolicyApplePPQSigning
,
3311 kSecPolicyNamePPQSigning
, options
), errOut
);
3314 CFReleaseSafe(options
);
3319 @function SecPolicyCreateTestApplePPQSigning
3320 @abstract Check for intermediate certificate 'Apple System Integration 2 Certification Authority' by name,
3322 Leaf cert must have Digital Signature usage.
3323 Leaf cert must have Apple PPQ Signing Test marker OID (1.2.840.113635.100.6.38.1).
3324 Intermediate must have marker OID (1.2.840.113635.100.6.2.10).
3326 SecPolicyRef
SecPolicyCreateTestApplePPQSigning(void)
3328 /* Guard against use of test policy on production devices */
3329 if (!SecIsInternalRelease()) {
3330 return SecPolicyCreateApplePPQSigning();
3333 SecPolicyRef result
= NULL
;
3334 CFMutableDictionaryRef options
= NULL
;
3335 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3336 &kCFTypeDictionaryKeyCallBacks
,
3337 &kCFTypeDictionaryValueCallBacks
), errOut
);
3338 SecPolicyAddBasicCertOptions(options
);
3340 SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameTestPPQSigning
);
3341 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3343 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
3344 CFSTR("Apple System Integration 2 Certification Authority"));
3346 // Check that leaf has extension with "Apple PPQ Signing" test oid (1.2.840.113635.100.6.38.1)
3347 add_leaf_marker(options
, &oidAppleCertExtApplePPQSigningProdQA
);
3349 // Check that intermediate has extension (1.2.840.113635.100.6.2.10)
3350 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleSystemIntg2
);
3352 add_ku(options
, kSecKeyUsageDigitalSignature
);
3354 require(result
= SecPolicyCreate(kSecPolicyAppleTestPPQSigning
,
3355 kSecPolicyNameTestPPQSigning
, options
), errOut
);
3358 CFReleaseSafe(options
);
3362 @function SecPolicyCreateAppleTimeStamping
3363 @abstract Check for RFC3161 timestamping EKU.
3365 SecPolicyRef
SecPolicyCreateAppleTimeStamping(void)
3367 SecPolicyRef result
= NULL
;
3368 CFMutableDictionaryRef options
= NULL
;
3369 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3370 &kCFTypeDictionaryKeyCallBacks
,
3371 &kCFTypeDictionaryValueCallBacks
), errOut
);
3373 SecPolicyAddBasicX509Options(options
);
3375 /* Require id-kp-timeStamping extendedKeyUsage to be present. */
3376 add_eku(options
, &oidExtendedKeyUsageTimeStamping
);
3378 require(result
= SecPolicyCreate(kSecPolicyAppleTimeStamping
,
3379 kSecPolicyNameTimeStamping
, options
), errOut
);
3382 CFReleaseSafe(options
);
3387 @function SecPolicyCreateApplePayIssuerEncryption
3388 @abstract Check for intermediate certificate 'Apple Worldwide Developer Relations CA - G2' by name,
3389 and ECC apple anchor.
3390 Leaf cert must have Key Encipherment and Key Agreement usage.
3391 Leaf cert must have Apple Pay Issuer Encryption marker OID (1.2.840.113635.100.6.39).
3393 SecPolicyRef
SecPolicyCreateApplePayIssuerEncryption(void)
3395 SecPolicyRef result
= NULL
;
3396 CFMutableDictionaryRef options
= NULL
;
3397 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3398 &kCFTypeDictionaryKeyCallBacks
,
3399 &kCFTypeDictionaryValueCallBacks
), errOut
);
3400 SecPolicyAddBasicCertOptions(options
);
3402 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNamePayIssuerEncryption
),
3404 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3406 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
3407 CFSTR("Apple Worldwide Developer Relations CA - G2"));
3409 // Check that leaf has extension with "Apple Pay Issuer Encryption" oid (1.2.840.113635.100.6.39)
3410 add_leaf_marker(options
, &oidAppleCertExtCryptoServicesExtEncryption
);
3412 add_ku(options
, kSecKeyUsageKeyEncipherment
);
3414 require(result
= SecPolicyCreate(kSecPolicyApplePayIssuerEncryption
,
3415 kSecPolicyNamePayIssuerEncryption
, options
), errOut
);
3418 CFReleaseSafe(options
);
3423 @function SecPolicyCreateAppleATVVPNProfileSigning
3424 @abstract Check for leaf marker OID 1.2.840.113635.100.6.43,
3425 intermediate marker OID 1.2.840.113635.100.6.2.10,
3426 chains to Apple Root CA, path length 3
3428 SecPolicyRef
SecPolicyCreateAppleATVVPNProfileSigning(void)
3430 SecPolicyRef result
= NULL
;
3431 CFMutableDictionaryRef options
= NULL
;
3432 CFMutableDictionaryRef appleAnchorOptions
= NULL
;
3433 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3434 &kCFTypeDictionaryKeyCallBacks
,
3435 &kCFTypeDictionaryValueCallBacks
), errOut
);
3437 SecPolicyAddBasicCertOptions(options
);
3439 // Require pinning to the Apple CAs (including test CA for internal releases)
3440 appleAnchorOptions
= CFDictionaryCreateMutableForCFTypes(NULL
);
3441 require(appleAnchorOptions
, errOut
);
3443 if (SecIsInternalRelease()) {
3444 CFDictionarySetValue(appleAnchorOptions
,
3445 kSecPolicyAppleAnchorIncludeTestRoots
, kCFBooleanTrue
);
3448 add_element(options
, kSecPolicyCheckAnchorApple
, appleAnchorOptions
);
3450 // Cert chain length 3
3451 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3453 // Check leaf for Apple ATV VPN Profile Signing OID (1.2.840.113635.100.6.43)
3454 add_leaf_marker(options
, &oidAppleCertExtATVVPNProfileSigning
);
3456 // Check intermediate for Apple System Integration 2 CA intermediate marker (1.2.840.113635.100.6.2.10)
3457 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleSystemIntg2
);
3459 // Ensure that revocation is checked (OCSP only)
3460 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationOCSP
);
3462 require(result
= SecPolicyCreate(kSecPolicyAppleATVVPNProfileSigning
,
3463 kSecPolicyNameATVVPNProfileSigning
, options
), errOut
);
3466 CFReleaseSafe(options
);
3467 CFReleaseSafe(appleAnchorOptions
);
3471 SecPolicyRef
SecPolicyCreateAppleHomeKitServerAuth(CFStringRef hostname
) {
3472 CFMutableDictionaryRef appleAnchorOptions
= NULL
;
3473 CFMutableDictionaryRef options
= NULL
;
3474 SecPolicyRef result
= NULL
;
3475 CFDataRef oid
= NULL
;
3477 options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0, &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
3478 require(options
, errOut
);
3480 SecPolicyAddBasicX509Options(options
);
3482 CFDictionaryAddValue(options
, kSecPolicyCheckSSLHostname
, hostname
);
3484 add_eku(options
, &oidExtendedKeyUsageServerAuth
);
3486 if (requireUATPinning(kSecPolicyNameAppleHomeKitService
)) {
3488 // Cert chain length 3
3489 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3491 // Apple anchors, allowing test anchors for internal release
3492 SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameAppleHomeKitService
);
3494 add_leaf_marker(options
, &oidAppleCertExtHomeKitServerAuth
);
3496 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleHomeKitServerCA
);
3499 /* Check for weak hashes */
3500 CFDictionaryAddValue(options
, kSecPolicyCheckSystemTrustedWeakHash
, kCFBooleanTrue
);
3501 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
3503 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
3505 result
= SecPolicyCreate(kSecPolicyAppleHomeKitServerAuth
,
3506 kSecPolicyNameAppleHomeKitService
, options
);
3507 require(result
, errOut
);
3510 CFReleaseSafe(appleAnchorOptions
);
3511 CFReleaseSafe(options
);
3516 SecPolicyRef
SecPolicyCreateAppleExternalDeveloper(void) {
3517 CFMutableDictionaryRef options
= NULL
;
3518 SecPolicyRef result
= NULL
;
3520 /* Create basic Apple pinned policy */
3521 require(result
= SecPolicyCreateApplePinned(kSecPolicyNameExternalDeveloper
,
3522 CFSTR("1.2.840.113635.100.6.2.1"), // WWDR Intermediate OID
3523 CFSTR("1.2.840.113635.100.6.1.2")), // "iPhone Developer" leaf OID
3526 require_action(options
= CFDictionaryCreateMutableCopy(NULL
, 0, result
->_options
), errOut
, CFReleaseNull(result
));
3528 /* Additional intermediate OIDs */
3529 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
,
3530 CFSTR("1.2.840.113635.100.6.2.6")); // "Developer ID" Intermediate OID
3532 /* Addtional leaf OIDS */
3533 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.4")); // "iPhone Distribution" leaf OID
3534 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.5")); // "Safari Developer" leaf OID
3535 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.7")); // "3rd Party Mac Developer Application" leaf OID
3536 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.8")); // "3rd Party Mac Developer Installer" leaf OID
3537 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.12")); // "Mac Developer" leaf OID
3538 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.13")); // "Developer ID Application" leaf OID
3539 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.14")); // "Developer ID Installer" leaf OID
3542 add_eku_string(options
, CFSTR("1.3.6.1.5.5.7.3.3")); // CodeSigning EKU
3543 add_eku_string(options
, CFSTR("1.2.840.113635.100.4.8")); // "Safari Developer" EKU
3544 add_eku_string(options
, CFSTR("1.2.840.113635.100.4.9")); // "3rd Party Mac Developer Installer" EKU
3545 add_eku_string(options
, CFSTR("1.2.840.113635.100.4.13")); // "Developer ID Installer" EKU
3547 CFReleaseSafe(result
->_options
);
3548 result
->_options
= CFRetainSafe(options
);
3550 SecPolicySetOid(result
, kSecPolicyAppleExternalDeveloper
);
3553 CFReleaseSafe(options
);
3557 /* This one is special because the intermediate has no marker OID */
3558 SecPolicyRef
SecPolicyCreateAppleSoftwareSigning(void) {
3559 CFMutableDictionaryRef options
= NULL
;
3560 CFDictionaryRef keySizes
= NULL
;
3561 CFNumberRef rsaSize
= NULL
, ecSize
= NULL
;
3562 SecPolicyRef result
= NULL
;
3564 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3565 &kCFTypeDictionaryKeyCallBacks
,
3566 &kCFTypeDictionaryValueCallBacks
), errOut
);
3568 SecPolicyAddBasicCertOptions(options
);
3570 /* Anchored to the Apple Roots */
3571 require_quiet(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameSoftwareSigning
),
3574 /* Exactly 3 certs in the chain */
3575 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3577 /* Intermediate Common Name matches */
3578 add_element(options
, kSecPolicyCheckIssuerCommonName
, CFSTR("Apple Code Signing Certification Authority"));
3580 /* Leaf marker OID matches */
3581 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.22"));
3583 /* Leaf has CodeSigning EKU */
3584 add_eku_string(options
, CFSTR("1.3.6.1.5.5.7.3.3"));
3586 /* Check revocation using any available method */
3587 add_element(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
3589 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
3590 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
3592 require(result
= SecPolicyCreate(kSecPolicyAppleSoftwareSigning
,
3593 kSecPolicyNameSoftwareSigning
, options
), errOut
);
3596 CFReleaseSafe(options
);
3597 CFReleaseSafe(keySizes
);
3598 CFReleaseSafe(rsaSize
);
3599 CFReleaseSafe(ecSize
);
3603 /* subject:/CN=SEP Root CA/O=Apple Inc./ST=California */
3604 /* SKID: 58:EF:D6:BE:C5:82:B0:54:CD:18:A6:84:AD:A2:F6:7B:7B:3A:7F:CF */
3605 /* Not Before: Jun 24 21:43:24 2014 GMT, Not After : Jun 24 21:43:24 2029 GMT */
3606 /* Signature Algorithm: ecdsa-with-SHA384 */
3607 const uint8_t SEPRootCA_SHA256
[kSecPolicySHA256Size
] = {
3608 0xd1, 0xdf, 0x82, 0x00, 0xf3, 0x89, 0x4e, 0xe9, 0x96, 0xf3, 0x77, 0xdf, 0x76, 0x3b, 0x0a, 0x16,
3609 0x8f, 0xd9, 0x6c, 0x58, 0xc0, 0x3e, 0xc9, 0xb0, 0x5f, 0xa5, 0x64, 0x79, 0xc0, 0xe8, 0xc9, 0xe7
3612 SecPolicyRef
SecPolicyCreateAppleUniqueDeviceCertificate(CFDataRef testRootHash
) {
3613 CFMutableDictionaryRef options
= NULL
;
3614 CFDictionaryRef keySizes
= NULL
;
3615 CFNumberRef ecSize
= NULL
;
3616 SecPolicyRef result
= NULL
;
3618 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3619 &kCFTypeDictionaryKeyCallBacks
,
3620 &kCFTypeDictionaryValueCallBacks
), errOut
);
3622 /* Device certificate should never expire */
3623 SecPolicyAddBasicCertOptions(options
);
3625 /* Anchored to the SEP Root CA. Allow alternative root for developers */
3626 require(SecPolicyAddAnchorSHA256Options(options
, SEPRootCA_SHA256
),errOut
);
3627 if (testRootHash
&& SecIsInternalRelease() && (kSecPolicySHA256Size
== CFDataGetLength(testRootHash
))) {
3628 add_element(options
, kSecPolicyCheckAnchorSHA256
, testRootHash
);
3631 /* Exactly 3 certs in the chain */
3632 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3634 /* Intermediate has marker OID with value */
3635 add_intermediate_marker_value_string(options
, CFSTR("1.2.840.113635.100.6.44"), CFSTR("ucrt"));
3637 /* Leaf has marker OID with varying value that can't be pre-determined */
3638 add_element(options
, kSecPolicyCheckLeafMarkerOidWithoutValueCheck
, CFSTR("1.2.840.113635.100.10.1"));
3640 /* RSA key sizes are disallowed. EC key sizes are P-256 or larger. */
3641 require(ecSize
= CFNumberCreateWithCFIndex(NULL
, 256), errOut
);
3642 require(keySizes
= CFDictionaryCreate(NULL
, (const void**)&kSecAttrKeyTypeEC
,
3643 (const void**)&ecSize
, 1,
3644 &kCFTypeDictionaryKeyCallBacks
,
3645 &kCFTypeDictionaryValueCallBacks
), errOut
);
3646 add_element(options
, kSecPolicyCheckKeySize
, keySizes
);
3649 require(result
= SecPolicyCreate(kSecPolicyAppleUniqueDeviceIdentifierCertificate
,
3650 kSecPolicyNameUniqueDeviceIdentifierCertificate
, options
), errOut
);
3653 CFReleaseSafe(options
);
3654 CFReleaseSafe(keySizes
);
3655 CFReleaseSafe(ecSize
);
3659 SecPolicyRef
SecPolicyCreateAppleWarsaw(void) {
3660 CFMutableDictionaryRef options
= NULL
;
3661 SecPolicyRef result
= NULL
;
3662 #if TARGET_OS_BRIDGE
3663 CFMutableDictionaryRef appleAnchorOptions
= NULL
;
3666 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3667 &kCFTypeDictionaryKeyCallBacks
,
3668 &kCFTypeDictionaryValueCallBacks
), errOut
);
3670 SecPolicyAddBasicX509Options(options
);
3672 /* Anchored to the Apple Roots. */
3673 require_quiet(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameWarsaw
),
3676 /* Exactly 3 certs in the chain */
3677 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3679 /* Intermediate marker OID matches input OID */
3680 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.14"));
3682 /* Leaf marker OID matches input OID */
3683 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.29"));
3685 /* Check revocation using any available method */
3686 add_element(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
3688 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
3689 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
3691 require(result
= SecPolicyCreate(kSecPolicyAppleWarsaw
,
3692 kSecPolicyNameWarsaw
, options
), errOut
);
3695 CFReleaseSafe(options
);
3699 SecPolicyRef
SecPolicyCreateAppleSecureIOStaticAsset(void) {
3700 CFMutableDictionaryRef options
= NULL
;
3701 SecPolicyRef result
= NULL
;
3702 #if TARGET_OS_BRIDGE
3703 CFMutableDictionaryRef appleAnchorOptions
= NULL
;
3706 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3707 &kCFTypeDictionaryKeyCallBacks
,
3708 &kCFTypeDictionaryValueCallBacks
), errOut
);
3710 /* This certificate cannot expire so that assets always load */
3711 SecPolicyAddBasicCertOptions(options
);
3713 /* Anchored to the Apple Roots. */
3714 #if TARGET_OS_BRIDGE
3715 /* On the bridge, test roots are gated in the trust and policy servers. */
3716 require_quiet(appleAnchorOptions
= CFDictionaryCreateMutableForCFTypes(NULL
), errOut
);
3717 CFDictionarySetValue(appleAnchorOptions
,
3718 kSecPolicyAppleAnchorIncludeTestRoots
, kCFBooleanTrue
);
3719 add_element(options
, kSecPolicyCheckAnchorApple
, appleAnchorOptions
);
3720 CFReleaseSafe(appleAnchorOptions
);
3722 require_quiet(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameSecureIOStaticAsset
),
3726 /* Exactly 3 certs in the chain */
3727 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3729 /* Intermediate marker OID matches ASI CA */
3730 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.10"));
3732 /* Leaf marker OID matches static IO OID */
3733 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.50"));
3735 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
3736 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
3738 require(result
= SecPolicyCreate(kSecPolicyAppleSecureIOStaticAsset
,
3739 kSecPolicyNameSecureIOStaticAsset
, options
), errOut
);
3742 CFReleaseSafe(options
);
3746 SecPolicyRef
SecPolicyCreateAppleAppTransportSecurity(void) {
3747 CFMutableDictionaryRef options
= NULL
;
3748 SecPolicyRef result
= NULL
;
3749 CFMutableSetRef disallowedHashes
= NULL
;
3751 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3752 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
3754 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
3755 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
3757 /* Hash algorithm is SHA-256 or better */
3758 require(disallowedHashes
= CFSetCreateMutable(NULL
, 5, &kCFTypeSetCallBacks
), errOut
);
3759 CFSetAddValue(disallowedHashes
, kSecSignatureDigestAlgorithmMD2
);
3760 CFSetAddValue(disallowedHashes
, kSecSignatureDigestAlgorithmMD4
);
3761 CFSetAddValue(disallowedHashes
, kSecSignatureDigestAlgorithmMD5
);
3762 CFSetAddValue(disallowedHashes
, kSecSignatureDigestAlgorithmSHA1
);
3763 CFSetAddValue(disallowedHashes
, kSecSignatureDigestAlgorithmSHA224
);
3765 add_element(options
, kSecPolicyCheckSignatureHashAlgorithms
, disallowedHashes
);
3767 require_quiet(result
= SecPolicyCreate(kSecPolicyAppleAppTransportSecurity
,
3768 kSecPolicyNameAppTransportSecurity
,
3772 CFReleaseSafe(options
);
3776 SecPolicyRef
SecPolicyCreateMobileSoftwareUpdate(void) {
3777 CFMutableDictionaryRef options
= NULL
;
3778 SecPolicyRef result
= NULL
;
3779 #if TARGET_OS_BRIDGE
3780 CFMutableDictionaryRef appleAnchorOptions
= NULL
;
3783 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3784 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
3786 /* No expiration check. */
3787 SecPolicyAddBasicCertOptions(options
);
3790 require_quiet(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameMobileSoftwareUpdate
),
3793 /* Exactly 3 certs in the chain */
3794 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3796 /* Intermediate marker OID is iPhone CA OID */
3797 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.18"));
3799 /* Leaf marker OID is either the prod MSU OID, or, on internal builds, the prodQA OID */
3800 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.57.2"));
3801 if (SecIsInternalRelease()) {
3802 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.57.1"));
3805 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
3806 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
3808 require(result
= SecPolicyCreate(kSecPolicyAppleMobileSoftwareUpdate
,
3809 kSecPolicyNameMobileSoftwareUpdate
, options
), errOut
);
3812 CFReleaseNull(options
);
3816 /* subject:/CN=Basic Attestation System Root CA/O=Apple Inc./ST=California */
3817 /* SKID: FE:D1:D1:C2:08:07:03:D5:B9:3C:34:B2:BB:FD:7C:3A:99:25:1B:8F */
3818 /* Not Before: Apr 20 00:22:09 2017 GMT, Not After : Mar 22 00:00:00 2032 GMT */
3819 /* Signature Algorithm: ecdsa-with-SHA384 */
3820 const uint8_t BASystemRootCA_SHA256
[kSecPolicySHA256Size
] = {
3821 0x29, 0x75, 0x9b, 0x53, 0x8a, 0xd1, 0xcb, 0x4f, 0x3b, 0xa5, 0x20, 0x4d, 0x60, 0x4b, 0x25, 0x81,
3822 0x8d, 0x18, 0x9f, 0x62, 0xe3, 0x94, 0x2d, 0x99, 0x52, 0x54, 0x22, 0x5a, 0xe5, 0x7f, 0x42, 0xca
3825 /* subject:/CN=Basic Attestation User Root CA/O=Apple Inc./ST=California */
3826 /* SKID: 83:E5:A3:21:9E:B0:74:C3:F9:61:90:FD:97:4E:23:10:76:A4:A3:F2 */
3827 /* Not Before: Apr 19 21:41:56 2017 GMT, Not After : Mar 22 00:00:00 2032 GMT */
3828 /* Signature Algorithm: ecdsa-with-SHA384 */
3829 const uint8_t BAUserRootCA_SHA256
[kSecPolicySHA256Size
] = {
3830 0x03, 0x75, 0x1c, 0x80, 0xfc, 0xbe, 0x58, 0x19, 0xd1, 0x70, 0xd2, 0x67, 0xce, 0x1a, 0xd6, 0xd0,
3831 0x94, 0x40, 0x7c, 0x91, 0xd8, 0x73, 0xd7, 0xa6, 0x56, 0x2d, 0xe3, 0x66, 0x6d, 0x35, 0x94, 0xc6
3834 SecPolicyRef
SecPolicyCreateAppleBasicAttestationSystem(CFDataRef testRootHash
) {
3835 CFMutableDictionaryRef options
= NULL
;
3836 SecPolicyRef result
= NULL
;
3838 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3839 &kCFTypeDictionaryKeyCallBacks
,
3840 &kCFTypeDictionaryValueCallBacks
), errOut
);
3841 /* BAA certs expire */
3842 SecPolicyAddBasicX509Options(options
);
3844 /* Anchored to one of the Basic Attestation roots. Allow alternative root for developers */
3845 SecPolicyAddAnchorSHA256Options(options
, BASystemRootCA_SHA256
);
3846 if (testRootHash
&& SecIsInternalRelease() && (kSecPolicySHA256Size
== CFDataGetLength(testRootHash
))) {
3847 add_element(options
, kSecPolicyCheckAnchorSHA256
, testRootHash
);
3850 /* Exactly 3 certs in the chain */
3851 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3853 require(result
= SecPolicyCreate(kSecPolicyAppleBasicAttestationSystem
,
3854 kSecPolicyNameBasicAttestationSystem
, options
), errOut
);
3857 CFReleaseSafe(options
);
3861 SecPolicyRef
SecPolicyCreateAppleBasicAttestationUser(CFDataRef testRootHash
) {
3862 CFMutableDictionaryRef options
= NULL
;
3863 SecPolicyRef result
= NULL
;
3865 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3866 &kCFTypeDictionaryKeyCallBacks
,
3867 &kCFTypeDictionaryValueCallBacks
), errOut
);
3868 /* BAA certs expire */
3869 SecPolicyAddBasicX509Options(options
);
3871 /* Anchored to one of the Basic Attestation roots. Allow alternative root for developers */
3872 SecPolicyAddAnchorSHA256Options(options
, BAUserRootCA_SHA256
);
3873 if (testRootHash
&& SecIsInternalRelease() && (kSecPolicySHA256Size
== CFDataGetLength(testRootHash
))) {
3874 add_element(options
, kSecPolicyCheckAnchorSHA256
, testRootHash
);
3877 /* Exactly 3 certs in the chain */
3878 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3880 require(result
= SecPolicyCreate(kSecPolicyAppleBasicAttestationUser
,
3881 kSecPolicyNameBasicAttestationUser
, options
), errOut
);
3884 CFReleaseSafe(options
);
3888 SecPolicyRef
SecPolicyCreateDemoDigitalCatalogSigning(void) {
3889 CFMutableDictionaryRef options
= NULL
;
3890 SecPolicyRef result
= NULL
;
3892 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3893 &kCFTypeDictionaryKeyCallBacks
,
3894 &kCFTypeDictionaryValueCallBacks
), errOut
);
3895 SecPolicyAddBasicX509Options(options
);
3897 /* Exactly 3 certs in the chain */
3898 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3900 /* Demo Signing Extension present in leaf */
3901 add_element(options
, kSecPolicyCheckLeafMarkerOid
, CFSTR("1.2.840.113635.100.6.60"));
3903 /* Issuer common name is "DemoUnit CA" */
3904 add_element(options
, kSecPolicyCheckIssuerCommonName
, CFSTR("DemoUnit CA"));
3906 require(result
= SecPolicyCreate(kSecPolicyAppleDemoDigitalCatalog
,
3907 kSecPolicyNameDemoDigitalCatalog
, options
), errOut
);
3910 CFReleaseSafe(options
);