2 * Copyright (c) 2007-2015 Apple Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
25 * SecPolicy.c - Implementation of various X.509 certificate trust policies
28 #include <Security/SecPolicyInternal.h>
29 #include <Security/SecPolicyPriv.h>
30 #include <AssertMacros.h>
32 #include <utilities/debugging.h>
33 #include <Security/SecInternal.h>
34 #include <CoreFoundation/CFDictionary.h>
35 #include <CoreFoundation/CFNumber.h>
36 #include <CoreFoundation/CFRuntime.h>
37 #include <CoreFoundation/CFString.h>
38 #include <CoreFoundation/CFTimeZone.h>
39 #include <Security/SecCertificateInternal.h>
40 #include <Security/SecCertificatePriv.h>
41 #include <libDER/oidsPriv.h>
42 #include <utilities/SecCFError.h>
43 #include <utilities/SecCFWrappers.h>
44 #include <utilities/array_size.h>
45 #include <ipc/securityd_client.h>
46 #if TARGET_OS_EMBEDDED
47 #include <MobileGestalt.h>
49 #include <sys/utsname.h>
52 #include <utilities/SecInternalReleasePriv.h>
54 /********************************************************
55 **************** SecPolicy Constants *******************
56 ********************************************************/
58 // MARK: SecPolicy Constants
60 #define SEC_CONST_DECL(k,v) const CFStringRef k = CFSTR(v);
62 /********************************************************
63 ************** Unverified Leaf Checks ******************
64 ********************************************************/
65 SEC_CONST_DECL (kSecPolicyCheckSSLHostname
, "SSLHostname");
66 SEC_CONST_DECL (kSecPolicyCheckEmail
, "email");
68 /* Checks that the issuer of the leaf has exactly one Common Name and that it
69 matches the specified string. */
70 SEC_CONST_DECL (kSecPolicyCheckIssuerCommonName
, "IssuerCommonName");
72 /* Checks that the leaf has exactly one Common Name and that it
73 matches the specified string. */
74 SEC_CONST_DECL (kSecPolicyCheckSubjectCommonName
, "SubjectCommonName");
76 /* Checks that the leaf has exactly one Common Name and that it has the
77 specified string as a prefix. */
78 SEC_CONST_DECL (kSecPolicyCheckSubjectCommonNamePrefix
, "SubjectCommonNamePrefix");
80 /* Checks that the leaf has exactly one Common Name and that it
81 matches the specified "<string>" or "TEST <string> TEST". */
82 SEC_CONST_DECL (kSecPolicyCheckSubjectCommonNameTEST
, "SubjectCommonNameTEST");
84 /* Checks that the leaf has exactly one Organization and that it
85 matches the specified string. */
86 SEC_CONST_DECL (kSecPolicyCheckSubjectOrganization
, "SubjectOrganization");
88 /* Checks that the leaf has exactly one Organizational Unit and that it
89 matches the specified string. */
90 SEC_CONST_DECL (kSecPolicyCheckSubjectOrganizationalUnit
, "SubjectOrganizationalUnit");
92 /* Check that the leaf is not valid before the specified date (or verifyDate
93 if none is provided?). */
94 SEC_CONST_DECL (kSecPolicyCheckNotValidBefore
, "NotValidBefore");
96 SEC_CONST_DECL (kSecPolicyCheckEAPTrustedServerNames
, "EAPTrustedServerNames");
98 SEC_CONST_DECL (kSecPolicyCheckCertificatePolicy
, "CertificatePolicy");
101 /* Check for basic constraints on leaf to be valid. (rfc5280 check) */
102 SEC_CONST_DECL (kSecPolicyCheckLeafBasicConstraints
, "LeafBasicContraints");
105 /********************************************************
106 *********** Unverified Intermediate Checks *************
107 ********************************************************/
108 SEC_CONST_DECL (kSecPolicyCheckKeyUsage
, "KeyUsage"); /* (rfc5280 check) */
109 SEC_CONST_DECL (kSecPolicyCheckExtendedKeyUsage
, "ExtendedKeyUsage"); /* (rfc5280 check) */
110 SEC_CONST_DECL (kSecPolicyCheckBasicContraints
, "BasicContraints"); /* (rfc5280 check) */
111 SEC_CONST_DECL (kSecPolicyCheckQualifiedCertStatements
, "QualifiedCertStatements"); /* (rfc5280 check) */
112 SEC_CONST_DECL (kSecPolicyCheckIntermediateSPKISHA256
, "IntermediateSPKISHA256")
114 /********************************************************
115 ************** Unverified Anchor Checks ****************
116 ********************************************************/
117 SEC_CONST_DECL (kSecPolicyCheckAnchorSHA1
, "AnchorSHA1");
119 /* Fake key for isAnchored check. */
120 SEC_CONST_DECL (kSecPolicyCheckAnchorTrusted
, "AnchorTrusted");
122 /* Anchor is one of the apple trust anchors */
123 SEC_CONST_DECL (kSecPolicyCheckAnchorApple
, "AnchorApple");
125 /* options for kSecPolicyCheckAnchorApple */
126 SEC_CONST_DECL (kSecPolicyAppleAnchorIncludeTestRoots
, "AnchorAppleTestRoots");
128 /********************************************************
129 *********** Unverified Certificate Checks **************
130 ********************************************************/
131 /* Unverified Certificate Checks (any of the above) */
132 SEC_CONST_DECL (kSecPolicyCheckNonEmptySubject
, "NonEmptySubject");
133 SEC_CONST_DECL (kSecPolicyCheckIdLinkage
, "IdLinkage") /* (rfc5280 check) */
135 SEC_CONST_DECL (kSecPolicyCheckValidityStarted
, "ValidStarted");
136 SEC_CONST_DECL (kSecPolicyCheckValidityExpired
, "ValidExpired");
138 SEC_CONST_DECL (kSecPolicyCheckValidIntermediates
, "ValidIntermediates");
139 SEC_CONST_DECL (kSecPolicyCheckValidLeaf
, "ValidLeaf");
140 SEC_CONST_DECL (kSecPolicyCheckValidRoot
, "ValidRoot");
144 /********************************************************
145 **************** Verified Path Checks ******************
146 ********************************************************/
147 /* (rfc5280 check) Ideally we should dynamically track all the extensions
148 we processed for each certificate and fail this test if any critical
149 extensions remain. */
150 SEC_CONST_DECL (kSecPolicyCheckCriticalExtensions
, "CriticalExtensions");
152 /* Check that the certificate chain length matches the specificed CFNumberRef
154 SEC_CONST_DECL (kSecPolicyCheckChainLength
, "ChainLength");
156 /* (rfc5280 check) */
157 SEC_CONST_DECL (kSecPolicyCheckBasicCertificateProcessing
, "BasicCertificateProcessing");
159 /********************************************************
160 ******************* Feature toggles ********************
161 ********************************************************/
163 /* Check revocation if specified. */
164 SEC_CONST_DECL (kSecPolicyCheckExtendedValidation
, "ExtendedValidation");
165 SEC_CONST_DECL (kSecPolicyCheckRevocation
, "Revocation");
166 SEC_CONST_DECL (kSecPolicyCheckRevocationResponseRequired
, "RevocationResponseRequired");
168 /* Check Certificate Transparency if specified. */
169 SEC_CONST_DECL (kSecPolicyCheckCertificateTransparency
, "CertificateTransparency");
171 /* If present and true, we never go out to the network for anything
172 (OCSP, CRL or CA Issuer checking) but just used cached data instead. */
173 SEC_CONST_DECL (kSecPolicyCheckNoNetworkAccess
, "NoNetworkAccess");
175 /* Hack to quickly blacklist certain certs. */
176 SEC_CONST_DECL (kSecPolicyCheckBlackListedLeaf
, "BlackListedLeaf");
177 SEC_CONST_DECL (kSecPolicyCheckGrayListedLeaf
, "GrayListedLeaf");
178 SEC_CONST_DECL (kSecPolicyCheckGrayListedKey
, "GrayListedKey");
179 SEC_CONST_DECL (kSecPolicyCheckBlackListedKey
, "BlackListedKey");
181 SEC_CONST_DECL (kSecPolicyCheckLeafMarkerOid
, "CheckLeafMarkerOid");
182 SEC_CONST_DECL (kSecPolicyCheckIntermediateMarkerOid
, "CheckIntermediateMarkerOid");
184 /* Public policy names. */
185 SEC_CONST_DECL (kSecPolicyAppleX509Basic
, "1.2.840.113635.100.1.2");
186 SEC_CONST_DECL (kSecPolicyAppleSSL
, "1.2.840.113635.100.1.3");
187 SEC_CONST_DECL (kSecPolicyAppleSMIME
, "1.2.840.113635.100.1.8");
188 SEC_CONST_DECL (kSecPolicyAppleEAP
, "1.2.840.113635.100.1.9");
189 SEC_CONST_DECL (kSecPolicyAppleSWUpdateSigning
, "1.2.840.113635.100.1.10");
190 SEC_CONST_DECL (kSecPolicyAppleIPsec
, "1.2.840.113635.100.1.11");
191 SEC_CONST_DECL (kSecPolicyApplePKINITClient
, "1.2.840.113635.100.1.14");
192 SEC_CONST_DECL (kSecPolicyApplePKINITServer
, "1.2.840.113635.100.1.15");
193 SEC_CONST_DECL (kSecPolicyAppleCodeSigning
, "1.2.840.113635.100.1.16");
194 SEC_CONST_DECL (kSecPolicyApplePackageSigning
, "1.2.840.113635.100.1.17");
195 SEC_CONST_DECL (kSecPolicyAppleIDValidation
, "1.2.840.113635.100.1.18");
196 SEC_CONST_DECL (kSecPolicyMacAppStoreReceipt
, "1.2.840.113635.100.1.19");
197 SEC_CONST_DECL (kSecPolicyAppleTimeStamping
, "1.2.840.113635.100.1.20");
198 SEC_CONST_DECL (kSecPolicyAppleRevocation
, "1.2.840.113635.100.1.21");
199 SEC_CONST_DECL (kSecPolicyApplePassbookSigning
, "1.2.840.113635.100.1.22");
200 SEC_CONST_DECL (kSecPolicyAppleMobileStore
, "1.2.840.113635.100.1.23");
201 SEC_CONST_DECL (kSecPolicyAppleEscrowService
, "1.2.840.113635.100.1.24");
202 SEC_CONST_DECL (kSecPolicyAppleProfileSigner
, "1.2.840.113635.100.1.25");
203 SEC_CONST_DECL (kSecPolicyAppleQAProfileSigner
, "1.2.840.113635.100.1.26");
204 SEC_CONST_DECL (kSecPolicyAppleTestMobileStore
, "1.2.840.113635.100.1.27");
205 SEC_CONST_DECL (kSecPolicyAppleOTAPKISigner
, "1.2.840.113635.100.1.28");
206 SEC_CONST_DECL (kSecPolicyAppleTestOTAPKISigner
, "1.2.840.113635.100.1.29");
207 /* FIXME: this policy name should be deprecated and replaced with "kSecPolicyAppleIDValidationRecordSigning" */
208 SEC_CONST_DECL (kSecPolicyAppleIDValidationRecordSigningPolicy
, "1.2.840.113625.100.1.30");
209 SEC_CONST_DECL (kSecPolicyAppleSMPEncryption
, "1.2.840.113625.100.1.31");
210 SEC_CONST_DECL (kSecPolicyAppleTestSMPEncryption
, "1.2.840.113625.100.1.32");
211 SEC_CONST_DECL (kSecPolicyAppleServerAuthentication
, "1.2.840.113635.100.1.33");
212 SEC_CONST_DECL (kSecPolicyApplePCSEscrowService
, "1.2.840.113635.100.1.34");
213 SEC_CONST_DECL (kSecPolicyApplePPQSigning
, "1.2.840.113625.100.1.35");
214 SEC_CONST_DECL (kSecPolicyAppleTestPPQSigning
, "1.2.840.113625.100.1.36");
215 SEC_CONST_DECL (kSecPolicyAppleATVAppSigning
, "1.2.840.113625.100.1.37");
216 SEC_CONST_DECL (kSecPolicyAppleTestATVAppSigning
, "1.2.840.113625.100.1.38");
217 SEC_CONST_DECL (kSecPolicyApplePayIssuerEncryption
, "1.2.840.113625.100.1.39");
218 SEC_CONST_DECL (kSecPolicyAppleOSXProvisioningProfileSigning
, "1.2.840.113625.100.1.40");
219 SEC_CONST_DECL (kSecPolicyAppleATVVPNProfileSigning
, "1.2.840.113625.100.1.41");
220 // TODO need confirmation that OID for kSecPolicyAppleATVVPNProfileSigning is reserved
222 SEC_CONST_DECL (kSecPolicyOid
, "SecPolicyOid");
223 SEC_CONST_DECL (kSecPolicyName
, "SecPolicyName");
224 SEC_CONST_DECL (kSecPolicyClient
, "SecPolicyClient");
225 SEC_CONST_DECL (kSecPolicyRevocationFlags
, "SecPolicyRevocationFlags");
226 SEC_CONST_DECL (kSecPolicyTeamIdentifier
, "SecPolicyTeamIdentifier");
228 /* Private policy names */
229 static CFStringRef kSecPolicyOIDBasicX509
= CFSTR("basicX509");
230 static CFStringRef kSecPolicyOIDSSLServer
= CFSTR("sslServer");
231 static CFStringRef kSecPolicyOIDSSLClient
= CFSTR("sslClient");
232 static CFStringRef kSecPolicyOIDiPhoneActivation
= CFSTR("iPhoneActivation");
233 static CFStringRef kSecPolicyOIDiPhoneDeviceCertificate
=
234 CFSTR("iPhoneDeviceCertificate");
235 static CFStringRef kSecPolicyOIDFactoryDeviceCertificate
=
236 CFSTR("FactoryDeviceCertificate");
237 static CFStringRef kSecPolicyOIDiAP
= CFSTR("iAP");
238 static CFStringRef kSecPolicyOIDiTunesStoreURLBag
= CFSTR("iTunesStoreURLBag");
239 static CFStringRef kSecPolicyOIDEAPServer
= CFSTR("eapServer");
240 static CFStringRef kSecPolicyOIDEAPClient
= CFSTR("eapClient");
241 static CFStringRef kSecPolicyOIDIPSecServer
= CFSTR("ipsecServer");
242 static CFStringRef kSecPolicyOIDIPSecClient
= CFSTR("ipsecClient");
243 static CFStringRef kSecPolicyOIDiPhoneApplicationSigning
=
244 CFSTR("iPhoneApplicationSigning");
245 static CFStringRef kSecPolicyOIDiPhoneProfileApplicationSigning
=
246 CFSTR("iPhoneProfileApplicationSigning");
247 static CFStringRef kSecPolicyOIDiPhoneProvisioningProfileSigning
=
248 CFSTR("iPhoneProvisioningProfileSigning");
249 static CFStringRef kSecPolicyOIDAppleSWUpdateSigning
= CFSTR("AppleSWUpdateSigning");
250 static CFStringRef kSecPolicyOIDAppleTVOSApplicationSigning
=
251 CFSTR("AppleTVApplicationSigning");
252 static CFStringRef kSecPolicyOIDRevocation
= CFSTR("revocation");
253 static CFStringRef kSecPolicyOIDOCSPSigner
= CFSTR("OCSPSigner");
254 static CFStringRef kSecPolicyOIDSMIME
= CFSTR("SMIME");
255 static CFStringRef kSecPolicyOIDCodeSigning
= CFSTR("CodeSigning");
256 static CFStringRef kSecPolicyOIDPackageSigning
= CFSTR("PackageSigning");
257 static CFStringRef kSecPolicyOIDLockdownPairing
= CFSTR("LockdownPairing");
258 static CFStringRef kSecPolicyOIDURLBag
= CFSTR("URLBag");
259 static CFStringRef kSecPolicyOIDOTATasking
= CFSTR("OTATasking");
260 static CFStringRef kSecPolicyOIDMobileAsset
= CFSTR("MobileAsset");
261 static CFStringRef kSecPolicyOIDAppleIDAuthority
= CFSTR("AppleIDAuthority");
262 static CFStringRef kSecPolicyOIDMacAppStoreReceipt
= CFSTR("MacAppStoreReceipt");
263 static CFStringRef kSecPolicyOIDAppleTimeStamping
= CFSTR("AppleTimeStamping");
264 static CFStringRef kSecPolicyOIDApplePassbook
= CFSTR("ApplePassbook");
265 static CFStringRef kSecPolicyOIDAppleMobileStore
= CFSTR("AppleMobileStore");
266 static CFStringRef kSecPolicyOIDAppleTestMobileStore
= CFSTR("AppleTestMobileStore");
267 static CFStringRef kSecPolicyOIDAppleEscrowService
= CFSTR("AppleEscrowService");
268 static CFStringRef kSecPolicyOIDApplePCSEscrowService
= CFSTR("ApplePCSEscrowService");
269 static CFStringRef kSecPolicyOIDAppleProfileSigner
= CFSTR("AppleProfileSigner");
270 static CFStringRef kSecPolicyOIDAppleQAProfileSigner
= CFSTR("AppleQAProfileSigner");
271 static CFStringRef kSecPolicyOIDAppleOTAPKIAssetSigner
= CFSTR("AppleOTAPKIAssetSigner");
272 static CFStringRef kSecPolicyOIDAppleTestOTAPKIAssetSigner
= CFSTR("AppleTestOTAPKIAssetSigner");
273 static CFStringRef kSecPolicyOIDAppleIDValidationRecordSigningPolicy
= CFSTR("AppleIDValidationRecordSigningPolicy");
274 static CFStringRef kSecPolicyOIDAppleATVAppSigning
= CFSTR("AppleATVAppSigning");
275 static CFStringRef kSecPolicyOIDAppleTestATVAppSigning
= CFSTR("AppleTestATVAppSigning");
276 static CFStringRef kSecPolicyOIDApplePayIssuerEncryption
= CFSTR("ApplePayIssuerEncryption");
277 static CFStringRef kSecPolicyOIDAppleOSXProvisioningProfileSigning
= CFSTR("AppleOSXProvisioningProfileSigning");
278 static CFStringRef kSecPolicyOIDAppleATVVPNProfileSigning
= CFSTR("AppleATVVPNProfileSigning");
280 /* Policies will now change to multiple categories of checks.
282 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.
283 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.
285 kSecPolicySLCheck Static Subscriber Certificate Checks
286 kSecPolicySICheck Static Subsidiary CA Checks
287 kSecPolicySACheck Static Anchor Checks
289 kSecPolicyDLCheck Dynamic Subscriber Certificate Checks
290 kSecPolicyDICheck Dynamic Subsidiary CA Checks
291 kSecPolicyDACheck Dynamic Anchor Checks ? not yet needed other than to
292 possibly exclude in a exception template (but those should still be per
293 certificate --- i.o.w. exceptions (or a database backed multiple role/user
294 trust store of some sort) and policies are 2 different things and this
295 text is about policies.
297 All static checks are only allowed to consider the certificate in isolation,
298 just given the position in the chain or the cert (leaf, intermidate, root).
299 dynamic checks can make determinations about the chain as a whole.
301 Static Subscriber Certificate Checks will be done up front before the
302 chainbuilder is even instantiated. If they fail and details aren't required
303 by the client (if no exceptions were present for this certificate) we could
304 short circuit fail the evaluation.
305 IDEA: These checks can dynamically add new checks...[needs work]
306 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
307 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
308 equivalent subtree from that level down. So SSL has EV as a subpolicy, but
309 EV dynamically enables the ocsp or crl or dcrl or any combination thereof subpolicies.
311 Static Subsidiary CA Checks will be used by the chain-builder to choose the
312 best parents to evaluate first. This feature is currently already implemented
313 but with a hardcoded is_valid(verifyTime) check. Instead we will evaluate all
314 Static Subsidiary CA Checks. The results of these checks for purposes of
315 generating details could be cached in the SecCertificatePathRefs themselves, or we can short circuit fail and recalc details on demand later.
317 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.
319 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.
321 Dynamic Subsidiary CA Checks might not be needed to have custom
322 implementations, since they are all done as part of the rfc5280 checks now.
323 This assumes that checks like issuer common name includes 'foo' are
324 implmented as Static Subscriber Certificate Checks instead.
326 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.
329 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.
331 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.
333 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.
335 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.
337 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.
339 We need to remember the best successful chain we find, where best is defined by: satisfies as many optional policies as possible.
341 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.
343 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.
345 Example sectrust operation in psuedocode:
349 new builder(verifyTime, certificates, anchors, anchorsOnly, policies);
350 chain = builder.subscriber_only_chain;
351 foreach (policy in policies{kSecPolicySLCheck}) {
352 foreach(check in policy)
353 SecPolicyRunCheck(builder, chain, check, details);
354 foreach (subpolicy in policy) {
355 check_policy(builder, chain, subpolicy, details{subpolicy.name})
357 propagate_subpolicy_results(builder, chain, details);
359 while (chain = builder.next) {
360 for (depth = 0; p_d = policies.at_depth(depth),
361 d_p_d = dynamic_policies.at_depth(depth), p_d || d_p_d; ++depth)
363 // Modify SecPathBuilderIsPartial() to
364 // run builder_check(buildier, policies, kSecPolicySICheck) instead
365 // of SecCertificateIsValid. Also rename considerExpired to
366 // considerSIFailures.
367 foreach (policy in p_d) {
368 check_policy(builder, chain, policy, kSecPolicySICheck, depth);
370 /// Recalculate since the static checks might have added new dynamic
372 d_p_d = dynamic_policies.at_depth(depth);
373 foreach (policy in d_p_d) {
374 check_policy(builder, chain, policy, kSecPolicySICheck, depth);
376 if (chain.is_anchored) {
377 foreach (policy in p_d) {
378 check_policy(builder, chain, policy, kSecPolicySACheck, depth);
380 foreach (policy in d_p_d) {
381 check_policy(builder, chain, policy, kSecPolicySACheck, depth);
383 foreach (policy in p_d) {
384 check_policy(builder, chain, policy, kSecPolicyDACheck, depth);
386 foreach (policy in d_p_d) {
387 check_policy(builder, chain, policy, kSecPolicyDACheck, depth);
390 foreach (policy in policies) {
391 check_policy(builder, chain, policy, kSecPolicySACheck, depth);
392 check_policy(builder, chain, policy, kSecPolicyDACheck, depth);
394 foreach (policy in policies{kSecPolicySDCheck}) {
399 check_policy(builder, chain, policy, check_class, details, depth) {
401 foreach(check in policy{check_class}) {
402 SecPolicyRunCheck(builder, chain, check, details);
406 foreach (subpolicy in policy) {
407 if (!check_policy(builder, chain, subpolicy, check_class,
408 details{subpolicy.name}) && subpolicy.is_required, depth)
412 propagate_subpolicy_results(builder, chain, details);
419 #define kSecPolicySHA1Size 20
420 #define kSecPolicySHA256Size 32
421 const UInt8 kAppleCASHA1
[kSecPolicySHA1Size
] = {
422 0x61, 0x1E, 0x5B, 0x66, 0x2C, 0x59, 0x3A, 0x08, 0xFF, 0x58,
423 0xD1, 0x4A, 0xE2, 0x24, 0x52, 0xD1, 0x98, 0xDF, 0x6C, 0x60
426 __unused
static const UInt8 kAppleTESTCASHA1
[kSecPolicySHA1Size
] = {
427 0xbc, 0x30, 0x55, 0xc8, 0xc8, 0xd3, 0x48, 0x3f, 0xf4, 0x8d,
428 0xfe, 0x3d, 0x51, 0x75, 0x31, 0xc9, 0xf4, 0xd7, 0x4a, 0xf7
431 static const UInt8 kITMSCASHA1
[kSecPolicySHA1Size
] = {
432 0x1D, 0x33, 0x42, 0x46, 0x8B, 0x10, 0xBD, 0xE6, 0x45, 0xCE,
433 0x44, 0x6E, 0xBB, 0xE8, 0xF5, 0x03, 0x5D, 0xF8, 0x32, 0x22
436 static const UInt8 kFactoryDeviceCASHA1
[kSecPolicySHA1Size
] = {
437 0xef, 0x68, 0x73, 0x17, 0xa4, 0xf8, 0xf9, 0x4b, 0x7b, 0x21,
438 0xe2, 0x2f, 0x09, 0x8f, 0xfd, 0x6a, 0xae, 0xc0, 0x0d, 0x63
441 static const UInt8 kApplePKISettingsAuthority
[kSecPolicySHA1Size
] = {
442 0x1D, 0x0C, 0xBA, 0xAD, 0x17, 0xFD, 0x7E, 0x9E, 0x9F, 0xF1,
443 0xC9, 0xA2, 0x66, 0x79, 0x60, 0x00, 0x8B, 0xAE, 0x70, 0xB8
446 static const UInt8 kAppleTestPKISettingsAuthority
[kSecPolicySHA1Size
] = {
447 0xDB, 0xBA, 0x25, 0x0B, 0xD8, 0x62, 0x71, 0x87, 0x54, 0x7E,
448 0xD7, 0xEF, 0x11, 0x94, 0x7E, 0x82, 0xE6, 0xD8, 0x1C, 0x9A
451 static const UInt8 kTestAppleRootCA_ECC_SHA1
[kSecPolicySHA1Size
] = {
452 0x62, 0x0A, 0xED, 0x83, 0xD2, 0x97, 0x4A, 0x77, 0x56, 0x33,
453 0x83, 0xBE, 0xDB, 0xF9, 0xA1, 0xBD, 0x5F, 0xFE, 0x55, 0x7B
456 static const UInt8 kAppleRootCA_ECC_SHA1
[kSecPolicySHA1Size
] = {
457 0xB5, 0x2C, 0xB0, 0x2F, 0xD5, 0x67, 0xE0, 0x35, 0x9F, 0xE8,
458 0xFA, 0x4D, 0x4C, 0x41, 0x03, 0x79, 0x70, 0xFE, 0x01, 0xB0
463 /********************************************************
464 ****************** SecPolicy object ********************
465 ********************************************************/
467 static void SecPolicyDestroy(CFTypeRef cf
) {
468 SecPolicyRef policy
= (SecPolicyRef
) cf
;
469 CFRelease(policy
->_oid
);
470 CFRelease(policy
->_options
);
473 static Boolean
SecPolicyCompare(CFTypeRef cf1
, CFTypeRef cf2
) {
474 SecPolicyRef policy1
= (SecPolicyRef
) cf1
;
475 SecPolicyRef policy2
= (SecPolicyRef
) cf2
;
476 return CFEqual(policy1
->_oid
, policy2
->_oid
) &&
477 CFEqual(policy1
->_options
, policy2
->_options
);
480 static CFHashCode
SecPolicyHash(CFTypeRef cf
) {
481 SecPolicyRef policy
= (SecPolicyRef
) cf
;
483 return CFHash(policy
->_oid
) + CFHash(policy
->_options
);
486 static CFStringRef
SecPolicyCopyFormatDescription(CFTypeRef cf
, CFDictionaryRef formatOptions
) {
487 SecPolicyRef policy
= (SecPolicyRef
) cf
;
488 CFMutableStringRef desc
= CFStringCreateMutable(kCFAllocatorDefault
, 0);
489 CFStringRef typeStr
= CFCopyTypeIDDescription(CFGetTypeID(cf
));
490 CFStringAppendFormat(desc
, NULL
,
491 CFSTR("<%@: oid: %@ options %@"), typeStr
,
492 policy
->_oid
, policy
->_options
);
494 CFStringAppend(desc
, CFSTR(" >"));
499 /* SecPolicy API functions. */
500 CFGiblisWithHashFor(SecPolicy
);
502 /* AUDIT[securityd](done):
503 oid (ok) is a caller provided string, only its cf type has been checked.
504 options is a caller provided dictionary, only its cf type has been checked.
506 SecPolicyRef
SecPolicyCreate(CFStringRef oid
, CFDictionaryRef options
) {
507 SecPolicyRef result
= NULL
;
509 require(oid
, errOut
);
510 require(options
, errOut
);
512 (SecPolicyRef
)_CFRuntimeCreateInstance(kCFAllocatorDefault
,
513 SecPolicyGetTypeID(),
514 sizeof(struct __SecPolicy
) - sizeof(CFRuntimeBase
), 0), errOut
);
519 result
->_options
= options
;
525 SecPolicyRef
SecPolicyCreateWithProperties(CFTypeRef policyIdentifier
,
526 CFDictionaryRef properties
) {
527 // Creates a policy reference for a given policy object identifier.
528 // If policy-specific parameters can be supplied (e.g. hostname),
529 // attempt to obtain from input properties dictionary.
530 // Returns NULL if the given identifier is unsupported.
532 SecPolicyRef policy
= NULL
;
533 CFStringRef name
= NULL
;
534 CFStringRef teamID
= NULL
;
535 Boolean client
= false;
536 require(policyIdentifier
&& (CFStringGetTypeID() == CFGetTypeID(policyIdentifier
)), errOut
);
539 name
= CFDictionaryGetValue(properties
, kSecPolicyName
);
540 teamID
= CFDictionaryGetValue(properties
, kSecPolicyTeamIdentifier
);
542 CFBooleanRef dictionaryClientValue
;
543 client
= (CFDictionaryGetValueIfPresent(properties
, kSecPolicyClient
, (const void **)&dictionaryClientValue
) &&
544 (dictionaryClientValue
!= NULL
) && CFEqual(kCFBooleanTrue
, dictionaryClientValue
));
547 if (CFEqual(policyIdentifier
, kSecPolicyAppleX509Basic
)) {
548 policy
= SecPolicyCreateBasicX509();
550 else if (CFEqual(policyIdentifier
, kSecPolicyAppleSSL
)) {
551 policy
= SecPolicyCreateSSL(!client
, name
);
553 else if (CFEqual(policyIdentifier
, kSecPolicyAppleEAP
)) {
554 CFArrayRef array
= NULL
;
556 array
= CFArrayCreate(kCFAllocatorDefault
, (const void **)&name
, 1, &kCFTypeArrayCallBacks
);
558 policy
= SecPolicyCreateEAP(!client
, array
);
559 CFReleaseSafe(array
);
561 else if (CFEqual(policyIdentifier
, kSecPolicyApplePackageSigning
)) {
562 policy
= SecPolicyCreateApplePackageSigning();
564 else if (CFEqual(policyIdentifier
, kSecPolicyAppleSWUpdateSigning
)) {
565 policy
= SecPolicyCreateAppleSWUpdateSigning();
567 else if (CFEqual(policyIdentifier
, kSecPolicyAppleIPsec
)) {
568 policy
= SecPolicyCreateIPSec(!client
, name
);
570 else if (CFEqual(policyIdentifier
, kSecPolicyAppleRevocation
)) {
571 policy
= SecPolicyCreateRevocation(kSecRevocationUseAnyAvailableMethod
);
573 else if (CFEqual(policyIdentifier
, kSecPolicyAppleSMIME
)) {
574 policy
= SecPolicyCreateSMIME(kSecSignSMIMEUsage
| kSecAnyEncryptSMIME
, name
);
576 else if (CFEqual(policyIdentifier
, kSecPolicyAppleCodeSigning
)) {
577 policy
= SecPolicyCreateCodeSigning();
579 else if (CFEqual(policyIdentifier
, kSecPolicyAppleTimeStamping
)) {
580 policy
= SecPolicyCreateAppleTimeStamping();
582 else if (CFEqual(policyIdentifier
, kSecPolicyMacAppStoreReceipt
)) {
583 policy
= SecPolicyCreateMacAppStoreReceipt();
585 else if (CFEqual(policyIdentifier
, kSecPolicyAppleIDValidation
)) {
586 policy
= SecPolicyCreateAppleIDAuthorityPolicy();
588 else if (CFEqual(policyIdentifier
, kSecPolicyApplePassbookSigning
)) {
589 policy
= SecPolicyCreatePassbookCardSigner(name
, teamID
);
591 else if (CFEqual(policyIdentifier
, kSecPolicyAppleMobileStore
)) {
592 policy
= SecPolicyCreateMobileStoreSigner();
594 else if (CFEqual(policyIdentifier
, kSecPolicyAppleTestMobileStore
)) {
595 policy
= SecPolicyCreateTestMobileStoreSigner();
597 else if (CFEqual(policyIdentifier
, kSecPolicyAppleEscrowService
)) {
598 policy
= SecPolicyCreateEscrowServiceSigner();
600 else if (CFEqual(policyIdentifier
, kSecPolicyApplePCSEscrowService
)) {
601 policy
= SecPolicyCreatePCSEscrowServiceSigner();
603 else if (CFEqual(policyIdentifier
, kSecPolicyAppleProfileSigner
)) {
604 policy
= SecPolicyCreateConfigurationProfileSigner();
606 else if (CFEqual(policyIdentifier
, kSecPolicyAppleQAProfileSigner
)) {
607 policy
= SecPolicyCreateQAConfigurationProfileSigner();
609 else if (CFEqual(policyIdentifier
, kSecPolicyAppleServerAuthentication
)) {
610 policy
= SecPolicyCreateAppleSSLService(name
);
612 #if TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR
613 else if (CFEqual(policyIdentifier
, kSecPolicyAppleOTAPKISigner
)) {
614 policy
= SecPolicyCreateOTAPKISigner();
616 else if (CFEqual(policyIdentifier
, kSecPolicyAppleTestOTAPKISigner
)) {
617 policy
= SecPolicyCreateTestOTAPKISigner();
619 else if (CFEqual(policyIdentifier
, kSecPolicyAppleIDValidationRecordSigningPolicy
)) {
620 policy
= SecPolicyCreateAppleIDValidationRecordSigningPolicy();
622 else if (CFEqual(policyIdentifier
, kSecPolicyAppleSMPEncryption
)) {
623 policy
= SecPolicyCreateAppleSMPEncryption();
625 else if (CFEqual(policyIdentifier
, kSecPolicyAppleTestSMPEncryption
)) {
626 policy
= SecPolicyCreateTestAppleSMPEncryption();
628 else if (CFEqual(policyIdentifier
, kSecPolicyAppleATVAppSigning
)) {
629 policy
= SecPolicyCreateAppleATVAppSigning();
631 else if (CFEqual(policyIdentifier
, kSecPolicyAppleTestATVAppSigning
)) {
632 policy
= SecPolicyCreateTestAppleATVAppSigning();
635 else if (CFEqual(policyIdentifier
, kSecPolicyApplePPQSigning
)) {
636 policy
= SecPolicyCreateApplePPQSigning();
638 else if (CFEqual(policyIdentifier
, kSecPolicyAppleTestPPQSigning
)) {
639 policy
= SecPolicyCreateTestApplePPQSigning();
641 else if (CFEqual(policyIdentifier
, kSecPolicyApplePayIssuerEncryption
)) {
642 policy
= SecPolicyCreateApplePayIssuerEncryption();
644 else if (CFEqual(policyIdentifier
, kSecPolicyAppleATVVPNProfileSigning
)) {
645 policy
= SecPolicyCreateAppleATVVPNProfileSigning();
648 secerror("ERROR: policy \"%@\" is unsupported", policyIdentifier
);
655 CFDictionaryRef
SecPolicyCopyProperties(SecPolicyRef policyRef
) {
656 // Builds and returns a dictionary which the caller must release.
658 #pragma clang diagnostic push
659 #pragma clang diagnostic ignored "-Wnonnull"
660 // After introducing nullability annotations, policyRef is supposed to be nonnull, suppress the warning
661 if (!policyRef
) return NULL
;
662 #pragma clang diagnostic pop
663 CFMutableDictionaryRef properties
= CFDictionaryCreateMutable(NULL
, 0,
664 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
665 #pragma clang diagnostic push
666 #pragma clang diagnostic ignored "-Wnonnull"
667 // 'properties' is nonnull in reality suppress the warning
668 if (!properties
) return NULL
;
669 #pragma clang diagnostic pop
670 CFStringRef oid
= (CFStringRef
) CFRetain(policyRef
->_oid
);
671 CFTypeRef nameKey
= NULL
;
673 // Convert private to public OID if we have one
674 CFStringRef outOid
= oid
;
675 if (CFEqual(oid
, kSecPolicyOIDBasicX509
)) {
676 outOid
= kSecPolicyAppleX509Basic
;
678 else if (CFEqual(oid
, kSecPolicyOIDSSLServer
) ||
679 CFEqual(oid
, kSecPolicyOIDSSLClient
)) {
680 outOid
= kSecPolicyAppleSSL
;
681 nameKey
= kSecPolicyCheckSSLHostname
;
683 else if (CFEqual(oid
, kSecPolicyOIDEAPServer
) ||
684 CFEqual(oid
, kSecPolicyOIDEAPClient
)) {
685 outOid
= kSecPolicyAppleEAP
;
686 nameKey
= kSecPolicyCheckEAPTrustedServerNames
;
688 else if (CFEqual(oid
, kSecPolicyOIDIPSecServer
) ||
689 CFEqual(oid
, kSecPolicyOIDIPSecClient
)) {
690 outOid
= kSecPolicyAppleIPsec
;
691 nameKey
= kSecPolicyCheckSSLHostname
;
693 else if (CFEqual(oid
, kSecPolicyOIDRevocation
)) {
694 outOid
= kSecPolicyAppleRevocation
;
696 else if (CFEqual(oid
, kSecPolicyOIDSMIME
)) {
697 outOid
= kSecPolicyAppleSMIME
;
698 nameKey
= kSecPolicyCheckEmail
;
700 else if (CFEqual(oid
, kSecPolicyOIDCodeSigning
)) {
701 outOid
= kSecPolicyAppleCodeSigning
;
703 else if (CFEqual(oid
, kSecPolicyOIDAppleIDAuthority
)) {
704 outOid
= kSecPolicyAppleIDValidation
;
706 else if (CFEqual(oid
, kSecPolicyOIDApplePassbook
)) {
707 outOid
= kSecPolicyApplePassbookSigning
;
709 else if (CFEqual(oid
, kSecPolicyOIDAppleMobileStore
)) {
710 outOid
= kSecPolicyAppleMobileStore
;
712 else if (CFEqual(oid
, kSecPolicyOIDAppleTestMobileStore
)) {
713 outOid
= kSecPolicyAppleTestMobileStore
;
715 else if (CFEqual(oid
, kSecPolicyOIDAppleEscrowService
)) {
716 outOid
= kSecPolicyAppleEscrowService
;
718 else if (CFEqual(oid
, kSecPolicyOIDApplePCSEscrowService
)) {
719 outOid
= kSecPolicyApplePCSEscrowService
;
721 else if (CFEqual(oid
, kSecPolicyOIDAppleProfileSigner
)) {
722 outOid
= kSecPolicyAppleProfileSigner
;
724 else if (CFEqual(oid
, kSecPolicyOIDAppleQAProfileSigner
)) {
725 outOid
= kSecPolicyAppleQAProfileSigner
;
727 #if TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR
728 else if (CFEqual(oid
, kSecPolicyOIDAppleOTAPKIAssetSigner
)) {
729 outOid
= kSecPolicyAppleOTAPKISigner
;
731 else if (CFEqual(oid
, kSecPolicyOIDAppleTestOTAPKIAssetSigner
)) {
732 outOid
= kSecPolicyAppleTestOTAPKISigner
;
734 else if (CFEqual(oid
, kSecPolicyOIDAppleIDValidationRecordSigningPolicy
)) {
735 outOid
= kSecPolicyAppleIDValidationRecordSigningPolicy
;
737 else if (CFEqual(oid
, kSecPolicyOIDAppleATVAppSigning
)) {
738 outOid
= kSecPolicyAppleATVAppSigning
;
740 else if (CFEqual(oid
, kSecPolicyOIDAppleTestATVAppSigning
)) {
741 outOid
= kSecPolicyAppleTestATVAppSigning
;
744 else if (CFEqual(oid
, kSecPolicyOIDApplePayIssuerEncryption
)) {
745 outOid
= kSecPolicyApplePayIssuerEncryption
;
747 else if (CFEqual(oid
, kSecPolicyOIDAppleOSXProvisioningProfileSigning
)) {
748 outOid
= kSecPolicyAppleOSXProvisioningProfileSigning
;
750 else if (CFEqual(oid
, kSecPolicyOIDAppleATVVPNProfileSigning
)) {
751 outOid
= kSecPolicyAppleATVVPNProfileSigning
;
755 CFDictionarySetValue(properties
, (const void *)kSecPolicyOid
,
756 (const void *)outOid
);
758 // Set kSecPolicyName if we have one
759 if (nameKey
&& policyRef
->_options
) {
760 CFTypeRef name
= (CFTypeRef
) CFDictionaryGetValue(policyRef
->_options
,
763 CFDictionarySetValue(properties
, (const void *)kSecPolicyName
,
768 // Set kSecPolicyClient
769 if (CFEqual(oid
, kSecPolicyOIDSSLClient
) ||
770 CFEqual(oid
, kSecPolicyOIDIPSecClient
) ||
771 CFEqual(oid
, kSecPolicyOIDEAPClient
)) {
772 CFDictionarySetValue(properties
, (const void *)kSecPolicyClient
,
773 (const void *)kCFBooleanTrue
);
780 static void SecPolicySetOid(SecPolicyRef policy
, CFStringRef oid
) {
781 if (!policy
|| !oid
) return;
782 CFStringRef temp
= policy
->_oid
;
788 CFStringRef
SecPolicyGetOidString(SecPolicyRef policy
) {
792 CFDictionaryRef
SecPolicyGetOptions(SecPolicyRef policy
) {
793 return policy
->_options
;
796 void SecPolicySetOptionsValue(SecPolicyRef policy
, CFStringRef key
, CFTypeRef value
) {
797 if (!policy
|| !key
) return;
798 CFMutableDictionaryRef options
= (CFMutableDictionaryRef
) policy
->_options
;
800 options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
801 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
802 if (!options
) return;
803 policy
->_options
= options
;
805 CFDictionarySetValue(options
, key
, value
);
809 // this is declared as NA for iPhone in SecPolicy.h, so declare here
810 OSStatus
SecPolicySetProperties(SecPolicyRef policyRef
, CFDictionaryRef properties
);
813 OSStatus
SecPolicySetProperties(SecPolicyRef policyRef
, CFDictionaryRef properties
) {
814 // Set policy options based on the provided dictionary keys.
816 if (!(policyRef
&& properties
&& (CFDictionaryGetTypeID() == CFGetTypeID(properties
)))) {
819 CFStringRef oid
= (CFStringRef
) CFRetain(policyRef
->_oid
);
820 OSStatus result
= errSecSuccess
;
823 CFTypeRef name
= NULL
;
824 if (CFDictionaryGetValueIfPresent(properties
, (const void *)kSecPolicyName
,
825 (const void **)&name
) && name
) {
826 CFTypeID typeID
= CFGetTypeID(name
);
827 if (CFEqual(oid
, kSecPolicyOIDSSLServer
) ||
828 CFEqual(oid
, kSecPolicyOIDSSLClient
) ||
829 CFEqual(oid
, kSecPolicyOIDIPSecServer
) ||
830 CFEqual(oid
, kSecPolicyOIDIPSecClient
)) {
831 if (CFStringGetTypeID() == typeID
) {
832 SecPolicySetOptionsValue(policyRef
, kSecPolicyCheckSSLHostname
, name
);
834 else result
= errSecParam
;
836 else if (CFEqual(oid
, kSecPolicyOIDEAPServer
) ||
837 CFEqual(oid
, kSecPolicyOIDEAPClient
)) {
838 if ((CFStringGetTypeID() == typeID
) ||
839 (CFArrayGetTypeID() == typeID
)) {
840 SecPolicySetOptionsValue(policyRef
, kSecPolicyCheckEAPTrustedServerNames
, name
);
842 else result
= errSecParam
;
844 else if (CFEqual(oid
, kSecPolicyOIDSMIME
)) {
845 if (CFStringGetTypeID() == typeID
) {
846 SecPolicySetOptionsValue(policyRef
, kSecPolicyCheckEmail
, name
);
848 else result
= errSecParam
;
853 CFTypeRef client
= NULL
;
854 if (CFDictionaryGetValueIfPresent(properties
, (const void *)kSecPolicyClient
,
855 (const void **)&client
) && client
) {
856 if (!(CFBooleanGetTypeID() == CFGetTypeID(client
))) {
857 result
= errSecParam
;
859 else if (CFEqual(client
, kCFBooleanTrue
)) {
860 if (CFEqual(oid
, kSecPolicyOIDSSLServer
)) {
861 SecPolicySetOid(policyRef
, kSecPolicyOIDSSLClient
);
863 else if (CFEqual(oid
, kSecPolicyOIDIPSecServer
)) {
864 SecPolicySetOid(policyRef
, kSecPolicyOIDIPSecClient
);
866 else if (CFEqual(oid
, kSecPolicyOIDEAPServer
)) {
867 SecPolicySetOid(policyRef
, kSecPolicyOIDEAPClient
);
871 if (CFEqual(oid
, kSecPolicyOIDSSLClient
)) {
872 SecPolicySetOid(policyRef
, kSecPolicyOIDSSLServer
);
874 else if (CFEqual(oid
, kSecPolicyOIDIPSecClient
)) {
875 SecPolicySetOid(policyRef
, kSecPolicyOIDIPSecServer
);
877 else if (CFEqual(oid
, kSecPolicyOIDEAPClient
)) {
878 SecPolicySetOid(policyRef
, kSecPolicyOIDEAPServer
);
887 static xpc_object_t
copy_xpc_policy_object(SecPolicyRef policy
);
888 static bool append_policy_to_xpc_array(SecPolicyRef policy
, xpc_object_t xpc_policies
);
889 extern xpc_object_t
copy_xpc_policies_array(CFArrayRef policies
);
890 extern OSStatus
validate_array_of_items(CFArrayRef array
, CFStringRef arrayItemType
, CFTypeID itemTypeID
, bool required
);
892 static xpc_object_t
copy_xpc_policy_object(SecPolicyRef policy
) {
893 xpc_object_t xpc_policy
= NULL
;
894 xpc_object_t data
[2] = { NULL
, NULL
};
895 if (policy
->_oid
&& (CFGetTypeID(policy
->_oid
) == CFStringGetTypeID())) {
896 data
[0] = _CFXPCCreateXPCObjectFromCFObject(policy
->_oid
);
898 secerror("policy 0x%lX has no _oid", (uintptr_t)policy
);
900 if (policy
->_options
&& (CFGetTypeID(policy
->_options
) == CFDictionaryGetTypeID())) {
901 data
[1] = _CFXPCCreateXPCObjectFromCFObject(policy
->_options
);
903 secerror("policy 0x%lX has no _options", (uintptr_t)policy
);
905 xpc_policy
= xpc_array_create(data
, array_size(data
));
906 if (data
[0]) xpc_release(data
[0]);
907 if (data
[1]) xpc_release(data
[1]);
911 static bool append_policy_to_xpc_array(SecPolicyRef policy
, xpc_object_t xpc_policies
) {
915 xpc_object_t xpc_policy
= copy_xpc_policy_object(policy
);
919 xpc_array_append_value(xpc_policies
, xpc_policy
);
920 xpc_release(xpc_policy
);
924 xpc_object_t
copy_xpc_policies_array(CFArrayRef policies
) {
925 xpc_object_t xpc_policies
= xpc_array_create(NULL
, 0);
929 validate_array_of_items(policies
, CFSTR("policy"), SecPolicyGetTypeID(), true);
930 CFIndex ix
, count
= CFArrayGetCount(policies
);
931 for (ix
= 0; ix
< count
; ++ix
) {
932 SecPolicyRef policy
= (SecPolicyRef
) CFArrayGetValueAtIndex(policies
, ix
);
933 #if SECTRUST_VERBOSE_DEBUG
934 CFDictionaryRef props
= SecPolicyCopyProperties(policy
);
935 secerror("idx=%d of %d; policy=0x%lX properties=%@", (int)ix
, (int)count
, (uintptr_t)policy
, props
);
936 CFReleaseSafe(props
);
938 if (!append_policy_to_xpc_array(policy
, xpc_policies
)) {
939 xpc_release(xpc_policies
);
947 static xpc_object_t
SecPolicyCopyXPCObject(SecPolicyRef policy
, CFErrorRef
*error
) {
948 xpc_object_t xpc_policy
= NULL
;
949 xpc_object_t data
[2] = {};
950 require_action_quiet(data
[0] = _CFXPCCreateXPCObjectFromCFObject(policy
->_oid
), exit
,
951 SecError(errSecParam
, error
, CFSTR("failed to create xpc_object from policy oid")));
952 require_action_quiet(data
[1] = _CFXPCCreateXPCObjectFromCFObject(policy
->_options
), exit
,
953 SecError(errSecParam
, error
, CFSTR("failed to create xpc_object from policy options")));
954 require_action_quiet(xpc_policy
= xpc_array_create(data
, array_size(data
)), exit
,
955 SecError(errSecAllocate
, error
, CFSTR("failed to create xpc_array for policy")));
958 if (data
[0]) xpc_release(data
[0]);
959 if (data
[1]) xpc_release(data
[1]);
963 static bool SecPolicyAppendToXPCArray(SecPolicyRef policy
, xpc_object_t policies
, CFErrorRef
*error
) {
967 xpc_object_t xpc_policy
= SecPolicyCopyXPCObject(policy
, error
);
971 xpc_array_append_value(policies
, xpc_policy
);
972 xpc_release(xpc_policy
);
976 xpc_object_t
SecPolicyArrayCopyXPCArray(CFArrayRef policies
, CFErrorRef
*error
) {
977 xpc_object_t xpc_policies
;
978 require_action_quiet(xpc_policies
= xpc_array_create(NULL
, 0), exit
,
979 SecError(errSecAllocate
, error
, CFSTR("failed to create xpc_array")));
980 CFIndex ix
, count
= CFArrayGetCount(policies
);
981 for (ix
= 0; ix
< count
; ++ix
) {
982 if (!SecPolicyAppendToXPCArray((SecPolicyRef
)CFArrayGetValueAtIndex(policies
, ix
), xpc_policies
, error
)) {
983 xpc_release(xpc_policies
);
991 static SecPolicyRef
SecPolicyCreateWithXPCObject(xpc_object_t xpc_policy
, CFErrorRef
*error
) {
992 SecPolicyRef policy
= NULL
;
993 CFTypeRef oid
= NULL
;
994 CFTypeRef options
= NULL
;
996 require_action_quiet(xpc_policy
, exit
, SecError(errSecParam
, error
, CFSTR("policy xpc value is NULL")));
997 require_action_quiet(xpc_get_type(xpc_policy
) == XPC_TYPE_ARRAY
, exit
, SecError(errSecDecode
, error
, CFSTR("policy xpc value is not an array")));
998 require_action_quiet(xpc_array_get_count(xpc_policy
) == 2, exit
, SecError(errSecDecode
, error
, CFSTR("policy xpc array count != 2")));
999 oid
= _CFXPCCreateCFObjectFromXPCObject(xpc_array_get_value(xpc_policy
, 0));
1000 require_action_quiet(isString(oid
), exit
,
1001 SecError(errSecParam
, error
, CFSTR("failed to convert xpc policy[0]=%@ to CFString"), oid
));
1002 options
= _CFXPCCreateCFObjectFromXPCObject(xpc_array_get_value(xpc_policy
, 1));
1003 require_action_quiet(isDictionary(options
), exit
,
1004 SecError(errSecParam
, error
, CFSTR("failed to convert xpc policy[1]=%@ to CFDictionary"), options
));
1005 require_action_quiet(policy
= SecPolicyCreate(oid
, options
), exit
, SecError(errSecDecode
, error
, CFSTR("Failed to create policy")));
1009 CFReleaseSafe(options
);
1013 CFArrayRef
SecPolicyXPCArrayCopyArray(xpc_object_t xpc_policies
, CFErrorRef
*error
) {
1014 CFMutableArrayRef policies
= NULL
;
1015 require_action_quiet(xpc_get_type(xpc_policies
) == XPC_TYPE_ARRAY
, exit
,
1016 SecError(errSecParam
, error
, CFSTR("policies xpc value is not an array")));
1017 size_t count
= xpc_array_get_count(xpc_policies
);
1018 require_action_quiet(policies
= CFArrayCreateMutable(kCFAllocatorDefault
, count
, &kCFTypeArrayCallBacks
), exit
,
1019 SecError(errSecAllocate
, error
, CFSTR("failed to create CFArray of capacity %zu"), count
));
1022 for (ix
= 0; ix
< count
; ++ix
) {
1023 SecPolicyRef policy
= SecPolicyCreateWithXPCObject(xpc_array_get_value(xpc_policies
, ix
), error
);
1025 CFRelease(policies
);
1028 CFArraySetValueAtIndex(policies
, ix
, policy
);
1037 static void add_element(CFMutableDictionaryRef options
, CFStringRef key
,
1039 CFTypeRef old_value
= CFDictionaryGetValue(options
, key
);
1041 CFMutableArrayRef array
;
1042 if (CFGetTypeID(old_value
) == CFArrayGetTypeID()) {
1043 array
= (CFMutableArrayRef
)old_value
;
1045 array
= CFArrayCreateMutable(kCFAllocatorDefault
, 0,
1046 &kCFTypeArrayCallBacks
);
1047 CFArrayAppendValue(array
, old_value
);
1048 CFDictionarySetValue(options
, key
, array
);
1051 CFArrayAppendValue(array
, value
);
1053 CFDictionaryAddValue(options
, key
, value
);
1057 static void add_eku(CFMutableDictionaryRef options
, const DERItem
*ekuOid
) {
1058 CFDataRef eku
= CFDataCreate(kCFAllocatorDefault
,
1059 ekuOid
? ekuOid
->data
: NULL
,
1060 ekuOid
? ekuOid
->length
: 0);
1062 add_element(options
, kSecPolicyCheckExtendedKeyUsage
, eku
);
1067 static void add_ku(CFMutableDictionaryRef options
, SecKeyUsage keyUsage
) {
1068 SInt32 dku
= keyUsage
;
1069 CFNumberRef ku
= CFNumberCreate(kCFAllocatorDefault
, kCFNumberSInt32Type
,
1072 add_element(options
, kSecPolicyCheckKeyUsage
, ku
);
1077 static void add_oid(CFMutableDictionaryRef options
, CFStringRef policy_key
, const DERItem
*oid
) {
1078 CFDataRef oid_data
= CFDataCreate(kCFAllocatorDefault
,
1079 oid
? oid
->data
: NULL
,
1080 oid
? oid
->length
: 0);
1082 add_element(options
, policy_key
, oid_data
);
1083 CFRelease(oid_data
);
1087 static void add_leaf_marker_value(CFMutableDictionaryRef options
, const DERItem
*markerOid
, CFStringRef string_value
) {
1089 CFTypeRef policyData
= NULL
;
1091 if (NULL
== string_value
) {
1092 policyData
= CFDataCreate(kCFAllocatorDefault
,
1093 markerOid
? markerOid
->data
: NULL
,
1094 markerOid
? markerOid
->length
: 0);
1096 CFStringRef oid_as_string
= SecDERItemCopyOIDDecimalRepresentation(kCFAllocatorDefault
, markerOid
);
1098 const void *key
[1] = { oid_as_string
};
1099 const void *value
[1] = { string_value
};
1100 policyData
= CFDictionaryCreate(kCFAllocatorDefault
,
1102 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
1103 CFReleaseNull(oid_as_string
);
1106 add_element(options
, kSecPolicyCheckLeafMarkerOid
, policyData
);
1108 CFReleaseNull(policyData
);
1112 static void add_leaf_marker(CFMutableDictionaryRef options
, const DERItem
*markerOid
) {
1113 add_leaf_marker_value(options
, markerOid
, NULL
);
1117 static void add_certificate_policy_oid(CFMutableDictionaryRef options
, const DERItem
*certificatePolicyOid
, CFStringRef string_value
) {
1118 CFTypeRef certificatePolicyData
= NULL
;
1120 if (NULL
== string_value
) {
1121 certificatePolicyData
= CFDataCreate(kCFAllocatorDefault
,
1122 certificatePolicyOid
? certificatePolicyOid
->data
: NULL
,
1123 certificatePolicyOid
? certificatePolicyOid
->length
: 0);
1125 CFStringRef oid_as_string
= SecDERItemCopyOIDDecimalRepresentation(kCFAllocatorDefault
, certificatePolicyOid
);
1127 const void *key
[1] = { oid_as_string
};
1128 const void *value
[1] = { string_value
};
1129 certificatePolicyData
= CFDictionaryCreate(kCFAllocatorDefault
,
1131 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
1132 CFReleaseNull(oid_as_string
);
1135 add_element(options
, kSecPolicyCheckCertificatePolicy
, certificatePolicyData
);
1137 CFReleaseNull(certificatePolicyData
);
1140 // Routines for adding dictionary entries for policies.
1143 // X.509, but missing validity requirements.
1144 static void SecPolicyAddBasicCertOptions(CFMutableDictionaryRef options
)
1146 //CFDictionaryAddValue(options, kSecPolicyCheckBasicCertificateProcessing, kCFBooleanTrue);
1147 CFDictionaryAddValue(options
, kSecPolicyCheckCriticalExtensions
, kCFBooleanTrue
);
1148 CFDictionaryAddValue(options
, kSecPolicyCheckIdLinkage
, kCFBooleanTrue
);
1149 CFDictionaryAddValue(options
, kSecPolicyCheckBasicContraints
, kCFBooleanTrue
);
1150 CFDictionaryAddValue(options
, kSecPolicyCheckNonEmptySubject
, kCFBooleanTrue
);
1151 CFDictionaryAddValue(options
, kSecPolicyCheckQualifiedCertStatements
, kCFBooleanTrue
);
1154 static void SecPolicyAddBasicX509Options(CFMutableDictionaryRef options
)
1156 SecPolicyAddBasicCertOptions(options
);
1157 CFDictionaryAddValue(options
, kSecPolicyCheckValidIntermediates
, kCFBooleanTrue
);
1158 CFDictionaryAddValue(options
, kSecPolicyCheckValidLeaf
, kCFBooleanTrue
);
1159 CFDictionaryAddValue(options
, kSecPolicyCheckValidRoot
, kCFBooleanTrue
);
1161 // Make sure that black and gray leaf checks are performed for basic X509 chain building
1162 CFDictionaryAddValue(options
, kSecPolicyCheckBlackListedLeaf
, kCFBooleanTrue
);
1163 CFDictionaryAddValue(options
, kSecPolicyCheckGrayListedLeaf
, kCFBooleanTrue
);
1166 static bool SecPolicyAddChainLengthOptions(CFMutableDictionaryRef options
, CFIndex length
)
1168 bool result
= false;
1169 CFNumberRef lengthAsCF
= NULL
;
1171 require(lengthAsCF
= CFNumberCreate(kCFAllocatorDefault
,
1172 kCFNumberCFIndexType
, &length
), errOut
);
1173 CFDictionaryAddValue(options
, kSecPolicyCheckChainLength
, lengthAsCF
);
1178 CFReleaseSafe(lengthAsCF
);
1182 static bool SecPolicyAddAnchorSHA1Options(CFMutableDictionaryRef options
,
1183 const UInt8 anchorSha1
[kSecPolicySHA1Size
])
1185 bool success
= false;
1186 CFDataRef anchorData
= NULL
;
1188 require(anchorData
= CFDataCreate(kCFAllocatorDefault
, anchorSha1
, kSecPolicySHA1Size
), errOut
);
1189 add_element(options
, kSecPolicyCheckAnchorSHA1
, anchorData
);
1194 CFReleaseSafe(anchorData
);
1198 static bool SecPolicyAddAppleAnchorOptions(CFMutableDictionaryRef options
)
1200 return SecPolicyAddAnchorSHA1Options(options
, kAppleCASHA1
);
1204 // Policy Creation Functions
1206 SecPolicyRef
SecPolicyCreateBasicX509(void) {
1207 CFMutableDictionaryRef options
= NULL
;
1208 SecPolicyRef result
= NULL
;
1210 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1211 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1213 SecPolicyAddBasicX509Options(options
);
1214 CFDictionaryAddValue(options
, kSecPolicyCheckNoNetworkAccess
,
1217 require(result
= SecPolicyCreate(kSecPolicyOIDBasicX509
, options
), errOut
);
1220 CFReleaseSafe(options
);
1224 SecPolicyRef
SecPolicyCreateSSL(Boolean server
, CFStringRef hostname
) {
1225 CFMutableDictionaryRef options
= NULL
;
1226 SecPolicyRef result
= NULL
;
1228 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1229 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1231 SecPolicyAddBasicX509Options(options
);
1234 CFDictionaryAddValue(options
, kSecPolicyCheckSSLHostname
, hostname
);
1237 CFDictionaryAddValue(options
, kSecPolicyCheckBlackListedLeaf
, kCFBooleanTrue
);
1238 CFDictionaryAddValue(options
, kSecPolicyCheckGrayListedLeaf
, kCFBooleanTrue
);
1240 /* If server and EKU ext present then EKU ext should contain one of
1241 ServerAuth or ExtendedKeyUsageAny or NetscapeSGC or MicrosoftSGC.
1242 else if !server and EKU ext present then EKU ext should contain one of
1243 ClientAuth or ExtendedKeyUsageAny. */
1245 /* We always allow certificates that specify oidAnyExtendedKeyUsage. */
1246 add_eku(options
, NULL
); /* eku extension is optional */
1247 add_eku(options
, &oidAnyExtendedKeyUsage
);
1249 add_eku(options
, &oidExtendedKeyUsageServerAuth
);
1250 add_eku(options
, &oidExtendedKeyUsageMicrosoftSGC
);
1251 add_eku(options
, &oidExtendedKeyUsageNetscapeSGC
);
1253 add_eku(options
, &oidExtendedKeyUsageClientAuth
);
1256 require(result
= SecPolicyCreate(
1257 server
? kSecPolicyOIDSSLServer
: kSecPolicyOIDSSLClient
,
1261 CFReleaseSafe(options
);
1265 SecPolicyRef
SecPolicyCreateiPhoneActivation(void) {
1266 CFMutableDictionaryRef options
= NULL
;
1267 SecPolicyRef result
= NULL
;
1269 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1270 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1272 SecPolicyAddBasicCertOptions(options
);
1275 CFDictionaryAddValue(options
, kSecPolicyCheckKeyUsage
,
1277 CFDictionaryAddValue(options
, kSecPolicyCheckExtendedKeyUsage
,
1281 /* Basic X.509 policy with the additional requirements that the chain
1282 length is 3, it's anchored at the AppleCA and the leaf certificate
1283 has issuer "Apple iPhone Certification Authority" and
1284 subject "Apple iPhone Activation" for the common name. */
1285 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
1286 CFSTR("Apple iPhone Certification Authority"));
1287 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
,
1288 CFSTR("Apple iPhone Activation"));
1290 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1291 require(SecPolicyAddAppleAnchorOptions(options
), errOut
);
1293 require(result
= SecPolicyCreate(kSecPolicyOIDiPhoneActivation
, options
),
1297 CFReleaseSafe(options
);
1301 SecPolicyRef
SecPolicyCreateiPhoneDeviceCertificate(void) {
1302 CFMutableDictionaryRef options
= NULL
;
1303 SecPolicyRef result
= NULL
;
1305 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1306 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1308 SecPolicyAddBasicCertOptions(options
);
1311 CFDictionaryAddValue(options
, kSecPolicyCheckKeyUsage
,
1313 CFDictionaryAddValue(options
, kSecPolicyCheckExtendedKeyUsage
,
1317 /* Basic X.509 policy with the additional requirements that the chain
1318 length is 4, it's anchored at the AppleCA and the first intermediate
1319 has the subject "Apple iPhone Device CA". */
1320 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
1321 CFSTR("Apple iPhone Device CA"));
1323 require(SecPolicyAddChainLengthOptions(options
, 4), errOut
);
1324 require(SecPolicyAddAppleAnchorOptions(options
), errOut
);
1326 require(result
= SecPolicyCreate(kSecPolicyOIDiPhoneDeviceCertificate
, options
),
1330 CFReleaseSafe(options
);
1334 SecPolicyRef
SecPolicyCreateFactoryDeviceCertificate(void) {
1335 CFMutableDictionaryRef options
= NULL
;
1336 SecPolicyRef result
= NULL
;
1338 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1339 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1341 SecPolicyAddBasicCertOptions(options
);
1344 CFDictionaryAddValue(options
, kSecPolicyCheckKeyUsage
,
1346 CFDictionaryAddValue(options
, kSecPolicyCheckExtendedKeyUsage
,
1350 /* Basic X.509 policy with the additional requirements that the chain
1351 is anchored at the factory device certificate issuer. */
1352 require(SecPolicyAddAnchorSHA1Options(options
, kFactoryDeviceCASHA1
), errOut
);
1354 require(result
= SecPolicyCreate(kSecPolicyOIDFactoryDeviceCertificate
, options
),
1358 CFReleaseSafe(options
);
1362 SecPolicyRef
SecPolicyCreateiAP(void) {
1363 CFMutableDictionaryRef options
= NULL
;
1364 SecPolicyRef result
= NULL
;
1365 CFTimeZoneRef tz
= NULL
;
1366 CFDateRef date
= NULL
;
1368 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1369 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1371 SecPolicyAddBasicCertOptions(options
);
1373 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonNamePrefix
,
1376 date
= CFDateCreateForGregorianZuluDay(NULL
, 2006, 5, 31);
1377 CFDictionaryAddValue(options
, kSecPolicyCheckNotValidBefore
, date
);
1379 require(result
= SecPolicyCreate(kSecPolicyOIDiAP
, options
),
1383 CFReleaseSafe(date
);
1385 CFReleaseSafe(options
);
1389 SecPolicyRef
SecPolicyCreateiTunesStoreURLBag(void) {
1390 CFMutableDictionaryRef options
= NULL
;
1391 SecPolicyRef result
= NULL
;
1394 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1395 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1397 SecPolicyAddBasicCertOptions(options
);
1399 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectOrganization
,
1400 CFSTR("Apple Inc."));
1401 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
,
1402 CFSTR("iTunes Store URL Bag"));
1404 require(SecPolicyAddChainLengthOptions(options
, 2), errOut
);
1405 require(SecPolicyAddAnchorSHA1Options(options
, kITMSCASHA1
), errOut
);
1407 require(result
= SecPolicyCreate(kSecPolicyOIDiTunesStoreURLBag
, options
), errOut
);
1410 CFReleaseSafe(options
);
1414 SecPolicyRef
SecPolicyCreateEAP(Boolean server
, CFArrayRef trustedServerNames
) {
1415 CFMutableDictionaryRef options
= NULL
;
1416 SecPolicyRef result
= NULL
;
1418 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1419 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1421 SecPolicyAddBasicX509Options(options
);
1423 /* Since EAP is used to setup the network we don't want evaluation
1424 using this policy to access the network. */
1425 CFDictionaryAddValue(options
, kSecPolicyCheckNoNetworkAccess
,
1428 if (trustedServerNames
) {
1429 CFDictionaryAddValue(options
, kSecPolicyCheckEAPTrustedServerNames
, trustedServerNames
);
1431 /* Specifying trusted server names implies EAP-TLS,
1432 so we need to check for EKU per rdar://22206018 */
1434 /* If server and EKU ext present then EKU ext should contain one of
1435 ServerAuth or ExtendedKeyUsageAny or NetscapeSGC or MicrosoftSGC.
1436 else if !server and EKU ext present then EKU ext should contain one of
1437 ClientAuth or ExtendedKeyUsageAny. */
1439 /* We always allow certificates that specify oidAnyExtendedKeyUsage. */
1440 add_eku(options
, NULL
); /* eku extension is optional */
1441 add_eku(options
, &oidAnyExtendedKeyUsage
);
1443 add_eku(options
, &oidExtendedKeyUsageServerAuth
);
1444 add_eku(options
, &oidExtendedKeyUsageMicrosoftSGC
);
1445 add_eku(options
, &oidExtendedKeyUsageNetscapeSGC
);
1447 add_eku(options
, &oidExtendedKeyUsageClientAuth
);
1451 require(result
= SecPolicyCreate(
1452 server
? kSecPolicyOIDEAPServer
: kSecPolicyOIDEAPClient
,
1456 CFReleaseSafe(options
);
1460 SecPolicyRef
SecPolicyCreateIPSec(Boolean server
, CFStringRef hostname
) {
1461 CFMutableDictionaryRef options
= NULL
;
1462 SecPolicyRef result
= NULL
;
1464 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1465 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1467 SecPolicyAddBasicX509Options(options
);
1470 CFDictionaryAddValue(options
, kSecPolicyCheckSSLHostname
, hostname
);
1473 /* Require oidExtendedKeyUsageIPSec if Extended Keyusage Extention is
1475 /* Per <rdar://problem/6843827> Cisco VPN Certificate compatibility issue.
1476 We don't check the EKU for IPSec certs for now. If we do add eku
1477 checking back in the future, we should probably also accept the
1479 ipsecEndSystem 1.3.6.1.5.5.7.3.5
1481 ipsecTunnel 1.3.6.1.5.5.7.3.6
1482 ipsecUser 1.3.6.1.5.5.7.3.7
1484 //add_eku(options, NULL); /* eku extension is optional */
1485 //add_eku(options, &oidAnyExtendedKeyUsage);
1486 //add_eku(options, &oidExtendedKeyUsageIPSec);
1488 require(result
= SecPolicyCreate(
1489 server
? kSecPolicyOIDIPSecServer
: kSecPolicyOIDIPSecClient
,
1493 CFReleaseSafe(options
);
1497 SecPolicyRef
SecPolicyCreateiPhoneApplicationSigning(void) {
1498 CFMutableDictionaryRef options
= NULL
;
1499 SecPolicyRef result
= NULL
;
1501 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1502 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1504 SecPolicyAddBasicCertOptions(options
);
1506 /* Basic X.509 policy with the additional requirements that the chain
1507 length is 3, it's anchored at the AppleCA and the leaf certificate
1508 has issuer "Apple iPhone Certification Authority" and
1509 subject "Apple iPhone OS Application Signing" for the common name. */
1510 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
1511 CFSTR("Apple iPhone Certification Authority"));
1512 if (SecIsInternalRelease() && !SecIsProductionFused()) {
1513 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonNameTEST
,
1514 CFSTR("Apple iPhone OS Application Signing"));
1517 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
,
1518 CFSTR("Apple iPhone OS Application Signing"));
1521 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1522 require(SecPolicyAddAppleAnchorOptions(options
), errOut
);
1524 add_eku(options
, NULL
); /* eku extension is optional */
1525 add_eku(options
, &oidAnyExtendedKeyUsage
);
1526 add_eku(options
, &oidExtendedKeyUsageCodeSigning
);
1528 require(result
= SecPolicyCreate(kSecPolicyOIDiPhoneApplicationSigning
, options
),
1531 /* 1.2.840.113635.100.6.1.3, non-critical: DER:05:00 - application signing */
1534 CFReleaseSafe(options
);
1538 SecPolicyRef
SecPolicyCreateiPhoneProfileApplicationSigning(void) {
1539 CFMutableDictionaryRef options
= NULL
;
1540 SecPolicyRef result
= NULL
;
1542 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1543 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1544 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kCFBooleanFalse
);
1545 CFDictionaryAddValue(options
, kSecPolicyCheckValidLeaf
, kCFBooleanFalse
);
1547 require(result
= SecPolicyCreate(kSecPolicyOIDiPhoneProfileApplicationSigning
,
1551 CFReleaseSafe(options
);
1555 SecPolicyRef
SecPolicyCreateiPhoneProvisioningProfileSigning(void) {
1556 CFMutableDictionaryRef options
= NULL
;
1557 SecPolicyRef result
= NULL
;
1559 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1560 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1562 SecPolicyAddBasicCertOptions(options
);
1564 /* Basic X.509 policy with the additional requirements that the chain
1565 length is 3, it's anchored at the AppleCA and the leaf certificate
1566 has issuer "Apple iPhone Certification Authority" and
1567 subject "Apple iPhone OS Provisioning Profile Signing" for the common name. */
1568 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
1569 CFSTR("Apple iPhone Certification Authority"));
1570 if (SecIsInternalRelease() && !SecIsProductionFused()) {
1571 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonNameTEST
,
1572 CFSTR("Apple iPhone OS Provisioning Profile Signing"));
1575 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
,
1576 CFSTR("Apple iPhone OS Provisioning Profile Signing"));
1579 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1580 require(SecPolicyAddAppleAnchorOptions(options
), errOut
);
1582 require(result
= SecPolicyCreate(kSecPolicyOIDiPhoneProvisioningProfileSigning
, options
),
1585 /* 1.2.840.113635.100.6.2.2.1, non-critical: DER:05:00 - provisioning profile */
1588 CFReleaseSafe(options
);
1592 SecPolicyRef
SecPolicyCreateAppleTVOSApplicationSigning(void) {
1593 CFMutableDictionaryRef options
= NULL
;
1594 SecPolicyRef result
= NULL
;
1595 CFDataRef atvProdOid
= NULL
;
1596 CFDataRef atvTestOid
= NULL
;
1597 CFArrayRef oids
= NULL
;
1599 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1600 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1602 SecPolicyAddBasicCertOptions(options
);
1604 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1606 CFMutableDictionaryRef appleAnchorOptions
= CFDictionaryCreateMutableForCFTypes(NULL
);
1607 require(appleAnchorOptions
, errOut
);
1608 add_element(options
, kSecPolicyCheckAnchorApple
, appleAnchorOptions
);
1610 /* Check for intermediate: Apple Worldwide Developer Relations */
1611 /* 1.2.840.113635.100.6.2.1 */
1612 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleWWDR
);
1614 add_eku(options
, NULL
); /* eku extension is optional */
1615 add_eku(options
, &oidAnyExtendedKeyUsage
);
1616 add_eku(options
, &oidExtendedKeyUsageCodeSigning
);
1618 /* Check for prod or test AppleTV Application Signing OIDs */
1619 /* Prod: 1.2.840.113635.100.6.1.24 */
1620 /* Test: 1.2.840.113635.100.6.1.24.1 */
1621 atvProdOid
= CFDataCreate(kCFAllocatorDefault
, oidAppleTVOSApplicationSigningProd
.data
, oidAppleTVOSApplicationSigningProd
.length
);
1622 require(atvProdOid
, errOut
);
1623 atvTestOid
= CFDataCreate(kCFAllocatorDefault
, oidAppleTVOSApplicationSigningTest
.data
, oidAppleTVOSApplicationSigningTest
.length
);
1624 require(atvTestOid
, errOut
);
1626 oids
= CFArrayCreateForCFTypes(kCFAllocatorDefault
, atvProdOid
, atvTestOid
, NULL
);
1627 require(oids
, errOut
);
1629 add_element(options
, kSecPolicyCheckLeafMarkerOid
, oids
);
1631 require(result
= SecPolicyCreate(kSecPolicyOIDAppleTVOSApplicationSigning
, options
),
1635 CFReleaseSafe(options
);
1636 CFReleaseSafe(oids
);
1637 CFReleaseSafe(atvProdOid
);
1638 CFReleaseSafe(atvTestOid
);
1642 SecPolicyRef
SecPolicyCreateOCSPSigner(void) {
1643 CFMutableDictionaryRef options
= NULL
;
1644 SecPolicyRef result
= NULL
;
1646 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1647 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1649 SecPolicyAddBasicX509Options(options
);
1651 /* Require id-kp-OCSPSigning extendedKeyUsage to be present, not optional. */
1652 add_eku(options
, &oidExtendedKeyUsageOCSPSigning
);
1654 require(result
= SecPolicyCreate(kSecPolicyOIDOCSPSigner
, options
), errOut
);
1657 CFReleaseSafe(options
);
1661 SecPolicyRef
SecPolicyCreateRevocation(CFOptionFlags revocationFlags
) {
1662 CFMutableDictionaryRef options
= NULL
;
1663 SecPolicyRef result
= NULL
;
1665 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1666 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1668 /* false = ocsp, true = crl, string/url value = crl distribution point,
1669 array = list of multiple values for example false, true, url1, url2
1670 check ocsp, crl, and url1 and url2 for certs which have no extensions.
1672 if (revocationFlags
& kSecRevocationOCSPMethod
) {
1673 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kCFBooleanFalse
);
1675 else if (revocationFlags
& kSecRevocationCRLMethod
) {
1676 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kCFBooleanTrue
);
1679 if (revocationFlags
& kSecRevocationRequirePositiveResponse
) {
1680 CFDictionaryAddValue(options
, kSecPolicyCheckRevocationResponseRequired
, kCFBooleanTrue
);
1683 if (revocationFlags
& kSecRevocationNetworkAccessDisabled
) {
1684 CFDictionaryAddValue(options
, kSecPolicyCheckNoNetworkAccess
, kCFBooleanTrue
);
1687 /* Only flag bits 0-4 are currently defined */
1688 require(((revocationFlags
>> 5) == 0), errOut
);
1690 require(result
= SecPolicyCreate(kSecPolicyOIDRevocation
, options
), errOut
);
1693 CFReleaseSafe(options
);
1697 SecPolicyRef
SecPolicyCreateSMIME(CFIndex smimeUsage
, CFStringRef email
) {
1698 CFMutableDictionaryRef options
= NULL
;
1699 SecPolicyRef result
= NULL
;
1701 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1702 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1704 SecPolicyAddBasicX509Options(options
);
1706 /* We call add_ku for each combination of bits we are willing to allow. */
1707 if (smimeUsage
& kSecSignSMIMEUsage
) {
1708 add_ku(options
, kSecKeyUsageUnspecified
);
1709 add_ku(options
, kSecKeyUsageDigitalSignature
);
1710 add_ku(options
, kSecKeyUsageNonRepudiation
);
1712 if (smimeUsage
& kSecKeyEncryptSMIMEUsage
) {
1713 add_ku(options
, kSecKeyUsageKeyEncipherment
);
1715 if (smimeUsage
& kSecDataEncryptSMIMEUsage
) {
1716 add_ku(options
, kSecKeyUsageDataEncipherment
);
1718 if (smimeUsage
& kSecKeyExchangeDecryptSMIMEUsage
) {
1719 add_ku(options
, kSecKeyUsageKeyAgreement
| kSecKeyUsageDecipherOnly
);
1721 if (smimeUsage
& kSecKeyExchangeEncryptSMIMEUsage
) {
1722 add_ku(options
, kSecKeyUsageKeyAgreement
| kSecKeyUsageEncipherOnly
);
1724 if (smimeUsage
& kSecKeyExchangeBothSMIMEUsage
) {
1725 add_ku(options
, kSecKeyUsageKeyAgreement
| kSecKeyUsageEncipherOnly
| kSecKeyUsageDecipherOnly
);
1729 CFDictionaryAddValue(options
, kSecPolicyCheckEmail
, email
);
1732 /* RFC 3850 paragraph 4.4.4
1734 If the extended key usage extension is present in the certificate
1735 then interpersonal message S/MIME receiving agents MUST check that it
1736 contains either the emailProtection or the anyExtendedKeyUsage OID as
1737 defined in [KEYM]. S/MIME uses other than interpersonal messaging
1738 MAY require the explicit presence of the extended key usage extension
1739 or other OIDs to be present in the extension or both.
1741 add_eku(options
, NULL
); /* eku extension is optional */
1742 add_eku(options
, &oidAnyExtendedKeyUsage
);
1743 add_eku(options
, &oidExtendedKeyUsageEmailProtection
);
1745 require(result
= SecPolicyCreate(kSecPolicyOIDSMIME
, options
), errOut
);
1748 CFReleaseSafe(options
);
1752 SecPolicyRef
SecPolicyCreateApplePackageSigning(void) {
1753 CFMutableDictionaryRef options
= NULL
;
1754 SecPolicyRef result
= NULL
;
1756 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1757 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1759 // TBD: review OS X policy to see what options are needed for this policy
1760 SecPolicyAddBasicCertOptions(options
);
1762 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1763 require(SecPolicyAddAppleAnchorOptions(options
), errOut
);
1765 require(result
= SecPolicyCreate(kSecPolicyOIDPackageSigning
, options
),
1769 CFReleaseSafe(options
);
1774 SecPolicyRef
SecPolicyCreateAppleSWUpdateSigning(void) {
1775 CFMutableDictionaryRef options
= NULL
;
1776 SecPolicyRef result
= NULL
;
1778 * OS X rules for this policy:
1779 * -- Must have one intermediate cert
1780 * -- intermediate must have basic constraints with path length 0
1781 * -- intermediate has CSSMOID_APPLE_EKU_CODE_SIGNING EKU
1782 * -- leaf cert has either CODE_SIGNING or CODE_SIGN_DEVELOPMENT EKU (the latter of
1783 * which triggers a CSSMERR_APPLETP_CODE_SIGN_DEVELOPMENT error)
1785 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1786 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1788 // TBD: review OS X policy to see what options are needed for this policy
1789 SecPolicyAddBasicCertOptions(options
);
1791 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1792 require(SecPolicyAddAppleAnchorOptions(options
), errOut
);
1794 add_eku(options
, &oidAppleExtendedKeyUsageCodeSigning
);
1795 add_eku(options
, &oidAppleExtendedKeyUsageCodeSigningDev
);
1797 require(result
= SecPolicyCreate(kSecPolicyOIDAppleSWUpdateSigning
, options
),
1801 CFReleaseSafe(options
);
1806 SecPolicyRef
SecPolicyCreateCodeSigning(void) {
1807 CFMutableDictionaryRef options
= NULL
;
1808 SecPolicyRef result
= NULL
;
1810 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1811 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1814 #warning STU: <rdar://21328880>
1815 //%%% figure out why this policy is not passing for OS X.
1816 // I suspect it has to do with iOS not supporting anchor and keychain options yet.
1817 SecPolicyAddBasicCertOptions(options
);
1819 SecPolicyAddBasicX509Options(options
);
1821 /* If the key usage extension is present we accept it having either of
1823 add_ku(options
, kSecKeyUsageDigitalSignature
);
1824 add_ku(options
, kSecKeyUsageNonRepudiation
);
1826 /* We require a extended key usage extension and we accept any or
1827 codesigning ekus. */
1828 /* TODO: Do we want to accept the apple codesigning oid as well or is
1829 that a separate policy? */
1830 /* ANSWER: it's a separate policy, SecPolicyCreateAppleSWUpdateSigning */
1831 add_eku(options
, &oidAnyExtendedKeyUsage
);
1832 add_eku(options
, &oidExtendedKeyUsageCodeSigning
);
1835 require(result
= SecPolicyCreate(kSecPolicyOIDCodeSigning
, options
),
1839 CFReleaseSafe(options
);
1843 /* Explicitly leave out empty subject/subjectaltname check */
1844 SecPolicyRef
SecPolicyCreateLockdownPairing(void) {
1845 CFMutableDictionaryRef options
= NULL
;
1846 SecPolicyRef result
= NULL
;
1848 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1849 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1850 //CFDictionaryAddValue(options, kSecPolicyCheckBasicCertificateProcessing,
1852 CFDictionaryAddValue(options
, kSecPolicyCheckCriticalExtensions
,
1854 CFDictionaryAddValue(options
, kSecPolicyCheckIdLinkage
,
1856 CFDictionaryAddValue(options
, kSecPolicyCheckBasicContraints
,
1858 CFDictionaryAddValue(options
, kSecPolicyCheckQualifiedCertStatements
,
1861 require(result
= SecPolicyCreate(kSecPolicyOIDLockdownPairing
, options
), errOut
);
1864 CFReleaseSafe(options
);
1868 SecPolicyRef
SecPolicyCreateURLBag(void) {
1869 CFMutableDictionaryRef options
= NULL
;
1870 SecPolicyRef result
= NULL
;
1872 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1873 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1875 SecPolicyAddBasicCertOptions(options
);
1877 add_eku(options
, &oidExtendedKeyUsageCodeSigning
);
1879 require(result
= SecPolicyCreate(kSecPolicyOIDURLBag
, options
), errOut
);
1882 CFReleaseSafe(options
);
1886 static bool SecPolicyAddAppleCertificationAuthorityOptions(CFMutableDictionaryRef options
, bool honorValidity
)
1888 bool success
= false;
1891 SecPolicyAddBasicX509Options(options
);
1893 SecPolicyAddBasicCertOptions(options
);
1896 CFDictionaryAddValue(options
, kSecPolicyCheckKeyUsage
,
1898 CFDictionaryAddValue(options
, kSecPolicyCheckExtendedKeyUsage
,
1902 /* Basic X.509 policy with the additional requirements that the chain
1903 length is 3, it's anchored at the AppleCA and the leaf certificate
1904 has issuer "Apple iPhone Certification Authority". */
1905 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
1906 CFSTR("Apple iPhone Certification Authority"));
1908 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1909 require(SecPolicyAddAppleAnchorOptions(options
), errOut
);
1917 static SecPolicyRef
SecPolicyCreateAppleCertificationAuthorityPolicy(CFStringRef policyOID
, CFStringRef leafName
, bool honorValidity
)
1919 CFMutableDictionaryRef options
= NULL
;
1920 SecPolicyRef result
= NULL
;
1922 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1923 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1925 require(SecPolicyAddAppleCertificationAuthorityOptions(options
, honorValidity
), errOut
);
1927 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
, leafName
);
1929 require(result
= SecPolicyCreate(policyOID
, options
),
1933 CFReleaseSafe(options
);
1938 SecPolicyRef
SecPolicyCreateOTATasking(void)
1940 return SecPolicyCreateAppleCertificationAuthorityPolicy(kSecPolicyOIDOTATasking
, CFSTR("OTA Task Signing"), true);
1943 SecPolicyRef
SecPolicyCreateMobileAsset(void)
1945 return SecPolicyCreateAppleCertificationAuthorityPolicy(kSecPolicyOIDMobileAsset
, CFSTR("Asset Manifest Signing"), false);
1948 SecPolicyRef
SecPolicyCreateAppleIDAuthorityPolicy(void)
1950 SecPolicyRef result
= NULL
;
1951 CFMutableDictionaryRef options
= NULL
;
1952 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1953 &kCFTypeDictionaryKeyCallBacks
,
1954 &kCFTypeDictionaryValueCallBacks
), out
);
1956 //Leaf appears to be a SSL only cert, so policy should expand on that policy
1957 SecPolicyAddBasicX509Options(options
);
1959 // Apple CA anchored
1960 require(SecPolicyAddAppleAnchorOptions(options
), out
);
1962 // with the addition of the existence check of an extension with "Apple ID Sharing Certificate" oid (1.2.840.113635.100.4.7)
1963 // NOTE: this obviously intended to have gone into Extended Key Usage, but evidence of existing certs proves the contrary.
1964 add_leaf_marker(options
, &oidAppleExtendedKeyUsageAppleID
);
1966 // 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.
1967 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleID
);
1968 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleID2
);
1970 require(result
= SecPolicyCreate(kSecPolicyOIDAppleIDAuthority
, options
), out
);
1973 CFReleaseSafe(options
);
1977 SecPolicyRef
SecPolicyCreateMacAppStoreReceipt(void)
1979 SecPolicyRef result
= NULL
;
1980 CFMutableDictionaryRef options
= NULL
;
1981 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1982 &kCFTypeDictionaryKeyCallBacks
,
1983 &kCFTypeDictionaryValueCallBacks
), out
);
1985 SecPolicyAddBasicX509Options(options
);
1987 // Apple CA anchored
1988 require(SecPolicyAddAppleAnchorOptions(options
), out
);
1990 // - leaf needs certificatePolicies with CSSMOID_MACAPPSTORE_RECEIPT_CERT_POLICY
1991 // - chain length must be 3
1993 require(result
= SecPolicyCreate(kSecPolicyOIDMacAppStoreReceipt
, options
), out
);
1996 CFReleaseSafe(options
);
2001 static SecPolicyRef
_SecPolicyCreatePassbookCardSigner(CFStringRef cardIssuer
, CFStringRef teamIdentifier
, bool requireTeamID
)
2003 SecPolicyRef result
= NULL
;
2004 CFMutableDictionaryRef options
= NULL
;
2005 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2006 &kCFTypeDictionaryKeyCallBacks
,
2007 &kCFTypeDictionaryValueCallBacks
), out
);
2009 SecPolicyAddBasicX509Options(options
);
2010 SecPolicyAddAppleAnchorOptions(options
);
2012 if (teamIdentifier
) {
2013 // If supplied, teamIdentifier must match subject OU field
2014 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectOrganizationalUnit
, teamIdentifier
);
2017 // If not supplied, and it was required, fail
2018 require(!requireTeamID
, out
);
2021 // Must be both push and 3rd party package signing
2022 add_leaf_marker_value(options
, &oidAppleInstallerPackagingSigningExternal
, cardIssuer
);
2024 // We should check that it also has push marker, but we don't support requiring both, only either.
2025 // add_independent_oid(options, kSecPolicyCheckLeafMarkerOid, &oidApplePushServiceClient);
2027 // And Passbook signing eku
2028 add_eku(options
, &oidAppleExtendedKeyUsagePassbook
);
2030 require(result
= SecPolicyCreate(kSecPolicyOIDApplePassbook
, options
), out
);
2033 CFReleaseSafe(options
);
2037 SecPolicyRef
SecPolicyCreatePassbookCardSigner(CFStringRef cardIssuer
, CFStringRef teamIdentifier
)
2039 return _SecPolicyCreatePassbookCardSigner(cardIssuer
, teamIdentifier
, true);
2043 static SecPolicyRef
CreateMobileStoreSigner(Boolean forTest
)
2046 SecPolicyRef result
= NULL
;
2047 CFMutableDictionaryRef options
= NULL
;
2048 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2049 &kCFTypeDictionaryKeyCallBacks
,
2050 &kCFTypeDictionaryValueCallBacks
), errOut
);
2051 SecPolicyAddBasicX509Options(options
);
2052 SecPolicyAddAppleAnchorOptions(options
);
2054 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2056 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2057 CFSTR("Apple System Integration 2 Certification Authority"));
2059 add_ku(options
, kSecKeyUsageDigitalSignature
);
2061 const DERItem
* pOID
= (forTest
) ? &oidApplePolicyTestMobileStore
: &oidApplePolicyMobileStore
;
2063 add_certificate_policy_oid(options
, pOID
, NULL
);
2065 require(result
= SecPolicyCreate(kSecPolicyOIDAppleMobileStore
, options
), errOut
);
2068 CFReleaseSafe(options
);
2072 SecPolicyRef
SecPolicyCreateMobileStoreSigner(void)
2075 return CreateMobileStoreSigner(false);
2078 SecPolicyRef
SecPolicyCreateTestMobileStoreSigner(void)
2081 return CreateMobileStoreSigner(true);
2085 CF_RETURNS_RETAINED SecPolicyRef
SecPolicyCreateEscrowServiceSigner(void)
2087 SecPolicyRef result
= NULL
;
2088 CFMutableDictionaryRef options
= NULL
;
2089 CFArrayRef anArray
= NULL
;
2090 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2091 &kCFTypeDictionaryKeyCallBacks
,
2092 &kCFTypeDictionaryValueCallBacks
), errOut
);
2094 // X509, ignoring date validity
2095 SecPolicyAddBasicCertOptions(options
);
2098 add_ku(options
, kSecKeyUsageKeyEncipherment
);
2100 //add_leaf_marker(options, &oidApplePolicyEscrowService);
2101 require(SecPolicyAddChainLengthOptions(options
, 2), errOut
);
2104 Boolean anchorAdded
= false;
2105 // Get the roots by calling the SecCertificateCopyEscrowRoots
2106 anArray
= SecCertificateCopyEscrowRoots(kSecCertificateProductionEscrowRoot
);
2107 CFIndex numRoots
= 0;
2108 if (NULL
== anArray
|| 0 == (numRoots
= CFArrayGetCount(anArray
)))
2113 for (CFIndex iCnt
= 0; iCnt
< numRoots
; iCnt
++)
2115 SecCertificateRef aCert
= (SecCertificateRef
)CFArrayGetValueAtIndex(anArray
, iCnt
);
2119 CFDataRef sha_data
= SecCertificateGetSHA1Digest(aCert
);
2120 if (NULL
!= sha_data
)
2122 const UInt8
* pSHAData
= CFDataGetBytePtr(sha_data
);
2123 if (NULL
!= pSHAData
)
2125 SecPolicyAddAnchorSHA1Options(options
, pSHAData
);
2131 CFReleaseNull(anArray
);
2139 require(result
= SecPolicyCreate(kSecPolicyOIDAppleEscrowService
, options
), errOut
);
2142 CFReleaseSafe(anArray
);
2143 CFReleaseSafe(options
);
2147 CF_RETURNS_RETAINED SecPolicyRef
SecPolicyCreatePCSEscrowServiceSigner(void)
2149 SecPolicyRef result
= NULL
;
2150 CFMutableDictionaryRef options
= NULL
;
2151 CFArrayRef anArray
= NULL
;
2152 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2153 &kCFTypeDictionaryKeyCallBacks
,
2154 &kCFTypeDictionaryValueCallBacks
), errOut
);
2156 SecPolicyAddBasicX509Options(options
);
2159 add_ku(options
, kSecKeyUsageKeyEncipherment
);
2161 //add_leaf_marker(options, &oidApplePolicyEscrowService);
2162 require(SecPolicyAddChainLengthOptions(options
, 2), errOut
);
2165 Boolean anchorAdded
= false;
2166 anArray
= SecCertificateCopyEscrowRoots(kSecCertificateProductionPCSEscrowRoot
);
2167 CFIndex numRoots
= 0;
2168 if (NULL
== anArray
|| 0 == (numRoots
= CFArrayGetCount(anArray
)))
2173 for (CFIndex iCnt
= 0; iCnt
< numRoots
; iCnt
++)
2175 SecCertificateRef aCert
= (SecCertificateRef
)CFArrayGetValueAtIndex(anArray
, iCnt
);
2179 CFDataRef sha_data
= SecCertificateGetSHA1Digest(aCert
);
2180 if (NULL
!= sha_data
)
2182 const UInt8
* pSHAData
= CFDataGetBytePtr(sha_data
);
2183 if (NULL
!= pSHAData
)
2185 SecPolicyAddAnchorSHA1Options(options
, pSHAData
);
2191 CFReleaseNull(anArray
);
2199 require(result
= SecPolicyCreate(kSecPolicyOIDApplePCSEscrowService
, options
), errOut
);
2202 CFReleaseSafe(anArray
);
2203 CFReleaseSafe(options
);
2206 SecCertificateRef
SecPolicyCopyEscrowRootCertificate(void)
2208 SecCertificateRef result
= NULL
;
2213 SecPolicyRef
SecPolicyCreateConfigurationProfileSigner(void)
2215 SecPolicyRef result
= NULL
;
2216 CFMutableDictionaryRef options
= NULL
;
2217 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2218 &kCFTypeDictionaryKeyCallBacks
,
2219 &kCFTypeDictionaryValueCallBacks
), errOut
);
2221 SecPolicyAddBasicX509Options(options
);
2222 SecPolicyAddAppleAnchorOptions(options
);
2224 // Require the profile signing EKU
2225 add_eku(options
, &oidAppleExtendedKeyUsageProfileSigning
);
2227 require(result
= SecPolicyCreate(kSecPolicyOIDAppleProfileSigner
, options
), errOut
);
2230 CFReleaseSafe(options
);
2235 SecPolicyRef
SecPolicyCreateQAConfigurationProfileSigner(void)
2237 SecPolicyRef result
= NULL
;
2238 CFMutableDictionaryRef options
= NULL
;
2239 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2240 &kCFTypeDictionaryKeyCallBacks
,
2241 &kCFTypeDictionaryValueCallBacks
), errOut
);
2243 SecPolicyAddBasicX509Options(options
);
2244 SecPolicyAddAppleAnchorOptions(options
);
2246 // Require the QA profile signing EKU
2247 add_eku(options
, &oidAppleExtendedKeyUsageQAProfileSigning
);
2249 require(result
= SecPolicyCreate(kSecPolicyOIDAppleQAProfileSigner
, options
), errOut
);
2252 CFReleaseSafe(options
);
2256 SecPolicyRef
SecPolicyCreateOSXProvisioningProfileSigning(void)
2258 SecPolicyRef result
= NULL
;
2259 CFMutableDictionaryRef options
= NULL
;
2260 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2261 &kCFTypeDictionaryKeyCallBacks
,
2262 &kCFTypeDictionaryValueCallBacks
), errOut
);
2263 // Require valid chain from the Apple root
2264 SecPolicyAddBasicX509Options(options
);
2265 SecPolicyAddAppleAnchorOptions(options
);
2267 // Require provisioning profile leaf marker OID (1.2.840.113635.100.4.11)
2268 add_leaf_marker(options
, &oidAppleCertExtOSXProvisioningProfileSigning
);
2270 // Require intermediate marker OID (1.2.840.113635.100.6.2.1)
2271 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleWWDR
);
2273 // Require key usage that allows signing
2274 add_ku(options
, kSecKeyUsageDigitalSignature
);
2276 // Ensure that revocation is checked (OCSP)
2277 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kCFBooleanFalse
);
2279 require(result
= SecPolicyCreate(kSecPolicyOIDAppleOSXProvisioningProfileSigning
, options
), errOut
);
2282 CFReleaseSafe(options
);
2287 SecPolicyRef
SecPolicyCreateOTAPKISigner(void)
2289 SecPolicyRef result
= NULL
;
2290 CFMutableDictionaryRef options
= NULL
;
2291 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2292 &kCFTypeDictionaryKeyCallBacks
,
2293 &kCFTypeDictionaryValueCallBacks
), errOut
);
2294 SecPolicyAddBasicX509Options(options
);
2296 SecPolicyAddAnchorSHA1Options(options
, kApplePKISettingsAuthority
);
2297 require(SecPolicyAddChainLengthOptions(options
, 2), errOut
);
2299 require(result
= SecPolicyCreate(kSecPolicyOIDAppleOTAPKIAssetSigner
, options
), errOut
);
2302 CFReleaseSafe(options
);
2308 SecPolicyRef
SecPolicyCreateTestOTAPKISigner(void)
2310 SecPolicyRef result
= NULL
;
2311 CFMutableDictionaryRef options
= NULL
;
2312 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2313 &kCFTypeDictionaryKeyCallBacks
,
2314 &kCFTypeDictionaryValueCallBacks
), errOut
);
2315 SecPolicyAddBasicX509Options(options
);
2317 SecPolicyAddAnchorSHA1Options(options
, kAppleTestPKISettingsAuthority
);
2318 require(SecPolicyAddChainLengthOptions(options
, 2), errOut
);
2320 require(result
= SecPolicyCreate(kSecPolicyOIDAppleTestOTAPKIAssetSigner
, options
), errOut
);
2323 CFReleaseSafe(options
);
2328 @function SecPolicyCreateAppleSMPEncryption
2329 @abstract Check for intermediate certificate 'Apple System Integration CA - G3' by name,
2330 and root certificate 'Apple Root CA - G3' by hash.
2331 Leaf cert must have Key Encipherment usage.
2332 Leaf cert must have Apple SMP Encryption marker OID (1.2.840.113635.100.6.30).
2333 Intermediate must have marker OID (1.2.840.113635.100.6.2.13).
2335 SecPolicyRef
SecPolicyCreateAppleSMPEncryption(void)
2337 SecPolicyRef result
= NULL
;
2338 CFMutableDictionaryRef options
= NULL
;
2339 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2340 &kCFTypeDictionaryKeyCallBacks
,
2341 &kCFTypeDictionaryValueCallBacks
), errOut
);
2342 SecPolicyAddBasicCertOptions(options
);
2344 SecPolicyAddAnchorSHA1Options(options
, kAppleRootCA_ECC_SHA1
);
2345 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2347 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2348 CFSTR("Apple System Integration CA - G3"));
2350 // Check that leaf has extension with "Apple SMP Encryption" oid (1.2.840.113635.100.6.30)
2351 add_leaf_marker(options
, &oidAppleCertExtAppleSMPEncryption
);
2353 // Check that intermediate has extension (1.2.840.113635.100.6.2.13)
2354 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleSystemIntgG3
);
2356 add_ku(options
, kSecKeyUsageKeyEncipherment
);
2358 // Ensure that revocation is checked (OCSP)
2359 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kCFBooleanFalse
);
2361 require(result
= SecPolicyCreate(kSecPolicyAppleSMPEncryption
, options
), errOut
);
2364 CFReleaseSafe(options
);
2369 @function SecPolicyCreateTestAppleSMPEncryption
2370 @abstract Check for intermediate certificate 'Test Apple System Integration CA - ECC' by name,
2371 and root certificate 'Test Apple Root CA - ECC' by hash.
2372 Leaf cert must have Key Encipherment usage. Other checks TBD.
2374 SecPolicyRef
SecPolicyCreateTestAppleSMPEncryption(void)
2376 SecPolicyRef result
= NULL
;
2377 CFMutableDictionaryRef options
= NULL
;
2378 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2379 &kCFTypeDictionaryKeyCallBacks
,
2380 &kCFTypeDictionaryValueCallBacks
), errOut
);
2381 SecPolicyAddBasicCertOptions(options
);
2383 SecPolicyAddAnchorSHA1Options(options
, kTestAppleRootCA_ECC_SHA1
);
2384 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2386 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2387 CFSTR("Test Apple System Integration CA - ECC"));
2389 add_ku(options
, kSecKeyUsageKeyEncipherment
);
2391 // Ensure that revocation is checked (OCSP)
2392 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kCFBooleanFalse
);
2394 require(result
= SecPolicyCreate(kSecPolicyAppleTestSMPEncryption
, options
), errOut
);
2397 CFReleaseSafe(options
);
2402 SecPolicyRef
SecPolicyCreateAppleIDValidationRecordSigningPolicy(void)
2404 SecPolicyRef result
= NULL
;
2405 CFMutableDictionaryRef options
= NULL
;
2406 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2407 &kCFTypeDictionaryKeyCallBacks
,
2408 &kCFTypeDictionaryValueCallBacks
), errOut
);
2410 //Leaf appears to be a SSL only cert, so policy should expand on that policy
2411 SecPolicyAddBasicX509Options(options
);
2413 // Apple CA anchored
2414 require(SecPolicyAddAppleAnchorOptions(options
), errOut
);
2416 // Check for an extension with " Apple ID Validation Record Signing" oid (1.2.840.113635.100.6.25)
2417 add_leaf_marker(options
, &oidAppleCertExtensionAppleIDRecordValidationSigning
);
2419 // and validate that intermediate has extension
2420 // Application Integration Intermediate Certificate (1.2.840.113635.100.6.2.3)
2421 // and also validate that intermediate has extension
2422 // System Integration 2 Intermediate Certificate (1.2.840.113635.100.6.2.10)
2423 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleID
);
2424 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleSystemIntg2
);
2426 // Ensure that revocation is checked (OCSP)
2427 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kCFBooleanFalse
);
2429 require(result
= SecPolicyCreate(kSecPolicyOIDAppleIDValidationRecordSigningPolicy
, options
), errOut
);
2432 CFReleaseSafe(options
);
2437 allowUATRoot(CFStringRef service
, CFDictionaryRef context
)
2439 bool UATAllowed
= false;
2440 if (SecIsInternalRelease()) {
2441 CFStringRef setting
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("AppleServerAuthenticationAllowUAT%@"), service
);
2442 CFTypeRef value
= NULL
;
2443 require(setting
, fail
);
2446 CFDictionaryGetValueIfPresent(context
, setting
, &value
) &&
2448 CFBooleanGetValue(value
))
2453 if (CFPreferencesGetAppBooleanValue(setting
, CFSTR("com.apple.Security"), NULL
)) {
2463 requirePinning(CFStringRef service
)
2465 bool pinningRequired
= true;
2467 if (SecIsInternalRelease()) {
2468 CFStringRef setting
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("AppleServerAuthenticationNoPinning%@"), service
);
2469 require(setting
, fail
);
2470 if (CFPreferencesGetAppBooleanValue(setting
, CFSTR("com.apple.Security"), NULL
))
2471 pinningRequired
= false;
2475 return pinningRequired
;
2479 @function SecPolicyCreateAppleServerAuthCommon
2480 @abstract Generic policy for server authentication Sub CAs
2482 Allows control for both if pinning is required at all and if UAT environments should be added
2483 to the trust policy.
2485 No pinning is for developer/QA that needs to use proxy to debug the protocol, while UAT
2486 environment is for QA/internal developer that have no need allow fake servers.
2488 Both the noPinning and allowUAT are gated on that you run on internal hardware.
2493 SecPolicyCreateAppleServerAuthCommon(CFStringRef hostname
,
2494 CFDictionaryRef __unused context
,
2495 CFStringRef service
,
2496 const DERItem
*leafMarkerOID
,
2497 const DERItem
*UATLeafMarkerOID
)
2499 CFMutableDictionaryRef appleAnchorOptions
= NULL
;
2500 CFMutableDictionaryRef options
= NULL
;
2501 SecPolicyRef result
= NULL
;
2502 CFDataRef oid
= NULL
, uatoid
= NULL
;
2504 options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0, &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
2505 require(options
, errOut
);
2507 SecPolicyAddBasicX509Options(options
);
2509 CFDictionaryAddValue(options
, kSecPolicyCheckSSLHostname
, hostname
);
2511 CFDictionaryAddValue(options
, kSecPolicyCheckBlackListedLeaf
, kCFBooleanTrue
);
2512 CFDictionaryAddValue(options
, kSecPolicyCheckGrayListedLeaf
, kCFBooleanTrue
);
2514 add_eku(options
, &oidExtendedKeyUsageServerAuth
);
2516 if (requirePinning(service
)) {
2517 bool allowUAT
= allowUATRoot(service
, context
);
2520 * Require pinning to the Apple CA's (and if UAT environment,
2521 * include the Apple Test CA's as anchors).
2524 appleAnchorOptions
= CFDictionaryCreateMutableForCFTypes(NULL
);
2525 require(appleAnchorOptions
, errOut
);
2528 CFDictionarySetValue(appleAnchorOptions
,
2529 kSecPolicyAppleAnchorIncludeTestRoots
, kCFBooleanTrue
);
2532 add_element(options
, kSecPolicyCheckAnchorApple
, appleAnchorOptions
);
2535 * Check if we also should allow the UAT variant of the leafs
2536 * as some variants of the UAT environment uses that instead
2537 * of the test Apple CA's.
2541 oid
= CFDataCreate(kCFAllocatorDefault
, leafMarkerOID
->data
, leafMarkerOID
->length
);
2542 require(oid
, errOut
);
2544 uatoid
= CFDataCreate(kCFAllocatorDefault
, UATLeafMarkerOID
->data
, UATLeafMarkerOID
->length
);
2545 require(oid
, errOut
);
2547 CFArrayRef array
= CFArrayCreateForCFTypes(NULL
, oid
, uatoid
, NULL
);
2548 require(array
, errOut
);
2550 add_element(options
, kSecPolicyCheckLeafMarkerOid
, array
);
2551 CFReleaseSafe(array
);
2553 add_leaf_marker(options
, leafMarkerOID
);
2556 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleServerAuthentication
);
2560 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kCFBooleanFalse
);
2562 result
= SecPolicyCreate(kSecPolicyOIDSSLServer
, options
);
2563 require(result
, errOut
);
2566 CFReleaseSafe(appleAnchorOptions
);
2567 CFReleaseSafe(options
);
2569 CFReleaseSafe(uatoid
);
2576 @function SecPolicyCreateAppleIDSService
2577 @abstract Ensure we're appropriately pinned to the IDS service (SSL + Apple restrictions)
2579 SecPolicyRef
SecPolicyCreateAppleIDSService(CFStringRef hostname
)
2582 return SecPolicyCreateSSL(true, hostname
);
2584 return SecPolicyCreateAppleServerAuthCommon(hostname
, NULL
, CFSTR("IDS"),
2585 &oidAppleCertExtAppleServerAuthenticationIDSProd
,
2586 &oidAppleCertExtAppleServerAuthenticationIDSTest
);
2591 @function SecPolicyCreateAppleIDSService
2592 @abstract Ensure we're appropriately pinned to the IDS service (SSL + Apple restrictions)
2594 SecPolicyRef
SecPolicyCreateAppleIDSServiceContext(CFStringRef hostname
, CFDictionaryRef context
)
2596 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, CFSTR("IDS"),
2597 &oidAppleCertExtAppleServerAuthenticationIDSProd
,
2598 &oidAppleCertExtAppleServerAuthenticationIDSTest
);
2602 @function SecPolicyCreateAppleGSService
2603 @abstract Ensure we're appropriately pinned to the GS service
2605 SecPolicyRef
SecPolicyCreateAppleGSService(CFStringRef hostname
, CFDictionaryRef context
)
2607 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, CFSTR("GS"),
2608 &oidAppleCertExtAppleServerAuthenticationGS
,
2613 @function SecPolicyCreateApplePushService
2614 @abstract Ensure we're appropriately pinned to the Push service (SSL + Apple restrictions)
2616 SecPolicyRef
SecPolicyCreateApplePushService(CFStringRef hostname
, CFDictionaryRef context
)
2618 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, CFSTR("APN"),
2619 &oidAppleCertExtAppleServerAuthenticationAPNProd
,
2620 &oidAppleCertExtAppleServerAuthenticationAPNTest
);
2624 @function SecPolicyCreateApplePPQService
2625 @abstract Ensure we're appropriately pinned to the PPQ service (SSL + Apple restrictions)
2627 SecPolicyRef
SecPolicyCreateApplePPQService(CFStringRef hostname
, CFDictionaryRef context
)
2629 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, CFSTR("PPQ"),
2630 &oidAppleCertExtAppleServerAuthenticationPPQProd
,
2631 &oidAppleCertExtAppleServerAuthenticationPPQTest
);
2634 /* should use verbatim copy, but since this is the deprecated way, don't care right now */
2635 static const UInt8 entrustSPKIL1C
[kSecPolicySHA256Size
] = {
2636 0x54, 0x5b, 0xf9, 0x35, 0xe9, 0xad, 0xa1, 0xda,
2637 0x11, 0x7e, 0xdc, 0x3c, 0x2a, 0xcb, 0xc5, 0x6f,
2638 0xc0, 0x28, 0x09, 0x6c, 0x0e, 0x24, 0xbe, 0x9b,
2639 0x38, 0x94, 0xbe, 0x52, 0x2d, 0x1b, 0x43, 0xde
2643 @function SecPolicyCreateApplePushServiceLegacy
2644 @abstract Ensure we're appropriately pinned to the Push service (via Entrust)
2646 SecPolicyRef
SecPolicyCreateApplePushServiceLegacy(CFStringRef hostname
)
2648 CFMutableDictionaryRef options
= NULL
;
2649 SecPolicyRef result
= NULL
;
2650 CFDataRef digest
= NULL
;
2652 digest
= CFDataCreateWithBytesNoCopy(kCFAllocatorDefault
, entrustSPKIL1C
, sizeof(entrustSPKIL1C
), kCFAllocatorNull
);
2653 require(digest
, errOut
);
2655 options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0, &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
2656 require(options
, errOut
);
2658 SecPolicyAddBasicX509Options(options
);
2660 CFDictionaryAddValue(options
, kSecPolicyCheckSSLHostname
, hostname
);
2662 CFDictionaryAddValue(options
, kSecPolicyCheckBlackListedLeaf
, kCFBooleanTrue
);
2663 CFDictionaryAddValue(options
, kSecPolicyCheckGrayListedLeaf
, kCFBooleanTrue
);
2665 CFDictionaryAddValue(options
, kSecPolicyCheckIntermediateSPKISHA256
, digest
);
2667 add_eku(options
, &oidExtendedKeyUsageServerAuth
);
2669 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kCFBooleanFalse
);
2671 result
= SecPolicyCreate(kSecPolicyOIDSSLServer
, options
);
2672 require(result
, errOut
);
2675 CFReleaseSafe(digest
);
2676 CFReleaseSafe(options
);
2681 @function SecPolicyCreateAppleMMCSService
2682 @abstract Ensure we're appropriately pinned to the IDS service (SSL + Apple restrictions)
2684 SecPolicyRef
SecPolicyCreateAppleMMCSService(CFStringRef hostname
, CFDictionaryRef __unused context
)
2686 return SecPolicyCreateSSL(true, hostname
);
2690 @function SecPolicyCreateAppleSSLService
2691 @abstract Ensure we're appropriately pinned to an Apple server (SSL + Apple restrictions)
2693 SecPolicyRef
SecPolicyCreateAppleSSLService(CFStringRef hostname
)
2695 // SSL server, pinned to an Apple intermediate
2696 SecPolicyRef policy
= SecPolicyCreateSSL(true, hostname
);
2697 CFMutableDictionaryRef options
= NULL
;
2698 require(policy
, errOut
);
2700 // change options for SSL policy evaluation
2701 require((options
=(CFMutableDictionaryRef
)policy
->_options
) != NULL
, errOut
);
2703 // Apple CA anchored
2704 require(SecPolicyAddAppleAnchorOptions(options
), errOut
);
2706 // Check leaf for Apple Server Authentication marker oid (1.2.840.113635.100.6.27.1)
2707 add_leaf_marker(options
, &oidAppleCertExtAppleServerAuthentication
);
2709 // Check intermediate for Apple Server Authentication intermediate marker (1.2.840.113635.100.6.2.12)
2710 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleServerAuthentication
);
2712 // Ensure that revocation is checked (OCSP only)
2713 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kCFBooleanFalse
);
2718 CFReleaseSafe(options
);
2719 CFReleaseSafe(policy
);
2724 @function SecPolicyCreateApplePPQSigning
2725 @abstract Check for intermediate certificate 'Apple System Integration 2 Certification Authority' by name,
2727 Leaf cert must have Digital Signature usage.
2728 Leaf cert must have Apple PPQ Signing marker OID (1.2.840.113635.100.6.38.2).
2729 Intermediate must have marker OID (1.2.840.113635.100.6.2.10).
2731 SecPolicyRef
SecPolicyCreateApplePPQSigning(void)
2733 SecPolicyRef result
= NULL
;
2734 CFMutableDictionaryRef options
= NULL
;
2735 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2736 &kCFTypeDictionaryKeyCallBacks
,
2737 &kCFTypeDictionaryValueCallBacks
), errOut
);
2738 SecPolicyAddBasicCertOptions(options
);
2740 SecPolicyAddAppleAnchorOptions(options
);
2741 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2743 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2744 CFSTR("Apple System Integration 2 Certification Authority"));
2746 // Check that leaf has extension with "Apple PPQ Signing" prod oid (1.2.840.113635.100.6.38.2)
2747 add_leaf_marker(options
, &oidAppleCertExtApplePPQSigningProd
);
2749 // Check that intermediate has extension (1.2.840.113635.100.6.2.10)
2750 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleSystemIntg2
);
2752 add_ku(options
, kSecKeyUsageDigitalSignature
);
2754 require(result
= SecPolicyCreate(kSecPolicyApplePPQSigning
, options
), errOut
);
2757 CFReleaseSafe(options
);
2762 @function SecPolicyCreateTestApplePPQSigning
2763 @abstract Check for intermediate certificate 'Apple System Integration 2 Certification Authority' by name,
2765 Leaf cert must have Digital Signature usage.
2766 Leaf cert must have Apple PPQ Signing Test marker OID (1.2.840.113635.100.6.38.1).
2767 Intermediate must have marker OID (1.2.840.113635.100.6.2.10).
2769 SecPolicyRef
SecPolicyCreateTestApplePPQSigning(void)
2771 SecPolicyRef result
= NULL
;
2772 CFMutableDictionaryRef options
= NULL
;
2773 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2774 &kCFTypeDictionaryKeyCallBacks
,
2775 &kCFTypeDictionaryValueCallBacks
), errOut
);
2776 SecPolicyAddBasicCertOptions(options
);
2778 SecPolicyAddAppleAnchorOptions(options
);
2779 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2781 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2782 CFSTR("Apple System Integration 2 Certification Authority"));
2784 // Check that leaf has extension with "Apple PPQ Signing" test oid (1.2.840.113635.100.6.38.1)
2785 add_leaf_marker(options
, &oidAppleCertExtApplePPQSigningTest
);
2787 // Check that intermediate has extension (1.2.840.113635.100.6.2.10)
2788 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleSystemIntg2
);
2790 add_ku(options
, kSecKeyUsageDigitalSignature
);
2792 require(result
= SecPolicyCreate(kSecPolicyAppleTestPPQSigning
, options
), errOut
);
2795 CFReleaseSafe(options
);
2799 @function SecPolicyCreateAppleTimeStamping
2800 @abstract Check for RFC3161 timestamping EKU.
2802 SecPolicyRef
SecPolicyCreateAppleTimeStamping(void)
2804 SecPolicyRef result
= NULL
;
2805 CFMutableDictionaryRef options
= NULL
;
2806 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2807 &kCFTypeDictionaryKeyCallBacks
,
2808 &kCFTypeDictionaryValueCallBacks
), errOut
);
2810 SecPolicyAddBasicX509Options(options
);
2812 /* Require id-kp-timeStamping extendedKeyUsage to be present. */
2813 add_eku(options
, &oidExtendedKeyUsageTimeStamping
);
2815 require(result
= SecPolicyCreate(kSecPolicyOIDAppleTimeStamping
, options
), errOut
);
2818 CFReleaseSafe(options
);
2823 @function SecPolicyCreateAppleATVAppSigning
2824 @abstract Check for intermediate certificate 'Apple Worldwide Developer Relations Certification Authority' by name,
2826 Leaf cert must have Digital Signature usage.
2827 Leaf cert must have Apple ATV App Signing marker OID (1.2.840.113635.100.6.1.24).
2828 Leaf cert must have 'Apple TVOS Application Signing' common name.
2830 SecPolicyRef
SecPolicyCreateAppleATVAppSigning(void)
2832 SecPolicyRef result
= NULL
;
2833 CFMutableDictionaryRef options
= NULL
;
2834 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2835 &kCFTypeDictionaryKeyCallBacks
,
2836 &kCFTypeDictionaryValueCallBacks
), errOut
);
2837 SecPolicyAddBasicCertOptions(options
);
2839 require(SecPolicyAddAppleAnchorOptions(options
), errOut
);
2840 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2842 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2843 CFSTR("Apple Worldwide Developer Relations Certification Authority"));
2844 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
,
2845 CFSTR("Apple TVOS Application Signing"));
2847 // Check that leaf has extension with "Apple ATV App Signing" prod oid (1.2.840.113635.100.6.1.24)
2848 add_leaf_marker(options
, &oidAppleCertExtATVAppSigningProd
);
2850 add_ku(options
, kSecKeyUsageDigitalSignature
);
2852 require(result
= SecPolicyCreate(kSecPolicyAppleATVAppSigning
, options
), errOut
);
2855 CFReleaseSafe(options
);
2860 @function SecPolicyCreateTestAppleATVAppSigning
2861 @abstract Check for intermediate certificate 'Apple Worldwide Developer Relations Certification Authority' by name,
2863 Leaf cert must have Digital Signature usage.
2864 Leaf cert must have Apple ATV App Signing Test marker OID (1.2.840.113635.100.6.1.24.1).
2865 Leaf cert must have 'TEST Apple TVOS Application Signing TEST' common name.
2867 SecPolicyRef
SecPolicyCreateTestAppleATVAppSigning(void)
2869 SecPolicyRef result
= NULL
;
2870 CFMutableDictionaryRef options
= NULL
;
2871 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2872 &kCFTypeDictionaryKeyCallBacks
,
2873 &kCFTypeDictionaryValueCallBacks
), errOut
);
2874 SecPolicyAddBasicCertOptions(options
);
2876 require(SecPolicyAddAppleAnchorOptions(options
), errOut
);
2877 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2879 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2880 CFSTR("Apple Worldwide Developer Relations Certification Authority"));
2881 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
,
2882 CFSTR("TEST Apple TVOS Application Signing TEST"));
2884 // Check that leaf has extension with "Apple ATV App Signing" test oid (1.2.840.113635.100.6.1.24.1)
2885 add_leaf_marker(options
, &oidAppleCertExtATVAppSigningTest
);
2887 add_ku(options
, kSecKeyUsageDigitalSignature
);
2889 require(result
= SecPolicyCreate(kSecPolicyAppleTestATVAppSigning
, options
), errOut
);
2892 CFReleaseSafe(options
);
2897 @function SecPolicyCreateApplePayIssuerEncryption
2898 @abstract Check for intermediate certificate 'Apple Worldwide Developer Relations CA - G2' by name,
2899 and ECC apple anchor.
2900 Leaf cert must have Key Encipherment and Key Agreement usage.
2901 Leaf cert must have Apple Pay Issuer Encryption marker OID (1.2.840.113635.100.6.39).
2903 SecPolicyRef
SecPolicyCreateApplePayIssuerEncryption(void)
2905 SecPolicyRef result
= NULL
;
2906 CFMutableDictionaryRef options
= NULL
;
2907 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2908 &kCFTypeDictionaryKeyCallBacks
,
2909 &kCFTypeDictionaryValueCallBacks
), errOut
);
2910 SecPolicyAddBasicCertOptions(options
);
2912 require(SecPolicyAddAnchorSHA1Options(options
, kAppleRootCA_ECC_SHA1
), errOut
);
2913 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2915 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2916 CFSTR("Apple Worldwide Developer Relations CA - G2"));
2918 // Check that leaf has extension with "Apple Pay Issuer Encryption" oid (1.2.840.113635.100.6.39)
2919 add_leaf_marker(options
, &oidAppleCertExtCryptoServicesExtEncryption
);
2921 add_ku(options
, kSecKeyUsageKeyEncipherment
);
2923 require(result
= SecPolicyCreate(kSecPolicyApplePayIssuerEncryption
, options
), errOut
);
2926 CFReleaseSafe(options
);
2931 @function SecPolicyCreateAppleATVVPNProfileSigning
2932 @abstract Check for leaf marker OID 1.2.840.113635.100.6.43,
2933 intermediate marker OID 1.2.840.113635.100.6.2.10,
2934 chains to Apple Root CA, path length 3
2936 SecPolicyRef
SecPolicyCreateAppleATVVPNProfileSigning(void)
2938 SecPolicyRef result
= NULL
;
2939 CFMutableDictionaryRef options
= NULL
;
2940 CFMutableDictionaryRef appleAnchorOptions
= NULL
;
2941 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2942 &kCFTypeDictionaryKeyCallBacks
,
2943 &kCFTypeDictionaryValueCallBacks
), errOut
);
2945 SecPolicyAddBasicCertOptions(options
);
2947 // Require pinning to the Apple CAs (including test CA for internal releases)
2948 appleAnchorOptions
= CFDictionaryCreateMutableForCFTypes(NULL
);
2949 require(appleAnchorOptions
, errOut
);
2951 if (SecIsInternalRelease()) {
2952 CFDictionarySetValue(appleAnchorOptions
,
2953 kSecPolicyAppleAnchorIncludeTestRoots
, kCFBooleanTrue
);
2956 add_element(options
, kSecPolicyCheckAnchorApple
, appleAnchorOptions
);
2958 // Cert chain length 3
2959 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2961 // Check leaf for Apple ATV VPN Profile Signing OID (1.2.840.113635.100.6.43)
2962 add_leaf_marker(options
, &oidAppleCertExtATVVPNProfileSigning
);
2964 // Check intermediate for Apple System Integration 2 CA intermediate marker (1.2.840.113635.100.6.2.10)
2965 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleSystemIntg2
);
2967 // Ensure that revocation is checked (OCSP only)
2968 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kCFBooleanFalse
);
2970 require(result
= SecPolicyCreate(kSecPolicyAppleATVVPNProfileSigning
, options
), errOut
);
2973 CFReleaseSafe(options
);
2974 CFReleaseSafe(appleAnchorOptions
);