]> git.saurik.com Git - apple/security.git/blob - OSX/sec/Security/SecPolicy.c
Security-57337.40.85.tar.gz
[apple/security.git] / OSX / sec / Security / SecPolicy.c
1 /*
2 * Copyright (c) 2007-2015 Apple Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
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
11 * file.
12 *
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.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24 /*
25 * SecPolicy.c - Implementation of various X.509 certificate trust policies
26 */
27
28 #include <Security/SecPolicyInternal.h>
29 #include <Security/SecPolicyPriv.h>
30 #include <AssertMacros.h>
31 #include <pthread.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>
48 #else
49 #include <sys/utsname.h>
50 #endif
51
52 #include <utilities/SecInternalReleasePriv.h>
53
54 /********************************************************
55 **************** SecPolicy Constants *******************
56 ********************************************************/
57 // MARK: -
58 // MARK: SecPolicy Constants
59
60 #define SEC_CONST_DECL(k,v) const CFStringRef k = CFSTR(v);
61
62 /********************************************************
63 ************** Unverified Leaf Checks ******************
64 ********************************************************/
65 SEC_CONST_DECL (kSecPolicyCheckSSLHostname, "SSLHostname");
66 SEC_CONST_DECL (kSecPolicyCheckEmail, "email");
67
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");
71
72 /* Checks that the leaf has exactly one Common Name and that it
73 matches the specified string. */
74 SEC_CONST_DECL (kSecPolicyCheckSubjectCommonName, "SubjectCommonName");
75
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");
79
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");
83
84 /* Checks that the leaf has exactly one Organization and that it
85 matches the specified string. */
86 SEC_CONST_DECL (kSecPolicyCheckSubjectOrganization, "SubjectOrganization");
87
88 /* Checks that the leaf has exactly one Organizational Unit and that it
89 matches the specified string. */
90 SEC_CONST_DECL (kSecPolicyCheckSubjectOrganizationalUnit, "SubjectOrganizationalUnit");
91
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");
95
96 SEC_CONST_DECL (kSecPolicyCheckEAPTrustedServerNames, "EAPTrustedServerNames");
97
98 SEC_CONST_DECL (kSecPolicyCheckCertificatePolicy, "CertificatePolicy");
99
100 #if 0
101 /* Check for basic constraints on leaf to be valid. (rfc5280 check) */
102 SEC_CONST_DECL (kSecPolicyCheckLeafBasicConstraints, "LeafBasicContraints");
103 #endif
104
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")
113
114 /********************************************************
115 ************** Unverified Anchor Checks ****************
116 ********************************************************/
117 SEC_CONST_DECL (kSecPolicyCheckAnchorSHA1, "AnchorSHA1");
118
119 /* Fake key for isAnchored check. */
120 SEC_CONST_DECL (kSecPolicyCheckAnchorTrusted, "AnchorTrusted");
121
122 /* Anchor is one of the apple trust anchors */
123 SEC_CONST_DECL (kSecPolicyCheckAnchorApple, "AnchorApple");
124
125 /* options for kSecPolicyCheckAnchorApple */
126 SEC_CONST_DECL (kSecPolicyAppleAnchorIncludeTestRoots, "AnchorAppleTestRoots");
127 SEC_CONST_DECL (kSecPolicyAppleAnchorAllowTestRootsOnProduction, "AnchorAppleTestRootsOnProduction");
128
129 /********************************************************
130 *********** Unverified Certificate Checks **************
131 ********************************************************/
132 /* Unverified Certificate Checks (any of the above) */
133 SEC_CONST_DECL (kSecPolicyCheckNonEmptySubject, "NonEmptySubject");
134 SEC_CONST_DECL (kSecPolicyCheckIdLinkage, "IdLinkage") /* (rfc5280 check) */
135 #if 0
136 SEC_CONST_DECL (kSecPolicyCheckValidityStarted, "ValidStarted");
137 SEC_CONST_DECL (kSecPolicyCheckValidityExpired, "ValidExpired");
138 #else
139 SEC_CONST_DECL (kSecPolicyCheckValidIntermediates, "ValidIntermediates");
140 SEC_CONST_DECL (kSecPolicyCheckValidLeaf, "ValidLeaf");
141 SEC_CONST_DECL (kSecPolicyCheckValidRoot, "ValidRoot");
142 SEC_CONST_DECL (kSecPolicyCheckWeakIntermediates, "WeakIntermediates");
143 SEC_CONST_DECL (kSecPolicyCheckWeakLeaf, "WeakLeaf");
144 SEC_CONST_DECL (kSecPolicyCheckWeakRoot, "WeakRoot");
145 #endif
146
147
148 /********************************************************
149 **************** Verified Path Checks ******************
150 ********************************************************/
151 /* (rfc5280 check) Ideally we should dynamically track all the extensions
152 we processed for each certificate and fail this test if any critical
153 extensions remain. */
154 SEC_CONST_DECL (kSecPolicyCheckCriticalExtensions, "CriticalExtensions");
155
156 /* Check that the certificate chain length matches the specificed CFNumberRef
157 length. */
158 SEC_CONST_DECL (kSecPolicyCheckChainLength, "ChainLength");
159
160 /* (rfc5280 check) */
161 SEC_CONST_DECL (kSecPolicyCheckBasicCertificateProcessing, "BasicCertificateProcessing");
162
163 /********************************************************
164 ******************* Feature toggles ********************
165 ********************************************************/
166
167 /* Check revocation if specified. */
168 SEC_CONST_DECL (kSecPolicyCheckExtendedValidation, "ExtendedValidation");
169 SEC_CONST_DECL (kSecPolicyCheckRevocation, "Revocation");
170 SEC_CONST_DECL (kSecPolicyCheckRevocationResponseRequired, "RevocationResponseRequired");
171
172 /* Check Certificate Transparency if specified. */
173 SEC_CONST_DECL (kSecPolicyCheckCertificateTransparency, "CertificateTransparency");
174
175 /* If present and true, we never go out to the network for anything
176 (OCSP, CRL or CA Issuer checking) but just used cached data instead. */
177 SEC_CONST_DECL (kSecPolicyCheckNoNetworkAccess, "NoNetworkAccess");
178
179 /* Hack to quickly blacklist certain certs. */
180 SEC_CONST_DECL (kSecPolicyCheckBlackListedLeaf, "BlackListedLeaf");
181 SEC_CONST_DECL (kSecPolicyCheckGrayListedLeaf, "GrayListedLeaf");
182 SEC_CONST_DECL (kSecPolicyCheckGrayListedKey, "GrayListedKey");
183 SEC_CONST_DECL (kSecPolicyCheckBlackListedKey, "BlackListedKey");
184
185 SEC_CONST_DECL (kSecPolicyCheckLeafMarkerOid, "CheckLeafMarkerOid");
186 SEC_CONST_DECL (kSecPolicyCheckIntermediateMarkerOid, "CheckIntermediateMarkerOid");
187
188 /* Public policy names. */
189 SEC_CONST_DECL (kSecPolicyAppleX509Basic, "1.2.840.113635.100.1.2");
190 SEC_CONST_DECL (kSecPolicyAppleSSL, "1.2.840.113635.100.1.3");
191 SEC_CONST_DECL (kSecPolicyAppleSMIME, "1.2.840.113635.100.1.8");
192 SEC_CONST_DECL (kSecPolicyAppleEAP, "1.2.840.113635.100.1.9");
193 SEC_CONST_DECL (kSecPolicyAppleSWUpdateSigning, "1.2.840.113635.100.1.10");
194 SEC_CONST_DECL (kSecPolicyAppleIPsec, "1.2.840.113635.100.1.11");
195 SEC_CONST_DECL (kSecPolicyApplePKINITClient, "1.2.840.113635.100.1.14");
196 SEC_CONST_DECL (kSecPolicyApplePKINITServer, "1.2.840.113635.100.1.15");
197 SEC_CONST_DECL (kSecPolicyAppleCodeSigning, "1.2.840.113635.100.1.16");
198 SEC_CONST_DECL (kSecPolicyApplePackageSigning, "1.2.840.113635.100.1.17");
199 SEC_CONST_DECL (kSecPolicyAppleIDValidation, "1.2.840.113635.100.1.18");
200 SEC_CONST_DECL (kSecPolicyMacAppStoreReceipt, "1.2.840.113635.100.1.19");
201 SEC_CONST_DECL (kSecPolicyAppleTimeStamping, "1.2.840.113635.100.1.20");
202 SEC_CONST_DECL (kSecPolicyAppleRevocation, "1.2.840.113635.100.1.21");
203 SEC_CONST_DECL (kSecPolicyApplePassbookSigning, "1.2.840.113635.100.1.22");
204 SEC_CONST_DECL (kSecPolicyAppleMobileStore, "1.2.840.113635.100.1.23");
205 SEC_CONST_DECL (kSecPolicyAppleEscrowService, "1.2.840.113635.100.1.24");
206 SEC_CONST_DECL (kSecPolicyAppleProfileSigner, "1.2.840.113635.100.1.25");
207 SEC_CONST_DECL (kSecPolicyAppleQAProfileSigner, "1.2.840.113635.100.1.26");
208 SEC_CONST_DECL (kSecPolicyAppleTestMobileStore, "1.2.840.113635.100.1.27");
209 SEC_CONST_DECL (kSecPolicyAppleOTAPKISigner, "1.2.840.113635.100.1.28");
210 SEC_CONST_DECL (kSecPolicyAppleTestOTAPKISigner, "1.2.840.113635.100.1.29");
211 /* FIXME: this policy name should be deprecated and replaced with "kSecPolicyAppleIDValidationRecordSigning" */
212 SEC_CONST_DECL (kSecPolicyAppleIDValidationRecordSigningPolicy, "1.2.840.113625.100.1.30");
213 SEC_CONST_DECL (kSecPolicyAppleSMPEncryption, "1.2.840.113625.100.1.31");
214 SEC_CONST_DECL (kSecPolicyAppleTestSMPEncryption, "1.2.840.113625.100.1.32");
215 SEC_CONST_DECL (kSecPolicyAppleServerAuthentication, "1.2.840.113635.100.1.33");
216 SEC_CONST_DECL (kSecPolicyApplePCSEscrowService, "1.2.840.113635.100.1.34");
217 SEC_CONST_DECL (kSecPolicyApplePPQSigning, "1.2.840.113625.100.1.35");
218 SEC_CONST_DECL (kSecPolicyAppleTestPPQSigning, "1.2.840.113625.100.1.36");
219 SEC_CONST_DECL (kSecPolicyAppleATVAppSigning, "1.2.840.113625.100.1.37");
220 SEC_CONST_DECL (kSecPolicyAppleTestATVAppSigning, "1.2.840.113625.100.1.38");
221 SEC_CONST_DECL (kSecPolicyApplePayIssuerEncryption, "1.2.840.113625.100.1.39");
222 SEC_CONST_DECL (kSecPolicyAppleOSXProvisioningProfileSigning, "1.2.840.113625.100.1.40");
223 SEC_CONST_DECL (kSecPolicyAppleATVVPNProfileSigning, "1.2.840.113625.100.1.41");
224 SEC_CONST_DECL (kSecPolicyAppleAST2DiagnosticsServerAuth, "1.2.840.113625.100.1.42");
225
226 SEC_CONST_DECL (kSecPolicyOid, "SecPolicyOid");
227 SEC_CONST_DECL (kSecPolicyName, "SecPolicyName");
228 SEC_CONST_DECL (kSecPolicyClient, "SecPolicyClient");
229 SEC_CONST_DECL (kSecPolicyRevocationFlags, "SecPolicyRevocationFlags");
230 SEC_CONST_DECL (kSecPolicyTeamIdentifier, "SecPolicyTeamIdentifier");
231
232 /* Private policy names */
233 static CFStringRef kSecPolicyOIDBasicX509 = CFSTR("basicX509");
234 static CFStringRef kSecPolicyOIDSSLServer = CFSTR("sslServer");
235 static CFStringRef kSecPolicyOIDSSLClient = CFSTR("sslClient");
236 static CFStringRef kSecPolicyOIDiPhoneActivation = CFSTR("iPhoneActivation");
237 static CFStringRef kSecPolicyOIDiPhoneDeviceCertificate =
238 CFSTR("iPhoneDeviceCertificate");
239 static CFStringRef kSecPolicyOIDFactoryDeviceCertificate =
240 CFSTR("FactoryDeviceCertificate");
241 static CFStringRef kSecPolicyOIDiAP = CFSTR("iAP");
242 static CFStringRef kSecPolicyOIDiTunesStoreURLBag = CFSTR("iTunesStoreURLBag");
243 static CFStringRef kSecPolicyOIDEAPServer = CFSTR("eapServer");
244 static CFStringRef kSecPolicyOIDEAPClient = CFSTR("eapClient");
245 static CFStringRef kSecPolicyOIDIPSecServer = CFSTR("ipsecServer");
246 static CFStringRef kSecPolicyOIDIPSecClient = CFSTR("ipsecClient");
247 static CFStringRef kSecPolicyOIDiPhoneApplicationSigning =
248 CFSTR("iPhoneApplicationSigning");
249 static CFStringRef kSecPolicyOIDiPhoneProfileApplicationSigning =
250 CFSTR("iPhoneProfileApplicationSigning");
251 static CFStringRef kSecPolicyOIDiPhoneProvisioningProfileSigning =
252 CFSTR("iPhoneProvisioningProfileSigning");
253 static CFStringRef kSecPolicyOIDAppleSWUpdateSigning = CFSTR("AppleSWUpdateSigning");
254 static CFStringRef kSecPolicyOIDAppleTVOSApplicationSigning =
255 CFSTR("AppleTVApplicationSigning");
256 static CFStringRef kSecPolicyOIDRevocation = CFSTR("revocation");
257 static CFStringRef kSecPolicyOIDOCSPSigner = CFSTR("OCSPSigner");
258 static CFStringRef kSecPolicyOIDSMIME = CFSTR("SMIME");
259 static CFStringRef kSecPolicyOIDCodeSigning = CFSTR("CodeSigning");
260 static CFStringRef kSecPolicyOIDPackageSigning = CFSTR("PackageSigning");
261 static CFStringRef kSecPolicyOIDLockdownPairing = CFSTR("LockdownPairing");
262 static CFStringRef kSecPolicyOIDURLBag = CFSTR("URLBag");
263 static CFStringRef kSecPolicyOIDOTATasking = CFSTR("OTATasking");
264 static CFStringRef kSecPolicyOIDMobileAsset = CFSTR("MobileAsset");
265 static CFStringRef kSecPolicyOIDAppleIDAuthority = CFSTR("AppleIDAuthority");
266 static CFStringRef kSecPolicyOIDMacAppStoreReceipt = CFSTR("MacAppStoreReceipt");
267 static CFStringRef kSecPolicyOIDAppleTimeStamping = CFSTR("AppleTimeStamping");
268 static CFStringRef kSecPolicyOIDApplePassbook = CFSTR("ApplePassbook");
269 static CFStringRef kSecPolicyOIDAppleMobileStore = CFSTR("AppleMobileStore");
270 static CFStringRef kSecPolicyOIDAppleTestMobileStore = CFSTR("AppleTestMobileStore");
271 static CFStringRef kSecPolicyOIDAppleEscrowService = CFSTR("AppleEscrowService");
272 static CFStringRef kSecPolicyOIDApplePCSEscrowService = CFSTR("ApplePCSEscrowService");
273 static CFStringRef kSecPolicyOIDAppleProfileSigner = CFSTR("AppleProfileSigner");
274 static CFStringRef kSecPolicyOIDAppleQAProfileSigner = CFSTR("AppleQAProfileSigner");
275 static CFStringRef kSecPolicyOIDAppleOTAPKIAssetSigner = CFSTR("AppleOTAPKIAssetSigner");
276 static CFStringRef kSecPolicyOIDAppleTestOTAPKIAssetSigner = CFSTR("AppleTestOTAPKIAssetSigner");
277 static CFStringRef kSecPolicyOIDAppleIDValidationRecordSigningPolicy = CFSTR("AppleIDValidationRecordSigningPolicy");
278 #if TARGET_OS_EMBEDDED
279 static CFStringRef kSecPolicyOIDAppleATVAppSigning = CFSTR("AppleATVAppSigning");
280 static CFStringRef kSecPolicyOIDAppleTestATVAppSigning = CFSTR("AppleTestATVAppSigning");
281 #endif
282 static CFStringRef kSecPolicyOIDApplePayIssuerEncryption = CFSTR("ApplePayIssuerEncryption");
283 static CFStringRef kSecPolicyOIDAppleOSXProvisioningProfileSigning = CFSTR("AppleOSXProvisioningProfileSigning");
284 static CFStringRef kSecPolicyOIDAppleATVVPNProfileSigning = CFSTR("AppleATVVPNProfileSigning");
285 static CFStringRef kSecPolicyOIDAppleAST2Service = CFSTR("AST2Service");
286
287 /* Policies will now change to multiple categories of checks.
288
289 IDEA Store partial valid policy tree in each chain? Result tree pruning might make this not feasible unless you can pretend to prune the tree without actually deleting nodes and somehow still have shable nodes with parent chains (this assumes that chains will be built as cached things from the root down), and we can build something equivalent to rfc5280 in a tree of certs. So we need to maintain a cache of leaf->chain with this certificate as any_ca_cert->tree. Revocation status caching can be done in this cache as well, so maybe the cache should be in sqlite3, or at least written there before exit and querying of the cache could be done first on the in core (possibly CF or custom tree like structure) and secondarly on the sqlite3 backed store. We should choose the lowest memory footprint solution in my mind, while choosing a sqlite3 cache size that gives us a resonable io usage pattern.
290 NOTE no certificate can be an intermediate unless it is X.509V3 and it has a basicConstraints extension with isCA set to true. This can be used to classify certs for caching purposes.
291
292 kSecPolicySLCheck Static Subscriber Certificate Checks
293 kSecPolicySICheck Static Subsidiary CA Checks
294 kSecPolicySACheck Static Anchor Checks
295
296 kSecPolicyDLCheck Dynamic Subscriber Certificate Checks
297 kSecPolicyDICheck Dynamic Subsidiary CA Checks
298 kSecPolicyDACheck Dynamic Anchor Checks ? not yet needed other than to
299 possibly exclude in a exception template (but those should still be per
300 certificate --- i.o.w. exceptions (or a database backed multiple role/user
301 trust store of some sort) and policies are 2 different things and this
302 text is about policies.
303
304 All static checks are only allowed to consider the certificate in isolation,
305 just given the position in the chain or the cert (leaf, intermidate, root).
306 dynamic checks can make determinations about the chain as a whole.
307
308 Static Subscriber Certificate Checks will be done up front before the
309 chainbuilder is even instantiated. If they fail and details aren't required
310 by the client (if no exceptions were present for this certificate) we could
311 short circuit fail the evaluation.
312 IDEA: These checks can dynamically add new checks...[needs work]
313 ALTERNATIVE: A policy can have one or more sub-policies. Each sub-policy will be evaluated only after the parent policy succeeds. Subpolicies can be either required (making the parent policy fail) or optional making the parent policy succeed, but allowing the chainbuilder to continue building chains after an optional subpolicy failure in search of a chain for which the subpolicy also succeeded. Subpolicies can be dynamically added to the policy evaluation context tree (a tree with a node for every node in the certificate path. This tree however is from the leaf up stored in the SecCertificatePathRef objects themselves possibly - requiring a separate shared subtree of nodes for the underlying certificate state tree.) by a parent policy at any stage, since the subpolicy evaluation only starts after
314 will have a key in the info (or even details and make info client side generated from info to indicate the success or failure of optional subpolicies) tree the value of which is an
315 equivalent subtree from that level down. So SSL has EV as a subpolicy, but
316 EV dynamically enables the ocsp or crl or dcrl or any combination thereof subpolicies.
317
318 Static Subsidiary CA Checks will be used by the chain-builder to choose the
319 best parents to evaluate first. This feature is currently already implemented
320 but with a hardcoded is_valid(verifyTime) check. Instead we will evaluate all
321 Static Subsidiary CA Checks. The results of these checks for purposes of
322 generating details could be cached in the SecCertificatePathRefs themselves, or we can short circuit fail and recalc details on demand later.
323
324 Static Anchor Checks can do things like populate the chainbuilder level context value of the initial_valid_policy_tree with a particular anchors list of ev policies it represents or modify inputs to the policy itself.
325
326 Dynamic Subscriber Certificate Checks These can do things like check for EV policy conformance based on the valid_policy_tree at the end of the certificate evaluation, or based on things like the pathlen, etc. in the chain validation context.
327
328 Dynamic Subsidiary CA Checks might not be needed to have custom
329 implementations, since they are all done as part of the rfc5280 checks now.
330 This assumes that checks like issuer common name includes 'foo' are
331 implmented as Static Subscriber Certificate Checks instead.
332
333 Dynamic Anchor Checks might include EV type checks or chain validation context seeding as well, allthough we might be able to do them as static checks to seed the chain validation context instead.
334
335
336 Questions/Notes: Do we need to dynamically add new policies? If policy static checks fail and policy is optional we don't even run policy dynamic checks nor do we compute subpolicy values. So if the static check of the leaf for EV fails we skip the rest of the EV style checks and instead don't run the revocation subpolicy of the ev policy.
337
338 If an optional subpolicy s_p has a required subpolicy r_s_p. Then success of s_p will cause the entire chain evaluation to fail if r_s_p fails.
339
340 All policies static revocation checks are run at the appropriate phase in the evaluation. static leaf checks are done before chainbuilding even starts. static intermediate checks are done in the chainbuilder for each cadidate parent certificate. If all policies pass we check the signatures. We reject the whole chain if that step fails. Otherwise we add the path to builder->candidatePaths. If the top level policy or a required subpolicy or a required subpolicy of a successful subpolicy fails we stick the chain at the end of the expiredPaths, if one of the optional subpolicies fail, we stick the chain at the start of expiredPaths so it's considered first after all real candidatePaths have been processed.
341
342 Static revocation policy checks could check the passed in ocspresponses or even the local cache, though the latter is probably best left for the dynamic phase.
343
344 The same rules that apply above to the adding paths to candidatePaths v/s expiredPaths apply to dynamicpolicy checks, except that we don't remember failures anymore, we reject them.
345
346 We need to remember the best successful chain we find, where best is defined by: satisfies as many optional policies as possible.
347
348 Chain building ends when either we find a chain that matches all optional and required policies, or we run out of chains to build. Another case is if we run out of candiate paths but we already have a chain that matches at least the top level and required subpolicies. In that case we don't even consider any expiredPaths. Example: we find a valid SSL chain (top level policy), but no partial chain we constructed satisfied the static checks of the ev subpolicy, or the required revocation sub-subpolicy of the ev policy.
349
350 In order for this to work well with exceptions on subpolicies, we'd need to move the validation of exceptions to the server, something we'd do anyway if we had full on truststore. In this case exceptions would be live in the failure callback for a trust check.
351
352 Example sectrust operation in psuedocode:
353 */
354 /*
355 {
356 new builder(verifyTime, certificates, anchors, anchorsOnly, policies);
357 chain = builder.subscriber_only_chain;
358 foreach (policy in policies{kSecPolicySLCheck}) {
359 foreach(check in policy)
360 SecPolicyRunCheck(builder, chain, check, details);
361 foreach (subpolicy in policy) {
362 check_policy(builder, chain, subpolicy, details{subpolicy.name})
363 }
364 propagate_subpolicy_results(builder, chain, details);
365 }
366 while (chain = builder.next) {
367 for (depth = 0; p_d = policies.at_depth(depth),
368 d_p_d = dynamic_policies.at_depth(depth), p_d || d_p_d; ++depth)
369 {
370 // Modify SecPathBuilderIsPartial() to
371 // run builder_check(buildier, policies, kSecPolicySICheck) instead
372 // of SecCertificateIsValid. Also rename considerExpired to
373 // considerSIFailures.
374 foreach (policy in p_d) {
375 check_policy(builder, chain, policy, kSecPolicySICheck, depth);
376 }
377 /// Recalculate since the static checks might have added new dynamic
378 // policies.
379 d_p_d = dynamic_policies.at_depth(depth);
380 foreach (policy in d_p_d) {
381 check_policy(builder, chain, policy, kSecPolicySICheck, depth);
382 }
383 if (chain.is_anchored) {
384 foreach (policy in p_d) {
385 check_policy(builder, chain, policy, kSecPolicySACheck, depth);
386 }
387 foreach (policy in d_p_d) {
388 check_policy(builder, chain, policy, kSecPolicySACheck, depth);
389 }
390 foreach (policy in p_d) {
391 check_policy(builder, chain, policy, kSecPolicyDACheck, depth);
392 }
393 foreach (policy in d_p_d) {
394 check_policy(builder, chain, policy, kSecPolicyDACheck, depth);
395 }
396 }
397 foreach (policy in policies) {
398 check_policy(builder, chain, policy, kSecPolicySACheck, depth);
399 check_policy(builder, chain, policy, kSecPolicyDACheck, depth);
400 }
401 foreach (policy in policies{kSecPolicySDCheck}) {
402 }
403 }
404 }
405
406 check_policy(builder, chain, policy, check_class, details, depth) {
407 if (depth == 0) {
408 foreach(check in policy{check_class}) {
409 SecPolicyRunCheck(builder, chain, check, details);
410 }
411 } else {
412 depth--;
413 foreach (subpolicy in policy) {
414 if (!check_policy(builder, chain, subpolicy, check_class,
415 details{subpolicy.name}) && subpolicy.is_required, depth)
416 secpvcsetresult()
417 }
418 }
419 propagate_subpolicy_results(builder, chain, details);
420 }
421
422 */
423
424
425
426 #define kSecPolicySHA1Size 20
427 #define kSecPolicySHA256Size 32
428 const UInt8 kAppleCASHA1[kSecPolicySHA1Size] = {
429 0x61, 0x1E, 0x5B, 0x66, 0x2C, 0x59, 0x3A, 0x08, 0xFF, 0x58,
430 0xD1, 0x4A, 0xE2, 0x24, 0x52, 0xD1, 0x98, 0xDF, 0x6C, 0x60
431 };
432
433 __unused static const UInt8 kAppleTESTCASHA1[kSecPolicySHA1Size] = {
434 0xbc, 0x30, 0x55, 0xc8, 0xc8, 0xd3, 0x48, 0x3f, 0xf4, 0x8d,
435 0xfe, 0x3d, 0x51, 0x75, 0x31, 0xc9, 0xf4, 0xd7, 0x4a, 0xf7
436 };
437
438 static const UInt8 kITMSCASHA1[kSecPolicySHA1Size] = {
439 0x1D, 0x33, 0x42, 0x46, 0x8B, 0x10, 0xBD, 0xE6, 0x45, 0xCE,
440 0x44, 0x6E, 0xBB, 0xE8, 0xF5, 0x03, 0x5D, 0xF8, 0x32, 0x22
441 };
442
443 static const UInt8 kFactoryDeviceCASHA1[kSecPolicySHA1Size] = {
444 0xef, 0x68, 0x73, 0x17, 0xa4, 0xf8, 0xf9, 0x4b, 0x7b, 0x21,
445 0xe2, 0x2f, 0x09, 0x8f, 0xfd, 0x6a, 0xae, 0xc0, 0x0d, 0x63
446 };
447
448 static const UInt8 kApplePKISettingsAuthority[kSecPolicySHA1Size] = {
449 0x1D, 0x0C, 0xBA, 0xAD, 0x17, 0xFD, 0x7E, 0x9E, 0x9F, 0xF1,
450 0xC9, 0xA2, 0x66, 0x79, 0x60, 0x00, 0x8B, 0xAE, 0x70, 0xB8
451 };
452
453 static const UInt8 kAppleTestPKISettingsAuthority[kSecPolicySHA1Size] = {
454 0xDB, 0xBA, 0x25, 0x0B, 0xD8, 0x62, 0x71, 0x87, 0x54, 0x7E,
455 0xD7, 0xEF, 0x11, 0x94, 0x7E, 0x82, 0xE6, 0xD8, 0x1C, 0x9A
456 };
457
458 static const UInt8 kTestAppleRootCA_ECC_SHA1[kSecPolicySHA1Size] = {
459 0x62, 0x0A, 0xED, 0x83, 0xD2, 0x97, 0x4A, 0x77, 0x56, 0x33,
460 0x83, 0xBE, 0xDB, 0xF9, 0xA1, 0xBD, 0x5F, 0xFE, 0x55, 0x7B
461 };
462
463 static const UInt8 kAppleRootCA_ECC_SHA1[kSecPolicySHA1Size] = {
464 0xB5, 0x2C, 0xB0, 0x2F, 0xD5, 0x67, 0xE0, 0x35, 0x9F, 0xE8,
465 0xFA, 0x4D, 0x4C, 0x41, 0x03, 0x79, 0x70, 0xFE, 0x01, 0xB0
466 };
467
468 // MARK: -
469 // MARK: SecPolicy
470 /********************************************************
471 ****************** SecPolicy object ********************
472 ********************************************************/
473
474 static void SecPolicyDestroy(CFTypeRef cf) {
475 SecPolicyRef policy = (SecPolicyRef) cf;
476 CFRelease(policy->_oid);
477 CFRelease(policy->_options);
478 }
479
480 static Boolean SecPolicyCompare(CFTypeRef cf1, CFTypeRef cf2) {
481 SecPolicyRef policy1 = (SecPolicyRef) cf1;
482 SecPolicyRef policy2 = (SecPolicyRef) cf2;
483 return CFEqual(policy1->_oid, policy2->_oid) &&
484 CFEqual(policy1->_options, policy2->_options);
485 }
486
487 static CFHashCode SecPolicyHash(CFTypeRef cf) {
488 SecPolicyRef policy = (SecPolicyRef) cf;
489
490 return CFHash(policy->_oid) + CFHash(policy->_options);
491 }
492
493 static CFStringRef SecPolicyCopyFormatDescription(CFTypeRef cf, CFDictionaryRef formatOptions) {
494 SecPolicyRef policy = (SecPolicyRef) cf;
495 CFMutableStringRef desc = CFStringCreateMutable(kCFAllocatorDefault, 0);
496 CFStringRef typeStr = CFCopyTypeIDDescription(CFGetTypeID(cf));
497 CFStringAppendFormat(desc, NULL,
498 CFSTR("<%@: oid: %@ options %@"), typeStr,
499 policy->_oid, policy->_options);
500 CFRelease(typeStr);
501 CFStringAppend(desc, CFSTR(" >"));
502
503 return desc;
504 }
505
506 /* SecPolicy API functions. */
507 CFGiblisWithHashFor(SecPolicy);
508
509 /* AUDIT[securityd](done):
510 oid (ok) is a caller provided string, only its cf type has been checked.
511 options is a caller provided dictionary, only its cf type has been checked.
512 */
513 SecPolicyRef SecPolicyCreate(CFStringRef oid, CFDictionaryRef options) {
514 SecPolicyRef result = NULL;
515
516 require(oid, errOut);
517 require(options, errOut);
518 require(result =
519 (SecPolicyRef)_CFRuntimeCreateInstance(kCFAllocatorDefault,
520 SecPolicyGetTypeID(),
521 sizeof(struct __SecPolicy) - sizeof(CFRuntimeBase), 0), errOut);
522
523 CFRetain(oid);
524 result->_oid = oid;
525 CFRetain(options);
526 result->_options = options;
527
528 errOut:
529 return result;
530 }
531
532 SecPolicyRef SecPolicyCreateWithProperties(CFTypeRef policyIdentifier,
533 CFDictionaryRef properties) {
534 // Creates a policy reference for a given policy object identifier.
535 // If policy-specific parameters can be supplied (e.g. hostname),
536 // attempt to obtain from input properties dictionary.
537 // Returns NULL if the given identifier is unsupported.
538
539 SecPolicyRef policy = NULL;
540 CFStringRef name = NULL;
541 CFStringRef teamID = NULL;
542 Boolean client = false;
543 require(policyIdentifier && (CFStringGetTypeID() == CFGetTypeID(policyIdentifier)), errOut);
544
545 if (properties) {
546 name = CFDictionaryGetValue(properties, kSecPolicyName);
547 teamID = CFDictionaryGetValue(properties, kSecPolicyTeamIdentifier);
548
549 CFBooleanRef dictionaryClientValue;
550 client = (CFDictionaryGetValueIfPresent(properties, kSecPolicyClient, (const void **)&dictionaryClientValue) &&
551 (dictionaryClientValue != NULL) && CFEqual(kCFBooleanTrue, dictionaryClientValue));
552 }
553
554 if (CFEqual(policyIdentifier, kSecPolicyAppleX509Basic)) {
555 policy = SecPolicyCreateBasicX509();
556 }
557 else if (CFEqual(policyIdentifier, kSecPolicyAppleSSL)) {
558 policy = SecPolicyCreateSSL(!client, name);
559 }
560 else if (CFEqual(policyIdentifier, kSecPolicyAppleEAP)) {
561 CFArrayRef array = NULL;
562 if (name) {
563 array = CFArrayCreate(kCFAllocatorDefault, (const void **)&name, 1, &kCFTypeArrayCallBacks);
564 }
565 policy = SecPolicyCreateEAP(!client, array);
566 CFReleaseSafe(array);
567 }
568 else if (CFEqual(policyIdentifier, kSecPolicyApplePackageSigning)) {
569 policy = SecPolicyCreateApplePackageSigning();
570 }
571 else if (CFEqual(policyIdentifier, kSecPolicyAppleSWUpdateSigning)) {
572 policy = SecPolicyCreateAppleSWUpdateSigning();
573 }
574 else if (CFEqual(policyIdentifier, kSecPolicyAppleIPsec)) {
575 policy = SecPolicyCreateIPSec(!client, name);
576 }
577 else if (CFEqual(policyIdentifier, kSecPolicyAppleRevocation)) {
578 policy = SecPolicyCreateRevocation(kSecRevocationUseAnyAvailableMethod);
579 }
580 else if (CFEqual(policyIdentifier, kSecPolicyAppleSMIME)) {
581 policy = SecPolicyCreateSMIME(kSecSignSMIMEUsage | kSecAnyEncryptSMIME, name);
582 }
583 else if (CFEqual(policyIdentifier, kSecPolicyAppleCodeSigning)) {
584 policy = SecPolicyCreateCodeSigning();
585 }
586 else if (CFEqual(policyIdentifier, kSecPolicyAppleTimeStamping)) {
587 policy = SecPolicyCreateAppleTimeStamping();
588 }
589 else if (CFEqual(policyIdentifier, kSecPolicyMacAppStoreReceipt)) {
590 policy = SecPolicyCreateMacAppStoreReceipt();
591 }
592 else if (CFEqual(policyIdentifier, kSecPolicyAppleIDValidation)) {
593 policy = SecPolicyCreateAppleIDAuthorityPolicy();
594 }
595 else if (CFEqual(policyIdentifier, kSecPolicyApplePassbookSigning)) {
596 policy = SecPolicyCreatePassbookCardSigner(name, teamID);
597 }
598 else if (CFEqual(policyIdentifier, kSecPolicyAppleMobileStore)) {
599 policy = SecPolicyCreateMobileStoreSigner();
600 }
601 else if (CFEqual(policyIdentifier, kSecPolicyAppleTestMobileStore)) {
602 policy = SecPolicyCreateTestMobileStoreSigner();
603 }
604 else if (CFEqual(policyIdentifier, kSecPolicyAppleEscrowService)) {
605 policy = SecPolicyCreateEscrowServiceSigner();
606 }
607 else if (CFEqual(policyIdentifier, kSecPolicyApplePCSEscrowService)) {
608 policy = SecPolicyCreatePCSEscrowServiceSigner();
609 }
610 else if (CFEqual(policyIdentifier, kSecPolicyAppleProfileSigner)) {
611 policy = SecPolicyCreateConfigurationProfileSigner();
612 }
613 else if (CFEqual(policyIdentifier, kSecPolicyAppleQAProfileSigner)) {
614 policy = SecPolicyCreateQAConfigurationProfileSigner();
615 }
616 else if (CFEqual(policyIdentifier, kSecPolicyAppleServerAuthentication)) {
617 policy = SecPolicyCreateAppleSSLService(name);
618 }
619 #if TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR
620 else if (CFEqual(policyIdentifier, kSecPolicyAppleOTAPKISigner)) {
621 policy = SecPolicyCreateOTAPKISigner();
622 }
623 else if (CFEqual(policyIdentifier, kSecPolicyAppleTestOTAPKISigner)) {
624 policy = SecPolicyCreateTestOTAPKISigner();
625 }
626 else if (CFEqual(policyIdentifier, kSecPolicyAppleIDValidationRecordSigningPolicy)) {
627 policy = SecPolicyCreateAppleIDValidationRecordSigningPolicy();
628 }
629 else if (CFEqual(policyIdentifier, kSecPolicyAppleSMPEncryption)) {
630 policy = SecPolicyCreateAppleSMPEncryption();
631 }
632 else if (CFEqual(policyIdentifier, kSecPolicyAppleTestSMPEncryption)) {
633 policy = SecPolicyCreateTestAppleSMPEncryption();
634 }
635 else if (CFEqual(policyIdentifier, kSecPolicyAppleATVAppSigning)) {
636 policy = SecPolicyCreateAppleATVAppSigning();
637 }
638 else if (CFEqual(policyIdentifier, kSecPolicyAppleTestATVAppSigning)) {
639 policy = SecPolicyCreateTestAppleATVAppSigning();
640 }
641 #endif
642 else if (CFEqual(policyIdentifier, kSecPolicyApplePPQSigning)) {
643 policy = SecPolicyCreateApplePPQSigning();
644 }
645 else if (CFEqual(policyIdentifier, kSecPolicyAppleTestPPQSigning)) {
646 policy = SecPolicyCreateTestApplePPQSigning();
647 }
648 else if (CFEqual(policyIdentifier, kSecPolicyApplePayIssuerEncryption)) {
649 policy = SecPolicyCreateApplePayIssuerEncryption();
650 }
651 else if (CFEqual(policyIdentifier, kSecPolicyAppleATVVPNProfileSigning)) {
652 policy = SecPolicyCreateAppleATVVPNProfileSigning();
653 }
654 else if (CFEqual(policyIdentifier, kSecPolicyAppleAST2DiagnosticsServerAuth)) {
655 policy = SecPolicyCreateAppleAST2Service(name, NULL);
656 }
657 else {
658 secerror("ERROR: policy \"%@\" is unsupported", policyIdentifier);
659 }
660
661 errOut:
662 return policy;
663 }
664
665 CFDictionaryRef SecPolicyCopyProperties(SecPolicyRef policyRef) {
666 // Builds and returns a dictionary which the caller must release.
667
668 #pragma clang diagnostic push
669 #pragma clang diagnostic ignored "-Wnonnull"
670 // After introducing nullability annotations, policyRef is supposed to be nonnull, suppress the warning
671 if (!policyRef) return NULL;
672 #pragma clang diagnostic pop
673 CFMutableDictionaryRef properties = CFDictionaryCreateMutable(NULL, 0,
674 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
675 #pragma clang diagnostic push
676 #pragma clang diagnostic ignored "-Wnonnull"
677 // 'properties' is nonnull in reality suppress the warning
678 if (!properties) return NULL;
679 #pragma clang diagnostic pop
680 CFStringRef oid = (CFStringRef) CFRetain(policyRef->_oid);
681 CFTypeRef nameKey = NULL;
682
683 // Convert private to public OID if we have one
684 CFStringRef outOid = oid;
685 if (CFEqual(oid, kSecPolicyOIDBasicX509)) {
686 outOid = kSecPolicyAppleX509Basic;
687 }
688 else if (CFEqual(oid, kSecPolicyOIDSSLServer) ||
689 CFEqual(oid, kSecPolicyOIDSSLClient)) {
690 outOid = kSecPolicyAppleSSL;
691 nameKey = kSecPolicyCheckSSLHostname;
692 }
693 else if (CFEqual(oid, kSecPolicyOIDEAPServer) ||
694 CFEqual(oid, kSecPolicyOIDEAPClient)) {
695 outOid = kSecPolicyAppleEAP;
696 nameKey = kSecPolicyCheckEAPTrustedServerNames;
697 }
698 else if (CFEqual(oid, kSecPolicyOIDIPSecServer) ||
699 CFEqual(oid, kSecPolicyOIDIPSecClient)) {
700 outOid = kSecPolicyAppleIPsec;
701 nameKey = kSecPolicyCheckSSLHostname;
702 }
703 else if (CFEqual(oid, kSecPolicyOIDRevocation)) {
704 outOid = kSecPolicyAppleRevocation;
705 }
706 else if (CFEqual(oid, kSecPolicyOIDSMIME)) {
707 outOid = kSecPolicyAppleSMIME;
708 nameKey = kSecPolicyCheckEmail;
709 }
710 else if (CFEqual(oid, kSecPolicyOIDCodeSigning)) {
711 outOid = kSecPolicyAppleCodeSigning;
712 }
713 else if (CFEqual(oid, kSecPolicyOIDAppleIDAuthority)) {
714 outOid = kSecPolicyAppleIDValidation;
715 }
716 else if (CFEqual(oid, kSecPolicyOIDApplePassbook)) {
717 outOid = kSecPolicyApplePassbookSigning;
718 }
719 else if (CFEqual(oid, kSecPolicyOIDAppleMobileStore)) {
720 outOid = kSecPolicyAppleMobileStore;
721 }
722 else if (CFEqual(oid, kSecPolicyOIDAppleTestMobileStore)) {
723 outOid = kSecPolicyAppleTestMobileStore;
724 }
725 else if (CFEqual(oid, kSecPolicyOIDAppleEscrowService)) {
726 outOid = kSecPolicyAppleEscrowService;
727 }
728 else if (CFEqual(oid, kSecPolicyOIDApplePCSEscrowService)) {
729 outOid = kSecPolicyApplePCSEscrowService;
730 }
731 else if (CFEqual(oid, kSecPolicyOIDAppleProfileSigner)) {
732 outOid = kSecPolicyAppleProfileSigner;
733 }
734 else if (CFEqual(oid, kSecPolicyOIDAppleQAProfileSigner)) {
735 outOid = kSecPolicyAppleQAProfileSigner;
736 }
737 #if TARGET_OS_EMBEDDED
738 else if (CFEqual(oid, kSecPolicyOIDAppleOTAPKIAssetSigner)) {
739 outOid = kSecPolicyAppleOTAPKISigner;
740 }
741 else if (CFEqual(oid, kSecPolicyOIDAppleTestOTAPKIAssetSigner)) {
742 outOid = kSecPolicyAppleTestOTAPKISigner;
743 }
744 else if (CFEqual(oid, kSecPolicyOIDAppleIDValidationRecordSigningPolicy)) {
745 outOid = kSecPolicyAppleIDValidationRecordSigningPolicy;
746 }
747 else if (CFEqual(oid, kSecPolicyOIDAppleATVAppSigning)) {
748 outOid = kSecPolicyAppleATVAppSigning;
749 }
750 else if (CFEqual(oid, kSecPolicyOIDAppleTestATVAppSigning)) {
751 outOid = kSecPolicyAppleTestATVAppSigning;
752 }
753 #endif
754 else if (CFEqual(oid, kSecPolicyOIDApplePayIssuerEncryption)) {
755 outOid = kSecPolicyApplePayIssuerEncryption;
756 }
757 else if (CFEqual(oid, kSecPolicyOIDAppleOSXProvisioningProfileSigning)) {
758 outOid = kSecPolicyAppleOSXProvisioningProfileSigning;
759 }
760 else if (CFEqual(oid, kSecPolicyOIDAppleATVVPNProfileSigning)) {
761 outOid = kSecPolicyAppleATVVPNProfileSigning;
762 }
763 else if (CFEqual(oid, kSecPolicyOIDAppleAST2Service)) {
764 outOid = kSecPolicyAppleAST2DiagnosticsServerAuth;
765 }
766
767 // Set kSecPolicyOid
768 CFDictionarySetValue(properties, (const void *)kSecPolicyOid,
769 (const void *)outOid);
770
771 // Set kSecPolicyName if we have one
772 if (nameKey && policyRef->_options) {
773 CFTypeRef name = (CFTypeRef) CFDictionaryGetValue(policyRef->_options,
774 nameKey);
775 if (name) {
776 CFDictionarySetValue(properties, (const void *)kSecPolicyName,
777 (const void *)name);
778 }
779 }
780
781 // Set kSecPolicyClient
782 if (CFEqual(oid, kSecPolicyOIDSSLClient) ||
783 CFEqual(oid, kSecPolicyOIDIPSecClient) ||
784 CFEqual(oid, kSecPolicyOIDEAPClient)) {
785 CFDictionarySetValue(properties, (const void *)kSecPolicyClient,
786 (const void *)kCFBooleanTrue);
787 }
788
789 CFRelease(oid);
790 return properties;
791 }
792
793 static void SecPolicySetOid(SecPolicyRef policy, CFStringRef oid) {
794 if (!policy || !oid) return;
795 CFStringRef temp = policy->_oid;
796 CFRetain(oid);
797 policy->_oid = oid;
798 CFReleaseSafe(temp);
799 }
800
801 CFStringRef SecPolicyGetOidString(SecPolicyRef policy) {
802 return policy->_oid;
803 }
804
805 CFDictionaryRef SecPolicyGetOptions(SecPolicyRef policy) {
806 return policy->_options;
807 }
808
809 void SecPolicySetOptionsValue(SecPolicyRef policy, CFStringRef key, CFTypeRef value) {
810 if (!policy || !key) return;
811 CFMutableDictionaryRef options = (CFMutableDictionaryRef) policy->_options;
812 if (!options) {
813 options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
814 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
815 if (!options) return;
816 policy->_options = options;
817 }
818 CFDictionarySetValue(options, key, value);
819 }
820
821 #if !SECTRUST_OSX
822 // this is declared as NA for iPhone in SecPolicy.h, so declare here
823 OSStatus SecPolicySetProperties(SecPolicyRef policyRef, CFDictionaryRef properties);
824 #endif
825
826 OSStatus SecPolicySetProperties(SecPolicyRef policyRef, CFDictionaryRef properties) {
827 // Set policy options based on the provided dictionary keys.
828
829 if (!(policyRef && properties && (CFDictionaryGetTypeID() == CFGetTypeID(properties)))) {
830 return errSecParam;
831 }
832 CFStringRef oid = (CFStringRef) CFRetain(policyRef->_oid);
833 OSStatus result = errSecSuccess;
834
835 // kSecPolicyName
836 CFTypeRef name = NULL;
837 if (CFDictionaryGetValueIfPresent(properties, (const void *)kSecPolicyName,
838 (const void **)&name) && name) {
839 CFTypeID typeID = CFGetTypeID(name);
840 if (CFEqual(oid, kSecPolicyOIDSSLServer) ||
841 CFEqual(oid, kSecPolicyOIDSSLClient) ||
842 CFEqual(oid, kSecPolicyOIDIPSecServer) ||
843 CFEqual(oid, kSecPolicyOIDIPSecClient)) {
844 if (CFStringGetTypeID() == typeID) {
845 SecPolicySetOptionsValue(policyRef, kSecPolicyCheckSSLHostname, name);
846 }
847 else result = errSecParam;
848 }
849 else if (CFEqual(oid, kSecPolicyOIDEAPServer) ||
850 CFEqual(oid, kSecPolicyOIDEAPClient)) {
851 if ((CFStringGetTypeID() == typeID) ||
852 (CFArrayGetTypeID() == typeID)) {
853 SecPolicySetOptionsValue(policyRef, kSecPolicyCheckEAPTrustedServerNames, name);
854 }
855 else result = errSecParam;
856 }
857 else if (CFEqual(oid, kSecPolicyOIDSMIME)) {
858 if (CFStringGetTypeID() == typeID) {
859 SecPolicySetOptionsValue(policyRef, kSecPolicyCheckEmail, name);
860 }
861 else result = errSecParam;
862 }
863 }
864
865 // kSecPolicyClient
866 CFTypeRef client = NULL;
867 if (CFDictionaryGetValueIfPresent(properties, (const void *)kSecPolicyClient,
868 (const void **)&client) && client) {
869 if (!(CFBooleanGetTypeID() == CFGetTypeID(client))) {
870 result = errSecParam;
871 }
872 else if (CFEqual(client, kCFBooleanTrue)) {
873 if (CFEqual(oid, kSecPolicyOIDSSLServer)) {
874 SecPolicySetOid(policyRef, kSecPolicyOIDSSLClient);
875 }
876 else if (CFEqual(oid, kSecPolicyOIDIPSecServer)) {
877 SecPolicySetOid(policyRef, kSecPolicyOIDIPSecClient);
878 }
879 else if (CFEqual(oid, kSecPolicyOIDEAPServer)) {
880 SecPolicySetOid(policyRef, kSecPolicyOIDEAPClient);
881 }
882 }
883 else {
884 if (CFEqual(oid, kSecPolicyOIDSSLClient)) {
885 SecPolicySetOid(policyRef, kSecPolicyOIDSSLServer);
886 }
887 else if (CFEqual(oid, kSecPolicyOIDIPSecClient)) {
888 SecPolicySetOid(policyRef, kSecPolicyOIDIPSecServer);
889 }
890 else if (CFEqual(oid, kSecPolicyOIDEAPClient)) {
891 SecPolicySetOid(policyRef, kSecPolicyOIDEAPServer);
892 }
893 }
894 }
895
896 CFRelease(oid);
897 return result;
898 }
899
900 static xpc_object_t copy_xpc_policy_object(SecPolicyRef policy);
901 static bool append_policy_to_xpc_array(SecPolicyRef policy, xpc_object_t xpc_policies);
902 extern xpc_object_t copy_xpc_policies_array(CFArrayRef policies);
903 extern OSStatus validate_array_of_items(CFArrayRef array, CFStringRef arrayItemType, CFTypeID itemTypeID, bool required);
904
905 static xpc_object_t copy_xpc_policy_object(SecPolicyRef policy) {
906 xpc_object_t xpc_policy = NULL;
907 xpc_object_t data[2] = { NULL, NULL };
908 if (policy->_oid && (CFGetTypeID(policy->_oid) == CFStringGetTypeID())) {
909 data[0] = _CFXPCCreateXPCObjectFromCFObject(policy->_oid);
910 } else {
911 secerror("policy 0x%lX has no _oid", (uintptr_t)policy);
912 }
913 if (policy->_options && (CFGetTypeID(policy->_options) == CFDictionaryGetTypeID())) {
914 data[1] = _CFXPCCreateXPCObjectFromCFObject(policy->_options);
915 } else {
916 secerror("policy 0x%lX has no _options", (uintptr_t)policy);
917 }
918 xpc_policy = xpc_array_create(data, array_size(data));
919 if (data[0]) xpc_release(data[0]);
920 if (data[1]) xpc_release(data[1]);
921 return xpc_policy;
922 }
923
924 static bool append_policy_to_xpc_array(SecPolicyRef policy, xpc_object_t xpc_policies) {
925 if (!policy) {
926 return true; // NOOP
927 }
928 xpc_object_t xpc_policy = copy_xpc_policy_object(policy);
929 if (!xpc_policy) {
930 return false;
931 }
932 xpc_array_append_value(xpc_policies, xpc_policy);
933 xpc_release(xpc_policy);
934 return true;
935 }
936
937 xpc_object_t copy_xpc_policies_array(CFArrayRef policies) {
938 xpc_object_t xpc_policies = xpc_array_create(NULL, 0);
939 if (!xpc_policies) {
940 return NULL;
941 }
942 validate_array_of_items(policies, CFSTR("policy"), SecPolicyGetTypeID(), true);
943 CFIndex ix, count = CFArrayGetCount(policies);
944 for (ix = 0; ix < count; ++ix) {
945 SecPolicyRef policy = (SecPolicyRef) CFArrayGetValueAtIndex(policies, ix);
946 #if SECTRUST_VERBOSE_DEBUG
947 CFDictionaryRef props = SecPolicyCopyProperties(policy);
948 secerror("idx=%d of %d; policy=0x%lX properties=%@", (int)ix, (int)count, (uintptr_t)policy, props);
949 CFReleaseSafe(props);
950 #endif
951 if (!append_policy_to_xpc_array(policy, xpc_policies)) {
952 xpc_release(xpc_policies);
953 xpc_policies = NULL;
954 break;
955 }
956 }
957 return xpc_policies;
958 }
959
960 static xpc_object_t SecPolicyCopyXPCObject(SecPolicyRef policy, CFErrorRef *error) {
961 xpc_object_t xpc_policy = NULL;
962 xpc_object_t data[2] = {};
963 require_action_quiet(data[0] = _CFXPCCreateXPCObjectFromCFObject(policy->_oid), exit,
964 SecError(errSecParam, error, CFSTR("failed to create xpc_object from policy oid")));
965 require_action_quiet(data[1] = _CFXPCCreateXPCObjectFromCFObject(policy->_options), exit,
966 SecError(errSecParam, error, CFSTR("failed to create xpc_object from policy options")));
967 require_action_quiet(xpc_policy = xpc_array_create(data, array_size(data)), exit,
968 SecError(errSecAllocate, error, CFSTR("failed to create xpc_array for policy")));
969
970 exit:
971 if (data[0]) xpc_release(data[0]);
972 if (data[1]) xpc_release(data[1]);
973 return xpc_policy;
974 }
975
976 static bool SecPolicyAppendToXPCArray(SecPolicyRef policy, xpc_object_t policies, CFErrorRef *error) {
977 if (!policy)
978 return true; // NOOP
979
980 xpc_object_t xpc_policy = SecPolicyCopyXPCObject(policy, error);
981 if (!xpc_policy)
982 return false;
983
984 xpc_array_append_value(policies, xpc_policy);
985 xpc_release(xpc_policy);
986 return true;
987 }
988
989 xpc_object_t SecPolicyArrayCopyXPCArray(CFArrayRef policies, CFErrorRef *error) {
990 xpc_object_t xpc_policies;
991 require_action_quiet(xpc_policies = xpc_array_create(NULL, 0), exit,
992 SecError(errSecAllocate, error, CFSTR("failed to create xpc_array")));
993 CFIndex ix, count = CFArrayGetCount(policies);
994 for (ix = 0; ix < count; ++ix) {
995 if (!SecPolicyAppendToXPCArray((SecPolicyRef)CFArrayGetValueAtIndex(policies, ix), xpc_policies, error)) {
996 xpc_release(xpc_policies);
997 return NULL;
998 }
999 }
1000 exit:
1001 return xpc_policies;
1002 }
1003
1004 static SecPolicyRef SecPolicyCreateWithXPCObject(xpc_object_t xpc_policy, CFErrorRef *error) {
1005 SecPolicyRef policy = NULL;
1006 CFTypeRef oid = NULL;
1007 CFTypeRef options = NULL;
1008
1009 require_action_quiet(xpc_policy, exit, SecError(errSecParam, error, CFSTR("policy xpc value is NULL")));
1010 require_action_quiet(xpc_get_type(xpc_policy) == XPC_TYPE_ARRAY, exit, SecError(errSecDecode, error, CFSTR("policy xpc value is not an array")));
1011 require_action_quiet(xpc_array_get_count(xpc_policy) == 2, exit, SecError(errSecDecode, error, CFSTR("policy xpc array count != 2")));
1012 oid = _CFXPCCreateCFObjectFromXPCObject(xpc_array_get_value(xpc_policy, 0));
1013 require_action_quiet(isString(oid), exit,
1014 SecError(errSecParam, error, CFSTR("failed to convert xpc policy[0]=%@ to CFString"), oid));
1015 options = _CFXPCCreateCFObjectFromXPCObject(xpc_array_get_value(xpc_policy, 1));
1016 require_action_quiet(isDictionary(options), exit,
1017 SecError(errSecParam, error, CFSTR("failed to convert xpc policy[1]=%@ to CFDictionary"), options));
1018 require_action_quiet(policy = SecPolicyCreate(oid, options), exit, SecError(errSecDecode, error, CFSTR("Failed to create policy")));
1019
1020 exit:
1021 CFReleaseSafe(oid);
1022 CFReleaseSafe(options);
1023 return policy;
1024 }
1025
1026 CFArrayRef SecPolicyXPCArrayCopyArray(xpc_object_t xpc_policies, CFErrorRef *error) {
1027 CFMutableArrayRef policies = NULL;
1028 require_action_quiet(xpc_get_type(xpc_policies) == XPC_TYPE_ARRAY, exit,
1029 SecError(errSecParam, error, CFSTR("policies xpc value is not an array")));
1030 size_t count = xpc_array_get_count(xpc_policies);
1031 require_action_quiet(policies = CFArrayCreateMutable(kCFAllocatorDefault, count, &kCFTypeArrayCallBacks), exit,
1032 SecError(errSecAllocate, error, CFSTR("failed to create CFArray of capacity %zu"), count));
1033
1034 size_t ix;
1035 for (ix = 0; ix < count; ++ix) {
1036 SecPolicyRef policy = SecPolicyCreateWithXPCObject(xpc_array_get_value(xpc_policies, ix), error);
1037 if (!policy) {
1038 CFRelease(policies);
1039 return NULL;
1040 }
1041 CFArraySetValueAtIndex(policies, ix, policy);
1042 CFRelease(policy);
1043 }
1044
1045 exit:
1046 return policies;
1047
1048 }
1049
1050 static void add_element(CFMutableDictionaryRef options, CFStringRef key,
1051 CFTypeRef value) {
1052 CFTypeRef old_value = CFDictionaryGetValue(options, key);
1053 if (old_value) {
1054 CFMutableArrayRef array;
1055 if (CFGetTypeID(old_value) == CFArrayGetTypeID()) {
1056 array = (CFMutableArrayRef)old_value;
1057 } else {
1058 array = CFArrayCreateMutable(kCFAllocatorDefault, 0,
1059 &kCFTypeArrayCallBacks);
1060 CFArrayAppendValue(array, old_value);
1061 CFDictionarySetValue(options, key, array);
1062 CFRelease(array);
1063 }
1064 CFArrayAppendValue(array, value);
1065 } else {
1066 CFDictionaryAddValue(options, key, value);
1067 }
1068 }
1069
1070 static void add_eku(CFMutableDictionaryRef options, const DERItem *ekuOid) {
1071 CFDataRef eku = CFDataCreate(kCFAllocatorDefault,
1072 ekuOid ? ekuOid->data : NULL,
1073 ekuOid ? ekuOid->length : 0);
1074 if (eku) {
1075 add_element(options, kSecPolicyCheckExtendedKeyUsage, eku);
1076 CFRelease(eku);
1077 }
1078 }
1079
1080 static void add_ku(CFMutableDictionaryRef options, SecKeyUsage keyUsage) {
1081 SInt32 dku = keyUsage;
1082 CFNumberRef ku = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type,
1083 &dku);
1084 if (ku) {
1085 add_element(options, kSecPolicyCheckKeyUsage, ku);
1086 CFRelease(ku);
1087 }
1088 }
1089
1090 static void add_oid(CFMutableDictionaryRef options, CFStringRef policy_key, const DERItem *oid) {
1091 CFDataRef oid_data = CFDataCreate(kCFAllocatorDefault,
1092 oid ? oid->data : NULL,
1093 oid ? oid->length : 0);
1094 if (oid_data) {
1095 add_element(options, policy_key, oid_data);
1096 CFRelease(oid_data);
1097 }
1098 }
1099
1100 static void add_leaf_marker_value(CFMutableDictionaryRef options, const DERItem *markerOid, CFStringRef string_value) {
1101
1102 CFTypeRef policyData = NULL;
1103
1104 if (NULL == string_value) {
1105 policyData = CFDataCreate(kCFAllocatorDefault,
1106 markerOid ? markerOid->data : NULL,
1107 markerOid ? markerOid->length : 0);
1108 } else {
1109 CFStringRef oid_as_string = SecDERItemCopyOIDDecimalRepresentation(kCFAllocatorDefault, markerOid);
1110
1111 const void *key[1] = { oid_as_string };
1112 const void *value[1] = { string_value };
1113 policyData = CFDictionaryCreate(kCFAllocatorDefault,
1114 key, value, 1,
1115 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
1116 CFReleaseNull(oid_as_string);
1117 }
1118
1119 add_element(options, kSecPolicyCheckLeafMarkerOid, policyData);
1120
1121 CFReleaseNull(policyData);
1122
1123 }
1124
1125 static void add_leaf_marker(CFMutableDictionaryRef options, const DERItem *markerOid) {
1126 add_leaf_marker_value(options, markerOid, NULL);
1127 }
1128
1129
1130 static void add_certificate_policy_oid(CFMutableDictionaryRef options, const DERItem *certificatePolicyOid, CFStringRef string_value) {
1131 CFTypeRef certificatePolicyData = NULL;
1132
1133 if (NULL == string_value) {
1134 certificatePolicyData = CFDataCreate(kCFAllocatorDefault,
1135 certificatePolicyOid ? certificatePolicyOid->data : NULL,
1136 certificatePolicyOid ? certificatePolicyOid->length : 0);
1137 } else {
1138 CFStringRef oid_as_string = SecDERItemCopyOIDDecimalRepresentation(kCFAllocatorDefault, certificatePolicyOid);
1139
1140 const void *key[1] = { oid_as_string };
1141 const void *value[1] = { string_value };
1142 certificatePolicyData = CFDictionaryCreate(kCFAllocatorDefault,
1143 key, value, 1,
1144 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
1145 CFReleaseNull(oid_as_string);
1146 }
1147
1148 add_element(options, kSecPolicyCheckCertificatePolicy, certificatePolicyData);
1149
1150 CFReleaseNull(certificatePolicyData);
1151 }
1152 //
1153 // Routines for adding dictionary entries for policies.
1154 //
1155
1156 // X.509, but missing validity requirements.
1157 static void SecPolicyAddBasicCertOptions(CFMutableDictionaryRef options)
1158 {
1159 //CFDictionaryAddValue(options, kSecPolicyCheckBasicCertificateProcessing, kCFBooleanTrue);
1160 CFDictionaryAddValue(options, kSecPolicyCheckCriticalExtensions, kCFBooleanTrue);
1161 CFDictionaryAddValue(options, kSecPolicyCheckIdLinkage, kCFBooleanTrue);
1162 CFDictionaryAddValue(options, kSecPolicyCheckBasicContraints, kCFBooleanTrue);
1163 CFDictionaryAddValue(options, kSecPolicyCheckNonEmptySubject, kCFBooleanTrue);
1164 CFDictionaryAddValue(options, kSecPolicyCheckQualifiedCertStatements, kCFBooleanTrue);
1165 CFDictionaryAddValue(options, kSecPolicyCheckWeakIntermediates, kCFBooleanTrue);
1166 CFDictionaryAddValue(options, kSecPolicyCheckWeakLeaf, kCFBooleanTrue);
1167 CFDictionaryAddValue(options, kSecPolicyCheckWeakRoot, kCFBooleanTrue);
1168 }
1169
1170 static void SecPolicyAddBasicX509Options(CFMutableDictionaryRef options)
1171 {
1172 SecPolicyAddBasicCertOptions(options);
1173 CFDictionaryAddValue(options, kSecPolicyCheckValidIntermediates, kCFBooleanTrue);
1174 CFDictionaryAddValue(options, kSecPolicyCheckValidLeaf, kCFBooleanTrue);
1175 CFDictionaryAddValue(options, kSecPolicyCheckValidRoot, kCFBooleanTrue);
1176
1177 // Make sure that black and gray leaf checks are performed for basic X509 chain building
1178 CFDictionaryAddValue(options, kSecPolicyCheckBlackListedLeaf, kCFBooleanTrue);
1179 CFDictionaryAddValue(options, kSecPolicyCheckGrayListedLeaf, kCFBooleanTrue);
1180 }
1181
1182 static bool SecPolicyAddChainLengthOptions(CFMutableDictionaryRef options, CFIndex length)
1183 {
1184 bool result = false;
1185 CFNumberRef lengthAsCF = NULL;
1186
1187 require(lengthAsCF = CFNumberCreate(kCFAllocatorDefault,
1188 kCFNumberCFIndexType, &length), errOut);
1189 CFDictionaryAddValue(options, kSecPolicyCheckChainLength, lengthAsCF);
1190
1191 result = true;
1192
1193 errOut:
1194 CFReleaseSafe(lengthAsCF);
1195 return result;
1196 }
1197
1198 static bool SecPolicyAddAnchorSHA1Options(CFMutableDictionaryRef options,
1199 const UInt8 anchorSha1[kSecPolicySHA1Size])
1200 {
1201 bool success = false;
1202 CFDataRef anchorData = NULL;
1203
1204 require(anchorData = CFDataCreate(kCFAllocatorDefault, anchorSha1, kSecPolicySHA1Size), errOut);
1205 add_element(options, kSecPolicyCheckAnchorSHA1, anchorData);
1206
1207 success = true;
1208
1209 errOut:
1210 CFReleaseSafe(anchorData);
1211 return success;
1212 }
1213
1214 static bool SecPolicyAddAppleAnchorOptions(CFMutableDictionaryRef options)
1215 {
1216 return SecPolicyAddAnchorSHA1Options(options, kAppleCASHA1);
1217 }
1218
1219 //
1220 // Policy Creation Functions
1221 //
1222 SecPolicyRef SecPolicyCreateBasicX509(void) {
1223 CFMutableDictionaryRef options = NULL;
1224 SecPolicyRef result = NULL;
1225
1226 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
1227 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut);
1228
1229 SecPolicyAddBasicX509Options(options);
1230 CFDictionaryAddValue(options, kSecPolicyCheckNoNetworkAccess,
1231 kCFBooleanTrue);
1232
1233 require(result = SecPolicyCreate(kSecPolicyOIDBasicX509, options), errOut);
1234
1235 errOut:
1236 CFReleaseSafe(options);
1237 return result;
1238 }
1239
1240 SecPolicyRef SecPolicyCreateSSL(Boolean server, CFStringRef hostname) {
1241 CFMutableDictionaryRef options = NULL;
1242 SecPolicyRef result = NULL;
1243
1244 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
1245 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut);
1246
1247 SecPolicyAddBasicX509Options(options);
1248
1249 if (hostname) {
1250 CFDictionaryAddValue(options, kSecPolicyCheckSSLHostname, hostname);
1251 }
1252
1253 CFDictionaryAddValue(options, kSecPolicyCheckBlackListedLeaf, kCFBooleanTrue);
1254 CFDictionaryAddValue(options, kSecPolicyCheckGrayListedLeaf, kCFBooleanTrue);
1255
1256 /* If server and EKU ext present then EKU ext should contain one of
1257 ServerAuth or ExtendedKeyUsageAny or NetscapeSGC or MicrosoftSGC.
1258 else if !server and EKU ext present then EKU ext should contain one of
1259 ClientAuth or ExtendedKeyUsageAny. */
1260
1261 /* We always allow certificates that specify oidAnyExtendedKeyUsage. */
1262 add_eku(options, NULL); /* eku extension is optional */
1263 add_eku(options, &oidAnyExtendedKeyUsage);
1264 if (server) {
1265 add_eku(options, &oidExtendedKeyUsageServerAuth);
1266 add_eku(options, &oidExtendedKeyUsageMicrosoftSGC);
1267 add_eku(options, &oidExtendedKeyUsageNetscapeSGC);
1268 } else {
1269 add_eku(options, &oidExtendedKeyUsageClientAuth);
1270 }
1271
1272 require(result = SecPolicyCreate(
1273 server ? kSecPolicyOIDSSLServer : kSecPolicyOIDSSLClient,
1274 options), errOut);
1275
1276 errOut:
1277 CFReleaseSafe(options);
1278 return result;
1279 }
1280
1281 SecPolicyRef SecPolicyCreateiPhoneActivation(void) {
1282 CFMutableDictionaryRef options = NULL;
1283 SecPolicyRef result = NULL;
1284
1285 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
1286 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut);
1287
1288 SecPolicyAddBasicCertOptions(options);
1289
1290 #if 0
1291 CFDictionaryAddValue(options, kSecPolicyCheckKeyUsage,
1292 kCFBooleanTrue);
1293 CFDictionaryAddValue(options, kSecPolicyCheckExtendedKeyUsage,
1294 kCFBooleanTrue);
1295 #endif
1296
1297 /* Basic X.509 policy with the additional requirements that the chain
1298 length is 3, it's anchored at the AppleCA and the leaf certificate
1299 has issuer "Apple iPhone Certification Authority" and
1300 subject "Apple iPhone Activation" for the common name. */
1301 CFDictionaryAddValue(options, kSecPolicyCheckIssuerCommonName,
1302 CFSTR("Apple iPhone Certification Authority"));
1303 CFDictionaryAddValue(options, kSecPolicyCheckSubjectCommonName,
1304 CFSTR("Apple iPhone Activation"));
1305
1306 require(SecPolicyAddChainLengthOptions(options, 3), errOut);
1307 require(SecPolicyAddAppleAnchorOptions(options), errOut);
1308
1309 require(result = SecPolicyCreate(kSecPolicyOIDiPhoneActivation, options),
1310 errOut);
1311
1312 errOut:
1313 CFReleaseSafe(options);
1314 return result;
1315 }
1316
1317 SecPolicyRef SecPolicyCreateiPhoneDeviceCertificate(void) {
1318 CFMutableDictionaryRef options = NULL;
1319 SecPolicyRef result = NULL;
1320
1321 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
1322 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut);
1323
1324 SecPolicyAddBasicCertOptions(options);
1325
1326 #if 0
1327 CFDictionaryAddValue(options, kSecPolicyCheckKeyUsage,
1328 kCFBooleanTrue);
1329 CFDictionaryAddValue(options, kSecPolicyCheckExtendedKeyUsage,
1330 kCFBooleanTrue);
1331 #endif
1332
1333 /* Basic X.509 policy with the additional requirements that the chain
1334 length is 4, it's anchored at the AppleCA and the first intermediate
1335 has the subject "Apple iPhone Device CA". */
1336 CFDictionaryAddValue(options, kSecPolicyCheckIssuerCommonName,
1337 CFSTR("Apple iPhone Device CA"));
1338
1339 require(SecPolicyAddChainLengthOptions(options, 4), errOut);
1340 require(SecPolicyAddAppleAnchorOptions(options), errOut);
1341
1342 require(result = SecPolicyCreate(kSecPolicyOIDiPhoneDeviceCertificate, options),
1343 errOut);
1344
1345 errOut:
1346 CFReleaseSafe(options);
1347 return result;
1348 }
1349
1350 SecPolicyRef SecPolicyCreateFactoryDeviceCertificate(void) {
1351 CFMutableDictionaryRef options = NULL;
1352 SecPolicyRef result = NULL;
1353
1354 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
1355 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut);
1356
1357 SecPolicyAddBasicCertOptions(options);
1358
1359 #if 0
1360 CFDictionaryAddValue(options, kSecPolicyCheckKeyUsage,
1361 kCFBooleanTrue);
1362 CFDictionaryAddValue(options, kSecPolicyCheckExtendedKeyUsage,
1363 kCFBooleanTrue);
1364 #endif
1365
1366 /* Basic X.509 policy with the additional requirements that the chain
1367 is anchored at the factory device certificate issuer. */
1368 require(SecPolicyAddAnchorSHA1Options(options, kFactoryDeviceCASHA1), errOut);
1369
1370 require(result = SecPolicyCreate(kSecPolicyOIDFactoryDeviceCertificate, options),
1371 errOut);
1372
1373 errOut:
1374 CFReleaseSafe(options);
1375 return result;
1376 }
1377
1378 SecPolicyRef SecPolicyCreateiAP(void) {
1379 CFMutableDictionaryRef options = NULL;
1380 SecPolicyRef result = NULL;
1381 CFTimeZoneRef tz = NULL;
1382 CFDateRef date = NULL;
1383
1384 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
1385 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut);
1386
1387 SecPolicyAddBasicCertOptions(options);
1388
1389 CFDictionaryAddValue(options, kSecPolicyCheckSubjectCommonNamePrefix,
1390 CFSTR("IPA_"));
1391
1392 date = CFDateCreateForGregorianZuluDay(NULL, 2006, 5, 31);
1393 CFDictionaryAddValue(options, kSecPolicyCheckNotValidBefore, date);
1394
1395 require(result = SecPolicyCreate(kSecPolicyOIDiAP, options),
1396 errOut);
1397
1398 errOut:
1399 CFReleaseSafe(date);
1400 CFReleaseSafe(tz);
1401 CFReleaseSafe(options);
1402 return result;
1403 }
1404
1405 SecPolicyRef SecPolicyCreateiTunesStoreURLBag(void) {
1406 CFMutableDictionaryRef options = NULL;
1407 SecPolicyRef result = NULL;
1408
1409
1410 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
1411 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut);
1412
1413 SecPolicyAddBasicCertOptions(options);
1414
1415 CFDictionaryAddValue(options, kSecPolicyCheckSubjectOrganization,
1416 CFSTR("Apple Inc."));
1417 CFDictionaryAddValue(options, kSecPolicyCheckSubjectCommonName,
1418 CFSTR("iTunes Store URL Bag"));
1419
1420 require(SecPolicyAddChainLengthOptions(options, 2), errOut);
1421 require(SecPolicyAddAnchorSHA1Options(options, kITMSCASHA1), errOut);
1422
1423 require(result = SecPolicyCreate(kSecPolicyOIDiTunesStoreURLBag, options), errOut);
1424
1425 errOut:
1426 CFReleaseSafe(options);
1427 return result;
1428 }
1429
1430 SecPolicyRef SecPolicyCreateEAP(Boolean server, CFArrayRef trustedServerNames) {
1431 CFMutableDictionaryRef options = NULL;
1432 SecPolicyRef result = NULL;
1433
1434 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
1435 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut);
1436
1437 SecPolicyAddBasicX509Options(options);
1438
1439 /* Since EAP is used to setup the network we don't want evaluation
1440 using this policy to access the network. */
1441 CFDictionaryAddValue(options, kSecPolicyCheckNoNetworkAccess,
1442 kCFBooleanTrue);
1443
1444 if (trustedServerNames) {
1445 CFDictionaryAddValue(options, kSecPolicyCheckEAPTrustedServerNames, trustedServerNames);
1446
1447 /* Specifying trusted server names implies EAP-TLS,
1448 so we need to check for EKU per rdar://22206018 */
1449
1450 /* If server and EKU ext present then EKU ext should contain one of
1451 ServerAuth or ExtendedKeyUsageAny or NetscapeSGC or MicrosoftSGC.
1452 else if !server and EKU ext present then EKU ext should contain one of
1453 ClientAuth or ExtendedKeyUsageAny. */
1454
1455 /* We always allow certificates that specify oidAnyExtendedKeyUsage. */
1456 add_eku(options, NULL); /* eku extension is optional */
1457 add_eku(options, &oidAnyExtendedKeyUsage);
1458 if (server) {
1459 add_eku(options, &oidExtendedKeyUsageServerAuth);
1460 add_eku(options, &oidExtendedKeyUsageMicrosoftSGC);
1461 add_eku(options, &oidExtendedKeyUsageNetscapeSGC);
1462 } else {
1463 add_eku(options, &oidExtendedKeyUsageClientAuth);
1464 }
1465 }
1466
1467 require(result = SecPolicyCreate(
1468 server ? kSecPolicyOIDEAPServer : kSecPolicyOIDEAPClient,
1469 options), errOut);
1470
1471 errOut:
1472 CFReleaseSafe(options);
1473 return result;
1474 }
1475
1476 SecPolicyRef SecPolicyCreateIPSec(Boolean server, CFStringRef hostname) {
1477 CFMutableDictionaryRef options = NULL;
1478 SecPolicyRef result = NULL;
1479
1480 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
1481 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut);
1482
1483 SecPolicyAddBasicX509Options(options);
1484
1485 if (hostname) {
1486 CFDictionaryAddValue(options, kSecPolicyCheckSSLHostname, hostname);
1487 }
1488
1489 /* Require oidExtendedKeyUsageIPSec if Extended Keyusage Extention is
1490 present. */
1491 /* Per <rdar://problem/6843827> Cisco VPN Certificate compatibility issue.
1492 We don't check the EKU for IPSec certs for now. If we do add eku
1493 checking back in the future, we should probably also accept the
1494 following EKUs:
1495 ipsecEndSystem 1.3.6.1.5.5.7.3.5
1496 and possibly even
1497 ipsecTunnel 1.3.6.1.5.5.7.3.6
1498 ipsecUser 1.3.6.1.5.5.7.3.7
1499 */
1500 //add_eku(options, NULL); /* eku extension is optional */
1501 //add_eku(options, &oidAnyExtendedKeyUsage);
1502 //add_eku(options, &oidExtendedKeyUsageIPSec);
1503
1504 require(result = SecPolicyCreate(
1505 server ? kSecPolicyOIDIPSecServer : kSecPolicyOIDIPSecClient,
1506 options), errOut);
1507
1508 errOut:
1509 CFReleaseSafe(options);
1510 return result;
1511 }
1512
1513 SecPolicyRef SecPolicyCreateiPhoneApplicationSigning(void) {
1514 CFMutableDictionaryRef options = NULL;
1515 SecPolicyRef result = NULL;
1516
1517 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
1518 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut);
1519
1520 SecPolicyAddBasicCertOptions(options);
1521
1522 /* Basic X.509 policy with the additional requirements that the chain
1523 length is 3, it's anchored at the AppleCA and the leaf certificate
1524 has issuer "Apple iPhone Certification Authority" and
1525 subject "Apple iPhone OS Application Signing" for the common name. */
1526 CFDictionaryAddValue(options, kSecPolicyCheckIssuerCommonName,
1527 CFSTR("Apple iPhone Certification Authority"));
1528 if (SecIsInternalRelease() && !SecIsProductionFused()) {
1529 CFDictionaryAddValue(options, kSecPolicyCheckSubjectCommonNameTEST,
1530 CFSTR("Apple iPhone OS Application Signing"));
1531 }
1532 else {
1533 CFDictionaryAddValue(options, kSecPolicyCheckSubjectCommonName,
1534 CFSTR("Apple iPhone OS Application Signing"));
1535 }
1536
1537 require(SecPolicyAddChainLengthOptions(options, 3), errOut);
1538 require(SecPolicyAddAppleAnchorOptions(options), errOut);
1539
1540 add_eku(options, NULL); /* eku extension is optional */
1541 add_eku(options, &oidAnyExtendedKeyUsage);
1542 add_eku(options, &oidExtendedKeyUsageCodeSigning);
1543
1544 require(result = SecPolicyCreate(kSecPolicyOIDiPhoneApplicationSigning, options),
1545 errOut);
1546
1547 /* 1.2.840.113635.100.6.1.3, non-critical: DER:05:00 - application signing */
1548
1549 errOut:
1550 CFReleaseSafe(options);
1551 return result;
1552 }
1553
1554 SecPolicyRef SecPolicyCreateiPhoneProfileApplicationSigning(void) {
1555 CFMutableDictionaryRef options = NULL;
1556 SecPolicyRef result = NULL;
1557
1558 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
1559 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut);
1560 CFDictionaryAddValue(options, kSecPolicyCheckRevocation, kCFBooleanFalse);
1561 CFDictionaryAddValue(options, kSecPolicyCheckValidLeaf, kCFBooleanFalse);
1562
1563 require(result = SecPolicyCreate(kSecPolicyOIDiPhoneProfileApplicationSigning,
1564 options), errOut);
1565
1566 errOut:
1567 CFReleaseSafe(options);
1568 return result;
1569 }
1570
1571 SecPolicyRef SecPolicyCreateiPhoneProvisioningProfileSigning(void) {
1572 CFMutableDictionaryRef options = NULL;
1573 SecPolicyRef result = NULL;
1574
1575 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
1576 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut);
1577
1578 SecPolicyAddBasicCertOptions(options);
1579
1580 /* Basic X.509 policy with the additional requirements that the chain
1581 length is 3, it's anchored at the AppleCA and the leaf certificate
1582 has issuer "Apple iPhone Certification Authority" and
1583 subject "Apple iPhone OS Provisioning Profile Signing" for the common name. */
1584 CFDictionaryAddValue(options, kSecPolicyCheckIssuerCommonName,
1585 CFSTR("Apple iPhone Certification Authority"));
1586 if (SecIsInternalRelease() && !SecIsProductionFused()) {
1587 CFDictionaryAddValue(options, kSecPolicyCheckSubjectCommonNameTEST,
1588 CFSTR("Apple iPhone OS Provisioning Profile Signing"));
1589 }
1590 else {
1591 CFDictionaryAddValue(options, kSecPolicyCheckSubjectCommonName,
1592 CFSTR("Apple iPhone OS Provisioning Profile Signing"));
1593 }
1594
1595 require(SecPolicyAddChainLengthOptions(options, 3), errOut);
1596 require(SecPolicyAddAppleAnchorOptions(options), errOut);
1597
1598 require(result = SecPolicyCreate(kSecPolicyOIDiPhoneProvisioningProfileSigning, options),
1599 errOut);
1600
1601 /* 1.2.840.113635.100.6.2.2.1, non-critical: DER:05:00 - provisioning profile */
1602
1603 errOut:
1604 CFReleaseSafe(options);
1605 return result;
1606 }
1607
1608 SecPolicyRef SecPolicyCreateAppleTVOSApplicationSigning(void) {
1609 CFMutableDictionaryRef options = NULL;
1610 SecPolicyRef result = NULL;
1611 CFDataRef atvProdOid = NULL;
1612 CFDataRef atvTestOid = NULL;
1613 CFArrayRef oids = NULL;
1614
1615 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
1616 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut);
1617
1618 SecPolicyAddBasicCertOptions(options);
1619
1620 require(SecPolicyAddChainLengthOptions(options, 3), errOut);
1621
1622 CFMutableDictionaryRef appleAnchorOptions = CFDictionaryCreateMutableForCFTypes(NULL);
1623 require(appleAnchorOptions, errOut);
1624 add_element(options, kSecPolicyCheckAnchorApple, appleAnchorOptions);
1625
1626 /* Check for intermediate: Apple Worldwide Developer Relations */
1627 /* 1.2.840.113635.100.6.2.1 */
1628 add_oid(options, kSecPolicyCheckIntermediateMarkerOid, &oidAppleIntmMarkerAppleWWDR);
1629
1630 add_eku(options, NULL); /* eku extension is optional */
1631 add_eku(options, &oidAnyExtendedKeyUsage);
1632 add_eku(options, &oidExtendedKeyUsageCodeSigning);
1633
1634 /* Check for prod or test AppleTV Application Signing OIDs */
1635 /* Prod: 1.2.840.113635.100.6.1.24 */
1636 /* Test: 1.2.840.113635.100.6.1.24.1 */
1637 atvProdOid = CFDataCreate(kCFAllocatorDefault, oidAppleTVOSApplicationSigningProd.data, oidAppleTVOSApplicationSigningProd.length);
1638 require(atvProdOid, errOut);
1639 atvTestOid = CFDataCreate(kCFAllocatorDefault, oidAppleTVOSApplicationSigningTest.data, oidAppleTVOSApplicationSigningTest.length);
1640 require(atvTestOid, errOut);
1641
1642 oids = CFArrayCreateForCFTypes(kCFAllocatorDefault, atvProdOid, atvTestOid, NULL);
1643 require(oids, errOut);
1644
1645 add_element(options, kSecPolicyCheckLeafMarkerOid, oids);
1646
1647 require(result = SecPolicyCreate(kSecPolicyOIDAppleTVOSApplicationSigning, options),
1648 errOut);
1649
1650 errOut:
1651 CFReleaseSafe(options);
1652 CFReleaseSafe(oids);
1653 CFReleaseSafe(atvProdOid);
1654 CFReleaseSafe(atvTestOid);
1655 return result;
1656 }
1657
1658 SecPolicyRef SecPolicyCreateOCSPSigner(void) {
1659 CFMutableDictionaryRef options = NULL;
1660 SecPolicyRef result = NULL;
1661
1662 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
1663 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut);
1664
1665 SecPolicyAddBasicX509Options(options);
1666
1667 /* Require id-kp-OCSPSigning extendedKeyUsage to be present, not optional. */
1668 add_eku(options, &oidExtendedKeyUsageOCSPSigning);
1669
1670 require(result = SecPolicyCreate(kSecPolicyOIDOCSPSigner, options), errOut);
1671
1672 errOut:
1673 CFReleaseSafe(options);
1674 return result;
1675 }
1676
1677 SecPolicyRef SecPolicyCreateRevocation(CFOptionFlags revocationFlags) {
1678 CFMutableDictionaryRef options = NULL;
1679 SecPolicyRef result = NULL;
1680
1681 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
1682 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut);
1683
1684 /* false = ocsp, true = crl, string/url value = crl distribution point,
1685 array = list of multiple values for example false, true, url1, url2
1686 check ocsp, crl, and url1 and url2 for certs which have no extensions.
1687 */
1688 if (revocationFlags & kSecRevocationOCSPMethod) {
1689 CFDictionaryAddValue(options, kSecPolicyCheckRevocation, kCFBooleanFalse);
1690 }
1691 else if (revocationFlags & kSecRevocationCRLMethod) {
1692 CFDictionaryAddValue(options, kSecPolicyCheckRevocation, kCFBooleanTrue);
1693 }
1694
1695 if (revocationFlags & kSecRevocationRequirePositiveResponse) {
1696 CFDictionaryAddValue(options, kSecPolicyCheckRevocationResponseRequired, kCFBooleanTrue);
1697 }
1698
1699 if (revocationFlags & kSecRevocationNetworkAccessDisabled) {
1700 CFDictionaryAddValue(options, kSecPolicyCheckNoNetworkAccess, kCFBooleanTrue);
1701 }
1702
1703 /* Only flag bits 0-4 are currently defined */
1704 require(((revocationFlags >> 5) == 0), errOut);
1705
1706 require(result = SecPolicyCreate(kSecPolicyOIDRevocation, options), errOut);
1707
1708 errOut:
1709 CFReleaseSafe(options);
1710 return result;
1711 }
1712
1713 SecPolicyRef SecPolicyCreateSMIME(CFIndex smimeUsage, CFStringRef email) {
1714 CFMutableDictionaryRef options = NULL;
1715 SecPolicyRef result = NULL;
1716
1717 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
1718 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut);
1719
1720 SecPolicyAddBasicX509Options(options);
1721
1722 /* We call add_ku for each combination of bits we are willing to allow. */
1723 if (smimeUsage & kSecSignSMIMEUsage) {
1724 add_ku(options, kSecKeyUsageUnspecified);
1725 add_ku(options, kSecKeyUsageDigitalSignature);
1726 add_ku(options, kSecKeyUsageNonRepudiation);
1727 }
1728 if (smimeUsage & kSecKeyEncryptSMIMEUsage) {
1729 add_ku(options, kSecKeyUsageKeyEncipherment);
1730 }
1731 if (smimeUsage & kSecDataEncryptSMIMEUsage) {
1732 add_ku(options, kSecKeyUsageDataEncipherment);
1733 }
1734 if (smimeUsage & kSecKeyExchangeDecryptSMIMEUsage) {
1735 add_ku(options, kSecKeyUsageKeyAgreement | kSecKeyUsageDecipherOnly);
1736 }
1737 if (smimeUsage & kSecKeyExchangeEncryptSMIMEUsage) {
1738 add_ku(options, kSecKeyUsageKeyAgreement | kSecKeyUsageEncipherOnly);
1739 }
1740 if (smimeUsage & kSecKeyExchangeBothSMIMEUsage) {
1741 add_ku(options, kSecKeyUsageKeyAgreement | kSecKeyUsageEncipherOnly | kSecKeyUsageDecipherOnly);
1742 }
1743
1744 if (email) {
1745 CFDictionaryAddValue(options, kSecPolicyCheckEmail, email);
1746 }
1747
1748 /* RFC 3850 paragraph 4.4.4
1749
1750 If the extended key usage extension is present in the certificate
1751 then interpersonal message S/MIME receiving agents MUST check that it
1752 contains either the emailProtection or the anyExtendedKeyUsage OID as
1753 defined in [KEYM]. S/MIME uses other than interpersonal messaging
1754 MAY require the explicit presence of the extended key usage extension
1755 or other OIDs to be present in the extension or both.
1756 */
1757 add_eku(options, NULL); /* eku extension is optional */
1758 add_eku(options, &oidAnyExtendedKeyUsage);
1759 add_eku(options, &oidExtendedKeyUsageEmailProtection);
1760
1761 require(result = SecPolicyCreate(kSecPolicyOIDSMIME, options), errOut);
1762
1763 errOut:
1764 CFReleaseSafe(options);
1765 return result;
1766 }
1767
1768 SecPolicyRef SecPolicyCreateApplePackageSigning(void) {
1769 CFMutableDictionaryRef options = NULL;
1770 SecPolicyRef result = NULL;
1771
1772 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
1773 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut);
1774
1775 // TBD: review OS X policy to see what options are needed for this policy
1776 SecPolicyAddBasicCertOptions(options);
1777
1778 require(SecPolicyAddChainLengthOptions(options, 3), errOut);
1779 require(SecPolicyAddAppleAnchorOptions(options), errOut);
1780
1781 require(result = SecPolicyCreate(kSecPolicyOIDPackageSigning, options),
1782 errOut);
1783
1784 errOut:
1785 CFReleaseSafe(options);
1786 return result;
1787
1788 }
1789
1790 SecPolicyRef SecPolicyCreateAppleSWUpdateSigning(void) {
1791 CFMutableDictionaryRef options = NULL;
1792 SecPolicyRef result = NULL;
1793 /*
1794 * OS X rules for this policy:
1795 * -- Must have one intermediate cert
1796 * -- intermediate must have basic constraints with path length 0
1797 * -- intermediate has CSSMOID_APPLE_EKU_CODE_SIGNING EKU
1798 * -- leaf cert has either CODE_SIGNING or CODE_SIGN_DEVELOPMENT EKU (the latter of
1799 * which triggers a CSSMERR_APPLETP_CODE_SIGN_DEVELOPMENT error)
1800 */
1801 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
1802 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut);
1803
1804 // TBD: review OS X policy to see what options are needed for this policy
1805 SecPolicyAddBasicCertOptions(options);
1806
1807 require(SecPolicyAddChainLengthOptions(options, 3), errOut);
1808 require(SecPolicyAddAppleAnchorOptions(options), errOut);
1809
1810 add_eku(options, &oidAppleExtendedKeyUsageCodeSigning);
1811 add_eku(options, &oidAppleExtendedKeyUsageCodeSigningDev);
1812
1813 require(result = SecPolicyCreate(kSecPolicyOIDAppleSWUpdateSigning, options),
1814 errOut);
1815
1816 errOut:
1817 CFReleaseSafe(options);
1818 return result;
1819
1820 }
1821
1822 SecPolicyRef SecPolicyCreateCodeSigning(void) {
1823 CFMutableDictionaryRef options = NULL;
1824 SecPolicyRef result = NULL;
1825
1826 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
1827 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut);
1828
1829 #if SECTRUST_OSX
1830 #warning STU: <rdar://21328880>
1831 //%%% figure out why this policy is not passing for OS X.
1832 // I suspect it has to do with iOS not supporting anchor and keychain options yet.
1833 SecPolicyAddBasicCertOptions(options);
1834 #else
1835 SecPolicyAddBasicX509Options(options);
1836
1837 /* If the key usage extension is present we accept it having either of
1838 these values. */
1839 add_ku(options, kSecKeyUsageDigitalSignature);
1840 add_ku(options, kSecKeyUsageNonRepudiation);
1841
1842 /* We require a extended key usage extension and we accept any or
1843 codesigning ekus. */
1844 /* TODO: Do we want to accept the apple codesigning oid as well or is
1845 that a separate policy? */
1846 /* ANSWER: it's a separate policy, SecPolicyCreateAppleSWUpdateSigning */
1847 add_eku(options, &oidAnyExtendedKeyUsage);
1848 add_eku(options, &oidExtendedKeyUsageCodeSigning);
1849 #endif
1850
1851 require(result = SecPolicyCreate(kSecPolicyOIDCodeSigning, options),
1852 errOut);
1853
1854 errOut:
1855 CFReleaseSafe(options);
1856 return result;
1857 }
1858
1859 /* Explicitly leave out empty subject/subjectaltname check */
1860 SecPolicyRef SecPolicyCreateLockdownPairing(void) {
1861 CFMutableDictionaryRef options = NULL;
1862 SecPolicyRef result = NULL;
1863
1864 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
1865 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut);
1866 //CFDictionaryAddValue(options, kSecPolicyCheckBasicCertificateProcessing,
1867 // kCFBooleanTrue);
1868 CFDictionaryAddValue(options, kSecPolicyCheckCriticalExtensions,
1869 kCFBooleanTrue);
1870 CFDictionaryAddValue(options, kSecPolicyCheckIdLinkage,
1871 kCFBooleanTrue);
1872 CFDictionaryAddValue(options, kSecPolicyCheckBasicContraints,
1873 kCFBooleanTrue);
1874 CFDictionaryAddValue(options, kSecPolicyCheckQualifiedCertStatements,
1875 kCFBooleanTrue);
1876
1877 require(result = SecPolicyCreate(kSecPolicyOIDLockdownPairing, options), errOut);
1878
1879 errOut:
1880 CFReleaseSafe(options);
1881 return result;
1882 }
1883
1884 SecPolicyRef SecPolicyCreateURLBag(void) {
1885 CFMutableDictionaryRef options = NULL;
1886 SecPolicyRef result = NULL;
1887
1888 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
1889 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut);
1890
1891 SecPolicyAddBasicCertOptions(options);
1892
1893 add_eku(options, &oidExtendedKeyUsageCodeSigning);
1894
1895 require(result = SecPolicyCreate(kSecPolicyOIDURLBag, options), errOut);
1896
1897 errOut:
1898 CFReleaseSafe(options);
1899 return result;
1900 }
1901
1902 static bool SecPolicyAddAppleCertificationAuthorityOptions(CFMutableDictionaryRef options, bool honorValidity)
1903 {
1904 bool success = false;
1905
1906 if (honorValidity)
1907 SecPolicyAddBasicX509Options(options);
1908 else
1909 SecPolicyAddBasicCertOptions(options);
1910
1911 #if 0
1912 CFDictionaryAddValue(options, kSecPolicyCheckKeyUsage,
1913 kCFBooleanTrue);
1914 CFDictionaryAddValue(options, kSecPolicyCheckExtendedKeyUsage,
1915 kCFBooleanTrue);
1916 #endif
1917
1918 /* Basic X.509 policy with the additional requirements that the chain
1919 length is 3, it's anchored at the AppleCA and the leaf certificate
1920 has issuer "Apple iPhone Certification Authority". */
1921 CFDictionaryAddValue(options, kSecPolicyCheckIssuerCommonName,
1922 CFSTR("Apple iPhone Certification Authority"));
1923
1924 require(SecPolicyAddChainLengthOptions(options, 3), errOut);
1925 require(SecPolicyAddAppleAnchorOptions(options), errOut);
1926
1927 success = true;
1928
1929 errOut:
1930 return success;
1931 }
1932
1933 static SecPolicyRef SecPolicyCreateAppleCertificationAuthorityPolicy(CFStringRef policyOID, CFStringRef leafName, bool honorValidity)
1934 {
1935 CFMutableDictionaryRef options = NULL;
1936 SecPolicyRef result = NULL;
1937
1938 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
1939 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut);
1940
1941 require(SecPolicyAddAppleCertificationAuthorityOptions(options, honorValidity), errOut);
1942
1943 CFDictionaryAddValue(options, kSecPolicyCheckSubjectCommonName, leafName);
1944
1945 require(result = SecPolicyCreate(policyOID, options),
1946 errOut);
1947
1948 errOut:
1949 CFReleaseSafe(options);
1950 return result;
1951 }
1952
1953
1954 SecPolicyRef SecPolicyCreateOTATasking(void)
1955 {
1956 return SecPolicyCreateAppleCertificationAuthorityPolicy(kSecPolicyOIDOTATasking, CFSTR("OTA Task Signing"), true);
1957 }
1958
1959 SecPolicyRef SecPolicyCreateMobileAsset(void)
1960 {
1961 return SecPolicyCreateAppleCertificationAuthorityPolicy(kSecPolicyOIDMobileAsset, CFSTR("Asset Manifest Signing"), false);
1962 }
1963
1964 SecPolicyRef SecPolicyCreateAppleIDAuthorityPolicy(void)
1965 {
1966 SecPolicyRef result = NULL;
1967 CFMutableDictionaryRef options = NULL;
1968 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
1969 &kCFTypeDictionaryKeyCallBacks,
1970 &kCFTypeDictionaryValueCallBacks), out);
1971
1972 //Leaf appears to be a SSL only cert, so policy should expand on that policy
1973 SecPolicyAddBasicX509Options(options);
1974
1975 // Apple CA anchored
1976 require(SecPolicyAddAppleAnchorOptions(options), out);
1977
1978 // with the addition of the existence check of an extension with "Apple ID Sharing Certificate" oid (1.2.840.113635.100.4.7)
1979 // NOTE: this obviously intended to have gone into Extended Key Usage, but evidence of existing certs proves the contrary.
1980 add_leaf_marker(options, &oidAppleExtendedKeyUsageAppleID);
1981
1982 // and validate that intermediate has extension with CSSMOID_APPLE_EXTENSION_AAI_INTERMEDIATE oid (1.2.840.113635.100.6.2.3) and goes back to the Apple Root CA.
1983 add_oid(options, kSecPolicyCheckIntermediateMarkerOid, &oidAppleIntmMarkerAppleID);
1984 add_oid(options, kSecPolicyCheckIntermediateMarkerOid, &oidAppleIntmMarkerAppleID2);
1985
1986 require(result = SecPolicyCreate(kSecPolicyOIDAppleIDAuthority, options), out);
1987
1988 out:
1989 CFReleaseSafe(options);
1990 return result;
1991 }
1992
1993 SecPolicyRef SecPolicyCreateMacAppStoreReceipt(void)
1994 {
1995 SecPolicyRef result = NULL;
1996 CFMutableDictionaryRef options = NULL;
1997 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
1998 &kCFTypeDictionaryKeyCallBacks,
1999 &kCFTypeDictionaryValueCallBacks), out);
2000
2001 SecPolicyAddBasicX509Options(options);
2002
2003 // Apple CA anchored
2004 require(SecPolicyAddAppleAnchorOptions(options), out);
2005
2006 // - leaf needs certificatePolicies with CSSMOID_MACAPPSTORE_RECEIPT_CERT_POLICY
2007 // - chain length must be 3
2008
2009 require(result = SecPolicyCreate(kSecPolicyOIDMacAppStoreReceipt, options), out);
2010
2011 out:
2012 CFReleaseSafe(options);
2013 return result;
2014
2015 }
2016
2017 static SecPolicyRef _SecPolicyCreatePassbookCardSigner(CFStringRef cardIssuer, CFStringRef teamIdentifier, bool requireTeamID)
2018 {
2019 SecPolicyRef result = NULL;
2020 CFMutableDictionaryRef options = NULL;
2021 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
2022 &kCFTypeDictionaryKeyCallBacks,
2023 &kCFTypeDictionaryValueCallBacks), out);
2024
2025 SecPolicyAddBasicX509Options(options);
2026 SecPolicyAddAppleAnchorOptions(options);
2027
2028 if (teamIdentifier) {
2029 // If supplied, teamIdentifier must match subject OU field
2030 CFDictionaryAddValue(options, kSecPolicyCheckSubjectOrganizationalUnit, teamIdentifier);
2031 }
2032 else {
2033 // If not supplied, and it was required, fail
2034 require(!requireTeamID, out);
2035 }
2036
2037 // Must be both push and 3rd party package signing
2038 add_leaf_marker_value(options, &oidAppleInstallerPackagingSigningExternal, cardIssuer);
2039
2040 // We should check that it also has push marker, but we don't support requiring both, only either.
2041 // add_independent_oid(options, kSecPolicyCheckLeafMarkerOid, &oidApplePushServiceClient);
2042
2043 // And Passbook signing eku
2044 add_eku(options, &oidAppleExtendedKeyUsagePassbook);
2045
2046 require(result = SecPolicyCreate(kSecPolicyOIDApplePassbook, options), out);
2047
2048 out:
2049 CFReleaseSafe(options);
2050 return result;
2051 }
2052
2053 SecPolicyRef SecPolicyCreatePassbookCardSigner(CFStringRef cardIssuer, CFStringRef teamIdentifier)
2054 {
2055 return _SecPolicyCreatePassbookCardSigner(cardIssuer, teamIdentifier, true);
2056 }
2057
2058
2059 static SecPolicyRef CreateMobileStoreSigner(Boolean forTest)
2060 {
2061
2062 SecPolicyRef result = NULL;
2063 CFMutableDictionaryRef options = NULL;
2064 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
2065 &kCFTypeDictionaryKeyCallBacks,
2066 &kCFTypeDictionaryValueCallBacks), errOut);
2067 SecPolicyAddBasicX509Options(options);
2068 SecPolicyAddAppleAnchorOptions(options);
2069
2070 require(SecPolicyAddChainLengthOptions(options, 3), errOut);
2071
2072 CFDictionaryAddValue(options, kSecPolicyCheckIssuerCommonName,
2073 CFSTR("Apple System Integration 2 Certification Authority"));
2074
2075 add_ku(options, kSecKeyUsageDigitalSignature);
2076
2077 const DERItem* pOID = (forTest) ? &oidApplePolicyTestMobileStore : &oidApplePolicyMobileStore;
2078
2079 add_certificate_policy_oid(options, pOID, NULL);
2080
2081 require(result = SecPolicyCreate(kSecPolicyOIDAppleMobileStore, options), errOut);
2082
2083 errOut:
2084 CFReleaseSafe(options);
2085 return result;
2086 }
2087
2088 SecPolicyRef SecPolicyCreateMobileStoreSigner(void)
2089 {
2090
2091 return CreateMobileStoreSigner(false);
2092 }
2093
2094 SecPolicyRef SecPolicyCreateTestMobileStoreSigner(void)
2095 {
2096
2097 return CreateMobileStoreSigner(true);
2098 }
2099
2100
2101 CF_RETURNS_RETAINED SecPolicyRef SecPolicyCreateEscrowServiceSigner(void)
2102 {
2103 SecPolicyRef result = NULL;
2104 CFMutableDictionaryRef options = NULL;
2105 CFArrayRef anArray = NULL;
2106 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
2107 &kCFTypeDictionaryKeyCallBacks,
2108 &kCFTypeDictionaryValueCallBacks), errOut);
2109
2110 // X509, ignoring date validity
2111 SecPolicyAddBasicCertOptions(options);
2112
2113
2114 add_ku(options, kSecKeyUsageKeyEncipherment);
2115
2116 //add_leaf_marker(options, &oidApplePolicyEscrowService);
2117 require(SecPolicyAddChainLengthOptions(options, 2), errOut);
2118
2119
2120 Boolean anchorAdded = false;
2121 // Get the roots by calling the SecCertificateCopyEscrowRoots
2122 anArray = SecCertificateCopyEscrowRoots(kSecCertificateProductionEscrowRoot);
2123 CFIndex numRoots = 0;
2124 if (NULL == anArray || 0 == (numRoots = CFArrayGetCount(anArray)))
2125 {
2126 goto errOut;
2127 }
2128
2129 for (CFIndex iCnt = 0; iCnt < numRoots; iCnt++)
2130 {
2131 SecCertificateRef aCert = (SecCertificateRef)CFArrayGetValueAtIndex(anArray, iCnt);
2132
2133 if (NULL != aCert)
2134 {
2135 CFDataRef sha_data = SecCertificateGetSHA1Digest(aCert);
2136 if (NULL != sha_data)
2137 {
2138 const UInt8* pSHAData = CFDataGetBytePtr(sha_data);
2139 if (NULL != pSHAData)
2140 {
2141 SecPolicyAddAnchorSHA1Options(options, pSHAData);
2142 anchorAdded = true;
2143 }
2144 }
2145 }
2146 }
2147 CFReleaseNull(anArray);
2148
2149 if (!anchorAdded)
2150 {
2151 goto errOut;
2152 }
2153
2154
2155 require(result = SecPolicyCreate(kSecPolicyOIDAppleEscrowService, options), errOut);
2156
2157 errOut:
2158 CFReleaseSafe(anArray);
2159 CFReleaseSafe(options);
2160 return result;
2161 }
2162
2163 CF_RETURNS_RETAINED SecPolicyRef SecPolicyCreatePCSEscrowServiceSigner(void)
2164 {
2165 SecPolicyRef result = NULL;
2166 CFMutableDictionaryRef options = NULL;
2167 CFArrayRef anArray = NULL;
2168 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
2169 &kCFTypeDictionaryKeyCallBacks,
2170 &kCFTypeDictionaryValueCallBacks), errOut);
2171
2172 SecPolicyAddBasicX509Options(options);
2173
2174
2175 add_ku(options, kSecKeyUsageKeyEncipherment);
2176
2177 //add_leaf_marker(options, &oidApplePolicyEscrowService);
2178 require(SecPolicyAddChainLengthOptions(options, 2), errOut);
2179
2180
2181 Boolean anchorAdded = false;
2182 anArray = SecCertificateCopyEscrowRoots(kSecCertificateProductionPCSEscrowRoot);
2183 CFIndex numRoots = 0;
2184 if (NULL == anArray || 0 == (numRoots = CFArrayGetCount(anArray)))
2185 {
2186 goto errOut;
2187 }
2188
2189 for (CFIndex iCnt = 0; iCnt < numRoots; iCnt++)
2190 {
2191 SecCertificateRef aCert = (SecCertificateRef)CFArrayGetValueAtIndex(anArray, iCnt);
2192
2193 if (NULL != aCert)
2194 {
2195 CFDataRef sha_data = SecCertificateGetSHA1Digest(aCert);
2196 if (NULL != sha_data)
2197 {
2198 const UInt8* pSHAData = CFDataGetBytePtr(sha_data);
2199 if (NULL != pSHAData)
2200 {
2201 SecPolicyAddAnchorSHA1Options(options, pSHAData);
2202 anchorAdded = true;
2203 }
2204 }
2205 }
2206 }
2207 CFReleaseNull(anArray);
2208
2209 if (!anchorAdded)
2210 {
2211 goto errOut;
2212 }
2213
2214
2215 require(result = SecPolicyCreate(kSecPolicyOIDApplePCSEscrowService, options), errOut);
2216
2217 errOut:
2218 CFReleaseSafe(anArray);
2219 CFReleaseSafe(options);
2220 return result;
2221 }
2222 SecCertificateRef SecPolicyCopyEscrowRootCertificate(void)
2223 {
2224 SecCertificateRef result = NULL;
2225
2226 return result;
2227 }
2228
2229 SecPolicyRef SecPolicyCreateConfigurationProfileSigner(void)
2230 {
2231 SecPolicyRef result = NULL;
2232 CFMutableDictionaryRef options = NULL;
2233 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
2234 &kCFTypeDictionaryKeyCallBacks,
2235 &kCFTypeDictionaryValueCallBacks), errOut);
2236
2237 SecPolicyAddBasicX509Options(options);
2238 SecPolicyAddAppleAnchorOptions(options);
2239
2240 // Require the profile signing EKU
2241 add_eku(options, &oidAppleExtendedKeyUsageProfileSigning);
2242
2243 require(result = SecPolicyCreate(kSecPolicyOIDAppleProfileSigner, options), errOut);
2244
2245 errOut:
2246 CFReleaseSafe(options);
2247 return result;
2248 }
2249
2250
2251 SecPolicyRef SecPolicyCreateQAConfigurationProfileSigner(void)
2252 {
2253 SecPolicyRef result = NULL;
2254 CFMutableDictionaryRef options = NULL;
2255 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
2256 &kCFTypeDictionaryKeyCallBacks,
2257 &kCFTypeDictionaryValueCallBacks), errOut);
2258
2259 SecPolicyAddBasicX509Options(options);
2260 SecPolicyAddAppleAnchorOptions(options);
2261
2262 // Require the QA profile signing EKU
2263 add_eku(options, &oidAppleExtendedKeyUsageQAProfileSigning);
2264
2265 require(result = SecPolicyCreate(kSecPolicyOIDAppleQAProfileSigner, options), errOut);
2266
2267 errOut:
2268 CFReleaseSafe(options);
2269 return result;
2270 }
2271
2272 SecPolicyRef SecPolicyCreateOSXProvisioningProfileSigning(void)
2273 {
2274 SecPolicyRef result = NULL;
2275 CFMutableDictionaryRef options = NULL;
2276 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
2277 &kCFTypeDictionaryKeyCallBacks,
2278 &kCFTypeDictionaryValueCallBacks), errOut);
2279 // Require valid chain from the Apple root
2280 SecPolicyAddBasicX509Options(options);
2281 SecPolicyAddAppleAnchorOptions(options);
2282
2283 // Require provisioning profile leaf marker OID (1.2.840.113635.100.4.11)
2284 add_leaf_marker(options, &oidAppleCertExtOSXProvisioningProfileSigning);
2285
2286 // Require intermediate marker OID (1.2.840.113635.100.6.2.1)
2287 add_oid(options, kSecPolicyCheckIntermediateMarkerOid, &oidAppleIntmMarkerAppleWWDR);
2288
2289 // Require key usage that allows signing
2290 add_ku(options, kSecKeyUsageDigitalSignature);
2291
2292 // Ensure that revocation is checked (OCSP)
2293 CFDictionaryAddValue(options, kSecPolicyCheckRevocation, kCFBooleanFalse);
2294
2295 require(result = SecPolicyCreate(kSecPolicyOIDAppleOSXProvisioningProfileSigning, options), errOut);
2296
2297 errOut:
2298 CFReleaseSafe(options);
2299 return result;
2300 }
2301
2302
2303 SecPolicyRef SecPolicyCreateOTAPKISigner(void)
2304 {
2305 SecPolicyRef result = NULL;
2306 CFMutableDictionaryRef options = NULL;
2307 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
2308 &kCFTypeDictionaryKeyCallBacks,
2309 &kCFTypeDictionaryValueCallBacks), errOut);
2310 SecPolicyAddBasicX509Options(options);
2311
2312 SecPolicyAddAnchorSHA1Options(options, kApplePKISettingsAuthority);
2313 require(SecPolicyAddChainLengthOptions(options, 2), errOut);
2314
2315 require(result = SecPolicyCreate(kSecPolicyOIDAppleOTAPKIAssetSigner, options), errOut);
2316
2317 errOut:
2318 CFReleaseSafe(options);
2319 return result;
2320
2321 }
2322
2323
2324 SecPolicyRef SecPolicyCreateTestOTAPKISigner(void)
2325 {
2326 SecPolicyRef result = NULL;
2327 CFMutableDictionaryRef options = NULL;
2328 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
2329 &kCFTypeDictionaryKeyCallBacks,
2330 &kCFTypeDictionaryValueCallBacks), errOut);
2331 SecPolicyAddBasicX509Options(options);
2332
2333 SecPolicyAddAnchorSHA1Options(options, kAppleTestPKISettingsAuthority);
2334 require(SecPolicyAddChainLengthOptions(options, 2), errOut);
2335
2336 require(result = SecPolicyCreate(kSecPolicyOIDAppleTestOTAPKIAssetSigner, options), errOut);
2337
2338 errOut:
2339 CFReleaseSafe(options);
2340 return result;
2341 }
2342
2343 /*!
2344 @function SecPolicyCreateAppleSMPEncryption
2345 @abstract Check for intermediate certificate 'Apple System Integration CA - G3' by name,
2346 and root certificate 'Apple Root CA - G3' by hash.
2347 Leaf cert must have Key Encipherment usage.
2348 Leaf cert must have Apple SMP Encryption marker OID (1.2.840.113635.100.6.30).
2349 Intermediate must have marker OID (1.2.840.113635.100.6.2.13).
2350 */
2351 SecPolicyRef SecPolicyCreateAppleSMPEncryption(void)
2352 {
2353 SecPolicyRef result = NULL;
2354 CFMutableDictionaryRef options = NULL;
2355 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
2356 &kCFTypeDictionaryKeyCallBacks,
2357 &kCFTypeDictionaryValueCallBacks), errOut);
2358 SecPolicyAddBasicCertOptions(options);
2359
2360 SecPolicyAddAnchorSHA1Options(options, kAppleRootCA_ECC_SHA1);
2361 require(SecPolicyAddChainLengthOptions(options, 3), errOut);
2362
2363 CFDictionaryAddValue(options, kSecPolicyCheckIssuerCommonName,
2364 CFSTR("Apple System Integration CA - G3"));
2365
2366 // Check that leaf has extension with "Apple SMP Encryption" oid (1.2.840.113635.100.6.30)
2367 add_leaf_marker(options, &oidAppleCertExtAppleSMPEncryption);
2368
2369 // Check that intermediate has extension (1.2.840.113635.100.6.2.13)
2370 add_oid(options, kSecPolicyCheckIntermediateMarkerOid, &oidAppleIntmMarkerAppleSystemIntgG3);
2371
2372 add_ku(options, kSecKeyUsageKeyEncipherment);
2373
2374 // Ensure that revocation is checked (OCSP)
2375 CFDictionaryAddValue(options, kSecPolicyCheckRevocation, kCFBooleanFalse);
2376
2377 require(result = SecPolicyCreate(kSecPolicyAppleSMPEncryption, options), errOut);
2378
2379 errOut:
2380 CFReleaseSafe(options);
2381 return result;
2382 }
2383
2384 /*!
2385 @function SecPolicyCreateTestAppleSMPEncryption
2386 @abstract Check for intermediate certificate 'Test Apple System Integration CA - ECC' by name,
2387 and root certificate 'Test Apple Root CA - ECC' by hash.
2388 Leaf cert must have Key Encipherment usage. Other checks TBD.
2389 */
2390 SecPolicyRef SecPolicyCreateTestAppleSMPEncryption(void)
2391 {
2392 SecPolicyRef result = NULL;
2393 CFMutableDictionaryRef options = NULL;
2394 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
2395 &kCFTypeDictionaryKeyCallBacks,
2396 &kCFTypeDictionaryValueCallBacks), errOut);
2397 SecPolicyAddBasicCertOptions(options);
2398
2399 SecPolicyAddAnchorSHA1Options(options, kTestAppleRootCA_ECC_SHA1);
2400 require(SecPolicyAddChainLengthOptions(options, 3), errOut);
2401
2402 CFDictionaryAddValue(options, kSecPolicyCheckIssuerCommonName,
2403 CFSTR("Test Apple System Integration CA - ECC"));
2404
2405 add_ku(options, kSecKeyUsageKeyEncipherment);
2406
2407 // Ensure that revocation is checked (OCSP)
2408 CFDictionaryAddValue(options, kSecPolicyCheckRevocation, kCFBooleanFalse);
2409
2410 require(result = SecPolicyCreate(kSecPolicyAppleTestSMPEncryption, options), errOut);
2411
2412 errOut:
2413 CFReleaseSafe(options);
2414 return result;
2415 }
2416
2417
2418 SecPolicyRef SecPolicyCreateAppleIDValidationRecordSigningPolicy(void)
2419 {
2420 SecPolicyRef result = NULL;
2421 CFMutableDictionaryRef options = NULL;
2422 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
2423 &kCFTypeDictionaryKeyCallBacks,
2424 &kCFTypeDictionaryValueCallBacks), errOut);
2425
2426 //Leaf appears to be a SSL only cert, so policy should expand on that policy
2427 SecPolicyAddBasicX509Options(options);
2428
2429 // Apple CA anchored
2430 require(SecPolicyAddAppleAnchorOptions(options), errOut);
2431
2432 // Check for an extension with " Apple ID Validation Record Signing" oid (1.2.840.113635.100.6.25)
2433 add_leaf_marker(options, &oidAppleCertExtensionAppleIDRecordValidationSigning);
2434
2435 // and validate that intermediate has extension
2436 // Application Integration Intermediate Certificate (1.2.840.113635.100.6.2.3)
2437 // and also validate that intermediate has extension
2438 // System Integration 2 Intermediate Certificate (1.2.840.113635.100.6.2.10)
2439 add_oid(options, kSecPolicyCheckIntermediateMarkerOid, &oidAppleIntmMarkerAppleID);
2440 add_oid(options, kSecPolicyCheckIntermediateMarkerOid, &oidAppleIntmMarkerAppleSystemIntg2);
2441
2442 // Ensure that revocation is checked (OCSP)
2443 CFDictionaryAddValue(options, kSecPolicyCheckRevocation, kCFBooleanFalse);
2444
2445 require(result = SecPolicyCreate(kSecPolicyOIDAppleIDValidationRecordSigningPolicy, options), errOut);
2446
2447 errOut:
2448 CFReleaseSafe(options);
2449 return result;
2450 }
2451
2452 static bool
2453 allowUATRoot(bool allowNonProd, CFStringRef service, CFDictionaryRef context)
2454 {
2455 bool UATAllowed = false;
2456 if (SecIsInternalRelease() || allowNonProd) {
2457 CFStringRef setting = CFStringCreateWithFormat(NULL, NULL, CFSTR("AppleServerAuthenticationAllowUAT%@"), service);
2458 CFTypeRef value = NULL;
2459 require(setting, fail);
2460
2461 if (context &&
2462 CFDictionaryGetValueIfPresent(context, setting, &value) &&
2463 isBoolean(value) &&
2464 CFBooleanGetValue(value))
2465 {
2466 UATAllowed = true;
2467 }
2468
2469 if (CFPreferencesGetAppBooleanValue(setting, CFSTR("com.apple.Security"), NULL)) {
2470 UATAllowed = true;
2471 }
2472 CFRelease(setting);
2473 }
2474 fail:
2475 return UATAllowed;
2476 }
2477
2478 static bool
2479 requirePinning(bool allowNonProd, CFStringRef service)
2480 {
2481 bool pinningRequired = true;
2482
2483 if (SecIsInternalRelease() || allowNonProd) {
2484 CFStringRef setting = CFStringCreateWithFormat(NULL, NULL, CFSTR("AppleServerAuthenticationNoPinning%@"), service);
2485 require(setting, fail);
2486 if (CFPreferencesGetAppBooleanValue(setting, CFSTR("com.apple.Security"), NULL))
2487 pinningRequired = false;
2488 CFRelease(setting);
2489 }
2490 fail:
2491 return pinningRequired;
2492 }
2493
2494 /*!
2495 @function SecPolicyCreateAppleServerAuthCommon
2496 @abstract Generic policy for server authentication Sub CAs
2497
2498 Allows control for both if pinning is required at all and if UAT environments should be added
2499 to the trust policy.
2500
2501 No pinning is for developer/QA that needs to use proxy to debug the protocol, while UAT
2502 environment is for QA/internal developer that have no need allow fake servers.
2503
2504 Both the noPinning and allowUAT are gated on that you run on internal hardware.
2505
2506 */
2507
2508 static SecPolicyRef
2509 SecPolicyCreateAppleServerAuthCommon(CFStringRef hostname,
2510 CFDictionaryRef __unused context,
2511 CFStringRef service, bool allowNonProd,
2512 const DERItem *leafMarkerOID,
2513 const DERItem *UATLeafMarkerOID)
2514 {
2515 CFMutableDictionaryRef appleAnchorOptions = NULL;
2516 CFMutableDictionaryRef options = NULL;
2517 SecPolicyRef result = NULL;
2518 CFDataRef oid = NULL, uatoid = NULL;
2519
2520 options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
2521 require(options, errOut);
2522
2523 SecPolicyAddBasicX509Options(options);
2524
2525 CFDictionaryAddValue(options, kSecPolicyCheckSSLHostname, hostname);
2526
2527 CFDictionaryAddValue(options, kSecPolicyCheckBlackListedLeaf, kCFBooleanTrue);
2528 CFDictionaryAddValue(options, kSecPolicyCheckGrayListedLeaf, kCFBooleanTrue);
2529
2530 add_eku(options, &oidExtendedKeyUsageServerAuth);
2531
2532 if (requirePinning(allowNonProd, service)) {
2533 bool allowUAT = allowUATRoot(allowNonProd, service, context);
2534
2535 /*
2536 * Require pinning to the Apple CA's (and if UAT environment,
2537 * include the Apple Test CA's as anchors).
2538 */
2539
2540 appleAnchorOptions = CFDictionaryCreateMutableForCFTypes(NULL);
2541 require(appleAnchorOptions, errOut);
2542
2543 if (allowUAT) {
2544 CFDictionarySetValue(appleAnchorOptions,
2545 kSecPolicyAppleAnchorIncludeTestRoots, kCFBooleanTrue);
2546 if (allowNonProd) {
2547 CFDictionarySetValue(appleAnchorOptions,
2548 kSecPolicyAppleAnchorAllowTestRootsOnProduction, kCFBooleanTrue);
2549 }
2550 }
2551
2552 add_element(options, kSecPolicyCheckAnchorApple, appleAnchorOptions);
2553
2554 /*
2555 * Check if we also should allow the UAT variant of the leafs
2556 * as some variants of the UAT environment uses that instead
2557 * of the test Apple CA's.
2558 */
2559
2560 if (allowUAT) {
2561 oid = CFDataCreate(kCFAllocatorDefault, leafMarkerOID->data, leafMarkerOID->length);
2562 require(oid, errOut);
2563
2564 uatoid = CFDataCreate(kCFAllocatorDefault, UATLeafMarkerOID->data, UATLeafMarkerOID->length);
2565 require(oid, errOut);
2566
2567 CFArrayRef array = CFArrayCreateForCFTypes(NULL, oid, uatoid, NULL);
2568 require(array, errOut);
2569
2570 add_element(options, kSecPolicyCheckLeafMarkerOid, array);
2571 CFReleaseSafe(array);
2572 } else {
2573 add_leaf_marker(options, leafMarkerOID);
2574
2575 }
2576 add_oid(options, kSecPolicyCheckIntermediateMarkerOid, &oidAppleIntmMarkerAppleServerAuthentication);
2577 }
2578
2579
2580 CFDictionaryAddValue(options, kSecPolicyCheckRevocation, kCFBooleanFalse);
2581
2582 result = SecPolicyCreate(kSecPolicyOIDSSLServer, options);
2583 require(result, errOut);
2584
2585 errOut:
2586 CFReleaseSafe(appleAnchorOptions);
2587 CFReleaseSafe(options);
2588 CFReleaseSafe(oid);
2589 CFReleaseSafe(uatoid);
2590 return result;
2591 }
2592
2593
2594
2595 /*!
2596 @function SecPolicyCreateAppleIDSService
2597 @abstract Ensure we're appropriately pinned to the IDS service (SSL + Apple restrictions)
2598 */
2599 SecPolicyRef SecPolicyCreateAppleIDSService(CFStringRef hostname)
2600 {
2601 #if 1
2602 return SecPolicyCreateSSL(true, hostname);
2603 #else
2604 return SecPolicyCreateAppleServerAuthCommon(hostname, NULL, CFSTR("IDS"), false,
2605 &oidAppleCertExtAppleServerAuthenticationIDSProd,
2606 &oidAppleCertExtAppleServerAuthenticationIDSTest);
2607 #endif
2608 }
2609
2610 /*!
2611 @function SecPolicyCreateAppleIDSService
2612 @abstract Ensure we're appropriately pinned to the IDS service (SSL + Apple restrictions)
2613 */
2614 SecPolicyRef SecPolicyCreateAppleIDSServiceContext(CFStringRef hostname, CFDictionaryRef context)
2615 {
2616 return SecPolicyCreateAppleServerAuthCommon(hostname, context, CFSTR("IDS"), false,
2617 &oidAppleCertExtAppleServerAuthenticationIDSProd,
2618 &oidAppleCertExtAppleServerAuthenticationIDSTest);
2619 }
2620
2621 /*!
2622 @function SecPolicyCreateAppleGSService
2623 @abstract Ensure we're appropriately pinned to the GS service
2624 */
2625 SecPolicyRef SecPolicyCreateAppleGSService(CFStringRef hostname, CFDictionaryRef context)
2626 {
2627 return SecPolicyCreateAppleServerAuthCommon(hostname, context, CFSTR("GS"), false,
2628 &oidAppleCertExtAppleServerAuthenticationGS,
2629 NULL);
2630 }
2631
2632 /*!
2633 @function SecPolicyCreateApplePushService
2634 @abstract Ensure we're appropriately pinned to the Push service (SSL + Apple restrictions)
2635 */
2636 SecPolicyRef SecPolicyCreateApplePushService(CFStringRef hostname, CFDictionaryRef context)
2637 {
2638 return SecPolicyCreateAppleServerAuthCommon(hostname, context, CFSTR("APN"), false,
2639 &oidAppleCertExtAppleServerAuthenticationAPNProd,
2640 &oidAppleCertExtAppleServerAuthenticationAPNTest);
2641 }
2642
2643 /*!
2644 @function SecPolicyCreateApplePPQService
2645 @abstract Ensure we're appropriately pinned to the PPQ service (SSL + Apple restrictions)
2646 */
2647 SecPolicyRef SecPolicyCreateApplePPQService(CFStringRef hostname, CFDictionaryRef context)
2648 {
2649 return SecPolicyCreateAppleServerAuthCommon(hostname, context, CFSTR("PPQ"), false,
2650 &oidAppleCertExtAppleServerAuthenticationPPQProd ,
2651 &oidAppleCertExtAppleServerAuthenticationPPQTest);
2652 }
2653
2654 /*!
2655 @function SecPolicyCreateAppleAST2Service
2656 @abstract Ensure we're appropriately pinned to the AST2 Diagnostic service (SSL + Apple restrictions)
2657 */
2658 SecPolicyRef SecPolicyCreateAppleAST2Service(CFStringRef hostname, CFDictionaryRef context)
2659 {
2660 return SecPolicyCreateAppleServerAuthCommon(hostname, context, CFSTR("AST2"), true,
2661 &oidAppleCertExtAST2DiagnosticsServerAuthProd,
2662 &oidAppleCertExtAST2DiagnosticsServerAuthTest);
2663 }
2664
2665 /* should use verbatim copy, but since this is the deprecated way, don't care right now */
2666 static const UInt8 entrustSPKIL1C[kSecPolicySHA256Size] = {
2667 0x54, 0x5b, 0xf9, 0x35, 0xe9, 0xad, 0xa1, 0xda,
2668 0x11, 0x7e, 0xdc, 0x3c, 0x2a, 0xcb, 0xc5, 0x6f,
2669 0xc0, 0x28, 0x09, 0x6c, 0x0e, 0x24, 0xbe, 0x9b,
2670 0x38, 0x94, 0xbe, 0x52, 0x2d, 0x1b, 0x43, 0xde
2671 };
2672
2673 /*!
2674 @function SecPolicyCreateApplePushServiceLegacy
2675 @abstract Ensure we're appropriately pinned to the Push service (via Entrust)
2676 */
2677 SecPolicyRef SecPolicyCreateApplePushServiceLegacy(CFStringRef hostname)
2678 {
2679 CFMutableDictionaryRef options = NULL;
2680 SecPolicyRef result = NULL;
2681 CFDataRef digest = NULL;
2682
2683 digest = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, entrustSPKIL1C, sizeof(entrustSPKIL1C), kCFAllocatorNull);
2684 require(digest, errOut);
2685
2686 options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
2687 require(options, errOut);
2688
2689 SecPolicyAddBasicX509Options(options);
2690
2691 CFDictionaryAddValue(options, kSecPolicyCheckSSLHostname, hostname);
2692
2693 CFDictionaryAddValue(options, kSecPolicyCheckBlackListedLeaf, kCFBooleanTrue);
2694 CFDictionaryAddValue(options, kSecPolicyCheckGrayListedLeaf, kCFBooleanTrue);
2695
2696 CFDictionaryAddValue(options, kSecPolicyCheckIntermediateSPKISHA256, digest);
2697
2698 add_eku(options, &oidExtendedKeyUsageServerAuth);
2699
2700 CFDictionaryAddValue(options, kSecPolicyCheckRevocation, kCFBooleanFalse);
2701
2702 result = SecPolicyCreate(kSecPolicyOIDSSLServer, options);
2703 require(result, errOut);
2704
2705 errOut:
2706 CFReleaseSafe(digest);
2707 CFReleaseSafe(options);
2708 return result;
2709 }
2710
2711 /*!
2712 @function SecPolicyCreateAppleMMCSService
2713 @abstract Ensure we're appropriately pinned to the IDS service (SSL + Apple restrictions)
2714 */
2715 SecPolicyRef SecPolicyCreateAppleMMCSService(CFStringRef hostname, CFDictionaryRef __unused context)
2716 {
2717 return SecPolicyCreateSSL(true, hostname);
2718 }
2719
2720 /*!
2721 @function SecPolicyCreateAppleSSLService
2722 @abstract Ensure we're appropriately pinned to an Apple server (SSL + Apple restrictions)
2723 */
2724 SecPolicyRef SecPolicyCreateAppleSSLService(CFStringRef hostname)
2725 {
2726 // SSL server, pinned to an Apple intermediate
2727 SecPolicyRef policy = SecPolicyCreateSSL(true, hostname);
2728 CFMutableDictionaryRef options = NULL;
2729 require(policy, errOut);
2730
2731 // change options for SSL policy evaluation
2732 require((options=(CFMutableDictionaryRef)policy->_options) != NULL, errOut);
2733
2734 // Apple CA anchored
2735 require(SecPolicyAddAppleAnchorOptions(options), errOut);
2736
2737 // Check leaf for Apple Server Authentication marker oid (1.2.840.113635.100.6.27.1)
2738 add_leaf_marker(options, &oidAppleCertExtAppleServerAuthentication);
2739
2740 // Check intermediate for Apple Server Authentication intermediate marker (1.2.840.113635.100.6.2.12)
2741 add_oid(options, kSecPolicyCheckIntermediateMarkerOid, &oidAppleIntmMarkerAppleServerAuthentication);
2742
2743 // Ensure that revocation is checked (OCSP only)
2744 CFDictionaryAddValue(options, kSecPolicyCheckRevocation, kCFBooleanFalse);
2745
2746 return policy;
2747
2748 errOut:
2749 CFReleaseSafe(options);
2750 CFReleaseSafe(policy);
2751 return NULL;
2752 }
2753
2754 /*!
2755 @function SecPolicyCreateApplePPQSigning
2756 @abstract Check for intermediate certificate 'Apple System Integration 2 Certification Authority' by name,
2757 and apple anchor.
2758 Leaf cert must have Digital Signature usage.
2759 Leaf cert must have Apple PPQ Signing marker OID (1.2.840.113635.100.6.38.2).
2760 Intermediate must have marker OID (1.2.840.113635.100.6.2.10).
2761 */
2762 SecPolicyRef SecPolicyCreateApplePPQSigning(void)
2763 {
2764 SecPolicyRef result = NULL;
2765 CFMutableDictionaryRef options = NULL;
2766 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
2767 &kCFTypeDictionaryKeyCallBacks,
2768 &kCFTypeDictionaryValueCallBacks), errOut);
2769 SecPolicyAddBasicCertOptions(options);
2770
2771 SecPolicyAddAppleAnchorOptions(options);
2772 require(SecPolicyAddChainLengthOptions(options, 3), errOut);
2773
2774 CFDictionaryAddValue(options, kSecPolicyCheckIssuerCommonName,
2775 CFSTR("Apple System Integration 2 Certification Authority"));
2776
2777 // Check that leaf has extension with "Apple PPQ Signing" prod oid (1.2.840.113635.100.6.38.2)
2778 add_leaf_marker(options, &oidAppleCertExtApplePPQSigningProd);
2779
2780 // Check that intermediate has extension (1.2.840.113635.100.6.2.10)
2781 add_oid(options, kSecPolicyCheckIntermediateMarkerOid, &oidAppleIntmMarkerAppleSystemIntg2);
2782
2783 add_ku(options, kSecKeyUsageDigitalSignature);
2784
2785 require(result = SecPolicyCreate(kSecPolicyApplePPQSigning, options), errOut);
2786
2787 errOut:
2788 CFReleaseSafe(options);
2789 return result;
2790 }
2791
2792 /*!
2793 @function SecPolicyCreateTestApplePPQSigning
2794 @abstract Check for intermediate certificate 'Apple System Integration 2 Certification Authority' by name,
2795 and apple anchor.
2796 Leaf cert must have Digital Signature usage.
2797 Leaf cert must have Apple PPQ Signing Test marker OID (1.2.840.113635.100.6.38.1).
2798 Intermediate must have marker OID (1.2.840.113635.100.6.2.10).
2799 */
2800 SecPolicyRef SecPolicyCreateTestApplePPQSigning(void)
2801 {
2802 SecPolicyRef result = NULL;
2803 CFMutableDictionaryRef options = NULL;
2804 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
2805 &kCFTypeDictionaryKeyCallBacks,
2806 &kCFTypeDictionaryValueCallBacks), errOut);
2807 SecPolicyAddBasicCertOptions(options);
2808
2809 SecPolicyAddAppleAnchorOptions(options);
2810 require(SecPolicyAddChainLengthOptions(options, 3), errOut);
2811
2812 CFDictionaryAddValue(options, kSecPolicyCheckIssuerCommonName,
2813 CFSTR("Apple System Integration 2 Certification Authority"));
2814
2815 // Check that leaf has extension with "Apple PPQ Signing" test oid (1.2.840.113635.100.6.38.1)
2816 add_leaf_marker(options, &oidAppleCertExtApplePPQSigningTest);
2817
2818 // Check that intermediate has extension (1.2.840.113635.100.6.2.10)
2819 add_oid(options, kSecPolicyCheckIntermediateMarkerOid, &oidAppleIntmMarkerAppleSystemIntg2);
2820
2821 add_ku(options, kSecKeyUsageDigitalSignature);
2822
2823 require(result = SecPolicyCreate(kSecPolicyAppleTestPPQSigning, options), errOut);
2824
2825 errOut:
2826 CFReleaseSafe(options);
2827 return result;
2828 }
2829 /*!
2830 @function SecPolicyCreateAppleTimeStamping
2831 @abstract Check for RFC3161 timestamping EKU.
2832 */
2833 SecPolicyRef SecPolicyCreateAppleTimeStamping(void)
2834 {
2835 SecPolicyRef result = NULL;
2836 CFMutableDictionaryRef options = NULL;
2837 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
2838 &kCFTypeDictionaryKeyCallBacks,
2839 &kCFTypeDictionaryValueCallBacks), errOut);
2840
2841 SecPolicyAddBasicX509Options(options);
2842
2843 /* Require id-kp-timeStamping extendedKeyUsage to be present. */
2844 add_eku(options, &oidExtendedKeyUsageTimeStamping);
2845
2846 require(result = SecPolicyCreate(kSecPolicyOIDAppleTimeStamping, options), errOut);
2847
2848 errOut:
2849 CFReleaseSafe(options);
2850 return result;
2851 }
2852
2853 /*!
2854 @function SecPolicyCreateAppleATVAppSigning
2855 @abstract Check for intermediate certificate 'Apple Worldwide Developer Relations Certification Authority' by name,
2856 and apple anchor.
2857 Leaf cert must have Digital Signature usage.
2858 Leaf cert must have Apple ATV App Signing marker OID (1.2.840.113635.100.6.1.24).
2859 Leaf cert must have 'Apple TVOS Application Signing' common name.
2860 */
2861 SecPolicyRef SecPolicyCreateAppleATVAppSigning(void)
2862 {
2863 SecPolicyRef result = NULL;
2864 CFMutableDictionaryRef options = NULL;
2865 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
2866 &kCFTypeDictionaryKeyCallBacks,
2867 &kCFTypeDictionaryValueCallBacks), errOut);
2868 SecPolicyAddBasicCertOptions(options);
2869
2870 require(SecPolicyAddAppleAnchorOptions(options), errOut);
2871 require(SecPolicyAddChainLengthOptions(options, 3), errOut);
2872
2873 CFDictionaryAddValue(options, kSecPolicyCheckIssuerCommonName,
2874 CFSTR("Apple Worldwide Developer Relations Certification Authority"));
2875 CFDictionaryAddValue(options, kSecPolicyCheckSubjectCommonName,
2876 CFSTR("Apple TVOS Application Signing"));
2877
2878 // Check that leaf has extension with "Apple ATV App Signing" prod oid (1.2.840.113635.100.6.1.24)
2879 add_leaf_marker(options, &oidAppleCertExtATVAppSigningProd);
2880
2881 add_ku(options, kSecKeyUsageDigitalSignature);
2882
2883 require(result = SecPolicyCreate(kSecPolicyAppleATVAppSigning, options), errOut);
2884
2885 errOut:
2886 CFReleaseSafe(options);
2887 return result;
2888 }
2889
2890 /*!
2891 @function SecPolicyCreateTestAppleATVAppSigning
2892 @abstract Check for intermediate certificate 'Apple Worldwide Developer Relations Certification Authority' by name,
2893 and apple anchor.
2894 Leaf cert must have Digital Signature usage.
2895 Leaf cert must have Apple ATV App Signing Test marker OID (1.2.840.113635.100.6.1.24.1).
2896 Leaf cert must have 'TEST Apple TVOS Application Signing TEST' common name.
2897 */
2898 SecPolicyRef SecPolicyCreateTestAppleATVAppSigning(void)
2899 {
2900 SecPolicyRef result = NULL;
2901 CFMutableDictionaryRef options = NULL;
2902 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
2903 &kCFTypeDictionaryKeyCallBacks,
2904 &kCFTypeDictionaryValueCallBacks), errOut);
2905 SecPolicyAddBasicCertOptions(options);
2906
2907 require(SecPolicyAddAppleAnchorOptions(options), errOut);
2908 require(SecPolicyAddChainLengthOptions(options, 3), errOut);
2909
2910 CFDictionaryAddValue(options, kSecPolicyCheckIssuerCommonName,
2911 CFSTR("Apple Worldwide Developer Relations Certification Authority"));
2912 CFDictionaryAddValue(options, kSecPolicyCheckSubjectCommonName,
2913 CFSTR("TEST Apple TVOS Application Signing TEST"));
2914
2915 // Check that leaf has extension with "Apple ATV App Signing" test oid (1.2.840.113635.100.6.1.24.1)
2916 add_leaf_marker(options, &oidAppleCertExtATVAppSigningTest);
2917
2918 add_ku(options, kSecKeyUsageDigitalSignature);
2919
2920 require(result = SecPolicyCreate(kSecPolicyAppleTestATVAppSigning, options), errOut);
2921
2922 errOut:
2923 CFReleaseSafe(options);
2924 return result;
2925 }
2926
2927 /*!
2928 @function SecPolicyCreateApplePayIssuerEncryption
2929 @abstract Check for intermediate certificate 'Apple Worldwide Developer Relations CA - G2' by name,
2930 and ECC apple anchor.
2931 Leaf cert must have Key Encipherment and Key Agreement usage.
2932 Leaf cert must have Apple Pay Issuer Encryption marker OID (1.2.840.113635.100.6.39).
2933 */
2934 SecPolicyRef SecPolicyCreateApplePayIssuerEncryption(void)
2935 {
2936 SecPolicyRef result = NULL;
2937 CFMutableDictionaryRef options = NULL;
2938 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
2939 &kCFTypeDictionaryKeyCallBacks,
2940 &kCFTypeDictionaryValueCallBacks), errOut);
2941 SecPolicyAddBasicCertOptions(options);
2942
2943 require(SecPolicyAddAnchorSHA1Options(options, kAppleRootCA_ECC_SHA1), errOut);
2944 require(SecPolicyAddChainLengthOptions(options, 3), errOut);
2945
2946 CFDictionaryAddValue(options, kSecPolicyCheckIssuerCommonName,
2947 CFSTR("Apple Worldwide Developer Relations CA - G2"));
2948
2949 // Check that leaf has extension with "Apple Pay Issuer Encryption" oid (1.2.840.113635.100.6.39)
2950 add_leaf_marker(options, &oidAppleCertExtCryptoServicesExtEncryption);
2951
2952 add_ku(options, kSecKeyUsageKeyEncipherment);
2953
2954 require(result = SecPolicyCreate(kSecPolicyApplePayIssuerEncryption, options), errOut);
2955
2956 errOut:
2957 CFReleaseSafe(options);
2958 return result;
2959 }
2960
2961 /*!
2962 @function SecPolicyCreateAppleATVVPNProfileSigning
2963 @abstract Check for leaf marker OID 1.2.840.113635.100.6.43,
2964 intermediate marker OID 1.2.840.113635.100.6.2.10,
2965 chains to Apple Root CA, path length 3
2966 */
2967 SecPolicyRef SecPolicyCreateAppleATVVPNProfileSigning(void)
2968 {
2969 SecPolicyRef result = NULL;
2970 CFMutableDictionaryRef options = NULL;
2971 CFMutableDictionaryRef appleAnchorOptions = NULL;
2972 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
2973 &kCFTypeDictionaryKeyCallBacks,
2974 &kCFTypeDictionaryValueCallBacks), errOut);
2975
2976 SecPolicyAddBasicCertOptions(options);
2977
2978 // Require pinning to the Apple CAs (including test CA for internal releases)
2979 appleAnchorOptions = CFDictionaryCreateMutableForCFTypes(NULL);
2980 require(appleAnchorOptions, errOut);
2981
2982 if (SecIsInternalRelease()) {
2983 CFDictionarySetValue(appleAnchorOptions,
2984 kSecPolicyAppleAnchorIncludeTestRoots, kCFBooleanTrue);
2985 }
2986
2987 add_element(options, kSecPolicyCheckAnchorApple, appleAnchorOptions);
2988
2989 // Cert chain length 3
2990 require(SecPolicyAddChainLengthOptions(options, 3), errOut);
2991
2992 // Check leaf for Apple ATV VPN Profile Signing OID (1.2.840.113635.100.6.43)
2993 add_leaf_marker(options, &oidAppleCertExtATVVPNProfileSigning);
2994
2995 // Check intermediate for Apple System Integration 2 CA intermediate marker (1.2.840.113635.100.6.2.10)
2996 add_oid(options, kSecPolicyCheckIntermediateMarkerOid, &oidAppleIntmMarkerAppleSystemIntg2);
2997
2998 // Ensure that revocation is checked (OCSP only)
2999 CFDictionaryAddValue(options, kSecPolicyCheckRevocation, kCFBooleanFalse);
3000
3001 require(result = SecPolicyCreate(kSecPolicyAppleATVVPNProfileSigning, options), errOut);
3002
3003 errOut:
3004 CFReleaseSafe(options);
3005 CFReleaseSafe(appleAnchorOptions);
3006 return result;
3007 }