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");
135 #define kSecPolicySHA1Size 20
136 #define kSecPolicySHA256Size 32
137 __unused
const UInt8 kAppleCASHA1
[kSecPolicySHA1Size
] = {
138 0x61, 0x1E, 0x5B, 0x66, 0x2C, 0x59, 0x3A, 0x08, 0xFF, 0x58,
139 0xD1, 0x4A, 0xE2, 0x24, 0x52, 0xD1, 0x98, 0xDF, 0x6C, 0x60
142 __unused
static const UInt8 kAppleTESTCASHA1
[kSecPolicySHA1Size
] = {
143 0xbc, 0x30, 0x55, 0xc8, 0xc8, 0xd3, 0x48, 0x3f, 0xf4, 0x8d,
144 0xfe, 0x3d, 0x51, 0x75, 0x31, 0xc9, 0xf4, 0xd7, 0x4a, 0xf7
147 static const UInt8 kITMSCASHA1
[kSecPolicySHA1Size
] = {
148 0x1D, 0x33, 0x42, 0x46, 0x8B, 0x10, 0xBD, 0xE6, 0x45, 0xCE,
149 0x44, 0x6E, 0xBB, 0xE8, 0xF5, 0x03, 0x5D, 0xF8, 0x32, 0x22
152 static const UInt8 kFactoryDeviceCASHA1
[kSecPolicySHA1Size
] = {
153 0xef, 0x68, 0x73, 0x17, 0xa4, 0xf8, 0xf9, 0x4b, 0x7b, 0x21,
154 0xe2, 0x2f, 0x09, 0x8f, 0xfd, 0x6a, 0xae, 0xc0, 0x0d, 0x63
157 static const UInt8 kApplePKISettingsAuthority
[kSecPolicySHA1Size
] = {
158 0x1D, 0x0C, 0xBA, 0xAD, 0x17, 0xFD, 0x7E, 0x9E, 0x9F, 0xF1,
159 0xC9, 0xA2, 0x66, 0x79, 0x60, 0x00, 0x8B, 0xAE, 0x70, 0xB8
162 static const UInt8 kAppleTestPKISettingsAuthority
[kSecPolicySHA1Size
] = {
163 0xDB, 0xBA, 0x25, 0x0B, 0xD8, 0x62, 0x71, 0x87, 0x54, 0x7E,
164 0xD7, 0xEF, 0x11, 0x94, 0x7E, 0x82, 0xE6, 0xD8, 0x1C, 0x9A
167 static const UInt8 kTestAppleRootCA_ECC_SHA1
[kSecPolicySHA1Size
] = {
168 0x62, 0x0A, 0xED, 0x83, 0xD2, 0x97, 0x4A, 0x77, 0x56, 0x33,
169 0x83, 0xBE, 0xDB, 0xF9, 0xA1, 0xBD, 0x5F, 0xFE, 0x55, 0x7B
172 __unused
static const UInt8 kAppleRootCA_ECC_SHA1
[kSecPolicySHA1Size
] = {
173 0xB5, 0x2C, 0xB0, 0x2F, 0xD5, 0x67, 0xE0, 0x35, 0x9F, 0xE8,
174 0xFA, 0x4D, 0x4C, 0x41, 0x03, 0x79, 0x70, 0xFE, 0x01, 0xB0
179 /********************************************************
180 ****************** SecPolicy object ********************
181 ********************************************************/
183 static void SecPolicyDestroy(CFTypeRef cf
) {
184 SecPolicyRef policy
= (SecPolicyRef
) cf
;
185 CFRelease(policy
->_oid
);
186 CFReleaseSafe(policy
->_name
);
187 CFRelease(policy
->_options
);
190 static Boolean
SecPolicyCompare(CFTypeRef cf1
, CFTypeRef cf2
) {
191 SecPolicyRef policy1
= (SecPolicyRef
) cf1
;
192 SecPolicyRef policy2
= (SecPolicyRef
) cf2
;
193 if (policy1
->_name
&& policy2
->_name
) {
194 return CFEqual(policy1
->_oid
, policy2
->_oid
) &&
195 CFEqual(policy1
->_name
, policy2
->_name
) &&
196 CFEqual(policy1
->_options
, policy2
->_options
);
198 return CFEqual(policy1
->_oid
, policy2
->_oid
) &&
199 CFEqual(policy1
->_options
, policy2
->_options
);
203 static CFHashCode
SecPolicyHash(CFTypeRef cf
) {
204 SecPolicyRef policy
= (SecPolicyRef
) cf
;
206 return CFHash(policy
->_oid
) + CFHash(policy
->_name
) + CFHash(policy
->_options
);
208 return CFHash(policy
->_oid
) + CFHash(policy
->_options
);
212 static CFStringRef
SecPolicyCopyFormatDescription(CFTypeRef cf
, CFDictionaryRef formatOptions
) {
213 SecPolicyRef policy
= (SecPolicyRef
) cf
;
214 CFMutableStringRef desc
= CFStringCreateMutable(kCFAllocatorDefault
, 0);
215 CFStringRef typeStr
= CFCopyTypeIDDescription(CFGetTypeID(cf
));
216 CFStringAppendFormat(desc
, NULL
,
217 CFSTR("<%@: oid: %@ name: %@ options %@"), typeStr
,
218 policy
->_oid
, (policy
->_name
) ? policy
->_name
: CFSTR(""),
221 CFStringAppend(desc
, CFSTR(" >"));
226 /* SecPolicy API functions. */
227 CFGiblisWithHashFor(SecPolicy
);
229 /* AUDIT[securityd](done):
230 oid (ok) is a caller provided string, only its cf type has been checked.
231 options is a caller provided dictionary, only its cf type has been checked.
233 SecPolicyRef
SecPolicyCreate(CFStringRef oid
, CFStringRef name
, CFDictionaryRef options
) {
234 SecPolicyRef result
= NULL
;
236 require(oid
, errOut
);
237 require(options
, errOut
);
239 (SecPolicyRef
)_CFRuntimeCreateInstance(kCFAllocatorDefault
,
240 SecPolicyGetTypeID(),
241 sizeof(struct __SecPolicy
) - sizeof(CFRuntimeBase
), 0), errOut
);
246 result
->_name
= name
;
248 result
->_options
= options
;
255 static void set_ku_from_properties(SecPolicyRef policy
, CFDictionaryRef properties
);
258 SecPolicyRef
SecPolicyCreateWithProperties(CFTypeRef policyIdentifier
,
259 CFDictionaryRef properties
) {
260 // Creates a policy reference for a given policy object identifier.
261 // If policy-specific parameters can be supplied (e.g. hostname),
262 // attempt to obtain from input properties dictionary.
263 // Returns NULL if the given identifier is unsupported.
265 SecPolicyRef policy
= NULL
;
266 CFTypeRef name
= NULL
;
267 CFStringRef teamID
= NULL
;
268 Boolean client
= false;
269 CFDictionaryRef context
= NULL
;
270 CFStringRef policyName
= NULL
, intermediateMarkerOid
= NULL
, leafMarkerOid
= NULL
;
271 CFDataRef rootDigest
= NULL
;
272 require(policyIdentifier
&& (CFStringGetTypeID() == CFGetTypeID(policyIdentifier
)), errOut
);
275 name
= CFDictionaryGetValue(properties
, kSecPolicyName
);
276 teamID
= CFDictionaryGetValue(properties
, kSecPolicyTeamIdentifier
);
278 CFBooleanRef dictionaryClientValue
;
279 client
= (CFDictionaryGetValueIfPresent(properties
, kSecPolicyClient
, (const void **)&dictionaryClientValue
) &&
280 (dictionaryClientValue
!= NULL
) && CFEqual(kCFBooleanTrue
, dictionaryClientValue
));
281 context
= CFDictionaryGetValue(properties
, kSecPolicyContext
);
282 policyName
= CFDictionaryGetValue(properties
, kSecPolicyPolicyName
);
283 intermediateMarkerOid
= CFDictionaryGetValue(properties
, kSecPolicyIntermediateMarkerOid
);
284 leafMarkerOid
= CFDictionaryGetValue(properties
, kSecPolicyLeafMarkerOid
);
285 rootDigest
= CFDictionaryGetValue(properties
, kSecPolicyRootDigest
);
288 /* only the EAP policy allows a non-string name */
289 if (name
&& !isString(name
) && !CFEqual(policyIdentifier
, kSecPolicyAppleEAP
)) {
290 secerror("policy \"%@\" requires a string value for the %@ key", policyIdentifier
, kSecPolicyName
);
294 /* What follows are all the exceptional functions that do not match the macro below */
295 if (CFEqual(policyIdentifier
, kSecPolicyAppleSSL
)) {
296 policy
= SecPolicyCreateSSL(!client
, name
);
297 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleSMIME
)) {
298 policy
= SecPolicyCreateSMIME(kSecSignSMIMEUsage
| kSecAnyEncryptSMIME
, name
);
299 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleEAP
)) {
300 CFArrayRef array
= NULL
;
301 if (isString(name
)) {
302 array
= CFArrayCreate(kCFAllocatorDefault
, (const void **)&name
, 1, &kCFTypeArrayCallBacks
);
303 } else if (isArray(name
)) {
304 array
= CFArrayCreateCopy(NULL
, name
);
306 policy
= SecPolicyCreateEAP(!client
, array
);
307 CFReleaseSafe(array
);
308 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleIPsec
)) {
309 policy
= SecPolicyCreateIPSec(!client
, name
);
310 } else if (CFEqual(policyIdentifier
, kSecPolicyMacAppStoreReceipt
)) {
311 policy
= SecPolicyCreateMacAppStoreReceipt();
312 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleRevocation
)) {
313 policy
= SecPolicyCreateRevocation(kSecRevocationUseAnyAvailableMethod
);
314 } else if (CFEqual(policyIdentifier
, kSecPolicyApplePassbookSigning
)) {
315 policy
= SecPolicyCreatePassbookCardSigner(name
, teamID
);
316 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleAST2DiagnosticsServerAuth
)) {
318 policy
= SecPolicyCreateAppleAST2Service(name
, context
);
320 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier
);
322 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleEscrowProxyServerAuth
)) {
324 policy
= SecPolicyCreateAppleEscrowProxyService(name
, context
);
326 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier
);
328 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleFMiPServerAuth
)) {
330 policy
= SecPolicyCreateAppleFMiPService(name
, context
);
332 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier
);
334 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleMMCService
)) {
336 policy
= SecPolicyCreateAppleMMCSService(name
, context
);
338 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier
);
340 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleGSService
)) {
342 policy
= SecPolicyCreateAppleGSService(name
, context
);
344 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier
);
346 } else if (CFEqual(policyIdentifier
, kSecPolicyApplePPQService
)) {
348 policy
= SecPolicyCreateApplePPQService(name
, context
);
350 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier
);
352 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleGenericApplePinned
)) {
354 policy
= SecPolicyCreateApplePinned(policyName
, intermediateMarkerOid
, leafMarkerOid
);
356 secerror("policy \"%@\" requires kSecPolicyPolicyName input", policyIdentifier
);
358 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleGenericAppleSSLPinned
)) {
360 policy
= SecPolicyCreateAppleSSLPinned(policyName
, name
, intermediateMarkerOid
, leafMarkerOid
);
362 secerror("policy \"%@\" requires kSecPolicyPolicyName input", policyIdentifier
);
364 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleIDSServiceContext
)) {
366 policy
= SecPolicyCreateAppleIDSServiceContext(name
, context
);
368 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier
);
370 } else if (CFEqual(policyIdentifier
, kSecPolicyApplePushService
)) {
372 policy
= SecPolicyCreateApplePushService(name
, context
);
374 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier
);
376 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleUniqueDeviceIdentifierCertificate
)) {
377 policy
= SecPolicyCreateAppleUniqueDeviceCertificate(rootDigest
);
378 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleiCloudSetupServerAuth
)) {
380 policy
= SecPolicyCreateAppleiCloudSetupService(name
, context
);
382 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier
);
384 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleBasicAttestationSystem
)) {
385 policy
= SecPolicyCreateAppleBasicAttestationSystem(rootDigest
);
386 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleBasicAttestationUser
)) {
387 policy
= SecPolicyCreateAppleBasicAttestationUser(rootDigest
);
388 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleComponentCertificate
)) {
389 policy
= SecPolicyCreateAppleComponentCertificate(rootDigest
);
391 /* For a couple of common patterns we use the macro, but some of the
392 * policies are deprecated, so we need to ignore the warning. */
393 #pragma clang diagnostic push
394 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
396 #define _P_OPTION_N name
397 #define _P_PROPERTIES_(NAME, IN_NAME, FUNCTION)
398 #define _P_PROPERTIES_Y(NAME, IN_NAME, FUNCTION) else if (CFEqual(policyIdentifier, kSecPolicyApple##NAME)) { \
399 policy = SecPolicyCreate##FUNCTION(_P_OPTION_##IN_NAME); \
402 #define POLICYMACRO(NAME, OID, ISPUBLIC, INTNAME, IN_NAME, IN_PROPERTIES, FUNCTION) \
403 _P_PROPERTIES_##IN_PROPERTIES(NAME, IN_NAME, FUNCTION)
404 #include "SecPolicy.list"
406 secerror("ERROR: policy \"%@\" is unsupported", policyIdentifier
);
408 #pragma clang diagnostic pop // ignored "-Wdeprecated-declarations"
415 set_ku_from_properties(policy
, properties
);
419 SecPolicySetName(policy
, policyName
);
426 CFDictionaryRef
SecPolicyCopyProperties(SecPolicyRef policyRef
) {
427 // Builds and returns a dictionary which the caller must release.
429 #pragma clang diagnostic push
430 #pragma clang diagnostic ignored "-Wnonnull"
431 // After introducing nullability annotations, policyRef is supposed to be nonnull, suppress the warning
432 if (!policyRef
) return NULL
;
433 #pragma clang diagnostic pop
434 CFMutableDictionaryRef properties
= CFDictionaryCreateMutable(NULL
, 0,
435 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
436 #pragma clang diagnostic push
437 #pragma clang diagnostic ignored "-Wnonnull"
438 // 'properties' is nonnull in reality suppress the warning
439 if (!properties
) return NULL
;
440 #pragma clang diagnostic pop
441 CFStringRef oid
= (CFStringRef
) CFRetain(policyRef
->_oid
);
442 CFTypeRef nameKey
= NULL
;
444 // Determine name key
445 if (policyRef
->_options
) {
446 if (CFDictionaryContainsKey(policyRef
->_options
, kSecPolicyCheckSSLHostname
)) {
447 nameKey
= kSecPolicyCheckSSLHostname
;
448 } else if (CFDictionaryContainsKey(policyRef
->_options
, kSecPolicyCheckEAPTrustedServerNames
)) {
449 nameKey
= kSecPolicyCheckEAPTrustedServerNames
;
450 } else if (CFDictionaryContainsKey(policyRef
->_options
, kSecPolicyCheckEmail
)) {
451 nameKey
= kSecPolicyCheckEmail
;
456 CFDictionarySetValue(properties
, (const void *)kSecPolicyOid
,
459 // Set kSecPolicyName if we have one
460 if (nameKey
&& policyRef
->_options
) {
461 CFTypeRef name
= (CFTypeRef
) CFDictionaryGetValue(policyRef
->_options
,
464 CFDictionarySetValue(properties
, (const void *)kSecPolicyName
,
469 // Set kSecPolicyClient
470 CFStringRef policyName
= (CFStringRef
) CFRetainSafe(policyRef
->_name
);
471 if (policyName
&& (CFEqual(policyName
, kSecPolicyNameSSLClient
) ||
472 CFEqual(policyName
, kSecPolicyNameIPSecClient
) ||
473 CFEqual(policyName
, kSecPolicyNameEAPClient
))) {
474 CFDictionarySetValue(properties
, (const void *)kSecPolicyClient
,
475 (const void *)kCFBooleanTrue
);
482 static void SecPolicySetOid(SecPolicyRef policy
, CFStringRef oid
) {
483 if (!policy
|| !oid
) return;
484 CFStringRef temp
= policy
->_oid
;
490 void SecPolicySetName(SecPolicyRef policy
, CFStringRef policyName
) {
491 if (!policy
|| !policyName
) return;
492 CFStringRef temp
= policy
->_name
;
493 CFRetain(policyName
);
494 policy
->_name
= policyName
;
498 CFStringRef
SecPolicyGetOidString(SecPolicyRef policy
) {
502 CFStringRef
SecPolicyGetName(SecPolicyRef policy
) {
503 return policy
->_name
;
506 CFDictionaryRef
SecPolicyGetOptions(SecPolicyRef policy
) {
507 return policy
->_options
;
510 void SecPolicySetOptionsValue(SecPolicyRef policy
, CFStringRef key
, CFTypeRef value
) {
511 if (!policy
|| !key
) return;
512 CFMutableDictionaryRef options
= (CFMutableDictionaryRef
) policy
->_options
;
514 options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
515 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
516 if (!options
) return;
517 policy
->_options
= options
;
519 CFDictionarySetValue(options
, key
, value
);
522 /* Local forward declaration */
523 static void set_ssl_ekus(CFMutableDictionaryRef options
, bool server
);
526 // this is declared as NA for iPhone in SecPolicy.h, so declare here
527 OSStatus
SecPolicySetProperties(SecPolicyRef policyRef
, CFDictionaryRef properties
);
530 OSStatus
SecPolicySetProperties(SecPolicyRef policyRef
, CFDictionaryRef properties
) {
531 // Set policy options based on the provided dictionary keys.
533 if (!(policyRef
&& properties
&& (CFDictionaryGetTypeID() == CFGetTypeID(properties
)))) {
536 CFStringRef oid
= (CFStringRef
) CFRetain(policyRef
->_oid
);
537 OSStatus result
= errSecSuccess
;
540 CFTypeRef name
= NULL
;
541 if (CFDictionaryGetValueIfPresent(properties
, (const void *)kSecPolicyName
,
542 (const void **)&name
) && name
) {
543 CFTypeID typeID
= CFGetTypeID(name
);
544 if (CFEqual(oid
, kSecPolicyAppleSSL
) ||
545 CFEqual(oid
, kSecPolicyAppleIPsec
)) {
546 if (CFStringGetTypeID() == typeID
) {
547 SecPolicySetOptionsValue(policyRef
, kSecPolicyCheckSSLHostname
, name
);
549 else result
= errSecParam
;
551 else if (CFEqual(oid
, kSecPolicyAppleEAP
)) {
552 if ((CFStringGetTypeID() == typeID
) ||
553 (CFArrayGetTypeID() == typeID
)) {
554 SecPolicySetOptionsValue(policyRef
, kSecPolicyCheckEAPTrustedServerNames
, name
);
556 else result
= errSecParam
;
558 else if (CFEqual(oid
, kSecPolicyAppleSMIME
)) {
559 if (CFStringGetTypeID() == typeID
) {
560 SecPolicySetOptionsValue(policyRef
, kSecPolicyCheckEmail
, name
);
562 else result
= errSecParam
;
567 CFTypeRef client
= NULL
;
568 if (CFDictionaryGetValueIfPresent(properties
, (const void *)kSecPolicyClient
,
569 (const void **)&client
) && client
) {
570 if (!(CFBooleanGetTypeID() == CFGetTypeID(client
))) {
571 result
= errSecParam
;
573 else if (CFEqual(client
, kCFBooleanTrue
)) {
574 if (CFEqual(oid
, kSecPolicyAppleSSL
)) {
575 SecPolicySetName(policyRef
, kSecPolicyNameSSLClient
);
576 /* Set EKU checks for clients */
577 CFMutableDictionaryRef newOptions
= CFDictionaryCreateMutableCopy(NULL
, 0, policyRef
->_options
);
578 set_ssl_ekus(newOptions
, false);
579 CFReleaseSafe(policyRef
->_options
);
580 policyRef
->_options
= newOptions
;
582 else if (CFEqual(oid
, kSecPolicyAppleIPsec
)) {
583 SecPolicySetName(policyRef
, kSecPolicyNameIPSecClient
);
585 else if (CFEqual(oid
, kSecPolicyNameEAPServer
)) {
586 SecPolicySetName(policyRef
, kSecPolicyNameEAPClient
);
587 /* Set EKU checks for clients */
588 CFMutableDictionaryRef newOptions
= CFDictionaryCreateMutableCopy(NULL
, 0, policyRef
->_options
);
589 set_ssl_ekus(newOptions
, false);
590 CFReleaseSafe(policyRef
->_options
);
591 policyRef
->_options
= newOptions
;
595 if (CFEqual(oid
, kSecPolicyAppleSSL
)) {
596 SecPolicySetName(policyRef
, kSecPolicyNameSSLServer
);
597 /* Set EKU checks for servers */
598 CFMutableDictionaryRef newOptions
= CFDictionaryCreateMutableCopy(NULL
, 0, policyRef
->_options
);
599 set_ssl_ekus(newOptions
, true);
600 CFReleaseSafe(policyRef
->_options
);
601 policyRef
->_options
= newOptions
;
603 else if (CFEqual(oid
, kSecPolicyAppleIPsec
)) {
604 SecPolicySetName(policyRef
, kSecPolicyNameIPSecServer
);
606 else if (CFEqual(oid
, kSecPolicyAppleEAP
)) {
607 SecPolicySetName(policyRef
, kSecPolicyNameEAPServer
);
608 /* Set EKU checks for servers */
609 CFMutableDictionaryRef newOptions
= CFDictionaryCreateMutableCopy(NULL
, 0, policyRef
->_options
);
610 set_ssl_ekus(newOptions
, true);
611 CFReleaseSafe(policyRef
->_options
);
612 policyRef
->_options
= newOptions
;
618 set_ku_from_properties(policyRef
, properties
);
624 static xpc_object_t
copy_xpc_policy_object(SecPolicyRef policy
);
625 static bool append_policy_to_xpc_array(SecPolicyRef policy
, xpc_object_t xpc_policies
);
626 extern xpc_object_t
copy_xpc_policies_array(CFArrayRef policies
);
627 extern OSStatus
validate_array_of_items(CFArrayRef array
, CFStringRef arrayItemType
, CFTypeID itemTypeID
, bool required
);
629 static xpc_object_t
copy_xpc_policy_object(SecPolicyRef policy
) {
630 xpc_object_t xpc_policy
= NULL
;
631 xpc_object_t data
[2] = { NULL
, NULL
};
632 if (policy
->_oid
&& (CFGetTypeID(policy
->_oid
) == CFStringGetTypeID()) &&
633 policy
->_name
&& (CFGetTypeID(policy
->_name
) == CFStringGetTypeID())) {
634 /* These should really be different elements of the xpc array. But
635 * SecPolicyCreateWithXPCObject previously checked the size via ==, which prevents
636 * us from appending new information while maintaining backward compatibility.
637 * Doing this makes the builders happy. */
638 CFMutableStringRef oidAndName
= NULL
;
639 oidAndName
= CFStringCreateMutableCopy(NULL
, 0, policy
->_oid
);
641 CFStringAppend(oidAndName
, CFSTR("++"));
642 CFStringAppend(oidAndName
, policy
->_name
);
643 data
[0] = _CFXPCCreateXPCObjectFromCFObject(oidAndName
);
644 CFReleaseNull(oidAndName
);
646 data
[0] = _CFXPCCreateXPCObjectFromCFObject(policy
->_oid
);
648 } else if (policy
->_oid
&& (CFGetTypeID(policy
->_oid
) == CFStringGetTypeID())) {
649 data
[0] = _CFXPCCreateXPCObjectFromCFObject(policy
->_oid
);
651 secerror("policy 0x%lX has no _oid", (uintptr_t)policy
);
653 if (policy
->_options
&& (CFGetTypeID(policy
->_options
) == CFDictionaryGetTypeID())) {
654 data
[1] = _CFXPCCreateXPCObjectFromCFObject(policy
->_options
);
656 secerror("policy 0x%lX has no _options", (uintptr_t)policy
);
658 xpc_policy
= xpc_array_create(data
, array_size(data
));
659 if (data
[0]) xpc_release(data
[0]);
660 if (data
[1]) xpc_release(data
[1]);
664 static bool append_policy_to_xpc_array(SecPolicyRef policy
, xpc_object_t xpc_policies
) {
668 xpc_object_t xpc_policy
= copy_xpc_policy_object(policy
);
672 xpc_array_append_value(xpc_policies
, xpc_policy
);
673 xpc_release(xpc_policy
);
677 xpc_object_t
copy_xpc_policies_array(CFArrayRef policies
) {
678 xpc_object_t xpc_policies
= xpc_array_create(NULL
, 0);
682 validate_array_of_items(policies
, CFSTR("policy"), SecPolicyGetTypeID(), true);
683 CFIndex ix
, count
= CFArrayGetCount(policies
);
684 for (ix
= 0; ix
< count
; ++ix
) {
685 SecPolicyRef policy
= (SecPolicyRef
) CFArrayGetValueAtIndex(policies
, ix
);
686 #if SECTRUST_VERBOSE_DEBUG
687 CFDictionaryRef props
= SecPolicyCopyProperties(policy
);
688 secerror("idx=%d of %d; policy=0x%lX properties=%@", (int)ix
, (int)count
, (uintptr_t)policy
, props
);
689 CFReleaseSafe(props
);
691 if (!append_policy_to_xpc_array(policy
, xpc_policies
)) {
692 xpc_release(xpc_policies
);
700 static xpc_object_t
SecPolicyCopyXPCObject(SecPolicyRef policy
, CFErrorRef
*error
) {
701 xpc_object_t xpc_policy
= NULL
;
702 xpc_object_t data
[2] = {};
703 CFMutableStringRef oidAndName
= NULL
;
704 oidAndName
= CFStringCreateMutableCopy(NULL
, 0, policy
->_oid
);
707 CFStringAppend(oidAndName
, CFSTR("++"));
708 CFStringAppend(oidAndName
, policy
->_name
);
711 require_action_quiet(data
[0] = _CFXPCCreateXPCObjectFromCFObject(oidAndName
), exit
,
712 SecError(errSecParam
, error
,
713 CFSTR("failed to create xpc_object from policy oid and name")));
715 require_action_quiet(data
[0] = _CFXPCCreateXPCObjectFromCFObject(policy
->_oid
), exit
,
716 SecError(errSecParam
, error
, CFSTR("failed to create xpc_object from policy oid")));
718 require_action_quiet(data
[1] = _CFXPCCreateXPCObjectFromCFObject(policy
->_options
), exit
,
719 SecError(errSecParam
, error
, CFSTR("failed to create xpc_object from policy options")));
720 require_action_quiet(xpc_policy
= xpc_array_create(data
, array_size(data
)), exit
,
721 SecError(errSecAllocate
, error
, CFSTR("failed to create xpc_array for policy")));
724 if (data
[0]) xpc_release(data
[0]);
725 if (data
[1]) xpc_release(data
[1]);
726 CFReleaseNull(oidAndName
);
730 static bool SecPolicyAppendToXPCArray(SecPolicyRef policy
, xpc_object_t policies
, CFErrorRef
*error
) {
734 xpc_object_t xpc_policy
= SecPolicyCopyXPCObject(policy
, error
);
738 xpc_array_append_value(policies
, xpc_policy
);
739 xpc_release(xpc_policy
);
743 xpc_object_t
SecPolicyArrayCopyXPCArray(CFArrayRef policies
, CFErrorRef
*error
) {
744 xpc_object_t xpc_policies
;
745 require_action_quiet(xpc_policies
= xpc_array_create(NULL
, 0), exit
,
746 SecError(errSecAllocate
, error
, CFSTR("failed to create xpc_array")));
747 CFIndex ix
, count
= CFArrayGetCount(policies
);
748 for (ix
= 0; ix
< count
; ++ix
) {
749 if (!SecPolicyAppendToXPCArray((SecPolicyRef
)CFArrayGetValueAtIndex(policies
, ix
), xpc_policies
, error
)) {
750 xpc_release(xpc_policies
);
758 static OSStatus
parseOidAndName(CFStringRef oidAndName
, CFStringRef
*oid
, CFStringRef
*name
) {
759 OSStatus result
= errSecSuccess
;
760 CFStringRef partial
= NULL
;
762 CFRange delimiter
= CFStringFind(oidAndName
, CFSTR("++"), 0);
763 if (delimiter
.length
!= 2) {
767 /* get first half: oid */
768 partial
= CFStringCreateWithSubstring(NULL
, oidAndName
, CFRangeMake(0, delimiter
.location
));
769 if (oid
) { *oid
= CFRetainSafe(partial
); }
770 CFReleaseNull(partial
);
772 /* get second half: name */
773 if (delimiter
.location
+ 2 >= CFStringGetLength(oidAndName
)) {
774 return errSecSuccess
; // name is optional
776 CFRange nameRange
= CFRangeMake(delimiter
.location
+2,
777 CFStringGetLength(oidAndName
) - delimiter
.location
- 2);
778 partial
= CFStringCreateWithSubstring(NULL
, oidAndName
, nameRange
);
779 if (name
) { *name
= CFRetainSafe(partial
); }
780 CFReleaseNull(partial
);
784 static SecPolicyRef
SecPolicyCreateWithXPCObject(xpc_object_t xpc_policy
, CFErrorRef
*error
) {
785 SecPolicyRef policy
= NULL
;
786 CFTypeRef oidAndName
= NULL
;
787 CFStringRef oid
= NULL
;
788 CFStringRef name
= NULL
;
789 CFTypeRef options
= NULL
;
791 require_action_quiet(xpc_policy
, exit
, SecError(errSecParam
, error
, CFSTR("policy xpc value is NULL")));
792 require_action_quiet(xpc_get_type(xpc_policy
) == XPC_TYPE_ARRAY
, exit
, SecError(errSecDecode
, error
, CFSTR("policy xpc value is not an array")));
793 require_action_quiet(xpc_array_get_count(xpc_policy
) >= 2, exit
, SecError(errSecDecode
, error
, CFSTR("policy xpc array count < 2")));
794 oidAndName
= _CFXPCCreateCFObjectFromXPCObject(xpc_array_get_value(xpc_policy
, 0));
795 require_action_quiet(isString(oidAndName
), exit
,
796 SecError(errSecParam
, error
, CFSTR("failed to convert xpc policy[0]=%@ to CFString"), oidAndName
));
797 options
= _CFXPCCreateCFObjectFromXPCObject(xpc_array_get_value(xpc_policy
, 1));
798 require_action_quiet(isDictionary(options
), exit
,
799 SecError(errSecParam
, error
, CFSTR("failed to convert xpc policy[1]=%@ to CFDictionary"), options
));
800 require_noerr_action_quiet(parseOidAndName(oidAndName
, &oid
, &name
), exit
,
801 SecError(errSecParam
, error
, CFSTR("failed to convert combined %@ to name and oid"), oidAndName
));
802 require_action_quiet(policy
= SecPolicyCreate(oid
, name
, options
), exit
,
803 SecError(errSecDecode
, error
, CFSTR("Failed to create policy")));
806 CFReleaseSafe(oidAndName
);
809 CFReleaseSafe(options
);
813 CFArrayRef
SecPolicyXPCArrayCopyArray(xpc_object_t xpc_policies
, CFErrorRef
*error
) {
814 CFMutableArrayRef policies
= NULL
;
815 require_action_quiet(xpc_get_type(xpc_policies
) == XPC_TYPE_ARRAY
, exit
,
816 SecError(errSecParam
, error
, CFSTR("policies xpc value is not an array")));
817 size_t count
= xpc_array_get_count(xpc_policies
);
818 require_action_quiet(policies
= CFArrayCreateMutable(kCFAllocatorDefault
, count
, &kCFTypeArrayCallBacks
), exit
,
819 SecError(errSecAllocate
, error
, CFSTR("failed to create CFArray of capacity %zu"), count
));
822 for (ix
= 0; ix
< count
; ++ix
) {
823 SecPolicyRef policy
= SecPolicyCreateWithXPCObject(xpc_array_get_value(xpc_policies
, ix
), error
);
828 CFArraySetValueAtIndex(policies
, ix
, policy
);
837 static SEC_CONST_DECL (kSecPolicyOptions
, "policyOptions");
839 static SecPolicyRef
SecPolicyCreateWithDictionary(CFDictionaryRef dict
) {
840 SecPolicyRef policy
= NULL
;
841 CFStringRef oid
= (CFStringRef
)CFDictionaryGetValue(dict
, kSecPolicyOid
);
842 require_quiet(isString(oid
), errOut
);
843 CFDictionaryRef options
= (CFDictionaryRef
)CFDictionaryGetValue(dict
, kSecPolicyOptions
);
844 require_quiet(isDictionary(options
), errOut
);
845 CFStringRef name
= (CFStringRef
)CFDictionaryGetValue(dict
, kSecPolicyPolicyName
);
846 policy
= SecPolicyCreate(oid
, name
, options
);
851 static void deserializePolicy(const void *value
, void *context
) {
852 CFDictionaryRef policyDict
= (CFDictionaryRef
)value
;
853 if (isDictionary(policyDict
)) {
854 CFTypeRef deserializedPolicy
= SecPolicyCreateWithDictionary(policyDict
);
855 if (deserializedPolicy
) {
856 CFArrayAppendValue((CFMutableArrayRef
)context
, deserializedPolicy
);
857 CFRelease(deserializedPolicy
);
862 CFArrayRef
SecPolicyArrayCreateDeserialized(CFArrayRef serializedPolicies
) {
863 CFMutableArrayRef result
= NULL
;
864 require_quiet(isArray(serializedPolicies
), errOut
);
865 CFIndex count
= CFArrayGetCount(serializedPolicies
);
866 result
= CFArrayCreateMutable(kCFAllocatorDefault
, count
, &kCFTypeArrayCallBacks
);
867 CFRange all_policies
= { 0, count
};
868 CFArrayApplyFunction(serializedPolicies
, all_policies
, deserializePolicy
, result
);
873 static CFDictionaryRef
SecPolicyCreateDictionary(SecPolicyRef policy
) {
874 CFMutableDictionaryRef dict
= NULL
;
875 dict
= CFDictionaryCreateMutable(NULL
, 3, &kCFTypeDictionaryKeyCallBacks
,
876 &kCFTypeDictionaryValueCallBacks
);
877 CFDictionaryAddValue(dict
, kSecPolicyOid
, policy
->_oid
);
878 CFDictionaryAddValue(dict
, kSecPolicyOptions
, policy
->_options
);
880 CFDictionaryAddValue(dict
, kSecPolicyPolicyName
, policy
->_name
);
885 static void serializePolicy(const void *value
, void *context
) {
886 SecPolicyRef policy
= (SecPolicyRef
)value
;
887 if (policy
&& SecPolicyGetTypeID() == CFGetTypeID(policy
)) {
888 CFDictionaryRef serializedPolicy
= SecPolicyCreateDictionary(policy
);
889 if (serializedPolicy
) {
890 CFArrayAppendValue((CFMutableArrayRef
)context
, serializedPolicy
);
891 CFRelease(serializedPolicy
);
896 CFArrayRef
SecPolicyArrayCreateSerialized(CFArrayRef policies
) {
897 CFMutableArrayRef result
= NULL
;
898 require_quiet(isArray(policies
), errOut
);
899 CFIndex count
= CFArrayGetCount(policies
);
900 result
= CFArrayCreateMutable(NULL
, count
, &kCFTypeArrayCallBacks
);
901 CFRange all_policies
= { 0, count
};
902 CFArrayApplyFunction(policies
, all_policies
, serializePolicy
, result
);
907 static void add_element(CFMutableDictionaryRef options
, CFStringRef key
,
909 CFTypeRef old_value
= CFDictionaryGetValue(options
, key
);
911 CFMutableArrayRef array
;
912 if (CFGetTypeID(old_value
) == CFArrayGetTypeID()) {
913 array
= (CFMutableArrayRef
)old_value
;
915 array
= CFArrayCreateMutable(kCFAllocatorDefault
, 0,
916 &kCFTypeArrayCallBacks
);
917 CFArrayAppendValue(array
, old_value
);
918 CFDictionarySetValue(options
, key
, array
);
921 CFArrayAppendValue(array
, value
);
923 CFDictionaryAddValue(options
, key
, value
);
927 static void add_eku(CFMutableDictionaryRef options
, const DERItem
*ekuOid
) {
928 CFDataRef eku
= CFDataCreate(kCFAllocatorDefault
,
929 ekuOid
? ekuOid
->data
: NULL
,
930 ekuOid
? ekuOid
->length
: 0);
932 add_element(options
, kSecPolicyCheckExtendedKeyUsage
, eku
);
937 static void add_eku_string(CFMutableDictionaryRef options
, CFStringRef ekuOid
) {
939 add_element(options
, kSecPolicyCheckExtendedKeyUsage
, ekuOid
);
943 static void set_ssl_ekus(CFMutableDictionaryRef options
, bool server
) {
944 CFDictionaryRemoveValue(options
, kSecPolicyCheckExtendedKeyUsage
);
946 /* If server and EKU ext present then EKU ext should contain one of
947 ServerAuth or ExtendedKeyUsageAny or NetscapeSGC or MicrosoftSGC.
948 else if !server and EKU ext present then EKU ext should contain one of
949 ClientAuth or ExtendedKeyUsageAny. */
951 /* We always allow certificates that specify oidAnyExtendedKeyUsage. */
952 add_eku(options
, NULL
); /* eku extension is optional */
953 add_eku(options
, &oidAnyExtendedKeyUsage
);
955 add_eku(options
, &oidExtendedKeyUsageServerAuth
);
956 add_eku(options
, &oidExtendedKeyUsageMicrosoftSGC
);
957 add_eku(options
, &oidExtendedKeyUsageNetscapeSGC
);
959 add_eku(options
, &oidExtendedKeyUsageClientAuth
);
963 static void add_ku(CFMutableDictionaryRef options
, SecKeyUsage keyUsage
) {
964 SInt32 dku
= keyUsage
;
965 CFNumberRef ku
= CFNumberCreate(kCFAllocatorDefault
, kCFNumberSInt32Type
,
968 add_element(options
, kSecPolicyCheckKeyUsage
, ku
);
974 static void set_ku_from_properties(SecPolicyRef policy
, CFDictionaryRef properties
) {
975 if (!policy
|| !properties
) {
979 CFStringRef keyNames
[] = { kSecPolicyKU_DigitalSignature
, kSecPolicyKU_NonRepudiation
, kSecPolicyKU_KeyEncipherment
, kSecPolicyKU_DataEncipherment
,
980 kSecPolicyKU_KeyAgreement
, kSecPolicyKU_KeyCertSign
, kSecPolicyKU_CRLSign
, kSecPolicyKU_EncipherOnly
, kSecPolicyKU_DecipherOnly
};
982 uint32_t keyUsageValues
[] = { kSecKeyUsageDigitalSignature
, kSecKeyUsageNonRepudiation
, kSecKeyUsageKeyEncipherment
, kSecKeyUsageDataEncipherment
,
983 kSecKeyUsageKeyAgreement
, kSecKeyUsageKeyCertSign
, kSecKeyUsageCRLSign
, kSecKeyUsageEncipherOnly
, kSecKeyUsageDecipherOnly
};
985 bool haveKeyUsage
= false;
986 CFTypeRef keyUsageBoolean
;
987 for (uint32_t i
= 0; i
< sizeof(keyNames
) / sizeof(CFStringRef
); ++i
) {
988 if (CFDictionaryGetValueIfPresent(properties
, keyNames
[i
], (const void**)&keyUsageBoolean
)) {
989 if (CFEqual(keyUsageBoolean
, kCFBooleanTrue
)) {
1000 CFMutableDictionaryRef options
= (CFMutableDictionaryRef
) policy
->_options
;
1002 options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1003 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
1004 if (!options
) return;
1005 policy
->_options
= options
;
1007 CFDictionaryRemoveValue(options
, kSecPolicyCheckKeyUsage
);
1010 for (uint32_t i
= 0; i
< sizeof(keyNames
) / sizeof(CFStringRef
); ++i
) {
1011 if (CFDictionaryGetValueIfPresent(properties
, keyNames
[i
], (const void**)&keyUsageBoolean
)) {
1012 if (CFEqual(keyUsageBoolean
, kCFBooleanTrue
)) {
1013 add_ku(options
, keyUsageValues
[i
]);
1020 static void add_oid(CFMutableDictionaryRef options
, CFStringRef policy_key
, const DERItem
*oid
) {
1021 CFDataRef oid_data
= CFDataCreate(kCFAllocatorDefault
,
1022 oid
? oid
->data
: NULL
,
1023 oid
? oid
->length
: 0);
1025 add_element(options
, policy_key
, oid_data
);
1026 CFRelease(oid_data
);
1030 static void add_leaf_marker_value(CFMutableDictionaryRef options
, const DERItem
*markerOid
, CFStringRef string_value
) {
1032 CFTypeRef policyData
= NULL
;
1034 if (NULL
== string_value
) {
1035 policyData
= CFDataCreate(kCFAllocatorDefault
,
1036 markerOid
? markerOid
->data
: NULL
,
1037 markerOid
? markerOid
->length
: 0);
1039 CFStringRef oid_as_string
= SecDERItemCopyOIDDecimalRepresentation(kCFAllocatorDefault
, markerOid
);
1041 const void *key
[1] = { oid_as_string
};
1042 const void *value
[1] = { string_value
};
1043 policyData
= CFDictionaryCreate(kCFAllocatorDefault
,
1045 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
1046 CFReleaseNull(oid_as_string
);
1049 add_element(options
, kSecPolicyCheckLeafMarkerOid
, policyData
);
1051 CFReleaseNull(policyData
);
1055 static void add_leaf_marker(CFMutableDictionaryRef options
, const DERItem
*markerOid
) {
1056 add_leaf_marker_value(options
, markerOid
, NULL
);
1059 static void add_leaf_marker_value_string(CFMutableDictionaryRef options
, CFStringRef markerOid
, CFStringRef string_value
) {
1060 if (NULL
== string_value
) {
1061 add_element(options
, kSecPolicyCheckLeafMarkerOid
, markerOid
);
1063 CFDictionaryRef policyData
= NULL
;
1064 const void *key
[1] = { markerOid
};
1065 const void *value
[1] = { string_value
};
1066 policyData
= CFDictionaryCreate(kCFAllocatorDefault
,
1068 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
1069 add_element(options
, kSecPolicyCheckLeafMarkerOid
, policyData
);
1071 CFReleaseNull(policyData
);
1075 static void add_leaf_marker_string(CFMutableDictionaryRef options
, CFStringRef markerOid
) {
1076 add_leaf_marker_value_string(options
, markerOid
, NULL
);
1079 static void add_leaf_prod_qa_element(CFMutableDictionaryRef options
, CFTypeRef prodValue
, CFTypeRef qaValue
)
1081 CFMutableDictionaryRef prodAndQADictionary
= CFDictionaryCreateMutable(NULL
, 0, &kCFTypeDictionaryKeyCallBacks
,
1082 &kCFTypeDictionaryValueCallBacks
);
1083 CFDictionaryRef old_value
= CFDictionaryGetValue(options
, kSecPolicyCheckLeafMarkersProdAndQA
);
1085 CFMutableArrayRef prodArray
= NULL
, qaArray
= NULL
;
1086 CFTypeRef old_prod_value
= CFDictionaryGetValue(old_value
, kSecPolicyLeafMarkerProd
);
1087 CFTypeRef old_qa_value
= CFDictionaryGetValue(old_value
, kSecPolicyLeafMarkerQA
);
1088 if (isArray(old_prod_value
) && isArray(old_qa_value
)) {
1089 prodArray
= (CFMutableArrayRef
)CFRetainSafe(old_prod_value
);
1090 qaArray
= (CFMutableArrayRef
)CFRetainSafe(old_qa_value
);
1092 prodArray
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
1093 qaArray
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
1094 CFArrayAppendValue(prodArray
, old_prod_value
);
1095 CFArrayAppendValue(qaArray
, old_qa_value
);
1097 CFArrayAppendValue(prodArray
, prodValue
);
1098 CFArrayAppendValue(qaArray
, qaValue
);
1099 CFDictionaryAddValue(prodAndQADictionary
, kSecPolicyLeafMarkerProd
, prodArray
);
1100 CFDictionaryAddValue(prodAndQADictionary
, kSecPolicyLeafMarkerQA
, qaArray
);
1101 CFReleaseNull(prodArray
);
1102 CFReleaseNull(qaArray
);
1105 CFDictionaryAddValue(prodAndQADictionary
, kSecPolicyLeafMarkerProd
, prodValue
);
1106 CFDictionaryAddValue(prodAndQADictionary
, kSecPolicyLeafMarkerQA
, qaValue
);
1108 CFDictionarySetValue(options
, kSecPolicyCheckLeafMarkersProdAndQA
, prodAndQADictionary
);
1109 CFReleaseNull(prodAndQADictionary
);
1113 static void add_leaf_prod_qa_markers(CFMutableDictionaryRef options
, const DERItem
*prodMarkerOid
, const DERItem
*qaMarkerOid
)
1115 CFDataRef prodData
= NULL
, qaData
= NULL
;
1116 prodData
= CFDataCreate(NULL
, prodMarkerOid
? prodMarkerOid
->data
: NULL
,
1117 prodMarkerOid
? prodMarkerOid
->length
: 0);
1118 qaData
= CFDataCreate(NULL
, qaMarkerOid
? qaMarkerOid
->data
: NULL
,
1119 qaMarkerOid
? qaMarkerOid
->length
: 0);
1120 add_leaf_prod_qa_element(options
, prodData
, qaData
);
1121 CFReleaseNull(prodData
);
1122 CFReleaseNull(qaData
);
1125 static void add_leaf_prod_qa_markers_string(CFMutableDictionaryRef options
, CFStringRef prodMarkerOid
, CFStringRef qaMarkerOid
)
1127 add_leaf_prod_qa_element(options
, prodMarkerOid
, qaMarkerOid
);
1130 static void add_leaf_prod_qa_markers_value_string(CFMutableDictionaryRef options
,
1131 CFStringRef prodMarkerOid
, CFStringRef prod_value
,
1132 CFStringRef qaMarkerOid
, CFStringRef qa_value
)
1134 if (!prod_value
&& !qa_value
) {
1135 add_leaf_prod_qa_element(options
, prodMarkerOid
, qaMarkerOid
);
1137 CFDictionaryRef prodData
= NULL
, qaData
= NULL
;
1138 const void *prodKey
[1] = { prodMarkerOid
}, *qaKey
[1] = { qaMarkerOid
};
1139 const void *prodValue
[1] = { prod_value
}, *qaValue
[1] = { qa_value
};
1140 prodData
= CFDictionaryCreate(NULL
, prodKey
, prodValue
, 1, &kCFTypeDictionaryKeyCallBacks
,
1141 &kCFTypeDictionaryValueCallBacks
);
1142 qaData
= CFDictionaryCreate(NULL
, qaKey
, qaValue
, 1, &kCFTypeDictionaryKeyCallBacks
,
1143 &kCFTypeDictionaryValueCallBacks
);
1144 add_leaf_prod_qa_element(options
, prodData
, qaData
);
1145 CFReleaseNull(prodData
);
1146 CFReleaseNull(qaData
);
1150 static void add_intermediate_marker_value_string(CFMutableDictionaryRef options
, CFStringRef markerOid
, CFStringRef string_value
) {
1151 if (NULL
== string_value
) {
1152 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, markerOid
);
1154 CFDictionaryRef policyData
= NULL
;
1155 const void *key
[1] = { markerOid
};
1156 const void *value
[1] = { string_value
};
1157 policyData
= CFDictionaryCreate(kCFAllocatorDefault
,
1159 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
1160 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, policyData
);
1162 CFReleaseNull(policyData
);
1166 static void add_certificate_policy_oid(CFMutableDictionaryRef options
, const DERItem
*certificatePolicyOid
) {
1167 CFTypeRef certificatePolicyData
= NULL
;
1168 certificatePolicyData
= CFDataCreate(kCFAllocatorDefault
,
1169 certificatePolicyOid
? certificatePolicyOid
->data
: NULL
,
1170 certificatePolicyOid
? certificatePolicyOid
->length
: 0);
1171 if (certificatePolicyData
) {
1172 add_element(options
, kSecPolicyCheckCertificatePolicy
, certificatePolicyData
);
1173 CFRelease(certificatePolicyData
);
1177 static void add_certificate_policy_oid_string(CFMutableDictionaryRef options
, CFStringRef certificatePolicyOid
) {
1178 if (certificatePolicyOid
) {
1179 add_element(options
, kSecPolicyCheckCertificatePolicy
, certificatePolicyOid
);
1184 // Routines for adding dictionary entries for policies.
1187 // X.509, but missing validity requirements.
1188 static void SecPolicyAddBasicCertOptions(CFMutableDictionaryRef options
)
1190 //CFDictionaryAddValue(options, kSecPolicyCheckBasicCertificateProcessing, kCFBooleanTrue);
1191 // Happens automatically in SecPVCPathChecks
1192 CFDictionaryAddValue(options
, kSecPolicyCheckCriticalExtensions
, kCFBooleanTrue
);
1193 CFDictionaryAddValue(options
, kSecPolicyCheckIdLinkage
, kCFBooleanTrue
);
1194 CFDictionaryAddValue(options
, kSecPolicyCheckBasicConstraints
, kCFBooleanTrue
);
1195 CFDictionaryAddValue(options
, kSecPolicyCheckNonEmptySubject
, kCFBooleanTrue
);
1196 CFDictionaryAddValue(options
, kSecPolicyCheckWeakKeySize
, kCFBooleanTrue
);
1197 CFDictionaryAddValue(options
, kSecPolicyCheckWeakSignature
, kCFBooleanTrue
);
1200 static void SecPolicyAddBasicX509Options(CFMutableDictionaryRef options
)
1202 SecPolicyAddBasicCertOptions(options
);
1203 CFDictionaryAddValue(options
, kSecPolicyCheckTemporalValidity
, kCFBooleanTrue
);
1205 // Make sure that black and gray leaf checks are performed for basic X509 chain building
1206 CFDictionaryAddValue(options
, kSecPolicyCheckBlackListedLeaf
, kCFBooleanTrue
);
1207 CFDictionaryAddValue(options
, kSecPolicyCheckGrayListedLeaf
, kCFBooleanTrue
);
1210 static bool SecPolicyAddChainLengthOptions(CFMutableDictionaryRef options
, CFIndex length
)
1212 bool result
= false;
1213 CFNumberRef lengthAsCF
= NULL
;
1215 require(lengthAsCF
= CFNumberCreate(kCFAllocatorDefault
,
1216 kCFNumberCFIndexType
, &length
), errOut
);
1217 CFDictionaryAddValue(options
, kSecPolicyCheckChainLength
, lengthAsCF
);
1222 CFReleaseSafe(lengthAsCF
);
1226 static bool SecPolicyAddAnchorSHA1Options(CFMutableDictionaryRef options
,
1227 const UInt8 anchorSha1
[kSecPolicySHA1Size
])
1229 bool success
= false;
1230 CFDataRef anchorData
= NULL
;
1232 require(anchorData
= CFDataCreate(kCFAllocatorDefault
, anchorSha1
, kSecPolicySHA1Size
), errOut
);
1233 add_element(options
, kSecPolicyCheckAnchorSHA1
, anchorData
);
1238 CFReleaseSafe(anchorData
);
1242 static bool SecPolicyAddAnchorSHA256Options(CFMutableDictionaryRef options
,
1243 const UInt8 anchorSha1
[kSecPolicySHA256Size
])
1245 bool success
= false;
1246 CFDataRef anchorData
= NULL
;
1248 require(anchorData
= CFDataCreate(kCFAllocatorDefault
, anchorSha1
, kSecPolicySHA256Size
), errOut
);
1249 add_element(options
, kSecPolicyCheckAnchorSHA256
, anchorData
);
1254 CFReleaseSafe(anchorData
);
1258 static bool SecPolicyAddStrongKeySizeOptions(CFMutableDictionaryRef options
) {
1259 bool success
= false;
1260 CFDictionaryRef keySizes
= NULL
;
1261 CFNumberRef rsaSize
= NULL
, ecSize
= NULL
;
1263 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
1264 require(rsaSize
= CFNumberCreateWithCFIndex(NULL
, 2048), errOut
);
1265 require(ecSize
= CFNumberCreateWithCFIndex(NULL
, 256), errOut
);
1266 const void *keys
[] = { kSecAttrKeyTypeRSA
, kSecAttrKeyTypeEC
};
1267 const void *values
[] = { rsaSize
, ecSize
};
1268 require(keySizes
= CFDictionaryCreate(NULL
, keys
, values
, 2,
1269 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1270 add_element(options
, kSecPolicyCheckKeySize
, keySizes
);
1275 CFReleaseSafe(keySizes
);
1276 CFReleaseSafe(rsaSize
);
1277 CFReleaseSafe(ecSize
);
1281 static bool SecPolicyRemoveWeakHashOptions(CFMutableDictionaryRef options
) {
1282 CFMutableArrayRef disallowedHashes
= CFArrayCreateMutable(NULL
, 5, &kCFTypeArrayCallBacks
);
1283 if (!disallowedHashes
) {
1286 CFArrayAppendValue(disallowedHashes
, kSecSignatureDigestAlgorithmMD2
);
1287 CFArrayAppendValue(disallowedHashes
, kSecSignatureDigestAlgorithmMD4
);
1288 CFArrayAppendValue(disallowedHashes
, kSecSignatureDigestAlgorithmMD5
);
1289 CFArrayAppendValue(disallowedHashes
, kSecSignatureDigestAlgorithmSHA1
);
1291 add_element(options
, kSecPolicyCheckSignatureHashAlgorithms
, disallowedHashes
);
1292 CFReleaseNull(disallowedHashes
);
1296 static bool isAppleOid(CFStringRef oid
) {
1297 if (!SecCertificateIsOidString(oid
)) {
1300 if (CFStringHasPrefix(oid
, CFSTR("1.2.840.113635"))) {
1306 static bool isCFPreferenceInSecurityDomain(CFStringRef setting
) {
1307 return (CFPreferencesGetAppBooleanValue(setting
, CFSTR("com.apple.security"), NULL
));
1310 static bool SecPolicyAddAppleAnchorOptions(CFMutableDictionaryRef options
, CFStringRef __unused policyName
)
1312 CFMutableDictionaryRef appleAnchorOptions
= NULL
;
1313 appleAnchorOptions
= CFDictionaryCreateMutableForCFTypes(NULL
);
1314 if (!appleAnchorOptions
) {
1318 /* Currently no Apple Anchor options */
1319 add_element(options
, kSecPolicyCheckAnchorApple
, appleAnchorOptions
);
1320 CFReleaseSafe(appleAnchorOptions
);
1324 static bool SecPolicyAddPinningRequiredIfInfoSpecified(CFMutableDictionaryRef options
)
1326 CFBundleRef bundle
= CFBundleGetMainBundle();
1328 CFTypeRef value
= CFBundleGetValueForInfoDictionaryKey(bundle
, CFSTR("SecTrustPinningRequired"));
1329 if (isBoolean(value
) && CFBooleanGetValue(value
)) {
1330 add_element(options
, kSecPolicyCheckPinningRequired
, kCFBooleanTrue
);
1339 // MARK: Policy Creation Functions
1341 SecPolicyRef
SecPolicyCreateBasicX509(void) {
1342 CFMutableDictionaryRef options
= NULL
;
1343 SecPolicyRef result
= NULL
;
1345 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1346 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1348 SecPolicyAddBasicX509Options(options
);
1349 CFDictionaryAddValue(options
, kSecPolicyCheckNoNetworkAccess
,
1352 require(result
= SecPolicyCreate(kSecPolicyAppleX509Basic
, kSecPolicyNameX509Basic
, options
), errOut
);
1355 CFReleaseSafe(options
);
1356 return (SecPolicyRef _Nonnull
)result
;
1359 SecPolicyRef
SecPolicyCreateSSL(Boolean server
, CFStringRef hostname
) {
1360 CFMutableDictionaryRef options
= NULL
;
1361 SecPolicyRef result
= NULL
;
1363 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1364 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1366 SecPolicyAddBasicX509Options(options
);
1369 CFDictionaryAddValue(options
, kSecPolicyCheckSSLHostname
, hostname
);
1372 CFDictionaryAddValue(options
, kSecPolicyCheckBlackListedLeaf
, kCFBooleanTrue
);
1373 CFDictionaryAddValue(options
, kSecPolicyCheckGrayListedLeaf
, kCFBooleanTrue
);
1376 require_quiet(SecPolicyRemoveWeakHashOptions(options
), errOut
);
1377 require_quiet(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
1378 require_quiet(SecPolicyAddPinningRequiredIfInfoSpecified(options
), errOut
);
1379 CFDictionaryAddValue(options
, kSecPolicyCheckValidityPeriodMaximums
, kCFBooleanTrue
);
1380 CFDictionaryAddValue(options
, kSecPolicyCheckServerAuthEKU
, kCFBooleanTrue
); // enforces stricter EKU rules than set_ssl_ekus below for certain anchor types
1381 #if !TARGET_OS_BRIDGE
1382 CFDictionaryAddValue(options
, kSecPolicyCheckSystemTrustedCTRequired
, kCFBooleanTrue
);
1386 set_ssl_ekus(options
, server
);
1388 require(result
= SecPolicyCreate(kSecPolicyAppleSSL
,
1389 server
? kSecPolicyNameSSLServer
: kSecPolicyNameSSLClient
,
1393 CFReleaseSafe(options
);
1394 return (SecPolicyRef _Nonnull
)result
;
1397 SecPolicyRef
SecPolicyCreateLegacySSL(Boolean server
, CFStringRef hostname
) {
1398 CFMutableDictionaryRef options
= NULL
;
1399 SecPolicyRef result
= NULL
;
1401 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1402 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1404 SecPolicyAddBasicX509Options(options
);
1407 CFDictionaryAddValue(options
, kSecPolicyCheckSSLHostname
, hostname
);
1410 CFDictionaryAddValue(options
, kSecPolicyCheckBlackListedLeaf
, kCFBooleanTrue
);
1411 CFDictionaryAddValue(options
, kSecPolicyCheckGrayListedLeaf
, kCFBooleanTrue
);
1414 // fewer requirements than the standard SSL policy
1415 require_quiet(SecPolicyAddPinningRequiredIfInfoSpecified(options
), errOut
);
1416 CFDictionaryAddValue(options
, kSecPolicyCheckValidityPeriodMaximums
, kCFBooleanTrue
);
1417 #if !TARGET_OS_BRIDGE
1418 CFDictionaryAddValue(options
, kSecPolicyCheckSystemTrustedCTRequired
, kCFBooleanTrue
);
1422 set_ssl_ekus(options
, server
);
1424 require(result
= SecPolicyCreate(kSecPolicyAppleLegacySSL
, kSecPolicyNameLegacySSL
, options
), errOut
);
1427 CFReleaseSafe(options
);
1428 return (SecPolicyRef _Nonnull
)result
;
1431 SecPolicyRef
SecPolicyCreateApplePinned(CFStringRef policyName
, CFStringRef intermediateMarkerOID
, CFStringRef leafMarkerOID
) {
1432 CFMutableDictionaryRef options
= NULL
;
1433 SecPolicyRef result
= NULL
;
1435 if (!policyName
|| !intermediateMarkerOID
|| !leafMarkerOID
) {
1439 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1440 &kCFTypeDictionaryKeyCallBacks
,
1441 &kCFTypeDictionaryValueCallBacks
), errOut
);
1443 SecPolicyAddBasicX509Options(options
);
1445 /* Anchored to the Apple Roots */
1446 require(SecPolicyAddAppleAnchorOptions(options
, policyName
), errOut
);
1448 /* Exactly 3 certs in the chain */
1449 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1451 /* Intermediate marker OID matches input OID */
1452 if (!isAppleOid(intermediateMarkerOID
)) {
1453 secwarning("creating an Apple pinning policy with a non-Apple OID: %@", intermediateMarkerOID
);
1455 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, intermediateMarkerOID
);
1457 /* Leaf marker OID matches input OID */
1458 if (!isAppleOid(leafMarkerOID
)) {
1459 secwarning("creating an Apple pinning policy with a non-Apple OID: %@", leafMarkerOID
);
1461 add_leaf_marker_string(options
, leafMarkerOID
);
1463 /* Check revocation using any available method */
1464 add_element(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
1466 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
1467 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
1469 /* Check for weak hashes */
1470 // require(SecPolicyRemoveWeakHashOptions(options), errOut); // the current WWDR CA cert is signed with SHA1
1471 require(result
= SecPolicyCreate(kSecPolicyAppleGenericApplePinned
,
1472 policyName
, options
), errOut
);
1475 CFReleaseSafe(options
);
1480 requireUATPinning(CFStringRef service
)
1482 bool pinningRequired
= true;
1484 if (SecIsInternalRelease()) {
1485 CFStringRef setting
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("AppleServerAuthenticationNoPinning%@"), service
);
1486 require(setting
, fail
);
1487 if(isCFPreferenceInSecurityDomain(setting
)) {
1488 pinningRequired
= false;
1490 secnotice("pinningQA", "could not disable pinning: %@ not true", setting
);
1494 if (!pinningRequired
) {
1498 if(isCFPreferenceInSecurityDomain(CFSTR("AppleServerAuthenticationNoPinning"))) {
1499 pinningRequired
= false;
1501 secnotice("pinningQA", "could not disable pinning: AppleServerAuthenticationNoPinning not true");
1504 secnotice("pinningQA", "could not disable pinning: not an internal release");
1507 return pinningRequired
;
1510 SecPolicyRef
SecPolicyCreateAppleSSLPinned(CFStringRef policyName
, CFStringRef hostname
,
1511 CFStringRef intermediateMarkerOID
, CFStringRef leafMarkerOID
) {
1512 CFMutableDictionaryRef options
= NULL
, appleAnchorOptions
= NULL
;
1513 SecPolicyRef result
= NULL
;
1515 if (!policyName
|| !hostname
|| !leafMarkerOID
) {
1519 if (requireUATPinning(policyName
)) {
1520 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1521 &kCFTypeDictionaryKeyCallBacks
,
1522 &kCFTypeDictionaryValueCallBacks
), errOut
);
1524 SecPolicyAddBasicX509Options(options
);
1526 /* Anchored to the Apple Roots */
1527 require(SecPolicyAddAppleAnchorOptions(options
, policyName
), errOut
);
1529 /* Exactly 3 certs in the chain */
1530 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1532 if (intermediateMarkerOID
) {
1533 /* Intermediate marker OID matches input OID */
1534 if (!isAppleOid(intermediateMarkerOID
)) {
1535 secwarning("creating an Apple pinning policy with a non-Apple OID: %@", intermediateMarkerOID
);
1537 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, intermediateMarkerOID
);
1539 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.12"));
1542 /* Leaf marker OID matches input OID */
1543 if (!isAppleOid(leafMarkerOID
)) {
1544 secwarning("creating an Apple pinning policy with a non-Apple OID: %@", leafMarkerOID
);
1546 add_leaf_marker_string(options
, leafMarkerOID
);
1548 /* New leaf marker OID format */
1549 add_leaf_marker_value_string(options
, CFSTR("1.2.840.113635.100.6.48.1"), leafMarkerOID
);
1551 /* ServerAuth EKU is in leaf cert */
1552 add_eku_string(options
, CFSTR("1.3.6.1.5.5.7.3.1"));
1554 /* Hostname is in leaf cert */
1555 add_element(options
, kSecPolicyCheckSSLHostname
, hostname
);
1557 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
1558 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
1560 /* Check for weak hashes */
1561 require(SecPolicyRemoveWeakHashOptions(options
), errOut
);
1563 /* Check revocation using any available method */
1564 add_element(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
1566 require(result
= SecPolicyCreate(kSecPolicyAppleGenericAppleSSLPinned
,
1567 policyName
, options
), errOut
);
1570 result
= SecPolicyCreateSSL(true, hostname
);
1571 SecPolicySetOid(result
, kSecPolicyAppleGenericAppleSSLPinned
);
1572 SecPolicySetName(result
, policyName
);
1576 CFReleaseSafe(options
);
1577 CFReleaseSafe(appleAnchorOptions
);
1581 SecPolicyRef
SecPolicyCreateiPhoneActivation(void) {
1582 CFMutableDictionaryRef options
= NULL
;
1583 SecPolicyRef result
= NULL
;
1585 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1586 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1588 SecPolicyAddBasicCertOptions(options
);
1591 CFDictionaryAddValue(options
, kSecPolicyCheckKeyUsage
,
1593 CFDictionaryAddValue(options
, kSecPolicyCheckExtendedKeyUsage
,
1597 /* Basic X.509 policy with the additional requirements that the chain
1598 length is 3, it's anchored at the AppleCA and the leaf certificate
1599 has issuer "Apple iPhone Certification Authority" and
1600 subject "Apple iPhone Activation" for the common name. */
1601 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
1602 CFSTR("Apple iPhone Certification Authority"));
1603 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
,
1604 CFSTR("Apple iPhone Activation"));
1606 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1607 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameiPhoneActivation
), errOut
);
1609 require(result
= SecPolicyCreate(kSecPolicyAppleiPhoneActivation
,
1610 kSecPolicyNameiPhoneActivation
, options
),
1614 CFReleaseSafe(options
);
1618 SecPolicyRef
SecPolicyCreateiPhoneDeviceCertificate(void) {
1619 CFMutableDictionaryRef options
= NULL
;
1620 SecPolicyRef result
= NULL
;
1622 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1623 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1625 SecPolicyAddBasicCertOptions(options
);
1628 CFDictionaryAddValue(options
, kSecPolicyCheckKeyUsage
,
1630 CFDictionaryAddValue(options
, kSecPolicyCheckExtendedKeyUsage
,
1634 /* Basic X.509 policy with the additional requirements that the chain
1635 length is 4, it's anchored at the AppleCA and the first intermediate
1636 has the subject "Apple iPhone Device CA". */
1637 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
1638 CFSTR("Apple iPhone Device CA"));
1640 require(SecPolicyAddChainLengthOptions(options
, 4), errOut
);
1641 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameiPhoneDeviceCertificate
), errOut
);
1643 require(result
= SecPolicyCreate(kSecPolicyAppleiPhoneDeviceCertificate
,
1644 kSecPolicyNameiPhoneDeviceCertificate
, options
),
1648 CFReleaseSafe(options
);
1652 SecPolicyRef
SecPolicyCreateFactoryDeviceCertificate(void) {
1653 CFMutableDictionaryRef options
= NULL
;
1654 SecPolicyRef result
= NULL
;
1656 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1657 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1659 SecPolicyAddBasicCertOptions(options
);
1662 CFDictionaryAddValue(options
, kSecPolicyCheckKeyUsage
,
1664 CFDictionaryAddValue(options
, kSecPolicyCheckExtendedKeyUsage
,
1668 /* Basic X.509 policy with the additional requirements that the chain
1669 is anchored at the factory device certificate issuer. */
1670 require(SecPolicyAddAnchorSHA1Options(options
, kFactoryDeviceCASHA1
), errOut
);
1672 require(result
= SecPolicyCreate(kSecPolicyAppleFactoryDeviceCertificate
,
1673 kSecPolicyNameFactoryDeviceCertificate
, options
),
1677 CFReleaseSafe(options
);
1681 SecPolicyRef
SecPolicyCreateiAP(void) {
1682 CFMutableDictionaryRef options
= NULL
;
1683 SecPolicyRef result
= NULL
;
1684 CFTimeZoneRef tz
= NULL
;
1685 CFDateRef date
= NULL
;
1687 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1688 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1690 SecPolicyAddBasicCertOptions(options
);
1692 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonNamePrefix
,
1695 date
= CFDateCreateForGregorianZuluDay(NULL
, 2006, 5, 31);
1696 CFDictionaryAddValue(options
, kSecPolicyCheckNotValidBefore
, date
);
1698 require(result
= SecPolicyCreate(kSecPolicyAppleiAP
,
1699 kSecPolicyNameiAP
, options
),
1703 CFReleaseSafe(date
);
1705 CFReleaseSafe(options
);
1709 SecPolicyRef
SecPolicyCreateiTunesStoreURLBag(void) {
1710 CFMutableDictionaryRef options
= NULL
;
1711 SecPolicyRef result
= NULL
;
1714 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1715 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1717 SecPolicyAddBasicCertOptions(options
);
1719 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectOrganization
,
1720 CFSTR("Apple Inc."));
1721 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
,
1722 CFSTR("iTunes Store URL Bag"));
1724 require(SecPolicyAddChainLengthOptions(options
, 2), errOut
);
1725 require(SecPolicyAddAnchorSHA1Options(options
, kITMSCASHA1
), errOut
);
1727 require(result
= SecPolicyCreate(kSecPolicyAppleiTunesStoreURLBag
,
1728 kSecPolicyNameiTunesStoreURLBag
, options
), errOut
);
1731 CFReleaseSafe(options
);
1735 SecPolicyRef
SecPolicyCreateEAP(Boolean server
, CFArrayRef trustedServerNames
) {
1736 CFMutableDictionaryRef options
= NULL
;
1737 SecPolicyRef result
= NULL
;
1739 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1740 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1742 SecPolicyAddBasicX509Options(options
);
1744 /* Since EAP is used to setup the network we don't want evaluation
1745 using this policy to access the network. */
1746 CFDictionaryAddValue(options
, kSecPolicyCheckNoNetworkAccess
,
1749 if (trustedServerNames
) {
1750 CFDictionaryAddValue(options
, kSecPolicyCheckEAPTrustedServerNames
, trustedServerNames
);
1754 /* Check for weak hashes and keys, but only on system-trusted roots, because enterprise
1755 * PKIs are the absolute worst. */
1756 CFDictionaryAddValue(options
, kSecPolicyCheckSystemTrustedWeakHash
, kCFBooleanTrue
);
1757 CFDictionaryAddValue(options
, kSecPolicyCheckSystemTrustedWeakKey
, kCFBooleanTrue
);
1760 /* We need to check for EKU per rdar://22206018 */
1761 set_ssl_ekus(options
, server
);
1763 require(result
= SecPolicyCreate(kSecPolicyAppleEAP
,
1764 server
? kSecPolicyNameEAPServer
: kSecPolicyNameEAPClient
,
1768 CFReleaseSafe(options
);
1772 SecPolicyRef
SecPolicyCreateIPSec(Boolean server
, CFStringRef hostname
) {
1773 CFMutableDictionaryRef options
= NULL
;
1774 SecPolicyRef result
= NULL
;
1776 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1777 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1779 SecPolicyAddBasicX509Options(options
);
1782 CFDictionaryAddValue(options
, kSecPolicyCheckSSLHostname
, hostname
);
1785 /* Require oidExtendedKeyUsageIPSec if Extended Keyusage Extention is
1787 /* Per <rdar://problem/6843827> Cisco VPN Certificate compatibility issue.
1788 We don't check the EKU for IPSec certs for now. If we do add eku
1789 checking back in the future, we should probably also accept the
1791 ipsecEndSystem 1.3.6.1.5.5.7.3.5
1793 ipsecTunnel 1.3.6.1.5.5.7.3.6
1794 ipsecUser 1.3.6.1.5.5.7.3.7
1796 //add_eku(options, NULL); /* eku extension is optional */
1797 //add_eku(options, &oidAnyExtendedKeyUsage);
1798 //add_eku(options, &oidExtendedKeyUsageIPSec);
1800 require(result
= SecPolicyCreate(kSecPolicyAppleIPsec
,
1801 server
? kSecPolicyNameIPSecServer
: kSecPolicyNameIPSecClient
,
1805 CFReleaseSafe(options
);
1809 SecPolicyRef
SecPolicyCreateiPhoneApplicationSigning(void) {
1810 CFMutableDictionaryRef options
= NULL
;
1811 SecPolicyRef result
= NULL
;
1813 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1814 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1816 SecPolicyAddBasicCertOptions(options
);
1818 /* Anchored to the Apple Roots */
1819 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameiPhoneApplicationSigning
), errOut
);
1822 if (SecIsInternalRelease()) {
1823 /* Allow a prod hierarchy-signed test cert */
1824 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonNameTEST
,
1825 CFSTR("Apple iPhone OS Application Signing"));
1826 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.3.1"));
1829 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
,
1830 CFSTR("Apple iPhone OS Application Signing"));
1832 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.3"));
1834 add_eku(options
, NULL
); /* eku extension is optional */
1835 add_eku(options
, &oidAnyExtendedKeyUsage
);
1836 add_eku(options
, &oidExtendedKeyUsageCodeSigning
);
1838 /* Intermediate check */
1839 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
1840 CFSTR("Apple iPhone Certification Authority"));
1842 /* Chain length check */
1843 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1845 /* Skip networked revocation checks */
1846 CFDictionaryAddValue(options
, kSecPolicyCheckNoNetworkAccess
, kCFBooleanTrue
);
1848 require(result
= SecPolicyCreate(kSecPolicyAppleiPhoneApplicationSigning
,
1849 kSecPolicyNameiPhoneApplicationSigning
, options
),
1853 CFReleaseSafe(options
);
1857 SecPolicyRef
SecPolicyCreateiPhoneVPNApplicationSigning(void) {
1858 CFMutableDictionaryRef options
= NULL
;
1859 SecPolicyRef result
= NULL
;
1861 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1862 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1864 SecPolicyAddBasicCertOptions(options
);
1866 /* Anchored to the Apple Roots */
1867 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameiPhoneVPNApplicationSigning
), errOut
);
1870 if (SecIsInternalRelease()) {
1871 /* Allow a prod hierarchy-signed test cert */
1872 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonNameTEST
,
1873 CFSTR("Apple iPhone OS Application Signing"));
1874 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.6.1"));
1877 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
,
1878 CFSTR("Apple iPhone OS Application Signing"));
1880 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.6"));
1882 add_eku(options
, NULL
); /* eku extension is optional */
1883 add_eku(options
, &oidAnyExtendedKeyUsage
);
1884 add_eku(options
, &oidExtendedKeyUsageCodeSigning
);
1886 /* Intermediate check */
1887 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
1888 CFSTR("Apple iPhone Certification Authority"));
1890 /* Chain length check */
1891 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1893 /* Skip networked revocation checks */
1894 CFDictionaryAddValue(options
, kSecPolicyCheckNoNetworkAccess
, kCFBooleanTrue
);
1896 require(result
= SecPolicyCreate(kSecPolicyAppleiPhoneVPNApplicationSigning
,
1897 kSecPolicyNameiPhoneVPNApplicationSigning
, options
),
1901 CFReleaseSafe(options
);
1905 SecPolicyRef
SecPolicyCreateiPhoneProfileApplicationSigning(void) {
1906 CFMutableDictionaryRef options
= NULL
;
1907 SecPolicyRef result
= NULL
;
1909 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1910 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1912 SecPolicyAddBasicX509Options(options
); // With expiration checking
1915 require_quiet(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameiPhoneProfileApplicationSigning
),
1919 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1921 /* Leaf has CodeSigning EKU */
1922 add_eku_string(options
, CFSTR("1.3.6.1.5.5.7.3.3"));
1924 /* On iOS, the cert in the provisioning profile may be one of:
1925 leaf OID intermediate OID
1926 iPhone Developer <ADS>.6.1.2 <ADS>.6.2.1
1927 iPhone Distribution <ADS>.6.1.4 <ADS>.6.2.1
1928 TestFlight (Prod) <ADS>.6.1.25.1 <ADS>.6.2.1
1929 TestFlight (QA) <ADS>.6.1.25.2 <ADS>.6.2.1
1931 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.1"));
1932 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.2"));
1933 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.4"));
1934 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.25.1"));
1935 if (SecIsInternalRelease()) {
1936 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.25.2"));
1939 /* Revocation via any available method */
1940 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
1942 require(result
= SecPolicyCreate(kSecPolicyAppleiPhoneProfileApplicationSigning
,
1943 kSecPolicyNameiPhoneProfileApplicationSigning
,
1947 CFReleaseSafe(options
);
1951 SecPolicyRef
SecPolicyCreateMacOSProfileApplicationSigning(void) {
1952 CFMutableDictionaryRef options
= NULL
;
1953 SecPolicyRef result
= NULL
;
1955 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1956 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1958 SecPolicyAddBasicCertOptions(options
); // Without expiration checking
1961 require_quiet(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameiPhoneProfileApplicationSigning
),
1965 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1967 /* Leaf has CodeSigning EKU */
1968 add_eku_string(options
, CFSTR("1.3.6.1.5.5.7.3.3"));
1971 /* On macOS, the cert in the provisioning profile may be one of:
1972 leaf OID intermediate OID
1973 MAS Development <ADS>.6.1.12 <ADS>.6.2.1
1974 MAS Submission <ADS>.6.1.7 <ADS>.6.2.1
1975 Developer ID <ADS>.6.1.13 <ADS>.6.2.6
1976 B&I <ADS>.6.22 None - "Apple Code Signing Certification Authority"
1978 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.12"));
1979 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.7"));
1980 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.13"));
1981 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.22"));
1983 /* Revocation via any available method */
1984 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
1986 require(result
= SecPolicyCreate(kSecPolicyAppleMacOSProfileApplicationSigning
,
1987 kSecPolicyNameMacOSProfileApplicationSigning
,
1991 CFReleaseSafe(options
);
1995 SecPolicyRef
SecPolicyCreateiPhoneProvisioningProfileSigning(void) {
1996 CFMutableDictionaryRef options
= NULL
;
1997 SecPolicyRef result
= NULL
;
1999 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2000 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2002 SecPolicyAddBasicCertOptions(options
);
2004 /* Basic X.509 policy with the additional requirements that the chain
2005 length is 3, it's anchored at the AppleCA and the leaf certificate
2006 has issuer "Apple iPhone Certification Authority" and
2007 subject "Apple iPhone OS Provisioning Profile Signing" for the common name. */
2008 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2009 CFSTR("Apple iPhone Certification Authority"));
2010 if (SecIsInternalRelease()) {
2011 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonNameTEST
,
2012 CFSTR("Apple iPhone OS Provisioning Profile Signing"));
2015 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
,
2016 CFSTR("Apple iPhone OS Provisioning Profile Signing"));
2019 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2020 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameiPhoneProvisioningProfileSigning
), errOut
);
2022 /* Skip networked revocation checks */
2023 CFDictionaryAddValue(options
, kSecPolicyCheckNoNetworkAccess
, kCFBooleanTrue
);
2025 require(result
= SecPolicyCreate(kSecPolicyAppleiPhoneProvisioningProfileSigning
,
2026 kSecPolicyNameiPhoneProvisioningProfileSigning
, options
),
2029 /* 1.2.840.113635.100.6.2.2.1, non-critical: DER:05:00 - provisioning profile */
2032 CFReleaseSafe(options
);
2036 SecPolicyRef
SecPolicyCreateAppleTVOSApplicationSigning(void) {
2037 CFMutableDictionaryRef options
= NULL
;
2038 SecPolicyRef result
= NULL
;
2039 CFDataRef atvProdOid
= NULL
;
2040 CFDataRef atvTestOid
= NULL
;
2041 CFArrayRef oids
= NULL
;
2043 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2044 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2046 SecPolicyAddBasicCertOptions(options
);
2048 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2050 require_quiet(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameTVOSApplicationSigning
),
2053 /* Check for intermediate: Apple Worldwide Developer Relations */
2054 /* 1.2.840.113635.100.6.2.1 */
2055 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleWWDR
);
2057 add_ku(options
, kSecKeyUsageDigitalSignature
);
2059 /* Check for prod or test AppleTV Application Signing OIDs */
2060 /* Prod: 1.2.840.113635.100.6.1.24 */
2061 /* ProdQA: 1.2.840.113635.100.6.1.24.1 */
2062 add_leaf_marker(options
, &oidAppleTVOSApplicationSigningProd
);
2063 add_leaf_marker(options
, &oidAppleTVOSApplicationSigningProdQA
);
2065 /* Skip networked revocation checks */
2066 CFDictionaryAddValue(options
, kSecPolicyCheckNoNetworkAccess
, kCFBooleanTrue
);
2068 require(result
= SecPolicyCreate(kSecPolicyAppleTVOSApplicationSigning
,
2069 kSecPolicyNameTVOSApplicationSigning
, options
),
2073 CFReleaseSafe(options
);
2074 CFReleaseSafe(oids
);
2075 CFReleaseSafe(atvProdOid
);
2076 CFReleaseSafe(atvTestOid
);
2080 SecPolicyRef
SecPolicyCreateOCSPSigner(void) {
2081 CFMutableDictionaryRef options
= NULL
;
2082 SecPolicyRef result
= NULL
;
2084 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2085 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2087 SecPolicyAddBasicX509Options(options
);
2089 /* Require id-kp-OCSPSigning extendedKeyUsage to be present, not optional. */
2090 add_eku(options
, &oidExtendedKeyUsageOCSPSigning
);
2092 require(result
= SecPolicyCreate(kSecPolicyAppleOCSPSigner
,
2093 kSecPolicyNameOCSPSigner
, options
), errOut
);
2096 CFReleaseSafe(options
);
2100 SecPolicyRef
SecPolicyCreateRevocation(CFOptionFlags revocationFlags
) {
2101 CFMutableDictionaryRef options
= NULL
;
2102 SecPolicyRef result
= NULL
;
2104 require(revocationFlags
!= 0, errOut
);
2106 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2107 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2109 if (revocationFlags
& kSecRevocationCheckIfTrusted
) {
2110 CFDictionaryAddValue(options
, kSecPolicyCheckRevocationIfTrusted
, kCFBooleanTrue
);
2111 /* Set method, but allow caller to override with later checks */
2112 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
2115 if (revocationFlags
& kSecRevocationOnlineCheck
) {
2116 CFDictionaryAddValue(options
, kSecPolicyCheckRevocationOnline
, kCFBooleanTrue
);
2117 /* Set method, but allow caller to override with later checks */
2118 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
2121 if (revocationFlags
& kSecRevocationOCSPMethod
&& revocationFlags
& kSecRevocationCRLMethod
) {
2122 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
2124 else if (revocationFlags
& kSecRevocationOCSPMethod
) {
2125 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationOCSP
);
2127 else if (revocationFlags
& kSecRevocationCRLMethod
) {
2128 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationCRL
);
2131 if (revocationFlags
& kSecRevocationRequirePositiveResponse
) {
2132 CFDictionaryAddValue(options
, kSecPolicyCheckRevocationResponseRequired
, kCFBooleanTrue
);
2135 if (revocationFlags
& kSecRevocationNetworkAccessDisabled
) {
2136 CFDictionaryAddValue(options
, kSecPolicyCheckNoNetworkAccess
, kCFBooleanTrue
);
2138 /* If the caller didn't explicitly disable network access, the revocation policy
2139 * should override any other policy's network setting.
2140 * In particular, pairing a revocation policy with BasicX509 should result in
2141 * allowing network access for revocation unless explicitly disabled.
2142 * Note that SecTrustSetNetworkFetchAllowed can override even this. */
2143 CFDictionaryAddValue(options
, kSecPolicyCheckNoNetworkAccess
, kCFBooleanFalse
);
2146 /* Only flag bits 0-6 are currently defined */
2147 require(((revocationFlags
>> 7) == 0), errOut
);
2149 require(result
= SecPolicyCreate(kSecPolicyAppleRevocation
,
2150 kSecPolicyNameRevocation
, options
), errOut
);
2153 CFReleaseSafe(options
);
2157 SecPolicyRef
SecPolicyCreateSMIME(CFIndex smimeUsage
, CFStringRef email
) {
2158 CFMutableDictionaryRef options
= NULL
;
2159 SecPolicyRef result
= NULL
;
2161 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2162 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2164 if (smimeUsage
& kSecIgnoreExpirationSMIMEUsage
) {
2165 SecPolicyAddBasicCertOptions(options
);
2167 SecPolicyAddBasicX509Options(options
);
2170 /* We call add_ku for each combination of bits we are willing to allow. */
2171 if (smimeUsage
& kSecSignSMIMEUsage
) {
2172 add_ku(options
, kSecKeyUsageUnspecified
);
2173 add_ku(options
, kSecKeyUsageDigitalSignature
);
2174 add_ku(options
, kSecKeyUsageNonRepudiation
);
2176 if (smimeUsage
& kSecKeyEncryptSMIMEUsage
) {
2177 add_ku(options
, kSecKeyUsageKeyEncipherment
);
2179 if (smimeUsage
& kSecDataEncryptSMIMEUsage
) {
2180 add_ku(options
, kSecKeyUsageDataEncipherment
);
2182 if (smimeUsage
& kSecKeyExchangeDecryptSMIMEUsage
) {
2183 add_ku(options
, kSecKeyUsageKeyAgreement
| kSecKeyUsageDecipherOnly
);
2185 if (smimeUsage
& kSecKeyExchangeEncryptSMIMEUsage
) {
2186 add_ku(options
, kSecKeyUsageKeyAgreement
| kSecKeyUsageEncipherOnly
);
2188 if (smimeUsage
& kSecKeyExchangeBothSMIMEUsage
) {
2189 add_ku(options
, kSecKeyUsageKeyAgreement
| kSecKeyUsageEncipherOnly
| kSecKeyUsageDecipherOnly
);
2193 CFDictionaryAddValue(options
, kSecPolicyCheckEmail
, email
);
2196 /* RFC 3850 paragraph 4.4.4
2198 If the extended key usage extension is present in the certificate
2199 then interpersonal message S/MIME receiving agents MUST check that it
2200 contains either the emailProtection or the anyExtendedKeyUsage OID as
2201 defined in [KEYM]. S/MIME uses other than interpersonal messaging
2202 MAY require the explicit presence of the extended key usage extension
2203 or other OIDs to be present in the extension or both.
2205 add_eku(options
, NULL
); /* eku extension is optional */
2206 add_eku(options
, &oidAnyExtendedKeyUsage
);
2207 add_eku(options
, &oidExtendedKeyUsageEmailProtection
);
2209 #if !TARGET_OS_IPHONE
2210 // Check revocation on OS X
2211 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
2214 require(result
= SecPolicyCreate(kSecPolicyAppleSMIME
, kSecPolicyNameSMIME
, options
), errOut
);
2217 CFReleaseSafe(options
);
2221 SecPolicyRef
SecPolicyCreateApplePackageSigning(void) {
2222 CFMutableDictionaryRef options
= NULL
;
2223 SecPolicyRef result
= NULL
;
2225 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2226 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2228 SecPolicyAddBasicCertOptions(options
);
2230 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2231 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNamePackageSigning
), errOut
);
2233 add_ku(options
, kSecKeyUsageDigitalSignature
);
2234 add_eku(options
, &oidExtendedKeyUsageCodeSigning
);
2236 require(result
= SecPolicyCreate(kSecPolicyApplePackageSigning
,
2237 kSecPolicyNamePackageSigning
, options
),
2241 CFReleaseSafe(options
);
2246 SecPolicyRef
SecPolicyCreateAppleSWUpdateSigning(void) {
2247 CFMutableDictionaryRef options
= NULL
;
2248 SecPolicyRef result
= NULL
;
2250 * OS X rules for this policy:
2251 * -- Must have one intermediate cert
2252 * -- intermediate must have basic constraints with path length 0
2253 * -- intermediate has CSSMOID_APPLE_EKU_CODE_SIGNING EKU
2254 * -- leaf cert has either CODE_SIGNING or CODE_SIGN_DEVELOPMENT EKU (the latter of
2255 * which triggers a CSSMERR_APPLETP_CODE_SIGN_DEVELOPMENT error)
2257 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2258 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2260 SecPolicyAddBasicX509Options(options
);
2262 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2263 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameSWUpdateSigning
), errOut
);
2265 add_eku(options
, &oidAppleExtendedKeyUsageCodeSigning
);
2266 add_oid(options
, kSecPolicyCheckIntermediateEKU
, &oidAppleExtendedKeyUsageCodeSigning
);
2268 require(result
= SecPolicyCreate(kSecPolicyAppleSWUpdateSigning
,
2269 kSecPolicyNameSWUpdateSigning
, options
),
2273 CFReleaseSafe(options
);
2278 SecPolicyRef
SecPolicyCreateCodeSigning(void) {
2279 CFMutableDictionaryRef options
= NULL
;
2280 SecPolicyRef result
= NULL
;
2282 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2283 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2285 SecPolicyAddBasicX509Options(options
);
2287 /* If the key usage extension is present, we accept it having either of
2289 add_ku(options
, kSecKeyUsageDigitalSignature
);
2290 add_ku(options
, kSecKeyUsageNonRepudiation
);
2292 /* We require an extended key usage extension with the codesigning
2293 eku purpose. (The Apple codesigning eku is not accepted here
2294 since it's valid only for SecPolicyCreateAppleSWUpdateSigning.) */
2295 add_eku(options
, &oidExtendedKeyUsageCodeSigning
);
2296 #if TARGET_OS_IPHONE
2297 /* Accept the 'any' eku on iOS only to match prior behavior.
2298 This may be further restricted in future releases. */
2299 add_eku(options
, &oidAnyExtendedKeyUsage
);
2302 require(result
= SecPolicyCreate(kSecPolicyAppleCodeSigning
,
2303 kSecPolicyNameCodeSigning
, options
),
2307 CFReleaseSafe(options
);
2311 /* Explicitly leave out empty subject/subjectaltname check */
2312 SecPolicyRef
SecPolicyCreateLockdownPairing(void) {
2313 CFMutableDictionaryRef options
= NULL
;
2314 SecPolicyRef result
= NULL
;
2316 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2317 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2318 //CFDictionaryAddValue(options, kSecPolicyCheckBasicCertificateProcessing,
2319 // kCFBooleanTrue); // Happens automatically in SecPVCPathChecks
2320 CFDictionaryAddValue(options
, kSecPolicyCheckCriticalExtensions
,
2322 CFDictionaryAddValue(options
, kSecPolicyCheckIdLinkage
,
2324 CFDictionaryAddValue(options
, kSecPolicyCheckBasicConstraints
,
2326 CFDictionaryAddValue(options
, kSecPolicyCheckWeakKeySize
, kCFBooleanTrue
);
2328 require(result
= SecPolicyCreate(kSecPolicyAppleLockdownPairing
,
2329 kSecPolicyNameLockdownPairing
, options
), errOut
);
2332 CFReleaseSafe(options
);
2336 SecPolicyRef
SecPolicyCreateURLBag(void) {
2337 CFMutableDictionaryRef options
= NULL
;
2338 SecPolicyRef result
= NULL
;
2340 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2341 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2343 SecPolicyAddBasicCertOptions(options
);
2345 add_eku(options
, &oidExtendedKeyUsageCodeSigning
);
2347 require(result
= SecPolicyCreate(kSecPolicyAppleURLBag
,
2348 kSecPolicyNameURLBag
, options
), errOut
);
2351 CFReleaseSafe(options
);
2355 SecPolicyRef
SecPolicyCreateOTATasking(void)
2357 CFMutableDictionaryRef options
= NULL
;
2358 SecPolicyRef result
= NULL
;
2360 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2361 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2363 SecPolicyAddBasicX509Options(options
);
2366 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameMobileAsset
), errOut
);
2368 /* Chain length of 3 */
2369 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2371 /* Intermediate has common name "Apple iPhone Certification Authority". */
2372 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2373 CFSTR("Apple iPhone Certification Authority"));
2375 /* Leaf has common name "Asset Manifest Signing" */
2376 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
, CFSTR("OTA Task Signing"));
2378 require(result
= SecPolicyCreate(kSecPolicyAppleOTATasking
, kSecPolicyNameOTATasking
, options
),
2382 CFReleaseSafe(options
);
2386 SecPolicyRef
SecPolicyCreateMobileAsset(void)
2388 CFMutableDictionaryRef options
= NULL
;
2389 SecPolicyRef result
= NULL
;
2391 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2392 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2394 /* No expiration check */
2395 SecPolicyAddBasicCertOptions(options
);
2398 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameMobileAsset
), errOut
);
2400 /* Chain length of 3 */
2401 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2403 /* Intermediate has common name "Apple iPhone Certification Authority". */
2404 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2405 CFSTR("Apple iPhone Certification Authority"));
2407 /* Leaf has common name "Asset Manifest Signing" */
2408 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
, CFSTR("Asset Manifest Signing"));
2410 require(result
= SecPolicyCreate(kSecPolicyAppleMobileAsset
, kSecPolicyNameMobileAsset
, options
),
2414 CFReleaseSafe(options
);
2418 SecPolicyRef
SecPolicyCreateMobileAssetDevelopment(void) {
2419 CFMutableDictionaryRef options
= NULL
;
2420 SecPolicyRef result
= NULL
;
2422 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2423 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2425 /* No expiration check */
2426 SecPolicyAddBasicCertOptions(options
);
2429 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameMobileAsset
), errOut
);
2431 /* Chain length of 3 */
2432 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2434 /* Intermediate has the iPhone CA Marker extension */
2435 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.18"));
2437 /* Leaf has ProdQA Mobile Asset Marker extension */
2438 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.55.1"));
2440 require(result
= SecPolicyCreate(kSecPolicyAppleMobileAssetDevelopment
, kSecPolicyNameMobileAsset
, options
),
2444 CFReleaseSafe(options
);
2448 SecPolicyRef
SecPolicyCreateAppleIDAuthorityPolicy(void)
2450 SecPolicyRef result
= NULL
;
2451 CFMutableDictionaryRef options
= NULL
;
2452 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2453 &kCFTypeDictionaryKeyCallBacks
,
2454 &kCFTypeDictionaryValueCallBacks
), out
);
2456 //Leaf appears to be a SSL only cert, so policy should expand on that policy
2457 SecPolicyAddBasicX509Options(options
);
2459 // Apple CA anchored
2460 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameIDAuthority
), out
);
2462 // with the addition of the existence check of an extension with "Apple ID Sharing Certificate" oid (1.2.840.113635.100.4.7)
2463 // NOTE: this obviously intended to have gone into Extended Key Usage, but evidence of existing certs proves the contrary.
2464 add_leaf_marker(options
, &oidAppleExtendedKeyUsageAppleID
);
2466 // 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.
2467 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleID
);
2468 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleID2
);
2470 require(result
= SecPolicyCreate(kSecPolicyAppleIDAuthority
,
2471 kSecPolicyNameIDAuthority
, options
), out
);
2474 CFReleaseSafe(options
);
2478 SecPolicyRef
SecPolicyCreateMacAppStoreReceipt(void)
2480 SecPolicyRef result
= NULL
;
2481 CFMutableDictionaryRef options
= NULL
;
2482 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2483 &kCFTypeDictionaryKeyCallBacks
,
2484 &kCFTypeDictionaryValueCallBacks
), out
);
2486 SecPolicyAddBasicX509Options(options
);
2488 // Apple CA anchored
2489 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameMacAppStoreReceipt
), out
);
2491 // Chain length of 3
2492 require(SecPolicyAddChainLengthOptions(options
, 3), out
);
2494 // MacAppStoreReceipt policy OID
2495 add_certificate_policy_oid_string(options
, CFSTR("1.2.840.113635.100.5.6.1"));
2497 // Intermediate marker OID
2498 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.1"));
2501 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.11.1"));
2504 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
2506 require(result
= SecPolicyCreate(kSecPolicyMacAppStoreReceipt
,
2507 kSecPolicyNameMacAppStoreReceipt
, options
), out
);
2510 CFReleaseSafe(options
);
2515 static SecPolicyRef
_SecPolicyCreatePassbookCardSigner(CFStringRef cardIssuer
, CFStringRef teamIdentifier
, bool requireTeamID
)
2517 SecPolicyRef result
= NULL
;
2518 CFMutableDictionaryRef options
= NULL
;
2519 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2520 &kCFTypeDictionaryKeyCallBacks
,
2521 &kCFTypeDictionaryValueCallBacks
), out
);
2523 SecPolicyAddBasicX509Options(options
);
2524 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNamePassbookSigning
), out
);
2526 // Chain length of 3
2527 require(SecPolicyAddChainLengthOptions(options
, 3), out
);
2529 if (teamIdentifier
) {
2530 // If supplied, teamIdentifier must match subject OU field
2531 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectOrganizationalUnit
, teamIdentifier
);
2534 // If not supplied, and it was required, fail
2535 require(!requireTeamID
, out
);
2538 // Must be both push and 3rd party package signing
2539 add_leaf_marker_value(options
, &oidAppleInstallerPackagingSigningExternal
, cardIssuer
);
2541 // We should check that it also has push marker, but we don't support requiring both, only either.
2542 // add_independent_oid(options, kSecPolicyCheckLeafMarkerOid, &oidApplePushServiceClient);
2544 //WWDR Intermediate marker OID
2545 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.1"));
2547 // And Passbook signing eku
2548 add_eku(options
, &oidAppleExtendedKeyUsagePassbook
);
2550 require(result
= SecPolicyCreate(kSecPolicyApplePassbookSigning
,
2551 kSecPolicyNamePassbookSigning
, options
), out
);
2554 CFReleaseSafe(options
);
2558 SecPolicyRef
SecPolicyCreatePassbookCardSigner(CFStringRef cardIssuer
, CFStringRef teamIdentifier
)
2560 return _SecPolicyCreatePassbookCardSigner(cardIssuer
, teamIdentifier
, true);
2564 static SecPolicyRef
CreateMobileStoreSigner(Boolean forTest
)
2567 SecPolicyRef result
= NULL
;
2568 CFMutableDictionaryRef options
= NULL
;
2569 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2570 &kCFTypeDictionaryKeyCallBacks
,
2571 &kCFTypeDictionaryValueCallBacks
), errOut
);
2572 SecPolicyAddBasicX509Options(options
);
2573 require(SecPolicyAddAppleAnchorOptions(options
,
2574 ((forTest
) ? kSecPolicyNameTestMobileStore
:
2575 kSecPolicyNameMobileStore
)), errOut
);
2577 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2579 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2580 CFSTR("Apple System Integration 2 Certification Authority"));
2582 add_ku(options
, kSecKeyUsageDigitalSignature
);
2584 const DERItem
* pOID
= (forTest
) ? &oidApplePolicyMobileStoreProdQA
: &oidApplePolicyMobileStore
;
2586 add_certificate_policy_oid(options
, pOID
);
2588 require(result
= SecPolicyCreate((forTest
) ? kSecPolicyAppleTestMobileStore
: kSecPolicyAppleMobileStore
,
2589 (forTest
) ? kSecPolicyNameTestMobileStore
: kSecPolicyNameMobileStore
,
2593 CFReleaseSafe(options
);
2597 SecPolicyRef
SecPolicyCreateMobileStoreSigner(void)
2599 return CreateMobileStoreSigner(false);
2602 SecPolicyRef
SecPolicyCreateTestMobileStoreSigner(void)
2604 return CreateMobileStoreSigner(true);
2608 CF_RETURNS_RETAINED SecPolicyRef
SecPolicyCreateEscrowServiceSigner(void)
2610 SecPolicyRef result
= NULL
;
2611 CFMutableDictionaryRef options
= NULL
;
2612 CFArrayRef anArray
= NULL
;
2613 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2614 &kCFTypeDictionaryKeyCallBacks
,
2615 &kCFTypeDictionaryValueCallBacks
), errOut
);
2617 // 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 Boolean anchorAdded
= false;
2627 // Get the roots by calling the SecCertificateCopyEscrowRoots
2628 anArray
= SecCertificateCopyEscrowRoots(kSecCertificateProductionEscrowRoot
);
2629 CFIndex numRoots
= 0;
2630 if (NULL
== anArray
|| 0 == (numRoots
= CFArrayGetCount(anArray
))) {
2634 for (CFIndex iCnt
= 0; iCnt
< numRoots
; iCnt
++) {
2635 SecCertificateRef aCert
= (SecCertificateRef
)CFArrayGetValueAtIndex(anArray
, iCnt
);
2637 if (NULL
!= aCert
) {
2638 CFDataRef sha_data
= SecCertificateGetSHA1Digest(aCert
);
2639 if (NULL
!= sha_data
) {
2640 const UInt8
* pSHAData
= CFDataGetBytePtr(sha_data
);
2641 if (NULL
!= pSHAData
) {
2642 SecPolicyAddAnchorSHA1Options(options
, pSHAData
);
2648 CFReleaseNull(anArray
);
2654 require(result
= SecPolicyCreate(kSecPolicyAppleEscrowService
,
2655 kSecPolicyNameEscrowService
, options
), errOut
);
2658 CFReleaseSafe(anArray
);
2659 CFReleaseSafe(options
);
2663 CF_RETURNS_RETAINED SecPolicyRef
SecPolicyCreatePCSEscrowServiceSigner(void)
2665 SecPolicyRef result
= NULL
;
2666 CFMutableDictionaryRef options
= NULL
;
2667 CFArrayRef anArray
= NULL
;
2668 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2669 &kCFTypeDictionaryKeyCallBacks
,
2670 &kCFTypeDictionaryValueCallBacks
), errOut
);
2672 SecPolicyAddBasicX509Options(options
);
2673 add_ku(options
, kSecKeyUsageKeyEncipherment
);
2675 /* Leaf has marker OID with value that can't be pre-determined */
2676 add_element(options
, kSecPolicyCheckLeafMarkerOidWithoutValueCheck
, CFSTR("1.2.840.113635.100.6.23.1"));
2677 require(SecPolicyAddChainLengthOptions(options
, 2), errOut
);
2679 Boolean anchorAdded
= false;
2680 anArray
= SecCertificateCopyEscrowRoots(kSecCertificateProductionPCSEscrowRoot
);
2681 CFIndex numRoots
= 0;
2682 if (NULL
== anArray
|| 0 == (numRoots
= CFArrayGetCount(anArray
))) {
2686 for (CFIndex iCnt
= 0; iCnt
< numRoots
; iCnt
++) {
2687 SecCertificateRef aCert
= (SecCertificateRef
)CFArrayGetValueAtIndex(anArray
, iCnt
);
2689 if (NULL
!= aCert
) {
2690 CFDataRef sha_data
= SecCertificateGetSHA1Digest(aCert
);
2691 if (NULL
!= sha_data
) {
2692 const UInt8
* pSHAData
= CFDataGetBytePtr(sha_data
);
2693 if (NULL
!= pSHAData
) {
2694 SecPolicyAddAnchorSHA1Options(options
, pSHAData
);
2700 CFReleaseNull(anArray
);
2706 require(result
= SecPolicyCreate(kSecPolicyApplePCSEscrowService
,
2707 kSecPolicyNamePCSEscrowService
, options
), errOut
);
2710 CFReleaseSafe(anArray
);
2711 CFReleaseSafe(options
);
2715 static SecPolicyRef
CreateConfigurationProfileSigner(bool forTest
) {
2716 SecPolicyRef result
= NULL
;
2717 CFMutableDictionaryRef options
= NULL
;
2718 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2719 &kCFTypeDictionaryKeyCallBacks
,
2720 &kCFTypeDictionaryValueCallBacks
), errOut
);
2722 SecPolicyAddBasicX509Options(options
);
2723 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameProfileSigner
), errOut
);
2726 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2728 // Require the profile signing EKU
2729 const DERItem
* pOID
= (forTest
) ? &oidAppleExtendedKeyUsageQAProfileSigning
:&oidAppleExtendedKeyUsageProfileSigning
;
2730 add_eku(options
, pOID
);
2732 // Require the Apple Application Integration CA marker OID
2733 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.3"));
2735 require(result
= SecPolicyCreate((forTest
) ? kSecPolicyAppleQAProfileSigner
: kSecPolicyAppleProfileSigner
,
2736 (forTest
) ? kSecPolicyNameQAProfileSigner
: kSecPolicyNameProfileSigner
,
2740 CFReleaseSafe(options
);
2744 SecPolicyRef
SecPolicyCreateConfigurationProfileSigner(void)
2746 return CreateConfigurationProfileSigner(false);
2750 SecPolicyRef
SecPolicyCreateQAConfigurationProfileSigner(void)
2752 if (SecIsInternalRelease()) {
2753 return CreateConfigurationProfileSigner(true);
2755 return CreateConfigurationProfileSigner(false);
2759 SecPolicyRef
SecPolicyCreateOSXProvisioningProfileSigning(void)
2761 SecPolicyRef result
= NULL
;
2762 CFMutableDictionaryRef options
= NULL
;
2763 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2764 &kCFTypeDictionaryKeyCallBacks
,
2765 &kCFTypeDictionaryValueCallBacks
), errOut
);
2766 // Require valid chain from the Apple root
2767 SecPolicyAddBasicX509Options(options
);
2768 SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameOSXProvisioningProfileSigning
);
2770 // Require provisioning profile leaf marker OID (1.2.840.113635.100.4.11)
2771 add_leaf_marker(options
, &oidAppleCertExtOSXProvisioningProfileSigning
);
2773 // Require intermediate marker OID (1.2.840.113635.100.6.2.1)
2774 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleWWDR
);
2776 // Require key usage that allows signing
2777 add_ku(options
, kSecKeyUsageDigitalSignature
);
2779 // Ensure that revocation is checked (OCSP)
2780 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationOCSP
);
2782 require(result
= SecPolicyCreate(kSecPolicyAppleOSXProvisioningProfileSigning
,
2783 kSecPolicyNameOSXProvisioningProfileSigning
, options
), errOut
);
2786 CFReleaseSafe(options
);
2791 SecPolicyRef
SecPolicyCreateOTAPKISigner(void)
2793 SecPolicyRef result
= NULL
;
2794 CFMutableDictionaryRef options
= NULL
;
2795 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2796 &kCFTypeDictionaryKeyCallBacks
,
2797 &kCFTypeDictionaryValueCallBacks
), errOut
);
2798 SecPolicyAddBasicX509Options(options
);
2800 SecPolicyAddAnchorSHA1Options(options
, kApplePKISettingsAuthority
);
2801 require(SecPolicyAddChainLengthOptions(options
, 2), errOut
);
2803 require(result
= SecPolicyCreate(kSecPolicyAppleOTAPKISigner
,
2804 kSecPolicyNameOTAPKISigner
, options
), errOut
);
2807 CFReleaseSafe(options
);
2813 SecPolicyRef
SecPolicyCreateTestOTAPKISigner(void)
2815 /* Guard against use on production devices */
2816 if (!SecIsInternalRelease()) {
2817 return SecPolicyCreateOTAPKISigner();
2820 SecPolicyRef result
= NULL
;
2821 CFMutableDictionaryRef options
= NULL
;
2822 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2823 &kCFTypeDictionaryKeyCallBacks
,
2824 &kCFTypeDictionaryValueCallBacks
), errOut
);
2825 SecPolicyAddBasicX509Options(options
);
2827 SecPolicyAddAnchorSHA1Options(options
, kAppleTestPKISettingsAuthority
);
2828 require(SecPolicyAddChainLengthOptions(options
, 2), errOut
);
2830 require(result
= SecPolicyCreate(kSecPolicyAppleTestOTAPKISigner
,
2831 kSecPolicyNameTestOTAPKISigner
, options
), errOut
);
2834 CFReleaseSafe(options
);
2839 @function SecPolicyCreateAppleSMPEncryption
2840 @abstract Check for intermediate certificate 'Apple System Integration CA - G3' by name,
2841 and root certificate 'Apple Root CA - G3' by hash.
2842 Leaf cert must have Key Encipherment usage.
2843 Leaf cert must have Apple SMP Encryption marker OID (1.2.840.113635.100.6.30).
2844 Intermediate must have marker OID (1.2.840.113635.100.6.2.13).
2846 SecPolicyRef
SecPolicyCreateAppleSMPEncryption(void)
2848 SecPolicyRef result
= NULL
;
2849 CFMutableDictionaryRef options
= NULL
;
2850 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2851 &kCFTypeDictionaryKeyCallBacks
,
2852 &kCFTypeDictionaryValueCallBacks
), errOut
);
2853 SecPolicyAddBasicCertOptions(options
);
2855 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameSMPEncryption
),
2857 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2859 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2860 CFSTR("Apple System Integration CA - G3"));
2862 // Check that leaf has extension with "Apple SMP Encryption" oid (1.2.840.113635.100.6.30)
2863 add_leaf_marker(options
, &oidAppleCertExtAppleSMPEncryption
);
2865 // Check that intermediate has extension (1.2.840.113635.100.6.2.13)
2866 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleSystemIntgG3
);
2868 add_ku(options
, kSecKeyUsageKeyEncipherment
);
2870 // Ensure that revocation is checked (OCSP)
2871 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationOCSP
);
2873 require(result
= SecPolicyCreate(kSecPolicyAppleSMPEncryption
,
2874 kSecPolicyNameSMPEncryption
, options
), errOut
);
2877 CFReleaseSafe(options
);
2882 @function SecPolicyCreateTestAppleSMPEncryption
2883 @abstract Check for intermediate certificate 'Test Apple System Integration CA - ECC' by name,
2884 and root certificate 'Test Apple Root CA - ECC' by hash.
2885 Leaf cert must have Key Encipherment usage. Other checks TBD.
2887 SecPolicyRef
SecPolicyCreateTestAppleSMPEncryption(void)
2889 SecPolicyRef result
= NULL
;
2890 CFMutableDictionaryRef options
= NULL
;
2891 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2892 &kCFTypeDictionaryKeyCallBacks
,
2893 &kCFTypeDictionaryValueCallBacks
), errOut
);
2894 SecPolicyAddBasicCertOptions(options
);
2896 SecPolicyAddAnchorSHA1Options(options
, kTestAppleRootCA_ECC_SHA1
);
2897 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2899 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2900 CFSTR("Test Apple System Integration CA - ECC"));
2902 add_ku(options
, kSecKeyUsageKeyEncipherment
);
2904 // Ensure that revocation is checked (OCSP)
2905 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationOCSP
);
2907 require(result
= SecPolicyCreate(kSecPolicyAppleTestSMPEncryption
,
2908 kSecPolicyNameTestSMPEncryption
, options
), errOut
);
2911 CFReleaseSafe(options
);
2916 SecPolicyRef
SecPolicyCreateAppleIDValidationRecordSigningPolicy(void)
2918 SecPolicyRef result
= NULL
;
2919 CFMutableDictionaryRef options
= NULL
;
2920 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2921 &kCFTypeDictionaryKeyCallBacks
,
2922 &kCFTypeDictionaryValueCallBacks
), errOut
);
2924 //Leaf appears to be a SSL only cert, so policy should expand on that policy
2925 SecPolicyAddBasicX509Options(options
);
2927 // Apple CA anchored
2928 require(SecPolicyAddAppleAnchorOptions(options
,
2929 kSecPolicyNameIDValidationRecordSigning
),
2932 // Check for an extension with " Apple ID Validation Record Signing" oid (1.2.840.113635.100.6.25)
2933 add_leaf_marker(options
, &oidAppleCertExtensionAppleIDRecordValidationSigning
);
2935 // and validate that intermediate has extension
2936 // Application Integration Intermediate Certificate (1.2.840.113635.100.6.2.3)
2937 // and also validate that intermediate has extension
2938 // System Integration 2 Intermediate Certificate (1.2.840.113635.100.6.2.10)
2939 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleID
);
2940 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleSystemIntg2
);
2942 // Ensure that revocation is checked (OCSP)
2943 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationOCSP
);
2945 require(result
= SecPolicyCreate(kSecPolicyAppleIDValidationRecordSigning
,
2946 kSecPolicyNameIDValidationRecordSigning
, options
), errOut
);
2949 CFReleaseSafe(options
);
2954 @function SecPolicyCreateAppleServerAuthCommon
2955 @abstract Generic policy for server authentication Sub CAs
2957 Allows control for both if pinning is required at all and if UAT environments should be added
2958 to the trust policy.
2960 No pinning is for developer/QA that needs to use proxy to debug the protocol, while UAT
2961 environment is for QA/internal developer that have no need allow fake servers.
2963 Both the noPinning and UAT are gated on that you run on internal hardware.
2968 SecPolicyCreateAppleServerAuthCommon(CFStringRef hostname
,
2969 CFDictionaryRef __unused context
,
2970 CFStringRef policyOID
, CFStringRef service
,
2971 const DERItem
*leafMarkerOID
,
2972 const DERItem
*UATLeafMarkerOID
)
2974 CFMutableDictionaryRef appleAnchorOptions
= NULL
;
2975 CFMutableDictionaryRef options
= NULL
;
2976 SecPolicyRef result
= NULL
;
2977 CFDataRef oid
= NULL
, uatoid
= NULL
;
2979 options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0, &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
2980 require(options
, errOut
);
2982 SecPolicyAddBasicX509Options(options
);
2984 require(hostname
, errOut
);
2985 CFDictionaryAddValue(options
, kSecPolicyCheckSSLHostname
, hostname
);
2987 CFDictionaryAddValue(options
, kSecPolicyCheckBlackListedLeaf
, kCFBooleanTrue
);
2988 CFDictionaryAddValue(options
, kSecPolicyCheckGrayListedLeaf
, kCFBooleanTrue
);
2990 add_eku(options
, &oidExtendedKeyUsageServerAuth
);
2992 if (requireUATPinning(service
)) {
2995 * Require pinning to the Apple CA's.
2997 SecPolicyAddAppleAnchorOptions(options
, service
);
2999 /* old-style leaf marker OIDs */
3000 if (UATLeafMarkerOID
) {
3001 add_leaf_prod_qa_markers(options
, leafMarkerOID
, UATLeafMarkerOID
);
3003 add_leaf_marker(options
, leafMarkerOID
);
3006 /* new-style leaf marker OIDs */
3007 CFStringRef leafMarkerOIDStr
= NULL
, UATLeafMarkerOIDStr
= NULL
;
3008 leafMarkerOIDStr
= SecDERItemCopyOIDDecimalRepresentation(NULL
, leafMarkerOID
);
3009 if (UATLeafMarkerOID
) {
3010 UATLeafMarkerOIDStr
= SecDERItemCopyOIDDecimalRepresentation(NULL
, UATLeafMarkerOID
);
3013 if (leafMarkerOIDStr
&& UATLeafMarkerOIDStr
) {
3014 add_leaf_prod_qa_markers_value_string(options
,
3015 CFSTR("1.2.840.113635.100.6.48.1"), leafMarkerOIDStr
,
3016 CFSTR("1.2.840.113635.100.6.48.1"), UATLeafMarkerOIDStr
);
3017 } else if (leafMarkerOIDStr
) {
3018 add_leaf_marker_value_string(options
, CFSTR("1.2.840.113635.100.6.48.1"), leafMarkerOIDStr
);
3021 CFReleaseNull(leafMarkerOIDStr
);
3022 CFReleaseNull(UATLeafMarkerOIDStr
);
3024 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleServerAuthentication
);
3027 /* Check for weak hashes and keys */
3028 require(SecPolicyRemoveWeakHashOptions(options
), errOut
);
3029 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
3031 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
3033 result
= SecPolicyCreate(policyOID
, service
, options
);
3034 require(result
, errOut
);
3037 CFReleaseSafe(appleAnchorOptions
);
3038 CFReleaseSafe(options
);
3040 CFReleaseSafe(uatoid
);
3045 @function SecPolicyCreateAppleIDSService
3046 @abstract Ensure we're appropriately pinned to the IDS service (SSL + Apple restrictions)
3048 SecPolicyRef
SecPolicyCreateAppleIDSService(CFStringRef hostname
)
3050 SecPolicyRef result
= SecPolicyCreateSSL(true, hostname
);
3052 SecPolicySetOid(result
, kSecPolicyAppleIDSService
);
3053 SecPolicySetName(result
, kSecPolicyNameAppleIDSBag
);
3059 @function SecPolicyCreateAppleIDSService
3060 @abstract Ensure we're appropriately pinned to the IDS service (SSL + Apple restrictions)
3062 SecPolicyRef
SecPolicyCreateAppleIDSServiceContext(CFStringRef hostname
, CFDictionaryRef context
)
3064 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyAppleIDSServiceContext
,
3065 kSecPolicyNameAppleIDSService
,
3066 &oidAppleCertExtAppleServerAuthenticationIDSProd
,
3067 &oidAppleCertExtAppleServerAuthenticationIDSProdQA
);
3071 @function SecPolicyCreateAppleGSService
3072 @abstract Ensure we're appropriately pinned to the GS service
3074 SecPolicyRef
SecPolicyCreateAppleGSService(CFStringRef hostname
, CFDictionaryRef context
)
3076 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyAppleGSService
,
3077 kSecPolicyNameAppleGSService
,
3078 &oidAppleCertExtAppleServerAuthenticationGS
,
3083 @function SecPolicyCreateApplePushService
3084 @abstract Ensure we're appropriately pinned to the Push service (SSL + Apple restrictions)
3086 SecPolicyRef
SecPolicyCreateApplePushService(CFStringRef hostname
, CFDictionaryRef context
)
3088 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyApplePushService
,
3089 kSecPolicyNameApplePushService
,
3090 &oidAppleCertExtAppleServerAuthenticationAPNProd
,
3091 &oidAppleCertExtAppleServerAuthenticationAPNProdQA
);
3095 @function SecPolicyCreateApplePPQService
3096 @abstract Ensure we're appropriately pinned to the PPQ service (SSL + Apple restrictions)
3098 SecPolicyRef
SecPolicyCreateApplePPQService(CFStringRef hostname
, CFDictionaryRef context
)
3100 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyApplePPQService
,
3101 kSecPolicyNameApplePPQService
,
3102 &oidAppleCertExtAppleServerAuthenticationPPQProd
,
3103 &oidAppleCertExtAppleServerAuthenticationPPQProdQA
);
3107 @function SecPolicyCreateAppleAST2Service
3108 @abstract Ensure we're appropriately pinned to the AST2 Diagnostic service (SSL + Apple restrictions)
3110 SecPolicyRef
SecPolicyCreateAppleAST2Service(CFStringRef hostname
, CFDictionaryRef context
)
3112 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyAppleAST2DiagnosticsServerAuth
,
3113 kSecPolicyNameAppleAST2Service
,
3114 &oidAppleCertExtAST2DiagnosticsServerAuthProd
,
3115 &oidAppleCertExtAST2DiagnosticsServerAuthProdQA
);
3119 @function SecPolicyCreateAppleEscrowProxyService
3120 @abstract Ensure we're appropriately pinned to the iCloud Escrow Proxy service (SSL + Apple restrictions)
3122 SecPolicyRef
SecPolicyCreateAppleEscrowProxyService(CFStringRef hostname
, CFDictionaryRef context
)
3124 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyAppleEscrowProxyServerAuth
,
3125 kSecPolicyNameAppleEscrowProxyService
,
3126 &oidAppleCertExtEscrowProxyServerAuthProd
,
3127 &oidAppleCertExtEscrowProxyServerAuthProdQA
);
3130 /* subject:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA */
3131 /* SKID: C0:7A:98:68:8D:89:FB:AB:05:64:0C:11:7D:AA:7D:65:B8:CA:CC:4E */
3132 /* Not Before: May 21 04:00:00 2002 GMT, Not After : May 21 04:00:00 2022 GMT */
3133 /* Signature Algorithm: sha1WithRSAEncryption */
3134 unsigned char GeoTrust_Global_CA_sha256
[kSecPolicySHA256Size
] = {
3135 0xff, 0x85, 0x6a, 0x2d, 0x25, 0x1d, 0xcd, 0x88, 0xd3, 0x66, 0x56, 0xf4, 0x50, 0x12, 0x67, 0x98,
3136 0xcf, 0xab, 0xaa, 0xde, 0x40, 0x79, 0x9c, 0x72, 0x2d, 0xe4, 0xd2, 0xb5, 0xdb, 0x36, 0xa7, 0x3a
3139 static SecPolicyRef
SecPolicyCreateAppleGeoTrustServerAuthCommon(CFStringRef hostname
, CFStringRef policyOid
,
3140 CFStringRef policyName
,
3141 CFStringRef leafMarkerOid
,
3142 CFStringRef qaLeafMarkerOid
) {
3143 CFMutableDictionaryRef options
= NULL
;
3144 CFDataRef spkiDigest
= NULL
;
3145 SecPolicyRef result
= NULL
;
3147 require(options
= CFDictionaryCreateMutable(NULL
, 0, &kCFTypeDictionaryKeyCallBacks
,
3148 &kCFTypeDictionaryValueCallBacks
), errOut
);
3151 SecPolicyAddBasicX509Options(options
);
3153 require(hostname
, errOut
);
3154 CFDictionaryAddValue(options
, kSecPolicyCheckSSLHostname
, hostname
);
3156 add_eku(options
, &oidExtendedKeyUsageServerAuth
);
3159 if (requireUATPinning(policyName
)) {
3161 SecPolicyAddAnchorSHA256Options(options
, GeoTrust_Global_CA_sha256
);
3163 /* Issued to Apple Inc. in the US */
3164 add_element(options
, kSecPolicyCheckIntermediateCountry
, CFSTR("US"));
3165 add_element(options
, kSecPolicyCheckIntermediateOrganization
, CFSTR("Apple Inc."));
3167 require_action(SecPolicyAddChainLengthOptions(options
, 3), errOut
, CFReleaseNull(result
));
3169 /* Marker OIDs in both formats */
3170 if (qaLeafMarkerOid
) {
3171 add_leaf_prod_qa_markers_string(options
, leafMarkerOid
, qaLeafMarkerOid
);
3172 add_leaf_prod_qa_markers_value_string(options
,
3173 CFSTR("1.2.840.113635.100.6.48.1"), leafMarkerOid
,
3174 CFSTR("1.2.840.113635.100.6.48.1"), qaLeafMarkerOid
);
3176 add_leaf_marker_string(options
, leafMarkerOid
);
3177 add_leaf_marker_value_string(options
, CFSTR("1.2.840.113635.100.6.48.1"), leafMarkerOid
);
3181 /* Check for weak hashes */
3182 require(SecPolicyRemoveWeakHashOptions(options
), errOut
);
3183 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
3185 /* See <rdar://25344801> for more details */
3187 result
= SecPolicyCreate(policyOid
, policyName
, options
);
3190 CFReleaseSafe(options
);
3191 CFReleaseSafe(spkiDigest
);
3195 SecPolicyRef
SecPolicyCreateAppleCompatibilityEscrowProxyService(CFStringRef hostname
) {
3196 return SecPolicyCreateAppleGeoTrustServerAuthCommon(hostname
, kSecPolicyAppleEscrowProxyCompatibilityServerAuth
,
3197 kSecPolicyNameAppleEscrowProxyService
,
3198 CFSTR("1.2.840.113635.100.6.27.7.2"),
3199 CFSTR("1.2.840.113635.100.6.27.7.1"));
3203 @function SecPolicyCreateAppleFMiPService
3204 @abstract Ensure we're appropriately pinned to the Find My iPhone service (SSL + Apple restrictions)
3206 SecPolicyRef
SecPolicyCreateAppleFMiPService(CFStringRef hostname
, CFDictionaryRef context
)
3208 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyAppleFMiPServerAuth
,
3209 kSecPolicyNameAppleFMiPService
,
3210 &oidAppleCertExtFMiPServerAuthProd
,
3211 &oidAppleCertExtFMiPServerAuthProdQA
);
3215 /* should use verbatim copy, but since this is the deprecated way, don't care right now */
3216 static const UInt8 entrustSPKIL1C
[kSecPolicySHA256Size
] = {
3217 0x54, 0x5b, 0xf9, 0x35, 0xe9, 0xad, 0xa1, 0xda,
3218 0x11, 0x7e, 0xdc, 0x3c, 0x2a, 0xcb, 0xc5, 0x6f,
3219 0xc0, 0x28, 0x09, 0x6c, 0x0e, 0x24, 0xbe, 0x9b,
3220 0x38, 0x94, 0xbe, 0x52, 0x2d, 0x1b, 0x43, 0xde
3224 @function SecPolicyCreateApplePushServiceLegacy
3225 @abstract Ensure we're appropriately pinned to the Push service (via Entrust)
3227 SecPolicyRef
SecPolicyCreateApplePushServiceLegacy(CFStringRef hostname
)
3229 CFMutableDictionaryRef options
= NULL
;
3230 SecPolicyRef result
= NULL
;
3231 CFDataRef digest
= NULL
;
3233 digest
= CFDataCreateWithBytesNoCopy(kCFAllocatorDefault
, entrustSPKIL1C
, sizeof(entrustSPKIL1C
), kCFAllocatorNull
);
3234 require(digest
, errOut
);
3236 options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0, &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
3237 require(options
, errOut
);
3239 SecPolicyAddBasicX509Options(options
);
3241 CFDictionaryAddValue(options
, kSecPolicyCheckSSLHostname
, hostname
);
3243 CFDictionaryAddValue(options
, kSecPolicyCheckBlackListedLeaf
, kCFBooleanTrue
);
3244 CFDictionaryAddValue(options
, kSecPolicyCheckGrayListedLeaf
, kCFBooleanTrue
);
3246 CFDictionaryAddValue(options
, kSecPolicyCheckIntermediateSPKISHA256
, digest
);
3248 add_eku(options
, &oidExtendedKeyUsageServerAuth
);
3250 /* Check for weak hashes and keys */
3251 require(SecPolicyRemoveWeakHashOptions(options
), errOut
);
3252 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
3254 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
3256 result
= SecPolicyCreate(kSecPolicyAppleLegacyPushService
,
3257 kSecPolicyNameLegacyPushService
, options
);
3258 require(result
, errOut
);
3261 CFReleaseSafe(digest
);
3262 CFReleaseSafe(options
);
3267 @function SecPolicyCreateAppleMMCSService
3268 @abstract Ensure we're appropriately pinned to the IDS service (SSL + Apple restrictions)
3270 SecPolicyRef
SecPolicyCreateAppleMMCSService(CFStringRef hostname
, CFDictionaryRef context
)
3272 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyAppleMMCService
,
3273 kSecPolicyNameAppleMMCSService
,
3274 &oidAppleCertExtAppleServerAuthenticationMMCSProd
,
3275 &oidAppleCertExtAppleServerAuthenticationMMCSProdQA
);
3278 SecPolicyRef
SecPolicyCreateAppleCompatibilityMMCSService(CFStringRef hostname
) {
3279 return SecPolicyCreateAppleGeoTrustServerAuthCommon(hostname
, kSecPolicyAppleMMCSCompatibilityServerAuth
,
3280 kSecPolicyNameAppleMMCSService
,
3281 CFSTR("1.2.840.113635.100.6.27.11.2"),
3282 CFSTR("1.2.840.113635.100.6.27.11.1"));
3286 SecPolicyRef
SecPolicyCreateAppleiCloudSetupService(CFStringRef hostname
, CFDictionaryRef context
)
3288 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyAppleiCloudSetupServerAuth
,
3289 kSecPolicyNameAppleiCloudSetupService
,
3290 &oidAppleCertExtAppleServerAuthenticationiCloudSetupProd
,
3291 &oidAppleCertExtAppleServerAuthenticationiCloudSetupProdQA
);
3294 SecPolicyRef
SecPolicyCreateAppleCompatibilityiCloudSetupService(CFStringRef hostname
)
3296 return SecPolicyCreateAppleGeoTrustServerAuthCommon(hostname
, kSecPolicyAppleiCloudSetupCompatibilityServerAuth
,
3297 kSecPolicyNameAppleiCloudSetupService
,
3298 CFSTR("1.2.840.113635.100.6.27.15.2"),
3299 CFSTR("1.2.840.113635.100.6.27.15.1"));
3303 @function SecPolicyCreateAppleSSLService
3304 @abstract Ensure we're appropriately pinned to an Apple server (SSL + Apple restrictions)
3306 SecPolicyRef
SecPolicyCreateAppleSSLService(CFStringRef hostname
)
3308 // SSL server, pinned to an Apple intermediate
3309 SecPolicyRef policy
= SecPolicyCreateSSL(true, hostname
);
3310 CFMutableDictionaryRef options
= NULL
;
3311 require(policy
, errOut
);
3313 // change options for SSL policy evaluation
3314 require((options
=(CFMutableDictionaryRef
)policy
->_options
) != NULL
, errOut
);
3316 // Apple CA anchored
3317 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameServerAuthentication
), errOut
);
3319 // Check leaf for Apple Server Authentication marker oid (1.2.840.113635.100.6.27.1)
3320 add_leaf_marker(options
, &oidAppleCertExtAppleServerAuthentication
);
3322 // Check intermediate for Apple Server Authentication intermediate marker (1.2.840.113635.100.6.2.12)
3323 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleServerAuthentication
);
3325 /* Check for weak hashes */
3326 require(SecPolicyRemoveWeakHashOptions(options
), errOut
);
3328 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
3330 SecPolicySetOid(policy
, kSecPolicyAppleServerAuthentication
);
3331 SecPolicySetName(policy
, kSecPolicyNameServerAuthentication
);
3336 CFReleaseSafe(options
);
3337 CFReleaseSafe(policy
);
3342 @function SecPolicyCreateApplePPQSigning
3343 @abstract Check for intermediate certificate 'Apple System Integration 2 Certification Authority' by name,
3345 Leaf cert must have Digital Signature usage.
3346 Leaf cert must have Apple PPQ Signing marker OID (1.2.840.113635.100.6.38.2).
3347 Intermediate must have marker OID (1.2.840.113635.100.6.2.10).
3349 SecPolicyRef
SecPolicyCreateApplePPQSigning(void)
3351 SecPolicyRef result
= NULL
;
3352 CFMutableDictionaryRef options
= NULL
;
3353 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3354 &kCFTypeDictionaryKeyCallBacks
,
3355 &kCFTypeDictionaryValueCallBacks
), errOut
);
3356 SecPolicyAddBasicCertOptions(options
);
3358 SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNamePPQSigning
);
3359 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3361 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
3362 CFSTR("Apple System Integration 2 Certification Authority"));
3364 // Check that leaf has extension with "Apple PPQ Signing" prod oid (1.2.840.113635.100.6.38.2)
3365 add_leaf_marker(options
, &oidAppleCertExtApplePPQSigningProd
);
3367 // Check that intermediate has extension (1.2.840.113635.100.6.2.10)
3368 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleSystemIntg2
);
3370 add_ku(options
, kSecKeyUsageDigitalSignature
);
3372 require(result
= SecPolicyCreate(kSecPolicyApplePPQSigning
,
3373 kSecPolicyNamePPQSigning
, options
), errOut
);
3376 CFReleaseSafe(options
);
3381 @function SecPolicyCreateTestApplePPQSigning
3382 @abstract Check for intermediate certificate 'Apple System Integration 2 Certification Authority' by name,
3384 Leaf cert must have Digital Signature usage.
3385 Leaf cert must have Apple PPQ Signing Test marker OID (1.2.840.113635.100.6.38.1).
3386 Intermediate must have marker OID (1.2.840.113635.100.6.2.10).
3388 SecPolicyRef
SecPolicyCreateTestApplePPQSigning(void)
3390 /* Guard against use of test policy on production devices */
3391 if (!SecIsInternalRelease()) {
3392 return SecPolicyCreateApplePPQSigning();
3395 SecPolicyRef result
= NULL
;
3396 CFMutableDictionaryRef options
= NULL
;
3397 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3398 &kCFTypeDictionaryKeyCallBacks
,
3399 &kCFTypeDictionaryValueCallBacks
), errOut
);
3400 SecPolicyAddBasicCertOptions(options
);
3402 SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameTestPPQSigning
);
3403 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3405 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
3406 CFSTR("Apple System Integration 2 Certification Authority"));
3408 // Check that leaf has extension with "Apple PPQ Signing" test oid (1.2.840.113635.100.6.38.1)
3409 add_leaf_marker(options
, &oidAppleCertExtApplePPQSigningProdQA
);
3411 // Check that intermediate has extension (1.2.840.113635.100.6.2.10)
3412 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleSystemIntg2
);
3414 add_ku(options
, kSecKeyUsageDigitalSignature
);
3416 require(result
= SecPolicyCreate(kSecPolicyAppleTestPPQSigning
,
3417 kSecPolicyNameTestPPQSigning
, options
), errOut
);
3420 CFReleaseSafe(options
);
3424 @function SecPolicyCreateAppleTimeStamping
3425 @abstract Check for RFC3161 timestamping EKU.
3427 SecPolicyRef
SecPolicyCreateAppleTimeStamping(void)
3429 SecPolicyRef result
= NULL
;
3430 CFMutableDictionaryRef options
= NULL
;
3431 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3432 &kCFTypeDictionaryKeyCallBacks
,
3433 &kCFTypeDictionaryValueCallBacks
), errOut
);
3435 SecPolicyAddBasicX509Options(options
);
3437 /* Require id-kp-timeStamping extendedKeyUsage to be present. */
3438 add_eku(options
, &oidExtendedKeyUsageTimeStamping
);
3440 require(result
= SecPolicyCreate(kSecPolicyAppleTimeStamping
,
3441 kSecPolicyNameTimeStamping
, options
), errOut
);
3444 CFReleaseSafe(options
);
3449 @function SecPolicyCreateApplePayIssuerEncryption
3450 @abstract Check for intermediate certificate 'Apple Worldwide Developer Relations CA - G2' by name,
3451 and ECC apple anchor.
3452 Leaf cert must have Key Encipherment and Key Agreement usage.
3453 Leaf cert must have Apple Pay Issuer Encryption marker OID (1.2.840.113635.100.6.39).
3455 SecPolicyRef
SecPolicyCreateApplePayIssuerEncryption(void)
3457 SecPolicyRef result
= NULL
;
3458 CFMutableDictionaryRef options
= NULL
;
3459 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3460 &kCFTypeDictionaryKeyCallBacks
,
3461 &kCFTypeDictionaryValueCallBacks
), errOut
);
3462 SecPolicyAddBasicCertOptions(options
);
3464 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNamePayIssuerEncryption
),
3466 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3468 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
3469 CFSTR("Apple Worldwide Developer Relations CA - G2"));
3471 // Check that leaf has extension with "Apple Pay Issuer Encryption" oid (1.2.840.113635.100.6.39)
3472 add_leaf_marker(options
, &oidAppleCertExtCryptoServicesExtEncryption
);
3474 add_ku(options
, kSecKeyUsageKeyEncipherment
);
3476 require(result
= SecPolicyCreate(kSecPolicyApplePayIssuerEncryption
,
3477 kSecPolicyNamePayIssuerEncryption
, options
), errOut
);
3480 CFReleaseSafe(options
);
3485 @function SecPolicyCreateAppleATVVPNProfileSigning
3486 @abstract Check for leaf marker OID 1.2.840.113635.100.6.43,
3487 intermediate marker OID 1.2.840.113635.100.6.2.10,
3488 chains to Apple Root CA, path length 3
3490 SecPolicyRef
SecPolicyCreateAppleATVVPNProfileSigning(void)
3492 SecPolicyRef result
= NULL
;
3493 CFMutableDictionaryRef options
= NULL
;
3494 CFMutableDictionaryRef appleAnchorOptions
= NULL
;
3495 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3496 &kCFTypeDictionaryKeyCallBacks
,
3497 &kCFTypeDictionaryValueCallBacks
), errOut
);
3499 SecPolicyAddBasicCertOptions(options
);
3501 // Require pinning to the Apple CAs (including test CA for internal releases)
3502 appleAnchorOptions
= CFDictionaryCreateMutableForCFTypes(NULL
);
3503 require(appleAnchorOptions
, errOut
);
3505 if (SecIsInternalRelease()) {
3506 CFDictionarySetValue(appleAnchorOptions
,
3507 kSecPolicyAppleAnchorIncludeTestRoots
, kCFBooleanTrue
);
3510 add_element(options
, kSecPolicyCheckAnchorApple
, appleAnchorOptions
);
3512 // Cert chain length 3
3513 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3515 // Check leaf for Apple ATV VPN Profile Signing OID (1.2.840.113635.100.6.43)
3516 add_leaf_marker(options
, &oidAppleCertExtATVVPNProfileSigning
);
3518 // Check intermediate for Apple System Integration 2 CA intermediate marker (1.2.840.113635.100.6.2.10)
3519 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleSystemIntg2
);
3521 // Ensure that revocation is checked (OCSP only)
3522 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationOCSP
);
3524 require(result
= SecPolicyCreate(kSecPolicyAppleATVVPNProfileSigning
,
3525 kSecPolicyNameATVVPNProfileSigning
, options
), errOut
);
3528 CFReleaseSafe(options
);
3529 CFReleaseSafe(appleAnchorOptions
);
3533 SecPolicyRef
SecPolicyCreateAppleHomeKitServerAuth(CFStringRef hostname
) {
3534 CFMutableDictionaryRef appleAnchorOptions
= NULL
;
3535 CFMutableDictionaryRef options
= NULL
;
3536 SecPolicyRef result
= NULL
;
3537 CFDataRef oid
= NULL
;
3539 options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0, &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
3540 require(options
, errOut
);
3542 SecPolicyAddBasicX509Options(options
);
3544 CFDictionaryAddValue(options
, kSecPolicyCheckSSLHostname
, hostname
);
3546 add_eku(options
, &oidExtendedKeyUsageServerAuth
);
3548 if (requireUATPinning(kSecPolicyNameAppleHomeKitService
)) {
3550 // Cert chain length 3
3551 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3553 // Apple anchors, allowing test anchors for internal release
3554 SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameAppleHomeKitService
);
3556 add_leaf_marker(options
, &oidAppleCertExtHomeKitServerAuth
);
3558 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleHomeKitServerCA
);
3561 /* Check for weak hashes */
3562 require(SecPolicyRemoveWeakHashOptions(options
), errOut
);
3563 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
3565 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
3567 result
= SecPolicyCreate(kSecPolicyAppleHomeKitServerAuth
,
3568 kSecPolicyNameAppleHomeKitService
, options
);
3569 require(result
, errOut
);
3572 CFReleaseSafe(appleAnchorOptions
);
3573 CFReleaseSafe(options
);
3578 SecPolicyRef
SecPolicyCreateAppleExternalDeveloper(void) {
3579 CFMutableDictionaryRef options
= NULL
;
3580 SecPolicyRef result
= NULL
;
3582 /* Create basic Apple pinned policy */
3583 require(result
= SecPolicyCreateApplePinned(kSecPolicyNameExternalDeveloper
,
3584 CFSTR("1.2.840.113635.100.6.2.1"), // WWDR Intermediate OID
3585 CFSTR("1.2.840.113635.100.6.1.2")), // "iPhone Developer" leaf OID
3588 require_action(options
= CFDictionaryCreateMutableCopy(NULL
, 0, result
->_options
), errOut
, CFReleaseNull(result
));
3590 /* Additional intermediate OIDs */
3591 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
,
3592 CFSTR("1.2.840.113635.100.6.2.6")); // "Developer ID" Intermediate OID
3594 /* Addtional leaf OIDS */
3595 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.4")); // "iPhone Distribution" leaf OID
3596 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.5")); // "Safari Developer" leaf OID
3597 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.7")); // "3rd Party Mac Developer Application" leaf OID
3598 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.8")); // "3rd Party Mac Developer Installer" leaf OID
3599 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.12")); // "Mac Developer" leaf OID
3600 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.13")); // "Developer ID Application" leaf OID
3601 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.14")); // "Developer ID Installer" leaf OID
3604 add_eku_string(options
, CFSTR("1.3.6.1.5.5.7.3.3")); // CodeSigning EKU
3605 add_eku_string(options
, CFSTR("1.2.840.113635.100.4.8")); // "Safari Developer" EKU
3606 add_eku_string(options
, CFSTR("1.2.840.113635.100.4.9")); // "3rd Party Mac Developer Installer" EKU
3607 add_eku_string(options
, CFSTR("1.2.840.113635.100.4.13")); // "Developer ID Installer" EKU
3609 CFReleaseSafe(result
->_options
);
3610 result
->_options
= CFRetainSafe(options
);
3612 SecPolicySetOid(result
, kSecPolicyAppleExternalDeveloper
);
3615 CFReleaseSafe(options
);
3619 /* This one is special because the intermediate has no marker OID */
3620 SecPolicyRef
SecPolicyCreateAppleSoftwareSigning(void) {
3621 CFMutableDictionaryRef options
= NULL
;
3622 CFDictionaryRef keySizes
= NULL
;
3623 CFNumberRef rsaSize
= NULL
, ecSize
= NULL
;
3624 SecPolicyRef result
= NULL
;
3626 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3627 &kCFTypeDictionaryKeyCallBacks
,
3628 &kCFTypeDictionaryValueCallBacks
), errOut
);
3630 SecPolicyAddBasicCertOptions(options
);
3632 /* Anchored to the Apple Roots */
3633 require_quiet(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameSoftwareSigning
),
3636 /* Exactly 3 certs in the chain */
3637 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3639 /* Intermediate Common Name matches */
3640 add_element(options
, kSecPolicyCheckIssuerCommonName
, CFSTR("Apple Code Signing Certification Authority"));
3642 /* Leaf marker OID matches */
3643 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.22"));
3645 /* Leaf has CodeSigning EKU */
3646 add_eku_string(options
, CFSTR("1.3.6.1.5.5.7.3.3"));
3648 /* Check revocation using any available method */
3649 add_element(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
3651 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
3652 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
3654 require(result
= SecPolicyCreate(kSecPolicyAppleSoftwareSigning
,
3655 kSecPolicyNameSoftwareSigning
, options
), errOut
);
3658 CFReleaseSafe(options
);
3659 CFReleaseSafe(keySizes
);
3660 CFReleaseSafe(rsaSize
);
3661 CFReleaseSafe(ecSize
);
3665 /* subject:/CN=SEP Root CA/O=Apple Inc./ST=California */
3666 /* SKID: 58:EF:D6:BE:C5:82:B0:54:CD:18:A6:84:AD:A2:F6:7B:7B:3A:7F:CF */
3667 /* Not Before: Jun 24 21:43:24 2014 GMT, Not After : Jun 24 21:43:24 2029 GMT */
3668 /* Signature Algorithm: ecdsa-with-SHA384 */
3669 const uint8_t SEPRootCA_SHA256
[kSecPolicySHA256Size
] = {
3670 0xd1, 0xdf, 0x82, 0x00, 0xf3, 0x89, 0x4e, 0xe9, 0x96, 0xf3, 0x77, 0xdf, 0x76, 0x3b, 0x0a, 0x16,
3671 0x8f, 0xd9, 0x6c, 0x58, 0xc0, 0x3e, 0xc9, 0xb0, 0x5f, 0xa5, 0x64, 0x79, 0xc0, 0xe8, 0xc9, 0xe7
3674 SecPolicyRef
SecPolicyCreateAppleUniqueDeviceCertificate(CFDataRef testRootHash
) {
3675 CFMutableDictionaryRef options
= NULL
;
3676 CFDictionaryRef keySizes
= NULL
;
3677 CFNumberRef ecSize
= NULL
;
3678 SecPolicyRef result
= NULL
;
3680 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3681 &kCFTypeDictionaryKeyCallBacks
,
3682 &kCFTypeDictionaryValueCallBacks
), errOut
);
3684 /* Device certificate should never expire */
3685 SecPolicyAddBasicCertOptions(options
);
3687 /* Anchored to the SEP Root CA. Allow alternative root for developers */
3688 require(SecPolicyAddAnchorSHA256Options(options
, SEPRootCA_SHA256
),errOut
);
3689 if (testRootHash
&& SecIsInternalRelease() && (kSecPolicySHA256Size
== CFDataGetLength(testRootHash
))) {
3690 add_element(options
, kSecPolicyCheckAnchorSHA256
, testRootHash
);
3693 /* Exactly 3 certs in the chain */
3694 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3696 /* Intermediate has marker OID with value */
3697 add_intermediate_marker_value_string(options
, CFSTR("1.2.840.113635.100.6.44"), CFSTR("ucrt"));
3699 /* Leaf has marker OID with varying value that can't be pre-determined */
3700 add_element(options
, kSecPolicyCheckLeafMarkerOidWithoutValueCheck
, CFSTR("1.2.840.113635.100.10.1"));
3702 /* RSA key sizes are disallowed. EC key sizes are P-256 or larger. */
3703 require(ecSize
= CFNumberCreateWithCFIndex(NULL
, 256), errOut
);
3704 require(keySizes
= CFDictionaryCreate(NULL
, (const void**)&kSecAttrKeyTypeEC
,
3705 (const void**)&ecSize
, 1,
3706 &kCFTypeDictionaryKeyCallBacks
,
3707 &kCFTypeDictionaryValueCallBacks
), errOut
);
3708 add_element(options
, kSecPolicyCheckKeySize
, keySizes
);
3711 require(result
= SecPolicyCreate(kSecPolicyAppleUniqueDeviceIdentifierCertificate
,
3712 kSecPolicyNameUniqueDeviceIdentifierCertificate
, options
), errOut
);
3715 CFReleaseSafe(options
);
3716 CFReleaseSafe(keySizes
);
3717 CFReleaseSafe(ecSize
);
3721 SecPolicyRef
SecPolicyCreateAppleWarsaw(void) {
3722 CFMutableDictionaryRef options
= NULL
;
3723 SecPolicyRef result
= NULL
;
3724 #if TARGET_OS_BRIDGE
3725 CFMutableDictionaryRef appleAnchorOptions
= NULL
;
3728 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3729 &kCFTypeDictionaryKeyCallBacks
,
3730 &kCFTypeDictionaryValueCallBacks
), errOut
);
3732 SecPolicyAddBasicX509Options(options
);
3734 /* Anchored to the Apple Roots. */
3735 require_quiet(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameWarsaw
),
3738 /* Exactly 3 certs in the chain */
3739 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3741 /* Intermediate marker OID matches input OID */
3742 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.14"));
3744 /* Leaf marker OID matches input OID */
3745 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.29"));
3747 /* Check revocation using any available method */
3748 add_element(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
3750 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
3751 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
3753 require(result
= SecPolicyCreate(kSecPolicyAppleWarsaw
,
3754 kSecPolicyNameWarsaw
, options
), errOut
);
3757 CFReleaseSafe(options
);
3761 SecPolicyRef
SecPolicyCreateAppleSecureIOStaticAsset(void) {
3762 CFMutableDictionaryRef options
= NULL
;
3763 SecPolicyRef result
= NULL
;
3764 #if TARGET_OS_BRIDGE
3765 CFMutableDictionaryRef appleAnchorOptions
= NULL
;
3768 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3769 &kCFTypeDictionaryKeyCallBacks
,
3770 &kCFTypeDictionaryValueCallBacks
), errOut
);
3772 /* This certificate cannot expire so that assets always load */
3773 SecPolicyAddBasicCertOptions(options
);
3775 /* Anchored to the Apple Roots. */
3776 #if TARGET_OS_BRIDGE
3777 /* On the bridge, test roots are gated in the trust and policy servers. */
3778 require_quiet(appleAnchorOptions
= CFDictionaryCreateMutableForCFTypes(NULL
), errOut
);
3779 CFDictionarySetValue(appleAnchorOptions
,
3780 kSecPolicyAppleAnchorIncludeTestRoots
, kCFBooleanTrue
);
3781 add_element(options
, kSecPolicyCheckAnchorApple
, appleAnchorOptions
);
3782 CFReleaseSafe(appleAnchorOptions
);
3784 require_quiet(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameSecureIOStaticAsset
),
3788 /* Exactly 3 certs in the chain */
3789 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3791 /* Intermediate marker OID matches ASI CA */
3792 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.10"));
3794 /* Leaf marker OID matches static IO OID */
3795 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.50"));
3797 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
3798 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
3800 require(result
= SecPolicyCreate(kSecPolicyAppleSecureIOStaticAsset
,
3801 kSecPolicyNameSecureIOStaticAsset
, options
), errOut
);
3804 CFReleaseSafe(options
);
3808 SecPolicyRef
SecPolicyCreateAppleAppTransportSecurity(void) {
3809 CFMutableDictionaryRef options
= NULL
;
3810 SecPolicyRef result
= NULL
;
3811 CFMutableArrayRef disallowedHashes
= NULL
;
3813 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3814 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
3816 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
3817 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
3819 /* Hash algorithm is SHA-256 or better */
3820 require(disallowedHashes
= CFArrayCreateMutable(NULL
, 5, &kCFTypeArrayCallBacks
), errOut
);
3821 CFArrayAppendValue(disallowedHashes
, kSecSignatureDigestAlgorithmMD2
);
3822 CFArrayAppendValue(disallowedHashes
, kSecSignatureDigestAlgorithmMD4
);
3823 CFArrayAppendValue(disallowedHashes
, kSecSignatureDigestAlgorithmMD5
);
3824 CFArrayAppendValue(disallowedHashes
, kSecSignatureDigestAlgorithmSHA1
);
3825 CFArrayAppendValue(disallowedHashes
, kSecSignatureDigestAlgorithmSHA224
);
3827 add_element(options
, kSecPolicyCheckSignatureHashAlgorithms
, disallowedHashes
);
3829 require_quiet(result
= SecPolicyCreate(kSecPolicyAppleAppTransportSecurity
,
3830 kSecPolicyNameAppTransportSecurity
,
3834 CFReleaseSafe(options
);
3838 SecPolicyRef
SecPolicyCreateMobileSoftwareUpdate(void) {
3839 CFMutableDictionaryRef options
= NULL
;
3840 SecPolicyRef result
= NULL
;
3841 #if TARGET_OS_BRIDGE
3842 CFMutableDictionaryRef appleAnchorOptions
= NULL
;
3845 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3846 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
3848 /* No expiration check. */
3849 SecPolicyAddBasicCertOptions(options
);
3852 require_quiet(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameMobileSoftwareUpdate
),
3855 /* Exactly 3 certs in the chain */
3856 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3858 /* Intermediate marker OID is iPhone CA OID */
3859 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.18"));
3861 /* Leaf marker OID is either the prod MSU OID, or, on internal builds, the prodQA OID */
3862 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.57.2"));
3863 if (SecIsInternalRelease()) {
3864 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.57.1"));
3867 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
3868 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
3870 require(result
= SecPolicyCreate(kSecPolicyAppleMobileSoftwareUpdate
,
3871 kSecPolicyNameMobileSoftwareUpdate
, options
), errOut
);
3874 CFReleaseNull(options
);
3878 /* subject:/CN=Basic Attestation System Root CA/O=Apple Inc./ST=California */
3879 /* SKID: FE:D1:D1:C2:08:07:03:D5:B9:3C:34:B2:BB:FD:7C:3A:99:25:1B:8F */
3880 /* Not Before: Apr 20 00:22:09 2017 GMT, Not After : Mar 22 00:00:00 2032 GMT */
3881 /* Signature Algorithm: ecdsa-with-SHA384 */
3882 const uint8_t BASystemRootCA_SHA256
[kSecPolicySHA256Size
] = {
3883 0x10, 0xD3, 0xC8, 0x67, 0xF0, 0xAE, 0xFB, 0x24, 0x31, 0xA0, 0xA9, 0x7A, 0x88, 0x18, 0xBD, 0x64,
3884 0xF7, 0xF9, 0x0F, 0xFE, 0x11, 0x94, 0x48, 0x4F, 0xCA, 0x97, 0xF0, 0xF2, 0x9E, 0xCA, 0x00, 0x47
3887 /* subject:/CN=Basic Attestation User Root CA/O=Apple Inc./ST=California */
3888 /* SKID: 83:E5:A3:21:9E:B0:74:C3:F9:61:90:FD:97:4E:23:10:76:A4:A3:F2 */
3889 /* Not Before: Apr 19 21:41:56 2017 GMT, Not After : Mar 22 00:00:00 2032 GMT */
3890 /* Signature Algorithm: ecdsa-with-SHA384 */
3891 const uint8_t BAUserRootCA_SHA256
[kSecPolicySHA256Size
] = {
3892 0x03, 0x75, 0x1c, 0x80, 0xfc, 0xbe, 0x58, 0x19, 0xd1, 0x70, 0xd2, 0x67, 0xce, 0x1a, 0xd6, 0xd0,
3893 0x94, 0x40, 0x7c, 0x91, 0xd8, 0x73, 0xd7, 0xa6, 0x56, 0x2d, 0xe3, 0x66, 0x6d, 0x35, 0x94, 0xc6
3896 SecPolicyRef
SecPolicyCreateAppleBasicAttestationSystem(CFDataRef testRootHash
) {
3897 CFMutableDictionaryRef options
= NULL
;
3898 SecPolicyRef result
= NULL
;
3900 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3901 &kCFTypeDictionaryKeyCallBacks
,
3902 &kCFTypeDictionaryValueCallBacks
), errOut
);
3903 /* BAA certs expire */
3904 SecPolicyAddBasicX509Options(options
);
3906 /* Anchored to one of the Basic Attestation roots. Allow alternative root for developers */
3907 SecPolicyAddAnchorSHA256Options(options
, BASystemRootCA_SHA256
);
3908 if (testRootHash
&& SecIsInternalRelease() && (kSecPolicySHA256Size
== CFDataGetLength(testRootHash
))) {
3909 add_element(options
, kSecPolicyCheckAnchorSHA256
, testRootHash
);
3912 /* Exactly 3 certs in the chain */
3913 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3915 require(result
= SecPolicyCreate(kSecPolicyAppleBasicAttestationSystem
,
3916 kSecPolicyNameBasicAttestationSystem
, options
), errOut
);
3919 CFReleaseSafe(options
);
3923 SecPolicyRef
SecPolicyCreateAppleBasicAttestationUser(CFDataRef testRootHash
) {
3924 CFMutableDictionaryRef options
= NULL
;
3925 SecPolicyRef result
= NULL
;
3927 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3928 &kCFTypeDictionaryKeyCallBacks
,
3929 &kCFTypeDictionaryValueCallBacks
), errOut
);
3930 /* BAA certs expire */
3931 SecPolicyAddBasicX509Options(options
);
3933 /* Anchored to one of the Basic Attestation roots. Allow alternative root for developers */
3934 SecPolicyAddAnchorSHA256Options(options
, BAUserRootCA_SHA256
);
3935 if (testRootHash
&& SecIsInternalRelease() && (kSecPolicySHA256Size
== CFDataGetLength(testRootHash
))) {
3936 add_element(options
, kSecPolicyCheckAnchorSHA256
, testRootHash
);
3939 /* Exactly 3 certs in the chain */
3940 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3942 require(result
= SecPolicyCreate(kSecPolicyAppleBasicAttestationUser
,
3943 kSecPolicyNameBasicAttestationUser
, options
), errOut
);
3946 CFReleaseSafe(options
);
3950 SecPolicyRef
SecPolicyCreateiAPSWAuthWithExpiration(bool checkExpiration
) {
3951 CFMutableDictionaryRef options
= NULL
;
3952 SecPolicyRef result
= NULL
;
3954 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3955 &kCFTypeDictionaryKeyCallBacks
,
3956 &kCFTypeDictionaryValueCallBacks
), errOut
);
3958 /* iAP checks expiration on developement certs, but not on production certs */
3959 if (checkExpiration
) {
3960 SecPolicyAddBasicX509Options(options
);
3962 SecPolicyAddBasicCertOptions(options
);
3965 /* Exactly 2 certs in the chain */
3966 require(SecPolicyAddChainLengthOptions(options
, 2), errOut
);
3968 /* iAP SW Auth General Capabilities Extension present */
3969 add_element(options
, kSecPolicyCheckLeafMarkerOidWithoutValueCheck
, CFSTR("1.2.840.113635.100.6.59.1"));
3971 require(result
= SecPolicyCreate(kSecPolicyAppleiAPSWAuth
,
3972 kSecPolicyNameiAPSWAuth
, options
), errOut
);
3975 CFReleaseSafe(options
);
3979 SecPolicyRef
SecPolicyCreateiAPSWAuth(void) {
3980 /* By default, iAP SW Auth certs don't expire */
3981 return SecPolicyCreateiAPSWAuthWithExpiration(false);
3984 SecPolicyRef
SecPolicyCreateDemoDigitalCatalogSigning(void) {
3985 CFMutableDictionaryRef options
= NULL
;
3986 SecPolicyRef result
= NULL
;
3988 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3989 &kCFTypeDictionaryKeyCallBacks
,
3990 &kCFTypeDictionaryValueCallBacks
), errOut
);
3991 SecPolicyAddBasicX509Options(options
);
3993 /* Exactly 3 certs in the chain */
3994 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3996 /* Demo Signing Extension present in leaf */
3997 add_element(options
, kSecPolicyCheckLeafMarkerOid
, CFSTR("1.2.840.113635.100.6.60"));
3999 /* Issuer common name is "DemoUnit CA" */
4000 add_element(options
, kSecPolicyCheckIssuerCommonName
, CFSTR("DemoUnit CA"));
4002 require(result
= SecPolicyCreate(kSecPolicyAppleDemoDigitalCatalog
,
4003 kSecPolicyNameDemoDigitalCatalog
, options
), errOut
);
4006 CFReleaseSafe(options
);
4010 SecPolicyRef
SecPolicyCreateAppleAssetReceipt(void) {
4011 CFMutableDictionaryRef options
= NULL
;
4012 SecPolicyRef result
= NULL
;
4014 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
4015 &kCFTypeDictionaryKeyCallBacks
,
4016 &kCFTypeDictionaryValueCallBacks
), errOut
);
4018 /* No expiration check. */
4019 SecPolicyAddBasicCertOptions(options
);
4022 require_quiet(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameAssetReceipt
), errOut
);
4024 /* Exactly 3 certs in the chain */
4025 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
4027 /* Intermediate marker OID is Apple System Integration 2 CA */
4028 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.10"));
4030 /* Leaf marker OID is the Asset Receipt OID */
4031 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.61"));
4033 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
4034 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
4036 require(result
= SecPolicyCreate(kSecPolicyAppleAssetReceipt
,
4037 kSecPolicyNameAssetReceipt
, options
), errOut
);
4040 CFReleaseNull(options
);
4044 SecPolicyRef
SecPolicyCreateAppleDeveloperIDPlusTicket(void) {
4045 CFMutableDictionaryRef options
= NULL
;
4046 SecPolicyRef result
= NULL
;
4048 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
4049 &kCFTypeDictionaryKeyCallBacks
,
4050 &kCFTypeDictionaryValueCallBacks
), errOut
);
4052 /* No expiration check. */
4053 SecPolicyAddBasicCertOptions(options
);
4056 require_quiet(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameDeveloperIDPlusTicket
), errOut
);
4058 /* Exactly 3 certs in the chain */
4059 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
4061 /* Intermediate marker OID is Apple System Integration CA 4 */
4062 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.17"));
4064 /* Leaf marker OID is the Developer ID+ Ticket OID */
4065 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.30"));
4067 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
4068 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
4070 require(result
= SecPolicyCreate(kSecPolicyAppleDeveloperIDPlusTicket
,
4071 kSecPolicyNameDeveloperIDPlusTicket
, options
), errOut
);
4074 CFReleaseNull(options
);
4078 SecPolicyRef
SecPolicyCreateAppleFDRProvisioning(void) {
4079 CFMutableDictionaryRef options
= NULL
;
4080 SecPolicyRef result
= NULL
;
4082 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
4083 &kCFTypeDictionaryKeyCallBacks
,
4084 &kCFTypeDictionaryValueCallBacks
), errOut
);
4086 /* No expiration check. */
4087 SecPolicyAddBasicCertOptions(options
);
4089 require(result
= SecPolicyCreate(kSecPolicyAppleFDRProvisioning
,
4090 kSecPolicyNameFDRProvisioning
, options
), errOut
);
4092 CFReleaseNull(options
);
4096 /* subject:/CN=Component Root CA/O=Apple Inc./ST=California */
4097 /* SKID: 90:D1:56:A9:3E:B4:EE:8C:D0:10:4B:9F:17:1C:5B:55:F2:12:F6:4C */
4098 /* Not Before: Dec 19 19:31:54 2018 GMT, Not After : Dec 16 00:00:00 2043 GMT */
4099 /* Signature Algorithm: ecdsa-with-SHA384 */
4100 const uint8_t ComponentRootCA_SHA256
[kSecPolicySHA256Size
] = {
4101 0x2f, 0x71, 0x9d, 0xbf, 0x3c, 0xcd, 0xe7, 0xc2, 0xb2, 0x59, 0x3f, 0x32, 0x1f, 0x90, 0xf3, 0x42,
4102 0x42, 0xaa, 0x84, 0xa1, 0xb2, 0x0d, 0xca, 0xcc, 0x10, 0xc0, 0x5b, 0x26, 0xd6, 0x23, 0xb8, 0x47,
4104 SecPolicyRef
SecPolicyCreateAppleComponentCertificate(CFDataRef testRootHash
) {
4105 CFMutableDictionaryRef options
= NULL
;
4106 SecPolicyRef result
= NULL
;
4108 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
4109 &kCFTypeDictionaryKeyCallBacks
,
4110 &kCFTypeDictionaryValueCallBacks
), errOut
);
4112 /* Component certificates don't expire */
4113 SecPolicyAddBasicCertOptions(options
);
4115 /* Anchored to one of the Component roots. Allow alternative root for developers */
4116 SecPolicyAddAnchorSHA256Options(options
, ComponentRootCA_SHA256
);
4117 if (testRootHash
&& SecIsInternalRelease() && (kSecPolicySHA256Size
== CFDataGetLength(testRootHash
))) {
4118 add_element(options
, kSecPolicyCheckAnchorSHA256
, testRootHash
);
4121 /* Exactly 3 certs in the chain */
4122 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
4124 /* Leaf and intermediate must contain Component Type OID */
4125 add_element(options
, kSecPolicyCheckLeafMarkerOidWithoutValueCheck
, CFSTR("1.2.840.113635.100.11.1"));
4126 add_element(options
, kSecPolicyCheckIntermediateMarkerOidWithoutValueCheck
, CFSTR("1.2.840.113635.100.11.1"));
4128 require(result
= SecPolicyCreate(kSecPolicyAppleComponentCertificate
,
4129 kSecPolicyNameComponentCertificate
, options
), errOut
);
4131 CFReleaseNull(options
);
4135 SecPolicyRef
SecPolicyCreateAppleKeyTransparency(CFStringRef applicationId
) {
4136 CFMutableDictionaryRef options
= NULL
;
4137 SecPolicyRef result
= NULL
;
4139 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
4140 &kCFTypeDictionaryKeyCallBacks
,
4141 &kCFTypeDictionaryValueCallBacks
), errOut
);
4143 /* KT signing certs don't expire */
4144 SecPolicyAddBasicCertOptions(options
);
4147 require_quiet(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameKeyTransparency
), errOut
);
4149 /* Exactly 3 certs in the chain */
4150 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
4152 /* Intermediate marker OID matches AAI CA 5 */
4153 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.3"));
4155 /* Leaf marker extension matches input applicationId */
4156 add_leaf_marker_value_string(options
, CFSTR("1.2.840.113635.100.12.4"), applicationId
);
4158 /* Check revocation using any available method */
4159 add_element(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
4161 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
4162 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
4164 /* Check for weak hashes */
4165 require(SecPolicyRemoveWeakHashOptions(options
), errOut
);
4167 /* Future CT requirement */
4169 require(result
= SecPolicyCreate(kSecPolicyAppleKeyTransparency
,
4170 kSecPolicyNameKeyTransparency
, options
), errOut
);
4172 CFReleaseNull(options
);