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");
287 /* Policies will now change to multiple categories of checks.
289 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.
290 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.
292 kSecPolicySLCheck Static Subscriber Certificate Checks
293 kSecPolicySICheck Static Subsidiary CA Checks
294 kSecPolicySACheck Static Anchor Checks
296 kSecPolicyDLCheck Dynamic Subscriber Certificate Checks
297 kSecPolicyDICheck Dynamic Subsidiary CA Checks
298 kSecPolicyDACheck Dynamic Anchor Checks ? not yet needed other than to
299 possibly exclude in a exception template (but those should still be per
300 certificate --- i.o.w. exceptions (or a database backed multiple role/user
301 trust store of some sort) and policies are 2 different things and this
302 text is about policies.
304 All static checks are only allowed to consider the certificate in isolation,
305 just given the position in the chain or the cert (leaf, intermidate, root).
306 dynamic checks can make determinations about the chain as a whole.
308 Static Subscriber Certificate Checks will be done up front before the
309 chainbuilder is even instantiated. If they fail and details aren't required
310 by the client (if no exceptions were present for this certificate) we could
311 short circuit fail the evaluation.
312 IDEA: These checks can dynamically add new checks...[needs work]
313 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
314 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
315 equivalent subtree from that level down. So SSL has EV as a subpolicy, but
316 EV dynamically enables the ocsp or crl or dcrl or any combination thereof subpolicies.
318 Static Subsidiary CA Checks will be used by the chain-builder to choose the
319 best parents to evaluate first. This feature is currently already implemented
320 but with a hardcoded is_valid(verifyTime) check. Instead we will evaluate all
321 Static Subsidiary CA Checks. The results of these checks for purposes of
322 generating details could be cached in the SecCertificatePathRefs themselves, or we can short circuit fail and recalc details on demand later.
324 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.
326 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.
328 Dynamic Subsidiary CA Checks might not be needed to have custom
329 implementations, since they are all done as part of the rfc5280 checks now.
330 This assumes that checks like issuer common name includes 'foo' are
331 implmented as Static Subscriber Certificate Checks instead.
333 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.
336 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.
338 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.
340 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.
342 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.
344 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.
346 We need to remember the best successful chain we find, where best is defined by: satisfies as many optional policies as possible.
348 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.
350 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.
352 Example sectrust operation in psuedocode:
356 new builder(verifyTime, certificates, anchors, anchorsOnly, policies);
357 chain = builder.subscriber_only_chain;
358 foreach (policy in policies{kSecPolicySLCheck}) {
359 foreach(check in policy)
360 SecPolicyRunCheck(builder, chain, check, details);
361 foreach (subpolicy in policy) {
362 check_policy(builder, chain, subpolicy, details{subpolicy.name})
364 propagate_subpolicy_results(builder, chain, details);
366 while (chain = builder.next) {
367 for (depth = 0; p_d = policies.at_depth(depth),
368 d_p_d = dynamic_policies.at_depth(depth), p_d || d_p_d; ++depth)
370 // Modify SecPathBuilderIsPartial() to
371 // run builder_check(buildier, policies, kSecPolicySICheck) instead
372 // of SecCertificateIsValid. Also rename considerExpired to
373 // considerSIFailures.
374 foreach (policy in p_d) {
375 check_policy(builder, chain, policy, kSecPolicySICheck, depth);
377 /// Recalculate since the static checks might have added new dynamic
379 d_p_d = dynamic_policies.at_depth(depth);
380 foreach (policy in d_p_d) {
381 check_policy(builder, chain, policy, kSecPolicySICheck, depth);
383 if (chain.is_anchored) {
384 foreach (policy in p_d) {
385 check_policy(builder, chain, policy, kSecPolicySACheck, depth);
387 foreach (policy in d_p_d) {
388 check_policy(builder, chain, policy, kSecPolicySACheck, depth);
390 foreach (policy in p_d) {
391 check_policy(builder, chain, policy, kSecPolicyDACheck, depth);
393 foreach (policy in d_p_d) {
394 check_policy(builder, chain, policy, kSecPolicyDACheck, depth);
397 foreach (policy in policies) {
398 check_policy(builder, chain, policy, kSecPolicySACheck, depth);
399 check_policy(builder, chain, policy, kSecPolicyDACheck, depth);
401 foreach (policy in policies{kSecPolicySDCheck}) {
406 check_policy(builder, chain, policy, check_class, details, depth) {
408 foreach(check in policy{check_class}) {
409 SecPolicyRunCheck(builder, chain, check, details);
413 foreach (subpolicy in policy) {
414 if (!check_policy(builder, chain, subpolicy, check_class,
415 details{subpolicy.name}) && subpolicy.is_required, depth)
419 propagate_subpolicy_results(builder, chain, details);
426 #define kSecPolicySHA1Size 20
427 #define kSecPolicySHA256Size 32
428 const UInt8 kAppleCASHA1
[kSecPolicySHA1Size
] = {
429 0x61, 0x1E, 0x5B, 0x66, 0x2C, 0x59, 0x3A, 0x08, 0xFF, 0x58,
430 0xD1, 0x4A, 0xE2, 0x24, 0x52, 0xD1, 0x98, 0xDF, 0x6C, 0x60
433 __unused
static const UInt8 kAppleTESTCASHA1
[kSecPolicySHA1Size
] = {
434 0xbc, 0x30, 0x55, 0xc8, 0xc8, 0xd3, 0x48, 0x3f, 0xf4, 0x8d,
435 0xfe, 0x3d, 0x51, 0x75, 0x31, 0xc9, 0xf4, 0xd7, 0x4a, 0xf7
438 static const UInt8 kITMSCASHA1
[kSecPolicySHA1Size
] = {
439 0x1D, 0x33, 0x42, 0x46, 0x8B, 0x10, 0xBD, 0xE6, 0x45, 0xCE,
440 0x44, 0x6E, 0xBB, 0xE8, 0xF5, 0x03, 0x5D, 0xF8, 0x32, 0x22
443 static const UInt8 kFactoryDeviceCASHA1
[kSecPolicySHA1Size
] = {
444 0xef, 0x68, 0x73, 0x17, 0xa4, 0xf8, 0xf9, 0x4b, 0x7b, 0x21,
445 0xe2, 0x2f, 0x09, 0x8f, 0xfd, 0x6a, 0xae, 0xc0, 0x0d, 0x63
448 static const UInt8 kApplePKISettingsAuthority
[kSecPolicySHA1Size
] = {
449 0x1D, 0x0C, 0xBA, 0xAD, 0x17, 0xFD, 0x7E, 0x9E, 0x9F, 0xF1,
450 0xC9, 0xA2, 0x66, 0x79, 0x60, 0x00, 0x8B, 0xAE, 0x70, 0xB8
453 static const UInt8 kAppleTestPKISettingsAuthority
[kSecPolicySHA1Size
] = {
454 0xDB, 0xBA, 0x25, 0x0B, 0xD8, 0x62, 0x71, 0x87, 0x54, 0x7E,
455 0xD7, 0xEF, 0x11, 0x94, 0x7E, 0x82, 0xE6, 0xD8, 0x1C, 0x9A
458 static const UInt8 kTestAppleRootCA_ECC_SHA1
[kSecPolicySHA1Size
] = {
459 0x62, 0x0A, 0xED, 0x83, 0xD2, 0x97, 0x4A, 0x77, 0x56, 0x33,
460 0x83, 0xBE, 0xDB, 0xF9, 0xA1, 0xBD, 0x5F, 0xFE, 0x55, 0x7B
463 static const UInt8 kAppleRootCA_ECC_SHA1
[kSecPolicySHA1Size
] = {
464 0xB5, 0x2C, 0xB0, 0x2F, 0xD5, 0x67, 0xE0, 0x35, 0x9F, 0xE8,
465 0xFA, 0x4D, 0x4C, 0x41, 0x03, 0x79, 0x70, 0xFE, 0x01, 0xB0
470 /********************************************************
471 ****************** SecPolicy object ********************
472 ********************************************************/
474 static void SecPolicyDestroy(CFTypeRef cf
) {
475 SecPolicyRef policy
= (SecPolicyRef
) cf
;
476 CFRelease(policy
->_oid
);
477 CFRelease(policy
->_options
);
480 static Boolean
SecPolicyCompare(CFTypeRef cf1
, CFTypeRef cf2
) {
481 SecPolicyRef policy1
= (SecPolicyRef
) cf1
;
482 SecPolicyRef policy2
= (SecPolicyRef
) cf2
;
483 return CFEqual(policy1
->_oid
, policy2
->_oid
) &&
484 CFEqual(policy1
->_options
, policy2
->_options
);
487 static CFHashCode
SecPolicyHash(CFTypeRef cf
) {
488 SecPolicyRef policy
= (SecPolicyRef
) cf
;
490 return CFHash(policy
->_oid
) + CFHash(policy
->_options
);
493 static CFStringRef
SecPolicyCopyFormatDescription(CFTypeRef cf
, CFDictionaryRef formatOptions
) {
494 SecPolicyRef policy
= (SecPolicyRef
) cf
;
495 CFMutableStringRef desc
= CFStringCreateMutable(kCFAllocatorDefault
, 0);
496 CFStringRef typeStr
= CFCopyTypeIDDescription(CFGetTypeID(cf
));
497 CFStringAppendFormat(desc
, NULL
,
498 CFSTR("<%@: oid: %@ options %@"), typeStr
,
499 policy
->_oid
, policy
->_options
);
501 CFStringAppend(desc
, CFSTR(" >"));
506 /* SecPolicy API functions. */
507 CFGiblisWithHashFor(SecPolicy
);
509 /* AUDIT[securityd](done):
510 oid (ok) is a caller provided string, only its cf type has been checked.
511 options is a caller provided dictionary, only its cf type has been checked.
513 SecPolicyRef
SecPolicyCreate(CFStringRef oid
, CFDictionaryRef options
) {
514 SecPolicyRef result
= NULL
;
516 require(oid
, errOut
);
517 require(options
, errOut
);
519 (SecPolicyRef
)_CFRuntimeCreateInstance(kCFAllocatorDefault
,
520 SecPolicyGetTypeID(),
521 sizeof(struct __SecPolicy
) - sizeof(CFRuntimeBase
), 0), errOut
);
526 result
->_options
= options
;
532 SecPolicyRef
SecPolicyCreateWithProperties(CFTypeRef policyIdentifier
,
533 CFDictionaryRef properties
) {
534 // Creates a policy reference for a given policy object identifier.
535 // If policy-specific parameters can be supplied (e.g. hostname),
536 // attempt to obtain from input properties dictionary.
537 // Returns NULL if the given identifier is unsupported.
539 SecPolicyRef policy
= NULL
;
540 CFStringRef name
= NULL
;
541 CFStringRef teamID
= NULL
;
542 Boolean client
= false;
543 require(policyIdentifier
&& (CFStringGetTypeID() == CFGetTypeID(policyIdentifier
)), errOut
);
546 name
= CFDictionaryGetValue(properties
, kSecPolicyName
);
547 teamID
= CFDictionaryGetValue(properties
, kSecPolicyTeamIdentifier
);
549 CFBooleanRef dictionaryClientValue
;
550 client
= (CFDictionaryGetValueIfPresent(properties
, kSecPolicyClient
, (const void **)&dictionaryClientValue
) &&
551 (dictionaryClientValue
!= NULL
) && CFEqual(kCFBooleanTrue
, dictionaryClientValue
));
554 if (CFEqual(policyIdentifier
, kSecPolicyAppleX509Basic
)) {
555 policy
= SecPolicyCreateBasicX509();
557 else if (CFEqual(policyIdentifier
, kSecPolicyAppleSSL
)) {
558 policy
= SecPolicyCreateSSL(!client
, name
);
560 else if (CFEqual(policyIdentifier
, kSecPolicyAppleEAP
)) {
561 CFArrayRef array
= NULL
;
563 array
= CFArrayCreate(kCFAllocatorDefault
, (const void **)&name
, 1, &kCFTypeArrayCallBacks
);
565 policy
= SecPolicyCreateEAP(!client
, array
);
566 CFReleaseSafe(array
);
568 else if (CFEqual(policyIdentifier
, kSecPolicyApplePackageSigning
)) {
569 policy
= SecPolicyCreateApplePackageSigning();
571 else if (CFEqual(policyIdentifier
, kSecPolicyAppleSWUpdateSigning
)) {
572 policy
= SecPolicyCreateAppleSWUpdateSigning();
574 else if (CFEqual(policyIdentifier
, kSecPolicyAppleIPsec
)) {
575 policy
= SecPolicyCreateIPSec(!client
, name
);
577 else if (CFEqual(policyIdentifier
, kSecPolicyAppleRevocation
)) {
578 policy
= SecPolicyCreateRevocation(kSecRevocationUseAnyAvailableMethod
);
580 else if (CFEqual(policyIdentifier
, kSecPolicyAppleSMIME
)) {
581 policy
= SecPolicyCreateSMIME(kSecSignSMIMEUsage
| kSecAnyEncryptSMIME
, name
);
583 else if (CFEqual(policyIdentifier
, kSecPolicyAppleCodeSigning
)) {
584 policy
= SecPolicyCreateCodeSigning();
586 else if (CFEqual(policyIdentifier
, kSecPolicyAppleTimeStamping
)) {
587 policy
= SecPolicyCreateAppleTimeStamping();
589 else if (CFEqual(policyIdentifier
, kSecPolicyMacAppStoreReceipt
)) {
590 policy
= SecPolicyCreateMacAppStoreReceipt();
592 else if (CFEqual(policyIdentifier
, kSecPolicyAppleIDValidation
)) {
593 policy
= SecPolicyCreateAppleIDAuthorityPolicy();
595 else if (CFEqual(policyIdentifier
, kSecPolicyApplePassbookSigning
)) {
596 policy
= SecPolicyCreatePassbookCardSigner(name
, teamID
);
598 else if (CFEqual(policyIdentifier
, kSecPolicyAppleMobileStore
)) {
599 policy
= SecPolicyCreateMobileStoreSigner();
601 else if (CFEqual(policyIdentifier
, kSecPolicyAppleTestMobileStore
)) {
602 policy
= SecPolicyCreateTestMobileStoreSigner();
604 else if (CFEqual(policyIdentifier
, kSecPolicyAppleEscrowService
)) {
605 policy
= SecPolicyCreateEscrowServiceSigner();
607 else if (CFEqual(policyIdentifier
, kSecPolicyApplePCSEscrowService
)) {
608 policy
= SecPolicyCreatePCSEscrowServiceSigner();
610 else if (CFEqual(policyIdentifier
, kSecPolicyAppleProfileSigner
)) {
611 policy
= SecPolicyCreateConfigurationProfileSigner();
613 else if (CFEqual(policyIdentifier
, kSecPolicyAppleQAProfileSigner
)) {
614 policy
= SecPolicyCreateQAConfigurationProfileSigner();
616 else if (CFEqual(policyIdentifier
, kSecPolicyAppleServerAuthentication
)) {
617 policy
= SecPolicyCreateAppleSSLService(name
);
619 #if TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR
620 else if (CFEqual(policyIdentifier
, kSecPolicyAppleOTAPKISigner
)) {
621 policy
= SecPolicyCreateOTAPKISigner();
623 else if (CFEqual(policyIdentifier
, kSecPolicyAppleTestOTAPKISigner
)) {
624 policy
= SecPolicyCreateTestOTAPKISigner();
626 else if (CFEqual(policyIdentifier
, kSecPolicyAppleIDValidationRecordSigningPolicy
)) {
627 policy
= SecPolicyCreateAppleIDValidationRecordSigningPolicy();
629 else if (CFEqual(policyIdentifier
, kSecPolicyAppleSMPEncryption
)) {
630 policy
= SecPolicyCreateAppleSMPEncryption();
632 else if (CFEqual(policyIdentifier
, kSecPolicyAppleTestSMPEncryption
)) {
633 policy
= SecPolicyCreateTestAppleSMPEncryption();
635 else if (CFEqual(policyIdentifier
, kSecPolicyAppleATVAppSigning
)) {
636 policy
= SecPolicyCreateAppleATVAppSigning();
638 else if (CFEqual(policyIdentifier
, kSecPolicyAppleTestATVAppSigning
)) {
639 policy
= SecPolicyCreateTestAppleATVAppSigning();
642 else if (CFEqual(policyIdentifier
, kSecPolicyApplePPQSigning
)) {
643 policy
= SecPolicyCreateApplePPQSigning();
645 else if (CFEqual(policyIdentifier
, kSecPolicyAppleTestPPQSigning
)) {
646 policy
= SecPolicyCreateTestApplePPQSigning();
648 else if (CFEqual(policyIdentifier
, kSecPolicyApplePayIssuerEncryption
)) {
649 policy
= SecPolicyCreateApplePayIssuerEncryption();
651 else if (CFEqual(policyIdentifier
, kSecPolicyAppleATVVPNProfileSigning
)) {
652 policy
= SecPolicyCreateAppleATVVPNProfileSigning();
654 else if (CFEqual(policyIdentifier
, kSecPolicyAppleAST2DiagnosticsServerAuth
)) {
655 policy
= SecPolicyCreateAppleAST2Service(name
, NULL
);
658 secerror("ERROR: policy \"%@\" is unsupported", policyIdentifier
);
665 CFDictionaryRef
SecPolicyCopyProperties(SecPolicyRef policyRef
) {
666 // Builds and returns a dictionary which the caller must release.
668 #pragma clang diagnostic push
669 #pragma clang diagnostic ignored "-Wnonnull"
670 // After introducing nullability annotations, policyRef is supposed to be nonnull, suppress the warning
671 if (!policyRef
) return NULL
;
672 #pragma clang diagnostic pop
673 CFMutableDictionaryRef properties
= CFDictionaryCreateMutable(NULL
, 0,
674 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
675 #pragma clang diagnostic push
676 #pragma clang diagnostic ignored "-Wnonnull"
677 // 'properties' is nonnull in reality suppress the warning
678 if (!properties
) return NULL
;
679 #pragma clang diagnostic pop
680 CFStringRef oid
= (CFStringRef
) CFRetain(policyRef
->_oid
);
681 CFTypeRef nameKey
= NULL
;
683 // Convert private to public OID if we have one
684 CFStringRef outOid
= oid
;
685 if (CFEqual(oid
, kSecPolicyOIDBasicX509
)) {
686 outOid
= kSecPolicyAppleX509Basic
;
688 else if (CFEqual(oid
, kSecPolicyOIDSSLServer
) ||
689 CFEqual(oid
, kSecPolicyOIDSSLClient
)) {
690 outOid
= kSecPolicyAppleSSL
;
691 nameKey
= kSecPolicyCheckSSLHostname
;
693 else if (CFEqual(oid
, kSecPolicyOIDEAPServer
) ||
694 CFEqual(oid
, kSecPolicyOIDEAPClient
)) {
695 outOid
= kSecPolicyAppleEAP
;
696 nameKey
= kSecPolicyCheckEAPTrustedServerNames
;
698 else if (CFEqual(oid
, kSecPolicyOIDIPSecServer
) ||
699 CFEqual(oid
, kSecPolicyOIDIPSecClient
)) {
700 outOid
= kSecPolicyAppleIPsec
;
701 nameKey
= kSecPolicyCheckSSLHostname
;
703 else if (CFEqual(oid
, kSecPolicyOIDRevocation
)) {
704 outOid
= kSecPolicyAppleRevocation
;
706 else if (CFEqual(oid
, kSecPolicyOIDSMIME
)) {
707 outOid
= kSecPolicyAppleSMIME
;
708 nameKey
= kSecPolicyCheckEmail
;
710 else if (CFEqual(oid
, kSecPolicyOIDCodeSigning
)) {
711 outOid
= kSecPolicyAppleCodeSigning
;
713 else if (CFEqual(oid
, kSecPolicyOIDAppleIDAuthority
)) {
714 outOid
= kSecPolicyAppleIDValidation
;
716 else if (CFEqual(oid
, kSecPolicyOIDApplePassbook
)) {
717 outOid
= kSecPolicyApplePassbookSigning
;
719 else if (CFEqual(oid
, kSecPolicyOIDAppleMobileStore
)) {
720 outOid
= kSecPolicyAppleMobileStore
;
722 else if (CFEqual(oid
, kSecPolicyOIDAppleTestMobileStore
)) {
723 outOid
= kSecPolicyAppleTestMobileStore
;
725 else if (CFEqual(oid
, kSecPolicyOIDAppleEscrowService
)) {
726 outOid
= kSecPolicyAppleEscrowService
;
728 else if (CFEqual(oid
, kSecPolicyOIDApplePCSEscrowService
)) {
729 outOid
= kSecPolicyApplePCSEscrowService
;
731 else if (CFEqual(oid
, kSecPolicyOIDAppleProfileSigner
)) {
732 outOid
= kSecPolicyAppleProfileSigner
;
734 else if (CFEqual(oid
, kSecPolicyOIDAppleQAProfileSigner
)) {
735 outOid
= kSecPolicyAppleQAProfileSigner
;
737 #if TARGET_OS_EMBEDDED
738 else if (CFEqual(oid
, kSecPolicyOIDAppleOTAPKIAssetSigner
)) {
739 outOid
= kSecPolicyAppleOTAPKISigner
;
741 else if (CFEqual(oid
, kSecPolicyOIDAppleTestOTAPKIAssetSigner
)) {
742 outOid
= kSecPolicyAppleTestOTAPKISigner
;
744 else if (CFEqual(oid
, kSecPolicyOIDAppleIDValidationRecordSigningPolicy
)) {
745 outOid
= kSecPolicyAppleIDValidationRecordSigningPolicy
;
747 else if (CFEqual(oid
, kSecPolicyOIDAppleATVAppSigning
)) {
748 outOid
= kSecPolicyAppleATVAppSigning
;
750 else if (CFEqual(oid
, kSecPolicyOIDAppleTestATVAppSigning
)) {
751 outOid
= kSecPolicyAppleTestATVAppSigning
;
754 else if (CFEqual(oid
, kSecPolicyOIDApplePayIssuerEncryption
)) {
755 outOid
= kSecPolicyApplePayIssuerEncryption
;
757 else if (CFEqual(oid
, kSecPolicyOIDAppleOSXProvisioningProfileSigning
)) {
758 outOid
= kSecPolicyAppleOSXProvisioningProfileSigning
;
760 else if (CFEqual(oid
, kSecPolicyOIDAppleATVVPNProfileSigning
)) {
761 outOid
= kSecPolicyAppleATVVPNProfileSigning
;
763 else if (CFEqual(oid
, kSecPolicyOIDAppleAST2Service
)) {
764 outOid
= kSecPolicyAppleAST2DiagnosticsServerAuth
;
768 CFDictionarySetValue(properties
, (const void *)kSecPolicyOid
,
769 (const void *)outOid
);
771 // Set kSecPolicyName if we have one
772 if (nameKey
&& policyRef
->_options
) {
773 CFTypeRef name
= (CFTypeRef
) CFDictionaryGetValue(policyRef
->_options
,
776 CFDictionarySetValue(properties
, (const void *)kSecPolicyName
,
781 // Set kSecPolicyClient
782 if (CFEqual(oid
, kSecPolicyOIDSSLClient
) ||
783 CFEqual(oid
, kSecPolicyOIDIPSecClient
) ||
784 CFEqual(oid
, kSecPolicyOIDEAPClient
)) {
785 CFDictionarySetValue(properties
, (const void *)kSecPolicyClient
,
786 (const void *)kCFBooleanTrue
);
793 static void SecPolicySetOid(SecPolicyRef policy
, CFStringRef oid
) {
794 if (!policy
|| !oid
) return;
795 CFStringRef temp
= policy
->_oid
;
801 CFStringRef
SecPolicyGetOidString(SecPolicyRef policy
) {
805 CFDictionaryRef
SecPolicyGetOptions(SecPolicyRef policy
) {
806 return policy
->_options
;
809 void SecPolicySetOptionsValue(SecPolicyRef policy
, CFStringRef key
, CFTypeRef value
) {
810 if (!policy
|| !key
) return;
811 CFMutableDictionaryRef options
= (CFMutableDictionaryRef
) policy
->_options
;
813 options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
814 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
815 if (!options
) return;
816 policy
->_options
= options
;
818 CFDictionarySetValue(options
, key
, value
);
822 // this is declared as NA for iPhone in SecPolicy.h, so declare here
823 OSStatus
SecPolicySetProperties(SecPolicyRef policyRef
, CFDictionaryRef properties
);
826 OSStatus
SecPolicySetProperties(SecPolicyRef policyRef
, CFDictionaryRef properties
) {
827 // Set policy options based on the provided dictionary keys.
829 if (!(policyRef
&& properties
&& (CFDictionaryGetTypeID() == CFGetTypeID(properties
)))) {
832 CFStringRef oid
= (CFStringRef
) CFRetain(policyRef
->_oid
);
833 OSStatus result
= errSecSuccess
;
836 CFTypeRef name
= NULL
;
837 if (CFDictionaryGetValueIfPresent(properties
, (const void *)kSecPolicyName
,
838 (const void **)&name
) && name
) {
839 CFTypeID typeID
= CFGetTypeID(name
);
840 if (CFEqual(oid
, kSecPolicyOIDSSLServer
) ||
841 CFEqual(oid
, kSecPolicyOIDSSLClient
) ||
842 CFEqual(oid
, kSecPolicyOIDIPSecServer
) ||
843 CFEqual(oid
, kSecPolicyOIDIPSecClient
)) {
844 if (CFStringGetTypeID() == typeID
) {
845 SecPolicySetOptionsValue(policyRef
, kSecPolicyCheckSSLHostname
, name
);
847 else result
= errSecParam
;
849 else if (CFEqual(oid
, kSecPolicyOIDEAPServer
) ||
850 CFEqual(oid
, kSecPolicyOIDEAPClient
)) {
851 if ((CFStringGetTypeID() == typeID
) ||
852 (CFArrayGetTypeID() == typeID
)) {
853 SecPolicySetOptionsValue(policyRef
, kSecPolicyCheckEAPTrustedServerNames
, name
);
855 else result
= errSecParam
;
857 else if (CFEqual(oid
, kSecPolicyOIDSMIME
)) {
858 if (CFStringGetTypeID() == typeID
) {
859 SecPolicySetOptionsValue(policyRef
, kSecPolicyCheckEmail
, name
);
861 else result
= errSecParam
;
866 CFTypeRef client
= NULL
;
867 if (CFDictionaryGetValueIfPresent(properties
, (const void *)kSecPolicyClient
,
868 (const void **)&client
) && client
) {
869 if (!(CFBooleanGetTypeID() == CFGetTypeID(client
))) {
870 result
= errSecParam
;
872 else if (CFEqual(client
, kCFBooleanTrue
)) {
873 if (CFEqual(oid
, kSecPolicyOIDSSLServer
)) {
874 SecPolicySetOid(policyRef
, kSecPolicyOIDSSLClient
);
876 else if (CFEqual(oid
, kSecPolicyOIDIPSecServer
)) {
877 SecPolicySetOid(policyRef
, kSecPolicyOIDIPSecClient
);
879 else if (CFEqual(oid
, kSecPolicyOIDEAPServer
)) {
880 SecPolicySetOid(policyRef
, kSecPolicyOIDEAPClient
);
884 if (CFEqual(oid
, kSecPolicyOIDSSLClient
)) {
885 SecPolicySetOid(policyRef
, kSecPolicyOIDSSLServer
);
887 else if (CFEqual(oid
, kSecPolicyOIDIPSecClient
)) {
888 SecPolicySetOid(policyRef
, kSecPolicyOIDIPSecServer
);
890 else if (CFEqual(oid
, kSecPolicyOIDEAPClient
)) {
891 SecPolicySetOid(policyRef
, kSecPolicyOIDEAPServer
);
900 static xpc_object_t
copy_xpc_policy_object(SecPolicyRef policy
);
901 static bool append_policy_to_xpc_array(SecPolicyRef policy
, xpc_object_t xpc_policies
);
902 extern xpc_object_t
copy_xpc_policies_array(CFArrayRef policies
);
903 extern OSStatus
validate_array_of_items(CFArrayRef array
, CFStringRef arrayItemType
, CFTypeID itemTypeID
, bool required
);
905 static xpc_object_t
copy_xpc_policy_object(SecPolicyRef policy
) {
906 xpc_object_t xpc_policy
= NULL
;
907 xpc_object_t data
[2] = { NULL
, NULL
};
908 if (policy
->_oid
&& (CFGetTypeID(policy
->_oid
) == CFStringGetTypeID())) {
909 data
[0] = _CFXPCCreateXPCObjectFromCFObject(policy
->_oid
);
911 secerror("policy 0x%lX has no _oid", (uintptr_t)policy
);
913 if (policy
->_options
&& (CFGetTypeID(policy
->_options
) == CFDictionaryGetTypeID())) {
914 data
[1] = _CFXPCCreateXPCObjectFromCFObject(policy
->_options
);
916 secerror("policy 0x%lX has no _options", (uintptr_t)policy
);
918 xpc_policy
= xpc_array_create(data
, array_size(data
));
919 if (data
[0]) xpc_release(data
[0]);
920 if (data
[1]) xpc_release(data
[1]);
924 static bool append_policy_to_xpc_array(SecPolicyRef policy
, xpc_object_t xpc_policies
) {
928 xpc_object_t xpc_policy
= copy_xpc_policy_object(policy
);
932 xpc_array_append_value(xpc_policies
, xpc_policy
);
933 xpc_release(xpc_policy
);
937 xpc_object_t
copy_xpc_policies_array(CFArrayRef policies
) {
938 xpc_object_t xpc_policies
= xpc_array_create(NULL
, 0);
942 validate_array_of_items(policies
, CFSTR("policy"), SecPolicyGetTypeID(), true);
943 CFIndex ix
, count
= CFArrayGetCount(policies
);
944 for (ix
= 0; ix
< count
; ++ix
) {
945 SecPolicyRef policy
= (SecPolicyRef
) CFArrayGetValueAtIndex(policies
, ix
);
946 #if SECTRUST_VERBOSE_DEBUG
947 CFDictionaryRef props
= SecPolicyCopyProperties(policy
);
948 secerror("idx=%d of %d; policy=0x%lX properties=%@", (int)ix
, (int)count
, (uintptr_t)policy
, props
);
949 CFReleaseSafe(props
);
951 if (!append_policy_to_xpc_array(policy
, xpc_policies
)) {
952 xpc_release(xpc_policies
);
960 static xpc_object_t
SecPolicyCopyXPCObject(SecPolicyRef policy
, CFErrorRef
*error
) {
961 xpc_object_t xpc_policy
= NULL
;
962 xpc_object_t data
[2] = {};
963 require_action_quiet(data
[0] = _CFXPCCreateXPCObjectFromCFObject(policy
->_oid
), exit
,
964 SecError(errSecParam
, error
, CFSTR("failed to create xpc_object from policy oid")));
965 require_action_quiet(data
[1] = _CFXPCCreateXPCObjectFromCFObject(policy
->_options
), exit
,
966 SecError(errSecParam
, error
, CFSTR("failed to create xpc_object from policy options")));
967 require_action_quiet(xpc_policy
= xpc_array_create(data
, array_size(data
)), exit
,
968 SecError(errSecAllocate
, error
, CFSTR("failed to create xpc_array for policy")));
971 if (data
[0]) xpc_release(data
[0]);
972 if (data
[1]) xpc_release(data
[1]);
976 static bool SecPolicyAppendToXPCArray(SecPolicyRef policy
, xpc_object_t policies
, CFErrorRef
*error
) {
980 xpc_object_t xpc_policy
= SecPolicyCopyXPCObject(policy
, error
);
984 xpc_array_append_value(policies
, xpc_policy
);
985 xpc_release(xpc_policy
);
989 xpc_object_t
SecPolicyArrayCopyXPCArray(CFArrayRef policies
, CFErrorRef
*error
) {
990 xpc_object_t xpc_policies
;
991 require_action_quiet(xpc_policies
= xpc_array_create(NULL
, 0), exit
,
992 SecError(errSecAllocate
, error
, CFSTR("failed to create xpc_array")));
993 CFIndex ix
, count
= CFArrayGetCount(policies
);
994 for (ix
= 0; ix
< count
; ++ix
) {
995 if (!SecPolicyAppendToXPCArray((SecPolicyRef
)CFArrayGetValueAtIndex(policies
, ix
), xpc_policies
, error
)) {
996 xpc_release(xpc_policies
);
1001 return xpc_policies
;
1004 static SecPolicyRef
SecPolicyCreateWithXPCObject(xpc_object_t xpc_policy
, CFErrorRef
*error
) {
1005 SecPolicyRef policy
= NULL
;
1006 CFTypeRef oid
= NULL
;
1007 CFTypeRef options
= NULL
;
1009 require_action_quiet(xpc_policy
, exit
, SecError(errSecParam
, error
, CFSTR("policy xpc value is NULL")));
1010 require_action_quiet(xpc_get_type(xpc_policy
) == XPC_TYPE_ARRAY
, exit
, SecError(errSecDecode
, error
, CFSTR("policy xpc value is not an array")));
1011 require_action_quiet(xpc_array_get_count(xpc_policy
) == 2, exit
, SecError(errSecDecode
, error
, CFSTR("policy xpc array count != 2")));
1012 oid
= _CFXPCCreateCFObjectFromXPCObject(xpc_array_get_value(xpc_policy
, 0));
1013 require_action_quiet(isString(oid
), exit
,
1014 SecError(errSecParam
, error
, CFSTR("failed to convert xpc policy[0]=%@ to CFString"), oid
));
1015 options
= _CFXPCCreateCFObjectFromXPCObject(xpc_array_get_value(xpc_policy
, 1));
1016 require_action_quiet(isDictionary(options
), exit
,
1017 SecError(errSecParam
, error
, CFSTR("failed to convert xpc policy[1]=%@ to CFDictionary"), options
));
1018 require_action_quiet(policy
= SecPolicyCreate(oid
, options
), exit
, SecError(errSecDecode
, error
, CFSTR("Failed to create policy")));
1022 CFReleaseSafe(options
);
1026 CFArrayRef
SecPolicyXPCArrayCopyArray(xpc_object_t xpc_policies
, CFErrorRef
*error
) {
1027 CFMutableArrayRef policies
= NULL
;
1028 require_action_quiet(xpc_get_type(xpc_policies
) == XPC_TYPE_ARRAY
, exit
,
1029 SecError(errSecParam
, error
, CFSTR("policies xpc value is not an array")));
1030 size_t count
= xpc_array_get_count(xpc_policies
);
1031 require_action_quiet(policies
= CFArrayCreateMutable(kCFAllocatorDefault
, count
, &kCFTypeArrayCallBacks
), exit
,
1032 SecError(errSecAllocate
, error
, CFSTR("failed to create CFArray of capacity %zu"), count
));
1035 for (ix
= 0; ix
< count
; ++ix
) {
1036 SecPolicyRef policy
= SecPolicyCreateWithXPCObject(xpc_array_get_value(xpc_policies
, ix
), error
);
1038 CFRelease(policies
);
1041 CFArraySetValueAtIndex(policies
, ix
, policy
);
1050 static void add_element(CFMutableDictionaryRef options
, CFStringRef key
,
1052 CFTypeRef old_value
= CFDictionaryGetValue(options
, key
);
1054 CFMutableArrayRef array
;
1055 if (CFGetTypeID(old_value
) == CFArrayGetTypeID()) {
1056 array
= (CFMutableArrayRef
)old_value
;
1058 array
= CFArrayCreateMutable(kCFAllocatorDefault
, 0,
1059 &kCFTypeArrayCallBacks
);
1060 CFArrayAppendValue(array
, old_value
);
1061 CFDictionarySetValue(options
, key
, array
);
1064 CFArrayAppendValue(array
, value
);
1066 CFDictionaryAddValue(options
, key
, value
);
1070 static void add_eku(CFMutableDictionaryRef options
, const DERItem
*ekuOid
) {
1071 CFDataRef eku
= CFDataCreate(kCFAllocatorDefault
,
1072 ekuOid
? ekuOid
->data
: NULL
,
1073 ekuOid
? ekuOid
->length
: 0);
1075 add_element(options
, kSecPolicyCheckExtendedKeyUsage
, eku
);
1080 static void add_ku(CFMutableDictionaryRef options
, SecKeyUsage keyUsage
) {
1081 SInt32 dku
= keyUsage
;
1082 CFNumberRef ku
= CFNumberCreate(kCFAllocatorDefault
, kCFNumberSInt32Type
,
1085 add_element(options
, kSecPolicyCheckKeyUsage
, ku
);
1090 static void add_oid(CFMutableDictionaryRef options
, CFStringRef policy_key
, const DERItem
*oid
) {
1091 CFDataRef oid_data
= CFDataCreate(kCFAllocatorDefault
,
1092 oid
? oid
->data
: NULL
,
1093 oid
? oid
->length
: 0);
1095 add_element(options
, policy_key
, oid_data
);
1096 CFRelease(oid_data
);
1100 static void add_leaf_marker_value(CFMutableDictionaryRef options
, const DERItem
*markerOid
, CFStringRef string_value
) {
1102 CFTypeRef policyData
= NULL
;
1104 if (NULL
== string_value
) {
1105 policyData
= CFDataCreate(kCFAllocatorDefault
,
1106 markerOid
? markerOid
->data
: NULL
,
1107 markerOid
? markerOid
->length
: 0);
1109 CFStringRef oid_as_string
= SecDERItemCopyOIDDecimalRepresentation(kCFAllocatorDefault
, markerOid
);
1111 const void *key
[1] = { oid_as_string
};
1112 const void *value
[1] = { string_value
};
1113 policyData
= CFDictionaryCreate(kCFAllocatorDefault
,
1115 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
1116 CFReleaseNull(oid_as_string
);
1119 add_element(options
, kSecPolicyCheckLeafMarkerOid
, policyData
);
1121 CFReleaseNull(policyData
);
1125 static void add_leaf_marker(CFMutableDictionaryRef options
, const DERItem
*markerOid
) {
1126 add_leaf_marker_value(options
, markerOid
, NULL
);
1130 static void add_certificate_policy_oid(CFMutableDictionaryRef options
, const DERItem
*certificatePolicyOid
, CFStringRef string_value
) {
1131 CFTypeRef certificatePolicyData
= NULL
;
1133 if (NULL
== string_value
) {
1134 certificatePolicyData
= CFDataCreate(kCFAllocatorDefault
,
1135 certificatePolicyOid
? certificatePolicyOid
->data
: NULL
,
1136 certificatePolicyOid
? certificatePolicyOid
->length
: 0);
1138 CFStringRef oid_as_string
= SecDERItemCopyOIDDecimalRepresentation(kCFAllocatorDefault
, certificatePolicyOid
);
1140 const void *key
[1] = { oid_as_string
};
1141 const void *value
[1] = { string_value
};
1142 certificatePolicyData
= CFDictionaryCreate(kCFAllocatorDefault
,
1144 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
1145 CFReleaseNull(oid_as_string
);
1148 add_element(options
, kSecPolicyCheckCertificatePolicy
, certificatePolicyData
);
1150 CFReleaseNull(certificatePolicyData
);
1153 // Routines for adding dictionary entries for policies.
1156 // X.509, but missing validity requirements.
1157 static void SecPolicyAddBasicCertOptions(CFMutableDictionaryRef options
)
1159 //CFDictionaryAddValue(options, kSecPolicyCheckBasicCertificateProcessing, kCFBooleanTrue);
1160 CFDictionaryAddValue(options
, kSecPolicyCheckCriticalExtensions
, kCFBooleanTrue
);
1161 CFDictionaryAddValue(options
, kSecPolicyCheckIdLinkage
, kCFBooleanTrue
);
1162 CFDictionaryAddValue(options
, kSecPolicyCheckBasicContraints
, kCFBooleanTrue
);
1163 CFDictionaryAddValue(options
, kSecPolicyCheckNonEmptySubject
, kCFBooleanTrue
);
1164 CFDictionaryAddValue(options
, kSecPolicyCheckQualifiedCertStatements
, kCFBooleanTrue
);
1165 CFDictionaryAddValue(options
, kSecPolicyCheckWeakIntermediates
, kCFBooleanTrue
);
1166 CFDictionaryAddValue(options
, kSecPolicyCheckWeakLeaf
, kCFBooleanTrue
);
1167 CFDictionaryAddValue(options
, kSecPolicyCheckWeakRoot
, kCFBooleanTrue
);
1170 static void SecPolicyAddBasicX509Options(CFMutableDictionaryRef options
)
1172 SecPolicyAddBasicCertOptions(options
);
1173 CFDictionaryAddValue(options
, kSecPolicyCheckValidIntermediates
, kCFBooleanTrue
);
1174 CFDictionaryAddValue(options
, kSecPolicyCheckValidLeaf
, kCFBooleanTrue
);
1175 CFDictionaryAddValue(options
, kSecPolicyCheckValidRoot
, kCFBooleanTrue
);
1177 // Make sure that black and gray leaf checks are performed for basic X509 chain building
1178 CFDictionaryAddValue(options
, kSecPolicyCheckBlackListedLeaf
, kCFBooleanTrue
);
1179 CFDictionaryAddValue(options
, kSecPolicyCheckGrayListedLeaf
, kCFBooleanTrue
);
1182 static bool SecPolicyAddChainLengthOptions(CFMutableDictionaryRef options
, CFIndex length
)
1184 bool result
= false;
1185 CFNumberRef lengthAsCF
= NULL
;
1187 require(lengthAsCF
= CFNumberCreate(kCFAllocatorDefault
,
1188 kCFNumberCFIndexType
, &length
), errOut
);
1189 CFDictionaryAddValue(options
, kSecPolicyCheckChainLength
, lengthAsCF
);
1194 CFReleaseSafe(lengthAsCF
);
1198 static bool SecPolicyAddAnchorSHA1Options(CFMutableDictionaryRef options
,
1199 const UInt8 anchorSha1
[kSecPolicySHA1Size
])
1201 bool success
= false;
1202 CFDataRef anchorData
= NULL
;
1204 require(anchorData
= CFDataCreate(kCFAllocatorDefault
, anchorSha1
, kSecPolicySHA1Size
), errOut
);
1205 add_element(options
, kSecPolicyCheckAnchorSHA1
, anchorData
);
1210 CFReleaseSafe(anchorData
);
1214 static bool SecPolicyAddAppleAnchorOptions(CFMutableDictionaryRef options
)
1216 return SecPolicyAddAnchorSHA1Options(options
, kAppleCASHA1
);
1220 // Policy Creation Functions
1222 SecPolicyRef
SecPolicyCreateBasicX509(void) {
1223 CFMutableDictionaryRef options
= NULL
;
1224 SecPolicyRef result
= NULL
;
1226 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1227 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1229 SecPolicyAddBasicX509Options(options
);
1230 CFDictionaryAddValue(options
, kSecPolicyCheckNoNetworkAccess
,
1233 require(result
= SecPolicyCreate(kSecPolicyOIDBasicX509
, options
), errOut
);
1236 CFReleaseSafe(options
);
1240 SecPolicyRef
SecPolicyCreateSSL(Boolean server
, CFStringRef hostname
) {
1241 CFMutableDictionaryRef options
= NULL
;
1242 SecPolicyRef result
= NULL
;
1244 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1245 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1247 SecPolicyAddBasicX509Options(options
);
1250 CFDictionaryAddValue(options
, kSecPolicyCheckSSLHostname
, hostname
);
1253 CFDictionaryAddValue(options
, kSecPolicyCheckBlackListedLeaf
, kCFBooleanTrue
);
1254 CFDictionaryAddValue(options
, kSecPolicyCheckGrayListedLeaf
, kCFBooleanTrue
);
1256 /* If server and EKU ext present then EKU ext should contain one of
1257 ServerAuth or ExtendedKeyUsageAny or NetscapeSGC or MicrosoftSGC.
1258 else if !server and EKU ext present then EKU ext should contain one of
1259 ClientAuth or ExtendedKeyUsageAny. */
1261 /* We always allow certificates that specify oidAnyExtendedKeyUsage. */
1262 add_eku(options
, NULL
); /* eku extension is optional */
1263 add_eku(options
, &oidAnyExtendedKeyUsage
);
1265 add_eku(options
, &oidExtendedKeyUsageServerAuth
);
1266 add_eku(options
, &oidExtendedKeyUsageMicrosoftSGC
);
1267 add_eku(options
, &oidExtendedKeyUsageNetscapeSGC
);
1269 add_eku(options
, &oidExtendedKeyUsageClientAuth
);
1272 require(result
= SecPolicyCreate(
1273 server
? kSecPolicyOIDSSLServer
: kSecPolicyOIDSSLClient
,
1277 CFReleaseSafe(options
);
1281 SecPolicyRef
SecPolicyCreateiPhoneActivation(void) {
1282 CFMutableDictionaryRef options
= NULL
;
1283 SecPolicyRef result
= NULL
;
1285 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1286 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1288 SecPolicyAddBasicCertOptions(options
);
1291 CFDictionaryAddValue(options
, kSecPolicyCheckKeyUsage
,
1293 CFDictionaryAddValue(options
, kSecPolicyCheckExtendedKeyUsage
,
1297 /* Basic X.509 policy with the additional requirements that the chain
1298 length is 3, it's anchored at the AppleCA and the leaf certificate
1299 has issuer "Apple iPhone Certification Authority" and
1300 subject "Apple iPhone Activation" for the common name. */
1301 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
1302 CFSTR("Apple iPhone Certification Authority"));
1303 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
,
1304 CFSTR("Apple iPhone Activation"));
1306 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1307 require(SecPolicyAddAppleAnchorOptions(options
), errOut
);
1309 require(result
= SecPolicyCreate(kSecPolicyOIDiPhoneActivation
, options
),
1313 CFReleaseSafe(options
);
1317 SecPolicyRef
SecPolicyCreateiPhoneDeviceCertificate(void) {
1318 CFMutableDictionaryRef options
= NULL
;
1319 SecPolicyRef result
= NULL
;
1321 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1322 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1324 SecPolicyAddBasicCertOptions(options
);
1327 CFDictionaryAddValue(options
, kSecPolicyCheckKeyUsage
,
1329 CFDictionaryAddValue(options
, kSecPolicyCheckExtendedKeyUsage
,
1333 /* Basic X.509 policy with the additional requirements that the chain
1334 length is 4, it's anchored at the AppleCA and the first intermediate
1335 has the subject "Apple iPhone Device CA". */
1336 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
1337 CFSTR("Apple iPhone Device CA"));
1339 require(SecPolicyAddChainLengthOptions(options
, 4), errOut
);
1340 require(SecPolicyAddAppleAnchorOptions(options
), errOut
);
1342 require(result
= SecPolicyCreate(kSecPolicyOIDiPhoneDeviceCertificate
, options
),
1346 CFReleaseSafe(options
);
1350 SecPolicyRef
SecPolicyCreateFactoryDeviceCertificate(void) {
1351 CFMutableDictionaryRef options
= NULL
;
1352 SecPolicyRef result
= NULL
;
1354 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1355 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1357 SecPolicyAddBasicCertOptions(options
);
1360 CFDictionaryAddValue(options
, kSecPolicyCheckKeyUsage
,
1362 CFDictionaryAddValue(options
, kSecPolicyCheckExtendedKeyUsage
,
1366 /* Basic X.509 policy with the additional requirements that the chain
1367 is anchored at the factory device certificate issuer. */
1368 require(SecPolicyAddAnchorSHA1Options(options
, kFactoryDeviceCASHA1
), errOut
);
1370 require(result
= SecPolicyCreate(kSecPolicyOIDFactoryDeviceCertificate
, options
),
1374 CFReleaseSafe(options
);
1378 SecPolicyRef
SecPolicyCreateiAP(void) {
1379 CFMutableDictionaryRef options
= NULL
;
1380 SecPolicyRef result
= NULL
;
1381 CFTimeZoneRef tz
= NULL
;
1382 CFDateRef date
= NULL
;
1384 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1385 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1387 SecPolicyAddBasicCertOptions(options
);
1389 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonNamePrefix
,
1392 date
= CFDateCreateForGregorianZuluDay(NULL
, 2006, 5, 31);
1393 CFDictionaryAddValue(options
, kSecPolicyCheckNotValidBefore
, date
);
1395 require(result
= SecPolicyCreate(kSecPolicyOIDiAP
, options
),
1399 CFReleaseSafe(date
);
1401 CFReleaseSafe(options
);
1405 SecPolicyRef
SecPolicyCreateiTunesStoreURLBag(void) {
1406 CFMutableDictionaryRef options
= NULL
;
1407 SecPolicyRef result
= NULL
;
1410 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1411 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1413 SecPolicyAddBasicCertOptions(options
);
1415 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectOrganization
,
1416 CFSTR("Apple Inc."));
1417 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
,
1418 CFSTR("iTunes Store URL Bag"));
1420 require(SecPolicyAddChainLengthOptions(options
, 2), errOut
);
1421 require(SecPolicyAddAnchorSHA1Options(options
, kITMSCASHA1
), errOut
);
1423 require(result
= SecPolicyCreate(kSecPolicyOIDiTunesStoreURLBag
, options
), errOut
);
1426 CFReleaseSafe(options
);
1430 SecPolicyRef
SecPolicyCreateEAP(Boolean server
, CFArrayRef trustedServerNames
) {
1431 CFMutableDictionaryRef options
= NULL
;
1432 SecPolicyRef result
= NULL
;
1434 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1435 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1437 SecPolicyAddBasicX509Options(options
);
1439 /* Since EAP is used to setup the network we don't want evaluation
1440 using this policy to access the network. */
1441 CFDictionaryAddValue(options
, kSecPolicyCheckNoNetworkAccess
,
1444 if (trustedServerNames
) {
1445 CFDictionaryAddValue(options
, kSecPolicyCheckEAPTrustedServerNames
, trustedServerNames
);
1447 /* Specifying trusted server names implies EAP-TLS,
1448 so we need to check for EKU per rdar://22206018 */
1450 /* If server and EKU ext present then EKU ext should contain one of
1451 ServerAuth or ExtendedKeyUsageAny or NetscapeSGC or MicrosoftSGC.
1452 else if !server and EKU ext present then EKU ext should contain one of
1453 ClientAuth or ExtendedKeyUsageAny. */
1455 /* We always allow certificates that specify oidAnyExtendedKeyUsage. */
1456 add_eku(options
, NULL
); /* eku extension is optional */
1457 add_eku(options
, &oidAnyExtendedKeyUsage
);
1459 add_eku(options
, &oidExtendedKeyUsageServerAuth
);
1460 add_eku(options
, &oidExtendedKeyUsageMicrosoftSGC
);
1461 add_eku(options
, &oidExtendedKeyUsageNetscapeSGC
);
1463 add_eku(options
, &oidExtendedKeyUsageClientAuth
);
1467 require(result
= SecPolicyCreate(
1468 server
? kSecPolicyOIDEAPServer
: kSecPolicyOIDEAPClient
,
1472 CFReleaseSafe(options
);
1476 SecPolicyRef
SecPolicyCreateIPSec(Boolean server
, CFStringRef hostname
) {
1477 CFMutableDictionaryRef options
= NULL
;
1478 SecPolicyRef result
= NULL
;
1480 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1481 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1483 SecPolicyAddBasicX509Options(options
);
1486 CFDictionaryAddValue(options
, kSecPolicyCheckSSLHostname
, hostname
);
1489 /* Require oidExtendedKeyUsageIPSec if Extended Keyusage Extention is
1491 /* Per <rdar://problem/6843827> Cisco VPN Certificate compatibility issue.
1492 We don't check the EKU for IPSec certs for now. If we do add eku
1493 checking back in the future, we should probably also accept the
1495 ipsecEndSystem 1.3.6.1.5.5.7.3.5
1497 ipsecTunnel 1.3.6.1.5.5.7.3.6
1498 ipsecUser 1.3.6.1.5.5.7.3.7
1500 //add_eku(options, NULL); /* eku extension is optional */
1501 //add_eku(options, &oidAnyExtendedKeyUsage);
1502 //add_eku(options, &oidExtendedKeyUsageIPSec);
1504 require(result
= SecPolicyCreate(
1505 server
? kSecPolicyOIDIPSecServer
: kSecPolicyOIDIPSecClient
,
1509 CFReleaseSafe(options
);
1513 SecPolicyRef
SecPolicyCreateiPhoneApplicationSigning(void) {
1514 CFMutableDictionaryRef options
= NULL
;
1515 SecPolicyRef result
= NULL
;
1517 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1518 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1520 SecPolicyAddBasicCertOptions(options
);
1522 /* Basic X.509 policy with the additional requirements that the chain
1523 length is 3, it's anchored at the AppleCA and the leaf certificate
1524 has issuer "Apple iPhone Certification Authority" and
1525 subject "Apple iPhone OS Application Signing" for the common name. */
1526 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
1527 CFSTR("Apple iPhone Certification Authority"));
1528 if (SecIsInternalRelease() && !SecIsProductionFused()) {
1529 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonNameTEST
,
1530 CFSTR("Apple iPhone OS Application Signing"));
1533 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
,
1534 CFSTR("Apple iPhone OS Application Signing"));
1537 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1538 require(SecPolicyAddAppleAnchorOptions(options
), errOut
);
1540 add_eku(options
, NULL
); /* eku extension is optional */
1541 add_eku(options
, &oidAnyExtendedKeyUsage
);
1542 add_eku(options
, &oidExtendedKeyUsageCodeSigning
);
1544 require(result
= SecPolicyCreate(kSecPolicyOIDiPhoneApplicationSigning
, options
),
1547 /* 1.2.840.113635.100.6.1.3, non-critical: DER:05:00 - application signing */
1550 CFReleaseSafe(options
);
1554 SecPolicyRef
SecPolicyCreateiPhoneProfileApplicationSigning(void) {
1555 CFMutableDictionaryRef options
= NULL
;
1556 SecPolicyRef result
= NULL
;
1558 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1559 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1560 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kCFBooleanFalse
);
1561 CFDictionaryAddValue(options
, kSecPolicyCheckValidLeaf
, kCFBooleanFalse
);
1563 require(result
= SecPolicyCreate(kSecPolicyOIDiPhoneProfileApplicationSigning
,
1567 CFReleaseSafe(options
);
1571 SecPolicyRef
SecPolicyCreateiPhoneProvisioningProfileSigning(void) {
1572 CFMutableDictionaryRef options
= NULL
;
1573 SecPolicyRef result
= NULL
;
1575 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1576 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1578 SecPolicyAddBasicCertOptions(options
);
1580 /* Basic X.509 policy with the additional requirements that the chain
1581 length is 3, it's anchored at the AppleCA and the leaf certificate
1582 has issuer "Apple iPhone Certification Authority" and
1583 subject "Apple iPhone OS Provisioning Profile Signing" for the common name. */
1584 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
1585 CFSTR("Apple iPhone Certification Authority"));
1586 if (SecIsInternalRelease() && !SecIsProductionFused()) {
1587 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonNameTEST
,
1588 CFSTR("Apple iPhone OS Provisioning Profile Signing"));
1591 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
,
1592 CFSTR("Apple iPhone OS Provisioning Profile Signing"));
1595 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1596 require(SecPolicyAddAppleAnchorOptions(options
), errOut
);
1598 require(result
= SecPolicyCreate(kSecPolicyOIDiPhoneProvisioningProfileSigning
, options
),
1601 /* 1.2.840.113635.100.6.2.2.1, non-critical: DER:05:00 - provisioning profile */
1604 CFReleaseSafe(options
);
1608 SecPolicyRef
SecPolicyCreateAppleTVOSApplicationSigning(void) {
1609 CFMutableDictionaryRef options
= NULL
;
1610 SecPolicyRef result
= NULL
;
1611 CFDataRef atvProdOid
= NULL
;
1612 CFDataRef atvTestOid
= NULL
;
1613 CFArrayRef oids
= NULL
;
1615 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1616 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1618 SecPolicyAddBasicCertOptions(options
);
1620 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1622 CFMutableDictionaryRef appleAnchorOptions
= CFDictionaryCreateMutableForCFTypes(NULL
);
1623 require(appleAnchorOptions
, errOut
);
1624 add_element(options
, kSecPolicyCheckAnchorApple
, appleAnchorOptions
);
1626 /* Check for intermediate: Apple Worldwide Developer Relations */
1627 /* 1.2.840.113635.100.6.2.1 */
1628 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleWWDR
);
1630 add_eku(options
, NULL
); /* eku extension is optional */
1631 add_eku(options
, &oidAnyExtendedKeyUsage
);
1632 add_eku(options
, &oidExtendedKeyUsageCodeSigning
);
1634 /* Check for prod or test AppleTV Application Signing OIDs */
1635 /* Prod: 1.2.840.113635.100.6.1.24 */
1636 /* Test: 1.2.840.113635.100.6.1.24.1 */
1637 atvProdOid
= CFDataCreate(kCFAllocatorDefault
, oidAppleTVOSApplicationSigningProd
.data
, oidAppleTVOSApplicationSigningProd
.length
);
1638 require(atvProdOid
, errOut
);
1639 atvTestOid
= CFDataCreate(kCFAllocatorDefault
, oidAppleTVOSApplicationSigningTest
.data
, oidAppleTVOSApplicationSigningTest
.length
);
1640 require(atvTestOid
, errOut
);
1642 oids
= CFArrayCreateForCFTypes(kCFAllocatorDefault
, atvProdOid
, atvTestOid
, NULL
);
1643 require(oids
, errOut
);
1645 add_element(options
, kSecPolicyCheckLeafMarkerOid
, oids
);
1647 require(result
= SecPolicyCreate(kSecPolicyOIDAppleTVOSApplicationSigning
, options
),
1651 CFReleaseSafe(options
);
1652 CFReleaseSafe(oids
);
1653 CFReleaseSafe(atvProdOid
);
1654 CFReleaseSafe(atvTestOid
);
1658 SecPolicyRef
SecPolicyCreateOCSPSigner(void) {
1659 CFMutableDictionaryRef options
= NULL
;
1660 SecPolicyRef result
= NULL
;
1662 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1663 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1665 SecPolicyAddBasicX509Options(options
);
1667 /* Require id-kp-OCSPSigning extendedKeyUsage to be present, not optional. */
1668 add_eku(options
, &oidExtendedKeyUsageOCSPSigning
);
1670 require(result
= SecPolicyCreate(kSecPolicyOIDOCSPSigner
, options
), errOut
);
1673 CFReleaseSafe(options
);
1677 SecPolicyRef
SecPolicyCreateRevocation(CFOptionFlags revocationFlags
) {
1678 CFMutableDictionaryRef options
= NULL
;
1679 SecPolicyRef result
= NULL
;
1681 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1682 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1684 /* false = ocsp, true = crl, string/url value = crl distribution point,
1685 array = list of multiple values for example false, true, url1, url2
1686 check ocsp, crl, and url1 and url2 for certs which have no extensions.
1688 if (revocationFlags
& kSecRevocationOCSPMethod
) {
1689 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kCFBooleanFalse
);
1691 else if (revocationFlags
& kSecRevocationCRLMethod
) {
1692 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kCFBooleanTrue
);
1695 if (revocationFlags
& kSecRevocationRequirePositiveResponse
) {
1696 CFDictionaryAddValue(options
, kSecPolicyCheckRevocationResponseRequired
, kCFBooleanTrue
);
1699 if (revocationFlags
& kSecRevocationNetworkAccessDisabled
) {
1700 CFDictionaryAddValue(options
, kSecPolicyCheckNoNetworkAccess
, kCFBooleanTrue
);
1703 /* Only flag bits 0-4 are currently defined */
1704 require(((revocationFlags
>> 5) == 0), errOut
);
1706 require(result
= SecPolicyCreate(kSecPolicyOIDRevocation
, options
), errOut
);
1709 CFReleaseSafe(options
);
1713 SecPolicyRef
SecPolicyCreateSMIME(CFIndex smimeUsage
, CFStringRef email
) {
1714 CFMutableDictionaryRef options
= NULL
;
1715 SecPolicyRef result
= NULL
;
1717 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1718 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1720 SecPolicyAddBasicX509Options(options
);
1722 /* We call add_ku for each combination of bits we are willing to allow. */
1723 if (smimeUsage
& kSecSignSMIMEUsage
) {
1724 add_ku(options
, kSecKeyUsageUnspecified
);
1725 add_ku(options
, kSecKeyUsageDigitalSignature
);
1726 add_ku(options
, kSecKeyUsageNonRepudiation
);
1728 if (smimeUsage
& kSecKeyEncryptSMIMEUsage
) {
1729 add_ku(options
, kSecKeyUsageKeyEncipherment
);
1731 if (smimeUsage
& kSecDataEncryptSMIMEUsage
) {
1732 add_ku(options
, kSecKeyUsageDataEncipherment
);
1734 if (smimeUsage
& kSecKeyExchangeDecryptSMIMEUsage
) {
1735 add_ku(options
, kSecKeyUsageKeyAgreement
| kSecKeyUsageDecipherOnly
);
1737 if (smimeUsage
& kSecKeyExchangeEncryptSMIMEUsage
) {
1738 add_ku(options
, kSecKeyUsageKeyAgreement
| kSecKeyUsageEncipherOnly
);
1740 if (smimeUsage
& kSecKeyExchangeBothSMIMEUsage
) {
1741 add_ku(options
, kSecKeyUsageKeyAgreement
| kSecKeyUsageEncipherOnly
| kSecKeyUsageDecipherOnly
);
1745 CFDictionaryAddValue(options
, kSecPolicyCheckEmail
, email
);
1748 /* RFC 3850 paragraph 4.4.4
1750 If the extended key usage extension is present in the certificate
1751 then interpersonal message S/MIME receiving agents MUST check that it
1752 contains either the emailProtection or the anyExtendedKeyUsage OID as
1753 defined in [KEYM]. S/MIME uses other than interpersonal messaging
1754 MAY require the explicit presence of the extended key usage extension
1755 or other OIDs to be present in the extension or both.
1757 add_eku(options
, NULL
); /* eku extension is optional */
1758 add_eku(options
, &oidAnyExtendedKeyUsage
);
1759 add_eku(options
, &oidExtendedKeyUsageEmailProtection
);
1761 require(result
= SecPolicyCreate(kSecPolicyOIDSMIME
, options
), errOut
);
1764 CFReleaseSafe(options
);
1768 SecPolicyRef
SecPolicyCreateApplePackageSigning(void) {
1769 CFMutableDictionaryRef options
= NULL
;
1770 SecPolicyRef result
= NULL
;
1772 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1773 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1775 // TBD: review OS X policy to see what options are needed for this policy
1776 SecPolicyAddBasicCertOptions(options
);
1778 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1779 require(SecPolicyAddAppleAnchorOptions(options
), errOut
);
1781 require(result
= SecPolicyCreate(kSecPolicyOIDPackageSigning
, options
),
1785 CFReleaseSafe(options
);
1790 SecPolicyRef
SecPolicyCreateAppleSWUpdateSigning(void) {
1791 CFMutableDictionaryRef options
= NULL
;
1792 SecPolicyRef result
= NULL
;
1794 * OS X rules for this policy:
1795 * -- Must have one intermediate cert
1796 * -- intermediate must have basic constraints with path length 0
1797 * -- intermediate has CSSMOID_APPLE_EKU_CODE_SIGNING EKU
1798 * -- leaf cert has either CODE_SIGNING or CODE_SIGN_DEVELOPMENT EKU (the latter of
1799 * which triggers a CSSMERR_APPLETP_CODE_SIGN_DEVELOPMENT error)
1801 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1802 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1804 // TBD: review OS X policy to see what options are needed for this policy
1805 SecPolicyAddBasicCertOptions(options
);
1807 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1808 require(SecPolicyAddAppleAnchorOptions(options
), errOut
);
1810 add_eku(options
, &oidAppleExtendedKeyUsageCodeSigning
);
1811 add_eku(options
, &oidAppleExtendedKeyUsageCodeSigningDev
);
1813 require(result
= SecPolicyCreate(kSecPolicyOIDAppleSWUpdateSigning
, options
),
1817 CFReleaseSafe(options
);
1822 SecPolicyRef
SecPolicyCreateCodeSigning(void) {
1823 CFMutableDictionaryRef options
= NULL
;
1824 SecPolicyRef result
= NULL
;
1826 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1827 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1830 #warning STU: <rdar://21328880>
1831 //%%% figure out why this policy is not passing for OS X.
1832 // I suspect it has to do with iOS not supporting anchor and keychain options yet.
1833 SecPolicyAddBasicCertOptions(options
);
1835 SecPolicyAddBasicX509Options(options
);
1837 /* If the key usage extension is present we accept it having either of
1839 add_ku(options
, kSecKeyUsageDigitalSignature
);
1840 add_ku(options
, kSecKeyUsageNonRepudiation
);
1842 /* We require a extended key usage extension and we accept any or
1843 codesigning ekus. */
1844 /* TODO: Do we want to accept the apple codesigning oid as well or is
1845 that a separate policy? */
1846 /* ANSWER: it's a separate policy, SecPolicyCreateAppleSWUpdateSigning */
1847 add_eku(options
, &oidAnyExtendedKeyUsage
);
1848 add_eku(options
, &oidExtendedKeyUsageCodeSigning
);
1851 require(result
= SecPolicyCreate(kSecPolicyOIDCodeSigning
, options
),
1855 CFReleaseSafe(options
);
1859 /* Explicitly leave out empty subject/subjectaltname check */
1860 SecPolicyRef
SecPolicyCreateLockdownPairing(void) {
1861 CFMutableDictionaryRef options
= NULL
;
1862 SecPolicyRef result
= NULL
;
1864 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1865 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1866 //CFDictionaryAddValue(options, kSecPolicyCheckBasicCertificateProcessing,
1868 CFDictionaryAddValue(options
, kSecPolicyCheckCriticalExtensions
,
1870 CFDictionaryAddValue(options
, kSecPolicyCheckIdLinkage
,
1872 CFDictionaryAddValue(options
, kSecPolicyCheckBasicContraints
,
1874 CFDictionaryAddValue(options
, kSecPolicyCheckQualifiedCertStatements
,
1877 require(result
= SecPolicyCreate(kSecPolicyOIDLockdownPairing
, options
), errOut
);
1880 CFReleaseSafe(options
);
1884 SecPolicyRef
SecPolicyCreateURLBag(void) {
1885 CFMutableDictionaryRef options
= NULL
;
1886 SecPolicyRef result
= NULL
;
1888 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1889 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1891 SecPolicyAddBasicCertOptions(options
);
1893 add_eku(options
, &oidExtendedKeyUsageCodeSigning
);
1895 require(result
= SecPolicyCreate(kSecPolicyOIDURLBag
, options
), errOut
);
1898 CFReleaseSafe(options
);
1902 static bool SecPolicyAddAppleCertificationAuthorityOptions(CFMutableDictionaryRef options
, bool honorValidity
)
1904 bool success
= false;
1907 SecPolicyAddBasicX509Options(options
);
1909 SecPolicyAddBasicCertOptions(options
);
1912 CFDictionaryAddValue(options
, kSecPolicyCheckKeyUsage
,
1914 CFDictionaryAddValue(options
, kSecPolicyCheckExtendedKeyUsage
,
1918 /* Basic X.509 policy with the additional requirements that the chain
1919 length is 3, it's anchored at the AppleCA and the leaf certificate
1920 has issuer "Apple iPhone Certification Authority". */
1921 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
1922 CFSTR("Apple iPhone Certification Authority"));
1924 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1925 require(SecPolicyAddAppleAnchorOptions(options
), errOut
);
1933 static SecPolicyRef
SecPolicyCreateAppleCertificationAuthorityPolicy(CFStringRef policyOID
, CFStringRef leafName
, bool honorValidity
)
1935 CFMutableDictionaryRef options
= NULL
;
1936 SecPolicyRef result
= NULL
;
1938 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1939 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1941 require(SecPolicyAddAppleCertificationAuthorityOptions(options
, honorValidity
), errOut
);
1943 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
, leafName
);
1945 require(result
= SecPolicyCreate(policyOID
, options
),
1949 CFReleaseSafe(options
);
1954 SecPolicyRef
SecPolicyCreateOTATasking(void)
1956 return SecPolicyCreateAppleCertificationAuthorityPolicy(kSecPolicyOIDOTATasking
, CFSTR("OTA Task Signing"), true);
1959 SecPolicyRef
SecPolicyCreateMobileAsset(void)
1961 return SecPolicyCreateAppleCertificationAuthorityPolicy(kSecPolicyOIDMobileAsset
, CFSTR("Asset Manifest Signing"), false);
1964 SecPolicyRef
SecPolicyCreateAppleIDAuthorityPolicy(void)
1966 SecPolicyRef result
= NULL
;
1967 CFMutableDictionaryRef options
= NULL
;
1968 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1969 &kCFTypeDictionaryKeyCallBacks
,
1970 &kCFTypeDictionaryValueCallBacks
), out
);
1972 //Leaf appears to be a SSL only cert, so policy should expand on that policy
1973 SecPolicyAddBasicX509Options(options
);
1975 // Apple CA anchored
1976 require(SecPolicyAddAppleAnchorOptions(options
), out
);
1978 // with the addition of the existence check of an extension with "Apple ID Sharing Certificate" oid (1.2.840.113635.100.4.7)
1979 // NOTE: this obviously intended to have gone into Extended Key Usage, but evidence of existing certs proves the contrary.
1980 add_leaf_marker(options
, &oidAppleExtendedKeyUsageAppleID
);
1982 // 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.
1983 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleID
);
1984 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleID2
);
1986 require(result
= SecPolicyCreate(kSecPolicyOIDAppleIDAuthority
, options
), out
);
1989 CFReleaseSafe(options
);
1993 SecPolicyRef
SecPolicyCreateMacAppStoreReceipt(void)
1995 SecPolicyRef result
= NULL
;
1996 CFMutableDictionaryRef options
= NULL
;
1997 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1998 &kCFTypeDictionaryKeyCallBacks
,
1999 &kCFTypeDictionaryValueCallBacks
), out
);
2001 SecPolicyAddBasicX509Options(options
);
2003 // Apple CA anchored
2004 require(SecPolicyAddAppleAnchorOptions(options
), out
);
2006 // - leaf needs certificatePolicies with CSSMOID_MACAPPSTORE_RECEIPT_CERT_POLICY
2007 // - chain length must be 3
2009 require(result
= SecPolicyCreate(kSecPolicyOIDMacAppStoreReceipt
, options
), out
);
2012 CFReleaseSafe(options
);
2017 static SecPolicyRef
_SecPolicyCreatePassbookCardSigner(CFStringRef cardIssuer
, CFStringRef teamIdentifier
, bool requireTeamID
)
2019 SecPolicyRef result
= NULL
;
2020 CFMutableDictionaryRef options
= NULL
;
2021 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2022 &kCFTypeDictionaryKeyCallBacks
,
2023 &kCFTypeDictionaryValueCallBacks
), out
);
2025 SecPolicyAddBasicX509Options(options
);
2026 SecPolicyAddAppleAnchorOptions(options
);
2028 if (teamIdentifier
) {
2029 // If supplied, teamIdentifier must match subject OU field
2030 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectOrganizationalUnit
, teamIdentifier
);
2033 // If not supplied, and it was required, fail
2034 require(!requireTeamID
, out
);
2037 // Must be both push and 3rd party package signing
2038 add_leaf_marker_value(options
, &oidAppleInstallerPackagingSigningExternal
, cardIssuer
);
2040 // We should check that it also has push marker, but we don't support requiring both, only either.
2041 // add_independent_oid(options, kSecPolicyCheckLeafMarkerOid, &oidApplePushServiceClient);
2043 // And Passbook signing eku
2044 add_eku(options
, &oidAppleExtendedKeyUsagePassbook
);
2046 require(result
= SecPolicyCreate(kSecPolicyOIDApplePassbook
, options
), out
);
2049 CFReleaseSafe(options
);
2053 SecPolicyRef
SecPolicyCreatePassbookCardSigner(CFStringRef cardIssuer
, CFStringRef teamIdentifier
)
2055 return _SecPolicyCreatePassbookCardSigner(cardIssuer
, teamIdentifier
, true);
2059 static SecPolicyRef
CreateMobileStoreSigner(Boolean forTest
)
2062 SecPolicyRef result
= NULL
;
2063 CFMutableDictionaryRef options
= NULL
;
2064 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2065 &kCFTypeDictionaryKeyCallBacks
,
2066 &kCFTypeDictionaryValueCallBacks
), errOut
);
2067 SecPolicyAddBasicX509Options(options
);
2068 SecPolicyAddAppleAnchorOptions(options
);
2070 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2072 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2073 CFSTR("Apple System Integration 2 Certification Authority"));
2075 add_ku(options
, kSecKeyUsageDigitalSignature
);
2077 const DERItem
* pOID
= (forTest
) ? &oidApplePolicyTestMobileStore
: &oidApplePolicyMobileStore
;
2079 add_certificate_policy_oid(options
, pOID
, NULL
);
2081 require(result
= SecPolicyCreate(kSecPolicyOIDAppleMobileStore
, options
), errOut
);
2084 CFReleaseSafe(options
);
2088 SecPolicyRef
SecPolicyCreateMobileStoreSigner(void)
2091 return CreateMobileStoreSigner(false);
2094 SecPolicyRef
SecPolicyCreateTestMobileStoreSigner(void)
2097 return CreateMobileStoreSigner(true);
2101 CF_RETURNS_RETAINED SecPolicyRef
SecPolicyCreateEscrowServiceSigner(void)
2103 SecPolicyRef result
= NULL
;
2104 CFMutableDictionaryRef options
= NULL
;
2105 CFArrayRef anArray
= NULL
;
2106 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2107 &kCFTypeDictionaryKeyCallBacks
,
2108 &kCFTypeDictionaryValueCallBacks
), errOut
);
2110 // X509, ignoring date validity
2111 SecPolicyAddBasicCertOptions(options
);
2114 add_ku(options
, kSecKeyUsageKeyEncipherment
);
2116 //add_leaf_marker(options, &oidApplePolicyEscrowService);
2117 require(SecPolicyAddChainLengthOptions(options
, 2), errOut
);
2120 Boolean anchorAdded
= false;
2121 // Get the roots by calling the SecCertificateCopyEscrowRoots
2122 anArray
= SecCertificateCopyEscrowRoots(kSecCertificateProductionEscrowRoot
);
2123 CFIndex numRoots
= 0;
2124 if (NULL
== anArray
|| 0 == (numRoots
= CFArrayGetCount(anArray
)))
2129 for (CFIndex iCnt
= 0; iCnt
< numRoots
; iCnt
++)
2131 SecCertificateRef aCert
= (SecCertificateRef
)CFArrayGetValueAtIndex(anArray
, iCnt
);
2135 CFDataRef sha_data
= SecCertificateGetSHA1Digest(aCert
);
2136 if (NULL
!= sha_data
)
2138 const UInt8
* pSHAData
= CFDataGetBytePtr(sha_data
);
2139 if (NULL
!= pSHAData
)
2141 SecPolicyAddAnchorSHA1Options(options
, pSHAData
);
2147 CFReleaseNull(anArray
);
2155 require(result
= SecPolicyCreate(kSecPolicyOIDAppleEscrowService
, options
), errOut
);
2158 CFReleaseSafe(anArray
);
2159 CFReleaseSafe(options
);
2163 CF_RETURNS_RETAINED SecPolicyRef
SecPolicyCreatePCSEscrowServiceSigner(void)
2165 SecPolicyRef result
= NULL
;
2166 CFMutableDictionaryRef options
= NULL
;
2167 CFArrayRef anArray
= NULL
;
2168 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2169 &kCFTypeDictionaryKeyCallBacks
,
2170 &kCFTypeDictionaryValueCallBacks
), errOut
);
2172 SecPolicyAddBasicX509Options(options
);
2175 add_ku(options
, kSecKeyUsageKeyEncipherment
);
2177 //add_leaf_marker(options, &oidApplePolicyEscrowService);
2178 require(SecPolicyAddChainLengthOptions(options
, 2), errOut
);
2181 Boolean anchorAdded
= false;
2182 anArray
= SecCertificateCopyEscrowRoots(kSecCertificateProductionPCSEscrowRoot
);
2183 CFIndex numRoots
= 0;
2184 if (NULL
== anArray
|| 0 == (numRoots
= CFArrayGetCount(anArray
)))
2189 for (CFIndex iCnt
= 0; iCnt
< numRoots
; iCnt
++)
2191 SecCertificateRef aCert
= (SecCertificateRef
)CFArrayGetValueAtIndex(anArray
, iCnt
);
2195 CFDataRef sha_data
= SecCertificateGetSHA1Digest(aCert
);
2196 if (NULL
!= sha_data
)
2198 const UInt8
* pSHAData
= CFDataGetBytePtr(sha_data
);
2199 if (NULL
!= pSHAData
)
2201 SecPolicyAddAnchorSHA1Options(options
, pSHAData
);
2207 CFReleaseNull(anArray
);
2215 require(result
= SecPolicyCreate(kSecPolicyOIDApplePCSEscrowService
, options
), errOut
);
2218 CFReleaseSafe(anArray
);
2219 CFReleaseSafe(options
);
2222 SecCertificateRef
SecPolicyCopyEscrowRootCertificate(void)
2224 SecCertificateRef result
= NULL
;
2229 SecPolicyRef
SecPolicyCreateConfigurationProfileSigner(void)
2231 SecPolicyRef result
= NULL
;
2232 CFMutableDictionaryRef options
= NULL
;
2233 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2234 &kCFTypeDictionaryKeyCallBacks
,
2235 &kCFTypeDictionaryValueCallBacks
), errOut
);
2237 SecPolicyAddBasicX509Options(options
);
2238 SecPolicyAddAppleAnchorOptions(options
);
2240 // Require the profile signing EKU
2241 add_eku(options
, &oidAppleExtendedKeyUsageProfileSigning
);
2243 require(result
= SecPolicyCreate(kSecPolicyOIDAppleProfileSigner
, options
), errOut
);
2246 CFReleaseSafe(options
);
2251 SecPolicyRef
SecPolicyCreateQAConfigurationProfileSigner(void)
2253 SecPolicyRef result
= NULL
;
2254 CFMutableDictionaryRef options
= NULL
;
2255 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2256 &kCFTypeDictionaryKeyCallBacks
,
2257 &kCFTypeDictionaryValueCallBacks
), errOut
);
2259 SecPolicyAddBasicX509Options(options
);
2260 SecPolicyAddAppleAnchorOptions(options
);
2262 // Require the QA profile signing EKU
2263 add_eku(options
, &oidAppleExtendedKeyUsageQAProfileSigning
);
2265 require(result
= SecPolicyCreate(kSecPolicyOIDAppleQAProfileSigner
, options
), errOut
);
2268 CFReleaseSafe(options
);
2272 SecPolicyRef
SecPolicyCreateOSXProvisioningProfileSigning(void)
2274 SecPolicyRef result
= NULL
;
2275 CFMutableDictionaryRef options
= NULL
;
2276 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2277 &kCFTypeDictionaryKeyCallBacks
,
2278 &kCFTypeDictionaryValueCallBacks
), errOut
);
2279 // Require valid chain from the Apple root
2280 SecPolicyAddBasicX509Options(options
);
2281 SecPolicyAddAppleAnchorOptions(options
);
2283 // Require provisioning profile leaf marker OID (1.2.840.113635.100.4.11)
2284 add_leaf_marker(options
, &oidAppleCertExtOSXProvisioningProfileSigning
);
2286 // Require intermediate marker OID (1.2.840.113635.100.6.2.1)
2287 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleWWDR
);
2289 // Require key usage that allows signing
2290 add_ku(options
, kSecKeyUsageDigitalSignature
);
2292 // Ensure that revocation is checked (OCSP)
2293 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kCFBooleanFalse
);
2295 require(result
= SecPolicyCreate(kSecPolicyOIDAppleOSXProvisioningProfileSigning
, options
), errOut
);
2298 CFReleaseSafe(options
);
2303 SecPolicyRef
SecPolicyCreateOTAPKISigner(void)
2305 SecPolicyRef result
= NULL
;
2306 CFMutableDictionaryRef options
= NULL
;
2307 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2308 &kCFTypeDictionaryKeyCallBacks
,
2309 &kCFTypeDictionaryValueCallBacks
), errOut
);
2310 SecPolicyAddBasicX509Options(options
);
2312 SecPolicyAddAnchorSHA1Options(options
, kApplePKISettingsAuthority
);
2313 require(SecPolicyAddChainLengthOptions(options
, 2), errOut
);
2315 require(result
= SecPolicyCreate(kSecPolicyOIDAppleOTAPKIAssetSigner
, options
), errOut
);
2318 CFReleaseSafe(options
);
2324 SecPolicyRef
SecPolicyCreateTestOTAPKISigner(void)
2326 SecPolicyRef result
= NULL
;
2327 CFMutableDictionaryRef options
= NULL
;
2328 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2329 &kCFTypeDictionaryKeyCallBacks
,
2330 &kCFTypeDictionaryValueCallBacks
), errOut
);
2331 SecPolicyAddBasicX509Options(options
);
2333 SecPolicyAddAnchorSHA1Options(options
, kAppleTestPKISettingsAuthority
);
2334 require(SecPolicyAddChainLengthOptions(options
, 2), errOut
);
2336 require(result
= SecPolicyCreate(kSecPolicyOIDAppleTestOTAPKIAssetSigner
, options
), errOut
);
2339 CFReleaseSafe(options
);
2344 @function SecPolicyCreateAppleSMPEncryption
2345 @abstract Check for intermediate certificate 'Apple System Integration CA - G3' by name,
2346 and root certificate 'Apple Root CA - G3' by hash.
2347 Leaf cert must have Key Encipherment usage.
2348 Leaf cert must have Apple SMP Encryption marker OID (1.2.840.113635.100.6.30).
2349 Intermediate must have marker OID (1.2.840.113635.100.6.2.13).
2351 SecPolicyRef
SecPolicyCreateAppleSMPEncryption(void)
2353 SecPolicyRef result
= NULL
;
2354 CFMutableDictionaryRef options
= NULL
;
2355 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2356 &kCFTypeDictionaryKeyCallBacks
,
2357 &kCFTypeDictionaryValueCallBacks
), errOut
);
2358 SecPolicyAddBasicCertOptions(options
);
2360 SecPolicyAddAnchorSHA1Options(options
, kAppleRootCA_ECC_SHA1
);
2361 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2363 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2364 CFSTR("Apple System Integration CA - G3"));
2366 // Check that leaf has extension with "Apple SMP Encryption" oid (1.2.840.113635.100.6.30)
2367 add_leaf_marker(options
, &oidAppleCertExtAppleSMPEncryption
);
2369 // Check that intermediate has extension (1.2.840.113635.100.6.2.13)
2370 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleSystemIntgG3
);
2372 add_ku(options
, kSecKeyUsageKeyEncipherment
);
2374 // Ensure that revocation is checked (OCSP)
2375 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kCFBooleanFalse
);
2377 require(result
= SecPolicyCreate(kSecPolicyAppleSMPEncryption
, options
), errOut
);
2380 CFReleaseSafe(options
);
2385 @function SecPolicyCreateTestAppleSMPEncryption
2386 @abstract Check for intermediate certificate 'Test Apple System Integration CA - ECC' by name,
2387 and root certificate 'Test Apple Root CA - ECC' by hash.
2388 Leaf cert must have Key Encipherment usage. Other checks TBD.
2390 SecPolicyRef
SecPolicyCreateTestAppleSMPEncryption(void)
2392 SecPolicyRef result
= NULL
;
2393 CFMutableDictionaryRef options
= NULL
;
2394 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2395 &kCFTypeDictionaryKeyCallBacks
,
2396 &kCFTypeDictionaryValueCallBacks
), errOut
);
2397 SecPolicyAddBasicCertOptions(options
);
2399 SecPolicyAddAnchorSHA1Options(options
, kTestAppleRootCA_ECC_SHA1
);
2400 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2402 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2403 CFSTR("Test Apple System Integration CA - ECC"));
2405 add_ku(options
, kSecKeyUsageKeyEncipherment
);
2407 // Ensure that revocation is checked (OCSP)
2408 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kCFBooleanFalse
);
2410 require(result
= SecPolicyCreate(kSecPolicyAppleTestSMPEncryption
, options
), errOut
);
2413 CFReleaseSafe(options
);
2418 SecPolicyRef
SecPolicyCreateAppleIDValidationRecordSigningPolicy(void)
2420 SecPolicyRef result
= NULL
;
2421 CFMutableDictionaryRef options
= NULL
;
2422 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2423 &kCFTypeDictionaryKeyCallBacks
,
2424 &kCFTypeDictionaryValueCallBacks
), errOut
);
2426 //Leaf appears to be a SSL only cert, so policy should expand on that policy
2427 SecPolicyAddBasicX509Options(options
);
2429 // Apple CA anchored
2430 require(SecPolicyAddAppleAnchorOptions(options
), errOut
);
2432 // Check for an extension with " Apple ID Validation Record Signing" oid (1.2.840.113635.100.6.25)
2433 add_leaf_marker(options
, &oidAppleCertExtensionAppleIDRecordValidationSigning
);
2435 // and validate that intermediate has extension
2436 // Application Integration Intermediate Certificate (1.2.840.113635.100.6.2.3)
2437 // and also validate that intermediate has extension
2438 // System Integration 2 Intermediate Certificate (1.2.840.113635.100.6.2.10)
2439 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleID
);
2440 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleSystemIntg2
);
2442 // Ensure that revocation is checked (OCSP)
2443 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kCFBooleanFalse
);
2445 require(result
= SecPolicyCreate(kSecPolicyOIDAppleIDValidationRecordSigningPolicy
, options
), errOut
);
2448 CFReleaseSafe(options
);
2453 allowUATRoot(bool allowNonProd
, CFStringRef service
, CFDictionaryRef context
)
2455 bool UATAllowed
= false;
2456 if (SecIsInternalRelease() || allowNonProd
) {
2457 CFStringRef setting
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("AppleServerAuthenticationAllowUAT%@"), service
);
2458 CFTypeRef value
= NULL
;
2459 require(setting
, fail
);
2462 CFDictionaryGetValueIfPresent(context
, setting
, &value
) &&
2464 CFBooleanGetValue(value
))
2469 if (CFPreferencesGetAppBooleanValue(setting
, CFSTR("com.apple.Security"), NULL
)) {
2479 requirePinning(bool allowNonProd
, CFStringRef service
)
2481 bool pinningRequired
= true;
2483 if (SecIsInternalRelease() || allowNonProd
) {
2484 CFStringRef setting
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("AppleServerAuthenticationNoPinning%@"), service
);
2485 require(setting
, fail
);
2486 if (CFPreferencesGetAppBooleanValue(setting
, CFSTR("com.apple.Security"), NULL
))
2487 pinningRequired
= false;
2491 return pinningRequired
;
2495 @function SecPolicyCreateAppleServerAuthCommon
2496 @abstract Generic policy for server authentication Sub CAs
2498 Allows control for both if pinning is required at all and if UAT environments should be added
2499 to the trust policy.
2501 No pinning is for developer/QA that needs to use proxy to debug the protocol, while UAT
2502 environment is for QA/internal developer that have no need allow fake servers.
2504 Both the noPinning and allowUAT are gated on that you run on internal hardware.
2509 SecPolicyCreateAppleServerAuthCommon(CFStringRef hostname
,
2510 CFDictionaryRef __unused context
,
2511 CFStringRef service
, bool allowNonProd
,
2512 const DERItem
*leafMarkerOID
,
2513 const DERItem
*UATLeafMarkerOID
)
2515 CFMutableDictionaryRef appleAnchorOptions
= NULL
;
2516 CFMutableDictionaryRef options
= NULL
;
2517 SecPolicyRef result
= NULL
;
2518 CFDataRef oid
= NULL
, uatoid
= NULL
;
2520 options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0, &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
2521 require(options
, errOut
);
2523 SecPolicyAddBasicX509Options(options
);
2525 CFDictionaryAddValue(options
, kSecPolicyCheckSSLHostname
, hostname
);
2527 CFDictionaryAddValue(options
, kSecPolicyCheckBlackListedLeaf
, kCFBooleanTrue
);
2528 CFDictionaryAddValue(options
, kSecPolicyCheckGrayListedLeaf
, kCFBooleanTrue
);
2530 add_eku(options
, &oidExtendedKeyUsageServerAuth
);
2532 if (requirePinning(allowNonProd
, service
)) {
2533 bool allowUAT
= allowUATRoot(allowNonProd
, service
, context
);
2536 * Require pinning to the Apple CA's (and if UAT environment,
2537 * include the Apple Test CA's as anchors).
2540 appleAnchorOptions
= CFDictionaryCreateMutableForCFTypes(NULL
);
2541 require(appleAnchorOptions
, errOut
);
2544 CFDictionarySetValue(appleAnchorOptions
,
2545 kSecPolicyAppleAnchorIncludeTestRoots
, kCFBooleanTrue
);
2547 CFDictionarySetValue(appleAnchorOptions
,
2548 kSecPolicyAppleAnchorAllowTestRootsOnProduction
, kCFBooleanTrue
);
2552 add_element(options
, kSecPolicyCheckAnchorApple
, appleAnchorOptions
);
2555 * Check if we also should allow the UAT variant of the leafs
2556 * as some variants of the UAT environment uses that instead
2557 * of the test Apple CA's.
2561 oid
= CFDataCreate(kCFAllocatorDefault
, leafMarkerOID
->data
, leafMarkerOID
->length
);
2562 require(oid
, errOut
);
2564 uatoid
= CFDataCreate(kCFAllocatorDefault
, UATLeafMarkerOID
->data
, UATLeafMarkerOID
->length
);
2565 require(oid
, errOut
);
2567 CFArrayRef array
= CFArrayCreateForCFTypes(NULL
, oid
, uatoid
, NULL
);
2568 require(array
, errOut
);
2570 add_element(options
, kSecPolicyCheckLeafMarkerOid
, array
);
2571 CFReleaseSafe(array
);
2573 add_leaf_marker(options
, leafMarkerOID
);
2576 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleServerAuthentication
);
2580 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kCFBooleanFalse
);
2582 result
= SecPolicyCreate(kSecPolicyOIDSSLServer
, options
);
2583 require(result
, errOut
);
2586 CFReleaseSafe(appleAnchorOptions
);
2587 CFReleaseSafe(options
);
2589 CFReleaseSafe(uatoid
);
2596 @function SecPolicyCreateAppleIDSService
2597 @abstract Ensure we're appropriately pinned to the IDS service (SSL + Apple restrictions)
2599 SecPolicyRef
SecPolicyCreateAppleIDSService(CFStringRef hostname
)
2602 return SecPolicyCreateSSL(true, hostname
);
2604 return SecPolicyCreateAppleServerAuthCommon(hostname
, NULL
, CFSTR("IDS"), false,
2605 &oidAppleCertExtAppleServerAuthenticationIDSProd
,
2606 &oidAppleCertExtAppleServerAuthenticationIDSTest
);
2611 @function SecPolicyCreateAppleIDSService
2612 @abstract Ensure we're appropriately pinned to the IDS service (SSL + Apple restrictions)
2614 SecPolicyRef
SecPolicyCreateAppleIDSServiceContext(CFStringRef hostname
, CFDictionaryRef context
)
2616 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, CFSTR("IDS"), false,
2617 &oidAppleCertExtAppleServerAuthenticationIDSProd
,
2618 &oidAppleCertExtAppleServerAuthenticationIDSTest
);
2622 @function SecPolicyCreateAppleGSService
2623 @abstract Ensure we're appropriately pinned to the GS service
2625 SecPolicyRef
SecPolicyCreateAppleGSService(CFStringRef hostname
, CFDictionaryRef context
)
2627 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, CFSTR("GS"), false,
2628 &oidAppleCertExtAppleServerAuthenticationGS
,
2633 @function SecPolicyCreateApplePushService
2634 @abstract Ensure we're appropriately pinned to the Push service (SSL + Apple restrictions)
2636 SecPolicyRef
SecPolicyCreateApplePushService(CFStringRef hostname
, CFDictionaryRef context
)
2638 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, CFSTR("APN"), false,
2639 &oidAppleCertExtAppleServerAuthenticationAPNProd
,
2640 &oidAppleCertExtAppleServerAuthenticationAPNTest
);
2644 @function SecPolicyCreateApplePPQService
2645 @abstract Ensure we're appropriately pinned to the PPQ service (SSL + Apple restrictions)
2647 SecPolicyRef
SecPolicyCreateApplePPQService(CFStringRef hostname
, CFDictionaryRef context
)
2649 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, CFSTR("PPQ"), false,
2650 &oidAppleCertExtAppleServerAuthenticationPPQProd
,
2651 &oidAppleCertExtAppleServerAuthenticationPPQTest
);
2655 @function SecPolicyCreateAppleAST2Service
2656 @abstract Ensure we're appropriately pinned to the AST2 Diagnostic service (SSL + Apple restrictions)
2658 SecPolicyRef
SecPolicyCreateAppleAST2Service(CFStringRef hostname
, CFDictionaryRef context
)
2660 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, CFSTR("AST2"), true,
2661 &oidAppleCertExtAST2DiagnosticsServerAuthProd
,
2662 &oidAppleCertExtAST2DiagnosticsServerAuthTest
);
2665 /* should use verbatim copy, but since this is the deprecated way, don't care right now */
2666 static const UInt8 entrustSPKIL1C
[kSecPolicySHA256Size
] = {
2667 0x54, 0x5b, 0xf9, 0x35, 0xe9, 0xad, 0xa1, 0xda,
2668 0x11, 0x7e, 0xdc, 0x3c, 0x2a, 0xcb, 0xc5, 0x6f,
2669 0xc0, 0x28, 0x09, 0x6c, 0x0e, 0x24, 0xbe, 0x9b,
2670 0x38, 0x94, 0xbe, 0x52, 0x2d, 0x1b, 0x43, 0xde
2674 @function SecPolicyCreateApplePushServiceLegacy
2675 @abstract Ensure we're appropriately pinned to the Push service (via Entrust)
2677 SecPolicyRef
SecPolicyCreateApplePushServiceLegacy(CFStringRef hostname
)
2679 CFMutableDictionaryRef options
= NULL
;
2680 SecPolicyRef result
= NULL
;
2681 CFDataRef digest
= NULL
;
2683 digest
= CFDataCreateWithBytesNoCopy(kCFAllocatorDefault
, entrustSPKIL1C
, sizeof(entrustSPKIL1C
), kCFAllocatorNull
);
2684 require(digest
, errOut
);
2686 options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0, &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
2687 require(options
, errOut
);
2689 SecPolicyAddBasicX509Options(options
);
2691 CFDictionaryAddValue(options
, kSecPolicyCheckSSLHostname
, hostname
);
2693 CFDictionaryAddValue(options
, kSecPolicyCheckBlackListedLeaf
, kCFBooleanTrue
);
2694 CFDictionaryAddValue(options
, kSecPolicyCheckGrayListedLeaf
, kCFBooleanTrue
);
2696 CFDictionaryAddValue(options
, kSecPolicyCheckIntermediateSPKISHA256
, digest
);
2698 add_eku(options
, &oidExtendedKeyUsageServerAuth
);
2700 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kCFBooleanFalse
);
2702 result
= SecPolicyCreate(kSecPolicyOIDSSLServer
, options
);
2703 require(result
, errOut
);
2706 CFReleaseSafe(digest
);
2707 CFReleaseSafe(options
);
2712 @function SecPolicyCreateAppleMMCSService
2713 @abstract Ensure we're appropriately pinned to the IDS service (SSL + Apple restrictions)
2715 SecPolicyRef
SecPolicyCreateAppleMMCSService(CFStringRef hostname
, CFDictionaryRef __unused context
)
2717 return SecPolicyCreateSSL(true, hostname
);
2721 @function SecPolicyCreateAppleSSLService
2722 @abstract Ensure we're appropriately pinned to an Apple server (SSL + Apple restrictions)
2724 SecPolicyRef
SecPolicyCreateAppleSSLService(CFStringRef hostname
)
2726 // SSL server, pinned to an Apple intermediate
2727 SecPolicyRef policy
= SecPolicyCreateSSL(true, hostname
);
2728 CFMutableDictionaryRef options
= NULL
;
2729 require(policy
, errOut
);
2731 // change options for SSL policy evaluation
2732 require((options
=(CFMutableDictionaryRef
)policy
->_options
) != NULL
, errOut
);
2734 // Apple CA anchored
2735 require(SecPolicyAddAppleAnchorOptions(options
), errOut
);
2737 // Check leaf for Apple Server Authentication marker oid (1.2.840.113635.100.6.27.1)
2738 add_leaf_marker(options
, &oidAppleCertExtAppleServerAuthentication
);
2740 // Check intermediate for Apple Server Authentication intermediate marker (1.2.840.113635.100.6.2.12)
2741 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleServerAuthentication
);
2743 // Ensure that revocation is checked (OCSP only)
2744 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kCFBooleanFalse
);
2749 CFReleaseSafe(options
);
2750 CFReleaseSafe(policy
);
2755 @function SecPolicyCreateApplePPQSigning
2756 @abstract Check for intermediate certificate 'Apple System Integration 2 Certification Authority' by name,
2758 Leaf cert must have Digital Signature usage.
2759 Leaf cert must have Apple PPQ Signing marker OID (1.2.840.113635.100.6.38.2).
2760 Intermediate must have marker OID (1.2.840.113635.100.6.2.10).
2762 SecPolicyRef
SecPolicyCreateApplePPQSigning(void)
2764 SecPolicyRef result
= NULL
;
2765 CFMutableDictionaryRef options
= NULL
;
2766 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2767 &kCFTypeDictionaryKeyCallBacks
,
2768 &kCFTypeDictionaryValueCallBacks
), errOut
);
2769 SecPolicyAddBasicCertOptions(options
);
2771 SecPolicyAddAppleAnchorOptions(options
);
2772 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2774 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2775 CFSTR("Apple System Integration 2 Certification Authority"));
2777 // Check that leaf has extension with "Apple PPQ Signing" prod oid (1.2.840.113635.100.6.38.2)
2778 add_leaf_marker(options
, &oidAppleCertExtApplePPQSigningProd
);
2780 // Check that intermediate has extension (1.2.840.113635.100.6.2.10)
2781 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleSystemIntg2
);
2783 add_ku(options
, kSecKeyUsageDigitalSignature
);
2785 require(result
= SecPolicyCreate(kSecPolicyApplePPQSigning
, options
), errOut
);
2788 CFReleaseSafe(options
);
2793 @function SecPolicyCreateTestApplePPQSigning
2794 @abstract Check for intermediate certificate 'Apple System Integration 2 Certification Authority' by name,
2796 Leaf cert must have Digital Signature usage.
2797 Leaf cert must have Apple PPQ Signing Test marker OID (1.2.840.113635.100.6.38.1).
2798 Intermediate must have marker OID (1.2.840.113635.100.6.2.10).
2800 SecPolicyRef
SecPolicyCreateTestApplePPQSigning(void)
2802 SecPolicyRef result
= NULL
;
2803 CFMutableDictionaryRef options
= NULL
;
2804 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2805 &kCFTypeDictionaryKeyCallBacks
,
2806 &kCFTypeDictionaryValueCallBacks
), errOut
);
2807 SecPolicyAddBasicCertOptions(options
);
2809 SecPolicyAddAppleAnchorOptions(options
);
2810 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2812 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2813 CFSTR("Apple System Integration 2 Certification Authority"));
2815 // Check that leaf has extension with "Apple PPQ Signing" test oid (1.2.840.113635.100.6.38.1)
2816 add_leaf_marker(options
, &oidAppleCertExtApplePPQSigningTest
);
2818 // Check that intermediate has extension (1.2.840.113635.100.6.2.10)
2819 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleSystemIntg2
);
2821 add_ku(options
, kSecKeyUsageDigitalSignature
);
2823 require(result
= SecPolicyCreate(kSecPolicyAppleTestPPQSigning
, options
), errOut
);
2826 CFReleaseSafe(options
);
2830 @function SecPolicyCreateAppleTimeStamping
2831 @abstract Check for RFC3161 timestamping EKU.
2833 SecPolicyRef
SecPolicyCreateAppleTimeStamping(void)
2835 SecPolicyRef result
= NULL
;
2836 CFMutableDictionaryRef options
= NULL
;
2837 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2838 &kCFTypeDictionaryKeyCallBacks
,
2839 &kCFTypeDictionaryValueCallBacks
), errOut
);
2841 SecPolicyAddBasicX509Options(options
);
2843 /* Require id-kp-timeStamping extendedKeyUsage to be present. */
2844 add_eku(options
, &oidExtendedKeyUsageTimeStamping
);
2846 require(result
= SecPolicyCreate(kSecPolicyOIDAppleTimeStamping
, options
), errOut
);
2849 CFReleaseSafe(options
);
2854 @function SecPolicyCreateAppleATVAppSigning
2855 @abstract Check for intermediate certificate 'Apple Worldwide Developer Relations Certification Authority' by name,
2857 Leaf cert must have Digital Signature usage.
2858 Leaf cert must have Apple ATV App Signing marker OID (1.2.840.113635.100.6.1.24).
2859 Leaf cert must have 'Apple TVOS Application Signing' common name.
2861 SecPolicyRef
SecPolicyCreateAppleATVAppSigning(void)
2863 SecPolicyRef result
= NULL
;
2864 CFMutableDictionaryRef options
= NULL
;
2865 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2866 &kCFTypeDictionaryKeyCallBacks
,
2867 &kCFTypeDictionaryValueCallBacks
), errOut
);
2868 SecPolicyAddBasicCertOptions(options
);
2870 require(SecPolicyAddAppleAnchorOptions(options
), errOut
);
2871 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2873 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2874 CFSTR("Apple Worldwide Developer Relations Certification Authority"));
2875 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
,
2876 CFSTR("Apple TVOS Application Signing"));
2878 // Check that leaf has extension with "Apple ATV App Signing" prod oid (1.2.840.113635.100.6.1.24)
2879 add_leaf_marker(options
, &oidAppleCertExtATVAppSigningProd
);
2881 add_ku(options
, kSecKeyUsageDigitalSignature
);
2883 require(result
= SecPolicyCreate(kSecPolicyAppleATVAppSigning
, options
), errOut
);
2886 CFReleaseSafe(options
);
2891 @function SecPolicyCreateTestAppleATVAppSigning
2892 @abstract Check for intermediate certificate 'Apple Worldwide Developer Relations Certification Authority' by name,
2894 Leaf cert must have Digital Signature usage.
2895 Leaf cert must have Apple ATV App Signing Test marker OID (1.2.840.113635.100.6.1.24.1).
2896 Leaf cert must have 'TEST Apple TVOS Application Signing TEST' common name.
2898 SecPolicyRef
SecPolicyCreateTestAppleATVAppSigning(void)
2900 SecPolicyRef result
= NULL
;
2901 CFMutableDictionaryRef options
= NULL
;
2902 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2903 &kCFTypeDictionaryKeyCallBacks
,
2904 &kCFTypeDictionaryValueCallBacks
), errOut
);
2905 SecPolicyAddBasicCertOptions(options
);
2907 require(SecPolicyAddAppleAnchorOptions(options
), errOut
);
2908 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2910 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2911 CFSTR("Apple Worldwide Developer Relations Certification Authority"));
2912 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
,
2913 CFSTR("TEST Apple TVOS Application Signing TEST"));
2915 // Check that leaf has extension with "Apple ATV App Signing" test oid (1.2.840.113635.100.6.1.24.1)
2916 add_leaf_marker(options
, &oidAppleCertExtATVAppSigningTest
);
2918 add_ku(options
, kSecKeyUsageDigitalSignature
);
2920 require(result
= SecPolicyCreate(kSecPolicyAppleTestATVAppSigning
, options
), errOut
);
2923 CFReleaseSafe(options
);
2928 @function SecPolicyCreateApplePayIssuerEncryption
2929 @abstract Check for intermediate certificate 'Apple Worldwide Developer Relations CA - G2' by name,
2930 and ECC apple anchor.
2931 Leaf cert must have Key Encipherment and Key Agreement usage.
2932 Leaf cert must have Apple Pay Issuer Encryption marker OID (1.2.840.113635.100.6.39).
2934 SecPolicyRef
SecPolicyCreateApplePayIssuerEncryption(void)
2936 SecPolicyRef result
= NULL
;
2937 CFMutableDictionaryRef options
= NULL
;
2938 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2939 &kCFTypeDictionaryKeyCallBacks
,
2940 &kCFTypeDictionaryValueCallBacks
), errOut
);
2941 SecPolicyAddBasicCertOptions(options
);
2943 require(SecPolicyAddAnchorSHA1Options(options
, kAppleRootCA_ECC_SHA1
), errOut
);
2944 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2946 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2947 CFSTR("Apple Worldwide Developer Relations CA - G2"));
2949 // Check that leaf has extension with "Apple Pay Issuer Encryption" oid (1.2.840.113635.100.6.39)
2950 add_leaf_marker(options
, &oidAppleCertExtCryptoServicesExtEncryption
);
2952 add_ku(options
, kSecKeyUsageKeyEncipherment
);
2954 require(result
= SecPolicyCreate(kSecPolicyApplePayIssuerEncryption
, options
), errOut
);
2957 CFReleaseSafe(options
);
2962 @function SecPolicyCreateAppleATVVPNProfileSigning
2963 @abstract Check for leaf marker OID 1.2.840.113635.100.6.43,
2964 intermediate marker OID 1.2.840.113635.100.6.2.10,
2965 chains to Apple Root CA, path length 3
2967 SecPolicyRef
SecPolicyCreateAppleATVVPNProfileSigning(void)
2969 SecPolicyRef result
= NULL
;
2970 CFMutableDictionaryRef options
= NULL
;
2971 CFMutableDictionaryRef appleAnchorOptions
= NULL
;
2972 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2973 &kCFTypeDictionaryKeyCallBacks
,
2974 &kCFTypeDictionaryValueCallBacks
), errOut
);
2976 SecPolicyAddBasicCertOptions(options
);
2978 // Require pinning to the Apple CAs (including test CA for internal releases)
2979 appleAnchorOptions
= CFDictionaryCreateMutableForCFTypes(NULL
);
2980 require(appleAnchorOptions
, errOut
);
2982 if (SecIsInternalRelease()) {
2983 CFDictionarySetValue(appleAnchorOptions
,
2984 kSecPolicyAppleAnchorIncludeTestRoots
, kCFBooleanTrue
);
2987 add_element(options
, kSecPolicyCheckAnchorApple
, appleAnchorOptions
);
2989 // Cert chain length 3
2990 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2992 // Check leaf for Apple ATV VPN Profile Signing OID (1.2.840.113635.100.6.43)
2993 add_leaf_marker(options
, &oidAppleCertExtATVVPNProfileSigning
);
2995 // Check intermediate for Apple System Integration 2 CA intermediate marker (1.2.840.113635.100.6.2.10)
2996 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleSystemIntg2
);
2998 // Ensure that revocation is checked (OCSP only)
2999 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kCFBooleanFalse
);
3001 require(result
= SecPolicyCreate(kSecPolicyAppleATVVPNProfileSigning
, options
), errOut
);
3004 CFReleaseSafe(options
);
3005 CFReleaseSafe(appleAnchorOptions
);