2 * Copyright (c) 2007-2017 Apple Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
25 * SecPolicy.c - Implementation of various X.509 certificate trust policies
28 #include <Security/SecPolicyInternal.h>
29 #include <Security/SecPolicyPriv.h>
30 #include <AssertMacros.h>
32 #include <utilities/debugging.h>
33 #include <Security/SecInternal.h>
34 #include <CoreFoundation/CFDictionary.h>
35 #include <CoreFoundation/CFNumber.h>
36 #include <CoreFoundation/CFRuntime.h>
37 #include <CoreFoundation/CFString.h>
38 #include <CoreFoundation/CFTimeZone.h>
39 #include <Security/SecCertificateInternal.h>
40 #include <Security/SecCertificatePriv.h>
41 #include <Security/SecItem.h>
42 #include <libDER/oids.h>
43 #include <utilities/SecCFError.h>
44 #include <utilities/SecCFWrappers.h>
45 #include <utilities/array_size.h>
46 #include <ipc/securityd_client.h>
48 #include <utilities/SecInternalReleasePriv.h>
50 #undef POLICYCHECKMACRO
51 #define POLICYCHECKMACRO(NAME, TRUSTRESULT, SUBTYPE, LEAFCHECK, PATHCHECK, LEAFONLY, CSSMERR, OSSTATUS) \
52 const CFStringRef kSecPolicyCheck##NAME = CFSTR(#NAME);
53 #include "SecPolicyChecks.list"
55 #define SEC_CONST_DECL(k,v) const CFStringRef k = CFSTR(v);
57 /********************************************************
58 ******************* Feature toggles ********************
59 ********************************************************/
60 /* Option for AnchorApple */
61 SEC_CONST_DECL (kSecPolicyAppleAnchorIncludeTestRoots
, "AnchorAppleTestRoots");
63 /* options for kSecPolicyCheckLeafMarkersProdAndQA */
64 SEC_CONST_DECL (kSecPolicyLeafMarkerProd
, "ProdMarker");
65 SEC_CONST_DECL (kSecPolicyLeafMarkerQA
, "QAMarker");
67 /* Revocation toggles */
68 SEC_CONST_DECL (kSecPolicyCheckRevocationOCSP
, "OCSP");
69 SEC_CONST_DECL (kSecPolicyCheckRevocationCRL
, "CRL");
70 SEC_CONST_DECL (kSecPolicyCheckRevocationAny
, "AnyRevocationMethod");
72 /* Public policy oids. */
73 #define POLICYMACRO(NAME, OID, ISPUBLIC, INTNAME, IN_NAME, IN_PROPERTIES, FUNCTION) \
74 const CFStringRef kSecPolicyApple##NAME = CFSTR("1.2.840.113635.100.1."#OID);
75 #include "SecPolicy.list"
76 //Some naming exceptions
77 SEC_CONST_DECL(kSecPolicyMacAppStoreReceipt
, "1.2.840.113635.100.1.19")
78 SEC_CONST_DECL(kSecPolicyAppleIDValidationRecordSigningPolicy
, "1.2.840.113635.100.1.30");
80 SEC_CONST_DECL (kSecPolicyOid
, "SecPolicyOid");
81 SEC_CONST_DECL (kSecPolicyName
, "SecPolicyName");
82 SEC_CONST_DECL (kSecPolicyClient
, "SecPolicyClient");
83 SEC_CONST_DECL (kSecPolicyRevocationFlags
, "SecPolicyRevocationFlags");
84 SEC_CONST_DECL (kSecPolicyTeamIdentifier
, "SecPolicyTeamIdentifier");
85 SEC_CONST_DECL (kSecPolicyContext
, "SecPolicyContext");
86 SEC_CONST_DECL (kSecPolicyPolicyName
, "SecPolicyPolicyName");
87 SEC_CONST_DECL (kSecPolicyIntermediateMarkerOid
, "SecPolicyIntermediateMarkerOid");
88 SEC_CONST_DECL (kSecPolicyLeafMarkerOid
, "SecPolicyLeafMarkerOid");
89 SEC_CONST_DECL (kSecPolicyRootDigest
, "SecPolicyRootDigest");
91 SEC_CONST_DECL (kSecPolicyKU_DigitalSignature
, "CE_KU_DigitalSignature");
92 SEC_CONST_DECL (kSecPolicyKU_NonRepudiation
, "CE_KU_NonRepudiation");
93 SEC_CONST_DECL (kSecPolicyKU_KeyEncipherment
, "CE_KU_KeyEncipherment");
94 SEC_CONST_DECL (kSecPolicyKU_DataEncipherment
, "CE_KU_DataEncipherment");
95 SEC_CONST_DECL (kSecPolicyKU_KeyAgreement
, "CE_KU_KeyAgreement");
96 SEC_CONST_DECL (kSecPolicyKU_KeyCertSign
, "CE_KU_KeyCertSign");
97 SEC_CONST_DECL (kSecPolicyKU_CRLSign
, "CE_KU_CRLSign");
98 SEC_CONST_DECL (kSecPolicyKU_EncipherOnly
, "CE_KU_EncipherOnly");
99 SEC_CONST_DECL (kSecPolicyKU_DecipherOnly
, "CE_KU_DecipherOnly");
101 /* Internal policy names */
103 #define __P_DO_DECLARE_(NAME, INTNAME) static CFStringRef kSecPolicyName##NAME = CFSTR(#INTNAME);
104 #define __P_DO_DECLARE_E(NAME, INTNAME) static CFStringRef kSecPolicyName##NAME = CFSTR(#INTNAME);
105 #define __P_DO_DECLARE_P(NAME, INTNAME) const CFStringRef kSecPolicyNameApple##NAME = CFSTR(#INTNAME);
106 #define __P_DO_DECLARE_I(NAME, INTNAME) const CFStringRef kSecPolicyName##NAME = CFSTR(#INTNAME);
107 #define POLICYMACRO(NAME, OID, ISPUBLIC, INTNAME, IN_NAME, IN_PROPERTIES, FUNCTION) \
108 __P_DO_DECLARE_##ISPUBLIC(NAME, INTNAME)
109 #include "SecPolicy.list"
110 //Some naming exceptions
111 static CFStringRef kSecPolicyNameAppleIDSBag
= CFSTR("IDSBag");
113 /* External Policy Names
114 * These correspond to the names defined in CertificatePinning.plist
115 * in security_certificates */
116 SEC_CONST_DECL (kSecPolicyNameSSLServer
, "sslServer");
117 SEC_CONST_DECL (kSecPolicyNameSSLClient
, "sslClient");
118 SEC_CONST_DECL (kSecPolicyNameEAPServer
, "eapServer");
119 SEC_CONST_DECL (kSecPolicyNameEAPClient
, "eapClient");
120 SEC_CONST_DECL (kSecPolicyNameIPSecServer
, "ipsecServer");
121 SEC_CONST_DECL (kSecPolicyNameIPSecClient
, "ipsecClient");
122 SEC_CONST_DECL (kSecPolicyNameAppleiCloudSetupService
, "iCloudSetup");
123 SEC_CONST_DECL (kSecPolicyNameAppleMMCSService
, "MMCS");
124 SEC_CONST_DECL (kSecPolicyNameAppleAST2Service
, "AST2");
125 SEC_CONST_DECL (kSecPolicyNameAppleEscrowProxyService
, "Escrow");
126 SEC_CONST_DECL (kSecPolicyNameAppleFMiPService
, "FMiP");
127 SEC_CONST_DECL (kSecPolicyNameAppleHomeKitService
, "HomeKit");
128 SEC_CONST_DECL (kSecPolicyNameAppleAIDCService
, "AIDC");
129 SEC_CONST_DECL (kSecPolicyNameAppleMapsService
, "Maps");
130 SEC_CONST_DECL (kSecPolicyNameAppleHealthProviderService
, "HealthProvider");
131 SEC_CONST_DECL (kSecPolicyNameAppleParsecService
, "Parsec");
132 SEC_CONST_DECL (kSecPolicyNameAppleAMPService
, "AMP");
133 SEC_CONST_DECL (kSecPolicyNameAppleSiriService
, "Siri");
134 SEC_CONST_DECL (kSecPolicyNameAppleHomeAppClipUploadService
, "HomeAppClipUploadService");
135 SEC_CONST_DECL (kSecPolicyNameAppleUpdatesService
, "Updates");
137 #define kSecPolicySHA1Size 20
138 #define kSecPolicySHA256Size 32
139 __unused
const UInt8 kAppleCASHA1
[kSecPolicySHA1Size
] = {
140 0x61, 0x1E, 0x5B, 0x66, 0x2C, 0x59, 0x3A, 0x08, 0xFF, 0x58,
141 0xD1, 0x4A, 0xE2, 0x24, 0x52, 0xD1, 0x98, 0xDF, 0x6C, 0x60
144 __unused
static const UInt8 kAppleTESTCASHA1
[kSecPolicySHA1Size
] = {
145 0xbc, 0x30, 0x55, 0xc8, 0xc8, 0xd3, 0x48, 0x3f, 0xf4, 0x8d,
146 0xfe, 0x3d, 0x51, 0x75, 0x31, 0xc9, 0xf4, 0xd7, 0x4a, 0xf7
149 static const UInt8 kITMSCASHA1
[kSecPolicySHA1Size
] = {
150 0x1D, 0x33, 0x42, 0x46, 0x8B, 0x10, 0xBD, 0xE6, 0x45, 0xCE,
151 0x44, 0x6E, 0xBB, 0xE8, 0xF5, 0x03, 0x5D, 0xF8, 0x32, 0x22
154 static const UInt8 kFactoryDeviceCASHA1
[kSecPolicySHA1Size
] = {
155 0xef, 0x68, 0x73, 0x17, 0xa4, 0xf8, 0xf9, 0x4b, 0x7b, 0x21,
156 0xe2, 0x2f, 0x09, 0x8f, 0xfd, 0x6a, 0xae, 0xc0, 0x0d, 0x63
159 static const UInt8 kApplePKISettingsAuthority
[kSecPolicySHA1Size
] = {
160 0x1D, 0x0C, 0xBA, 0xAD, 0x17, 0xFD, 0x7E, 0x9E, 0x9F, 0xF1,
161 0xC9, 0xA2, 0x66, 0x79, 0x60, 0x00, 0x8B, 0xAE, 0x70, 0xB8
164 static const UInt8 kAppleTestPKISettingsAuthority
[kSecPolicySHA1Size
] = {
165 0xDB, 0xBA, 0x25, 0x0B, 0xD8, 0x62, 0x71, 0x87, 0x54, 0x7E,
166 0xD7, 0xEF, 0x11, 0x94, 0x7E, 0x82, 0xE6, 0xD8, 0x1C, 0x9A
169 static const UInt8 kTestAppleRootCA_ECC_SHA1
[kSecPolicySHA1Size
] = {
170 0x62, 0x0A, 0xED, 0x83, 0xD2, 0x97, 0x4A, 0x77, 0x56, 0x33,
171 0x83, 0xBE, 0xDB, 0xF9, 0xA1, 0xBD, 0x5F, 0xFE, 0x55, 0x7B
174 __unused
static const UInt8 kAppleRootCA_ECC_SHA1
[kSecPolicySHA1Size
] = {
175 0xB5, 0x2C, 0xB0, 0x2F, 0xD5, 0x67, 0xE0, 0x35, 0x9F, 0xE8,
176 0xFA, 0x4D, 0x4C, 0x41, 0x03, 0x79, 0x70, 0xFE, 0x01, 0xB0
181 /********************************************************
182 ****************** SecPolicy object ********************
183 ********************************************************/
185 static void SecPolicyDestroy(CFTypeRef cf
) {
186 SecPolicyRef policy
= (SecPolicyRef
) cf
;
187 CFRelease(policy
->_oid
);
188 CFReleaseSafe(policy
->_name
);
189 CFRelease(policy
->_options
);
192 static Boolean
SecPolicyCompare(CFTypeRef cf1
, CFTypeRef cf2
) {
193 SecPolicyRef policy1
= (SecPolicyRef
) cf1
;
194 SecPolicyRef policy2
= (SecPolicyRef
) cf2
;
195 if (policy1
->_name
&& policy2
->_name
) {
196 return CFEqual(policy1
->_oid
, policy2
->_oid
) &&
197 CFEqual(policy1
->_name
, policy2
->_name
) &&
198 CFEqual(policy1
->_options
, policy2
->_options
);
200 return CFEqual(policy1
->_oid
, policy2
->_oid
) &&
201 CFEqual(policy1
->_options
, policy2
->_options
);
205 static CFHashCode
SecPolicyHash(CFTypeRef cf
) {
206 SecPolicyRef policy
= (SecPolicyRef
) cf
;
208 return CFHash(policy
->_oid
) + CFHash(policy
->_name
) + CFHash(policy
->_options
);
210 return CFHash(policy
->_oid
) + CFHash(policy
->_options
);
214 static CFStringRef
SecPolicyCopyFormatDescription(CFTypeRef cf
, CFDictionaryRef formatOptions
) {
215 SecPolicyRef policy
= (SecPolicyRef
) cf
;
216 CFMutableStringRef desc
= CFStringCreateMutable(kCFAllocatorDefault
, 0);
217 CFStringRef typeStr
= CFCopyTypeIDDescription(CFGetTypeID(cf
));
218 CFStringAppendFormat(desc
, NULL
,
219 CFSTR("<%@: oid: %@ name: %@ options %@"), typeStr
,
220 policy
->_oid
, (policy
->_name
) ? policy
->_name
: CFSTR(""),
223 CFStringAppend(desc
, CFSTR(" >"));
228 /* SecPolicy API functions. */
229 CFGiblisWithHashFor(SecPolicy
);
231 /* AUDIT[securityd](done):
232 oid (ok) is a caller provided string, only its cf type has been checked.
233 options is a caller provided dictionary, only its cf type has been checked.
235 SecPolicyRef
SecPolicyCreate(CFStringRef oid
, CFStringRef name
, CFDictionaryRef options
) {
236 SecPolicyRef result
= NULL
;
238 require(oid
, errOut
);
239 require(options
, errOut
);
241 (SecPolicyRef
)_CFRuntimeCreateInstance(kCFAllocatorDefault
,
242 SecPolicyGetTypeID(),
243 sizeof(struct __SecPolicy
) - sizeof(CFRuntimeBase
), 0), errOut
);
248 result
->_name
= name
;
250 result
->_options
= options
;
257 static void set_ku_from_properties(SecPolicyRef policy
, CFDictionaryRef properties
);
260 SecPolicyRef
SecPolicyCreateWithProperties(CFTypeRef policyIdentifier
,
261 CFDictionaryRef properties
) {
262 // Creates a policy reference for a given policy object identifier.
263 // If policy-specific parameters can be supplied (e.g. hostname),
264 // attempt to obtain from input properties dictionary.
265 // Returns NULL if the given identifier is unsupported.
267 SecPolicyRef policy
= NULL
;
268 CFTypeRef name
= NULL
;
269 CFStringRef teamID
= NULL
;
270 Boolean client
= false;
271 CFDictionaryRef context
= NULL
;
272 CFStringRef policyName
= NULL
, intermediateMarkerOid
= NULL
, leafMarkerOid
= NULL
;
273 CFDataRef rootDigest
= NULL
;
274 require(policyIdentifier
&& (CFStringGetTypeID() == CFGetTypeID(policyIdentifier
)), errOut
);
277 name
= CFDictionaryGetValue(properties
, kSecPolicyName
);
278 teamID
= CFDictionaryGetValue(properties
, kSecPolicyTeamIdentifier
);
280 CFBooleanRef dictionaryClientValue
;
281 client
= (CFDictionaryGetValueIfPresent(properties
, kSecPolicyClient
, (const void **)&dictionaryClientValue
) &&
282 (dictionaryClientValue
!= NULL
) && CFEqual(kCFBooleanTrue
, dictionaryClientValue
));
283 context
= CFDictionaryGetValue(properties
, kSecPolicyContext
);
284 policyName
= CFDictionaryGetValue(properties
, kSecPolicyPolicyName
);
285 intermediateMarkerOid
= CFDictionaryGetValue(properties
, kSecPolicyIntermediateMarkerOid
);
286 leafMarkerOid
= CFDictionaryGetValue(properties
, kSecPolicyLeafMarkerOid
);
287 rootDigest
= CFDictionaryGetValue(properties
, kSecPolicyRootDigest
);
290 /* only the EAP policy allows a non-string name */
291 if (name
&& !isString(name
) && !CFEqual(policyIdentifier
, kSecPolicyAppleEAP
)) {
292 secerror("policy \"%@\" requires a string value for the %@ key", policyIdentifier
, kSecPolicyName
);
296 /* What follows are all the exceptional functions that do not match the macro below */
297 if (CFEqual(policyIdentifier
, kSecPolicyAppleSSL
)) {
298 policy
= SecPolicyCreateSSL(!client
, name
);
299 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleSMIME
)) {
300 policy
= SecPolicyCreateSMIME(kSecSignSMIMEUsage
| kSecAnyEncryptSMIME
, name
);
301 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleEAP
)) {
302 CFArrayRef array
= NULL
;
303 if (isString(name
)) {
304 array
= CFArrayCreate(kCFAllocatorDefault
, (const void **)&name
, 1, &kCFTypeArrayCallBacks
);
305 } else if (isArray(name
)) {
306 array
= CFArrayCreateCopy(NULL
, name
);
308 policy
= SecPolicyCreateEAP(!client
, array
);
309 CFReleaseSafe(array
);
310 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleIPsec
)) {
311 policy
= SecPolicyCreateIPSec(!client
, name
);
312 } else if (CFEqual(policyIdentifier
, kSecPolicyMacAppStoreReceipt
)) {
313 policy
= SecPolicyCreateMacAppStoreReceipt();
314 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleRevocation
)) {
315 policy
= SecPolicyCreateRevocation(kSecRevocationUseAnyAvailableMethod
);
316 } else if (CFEqual(policyIdentifier
, kSecPolicyApplePassbookSigning
)) {
317 policy
= SecPolicyCreatePassbookCardSigner(name
, teamID
);
318 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleAST2DiagnosticsServerAuth
)) {
320 policy
= SecPolicyCreateAppleAST2Service(name
, context
);
322 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier
);
324 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleEscrowProxyServerAuth
)) {
326 policy
= SecPolicyCreateAppleEscrowProxyService(name
, context
);
328 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier
);
330 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleFMiPServerAuth
)) {
332 policy
= SecPolicyCreateAppleFMiPService(name
, context
);
334 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier
);
336 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleMMCService
)) {
338 policy
= SecPolicyCreateAppleMMCSService(name
, context
);
340 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier
);
342 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleGSService
)) {
344 policy
= SecPolicyCreateAppleGSService(name
, context
);
346 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier
);
348 } else if (CFEqual(policyIdentifier
, kSecPolicyApplePPQService
)) {
350 policy
= SecPolicyCreateApplePPQService(name
, context
);
352 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier
);
354 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleGenericApplePinned
)) {
356 policy
= SecPolicyCreateApplePinned(policyName
, intermediateMarkerOid
, leafMarkerOid
);
358 secerror("policy \"%@\" requires kSecPolicyPolicyName input", policyIdentifier
);
360 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleGenericAppleSSLPinned
)) {
362 policy
= SecPolicyCreateAppleSSLPinned(policyName
, name
, intermediateMarkerOid
, leafMarkerOid
);
364 secerror("policy \"%@\" requires kSecPolicyPolicyName input", policyIdentifier
);
366 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleIDSServiceContext
)) {
368 policy
= SecPolicyCreateAppleIDSServiceContext(name
, context
);
370 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier
);
372 } else if (CFEqual(policyIdentifier
, kSecPolicyApplePushService
)) {
374 policy
= SecPolicyCreateApplePushService(name
, context
);
376 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier
);
378 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleUniqueDeviceIdentifierCertificate
)) {
379 policy
= SecPolicyCreateAppleUniqueDeviceCertificate(rootDigest
);
380 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleiCloudSetupServerAuth
)) {
382 policy
= SecPolicyCreateAppleiCloudSetupService(name
, context
);
384 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier
);
386 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleBasicAttestationSystem
)) {
387 policy
= SecPolicyCreateAppleBasicAttestationSystem(rootDigest
);
388 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleBasicAttestationUser
)) {
389 policy
= SecPolicyCreateAppleBasicAttestationUser(rootDigest
);
390 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleComponentCertificate
)) {
391 policy
= SecPolicyCreateAppleComponentCertificate(rootDigest
);
393 /* For a couple of common patterns we use the macro, but some of the
394 * policies are deprecated (or not yet available), so we need to ignore the warning. */
395 #pragma clang diagnostic push
396 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
397 #pragma clang diagnostic ignored "-Wunguarded-availability"
399 #define _P_OPTION_N name
400 #define _P_PROPERTIES_(NAME, IN_NAME, FUNCTION)
401 #define _P_PROPERTIES_Y(NAME, IN_NAME, FUNCTION) else if (CFEqual(policyIdentifier, kSecPolicyApple##NAME)) { \
402 policy = SecPolicyCreate##FUNCTION(_P_OPTION_##IN_NAME); \
405 #define POLICYMACRO(NAME, OID, ISPUBLIC, INTNAME, IN_NAME, IN_PROPERTIES, FUNCTION) \
406 _P_PROPERTIES_##IN_PROPERTIES(NAME, IN_NAME, FUNCTION)
407 #include "SecPolicy.list"
409 secerror("ERROR: policy \"%@\" is unsupported", policyIdentifier
);
411 #pragma clang diagnostic pop // ignored "-Wdeprecated-declarations"
418 set_ku_from_properties(policy
, properties
);
422 SecPolicySetName(policy
, policyName
);
429 CFDictionaryRef
SecPolicyCopyProperties(SecPolicyRef policyRef
) {
430 // Builds and returns a dictionary which the caller must release.
432 #pragma clang diagnostic push
433 #pragma clang diagnostic ignored "-Wnonnull"
434 // After introducing nullability annotations, policyRef is supposed to be nonnull, suppress the warning
435 if (!policyRef
) return NULL
;
436 #pragma clang diagnostic pop
437 CFMutableDictionaryRef properties
= CFDictionaryCreateMutable(NULL
, 0,
438 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
439 #pragma clang diagnostic push
440 #pragma clang diagnostic ignored "-Wnonnull"
441 // 'properties' is nonnull in reality suppress the warning
442 if (!properties
) return NULL
;
443 #pragma clang diagnostic pop
444 CFStringRef oid
= (CFStringRef
) CFRetain(policyRef
->_oid
);
445 CFTypeRef nameKey
= NULL
;
447 // Determine name key
448 if (policyRef
->_options
) {
449 if (CFDictionaryContainsKey(policyRef
->_options
, kSecPolicyCheckSSLHostname
)) {
450 nameKey
= kSecPolicyCheckSSLHostname
;
451 } else if (CFDictionaryContainsKey(policyRef
->_options
, kSecPolicyCheckEAPTrustedServerNames
)) {
452 nameKey
= kSecPolicyCheckEAPTrustedServerNames
;
453 } else if (CFDictionaryContainsKey(policyRef
->_options
, kSecPolicyCheckEmail
)) {
454 nameKey
= kSecPolicyCheckEmail
;
459 CFDictionarySetValue(properties
, (const void *)kSecPolicyOid
,
462 // Set kSecPolicyName if we have one
463 if (nameKey
&& policyRef
->_options
) {
464 CFTypeRef name
= (CFTypeRef
) CFDictionaryGetValue(policyRef
->_options
,
467 CFDictionarySetValue(properties
, (const void *)kSecPolicyName
,
472 // Set kSecPolicyClient
473 CFStringRef policyName
= (CFStringRef
) CFRetainSafe(policyRef
->_name
);
474 if (policyName
&& (CFEqual(policyName
, kSecPolicyNameSSLClient
) ||
475 CFEqual(policyName
, kSecPolicyNameIPSecClient
) ||
476 CFEqual(policyName
, kSecPolicyNameEAPClient
))) {
477 CFDictionarySetValue(properties
, (const void *)kSecPolicyClient
,
478 (const void *)kCFBooleanTrue
);
485 static void SecPolicySetOid(SecPolicyRef policy
, CFStringRef oid
) {
486 if (!policy
|| !oid
) return;
487 CFStringRef temp
= policy
->_oid
;
493 void SecPolicySetName(SecPolicyRef policy
, CFStringRef policyName
) {
494 if (!policy
|| !policyName
) return;
495 CFStringRef temp
= policy
->_name
;
496 CFRetain(policyName
);
497 policy
->_name
= policyName
;
501 CFStringRef
SecPolicyGetOidString(SecPolicyRef policy
) {
505 CFStringRef
SecPolicyGetName(SecPolicyRef policy
) {
506 return policy
->_name
;
509 CFDictionaryRef
SecPolicyGetOptions(SecPolicyRef policy
) {
510 return policy
->_options
;
513 void SecPolicySetOptionsValue(SecPolicyRef policy
, CFStringRef key
, CFTypeRef value
) {
514 if (!policy
|| !key
) return;
515 CFMutableDictionaryRef options
= (CFMutableDictionaryRef
) policy
->_options
;
517 options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
518 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
519 if (!options
) return;
520 policy
->_options
= options
;
522 CFDictionarySetValue(options
, key
, value
);
525 /* Local forward declaration */
526 static void set_ssl_ekus(CFMutableDictionaryRef options
, bool server
);
529 // this is declared as NA for iPhone in SecPolicy.h, so declare here
530 OSStatus
SecPolicySetProperties(SecPolicyRef policyRef
, CFDictionaryRef properties
);
533 OSStatus
SecPolicySetProperties(SecPolicyRef policyRef
, CFDictionaryRef properties
) {
534 // Set policy options based on the provided dictionary keys.
536 if (!(policyRef
&& properties
&& (CFDictionaryGetTypeID() == CFGetTypeID(properties
)))) {
539 CFStringRef oid
= (CFStringRef
) CFRetain(policyRef
->_oid
);
540 OSStatus result
= errSecSuccess
;
543 CFTypeRef name
= NULL
;
544 if (CFDictionaryGetValueIfPresent(properties
, (const void *)kSecPolicyName
,
545 (const void **)&name
) && name
) {
546 CFTypeID typeID
= CFGetTypeID(name
);
547 if (CFEqual(oid
, kSecPolicyAppleSSL
) ||
548 CFEqual(oid
, kSecPolicyAppleIPsec
)) {
549 if (CFStringGetTypeID() == typeID
) {
550 SecPolicySetOptionsValue(policyRef
, kSecPolicyCheckSSLHostname
, name
);
552 else result
= errSecParam
;
554 else if (CFEqual(oid
, kSecPolicyAppleEAP
)) {
555 if ((CFStringGetTypeID() == typeID
) ||
556 (CFArrayGetTypeID() == typeID
)) {
557 SecPolicySetOptionsValue(policyRef
, kSecPolicyCheckEAPTrustedServerNames
, name
);
559 else result
= errSecParam
;
561 else if (CFEqual(oid
, kSecPolicyAppleSMIME
)) {
562 if (CFStringGetTypeID() == typeID
) {
563 SecPolicySetOptionsValue(policyRef
, kSecPolicyCheckEmail
, name
);
565 else result
= errSecParam
;
570 CFTypeRef client
= NULL
;
571 if (CFDictionaryGetValueIfPresent(properties
, (const void *)kSecPolicyClient
,
572 (const void **)&client
) && client
) {
573 if (!(CFBooleanGetTypeID() == CFGetTypeID(client
))) {
574 result
= errSecParam
;
576 else if (CFEqual(client
, kCFBooleanTrue
)) {
577 if (CFEqual(oid
, kSecPolicyAppleSSL
)) {
578 SecPolicySetName(policyRef
, kSecPolicyNameSSLClient
);
579 /* Set EKU checks for clients */
580 CFMutableDictionaryRef newOptions
= CFDictionaryCreateMutableCopy(NULL
, 0, policyRef
->_options
);
581 set_ssl_ekus(newOptions
, false);
582 CFReleaseSafe(policyRef
->_options
);
583 policyRef
->_options
= newOptions
;
585 else if (CFEqual(oid
, kSecPolicyAppleIPsec
)) {
586 SecPolicySetName(policyRef
, kSecPolicyNameIPSecClient
);
588 else if (CFEqual(oid
, kSecPolicyNameEAPServer
)) {
589 SecPolicySetName(policyRef
, kSecPolicyNameEAPClient
);
590 /* Set EKU checks for clients */
591 CFMutableDictionaryRef newOptions
= CFDictionaryCreateMutableCopy(NULL
, 0, policyRef
->_options
);
592 set_ssl_ekus(newOptions
, false);
593 CFReleaseSafe(policyRef
->_options
);
594 policyRef
->_options
= newOptions
;
598 if (CFEqual(oid
, kSecPolicyAppleSSL
)) {
599 SecPolicySetName(policyRef
, kSecPolicyNameSSLServer
);
600 /* Set EKU checks for servers */
601 CFMutableDictionaryRef newOptions
= CFDictionaryCreateMutableCopy(NULL
, 0, policyRef
->_options
);
602 set_ssl_ekus(newOptions
, true);
603 CFReleaseSafe(policyRef
->_options
);
604 policyRef
->_options
= newOptions
;
606 else if (CFEqual(oid
, kSecPolicyAppleIPsec
)) {
607 SecPolicySetName(policyRef
, kSecPolicyNameIPSecServer
);
609 else if (CFEqual(oid
, kSecPolicyAppleEAP
)) {
610 SecPolicySetName(policyRef
, kSecPolicyNameEAPServer
);
611 /* Set EKU checks for servers */
612 CFMutableDictionaryRef newOptions
= CFDictionaryCreateMutableCopy(NULL
, 0, policyRef
->_options
);
613 set_ssl_ekus(newOptions
, true);
614 CFReleaseSafe(policyRef
->_options
);
615 policyRef
->_options
= newOptions
;
621 set_ku_from_properties(policyRef
, properties
);
627 static xpc_object_t
copy_xpc_policy_object(SecPolicyRef policy
);
628 static bool append_policy_to_xpc_array(SecPolicyRef policy
, xpc_object_t xpc_policies
);
629 extern xpc_object_t
copy_xpc_policies_array(CFArrayRef policies
);
630 extern OSStatus
validate_array_of_items(CFArrayRef array
, CFStringRef arrayItemType
, CFTypeID itemTypeID
, bool required
);
632 static xpc_object_t
copy_xpc_policy_object(SecPolicyRef policy
) {
633 xpc_object_t xpc_policy
= NULL
;
634 xpc_object_t data
[2] = { NULL
, NULL
};
635 if (policy
->_oid
&& (CFGetTypeID(policy
->_oid
) == CFStringGetTypeID()) &&
636 policy
->_name
&& (CFGetTypeID(policy
->_name
) == CFStringGetTypeID())) {
637 /* These should really be different elements of the xpc array. But
638 * SecPolicyCreateWithXPCObject previously checked the size via ==, which prevents
639 * us from appending new information while maintaining backward compatibility.
640 * Doing this makes the builders happy. */
641 CFMutableStringRef oidAndName
= NULL
;
642 oidAndName
= CFStringCreateMutableCopy(NULL
, 0, policy
->_oid
);
644 CFStringAppend(oidAndName
, CFSTR("++"));
645 CFStringAppend(oidAndName
, policy
->_name
);
646 data
[0] = _CFXPCCreateXPCObjectFromCFObject(oidAndName
);
647 CFReleaseNull(oidAndName
);
649 data
[0] = _CFXPCCreateXPCObjectFromCFObject(policy
->_oid
);
651 } else if (policy
->_oid
&& (CFGetTypeID(policy
->_oid
) == CFStringGetTypeID())) {
652 data
[0] = _CFXPCCreateXPCObjectFromCFObject(policy
->_oid
);
654 secerror("policy 0x%lX has no _oid", (uintptr_t)policy
);
656 if (policy
->_options
&& (CFGetTypeID(policy
->_options
) == CFDictionaryGetTypeID())) {
657 data
[1] = _CFXPCCreateXPCObjectFromCFObject(policy
->_options
);
659 secerror("policy 0x%lX has no _options", (uintptr_t)policy
);
661 xpc_policy
= xpc_array_create(data
, array_size(data
));
662 if (data
[0]) xpc_release(data
[0]);
663 if (data
[1]) xpc_release(data
[1]);
667 static bool append_policy_to_xpc_array(SecPolicyRef policy
, xpc_object_t xpc_policies
) {
671 xpc_object_t xpc_policy
= copy_xpc_policy_object(policy
);
675 xpc_array_append_value(xpc_policies
, xpc_policy
);
676 xpc_release(xpc_policy
);
680 xpc_object_t
copy_xpc_policies_array(CFArrayRef policies
) {
681 xpc_object_t xpc_policies
= xpc_array_create(NULL
, 0);
685 validate_array_of_items(policies
, CFSTR("policy"), SecPolicyGetTypeID(), true);
686 CFIndex ix
, count
= CFArrayGetCount(policies
);
687 for (ix
= 0; ix
< count
; ++ix
) {
688 SecPolicyRef policy
= (SecPolicyRef
) CFArrayGetValueAtIndex(policies
, ix
);
689 #if SECTRUST_VERBOSE_DEBUG
690 CFDictionaryRef props
= SecPolicyCopyProperties(policy
);
691 secerror("idx=%d of %d; policy=0x%lX properties=%@", (int)ix
, (int)count
, (uintptr_t)policy
, props
);
692 CFReleaseSafe(props
);
694 if (!append_policy_to_xpc_array(policy
, xpc_policies
)) {
695 xpc_release(xpc_policies
);
703 static xpc_object_t
SecPolicyCopyXPCObject(SecPolicyRef policy
, CFErrorRef
*error
) {
704 xpc_object_t xpc_policy
= NULL
;
705 xpc_object_t data
[2] = {};
706 CFMutableStringRef oidAndName
= NULL
;
707 oidAndName
= CFStringCreateMutableCopy(NULL
, 0, policy
->_oid
);
710 CFStringAppend(oidAndName
, CFSTR("++"));
711 CFStringAppend(oidAndName
, policy
->_name
);
714 require_action_quiet(data
[0] = _CFXPCCreateXPCObjectFromCFObject(oidAndName
), exit
,
715 SecError(errSecParam
, error
,
716 CFSTR("failed to create xpc_object from policy oid and name")));
718 require_action_quiet(data
[0] = _CFXPCCreateXPCObjectFromCFObject(policy
->_oid
), exit
,
719 SecError(errSecParam
, error
, CFSTR("failed to create xpc_object from policy oid")));
721 require_action_quiet(data
[1] = _CFXPCCreateXPCObjectFromCFObject(policy
->_options
), exit
,
722 SecError(errSecParam
, error
, CFSTR("failed to create xpc_object from policy options")));
723 require_action_quiet(xpc_policy
= xpc_array_create(data
, array_size(data
)), exit
,
724 SecError(errSecAllocate
, error
, CFSTR("failed to create xpc_array for policy")));
727 if (data
[0]) xpc_release(data
[0]);
728 if (data
[1]) xpc_release(data
[1]);
729 CFReleaseNull(oidAndName
);
733 static bool SecPolicyAppendToXPCArray(SecPolicyRef policy
, xpc_object_t policies
, CFErrorRef
*error
) {
737 xpc_object_t xpc_policy
= SecPolicyCopyXPCObject(policy
, error
);
741 xpc_array_append_value(policies
, xpc_policy
);
742 xpc_release(xpc_policy
);
746 xpc_object_t
SecPolicyArrayCopyXPCArray(CFArrayRef policies
, CFErrorRef
*error
) {
747 xpc_object_t xpc_policies
;
748 require_action_quiet(xpc_policies
= xpc_array_create(NULL
, 0), exit
,
749 SecError(errSecAllocate
, error
, CFSTR("failed to create xpc_array")));
750 CFIndex ix
, count
= CFArrayGetCount(policies
);
751 for (ix
= 0; ix
< count
; ++ix
) {
752 if (!SecPolicyAppendToXPCArray((SecPolicyRef
)CFArrayGetValueAtIndex(policies
, ix
), xpc_policies
, error
)) {
753 xpc_release(xpc_policies
);
761 static OSStatus
parseOidAndName(CFStringRef oidAndName
, CFStringRef
*oid
, CFStringRef
*name
) {
762 OSStatus result
= errSecSuccess
;
763 CFStringRef partial
= NULL
;
765 CFRange delimiter
= CFStringFind(oidAndName
, CFSTR("++"), 0);
766 if (delimiter
.length
!= 2) {
770 /* get first half: oid */
771 partial
= CFStringCreateWithSubstring(NULL
, oidAndName
, CFRangeMake(0, delimiter
.location
));
772 if (oid
) { *oid
= CFRetainSafe(partial
); }
773 CFReleaseNull(partial
);
775 /* get second half: name */
776 if (delimiter
.location
+ 2 >= CFStringGetLength(oidAndName
)) {
777 return errSecSuccess
; // name is optional
779 CFRange nameRange
= CFRangeMake(delimiter
.location
+2,
780 CFStringGetLength(oidAndName
) - delimiter
.location
- 2);
781 partial
= CFStringCreateWithSubstring(NULL
, oidAndName
, nameRange
);
782 if (name
) { *name
= CFRetainSafe(partial
); }
783 CFReleaseNull(partial
);
787 static SecPolicyRef
SecPolicyCreateWithXPCObject(xpc_object_t xpc_policy
, CFErrorRef
*error
) {
788 SecPolicyRef policy
= NULL
;
789 CFTypeRef oidAndName
= NULL
;
790 CFStringRef oid
= NULL
;
791 CFStringRef name
= NULL
;
792 CFTypeRef options
= NULL
;
794 require_action_quiet(xpc_policy
, exit
, SecError(errSecParam
, error
, CFSTR("policy xpc value is NULL")));
795 require_action_quiet(xpc_get_type(xpc_policy
) == XPC_TYPE_ARRAY
, exit
, SecError(errSecDecode
, error
, CFSTR("policy xpc value is not an array")));
796 require_action_quiet(xpc_array_get_count(xpc_policy
) >= 2, exit
, SecError(errSecDecode
, error
, CFSTR("policy xpc array count < 2")));
797 oidAndName
= _CFXPCCreateCFObjectFromXPCObject(xpc_array_get_value(xpc_policy
, 0));
798 require_action_quiet(isString(oidAndName
), exit
,
799 SecError(errSecParam
, error
, CFSTR("failed to convert xpc policy[0]=%@ to CFString"), oidAndName
));
800 options
= _CFXPCCreateCFObjectFromXPCObject(xpc_array_get_value(xpc_policy
, 1));
801 require_action_quiet(isDictionary(options
), exit
,
802 SecError(errSecParam
, error
, CFSTR("failed to convert xpc policy[1]=%@ to CFDictionary"), options
));
803 require_noerr_action_quiet(parseOidAndName(oidAndName
, &oid
, &name
), exit
,
804 SecError(errSecParam
, error
, CFSTR("failed to convert combined %@ to name and oid"), oidAndName
));
805 require_action_quiet(policy
= SecPolicyCreate(oid
, name
, options
), exit
,
806 SecError(errSecDecode
, error
, CFSTR("Failed to create policy")));
809 CFReleaseSafe(oidAndName
);
812 CFReleaseSafe(options
);
816 CFArrayRef
SecPolicyXPCArrayCopyArray(xpc_object_t xpc_policies
, CFErrorRef
*error
) {
817 CFMutableArrayRef policies
= NULL
;
818 require_action_quiet(xpc_get_type(xpc_policies
) == XPC_TYPE_ARRAY
, exit
,
819 SecError(errSecParam
, error
, CFSTR("policies xpc value is not an array")));
820 size_t count
= xpc_array_get_count(xpc_policies
);
821 require_action_quiet(policies
= CFArrayCreateMutable(kCFAllocatorDefault
, count
, &kCFTypeArrayCallBacks
), exit
,
822 SecError(errSecAllocate
, error
, CFSTR("failed to create CFArray of capacity %zu"), count
));
825 for (ix
= 0; ix
< count
; ++ix
) {
826 SecPolicyRef policy
= SecPolicyCreateWithXPCObject(xpc_array_get_value(xpc_policies
, ix
), error
);
831 CFArraySetValueAtIndex(policies
, ix
, policy
);
840 static SEC_CONST_DECL (kSecPolicyOptions
, "policyOptions");
842 static SecPolicyRef
SecPolicyCreateWithDictionary(CFDictionaryRef dict
) {
843 SecPolicyRef policy
= NULL
;
844 CFStringRef oid
= (CFStringRef
)CFDictionaryGetValue(dict
, kSecPolicyOid
);
845 require_quiet(isString(oid
), errOut
);
846 CFDictionaryRef options
= (CFDictionaryRef
)CFDictionaryGetValue(dict
, kSecPolicyOptions
);
847 require_quiet(isDictionary(options
), errOut
);
848 CFStringRef name
= (CFStringRef
)CFDictionaryGetValue(dict
, kSecPolicyPolicyName
);
849 policy
= SecPolicyCreate(oid
, name
, options
);
854 static void deserializePolicy(const void *value
, void *context
) {
855 CFDictionaryRef policyDict
= (CFDictionaryRef
)value
;
856 if (isDictionary(policyDict
)) {
857 CFTypeRef deserializedPolicy
= SecPolicyCreateWithDictionary(policyDict
);
858 if (deserializedPolicy
) {
859 CFArrayAppendValue((CFMutableArrayRef
)context
, deserializedPolicy
);
860 CFRelease(deserializedPolicy
);
865 CFArrayRef
SecPolicyArrayCreateDeserialized(CFArrayRef serializedPolicies
) {
866 CFMutableArrayRef result
= NULL
;
867 require_quiet(isArray(serializedPolicies
), errOut
);
868 CFIndex count
= CFArrayGetCount(serializedPolicies
);
869 result
= CFArrayCreateMutable(kCFAllocatorDefault
, count
, &kCFTypeArrayCallBacks
);
870 CFRange all_policies
= { 0, count
};
871 CFArrayApplyFunction(serializedPolicies
, all_policies
, deserializePolicy
, result
);
876 static CFDictionaryRef
SecPolicyCreateDictionary(SecPolicyRef policy
) {
877 CFMutableDictionaryRef dict
= NULL
;
878 dict
= CFDictionaryCreateMutable(NULL
, 3, &kCFTypeDictionaryKeyCallBacks
,
879 &kCFTypeDictionaryValueCallBacks
);
880 CFDictionaryAddValue(dict
, kSecPolicyOid
, policy
->_oid
);
881 CFDictionaryAddValue(dict
, kSecPolicyOptions
, policy
->_options
);
883 CFDictionaryAddValue(dict
, kSecPolicyPolicyName
, policy
->_name
);
888 static void serializePolicy(const void *value
, void *context
) {
889 SecPolicyRef policy
= (SecPolicyRef
)value
;
890 if (policy
&& SecPolicyGetTypeID() == CFGetTypeID(policy
)) {
891 CFDictionaryRef serializedPolicy
= SecPolicyCreateDictionary(policy
);
892 if (serializedPolicy
) {
893 CFArrayAppendValue((CFMutableArrayRef
)context
, serializedPolicy
);
894 CFRelease(serializedPolicy
);
899 CFArrayRef
SecPolicyArrayCreateSerialized(CFArrayRef policies
) {
900 CFMutableArrayRef result
= NULL
;
901 require_quiet(isArray(policies
), errOut
);
902 CFIndex count
= CFArrayGetCount(policies
);
903 result
= CFArrayCreateMutable(NULL
, count
, &kCFTypeArrayCallBacks
);
904 CFRange all_policies
= { 0, count
};
905 CFArrayApplyFunction(policies
, all_policies
, serializePolicy
, result
);
910 static void add_element(CFMutableDictionaryRef options
, CFStringRef key
,
912 CFTypeRef old_value
= CFDictionaryGetValue(options
, key
);
914 CFMutableArrayRef array
;
915 if (CFGetTypeID(old_value
) == CFArrayGetTypeID()) {
916 array
= (CFMutableArrayRef
)old_value
;
918 array
= CFArrayCreateMutable(kCFAllocatorDefault
, 0,
919 &kCFTypeArrayCallBacks
);
920 CFArrayAppendValue(array
, old_value
);
921 CFDictionarySetValue(options
, key
, array
);
924 CFArrayAppendValue(array
, value
);
926 CFDictionaryAddValue(options
, key
, value
);
930 static void add_eku(CFMutableDictionaryRef options
, const DERItem
*ekuOid
) {
931 CFDataRef eku
= CFDataCreate(kCFAllocatorDefault
,
932 ekuOid
? ekuOid
->data
: NULL
,
933 ekuOid
? ekuOid
->length
: 0);
935 add_element(options
, kSecPolicyCheckExtendedKeyUsage
, eku
);
940 static void add_eku_string(CFMutableDictionaryRef options
, CFStringRef ekuOid
) {
942 add_element(options
, kSecPolicyCheckExtendedKeyUsage
, ekuOid
);
946 static void set_ssl_ekus(CFMutableDictionaryRef options
, bool server
) {
947 CFDictionaryRemoveValue(options
, kSecPolicyCheckExtendedKeyUsage
);
949 /* If server and EKU ext present then EKU ext should contain one of
950 ServerAuth or ExtendedKeyUsageAny or NetscapeSGC or MicrosoftSGC.
951 else if !server and EKU ext present then EKU ext should contain one of
952 ClientAuth or ExtendedKeyUsageAny. */
954 /* We always allow certificates that specify oidAnyExtendedKeyUsage. */
955 add_eku(options
, NULL
); /* eku extension is optional */
956 add_eku(options
, &oidAnyExtendedKeyUsage
);
958 add_eku(options
, &oidExtendedKeyUsageServerAuth
);
959 add_eku(options
, &oidExtendedKeyUsageMicrosoftSGC
);
960 add_eku(options
, &oidExtendedKeyUsageNetscapeSGC
);
962 add_eku(options
, &oidExtendedKeyUsageClientAuth
);
966 static void add_ku(CFMutableDictionaryRef options
, SecKeyUsage keyUsage
) {
967 SInt32 dku
= keyUsage
;
968 CFNumberRef ku
= CFNumberCreate(kCFAllocatorDefault
, kCFNumberSInt32Type
,
971 add_element(options
, kSecPolicyCheckKeyUsage
, ku
);
977 static void set_ku_from_properties(SecPolicyRef policy
, CFDictionaryRef properties
) {
978 if (!policy
|| !properties
) {
982 CFStringRef keyNames
[] = { kSecPolicyKU_DigitalSignature
, kSecPolicyKU_NonRepudiation
, kSecPolicyKU_KeyEncipherment
, kSecPolicyKU_DataEncipherment
,
983 kSecPolicyKU_KeyAgreement
, kSecPolicyKU_KeyCertSign
, kSecPolicyKU_CRLSign
, kSecPolicyKU_EncipherOnly
, kSecPolicyKU_DecipherOnly
};
985 uint32_t keyUsageValues
[] = { kSecKeyUsageDigitalSignature
, kSecKeyUsageNonRepudiation
, kSecKeyUsageKeyEncipherment
, kSecKeyUsageDataEncipherment
,
986 kSecKeyUsageKeyAgreement
, kSecKeyUsageKeyCertSign
, kSecKeyUsageCRLSign
, kSecKeyUsageEncipherOnly
, kSecKeyUsageDecipherOnly
};
988 bool haveKeyUsage
= false;
989 CFTypeRef keyUsageBoolean
;
990 for (uint32_t i
= 0; i
< sizeof(keyNames
) / sizeof(CFStringRef
); ++i
) {
991 if (CFDictionaryGetValueIfPresent(properties
, keyNames
[i
], (const void**)&keyUsageBoolean
)) {
992 if (CFEqual(keyUsageBoolean
, kCFBooleanTrue
)) {
1003 CFMutableDictionaryRef options
= (CFMutableDictionaryRef
) policy
->_options
;
1005 options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1006 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
1007 if (!options
) return;
1008 policy
->_options
= options
;
1010 CFDictionaryRemoveValue(options
, kSecPolicyCheckKeyUsage
);
1013 for (uint32_t i
= 0; i
< sizeof(keyNames
) / sizeof(CFStringRef
); ++i
) {
1014 if (CFDictionaryGetValueIfPresent(properties
, keyNames
[i
], (const void**)&keyUsageBoolean
)) {
1015 if (CFEqual(keyUsageBoolean
, kCFBooleanTrue
)) {
1016 add_ku(options
, keyUsageValues
[i
]);
1023 static void add_oid(CFMutableDictionaryRef options
, CFStringRef policy_key
, const DERItem
*oid
) {
1024 CFDataRef oid_data
= CFDataCreate(kCFAllocatorDefault
,
1025 oid
? oid
->data
: NULL
,
1026 oid
? oid
->length
: 0);
1028 add_element(options
, policy_key
, oid_data
);
1029 CFRelease(oid_data
);
1033 static void add_leaf_marker_value(CFMutableDictionaryRef options
, const DERItem
*markerOid
, CFStringRef string_value
) {
1035 CFTypeRef policyData
= NULL
;
1037 if (NULL
== string_value
) {
1038 policyData
= CFDataCreate(kCFAllocatorDefault
,
1039 markerOid
? markerOid
->data
: NULL
,
1040 markerOid
? markerOid
->length
: 0);
1042 CFStringRef oid_as_string
= SecDERItemCopyOIDDecimalRepresentation(kCFAllocatorDefault
, markerOid
);
1044 const void *key
[1] = { oid_as_string
};
1045 const void *value
[1] = { string_value
};
1046 policyData
= CFDictionaryCreate(kCFAllocatorDefault
,
1048 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
1049 CFReleaseNull(oid_as_string
);
1052 add_element(options
, kSecPolicyCheckLeafMarkerOid
, policyData
);
1054 CFReleaseNull(policyData
);
1058 static void add_leaf_marker(CFMutableDictionaryRef options
, const DERItem
*markerOid
) {
1059 add_leaf_marker_value(options
, markerOid
, NULL
);
1062 static void add_leaf_marker_value_string(CFMutableDictionaryRef options
, CFStringRef markerOid
, CFStringRef string_value
) {
1063 if (NULL
== string_value
) {
1064 add_element(options
, kSecPolicyCheckLeafMarkerOid
, markerOid
);
1066 CFDictionaryRef policyData
= NULL
;
1067 const void *key
[1] = { markerOid
};
1068 const void *value
[1] = { string_value
};
1069 policyData
= CFDictionaryCreate(kCFAllocatorDefault
,
1071 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
1072 add_element(options
, kSecPolicyCheckLeafMarkerOid
, policyData
);
1074 CFReleaseNull(policyData
);
1078 static void add_leaf_marker_string(CFMutableDictionaryRef options
, CFStringRef markerOid
) {
1079 add_leaf_marker_value_string(options
, markerOid
, NULL
);
1082 static void add_leaf_prod_qa_element(CFMutableDictionaryRef options
, CFTypeRef prodValue
, CFTypeRef qaValue
)
1084 CFMutableDictionaryRef prodAndQADictionary
= CFDictionaryCreateMutable(NULL
, 0, &kCFTypeDictionaryKeyCallBacks
,
1085 &kCFTypeDictionaryValueCallBacks
);
1086 CFDictionaryRef old_value
= CFDictionaryGetValue(options
, kSecPolicyCheckLeafMarkersProdAndQA
);
1088 CFMutableArrayRef prodArray
= NULL
, qaArray
= NULL
;
1089 CFTypeRef old_prod_value
= CFDictionaryGetValue(old_value
, kSecPolicyLeafMarkerProd
);
1090 CFTypeRef old_qa_value
= CFDictionaryGetValue(old_value
, kSecPolicyLeafMarkerQA
);
1091 if (isArray(old_prod_value
) && isArray(old_qa_value
)) {
1092 prodArray
= (CFMutableArrayRef
)CFRetainSafe(old_prod_value
);
1093 qaArray
= (CFMutableArrayRef
)CFRetainSafe(old_qa_value
);
1095 prodArray
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
1096 qaArray
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
1097 CFArrayAppendValue(prodArray
, old_prod_value
);
1098 CFArrayAppendValue(qaArray
, old_qa_value
);
1100 CFArrayAppendValue(prodArray
, prodValue
);
1101 CFArrayAppendValue(qaArray
, qaValue
);
1102 CFDictionaryAddValue(prodAndQADictionary
, kSecPolicyLeafMarkerProd
, prodArray
);
1103 CFDictionaryAddValue(prodAndQADictionary
, kSecPolicyLeafMarkerQA
, qaArray
);
1104 CFReleaseNull(prodArray
);
1105 CFReleaseNull(qaArray
);
1108 CFDictionaryAddValue(prodAndQADictionary
, kSecPolicyLeafMarkerProd
, prodValue
);
1109 CFDictionaryAddValue(prodAndQADictionary
, kSecPolicyLeafMarkerQA
, qaValue
);
1111 CFDictionarySetValue(options
, kSecPolicyCheckLeafMarkersProdAndQA
, prodAndQADictionary
);
1112 CFReleaseNull(prodAndQADictionary
);
1116 static void add_leaf_prod_qa_markers(CFMutableDictionaryRef options
, const DERItem
*prodMarkerOid
, const DERItem
*qaMarkerOid
)
1118 CFDataRef prodData
= NULL
, qaData
= NULL
;
1119 prodData
= CFDataCreate(NULL
, prodMarkerOid
? prodMarkerOid
->data
: NULL
,
1120 prodMarkerOid
? prodMarkerOid
->length
: 0);
1121 qaData
= CFDataCreate(NULL
, qaMarkerOid
? qaMarkerOid
->data
: NULL
,
1122 qaMarkerOid
? qaMarkerOid
->length
: 0);
1123 add_leaf_prod_qa_element(options
, prodData
, qaData
);
1124 CFReleaseNull(prodData
);
1125 CFReleaseNull(qaData
);
1128 static void add_leaf_prod_qa_markers_string(CFMutableDictionaryRef options
, CFStringRef prodMarkerOid
, CFStringRef qaMarkerOid
)
1130 add_leaf_prod_qa_element(options
, prodMarkerOid
, qaMarkerOid
);
1133 static void add_leaf_prod_qa_markers_value_string(CFMutableDictionaryRef options
,
1134 CFStringRef prodMarkerOid
, CFStringRef prod_value
,
1135 CFStringRef qaMarkerOid
, CFStringRef qa_value
)
1137 if (!prod_value
&& !qa_value
) {
1138 add_leaf_prod_qa_element(options
, prodMarkerOid
, qaMarkerOid
);
1140 CFDictionaryRef prodData
= NULL
, qaData
= NULL
;
1141 const void *prodKey
[1] = { prodMarkerOid
}, *qaKey
[1] = { qaMarkerOid
};
1142 const void *prodValue
[1] = { prod_value
}, *qaValue
[1] = { qa_value
};
1143 prodData
= CFDictionaryCreate(NULL
, prodKey
, prodValue
, 1, &kCFTypeDictionaryKeyCallBacks
,
1144 &kCFTypeDictionaryValueCallBacks
);
1145 qaData
= CFDictionaryCreate(NULL
, qaKey
, qaValue
, 1, &kCFTypeDictionaryKeyCallBacks
,
1146 &kCFTypeDictionaryValueCallBacks
);
1147 add_leaf_prod_qa_element(options
, prodData
, qaData
);
1148 CFReleaseNull(prodData
);
1149 CFReleaseNull(qaData
);
1153 static void add_intermediate_marker_value_string(CFMutableDictionaryRef options
, CFStringRef markerOid
, CFStringRef string_value
) {
1154 if (NULL
== string_value
) {
1155 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, markerOid
);
1157 CFDictionaryRef policyData
= NULL
;
1158 const void *key
[1] = { markerOid
};
1159 const void *value
[1] = { string_value
};
1160 policyData
= CFDictionaryCreate(kCFAllocatorDefault
,
1162 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
1163 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, policyData
);
1165 CFReleaseNull(policyData
);
1169 static void add_certificate_policy_oid(CFMutableDictionaryRef options
, const DERItem
*certificatePolicyOid
) {
1170 CFTypeRef certificatePolicyData
= NULL
;
1171 certificatePolicyData
= CFDataCreate(kCFAllocatorDefault
,
1172 certificatePolicyOid
? certificatePolicyOid
->data
: NULL
,
1173 certificatePolicyOid
? certificatePolicyOid
->length
: 0);
1174 if (certificatePolicyData
) {
1175 add_element(options
, kSecPolicyCheckCertificatePolicy
, certificatePolicyData
);
1176 CFRelease(certificatePolicyData
);
1180 static void add_certificate_policy_oid_string(CFMutableDictionaryRef options
, CFStringRef certificatePolicyOid
) {
1181 if (certificatePolicyOid
) {
1182 add_element(options
, kSecPolicyCheckCertificatePolicy
, certificatePolicyOid
);
1187 // Routines for adding dictionary entries for policies.
1190 // X.509, but missing validity requirements.
1191 static void SecPolicyAddBasicCertOptions(CFMutableDictionaryRef options
)
1193 //CFDictionaryAddValue(options, kSecPolicyCheckBasicCertificateProcessing, kCFBooleanTrue);
1194 // Happens automatically in SecPVCPathChecks
1195 CFDictionaryAddValue(options
, kSecPolicyCheckCriticalExtensions
, kCFBooleanTrue
);
1196 CFDictionaryAddValue(options
, kSecPolicyCheckIdLinkage
, kCFBooleanTrue
);
1197 CFDictionaryAddValue(options
, kSecPolicyCheckBasicConstraints
, kCFBooleanTrue
);
1198 CFDictionaryAddValue(options
, kSecPolicyCheckNonEmptySubject
, kCFBooleanTrue
);
1199 CFDictionaryAddValue(options
, kSecPolicyCheckWeakKeySize
, kCFBooleanTrue
);
1200 CFDictionaryAddValue(options
, kSecPolicyCheckWeakSignature
, kCFBooleanTrue
);
1203 static void SecPolicyAddBasicX509Options(CFMutableDictionaryRef options
)
1205 SecPolicyAddBasicCertOptions(options
);
1206 CFDictionaryAddValue(options
, kSecPolicyCheckTemporalValidity
, kCFBooleanTrue
);
1208 // Make sure that black and gray leaf checks are performed for basic X509 chain building
1209 CFDictionaryAddValue(options
, kSecPolicyCheckBlackListedLeaf
, kCFBooleanTrue
);
1210 CFDictionaryAddValue(options
, kSecPolicyCheckGrayListedLeaf
, kCFBooleanTrue
);
1213 static bool SecPolicyAddChainLengthOptions(CFMutableDictionaryRef options
, CFIndex length
)
1215 bool result
= false;
1216 CFNumberRef lengthAsCF
= NULL
;
1218 require(lengthAsCF
= CFNumberCreate(kCFAllocatorDefault
,
1219 kCFNumberCFIndexType
, &length
), errOut
);
1220 CFDictionaryAddValue(options
, kSecPolicyCheckChainLength
, lengthAsCF
);
1225 CFReleaseSafe(lengthAsCF
);
1229 static bool SecPolicyAddAnchorSHA1Options(CFMutableDictionaryRef options
,
1230 const UInt8 anchorSha1
[kSecPolicySHA1Size
])
1232 bool success
= false;
1233 CFDataRef anchorData
= NULL
;
1235 require(anchorData
= CFDataCreate(kCFAllocatorDefault
, anchorSha1
, kSecPolicySHA1Size
), errOut
);
1236 add_element(options
, kSecPolicyCheckAnchorSHA1
, anchorData
);
1241 CFReleaseSafe(anchorData
);
1245 static bool SecPolicyAddAnchorSHA256Options(CFMutableDictionaryRef options
,
1246 const UInt8 anchorSha1
[kSecPolicySHA256Size
])
1248 bool success
= false;
1249 CFDataRef anchorData
= NULL
;
1251 require(anchorData
= CFDataCreate(kCFAllocatorDefault
, anchorSha1
, kSecPolicySHA256Size
), errOut
);
1252 add_element(options
, kSecPolicyCheckAnchorSHA256
, anchorData
);
1257 CFReleaseSafe(anchorData
);
1261 static bool SecPolicyAddStrongKeySizeOptions(CFMutableDictionaryRef options
) {
1262 bool success
= false;
1263 CFDictionaryRef keySizes
= NULL
;
1264 CFNumberRef rsaSize
= NULL
, ecSize
= NULL
;
1266 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
1267 require(rsaSize
= CFNumberCreateWithCFIndex(NULL
, 2048), errOut
);
1268 require(ecSize
= CFNumberCreateWithCFIndex(NULL
, 256), errOut
);
1269 const void *keys
[] = { kSecAttrKeyTypeRSA
, kSecAttrKeyTypeEC
};
1270 const void *values
[] = { rsaSize
, ecSize
};
1271 require(keySizes
= CFDictionaryCreate(NULL
, keys
, values
, 2,
1272 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1273 add_element(options
, kSecPolicyCheckKeySize
, keySizes
);
1278 CFReleaseSafe(keySizes
);
1279 CFReleaseSafe(rsaSize
);
1280 CFReleaseSafe(ecSize
);
1284 static bool SecPolicyRemoveWeakHashOptions(CFMutableDictionaryRef options
) {
1285 CFMutableArrayRef disallowedHashes
= CFArrayCreateMutable(NULL
, 5, &kCFTypeArrayCallBacks
);
1286 if (!disallowedHashes
) {
1289 CFArrayAppendValue(disallowedHashes
, kSecSignatureDigestAlgorithmMD2
);
1290 CFArrayAppendValue(disallowedHashes
, kSecSignatureDigestAlgorithmMD4
);
1291 CFArrayAppendValue(disallowedHashes
, kSecSignatureDigestAlgorithmMD5
);
1292 CFArrayAppendValue(disallowedHashes
, kSecSignatureDigestAlgorithmSHA1
);
1294 add_element(options
, kSecPolicyCheckSignatureHashAlgorithms
, disallowedHashes
);
1295 CFReleaseNull(disallowedHashes
);
1299 static bool isAppleOid(CFStringRef oid
) {
1300 if (!SecCertificateIsOidString(oid
)) {
1303 if (CFStringHasPrefix(oid
, CFSTR("1.2.840.113635"))) {
1309 static bool isCFPreferenceInSecurityDomain(CFStringRef setting
) {
1310 return (CFPreferencesGetAppBooleanValue(setting
, CFSTR("com.apple.security"), NULL
));
1313 static bool SecPolicyAddAppleAnchorOptions(CFMutableDictionaryRef options
, CFStringRef __unused policyName
)
1315 CFMutableDictionaryRef appleAnchorOptions
= NULL
;
1316 appleAnchorOptions
= CFDictionaryCreateMutableForCFTypes(NULL
);
1317 if (!appleAnchorOptions
) {
1321 /* Currently no Apple Anchor options */
1322 add_element(options
, kSecPolicyCheckAnchorApple
, appleAnchorOptions
);
1323 CFReleaseSafe(appleAnchorOptions
);
1327 static bool SecPolicyAddPinningRequiredIfInfoSpecified(CFMutableDictionaryRef options
)
1329 CFBundleRef bundle
= CFBundleGetMainBundle();
1331 CFTypeRef value
= CFBundleGetValueForInfoDictionaryKey(bundle
, CFSTR("SecTrustPinningRequired"));
1332 if (isBoolean(value
) && CFBooleanGetValue(value
)) {
1333 add_element(options
, kSecPolicyCheckPinningRequired
, kCFBooleanTrue
);
1342 // MARK: Policy Creation Functions
1344 SecPolicyRef
SecPolicyCreateBasicX509(void) {
1345 CFMutableDictionaryRef options
= NULL
;
1346 SecPolicyRef result
= NULL
;
1348 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1349 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1351 SecPolicyAddBasicX509Options(options
);
1352 CFDictionaryAddValue(options
, kSecPolicyCheckNoNetworkAccess
,
1355 require(result
= SecPolicyCreate(kSecPolicyAppleX509Basic
, kSecPolicyNameX509Basic
, options
), errOut
);
1358 CFReleaseSafe(options
);
1359 return (SecPolicyRef _Nonnull
)result
;
1362 SecPolicyRef
SecPolicyCreateSSL(Boolean server
, CFStringRef hostname
) {
1363 CFMutableDictionaryRef options
= NULL
;
1364 SecPolicyRef result
= NULL
;
1366 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1367 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1369 SecPolicyAddBasicX509Options(options
);
1372 CFDictionaryAddValue(options
, kSecPolicyCheckSSLHostname
, hostname
);
1375 CFDictionaryAddValue(options
, kSecPolicyCheckBlackListedLeaf
, kCFBooleanTrue
);
1376 CFDictionaryAddValue(options
, kSecPolicyCheckGrayListedLeaf
, kCFBooleanTrue
);
1379 require_quiet(SecPolicyRemoveWeakHashOptions(options
), errOut
);
1380 require_quiet(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
1381 require_quiet(SecPolicyAddPinningRequiredIfInfoSpecified(options
), errOut
);
1382 CFDictionaryAddValue(options
, kSecPolicyCheckValidityPeriodMaximums
, kCFBooleanTrue
);
1383 CFDictionaryAddValue(options
, kSecPolicyCheckServerAuthEKU
, kCFBooleanTrue
); // enforces stricter EKU rules than set_ssl_ekus below for certain anchor types
1384 #if !TARGET_OS_BRIDGE
1385 CFDictionaryAddValue(options
, kSecPolicyCheckSystemTrustedCTRequired
, kCFBooleanTrue
);
1389 set_ssl_ekus(options
, server
);
1391 require(result
= SecPolicyCreate(kSecPolicyAppleSSL
,
1392 server
? kSecPolicyNameSSLServer
: kSecPolicyNameSSLClient
,
1396 CFReleaseSafe(options
);
1397 return (SecPolicyRef _Nonnull
)result
;
1400 SecPolicyRef
SecPolicyCreateLegacySSL(Boolean server
, CFStringRef hostname
) {
1401 CFMutableDictionaryRef options
= NULL
;
1402 SecPolicyRef result
= NULL
;
1404 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1405 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1407 SecPolicyAddBasicX509Options(options
);
1410 CFDictionaryAddValue(options
, kSecPolicyCheckSSLHostname
, hostname
);
1413 CFDictionaryAddValue(options
, kSecPolicyCheckBlackListedLeaf
, kCFBooleanTrue
);
1414 CFDictionaryAddValue(options
, kSecPolicyCheckGrayListedLeaf
, kCFBooleanTrue
);
1417 // fewer requirements than the standard SSL policy
1418 require_quiet(SecPolicyAddPinningRequiredIfInfoSpecified(options
), errOut
);
1419 CFDictionaryAddValue(options
, kSecPolicyCheckValidityPeriodMaximums
, kCFBooleanTrue
);
1420 #if !TARGET_OS_BRIDGE
1421 CFDictionaryAddValue(options
, kSecPolicyCheckSystemTrustedCTRequired
, kCFBooleanTrue
);
1425 set_ssl_ekus(options
, server
);
1427 require(result
= SecPolicyCreate(kSecPolicyAppleLegacySSL
, kSecPolicyNameLegacySSL
, options
), errOut
);
1430 CFReleaseSafe(options
);
1431 return (SecPolicyRef _Nonnull
)result
;
1434 SecPolicyRef
SecPolicyCreateApplePinned(CFStringRef policyName
, CFStringRef intermediateMarkerOID
, CFStringRef leafMarkerOID
) {
1435 CFMutableDictionaryRef options
= NULL
;
1436 SecPolicyRef result
= NULL
;
1438 if (!policyName
|| !intermediateMarkerOID
|| !leafMarkerOID
) {
1442 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1443 &kCFTypeDictionaryKeyCallBacks
,
1444 &kCFTypeDictionaryValueCallBacks
), errOut
);
1446 SecPolicyAddBasicX509Options(options
);
1448 /* Anchored to the Apple Roots */
1449 require(SecPolicyAddAppleAnchorOptions(options
, policyName
), errOut
);
1451 /* Exactly 3 certs in the chain */
1452 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1454 /* Intermediate marker OID matches input OID */
1455 if (!isAppleOid(intermediateMarkerOID
)) {
1456 secwarning("creating an Apple pinning policy with a non-Apple OID: %@", intermediateMarkerOID
);
1458 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, intermediateMarkerOID
);
1460 /* Leaf marker OID matches input OID */
1461 if (!isAppleOid(leafMarkerOID
)) {
1462 secwarning("creating an Apple pinning policy with a non-Apple OID: %@", leafMarkerOID
);
1464 add_leaf_marker_string(options
, leafMarkerOID
);
1466 /* Check revocation using any available method */
1467 add_element(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
1469 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
1470 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
1472 /* Check for weak hashes */
1473 // require(SecPolicyRemoveWeakHashOptions(options), errOut); // the current WWDR CA cert is signed with SHA1
1474 require(result
= SecPolicyCreate(kSecPolicyAppleGenericApplePinned
,
1475 policyName
, options
), errOut
);
1478 CFReleaseSafe(options
);
1483 requireUATPinning(CFStringRef service
)
1485 bool pinningRequired
= true;
1487 if (SecIsInternalRelease()) {
1488 CFStringRef setting
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("AppleServerAuthenticationNoPinning%@"), service
);
1489 require(setting
, fail
);
1490 if(isCFPreferenceInSecurityDomain(setting
)) {
1491 pinningRequired
= false;
1493 secnotice("pinningQA", "could not disable pinning: %@ not true", setting
);
1497 if (!pinningRequired
) {
1501 if(isCFPreferenceInSecurityDomain(CFSTR("AppleServerAuthenticationNoPinning"))) {
1502 pinningRequired
= false;
1504 secnotice("pinningQA", "could not disable pinning: AppleServerAuthenticationNoPinning not true");
1507 secnotice("pinningQA", "could not disable pinning: not an internal release");
1510 return pinningRequired
;
1513 SecPolicyRef
SecPolicyCreateAppleSSLPinned(CFStringRef policyName
, CFStringRef hostname
,
1514 CFStringRef intermediateMarkerOID
, CFStringRef leafMarkerOID
) {
1515 CFMutableDictionaryRef options
= NULL
, appleAnchorOptions
= NULL
;
1516 SecPolicyRef result
= NULL
;
1518 if (!policyName
|| !hostname
|| !leafMarkerOID
) {
1522 if (requireUATPinning(policyName
)) {
1523 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1524 &kCFTypeDictionaryKeyCallBacks
,
1525 &kCFTypeDictionaryValueCallBacks
), errOut
);
1527 SecPolicyAddBasicX509Options(options
);
1529 /* Anchored to the Apple Roots */
1530 require(SecPolicyAddAppleAnchorOptions(options
, policyName
), errOut
);
1532 /* Exactly 3 certs in the chain */
1533 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1535 if (intermediateMarkerOID
) {
1536 /* Intermediate marker OID matches input OID */
1537 if (!isAppleOid(intermediateMarkerOID
)) {
1538 secwarning("creating an Apple pinning policy with a non-Apple OID: %@", intermediateMarkerOID
);
1540 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, intermediateMarkerOID
);
1542 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.12"));
1545 /* Leaf marker OID matches input OID */
1546 if (!isAppleOid(leafMarkerOID
)) {
1547 secwarning("creating an Apple pinning policy with a non-Apple OID: %@", leafMarkerOID
);
1549 add_leaf_marker_string(options
, leafMarkerOID
);
1551 /* New leaf marker OID format */
1552 add_leaf_marker_value_string(options
, CFSTR("1.2.840.113635.100.6.48.1"), leafMarkerOID
);
1554 /* ServerAuth EKU is in leaf cert */
1555 add_eku_string(options
, CFSTR("1.3.6.1.5.5.7.3.1"));
1557 /* Hostname is in leaf cert */
1558 add_element(options
, kSecPolicyCheckSSLHostname
, hostname
);
1560 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
1561 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
1563 /* Check for weak hashes */
1564 require(SecPolicyRemoveWeakHashOptions(options
), errOut
);
1566 /* Check revocation using any available method */
1567 add_element(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
1569 require(result
= SecPolicyCreate(kSecPolicyAppleGenericAppleSSLPinned
,
1570 policyName
, options
), errOut
);
1573 result
= SecPolicyCreateSSL(true, hostname
);
1574 SecPolicySetOid(result
, kSecPolicyAppleGenericAppleSSLPinned
);
1575 SecPolicySetName(result
, policyName
);
1579 CFReleaseSafe(options
);
1580 CFReleaseSafe(appleAnchorOptions
);
1584 SecPolicyRef
SecPolicyCreateiPhoneActivation(void) {
1585 CFMutableDictionaryRef options
= NULL
;
1586 SecPolicyRef result
= NULL
;
1588 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1589 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1591 SecPolicyAddBasicCertOptions(options
);
1594 CFDictionaryAddValue(options
, kSecPolicyCheckKeyUsage
,
1596 CFDictionaryAddValue(options
, kSecPolicyCheckExtendedKeyUsage
,
1600 /* Basic X.509 policy with the additional requirements that the chain
1601 length is 3, it's anchored at the AppleCA and the leaf certificate
1602 has issuer "Apple iPhone Certification Authority" and
1603 subject "Apple iPhone Activation" for the common name. */
1604 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
1605 CFSTR("Apple iPhone Certification Authority"));
1606 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
,
1607 CFSTR("Apple iPhone Activation"));
1609 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1610 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameiPhoneActivation
), errOut
);
1612 require(result
= SecPolicyCreate(kSecPolicyAppleiPhoneActivation
,
1613 kSecPolicyNameiPhoneActivation
, options
),
1617 CFReleaseSafe(options
);
1621 SecPolicyRef
SecPolicyCreateiPhoneDeviceCertificate(void) {
1622 CFMutableDictionaryRef options
= NULL
;
1623 SecPolicyRef result
= NULL
;
1625 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1626 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1628 SecPolicyAddBasicCertOptions(options
);
1631 CFDictionaryAddValue(options
, kSecPolicyCheckKeyUsage
,
1633 CFDictionaryAddValue(options
, kSecPolicyCheckExtendedKeyUsage
,
1637 /* Basic X.509 policy with the additional requirements that the chain
1638 length is 4, it's anchored at the AppleCA and the first intermediate
1639 has the subject "Apple iPhone Device CA". */
1640 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
1641 CFSTR("Apple iPhone Device CA"));
1643 require(SecPolicyAddChainLengthOptions(options
, 4), errOut
);
1644 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameiPhoneDeviceCertificate
), errOut
);
1646 require(result
= SecPolicyCreate(kSecPolicyAppleiPhoneDeviceCertificate
,
1647 kSecPolicyNameiPhoneDeviceCertificate
, options
),
1651 CFReleaseSafe(options
);
1655 SecPolicyRef
SecPolicyCreateFactoryDeviceCertificate(void) {
1656 CFMutableDictionaryRef options
= NULL
;
1657 SecPolicyRef result
= NULL
;
1659 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1660 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1662 SecPolicyAddBasicCertOptions(options
);
1665 CFDictionaryAddValue(options
, kSecPolicyCheckKeyUsage
,
1667 CFDictionaryAddValue(options
, kSecPolicyCheckExtendedKeyUsage
,
1671 /* Basic X.509 policy with the additional requirements that the chain
1672 is anchored at the factory device certificate issuer. */
1673 require(SecPolicyAddAnchorSHA1Options(options
, kFactoryDeviceCASHA1
), errOut
);
1675 require(result
= SecPolicyCreate(kSecPolicyAppleFactoryDeviceCertificate
,
1676 kSecPolicyNameFactoryDeviceCertificate
, options
),
1680 CFReleaseSafe(options
);
1684 SecPolicyRef
SecPolicyCreateiAP(void) {
1685 CFMutableDictionaryRef options
= NULL
;
1686 SecPolicyRef result
= NULL
;
1687 CFTimeZoneRef tz
= NULL
;
1688 CFDateRef date
= NULL
;
1690 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1691 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1693 SecPolicyAddBasicCertOptions(options
);
1695 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonNamePrefix
,
1698 date
= CFDateCreateForGregorianZuluDay(NULL
, 2006, 5, 31);
1699 CFDictionaryAddValue(options
, kSecPolicyCheckNotValidBefore
, date
);
1701 require(result
= SecPolicyCreate(kSecPolicyAppleiAP
,
1702 kSecPolicyNameiAP
, options
),
1706 CFReleaseSafe(date
);
1708 CFReleaseSafe(options
);
1712 SecPolicyRef
SecPolicyCreateiTunesStoreURLBag(void) {
1713 CFMutableDictionaryRef options
= NULL
;
1714 SecPolicyRef result
= NULL
;
1717 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1718 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1720 SecPolicyAddBasicCertOptions(options
);
1722 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectOrganization
,
1723 CFSTR("Apple Inc."));
1724 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
,
1725 CFSTR("iTunes Store URL Bag"));
1727 require(SecPolicyAddChainLengthOptions(options
, 2), errOut
);
1728 require(SecPolicyAddAnchorSHA1Options(options
, kITMSCASHA1
), errOut
);
1730 require(result
= SecPolicyCreate(kSecPolicyAppleiTunesStoreURLBag
,
1731 kSecPolicyNameiTunesStoreURLBag
, options
), errOut
);
1734 CFReleaseSafe(options
);
1738 SecPolicyRef
SecPolicyCreateEAP(Boolean server
, CFArrayRef trustedServerNames
) {
1739 CFMutableDictionaryRef options
= NULL
;
1740 SecPolicyRef result
= NULL
;
1742 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1743 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1745 SecPolicyAddBasicX509Options(options
);
1747 /* Since EAP is used to setup the network we don't want evaluation
1748 using this policy to access the network. */
1749 CFDictionaryAddValue(options
, kSecPolicyCheckNoNetworkAccess
,
1752 if (trustedServerNames
) {
1753 CFDictionaryAddValue(options
, kSecPolicyCheckEAPTrustedServerNames
, trustedServerNames
);
1757 /* Check for weak hashes and keys, but only on system-trusted roots, because enterprise
1758 * PKIs are the absolute worst. */
1759 CFDictionaryAddValue(options
, kSecPolicyCheckSystemTrustedWeakHash
, kCFBooleanTrue
);
1760 CFDictionaryAddValue(options
, kSecPolicyCheckSystemTrustedWeakKey
, kCFBooleanTrue
);
1763 /* We need to check for EKU per rdar://22206018 */
1764 set_ssl_ekus(options
, server
);
1766 require(result
= SecPolicyCreate(kSecPolicyAppleEAP
,
1767 server
? kSecPolicyNameEAPServer
: kSecPolicyNameEAPClient
,
1771 CFReleaseSafe(options
);
1775 SecPolicyRef
SecPolicyCreateIPSec(Boolean server
, CFStringRef hostname
) {
1776 CFMutableDictionaryRef options
= NULL
;
1777 SecPolicyRef result
= NULL
;
1779 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1780 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1782 SecPolicyAddBasicX509Options(options
);
1785 CFDictionaryAddValue(options
, kSecPolicyCheckSSLHostname
, hostname
);
1788 /* Require oidExtendedKeyUsageIPSec if Extended Keyusage Extention is
1790 /* Per <rdar://problem/6843827> Cisco VPN Certificate compatibility issue.
1791 We don't check the EKU for IPSec certs for now. If we do add eku
1792 checking back in the future, we should probably also accept the
1794 ipsecEndSystem 1.3.6.1.5.5.7.3.5
1796 ipsecTunnel 1.3.6.1.5.5.7.3.6
1797 ipsecUser 1.3.6.1.5.5.7.3.7
1799 //add_eku(options, NULL); /* eku extension is optional */
1800 //add_eku(options, &oidAnyExtendedKeyUsage);
1801 //add_eku(options, &oidExtendedKeyUsageIPSec);
1803 require(result
= SecPolicyCreate(kSecPolicyAppleIPsec
,
1804 server
? kSecPolicyNameIPSecServer
: kSecPolicyNameIPSecClient
,
1808 CFReleaseSafe(options
);
1812 SecPolicyRef
SecPolicyCreateiPhoneApplicationSigning(void) {
1813 CFMutableDictionaryRef options
= NULL
;
1814 SecPolicyRef result
= NULL
;
1816 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1817 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1819 SecPolicyAddBasicCertOptions(options
);
1821 /* Anchored to the Apple Roots */
1822 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameiPhoneApplicationSigning
), errOut
);
1825 if (SecIsInternalRelease()) {
1826 /* Allow a prod hierarchy-signed test cert */
1827 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonNameTEST
,
1828 CFSTR("Apple iPhone OS Application Signing"));
1829 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.3.1"));
1832 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
,
1833 CFSTR("Apple iPhone OS Application Signing"));
1835 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.3"));
1837 add_eku(options
, NULL
); /* eku extension is optional */
1838 add_eku(options
, &oidAnyExtendedKeyUsage
);
1839 add_eku(options
, &oidExtendedKeyUsageCodeSigning
);
1841 /* Intermediate check */
1842 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
1843 CFSTR("Apple iPhone Certification Authority"));
1845 /* Chain length check */
1846 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1848 /* Skip networked revocation checks */
1849 CFDictionaryAddValue(options
, kSecPolicyCheckNoNetworkAccess
, kCFBooleanTrue
);
1851 require(result
= SecPolicyCreate(kSecPolicyAppleiPhoneApplicationSigning
,
1852 kSecPolicyNameiPhoneApplicationSigning
, options
),
1856 CFReleaseSafe(options
);
1860 SecPolicyRef
SecPolicyCreateiPhoneVPNApplicationSigning(void) {
1861 CFMutableDictionaryRef options
= NULL
;
1862 SecPolicyRef result
= NULL
;
1864 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1865 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1867 SecPolicyAddBasicCertOptions(options
);
1869 /* Anchored to the Apple Roots */
1870 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameiPhoneVPNApplicationSigning
), errOut
);
1873 if (SecIsInternalRelease()) {
1874 /* Allow a prod hierarchy-signed test cert */
1875 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonNameTEST
,
1876 CFSTR("Apple iPhone OS Application Signing"));
1877 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.6.1"));
1880 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
,
1881 CFSTR("Apple iPhone OS Application Signing"));
1883 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.6"));
1885 add_eku(options
, NULL
); /* eku extension is optional */
1886 add_eku(options
, &oidAnyExtendedKeyUsage
);
1887 add_eku(options
, &oidExtendedKeyUsageCodeSigning
);
1889 /* Intermediate check */
1890 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
1891 CFSTR("Apple iPhone Certification Authority"));
1893 /* Chain length check */
1894 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1896 /* Skip networked revocation checks */
1897 CFDictionaryAddValue(options
, kSecPolicyCheckNoNetworkAccess
, kCFBooleanTrue
);
1899 require(result
= SecPolicyCreate(kSecPolicyAppleiPhoneVPNApplicationSigning
,
1900 kSecPolicyNameiPhoneVPNApplicationSigning
, options
),
1904 CFReleaseSafe(options
);
1908 SecPolicyRef
SecPolicyCreateiPhoneProfileApplicationSigning(void) {
1909 CFMutableDictionaryRef options
= NULL
;
1910 SecPolicyRef result
= NULL
;
1912 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1913 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1915 SecPolicyAddBasicX509Options(options
); // With expiration checking
1918 require_quiet(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameiPhoneProfileApplicationSigning
),
1922 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1924 /* Leaf has CodeSigning EKU */
1925 add_eku_string(options
, CFSTR("1.3.6.1.5.5.7.3.3"));
1927 /* On iOS, the cert in the provisioning profile may be one of:
1928 leaf OID intermediate OID
1929 iPhone Developer <ADS>.6.1.2 <ADS>.6.2.1
1930 iPhone Distribution <ADS>.6.1.4 <ADS>.6.2.1
1931 TestFlight (Prod) <ADS>.6.1.25.1 <ADS>.6.2.1
1932 TestFlight (QA) <ADS>.6.1.25.2 <ADS>.6.2.1
1934 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.1"));
1935 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.2"));
1936 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.4"));
1937 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.25.1"));
1938 if (SecIsInternalRelease()) {
1939 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.25.2"));
1942 /* Revocation via any available method */
1943 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
1945 require(result
= SecPolicyCreate(kSecPolicyAppleiPhoneProfileApplicationSigning
,
1946 kSecPolicyNameiPhoneProfileApplicationSigning
,
1950 CFReleaseSafe(options
);
1954 SecPolicyRef
SecPolicyCreateMacOSProfileApplicationSigning(void) {
1955 CFMutableDictionaryRef options
= NULL
;
1956 SecPolicyRef result
= NULL
;
1958 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1959 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1961 SecPolicyAddBasicCertOptions(options
); // Without expiration checking
1964 require_quiet(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameiPhoneProfileApplicationSigning
),
1968 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1970 /* Leaf has CodeSigning EKU */
1971 add_eku_string(options
, CFSTR("1.3.6.1.5.5.7.3.3"));
1974 /* On macOS, the cert in the provisioning profile may be one of:
1975 leaf OID intermediate OID
1976 MAS Development <ADS>.6.1.12 <ADS>.6.2.1
1977 MAS Submission <ADS>.6.1.7 <ADS>.6.2.1
1978 Developer ID <ADS>.6.1.13 <ADS>.6.2.6
1979 B&I <ADS>.6.22 None - "Apple Code Signing Certification Authority"
1981 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.12"));
1982 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.7"));
1983 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.13"));
1984 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.22"));
1986 /* Revocation via any available method */
1987 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
1989 require(result
= SecPolicyCreate(kSecPolicyAppleMacOSProfileApplicationSigning
,
1990 kSecPolicyNameMacOSProfileApplicationSigning
,
1994 CFReleaseSafe(options
);
1998 SecPolicyRef
SecPolicyCreateiPhoneProvisioningProfileSigning(void) {
1999 CFMutableDictionaryRef options
= NULL
;
2000 SecPolicyRef result
= NULL
;
2002 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2003 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2005 SecPolicyAddBasicCertOptions(options
);
2007 /* Basic X.509 policy with the additional requirements that the chain
2008 length is 3, it's anchored at the AppleCA and the leaf certificate
2009 has issuer "Apple iPhone Certification Authority" and
2010 subject "Apple iPhone OS Provisioning Profile Signing" for the common name. */
2011 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2012 CFSTR("Apple iPhone Certification Authority"));
2013 if (SecIsInternalRelease()) {
2014 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonNameTEST
,
2015 CFSTR("Apple iPhone OS Provisioning Profile Signing"));
2018 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
,
2019 CFSTR("Apple iPhone OS Provisioning Profile Signing"));
2022 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2023 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameiPhoneProvisioningProfileSigning
), errOut
);
2025 /* Skip networked revocation checks */
2026 CFDictionaryAddValue(options
, kSecPolicyCheckNoNetworkAccess
, kCFBooleanTrue
);
2028 require(result
= SecPolicyCreate(kSecPolicyAppleiPhoneProvisioningProfileSigning
,
2029 kSecPolicyNameiPhoneProvisioningProfileSigning
, options
),
2032 /* 1.2.840.113635.100.6.2.2.1, non-critical: DER:05:00 - provisioning profile */
2035 CFReleaseSafe(options
);
2039 SecPolicyRef
SecPolicyCreateAppleTVOSApplicationSigning(void) {
2040 CFMutableDictionaryRef options
= NULL
;
2041 SecPolicyRef result
= NULL
;
2042 CFDataRef atvProdOid
= NULL
;
2043 CFDataRef atvTestOid
= NULL
;
2044 CFArrayRef oids
= NULL
;
2046 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2047 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2049 SecPolicyAddBasicCertOptions(options
);
2051 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2053 require_quiet(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameTVOSApplicationSigning
),
2056 /* Check for intermediate: Apple Worldwide Developer Relations */
2057 /* 1.2.840.113635.100.6.2.1 */
2058 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleWWDR
);
2060 add_ku(options
, kSecKeyUsageDigitalSignature
);
2062 /* Check for prod or test AppleTV Application Signing OIDs */
2063 /* Prod: 1.2.840.113635.100.6.1.24 */
2064 /* ProdQA: 1.2.840.113635.100.6.1.24.1 */
2065 add_leaf_marker(options
, &oidAppleTVOSApplicationSigningProd
);
2066 add_leaf_marker(options
, &oidAppleTVOSApplicationSigningProdQA
);
2068 /* Skip networked revocation checks */
2069 CFDictionaryAddValue(options
, kSecPolicyCheckNoNetworkAccess
, kCFBooleanTrue
);
2071 require(result
= SecPolicyCreate(kSecPolicyAppleTVOSApplicationSigning
,
2072 kSecPolicyNameTVOSApplicationSigning
, options
),
2076 CFReleaseSafe(options
);
2077 CFReleaseSafe(oids
);
2078 CFReleaseSafe(atvProdOid
);
2079 CFReleaseSafe(atvTestOid
);
2083 SecPolicyRef
SecPolicyCreateOCSPSigner(void) {
2084 CFMutableDictionaryRef options
= NULL
;
2085 SecPolicyRef result
= NULL
;
2087 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2088 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2090 SecPolicyAddBasicX509Options(options
);
2092 /* Require id-kp-OCSPSigning extendedKeyUsage to be present, not optional. */
2093 add_eku(options
, &oidExtendedKeyUsageOCSPSigning
);
2095 require(result
= SecPolicyCreate(kSecPolicyAppleOCSPSigner
,
2096 kSecPolicyNameOCSPSigner
, options
), errOut
);
2099 CFReleaseSafe(options
);
2103 SecPolicyRef
SecPolicyCreateRevocation(CFOptionFlags revocationFlags
) {
2104 CFMutableDictionaryRef options
= NULL
;
2105 SecPolicyRef result
= NULL
;
2107 require(revocationFlags
!= 0, errOut
);
2109 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2110 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2112 if (revocationFlags
& kSecRevocationCheckIfTrusted
) {
2113 CFDictionaryAddValue(options
, kSecPolicyCheckRevocationIfTrusted
, kCFBooleanTrue
);
2114 /* Set method, but allow caller to override with later checks */
2115 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
2118 if (revocationFlags
& kSecRevocationOnlineCheck
) {
2119 CFDictionaryAddValue(options
, kSecPolicyCheckRevocationOnline
, kCFBooleanTrue
);
2120 /* Set method, but allow caller to override with later checks */
2121 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
2124 if (revocationFlags
& kSecRevocationOCSPMethod
&& revocationFlags
& kSecRevocationCRLMethod
) {
2125 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
2127 else if (revocationFlags
& kSecRevocationOCSPMethod
) {
2128 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationOCSP
);
2130 else if (revocationFlags
& kSecRevocationCRLMethod
) {
2131 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationCRL
);
2134 if (revocationFlags
& kSecRevocationRequirePositiveResponse
) {
2135 CFDictionaryAddValue(options
, kSecPolicyCheckRevocationResponseRequired
, kCFBooleanTrue
);
2138 if (revocationFlags
& kSecRevocationNetworkAccessDisabled
) {
2139 CFDictionaryAddValue(options
, kSecPolicyCheckNoNetworkAccess
, kCFBooleanTrue
);
2141 /* If the caller didn't explicitly disable network access, the revocation policy
2142 * should override any other policy's network setting.
2143 * In particular, pairing a revocation policy with BasicX509 should result in
2144 * allowing network access for revocation unless explicitly disabled.
2145 * Note that SecTrustSetNetworkFetchAllowed can override even this. */
2146 CFDictionaryAddValue(options
, kSecPolicyCheckNoNetworkAccess
, kCFBooleanFalse
);
2149 /* Only flag bits 0-6 are currently defined */
2150 require(((revocationFlags
>> 7) == 0), errOut
);
2152 require(result
= SecPolicyCreate(kSecPolicyAppleRevocation
,
2153 kSecPolicyNameRevocation
, options
), errOut
);
2156 CFReleaseSafe(options
);
2160 SecPolicyRef
SecPolicyCreateSMIME(CFIndex smimeUsage
, CFStringRef email
) {
2161 CFMutableDictionaryRef options
= NULL
;
2162 SecPolicyRef result
= NULL
;
2164 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2165 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2167 if (smimeUsage
& kSecIgnoreExpirationSMIMEUsage
) {
2168 SecPolicyAddBasicCertOptions(options
);
2170 SecPolicyAddBasicX509Options(options
);
2173 /* We call add_ku for each combination of bits we are willing to allow. */
2174 if (smimeUsage
& kSecSignSMIMEUsage
) {
2175 add_ku(options
, kSecKeyUsageUnspecified
);
2176 add_ku(options
, kSecKeyUsageDigitalSignature
);
2177 add_ku(options
, kSecKeyUsageNonRepudiation
);
2179 if (smimeUsage
& kSecKeyEncryptSMIMEUsage
) {
2180 add_ku(options
, kSecKeyUsageKeyEncipherment
);
2182 if (smimeUsage
& kSecDataEncryptSMIMEUsage
) {
2183 add_ku(options
, kSecKeyUsageDataEncipherment
);
2185 if (smimeUsage
& kSecKeyExchangeDecryptSMIMEUsage
) {
2186 add_ku(options
, kSecKeyUsageKeyAgreement
| kSecKeyUsageDecipherOnly
);
2188 if (smimeUsage
& kSecKeyExchangeEncryptSMIMEUsage
) {
2189 add_ku(options
, kSecKeyUsageKeyAgreement
| kSecKeyUsageEncipherOnly
);
2191 if (smimeUsage
& kSecKeyExchangeBothSMIMEUsage
) {
2192 add_ku(options
, kSecKeyUsageKeyAgreement
| kSecKeyUsageEncipherOnly
| kSecKeyUsageDecipherOnly
);
2196 CFDictionaryAddValue(options
, kSecPolicyCheckEmail
, email
);
2199 /* RFC 3850 paragraph 4.4.4
2201 If the extended key usage extension is present in the certificate
2202 then interpersonal message S/MIME receiving agents MUST check that it
2203 contains either the emailProtection or the anyExtendedKeyUsage OID as
2204 defined in [KEYM]. S/MIME uses other than interpersonal messaging
2205 MAY require the explicit presence of the extended key usage extension
2206 or other OIDs to be present in the extension or both.
2208 add_eku(options
, NULL
); /* eku extension is optional */
2209 add_eku(options
, &oidAnyExtendedKeyUsage
);
2210 add_eku(options
, &oidExtendedKeyUsageEmailProtection
);
2212 #if !TARGET_OS_IPHONE
2213 // Check revocation on OS X
2214 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
2217 require(result
= SecPolicyCreate(kSecPolicyAppleSMIME
, kSecPolicyNameSMIME
, options
), errOut
);
2220 CFReleaseSafe(options
);
2224 SecPolicyRef
SecPolicyCreateApplePackageSigning(void) {
2225 CFMutableDictionaryRef options
= NULL
;
2226 SecPolicyRef result
= NULL
;
2228 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2229 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2231 SecPolicyAddBasicCertOptions(options
);
2233 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2234 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNamePackageSigning
), errOut
);
2236 add_ku(options
, kSecKeyUsageDigitalSignature
);
2237 add_eku(options
, &oidExtendedKeyUsageCodeSigning
);
2239 require(result
= SecPolicyCreate(kSecPolicyApplePackageSigning
,
2240 kSecPolicyNamePackageSigning
, options
),
2244 CFReleaseSafe(options
);
2249 SecPolicyRef
SecPolicyCreateAppleSWUpdateSigning(void) {
2250 CFMutableDictionaryRef options
= NULL
;
2251 SecPolicyRef result
= NULL
;
2253 * OS X rules for this policy:
2254 * -- Must have one intermediate cert
2255 * -- intermediate must have basic constraints with path length 0
2256 * -- intermediate has CSSMOID_APPLE_EKU_CODE_SIGNING EKU
2257 * -- leaf cert has either CODE_SIGNING or CODE_SIGN_DEVELOPMENT EKU (the latter of
2258 * which triggers a CSSMERR_APPLETP_CODE_SIGN_DEVELOPMENT error)
2260 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2261 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2263 SecPolicyAddBasicX509Options(options
);
2265 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2266 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameSWUpdateSigning
), errOut
);
2268 add_eku(options
, &oidAppleExtendedKeyUsageCodeSigning
);
2269 add_oid(options
, kSecPolicyCheckIntermediateEKU
, &oidAppleExtendedKeyUsageCodeSigning
);
2271 require(result
= SecPolicyCreate(kSecPolicyAppleSWUpdateSigning
,
2272 kSecPolicyNameSWUpdateSigning
, options
),
2276 CFReleaseSafe(options
);
2281 SecPolicyRef
SecPolicyCreateCodeSigning(void) {
2282 CFMutableDictionaryRef options
= NULL
;
2283 SecPolicyRef result
= NULL
;
2285 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2286 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2288 SecPolicyAddBasicX509Options(options
);
2290 /* If the key usage extension is present, we accept it having either of
2292 add_ku(options
, kSecKeyUsageDigitalSignature
);
2293 add_ku(options
, kSecKeyUsageNonRepudiation
);
2295 /* We require an extended key usage extension with the codesigning
2296 eku purpose. (The Apple codesigning eku is not accepted here
2297 since it's valid only for SecPolicyCreateAppleSWUpdateSigning.) */
2298 add_eku(options
, &oidExtendedKeyUsageCodeSigning
);
2299 #if TARGET_OS_IPHONE
2300 /* Accept the 'any' eku on iOS only to match prior behavior.
2301 This may be further restricted in future releases. */
2302 add_eku(options
, &oidAnyExtendedKeyUsage
);
2305 require(result
= SecPolicyCreate(kSecPolicyAppleCodeSigning
,
2306 kSecPolicyNameCodeSigning
, options
),
2310 CFReleaseSafe(options
);
2314 /* Explicitly leave out empty subject/subjectaltname check */
2315 SecPolicyRef
SecPolicyCreateLockdownPairing(void) {
2316 CFMutableDictionaryRef options
= NULL
;
2317 SecPolicyRef result
= NULL
;
2319 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2320 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2321 //CFDictionaryAddValue(options, kSecPolicyCheckBasicCertificateProcessing,
2322 // kCFBooleanTrue); // Happens automatically in SecPVCPathChecks
2323 CFDictionaryAddValue(options
, kSecPolicyCheckCriticalExtensions
,
2325 CFDictionaryAddValue(options
, kSecPolicyCheckIdLinkage
,
2327 CFDictionaryAddValue(options
, kSecPolicyCheckBasicConstraints
,
2329 CFDictionaryAddValue(options
, kSecPolicyCheckWeakKeySize
, kCFBooleanTrue
);
2331 require(result
= SecPolicyCreate(kSecPolicyAppleLockdownPairing
,
2332 kSecPolicyNameLockdownPairing
, options
), errOut
);
2335 CFReleaseSafe(options
);
2339 SecPolicyRef
SecPolicyCreateURLBag(void) {
2340 CFMutableDictionaryRef options
= NULL
;
2341 SecPolicyRef result
= NULL
;
2343 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2344 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2346 SecPolicyAddBasicCertOptions(options
);
2348 add_eku(options
, &oidExtendedKeyUsageCodeSigning
);
2350 require(result
= SecPolicyCreate(kSecPolicyAppleURLBag
,
2351 kSecPolicyNameURLBag
, options
), errOut
);
2354 CFReleaseSafe(options
);
2358 SecPolicyRef
SecPolicyCreateOTATasking(void)
2360 CFMutableDictionaryRef options
= NULL
;
2361 SecPolicyRef result
= NULL
;
2363 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2364 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2366 SecPolicyAddBasicX509Options(options
);
2369 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameMobileAsset
), errOut
);
2371 /* Chain length of 3 */
2372 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2374 /* Intermediate has common name "Apple iPhone Certification Authority". */
2375 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2376 CFSTR("Apple iPhone Certification Authority"));
2378 /* Leaf has common name "Asset Manifest Signing" */
2379 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
, CFSTR("OTA Task Signing"));
2381 require(result
= SecPolicyCreate(kSecPolicyAppleOTATasking
, kSecPolicyNameOTATasking
, options
),
2385 CFReleaseSafe(options
);
2389 SecPolicyRef
SecPolicyCreateMobileAsset(void)
2391 CFMutableDictionaryRef options
= NULL
;
2392 SecPolicyRef result
= NULL
;
2394 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2395 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2397 /* No expiration check */
2398 SecPolicyAddBasicCertOptions(options
);
2401 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameMobileAsset
), errOut
);
2403 /* Chain length of 3 */
2404 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2406 /* Intermediate has common name "Apple iPhone Certification Authority". */
2407 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2408 CFSTR("Apple iPhone Certification Authority"));
2410 /* Leaf has common name "Asset Manifest Signing" */
2411 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
, CFSTR("Asset Manifest Signing"));
2413 require(result
= SecPolicyCreate(kSecPolicyAppleMobileAsset
, kSecPolicyNameMobileAsset
, options
),
2417 CFReleaseSafe(options
);
2421 SecPolicyRef
SecPolicyCreateMobileAssetDevelopment(void) {
2422 CFMutableDictionaryRef options
= NULL
;
2423 SecPolicyRef result
= NULL
;
2425 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2426 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2428 /* No expiration check */
2429 SecPolicyAddBasicCertOptions(options
);
2432 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameMobileAsset
), errOut
);
2434 /* Chain length of 3 */
2435 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2437 /* Intermediate has the iPhone CA Marker extension */
2438 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.18"));
2440 /* Leaf has ProdQA Mobile Asset Marker extension */
2441 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.55.1"));
2443 require(result
= SecPolicyCreate(kSecPolicyAppleMobileAssetDevelopment
, kSecPolicyNameMobileAsset
, options
),
2447 CFReleaseSafe(options
);
2451 SecPolicyRef
SecPolicyCreateAppleIDAuthorityPolicy(void)
2453 SecPolicyRef result
= NULL
;
2454 CFMutableDictionaryRef options
= NULL
;
2455 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2456 &kCFTypeDictionaryKeyCallBacks
,
2457 &kCFTypeDictionaryValueCallBacks
), out
);
2459 //Leaf appears to be a SSL only cert, so policy should expand on that policy
2460 SecPolicyAddBasicX509Options(options
);
2462 // Apple CA anchored
2463 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameIDAuthority
), out
);
2465 // with the addition of the existence check of an extension with "Apple ID Sharing Certificate" oid (1.2.840.113635.100.4.7)
2466 // NOTE: this obviously intended to have gone into Extended Key Usage, but evidence of existing certs proves the contrary.
2467 add_leaf_marker(options
, &oidAppleExtendedKeyUsageAppleID
);
2469 // 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.
2470 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleID
);
2471 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleID2
);
2473 require(result
= SecPolicyCreate(kSecPolicyAppleIDAuthority
,
2474 kSecPolicyNameIDAuthority
, options
), out
);
2477 CFReleaseSafe(options
);
2481 SecPolicyRef
SecPolicyCreateMacAppStoreReceipt(void)
2483 SecPolicyRef result
= NULL
;
2484 CFMutableDictionaryRef options
= NULL
;
2485 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2486 &kCFTypeDictionaryKeyCallBacks
,
2487 &kCFTypeDictionaryValueCallBacks
), out
);
2489 SecPolicyAddBasicX509Options(options
);
2491 // Apple CA anchored
2492 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameMacAppStoreReceipt
), out
);
2494 // Chain length of 3
2495 require(SecPolicyAddChainLengthOptions(options
, 3), out
);
2497 // MacAppStoreReceipt policy OID
2498 add_certificate_policy_oid_string(options
, CFSTR("1.2.840.113635.100.5.6.1"));
2500 // Intermediate marker OID
2501 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.1"));
2504 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.11.1"));
2507 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
2509 require(result
= SecPolicyCreate(kSecPolicyMacAppStoreReceipt
,
2510 kSecPolicyNameMacAppStoreReceipt
, options
), out
);
2513 CFReleaseSafe(options
);
2518 static SecPolicyRef
_SecPolicyCreatePassbookCardSigner(CFStringRef cardIssuer
, CFStringRef teamIdentifier
, bool requireTeamID
)
2520 SecPolicyRef result
= NULL
;
2521 CFMutableDictionaryRef options
= NULL
;
2522 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2523 &kCFTypeDictionaryKeyCallBacks
,
2524 &kCFTypeDictionaryValueCallBacks
), out
);
2526 SecPolicyAddBasicX509Options(options
);
2527 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNamePassbookSigning
), out
);
2529 // Chain length of 3
2530 require(SecPolicyAddChainLengthOptions(options
, 3), out
);
2532 if (teamIdentifier
) {
2533 // If supplied, teamIdentifier must match subject OU field
2534 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectOrganizationalUnit
, teamIdentifier
);
2537 // If not supplied, and it was required, fail
2538 require(!requireTeamID
, out
);
2541 // Must be both push and 3rd party package signing
2542 add_leaf_marker_value(options
, &oidAppleInstallerPackagingSigningExternal
, cardIssuer
);
2544 // We should check that it also has push marker, but we don't support requiring both, only either.
2545 // add_independent_oid(options, kSecPolicyCheckLeafMarkerOid, &oidApplePushServiceClient);
2547 //WWDR Intermediate marker OID
2548 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.1"));
2550 // And Passbook signing eku
2551 add_eku(options
, &oidAppleExtendedKeyUsagePassbook
);
2553 require(result
= SecPolicyCreate(kSecPolicyApplePassbookSigning
,
2554 kSecPolicyNamePassbookSigning
, options
), out
);
2557 CFReleaseSafe(options
);
2561 SecPolicyRef
SecPolicyCreatePassbookCardSigner(CFStringRef cardIssuer
, CFStringRef teamIdentifier
)
2563 return _SecPolicyCreatePassbookCardSigner(cardIssuer
, teamIdentifier
, true);
2567 static SecPolicyRef
CreateMobileStoreSigner(Boolean forTest
)
2570 SecPolicyRef result
= NULL
;
2571 CFMutableDictionaryRef options
= NULL
;
2572 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2573 &kCFTypeDictionaryKeyCallBacks
,
2574 &kCFTypeDictionaryValueCallBacks
), errOut
);
2575 SecPolicyAddBasicX509Options(options
);
2576 require(SecPolicyAddAppleAnchorOptions(options
,
2577 ((forTest
) ? kSecPolicyNameTestMobileStore
:
2578 kSecPolicyNameMobileStore
)), errOut
);
2580 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2582 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2583 CFSTR("Apple System Integration 2 Certification Authority"));
2585 add_ku(options
, kSecKeyUsageDigitalSignature
);
2587 const DERItem
* pOID
= (forTest
) ? &oidApplePolicyMobileStoreProdQA
: &oidApplePolicyMobileStore
;
2589 add_certificate_policy_oid(options
, pOID
);
2591 require(result
= SecPolicyCreate((forTest
) ? kSecPolicyAppleTestMobileStore
: kSecPolicyAppleMobileStore
,
2592 (forTest
) ? kSecPolicyNameTestMobileStore
: kSecPolicyNameMobileStore
,
2596 CFReleaseSafe(options
);
2600 SecPolicyRef
SecPolicyCreateMobileStoreSigner(void)
2602 return CreateMobileStoreSigner(false);
2605 SecPolicyRef
SecPolicyCreateTestMobileStoreSigner(void)
2607 return CreateMobileStoreSigner(true);
2611 CF_RETURNS_RETAINED SecPolicyRef
SecPolicyCreateEscrowServiceSigner(void)
2613 SecPolicyRef result
= NULL
;
2614 CFMutableDictionaryRef options
= NULL
;
2615 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2616 &kCFTypeDictionaryKeyCallBacks
,
2617 &kCFTypeDictionaryValueCallBacks
), errOut
);
2619 // X509, ignoring date validity
2620 SecPolicyAddBasicCertOptions(options
);
2622 add_ku(options
, kSecKeyUsageKeyEncipherment
);
2624 /* Leaf has marker OID with value that can't be pre-determined */
2625 add_element(options
, kSecPolicyCheckLeafMarkerOidWithoutValueCheck
, CFSTR("1.2.840.113635.100.6.23.1"));
2626 require(SecPolicyAddChainLengthOptions(options
, 2), errOut
);
2628 require(result
= SecPolicyCreate(kSecPolicyAppleEscrowService
,
2629 kSecPolicyNameEscrowService
, options
), errOut
);
2632 CFReleaseSafe(options
);
2636 CF_RETURNS_RETAINED SecPolicyRef
SecPolicyCreatePCSEscrowServiceSigner(void)
2638 SecPolicyRef result
= NULL
;
2639 CFMutableDictionaryRef options
= NULL
;
2640 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2641 &kCFTypeDictionaryKeyCallBacks
,
2642 &kCFTypeDictionaryValueCallBacks
), errOut
);
2644 SecPolicyAddBasicX509Options(options
);
2645 add_ku(options
, kSecKeyUsageKeyEncipherment
);
2647 /* Leaf has marker OID with value that can't be pre-determined */
2648 add_element(options
, kSecPolicyCheckLeafMarkerOidWithoutValueCheck
, CFSTR("1.2.840.113635.100.6.23.1"));
2649 require(SecPolicyAddChainLengthOptions(options
, 2), errOut
);
2651 require(result
= SecPolicyCreate(kSecPolicyApplePCSEscrowService
,
2652 kSecPolicyNamePCSEscrowService
, options
), errOut
);
2655 CFReleaseSafe(options
);
2659 static SecPolicyRef
CreateConfigurationProfileSigner(bool forTest
) {
2660 SecPolicyRef result
= NULL
;
2661 CFMutableDictionaryRef options
= NULL
;
2662 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2663 &kCFTypeDictionaryKeyCallBacks
,
2664 &kCFTypeDictionaryValueCallBacks
), errOut
);
2666 SecPolicyAddBasicX509Options(options
);
2667 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameProfileSigner
), errOut
);
2670 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2672 // Require the profile signing EKU
2673 const DERItem
* pOID
= (forTest
) ? &oidAppleExtendedKeyUsageQAProfileSigning
:&oidAppleExtendedKeyUsageProfileSigning
;
2674 add_eku(options
, pOID
);
2676 // Require the Apple Application Integration CA marker OID
2677 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.3"));
2679 require(result
= SecPolicyCreate((forTest
) ? kSecPolicyAppleQAProfileSigner
: kSecPolicyAppleProfileSigner
,
2680 (forTest
) ? kSecPolicyNameQAProfileSigner
: kSecPolicyNameProfileSigner
,
2684 CFReleaseSafe(options
);
2688 SecPolicyRef
SecPolicyCreateConfigurationProfileSigner(void)
2690 return CreateConfigurationProfileSigner(false);
2694 SecPolicyRef
SecPolicyCreateQAConfigurationProfileSigner(void)
2696 if (SecIsInternalRelease()) {
2697 return CreateConfigurationProfileSigner(true);
2699 return CreateConfigurationProfileSigner(false);
2703 SecPolicyRef
SecPolicyCreateOSXProvisioningProfileSigning(void)
2705 SecPolicyRef result
= NULL
;
2706 CFMutableDictionaryRef options
= NULL
;
2707 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2708 &kCFTypeDictionaryKeyCallBacks
,
2709 &kCFTypeDictionaryValueCallBacks
), errOut
);
2710 // Require valid chain from the Apple root
2711 SecPolicyAddBasicX509Options(options
);
2712 SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameOSXProvisioningProfileSigning
);
2714 // Require provisioning profile leaf marker OID (1.2.840.113635.100.4.11)
2715 add_leaf_marker(options
, &oidAppleCertExtOSXProvisioningProfileSigning
);
2717 // Require intermediate marker OID (1.2.840.113635.100.6.2.1)
2718 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleWWDR
);
2720 // Require key usage that allows signing
2721 add_ku(options
, kSecKeyUsageDigitalSignature
);
2723 // Ensure that revocation is checked (OCSP)
2724 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationOCSP
);
2726 require(result
= SecPolicyCreate(kSecPolicyAppleOSXProvisioningProfileSigning
,
2727 kSecPolicyNameOSXProvisioningProfileSigning
, options
), errOut
);
2730 CFReleaseSafe(options
);
2735 SecPolicyRef
SecPolicyCreateOTAPKISigner(void)
2737 SecPolicyRef result
= NULL
;
2738 CFMutableDictionaryRef options
= NULL
;
2739 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2740 &kCFTypeDictionaryKeyCallBacks
,
2741 &kCFTypeDictionaryValueCallBacks
), errOut
);
2742 SecPolicyAddBasicX509Options(options
);
2744 SecPolicyAddAnchorSHA1Options(options
, kApplePKISettingsAuthority
);
2745 require(SecPolicyAddChainLengthOptions(options
, 2), errOut
);
2747 require(result
= SecPolicyCreate(kSecPolicyAppleOTAPKISigner
,
2748 kSecPolicyNameOTAPKISigner
, options
), errOut
);
2751 CFReleaseSafe(options
);
2757 SecPolicyRef
SecPolicyCreateTestOTAPKISigner(void)
2759 /* Guard against use on production devices */
2760 if (!SecIsInternalRelease()) {
2761 return SecPolicyCreateOTAPKISigner();
2764 SecPolicyRef result
= NULL
;
2765 CFMutableDictionaryRef options
= NULL
;
2766 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2767 &kCFTypeDictionaryKeyCallBacks
,
2768 &kCFTypeDictionaryValueCallBacks
), errOut
);
2769 SecPolicyAddBasicX509Options(options
);
2771 SecPolicyAddAnchorSHA1Options(options
, kAppleTestPKISettingsAuthority
);
2772 require(SecPolicyAddChainLengthOptions(options
, 2), errOut
);
2774 require(result
= SecPolicyCreate(kSecPolicyAppleTestOTAPKISigner
,
2775 kSecPolicyNameTestOTAPKISigner
, options
), errOut
);
2778 CFReleaseSafe(options
);
2783 @function SecPolicyCreateAppleSMPEncryption
2784 @abstract Check for intermediate certificate 'Apple System Integration CA - G3' by name,
2785 and root certificate 'Apple Root CA - G3' by hash.
2786 Leaf cert must have Key Encipherment usage.
2787 Leaf cert must have Apple SMP Encryption marker OID (1.2.840.113635.100.6.30).
2788 Intermediate must have marker OID (1.2.840.113635.100.6.2.13).
2790 SecPolicyRef
SecPolicyCreateAppleSMPEncryption(void)
2792 SecPolicyRef result
= NULL
;
2793 CFMutableDictionaryRef options
= NULL
;
2794 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2795 &kCFTypeDictionaryKeyCallBacks
,
2796 &kCFTypeDictionaryValueCallBacks
), errOut
);
2797 SecPolicyAddBasicCertOptions(options
);
2799 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameSMPEncryption
),
2801 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2803 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2804 CFSTR("Apple System Integration CA - G3"));
2806 // Check that leaf has extension with "Apple SMP Encryption" oid (1.2.840.113635.100.6.30)
2807 add_leaf_marker(options
, &oidAppleCertExtAppleSMPEncryption
);
2809 // Check that intermediate has extension (1.2.840.113635.100.6.2.13)
2810 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleSystemIntgG3
);
2812 add_ku(options
, kSecKeyUsageKeyEncipherment
);
2814 // Ensure that revocation is checked (OCSP)
2815 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationOCSP
);
2817 require(result
= SecPolicyCreate(kSecPolicyAppleSMPEncryption
,
2818 kSecPolicyNameSMPEncryption
, options
), errOut
);
2821 CFReleaseSafe(options
);
2826 @function SecPolicyCreateTestAppleSMPEncryption
2827 @abstract Check for intermediate certificate 'Test Apple System Integration CA - ECC' by name,
2828 and root certificate 'Test Apple Root CA - ECC' by hash.
2829 Leaf cert must have Key Encipherment usage. Other checks TBD.
2831 SecPolicyRef
SecPolicyCreateTestAppleSMPEncryption(void)
2833 SecPolicyRef result
= NULL
;
2834 CFMutableDictionaryRef options
= NULL
;
2835 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2836 &kCFTypeDictionaryKeyCallBacks
,
2837 &kCFTypeDictionaryValueCallBacks
), errOut
);
2838 SecPolicyAddBasicCertOptions(options
);
2840 SecPolicyAddAnchorSHA1Options(options
, kTestAppleRootCA_ECC_SHA1
);
2841 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2843 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2844 CFSTR("Test Apple System Integration CA - ECC"));
2846 add_ku(options
, kSecKeyUsageKeyEncipherment
);
2848 // Ensure that revocation is checked (OCSP)
2849 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationOCSP
);
2851 require(result
= SecPolicyCreate(kSecPolicyAppleTestSMPEncryption
,
2852 kSecPolicyNameTestSMPEncryption
, options
), errOut
);
2855 CFReleaseSafe(options
);
2860 SecPolicyRef
SecPolicyCreateAppleIDValidationRecordSigningPolicy(void)
2862 SecPolicyRef result
= NULL
;
2863 CFMutableDictionaryRef options
= NULL
;
2864 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2865 &kCFTypeDictionaryKeyCallBacks
,
2866 &kCFTypeDictionaryValueCallBacks
), errOut
);
2868 //Leaf appears to be a SSL only cert, so policy should expand on that policy
2869 SecPolicyAddBasicX509Options(options
);
2871 // Apple CA anchored
2872 require(SecPolicyAddAppleAnchorOptions(options
,
2873 kSecPolicyNameIDValidationRecordSigning
),
2876 // Check for an extension with " Apple ID Validation Record Signing" oid (1.2.840.113635.100.6.25)
2877 add_leaf_marker(options
, &oidAppleCertExtensionAppleIDRecordValidationSigning
);
2879 // and validate that intermediate has extension
2880 // Application Integration Intermediate Certificate (1.2.840.113635.100.6.2.3)
2881 // and also validate that intermediate has extension
2882 // System Integration 2 Intermediate Certificate (1.2.840.113635.100.6.2.10)
2883 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleID
);
2884 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleSystemIntg2
);
2886 // Ensure that revocation is checked (OCSP)
2887 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationOCSP
);
2889 require(result
= SecPolicyCreate(kSecPolicyAppleIDValidationRecordSigning
,
2890 kSecPolicyNameIDValidationRecordSigning
, options
), errOut
);
2893 CFReleaseSafe(options
);
2898 @function SecPolicyCreateAppleServerAuthCommon
2899 @abstract Generic policy for server authentication Sub CAs
2901 Allows control for both if pinning is required at all and if UAT environments should be added
2902 to the trust policy.
2904 No pinning is for developer/QA that needs to use proxy to debug the protocol, while UAT
2905 environment is for QA/internal developer that have no need allow fake servers.
2907 Both the noPinning and UAT are gated on that you run on internal hardware.
2912 SecPolicyCreateAppleServerAuthCommon(CFStringRef hostname
,
2913 CFDictionaryRef __unused context
,
2914 CFStringRef policyOID
, CFStringRef service
,
2915 const DERItem
*leafMarkerOID
,
2916 const DERItem
*UATLeafMarkerOID
)
2918 CFMutableDictionaryRef appleAnchorOptions
= NULL
;
2919 CFMutableDictionaryRef options
= NULL
;
2920 SecPolicyRef result
= NULL
;
2921 CFDataRef oid
= NULL
, uatoid
= NULL
;
2923 options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0, &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
2924 require(options
, errOut
);
2926 SecPolicyAddBasicX509Options(options
);
2928 require(hostname
, errOut
);
2929 CFDictionaryAddValue(options
, kSecPolicyCheckSSLHostname
, hostname
);
2931 CFDictionaryAddValue(options
, kSecPolicyCheckBlackListedLeaf
, kCFBooleanTrue
);
2932 CFDictionaryAddValue(options
, kSecPolicyCheckGrayListedLeaf
, kCFBooleanTrue
);
2934 add_eku(options
, &oidExtendedKeyUsageServerAuth
);
2936 if (requireUATPinning(service
)) {
2939 * Require pinning to the Apple CA's.
2941 SecPolicyAddAppleAnchorOptions(options
, service
);
2943 /* old-style leaf marker OIDs */
2944 if (UATLeafMarkerOID
) {
2945 add_leaf_prod_qa_markers(options
, leafMarkerOID
, UATLeafMarkerOID
);
2947 add_leaf_marker(options
, leafMarkerOID
);
2950 /* new-style leaf marker OIDs */
2951 CFStringRef leafMarkerOIDStr
= NULL
, UATLeafMarkerOIDStr
= NULL
;
2952 leafMarkerOIDStr
= SecDERItemCopyOIDDecimalRepresentation(NULL
, leafMarkerOID
);
2953 if (UATLeafMarkerOID
) {
2954 UATLeafMarkerOIDStr
= SecDERItemCopyOIDDecimalRepresentation(NULL
, UATLeafMarkerOID
);
2957 if (leafMarkerOIDStr
&& UATLeafMarkerOIDStr
) {
2958 add_leaf_prod_qa_markers_value_string(options
,
2959 CFSTR("1.2.840.113635.100.6.48.1"), leafMarkerOIDStr
,
2960 CFSTR("1.2.840.113635.100.6.48.1"), UATLeafMarkerOIDStr
);
2961 } else if (leafMarkerOIDStr
) {
2962 add_leaf_marker_value_string(options
, CFSTR("1.2.840.113635.100.6.48.1"), leafMarkerOIDStr
);
2965 CFReleaseNull(leafMarkerOIDStr
);
2966 CFReleaseNull(UATLeafMarkerOIDStr
);
2968 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleServerAuthentication
);
2971 /* Check for weak hashes and keys */
2972 require(SecPolicyRemoveWeakHashOptions(options
), errOut
);
2973 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
2975 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
2977 result
= SecPolicyCreate(policyOID
, service
, options
);
2978 require(result
, errOut
);
2981 CFReleaseSafe(appleAnchorOptions
);
2982 CFReleaseSafe(options
);
2984 CFReleaseSafe(uatoid
);
2989 @function SecPolicyCreateAppleIDSService
2990 @abstract Ensure we're appropriately pinned to the IDS service (SSL + Apple restrictions)
2992 SecPolicyRef
SecPolicyCreateAppleIDSService(CFStringRef hostname
)
2994 SecPolicyRef result
= SecPolicyCreateSSL(true, hostname
);
2996 SecPolicySetOid(result
, kSecPolicyAppleIDSService
);
2997 SecPolicySetName(result
, kSecPolicyNameAppleIDSBag
);
3003 @function SecPolicyCreateAppleIDSService
3004 @abstract Ensure we're appropriately pinned to the IDS service (SSL + Apple restrictions)
3006 SecPolicyRef
SecPolicyCreateAppleIDSServiceContext(CFStringRef hostname
, CFDictionaryRef context
)
3008 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyAppleIDSServiceContext
,
3009 kSecPolicyNameAppleIDSService
,
3010 &oidAppleCertExtAppleServerAuthenticationIDSProd
,
3011 &oidAppleCertExtAppleServerAuthenticationIDSProdQA
);
3015 @function SecPolicyCreateAppleGSService
3016 @abstract Ensure we're appropriately pinned to the GS service
3018 SecPolicyRef
SecPolicyCreateAppleGSService(CFStringRef hostname
, CFDictionaryRef context
)
3020 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyAppleGSService
,
3021 kSecPolicyNameAppleGSService
,
3022 &oidAppleCertExtAppleServerAuthenticationGS
,
3027 @function SecPolicyCreateApplePushService
3028 @abstract Ensure we're appropriately pinned to the Push service (SSL + Apple restrictions)
3030 SecPolicyRef
SecPolicyCreateApplePushService(CFStringRef hostname
, CFDictionaryRef context
)
3032 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyApplePushService
,
3033 kSecPolicyNameApplePushService
,
3034 &oidAppleCertExtAppleServerAuthenticationAPNProd
,
3035 &oidAppleCertExtAppleServerAuthenticationAPNProdQA
);
3039 @function SecPolicyCreateApplePPQService
3040 @abstract Ensure we're appropriately pinned to the PPQ service (SSL + Apple restrictions)
3042 SecPolicyRef
SecPolicyCreateApplePPQService(CFStringRef hostname
, CFDictionaryRef context
)
3044 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyApplePPQService
,
3045 kSecPolicyNameApplePPQService
,
3046 &oidAppleCertExtAppleServerAuthenticationPPQProd
,
3047 &oidAppleCertExtAppleServerAuthenticationPPQProdQA
);
3051 @function SecPolicyCreateAppleAST2Service
3052 @abstract Ensure we're appropriately pinned to the AST2 Diagnostic service (SSL + Apple restrictions)
3054 SecPolicyRef
SecPolicyCreateAppleAST2Service(CFStringRef hostname
, CFDictionaryRef context
)
3056 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyAppleAST2DiagnosticsServerAuth
,
3057 kSecPolicyNameAppleAST2Service
,
3058 &oidAppleCertExtAST2DiagnosticsServerAuthProd
,
3059 &oidAppleCertExtAST2DiagnosticsServerAuthProdQA
);
3063 @function SecPolicyCreateAppleEscrowProxyService
3064 @abstract Ensure we're appropriately pinned to the iCloud Escrow Proxy service (SSL + Apple restrictions)
3066 SecPolicyRef
SecPolicyCreateAppleEscrowProxyService(CFStringRef hostname
, CFDictionaryRef context
)
3068 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyAppleEscrowProxyServerAuth
,
3069 kSecPolicyNameAppleEscrowProxyService
,
3070 &oidAppleCertExtEscrowProxyServerAuthProd
,
3071 &oidAppleCertExtEscrowProxyServerAuthProdQA
);
3074 /* subject:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA */
3075 /* SKID: C0:7A:98:68:8D:89:FB:AB:05:64:0C:11:7D:AA:7D:65:B8:CA:CC:4E */
3076 /* Not Before: May 21 04:00:00 2002 GMT, Not After : May 21 04:00:00 2022 GMT */
3077 /* Signature Algorithm: sha1WithRSAEncryption */
3078 unsigned char GeoTrust_Global_CA_sha256
[kSecPolicySHA256Size
] = {
3079 0xff, 0x85, 0x6a, 0x2d, 0x25, 0x1d, 0xcd, 0x88, 0xd3, 0x66, 0x56, 0xf4, 0x50, 0x12, 0x67, 0x98,
3080 0xcf, 0xab, 0xaa, 0xde, 0x40, 0x79, 0x9c, 0x72, 0x2d, 0xe4, 0xd2, 0xb5, 0xdb, 0x36, 0xa7, 0x3a
3083 static SecPolicyRef
SecPolicyCreateAppleGeoTrustServerAuthCommon(CFStringRef hostname
, CFStringRef policyOid
,
3084 CFStringRef policyName
,
3085 CFStringRef leafMarkerOid
,
3086 CFStringRef qaLeafMarkerOid
) {
3087 CFMutableDictionaryRef options
= NULL
;
3088 CFDataRef spkiDigest
= NULL
;
3089 SecPolicyRef result
= NULL
;
3091 require(options
= CFDictionaryCreateMutable(NULL
, 0, &kCFTypeDictionaryKeyCallBacks
,
3092 &kCFTypeDictionaryValueCallBacks
), errOut
);
3095 SecPolicyAddBasicX509Options(options
);
3097 require(hostname
, errOut
);
3098 CFDictionaryAddValue(options
, kSecPolicyCheckSSLHostname
, hostname
);
3100 add_eku(options
, &oidExtendedKeyUsageServerAuth
);
3103 if (requireUATPinning(policyName
)) {
3105 SecPolicyAddAnchorSHA256Options(options
, GeoTrust_Global_CA_sha256
);
3107 /* Issued to Apple Inc. in the US */
3108 add_element(options
, kSecPolicyCheckIntermediateCountry
, CFSTR("US"));
3109 add_element(options
, kSecPolicyCheckIntermediateOrganization
, CFSTR("Apple Inc."));
3111 require_action(SecPolicyAddChainLengthOptions(options
, 3), errOut
, CFReleaseNull(result
));
3113 /* Marker OIDs in both formats */
3114 if (qaLeafMarkerOid
) {
3115 add_leaf_prod_qa_markers_string(options
, leafMarkerOid
, qaLeafMarkerOid
);
3116 add_leaf_prod_qa_markers_value_string(options
,
3117 CFSTR("1.2.840.113635.100.6.48.1"), leafMarkerOid
,
3118 CFSTR("1.2.840.113635.100.6.48.1"), qaLeafMarkerOid
);
3120 add_leaf_marker_string(options
, leafMarkerOid
);
3121 add_leaf_marker_value_string(options
, CFSTR("1.2.840.113635.100.6.48.1"), leafMarkerOid
);
3125 /* Check for weak hashes */
3126 require(SecPolicyRemoveWeakHashOptions(options
), errOut
);
3127 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
3129 /* See <rdar://25344801> for more details */
3131 result
= SecPolicyCreate(policyOid
, policyName
, options
);
3134 CFReleaseSafe(options
);
3135 CFReleaseSafe(spkiDigest
);
3139 SecPolicyRef
SecPolicyCreateAppleCompatibilityEscrowProxyService(CFStringRef hostname
) {
3140 return SecPolicyCreateAppleGeoTrustServerAuthCommon(hostname
, kSecPolicyAppleEscrowProxyCompatibilityServerAuth
,
3141 kSecPolicyNameAppleEscrowProxyService
,
3142 CFSTR("1.2.840.113635.100.6.27.7.2"),
3143 CFSTR("1.2.840.113635.100.6.27.7.1"));
3147 @function SecPolicyCreateAppleFMiPService
3148 @abstract Ensure we're appropriately pinned to the Find My iPhone service (SSL + Apple restrictions)
3150 SecPolicyRef
SecPolicyCreateAppleFMiPService(CFStringRef hostname
, CFDictionaryRef context
)
3152 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyAppleFMiPServerAuth
,
3153 kSecPolicyNameAppleFMiPService
,
3154 &oidAppleCertExtFMiPServerAuthProd
,
3155 &oidAppleCertExtFMiPServerAuthProdQA
);
3159 /* should use verbatim copy, but since this is the deprecated way, don't care right now */
3160 static const UInt8 entrustSPKIL1C
[kSecPolicySHA256Size
] = {
3161 0x54, 0x5b, 0xf9, 0x35, 0xe9, 0xad, 0xa1, 0xda,
3162 0x11, 0x7e, 0xdc, 0x3c, 0x2a, 0xcb, 0xc5, 0x6f,
3163 0xc0, 0x28, 0x09, 0x6c, 0x0e, 0x24, 0xbe, 0x9b,
3164 0x38, 0x94, 0xbe, 0x52, 0x2d, 0x1b, 0x43, 0xde
3168 @function SecPolicyCreateApplePushServiceLegacy
3169 @abstract Ensure we're appropriately pinned to the Push service (via Entrust)
3171 SecPolicyRef
SecPolicyCreateApplePushServiceLegacy(CFStringRef hostname
)
3173 CFMutableDictionaryRef options
= NULL
;
3174 SecPolicyRef result
= NULL
;
3175 CFDataRef digest
= NULL
;
3177 digest
= CFDataCreateWithBytesNoCopy(kCFAllocatorDefault
, entrustSPKIL1C
, sizeof(entrustSPKIL1C
), kCFAllocatorNull
);
3178 require(digest
, errOut
);
3180 options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0, &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
3181 require(options
, errOut
);
3183 SecPolicyAddBasicX509Options(options
);
3185 CFDictionaryAddValue(options
, kSecPolicyCheckSSLHostname
, hostname
);
3187 CFDictionaryAddValue(options
, kSecPolicyCheckBlackListedLeaf
, kCFBooleanTrue
);
3188 CFDictionaryAddValue(options
, kSecPolicyCheckGrayListedLeaf
, kCFBooleanTrue
);
3190 CFDictionaryAddValue(options
, kSecPolicyCheckIntermediateSPKISHA256
, digest
);
3192 add_eku(options
, &oidExtendedKeyUsageServerAuth
);
3194 /* Check for weak hashes and keys */
3195 require(SecPolicyRemoveWeakHashOptions(options
), errOut
);
3196 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
3198 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
3200 result
= SecPolicyCreate(kSecPolicyAppleLegacyPushService
,
3201 kSecPolicyNameLegacyPushService
, options
);
3202 require(result
, errOut
);
3205 CFReleaseSafe(digest
);
3206 CFReleaseSafe(options
);
3211 @function SecPolicyCreateAppleMMCSService
3212 @abstract Ensure we're appropriately pinned to the IDS service (SSL + Apple restrictions)
3214 SecPolicyRef
SecPolicyCreateAppleMMCSService(CFStringRef hostname
, CFDictionaryRef context
)
3216 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyAppleMMCService
,
3217 kSecPolicyNameAppleMMCSService
,
3218 &oidAppleCertExtAppleServerAuthenticationMMCSProd
,
3219 &oidAppleCertExtAppleServerAuthenticationMMCSProdQA
);
3222 SecPolicyRef
SecPolicyCreateAppleCompatibilityMMCSService(CFStringRef hostname
) {
3223 return SecPolicyCreateAppleGeoTrustServerAuthCommon(hostname
, kSecPolicyAppleMMCSCompatibilityServerAuth
,
3224 kSecPolicyNameAppleMMCSService
,
3225 CFSTR("1.2.840.113635.100.6.27.11.2"),
3226 CFSTR("1.2.840.113635.100.6.27.11.1"));
3230 SecPolicyRef
SecPolicyCreateAppleiCloudSetupService(CFStringRef hostname
, CFDictionaryRef context
)
3232 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyAppleiCloudSetupServerAuth
,
3233 kSecPolicyNameAppleiCloudSetupService
,
3234 &oidAppleCertExtAppleServerAuthenticationiCloudSetupProd
,
3235 &oidAppleCertExtAppleServerAuthenticationiCloudSetupProdQA
);
3238 SecPolicyRef
SecPolicyCreateAppleCompatibilityiCloudSetupService(CFStringRef hostname
)
3240 return SecPolicyCreateAppleGeoTrustServerAuthCommon(hostname
, kSecPolicyAppleiCloudSetupCompatibilityServerAuth
,
3241 kSecPolicyNameAppleiCloudSetupService
,
3242 CFSTR("1.2.840.113635.100.6.27.15.2"),
3243 CFSTR("1.2.840.113635.100.6.27.15.1"));
3247 @function SecPolicyCreateAppleSSLService
3248 @abstract Ensure we're appropriately pinned to an Apple server (SSL + Apple restrictions)
3250 SecPolicyRef
SecPolicyCreateAppleSSLService(CFStringRef hostname
)
3252 // SSL server, pinned to an Apple intermediate
3253 SecPolicyRef policy
= SecPolicyCreateSSL(true, hostname
);
3254 CFMutableDictionaryRef options
= NULL
;
3255 require(policy
, errOut
);
3257 // change options for SSL policy evaluation
3258 require((options
=(CFMutableDictionaryRef
)policy
->_options
) != NULL
, errOut
);
3260 // Apple CA anchored
3261 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameServerAuthentication
), errOut
);
3263 // Check leaf for Apple Server Authentication marker oid (1.2.840.113635.100.6.27.1)
3264 add_leaf_marker(options
, &oidAppleCertExtAppleServerAuthentication
);
3266 // Check intermediate for Apple Server Authentication intermediate marker (1.2.840.113635.100.6.2.12)
3267 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleServerAuthentication
);
3269 /* Check for weak hashes */
3270 require(SecPolicyRemoveWeakHashOptions(options
), errOut
);
3272 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
3274 SecPolicySetOid(policy
, kSecPolicyAppleServerAuthentication
);
3275 SecPolicySetName(policy
, kSecPolicyNameServerAuthentication
);
3280 CFReleaseSafe(options
);
3281 CFReleaseSafe(policy
);
3286 @function SecPolicyCreateApplePPQSigning
3287 @abstract Check for intermediate certificate 'Apple System Integration 2 Certification Authority' by name,
3289 Leaf cert must have Digital Signature usage.
3290 Leaf cert must have Apple PPQ Signing marker OID (1.2.840.113635.100.6.38.2).
3291 Intermediate must have marker OID (1.2.840.113635.100.6.2.10).
3293 SecPolicyRef
SecPolicyCreateApplePPQSigning(void)
3295 SecPolicyRef result
= NULL
;
3296 CFMutableDictionaryRef options
= NULL
;
3297 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3298 &kCFTypeDictionaryKeyCallBacks
,
3299 &kCFTypeDictionaryValueCallBacks
), errOut
);
3300 SecPolicyAddBasicCertOptions(options
);
3302 SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNamePPQSigning
);
3303 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3305 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
3306 CFSTR("Apple System Integration 2 Certification Authority"));
3308 // Check that leaf has extension with "Apple PPQ Signing" prod oid (1.2.840.113635.100.6.38.2)
3309 add_leaf_marker(options
, &oidAppleCertExtApplePPQSigningProd
);
3311 // Check that intermediate has extension (1.2.840.113635.100.6.2.10)
3312 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleSystemIntg2
);
3314 add_ku(options
, kSecKeyUsageDigitalSignature
);
3316 require(result
= SecPolicyCreate(kSecPolicyApplePPQSigning
,
3317 kSecPolicyNamePPQSigning
, options
), errOut
);
3320 CFReleaseSafe(options
);
3325 @function SecPolicyCreateTestApplePPQSigning
3326 @abstract Check for intermediate certificate 'Apple System Integration 2 Certification Authority' by name,
3328 Leaf cert must have Digital Signature usage.
3329 Leaf cert must have Apple PPQ Signing Test marker OID (1.2.840.113635.100.6.38.1).
3330 Intermediate must have marker OID (1.2.840.113635.100.6.2.10).
3332 SecPolicyRef
SecPolicyCreateTestApplePPQSigning(void)
3334 /* Guard against use of test policy on production devices */
3335 if (!SecIsInternalRelease()) {
3336 return SecPolicyCreateApplePPQSigning();
3339 SecPolicyRef result
= NULL
;
3340 CFMutableDictionaryRef options
= NULL
;
3341 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3342 &kCFTypeDictionaryKeyCallBacks
,
3343 &kCFTypeDictionaryValueCallBacks
), errOut
);
3344 SecPolicyAddBasicCertOptions(options
);
3346 SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameTestPPQSigning
);
3347 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3349 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
3350 CFSTR("Apple System Integration 2 Certification Authority"));
3352 // Check that leaf has extension with "Apple PPQ Signing" test oid (1.2.840.113635.100.6.38.1)
3353 add_leaf_marker(options
, &oidAppleCertExtApplePPQSigningProdQA
);
3355 // Check that intermediate has extension (1.2.840.113635.100.6.2.10)
3356 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleSystemIntg2
);
3358 add_ku(options
, kSecKeyUsageDigitalSignature
);
3360 require(result
= SecPolicyCreate(kSecPolicyAppleTestPPQSigning
,
3361 kSecPolicyNameTestPPQSigning
, options
), errOut
);
3364 CFReleaseSafe(options
);
3368 @function SecPolicyCreateAppleTimeStamping
3369 @abstract Check for RFC3161 timestamping EKU.
3371 SecPolicyRef
SecPolicyCreateAppleTimeStamping(void)
3373 SecPolicyRef result
= NULL
;
3374 CFMutableDictionaryRef options
= NULL
;
3375 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3376 &kCFTypeDictionaryKeyCallBacks
,
3377 &kCFTypeDictionaryValueCallBacks
), errOut
);
3379 SecPolicyAddBasicX509Options(options
);
3381 /* Require id-kp-timeStamping extendedKeyUsage to be present. */
3382 add_eku(options
, &oidExtendedKeyUsageTimeStamping
);
3384 require(result
= SecPolicyCreate(kSecPolicyAppleTimeStamping
,
3385 kSecPolicyNameTimeStamping
, options
), errOut
);
3388 CFReleaseSafe(options
);
3393 @function SecPolicyCreateApplePayIssuerEncryption
3394 @abstract Check for intermediate certificate 'Apple Worldwide Developer Relations CA - G2' by name,
3395 and ECC apple anchor.
3396 Leaf cert must have Key Encipherment and Key Agreement usage.
3397 Leaf cert must have Apple Pay Issuer Encryption marker OID (1.2.840.113635.100.6.39).
3399 SecPolicyRef
SecPolicyCreateApplePayIssuerEncryption(void)
3401 SecPolicyRef result
= NULL
;
3402 CFMutableDictionaryRef options
= NULL
;
3403 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3404 &kCFTypeDictionaryKeyCallBacks
,
3405 &kCFTypeDictionaryValueCallBacks
), errOut
);
3406 SecPolicyAddBasicCertOptions(options
);
3408 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNamePayIssuerEncryption
),
3410 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3412 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
3413 CFSTR("Apple Worldwide Developer Relations CA - G2"));
3415 // Check that leaf has extension with "Apple Pay Issuer Encryption" oid (1.2.840.113635.100.6.39)
3416 add_leaf_marker(options
, &oidAppleCertExtCryptoServicesExtEncryption
);
3418 add_ku(options
, kSecKeyUsageKeyEncipherment
);
3420 require(result
= SecPolicyCreate(kSecPolicyApplePayIssuerEncryption
,
3421 kSecPolicyNamePayIssuerEncryption
, options
), errOut
);
3424 CFReleaseSafe(options
);
3429 @function SecPolicyCreateAppleATVVPNProfileSigning
3430 @abstract Check for leaf marker OID 1.2.840.113635.100.6.43,
3431 intermediate marker OID 1.2.840.113635.100.6.2.10,
3432 chains to Apple Root CA, path length 3
3434 SecPolicyRef
SecPolicyCreateAppleATVVPNProfileSigning(void)
3436 SecPolicyRef result
= NULL
;
3437 CFMutableDictionaryRef options
= NULL
;
3438 CFMutableDictionaryRef appleAnchorOptions
= NULL
;
3439 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3440 &kCFTypeDictionaryKeyCallBacks
,
3441 &kCFTypeDictionaryValueCallBacks
), errOut
);
3443 SecPolicyAddBasicCertOptions(options
);
3445 // Require pinning to the Apple CAs (including test CA for internal releases)
3446 appleAnchorOptions
= CFDictionaryCreateMutableForCFTypes(NULL
);
3447 require(appleAnchorOptions
, errOut
);
3449 if (SecIsInternalRelease()) {
3450 CFDictionarySetValue(appleAnchorOptions
,
3451 kSecPolicyAppleAnchorIncludeTestRoots
, kCFBooleanTrue
);
3454 add_element(options
, kSecPolicyCheckAnchorApple
, appleAnchorOptions
);
3456 // Cert chain length 3
3457 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3459 // Check leaf for Apple ATV VPN Profile Signing OID (1.2.840.113635.100.6.43)
3460 add_leaf_marker(options
, &oidAppleCertExtATVVPNProfileSigning
);
3462 // Check intermediate for Apple System Integration 2 CA intermediate marker (1.2.840.113635.100.6.2.10)
3463 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleSystemIntg2
);
3465 // Ensure that revocation is checked (OCSP only)
3466 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationOCSP
);
3468 require(result
= SecPolicyCreate(kSecPolicyAppleATVVPNProfileSigning
,
3469 kSecPolicyNameATVVPNProfileSigning
, options
), errOut
);
3472 CFReleaseSafe(options
);
3473 CFReleaseSafe(appleAnchorOptions
);
3477 SecPolicyRef
SecPolicyCreateAppleHomeKitServerAuth(CFStringRef hostname
) {
3478 CFMutableDictionaryRef appleAnchorOptions
= NULL
;
3479 CFMutableDictionaryRef options
= NULL
;
3480 SecPolicyRef result
= NULL
;
3481 CFDataRef oid
= NULL
;
3483 options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0, &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
3484 require(options
, errOut
);
3486 SecPolicyAddBasicX509Options(options
);
3488 CFDictionaryAddValue(options
, kSecPolicyCheckSSLHostname
, hostname
);
3490 add_eku(options
, &oidExtendedKeyUsageServerAuth
);
3492 if (requireUATPinning(kSecPolicyNameAppleHomeKitService
)) {
3494 // Cert chain length 3
3495 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3497 // Apple anchors, allowing test anchors for internal release
3498 SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameAppleHomeKitService
);
3500 add_leaf_marker(options
, &oidAppleCertExtHomeKitServerAuth
);
3502 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleHomeKitServerCA
);
3505 /* Check for weak hashes */
3506 require(SecPolicyRemoveWeakHashOptions(options
), errOut
);
3507 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
3509 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
3511 result
= SecPolicyCreate(kSecPolicyAppleHomeKitServerAuth
,
3512 kSecPolicyNameAppleHomeKitService
, options
);
3513 require(result
, errOut
);
3516 CFReleaseSafe(appleAnchorOptions
);
3517 CFReleaseSafe(options
);
3522 SecPolicyRef
SecPolicyCreateAppleExternalDeveloper(void) {
3523 CFMutableDictionaryRef options
= NULL
;
3524 SecPolicyRef result
= NULL
;
3526 /* Create basic Apple pinned policy */
3527 require(result
= SecPolicyCreateApplePinned(kSecPolicyNameExternalDeveloper
,
3528 CFSTR("1.2.840.113635.100.6.2.1"), // WWDR Intermediate OID
3529 CFSTR("1.2.840.113635.100.6.1.2")), // "iPhone Developer" leaf OID
3532 require_action(options
= CFDictionaryCreateMutableCopy(NULL
, 0, result
->_options
), errOut
, CFReleaseNull(result
));
3534 /* Additional intermediate OIDs */
3535 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
,
3536 CFSTR("1.2.840.113635.100.6.2.6")); // "Developer ID" Intermediate OID
3538 /* Addtional leaf OIDS */
3539 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.4")); // "iPhone Distribution" leaf OID
3540 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.5")); // "Safari Developer" leaf OID
3541 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.7")); // "3rd Party Mac Developer Application" leaf OID
3542 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.8")); // "3rd Party Mac Developer Installer" leaf OID
3543 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.12")); // "Mac Developer" leaf OID
3544 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.13")); // "Developer ID Application" leaf OID
3545 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.14")); // "Developer ID Installer" leaf OID
3548 add_eku_string(options
, CFSTR("1.3.6.1.5.5.7.3.3")); // CodeSigning EKU
3549 add_eku_string(options
, CFSTR("1.2.840.113635.100.4.8")); // "Safari Developer" EKU
3550 add_eku_string(options
, CFSTR("1.2.840.113635.100.4.9")); // "3rd Party Mac Developer Installer" EKU
3551 add_eku_string(options
, CFSTR("1.2.840.113635.100.4.13")); // "Developer ID Installer" EKU
3553 CFReleaseSafe(result
->_options
);
3554 result
->_options
= CFRetainSafe(options
);
3556 SecPolicySetOid(result
, kSecPolicyAppleExternalDeveloper
);
3559 CFReleaseSafe(options
);
3563 /* This one is special because the intermediate has no marker OID */
3564 SecPolicyRef
SecPolicyCreateAppleSoftwareSigning(void) {
3565 CFMutableDictionaryRef options
= NULL
;
3566 SecPolicyRef result
= NULL
;
3568 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3569 &kCFTypeDictionaryKeyCallBacks
,
3570 &kCFTypeDictionaryValueCallBacks
), errOut
);
3572 SecPolicyAddBasicCertOptions(options
);
3574 /* Anchored to the Apple Roots */
3575 require_quiet(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameSoftwareSigning
),
3578 /* Exactly 3 certs in the chain */
3579 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3581 /* Intermediate Common Name matches */
3582 add_element(options
, kSecPolicyCheckIssuerCommonName
, CFSTR("Apple Code Signing Certification Authority"));
3584 /* Leaf marker OID matches */
3585 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.22"));
3587 /* Leaf has CodeSigning EKU */
3588 add_eku_string(options
, CFSTR("1.3.6.1.5.5.7.3.3"));
3590 /* Check revocation using any available method */
3591 add_element(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
3593 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
3594 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
3596 require(result
= SecPolicyCreate(kSecPolicyAppleSoftwareSigning
,
3597 kSecPolicyNameSoftwareSigning
, options
), errOut
);
3600 CFReleaseSafe(options
);
3604 /* subject:/CN=SEP Root CA/O=Apple Inc./ST=California */
3605 /* SKID: 58:EF:D6:BE:C5:82:B0:54:CD:18:A6:84:AD:A2:F6:7B:7B:3A:7F:CF */
3606 /* Not Before: Jun 24 21:43:24 2014 GMT, Not After : Jun 24 21:43:24 2029 GMT */
3607 /* Signature Algorithm: ecdsa-with-SHA384 */
3608 const uint8_t SEPRootCA_SHA256
[kSecPolicySHA256Size
] = {
3609 0xd1, 0xdf, 0x82, 0x00, 0xf3, 0x89, 0x4e, 0xe9, 0x96, 0xf3, 0x77, 0xdf, 0x76, 0x3b, 0x0a, 0x16,
3610 0x8f, 0xd9, 0x6c, 0x58, 0xc0, 0x3e, 0xc9, 0xb0, 0x5f, 0xa5, 0x64, 0x79, 0xc0, 0xe8, 0xc9, 0xe7
3613 SecPolicyRef
SecPolicyCreateAppleUniqueDeviceCertificate(CFDataRef testRootHash
) {
3614 CFMutableDictionaryRef options
= NULL
;
3615 CFDictionaryRef keySizes
= NULL
;
3616 CFNumberRef ecSize
= NULL
;
3617 SecPolicyRef result
= NULL
;
3619 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3620 &kCFTypeDictionaryKeyCallBacks
,
3621 &kCFTypeDictionaryValueCallBacks
), errOut
);
3623 /* Device certificate should never expire */
3624 SecPolicyAddBasicCertOptions(options
);
3626 /* Anchored to the SEP Root CA. Allow alternative root for developers */
3627 require(SecPolicyAddAnchorSHA256Options(options
, SEPRootCA_SHA256
),errOut
);
3628 if (testRootHash
&& SecIsInternalRelease() && (kSecPolicySHA256Size
== CFDataGetLength(testRootHash
))) {
3629 add_element(options
, kSecPolicyCheckAnchorSHA256
, testRootHash
);
3632 /* Exactly 3 certs in the chain */
3633 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3635 /* Intermediate has marker OID with value */
3636 add_intermediate_marker_value_string(options
, CFSTR("1.2.840.113635.100.6.44"), CFSTR("ucrt"));
3638 /* Leaf has marker OID with varying value that can't be pre-determined */
3639 add_element(options
, kSecPolicyCheckLeafMarkerOidWithoutValueCheck
, CFSTR("1.2.840.113635.100.10.1"));
3641 /* RSA key sizes are disallowed. EC key sizes are P-256 or larger. */
3642 require(ecSize
= CFNumberCreateWithCFIndex(NULL
, 256), errOut
);
3643 require(keySizes
= CFDictionaryCreate(NULL
, (const void**)&kSecAttrKeyTypeEC
,
3644 (const void**)&ecSize
, 1,
3645 &kCFTypeDictionaryKeyCallBacks
,
3646 &kCFTypeDictionaryValueCallBacks
), errOut
);
3647 add_element(options
, kSecPolicyCheckKeySize
, keySizes
);
3650 require(result
= SecPolicyCreate(kSecPolicyAppleUniqueDeviceIdentifierCertificate
,
3651 kSecPolicyNameUniqueDeviceIdentifierCertificate
, options
), errOut
);
3654 CFReleaseSafe(options
);
3655 CFReleaseSafe(keySizes
);
3656 CFReleaseSafe(ecSize
);
3660 SecPolicyRef
SecPolicyCreateAppleWarsaw(void) {
3661 CFMutableDictionaryRef options
= NULL
;
3662 SecPolicyRef result
= NULL
;
3663 #if TARGET_OS_BRIDGE
3664 CFMutableDictionaryRef appleAnchorOptions
= NULL
;
3667 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3668 &kCFTypeDictionaryKeyCallBacks
,
3669 &kCFTypeDictionaryValueCallBacks
), errOut
);
3671 SecPolicyAddBasicX509Options(options
);
3673 /* Anchored to the Apple Roots. */
3674 require_quiet(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameWarsaw
),
3677 /* Exactly 3 certs in the chain */
3678 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3680 /* Intermediate marker OID matches input OID */
3681 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.14"));
3683 /* Leaf marker OID matches input OID */
3684 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.29"));
3686 /* Check revocation using any available method */
3687 add_element(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
3689 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
3690 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
3692 require(result
= SecPolicyCreate(kSecPolicyAppleWarsaw
,
3693 kSecPolicyNameWarsaw
, options
), errOut
);
3696 CFReleaseSafe(options
);
3700 SecPolicyRef
SecPolicyCreateAppleSecureIOStaticAsset(void) {
3701 CFMutableDictionaryRef options
= NULL
;
3702 SecPolicyRef result
= NULL
;
3703 #if TARGET_OS_BRIDGE
3704 CFMutableDictionaryRef appleAnchorOptions
= NULL
;
3707 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3708 &kCFTypeDictionaryKeyCallBacks
,
3709 &kCFTypeDictionaryValueCallBacks
), errOut
);
3711 /* This certificate cannot expire so that assets always load */
3712 SecPolicyAddBasicCertOptions(options
);
3714 /* Anchored to the Apple Roots. */
3715 #if TARGET_OS_BRIDGE
3716 /* On the bridge, test roots are gated in the trust and policy servers. */
3717 require_quiet(appleAnchorOptions
= CFDictionaryCreateMutableForCFTypes(NULL
), errOut
);
3718 CFDictionarySetValue(appleAnchorOptions
,
3719 kSecPolicyAppleAnchorIncludeTestRoots
, kCFBooleanTrue
);
3720 add_element(options
, kSecPolicyCheckAnchorApple
, appleAnchorOptions
);
3721 CFReleaseSafe(appleAnchorOptions
);
3723 require_quiet(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameSecureIOStaticAsset
),
3727 /* Exactly 3 certs in the chain */
3728 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3730 /* Intermediate marker OID matches ASI CA */
3731 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.10"));
3733 /* Leaf marker OID matches static IO OID */
3734 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.50"));
3736 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
3737 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
3739 require(result
= SecPolicyCreate(kSecPolicyAppleSecureIOStaticAsset
,
3740 kSecPolicyNameSecureIOStaticAsset
, options
), errOut
);
3743 CFReleaseSafe(options
);
3747 SecPolicyRef
SecPolicyCreateAppleAppTransportSecurity(void) {
3748 CFMutableDictionaryRef options
= NULL
;
3749 SecPolicyRef result
= NULL
;
3750 CFMutableArrayRef disallowedHashes
= NULL
;
3752 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3753 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
3755 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
3756 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
3758 /* Hash algorithm is SHA-256 or better */
3759 require(disallowedHashes
= CFArrayCreateMutable(NULL
, 5, &kCFTypeArrayCallBacks
), errOut
);
3760 CFArrayAppendValue(disallowedHashes
, kSecSignatureDigestAlgorithmMD2
);
3761 CFArrayAppendValue(disallowedHashes
, kSecSignatureDigestAlgorithmMD4
);
3762 CFArrayAppendValue(disallowedHashes
, kSecSignatureDigestAlgorithmMD5
);
3763 CFArrayAppendValue(disallowedHashes
, kSecSignatureDigestAlgorithmSHA1
);
3764 CFArrayAppendValue(disallowedHashes
, kSecSignatureDigestAlgorithmSHA224
);
3766 add_element(options
, kSecPolicyCheckSignatureHashAlgorithms
, disallowedHashes
);
3768 require_quiet(result
= SecPolicyCreate(kSecPolicyAppleAppTransportSecurity
,
3769 kSecPolicyNameAppTransportSecurity
,
3773 CFReleaseSafe(options
);
3777 SecPolicyRef
SecPolicyCreateMobileSoftwareUpdate(void) {
3778 CFMutableDictionaryRef options
= NULL
;
3779 SecPolicyRef result
= NULL
;
3780 #if TARGET_OS_BRIDGE
3781 CFMutableDictionaryRef appleAnchorOptions
= NULL
;
3784 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3785 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
3787 /* No expiration check. */
3788 SecPolicyAddBasicCertOptions(options
);
3791 require_quiet(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameMobileSoftwareUpdate
),
3794 /* Exactly 3 certs in the chain */
3795 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3797 /* Intermediate marker OID is iPhone CA OID */
3798 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.18"));
3800 /* Leaf marker OID is either the prod MSU OID, or, on internal builds, the prodQA OID */
3801 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.57.2"));
3802 if (SecIsInternalRelease()) {
3803 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.57.1"));
3806 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
3807 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
3809 require(result
= SecPolicyCreate(kSecPolicyAppleMobileSoftwareUpdate
,
3810 kSecPolicyNameMobileSoftwareUpdate
, options
), errOut
);
3813 CFReleaseNull(options
);
3817 /* subject:/CN=Basic Attestation System Root CA/O=Apple Inc./ST=California */
3818 /* SKID: FE:D1:D1:C2:08:07:03:D5:B9:3C:34:B2:BB:FD:7C:3A:99:25:1B:8F */
3819 /* Not Before: Apr 20 00:22:09 2017 GMT, Not After : Mar 22 00:00:00 2032 GMT */
3820 /* Signature Algorithm: ecdsa-with-SHA384 */
3821 const uint8_t BASystemRootCA_SHA256
[kSecPolicySHA256Size
] = {
3822 0x10, 0xD3, 0xC8, 0x67, 0xF0, 0xAE, 0xFB, 0x24, 0x31, 0xA0, 0xA9, 0x7A, 0x88, 0x18, 0xBD, 0x64,
3823 0xF7, 0xF9, 0x0F, 0xFE, 0x11, 0x94, 0x48, 0x4F, 0xCA, 0x97, 0xF0, 0xF2, 0x9E, 0xCA, 0x00, 0x47
3826 /* subject:/CN=Basic Attestation User Root CA/O=Apple Inc./ST=California */
3827 /* SKID: 83:E5:A3:21:9E:B0:74:C3:F9:61:90:FD:97:4E:23:10:76:A4:A3:F2 */
3828 /* Not Before: Apr 19 21:41:56 2017 GMT, Not After : Mar 22 00:00:00 2032 GMT */
3829 /* Signature Algorithm: ecdsa-with-SHA384 */
3830 const uint8_t BAUserRootCA_SHA256
[kSecPolicySHA256Size
] = {
3831 0x03, 0x75, 0x1c, 0x80, 0xfc, 0xbe, 0x58, 0x19, 0xd1, 0x70, 0xd2, 0x67, 0xce, 0x1a, 0xd6, 0xd0,
3832 0x94, 0x40, 0x7c, 0x91, 0xd8, 0x73, 0xd7, 0xa6, 0x56, 0x2d, 0xe3, 0x66, 0x6d, 0x35, 0x94, 0xc6
3835 SecPolicyRef
SecPolicyCreateAppleBasicAttestationSystem(CFDataRef testRootHash
) {
3836 CFMutableDictionaryRef options
= NULL
;
3837 SecPolicyRef result
= NULL
;
3839 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3840 &kCFTypeDictionaryKeyCallBacks
,
3841 &kCFTypeDictionaryValueCallBacks
), errOut
);
3842 /* BAA certs expire */
3843 SecPolicyAddBasicX509Options(options
);
3845 /* Anchored to one of the Basic Attestation roots. Allow alternative root for developers */
3846 SecPolicyAddAnchorSHA256Options(options
, BASystemRootCA_SHA256
);
3847 if (testRootHash
&& SecIsInternalRelease() && (kSecPolicySHA256Size
== CFDataGetLength(testRootHash
))) {
3848 add_element(options
, kSecPolicyCheckAnchorSHA256
, testRootHash
);
3851 /* Exactly 3 certs in the chain */
3852 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3854 require(result
= SecPolicyCreate(kSecPolicyAppleBasicAttestationSystem
,
3855 kSecPolicyNameBasicAttestationSystem
, options
), errOut
);
3858 CFReleaseSafe(options
);
3862 SecPolicyRef
SecPolicyCreateAppleBasicAttestationUser(CFDataRef testRootHash
) {
3863 CFMutableDictionaryRef options
= NULL
;
3864 SecPolicyRef result
= NULL
;
3866 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3867 &kCFTypeDictionaryKeyCallBacks
,
3868 &kCFTypeDictionaryValueCallBacks
), errOut
);
3869 /* BAA certs expire */
3870 SecPolicyAddBasicX509Options(options
);
3872 /* Anchored to one of the Basic Attestation roots. Allow alternative root for developers */
3873 SecPolicyAddAnchorSHA256Options(options
, BAUserRootCA_SHA256
);
3874 if (testRootHash
&& SecIsInternalRelease() && (kSecPolicySHA256Size
== CFDataGetLength(testRootHash
))) {
3875 add_element(options
, kSecPolicyCheckAnchorSHA256
, testRootHash
);
3878 /* Exactly 3 certs in the chain */
3879 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3881 require(result
= SecPolicyCreate(kSecPolicyAppleBasicAttestationUser
,
3882 kSecPolicyNameBasicAttestationUser
, options
), errOut
);
3885 CFReleaseSafe(options
);
3889 SecPolicyRef
SecPolicyCreateiAPSWAuthWithExpiration(bool checkExpiration
) {
3890 CFMutableDictionaryRef options
= NULL
;
3891 SecPolicyRef result
= NULL
;
3893 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3894 &kCFTypeDictionaryKeyCallBacks
,
3895 &kCFTypeDictionaryValueCallBacks
), errOut
);
3897 /* iAP checks expiration on developement certs, but not on production certs */
3898 if (checkExpiration
) {
3899 SecPolicyAddBasicX509Options(options
);
3901 SecPolicyAddBasicCertOptions(options
);
3904 /* Exactly 2 certs in the chain */
3905 require(SecPolicyAddChainLengthOptions(options
, 2), errOut
);
3907 /* iAP SW Auth General Capabilities Extension present */
3908 add_element(options
, kSecPolicyCheckLeafMarkerOidWithoutValueCheck
, CFSTR("1.2.840.113635.100.6.59.1"));
3910 require(result
= SecPolicyCreate(kSecPolicyAppleiAPSWAuth
,
3911 kSecPolicyNameiAPSWAuth
, options
), errOut
);
3914 CFReleaseSafe(options
);
3918 SecPolicyRef
SecPolicyCreateiAPSWAuth(void) {
3919 /* By default, iAP SW Auth certs don't expire */
3920 return SecPolicyCreateiAPSWAuthWithExpiration(false);
3923 SecPolicyRef
SecPolicyCreateDemoDigitalCatalogSigning(void) {
3924 CFMutableDictionaryRef options
= NULL
;
3925 SecPolicyRef result
= NULL
;
3927 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3928 &kCFTypeDictionaryKeyCallBacks
,
3929 &kCFTypeDictionaryValueCallBacks
), errOut
);
3930 SecPolicyAddBasicX509Options(options
);
3932 /* Exactly 3 certs in the chain */
3933 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3935 /* Demo Signing Extension present in leaf */
3936 add_element(options
, kSecPolicyCheckLeafMarkerOid
, CFSTR("1.2.840.113635.100.6.60"));
3938 /* Issuer common name is "DemoUnit CA" */
3939 add_element(options
, kSecPolicyCheckIssuerCommonName
, CFSTR("DemoUnit CA"));
3941 require(result
= SecPolicyCreate(kSecPolicyAppleDemoDigitalCatalog
,
3942 kSecPolicyNameDemoDigitalCatalog
, options
), errOut
);
3945 CFReleaseSafe(options
);
3949 SecPolicyRef
SecPolicyCreateAppleAssetReceipt(void) {
3950 CFMutableDictionaryRef options
= NULL
;
3951 SecPolicyRef result
= NULL
;
3953 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3954 &kCFTypeDictionaryKeyCallBacks
,
3955 &kCFTypeDictionaryValueCallBacks
), errOut
);
3957 /* No expiration check. */
3958 SecPolicyAddBasicCertOptions(options
);
3961 require_quiet(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameAssetReceipt
), errOut
);
3963 /* Exactly 3 certs in the chain */
3964 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3966 /* Intermediate marker OID is Apple System Integration 2 CA */
3967 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.10"));
3969 /* Leaf marker OID is the Asset Receipt OID */
3970 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.61"));
3972 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
3973 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
3975 require(result
= SecPolicyCreate(kSecPolicyAppleAssetReceipt
,
3976 kSecPolicyNameAssetReceipt
, options
), errOut
);
3979 CFReleaseNull(options
);
3983 SecPolicyRef
SecPolicyCreateAppleDeveloperIDPlusTicket(void) {
3984 CFMutableDictionaryRef options
= NULL
;
3985 SecPolicyRef result
= NULL
;
3987 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3988 &kCFTypeDictionaryKeyCallBacks
,
3989 &kCFTypeDictionaryValueCallBacks
), errOut
);
3991 /* No expiration check. */
3992 SecPolicyAddBasicCertOptions(options
);
3995 require_quiet(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameDeveloperIDPlusTicket
), errOut
);
3997 /* Exactly 3 certs in the chain */
3998 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
4000 /* Intermediate marker OID is Apple System Integration CA 4 */
4001 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.17"));
4003 /* Leaf marker OID is the Developer ID+ Ticket OID */
4004 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.30"));
4006 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
4007 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
4009 require(result
= SecPolicyCreate(kSecPolicyAppleDeveloperIDPlusTicket
,
4010 kSecPolicyNameDeveloperIDPlusTicket
, options
), errOut
);
4013 CFReleaseNull(options
);
4017 SecPolicyRef
SecPolicyCreateAppleFDRProvisioning(void) {
4018 CFMutableDictionaryRef options
= NULL
;
4019 SecPolicyRef result
= NULL
;
4021 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
4022 &kCFTypeDictionaryKeyCallBacks
,
4023 &kCFTypeDictionaryValueCallBacks
), errOut
);
4025 /* No expiration check. */
4026 SecPolicyAddBasicCertOptions(options
);
4028 require(result
= SecPolicyCreate(kSecPolicyAppleFDRProvisioning
,
4029 kSecPolicyNameFDRProvisioning
, options
), errOut
);
4031 CFReleaseNull(options
);
4035 /* subject:/CN=Component Root CA/O=Apple Inc./ST=California */
4036 /* SKID: 90:D1:56:A9:3E:B4:EE:8C:D0:10:4B:9F:17:1C:5B:55:F2:12:F6:4C */
4037 /* Not Before: Dec 19 19:31:54 2018 GMT, Not After : Dec 16 00:00:00 2043 GMT */
4038 /* Signature Algorithm: ecdsa-with-SHA384 */
4039 const uint8_t ComponentRootCA_SHA256
[kSecPolicySHA256Size
] = {
4040 0x2f, 0x71, 0x9d, 0xbf, 0x3c, 0xcd, 0xe7, 0xc2, 0xb2, 0x59, 0x3f, 0x32, 0x1f, 0x90, 0xf3, 0x42,
4041 0x42, 0xaa, 0x84, 0xa1, 0xb2, 0x0d, 0xca, 0xcc, 0x10, 0xc0, 0x5b, 0x26, 0xd6, 0x23, 0xb8, 0x47,
4043 SecPolicyRef
SecPolicyCreateAppleComponentCertificate(CFDataRef testRootHash
) {
4044 CFMutableDictionaryRef options
= NULL
;
4045 SecPolicyRef result
= NULL
;
4047 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
4048 &kCFTypeDictionaryKeyCallBacks
,
4049 &kCFTypeDictionaryValueCallBacks
), errOut
);
4051 /* Component certificates don't expire */
4052 SecPolicyAddBasicCertOptions(options
);
4054 /* Anchored to one of the Component roots. Allow alternative root for developers */
4055 SecPolicyAddAnchorSHA256Options(options
, ComponentRootCA_SHA256
);
4056 if (testRootHash
&& SecIsInternalRelease() && (kSecPolicySHA256Size
== CFDataGetLength(testRootHash
))) {
4057 add_element(options
, kSecPolicyCheckAnchorSHA256
, testRootHash
);
4060 /* Exactly 3 certs in the chain */
4061 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
4063 /* Leaf and intermediate must contain Component Type OID */
4064 add_element(options
, kSecPolicyCheckLeafMarkerOidWithoutValueCheck
, CFSTR("1.2.840.113635.100.11.1"));
4065 add_element(options
, kSecPolicyCheckIntermediateMarkerOidWithoutValueCheck
, CFSTR("1.2.840.113635.100.11.1"));
4067 require(result
= SecPolicyCreate(kSecPolicyAppleComponentCertificate
,
4068 kSecPolicyNameComponentCertificate
, options
), errOut
);
4070 CFReleaseNull(options
);
4074 SecPolicyRef
SecPolicyCreateAppleKeyTransparency(CFStringRef applicationId
) {
4075 CFMutableDictionaryRef options
= NULL
;
4076 SecPolicyRef result
= NULL
;
4078 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
4079 &kCFTypeDictionaryKeyCallBacks
,
4080 &kCFTypeDictionaryValueCallBacks
), errOut
);
4082 /* KT signing certs don't expire */
4083 SecPolicyAddBasicCertOptions(options
);
4086 require_quiet(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameKeyTransparency
), errOut
);
4088 /* Exactly 3 certs in the chain */
4089 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
4091 /* Intermediate marker OID matches AAI CA 5 */
4092 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.3"));
4094 /* Leaf marker extension matches input applicationId */
4095 add_leaf_marker_value_string(options
, CFSTR("1.2.840.113635.100.12.4"), applicationId
);
4097 /* Check revocation using any available method */
4098 add_element(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
4100 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
4101 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
4103 /* Check for weak hashes */
4104 require(SecPolicyRemoveWeakHashOptions(options
), errOut
);
4106 /* Future CT requirement */
4108 require(result
= SecPolicyCreate(kSecPolicyAppleKeyTransparency
,
4109 kSecPolicyNameKeyTransparency
, options
), errOut
);
4111 CFReleaseNull(options
);
4115 SecPolicyRef
SecPolicyCreateAlisha(void) {
4116 CFMutableDictionaryRef options
= NULL
;
4117 SecPolicyRef result
= NULL
;
4118 CFDictionaryRef keySizes
= NULL
;
4119 CFNumberRef ecSize
= NULL
;
4121 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
4122 &kCFTypeDictionaryKeyCallBacks
,
4123 &kCFTypeDictionaryValueCallBacks
), errOut
);
4125 /* Alisha certs don't expire */
4126 SecPolicyAddBasicCertOptions(options
);
4128 /* RSA key sizes are disallowed. EC key sizes are P-256 or larger. */
4129 require(ecSize
= CFNumberCreateWithCFIndex(NULL
, 256), errOut
);
4130 require(keySizes
= CFDictionaryCreate(NULL
, (const void**)&kSecAttrKeyTypeEC
,
4131 (const void**)&ecSize
, 1,
4132 &kCFTypeDictionaryKeyCallBacks
,
4133 &kCFTypeDictionaryValueCallBacks
), errOut
);
4134 add_element(options
, kSecPolicyCheckKeySize
, keySizes
);
4136 /* Check for weak hashes */
4137 require(SecPolicyRemoveWeakHashOptions(options
), errOut
);
4139 require(result
= SecPolicyCreate(kSecPolicyAppleAlisha
,
4140 kSecPolicyNameAlisha
, options
), errOut
);
4142 CFReleaseNull(options
);
4143 CFReleaseNull(keySizes
);
4144 CFReleaseNull(ecSize
);
4148 SecPolicyRef
SecPolicyCreateMeasuredBootPolicySigning(void) {
4149 CFMutableDictionaryRef options
= NULL
;
4150 SecPolicyRef result
= NULL
;
4152 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
4153 &kCFTypeDictionaryKeyCallBacks
,
4154 &kCFTypeDictionaryValueCallBacks
), errOut
);
4156 /* No expiration check. */
4157 SecPolicyAddBasicCertOptions(options
);
4159 /* Exactly 3 certs in the chain */
4160 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
4162 /* Corporate Signing subCA */
4163 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.24.17"));
4165 /* Measured Boot Policy Signing Leaf OID */
4166 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.26.6.1"));
4168 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
4169 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
4171 require(result
= SecPolicyCreate(kSecPolicyAppleMeasuredBootPolicySigning
,
4172 kSecPolicyNameMeasuredBootPolicySigning
, options
), errOut
);
4175 CFReleaseSafe(options
);