2 * Copyright (c) 2007-2017 Apple Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
25 * SecPolicy.c - Implementation of various X.509 certificate trust policies
28 #include <Security/SecPolicyInternal.h>
29 #include <Security/SecPolicyPriv.h>
30 #include <AssertMacros.h>
32 #include <utilities/debugging.h>
33 #include <Security/SecInternal.h>
34 #include <CoreFoundation/CFDictionary.h>
35 #include <CoreFoundation/CFNumber.h>
36 #include <CoreFoundation/CFRuntime.h>
37 #include <CoreFoundation/CFString.h>
38 #include <CoreFoundation/CFTimeZone.h>
39 #include <Security/SecCertificateInternal.h>
40 #include <Security/SecCertificatePriv.h>
41 #include <Security/SecItem.h>
42 #include <libDER/oids.h>
43 #include <utilities/SecCFError.h>
44 #include <utilities/SecCFWrappers.h>
45 #include <utilities/array_size.h>
46 #include <ipc/securityd_client.h>
48 #include <utilities/SecInternalReleasePriv.h>
50 #undef POLICYCHECKMACRO
51 #define POLICYCHECKMACRO(NAME, TRUSTRESULT, SUBTYPE, LEAFCHECK, PATHCHECK, LEAFONLY, CSSMERR, OSSTATUS) \
52 const CFStringRef kSecPolicyCheck##NAME = CFSTR(#NAME);
53 #include "SecPolicyChecks.list"
55 #define SEC_CONST_DECL(k,v) const CFStringRef k = CFSTR(v);
57 /********************************************************
58 ******************* Feature toggles ********************
59 ********************************************************/
60 /* Option for AnchorApple */
61 SEC_CONST_DECL (kSecPolicyAppleAnchorIncludeTestRoots
, "AnchorAppleTestRoots");
63 /* options for kSecPolicyCheckLeafMarkersProdAndQA */
64 SEC_CONST_DECL (kSecPolicyLeafMarkerProd
, "ProdMarker");
65 SEC_CONST_DECL (kSecPolicyLeafMarkerQA
, "QAMarker");
67 /* Revocation toggles */
68 SEC_CONST_DECL (kSecPolicyCheckRevocationOCSP
, "OCSP");
69 SEC_CONST_DECL (kSecPolicyCheckRevocationCRL
, "CRL");
70 SEC_CONST_DECL (kSecPolicyCheckRevocationAny
, "AnyRevocationMethod");
72 /* Public policy oids. */
73 #define POLICYMACRO(NAME, OID, ISPUBLIC, INTNAME, IN_NAME, IN_PROPERTIES, FUNCTION) \
74 const CFStringRef kSecPolicyApple##NAME = CFSTR("1.2.840.113635.100.1."#OID);
75 #include "SecPolicy.list"
76 //Some naming exceptions
77 SEC_CONST_DECL(kSecPolicyMacAppStoreReceipt
, "1.2.840.113635.100.1.19")
78 SEC_CONST_DECL(kSecPolicyAppleIDValidationRecordSigningPolicy
, "1.2.840.113635.100.1.30");
80 SEC_CONST_DECL (kSecPolicyOid
, "SecPolicyOid");
81 SEC_CONST_DECL (kSecPolicyName
, "SecPolicyName");
82 SEC_CONST_DECL (kSecPolicyClient
, "SecPolicyClient");
83 SEC_CONST_DECL (kSecPolicyRevocationFlags
, "SecPolicyRevocationFlags");
84 SEC_CONST_DECL (kSecPolicyTeamIdentifier
, "SecPolicyTeamIdentifier");
85 SEC_CONST_DECL (kSecPolicyContext
, "SecPolicyContext");
86 SEC_CONST_DECL (kSecPolicyPolicyName
, "SecPolicyPolicyName");
87 SEC_CONST_DECL (kSecPolicyIntermediateMarkerOid
, "SecPolicyIntermediateMarkerOid");
88 SEC_CONST_DECL (kSecPolicyLeafMarkerOid
, "SecPolicyLeafMarkerOid");
89 SEC_CONST_DECL (kSecPolicyRootDigest
, "SecPolicyRootDigest");
91 SEC_CONST_DECL (kSecPolicyKU_DigitalSignature
, "CE_KU_DigitalSignature");
92 SEC_CONST_DECL (kSecPolicyKU_NonRepudiation
, "CE_KU_NonRepudiation");
93 SEC_CONST_DECL (kSecPolicyKU_KeyEncipherment
, "CE_KU_KeyEncipherment");
94 SEC_CONST_DECL (kSecPolicyKU_DataEncipherment
, "CE_KU_DataEncipherment");
95 SEC_CONST_DECL (kSecPolicyKU_KeyAgreement
, "CE_KU_KeyAgreement");
96 SEC_CONST_DECL (kSecPolicyKU_KeyCertSign
, "CE_KU_KeyCertSign");
97 SEC_CONST_DECL (kSecPolicyKU_CRLSign
, "CE_KU_CRLSign");
98 SEC_CONST_DECL (kSecPolicyKU_EncipherOnly
, "CE_KU_EncipherOnly");
99 SEC_CONST_DECL (kSecPolicyKU_DecipherOnly
, "CE_KU_DecipherOnly");
101 /* Internal policy names */
103 #define __P_DO_DECLARE_(NAME, INTNAME) static CFStringRef kSecPolicyName##NAME = CFSTR(#INTNAME);
104 #define __P_DO_DECLARE_E(NAME, INTNAME) static CFStringRef kSecPolicyName##NAME = CFSTR(#INTNAME);
105 #define __P_DO_DECLARE_P(NAME, INTNAME) const CFStringRef kSecPolicyNameApple##NAME = CFSTR(#INTNAME);
106 #define __P_DO_DECLARE_I(NAME, INTNAME) const CFStringRef kSecPolicyName##NAME = CFSTR(#INTNAME);
107 #define POLICYMACRO(NAME, OID, ISPUBLIC, INTNAME, IN_NAME, IN_PROPERTIES, FUNCTION) \
108 __P_DO_DECLARE_##ISPUBLIC(NAME, INTNAME)
109 #include "SecPolicy.list"
110 //Some naming exceptions
111 static CFStringRef kSecPolicyNameAppleIDSBag
= CFSTR("IDSBag");
113 /* External Policy Names
114 * These correspond to the names defined in CertificatePinning.plist
115 * in security_certificates */
116 SEC_CONST_DECL (kSecPolicyNameSSLServer
, "sslServer");
117 SEC_CONST_DECL (kSecPolicyNameSSLClient
, "sslClient");
118 SEC_CONST_DECL (kSecPolicyNameEAPServer
, "eapServer");
119 SEC_CONST_DECL (kSecPolicyNameEAPClient
, "eapClient");
120 SEC_CONST_DECL (kSecPolicyNameIPSecServer
, "ipsecServer");
121 SEC_CONST_DECL (kSecPolicyNameIPSecClient
, "ipsecClient");
122 SEC_CONST_DECL (kSecPolicyNameAppleiCloudSetupService
, "iCloudSetup");
123 SEC_CONST_DECL (kSecPolicyNameAppleMMCSService
, "MMCS");
124 SEC_CONST_DECL (kSecPolicyNameAppleAST2Service
, "AST2");
125 SEC_CONST_DECL (kSecPolicyNameAppleEscrowProxyService
, "Escrow");
126 SEC_CONST_DECL (kSecPolicyNameAppleFMiPService
, "FMiP");
127 SEC_CONST_DECL (kSecPolicyNameAppleHomeKitService
, "HomeKit");
128 SEC_CONST_DECL (kSecPolicyNameAppleAIDCService
, "AIDC");
129 SEC_CONST_DECL (kSecPolicyNameAppleMapsService
, "Maps");
130 SEC_CONST_DECL (kSecPolicyNameAppleHealthProviderService
, "HealthProvider");
131 SEC_CONST_DECL (kSecPolicyNameAppleParsecService
, "Parsec");
132 SEC_CONST_DECL (kSecPolicyNameAppleAMPService
, "AMP");
133 SEC_CONST_DECL (kSecPolicyNameAppleSiriService
, "Siri");
134 SEC_CONST_DECL (kSecPolicyNameAppleHomeAppClipUploadService
, "HomeAppClipUploadService");
136 #define kSecPolicySHA1Size 20
137 #define kSecPolicySHA256Size 32
138 __unused
const UInt8 kAppleCASHA1
[kSecPolicySHA1Size
] = {
139 0x61, 0x1E, 0x5B, 0x66, 0x2C, 0x59, 0x3A, 0x08, 0xFF, 0x58,
140 0xD1, 0x4A, 0xE2, 0x24, 0x52, 0xD1, 0x98, 0xDF, 0x6C, 0x60
143 __unused
static const UInt8 kAppleTESTCASHA1
[kSecPolicySHA1Size
] = {
144 0xbc, 0x30, 0x55, 0xc8, 0xc8, 0xd3, 0x48, 0x3f, 0xf4, 0x8d,
145 0xfe, 0x3d, 0x51, 0x75, 0x31, 0xc9, 0xf4, 0xd7, 0x4a, 0xf7
148 static const UInt8 kITMSCASHA1
[kSecPolicySHA1Size
] = {
149 0x1D, 0x33, 0x42, 0x46, 0x8B, 0x10, 0xBD, 0xE6, 0x45, 0xCE,
150 0x44, 0x6E, 0xBB, 0xE8, 0xF5, 0x03, 0x5D, 0xF8, 0x32, 0x22
153 static const UInt8 kFactoryDeviceCASHA1
[kSecPolicySHA1Size
] = {
154 0xef, 0x68, 0x73, 0x17, 0xa4, 0xf8, 0xf9, 0x4b, 0x7b, 0x21,
155 0xe2, 0x2f, 0x09, 0x8f, 0xfd, 0x6a, 0xae, 0xc0, 0x0d, 0x63
158 static const UInt8 kApplePKISettingsAuthority
[kSecPolicySHA1Size
] = {
159 0x1D, 0x0C, 0xBA, 0xAD, 0x17, 0xFD, 0x7E, 0x9E, 0x9F, 0xF1,
160 0xC9, 0xA2, 0x66, 0x79, 0x60, 0x00, 0x8B, 0xAE, 0x70, 0xB8
163 static const UInt8 kAppleTestPKISettingsAuthority
[kSecPolicySHA1Size
] = {
164 0xDB, 0xBA, 0x25, 0x0B, 0xD8, 0x62, 0x71, 0x87, 0x54, 0x7E,
165 0xD7, 0xEF, 0x11, 0x94, 0x7E, 0x82, 0xE6, 0xD8, 0x1C, 0x9A
168 static const UInt8 kTestAppleRootCA_ECC_SHA1
[kSecPolicySHA1Size
] = {
169 0x62, 0x0A, 0xED, 0x83, 0xD2, 0x97, 0x4A, 0x77, 0x56, 0x33,
170 0x83, 0xBE, 0xDB, 0xF9, 0xA1, 0xBD, 0x5F, 0xFE, 0x55, 0x7B
173 __unused
static const UInt8 kAppleRootCA_ECC_SHA1
[kSecPolicySHA1Size
] = {
174 0xB5, 0x2C, 0xB0, 0x2F, 0xD5, 0x67, 0xE0, 0x35, 0x9F, 0xE8,
175 0xFA, 0x4D, 0x4C, 0x41, 0x03, 0x79, 0x70, 0xFE, 0x01, 0xB0
180 /********************************************************
181 ****************** SecPolicy object ********************
182 ********************************************************/
184 static void SecPolicyDestroy(CFTypeRef cf
) {
185 SecPolicyRef policy
= (SecPolicyRef
) cf
;
186 CFRelease(policy
->_oid
);
187 CFReleaseSafe(policy
->_name
);
188 CFRelease(policy
->_options
);
191 static Boolean
SecPolicyCompare(CFTypeRef cf1
, CFTypeRef cf2
) {
192 SecPolicyRef policy1
= (SecPolicyRef
) cf1
;
193 SecPolicyRef policy2
= (SecPolicyRef
) cf2
;
194 if (policy1
->_name
&& policy2
->_name
) {
195 return CFEqual(policy1
->_oid
, policy2
->_oid
) &&
196 CFEqual(policy1
->_name
, policy2
->_name
) &&
197 CFEqual(policy1
->_options
, policy2
->_options
);
199 return CFEqual(policy1
->_oid
, policy2
->_oid
) &&
200 CFEqual(policy1
->_options
, policy2
->_options
);
204 static CFHashCode
SecPolicyHash(CFTypeRef cf
) {
205 SecPolicyRef policy
= (SecPolicyRef
) cf
;
207 return CFHash(policy
->_oid
) + CFHash(policy
->_name
) + CFHash(policy
->_options
);
209 return CFHash(policy
->_oid
) + CFHash(policy
->_options
);
213 static CFStringRef
SecPolicyCopyFormatDescription(CFTypeRef cf
, CFDictionaryRef formatOptions
) {
214 SecPolicyRef policy
= (SecPolicyRef
) cf
;
215 CFMutableStringRef desc
= CFStringCreateMutable(kCFAllocatorDefault
, 0);
216 CFStringRef typeStr
= CFCopyTypeIDDescription(CFGetTypeID(cf
));
217 CFStringAppendFormat(desc
, NULL
,
218 CFSTR("<%@: oid: %@ name: %@ options %@"), typeStr
,
219 policy
->_oid
, (policy
->_name
) ? policy
->_name
: CFSTR(""),
222 CFStringAppend(desc
, CFSTR(" >"));
227 /* SecPolicy API functions. */
228 CFGiblisWithHashFor(SecPolicy
);
230 /* AUDIT[securityd](done):
231 oid (ok) is a caller provided string, only its cf type has been checked.
232 options is a caller provided dictionary, only its cf type has been checked.
234 SecPolicyRef
SecPolicyCreate(CFStringRef oid
, CFStringRef name
, CFDictionaryRef options
) {
235 SecPolicyRef result
= NULL
;
237 require(oid
, errOut
);
238 require(options
, errOut
);
240 (SecPolicyRef
)_CFRuntimeCreateInstance(kCFAllocatorDefault
,
241 SecPolicyGetTypeID(),
242 sizeof(struct __SecPolicy
) - sizeof(CFRuntimeBase
), 0), errOut
);
247 result
->_name
= name
;
249 result
->_options
= options
;
256 static void set_ku_from_properties(SecPolicyRef policy
, CFDictionaryRef properties
);
259 SecPolicyRef
SecPolicyCreateWithProperties(CFTypeRef policyIdentifier
,
260 CFDictionaryRef properties
) {
261 // Creates a policy reference for a given policy object identifier.
262 // If policy-specific parameters can be supplied (e.g. hostname),
263 // attempt to obtain from input properties dictionary.
264 // Returns NULL if the given identifier is unsupported.
266 SecPolicyRef policy
= NULL
;
267 CFTypeRef name
= NULL
;
268 CFStringRef teamID
= NULL
;
269 Boolean client
= false;
270 CFDictionaryRef context
= NULL
;
271 CFStringRef policyName
= NULL
, intermediateMarkerOid
= NULL
, leafMarkerOid
= NULL
;
272 CFDataRef rootDigest
= NULL
;
273 require(policyIdentifier
&& (CFStringGetTypeID() == CFGetTypeID(policyIdentifier
)), errOut
);
276 name
= CFDictionaryGetValue(properties
, kSecPolicyName
);
277 teamID
= CFDictionaryGetValue(properties
, kSecPolicyTeamIdentifier
);
279 CFBooleanRef dictionaryClientValue
;
280 client
= (CFDictionaryGetValueIfPresent(properties
, kSecPolicyClient
, (const void **)&dictionaryClientValue
) &&
281 (dictionaryClientValue
!= NULL
) && CFEqual(kCFBooleanTrue
, dictionaryClientValue
));
282 context
= CFDictionaryGetValue(properties
, kSecPolicyContext
);
283 policyName
= CFDictionaryGetValue(properties
, kSecPolicyPolicyName
);
284 intermediateMarkerOid
= CFDictionaryGetValue(properties
, kSecPolicyIntermediateMarkerOid
);
285 leafMarkerOid
= CFDictionaryGetValue(properties
, kSecPolicyLeafMarkerOid
);
286 rootDigest
= CFDictionaryGetValue(properties
, kSecPolicyRootDigest
);
289 /* only the EAP policy allows a non-string name */
290 if (name
&& !isString(name
) && !CFEqual(policyIdentifier
, kSecPolicyAppleEAP
)) {
291 secerror("policy \"%@\" requires a string value for the %@ key", policyIdentifier
, kSecPolicyName
);
295 /* What follows are all the exceptional functions that do not match the macro below */
296 if (CFEqual(policyIdentifier
, kSecPolicyAppleSSL
)) {
297 policy
= SecPolicyCreateSSL(!client
, name
);
298 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleSMIME
)) {
299 policy
= SecPolicyCreateSMIME(kSecSignSMIMEUsage
| kSecAnyEncryptSMIME
, name
);
300 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleEAP
)) {
301 CFArrayRef array
= NULL
;
302 if (isString(name
)) {
303 array
= CFArrayCreate(kCFAllocatorDefault
, (const void **)&name
, 1, &kCFTypeArrayCallBacks
);
304 } else if (isArray(name
)) {
305 array
= CFArrayCreateCopy(NULL
, name
);
307 policy
= SecPolicyCreateEAP(!client
, array
);
308 CFReleaseSafe(array
);
309 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleIPsec
)) {
310 policy
= SecPolicyCreateIPSec(!client
, name
);
311 } else if (CFEqual(policyIdentifier
, kSecPolicyMacAppStoreReceipt
)) {
312 policy
= SecPolicyCreateMacAppStoreReceipt();
313 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleRevocation
)) {
314 policy
= SecPolicyCreateRevocation(kSecRevocationUseAnyAvailableMethod
);
315 } else if (CFEqual(policyIdentifier
, kSecPolicyApplePassbookSigning
)) {
316 policy
= SecPolicyCreatePassbookCardSigner(name
, teamID
);
317 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleAST2DiagnosticsServerAuth
)) {
319 policy
= SecPolicyCreateAppleAST2Service(name
, context
);
321 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier
);
323 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleEscrowProxyServerAuth
)) {
325 policy
= SecPolicyCreateAppleEscrowProxyService(name
, context
);
327 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier
);
329 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleFMiPServerAuth
)) {
331 policy
= SecPolicyCreateAppleFMiPService(name
, context
);
333 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier
);
335 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleMMCService
)) {
337 policy
= SecPolicyCreateAppleMMCSService(name
, context
);
339 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier
);
341 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleGSService
)) {
343 policy
= SecPolicyCreateAppleGSService(name
, context
);
345 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier
);
347 } else if (CFEqual(policyIdentifier
, kSecPolicyApplePPQService
)) {
349 policy
= SecPolicyCreateApplePPQService(name
, context
);
351 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier
);
353 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleGenericApplePinned
)) {
355 policy
= SecPolicyCreateApplePinned(policyName
, intermediateMarkerOid
, leafMarkerOid
);
357 secerror("policy \"%@\" requires kSecPolicyPolicyName input", policyIdentifier
);
359 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleGenericAppleSSLPinned
)) {
361 policy
= SecPolicyCreateAppleSSLPinned(policyName
, name
, intermediateMarkerOid
, leafMarkerOid
);
363 secerror("policy \"%@\" requires kSecPolicyPolicyName input", policyIdentifier
);
365 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleIDSServiceContext
)) {
367 policy
= SecPolicyCreateAppleIDSServiceContext(name
, context
);
369 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier
);
371 } else if (CFEqual(policyIdentifier
, kSecPolicyApplePushService
)) {
373 policy
= SecPolicyCreateApplePushService(name
, context
);
375 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier
);
377 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleUniqueDeviceIdentifierCertificate
)) {
378 policy
= SecPolicyCreateAppleUniqueDeviceCertificate(rootDigest
);
379 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleiCloudSetupServerAuth
)) {
381 policy
= SecPolicyCreateAppleiCloudSetupService(name
, context
);
383 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier
);
385 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleBasicAttestationSystem
)) {
386 policy
= SecPolicyCreateAppleBasicAttestationSystem(rootDigest
);
387 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleBasicAttestationUser
)) {
388 policy
= SecPolicyCreateAppleBasicAttestationUser(rootDigest
);
389 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleComponentCertificate
)) {
390 policy
= SecPolicyCreateAppleComponentCertificate(rootDigest
);
392 /* For a couple of common patterns we use the macro, but some of the
393 * policies are deprecated, so we need to ignore the warning. */
394 #pragma clang diagnostic push
395 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
397 #define _P_OPTION_N name
398 #define _P_PROPERTIES_(NAME, IN_NAME, FUNCTION)
399 #define _P_PROPERTIES_Y(NAME, IN_NAME, FUNCTION) else if (CFEqual(policyIdentifier, kSecPolicyApple##NAME)) { \
400 policy = SecPolicyCreate##FUNCTION(_P_OPTION_##IN_NAME); \
403 #define POLICYMACRO(NAME, OID, ISPUBLIC, INTNAME, IN_NAME, IN_PROPERTIES, FUNCTION) \
404 _P_PROPERTIES_##IN_PROPERTIES(NAME, IN_NAME, FUNCTION)
405 #include "SecPolicy.list"
407 secerror("ERROR: policy \"%@\" is unsupported", policyIdentifier
);
409 #pragma clang diagnostic pop // ignored "-Wdeprecated-declarations"
416 set_ku_from_properties(policy
, properties
);
420 SecPolicySetName(policy
, policyName
);
427 CFDictionaryRef
SecPolicyCopyProperties(SecPolicyRef policyRef
) {
428 // Builds and returns a dictionary which the caller must release.
430 #pragma clang diagnostic push
431 #pragma clang diagnostic ignored "-Wnonnull"
432 // After introducing nullability annotations, policyRef is supposed to be nonnull, suppress the warning
433 if (!policyRef
) return NULL
;
434 #pragma clang diagnostic pop
435 CFMutableDictionaryRef properties
= CFDictionaryCreateMutable(NULL
, 0,
436 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
437 #pragma clang diagnostic push
438 #pragma clang diagnostic ignored "-Wnonnull"
439 // 'properties' is nonnull in reality suppress the warning
440 if (!properties
) return NULL
;
441 #pragma clang diagnostic pop
442 CFStringRef oid
= (CFStringRef
) CFRetain(policyRef
->_oid
);
443 CFTypeRef nameKey
= NULL
;
445 // Determine name key
446 if (policyRef
->_options
) {
447 if (CFDictionaryContainsKey(policyRef
->_options
, kSecPolicyCheckSSLHostname
)) {
448 nameKey
= kSecPolicyCheckSSLHostname
;
449 } else if (CFDictionaryContainsKey(policyRef
->_options
, kSecPolicyCheckEAPTrustedServerNames
)) {
450 nameKey
= kSecPolicyCheckEAPTrustedServerNames
;
451 } else if (CFDictionaryContainsKey(policyRef
->_options
, kSecPolicyCheckEmail
)) {
452 nameKey
= kSecPolicyCheckEmail
;
457 CFDictionarySetValue(properties
, (const void *)kSecPolicyOid
,
460 // Set kSecPolicyName if we have one
461 if (nameKey
&& policyRef
->_options
) {
462 CFTypeRef name
= (CFTypeRef
) CFDictionaryGetValue(policyRef
->_options
,
465 CFDictionarySetValue(properties
, (const void *)kSecPolicyName
,
470 // Set kSecPolicyClient
471 CFStringRef policyName
= (CFStringRef
) CFRetainSafe(policyRef
->_name
);
472 if (policyName
&& (CFEqual(policyName
, kSecPolicyNameSSLClient
) ||
473 CFEqual(policyName
, kSecPolicyNameIPSecClient
) ||
474 CFEqual(policyName
, kSecPolicyNameEAPClient
))) {
475 CFDictionarySetValue(properties
, (const void *)kSecPolicyClient
,
476 (const void *)kCFBooleanTrue
);
483 static void SecPolicySetOid(SecPolicyRef policy
, CFStringRef oid
) {
484 if (!policy
|| !oid
) return;
485 CFStringRef temp
= policy
->_oid
;
491 void SecPolicySetName(SecPolicyRef policy
, CFStringRef policyName
) {
492 if (!policy
|| !policyName
) return;
493 CFStringRef temp
= policy
->_name
;
494 CFRetain(policyName
);
495 policy
->_name
= policyName
;
499 CFStringRef
SecPolicyGetOidString(SecPolicyRef policy
) {
503 CFStringRef
SecPolicyGetName(SecPolicyRef policy
) {
504 return policy
->_name
;
507 CFDictionaryRef
SecPolicyGetOptions(SecPolicyRef policy
) {
508 return policy
->_options
;
511 void SecPolicySetOptionsValue(SecPolicyRef policy
, CFStringRef key
, CFTypeRef value
) {
512 if (!policy
|| !key
) return;
513 CFMutableDictionaryRef options
= (CFMutableDictionaryRef
) policy
->_options
;
515 options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
516 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
517 if (!options
) return;
518 policy
->_options
= options
;
520 CFDictionarySetValue(options
, key
, value
);
523 /* Local forward declaration */
524 static void set_ssl_ekus(CFMutableDictionaryRef options
, bool server
);
527 // this is declared as NA for iPhone in SecPolicy.h, so declare here
528 OSStatus
SecPolicySetProperties(SecPolicyRef policyRef
, CFDictionaryRef properties
);
531 OSStatus
SecPolicySetProperties(SecPolicyRef policyRef
, CFDictionaryRef properties
) {
532 // Set policy options based on the provided dictionary keys.
534 if (!(policyRef
&& properties
&& (CFDictionaryGetTypeID() == CFGetTypeID(properties
)))) {
537 CFStringRef oid
= (CFStringRef
) CFRetain(policyRef
->_oid
);
538 OSStatus result
= errSecSuccess
;
541 CFTypeRef name
= NULL
;
542 if (CFDictionaryGetValueIfPresent(properties
, (const void *)kSecPolicyName
,
543 (const void **)&name
) && name
) {
544 CFTypeID typeID
= CFGetTypeID(name
);
545 if (CFEqual(oid
, kSecPolicyAppleSSL
) ||
546 CFEqual(oid
, kSecPolicyAppleIPsec
)) {
547 if (CFStringGetTypeID() == typeID
) {
548 SecPolicySetOptionsValue(policyRef
, kSecPolicyCheckSSLHostname
, name
);
550 else result
= errSecParam
;
552 else if (CFEqual(oid
, kSecPolicyAppleEAP
)) {
553 if ((CFStringGetTypeID() == typeID
) ||
554 (CFArrayGetTypeID() == typeID
)) {
555 SecPolicySetOptionsValue(policyRef
, kSecPolicyCheckEAPTrustedServerNames
, name
);
557 else result
= errSecParam
;
559 else if (CFEqual(oid
, kSecPolicyAppleSMIME
)) {
560 if (CFStringGetTypeID() == typeID
) {
561 SecPolicySetOptionsValue(policyRef
, kSecPolicyCheckEmail
, name
);
563 else result
= errSecParam
;
568 CFTypeRef client
= NULL
;
569 if (CFDictionaryGetValueIfPresent(properties
, (const void *)kSecPolicyClient
,
570 (const void **)&client
) && client
) {
571 if (!(CFBooleanGetTypeID() == CFGetTypeID(client
))) {
572 result
= errSecParam
;
574 else if (CFEqual(client
, kCFBooleanTrue
)) {
575 if (CFEqual(oid
, kSecPolicyAppleSSL
)) {
576 SecPolicySetName(policyRef
, kSecPolicyNameSSLClient
);
577 /* Set EKU checks for clients */
578 CFMutableDictionaryRef newOptions
= CFDictionaryCreateMutableCopy(NULL
, 0, policyRef
->_options
);
579 set_ssl_ekus(newOptions
, false);
580 CFReleaseSafe(policyRef
->_options
);
581 policyRef
->_options
= newOptions
;
583 else if (CFEqual(oid
, kSecPolicyAppleIPsec
)) {
584 SecPolicySetName(policyRef
, kSecPolicyNameIPSecClient
);
586 else if (CFEqual(oid
, kSecPolicyNameEAPServer
)) {
587 SecPolicySetName(policyRef
, kSecPolicyNameEAPClient
);
588 /* Set EKU checks for clients */
589 CFMutableDictionaryRef newOptions
= CFDictionaryCreateMutableCopy(NULL
, 0, policyRef
->_options
);
590 set_ssl_ekus(newOptions
, false);
591 CFReleaseSafe(policyRef
->_options
);
592 policyRef
->_options
= newOptions
;
596 if (CFEqual(oid
, kSecPolicyAppleSSL
)) {
597 SecPolicySetName(policyRef
, kSecPolicyNameSSLServer
);
598 /* Set EKU checks for servers */
599 CFMutableDictionaryRef newOptions
= CFDictionaryCreateMutableCopy(NULL
, 0, policyRef
->_options
);
600 set_ssl_ekus(newOptions
, true);
601 CFReleaseSafe(policyRef
->_options
);
602 policyRef
->_options
= newOptions
;
604 else if (CFEqual(oid
, kSecPolicyAppleIPsec
)) {
605 SecPolicySetName(policyRef
, kSecPolicyNameIPSecServer
);
607 else if (CFEqual(oid
, kSecPolicyAppleEAP
)) {
608 SecPolicySetName(policyRef
, kSecPolicyNameEAPServer
);
609 /* Set EKU checks for servers */
610 CFMutableDictionaryRef newOptions
= CFDictionaryCreateMutableCopy(NULL
, 0, policyRef
->_options
);
611 set_ssl_ekus(newOptions
, true);
612 CFReleaseSafe(policyRef
->_options
);
613 policyRef
->_options
= newOptions
;
619 set_ku_from_properties(policyRef
, properties
);
625 static xpc_object_t
copy_xpc_policy_object(SecPolicyRef policy
);
626 static bool append_policy_to_xpc_array(SecPolicyRef policy
, xpc_object_t xpc_policies
);
627 extern xpc_object_t
copy_xpc_policies_array(CFArrayRef policies
);
628 extern OSStatus
validate_array_of_items(CFArrayRef array
, CFStringRef arrayItemType
, CFTypeID itemTypeID
, bool required
);
630 static xpc_object_t
copy_xpc_policy_object(SecPolicyRef policy
) {
631 xpc_object_t xpc_policy
= NULL
;
632 xpc_object_t data
[2] = { NULL
, NULL
};
633 if (policy
->_oid
&& (CFGetTypeID(policy
->_oid
) == CFStringGetTypeID()) &&
634 policy
->_name
&& (CFGetTypeID(policy
->_name
) == CFStringGetTypeID())) {
635 /* These should really be different elements of the xpc array. But
636 * SecPolicyCreateWithXPCObject previously checked the size via ==, which prevents
637 * us from appending new information while maintaining backward compatibility.
638 * Doing this makes the builders happy. */
639 CFMutableStringRef oidAndName
= NULL
;
640 oidAndName
= CFStringCreateMutableCopy(NULL
, 0, policy
->_oid
);
642 CFStringAppend(oidAndName
, CFSTR("++"));
643 CFStringAppend(oidAndName
, policy
->_name
);
644 data
[0] = _CFXPCCreateXPCObjectFromCFObject(oidAndName
);
645 CFReleaseNull(oidAndName
);
647 data
[0] = _CFXPCCreateXPCObjectFromCFObject(policy
->_oid
);
649 } else if (policy
->_oid
&& (CFGetTypeID(policy
->_oid
) == CFStringGetTypeID())) {
650 data
[0] = _CFXPCCreateXPCObjectFromCFObject(policy
->_oid
);
652 secerror("policy 0x%lX has no _oid", (uintptr_t)policy
);
654 if (policy
->_options
&& (CFGetTypeID(policy
->_options
) == CFDictionaryGetTypeID())) {
655 data
[1] = _CFXPCCreateXPCObjectFromCFObject(policy
->_options
);
657 secerror("policy 0x%lX has no _options", (uintptr_t)policy
);
659 xpc_policy
= xpc_array_create(data
, array_size(data
));
660 if (data
[0]) xpc_release(data
[0]);
661 if (data
[1]) xpc_release(data
[1]);
665 static bool append_policy_to_xpc_array(SecPolicyRef policy
, xpc_object_t xpc_policies
) {
669 xpc_object_t xpc_policy
= copy_xpc_policy_object(policy
);
673 xpc_array_append_value(xpc_policies
, xpc_policy
);
674 xpc_release(xpc_policy
);
678 xpc_object_t
copy_xpc_policies_array(CFArrayRef policies
) {
679 xpc_object_t xpc_policies
= xpc_array_create(NULL
, 0);
683 validate_array_of_items(policies
, CFSTR("policy"), SecPolicyGetTypeID(), true);
684 CFIndex ix
, count
= CFArrayGetCount(policies
);
685 for (ix
= 0; ix
< count
; ++ix
) {
686 SecPolicyRef policy
= (SecPolicyRef
) CFArrayGetValueAtIndex(policies
, ix
);
687 #if SECTRUST_VERBOSE_DEBUG
688 CFDictionaryRef props
= SecPolicyCopyProperties(policy
);
689 secerror("idx=%d of %d; policy=0x%lX properties=%@", (int)ix
, (int)count
, (uintptr_t)policy
, props
);
690 CFReleaseSafe(props
);
692 if (!append_policy_to_xpc_array(policy
, xpc_policies
)) {
693 xpc_release(xpc_policies
);
701 static xpc_object_t
SecPolicyCopyXPCObject(SecPolicyRef policy
, CFErrorRef
*error
) {
702 xpc_object_t xpc_policy
= NULL
;
703 xpc_object_t data
[2] = {};
704 CFMutableStringRef oidAndName
= NULL
;
705 oidAndName
= CFStringCreateMutableCopy(NULL
, 0, policy
->_oid
);
708 CFStringAppend(oidAndName
, CFSTR("++"));
709 CFStringAppend(oidAndName
, policy
->_name
);
712 require_action_quiet(data
[0] = _CFXPCCreateXPCObjectFromCFObject(oidAndName
), exit
,
713 SecError(errSecParam
, error
,
714 CFSTR("failed to create xpc_object from policy oid and name")));
716 require_action_quiet(data
[0] = _CFXPCCreateXPCObjectFromCFObject(policy
->_oid
), exit
,
717 SecError(errSecParam
, error
, CFSTR("failed to create xpc_object from policy oid")));
719 require_action_quiet(data
[1] = _CFXPCCreateXPCObjectFromCFObject(policy
->_options
), exit
,
720 SecError(errSecParam
, error
, CFSTR("failed to create xpc_object from policy options")));
721 require_action_quiet(xpc_policy
= xpc_array_create(data
, array_size(data
)), exit
,
722 SecError(errSecAllocate
, error
, CFSTR("failed to create xpc_array for policy")));
725 if (data
[0]) xpc_release(data
[0]);
726 if (data
[1]) xpc_release(data
[1]);
727 CFReleaseNull(oidAndName
);
731 static bool SecPolicyAppendToXPCArray(SecPolicyRef policy
, xpc_object_t policies
, CFErrorRef
*error
) {
735 xpc_object_t xpc_policy
= SecPolicyCopyXPCObject(policy
, error
);
739 xpc_array_append_value(policies
, xpc_policy
);
740 xpc_release(xpc_policy
);
744 xpc_object_t
SecPolicyArrayCopyXPCArray(CFArrayRef policies
, CFErrorRef
*error
) {
745 xpc_object_t xpc_policies
;
746 require_action_quiet(xpc_policies
= xpc_array_create(NULL
, 0), exit
,
747 SecError(errSecAllocate
, error
, CFSTR("failed to create xpc_array")));
748 CFIndex ix
, count
= CFArrayGetCount(policies
);
749 for (ix
= 0; ix
< count
; ++ix
) {
750 if (!SecPolicyAppendToXPCArray((SecPolicyRef
)CFArrayGetValueAtIndex(policies
, ix
), xpc_policies
, error
)) {
751 xpc_release(xpc_policies
);
759 static OSStatus
parseOidAndName(CFStringRef oidAndName
, CFStringRef
*oid
, CFStringRef
*name
) {
760 OSStatus result
= errSecSuccess
;
761 CFStringRef partial
= NULL
;
763 CFRange delimiter
= CFStringFind(oidAndName
, CFSTR("++"), 0);
764 if (delimiter
.length
!= 2) {
768 /* get first half: oid */
769 partial
= CFStringCreateWithSubstring(NULL
, oidAndName
, CFRangeMake(0, delimiter
.location
));
770 if (oid
) { *oid
= CFRetainSafe(partial
); }
771 CFReleaseNull(partial
);
773 /* get second half: name */
774 if (delimiter
.location
+ 2 >= CFStringGetLength(oidAndName
)) {
775 return errSecSuccess
; // name is optional
777 CFRange nameRange
= CFRangeMake(delimiter
.location
+2,
778 CFStringGetLength(oidAndName
) - delimiter
.location
- 2);
779 partial
= CFStringCreateWithSubstring(NULL
, oidAndName
, nameRange
);
780 if (name
) { *name
= CFRetainSafe(partial
); }
781 CFReleaseNull(partial
);
785 static SecPolicyRef
SecPolicyCreateWithXPCObject(xpc_object_t xpc_policy
, CFErrorRef
*error
) {
786 SecPolicyRef policy
= NULL
;
787 CFTypeRef oidAndName
= NULL
;
788 CFStringRef oid
= NULL
;
789 CFStringRef name
= NULL
;
790 CFTypeRef options
= NULL
;
792 require_action_quiet(xpc_policy
, exit
, SecError(errSecParam
, error
, CFSTR("policy xpc value is NULL")));
793 require_action_quiet(xpc_get_type(xpc_policy
) == XPC_TYPE_ARRAY
, exit
, SecError(errSecDecode
, error
, CFSTR("policy xpc value is not an array")));
794 require_action_quiet(xpc_array_get_count(xpc_policy
) >= 2, exit
, SecError(errSecDecode
, error
, CFSTR("policy xpc array count < 2")));
795 oidAndName
= _CFXPCCreateCFObjectFromXPCObject(xpc_array_get_value(xpc_policy
, 0));
796 require_action_quiet(isString(oidAndName
), exit
,
797 SecError(errSecParam
, error
, CFSTR("failed to convert xpc policy[0]=%@ to CFString"), oidAndName
));
798 options
= _CFXPCCreateCFObjectFromXPCObject(xpc_array_get_value(xpc_policy
, 1));
799 require_action_quiet(isDictionary(options
), exit
,
800 SecError(errSecParam
, error
, CFSTR("failed to convert xpc policy[1]=%@ to CFDictionary"), options
));
801 require_noerr_action_quiet(parseOidAndName(oidAndName
, &oid
, &name
), exit
,
802 SecError(errSecParam
, error
, CFSTR("failed to convert combined %@ to name and oid"), oidAndName
));
803 require_action_quiet(policy
= SecPolicyCreate(oid
, name
, options
), exit
,
804 SecError(errSecDecode
, error
, CFSTR("Failed to create policy")));
807 CFReleaseSafe(oidAndName
);
810 CFReleaseSafe(options
);
814 CFArrayRef
SecPolicyXPCArrayCopyArray(xpc_object_t xpc_policies
, CFErrorRef
*error
) {
815 CFMutableArrayRef policies
= NULL
;
816 require_action_quiet(xpc_get_type(xpc_policies
) == XPC_TYPE_ARRAY
, exit
,
817 SecError(errSecParam
, error
, CFSTR("policies xpc value is not an array")));
818 size_t count
= xpc_array_get_count(xpc_policies
);
819 require_action_quiet(policies
= CFArrayCreateMutable(kCFAllocatorDefault
, count
, &kCFTypeArrayCallBacks
), exit
,
820 SecError(errSecAllocate
, error
, CFSTR("failed to create CFArray of capacity %zu"), count
));
823 for (ix
= 0; ix
< count
; ++ix
) {
824 SecPolicyRef policy
= SecPolicyCreateWithXPCObject(xpc_array_get_value(xpc_policies
, ix
), error
);
829 CFArraySetValueAtIndex(policies
, ix
, policy
);
838 static SEC_CONST_DECL (kSecPolicyOptions
, "policyOptions");
840 static SecPolicyRef
SecPolicyCreateWithDictionary(CFDictionaryRef dict
) {
841 SecPolicyRef policy
= NULL
;
842 CFStringRef oid
= (CFStringRef
)CFDictionaryGetValue(dict
, kSecPolicyOid
);
843 require_quiet(isString(oid
), errOut
);
844 CFDictionaryRef options
= (CFDictionaryRef
)CFDictionaryGetValue(dict
, kSecPolicyOptions
);
845 require_quiet(isDictionary(options
), errOut
);
846 CFStringRef name
= (CFStringRef
)CFDictionaryGetValue(dict
, kSecPolicyPolicyName
);
847 policy
= SecPolicyCreate(oid
, name
, options
);
852 static void deserializePolicy(const void *value
, void *context
) {
853 CFDictionaryRef policyDict
= (CFDictionaryRef
)value
;
854 if (isDictionary(policyDict
)) {
855 CFTypeRef deserializedPolicy
= SecPolicyCreateWithDictionary(policyDict
);
856 if (deserializedPolicy
) {
857 CFArrayAppendValue((CFMutableArrayRef
)context
, deserializedPolicy
);
858 CFRelease(deserializedPolicy
);
863 CFArrayRef
SecPolicyArrayCreateDeserialized(CFArrayRef serializedPolicies
) {
864 CFMutableArrayRef result
= NULL
;
865 require_quiet(isArray(serializedPolicies
), errOut
);
866 CFIndex count
= CFArrayGetCount(serializedPolicies
);
867 result
= CFArrayCreateMutable(kCFAllocatorDefault
, count
, &kCFTypeArrayCallBacks
);
868 CFRange all_policies
= { 0, count
};
869 CFArrayApplyFunction(serializedPolicies
, all_policies
, deserializePolicy
, result
);
874 static CFDictionaryRef
SecPolicyCreateDictionary(SecPolicyRef policy
) {
875 CFMutableDictionaryRef dict
= NULL
;
876 dict
= CFDictionaryCreateMutable(NULL
, 3, &kCFTypeDictionaryKeyCallBacks
,
877 &kCFTypeDictionaryValueCallBacks
);
878 CFDictionaryAddValue(dict
, kSecPolicyOid
, policy
->_oid
);
879 CFDictionaryAddValue(dict
, kSecPolicyOptions
, policy
->_options
);
881 CFDictionaryAddValue(dict
, kSecPolicyPolicyName
, policy
->_name
);
886 static void serializePolicy(const void *value
, void *context
) {
887 SecPolicyRef policy
= (SecPolicyRef
)value
;
888 if (policy
&& SecPolicyGetTypeID() == CFGetTypeID(policy
)) {
889 CFDictionaryRef serializedPolicy
= SecPolicyCreateDictionary(policy
);
890 if (serializedPolicy
) {
891 CFArrayAppendValue((CFMutableArrayRef
)context
, serializedPolicy
);
892 CFRelease(serializedPolicy
);
897 CFArrayRef
SecPolicyArrayCreateSerialized(CFArrayRef policies
) {
898 CFMutableArrayRef result
= NULL
;
899 require_quiet(isArray(policies
), errOut
);
900 CFIndex count
= CFArrayGetCount(policies
);
901 result
= CFArrayCreateMutable(NULL
, count
, &kCFTypeArrayCallBacks
);
902 CFRange all_policies
= { 0, count
};
903 CFArrayApplyFunction(policies
, all_policies
, serializePolicy
, result
);
908 static void add_element(CFMutableDictionaryRef options
, CFStringRef key
,
910 CFTypeRef old_value
= CFDictionaryGetValue(options
, key
);
912 CFMutableArrayRef array
;
913 if (CFGetTypeID(old_value
) == CFArrayGetTypeID()) {
914 array
= (CFMutableArrayRef
)old_value
;
916 array
= CFArrayCreateMutable(kCFAllocatorDefault
, 0,
917 &kCFTypeArrayCallBacks
);
918 CFArrayAppendValue(array
, old_value
);
919 CFDictionarySetValue(options
, key
, array
);
922 CFArrayAppendValue(array
, value
);
924 CFDictionaryAddValue(options
, key
, value
);
928 static void add_eku(CFMutableDictionaryRef options
, const DERItem
*ekuOid
) {
929 CFDataRef eku
= CFDataCreate(kCFAllocatorDefault
,
930 ekuOid
? ekuOid
->data
: NULL
,
931 ekuOid
? ekuOid
->length
: 0);
933 add_element(options
, kSecPolicyCheckExtendedKeyUsage
, eku
);
938 static void add_eku_string(CFMutableDictionaryRef options
, CFStringRef ekuOid
) {
940 add_element(options
, kSecPolicyCheckExtendedKeyUsage
, ekuOid
);
944 static void set_ssl_ekus(CFMutableDictionaryRef options
, bool server
) {
945 CFDictionaryRemoveValue(options
, kSecPolicyCheckExtendedKeyUsage
);
947 /* If server and EKU ext present then EKU ext should contain one of
948 ServerAuth or ExtendedKeyUsageAny or NetscapeSGC or MicrosoftSGC.
949 else if !server and EKU ext present then EKU ext should contain one of
950 ClientAuth or ExtendedKeyUsageAny. */
952 /* We always allow certificates that specify oidAnyExtendedKeyUsage. */
953 add_eku(options
, NULL
); /* eku extension is optional */
954 add_eku(options
, &oidAnyExtendedKeyUsage
);
956 add_eku(options
, &oidExtendedKeyUsageServerAuth
);
957 add_eku(options
, &oidExtendedKeyUsageMicrosoftSGC
);
958 add_eku(options
, &oidExtendedKeyUsageNetscapeSGC
);
960 add_eku(options
, &oidExtendedKeyUsageClientAuth
);
964 static void add_ku(CFMutableDictionaryRef options
, SecKeyUsage keyUsage
) {
965 SInt32 dku
= keyUsage
;
966 CFNumberRef ku
= CFNumberCreate(kCFAllocatorDefault
, kCFNumberSInt32Type
,
969 add_element(options
, kSecPolicyCheckKeyUsage
, ku
);
975 static void set_ku_from_properties(SecPolicyRef policy
, CFDictionaryRef properties
) {
976 if (!policy
|| !properties
) {
980 CFStringRef keyNames
[] = { kSecPolicyKU_DigitalSignature
, kSecPolicyKU_NonRepudiation
, kSecPolicyKU_KeyEncipherment
, kSecPolicyKU_DataEncipherment
,
981 kSecPolicyKU_KeyAgreement
, kSecPolicyKU_KeyCertSign
, kSecPolicyKU_CRLSign
, kSecPolicyKU_EncipherOnly
, kSecPolicyKU_DecipherOnly
};
983 uint32_t keyUsageValues
[] = { kSecKeyUsageDigitalSignature
, kSecKeyUsageNonRepudiation
, kSecKeyUsageKeyEncipherment
, kSecKeyUsageDataEncipherment
,
984 kSecKeyUsageKeyAgreement
, kSecKeyUsageKeyCertSign
, kSecKeyUsageCRLSign
, kSecKeyUsageEncipherOnly
, kSecKeyUsageDecipherOnly
};
986 bool haveKeyUsage
= false;
987 CFTypeRef keyUsageBoolean
;
988 for (uint32_t i
= 0; i
< sizeof(keyNames
) / sizeof(CFStringRef
); ++i
) {
989 if (CFDictionaryGetValueIfPresent(properties
, keyNames
[i
], (const void**)&keyUsageBoolean
)) {
990 if (CFEqual(keyUsageBoolean
, kCFBooleanTrue
)) {
1001 CFMutableDictionaryRef options
= (CFMutableDictionaryRef
) policy
->_options
;
1003 options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1004 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
1005 if (!options
) return;
1006 policy
->_options
= options
;
1008 CFDictionaryRemoveValue(options
, kSecPolicyCheckKeyUsage
);
1011 for (uint32_t i
= 0; i
< sizeof(keyNames
) / sizeof(CFStringRef
); ++i
) {
1012 if (CFDictionaryGetValueIfPresent(properties
, keyNames
[i
], (const void**)&keyUsageBoolean
)) {
1013 if (CFEqual(keyUsageBoolean
, kCFBooleanTrue
)) {
1014 add_ku(options
, keyUsageValues
[i
]);
1021 static void add_oid(CFMutableDictionaryRef options
, CFStringRef policy_key
, const DERItem
*oid
) {
1022 CFDataRef oid_data
= CFDataCreate(kCFAllocatorDefault
,
1023 oid
? oid
->data
: NULL
,
1024 oid
? oid
->length
: 0);
1026 add_element(options
, policy_key
, oid_data
);
1027 CFRelease(oid_data
);
1031 static void add_leaf_marker_value(CFMutableDictionaryRef options
, const DERItem
*markerOid
, CFStringRef string_value
) {
1033 CFTypeRef policyData
= NULL
;
1035 if (NULL
== string_value
) {
1036 policyData
= CFDataCreate(kCFAllocatorDefault
,
1037 markerOid
? markerOid
->data
: NULL
,
1038 markerOid
? markerOid
->length
: 0);
1040 CFStringRef oid_as_string
= SecDERItemCopyOIDDecimalRepresentation(kCFAllocatorDefault
, markerOid
);
1042 const void *key
[1] = { oid_as_string
};
1043 const void *value
[1] = { string_value
};
1044 policyData
= CFDictionaryCreate(kCFAllocatorDefault
,
1046 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
1047 CFReleaseNull(oid_as_string
);
1050 add_element(options
, kSecPolicyCheckLeafMarkerOid
, policyData
);
1052 CFReleaseNull(policyData
);
1056 static void add_leaf_marker(CFMutableDictionaryRef options
, const DERItem
*markerOid
) {
1057 add_leaf_marker_value(options
, markerOid
, NULL
);
1060 static void add_leaf_marker_value_string(CFMutableDictionaryRef options
, CFStringRef markerOid
, CFStringRef string_value
) {
1061 if (NULL
== string_value
) {
1062 add_element(options
, kSecPolicyCheckLeafMarkerOid
, markerOid
);
1064 CFDictionaryRef policyData
= NULL
;
1065 const void *key
[1] = { markerOid
};
1066 const void *value
[1] = { string_value
};
1067 policyData
= CFDictionaryCreate(kCFAllocatorDefault
,
1069 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
1070 add_element(options
, kSecPolicyCheckLeafMarkerOid
, policyData
);
1072 CFReleaseNull(policyData
);
1076 static void add_leaf_marker_string(CFMutableDictionaryRef options
, CFStringRef markerOid
) {
1077 add_leaf_marker_value_string(options
, markerOid
, NULL
);
1080 static void add_leaf_prod_qa_element(CFMutableDictionaryRef options
, CFTypeRef prodValue
, CFTypeRef qaValue
)
1082 CFMutableDictionaryRef prodAndQADictionary
= CFDictionaryCreateMutable(NULL
, 0, &kCFTypeDictionaryKeyCallBacks
,
1083 &kCFTypeDictionaryValueCallBacks
);
1084 CFDictionaryRef old_value
= CFDictionaryGetValue(options
, kSecPolicyCheckLeafMarkersProdAndQA
);
1086 CFMutableArrayRef prodArray
= NULL
, qaArray
= NULL
;
1087 CFTypeRef old_prod_value
= CFDictionaryGetValue(old_value
, kSecPolicyLeafMarkerProd
);
1088 CFTypeRef old_qa_value
= CFDictionaryGetValue(old_value
, kSecPolicyLeafMarkerQA
);
1089 if (isArray(old_prod_value
) && isArray(old_qa_value
)) {
1090 prodArray
= (CFMutableArrayRef
)CFRetainSafe(old_prod_value
);
1091 qaArray
= (CFMutableArrayRef
)CFRetainSafe(old_qa_value
);
1093 prodArray
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
1094 qaArray
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
1095 CFArrayAppendValue(prodArray
, old_prod_value
);
1096 CFArrayAppendValue(qaArray
, old_qa_value
);
1098 CFArrayAppendValue(prodArray
, prodValue
);
1099 CFArrayAppendValue(qaArray
, qaValue
);
1100 CFDictionaryAddValue(prodAndQADictionary
, kSecPolicyLeafMarkerProd
, prodArray
);
1101 CFDictionaryAddValue(prodAndQADictionary
, kSecPolicyLeafMarkerQA
, qaArray
);
1102 CFReleaseNull(prodArray
);
1103 CFReleaseNull(qaArray
);
1106 CFDictionaryAddValue(prodAndQADictionary
, kSecPolicyLeafMarkerProd
, prodValue
);
1107 CFDictionaryAddValue(prodAndQADictionary
, kSecPolicyLeafMarkerQA
, qaValue
);
1109 CFDictionarySetValue(options
, kSecPolicyCheckLeafMarkersProdAndQA
, prodAndQADictionary
);
1110 CFReleaseNull(prodAndQADictionary
);
1114 static void add_leaf_prod_qa_markers(CFMutableDictionaryRef options
, const DERItem
*prodMarkerOid
, const DERItem
*qaMarkerOid
)
1116 CFDataRef prodData
= NULL
, qaData
= NULL
;
1117 prodData
= CFDataCreate(NULL
, prodMarkerOid
? prodMarkerOid
->data
: NULL
,
1118 prodMarkerOid
? prodMarkerOid
->length
: 0);
1119 qaData
= CFDataCreate(NULL
, qaMarkerOid
? qaMarkerOid
->data
: NULL
,
1120 qaMarkerOid
? qaMarkerOid
->length
: 0);
1121 add_leaf_prod_qa_element(options
, prodData
, qaData
);
1122 CFReleaseNull(prodData
);
1123 CFReleaseNull(qaData
);
1126 static void add_leaf_prod_qa_markers_string(CFMutableDictionaryRef options
, CFStringRef prodMarkerOid
, CFStringRef qaMarkerOid
)
1128 add_leaf_prod_qa_element(options
, prodMarkerOid
, qaMarkerOid
);
1131 static void add_leaf_prod_qa_markers_value_string(CFMutableDictionaryRef options
,
1132 CFStringRef prodMarkerOid
, CFStringRef prod_value
,
1133 CFStringRef qaMarkerOid
, CFStringRef qa_value
)
1135 if (!prod_value
&& !qa_value
) {
1136 add_leaf_prod_qa_element(options
, prodMarkerOid
, qaMarkerOid
);
1138 CFDictionaryRef prodData
= NULL
, qaData
= NULL
;
1139 const void *prodKey
[1] = { prodMarkerOid
}, *qaKey
[1] = { qaMarkerOid
};
1140 const void *prodValue
[1] = { prod_value
}, *qaValue
[1] = { qa_value
};
1141 prodData
= CFDictionaryCreate(NULL
, prodKey
, prodValue
, 1, &kCFTypeDictionaryKeyCallBacks
,
1142 &kCFTypeDictionaryValueCallBacks
);
1143 qaData
= CFDictionaryCreate(NULL
, qaKey
, qaValue
, 1, &kCFTypeDictionaryKeyCallBacks
,
1144 &kCFTypeDictionaryValueCallBacks
);
1145 add_leaf_prod_qa_element(options
, prodData
, qaData
);
1146 CFReleaseNull(prodData
);
1147 CFReleaseNull(qaData
);
1151 static void add_intermediate_marker_value_string(CFMutableDictionaryRef options
, CFStringRef markerOid
, CFStringRef string_value
) {
1152 if (NULL
== string_value
) {
1153 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, markerOid
);
1155 CFDictionaryRef policyData
= NULL
;
1156 const void *key
[1] = { markerOid
};
1157 const void *value
[1] = { string_value
};
1158 policyData
= CFDictionaryCreate(kCFAllocatorDefault
,
1160 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
1161 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, policyData
);
1163 CFReleaseNull(policyData
);
1167 static void add_certificate_policy_oid(CFMutableDictionaryRef options
, const DERItem
*certificatePolicyOid
) {
1168 CFTypeRef certificatePolicyData
= NULL
;
1169 certificatePolicyData
= CFDataCreate(kCFAllocatorDefault
,
1170 certificatePolicyOid
? certificatePolicyOid
->data
: NULL
,
1171 certificatePolicyOid
? certificatePolicyOid
->length
: 0);
1172 if (certificatePolicyData
) {
1173 add_element(options
, kSecPolicyCheckCertificatePolicy
, certificatePolicyData
);
1174 CFRelease(certificatePolicyData
);
1178 static void add_certificate_policy_oid_string(CFMutableDictionaryRef options
, CFStringRef certificatePolicyOid
) {
1179 if (certificatePolicyOid
) {
1180 add_element(options
, kSecPolicyCheckCertificatePolicy
, certificatePolicyOid
);
1185 // Routines for adding dictionary entries for policies.
1188 // X.509, but missing validity requirements.
1189 static void SecPolicyAddBasicCertOptions(CFMutableDictionaryRef options
)
1191 //CFDictionaryAddValue(options, kSecPolicyCheckBasicCertificateProcessing, kCFBooleanTrue);
1192 // Happens automatically in SecPVCPathChecks
1193 CFDictionaryAddValue(options
, kSecPolicyCheckCriticalExtensions
, kCFBooleanTrue
);
1194 CFDictionaryAddValue(options
, kSecPolicyCheckIdLinkage
, kCFBooleanTrue
);
1195 CFDictionaryAddValue(options
, kSecPolicyCheckBasicConstraints
, kCFBooleanTrue
);
1196 CFDictionaryAddValue(options
, kSecPolicyCheckNonEmptySubject
, kCFBooleanTrue
);
1197 CFDictionaryAddValue(options
, kSecPolicyCheckWeakKeySize
, kCFBooleanTrue
);
1198 CFDictionaryAddValue(options
, kSecPolicyCheckWeakSignature
, kCFBooleanTrue
);
1201 static void SecPolicyAddBasicX509Options(CFMutableDictionaryRef options
)
1203 SecPolicyAddBasicCertOptions(options
);
1204 CFDictionaryAddValue(options
, kSecPolicyCheckTemporalValidity
, kCFBooleanTrue
);
1206 // Make sure that black and gray leaf checks are performed for basic X509 chain building
1207 CFDictionaryAddValue(options
, kSecPolicyCheckBlackListedLeaf
, kCFBooleanTrue
);
1208 CFDictionaryAddValue(options
, kSecPolicyCheckGrayListedLeaf
, kCFBooleanTrue
);
1211 static bool SecPolicyAddChainLengthOptions(CFMutableDictionaryRef options
, CFIndex length
)
1213 bool result
= false;
1214 CFNumberRef lengthAsCF
= NULL
;
1216 require(lengthAsCF
= CFNumberCreate(kCFAllocatorDefault
,
1217 kCFNumberCFIndexType
, &length
), errOut
);
1218 CFDictionaryAddValue(options
, kSecPolicyCheckChainLength
, lengthAsCF
);
1223 CFReleaseSafe(lengthAsCF
);
1227 static bool SecPolicyAddAnchorSHA1Options(CFMutableDictionaryRef options
,
1228 const UInt8 anchorSha1
[kSecPolicySHA1Size
])
1230 bool success
= false;
1231 CFDataRef anchorData
= NULL
;
1233 require(anchorData
= CFDataCreate(kCFAllocatorDefault
, anchorSha1
, kSecPolicySHA1Size
), errOut
);
1234 add_element(options
, kSecPolicyCheckAnchorSHA1
, anchorData
);
1239 CFReleaseSafe(anchorData
);
1243 static bool SecPolicyAddAnchorSHA256Options(CFMutableDictionaryRef options
,
1244 const UInt8 anchorSha1
[kSecPolicySHA256Size
])
1246 bool success
= false;
1247 CFDataRef anchorData
= NULL
;
1249 require(anchorData
= CFDataCreate(kCFAllocatorDefault
, anchorSha1
, kSecPolicySHA256Size
), errOut
);
1250 add_element(options
, kSecPolicyCheckAnchorSHA256
, anchorData
);
1255 CFReleaseSafe(anchorData
);
1259 static bool SecPolicyAddStrongKeySizeOptions(CFMutableDictionaryRef options
) {
1260 bool success
= false;
1261 CFDictionaryRef keySizes
= NULL
;
1262 CFNumberRef rsaSize
= NULL
, ecSize
= NULL
;
1264 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
1265 require(rsaSize
= CFNumberCreateWithCFIndex(NULL
, 2048), errOut
);
1266 require(ecSize
= CFNumberCreateWithCFIndex(NULL
, 256), errOut
);
1267 const void *keys
[] = { kSecAttrKeyTypeRSA
, kSecAttrKeyTypeEC
};
1268 const void *values
[] = { rsaSize
, ecSize
};
1269 require(keySizes
= CFDictionaryCreate(NULL
, keys
, values
, 2,
1270 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1271 add_element(options
, kSecPolicyCheckKeySize
, keySizes
);
1276 CFReleaseSafe(keySizes
);
1277 CFReleaseSafe(rsaSize
);
1278 CFReleaseSafe(ecSize
);
1282 static bool SecPolicyRemoveWeakHashOptions(CFMutableDictionaryRef options
) {
1283 CFMutableArrayRef disallowedHashes
= CFArrayCreateMutable(NULL
, 5, &kCFTypeArrayCallBacks
);
1284 if (!disallowedHashes
) {
1287 CFArrayAppendValue(disallowedHashes
, kSecSignatureDigestAlgorithmMD2
);
1288 CFArrayAppendValue(disallowedHashes
, kSecSignatureDigestAlgorithmMD4
);
1289 CFArrayAppendValue(disallowedHashes
, kSecSignatureDigestAlgorithmMD5
);
1290 CFArrayAppendValue(disallowedHashes
, kSecSignatureDigestAlgorithmSHA1
);
1292 add_element(options
, kSecPolicyCheckSignatureHashAlgorithms
, disallowedHashes
);
1293 CFReleaseNull(disallowedHashes
);
1297 static bool isAppleOid(CFStringRef oid
) {
1298 if (!SecCertificateIsOidString(oid
)) {
1301 if (CFStringHasPrefix(oid
, CFSTR("1.2.840.113635"))) {
1307 static bool isCFPreferenceInSecurityDomain(CFStringRef setting
) {
1308 return (CFPreferencesGetAppBooleanValue(setting
, CFSTR("com.apple.security"), NULL
));
1311 static bool SecPolicyAddAppleAnchorOptions(CFMutableDictionaryRef options
, CFStringRef __unused policyName
)
1313 CFMutableDictionaryRef appleAnchorOptions
= NULL
;
1314 appleAnchorOptions
= CFDictionaryCreateMutableForCFTypes(NULL
);
1315 if (!appleAnchorOptions
) {
1319 /* Currently no Apple Anchor options */
1320 add_element(options
, kSecPolicyCheckAnchorApple
, appleAnchorOptions
);
1321 CFReleaseSafe(appleAnchorOptions
);
1325 static bool SecPolicyAddPinningRequiredIfInfoSpecified(CFMutableDictionaryRef options
)
1327 CFBundleRef bundle
= CFBundleGetMainBundle();
1329 CFTypeRef value
= CFBundleGetValueForInfoDictionaryKey(bundle
, CFSTR("SecTrustPinningRequired"));
1330 if (isBoolean(value
) && CFBooleanGetValue(value
)) {
1331 add_element(options
, kSecPolicyCheckPinningRequired
, kCFBooleanTrue
);
1340 // MARK: Policy Creation Functions
1342 SecPolicyRef
SecPolicyCreateBasicX509(void) {
1343 CFMutableDictionaryRef options
= NULL
;
1344 SecPolicyRef result
= NULL
;
1346 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1347 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1349 SecPolicyAddBasicX509Options(options
);
1350 CFDictionaryAddValue(options
, kSecPolicyCheckNoNetworkAccess
,
1353 require(result
= SecPolicyCreate(kSecPolicyAppleX509Basic
, kSecPolicyNameX509Basic
, options
), errOut
);
1356 CFReleaseSafe(options
);
1357 return (SecPolicyRef _Nonnull
)result
;
1360 SecPolicyRef
SecPolicyCreateSSL(Boolean server
, CFStringRef hostname
) {
1361 CFMutableDictionaryRef options
= NULL
;
1362 SecPolicyRef result
= NULL
;
1364 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1365 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1367 SecPolicyAddBasicX509Options(options
);
1370 CFDictionaryAddValue(options
, kSecPolicyCheckSSLHostname
, hostname
);
1373 CFDictionaryAddValue(options
, kSecPolicyCheckBlackListedLeaf
, kCFBooleanTrue
);
1374 CFDictionaryAddValue(options
, kSecPolicyCheckGrayListedLeaf
, kCFBooleanTrue
);
1377 require_quiet(SecPolicyRemoveWeakHashOptions(options
), errOut
);
1378 require_quiet(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
1379 require_quiet(SecPolicyAddPinningRequiredIfInfoSpecified(options
), errOut
);
1380 CFDictionaryAddValue(options
, kSecPolicyCheckValidityPeriodMaximums
, kCFBooleanTrue
);
1381 CFDictionaryAddValue(options
, kSecPolicyCheckServerAuthEKU
, kCFBooleanTrue
); // enforces stricter EKU rules than set_ssl_ekus below for certain anchor types
1382 #if !TARGET_OS_BRIDGE
1383 CFDictionaryAddValue(options
, kSecPolicyCheckSystemTrustedCTRequired
, kCFBooleanTrue
);
1387 set_ssl_ekus(options
, server
);
1389 require(result
= SecPolicyCreate(kSecPolicyAppleSSL
,
1390 server
? kSecPolicyNameSSLServer
: kSecPolicyNameSSLClient
,
1394 CFReleaseSafe(options
);
1395 return (SecPolicyRef _Nonnull
)result
;
1398 SecPolicyRef
SecPolicyCreateLegacySSL(Boolean server
, CFStringRef hostname
) {
1399 CFMutableDictionaryRef options
= NULL
;
1400 SecPolicyRef result
= NULL
;
1402 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1403 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1405 SecPolicyAddBasicX509Options(options
);
1408 CFDictionaryAddValue(options
, kSecPolicyCheckSSLHostname
, hostname
);
1411 CFDictionaryAddValue(options
, kSecPolicyCheckBlackListedLeaf
, kCFBooleanTrue
);
1412 CFDictionaryAddValue(options
, kSecPolicyCheckGrayListedLeaf
, kCFBooleanTrue
);
1415 // fewer requirements than the standard SSL policy
1416 require_quiet(SecPolicyAddPinningRequiredIfInfoSpecified(options
), errOut
);
1417 CFDictionaryAddValue(options
, kSecPolicyCheckValidityPeriodMaximums
, kCFBooleanTrue
);
1418 #if !TARGET_OS_BRIDGE
1419 CFDictionaryAddValue(options
, kSecPolicyCheckSystemTrustedCTRequired
, kCFBooleanTrue
);
1423 set_ssl_ekus(options
, server
);
1425 require(result
= SecPolicyCreate(kSecPolicyAppleLegacySSL
, kSecPolicyNameLegacySSL
, options
), errOut
);
1428 CFReleaseSafe(options
);
1429 return (SecPolicyRef _Nonnull
)result
;
1432 SecPolicyRef
SecPolicyCreateApplePinned(CFStringRef policyName
, CFStringRef intermediateMarkerOID
, CFStringRef leafMarkerOID
) {
1433 CFMutableDictionaryRef options
= NULL
;
1434 SecPolicyRef result
= NULL
;
1436 if (!policyName
|| !intermediateMarkerOID
|| !leafMarkerOID
) {
1440 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1441 &kCFTypeDictionaryKeyCallBacks
,
1442 &kCFTypeDictionaryValueCallBacks
), errOut
);
1444 SecPolicyAddBasicX509Options(options
);
1446 /* Anchored to the Apple Roots */
1447 require(SecPolicyAddAppleAnchorOptions(options
, policyName
), errOut
);
1449 /* Exactly 3 certs in the chain */
1450 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1452 /* Intermediate marker OID matches input OID */
1453 if (!isAppleOid(intermediateMarkerOID
)) {
1454 secwarning("creating an Apple pinning policy with a non-Apple OID: %@", intermediateMarkerOID
);
1456 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, intermediateMarkerOID
);
1458 /* Leaf marker OID matches input OID */
1459 if (!isAppleOid(leafMarkerOID
)) {
1460 secwarning("creating an Apple pinning policy with a non-Apple OID: %@", leafMarkerOID
);
1462 add_leaf_marker_string(options
, leafMarkerOID
);
1464 /* Check revocation using any available method */
1465 add_element(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
1467 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
1468 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
1470 /* Check for weak hashes */
1471 // require(SecPolicyRemoveWeakHashOptions(options), errOut); // the current WWDR CA cert is signed with SHA1
1472 require(result
= SecPolicyCreate(kSecPolicyAppleGenericApplePinned
,
1473 policyName
, options
), errOut
);
1476 CFReleaseSafe(options
);
1481 requireUATPinning(CFStringRef service
)
1483 bool pinningRequired
= true;
1485 if (SecIsInternalRelease()) {
1486 CFStringRef setting
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("AppleServerAuthenticationNoPinning%@"), service
);
1487 require(setting
, fail
);
1488 if(isCFPreferenceInSecurityDomain(setting
)) {
1489 pinningRequired
= false;
1491 secnotice("pinningQA", "could not disable pinning: %@ not true", setting
);
1495 if (!pinningRequired
) {
1499 if(isCFPreferenceInSecurityDomain(CFSTR("AppleServerAuthenticationNoPinning"))) {
1500 pinningRequired
= false;
1502 secnotice("pinningQA", "could not disable pinning: AppleServerAuthenticationNoPinning not true");
1505 secnotice("pinningQA", "could not disable pinning: not an internal release");
1508 return pinningRequired
;
1511 SecPolicyRef
SecPolicyCreateAppleSSLPinned(CFStringRef policyName
, CFStringRef hostname
,
1512 CFStringRef intermediateMarkerOID
, CFStringRef leafMarkerOID
) {
1513 CFMutableDictionaryRef options
= NULL
, appleAnchorOptions
= NULL
;
1514 SecPolicyRef result
= NULL
;
1516 if (!policyName
|| !hostname
|| !leafMarkerOID
) {
1520 if (requireUATPinning(policyName
)) {
1521 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1522 &kCFTypeDictionaryKeyCallBacks
,
1523 &kCFTypeDictionaryValueCallBacks
), errOut
);
1525 SecPolicyAddBasicX509Options(options
);
1527 /* Anchored to the Apple Roots */
1528 require(SecPolicyAddAppleAnchorOptions(options
, policyName
), errOut
);
1530 /* Exactly 3 certs in the chain */
1531 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1533 if (intermediateMarkerOID
) {
1534 /* Intermediate marker OID matches input OID */
1535 if (!isAppleOid(intermediateMarkerOID
)) {
1536 secwarning("creating an Apple pinning policy with a non-Apple OID: %@", intermediateMarkerOID
);
1538 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, intermediateMarkerOID
);
1540 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.12"));
1543 /* Leaf marker OID matches input OID */
1544 if (!isAppleOid(leafMarkerOID
)) {
1545 secwarning("creating an Apple pinning policy with a non-Apple OID: %@", leafMarkerOID
);
1547 add_leaf_marker_string(options
, leafMarkerOID
);
1549 /* New leaf marker OID format */
1550 add_leaf_marker_value_string(options
, CFSTR("1.2.840.113635.100.6.48.1"), leafMarkerOID
);
1552 /* ServerAuth EKU is in leaf cert */
1553 add_eku_string(options
, CFSTR("1.3.6.1.5.5.7.3.1"));
1555 /* Hostname is in leaf cert */
1556 add_element(options
, kSecPolicyCheckSSLHostname
, hostname
);
1558 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
1559 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
1561 /* Check for weak hashes */
1562 require(SecPolicyRemoveWeakHashOptions(options
), errOut
);
1564 /* Check revocation using any available method */
1565 add_element(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
1567 require(result
= SecPolicyCreate(kSecPolicyAppleGenericAppleSSLPinned
,
1568 policyName
, options
), errOut
);
1571 result
= SecPolicyCreateSSL(true, hostname
);
1572 SecPolicySetOid(result
, kSecPolicyAppleGenericAppleSSLPinned
);
1573 SecPolicySetName(result
, policyName
);
1577 CFReleaseSafe(options
);
1578 CFReleaseSafe(appleAnchorOptions
);
1582 SecPolicyRef
SecPolicyCreateiPhoneActivation(void) {
1583 CFMutableDictionaryRef options
= NULL
;
1584 SecPolicyRef result
= NULL
;
1586 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1587 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1589 SecPolicyAddBasicCertOptions(options
);
1592 CFDictionaryAddValue(options
, kSecPolicyCheckKeyUsage
,
1594 CFDictionaryAddValue(options
, kSecPolicyCheckExtendedKeyUsage
,
1598 /* Basic X.509 policy with the additional requirements that the chain
1599 length is 3, it's anchored at the AppleCA and the leaf certificate
1600 has issuer "Apple iPhone Certification Authority" and
1601 subject "Apple iPhone Activation" for the common name. */
1602 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
1603 CFSTR("Apple iPhone Certification Authority"));
1604 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
,
1605 CFSTR("Apple iPhone Activation"));
1607 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1608 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameiPhoneActivation
), errOut
);
1610 require(result
= SecPolicyCreate(kSecPolicyAppleiPhoneActivation
,
1611 kSecPolicyNameiPhoneActivation
, options
),
1615 CFReleaseSafe(options
);
1619 SecPolicyRef
SecPolicyCreateiPhoneDeviceCertificate(void) {
1620 CFMutableDictionaryRef options
= NULL
;
1621 SecPolicyRef result
= NULL
;
1623 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1624 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1626 SecPolicyAddBasicCertOptions(options
);
1629 CFDictionaryAddValue(options
, kSecPolicyCheckKeyUsage
,
1631 CFDictionaryAddValue(options
, kSecPolicyCheckExtendedKeyUsage
,
1635 /* Basic X.509 policy with the additional requirements that the chain
1636 length is 4, it's anchored at the AppleCA and the first intermediate
1637 has the subject "Apple iPhone Device CA". */
1638 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
1639 CFSTR("Apple iPhone Device CA"));
1641 require(SecPolicyAddChainLengthOptions(options
, 4), errOut
);
1642 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameiPhoneDeviceCertificate
), errOut
);
1644 require(result
= SecPolicyCreate(kSecPolicyAppleiPhoneDeviceCertificate
,
1645 kSecPolicyNameiPhoneDeviceCertificate
, options
),
1649 CFReleaseSafe(options
);
1653 SecPolicyRef
SecPolicyCreateFactoryDeviceCertificate(void) {
1654 CFMutableDictionaryRef options
= NULL
;
1655 SecPolicyRef result
= NULL
;
1657 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1658 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1660 SecPolicyAddBasicCertOptions(options
);
1663 CFDictionaryAddValue(options
, kSecPolicyCheckKeyUsage
,
1665 CFDictionaryAddValue(options
, kSecPolicyCheckExtendedKeyUsage
,
1669 /* Basic X.509 policy with the additional requirements that the chain
1670 is anchored at the factory device certificate issuer. */
1671 require(SecPolicyAddAnchorSHA1Options(options
, kFactoryDeviceCASHA1
), errOut
);
1673 require(result
= SecPolicyCreate(kSecPolicyAppleFactoryDeviceCertificate
,
1674 kSecPolicyNameFactoryDeviceCertificate
, options
),
1678 CFReleaseSafe(options
);
1682 SecPolicyRef
SecPolicyCreateiAP(void) {
1683 CFMutableDictionaryRef options
= NULL
;
1684 SecPolicyRef result
= NULL
;
1685 CFTimeZoneRef tz
= NULL
;
1686 CFDateRef date
= NULL
;
1688 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1689 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1691 SecPolicyAddBasicCertOptions(options
);
1693 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonNamePrefix
,
1696 date
= CFDateCreateForGregorianZuluDay(NULL
, 2006, 5, 31);
1697 CFDictionaryAddValue(options
, kSecPolicyCheckNotValidBefore
, date
);
1699 require(result
= SecPolicyCreate(kSecPolicyAppleiAP
,
1700 kSecPolicyNameiAP
, options
),
1704 CFReleaseSafe(date
);
1706 CFReleaseSafe(options
);
1710 SecPolicyRef
SecPolicyCreateiTunesStoreURLBag(void) {
1711 CFMutableDictionaryRef options
= NULL
;
1712 SecPolicyRef result
= NULL
;
1715 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1716 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1718 SecPolicyAddBasicCertOptions(options
);
1720 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectOrganization
,
1721 CFSTR("Apple Inc."));
1722 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
,
1723 CFSTR("iTunes Store URL Bag"));
1725 require(SecPolicyAddChainLengthOptions(options
, 2), errOut
);
1726 require(SecPolicyAddAnchorSHA1Options(options
, kITMSCASHA1
), errOut
);
1728 require(result
= SecPolicyCreate(kSecPolicyAppleiTunesStoreURLBag
,
1729 kSecPolicyNameiTunesStoreURLBag
, options
), errOut
);
1732 CFReleaseSafe(options
);
1736 SecPolicyRef
SecPolicyCreateEAP(Boolean server
, CFArrayRef trustedServerNames
) {
1737 CFMutableDictionaryRef options
= NULL
;
1738 SecPolicyRef result
= NULL
;
1740 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1741 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1743 SecPolicyAddBasicX509Options(options
);
1745 /* Since EAP is used to setup the network we don't want evaluation
1746 using this policy to access the network. */
1747 CFDictionaryAddValue(options
, kSecPolicyCheckNoNetworkAccess
,
1750 if (trustedServerNames
) {
1751 CFDictionaryAddValue(options
, kSecPolicyCheckEAPTrustedServerNames
, trustedServerNames
);
1755 /* Check for weak hashes and keys, but only on system-trusted roots, because enterprise
1756 * PKIs are the absolute worst. */
1757 CFDictionaryAddValue(options
, kSecPolicyCheckSystemTrustedWeakHash
, kCFBooleanTrue
);
1758 CFDictionaryAddValue(options
, kSecPolicyCheckSystemTrustedWeakKey
, kCFBooleanTrue
);
1761 /* We need to check for EKU per rdar://22206018 */
1762 set_ssl_ekus(options
, server
);
1764 require(result
= SecPolicyCreate(kSecPolicyAppleEAP
,
1765 server
? kSecPolicyNameEAPServer
: kSecPolicyNameEAPClient
,
1769 CFReleaseSafe(options
);
1773 SecPolicyRef
SecPolicyCreateIPSec(Boolean server
, CFStringRef hostname
) {
1774 CFMutableDictionaryRef options
= NULL
;
1775 SecPolicyRef result
= NULL
;
1777 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1778 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1780 SecPolicyAddBasicX509Options(options
);
1783 CFDictionaryAddValue(options
, kSecPolicyCheckSSLHostname
, hostname
);
1786 /* Require oidExtendedKeyUsageIPSec if Extended Keyusage Extention is
1788 /* Per <rdar://problem/6843827> Cisco VPN Certificate compatibility issue.
1789 We don't check the EKU for IPSec certs for now. If we do add eku
1790 checking back in the future, we should probably also accept the
1792 ipsecEndSystem 1.3.6.1.5.5.7.3.5
1794 ipsecTunnel 1.3.6.1.5.5.7.3.6
1795 ipsecUser 1.3.6.1.5.5.7.3.7
1797 //add_eku(options, NULL); /* eku extension is optional */
1798 //add_eku(options, &oidAnyExtendedKeyUsage);
1799 //add_eku(options, &oidExtendedKeyUsageIPSec);
1801 require(result
= SecPolicyCreate(kSecPolicyAppleIPsec
,
1802 server
? kSecPolicyNameIPSecServer
: kSecPolicyNameIPSecClient
,
1806 CFReleaseSafe(options
);
1810 SecPolicyRef
SecPolicyCreateiPhoneApplicationSigning(void) {
1811 CFMutableDictionaryRef options
= NULL
;
1812 SecPolicyRef result
= NULL
;
1814 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1815 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1817 SecPolicyAddBasicCertOptions(options
);
1819 /* Anchored to the Apple Roots */
1820 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameiPhoneApplicationSigning
), errOut
);
1823 if (SecIsInternalRelease()) {
1824 /* Allow a prod hierarchy-signed test cert */
1825 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonNameTEST
,
1826 CFSTR("Apple iPhone OS Application Signing"));
1827 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.3.1"));
1830 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
,
1831 CFSTR("Apple iPhone OS Application Signing"));
1833 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.3"));
1835 add_eku(options
, NULL
); /* eku extension is optional */
1836 add_eku(options
, &oidAnyExtendedKeyUsage
);
1837 add_eku(options
, &oidExtendedKeyUsageCodeSigning
);
1839 /* Intermediate check */
1840 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
1841 CFSTR("Apple iPhone Certification Authority"));
1843 /* Chain length check */
1844 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1846 /* Skip networked revocation checks */
1847 CFDictionaryAddValue(options
, kSecPolicyCheckNoNetworkAccess
, kCFBooleanTrue
);
1849 require(result
= SecPolicyCreate(kSecPolicyAppleiPhoneApplicationSigning
,
1850 kSecPolicyNameiPhoneApplicationSigning
, options
),
1854 CFReleaseSafe(options
);
1858 SecPolicyRef
SecPolicyCreateiPhoneVPNApplicationSigning(void) {
1859 CFMutableDictionaryRef options
= NULL
;
1860 SecPolicyRef result
= NULL
;
1862 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1863 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1865 SecPolicyAddBasicCertOptions(options
);
1867 /* Anchored to the Apple Roots */
1868 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameiPhoneVPNApplicationSigning
), errOut
);
1871 if (SecIsInternalRelease()) {
1872 /* Allow a prod hierarchy-signed test cert */
1873 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonNameTEST
,
1874 CFSTR("Apple iPhone OS Application Signing"));
1875 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.6.1"));
1878 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
,
1879 CFSTR("Apple iPhone OS Application Signing"));
1881 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.6"));
1883 add_eku(options
, NULL
); /* eku extension is optional */
1884 add_eku(options
, &oidAnyExtendedKeyUsage
);
1885 add_eku(options
, &oidExtendedKeyUsageCodeSigning
);
1887 /* Intermediate check */
1888 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
1889 CFSTR("Apple iPhone Certification Authority"));
1891 /* Chain length check */
1892 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1894 /* Skip networked revocation checks */
1895 CFDictionaryAddValue(options
, kSecPolicyCheckNoNetworkAccess
, kCFBooleanTrue
);
1897 require(result
= SecPolicyCreate(kSecPolicyAppleiPhoneVPNApplicationSigning
,
1898 kSecPolicyNameiPhoneVPNApplicationSigning
, options
),
1902 CFReleaseSafe(options
);
1906 SecPolicyRef
SecPolicyCreateiPhoneProfileApplicationSigning(void) {
1907 CFMutableDictionaryRef options
= NULL
;
1908 SecPolicyRef result
= NULL
;
1910 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1911 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1913 SecPolicyAddBasicX509Options(options
); // With expiration checking
1916 require_quiet(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameiPhoneProfileApplicationSigning
),
1920 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1922 /* Leaf has CodeSigning EKU */
1923 add_eku_string(options
, CFSTR("1.3.6.1.5.5.7.3.3"));
1925 /* On iOS, the cert in the provisioning profile may be one of:
1926 leaf OID intermediate OID
1927 iPhone Developer <ADS>.6.1.2 <ADS>.6.2.1
1928 iPhone Distribution <ADS>.6.1.4 <ADS>.6.2.1
1929 TestFlight (Prod) <ADS>.6.1.25.1 <ADS>.6.2.1
1930 TestFlight (QA) <ADS>.6.1.25.2 <ADS>.6.2.1
1932 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.1"));
1933 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.2"));
1934 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.4"));
1935 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.25.1"));
1936 if (SecIsInternalRelease()) {
1937 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.25.2"));
1940 /* Revocation via any available method */
1941 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
1943 require(result
= SecPolicyCreate(kSecPolicyAppleiPhoneProfileApplicationSigning
,
1944 kSecPolicyNameiPhoneProfileApplicationSigning
,
1948 CFReleaseSafe(options
);
1952 SecPolicyRef
SecPolicyCreateMacOSProfileApplicationSigning(void) {
1953 CFMutableDictionaryRef options
= NULL
;
1954 SecPolicyRef result
= NULL
;
1956 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1957 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1959 SecPolicyAddBasicCertOptions(options
); // Without expiration checking
1962 require_quiet(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameiPhoneProfileApplicationSigning
),
1966 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1968 /* Leaf has CodeSigning EKU */
1969 add_eku_string(options
, CFSTR("1.3.6.1.5.5.7.3.3"));
1972 /* On macOS, the cert in the provisioning profile may be one of:
1973 leaf OID intermediate OID
1974 MAS Development <ADS>.6.1.12 <ADS>.6.2.1
1975 MAS Submission <ADS>.6.1.7 <ADS>.6.2.1
1976 Developer ID <ADS>.6.1.13 <ADS>.6.2.6
1977 B&I <ADS>.6.22 None - "Apple Code Signing Certification Authority"
1979 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.12"));
1980 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.7"));
1981 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.13"));
1982 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.22"));
1984 /* Revocation via any available method */
1985 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
1987 require(result
= SecPolicyCreate(kSecPolicyAppleMacOSProfileApplicationSigning
,
1988 kSecPolicyNameMacOSProfileApplicationSigning
,
1992 CFReleaseSafe(options
);
1996 SecPolicyRef
SecPolicyCreateiPhoneProvisioningProfileSigning(void) {
1997 CFMutableDictionaryRef options
= NULL
;
1998 SecPolicyRef result
= NULL
;
2000 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2001 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2003 SecPolicyAddBasicCertOptions(options
);
2005 /* Basic X.509 policy with the additional requirements that the chain
2006 length is 3, it's anchored at the AppleCA and the leaf certificate
2007 has issuer "Apple iPhone Certification Authority" and
2008 subject "Apple iPhone OS Provisioning Profile Signing" for the common name. */
2009 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2010 CFSTR("Apple iPhone Certification Authority"));
2011 if (SecIsInternalRelease()) {
2012 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonNameTEST
,
2013 CFSTR("Apple iPhone OS Provisioning Profile Signing"));
2016 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
,
2017 CFSTR("Apple iPhone OS Provisioning Profile Signing"));
2020 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2021 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameiPhoneProvisioningProfileSigning
), errOut
);
2023 /* Skip networked revocation checks */
2024 CFDictionaryAddValue(options
, kSecPolicyCheckNoNetworkAccess
, kCFBooleanTrue
);
2026 require(result
= SecPolicyCreate(kSecPolicyAppleiPhoneProvisioningProfileSigning
,
2027 kSecPolicyNameiPhoneProvisioningProfileSigning
, options
),
2030 /* 1.2.840.113635.100.6.2.2.1, non-critical: DER:05:00 - provisioning profile */
2033 CFReleaseSafe(options
);
2037 SecPolicyRef
SecPolicyCreateAppleTVOSApplicationSigning(void) {
2038 CFMutableDictionaryRef options
= NULL
;
2039 SecPolicyRef result
= NULL
;
2040 CFDataRef atvProdOid
= NULL
;
2041 CFDataRef atvTestOid
= NULL
;
2042 CFArrayRef oids
= NULL
;
2044 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2045 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2047 SecPolicyAddBasicCertOptions(options
);
2049 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2051 require_quiet(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameTVOSApplicationSigning
),
2054 /* Check for intermediate: Apple Worldwide Developer Relations */
2055 /* 1.2.840.113635.100.6.2.1 */
2056 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleWWDR
);
2058 add_ku(options
, kSecKeyUsageDigitalSignature
);
2060 /* Check for prod or test AppleTV Application Signing OIDs */
2061 /* Prod: 1.2.840.113635.100.6.1.24 */
2062 /* ProdQA: 1.2.840.113635.100.6.1.24.1 */
2063 add_leaf_marker(options
, &oidAppleTVOSApplicationSigningProd
);
2064 add_leaf_marker(options
, &oidAppleTVOSApplicationSigningProdQA
);
2066 /* Skip networked revocation checks */
2067 CFDictionaryAddValue(options
, kSecPolicyCheckNoNetworkAccess
, kCFBooleanTrue
);
2069 require(result
= SecPolicyCreate(kSecPolicyAppleTVOSApplicationSigning
,
2070 kSecPolicyNameTVOSApplicationSigning
, options
),
2074 CFReleaseSafe(options
);
2075 CFReleaseSafe(oids
);
2076 CFReleaseSafe(atvProdOid
);
2077 CFReleaseSafe(atvTestOid
);
2081 SecPolicyRef
SecPolicyCreateOCSPSigner(void) {
2082 CFMutableDictionaryRef options
= NULL
;
2083 SecPolicyRef result
= NULL
;
2085 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2086 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2088 SecPolicyAddBasicX509Options(options
);
2090 /* Require id-kp-OCSPSigning extendedKeyUsage to be present, not optional. */
2091 add_eku(options
, &oidExtendedKeyUsageOCSPSigning
);
2093 require(result
= SecPolicyCreate(kSecPolicyAppleOCSPSigner
,
2094 kSecPolicyNameOCSPSigner
, options
), errOut
);
2097 CFReleaseSafe(options
);
2101 SecPolicyRef
SecPolicyCreateRevocation(CFOptionFlags revocationFlags
) {
2102 CFMutableDictionaryRef options
= NULL
;
2103 SecPolicyRef result
= NULL
;
2105 require(revocationFlags
!= 0, errOut
);
2107 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2108 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2110 if (revocationFlags
& kSecRevocationCheckIfTrusted
) {
2111 CFDictionaryAddValue(options
, kSecPolicyCheckRevocationIfTrusted
, kCFBooleanTrue
);
2112 /* Set method, but allow caller to override with later checks */
2113 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
2116 if (revocationFlags
& kSecRevocationOnlineCheck
) {
2117 CFDictionaryAddValue(options
, kSecPolicyCheckRevocationOnline
, kCFBooleanTrue
);
2118 /* Set method, but allow caller to override with later checks */
2119 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
2122 if (revocationFlags
& kSecRevocationOCSPMethod
&& revocationFlags
& kSecRevocationCRLMethod
) {
2123 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
2125 else if (revocationFlags
& kSecRevocationOCSPMethod
) {
2126 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationOCSP
);
2128 else if (revocationFlags
& kSecRevocationCRLMethod
) {
2129 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationCRL
);
2132 if (revocationFlags
& kSecRevocationRequirePositiveResponse
) {
2133 CFDictionaryAddValue(options
, kSecPolicyCheckRevocationResponseRequired
, kCFBooleanTrue
);
2136 if (revocationFlags
& kSecRevocationNetworkAccessDisabled
) {
2137 CFDictionaryAddValue(options
, kSecPolicyCheckNoNetworkAccess
, kCFBooleanTrue
);
2139 /* If the caller didn't explicitly disable network access, the revocation policy
2140 * should override any other policy's network setting.
2141 * In particular, pairing a revocation policy with BasicX509 should result in
2142 * allowing network access for revocation unless explicitly disabled.
2143 * Note that SecTrustSetNetworkFetchAllowed can override even this. */
2144 CFDictionaryAddValue(options
, kSecPolicyCheckNoNetworkAccess
, kCFBooleanFalse
);
2147 /* Only flag bits 0-6 are currently defined */
2148 require(((revocationFlags
>> 7) == 0), errOut
);
2150 require(result
= SecPolicyCreate(kSecPolicyAppleRevocation
,
2151 kSecPolicyNameRevocation
, options
), errOut
);
2154 CFReleaseSafe(options
);
2158 SecPolicyRef
SecPolicyCreateSMIME(CFIndex smimeUsage
, CFStringRef email
) {
2159 CFMutableDictionaryRef options
= NULL
;
2160 SecPolicyRef result
= NULL
;
2162 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2163 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2165 if (smimeUsage
& kSecIgnoreExpirationSMIMEUsage
) {
2166 SecPolicyAddBasicCertOptions(options
);
2168 SecPolicyAddBasicX509Options(options
);
2171 /* We call add_ku for each combination of bits we are willing to allow. */
2172 if (smimeUsage
& kSecSignSMIMEUsage
) {
2173 add_ku(options
, kSecKeyUsageUnspecified
);
2174 add_ku(options
, kSecKeyUsageDigitalSignature
);
2175 add_ku(options
, kSecKeyUsageNonRepudiation
);
2177 if (smimeUsage
& kSecKeyEncryptSMIMEUsage
) {
2178 add_ku(options
, kSecKeyUsageKeyEncipherment
);
2180 if (smimeUsage
& kSecDataEncryptSMIMEUsage
) {
2181 add_ku(options
, kSecKeyUsageDataEncipherment
);
2183 if (smimeUsage
& kSecKeyExchangeDecryptSMIMEUsage
) {
2184 add_ku(options
, kSecKeyUsageKeyAgreement
| kSecKeyUsageDecipherOnly
);
2186 if (smimeUsage
& kSecKeyExchangeEncryptSMIMEUsage
) {
2187 add_ku(options
, kSecKeyUsageKeyAgreement
| kSecKeyUsageEncipherOnly
);
2189 if (smimeUsage
& kSecKeyExchangeBothSMIMEUsage
) {
2190 add_ku(options
, kSecKeyUsageKeyAgreement
| kSecKeyUsageEncipherOnly
| kSecKeyUsageDecipherOnly
);
2194 CFDictionaryAddValue(options
, kSecPolicyCheckEmail
, email
);
2197 /* RFC 3850 paragraph 4.4.4
2199 If the extended key usage extension is present in the certificate
2200 then interpersonal message S/MIME receiving agents MUST check that it
2201 contains either the emailProtection or the anyExtendedKeyUsage OID as
2202 defined in [KEYM]. S/MIME uses other than interpersonal messaging
2203 MAY require the explicit presence of the extended key usage extension
2204 or other OIDs to be present in the extension or both.
2206 add_eku(options
, NULL
); /* eku extension is optional */
2207 add_eku(options
, &oidAnyExtendedKeyUsage
);
2208 add_eku(options
, &oidExtendedKeyUsageEmailProtection
);
2210 #if !TARGET_OS_IPHONE
2211 // Check revocation on OS X
2212 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
2215 require(result
= SecPolicyCreate(kSecPolicyAppleSMIME
, kSecPolicyNameSMIME
, options
), errOut
);
2218 CFReleaseSafe(options
);
2222 SecPolicyRef
SecPolicyCreateApplePackageSigning(void) {
2223 CFMutableDictionaryRef options
= NULL
;
2224 SecPolicyRef result
= NULL
;
2226 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2227 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2229 SecPolicyAddBasicCertOptions(options
);
2231 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2232 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNamePackageSigning
), errOut
);
2234 add_ku(options
, kSecKeyUsageDigitalSignature
);
2235 add_eku(options
, &oidExtendedKeyUsageCodeSigning
);
2237 require(result
= SecPolicyCreate(kSecPolicyApplePackageSigning
,
2238 kSecPolicyNamePackageSigning
, options
),
2242 CFReleaseSafe(options
);
2247 SecPolicyRef
SecPolicyCreateAppleSWUpdateSigning(void) {
2248 CFMutableDictionaryRef options
= NULL
;
2249 SecPolicyRef result
= NULL
;
2251 * OS X rules for this policy:
2252 * -- Must have one intermediate cert
2253 * -- intermediate must have basic constraints with path length 0
2254 * -- intermediate has CSSMOID_APPLE_EKU_CODE_SIGNING EKU
2255 * -- leaf cert has either CODE_SIGNING or CODE_SIGN_DEVELOPMENT EKU (the latter of
2256 * which triggers a CSSMERR_APPLETP_CODE_SIGN_DEVELOPMENT error)
2258 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2259 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2261 SecPolicyAddBasicX509Options(options
);
2263 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2264 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameSWUpdateSigning
), errOut
);
2266 add_eku(options
, &oidAppleExtendedKeyUsageCodeSigning
);
2267 add_oid(options
, kSecPolicyCheckIntermediateEKU
, &oidAppleExtendedKeyUsageCodeSigning
);
2269 require(result
= SecPolicyCreate(kSecPolicyAppleSWUpdateSigning
,
2270 kSecPolicyNameSWUpdateSigning
, options
),
2274 CFReleaseSafe(options
);
2279 SecPolicyRef
SecPolicyCreateCodeSigning(void) {
2280 CFMutableDictionaryRef options
= NULL
;
2281 SecPolicyRef result
= NULL
;
2283 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2284 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2286 SecPolicyAddBasicX509Options(options
);
2288 /* If the key usage extension is present, we accept it having either of
2290 add_ku(options
, kSecKeyUsageDigitalSignature
);
2291 add_ku(options
, kSecKeyUsageNonRepudiation
);
2293 /* We require an extended key usage extension with the codesigning
2294 eku purpose. (The Apple codesigning eku is not accepted here
2295 since it's valid only for SecPolicyCreateAppleSWUpdateSigning.) */
2296 add_eku(options
, &oidExtendedKeyUsageCodeSigning
);
2297 #if TARGET_OS_IPHONE
2298 /* Accept the 'any' eku on iOS only to match prior behavior.
2299 This may be further restricted in future releases. */
2300 add_eku(options
, &oidAnyExtendedKeyUsage
);
2303 require(result
= SecPolicyCreate(kSecPolicyAppleCodeSigning
,
2304 kSecPolicyNameCodeSigning
, options
),
2308 CFReleaseSafe(options
);
2312 /* Explicitly leave out empty subject/subjectaltname check */
2313 SecPolicyRef
SecPolicyCreateLockdownPairing(void) {
2314 CFMutableDictionaryRef options
= NULL
;
2315 SecPolicyRef result
= NULL
;
2317 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2318 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2319 //CFDictionaryAddValue(options, kSecPolicyCheckBasicCertificateProcessing,
2320 // kCFBooleanTrue); // Happens automatically in SecPVCPathChecks
2321 CFDictionaryAddValue(options
, kSecPolicyCheckCriticalExtensions
,
2323 CFDictionaryAddValue(options
, kSecPolicyCheckIdLinkage
,
2325 CFDictionaryAddValue(options
, kSecPolicyCheckBasicConstraints
,
2327 CFDictionaryAddValue(options
, kSecPolicyCheckWeakKeySize
, kCFBooleanTrue
);
2329 require(result
= SecPolicyCreate(kSecPolicyAppleLockdownPairing
,
2330 kSecPolicyNameLockdownPairing
, options
), errOut
);
2333 CFReleaseSafe(options
);
2337 SecPolicyRef
SecPolicyCreateURLBag(void) {
2338 CFMutableDictionaryRef options
= NULL
;
2339 SecPolicyRef result
= NULL
;
2341 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2342 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2344 SecPolicyAddBasicCertOptions(options
);
2346 add_eku(options
, &oidExtendedKeyUsageCodeSigning
);
2348 require(result
= SecPolicyCreate(kSecPolicyAppleURLBag
,
2349 kSecPolicyNameURLBag
, options
), errOut
);
2352 CFReleaseSafe(options
);
2356 SecPolicyRef
SecPolicyCreateOTATasking(void)
2358 CFMutableDictionaryRef options
= NULL
;
2359 SecPolicyRef result
= NULL
;
2361 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2362 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2364 SecPolicyAddBasicX509Options(options
);
2367 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameMobileAsset
), errOut
);
2369 /* Chain length of 3 */
2370 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2372 /* Intermediate has common name "Apple iPhone Certification Authority". */
2373 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2374 CFSTR("Apple iPhone Certification Authority"));
2376 /* Leaf has common name "Asset Manifest Signing" */
2377 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
, CFSTR("OTA Task Signing"));
2379 require(result
= SecPolicyCreate(kSecPolicyAppleOTATasking
, kSecPolicyNameOTATasking
, options
),
2383 CFReleaseSafe(options
);
2387 SecPolicyRef
SecPolicyCreateMobileAsset(void)
2389 CFMutableDictionaryRef options
= NULL
;
2390 SecPolicyRef result
= NULL
;
2392 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2393 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2395 /* No expiration check */
2396 SecPolicyAddBasicCertOptions(options
);
2399 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameMobileAsset
), errOut
);
2401 /* Chain length of 3 */
2402 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2404 /* Intermediate has common name "Apple iPhone Certification Authority". */
2405 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2406 CFSTR("Apple iPhone Certification Authority"));
2408 /* Leaf has common name "Asset Manifest Signing" */
2409 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
, CFSTR("Asset Manifest Signing"));
2411 require(result
= SecPolicyCreate(kSecPolicyAppleMobileAsset
, kSecPolicyNameMobileAsset
, options
),
2415 CFReleaseSafe(options
);
2419 SecPolicyRef
SecPolicyCreateMobileAssetDevelopment(void) {
2420 CFMutableDictionaryRef options
= NULL
;
2421 SecPolicyRef result
= NULL
;
2423 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2424 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2426 /* No expiration check */
2427 SecPolicyAddBasicCertOptions(options
);
2430 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameMobileAsset
), errOut
);
2432 /* Chain length of 3 */
2433 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2435 /* Intermediate has the iPhone CA Marker extension */
2436 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.18"));
2438 /* Leaf has ProdQA Mobile Asset Marker extension */
2439 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.55.1"));
2441 require(result
= SecPolicyCreate(kSecPolicyAppleMobileAssetDevelopment
, kSecPolicyNameMobileAsset
, options
),
2445 CFReleaseSafe(options
);
2449 SecPolicyRef
SecPolicyCreateAppleIDAuthorityPolicy(void)
2451 SecPolicyRef result
= NULL
;
2452 CFMutableDictionaryRef options
= NULL
;
2453 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2454 &kCFTypeDictionaryKeyCallBacks
,
2455 &kCFTypeDictionaryValueCallBacks
), out
);
2457 //Leaf appears to be a SSL only cert, so policy should expand on that policy
2458 SecPolicyAddBasicX509Options(options
);
2460 // Apple CA anchored
2461 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameIDAuthority
), out
);
2463 // with the addition of the existence check of an extension with "Apple ID Sharing Certificate" oid (1.2.840.113635.100.4.7)
2464 // NOTE: this obviously intended to have gone into Extended Key Usage, but evidence of existing certs proves the contrary.
2465 add_leaf_marker(options
, &oidAppleExtendedKeyUsageAppleID
);
2467 // and validate that intermediate has extension with CSSMOID_APPLE_EXTENSION_AAI_INTERMEDIATE oid (1.2.840.113635.100.6.2.3) and goes back to the Apple Root CA.
2468 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleID
);
2469 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleID2
);
2471 require(result
= SecPolicyCreate(kSecPolicyAppleIDAuthority
,
2472 kSecPolicyNameIDAuthority
, options
), out
);
2475 CFReleaseSafe(options
);
2479 SecPolicyRef
SecPolicyCreateMacAppStoreReceipt(void)
2481 SecPolicyRef result
= NULL
;
2482 CFMutableDictionaryRef options
= NULL
;
2483 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2484 &kCFTypeDictionaryKeyCallBacks
,
2485 &kCFTypeDictionaryValueCallBacks
), out
);
2487 SecPolicyAddBasicX509Options(options
);
2489 // Apple CA anchored
2490 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameMacAppStoreReceipt
), out
);
2492 // Chain length of 3
2493 require(SecPolicyAddChainLengthOptions(options
, 3), out
);
2495 // MacAppStoreReceipt policy OID
2496 add_certificate_policy_oid_string(options
, CFSTR("1.2.840.113635.100.5.6.1"));
2498 // Intermediate marker OID
2499 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.1"));
2502 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.11.1"));
2505 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
2507 require(result
= SecPolicyCreate(kSecPolicyMacAppStoreReceipt
,
2508 kSecPolicyNameMacAppStoreReceipt
, options
), out
);
2511 CFReleaseSafe(options
);
2516 static SecPolicyRef
_SecPolicyCreatePassbookCardSigner(CFStringRef cardIssuer
, CFStringRef teamIdentifier
, bool requireTeamID
)
2518 SecPolicyRef result
= NULL
;
2519 CFMutableDictionaryRef options
= NULL
;
2520 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2521 &kCFTypeDictionaryKeyCallBacks
,
2522 &kCFTypeDictionaryValueCallBacks
), out
);
2524 SecPolicyAddBasicX509Options(options
);
2525 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNamePassbookSigning
), out
);
2527 // Chain length of 3
2528 require(SecPolicyAddChainLengthOptions(options
, 3), out
);
2530 if (teamIdentifier
) {
2531 // If supplied, teamIdentifier must match subject OU field
2532 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectOrganizationalUnit
, teamIdentifier
);
2535 // If not supplied, and it was required, fail
2536 require(!requireTeamID
, out
);
2539 // Must be both push and 3rd party package signing
2540 add_leaf_marker_value(options
, &oidAppleInstallerPackagingSigningExternal
, cardIssuer
);
2542 // We should check that it also has push marker, but we don't support requiring both, only either.
2543 // add_independent_oid(options, kSecPolicyCheckLeafMarkerOid, &oidApplePushServiceClient);
2545 //WWDR Intermediate marker OID
2546 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.1"));
2548 // And Passbook signing eku
2549 add_eku(options
, &oidAppleExtendedKeyUsagePassbook
);
2551 require(result
= SecPolicyCreate(kSecPolicyApplePassbookSigning
,
2552 kSecPolicyNamePassbookSigning
, options
), out
);
2555 CFReleaseSafe(options
);
2559 SecPolicyRef
SecPolicyCreatePassbookCardSigner(CFStringRef cardIssuer
, CFStringRef teamIdentifier
)
2561 return _SecPolicyCreatePassbookCardSigner(cardIssuer
, teamIdentifier
, true);
2565 static SecPolicyRef
CreateMobileStoreSigner(Boolean forTest
)
2568 SecPolicyRef result
= NULL
;
2569 CFMutableDictionaryRef options
= NULL
;
2570 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2571 &kCFTypeDictionaryKeyCallBacks
,
2572 &kCFTypeDictionaryValueCallBacks
), errOut
);
2573 SecPolicyAddBasicX509Options(options
);
2574 require(SecPolicyAddAppleAnchorOptions(options
,
2575 ((forTest
) ? kSecPolicyNameTestMobileStore
:
2576 kSecPolicyNameMobileStore
)), errOut
);
2578 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2580 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2581 CFSTR("Apple System Integration 2 Certification Authority"));
2583 add_ku(options
, kSecKeyUsageDigitalSignature
);
2585 const DERItem
* pOID
= (forTest
) ? &oidApplePolicyMobileStoreProdQA
: &oidApplePolicyMobileStore
;
2587 add_certificate_policy_oid(options
, pOID
);
2589 require(result
= SecPolicyCreate((forTest
) ? kSecPolicyAppleTestMobileStore
: kSecPolicyAppleMobileStore
,
2590 (forTest
) ? kSecPolicyNameTestMobileStore
: kSecPolicyNameMobileStore
,
2594 CFReleaseSafe(options
);
2598 SecPolicyRef
SecPolicyCreateMobileStoreSigner(void)
2600 return CreateMobileStoreSigner(false);
2603 SecPolicyRef
SecPolicyCreateTestMobileStoreSigner(void)
2605 return CreateMobileStoreSigner(true);
2609 CF_RETURNS_RETAINED SecPolicyRef
SecPolicyCreateEscrowServiceSigner(void)
2611 SecPolicyRef result
= NULL
;
2612 CFMutableDictionaryRef options
= NULL
;
2613 CFArrayRef anArray
= NULL
;
2614 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2615 &kCFTypeDictionaryKeyCallBacks
,
2616 &kCFTypeDictionaryValueCallBacks
), errOut
);
2618 // X509, ignoring date validity
2619 SecPolicyAddBasicCertOptions(options
);
2621 add_ku(options
, kSecKeyUsageKeyEncipherment
);
2623 /* Leaf has marker OID with value that can't be pre-determined */
2624 add_element(options
, kSecPolicyCheckLeafMarkerOidWithoutValueCheck
, CFSTR("1.2.840.113635.100.6.23.1"));
2625 require(SecPolicyAddChainLengthOptions(options
, 2), errOut
);
2627 Boolean anchorAdded
= false;
2628 // Get the roots by calling the SecCertificateCopyEscrowRoots
2629 anArray
= SecCertificateCopyEscrowRoots(kSecCertificateProductionEscrowRoot
);
2630 CFIndex numRoots
= 0;
2631 if (NULL
== anArray
|| 0 == (numRoots
= CFArrayGetCount(anArray
))) {
2635 for (CFIndex iCnt
= 0; iCnt
< numRoots
; iCnt
++) {
2636 SecCertificateRef aCert
= (SecCertificateRef
)CFArrayGetValueAtIndex(anArray
, iCnt
);
2638 if (NULL
!= aCert
) {
2639 CFDataRef sha_data
= SecCertificateGetSHA1Digest(aCert
);
2640 if (NULL
!= sha_data
) {
2641 const UInt8
* pSHAData
= CFDataGetBytePtr(sha_data
);
2642 if (NULL
!= pSHAData
) {
2643 SecPolicyAddAnchorSHA1Options(options
, pSHAData
);
2649 CFReleaseNull(anArray
);
2655 require(result
= SecPolicyCreate(kSecPolicyAppleEscrowService
,
2656 kSecPolicyNameEscrowService
, options
), errOut
);
2659 CFReleaseSafe(anArray
);
2660 CFReleaseSafe(options
);
2664 CF_RETURNS_RETAINED SecPolicyRef
SecPolicyCreatePCSEscrowServiceSigner(void)
2666 SecPolicyRef result
= NULL
;
2667 CFMutableDictionaryRef options
= NULL
;
2668 CFArrayRef anArray
= NULL
;
2669 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2670 &kCFTypeDictionaryKeyCallBacks
,
2671 &kCFTypeDictionaryValueCallBacks
), errOut
);
2673 SecPolicyAddBasicX509Options(options
);
2674 add_ku(options
, kSecKeyUsageKeyEncipherment
);
2676 /* Leaf has marker OID with value that can't be pre-determined */
2677 add_element(options
, kSecPolicyCheckLeafMarkerOidWithoutValueCheck
, CFSTR("1.2.840.113635.100.6.23.1"));
2678 require(SecPolicyAddChainLengthOptions(options
, 2), errOut
);
2680 Boolean anchorAdded
= false;
2681 anArray
= SecCertificateCopyEscrowRoots(kSecCertificateProductionPCSEscrowRoot
);
2682 CFIndex numRoots
= 0;
2683 if (NULL
== anArray
|| 0 == (numRoots
= CFArrayGetCount(anArray
))) {
2687 for (CFIndex iCnt
= 0; iCnt
< numRoots
; iCnt
++) {
2688 SecCertificateRef aCert
= (SecCertificateRef
)CFArrayGetValueAtIndex(anArray
, iCnt
);
2690 if (NULL
!= aCert
) {
2691 CFDataRef sha_data
= SecCertificateGetSHA1Digest(aCert
);
2692 if (NULL
!= sha_data
) {
2693 const UInt8
* pSHAData
= CFDataGetBytePtr(sha_data
);
2694 if (NULL
!= pSHAData
) {
2695 SecPolicyAddAnchorSHA1Options(options
, pSHAData
);
2701 CFReleaseNull(anArray
);
2707 require(result
= SecPolicyCreate(kSecPolicyApplePCSEscrowService
,
2708 kSecPolicyNamePCSEscrowService
, options
), errOut
);
2711 CFReleaseSafe(anArray
);
2712 CFReleaseSafe(options
);
2716 static SecPolicyRef
CreateConfigurationProfileSigner(bool forTest
) {
2717 SecPolicyRef result
= NULL
;
2718 CFMutableDictionaryRef options
= NULL
;
2719 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2720 &kCFTypeDictionaryKeyCallBacks
,
2721 &kCFTypeDictionaryValueCallBacks
), errOut
);
2723 SecPolicyAddBasicX509Options(options
);
2724 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameProfileSigner
), errOut
);
2727 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2729 // Require the profile signing EKU
2730 const DERItem
* pOID
= (forTest
) ? &oidAppleExtendedKeyUsageQAProfileSigning
:&oidAppleExtendedKeyUsageProfileSigning
;
2731 add_eku(options
, pOID
);
2733 // Require the Apple Application Integration CA marker OID
2734 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.3"));
2736 require(result
= SecPolicyCreate((forTest
) ? kSecPolicyAppleQAProfileSigner
: kSecPolicyAppleProfileSigner
,
2737 (forTest
) ? kSecPolicyNameQAProfileSigner
: kSecPolicyNameProfileSigner
,
2741 CFReleaseSafe(options
);
2745 SecPolicyRef
SecPolicyCreateConfigurationProfileSigner(void)
2747 return CreateConfigurationProfileSigner(false);
2751 SecPolicyRef
SecPolicyCreateQAConfigurationProfileSigner(void)
2753 if (SecIsInternalRelease()) {
2754 return CreateConfigurationProfileSigner(true);
2756 return CreateConfigurationProfileSigner(false);
2760 SecPolicyRef
SecPolicyCreateOSXProvisioningProfileSigning(void)
2762 SecPolicyRef result
= NULL
;
2763 CFMutableDictionaryRef options
= NULL
;
2764 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2765 &kCFTypeDictionaryKeyCallBacks
,
2766 &kCFTypeDictionaryValueCallBacks
), errOut
);
2767 // Require valid chain from the Apple root
2768 SecPolicyAddBasicX509Options(options
);
2769 SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameOSXProvisioningProfileSigning
);
2771 // Require provisioning profile leaf marker OID (1.2.840.113635.100.4.11)
2772 add_leaf_marker(options
, &oidAppleCertExtOSXProvisioningProfileSigning
);
2774 // Require intermediate marker OID (1.2.840.113635.100.6.2.1)
2775 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleWWDR
);
2777 // Require key usage that allows signing
2778 add_ku(options
, kSecKeyUsageDigitalSignature
);
2780 // Ensure that revocation is checked (OCSP)
2781 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationOCSP
);
2783 require(result
= SecPolicyCreate(kSecPolicyAppleOSXProvisioningProfileSigning
,
2784 kSecPolicyNameOSXProvisioningProfileSigning
, options
), errOut
);
2787 CFReleaseSafe(options
);
2792 SecPolicyRef
SecPolicyCreateOTAPKISigner(void)
2794 SecPolicyRef result
= NULL
;
2795 CFMutableDictionaryRef options
= NULL
;
2796 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2797 &kCFTypeDictionaryKeyCallBacks
,
2798 &kCFTypeDictionaryValueCallBacks
), errOut
);
2799 SecPolicyAddBasicX509Options(options
);
2801 SecPolicyAddAnchorSHA1Options(options
, kApplePKISettingsAuthority
);
2802 require(SecPolicyAddChainLengthOptions(options
, 2), errOut
);
2804 require(result
= SecPolicyCreate(kSecPolicyAppleOTAPKISigner
,
2805 kSecPolicyNameOTAPKISigner
, options
), errOut
);
2808 CFReleaseSafe(options
);
2814 SecPolicyRef
SecPolicyCreateTestOTAPKISigner(void)
2816 /* Guard against use on production devices */
2817 if (!SecIsInternalRelease()) {
2818 return SecPolicyCreateOTAPKISigner();
2821 SecPolicyRef result
= NULL
;
2822 CFMutableDictionaryRef options
= NULL
;
2823 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2824 &kCFTypeDictionaryKeyCallBacks
,
2825 &kCFTypeDictionaryValueCallBacks
), errOut
);
2826 SecPolicyAddBasicX509Options(options
);
2828 SecPolicyAddAnchorSHA1Options(options
, kAppleTestPKISettingsAuthority
);
2829 require(SecPolicyAddChainLengthOptions(options
, 2), errOut
);
2831 require(result
= SecPolicyCreate(kSecPolicyAppleTestOTAPKISigner
,
2832 kSecPolicyNameTestOTAPKISigner
, options
), errOut
);
2835 CFReleaseSafe(options
);
2840 @function SecPolicyCreateAppleSMPEncryption
2841 @abstract Check for intermediate certificate 'Apple System Integration CA - G3' by name,
2842 and root certificate 'Apple Root CA - G3' by hash.
2843 Leaf cert must have Key Encipherment usage.
2844 Leaf cert must have Apple SMP Encryption marker OID (1.2.840.113635.100.6.30).
2845 Intermediate must have marker OID (1.2.840.113635.100.6.2.13).
2847 SecPolicyRef
SecPolicyCreateAppleSMPEncryption(void)
2849 SecPolicyRef result
= NULL
;
2850 CFMutableDictionaryRef options
= NULL
;
2851 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2852 &kCFTypeDictionaryKeyCallBacks
,
2853 &kCFTypeDictionaryValueCallBacks
), errOut
);
2854 SecPolicyAddBasicCertOptions(options
);
2856 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameSMPEncryption
),
2858 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2860 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2861 CFSTR("Apple System Integration CA - G3"));
2863 // Check that leaf has extension with "Apple SMP Encryption" oid (1.2.840.113635.100.6.30)
2864 add_leaf_marker(options
, &oidAppleCertExtAppleSMPEncryption
);
2866 // Check that intermediate has extension (1.2.840.113635.100.6.2.13)
2867 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleSystemIntgG3
);
2869 add_ku(options
, kSecKeyUsageKeyEncipherment
);
2871 // Ensure that revocation is checked (OCSP)
2872 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationOCSP
);
2874 require(result
= SecPolicyCreate(kSecPolicyAppleSMPEncryption
,
2875 kSecPolicyNameSMPEncryption
, options
), errOut
);
2878 CFReleaseSafe(options
);
2883 @function SecPolicyCreateTestAppleSMPEncryption
2884 @abstract Check for intermediate certificate 'Test Apple System Integration CA - ECC' by name,
2885 and root certificate 'Test Apple Root CA - ECC' by hash.
2886 Leaf cert must have Key Encipherment usage. Other checks TBD.
2888 SecPolicyRef
SecPolicyCreateTestAppleSMPEncryption(void)
2890 SecPolicyRef result
= NULL
;
2891 CFMutableDictionaryRef options
= NULL
;
2892 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2893 &kCFTypeDictionaryKeyCallBacks
,
2894 &kCFTypeDictionaryValueCallBacks
), errOut
);
2895 SecPolicyAddBasicCertOptions(options
);
2897 SecPolicyAddAnchorSHA1Options(options
, kTestAppleRootCA_ECC_SHA1
);
2898 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2900 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2901 CFSTR("Test Apple System Integration CA - ECC"));
2903 add_ku(options
, kSecKeyUsageKeyEncipherment
);
2905 // Ensure that revocation is checked (OCSP)
2906 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationOCSP
);
2908 require(result
= SecPolicyCreate(kSecPolicyAppleTestSMPEncryption
,
2909 kSecPolicyNameTestSMPEncryption
, options
), errOut
);
2912 CFReleaseSafe(options
);
2917 SecPolicyRef
SecPolicyCreateAppleIDValidationRecordSigningPolicy(void)
2919 SecPolicyRef result
= NULL
;
2920 CFMutableDictionaryRef options
= NULL
;
2921 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2922 &kCFTypeDictionaryKeyCallBacks
,
2923 &kCFTypeDictionaryValueCallBacks
), errOut
);
2925 //Leaf appears to be a SSL only cert, so policy should expand on that policy
2926 SecPolicyAddBasicX509Options(options
);
2928 // Apple CA anchored
2929 require(SecPolicyAddAppleAnchorOptions(options
,
2930 kSecPolicyNameIDValidationRecordSigning
),
2933 // Check for an extension with " Apple ID Validation Record Signing" oid (1.2.840.113635.100.6.25)
2934 add_leaf_marker(options
, &oidAppleCertExtensionAppleIDRecordValidationSigning
);
2936 // and validate that intermediate has extension
2937 // Application Integration Intermediate Certificate (1.2.840.113635.100.6.2.3)
2938 // and also validate that intermediate has extension
2939 // System Integration 2 Intermediate Certificate (1.2.840.113635.100.6.2.10)
2940 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleID
);
2941 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleSystemIntg2
);
2943 // Ensure that revocation is checked (OCSP)
2944 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationOCSP
);
2946 require(result
= SecPolicyCreate(kSecPolicyAppleIDValidationRecordSigning
,
2947 kSecPolicyNameIDValidationRecordSigning
, options
), errOut
);
2950 CFReleaseSafe(options
);
2955 @function SecPolicyCreateAppleServerAuthCommon
2956 @abstract Generic policy for server authentication Sub CAs
2958 Allows control for both if pinning is required at all and if UAT environments should be added
2959 to the trust policy.
2961 No pinning is for developer/QA that needs to use proxy to debug the protocol, while UAT
2962 environment is for QA/internal developer that have no need allow fake servers.
2964 Both the noPinning and UAT are gated on that you run on internal hardware.
2969 SecPolicyCreateAppleServerAuthCommon(CFStringRef hostname
,
2970 CFDictionaryRef __unused context
,
2971 CFStringRef policyOID
, CFStringRef service
,
2972 const DERItem
*leafMarkerOID
,
2973 const DERItem
*UATLeafMarkerOID
)
2975 CFMutableDictionaryRef appleAnchorOptions
= NULL
;
2976 CFMutableDictionaryRef options
= NULL
;
2977 SecPolicyRef result
= NULL
;
2978 CFDataRef oid
= NULL
, uatoid
= NULL
;
2980 options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0, &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
2981 require(options
, errOut
);
2983 SecPolicyAddBasicX509Options(options
);
2985 require(hostname
, errOut
);
2986 CFDictionaryAddValue(options
, kSecPolicyCheckSSLHostname
, hostname
);
2988 CFDictionaryAddValue(options
, kSecPolicyCheckBlackListedLeaf
, kCFBooleanTrue
);
2989 CFDictionaryAddValue(options
, kSecPolicyCheckGrayListedLeaf
, kCFBooleanTrue
);
2991 add_eku(options
, &oidExtendedKeyUsageServerAuth
);
2993 if (requireUATPinning(service
)) {
2996 * Require pinning to the Apple CA's.
2998 SecPolicyAddAppleAnchorOptions(options
, service
);
3000 /* old-style leaf marker OIDs */
3001 if (UATLeafMarkerOID
) {
3002 add_leaf_prod_qa_markers(options
, leafMarkerOID
, UATLeafMarkerOID
);
3004 add_leaf_marker(options
, leafMarkerOID
);
3007 /* new-style leaf marker OIDs */
3008 CFStringRef leafMarkerOIDStr
= NULL
, UATLeafMarkerOIDStr
= NULL
;
3009 leafMarkerOIDStr
= SecDERItemCopyOIDDecimalRepresentation(NULL
, leafMarkerOID
);
3010 if (UATLeafMarkerOID
) {
3011 UATLeafMarkerOIDStr
= SecDERItemCopyOIDDecimalRepresentation(NULL
, UATLeafMarkerOID
);
3014 if (leafMarkerOIDStr
&& UATLeafMarkerOIDStr
) {
3015 add_leaf_prod_qa_markers_value_string(options
,
3016 CFSTR("1.2.840.113635.100.6.48.1"), leafMarkerOIDStr
,
3017 CFSTR("1.2.840.113635.100.6.48.1"), UATLeafMarkerOIDStr
);
3018 } else if (leafMarkerOIDStr
) {
3019 add_leaf_marker_value_string(options
, CFSTR("1.2.840.113635.100.6.48.1"), leafMarkerOIDStr
);
3022 CFReleaseNull(leafMarkerOIDStr
);
3023 CFReleaseNull(UATLeafMarkerOIDStr
);
3025 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleServerAuthentication
);
3028 /* Check for weak hashes and keys */
3029 require(SecPolicyRemoveWeakHashOptions(options
), errOut
);
3030 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
3032 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
3034 result
= SecPolicyCreate(policyOID
, service
, options
);
3035 require(result
, errOut
);
3038 CFReleaseSafe(appleAnchorOptions
);
3039 CFReleaseSafe(options
);
3041 CFReleaseSafe(uatoid
);
3046 @function SecPolicyCreateAppleIDSService
3047 @abstract Ensure we're appropriately pinned to the IDS service (SSL + Apple restrictions)
3049 SecPolicyRef
SecPolicyCreateAppleIDSService(CFStringRef hostname
)
3051 SecPolicyRef result
= SecPolicyCreateSSL(true, hostname
);
3053 SecPolicySetOid(result
, kSecPolicyAppleIDSService
);
3054 SecPolicySetName(result
, kSecPolicyNameAppleIDSBag
);
3060 @function SecPolicyCreateAppleIDSService
3061 @abstract Ensure we're appropriately pinned to the IDS service (SSL + Apple restrictions)
3063 SecPolicyRef
SecPolicyCreateAppleIDSServiceContext(CFStringRef hostname
, CFDictionaryRef context
)
3065 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyAppleIDSServiceContext
,
3066 kSecPolicyNameAppleIDSService
,
3067 &oidAppleCertExtAppleServerAuthenticationIDSProd
,
3068 &oidAppleCertExtAppleServerAuthenticationIDSProdQA
);
3072 @function SecPolicyCreateAppleGSService
3073 @abstract Ensure we're appropriately pinned to the GS service
3075 SecPolicyRef
SecPolicyCreateAppleGSService(CFStringRef hostname
, CFDictionaryRef context
)
3077 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyAppleGSService
,
3078 kSecPolicyNameAppleGSService
,
3079 &oidAppleCertExtAppleServerAuthenticationGS
,
3084 @function SecPolicyCreateApplePushService
3085 @abstract Ensure we're appropriately pinned to the Push service (SSL + Apple restrictions)
3087 SecPolicyRef
SecPolicyCreateApplePushService(CFStringRef hostname
, CFDictionaryRef context
)
3089 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyApplePushService
,
3090 kSecPolicyNameApplePushService
,
3091 &oidAppleCertExtAppleServerAuthenticationAPNProd
,
3092 &oidAppleCertExtAppleServerAuthenticationAPNProdQA
);
3096 @function SecPolicyCreateApplePPQService
3097 @abstract Ensure we're appropriately pinned to the PPQ service (SSL + Apple restrictions)
3099 SecPolicyRef
SecPolicyCreateApplePPQService(CFStringRef hostname
, CFDictionaryRef context
)
3101 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyApplePPQService
,
3102 kSecPolicyNameApplePPQService
,
3103 &oidAppleCertExtAppleServerAuthenticationPPQProd
,
3104 &oidAppleCertExtAppleServerAuthenticationPPQProdQA
);
3108 @function SecPolicyCreateAppleAST2Service
3109 @abstract Ensure we're appropriately pinned to the AST2 Diagnostic service (SSL + Apple restrictions)
3111 SecPolicyRef
SecPolicyCreateAppleAST2Service(CFStringRef hostname
, CFDictionaryRef context
)
3113 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyAppleAST2DiagnosticsServerAuth
,
3114 kSecPolicyNameAppleAST2Service
,
3115 &oidAppleCertExtAST2DiagnosticsServerAuthProd
,
3116 &oidAppleCertExtAST2DiagnosticsServerAuthProdQA
);
3120 @function SecPolicyCreateAppleEscrowProxyService
3121 @abstract Ensure we're appropriately pinned to the iCloud Escrow Proxy service (SSL + Apple restrictions)
3123 SecPolicyRef
SecPolicyCreateAppleEscrowProxyService(CFStringRef hostname
, CFDictionaryRef context
)
3125 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyAppleEscrowProxyServerAuth
,
3126 kSecPolicyNameAppleEscrowProxyService
,
3127 &oidAppleCertExtEscrowProxyServerAuthProd
,
3128 &oidAppleCertExtEscrowProxyServerAuthProdQA
);
3131 /* subject:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA */
3132 /* SKID: C0:7A:98:68:8D:89:FB:AB:05:64:0C:11:7D:AA:7D:65:B8:CA:CC:4E */
3133 /* Not Before: May 21 04:00:00 2002 GMT, Not After : May 21 04:00:00 2022 GMT */
3134 /* Signature Algorithm: sha1WithRSAEncryption */
3135 unsigned char GeoTrust_Global_CA_sha256
[kSecPolicySHA256Size
] = {
3136 0xff, 0x85, 0x6a, 0x2d, 0x25, 0x1d, 0xcd, 0x88, 0xd3, 0x66, 0x56, 0xf4, 0x50, 0x12, 0x67, 0x98,
3137 0xcf, 0xab, 0xaa, 0xde, 0x40, 0x79, 0x9c, 0x72, 0x2d, 0xe4, 0xd2, 0xb5, 0xdb, 0x36, 0xa7, 0x3a
3140 static SecPolicyRef
SecPolicyCreateAppleGeoTrustServerAuthCommon(CFStringRef hostname
, CFStringRef policyOid
,
3141 CFStringRef policyName
,
3142 CFStringRef leafMarkerOid
,
3143 CFStringRef qaLeafMarkerOid
) {
3144 CFMutableDictionaryRef options
= NULL
;
3145 CFDataRef spkiDigest
= NULL
;
3146 SecPolicyRef result
= NULL
;
3148 require(options
= CFDictionaryCreateMutable(NULL
, 0, &kCFTypeDictionaryKeyCallBacks
,
3149 &kCFTypeDictionaryValueCallBacks
), errOut
);
3152 SecPolicyAddBasicX509Options(options
);
3154 require(hostname
, errOut
);
3155 CFDictionaryAddValue(options
, kSecPolicyCheckSSLHostname
, hostname
);
3157 add_eku(options
, &oidExtendedKeyUsageServerAuth
);
3160 if (requireUATPinning(policyName
)) {
3162 SecPolicyAddAnchorSHA256Options(options
, GeoTrust_Global_CA_sha256
);
3164 /* Issued to Apple Inc. in the US */
3165 add_element(options
, kSecPolicyCheckIntermediateCountry
, CFSTR("US"));
3166 add_element(options
, kSecPolicyCheckIntermediateOrganization
, CFSTR("Apple Inc."));
3168 require_action(SecPolicyAddChainLengthOptions(options
, 3), errOut
, CFReleaseNull(result
));
3170 /* Marker OIDs in both formats */
3171 if (qaLeafMarkerOid
) {
3172 add_leaf_prod_qa_markers_string(options
, leafMarkerOid
, qaLeafMarkerOid
);
3173 add_leaf_prod_qa_markers_value_string(options
,
3174 CFSTR("1.2.840.113635.100.6.48.1"), leafMarkerOid
,
3175 CFSTR("1.2.840.113635.100.6.48.1"), qaLeafMarkerOid
);
3177 add_leaf_marker_string(options
, leafMarkerOid
);
3178 add_leaf_marker_value_string(options
, CFSTR("1.2.840.113635.100.6.48.1"), leafMarkerOid
);
3182 /* Check for weak hashes */
3183 require(SecPolicyRemoveWeakHashOptions(options
), errOut
);
3184 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
3186 /* See <rdar://25344801> for more details */
3188 result
= SecPolicyCreate(policyOid
, policyName
, options
);
3191 CFReleaseSafe(options
);
3192 CFReleaseSafe(spkiDigest
);
3196 SecPolicyRef
SecPolicyCreateAppleCompatibilityEscrowProxyService(CFStringRef hostname
) {
3197 return SecPolicyCreateAppleGeoTrustServerAuthCommon(hostname
, kSecPolicyAppleEscrowProxyCompatibilityServerAuth
,
3198 kSecPolicyNameAppleEscrowProxyService
,
3199 CFSTR("1.2.840.113635.100.6.27.7.2"),
3200 CFSTR("1.2.840.113635.100.6.27.7.1"));
3204 @function SecPolicyCreateAppleFMiPService
3205 @abstract Ensure we're appropriately pinned to the Find My iPhone service (SSL + Apple restrictions)
3207 SecPolicyRef
SecPolicyCreateAppleFMiPService(CFStringRef hostname
, CFDictionaryRef context
)
3209 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyAppleFMiPServerAuth
,
3210 kSecPolicyNameAppleFMiPService
,
3211 &oidAppleCertExtFMiPServerAuthProd
,
3212 &oidAppleCertExtFMiPServerAuthProdQA
);
3216 /* should use verbatim copy, but since this is the deprecated way, don't care right now */
3217 static const UInt8 entrustSPKIL1C
[kSecPolicySHA256Size
] = {
3218 0x54, 0x5b, 0xf9, 0x35, 0xe9, 0xad, 0xa1, 0xda,
3219 0x11, 0x7e, 0xdc, 0x3c, 0x2a, 0xcb, 0xc5, 0x6f,
3220 0xc0, 0x28, 0x09, 0x6c, 0x0e, 0x24, 0xbe, 0x9b,
3221 0x38, 0x94, 0xbe, 0x52, 0x2d, 0x1b, 0x43, 0xde
3225 @function SecPolicyCreateApplePushServiceLegacy
3226 @abstract Ensure we're appropriately pinned to the Push service (via Entrust)
3228 SecPolicyRef
SecPolicyCreateApplePushServiceLegacy(CFStringRef hostname
)
3230 CFMutableDictionaryRef options
= NULL
;
3231 SecPolicyRef result
= NULL
;
3232 CFDataRef digest
= NULL
;
3234 digest
= CFDataCreateWithBytesNoCopy(kCFAllocatorDefault
, entrustSPKIL1C
, sizeof(entrustSPKIL1C
), kCFAllocatorNull
);
3235 require(digest
, errOut
);
3237 options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0, &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
3238 require(options
, errOut
);
3240 SecPolicyAddBasicX509Options(options
);
3242 CFDictionaryAddValue(options
, kSecPolicyCheckSSLHostname
, hostname
);
3244 CFDictionaryAddValue(options
, kSecPolicyCheckBlackListedLeaf
, kCFBooleanTrue
);
3245 CFDictionaryAddValue(options
, kSecPolicyCheckGrayListedLeaf
, kCFBooleanTrue
);
3247 CFDictionaryAddValue(options
, kSecPolicyCheckIntermediateSPKISHA256
, digest
);
3249 add_eku(options
, &oidExtendedKeyUsageServerAuth
);
3251 /* Check for weak hashes and keys */
3252 require(SecPolicyRemoveWeakHashOptions(options
), errOut
);
3253 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
3255 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
3257 result
= SecPolicyCreate(kSecPolicyAppleLegacyPushService
,
3258 kSecPolicyNameLegacyPushService
, options
);
3259 require(result
, errOut
);
3262 CFReleaseSafe(digest
);
3263 CFReleaseSafe(options
);
3268 @function SecPolicyCreateAppleMMCSService
3269 @abstract Ensure we're appropriately pinned to the IDS service (SSL + Apple restrictions)
3271 SecPolicyRef
SecPolicyCreateAppleMMCSService(CFStringRef hostname
, CFDictionaryRef context
)
3273 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyAppleMMCService
,
3274 kSecPolicyNameAppleMMCSService
,
3275 &oidAppleCertExtAppleServerAuthenticationMMCSProd
,
3276 &oidAppleCertExtAppleServerAuthenticationMMCSProdQA
);
3279 SecPolicyRef
SecPolicyCreateAppleCompatibilityMMCSService(CFStringRef hostname
) {
3280 return SecPolicyCreateAppleGeoTrustServerAuthCommon(hostname
, kSecPolicyAppleMMCSCompatibilityServerAuth
,
3281 kSecPolicyNameAppleMMCSService
,
3282 CFSTR("1.2.840.113635.100.6.27.11.2"),
3283 CFSTR("1.2.840.113635.100.6.27.11.1"));
3287 SecPolicyRef
SecPolicyCreateAppleiCloudSetupService(CFStringRef hostname
, CFDictionaryRef context
)
3289 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyAppleiCloudSetupServerAuth
,
3290 kSecPolicyNameAppleiCloudSetupService
,
3291 &oidAppleCertExtAppleServerAuthenticationiCloudSetupProd
,
3292 &oidAppleCertExtAppleServerAuthenticationiCloudSetupProdQA
);
3295 SecPolicyRef
SecPolicyCreateAppleCompatibilityiCloudSetupService(CFStringRef hostname
)
3297 return SecPolicyCreateAppleGeoTrustServerAuthCommon(hostname
, kSecPolicyAppleiCloudSetupCompatibilityServerAuth
,
3298 kSecPolicyNameAppleiCloudSetupService
,
3299 CFSTR("1.2.840.113635.100.6.27.15.2"),
3300 CFSTR("1.2.840.113635.100.6.27.15.1"));
3304 @function SecPolicyCreateAppleSSLService
3305 @abstract Ensure we're appropriately pinned to an Apple server (SSL + Apple restrictions)
3307 SecPolicyRef
SecPolicyCreateAppleSSLService(CFStringRef hostname
)
3309 // SSL server, pinned to an Apple intermediate
3310 SecPolicyRef policy
= SecPolicyCreateSSL(true, hostname
);
3311 CFMutableDictionaryRef options
= NULL
;
3312 require(policy
, errOut
);
3314 // change options for SSL policy evaluation
3315 require((options
=(CFMutableDictionaryRef
)policy
->_options
) != NULL
, errOut
);
3317 // Apple CA anchored
3318 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameServerAuthentication
), errOut
);
3320 // Check leaf for Apple Server Authentication marker oid (1.2.840.113635.100.6.27.1)
3321 add_leaf_marker(options
, &oidAppleCertExtAppleServerAuthentication
);
3323 // Check intermediate for Apple Server Authentication intermediate marker (1.2.840.113635.100.6.2.12)
3324 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleServerAuthentication
);
3326 /* Check for weak hashes */
3327 require(SecPolicyRemoveWeakHashOptions(options
), errOut
);
3329 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
3331 SecPolicySetOid(policy
, kSecPolicyAppleServerAuthentication
);
3332 SecPolicySetName(policy
, kSecPolicyNameServerAuthentication
);
3337 CFReleaseSafe(options
);
3338 CFReleaseSafe(policy
);
3343 @function SecPolicyCreateApplePPQSigning
3344 @abstract Check for intermediate certificate 'Apple System Integration 2 Certification Authority' by name,
3346 Leaf cert must have Digital Signature usage.
3347 Leaf cert must have Apple PPQ Signing marker OID (1.2.840.113635.100.6.38.2).
3348 Intermediate must have marker OID (1.2.840.113635.100.6.2.10).
3350 SecPolicyRef
SecPolicyCreateApplePPQSigning(void)
3352 SecPolicyRef result
= NULL
;
3353 CFMutableDictionaryRef options
= NULL
;
3354 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3355 &kCFTypeDictionaryKeyCallBacks
,
3356 &kCFTypeDictionaryValueCallBacks
), errOut
);
3357 SecPolicyAddBasicCertOptions(options
);
3359 SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNamePPQSigning
);
3360 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3362 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
3363 CFSTR("Apple System Integration 2 Certification Authority"));
3365 // Check that leaf has extension with "Apple PPQ Signing" prod oid (1.2.840.113635.100.6.38.2)
3366 add_leaf_marker(options
, &oidAppleCertExtApplePPQSigningProd
);
3368 // Check that intermediate has extension (1.2.840.113635.100.6.2.10)
3369 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleSystemIntg2
);
3371 add_ku(options
, kSecKeyUsageDigitalSignature
);
3373 require(result
= SecPolicyCreate(kSecPolicyApplePPQSigning
,
3374 kSecPolicyNamePPQSigning
, options
), errOut
);
3377 CFReleaseSafe(options
);
3382 @function SecPolicyCreateTestApplePPQSigning
3383 @abstract Check for intermediate certificate 'Apple System Integration 2 Certification Authority' by name,
3385 Leaf cert must have Digital Signature usage.
3386 Leaf cert must have Apple PPQ Signing Test marker OID (1.2.840.113635.100.6.38.1).
3387 Intermediate must have marker OID (1.2.840.113635.100.6.2.10).
3389 SecPolicyRef
SecPolicyCreateTestApplePPQSigning(void)
3391 /* Guard against use of test policy on production devices */
3392 if (!SecIsInternalRelease()) {
3393 return SecPolicyCreateApplePPQSigning();
3396 SecPolicyRef result
= NULL
;
3397 CFMutableDictionaryRef options
= NULL
;
3398 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3399 &kCFTypeDictionaryKeyCallBacks
,
3400 &kCFTypeDictionaryValueCallBacks
), errOut
);
3401 SecPolicyAddBasicCertOptions(options
);
3403 SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameTestPPQSigning
);
3404 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3406 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
3407 CFSTR("Apple System Integration 2 Certification Authority"));
3409 // Check that leaf has extension with "Apple PPQ Signing" test oid (1.2.840.113635.100.6.38.1)
3410 add_leaf_marker(options
, &oidAppleCertExtApplePPQSigningProdQA
);
3412 // Check that intermediate has extension (1.2.840.113635.100.6.2.10)
3413 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleSystemIntg2
);
3415 add_ku(options
, kSecKeyUsageDigitalSignature
);
3417 require(result
= SecPolicyCreate(kSecPolicyAppleTestPPQSigning
,
3418 kSecPolicyNameTestPPQSigning
, options
), errOut
);
3421 CFReleaseSafe(options
);
3425 @function SecPolicyCreateAppleTimeStamping
3426 @abstract Check for RFC3161 timestamping EKU.
3428 SecPolicyRef
SecPolicyCreateAppleTimeStamping(void)
3430 SecPolicyRef result
= NULL
;
3431 CFMutableDictionaryRef options
= NULL
;
3432 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3433 &kCFTypeDictionaryKeyCallBacks
,
3434 &kCFTypeDictionaryValueCallBacks
), errOut
);
3436 SecPolicyAddBasicX509Options(options
);
3438 /* Require id-kp-timeStamping extendedKeyUsage to be present. */
3439 add_eku(options
, &oidExtendedKeyUsageTimeStamping
);
3441 require(result
= SecPolicyCreate(kSecPolicyAppleTimeStamping
,
3442 kSecPolicyNameTimeStamping
, options
), errOut
);
3445 CFReleaseSafe(options
);
3450 @function SecPolicyCreateApplePayIssuerEncryption
3451 @abstract Check for intermediate certificate 'Apple Worldwide Developer Relations CA - G2' by name,
3452 and ECC apple anchor.
3453 Leaf cert must have Key Encipherment and Key Agreement usage.
3454 Leaf cert must have Apple Pay Issuer Encryption marker OID (1.2.840.113635.100.6.39).
3456 SecPolicyRef
SecPolicyCreateApplePayIssuerEncryption(void)
3458 SecPolicyRef result
= NULL
;
3459 CFMutableDictionaryRef options
= NULL
;
3460 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3461 &kCFTypeDictionaryKeyCallBacks
,
3462 &kCFTypeDictionaryValueCallBacks
), errOut
);
3463 SecPolicyAddBasicCertOptions(options
);
3465 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNamePayIssuerEncryption
),
3467 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3469 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
3470 CFSTR("Apple Worldwide Developer Relations CA - G2"));
3472 // Check that leaf has extension with "Apple Pay Issuer Encryption" oid (1.2.840.113635.100.6.39)
3473 add_leaf_marker(options
, &oidAppleCertExtCryptoServicesExtEncryption
);
3475 add_ku(options
, kSecKeyUsageKeyEncipherment
);
3477 require(result
= SecPolicyCreate(kSecPolicyApplePayIssuerEncryption
,
3478 kSecPolicyNamePayIssuerEncryption
, options
), errOut
);
3481 CFReleaseSafe(options
);
3486 @function SecPolicyCreateAppleATVVPNProfileSigning
3487 @abstract Check for leaf marker OID 1.2.840.113635.100.6.43,
3488 intermediate marker OID 1.2.840.113635.100.6.2.10,
3489 chains to Apple Root CA, path length 3
3491 SecPolicyRef
SecPolicyCreateAppleATVVPNProfileSigning(void)
3493 SecPolicyRef result
= NULL
;
3494 CFMutableDictionaryRef options
= NULL
;
3495 CFMutableDictionaryRef appleAnchorOptions
= NULL
;
3496 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3497 &kCFTypeDictionaryKeyCallBacks
,
3498 &kCFTypeDictionaryValueCallBacks
), errOut
);
3500 SecPolicyAddBasicCertOptions(options
);
3502 // Require pinning to the Apple CAs (including test CA for internal releases)
3503 appleAnchorOptions
= CFDictionaryCreateMutableForCFTypes(NULL
);
3504 require(appleAnchorOptions
, errOut
);
3506 if (SecIsInternalRelease()) {
3507 CFDictionarySetValue(appleAnchorOptions
,
3508 kSecPolicyAppleAnchorIncludeTestRoots
, kCFBooleanTrue
);
3511 add_element(options
, kSecPolicyCheckAnchorApple
, appleAnchorOptions
);
3513 // Cert chain length 3
3514 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3516 // Check leaf for Apple ATV VPN Profile Signing OID (1.2.840.113635.100.6.43)
3517 add_leaf_marker(options
, &oidAppleCertExtATVVPNProfileSigning
);
3519 // Check intermediate for Apple System Integration 2 CA intermediate marker (1.2.840.113635.100.6.2.10)
3520 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleSystemIntg2
);
3522 // Ensure that revocation is checked (OCSP only)
3523 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationOCSP
);
3525 require(result
= SecPolicyCreate(kSecPolicyAppleATVVPNProfileSigning
,
3526 kSecPolicyNameATVVPNProfileSigning
, options
), errOut
);
3529 CFReleaseSafe(options
);
3530 CFReleaseSafe(appleAnchorOptions
);
3534 SecPolicyRef
SecPolicyCreateAppleHomeKitServerAuth(CFStringRef hostname
) {
3535 CFMutableDictionaryRef appleAnchorOptions
= NULL
;
3536 CFMutableDictionaryRef options
= NULL
;
3537 SecPolicyRef result
= NULL
;
3538 CFDataRef oid
= NULL
;
3540 options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0, &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
3541 require(options
, errOut
);
3543 SecPolicyAddBasicX509Options(options
);
3545 CFDictionaryAddValue(options
, kSecPolicyCheckSSLHostname
, hostname
);
3547 add_eku(options
, &oidExtendedKeyUsageServerAuth
);
3549 if (requireUATPinning(kSecPolicyNameAppleHomeKitService
)) {
3551 // Cert chain length 3
3552 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3554 // Apple anchors, allowing test anchors for internal release
3555 SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameAppleHomeKitService
);
3557 add_leaf_marker(options
, &oidAppleCertExtHomeKitServerAuth
);
3559 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleHomeKitServerCA
);
3562 /* Check for weak hashes */
3563 require(SecPolicyRemoveWeakHashOptions(options
), errOut
);
3564 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
3566 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
3568 result
= SecPolicyCreate(kSecPolicyAppleHomeKitServerAuth
,
3569 kSecPolicyNameAppleHomeKitService
, options
);
3570 require(result
, errOut
);
3573 CFReleaseSafe(appleAnchorOptions
);
3574 CFReleaseSafe(options
);
3579 SecPolicyRef
SecPolicyCreateAppleExternalDeveloper(void) {
3580 CFMutableDictionaryRef options
= NULL
;
3581 SecPolicyRef result
= NULL
;
3583 /* Create basic Apple pinned policy */
3584 require(result
= SecPolicyCreateApplePinned(kSecPolicyNameExternalDeveloper
,
3585 CFSTR("1.2.840.113635.100.6.2.1"), // WWDR Intermediate OID
3586 CFSTR("1.2.840.113635.100.6.1.2")), // "iPhone Developer" leaf OID
3589 require_action(options
= CFDictionaryCreateMutableCopy(NULL
, 0, result
->_options
), errOut
, CFReleaseNull(result
));
3591 /* Additional intermediate OIDs */
3592 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
,
3593 CFSTR("1.2.840.113635.100.6.2.6")); // "Developer ID" Intermediate OID
3595 /* Addtional leaf OIDS */
3596 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.4")); // "iPhone Distribution" leaf OID
3597 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.5")); // "Safari Developer" leaf OID
3598 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.7")); // "3rd Party Mac Developer Application" leaf OID
3599 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.8")); // "3rd Party Mac Developer Installer" leaf OID
3600 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.12")); // "Mac Developer" leaf OID
3601 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.13")); // "Developer ID Application" leaf OID
3602 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.14")); // "Developer ID Installer" leaf OID
3605 add_eku_string(options
, CFSTR("1.3.6.1.5.5.7.3.3")); // CodeSigning EKU
3606 add_eku_string(options
, CFSTR("1.2.840.113635.100.4.8")); // "Safari Developer" EKU
3607 add_eku_string(options
, CFSTR("1.2.840.113635.100.4.9")); // "3rd Party Mac Developer Installer" EKU
3608 add_eku_string(options
, CFSTR("1.2.840.113635.100.4.13")); // "Developer ID Installer" EKU
3610 CFReleaseSafe(result
->_options
);
3611 result
->_options
= CFRetainSafe(options
);
3613 SecPolicySetOid(result
, kSecPolicyAppleExternalDeveloper
);
3616 CFReleaseSafe(options
);
3620 /* This one is special because the intermediate has no marker OID */
3621 SecPolicyRef
SecPolicyCreateAppleSoftwareSigning(void) {
3622 CFMutableDictionaryRef options
= NULL
;
3623 CFDictionaryRef keySizes
= NULL
;
3624 CFNumberRef rsaSize
= NULL
, ecSize
= NULL
;
3625 SecPolicyRef result
= NULL
;
3627 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3628 &kCFTypeDictionaryKeyCallBacks
,
3629 &kCFTypeDictionaryValueCallBacks
), errOut
);
3631 SecPolicyAddBasicCertOptions(options
);
3633 /* Anchored to the Apple Roots */
3634 require_quiet(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameSoftwareSigning
),
3637 /* Exactly 3 certs in the chain */
3638 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3640 /* Intermediate Common Name matches */
3641 add_element(options
, kSecPolicyCheckIssuerCommonName
, CFSTR("Apple Code Signing Certification Authority"));
3643 /* Leaf marker OID matches */
3644 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.22"));
3646 /* Leaf has CodeSigning EKU */
3647 add_eku_string(options
, CFSTR("1.3.6.1.5.5.7.3.3"));
3649 /* Check revocation using any available method */
3650 add_element(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
3652 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
3653 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
3655 require(result
= SecPolicyCreate(kSecPolicyAppleSoftwareSigning
,
3656 kSecPolicyNameSoftwareSigning
, options
), errOut
);
3659 CFReleaseSafe(options
);
3660 CFReleaseSafe(keySizes
);
3661 CFReleaseSafe(rsaSize
);
3662 CFReleaseSafe(ecSize
);
3666 /* subject:/CN=SEP Root CA/O=Apple Inc./ST=California */
3667 /* SKID: 58:EF:D6:BE:C5:82:B0:54:CD:18:A6:84:AD:A2:F6:7B:7B:3A:7F:CF */
3668 /* Not Before: Jun 24 21:43:24 2014 GMT, Not After : Jun 24 21:43:24 2029 GMT */
3669 /* Signature Algorithm: ecdsa-with-SHA384 */
3670 const uint8_t SEPRootCA_SHA256
[kSecPolicySHA256Size
] = {
3671 0xd1, 0xdf, 0x82, 0x00, 0xf3, 0x89, 0x4e, 0xe9, 0x96, 0xf3, 0x77, 0xdf, 0x76, 0x3b, 0x0a, 0x16,
3672 0x8f, 0xd9, 0x6c, 0x58, 0xc0, 0x3e, 0xc9, 0xb0, 0x5f, 0xa5, 0x64, 0x79, 0xc0, 0xe8, 0xc9, 0xe7
3675 SecPolicyRef
SecPolicyCreateAppleUniqueDeviceCertificate(CFDataRef testRootHash
) {
3676 CFMutableDictionaryRef options
= NULL
;
3677 CFDictionaryRef keySizes
= NULL
;
3678 CFNumberRef ecSize
= NULL
;
3679 SecPolicyRef result
= NULL
;
3681 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3682 &kCFTypeDictionaryKeyCallBacks
,
3683 &kCFTypeDictionaryValueCallBacks
), errOut
);
3685 /* Device certificate should never expire */
3686 SecPolicyAddBasicCertOptions(options
);
3688 /* Anchored to the SEP Root CA. Allow alternative root for developers */
3689 require(SecPolicyAddAnchorSHA256Options(options
, SEPRootCA_SHA256
),errOut
);
3690 if (testRootHash
&& SecIsInternalRelease() && (kSecPolicySHA256Size
== CFDataGetLength(testRootHash
))) {
3691 add_element(options
, kSecPolicyCheckAnchorSHA256
, testRootHash
);
3694 /* Exactly 3 certs in the chain */
3695 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3697 /* Intermediate has marker OID with value */
3698 add_intermediate_marker_value_string(options
, CFSTR("1.2.840.113635.100.6.44"), CFSTR("ucrt"));
3700 /* Leaf has marker OID with varying value that can't be pre-determined */
3701 add_element(options
, kSecPolicyCheckLeafMarkerOidWithoutValueCheck
, CFSTR("1.2.840.113635.100.10.1"));
3703 /* RSA key sizes are disallowed. EC key sizes are P-256 or larger. */
3704 require(ecSize
= CFNumberCreateWithCFIndex(NULL
, 256), errOut
);
3705 require(keySizes
= CFDictionaryCreate(NULL
, (const void**)&kSecAttrKeyTypeEC
,
3706 (const void**)&ecSize
, 1,
3707 &kCFTypeDictionaryKeyCallBacks
,
3708 &kCFTypeDictionaryValueCallBacks
), errOut
);
3709 add_element(options
, kSecPolicyCheckKeySize
, keySizes
);
3712 require(result
= SecPolicyCreate(kSecPolicyAppleUniqueDeviceIdentifierCertificate
,
3713 kSecPolicyNameUniqueDeviceIdentifierCertificate
, options
), errOut
);
3716 CFReleaseSafe(options
);
3717 CFReleaseSafe(keySizes
);
3718 CFReleaseSafe(ecSize
);
3722 SecPolicyRef
SecPolicyCreateAppleWarsaw(void) {
3723 CFMutableDictionaryRef options
= NULL
;
3724 SecPolicyRef result
= NULL
;
3725 #if TARGET_OS_BRIDGE
3726 CFMutableDictionaryRef appleAnchorOptions
= NULL
;
3729 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3730 &kCFTypeDictionaryKeyCallBacks
,
3731 &kCFTypeDictionaryValueCallBacks
), errOut
);
3733 SecPolicyAddBasicX509Options(options
);
3735 /* Anchored to the Apple Roots. */
3736 require_quiet(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameWarsaw
),
3739 /* Exactly 3 certs in the chain */
3740 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3742 /* Intermediate marker OID matches input OID */
3743 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.14"));
3745 /* Leaf marker OID matches input OID */
3746 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.29"));
3748 /* Check revocation using any available method */
3749 add_element(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
3751 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
3752 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
3754 require(result
= SecPolicyCreate(kSecPolicyAppleWarsaw
,
3755 kSecPolicyNameWarsaw
, options
), errOut
);
3758 CFReleaseSafe(options
);
3762 SecPolicyRef
SecPolicyCreateAppleSecureIOStaticAsset(void) {
3763 CFMutableDictionaryRef options
= NULL
;
3764 SecPolicyRef result
= NULL
;
3765 #if TARGET_OS_BRIDGE
3766 CFMutableDictionaryRef appleAnchorOptions
= NULL
;
3769 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3770 &kCFTypeDictionaryKeyCallBacks
,
3771 &kCFTypeDictionaryValueCallBacks
), errOut
);
3773 /* This certificate cannot expire so that assets always load */
3774 SecPolicyAddBasicCertOptions(options
);
3776 /* Anchored to the Apple Roots. */
3777 #if TARGET_OS_BRIDGE
3778 /* On the bridge, test roots are gated in the trust and policy servers. */
3779 require_quiet(appleAnchorOptions
= CFDictionaryCreateMutableForCFTypes(NULL
), errOut
);
3780 CFDictionarySetValue(appleAnchorOptions
,
3781 kSecPolicyAppleAnchorIncludeTestRoots
, kCFBooleanTrue
);
3782 add_element(options
, kSecPolicyCheckAnchorApple
, appleAnchorOptions
);
3783 CFReleaseSafe(appleAnchorOptions
);
3785 require_quiet(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameSecureIOStaticAsset
),
3789 /* Exactly 3 certs in the chain */
3790 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3792 /* Intermediate marker OID matches ASI CA */
3793 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.10"));
3795 /* Leaf marker OID matches static IO OID */
3796 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.50"));
3798 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
3799 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
3801 require(result
= SecPolicyCreate(kSecPolicyAppleSecureIOStaticAsset
,
3802 kSecPolicyNameSecureIOStaticAsset
, options
), errOut
);
3805 CFReleaseSafe(options
);
3809 SecPolicyRef
SecPolicyCreateAppleAppTransportSecurity(void) {
3810 CFMutableDictionaryRef options
= NULL
;
3811 SecPolicyRef result
= NULL
;
3812 CFMutableArrayRef disallowedHashes
= NULL
;
3814 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3815 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
3817 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
3818 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
3820 /* Hash algorithm is SHA-256 or better */
3821 require(disallowedHashes
= CFArrayCreateMutable(NULL
, 5, &kCFTypeArrayCallBacks
), errOut
);
3822 CFArrayAppendValue(disallowedHashes
, kSecSignatureDigestAlgorithmMD2
);
3823 CFArrayAppendValue(disallowedHashes
, kSecSignatureDigestAlgorithmMD4
);
3824 CFArrayAppendValue(disallowedHashes
, kSecSignatureDigestAlgorithmMD5
);
3825 CFArrayAppendValue(disallowedHashes
, kSecSignatureDigestAlgorithmSHA1
);
3826 CFArrayAppendValue(disallowedHashes
, kSecSignatureDigestAlgorithmSHA224
);
3828 add_element(options
, kSecPolicyCheckSignatureHashAlgorithms
, disallowedHashes
);
3830 require_quiet(result
= SecPolicyCreate(kSecPolicyAppleAppTransportSecurity
,
3831 kSecPolicyNameAppTransportSecurity
,
3835 CFReleaseSafe(options
);
3839 SecPolicyRef
SecPolicyCreateMobileSoftwareUpdate(void) {
3840 CFMutableDictionaryRef options
= NULL
;
3841 SecPolicyRef result
= NULL
;
3842 #if TARGET_OS_BRIDGE
3843 CFMutableDictionaryRef appleAnchorOptions
= NULL
;
3846 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3847 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
3849 /* No expiration check. */
3850 SecPolicyAddBasicCertOptions(options
);
3853 require_quiet(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameMobileSoftwareUpdate
),
3856 /* Exactly 3 certs in the chain */
3857 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3859 /* Intermediate marker OID is iPhone CA OID */
3860 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.18"));
3862 /* Leaf marker OID is either the prod MSU OID, or, on internal builds, the prodQA OID */
3863 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.57.2"));
3864 if (SecIsInternalRelease()) {
3865 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.57.1"));
3868 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
3869 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
3871 require(result
= SecPolicyCreate(kSecPolicyAppleMobileSoftwareUpdate
,
3872 kSecPolicyNameMobileSoftwareUpdate
, options
), errOut
);
3875 CFReleaseNull(options
);
3879 /* subject:/CN=Basic Attestation System Root CA/O=Apple Inc./ST=California */
3880 /* SKID: FE:D1:D1:C2:08:07:03:D5:B9:3C:34:B2:BB:FD:7C:3A:99:25:1B:8F */
3881 /* Not Before: Apr 20 00:22:09 2017 GMT, Not After : Mar 22 00:00:00 2032 GMT */
3882 /* Signature Algorithm: ecdsa-with-SHA384 */
3883 const uint8_t BASystemRootCA_SHA256
[kSecPolicySHA256Size
] = {
3884 0x10, 0xD3, 0xC8, 0x67, 0xF0, 0xAE, 0xFB, 0x24, 0x31, 0xA0, 0xA9, 0x7A, 0x88, 0x18, 0xBD, 0x64,
3885 0xF7, 0xF9, 0x0F, 0xFE, 0x11, 0x94, 0x48, 0x4F, 0xCA, 0x97, 0xF0, 0xF2, 0x9E, 0xCA, 0x00, 0x47
3888 /* subject:/CN=Basic Attestation User Root CA/O=Apple Inc./ST=California */
3889 /* SKID: 83:E5:A3:21:9E:B0:74:C3:F9:61:90:FD:97:4E:23:10:76:A4:A3:F2 */
3890 /* Not Before: Apr 19 21:41:56 2017 GMT, Not After : Mar 22 00:00:00 2032 GMT */
3891 /* Signature Algorithm: ecdsa-with-SHA384 */
3892 const uint8_t BAUserRootCA_SHA256
[kSecPolicySHA256Size
] = {
3893 0x03, 0x75, 0x1c, 0x80, 0xfc, 0xbe, 0x58, 0x19, 0xd1, 0x70, 0xd2, 0x67, 0xce, 0x1a, 0xd6, 0xd0,
3894 0x94, 0x40, 0x7c, 0x91, 0xd8, 0x73, 0xd7, 0xa6, 0x56, 0x2d, 0xe3, 0x66, 0x6d, 0x35, 0x94, 0xc6
3897 SecPolicyRef
SecPolicyCreateAppleBasicAttestationSystem(CFDataRef testRootHash
) {
3898 CFMutableDictionaryRef options
= NULL
;
3899 SecPolicyRef result
= NULL
;
3901 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3902 &kCFTypeDictionaryKeyCallBacks
,
3903 &kCFTypeDictionaryValueCallBacks
), errOut
);
3904 /* BAA certs expire */
3905 SecPolicyAddBasicX509Options(options
);
3907 /* Anchored to one of the Basic Attestation roots. Allow alternative root for developers */
3908 SecPolicyAddAnchorSHA256Options(options
, BASystemRootCA_SHA256
);
3909 if (testRootHash
&& SecIsInternalRelease() && (kSecPolicySHA256Size
== CFDataGetLength(testRootHash
))) {
3910 add_element(options
, kSecPolicyCheckAnchorSHA256
, testRootHash
);
3913 /* Exactly 3 certs in the chain */
3914 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3916 require(result
= SecPolicyCreate(kSecPolicyAppleBasicAttestationSystem
,
3917 kSecPolicyNameBasicAttestationSystem
, options
), errOut
);
3920 CFReleaseSafe(options
);
3924 SecPolicyRef
SecPolicyCreateAppleBasicAttestationUser(CFDataRef testRootHash
) {
3925 CFMutableDictionaryRef options
= NULL
;
3926 SecPolicyRef result
= NULL
;
3928 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3929 &kCFTypeDictionaryKeyCallBacks
,
3930 &kCFTypeDictionaryValueCallBacks
), errOut
);
3931 /* BAA certs expire */
3932 SecPolicyAddBasicX509Options(options
);
3934 /* Anchored to one of the Basic Attestation roots. Allow alternative root for developers */
3935 SecPolicyAddAnchorSHA256Options(options
, BAUserRootCA_SHA256
);
3936 if (testRootHash
&& SecIsInternalRelease() && (kSecPolicySHA256Size
== CFDataGetLength(testRootHash
))) {
3937 add_element(options
, kSecPolicyCheckAnchorSHA256
, testRootHash
);
3940 /* Exactly 3 certs in the chain */
3941 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3943 require(result
= SecPolicyCreate(kSecPolicyAppleBasicAttestationUser
,
3944 kSecPolicyNameBasicAttestationUser
, options
), errOut
);
3947 CFReleaseSafe(options
);
3951 SecPolicyRef
SecPolicyCreateiAPSWAuthWithExpiration(bool checkExpiration
) {
3952 CFMutableDictionaryRef options
= NULL
;
3953 SecPolicyRef result
= NULL
;
3955 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3956 &kCFTypeDictionaryKeyCallBacks
,
3957 &kCFTypeDictionaryValueCallBacks
), errOut
);
3959 /* iAP checks expiration on developement certs, but not on production certs */
3960 if (checkExpiration
) {
3961 SecPolicyAddBasicX509Options(options
);
3963 SecPolicyAddBasicCertOptions(options
);
3966 /* Exactly 2 certs in the chain */
3967 require(SecPolicyAddChainLengthOptions(options
, 2), errOut
);
3969 /* iAP SW Auth General Capabilities Extension present */
3970 add_element(options
, kSecPolicyCheckLeafMarkerOidWithoutValueCheck
, CFSTR("1.2.840.113635.100.6.59.1"));
3972 require(result
= SecPolicyCreate(kSecPolicyAppleiAPSWAuth
,
3973 kSecPolicyNameiAPSWAuth
, options
), errOut
);
3976 CFReleaseSafe(options
);
3980 SecPolicyRef
SecPolicyCreateiAPSWAuth(void) {
3981 /* By default, iAP SW Auth certs don't expire */
3982 return SecPolicyCreateiAPSWAuthWithExpiration(false);
3985 SecPolicyRef
SecPolicyCreateDemoDigitalCatalogSigning(void) {
3986 CFMutableDictionaryRef options
= NULL
;
3987 SecPolicyRef result
= NULL
;
3989 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3990 &kCFTypeDictionaryKeyCallBacks
,
3991 &kCFTypeDictionaryValueCallBacks
), errOut
);
3992 SecPolicyAddBasicX509Options(options
);
3994 /* Exactly 3 certs in the chain */
3995 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3997 /* Demo Signing Extension present in leaf */
3998 add_element(options
, kSecPolicyCheckLeafMarkerOid
, CFSTR("1.2.840.113635.100.6.60"));
4000 /* Issuer common name is "DemoUnit CA" */
4001 add_element(options
, kSecPolicyCheckIssuerCommonName
, CFSTR("DemoUnit CA"));
4003 require(result
= SecPolicyCreate(kSecPolicyAppleDemoDigitalCatalog
,
4004 kSecPolicyNameDemoDigitalCatalog
, options
), errOut
);
4007 CFReleaseSafe(options
);
4011 SecPolicyRef
SecPolicyCreateAppleAssetReceipt(void) {
4012 CFMutableDictionaryRef options
= NULL
;
4013 SecPolicyRef result
= NULL
;
4015 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
4016 &kCFTypeDictionaryKeyCallBacks
,
4017 &kCFTypeDictionaryValueCallBacks
), errOut
);
4019 /* No expiration check. */
4020 SecPolicyAddBasicCertOptions(options
);
4023 require_quiet(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameAssetReceipt
), errOut
);
4025 /* Exactly 3 certs in the chain */
4026 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
4028 /* Intermediate marker OID is Apple System Integration 2 CA */
4029 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.10"));
4031 /* Leaf marker OID is the Asset Receipt OID */
4032 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.61"));
4034 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
4035 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
4037 require(result
= SecPolicyCreate(kSecPolicyAppleAssetReceipt
,
4038 kSecPolicyNameAssetReceipt
, options
), errOut
);
4041 CFReleaseNull(options
);
4045 SecPolicyRef
SecPolicyCreateAppleDeveloperIDPlusTicket(void) {
4046 CFMutableDictionaryRef options
= NULL
;
4047 SecPolicyRef result
= NULL
;
4049 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
4050 &kCFTypeDictionaryKeyCallBacks
,
4051 &kCFTypeDictionaryValueCallBacks
), errOut
);
4053 /* No expiration check. */
4054 SecPolicyAddBasicCertOptions(options
);
4057 require_quiet(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameDeveloperIDPlusTicket
), errOut
);
4059 /* Exactly 3 certs in the chain */
4060 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
4062 /* Intermediate marker OID is Apple System Integration CA 4 */
4063 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.17"));
4065 /* Leaf marker OID is the Developer ID+ Ticket OID */
4066 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.30"));
4068 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
4069 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
4071 require(result
= SecPolicyCreate(kSecPolicyAppleDeveloperIDPlusTicket
,
4072 kSecPolicyNameDeveloperIDPlusTicket
, options
), errOut
);
4075 CFReleaseNull(options
);
4079 SecPolicyRef
SecPolicyCreateAppleFDRProvisioning(void) {
4080 CFMutableDictionaryRef options
= NULL
;
4081 SecPolicyRef result
= NULL
;
4083 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
4084 &kCFTypeDictionaryKeyCallBacks
,
4085 &kCFTypeDictionaryValueCallBacks
), errOut
);
4087 /* No expiration check. */
4088 SecPolicyAddBasicCertOptions(options
);
4090 require(result
= SecPolicyCreate(kSecPolicyAppleFDRProvisioning
,
4091 kSecPolicyNameFDRProvisioning
, options
), errOut
);
4093 CFReleaseNull(options
);
4097 /* subject:/CN=Component Root CA/O=Apple Inc./ST=California */
4098 /* SKID: 90:D1:56:A9:3E:B4:EE:8C:D0:10:4B:9F:17:1C:5B:55:F2:12:F6:4C */
4099 /* Not Before: Dec 19 19:31:54 2018 GMT, Not After : Dec 16 00:00:00 2043 GMT */
4100 /* Signature Algorithm: ecdsa-with-SHA384 */
4101 const uint8_t ComponentRootCA_SHA256
[kSecPolicySHA256Size
] = {
4102 0x2f, 0x71, 0x9d, 0xbf, 0x3c, 0xcd, 0xe7, 0xc2, 0xb2, 0x59, 0x3f, 0x32, 0x1f, 0x90, 0xf3, 0x42,
4103 0x42, 0xaa, 0x84, 0xa1, 0xb2, 0x0d, 0xca, 0xcc, 0x10, 0xc0, 0x5b, 0x26, 0xd6, 0x23, 0xb8, 0x47,
4105 SecPolicyRef
SecPolicyCreateAppleComponentCertificate(CFDataRef testRootHash
) {
4106 CFMutableDictionaryRef options
= NULL
;
4107 SecPolicyRef result
= NULL
;
4109 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
4110 &kCFTypeDictionaryKeyCallBacks
,
4111 &kCFTypeDictionaryValueCallBacks
), errOut
);
4113 /* Component certificates don't expire */
4114 SecPolicyAddBasicCertOptions(options
);
4116 /* Anchored to one of the Component roots. Allow alternative root for developers */
4117 SecPolicyAddAnchorSHA256Options(options
, ComponentRootCA_SHA256
);
4118 if (testRootHash
&& SecIsInternalRelease() && (kSecPolicySHA256Size
== CFDataGetLength(testRootHash
))) {
4119 add_element(options
, kSecPolicyCheckAnchorSHA256
, testRootHash
);
4122 /* Exactly 3 certs in the chain */
4123 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
4125 /* Leaf and intermediate must contain Component Type OID */
4126 add_element(options
, kSecPolicyCheckLeafMarkerOidWithoutValueCheck
, CFSTR("1.2.840.113635.100.11.1"));
4127 add_element(options
, kSecPolicyCheckIntermediateMarkerOidWithoutValueCheck
, CFSTR("1.2.840.113635.100.11.1"));
4129 require(result
= SecPolicyCreate(kSecPolicyAppleComponentCertificate
,
4130 kSecPolicyNameComponentCertificate
, options
), errOut
);
4132 CFReleaseNull(options
);
4136 SecPolicyRef
SecPolicyCreateAppleKeyTransparency(CFStringRef applicationId
) {
4137 CFMutableDictionaryRef options
= NULL
;
4138 SecPolicyRef result
= NULL
;
4140 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
4141 &kCFTypeDictionaryKeyCallBacks
,
4142 &kCFTypeDictionaryValueCallBacks
), errOut
);
4144 /* KT signing certs don't expire */
4145 SecPolicyAddBasicCertOptions(options
);
4148 require_quiet(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameKeyTransparency
), errOut
);
4150 /* Exactly 3 certs in the chain */
4151 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
4153 /* Intermediate marker OID matches AAI CA 5 */
4154 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.3"));
4156 /* Leaf marker extension matches input applicationId */
4157 add_leaf_marker_value_string(options
, CFSTR("1.2.840.113635.100.12.4"), applicationId
);
4159 /* Check revocation using any available method */
4160 add_element(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
4162 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
4163 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
4165 /* Check for weak hashes */
4166 require(SecPolicyRemoveWeakHashOptions(options
), errOut
);
4168 /* Future CT requirement */
4170 require(result
= SecPolicyCreate(kSecPolicyAppleKeyTransparency
,
4171 kSecPolicyNameKeyTransparency
, options
), errOut
);
4173 CFReleaseNull(options
);