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