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