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_E(NAME, INTNAME) static CFStringRef kSecPolicyName##NAME = CFSTR(#INTNAME);
105 #define __P_DO_DECLARE_P(NAME, INTNAME) const CFStringRef kSecPolicyNameApple##NAME = CFSTR(#INTNAME);
106 #define __P_DO_DECLARE_I(NAME, INTNAME) const CFStringRef kSecPolicyName##NAME = CFSTR(#INTNAME);
107 #define POLICYMACRO(NAME, OID, ISPUBLIC, INTNAME, IN_NAME, IN_PROPERTIES, FUNCTION) \
108 __P_DO_DECLARE_##ISPUBLIC(NAME, INTNAME)
109 #include "SecPolicy.list"
110 //Some naming exceptions
111 static CFStringRef kSecPolicyNameAppleIDSBag
= CFSTR("IDSBag");
113 /* External Policy Names
114 * These correspond to the names defined in CertificatePinning.plist
115 * in security_certificates */
116 SEC_CONST_DECL (kSecPolicyNameSSLServer
, "sslServer");
117 SEC_CONST_DECL (kSecPolicyNameSSLClient
, "sslClient");
118 SEC_CONST_DECL (kSecPolicyNameEAPServer
, "eapServer");
119 SEC_CONST_DECL (kSecPolicyNameEAPClient
, "eapClient");
120 SEC_CONST_DECL (kSecPolicyNameIPSecServer
, "ipsecServer");
121 SEC_CONST_DECL (kSecPolicyNameIPSecClient
, "ipsecClient");
122 SEC_CONST_DECL (kSecPolicyNameAppleiCloudSetupService
, "iCloudSetup");
123 SEC_CONST_DECL (kSecPolicyNameAppleMMCSService
, "MMCS");
124 SEC_CONST_DECL (kSecPolicyNameAppleAST2Service
, "AST2");
125 SEC_CONST_DECL (kSecPolicyNameAppleEscrowProxyService
, "Escrow");
126 SEC_CONST_DECL (kSecPolicyNameAppleFMiPService
, "FMiP");
127 SEC_CONST_DECL (kSecPolicyNameAppleHomeKitService
, "HomeKit");
128 SEC_CONST_DECL (kSecPolicyNameAppleAIDCService
, "AIDC");
129 SEC_CONST_DECL (kSecPolicyNameAppleMapsService
, "Maps");
130 SEC_CONST_DECL (kSecPolicyNameAppleHealthProviderService
, "HealthProvider");
131 SEC_CONST_DECL (kSecPolicyNameAppleParsecService
, "Parsec");
132 SEC_CONST_DECL (kSecPolicyNameAppleAMPService
, "AMP");
133 SEC_CONST_DECL (kSecPolicyNameAppleSiriService
, "Siri");
134 SEC_CONST_DECL (kSecPolicyNameAppleHomeAppClipUploadService
, "HomeAppClipUploadService");
136 #define kSecPolicySHA1Size 20
137 #define kSecPolicySHA256Size 32
138 __unused
const UInt8 kAppleCASHA1
[kSecPolicySHA1Size
] = {
139 0x61, 0x1E, 0x5B, 0x66, 0x2C, 0x59, 0x3A, 0x08, 0xFF, 0x58,
140 0xD1, 0x4A, 0xE2, 0x24, 0x52, 0xD1, 0x98, 0xDF, 0x6C, 0x60
143 __unused
static const UInt8 kAppleTESTCASHA1
[kSecPolicySHA1Size
] = {
144 0xbc, 0x30, 0x55, 0xc8, 0xc8, 0xd3, 0x48, 0x3f, 0xf4, 0x8d,
145 0xfe, 0x3d, 0x51, 0x75, 0x31, 0xc9, 0xf4, 0xd7, 0x4a, 0xf7
148 static const UInt8 kITMSCASHA1
[kSecPolicySHA1Size
] = {
149 0x1D, 0x33, 0x42, 0x46, 0x8B, 0x10, 0xBD, 0xE6, 0x45, 0xCE,
150 0x44, 0x6E, 0xBB, 0xE8, 0xF5, 0x03, 0x5D, 0xF8, 0x32, 0x22
153 static const UInt8 kFactoryDeviceCASHA1
[kSecPolicySHA1Size
] = {
154 0xef, 0x68, 0x73, 0x17, 0xa4, 0xf8, 0xf9, 0x4b, 0x7b, 0x21,
155 0xe2, 0x2f, 0x09, 0x8f, 0xfd, 0x6a, 0xae, 0xc0, 0x0d, 0x63
158 static const UInt8 kApplePKISettingsAuthority
[kSecPolicySHA1Size
] = {
159 0x1D, 0x0C, 0xBA, 0xAD, 0x17, 0xFD, 0x7E, 0x9E, 0x9F, 0xF1,
160 0xC9, 0xA2, 0x66, 0x79, 0x60, 0x00, 0x8B, 0xAE, 0x70, 0xB8
163 static const UInt8 kAppleTestPKISettingsAuthority
[kSecPolicySHA1Size
] = {
164 0xDB, 0xBA, 0x25, 0x0B, 0xD8, 0x62, 0x71, 0x87, 0x54, 0x7E,
165 0xD7, 0xEF, 0x11, 0x94, 0x7E, 0x82, 0xE6, 0xD8, 0x1C, 0x9A
168 static const UInt8 kTestAppleRootCA_ECC_SHA1
[kSecPolicySHA1Size
] = {
169 0x62, 0x0A, 0xED, 0x83, 0xD2, 0x97, 0x4A, 0x77, 0x56, 0x33,
170 0x83, 0xBE, 0xDB, 0xF9, 0xA1, 0xBD, 0x5F, 0xFE, 0x55, 0x7B
173 __unused
static const UInt8 kAppleRootCA_ECC_SHA1
[kSecPolicySHA1Size
] = {
174 0xB5, 0x2C, 0xB0, 0x2F, 0xD5, 0x67, 0xE0, 0x35, 0x9F, 0xE8,
175 0xFA, 0x4D, 0x4C, 0x41, 0x03, 0x79, 0x70, 0xFE, 0x01, 0xB0
180 /********************************************************
181 ****************** SecPolicy object ********************
182 ********************************************************/
184 static void SecPolicyDestroy(CFTypeRef cf
) {
185 SecPolicyRef policy
= (SecPolicyRef
) cf
;
186 CFRelease(policy
->_oid
);
187 CFReleaseSafe(policy
->_name
);
188 CFRelease(policy
->_options
);
191 static Boolean
SecPolicyCompare(CFTypeRef cf1
, CFTypeRef cf2
) {
192 SecPolicyRef policy1
= (SecPolicyRef
) cf1
;
193 SecPolicyRef policy2
= (SecPolicyRef
) cf2
;
194 if (policy1
->_name
&& policy2
->_name
) {
195 return CFEqual(policy1
->_oid
, policy2
->_oid
) &&
196 CFEqual(policy1
->_name
, policy2
->_name
) &&
197 CFEqual(policy1
->_options
, policy2
->_options
);
199 return CFEqual(policy1
->_oid
, policy2
->_oid
) &&
200 CFEqual(policy1
->_options
, policy2
->_options
);
204 static CFHashCode
SecPolicyHash(CFTypeRef cf
) {
205 SecPolicyRef policy
= (SecPolicyRef
) cf
;
207 return CFHash(policy
->_oid
) + CFHash(policy
->_name
) + CFHash(policy
->_options
);
209 return CFHash(policy
->_oid
) + CFHash(policy
->_options
);
213 static CFStringRef
SecPolicyCopyFormatDescription(CFTypeRef cf
, CFDictionaryRef formatOptions
) {
214 SecPolicyRef policy
= (SecPolicyRef
) cf
;
215 CFMutableStringRef desc
= CFStringCreateMutable(kCFAllocatorDefault
, 0);
216 CFStringRef typeStr
= CFCopyTypeIDDescription(CFGetTypeID(cf
));
217 CFStringAppendFormat(desc
, NULL
,
218 CFSTR("<%@: oid: %@ name: %@ options %@"), typeStr
,
219 policy
->_oid
, (policy
->_name
) ? policy
->_name
: CFSTR(""),
222 CFStringAppend(desc
, CFSTR(" >"));
227 /* SecPolicy API functions. */
228 CFGiblisWithHashFor(SecPolicy
);
230 /* AUDIT[securityd](done):
231 oid (ok) is a caller provided string, only its cf type has been checked.
232 options is a caller provided dictionary, only its cf type has been checked.
234 SecPolicyRef
SecPolicyCreate(CFStringRef oid
, CFStringRef name
, CFDictionaryRef options
) {
235 SecPolicyRef result
= NULL
;
237 require(oid
, errOut
);
238 require(options
, errOut
);
240 (SecPolicyRef
)_CFRuntimeCreateInstance(kCFAllocatorDefault
,
241 SecPolicyGetTypeID(),
242 sizeof(struct __SecPolicy
) - sizeof(CFRuntimeBase
), 0), errOut
);
247 result
->_name
= name
;
249 result
->_options
= options
;
256 static void set_ku_from_properties(SecPolicyRef policy
, CFDictionaryRef properties
);
259 SecPolicyRef
SecPolicyCreateWithProperties(CFTypeRef policyIdentifier
,
260 CFDictionaryRef properties
) {
261 // Creates a policy reference for a given policy object identifier.
262 // If policy-specific parameters can be supplied (e.g. hostname),
263 // attempt to obtain from input properties dictionary.
264 // Returns NULL if the given identifier is unsupported.
266 SecPolicyRef policy
= NULL
;
267 CFTypeRef name
= NULL
;
268 CFStringRef teamID
= NULL
;
269 Boolean client
= false;
270 CFDictionaryRef context
= NULL
;
271 CFStringRef policyName
= NULL
, intermediateMarkerOid
= NULL
, leafMarkerOid
= NULL
;
272 CFDataRef rootDigest
= NULL
;
273 require(policyIdentifier
&& (CFStringGetTypeID() == CFGetTypeID(policyIdentifier
)), errOut
);
276 name
= CFDictionaryGetValue(properties
, kSecPolicyName
);
277 teamID
= CFDictionaryGetValue(properties
, kSecPolicyTeamIdentifier
);
279 CFBooleanRef dictionaryClientValue
;
280 client
= (CFDictionaryGetValueIfPresent(properties
, kSecPolicyClient
, (const void **)&dictionaryClientValue
) &&
281 (dictionaryClientValue
!= NULL
) && CFEqual(kCFBooleanTrue
, dictionaryClientValue
));
282 context
= CFDictionaryGetValue(properties
, kSecPolicyContext
);
283 policyName
= CFDictionaryGetValue(properties
, kSecPolicyPolicyName
);
284 intermediateMarkerOid
= CFDictionaryGetValue(properties
, kSecPolicyIntermediateMarkerOid
);
285 leafMarkerOid
= CFDictionaryGetValue(properties
, kSecPolicyLeafMarkerOid
);
286 rootDigest
= CFDictionaryGetValue(properties
, kSecPolicyRootDigest
);
289 /* only the EAP policy allows a non-string name */
290 if (name
&& !isString(name
) && !CFEqual(policyIdentifier
, kSecPolicyAppleEAP
)) {
291 secerror("policy \"%@\" requires a string value for the %@ key", policyIdentifier
, kSecPolicyName
);
295 /* What follows are all the exceptional functions that do not match the macro below */
296 if (CFEqual(policyIdentifier
, kSecPolicyAppleSSL
)) {
297 policy
= SecPolicyCreateSSL(!client
, name
);
298 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleSMIME
)) {
299 policy
= SecPolicyCreateSMIME(kSecSignSMIMEUsage
| kSecAnyEncryptSMIME
, name
);
300 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleEAP
)) {
301 CFArrayRef array
= NULL
;
302 if (isString(name
)) {
303 array
= CFArrayCreate(kCFAllocatorDefault
, (const void **)&name
, 1, &kCFTypeArrayCallBacks
);
304 } else if (isArray(name
)) {
305 array
= CFArrayCreateCopy(NULL
, name
);
307 policy
= SecPolicyCreateEAP(!client
, array
);
308 CFReleaseSafe(array
);
309 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleIPsec
)) {
310 policy
= SecPolicyCreateIPSec(!client
, name
);
311 } else if (CFEqual(policyIdentifier
, kSecPolicyMacAppStoreReceipt
)) {
312 policy
= SecPolicyCreateMacAppStoreReceipt();
313 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleRevocation
)) {
314 policy
= SecPolicyCreateRevocation(kSecRevocationUseAnyAvailableMethod
);
315 } else if (CFEqual(policyIdentifier
, kSecPolicyApplePassbookSigning
)) {
316 policy
= SecPolicyCreatePassbookCardSigner(name
, teamID
);
317 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleAST2DiagnosticsServerAuth
)) {
319 policy
= SecPolicyCreateAppleAST2Service(name
, context
);
321 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier
);
323 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleEscrowProxyServerAuth
)) {
325 policy
= SecPolicyCreateAppleEscrowProxyService(name
, context
);
327 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier
);
329 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleFMiPServerAuth
)) {
331 policy
= SecPolicyCreateAppleFMiPService(name
, context
);
333 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier
);
335 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleMMCService
)) {
337 policy
= SecPolicyCreateAppleMMCSService(name
, context
);
339 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier
);
341 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleGSService
)) {
343 policy
= SecPolicyCreateAppleGSService(name
, context
);
345 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier
);
347 } else if (CFEqual(policyIdentifier
, kSecPolicyApplePPQService
)) {
349 policy
= SecPolicyCreateApplePPQService(name
, context
);
351 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier
);
353 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleGenericApplePinned
)) {
355 policy
= SecPolicyCreateApplePinned(policyName
, intermediateMarkerOid
, leafMarkerOid
);
357 secerror("policy \"%@\" requires kSecPolicyPolicyName input", policyIdentifier
);
359 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleGenericAppleSSLPinned
)) {
361 policy
= SecPolicyCreateAppleSSLPinned(policyName
, name
, intermediateMarkerOid
, leafMarkerOid
);
363 secerror("policy \"%@\" requires kSecPolicyPolicyName input", policyIdentifier
);
365 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleIDSServiceContext
)) {
367 policy
= SecPolicyCreateAppleIDSServiceContext(name
, context
);
369 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier
);
371 } else if (CFEqual(policyIdentifier
, kSecPolicyApplePushService
)) {
373 policy
= SecPolicyCreateApplePushService(name
, context
);
375 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier
);
377 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleUniqueDeviceIdentifierCertificate
)) {
378 policy
= SecPolicyCreateAppleUniqueDeviceCertificate(rootDigest
);
379 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleiCloudSetupServerAuth
)) {
381 policy
= SecPolicyCreateAppleiCloudSetupService(name
, context
);
383 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier
);
385 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleBasicAttestationSystem
)) {
386 policy
= SecPolicyCreateAppleBasicAttestationSystem(rootDigest
);
387 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleBasicAttestationUser
)) {
388 policy
= SecPolicyCreateAppleBasicAttestationUser(rootDigest
);
389 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleComponentCertificate
)) {
390 policy
= SecPolicyCreateAppleComponentCertificate(rootDigest
);
392 /* For a couple of common patterns we use the macro, but some of the
393 * policies are deprecated, so we need to ignore the warning. */
394 #pragma clang diagnostic push
395 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
397 #define _P_OPTION_N name
398 #define _P_PROPERTIES_(NAME, IN_NAME, FUNCTION)
399 #define _P_PROPERTIES_Y(NAME, IN_NAME, FUNCTION) else if (CFEqual(policyIdentifier, kSecPolicyApple##NAME)) { \
400 policy = SecPolicyCreate##FUNCTION(_P_OPTION_##IN_NAME); \
403 #define POLICYMACRO(NAME, OID, ISPUBLIC, INTNAME, IN_NAME, IN_PROPERTIES, FUNCTION) \
404 _P_PROPERTIES_##IN_PROPERTIES(NAME, IN_NAME, FUNCTION)
405 #include "SecPolicy.list"
407 secerror("ERROR: policy \"%@\" is unsupported", policyIdentifier
);
409 #pragma clang diagnostic pop // ignored "-Wdeprecated-declarations"
416 set_ku_from_properties(policy
, properties
);
420 SecPolicySetName(policy
, policyName
);
427 CFDictionaryRef
SecPolicyCopyProperties(SecPolicyRef policyRef
) {
428 // Builds and returns a dictionary which the caller must release.
430 #pragma clang diagnostic push
431 #pragma clang diagnostic ignored "-Wnonnull"
432 // After introducing nullability annotations, policyRef is supposed to be nonnull, suppress the warning
433 if (!policyRef
) return NULL
;
434 #pragma clang diagnostic pop
435 CFMutableDictionaryRef properties
= CFDictionaryCreateMutable(NULL
, 0,
436 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
437 #pragma clang diagnostic push
438 #pragma clang diagnostic ignored "-Wnonnull"
439 // 'properties' is nonnull in reality suppress the warning
440 if (!properties
) return NULL
;
441 #pragma clang diagnostic pop
442 CFStringRef oid
= (CFStringRef
) CFRetain(policyRef
->_oid
);
443 CFTypeRef nameKey
= NULL
;
445 // Determine name key
446 if (policyRef
->_options
) {
447 if (CFDictionaryContainsKey(policyRef
->_options
, kSecPolicyCheckSSLHostname
)) {
448 nameKey
= kSecPolicyCheckSSLHostname
;
449 } else if (CFDictionaryContainsKey(policyRef
->_options
, kSecPolicyCheckEAPTrustedServerNames
)) {
450 nameKey
= kSecPolicyCheckEAPTrustedServerNames
;
451 } else if (CFDictionaryContainsKey(policyRef
->_options
, kSecPolicyCheckEmail
)) {
452 nameKey
= kSecPolicyCheckEmail
;
457 CFDictionarySetValue(properties
, (const void *)kSecPolicyOid
,
460 // Set kSecPolicyName if we have one
461 if (nameKey
&& policyRef
->_options
) {
462 CFTypeRef name
= (CFTypeRef
) CFDictionaryGetValue(policyRef
->_options
,
465 CFDictionarySetValue(properties
, (const void *)kSecPolicyName
,
470 // Set kSecPolicyClient
471 CFStringRef policyName
= (CFStringRef
) CFRetainSafe(policyRef
->_name
);
472 if (policyName
&& (CFEqual(policyName
, kSecPolicyNameSSLClient
) ||
473 CFEqual(policyName
, kSecPolicyNameIPSecClient
) ||
474 CFEqual(policyName
, kSecPolicyNameEAPClient
))) {
475 CFDictionarySetValue(properties
, (const void *)kSecPolicyClient
,
476 (const void *)kCFBooleanTrue
);
483 static void SecPolicySetOid(SecPolicyRef policy
, CFStringRef oid
) {
484 if (!policy
|| !oid
) return;
485 CFStringRef temp
= policy
->_oid
;
491 void SecPolicySetName(SecPolicyRef policy
, CFStringRef policyName
) {
492 if (!policy
|| !policyName
) return;
493 CFStringRef temp
= policy
->_name
;
494 CFRetain(policyName
);
495 policy
->_name
= policyName
;
499 CFStringRef
SecPolicyGetOidString(SecPolicyRef policy
) {
503 CFStringRef
SecPolicyGetName(SecPolicyRef policy
) {
504 return policy
->_name
;
507 CFDictionaryRef
SecPolicyGetOptions(SecPolicyRef policy
) {
508 return policy
->_options
;
511 void SecPolicySetOptionsValue(SecPolicyRef policy
, CFStringRef key
, CFTypeRef value
) {
512 if (!policy
|| !key
) return;
513 CFMutableDictionaryRef options
= (CFMutableDictionaryRef
) policy
->_options
;
515 options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
516 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
517 if (!options
) return;
518 policy
->_options
= options
;
520 CFDictionarySetValue(options
, key
, value
);
523 /* Local forward declaration */
524 static void set_ssl_ekus(CFMutableDictionaryRef options
, bool server
);
527 // this is declared as NA for iPhone in SecPolicy.h, so declare here
528 OSStatus
SecPolicySetProperties(SecPolicyRef policyRef
, CFDictionaryRef properties
);
531 OSStatus
SecPolicySetProperties(SecPolicyRef policyRef
, CFDictionaryRef properties
) {
532 // Set policy options based on the provided dictionary keys.
534 if (!(policyRef
&& properties
&& (CFDictionaryGetTypeID() == CFGetTypeID(properties
)))) {
537 CFStringRef oid
= (CFStringRef
) CFRetain(policyRef
->_oid
);
538 OSStatus result
= errSecSuccess
;
541 CFTypeRef name
= NULL
;
542 if (CFDictionaryGetValueIfPresent(properties
, (const void *)kSecPolicyName
,
543 (const void **)&name
) && name
) {
544 CFTypeID typeID
= CFGetTypeID(name
);
545 if (CFEqual(oid
, kSecPolicyAppleSSL
) ||
546 CFEqual(oid
, kSecPolicyAppleIPsec
)) {
547 if (CFStringGetTypeID() == typeID
) {
548 SecPolicySetOptionsValue(policyRef
, kSecPolicyCheckSSLHostname
, name
);
550 else result
= errSecParam
;
552 else if (CFEqual(oid
, kSecPolicyAppleEAP
)) {
553 if ((CFStringGetTypeID() == typeID
) ||
554 (CFArrayGetTypeID() == typeID
)) {
555 SecPolicySetOptionsValue(policyRef
, kSecPolicyCheckEAPTrustedServerNames
, name
);
557 else result
= errSecParam
;
559 else if (CFEqual(oid
, kSecPolicyAppleSMIME
)) {
560 if (CFStringGetTypeID() == typeID
) {
561 SecPolicySetOptionsValue(policyRef
, kSecPolicyCheckEmail
, name
);
563 else result
= errSecParam
;
568 CFTypeRef client
= NULL
;
569 if (CFDictionaryGetValueIfPresent(properties
, (const void *)kSecPolicyClient
,
570 (const void **)&client
) && client
) {
571 if (!(CFBooleanGetTypeID() == CFGetTypeID(client
))) {
572 result
= errSecParam
;
574 else if (CFEqual(client
, kCFBooleanTrue
)) {
575 if (CFEqual(oid
, kSecPolicyAppleSSL
)) {
576 SecPolicySetName(policyRef
, kSecPolicyNameSSLClient
);
577 /* Set EKU checks for clients */
578 CFMutableDictionaryRef newOptions
= CFDictionaryCreateMutableCopy(NULL
, 0, policyRef
->_options
);
579 set_ssl_ekus(newOptions
, false);
580 CFReleaseSafe(policyRef
->_options
);
581 policyRef
->_options
= newOptions
;
583 else if (CFEqual(oid
, kSecPolicyAppleIPsec
)) {
584 SecPolicySetName(policyRef
, kSecPolicyNameIPSecClient
);
586 else if (CFEqual(oid
, kSecPolicyNameEAPServer
)) {
587 SecPolicySetName(policyRef
, kSecPolicyNameEAPClient
);
588 /* Set EKU checks for clients */
589 CFMutableDictionaryRef newOptions
= CFDictionaryCreateMutableCopy(NULL
, 0, policyRef
->_options
);
590 set_ssl_ekus(newOptions
, false);
591 CFReleaseSafe(policyRef
->_options
);
592 policyRef
->_options
= newOptions
;
596 if (CFEqual(oid
, kSecPolicyAppleSSL
)) {
597 SecPolicySetName(policyRef
, kSecPolicyNameSSLServer
);
598 /* Set EKU checks for servers */
599 CFMutableDictionaryRef newOptions
= CFDictionaryCreateMutableCopy(NULL
, 0, policyRef
->_options
);
600 set_ssl_ekus(newOptions
, true);
601 CFReleaseSafe(policyRef
->_options
);
602 policyRef
->_options
= newOptions
;
604 else if (CFEqual(oid
, kSecPolicyAppleIPsec
)) {
605 SecPolicySetName(policyRef
, kSecPolicyNameIPSecServer
);
607 else if (CFEqual(oid
, kSecPolicyAppleEAP
)) {
608 SecPolicySetName(policyRef
, kSecPolicyNameEAPServer
);
609 /* Set EKU checks for servers */
610 CFMutableDictionaryRef newOptions
= CFDictionaryCreateMutableCopy(NULL
, 0, policyRef
->_options
);
611 set_ssl_ekus(newOptions
, true);
612 CFReleaseSafe(policyRef
->_options
);
613 policyRef
->_options
= newOptions
;
619 set_ku_from_properties(policyRef
, properties
);
625 static xpc_object_t
copy_xpc_policy_object(SecPolicyRef policy
);
626 static bool append_policy_to_xpc_array(SecPolicyRef policy
, xpc_object_t xpc_policies
);
627 extern xpc_object_t
copy_xpc_policies_array(CFArrayRef policies
);
628 extern OSStatus
validate_array_of_items(CFArrayRef array
, CFStringRef arrayItemType
, CFTypeID itemTypeID
, bool required
);
630 static xpc_object_t
copy_xpc_policy_object(SecPolicyRef policy
) {
631 xpc_object_t xpc_policy
= NULL
;
632 xpc_object_t data
[2] = { NULL
, NULL
};
633 if (policy
->_oid
&& (CFGetTypeID(policy
->_oid
) == CFStringGetTypeID()) &&
634 policy
->_name
&& (CFGetTypeID(policy
->_name
) == CFStringGetTypeID())) {
635 /* These should really be different elements of the xpc array. But
636 * SecPolicyCreateWithXPCObject previously checked the size via ==, which prevents
637 * us from appending new information while maintaining backward compatibility.
638 * Doing this makes the builders happy. */
639 CFMutableStringRef oidAndName
= NULL
;
640 oidAndName
= CFStringCreateMutableCopy(NULL
, 0, policy
->_oid
);
642 CFStringAppend(oidAndName
, CFSTR("++"));
643 CFStringAppend(oidAndName
, policy
->_name
);
644 data
[0] = _CFXPCCreateXPCObjectFromCFObject(oidAndName
);
645 CFReleaseNull(oidAndName
);
647 data
[0] = _CFXPCCreateXPCObjectFromCFObject(policy
->_oid
);
649 } else if (policy
->_oid
&& (CFGetTypeID(policy
->_oid
) == CFStringGetTypeID())) {
650 data
[0] = _CFXPCCreateXPCObjectFromCFObject(policy
->_oid
);
652 secerror("policy 0x%lX has no _oid", (uintptr_t)policy
);
654 if (policy
->_options
&& (CFGetTypeID(policy
->_options
) == CFDictionaryGetTypeID())) {
655 data
[1] = _CFXPCCreateXPCObjectFromCFObject(policy
->_options
);
657 secerror("policy 0x%lX has no _options", (uintptr_t)policy
);
659 xpc_policy
= xpc_array_create(data
, array_size(data
));
660 if (data
[0]) xpc_release(data
[0]);
661 if (data
[1]) xpc_release(data
[1]);
665 static bool append_policy_to_xpc_array(SecPolicyRef policy
, xpc_object_t xpc_policies
) {
669 xpc_object_t xpc_policy
= copy_xpc_policy_object(policy
);
673 xpc_array_append_value(xpc_policies
, xpc_policy
);
674 xpc_release(xpc_policy
);
678 xpc_object_t
copy_xpc_policies_array(CFArrayRef policies
) {
679 xpc_object_t xpc_policies
= xpc_array_create(NULL
, 0);
683 validate_array_of_items(policies
, CFSTR("policy"), SecPolicyGetTypeID(), true);
684 CFIndex ix
, count
= CFArrayGetCount(policies
);
685 for (ix
= 0; ix
< count
; ++ix
) {
686 SecPolicyRef policy
= (SecPolicyRef
) CFArrayGetValueAtIndex(policies
, ix
);
687 #if SECTRUST_VERBOSE_DEBUG
688 CFDictionaryRef props
= SecPolicyCopyProperties(policy
);
689 secerror("idx=%d of %d; policy=0x%lX properties=%@", (int)ix
, (int)count
, (uintptr_t)policy
, props
);
690 CFReleaseSafe(props
);
692 if (!append_policy_to_xpc_array(policy
, xpc_policies
)) {
693 xpc_release(xpc_policies
);
701 static xpc_object_t
SecPolicyCopyXPCObject(SecPolicyRef policy
, CFErrorRef
*error
) {
702 xpc_object_t xpc_policy
= NULL
;
703 xpc_object_t data
[2] = {};
704 CFMutableStringRef oidAndName
= NULL
;
705 oidAndName
= CFStringCreateMutableCopy(NULL
, 0, policy
->_oid
);
708 CFStringAppend(oidAndName
, CFSTR("++"));
709 CFStringAppend(oidAndName
, policy
->_name
);
712 require_action_quiet(data
[0] = _CFXPCCreateXPCObjectFromCFObject(oidAndName
), exit
,
713 SecError(errSecParam
, error
,
714 CFSTR("failed to create xpc_object from policy oid and name")));
716 require_action_quiet(data
[0] = _CFXPCCreateXPCObjectFromCFObject(policy
->_oid
), exit
,
717 SecError(errSecParam
, error
, CFSTR("failed to create xpc_object from policy oid")));
719 require_action_quiet(data
[1] = _CFXPCCreateXPCObjectFromCFObject(policy
->_options
), exit
,
720 SecError(errSecParam
, error
, CFSTR("failed to create xpc_object from policy options")));
721 require_action_quiet(xpc_policy
= xpc_array_create(data
, array_size(data
)), exit
,
722 SecError(errSecAllocate
, error
, CFSTR("failed to create xpc_array for policy")));
725 if (data
[0]) xpc_release(data
[0]);
726 if (data
[1]) xpc_release(data
[1]);
727 CFReleaseNull(oidAndName
);
731 static bool SecPolicyAppendToXPCArray(SecPolicyRef policy
, xpc_object_t policies
, CFErrorRef
*error
) {
735 xpc_object_t xpc_policy
= SecPolicyCopyXPCObject(policy
, error
);
739 xpc_array_append_value(policies
, xpc_policy
);
740 xpc_release(xpc_policy
);
744 xpc_object_t
SecPolicyArrayCopyXPCArray(CFArrayRef policies
, CFErrorRef
*error
) {
745 xpc_object_t xpc_policies
;
746 require_action_quiet(xpc_policies
= xpc_array_create(NULL
, 0), exit
,
747 SecError(errSecAllocate
, error
, CFSTR("failed to create xpc_array")));
748 CFIndex ix
, count
= CFArrayGetCount(policies
);
749 for (ix
= 0; ix
< count
; ++ix
) {
750 if (!SecPolicyAppendToXPCArray((SecPolicyRef
)CFArrayGetValueAtIndex(policies
, ix
), xpc_policies
, error
)) {
751 xpc_release(xpc_policies
);
759 static OSStatus
parseOidAndName(CFStringRef oidAndName
, CFStringRef
*oid
, CFStringRef
*name
) {
760 OSStatus result
= errSecSuccess
;
761 CFStringRef partial
= NULL
;
763 CFRange delimiter
= CFStringFind(oidAndName
, CFSTR("++"), 0);
764 if (delimiter
.length
!= 2) {
768 /* get first half: oid */
769 partial
= CFStringCreateWithSubstring(NULL
, oidAndName
, CFRangeMake(0, delimiter
.location
));
770 if (oid
) { *oid
= CFRetainSafe(partial
); }
771 CFReleaseNull(partial
);
773 /* get second half: name */
774 if (delimiter
.location
+ 2 >= CFStringGetLength(oidAndName
)) {
775 return errSecSuccess
; // name is optional
777 CFRange nameRange
= CFRangeMake(delimiter
.location
+2,
778 CFStringGetLength(oidAndName
) - delimiter
.location
- 2);
779 partial
= CFStringCreateWithSubstring(NULL
, oidAndName
, nameRange
);
780 if (name
) { *name
= CFRetainSafe(partial
); }
781 CFReleaseNull(partial
);
785 static SecPolicyRef
SecPolicyCreateWithXPCObject(xpc_object_t xpc_policy
, CFErrorRef
*error
) {
786 SecPolicyRef policy
= NULL
;
787 CFTypeRef oidAndName
= NULL
;
788 CFStringRef oid
= NULL
;
789 CFStringRef name
= NULL
;
790 CFTypeRef options
= NULL
;
792 require_action_quiet(xpc_policy
, exit
, SecError(errSecParam
, error
, CFSTR("policy xpc value is NULL")));
793 require_action_quiet(xpc_get_type(xpc_policy
) == XPC_TYPE_ARRAY
, exit
, SecError(errSecDecode
, error
, CFSTR("policy xpc value is not an array")));
794 require_action_quiet(xpc_array_get_count(xpc_policy
) >= 2, exit
, SecError(errSecDecode
, error
, CFSTR("policy xpc array count < 2")));
795 oidAndName
= _CFXPCCreateCFObjectFromXPCObject(xpc_array_get_value(xpc_policy
, 0));
796 require_action_quiet(isString(oidAndName
), exit
,
797 SecError(errSecParam
, error
, CFSTR("failed to convert xpc policy[0]=%@ to CFString"), oidAndName
));
798 options
= _CFXPCCreateCFObjectFromXPCObject(xpc_array_get_value(xpc_policy
, 1));
799 require_action_quiet(isDictionary(options
), exit
,
800 SecError(errSecParam
, error
, CFSTR("failed to convert xpc policy[1]=%@ to CFDictionary"), options
));
801 require_noerr_action_quiet(parseOidAndName(oidAndName
, &oid
, &name
), exit
,
802 SecError(errSecParam
, error
, CFSTR("failed to convert combined %@ to name and oid"), oidAndName
));
803 require_action_quiet(policy
= SecPolicyCreate(oid
, name
, options
), exit
,
804 SecError(errSecDecode
, error
, CFSTR("Failed to create policy")));
807 CFReleaseSafe(oidAndName
);
810 CFReleaseSafe(options
);
814 CFArrayRef
SecPolicyXPCArrayCopyArray(xpc_object_t xpc_policies
, CFErrorRef
*error
) {
815 CFMutableArrayRef policies
= NULL
;
816 require_action_quiet(xpc_get_type(xpc_policies
) == XPC_TYPE_ARRAY
, exit
,
817 SecError(errSecParam
, error
, CFSTR("policies xpc value is not an array")));
818 size_t count
= xpc_array_get_count(xpc_policies
);
819 require_action_quiet(policies
= CFArrayCreateMutable(kCFAllocatorDefault
, count
, &kCFTypeArrayCallBacks
), exit
,
820 SecError(errSecAllocate
, error
, CFSTR("failed to create CFArray of capacity %zu"), count
));
823 for (ix
= 0; ix
< count
; ++ix
) {
824 SecPolicyRef policy
= SecPolicyCreateWithXPCObject(xpc_array_get_value(xpc_policies
, ix
), error
);
829 CFArraySetValueAtIndex(policies
, ix
, policy
);
838 static SEC_CONST_DECL (kSecPolicyOptions
, "policyOptions");
840 static SecPolicyRef
SecPolicyCreateWithDictionary(CFDictionaryRef dict
) {
841 SecPolicyRef policy
= NULL
;
842 CFStringRef oid
= (CFStringRef
)CFDictionaryGetValue(dict
, kSecPolicyOid
);
843 require_quiet(isString(oid
), errOut
);
844 CFDictionaryRef options
= (CFDictionaryRef
)CFDictionaryGetValue(dict
, kSecPolicyOptions
);
845 require_quiet(isDictionary(options
), errOut
);
846 CFStringRef name
= (CFStringRef
)CFDictionaryGetValue(dict
, kSecPolicyPolicyName
);
847 policy
= SecPolicyCreate(oid
, name
, options
);
852 static void deserializePolicy(const void *value
, void *context
) {
853 CFDictionaryRef policyDict
= (CFDictionaryRef
)value
;
854 if (isDictionary(policyDict
)) {
855 CFTypeRef deserializedPolicy
= SecPolicyCreateWithDictionary(policyDict
);
856 if (deserializedPolicy
) {
857 CFArrayAppendValue((CFMutableArrayRef
)context
, deserializedPolicy
);
858 CFRelease(deserializedPolicy
);
863 CFArrayRef
SecPolicyArrayCreateDeserialized(CFArrayRef serializedPolicies
) {
864 CFMutableArrayRef result
= NULL
;
865 require_quiet(isArray(serializedPolicies
), errOut
);
866 CFIndex count
= CFArrayGetCount(serializedPolicies
);
867 result
= CFArrayCreateMutable(kCFAllocatorDefault
, count
, &kCFTypeArrayCallBacks
);
868 CFRange all_policies
= { 0, count
};
869 CFArrayApplyFunction(serializedPolicies
, all_policies
, deserializePolicy
, result
);
874 static CFDictionaryRef
SecPolicyCreateDictionary(SecPolicyRef policy
) {
875 CFMutableDictionaryRef dict
= NULL
;
876 dict
= CFDictionaryCreateMutable(NULL
, 3, &kCFTypeDictionaryKeyCallBacks
,
877 &kCFTypeDictionaryValueCallBacks
);
878 CFDictionaryAddValue(dict
, kSecPolicyOid
, policy
->_oid
);
879 CFDictionaryAddValue(dict
, kSecPolicyOptions
, policy
->_options
);
881 CFDictionaryAddValue(dict
, kSecPolicyPolicyName
, policy
->_name
);
886 static void serializePolicy(const void *value
, void *context
) {
887 SecPolicyRef policy
= (SecPolicyRef
)value
;
888 if (policy
&& SecPolicyGetTypeID() == CFGetTypeID(policy
)) {
889 CFDictionaryRef serializedPolicy
= SecPolicyCreateDictionary(policy
);
890 if (serializedPolicy
) {
891 CFArrayAppendValue((CFMutableArrayRef
)context
, serializedPolicy
);
892 CFRelease(serializedPolicy
);
897 CFArrayRef
SecPolicyArrayCreateSerialized(CFArrayRef policies
) {
898 CFMutableArrayRef result
= NULL
;
899 require_quiet(isArray(policies
), errOut
);
900 CFIndex count
= CFArrayGetCount(policies
);
901 result
= CFArrayCreateMutable(NULL
, count
, &kCFTypeArrayCallBacks
);
902 CFRange all_policies
= { 0, count
};
903 CFArrayApplyFunction(policies
, all_policies
, serializePolicy
, result
);
908 static void add_element(CFMutableDictionaryRef options
, CFStringRef key
,
910 CFTypeRef old_value
= CFDictionaryGetValue(options
, key
);
912 CFMutableArrayRef array
;
913 if (CFGetTypeID(old_value
) == CFArrayGetTypeID()) {
914 array
= (CFMutableArrayRef
)old_value
;
916 array
= CFArrayCreateMutable(kCFAllocatorDefault
, 0,
917 &kCFTypeArrayCallBacks
);
918 CFArrayAppendValue(array
, old_value
);
919 CFDictionarySetValue(options
, key
, array
);
922 CFArrayAppendValue(array
, value
);
924 CFDictionaryAddValue(options
, key
, value
);
928 static void add_eku(CFMutableDictionaryRef options
, const DERItem
*ekuOid
) {
929 CFDataRef eku
= CFDataCreate(kCFAllocatorDefault
,
930 ekuOid
? ekuOid
->data
: NULL
,
931 ekuOid
? ekuOid
->length
: 0);
933 add_element(options
, kSecPolicyCheckExtendedKeyUsage
, eku
);
938 static void add_eku_string(CFMutableDictionaryRef options
, CFStringRef ekuOid
) {
940 add_element(options
, kSecPolicyCheckExtendedKeyUsage
, ekuOid
);
944 static void set_ssl_ekus(CFMutableDictionaryRef options
, bool server
) {
945 CFDictionaryRemoveValue(options
, kSecPolicyCheckExtendedKeyUsage
);
947 /* If server and EKU ext present then EKU ext should contain one of
948 ServerAuth or ExtendedKeyUsageAny or NetscapeSGC or MicrosoftSGC.
949 else if !server and EKU ext present then EKU ext should contain one of
950 ClientAuth or ExtendedKeyUsageAny. */
952 /* We always allow certificates that specify oidAnyExtendedKeyUsage. */
953 add_eku(options
, NULL
); /* eku extension is optional */
954 add_eku(options
, &oidAnyExtendedKeyUsage
);
956 add_eku(options
, &oidExtendedKeyUsageServerAuth
);
957 add_eku(options
, &oidExtendedKeyUsageMicrosoftSGC
);
958 add_eku(options
, &oidExtendedKeyUsageNetscapeSGC
);
960 add_eku(options
, &oidExtendedKeyUsageClientAuth
);
964 static void add_ku(CFMutableDictionaryRef options
, SecKeyUsage keyUsage
) {
965 SInt32 dku
= keyUsage
;
966 CFNumberRef ku
= CFNumberCreate(kCFAllocatorDefault
, kCFNumberSInt32Type
,
969 add_element(options
, kSecPolicyCheckKeyUsage
, ku
);
975 static void set_ku_from_properties(SecPolicyRef policy
, CFDictionaryRef properties
) {
976 if (!policy
|| !properties
) {
980 CFStringRef keyNames
[] = { kSecPolicyKU_DigitalSignature
, kSecPolicyKU_NonRepudiation
, kSecPolicyKU_KeyEncipherment
, kSecPolicyKU_DataEncipherment
,
981 kSecPolicyKU_KeyAgreement
, kSecPolicyKU_KeyCertSign
, kSecPolicyKU_CRLSign
, kSecPolicyKU_EncipherOnly
, kSecPolicyKU_DecipherOnly
};
983 uint32_t keyUsageValues
[] = { kSecKeyUsageDigitalSignature
, kSecKeyUsageNonRepudiation
, kSecKeyUsageKeyEncipherment
, kSecKeyUsageDataEncipherment
,
984 kSecKeyUsageKeyAgreement
, kSecKeyUsageKeyCertSign
, kSecKeyUsageCRLSign
, kSecKeyUsageEncipherOnly
, kSecKeyUsageDecipherOnly
};
986 bool haveKeyUsage
= false;
987 CFTypeRef keyUsageBoolean
;
988 for (uint32_t i
= 0; i
< sizeof(keyNames
) / sizeof(CFStringRef
); ++i
) {
989 if (CFDictionaryGetValueIfPresent(properties
, keyNames
[i
], (const void**)&keyUsageBoolean
)) {
990 if (CFEqual(keyUsageBoolean
, kCFBooleanTrue
)) {
1001 CFMutableDictionaryRef options
= (CFMutableDictionaryRef
) policy
->_options
;
1003 options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1004 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
1005 if (!options
) return;
1006 policy
->_options
= options
;
1008 CFDictionaryRemoveValue(options
, kSecPolicyCheckKeyUsage
);
1011 for (uint32_t i
= 0; i
< sizeof(keyNames
) / sizeof(CFStringRef
); ++i
) {
1012 if (CFDictionaryGetValueIfPresent(properties
, keyNames
[i
], (const void**)&keyUsageBoolean
)) {
1013 if (CFEqual(keyUsageBoolean
, kCFBooleanTrue
)) {
1014 add_ku(options
, keyUsageValues
[i
]);
1021 static void add_oid(CFMutableDictionaryRef options
, CFStringRef policy_key
, const DERItem
*oid
) {
1022 CFDataRef oid_data
= CFDataCreate(kCFAllocatorDefault
,
1023 oid
? oid
->data
: NULL
,
1024 oid
? oid
->length
: 0);
1026 add_element(options
, policy_key
, oid_data
);
1027 CFRelease(oid_data
);
1031 static void add_leaf_marker_value(CFMutableDictionaryRef options
, const DERItem
*markerOid
, CFStringRef string_value
) {
1033 CFTypeRef policyData
= NULL
;
1035 if (NULL
== string_value
) {
1036 policyData
= CFDataCreate(kCFAllocatorDefault
,
1037 markerOid
? markerOid
->data
: NULL
,
1038 markerOid
? markerOid
->length
: 0);
1040 CFStringRef oid_as_string
= SecDERItemCopyOIDDecimalRepresentation(kCFAllocatorDefault
, markerOid
);
1042 const void *key
[1] = { oid_as_string
};
1043 const void *value
[1] = { string_value
};
1044 policyData
= CFDictionaryCreate(kCFAllocatorDefault
,
1046 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
1047 CFReleaseNull(oid_as_string
);
1050 add_element(options
, kSecPolicyCheckLeafMarkerOid
, policyData
);
1052 CFReleaseNull(policyData
);
1056 static void add_leaf_marker(CFMutableDictionaryRef options
, const DERItem
*markerOid
) {
1057 add_leaf_marker_value(options
, markerOid
, NULL
);
1060 static void add_leaf_marker_value_string(CFMutableDictionaryRef options
, CFStringRef markerOid
, CFStringRef string_value
) {
1061 if (NULL
== string_value
) {
1062 add_element(options
, kSecPolicyCheckLeafMarkerOid
, markerOid
);
1064 CFDictionaryRef policyData
= NULL
;
1065 const void *key
[1] = { markerOid
};
1066 const void *value
[1] = { string_value
};
1067 policyData
= CFDictionaryCreate(kCFAllocatorDefault
,
1069 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
1070 add_element(options
, kSecPolicyCheckLeafMarkerOid
, policyData
);
1072 CFReleaseNull(policyData
);
1076 static void add_leaf_marker_string(CFMutableDictionaryRef options
, CFStringRef markerOid
) {
1077 add_leaf_marker_value_string(options
, markerOid
, NULL
);
1080 static void add_leaf_prod_qa_element(CFMutableDictionaryRef options
, CFTypeRef prodValue
, CFTypeRef qaValue
)
1082 CFMutableDictionaryRef prodAndQADictionary
= CFDictionaryCreateMutable(NULL
, 0, &kCFTypeDictionaryKeyCallBacks
,
1083 &kCFTypeDictionaryValueCallBacks
);
1084 CFDictionaryRef old_value
= CFDictionaryGetValue(options
, kSecPolicyCheckLeafMarkersProdAndQA
);
1086 CFMutableArrayRef prodArray
= NULL
, qaArray
= NULL
;
1087 CFTypeRef old_prod_value
= CFDictionaryGetValue(old_value
, kSecPolicyLeafMarkerProd
);
1088 CFTypeRef old_qa_value
= CFDictionaryGetValue(old_value
, kSecPolicyLeafMarkerQA
);
1089 if (isArray(old_prod_value
) && isArray(old_qa_value
)) {
1090 prodArray
= (CFMutableArrayRef
)CFRetainSafe(old_prod_value
);
1091 qaArray
= (CFMutableArrayRef
)CFRetainSafe(old_qa_value
);
1093 prodArray
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
1094 qaArray
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
1095 CFArrayAppendValue(prodArray
, old_prod_value
);
1096 CFArrayAppendValue(qaArray
, old_qa_value
);
1098 CFArrayAppendValue(prodArray
, prodValue
);
1099 CFArrayAppendValue(qaArray
, qaValue
);
1100 CFDictionaryAddValue(prodAndQADictionary
, kSecPolicyLeafMarkerProd
, prodArray
);
1101 CFDictionaryAddValue(prodAndQADictionary
, kSecPolicyLeafMarkerQA
, qaArray
);
1102 CFReleaseNull(prodArray
);
1103 CFReleaseNull(qaArray
);
1106 CFDictionaryAddValue(prodAndQADictionary
, kSecPolicyLeafMarkerProd
, prodValue
);
1107 CFDictionaryAddValue(prodAndQADictionary
, kSecPolicyLeafMarkerQA
, qaValue
);
1109 CFDictionarySetValue(options
, kSecPolicyCheckLeafMarkersProdAndQA
, prodAndQADictionary
);
1110 CFReleaseNull(prodAndQADictionary
);
1114 static void add_leaf_prod_qa_markers(CFMutableDictionaryRef options
, const DERItem
*prodMarkerOid
, const DERItem
*qaMarkerOid
)
1116 CFDataRef prodData
= NULL
, qaData
= NULL
;
1117 prodData
= CFDataCreate(NULL
, prodMarkerOid
? prodMarkerOid
->data
: NULL
,
1118 prodMarkerOid
? prodMarkerOid
->length
: 0);
1119 qaData
= CFDataCreate(NULL
, qaMarkerOid
? qaMarkerOid
->data
: NULL
,
1120 qaMarkerOid
? qaMarkerOid
->length
: 0);
1121 add_leaf_prod_qa_element(options
, prodData
, qaData
);
1122 CFReleaseNull(prodData
);
1123 CFReleaseNull(qaData
);
1126 static void add_leaf_prod_qa_markers_string(CFMutableDictionaryRef options
, CFStringRef prodMarkerOid
, CFStringRef qaMarkerOid
)
1128 add_leaf_prod_qa_element(options
, prodMarkerOid
, qaMarkerOid
);
1131 static void add_leaf_prod_qa_markers_value_string(CFMutableDictionaryRef options
,
1132 CFStringRef prodMarkerOid
, CFStringRef prod_value
,
1133 CFStringRef qaMarkerOid
, CFStringRef qa_value
)
1135 if (!prod_value
&& !qa_value
) {
1136 add_leaf_prod_qa_element(options
, prodMarkerOid
, qaMarkerOid
);
1138 CFDictionaryRef prodData
= NULL
, qaData
= NULL
;
1139 const void *prodKey
[1] = { prodMarkerOid
}, *qaKey
[1] = { qaMarkerOid
};
1140 const void *prodValue
[1] = { prod_value
}, *qaValue
[1] = { qa_value
};
1141 prodData
= CFDictionaryCreate(NULL
, prodKey
, prodValue
, 1, &kCFTypeDictionaryKeyCallBacks
,
1142 &kCFTypeDictionaryValueCallBacks
);
1143 qaData
= CFDictionaryCreate(NULL
, qaKey
, qaValue
, 1, &kCFTypeDictionaryKeyCallBacks
,
1144 &kCFTypeDictionaryValueCallBacks
);
1145 add_leaf_prod_qa_element(options
, prodData
, qaData
);
1146 CFReleaseNull(prodData
);
1147 CFReleaseNull(qaData
);
1151 static void add_intermediate_marker_value_string(CFMutableDictionaryRef options
, CFStringRef markerOid
, CFStringRef string_value
) {
1152 if (NULL
== string_value
) {
1153 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, markerOid
);
1155 CFDictionaryRef policyData
= NULL
;
1156 const void *key
[1] = { markerOid
};
1157 const void *value
[1] = { string_value
};
1158 policyData
= CFDictionaryCreate(kCFAllocatorDefault
,
1160 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
1161 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, policyData
);
1163 CFReleaseNull(policyData
);
1167 static void add_certificate_policy_oid(CFMutableDictionaryRef options
, const DERItem
*certificatePolicyOid
) {
1168 CFTypeRef certificatePolicyData
= NULL
;
1169 certificatePolicyData
= CFDataCreate(kCFAllocatorDefault
,
1170 certificatePolicyOid
? certificatePolicyOid
->data
: NULL
,
1171 certificatePolicyOid
? certificatePolicyOid
->length
: 0);
1172 if (certificatePolicyData
) {
1173 add_element(options
, kSecPolicyCheckCertificatePolicy
, certificatePolicyData
);
1174 CFRelease(certificatePolicyData
);
1178 static void add_certificate_policy_oid_string(CFMutableDictionaryRef options
, CFStringRef certificatePolicyOid
) {
1179 if (certificatePolicyOid
) {
1180 add_element(options
, kSecPolicyCheckCertificatePolicy
, certificatePolicyOid
);
1185 // Routines for adding dictionary entries for policies.
1188 // X.509, but missing validity requirements.
1189 static void SecPolicyAddBasicCertOptions(CFMutableDictionaryRef options
)
1191 //CFDictionaryAddValue(options, kSecPolicyCheckBasicCertificateProcessing, kCFBooleanTrue);
1192 // Happens automatically in SecPVCPathChecks
1193 CFDictionaryAddValue(options
, kSecPolicyCheckCriticalExtensions
, kCFBooleanTrue
);
1194 CFDictionaryAddValue(options
, kSecPolicyCheckIdLinkage
, kCFBooleanTrue
);
1195 CFDictionaryAddValue(options
, kSecPolicyCheckBasicConstraints
, kCFBooleanTrue
);
1196 CFDictionaryAddValue(options
, kSecPolicyCheckNonEmptySubject
, kCFBooleanTrue
);
1197 CFDictionaryAddValue(options
, kSecPolicyCheckWeakKeySize
, kCFBooleanTrue
);
1198 CFDictionaryAddValue(options
, kSecPolicyCheckWeakSignature
, kCFBooleanTrue
);
1201 static void SecPolicyAddBasicX509Options(CFMutableDictionaryRef options
)
1203 SecPolicyAddBasicCertOptions(options
);
1204 CFDictionaryAddValue(options
, kSecPolicyCheckTemporalValidity
, kCFBooleanTrue
);
1206 // Make sure that black and gray leaf checks are performed for basic X509 chain building
1207 CFDictionaryAddValue(options
, kSecPolicyCheckBlackListedLeaf
, kCFBooleanTrue
);
1208 CFDictionaryAddValue(options
, kSecPolicyCheckGrayListedLeaf
, kCFBooleanTrue
);
1211 static bool SecPolicyAddChainLengthOptions(CFMutableDictionaryRef options
, CFIndex length
)
1213 bool result
= false;
1214 CFNumberRef lengthAsCF
= NULL
;
1216 require(lengthAsCF
= CFNumberCreate(kCFAllocatorDefault
,
1217 kCFNumberCFIndexType
, &length
), errOut
);
1218 CFDictionaryAddValue(options
, kSecPolicyCheckChainLength
, lengthAsCF
);
1223 CFReleaseSafe(lengthAsCF
);
1227 static bool SecPolicyAddAnchorSHA1Options(CFMutableDictionaryRef options
,
1228 const UInt8 anchorSha1
[kSecPolicySHA1Size
])
1230 bool success
= false;
1231 CFDataRef anchorData
= NULL
;
1233 require(anchorData
= CFDataCreate(kCFAllocatorDefault
, anchorSha1
, kSecPolicySHA1Size
), errOut
);
1234 add_element(options
, kSecPolicyCheckAnchorSHA1
, anchorData
);
1239 CFReleaseSafe(anchorData
);
1243 static bool SecPolicyAddAnchorSHA256Options(CFMutableDictionaryRef options
,
1244 const UInt8 anchorSha1
[kSecPolicySHA256Size
])
1246 bool success
= false;
1247 CFDataRef anchorData
= NULL
;
1249 require(anchorData
= CFDataCreate(kCFAllocatorDefault
, anchorSha1
, kSecPolicySHA256Size
), errOut
);
1250 add_element(options
, kSecPolicyCheckAnchorSHA256
, anchorData
);
1255 CFReleaseSafe(anchorData
);
1259 static bool SecPolicyAddStrongKeySizeOptions(CFMutableDictionaryRef options
) {
1260 bool success
= false;
1261 CFDictionaryRef keySizes
= NULL
;
1262 CFNumberRef rsaSize
= NULL
, ecSize
= NULL
;
1264 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
1265 require(rsaSize
= CFNumberCreateWithCFIndex(NULL
, 2048), errOut
);
1266 require(ecSize
= CFNumberCreateWithCFIndex(NULL
, 256), errOut
);
1267 const void *keys
[] = { kSecAttrKeyTypeRSA
, kSecAttrKeyTypeEC
};
1268 const void *values
[] = { rsaSize
, ecSize
};
1269 require(keySizes
= CFDictionaryCreate(NULL
, keys
, values
, 2,
1270 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1271 add_element(options
, kSecPolicyCheckKeySize
, keySizes
);
1276 CFReleaseSafe(keySizes
);
1277 CFReleaseSafe(rsaSize
);
1278 CFReleaseSafe(ecSize
);
1282 static bool SecPolicyRemoveWeakHashOptions(CFMutableDictionaryRef options
) {
1283 CFMutableArrayRef disallowedHashes
= CFArrayCreateMutable(NULL
, 5, &kCFTypeArrayCallBacks
);
1284 if (!disallowedHashes
) {
1287 CFArrayAppendValue(disallowedHashes
, kSecSignatureDigestAlgorithmMD2
);
1288 CFArrayAppendValue(disallowedHashes
, kSecSignatureDigestAlgorithmMD4
);
1289 CFArrayAppendValue(disallowedHashes
, kSecSignatureDigestAlgorithmMD5
);
1290 CFArrayAppendValue(disallowedHashes
, kSecSignatureDigestAlgorithmSHA1
);
1292 add_element(options
, kSecPolicyCheckSignatureHashAlgorithms
, disallowedHashes
);
1293 CFReleaseNull(disallowedHashes
);
1297 static bool isAppleOid(CFStringRef oid
) {
1298 if (!SecCertificateIsOidString(oid
)) {
1301 if (CFStringHasPrefix(oid
, CFSTR("1.2.840.113635"))) {
1307 static bool isCFPreferenceInSecurityDomain(CFStringRef setting
) {
1308 return (CFPreferencesGetAppBooleanValue(setting
, CFSTR("com.apple.security"), NULL
));
1311 static bool SecPolicyAddAppleAnchorOptions(CFMutableDictionaryRef options
, CFStringRef __unused policyName
)
1313 CFMutableDictionaryRef appleAnchorOptions
= NULL
;
1314 appleAnchorOptions
= CFDictionaryCreateMutableForCFTypes(NULL
);
1315 if (!appleAnchorOptions
) {
1319 /* Currently no Apple Anchor options */
1320 add_element(options
, kSecPolicyCheckAnchorApple
, appleAnchorOptions
);
1321 CFReleaseSafe(appleAnchorOptions
);
1325 static bool SecPolicyAddPinningRequiredIfInfoSpecified(CFMutableDictionaryRef options
)
1327 CFBundleRef bundle
= CFBundleGetMainBundle();
1329 CFTypeRef value
= CFBundleGetValueForInfoDictionaryKey(bundle
, CFSTR("SecTrustPinningRequired"));
1330 if (isBoolean(value
) && CFBooleanGetValue(value
)) {
1331 add_element(options
, kSecPolicyCheckPinningRequired
, kCFBooleanTrue
);
1340 // MARK: Policy Creation Functions
1342 SecPolicyRef
SecPolicyCreateBasicX509(void) {
1343 CFMutableDictionaryRef options
= NULL
;
1344 SecPolicyRef result
= NULL
;
1346 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1347 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1349 SecPolicyAddBasicX509Options(options
);
1350 CFDictionaryAddValue(options
, kSecPolicyCheckNoNetworkAccess
,
1353 require(result
= SecPolicyCreate(kSecPolicyAppleX509Basic
, kSecPolicyNameX509Basic
, options
), errOut
);
1356 CFReleaseSafe(options
);
1357 return (SecPolicyRef _Nonnull
)result
;
1360 SecPolicyRef
SecPolicyCreateSSL(Boolean server
, CFStringRef hostname
) {
1361 CFMutableDictionaryRef options
= NULL
;
1362 SecPolicyRef result
= NULL
;
1364 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1365 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1367 SecPolicyAddBasicX509Options(options
);
1370 CFDictionaryAddValue(options
, kSecPolicyCheckSSLHostname
, hostname
);
1373 CFDictionaryAddValue(options
, kSecPolicyCheckBlackListedLeaf
, kCFBooleanTrue
);
1374 CFDictionaryAddValue(options
, kSecPolicyCheckGrayListedLeaf
, kCFBooleanTrue
);
1377 require_quiet(SecPolicyRemoveWeakHashOptions(options
), errOut
);
1378 require_quiet(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
1379 require_quiet(SecPolicyAddPinningRequiredIfInfoSpecified(options
), errOut
);
1380 CFDictionaryAddValue(options
, kSecPolicyCheckValidityPeriodMaximums
, kCFBooleanTrue
);
1381 CFDictionaryAddValue(options
, kSecPolicyCheckServerAuthEKU
, kCFBooleanTrue
); // enforces stricter EKU rules than set_ssl_ekus below for certain anchor types
1382 #if !TARGET_OS_BRIDGE
1383 CFDictionaryAddValue(options
, kSecPolicyCheckSystemTrustedCTRequired
, kCFBooleanTrue
);
1387 set_ssl_ekus(options
, server
);
1389 require(result
= SecPolicyCreate(kSecPolicyAppleSSL
,
1390 server
? kSecPolicyNameSSLServer
: kSecPolicyNameSSLClient
,
1394 CFReleaseSafe(options
);
1395 return (SecPolicyRef _Nonnull
)result
;
1398 SecPolicyRef
SecPolicyCreateLegacySSL(Boolean server
, CFStringRef hostname
) {
1399 CFMutableDictionaryRef options
= NULL
;
1400 SecPolicyRef result
= NULL
;
1402 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1403 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1405 SecPolicyAddBasicX509Options(options
);
1408 CFDictionaryAddValue(options
, kSecPolicyCheckSSLHostname
, hostname
);
1411 CFDictionaryAddValue(options
, kSecPolicyCheckBlackListedLeaf
, kCFBooleanTrue
);
1412 CFDictionaryAddValue(options
, kSecPolicyCheckGrayListedLeaf
, kCFBooleanTrue
);
1415 // fewer requirements than the standard SSL policy
1416 require_quiet(SecPolicyAddPinningRequiredIfInfoSpecified(options
), errOut
);
1417 CFDictionaryAddValue(options
, kSecPolicyCheckValidityPeriodMaximums
, kCFBooleanTrue
);
1418 #if !TARGET_OS_BRIDGE
1419 CFDictionaryAddValue(options
, kSecPolicyCheckSystemTrustedCTRequired
, kCFBooleanTrue
);
1423 set_ssl_ekus(options
, server
);
1425 require(result
= SecPolicyCreate(kSecPolicyAppleLegacySSL
, kSecPolicyNameLegacySSL
, options
), errOut
);
1428 CFReleaseSafe(options
);
1429 return (SecPolicyRef _Nonnull
)result
;
1432 SecPolicyRef
SecPolicyCreateApplePinned(CFStringRef policyName
, CFStringRef intermediateMarkerOID
, CFStringRef leafMarkerOID
) {
1433 CFMutableDictionaryRef options
= NULL
;
1434 SecPolicyRef result
= NULL
;
1436 if (!policyName
|| !intermediateMarkerOID
|| !leafMarkerOID
) {
1440 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1441 &kCFTypeDictionaryKeyCallBacks
,
1442 &kCFTypeDictionaryValueCallBacks
), errOut
);
1444 SecPolicyAddBasicX509Options(options
);
1446 /* Anchored to the Apple Roots */
1447 require(SecPolicyAddAppleAnchorOptions(options
, policyName
), errOut
);
1449 /* Exactly 3 certs in the chain */
1450 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1452 /* Intermediate marker OID matches input OID */
1453 if (!isAppleOid(intermediateMarkerOID
)) {
1454 secwarning("creating an Apple pinning policy with a non-Apple OID: %@", intermediateMarkerOID
);
1456 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, intermediateMarkerOID
);
1458 /* Leaf marker OID matches input OID */
1459 if (!isAppleOid(leafMarkerOID
)) {
1460 secwarning("creating an Apple pinning policy with a non-Apple OID: %@", leafMarkerOID
);
1462 add_leaf_marker_string(options
, leafMarkerOID
);
1464 /* Check revocation using any available method */
1465 add_element(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
1467 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
1468 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
1470 /* Check for weak hashes */
1471 // require(SecPolicyRemoveWeakHashOptions(options), errOut); // the current WWDR CA cert is signed with SHA1
1472 require(result
= SecPolicyCreate(kSecPolicyAppleGenericApplePinned
,
1473 policyName
, options
), errOut
);
1476 CFReleaseSafe(options
);
1481 requireUATPinning(CFStringRef service
)
1483 bool pinningRequired
= true;
1485 if (SecIsInternalRelease()) {
1486 CFStringRef setting
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("AppleServerAuthenticationNoPinning%@"), service
);
1487 require(setting
, fail
);
1488 if(isCFPreferenceInSecurityDomain(setting
)) {
1489 pinningRequired
= false;
1491 secnotice("pinningQA", "could not disable pinning: %@ not true", setting
);
1495 if (!pinningRequired
) {
1499 if(isCFPreferenceInSecurityDomain(CFSTR("AppleServerAuthenticationNoPinning"))) {
1500 pinningRequired
= false;
1502 secnotice("pinningQA", "could not disable pinning: AppleServerAuthenticationNoPinning not true");
1505 secnotice("pinningQA", "could not disable pinning: not an internal release");
1508 return pinningRequired
;
1511 SecPolicyRef
SecPolicyCreateAppleSSLPinned(CFStringRef policyName
, CFStringRef hostname
,
1512 CFStringRef intermediateMarkerOID
, CFStringRef leafMarkerOID
) {
1513 CFMutableDictionaryRef options
= NULL
, appleAnchorOptions
= NULL
;
1514 SecPolicyRef result
= NULL
;
1516 if (!policyName
|| !hostname
|| !leafMarkerOID
) {
1520 if (requireUATPinning(policyName
)) {
1521 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1522 &kCFTypeDictionaryKeyCallBacks
,
1523 &kCFTypeDictionaryValueCallBacks
), errOut
);
1525 SecPolicyAddBasicX509Options(options
);
1527 /* Anchored to the Apple Roots */
1528 require(SecPolicyAddAppleAnchorOptions(options
, policyName
), errOut
);
1530 /* Exactly 3 certs in the chain */
1531 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1533 if (intermediateMarkerOID
) {
1534 /* Intermediate marker OID matches input OID */
1535 if (!isAppleOid(intermediateMarkerOID
)) {
1536 secwarning("creating an Apple pinning policy with a non-Apple OID: %@", intermediateMarkerOID
);
1538 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, intermediateMarkerOID
);
1540 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.12"));
1543 /* Leaf marker OID matches input OID */
1544 if (!isAppleOid(leafMarkerOID
)) {
1545 secwarning("creating an Apple pinning policy with a non-Apple OID: %@", leafMarkerOID
);
1547 add_leaf_marker_string(options
, leafMarkerOID
);
1549 /* New leaf marker OID format */
1550 add_leaf_marker_value_string(options
, CFSTR("1.2.840.113635.100.6.48.1"), leafMarkerOID
);
1552 /* ServerAuth EKU is in leaf cert */
1553 add_eku_string(options
, CFSTR("1.3.6.1.5.5.7.3.1"));
1555 /* Hostname is in leaf cert */
1556 add_element(options
, kSecPolicyCheckSSLHostname
, hostname
);
1558 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
1559 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
1561 /* Check for weak hashes */
1562 require(SecPolicyRemoveWeakHashOptions(options
), errOut
);
1564 /* Check revocation using any available method */
1565 add_element(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
1567 require(result
= SecPolicyCreate(kSecPolicyAppleGenericAppleSSLPinned
,
1568 policyName
, options
), errOut
);
1571 result
= SecPolicyCreateSSL(true, hostname
);
1572 SecPolicySetOid(result
, kSecPolicyAppleGenericAppleSSLPinned
);
1573 SecPolicySetName(result
, policyName
);
1577 CFReleaseSafe(options
);
1578 CFReleaseSafe(appleAnchorOptions
);
1582 SecPolicyRef
SecPolicyCreateiPhoneActivation(void) {
1583 CFMutableDictionaryRef options
= NULL
;
1584 SecPolicyRef result
= NULL
;
1586 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1587 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1589 SecPolicyAddBasicCertOptions(options
);
1592 CFDictionaryAddValue(options
, kSecPolicyCheckKeyUsage
,
1594 CFDictionaryAddValue(options
, kSecPolicyCheckExtendedKeyUsage
,
1598 /* Basic X.509 policy with the additional requirements that the chain
1599 length is 3, it's anchored at the AppleCA and the leaf certificate
1600 has issuer "Apple iPhone Certification Authority" and
1601 subject "Apple iPhone Activation" for the common name. */
1602 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
1603 CFSTR("Apple iPhone Certification Authority"));
1604 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
,
1605 CFSTR("Apple iPhone Activation"));
1607 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1608 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameiPhoneActivation
), errOut
);
1610 require(result
= SecPolicyCreate(kSecPolicyAppleiPhoneActivation
,
1611 kSecPolicyNameiPhoneActivation
, options
),
1615 CFReleaseSafe(options
);
1619 SecPolicyRef
SecPolicyCreateiPhoneDeviceCertificate(void) {
1620 CFMutableDictionaryRef options
= NULL
;
1621 SecPolicyRef result
= NULL
;
1623 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1624 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1626 SecPolicyAddBasicCertOptions(options
);
1629 CFDictionaryAddValue(options
, kSecPolicyCheckKeyUsage
,
1631 CFDictionaryAddValue(options
, kSecPolicyCheckExtendedKeyUsage
,
1635 /* Basic X.509 policy with the additional requirements that the chain
1636 length is 4, it's anchored at the AppleCA and the first intermediate
1637 has the subject "Apple iPhone Device CA". */
1638 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
1639 CFSTR("Apple iPhone Device CA"));
1641 require(SecPolicyAddChainLengthOptions(options
, 4), errOut
);
1642 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameiPhoneDeviceCertificate
), errOut
);
1644 require(result
= SecPolicyCreate(kSecPolicyAppleiPhoneDeviceCertificate
,
1645 kSecPolicyNameiPhoneDeviceCertificate
, options
),
1649 CFReleaseSafe(options
);
1653 SecPolicyRef
SecPolicyCreateFactoryDeviceCertificate(void) {
1654 CFMutableDictionaryRef options
= NULL
;
1655 SecPolicyRef result
= NULL
;
1657 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1658 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1660 SecPolicyAddBasicCertOptions(options
);
1663 CFDictionaryAddValue(options
, kSecPolicyCheckKeyUsage
,
1665 CFDictionaryAddValue(options
, kSecPolicyCheckExtendedKeyUsage
,
1669 /* Basic X.509 policy with the additional requirements that the chain
1670 is anchored at the factory device certificate issuer. */
1671 require(SecPolicyAddAnchorSHA1Options(options
, kFactoryDeviceCASHA1
), errOut
);
1673 require(result
= SecPolicyCreate(kSecPolicyAppleFactoryDeviceCertificate
,
1674 kSecPolicyNameFactoryDeviceCertificate
, options
),
1678 CFReleaseSafe(options
);
1682 SecPolicyRef
SecPolicyCreateiAP(void) {
1683 CFMutableDictionaryRef options
= NULL
;
1684 SecPolicyRef result
= NULL
;
1685 CFTimeZoneRef tz
= NULL
;
1686 CFDateRef date
= NULL
;
1688 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1689 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1691 SecPolicyAddBasicCertOptions(options
);
1693 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonNamePrefix
,
1696 date
= CFDateCreateForGregorianZuluDay(NULL
, 2006, 5, 31);
1697 CFDictionaryAddValue(options
, kSecPolicyCheckNotValidBefore
, date
);
1699 require(result
= SecPolicyCreate(kSecPolicyAppleiAP
,
1700 kSecPolicyNameiAP
, options
),
1704 CFReleaseSafe(date
);
1706 CFReleaseSafe(options
);
1710 SecPolicyRef
SecPolicyCreateiTunesStoreURLBag(void) {
1711 CFMutableDictionaryRef options
= NULL
;
1712 SecPolicyRef result
= NULL
;
1715 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1716 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1718 SecPolicyAddBasicCertOptions(options
);
1720 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectOrganization
,
1721 CFSTR("Apple Inc."));
1722 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
,
1723 CFSTR("iTunes Store URL Bag"));
1725 require(SecPolicyAddChainLengthOptions(options
, 2), errOut
);
1726 require(SecPolicyAddAnchorSHA1Options(options
, kITMSCASHA1
), errOut
);
1728 require(result
= SecPolicyCreate(kSecPolicyAppleiTunesStoreURLBag
,
1729 kSecPolicyNameiTunesStoreURLBag
, options
), errOut
);
1732 CFReleaseSafe(options
);
1736 SecPolicyRef
SecPolicyCreateEAP(Boolean server
, CFArrayRef trustedServerNames
) {
1737 CFMutableDictionaryRef options
= NULL
;
1738 SecPolicyRef result
= NULL
;
1740 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1741 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1743 SecPolicyAddBasicX509Options(options
);
1745 /* Since EAP is used to setup the network we don't want evaluation
1746 using this policy to access the network. */
1747 CFDictionaryAddValue(options
, kSecPolicyCheckNoNetworkAccess
,
1750 if (trustedServerNames
) {
1751 CFDictionaryAddValue(options
, kSecPolicyCheckEAPTrustedServerNames
, trustedServerNames
);
1755 /* Check for weak hashes and keys, but only on system-trusted roots, because enterprise
1756 * PKIs are the absolute worst. */
1757 CFDictionaryAddValue(options
, kSecPolicyCheckSystemTrustedWeakHash
, kCFBooleanTrue
);
1758 CFDictionaryAddValue(options
, kSecPolicyCheckSystemTrustedWeakKey
, kCFBooleanTrue
);
1761 /* We need to check for EKU per rdar://22206018 */
1762 set_ssl_ekus(options
, server
);
1764 require(result
= SecPolicyCreate(kSecPolicyAppleEAP
,
1765 server
? kSecPolicyNameEAPServer
: kSecPolicyNameEAPClient
,
1769 CFReleaseSafe(options
);
1773 SecPolicyRef
SecPolicyCreateIPSec(Boolean server
, CFStringRef hostname
) {
1774 CFMutableDictionaryRef options
= NULL
;
1775 SecPolicyRef result
= NULL
;
1777 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1778 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1780 SecPolicyAddBasicX509Options(options
);
1783 CFDictionaryAddValue(options
, kSecPolicyCheckSSLHostname
, hostname
);
1786 /* Require oidExtendedKeyUsageIPSec if Extended Keyusage Extention is
1788 /* Per <rdar://problem/6843827> Cisco VPN Certificate compatibility issue.
1789 We don't check the EKU for IPSec certs for now. If we do add eku
1790 checking back in the future, we should probably also accept the
1792 ipsecEndSystem 1.3.6.1.5.5.7.3.5
1794 ipsecTunnel 1.3.6.1.5.5.7.3.6
1795 ipsecUser 1.3.6.1.5.5.7.3.7
1797 //add_eku(options, NULL); /* eku extension is optional */
1798 //add_eku(options, &oidAnyExtendedKeyUsage);
1799 //add_eku(options, &oidExtendedKeyUsageIPSec);
1801 require(result
= SecPolicyCreate(kSecPolicyAppleIPsec
,
1802 server
? kSecPolicyNameIPSecServer
: kSecPolicyNameIPSecClient
,
1806 CFReleaseSafe(options
);
1810 SecPolicyRef
SecPolicyCreateiPhoneApplicationSigning(void) {
1811 CFMutableDictionaryRef options
= NULL
;
1812 SecPolicyRef result
= NULL
;
1814 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1815 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1817 SecPolicyAddBasicCertOptions(options
);
1819 /* Anchored to the Apple Roots */
1820 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameiPhoneApplicationSigning
), errOut
);
1823 if (SecIsInternalRelease()) {
1824 /* Allow a prod hierarchy-signed test cert */
1825 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonNameTEST
,
1826 CFSTR("Apple iPhone OS Application Signing"));
1827 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.3.1"));
1830 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
,
1831 CFSTR("Apple iPhone OS Application Signing"));
1833 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.3"));
1835 add_eku(options
, NULL
); /* eku extension is optional */
1836 add_eku(options
, &oidAnyExtendedKeyUsage
);
1837 add_eku(options
, &oidExtendedKeyUsageCodeSigning
);
1839 /* Intermediate check */
1840 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
1841 CFSTR("Apple iPhone Certification Authority"));
1843 /* Chain length check */
1844 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1846 /* Skip networked revocation checks */
1847 CFDictionaryAddValue(options
, kSecPolicyCheckNoNetworkAccess
, kCFBooleanTrue
);
1849 require(result
= SecPolicyCreate(kSecPolicyAppleiPhoneApplicationSigning
,
1850 kSecPolicyNameiPhoneApplicationSigning
, options
),
1854 CFReleaseSafe(options
);
1858 SecPolicyRef
SecPolicyCreateiPhoneVPNApplicationSigning(void) {
1859 CFMutableDictionaryRef options
= NULL
;
1860 SecPolicyRef result
= NULL
;
1862 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1863 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1865 SecPolicyAddBasicCertOptions(options
);
1867 /* Anchored to the Apple Roots */
1868 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameiPhoneVPNApplicationSigning
), errOut
);
1871 if (SecIsInternalRelease()) {
1872 /* Allow a prod hierarchy-signed test cert */
1873 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonNameTEST
,
1874 CFSTR("Apple iPhone OS Application Signing"));
1875 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.6.1"));
1878 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
,
1879 CFSTR("Apple iPhone OS Application Signing"));
1881 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.6"));
1883 add_eku(options
, NULL
); /* eku extension is optional */
1884 add_eku(options
, &oidAnyExtendedKeyUsage
);
1885 add_eku(options
, &oidExtendedKeyUsageCodeSigning
);
1887 /* Intermediate check */
1888 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
1889 CFSTR("Apple iPhone Certification Authority"));
1891 /* Chain length check */
1892 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1894 /* Skip networked revocation checks */
1895 CFDictionaryAddValue(options
, kSecPolicyCheckNoNetworkAccess
, kCFBooleanTrue
);
1897 require(result
= SecPolicyCreate(kSecPolicyAppleiPhoneVPNApplicationSigning
,
1898 kSecPolicyNameiPhoneVPNApplicationSigning
, options
),
1902 CFReleaseSafe(options
);
1906 SecPolicyRef
SecPolicyCreateiPhoneProfileApplicationSigning(void) {
1907 CFMutableDictionaryRef options
= NULL
;
1908 SecPolicyRef result
= NULL
;
1910 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1911 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1913 SecPolicyAddBasicX509Options(options
); // With expiration checking
1916 require_quiet(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameiPhoneProfileApplicationSigning
),
1920 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1922 /* Leaf has CodeSigning EKU */
1923 add_eku_string(options
, CFSTR("1.3.6.1.5.5.7.3.3"));
1925 /* On iOS, the cert in the provisioning profile may be one of:
1926 leaf OID intermediate OID
1927 iPhone Developer <ADS>.6.1.2 <ADS>.6.2.1
1928 iPhone Distribution <ADS>.6.1.4 <ADS>.6.2.1
1929 TestFlight (Prod) <ADS>.6.1.25.1 <ADS>.6.2.1
1930 TestFlight (QA) <ADS>.6.1.25.2 <ADS>.6.2.1
1932 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.1"));
1933 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.2"));
1934 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.4"));
1935 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.25.1"));
1936 if (SecIsInternalRelease()) {
1937 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.25.2"));
1940 /* Revocation via any available method */
1941 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
1943 require(result
= SecPolicyCreate(kSecPolicyAppleiPhoneProfileApplicationSigning
,
1944 kSecPolicyNameiPhoneProfileApplicationSigning
,
1948 CFReleaseSafe(options
);
1952 SecPolicyRef
SecPolicyCreateMacOSProfileApplicationSigning(void) {
1953 CFMutableDictionaryRef options
= NULL
;
1954 SecPolicyRef result
= NULL
;
1956 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1957 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1959 SecPolicyAddBasicCertOptions(options
); // Without expiration checking
1962 require_quiet(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameiPhoneProfileApplicationSigning
),
1966 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1968 /* Leaf has CodeSigning EKU */
1969 add_eku_string(options
, CFSTR("1.3.6.1.5.5.7.3.3"));
1972 /* On macOS, the cert in the provisioning profile may be one of:
1973 leaf OID intermediate OID
1974 MAS Development <ADS>.6.1.12 <ADS>.6.2.1
1975 MAS Submission <ADS>.6.1.7 <ADS>.6.2.1
1976 Developer ID <ADS>.6.1.13 <ADS>.6.2.6
1977 B&I <ADS>.6.22 None - "Apple Code Signing Certification Authority"
1979 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.12"));
1980 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.7"));
1981 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.13"));
1982 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.22"));
1984 /* Revocation via any available method */
1985 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
1987 require(result
= SecPolicyCreate(kSecPolicyAppleMacOSProfileApplicationSigning
,
1988 kSecPolicyNameMacOSProfileApplicationSigning
,
1992 CFReleaseSafe(options
);
1996 SecPolicyRef
SecPolicyCreateiPhoneProvisioningProfileSigning(void) {
1997 CFMutableDictionaryRef options
= NULL
;
1998 SecPolicyRef result
= NULL
;
2000 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2001 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2003 SecPolicyAddBasicCertOptions(options
);
2005 /* Basic X.509 policy with the additional requirements that the chain
2006 length is 3, it's anchored at the AppleCA and the leaf certificate
2007 has issuer "Apple iPhone Certification Authority" and
2008 subject "Apple iPhone OS Provisioning Profile Signing" for the common name. */
2009 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2010 CFSTR("Apple iPhone Certification Authority"));
2011 if (SecIsInternalRelease()) {
2012 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonNameTEST
,
2013 CFSTR("Apple iPhone OS Provisioning Profile Signing"));
2016 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
,
2017 CFSTR("Apple iPhone OS Provisioning Profile Signing"));
2020 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2021 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameiPhoneProvisioningProfileSigning
), errOut
);
2023 /* Skip networked revocation checks */
2024 CFDictionaryAddValue(options
, kSecPolicyCheckNoNetworkAccess
, kCFBooleanTrue
);
2026 require(result
= SecPolicyCreate(kSecPolicyAppleiPhoneProvisioningProfileSigning
,
2027 kSecPolicyNameiPhoneProvisioningProfileSigning
, options
),
2030 /* 1.2.840.113635.100.6.2.2.1, non-critical: DER:05:00 - provisioning profile */
2033 CFReleaseSafe(options
);
2037 SecPolicyRef
SecPolicyCreateAppleTVOSApplicationSigning(void) {
2038 CFMutableDictionaryRef options
= NULL
;
2039 SecPolicyRef result
= NULL
;
2040 CFDataRef atvProdOid
= NULL
;
2041 CFDataRef atvTestOid
= NULL
;
2042 CFArrayRef oids
= NULL
;
2044 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2045 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2047 SecPolicyAddBasicCertOptions(options
);
2049 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2051 require_quiet(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameTVOSApplicationSigning
),
2054 /* Check for intermediate: Apple Worldwide Developer Relations */
2055 /* 1.2.840.113635.100.6.2.1 */
2056 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleWWDR
);
2058 add_ku(options
, kSecKeyUsageDigitalSignature
);
2060 /* Check for prod or test AppleTV Application Signing OIDs */
2061 /* Prod: 1.2.840.113635.100.6.1.24 */
2062 /* ProdQA: 1.2.840.113635.100.6.1.24.1 */
2063 add_leaf_marker(options
, &oidAppleTVOSApplicationSigningProd
);
2064 add_leaf_marker(options
, &oidAppleTVOSApplicationSigningProdQA
);
2066 /* Skip networked revocation checks */
2067 CFDictionaryAddValue(options
, kSecPolicyCheckNoNetworkAccess
, kCFBooleanTrue
);
2069 require(result
= SecPolicyCreate(kSecPolicyAppleTVOSApplicationSigning
,
2070 kSecPolicyNameTVOSApplicationSigning
, options
),
2074 CFReleaseSafe(options
);
2075 CFReleaseSafe(oids
);
2076 CFReleaseSafe(atvProdOid
);
2077 CFReleaseSafe(atvTestOid
);
2081 SecPolicyRef
SecPolicyCreateOCSPSigner(void) {
2082 CFMutableDictionaryRef options
= NULL
;
2083 SecPolicyRef result
= NULL
;
2085 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2086 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2088 SecPolicyAddBasicX509Options(options
);
2090 /* Require id-kp-OCSPSigning extendedKeyUsage to be present, not optional. */
2091 add_eku(options
, &oidExtendedKeyUsageOCSPSigning
);
2093 require(result
= SecPolicyCreate(kSecPolicyAppleOCSPSigner
,
2094 kSecPolicyNameOCSPSigner
, options
), errOut
);
2097 CFReleaseSafe(options
);
2101 SecPolicyRef
SecPolicyCreateRevocation(CFOptionFlags revocationFlags
) {
2102 CFMutableDictionaryRef options
= NULL
;
2103 SecPolicyRef result
= NULL
;
2105 require(revocationFlags
!= 0, errOut
);
2107 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2108 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2110 if (revocationFlags
& kSecRevocationCheckIfTrusted
) {
2111 CFDictionaryAddValue(options
, kSecPolicyCheckRevocationIfTrusted
, kCFBooleanTrue
);
2112 /* Set method, but allow caller to override with later checks */
2113 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
2116 if (revocationFlags
& kSecRevocationOnlineCheck
) {
2117 CFDictionaryAddValue(options
, kSecPolicyCheckRevocationOnline
, kCFBooleanTrue
);
2118 /* Set method, but allow caller to override with later checks */
2119 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
2122 if (revocationFlags
& kSecRevocationOCSPMethod
&& revocationFlags
& kSecRevocationCRLMethod
) {
2123 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
2125 else if (revocationFlags
& kSecRevocationOCSPMethod
) {
2126 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationOCSP
);
2128 else if (revocationFlags
& kSecRevocationCRLMethod
) {
2129 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationCRL
);
2132 if (revocationFlags
& kSecRevocationRequirePositiveResponse
) {
2133 CFDictionaryAddValue(options
, kSecPolicyCheckRevocationResponseRequired
, kCFBooleanTrue
);
2136 if (revocationFlags
& kSecRevocationNetworkAccessDisabled
) {
2137 CFDictionaryAddValue(options
, kSecPolicyCheckNoNetworkAccess
, kCFBooleanTrue
);
2139 /* If the caller didn't explicitly disable network access, the revocation policy
2140 * should override any other policy's network setting.
2141 * In particular, pairing a revocation policy with BasicX509 should result in
2142 * allowing network access for revocation unless explicitly disabled.
2143 * Note that SecTrustSetNetworkFetchAllowed can override even this. */
2144 CFDictionaryAddValue(options
, kSecPolicyCheckNoNetworkAccess
, kCFBooleanFalse
);
2147 /* Only flag bits 0-6 are currently defined */
2148 require(((revocationFlags
>> 7) == 0), errOut
);
2150 require(result
= SecPolicyCreate(kSecPolicyAppleRevocation
,
2151 kSecPolicyNameRevocation
, options
), errOut
);
2154 CFReleaseSafe(options
);
2158 SecPolicyRef
SecPolicyCreateSMIME(CFIndex smimeUsage
, CFStringRef email
) {
2159 CFMutableDictionaryRef options
= NULL
;
2160 SecPolicyRef result
= NULL
;
2162 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2163 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2165 if (smimeUsage
& kSecIgnoreExpirationSMIMEUsage
) {
2166 SecPolicyAddBasicCertOptions(options
);
2168 SecPolicyAddBasicX509Options(options
);
2171 /* We call add_ku for each combination of bits we are willing to allow. */
2172 if (smimeUsage
& kSecSignSMIMEUsage
) {
2173 add_ku(options
, kSecKeyUsageUnspecified
);
2174 add_ku(options
, kSecKeyUsageDigitalSignature
);
2175 add_ku(options
, kSecKeyUsageNonRepudiation
);
2177 if (smimeUsage
& kSecKeyEncryptSMIMEUsage
) {
2178 add_ku(options
, kSecKeyUsageKeyEncipherment
);
2180 if (smimeUsage
& kSecDataEncryptSMIMEUsage
) {
2181 add_ku(options
, kSecKeyUsageDataEncipherment
);
2183 if (smimeUsage
& kSecKeyExchangeDecryptSMIMEUsage
) {
2184 add_ku(options
, kSecKeyUsageKeyAgreement
| kSecKeyUsageDecipherOnly
);
2186 if (smimeUsage
& kSecKeyExchangeEncryptSMIMEUsage
) {
2187 add_ku(options
, kSecKeyUsageKeyAgreement
| kSecKeyUsageEncipherOnly
);
2189 if (smimeUsage
& kSecKeyExchangeBothSMIMEUsage
) {
2190 add_ku(options
, kSecKeyUsageKeyAgreement
| kSecKeyUsageEncipherOnly
| kSecKeyUsageDecipherOnly
);
2194 CFDictionaryAddValue(options
, kSecPolicyCheckEmail
, email
);
2197 /* RFC 3850 paragraph 4.4.4
2199 If the extended key usage extension is present in the certificate
2200 then interpersonal message S/MIME receiving agents MUST check that it
2201 contains either the emailProtection or the anyExtendedKeyUsage OID as
2202 defined in [KEYM]. S/MIME uses other than interpersonal messaging
2203 MAY require the explicit presence of the extended key usage extension
2204 or other OIDs to be present in the extension or both.
2206 add_eku(options
, NULL
); /* eku extension is optional */
2207 add_eku(options
, &oidAnyExtendedKeyUsage
);
2208 add_eku(options
, &oidExtendedKeyUsageEmailProtection
);
2210 #if !TARGET_OS_IPHONE
2211 // Check revocation on OS X
2212 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
2215 require(result
= SecPolicyCreate(kSecPolicyAppleSMIME
, kSecPolicyNameSMIME
, options
), errOut
);
2218 CFReleaseSafe(options
);
2222 SecPolicyRef
SecPolicyCreateApplePackageSigning(void) {
2223 CFMutableDictionaryRef options
= NULL
;
2224 SecPolicyRef result
= NULL
;
2226 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2227 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2229 SecPolicyAddBasicCertOptions(options
);
2231 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2232 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNamePackageSigning
), errOut
);
2234 add_ku(options
, kSecKeyUsageDigitalSignature
);
2235 add_eku(options
, &oidExtendedKeyUsageCodeSigning
);
2237 require(result
= SecPolicyCreate(kSecPolicyApplePackageSigning
,
2238 kSecPolicyNamePackageSigning
, options
),
2242 CFReleaseSafe(options
);
2247 SecPolicyRef
SecPolicyCreateAppleSWUpdateSigning(void) {
2248 CFMutableDictionaryRef options
= NULL
;
2249 SecPolicyRef result
= NULL
;
2251 * OS X rules for this policy:
2252 * -- Must have one intermediate cert
2253 * -- intermediate must have basic constraints with path length 0
2254 * -- intermediate has CSSMOID_APPLE_EKU_CODE_SIGNING EKU
2255 * -- leaf cert has either CODE_SIGNING or CODE_SIGN_DEVELOPMENT EKU (the latter of
2256 * which triggers a CSSMERR_APPLETP_CODE_SIGN_DEVELOPMENT error)
2258 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2259 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2261 SecPolicyAddBasicX509Options(options
);
2263 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2264 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameSWUpdateSigning
), errOut
);
2266 add_eku(options
, &oidAppleExtendedKeyUsageCodeSigning
);
2267 add_oid(options
, kSecPolicyCheckIntermediateEKU
, &oidAppleExtendedKeyUsageCodeSigning
);
2269 require(result
= SecPolicyCreate(kSecPolicyAppleSWUpdateSigning
,
2270 kSecPolicyNameSWUpdateSigning
, options
),
2274 CFReleaseSafe(options
);
2279 SecPolicyRef
SecPolicyCreateCodeSigning(void) {
2280 CFMutableDictionaryRef options
= NULL
;
2281 SecPolicyRef result
= NULL
;
2283 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2284 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2286 SecPolicyAddBasicX509Options(options
);
2288 /* If the key usage extension is present, we accept it having either of
2290 add_ku(options
, kSecKeyUsageDigitalSignature
);
2291 add_ku(options
, kSecKeyUsageNonRepudiation
);
2293 /* We require an extended key usage extension with the codesigning
2294 eku purpose. (The Apple codesigning eku is not accepted here
2295 since it's valid only for SecPolicyCreateAppleSWUpdateSigning.) */
2296 add_eku(options
, &oidExtendedKeyUsageCodeSigning
);
2297 #if TARGET_OS_IPHONE
2298 /* Accept the 'any' eku on iOS only to match prior behavior.
2299 This may be further restricted in future releases. */
2300 add_eku(options
, &oidAnyExtendedKeyUsage
);
2303 require(result
= SecPolicyCreate(kSecPolicyAppleCodeSigning
,
2304 kSecPolicyNameCodeSigning
, options
),
2308 CFReleaseSafe(options
);
2312 /* Explicitly leave out empty subject/subjectaltname check */
2313 SecPolicyRef
SecPolicyCreateLockdownPairing(void) {
2314 CFMutableDictionaryRef options
= NULL
;
2315 SecPolicyRef result
= NULL
;
2317 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2318 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2319 //CFDictionaryAddValue(options, kSecPolicyCheckBasicCertificateProcessing,
2320 // kCFBooleanTrue); // Happens automatically in SecPVCPathChecks
2321 CFDictionaryAddValue(options
, kSecPolicyCheckCriticalExtensions
,
2323 CFDictionaryAddValue(options
, kSecPolicyCheckIdLinkage
,
2325 CFDictionaryAddValue(options
, kSecPolicyCheckBasicConstraints
,
2327 CFDictionaryAddValue(options
, kSecPolicyCheckWeakKeySize
, kCFBooleanTrue
);
2329 require(result
= SecPolicyCreate(kSecPolicyAppleLockdownPairing
,
2330 kSecPolicyNameLockdownPairing
, options
), errOut
);
2333 CFReleaseSafe(options
);
2337 SecPolicyRef
SecPolicyCreateURLBag(void) {
2338 CFMutableDictionaryRef options
= NULL
;
2339 SecPolicyRef result
= NULL
;
2341 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2342 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2344 SecPolicyAddBasicCertOptions(options
);
2346 add_eku(options
, &oidExtendedKeyUsageCodeSigning
);
2348 require(result
= SecPolicyCreate(kSecPolicyAppleURLBag
,
2349 kSecPolicyNameURLBag
, options
), errOut
);
2352 CFReleaseSafe(options
);
2356 SecPolicyRef
SecPolicyCreateOTATasking(void)
2358 CFMutableDictionaryRef options
= NULL
;
2359 SecPolicyRef result
= NULL
;
2361 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2362 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2364 SecPolicyAddBasicX509Options(options
);
2367 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameMobileAsset
), errOut
);
2369 /* Chain length of 3 */
2370 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2372 /* Intermediate has common name "Apple iPhone Certification Authority". */
2373 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2374 CFSTR("Apple iPhone Certification Authority"));
2376 /* Leaf has common name "Asset Manifest Signing" */
2377 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
, CFSTR("OTA Task Signing"));
2379 require(result
= SecPolicyCreate(kSecPolicyAppleOTATasking
, kSecPolicyNameOTATasking
, options
),
2383 CFReleaseSafe(options
);
2387 SecPolicyRef
SecPolicyCreateMobileAsset(void)
2389 CFMutableDictionaryRef options
= NULL
;
2390 SecPolicyRef result
= NULL
;
2392 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2393 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2395 /* No expiration check */
2396 SecPolicyAddBasicCertOptions(options
);
2399 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameMobileAsset
), errOut
);
2401 /* Chain length of 3 */
2402 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2404 /* Intermediate has common name "Apple iPhone Certification Authority". */
2405 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2406 CFSTR("Apple iPhone Certification Authority"));
2408 /* Leaf has common name "Asset Manifest Signing" */
2409 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
, CFSTR("Asset Manifest Signing"));
2411 require(result
= SecPolicyCreate(kSecPolicyAppleMobileAsset
, kSecPolicyNameMobileAsset
, options
),
2415 CFReleaseSafe(options
);
2419 SecPolicyRef
SecPolicyCreateMobileAssetDevelopment(void) {
2420 CFMutableDictionaryRef options
= NULL
;
2421 SecPolicyRef result
= NULL
;
2423 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2424 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2426 /* No expiration check */
2427 SecPolicyAddBasicCertOptions(options
);
2430 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameMobileAsset
), errOut
);
2432 /* Chain length of 3 */
2433 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2435 /* Intermediate has the iPhone CA Marker extension */
2436 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.18"));
2438 /* Leaf has ProdQA Mobile Asset Marker extension */
2439 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.55.1"));
2441 require(result
= SecPolicyCreate(kSecPolicyAppleMobileAssetDevelopment
, kSecPolicyNameMobileAsset
, options
),
2445 CFReleaseSafe(options
);
2449 SecPolicyRef
SecPolicyCreateAppleIDAuthorityPolicy(void)
2451 SecPolicyRef result
= NULL
;
2452 CFMutableDictionaryRef options
= NULL
;
2453 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2454 &kCFTypeDictionaryKeyCallBacks
,
2455 &kCFTypeDictionaryValueCallBacks
), out
);
2457 //Leaf appears to be a SSL only cert, so policy should expand on that policy
2458 SecPolicyAddBasicX509Options(options
);
2460 // Apple CA anchored
2461 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameIDAuthority
), out
);
2463 // with the addition of the existence check of an extension with "Apple ID Sharing Certificate" oid (1.2.840.113635.100.4.7)
2464 // NOTE: this obviously intended to have gone into Extended Key Usage, but evidence of existing certs proves the contrary.
2465 add_leaf_marker(options
, &oidAppleExtendedKeyUsageAppleID
);
2467 // 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.
2468 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleID
);
2469 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleID2
);
2471 require(result
= SecPolicyCreate(kSecPolicyAppleIDAuthority
,
2472 kSecPolicyNameIDAuthority
, options
), out
);
2475 CFReleaseSafe(options
);
2479 SecPolicyRef
SecPolicyCreateMacAppStoreReceipt(void)
2481 SecPolicyRef result
= NULL
;
2482 CFMutableDictionaryRef options
= NULL
;
2483 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2484 &kCFTypeDictionaryKeyCallBacks
,
2485 &kCFTypeDictionaryValueCallBacks
), out
);
2487 SecPolicyAddBasicX509Options(options
);
2489 // Apple CA anchored
2490 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameMacAppStoreReceipt
), out
);
2492 // Chain length of 3
2493 require(SecPolicyAddChainLengthOptions(options
, 3), out
);
2495 // MacAppStoreReceipt policy OID
2496 add_certificate_policy_oid_string(options
, CFSTR("1.2.840.113635.100.5.6.1"));
2498 // Intermediate marker OID
2499 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.1"));
2502 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.11.1"));
2505 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
2507 require(result
= SecPolicyCreate(kSecPolicyMacAppStoreReceipt
,
2508 kSecPolicyNameMacAppStoreReceipt
, options
), out
);
2511 CFReleaseSafe(options
);
2516 static SecPolicyRef
_SecPolicyCreatePassbookCardSigner(CFStringRef cardIssuer
, CFStringRef teamIdentifier
, bool requireTeamID
)
2518 SecPolicyRef result
= NULL
;
2519 CFMutableDictionaryRef options
= NULL
;
2520 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2521 &kCFTypeDictionaryKeyCallBacks
,
2522 &kCFTypeDictionaryValueCallBacks
), out
);
2524 SecPolicyAddBasicX509Options(options
);
2525 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNamePassbookSigning
), out
);
2527 // Chain length of 3
2528 require(SecPolicyAddChainLengthOptions(options
, 3), out
);
2530 if (teamIdentifier
) {
2531 // If supplied, teamIdentifier must match subject OU field
2532 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectOrganizationalUnit
, teamIdentifier
);
2535 // If not supplied, and it was required, fail
2536 require(!requireTeamID
, out
);
2539 // Must be both push and 3rd party package signing
2540 add_leaf_marker_value(options
, &oidAppleInstallerPackagingSigningExternal
, cardIssuer
);
2542 // We should check that it also has push marker, but we don't support requiring both, only either.
2543 // add_independent_oid(options, kSecPolicyCheckLeafMarkerOid, &oidApplePushServiceClient);
2545 //WWDR Intermediate marker OID
2546 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.1"));
2548 // And Passbook signing eku
2549 add_eku(options
, &oidAppleExtendedKeyUsagePassbook
);
2551 require(result
= SecPolicyCreate(kSecPolicyApplePassbookSigning
,
2552 kSecPolicyNamePassbookSigning
, options
), out
);
2555 CFReleaseSafe(options
);
2559 SecPolicyRef
SecPolicyCreatePassbookCardSigner(CFStringRef cardIssuer
, CFStringRef teamIdentifier
)
2561 return _SecPolicyCreatePassbookCardSigner(cardIssuer
, teamIdentifier
, true);
2565 static SecPolicyRef
CreateMobileStoreSigner(Boolean forTest
)
2568 SecPolicyRef result
= NULL
;
2569 CFMutableDictionaryRef options
= NULL
;
2570 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2571 &kCFTypeDictionaryKeyCallBacks
,
2572 &kCFTypeDictionaryValueCallBacks
), errOut
);
2573 SecPolicyAddBasicX509Options(options
);
2574 require(SecPolicyAddAppleAnchorOptions(options
,
2575 ((forTest
) ? kSecPolicyNameTestMobileStore
:
2576 kSecPolicyNameMobileStore
)), errOut
);
2578 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2580 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2581 CFSTR("Apple System Integration 2 Certification Authority"));
2583 add_ku(options
, kSecKeyUsageDigitalSignature
);
2585 const DERItem
* pOID
= (forTest
) ? &oidApplePolicyMobileStoreProdQA
: &oidApplePolicyMobileStore
;
2587 add_certificate_policy_oid(options
, pOID
);
2589 require(result
= SecPolicyCreate((forTest
) ? kSecPolicyAppleTestMobileStore
: kSecPolicyAppleMobileStore
,
2590 (forTest
) ? kSecPolicyNameTestMobileStore
: kSecPolicyNameMobileStore
,
2594 CFReleaseSafe(options
);
2598 SecPolicyRef
SecPolicyCreateMobileStoreSigner(void)
2600 return CreateMobileStoreSigner(false);
2603 SecPolicyRef
SecPolicyCreateTestMobileStoreSigner(void)
2605 return CreateMobileStoreSigner(true);
2609 CF_RETURNS_RETAINED SecPolicyRef
SecPolicyCreateEscrowServiceSigner(void)
2611 SecPolicyRef result
= NULL
;
2612 CFMutableDictionaryRef options
= NULL
;
2613 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2614 &kCFTypeDictionaryKeyCallBacks
,
2615 &kCFTypeDictionaryValueCallBacks
), errOut
);
2617 // X509, ignoring date validity
2618 SecPolicyAddBasicCertOptions(options
);
2620 add_ku(options
, kSecKeyUsageKeyEncipherment
);
2622 /* Leaf has marker OID with value that can't be pre-determined */
2623 add_element(options
, kSecPolicyCheckLeafMarkerOidWithoutValueCheck
, CFSTR("1.2.840.113635.100.6.23.1"));
2624 require(SecPolicyAddChainLengthOptions(options
, 2), errOut
);
2626 require(result
= SecPolicyCreate(kSecPolicyAppleEscrowService
,
2627 kSecPolicyNameEscrowService
, options
), errOut
);
2630 CFReleaseSafe(options
);
2634 CF_RETURNS_RETAINED SecPolicyRef
SecPolicyCreatePCSEscrowServiceSigner(void)
2636 SecPolicyRef result
= NULL
;
2637 CFMutableDictionaryRef options
= NULL
;
2638 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2639 &kCFTypeDictionaryKeyCallBacks
,
2640 &kCFTypeDictionaryValueCallBacks
), errOut
);
2642 SecPolicyAddBasicX509Options(options
);
2643 add_ku(options
, kSecKeyUsageKeyEncipherment
);
2645 /* Leaf has marker OID with value that can't be pre-determined */
2646 add_element(options
, kSecPolicyCheckLeafMarkerOidWithoutValueCheck
, CFSTR("1.2.840.113635.100.6.23.1"));
2647 require(SecPolicyAddChainLengthOptions(options
, 2), errOut
);
2649 require(result
= SecPolicyCreate(kSecPolicyApplePCSEscrowService
,
2650 kSecPolicyNamePCSEscrowService
, options
), errOut
);
2653 CFReleaseSafe(options
);
2657 static SecPolicyRef
CreateConfigurationProfileSigner(bool forTest
) {
2658 SecPolicyRef result
= NULL
;
2659 CFMutableDictionaryRef options
= NULL
;
2660 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2661 &kCFTypeDictionaryKeyCallBacks
,
2662 &kCFTypeDictionaryValueCallBacks
), errOut
);
2664 SecPolicyAddBasicX509Options(options
);
2665 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameProfileSigner
), errOut
);
2668 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2670 // Require the profile signing EKU
2671 const DERItem
* pOID
= (forTest
) ? &oidAppleExtendedKeyUsageQAProfileSigning
:&oidAppleExtendedKeyUsageProfileSigning
;
2672 add_eku(options
, pOID
);
2674 // Require the Apple Application Integration CA marker OID
2675 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.3"));
2677 require(result
= SecPolicyCreate((forTest
) ? kSecPolicyAppleQAProfileSigner
: kSecPolicyAppleProfileSigner
,
2678 (forTest
) ? kSecPolicyNameQAProfileSigner
: kSecPolicyNameProfileSigner
,
2682 CFReleaseSafe(options
);
2686 SecPolicyRef
SecPolicyCreateConfigurationProfileSigner(void)
2688 return CreateConfigurationProfileSigner(false);
2692 SecPolicyRef
SecPolicyCreateQAConfigurationProfileSigner(void)
2694 if (SecIsInternalRelease()) {
2695 return CreateConfigurationProfileSigner(true);
2697 return CreateConfigurationProfileSigner(false);
2701 SecPolicyRef
SecPolicyCreateOSXProvisioningProfileSigning(void)
2703 SecPolicyRef result
= NULL
;
2704 CFMutableDictionaryRef options
= NULL
;
2705 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2706 &kCFTypeDictionaryKeyCallBacks
,
2707 &kCFTypeDictionaryValueCallBacks
), errOut
);
2708 // Require valid chain from the Apple root
2709 SecPolicyAddBasicX509Options(options
);
2710 SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameOSXProvisioningProfileSigning
);
2712 // Require provisioning profile leaf marker OID (1.2.840.113635.100.4.11)
2713 add_leaf_marker(options
, &oidAppleCertExtOSXProvisioningProfileSigning
);
2715 // Require intermediate marker OID (1.2.840.113635.100.6.2.1)
2716 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleWWDR
);
2718 // Require key usage that allows signing
2719 add_ku(options
, kSecKeyUsageDigitalSignature
);
2721 // Ensure that revocation is checked (OCSP)
2722 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationOCSP
);
2724 require(result
= SecPolicyCreate(kSecPolicyAppleOSXProvisioningProfileSigning
,
2725 kSecPolicyNameOSXProvisioningProfileSigning
, options
), errOut
);
2728 CFReleaseSafe(options
);
2733 SecPolicyRef
SecPolicyCreateOTAPKISigner(void)
2735 SecPolicyRef result
= NULL
;
2736 CFMutableDictionaryRef options
= NULL
;
2737 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2738 &kCFTypeDictionaryKeyCallBacks
,
2739 &kCFTypeDictionaryValueCallBacks
), errOut
);
2740 SecPolicyAddBasicX509Options(options
);
2742 SecPolicyAddAnchorSHA1Options(options
, kApplePKISettingsAuthority
);
2743 require(SecPolicyAddChainLengthOptions(options
, 2), errOut
);
2745 require(result
= SecPolicyCreate(kSecPolicyAppleOTAPKISigner
,
2746 kSecPolicyNameOTAPKISigner
, options
), errOut
);
2749 CFReleaseSafe(options
);
2755 SecPolicyRef
SecPolicyCreateTestOTAPKISigner(void)
2757 /* Guard against use on production devices */
2758 if (!SecIsInternalRelease()) {
2759 return SecPolicyCreateOTAPKISigner();
2762 SecPolicyRef result
= NULL
;
2763 CFMutableDictionaryRef options
= NULL
;
2764 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2765 &kCFTypeDictionaryKeyCallBacks
,
2766 &kCFTypeDictionaryValueCallBacks
), errOut
);
2767 SecPolicyAddBasicX509Options(options
);
2769 SecPolicyAddAnchorSHA1Options(options
, kAppleTestPKISettingsAuthority
);
2770 require(SecPolicyAddChainLengthOptions(options
, 2), errOut
);
2772 require(result
= SecPolicyCreate(kSecPolicyAppleTestOTAPKISigner
,
2773 kSecPolicyNameTestOTAPKISigner
, options
), errOut
);
2776 CFReleaseSafe(options
);
2781 @function SecPolicyCreateAppleSMPEncryption
2782 @abstract Check for intermediate certificate 'Apple System Integration CA - G3' by name,
2783 and root certificate 'Apple Root CA - G3' by hash.
2784 Leaf cert must have Key Encipherment usage.
2785 Leaf cert must have Apple SMP Encryption marker OID (1.2.840.113635.100.6.30).
2786 Intermediate must have marker OID (1.2.840.113635.100.6.2.13).
2788 SecPolicyRef
SecPolicyCreateAppleSMPEncryption(void)
2790 SecPolicyRef result
= NULL
;
2791 CFMutableDictionaryRef options
= NULL
;
2792 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2793 &kCFTypeDictionaryKeyCallBacks
,
2794 &kCFTypeDictionaryValueCallBacks
), errOut
);
2795 SecPolicyAddBasicCertOptions(options
);
2797 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameSMPEncryption
),
2799 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2801 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2802 CFSTR("Apple System Integration CA - G3"));
2804 // Check that leaf has extension with "Apple SMP Encryption" oid (1.2.840.113635.100.6.30)
2805 add_leaf_marker(options
, &oidAppleCertExtAppleSMPEncryption
);
2807 // Check that intermediate has extension (1.2.840.113635.100.6.2.13)
2808 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleSystemIntgG3
);
2810 add_ku(options
, kSecKeyUsageKeyEncipherment
);
2812 // Ensure that revocation is checked (OCSP)
2813 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationOCSP
);
2815 require(result
= SecPolicyCreate(kSecPolicyAppleSMPEncryption
,
2816 kSecPolicyNameSMPEncryption
, options
), errOut
);
2819 CFReleaseSafe(options
);
2824 @function SecPolicyCreateTestAppleSMPEncryption
2825 @abstract Check for intermediate certificate 'Test Apple System Integration CA - ECC' by name,
2826 and root certificate 'Test Apple Root CA - ECC' by hash.
2827 Leaf cert must have Key Encipherment usage. Other checks TBD.
2829 SecPolicyRef
SecPolicyCreateTestAppleSMPEncryption(void)
2831 SecPolicyRef result
= NULL
;
2832 CFMutableDictionaryRef options
= NULL
;
2833 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2834 &kCFTypeDictionaryKeyCallBacks
,
2835 &kCFTypeDictionaryValueCallBacks
), errOut
);
2836 SecPolicyAddBasicCertOptions(options
);
2838 SecPolicyAddAnchorSHA1Options(options
, kTestAppleRootCA_ECC_SHA1
);
2839 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2841 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2842 CFSTR("Test Apple System Integration CA - ECC"));
2844 add_ku(options
, kSecKeyUsageKeyEncipherment
);
2846 // Ensure that revocation is checked (OCSP)
2847 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationOCSP
);
2849 require(result
= SecPolicyCreate(kSecPolicyAppleTestSMPEncryption
,
2850 kSecPolicyNameTestSMPEncryption
, options
), errOut
);
2853 CFReleaseSafe(options
);
2858 SecPolicyRef
SecPolicyCreateAppleIDValidationRecordSigningPolicy(void)
2860 SecPolicyRef result
= NULL
;
2861 CFMutableDictionaryRef options
= NULL
;
2862 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2863 &kCFTypeDictionaryKeyCallBacks
,
2864 &kCFTypeDictionaryValueCallBacks
), errOut
);
2866 //Leaf appears to be a SSL only cert, so policy should expand on that policy
2867 SecPolicyAddBasicX509Options(options
);
2869 // Apple CA anchored
2870 require(SecPolicyAddAppleAnchorOptions(options
,
2871 kSecPolicyNameIDValidationRecordSigning
),
2874 // Check for an extension with " Apple ID Validation Record Signing" oid (1.2.840.113635.100.6.25)
2875 add_leaf_marker(options
, &oidAppleCertExtensionAppleIDRecordValidationSigning
);
2877 // and validate that intermediate has extension
2878 // Application Integration Intermediate Certificate (1.2.840.113635.100.6.2.3)
2879 // and also validate that intermediate has extension
2880 // System Integration 2 Intermediate Certificate (1.2.840.113635.100.6.2.10)
2881 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleID
);
2882 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleSystemIntg2
);
2884 // Ensure that revocation is checked (OCSP)
2885 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationOCSP
);
2887 require(result
= SecPolicyCreate(kSecPolicyAppleIDValidationRecordSigning
,
2888 kSecPolicyNameIDValidationRecordSigning
, options
), errOut
);
2891 CFReleaseSafe(options
);
2896 @function SecPolicyCreateAppleServerAuthCommon
2897 @abstract Generic policy for server authentication Sub CAs
2899 Allows control for both if pinning is required at all and if UAT environments should be added
2900 to the trust policy.
2902 No pinning is for developer/QA that needs to use proxy to debug the protocol, while UAT
2903 environment is for QA/internal developer that have no need allow fake servers.
2905 Both the noPinning and UAT are gated on that you run on internal hardware.
2910 SecPolicyCreateAppleServerAuthCommon(CFStringRef hostname
,
2911 CFDictionaryRef __unused context
,
2912 CFStringRef policyOID
, CFStringRef service
,
2913 const DERItem
*leafMarkerOID
,
2914 const DERItem
*UATLeafMarkerOID
)
2916 CFMutableDictionaryRef appleAnchorOptions
= NULL
;
2917 CFMutableDictionaryRef options
= NULL
;
2918 SecPolicyRef result
= NULL
;
2919 CFDataRef oid
= NULL
, uatoid
= NULL
;
2921 options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0, &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
2922 require(options
, errOut
);
2924 SecPolicyAddBasicX509Options(options
);
2926 require(hostname
, errOut
);
2927 CFDictionaryAddValue(options
, kSecPolicyCheckSSLHostname
, hostname
);
2929 CFDictionaryAddValue(options
, kSecPolicyCheckBlackListedLeaf
, kCFBooleanTrue
);
2930 CFDictionaryAddValue(options
, kSecPolicyCheckGrayListedLeaf
, kCFBooleanTrue
);
2932 add_eku(options
, &oidExtendedKeyUsageServerAuth
);
2934 if (requireUATPinning(service
)) {
2937 * Require pinning to the Apple CA's.
2939 SecPolicyAddAppleAnchorOptions(options
, service
);
2941 /* old-style leaf marker OIDs */
2942 if (UATLeafMarkerOID
) {
2943 add_leaf_prod_qa_markers(options
, leafMarkerOID
, UATLeafMarkerOID
);
2945 add_leaf_marker(options
, leafMarkerOID
);
2948 /* new-style leaf marker OIDs */
2949 CFStringRef leafMarkerOIDStr
= NULL
, UATLeafMarkerOIDStr
= NULL
;
2950 leafMarkerOIDStr
= SecDERItemCopyOIDDecimalRepresentation(NULL
, leafMarkerOID
);
2951 if (UATLeafMarkerOID
) {
2952 UATLeafMarkerOIDStr
= SecDERItemCopyOIDDecimalRepresentation(NULL
, UATLeafMarkerOID
);
2955 if (leafMarkerOIDStr
&& UATLeafMarkerOIDStr
) {
2956 add_leaf_prod_qa_markers_value_string(options
,
2957 CFSTR("1.2.840.113635.100.6.48.1"), leafMarkerOIDStr
,
2958 CFSTR("1.2.840.113635.100.6.48.1"), UATLeafMarkerOIDStr
);
2959 } else if (leafMarkerOIDStr
) {
2960 add_leaf_marker_value_string(options
, CFSTR("1.2.840.113635.100.6.48.1"), leafMarkerOIDStr
);
2963 CFReleaseNull(leafMarkerOIDStr
);
2964 CFReleaseNull(UATLeafMarkerOIDStr
);
2966 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleServerAuthentication
);
2969 /* Check for weak hashes and keys */
2970 require(SecPolicyRemoveWeakHashOptions(options
), errOut
);
2971 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
2973 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
2975 result
= SecPolicyCreate(policyOID
, service
, options
);
2976 require(result
, errOut
);
2979 CFReleaseSafe(appleAnchorOptions
);
2980 CFReleaseSafe(options
);
2982 CFReleaseSafe(uatoid
);
2987 @function SecPolicyCreateAppleIDSService
2988 @abstract Ensure we're appropriately pinned to the IDS service (SSL + Apple restrictions)
2990 SecPolicyRef
SecPolicyCreateAppleIDSService(CFStringRef hostname
)
2992 SecPolicyRef result
= SecPolicyCreateSSL(true, hostname
);
2994 SecPolicySetOid(result
, kSecPolicyAppleIDSService
);
2995 SecPolicySetName(result
, kSecPolicyNameAppleIDSBag
);
3001 @function SecPolicyCreateAppleIDSService
3002 @abstract Ensure we're appropriately pinned to the IDS service (SSL + Apple restrictions)
3004 SecPolicyRef
SecPolicyCreateAppleIDSServiceContext(CFStringRef hostname
, CFDictionaryRef context
)
3006 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyAppleIDSServiceContext
,
3007 kSecPolicyNameAppleIDSService
,
3008 &oidAppleCertExtAppleServerAuthenticationIDSProd
,
3009 &oidAppleCertExtAppleServerAuthenticationIDSProdQA
);
3013 @function SecPolicyCreateAppleGSService
3014 @abstract Ensure we're appropriately pinned to the GS service
3016 SecPolicyRef
SecPolicyCreateAppleGSService(CFStringRef hostname
, CFDictionaryRef context
)
3018 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyAppleGSService
,
3019 kSecPolicyNameAppleGSService
,
3020 &oidAppleCertExtAppleServerAuthenticationGS
,
3025 @function SecPolicyCreateApplePushService
3026 @abstract Ensure we're appropriately pinned to the Push service (SSL + Apple restrictions)
3028 SecPolicyRef
SecPolicyCreateApplePushService(CFStringRef hostname
, CFDictionaryRef context
)
3030 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyApplePushService
,
3031 kSecPolicyNameApplePushService
,
3032 &oidAppleCertExtAppleServerAuthenticationAPNProd
,
3033 &oidAppleCertExtAppleServerAuthenticationAPNProdQA
);
3037 @function SecPolicyCreateApplePPQService
3038 @abstract Ensure we're appropriately pinned to the PPQ service (SSL + Apple restrictions)
3040 SecPolicyRef
SecPolicyCreateApplePPQService(CFStringRef hostname
, CFDictionaryRef context
)
3042 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyApplePPQService
,
3043 kSecPolicyNameApplePPQService
,
3044 &oidAppleCertExtAppleServerAuthenticationPPQProd
,
3045 &oidAppleCertExtAppleServerAuthenticationPPQProdQA
);
3049 @function SecPolicyCreateAppleAST2Service
3050 @abstract Ensure we're appropriately pinned to the AST2 Diagnostic service (SSL + Apple restrictions)
3052 SecPolicyRef
SecPolicyCreateAppleAST2Service(CFStringRef hostname
, CFDictionaryRef context
)
3054 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyAppleAST2DiagnosticsServerAuth
,
3055 kSecPolicyNameAppleAST2Service
,
3056 &oidAppleCertExtAST2DiagnosticsServerAuthProd
,
3057 &oidAppleCertExtAST2DiagnosticsServerAuthProdQA
);
3061 @function SecPolicyCreateAppleEscrowProxyService
3062 @abstract Ensure we're appropriately pinned to the iCloud Escrow Proxy service (SSL + Apple restrictions)
3064 SecPolicyRef
SecPolicyCreateAppleEscrowProxyService(CFStringRef hostname
, CFDictionaryRef context
)
3066 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyAppleEscrowProxyServerAuth
,
3067 kSecPolicyNameAppleEscrowProxyService
,
3068 &oidAppleCertExtEscrowProxyServerAuthProd
,
3069 &oidAppleCertExtEscrowProxyServerAuthProdQA
);
3072 /* subject:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA */
3073 /* SKID: C0:7A:98:68:8D:89:FB:AB:05:64:0C:11:7D:AA:7D:65:B8:CA:CC:4E */
3074 /* Not Before: May 21 04:00:00 2002 GMT, Not After : May 21 04:00:00 2022 GMT */
3075 /* Signature Algorithm: sha1WithRSAEncryption */
3076 unsigned char GeoTrust_Global_CA_sha256
[kSecPolicySHA256Size
] = {
3077 0xff, 0x85, 0x6a, 0x2d, 0x25, 0x1d, 0xcd, 0x88, 0xd3, 0x66, 0x56, 0xf4, 0x50, 0x12, 0x67, 0x98,
3078 0xcf, 0xab, 0xaa, 0xde, 0x40, 0x79, 0x9c, 0x72, 0x2d, 0xe4, 0xd2, 0xb5, 0xdb, 0x36, 0xa7, 0x3a
3081 static SecPolicyRef
SecPolicyCreateAppleGeoTrustServerAuthCommon(CFStringRef hostname
, CFStringRef policyOid
,
3082 CFStringRef policyName
,
3083 CFStringRef leafMarkerOid
,
3084 CFStringRef qaLeafMarkerOid
) {
3085 CFMutableDictionaryRef options
= NULL
;
3086 CFDataRef spkiDigest
= NULL
;
3087 SecPolicyRef result
= NULL
;
3089 require(options
= CFDictionaryCreateMutable(NULL
, 0, &kCFTypeDictionaryKeyCallBacks
,
3090 &kCFTypeDictionaryValueCallBacks
), errOut
);
3093 SecPolicyAddBasicX509Options(options
);
3095 require(hostname
, errOut
);
3096 CFDictionaryAddValue(options
, kSecPolicyCheckSSLHostname
, hostname
);
3098 add_eku(options
, &oidExtendedKeyUsageServerAuth
);
3101 if (requireUATPinning(policyName
)) {
3103 SecPolicyAddAnchorSHA256Options(options
, GeoTrust_Global_CA_sha256
);
3105 /* Issued to Apple Inc. in the US */
3106 add_element(options
, kSecPolicyCheckIntermediateCountry
, CFSTR("US"));
3107 add_element(options
, kSecPolicyCheckIntermediateOrganization
, CFSTR("Apple Inc."));
3109 require_action(SecPolicyAddChainLengthOptions(options
, 3), errOut
, CFReleaseNull(result
));
3111 /* Marker OIDs in both formats */
3112 if (qaLeafMarkerOid
) {
3113 add_leaf_prod_qa_markers_string(options
, leafMarkerOid
, qaLeafMarkerOid
);
3114 add_leaf_prod_qa_markers_value_string(options
,
3115 CFSTR("1.2.840.113635.100.6.48.1"), leafMarkerOid
,
3116 CFSTR("1.2.840.113635.100.6.48.1"), qaLeafMarkerOid
);
3118 add_leaf_marker_string(options
, leafMarkerOid
);
3119 add_leaf_marker_value_string(options
, CFSTR("1.2.840.113635.100.6.48.1"), leafMarkerOid
);
3123 /* Check for weak hashes */
3124 require(SecPolicyRemoveWeakHashOptions(options
), errOut
);
3125 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
3127 /* See <rdar://25344801> for more details */
3129 result
= SecPolicyCreate(policyOid
, policyName
, options
);
3132 CFReleaseSafe(options
);
3133 CFReleaseSafe(spkiDigest
);
3137 SecPolicyRef
SecPolicyCreateAppleCompatibilityEscrowProxyService(CFStringRef hostname
) {
3138 return SecPolicyCreateAppleGeoTrustServerAuthCommon(hostname
, kSecPolicyAppleEscrowProxyCompatibilityServerAuth
,
3139 kSecPolicyNameAppleEscrowProxyService
,
3140 CFSTR("1.2.840.113635.100.6.27.7.2"),
3141 CFSTR("1.2.840.113635.100.6.27.7.1"));
3145 @function SecPolicyCreateAppleFMiPService
3146 @abstract Ensure we're appropriately pinned to the Find My iPhone service (SSL + Apple restrictions)
3148 SecPolicyRef
SecPolicyCreateAppleFMiPService(CFStringRef hostname
, CFDictionaryRef context
)
3150 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyAppleFMiPServerAuth
,
3151 kSecPolicyNameAppleFMiPService
,
3152 &oidAppleCertExtFMiPServerAuthProd
,
3153 &oidAppleCertExtFMiPServerAuthProdQA
);
3157 /* should use verbatim copy, but since this is the deprecated way, don't care right now */
3158 static const UInt8 entrustSPKIL1C
[kSecPolicySHA256Size
] = {
3159 0x54, 0x5b, 0xf9, 0x35, 0xe9, 0xad, 0xa1, 0xda,
3160 0x11, 0x7e, 0xdc, 0x3c, 0x2a, 0xcb, 0xc5, 0x6f,
3161 0xc0, 0x28, 0x09, 0x6c, 0x0e, 0x24, 0xbe, 0x9b,
3162 0x38, 0x94, 0xbe, 0x52, 0x2d, 0x1b, 0x43, 0xde
3166 @function SecPolicyCreateApplePushServiceLegacy
3167 @abstract Ensure we're appropriately pinned to the Push service (via Entrust)
3169 SecPolicyRef
SecPolicyCreateApplePushServiceLegacy(CFStringRef hostname
)
3171 CFMutableDictionaryRef options
= NULL
;
3172 SecPolicyRef result
= NULL
;
3173 CFDataRef digest
= NULL
;
3175 digest
= CFDataCreateWithBytesNoCopy(kCFAllocatorDefault
, entrustSPKIL1C
, sizeof(entrustSPKIL1C
), kCFAllocatorNull
);
3176 require(digest
, errOut
);
3178 options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0, &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
3179 require(options
, errOut
);
3181 SecPolicyAddBasicX509Options(options
);
3183 CFDictionaryAddValue(options
, kSecPolicyCheckSSLHostname
, hostname
);
3185 CFDictionaryAddValue(options
, kSecPolicyCheckBlackListedLeaf
, kCFBooleanTrue
);
3186 CFDictionaryAddValue(options
, kSecPolicyCheckGrayListedLeaf
, kCFBooleanTrue
);
3188 CFDictionaryAddValue(options
, kSecPolicyCheckIntermediateSPKISHA256
, digest
);
3190 add_eku(options
, &oidExtendedKeyUsageServerAuth
);
3192 /* Check for weak hashes and keys */
3193 require(SecPolicyRemoveWeakHashOptions(options
), errOut
);
3194 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
3196 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
3198 result
= SecPolicyCreate(kSecPolicyAppleLegacyPushService
,
3199 kSecPolicyNameLegacyPushService
, options
);
3200 require(result
, errOut
);
3203 CFReleaseSafe(digest
);
3204 CFReleaseSafe(options
);
3209 @function SecPolicyCreateAppleMMCSService
3210 @abstract Ensure we're appropriately pinned to the IDS service (SSL + Apple restrictions)
3212 SecPolicyRef
SecPolicyCreateAppleMMCSService(CFStringRef hostname
, CFDictionaryRef context
)
3214 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyAppleMMCService
,
3215 kSecPolicyNameAppleMMCSService
,
3216 &oidAppleCertExtAppleServerAuthenticationMMCSProd
,
3217 &oidAppleCertExtAppleServerAuthenticationMMCSProdQA
);
3220 SecPolicyRef
SecPolicyCreateAppleCompatibilityMMCSService(CFStringRef hostname
) {
3221 return SecPolicyCreateAppleGeoTrustServerAuthCommon(hostname
, kSecPolicyAppleMMCSCompatibilityServerAuth
,
3222 kSecPolicyNameAppleMMCSService
,
3223 CFSTR("1.2.840.113635.100.6.27.11.2"),
3224 CFSTR("1.2.840.113635.100.6.27.11.1"));
3228 SecPolicyRef
SecPolicyCreateAppleiCloudSetupService(CFStringRef hostname
, CFDictionaryRef context
)
3230 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyAppleiCloudSetupServerAuth
,
3231 kSecPolicyNameAppleiCloudSetupService
,
3232 &oidAppleCertExtAppleServerAuthenticationiCloudSetupProd
,
3233 &oidAppleCertExtAppleServerAuthenticationiCloudSetupProdQA
);
3236 SecPolicyRef
SecPolicyCreateAppleCompatibilityiCloudSetupService(CFStringRef hostname
)
3238 return SecPolicyCreateAppleGeoTrustServerAuthCommon(hostname
, kSecPolicyAppleiCloudSetupCompatibilityServerAuth
,
3239 kSecPolicyNameAppleiCloudSetupService
,
3240 CFSTR("1.2.840.113635.100.6.27.15.2"),
3241 CFSTR("1.2.840.113635.100.6.27.15.1"));
3245 @function SecPolicyCreateAppleSSLService
3246 @abstract Ensure we're appropriately pinned to an Apple server (SSL + Apple restrictions)
3248 SecPolicyRef
SecPolicyCreateAppleSSLService(CFStringRef hostname
)
3250 // SSL server, pinned to an Apple intermediate
3251 SecPolicyRef policy
= SecPolicyCreateSSL(true, hostname
);
3252 CFMutableDictionaryRef options
= NULL
;
3253 require(policy
, errOut
);
3255 // change options for SSL policy evaluation
3256 require((options
=(CFMutableDictionaryRef
)policy
->_options
) != NULL
, errOut
);
3258 // Apple CA anchored
3259 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameServerAuthentication
), errOut
);
3261 // Check leaf for Apple Server Authentication marker oid (1.2.840.113635.100.6.27.1)
3262 add_leaf_marker(options
, &oidAppleCertExtAppleServerAuthentication
);
3264 // Check intermediate for Apple Server Authentication intermediate marker (1.2.840.113635.100.6.2.12)
3265 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleServerAuthentication
);
3267 /* Check for weak hashes */
3268 require(SecPolicyRemoveWeakHashOptions(options
), errOut
);
3270 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
3272 SecPolicySetOid(policy
, kSecPolicyAppleServerAuthentication
);
3273 SecPolicySetName(policy
, kSecPolicyNameServerAuthentication
);
3278 CFReleaseSafe(options
);
3279 CFReleaseSafe(policy
);
3284 @function SecPolicyCreateApplePPQSigning
3285 @abstract Check for intermediate certificate 'Apple System Integration 2 Certification Authority' by name,
3287 Leaf cert must have Digital Signature usage.
3288 Leaf cert must have Apple PPQ Signing marker OID (1.2.840.113635.100.6.38.2).
3289 Intermediate must have marker OID (1.2.840.113635.100.6.2.10).
3291 SecPolicyRef
SecPolicyCreateApplePPQSigning(void)
3293 SecPolicyRef result
= NULL
;
3294 CFMutableDictionaryRef options
= NULL
;
3295 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3296 &kCFTypeDictionaryKeyCallBacks
,
3297 &kCFTypeDictionaryValueCallBacks
), errOut
);
3298 SecPolicyAddBasicCertOptions(options
);
3300 SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNamePPQSigning
);
3301 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3303 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
3304 CFSTR("Apple System Integration 2 Certification Authority"));
3306 // Check that leaf has extension with "Apple PPQ Signing" prod oid (1.2.840.113635.100.6.38.2)
3307 add_leaf_marker(options
, &oidAppleCertExtApplePPQSigningProd
);
3309 // Check that intermediate has extension (1.2.840.113635.100.6.2.10)
3310 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleSystemIntg2
);
3312 add_ku(options
, kSecKeyUsageDigitalSignature
);
3314 require(result
= SecPolicyCreate(kSecPolicyApplePPQSigning
,
3315 kSecPolicyNamePPQSigning
, options
), errOut
);
3318 CFReleaseSafe(options
);
3323 @function SecPolicyCreateTestApplePPQSigning
3324 @abstract Check for intermediate certificate 'Apple System Integration 2 Certification Authority' by name,
3326 Leaf cert must have Digital Signature usage.
3327 Leaf cert must have Apple PPQ Signing Test marker OID (1.2.840.113635.100.6.38.1).
3328 Intermediate must have marker OID (1.2.840.113635.100.6.2.10).
3330 SecPolicyRef
SecPolicyCreateTestApplePPQSigning(void)
3332 /* Guard against use of test policy on production devices */
3333 if (!SecIsInternalRelease()) {
3334 return SecPolicyCreateApplePPQSigning();
3337 SecPolicyRef result
= NULL
;
3338 CFMutableDictionaryRef options
= NULL
;
3339 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3340 &kCFTypeDictionaryKeyCallBacks
,
3341 &kCFTypeDictionaryValueCallBacks
), errOut
);
3342 SecPolicyAddBasicCertOptions(options
);
3344 SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameTestPPQSigning
);
3345 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3347 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
3348 CFSTR("Apple System Integration 2 Certification Authority"));
3350 // Check that leaf has extension with "Apple PPQ Signing" test oid (1.2.840.113635.100.6.38.1)
3351 add_leaf_marker(options
, &oidAppleCertExtApplePPQSigningProdQA
);
3353 // Check that intermediate has extension (1.2.840.113635.100.6.2.10)
3354 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleSystemIntg2
);
3356 add_ku(options
, kSecKeyUsageDigitalSignature
);
3358 require(result
= SecPolicyCreate(kSecPolicyAppleTestPPQSigning
,
3359 kSecPolicyNameTestPPQSigning
, options
), errOut
);
3362 CFReleaseSafe(options
);
3366 @function SecPolicyCreateAppleTimeStamping
3367 @abstract Check for RFC3161 timestamping EKU.
3369 SecPolicyRef
SecPolicyCreateAppleTimeStamping(void)
3371 SecPolicyRef result
= NULL
;
3372 CFMutableDictionaryRef options
= NULL
;
3373 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3374 &kCFTypeDictionaryKeyCallBacks
,
3375 &kCFTypeDictionaryValueCallBacks
), errOut
);
3377 SecPolicyAddBasicX509Options(options
);
3379 /* Require id-kp-timeStamping extendedKeyUsage to be present. */
3380 add_eku(options
, &oidExtendedKeyUsageTimeStamping
);
3382 require(result
= SecPolicyCreate(kSecPolicyAppleTimeStamping
,
3383 kSecPolicyNameTimeStamping
, options
), errOut
);
3386 CFReleaseSafe(options
);
3391 @function SecPolicyCreateApplePayIssuerEncryption
3392 @abstract Check for intermediate certificate 'Apple Worldwide Developer Relations CA - G2' by name,
3393 and ECC apple anchor.
3394 Leaf cert must have Key Encipherment and Key Agreement usage.
3395 Leaf cert must have Apple Pay Issuer Encryption marker OID (1.2.840.113635.100.6.39).
3397 SecPolicyRef
SecPolicyCreateApplePayIssuerEncryption(void)
3399 SecPolicyRef result
= NULL
;
3400 CFMutableDictionaryRef options
= NULL
;
3401 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3402 &kCFTypeDictionaryKeyCallBacks
,
3403 &kCFTypeDictionaryValueCallBacks
), errOut
);
3404 SecPolicyAddBasicCertOptions(options
);
3406 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNamePayIssuerEncryption
),
3408 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3410 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
3411 CFSTR("Apple Worldwide Developer Relations CA - G2"));
3413 // Check that leaf has extension with "Apple Pay Issuer Encryption" oid (1.2.840.113635.100.6.39)
3414 add_leaf_marker(options
, &oidAppleCertExtCryptoServicesExtEncryption
);
3416 add_ku(options
, kSecKeyUsageKeyEncipherment
);
3418 require(result
= SecPolicyCreate(kSecPolicyApplePayIssuerEncryption
,
3419 kSecPolicyNamePayIssuerEncryption
, options
), errOut
);
3422 CFReleaseSafe(options
);
3427 @function SecPolicyCreateAppleATVVPNProfileSigning
3428 @abstract Check for leaf marker OID 1.2.840.113635.100.6.43,
3429 intermediate marker OID 1.2.840.113635.100.6.2.10,
3430 chains to Apple Root CA, path length 3
3432 SecPolicyRef
SecPolicyCreateAppleATVVPNProfileSigning(void)
3434 SecPolicyRef result
= NULL
;
3435 CFMutableDictionaryRef options
= NULL
;
3436 CFMutableDictionaryRef appleAnchorOptions
= NULL
;
3437 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3438 &kCFTypeDictionaryKeyCallBacks
,
3439 &kCFTypeDictionaryValueCallBacks
), errOut
);
3441 SecPolicyAddBasicCertOptions(options
);
3443 // Require pinning to the Apple CAs (including test CA for internal releases)
3444 appleAnchorOptions
= CFDictionaryCreateMutableForCFTypes(NULL
);
3445 require(appleAnchorOptions
, errOut
);
3447 if (SecIsInternalRelease()) {
3448 CFDictionarySetValue(appleAnchorOptions
,
3449 kSecPolicyAppleAnchorIncludeTestRoots
, kCFBooleanTrue
);
3452 add_element(options
, kSecPolicyCheckAnchorApple
, appleAnchorOptions
);
3454 // Cert chain length 3
3455 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3457 // Check leaf for Apple ATV VPN Profile Signing OID (1.2.840.113635.100.6.43)
3458 add_leaf_marker(options
, &oidAppleCertExtATVVPNProfileSigning
);
3460 // Check intermediate for Apple System Integration 2 CA intermediate marker (1.2.840.113635.100.6.2.10)
3461 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleSystemIntg2
);
3463 // Ensure that revocation is checked (OCSP only)
3464 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationOCSP
);
3466 require(result
= SecPolicyCreate(kSecPolicyAppleATVVPNProfileSigning
,
3467 kSecPolicyNameATVVPNProfileSigning
, options
), errOut
);
3470 CFReleaseSafe(options
);
3471 CFReleaseSafe(appleAnchorOptions
);
3475 SecPolicyRef
SecPolicyCreateAppleHomeKitServerAuth(CFStringRef hostname
) {
3476 CFMutableDictionaryRef appleAnchorOptions
= NULL
;
3477 CFMutableDictionaryRef options
= NULL
;
3478 SecPolicyRef result
= NULL
;
3479 CFDataRef oid
= NULL
;
3481 options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0, &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
3482 require(options
, errOut
);
3484 SecPolicyAddBasicX509Options(options
);
3486 CFDictionaryAddValue(options
, kSecPolicyCheckSSLHostname
, hostname
);
3488 add_eku(options
, &oidExtendedKeyUsageServerAuth
);
3490 if (requireUATPinning(kSecPolicyNameAppleHomeKitService
)) {
3492 // Cert chain length 3
3493 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3495 // Apple anchors, allowing test anchors for internal release
3496 SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameAppleHomeKitService
);
3498 add_leaf_marker(options
, &oidAppleCertExtHomeKitServerAuth
);
3500 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleHomeKitServerCA
);
3503 /* Check for weak hashes */
3504 require(SecPolicyRemoveWeakHashOptions(options
), errOut
);
3505 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
3507 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
3509 result
= SecPolicyCreate(kSecPolicyAppleHomeKitServerAuth
,
3510 kSecPolicyNameAppleHomeKitService
, options
);
3511 require(result
, errOut
);
3514 CFReleaseSafe(appleAnchorOptions
);
3515 CFReleaseSafe(options
);
3520 SecPolicyRef
SecPolicyCreateAppleExternalDeveloper(void) {
3521 CFMutableDictionaryRef options
= NULL
;
3522 SecPolicyRef result
= NULL
;
3524 /* Create basic Apple pinned policy */
3525 require(result
= SecPolicyCreateApplePinned(kSecPolicyNameExternalDeveloper
,
3526 CFSTR("1.2.840.113635.100.6.2.1"), // WWDR Intermediate OID
3527 CFSTR("1.2.840.113635.100.6.1.2")), // "iPhone Developer" leaf OID
3530 require_action(options
= CFDictionaryCreateMutableCopy(NULL
, 0, result
->_options
), errOut
, CFReleaseNull(result
));
3532 /* Additional intermediate OIDs */
3533 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
,
3534 CFSTR("1.2.840.113635.100.6.2.6")); // "Developer ID" Intermediate OID
3536 /* Addtional leaf OIDS */
3537 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.4")); // "iPhone Distribution" leaf OID
3538 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.5")); // "Safari Developer" leaf OID
3539 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.7")); // "3rd Party Mac Developer Application" leaf OID
3540 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.8")); // "3rd Party Mac Developer Installer" leaf OID
3541 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.12")); // "Mac Developer" leaf OID
3542 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.13")); // "Developer ID Application" leaf OID
3543 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.14")); // "Developer ID Installer" leaf OID
3546 add_eku_string(options
, CFSTR("1.3.6.1.5.5.7.3.3")); // CodeSigning EKU
3547 add_eku_string(options
, CFSTR("1.2.840.113635.100.4.8")); // "Safari Developer" EKU
3548 add_eku_string(options
, CFSTR("1.2.840.113635.100.4.9")); // "3rd Party Mac Developer Installer" EKU
3549 add_eku_string(options
, CFSTR("1.2.840.113635.100.4.13")); // "Developer ID Installer" EKU
3551 CFReleaseSafe(result
->_options
);
3552 result
->_options
= CFRetainSafe(options
);
3554 SecPolicySetOid(result
, kSecPolicyAppleExternalDeveloper
);
3557 CFReleaseSafe(options
);
3561 /* This one is special because the intermediate has no marker OID */
3562 SecPolicyRef
SecPolicyCreateAppleSoftwareSigning(void) {
3563 CFMutableDictionaryRef options
= NULL
;
3564 CFDictionaryRef keySizes
= NULL
;
3565 CFNumberRef rsaSize
= NULL
, ecSize
= NULL
;
3566 SecPolicyRef result
= NULL
;
3568 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3569 &kCFTypeDictionaryKeyCallBacks
,
3570 &kCFTypeDictionaryValueCallBacks
), errOut
);
3572 SecPolicyAddBasicCertOptions(options
);
3574 /* Anchored to the Apple Roots */
3575 require_quiet(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameSoftwareSigning
),
3578 /* Exactly 3 certs in the chain */
3579 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3581 /* Intermediate Common Name matches */
3582 add_element(options
, kSecPolicyCheckIssuerCommonName
, CFSTR("Apple Code Signing Certification Authority"));
3584 /* Leaf marker OID matches */
3585 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.22"));
3587 /* Leaf has CodeSigning EKU */
3588 add_eku_string(options
, CFSTR("1.3.6.1.5.5.7.3.3"));
3590 /* Check revocation using any available method */
3591 add_element(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
3593 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
3594 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
3596 require(result
= SecPolicyCreate(kSecPolicyAppleSoftwareSigning
,
3597 kSecPolicyNameSoftwareSigning
, options
), errOut
);
3600 CFReleaseSafe(options
);
3601 CFReleaseSafe(keySizes
);
3602 CFReleaseSafe(rsaSize
);
3603 CFReleaseSafe(ecSize
);
3607 /* subject:/CN=SEP Root CA/O=Apple Inc./ST=California */
3608 /* SKID: 58:EF:D6:BE:C5:82:B0:54:CD:18:A6:84:AD:A2:F6:7B:7B:3A:7F:CF */
3609 /* Not Before: Jun 24 21:43:24 2014 GMT, Not After : Jun 24 21:43:24 2029 GMT */
3610 /* Signature Algorithm: ecdsa-with-SHA384 */
3611 const uint8_t SEPRootCA_SHA256
[kSecPolicySHA256Size
] = {
3612 0xd1, 0xdf, 0x82, 0x00, 0xf3, 0x89, 0x4e, 0xe9, 0x96, 0xf3, 0x77, 0xdf, 0x76, 0x3b, 0x0a, 0x16,
3613 0x8f, 0xd9, 0x6c, 0x58, 0xc0, 0x3e, 0xc9, 0xb0, 0x5f, 0xa5, 0x64, 0x79, 0xc0, 0xe8, 0xc9, 0xe7
3616 SecPolicyRef
SecPolicyCreateAppleUniqueDeviceCertificate(CFDataRef testRootHash
) {
3617 CFMutableDictionaryRef options
= NULL
;
3618 CFDictionaryRef keySizes
= NULL
;
3619 CFNumberRef ecSize
= NULL
;
3620 SecPolicyRef result
= NULL
;
3622 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3623 &kCFTypeDictionaryKeyCallBacks
,
3624 &kCFTypeDictionaryValueCallBacks
), errOut
);
3626 /* Device certificate should never expire */
3627 SecPolicyAddBasicCertOptions(options
);
3629 /* Anchored to the SEP Root CA. Allow alternative root for developers */
3630 require(SecPolicyAddAnchorSHA256Options(options
, SEPRootCA_SHA256
),errOut
);
3631 if (testRootHash
&& SecIsInternalRelease() && (kSecPolicySHA256Size
== CFDataGetLength(testRootHash
))) {
3632 add_element(options
, kSecPolicyCheckAnchorSHA256
, testRootHash
);
3635 /* Exactly 3 certs in the chain */
3636 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3638 /* Intermediate has marker OID with value */
3639 add_intermediate_marker_value_string(options
, CFSTR("1.2.840.113635.100.6.44"), CFSTR("ucrt"));
3641 /* Leaf has marker OID with varying value that can't be pre-determined */
3642 add_element(options
, kSecPolicyCheckLeafMarkerOidWithoutValueCheck
, CFSTR("1.2.840.113635.100.10.1"));
3644 /* RSA key sizes are disallowed. EC key sizes are P-256 or larger. */
3645 require(ecSize
= CFNumberCreateWithCFIndex(NULL
, 256), errOut
);
3646 require(keySizes
= CFDictionaryCreate(NULL
, (const void**)&kSecAttrKeyTypeEC
,
3647 (const void**)&ecSize
, 1,
3648 &kCFTypeDictionaryKeyCallBacks
,
3649 &kCFTypeDictionaryValueCallBacks
), errOut
);
3650 add_element(options
, kSecPolicyCheckKeySize
, keySizes
);
3653 require(result
= SecPolicyCreate(kSecPolicyAppleUniqueDeviceIdentifierCertificate
,
3654 kSecPolicyNameUniqueDeviceIdentifierCertificate
, options
), errOut
);
3657 CFReleaseSafe(options
);
3658 CFReleaseSafe(keySizes
);
3659 CFReleaseSafe(ecSize
);
3663 SecPolicyRef
SecPolicyCreateAppleWarsaw(void) {
3664 CFMutableDictionaryRef options
= NULL
;
3665 SecPolicyRef result
= NULL
;
3666 #if TARGET_OS_BRIDGE
3667 CFMutableDictionaryRef appleAnchorOptions
= NULL
;
3670 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3671 &kCFTypeDictionaryKeyCallBacks
,
3672 &kCFTypeDictionaryValueCallBacks
), errOut
);
3674 SecPolicyAddBasicX509Options(options
);
3676 /* Anchored to the Apple Roots. */
3677 require_quiet(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameWarsaw
),
3680 /* Exactly 3 certs in the chain */
3681 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3683 /* Intermediate marker OID matches input OID */
3684 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.14"));
3686 /* Leaf marker OID matches input OID */
3687 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.29"));
3689 /* Check revocation using any available method */
3690 add_element(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
3692 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
3693 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
3695 require(result
= SecPolicyCreate(kSecPolicyAppleWarsaw
,
3696 kSecPolicyNameWarsaw
, options
), errOut
);
3699 CFReleaseSafe(options
);
3703 SecPolicyRef
SecPolicyCreateAppleSecureIOStaticAsset(void) {
3704 CFMutableDictionaryRef options
= NULL
;
3705 SecPolicyRef result
= NULL
;
3706 #if TARGET_OS_BRIDGE
3707 CFMutableDictionaryRef appleAnchorOptions
= NULL
;
3710 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3711 &kCFTypeDictionaryKeyCallBacks
,
3712 &kCFTypeDictionaryValueCallBacks
), errOut
);
3714 /* This certificate cannot expire so that assets always load */
3715 SecPolicyAddBasicCertOptions(options
);
3717 /* Anchored to the Apple Roots. */
3718 #if TARGET_OS_BRIDGE
3719 /* On the bridge, test roots are gated in the trust and policy servers. */
3720 require_quiet(appleAnchorOptions
= CFDictionaryCreateMutableForCFTypes(NULL
), errOut
);
3721 CFDictionarySetValue(appleAnchorOptions
,
3722 kSecPolicyAppleAnchorIncludeTestRoots
, kCFBooleanTrue
);
3723 add_element(options
, kSecPolicyCheckAnchorApple
, appleAnchorOptions
);
3724 CFReleaseSafe(appleAnchorOptions
);
3726 require_quiet(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameSecureIOStaticAsset
),
3730 /* Exactly 3 certs in the chain */
3731 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3733 /* Intermediate marker OID matches ASI CA */
3734 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.10"));
3736 /* Leaf marker OID matches static IO OID */
3737 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.50"));
3739 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
3740 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
3742 require(result
= SecPolicyCreate(kSecPolicyAppleSecureIOStaticAsset
,
3743 kSecPolicyNameSecureIOStaticAsset
, options
), errOut
);
3746 CFReleaseSafe(options
);
3750 SecPolicyRef
SecPolicyCreateAppleAppTransportSecurity(void) {
3751 CFMutableDictionaryRef options
= NULL
;
3752 SecPolicyRef result
= NULL
;
3753 CFMutableArrayRef disallowedHashes
= NULL
;
3755 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3756 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
3758 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
3759 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
3761 /* Hash algorithm is SHA-256 or better */
3762 require(disallowedHashes
= CFArrayCreateMutable(NULL
, 5, &kCFTypeArrayCallBacks
), errOut
);
3763 CFArrayAppendValue(disallowedHashes
, kSecSignatureDigestAlgorithmMD2
);
3764 CFArrayAppendValue(disallowedHashes
, kSecSignatureDigestAlgorithmMD4
);
3765 CFArrayAppendValue(disallowedHashes
, kSecSignatureDigestAlgorithmMD5
);
3766 CFArrayAppendValue(disallowedHashes
, kSecSignatureDigestAlgorithmSHA1
);
3767 CFArrayAppendValue(disallowedHashes
, kSecSignatureDigestAlgorithmSHA224
);
3769 add_element(options
, kSecPolicyCheckSignatureHashAlgorithms
, disallowedHashes
);
3771 require_quiet(result
= SecPolicyCreate(kSecPolicyAppleAppTransportSecurity
,
3772 kSecPolicyNameAppTransportSecurity
,
3776 CFReleaseSafe(options
);
3780 SecPolicyRef
SecPolicyCreateMobileSoftwareUpdate(void) {
3781 CFMutableDictionaryRef options
= NULL
;
3782 SecPolicyRef result
= NULL
;
3783 #if TARGET_OS_BRIDGE
3784 CFMutableDictionaryRef appleAnchorOptions
= NULL
;
3787 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3788 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
3790 /* No expiration check. */
3791 SecPolicyAddBasicCertOptions(options
);
3794 require_quiet(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameMobileSoftwareUpdate
),
3797 /* Exactly 3 certs in the chain */
3798 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3800 /* Intermediate marker OID is iPhone CA OID */
3801 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.18"));
3803 /* Leaf marker OID is either the prod MSU OID, or, on internal builds, the prodQA OID */
3804 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.57.2"));
3805 if (SecIsInternalRelease()) {
3806 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.57.1"));
3809 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
3810 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
3812 require(result
= SecPolicyCreate(kSecPolicyAppleMobileSoftwareUpdate
,
3813 kSecPolicyNameMobileSoftwareUpdate
, options
), errOut
);
3816 CFReleaseNull(options
);
3820 /* subject:/CN=Basic Attestation System Root CA/O=Apple Inc./ST=California */
3821 /* SKID: FE:D1:D1:C2:08:07:03:D5:B9:3C:34:B2:BB:FD:7C:3A:99:25:1B:8F */
3822 /* Not Before: Apr 20 00:22:09 2017 GMT, Not After : Mar 22 00:00:00 2032 GMT */
3823 /* Signature Algorithm: ecdsa-with-SHA384 */
3824 const uint8_t BASystemRootCA_SHA256
[kSecPolicySHA256Size
] = {
3825 0x10, 0xD3, 0xC8, 0x67, 0xF0, 0xAE, 0xFB, 0x24, 0x31, 0xA0, 0xA9, 0x7A, 0x88, 0x18, 0xBD, 0x64,
3826 0xF7, 0xF9, 0x0F, 0xFE, 0x11, 0x94, 0x48, 0x4F, 0xCA, 0x97, 0xF0, 0xF2, 0x9E, 0xCA, 0x00, 0x47
3829 /* subject:/CN=Basic Attestation User Root CA/O=Apple Inc./ST=California */
3830 /* SKID: 83:E5:A3:21:9E:B0:74:C3:F9:61:90:FD:97:4E:23:10:76:A4:A3:F2 */
3831 /* Not Before: Apr 19 21:41:56 2017 GMT, Not After : Mar 22 00:00:00 2032 GMT */
3832 /* Signature Algorithm: ecdsa-with-SHA384 */
3833 const uint8_t BAUserRootCA_SHA256
[kSecPolicySHA256Size
] = {
3834 0x03, 0x75, 0x1c, 0x80, 0xfc, 0xbe, 0x58, 0x19, 0xd1, 0x70, 0xd2, 0x67, 0xce, 0x1a, 0xd6, 0xd0,
3835 0x94, 0x40, 0x7c, 0x91, 0xd8, 0x73, 0xd7, 0xa6, 0x56, 0x2d, 0xe3, 0x66, 0x6d, 0x35, 0x94, 0xc6
3838 SecPolicyRef
SecPolicyCreateAppleBasicAttestationSystem(CFDataRef testRootHash
) {
3839 CFMutableDictionaryRef options
= NULL
;
3840 SecPolicyRef result
= NULL
;
3842 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3843 &kCFTypeDictionaryKeyCallBacks
,
3844 &kCFTypeDictionaryValueCallBacks
), errOut
);
3845 /* BAA certs expire */
3846 SecPolicyAddBasicX509Options(options
);
3848 /* Anchored to one of the Basic Attestation roots. Allow alternative root for developers */
3849 SecPolicyAddAnchorSHA256Options(options
, BASystemRootCA_SHA256
);
3850 if (testRootHash
&& SecIsInternalRelease() && (kSecPolicySHA256Size
== CFDataGetLength(testRootHash
))) {
3851 add_element(options
, kSecPolicyCheckAnchorSHA256
, testRootHash
);
3854 /* Exactly 3 certs in the chain */
3855 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3857 require(result
= SecPolicyCreate(kSecPolicyAppleBasicAttestationSystem
,
3858 kSecPolicyNameBasicAttestationSystem
, options
), errOut
);
3861 CFReleaseSafe(options
);
3865 SecPolicyRef
SecPolicyCreateAppleBasicAttestationUser(CFDataRef testRootHash
) {
3866 CFMutableDictionaryRef options
= NULL
;
3867 SecPolicyRef result
= NULL
;
3869 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3870 &kCFTypeDictionaryKeyCallBacks
,
3871 &kCFTypeDictionaryValueCallBacks
), errOut
);
3872 /* BAA certs expire */
3873 SecPolicyAddBasicX509Options(options
);
3875 /* Anchored to one of the Basic Attestation roots. Allow alternative root for developers */
3876 SecPolicyAddAnchorSHA256Options(options
, BAUserRootCA_SHA256
);
3877 if (testRootHash
&& SecIsInternalRelease() && (kSecPolicySHA256Size
== CFDataGetLength(testRootHash
))) {
3878 add_element(options
, kSecPolicyCheckAnchorSHA256
, testRootHash
);
3881 /* Exactly 3 certs in the chain */
3882 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3884 require(result
= SecPolicyCreate(kSecPolicyAppleBasicAttestationUser
,
3885 kSecPolicyNameBasicAttestationUser
, options
), errOut
);
3888 CFReleaseSafe(options
);
3892 SecPolicyRef
SecPolicyCreateiAPSWAuthWithExpiration(bool checkExpiration
) {
3893 CFMutableDictionaryRef options
= NULL
;
3894 SecPolicyRef result
= NULL
;
3896 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3897 &kCFTypeDictionaryKeyCallBacks
,
3898 &kCFTypeDictionaryValueCallBacks
), errOut
);
3900 /* iAP checks expiration on developement certs, but not on production certs */
3901 if (checkExpiration
) {
3902 SecPolicyAddBasicX509Options(options
);
3904 SecPolicyAddBasicCertOptions(options
);
3907 /* Exactly 2 certs in the chain */
3908 require(SecPolicyAddChainLengthOptions(options
, 2), errOut
);
3910 /* iAP SW Auth General Capabilities Extension present */
3911 add_element(options
, kSecPolicyCheckLeafMarkerOidWithoutValueCheck
, CFSTR("1.2.840.113635.100.6.59.1"));
3913 require(result
= SecPolicyCreate(kSecPolicyAppleiAPSWAuth
,
3914 kSecPolicyNameiAPSWAuth
, options
), errOut
);
3917 CFReleaseSafe(options
);
3921 SecPolicyRef
SecPolicyCreateiAPSWAuth(void) {
3922 /* By default, iAP SW Auth certs don't expire */
3923 return SecPolicyCreateiAPSWAuthWithExpiration(false);
3926 SecPolicyRef
SecPolicyCreateDemoDigitalCatalogSigning(void) {
3927 CFMutableDictionaryRef options
= NULL
;
3928 SecPolicyRef result
= NULL
;
3930 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3931 &kCFTypeDictionaryKeyCallBacks
,
3932 &kCFTypeDictionaryValueCallBacks
), errOut
);
3933 SecPolicyAddBasicX509Options(options
);
3935 /* Exactly 3 certs in the chain */
3936 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3938 /* Demo Signing Extension present in leaf */
3939 add_element(options
, kSecPolicyCheckLeafMarkerOid
, CFSTR("1.2.840.113635.100.6.60"));
3941 /* Issuer common name is "DemoUnit CA" */
3942 add_element(options
, kSecPolicyCheckIssuerCommonName
, CFSTR("DemoUnit CA"));
3944 require(result
= SecPolicyCreate(kSecPolicyAppleDemoDigitalCatalog
,
3945 kSecPolicyNameDemoDigitalCatalog
, options
), errOut
);
3948 CFReleaseSafe(options
);
3952 SecPolicyRef
SecPolicyCreateAppleAssetReceipt(void) {
3953 CFMutableDictionaryRef options
= NULL
;
3954 SecPolicyRef result
= NULL
;
3956 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3957 &kCFTypeDictionaryKeyCallBacks
,
3958 &kCFTypeDictionaryValueCallBacks
), errOut
);
3960 /* No expiration check. */
3961 SecPolicyAddBasicCertOptions(options
);
3964 require_quiet(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameAssetReceipt
), errOut
);
3966 /* Exactly 3 certs in the chain */
3967 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3969 /* Intermediate marker OID is Apple System Integration 2 CA */
3970 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.10"));
3972 /* Leaf marker OID is the Asset Receipt OID */
3973 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.61"));
3975 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
3976 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
3978 require(result
= SecPolicyCreate(kSecPolicyAppleAssetReceipt
,
3979 kSecPolicyNameAssetReceipt
, options
), errOut
);
3982 CFReleaseNull(options
);
3986 SecPolicyRef
SecPolicyCreateAppleDeveloperIDPlusTicket(void) {
3987 CFMutableDictionaryRef options
= NULL
;
3988 SecPolicyRef result
= NULL
;
3990 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3991 &kCFTypeDictionaryKeyCallBacks
,
3992 &kCFTypeDictionaryValueCallBacks
), errOut
);
3994 /* No expiration check. */
3995 SecPolicyAddBasicCertOptions(options
);
3998 require_quiet(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameDeveloperIDPlusTicket
), errOut
);
4000 /* Exactly 3 certs in the chain */
4001 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
4003 /* Intermediate marker OID is Apple System Integration CA 4 */
4004 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.17"));
4006 /* Leaf marker OID is the Developer ID+ Ticket OID */
4007 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.30"));
4009 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
4010 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
4012 require(result
= SecPolicyCreate(kSecPolicyAppleDeveloperIDPlusTicket
,
4013 kSecPolicyNameDeveloperIDPlusTicket
, options
), errOut
);
4016 CFReleaseNull(options
);
4020 SecPolicyRef
SecPolicyCreateAppleFDRProvisioning(void) {
4021 CFMutableDictionaryRef options
= NULL
;
4022 SecPolicyRef result
= NULL
;
4024 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
4025 &kCFTypeDictionaryKeyCallBacks
,
4026 &kCFTypeDictionaryValueCallBacks
), errOut
);
4028 /* No expiration check. */
4029 SecPolicyAddBasicCertOptions(options
);
4031 require(result
= SecPolicyCreate(kSecPolicyAppleFDRProvisioning
,
4032 kSecPolicyNameFDRProvisioning
, options
), errOut
);
4034 CFReleaseNull(options
);
4038 /* subject:/CN=Component Root CA/O=Apple Inc./ST=California */
4039 /* SKID: 90:D1:56:A9:3E:B4:EE:8C:D0:10:4B:9F:17:1C:5B:55:F2:12:F6:4C */
4040 /* Not Before: Dec 19 19:31:54 2018 GMT, Not After : Dec 16 00:00:00 2043 GMT */
4041 /* Signature Algorithm: ecdsa-with-SHA384 */
4042 const uint8_t ComponentRootCA_SHA256
[kSecPolicySHA256Size
] = {
4043 0x2f, 0x71, 0x9d, 0xbf, 0x3c, 0xcd, 0xe7, 0xc2, 0xb2, 0x59, 0x3f, 0x32, 0x1f, 0x90, 0xf3, 0x42,
4044 0x42, 0xaa, 0x84, 0xa1, 0xb2, 0x0d, 0xca, 0xcc, 0x10, 0xc0, 0x5b, 0x26, 0xd6, 0x23, 0xb8, 0x47,
4046 SecPolicyRef
SecPolicyCreateAppleComponentCertificate(CFDataRef testRootHash
) {
4047 CFMutableDictionaryRef options
= NULL
;
4048 SecPolicyRef result
= NULL
;
4050 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
4051 &kCFTypeDictionaryKeyCallBacks
,
4052 &kCFTypeDictionaryValueCallBacks
), errOut
);
4054 /* Component certificates don't expire */
4055 SecPolicyAddBasicCertOptions(options
);
4057 /* Anchored to one of the Component roots. Allow alternative root for developers */
4058 SecPolicyAddAnchorSHA256Options(options
, ComponentRootCA_SHA256
);
4059 if (testRootHash
&& SecIsInternalRelease() && (kSecPolicySHA256Size
== CFDataGetLength(testRootHash
))) {
4060 add_element(options
, kSecPolicyCheckAnchorSHA256
, testRootHash
);
4063 /* Exactly 3 certs in the chain */
4064 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
4066 /* Leaf and intermediate must contain Component Type OID */
4067 add_element(options
, kSecPolicyCheckLeafMarkerOidWithoutValueCheck
, CFSTR("1.2.840.113635.100.11.1"));
4068 add_element(options
, kSecPolicyCheckIntermediateMarkerOidWithoutValueCheck
, CFSTR("1.2.840.113635.100.11.1"));
4070 require(result
= SecPolicyCreate(kSecPolicyAppleComponentCertificate
,
4071 kSecPolicyNameComponentCertificate
, options
), errOut
);
4073 CFReleaseNull(options
);
4077 SecPolicyRef
SecPolicyCreateAppleKeyTransparency(CFStringRef applicationId
) {
4078 CFMutableDictionaryRef options
= NULL
;
4079 SecPolicyRef result
= NULL
;
4081 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
4082 &kCFTypeDictionaryKeyCallBacks
,
4083 &kCFTypeDictionaryValueCallBacks
), errOut
);
4085 /* KT signing certs don't expire */
4086 SecPolicyAddBasicCertOptions(options
);
4089 require_quiet(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameKeyTransparency
), errOut
);
4091 /* Exactly 3 certs in the chain */
4092 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
4094 /* Intermediate marker OID matches AAI CA 5 */
4095 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.3"));
4097 /* Leaf marker extension matches input applicationId */
4098 add_leaf_marker_value_string(options
, CFSTR("1.2.840.113635.100.12.4"), applicationId
);
4100 /* Check revocation using any available method */
4101 add_element(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
4103 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
4104 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
4106 /* Check for weak hashes */
4107 require(SecPolicyRemoveWeakHashOptions(options
), errOut
);
4109 /* Future CT requirement */
4111 require(result
= SecPolicyCreate(kSecPolicyAppleKeyTransparency
,
4112 kSecPolicyNameKeyTransparency
, options
), errOut
);
4114 CFReleaseNull(options
);