2 * Copyright (c) 2007-2014 Apple Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
25 * SecPolicy.c - Implementation of various X.509 certificate trust policies
28 #include <Security/SecPolicyInternal.h>
29 #include <Security/SecPolicyPriv.h>
30 #include <AssertMacros.h>
32 #include <utilities/debugging.h>
33 #include <Security/SecInternal.h>
34 #include <CoreFoundation/CFDictionary.h>
35 #include <CoreFoundation/CFNumber.h>
36 #include <CoreFoundation/CFRuntime.h>
37 #include <CoreFoundation/CFString.h>
38 #include <CoreFoundation/CFTimeZone.h>
39 #include <Security/SecCertificateInternal.h>
40 #include <Security/SecCertificatePriv.h>
41 #include <libDER/oids.h>
42 #include <utilities/SecCFError.h>
43 #include <utilities/SecCFWrappers.h>
44 #include <utilities/array_size.h>
45 #include <ipc/securityd_client.h>
47 /********************************************************
48 **************** SecPolicy Constants *******************
49 ********************************************************/
51 // MARK: SecPolicy Constants
53 #define SEC_CONST_DECL(k,v) CFTypeRef k = (CFTypeRef)(CFSTR(v));
55 /********************************************************
56 ************** Unverified Leaf Checks ******************
57 ********************************************************/
58 CFStringRef kSecPolicyCheckSSLHostname
= CFSTR("SSLHostname");
60 CFStringRef kSecPolicyCheckEmail
= CFSTR("email");
62 /* Checks that the issuer of the leaf has exactly one Common Name and that it
63 matches the specified string. */
64 CFStringRef kSecPolicyCheckIssuerCommonName
= CFSTR("IssuerCommonName");
66 /* Checks that the leaf has exactly one Common Name and that it
67 matches the specified string. */
68 CFStringRef kSecPolicyCheckSubjectCommonName
= CFSTR("SubjectCommonName");
70 /* Checks that the leaf has exactly one Common Name and that it has the
71 specified string as a prefix. */
72 CFStringRef kSecPolicyCheckSubjectCommonNamePrefix
= CFSTR("SubjectCommonNamePrefix");
74 /* Checks that the leaf has exactly one Common Name and that it
75 matches the specified "<string>" or "TEST <string> TEST". */
76 CFStringRef kSecPolicyCheckSubjectCommonNameTEST
= CFSTR("SubjectCommonNameTEST");
78 /* Checks that the leaf has exactly one Organization and that it
79 matches the specified string. */
80 CFStringRef kSecPolicyCheckSubjectOrganization
= CFSTR("SubjectOrganization");
82 /* Checks that the leaf has exactly one Organizational Unit and that it
83 matches the specified string. */
84 CFStringRef kSecPolicyCheckSubjectOrganizationalUnit
= CFSTR("SubjectOrganizationalUnit");
86 /* Check that the leaf is not valid before the specified date (or verifyDate
87 if none is provided?). */
88 CFStringRef kSecPolicyCheckNotValidBefore
= CFSTR("NotValidBefore");
90 CFStringRef kSecPolicyCheckEAPTrustedServerNames
= CFSTR("EAPTrustedServerNames");
92 CFStringRef kSecPolicyCheckCertificatePolicy
= CFSTR("CertificatePolicy");
95 /* Check for basic constraints on leaf to be valid. (rfc5280 check) */
96 CFStringRef kSecPolicyCheckLeafBasicConstraints
= CFSTR("LeafBasicContraints");
99 /********************************************************
100 *********** Unverified Intermediate Checks *************
101 ********************************************************/
102 CFStringRef kSecPolicyCheckKeyUsage
= CFSTR("KeyUsage"); /* (rfc5280 check) */
103 CFStringRef kSecPolicyCheckExtendedKeyUsage
= CFSTR("ExtendedKeyUsage"); /* (rfc5280 check) */
104 CFStringRef kSecPolicyCheckBasicContraints
= CFSTR("BasicContraints"); /* (rfc5280 check) */
105 CFStringRef kSecPolicyCheckQualifiedCertStatements
=
106 CFSTR("QualifiedCertStatements"); /* (rfc5280 check) */
108 /********************************************************
109 ************** Unverified Anchor Checks ****************
110 ********************************************************/
111 CFStringRef kSecPolicyCheckAnchorSHA1
= CFSTR("AnchorSHA1");
113 /* Fake key for isAnchored check. */
114 CFStringRef kSecPolicyCheckAnchorTrusted
= CFSTR("AnchorTrusted");
116 /********************************************************
117 *********** Unverified Certificate Checks **************
118 ********************************************************/
119 /* Unverified Certificate Checks (any of the above) */
120 CFStringRef kSecPolicyCheckNonEmptySubject
= CFSTR("NonEmptySubject");
121 CFStringRef kSecPolicyCheckIdLinkage
= CFSTR("IdLinkage"); /* (rfc5280 check) */
123 CFStringRef kSecPolicyCheckValidityStarted
= CFSTR("ValidStarted");
124 CFStringRef kSecPolicyCheckValidityExpired
= CFSTR("ValidExpired");
126 CFStringRef kSecPolicyCheckValidIntermediates
= CFSTR("ValidIntermediates");
127 CFStringRef kSecPolicyCheckValidLeaf
= CFSTR("ValidLeaf");
128 CFStringRef kSecPolicyCheckValidRoot
= CFSTR("ValidRoot");
132 /********************************************************
133 **************** Verified Path Checks ******************
134 ********************************************************/
135 /* (rfc5280 check) Ideally we should dynamically track all the extensions
136 we processed for each certificate and fail this test if any critical
137 extensions remain. */
138 CFStringRef kSecPolicyCheckCriticalExtensions
= CFSTR("CriticalExtensions");
140 /* Check that the certificate chain length matches the specificed CFNumberRef
142 CFStringRef kSecPolicyCheckChainLength
= CFSTR("ChainLength");
144 /* (rfc5280 check) */
145 CFStringRef kSecPolicyCheckBasicCertificateProcessing
=
146 CFSTR("BasicCertificateProcessing");
148 /********************************************************
149 ******************* Feature toggles ********************
150 ********************************************************/
152 /* Check revocation if specified. */
153 CFStringRef kSecPolicyCheckExtendedValidation
= CFSTR("ExtendedValidation");
154 CFStringRef kSecPolicyCheckRevocation
= CFSTR("Revocation");
156 /* If present and true, we never go out to the network for anything
157 (OCSP, CRL or CA Issuer checking) but just used cached data instead. */
158 CFStringRef kSecPolicyCheckNoNetworkAccess
= CFSTR("NoNetworkAccess");
160 /* Hack to quickly blacklist certain certs. */
161 CFStringRef kSecPolicyCheckBlackListedLeaf
= CFSTR("BlackListedLeaf");
162 CFStringRef kSecPolicyCheckGrayListedLeaf
= CFSTR("GrayListedLeaf");
163 CFStringRef kSecPolicyCheckGrayListedKey
= CFSTR("GrayListedKey");
164 CFStringRef kSecPolicyCheckBlackListedKey
= CFSTR("BlackListedKey");
166 CFStringRef kSecPolicyCheckLeafMarkerOid
= CFSTR("CheckLeafMarkerOid");
167 CFStringRef kSecPolicyCheckIntermediateMarkerOid
= CFSTR("CheckIntermediateMarkerOid");
169 /* Public policy names. */
170 SEC_CONST_DECL (kSecPolicyAppleX509Basic
, "1.2.840.113635.100.1.2");
171 SEC_CONST_DECL (kSecPolicyAppleSSL
, "1.2.840.113635.100.1.3");
172 SEC_CONST_DECL (kSecPolicyAppleSMIME
, "1.2.840.113635.100.1.8");
173 SEC_CONST_DECL (kSecPolicyAppleEAP
, "1.2.840.113635.100.1.9");
174 SEC_CONST_DECL (kSecPolicyAppleIPsec
, "1.2.840.113635.100.1.11");
175 SEC_CONST_DECL (kSecPolicyApplePKINITClient
, "1.2.840.113635.100.1.14");
176 SEC_CONST_DECL (kSecPolicyApplePKINITServer
, "1.2.840.113635.100.1.15");
177 SEC_CONST_DECL (kSecPolicyAppleCodeSigning
, "1.2.840.113635.100.1.16");
178 SEC_CONST_DECL (kSecPolicyApplePackageSigning
, "1.2.840.113635.100.1.17");
179 SEC_CONST_DECL (kSecPolicyAppleIDValidation
, "1.2.840.113635.100.1.18");
180 SEC_CONST_DECL (kSecPolicyMacAppStoreReceipt
, "1.2.840.113635.100.1.19");
181 SEC_CONST_DECL (kSecPolicyAppleTimeStamping
, "1.2.840.113635.100.1.20");
182 SEC_CONST_DECL (kSecPolicyAppleRevocation
, "1.2.840.113635.100.1.21");
183 SEC_CONST_DECL (kSecPolicyApplePassbookSigning
, "1.2.840.113635.100.1.22");
184 SEC_CONST_DECL (kSecPolicyAppleMobileStore
, "1.2.840.113635.100.1.23");
185 SEC_CONST_DECL (kSecPolicyAppleEscrowService
, "1.2.840.113635.100.1.24");
186 SEC_CONST_DECL (kSecPolicyAppleProfileSigner
, "1.2.840.113635.100.1.25");
187 SEC_CONST_DECL (kSecPolicyAppleQAProfileSigner
, "1.2.840.113635.100.1.26");
188 SEC_CONST_DECL (kSecPolicyAppleTestMobileStore
, "1.2.840.113635.100.1.27");
190 SEC_CONST_DECL (kSecPolicyAppleOTAPKISigner
, "1.2.840.113635.100.1.28");
191 SEC_CONST_DECL (kSecPolicyAppleTestOTAPKISigner
, "1.2.840.113635.100.1.29");
192 /* FIXME: this policy name should be deprecated and replaced with "kSecPolicyAppleIDValidationRecordSigning" */
193 SEC_CONST_DECL (kSecPolicyAppleIDValidationRecordSigningPolicy
, "1.2.840.113625.100.1.30");
194 SEC_CONST_DECL (kSecPolicyAppleSMPEncryption
, "1.2.840.113625.100.1.31");
195 SEC_CONST_DECL (kSecPolicyAppleTestSMPEncryption
, "1.2.840.113625.100.1.32");
197 SEC_CONST_DECL (kSecPolicyAppleServerAuthentication
, "1.2.840.113635.100.1.33");
198 SEC_CONST_DECL (kSecPolicyApplePCSEscrowService
, "1.2.840.113635.100.1.34");
200 SEC_CONST_DECL (kSecPolicyOid
, "SecPolicyOid");
201 SEC_CONST_DECL (kSecPolicyName
, "SecPolicyName");
202 SEC_CONST_DECL (kSecPolicyClient
, "SecPolicyClient");
203 SEC_CONST_DECL (kSecPolicyRevocationFlags
, "SecPolicyRevocationFlags");
204 SEC_CONST_DECL (kSecPolicyTeamIdentifier
, "SecPolicyTeamIdentifier");
206 /* Private policy names */
207 static CFStringRef kSecPolicyOIDBasicX509
= CFSTR("basicX509");
208 static CFStringRef kSecPolicyOIDSSLServer
= CFSTR("sslServer");
209 static CFStringRef kSecPolicyOIDSSLClient
= CFSTR("sslClient");
210 static CFStringRef kSecPolicyOIDiPhoneActivation
= CFSTR("iPhoneActivation");
211 static CFStringRef kSecPolicyOIDiPhoneDeviceCertificate
=
212 CFSTR("iPhoneDeviceCertificate");
213 static CFStringRef kSecPolicyOIDFactoryDeviceCertificate
=
214 CFSTR("FactoryDeviceCertificate");
215 static CFStringRef kSecPolicyOIDiAP
= CFSTR("iAP");
216 static CFStringRef kSecPolicyOIDiTunesStoreURLBag
= CFSTR("iTunesStoreURLBag");
217 static CFStringRef kSecPolicyEAPServer
= CFSTR("eapServer");
218 static CFStringRef kSecPolicyEAPClient
= CFSTR("eapClient");
219 static CFStringRef kSecPolicyOIDIPSecServer
= CFSTR("ipsecServer");
220 static CFStringRef kSecPolicyOIDIPSecClient
= CFSTR("ipsecClient");
221 static CFStringRef kSecPolicyOIDiPhoneApplicationSigning
=
222 CFSTR("iPhoneApplicationSigning");
223 static CFStringRef kSecPolicyOIDiPhoneProfileApplicationSigning
=
224 CFSTR("iPhoneProfileApplicationSigning");
225 static CFStringRef kSecPolicyOIDiPhoneProvisioningProfileSigning
=
226 CFSTR("iPhoneProvisioningProfileSigning");
227 static CFStringRef kSecPolicyOIDRevocation
= CFSTR("revocation");
228 static CFStringRef kSecPolicyOIDOCSPSigner
= CFSTR("OCSPSigner");
229 static CFStringRef kSecPolicyOIDSMIME
= CFSTR("SMIME");
230 static CFStringRef kSecPolicyOIDCodeSigning
= CFSTR("CodeSigning");
231 static CFStringRef kSecPolicyOIDLockdownPairing
= CFSTR("LockdownPairing");
232 static CFStringRef kSecPolicyOIDURLBag
= CFSTR("URLBag");
233 static CFStringRef kSecPolicyOIDOTATasking
= CFSTR("OTATasking");
234 static CFStringRef kSecPolicyOIDMobileAsset
= CFSTR("MobileAsset");
235 static CFStringRef kSecPolicyOIDAppleIDAuthority
= CFSTR("AppleIDAuthority");
236 static CFStringRef kSecPolicyOIDAppleShoebox
= CFSTR("AppleShoebox");
237 static CFStringRef kSecPolicyOIDApplePassbook
= CFSTR("ApplePassbook");
238 static CFStringRef kSecPolicyOIDAppleMobileStore
= CFSTR("AppleMobileStore");
239 static CFStringRef kSecPolicyOIDAppleTestMobileStore
= CFSTR("AppleTestMobileStore");
240 static CFStringRef kSecPolicyOIDAppleEscrowService
= CFSTR("AppleEscrowService");
241 static CFStringRef kSecPolicyOIDApplePCSEscrowService
= CFSTR("ApplePCSEscrowService");
242 static CFStringRef kSecPolicyOIDAppleProfileSigner
= CFSTR("AppleProfileSigner");
243 static CFStringRef kSecPolicyOIDAppleQAProfileSigner
= CFSTR("AppleQAProfileSigner");
244 static CFStringRef kSecPolicyOIDAppleOTAPKIAssetSigner
= CFSTR("AppleOTAPKIAssetSigner");
245 static CFStringRef kSecPolicyOIDAppleTestOTAPKIAssetSigner
= CFSTR("AppleTestOTAPKIAssetSigner");
246 static CFStringRef kSecPolicyOIDAppleIDValidationRecordSigningPolicy
= CFSTR("AppleIDValidationRecordSigningPolicy");
249 /* Policies will now change to multiple categories of checks.
251 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.
252 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.
254 kSecPolicySLCheck Static Subscriber Certificate Checks
255 kSecPolicySICheck Static Subsidiary CA Checks
256 kSecPolicySACheck Static Anchor Checks
258 kSecPolicyDLCheck Dynamic Subscriber Certificate Checks
259 kSecPolicyDICheck Dynamic Subsidiary CA Checks
260 kSecPolicyDACheck Dynamic Anchor Checks ? not yet needed other than to
261 possibly exclude in a exception template (but those should still be per
262 certificate --- i.o.w. exceptions (or a database backed multiple role/user
263 trust store of some sort) and policies are 2 different things and this
264 text is about policies.
266 All static checks are only allowed to consider the certificate in isolation,
267 just given the position in the chain or the cert (leaf, intermidate, root).
268 dynamic checks can make determinations about the chain as a whole.
270 Static Subscriber Certificate Checks will be done up front before the
271 chainbuilder is even instantiated. If they fail and details aren't required
272 by the client (if no exceptions were present for this certificate) we could
273 short circuit fail the evaluation.
274 IDEA: These checks can dynamically add new checks...[needs work]
275 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
276 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
277 equivalent subtree from that level down. So SSL has EV as a subpolicy, but
278 EV dynamically enables the ocsp or crl or dcrl or any combination thereof subpolicies.
280 Static Subsidiary CA Checks will be used by the chain-builder to choose the
281 best parents to evaluate first. This feature is currently already implemented
282 but with a hardcoded is_valid(verifyTime) check. Instead we will evaluate all
283 Static Subsidiary CA Checks. The results of these checks for purposes of
284 generating details could be cached in the SecCertificatePathRefs themselves, or we can short circuit fail and recalc details on demand later.
286 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.
288 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.
290 Dynamic Subsidiary CA Checks might not be needed to have custom
291 implementations, since they are all done as part of the rfc5280 checks now.
292 This assumes that checks like issuer common name includes 'foo' are
293 implmented as Static Subscriber Certificate Checks instead.
295 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.
298 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.
300 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.
302 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.
304 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.
306 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.
308 We need to remember the best successful chain we find, where best is defined by: satisfies as many optional policies as possible.
310 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.
312 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.
314 Example sectrust operation in psuedocode:
318 new builder(verifyTime
, certificates
, anchors
, anchorsOnly
, policies
);
319 chain
= builder
.subscriber_only_chain
;
320 foreach (policy in policies
{kSecPolicySLCheck
}) {
321 foreach(check in policy
)
322 SecPolicyRunCheck(builder
, chain
, check
, details
);
323 foreach (subpolicy in policy
) {
324 check_policy(builder
, chain
, subpolicy
, details
{subpolicy
.name
})
326 propagate_subpolicy_results(builder
, chain
, details
);
328 while (chain
= builder
.next
) {
329 for (depth
= 0; p_d
= policies
.at_depth(depth
),
330 d_p_d
= dynamic_policies
.at_depth(depth
), p_d
|| d_p_d
; ++depth
)
332 /* Modify SecPathBuilderIsPartial() to
333 run builder_check(buildier, policies, kSecPolicySICheck) instead
334 of SecCertificateIsValid. Also rename considerExpired to
337 foreach (policy in p_d
) {
338 check_policy(builder
, chain
, policy
, kSecPolicySICheck
, depth
);
340 /* Recalculate since the static checks might have added new dynamic
342 d_p_d
= dynamic_policies
.at_depth(depth
);
343 foreach (policy in d_p_d
) {
344 check_policy(builder
, chain
, policy
, kSecPolicySICheck
, depth
);
346 if (chain
.is_anchored
) {
347 foreach (policy in p_d
) {
348 check_policy(builder
, chain
, policy
, kSecPolicySACheck
, depth
);
350 foreach (policy in d_p_d
) {
351 check_policy(builder
, chain
, policy
, kSecPolicySACheck
, depth
);
353 foreach (policy in p_d
) {
354 check_policy(builder
, chain
, policy
, kSecPolicyDACheck
, depth
);
356 foreach (policy in d_p_d
) {
357 check_policy(builder
, chain
, policy
, kSecPolicyDACheck
, depth
);
360 foreach (policy in policies
) {
361 check_policy(builder
, chain
, policy
, kSecPolicySACheck
, depth
);
362 check_policy(builder
, chain
, policy
, kSecPolicyDACheck
, depth
);
364 foreach (policy in policies
{kSecPolicySDCheck
}) {
369 check_policy(builder
, chain
, policy
, check_class
, details
, depth
) {
371 foreach(check in policy
{check_class
}) {
372 SecPolicyRunCheck(builder
, chain
, check
, details
);
376 foreach (subpolicy in policy
) {
377 if (!check_policy(builder
, chain
, subpolicy
, check_class
,
378 details
{subpolicy
.name
}) && subpolicy
.is_required
, depth
)
382 propagate_subpolicy_results(builder
, chain
, details
);
389 #define kSecPolicySHA1Size 20
390 const UInt8 kAppleCASHA1
[kSecPolicySHA1Size
] = {
391 0x61, 0x1E, 0x5B, 0x66, 0x2C, 0x59, 0x3A, 0x08, 0xFF, 0x58,
392 0xD1, 0x4A, 0xE2, 0x24, 0x52, 0xD1, 0x98, 0xDF, 0x6C, 0x60
395 __unused
static const UInt8 kAppleTESTCASHA1
[kSecPolicySHA1Size
] = {
396 0xbc, 0x30, 0x55, 0xc8, 0xc8, 0xd3, 0x48, 0x3f, 0xf4, 0x8d,
397 0xfe, 0x3d, 0x51, 0x75, 0x31, 0xc9, 0xf4, 0xd7, 0x4a, 0xf7
400 static const UInt8 kITMSCASHA1
[kSecPolicySHA1Size
] = {
401 0x1D, 0x33, 0x42, 0x46, 0x8B, 0x10, 0xBD, 0xE6, 0x45, 0xCE,
402 0x44, 0x6E, 0xBB, 0xE8, 0xF5, 0x03, 0x5D, 0xF8, 0x32, 0x22
405 static const UInt8 kFactoryDeviceCASHA1
[kSecPolicySHA1Size
] = {
406 0xef, 0x68, 0x73, 0x17, 0xa4, 0xf8, 0xf9, 0x4b, 0x7b, 0x21,
407 0xe2, 0x2f, 0x09, 0x8f, 0xfd, 0x6a, 0xae, 0xc0, 0x0d, 0x63
411 static const UInt8 kApplePKISettingsAuthority
[kSecPolicySHA1Size
] = {
412 0x1D, 0x0C, 0xBA, 0xAD, 0x17, 0xFD, 0x7E, 0x9E, 0x9F, 0xF1,
413 0xC9, 0xA2, 0x66, 0x79, 0x60, 0x00, 0x8B, 0xAE, 0x70, 0xB8
416 static const UInt8 kAppleTestPKISettingsAuthority
[kSecPolicySHA1Size
] = {
417 0xDB, 0xBA, 0x25, 0x0B, 0xD8, 0x62, 0x71, 0x87, 0x54, 0x7E,
418 0xD7, 0xEF, 0x11, 0x94, 0x7E, 0x82, 0xE6, 0xD8, 0x1C, 0x9A
421 static const UInt8 kTestAppleRootCA_ECC_SHA1
[kSecPolicySHA1Size
] = {
422 0x62, 0x0A, 0xED, 0x83, 0xD2, 0x97, 0x4A, 0x77, 0x56, 0x33,
423 0x83, 0xBE, 0xDB, 0xF9, 0xA1, 0xBD, 0x5F, 0xFE, 0x55, 0x7B
426 static const UInt8 kAppleRootCA_ECC_SHA1
[kSecPolicySHA1Size
] = {
427 0xB5, 0x2C, 0xB0, 0x2F, 0xD5, 0x67, 0xE0, 0x35, 0x9F, 0xE8,
428 0xFA, 0x4D, 0x4C, 0x41, 0x03, 0x79, 0x70, 0xFE, 0x01, 0xB0
434 /********************************************************
435 ****************** SecPolicy object ********************
436 ********************************************************/
438 static void SecPolicyDestroy(CFTypeRef cf
) {
439 SecPolicyRef policy
= (SecPolicyRef
) cf
;
440 CFRelease(policy
->_oid
);
441 CFRelease(policy
->_options
);
444 static Boolean
SecPolicyCompare(CFTypeRef cf1
, CFTypeRef cf2
) {
445 SecPolicyRef policy1
= (SecPolicyRef
) cf1
;
446 SecPolicyRef policy2
= (SecPolicyRef
) cf2
;
447 return CFEqual(policy1
->_oid
, policy2
->_oid
) &&
448 CFEqual(policy1
->_options
, policy2
->_options
);
451 static CFHashCode
SecPolicyHash(CFTypeRef cf
) {
452 SecPolicyRef policy
= (SecPolicyRef
) cf
;
454 return CFHash(policy
->_oid
) + CFHash(policy
->_options
);
457 static CFStringRef
SecPolicyCopyFormatDescription(CFTypeRef cf
, CFDictionaryRef formatOptions
) {
458 SecPolicyRef policy
= (SecPolicyRef
) cf
;
459 CFMutableStringRef desc
= CFStringCreateMutable(kCFAllocatorDefault
, 0);
460 CFStringRef typeStr
= CFCopyTypeIDDescription(CFGetTypeID(cf
));
461 CFStringAppendFormat(desc
, NULL
,
462 CFSTR("<%@: oid: %@ options %@"), typeStr
,
463 policy
->_oid
, policy
->_options
);
465 CFStringAppend(desc
, CFSTR(" >"));
470 /* SecPolicy API functions. */
471 CFGiblisWithHashFor(SecPolicy
)
473 /* AUDIT[securityd](done):
474 oid (ok) is a caller provided string, only its cf type has been checked.
475 options is a caller provided dictionary, only its cf type has been checked.
477 SecPolicyRef
SecPolicyCreate(CFStringRef oid
, CFDictionaryRef options
) {
478 SecPolicyRef result
= NULL
;
480 require(oid
, errOut
);
481 require(options
, errOut
);
483 (SecPolicyRef
)_CFRuntimeCreateInstance(kCFAllocatorDefault
,
484 SecPolicyGetTypeID(),
485 sizeof(struct __SecPolicy
) - sizeof(CFRuntimeBase
), 0), errOut
);
490 result
->_options
= options
;
496 SecPolicyRef
SecPolicyCreateWithProperties(CFTypeRef policyIdentifier
,
497 CFDictionaryRef properties
) {
498 // Creates a policy reference for a given policy object identifier.
499 // If policy-specific parameters can be supplied (e.g. hostname),
500 // attempt to obtain from input properties dictionary.
501 // Returns NULL if the given identifier is unsupported.
503 SecPolicyRef policy
= NULL
;
504 CFStringRef name
= NULL
;
505 CFStringRef teamID
= NULL
;
506 Boolean client
= false;
507 require(policyIdentifier
&& (CFStringGetTypeID() == CFGetTypeID(policyIdentifier
)), errOut
);
510 name
= CFDictionaryGetValue(properties
, kSecPolicyName
);
511 teamID
= CFDictionaryGetValue(properties
, kSecPolicyTeamIdentifier
);
513 CFBooleanRef dictionaryClientValue
;
514 client
= (CFDictionaryGetValueIfPresent(properties
, kSecPolicyClient
, (const void **)&dictionaryClientValue
) &&
515 (dictionaryClientValue
!= NULL
) && CFEqual(kCFBooleanTrue
, dictionaryClientValue
));
518 if (CFEqual(policyIdentifier
, kSecPolicyAppleX509Basic
)) {
519 policy
= SecPolicyCreateBasicX509();
521 else if (CFEqual(policyIdentifier
, kSecPolicyAppleSSL
)) {
522 policy
= SecPolicyCreateSSL(!client
, name
);
524 else if (CFEqual(policyIdentifier
, kSecPolicyAppleEAP
)) {
525 CFArrayRef array
= CFArrayCreate(kCFAllocatorDefault
, (const void **)&name
, 1,
526 &kCFTypeArrayCallBacks
);
527 policy
= SecPolicyCreateEAP(!client
, array
);
528 CFReleaseSafe(array
);
530 else if (CFEqual(policyIdentifier
, kSecPolicyAppleIPsec
)) {
531 policy
= SecPolicyCreateIPSec(!client
, name
);
533 else if (CFEqual(policyIdentifier
, kSecPolicyAppleRevocation
)) {
534 policy
= SecPolicyCreateRevocation(kSecRevocationUseAnyAvailableMethod
);
536 else if (CFEqual(policyIdentifier
, kSecPolicyAppleSMIME
)) {
537 policy
= SecPolicyCreateSMIME(kSecSignSMIMEUsage
| kSecAnyEncryptSMIME
, name
);
539 else if (CFEqual(policyIdentifier
, kSecPolicyAppleCodeSigning
)) {
540 policy
= SecPolicyCreateCodeSigning();
542 else if (CFEqual(policyIdentifier
, kSecPolicyAppleIDValidation
)) {
543 policy
= SecPolicyCreateAppleIDAuthorityPolicy();
545 else if (CFEqual(policyIdentifier
, kSecPolicyApplePassbookSigning
)) {
546 policy
= SecPolicyCreatePassbookCardSigner(name
, teamID
);
548 else if (CFEqual(policyIdentifier
, kSecPolicyAppleMobileStore
)) {
549 policy
= SecPolicyCreateMobileStoreSigner();
551 else if (CFEqual(policyIdentifier
, kSecPolicyAppleTestMobileStore
)) {
552 policy
= SecPolicyCreateTestMobileStoreSigner();
554 else if (CFEqual(policyIdentifier
, kSecPolicyAppleEscrowService
)) {
555 policy
= SecPolicyCreateEscrowServiceSigner();
557 else if (CFEqual(policyIdentifier
, kSecPolicyApplePCSEscrowService
)) {
558 policy
= SecPolicyCreatePCSEscrowServiceSigner();
560 else if (CFEqual(policyIdentifier
, kSecPolicyAppleProfileSigner
)) {
561 policy
= SecPolicyCreateConfigurationProfileSigner();
563 else if (CFEqual(policyIdentifier
, kSecPolicyAppleQAProfileSigner
)) {
564 policy
= SecPolicyCreateQAConfigurationProfileSigner();
566 else if (CFEqual(policyIdentifier
, kSecPolicyAppleServerAuthentication
)) {
567 policy
= SecPolicyCreateAppleSSLService(name
);
569 #if TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR
570 else if (CFEqual(policyIdentifier
, kSecPolicyAppleOTAPKISigner
)) {
571 policy
= SecPolicyCreateOTAPKISigner();
573 else if (CFEqual(policyIdentifier
, kSecPolicyAppleTestOTAPKISigner
)) {
574 policy
= SecPolicyCreateTestOTAPKISigner();
576 else if (CFEqual(policyIdentifier
, kSecPolicyAppleIDValidationRecordSigningPolicy
)) {
577 policy
= SecPolicyCreateAppleIDValidationRecordSigningPolicy();
579 else if (CFEqual(policyIdentifier
, kSecPolicyAppleSMPEncryption
)) {
580 policy
= SecPolicyCreateAppleSMPEncryption();
582 else if (CFEqual(policyIdentifier
, kSecPolicyAppleTestSMPEncryption
)) {
583 policy
= SecPolicyCreateTestAppleSMPEncryption();
591 CFDictionaryRef
SecPolicyCopyProperties(SecPolicyRef policyRef
) {
592 // Builds and returns a dictionary which the caller must release.
594 if (!policyRef
) return NULL
;
595 CFMutableDictionaryRef properties
= CFDictionaryCreateMutable(NULL
, 0,
596 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
597 if (!properties
) return NULL
;
598 CFStringRef oid
= (CFStringRef
) CFRetain(policyRef
->_oid
);
599 CFTypeRef nameKey
= NULL
;
601 // Convert private to public OID if we have one
602 CFStringRef outOid
= oid
;
603 if (CFEqual(oid
, kSecPolicyOIDBasicX509
)) {
604 outOid
= kSecPolicyAppleX509Basic
;
606 else if (CFEqual(oid
, kSecPolicyOIDSSLServer
) ||
607 CFEqual(oid
, kSecPolicyOIDSSLClient
)) {
608 outOid
= kSecPolicyAppleSSL
;
609 nameKey
= kSecPolicyCheckSSLHostname
;
611 else if (CFEqual(oid
, kSecPolicyEAPServer
) ||
612 CFEqual(oid
, kSecPolicyEAPClient
)) {
613 outOid
= kSecPolicyAppleEAP
;
614 nameKey
= kSecPolicyCheckEAPTrustedServerNames
;
616 else if (CFEqual(oid
, kSecPolicyOIDIPSecServer
) ||
617 CFEqual(oid
, kSecPolicyOIDIPSecClient
)) {
618 outOid
= kSecPolicyAppleIPsec
;
619 nameKey
= kSecPolicyCheckSSLHostname
;
621 else if (CFEqual(oid
, kSecPolicyOIDRevocation
)) {
622 outOid
= kSecPolicyAppleRevocation
;
624 else if (CFEqual(oid
, kSecPolicyOIDSMIME
)) {
625 outOid
= kSecPolicyAppleSMIME
;
626 nameKey
= kSecPolicyCheckEmail
;
628 else if (CFEqual(oid
, kSecPolicyOIDCodeSigning
)) {
629 outOid
= kSecPolicyAppleCodeSigning
;
631 else if (CFEqual(oid
, kSecPolicyOIDAppleIDAuthority
)) {
632 outOid
= kSecPolicyAppleIDValidation
;
634 else if (CFEqual(oid
, kSecPolicyOIDApplePassbook
)) {
635 outOid
= kSecPolicyApplePassbookSigning
;
637 else if (CFEqual(oid
, kSecPolicyOIDAppleMobileStore
)) {
638 outOid
= kSecPolicyAppleMobileStore
;
640 else if (CFEqual(oid
, kSecPolicyOIDAppleTestMobileStore
)) {
641 outOid
= kSecPolicyAppleTestMobileStore
;
643 else if (CFEqual(oid
, kSecPolicyOIDAppleEscrowService
)) {
644 outOid
= kSecPolicyAppleEscrowService
;
646 else if (CFEqual(oid
, kSecPolicyOIDApplePCSEscrowService
)) {
647 outOid
= kSecPolicyApplePCSEscrowService
;
649 else if (CFEqual(oid
, kSecPolicyOIDAppleProfileSigner
)) {
650 outOid
= kSecPolicyAppleProfileSigner
;
652 else if (CFEqual(oid
, kSecPolicyOIDAppleQAProfileSigner
)) {
653 outOid
= kSecPolicyAppleQAProfileSigner
;
655 #if TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR
656 else if (CFEqual(oid
, kSecPolicyOIDAppleOTAPKIAssetSigner
)) {
657 outOid
= kSecPolicyAppleOTAPKISigner
;
659 else if (CFEqual(oid
, kSecPolicyOIDAppleTestOTAPKIAssetSigner
)) {
660 outOid
= kSecPolicyAppleTestOTAPKISigner
;
662 else if (CFEqual(oid
, kSecPolicyOIDAppleIDValidationRecordSigningPolicy
)) {
663 outOid
= kSecPolicyAppleIDValidationRecordSigningPolicy
;
668 CFDictionarySetValue(properties
, (const void *)kSecPolicyOid
,
669 (const void *)outOid
);
671 // Set kSecPolicyName if we have one
672 if (nameKey
&& policyRef
->_options
) {
673 CFTypeRef name
= (CFTypeRef
) CFDictionaryGetValue(policyRef
->_options
,
676 CFDictionarySetValue(properties
, (const void *)kSecPolicyName
,
681 // Set kSecPolicyClient
682 if (CFEqual(oid
, kSecPolicyOIDSSLClient
) ||
683 CFEqual(oid
, kSecPolicyOIDIPSecClient
) ||
684 CFEqual(oid
, kSecPolicyEAPClient
)) {
685 CFDictionarySetValue(properties
, (const void *)kSecPolicyClient
,
686 (const void *)kCFBooleanTrue
);
693 #if TARGET_OS_MAC && !TARGET_OS_IPHONE
694 static void SecPolicySetOid(SecPolicyRef policy
, CFStringRef oid
) {
695 if (!policy
|| !oid
) return;
696 CFStringRef temp
= policy
->_oid
;
702 static void SecPolicySetOptionsValue(SecPolicyRef policy
, CFStringRef key
, CFTypeRef value
) {
703 if (!policy
|| !key
) return;
704 CFMutableDictionaryRef options
= (CFMutableDictionaryRef
) policy
->_options
;
706 options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
707 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
708 if (!options
) return;
709 policy
->_options
= options
;
711 CFDictionarySetValue(options
, key
, value
);
714 OSStatus
SecPolicySetProperties(SecPolicyRef policyRef
, CFDictionaryRef properties
) {
715 // Set policy options based on the provided dictionary keys.
717 if (!(policyRef
&& properties
&& (CFDictionaryGetTypeID() == CFGetTypeID(properties
)))) {
720 CFStringRef oid
= (CFStringRef
) CFRetain(policyRef
->_oid
);
721 OSStatus result
= errSecSuccess
;
724 CFTypeRef name
= NULL
;
725 if (CFDictionaryGetValueIfPresent(properties
, (const void *)kSecPolicyName
,
726 (const void **)&name
) && name
) {
727 CFTypeID typeID
= CFGetTypeID(name
);
728 if (CFEqual(oid
, kSecPolicyOIDSSLServer
) ||
729 CFEqual(oid
, kSecPolicyOIDSSLClient
) ||
730 CFEqual(oid
, kSecPolicyOIDIPSecServer
) ||
731 CFEqual(oid
, kSecPolicyOIDIPSecClient
)) {
732 if (CFStringGetTypeID() == typeID
) {
733 SecPolicySetOptionsValue(policyRef
, kSecPolicyCheckSSLHostname
, name
);
735 else result
= errSecParam
;
737 else if (CFEqual(oid
, kSecPolicyEAPServer
) ||
738 CFEqual(oid
, kSecPolicyEAPClient
)) {
739 if ((CFStringGetTypeID() == typeID
) ||
740 (CFArrayGetTypeID() == typeID
)) {
741 SecPolicySetOptionsValue(policyRef
, kSecPolicyCheckEAPTrustedServerNames
, name
);
743 else result
= errSecParam
;
745 else if (CFEqual(oid
, kSecPolicyOIDSMIME
)) {
746 if (CFStringGetTypeID() == typeID
) {
747 SecPolicySetOptionsValue(policyRef
, kSecPolicyCheckEmail
, name
);
749 else result
= errSecParam
;
754 CFTypeRef client
= NULL
;
755 if (CFDictionaryGetValueIfPresent(properties
, (const void *)kSecPolicyClient
,
756 (const void **)&client
) && client
) {
757 if (!(CFBooleanGetTypeID() == CFGetTypeID(client
))) {
758 result
= errSecParam
;
760 else if (CFEqual(client
, kCFBooleanTrue
)) {
761 if (CFEqual(oid
, kSecPolicyOIDSSLServer
)) {
762 SecPolicySetOid(policyRef
, kSecPolicyOIDSSLClient
);
764 else if (CFEqual(oid
, kSecPolicyOIDIPSecServer
)) {
765 SecPolicySetOid(policyRef
, kSecPolicyOIDIPSecClient
);
767 else if (CFEqual(oid
, kSecPolicyEAPServer
)) {
768 SecPolicySetOid(policyRef
, kSecPolicyEAPClient
);
772 if (CFEqual(oid
, kSecPolicyOIDSSLClient
)) {
773 SecPolicySetOid(policyRef
, kSecPolicyOIDSSLServer
);
775 else if (CFEqual(oid
, kSecPolicyOIDIPSecClient
)) {
776 SecPolicySetOid(policyRef
, kSecPolicyOIDIPSecServer
);
778 else if (CFEqual(oid
, kSecPolicyEAPClient
)) {
779 SecPolicySetOid(policyRef
, kSecPolicyEAPServer
);
789 static xpc_object_t
SecPolicyCopyXPCObject(SecPolicyRef policy
, CFErrorRef
*error
) {
790 xpc_object_t xpc_policy
= NULL
;
791 xpc_object_t data
[2] = {};
792 require_action_quiet(data
[0] = _CFXPCCreateXPCObjectFromCFObject(policy
->_oid
), exit
,
793 SecError(errSecParam
, error
, CFSTR("failed to create xpc_object from policy oid")));
794 require_action_quiet(data
[1] = _CFXPCCreateXPCObjectFromCFObject(policy
->_options
), exit
,
795 SecError(errSecParam
, error
, CFSTR("failed to create xpc_object from policy options")));
796 require_action_quiet(xpc_policy
= xpc_array_create(data
, array_size(data
)), exit
,
797 SecError(errSecAllocate
, error
, CFSTR("failed to create xpc_array for policy")));
800 if (data
[0]) xpc_release(data
[0]);
801 if (data
[1]) xpc_release(data
[1]);
805 static bool SecPolicyAppendToXPCArray(SecPolicyRef policy
, xpc_object_t policies
, CFErrorRef
*error
) {
809 xpc_object_t xpc_policy
= SecPolicyCopyXPCObject(policy
, error
);
813 xpc_array_append_value(policies
, xpc_policy
);
814 xpc_release(xpc_policy
);
818 xpc_object_t
SecPolicyArrayCopyXPCArray(CFArrayRef policies
, CFErrorRef
*error
) {
819 xpc_object_t xpc_policies
;
820 require_action_quiet(xpc_policies
= xpc_array_create(NULL
, 0), exit
,
821 SecError(errSecAllocate
, error
, CFSTR("failed to create xpc_array")));
822 CFIndex ix
, count
= CFArrayGetCount(policies
);
823 for (ix
= 0; ix
< count
; ++ix
) {
824 if (!SecPolicyAppendToXPCArray((SecPolicyRef
)CFArrayGetValueAtIndex(policies
, ix
), xpc_policies
, error
)) {
825 xpc_release(xpc_policies
);
833 static SecPolicyRef
SecPolicyCreateWithXPCObject(xpc_object_t xpc_policy
, CFErrorRef
*error
) {
834 SecPolicyRef policy
= NULL
;
835 CFTypeRef oid
= NULL
;
836 CFTypeRef options
= NULL
;
838 require_action_quiet(xpc_policy
, exit
, SecError(errSecParam
, error
, CFSTR("policy xpc value is NULL")));
839 require_action_quiet(xpc_get_type(xpc_policy
) == XPC_TYPE_ARRAY
, exit
, SecError(errSecDecode
, error
, CFSTR("policy xpc value is not an array")));
840 require_action_quiet(xpc_array_get_count(xpc_policy
) == 2, exit
, SecError(errSecDecode
, error
, CFSTR("policy xpc array count != 2")));
841 oid
= _CFXPCCreateCFObjectFromXPCObject(xpc_array_get_value(xpc_policy
, 0));
842 require_action_quiet(isString(oid
), exit
,
843 SecError(errSecParam
, error
, CFSTR("failed to convert xpc policy[0]=%@ to CFString"), oid
));
844 options
= _CFXPCCreateCFObjectFromXPCObject(xpc_array_get_value(xpc_policy
, 1));
845 require_action_quiet(isDictionary(options
), exit
,
846 SecError(errSecParam
, error
, CFSTR("failed to convert xpc policy[1]=%@ to CFDictionary"), options
));
847 require_action_quiet(policy
= SecPolicyCreate(oid
, options
), exit
, SecError(errSecDecode
, error
, CFSTR("Failed to create policy")));
851 CFReleaseSafe(options
);
855 CFArrayRef
SecPolicyXPCArrayCopyArray(xpc_object_t xpc_policies
, CFErrorRef
*error
) {
856 CFMutableArrayRef policies
= NULL
;
857 require_action_quiet(xpc_get_type(xpc_policies
) == XPC_TYPE_ARRAY
, exit
,
858 SecError(errSecParam
, error
, CFSTR("policies xpc value is not an array")));
859 size_t count
= xpc_array_get_count(xpc_policies
);
860 require_action_quiet(policies
= CFArrayCreateMutable(kCFAllocatorDefault
, count
, &kCFTypeArrayCallBacks
), exit
,
861 SecError(errSecAllocate
, error
, CFSTR("failed to create CFArray of capacity %zu"), count
));
864 for (ix
= 0; ix
< count
; ++ix
) {
865 SecPolicyRef policy
= SecPolicyCreateWithXPCObject(xpc_array_get_value(xpc_policies
, ix
), error
);
870 CFArraySetValueAtIndex(policies
, ix
, policy
);
879 static void add_element(CFMutableDictionaryRef options
, CFStringRef key
,
881 CFTypeRef old_value
= CFDictionaryGetValue(options
, key
);
883 CFMutableArrayRef array
;
884 if (CFGetTypeID(old_value
) == CFArrayGetTypeID()) {
885 array
= (CFMutableArrayRef
)old_value
;
887 array
= CFArrayCreateMutable(kCFAllocatorDefault
, 0,
888 &kCFTypeArrayCallBacks
);
889 CFArrayAppendValue(array
, old_value
);
890 CFDictionarySetValue(options
, key
, array
);
893 CFArrayAppendValue(array
, value
);
895 CFDictionaryAddValue(options
, key
, value
);
899 static void add_eku(CFMutableDictionaryRef options
, const DERItem
*ekuOid
) {
900 CFDataRef eku
= CFDataCreate(kCFAllocatorDefault
,
901 ekuOid
? ekuOid
->data
: NULL
,
902 ekuOid
? ekuOid
->length
: 0);
904 add_element(options
, kSecPolicyCheckExtendedKeyUsage
, eku
);
909 static void add_ku(CFMutableDictionaryRef options
, SecKeyUsage keyUsage
) {
910 SInt32 dku
= keyUsage
;
911 CFNumberRef ku
= CFNumberCreate(kCFAllocatorDefault
, kCFNumberSInt32Type
,
914 add_element(options
, kSecPolicyCheckKeyUsage
, ku
);
919 static void add_oid(CFMutableDictionaryRef options
, CFStringRef policy_key
, const DERItem
*oid
) {
920 CFDataRef oid_data
= CFDataCreate(kCFAllocatorDefault
,
921 oid
? oid
->data
: NULL
,
922 oid
? oid
->length
: 0);
924 add_element(options
, policy_key
, oid_data
);
929 static void add_leaf_marker_value(CFMutableDictionaryRef options
, const DERItem
*markerOid
, CFStringRef string_value
) {
931 CFTypeRef policyData
= NULL
;
933 if (NULL
== string_value
) {
934 policyData
= CFDataCreate(kCFAllocatorDefault
,
935 markerOid
? markerOid
->data
: NULL
,
936 markerOid
? markerOid
->length
: 0);
938 CFStringRef oid_as_string
= SecDERItemCopyOIDDecimalRepresentation(kCFAllocatorDefault
, markerOid
);
940 const void *key
[1] = { oid_as_string
};
941 const void *value
[1] = { string_value
};
942 policyData
= CFDictionaryCreate(kCFAllocatorDefault
,
944 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
945 CFReleaseNull(oid_as_string
);
948 add_element(options
, kSecPolicyCheckLeafMarkerOid
, policyData
);
950 CFReleaseNull(policyData
);
954 static void add_leaf_marker(CFMutableDictionaryRef options
, const DERItem
*markerOid
) {
955 add_leaf_marker_value(options
, markerOid
, NULL
);
959 static void add_certificate_policy_oid(CFMutableDictionaryRef options
, const DERItem
*certificatePolicyOid
, CFStringRef string_value
) {
960 CFTypeRef certificatePolicyData
= NULL
;
962 if (NULL
== string_value
) {
963 certificatePolicyData
= CFDataCreate(kCFAllocatorDefault
,
964 certificatePolicyOid
? certificatePolicyOid
->data
: NULL
,
965 certificatePolicyOid
? certificatePolicyOid
->length
: 0);
967 CFStringRef oid_as_string
= SecDERItemCopyOIDDecimalRepresentation(kCFAllocatorDefault
, certificatePolicyOid
);
969 const void *key
[1] = { oid_as_string
};
970 const void *value
[1] = { string_value
};
971 certificatePolicyData
= CFDictionaryCreate(kCFAllocatorDefault
,
973 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
974 CFReleaseNull(oid_as_string
);
977 add_element(options
, kSecPolicyCheckCertificatePolicy
, certificatePolicyData
);
979 CFReleaseNull(certificatePolicyData
);
982 // Routines for adding dictionary entries for policies.
985 // X.509, but missing validity requirements.
986 static void SecPolicyAddBasicCertOptions(CFMutableDictionaryRef options
)
988 //CFDictionaryAddValue(options, kSecPolicyCheckBasicCertificateProcessing, kCFBooleanTrue);
989 CFDictionaryAddValue(options
, kSecPolicyCheckCriticalExtensions
, kCFBooleanTrue
);
990 CFDictionaryAddValue(options
, kSecPolicyCheckIdLinkage
, kCFBooleanTrue
);
991 CFDictionaryAddValue(options
, kSecPolicyCheckBasicContraints
, kCFBooleanTrue
);
992 CFDictionaryAddValue(options
, kSecPolicyCheckNonEmptySubject
, kCFBooleanTrue
);
993 CFDictionaryAddValue(options
, kSecPolicyCheckQualifiedCertStatements
, kCFBooleanTrue
);
996 static void SecPolicyAddBasicX509Options(CFMutableDictionaryRef options
)
998 SecPolicyAddBasicCertOptions(options
);
999 CFDictionaryAddValue(options
, kSecPolicyCheckValidIntermediates
, kCFBooleanTrue
);
1000 CFDictionaryAddValue(options
, kSecPolicyCheckValidLeaf
, kCFBooleanTrue
);
1001 CFDictionaryAddValue(options
, kSecPolicyCheckValidRoot
, kCFBooleanTrue
);
1003 // Make sure that black and gray leaf checks are performed for basic X509 chain building
1004 CFDictionaryAddValue(options
, kSecPolicyCheckBlackListedLeaf
, kCFBooleanTrue
);
1005 CFDictionaryAddValue(options
, kSecPolicyCheckGrayListedLeaf
, kCFBooleanTrue
);
1008 static bool SecPolicyAddChainLengthOptions(CFMutableDictionaryRef options
, CFIndex length
)
1010 bool result
= false;
1011 CFNumberRef lengthAsCF
= NULL
;
1013 require(lengthAsCF
= CFNumberCreate(kCFAllocatorDefault
,
1014 kCFNumberCFIndexType
, &length
), errOut
);
1015 CFDictionaryAddValue(options
, kSecPolicyCheckChainLength
, lengthAsCF
);
1020 CFReleaseSafe(lengthAsCF
);
1024 static bool SecPolicyAddAnchorSHA1Options(CFMutableDictionaryRef options
,
1025 const UInt8 anchorSha1
[kSecPolicySHA1Size
])
1027 bool success
= false;
1028 CFDataRef anchorData
= NULL
;
1030 require(anchorData
= CFDataCreate(kCFAllocatorDefault
, anchorSha1
, kSecPolicySHA1Size
), errOut
);
1031 add_element(options
, kSecPolicyCheckAnchorSHA1
, anchorData
);
1036 CFReleaseSafe(anchorData
);
1040 static bool SecPolicyAddAppleAnchorOptions(CFMutableDictionaryRef options
)
1042 return SecPolicyAddAnchorSHA1Options(options
, kAppleCASHA1
);
1046 static bool SecPolicyAddAppleTESTAnchorOptions(CFMutableDictionaryRef options
)
1048 return SecPolicyAddAnchorSHA1Options(options
, kAppleTESTCASHA1
);
1053 // Policy Creation Functions
1055 SecPolicyRef
SecPolicyCreateBasicX509(void) {
1056 CFMutableDictionaryRef options
= NULL
;
1057 SecPolicyRef result
= NULL
;
1059 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1060 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1062 SecPolicyAddBasicX509Options(options
);
1063 CFDictionaryAddValue(options
, kSecPolicyCheckNoNetworkAccess
,
1066 require(result
= SecPolicyCreate(kSecPolicyOIDBasicX509
, options
), errOut
);
1069 CFReleaseSafe(options
);
1073 SecPolicyRef
SecPolicyCreateSSL(Boolean server
, CFStringRef hostname
) {
1074 CFMutableDictionaryRef options
= NULL
;
1075 SecPolicyRef result
= NULL
;
1077 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1078 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1080 SecPolicyAddBasicX509Options(options
);
1083 CFDictionaryAddValue(options
, kSecPolicyCheckKeyUsage
,
1088 CFDictionaryAddValue(options
, kSecPolicyCheckSSLHostname
, hostname
);
1091 CFDictionaryAddValue(options
, kSecPolicyCheckBlackListedLeaf
, kCFBooleanTrue
);
1092 CFDictionaryAddValue(options
, kSecPolicyCheckGrayListedLeaf
, kCFBooleanTrue
);
1094 /* If server and EKU ext present then EKU ext should contain one of
1095 CSSMOID_ServerAuth or CSSMOID_ExtendedKeyUsageAny or
1096 CSSMOID_NetscapeSGC or CSSMOID_MicrosoftSGC.
1097 else if !server and EKU ext present then EKU ext should contain one of
1098 CSSMOID_ClientAuth or CSSMOID_ExtendedKeyUsageAny. */
1100 /* We always allow certification that specify oidAnyExtendedKeyUsage. */
1101 add_eku(options
, NULL
); /* eku extension is optional */
1102 add_eku(options
, &oidAnyExtendedKeyUsage
);
1104 add_eku(options
, &oidExtendedKeyUsageServerAuth
);
1105 add_eku(options
, &oidExtendedKeyUsageMicrosoftSGC
);
1106 add_eku(options
, &oidExtendedKeyUsageNetscapeSGC
);
1108 add_eku(options
, &oidExtendedKeyUsageClientAuth
);
1111 require(result
= SecPolicyCreate(
1112 server
? kSecPolicyOIDSSLServer
: kSecPolicyOIDSSLClient
,
1116 CFReleaseSafe(options
);
1120 SecPolicyRef
SecPolicyCreateiPhoneActivation(void) {
1121 CFMutableDictionaryRef options
= NULL
;
1122 SecPolicyRef result
= NULL
;
1124 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1125 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1127 SecPolicyAddBasicCertOptions(options
);
1130 CFDictionaryAddValue(options
, kSecPolicyCheckKeyUsage
,
1132 CFDictionaryAddValue(options
, kSecPolicyCheckExtendedKeyUsage
,
1136 /* Basic X.509 policy with the additional requirements that the chain
1137 length is 3, it's anchored at the AppleCA and the leaf certificate
1138 has issuer "Apple iPhone Certification Authority" and
1139 subject "Apple iPhone Activation" for the common name. */
1140 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
1141 CFSTR("Apple iPhone Certification Authority"));
1142 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
,
1143 CFSTR("Apple iPhone Activation"));
1145 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1146 require(SecPolicyAddAppleAnchorOptions(options
), errOut
);
1148 require(result
= SecPolicyCreate(kSecPolicyOIDiPhoneActivation
, options
),
1152 CFReleaseSafe(options
);
1156 SecPolicyRef
SecPolicyCreateiPhoneDeviceCertificate(void) {
1157 CFMutableDictionaryRef options
= NULL
;
1158 SecPolicyRef result
= NULL
;
1160 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1161 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1163 SecPolicyAddBasicCertOptions(options
);
1166 CFDictionaryAddValue(options
, kSecPolicyCheckKeyUsage
,
1168 CFDictionaryAddValue(options
, kSecPolicyCheckExtendedKeyUsage
,
1172 /* Basic X.509 policy with the additional requirements that the chain
1173 length is 4, it's anchored at the AppleCA and the first intermediate
1174 has the subject "Apple iPhone Device CA". */
1175 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
1176 CFSTR("Apple iPhone Device CA"));
1178 require(SecPolicyAddChainLengthOptions(options
, 4), errOut
);
1179 require(SecPolicyAddAppleAnchorOptions(options
), errOut
);
1181 require(result
= SecPolicyCreate(kSecPolicyOIDiPhoneDeviceCertificate
, options
),
1185 CFReleaseSafe(options
);
1189 SecPolicyRef
SecPolicyCreateFactoryDeviceCertificate(void) {
1190 CFMutableDictionaryRef options
= NULL
;
1191 SecPolicyRef result
= NULL
;
1193 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1194 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1196 SecPolicyAddBasicCertOptions(options
);
1199 CFDictionaryAddValue(options
, kSecPolicyCheckKeyUsage
,
1201 CFDictionaryAddValue(options
, kSecPolicyCheckExtendedKeyUsage
,
1205 /* Basic X.509 policy with the additional requirements that the chain
1206 is anchored at the factory device certificate issuer. */
1207 require(SecPolicyAddAnchorSHA1Options(options
, kFactoryDeviceCASHA1
), errOut
);
1209 require(result
= SecPolicyCreate(kSecPolicyOIDFactoryDeviceCertificate
, options
),
1213 CFReleaseSafe(options
);
1217 SecPolicyRef
SecPolicyCreateiAP(void) {
1218 CFMutableDictionaryRef options
= NULL
;
1219 SecPolicyRef result
= NULL
;
1220 CFTimeZoneRef tz
= NULL
;
1221 CFDateRef date
= NULL
;
1223 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1224 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1226 SecPolicyAddBasicCertOptions(options
);
1228 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonNamePrefix
,
1231 date
= CFDateCreateForGregorianZuluDay(NULL
, 2006, 5, 31);
1232 CFDictionaryAddValue(options
, kSecPolicyCheckNotValidBefore
, date
);
1234 require(result
= SecPolicyCreate(kSecPolicyOIDiAP
, options
),
1238 CFReleaseSafe(date
);
1240 CFReleaseSafe(options
);
1244 SecPolicyRef
SecPolicyCreateiTunesStoreURLBag(void) {
1245 CFMutableDictionaryRef options
= NULL
;
1246 SecPolicyRef result
= NULL
;
1249 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1250 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1252 SecPolicyAddBasicCertOptions(options
);
1254 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectOrganization
,
1255 CFSTR("Apple Inc."));
1256 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
,
1257 CFSTR("iTunes Store URL Bag"));
1259 require(SecPolicyAddChainLengthOptions(options
, 2), errOut
);
1260 require(SecPolicyAddAnchorSHA1Options(options
, kITMSCASHA1
), errOut
);
1262 require(result
= SecPolicyCreate(kSecPolicyOIDiTunesStoreURLBag
, options
), errOut
);
1265 CFReleaseSafe(options
);
1269 SecPolicyRef
SecPolicyCreateEAP(Boolean server
, CFArrayRef trustedServerNames
) {
1270 CFMutableDictionaryRef options
= NULL
;
1271 SecPolicyRef result
= NULL
;
1273 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1274 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1276 SecPolicyAddBasicX509Options(options
);
1279 CFDictionaryAddValue(options
, kSecPolicyCheckKeyUsage
,
1281 CFDictionaryAddValue(options
, kSecPolicyCheckExtendedKeyUsage
,
1285 /* Since EAP is used to setup the network we don't want evaluation
1286 using this policy to access the network. */
1287 CFDictionaryAddValue(options
, kSecPolicyCheckNoNetworkAccess
,
1289 if (trustedServerNames
) {
1290 CFDictionaryAddValue(options
, kSecPolicyCheckEAPTrustedServerNames
, trustedServerNames
);
1293 require(result
= SecPolicyCreate(
1294 server
? kSecPolicyEAPServer
: kSecPolicyEAPClient
,
1298 CFReleaseSafe(options
);
1302 SecPolicyRef
SecPolicyCreateIPSec(Boolean server
, CFStringRef hostname
) {
1303 CFMutableDictionaryRef options
= NULL
;
1304 SecPolicyRef result
= NULL
;
1306 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1307 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1309 SecPolicyAddBasicX509Options(options
);
1312 CFDictionaryAddValue(options
, kSecPolicyCheckSSLHostname
, hostname
);
1315 /* Require oidExtendedKeyUsageIPSec if Extended Keyusage Extention is
1317 /* Per <rdar://problem/6843827> Cisco VPN Certificate compatibility issue.
1318 We don't check the EKU for IPSec certs for now. If we do add eku
1319 checking back in the future, we should probably also accept the
1321 ipsecEndSystem 1.3.6.1.5.5.7.3.5
1323 ipsecTunnel 1.3.6.1.5.5.7.3.6
1324 ipsecUser 1.3.6.1.5.5.7.3.7
1326 //add_eku(options, NULL); /* eku extension is optional */
1327 //add_eku(options, &oidAnyExtendedKeyUsage);
1328 //add_eku(options, &oidExtendedKeyUsageIPSec);
1330 require(result
= SecPolicyCreate(
1331 server
? kSecPolicyOIDIPSecServer
: kSecPolicyOIDIPSecClient
,
1335 CFReleaseSafe(options
);
1339 SecPolicyRef
SecPolicyCreateiPhoneApplicationSigning(void) {
1340 CFMutableDictionaryRef options
= NULL
;
1341 SecPolicyRef result
= NULL
;
1343 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1344 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1346 SecPolicyAddBasicCertOptions(options
);
1348 /* Basic X.509 policy with the additional requirements that the chain
1349 length is 3, it's anchored at the AppleCA and the leaf certificate
1350 has issuer "Apple iPhone Certification Authority" and
1351 subject "Apple iPhone OS Application Signing" for the common name. */
1352 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
1353 CFSTR("Apple iPhone Certification Authority"));
1354 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonNameTEST
,
1355 CFSTR("Apple iPhone OS Application Signing"));
1357 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1358 require(SecPolicyAddAppleAnchorOptions(options
), errOut
);
1360 add_eku(options
, NULL
); /* eku extension is optional */
1361 add_eku(options
, &oidAnyExtendedKeyUsage
);
1362 add_eku(options
, &oidExtendedKeyUsageCodeSigning
);
1364 require(result
= SecPolicyCreate(kSecPolicyOIDiPhoneApplicationSigning
, options
),
1367 /* 1.2.840.113635.100.6.1.3, non-critical: DER:05:00 - application signing */
1370 CFReleaseSafe(options
);
1374 SecPolicyRef
SecPolicyCreateiPhoneProfileApplicationSigning(void) {
1375 CFMutableDictionaryRef options
= NULL
;
1376 SecPolicyRef result
= NULL
;
1378 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1379 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1380 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kCFBooleanFalse
);
1381 CFDictionaryAddValue(options
, kSecPolicyCheckValidLeaf
, kCFBooleanFalse
);
1383 require(result
= SecPolicyCreate(kSecPolicyOIDiPhoneProfileApplicationSigning
,
1387 CFReleaseSafe(options
);
1391 SecPolicyRef
SecPolicyCreateiPhoneProvisioningProfileSigning(void) {
1392 CFMutableDictionaryRef options
= NULL
;
1393 SecPolicyRef result
= NULL
;
1395 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1396 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1398 SecPolicyAddBasicCertOptions(options
);
1400 /* Basic X.509 policy with the additional requirements that the chain
1401 length is 3, it's anchored at the AppleCA and the leaf certificate
1402 has issuer "Apple iPhone Certification Authority" and
1403 subject "Apple iPhone OS Provisioning Profile Signing" for the common name. */
1404 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
1405 CFSTR("Apple iPhone Certification Authority"));
1406 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonNameTEST
,
1407 CFSTR("Apple iPhone OS Provisioning Profile Signing"));
1409 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1410 require(SecPolicyAddAppleAnchorOptions(options
), errOut
);
1412 require(result
= SecPolicyCreate(kSecPolicyOIDiPhoneProvisioningProfileSigning
, options
),
1415 /* 1.2.840.113635.100.6.2.2.1, non-critical: DER:05:00 - provisioning profile */
1418 CFReleaseSafe(options
);
1422 SecPolicyRef
SecPolicyCreateOCSPSigner(void) {
1423 CFMutableDictionaryRef options
= NULL
;
1424 SecPolicyRef result
= NULL
;
1426 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1427 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1429 SecPolicyAddBasicX509Options(options
);
1431 /* Require id-kp-OCSPSigning extendedKeyUsage to be present, not optional. */
1432 add_eku(options
, &oidExtendedKeyUsageOCSPSigning
);
1434 require(result
= SecPolicyCreate(kSecPolicyOIDOCSPSigner
, options
), errOut
);
1437 CFReleaseSafe(options
);
1441 SecPolicyRef
SecPolicyCreateRevocation(CFOptionFlags revocationFlags
) {
1442 CFMutableDictionaryRef options
= NULL
;
1443 SecPolicyRef result
= NULL
;
1445 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1446 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1448 /* false = ocsp, true = crl, string/url value = crl distribution point,
1449 array = list of multiple values for example false, true, url1, url2
1450 check ocsp, crl, and url1 and url2 for certs which have no extensions.
1452 if (revocationFlags
& kSecRevocationOCSPMethod
) {
1453 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kCFBooleanFalse
);
1455 else if (revocationFlags
& kSecRevocationCRLMethod
) {
1456 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kCFBooleanTrue
);
1459 //FIXME: check additional revocation flags
1462 /* Only flag bits 0-4 are currently defined */
1463 require(((revocationFlags
>> 5) == 0), errOut
);
1465 require(result
= SecPolicyCreate(kSecPolicyOIDRevocation
, options
), errOut
);
1468 CFReleaseSafe(options
);
1472 SecPolicyRef
SecPolicyCreateSMIME(CFIndex smimeUsage
, CFStringRef email
) {
1473 CFMutableDictionaryRef options
= NULL
;
1474 SecPolicyRef result
= NULL
;
1476 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1477 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1479 SecPolicyAddBasicX509Options(options
);
1481 /* We call add_ku for each combination of bits we are willing to allow. */
1482 if (smimeUsage
& kSecSignSMIMEUsage
) {
1483 add_ku(options
, kSecKeyUsageUnspecified
);
1484 add_ku(options
, kSecKeyUsageDigitalSignature
);
1485 add_ku(options
, kSecKeyUsageNonRepudiation
);
1487 if (smimeUsage
& kSecKeyEncryptSMIMEUsage
) {
1488 add_ku(options
, kSecKeyUsageKeyEncipherment
);
1490 if (smimeUsage
& kSecDataEncryptSMIMEUsage
) {
1491 add_ku(options
, kSecKeyUsageDataEncipherment
);
1493 if (smimeUsage
& kSecKeyExchangeDecryptSMIMEUsage
) {
1494 add_ku(options
, kSecKeyUsageKeyAgreement
| kSecKeyUsageDecipherOnly
);
1496 if (smimeUsage
& kSecKeyExchangeEncryptSMIMEUsage
) {
1497 add_ku(options
, kSecKeyUsageKeyAgreement
| kSecKeyUsageEncipherOnly
);
1499 if (smimeUsage
& kSecKeyExchangeBothSMIMEUsage
) {
1500 add_ku(options
, kSecKeyUsageKeyAgreement
| kSecKeyUsageEncipherOnly
| kSecKeyUsageDecipherOnly
);
1504 CFDictionaryAddValue(options
, kSecPolicyCheckEmail
, email
);
1507 /* RFC 3850 paragraph 4.4.4
1509 If the extended key usage extension is present in the certificate
1510 then interpersonal message S/MIME receiving agents MUST check that it
1511 contains either the emailProtection or the anyExtendedKeyUsage OID as
1512 defined in [KEYM]. S/MIME uses other than interpersonal messaging
1513 MAY require the explicit presence of the extended key usage extension
1514 or other OIDs to be present in the extension or both.
1516 add_eku(options
, NULL
); /* eku extension is optional */
1517 add_eku(options
, &oidAnyExtendedKeyUsage
);
1518 add_eku(options
, &oidExtendedKeyUsageEmailProtection
);
1520 require(result
= SecPolicyCreate(kSecPolicyOIDSMIME
, options
), errOut
);
1523 CFReleaseSafe(options
);
1527 SecPolicyRef
SecPolicyCreateCodeSigning(void) {
1528 CFMutableDictionaryRef options
= NULL
;
1529 SecPolicyRef result
= NULL
;
1531 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1532 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1534 SecPolicyAddBasicX509Options(options
);
1536 /* If the key usage extension is present we accept it having either of
1538 add_ku(options
, kSecKeyUsageDigitalSignature
);
1539 add_ku(options
, kSecKeyUsageNonRepudiation
);
1541 /* We require a extended key usage extension and we accept any or
1542 codesigning ekus. */
1543 /* TODO: Do we want to accept the apple codesigning oid as well or is
1544 that a separate policy? */
1545 add_eku(options
, &oidAnyExtendedKeyUsage
);
1546 add_eku(options
, &oidExtendedKeyUsageCodeSigning
);
1548 require(result
= SecPolicyCreate(kSecPolicyOIDCodeSigning
, options
),
1552 CFReleaseSafe(options
);
1556 /* Explicitly leave out empty subject/subjectaltname check */
1557 SecPolicyRef
SecPolicyCreateLockdownPairing(void) {
1558 CFMutableDictionaryRef options
= NULL
;
1559 SecPolicyRef result
= NULL
;
1561 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1562 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1563 //CFDictionaryAddValue(options, kSecPolicyCheckBasicCertificateProcessing,
1565 CFDictionaryAddValue(options
, kSecPolicyCheckCriticalExtensions
,
1567 CFDictionaryAddValue(options
, kSecPolicyCheckIdLinkage
,
1569 CFDictionaryAddValue(options
, kSecPolicyCheckBasicContraints
,
1571 CFDictionaryAddValue(options
, kSecPolicyCheckQualifiedCertStatements
,
1574 require(result
= SecPolicyCreate(kSecPolicyOIDLockdownPairing
, options
), errOut
);
1577 CFReleaseSafe(options
);
1581 SecPolicyRef
SecPolicyCreateURLBag(void) {
1582 CFMutableDictionaryRef options
= NULL
;
1583 SecPolicyRef result
= NULL
;
1585 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1586 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1588 SecPolicyAddBasicCertOptions(options
);
1590 add_eku(options
, &oidExtendedKeyUsageCodeSigning
);
1592 require(result
= SecPolicyCreate(kSecPolicyOIDURLBag
, options
), errOut
);
1595 CFReleaseSafe(options
);
1599 static bool SecPolicyAddAppleCertificationAuthorityOptions(CFMutableDictionaryRef options
, bool honorValidity
)
1601 bool success
= false;
1604 SecPolicyAddBasicX509Options(options
);
1606 SecPolicyAddBasicCertOptions(options
);
1609 CFDictionaryAddValue(options
, kSecPolicyCheckKeyUsage
,
1611 CFDictionaryAddValue(options
, kSecPolicyCheckExtendedKeyUsage
,
1615 /* Basic X.509 policy with the additional requirements that the chain
1616 length is 3, it's anchored at the AppleCA and the leaf certificate
1617 has issuer "Apple iPhone Certification Authority". */
1618 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
1619 CFSTR("Apple iPhone Certification Authority"));
1621 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1622 require(SecPolicyAddAppleAnchorOptions(options
), errOut
);
1630 static SecPolicyRef
SecPolicyCreateAppleCertificationAuthorityPolicy(CFStringRef policyOID
, CFStringRef leafName
, bool honorValidity
)
1632 CFMutableDictionaryRef options
= NULL
;
1633 SecPolicyRef result
= NULL
;
1635 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1636 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1638 require(SecPolicyAddAppleCertificationAuthorityOptions(options
, honorValidity
), errOut
);
1640 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
, leafName
);
1642 require(result
= SecPolicyCreate(policyOID
, options
),
1646 CFReleaseSafe(options
);
1651 SecPolicyRef
SecPolicyCreateOTATasking(void)
1653 return SecPolicyCreateAppleCertificationAuthorityPolicy(kSecPolicyOIDOTATasking
, CFSTR("OTA Task Signing"), true);
1656 SecPolicyRef
SecPolicyCreateMobileAsset(void)
1658 return SecPolicyCreateAppleCertificationAuthorityPolicy(kSecPolicyOIDMobileAsset
, CFSTR("Asset Manifest Signing"), false);
1661 SecPolicyRef
SecPolicyCreateAppleIDAuthorityPolicy(void)
1663 SecPolicyRef result
= NULL
;
1664 CFMutableDictionaryRef options
= NULL
;
1665 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1666 &kCFTypeDictionaryKeyCallBacks
,
1667 &kCFTypeDictionaryValueCallBacks
), out
);
1669 //Leaf appears to be a SSL only cert, so policy should expand on that policy
1670 SecPolicyAddBasicX509Options(options
);
1672 // Apple CA anchored
1673 require(SecPolicyAddAppleAnchorOptions(options
), out
);
1675 // with the addition of the existence check of an extension with "Apple ID Sharing Certificate" oid (1.2.840.113635.100.4.7)
1676 // NOTE: this obviously intended to have gone into Extended Key Usage, but evidence of existing certs proves the contrary.
1677 add_leaf_marker(options
, &oidAppleExtendedKeyUsageAppleID
);
1679 // 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.
1680 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleID
);
1681 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleID2
);
1683 require(result
= SecPolicyCreate(kSecPolicyOIDAppleIDAuthority
, options
), out
);
1686 CFReleaseSafe(options
);
1690 static SecPolicyRef
_SecPolicyCreatePassbookCardSigner(CFStringRef cardIssuer
, CFStringRef teamIdentifier
, bool requireTeamID
)
1692 SecPolicyRef result
= NULL
;
1693 CFMutableDictionaryRef options
= NULL
;
1694 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1695 &kCFTypeDictionaryKeyCallBacks
,
1696 &kCFTypeDictionaryValueCallBacks
), out
);
1698 SecPolicyAddBasicX509Options(options
);
1699 SecPolicyAddAppleAnchorOptions(options
);
1701 if (teamIdentifier
) {
1702 // If supplied, teamIdentifier must match subject OU field
1703 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectOrganizationalUnit
, teamIdentifier
);
1706 // If not supplied, and it was required, fail
1707 require(!requireTeamID
, out
);
1710 // Must be both push and 3rd party package signing
1711 add_leaf_marker_value(options
, &oidAppleInstallerPackagingSigningExternal
, cardIssuer
);
1713 // We should check that it also has push marker, but we don't support requiring both, only either.
1714 // add_independent_oid(options, kSecPolicyCheckLeafMarkerOid, &oidApplePushServiceClient);
1716 // And Shoebox signing eku
1717 add_eku(options
, &oidAppleExtendedKeyUsageShoebox
);
1719 require(result
= SecPolicyCreate(kSecPolicyOIDApplePassbook
, options
), out
);
1722 CFReleaseSafe(options
);
1726 SecPolicyRef
SecPolicyCreatePassbookCardSigner(CFStringRef cardIssuer
, CFStringRef teamIdentifier
)
1728 return _SecPolicyCreatePassbookCardSigner(cardIssuer
, teamIdentifier
, true);
1732 SecPolicyRef
SecPolicyCreateShoeboxCardSigner(CFStringRef cardIssuer
)
1734 return _SecPolicyCreatePassbookCardSigner(cardIssuer
, nil
, false);
1737 static SecPolicyRef
CreateMobileStoreSigner(Boolean forTest
)
1740 SecPolicyRef result
= NULL
;
1741 CFMutableDictionaryRef options
= NULL
;
1742 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1743 &kCFTypeDictionaryKeyCallBacks
,
1744 &kCFTypeDictionaryValueCallBacks
), errOut
);
1745 SecPolicyAddBasicX509Options(options
);
1746 SecPolicyAddAppleAnchorOptions(options
);
1748 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1750 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
1751 CFSTR("Apple System Integration 2 Certification Authority"));
1753 add_ku(options
, kSecKeyUsageDigitalSignature
);
1755 const DERItem
* pOID
= (forTest
) ? &oidApplePolicyTestMobileStore
: &oidApplePolicyMobileStore
;
1757 add_certificate_policy_oid(options
, pOID
, NULL
);
1759 require(result
= SecPolicyCreate(kSecPolicyOIDAppleMobileStore
, options
), errOut
);
1762 CFReleaseSafe(options
);
1766 SecPolicyRef
SecPolicyCreateMobileStoreSigner(void)
1769 return CreateMobileStoreSigner(false);
1772 SecPolicyRef
SecPolicyCreateTestMobileStoreSigner(void)
1775 return CreateMobileStoreSigner(true);
1779 CF_RETURNS_RETAINED SecPolicyRef
SecPolicyCreateEscrowServiceSigner(void)
1781 SecPolicyRef result
= NULL
;
1782 CFMutableDictionaryRef options
= NULL
;
1783 CFArrayRef anArray
= NULL
;
1784 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1785 &kCFTypeDictionaryKeyCallBacks
,
1786 &kCFTypeDictionaryValueCallBacks
), errOut
);
1788 // X509, ignoring date validity
1789 SecPolicyAddBasicCertOptions(options
);
1792 add_ku(options
, kSecKeyUsageKeyEncipherment
);
1794 //add_leaf_marker(options, &oidApplePolicyEscrowService);
1795 require(SecPolicyAddChainLengthOptions(options
, 2), errOut
);
1798 Boolean anchorAdded
= false;
1799 // Get the roots by calling the SecCertificateCopyEscrowRoots
1800 anArray
= SecCertificateCopyEscrowRoots(kSecCertificateProductionEscrowRoot
);
1801 CFIndex numRoots
= 0;
1802 if (NULL
== anArray
|| 0 == (numRoots
= CFArrayGetCount(anArray
)))
1807 for (CFIndex iCnt
= 0; iCnt
< numRoots
; iCnt
++)
1809 SecCertificateRef aCert
= (SecCertificateRef
)CFArrayGetValueAtIndex(anArray
, iCnt
);
1813 CFDataRef sha_data
= SecCertificateGetSHA1Digest(aCert
);
1814 if (NULL
!= sha_data
)
1816 const UInt8
* pSHAData
= CFDataGetBytePtr(sha_data
);
1817 if (NULL
!= pSHAData
)
1819 SecPolicyAddAnchorSHA1Options(options
, pSHAData
);
1825 CFReleaseNull(anArray
);
1833 require(result
= SecPolicyCreate(kSecPolicyOIDAppleEscrowService
, options
), errOut
);
1836 CFReleaseSafe(anArray
);
1837 CFReleaseSafe(options
);
1841 CF_RETURNS_RETAINED SecPolicyRef
SecPolicyCreatePCSEscrowServiceSigner(void)
1843 SecPolicyRef result
= NULL
;
1844 CFMutableDictionaryRef options
= NULL
;
1845 CFArrayRef anArray
= NULL
;
1846 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1847 &kCFTypeDictionaryKeyCallBacks
,
1848 &kCFTypeDictionaryValueCallBacks
), errOut
);
1850 SecPolicyAddBasicX509Options(options
);
1853 add_ku(options
, kSecKeyUsageKeyEncipherment
);
1855 //add_leaf_marker(options, &oidApplePolicyEscrowService);
1856 require(SecPolicyAddChainLengthOptions(options
, 2), errOut
);
1859 Boolean anchorAdded
= false;
1860 anArray
= SecCertificateCopyEscrowRoots(kSecCertificateProductionPCSEscrowRoot
);
1861 CFIndex numRoots
= 0;
1862 if (NULL
== anArray
|| 0 == (numRoots
= CFArrayGetCount(anArray
)))
1867 for (CFIndex iCnt
= 0; iCnt
< numRoots
; iCnt
++)
1869 SecCertificateRef aCert
= (SecCertificateRef
)CFArrayGetValueAtIndex(anArray
, iCnt
);
1873 CFDataRef sha_data
= SecCertificateGetSHA1Digest(aCert
);
1874 if (NULL
!= sha_data
)
1876 const UInt8
* pSHAData
= CFDataGetBytePtr(sha_data
);
1877 if (NULL
!= pSHAData
)
1879 SecPolicyAddAnchorSHA1Options(options
, pSHAData
);
1885 CFReleaseNull(anArray
);
1893 require(result
= SecPolicyCreate(kSecPolicyOIDApplePCSEscrowService
, options
), errOut
);
1896 CFReleaseSafe(anArray
);
1897 CFReleaseSafe(options
);
1900 SecCertificateRef
SecPolicyCopyEscrowRootCertificate(void)
1902 SecCertificateRef result
= NULL
;
1907 SecPolicyRef
SecPolicyCreateConfigurationProfileSigner(void)
1909 SecPolicyRef result
= NULL
;
1910 CFMutableDictionaryRef options
= NULL
;
1911 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1912 &kCFTypeDictionaryKeyCallBacks
,
1913 &kCFTypeDictionaryValueCallBacks
), errOut
);
1915 SecPolicyAddBasicX509Options(options
);
1916 SecPolicyAddAppleAnchorOptions(options
);
1918 // Require the profile signing EKU
1919 add_eku(options
, &oidAppleExtendedKeyUsageProfileSigning
);
1921 require(result
= SecPolicyCreate(kSecPolicyOIDAppleProfileSigner
, options
), errOut
);
1924 CFReleaseSafe(options
);
1929 SecPolicyRef
SecPolicyCreateQAConfigurationProfileSigner(void)
1931 SecPolicyRef result
= NULL
;
1932 CFMutableDictionaryRef options
= NULL
;
1933 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1934 &kCFTypeDictionaryKeyCallBacks
,
1935 &kCFTypeDictionaryValueCallBacks
), errOut
);
1937 SecPolicyAddBasicX509Options(options
);
1938 SecPolicyAddAppleAnchorOptions(options
);
1940 // Require the QA profile signing EKU
1941 add_eku(options
, &oidAppleExtendedKeyUsageQAProfileSigning
);
1943 require(result
= SecPolicyCreate(kSecPolicyOIDAppleQAProfileSigner
, options
), errOut
);
1946 CFReleaseSafe(options
);
1950 #if TARGET_OS_IPHONE
1951 SecPolicyRef
SecPolicyCreateOTAPKISigner(void)
1953 SecPolicyRef result
= NULL
;
1954 CFMutableDictionaryRef options
= NULL
;
1955 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1956 &kCFTypeDictionaryKeyCallBacks
,
1957 &kCFTypeDictionaryValueCallBacks
), errOut
);
1958 SecPolicyAddBasicX509Options(options
);
1960 SecPolicyAddAnchorSHA1Options(options
, kApplePKISettingsAuthority
);
1961 require(SecPolicyAddChainLengthOptions(options
, 2), errOut
);
1963 require(result
= SecPolicyCreate(kSecPolicyOIDAppleOTAPKIAssetSigner
, options
), errOut
);
1966 CFReleaseSafe(options
);
1972 SecPolicyRef
SecPolicyCreateTestOTAPKISigner(void)
1974 SecPolicyRef result
= NULL
;
1975 CFMutableDictionaryRef options
= NULL
;
1976 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1977 &kCFTypeDictionaryKeyCallBacks
,
1978 &kCFTypeDictionaryValueCallBacks
), errOut
);
1979 SecPolicyAddBasicX509Options(options
);
1981 SecPolicyAddAnchorSHA1Options(options
, kAppleTestPKISettingsAuthority
);
1982 require(SecPolicyAddChainLengthOptions(options
, 2), errOut
);
1984 require(result
= SecPolicyCreate(kSecPolicyOIDAppleTestOTAPKIAssetSigner
, options
), errOut
);
1987 CFReleaseSafe(options
);
1992 @function SecPolicyCreateAppleSMPEncryption
1993 @abstract Check for intermediate certificate 'Apple System Integration CA - G3' by name,
1994 and root certificate 'Apple Root CA - G3' by hash.
1995 Leaf cert must have Key Encipherment usage.
1996 Leaf cert must have Apple SMP Encryption marker OID (1.2.840.113635.100.6.30).
1997 Intermediate must have marker OID (1.2.840.113635.100.6.2.13).
1999 SecPolicyRef
SecPolicyCreateAppleSMPEncryption(void)
2001 SecPolicyRef result
= NULL
;
2002 CFMutableDictionaryRef options
= NULL
;
2003 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2004 &kCFTypeDictionaryKeyCallBacks
,
2005 &kCFTypeDictionaryValueCallBacks
), errOut
);
2006 SecPolicyAddBasicCertOptions(options
);
2008 SecPolicyAddAnchorSHA1Options(options
, kAppleRootCA_ECC_SHA1
);
2009 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2011 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2012 CFSTR("Apple System Integration CA - G3"));
2014 // Check that leaf has extension with "Apple SMP Encryption" oid (1.2.840.113635.100.6.30)
2015 add_leaf_marker(options
, &oidAppleCertExtAppleSMPEncryption
);
2017 // Check that intermediate has extension (1.2.840.113635.100.6.2.13)
2018 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleSystemIntgG3
);
2020 add_ku(options
, kSecKeyUsageKeyEncipherment
);
2022 // Ensure that revocation is checked (OCSP)
2023 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kCFBooleanFalse
);
2025 require(result
= SecPolicyCreate(kSecPolicyAppleSMPEncryption
, options
), errOut
);
2028 CFReleaseSafe(options
);
2033 @function SecPolicyCreateTestAppleSMPEncryption
2034 @abstract Check for intermediate certificate 'Test Apple System Integration CA - ECC' by name,
2035 and root certificate 'Test Apple Root CA - ECC' by hash.
2036 Leaf cert must have Key Encipherment usage. Other checks TBD.
2038 SecPolicyRef
SecPolicyCreateTestAppleSMPEncryption(void)
2040 SecPolicyRef result
= NULL
;
2041 CFMutableDictionaryRef options
= NULL
;
2042 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2043 &kCFTypeDictionaryKeyCallBacks
,
2044 &kCFTypeDictionaryValueCallBacks
), errOut
);
2045 SecPolicyAddBasicCertOptions(options
);
2047 SecPolicyAddAnchorSHA1Options(options
, kTestAppleRootCA_ECC_SHA1
);
2048 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2050 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2051 CFSTR("Test Apple System Integration CA - ECC"));
2053 add_ku(options
, kSecKeyUsageKeyEncipherment
);
2055 // Ensure that revocation is checked (OCSP)
2056 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kCFBooleanFalse
);
2058 require(result
= SecPolicyCreate(kSecPolicyAppleTestSMPEncryption
, options
), errOut
);
2061 CFReleaseSafe(options
);
2066 SecPolicyRef
SecPolicyCreateAppleIDValidationRecordSigningPolicy(void)
2068 SecPolicyRef result
= NULL
;
2069 CFMutableDictionaryRef options
= NULL
;
2070 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2071 &kCFTypeDictionaryKeyCallBacks
,
2072 &kCFTypeDictionaryValueCallBacks
), errOut
);
2074 //Leaf appears to be a SSL only cert, so policy should expand on that policy
2075 SecPolicyAddBasicX509Options(options
);
2077 // Apple CA anchored
2078 require(SecPolicyAddAppleAnchorOptions(options
), errOut
);
2080 // Check for an extension with " Apple ID Validation Record Signing" oid (1.2.840.113635.100.6.25)
2081 add_leaf_marker(options
, &oidAppleCertExtensionAppleIDRecordValidationSigning
);
2083 // and validate that intermediate has extension
2084 // Application Integration Intermediate Certificate (1.2.840.113635.100.6.2.3)
2085 // and also validate that intermediate has extension
2086 // System Integration 2 Intermediate Certificate (1.2.840.113635.100.6.2.10)
2087 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleID
);
2088 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleSystemIntg2
);
2090 // Ensure that revocation is checked (OCSP)
2091 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kCFBooleanFalse
);
2093 require(result
= SecPolicyCreate(kSecPolicyOIDAppleIDValidationRecordSigningPolicy
, options
), errOut
);
2096 CFReleaseSafe(options
);
2101 @function SecPolicyCreateAppleIDSService
2102 @abstract Ensure we're appropriately pinned to the IDS service (SSL + Apple restrictions)
2104 SecPolicyRef
SecPolicyCreateAppleIDSService(CFStringRef hostname
)
2106 return SecPolicyCreateSSL(true, hostname
);
2110 @function SecPolicyCreateApplePushService
2111 @abstract Ensure we're appropriately pinned to the Push service (SSL + Apple restrictions)
2113 SecPolicyRef
SecPolicyCreateApplePushService(CFStringRef hostname
)
2115 return SecPolicyCreateSSL(true, hostname
);
2119 @function SecPolicyCreateAppleMMCSService
2120 @abstract Ensure we're appropriately pinned to the IDS service (SSL + Apple restrictions)
2122 SecPolicyRef
SecPolicyCreateAppleMMCSService(CFStringRef hostname
)
2124 return SecPolicyCreateSSL(true, hostname
);
2128 @function SecPolicyCreateAppleSSLService
2129 @abstract Ensure we're appropriately pinned to an Apple server (SSL + Apple restrictions)
2131 SecPolicyRef
SecPolicyCreateAppleSSLService(CFStringRef hostname
)
2133 // SSL server, pinned to an Apple intermediate
2134 SecPolicyRef policy
= SecPolicyCreateSSL(true, hostname
);
2135 CFMutableDictionaryRef options
= NULL
;
2136 require(policy
, errOut
);
2138 // change options for SSL policy evaluation
2139 require((options
=(CFMutableDictionaryRef
)policy
->_options
) != NULL
, errOut
);
2141 // Apple CA anchored
2142 require(SecPolicyAddAppleAnchorOptions(options
), errOut
);
2144 // Check leaf for Apple Server Authentication marker oid (1.2.840.113635.100.6.27.1)
2145 add_leaf_marker(options
, &oidAppleCertExtAppleServerAuthentication
);
2147 // Check intermediate for Apple Server Authentication intermediate marker (1.2.840.113635.100.6.2.12)
2148 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleServerAuthentication
);
2150 // Ensure that revocation is checked (OCSP only)
2151 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kCFBooleanFalse
);
2156 CFReleaseSafe(options
);
2157 CFReleaseSafe(policy
);
2161 #endif // TARGET_OS_IPHONE