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>
47 #include <os/variant_private.h>
49 #include <utilities/SecInternalReleasePriv.h>
51 #undef POLICYCHECKMACRO
52 #define POLICYCHECKMACRO(NAME, TRUSTRESULT, SUBTYPE, LEAFCHECK, PATHCHECK, LEAFONLY, CSSMERR, OSSTATUS) \
53 const CFStringRef kSecPolicyCheck##NAME = CFSTR(#NAME);
54 #include "SecPolicyChecks.list"
56 #define SEC_CONST_DECL(k,v) const CFStringRef k = CFSTR(v);
58 /********************************************************
59 ******************* Feature toggles ********************
60 ********************************************************/
61 /* Option for AnchorApple */
62 SEC_CONST_DECL (kSecPolicyAppleAnchorIncludeTestRoots
, "AnchorAppleTestRoots");
64 /* options for kSecPolicyCheckLeafMarkersProdAndQA */
65 SEC_CONST_DECL (kSecPolicyLeafMarkerProd
, "ProdMarker");
66 SEC_CONST_DECL (kSecPolicyLeafMarkerQA
, "QAMarker");
68 /* Revocation toggles */
69 SEC_CONST_DECL (kSecPolicyCheckRevocationOCSP
, "OCSP");
70 SEC_CONST_DECL (kSecPolicyCheckRevocationCRL
, "CRL");
71 SEC_CONST_DECL (kSecPolicyCheckRevocationAny
, "AnyRevocationMethod");
73 /* Public policy oids. */
74 #define POLICYMACRO(NAME, OID, ISPUBLIC, INTNAME, IN_NAME, IN_PROPERTIES, FUNCTION) \
75 const CFStringRef kSecPolicyApple##NAME = CFSTR("1.2.840.113635.100.1."#OID);
76 #include "SecPolicy.list"
77 //Some naming exceptions
78 SEC_CONST_DECL(kSecPolicyMacAppStoreReceipt
, "1.2.840.113635.100.1.19")
79 SEC_CONST_DECL(kSecPolicyAppleIDValidationRecordSigningPolicy
, "1.2.840.113635.100.1.30");
81 SEC_CONST_DECL (kSecPolicyOid
, "SecPolicyOid");
82 SEC_CONST_DECL (kSecPolicyName
, "SecPolicyName");
83 SEC_CONST_DECL (kSecPolicyClient
, "SecPolicyClient");
84 SEC_CONST_DECL (kSecPolicyRevocationFlags
, "SecPolicyRevocationFlags");
85 SEC_CONST_DECL (kSecPolicyTeamIdentifier
, "SecPolicyTeamIdentifier");
86 SEC_CONST_DECL (kSecPolicyContext
, "SecPolicyContext");
87 SEC_CONST_DECL (kSecPolicyPolicyName
, "SecPolicyPolicyName");
88 SEC_CONST_DECL (kSecPolicyIntermediateMarkerOid
, "SecPolicyIntermediateMarkerOid");
89 SEC_CONST_DECL (kSecPolicyLeafMarkerOid
, "SecPolicyLeafMarkerOid");
90 SEC_CONST_DECL (kSecPolicyRootDigest
, "SecPolicyRootDigest");
92 SEC_CONST_DECL (kSecPolicyKU_DigitalSignature
, "CE_KU_DigitalSignature");
93 SEC_CONST_DECL (kSecPolicyKU_NonRepudiation
, "CE_KU_NonRepudiation");
94 SEC_CONST_DECL (kSecPolicyKU_KeyEncipherment
, "CE_KU_KeyEncipherment");
95 SEC_CONST_DECL (kSecPolicyKU_DataEncipherment
, "CE_KU_DataEncipherment");
96 SEC_CONST_DECL (kSecPolicyKU_KeyAgreement
, "CE_KU_KeyAgreement");
97 SEC_CONST_DECL (kSecPolicyKU_KeyCertSign
, "CE_KU_KeyCertSign");
98 SEC_CONST_DECL (kSecPolicyKU_CRLSign
, "CE_KU_CRLSign");
99 SEC_CONST_DECL (kSecPolicyKU_EncipherOnly
, "CE_KU_EncipherOnly");
100 SEC_CONST_DECL (kSecPolicyKU_DecipherOnly
, "CE_KU_DecipherOnly");
102 /* Internal policy names */
104 #define __P_DO_DECLARE_(NAME, INTNAME) static CFStringRef kSecPolicyName##NAME = CFSTR(#INTNAME);
105 #define __P_DO_DECLARE_E(NAME, INTNAME) static CFStringRef kSecPolicyName##NAME = CFSTR(#INTNAME);
106 #define __P_DO_DECLARE_P(NAME, INTNAME) const CFStringRef kSecPolicyNameApple##NAME = CFSTR(#INTNAME);
107 #define __P_DO_DECLARE_I(NAME, INTNAME) const CFStringRef kSecPolicyName##NAME = CFSTR(#INTNAME);
108 #define POLICYMACRO(NAME, OID, ISPUBLIC, INTNAME, IN_NAME, IN_PROPERTIES, FUNCTION) \
109 __P_DO_DECLARE_##ISPUBLIC(NAME, INTNAME)
110 #include "SecPolicy.list"
111 //Some naming exceptions
112 static CFStringRef kSecPolicyNameAppleIDSBag
= CFSTR("IDSBag");
114 /* External Policy Names
115 * These correspond to the names defined in CertificatePinning.plist
116 * in security_certificates */
117 SEC_CONST_DECL (kSecPolicyNameSSLServer
, "sslServer");
118 SEC_CONST_DECL (kSecPolicyNameSSLClient
, "sslClient");
119 SEC_CONST_DECL (kSecPolicyNameEAPServer
, "eapServer");
120 SEC_CONST_DECL (kSecPolicyNameEAPClient
, "eapClient");
121 SEC_CONST_DECL (kSecPolicyNameIPSecServer
, "ipsecServer");
122 SEC_CONST_DECL (kSecPolicyNameIPSecClient
, "ipsecClient");
123 SEC_CONST_DECL (kSecPolicyNameAppleiCloudSetupService
, "iCloudSetup");
124 SEC_CONST_DECL (kSecPolicyNameAppleMMCSService
, "MMCS");
125 SEC_CONST_DECL (kSecPolicyNameAppleAST2Service
, "AST2");
126 SEC_CONST_DECL (kSecPolicyNameAppleEscrowProxyService
, "Escrow");
127 SEC_CONST_DECL (kSecPolicyNameAppleFMiPService
, "FMiP");
128 SEC_CONST_DECL (kSecPolicyNameAppleHomeKitService
, "HomeKit");
129 SEC_CONST_DECL (kSecPolicyNameAppleAIDCService
, "AIDC");
130 SEC_CONST_DECL (kSecPolicyNameAppleMapsService
, "Maps");
131 SEC_CONST_DECL (kSecPolicyNameAppleHealthProviderService
, "HealthProvider");
132 SEC_CONST_DECL (kSecPolicyNameAppleParsecService
, "Parsec");
133 SEC_CONST_DECL (kSecPolicyNameAppleAMPService
, "AMP");
134 SEC_CONST_DECL (kSecPolicyNameAppleSiriService
, "Siri");
135 SEC_CONST_DECL (kSecPolicyNameAppleHomeAppClipUploadService
, "HomeAppClipUploadService");
136 SEC_CONST_DECL (kSecPolicyNameAppleUpdatesService
, "Updates");
138 #define kSecPolicySHA1Size 20
139 #define kSecPolicySHA256Size 32
140 __unused
const UInt8 kAppleCASHA1
[kSecPolicySHA1Size
] = {
141 0x61, 0x1E, 0x5B, 0x66, 0x2C, 0x59, 0x3A, 0x08, 0xFF, 0x58,
142 0xD1, 0x4A, 0xE2, 0x24, 0x52, 0xD1, 0x98, 0xDF, 0x6C, 0x60
145 __unused
static const UInt8 kAppleTESTCASHA1
[kSecPolicySHA1Size
] = {
146 0xbc, 0x30, 0x55, 0xc8, 0xc8, 0xd3, 0x48, 0x3f, 0xf4, 0x8d,
147 0xfe, 0x3d, 0x51, 0x75, 0x31, 0xc9, 0xf4, 0xd7, 0x4a, 0xf7
150 static const UInt8 kITMSCASHA1
[kSecPolicySHA1Size
] = {
151 0x1D, 0x33, 0x42, 0x46, 0x8B, 0x10, 0xBD, 0xE6, 0x45, 0xCE,
152 0x44, 0x6E, 0xBB, 0xE8, 0xF5, 0x03, 0x5D, 0xF8, 0x32, 0x22
155 static const UInt8 kFactoryDeviceCASHA1
[kSecPolicySHA1Size
] = {
156 0xef, 0x68, 0x73, 0x17, 0xa4, 0xf8, 0xf9, 0x4b, 0x7b, 0x21,
157 0xe2, 0x2f, 0x09, 0x8f, 0xfd, 0x6a, 0xae, 0xc0, 0x0d, 0x63
160 static const UInt8 kApplePKISettingsAuthority
[kSecPolicySHA1Size
] = {
161 0x1D, 0x0C, 0xBA, 0xAD, 0x17, 0xFD, 0x7E, 0x9E, 0x9F, 0xF1,
162 0xC9, 0xA2, 0x66, 0x79, 0x60, 0x00, 0x8B, 0xAE, 0x70, 0xB8
165 static const UInt8 kAppleTestPKISettingsAuthority
[kSecPolicySHA1Size
] = {
166 0xDB, 0xBA, 0x25, 0x0B, 0xD8, 0x62, 0x71, 0x87, 0x54, 0x7E,
167 0xD7, 0xEF, 0x11, 0x94, 0x7E, 0x82, 0xE6, 0xD8, 0x1C, 0x9A
170 static const UInt8 kTestAppleRootCA_ECC_SHA1
[kSecPolicySHA1Size
] = {
171 0x62, 0x0A, 0xED, 0x83, 0xD2, 0x97, 0x4A, 0x77, 0x56, 0x33,
172 0x83, 0xBE, 0xDB, 0xF9, 0xA1, 0xBD, 0x5F, 0xFE, 0x55, 0x7B
175 __unused
static const UInt8 kAppleRootCA_ECC_SHA1
[kSecPolicySHA1Size
] = {
176 0xB5, 0x2C, 0xB0, 0x2F, 0xD5, 0x67, 0xE0, 0x35, 0x9F, 0xE8,
177 0xFA, 0x4D, 0x4C, 0x41, 0x03, 0x79, 0x70, 0xFE, 0x01, 0xB0
182 /********************************************************
183 ****************** SecPolicy object ********************
184 ********************************************************/
186 static void SecPolicyDestroy(CFTypeRef cf
) {
187 SecPolicyRef policy
= (SecPolicyRef
) cf
;
188 CFRelease(policy
->_oid
);
189 CFReleaseSafe(policy
->_name
);
190 CFRelease(policy
->_options
);
193 static Boolean
SecPolicyCompare(CFTypeRef cf1
, CFTypeRef cf2
) {
194 SecPolicyRef policy1
= (SecPolicyRef
) cf1
;
195 SecPolicyRef policy2
= (SecPolicyRef
) cf2
;
196 if (policy1
->_name
&& policy2
->_name
) {
197 return CFEqual(policy1
->_oid
, policy2
->_oid
) &&
198 CFEqual(policy1
->_name
, policy2
->_name
) &&
199 CFEqual(policy1
->_options
, policy2
->_options
);
201 return CFEqual(policy1
->_oid
, policy2
->_oid
) &&
202 CFEqual(policy1
->_options
, policy2
->_options
);
206 static CFHashCode
SecPolicyHash(CFTypeRef cf
) {
207 SecPolicyRef policy
= (SecPolicyRef
) cf
;
209 return CFHash(policy
->_oid
) + CFHash(policy
->_name
) + CFHash(policy
->_options
);
211 return CFHash(policy
->_oid
) + CFHash(policy
->_options
);
215 static CFStringRef
SecPolicyCopyFormatDescription(CFTypeRef cf
, CFDictionaryRef formatOptions
) {
216 SecPolicyRef policy
= (SecPolicyRef
) cf
;
217 CFMutableStringRef desc
= CFStringCreateMutable(kCFAllocatorDefault
, 0);
218 CFStringRef typeStr
= CFCopyTypeIDDescription(CFGetTypeID(cf
));
219 CFStringAppendFormat(desc
, NULL
,
220 CFSTR("<%@: oid: %@ name: %@ options %@"), typeStr
,
221 policy
->_oid
, (policy
->_name
) ? policy
->_name
: CFSTR(""),
224 CFStringAppend(desc
, CFSTR(" >"));
229 /* SecPolicy API functions. */
230 CFGiblisWithHashFor(SecPolicy
);
232 /* AUDIT[securityd](done):
233 oid (ok) is a caller provided string, only its cf type has been checked.
234 options is a caller provided dictionary, only its cf type has been checked.
236 SecPolicyRef
SecPolicyCreate(CFStringRef oid
, CFStringRef name
, CFDictionaryRef options
) {
237 SecPolicyRef result
= NULL
;
239 require(oid
, errOut
);
240 require(options
, errOut
);
242 (SecPolicyRef
)_CFRuntimeCreateInstance(kCFAllocatorDefault
,
243 SecPolicyGetTypeID(),
244 sizeof(struct __SecPolicy
) - sizeof(CFRuntimeBase
), 0), errOut
);
249 result
->_name
= name
;
251 result
->_options
= options
;
258 static void set_ku_from_properties(SecPolicyRef policy
, CFDictionaryRef properties
);
261 SecPolicyRef
SecPolicyCreateWithProperties(CFTypeRef policyIdentifier
,
262 CFDictionaryRef properties
) {
263 // Creates a policy reference for a given policy object identifier.
264 // If policy-specific parameters can be supplied (e.g. hostname),
265 // attempt to obtain from input properties dictionary.
266 // Returns NULL if the given identifier is unsupported.
268 SecPolicyRef policy
= NULL
;
269 CFTypeRef name
= NULL
;
270 CFStringRef teamID
= NULL
;
271 Boolean client
= false;
272 CFDictionaryRef context
= NULL
;
273 CFStringRef policyName
= NULL
, intermediateMarkerOid
= NULL
, leafMarkerOid
= NULL
;
274 CFDataRef rootDigest
= NULL
;
275 require(policyIdentifier
&& (CFStringGetTypeID() == CFGetTypeID(policyIdentifier
)), errOut
);
278 name
= CFDictionaryGetValue(properties
, kSecPolicyName
);
279 teamID
= CFDictionaryGetValue(properties
, kSecPolicyTeamIdentifier
);
281 CFBooleanRef dictionaryClientValue
;
282 client
= (CFDictionaryGetValueIfPresent(properties
, kSecPolicyClient
, (const void **)&dictionaryClientValue
) &&
283 (dictionaryClientValue
!= NULL
) && CFEqual(kCFBooleanTrue
, dictionaryClientValue
));
284 context
= CFDictionaryGetValue(properties
, kSecPolicyContext
);
285 policyName
= CFDictionaryGetValue(properties
, kSecPolicyPolicyName
);
286 intermediateMarkerOid
= CFDictionaryGetValue(properties
, kSecPolicyIntermediateMarkerOid
);
287 leafMarkerOid
= CFDictionaryGetValue(properties
, kSecPolicyLeafMarkerOid
);
288 rootDigest
= CFDictionaryGetValue(properties
, kSecPolicyRootDigest
);
291 /* only the EAP policy allows a non-string name */
292 if (name
&& !isString(name
) && !CFEqual(policyIdentifier
, kSecPolicyAppleEAP
)) {
293 secerror("policy \"%@\" requires a string value for the %@ key", policyIdentifier
, kSecPolicyName
);
297 /* What follows are all the exceptional functions that do not match the macro below */
298 if (CFEqual(policyIdentifier
, kSecPolicyAppleSSL
)) {
299 policy
= SecPolicyCreateSSL(!client
, name
);
300 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleSMIME
)) {
301 policy
= SecPolicyCreateSMIME(kSecSignSMIMEUsage
| kSecAnyEncryptSMIME
, name
);
302 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleEAP
)) {
303 CFArrayRef array
= NULL
;
304 if (isString(name
)) {
305 array
= CFArrayCreate(kCFAllocatorDefault
, (const void **)&name
, 1, &kCFTypeArrayCallBacks
);
306 } else if (isArray(name
)) {
307 array
= CFArrayCreateCopy(NULL
, name
);
309 policy
= SecPolicyCreateEAP(!client
, array
);
310 CFReleaseSafe(array
);
311 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleIPsec
)) {
312 policy
= SecPolicyCreateIPSec(!client
, name
);
313 } else if (CFEqual(policyIdentifier
, kSecPolicyMacAppStoreReceipt
)) {
314 policy
= SecPolicyCreateMacAppStoreReceipt();
315 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleRevocation
)) {
316 policy
= SecPolicyCreateRevocation(kSecRevocationUseAnyAvailableMethod
);
317 } else if (CFEqual(policyIdentifier
, kSecPolicyApplePassbookSigning
)) {
318 policy
= SecPolicyCreatePassbookCardSigner(name
, teamID
);
319 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleAST2DiagnosticsServerAuth
)) {
321 policy
= SecPolicyCreateAppleAST2Service(name
, context
);
323 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier
);
325 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleEscrowProxyServerAuth
)) {
327 policy
= SecPolicyCreateAppleEscrowProxyService(name
, context
);
329 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier
);
331 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleFMiPServerAuth
)) {
333 policy
= SecPolicyCreateAppleFMiPService(name
, context
);
335 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier
);
337 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleMMCService
)) {
339 policy
= SecPolicyCreateAppleMMCSService(name
, context
);
341 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier
);
343 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleGSService
)) {
345 policy
= SecPolicyCreateAppleGSService(name
, context
);
347 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier
);
349 } else if (CFEqual(policyIdentifier
, kSecPolicyApplePPQService
)) {
351 policy
= SecPolicyCreateApplePPQService(name
, context
);
353 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier
);
355 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleGenericApplePinned
)) {
357 policy
= SecPolicyCreateApplePinned(policyName
, intermediateMarkerOid
, leafMarkerOid
);
359 secerror("policy \"%@\" requires kSecPolicyPolicyName input", policyIdentifier
);
361 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleGenericAppleSSLPinned
)) {
363 policy
= SecPolicyCreateAppleSSLPinned(policyName
, name
, intermediateMarkerOid
, leafMarkerOid
);
365 secerror("policy \"%@\" requires kSecPolicyPolicyName input", policyIdentifier
);
367 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleIDSServiceContext
)) {
369 policy
= SecPolicyCreateAppleIDSServiceContext(name
, context
);
371 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier
);
373 } else if (CFEqual(policyIdentifier
, kSecPolicyApplePushService
)) {
375 policy
= SecPolicyCreateApplePushService(name
, context
);
377 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier
);
379 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleUniqueDeviceIdentifierCertificate
)) {
380 policy
= SecPolicyCreateAppleUniqueDeviceCertificate(rootDigest
);
381 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleiCloudSetupServerAuth
)) {
383 policy
= SecPolicyCreateAppleiCloudSetupService(name
, context
);
385 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier
);
387 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleBasicAttestationSystem
)) {
388 policy
= SecPolicyCreateAppleBasicAttestationSystem(rootDigest
);
389 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleBasicAttestationUser
)) {
390 policy
= SecPolicyCreateAppleBasicAttestationUser(rootDigest
);
391 } else if (CFEqual(policyIdentifier
, kSecPolicyAppleComponentCertificate
)) {
392 policy
= SecPolicyCreateAppleComponentCertificate(rootDigest
);
394 /* For a couple of common patterns we use the macro, but some of the
395 * policies are deprecated (or not yet available), so we need to ignore the warning. */
396 #pragma clang diagnostic push
397 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
398 #pragma clang diagnostic ignored "-Wunguarded-availability"
400 #define _P_OPTION_N name
401 #define _P_PROPERTIES_(NAME, IN_NAME, FUNCTION)
402 #define _P_PROPERTIES_Y(NAME, IN_NAME, FUNCTION) else if (CFEqual(policyIdentifier, kSecPolicyApple##NAME)) { \
403 policy = SecPolicyCreate##FUNCTION(_P_OPTION_##IN_NAME); \
406 #define POLICYMACRO(NAME, OID, ISPUBLIC, INTNAME, IN_NAME, IN_PROPERTIES, FUNCTION) \
407 _P_PROPERTIES_##IN_PROPERTIES(NAME, IN_NAME, FUNCTION)
408 #include "SecPolicy.list"
410 secerror("ERROR: policy \"%@\" is unsupported", policyIdentifier
);
412 #pragma clang diagnostic pop // ignored "-Wdeprecated-declarations"
419 set_ku_from_properties(policy
, properties
);
423 SecPolicySetName(policy
, policyName
);
430 CFDictionaryRef
SecPolicyCopyProperties(SecPolicyRef policyRef
) {
431 // Builds and returns a dictionary which the caller must release.
433 #pragma clang diagnostic push
434 #pragma clang diagnostic ignored "-Wnonnull"
435 // After introducing nullability annotations, policyRef is supposed to be nonnull, suppress the warning
436 if (!policyRef
) return NULL
;
437 #pragma clang diagnostic pop
438 CFMutableDictionaryRef properties
= CFDictionaryCreateMutable(NULL
, 0,
439 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
440 #pragma clang diagnostic push
441 #pragma clang diagnostic ignored "-Wnonnull"
442 // 'properties' is nonnull in reality suppress the warning
443 if (!properties
) return NULL
;
444 #pragma clang diagnostic pop
445 CFStringRef oid
= (CFStringRef
) CFRetain(policyRef
->_oid
);
446 CFTypeRef nameKey
= NULL
;
448 // Determine name key
449 if (policyRef
->_options
) {
450 if (CFDictionaryContainsKey(policyRef
->_options
, kSecPolicyCheckSSLHostname
)) {
451 nameKey
= kSecPolicyCheckSSLHostname
;
452 } else if (CFDictionaryContainsKey(policyRef
->_options
, kSecPolicyCheckEAPTrustedServerNames
)) {
453 nameKey
= kSecPolicyCheckEAPTrustedServerNames
;
454 } else if (CFDictionaryContainsKey(policyRef
->_options
, kSecPolicyCheckEmail
)) {
455 nameKey
= kSecPolicyCheckEmail
;
460 CFDictionarySetValue(properties
, (const void *)kSecPolicyOid
,
463 // Set kSecPolicyName if we have one
464 if (nameKey
&& policyRef
->_options
) {
465 CFTypeRef name
= (CFTypeRef
) CFDictionaryGetValue(policyRef
->_options
,
468 CFDictionarySetValue(properties
, (const void *)kSecPolicyName
,
473 // Set kSecPolicyClient
474 CFStringRef policyName
= (CFStringRef
) CFRetainSafe(policyRef
->_name
);
475 if (policyName
&& (CFEqual(policyName
, kSecPolicyNameSSLClient
) ||
476 CFEqual(policyName
, kSecPolicyNameIPSecClient
) ||
477 CFEqual(policyName
, kSecPolicyNameEAPClient
))) {
478 CFDictionarySetValue(properties
, (const void *)kSecPolicyClient
,
479 (const void *)kCFBooleanTrue
);
486 static void SecPolicySetOid(SecPolicyRef policy
, CFStringRef oid
) {
487 if (!policy
|| !oid
) return;
488 CFStringRef temp
= policy
->_oid
;
494 void SecPolicySetName(SecPolicyRef policy
, CFStringRef policyName
) {
495 if (!policy
|| !policyName
) return;
496 CFStringRef temp
= policy
->_name
;
497 CFRetain(policyName
);
498 policy
->_name
= policyName
;
502 CFStringRef
SecPolicyGetOidString(SecPolicyRef policy
) {
506 CFStringRef
SecPolicyGetName(SecPolicyRef policy
) {
507 return policy
->_name
;
510 CFDictionaryRef
SecPolicyGetOptions(SecPolicyRef policy
) {
511 return policy
->_options
;
514 void SecPolicySetOptionsValue(SecPolicyRef policy
, CFStringRef key
, CFTypeRef value
) {
515 if (!policy
|| !key
) return;
516 CFMutableDictionaryRef options
= (CFMutableDictionaryRef
) policy
->_options
;
518 options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
519 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
520 if (!options
) return;
521 policy
->_options
= options
;
523 CFDictionarySetValue(options
, key
, value
);
526 /* Local forward declaration */
527 static void set_ssl_ekus(CFMutableDictionaryRef options
, bool server
);
530 // this is declared as NA for iPhone in SecPolicy.h, so declare here
531 OSStatus
SecPolicySetProperties(SecPolicyRef policyRef
, CFDictionaryRef properties
);
534 OSStatus
SecPolicySetProperties(SecPolicyRef policyRef
, CFDictionaryRef properties
) {
535 // Set policy options based on the provided dictionary keys.
537 if (!(policyRef
&& properties
&& (CFDictionaryGetTypeID() == CFGetTypeID(properties
)))) {
540 CFStringRef oid
= (CFStringRef
) CFRetain(policyRef
->_oid
);
541 OSStatus result
= errSecSuccess
;
544 CFTypeRef name
= NULL
;
545 if (CFDictionaryGetValueIfPresent(properties
, (const void *)kSecPolicyName
,
546 (const void **)&name
) && name
) {
547 CFTypeID typeID
= CFGetTypeID(name
);
548 if (CFEqual(oid
, kSecPolicyAppleSSL
) ||
549 CFEqual(oid
, kSecPolicyAppleIPsec
)) {
550 if (CFStringGetTypeID() == typeID
) {
551 SecPolicySetOptionsValue(policyRef
, kSecPolicyCheckSSLHostname
, name
);
553 else result
= errSecParam
;
555 else if (CFEqual(oid
, kSecPolicyAppleEAP
)) {
556 if ((CFStringGetTypeID() == typeID
) ||
557 (CFArrayGetTypeID() == typeID
)) {
558 SecPolicySetOptionsValue(policyRef
, kSecPolicyCheckEAPTrustedServerNames
, name
);
560 else result
= errSecParam
;
562 else if (CFEqual(oid
, kSecPolicyAppleSMIME
)) {
563 if (CFStringGetTypeID() == typeID
) {
564 SecPolicySetOptionsValue(policyRef
, kSecPolicyCheckEmail
, name
);
566 else result
= errSecParam
;
571 CFTypeRef client
= NULL
;
572 if (CFDictionaryGetValueIfPresent(properties
, (const void *)kSecPolicyClient
,
573 (const void **)&client
) && client
) {
574 if (!(CFBooleanGetTypeID() == CFGetTypeID(client
))) {
575 result
= errSecParam
;
577 else if (CFEqual(client
, kCFBooleanTrue
)) {
578 if (CFEqual(oid
, kSecPolicyAppleSSL
)) {
579 SecPolicySetName(policyRef
, kSecPolicyNameSSLClient
);
580 /* Set EKU checks for clients */
581 CFMutableDictionaryRef newOptions
= CFDictionaryCreateMutableCopy(NULL
, 0, policyRef
->_options
);
582 set_ssl_ekus(newOptions
, false);
583 CFReleaseSafe(policyRef
->_options
);
584 policyRef
->_options
= newOptions
;
586 else if (CFEqual(oid
, kSecPolicyAppleIPsec
)) {
587 SecPolicySetName(policyRef
, kSecPolicyNameIPSecClient
);
589 else if (CFEqual(oid
, kSecPolicyNameEAPServer
)) {
590 SecPolicySetName(policyRef
, kSecPolicyNameEAPClient
);
591 /* Set EKU checks for clients */
592 CFMutableDictionaryRef newOptions
= CFDictionaryCreateMutableCopy(NULL
, 0, policyRef
->_options
);
593 set_ssl_ekus(newOptions
, false);
594 CFReleaseSafe(policyRef
->_options
);
595 policyRef
->_options
= newOptions
;
599 if (CFEqual(oid
, kSecPolicyAppleSSL
)) {
600 SecPolicySetName(policyRef
, kSecPolicyNameSSLServer
);
601 /* Set EKU checks for servers */
602 CFMutableDictionaryRef newOptions
= CFDictionaryCreateMutableCopy(NULL
, 0, policyRef
->_options
);
603 set_ssl_ekus(newOptions
, true);
604 CFReleaseSafe(policyRef
->_options
);
605 policyRef
->_options
= newOptions
;
607 else if (CFEqual(oid
, kSecPolicyAppleIPsec
)) {
608 SecPolicySetName(policyRef
, kSecPolicyNameIPSecServer
);
610 else if (CFEqual(oid
, kSecPolicyAppleEAP
)) {
611 SecPolicySetName(policyRef
, kSecPolicyNameEAPServer
);
612 /* Set EKU checks for servers */
613 CFMutableDictionaryRef newOptions
= CFDictionaryCreateMutableCopy(NULL
, 0, policyRef
->_options
);
614 set_ssl_ekus(newOptions
, true);
615 CFReleaseSafe(policyRef
->_options
);
616 policyRef
->_options
= newOptions
;
622 set_ku_from_properties(policyRef
, properties
);
628 static xpc_object_t
copy_xpc_policy_object(SecPolicyRef policy
);
629 static bool append_policy_to_xpc_array(SecPolicyRef policy
, xpc_object_t xpc_policies
);
630 extern xpc_object_t
copy_xpc_policies_array(CFArrayRef policies
);
631 extern OSStatus
validate_array_of_items(CFArrayRef array
, CFStringRef arrayItemType
, CFTypeID itemTypeID
, bool required
);
633 static xpc_object_t
copy_xpc_policy_object(SecPolicyRef policy
) {
634 xpc_object_t xpc_policy
= NULL
;
635 xpc_object_t data
[2] = { NULL
, NULL
};
636 if (policy
->_oid
&& (CFGetTypeID(policy
->_oid
) == CFStringGetTypeID()) &&
637 policy
->_name
&& (CFGetTypeID(policy
->_name
) == CFStringGetTypeID())) {
638 /* These should really be different elements of the xpc array. But
639 * SecPolicyCreateWithXPCObject previously checked the size via ==, which prevents
640 * us from appending new information while maintaining backward compatibility.
641 * Doing this makes the builders happy. */
642 CFMutableStringRef oidAndName
= NULL
;
643 oidAndName
= CFStringCreateMutableCopy(NULL
, 0, policy
->_oid
);
645 CFStringAppend(oidAndName
, CFSTR("++"));
646 CFStringAppend(oidAndName
, policy
->_name
);
647 data
[0] = _CFXPCCreateXPCObjectFromCFObject(oidAndName
);
648 CFReleaseNull(oidAndName
);
650 data
[0] = _CFXPCCreateXPCObjectFromCFObject(policy
->_oid
);
652 } else if (policy
->_oid
&& (CFGetTypeID(policy
->_oid
) == CFStringGetTypeID())) {
653 data
[0] = _CFXPCCreateXPCObjectFromCFObject(policy
->_oid
);
655 secerror("policy 0x%lX has no _oid", (uintptr_t)policy
);
657 if (policy
->_options
&& (CFGetTypeID(policy
->_options
) == CFDictionaryGetTypeID())) {
658 data
[1] = _CFXPCCreateXPCObjectFromCFObject(policy
->_options
);
660 secerror("policy 0x%lX has no _options", (uintptr_t)policy
);
662 xpc_policy
= xpc_array_create(data
, array_size(data
));
663 if (data
[0]) xpc_release(data
[0]);
664 if (data
[1]) xpc_release(data
[1]);
668 static bool append_policy_to_xpc_array(SecPolicyRef policy
, xpc_object_t xpc_policies
) {
672 xpc_object_t xpc_policy
= copy_xpc_policy_object(policy
);
676 xpc_array_append_value(xpc_policies
, xpc_policy
);
677 xpc_release(xpc_policy
);
681 xpc_object_t
copy_xpc_policies_array(CFArrayRef policies
) {
682 xpc_object_t xpc_policies
= xpc_array_create(NULL
, 0);
686 validate_array_of_items(policies
, CFSTR("policy"), SecPolicyGetTypeID(), true);
687 CFIndex ix
, count
= CFArrayGetCount(policies
);
688 for (ix
= 0; ix
< count
; ++ix
) {
689 SecPolicyRef policy
= (SecPolicyRef
) CFArrayGetValueAtIndex(policies
, ix
);
690 #if SECTRUST_VERBOSE_DEBUG
691 CFDictionaryRef props
= SecPolicyCopyProperties(policy
);
692 secerror("idx=%d of %d; policy=0x%lX properties=%@", (int)ix
, (int)count
, (uintptr_t)policy
, props
);
693 CFReleaseSafe(props
);
695 if (!append_policy_to_xpc_array(policy
, xpc_policies
)) {
696 xpc_release(xpc_policies
);
704 static xpc_object_t
SecPolicyCopyXPCObject(SecPolicyRef policy
, CFErrorRef
*error
) {
705 xpc_object_t xpc_policy
= NULL
;
706 xpc_object_t data
[2] = {};
707 CFMutableStringRef oidAndName
= NULL
;
708 oidAndName
= CFStringCreateMutableCopy(NULL
, 0, policy
->_oid
);
711 CFStringAppend(oidAndName
, CFSTR("++"));
712 CFStringAppend(oidAndName
, policy
->_name
);
715 require_action_quiet(data
[0] = _CFXPCCreateXPCObjectFromCFObject(oidAndName
), exit
,
716 SecError(errSecParam
, error
,
717 CFSTR("failed to create xpc_object from policy oid and name")));
719 require_action_quiet(data
[0] = _CFXPCCreateXPCObjectFromCFObject(policy
->_oid
), exit
,
720 SecError(errSecParam
, error
, CFSTR("failed to create xpc_object from policy oid")));
722 require_action_quiet(data
[1] = _CFXPCCreateXPCObjectFromCFObject(policy
->_options
), exit
,
723 SecError(errSecParam
, error
, CFSTR("failed to create xpc_object from policy options")));
724 require_action_quiet(xpc_policy
= xpc_array_create(data
, array_size(data
)), exit
,
725 SecError(errSecAllocate
, error
, CFSTR("failed to create xpc_array for policy")));
728 if (data
[0]) xpc_release(data
[0]);
729 if (data
[1]) xpc_release(data
[1]);
730 CFReleaseNull(oidAndName
);
734 static bool SecPolicyAppendToXPCArray(SecPolicyRef policy
, xpc_object_t policies
, CFErrorRef
*error
) {
738 xpc_object_t xpc_policy
= SecPolicyCopyXPCObject(policy
, error
);
742 xpc_array_append_value(policies
, xpc_policy
);
743 xpc_release(xpc_policy
);
747 xpc_object_t
SecPolicyArrayCopyXPCArray(CFArrayRef policies
, CFErrorRef
*error
) {
748 xpc_object_t xpc_policies
;
749 require_action_quiet(xpc_policies
= xpc_array_create(NULL
, 0), exit
,
750 SecError(errSecAllocate
, error
, CFSTR("failed to create xpc_array")));
751 CFIndex ix
, count
= CFArrayGetCount(policies
);
752 for (ix
= 0; ix
< count
; ++ix
) {
753 if (!SecPolicyAppendToXPCArray((SecPolicyRef
)CFArrayGetValueAtIndex(policies
, ix
), xpc_policies
, error
)) {
754 xpc_release(xpc_policies
);
762 static OSStatus
parseOidAndName(CFStringRef oidAndName
, CFStringRef
*oid
, CFStringRef
*name
) {
763 OSStatus result
= errSecSuccess
;
764 CFStringRef partial
= NULL
;
766 CFRange delimiter
= CFStringFind(oidAndName
, CFSTR("++"), 0);
767 if (delimiter
.length
!= 2) {
771 /* get first half: oid */
772 partial
= CFStringCreateWithSubstring(NULL
, oidAndName
, CFRangeMake(0, delimiter
.location
));
773 if (oid
) { *oid
= CFRetainSafe(partial
); }
774 CFReleaseNull(partial
);
776 /* get second half: name */
777 if (delimiter
.location
+ 2 >= CFStringGetLength(oidAndName
)) {
778 return errSecSuccess
; // name is optional
780 CFRange nameRange
= CFRangeMake(delimiter
.location
+2,
781 CFStringGetLength(oidAndName
) - delimiter
.location
- 2);
782 partial
= CFStringCreateWithSubstring(NULL
, oidAndName
, nameRange
);
783 if (name
) { *name
= CFRetainSafe(partial
); }
784 CFReleaseNull(partial
);
788 static SecPolicyRef
SecPolicyCreateWithXPCObject(xpc_object_t xpc_policy
, CFErrorRef
*error
) {
789 SecPolicyRef policy
= NULL
;
790 CFTypeRef oidAndName
= NULL
;
791 CFStringRef oid
= NULL
;
792 CFStringRef name
= NULL
;
793 CFTypeRef options
= NULL
;
795 require_action_quiet(xpc_policy
, exit
, SecError(errSecParam
, error
, CFSTR("policy xpc value is NULL")));
796 require_action_quiet(xpc_get_type(xpc_policy
) == XPC_TYPE_ARRAY
, exit
, SecError(errSecDecode
, error
, CFSTR("policy xpc value is not an array")));
797 require_action_quiet(xpc_array_get_count(xpc_policy
) >= 2, exit
, SecError(errSecDecode
, error
, CFSTR("policy xpc array count < 2")));
798 oidAndName
= _CFXPCCreateCFObjectFromXPCObject(xpc_array_get_value(xpc_policy
, 0));
799 require_action_quiet(isString(oidAndName
), exit
,
800 SecError(errSecParam
, error
, CFSTR("failed to convert xpc policy[0]=%@ to CFString"), oidAndName
));
801 options
= _CFXPCCreateCFObjectFromXPCObject(xpc_array_get_value(xpc_policy
, 1));
802 require_action_quiet(isDictionary(options
), exit
,
803 SecError(errSecParam
, error
, CFSTR("failed to convert xpc policy[1]=%@ to CFDictionary"), options
));
804 require_noerr_action_quiet(parseOidAndName(oidAndName
, &oid
, &name
), exit
,
805 SecError(errSecParam
, error
, CFSTR("failed to convert combined %@ to name and oid"), oidAndName
));
806 require_action_quiet(policy
= SecPolicyCreate(oid
, name
, options
), exit
,
807 SecError(errSecDecode
, error
, CFSTR("Failed to create policy")));
810 CFReleaseSafe(oidAndName
);
813 CFReleaseSafe(options
);
817 CFArrayRef
SecPolicyXPCArrayCopyArray(xpc_object_t xpc_policies
, CFErrorRef
*error
) {
818 CFMutableArrayRef policies
= NULL
;
819 require_action_quiet(xpc_get_type(xpc_policies
) == XPC_TYPE_ARRAY
, exit
,
820 SecError(errSecParam
, error
, CFSTR("policies xpc value is not an array")));
821 size_t count
= xpc_array_get_count(xpc_policies
);
822 require_action_quiet(policies
= CFArrayCreateMutable(kCFAllocatorDefault
, count
, &kCFTypeArrayCallBacks
), exit
,
823 SecError(errSecAllocate
, error
, CFSTR("failed to create CFArray of capacity %zu"), count
));
826 for (ix
= 0; ix
< count
; ++ix
) {
827 SecPolicyRef policy
= SecPolicyCreateWithXPCObject(xpc_array_get_value(xpc_policies
, ix
), error
);
832 CFArraySetValueAtIndex(policies
, ix
, policy
);
841 static SEC_CONST_DECL (kSecPolicyOptions
, "policyOptions");
843 static SecPolicyRef
SecPolicyCreateWithDictionary(CFDictionaryRef dict
) {
844 SecPolicyRef policy
= NULL
;
845 CFStringRef oid
= (CFStringRef
)CFDictionaryGetValue(dict
, kSecPolicyOid
);
846 require_quiet(isString(oid
), errOut
);
847 CFDictionaryRef options
= (CFDictionaryRef
)CFDictionaryGetValue(dict
, kSecPolicyOptions
);
848 require_quiet(isDictionary(options
), errOut
);
849 CFStringRef name
= (CFStringRef
)CFDictionaryGetValue(dict
, kSecPolicyPolicyName
);
850 policy
= SecPolicyCreate(oid
, name
, options
);
855 static void deserializePolicy(const void *value
, void *context
) {
856 CFDictionaryRef policyDict
= (CFDictionaryRef
)value
;
857 if (isDictionary(policyDict
)) {
858 CFTypeRef deserializedPolicy
= SecPolicyCreateWithDictionary(policyDict
);
859 if (deserializedPolicy
) {
860 CFArrayAppendValue((CFMutableArrayRef
)context
, deserializedPolicy
);
861 CFRelease(deserializedPolicy
);
866 CFArrayRef
SecPolicyArrayCreateDeserialized(CFArrayRef serializedPolicies
) {
867 CFMutableArrayRef result
= NULL
;
868 require_quiet(isArray(serializedPolicies
), errOut
);
869 CFIndex count
= CFArrayGetCount(serializedPolicies
);
870 result
= CFArrayCreateMutable(kCFAllocatorDefault
, count
, &kCFTypeArrayCallBacks
);
871 CFRange all_policies
= { 0, count
};
872 CFArrayApplyFunction(serializedPolicies
, all_policies
, deserializePolicy
, result
);
877 static CFDictionaryRef
SecPolicyCreateDictionary(SecPolicyRef policy
) {
878 CFMutableDictionaryRef dict
= NULL
;
879 dict
= CFDictionaryCreateMutable(NULL
, 3, &kCFTypeDictionaryKeyCallBacks
,
880 &kCFTypeDictionaryValueCallBacks
);
881 CFDictionaryAddValue(dict
, kSecPolicyOid
, policy
->_oid
);
882 CFDictionaryAddValue(dict
, kSecPolicyOptions
, policy
->_options
);
884 CFDictionaryAddValue(dict
, kSecPolicyPolicyName
, policy
->_name
);
889 static void serializePolicy(const void *value
, void *context
) {
890 SecPolicyRef policy
= (SecPolicyRef
)value
;
891 if (policy
&& SecPolicyGetTypeID() == CFGetTypeID(policy
)) {
892 CFDictionaryRef serializedPolicy
= SecPolicyCreateDictionary(policy
);
893 if (serializedPolicy
) {
894 CFArrayAppendValue((CFMutableArrayRef
)context
, serializedPolicy
);
895 CFRelease(serializedPolicy
);
900 CFArrayRef
SecPolicyArrayCreateSerialized(CFArrayRef policies
) {
901 CFMutableArrayRef result
= NULL
;
902 require_quiet(isArray(policies
), errOut
);
903 CFIndex count
= CFArrayGetCount(policies
);
904 result
= CFArrayCreateMutable(NULL
, count
, &kCFTypeArrayCallBacks
);
905 CFRange all_policies
= { 0, count
};
906 CFArrayApplyFunction(policies
, all_policies
, serializePolicy
, result
);
911 static void add_element(CFMutableDictionaryRef options
, CFStringRef key
,
913 CFTypeRef old_value
= CFDictionaryGetValue(options
, key
);
915 CFMutableArrayRef array
;
916 if (CFGetTypeID(old_value
) == CFArrayGetTypeID()) {
917 array
= (CFMutableArrayRef
)old_value
;
919 array
= CFArrayCreateMutable(kCFAllocatorDefault
, 0,
920 &kCFTypeArrayCallBacks
);
921 CFArrayAppendValue(array
, old_value
);
922 CFDictionarySetValue(options
, key
, array
);
925 CFArrayAppendValue(array
, value
);
927 CFDictionaryAddValue(options
, key
, value
);
931 static void add_eku(CFMutableDictionaryRef options
, const DERItem
*ekuOid
) {
932 CFDataRef eku
= CFDataCreate(kCFAllocatorDefault
,
933 ekuOid
? ekuOid
->data
: NULL
,
934 ekuOid
? ekuOid
->length
: 0);
936 add_element(options
, kSecPolicyCheckExtendedKeyUsage
, eku
);
941 static void add_eku_string(CFMutableDictionaryRef options
, CFStringRef ekuOid
) {
943 add_element(options
, kSecPolicyCheckExtendedKeyUsage
, ekuOid
);
947 static void set_ssl_ekus(CFMutableDictionaryRef options
, bool server
) {
948 CFDictionaryRemoveValue(options
, kSecPolicyCheckExtendedKeyUsage
);
950 /* If server and EKU ext present then EKU ext should contain one of
951 ServerAuth or ExtendedKeyUsageAny or NetscapeSGC or MicrosoftSGC.
952 else if !server and EKU ext present then EKU ext should contain one of
953 ClientAuth or ExtendedKeyUsageAny. */
955 /* We always allow certificates that specify oidAnyExtendedKeyUsage. */
956 add_eku(options
, NULL
); /* eku extension is optional */
957 add_eku(options
, &oidAnyExtendedKeyUsage
);
959 add_eku(options
, &oidExtendedKeyUsageServerAuth
);
960 add_eku(options
, &oidExtendedKeyUsageMicrosoftSGC
);
961 add_eku(options
, &oidExtendedKeyUsageNetscapeSGC
);
963 add_eku(options
, &oidExtendedKeyUsageClientAuth
);
967 static void add_ku(CFMutableDictionaryRef options
, SecKeyUsage keyUsage
) {
968 SInt32 dku
= keyUsage
;
969 CFNumberRef ku
= CFNumberCreate(kCFAllocatorDefault
, kCFNumberSInt32Type
,
972 add_element(options
, kSecPolicyCheckKeyUsage
, ku
);
978 static void set_ku_from_properties(SecPolicyRef policy
, CFDictionaryRef properties
) {
979 if (!policy
|| !properties
) {
983 CFStringRef keyNames
[] = { kSecPolicyKU_DigitalSignature
, kSecPolicyKU_NonRepudiation
, kSecPolicyKU_KeyEncipherment
, kSecPolicyKU_DataEncipherment
,
984 kSecPolicyKU_KeyAgreement
, kSecPolicyKU_KeyCertSign
, kSecPolicyKU_CRLSign
, kSecPolicyKU_EncipherOnly
, kSecPolicyKU_DecipherOnly
};
986 uint32_t keyUsageValues
[] = { kSecKeyUsageDigitalSignature
, kSecKeyUsageNonRepudiation
, kSecKeyUsageKeyEncipherment
, kSecKeyUsageDataEncipherment
,
987 kSecKeyUsageKeyAgreement
, kSecKeyUsageKeyCertSign
, kSecKeyUsageCRLSign
, kSecKeyUsageEncipherOnly
, kSecKeyUsageDecipherOnly
};
989 bool haveKeyUsage
= false;
990 CFTypeRef keyUsageBoolean
;
991 for (uint32_t i
= 0; i
< sizeof(keyNames
) / sizeof(CFStringRef
); ++i
) {
992 if (CFDictionaryGetValueIfPresent(properties
, keyNames
[i
], (const void**)&keyUsageBoolean
)) {
993 if (CFEqual(keyUsageBoolean
, kCFBooleanTrue
)) {
1000 if (!haveKeyUsage
) {
1004 CFMutableDictionaryRef options
= (CFMutableDictionaryRef
) policy
->_options
;
1006 options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1007 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
1008 if (!options
) return;
1009 policy
->_options
= options
;
1011 CFDictionaryRemoveValue(options
, kSecPolicyCheckKeyUsage
);
1014 for (uint32_t i
= 0; i
< sizeof(keyNames
) / sizeof(CFStringRef
); ++i
) {
1015 if (CFDictionaryGetValueIfPresent(properties
, keyNames
[i
], (const void**)&keyUsageBoolean
)) {
1016 if (CFEqual(keyUsageBoolean
, kCFBooleanTrue
)) {
1017 add_ku(options
, keyUsageValues
[i
]);
1024 static void add_oid(CFMutableDictionaryRef options
, CFStringRef policy_key
, const DERItem
*oid
) {
1025 CFDataRef oid_data
= CFDataCreate(kCFAllocatorDefault
,
1026 oid
? oid
->data
: NULL
,
1027 oid
? oid
->length
: 0);
1029 add_element(options
, policy_key
, oid_data
);
1030 CFRelease(oid_data
);
1034 static void add_leaf_marker_value(CFMutableDictionaryRef options
, const DERItem
*markerOid
, CFStringRef string_value
) {
1036 CFTypeRef policyData
= NULL
;
1038 if (NULL
== string_value
) {
1039 policyData
= CFDataCreate(kCFAllocatorDefault
,
1040 markerOid
? markerOid
->data
: NULL
,
1041 markerOid
? markerOid
->length
: 0);
1043 CFStringRef oid_as_string
= SecDERItemCopyOIDDecimalRepresentation(kCFAllocatorDefault
, markerOid
);
1045 const void *key
[1] = { oid_as_string
};
1046 const void *value
[1] = { string_value
};
1047 policyData
= CFDictionaryCreate(kCFAllocatorDefault
,
1049 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
1050 CFReleaseNull(oid_as_string
);
1053 add_element(options
, kSecPolicyCheckLeafMarkerOid
, policyData
);
1055 CFReleaseNull(policyData
);
1059 static void add_leaf_marker(CFMutableDictionaryRef options
, const DERItem
*markerOid
) {
1060 add_leaf_marker_value(options
, markerOid
, NULL
);
1063 static void add_leaf_marker_value_string(CFMutableDictionaryRef options
, CFStringRef markerOid
, CFStringRef string_value
) {
1064 if (NULL
== string_value
) {
1065 add_element(options
, kSecPolicyCheckLeafMarkerOid
, markerOid
);
1067 CFDictionaryRef policyData
= NULL
;
1068 const void *key
[1] = { markerOid
};
1069 const void *value
[1] = { string_value
};
1070 policyData
= CFDictionaryCreate(kCFAllocatorDefault
,
1072 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
1073 add_element(options
, kSecPolicyCheckLeafMarkerOid
, policyData
);
1075 CFReleaseNull(policyData
);
1079 static void add_leaf_marker_string(CFMutableDictionaryRef options
, CFStringRef markerOid
) {
1080 add_leaf_marker_value_string(options
, markerOid
, NULL
);
1083 static void add_leaf_prod_qa_element(CFMutableDictionaryRef options
, CFTypeRef prodValue
, CFTypeRef qaValue
)
1085 CFMutableDictionaryRef prodAndQADictionary
= CFDictionaryCreateMutable(NULL
, 0, &kCFTypeDictionaryKeyCallBacks
,
1086 &kCFTypeDictionaryValueCallBacks
);
1087 CFDictionaryRef old_value
= CFDictionaryGetValue(options
, kSecPolicyCheckLeafMarkersProdAndQA
);
1089 CFMutableArrayRef prodArray
= NULL
, qaArray
= NULL
;
1090 CFTypeRef old_prod_value
= CFDictionaryGetValue(old_value
, kSecPolicyLeafMarkerProd
);
1091 CFTypeRef old_qa_value
= CFDictionaryGetValue(old_value
, kSecPolicyLeafMarkerQA
);
1092 if (isArray(old_prod_value
) && isArray(old_qa_value
)) {
1093 prodArray
= (CFMutableArrayRef
)CFRetainSafe(old_prod_value
);
1094 qaArray
= (CFMutableArrayRef
)CFRetainSafe(old_qa_value
);
1096 prodArray
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
1097 qaArray
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
1098 CFArrayAppendValue(prodArray
, old_prod_value
);
1099 CFArrayAppendValue(qaArray
, old_qa_value
);
1101 CFArrayAppendValue(prodArray
, prodValue
);
1102 CFArrayAppendValue(qaArray
, qaValue
);
1103 CFDictionaryAddValue(prodAndQADictionary
, kSecPolicyLeafMarkerProd
, prodArray
);
1104 CFDictionaryAddValue(prodAndQADictionary
, kSecPolicyLeafMarkerQA
, qaArray
);
1105 CFReleaseNull(prodArray
);
1106 CFReleaseNull(qaArray
);
1109 CFDictionaryAddValue(prodAndQADictionary
, kSecPolicyLeafMarkerProd
, prodValue
);
1110 CFDictionaryAddValue(prodAndQADictionary
, kSecPolicyLeafMarkerQA
, qaValue
);
1112 CFDictionarySetValue(options
, kSecPolicyCheckLeafMarkersProdAndQA
, prodAndQADictionary
);
1113 CFReleaseNull(prodAndQADictionary
);
1117 static void add_leaf_prod_qa_markers(CFMutableDictionaryRef options
, const DERItem
*prodMarkerOid
, const DERItem
*qaMarkerOid
)
1119 CFDataRef prodData
= NULL
, qaData
= NULL
;
1120 prodData
= CFDataCreate(NULL
, prodMarkerOid
? prodMarkerOid
->data
: NULL
,
1121 prodMarkerOid
? prodMarkerOid
->length
: 0);
1122 qaData
= CFDataCreate(NULL
, qaMarkerOid
? qaMarkerOid
->data
: NULL
,
1123 qaMarkerOid
? qaMarkerOid
->length
: 0);
1124 add_leaf_prod_qa_element(options
, prodData
, qaData
);
1125 CFReleaseNull(prodData
);
1126 CFReleaseNull(qaData
);
1129 static void add_leaf_prod_qa_markers_string(CFMutableDictionaryRef options
, CFStringRef prodMarkerOid
, CFStringRef qaMarkerOid
)
1131 add_leaf_prod_qa_element(options
, prodMarkerOid
, qaMarkerOid
);
1134 static void add_leaf_prod_qa_markers_value_string(CFMutableDictionaryRef options
,
1135 CFStringRef prodMarkerOid
, CFStringRef prod_value
,
1136 CFStringRef qaMarkerOid
, CFStringRef qa_value
)
1138 if (!prod_value
&& !qa_value
) {
1139 add_leaf_prod_qa_element(options
, prodMarkerOid
, qaMarkerOid
);
1141 CFDictionaryRef prodData
= NULL
, qaData
= NULL
;
1142 const void *prodKey
[1] = { prodMarkerOid
}, *qaKey
[1] = { qaMarkerOid
};
1143 const void *prodValue
[1] = { prod_value
}, *qaValue
[1] = { qa_value
};
1144 prodData
= CFDictionaryCreate(NULL
, prodKey
, prodValue
, 1, &kCFTypeDictionaryKeyCallBacks
,
1145 &kCFTypeDictionaryValueCallBacks
);
1146 qaData
= CFDictionaryCreate(NULL
, qaKey
, qaValue
, 1, &kCFTypeDictionaryKeyCallBacks
,
1147 &kCFTypeDictionaryValueCallBacks
);
1148 add_leaf_prod_qa_element(options
, prodData
, qaData
);
1149 CFReleaseNull(prodData
);
1150 CFReleaseNull(qaData
);
1154 static void add_intermediate_marker_value_string(CFMutableDictionaryRef options
, CFStringRef markerOid
, CFStringRef string_value
) {
1155 if (NULL
== string_value
) {
1156 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, markerOid
);
1158 CFDictionaryRef policyData
= NULL
;
1159 const void *key
[1] = { markerOid
};
1160 const void *value
[1] = { string_value
};
1161 policyData
= CFDictionaryCreate(kCFAllocatorDefault
,
1163 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
1164 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, policyData
);
1166 CFReleaseNull(policyData
);
1170 static void add_certificate_policy_oid(CFMutableDictionaryRef options
, const DERItem
*certificatePolicyOid
) {
1171 CFTypeRef certificatePolicyData
= NULL
;
1172 certificatePolicyData
= CFDataCreate(kCFAllocatorDefault
,
1173 certificatePolicyOid
? certificatePolicyOid
->data
: NULL
,
1174 certificatePolicyOid
? certificatePolicyOid
->length
: 0);
1175 if (certificatePolicyData
) {
1176 add_element(options
, kSecPolicyCheckCertificatePolicy
, certificatePolicyData
);
1177 CFRelease(certificatePolicyData
);
1181 static void add_certificate_policy_oid_string(CFMutableDictionaryRef options
, CFStringRef certificatePolicyOid
) {
1182 if (certificatePolicyOid
) {
1183 add_element(options
, kSecPolicyCheckCertificatePolicy
, certificatePolicyOid
);
1188 // Routines for adding dictionary entries for policies.
1191 // X.509, but missing validity requirements.
1192 static void SecPolicyAddBasicCertOptions(CFMutableDictionaryRef options
)
1194 //CFDictionaryAddValue(options, kSecPolicyCheckBasicCertificateProcessing, kCFBooleanTrue);
1195 // Happens automatically in SecPVCPathChecks
1196 CFDictionaryAddValue(options
, kSecPolicyCheckCriticalExtensions
, kCFBooleanTrue
);
1197 CFDictionaryAddValue(options
, kSecPolicyCheckIdLinkage
, kCFBooleanTrue
);
1198 CFDictionaryAddValue(options
, kSecPolicyCheckBasicConstraints
, kCFBooleanTrue
);
1199 CFDictionaryAddValue(options
, kSecPolicyCheckNonEmptySubject
, kCFBooleanTrue
);
1200 CFDictionaryAddValue(options
, kSecPolicyCheckWeakKeySize
, kCFBooleanTrue
);
1201 CFDictionaryAddValue(options
, kSecPolicyCheckWeakSignature
, kCFBooleanTrue
);
1204 static void SecPolicyAddBasicX509Options(CFMutableDictionaryRef options
)
1206 SecPolicyAddBasicCertOptions(options
);
1207 CFDictionaryAddValue(options
, kSecPolicyCheckTemporalValidity
, kCFBooleanTrue
);
1209 // Make sure that black and gray leaf checks are performed for basic X509 chain building
1210 CFDictionaryAddValue(options
, kSecPolicyCheckBlackListedLeaf
, kCFBooleanTrue
);
1211 CFDictionaryAddValue(options
, kSecPolicyCheckGrayListedLeaf
, kCFBooleanTrue
);
1214 static bool SecPolicyAddChainLengthOptions(CFMutableDictionaryRef options
, CFIndex length
)
1216 bool result
= false;
1217 CFNumberRef lengthAsCF
= NULL
;
1219 require(lengthAsCF
= CFNumberCreate(kCFAllocatorDefault
,
1220 kCFNumberCFIndexType
, &length
), errOut
);
1221 CFDictionaryAddValue(options
, kSecPolicyCheckChainLength
, lengthAsCF
);
1226 CFReleaseSafe(lengthAsCF
);
1230 static bool SecPolicyAddAnchorSHA1Options(CFMutableDictionaryRef options
,
1231 const UInt8 anchorSha1
[kSecPolicySHA1Size
])
1233 bool success
= false;
1234 CFDataRef anchorData
= NULL
;
1236 require(anchorData
= CFDataCreate(kCFAllocatorDefault
, anchorSha1
, kSecPolicySHA1Size
), errOut
);
1237 add_element(options
, kSecPolicyCheckAnchorSHA1
, anchorData
);
1242 CFReleaseSafe(anchorData
);
1246 static bool SecPolicyAddAnchorSHA256Options(CFMutableDictionaryRef options
,
1247 const UInt8 anchorSha1
[kSecPolicySHA256Size
])
1249 bool success
= false;
1250 CFDataRef anchorData
= NULL
;
1252 require(anchorData
= CFDataCreate(kCFAllocatorDefault
, anchorSha1
, kSecPolicySHA256Size
), errOut
);
1253 add_element(options
, kSecPolicyCheckAnchorSHA256
, anchorData
);
1258 CFReleaseSafe(anchorData
);
1262 static bool SecPolicyAddStrongKeySizeOptions(CFMutableDictionaryRef options
) {
1263 bool success
= false;
1264 CFDictionaryRef keySizes
= NULL
;
1265 CFNumberRef rsaSize
= NULL
, ecSize
= NULL
;
1267 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
1268 require(rsaSize
= CFNumberCreateWithCFIndex(NULL
, 2048), errOut
);
1269 require(ecSize
= CFNumberCreateWithCFIndex(NULL
, 256), errOut
);
1270 const void *keys
[] = { kSecAttrKeyTypeRSA
, kSecAttrKeyTypeEC
};
1271 const void *values
[] = { rsaSize
, ecSize
};
1272 require(keySizes
= CFDictionaryCreate(NULL
, keys
, values
, 2,
1273 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1274 add_element(options
, kSecPolicyCheckKeySize
, keySizes
);
1279 CFReleaseSafe(keySizes
);
1280 CFReleaseSafe(rsaSize
);
1281 CFReleaseSafe(ecSize
);
1285 static bool SecPolicyRemoveWeakHashOptions(CFMutableDictionaryRef options
) {
1286 CFMutableArrayRef disallowedHashes
= CFArrayCreateMutable(NULL
, 5, &kCFTypeArrayCallBacks
);
1287 if (!disallowedHashes
) {
1290 CFArrayAppendValue(disallowedHashes
, kSecSignatureDigestAlgorithmMD2
);
1291 CFArrayAppendValue(disallowedHashes
, kSecSignatureDigestAlgorithmMD4
);
1292 CFArrayAppendValue(disallowedHashes
, kSecSignatureDigestAlgorithmMD5
);
1293 CFArrayAppendValue(disallowedHashes
, kSecSignatureDigestAlgorithmSHA1
);
1295 add_element(options
, kSecPolicyCheckSignatureHashAlgorithms
, disallowedHashes
);
1296 CFReleaseNull(disallowedHashes
);
1300 static bool isAppleOid(CFStringRef oid
) {
1301 if (!SecCertificateIsOidString(oid
)) {
1304 if (CFStringHasPrefix(oid
, CFSTR("1.2.840.113635"))) {
1310 static bool isCFPreferenceInSecurityDomain(CFStringRef setting
) {
1311 return (CFPreferencesGetAppBooleanValue(setting
, CFSTR("com.apple.security"), NULL
));
1314 static bool SecPolicyAddAppleAnchorOptions(CFMutableDictionaryRef options
, CFStringRef __unused policyName
)
1316 CFMutableDictionaryRef appleAnchorOptions
= NULL
;
1317 appleAnchorOptions
= CFDictionaryCreateMutableForCFTypes(NULL
);
1318 if (!appleAnchorOptions
) {
1322 /* Currently no Apple Anchor options */
1323 add_element(options
, kSecPolicyCheckAnchorApple
, appleAnchorOptions
);
1324 CFReleaseSafe(appleAnchorOptions
);
1328 static bool SecPolicyAddPinningRequiredIfInfoSpecified(CFMutableDictionaryRef options
)
1330 CFBundleRef bundle
= CFBundleGetMainBundle();
1332 CFTypeRef value
= CFBundleGetValueForInfoDictionaryKey(bundle
, CFSTR("SecTrustPinningRequired"));
1333 if (isBoolean(value
) && CFBooleanGetValue(value
)) {
1334 add_element(options
, kSecPolicyCheckPinningRequired
, kCFBooleanTrue
);
1343 // MARK: Policy Creation Functions
1345 SecPolicyRef
SecPolicyCreateBasicX509(void) {
1346 CFMutableDictionaryRef options
= NULL
;
1347 SecPolicyRef result
= NULL
;
1349 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1350 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1352 SecPolicyAddBasicX509Options(options
);
1353 CFDictionaryAddValue(options
, kSecPolicyCheckNoNetworkAccess
,
1356 require(result
= SecPolicyCreate(kSecPolicyAppleX509Basic
, kSecPolicyNameX509Basic
, options
), errOut
);
1359 CFReleaseSafe(options
);
1360 return (SecPolicyRef _Nonnull
)result
;
1363 SecPolicyRef
SecPolicyCreateSSL(Boolean server
, CFStringRef hostname
) {
1364 CFMutableDictionaryRef options
= NULL
;
1365 SecPolicyRef result
= NULL
;
1367 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1368 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1370 SecPolicyAddBasicX509Options(options
);
1373 CFDictionaryAddValue(options
, kSecPolicyCheckSSLHostname
, hostname
);
1376 CFDictionaryAddValue(options
, kSecPolicyCheckBlackListedLeaf
, kCFBooleanTrue
);
1377 CFDictionaryAddValue(options
, kSecPolicyCheckGrayListedLeaf
, kCFBooleanTrue
);
1380 require_quiet(SecPolicyRemoveWeakHashOptions(options
), errOut
);
1381 require_quiet(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
1382 require_quiet(SecPolicyAddPinningRequiredIfInfoSpecified(options
), errOut
);
1383 CFDictionaryAddValue(options
, kSecPolicyCheckValidityPeriodMaximums
, kCFBooleanTrue
);
1384 CFDictionaryAddValue(options
, kSecPolicyCheckServerAuthEKU
, kCFBooleanTrue
); // enforces stricter EKU rules than set_ssl_ekus below for certain anchor types
1385 #if !TARGET_OS_BRIDGE
1386 CFDictionaryAddValue(options
, kSecPolicyCheckSystemTrustedCTRequired
, kCFBooleanTrue
);
1390 set_ssl_ekus(options
, server
);
1392 require(result
= SecPolicyCreate(kSecPolicyAppleSSL
,
1393 server
? kSecPolicyNameSSLServer
: kSecPolicyNameSSLClient
,
1397 CFReleaseSafe(options
);
1398 return (SecPolicyRef _Nonnull
)result
;
1401 SecPolicyRef
SecPolicyCreateLegacySSL(Boolean server
, CFStringRef hostname
) {
1402 CFMutableDictionaryRef options
= NULL
;
1403 SecPolicyRef result
= NULL
;
1405 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1406 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1408 SecPolicyAddBasicX509Options(options
);
1411 CFDictionaryAddValue(options
, kSecPolicyCheckSSLHostname
, hostname
);
1414 CFDictionaryAddValue(options
, kSecPolicyCheckBlackListedLeaf
, kCFBooleanTrue
);
1415 CFDictionaryAddValue(options
, kSecPolicyCheckGrayListedLeaf
, kCFBooleanTrue
);
1418 // fewer requirements than the standard SSL policy
1419 require_quiet(SecPolicyAddPinningRequiredIfInfoSpecified(options
), errOut
);
1420 CFDictionaryAddValue(options
, kSecPolicyCheckValidityPeriodMaximums
, kCFBooleanTrue
);
1421 #if !TARGET_OS_BRIDGE
1422 CFDictionaryAddValue(options
, kSecPolicyCheckSystemTrustedCTRequired
, kCFBooleanTrue
);
1426 set_ssl_ekus(options
, server
);
1428 require(result
= SecPolicyCreate(kSecPolicyAppleLegacySSL
, kSecPolicyNameLegacySSL
, options
), errOut
);
1431 CFReleaseSafe(options
);
1432 return (SecPolicyRef _Nonnull
)result
;
1435 SecPolicyRef
SecPolicyCreateApplePinned(CFStringRef policyName
, CFStringRef intermediateMarkerOID
, CFStringRef leafMarkerOID
) {
1436 CFMutableDictionaryRef options
= NULL
;
1437 SecPolicyRef result
= NULL
;
1439 if (!policyName
|| !intermediateMarkerOID
|| !leafMarkerOID
) {
1443 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1444 &kCFTypeDictionaryKeyCallBacks
,
1445 &kCFTypeDictionaryValueCallBacks
), errOut
);
1447 SecPolicyAddBasicX509Options(options
);
1449 /* Anchored to the Apple Roots */
1450 require(SecPolicyAddAppleAnchorOptions(options
, policyName
), errOut
);
1452 /* Exactly 3 certs in the chain */
1453 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1455 /* Intermediate marker OID matches input OID */
1456 if (!isAppleOid(intermediateMarkerOID
)) {
1457 secwarning("creating an Apple pinning policy with a non-Apple OID: %@", intermediateMarkerOID
);
1459 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, intermediateMarkerOID
);
1461 /* Leaf marker OID matches input OID */
1462 if (!isAppleOid(leafMarkerOID
)) {
1463 secwarning("creating an Apple pinning policy with a non-Apple OID: %@", leafMarkerOID
);
1465 add_leaf_marker_string(options
, leafMarkerOID
);
1467 /* Check revocation using any available method */
1468 add_element(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
1470 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
1471 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
1473 /* Check for weak hashes */
1474 // require(SecPolicyRemoveWeakHashOptions(options), errOut); // the current WWDR CA cert is signed with SHA1
1475 require(result
= SecPolicyCreate(kSecPolicyAppleGenericApplePinned
,
1476 policyName
, options
), errOut
);
1479 CFReleaseSafe(options
);
1484 requireUATPinning(CFStringRef service
)
1486 bool pinningRequired
= true;
1488 if (SecIsInternalRelease()) {
1489 CFStringRef setting
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("AppleServerAuthenticationNoPinning%@"), service
);
1490 require(setting
, fail
);
1491 if(isCFPreferenceInSecurityDomain(setting
)) {
1492 pinningRequired
= false;
1494 secnotice("pinningQA", "could not disable pinning: %@ not true", setting
);
1498 if (!pinningRequired
) {
1502 if(isCFPreferenceInSecurityDomain(CFSTR("AppleServerAuthenticationNoPinning"))) {
1503 pinningRequired
= false;
1505 secnotice("pinningQA", "could not disable pinning: AppleServerAuthenticationNoPinning not true");
1508 secnotice("pinningQA", "could not disable pinning: not an internal release");
1511 return pinningRequired
;
1514 SecPolicyRef
SecPolicyCreateAppleSSLPinned(CFStringRef policyName
, CFStringRef hostname
,
1515 CFStringRef intermediateMarkerOID
, CFStringRef leafMarkerOID
) {
1516 CFMutableDictionaryRef options
= NULL
, appleAnchorOptions
= NULL
;
1517 SecPolicyRef result
= NULL
;
1519 if (!policyName
|| !hostname
|| !leafMarkerOID
) {
1523 if (requireUATPinning(policyName
)) {
1524 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1525 &kCFTypeDictionaryKeyCallBacks
,
1526 &kCFTypeDictionaryValueCallBacks
), errOut
);
1528 SecPolicyAddBasicX509Options(options
);
1530 /* Anchored to the Apple Roots */
1531 require(SecPolicyAddAppleAnchorOptions(options
, policyName
), errOut
);
1533 /* Exactly 3 certs in the chain */
1534 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1536 if (intermediateMarkerOID
) {
1537 /* Intermediate marker OID matches input OID */
1538 if (!isAppleOid(intermediateMarkerOID
)) {
1539 secwarning("creating an Apple pinning policy with a non-Apple OID: %@", intermediateMarkerOID
);
1541 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, intermediateMarkerOID
);
1543 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.12"));
1546 /* Leaf marker OID matches input OID */
1547 if (!isAppleOid(leafMarkerOID
)) {
1548 secwarning("creating an Apple pinning policy with a non-Apple OID: %@", leafMarkerOID
);
1550 add_leaf_marker_string(options
, leafMarkerOID
);
1552 /* New leaf marker OID format */
1553 add_leaf_marker_value_string(options
, CFSTR("1.2.840.113635.100.6.48.1"), leafMarkerOID
);
1555 /* ServerAuth EKU is in leaf cert */
1556 add_eku_string(options
, CFSTR("1.3.6.1.5.5.7.3.1"));
1558 /* Hostname is in leaf cert */
1559 add_element(options
, kSecPolicyCheckSSLHostname
, hostname
);
1561 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
1562 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
1564 /* Check for weak hashes */
1565 require(SecPolicyRemoveWeakHashOptions(options
), errOut
);
1567 /* Check revocation using any available method */
1568 add_element(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
1570 require(result
= SecPolicyCreate(kSecPolicyAppleGenericAppleSSLPinned
,
1571 policyName
, options
), errOut
);
1574 result
= SecPolicyCreateSSL(true, hostname
);
1575 SecPolicySetOid(result
, kSecPolicyAppleGenericAppleSSLPinned
);
1576 SecPolicySetName(result
, policyName
);
1580 CFReleaseSafe(options
);
1581 CFReleaseSafe(appleAnchorOptions
);
1585 SecPolicyRef
SecPolicyCreateiPhoneActivation(void) {
1586 CFMutableDictionaryRef options
= NULL
;
1587 SecPolicyRef result
= NULL
;
1589 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1590 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1592 SecPolicyAddBasicCertOptions(options
);
1595 CFDictionaryAddValue(options
, kSecPolicyCheckKeyUsage
,
1597 CFDictionaryAddValue(options
, kSecPolicyCheckExtendedKeyUsage
,
1601 /* Basic X.509 policy with the additional requirements that the chain
1602 length is 3, it's anchored at the AppleCA and the leaf certificate
1603 has issuer "Apple iPhone Certification Authority" and
1604 subject "Apple iPhone Activation" for the common name. */
1605 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
1606 CFSTR("Apple iPhone Certification Authority"));
1607 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
,
1608 CFSTR("Apple iPhone Activation"));
1610 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1611 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameiPhoneActivation
), errOut
);
1613 require(result
= SecPolicyCreate(kSecPolicyAppleiPhoneActivation
,
1614 kSecPolicyNameiPhoneActivation
, options
),
1618 CFReleaseSafe(options
);
1622 SecPolicyRef
SecPolicyCreateiPhoneDeviceCertificate(void) {
1623 CFMutableDictionaryRef options
= NULL
;
1624 SecPolicyRef result
= NULL
;
1626 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1627 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1629 SecPolicyAddBasicCertOptions(options
);
1632 CFDictionaryAddValue(options
, kSecPolicyCheckKeyUsage
,
1634 CFDictionaryAddValue(options
, kSecPolicyCheckExtendedKeyUsage
,
1638 /* Basic X.509 policy with the additional requirements that the chain
1639 length is 4, it's anchored at the AppleCA and the first intermediate
1640 has the subject "Apple iPhone Device CA". */
1641 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
1642 CFSTR("Apple iPhone Device CA"));
1644 require(SecPolicyAddChainLengthOptions(options
, 4), errOut
);
1645 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameiPhoneDeviceCertificate
), errOut
);
1647 require(result
= SecPolicyCreate(kSecPolicyAppleiPhoneDeviceCertificate
,
1648 kSecPolicyNameiPhoneDeviceCertificate
, options
),
1652 CFReleaseSafe(options
);
1656 SecPolicyRef
SecPolicyCreateFactoryDeviceCertificate(void) {
1657 CFMutableDictionaryRef options
= NULL
;
1658 SecPolicyRef result
= NULL
;
1660 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1661 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1663 SecPolicyAddBasicCertOptions(options
);
1666 CFDictionaryAddValue(options
, kSecPolicyCheckKeyUsage
,
1668 CFDictionaryAddValue(options
, kSecPolicyCheckExtendedKeyUsage
,
1672 /* Basic X.509 policy with the additional requirements that the chain
1673 is anchored at the factory device certificate issuer. */
1674 require(SecPolicyAddAnchorSHA1Options(options
, kFactoryDeviceCASHA1
), errOut
);
1676 require(result
= SecPolicyCreate(kSecPolicyAppleFactoryDeviceCertificate
,
1677 kSecPolicyNameFactoryDeviceCertificate
, options
),
1681 CFReleaseSafe(options
);
1685 SecPolicyRef
SecPolicyCreateiAP(void) {
1686 CFMutableDictionaryRef options
= NULL
;
1687 SecPolicyRef result
= NULL
;
1688 CFTimeZoneRef tz
= NULL
;
1689 CFDateRef date
= NULL
;
1691 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1692 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1694 SecPolicyAddBasicCertOptions(options
);
1696 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonNamePrefix
,
1699 date
= CFDateCreateForGregorianZuluDay(NULL
, 2006, 5, 31);
1700 CFDictionaryAddValue(options
, kSecPolicyCheckNotValidBefore
, date
);
1702 require(result
= SecPolicyCreate(kSecPolicyAppleiAP
,
1703 kSecPolicyNameiAP
, options
),
1707 CFReleaseSafe(date
);
1709 CFReleaseSafe(options
);
1713 SecPolicyRef
SecPolicyCreateiTunesStoreURLBag(void) {
1714 CFMutableDictionaryRef options
= NULL
;
1715 SecPolicyRef result
= NULL
;
1718 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1719 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1721 SecPolicyAddBasicCertOptions(options
);
1723 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectOrganization
,
1724 CFSTR("Apple Inc."));
1725 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
,
1726 CFSTR("iTunes Store URL Bag"));
1728 require(SecPolicyAddChainLengthOptions(options
, 2), errOut
);
1729 require(SecPolicyAddAnchorSHA1Options(options
, kITMSCASHA1
), errOut
);
1731 require(result
= SecPolicyCreate(kSecPolicyAppleiTunesStoreURLBag
,
1732 kSecPolicyNameiTunesStoreURLBag
, options
), errOut
);
1735 CFReleaseSafe(options
);
1739 SecPolicyRef
SecPolicyCreateEAP(Boolean server
, CFArrayRef trustedServerNames
) {
1740 CFMutableDictionaryRef options
= NULL
;
1741 SecPolicyRef result
= NULL
;
1743 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1744 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1746 SecPolicyAddBasicX509Options(options
);
1748 /* Since EAP is used to setup the network we don't want evaluation
1749 using this policy to access the network. */
1750 CFDictionaryAddValue(options
, kSecPolicyCheckNoNetworkAccess
,
1753 if (trustedServerNames
) {
1754 CFDictionaryAddValue(options
, kSecPolicyCheckEAPTrustedServerNames
, trustedServerNames
);
1758 /* Check for weak hashes and keys, but only on system-trusted roots, because enterprise
1759 * PKIs are the absolute worst. */
1760 CFDictionaryAddValue(options
, kSecPolicyCheckSystemTrustedWeakHash
, kCFBooleanTrue
);
1761 CFDictionaryAddValue(options
, kSecPolicyCheckSystemTrustedWeakKey
, kCFBooleanTrue
);
1764 /* We need to check for EKU per rdar://22206018 */
1765 set_ssl_ekus(options
, server
);
1767 require(result
= SecPolicyCreate(kSecPolicyAppleEAP
,
1768 server
? kSecPolicyNameEAPServer
: kSecPolicyNameEAPClient
,
1772 CFReleaseSafe(options
);
1776 SecPolicyRef
SecPolicyCreateIPSec(Boolean server
, CFStringRef hostname
) {
1777 CFMutableDictionaryRef options
= NULL
;
1778 SecPolicyRef result
= NULL
;
1780 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1781 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1783 SecPolicyAddBasicX509Options(options
);
1786 CFDictionaryAddValue(options
, kSecPolicyCheckSSLHostname
, hostname
);
1789 /* Require oidExtendedKeyUsageIPSec if Extended Keyusage Extention is
1791 /* Per <rdar://problem/6843827> Cisco VPN Certificate compatibility issue.
1792 We don't check the EKU for IPSec certs for now. If we do add eku
1793 checking back in the future, we should probably also accept the
1795 ipsecEndSystem 1.3.6.1.5.5.7.3.5
1797 ipsecTunnel 1.3.6.1.5.5.7.3.6
1798 ipsecUser 1.3.6.1.5.5.7.3.7
1800 //add_eku(options, NULL); /* eku extension is optional */
1801 //add_eku(options, &oidAnyExtendedKeyUsage);
1802 //add_eku(options, &oidExtendedKeyUsageIPSec);
1804 require(result
= SecPolicyCreate(kSecPolicyAppleIPsec
,
1805 server
? kSecPolicyNameIPSecServer
: kSecPolicyNameIPSecClient
,
1809 CFReleaseSafe(options
);
1813 SecPolicyRef
SecPolicyCreateiPhoneApplicationSigning(void) {
1814 CFMutableDictionaryRef options
= NULL
;
1815 SecPolicyRef result
= NULL
;
1817 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1818 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1820 SecPolicyAddBasicCertOptions(options
);
1822 /* Anchored to the Apple Roots */
1823 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameiPhoneApplicationSigning
), errOut
);
1826 if (SecIsInternalRelease()) {
1827 /* Allow a prod hierarchy-signed test cert */
1828 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonNameTEST
,
1829 CFSTR("Apple iPhone OS Application Signing"));
1830 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.3.1"));
1833 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
,
1834 CFSTR("Apple iPhone OS Application Signing"));
1836 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.3"));
1838 add_eku(options
, NULL
); /* eku extension is optional */
1839 add_eku(options
, &oidAnyExtendedKeyUsage
);
1840 add_eku(options
, &oidExtendedKeyUsageCodeSigning
);
1842 /* Intermediate check */
1843 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
1844 CFSTR("Apple iPhone Certification Authority"));
1846 /* Chain length check */
1847 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1849 /* Skip networked revocation checks */
1850 CFDictionaryAddValue(options
, kSecPolicyCheckNoNetworkAccess
, kCFBooleanTrue
);
1852 require(result
= SecPolicyCreate(kSecPolicyAppleiPhoneApplicationSigning
,
1853 kSecPolicyNameiPhoneApplicationSigning
, options
),
1857 CFReleaseSafe(options
);
1861 SecPolicyRef
SecPolicyCreateiPhoneVPNApplicationSigning(void) {
1862 CFMutableDictionaryRef options
= NULL
;
1863 SecPolicyRef result
= NULL
;
1865 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1866 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1868 SecPolicyAddBasicCertOptions(options
);
1870 /* Anchored to the Apple Roots */
1871 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameiPhoneVPNApplicationSigning
), errOut
);
1874 if (SecIsInternalRelease()) {
1875 /* Allow a prod hierarchy-signed test cert */
1876 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonNameTEST
,
1877 CFSTR("Apple iPhone OS Application Signing"));
1878 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.6.1"));
1881 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
,
1882 CFSTR("Apple iPhone OS Application Signing"));
1884 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.6"));
1886 add_eku(options
, NULL
); /* eku extension is optional */
1887 add_eku(options
, &oidAnyExtendedKeyUsage
);
1888 add_eku(options
, &oidExtendedKeyUsageCodeSigning
);
1890 /* Intermediate check */
1891 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
1892 CFSTR("Apple iPhone Certification Authority"));
1894 /* Chain length check */
1895 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1897 /* Skip networked revocation checks */
1898 CFDictionaryAddValue(options
, kSecPolicyCheckNoNetworkAccess
, kCFBooleanTrue
);
1900 require(result
= SecPolicyCreate(kSecPolicyAppleiPhoneVPNApplicationSigning
,
1901 kSecPolicyNameiPhoneVPNApplicationSigning
, options
),
1905 CFReleaseSafe(options
);
1909 SecPolicyRef
SecPolicyCreateiPhoneProfileApplicationSigning(void) {
1910 CFMutableDictionaryRef options
= NULL
;
1911 SecPolicyRef result
= NULL
;
1913 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1914 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1916 SecPolicyAddBasicX509Options(options
); // With expiration checking
1919 require_quiet(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameiPhoneProfileApplicationSigning
),
1923 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1925 /* Leaf has CodeSigning EKU */
1926 add_eku_string(options
, CFSTR("1.3.6.1.5.5.7.3.3"));
1928 /* On iOS, the cert in the provisioning profile may be one of:
1929 leaf OID intermediate OID
1930 iPhone Developer <ADS>.6.1.2 <ADS>.6.2.1
1931 iPhone Distribution <ADS>.6.1.4 <ADS>.6.2.1
1932 TestFlight (Prod) <ADS>.6.1.25.1 <ADS>.6.2.1
1933 TestFlight (QA) <ADS>.6.1.25.2 <ADS>.6.2.1
1935 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.1"));
1936 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.2"));
1937 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.4"));
1938 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.25.1"));
1939 if (SecIsInternalRelease()) {
1940 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.25.2"));
1943 /* Revocation via any available method */
1944 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
1946 require(result
= SecPolicyCreate(kSecPolicyAppleiPhoneProfileApplicationSigning
,
1947 kSecPolicyNameiPhoneProfileApplicationSigning
,
1951 CFReleaseSafe(options
);
1955 SecPolicyRef
SecPolicyCreateMacOSProfileApplicationSigning(void) {
1956 CFMutableDictionaryRef options
= NULL
;
1957 SecPolicyRef result
= NULL
;
1959 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1960 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1962 SecPolicyAddBasicCertOptions(options
); // Without expiration checking
1965 require_quiet(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameiPhoneProfileApplicationSigning
),
1969 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1971 /* Leaf has CodeSigning EKU */
1972 add_eku_string(options
, CFSTR("1.3.6.1.5.5.7.3.3"));
1975 /* On macOS, the cert in the provisioning profile may be one of:
1976 leaf OID intermediate OID
1977 MAS Development <ADS>.6.1.12 <ADS>.6.2.1
1978 MAS Submission <ADS>.6.1.7 <ADS>.6.2.1
1979 Developer ID <ADS>.6.1.13 <ADS>.6.2.6
1980 B&I <ADS>.6.22 None - "Apple Code Signing Certification Authority"
1982 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.12"));
1983 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.7"));
1984 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.13"));
1985 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.22"));
1987 /* Revocation via any available method */
1988 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
1990 require(result
= SecPolicyCreate(kSecPolicyAppleMacOSProfileApplicationSigning
,
1991 kSecPolicyNameMacOSProfileApplicationSigning
,
1995 CFReleaseSafe(options
);
1999 SecPolicyRef
SecPolicyCreateiPhoneProvisioningProfileSigning(void) {
2000 CFMutableDictionaryRef options
= NULL
;
2001 SecPolicyRef result
= NULL
;
2003 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2004 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2006 SecPolicyAddBasicCertOptions(options
);
2008 /* Basic X.509 policy with the additional requirements that the chain
2009 length is 3, it's anchored at the AppleCA and the leaf certificate
2010 has issuer "Apple iPhone Certification Authority" and
2011 subject "Apple iPhone OS Provisioning Profile Signing" for the common name. */
2012 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2013 CFSTR("Apple iPhone Certification Authority"));
2014 if (SecIsInternalRelease()) {
2015 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonNameTEST
,
2016 CFSTR("Apple iPhone OS Provisioning Profile Signing"));
2019 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
,
2020 CFSTR("Apple iPhone OS Provisioning Profile Signing"));
2023 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2024 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameiPhoneProvisioningProfileSigning
), errOut
);
2026 /* Skip networked revocation checks */
2027 CFDictionaryAddValue(options
, kSecPolicyCheckNoNetworkAccess
, kCFBooleanTrue
);
2029 require(result
= SecPolicyCreate(kSecPolicyAppleiPhoneProvisioningProfileSigning
,
2030 kSecPolicyNameiPhoneProvisioningProfileSigning
, options
),
2033 /* 1.2.840.113635.100.6.2.2.1, non-critical: DER:05:00 - provisioning profile */
2036 CFReleaseSafe(options
);
2040 SecPolicyRef
SecPolicyCreateAppleTVOSApplicationSigning(void) {
2041 CFMutableDictionaryRef options
= NULL
;
2042 SecPolicyRef result
= NULL
;
2043 CFDataRef atvProdOid
= NULL
;
2044 CFDataRef atvTestOid
= NULL
;
2045 CFArrayRef oids
= NULL
;
2047 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2048 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2050 SecPolicyAddBasicCertOptions(options
);
2052 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2054 require_quiet(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameTVOSApplicationSigning
),
2057 /* Check for intermediate: Apple Worldwide Developer Relations */
2058 /* 1.2.840.113635.100.6.2.1 */
2059 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleWWDR
);
2061 add_ku(options
, kSecKeyUsageDigitalSignature
);
2063 /* Check for prod or test AppleTV Application Signing OIDs */
2064 /* Prod: 1.2.840.113635.100.6.1.24 */
2065 /* ProdQA: 1.2.840.113635.100.6.1.24.1 */
2066 add_leaf_marker(options
, &oidAppleTVOSApplicationSigningProd
);
2067 add_leaf_marker(options
, &oidAppleTVOSApplicationSigningProdQA
);
2069 /* Skip networked revocation checks */
2070 CFDictionaryAddValue(options
, kSecPolicyCheckNoNetworkAccess
, kCFBooleanTrue
);
2072 require(result
= SecPolicyCreate(kSecPolicyAppleTVOSApplicationSigning
,
2073 kSecPolicyNameTVOSApplicationSigning
, options
),
2077 CFReleaseSafe(options
);
2078 CFReleaseSafe(oids
);
2079 CFReleaseSafe(atvProdOid
);
2080 CFReleaseSafe(atvTestOid
);
2084 SecPolicyRef
SecPolicyCreateOCSPSigner(void) {
2085 CFMutableDictionaryRef options
= NULL
;
2086 SecPolicyRef result
= NULL
;
2088 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2089 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2091 SecPolicyAddBasicX509Options(options
);
2093 /* Require id-kp-OCSPSigning extendedKeyUsage to be present, not optional. */
2094 add_eku(options
, &oidExtendedKeyUsageOCSPSigning
);
2096 require(result
= SecPolicyCreate(kSecPolicyAppleOCSPSigner
,
2097 kSecPolicyNameOCSPSigner
, options
), errOut
);
2100 CFReleaseSafe(options
);
2104 SecPolicyRef
SecPolicyCreateRevocation(CFOptionFlags revocationFlags
) {
2105 CFMutableDictionaryRef options
= NULL
;
2106 SecPolicyRef result
= NULL
;
2108 require(revocationFlags
!= 0, errOut
);
2110 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2111 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2113 if (revocationFlags
& kSecRevocationCheckIfTrusted
) {
2114 CFDictionaryAddValue(options
, kSecPolicyCheckRevocationIfTrusted
, kCFBooleanTrue
);
2115 /* Set method, but allow caller to override with later checks */
2116 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
2119 if (revocationFlags
& kSecRevocationOnlineCheck
) {
2120 CFDictionaryAddValue(options
, kSecPolicyCheckRevocationOnline
, kCFBooleanTrue
);
2121 /* Set method, but allow caller to override with later checks */
2122 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
2125 if (revocationFlags
& kSecRevocationOCSPMethod
&& revocationFlags
& kSecRevocationCRLMethod
) {
2126 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
2128 else if (revocationFlags
& kSecRevocationOCSPMethod
) {
2129 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationOCSP
);
2131 else if (revocationFlags
& kSecRevocationCRLMethod
) {
2132 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationCRL
);
2135 if (revocationFlags
& kSecRevocationRequirePositiveResponse
) {
2136 CFDictionaryAddValue(options
, kSecPolicyCheckRevocationResponseRequired
, kCFBooleanTrue
);
2139 if (revocationFlags
& kSecRevocationNetworkAccessDisabled
) {
2140 CFDictionaryAddValue(options
, kSecPolicyCheckNoNetworkAccess
, kCFBooleanTrue
);
2142 /* If the caller didn't explicitly disable network access, the revocation policy
2143 * should override any other policy's network setting.
2144 * In particular, pairing a revocation policy with BasicX509 should result in
2145 * allowing network access for revocation unless explicitly disabled.
2146 * Note that SecTrustSetNetworkFetchAllowed can override even this. */
2147 CFDictionaryAddValue(options
, kSecPolicyCheckNoNetworkAccess
, kCFBooleanFalse
);
2150 /* Only flag bits 0-6 are currently defined */
2151 require(((revocationFlags
>> 7) == 0), errOut
);
2153 require(result
= SecPolicyCreate(kSecPolicyAppleRevocation
,
2154 kSecPolicyNameRevocation
, options
), errOut
);
2157 CFReleaseSafe(options
);
2161 SecPolicyRef
SecPolicyCreateSMIME(CFIndex smimeUsage
, CFStringRef email
) {
2162 CFMutableDictionaryRef options
= NULL
;
2163 SecPolicyRef result
= NULL
;
2165 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2166 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2168 if (smimeUsage
& kSecIgnoreExpirationSMIMEUsage
) {
2169 SecPolicyAddBasicCertOptions(options
);
2171 SecPolicyAddBasicX509Options(options
);
2174 /* We call add_ku for each combination of bits we are willing to allow. */
2175 if (smimeUsage
& kSecSignSMIMEUsage
) {
2176 add_ku(options
, kSecKeyUsageUnspecified
);
2177 add_ku(options
, kSecKeyUsageDigitalSignature
);
2178 add_ku(options
, kSecKeyUsageNonRepudiation
);
2180 if (smimeUsage
& kSecKeyEncryptSMIMEUsage
) {
2181 add_ku(options
, kSecKeyUsageKeyEncipherment
);
2183 if (smimeUsage
& kSecDataEncryptSMIMEUsage
) {
2184 add_ku(options
, kSecKeyUsageDataEncipherment
);
2186 if (smimeUsage
& kSecKeyExchangeDecryptSMIMEUsage
) {
2187 add_ku(options
, kSecKeyUsageKeyAgreement
| kSecKeyUsageDecipherOnly
);
2189 if (smimeUsage
& kSecKeyExchangeEncryptSMIMEUsage
) {
2190 add_ku(options
, kSecKeyUsageKeyAgreement
| kSecKeyUsageEncipherOnly
);
2192 if (smimeUsage
& kSecKeyExchangeBothSMIMEUsage
) {
2193 add_ku(options
, kSecKeyUsageKeyAgreement
| kSecKeyUsageEncipherOnly
| kSecKeyUsageDecipherOnly
);
2197 CFDictionaryAddValue(options
, kSecPolicyCheckEmail
, email
);
2200 /* RFC 3850 paragraph 4.4.4
2202 If the extended key usage extension is present in the certificate
2203 then interpersonal message S/MIME receiving agents MUST check that it
2204 contains either the emailProtection or the anyExtendedKeyUsage OID as
2205 defined in [KEYM]. S/MIME uses other than interpersonal messaging
2206 MAY require the explicit presence of the extended key usage extension
2207 or other OIDs to be present in the extension or both.
2209 add_eku(options
, NULL
); /* eku extension is optional */
2210 add_eku(options
, &oidAnyExtendedKeyUsage
);
2211 add_eku(options
, &oidExtendedKeyUsageEmailProtection
);
2213 #if !TARGET_OS_IPHONE
2214 // Check revocation on OS X
2215 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
2218 require(result
= SecPolicyCreate(kSecPolicyAppleSMIME
, kSecPolicyNameSMIME
, options
), errOut
);
2221 CFReleaseSafe(options
);
2225 SecPolicyRef
SecPolicyCreateApplePackageSigning(void) {
2226 CFMutableDictionaryRef options
= NULL
;
2227 SecPolicyRef result
= NULL
;
2229 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2230 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2232 SecPolicyAddBasicCertOptions(options
);
2234 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2235 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNamePackageSigning
), errOut
);
2237 add_ku(options
, kSecKeyUsageDigitalSignature
);
2238 add_eku(options
, &oidExtendedKeyUsageCodeSigning
);
2240 require(result
= SecPolicyCreate(kSecPolicyApplePackageSigning
,
2241 kSecPolicyNamePackageSigning
, options
),
2245 CFReleaseSafe(options
);
2250 SecPolicyRef
SecPolicyCreateAppleSWUpdateSigning(void) {
2251 CFMutableDictionaryRef options
= NULL
;
2252 SecPolicyRef result
= NULL
;
2254 * OS X rules for this policy:
2255 * -- Must have one intermediate cert
2256 * -- intermediate must have basic constraints with path length 0
2257 * -- intermediate has CSSMOID_APPLE_EKU_CODE_SIGNING EKU
2258 * -- leaf cert has either CODE_SIGNING or CODE_SIGN_DEVELOPMENT EKU (the latter of
2259 * which triggers a CSSMERR_APPLETP_CODE_SIGN_DEVELOPMENT error)
2261 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2262 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2264 SecPolicyAddBasicX509Options(options
);
2266 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2267 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameSWUpdateSigning
), errOut
);
2269 add_eku(options
, &oidAppleExtendedKeyUsageCodeSigning
);
2270 add_oid(options
, kSecPolicyCheckIntermediateEKU
, &oidAppleExtendedKeyUsageCodeSigning
);
2272 require(result
= SecPolicyCreate(kSecPolicyAppleSWUpdateSigning
,
2273 kSecPolicyNameSWUpdateSigning
, options
),
2277 CFReleaseSafe(options
);
2282 SecPolicyRef
SecPolicyCreateCodeSigning(void) {
2283 CFMutableDictionaryRef options
= NULL
;
2284 SecPolicyRef result
= NULL
;
2286 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2287 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2289 SecPolicyAddBasicX509Options(options
);
2291 /* If the key usage extension is present, we accept it having either of
2293 add_ku(options
, kSecKeyUsageDigitalSignature
);
2294 add_ku(options
, kSecKeyUsageNonRepudiation
);
2296 /* We require an extended key usage extension with the codesigning
2297 eku purpose. (The Apple codesigning eku is not accepted here
2298 since it's valid only for SecPolicyCreateAppleSWUpdateSigning.) */
2299 add_eku(options
, &oidExtendedKeyUsageCodeSigning
);
2300 #if TARGET_OS_IPHONE
2301 /* Accept the 'any' eku on iOS only to match prior behavior.
2302 This may be further restricted in future releases. */
2303 add_eku(options
, &oidAnyExtendedKeyUsage
);
2306 require(result
= SecPolicyCreate(kSecPolicyAppleCodeSigning
,
2307 kSecPolicyNameCodeSigning
, options
),
2311 CFReleaseSafe(options
);
2315 /* Explicitly leave out empty subject/subjectaltname check */
2316 SecPolicyRef
SecPolicyCreateLockdownPairing(void) {
2317 CFMutableDictionaryRef options
= NULL
;
2318 SecPolicyRef result
= NULL
;
2320 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2321 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2322 //CFDictionaryAddValue(options, kSecPolicyCheckBasicCertificateProcessing,
2323 // kCFBooleanTrue); // Happens automatically in SecPVCPathChecks
2324 CFDictionaryAddValue(options
, kSecPolicyCheckCriticalExtensions
,
2326 CFDictionaryAddValue(options
, kSecPolicyCheckIdLinkage
,
2328 CFDictionaryAddValue(options
, kSecPolicyCheckBasicConstraints
,
2330 CFDictionaryAddValue(options
, kSecPolicyCheckWeakKeySize
, kCFBooleanTrue
);
2332 require(result
= SecPolicyCreate(kSecPolicyAppleLockdownPairing
,
2333 kSecPolicyNameLockdownPairing
, options
), errOut
);
2336 CFReleaseSafe(options
);
2340 SecPolicyRef
SecPolicyCreateURLBag(void) {
2341 CFMutableDictionaryRef options
= NULL
;
2342 SecPolicyRef result
= NULL
;
2344 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2345 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2347 SecPolicyAddBasicCertOptions(options
);
2349 add_eku(options
, &oidExtendedKeyUsageCodeSigning
);
2351 require(result
= SecPolicyCreate(kSecPolicyAppleURLBag
,
2352 kSecPolicyNameURLBag
, options
), errOut
);
2355 CFReleaseSafe(options
);
2359 SecPolicyRef
SecPolicyCreateOTATasking(void)
2361 CFMutableDictionaryRef options
= NULL
;
2362 SecPolicyRef result
= NULL
;
2364 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2365 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2367 SecPolicyAddBasicX509Options(options
);
2370 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameMobileAsset
), errOut
);
2372 /* Chain length of 3 */
2373 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2375 /* Intermediate has common name "Apple iPhone Certification Authority". */
2376 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2377 CFSTR("Apple iPhone Certification Authority"));
2379 /* Leaf has common name "Asset Manifest Signing" */
2380 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
, CFSTR("OTA Task Signing"));
2382 require(result
= SecPolicyCreate(kSecPolicyAppleOTATasking
, kSecPolicyNameOTATasking
, options
),
2386 CFReleaseSafe(options
);
2390 SecPolicyRef
SecPolicyCreateMobileAsset(void)
2392 CFMutableDictionaryRef options
= NULL
;
2393 SecPolicyRef result
= NULL
;
2395 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2396 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2398 /* No expiration check */
2399 SecPolicyAddBasicCertOptions(options
);
2402 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameMobileAsset
), errOut
);
2404 /* Chain length of 3 */
2405 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2407 /* Intermediate has common name "Apple iPhone Certification Authority". */
2408 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2409 CFSTR("Apple iPhone Certification Authority"));
2411 /* Leaf has common name "Asset Manifest Signing" */
2412 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
, CFSTR("Asset Manifest Signing"));
2414 require(result
= SecPolicyCreate(kSecPolicyAppleMobileAsset
, kSecPolicyNameMobileAsset
, options
),
2418 CFReleaseSafe(options
);
2422 SecPolicyRef
SecPolicyCreateMobileAssetDevelopment(void) {
2423 CFMutableDictionaryRef options
= NULL
;
2424 SecPolicyRef result
= NULL
;
2426 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2427 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2429 /* No expiration check */
2430 SecPolicyAddBasicCertOptions(options
);
2433 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameMobileAsset
), errOut
);
2435 /* Chain length of 3 */
2436 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2438 /* Intermediate has the iPhone CA Marker extension */
2439 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.18"));
2441 /* Leaf has ProdQA Mobile Asset Marker extension */
2442 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.55.1"));
2444 require(result
= SecPolicyCreate(kSecPolicyAppleMobileAssetDevelopment
, kSecPolicyNameMobileAsset
, options
),
2448 CFReleaseSafe(options
);
2452 SecPolicyRef
SecPolicyCreateAppleIDAuthorityPolicy(void)
2454 SecPolicyRef result
= NULL
;
2455 CFMutableDictionaryRef options
= NULL
;
2456 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2457 &kCFTypeDictionaryKeyCallBacks
,
2458 &kCFTypeDictionaryValueCallBacks
), out
);
2460 //Leaf appears to be a SSL only cert, so policy should expand on that policy
2461 SecPolicyAddBasicX509Options(options
);
2463 // Apple CA anchored
2464 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameIDAuthority
), out
);
2466 // with the addition of the existence check of an extension with "Apple ID Sharing Certificate" oid (1.2.840.113635.100.4.7)
2467 // NOTE: this obviously intended to have gone into Extended Key Usage, but evidence of existing certs proves the contrary.
2468 add_leaf_marker(options
, &oidAppleExtendedKeyUsageAppleID
);
2470 // 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.
2471 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleID
);
2472 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleID2
);
2474 require(result
= SecPolicyCreate(kSecPolicyAppleIDAuthority
,
2475 kSecPolicyNameIDAuthority
, options
), out
);
2478 CFReleaseSafe(options
);
2482 SecPolicyRef
SecPolicyCreateMacAppStoreReceipt(void)
2484 SecPolicyRef result
= NULL
;
2485 CFMutableDictionaryRef options
= NULL
;
2486 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2487 &kCFTypeDictionaryKeyCallBacks
,
2488 &kCFTypeDictionaryValueCallBacks
), out
);
2490 SecPolicyAddBasicX509Options(options
);
2492 // Apple CA anchored
2493 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameMacAppStoreReceipt
), out
);
2495 // Chain length of 3
2496 require(SecPolicyAddChainLengthOptions(options
, 3), out
);
2498 // MacAppStoreReceipt policy OID
2499 add_certificate_policy_oid_string(options
, CFSTR("1.2.840.113635.100.5.6.1"));
2501 // Intermediate marker OID
2502 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.1"));
2505 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.11.1"));
2508 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
2510 require(result
= SecPolicyCreate(kSecPolicyMacAppStoreReceipt
,
2511 kSecPolicyNameMacAppStoreReceipt
, options
), out
);
2514 CFReleaseSafe(options
);
2519 static SecPolicyRef
_SecPolicyCreatePassbookCardSigner(CFStringRef cardIssuer
, CFStringRef teamIdentifier
, bool requireTeamID
)
2521 SecPolicyRef result
= NULL
;
2522 CFMutableDictionaryRef options
= NULL
;
2523 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2524 &kCFTypeDictionaryKeyCallBacks
,
2525 &kCFTypeDictionaryValueCallBacks
), out
);
2527 SecPolicyAddBasicX509Options(options
);
2528 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNamePassbookSigning
), out
);
2530 // Chain length of 3
2531 require(SecPolicyAddChainLengthOptions(options
, 3), out
);
2533 if (teamIdentifier
) {
2534 // If supplied, teamIdentifier must match subject OU field
2535 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectOrganizationalUnit
, teamIdentifier
);
2538 // If not supplied, and it was required, fail
2539 require(!requireTeamID
, out
);
2542 // Must be both push and 3rd party package signing
2543 add_leaf_marker_value(options
, &oidAppleInstallerPackagingSigningExternal
, cardIssuer
);
2545 // We should check that it also has push marker, but we don't support requiring both, only either.
2546 // add_independent_oid(options, kSecPolicyCheckLeafMarkerOid, &oidApplePushServiceClient);
2548 //WWDR Intermediate marker OID
2549 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.1"));
2551 // And Passbook signing eku
2552 add_eku(options
, &oidAppleExtendedKeyUsagePassbook
);
2554 require(result
= SecPolicyCreate(kSecPolicyApplePassbookSigning
,
2555 kSecPolicyNamePassbookSigning
, options
), out
);
2558 CFReleaseSafe(options
);
2562 SecPolicyRef
SecPolicyCreatePassbookCardSigner(CFStringRef cardIssuer
, CFStringRef teamIdentifier
)
2564 return _SecPolicyCreatePassbookCardSigner(cardIssuer
, teamIdentifier
, true);
2568 static SecPolicyRef
CreateMobileStoreSigner(Boolean forTest
)
2571 SecPolicyRef result
= NULL
;
2572 CFMutableDictionaryRef options
= NULL
;
2573 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2574 &kCFTypeDictionaryKeyCallBacks
,
2575 &kCFTypeDictionaryValueCallBacks
), errOut
);
2576 SecPolicyAddBasicX509Options(options
);
2577 require(SecPolicyAddAppleAnchorOptions(options
,
2578 ((forTest
) ? kSecPolicyNameTestMobileStore
:
2579 kSecPolicyNameMobileStore
)), errOut
);
2581 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2583 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2584 CFSTR("Apple System Integration 2 Certification Authority"));
2586 add_ku(options
, kSecKeyUsageDigitalSignature
);
2588 const DERItem
* pOID
= (forTest
) ? &oidApplePolicyMobileStoreProdQA
: &oidApplePolicyMobileStore
;
2590 add_certificate_policy_oid(options
, pOID
);
2592 require(result
= SecPolicyCreate((forTest
) ? kSecPolicyAppleTestMobileStore
: kSecPolicyAppleMobileStore
,
2593 (forTest
) ? kSecPolicyNameTestMobileStore
: kSecPolicyNameMobileStore
,
2597 CFReleaseSafe(options
);
2601 SecPolicyRef
SecPolicyCreateMobileStoreSigner(void)
2603 return CreateMobileStoreSigner(false);
2606 SecPolicyRef
SecPolicyCreateTestMobileStoreSigner(void)
2608 return CreateMobileStoreSigner(true);
2612 CF_RETURNS_RETAINED SecPolicyRef
SecPolicyCreateEscrowServiceSigner(void)
2614 SecPolicyRef result
= NULL
;
2615 CFMutableDictionaryRef options
= NULL
;
2616 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2617 &kCFTypeDictionaryKeyCallBacks
,
2618 &kCFTypeDictionaryValueCallBacks
), errOut
);
2620 // X509, ignoring date validity
2621 SecPolicyAddBasicCertOptions(options
);
2623 add_ku(options
, kSecKeyUsageKeyEncipherment
);
2625 /* Leaf has marker OID with value that can't be pre-determined */
2626 add_element(options
, kSecPolicyCheckLeafMarkerOidWithoutValueCheck
, CFSTR("1.2.840.113635.100.6.23.1"));
2627 require(SecPolicyAddChainLengthOptions(options
, 2), errOut
);
2629 require(result
= SecPolicyCreate(kSecPolicyAppleEscrowService
,
2630 kSecPolicyNameEscrowService
, options
), errOut
);
2633 CFReleaseSafe(options
);
2637 CF_RETURNS_RETAINED SecPolicyRef
SecPolicyCreatePCSEscrowServiceSigner(void)
2639 SecPolicyRef result
= NULL
;
2640 CFMutableDictionaryRef options
= NULL
;
2641 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2642 &kCFTypeDictionaryKeyCallBacks
,
2643 &kCFTypeDictionaryValueCallBacks
), errOut
);
2645 SecPolicyAddBasicX509Options(options
);
2646 add_ku(options
, kSecKeyUsageKeyEncipherment
);
2648 /* Leaf has marker OID with value that can't be pre-determined */
2649 add_element(options
, kSecPolicyCheckLeafMarkerOidWithoutValueCheck
, CFSTR("1.2.840.113635.100.6.23.1"));
2650 require(SecPolicyAddChainLengthOptions(options
, 2), errOut
);
2652 require(result
= SecPolicyCreate(kSecPolicyApplePCSEscrowService
,
2653 kSecPolicyNamePCSEscrowService
, options
), errOut
);
2656 CFReleaseSafe(options
);
2660 static SecPolicyRef
CreateConfigurationProfileSigner(bool forTest
) {
2661 SecPolicyRef result
= NULL
;
2662 CFMutableDictionaryRef options
= NULL
;
2663 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2664 &kCFTypeDictionaryKeyCallBacks
,
2665 &kCFTypeDictionaryValueCallBacks
), errOut
);
2667 SecPolicyAddBasicX509Options(options
);
2668 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameProfileSigner
), errOut
);
2671 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2673 // Require the profile signing EKU
2674 const DERItem
* pOID
= (forTest
) ? &oidAppleExtendedKeyUsageQAProfileSigning
:&oidAppleExtendedKeyUsageProfileSigning
;
2675 add_eku(options
, pOID
);
2677 // Require the Apple Application Integration CA marker OID
2678 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.3"));
2680 require(result
= SecPolicyCreate((forTest
) ? kSecPolicyAppleQAProfileSigner
: kSecPolicyAppleProfileSigner
,
2681 (forTest
) ? kSecPolicyNameQAProfileSigner
: kSecPolicyNameProfileSigner
,
2685 CFReleaseSafe(options
);
2689 SecPolicyRef
SecPolicyCreateConfigurationProfileSigner(void)
2691 return CreateConfigurationProfileSigner(false);
2695 SecPolicyRef
SecPolicyCreateQAConfigurationProfileSigner(void)
2698 // Seed builds permit the QA signer
2699 return CreateConfigurationProfileSigner(true);
2700 #else // !RC_SEED_BUILD
2701 if (os_variant_has_internal_diagnostics("com.apple.security")) {
2702 // Internal builds permit the QA signer
2703 return CreateConfigurationProfileSigner(true);
2705 // GM builds do not trust the QA signer
2706 return CreateConfigurationProfileSigner(false);
2708 #endif // !RC_SEED_BUILD
2711 SecPolicyRef
SecPolicyCreateOSXProvisioningProfileSigning(void)
2713 SecPolicyRef result
= NULL
;
2714 CFMutableDictionaryRef options
= NULL
;
2715 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2716 &kCFTypeDictionaryKeyCallBacks
,
2717 &kCFTypeDictionaryValueCallBacks
), errOut
);
2718 // Require valid chain from the Apple root
2719 SecPolicyAddBasicX509Options(options
);
2720 SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameOSXProvisioningProfileSigning
);
2722 // Require provisioning profile leaf marker OID (1.2.840.113635.100.4.11)
2723 add_leaf_marker(options
, &oidAppleCertExtOSXProvisioningProfileSigning
);
2725 // Require intermediate marker OID (1.2.840.113635.100.6.2.1)
2726 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleWWDR
);
2728 // Require key usage that allows signing
2729 add_ku(options
, kSecKeyUsageDigitalSignature
);
2731 // Ensure that revocation is checked (OCSP)
2732 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationOCSP
);
2734 require(result
= SecPolicyCreate(kSecPolicyAppleOSXProvisioningProfileSigning
,
2735 kSecPolicyNameOSXProvisioningProfileSigning
, options
), errOut
);
2738 CFReleaseSafe(options
);
2743 SecPolicyRef
SecPolicyCreateOTAPKISigner(void)
2745 SecPolicyRef result
= NULL
;
2746 CFMutableDictionaryRef options
= NULL
;
2747 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2748 &kCFTypeDictionaryKeyCallBacks
,
2749 &kCFTypeDictionaryValueCallBacks
), errOut
);
2750 SecPolicyAddBasicX509Options(options
);
2752 SecPolicyAddAnchorSHA1Options(options
, kApplePKISettingsAuthority
);
2753 require(SecPolicyAddChainLengthOptions(options
, 2), errOut
);
2755 require(result
= SecPolicyCreate(kSecPolicyAppleOTAPKISigner
,
2756 kSecPolicyNameOTAPKISigner
, options
), errOut
);
2759 CFReleaseSafe(options
);
2765 SecPolicyRef
SecPolicyCreateTestOTAPKISigner(void)
2767 /* Guard against use on production devices */
2768 if (!SecIsInternalRelease()) {
2769 return SecPolicyCreateOTAPKISigner();
2772 SecPolicyRef result
= NULL
;
2773 CFMutableDictionaryRef options
= NULL
;
2774 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2775 &kCFTypeDictionaryKeyCallBacks
,
2776 &kCFTypeDictionaryValueCallBacks
), errOut
);
2777 SecPolicyAddBasicX509Options(options
);
2779 SecPolicyAddAnchorSHA1Options(options
, kAppleTestPKISettingsAuthority
);
2780 require(SecPolicyAddChainLengthOptions(options
, 2), errOut
);
2782 require(result
= SecPolicyCreate(kSecPolicyAppleTestOTAPKISigner
,
2783 kSecPolicyNameTestOTAPKISigner
, options
), errOut
);
2786 CFReleaseSafe(options
);
2791 @function SecPolicyCreateAppleSMPEncryption
2792 @abstract Check for intermediate certificate 'Apple System Integration CA - G3' by name,
2793 and root certificate 'Apple Root CA - G3' by hash.
2794 Leaf cert must have Key Encipherment usage.
2795 Leaf cert must have Apple SMP Encryption marker OID (1.2.840.113635.100.6.30).
2796 Intermediate must have marker OID (1.2.840.113635.100.6.2.13).
2798 SecPolicyRef
SecPolicyCreateAppleSMPEncryption(void)
2800 SecPolicyRef result
= NULL
;
2801 CFMutableDictionaryRef options
= NULL
;
2802 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2803 &kCFTypeDictionaryKeyCallBacks
,
2804 &kCFTypeDictionaryValueCallBacks
), errOut
);
2805 SecPolicyAddBasicCertOptions(options
);
2807 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameSMPEncryption
),
2809 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2811 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2812 CFSTR("Apple System Integration CA - G3"));
2814 // Check that leaf has extension with "Apple SMP Encryption" oid (1.2.840.113635.100.6.30)
2815 add_leaf_marker(options
, &oidAppleCertExtAppleSMPEncryption
);
2817 // Check that intermediate has extension (1.2.840.113635.100.6.2.13)
2818 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleSystemIntgG3
);
2820 add_ku(options
, kSecKeyUsageKeyEncipherment
);
2822 // Ensure that revocation is checked (OCSP)
2823 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationOCSP
);
2825 require(result
= SecPolicyCreate(kSecPolicyAppleSMPEncryption
,
2826 kSecPolicyNameSMPEncryption
, options
), errOut
);
2829 CFReleaseSafe(options
);
2834 @function SecPolicyCreateTestAppleSMPEncryption
2835 @abstract Check for intermediate certificate 'Test Apple System Integration CA - ECC' by name,
2836 and root certificate 'Test Apple Root CA - ECC' by hash.
2837 Leaf cert must have Key Encipherment usage. Other checks TBD.
2839 SecPolicyRef
SecPolicyCreateTestAppleSMPEncryption(void)
2841 SecPolicyRef result
= NULL
;
2842 CFMutableDictionaryRef options
= NULL
;
2843 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2844 &kCFTypeDictionaryKeyCallBacks
,
2845 &kCFTypeDictionaryValueCallBacks
), errOut
);
2846 SecPolicyAddBasicCertOptions(options
);
2848 SecPolicyAddAnchorSHA1Options(options
, kTestAppleRootCA_ECC_SHA1
);
2849 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2851 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2852 CFSTR("Test Apple System Integration CA - ECC"));
2854 add_ku(options
, kSecKeyUsageKeyEncipherment
);
2856 // Ensure that revocation is checked (OCSP)
2857 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationOCSP
);
2859 require(result
= SecPolicyCreate(kSecPolicyAppleTestSMPEncryption
,
2860 kSecPolicyNameTestSMPEncryption
, options
), errOut
);
2863 CFReleaseSafe(options
);
2868 SecPolicyRef
SecPolicyCreateAppleIDValidationRecordSigningPolicy(void)
2870 SecPolicyRef result
= NULL
;
2871 CFMutableDictionaryRef options
= NULL
;
2872 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2873 &kCFTypeDictionaryKeyCallBacks
,
2874 &kCFTypeDictionaryValueCallBacks
), errOut
);
2876 //Leaf appears to be a SSL only cert, so policy should expand on that policy
2877 SecPolicyAddBasicX509Options(options
);
2879 // Apple CA anchored
2880 require(SecPolicyAddAppleAnchorOptions(options
,
2881 kSecPolicyNameIDValidationRecordSigning
),
2884 // Check for an extension with " Apple ID Validation Record Signing" oid (1.2.840.113635.100.6.25)
2885 add_leaf_marker(options
, &oidAppleCertExtensionAppleIDRecordValidationSigning
);
2887 // and validate that intermediate has extension
2888 // Application Integration Intermediate Certificate (1.2.840.113635.100.6.2.3)
2889 // and also validate that intermediate has extension
2890 // System Integration 2 Intermediate Certificate (1.2.840.113635.100.6.2.10)
2891 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleID
);
2892 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleSystemIntg2
);
2894 // Ensure that revocation is checked (OCSP)
2895 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationOCSP
);
2897 require(result
= SecPolicyCreate(kSecPolicyAppleIDValidationRecordSigning
,
2898 kSecPolicyNameIDValidationRecordSigning
, options
), errOut
);
2901 CFReleaseSafe(options
);
2906 @function SecPolicyCreateAppleServerAuthCommon
2907 @abstract Generic policy for server authentication Sub CAs
2909 Allows control for both if pinning is required at all and if UAT environments should be added
2910 to the trust policy.
2912 No pinning is for developer/QA that needs to use proxy to debug the protocol, while UAT
2913 environment is for QA/internal developer that have no need allow fake servers.
2915 Both the noPinning and UAT are gated on that you run on internal hardware.
2920 SecPolicyCreateAppleServerAuthCommon(CFStringRef hostname
,
2921 CFDictionaryRef __unused context
,
2922 CFStringRef policyOID
, CFStringRef service
,
2923 const DERItem
*leafMarkerOID
,
2924 const DERItem
*UATLeafMarkerOID
)
2926 CFMutableDictionaryRef appleAnchorOptions
= NULL
;
2927 CFMutableDictionaryRef options
= NULL
;
2928 SecPolicyRef result
= NULL
;
2929 CFDataRef oid
= NULL
, uatoid
= NULL
;
2931 options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0, &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
2932 require(options
, errOut
);
2934 SecPolicyAddBasicX509Options(options
);
2936 require(hostname
, errOut
);
2937 CFDictionaryAddValue(options
, kSecPolicyCheckSSLHostname
, hostname
);
2939 CFDictionaryAddValue(options
, kSecPolicyCheckBlackListedLeaf
, kCFBooleanTrue
);
2940 CFDictionaryAddValue(options
, kSecPolicyCheckGrayListedLeaf
, kCFBooleanTrue
);
2942 add_eku(options
, &oidExtendedKeyUsageServerAuth
);
2944 if (requireUATPinning(service
)) {
2947 * Require pinning to the Apple CA's.
2949 SecPolicyAddAppleAnchorOptions(options
, service
);
2951 /* old-style leaf marker OIDs */
2952 if (UATLeafMarkerOID
) {
2953 add_leaf_prod_qa_markers(options
, leafMarkerOID
, UATLeafMarkerOID
);
2955 add_leaf_marker(options
, leafMarkerOID
);
2958 /* new-style leaf marker OIDs */
2959 CFStringRef leafMarkerOIDStr
= NULL
, UATLeafMarkerOIDStr
= NULL
;
2960 leafMarkerOIDStr
= SecDERItemCopyOIDDecimalRepresentation(NULL
, leafMarkerOID
);
2961 if (UATLeafMarkerOID
) {
2962 UATLeafMarkerOIDStr
= SecDERItemCopyOIDDecimalRepresentation(NULL
, UATLeafMarkerOID
);
2965 if (leafMarkerOIDStr
&& UATLeafMarkerOIDStr
) {
2966 add_leaf_prod_qa_markers_value_string(options
,
2967 CFSTR("1.2.840.113635.100.6.48.1"), leafMarkerOIDStr
,
2968 CFSTR("1.2.840.113635.100.6.48.1"), UATLeafMarkerOIDStr
);
2969 } else if (leafMarkerOIDStr
) {
2970 add_leaf_marker_value_string(options
, CFSTR("1.2.840.113635.100.6.48.1"), leafMarkerOIDStr
);
2973 CFReleaseNull(leafMarkerOIDStr
);
2974 CFReleaseNull(UATLeafMarkerOIDStr
);
2976 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleServerAuthentication
);
2979 /* Check for weak hashes and keys */
2980 require(SecPolicyRemoveWeakHashOptions(options
), errOut
);
2981 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
2983 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
2985 result
= SecPolicyCreate(policyOID
, service
, options
);
2986 require(result
, errOut
);
2989 CFReleaseSafe(appleAnchorOptions
);
2990 CFReleaseSafe(options
);
2992 CFReleaseSafe(uatoid
);
2997 @function SecPolicyCreateAppleIDSService
2998 @abstract Ensure we're appropriately pinned to the IDS service (SSL + Apple restrictions)
3000 SecPolicyRef
SecPolicyCreateAppleIDSService(CFStringRef hostname
)
3002 SecPolicyRef result
= SecPolicyCreateSSL(true, hostname
);
3004 SecPolicySetOid(result
, kSecPolicyAppleIDSService
);
3005 SecPolicySetName(result
, kSecPolicyNameAppleIDSBag
);
3011 @function SecPolicyCreateAppleIDSService
3012 @abstract Ensure we're appropriately pinned to the IDS service (SSL + Apple restrictions)
3014 SecPolicyRef
SecPolicyCreateAppleIDSServiceContext(CFStringRef hostname
, CFDictionaryRef context
)
3016 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyAppleIDSServiceContext
,
3017 kSecPolicyNameAppleIDSService
,
3018 &oidAppleCertExtAppleServerAuthenticationIDSProd
,
3019 &oidAppleCertExtAppleServerAuthenticationIDSProdQA
);
3023 @function SecPolicyCreateAppleGSService
3024 @abstract Ensure we're appropriately pinned to the GS service
3026 SecPolicyRef
SecPolicyCreateAppleGSService(CFStringRef hostname
, CFDictionaryRef context
)
3028 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyAppleGSService
,
3029 kSecPolicyNameAppleGSService
,
3030 &oidAppleCertExtAppleServerAuthenticationGS
,
3035 @function SecPolicyCreateApplePushService
3036 @abstract Ensure we're appropriately pinned to the Push service (SSL + Apple restrictions)
3038 SecPolicyRef
SecPolicyCreateApplePushService(CFStringRef hostname
, CFDictionaryRef context
)
3040 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyApplePushService
,
3041 kSecPolicyNameApplePushService
,
3042 &oidAppleCertExtAppleServerAuthenticationAPNProd
,
3043 &oidAppleCertExtAppleServerAuthenticationAPNProdQA
);
3047 @function SecPolicyCreateApplePPQService
3048 @abstract Ensure we're appropriately pinned to the PPQ service (SSL + Apple restrictions)
3050 SecPolicyRef
SecPolicyCreateApplePPQService(CFStringRef hostname
, CFDictionaryRef context
)
3052 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyApplePPQService
,
3053 kSecPolicyNameApplePPQService
,
3054 &oidAppleCertExtAppleServerAuthenticationPPQProd
,
3055 &oidAppleCertExtAppleServerAuthenticationPPQProdQA
);
3059 @function SecPolicyCreateAppleAST2Service
3060 @abstract Ensure we're appropriately pinned to the AST2 Diagnostic service (SSL + Apple restrictions)
3062 SecPolicyRef
SecPolicyCreateAppleAST2Service(CFStringRef hostname
, CFDictionaryRef context
)
3064 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyAppleAST2DiagnosticsServerAuth
,
3065 kSecPolicyNameAppleAST2Service
,
3066 &oidAppleCertExtAST2DiagnosticsServerAuthProd
,
3067 &oidAppleCertExtAST2DiagnosticsServerAuthProdQA
);
3071 @function SecPolicyCreateAppleEscrowProxyService
3072 @abstract Ensure we're appropriately pinned to the iCloud Escrow Proxy service (SSL + Apple restrictions)
3074 SecPolicyRef
SecPolicyCreateAppleEscrowProxyService(CFStringRef hostname
, CFDictionaryRef context
)
3076 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyAppleEscrowProxyServerAuth
,
3077 kSecPolicyNameAppleEscrowProxyService
,
3078 &oidAppleCertExtEscrowProxyServerAuthProd
,
3079 &oidAppleCertExtEscrowProxyServerAuthProdQA
);
3082 /* subject:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA */
3083 /* SKID: C0:7A:98:68:8D:89:FB:AB:05:64:0C:11:7D:AA:7D:65:B8:CA:CC:4E */
3084 /* Not Before: May 21 04:00:00 2002 GMT, Not After : May 21 04:00:00 2022 GMT */
3085 /* Signature Algorithm: sha1WithRSAEncryption */
3086 unsigned char GeoTrust_Global_CA_sha256
[kSecPolicySHA256Size
] = {
3087 0xff, 0x85, 0x6a, 0x2d, 0x25, 0x1d, 0xcd, 0x88, 0xd3, 0x66, 0x56, 0xf4, 0x50, 0x12, 0x67, 0x98,
3088 0xcf, 0xab, 0xaa, 0xde, 0x40, 0x79, 0x9c, 0x72, 0x2d, 0xe4, 0xd2, 0xb5, 0xdb, 0x36, 0xa7, 0x3a
3091 static SecPolicyRef
SecPolicyCreateAppleGeoTrustServerAuthCommon(CFStringRef hostname
, CFStringRef policyOid
,
3092 CFStringRef policyName
,
3093 CFStringRef leafMarkerOid
,
3094 CFStringRef qaLeafMarkerOid
) {
3095 CFMutableDictionaryRef options
= NULL
;
3096 CFDataRef spkiDigest
= NULL
;
3097 SecPolicyRef result
= NULL
;
3099 require(options
= CFDictionaryCreateMutable(NULL
, 0, &kCFTypeDictionaryKeyCallBacks
,
3100 &kCFTypeDictionaryValueCallBacks
), errOut
);
3103 SecPolicyAddBasicX509Options(options
);
3105 require(hostname
, errOut
);
3106 CFDictionaryAddValue(options
, kSecPolicyCheckSSLHostname
, hostname
);
3108 add_eku(options
, &oidExtendedKeyUsageServerAuth
);
3111 if (requireUATPinning(policyName
)) {
3113 SecPolicyAddAnchorSHA256Options(options
, GeoTrust_Global_CA_sha256
);
3115 /* Issued to Apple Inc. in the US */
3116 add_element(options
, kSecPolicyCheckIntermediateCountry
, CFSTR("US"));
3117 add_element(options
, kSecPolicyCheckIntermediateOrganization
, CFSTR("Apple Inc."));
3119 require_action(SecPolicyAddChainLengthOptions(options
, 3), errOut
, CFReleaseNull(result
));
3121 /* Marker OIDs in both formats */
3122 if (qaLeafMarkerOid
) {
3123 add_leaf_prod_qa_markers_string(options
, leafMarkerOid
, qaLeafMarkerOid
);
3124 add_leaf_prod_qa_markers_value_string(options
,
3125 CFSTR("1.2.840.113635.100.6.48.1"), leafMarkerOid
,
3126 CFSTR("1.2.840.113635.100.6.48.1"), qaLeafMarkerOid
);
3128 add_leaf_marker_string(options
, leafMarkerOid
);
3129 add_leaf_marker_value_string(options
, CFSTR("1.2.840.113635.100.6.48.1"), leafMarkerOid
);
3133 /* Check for weak hashes */
3134 require(SecPolicyRemoveWeakHashOptions(options
), errOut
);
3135 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
3137 /* See <rdar://25344801> for more details */
3139 result
= SecPolicyCreate(policyOid
, policyName
, options
);
3142 CFReleaseSafe(options
);
3143 CFReleaseSafe(spkiDigest
);
3147 SecPolicyRef
SecPolicyCreateAppleCompatibilityEscrowProxyService(CFStringRef hostname
) {
3148 return SecPolicyCreateAppleGeoTrustServerAuthCommon(hostname
, kSecPolicyAppleEscrowProxyCompatibilityServerAuth
,
3149 kSecPolicyNameAppleEscrowProxyService
,
3150 CFSTR("1.2.840.113635.100.6.27.7.2"),
3151 CFSTR("1.2.840.113635.100.6.27.7.1"));
3155 @function SecPolicyCreateAppleFMiPService
3156 @abstract Ensure we're appropriately pinned to the Find My iPhone service (SSL + Apple restrictions)
3158 SecPolicyRef
SecPolicyCreateAppleFMiPService(CFStringRef hostname
, CFDictionaryRef context
)
3160 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyAppleFMiPServerAuth
,
3161 kSecPolicyNameAppleFMiPService
,
3162 &oidAppleCertExtFMiPServerAuthProd
,
3163 &oidAppleCertExtFMiPServerAuthProdQA
);
3167 /* should use verbatim copy, but since this is the deprecated way, don't care right now */
3168 static const UInt8 entrustSPKIL1C
[kSecPolicySHA256Size
] = {
3169 0x54, 0x5b, 0xf9, 0x35, 0xe9, 0xad, 0xa1, 0xda,
3170 0x11, 0x7e, 0xdc, 0x3c, 0x2a, 0xcb, 0xc5, 0x6f,
3171 0xc0, 0x28, 0x09, 0x6c, 0x0e, 0x24, 0xbe, 0x9b,
3172 0x38, 0x94, 0xbe, 0x52, 0x2d, 0x1b, 0x43, 0xde
3176 @function SecPolicyCreateApplePushServiceLegacy
3177 @abstract Ensure we're appropriately pinned to the Push service (via Entrust)
3179 SecPolicyRef
SecPolicyCreateApplePushServiceLegacy(CFStringRef hostname
)
3181 CFMutableDictionaryRef options
= NULL
;
3182 SecPolicyRef result
= NULL
;
3183 CFDataRef digest
= NULL
;
3185 digest
= CFDataCreateWithBytesNoCopy(kCFAllocatorDefault
, entrustSPKIL1C
, sizeof(entrustSPKIL1C
), kCFAllocatorNull
);
3186 require(digest
, errOut
);
3188 options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0, &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
3189 require(options
, errOut
);
3191 SecPolicyAddBasicX509Options(options
);
3193 CFDictionaryAddValue(options
, kSecPolicyCheckSSLHostname
, hostname
);
3195 CFDictionaryAddValue(options
, kSecPolicyCheckBlackListedLeaf
, kCFBooleanTrue
);
3196 CFDictionaryAddValue(options
, kSecPolicyCheckGrayListedLeaf
, kCFBooleanTrue
);
3198 CFDictionaryAddValue(options
, kSecPolicyCheckIntermediateSPKISHA256
, digest
);
3200 add_eku(options
, &oidExtendedKeyUsageServerAuth
);
3202 /* Check for weak hashes and keys */
3203 require(SecPolicyRemoveWeakHashOptions(options
), errOut
);
3204 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
3206 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
3208 result
= SecPolicyCreate(kSecPolicyAppleLegacyPushService
,
3209 kSecPolicyNameLegacyPushService
, options
);
3210 require(result
, errOut
);
3213 CFReleaseSafe(digest
);
3214 CFReleaseSafe(options
);
3219 @function SecPolicyCreateAppleMMCSService
3220 @abstract Ensure we're appropriately pinned to the IDS service (SSL + Apple restrictions)
3222 SecPolicyRef
SecPolicyCreateAppleMMCSService(CFStringRef hostname
, CFDictionaryRef context
)
3224 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyAppleMMCService
,
3225 kSecPolicyNameAppleMMCSService
,
3226 &oidAppleCertExtAppleServerAuthenticationMMCSProd
,
3227 &oidAppleCertExtAppleServerAuthenticationMMCSProdQA
);
3230 SecPolicyRef
SecPolicyCreateAppleCompatibilityMMCSService(CFStringRef hostname
) {
3231 return SecPolicyCreateAppleGeoTrustServerAuthCommon(hostname
, kSecPolicyAppleMMCSCompatibilityServerAuth
,
3232 kSecPolicyNameAppleMMCSService
,
3233 CFSTR("1.2.840.113635.100.6.27.11.2"),
3234 CFSTR("1.2.840.113635.100.6.27.11.1"));
3238 SecPolicyRef
SecPolicyCreateAppleiCloudSetupService(CFStringRef hostname
, CFDictionaryRef context
)
3240 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyAppleiCloudSetupServerAuth
,
3241 kSecPolicyNameAppleiCloudSetupService
,
3242 &oidAppleCertExtAppleServerAuthenticationiCloudSetupProd
,
3243 &oidAppleCertExtAppleServerAuthenticationiCloudSetupProdQA
);
3246 SecPolicyRef
SecPolicyCreateAppleCompatibilityiCloudSetupService(CFStringRef hostname
)
3248 return SecPolicyCreateAppleGeoTrustServerAuthCommon(hostname
, kSecPolicyAppleiCloudSetupCompatibilityServerAuth
,
3249 kSecPolicyNameAppleiCloudSetupService
,
3250 CFSTR("1.2.840.113635.100.6.27.15.2"),
3251 CFSTR("1.2.840.113635.100.6.27.15.1"));
3255 @function SecPolicyCreateAppleSSLService
3256 @abstract Ensure we're appropriately pinned to an Apple server (SSL + Apple restrictions)
3258 SecPolicyRef
SecPolicyCreateAppleSSLService(CFStringRef hostname
)
3260 // SSL server, pinned to an Apple intermediate
3261 SecPolicyRef policy
= SecPolicyCreateSSL(true, hostname
);
3262 CFMutableDictionaryRef options
= NULL
;
3263 require(policy
, errOut
);
3265 // change options for SSL policy evaluation
3266 require((options
=(CFMutableDictionaryRef
)policy
->_options
) != NULL
, errOut
);
3268 // Apple CA anchored
3269 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameServerAuthentication
), errOut
);
3271 // Check leaf for Apple Server Authentication marker oid (1.2.840.113635.100.6.27.1)
3272 add_leaf_marker(options
, &oidAppleCertExtAppleServerAuthentication
);
3274 // Check intermediate for Apple Server Authentication intermediate marker (1.2.840.113635.100.6.2.12)
3275 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleServerAuthentication
);
3277 /* Check for weak hashes */
3278 require(SecPolicyRemoveWeakHashOptions(options
), errOut
);
3280 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
3282 SecPolicySetOid(policy
, kSecPolicyAppleServerAuthentication
);
3283 SecPolicySetName(policy
, kSecPolicyNameServerAuthentication
);
3288 CFReleaseSafe(options
);
3289 CFReleaseSafe(policy
);
3294 @function SecPolicyCreateApplePPQSigning
3295 @abstract Check for intermediate certificate 'Apple System Integration 2 Certification Authority' by name,
3297 Leaf cert must have Digital Signature usage.
3298 Leaf cert must have Apple PPQ Signing marker OID (1.2.840.113635.100.6.38.2).
3299 Intermediate must have marker OID (1.2.840.113635.100.6.2.10).
3301 SecPolicyRef
SecPolicyCreateApplePPQSigning(void)
3303 SecPolicyRef result
= NULL
;
3304 CFMutableDictionaryRef options
= NULL
;
3305 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3306 &kCFTypeDictionaryKeyCallBacks
,
3307 &kCFTypeDictionaryValueCallBacks
), errOut
);
3308 SecPolicyAddBasicCertOptions(options
);
3310 SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNamePPQSigning
);
3311 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3313 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
3314 CFSTR("Apple System Integration 2 Certification Authority"));
3316 // Check that leaf has extension with "Apple PPQ Signing" prod oid (1.2.840.113635.100.6.38.2)
3317 add_leaf_marker(options
, &oidAppleCertExtApplePPQSigningProd
);
3319 // Check that intermediate has extension (1.2.840.113635.100.6.2.10)
3320 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleSystemIntg2
);
3322 add_ku(options
, kSecKeyUsageDigitalSignature
);
3324 require(result
= SecPolicyCreate(kSecPolicyApplePPQSigning
,
3325 kSecPolicyNamePPQSigning
, options
), errOut
);
3328 CFReleaseSafe(options
);
3333 @function SecPolicyCreateTestApplePPQSigning
3334 @abstract Check for intermediate certificate 'Apple System Integration 2 Certification Authority' by name,
3336 Leaf cert must have Digital Signature usage.
3337 Leaf cert must have Apple PPQ Signing Test marker OID (1.2.840.113635.100.6.38.1).
3338 Intermediate must have marker OID (1.2.840.113635.100.6.2.10).
3340 SecPolicyRef
SecPolicyCreateTestApplePPQSigning(void)
3342 /* Guard against use of test policy on production devices */
3343 if (!SecIsInternalRelease()) {
3344 return SecPolicyCreateApplePPQSigning();
3347 SecPolicyRef result
= NULL
;
3348 CFMutableDictionaryRef options
= NULL
;
3349 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3350 &kCFTypeDictionaryKeyCallBacks
,
3351 &kCFTypeDictionaryValueCallBacks
), errOut
);
3352 SecPolicyAddBasicCertOptions(options
);
3354 SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameTestPPQSigning
);
3355 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3357 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
3358 CFSTR("Apple System Integration 2 Certification Authority"));
3360 // Check that leaf has extension with "Apple PPQ Signing" test oid (1.2.840.113635.100.6.38.1)
3361 add_leaf_marker(options
, &oidAppleCertExtApplePPQSigningProdQA
);
3363 // Check that intermediate has extension (1.2.840.113635.100.6.2.10)
3364 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleSystemIntg2
);
3366 add_ku(options
, kSecKeyUsageDigitalSignature
);
3368 require(result
= SecPolicyCreate(kSecPolicyAppleTestPPQSigning
,
3369 kSecPolicyNameTestPPQSigning
, options
), errOut
);
3372 CFReleaseSafe(options
);
3376 @function SecPolicyCreateAppleTimeStamping
3377 @abstract Check for RFC3161 timestamping EKU.
3379 SecPolicyRef
SecPolicyCreateAppleTimeStamping(void)
3381 SecPolicyRef result
= NULL
;
3382 CFMutableDictionaryRef options
= NULL
;
3383 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3384 &kCFTypeDictionaryKeyCallBacks
,
3385 &kCFTypeDictionaryValueCallBacks
), errOut
);
3387 SecPolicyAddBasicX509Options(options
);
3389 /* Require id-kp-timeStamping extendedKeyUsage to be present. */
3390 add_eku(options
, &oidExtendedKeyUsageTimeStamping
);
3392 require(result
= SecPolicyCreate(kSecPolicyAppleTimeStamping
,
3393 kSecPolicyNameTimeStamping
, options
), errOut
);
3396 CFReleaseSafe(options
);
3401 @function SecPolicyCreateApplePayIssuerEncryption
3402 @abstract Check for intermediate certificate 'Apple Worldwide Developer Relations CA - G2' by name,
3403 and ECC apple anchor.
3404 Leaf cert must have Key Encipherment and Key Agreement usage.
3405 Leaf cert must have Apple Pay Issuer Encryption marker OID (1.2.840.113635.100.6.39).
3407 SecPolicyRef
SecPolicyCreateApplePayIssuerEncryption(void)
3409 SecPolicyRef result
= NULL
;
3410 CFMutableDictionaryRef options
= NULL
;
3411 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3412 &kCFTypeDictionaryKeyCallBacks
,
3413 &kCFTypeDictionaryValueCallBacks
), errOut
);
3414 SecPolicyAddBasicCertOptions(options
);
3416 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNamePayIssuerEncryption
),
3418 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3420 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
3421 CFSTR("Apple Worldwide Developer Relations CA - G2"));
3423 // Check that leaf has extension with "Apple Pay Issuer Encryption" oid (1.2.840.113635.100.6.39)
3424 add_leaf_marker(options
, &oidAppleCertExtCryptoServicesExtEncryption
);
3426 add_ku(options
, kSecKeyUsageKeyEncipherment
);
3428 require(result
= SecPolicyCreate(kSecPolicyApplePayIssuerEncryption
,
3429 kSecPolicyNamePayIssuerEncryption
, options
), errOut
);
3432 CFReleaseSafe(options
);
3437 @function SecPolicyCreateAppleATVVPNProfileSigning
3438 @abstract Check for leaf marker OID 1.2.840.113635.100.6.43,
3439 intermediate marker OID 1.2.840.113635.100.6.2.10,
3440 chains to Apple Root CA, path length 3
3442 SecPolicyRef
SecPolicyCreateAppleATVVPNProfileSigning(void)
3444 SecPolicyRef result
= NULL
;
3445 CFMutableDictionaryRef options
= NULL
;
3446 CFMutableDictionaryRef appleAnchorOptions
= NULL
;
3447 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3448 &kCFTypeDictionaryKeyCallBacks
,
3449 &kCFTypeDictionaryValueCallBacks
), errOut
);
3451 SecPolicyAddBasicCertOptions(options
);
3453 // Require pinning to the Apple CAs (including test CA for internal releases)
3454 appleAnchorOptions
= CFDictionaryCreateMutableForCFTypes(NULL
);
3455 require(appleAnchorOptions
, errOut
);
3457 if (SecIsInternalRelease()) {
3458 CFDictionarySetValue(appleAnchorOptions
,
3459 kSecPolicyAppleAnchorIncludeTestRoots
, kCFBooleanTrue
);
3462 add_element(options
, kSecPolicyCheckAnchorApple
, appleAnchorOptions
);
3464 // Cert chain length 3
3465 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3467 // Check leaf for Apple ATV VPN Profile Signing OID (1.2.840.113635.100.6.43)
3468 add_leaf_marker(options
, &oidAppleCertExtATVVPNProfileSigning
);
3470 // Check intermediate for Apple System Integration 2 CA intermediate marker (1.2.840.113635.100.6.2.10)
3471 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleSystemIntg2
);
3473 // Ensure that revocation is checked (OCSP only)
3474 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationOCSP
);
3476 require(result
= SecPolicyCreate(kSecPolicyAppleATVVPNProfileSigning
,
3477 kSecPolicyNameATVVPNProfileSigning
, options
), errOut
);
3480 CFReleaseSafe(options
);
3481 CFReleaseSafe(appleAnchorOptions
);
3485 SecPolicyRef
SecPolicyCreateAppleHomeKitServerAuth(CFStringRef hostname
) {
3486 CFMutableDictionaryRef appleAnchorOptions
= NULL
;
3487 CFMutableDictionaryRef options
= NULL
;
3488 SecPolicyRef result
= NULL
;
3489 CFDataRef oid
= NULL
;
3491 options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0, &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
3492 require(options
, errOut
);
3494 SecPolicyAddBasicX509Options(options
);
3496 CFDictionaryAddValue(options
, kSecPolicyCheckSSLHostname
, hostname
);
3498 add_eku(options
, &oidExtendedKeyUsageServerAuth
);
3500 if (requireUATPinning(kSecPolicyNameAppleHomeKitService
)) {
3502 // Cert chain length 3
3503 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3505 // Apple anchors, allowing test anchors for internal release
3506 SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameAppleHomeKitService
);
3508 add_leaf_marker(options
, &oidAppleCertExtHomeKitServerAuth
);
3510 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleHomeKitServerCA
);
3513 /* Check for weak hashes */
3514 require(SecPolicyRemoveWeakHashOptions(options
), errOut
);
3515 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
3517 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
3519 result
= SecPolicyCreate(kSecPolicyAppleHomeKitServerAuth
,
3520 kSecPolicyNameAppleHomeKitService
, options
);
3521 require(result
, errOut
);
3524 CFReleaseSafe(appleAnchorOptions
);
3525 CFReleaseSafe(options
);
3530 SecPolicyRef
SecPolicyCreateAppleExternalDeveloper(void) {
3531 CFMutableDictionaryRef options
= NULL
;
3532 SecPolicyRef result
= NULL
;
3534 /* Create basic Apple pinned policy */
3535 require(result
= SecPolicyCreateApplePinned(kSecPolicyNameExternalDeveloper
,
3536 CFSTR("1.2.840.113635.100.6.2.1"), // WWDR Intermediate OID
3537 CFSTR("1.2.840.113635.100.6.1.2")), // "iPhone Developer" leaf OID
3540 require_action(options
= CFDictionaryCreateMutableCopy(NULL
, 0, result
->_options
), errOut
, CFReleaseNull(result
));
3542 /* Additional intermediate OIDs */
3543 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
,
3544 CFSTR("1.2.840.113635.100.6.2.6")); // "Developer ID" Intermediate OID
3546 /* Addtional leaf OIDS */
3547 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.4")); // "iPhone Distribution" leaf OID
3548 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.5")); // "Safari Developer" leaf OID
3549 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.7")); // "3rd Party Mac Developer Application" leaf OID
3550 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.8")); // "3rd Party Mac Developer Installer" leaf OID
3551 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.12")); // "Mac Developer" leaf OID
3552 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.13")); // "Developer ID Application" leaf OID
3553 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.14")); // "Developer ID Installer" leaf OID
3556 add_eku_string(options
, CFSTR("1.3.6.1.5.5.7.3.3")); // CodeSigning EKU
3557 add_eku_string(options
, CFSTR("1.2.840.113635.100.4.8")); // "Safari Developer" EKU
3558 add_eku_string(options
, CFSTR("1.2.840.113635.100.4.9")); // "3rd Party Mac Developer Installer" EKU
3559 add_eku_string(options
, CFSTR("1.2.840.113635.100.4.13")); // "Developer ID Installer" EKU
3561 CFReleaseSafe(result
->_options
);
3562 result
->_options
= CFRetainSafe(options
);
3564 SecPolicySetOid(result
, kSecPolicyAppleExternalDeveloper
);
3567 CFReleaseSafe(options
);
3571 /* This one is special because the intermediate has no marker OID */
3572 SecPolicyRef
SecPolicyCreateAppleSoftwareSigning(void) {
3573 CFMutableDictionaryRef options
= NULL
;
3574 SecPolicyRef result
= NULL
;
3576 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3577 &kCFTypeDictionaryKeyCallBacks
,
3578 &kCFTypeDictionaryValueCallBacks
), errOut
);
3580 SecPolicyAddBasicCertOptions(options
);
3582 /* Anchored to the Apple Roots */
3583 require_quiet(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameSoftwareSigning
),
3586 /* Exactly 3 certs in the chain */
3587 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3589 /* Intermediate Common Name matches */
3590 add_element(options
, kSecPolicyCheckIssuerCommonName
, CFSTR("Apple Code Signing Certification Authority"));
3592 /* Leaf marker OID matches */
3593 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.22"));
3595 /* Leaf has CodeSigning EKU */
3596 add_eku_string(options
, CFSTR("1.3.6.1.5.5.7.3.3"));
3598 /* Check revocation using any available method */
3599 add_element(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
3601 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
3602 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
3604 require(result
= SecPolicyCreate(kSecPolicyAppleSoftwareSigning
,
3605 kSecPolicyNameSoftwareSigning
, options
), errOut
);
3608 CFReleaseSafe(options
);
3612 /* subject:/CN=SEP Root CA/O=Apple Inc./ST=California */
3613 /* SKID: 58:EF:D6:BE:C5:82:B0:54:CD:18:A6:84:AD:A2:F6:7B:7B:3A:7F:CF */
3614 /* Not Before: Jun 24 21:43:24 2014 GMT, Not After : Jun 24 21:43:24 2029 GMT */
3615 /* Signature Algorithm: ecdsa-with-SHA384 */
3616 const uint8_t SEPRootCA_SHA256
[kSecPolicySHA256Size
] = {
3617 0xd1, 0xdf, 0x82, 0x00, 0xf3, 0x89, 0x4e, 0xe9, 0x96, 0xf3, 0x77, 0xdf, 0x76, 0x3b, 0x0a, 0x16,
3618 0x8f, 0xd9, 0x6c, 0x58, 0xc0, 0x3e, 0xc9, 0xb0, 0x5f, 0xa5, 0x64, 0x79, 0xc0, 0xe8, 0xc9, 0xe7
3621 SecPolicyRef
SecPolicyCreateAppleUniqueDeviceCertificate(CFDataRef testRootHash
) {
3622 CFMutableDictionaryRef options
= NULL
;
3623 CFDictionaryRef keySizes
= NULL
;
3624 CFNumberRef ecSize
= NULL
;
3625 SecPolicyRef result
= NULL
;
3627 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3628 &kCFTypeDictionaryKeyCallBacks
,
3629 &kCFTypeDictionaryValueCallBacks
), errOut
);
3631 /* Device certificate should never expire */
3632 SecPolicyAddBasicCertOptions(options
);
3634 /* Anchored to the SEP Root CA. Allow alternative root for developers */
3635 require(SecPolicyAddAnchorSHA256Options(options
, SEPRootCA_SHA256
),errOut
);
3636 if (testRootHash
&& SecIsInternalRelease() && (kSecPolicySHA256Size
== CFDataGetLength(testRootHash
))) {
3637 add_element(options
, kSecPolicyCheckAnchorSHA256
, testRootHash
);
3640 /* Exactly 3 certs in the chain */
3641 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3643 /* Intermediate has marker OID with value */
3644 add_intermediate_marker_value_string(options
, CFSTR("1.2.840.113635.100.6.44"), CFSTR("ucrt"));
3646 /* Leaf has marker OID with varying value that can't be pre-determined */
3647 add_element(options
, kSecPolicyCheckLeafMarkerOidWithoutValueCheck
, CFSTR("1.2.840.113635.100.10.1"));
3649 /* RSA key sizes are disallowed. EC key sizes are P-256 or larger. */
3650 require(ecSize
= CFNumberCreateWithCFIndex(NULL
, 256), errOut
);
3651 require(keySizes
= CFDictionaryCreate(NULL
, (const void**)&kSecAttrKeyTypeEC
,
3652 (const void**)&ecSize
, 1,
3653 &kCFTypeDictionaryKeyCallBacks
,
3654 &kCFTypeDictionaryValueCallBacks
), errOut
);
3655 add_element(options
, kSecPolicyCheckKeySize
, keySizes
);
3658 require(result
= SecPolicyCreate(kSecPolicyAppleUniqueDeviceIdentifierCertificate
,
3659 kSecPolicyNameUniqueDeviceIdentifierCertificate
, options
), errOut
);
3662 CFReleaseSafe(options
);
3663 CFReleaseSafe(keySizes
);
3664 CFReleaseSafe(ecSize
);
3668 SecPolicyRef
SecPolicyCreateAppleWarsaw(void) {
3669 CFMutableDictionaryRef options
= NULL
;
3670 SecPolicyRef result
= NULL
;
3671 #if TARGET_OS_BRIDGE
3672 CFMutableDictionaryRef appleAnchorOptions
= NULL
;
3675 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3676 &kCFTypeDictionaryKeyCallBacks
,
3677 &kCFTypeDictionaryValueCallBacks
), errOut
);
3679 SecPolicyAddBasicX509Options(options
);
3681 /* Anchored to the Apple Roots. */
3682 require_quiet(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameWarsaw
),
3685 /* Exactly 3 certs in the chain */
3686 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3688 /* Intermediate marker OID matches input OID */
3689 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.14"));
3691 /* Leaf marker OID matches input OID */
3692 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.29"));
3694 /* Check revocation using any available method */
3695 add_element(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
3697 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
3698 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
3700 require(result
= SecPolicyCreate(kSecPolicyAppleWarsaw
,
3701 kSecPolicyNameWarsaw
, options
), errOut
);
3704 CFReleaseSafe(options
);
3708 SecPolicyRef
SecPolicyCreateAppleSecureIOStaticAsset(void) {
3709 CFMutableDictionaryRef options
= NULL
;
3710 SecPolicyRef result
= NULL
;
3711 #if TARGET_OS_BRIDGE
3712 CFMutableDictionaryRef appleAnchorOptions
= NULL
;
3715 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3716 &kCFTypeDictionaryKeyCallBacks
,
3717 &kCFTypeDictionaryValueCallBacks
), errOut
);
3719 /* This certificate cannot expire so that assets always load */
3720 SecPolicyAddBasicCertOptions(options
);
3722 /* Anchored to the Apple Roots. */
3723 #if TARGET_OS_BRIDGE
3724 /* On the bridge, test roots are gated in the trust and policy servers. */
3725 require_quiet(appleAnchorOptions
= CFDictionaryCreateMutableForCFTypes(NULL
), errOut
);
3726 CFDictionarySetValue(appleAnchorOptions
,
3727 kSecPolicyAppleAnchorIncludeTestRoots
, kCFBooleanTrue
);
3728 add_element(options
, kSecPolicyCheckAnchorApple
, appleAnchorOptions
);
3729 CFReleaseSafe(appleAnchorOptions
);
3731 require_quiet(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameSecureIOStaticAsset
),
3735 /* Exactly 3 certs in the chain */
3736 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3738 /* Intermediate marker OID matches ASI CA */
3739 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.10"));
3741 /* Leaf marker OID matches static IO OID */
3742 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.50"));
3744 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
3745 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
3747 require(result
= SecPolicyCreate(kSecPolicyAppleSecureIOStaticAsset
,
3748 kSecPolicyNameSecureIOStaticAsset
, options
), errOut
);
3751 CFReleaseSafe(options
);
3755 SecPolicyRef
SecPolicyCreateAppleAppTransportSecurity(void) {
3756 CFMutableDictionaryRef options
= NULL
;
3757 SecPolicyRef result
= NULL
;
3758 CFMutableArrayRef disallowedHashes
= NULL
;
3760 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3761 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
3763 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
3764 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
3766 /* Hash algorithm is SHA-256 or better */
3767 require(disallowedHashes
= CFArrayCreateMutable(NULL
, 5, &kCFTypeArrayCallBacks
), errOut
);
3768 CFArrayAppendValue(disallowedHashes
, kSecSignatureDigestAlgorithmMD2
);
3769 CFArrayAppendValue(disallowedHashes
, kSecSignatureDigestAlgorithmMD4
);
3770 CFArrayAppendValue(disallowedHashes
, kSecSignatureDigestAlgorithmMD5
);
3771 CFArrayAppendValue(disallowedHashes
, kSecSignatureDigestAlgorithmSHA1
);
3772 CFArrayAppendValue(disallowedHashes
, kSecSignatureDigestAlgorithmSHA224
);
3774 add_element(options
, kSecPolicyCheckSignatureHashAlgorithms
, disallowedHashes
);
3776 require_quiet(result
= SecPolicyCreate(kSecPolicyAppleAppTransportSecurity
,
3777 kSecPolicyNameAppTransportSecurity
,
3781 CFReleaseSafe(options
);
3785 SecPolicyRef
SecPolicyCreateMobileSoftwareUpdate(void) {
3786 CFMutableDictionaryRef options
= NULL
;
3787 SecPolicyRef result
= NULL
;
3788 #if TARGET_OS_BRIDGE
3789 CFMutableDictionaryRef appleAnchorOptions
= NULL
;
3792 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3793 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
3795 /* No expiration check. */
3796 SecPolicyAddBasicCertOptions(options
);
3799 require_quiet(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameMobileSoftwareUpdate
),
3802 /* Exactly 3 certs in the chain */
3803 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3805 /* Intermediate marker OID is iPhone CA OID */
3806 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.18"));
3808 /* Leaf marker OID is either the prod MSU OID, or, on internal builds, the prodQA OID */
3809 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.57.2"));
3810 if (SecIsInternalRelease()) {
3811 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.57.1"));
3814 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
3815 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
3817 require(result
= SecPolicyCreate(kSecPolicyAppleMobileSoftwareUpdate
,
3818 kSecPolicyNameMobileSoftwareUpdate
, options
), errOut
);
3821 CFReleaseNull(options
);
3825 /* subject:/CN=Basic Attestation System Root CA/O=Apple Inc./ST=California */
3826 /* SKID: FE:D1:D1:C2:08:07:03:D5:B9:3C:34:B2:BB:FD:7C:3A:99:25:1B:8F */
3827 /* Not Before: Apr 20 00:22:09 2017 GMT, Not After : Mar 22 00:00:00 2032 GMT */
3828 /* Signature Algorithm: ecdsa-with-SHA384 */
3829 const uint8_t BASystemRootCA_SHA256
[kSecPolicySHA256Size
] = {
3830 0x10, 0xD3, 0xC8, 0x67, 0xF0, 0xAE, 0xFB, 0x24, 0x31, 0xA0, 0xA9, 0x7A, 0x88, 0x18, 0xBD, 0x64,
3831 0xF7, 0xF9, 0x0F, 0xFE, 0x11, 0x94, 0x48, 0x4F, 0xCA, 0x97, 0xF0, 0xF2, 0x9E, 0xCA, 0x00, 0x47
3834 /* subject:/CN=Basic Attestation User Root CA/O=Apple Inc./ST=California */
3835 /* SKID: 83:E5:A3:21:9E:B0:74:C3:F9:61:90:FD:97:4E:23:10:76:A4:A3:F2 */
3836 /* Not Before: Apr 19 21:41:56 2017 GMT, Not After : Mar 22 00:00:00 2032 GMT */
3837 /* Signature Algorithm: ecdsa-with-SHA384 */
3838 const uint8_t BAUserRootCA_SHA256
[kSecPolicySHA256Size
] = {
3839 0x03, 0x75, 0x1c, 0x80, 0xfc, 0xbe, 0x58, 0x19, 0xd1, 0x70, 0xd2, 0x67, 0xce, 0x1a, 0xd6, 0xd0,
3840 0x94, 0x40, 0x7c, 0x91, 0xd8, 0x73, 0xd7, 0xa6, 0x56, 0x2d, 0xe3, 0x66, 0x6d, 0x35, 0x94, 0xc6
3843 SecPolicyRef
SecPolicyCreateAppleBasicAttestationSystem(CFDataRef testRootHash
) {
3844 CFMutableDictionaryRef options
= NULL
;
3845 SecPolicyRef result
= NULL
;
3847 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3848 &kCFTypeDictionaryKeyCallBacks
,
3849 &kCFTypeDictionaryValueCallBacks
), errOut
);
3850 /* BAA certs expire */
3851 SecPolicyAddBasicX509Options(options
);
3853 /* Anchored to one of the Basic Attestation roots. Allow alternative root for developers */
3854 SecPolicyAddAnchorSHA256Options(options
, BASystemRootCA_SHA256
);
3855 if (testRootHash
&& SecIsInternalRelease() && (kSecPolicySHA256Size
== CFDataGetLength(testRootHash
))) {
3856 add_element(options
, kSecPolicyCheckAnchorSHA256
, testRootHash
);
3859 /* Exactly 3 certs in the chain */
3860 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3862 require(result
= SecPolicyCreate(kSecPolicyAppleBasicAttestationSystem
,
3863 kSecPolicyNameBasicAttestationSystem
, options
), errOut
);
3866 CFReleaseSafe(options
);
3870 SecPolicyRef
SecPolicyCreateAppleBasicAttestationUser(CFDataRef testRootHash
) {
3871 CFMutableDictionaryRef options
= NULL
;
3872 SecPolicyRef result
= NULL
;
3874 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3875 &kCFTypeDictionaryKeyCallBacks
,
3876 &kCFTypeDictionaryValueCallBacks
), errOut
);
3877 /* BAA certs expire */
3878 SecPolicyAddBasicX509Options(options
);
3880 /* Anchored to one of the Basic Attestation roots. Allow alternative root for developers */
3881 SecPolicyAddAnchorSHA256Options(options
, BAUserRootCA_SHA256
);
3882 if (testRootHash
&& SecIsInternalRelease() && (kSecPolicySHA256Size
== CFDataGetLength(testRootHash
))) {
3883 add_element(options
, kSecPolicyCheckAnchorSHA256
, testRootHash
);
3886 /* Exactly 3 certs in the chain */
3887 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3889 require(result
= SecPolicyCreate(kSecPolicyAppleBasicAttestationUser
,
3890 kSecPolicyNameBasicAttestationUser
, options
), errOut
);
3893 CFReleaseSafe(options
);
3897 SecPolicyRef
SecPolicyCreateiAPSWAuthWithExpiration(bool checkExpiration
) {
3898 CFMutableDictionaryRef options
= NULL
;
3899 SecPolicyRef result
= NULL
;
3901 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3902 &kCFTypeDictionaryKeyCallBacks
,
3903 &kCFTypeDictionaryValueCallBacks
), errOut
);
3905 /* iAP checks expiration on developement certs, but not on production certs */
3906 if (checkExpiration
) {
3907 SecPolicyAddBasicX509Options(options
);
3909 SecPolicyAddBasicCertOptions(options
);
3912 /* Exactly 2 certs in the chain */
3913 require(SecPolicyAddChainLengthOptions(options
, 2), errOut
);
3915 /* iAP SW Auth General Capabilities Extension present */
3916 add_element(options
, kSecPolicyCheckLeafMarkerOidWithoutValueCheck
, CFSTR("1.2.840.113635.100.6.59.1"));
3918 require(result
= SecPolicyCreate(kSecPolicyAppleiAPSWAuth
,
3919 kSecPolicyNameiAPSWAuth
, options
), errOut
);
3922 CFReleaseSafe(options
);
3926 SecPolicyRef
SecPolicyCreateiAPSWAuth(void) {
3927 /* By default, iAP SW Auth certs don't expire */
3928 return SecPolicyCreateiAPSWAuthWithExpiration(false);
3931 SecPolicyRef
SecPolicyCreateDemoDigitalCatalogSigning(void) {
3932 CFMutableDictionaryRef options
= NULL
;
3933 SecPolicyRef result
= NULL
;
3935 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3936 &kCFTypeDictionaryKeyCallBacks
,
3937 &kCFTypeDictionaryValueCallBacks
), errOut
);
3938 SecPolicyAddBasicX509Options(options
);
3940 /* Exactly 3 certs in the chain */
3941 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3943 /* Demo Signing Extension present in leaf */
3944 add_element(options
, kSecPolicyCheckLeafMarkerOid
, CFSTR("1.2.840.113635.100.6.60"));
3946 /* Issuer common name is "DemoUnit CA" */
3947 add_element(options
, kSecPolicyCheckIssuerCommonName
, CFSTR("DemoUnit CA"));
3949 require(result
= SecPolicyCreate(kSecPolicyAppleDemoDigitalCatalog
,
3950 kSecPolicyNameDemoDigitalCatalog
, options
), errOut
);
3953 CFReleaseSafe(options
);
3957 SecPolicyRef
SecPolicyCreateAppleAssetReceipt(void) {
3958 CFMutableDictionaryRef options
= NULL
;
3959 SecPolicyRef result
= NULL
;
3961 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3962 &kCFTypeDictionaryKeyCallBacks
,
3963 &kCFTypeDictionaryValueCallBacks
), errOut
);
3965 /* No expiration check. */
3966 SecPolicyAddBasicCertOptions(options
);
3969 require_quiet(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameAssetReceipt
), errOut
);
3971 /* Exactly 3 certs in the chain */
3972 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3974 /* Intermediate marker OID is Apple System Integration 2 CA */
3975 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.10"));
3977 /* Leaf marker OID is the Asset Receipt OID */
3978 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.61"));
3980 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
3981 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
3983 require(result
= SecPolicyCreate(kSecPolicyAppleAssetReceipt
,
3984 kSecPolicyNameAssetReceipt
, options
), errOut
);
3987 CFReleaseNull(options
);
3991 SecPolicyRef
SecPolicyCreateAppleDeveloperIDPlusTicket(void) {
3992 CFMutableDictionaryRef options
= NULL
;
3993 SecPolicyRef result
= NULL
;
3995 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3996 &kCFTypeDictionaryKeyCallBacks
,
3997 &kCFTypeDictionaryValueCallBacks
), errOut
);
3999 /* No expiration check. */
4000 SecPolicyAddBasicCertOptions(options
);
4003 require_quiet(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameDeveloperIDPlusTicket
), errOut
);
4005 /* Exactly 3 certs in the chain */
4006 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
4008 /* Intermediate marker OID is Apple System Integration CA 4 */
4009 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.17"));
4011 /* Leaf marker OID is the Developer ID+ Ticket OID */
4012 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.30"));
4014 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
4015 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
4017 require(result
= SecPolicyCreate(kSecPolicyAppleDeveloperIDPlusTicket
,
4018 kSecPolicyNameDeveloperIDPlusTicket
, options
), errOut
);
4021 CFReleaseNull(options
);
4025 SecPolicyRef
SecPolicyCreateAppleFDRProvisioning(void) {
4026 CFMutableDictionaryRef options
= NULL
;
4027 SecPolicyRef result
= NULL
;
4029 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
4030 &kCFTypeDictionaryKeyCallBacks
,
4031 &kCFTypeDictionaryValueCallBacks
), errOut
);
4033 /* No expiration check. */
4034 SecPolicyAddBasicCertOptions(options
);
4036 require(result
= SecPolicyCreate(kSecPolicyAppleFDRProvisioning
,
4037 kSecPolicyNameFDRProvisioning
, options
), errOut
);
4039 CFReleaseNull(options
);
4043 /* subject:/CN=Component Root CA/O=Apple Inc./ST=California */
4044 /* SKID: 90:D1:56:A9:3E:B4:EE:8C:D0:10:4B:9F:17:1C:5B:55:F2:12:F6:4C */
4045 /* Not Before: Dec 19 19:31:54 2018 GMT, Not After : Dec 16 00:00:00 2043 GMT */
4046 /* Signature Algorithm: ecdsa-with-SHA384 */
4047 const uint8_t ComponentRootCA_SHA256
[kSecPolicySHA256Size
] = {
4048 0x2f, 0x71, 0x9d, 0xbf, 0x3c, 0xcd, 0xe7, 0xc2, 0xb2, 0x59, 0x3f, 0x32, 0x1f, 0x90, 0xf3, 0x42,
4049 0x42, 0xaa, 0x84, 0xa1, 0xb2, 0x0d, 0xca, 0xcc, 0x10, 0xc0, 0x5b, 0x26, 0xd6, 0x23, 0xb8, 0x47,
4051 SecPolicyRef
SecPolicyCreateAppleComponentCertificate(CFDataRef testRootHash
) {
4052 CFMutableDictionaryRef options
= NULL
;
4053 SecPolicyRef result
= NULL
;
4055 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
4056 &kCFTypeDictionaryKeyCallBacks
,
4057 &kCFTypeDictionaryValueCallBacks
), errOut
);
4059 /* Component certificates don't expire */
4060 SecPolicyAddBasicCertOptions(options
);
4062 /* Anchored to one of the Component roots. Allow alternative root for developers */
4063 SecPolicyAddAnchorSHA256Options(options
, ComponentRootCA_SHA256
);
4064 if (testRootHash
&& SecIsInternalRelease() && (kSecPolicySHA256Size
== CFDataGetLength(testRootHash
))) {
4065 add_element(options
, kSecPolicyCheckAnchorSHA256
, testRootHash
);
4068 /* Exactly 3 certs in the chain */
4069 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
4071 /* Leaf and intermediate must contain Component Type OID */
4072 add_element(options
, kSecPolicyCheckLeafMarkerOidWithoutValueCheck
, CFSTR("1.2.840.113635.100.11.1"));
4073 add_element(options
, kSecPolicyCheckIntermediateMarkerOidWithoutValueCheck
, CFSTR("1.2.840.113635.100.11.1"));
4075 require(result
= SecPolicyCreate(kSecPolicyAppleComponentCertificate
,
4076 kSecPolicyNameComponentCertificate
, options
), errOut
);
4078 CFReleaseNull(options
);
4082 SecPolicyRef
SecPolicyCreateAppleKeyTransparency(CFStringRef applicationId
) {
4083 CFMutableDictionaryRef options
= NULL
;
4084 SecPolicyRef result
= NULL
;
4086 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
4087 &kCFTypeDictionaryKeyCallBacks
,
4088 &kCFTypeDictionaryValueCallBacks
), errOut
);
4090 /* KT signing certs don't expire */
4091 SecPolicyAddBasicCertOptions(options
);
4094 require_quiet(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameKeyTransparency
), errOut
);
4096 /* Exactly 3 certs in the chain */
4097 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
4099 /* Intermediate marker OID matches AAI CA 5 */
4100 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.3"));
4102 /* Leaf marker extension matches input applicationId */
4103 add_leaf_marker_value_string(options
, CFSTR("1.2.840.113635.100.12.4"), applicationId
);
4105 /* Check revocation using any available method */
4106 add_element(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
4108 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
4109 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
4111 /* Check for weak hashes */
4112 require(SecPolicyRemoveWeakHashOptions(options
), errOut
);
4114 /* Future CT requirement */
4116 require(result
= SecPolicyCreate(kSecPolicyAppleKeyTransparency
,
4117 kSecPolicyNameKeyTransparency
, options
), errOut
);
4119 CFReleaseNull(options
);
4123 SecPolicyRef
SecPolicyCreateAlisha(void) {
4124 CFMutableDictionaryRef options
= NULL
;
4125 SecPolicyRef result
= NULL
;
4126 CFDictionaryRef keySizes
= NULL
;
4127 CFNumberRef ecSize
= NULL
;
4129 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
4130 &kCFTypeDictionaryKeyCallBacks
,
4131 &kCFTypeDictionaryValueCallBacks
), errOut
);
4133 /* Alisha certs don't expire */
4134 SecPolicyAddBasicCertOptions(options
);
4136 /* RSA key sizes are disallowed. EC key sizes are P-256 or larger. */
4137 require(ecSize
= CFNumberCreateWithCFIndex(NULL
, 256), errOut
);
4138 require(keySizes
= CFDictionaryCreate(NULL
, (const void**)&kSecAttrKeyTypeEC
,
4139 (const void**)&ecSize
, 1,
4140 &kCFTypeDictionaryKeyCallBacks
,
4141 &kCFTypeDictionaryValueCallBacks
), errOut
);
4142 add_element(options
, kSecPolicyCheckKeySize
, keySizes
);
4144 /* Check for weak hashes */
4145 require(SecPolicyRemoveWeakHashOptions(options
), errOut
);
4147 require(result
= SecPolicyCreate(kSecPolicyAppleAlisha
,
4148 kSecPolicyNameAlisha
, options
), errOut
);
4150 CFReleaseNull(options
);
4151 CFReleaseNull(keySizes
);
4152 CFReleaseNull(ecSize
);
4156 SecPolicyRef
SecPolicyCreateMeasuredBootPolicySigning(void) {
4157 CFMutableDictionaryRef options
= NULL
;
4158 SecPolicyRef result
= NULL
;
4160 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
4161 &kCFTypeDictionaryKeyCallBacks
,
4162 &kCFTypeDictionaryValueCallBacks
), errOut
);
4164 /* No expiration check. */
4165 SecPolicyAddBasicCertOptions(options
);
4167 /* Exactly 3 certs in the chain */
4168 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
4170 /* Corporate Signing subCA */
4171 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.24.17"));
4173 /* Measured Boot Policy Signing Leaf OID */
4174 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.26.6.1"));
4176 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
4177 require(SecPolicyAddStrongKeySizeOptions(options
), errOut
);
4179 require(result
= SecPolicyCreate(kSecPolicyAppleMeasuredBootPolicySigning
,
4180 kSecPolicyNameMeasuredBootPolicySigning
, options
), errOut
);
4183 CFReleaseSafe(options
);
4187 CF_RETURNS_RETAINED SecPolicyRef
SecPolicyCreateEscrowServiceIdKeySigning(void)
4189 SecPolicyRef result
= NULL
;
4190 CFMutableDictionaryRef options
= NULL
;
4191 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
4192 &kCFTypeDictionaryKeyCallBacks
,
4193 &kCFTypeDictionaryValueCallBacks
), errOut
);
4195 // X509, ignoring date validity
4196 SecPolicyAddBasicCertOptions(options
);
4198 add_ku(options
, kSecKeyUsageDigitalSignature
);
4200 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
,
4201 CFSTR("Escrow Service ID Key"));
4203 /* Exactly 2 certs in the chain */
4204 require(SecPolicyAddChainLengthOptions(options
, 2), errOut
);
4206 require(result
= SecPolicyCreate(kSecPolicyAppleEscrowServiceIdKeySigning
,
4207 kSecPolicyNameEscrowServiceIdKeySigning
, options
), errOut
);
4210 CFReleaseSafe(options
);
4214 CF_RETURNS_RETAINED SecPolicyRef
SecPolicyCreatePCSEscrowServiceIdKeySigning(void)
4216 SecPolicyRef result
= NULL
;
4217 CFMutableDictionaryRef options
= NULL
;
4218 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
4219 &kCFTypeDictionaryKeyCallBacks
,
4220 &kCFTypeDictionaryValueCallBacks
), errOut
);
4222 SecPolicyAddBasicX509Options(options
);
4223 add_ku(options
, kSecKeyUsageDigitalSignature
);
4225 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
,
4226 CFSTR("Effaceable Service ID Key"));
4228 /* Exactly 2 certs in the chain */
4229 require(SecPolicyAddChainLengthOptions(options
, 2), errOut
);
4231 require(result
= SecPolicyCreate(kSecPolicyApplePCSEscrowServiceIdKeySigning
,
4232 kSecPolicyNamePCSEscrowServiceIdKeySigning
, options
), errOut
);
4235 CFReleaseSafe(options
);