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");
220 SEC_CONST_DECL (kSecPolicyOid
, "SecPolicyOid");
221 SEC_CONST_DECL (kSecPolicyName
, "SecPolicyName");
222 SEC_CONST_DECL (kSecPolicyClient
, "SecPolicyClient");
223 SEC_CONST_DECL (kSecPolicyRevocationFlags
, "SecPolicyRevocationFlags");
224 SEC_CONST_DECL (kSecPolicyTeamIdentifier
, "SecPolicyTeamIdentifier");
226 /* Private policy names */
227 static CFStringRef kSecPolicyOIDBasicX509
= CFSTR("basicX509");
228 static CFStringRef kSecPolicyOIDSSLServer
= CFSTR("sslServer");
229 static CFStringRef kSecPolicyOIDSSLClient
= CFSTR("sslClient");
230 static CFStringRef kSecPolicyOIDiPhoneActivation
= CFSTR("iPhoneActivation");
231 static CFStringRef kSecPolicyOIDiPhoneDeviceCertificate
=
232 CFSTR("iPhoneDeviceCertificate");
233 static CFStringRef kSecPolicyOIDFactoryDeviceCertificate
=
234 CFSTR("FactoryDeviceCertificate");
235 static CFStringRef kSecPolicyOIDiAP
= CFSTR("iAP");
236 static CFStringRef kSecPolicyOIDiTunesStoreURLBag
= CFSTR("iTunesStoreURLBag");
237 static CFStringRef kSecPolicyOIDEAPServer
= CFSTR("eapServer");
238 static CFStringRef kSecPolicyOIDEAPClient
= CFSTR("eapClient");
239 static CFStringRef kSecPolicyOIDIPSecServer
= CFSTR("ipsecServer");
240 static CFStringRef kSecPolicyOIDIPSecClient
= CFSTR("ipsecClient");
241 static CFStringRef kSecPolicyOIDiPhoneApplicationSigning
=
242 CFSTR("iPhoneApplicationSigning");
243 static CFStringRef kSecPolicyOIDiPhoneProfileApplicationSigning
=
244 CFSTR("iPhoneProfileApplicationSigning");
245 static CFStringRef kSecPolicyOIDiPhoneProvisioningProfileSigning
=
246 CFSTR("iPhoneProvisioningProfileSigning");
247 static CFStringRef kSecPolicyOIDAppleSWUpdateSigning
= CFSTR("AppleSWUpdateSigning");
248 static CFStringRef kSecPolicyOIDAppleTVOSApplicationSigning
=
249 CFSTR("AppleTVApplicationSigning");
250 static CFStringRef kSecPolicyOIDRevocation
= CFSTR("revocation");
251 static CFStringRef kSecPolicyOIDOCSPSigner
= CFSTR("OCSPSigner");
252 static CFStringRef kSecPolicyOIDSMIME
= CFSTR("SMIME");
253 static CFStringRef kSecPolicyOIDCodeSigning
= CFSTR("CodeSigning");
254 static CFStringRef kSecPolicyOIDPackageSigning
= CFSTR("PackageSigning");
255 static CFStringRef kSecPolicyOIDLockdownPairing
= CFSTR("LockdownPairing");
256 static CFStringRef kSecPolicyOIDURLBag
= CFSTR("URLBag");
257 static CFStringRef kSecPolicyOIDOTATasking
= CFSTR("OTATasking");
258 static CFStringRef kSecPolicyOIDMobileAsset
= CFSTR("MobileAsset");
259 static CFStringRef kSecPolicyOIDAppleIDAuthority
= CFSTR("AppleIDAuthority");
260 static CFStringRef kSecPolicyOIDMacAppStoreReceipt
= CFSTR("MacAppStoreReceipt");
261 static CFStringRef kSecPolicyOIDAppleTimeStamping
= CFSTR("AppleTimeStamping");
262 static CFStringRef kSecPolicyOIDApplePassbook
= CFSTR("ApplePassbook");
263 static CFStringRef kSecPolicyOIDAppleMobileStore
= CFSTR("AppleMobileStore");
264 static CFStringRef kSecPolicyOIDAppleTestMobileStore
= CFSTR("AppleTestMobileStore");
265 static CFStringRef kSecPolicyOIDAppleEscrowService
= CFSTR("AppleEscrowService");
266 static CFStringRef kSecPolicyOIDApplePCSEscrowService
= CFSTR("ApplePCSEscrowService");
267 static CFStringRef kSecPolicyOIDAppleProfileSigner
= CFSTR("AppleProfileSigner");
268 static CFStringRef kSecPolicyOIDAppleQAProfileSigner
= CFSTR("AppleQAProfileSigner");
269 static CFStringRef kSecPolicyOIDAppleOTAPKIAssetSigner
= CFSTR("AppleOTAPKIAssetSigner");
270 static CFStringRef kSecPolicyOIDAppleTestOTAPKIAssetSigner
= CFSTR("AppleTestOTAPKIAssetSigner");
271 static CFStringRef kSecPolicyOIDAppleIDValidationRecordSigningPolicy
= CFSTR("AppleIDValidationRecordSigningPolicy");
272 static CFStringRef kSecPolicyOIDAppleATVAppSigning
= CFSTR("AppleATVAppSigning");
273 static CFStringRef kSecPolicyOIDAppleTestATVAppSigning
= CFSTR("AppleTestATVAppSigning");
274 static CFStringRef kSecPolicyOIDApplePayIssuerEncryption
= CFSTR("ApplePayIssuerEncryption");
275 static CFStringRef kSecPolicyOIDAppleOSXProvisioningProfileSigning
= CFSTR("AppleOSXProvisioningProfileSigning");
277 /* Policies will now change to multiple categories of checks.
279 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.
280 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.
282 kSecPolicySLCheck Static Subscriber Certificate Checks
283 kSecPolicySICheck Static Subsidiary CA Checks
284 kSecPolicySACheck Static Anchor Checks
286 kSecPolicyDLCheck Dynamic Subscriber Certificate Checks
287 kSecPolicyDICheck Dynamic Subsidiary CA Checks
288 kSecPolicyDACheck Dynamic Anchor Checks ? not yet needed other than to
289 possibly exclude in a exception template (but those should still be per
290 certificate --- i.o.w. exceptions (or a database backed multiple role/user
291 trust store of some sort) and policies are 2 different things and this
292 text is about policies.
294 All static checks are only allowed to consider the certificate in isolation,
295 just given the position in the chain or the cert (leaf, intermidate, root).
296 dynamic checks can make determinations about the chain as a whole.
298 Static Subscriber Certificate Checks will be done up front before the
299 chainbuilder is even instantiated. If they fail and details aren't required
300 by the client (if no exceptions were present for this certificate) we could
301 short circuit fail the evaluation.
302 IDEA: These checks can dynamically add new checks...[needs work]
303 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
304 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
305 equivalent subtree from that level down. So SSL has EV as a subpolicy, but
306 EV dynamically enables the ocsp or crl or dcrl or any combination thereof subpolicies.
308 Static Subsidiary CA Checks will be used by the chain-builder to choose the
309 best parents to evaluate first. This feature is currently already implemented
310 but with a hardcoded is_valid(verifyTime) check. Instead we will evaluate all
311 Static Subsidiary CA Checks. The results of these checks for purposes of
312 generating details could be cached in the SecCertificatePathRefs themselves, or we can short circuit fail and recalc details on demand later.
314 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.
316 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.
318 Dynamic Subsidiary CA Checks might not be needed to have custom
319 implementations, since they are all done as part of the rfc5280 checks now.
320 This assumes that checks like issuer common name includes 'foo' are
321 implmented as Static Subscriber Certificate Checks instead.
323 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.
326 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.
328 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.
330 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.
332 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.
334 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.
336 We need to remember the best successful chain we find, where best is defined by: satisfies as many optional policies as possible.
338 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.
340 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.
342 Example sectrust operation in psuedocode:
346 new builder(verifyTime, certificates, anchors, anchorsOnly, policies);
347 chain = builder.subscriber_only_chain;
348 foreach (policy in policies{kSecPolicySLCheck}) {
349 foreach(check in policy)
350 SecPolicyRunCheck(builder, chain, check, details);
351 foreach (subpolicy in policy) {
352 check_policy(builder, chain, subpolicy, details{subpolicy.name})
354 propagate_subpolicy_results(builder, chain, details);
356 while (chain = builder.next) {
357 for (depth = 0; p_d = policies.at_depth(depth),
358 d_p_d = dynamic_policies.at_depth(depth), p_d || d_p_d; ++depth)
360 // Modify SecPathBuilderIsPartial() to
361 // run builder_check(buildier, policies, kSecPolicySICheck) instead
362 // of SecCertificateIsValid. Also rename considerExpired to
363 // considerSIFailures.
364 foreach (policy in p_d) {
365 check_policy(builder, chain, policy, kSecPolicySICheck, depth);
367 /// Recalculate since the static checks might have added new dynamic
369 d_p_d = dynamic_policies.at_depth(depth);
370 foreach (policy in d_p_d) {
371 check_policy(builder, chain, policy, kSecPolicySICheck, depth);
373 if (chain.is_anchored) {
374 foreach (policy in p_d) {
375 check_policy(builder, chain, policy, kSecPolicySACheck, depth);
377 foreach (policy in d_p_d) {
378 check_policy(builder, chain, policy, kSecPolicySACheck, depth);
380 foreach (policy in p_d) {
381 check_policy(builder, chain, policy, kSecPolicyDACheck, depth);
383 foreach (policy in d_p_d) {
384 check_policy(builder, chain, policy, kSecPolicyDACheck, depth);
387 foreach (policy in policies) {
388 check_policy(builder, chain, policy, kSecPolicySACheck, depth);
389 check_policy(builder, chain, policy, kSecPolicyDACheck, depth);
391 foreach (policy in policies{kSecPolicySDCheck}) {
396 check_policy(builder, chain, policy, check_class, details, depth) {
398 foreach(check in policy{check_class}) {
399 SecPolicyRunCheck(builder, chain, check, details);
403 foreach (subpolicy in policy) {
404 if (!check_policy(builder, chain, subpolicy, check_class,
405 details{subpolicy.name}) && subpolicy.is_required, depth)
409 propagate_subpolicy_results(builder, chain, details);
416 #define kSecPolicySHA1Size 20
417 #define kSecPolicySHA256Size 32
418 const UInt8 kAppleCASHA1
[kSecPolicySHA1Size
] = {
419 0x61, 0x1E, 0x5B, 0x66, 0x2C, 0x59, 0x3A, 0x08, 0xFF, 0x58,
420 0xD1, 0x4A, 0xE2, 0x24, 0x52, 0xD1, 0x98, 0xDF, 0x6C, 0x60
423 __unused
static const UInt8 kAppleTESTCASHA1
[kSecPolicySHA1Size
] = {
424 0xbc, 0x30, 0x55, 0xc8, 0xc8, 0xd3, 0x48, 0x3f, 0xf4, 0x8d,
425 0xfe, 0x3d, 0x51, 0x75, 0x31, 0xc9, 0xf4, 0xd7, 0x4a, 0xf7
428 static const UInt8 kITMSCASHA1
[kSecPolicySHA1Size
] = {
429 0x1D, 0x33, 0x42, 0x46, 0x8B, 0x10, 0xBD, 0xE6, 0x45, 0xCE,
430 0x44, 0x6E, 0xBB, 0xE8, 0xF5, 0x03, 0x5D, 0xF8, 0x32, 0x22
433 static const UInt8 kFactoryDeviceCASHA1
[kSecPolicySHA1Size
] = {
434 0xef, 0x68, 0x73, 0x17, 0xa4, 0xf8, 0xf9, 0x4b, 0x7b, 0x21,
435 0xe2, 0x2f, 0x09, 0x8f, 0xfd, 0x6a, 0xae, 0xc0, 0x0d, 0x63
438 static const UInt8 kApplePKISettingsAuthority
[kSecPolicySHA1Size
] = {
439 0x1D, 0x0C, 0xBA, 0xAD, 0x17, 0xFD, 0x7E, 0x9E, 0x9F, 0xF1,
440 0xC9, 0xA2, 0x66, 0x79, 0x60, 0x00, 0x8B, 0xAE, 0x70, 0xB8
443 static const UInt8 kAppleTestPKISettingsAuthority
[kSecPolicySHA1Size
] = {
444 0xDB, 0xBA, 0x25, 0x0B, 0xD8, 0x62, 0x71, 0x87, 0x54, 0x7E,
445 0xD7, 0xEF, 0x11, 0x94, 0x7E, 0x82, 0xE6, 0xD8, 0x1C, 0x9A
448 static const UInt8 kTestAppleRootCA_ECC_SHA1
[kSecPolicySHA1Size
] = {
449 0x62, 0x0A, 0xED, 0x83, 0xD2, 0x97, 0x4A, 0x77, 0x56, 0x33,
450 0x83, 0xBE, 0xDB, 0xF9, 0xA1, 0xBD, 0x5F, 0xFE, 0x55, 0x7B
453 static const UInt8 kAppleRootCA_ECC_SHA1
[kSecPolicySHA1Size
] = {
454 0xB5, 0x2C, 0xB0, 0x2F, 0xD5, 0x67, 0xE0, 0x35, 0x9F, 0xE8,
455 0xFA, 0x4D, 0x4C, 0x41, 0x03, 0x79, 0x70, 0xFE, 0x01, 0xB0
460 /********************************************************
461 ****************** SecPolicy object ********************
462 ********************************************************/
464 static void SecPolicyDestroy(CFTypeRef cf
) {
465 SecPolicyRef policy
= (SecPolicyRef
) cf
;
466 CFRelease(policy
->_oid
);
467 CFRelease(policy
->_options
);
470 static Boolean
SecPolicyCompare(CFTypeRef cf1
, CFTypeRef cf2
) {
471 SecPolicyRef policy1
= (SecPolicyRef
) cf1
;
472 SecPolicyRef policy2
= (SecPolicyRef
) cf2
;
473 return CFEqual(policy1
->_oid
, policy2
->_oid
) &&
474 CFEqual(policy1
->_options
, policy2
->_options
);
477 static CFHashCode
SecPolicyHash(CFTypeRef cf
) {
478 SecPolicyRef policy
= (SecPolicyRef
) cf
;
480 return CFHash(policy
->_oid
) + CFHash(policy
->_options
);
483 static CFStringRef
SecPolicyCopyFormatDescription(CFTypeRef cf
, CFDictionaryRef formatOptions
) {
484 SecPolicyRef policy
= (SecPolicyRef
) cf
;
485 CFMutableStringRef desc
= CFStringCreateMutable(kCFAllocatorDefault
, 0);
486 CFStringRef typeStr
= CFCopyTypeIDDescription(CFGetTypeID(cf
));
487 CFStringAppendFormat(desc
, NULL
,
488 CFSTR("<%@: oid: %@ options %@"), typeStr
,
489 policy
->_oid
, policy
->_options
);
491 CFStringAppend(desc
, CFSTR(" >"));
496 /* SecPolicy API functions. */
497 CFGiblisWithHashFor(SecPolicy
);
499 /* AUDIT[securityd](done):
500 oid (ok) is a caller provided string, only its cf type has been checked.
501 options is a caller provided dictionary, only its cf type has been checked.
503 SecPolicyRef
SecPolicyCreate(CFStringRef oid
, CFDictionaryRef options
) {
504 SecPolicyRef result
= NULL
;
506 require(oid
, errOut
);
507 require(options
, errOut
);
509 (SecPolicyRef
)_CFRuntimeCreateInstance(kCFAllocatorDefault
,
510 SecPolicyGetTypeID(),
511 sizeof(struct __SecPolicy
) - sizeof(CFRuntimeBase
), 0), errOut
);
516 result
->_options
= options
;
522 SecPolicyRef
SecPolicyCreateWithProperties(CFTypeRef policyIdentifier
,
523 CFDictionaryRef properties
) {
524 // Creates a policy reference for a given policy object identifier.
525 // If policy-specific parameters can be supplied (e.g. hostname),
526 // attempt to obtain from input properties dictionary.
527 // Returns NULL if the given identifier is unsupported.
529 SecPolicyRef policy
= NULL
;
530 CFStringRef name
= NULL
;
531 CFStringRef teamID
= NULL
;
532 Boolean client
= false;
533 require(policyIdentifier
&& (CFStringGetTypeID() == CFGetTypeID(policyIdentifier
)), errOut
);
536 name
= CFDictionaryGetValue(properties
, kSecPolicyName
);
537 teamID
= CFDictionaryGetValue(properties
, kSecPolicyTeamIdentifier
);
539 CFBooleanRef dictionaryClientValue
;
540 client
= (CFDictionaryGetValueIfPresent(properties
, kSecPolicyClient
, (const void **)&dictionaryClientValue
) &&
541 (dictionaryClientValue
!= NULL
) && CFEqual(kCFBooleanTrue
, dictionaryClientValue
));
544 if (CFEqual(policyIdentifier
, kSecPolicyAppleX509Basic
)) {
545 policy
= SecPolicyCreateBasicX509();
547 else if (CFEqual(policyIdentifier
, kSecPolicyAppleSSL
)) {
548 policy
= SecPolicyCreateSSL(!client
, name
);
550 else if (CFEqual(policyIdentifier
, kSecPolicyAppleEAP
)) {
551 CFArrayRef array
= NULL
;
553 array
= CFArrayCreate(kCFAllocatorDefault
, (const void **)&name
, 1, &kCFTypeArrayCallBacks
);
555 policy
= SecPolicyCreateEAP(!client
, array
);
556 CFReleaseSafe(array
);
558 else if (CFEqual(policyIdentifier
, kSecPolicyApplePackageSigning
)) {
559 policy
= SecPolicyCreateApplePackageSigning();
561 else if (CFEqual(policyIdentifier
, kSecPolicyAppleSWUpdateSigning
)) {
562 policy
= SecPolicyCreateAppleSWUpdateSigning();
564 else if (CFEqual(policyIdentifier
, kSecPolicyAppleIPsec
)) {
565 policy
= SecPolicyCreateIPSec(!client
, name
);
567 else if (CFEqual(policyIdentifier
, kSecPolicyAppleRevocation
)) {
568 policy
= SecPolicyCreateRevocation(kSecRevocationUseAnyAvailableMethod
);
570 else if (CFEqual(policyIdentifier
, kSecPolicyAppleSMIME
)) {
571 policy
= SecPolicyCreateSMIME(kSecSignSMIMEUsage
| kSecAnyEncryptSMIME
, name
);
573 else if (CFEqual(policyIdentifier
, kSecPolicyAppleCodeSigning
)) {
574 policy
= SecPolicyCreateCodeSigning();
576 else if (CFEqual(policyIdentifier
, kSecPolicyAppleTimeStamping
)) {
577 policy
= SecPolicyCreateAppleTimeStamping();
579 else if (CFEqual(policyIdentifier
, kSecPolicyMacAppStoreReceipt
)) {
580 policy
= SecPolicyCreateMacAppStoreReceipt();
582 else if (CFEqual(policyIdentifier
, kSecPolicyAppleIDValidation
)) {
583 policy
= SecPolicyCreateAppleIDAuthorityPolicy();
585 else if (CFEqual(policyIdentifier
, kSecPolicyApplePassbookSigning
)) {
586 policy
= SecPolicyCreatePassbookCardSigner(name
, teamID
);
588 else if (CFEqual(policyIdentifier
, kSecPolicyAppleMobileStore
)) {
589 policy
= SecPolicyCreateMobileStoreSigner();
591 else if (CFEqual(policyIdentifier
, kSecPolicyAppleTestMobileStore
)) {
592 policy
= SecPolicyCreateTestMobileStoreSigner();
594 else if (CFEqual(policyIdentifier
, kSecPolicyAppleEscrowService
)) {
595 policy
= SecPolicyCreateEscrowServiceSigner();
597 else if (CFEqual(policyIdentifier
, kSecPolicyApplePCSEscrowService
)) {
598 policy
= SecPolicyCreatePCSEscrowServiceSigner();
600 else if (CFEqual(policyIdentifier
, kSecPolicyAppleProfileSigner
)) {
601 policy
= SecPolicyCreateConfigurationProfileSigner();
603 else if (CFEqual(policyIdentifier
, kSecPolicyAppleQAProfileSigner
)) {
604 policy
= SecPolicyCreateQAConfigurationProfileSigner();
606 else if (CFEqual(policyIdentifier
, kSecPolicyAppleServerAuthentication
)) {
607 policy
= SecPolicyCreateAppleSSLService(name
);
609 #if TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR
610 else if (CFEqual(policyIdentifier
, kSecPolicyAppleOTAPKISigner
)) {
611 policy
= SecPolicyCreateOTAPKISigner();
613 else if (CFEqual(policyIdentifier
, kSecPolicyAppleTestOTAPKISigner
)) {
614 policy
= SecPolicyCreateTestOTAPKISigner();
616 else if (CFEqual(policyIdentifier
, kSecPolicyAppleIDValidationRecordSigningPolicy
)) {
617 policy
= SecPolicyCreateAppleIDValidationRecordSigningPolicy();
619 else if (CFEqual(policyIdentifier
, kSecPolicyAppleSMPEncryption
)) {
620 policy
= SecPolicyCreateAppleSMPEncryption();
622 else if (CFEqual(policyIdentifier
, kSecPolicyAppleTestSMPEncryption
)) {
623 policy
= SecPolicyCreateTestAppleSMPEncryption();
625 else if (CFEqual(policyIdentifier
, kSecPolicyAppleATVAppSigning
)) {
626 policy
= SecPolicyCreateAppleATVAppSigning();
628 else if (CFEqual(policyIdentifier
, kSecPolicyAppleTestATVAppSigning
)) {
629 policy
= SecPolicyCreateTestAppleATVAppSigning();
632 else if (CFEqual(policyIdentifier
, kSecPolicyApplePPQSigning
)) {
633 policy
= SecPolicyCreateApplePPQSigning();
635 else if (CFEqual(policyIdentifier
, kSecPolicyAppleTestPPQSigning
)) {
636 policy
= SecPolicyCreateTestApplePPQSigning();
638 else if (CFEqual(policyIdentifier
, kSecPolicyApplePayIssuerEncryption
)) {
639 policy
= SecPolicyCreateApplePayIssuerEncryption();
642 secerror("ERROR: policy \"%@\" is unsupported", policyIdentifier
);
649 CFDictionaryRef
SecPolicyCopyProperties(SecPolicyRef policyRef
) {
650 // Builds and returns a dictionary which the caller must release.
652 #pragma clang diagnostic push
653 #pragma clang diagnostic ignored "-Wnonnull"
654 // After introducing nullability annotations, policyRef is supposed to be nonnull, suppress the warning
655 if (!policyRef
) return NULL
;
656 #pragma clang diagnostic pop
657 CFMutableDictionaryRef properties
= CFDictionaryCreateMutable(NULL
, 0,
658 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
659 #pragma clang diagnostic push
660 #pragma clang diagnostic ignored "-Wnonnull"
661 // 'properties' is nonnull in reality suppress the warning
662 if (!properties
) return NULL
;
663 #pragma clang diagnostic pop
664 CFStringRef oid
= (CFStringRef
) CFRetain(policyRef
->_oid
);
665 CFTypeRef nameKey
= NULL
;
667 // Convert private to public OID if we have one
668 CFStringRef outOid
= oid
;
669 if (CFEqual(oid
, kSecPolicyOIDBasicX509
)) {
670 outOid
= kSecPolicyAppleX509Basic
;
672 else if (CFEqual(oid
, kSecPolicyOIDSSLServer
) ||
673 CFEqual(oid
, kSecPolicyOIDSSLClient
)) {
674 outOid
= kSecPolicyAppleSSL
;
675 nameKey
= kSecPolicyCheckSSLHostname
;
677 else if (CFEqual(oid
, kSecPolicyOIDEAPServer
) ||
678 CFEqual(oid
, kSecPolicyOIDEAPClient
)) {
679 outOid
= kSecPolicyAppleEAP
;
680 nameKey
= kSecPolicyCheckEAPTrustedServerNames
;
682 else if (CFEqual(oid
, kSecPolicyOIDIPSecServer
) ||
683 CFEqual(oid
, kSecPolicyOIDIPSecClient
)) {
684 outOid
= kSecPolicyAppleIPsec
;
685 nameKey
= kSecPolicyCheckSSLHostname
;
687 else if (CFEqual(oid
, kSecPolicyOIDRevocation
)) {
688 outOid
= kSecPolicyAppleRevocation
;
690 else if (CFEqual(oid
, kSecPolicyOIDSMIME
)) {
691 outOid
= kSecPolicyAppleSMIME
;
692 nameKey
= kSecPolicyCheckEmail
;
694 else if (CFEqual(oid
, kSecPolicyOIDCodeSigning
)) {
695 outOid
= kSecPolicyAppleCodeSigning
;
697 else if (CFEqual(oid
, kSecPolicyOIDAppleIDAuthority
)) {
698 outOid
= kSecPolicyAppleIDValidation
;
700 else if (CFEqual(oid
, kSecPolicyOIDApplePassbook
)) {
701 outOid
= kSecPolicyApplePassbookSigning
;
703 else if (CFEqual(oid
, kSecPolicyOIDAppleMobileStore
)) {
704 outOid
= kSecPolicyAppleMobileStore
;
706 else if (CFEqual(oid
, kSecPolicyOIDAppleTestMobileStore
)) {
707 outOid
= kSecPolicyAppleTestMobileStore
;
709 else if (CFEqual(oid
, kSecPolicyOIDAppleEscrowService
)) {
710 outOid
= kSecPolicyAppleEscrowService
;
712 else if (CFEqual(oid
, kSecPolicyOIDApplePCSEscrowService
)) {
713 outOid
= kSecPolicyApplePCSEscrowService
;
715 else if (CFEqual(oid
, kSecPolicyOIDAppleProfileSigner
)) {
716 outOid
= kSecPolicyAppleProfileSigner
;
718 else if (CFEqual(oid
, kSecPolicyOIDAppleQAProfileSigner
)) {
719 outOid
= kSecPolicyAppleQAProfileSigner
;
721 #if TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR
722 else if (CFEqual(oid
, kSecPolicyOIDAppleOTAPKIAssetSigner
)) {
723 outOid
= kSecPolicyAppleOTAPKISigner
;
725 else if (CFEqual(oid
, kSecPolicyOIDAppleTestOTAPKIAssetSigner
)) {
726 outOid
= kSecPolicyAppleTestOTAPKISigner
;
728 else if (CFEqual(oid
, kSecPolicyOIDAppleIDValidationRecordSigningPolicy
)) {
729 outOid
= kSecPolicyAppleIDValidationRecordSigningPolicy
;
731 else if (CFEqual(oid
, kSecPolicyOIDAppleATVAppSigning
)) {
732 outOid
= kSecPolicyAppleATVAppSigning
;
734 else if (CFEqual(oid
, kSecPolicyOIDAppleTestATVAppSigning
)) {
735 outOid
= kSecPolicyAppleTestATVAppSigning
;
738 else if (CFEqual(oid
, kSecPolicyOIDApplePayIssuerEncryption
)) {
739 outOid
= kSecPolicyApplePayIssuerEncryption
;
741 else if (CFEqual(oid
, kSecPolicyOIDAppleOSXProvisioningProfileSigning
)) {
742 outOid
= kSecPolicyAppleOSXProvisioningProfileSigning
;
746 CFDictionarySetValue(properties
, (const void *)kSecPolicyOid
,
747 (const void *)outOid
);
749 // Set kSecPolicyName if we have one
750 if (nameKey
&& policyRef
->_options
) {
751 CFTypeRef name
= (CFTypeRef
) CFDictionaryGetValue(policyRef
->_options
,
754 CFDictionarySetValue(properties
, (const void *)kSecPolicyName
,
759 // Set kSecPolicyClient
760 if (CFEqual(oid
, kSecPolicyOIDSSLClient
) ||
761 CFEqual(oid
, kSecPolicyOIDIPSecClient
) ||
762 CFEqual(oid
, kSecPolicyOIDEAPClient
)) {
763 CFDictionarySetValue(properties
, (const void *)kSecPolicyClient
,
764 (const void *)kCFBooleanTrue
);
771 static void SecPolicySetOid(SecPolicyRef policy
, CFStringRef oid
) {
772 if (!policy
|| !oid
) return;
773 CFStringRef temp
= policy
->_oid
;
779 CFStringRef
SecPolicyGetOidString(SecPolicyRef policy
) {
783 CFDictionaryRef
SecPolicyGetOptions(SecPolicyRef policy
) {
784 return policy
->_options
;
787 void SecPolicySetOptionsValue(SecPolicyRef policy
, CFStringRef key
, CFTypeRef value
) {
788 if (!policy
|| !key
) return;
789 CFMutableDictionaryRef options
= (CFMutableDictionaryRef
) policy
->_options
;
791 options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
792 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
793 if (!options
) return;
794 policy
->_options
= options
;
796 CFDictionarySetValue(options
, key
, value
);
800 // this is declared as NA for iPhone in SecPolicy.h, so declare here
801 OSStatus
SecPolicySetProperties(SecPolicyRef policyRef
, CFDictionaryRef properties
);
804 OSStatus
SecPolicySetProperties(SecPolicyRef policyRef
, CFDictionaryRef properties
) {
805 // Set policy options based on the provided dictionary keys.
807 if (!(policyRef
&& properties
&& (CFDictionaryGetTypeID() == CFGetTypeID(properties
)))) {
810 CFStringRef oid
= (CFStringRef
) CFRetain(policyRef
->_oid
);
811 OSStatus result
= errSecSuccess
;
814 CFTypeRef name
= NULL
;
815 if (CFDictionaryGetValueIfPresent(properties
, (const void *)kSecPolicyName
,
816 (const void **)&name
) && name
) {
817 CFTypeID typeID
= CFGetTypeID(name
);
818 if (CFEqual(oid
, kSecPolicyOIDSSLServer
) ||
819 CFEqual(oid
, kSecPolicyOIDSSLClient
) ||
820 CFEqual(oid
, kSecPolicyOIDIPSecServer
) ||
821 CFEqual(oid
, kSecPolicyOIDIPSecClient
)) {
822 if (CFStringGetTypeID() == typeID
) {
823 SecPolicySetOptionsValue(policyRef
, kSecPolicyCheckSSLHostname
, name
);
825 else result
= errSecParam
;
827 else if (CFEqual(oid
, kSecPolicyOIDEAPServer
) ||
828 CFEqual(oid
, kSecPolicyOIDEAPClient
)) {
829 if ((CFStringGetTypeID() == typeID
) ||
830 (CFArrayGetTypeID() == typeID
)) {
831 SecPolicySetOptionsValue(policyRef
, kSecPolicyCheckEAPTrustedServerNames
, name
);
833 else result
= errSecParam
;
835 else if (CFEqual(oid
, kSecPolicyOIDSMIME
)) {
836 if (CFStringGetTypeID() == typeID
) {
837 SecPolicySetOptionsValue(policyRef
, kSecPolicyCheckEmail
, name
);
839 else result
= errSecParam
;
844 CFTypeRef client
= NULL
;
845 if (CFDictionaryGetValueIfPresent(properties
, (const void *)kSecPolicyClient
,
846 (const void **)&client
) && client
) {
847 if (!(CFBooleanGetTypeID() == CFGetTypeID(client
))) {
848 result
= errSecParam
;
850 else if (CFEqual(client
, kCFBooleanTrue
)) {
851 if (CFEqual(oid
, kSecPolicyOIDSSLServer
)) {
852 SecPolicySetOid(policyRef
, kSecPolicyOIDSSLClient
);
854 else if (CFEqual(oid
, kSecPolicyOIDIPSecServer
)) {
855 SecPolicySetOid(policyRef
, kSecPolicyOIDIPSecClient
);
857 else if (CFEqual(oid
, kSecPolicyOIDEAPServer
)) {
858 SecPolicySetOid(policyRef
, kSecPolicyOIDEAPClient
);
862 if (CFEqual(oid
, kSecPolicyOIDSSLClient
)) {
863 SecPolicySetOid(policyRef
, kSecPolicyOIDSSLServer
);
865 else if (CFEqual(oid
, kSecPolicyOIDIPSecClient
)) {
866 SecPolicySetOid(policyRef
, kSecPolicyOIDIPSecServer
);
868 else if (CFEqual(oid
, kSecPolicyOIDEAPClient
)) {
869 SecPolicySetOid(policyRef
, kSecPolicyOIDEAPServer
);
878 static xpc_object_t
copy_xpc_policy_object(SecPolicyRef policy
);
879 static bool append_policy_to_xpc_array(SecPolicyRef policy
, xpc_object_t xpc_policies
);
880 extern xpc_object_t
copy_xpc_policies_array(CFArrayRef policies
);
881 extern OSStatus
validate_array_of_items(CFArrayRef array
, CFStringRef arrayItemType
, CFTypeID itemTypeID
, bool required
);
883 static xpc_object_t
copy_xpc_policy_object(SecPolicyRef policy
) {
884 xpc_object_t xpc_policy
= NULL
;
885 xpc_object_t data
[2] = { NULL
, NULL
};
886 if (policy
->_oid
&& (CFGetTypeID(policy
->_oid
) == CFStringGetTypeID())) {
887 data
[0] = _CFXPCCreateXPCObjectFromCFObject(policy
->_oid
);
889 secerror("policy 0x%lX has no _oid", (uintptr_t)policy
);
891 if (policy
->_options
&& (CFGetTypeID(policy
->_options
) == CFDictionaryGetTypeID())) {
892 data
[1] = _CFXPCCreateXPCObjectFromCFObject(policy
->_options
);
894 secerror("policy 0x%lX has no _options", (uintptr_t)policy
);
896 xpc_policy
= xpc_array_create(data
, array_size(data
));
897 if (data
[0]) xpc_release(data
[0]);
898 if (data
[1]) xpc_release(data
[1]);
902 static bool append_policy_to_xpc_array(SecPolicyRef policy
, xpc_object_t xpc_policies
) {
906 xpc_object_t xpc_policy
= copy_xpc_policy_object(policy
);
910 xpc_array_append_value(xpc_policies
, xpc_policy
);
911 xpc_release(xpc_policy
);
915 xpc_object_t
copy_xpc_policies_array(CFArrayRef policies
) {
916 xpc_object_t xpc_policies
= xpc_array_create(NULL
, 0);
920 validate_array_of_items(policies
, CFSTR("policy"), SecPolicyGetTypeID(), true);
921 CFIndex ix
, count
= CFArrayGetCount(policies
);
922 for (ix
= 0; ix
< count
; ++ix
) {
923 SecPolicyRef policy
= (SecPolicyRef
) CFArrayGetValueAtIndex(policies
, ix
);
924 #if SECTRUST_VERBOSE_DEBUG
925 CFDictionaryRef props
= SecPolicyCopyProperties(policy
);
926 secerror("idx=%d of %d; policy=0x%lX properties=%@", (int)ix
, (int)count
, (uintptr_t)policy
, props
);
927 CFReleaseSafe(props
);
929 if (!append_policy_to_xpc_array(policy
, xpc_policies
)) {
930 xpc_release(xpc_policies
);
938 static xpc_object_t
SecPolicyCopyXPCObject(SecPolicyRef policy
, CFErrorRef
*error
) {
939 xpc_object_t xpc_policy
= NULL
;
940 xpc_object_t data
[2] = {};
941 require_action_quiet(data
[0] = _CFXPCCreateXPCObjectFromCFObject(policy
->_oid
), exit
,
942 SecError(errSecParam
, error
, CFSTR("failed to create xpc_object from policy oid")));
943 require_action_quiet(data
[1] = _CFXPCCreateXPCObjectFromCFObject(policy
->_options
), exit
,
944 SecError(errSecParam
, error
, CFSTR("failed to create xpc_object from policy options")));
945 require_action_quiet(xpc_policy
= xpc_array_create(data
, array_size(data
)), exit
,
946 SecError(errSecAllocate
, error
, CFSTR("failed to create xpc_array for policy")));
949 if (data
[0]) xpc_release(data
[0]);
950 if (data
[1]) xpc_release(data
[1]);
954 static bool SecPolicyAppendToXPCArray(SecPolicyRef policy
, xpc_object_t policies
, CFErrorRef
*error
) {
958 xpc_object_t xpc_policy
= SecPolicyCopyXPCObject(policy
, error
);
962 xpc_array_append_value(policies
, xpc_policy
);
963 xpc_release(xpc_policy
);
967 xpc_object_t
SecPolicyArrayCopyXPCArray(CFArrayRef policies
, CFErrorRef
*error
) {
968 xpc_object_t xpc_policies
;
969 require_action_quiet(xpc_policies
= xpc_array_create(NULL
, 0), exit
,
970 SecError(errSecAllocate
, error
, CFSTR("failed to create xpc_array")));
971 CFIndex ix
, count
= CFArrayGetCount(policies
);
972 for (ix
= 0; ix
< count
; ++ix
) {
973 if (!SecPolicyAppendToXPCArray((SecPolicyRef
)CFArrayGetValueAtIndex(policies
, ix
), xpc_policies
, error
)) {
974 xpc_release(xpc_policies
);
982 static SecPolicyRef
SecPolicyCreateWithXPCObject(xpc_object_t xpc_policy
, CFErrorRef
*error
) {
983 SecPolicyRef policy
= NULL
;
984 CFTypeRef oid
= NULL
;
985 CFTypeRef options
= NULL
;
987 require_action_quiet(xpc_policy
, exit
, SecError(errSecParam
, error
, CFSTR("policy xpc value is NULL")));
988 require_action_quiet(xpc_get_type(xpc_policy
) == XPC_TYPE_ARRAY
, exit
, SecError(errSecDecode
, error
, CFSTR("policy xpc value is not an array")));
989 require_action_quiet(xpc_array_get_count(xpc_policy
) == 2, exit
, SecError(errSecDecode
, error
, CFSTR("policy xpc array count != 2")));
990 oid
= _CFXPCCreateCFObjectFromXPCObject(xpc_array_get_value(xpc_policy
, 0));
991 require_action_quiet(isString(oid
), exit
,
992 SecError(errSecParam
, error
, CFSTR("failed to convert xpc policy[0]=%@ to CFString"), oid
));
993 options
= _CFXPCCreateCFObjectFromXPCObject(xpc_array_get_value(xpc_policy
, 1));
994 require_action_quiet(isDictionary(options
), exit
,
995 SecError(errSecParam
, error
, CFSTR("failed to convert xpc policy[1]=%@ to CFDictionary"), options
));
996 require_action_quiet(policy
= SecPolicyCreate(oid
, options
), exit
, SecError(errSecDecode
, error
, CFSTR("Failed to create policy")));
1000 CFReleaseSafe(options
);
1004 CFArrayRef
SecPolicyXPCArrayCopyArray(xpc_object_t xpc_policies
, CFErrorRef
*error
) {
1005 CFMutableArrayRef policies
= NULL
;
1006 require_action_quiet(xpc_get_type(xpc_policies
) == XPC_TYPE_ARRAY
, exit
,
1007 SecError(errSecParam
, error
, CFSTR("policies xpc value is not an array")));
1008 size_t count
= xpc_array_get_count(xpc_policies
);
1009 require_action_quiet(policies
= CFArrayCreateMutable(kCFAllocatorDefault
, count
, &kCFTypeArrayCallBacks
), exit
,
1010 SecError(errSecAllocate
, error
, CFSTR("failed to create CFArray of capacity %zu"), count
));
1013 for (ix
= 0; ix
< count
; ++ix
) {
1014 SecPolicyRef policy
= SecPolicyCreateWithXPCObject(xpc_array_get_value(xpc_policies
, ix
), error
);
1016 CFRelease(policies
);
1019 CFArraySetValueAtIndex(policies
, ix
, policy
);
1028 static void add_element(CFMutableDictionaryRef options
, CFStringRef key
,
1030 CFTypeRef old_value
= CFDictionaryGetValue(options
, key
);
1032 CFMutableArrayRef array
;
1033 if (CFGetTypeID(old_value
) == CFArrayGetTypeID()) {
1034 array
= (CFMutableArrayRef
)old_value
;
1036 array
= CFArrayCreateMutable(kCFAllocatorDefault
, 0,
1037 &kCFTypeArrayCallBacks
);
1038 CFArrayAppendValue(array
, old_value
);
1039 CFDictionarySetValue(options
, key
, array
);
1042 CFArrayAppendValue(array
, value
);
1044 CFDictionaryAddValue(options
, key
, value
);
1048 static void add_eku(CFMutableDictionaryRef options
, const DERItem
*ekuOid
) {
1049 CFDataRef eku
= CFDataCreate(kCFAllocatorDefault
,
1050 ekuOid
? ekuOid
->data
: NULL
,
1051 ekuOid
? ekuOid
->length
: 0);
1053 add_element(options
, kSecPolicyCheckExtendedKeyUsage
, eku
);
1058 static void add_ku(CFMutableDictionaryRef options
, SecKeyUsage keyUsage
) {
1059 SInt32 dku
= keyUsage
;
1060 CFNumberRef ku
= CFNumberCreate(kCFAllocatorDefault
, kCFNumberSInt32Type
,
1063 add_element(options
, kSecPolicyCheckKeyUsage
, ku
);
1068 static void add_oid(CFMutableDictionaryRef options
, CFStringRef policy_key
, const DERItem
*oid
) {
1069 CFDataRef oid_data
= CFDataCreate(kCFAllocatorDefault
,
1070 oid
? oid
->data
: NULL
,
1071 oid
? oid
->length
: 0);
1073 add_element(options
, policy_key
, oid_data
);
1074 CFRelease(oid_data
);
1078 static void add_leaf_marker_value(CFMutableDictionaryRef options
, const DERItem
*markerOid
, CFStringRef string_value
) {
1080 CFTypeRef policyData
= NULL
;
1082 if (NULL
== string_value
) {
1083 policyData
= CFDataCreate(kCFAllocatorDefault
,
1084 markerOid
? markerOid
->data
: NULL
,
1085 markerOid
? markerOid
->length
: 0);
1087 CFStringRef oid_as_string
= SecDERItemCopyOIDDecimalRepresentation(kCFAllocatorDefault
, markerOid
);
1089 const void *key
[1] = { oid_as_string
};
1090 const void *value
[1] = { string_value
};
1091 policyData
= CFDictionaryCreate(kCFAllocatorDefault
,
1093 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
1094 CFReleaseNull(oid_as_string
);
1097 add_element(options
, kSecPolicyCheckLeafMarkerOid
, policyData
);
1099 CFReleaseNull(policyData
);
1103 static void add_leaf_marker(CFMutableDictionaryRef options
, const DERItem
*markerOid
) {
1104 add_leaf_marker_value(options
, markerOid
, NULL
);
1108 static void add_certificate_policy_oid(CFMutableDictionaryRef options
, const DERItem
*certificatePolicyOid
, CFStringRef string_value
) {
1109 CFTypeRef certificatePolicyData
= NULL
;
1111 if (NULL
== string_value
) {
1112 certificatePolicyData
= CFDataCreate(kCFAllocatorDefault
,
1113 certificatePolicyOid
? certificatePolicyOid
->data
: NULL
,
1114 certificatePolicyOid
? certificatePolicyOid
->length
: 0);
1116 CFStringRef oid_as_string
= SecDERItemCopyOIDDecimalRepresentation(kCFAllocatorDefault
, certificatePolicyOid
);
1118 const void *key
[1] = { oid_as_string
};
1119 const void *value
[1] = { string_value
};
1120 certificatePolicyData
= CFDictionaryCreate(kCFAllocatorDefault
,
1122 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
1123 CFReleaseNull(oid_as_string
);
1126 add_element(options
, kSecPolicyCheckCertificatePolicy
, certificatePolicyData
);
1128 CFReleaseNull(certificatePolicyData
);
1131 // Routines for adding dictionary entries for policies.
1134 // X.509, but missing validity requirements.
1135 static void SecPolicyAddBasicCertOptions(CFMutableDictionaryRef options
)
1137 //CFDictionaryAddValue(options, kSecPolicyCheckBasicCertificateProcessing, kCFBooleanTrue);
1138 CFDictionaryAddValue(options
, kSecPolicyCheckCriticalExtensions
, kCFBooleanTrue
);
1139 CFDictionaryAddValue(options
, kSecPolicyCheckIdLinkage
, kCFBooleanTrue
);
1140 CFDictionaryAddValue(options
, kSecPolicyCheckBasicContraints
, kCFBooleanTrue
);
1141 CFDictionaryAddValue(options
, kSecPolicyCheckNonEmptySubject
, kCFBooleanTrue
);
1142 CFDictionaryAddValue(options
, kSecPolicyCheckQualifiedCertStatements
, kCFBooleanTrue
);
1145 static void SecPolicyAddBasicX509Options(CFMutableDictionaryRef options
)
1147 SecPolicyAddBasicCertOptions(options
);
1148 CFDictionaryAddValue(options
, kSecPolicyCheckValidIntermediates
, kCFBooleanTrue
);
1149 CFDictionaryAddValue(options
, kSecPolicyCheckValidLeaf
, kCFBooleanTrue
);
1150 CFDictionaryAddValue(options
, kSecPolicyCheckValidRoot
, kCFBooleanTrue
);
1152 // Make sure that black and gray leaf checks are performed for basic X509 chain building
1153 CFDictionaryAddValue(options
, kSecPolicyCheckBlackListedLeaf
, kCFBooleanTrue
);
1154 CFDictionaryAddValue(options
, kSecPolicyCheckGrayListedLeaf
, kCFBooleanTrue
);
1157 static bool SecPolicyAddChainLengthOptions(CFMutableDictionaryRef options
, CFIndex length
)
1159 bool result
= false;
1160 CFNumberRef lengthAsCF
= NULL
;
1162 require(lengthAsCF
= CFNumberCreate(kCFAllocatorDefault
,
1163 kCFNumberCFIndexType
, &length
), errOut
);
1164 CFDictionaryAddValue(options
, kSecPolicyCheckChainLength
, lengthAsCF
);
1169 CFReleaseSafe(lengthAsCF
);
1173 static bool SecPolicyAddAnchorSHA1Options(CFMutableDictionaryRef options
,
1174 const UInt8 anchorSha1
[kSecPolicySHA1Size
])
1176 bool success
= false;
1177 CFDataRef anchorData
= NULL
;
1179 require(anchorData
= CFDataCreate(kCFAllocatorDefault
, anchorSha1
, kSecPolicySHA1Size
), errOut
);
1180 add_element(options
, kSecPolicyCheckAnchorSHA1
, anchorData
);
1185 CFReleaseSafe(anchorData
);
1189 static bool SecPolicyAddAppleAnchorOptions(CFMutableDictionaryRef options
)
1191 return SecPolicyAddAnchorSHA1Options(options
, kAppleCASHA1
);
1195 // Policy Creation Functions
1197 SecPolicyRef
SecPolicyCreateBasicX509(void) {
1198 CFMutableDictionaryRef options
= NULL
;
1199 SecPolicyRef result
= NULL
;
1201 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1202 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1204 SecPolicyAddBasicX509Options(options
);
1205 CFDictionaryAddValue(options
, kSecPolicyCheckNoNetworkAccess
,
1208 require(result
= SecPolicyCreate(kSecPolicyOIDBasicX509
, options
), errOut
);
1211 CFReleaseSafe(options
);
1215 SecPolicyRef
SecPolicyCreateSSL(Boolean server
, CFStringRef hostname
) {
1216 CFMutableDictionaryRef options
= NULL
;
1217 SecPolicyRef result
= NULL
;
1219 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1220 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1222 SecPolicyAddBasicX509Options(options
);
1225 CFDictionaryAddValue(options
, kSecPolicyCheckSSLHostname
, hostname
);
1228 CFDictionaryAddValue(options
, kSecPolicyCheckBlackListedLeaf
, kCFBooleanTrue
);
1229 CFDictionaryAddValue(options
, kSecPolicyCheckGrayListedLeaf
, kCFBooleanTrue
);
1231 /* If server and EKU ext present then EKU ext should contain one of
1232 ServerAuth or ExtendedKeyUsageAny or NetscapeSGC or MicrosoftSGC.
1233 else if !server and EKU ext present then EKU ext should contain one of
1234 ClientAuth or ExtendedKeyUsageAny. */
1236 /* We always allow certificates that specify oidAnyExtendedKeyUsage. */
1237 add_eku(options
, NULL
); /* eku extension is optional */
1238 add_eku(options
, &oidAnyExtendedKeyUsage
);
1240 add_eku(options
, &oidExtendedKeyUsageServerAuth
);
1241 add_eku(options
, &oidExtendedKeyUsageMicrosoftSGC
);
1242 add_eku(options
, &oidExtendedKeyUsageNetscapeSGC
);
1244 add_eku(options
, &oidExtendedKeyUsageClientAuth
);
1247 require(result
= SecPolicyCreate(
1248 server
? kSecPolicyOIDSSLServer
: kSecPolicyOIDSSLClient
,
1252 CFReleaseSafe(options
);
1256 SecPolicyRef
SecPolicyCreateiPhoneActivation(void) {
1257 CFMutableDictionaryRef options
= NULL
;
1258 SecPolicyRef result
= NULL
;
1260 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1261 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1263 SecPolicyAddBasicCertOptions(options
);
1266 CFDictionaryAddValue(options
, kSecPolicyCheckKeyUsage
,
1268 CFDictionaryAddValue(options
, kSecPolicyCheckExtendedKeyUsage
,
1272 /* Basic X.509 policy with the additional requirements that the chain
1273 length is 3, it's anchored at the AppleCA and the leaf certificate
1274 has issuer "Apple iPhone Certification Authority" and
1275 subject "Apple iPhone Activation" for the common name. */
1276 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
1277 CFSTR("Apple iPhone Certification Authority"));
1278 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
,
1279 CFSTR("Apple iPhone Activation"));
1281 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1282 require(SecPolicyAddAppleAnchorOptions(options
), errOut
);
1284 require(result
= SecPolicyCreate(kSecPolicyOIDiPhoneActivation
, options
),
1288 CFReleaseSafe(options
);
1292 SecPolicyRef
SecPolicyCreateiPhoneDeviceCertificate(void) {
1293 CFMutableDictionaryRef options
= NULL
;
1294 SecPolicyRef result
= NULL
;
1296 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1297 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1299 SecPolicyAddBasicCertOptions(options
);
1302 CFDictionaryAddValue(options
, kSecPolicyCheckKeyUsage
,
1304 CFDictionaryAddValue(options
, kSecPolicyCheckExtendedKeyUsage
,
1308 /* Basic X.509 policy with the additional requirements that the chain
1309 length is 4, it's anchored at the AppleCA and the first intermediate
1310 has the subject "Apple iPhone Device CA". */
1311 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
1312 CFSTR("Apple iPhone Device CA"));
1314 require(SecPolicyAddChainLengthOptions(options
, 4), errOut
);
1315 require(SecPolicyAddAppleAnchorOptions(options
), errOut
);
1317 require(result
= SecPolicyCreate(kSecPolicyOIDiPhoneDeviceCertificate
, options
),
1321 CFReleaseSafe(options
);
1325 SecPolicyRef
SecPolicyCreateFactoryDeviceCertificate(void) {
1326 CFMutableDictionaryRef options
= NULL
;
1327 SecPolicyRef result
= NULL
;
1329 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1330 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1332 SecPolicyAddBasicCertOptions(options
);
1335 CFDictionaryAddValue(options
, kSecPolicyCheckKeyUsage
,
1337 CFDictionaryAddValue(options
, kSecPolicyCheckExtendedKeyUsage
,
1341 /* Basic X.509 policy with the additional requirements that the chain
1342 is anchored at the factory device certificate issuer. */
1343 require(SecPolicyAddAnchorSHA1Options(options
, kFactoryDeviceCASHA1
), errOut
);
1345 require(result
= SecPolicyCreate(kSecPolicyOIDFactoryDeviceCertificate
, options
),
1349 CFReleaseSafe(options
);
1353 SecPolicyRef
SecPolicyCreateiAP(void) {
1354 CFMutableDictionaryRef options
= NULL
;
1355 SecPolicyRef result
= NULL
;
1356 CFTimeZoneRef tz
= NULL
;
1357 CFDateRef date
= NULL
;
1359 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1360 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1362 SecPolicyAddBasicCertOptions(options
);
1364 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonNamePrefix
,
1367 date
= CFDateCreateForGregorianZuluDay(NULL
, 2006, 5, 31);
1368 CFDictionaryAddValue(options
, kSecPolicyCheckNotValidBefore
, date
);
1370 require(result
= SecPolicyCreate(kSecPolicyOIDiAP
, options
),
1374 CFReleaseSafe(date
);
1376 CFReleaseSafe(options
);
1380 SecPolicyRef
SecPolicyCreateiTunesStoreURLBag(void) {
1381 CFMutableDictionaryRef options
= NULL
;
1382 SecPolicyRef result
= NULL
;
1385 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1386 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1388 SecPolicyAddBasicCertOptions(options
);
1390 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectOrganization
,
1391 CFSTR("Apple Inc."));
1392 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
,
1393 CFSTR("iTunes Store URL Bag"));
1395 require(SecPolicyAddChainLengthOptions(options
, 2), errOut
);
1396 require(SecPolicyAddAnchorSHA1Options(options
, kITMSCASHA1
), errOut
);
1398 require(result
= SecPolicyCreate(kSecPolicyOIDiTunesStoreURLBag
, options
), errOut
);
1401 CFReleaseSafe(options
);
1405 SecPolicyRef
SecPolicyCreateEAP(Boolean server
, CFArrayRef trustedServerNames
) {
1406 CFMutableDictionaryRef options
= NULL
;
1407 SecPolicyRef result
= NULL
;
1409 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1410 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1412 SecPolicyAddBasicX509Options(options
);
1414 /* Since EAP is used to setup the network we don't want evaluation
1415 using this policy to access the network. */
1416 CFDictionaryAddValue(options
, kSecPolicyCheckNoNetworkAccess
,
1419 if (trustedServerNames
) {
1420 CFDictionaryAddValue(options
, kSecPolicyCheckEAPTrustedServerNames
, trustedServerNames
);
1422 /* Specifying trusted server names implies EAP-TLS,
1423 so we need to check for EKU per rdar://22206018 */
1425 /* If server and EKU ext present then EKU ext should contain one of
1426 ServerAuth or ExtendedKeyUsageAny or NetscapeSGC or MicrosoftSGC.
1427 else if !server and EKU ext present then EKU ext should contain one of
1428 ClientAuth or ExtendedKeyUsageAny. */
1430 /* We always allow certificates that specify oidAnyExtendedKeyUsage. */
1431 add_eku(options
, NULL
); /* eku extension is optional */
1432 add_eku(options
, &oidAnyExtendedKeyUsage
);
1434 add_eku(options
, &oidExtendedKeyUsageServerAuth
);
1435 add_eku(options
, &oidExtendedKeyUsageMicrosoftSGC
);
1436 add_eku(options
, &oidExtendedKeyUsageNetscapeSGC
);
1438 add_eku(options
, &oidExtendedKeyUsageClientAuth
);
1442 require(result
= SecPolicyCreate(
1443 server
? kSecPolicyOIDEAPServer
: kSecPolicyOIDEAPClient
,
1447 CFReleaseSafe(options
);
1451 SecPolicyRef
SecPolicyCreateIPSec(Boolean server
, CFStringRef hostname
) {
1452 CFMutableDictionaryRef options
= NULL
;
1453 SecPolicyRef result
= NULL
;
1455 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1456 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1458 SecPolicyAddBasicX509Options(options
);
1461 CFDictionaryAddValue(options
, kSecPolicyCheckSSLHostname
, hostname
);
1464 /* Require oidExtendedKeyUsageIPSec if Extended Keyusage Extention is
1466 /* Per <rdar://problem/6843827> Cisco VPN Certificate compatibility issue.
1467 We don't check the EKU for IPSec certs for now. If we do add eku
1468 checking back in the future, we should probably also accept the
1470 ipsecEndSystem 1.3.6.1.5.5.7.3.5
1472 ipsecTunnel 1.3.6.1.5.5.7.3.6
1473 ipsecUser 1.3.6.1.5.5.7.3.7
1475 //add_eku(options, NULL); /* eku extension is optional */
1476 //add_eku(options, &oidAnyExtendedKeyUsage);
1477 //add_eku(options, &oidExtendedKeyUsageIPSec);
1479 require(result
= SecPolicyCreate(
1480 server
? kSecPolicyOIDIPSecServer
: kSecPolicyOIDIPSecClient
,
1484 CFReleaseSafe(options
);
1488 SecPolicyRef
SecPolicyCreateiPhoneApplicationSigning(void) {
1489 CFMutableDictionaryRef options
= NULL
;
1490 SecPolicyRef result
= NULL
;
1492 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1493 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1495 SecPolicyAddBasicCertOptions(options
);
1497 /* Basic X.509 policy with the additional requirements that the chain
1498 length is 3, it's anchored at the AppleCA and the leaf certificate
1499 has issuer "Apple iPhone Certification Authority" and
1500 subject "Apple iPhone OS Application Signing" for the common name. */
1501 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
1502 CFSTR("Apple iPhone Certification Authority"));
1503 if (SecIsInternalRelease() && !SecIsProductionFused()) {
1504 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonNameTEST
,
1505 CFSTR("Apple iPhone OS Application Signing"));
1508 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
,
1509 CFSTR("Apple iPhone OS Application Signing"));
1512 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1513 require(SecPolicyAddAppleAnchorOptions(options
), errOut
);
1515 add_eku(options
, NULL
); /* eku extension is optional */
1516 add_eku(options
, &oidAnyExtendedKeyUsage
);
1517 add_eku(options
, &oidExtendedKeyUsageCodeSigning
);
1519 require(result
= SecPolicyCreate(kSecPolicyOIDiPhoneApplicationSigning
, options
),
1522 /* 1.2.840.113635.100.6.1.3, non-critical: DER:05:00 - application signing */
1525 CFReleaseSafe(options
);
1529 SecPolicyRef
SecPolicyCreateiPhoneProfileApplicationSigning(void) {
1530 CFMutableDictionaryRef options
= NULL
;
1531 SecPolicyRef result
= NULL
;
1533 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1534 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1535 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kCFBooleanFalse
);
1536 CFDictionaryAddValue(options
, kSecPolicyCheckValidLeaf
, kCFBooleanFalse
);
1538 require(result
= SecPolicyCreate(kSecPolicyOIDiPhoneProfileApplicationSigning
,
1542 CFReleaseSafe(options
);
1546 SecPolicyRef
SecPolicyCreateiPhoneProvisioningProfileSigning(void) {
1547 CFMutableDictionaryRef options
= NULL
;
1548 SecPolicyRef result
= NULL
;
1550 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1551 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1553 SecPolicyAddBasicCertOptions(options
);
1555 /* Basic X.509 policy with the additional requirements that the chain
1556 length is 3, it's anchored at the AppleCA and the leaf certificate
1557 has issuer "Apple iPhone Certification Authority" and
1558 subject "Apple iPhone OS Provisioning Profile Signing" for the common name. */
1559 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
1560 CFSTR("Apple iPhone Certification Authority"));
1561 if (SecIsInternalRelease() && !SecIsProductionFused()) {
1562 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonNameTEST
,
1563 CFSTR("Apple iPhone OS Provisioning Profile Signing"));
1566 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
,
1567 CFSTR("Apple iPhone OS Provisioning Profile Signing"));
1570 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1571 require(SecPolicyAddAppleAnchorOptions(options
), errOut
);
1573 require(result
= SecPolicyCreate(kSecPolicyOIDiPhoneProvisioningProfileSigning
, options
),
1576 /* 1.2.840.113635.100.6.2.2.1, non-critical: DER:05:00 - provisioning profile */
1579 CFReleaseSafe(options
);
1583 SecPolicyRef
SecPolicyCreateAppleTVOSApplicationSigning(void) {
1584 CFMutableDictionaryRef options
= NULL
;
1585 SecPolicyRef result
= NULL
;
1586 CFDataRef atvProdOid
= NULL
;
1587 CFDataRef atvTestOid
= NULL
;
1588 CFArrayRef oids
= NULL
;
1590 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1591 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1593 SecPolicyAddBasicCertOptions(options
);
1595 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1597 CFMutableDictionaryRef appleAnchorOptions
= CFDictionaryCreateMutableForCFTypes(NULL
);
1598 require(appleAnchorOptions
, errOut
);
1599 add_element(options
, kSecPolicyCheckAnchorApple
, appleAnchorOptions
);
1601 /* Check for intermediate: Apple Worldwide Developer Relations */
1602 /* 1.2.840.113635.100.6.2.1 */
1603 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleWWDR
);
1605 add_eku(options
, NULL
); /* eku extension is optional */
1606 add_eku(options
, &oidAnyExtendedKeyUsage
);
1607 add_eku(options
, &oidExtendedKeyUsageCodeSigning
);
1609 /* Check for prod or test AppleTV Application Signing OIDs */
1610 /* Prod: 1.2.840.113635.100.6.1.24 */
1611 /* Test: 1.2.840.113635.100.6.1.24.1 */
1612 atvProdOid
= CFDataCreate(kCFAllocatorDefault
, oidAppleTVOSApplicationSigningProd
.data
, oidAppleTVOSApplicationSigningProd
.length
);
1613 require(atvProdOid
, errOut
);
1614 atvTestOid
= CFDataCreate(kCFAllocatorDefault
, oidAppleTVOSApplicationSigningTest
.data
, oidAppleTVOSApplicationSigningTest
.length
);
1615 require(atvTestOid
, errOut
);
1617 oids
= CFArrayCreateForCFTypes(kCFAllocatorDefault
, atvProdOid
, atvTestOid
, NULL
);
1618 require(oids
, errOut
);
1620 add_element(options
, kSecPolicyCheckLeafMarkerOid
, oids
);
1622 require(result
= SecPolicyCreate(kSecPolicyOIDAppleTVOSApplicationSigning
, options
),
1626 CFReleaseSafe(options
);
1627 CFReleaseSafe(oids
);
1628 CFReleaseSafe(atvProdOid
);
1629 CFReleaseSafe(atvTestOid
);
1633 SecPolicyRef
SecPolicyCreateOCSPSigner(void) {
1634 CFMutableDictionaryRef options
= NULL
;
1635 SecPolicyRef result
= NULL
;
1637 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1638 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1640 SecPolicyAddBasicX509Options(options
);
1642 /* Require id-kp-OCSPSigning extendedKeyUsage to be present, not optional. */
1643 add_eku(options
, &oidExtendedKeyUsageOCSPSigning
);
1645 require(result
= SecPolicyCreate(kSecPolicyOIDOCSPSigner
, options
), errOut
);
1648 CFReleaseSafe(options
);
1652 SecPolicyRef
SecPolicyCreateRevocation(CFOptionFlags revocationFlags
) {
1653 CFMutableDictionaryRef options
= NULL
;
1654 SecPolicyRef result
= NULL
;
1656 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1657 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1659 /* false = ocsp, true = crl, string/url value = crl distribution point,
1660 array = list of multiple values for example false, true, url1, url2
1661 check ocsp, crl, and url1 and url2 for certs which have no extensions.
1663 if (revocationFlags
& kSecRevocationOCSPMethod
) {
1664 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kCFBooleanFalse
);
1666 else if (revocationFlags
& kSecRevocationCRLMethod
) {
1667 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kCFBooleanTrue
);
1670 if (revocationFlags
& kSecRevocationRequirePositiveResponse
) {
1671 CFDictionaryAddValue(options
, kSecPolicyCheckRevocationResponseRequired
, kCFBooleanTrue
);
1674 if (revocationFlags
& kSecRevocationNetworkAccessDisabled
) {
1675 CFDictionaryAddValue(options
, kSecPolicyCheckNoNetworkAccess
, kCFBooleanTrue
);
1678 /* Only flag bits 0-4 are currently defined */
1679 require(((revocationFlags
>> 5) == 0), errOut
);
1681 require(result
= SecPolicyCreate(kSecPolicyOIDRevocation
, options
), errOut
);
1684 CFReleaseSafe(options
);
1688 SecPolicyRef
SecPolicyCreateSMIME(CFIndex smimeUsage
, CFStringRef email
) {
1689 CFMutableDictionaryRef options
= NULL
;
1690 SecPolicyRef result
= NULL
;
1692 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1693 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1695 SecPolicyAddBasicX509Options(options
);
1697 /* We call add_ku for each combination of bits we are willing to allow. */
1698 if (smimeUsage
& kSecSignSMIMEUsage
) {
1699 add_ku(options
, kSecKeyUsageUnspecified
);
1700 add_ku(options
, kSecKeyUsageDigitalSignature
);
1701 add_ku(options
, kSecKeyUsageNonRepudiation
);
1703 if (smimeUsage
& kSecKeyEncryptSMIMEUsage
) {
1704 add_ku(options
, kSecKeyUsageKeyEncipherment
);
1706 if (smimeUsage
& kSecDataEncryptSMIMEUsage
) {
1707 add_ku(options
, kSecKeyUsageDataEncipherment
);
1709 if (smimeUsage
& kSecKeyExchangeDecryptSMIMEUsage
) {
1710 add_ku(options
, kSecKeyUsageKeyAgreement
| kSecKeyUsageDecipherOnly
);
1712 if (smimeUsage
& kSecKeyExchangeEncryptSMIMEUsage
) {
1713 add_ku(options
, kSecKeyUsageKeyAgreement
| kSecKeyUsageEncipherOnly
);
1715 if (smimeUsage
& kSecKeyExchangeBothSMIMEUsage
) {
1716 add_ku(options
, kSecKeyUsageKeyAgreement
| kSecKeyUsageEncipherOnly
| kSecKeyUsageDecipherOnly
);
1720 CFDictionaryAddValue(options
, kSecPolicyCheckEmail
, email
);
1723 /* RFC 3850 paragraph 4.4.4
1725 If the extended key usage extension is present in the certificate
1726 then interpersonal message S/MIME receiving agents MUST check that it
1727 contains either the emailProtection or the anyExtendedKeyUsage OID as
1728 defined in [KEYM]. S/MIME uses other than interpersonal messaging
1729 MAY require the explicit presence of the extended key usage extension
1730 or other OIDs to be present in the extension or both.
1732 add_eku(options
, NULL
); /* eku extension is optional */
1733 add_eku(options
, &oidAnyExtendedKeyUsage
);
1734 add_eku(options
, &oidExtendedKeyUsageEmailProtection
);
1736 require(result
= SecPolicyCreate(kSecPolicyOIDSMIME
, options
), errOut
);
1739 CFReleaseSafe(options
);
1743 SecPolicyRef
SecPolicyCreateApplePackageSigning(void) {
1744 CFMutableDictionaryRef options
= NULL
;
1745 SecPolicyRef result
= NULL
;
1747 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1748 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1750 // TBD: review OS X policy to see what options are needed for this policy
1751 SecPolicyAddBasicCertOptions(options
);
1753 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1754 require(SecPolicyAddAppleAnchorOptions(options
), errOut
);
1756 require(result
= SecPolicyCreate(kSecPolicyOIDPackageSigning
, options
),
1760 CFReleaseSafe(options
);
1765 SecPolicyRef
SecPolicyCreateAppleSWUpdateSigning(void) {
1766 CFMutableDictionaryRef options
= NULL
;
1767 SecPolicyRef result
= NULL
;
1769 * OS X rules for this policy:
1770 * -- Must have one intermediate cert
1771 * -- intermediate must have basic constraints with path length 0
1772 * -- intermediate has CSSMOID_APPLE_EKU_CODE_SIGNING EKU
1773 * -- leaf cert has either CODE_SIGNING or CODE_SIGN_DEVELOPMENT EKU (the latter of
1774 * which triggers a CSSMERR_APPLETP_CODE_SIGN_DEVELOPMENT error)
1776 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1777 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1779 // TBD: review OS X policy to see what options are needed for this policy
1780 SecPolicyAddBasicCertOptions(options
);
1782 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1783 require(SecPolicyAddAppleAnchorOptions(options
), errOut
);
1785 add_eku(options
, &oidAppleExtendedKeyUsageCodeSigning
);
1786 add_eku(options
, &oidAppleExtendedKeyUsageCodeSigningDev
);
1788 require(result
= SecPolicyCreate(kSecPolicyOIDAppleSWUpdateSigning
, options
),
1792 CFReleaseSafe(options
);
1797 SecPolicyRef
SecPolicyCreateCodeSigning(void) {
1798 CFMutableDictionaryRef options
= NULL
;
1799 SecPolicyRef result
= NULL
;
1801 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1802 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1805 #warning STU: <rdar://21328880>
1806 //%%% figure out why this policy is not passing for OS X.
1807 // I suspect it has to do with iOS not supporting anchor and keychain options yet.
1808 SecPolicyAddBasicCertOptions(options
);
1810 SecPolicyAddBasicX509Options(options
);
1812 /* If the key usage extension is present we accept it having either of
1814 add_ku(options
, kSecKeyUsageDigitalSignature
);
1815 add_ku(options
, kSecKeyUsageNonRepudiation
);
1817 /* We require a extended key usage extension and we accept any or
1818 codesigning ekus. */
1819 /* TODO: Do we want to accept the apple codesigning oid as well or is
1820 that a separate policy? */
1821 /* ANSWER: it's a separate policy, SecPolicyCreateAppleSWUpdateSigning */
1822 add_eku(options
, &oidAnyExtendedKeyUsage
);
1823 add_eku(options
, &oidExtendedKeyUsageCodeSigning
);
1826 require(result
= SecPolicyCreate(kSecPolicyOIDCodeSigning
, options
),
1830 CFReleaseSafe(options
);
1834 /* Explicitly leave out empty subject/subjectaltname check */
1835 SecPolicyRef
SecPolicyCreateLockdownPairing(void) {
1836 CFMutableDictionaryRef options
= NULL
;
1837 SecPolicyRef result
= NULL
;
1839 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1840 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1841 //CFDictionaryAddValue(options, kSecPolicyCheckBasicCertificateProcessing,
1843 CFDictionaryAddValue(options
, kSecPolicyCheckCriticalExtensions
,
1845 CFDictionaryAddValue(options
, kSecPolicyCheckIdLinkage
,
1847 CFDictionaryAddValue(options
, kSecPolicyCheckBasicContraints
,
1849 CFDictionaryAddValue(options
, kSecPolicyCheckQualifiedCertStatements
,
1852 require(result
= SecPolicyCreate(kSecPolicyOIDLockdownPairing
, options
), errOut
);
1855 CFReleaseSafe(options
);
1859 SecPolicyRef
SecPolicyCreateURLBag(void) {
1860 CFMutableDictionaryRef options
= NULL
;
1861 SecPolicyRef result
= NULL
;
1863 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1864 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1866 SecPolicyAddBasicCertOptions(options
);
1868 add_eku(options
, &oidExtendedKeyUsageCodeSigning
);
1870 require(result
= SecPolicyCreate(kSecPolicyOIDURLBag
, options
), errOut
);
1873 CFReleaseSafe(options
);
1877 static bool SecPolicyAddAppleCertificationAuthorityOptions(CFMutableDictionaryRef options
, bool honorValidity
)
1879 bool success
= false;
1882 SecPolicyAddBasicX509Options(options
);
1884 SecPolicyAddBasicCertOptions(options
);
1887 CFDictionaryAddValue(options
, kSecPolicyCheckKeyUsage
,
1889 CFDictionaryAddValue(options
, kSecPolicyCheckExtendedKeyUsage
,
1893 /* Basic X.509 policy with the additional requirements that the chain
1894 length is 3, it's anchored at the AppleCA and the leaf certificate
1895 has issuer "Apple iPhone Certification Authority". */
1896 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
1897 CFSTR("Apple iPhone Certification Authority"));
1899 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1900 require(SecPolicyAddAppleAnchorOptions(options
), errOut
);
1908 static SecPolicyRef
SecPolicyCreateAppleCertificationAuthorityPolicy(CFStringRef policyOID
, CFStringRef leafName
, bool honorValidity
)
1910 CFMutableDictionaryRef options
= NULL
;
1911 SecPolicyRef result
= NULL
;
1913 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1914 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1916 require(SecPolicyAddAppleCertificationAuthorityOptions(options
, honorValidity
), errOut
);
1918 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
, leafName
);
1920 require(result
= SecPolicyCreate(policyOID
, options
),
1924 CFReleaseSafe(options
);
1929 SecPolicyRef
SecPolicyCreateOTATasking(void)
1931 return SecPolicyCreateAppleCertificationAuthorityPolicy(kSecPolicyOIDOTATasking
, CFSTR("OTA Task Signing"), true);
1934 SecPolicyRef
SecPolicyCreateMobileAsset(void)
1936 return SecPolicyCreateAppleCertificationAuthorityPolicy(kSecPolicyOIDMobileAsset
, CFSTR("Asset Manifest Signing"), false);
1939 SecPolicyRef
SecPolicyCreateAppleIDAuthorityPolicy(void)
1941 SecPolicyRef result
= NULL
;
1942 CFMutableDictionaryRef options
= NULL
;
1943 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1944 &kCFTypeDictionaryKeyCallBacks
,
1945 &kCFTypeDictionaryValueCallBacks
), out
);
1947 //Leaf appears to be a SSL only cert, so policy should expand on that policy
1948 SecPolicyAddBasicX509Options(options
);
1950 // Apple CA anchored
1951 require(SecPolicyAddAppleAnchorOptions(options
), out
);
1953 // with the addition of the existence check of an extension with "Apple ID Sharing Certificate" oid (1.2.840.113635.100.4.7)
1954 // NOTE: this obviously intended to have gone into Extended Key Usage, but evidence of existing certs proves the contrary.
1955 add_leaf_marker(options
, &oidAppleExtendedKeyUsageAppleID
);
1957 // 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.
1958 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleID
);
1959 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleID2
);
1961 require(result
= SecPolicyCreate(kSecPolicyOIDAppleIDAuthority
, options
), out
);
1964 CFReleaseSafe(options
);
1968 SecPolicyRef
SecPolicyCreateMacAppStoreReceipt(void)
1970 SecPolicyRef result
= NULL
;
1971 CFMutableDictionaryRef options
= NULL
;
1972 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1973 &kCFTypeDictionaryKeyCallBacks
,
1974 &kCFTypeDictionaryValueCallBacks
), out
);
1976 SecPolicyAddBasicX509Options(options
);
1978 // Apple CA anchored
1979 require(SecPolicyAddAppleAnchorOptions(options
), out
);
1981 // - leaf needs certificatePolicies with CSSMOID_MACAPPSTORE_RECEIPT_CERT_POLICY
1982 // - chain length must be 3
1984 require(result
= SecPolicyCreate(kSecPolicyOIDMacAppStoreReceipt
, options
), out
);
1987 CFReleaseSafe(options
);
1992 static SecPolicyRef
_SecPolicyCreatePassbookCardSigner(CFStringRef cardIssuer
, CFStringRef teamIdentifier
, bool requireTeamID
)
1994 SecPolicyRef result
= NULL
;
1995 CFMutableDictionaryRef options
= NULL
;
1996 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1997 &kCFTypeDictionaryKeyCallBacks
,
1998 &kCFTypeDictionaryValueCallBacks
), out
);
2000 SecPolicyAddBasicX509Options(options
);
2001 SecPolicyAddAppleAnchorOptions(options
);
2003 if (teamIdentifier
) {
2004 // If supplied, teamIdentifier must match subject OU field
2005 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectOrganizationalUnit
, teamIdentifier
);
2008 // If not supplied, and it was required, fail
2009 require(!requireTeamID
, out
);
2012 // Must be both push and 3rd party package signing
2013 add_leaf_marker_value(options
, &oidAppleInstallerPackagingSigningExternal
, cardIssuer
);
2015 // We should check that it also has push marker, but we don't support requiring both, only either.
2016 // add_independent_oid(options, kSecPolicyCheckLeafMarkerOid, &oidApplePushServiceClient);
2018 // And Passbook signing eku
2019 add_eku(options
, &oidAppleExtendedKeyUsagePassbook
);
2021 require(result
= SecPolicyCreate(kSecPolicyOIDApplePassbook
, options
), out
);
2024 CFReleaseSafe(options
);
2028 SecPolicyRef
SecPolicyCreatePassbookCardSigner(CFStringRef cardIssuer
, CFStringRef teamIdentifier
)
2030 return _SecPolicyCreatePassbookCardSigner(cardIssuer
, teamIdentifier
, true);
2034 static SecPolicyRef
CreateMobileStoreSigner(Boolean forTest
)
2037 SecPolicyRef result
= NULL
;
2038 CFMutableDictionaryRef options
= NULL
;
2039 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2040 &kCFTypeDictionaryKeyCallBacks
,
2041 &kCFTypeDictionaryValueCallBacks
), errOut
);
2042 SecPolicyAddBasicX509Options(options
);
2043 SecPolicyAddAppleAnchorOptions(options
);
2045 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2047 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2048 CFSTR("Apple System Integration 2 Certification Authority"));
2050 add_ku(options
, kSecKeyUsageDigitalSignature
);
2052 const DERItem
* pOID
= (forTest
) ? &oidApplePolicyTestMobileStore
: &oidApplePolicyMobileStore
;
2054 add_certificate_policy_oid(options
, pOID
, NULL
);
2056 require(result
= SecPolicyCreate(kSecPolicyOIDAppleMobileStore
, options
), errOut
);
2059 CFReleaseSafe(options
);
2063 SecPolicyRef
SecPolicyCreateMobileStoreSigner(void)
2066 return CreateMobileStoreSigner(false);
2069 SecPolicyRef
SecPolicyCreateTestMobileStoreSigner(void)
2072 return CreateMobileStoreSigner(true);
2076 CF_RETURNS_RETAINED SecPolicyRef
SecPolicyCreateEscrowServiceSigner(void)
2078 SecPolicyRef result
= NULL
;
2079 CFMutableDictionaryRef options
= NULL
;
2080 CFArrayRef anArray
= NULL
;
2081 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2082 &kCFTypeDictionaryKeyCallBacks
,
2083 &kCFTypeDictionaryValueCallBacks
), errOut
);
2085 // X509, ignoring date validity
2086 SecPolicyAddBasicCertOptions(options
);
2089 add_ku(options
, kSecKeyUsageKeyEncipherment
);
2091 //add_leaf_marker(options, &oidApplePolicyEscrowService);
2092 require(SecPolicyAddChainLengthOptions(options
, 2), errOut
);
2095 Boolean anchorAdded
= false;
2096 // Get the roots by calling the SecCertificateCopyEscrowRoots
2097 anArray
= SecCertificateCopyEscrowRoots(kSecCertificateProductionEscrowRoot
);
2098 CFIndex numRoots
= 0;
2099 if (NULL
== anArray
|| 0 == (numRoots
= CFArrayGetCount(anArray
)))
2104 for (CFIndex iCnt
= 0; iCnt
< numRoots
; iCnt
++)
2106 SecCertificateRef aCert
= (SecCertificateRef
)CFArrayGetValueAtIndex(anArray
, iCnt
);
2110 CFDataRef sha_data
= SecCertificateGetSHA1Digest(aCert
);
2111 if (NULL
!= sha_data
)
2113 const UInt8
* pSHAData
= CFDataGetBytePtr(sha_data
);
2114 if (NULL
!= pSHAData
)
2116 SecPolicyAddAnchorSHA1Options(options
, pSHAData
);
2122 CFReleaseNull(anArray
);
2130 require(result
= SecPolicyCreate(kSecPolicyOIDAppleEscrowService
, options
), errOut
);
2133 CFReleaseSafe(anArray
);
2134 CFReleaseSafe(options
);
2138 CF_RETURNS_RETAINED SecPolicyRef
SecPolicyCreatePCSEscrowServiceSigner(void)
2140 SecPolicyRef result
= NULL
;
2141 CFMutableDictionaryRef options
= NULL
;
2142 CFArrayRef anArray
= NULL
;
2143 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2144 &kCFTypeDictionaryKeyCallBacks
,
2145 &kCFTypeDictionaryValueCallBacks
), errOut
);
2147 SecPolicyAddBasicX509Options(options
);
2150 add_ku(options
, kSecKeyUsageKeyEncipherment
);
2152 //add_leaf_marker(options, &oidApplePolicyEscrowService);
2153 require(SecPolicyAddChainLengthOptions(options
, 2), errOut
);
2156 Boolean anchorAdded
= false;
2157 anArray
= SecCertificateCopyEscrowRoots(kSecCertificateProductionPCSEscrowRoot
);
2158 CFIndex numRoots
= 0;
2159 if (NULL
== anArray
|| 0 == (numRoots
= CFArrayGetCount(anArray
)))
2164 for (CFIndex iCnt
= 0; iCnt
< numRoots
; iCnt
++)
2166 SecCertificateRef aCert
= (SecCertificateRef
)CFArrayGetValueAtIndex(anArray
, iCnt
);
2170 CFDataRef sha_data
= SecCertificateGetSHA1Digest(aCert
);
2171 if (NULL
!= sha_data
)
2173 const UInt8
* pSHAData
= CFDataGetBytePtr(sha_data
);
2174 if (NULL
!= pSHAData
)
2176 SecPolicyAddAnchorSHA1Options(options
, pSHAData
);
2182 CFReleaseNull(anArray
);
2190 require(result
= SecPolicyCreate(kSecPolicyOIDApplePCSEscrowService
, options
), errOut
);
2193 CFReleaseSafe(anArray
);
2194 CFReleaseSafe(options
);
2197 SecCertificateRef
SecPolicyCopyEscrowRootCertificate(void)
2199 SecCertificateRef result
= NULL
;
2204 SecPolicyRef
SecPolicyCreateConfigurationProfileSigner(void)
2206 SecPolicyRef result
= NULL
;
2207 CFMutableDictionaryRef options
= NULL
;
2208 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2209 &kCFTypeDictionaryKeyCallBacks
,
2210 &kCFTypeDictionaryValueCallBacks
), errOut
);
2212 SecPolicyAddBasicX509Options(options
);
2213 SecPolicyAddAppleAnchorOptions(options
);
2215 // Require the profile signing EKU
2216 add_eku(options
, &oidAppleExtendedKeyUsageProfileSigning
);
2218 require(result
= SecPolicyCreate(kSecPolicyOIDAppleProfileSigner
, options
), errOut
);
2221 CFReleaseSafe(options
);
2226 SecPolicyRef
SecPolicyCreateQAConfigurationProfileSigner(void)
2228 SecPolicyRef result
= NULL
;
2229 CFMutableDictionaryRef options
= NULL
;
2230 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2231 &kCFTypeDictionaryKeyCallBacks
,
2232 &kCFTypeDictionaryValueCallBacks
), errOut
);
2234 SecPolicyAddBasicX509Options(options
);
2235 SecPolicyAddAppleAnchorOptions(options
);
2237 // Require the QA profile signing EKU
2238 add_eku(options
, &oidAppleExtendedKeyUsageQAProfileSigning
);
2240 require(result
= SecPolicyCreate(kSecPolicyOIDAppleQAProfileSigner
, options
), errOut
);
2243 CFReleaseSafe(options
);
2247 SecPolicyRef
SecPolicyCreateOSXProvisioningProfileSigning(void)
2249 SecPolicyRef result
= NULL
;
2250 CFMutableDictionaryRef options
= NULL
;
2251 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2252 &kCFTypeDictionaryKeyCallBacks
,
2253 &kCFTypeDictionaryValueCallBacks
), errOut
);
2254 // Require valid chain from the Apple root
2255 SecPolicyAddBasicX509Options(options
);
2256 SecPolicyAddAppleAnchorOptions(options
);
2258 // Require provisioning profile leaf marker OID (1.2.840.113635.100.4.11)
2259 add_leaf_marker(options
, &oidAppleCertExtOSXProvisioningProfileSigning
);
2261 // Require intermediate marker OID (1.2.840.113635.100.6.2.1)
2262 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleWWDR
);
2264 // Require key usage that allows signing
2265 add_ku(options
, kSecKeyUsageDigitalSignature
);
2267 // Ensure that revocation is checked (OCSP)
2268 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kCFBooleanFalse
);
2270 require(result
= SecPolicyCreate(kSecPolicyOIDAppleOSXProvisioningProfileSigning
, options
), errOut
);
2273 CFReleaseSafe(options
);
2278 SecPolicyRef
SecPolicyCreateOTAPKISigner(void)
2280 SecPolicyRef result
= NULL
;
2281 CFMutableDictionaryRef options
= NULL
;
2282 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2283 &kCFTypeDictionaryKeyCallBacks
,
2284 &kCFTypeDictionaryValueCallBacks
), errOut
);
2285 SecPolicyAddBasicX509Options(options
);
2287 SecPolicyAddAnchorSHA1Options(options
, kApplePKISettingsAuthority
);
2288 require(SecPolicyAddChainLengthOptions(options
, 2), errOut
);
2290 require(result
= SecPolicyCreate(kSecPolicyOIDAppleOTAPKIAssetSigner
, options
), errOut
);
2293 CFReleaseSafe(options
);
2299 SecPolicyRef
SecPolicyCreateTestOTAPKISigner(void)
2301 SecPolicyRef result
= NULL
;
2302 CFMutableDictionaryRef options
= NULL
;
2303 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2304 &kCFTypeDictionaryKeyCallBacks
,
2305 &kCFTypeDictionaryValueCallBacks
), errOut
);
2306 SecPolicyAddBasicX509Options(options
);
2308 SecPolicyAddAnchorSHA1Options(options
, kAppleTestPKISettingsAuthority
);
2309 require(SecPolicyAddChainLengthOptions(options
, 2), errOut
);
2311 require(result
= SecPolicyCreate(kSecPolicyOIDAppleTestOTAPKIAssetSigner
, options
), errOut
);
2314 CFReleaseSafe(options
);
2319 @function SecPolicyCreateAppleSMPEncryption
2320 @abstract Check for intermediate certificate 'Apple System Integration CA - G3' by name,
2321 and root certificate 'Apple Root CA - G3' by hash.
2322 Leaf cert must have Key Encipherment usage.
2323 Leaf cert must have Apple SMP Encryption marker OID (1.2.840.113635.100.6.30).
2324 Intermediate must have marker OID (1.2.840.113635.100.6.2.13).
2326 SecPolicyRef
SecPolicyCreateAppleSMPEncryption(void)
2328 SecPolicyRef result
= NULL
;
2329 CFMutableDictionaryRef options
= NULL
;
2330 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2331 &kCFTypeDictionaryKeyCallBacks
,
2332 &kCFTypeDictionaryValueCallBacks
), errOut
);
2333 SecPolicyAddBasicCertOptions(options
);
2335 SecPolicyAddAnchorSHA1Options(options
, kAppleRootCA_ECC_SHA1
);
2336 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2338 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2339 CFSTR("Apple System Integration CA - G3"));
2341 // Check that leaf has extension with "Apple SMP Encryption" oid (1.2.840.113635.100.6.30)
2342 add_leaf_marker(options
, &oidAppleCertExtAppleSMPEncryption
);
2344 // Check that intermediate has extension (1.2.840.113635.100.6.2.13)
2345 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleSystemIntgG3
);
2347 add_ku(options
, kSecKeyUsageKeyEncipherment
);
2349 // Ensure that revocation is checked (OCSP)
2350 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kCFBooleanFalse
);
2352 require(result
= SecPolicyCreate(kSecPolicyAppleSMPEncryption
, options
), errOut
);
2355 CFReleaseSafe(options
);
2360 @function SecPolicyCreateTestAppleSMPEncryption
2361 @abstract Check for intermediate certificate 'Test Apple System Integration CA - ECC' by name,
2362 and root certificate 'Test Apple Root CA - ECC' by hash.
2363 Leaf cert must have Key Encipherment usage. Other checks TBD.
2365 SecPolicyRef
SecPolicyCreateTestAppleSMPEncryption(void)
2367 SecPolicyRef result
= NULL
;
2368 CFMutableDictionaryRef options
= NULL
;
2369 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2370 &kCFTypeDictionaryKeyCallBacks
,
2371 &kCFTypeDictionaryValueCallBacks
), errOut
);
2372 SecPolicyAddBasicCertOptions(options
);
2374 SecPolicyAddAnchorSHA1Options(options
, kTestAppleRootCA_ECC_SHA1
);
2375 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2377 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2378 CFSTR("Test Apple System Integration CA - ECC"));
2380 add_ku(options
, kSecKeyUsageKeyEncipherment
);
2382 // Ensure that revocation is checked (OCSP)
2383 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kCFBooleanFalse
);
2385 require(result
= SecPolicyCreate(kSecPolicyAppleTestSMPEncryption
, options
), errOut
);
2388 CFReleaseSafe(options
);
2393 SecPolicyRef
SecPolicyCreateAppleIDValidationRecordSigningPolicy(void)
2395 SecPolicyRef result
= NULL
;
2396 CFMutableDictionaryRef options
= NULL
;
2397 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2398 &kCFTypeDictionaryKeyCallBacks
,
2399 &kCFTypeDictionaryValueCallBacks
), errOut
);
2401 //Leaf appears to be a SSL only cert, so policy should expand on that policy
2402 SecPolicyAddBasicX509Options(options
);
2404 // Apple CA anchored
2405 require(SecPolicyAddAppleAnchorOptions(options
), errOut
);
2407 // Check for an extension with " Apple ID Validation Record Signing" oid (1.2.840.113635.100.6.25)
2408 add_leaf_marker(options
, &oidAppleCertExtensionAppleIDRecordValidationSigning
);
2410 // and validate that intermediate has extension
2411 // Application Integration Intermediate Certificate (1.2.840.113635.100.6.2.3)
2412 // and also validate that intermediate has extension
2413 // System Integration 2 Intermediate Certificate (1.2.840.113635.100.6.2.10)
2414 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleID
);
2415 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleSystemIntg2
);
2417 // Ensure that revocation is checked (OCSP)
2418 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kCFBooleanFalse
);
2420 require(result
= SecPolicyCreate(kSecPolicyOIDAppleIDValidationRecordSigningPolicy
, options
), errOut
);
2423 CFReleaseSafe(options
);
2428 allowUATRoot(CFStringRef service
, CFDictionaryRef context
)
2430 bool UATAllowed
= false;
2431 if (SecIsInternalRelease()) {
2432 CFStringRef setting
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("AppleServerAuthenticationAllowUAT%@"), service
);
2433 CFTypeRef value
= NULL
;
2434 require(setting
, fail
);
2437 CFDictionaryGetValueIfPresent(context
, setting
, &value
) &&
2439 CFBooleanGetValue(value
))
2444 if (CFPreferencesGetAppBooleanValue(setting
, CFSTR("com.apple.Security"), NULL
)) {
2454 requirePinning(CFStringRef service
)
2456 bool pinningRequired
= true;
2458 if (SecIsInternalRelease()) {
2459 CFStringRef setting
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("AppleServerAuthenticationNoPinning%@"), service
);
2460 require(setting
, fail
);
2461 if (CFPreferencesGetAppBooleanValue(setting
, CFSTR("com.apple.Security"), NULL
))
2462 pinningRequired
= false;
2466 return pinningRequired
;
2470 @function SecPolicyCreateAppleServerAuthCommon
2471 @abstract Generic policy for server authentication Sub CAs
2473 Allows control for both if pinning is required at all and if UAT environments should be added
2474 to the trust policy.
2476 No pinning is for developer/QA that needs to use proxy to debug the protocol, while UAT
2477 environment is for QA/internal developer that have no need allow fake servers.
2479 Both the noPinning and allowUAT are gated on that you run on internal hardware.
2484 SecPolicyCreateAppleServerAuthCommon(CFStringRef hostname
,
2485 CFDictionaryRef __unused context
,
2486 CFStringRef service
,
2487 const DERItem
*leafMarkerOID
,
2488 const DERItem
*UATLeafMarkerOID
)
2490 CFMutableDictionaryRef appleAnchorOptions
= NULL
;
2491 CFMutableDictionaryRef options
= NULL
;
2492 SecPolicyRef result
= NULL
;
2493 CFDataRef oid
= NULL
, uatoid
= NULL
;
2495 options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0, &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
2496 require(options
, errOut
);
2498 SecPolicyAddBasicX509Options(options
);
2500 CFDictionaryAddValue(options
, kSecPolicyCheckSSLHostname
, hostname
);
2502 CFDictionaryAddValue(options
, kSecPolicyCheckBlackListedLeaf
, kCFBooleanTrue
);
2503 CFDictionaryAddValue(options
, kSecPolicyCheckGrayListedLeaf
, kCFBooleanTrue
);
2505 add_eku(options
, &oidExtendedKeyUsageServerAuth
);
2507 if (requirePinning(service
)) {
2508 bool allowUAT
= allowUATRoot(service
, context
);
2511 * Require pinning to the Apple CA's (and if UAT environment,
2512 * include the Apple Test CA's as anchors).
2515 appleAnchorOptions
= CFDictionaryCreateMutableForCFTypes(NULL
);
2516 require(appleAnchorOptions
, errOut
);
2519 CFDictionarySetValue(appleAnchorOptions
,
2520 kSecPolicyAppleAnchorIncludeTestRoots
, kCFBooleanTrue
);
2523 add_element(options
, kSecPolicyCheckAnchorApple
, appleAnchorOptions
);
2526 * Check if we also should allow the UAT variant of the leafs
2527 * as some variants of the UAT environment uses that instead
2528 * of the test Apple CA's.
2532 oid
= CFDataCreate(kCFAllocatorDefault
, leafMarkerOID
->data
, leafMarkerOID
->length
);
2533 require(oid
, errOut
);
2535 uatoid
= CFDataCreate(kCFAllocatorDefault
, UATLeafMarkerOID
->data
, UATLeafMarkerOID
->length
);
2536 require(oid
, errOut
);
2538 CFArrayRef array
= CFArrayCreateForCFTypes(NULL
, oid
, uatoid
, NULL
);
2539 require(array
, errOut
);
2541 add_element(options
, kSecPolicyCheckLeafMarkerOid
, array
);
2542 CFReleaseSafe(array
);
2544 add_leaf_marker(options
, leafMarkerOID
);
2547 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleServerAuthentication
);
2551 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kCFBooleanFalse
);
2553 result
= SecPolicyCreate(kSecPolicyOIDSSLServer
, options
);
2554 require(result
, errOut
);
2557 CFReleaseSafe(appleAnchorOptions
);
2558 CFReleaseSafe(options
);
2560 CFReleaseSafe(uatoid
);
2567 @function SecPolicyCreateAppleIDSService
2568 @abstract Ensure we're appropriately pinned to the IDS service (SSL + Apple restrictions)
2570 SecPolicyRef
SecPolicyCreateAppleIDSService(CFStringRef hostname
)
2573 return SecPolicyCreateSSL(true, hostname
);
2575 return SecPolicyCreateAppleServerAuthCommon(hostname
, NULL
, CFSTR("IDS"),
2576 &oidAppleCertExtAppleServerAuthenticationIDSProd
,
2577 &oidAppleCertExtAppleServerAuthenticationIDSTest
);
2582 @function SecPolicyCreateAppleIDSService
2583 @abstract Ensure we're appropriately pinned to the IDS service (SSL + Apple restrictions)
2585 SecPolicyRef
SecPolicyCreateAppleIDSServiceContext(CFStringRef hostname
, CFDictionaryRef context
)
2587 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, CFSTR("IDS"),
2588 &oidAppleCertExtAppleServerAuthenticationIDSProd
,
2589 &oidAppleCertExtAppleServerAuthenticationIDSTest
);
2593 @function SecPolicyCreateAppleGSService
2594 @abstract Ensure we're appropriately pinned to the GS service
2596 SecPolicyRef
SecPolicyCreateAppleGSService(CFStringRef hostname
, CFDictionaryRef context
)
2598 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, CFSTR("GS"),
2599 &oidAppleCertExtAppleServerAuthenticationGS
,
2604 @function SecPolicyCreateApplePushService
2605 @abstract Ensure we're appropriately pinned to the Push service (SSL + Apple restrictions)
2607 SecPolicyRef
SecPolicyCreateApplePushService(CFStringRef hostname
, CFDictionaryRef context
)
2609 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, CFSTR("APN"),
2610 &oidAppleCertExtAppleServerAuthenticationAPNProd
,
2611 &oidAppleCertExtAppleServerAuthenticationAPNTest
);
2615 @function SecPolicyCreateApplePPQService
2616 @abstract Ensure we're appropriately pinned to the PPQ service (SSL + Apple restrictions)
2618 SecPolicyRef
SecPolicyCreateApplePPQService(CFStringRef hostname
, CFDictionaryRef context
)
2620 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, CFSTR("PPQ"),
2621 &oidAppleCertExtAppleServerAuthenticationPPQProd
,
2622 &oidAppleCertExtAppleServerAuthenticationPPQTest
);
2625 /* should use verbatim copy, but since this is the deprecated way, don't care right now */
2626 static const UInt8 entrustSPKIL1C
[kSecPolicySHA256Size
] = {
2627 0x54, 0x5b, 0xf9, 0x35, 0xe9, 0xad, 0xa1, 0xda,
2628 0x11, 0x7e, 0xdc, 0x3c, 0x2a, 0xcb, 0xc5, 0x6f,
2629 0xc0, 0x28, 0x09, 0x6c, 0x0e, 0x24, 0xbe, 0x9b,
2630 0x38, 0x94, 0xbe, 0x52, 0x2d, 0x1b, 0x43, 0xde
2634 @function SecPolicyCreateApplePushServiceLegacy
2635 @abstract Ensure we're appropriately pinned to the Push service (via Entrust)
2637 SecPolicyRef
SecPolicyCreateApplePushServiceLegacy(CFStringRef hostname
)
2639 CFMutableDictionaryRef options
= NULL
;
2640 SecPolicyRef result
= NULL
;
2641 CFDataRef digest
= NULL
;
2643 digest
= CFDataCreateWithBytesNoCopy(kCFAllocatorDefault
, entrustSPKIL1C
, sizeof(entrustSPKIL1C
), kCFAllocatorNull
);
2644 require(digest
, errOut
);
2646 options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0, &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
2647 require(options
, errOut
);
2649 SecPolicyAddBasicX509Options(options
);
2651 CFDictionaryAddValue(options
, kSecPolicyCheckSSLHostname
, hostname
);
2653 CFDictionaryAddValue(options
, kSecPolicyCheckBlackListedLeaf
, kCFBooleanTrue
);
2654 CFDictionaryAddValue(options
, kSecPolicyCheckGrayListedLeaf
, kCFBooleanTrue
);
2656 CFDictionaryAddValue(options
, kSecPolicyCheckIntermediateSPKISHA256
, digest
);
2658 add_eku(options
, &oidExtendedKeyUsageServerAuth
);
2660 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kCFBooleanFalse
);
2662 result
= SecPolicyCreate(kSecPolicyOIDSSLServer
, options
);
2663 require(result
, errOut
);
2666 CFReleaseSafe(digest
);
2667 CFReleaseSafe(options
);
2672 @function SecPolicyCreateAppleMMCSService
2673 @abstract Ensure we're appropriately pinned to the IDS service (SSL + Apple restrictions)
2675 SecPolicyRef
SecPolicyCreateAppleMMCSService(CFStringRef hostname
, CFDictionaryRef __unused context
)
2677 return SecPolicyCreateSSL(true, hostname
);
2681 @function SecPolicyCreateAppleSSLService
2682 @abstract Ensure we're appropriately pinned to an Apple server (SSL + Apple restrictions)
2684 SecPolicyRef
SecPolicyCreateAppleSSLService(CFStringRef hostname
)
2686 // SSL server, pinned to an Apple intermediate
2687 SecPolicyRef policy
= SecPolicyCreateSSL(true, hostname
);
2688 CFMutableDictionaryRef options
= NULL
;
2689 require(policy
, errOut
);
2691 // change options for SSL policy evaluation
2692 require((options
=(CFMutableDictionaryRef
)policy
->_options
) != NULL
, errOut
);
2694 // Apple CA anchored
2695 require(SecPolicyAddAppleAnchorOptions(options
), errOut
);
2697 // Check leaf for Apple Server Authentication marker oid (1.2.840.113635.100.6.27.1)
2698 add_leaf_marker(options
, &oidAppleCertExtAppleServerAuthentication
);
2700 // Check intermediate for Apple Server Authentication intermediate marker (1.2.840.113635.100.6.2.12)
2701 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleServerAuthentication
);
2703 // Ensure that revocation is checked (OCSP only)
2704 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kCFBooleanFalse
);
2709 CFReleaseSafe(options
);
2710 CFReleaseSafe(policy
);
2715 @function SecPolicyCreateApplePPQSigning
2716 @abstract Check for intermediate certificate 'Apple System Integration 2 Certification Authority' by name,
2718 Leaf cert must have Digital Signature usage.
2719 Leaf cert must have Apple PPQ Signing marker OID (1.2.840.113635.100.6.38.2).
2720 Intermediate must have marker OID (1.2.840.113635.100.6.2.10).
2722 SecPolicyRef
SecPolicyCreateApplePPQSigning(void)
2724 SecPolicyRef result
= NULL
;
2725 CFMutableDictionaryRef options
= NULL
;
2726 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2727 &kCFTypeDictionaryKeyCallBacks
,
2728 &kCFTypeDictionaryValueCallBacks
), errOut
);
2729 SecPolicyAddBasicCertOptions(options
);
2731 SecPolicyAddAppleAnchorOptions(options
);
2732 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2734 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2735 CFSTR("Apple System Integration 2 Certification Authority"));
2737 // Check that leaf has extension with "Apple PPQ Signing" prod oid (1.2.840.113635.100.6.38.2)
2738 add_leaf_marker(options
, &oidAppleCertExtApplePPQSigningProd
);
2740 // Check that intermediate has extension (1.2.840.113635.100.6.2.10)
2741 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleSystemIntg2
);
2743 add_ku(options
, kSecKeyUsageDigitalSignature
);
2745 require(result
= SecPolicyCreate(kSecPolicyApplePPQSigning
, options
), errOut
);
2748 CFReleaseSafe(options
);
2753 @function SecPolicyCreateTestApplePPQSigning
2754 @abstract Check for intermediate certificate 'Apple System Integration 2 Certification Authority' by name,
2756 Leaf cert must have Digital Signature usage.
2757 Leaf cert must have Apple PPQ Signing Test marker OID (1.2.840.113635.100.6.38.1).
2758 Intermediate must have marker OID (1.2.840.113635.100.6.2.10).
2760 SecPolicyRef
SecPolicyCreateTestApplePPQSigning(void)
2762 SecPolicyRef result
= NULL
;
2763 CFMutableDictionaryRef options
= NULL
;
2764 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2765 &kCFTypeDictionaryKeyCallBacks
,
2766 &kCFTypeDictionaryValueCallBacks
), errOut
);
2767 SecPolicyAddBasicCertOptions(options
);
2769 SecPolicyAddAppleAnchorOptions(options
);
2770 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2772 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2773 CFSTR("Apple System Integration 2 Certification Authority"));
2775 // Check that leaf has extension with "Apple PPQ Signing" test oid (1.2.840.113635.100.6.38.1)
2776 add_leaf_marker(options
, &oidAppleCertExtApplePPQSigningTest
);
2778 // Check that intermediate has extension (1.2.840.113635.100.6.2.10)
2779 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleSystemIntg2
);
2781 add_ku(options
, kSecKeyUsageDigitalSignature
);
2783 require(result
= SecPolicyCreate(kSecPolicyAppleTestPPQSigning
, options
), errOut
);
2786 CFReleaseSafe(options
);
2790 @function SecPolicyCreateAppleTimeStamping
2791 @abstract Check for RFC3161 timestamping EKU.
2793 SecPolicyRef
SecPolicyCreateAppleTimeStamping(void)
2795 SecPolicyRef result
= NULL
;
2796 CFMutableDictionaryRef options
= NULL
;
2797 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2798 &kCFTypeDictionaryKeyCallBacks
,
2799 &kCFTypeDictionaryValueCallBacks
), errOut
);
2801 SecPolicyAddBasicX509Options(options
);
2803 /* Require id-kp-timeStamping extendedKeyUsage to be present. */
2804 add_eku(options
, &oidExtendedKeyUsageTimeStamping
);
2806 require(result
= SecPolicyCreate(kSecPolicyOIDAppleTimeStamping
, options
), errOut
);
2809 CFReleaseSafe(options
);
2814 @function SecPolicyCreateAppleATVAppSigning
2815 @abstract Check for intermediate certificate 'Apple Worldwide Developer Relations Certification Authority' by name,
2817 Leaf cert must have Digital Signature usage.
2818 Leaf cert must have Apple ATV App Signing marker OID (1.2.840.113635.100.6.1.24).
2819 Leaf cert must have 'Apple TVOS Application Signing' common name.
2821 SecPolicyRef
SecPolicyCreateAppleATVAppSigning(void)
2823 SecPolicyRef result
= NULL
;
2824 CFMutableDictionaryRef options
= NULL
;
2825 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2826 &kCFTypeDictionaryKeyCallBacks
,
2827 &kCFTypeDictionaryValueCallBacks
), errOut
);
2828 SecPolicyAddBasicCertOptions(options
);
2830 require(SecPolicyAddAppleAnchorOptions(options
), errOut
);
2831 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2833 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2834 CFSTR("Apple Worldwide Developer Relations Certification Authority"));
2835 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
,
2836 CFSTR("Apple TVOS Application Signing"));
2838 // Check that leaf has extension with "Apple ATV App Signing" prod oid (1.2.840.113635.100.6.1.24)
2839 add_leaf_marker(options
, &oidAppleCertExtATVAppSigningProd
);
2841 add_ku(options
, kSecKeyUsageDigitalSignature
);
2843 require(result
= SecPolicyCreate(kSecPolicyAppleATVAppSigning
, options
), errOut
);
2846 CFReleaseSafe(options
);
2851 @function SecPolicyCreateTestAppleATVAppSigning
2852 @abstract Check for intermediate certificate 'Apple Worldwide Developer Relations Certification Authority' by name,
2854 Leaf cert must have Digital Signature usage.
2855 Leaf cert must have Apple ATV App Signing Test marker OID (1.2.840.113635.100.6.1.24.1).
2856 Leaf cert must have 'TEST Apple TVOS Application Signing TEST' common name.
2858 SecPolicyRef
SecPolicyCreateTestAppleATVAppSigning(void)
2860 SecPolicyRef result
= NULL
;
2861 CFMutableDictionaryRef options
= NULL
;
2862 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2863 &kCFTypeDictionaryKeyCallBacks
,
2864 &kCFTypeDictionaryValueCallBacks
), errOut
);
2865 SecPolicyAddBasicCertOptions(options
);
2867 require(SecPolicyAddAppleAnchorOptions(options
), errOut
);
2868 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2870 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2871 CFSTR("Apple Worldwide Developer Relations Certification Authority"));
2872 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
,
2873 CFSTR("TEST Apple TVOS Application Signing TEST"));
2875 // Check that leaf has extension with "Apple ATV App Signing" test oid (1.2.840.113635.100.6.1.24.1)
2876 add_leaf_marker(options
, &oidAppleCertExtATVAppSigningTest
);
2878 add_ku(options
, kSecKeyUsageDigitalSignature
);
2880 require(result
= SecPolicyCreate(kSecPolicyAppleTestATVAppSigning
, options
), errOut
);
2883 CFReleaseSafe(options
);
2888 @function SecPolicyCreateApplePayIssuerEncryption
2889 @abstract Check for intermediate certificate 'Apple Worldwide Developer Relations CA - G2' by name,
2890 and ECC apple anchor.
2891 Leaf cert must have Key Encipherment and Key Agreement usage.
2892 Leaf cert must have Apple Pay Issuer Encryption marker OID (1.2.840.113635.100.6.39).
2894 SecPolicyRef
SecPolicyCreateApplePayIssuerEncryption(void)
2896 SecPolicyRef result
= NULL
;
2897 CFMutableDictionaryRef options
= NULL
;
2898 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2899 &kCFTypeDictionaryKeyCallBacks
,
2900 &kCFTypeDictionaryValueCallBacks
), errOut
);
2901 SecPolicyAddBasicCertOptions(options
);
2903 require(SecPolicyAddAnchorSHA1Options(options
, kAppleRootCA_ECC_SHA1
), errOut
);
2904 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2906 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2907 CFSTR("Apple Worldwide Developer Relations CA - G2"));
2909 // Check that leaf has extension with "Apple Pay Issuer Encryption" oid (1.2.840.113635.100.6.39)
2910 add_leaf_marker(options
, &oidAppleCertExtCryptoServicesExtEncryption
);
2912 add_ku(options
, kSecKeyUsageKeyEncipherment
);
2914 require(result
= SecPolicyCreate(kSecPolicyApplePayIssuerEncryption
, options
), errOut
);
2917 CFReleaseSafe(options
);