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");
127 SEC_CONST_DECL (kSecPolicyAppleAnchorAllowTestRootsOnProduction
, "AnchorAppleTestRootsOnProduction");
129 /********************************************************
130 *********** Unverified Certificate Checks **************
131 ********************************************************/
132 /* Unverified Certificate Checks (any of the above) */
133 SEC_CONST_DECL (kSecPolicyCheckNonEmptySubject
, "NonEmptySubject");
134 SEC_CONST_DECL (kSecPolicyCheckIdLinkage
, "IdLinkage") /* (rfc5280 check) */
136 SEC_CONST_DECL (kSecPolicyCheckValidityStarted
, "ValidStarted");
137 SEC_CONST_DECL (kSecPolicyCheckValidityExpired
, "ValidExpired");
139 SEC_CONST_DECL (kSecPolicyCheckValidIntermediates
, "ValidIntermediates");
140 SEC_CONST_DECL (kSecPolicyCheckValidLeaf
, "ValidLeaf");
141 SEC_CONST_DECL (kSecPolicyCheckValidRoot
, "ValidRoot");
142 SEC_CONST_DECL (kSecPolicyCheckWeakIntermediates
, "WeakIntermediates");
143 SEC_CONST_DECL (kSecPolicyCheckWeakLeaf
, "WeakLeaf");
144 SEC_CONST_DECL (kSecPolicyCheckWeakRoot
, "WeakRoot");
148 /********************************************************
149 **************** Verified Path Checks ******************
150 ********************************************************/
151 /* (rfc5280 check) Ideally we should dynamically track all the extensions
152 we processed for each certificate and fail this test if any critical
153 extensions remain. */
154 SEC_CONST_DECL (kSecPolicyCheckCriticalExtensions
, "CriticalExtensions");
156 /* Check that the certificate chain length matches the specificed CFNumberRef
158 SEC_CONST_DECL (kSecPolicyCheckChainLength
, "ChainLength");
160 /* (rfc5280 check) */
161 SEC_CONST_DECL (kSecPolicyCheckBasicCertificateProcessing
, "BasicCertificateProcessing");
163 /********************************************************
164 ******************* Feature toggles ********************
165 ********************************************************/
167 /* Check revocation if specified. */
168 SEC_CONST_DECL (kSecPolicyCheckExtendedValidation
, "ExtendedValidation");
169 SEC_CONST_DECL (kSecPolicyCheckRevocation
, "Revocation");
170 SEC_CONST_DECL (kSecPolicyCheckRevocationResponseRequired
, "RevocationResponseRequired");
172 /* Check Certificate Transparency if specified. */
173 SEC_CONST_DECL (kSecPolicyCheckCertificateTransparency
, "CertificateTransparency");
175 /* If present and true, we never go out to the network for anything
176 (OCSP, CRL or CA Issuer checking) but just used cached data instead. */
177 SEC_CONST_DECL (kSecPolicyCheckNoNetworkAccess
, "NoNetworkAccess");
179 /* Hack to quickly blacklist certain certs. */
180 SEC_CONST_DECL (kSecPolicyCheckBlackListedLeaf
, "BlackListedLeaf");
181 SEC_CONST_DECL (kSecPolicyCheckGrayListedLeaf
, "GrayListedLeaf");
182 SEC_CONST_DECL (kSecPolicyCheckGrayListedKey
, "GrayListedKey");
183 SEC_CONST_DECL (kSecPolicyCheckBlackListedKey
, "BlackListedKey");
185 SEC_CONST_DECL (kSecPolicyCheckLeafMarkerOid
, "CheckLeafMarkerOid");
186 SEC_CONST_DECL (kSecPolicyCheckIntermediateMarkerOid
, "CheckIntermediateMarkerOid");
188 /* Public policy names. */
189 SEC_CONST_DECL (kSecPolicyAppleX509Basic
, "1.2.840.113635.100.1.2");
190 SEC_CONST_DECL (kSecPolicyAppleSSL
, "1.2.840.113635.100.1.3");
191 SEC_CONST_DECL (kSecPolicyAppleSMIME
, "1.2.840.113635.100.1.8");
192 SEC_CONST_DECL (kSecPolicyAppleEAP
, "1.2.840.113635.100.1.9");
193 SEC_CONST_DECL (kSecPolicyAppleSWUpdateSigning
, "1.2.840.113635.100.1.10");
194 SEC_CONST_DECL (kSecPolicyAppleIPsec
, "1.2.840.113635.100.1.11");
195 SEC_CONST_DECL (kSecPolicyApplePKINITClient
, "1.2.840.113635.100.1.14");
196 SEC_CONST_DECL (kSecPolicyApplePKINITServer
, "1.2.840.113635.100.1.15");
197 SEC_CONST_DECL (kSecPolicyAppleCodeSigning
, "1.2.840.113635.100.1.16");
198 SEC_CONST_DECL (kSecPolicyApplePackageSigning
, "1.2.840.113635.100.1.17");
199 SEC_CONST_DECL (kSecPolicyAppleIDValidation
, "1.2.840.113635.100.1.18");
200 SEC_CONST_DECL (kSecPolicyMacAppStoreReceipt
, "1.2.840.113635.100.1.19");
201 SEC_CONST_DECL (kSecPolicyAppleTimeStamping
, "1.2.840.113635.100.1.20");
202 SEC_CONST_DECL (kSecPolicyAppleRevocation
, "1.2.840.113635.100.1.21");
203 SEC_CONST_DECL (kSecPolicyApplePassbookSigning
, "1.2.840.113635.100.1.22");
204 SEC_CONST_DECL (kSecPolicyAppleMobileStore
, "1.2.840.113635.100.1.23");
205 SEC_CONST_DECL (kSecPolicyAppleEscrowService
, "1.2.840.113635.100.1.24");
206 SEC_CONST_DECL (kSecPolicyAppleProfileSigner
, "1.2.840.113635.100.1.25");
207 SEC_CONST_DECL (kSecPolicyAppleQAProfileSigner
, "1.2.840.113635.100.1.26");
208 SEC_CONST_DECL (kSecPolicyAppleTestMobileStore
, "1.2.840.113635.100.1.27");
209 SEC_CONST_DECL (kSecPolicyAppleOTAPKISigner
, "1.2.840.113635.100.1.28");
210 SEC_CONST_DECL (kSecPolicyAppleTestOTAPKISigner
, "1.2.840.113635.100.1.29");
211 /* FIXME: this policy name should be deprecated and replaced with "kSecPolicyAppleIDValidationRecordSigning" */
212 SEC_CONST_DECL (kSecPolicyAppleIDValidationRecordSigningPolicy
, "1.2.840.113625.100.1.30");
213 SEC_CONST_DECL (kSecPolicyAppleSMPEncryption
, "1.2.840.113625.100.1.31");
214 SEC_CONST_DECL (kSecPolicyAppleTestSMPEncryption
, "1.2.840.113625.100.1.32");
215 SEC_CONST_DECL (kSecPolicyAppleServerAuthentication
, "1.2.840.113635.100.1.33");
216 SEC_CONST_DECL (kSecPolicyApplePCSEscrowService
, "1.2.840.113635.100.1.34");
217 SEC_CONST_DECL (kSecPolicyApplePPQSigning
, "1.2.840.113625.100.1.35");
218 SEC_CONST_DECL (kSecPolicyAppleTestPPQSigning
, "1.2.840.113625.100.1.36");
219 SEC_CONST_DECL (kSecPolicyAppleATVAppSigning
, "1.2.840.113625.100.1.37");
220 SEC_CONST_DECL (kSecPolicyAppleTestATVAppSigning
, "1.2.840.113625.100.1.38");
221 SEC_CONST_DECL (kSecPolicyApplePayIssuerEncryption
, "1.2.840.113625.100.1.39");
222 SEC_CONST_DECL (kSecPolicyAppleOSXProvisioningProfileSigning
, "1.2.840.113625.100.1.40");
223 SEC_CONST_DECL (kSecPolicyAppleATVVPNProfileSigning
, "1.2.840.113625.100.1.41");
224 SEC_CONST_DECL (kSecPolicyAppleAST2DiagnosticsServerAuth
, "1.2.840.113625.100.1.42");
226 SEC_CONST_DECL (kSecPolicyOid
, "SecPolicyOid");
227 SEC_CONST_DECL (kSecPolicyName
, "SecPolicyName");
228 SEC_CONST_DECL (kSecPolicyClient
, "SecPolicyClient");
229 SEC_CONST_DECL (kSecPolicyRevocationFlags
, "SecPolicyRevocationFlags");
230 SEC_CONST_DECL (kSecPolicyTeamIdentifier
, "SecPolicyTeamIdentifier");
232 /* Private policy names */
233 static CFStringRef kSecPolicyOIDBasicX509
= CFSTR("basicX509");
234 static CFStringRef kSecPolicyOIDSSLServer
= CFSTR("sslServer");
235 static CFStringRef kSecPolicyOIDSSLClient
= CFSTR("sslClient");
236 static CFStringRef kSecPolicyOIDiPhoneActivation
= CFSTR("iPhoneActivation");
237 static CFStringRef kSecPolicyOIDiPhoneDeviceCertificate
=
238 CFSTR("iPhoneDeviceCertificate");
239 static CFStringRef kSecPolicyOIDFactoryDeviceCertificate
=
240 CFSTR("FactoryDeviceCertificate");
241 static CFStringRef kSecPolicyOIDiAP
= CFSTR("iAP");
242 static CFStringRef kSecPolicyOIDiTunesStoreURLBag
= CFSTR("iTunesStoreURLBag");
243 static CFStringRef kSecPolicyOIDEAPServer
= CFSTR("eapServer");
244 static CFStringRef kSecPolicyOIDEAPClient
= CFSTR("eapClient");
245 static CFStringRef kSecPolicyOIDIPSecServer
= CFSTR("ipsecServer");
246 static CFStringRef kSecPolicyOIDIPSecClient
= CFSTR("ipsecClient");
247 static CFStringRef kSecPolicyOIDiPhoneApplicationSigning
=
248 CFSTR("iPhoneApplicationSigning");
249 static CFStringRef kSecPolicyOIDiPhoneProfileApplicationSigning
=
250 CFSTR("iPhoneProfileApplicationSigning");
251 static CFStringRef kSecPolicyOIDiPhoneProvisioningProfileSigning
=
252 CFSTR("iPhoneProvisioningProfileSigning");
253 static CFStringRef kSecPolicyOIDAppleSWUpdateSigning
= CFSTR("AppleSWUpdateSigning");
254 static CFStringRef kSecPolicyOIDAppleTVOSApplicationSigning
=
255 CFSTR("AppleTVApplicationSigning");
256 static CFStringRef kSecPolicyOIDRevocation
= CFSTR("revocation");
257 static CFStringRef kSecPolicyOIDOCSPSigner
= CFSTR("OCSPSigner");
258 static CFStringRef kSecPolicyOIDSMIME
= CFSTR("SMIME");
259 static CFStringRef kSecPolicyOIDCodeSigning
= CFSTR("CodeSigning");
260 static CFStringRef kSecPolicyOIDPackageSigning
= CFSTR("PackageSigning");
261 static CFStringRef kSecPolicyOIDLockdownPairing
= CFSTR("LockdownPairing");
262 static CFStringRef kSecPolicyOIDURLBag
= CFSTR("URLBag");
263 static CFStringRef kSecPolicyOIDOTATasking
= CFSTR("OTATasking");
264 static CFStringRef kSecPolicyOIDMobileAsset
= CFSTR("MobileAsset");
265 static CFStringRef kSecPolicyOIDAppleIDAuthority
= CFSTR("AppleIDAuthority");
266 static CFStringRef kSecPolicyOIDMacAppStoreReceipt
= CFSTR("MacAppStoreReceipt");
267 static CFStringRef kSecPolicyOIDAppleTimeStamping
= CFSTR("AppleTimeStamping");
268 static CFStringRef kSecPolicyOIDApplePassbook
= CFSTR("ApplePassbook");
269 static CFStringRef kSecPolicyOIDAppleMobileStore
= CFSTR("AppleMobileStore");
270 static CFStringRef kSecPolicyOIDAppleTestMobileStore
= CFSTR("AppleTestMobileStore");
271 static CFStringRef kSecPolicyOIDAppleEscrowService
= CFSTR("AppleEscrowService");
272 static CFStringRef kSecPolicyOIDApplePCSEscrowService
= CFSTR("ApplePCSEscrowService");
273 static CFStringRef kSecPolicyOIDAppleProfileSigner
= CFSTR("AppleProfileSigner");
274 static CFStringRef kSecPolicyOIDAppleQAProfileSigner
= CFSTR("AppleQAProfileSigner");
275 static CFStringRef kSecPolicyOIDAppleOTAPKIAssetSigner
= CFSTR("AppleOTAPKIAssetSigner");
276 static CFStringRef kSecPolicyOIDAppleTestOTAPKIAssetSigner
= CFSTR("AppleTestOTAPKIAssetSigner");
277 static CFStringRef kSecPolicyOIDAppleIDValidationRecordSigningPolicy
= CFSTR("AppleIDValidationRecordSigningPolicy");
278 #if TARGET_OS_EMBEDDED
279 static CFStringRef kSecPolicyOIDAppleATVAppSigning
= CFSTR("AppleATVAppSigning");
280 static CFStringRef kSecPolicyOIDAppleTestATVAppSigning
= CFSTR("AppleTestATVAppSigning");
282 static CFStringRef kSecPolicyOIDApplePayIssuerEncryption
= CFSTR("ApplePayIssuerEncryption");
283 static CFStringRef kSecPolicyOIDAppleOSXProvisioningProfileSigning
= CFSTR("AppleOSXProvisioningProfileSigning");
284 static CFStringRef kSecPolicyOIDAppleATVVPNProfileSigning
= CFSTR("AppleATVVPNProfileSigning");
285 static CFStringRef kSecPolicyOIDAppleAST2Service
= CFSTR("AST2Service");
286 static CFStringRef kSecPolicyOIDAppleHomeKitServerAuth
= CFSTR("HomeKitServerAuth");
288 /* Policies will now change to multiple categories of checks.
290 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.
291 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.
293 kSecPolicySLCheck Static Subscriber Certificate Checks
294 kSecPolicySICheck Static Subsidiary CA Checks
295 kSecPolicySACheck Static Anchor Checks
297 kSecPolicyDLCheck Dynamic Subscriber Certificate Checks
298 kSecPolicyDICheck Dynamic Subsidiary CA Checks
299 kSecPolicyDACheck Dynamic Anchor Checks ? not yet needed other than to
300 possibly exclude in a exception template (but those should still be per
301 certificate --- i.o.w. exceptions (or a database backed multiple role/user
302 trust store of some sort) and policies are 2 different things and this
303 text is about policies.
305 All static checks are only allowed to consider the certificate in isolation,
306 just given the position in the chain or the cert (leaf, intermidate, root).
307 dynamic checks can make determinations about the chain as a whole.
309 Static Subscriber Certificate Checks will be done up front before the
310 chainbuilder is even instantiated. If they fail and details aren't required
311 by the client (if no exceptions were present for this certificate) we could
312 short circuit fail the evaluation.
313 IDEA: These checks can dynamically add new checks...[needs work]
314 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
315 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
316 equivalent subtree from that level down. So SSL has EV as a subpolicy, but
317 EV dynamically enables the ocsp or crl or dcrl or any combination thereof subpolicies.
319 Static Subsidiary CA Checks will be used by the chain-builder to choose the
320 best parents to evaluate first. This feature is currently already implemented
321 but with a hardcoded is_valid(verifyTime) check. Instead we will evaluate all
322 Static Subsidiary CA Checks. The results of these checks for purposes of
323 generating details could be cached in the SecCertificatePathRefs themselves, or we can short circuit fail and recalc details on demand later.
325 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.
327 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.
329 Dynamic Subsidiary CA Checks might not be needed to have custom
330 implementations, since they are all done as part of the rfc5280 checks now.
331 This assumes that checks like issuer common name includes 'foo' are
332 implmented as Static Subscriber Certificate Checks instead.
334 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.
337 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.
339 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.
341 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.
343 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.
345 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.
347 We need to remember the best successful chain we find, where best is defined by: satisfies as many optional policies as possible.
349 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.
351 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.
353 Example sectrust operation in psuedocode:
357 new builder(verifyTime, certificates, anchors, anchorsOnly, policies);
358 chain = builder.subscriber_only_chain;
359 foreach (policy in policies{kSecPolicySLCheck}) {
360 foreach(check in policy)
361 SecPolicyRunCheck(builder, chain, check, details);
362 foreach (subpolicy in policy) {
363 check_policy(builder, chain, subpolicy, details{subpolicy.name})
365 propagate_subpolicy_results(builder, chain, details);
367 while (chain = builder.next) {
368 for (depth = 0; p_d = policies.at_depth(depth),
369 d_p_d = dynamic_policies.at_depth(depth), p_d || d_p_d; ++depth)
371 // Modify SecPathBuilderIsPartial() to
372 // run builder_check(buildier, policies, kSecPolicySICheck) instead
373 // of SecCertificateIsValid. Also rename considerExpired to
374 // considerSIFailures.
375 foreach (policy in p_d) {
376 check_policy(builder, chain, policy, kSecPolicySICheck, depth);
378 /// Recalculate since the static checks might have added new dynamic
380 d_p_d = dynamic_policies.at_depth(depth);
381 foreach (policy in d_p_d) {
382 check_policy(builder, chain, policy, kSecPolicySICheck, depth);
384 if (chain.is_anchored) {
385 foreach (policy in p_d) {
386 check_policy(builder, chain, policy, kSecPolicySACheck, depth);
388 foreach (policy in d_p_d) {
389 check_policy(builder, chain, policy, kSecPolicySACheck, depth);
391 foreach (policy in p_d) {
392 check_policy(builder, chain, policy, kSecPolicyDACheck, depth);
394 foreach (policy in d_p_d) {
395 check_policy(builder, chain, policy, kSecPolicyDACheck, depth);
398 foreach (policy in policies) {
399 check_policy(builder, chain, policy, kSecPolicySACheck, depth);
400 check_policy(builder, chain, policy, kSecPolicyDACheck, depth);
402 foreach (policy in policies{kSecPolicySDCheck}) {
407 check_policy(builder, chain, policy, check_class, details, depth) {
409 foreach(check in policy{check_class}) {
410 SecPolicyRunCheck(builder, chain, check, details);
414 foreach (subpolicy in policy) {
415 if (!check_policy(builder, chain, subpolicy, check_class,
416 details{subpolicy.name}) && subpolicy.is_required, depth)
420 propagate_subpolicy_results(builder, chain, details);
427 #define kSecPolicySHA1Size 20
428 #define kSecPolicySHA256Size 32
429 const UInt8 kAppleCASHA1
[kSecPolicySHA1Size
] = {
430 0x61, 0x1E, 0x5B, 0x66, 0x2C, 0x59, 0x3A, 0x08, 0xFF, 0x58,
431 0xD1, 0x4A, 0xE2, 0x24, 0x52, 0xD1, 0x98, 0xDF, 0x6C, 0x60
434 __unused
static const UInt8 kAppleTESTCASHA1
[kSecPolicySHA1Size
] = {
435 0xbc, 0x30, 0x55, 0xc8, 0xc8, 0xd3, 0x48, 0x3f, 0xf4, 0x8d,
436 0xfe, 0x3d, 0x51, 0x75, 0x31, 0xc9, 0xf4, 0xd7, 0x4a, 0xf7
439 static const UInt8 kITMSCASHA1
[kSecPolicySHA1Size
] = {
440 0x1D, 0x33, 0x42, 0x46, 0x8B, 0x10, 0xBD, 0xE6, 0x45, 0xCE,
441 0x44, 0x6E, 0xBB, 0xE8, 0xF5, 0x03, 0x5D, 0xF8, 0x32, 0x22
444 static const UInt8 kFactoryDeviceCASHA1
[kSecPolicySHA1Size
] = {
445 0xef, 0x68, 0x73, 0x17, 0xa4, 0xf8, 0xf9, 0x4b, 0x7b, 0x21,
446 0xe2, 0x2f, 0x09, 0x8f, 0xfd, 0x6a, 0xae, 0xc0, 0x0d, 0x63
449 static const UInt8 kApplePKISettingsAuthority
[kSecPolicySHA1Size
] = {
450 0x1D, 0x0C, 0xBA, 0xAD, 0x17, 0xFD, 0x7E, 0x9E, 0x9F, 0xF1,
451 0xC9, 0xA2, 0x66, 0x79, 0x60, 0x00, 0x8B, 0xAE, 0x70, 0xB8
454 static const UInt8 kAppleTestPKISettingsAuthority
[kSecPolicySHA1Size
] = {
455 0xDB, 0xBA, 0x25, 0x0B, 0xD8, 0x62, 0x71, 0x87, 0x54, 0x7E,
456 0xD7, 0xEF, 0x11, 0x94, 0x7E, 0x82, 0xE6, 0xD8, 0x1C, 0x9A
459 static const UInt8 kTestAppleRootCA_ECC_SHA1
[kSecPolicySHA1Size
] = {
460 0x62, 0x0A, 0xED, 0x83, 0xD2, 0x97, 0x4A, 0x77, 0x56, 0x33,
461 0x83, 0xBE, 0xDB, 0xF9, 0xA1, 0xBD, 0x5F, 0xFE, 0x55, 0x7B
464 static const UInt8 kAppleRootCA_ECC_SHA1
[kSecPolicySHA1Size
] = {
465 0xB5, 0x2C, 0xB0, 0x2F, 0xD5, 0x67, 0xE0, 0x35, 0x9F, 0xE8,
466 0xFA, 0x4D, 0x4C, 0x41, 0x03, 0x79, 0x70, 0xFE, 0x01, 0xB0
471 /********************************************************
472 ****************** SecPolicy object ********************
473 ********************************************************/
475 static void SecPolicyDestroy(CFTypeRef cf
) {
476 SecPolicyRef policy
= (SecPolicyRef
) cf
;
477 CFRelease(policy
->_oid
);
478 CFRelease(policy
->_options
);
481 static Boolean
SecPolicyCompare(CFTypeRef cf1
, CFTypeRef cf2
) {
482 SecPolicyRef policy1
= (SecPolicyRef
) cf1
;
483 SecPolicyRef policy2
= (SecPolicyRef
) cf2
;
484 return CFEqual(policy1
->_oid
, policy2
->_oid
) &&
485 CFEqual(policy1
->_options
, policy2
->_options
);
488 static CFHashCode
SecPolicyHash(CFTypeRef cf
) {
489 SecPolicyRef policy
= (SecPolicyRef
) cf
;
491 return CFHash(policy
->_oid
) + CFHash(policy
->_options
);
494 static CFStringRef
SecPolicyCopyFormatDescription(CFTypeRef cf
, CFDictionaryRef formatOptions
) {
495 SecPolicyRef policy
= (SecPolicyRef
) cf
;
496 CFMutableStringRef desc
= CFStringCreateMutable(kCFAllocatorDefault
, 0);
497 CFStringRef typeStr
= CFCopyTypeIDDescription(CFGetTypeID(cf
));
498 CFStringAppendFormat(desc
, NULL
,
499 CFSTR("<%@: oid: %@ options %@"), typeStr
,
500 policy
->_oid
, policy
->_options
);
502 CFStringAppend(desc
, CFSTR(" >"));
507 /* SecPolicy API functions. */
508 CFGiblisWithHashFor(SecPolicy
);
510 /* AUDIT[securityd](done):
511 oid (ok) is a caller provided string, only its cf type has been checked.
512 options is a caller provided dictionary, only its cf type has been checked.
514 SecPolicyRef
SecPolicyCreate(CFStringRef oid
, CFDictionaryRef options
) {
515 SecPolicyRef result
= NULL
;
517 require(oid
, errOut
);
518 require(options
, errOut
);
520 (SecPolicyRef
)_CFRuntimeCreateInstance(kCFAllocatorDefault
,
521 SecPolicyGetTypeID(),
522 sizeof(struct __SecPolicy
) - sizeof(CFRuntimeBase
), 0), errOut
);
527 result
->_options
= options
;
533 SecPolicyRef
SecPolicyCreateWithProperties(CFTypeRef policyIdentifier
,
534 CFDictionaryRef properties
) {
535 // Creates a policy reference for a given policy object identifier.
536 // If policy-specific parameters can be supplied (e.g. hostname),
537 // attempt to obtain from input properties dictionary.
538 // Returns NULL if the given identifier is unsupported.
540 SecPolicyRef policy
= NULL
;
541 CFStringRef name
= NULL
;
542 CFStringRef teamID
= NULL
;
543 Boolean client
= false;
544 require(policyIdentifier
&& (CFStringGetTypeID() == CFGetTypeID(policyIdentifier
)), errOut
);
547 name
= CFDictionaryGetValue(properties
, kSecPolicyName
);
548 teamID
= CFDictionaryGetValue(properties
, kSecPolicyTeamIdentifier
);
550 CFBooleanRef dictionaryClientValue
;
551 client
= (CFDictionaryGetValueIfPresent(properties
, kSecPolicyClient
, (const void **)&dictionaryClientValue
) &&
552 (dictionaryClientValue
!= NULL
) && CFEqual(kCFBooleanTrue
, dictionaryClientValue
));
555 if (CFEqual(policyIdentifier
, kSecPolicyAppleX509Basic
)) {
556 policy
= SecPolicyCreateBasicX509();
558 else if (CFEqual(policyIdentifier
, kSecPolicyAppleSSL
)) {
559 policy
= SecPolicyCreateSSL(!client
, name
);
561 else if (CFEqual(policyIdentifier
, kSecPolicyAppleEAP
)) {
562 CFArrayRef array
= NULL
;
564 array
= CFArrayCreate(kCFAllocatorDefault
, (const void **)&name
, 1, &kCFTypeArrayCallBacks
);
566 policy
= SecPolicyCreateEAP(!client
, array
);
567 CFReleaseSafe(array
);
569 else if (CFEqual(policyIdentifier
, kSecPolicyApplePackageSigning
)) {
570 policy
= SecPolicyCreateApplePackageSigning();
572 else if (CFEqual(policyIdentifier
, kSecPolicyAppleSWUpdateSigning
)) {
573 policy
= SecPolicyCreateAppleSWUpdateSigning();
575 else if (CFEqual(policyIdentifier
, kSecPolicyAppleIPsec
)) {
576 policy
= SecPolicyCreateIPSec(!client
, name
);
578 else if (CFEqual(policyIdentifier
, kSecPolicyAppleRevocation
)) {
579 policy
= SecPolicyCreateRevocation(kSecRevocationUseAnyAvailableMethod
);
581 else if (CFEqual(policyIdentifier
, kSecPolicyAppleSMIME
)) {
582 policy
= SecPolicyCreateSMIME(kSecSignSMIMEUsage
| kSecAnyEncryptSMIME
, name
);
584 else if (CFEqual(policyIdentifier
, kSecPolicyAppleCodeSigning
)) {
585 policy
= SecPolicyCreateCodeSigning();
587 else if (CFEqual(policyIdentifier
, kSecPolicyAppleTimeStamping
)) {
588 policy
= SecPolicyCreateAppleTimeStamping();
590 else if (CFEqual(policyIdentifier
, kSecPolicyMacAppStoreReceipt
)) {
591 policy
= SecPolicyCreateMacAppStoreReceipt();
593 else if (CFEqual(policyIdentifier
, kSecPolicyAppleIDValidation
)) {
594 policy
= SecPolicyCreateAppleIDAuthorityPolicy();
596 else if (CFEqual(policyIdentifier
, kSecPolicyApplePassbookSigning
)) {
597 policy
= SecPolicyCreatePassbookCardSigner(name
, teamID
);
599 else if (CFEqual(policyIdentifier
, kSecPolicyAppleMobileStore
)) {
600 policy
= SecPolicyCreateMobileStoreSigner();
602 else if (CFEqual(policyIdentifier
, kSecPolicyAppleTestMobileStore
)) {
603 policy
= SecPolicyCreateTestMobileStoreSigner();
605 else if (CFEqual(policyIdentifier
, kSecPolicyAppleEscrowService
)) {
606 policy
= SecPolicyCreateEscrowServiceSigner();
608 else if (CFEqual(policyIdentifier
, kSecPolicyApplePCSEscrowService
)) {
609 policy
= SecPolicyCreatePCSEscrowServiceSigner();
611 else if (CFEqual(policyIdentifier
, kSecPolicyAppleProfileSigner
)) {
612 policy
= SecPolicyCreateConfigurationProfileSigner();
614 else if (CFEqual(policyIdentifier
, kSecPolicyAppleQAProfileSigner
)) {
615 policy
= SecPolicyCreateQAConfigurationProfileSigner();
617 else if (CFEqual(policyIdentifier
, kSecPolicyAppleServerAuthentication
)) {
618 policy
= SecPolicyCreateAppleSSLService(name
);
620 #if TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR
621 else if (CFEqual(policyIdentifier
, kSecPolicyAppleOTAPKISigner
)) {
622 policy
= SecPolicyCreateOTAPKISigner();
624 else if (CFEqual(policyIdentifier
, kSecPolicyAppleTestOTAPKISigner
)) {
625 policy
= SecPolicyCreateTestOTAPKISigner();
627 else if (CFEqual(policyIdentifier
, kSecPolicyAppleIDValidationRecordSigningPolicy
)) {
628 policy
= SecPolicyCreateAppleIDValidationRecordSigningPolicy();
630 else if (CFEqual(policyIdentifier
, kSecPolicyAppleSMPEncryption
)) {
631 policy
= SecPolicyCreateAppleSMPEncryption();
633 else if (CFEqual(policyIdentifier
, kSecPolicyAppleTestSMPEncryption
)) {
634 policy
= SecPolicyCreateTestAppleSMPEncryption();
636 else if (CFEqual(policyIdentifier
, kSecPolicyAppleATVAppSigning
)) {
637 policy
= SecPolicyCreateAppleATVAppSigning();
639 else if (CFEqual(policyIdentifier
, kSecPolicyAppleTestATVAppSigning
)) {
640 policy
= SecPolicyCreateTestAppleATVAppSigning();
643 else if (CFEqual(policyIdentifier
, kSecPolicyApplePPQSigning
)) {
644 policy
= SecPolicyCreateApplePPQSigning();
646 else if (CFEqual(policyIdentifier
, kSecPolicyAppleTestPPQSigning
)) {
647 policy
= SecPolicyCreateTestApplePPQSigning();
649 else if (CFEqual(policyIdentifier
, kSecPolicyApplePayIssuerEncryption
)) {
650 policy
= SecPolicyCreateApplePayIssuerEncryption();
652 else if (CFEqual(policyIdentifier
, kSecPolicyAppleATVVPNProfileSigning
)) {
653 policy
= SecPolicyCreateAppleATVVPNProfileSigning();
655 else if (CFEqual(policyIdentifier
, kSecPolicyAppleAST2DiagnosticsServerAuth
)) {
656 policy
= SecPolicyCreateAppleAST2Service(name
, NULL
);
659 secerror("ERROR: policy \"%@\" is unsupported", policyIdentifier
);
666 CFDictionaryRef
SecPolicyCopyProperties(SecPolicyRef policyRef
) {
667 // Builds and returns a dictionary which the caller must release.
669 #pragma clang diagnostic push
670 #pragma clang diagnostic ignored "-Wnonnull"
671 // After introducing nullability annotations, policyRef is supposed to be nonnull, suppress the warning
672 if (!policyRef
) return NULL
;
673 #pragma clang diagnostic pop
674 CFMutableDictionaryRef properties
= CFDictionaryCreateMutable(NULL
, 0,
675 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
676 #pragma clang diagnostic push
677 #pragma clang diagnostic ignored "-Wnonnull"
678 // 'properties' is nonnull in reality suppress the warning
679 if (!properties
) return NULL
;
680 #pragma clang diagnostic pop
681 CFStringRef oid
= (CFStringRef
) CFRetain(policyRef
->_oid
);
682 CFTypeRef nameKey
= NULL
;
684 // Convert private to public OID if we have one
685 CFStringRef outOid
= oid
;
686 if (CFEqual(oid
, kSecPolicyOIDBasicX509
)) {
687 outOid
= kSecPolicyAppleX509Basic
;
689 else if (CFEqual(oid
, kSecPolicyOIDSSLServer
) ||
690 CFEqual(oid
, kSecPolicyOIDSSLClient
)) {
691 outOid
= kSecPolicyAppleSSL
;
692 nameKey
= kSecPolicyCheckSSLHostname
;
694 else if (CFEqual(oid
, kSecPolicyOIDEAPServer
) ||
695 CFEqual(oid
, kSecPolicyOIDEAPClient
)) {
696 outOid
= kSecPolicyAppleEAP
;
697 nameKey
= kSecPolicyCheckEAPTrustedServerNames
;
699 else if (CFEqual(oid
, kSecPolicyOIDIPSecServer
) ||
700 CFEqual(oid
, kSecPolicyOIDIPSecClient
)) {
701 outOid
= kSecPolicyAppleIPsec
;
702 nameKey
= kSecPolicyCheckSSLHostname
;
704 else if (CFEqual(oid
, kSecPolicyOIDRevocation
)) {
705 outOid
= kSecPolicyAppleRevocation
;
707 else if (CFEqual(oid
, kSecPolicyOIDSMIME
)) {
708 outOid
= kSecPolicyAppleSMIME
;
709 nameKey
= kSecPolicyCheckEmail
;
711 else if (CFEqual(oid
, kSecPolicyOIDCodeSigning
)) {
712 outOid
= kSecPolicyAppleCodeSigning
;
714 else if (CFEqual(oid
, kSecPolicyOIDAppleIDAuthority
)) {
715 outOid
= kSecPolicyAppleIDValidation
;
717 else if (CFEqual(oid
, kSecPolicyOIDApplePassbook
)) {
718 outOid
= kSecPolicyApplePassbookSigning
;
720 else if (CFEqual(oid
, kSecPolicyOIDAppleMobileStore
)) {
721 outOid
= kSecPolicyAppleMobileStore
;
723 else if (CFEqual(oid
, kSecPolicyOIDAppleTestMobileStore
)) {
724 outOid
= kSecPolicyAppleTestMobileStore
;
726 else if (CFEqual(oid
, kSecPolicyOIDAppleEscrowService
)) {
727 outOid
= kSecPolicyAppleEscrowService
;
729 else if (CFEqual(oid
, kSecPolicyOIDApplePCSEscrowService
)) {
730 outOid
= kSecPolicyApplePCSEscrowService
;
732 else if (CFEqual(oid
, kSecPolicyOIDAppleProfileSigner
)) {
733 outOid
= kSecPolicyAppleProfileSigner
;
735 else if (CFEqual(oid
, kSecPolicyOIDAppleQAProfileSigner
)) {
736 outOid
= kSecPolicyAppleQAProfileSigner
;
738 #if TARGET_OS_EMBEDDED
739 else if (CFEqual(oid
, kSecPolicyOIDAppleOTAPKIAssetSigner
)) {
740 outOid
= kSecPolicyAppleOTAPKISigner
;
742 else if (CFEqual(oid
, kSecPolicyOIDAppleTestOTAPKIAssetSigner
)) {
743 outOid
= kSecPolicyAppleTestOTAPKISigner
;
745 else if (CFEqual(oid
, kSecPolicyOIDAppleIDValidationRecordSigningPolicy
)) {
746 outOid
= kSecPolicyAppleIDValidationRecordSigningPolicy
;
748 else if (CFEqual(oid
, kSecPolicyOIDAppleATVAppSigning
)) {
749 outOid
= kSecPolicyAppleATVAppSigning
;
751 else if (CFEqual(oid
, kSecPolicyOIDAppleTestATVAppSigning
)) {
752 outOid
= kSecPolicyAppleTestATVAppSigning
;
755 else if (CFEqual(oid
, kSecPolicyOIDApplePayIssuerEncryption
)) {
756 outOid
= kSecPolicyApplePayIssuerEncryption
;
758 else if (CFEqual(oid
, kSecPolicyOIDAppleOSXProvisioningProfileSigning
)) {
759 outOid
= kSecPolicyAppleOSXProvisioningProfileSigning
;
761 else if (CFEqual(oid
, kSecPolicyOIDAppleATVVPNProfileSigning
)) {
762 outOid
= kSecPolicyAppleATVVPNProfileSigning
;
764 else if (CFEqual(oid
, kSecPolicyOIDAppleAST2Service
)) {
765 outOid
= kSecPolicyAppleAST2DiagnosticsServerAuth
;
769 CFDictionarySetValue(properties
, (const void *)kSecPolicyOid
,
770 (const void *)outOid
);
772 // Set kSecPolicyName if we have one
773 if (nameKey
&& policyRef
->_options
) {
774 CFTypeRef name
= (CFTypeRef
) CFDictionaryGetValue(policyRef
->_options
,
777 CFDictionarySetValue(properties
, (const void *)kSecPolicyName
,
782 // Set kSecPolicyClient
783 if (CFEqual(oid
, kSecPolicyOIDSSLClient
) ||
784 CFEqual(oid
, kSecPolicyOIDIPSecClient
) ||
785 CFEqual(oid
, kSecPolicyOIDEAPClient
)) {
786 CFDictionarySetValue(properties
, (const void *)kSecPolicyClient
,
787 (const void *)kCFBooleanTrue
);
794 static void SecPolicySetOid(SecPolicyRef policy
, CFStringRef oid
) {
795 if (!policy
|| !oid
) return;
796 CFStringRef temp
= policy
->_oid
;
802 CFStringRef
SecPolicyGetOidString(SecPolicyRef policy
) {
806 CFDictionaryRef
SecPolicyGetOptions(SecPolicyRef policy
) {
807 return policy
->_options
;
810 void SecPolicySetOptionsValue(SecPolicyRef policy
, CFStringRef key
, CFTypeRef value
) {
811 if (!policy
|| !key
) return;
812 CFMutableDictionaryRef options
= (CFMutableDictionaryRef
) policy
->_options
;
814 options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
815 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
816 if (!options
) return;
817 policy
->_options
= options
;
819 CFDictionarySetValue(options
, key
, value
);
823 // this is declared as NA for iPhone in SecPolicy.h, so declare here
824 OSStatus
SecPolicySetProperties(SecPolicyRef policyRef
, CFDictionaryRef properties
);
827 OSStatus
SecPolicySetProperties(SecPolicyRef policyRef
, CFDictionaryRef properties
) {
828 // Set policy options based on the provided dictionary keys.
830 if (!(policyRef
&& properties
&& (CFDictionaryGetTypeID() == CFGetTypeID(properties
)))) {
833 CFStringRef oid
= (CFStringRef
) CFRetain(policyRef
->_oid
);
834 OSStatus result
= errSecSuccess
;
837 CFTypeRef name
= NULL
;
838 if (CFDictionaryGetValueIfPresent(properties
, (const void *)kSecPolicyName
,
839 (const void **)&name
) && name
) {
840 CFTypeID typeID
= CFGetTypeID(name
);
841 if (CFEqual(oid
, kSecPolicyOIDSSLServer
) ||
842 CFEqual(oid
, kSecPolicyOIDSSLClient
) ||
843 CFEqual(oid
, kSecPolicyOIDIPSecServer
) ||
844 CFEqual(oid
, kSecPolicyOIDIPSecClient
)) {
845 if (CFStringGetTypeID() == typeID
) {
846 SecPolicySetOptionsValue(policyRef
, kSecPolicyCheckSSLHostname
, name
);
848 else result
= errSecParam
;
850 else if (CFEqual(oid
, kSecPolicyOIDEAPServer
) ||
851 CFEqual(oid
, kSecPolicyOIDEAPClient
)) {
852 if ((CFStringGetTypeID() == typeID
) ||
853 (CFArrayGetTypeID() == typeID
)) {
854 SecPolicySetOptionsValue(policyRef
, kSecPolicyCheckEAPTrustedServerNames
, name
);
856 else result
= errSecParam
;
858 else if (CFEqual(oid
, kSecPolicyOIDSMIME
)) {
859 if (CFStringGetTypeID() == typeID
) {
860 SecPolicySetOptionsValue(policyRef
, kSecPolicyCheckEmail
, name
);
862 else result
= errSecParam
;
867 CFTypeRef client
= NULL
;
868 if (CFDictionaryGetValueIfPresent(properties
, (const void *)kSecPolicyClient
,
869 (const void **)&client
) && client
) {
870 if (!(CFBooleanGetTypeID() == CFGetTypeID(client
))) {
871 result
= errSecParam
;
873 else if (CFEqual(client
, kCFBooleanTrue
)) {
874 if (CFEqual(oid
, kSecPolicyOIDSSLServer
)) {
875 SecPolicySetOid(policyRef
, kSecPolicyOIDSSLClient
);
877 else if (CFEqual(oid
, kSecPolicyOIDIPSecServer
)) {
878 SecPolicySetOid(policyRef
, kSecPolicyOIDIPSecClient
);
880 else if (CFEqual(oid
, kSecPolicyOIDEAPServer
)) {
881 SecPolicySetOid(policyRef
, kSecPolicyOIDEAPClient
);
885 if (CFEqual(oid
, kSecPolicyOIDSSLClient
)) {
886 SecPolicySetOid(policyRef
, kSecPolicyOIDSSLServer
);
888 else if (CFEqual(oid
, kSecPolicyOIDIPSecClient
)) {
889 SecPolicySetOid(policyRef
, kSecPolicyOIDIPSecServer
);
891 else if (CFEqual(oid
, kSecPolicyOIDEAPClient
)) {
892 SecPolicySetOid(policyRef
, kSecPolicyOIDEAPServer
);
901 static xpc_object_t
copy_xpc_policy_object(SecPolicyRef policy
);
902 static bool append_policy_to_xpc_array(SecPolicyRef policy
, xpc_object_t xpc_policies
);
903 extern xpc_object_t
copy_xpc_policies_array(CFArrayRef policies
);
904 extern OSStatus
validate_array_of_items(CFArrayRef array
, CFStringRef arrayItemType
, CFTypeID itemTypeID
, bool required
);
906 static xpc_object_t
copy_xpc_policy_object(SecPolicyRef policy
) {
907 xpc_object_t xpc_policy
= NULL
;
908 xpc_object_t data
[2] = { NULL
, NULL
};
909 if (policy
->_oid
&& (CFGetTypeID(policy
->_oid
) == CFStringGetTypeID())) {
910 data
[0] = _CFXPCCreateXPCObjectFromCFObject(policy
->_oid
);
912 secerror("policy 0x%lX has no _oid", (uintptr_t)policy
);
914 if (policy
->_options
&& (CFGetTypeID(policy
->_options
) == CFDictionaryGetTypeID())) {
915 data
[1] = _CFXPCCreateXPCObjectFromCFObject(policy
->_options
);
917 secerror("policy 0x%lX has no _options", (uintptr_t)policy
);
919 xpc_policy
= xpc_array_create(data
, array_size(data
));
920 if (data
[0]) xpc_release(data
[0]);
921 if (data
[1]) xpc_release(data
[1]);
925 static bool append_policy_to_xpc_array(SecPolicyRef policy
, xpc_object_t xpc_policies
) {
929 xpc_object_t xpc_policy
= copy_xpc_policy_object(policy
);
933 xpc_array_append_value(xpc_policies
, xpc_policy
);
934 xpc_release(xpc_policy
);
938 xpc_object_t
copy_xpc_policies_array(CFArrayRef policies
) {
939 xpc_object_t xpc_policies
= xpc_array_create(NULL
, 0);
943 validate_array_of_items(policies
, CFSTR("policy"), SecPolicyGetTypeID(), true);
944 CFIndex ix
, count
= CFArrayGetCount(policies
);
945 for (ix
= 0; ix
< count
; ++ix
) {
946 SecPolicyRef policy
= (SecPolicyRef
) CFArrayGetValueAtIndex(policies
, ix
);
947 #if SECTRUST_VERBOSE_DEBUG
948 CFDictionaryRef props
= SecPolicyCopyProperties(policy
);
949 secerror("idx=%d of %d; policy=0x%lX properties=%@", (int)ix
, (int)count
, (uintptr_t)policy
, props
);
950 CFReleaseSafe(props
);
952 if (!append_policy_to_xpc_array(policy
, xpc_policies
)) {
953 xpc_release(xpc_policies
);
961 static xpc_object_t
SecPolicyCopyXPCObject(SecPolicyRef policy
, CFErrorRef
*error
) {
962 xpc_object_t xpc_policy
= NULL
;
963 xpc_object_t data
[2] = {};
964 require_action_quiet(data
[0] = _CFXPCCreateXPCObjectFromCFObject(policy
->_oid
), exit
,
965 SecError(errSecParam
, error
, CFSTR("failed to create xpc_object from policy oid")));
966 require_action_quiet(data
[1] = _CFXPCCreateXPCObjectFromCFObject(policy
->_options
), exit
,
967 SecError(errSecParam
, error
, CFSTR("failed to create xpc_object from policy options")));
968 require_action_quiet(xpc_policy
= xpc_array_create(data
, array_size(data
)), exit
,
969 SecError(errSecAllocate
, error
, CFSTR("failed to create xpc_array for policy")));
972 if (data
[0]) xpc_release(data
[0]);
973 if (data
[1]) xpc_release(data
[1]);
977 static bool SecPolicyAppendToXPCArray(SecPolicyRef policy
, xpc_object_t policies
, CFErrorRef
*error
) {
981 xpc_object_t xpc_policy
= SecPolicyCopyXPCObject(policy
, error
);
985 xpc_array_append_value(policies
, xpc_policy
);
986 xpc_release(xpc_policy
);
990 xpc_object_t
SecPolicyArrayCopyXPCArray(CFArrayRef policies
, CFErrorRef
*error
) {
991 xpc_object_t xpc_policies
;
992 require_action_quiet(xpc_policies
= xpc_array_create(NULL
, 0), exit
,
993 SecError(errSecAllocate
, error
, CFSTR("failed to create xpc_array")));
994 CFIndex ix
, count
= CFArrayGetCount(policies
);
995 for (ix
= 0; ix
< count
; ++ix
) {
996 if (!SecPolicyAppendToXPCArray((SecPolicyRef
)CFArrayGetValueAtIndex(policies
, ix
), xpc_policies
, error
)) {
997 xpc_release(xpc_policies
);
1002 return xpc_policies
;
1005 static SecPolicyRef
SecPolicyCreateWithXPCObject(xpc_object_t xpc_policy
, CFErrorRef
*error
) {
1006 SecPolicyRef policy
= NULL
;
1007 CFTypeRef oid
= NULL
;
1008 CFTypeRef options
= NULL
;
1010 require_action_quiet(xpc_policy
, exit
, SecError(errSecParam
, error
, CFSTR("policy xpc value is NULL")));
1011 require_action_quiet(xpc_get_type(xpc_policy
) == XPC_TYPE_ARRAY
, exit
, SecError(errSecDecode
, error
, CFSTR("policy xpc value is not an array")));
1012 require_action_quiet(xpc_array_get_count(xpc_policy
) == 2, exit
, SecError(errSecDecode
, error
, CFSTR("policy xpc array count != 2")));
1013 oid
= _CFXPCCreateCFObjectFromXPCObject(xpc_array_get_value(xpc_policy
, 0));
1014 require_action_quiet(isString(oid
), exit
,
1015 SecError(errSecParam
, error
, CFSTR("failed to convert xpc policy[0]=%@ to CFString"), oid
));
1016 options
= _CFXPCCreateCFObjectFromXPCObject(xpc_array_get_value(xpc_policy
, 1));
1017 require_action_quiet(isDictionary(options
), exit
,
1018 SecError(errSecParam
, error
, CFSTR("failed to convert xpc policy[1]=%@ to CFDictionary"), options
));
1019 require_action_quiet(policy
= SecPolicyCreate(oid
, options
), exit
, SecError(errSecDecode
, error
, CFSTR("Failed to create policy")));
1023 CFReleaseSafe(options
);
1027 CFArrayRef
SecPolicyXPCArrayCopyArray(xpc_object_t xpc_policies
, CFErrorRef
*error
) {
1028 CFMutableArrayRef policies
= NULL
;
1029 require_action_quiet(xpc_get_type(xpc_policies
) == XPC_TYPE_ARRAY
, exit
,
1030 SecError(errSecParam
, error
, CFSTR("policies xpc value is not an array")));
1031 size_t count
= xpc_array_get_count(xpc_policies
);
1032 require_action_quiet(policies
= CFArrayCreateMutable(kCFAllocatorDefault
, count
, &kCFTypeArrayCallBacks
), exit
,
1033 SecError(errSecAllocate
, error
, CFSTR("failed to create CFArray of capacity %zu"), count
));
1036 for (ix
= 0; ix
< count
; ++ix
) {
1037 SecPolicyRef policy
= SecPolicyCreateWithXPCObject(xpc_array_get_value(xpc_policies
, ix
), error
);
1039 CFRelease(policies
);
1042 CFArraySetValueAtIndex(policies
, ix
, policy
);
1051 static void add_element(CFMutableDictionaryRef options
, CFStringRef key
,
1053 CFTypeRef old_value
= CFDictionaryGetValue(options
, key
);
1055 CFMutableArrayRef array
;
1056 if (CFGetTypeID(old_value
) == CFArrayGetTypeID()) {
1057 array
= (CFMutableArrayRef
)old_value
;
1059 array
= CFArrayCreateMutable(kCFAllocatorDefault
, 0,
1060 &kCFTypeArrayCallBacks
);
1061 CFArrayAppendValue(array
, old_value
);
1062 CFDictionarySetValue(options
, key
, array
);
1065 CFArrayAppendValue(array
, value
);
1067 CFDictionaryAddValue(options
, key
, value
);
1071 static void add_eku(CFMutableDictionaryRef options
, const DERItem
*ekuOid
) {
1072 CFDataRef eku
= CFDataCreate(kCFAllocatorDefault
,
1073 ekuOid
? ekuOid
->data
: NULL
,
1074 ekuOid
? ekuOid
->length
: 0);
1076 add_element(options
, kSecPolicyCheckExtendedKeyUsage
, eku
);
1081 static void add_ku(CFMutableDictionaryRef options
, SecKeyUsage keyUsage
) {
1082 SInt32 dku
= keyUsage
;
1083 CFNumberRef ku
= CFNumberCreate(kCFAllocatorDefault
, kCFNumberSInt32Type
,
1086 add_element(options
, kSecPolicyCheckKeyUsage
, ku
);
1091 static void add_oid(CFMutableDictionaryRef options
, CFStringRef policy_key
, const DERItem
*oid
) {
1092 CFDataRef oid_data
= CFDataCreate(kCFAllocatorDefault
,
1093 oid
? oid
->data
: NULL
,
1094 oid
? oid
->length
: 0);
1096 add_element(options
, policy_key
, oid_data
);
1097 CFRelease(oid_data
);
1101 static void add_leaf_marker_value(CFMutableDictionaryRef options
, const DERItem
*markerOid
, CFStringRef string_value
) {
1103 CFTypeRef policyData
= NULL
;
1105 if (NULL
== string_value
) {
1106 policyData
= CFDataCreate(kCFAllocatorDefault
,
1107 markerOid
? markerOid
->data
: NULL
,
1108 markerOid
? markerOid
->length
: 0);
1110 CFStringRef oid_as_string
= SecDERItemCopyOIDDecimalRepresentation(kCFAllocatorDefault
, markerOid
);
1112 const void *key
[1] = { oid_as_string
};
1113 const void *value
[1] = { string_value
};
1114 policyData
= CFDictionaryCreate(kCFAllocatorDefault
,
1116 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
1117 CFReleaseNull(oid_as_string
);
1120 add_element(options
, kSecPolicyCheckLeafMarkerOid
, policyData
);
1122 CFReleaseNull(policyData
);
1126 static void add_leaf_marker(CFMutableDictionaryRef options
, const DERItem
*markerOid
) {
1127 add_leaf_marker_value(options
, markerOid
, NULL
);
1131 static void add_certificate_policy_oid(CFMutableDictionaryRef options
, const DERItem
*certificatePolicyOid
, CFStringRef string_value
) {
1132 CFTypeRef certificatePolicyData
= NULL
;
1134 if (NULL
== string_value
) {
1135 certificatePolicyData
= CFDataCreate(kCFAllocatorDefault
,
1136 certificatePolicyOid
? certificatePolicyOid
->data
: NULL
,
1137 certificatePolicyOid
? certificatePolicyOid
->length
: 0);
1139 CFStringRef oid_as_string
= SecDERItemCopyOIDDecimalRepresentation(kCFAllocatorDefault
, certificatePolicyOid
);
1141 const void *key
[1] = { oid_as_string
};
1142 const void *value
[1] = { string_value
};
1143 certificatePolicyData
= CFDictionaryCreate(kCFAllocatorDefault
,
1145 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
1146 CFReleaseNull(oid_as_string
);
1149 add_element(options
, kSecPolicyCheckCertificatePolicy
, certificatePolicyData
);
1151 CFReleaseNull(certificatePolicyData
);
1154 // Routines for adding dictionary entries for policies.
1157 // X.509, but missing validity requirements.
1158 static void SecPolicyAddBasicCertOptions(CFMutableDictionaryRef options
)
1160 //CFDictionaryAddValue(options, kSecPolicyCheckBasicCertificateProcessing, kCFBooleanTrue);
1161 CFDictionaryAddValue(options
, kSecPolicyCheckCriticalExtensions
, kCFBooleanTrue
);
1162 CFDictionaryAddValue(options
, kSecPolicyCheckIdLinkage
, kCFBooleanTrue
);
1163 CFDictionaryAddValue(options
, kSecPolicyCheckBasicContraints
, kCFBooleanTrue
);
1164 CFDictionaryAddValue(options
, kSecPolicyCheckNonEmptySubject
, kCFBooleanTrue
);
1165 CFDictionaryAddValue(options
, kSecPolicyCheckQualifiedCertStatements
, kCFBooleanTrue
);
1166 CFDictionaryAddValue(options
, kSecPolicyCheckWeakIntermediates
, kCFBooleanTrue
);
1167 CFDictionaryAddValue(options
, kSecPolicyCheckWeakLeaf
, kCFBooleanTrue
);
1168 CFDictionaryAddValue(options
, kSecPolicyCheckWeakRoot
, kCFBooleanTrue
);
1171 static void SecPolicyAddBasicX509Options(CFMutableDictionaryRef options
)
1173 SecPolicyAddBasicCertOptions(options
);
1174 CFDictionaryAddValue(options
, kSecPolicyCheckValidIntermediates
, kCFBooleanTrue
);
1175 CFDictionaryAddValue(options
, kSecPolicyCheckValidLeaf
, kCFBooleanTrue
);
1176 CFDictionaryAddValue(options
, kSecPolicyCheckValidRoot
, kCFBooleanTrue
);
1178 // Make sure that black and gray leaf checks are performed for basic X509 chain building
1179 CFDictionaryAddValue(options
, kSecPolicyCheckBlackListedLeaf
, kCFBooleanTrue
);
1180 CFDictionaryAddValue(options
, kSecPolicyCheckGrayListedLeaf
, kCFBooleanTrue
);
1183 static bool SecPolicyAddChainLengthOptions(CFMutableDictionaryRef options
, CFIndex length
)
1185 bool result
= false;
1186 CFNumberRef lengthAsCF
= NULL
;
1188 require(lengthAsCF
= CFNumberCreate(kCFAllocatorDefault
,
1189 kCFNumberCFIndexType
, &length
), errOut
);
1190 CFDictionaryAddValue(options
, kSecPolicyCheckChainLength
, lengthAsCF
);
1195 CFReleaseSafe(lengthAsCF
);
1199 static bool SecPolicyAddAnchorSHA1Options(CFMutableDictionaryRef options
,
1200 const UInt8 anchorSha1
[kSecPolicySHA1Size
])
1202 bool success
= false;
1203 CFDataRef anchorData
= NULL
;
1205 require(anchorData
= CFDataCreate(kCFAllocatorDefault
, anchorSha1
, kSecPolicySHA1Size
), errOut
);
1206 add_element(options
, kSecPolicyCheckAnchorSHA1
, anchorData
);
1211 CFReleaseSafe(anchorData
);
1215 static bool SecPolicyAddAppleAnchorOptions(CFMutableDictionaryRef options
)
1217 return SecPolicyAddAnchorSHA1Options(options
, kAppleCASHA1
);
1221 // Policy Creation Functions
1223 SecPolicyRef
SecPolicyCreateBasicX509(void) {
1224 CFMutableDictionaryRef options
= NULL
;
1225 SecPolicyRef result
= NULL
;
1227 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1228 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1230 SecPolicyAddBasicX509Options(options
);
1231 CFDictionaryAddValue(options
, kSecPolicyCheckNoNetworkAccess
,
1234 require(result
= SecPolicyCreate(kSecPolicyOIDBasicX509
, options
), errOut
);
1237 CFReleaseSafe(options
);
1241 SecPolicyRef
SecPolicyCreateSSL(Boolean server
, CFStringRef hostname
) {
1242 CFMutableDictionaryRef options
= NULL
;
1243 SecPolicyRef result
= NULL
;
1245 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1246 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1248 SecPolicyAddBasicX509Options(options
);
1251 CFDictionaryAddValue(options
, kSecPolicyCheckSSLHostname
, hostname
);
1254 CFDictionaryAddValue(options
, kSecPolicyCheckBlackListedLeaf
, kCFBooleanTrue
);
1255 CFDictionaryAddValue(options
, kSecPolicyCheckGrayListedLeaf
, kCFBooleanTrue
);
1257 /* If server and EKU ext present then EKU ext should contain one of
1258 ServerAuth or ExtendedKeyUsageAny or NetscapeSGC or MicrosoftSGC.
1259 else if !server and EKU ext present then EKU ext should contain one of
1260 ClientAuth or ExtendedKeyUsageAny. */
1262 /* We always allow certificates that specify oidAnyExtendedKeyUsage. */
1263 add_eku(options
, NULL
); /* eku extension is optional */
1264 add_eku(options
, &oidAnyExtendedKeyUsage
);
1266 add_eku(options
, &oidExtendedKeyUsageServerAuth
);
1267 add_eku(options
, &oidExtendedKeyUsageMicrosoftSGC
);
1268 add_eku(options
, &oidExtendedKeyUsageNetscapeSGC
);
1270 add_eku(options
, &oidExtendedKeyUsageClientAuth
);
1273 require(result
= SecPolicyCreate(
1274 server
? kSecPolicyOIDSSLServer
: kSecPolicyOIDSSLClient
,
1278 CFReleaseSafe(options
);
1282 SecPolicyRef
SecPolicyCreateiPhoneActivation(void) {
1283 CFMutableDictionaryRef options
= NULL
;
1284 SecPolicyRef result
= NULL
;
1286 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1287 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1289 SecPolicyAddBasicCertOptions(options
);
1292 CFDictionaryAddValue(options
, kSecPolicyCheckKeyUsage
,
1294 CFDictionaryAddValue(options
, kSecPolicyCheckExtendedKeyUsage
,
1298 /* Basic X.509 policy with the additional requirements that the chain
1299 length is 3, it's anchored at the AppleCA and the leaf certificate
1300 has issuer "Apple iPhone Certification Authority" and
1301 subject "Apple iPhone Activation" for the common name. */
1302 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
1303 CFSTR("Apple iPhone Certification Authority"));
1304 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
,
1305 CFSTR("Apple iPhone Activation"));
1307 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1308 require(SecPolicyAddAppleAnchorOptions(options
), errOut
);
1310 require(result
= SecPolicyCreate(kSecPolicyOIDiPhoneActivation
, options
),
1314 CFReleaseSafe(options
);
1318 SecPolicyRef
SecPolicyCreateiPhoneDeviceCertificate(void) {
1319 CFMutableDictionaryRef options
= NULL
;
1320 SecPolicyRef result
= NULL
;
1322 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1323 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1325 SecPolicyAddBasicCertOptions(options
);
1328 CFDictionaryAddValue(options
, kSecPolicyCheckKeyUsage
,
1330 CFDictionaryAddValue(options
, kSecPolicyCheckExtendedKeyUsage
,
1334 /* Basic X.509 policy with the additional requirements that the chain
1335 length is 4, it's anchored at the AppleCA and the first intermediate
1336 has the subject "Apple iPhone Device CA". */
1337 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
1338 CFSTR("Apple iPhone Device CA"));
1340 require(SecPolicyAddChainLengthOptions(options
, 4), errOut
);
1341 require(SecPolicyAddAppleAnchorOptions(options
), errOut
);
1343 require(result
= SecPolicyCreate(kSecPolicyOIDiPhoneDeviceCertificate
, options
),
1347 CFReleaseSafe(options
);
1351 SecPolicyRef
SecPolicyCreateFactoryDeviceCertificate(void) {
1352 CFMutableDictionaryRef options
= NULL
;
1353 SecPolicyRef result
= NULL
;
1355 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1356 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1358 SecPolicyAddBasicCertOptions(options
);
1361 CFDictionaryAddValue(options
, kSecPolicyCheckKeyUsage
,
1363 CFDictionaryAddValue(options
, kSecPolicyCheckExtendedKeyUsage
,
1367 /* Basic X.509 policy with the additional requirements that the chain
1368 is anchored at the factory device certificate issuer. */
1369 require(SecPolicyAddAnchorSHA1Options(options
, kFactoryDeviceCASHA1
), errOut
);
1371 require(result
= SecPolicyCreate(kSecPolicyOIDFactoryDeviceCertificate
, options
),
1375 CFReleaseSafe(options
);
1379 SecPolicyRef
SecPolicyCreateiAP(void) {
1380 CFMutableDictionaryRef options
= NULL
;
1381 SecPolicyRef result
= NULL
;
1382 CFTimeZoneRef tz
= NULL
;
1383 CFDateRef date
= NULL
;
1385 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1386 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1388 SecPolicyAddBasicCertOptions(options
);
1390 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonNamePrefix
,
1393 date
= CFDateCreateForGregorianZuluDay(NULL
, 2006, 5, 31);
1394 CFDictionaryAddValue(options
, kSecPolicyCheckNotValidBefore
, date
);
1396 require(result
= SecPolicyCreate(kSecPolicyOIDiAP
, options
),
1400 CFReleaseSafe(date
);
1402 CFReleaseSafe(options
);
1406 SecPolicyRef
SecPolicyCreateiTunesStoreURLBag(void) {
1407 CFMutableDictionaryRef options
= NULL
;
1408 SecPolicyRef result
= NULL
;
1411 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1412 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1414 SecPolicyAddBasicCertOptions(options
);
1416 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectOrganization
,
1417 CFSTR("Apple Inc."));
1418 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
,
1419 CFSTR("iTunes Store URL Bag"));
1421 require(SecPolicyAddChainLengthOptions(options
, 2), errOut
);
1422 require(SecPolicyAddAnchorSHA1Options(options
, kITMSCASHA1
), errOut
);
1424 require(result
= SecPolicyCreate(kSecPolicyOIDiTunesStoreURLBag
, options
), errOut
);
1427 CFReleaseSafe(options
);
1431 SecPolicyRef
SecPolicyCreateEAP(Boolean server
, CFArrayRef trustedServerNames
) {
1432 CFMutableDictionaryRef options
= NULL
;
1433 SecPolicyRef result
= NULL
;
1435 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1436 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1438 SecPolicyAddBasicX509Options(options
);
1440 /* Since EAP is used to setup the network we don't want evaluation
1441 using this policy to access the network. */
1442 CFDictionaryAddValue(options
, kSecPolicyCheckNoNetworkAccess
,
1445 if (trustedServerNames
) {
1446 CFDictionaryAddValue(options
, kSecPolicyCheckEAPTrustedServerNames
, trustedServerNames
);
1448 /* Specifying trusted server names implies EAP-TLS,
1449 so we need to check for EKU per rdar://22206018 */
1451 /* If server and EKU ext present then EKU ext should contain one of
1452 ServerAuth or ExtendedKeyUsageAny or NetscapeSGC or MicrosoftSGC.
1453 else if !server and EKU ext present then EKU ext should contain one of
1454 ClientAuth or ExtendedKeyUsageAny. */
1456 /* We always allow certificates that specify oidAnyExtendedKeyUsage. */
1457 add_eku(options
, NULL
); /* eku extension is optional */
1458 add_eku(options
, &oidAnyExtendedKeyUsage
);
1460 add_eku(options
, &oidExtendedKeyUsageServerAuth
);
1461 add_eku(options
, &oidExtendedKeyUsageMicrosoftSGC
);
1462 add_eku(options
, &oidExtendedKeyUsageNetscapeSGC
);
1464 add_eku(options
, &oidExtendedKeyUsageClientAuth
);
1468 require(result
= SecPolicyCreate(
1469 server
? kSecPolicyOIDEAPServer
: kSecPolicyOIDEAPClient
,
1473 CFReleaseSafe(options
);
1477 SecPolicyRef
SecPolicyCreateIPSec(Boolean server
, CFStringRef hostname
) {
1478 CFMutableDictionaryRef options
= NULL
;
1479 SecPolicyRef result
= NULL
;
1481 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1482 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1484 SecPolicyAddBasicX509Options(options
);
1487 CFDictionaryAddValue(options
, kSecPolicyCheckSSLHostname
, hostname
);
1490 /* Require oidExtendedKeyUsageIPSec if Extended Keyusage Extention is
1492 /* Per <rdar://problem/6843827> Cisco VPN Certificate compatibility issue.
1493 We don't check the EKU for IPSec certs for now. If we do add eku
1494 checking back in the future, we should probably also accept the
1496 ipsecEndSystem 1.3.6.1.5.5.7.3.5
1498 ipsecTunnel 1.3.6.1.5.5.7.3.6
1499 ipsecUser 1.3.6.1.5.5.7.3.7
1501 //add_eku(options, NULL); /* eku extension is optional */
1502 //add_eku(options, &oidAnyExtendedKeyUsage);
1503 //add_eku(options, &oidExtendedKeyUsageIPSec);
1505 require(result
= SecPolicyCreate(
1506 server
? kSecPolicyOIDIPSecServer
: kSecPolicyOIDIPSecClient
,
1510 CFReleaseSafe(options
);
1514 SecPolicyRef
SecPolicyCreateiPhoneApplicationSigning(void) {
1515 CFMutableDictionaryRef options
= NULL
;
1516 SecPolicyRef result
= NULL
;
1518 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1519 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1521 SecPolicyAddBasicCertOptions(options
);
1523 /* Basic X.509 policy with the additional requirements that the chain
1524 length is 3, it's anchored at the AppleCA and the leaf certificate
1525 has issuer "Apple iPhone Certification Authority" and
1526 subject "Apple iPhone OS Application Signing" for the common name. */
1527 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
1528 CFSTR("Apple iPhone Certification Authority"));
1529 if (SecIsInternalRelease() && !SecIsProductionFused()) {
1530 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonNameTEST
,
1531 CFSTR("Apple iPhone OS Application Signing"));
1534 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
,
1535 CFSTR("Apple iPhone OS Application Signing"));
1538 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1539 require(SecPolicyAddAppleAnchorOptions(options
), errOut
);
1541 add_eku(options
, NULL
); /* eku extension is optional */
1542 add_eku(options
, &oidAnyExtendedKeyUsage
);
1543 add_eku(options
, &oidExtendedKeyUsageCodeSigning
);
1545 require(result
= SecPolicyCreate(kSecPolicyOIDiPhoneApplicationSigning
, options
),
1548 /* 1.2.840.113635.100.6.1.3, non-critical: DER:05:00 - application signing */
1551 CFReleaseSafe(options
);
1555 SecPolicyRef
SecPolicyCreateiPhoneProfileApplicationSigning(void) {
1556 CFMutableDictionaryRef options
= NULL
;
1557 SecPolicyRef result
= NULL
;
1559 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1560 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1561 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kCFBooleanFalse
);
1562 CFDictionaryAddValue(options
, kSecPolicyCheckValidLeaf
, kCFBooleanFalse
);
1564 require(result
= SecPolicyCreate(kSecPolicyOIDiPhoneProfileApplicationSigning
,
1568 CFReleaseSafe(options
);
1572 SecPolicyRef
SecPolicyCreateiPhoneProvisioningProfileSigning(void) {
1573 CFMutableDictionaryRef options
= NULL
;
1574 SecPolicyRef result
= NULL
;
1576 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1577 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1579 SecPolicyAddBasicCertOptions(options
);
1581 /* Basic X.509 policy with the additional requirements that the chain
1582 length is 3, it's anchored at the AppleCA and the leaf certificate
1583 has issuer "Apple iPhone Certification Authority" and
1584 subject "Apple iPhone OS Provisioning Profile Signing" for the common name. */
1585 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
1586 CFSTR("Apple iPhone Certification Authority"));
1587 if (SecIsInternalRelease() && !SecIsProductionFused()) {
1588 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonNameTEST
,
1589 CFSTR("Apple iPhone OS Provisioning Profile Signing"));
1592 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
,
1593 CFSTR("Apple iPhone OS Provisioning Profile Signing"));
1596 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1597 require(SecPolicyAddAppleAnchorOptions(options
), errOut
);
1599 require(result
= SecPolicyCreate(kSecPolicyOIDiPhoneProvisioningProfileSigning
, options
),
1602 /* 1.2.840.113635.100.6.2.2.1, non-critical: DER:05:00 - provisioning profile */
1605 CFReleaseSafe(options
);
1609 SecPolicyRef
SecPolicyCreateAppleTVOSApplicationSigning(void) {
1610 CFMutableDictionaryRef options
= NULL
;
1611 SecPolicyRef result
= NULL
;
1612 CFDataRef atvProdOid
= NULL
;
1613 CFDataRef atvTestOid
= NULL
;
1614 CFArrayRef oids
= NULL
;
1616 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1617 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1619 SecPolicyAddBasicCertOptions(options
);
1621 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1623 CFMutableDictionaryRef appleAnchorOptions
= CFDictionaryCreateMutableForCFTypes(NULL
);
1624 require(appleAnchorOptions
, errOut
);
1625 add_element(options
, kSecPolicyCheckAnchorApple
, appleAnchorOptions
);
1627 /* Check for intermediate: Apple Worldwide Developer Relations */
1628 /* 1.2.840.113635.100.6.2.1 */
1629 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleWWDR
);
1631 add_eku(options
, NULL
); /* eku extension is optional */
1632 add_eku(options
, &oidAnyExtendedKeyUsage
);
1633 add_eku(options
, &oidExtendedKeyUsageCodeSigning
);
1635 /* Check for prod or test AppleTV Application Signing OIDs */
1636 /* Prod: 1.2.840.113635.100.6.1.24 */
1637 /* Test: 1.2.840.113635.100.6.1.24.1 */
1638 atvProdOid
= CFDataCreate(kCFAllocatorDefault
, oidAppleTVOSApplicationSigningProd
.data
, oidAppleTVOSApplicationSigningProd
.length
);
1639 require(atvProdOid
, errOut
);
1640 atvTestOid
= CFDataCreate(kCFAllocatorDefault
, oidAppleTVOSApplicationSigningTest
.data
, oidAppleTVOSApplicationSigningTest
.length
);
1641 require(atvTestOid
, errOut
);
1643 oids
= CFArrayCreateForCFTypes(kCFAllocatorDefault
, atvProdOid
, atvTestOid
, NULL
);
1644 require(oids
, errOut
);
1646 add_element(options
, kSecPolicyCheckLeafMarkerOid
, oids
);
1648 require(result
= SecPolicyCreate(kSecPolicyOIDAppleTVOSApplicationSigning
, options
),
1652 CFReleaseSafe(options
);
1653 CFReleaseSafe(oids
);
1654 CFReleaseSafe(atvProdOid
);
1655 CFReleaseSafe(atvTestOid
);
1659 SecPolicyRef
SecPolicyCreateOCSPSigner(void) {
1660 CFMutableDictionaryRef options
= NULL
;
1661 SecPolicyRef result
= NULL
;
1663 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1664 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1666 SecPolicyAddBasicX509Options(options
);
1668 /* Require id-kp-OCSPSigning extendedKeyUsage to be present, not optional. */
1669 add_eku(options
, &oidExtendedKeyUsageOCSPSigning
);
1671 require(result
= SecPolicyCreate(kSecPolicyOIDOCSPSigner
, options
), errOut
);
1674 CFReleaseSafe(options
);
1678 SecPolicyRef
SecPolicyCreateRevocation(CFOptionFlags revocationFlags
) {
1679 CFMutableDictionaryRef options
= NULL
;
1680 SecPolicyRef result
= NULL
;
1682 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1683 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1685 /* false = ocsp, true = crl, string/url value = crl distribution point,
1686 array = list of multiple values for example false, true, url1, url2
1687 check ocsp, crl, and url1 and url2 for certs which have no extensions.
1689 if (revocationFlags
& kSecRevocationOCSPMethod
) {
1690 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kCFBooleanFalse
);
1692 else if (revocationFlags
& kSecRevocationCRLMethod
) {
1693 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kCFBooleanTrue
);
1696 if (revocationFlags
& kSecRevocationRequirePositiveResponse
) {
1697 CFDictionaryAddValue(options
, kSecPolicyCheckRevocationResponseRequired
, kCFBooleanTrue
);
1700 if (revocationFlags
& kSecRevocationNetworkAccessDisabled
) {
1701 CFDictionaryAddValue(options
, kSecPolicyCheckNoNetworkAccess
, kCFBooleanTrue
);
1704 /* Only flag bits 0-4 are currently defined */
1705 require(((revocationFlags
>> 5) == 0), errOut
);
1707 require(result
= SecPolicyCreate(kSecPolicyOIDRevocation
, options
), errOut
);
1710 CFReleaseSafe(options
);
1714 SecPolicyRef
SecPolicyCreateSMIME(CFIndex smimeUsage
, CFStringRef email
) {
1715 CFMutableDictionaryRef options
= NULL
;
1716 SecPolicyRef result
= NULL
;
1718 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1719 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1721 SecPolicyAddBasicX509Options(options
);
1723 /* We call add_ku for each combination of bits we are willing to allow. */
1724 if (smimeUsage
& kSecSignSMIMEUsage
) {
1725 add_ku(options
, kSecKeyUsageUnspecified
);
1726 add_ku(options
, kSecKeyUsageDigitalSignature
);
1727 add_ku(options
, kSecKeyUsageNonRepudiation
);
1729 if (smimeUsage
& kSecKeyEncryptSMIMEUsage
) {
1730 add_ku(options
, kSecKeyUsageKeyEncipherment
);
1732 if (smimeUsage
& kSecDataEncryptSMIMEUsage
) {
1733 add_ku(options
, kSecKeyUsageDataEncipherment
);
1735 if (smimeUsage
& kSecKeyExchangeDecryptSMIMEUsage
) {
1736 add_ku(options
, kSecKeyUsageKeyAgreement
| kSecKeyUsageDecipherOnly
);
1738 if (smimeUsage
& kSecKeyExchangeEncryptSMIMEUsage
) {
1739 add_ku(options
, kSecKeyUsageKeyAgreement
| kSecKeyUsageEncipherOnly
);
1741 if (smimeUsage
& kSecKeyExchangeBothSMIMEUsage
) {
1742 add_ku(options
, kSecKeyUsageKeyAgreement
| kSecKeyUsageEncipherOnly
| kSecKeyUsageDecipherOnly
);
1746 CFDictionaryAddValue(options
, kSecPolicyCheckEmail
, email
);
1749 /* RFC 3850 paragraph 4.4.4
1751 If the extended key usage extension is present in the certificate
1752 then interpersonal message S/MIME receiving agents MUST check that it
1753 contains either the emailProtection or the anyExtendedKeyUsage OID as
1754 defined in [KEYM]. S/MIME uses other than interpersonal messaging
1755 MAY require the explicit presence of the extended key usage extension
1756 or other OIDs to be present in the extension or both.
1758 add_eku(options
, NULL
); /* eku extension is optional */
1759 add_eku(options
, &oidAnyExtendedKeyUsage
);
1760 add_eku(options
, &oidExtendedKeyUsageEmailProtection
);
1762 require(result
= SecPolicyCreate(kSecPolicyOIDSMIME
, options
), errOut
);
1765 CFReleaseSafe(options
);
1769 SecPolicyRef
SecPolicyCreateApplePackageSigning(void) {
1770 CFMutableDictionaryRef options
= NULL
;
1771 SecPolicyRef result
= NULL
;
1773 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1774 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1776 // TBD: review OS X policy to see what options are needed for this policy
1777 SecPolicyAddBasicCertOptions(options
);
1779 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1780 require(SecPolicyAddAppleAnchorOptions(options
), errOut
);
1782 require(result
= SecPolicyCreate(kSecPolicyOIDPackageSigning
, options
),
1786 CFReleaseSafe(options
);
1791 SecPolicyRef
SecPolicyCreateAppleSWUpdateSigning(void) {
1792 CFMutableDictionaryRef options
= NULL
;
1793 SecPolicyRef result
= NULL
;
1795 * OS X rules for this policy:
1796 * -- Must have one intermediate cert
1797 * -- intermediate must have basic constraints with path length 0
1798 * -- intermediate has CSSMOID_APPLE_EKU_CODE_SIGNING EKU
1799 * -- leaf cert has either CODE_SIGNING or CODE_SIGN_DEVELOPMENT EKU (the latter of
1800 * which triggers a CSSMERR_APPLETP_CODE_SIGN_DEVELOPMENT error)
1802 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1803 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1805 // TBD: review OS X policy to see what options are needed for this policy
1806 SecPolicyAddBasicCertOptions(options
);
1808 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1809 require(SecPolicyAddAppleAnchorOptions(options
), errOut
);
1811 add_eku(options
, &oidAppleExtendedKeyUsageCodeSigning
);
1812 add_eku(options
, &oidAppleExtendedKeyUsageCodeSigningDev
);
1814 require(result
= SecPolicyCreate(kSecPolicyOIDAppleSWUpdateSigning
, options
),
1818 CFReleaseSafe(options
);
1823 SecPolicyRef
SecPolicyCreateCodeSigning(void) {
1824 CFMutableDictionaryRef options
= NULL
;
1825 SecPolicyRef result
= NULL
;
1827 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1828 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1831 #warning STU: <rdar://21328880>
1832 //%%% figure out why this policy is not passing for OS X.
1833 // I suspect it has to do with iOS not supporting anchor and keychain options yet.
1834 SecPolicyAddBasicCertOptions(options
);
1836 SecPolicyAddBasicX509Options(options
);
1838 /* If the key usage extension is present we accept it having either of
1840 add_ku(options
, kSecKeyUsageDigitalSignature
);
1841 add_ku(options
, kSecKeyUsageNonRepudiation
);
1843 /* We require a extended key usage extension and we accept any or
1844 codesigning ekus. */
1845 /* TODO: Do we want to accept the apple codesigning oid as well or is
1846 that a separate policy? */
1847 /* ANSWER: it's a separate policy, SecPolicyCreateAppleSWUpdateSigning */
1848 add_eku(options
, &oidAnyExtendedKeyUsage
);
1849 add_eku(options
, &oidExtendedKeyUsageCodeSigning
);
1852 require(result
= SecPolicyCreate(kSecPolicyOIDCodeSigning
, options
),
1856 CFReleaseSafe(options
);
1860 /* Explicitly leave out empty subject/subjectaltname check */
1861 SecPolicyRef
SecPolicyCreateLockdownPairing(void) {
1862 CFMutableDictionaryRef options
= NULL
;
1863 SecPolicyRef result
= NULL
;
1865 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1866 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1867 //CFDictionaryAddValue(options, kSecPolicyCheckBasicCertificateProcessing,
1869 CFDictionaryAddValue(options
, kSecPolicyCheckCriticalExtensions
,
1871 CFDictionaryAddValue(options
, kSecPolicyCheckIdLinkage
,
1873 CFDictionaryAddValue(options
, kSecPolicyCheckBasicContraints
,
1875 CFDictionaryAddValue(options
, kSecPolicyCheckQualifiedCertStatements
,
1878 require(result
= SecPolicyCreate(kSecPolicyOIDLockdownPairing
, options
), errOut
);
1881 CFReleaseSafe(options
);
1885 SecPolicyRef
SecPolicyCreateURLBag(void) {
1886 CFMutableDictionaryRef options
= NULL
;
1887 SecPolicyRef result
= NULL
;
1889 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1890 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1892 SecPolicyAddBasicCertOptions(options
);
1894 add_eku(options
, &oidExtendedKeyUsageCodeSigning
);
1896 require(result
= SecPolicyCreate(kSecPolicyOIDURLBag
, options
), errOut
);
1899 CFReleaseSafe(options
);
1903 static bool SecPolicyAddAppleCertificationAuthorityOptions(CFMutableDictionaryRef options
, bool honorValidity
)
1905 bool success
= false;
1908 SecPolicyAddBasicX509Options(options
);
1910 SecPolicyAddBasicCertOptions(options
);
1913 CFDictionaryAddValue(options
, kSecPolicyCheckKeyUsage
,
1915 CFDictionaryAddValue(options
, kSecPolicyCheckExtendedKeyUsage
,
1919 /* Basic X.509 policy with the additional requirements that the chain
1920 length is 3, it's anchored at the AppleCA and the leaf certificate
1921 has issuer "Apple iPhone Certification Authority". */
1922 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
1923 CFSTR("Apple iPhone Certification Authority"));
1925 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1926 require(SecPolicyAddAppleAnchorOptions(options
), errOut
);
1934 static SecPolicyRef
SecPolicyCreateAppleCertificationAuthorityPolicy(CFStringRef policyOID
, CFStringRef leafName
, bool honorValidity
)
1936 CFMutableDictionaryRef options
= NULL
;
1937 SecPolicyRef result
= NULL
;
1939 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1940 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1942 require(SecPolicyAddAppleCertificationAuthorityOptions(options
, honorValidity
), errOut
);
1944 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
, leafName
);
1946 require(result
= SecPolicyCreate(policyOID
, options
),
1950 CFReleaseSafe(options
);
1955 SecPolicyRef
SecPolicyCreateOTATasking(void)
1957 return SecPolicyCreateAppleCertificationAuthorityPolicy(kSecPolicyOIDOTATasking
, CFSTR("OTA Task Signing"), true);
1960 SecPolicyRef
SecPolicyCreateMobileAsset(void)
1962 return SecPolicyCreateAppleCertificationAuthorityPolicy(kSecPolicyOIDMobileAsset
, CFSTR("Asset Manifest Signing"), false);
1965 SecPolicyRef
SecPolicyCreateAppleIDAuthorityPolicy(void)
1967 SecPolicyRef result
= NULL
;
1968 CFMutableDictionaryRef options
= NULL
;
1969 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1970 &kCFTypeDictionaryKeyCallBacks
,
1971 &kCFTypeDictionaryValueCallBacks
), out
);
1973 //Leaf appears to be a SSL only cert, so policy should expand on that policy
1974 SecPolicyAddBasicX509Options(options
);
1976 // Apple CA anchored
1977 require(SecPolicyAddAppleAnchorOptions(options
), out
);
1979 // with the addition of the existence check of an extension with "Apple ID Sharing Certificate" oid (1.2.840.113635.100.4.7)
1980 // NOTE: this obviously intended to have gone into Extended Key Usage, but evidence of existing certs proves the contrary.
1981 add_leaf_marker(options
, &oidAppleExtendedKeyUsageAppleID
);
1983 // 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.
1984 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleID
);
1985 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleID2
);
1987 require(result
= SecPolicyCreate(kSecPolicyOIDAppleIDAuthority
, options
), out
);
1990 CFReleaseSafe(options
);
1994 SecPolicyRef
SecPolicyCreateMacAppStoreReceipt(void)
1996 SecPolicyRef result
= NULL
;
1997 CFMutableDictionaryRef options
= NULL
;
1998 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1999 &kCFTypeDictionaryKeyCallBacks
,
2000 &kCFTypeDictionaryValueCallBacks
), out
);
2002 SecPolicyAddBasicX509Options(options
);
2004 // Apple CA anchored
2005 require(SecPolicyAddAppleAnchorOptions(options
), out
);
2007 // - leaf needs certificatePolicies with CSSMOID_MACAPPSTORE_RECEIPT_CERT_POLICY
2008 // - chain length must be 3
2010 require(result
= SecPolicyCreate(kSecPolicyOIDMacAppStoreReceipt
, options
), out
);
2013 CFReleaseSafe(options
);
2018 static SecPolicyRef
_SecPolicyCreatePassbookCardSigner(CFStringRef cardIssuer
, CFStringRef teamIdentifier
, bool requireTeamID
)
2020 SecPolicyRef result
= NULL
;
2021 CFMutableDictionaryRef options
= NULL
;
2022 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2023 &kCFTypeDictionaryKeyCallBacks
,
2024 &kCFTypeDictionaryValueCallBacks
), out
);
2026 SecPolicyAddBasicX509Options(options
);
2027 SecPolicyAddAppleAnchorOptions(options
);
2029 if (teamIdentifier
) {
2030 // If supplied, teamIdentifier must match subject OU field
2031 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectOrganizationalUnit
, teamIdentifier
);
2034 // If not supplied, and it was required, fail
2035 require(!requireTeamID
, out
);
2038 // Must be both push and 3rd party package signing
2039 add_leaf_marker_value(options
, &oidAppleInstallerPackagingSigningExternal
, cardIssuer
);
2041 // We should check that it also has push marker, but we don't support requiring both, only either.
2042 // add_independent_oid(options, kSecPolicyCheckLeafMarkerOid, &oidApplePushServiceClient);
2044 // And Passbook signing eku
2045 add_eku(options
, &oidAppleExtendedKeyUsagePassbook
);
2047 require(result
= SecPolicyCreate(kSecPolicyOIDApplePassbook
, options
), out
);
2050 CFReleaseSafe(options
);
2054 SecPolicyRef
SecPolicyCreatePassbookCardSigner(CFStringRef cardIssuer
, CFStringRef teamIdentifier
)
2056 return _SecPolicyCreatePassbookCardSigner(cardIssuer
, teamIdentifier
, true);
2060 static SecPolicyRef
CreateMobileStoreSigner(Boolean forTest
)
2063 SecPolicyRef result
= NULL
;
2064 CFMutableDictionaryRef options
= NULL
;
2065 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2066 &kCFTypeDictionaryKeyCallBacks
,
2067 &kCFTypeDictionaryValueCallBacks
), errOut
);
2068 SecPolicyAddBasicX509Options(options
);
2069 SecPolicyAddAppleAnchorOptions(options
);
2071 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2073 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2074 CFSTR("Apple System Integration 2 Certification Authority"));
2076 add_ku(options
, kSecKeyUsageDigitalSignature
);
2078 const DERItem
* pOID
= (forTest
) ? &oidApplePolicyTestMobileStore
: &oidApplePolicyMobileStore
;
2080 add_certificate_policy_oid(options
, pOID
, NULL
);
2082 require(result
= SecPolicyCreate(kSecPolicyOIDAppleMobileStore
, options
), errOut
);
2085 CFReleaseSafe(options
);
2089 SecPolicyRef
SecPolicyCreateMobileStoreSigner(void)
2092 return CreateMobileStoreSigner(false);
2095 SecPolicyRef
SecPolicyCreateTestMobileStoreSigner(void)
2098 return CreateMobileStoreSigner(true);
2102 CF_RETURNS_RETAINED SecPolicyRef
SecPolicyCreateEscrowServiceSigner(void)
2104 SecPolicyRef result
= NULL
;
2105 CFMutableDictionaryRef options
= NULL
;
2106 CFArrayRef anArray
= NULL
;
2107 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2108 &kCFTypeDictionaryKeyCallBacks
,
2109 &kCFTypeDictionaryValueCallBacks
), errOut
);
2111 // X509, ignoring date validity
2112 SecPolicyAddBasicCertOptions(options
);
2115 add_ku(options
, kSecKeyUsageKeyEncipherment
);
2117 //add_leaf_marker(options, &oidApplePolicyEscrowService);
2118 require(SecPolicyAddChainLengthOptions(options
, 2), errOut
);
2121 Boolean anchorAdded
= false;
2122 // Get the roots by calling the SecCertificateCopyEscrowRoots
2123 anArray
= SecCertificateCopyEscrowRoots(kSecCertificateProductionEscrowRoot
);
2124 CFIndex numRoots
= 0;
2125 if (NULL
== anArray
|| 0 == (numRoots
= CFArrayGetCount(anArray
)))
2130 for (CFIndex iCnt
= 0; iCnt
< numRoots
; iCnt
++)
2132 SecCertificateRef aCert
= (SecCertificateRef
)CFArrayGetValueAtIndex(anArray
, iCnt
);
2136 CFDataRef sha_data
= SecCertificateGetSHA1Digest(aCert
);
2137 if (NULL
!= sha_data
)
2139 const UInt8
* pSHAData
= CFDataGetBytePtr(sha_data
);
2140 if (NULL
!= pSHAData
)
2142 SecPolicyAddAnchorSHA1Options(options
, pSHAData
);
2148 CFReleaseNull(anArray
);
2156 require(result
= SecPolicyCreate(kSecPolicyOIDAppleEscrowService
, options
), errOut
);
2159 CFReleaseSafe(anArray
);
2160 CFReleaseSafe(options
);
2164 CF_RETURNS_RETAINED SecPolicyRef
SecPolicyCreatePCSEscrowServiceSigner(void)
2166 SecPolicyRef result
= NULL
;
2167 CFMutableDictionaryRef options
= NULL
;
2168 CFArrayRef anArray
= NULL
;
2169 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2170 &kCFTypeDictionaryKeyCallBacks
,
2171 &kCFTypeDictionaryValueCallBacks
), errOut
);
2173 SecPolicyAddBasicX509Options(options
);
2176 add_ku(options
, kSecKeyUsageKeyEncipherment
);
2178 //add_leaf_marker(options, &oidApplePolicyEscrowService);
2179 require(SecPolicyAddChainLengthOptions(options
, 2), errOut
);
2182 Boolean anchorAdded
= false;
2183 anArray
= SecCertificateCopyEscrowRoots(kSecCertificateProductionPCSEscrowRoot
);
2184 CFIndex numRoots
= 0;
2185 if (NULL
== anArray
|| 0 == (numRoots
= CFArrayGetCount(anArray
)))
2190 for (CFIndex iCnt
= 0; iCnt
< numRoots
; iCnt
++)
2192 SecCertificateRef aCert
= (SecCertificateRef
)CFArrayGetValueAtIndex(anArray
, iCnt
);
2196 CFDataRef sha_data
= SecCertificateGetSHA1Digest(aCert
);
2197 if (NULL
!= sha_data
)
2199 const UInt8
* pSHAData
= CFDataGetBytePtr(sha_data
);
2200 if (NULL
!= pSHAData
)
2202 SecPolicyAddAnchorSHA1Options(options
, pSHAData
);
2208 CFReleaseNull(anArray
);
2216 require(result
= SecPolicyCreate(kSecPolicyOIDApplePCSEscrowService
, options
), errOut
);
2219 CFReleaseSafe(anArray
);
2220 CFReleaseSafe(options
);
2223 SecCertificateRef
SecPolicyCopyEscrowRootCertificate(void)
2225 SecCertificateRef result
= NULL
;
2230 SecPolicyRef
SecPolicyCreateConfigurationProfileSigner(void)
2232 SecPolicyRef result
= NULL
;
2233 CFMutableDictionaryRef options
= NULL
;
2234 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2235 &kCFTypeDictionaryKeyCallBacks
,
2236 &kCFTypeDictionaryValueCallBacks
), errOut
);
2238 SecPolicyAddBasicX509Options(options
);
2239 SecPolicyAddAppleAnchorOptions(options
);
2241 // Require the profile signing EKU
2242 add_eku(options
, &oidAppleExtendedKeyUsageProfileSigning
);
2244 require(result
= SecPolicyCreate(kSecPolicyOIDAppleProfileSigner
, options
), errOut
);
2247 CFReleaseSafe(options
);
2252 SecPolicyRef
SecPolicyCreateQAConfigurationProfileSigner(void)
2254 SecPolicyRef result
= NULL
;
2255 CFMutableDictionaryRef options
= NULL
;
2256 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2257 &kCFTypeDictionaryKeyCallBacks
,
2258 &kCFTypeDictionaryValueCallBacks
), errOut
);
2260 SecPolicyAddBasicX509Options(options
);
2261 SecPolicyAddAppleAnchorOptions(options
);
2263 // Require the QA profile signing EKU
2264 add_eku(options
, &oidAppleExtendedKeyUsageQAProfileSigning
);
2266 require(result
= SecPolicyCreate(kSecPolicyOIDAppleQAProfileSigner
, options
), errOut
);
2269 CFReleaseSafe(options
);
2273 SecPolicyRef
SecPolicyCreateOSXProvisioningProfileSigning(void)
2275 SecPolicyRef result
= NULL
;
2276 CFMutableDictionaryRef options
= NULL
;
2277 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2278 &kCFTypeDictionaryKeyCallBacks
,
2279 &kCFTypeDictionaryValueCallBacks
), errOut
);
2280 // Require valid chain from the Apple root
2281 SecPolicyAddBasicX509Options(options
);
2282 SecPolicyAddAppleAnchorOptions(options
);
2284 // Require provisioning profile leaf marker OID (1.2.840.113635.100.4.11)
2285 add_leaf_marker(options
, &oidAppleCertExtOSXProvisioningProfileSigning
);
2287 // Require intermediate marker OID (1.2.840.113635.100.6.2.1)
2288 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleWWDR
);
2290 // Require key usage that allows signing
2291 add_ku(options
, kSecKeyUsageDigitalSignature
);
2293 // Ensure that revocation is checked (OCSP)
2294 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kCFBooleanFalse
);
2296 require(result
= SecPolicyCreate(kSecPolicyOIDAppleOSXProvisioningProfileSigning
, options
), errOut
);
2299 CFReleaseSafe(options
);
2304 SecPolicyRef
SecPolicyCreateOTAPKISigner(void)
2306 SecPolicyRef result
= NULL
;
2307 CFMutableDictionaryRef options
= NULL
;
2308 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2309 &kCFTypeDictionaryKeyCallBacks
,
2310 &kCFTypeDictionaryValueCallBacks
), errOut
);
2311 SecPolicyAddBasicX509Options(options
);
2313 SecPolicyAddAnchorSHA1Options(options
, kApplePKISettingsAuthority
);
2314 require(SecPolicyAddChainLengthOptions(options
, 2), errOut
);
2316 require(result
= SecPolicyCreate(kSecPolicyOIDAppleOTAPKIAssetSigner
, options
), errOut
);
2319 CFReleaseSafe(options
);
2325 SecPolicyRef
SecPolicyCreateTestOTAPKISigner(void)
2327 SecPolicyRef result
= NULL
;
2328 CFMutableDictionaryRef options
= NULL
;
2329 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2330 &kCFTypeDictionaryKeyCallBacks
,
2331 &kCFTypeDictionaryValueCallBacks
), errOut
);
2332 SecPolicyAddBasicX509Options(options
);
2334 SecPolicyAddAnchorSHA1Options(options
, kAppleTestPKISettingsAuthority
);
2335 require(SecPolicyAddChainLengthOptions(options
, 2), errOut
);
2337 require(result
= SecPolicyCreate(kSecPolicyOIDAppleTestOTAPKIAssetSigner
, options
), errOut
);
2340 CFReleaseSafe(options
);
2345 @function SecPolicyCreateAppleSMPEncryption
2346 @abstract Check for intermediate certificate 'Apple System Integration CA - G3' by name,
2347 and root certificate 'Apple Root CA - G3' by hash.
2348 Leaf cert must have Key Encipherment usage.
2349 Leaf cert must have Apple SMP Encryption marker OID (1.2.840.113635.100.6.30).
2350 Intermediate must have marker OID (1.2.840.113635.100.6.2.13).
2352 SecPolicyRef
SecPolicyCreateAppleSMPEncryption(void)
2354 SecPolicyRef result
= NULL
;
2355 CFMutableDictionaryRef options
= NULL
;
2356 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2357 &kCFTypeDictionaryKeyCallBacks
,
2358 &kCFTypeDictionaryValueCallBacks
), errOut
);
2359 SecPolicyAddBasicCertOptions(options
);
2361 SecPolicyAddAnchorSHA1Options(options
, kAppleRootCA_ECC_SHA1
);
2362 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2364 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2365 CFSTR("Apple System Integration CA - G3"));
2367 // Check that leaf has extension with "Apple SMP Encryption" oid (1.2.840.113635.100.6.30)
2368 add_leaf_marker(options
, &oidAppleCertExtAppleSMPEncryption
);
2370 // Check that intermediate has extension (1.2.840.113635.100.6.2.13)
2371 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleSystemIntgG3
);
2373 add_ku(options
, kSecKeyUsageKeyEncipherment
);
2375 // Ensure that revocation is checked (OCSP)
2376 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kCFBooleanFalse
);
2378 require(result
= SecPolicyCreate(kSecPolicyAppleSMPEncryption
, options
), errOut
);
2381 CFReleaseSafe(options
);
2386 @function SecPolicyCreateTestAppleSMPEncryption
2387 @abstract Check for intermediate certificate 'Test Apple System Integration CA - ECC' by name,
2388 and root certificate 'Test Apple Root CA - ECC' by hash.
2389 Leaf cert must have Key Encipherment usage. Other checks TBD.
2391 SecPolicyRef
SecPolicyCreateTestAppleSMPEncryption(void)
2393 SecPolicyRef result
= NULL
;
2394 CFMutableDictionaryRef options
= NULL
;
2395 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2396 &kCFTypeDictionaryKeyCallBacks
,
2397 &kCFTypeDictionaryValueCallBacks
), errOut
);
2398 SecPolicyAddBasicCertOptions(options
);
2400 SecPolicyAddAnchorSHA1Options(options
, kTestAppleRootCA_ECC_SHA1
);
2401 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2403 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2404 CFSTR("Test Apple System Integration CA - ECC"));
2406 add_ku(options
, kSecKeyUsageKeyEncipherment
);
2408 // Ensure that revocation is checked (OCSP)
2409 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kCFBooleanFalse
);
2411 require(result
= SecPolicyCreate(kSecPolicyAppleTestSMPEncryption
, options
), errOut
);
2414 CFReleaseSafe(options
);
2419 SecPolicyRef
SecPolicyCreateAppleIDValidationRecordSigningPolicy(void)
2421 SecPolicyRef result
= NULL
;
2422 CFMutableDictionaryRef options
= NULL
;
2423 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2424 &kCFTypeDictionaryKeyCallBacks
,
2425 &kCFTypeDictionaryValueCallBacks
), errOut
);
2427 //Leaf appears to be a SSL only cert, so policy should expand on that policy
2428 SecPolicyAddBasicX509Options(options
);
2430 // Apple CA anchored
2431 require(SecPolicyAddAppleAnchorOptions(options
), errOut
);
2433 // Check for an extension with " Apple ID Validation Record Signing" oid (1.2.840.113635.100.6.25)
2434 add_leaf_marker(options
, &oidAppleCertExtensionAppleIDRecordValidationSigning
);
2436 // and validate that intermediate has extension
2437 // Application Integration Intermediate Certificate (1.2.840.113635.100.6.2.3)
2438 // and also validate that intermediate has extension
2439 // System Integration 2 Intermediate Certificate (1.2.840.113635.100.6.2.10)
2440 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleID
);
2441 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleSystemIntg2
);
2443 // Ensure that revocation is checked (OCSP)
2444 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kCFBooleanFalse
);
2446 require(result
= SecPolicyCreate(kSecPolicyOIDAppleIDValidationRecordSigningPolicy
, options
), errOut
);
2449 CFReleaseSafe(options
);
2454 allowUATRoot(bool allowNonProd
, CFStringRef service
, CFDictionaryRef context
)
2456 bool UATAllowed
= false;
2457 if (SecIsInternalRelease() || allowNonProd
) {
2458 CFStringRef setting
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("AppleServerAuthenticationAllowUAT%@"), service
);
2459 CFTypeRef value
= NULL
;
2460 require(setting
, fail
);
2463 CFDictionaryGetValueIfPresent(context
, setting
, &value
) &&
2465 CFBooleanGetValue(value
))
2470 if (CFPreferencesGetAppBooleanValue(setting
, CFSTR("com.apple.Security"), NULL
)) {
2480 requirePinning(bool allowNonProd
, CFStringRef service
)
2482 bool pinningRequired
= true;
2484 if (SecIsInternalRelease() || allowNonProd
) {
2485 CFStringRef setting
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("AppleServerAuthenticationNoPinning%@"), service
);
2486 require(setting
, fail
);
2487 if (CFPreferencesGetAppBooleanValue(setting
, CFSTR("com.apple.Security"), NULL
))
2488 pinningRequired
= false;
2492 return pinningRequired
;
2496 @function SecPolicyCreateAppleServerAuthCommon
2497 @abstract Generic policy for server authentication Sub CAs
2499 Allows control for both if pinning is required at all and if UAT environments should be added
2500 to the trust policy.
2502 No pinning is for developer/QA that needs to use proxy to debug the protocol, while UAT
2503 environment is for QA/internal developer that have no need allow fake servers.
2505 Both the noPinning and allowUAT are gated on that you run on internal hardware.
2510 SecPolicyCreateAppleServerAuthCommon(CFStringRef hostname
,
2511 CFDictionaryRef __unused context
,
2512 CFStringRef service
, bool allowNonProd
,
2513 const DERItem
*leafMarkerOID
,
2514 const DERItem
*UATLeafMarkerOID
)
2516 CFMutableDictionaryRef appleAnchorOptions
= NULL
;
2517 CFMutableDictionaryRef options
= NULL
;
2518 SecPolicyRef result
= NULL
;
2519 CFDataRef oid
= NULL
, uatoid
= NULL
;
2521 options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0, &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
2522 require(options
, errOut
);
2524 SecPolicyAddBasicX509Options(options
);
2526 CFDictionaryAddValue(options
, kSecPolicyCheckSSLHostname
, hostname
);
2528 CFDictionaryAddValue(options
, kSecPolicyCheckBlackListedLeaf
, kCFBooleanTrue
);
2529 CFDictionaryAddValue(options
, kSecPolicyCheckGrayListedLeaf
, kCFBooleanTrue
);
2531 add_eku(options
, &oidExtendedKeyUsageServerAuth
);
2533 if (requirePinning(allowNonProd
, service
)) {
2534 bool allowUAT
= allowUATRoot(allowNonProd
, service
, context
);
2537 * Require pinning to the Apple CA's (and if UAT environment,
2538 * include the Apple Test CA's as anchors).
2541 appleAnchorOptions
= CFDictionaryCreateMutableForCFTypes(NULL
);
2542 require(appleAnchorOptions
, errOut
);
2545 CFDictionarySetValue(appleAnchorOptions
,
2546 kSecPolicyAppleAnchorIncludeTestRoots
, kCFBooleanTrue
);
2548 CFDictionarySetValue(appleAnchorOptions
,
2549 kSecPolicyAppleAnchorAllowTestRootsOnProduction
, kCFBooleanTrue
);
2553 add_element(options
, kSecPolicyCheckAnchorApple
, appleAnchorOptions
);
2556 * Check if we also should allow the UAT variant of the leafs
2557 * as some variants of the UAT environment uses that instead
2558 * of the test Apple CA's.
2562 oid
= CFDataCreate(kCFAllocatorDefault
, leafMarkerOID
->data
, leafMarkerOID
->length
);
2563 require(oid
, errOut
);
2565 uatoid
= CFDataCreate(kCFAllocatorDefault
, UATLeafMarkerOID
->data
, UATLeafMarkerOID
->length
);
2566 require(oid
, errOut
);
2568 CFArrayRef array
= CFArrayCreateForCFTypes(NULL
, oid
, uatoid
, NULL
);
2569 require(array
, errOut
);
2571 add_element(options
, kSecPolicyCheckLeafMarkerOid
, array
);
2572 CFReleaseSafe(array
);
2574 add_leaf_marker(options
, leafMarkerOID
);
2577 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleServerAuthentication
);
2581 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kCFBooleanFalse
);
2583 result
= SecPolicyCreate(kSecPolicyOIDSSLServer
, options
);
2584 require(result
, errOut
);
2587 CFReleaseSafe(appleAnchorOptions
);
2588 CFReleaseSafe(options
);
2590 CFReleaseSafe(uatoid
);
2597 @function SecPolicyCreateAppleIDSService
2598 @abstract Ensure we're appropriately pinned to the IDS service (SSL + Apple restrictions)
2600 SecPolicyRef
SecPolicyCreateAppleIDSService(CFStringRef hostname
)
2603 return SecPolicyCreateSSL(true, hostname
);
2605 return SecPolicyCreateAppleServerAuthCommon(hostname
, NULL
, CFSTR("IDS"), false,
2606 &oidAppleCertExtAppleServerAuthenticationIDSProd
,
2607 &oidAppleCertExtAppleServerAuthenticationIDSTest
);
2612 @function SecPolicyCreateAppleIDSService
2613 @abstract Ensure we're appropriately pinned to the IDS service (SSL + Apple restrictions)
2615 SecPolicyRef
SecPolicyCreateAppleIDSServiceContext(CFStringRef hostname
, CFDictionaryRef context
)
2617 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, CFSTR("IDS"), false,
2618 &oidAppleCertExtAppleServerAuthenticationIDSProd
,
2619 &oidAppleCertExtAppleServerAuthenticationIDSTest
);
2623 @function SecPolicyCreateAppleGSService
2624 @abstract Ensure we're appropriately pinned to the GS service
2626 SecPolicyRef
SecPolicyCreateAppleGSService(CFStringRef hostname
, CFDictionaryRef context
)
2628 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, CFSTR("GS"), false,
2629 &oidAppleCertExtAppleServerAuthenticationGS
,
2634 @function SecPolicyCreateApplePushService
2635 @abstract Ensure we're appropriately pinned to the Push service (SSL + Apple restrictions)
2637 SecPolicyRef
SecPolicyCreateApplePushService(CFStringRef hostname
, CFDictionaryRef context
)
2639 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, CFSTR("APN"), false,
2640 &oidAppleCertExtAppleServerAuthenticationAPNProd
,
2641 &oidAppleCertExtAppleServerAuthenticationAPNTest
);
2645 @function SecPolicyCreateApplePPQService
2646 @abstract Ensure we're appropriately pinned to the PPQ service (SSL + Apple restrictions)
2648 SecPolicyRef
SecPolicyCreateApplePPQService(CFStringRef hostname
, CFDictionaryRef context
)
2650 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, CFSTR("PPQ"), false,
2651 &oidAppleCertExtAppleServerAuthenticationPPQProd
,
2652 &oidAppleCertExtAppleServerAuthenticationPPQTest
);
2656 @function SecPolicyCreateAppleAST2Service
2657 @abstract Ensure we're appropriately pinned to the AST2 Diagnostic service (SSL + Apple restrictions)
2659 SecPolicyRef
SecPolicyCreateAppleAST2Service(CFStringRef hostname
, CFDictionaryRef context
)
2661 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, CFSTR("AST2"), true,
2662 &oidAppleCertExtAST2DiagnosticsServerAuthProd
,
2663 &oidAppleCertExtAST2DiagnosticsServerAuthTest
);
2666 /* should use verbatim copy, but since this is the deprecated way, don't care right now */
2667 static const UInt8 entrustSPKIL1C
[kSecPolicySHA256Size
] = {
2668 0x54, 0x5b, 0xf9, 0x35, 0xe9, 0xad, 0xa1, 0xda,
2669 0x11, 0x7e, 0xdc, 0x3c, 0x2a, 0xcb, 0xc5, 0x6f,
2670 0xc0, 0x28, 0x09, 0x6c, 0x0e, 0x24, 0xbe, 0x9b,
2671 0x38, 0x94, 0xbe, 0x52, 0x2d, 0x1b, 0x43, 0xde
2675 @function SecPolicyCreateApplePushServiceLegacy
2676 @abstract Ensure we're appropriately pinned to the Push service (via Entrust)
2678 SecPolicyRef
SecPolicyCreateApplePushServiceLegacy(CFStringRef hostname
)
2680 CFMutableDictionaryRef options
= NULL
;
2681 SecPolicyRef result
= NULL
;
2682 CFDataRef digest
= NULL
;
2684 digest
= CFDataCreateWithBytesNoCopy(kCFAllocatorDefault
, entrustSPKIL1C
, sizeof(entrustSPKIL1C
), kCFAllocatorNull
);
2685 require(digest
, errOut
);
2687 options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0, &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
2688 require(options
, errOut
);
2690 SecPolicyAddBasicX509Options(options
);
2692 CFDictionaryAddValue(options
, kSecPolicyCheckSSLHostname
, hostname
);
2694 CFDictionaryAddValue(options
, kSecPolicyCheckBlackListedLeaf
, kCFBooleanTrue
);
2695 CFDictionaryAddValue(options
, kSecPolicyCheckGrayListedLeaf
, kCFBooleanTrue
);
2697 CFDictionaryAddValue(options
, kSecPolicyCheckIntermediateSPKISHA256
, digest
);
2699 add_eku(options
, &oidExtendedKeyUsageServerAuth
);
2701 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kCFBooleanFalse
);
2703 result
= SecPolicyCreate(kSecPolicyOIDSSLServer
, options
);
2704 require(result
, errOut
);
2707 CFReleaseSafe(digest
);
2708 CFReleaseSafe(options
);
2713 @function SecPolicyCreateAppleMMCSService
2714 @abstract Ensure we're appropriately pinned to the IDS service (SSL + Apple restrictions)
2716 SecPolicyRef
SecPolicyCreateAppleMMCSService(CFStringRef hostname
, CFDictionaryRef __unused context
)
2718 return SecPolicyCreateSSL(true, hostname
);
2722 @function SecPolicyCreateAppleSSLService
2723 @abstract Ensure we're appropriately pinned to an Apple server (SSL + Apple restrictions)
2725 SecPolicyRef
SecPolicyCreateAppleSSLService(CFStringRef hostname
)
2727 // SSL server, pinned to an Apple intermediate
2728 SecPolicyRef policy
= SecPolicyCreateSSL(true, hostname
);
2729 CFMutableDictionaryRef options
= NULL
;
2730 require(policy
, errOut
);
2732 // change options for SSL policy evaluation
2733 require((options
=(CFMutableDictionaryRef
)policy
->_options
) != NULL
, errOut
);
2735 // Apple CA anchored
2736 require(SecPolicyAddAppleAnchorOptions(options
), errOut
);
2738 // Check leaf for Apple Server Authentication marker oid (1.2.840.113635.100.6.27.1)
2739 add_leaf_marker(options
, &oidAppleCertExtAppleServerAuthentication
);
2741 // Check intermediate for Apple Server Authentication intermediate marker (1.2.840.113635.100.6.2.12)
2742 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleServerAuthentication
);
2744 // Ensure that revocation is checked (OCSP only)
2745 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kCFBooleanFalse
);
2750 CFReleaseSafe(options
);
2751 CFReleaseSafe(policy
);
2756 @function SecPolicyCreateApplePPQSigning
2757 @abstract Check for intermediate certificate 'Apple System Integration 2 Certification Authority' by name,
2759 Leaf cert must have Digital Signature usage.
2760 Leaf cert must have Apple PPQ Signing marker OID (1.2.840.113635.100.6.38.2).
2761 Intermediate must have marker OID (1.2.840.113635.100.6.2.10).
2763 SecPolicyRef
SecPolicyCreateApplePPQSigning(void)
2765 SecPolicyRef result
= NULL
;
2766 CFMutableDictionaryRef options
= NULL
;
2767 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2768 &kCFTypeDictionaryKeyCallBacks
,
2769 &kCFTypeDictionaryValueCallBacks
), errOut
);
2770 SecPolicyAddBasicCertOptions(options
);
2772 SecPolicyAddAppleAnchorOptions(options
);
2773 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2775 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2776 CFSTR("Apple System Integration 2 Certification Authority"));
2778 // Check that leaf has extension with "Apple PPQ Signing" prod oid (1.2.840.113635.100.6.38.2)
2779 add_leaf_marker(options
, &oidAppleCertExtApplePPQSigningProd
);
2781 // Check that intermediate has extension (1.2.840.113635.100.6.2.10)
2782 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleSystemIntg2
);
2784 add_ku(options
, kSecKeyUsageDigitalSignature
);
2786 require(result
= SecPolicyCreate(kSecPolicyApplePPQSigning
, options
), errOut
);
2789 CFReleaseSafe(options
);
2794 @function SecPolicyCreateTestApplePPQSigning
2795 @abstract Check for intermediate certificate 'Apple System Integration 2 Certification Authority' by name,
2797 Leaf cert must have Digital Signature usage.
2798 Leaf cert must have Apple PPQ Signing Test marker OID (1.2.840.113635.100.6.38.1).
2799 Intermediate must have marker OID (1.2.840.113635.100.6.2.10).
2801 SecPolicyRef
SecPolicyCreateTestApplePPQSigning(void)
2803 SecPolicyRef result
= NULL
;
2804 CFMutableDictionaryRef options
= NULL
;
2805 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2806 &kCFTypeDictionaryKeyCallBacks
,
2807 &kCFTypeDictionaryValueCallBacks
), errOut
);
2808 SecPolicyAddBasicCertOptions(options
);
2810 SecPolicyAddAppleAnchorOptions(options
);
2811 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2813 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2814 CFSTR("Apple System Integration 2 Certification Authority"));
2816 // Check that leaf has extension with "Apple PPQ Signing" test oid (1.2.840.113635.100.6.38.1)
2817 add_leaf_marker(options
, &oidAppleCertExtApplePPQSigningTest
);
2819 // Check that intermediate has extension (1.2.840.113635.100.6.2.10)
2820 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleSystemIntg2
);
2822 add_ku(options
, kSecKeyUsageDigitalSignature
);
2824 require(result
= SecPolicyCreate(kSecPolicyAppleTestPPQSigning
, options
), errOut
);
2827 CFReleaseSafe(options
);
2831 @function SecPolicyCreateAppleTimeStamping
2832 @abstract Check for RFC3161 timestamping EKU.
2834 SecPolicyRef
SecPolicyCreateAppleTimeStamping(void)
2836 SecPolicyRef result
= NULL
;
2837 CFMutableDictionaryRef options
= NULL
;
2838 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2839 &kCFTypeDictionaryKeyCallBacks
,
2840 &kCFTypeDictionaryValueCallBacks
), errOut
);
2842 SecPolicyAddBasicX509Options(options
);
2844 /* Require id-kp-timeStamping extendedKeyUsage to be present. */
2845 add_eku(options
, &oidExtendedKeyUsageTimeStamping
);
2847 require(result
= SecPolicyCreate(kSecPolicyOIDAppleTimeStamping
, options
), errOut
);
2850 CFReleaseSafe(options
);
2855 @function SecPolicyCreateAppleATVAppSigning
2856 @abstract Check for intermediate certificate 'Apple Worldwide Developer Relations Certification Authority' by name,
2858 Leaf cert must have Digital Signature usage.
2859 Leaf cert must have Apple ATV App Signing marker OID (1.2.840.113635.100.6.1.24).
2860 Leaf cert must have 'Apple TVOS Application Signing' common name.
2862 SecPolicyRef
SecPolicyCreateAppleATVAppSigning(void)
2864 SecPolicyRef result
= NULL
;
2865 CFMutableDictionaryRef options
= NULL
;
2866 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2867 &kCFTypeDictionaryKeyCallBacks
,
2868 &kCFTypeDictionaryValueCallBacks
), errOut
);
2869 SecPolicyAddBasicCertOptions(options
);
2871 require(SecPolicyAddAppleAnchorOptions(options
), errOut
);
2872 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2874 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2875 CFSTR("Apple Worldwide Developer Relations Certification Authority"));
2876 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
,
2877 CFSTR("Apple TVOS Application Signing"));
2879 // Check that leaf has extension with "Apple ATV App Signing" prod oid (1.2.840.113635.100.6.1.24)
2880 add_leaf_marker(options
, &oidAppleCertExtATVAppSigningProd
);
2882 add_ku(options
, kSecKeyUsageDigitalSignature
);
2884 require(result
= SecPolicyCreate(kSecPolicyAppleATVAppSigning
, options
), errOut
);
2887 CFReleaseSafe(options
);
2892 @function SecPolicyCreateTestAppleATVAppSigning
2893 @abstract Check for intermediate certificate 'Apple Worldwide Developer Relations Certification Authority' by name,
2895 Leaf cert must have Digital Signature usage.
2896 Leaf cert must have Apple ATV App Signing Test marker OID (1.2.840.113635.100.6.1.24.1).
2897 Leaf cert must have 'TEST Apple TVOS Application Signing TEST' common name.
2899 SecPolicyRef
SecPolicyCreateTestAppleATVAppSigning(void)
2901 SecPolicyRef result
= NULL
;
2902 CFMutableDictionaryRef options
= NULL
;
2903 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2904 &kCFTypeDictionaryKeyCallBacks
,
2905 &kCFTypeDictionaryValueCallBacks
), errOut
);
2906 SecPolicyAddBasicCertOptions(options
);
2908 require(SecPolicyAddAppleAnchorOptions(options
), errOut
);
2909 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2911 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2912 CFSTR("Apple Worldwide Developer Relations Certification Authority"));
2913 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
,
2914 CFSTR("TEST Apple TVOS Application Signing TEST"));
2916 // Check that leaf has extension with "Apple ATV App Signing" test oid (1.2.840.113635.100.6.1.24.1)
2917 add_leaf_marker(options
, &oidAppleCertExtATVAppSigningTest
);
2919 add_ku(options
, kSecKeyUsageDigitalSignature
);
2921 require(result
= SecPolicyCreate(kSecPolicyAppleTestATVAppSigning
, options
), errOut
);
2924 CFReleaseSafe(options
);
2929 @function SecPolicyCreateApplePayIssuerEncryption
2930 @abstract Check for intermediate certificate 'Apple Worldwide Developer Relations CA - G2' by name,
2931 and ECC apple anchor.
2932 Leaf cert must have Key Encipherment and Key Agreement usage.
2933 Leaf cert must have Apple Pay Issuer Encryption marker OID (1.2.840.113635.100.6.39).
2935 SecPolicyRef
SecPolicyCreateApplePayIssuerEncryption(void)
2937 SecPolicyRef result
= NULL
;
2938 CFMutableDictionaryRef options
= NULL
;
2939 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2940 &kCFTypeDictionaryKeyCallBacks
,
2941 &kCFTypeDictionaryValueCallBacks
), errOut
);
2942 SecPolicyAddBasicCertOptions(options
);
2944 require(SecPolicyAddAnchorSHA1Options(options
, kAppleRootCA_ECC_SHA1
), errOut
);
2945 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2947 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2948 CFSTR("Apple Worldwide Developer Relations CA - G2"));
2950 // Check that leaf has extension with "Apple Pay Issuer Encryption" oid (1.2.840.113635.100.6.39)
2951 add_leaf_marker(options
, &oidAppleCertExtCryptoServicesExtEncryption
);
2953 add_ku(options
, kSecKeyUsageKeyEncipherment
);
2955 require(result
= SecPolicyCreate(kSecPolicyApplePayIssuerEncryption
, options
), errOut
);
2958 CFReleaseSafe(options
);
2963 @function SecPolicyCreateAppleATVVPNProfileSigning
2964 @abstract Check for leaf marker OID 1.2.840.113635.100.6.43,
2965 intermediate marker OID 1.2.840.113635.100.6.2.10,
2966 chains to Apple Root CA, path length 3
2968 SecPolicyRef
SecPolicyCreateAppleATVVPNProfileSigning(void)
2970 SecPolicyRef result
= NULL
;
2971 CFMutableDictionaryRef options
= NULL
;
2972 CFMutableDictionaryRef appleAnchorOptions
= NULL
;
2973 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2974 &kCFTypeDictionaryKeyCallBacks
,
2975 &kCFTypeDictionaryValueCallBacks
), errOut
);
2977 SecPolicyAddBasicCertOptions(options
);
2979 // Require pinning to the Apple CAs (including test CA for internal releases)
2980 appleAnchorOptions
= CFDictionaryCreateMutableForCFTypes(NULL
);
2981 require(appleAnchorOptions
, errOut
);
2983 if (SecIsInternalRelease()) {
2984 CFDictionarySetValue(appleAnchorOptions
,
2985 kSecPolicyAppleAnchorIncludeTestRoots
, kCFBooleanTrue
);
2988 add_element(options
, kSecPolicyCheckAnchorApple
, appleAnchorOptions
);
2990 // Cert chain length 3
2991 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2993 // Check leaf for Apple ATV VPN Profile Signing OID (1.2.840.113635.100.6.43)
2994 add_leaf_marker(options
, &oidAppleCertExtATVVPNProfileSigning
);
2996 // Check intermediate for Apple System Integration 2 CA intermediate marker (1.2.840.113635.100.6.2.10)
2997 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleSystemIntg2
);
2999 // Ensure that revocation is checked (OCSP only)
3000 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kCFBooleanFalse
);
3002 require(result
= SecPolicyCreate(kSecPolicyAppleATVVPNProfileSigning
, options
), errOut
);
3005 CFReleaseSafe(options
);
3006 CFReleaseSafe(appleAnchorOptions
);
3010 SecPolicyRef
SecPolicyCreateAppleHomeKitServerAuth(CFStringRef hostname
) {
3011 CFMutableDictionaryRef appleAnchorOptions
= NULL
;
3012 CFMutableDictionaryRef options
= NULL
;
3013 SecPolicyRef result
= NULL
;
3014 CFDataRef oid
= NULL
;
3016 options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0, &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
3017 require(options
, errOut
);
3019 SecPolicyAddBasicX509Options(options
);
3021 CFDictionaryAddValue(options
, kSecPolicyCheckSSLHostname
, hostname
);
3023 add_eku(options
, &oidExtendedKeyUsageServerAuth
);
3025 if (requirePinning(false, CFSTR("HomeKit"))) {
3026 bool allowUAT
= allowUATRoot(false, CFSTR("HomeKit"), NULL
);
3028 // Cert chain length 3
3029 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3031 // Apple anchors, allowing test anchors for internal releases properly configured
3032 appleAnchorOptions
= CFDictionaryCreateMutableForCFTypes(NULL
);
3033 require(appleAnchorOptions
, errOut
);
3035 CFDictionarySetValue(appleAnchorOptions
,
3036 kSecPolicyAppleAnchorIncludeTestRoots
, kCFBooleanTrue
);
3038 add_element(options
, kSecPolicyCheckAnchorApple
, appleAnchorOptions
);
3040 add_leaf_marker(options
, &oidAppleCertExtHomeKitServerAuth
);
3042 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleHomeKitServerCA
);
3046 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kCFBooleanTrue
);
3048 result
= SecPolicyCreate(kSecPolicyOIDAppleHomeKitServerAuth
, options
);
3049 require(result
, errOut
);
3052 CFReleaseSafe(appleAnchorOptions
);
3053 CFReleaseSafe(options
);