2 * Copyright (c) 2007-2015 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 <libDER/oidsPriv.h>
42 #include <utilities/SecCFError.h>
43 #include <utilities/SecCFWrappers.h>
44 #include <utilities/array_size.h>
45 #include <ipc/securityd_client.h>
46 #if TARGET_OS_EMBEDDED
47 #include <MobileGestalt.h>
49 #include <sys/utsname.h>
52 #include <utilities/SecInternalReleasePriv.h>
54 /********************************************************
55 **************** SecPolicy Constants *******************
56 ********************************************************/
58 // MARK: SecPolicy Constants
60 #define SEC_CONST_DECL(k,v) const CFStringRef k = CFSTR(v);
62 /********************************************************
63 ************** Unverified Leaf Checks ******************
64 ********************************************************/
65 SEC_CONST_DECL (kSecPolicyCheckSSLHostname
, "SSLHostname");
66 SEC_CONST_DECL (kSecPolicyCheckEmail
, "email");
68 /* Checks that the issuer of the leaf has exactly one Common Name and that it
69 matches the specified string. */
70 SEC_CONST_DECL (kSecPolicyCheckIssuerCommonName
, "IssuerCommonName");
72 /* Checks that the leaf has exactly one Common Name and that it
73 matches the specified string. */
74 SEC_CONST_DECL (kSecPolicyCheckSubjectCommonName
, "SubjectCommonName");
76 /* Checks that the leaf has exactly one Common Name and that it has the
77 specified string as a prefix. */
78 SEC_CONST_DECL (kSecPolicyCheckSubjectCommonNamePrefix
, "SubjectCommonNamePrefix");
80 /* Checks that the leaf has exactly one Common Name and that it
81 matches the specified "<string>" or "TEST <string> TEST". */
82 SEC_CONST_DECL (kSecPolicyCheckSubjectCommonNameTEST
, "SubjectCommonNameTEST");
84 /* Checks that the leaf has exactly one Organization and that it
85 matches the specified string. */
86 SEC_CONST_DECL (kSecPolicyCheckSubjectOrganization
, "SubjectOrganization");
88 /* Checks that the leaf has exactly one Organizational Unit and that it
89 matches the specified string. */
90 SEC_CONST_DECL (kSecPolicyCheckSubjectOrganizationalUnit
, "SubjectOrganizationalUnit");
92 /* Check that the leaf is not valid before the specified date (or verifyDate
93 if none is provided?). */
94 SEC_CONST_DECL (kSecPolicyCheckNotValidBefore
, "NotValidBefore");
96 SEC_CONST_DECL (kSecPolicyCheckEAPTrustedServerNames
, "EAPTrustedServerNames");
98 SEC_CONST_DECL (kSecPolicyCheckCertificatePolicy
, "CertificatePolicy");
101 /* Check for basic constraints on leaf to be valid. (rfc5280 check) */
102 SEC_CONST_DECL (kSecPolicyCheckLeafBasicConstraints
, "LeafBasicContraints");
105 /********************************************************
106 *********** Unverified Intermediate Checks *************
107 ********************************************************/
108 SEC_CONST_DECL (kSecPolicyCheckKeyUsage
, "KeyUsage"); /* (rfc5280 check) */
109 SEC_CONST_DECL (kSecPolicyCheckExtendedKeyUsage
, "ExtendedKeyUsage"); /* (rfc5280 check) */
110 SEC_CONST_DECL (kSecPolicyCheckBasicContraints
, "BasicContraints"); /* (rfc5280 check) */
111 SEC_CONST_DECL (kSecPolicyCheckQualifiedCertStatements
, "QualifiedCertStatements"); /* (rfc5280 check) */
112 SEC_CONST_DECL (kSecPolicyCheckIntermediateSPKISHA256
, "IntermediateSPKISHA256")
114 /********************************************************
115 ************** Unverified Anchor Checks ****************
116 ********************************************************/
117 SEC_CONST_DECL (kSecPolicyCheckAnchorSHA1
, "AnchorSHA1");
119 /* Fake key for isAnchored check. */
120 SEC_CONST_DECL (kSecPolicyCheckAnchorTrusted
, "AnchorTrusted");
122 /* Anchor is one of the apple trust anchors */
123 SEC_CONST_DECL (kSecPolicyCheckAnchorApple
, "AnchorApple");
125 /* options for kSecPolicyCheckAnchorApple */
126 SEC_CONST_DECL (kSecPolicyAppleAnchorIncludeTestRoots
, "AnchorAppleTestRoots");
128 /********************************************************
129 *********** Unverified Certificate Checks **************
130 ********************************************************/
131 /* Unverified Certificate Checks (any of the above) */
132 SEC_CONST_DECL (kSecPolicyCheckNonEmptySubject
, "NonEmptySubject");
133 SEC_CONST_DECL (kSecPolicyCheckIdLinkage
, "IdLinkage") /* (rfc5280 check) */
135 SEC_CONST_DECL (kSecPolicyCheckValidityStarted
, "ValidStarted");
136 SEC_CONST_DECL (kSecPolicyCheckValidityExpired
, "ValidExpired");
138 SEC_CONST_DECL (kSecPolicyCheckValidIntermediates
, "ValidIntermediates");
139 SEC_CONST_DECL (kSecPolicyCheckValidLeaf
, "ValidLeaf");
140 SEC_CONST_DECL (kSecPolicyCheckValidRoot
, "ValidRoot");
144 /********************************************************
145 **************** Verified Path Checks ******************
146 ********************************************************/
147 /* (rfc5280 check) Ideally we should dynamically track all the extensions
148 we processed for each certificate and fail this test if any critical
149 extensions remain. */
150 SEC_CONST_DECL (kSecPolicyCheckCriticalExtensions
, "CriticalExtensions");
152 /* Check that the certificate chain length matches the specificed CFNumberRef
154 SEC_CONST_DECL (kSecPolicyCheckChainLength
, "ChainLength");
156 /* (rfc5280 check) */
157 SEC_CONST_DECL (kSecPolicyCheckBasicCertificateProcessing
, "BasicCertificateProcessing");
159 /********************************************************
160 ******************* Feature toggles ********************
161 ********************************************************/
163 /* Check revocation if specified. */
164 SEC_CONST_DECL (kSecPolicyCheckExtendedValidation
, "ExtendedValidation");
165 SEC_CONST_DECL (kSecPolicyCheckRevocation
, "Revocation");
166 SEC_CONST_DECL (kSecPolicyCheckRevocationResponseRequired
, "RevocationResponseRequired");
168 /* Check Certificate Transparency if specified. */
169 SEC_CONST_DECL (kSecPolicyCheckCertificateTransparency
, "CertificateTransparency");
171 /* If present and true, we never go out to the network for anything
172 (OCSP, CRL or CA Issuer checking) but just used cached data instead. */
173 SEC_CONST_DECL (kSecPolicyCheckNoNetworkAccess
, "NoNetworkAccess");
175 /* Hack to quickly blacklist certain certs. */
176 SEC_CONST_DECL (kSecPolicyCheckBlackListedLeaf
, "BlackListedLeaf");
177 SEC_CONST_DECL (kSecPolicyCheckGrayListedLeaf
, "GrayListedLeaf");
178 SEC_CONST_DECL (kSecPolicyCheckGrayListedKey
, "GrayListedKey");
179 SEC_CONST_DECL (kSecPolicyCheckBlackListedKey
, "BlackListedKey");
181 SEC_CONST_DECL (kSecPolicyCheckLeafMarkerOid
, "CheckLeafMarkerOid");
182 SEC_CONST_DECL (kSecPolicyCheckIntermediateMarkerOid
, "CheckIntermediateMarkerOid");
184 /* Public policy names. */
185 SEC_CONST_DECL (kSecPolicyAppleX509Basic
, "1.2.840.113635.100.1.2");
186 SEC_CONST_DECL (kSecPolicyAppleSSL
, "1.2.840.113635.100.1.3");
187 SEC_CONST_DECL (kSecPolicyAppleSMIME
, "1.2.840.113635.100.1.8");
188 SEC_CONST_DECL (kSecPolicyAppleEAP
, "1.2.840.113635.100.1.9");
189 SEC_CONST_DECL (kSecPolicyAppleSWUpdateSigning
, "1.2.840.113635.100.1.10");
190 SEC_CONST_DECL (kSecPolicyAppleIPsec
, "1.2.840.113635.100.1.11");
191 SEC_CONST_DECL (kSecPolicyApplePKINITClient
, "1.2.840.113635.100.1.14");
192 SEC_CONST_DECL (kSecPolicyApplePKINITServer
, "1.2.840.113635.100.1.15");
193 SEC_CONST_DECL (kSecPolicyAppleCodeSigning
, "1.2.840.113635.100.1.16");
194 SEC_CONST_DECL (kSecPolicyApplePackageSigning
, "1.2.840.113635.100.1.17");
195 SEC_CONST_DECL (kSecPolicyAppleIDValidation
, "1.2.840.113635.100.1.18");
196 SEC_CONST_DECL (kSecPolicyMacAppStoreReceipt
, "1.2.840.113635.100.1.19");
197 SEC_CONST_DECL (kSecPolicyAppleTimeStamping
, "1.2.840.113635.100.1.20");
198 SEC_CONST_DECL (kSecPolicyAppleRevocation
, "1.2.840.113635.100.1.21");
199 SEC_CONST_DECL (kSecPolicyApplePassbookSigning
, "1.2.840.113635.100.1.22");
200 SEC_CONST_DECL (kSecPolicyAppleMobileStore
, "1.2.840.113635.100.1.23");
201 SEC_CONST_DECL (kSecPolicyAppleEscrowService
, "1.2.840.113635.100.1.24");
202 SEC_CONST_DECL (kSecPolicyAppleProfileSigner
, "1.2.840.113635.100.1.25");
203 SEC_CONST_DECL (kSecPolicyAppleQAProfileSigner
, "1.2.840.113635.100.1.26");
204 SEC_CONST_DECL (kSecPolicyAppleTestMobileStore
, "1.2.840.113635.100.1.27");
205 SEC_CONST_DECL (kSecPolicyAppleOTAPKISigner
, "1.2.840.113635.100.1.28");
206 SEC_CONST_DECL (kSecPolicyAppleTestOTAPKISigner
, "1.2.840.113635.100.1.29");
207 /* FIXME: this policy name should be deprecated and replaced with "kSecPolicyAppleIDValidationRecordSigning" */
208 SEC_CONST_DECL (kSecPolicyAppleIDValidationRecordSigningPolicy
, "1.2.840.113625.100.1.30");
209 SEC_CONST_DECL (kSecPolicyAppleSMPEncryption
, "1.2.840.113625.100.1.31");
210 SEC_CONST_DECL (kSecPolicyAppleTestSMPEncryption
, "1.2.840.113625.100.1.32");
211 SEC_CONST_DECL (kSecPolicyAppleServerAuthentication
, "1.2.840.113635.100.1.33");
212 SEC_CONST_DECL (kSecPolicyApplePCSEscrowService
, "1.2.840.113635.100.1.34");
213 SEC_CONST_DECL (kSecPolicyApplePPQSigning
, "1.2.840.113625.100.1.35");
214 SEC_CONST_DECL (kSecPolicyAppleTestPPQSigning
, "1.2.840.113625.100.1.36");
215 SEC_CONST_DECL (kSecPolicyAppleATVAppSigning
, "1.2.840.113625.100.1.37");
216 SEC_CONST_DECL (kSecPolicyAppleTestATVAppSigning
, "1.2.840.113625.100.1.38");
217 SEC_CONST_DECL (kSecPolicyApplePayIssuerEncryption
, "1.2.840.113625.100.1.39");
219 SEC_CONST_DECL (kSecPolicyOid
, "SecPolicyOid");
220 SEC_CONST_DECL (kSecPolicyName
, "SecPolicyName");
221 SEC_CONST_DECL (kSecPolicyClient
, "SecPolicyClient");
222 SEC_CONST_DECL (kSecPolicyRevocationFlags
, "SecPolicyRevocationFlags");
223 SEC_CONST_DECL (kSecPolicyTeamIdentifier
, "SecPolicyTeamIdentifier");
225 /* Private policy names */
226 static CFStringRef kSecPolicyOIDBasicX509
= CFSTR("basicX509");
227 static CFStringRef kSecPolicyOIDSSLServer
= CFSTR("sslServer");
228 static CFStringRef kSecPolicyOIDSSLClient
= CFSTR("sslClient");
229 static CFStringRef kSecPolicyOIDiPhoneActivation
= CFSTR("iPhoneActivation");
230 static CFStringRef kSecPolicyOIDiPhoneDeviceCertificate
=
231 CFSTR("iPhoneDeviceCertificate");
232 static CFStringRef kSecPolicyOIDFactoryDeviceCertificate
=
233 CFSTR("FactoryDeviceCertificate");
234 static CFStringRef kSecPolicyOIDiAP
= CFSTR("iAP");
235 static CFStringRef kSecPolicyOIDiTunesStoreURLBag
= CFSTR("iTunesStoreURLBag");
236 static CFStringRef kSecPolicyOIDEAPServer
= CFSTR("eapServer");
237 static CFStringRef kSecPolicyOIDEAPClient
= CFSTR("eapClient");
238 static CFStringRef kSecPolicyOIDIPSecServer
= CFSTR("ipsecServer");
239 static CFStringRef kSecPolicyOIDIPSecClient
= CFSTR("ipsecClient");
240 static CFStringRef kSecPolicyOIDiPhoneApplicationSigning
=
241 CFSTR("iPhoneApplicationSigning");
242 static CFStringRef kSecPolicyOIDiPhoneProfileApplicationSigning
=
243 CFSTR("iPhoneProfileApplicationSigning");
244 static CFStringRef kSecPolicyOIDiPhoneProvisioningProfileSigning
=
245 CFSTR("iPhoneProvisioningProfileSigning");
246 static CFStringRef kSecPolicyOIDAppleSWUpdateSigning
= CFSTR("AppleSWUpdateSigning");
247 static CFStringRef kSecPolicyOIDAppleTVOSApplicationSigning
=
248 CFSTR("AppleTVApplicationSigning");
249 static CFStringRef kSecPolicyOIDRevocation
= CFSTR("revocation");
250 static CFStringRef kSecPolicyOIDOCSPSigner
= CFSTR("OCSPSigner");
251 static CFStringRef kSecPolicyOIDSMIME
= CFSTR("SMIME");
252 static CFStringRef kSecPolicyOIDCodeSigning
= CFSTR("CodeSigning");
253 static CFStringRef kSecPolicyOIDPackageSigning
= CFSTR("PackageSigning");
254 static CFStringRef kSecPolicyOIDLockdownPairing
= CFSTR("LockdownPairing");
255 static CFStringRef kSecPolicyOIDURLBag
= CFSTR("URLBag");
256 static CFStringRef kSecPolicyOIDOTATasking
= CFSTR("OTATasking");
257 static CFStringRef kSecPolicyOIDMobileAsset
= CFSTR("MobileAsset");
258 static CFStringRef kSecPolicyOIDAppleIDAuthority
= CFSTR("AppleIDAuthority");
259 static CFStringRef kSecPolicyOIDMacAppStoreReceipt
= CFSTR("MacAppStoreReceipt");
260 static CFStringRef kSecPolicyOIDAppleTimeStamping
= CFSTR("AppleTimeStamping");
261 static CFStringRef kSecPolicyOIDApplePassbook
= CFSTR("ApplePassbook");
262 static CFStringRef kSecPolicyOIDAppleMobileStore
= CFSTR("AppleMobileStore");
263 static CFStringRef kSecPolicyOIDAppleTestMobileStore
= CFSTR("AppleTestMobileStore");
264 static CFStringRef kSecPolicyOIDAppleEscrowService
= CFSTR("AppleEscrowService");
265 static CFStringRef kSecPolicyOIDApplePCSEscrowService
= CFSTR("ApplePCSEscrowService");
266 static CFStringRef kSecPolicyOIDAppleProfileSigner
= CFSTR("AppleProfileSigner");
267 static CFStringRef kSecPolicyOIDAppleQAProfileSigner
= CFSTR("AppleQAProfileSigner");
268 static CFStringRef kSecPolicyOIDAppleOTAPKIAssetSigner
= CFSTR("AppleOTAPKIAssetSigner");
269 static CFStringRef kSecPolicyOIDAppleTestOTAPKIAssetSigner
= CFSTR("AppleTestOTAPKIAssetSigner");
270 static CFStringRef kSecPolicyOIDAppleIDValidationRecordSigningPolicy
= CFSTR("AppleIDValidationRecordSigningPolicy");
271 static CFStringRef kSecPolicyOIDAppleATVAppSigning
= CFSTR("AppleATVAppSigning");
272 static CFStringRef kSecPolicyOIDAppleTestATVAppSigning
= CFSTR("AppleTestATVAppSigning");
273 static CFStringRef kSecPolicyOIDApplePayIssuerEncryption
= CFSTR("ApplePayIssuerEncryption");
275 /* Policies will now change to multiple categories of checks.
277 IDEA Store partial valid policy tree in each chain? Result tree pruning might make this not feasible unless you can pretend to prune the tree without actually deleting nodes and somehow still have shable nodes with parent chains (this assumes that chains will be built as cached things from the root down), and we can build something equivalent to rfc5280 in a tree of certs. So we need to maintain a cache of leaf->chain with this certificate as any_ca_cert->tree. Revocation status caching can be done in this cache as well, so maybe the cache should be in sqlite3, or at least written there before exit and querying of the cache could be done first on the in core (possibly CF or custom tree like structure) and secondarly on the sqlite3 backed store. We should choose the lowest memory footprint solution in my mind, while choosing a sqlite3 cache size that gives us a resonable io usage pattern.
278 NOTE no certificate can be an intermediate unless it is X.509V3 and it has a basicConstraints extension with isCA set to true. This can be used to classify certs for caching purposes.
280 kSecPolicySLCheck Static Subscriber Certificate Checks
281 kSecPolicySICheck Static Subsidiary CA Checks
282 kSecPolicySACheck Static Anchor Checks
284 kSecPolicyDLCheck Dynamic Subscriber Certificate Checks
285 kSecPolicyDICheck Dynamic Subsidiary CA Checks
286 kSecPolicyDACheck Dynamic Anchor Checks ? not yet needed other than to
287 possibly exclude in a exception template (but those should still be per
288 certificate --- i.o.w. exceptions (or a database backed multiple role/user
289 trust store of some sort) and policies are 2 different things and this
290 text is about policies.
292 All static checks are only allowed to consider the certificate in isolation,
293 just given the position in the chain or the cert (leaf, intermidate, root).
294 dynamic checks can make determinations about the chain as a whole.
296 Static Subscriber Certificate Checks will be done up front before the
297 chainbuilder is even instantiated. If they fail and details aren't required
298 by the client (if no exceptions were present for this certificate) we could
299 short circuit fail the evaluation.
300 IDEA: These checks can dynamically add new checks...[needs work]
301 ALTERNATIVE: A policy can have one or more sub-policies. Each sub-policy will be evaluated only after the parent policy succeeds. Subpolicies can be either required (making the parent policy fail) or optional making the parent policy succeed, but allowing the chainbuilder to continue building chains after an optional subpolicy failure in search of a chain for which the subpolicy also succeeded. Subpolicies can be dynamically added to the policy evaluation context tree (a tree with a node for every node in the certificate path. This tree however is from the leaf up stored in the SecCertificatePathRef objects themselves possibly - requiring a separate shared subtree of nodes for the underlying certificate state tree.) by a parent policy at any stage, since the subpolicy evaluation only starts after
302 will have a key in the info (or even details and make info client side generated from info to indicate the success or failure of optional subpolicies) tree the value of which is an
303 equivalent subtree from that level down. So SSL has EV as a subpolicy, but
304 EV dynamically enables the ocsp or crl or dcrl or any combination thereof subpolicies.
306 Static Subsidiary CA Checks will be used by the chain-builder to choose the
307 best parents to evaluate first. This feature is currently already implemented
308 but with a hardcoded is_valid(verifyTime) check. Instead we will evaluate all
309 Static Subsidiary CA Checks. The results of these checks for purposes of
310 generating details could be cached in the SecCertificatePathRefs themselves, or we can short circuit fail and recalc details on demand later.
312 Static Anchor Checks can do things like populate the chainbuilder level context value of the initial_valid_policy_tree with a particular anchors list of ev policies it represents or modify inputs to the policy itself.
314 Dynamic Subscriber Certificate Checks These can do things like check for EV policy conformance based on the valid_policy_tree at the end of the certificate evaluation, or based on things like the pathlen, etc. in the chain validation context.
316 Dynamic Subsidiary CA Checks might not be needed to have custom
317 implementations, since they are all done as part of the rfc5280 checks now.
318 This assumes that checks like issuer common name includes 'foo' are
319 implmented as Static Subscriber Certificate Checks instead.
321 Dynamic Anchor Checks might include EV type checks or chain validation context seeding as well, allthough we might be able to do them as static checks to seed the chain validation context instead.
324 Questions/Notes: Do we need to dynamically add new policies? If policy static checks fail and policy is optional we don't even run policy dynamic checks nor do we compute subpolicy values. So if the static check of the leaf for EV fails we skip the rest of the EV style checks and instead don't run the revocation subpolicy of the ev policy.
326 If an optional subpolicy s_p has a required subpolicy r_s_p. Then success of s_p will cause the entire chain evaluation to fail if r_s_p fails.
328 All policies static revocation checks are run at the appropriate phase in the evaluation. static leaf checks are done before chainbuilding even starts. static intermediate checks are done in the chainbuilder for each cadidate parent certificate. If all policies pass we check the signatures. We reject the whole chain if that step fails. Otherwise we add the path to builder->candidatePaths. If the top level policy or a required subpolicy or a required subpolicy of a successful subpolicy fails we stick the chain at the end of the expiredPaths, if one of the optional subpolicies fail, we stick the chain at the start of expiredPaths so it's considered first after all real candidatePaths have been processed.
330 Static revocation policy checks could check the passed in ocspresponses or even the local cache, though the latter is probably best left for the dynamic phase.
332 The same rules that apply above to the adding paths to candidatePaths v/s expiredPaths apply to dynamicpolicy checks, except that we don't remember failures anymore, we reject them.
334 We need to remember the best successful chain we find, where best is defined by: satisfies as many optional policies as possible.
336 Chain building ends when either we find a chain that matches all optional and required policies, or we run out of chains to build. Another case is if we run out of candiate paths but we already have a chain that matches at least the top level and required subpolicies. In that case we don't even consider any expiredPaths. Example: we find a valid SSL chain (top level policy), but no partial chain we constructed satisfied the static checks of the ev subpolicy, or the required revocation sub-subpolicy of the ev policy.
338 In order for this to work well with exceptions on subpolicies, we'd need to move the validation of exceptions to the server, something we'd do anyway if we had full on truststore. In this case exceptions would be live in the failure callback for a trust check.
340 Example sectrust operation in psuedocode:
344 new builder(verifyTime, certificates, anchors, anchorsOnly, policies);
345 chain = builder.subscriber_only_chain;
346 foreach (policy in policies{kSecPolicySLCheck}) {
347 foreach(check in policy)
348 SecPolicyRunCheck(builder, chain, check, details);
349 foreach (subpolicy in policy) {
350 check_policy(builder, chain, subpolicy, details{subpolicy.name})
352 propagate_subpolicy_results(builder, chain, details);
354 while (chain = builder.next) {
355 for (depth = 0; p_d = policies.at_depth(depth),
356 d_p_d = dynamic_policies.at_depth(depth), p_d || d_p_d; ++depth)
358 // Modify SecPathBuilderIsPartial() to
359 // run builder_check(buildier, policies, kSecPolicySICheck) instead
360 // of SecCertificateIsValid. Also rename considerExpired to
361 // considerSIFailures.
362 foreach (policy in p_d) {
363 check_policy(builder, chain, policy, kSecPolicySICheck, depth);
365 /// Recalculate since the static checks might have added new dynamic
367 d_p_d = dynamic_policies.at_depth(depth);
368 foreach (policy in d_p_d) {
369 check_policy(builder, chain, policy, kSecPolicySICheck, depth);
371 if (chain.is_anchored) {
372 foreach (policy in p_d) {
373 check_policy(builder, chain, policy, kSecPolicySACheck, depth);
375 foreach (policy in d_p_d) {
376 check_policy(builder, chain, policy, kSecPolicySACheck, depth);
378 foreach (policy in p_d) {
379 check_policy(builder, chain, policy, kSecPolicyDACheck, depth);
381 foreach (policy in d_p_d) {
382 check_policy(builder, chain, policy, kSecPolicyDACheck, depth);
385 foreach (policy in policies) {
386 check_policy(builder, chain, policy, kSecPolicySACheck, depth);
387 check_policy(builder, chain, policy, kSecPolicyDACheck, depth);
389 foreach (policy in policies{kSecPolicySDCheck}) {
394 check_policy(builder, chain, policy, check_class, details, depth) {
396 foreach(check in policy{check_class}) {
397 SecPolicyRunCheck(builder, chain, check, details);
401 foreach (subpolicy in policy) {
402 if (!check_policy(builder, chain, subpolicy, check_class,
403 details{subpolicy.name}) && subpolicy.is_required, depth)
407 propagate_subpolicy_results(builder, chain, details);
414 #define kSecPolicySHA1Size 20
415 #define kSecPolicySHA256Size 32
416 const UInt8 kAppleCASHA1
[kSecPolicySHA1Size
] = {
417 0x61, 0x1E, 0x5B, 0x66, 0x2C, 0x59, 0x3A, 0x08, 0xFF, 0x58,
418 0xD1, 0x4A, 0xE2, 0x24, 0x52, 0xD1, 0x98, 0xDF, 0x6C, 0x60
421 __unused
static const UInt8 kAppleTESTCASHA1
[kSecPolicySHA1Size
] = {
422 0xbc, 0x30, 0x55, 0xc8, 0xc8, 0xd3, 0x48, 0x3f, 0xf4, 0x8d,
423 0xfe, 0x3d, 0x51, 0x75, 0x31, 0xc9, 0xf4, 0xd7, 0x4a, 0xf7
426 static const UInt8 kITMSCASHA1
[kSecPolicySHA1Size
] = {
427 0x1D, 0x33, 0x42, 0x46, 0x8B, 0x10, 0xBD, 0xE6, 0x45, 0xCE,
428 0x44, 0x6E, 0xBB, 0xE8, 0xF5, 0x03, 0x5D, 0xF8, 0x32, 0x22
431 static const UInt8 kFactoryDeviceCASHA1
[kSecPolicySHA1Size
] = {
432 0xef, 0x68, 0x73, 0x17, 0xa4, 0xf8, 0xf9, 0x4b, 0x7b, 0x21,
433 0xe2, 0x2f, 0x09, 0x8f, 0xfd, 0x6a, 0xae, 0xc0, 0x0d, 0x63
436 static const UInt8 kApplePKISettingsAuthority
[kSecPolicySHA1Size
] = {
437 0x1D, 0x0C, 0xBA, 0xAD, 0x17, 0xFD, 0x7E, 0x9E, 0x9F, 0xF1,
438 0xC9, 0xA2, 0x66, 0x79, 0x60, 0x00, 0x8B, 0xAE, 0x70, 0xB8
441 static const UInt8 kAppleTestPKISettingsAuthority
[kSecPolicySHA1Size
] = {
442 0xDB, 0xBA, 0x25, 0x0B, 0xD8, 0x62, 0x71, 0x87, 0x54, 0x7E,
443 0xD7, 0xEF, 0x11, 0x94, 0x7E, 0x82, 0xE6, 0xD8, 0x1C, 0x9A
446 static const UInt8 kTestAppleRootCA_ECC_SHA1
[kSecPolicySHA1Size
] = {
447 0x62, 0x0A, 0xED, 0x83, 0xD2, 0x97, 0x4A, 0x77, 0x56, 0x33,
448 0x83, 0xBE, 0xDB, 0xF9, 0xA1, 0xBD, 0x5F, 0xFE, 0x55, 0x7B
451 static const UInt8 kAppleRootCA_ECC_SHA1
[kSecPolicySHA1Size
] = {
452 0xB5, 0x2C, 0xB0, 0x2F, 0xD5, 0x67, 0xE0, 0x35, 0x9F, 0xE8,
453 0xFA, 0x4D, 0x4C, 0x41, 0x03, 0x79, 0x70, 0xFE, 0x01, 0xB0
458 /********************************************************
459 ****************** SecPolicy object ********************
460 ********************************************************/
462 static void SecPolicyDestroy(CFTypeRef cf
) {
463 SecPolicyRef policy
= (SecPolicyRef
) cf
;
464 CFRelease(policy
->_oid
);
465 CFRelease(policy
->_options
);
468 static Boolean
SecPolicyCompare(CFTypeRef cf1
, CFTypeRef cf2
) {
469 SecPolicyRef policy1
= (SecPolicyRef
) cf1
;
470 SecPolicyRef policy2
= (SecPolicyRef
) cf2
;
471 return CFEqual(policy1
->_oid
, policy2
->_oid
) &&
472 CFEqual(policy1
->_options
, policy2
->_options
);
475 static CFHashCode
SecPolicyHash(CFTypeRef cf
) {
476 SecPolicyRef policy
= (SecPolicyRef
) cf
;
478 return CFHash(policy
->_oid
) + CFHash(policy
->_options
);
481 static CFStringRef
SecPolicyCopyFormatDescription(CFTypeRef cf
, CFDictionaryRef formatOptions
) {
482 SecPolicyRef policy
= (SecPolicyRef
) cf
;
483 CFMutableStringRef desc
= CFStringCreateMutable(kCFAllocatorDefault
, 0);
484 CFStringRef typeStr
= CFCopyTypeIDDescription(CFGetTypeID(cf
));
485 CFStringAppendFormat(desc
, NULL
,
486 CFSTR("<%@: oid: %@ options %@"), typeStr
,
487 policy
->_oid
, policy
->_options
);
489 CFStringAppend(desc
, CFSTR(" >"));
494 /* SecPolicy API functions. */
495 CFGiblisWithHashFor(SecPolicy
);
497 /* AUDIT[securityd](done):
498 oid (ok) is a caller provided string, only its cf type has been checked.
499 options is a caller provided dictionary, only its cf type has been checked.
501 SecPolicyRef
SecPolicyCreate(CFStringRef oid
, CFDictionaryRef options
) {
502 SecPolicyRef result
= NULL
;
504 require(oid
, errOut
);
505 require(options
, errOut
);
507 (SecPolicyRef
)_CFRuntimeCreateInstance(kCFAllocatorDefault
,
508 SecPolicyGetTypeID(),
509 sizeof(struct __SecPolicy
) - sizeof(CFRuntimeBase
), 0), errOut
);
514 result
->_options
= options
;
520 SecPolicyRef
SecPolicyCreateWithProperties(CFTypeRef policyIdentifier
,
521 CFDictionaryRef properties
) {
522 // Creates a policy reference for a given policy object identifier.
523 // If policy-specific parameters can be supplied (e.g. hostname),
524 // attempt to obtain from input properties dictionary.
525 // Returns NULL if the given identifier is unsupported.
527 SecPolicyRef policy
= NULL
;
528 CFStringRef name
= NULL
;
529 CFStringRef teamID
= NULL
;
530 Boolean client
= false;
531 require(policyIdentifier
&& (CFStringGetTypeID() == CFGetTypeID(policyIdentifier
)), errOut
);
534 name
= CFDictionaryGetValue(properties
, kSecPolicyName
);
535 teamID
= CFDictionaryGetValue(properties
, kSecPolicyTeamIdentifier
);
537 CFBooleanRef dictionaryClientValue
;
538 client
= (CFDictionaryGetValueIfPresent(properties
, kSecPolicyClient
, (const void **)&dictionaryClientValue
) &&
539 (dictionaryClientValue
!= NULL
) && CFEqual(kCFBooleanTrue
, dictionaryClientValue
));
542 if (CFEqual(policyIdentifier
, kSecPolicyAppleX509Basic
)) {
543 policy
= SecPolicyCreateBasicX509();
545 else if (CFEqual(policyIdentifier
, kSecPolicyAppleSSL
)) {
546 policy
= SecPolicyCreateSSL(!client
, name
);
548 else if (CFEqual(policyIdentifier
, kSecPolicyAppleEAP
)) {
549 CFArrayRef array
= NULL
;
551 array
= CFArrayCreate(kCFAllocatorDefault
, (const void **)&name
, 1, &kCFTypeArrayCallBacks
);
553 policy
= SecPolicyCreateEAP(!client
, array
);
554 CFReleaseSafe(array
);
556 else if (CFEqual(policyIdentifier
, kSecPolicyApplePackageSigning
)) {
557 policy
= SecPolicyCreateApplePackageSigning();
559 else if (CFEqual(policyIdentifier
, kSecPolicyAppleSWUpdateSigning
)) {
560 policy
= SecPolicyCreateAppleSWUpdateSigning();
562 else if (CFEqual(policyIdentifier
, kSecPolicyAppleIPsec
)) {
563 policy
= SecPolicyCreateIPSec(!client
, name
);
565 else if (CFEqual(policyIdentifier
, kSecPolicyAppleRevocation
)) {
566 policy
= SecPolicyCreateRevocation(kSecRevocationUseAnyAvailableMethod
);
568 else if (CFEqual(policyIdentifier
, kSecPolicyAppleSMIME
)) {
569 policy
= SecPolicyCreateSMIME(kSecSignSMIMEUsage
| kSecAnyEncryptSMIME
, name
);
571 else if (CFEqual(policyIdentifier
, kSecPolicyAppleCodeSigning
)) {
572 policy
= SecPolicyCreateCodeSigning();
574 else if (CFEqual(policyIdentifier
, kSecPolicyAppleTimeStamping
)) {
575 policy
= SecPolicyCreateAppleTimeStamping();
577 else if (CFEqual(policyIdentifier
, kSecPolicyMacAppStoreReceipt
)) {
578 policy
= SecPolicyCreateMacAppStoreReceipt();
580 else if (CFEqual(policyIdentifier
, kSecPolicyAppleIDValidation
)) {
581 policy
= SecPolicyCreateAppleIDAuthorityPolicy();
583 else if (CFEqual(policyIdentifier
, kSecPolicyApplePassbookSigning
)) {
584 policy
= SecPolicyCreatePassbookCardSigner(name
, teamID
);
586 else if (CFEqual(policyIdentifier
, kSecPolicyAppleMobileStore
)) {
587 policy
= SecPolicyCreateMobileStoreSigner();
589 else if (CFEqual(policyIdentifier
, kSecPolicyAppleTestMobileStore
)) {
590 policy
= SecPolicyCreateTestMobileStoreSigner();
592 else if (CFEqual(policyIdentifier
, kSecPolicyAppleEscrowService
)) {
593 policy
= SecPolicyCreateEscrowServiceSigner();
595 else if (CFEqual(policyIdentifier
, kSecPolicyApplePCSEscrowService
)) {
596 policy
= SecPolicyCreatePCSEscrowServiceSigner();
598 else if (CFEqual(policyIdentifier
, kSecPolicyAppleProfileSigner
)) {
599 policy
= SecPolicyCreateConfigurationProfileSigner();
601 else if (CFEqual(policyIdentifier
, kSecPolicyAppleQAProfileSigner
)) {
602 policy
= SecPolicyCreateQAConfigurationProfileSigner();
604 else if (CFEqual(policyIdentifier
, kSecPolicyAppleServerAuthentication
)) {
605 policy
= SecPolicyCreateAppleSSLService(name
);
607 #if TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR
608 else if (CFEqual(policyIdentifier
, kSecPolicyAppleOTAPKISigner
)) {
609 policy
= SecPolicyCreateOTAPKISigner();
611 else if (CFEqual(policyIdentifier
, kSecPolicyAppleTestOTAPKISigner
)) {
612 policy
= SecPolicyCreateTestOTAPKISigner();
614 else if (CFEqual(policyIdentifier
, kSecPolicyAppleIDValidationRecordSigningPolicy
)) {
615 policy
= SecPolicyCreateAppleIDValidationRecordSigningPolicy();
617 else if (CFEqual(policyIdentifier
, kSecPolicyAppleSMPEncryption
)) {
618 policy
= SecPolicyCreateAppleSMPEncryption();
620 else if (CFEqual(policyIdentifier
, kSecPolicyAppleTestSMPEncryption
)) {
621 policy
= SecPolicyCreateTestAppleSMPEncryption();
623 else if (CFEqual(policyIdentifier
, kSecPolicyAppleATVAppSigning
)) {
624 policy
= SecPolicyCreateAppleATVAppSigning();
626 else if (CFEqual(policyIdentifier
, kSecPolicyAppleTestATVAppSigning
)) {
627 policy
= SecPolicyCreateTestAppleATVAppSigning();
630 else if (CFEqual(policyIdentifier
, kSecPolicyApplePPQSigning
)) {
631 policy
= SecPolicyCreateApplePPQSigning();
633 else if (CFEqual(policyIdentifier
, kSecPolicyAppleTestPPQSigning
)) {
634 policy
= SecPolicyCreateTestApplePPQSigning();
636 else if (CFEqual(policyIdentifier
, kSecPolicyApplePayIssuerEncryption
)) {
637 policy
= SecPolicyCreateApplePayIssuerEncryption();
640 secerror("ERROR: policy \"%@\" is unsupported", policyIdentifier
);
647 CFDictionaryRef
SecPolicyCopyProperties(SecPolicyRef policyRef
) {
648 // Builds and returns a dictionary which the caller must release.
650 #pragma clang diagnostic push
651 #pragma clang diagnostic ignored "-Wnonnull"
652 // After introducing nullability annotations, policyRef is supposed to be nonnull, suppress the warning
653 if (!policyRef
) return NULL
;
654 #pragma clang diagnostic pop
655 CFMutableDictionaryRef properties
= CFDictionaryCreateMutable(NULL
, 0,
656 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
657 #pragma clang diagnostic push
658 #pragma clang diagnostic ignored "-Wnonnull"
659 // 'properties' is nonnull in reality suppress the warning
660 if (!properties
) return NULL
;
661 #pragma clang diagnostic pop
662 CFStringRef oid
= (CFStringRef
) CFRetain(policyRef
->_oid
);
663 CFTypeRef nameKey
= NULL
;
665 // Convert private to public OID if we have one
666 CFStringRef outOid
= oid
;
667 if (CFEqual(oid
, kSecPolicyOIDBasicX509
)) {
668 outOid
= kSecPolicyAppleX509Basic
;
670 else if (CFEqual(oid
, kSecPolicyOIDSSLServer
) ||
671 CFEqual(oid
, kSecPolicyOIDSSLClient
)) {
672 outOid
= kSecPolicyAppleSSL
;
673 nameKey
= kSecPolicyCheckSSLHostname
;
675 else if (CFEqual(oid
, kSecPolicyOIDEAPServer
) ||
676 CFEqual(oid
, kSecPolicyOIDEAPClient
)) {
677 outOid
= kSecPolicyAppleEAP
;
678 nameKey
= kSecPolicyCheckEAPTrustedServerNames
;
680 else if (CFEqual(oid
, kSecPolicyOIDIPSecServer
) ||
681 CFEqual(oid
, kSecPolicyOIDIPSecClient
)) {
682 outOid
= kSecPolicyAppleIPsec
;
683 nameKey
= kSecPolicyCheckSSLHostname
;
685 else if (CFEqual(oid
, kSecPolicyOIDRevocation
)) {
686 outOid
= kSecPolicyAppleRevocation
;
688 else if (CFEqual(oid
, kSecPolicyOIDSMIME
)) {
689 outOid
= kSecPolicyAppleSMIME
;
690 nameKey
= kSecPolicyCheckEmail
;
692 else if (CFEqual(oid
, kSecPolicyOIDCodeSigning
)) {
693 outOid
= kSecPolicyAppleCodeSigning
;
695 else if (CFEqual(oid
, kSecPolicyOIDAppleIDAuthority
)) {
696 outOid
= kSecPolicyAppleIDValidation
;
698 else if (CFEqual(oid
, kSecPolicyOIDApplePassbook
)) {
699 outOid
= kSecPolicyApplePassbookSigning
;
701 else if (CFEqual(oid
, kSecPolicyOIDAppleMobileStore
)) {
702 outOid
= kSecPolicyAppleMobileStore
;
704 else if (CFEqual(oid
, kSecPolicyOIDAppleTestMobileStore
)) {
705 outOid
= kSecPolicyAppleTestMobileStore
;
707 else if (CFEqual(oid
, kSecPolicyOIDAppleEscrowService
)) {
708 outOid
= kSecPolicyAppleEscrowService
;
710 else if (CFEqual(oid
, kSecPolicyOIDApplePCSEscrowService
)) {
711 outOid
= kSecPolicyApplePCSEscrowService
;
713 else if (CFEqual(oid
, kSecPolicyOIDAppleProfileSigner
)) {
714 outOid
= kSecPolicyAppleProfileSigner
;
716 else if (CFEqual(oid
, kSecPolicyOIDAppleQAProfileSigner
)) {
717 outOid
= kSecPolicyAppleQAProfileSigner
;
719 #if TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR
720 else if (CFEqual(oid
, kSecPolicyOIDAppleOTAPKIAssetSigner
)) {
721 outOid
= kSecPolicyAppleOTAPKISigner
;
723 else if (CFEqual(oid
, kSecPolicyOIDAppleTestOTAPKIAssetSigner
)) {
724 outOid
= kSecPolicyAppleTestOTAPKISigner
;
726 else if (CFEqual(oid
, kSecPolicyOIDAppleIDValidationRecordSigningPolicy
)) {
727 outOid
= kSecPolicyAppleIDValidationRecordSigningPolicy
;
729 else if (CFEqual(oid
, kSecPolicyOIDAppleATVAppSigning
)) {
730 outOid
= kSecPolicyAppleATVAppSigning
;
732 else if (CFEqual(oid
, kSecPolicyOIDAppleTestATVAppSigning
)) {
733 outOid
= kSecPolicyAppleTestATVAppSigning
;
736 else if (CFEqual(oid
, kSecPolicyOIDApplePayIssuerEncryption
)) {
737 outOid
= kSecPolicyApplePayIssuerEncryption
;
741 CFDictionarySetValue(properties
, (const void *)kSecPolicyOid
,
742 (const void *)outOid
);
744 // Set kSecPolicyName if we have one
745 if (nameKey
&& policyRef
->_options
) {
746 CFTypeRef name
= (CFTypeRef
) CFDictionaryGetValue(policyRef
->_options
,
749 CFDictionarySetValue(properties
, (const void *)kSecPolicyName
,
754 // Set kSecPolicyClient
755 if (CFEqual(oid
, kSecPolicyOIDSSLClient
) ||
756 CFEqual(oid
, kSecPolicyOIDIPSecClient
) ||
757 CFEqual(oid
, kSecPolicyOIDEAPClient
)) {
758 CFDictionarySetValue(properties
, (const void *)kSecPolicyClient
,
759 (const void *)kCFBooleanTrue
);
766 static void SecPolicySetOid(SecPolicyRef policy
, CFStringRef oid
) {
767 if (!policy
|| !oid
) return;
768 CFStringRef temp
= policy
->_oid
;
774 CFStringRef
SecPolicyGetOidString(SecPolicyRef policy
) {
778 CFDictionaryRef
SecPolicyGetOptions(SecPolicyRef policy
) {
779 return policy
->_options
;
782 void SecPolicySetOptionsValue(SecPolicyRef policy
, CFStringRef key
, CFTypeRef value
) {
783 if (!policy
|| !key
) return;
784 CFMutableDictionaryRef options
= (CFMutableDictionaryRef
) policy
->_options
;
786 options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
787 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
788 if (!options
) return;
789 policy
->_options
= options
;
791 CFDictionarySetValue(options
, key
, value
);
795 // this is declared as NA for iPhone in SecPolicy.h, so declare here
796 OSStatus
SecPolicySetProperties(SecPolicyRef policyRef
, CFDictionaryRef properties
);
799 OSStatus
SecPolicySetProperties(SecPolicyRef policyRef
, CFDictionaryRef properties
) {
800 // Set policy options based on the provided dictionary keys.
802 if (!(policyRef
&& properties
&& (CFDictionaryGetTypeID() == CFGetTypeID(properties
)))) {
805 CFStringRef oid
= (CFStringRef
) CFRetain(policyRef
->_oid
);
806 OSStatus result
= errSecSuccess
;
809 CFTypeRef name
= NULL
;
810 if (CFDictionaryGetValueIfPresent(properties
, (const void *)kSecPolicyName
,
811 (const void **)&name
) && name
) {
812 CFTypeID typeID
= CFGetTypeID(name
);
813 if (CFEqual(oid
, kSecPolicyOIDSSLServer
) ||
814 CFEqual(oid
, kSecPolicyOIDSSLClient
) ||
815 CFEqual(oid
, kSecPolicyOIDIPSecServer
) ||
816 CFEqual(oid
, kSecPolicyOIDIPSecClient
)) {
817 if (CFStringGetTypeID() == typeID
) {
818 SecPolicySetOptionsValue(policyRef
, kSecPolicyCheckSSLHostname
, name
);
820 else result
= errSecParam
;
822 else if (CFEqual(oid
, kSecPolicyOIDEAPServer
) ||
823 CFEqual(oid
, kSecPolicyOIDEAPClient
)) {
824 if ((CFStringGetTypeID() == typeID
) ||
825 (CFArrayGetTypeID() == typeID
)) {
826 SecPolicySetOptionsValue(policyRef
, kSecPolicyCheckEAPTrustedServerNames
, name
);
828 else result
= errSecParam
;
830 else if (CFEqual(oid
, kSecPolicyOIDSMIME
)) {
831 if (CFStringGetTypeID() == typeID
) {
832 SecPolicySetOptionsValue(policyRef
, kSecPolicyCheckEmail
, name
);
834 else result
= errSecParam
;
839 CFTypeRef client
= NULL
;
840 if (CFDictionaryGetValueIfPresent(properties
, (const void *)kSecPolicyClient
,
841 (const void **)&client
) && client
) {
842 if (!(CFBooleanGetTypeID() == CFGetTypeID(client
))) {
843 result
= errSecParam
;
845 else if (CFEqual(client
, kCFBooleanTrue
)) {
846 if (CFEqual(oid
, kSecPolicyOIDSSLServer
)) {
847 SecPolicySetOid(policyRef
, kSecPolicyOIDSSLClient
);
849 else if (CFEqual(oid
, kSecPolicyOIDIPSecServer
)) {
850 SecPolicySetOid(policyRef
, kSecPolicyOIDIPSecClient
);
852 else if (CFEqual(oid
, kSecPolicyOIDEAPServer
)) {
853 SecPolicySetOid(policyRef
, kSecPolicyOIDEAPClient
);
857 if (CFEqual(oid
, kSecPolicyOIDSSLClient
)) {
858 SecPolicySetOid(policyRef
, kSecPolicyOIDSSLServer
);
860 else if (CFEqual(oid
, kSecPolicyOIDIPSecClient
)) {
861 SecPolicySetOid(policyRef
, kSecPolicyOIDIPSecServer
);
863 else if (CFEqual(oid
, kSecPolicyOIDEAPClient
)) {
864 SecPolicySetOid(policyRef
, kSecPolicyOIDEAPServer
);
873 static xpc_object_t
copy_xpc_policy_object(SecPolicyRef policy
);
874 static bool append_policy_to_xpc_array(SecPolicyRef policy
, xpc_object_t xpc_policies
);
875 extern xpc_object_t
copy_xpc_policies_array(CFArrayRef policies
);
876 extern OSStatus
validate_array_of_items(CFArrayRef array
, CFStringRef arrayItemType
, CFTypeID itemTypeID
, bool required
);
878 static xpc_object_t
copy_xpc_policy_object(SecPolicyRef policy
) {
879 xpc_object_t xpc_policy
= NULL
;
880 xpc_object_t data
[2] = { NULL
, NULL
};
881 if (policy
->_oid
&& (CFGetTypeID(policy
->_oid
) == CFStringGetTypeID())) {
882 data
[0] = _CFXPCCreateXPCObjectFromCFObject(policy
->_oid
);
884 secerror("policy 0x%lX has no _oid", (uintptr_t)policy
);
886 if (policy
->_options
&& (CFGetTypeID(policy
->_options
) == CFDictionaryGetTypeID())) {
887 data
[1] = _CFXPCCreateXPCObjectFromCFObject(policy
->_options
);
889 secerror("policy 0x%lX has no _options", (uintptr_t)policy
);
891 xpc_policy
= xpc_array_create(data
, array_size(data
));
892 if (data
[0]) xpc_release(data
[0]);
893 if (data
[1]) xpc_release(data
[1]);
897 static bool append_policy_to_xpc_array(SecPolicyRef policy
, xpc_object_t xpc_policies
) {
901 xpc_object_t xpc_policy
= copy_xpc_policy_object(policy
);
905 xpc_array_append_value(xpc_policies
, xpc_policy
);
906 xpc_release(xpc_policy
);
910 xpc_object_t
copy_xpc_policies_array(CFArrayRef policies
) {
911 xpc_object_t xpc_policies
= xpc_array_create(NULL
, 0);
915 validate_array_of_items(policies
, CFSTR("policy"), SecPolicyGetTypeID(), true);
916 CFIndex ix
, count
= CFArrayGetCount(policies
);
917 for (ix
= 0; ix
< count
; ++ix
) {
918 SecPolicyRef policy
= (SecPolicyRef
) CFArrayGetValueAtIndex(policies
, ix
);
919 #if SECTRUST_VERBOSE_DEBUG
920 CFDictionaryRef props
= SecPolicyCopyProperties(policy
);
921 secerror("idx=%d of %d; policy=0x%lX properties=%@", (int)ix
, (int)count
, (uintptr_t)policy
, props
);
922 CFReleaseSafe(props
);
924 if (!append_policy_to_xpc_array(policy
, xpc_policies
)) {
925 xpc_release(xpc_policies
);
933 static xpc_object_t
SecPolicyCopyXPCObject(SecPolicyRef policy
, CFErrorRef
*error
) {
934 xpc_object_t xpc_policy
= NULL
;
935 xpc_object_t data
[2] = {};
936 require_action_quiet(data
[0] = _CFXPCCreateXPCObjectFromCFObject(policy
->_oid
), exit
,
937 SecError(errSecParam
, error
, CFSTR("failed to create xpc_object from policy oid")));
938 require_action_quiet(data
[1] = _CFXPCCreateXPCObjectFromCFObject(policy
->_options
), exit
,
939 SecError(errSecParam
, error
, CFSTR("failed to create xpc_object from policy options")));
940 require_action_quiet(xpc_policy
= xpc_array_create(data
, array_size(data
)), exit
,
941 SecError(errSecAllocate
, error
, CFSTR("failed to create xpc_array for policy")));
944 if (data
[0]) xpc_release(data
[0]);
945 if (data
[1]) xpc_release(data
[1]);
949 static bool SecPolicyAppendToXPCArray(SecPolicyRef policy
, xpc_object_t policies
, CFErrorRef
*error
) {
953 xpc_object_t xpc_policy
= SecPolicyCopyXPCObject(policy
, error
);
957 xpc_array_append_value(policies
, xpc_policy
);
958 xpc_release(xpc_policy
);
962 xpc_object_t
SecPolicyArrayCopyXPCArray(CFArrayRef policies
, CFErrorRef
*error
) {
963 xpc_object_t xpc_policies
;
964 require_action_quiet(xpc_policies
= xpc_array_create(NULL
, 0), exit
,
965 SecError(errSecAllocate
, error
, CFSTR("failed to create xpc_array")));
966 CFIndex ix
, count
= CFArrayGetCount(policies
);
967 for (ix
= 0; ix
< count
; ++ix
) {
968 if (!SecPolicyAppendToXPCArray((SecPolicyRef
)CFArrayGetValueAtIndex(policies
, ix
), xpc_policies
, error
)) {
969 xpc_release(xpc_policies
);
977 static SecPolicyRef
SecPolicyCreateWithXPCObject(xpc_object_t xpc_policy
, CFErrorRef
*error
) {
978 SecPolicyRef policy
= NULL
;
979 CFTypeRef oid
= NULL
;
980 CFTypeRef options
= NULL
;
982 require_action_quiet(xpc_policy
, exit
, SecError(errSecParam
, error
, CFSTR("policy xpc value is NULL")));
983 require_action_quiet(xpc_get_type(xpc_policy
) == XPC_TYPE_ARRAY
, exit
, SecError(errSecDecode
, error
, CFSTR("policy xpc value is not an array")));
984 require_action_quiet(xpc_array_get_count(xpc_policy
) == 2, exit
, SecError(errSecDecode
, error
, CFSTR("policy xpc array count != 2")));
985 oid
= _CFXPCCreateCFObjectFromXPCObject(xpc_array_get_value(xpc_policy
, 0));
986 require_action_quiet(isString(oid
), exit
,
987 SecError(errSecParam
, error
, CFSTR("failed to convert xpc policy[0]=%@ to CFString"), oid
));
988 options
= _CFXPCCreateCFObjectFromXPCObject(xpc_array_get_value(xpc_policy
, 1));
989 require_action_quiet(isDictionary(options
), exit
,
990 SecError(errSecParam
, error
, CFSTR("failed to convert xpc policy[1]=%@ to CFDictionary"), options
));
991 require_action_quiet(policy
= SecPolicyCreate(oid
, options
), exit
, SecError(errSecDecode
, error
, CFSTR("Failed to create policy")));
995 CFReleaseSafe(options
);
999 CFArrayRef
SecPolicyXPCArrayCopyArray(xpc_object_t xpc_policies
, CFErrorRef
*error
) {
1000 CFMutableArrayRef policies
= NULL
;
1001 require_action_quiet(xpc_get_type(xpc_policies
) == XPC_TYPE_ARRAY
, exit
,
1002 SecError(errSecParam
, error
, CFSTR("policies xpc value is not an array")));
1003 size_t count
= xpc_array_get_count(xpc_policies
);
1004 require_action_quiet(policies
= CFArrayCreateMutable(kCFAllocatorDefault
, count
, &kCFTypeArrayCallBacks
), exit
,
1005 SecError(errSecAllocate
, error
, CFSTR("failed to create CFArray of capacity %zu"), count
));
1008 for (ix
= 0; ix
< count
; ++ix
) {
1009 SecPolicyRef policy
= SecPolicyCreateWithXPCObject(xpc_array_get_value(xpc_policies
, ix
), error
);
1011 CFRelease(policies
);
1014 CFArraySetValueAtIndex(policies
, ix
, policy
);
1023 static void add_element(CFMutableDictionaryRef options
, CFStringRef key
,
1025 CFTypeRef old_value
= CFDictionaryGetValue(options
, key
);
1027 CFMutableArrayRef array
;
1028 if (CFGetTypeID(old_value
) == CFArrayGetTypeID()) {
1029 array
= (CFMutableArrayRef
)old_value
;
1031 array
= CFArrayCreateMutable(kCFAllocatorDefault
, 0,
1032 &kCFTypeArrayCallBacks
);
1033 CFArrayAppendValue(array
, old_value
);
1034 CFDictionarySetValue(options
, key
, array
);
1037 CFArrayAppendValue(array
, value
);
1039 CFDictionaryAddValue(options
, key
, value
);
1043 static void add_eku(CFMutableDictionaryRef options
, const DERItem
*ekuOid
) {
1044 CFDataRef eku
= CFDataCreate(kCFAllocatorDefault
,
1045 ekuOid
? ekuOid
->data
: NULL
,
1046 ekuOid
? ekuOid
->length
: 0);
1048 add_element(options
, kSecPolicyCheckExtendedKeyUsage
, eku
);
1053 static void add_ku(CFMutableDictionaryRef options
, SecKeyUsage keyUsage
) {
1054 SInt32 dku
= keyUsage
;
1055 CFNumberRef ku
= CFNumberCreate(kCFAllocatorDefault
, kCFNumberSInt32Type
,
1058 add_element(options
, kSecPolicyCheckKeyUsage
, ku
);
1063 static void add_oid(CFMutableDictionaryRef options
, CFStringRef policy_key
, const DERItem
*oid
) {
1064 CFDataRef oid_data
= CFDataCreate(kCFAllocatorDefault
,
1065 oid
? oid
->data
: NULL
,
1066 oid
? oid
->length
: 0);
1068 add_element(options
, policy_key
, oid_data
);
1069 CFRelease(oid_data
);
1073 static void add_leaf_marker_value(CFMutableDictionaryRef options
, const DERItem
*markerOid
, CFStringRef string_value
) {
1075 CFTypeRef policyData
= NULL
;
1077 if (NULL
== string_value
) {
1078 policyData
= CFDataCreate(kCFAllocatorDefault
,
1079 markerOid
? markerOid
->data
: NULL
,
1080 markerOid
? markerOid
->length
: 0);
1082 CFStringRef oid_as_string
= SecDERItemCopyOIDDecimalRepresentation(kCFAllocatorDefault
, markerOid
);
1084 const void *key
[1] = { oid_as_string
};
1085 const void *value
[1] = { string_value
};
1086 policyData
= CFDictionaryCreate(kCFAllocatorDefault
,
1088 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
1089 CFReleaseNull(oid_as_string
);
1092 add_element(options
, kSecPolicyCheckLeafMarkerOid
, policyData
);
1094 CFReleaseNull(policyData
);
1098 static void add_leaf_marker(CFMutableDictionaryRef options
, const DERItem
*markerOid
) {
1099 add_leaf_marker_value(options
, markerOid
, NULL
);
1103 static void add_certificate_policy_oid(CFMutableDictionaryRef options
, const DERItem
*certificatePolicyOid
, CFStringRef string_value
) {
1104 CFTypeRef certificatePolicyData
= NULL
;
1106 if (NULL
== string_value
) {
1107 certificatePolicyData
= CFDataCreate(kCFAllocatorDefault
,
1108 certificatePolicyOid
? certificatePolicyOid
->data
: NULL
,
1109 certificatePolicyOid
? certificatePolicyOid
->length
: 0);
1111 CFStringRef oid_as_string
= SecDERItemCopyOIDDecimalRepresentation(kCFAllocatorDefault
, certificatePolicyOid
);
1113 const void *key
[1] = { oid_as_string
};
1114 const void *value
[1] = { string_value
};
1115 certificatePolicyData
= CFDictionaryCreate(kCFAllocatorDefault
,
1117 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
1118 CFReleaseNull(oid_as_string
);
1121 add_element(options
, kSecPolicyCheckCertificatePolicy
, certificatePolicyData
);
1123 CFReleaseNull(certificatePolicyData
);
1126 // Routines for adding dictionary entries for policies.
1129 // X.509, but missing validity requirements.
1130 static void SecPolicyAddBasicCertOptions(CFMutableDictionaryRef options
)
1132 //CFDictionaryAddValue(options, kSecPolicyCheckBasicCertificateProcessing, kCFBooleanTrue);
1133 CFDictionaryAddValue(options
, kSecPolicyCheckCriticalExtensions
, kCFBooleanTrue
);
1134 CFDictionaryAddValue(options
, kSecPolicyCheckIdLinkage
, kCFBooleanTrue
);
1135 CFDictionaryAddValue(options
, kSecPolicyCheckBasicContraints
, kCFBooleanTrue
);
1136 CFDictionaryAddValue(options
, kSecPolicyCheckNonEmptySubject
, kCFBooleanTrue
);
1137 CFDictionaryAddValue(options
, kSecPolicyCheckQualifiedCertStatements
, kCFBooleanTrue
);
1140 static void SecPolicyAddBasicX509Options(CFMutableDictionaryRef options
)
1142 SecPolicyAddBasicCertOptions(options
);
1143 CFDictionaryAddValue(options
, kSecPolicyCheckValidIntermediates
, kCFBooleanTrue
);
1144 CFDictionaryAddValue(options
, kSecPolicyCheckValidLeaf
, kCFBooleanTrue
);
1145 CFDictionaryAddValue(options
, kSecPolicyCheckValidRoot
, kCFBooleanTrue
);
1147 // Make sure that black and gray leaf checks are performed for basic X509 chain building
1148 CFDictionaryAddValue(options
, kSecPolicyCheckBlackListedLeaf
, kCFBooleanTrue
);
1149 CFDictionaryAddValue(options
, kSecPolicyCheckGrayListedLeaf
, kCFBooleanTrue
);
1152 static bool SecPolicyAddChainLengthOptions(CFMutableDictionaryRef options
, CFIndex length
)
1154 bool result
= false;
1155 CFNumberRef lengthAsCF
= NULL
;
1157 require(lengthAsCF
= CFNumberCreate(kCFAllocatorDefault
,
1158 kCFNumberCFIndexType
, &length
), errOut
);
1159 CFDictionaryAddValue(options
, kSecPolicyCheckChainLength
, lengthAsCF
);
1164 CFReleaseSafe(lengthAsCF
);
1168 static bool SecPolicyAddAnchorSHA1Options(CFMutableDictionaryRef options
,
1169 const UInt8 anchorSha1
[kSecPolicySHA1Size
])
1171 bool success
= false;
1172 CFDataRef anchorData
= NULL
;
1174 require(anchorData
= CFDataCreate(kCFAllocatorDefault
, anchorSha1
, kSecPolicySHA1Size
), errOut
);
1175 add_element(options
, kSecPolicyCheckAnchorSHA1
, anchorData
);
1180 CFReleaseSafe(anchorData
);
1184 static bool SecPolicyAddAppleAnchorOptions(CFMutableDictionaryRef options
)
1186 return SecPolicyAddAnchorSHA1Options(options
, kAppleCASHA1
);
1190 // Policy Creation Functions
1192 SecPolicyRef
SecPolicyCreateBasicX509(void) {
1193 CFMutableDictionaryRef options
= NULL
;
1194 SecPolicyRef result
= NULL
;
1196 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1197 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1199 SecPolicyAddBasicX509Options(options
);
1200 CFDictionaryAddValue(options
, kSecPolicyCheckNoNetworkAccess
,
1203 require(result
= SecPolicyCreate(kSecPolicyOIDBasicX509
, options
), errOut
);
1206 CFReleaseSafe(options
);
1210 SecPolicyRef
SecPolicyCreateSSL(Boolean server
, CFStringRef hostname
) {
1211 CFMutableDictionaryRef options
= NULL
;
1212 SecPolicyRef result
= NULL
;
1214 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1215 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1217 SecPolicyAddBasicX509Options(options
);
1220 CFDictionaryAddValue(options
, kSecPolicyCheckKeyUsage
,
1225 CFDictionaryAddValue(options
, kSecPolicyCheckSSLHostname
, hostname
);
1228 CFDictionaryAddValue(options
, kSecPolicyCheckBlackListedLeaf
, kCFBooleanTrue
);
1229 CFDictionaryAddValue(options
, kSecPolicyCheckGrayListedLeaf
, kCFBooleanTrue
);
1231 /* If server and EKU ext present then EKU ext should contain one of
1232 CSSMOID_ServerAuth or CSSMOID_ExtendedKeyUsageAny or
1233 CSSMOID_NetscapeSGC or CSSMOID_MicrosoftSGC.
1234 else if !server and EKU ext present then EKU ext should contain one of
1235 CSSMOID_ClientAuth or CSSMOID_ExtendedKeyUsageAny. */
1237 /* We always allow certification that specify oidAnyExtendedKeyUsage. */
1238 add_eku(options
, NULL
); /* eku extension is optional */
1239 add_eku(options
, &oidAnyExtendedKeyUsage
);
1241 add_eku(options
, &oidExtendedKeyUsageServerAuth
);
1242 add_eku(options
, &oidExtendedKeyUsageMicrosoftSGC
);
1243 add_eku(options
, &oidExtendedKeyUsageNetscapeSGC
);
1245 add_eku(options
, &oidExtendedKeyUsageClientAuth
);
1248 require(result
= SecPolicyCreate(
1249 server
? kSecPolicyOIDSSLServer
: kSecPolicyOIDSSLClient
,
1253 CFReleaseSafe(options
);
1257 SecPolicyRef
SecPolicyCreateiPhoneActivation(void) {
1258 CFMutableDictionaryRef options
= NULL
;
1259 SecPolicyRef result
= NULL
;
1261 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1262 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1264 SecPolicyAddBasicCertOptions(options
);
1267 CFDictionaryAddValue(options
, kSecPolicyCheckKeyUsage
,
1269 CFDictionaryAddValue(options
, kSecPolicyCheckExtendedKeyUsage
,
1273 /* Basic X.509 policy with the additional requirements that the chain
1274 length is 3, it's anchored at the AppleCA and the leaf certificate
1275 has issuer "Apple iPhone Certification Authority" and
1276 subject "Apple iPhone Activation" for the common name. */
1277 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
1278 CFSTR("Apple iPhone Certification Authority"));
1279 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
,
1280 CFSTR("Apple iPhone Activation"));
1282 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1283 require(SecPolicyAddAppleAnchorOptions(options
), errOut
);
1285 require(result
= SecPolicyCreate(kSecPolicyOIDiPhoneActivation
, options
),
1289 CFReleaseSafe(options
);
1293 SecPolicyRef
SecPolicyCreateiPhoneDeviceCertificate(void) {
1294 CFMutableDictionaryRef options
= NULL
;
1295 SecPolicyRef result
= NULL
;
1297 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1298 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1300 SecPolicyAddBasicCertOptions(options
);
1303 CFDictionaryAddValue(options
, kSecPolicyCheckKeyUsage
,
1305 CFDictionaryAddValue(options
, kSecPolicyCheckExtendedKeyUsage
,
1309 /* Basic X.509 policy with the additional requirements that the chain
1310 length is 4, it's anchored at the AppleCA and the first intermediate
1311 has the subject "Apple iPhone Device CA". */
1312 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
1313 CFSTR("Apple iPhone Device CA"));
1315 require(SecPolicyAddChainLengthOptions(options
, 4), errOut
);
1316 require(SecPolicyAddAppleAnchorOptions(options
), errOut
);
1318 require(result
= SecPolicyCreate(kSecPolicyOIDiPhoneDeviceCertificate
, options
),
1322 CFReleaseSafe(options
);
1326 SecPolicyRef
SecPolicyCreateFactoryDeviceCertificate(void) {
1327 CFMutableDictionaryRef options
= NULL
;
1328 SecPolicyRef result
= NULL
;
1330 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1331 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1333 SecPolicyAddBasicCertOptions(options
);
1336 CFDictionaryAddValue(options
, kSecPolicyCheckKeyUsage
,
1338 CFDictionaryAddValue(options
, kSecPolicyCheckExtendedKeyUsage
,
1342 /* Basic X.509 policy with the additional requirements that the chain
1343 is anchored at the factory device certificate issuer. */
1344 require(SecPolicyAddAnchorSHA1Options(options
, kFactoryDeviceCASHA1
), errOut
);
1346 require(result
= SecPolicyCreate(kSecPolicyOIDFactoryDeviceCertificate
, options
),
1350 CFReleaseSafe(options
);
1354 SecPolicyRef
SecPolicyCreateiAP(void) {
1355 CFMutableDictionaryRef options
= NULL
;
1356 SecPolicyRef result
= NULL
;
1357 CFTimeZoneRef tz
= NULL
;
1358 CFDateRef date
= NULL
;
1360 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1361 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1363 SecPolicyAddBasicCertOptions(options
);
1365 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonNamePrefix
,
1368 date
= CFDateCreateForGregorianZuluDay(NULL
, 2006, 5, 31);
1369 CFDictionaryAddValue(options
, kSecPolicyCheckNotValidBefore
, date
);
1371 require(result
= SecPolicyCreate(kSecPolicyOIDiAP
, options
),
1375 CFReleaseSafe(date
);
1377 CFReleaseSafe(options
);
1381 SecPolicyRef
SecPolicyCreateiTunesStoreURLBag(void) {
1382 CFMutableDictionaryRef options
= NULL
;
1383 SecPolicyRef result
= NULL
;
1386 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1387 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1389 SecPolicyAddBasicCertOptions(options
);
1391 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectOrganization
,
1392 CFSTR("Apple Inc."));
1393 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
,
1394 CFSTR("iTunes Store URL Bag"));
1396 require(SecPolicyAddChainLengthOptions(options
, 2), errOut
);
1397 require(SecPolicyAddAnchorSHA1Options(options
, kITMSCASHA1
), errOut
);
1399 require(result
= SecPolicyCreate(kSecPolicyOIDiTunesStoreURLBag
, options
), errOut
);
1402 CFReleaseSafe(options
);
1406 SecPolicyRef
SecPolicyCreateEAP(Boolean server
, CFArrayRef trustedServerNames
) {
1407 CFMutableDictionaryRef options
= NULL
;
1408 SecPolicyRef result
= NULL
;
1410 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1411 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1413 SecPolicyAddBasicX509Options(options
);
1416 CFDictionaryAddValue(options
, kSecPolicyCheckKeyUsage
,
1418 CFDictionaryAddValue(options
, kSecPolicyCheckExtendedKeyUsage
,
1422 /* Since EAP is used to setup the network we don't want evaluation
1423 using this policy to access the network. */
1424 CFDictionaryAddValue(options
, kSecPolicyCheckNoNetworkAccess
,
1426 if (trustedServerNames
) {
1427 CFDictionaryAddValue(options
, kSecPolicyCheckEAPTrustedServerNames
, trustedServerNames
);
1430 require(result
= SecPolicyCreate(
1431 server
? kSecPolicyOIDEAPServer
: kSecPolicyOIDEAPClient
,
1435 CFReleaseSafe(options
);
1439 SecPolicyRef
SecPolicyCreateIPSec(Boolean server
, CFStringRef hostname
) {
1440 CFMutableDictionaryRef options
= NULL
;
1441 SecPolicyRef result
= NULL
;
1443 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1444 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1446 SecPolicyAddBasicX509Options(options
);
1449 CFDictionaryAddValue(options
, kSecPolicyCheckSSLHostname
, hostname
);
1452 /* Require oidExtendedKeyUsageIPSec if Extended Keyusage Extention is
1454 /* Per <rdar://problem/6843827> Cisco VPN Certificate compatibility issue.
1455 We don't check the EKU for IPSec certs for now. If we do add eku
1456 checking back in the future, we should probably also accept the
1458 ipsecEndSystem 1.3.6.1.5.5.7.3.5
1460 ipsecTunnel 1.3.6.1.5.5.7.3.6
1461 ipsecUser 1.3.6.1.5.5.7.3.7
1463 //add_eku(options, NULL); /* eku extension is optional */
1464 //add_eku(options, &oidAnyExtendedKeyUsage);
1465 //add_eku(options, &oidExtendedKeyUsageIPSec);
1467 require(result
= SecPolicyCreate(
1468 server
? kSecPolicyOIDIPSecServer
: kSecPolicyOIDIPSecClient
,
1472 CFReleaseSafe(options
);
1476 SecPolicyRef
SecPolicyCreateiPhoneApplicationSigning(void) {
1477 CFMutableDictionaryRef options
= NULL
;
1478 SecPolicyRef result
= NULL
;
1480 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1481 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1483 SecPolicyAddBasicCertOptions(options
);
1485 /* Basic X.509 policy with the additional requirements that the chain
1486 length is 3, it's anchored at the AppleCA and the leaf certificate
1487 has issuer "Apple iPhone Certification Authority" and
1488 subject "Apple iPhone OS Application Signing" for the common name. */
1489 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
1490 CFSTR("Apple iPhone Certification Authority"));
1491 if (SecIsInternalRelease() && !SecIsProductionFused()) {
1492 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonNameTEST
,
1493 CFSTR("Apple iPhone OS Application Signing"));
1496 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
,
1497 CFSTR("Apple iPhone OS Application Signing"));
1500 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1501 require(SecPolicyAddAppleAnchorOptions(options
), errOut
);
1503 add_eku(options
, NULL
); /* eku extension is optional */
1504 add_eku(options
, &oidAnyExtendedKeyUsage
);
1505 add_eku(options
, &oidExtendedKeyUsageCodeSigning
);
1507 require(result
= SecPolicyCreate(kSecPolicyOIDiPhoneApplicationSigning
, options
),
1510 /* 1.2.840.113635.100.6.1.3, non-critical: DER:05:00 - application signing */
1513 CFReleaseSafe(options
);
1517 SecPolicyRef
SecPolicyCreateiPhoneProfileApplicationSigning(void) {
1518 CFMutableDictionaryRef options
= NULL
;
1519 SecPolicyRef result
= NULL
;
1521 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1522 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1523 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kCFBooleanFalse
);
1524 CFDictionaryAddValue(options
, kSecPolicyCheckValidLeaf
, kCFBooleanFalse
);
1526 require(result
= SecPolicyCreate(kSecPolicyOIDiPhoneProfileApplicationSigning
,
1530 CFReleaseSafe(options
);
1534 SecPolicyRef
SecPolicyCreateiPhoneProvisioningProfileSigning(void) {
1535 CFMutableDictionaryRef options
= NULL
;
1536 SecPolicyRef result
= NULL
;
1538 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1539 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1541 SecPolicyAddBasicCertOptions(options
);
1543 /* Basic X.509 policy with the additional requirements that the chain
1544 length is 3, it's anchored at the AppleCA and the leaf certificate
1545 has issuer "Apple iPhone Certification Authority" and
1546 subject "Apple iPhone OS Provisioning Profile Signing" for the common name. */
1547 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
1548 CFSTR("Apple iPhone Certification Authority"));
1549 if (SecIsInternalRelease() && !SecIsProductionFused()) {
1550 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonNameTEST
,
1551 CFSTR("Apple iPhone OS Provisioning Profile Signing"));
1554 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
,
1555 CFSTR("Apple iPhone OS Provisioning Profile Signing"));
1558 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1559 require(SecPolicyAddAppleAnchorOptions(options
), errOut
);
1561 require(result
= SecPolicyCreate(kSecPolicyOIDiPhoneProvisioningProfileSigning
, options
),
1564 /* 1.2.840.113635.100.6.2.2.1, non-critical: DER:05:00 - provisioning profile */
1567 CFReleaseSafe(options
);
1571 SecPolicyRef
SecPolicyCreateAppleTVOSApplicationSigning(void) {
1572 CFMutableDictionaryRef options
= NULL
;
1573 SecPolicyRef result
= NULL
;
1574 CFDataRef atvProdOid
= NULL
;
1575 CFDataRef atvTestOid
= NULL
;
1576 CFArrayRef oids
= NULL
;
1578 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1579 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1581 SecPolicyAddBasicCertOptions(options
);
1583 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1585 CFMutableDictionaryRef appleAnchorOptions
= CFDictionaryCreateMutableForCFTypes(NULL
);
1586 require(appleAnchorOptions
, errOut
);
1587 add_element(options
, kSecPolicyCheckAnchorApple
, appleAnchorOptions
);
1589 /* Check for intermediate: Apple Worldwide Developer Relations */
1590 /* 1.2.840.113635.100.6.2.1 */
1591 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleWWDR
);
1593 add_eku(options
, NULL
); /* eku extension is optional */
1594 add_eku(options
, &oidAnyExtendedKeyUsage
);
1595 add_eku(options
, &oidExtendedKeyUsageCodeSigning
);
1597 /* Check for prod or test AppleTV Application Signing OIDs */
1598 /* Prod: 1.2.840.113635.100.6.1.24 */
1599 /* Test: 1.2.840.113635.100.6.1.24.1 */
1600 atvProdOid
= CFDataCreate(kCFAllocatorDefault
, oidAppleTVOSApplicationSigningProd
.data
, oidAppleTVOSApplicationSigningProd
.length
);
1601 require(atvProdOid
, errOut
);
1602 atvTestOid
= CFDataCreate(kCFAllocatorDefault
, oidAppleTVOSApplicationSigningTest
.data
, oidAppleTVOSApplicationSigningTest
.length
);
1603 require(atvTestOid
, errOut
);
1605 oids
= CFArrayCreateForCFTypes(kCFAllocatorDefault
, atvProdOid
, atvTestOid
, NULL
);
1606 require(oids
, errOut
);
1608 add_element(options
, kSecPolicyCheckLeafMarkerOid
, oids
);
1610 require(result
= SecPolicyCreate(kSecPolicyOIDAppleTVOSApplicationSigning
, options
),
1614 CFReleaseSafe(options
);
1615 CFReleaseSafe(oids
);
1616 CFReleaseSafe(atvProdOid
);
1617 CFReleaseSafe(atvTestOid
);
1621 SecPolicyRef
SecPolicyCreateOCSPSigner(void) {
1622 CFMutableDictionaryRef options
= NULL
;
1623 SecPolicyRef result
= NULL
;
1625 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1626 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1628 SecPolicyAddBasicX509Options(options
);
1630 /* Require id-kp-OCSPSigning extendedKeyUsage to be present, not optional. */
1631 add_eku(options
, &oidExtendedKeyUsageOCSPSigning
);
1633 require(result
= SecPolicyCreate(kSecPolicyOIDOCSPSigner
, options
), errOut
);
1636 CFReleaseSafe(options
);
1640 SecPolicyRef
SecPolicyCreateRevocation(CFOptionFlags revocationFlags
) {
1641 CFMutableDictionaryRef options
= NULL
;
1642 SecPolicyRef result
= NULL
;
1644 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1645 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1647 /* false = ocsp, true = crl, string/url value = crl distribution point,
1648 array = list of multiple values for example false, true, url1, url2
1649 check ocsp, crl, and url1 and url2 for certs which have no extensions.
1651 if (revocationFlags
& kSecRevocationOCSPMethod
) {
1652 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kCFBooleanFalse
);
1654 else if (revocationFlags
& kSecRevocationCRLMethod
) {
1655 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kCFBooleanTrue
);
1658 if (revocationFlags
& kSecRevocationRequirePositiveResponse
) {
1659 CFDictionaryAddValue(options
, kSecPolicyCheckRevocationResponseRequired
, kCFBooleanTrue
);
1662 if (revocationFlags
& kSecRevocationNetworkAccessDisabled
) {
1663 CFDictionaryAddValue(options
, kSecPolicyCheckNoNetworkAccess
, kCFBooleanTrue
);
1666 /* Only flag bits 0-4 are currently defined */
1667 require(((revocationFlags
>> 5) == 0), errOut
);
1669 require(result
= SecPolicyCreate(kSecPolicyOIDRevocation
, options
), errOut
);
1672 CFReleaseSafe(options
);
1676 SecPolicyRef
SecPolicyCreateSMIME(CFIndex smimeUsage
, CFStringRef email
) {
1677 CFMutableDictionaryRef options
= NULL
;
1678 SecPolicyRef result
= NULL
;
1680 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1681 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1683 SecPolicyAddBasicX509Options(options
);
1685 /* We call add_ku for each combination of bits we are willing to allow. */
1686 if (smimeUsage
& kSecSignSMIMEUsage
) {
1687 add_ku(options
, kSecKeyUsageUnspecified
);
1688 add_ku(options
, kSecKeyUsageDigitalSignature
);
1689 add_ku(options
, kSecKeyUsageNonRepudiation
);
1691 if (smimeUsage
& kSecKeyEncryptSMIMEUsage
) {
1692 add_ku(options
, kSecKeyUsageKeyEncipherment
);
1694 if (smimeUsage
& kSecDataEncryptSMIMEUsage
) {
1695 add_ku(options
, kSecKeyUsageDataEncipherment
);
1697 if (smimeUsage
& kSecKeyExchangeDecryptSMIMEUsage
) {
1698 add_ku(options
, kSecKeyUsageKeyAgreement
| kSecKeyUsageDecipherOnly
);
1700 if (smimeUsage
& kSecKeyExchangeEncryptSMIMEUsage
) {
1701 add_ku(options
, kSecKeyUsageKeyAgreement
| kSecKeyUsageEncipherOnly
);
1703 if (smimeUsage
& kSecKeyExchangeBothSMIMEUsage
) {
1704 add_ku(options
, kSecKeyUsageKeyAgreement
| kSecKeyUsageEncipherOnly
| kSecKeyUsageDecipherOnly
);
1708 CFDictionaryAddValue(options
, kSecPolicyCheckEmail
, email
);
1711 /* RFC 3850 paragraph 4.4.4
1713 If the extended key usage extension is present in the certificate
1714 then interpersonal message S/MIME receiving agents MUST check that it
1715 contains either the emailProtection or the anyExtendedKeyUsage OID as
1716 defined in [KEYM]. S/MIME uses other than interpersonal messaging
1717 MAY require the explicit presence of the extended key usage extension
1718 or other OIDs to be present in the extension or both.
1720 add_eku(options
, NULL
); /* eku extension is optional */
1721 add_eku(options
, &oidAnyExtendedKeyUsage
);
1722 add_eku(options
, &oidExtendedKeyUsageEmailProtection
);
1724 require(result
= SecPolicyCreate(kSecPolicyOIDSMIME
, options
), errOut
);
1727 CFReleaseSafe(options
);
1731 SecPolicyRef
SecPolicyCreateApplePackageSigning(void) {
1732 CFMutableDictionaryRef options
= NULL
;
1733 SecPolicyRef result
= NULL
;
1735 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1736 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1738 // TBD: review OS X policy to see what options are needed for this policy
1739 SecPolicyAddBasicCertOptions(options
);
1741 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1742 require(SecPolicyAddAppleAnchorOptions(options
), errOut
);
1744 require(result
= SecPolicyCreate(kSecPolicyOIDPackageSigning
, options
),
1748 CFReleaseSafe(options
);
1753 SecPolicyRef
SecPolicyCreateAppleSWUpdateSigning(void) {
1754 CFMutableDictionaryRef options
= NULL
;
1755 SecPolicyRef result
= NULL
;
1757 * OS X rules for this policy:
1758 * -- Must have one intermediate cert
1759 * -- intermediate must have basic constraints with path length 0
1760 * -- intermediate has CSSMOID_APPLE_EKU_CODE_SIGNING EKU
1761 * -- leaf cert has either CODE_SIGNING or CODE_SIGN_DEVELOPMENT EKU (the latter of
1762 * which triggers a CSSMERR_APPLETP_CODE_SIGN_DEVELOPMENT error)
1764 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1765 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1767 // TBD: review OS X policy to see what options are needed for this policy
1768 SecPolicyAddBasicCertOptions(options
);
1770 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1771 require(SecPolicyAddAppleAnchorOptions(options
), errOut
);
1773 add_eku(options
, &oidAppleExtendedKeyUsageCodeSigning
);
1774 add_eku(options
, &oidAppleExtendedKeyUsageCodeSigningDev
);
1776 require(result
= SecPolicyCreate(kSecPolicyOIDAppleSWUpdateSigning
, options
),
1780 CFReleaseSafe(options
);
1785 SecPolicyRef
SecPolicyCreateCodeSigning(void) {
1786 CFMutableDictionaryRef options
= NULL
;
1787 SecPolicyRef result
= NULL
;
1789 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1790 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1793 #warning STU: <rdar://21328880>
1794 //%%% figure out why this policy is not passing for OS X.
1795 // I suspect it has to do with iOS not supporting anchor and keychain options yet.
1796 SecPolicyAddBasicCertOptions(options
);
1798 SecPolicyAddBasicX509Options(options
);
1800 /* If the key usage extension is present we accept it having either of
1802 add_ku(options
, kSecKeyUsageDigitalSignature
);
1803 add_ku(options
, kSecKeyUsageNonRepudiation
);
1805 /* We require a extended key usage extension and we accept any or
1806 codesigning ekus. */
1807 /* TODO: Do we want to accept the apple codesigning oid as well or is
1808 that a separate policy? */
1809 /* ANSWER: it's a separate policy, SecPolicyCreateAppleSWUpdateSigning */
1810 add_eku(options
, &oidAnyExtendedKeyUsage
);
1811 add_eku(options
, &oidExtendedKeyUsageCodeSigning
);
1814 require(result
= SecPolicyCreate(kSecPolicyOIDCodeSigning
, options
),
1818 CFReleaseSafe(options
);
1822 /* Explicitly leave out empty subject/subjectaltname check */
1823 SecPolicyRef
SecPolicyCreateLockdownPairing(void) {
1824 CFMutableDictionaryRef options
= NULL
;
1825 SecPolicyRef result
= NULL
;
1827 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1828 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1829 //CFDictionaryAddValue(options, kSecPolicyCheckBasicCertificateProcessing,
1831 CFDictionaryAddValue(options
, kSecPolicyCheckCriticalExtensions
,
1833 CFDictionaryAddValue(options
, kSecPolicyCheckIdLinkage
,
1835 CFDictionaryAddValue(options
, kSecPolicyCheckBasicContraints
,
1837 CFDictionaryAddValue(options
, kSecPolicyCheckQualifiedCertStatements
,
1840 require(result
= SecPolicyCreate(kSecPolicyOIDLockdownPairing
, options
), errOut
);
1843 CFReleaseSafe(options
);
1847 SecPolicyRef
SecPolicyCreateURLBag(void) {
1848 CFMutableDictionaryRef options
= NULL
;
1849 SecPolicyRef result
= NULL
;
1851 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1852 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1854 SecPolicyAddBasicCertOptions(options
);
1856 add_eku(options
, &oidExtendedKeyUsageCodeSigning
);
1858 require(result
= SecPolicyCreate(kSecPolicyOIDURLBag
, options
), errOut
);
1861 CFReleaseSafe(options
);
1865 static bool SecPolicyAddAppleCertificationAuthorityOptions(CFMutableDictionaryRef options
, bool honorValidity
)
1867 bool success
= false;
1870 SecPolicyAddBasicX509Options(options
);
1872 SecPolicyAddBasicCertOptions(options
);
1875 CFDictionaryAddValue(options
, kSecPolicyCheckKeyUsage
,
1877 CFDictionaryAddValue(options
, kSecPolicyCheckExtendedKeyUsage
,
1881 /* Basic X.509 policy with the additional requirements that the chain
1882 length is 3, it's anchored at the AppleCA and the leaf certificate
1883 has issuer "Apple iPhone Certification Authority". */
1884 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
1885 CFSTR("Apple iPhone Certification Authority"));
1887 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1888 require(SecPolicyAddAppleAnchorOptions(options
), errOut
);
1896 static SecPolicyRef
SecPolicyCreateAppleCertificationAuthorityPolicy(CFStringRef policyOID
, CFStringRef leafName
, bool honorValidity
)
1898 CFMutableDictionaryRef options
= NULL
;
1899 SecPolicyRef result
= NULL
;
1901 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1902 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1904 require(SecPolicyAddAppleCertificationAuthorityOptions(options
, honorValidity
), errOut
);
1906 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
, leafName
);
1908 require(result
= SecPolicyCreate(policyOID
, options
),
1912 CFReleaseSafe(options
);
1917 SecPolicyRef
SecPolicyCreateOTATasking(void)
1919 return SecPolicyCreateAppleCertificationAuthorityPolicy(kSecPolicyOIDOTATasking
, CFSTR("OTA Task Signing"), true);
1922 SecPolicyRef
SecPolicyCreateMobileAsset(void)
1924 return SecPolicyCreateAppleCertificationAuthorityPolicy(kSecPolicyOIDMobileAsset
, CFSTR("Asset Manifest Signing"), false);
1927 SecPolicyRef
SecPolicyCreateAppleIDAuthorityPolicy(void)
1929 SecPolicyRef result
= NULL
;
1930 CFMutableDictionaryRef options
= NULL
;
1931 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1932 &kCFTypeDictionaryKeyCallBacks
,
1933 &kCFTypeDictionaryValueCallBacks
), out
);
1935 //Leaf appears to be a SSL only cert, so policy should expand on that policy
1936 SecPolicyAddBasicX509Options(options
);
1938 // Apple CA anchored
1939 require(SecPolicyAddAppleAnchorOptions(options
), out
);
1941 // with the addition of the existence check of an extension with "Apple ID Sharing Certificate" oid (1.2.840.113635.100.4.7)
1942 // NOTE: this obviously intended to have gone into Extended Key Usage, but evidence of existing certs proves the contrary.
1943 add_leaf_marker(options
, &oidAppleExtendedKeyUsageAppleID
);
1945 // 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.
1946 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleID
);
1947 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleID2
);
1949 require(result
= SecPolicyCreate(kSecPolicyOIDAppleIDAuthority
, options
), out
);
1952 CFReleaseSafe(options
);
1956 SecPolicyRef
SecPolicyCreateMacAppStoreReceipt(void)
1958 SecPolicyRef result
= NULL
;
1959 CFMutableDictionaryRef options
= NULL
;
1960 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1961 &kCFTypeDictionaryKeyCallBacks
,
1962 &kCFTypeDictionaryValueCallBacks
), out
);
1964 SecPolicyAddBasicX509Options(options
);
1966 // Apple CA anchored
1967 require(SecPolicyAddAppleAnchorOptions(options
), out
);
1969 // - leaf needs certificatePolicies with CSSMOID_MACAPPSTORE_RECEIPT_CERT_POLICY
1970 // - chain length must be 3
1972 require(result
= SecPolicyCreate(kSecPolicyOIDMacAppStoreReceipt
, options
), out
);
1975 CFReleaseSafe(options
);
1980 static SecPolicyRef
_SecPolicyCreatePassbookCardSigner(CFStringRef cardIssuer
, CFStringRef teamIdentifier
, bool requireTeamID
)
1982 SecPolicyRef result
= NULL
;
1983 CFMutableDictionaryRef options
= NULL
;
1984 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1985 &kCFTypeDictionaryKeyCallBacks
,
1986 &kCFTypeDictionaryValueCallBacks
), out
);
1988 SecPolicyAddBasicX509Options(options
);
1989 SecPolicyAddAppleAnchorOptions(options
);
1991 if (teamIdentifier
) {
1992 // If supplied, teamIdentifier must match subject OU field
1993 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectOrganizationalUnit
, teamIdentifier
);
1996 // If not supplied, and it was required, fail
1997 require(!requireTeamID
, out
);
2000 // Must be both push and 3rd party package signing
2001 add_leaf_marker_value(options
, &oidAppleInstallerPackagingSigningExternal
, cardIssuer
);
2003 // We should check that it also has push marker, but we don't support requiring both, only either.
2004 // add_independent_oid(options, kSecPolicyCheckLeafMarkerOid, &oidApplePushServiceClient);
2006 // And Passbook signing eku
2007 add_eku(options
, &oidAppleExtendedKeyUsagePassbook
);
2009 require(result
= SecPolicyCreate(kSecPolicyOIDApplePassbook
, options
), out
);
2012 CFReleaseSafe(options
);
2016 SecPolicyRef
SecPolicyCreatePassbookCardSigner(CFStringRef cardIssuer
, CFStringRef teamIdentifier
)
2018 return _SecPolicyCreatePassbookCardSigner(cardIssuer
, teamIdentifier
, true);
2022 static SecPolicyRef
CreateMobileStoreSigner(Boolean forTest
)
2025 SecPolicyRef result
= NULL
;
2026 CFMutableDictionaryRef options
= NULL
;
2027 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2028 &kCFTypeDictionaryKeyCallBacks
,
2029 &kCFTypeDictionaryValueCallBacks
), errOut
);
2030 SecPolicyAddBasicX509Options(options
);
2031 SecPolicyAddAppleAnchorOptions(options
);
2033 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2035 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2036 CFSTR("Apple System Integration 2 Certification Authority"));
2038 add_ku(options
, kSecKeyUsageDigitalSignature
);
2040 const DERItem
* pOID
= (forTest
) ? &oidApplePolicyTestMobileStore
: &oidApplePolicyMobileStore
;
2042 add_certificate_policy_oid(options
, pOID
, NULL
);
2044 require(result
= SecPolicyCreate(kSecPolicyOIDAppleMobileStore
, options
), errOut
);
2047 CFReleaseSafe(options
);
2051 SecPolicyRef
SecPolicyCreateMobileStoreSigner(void)
2054 return CreateMobileStoreSigner(false);
2057 SecPolicyRef
SecPolicyCreateTestMobileStoreSigner(void)
2060 return CreateMobileStoreSigner(true);
2064 CF_RETURNS_RETAINED SecPolicyRef
SecPolicyCreateEscrowServiceSigner(void)
2066 SecPolicyRef result
= NULL
;
2067 CFMutableDictionaryRef options
= NULL
;
2068 CFArrayRef anArray
= NULL
;
2069 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2070 &kCFTypeDictionaryKeyCallBacks
,
2071 &kCFTypeDictionaryValueCallBacks
), errOut
);
2073 // X509, ignoring date validity
2074 SecPolicyAddBasicCertOptions(options
);
2077 add_ku(options
, kSecKeyUsageKeyEncipherment
);
2079 //add_leaf_marker(options, &oidApplePolicyEscrowService);
2080 require(SecPolicyAddChainLengthOptions(options
, 2), errOut
);
2083 Boolean anchorAdded
= false;
2084 // Get the roots by calling the SecCertificateCopyEscrowRoots
2085 anArray
= SecCertificateCopyEscrowRoots(kSecCertificateProductionEscrowRoot
);
2086 CFIndex numRoots
= 0;
2087 if (NULL
== anArray
|| 0 == (numRoots
= CFArrayGetCount(anArray
)))
2092 for (CFIndex iCnt
= 0; iCnt
< numRoots
; iCnt
++)
2094 SecCertificateRef aCert
= (SecCertificateRef
)CFArrayGetValueAtIndex(anArray
, iCnt
);
2098 CFDataRef sha_data
= SecCertificateGetSHA1Digest(aCert
);
2099 if (NULL
!= sha_data
)
2101 const UInt8
* pSHAData
= CFDataGetBytePtr(sha_data
);
2102 if (NULL
!= pSHAData
)
2104 SecPolicyAddAnchorSHA1Options(options
, pSHAData
);
2110 CFReleaseNull(anArray
);
2118 require(result
= SecPolicyCreate(kSecPolicyOIDAppleEscrowService
, options
), errOut
);
2121 CFReleaseSafe(anArray
);
2122 CFReleaseSafe(options
);
2126 CF_RETURNS_RETAINED SecPolicyRef
SecPolicyCreatePCSEscrowServiceSigner(void)
2128 SecPolicyRef result
= NULL
;
2129 CFMutableDictionaryRef options
= NULL
;
2130 CFArrayRef anArray
= NULL
;
2131 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2132 &kCFTypeDictionaryKeyCallBacks
,
2133 &kCFTypeDictionaryValueCallBacks
), errOut
);
2135 SecPolicyAddBasicX509Options(options
);
2138 add_ku(options
, kSecKeyUsageKeyEncipherment
);
2140 //add_leaf_marker(options, &oidApplePolicyEscrowService);
2141 require(SecPolicyAddChainLengthOptions(options
, 2), errOut
);
2144 Boolean anchorAdded
= false;
2145 anArray
= SecCertificateCopyEscrowRoots(kSecCertificateProductionPCSEscrowRoot
);
2146 CFIndex numRoots
= 0;
2147 if (NULL
== anArray
|| 0 == (numRoots
= CFArrayGetCount(anArray
)))
2152 for (CFIndex iCnt
= 0; iCnt
< numRoots
; iCnt
++)
2154 SecCertificateRef aCert
= (SecCertificateRef
)CFArrayGetValueAtIndex(anArray
, iCnt
);
2158 CFDataRef sha_data
= SecCertificateGetSHA1Digest(aCert
);
2159 if (NULL
!= sha_data
)
2161 const UInt8
* pSHAData
= CFDataGetBytePtr(sha_data
);
2162 if (NULL
!= pSHAData
)
2164 SecPolicyAddAnchorSHA1Options(options
, pSHAData
);
2170 CFReleaseNull(anArray
);
2178 require(result
= SecPolicyCreate(kSecPolicyOIDApplePCSEscrowService
, options
), errOut
);
2181 CFReleaseSafe(anArray
);
2182 CFReleaseSafe(options
);
2185 SecCertificateRef
SecPolicyCopyEscrowRootCertificate(void)
2187 SecCertificateRef result
= NULL
;
2192 SecPolicyRef
SecPolicyCreateConfigurationProfileSigner(void)
2194 SecPolicyRef result
= NULL
;
2195 CFMutableDictionaryRef options
= NULL
;
2196 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2197 &kCFTypeDictionaryKeyCallBacks
,
2198 &kCFTypeDictionaryValueCallBacks
), errOut
);
2200 SecPolicyAddBasicX509Options(options
);
2201 SecPolicyAddAppleAnchorOptions(options
);
2203 // Require the profile signing EKU
2204 add_eku(options
, &oidAppleExtendedKeyUsageProfileSigning
);
2206 require(result
= SecPolicyCreate(kSecPolicyOIDAppleProfileSigner
, options
), errOut
);
2209 CFReleaseSafe(options
);
2214 SecPolicyRef
SecPolicyCreateQAConfigurationProfileSigner(void)
2216 SecPolicyRef result
= NULL
;
2217 CFMutableDictionaryRef options
= NULL
;
2218 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2219 &kCFTypeDictionaryKeyCallBacks
,
2220 &kCFTypeDictionaryValueCallBacks
), errOut
);
2222 SecPolicyAddBasicX509Options(options
);
2223 SecPolicyAddAppleAnchorOptions(options
);
2225 // Require the QA profile signing EKU
2226 add_eku(options
, &oidAppleExtendedKeyUsageQAProfileSigning
);
2228 require(result
= SecPolicyCreate(kSecPolicyOIDAppleQAProfileSigner
, options
), errOut
);
2231 CFReleaseSafe(options
);
2236 SecPolicyRef
SecPolicyCreateOTAPKISigner(void)
2238 SecPolicyRef result
= NULL
;
2239 CFMutableDictionaryRef options
= NULL
;
2240 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2241 &kCFTypeDictionaryKeyCallBacks
,
2242 &kCFTypeDictionaryValueCallBacks
), errOut
);
2243 SecPolicyAddBasicX509Options(options
);
2245 SecPolicyAddAnchorSHA1Options(options
, kApplePKISettingsAuthority
);
2246 require(SecPolicyAddChainLengthOptions(options
, 2), errOut
);
2248 require(result
= SecPolicyCreate(kSecPolicyOIDAppleOTAPKIAssetSigner
, options
), errOut
);
2251 CFReleaseSafe(options
);
2257 SecPolicyRef
SecPolicyCreateTestOTAPKISigner(void)
2259 SecPolicyRef result
= NULL
;
2260 CFMutableDictionaryRef options
= NULL
;
2261 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2262 &kCFTypeDictionaryKeyCallBacks
,
2263 &kCFTypeDictionaryValueCallBacks
), errOut
);
2264 SecPolicyAddBasicX509Options(options
);
2266 SecPolicyAddAnchorSHA1Options(options
, kAppleTestPKISettingsAuthority
);
2267 require(SecPolicyAddChainLengthOptions(options
, 2), errOut
);
2269 require(result
= SecPolicyCreate(kSecPolicyOIDAppleTestOTAPKIAssetSigner
, options
), errOut
);
2272 CFReleaseSafe(options
);
2277 @function SecPolicyCreateAppleSMPEncryption
2278 @abstract Check for intermediate certificate 'Apple System Integration CA - G3' by name,
2279 and root certificate 'Apple Root CA - G3' by hash.
2280 Leaf cert must have Key Encipherment usage.
2281 Leaf cert must have Apple SMP Encryption marker OID (1.2.840.113635.100.6.30).
2282 Intermediate must have marker OID (1.2.840.113635.100.6.2.13).
2284 SecPolicyRef
SecPolicyCreateAppleSMPEncryption(void)
2286 SecPolicyRef result
= NULL
;
2287 CFMutableDictionaryRef options
= NULL
;
2288 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2289 &kCFTypeDictionaryKeyCallBacks
,
2290 &kCFTypeDictionaryValueCallBacks
), errOut
);
2291 SecPolicyAddBasicCertOptions(options
);
2293 SecPolicyAddAnchorSHA1Options(options
, kAppleRootCA_ECC_SHA1
);
2294 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2296 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2297 CFSTR("Apple System Integration CA - G3"));
2299 // Check that leaf has extension with "Apple SMP Encryption" oid (1.2.840.113635.100.6.30)
2300 add_leaf_marker(options
, &oidAppleCertExtAppleSMPEncryption
);
2302 // Check that intermediate has extension (1.2.840.113635.100.6.2.13)
2303 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleSystemIntgG3
);
2305 add_ku(options
, kSecKeyUsageKeyEncipherment
);
2307 // Ensure that revocation is checked (OCSP)
2308 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kCFBooleanFalse
);
2310 require(result
= SecPolicyCreate(kSecPolicyAppleSMPEncryption
, options
), errOut
);
2313 CFReleaseSafe(options
);
2318 @function SecPolicyCreateTestAppleSMPEncryption
2319 @abstract Check for intermediate certificate 'Test Apple System Integration CA - ECC' by name,
2320 and root certificate 'Test Apple Root CA - ECC' by hash.
2321 Leaf cert must have Key Encipherment usage. Other checks TBD.
2323 SecPolicyRef
SecPolicyCreateTestAppleSMPEncryption(void)
2325 SecPolicyRef result
= NULL
;
2326 CFMutableDictionaryRef options
= NULL
;
2327 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2328 &kCFTypeDictionaryKeyCallBacks
,
2329 &kCFTypeDictionaryValueCallBacks
), errOut
);
2330 SecPolicyAddBasicCertOptions(options
);
2332 SecPolicyAddAnchorSHA1Options(options
, kTestAppleRootCA_ECC_SHA1
);
2333 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2335 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2336 CFSTR("Test Apple System Integration CA - ECC"));
2338 add_ku(options
, kSecKeyUsageKeyEncipherment
);
2340 // Ensure that revocation is checked (OCSP)
2341 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kCFBooleanFalse
);
2343 require(result
= SecPolicyCreate(kSecPolicyAppleTestSMPEncryption
, options
), errOut
);
2346 CFReleaseSafe(options
);
2351 SecPolicyRef
SecPolicyCreateAppleIDValidationRecordSigningPolicy(void)
2353 SecPolicyRef result
= NULL
;
2354 CFMutableDictionaryRef options
= NULL
;
2355 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2356 &kCFTypeDictionaryKeyCallBacks
,
2357 &kCFTypeDictionaryValueCallBacks
), errOut
);
2359 //Leaf appears to be a SSL only cert, so policy should expand on that policy
2360 SecPolicyAddBasicX509Options(options
);
2362 // Apple CA anchored
2363 require(SecPolicyAddAppleAnchorOptions(options
), errOut
);
2365 // Check for an extension with " Apple ID Validation Record Signing" oid (1.2.840.113635.100.6.25)
2366 add_leaf_marker(options
, &oidAppleCertExtensionAppleIDRecordValidationSigning
);
2368 // and validate that intermediate has extension
2369 // Application Integration Intermediate Certificate (1.2.840.113635.100.6.2.3)
2370 // and also validate that intermediate has extension
2371 // System Integration 2 Intermediate Certificate (1.2.840.113635.100.6.2.10)
2372 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleID
);
2373 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleSystemIntg2
);
2375 // Ensure that revocation is checked (OCSP)
2376 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kCFBooleanFalse
);
2378 require(result
= SecPolicyCreate(kSecPolicyOIDAppleIDValidationRecordSigningPolicy
, options
), errOut
);
2381 CFReleaseSafe(options
);
2386 allowUATRoot(CFStringRef service
, CFDictionaryRef context
)
2388 bool UATAllowed
= false;
2389 if (SecIsInternalRelease()) {
2390 CFStringRef setting
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("AppleServerAuthenticationAllowUAT%@"), service
);
2391 CFTypeRef value
= NULL
;
2392 require(setting
, fail
);
2395 CFDictionaryGetValueIfPresent(context
, setting
, &value
) &&
2397 CFBooleanGetValue(value
))
2402 if (CFPreferencesGetAppBooleanValue(setting
, CFSTR("com.apple.Security"), NULL
)) {
2412 requirePinning(CFStringRef service
)
2414 bool pinningRequired
= true;
2416 if (SecIsInternalRelease()) {
2417 CFStringRef setting
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("AppleServerAuthenticationNoPinning%@"), service
);
2418 require(setting
, fail
);
2419 if (CFPreferencesGetAppBooleanValue(setting
, CFSTR("com.apple.Security"), NULL
))
2420 pinningRequired
= false;
2424 return pinningRequired
;
2428 @function SecPolicyCreateAppleServerAuthCommon
2429 @abstract Generic policy for server authentication Sub CAs
2431 Allows control for both if pinning is required at all and if UAT environments should be added
2432 to the trust policy.
2434 No pinning is for developer/QA that needs to use proxy to debug the protocol, while UAT
2435 environment is for QA/internal developer that have no need allow fake servers.
2437 Both the noPinning and allowUAT are gated on that you run on internal hardware.
2442 SecPolicyCreateAppleServerAuthCommon(CFStringRef hostname
,
2443 CFDictionaryRef __unused context
,
2444 CFStringRef service
,
2445 const DERItem
*leafMarkerOID
,
2446 const DERItem
*UATLeafMarkerOID
)
2448 CFMutableDictionaryRef appleAnchorOptions
= NULL
;
2449 CFMutableDictionaryRef options
= NULL
;
2450 SecPolicyRef result
= NULL
;
2451 CFDataRef oid
= NULL
, uatoid
= NULL
;
2453 options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0, &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
2454 require(options
, errOut
);
2456 SecPolicyAddBasicX509Options(options
);
2458 CFDictionaryAddValue(options
, kSecPolicyCheckSSLHostname
, hostname
);
2460 CFDictionaryAddValue(options
, kSecPolicyCheckBlackListedLeaf
, kCFBooleanTrue
);
2461 CFDictionaryAddValue(options
, kSecPolicyCheckGrayListedLeaf
, kCFBooleanTrue
);
2463 add_eku(options
, &oidExtendedKeyUsageServerAuth
);
2465 if (requirePinning(service
)) {
2466 bool allowUAT
= allowUATRoot(service
, context
);
2469 * Require pinning to the Apple CA's (and if UAT environment,
2470 * include the Apple Test CA's as anchors).
2473 appleAnchorOptions
= CFDictionaryCreateMutableForCFTypes(NULL
);
2474 require(appleAnchorOptions
, errOut
);
2477 CFDictionarySetValue(appleAnchorOptions
,
2478 kSecPolicyAppleAnchorIncludeTestRoots
, kCFBooleanTrue
);
2481 add_element(options
, kSecPolicyCheckAnchorApple
, appleAnchorOptions
);
2484 * Check if we also should allow the UAT variant of the leafs
2485 * as some variants of the UAT environment uses that instead
2486 * of the test Apple CA's.
2490 oid
= CFDataCreate(kCFAllocatorDefault
, leafMarkerOID
->data
, leafMarkerOID
->length
);
2491 require(oid
, errOut
);
2493 uatoid
= CFDataCreate(kCFAllocatorDefault
, UATLeafMarkerOID
->data
, UATLeafMarkerOID
->length
);
2494 require(oid
, errOut
);
2496 CFArrayRef array
= CFArrayCreateForCFTypes(NULL
, oid
, uatoid
, NULL
);
2497 require(array
, errOut
);
2499 add_element(options
, kSecPolicyCheckLeafMarkerOid
, array
);
2500 CFReleaseSafe(array
);
2502 add_leaf_marker(options
, leafMarkerOID
);
2505 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleServerAuthentication
);
2509 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kCFBooleanFalse
);
2511 result
= SecPolicyCreate(kSecPolicyOIDSSLServer
, options
);
2512 require(result
, errOut
);
2515 CFReleaseSafe(appleAnchorOptions
);
2516 CFReleaseSafe(options
);
2518 CFReleaseSafe(uatoid
);
2525 @function SecPolicyCreateAppleIDSService
2526 @abstract Ensure we're appropriately pinned to the IDS service (SSL + Apple restrictions)
2528 SecPolicyRef
SecPolicyCreateAppleIDSService(CFStringRef hostname
)
2531 return SecPolicyCreateSSL(true, hostname
);
2533 return SecPolicyCreateAppleServerAuthCommon(hostname
, NULL
, CFSTR("IDS"),
2534 &oidAppleCertExtAppleServerAuthenticationIDSProd
,
2535 &oidAppleCertExtAppleServerAuthenticationIDSTest
);
2540 @function SecPolicyCreateAppleIDSService
2541 @abstract Ensure we're appropriately pinned to the IDS service (SSL + Apple restrictions)
2543 SecPolicyRef
SecPolicyCreateAppleIDSServiceContext(CFStringRef hostname
, CFDictionaryRef context
)
2545 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, CFSTR("IDS"),
2546 &oidAppleCertExtAppleServerAuthenticationIDSProd
,
2547 &oidAppleCertExtAppleServerAuthenticationIDSTest
);
2551 @function SecPolicyCreateAppleGSService
2552 @abstract Ensure we're appropriately pinned to the GS service
2554 SecPolicyRef
SecPolicyCreateAppleGSService(CFStringRef hostname
, CFDictionaryRef context
)
2556 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, CFSTR("GS"),
2557 &oidAppleCertExtAppleServerAuthenticationGS
,
2562 @function SecPolicyCreateApplePushService
2563 @abstract Ensure we're appropriately pinned to the Push service (SSL + Apple restrictions)
2565 SecPolicyRef
SecPolicyCreateApplePushService(CFStringRef hostname
, CFDictionaryRef context
)
2567 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, CFSTR("APN"),
2568 &oidAppleCertExtAppleServerAuthenticationAPNProd
,
2569 &oidAppleCertExtAppleServerAuthenticationAPNTest
);
2573 @function SecPolicyCreateApplePPQService
2574 @abstract Ensure we're appropriately pinned to the PPQ service (SSL + Apple restrictions)
2576 SecPolicyRef
SecPolicyCreateApplePPQService(CFStringRef hostname
, CFDictionaryRef context
)
2578 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, CFSTR("PPQ"),
2579 &oidAppleCertExtAppleServerAuthenticationPPQProd
,
2580 &oidAppleCertExtAppleServerAuthenticationPPQTest
);
2583 /* should use verbatim copy, but since this is the deprecated way, don't care right now */
2584 static const UInt8 entrustSPKIL1C
[kSecPolicySHA256Size
] = {
2585 0x54, 0x5b, 0xf9, 0x35, 0xe9, 0xad, 0xa1, 0xda,
2586 0x11, 0x7e, 0xdc, 0x3c, 0x2a, 0xcb, 0xc5, 0x6f,
2587 0xc0, 0x28, 0x09, 0x6c, 0x0e, 0x24, 0xbe, 0x9b,
2588 0x38, 0x94, 0xbe, 0x52, 0x2d, 0x1b, 0x43, 0xde
2592 @function SecPolicyCreateApplePushServiceLegacy
2593 @abstract Ensure we're appropriately pinned to the Push service (via Entrust)
2595 SecPolicyRef
SecPolicyCreateApplePushServiceLegacy(CFStringRef hostname
)
2597 CFMutableDictionaryRef options
= NULL
;
2598 SecPolicyRef result
= NULL
;
2599 CFDataRef digest
= NULL
;
2601 digest
= CFDataCreateWithBytesNoCopy(kCFAllocatorDefault
, entrustSPKIL1C
, sizeof(entrustSPKIL1C
), kCFAllocatorNull
);
2602 require(digest
, errOut
);
2604 options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0, &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
2605 require(options
, errOut
);
2607 SecPolicyAddBasicX509Options(options
);
2609 CFDictionaryAddValue(options
, kSecPolicyCheckSSLHostname
, hostname
);
2611 CFDictionaryAddValue(options
, kSecPolicyCheckBlackListedLeaf
, kCFBooleanTrue
);
2612 CFDictionaryAddValue(options
, kSecPolicyCheckGrayListedLeaf
, kCFBooleanTrue
);
2614 CFDictionaryAddValue(options
, kSecPolicyCheckIntermediateSPKISHA256
, digest
);
2616 add_eku(options
, &oidExtendedKeyUsageServerAuth
);
2618 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kCFBooleanFalse
);
2620 result
= SecPolicyCreate(kSecPolicyOIDSSLServer
, options
);
2621 require(result
, errOut
);
2624 CFReleaseSafe(digest
);
2625 CFReleaseSafe(options
);
2630 @function SecPolicyCreateAppleMMCSService
2631 @abstract Ensure we're appropriately pinned to the IDS service (SSL + Apple restrictions)
2633 SecPolicyRef
SecPolicyCreateAppleMMCSService(CFStringRef hostname
, CFDictionaryRef __unused context
)
2635 return SecPolicyCreateSSL(true, hostname
);
2639 @function SecPolicyCreateAppleSSLService
2640 @abstract Ensure we're appropriately pinned to an Apple server (SSL + Apple restrictions)
2642 SecPolicyRef
SecPolicyCreateAppleSSLService(CFStringRef hostname
)
2644 // SSL server, pinned to an Apple intermediate
2645 SecPolicyRef policy
= SecPolicyCreateSSL(true, hostname
);
2646 CFMutableDictionaryRef options
= NULL
;
2647 require(policy
, errOut
);
2649 // change options for SSL policy evaluation
2650 require((options
=(CFMutableDictionaryRef
)policy
->_options
) != NULL
, errOut
);
2652 // Apple CA anchored
2653 require(SecPolicyAddAppleAnchorOptions(options
), errOut
);
2655 // Check leaf for Apple Server Authentication marker oid (1.2.840.113635.100.6.27.1)
2656 add_leaf_marker(options
, &oidAppleCertExtAppleServerAuthentication
);
2658 // Check intermediate for Apple Server Authentication intermediate marker (1.2.840.113635.100.6.2.12)
2659 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleServerAuthentication
);
2661 // Ensure that revocation is checked (OCSP only)
2662 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kCFBooleanFalse
);
2667 CFReleaseSafe(options
);
2668 CFReleaseSafe(policy
);
2673 @function SecPolicyCreateApplePPQSigning
2674 @abstract Check for intermediate certificate 'Apple System Integration 2 Certification Authority' by name,
2676 Leaf cert must have Digital Signature usage.
2677 Leaf cert must have Apple PPQ Signing marker OID (1.2.840.113635.100.6.38.2).
2678 Intermediate must have marker OID (1.2.840.113635.100.6.2.10).
2680 SecPolicyRef
SecPolicyCreateApplePPQSigning(void)
2682 SecPolicyRef result
= NULL
;
2683 CFMutableDictionaryRef options
= NULL
;
2684 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2685 &kCFTypeDictionaryKeyCallBacks
,
2686 &kCFTypeDictionaryValueCallBacks
), errOut
);
2687 SecPolicyAddBasicCertOptions(options
);
2689 SecPolicyAddAppleAnchorOptions(options
);
2690 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2692 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2693 CFSTR("Apple System Integration 2 Certification Authority"));
2695 // Check that leaf has extension with "Apple PPQ Signing" prod oid (1.2.840.113635.100.6.38.2)
2696 add_leaf_marker(options
, &oidAppleCertExtApplePPQSigningProd
);
2698 // Check that intermediate has extension (1.2.840.113635.100.6.2.10)
2699 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleSystemIntg2
);
2701 add_ku(options
, kSecKeyUsageDigitalSignature
);
2703 require(result
= SecPolicyCreate(kSecPolicyApplePPQSigning
, options
), errOut
);
2706 CFReleaseSafe(options
);
2711 @function SecPolicyCreateTestApplePPQSigning
2712 @abstract Check for intermediate certificate 'Apple System Integration 2 Certification Authority' by name,
2714 Leaf cert must have Digital Signature usage.
2715 Leaf cert must have Apple PPQ Signing Test marker OID (1.2.840.113635.100.6.38.1).
2716 Intermediate must have marker OID (1.2.840.113635.100.6.2.10).
2718 SecPolicyRef
SecPolicyCreateTestApplePPQSigning(void)
2720 SecPolicyRef result
= NULL
;
2721 CFMutableDictionaryRef options
= NULL
;
2722 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2723 &kCFTypeDictionaryKeyCallBacks
,
2724 &kCFTypeDictionaryValueCallBacks
), errOut
);
2725 SecPolicyAddBasicCertOptions(options
);
2727 SecPolicyAddAppleAnchorOptions(options
);
2728 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2730 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2731 CFSTR("Apple System Integration 2 Certification Authority"));
2733 // Check that leaf has extension with "Apple PPQ Signing" test oid (1.2.840.113635.100.6.38.1)
2734 add_leaf_marker(options
, &oidAppleCertExtApplePPQSigningTest
);
2736 // Check that intermediate has extension (1.2.840.113635.100.6.2.10)
2737 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleSystemIntg2
);
2739 add_ku(options
, kSecKeyUsageDigitalSignature
);
2741 require(result
= SecPolicyCreate(kSecPolicyAppleTestPPQSigning
, options
), errOut
);
2744 CFReleaseSafe(options
);
2748 @function SecPolicyCreateAppleTimeStamping
2749 @abstract Check for RFC3161 timestamping EKU.
2751 SecPolicyRef
SecPolicyCreateAppleTimeStamping(void)
2753 SecPolicyRef result
= NULL
;
2754 CFMutableDictionaryRef options
= NULL
;
2755 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2756 &kCFTypeDictionaryKeyCallBacks
,
2757 &kCFTypeDictionaryValueCallBacks
), errOut
);
2759 SecPolicyAddBasicX509Options(options
);
2761 /* Require id-kp-timeStamping extendedKeyUsage to be present. */
2762 add_eku(options
, &oidExtendedKeyUsageTimeStamping
);
2764 require(result
= SecPolicyCreate(kSecPolicyOIDAppleTimeStamping
, options
), errOut
);
2767 CFReleaseSafe(options
);
2772 @function SecPolicyCreateAppleATVAppSigning
2773 @abstract Check for intermediate certificate 'Apple Worldwide Developer Relations Certification Authority' by name,
2775 Leaf cert must have Digital Signature usage.
2776 Leaf cert must have Apple ATV App Signing marker OID (1.2.840.113635.100.6.1.24).
2777 Leaf cert must have 'Apple TVOS Application Signing' common name.
2779 SecPolicyRef
SecPolicyCreateAppleATVAppSigning(void)
2781 SecPolicyRef result
= NULL
;
2782 CFMutableDictionaryRef options
= NULL
;
2783 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2784 &kCFTypeDictionaryKeyCallBacks
,
2785 &kCFTypeDictionaryValueCallBacks
), errOut
);
2786 SecPolicyAddBasicCertOptions(options
);
2788 require(SecPolicyAddAppleAnchorOptions(options
), errOut
);
2789 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2791 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2792 CFSTR("Apple Worldwide Developer Relations Certification Authority"));
2793 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
,
2794 CFSTR("Apple TVOS Application Signing"));
2796 // Check that leaf has extension with "Apple ATV App Signing" prod oid (1.2.840.113635.100.6.1.24)
2797 add_leaf_marker(options
, &oidAppleCertExtATVAppSigningProd
);
2799 add_ku(options
, kSecKeyUsageDigitalSignature
);
2801 require(result
= SecPolicyCreate(kSecPolicyAppleATVAppSigning
, options
), errOut
);
2804 CFReleaseSafe(options
);
2809 @function SecPolicyCreateTestAppleATVAppSigning
2810 @abstract Check for intermediate certificate 'Apple Worldwide Developer Relations Certification Authority' by name,
2812 Leaf cert must have Digital Signature usage.
2813 Leaf cert must have Apple ATV App Signing Test marker OID (1.2.840.113635.100.6.1.24.1).
2814 Leaf cert must have 'TEST Apple TVOS Application Signing TEST' common name.
2816 SecPolicyRef
SecPolicyCreateTestAppleATVAppSigning(void)
2818 SecPolicyRef result
= NULL
;
2819 CFMutableDictionaryRef options
= NULL
;
2820 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2821 &kCFTypeDictionaryKeyCallBacks
,
2822 &kCFTypeDictionaryValueCallBacks
), errOut
);
2823 SecPolicyAddBasicCertOptions(options
);
2825 require(SecPolicyAddAppleAnchorOptions(options
), errOut
);
2826 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2828 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2829 CFSTR("Apple Worldwide Developer Relations Certification Authority"));
2830 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
,
2831 CFSTR("TEST Apple TVOS Application Signing TEST"));
2833 // Check that leaf has extension with "Apple ATV App Signing" test oid (1.2.840.113635.100.6.1.24.1)
2834 add_leaf_marker(options
, &oidAppleCertExtATVAppSigningTest
);
2836 add_ku(options
, kSecKeyUsageDigitalSignature
);
2838 require(result
= SecPolicyCreate(kSecPolicyAppleTestATVAppSigning
, options
), errOut
);
2841 CFReleaseSafe(options
);
2846 @function SecPolicyCreateApplePayIssuerEncryption
2847 @abstract Check for intermediate certificate 'Apple Worldwide Developer Relations CA - G2' by name,
2848 and ECC apple anchor.
2849 Leaf cert must have Key Encipherment and Key Agreement usage.
2850 Leaf cert must have Apple Pay Issuer Encryption marker OID (1.2.840.113635.100.6.39).
2852 SecPolicyRef
SecPolicyCreateApplePayIssuerEncryption(void)
2854 SecPolicyRef result
= NULL
;
2855 CFMutableDictionaryRef options
= NULL
;
2856 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2857 &kCFTypeDictionaryKeyCallBacks
,
2858 &kCFTypeDictionaryValueCallBacks
), errOut
);
2859 SecPolicyAddBasicCertOptions(options
);
2861 require(SecPolicyAddAnchorSHA1Options(options
, kAppleRootCA_ECC_SHA1
), errOut
);
2862 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2864 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2865 CFSTR("Apple Worldwide Developer Relations CA - G2"));
2867 // Check that leaf has extension with "Apple Pay Issuer Encryption" oid (1.2.840.113635.100.6.39)
2868 add_leaf_marker(options
, &oidAppleCertExtCryptoServicesExtEncryption
);
2870 add_ku(options
, kSecKeyUsageKeyEncipherment
);
2872 require(result
= SecPolicyCreate(kSecPolicyApplePayIssuerEncryption
, options
), errOut
);
2875 CFReleaseSafe(options
);