]> git.saurik.com Git - apple/security.git/blob - OSX/sec/Security/SecPolicy.c
Security-57740.51.3.tar.gz
[apple/security.git] / OSX / sec / Security / SecPolicy.c
1 /*
2 * Copyright (c) 2007-2015 Apple Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24 /*
25 * SecPolicy.c - Implementation of various X.509 certificate trust policies
26 */
27
28 #include <Security/SecPolicyInternal.h>
29 #include <Security/SecPolicyPriv.h>
30 #include <AssertMacros.h>
31 #include <pthread.h>
32 #include <utilities/debugging.h>
33 #include <Security/SecInternal.h>
34 #include <CoreFoundation/CFDictionary.h>
35 #include <CoreFoundation/CFNumber.h>
36 #include <CoreFoundation/CFRuntime.h>
37 #include <CoreFoundation/CFString.h>
38 #include <CoreFoundation/CFTimeZone.h>
39 #include <Security/SecCertificateInternal.h>
40 #include <Security/SecCertificatePriv.h>
41 #include <Security/SecItem.h>
42 #include <libDER/oidsPriv.h>
43 #include <utilities/SecCFError.h>
44 #include <utilities/SecCFWrappers.h>
45 #include <utilities/array_size.h>
46 #include <ipc/securityd_client.h>
47
48 #include <utilities/SecInternalReleasePriv.h>
49
50 /********************************************************
51 **************** SecPolicy Constants *******************
52 ********************************************************/
53 // MARK: -
54 // MARK: SecPolicy Constants
55
56 #define SEC_CONST_DECL(k,v) const CFStringRef k = CFSTR(v);
57
58 /********************************************************
59 ************** Unverified Leaf Checks ******************
60 ********************************************************/
61 SEC_CONST_DECL (kSecPolicyCheckSSLHostname, "SSLHostname");
62 SEC_CONST_DECL (kSecPolicyCheckEmail, "email");
63
64 /* Checks that the issuer of the leaf has exactly one Common Name and that it
65 matches the specified string. */
66 SEC_CONST_DECL (kSecPolicyCheckIssuerCommonName, "IssuerCommonName");
67
68 /* Checks that the leaf has exactly one Common Name and that it
69 matches the specified string. */
70 SEC_CONST_DECL (kSecPolicyCheckSubjectCommonName, "SubjectCommonName");
71
72 /* Checks that the leaf has exactly one Common Name and that it has the
73 specified string as a prefix. */
74 SEC_CONST_DECL (kSecPolicyCheckSubjectCommonNamePrefix, "SubjectCommonNamePrefix");
75
76 /* Checks that the leaf has exactly one Common Name and that it
77 matches the specified "<string>" or "TEST <string> TEST". */
78 SEC_CONST_DECL (kSecPolicyCheckSubjectCommonNameTEST, "SubjectCommonNameTEST");
79
80 /* Checks that the leaf has exactly one Organization and that it
81 matches the specified string. */
82 SEC_CONST_DECL (kSecPolicyCheckSubjectOrganization, "SubjectOrganization");
83
84 /* Checks that the leaf has exactly one Organizational Unit and that it
85 matches the specified string. */
86 SEC_CONST_DECL (kSecPolicyCheckSubjectOrganizationalUnit, "SubjectOrganizationalUnit");
87
88 /* Check that the leaf is not valid before the specified date (or verifyDate
89 if none is provided?). */
90 SEC_CONST_DECL (kSecPolicyCheckNotValidBefore, "NotValidBefore");
91
92 SEC_CONST_DECL (kSecPolicyCheckEAPTrustedServerNames, "EAPTrustedServerNames");
93
94 SEC_CONST_DECL (kSecPolicyCheckCertificatePolicy, "CertificatePolicy");
95
96 SEC_CONST_DECL (kSecPolicyCheckLeafMarkerOid, "CheckLeafMarkerOid");
97 SEC_CONST_DECL (kSecPolicyCheckLeafMarkerOidWithoutValueCheck, "CheckLeafMarkerOidNoValueCheck");
98 SEC_CONST_DECL (kSecPolicyCheckLeafMarkersProdAndQA, "CheckLeafMarkersProdAndQA");
99
100 /* options for kSecPolicyCheckLeafMarkersProdAndQA */
101 SEC_CONST_DECL (kSecPolicyLeafMarkerProd, "ProdMarker");
102 SEC_CONST_DECL (kSecPolicyLeafMarkerQA, "QAMarker");
103
104 #if 0
105 /* Check for basic constraints on leaf to be valid. (rfc5280 check) */
106 SEC_CONST_DECL (kSecPolicyCheckLeafBasicConstraints, "LeafBasicContraints");
107 #endif
108
109 SEC_CONST_DECL (kSecPolicyCheckBlackListedLeaf, "BlackListedLeaf");
110 SEC_CONST_DECL (kSecPolicyCheckGrayListedLeaf, "GrayListedLeaf");
111
112 /********************************************************
113 *********** Unverified Intermediate Checks *************
114 ********************************************************/
115 SEC_CONST_DECL (kSecPolicyCheckKeyUsage, "KeyUsage"); /* (rfc5280 check) */
116 SEC_CONST_DECL (kSecPolicyCheckExtendedKeyUsage, "ExtendedKeyUsage"); /* (rfc5280 check) */
117 SEC_CONST_DECL (kSecPolicyCheckBasicConstraints, "BasicConstraints"); /* (rfc5280 check) */
118 SEC_CONST_DECL (kSecPolicyCheckQualifiedCertStatements, "QualifiedCertStatements"); /* (rfc5280 check) */
119 SEC_CONST_DECL (kSecPolicyCheckIntermediateSPKISHA256, "IntermediateSPKISHA256");
120 SEC_CONST_DECL (kSecPolicyCheckIntermediateEKU, "IntermediateEKU");
121 SEC_CONST_DECL (kSecPolicyCheckIntermediateMarkerOid, "CheckIntermediateMarkerOid");
122 SEC_CONST_DECL (kSecPolicyCheckIntermediateOrganization, "CheckIntermediateOrganization");
123 SEC_CONST_DECL (kSecPolicyCheckIntermediateCountry, "CheckIntermediateCountry");
124
125 /********************************************************
126 ************** Unverified Anchor Checks ****************
127 ********************************************************/
128 SEC_CONST_DECL (kSecPolicyCheckAnchorSHA1, "AnchorSHA1");
129 SEC_CONST_DECL (kSecPolicyCheckAnchorSHA256, "AnchorSHA256");
130
131 /* Fake key for isAnchored check. */
132 SEC_CONST_DECL (kSecPolicyCheckAnchorTrusted, "AnchorTrusted");
133
134 /* Anchor is one of the apple trust anchors */
135 SEC_CONST_DECL (kSecPolicyCheckAnchorApple, "AnchorApple");
136
137 /* options for kSecPolicyCheckAnchorApple */
138 SEC_CONST_DECL (kSecPolicyAppleAnchorIncludeTestRoots, "AnchorAppleTestRoots");
139
140 /********************************************************
141 *********** Unverified Certificate Checks **************
142 ********************************************************/
143 /* Unverified Certificate Checks (any of the above) */
144 SEC_CONST_DECL (kSecPolicyCheckNonEmptySubject, "NonEmptySubject");
145 SEC_CONST_DECL (kSecPolicyCheckIdLinkage, "IdLinkage") /* (rfc5280 check) */
146 SEC_CONST_DECL (kSecPolicyCheckValidIntermediates, "ValidIntermediates");
147 SEC_CONST_DECL (kSecPolicyCheckValidLeaf, "ValidLeaf");
148 SEC_CONST_DECL (kSecPolicyCheckValidRoot, "ValidRoot");
149 SEC_CONST_DECL (kSecPolicyCheckWeakIntermediates, "WeakIntermediates");
150 SEC_CONST_DECL (kSecPolicyCheckWeakLeaf, "WeakLeaf");
151 SEC_CONST_DECL (kSecPolicyCheckWeakRoot, "WeakRoot");
152 SEC_CONST_DECL (kSecPolicyCheckKeySize, "KeySize");
153 SEC_CONST_DECL (kSecPolicyCheckSignatureHashAlgorithms, "SignatureHashAlgorithms");
154
155 /********************************************************
156 **************** Verified Path Checks ******************
157 ********************************************************/
158 /* (rfc5280 check) Ideally we should dynamically track all the extensions
159 we processed for each certificate and fail this test if any critical
160 extensions remain. */
161 SEC_CONST_DECL (kSecPolicyCheckCriticalExtensions, "CriticalExtensions");
162
163 /* Check that the certificate chain length matches the specificed CFNumberRef
164 length. */
165 SEC_CONST_DECL (kSecPolicyCheckChainLength, "ChainLength");
166
167 /* (rfc5280 check) */
168 SEC_CONST_DECL (kSecPolicyCheckBasicCertificateProcessing, "BasicCertificateProcessing");
169
170 /* Check Certificate Transparency if specified. */
171 SEC_CONST_DECL (kSecPolicyCheckCertificateTransparency, "CertificateTransparency");
172
173 SEC_CONST_DECL (kSecPolicyCheckGrayListedKey, "GrayListedKey");
174 SEC_CONST_DECL (kSecPolicyCheckBlackListedKey, "BlackListedKey");
175
176 SEC_CONST_DECL (kSecPolicyCheckUsageConstraints, "UsageConstraints");
177
178 SEC_CONST_DECL (kSecPolicyCheckSystemTrustedWeakHash, "SystemTrustedWeakHash");
179
180 /********************************************************
181 ******************* Feature toggles ********************
182 ********************************************************/
183
184 /* Check revocation if specified. */
185 SEC_CONST_DECL (kSecPolicyCheckExtendedValidation, "ExtendedValidation");
186 SEC_CONST_DECL (kSecPolicyCheckRevocation, "Revocation");
187 SEC_CONST_DECL (kSecPolicyCheckRevocationResponseRequired, "RevocationResponseRequired");
188 SEC_CONST_DECL (kSecPolicyCheckRevocationOCSP, "OCSP");
189 SEC_CONST_DECL (kSecPolicyCheckRevocationCRL, "CRL");
190 SEC_CONST_DECL (kSecPolicyCheckRevocationAny, "AnyRevocationMethod");
191 SEC_CONST_DECL (kSecPolicyCheckRevocationOnline, "Online");
192
193 /* If present and true, we never go out to the network for anything
194 (OCSP, CRL or CA Issuer checking) but just used cached data instead. */
195 SEC_CONST_DECL (kSecPolicyCheckNoNetworkAccess, "NoNetworkAccess");
196
197 /* Public policy names. */
198 SEC_CONST_DECL (kSecPolicyAppleX509Basic, "1.2.840.113635.100.1.2");
199 SEC_CONST_DECL (kSecPolicyAppleSSL, "1.2.840.113635.100.1.3");
200 SEC_CONST_DECL (kSecPolicyAppleSMIME, "1.2.840.113635.100.1.8");
201 SEC_CONST_DECL (kSecPolicyAppleEAP, "1.2.840.113635.100.1.9");
202 SEC_CONST_DECL (kSecPolicyAppleSWUpdateSigning, "1.2.840.113635.100.1.10");
203 SEC_CONST_DECL (kSecPolicyAppleIPsec, "1.2.840.113635.100.1.11");
204 SEC_CONST_DECL (kSecPolicyApplePKINITClient, "1.2.840.113635.100.1.14");
205 SEC_CONST_DECL (kSecPolicyApplePKINITServer, "1.2.840.113635.100.1.15");
206 SEC_CONST_DECL (kSecPolicyAppleCodeSigning, "1.2.840.113635.100.1.16");
207 SEC_CONST_DECL (kSecPolicyApplePackageSigning, "1.2.840.113635.100.1.17");
208 SEC_CONST_DECL (kSecPolicyAppleIDValidation, "1.2.840.113635.100.1.18");
209 SEC_CONST_DECL (kSecPolicyMacAppStoreReceipt, "1.2.840.113635.100.1.19");
210 SEC_CONST_DECL (kSecPolicyAppleTimeStamping, "1.2.840.113635.100.1.20");
211 SEC_CONST_DECL (kSecPolicyAppleRevocation, "1.2.840.113635.100.1.21");
212 SEC_CONST_DECL (kSecPolicyApplePassbookSigning, "1.2.840.113635.100.1.22");
213 SEC_CONST_DECL (kSecPolicyAppleMobileStore, "1.2.840.113635.100.1.23");
214 SEC_CONST_DECL (kSecPolicyAppleEscrowService, "1.2.840.113635.100.1.24");
215 SEC_CONST_DECL (kSecPolicyAppleProfileSigner, "1.2.840.113635.100.1.25");
216 SEC_CONST_DECL (kSecPolicyAppleQAProfileSigner, "1.2.840.113635.100.1.26");
217 SEC_CONST_DECL (kSecPolicyAppleTestMobileStore, "1.2.840.113635.100.1.27");
218 SEC_CONST_DECL (kSecPolicyAppleOTAPKISigner, "1.2.840.113635.100.1.28");
219 SEC_CONST_DECL (kSecPolicyAppleTestOTAPKISigner, "1.2.840.113635.100.1.29");
220 SEC_CONST_DECL (kSecPolicyAppleIDValidationRecordSigningPolicy, "1.2.840.113635.100.1.30");
221 SEC_CONST_DECL (kSecPolicyAppleIDValidationRecordSigning, "1.2.840.113635.100.1.30");
222 SEC_CONST_DECL (kSecPolicyAppleSMPEncryption, "1.2.840.113635.100.1.31");
223 SEC_CONST_DECL (kSecPolicyAppleTestSMPEncryption, "1.2.840.113635.100.1.32");
224 SEC_CONST_DECL (kSecPolicyAppleServerAuthentication, "1.2.840.113635.100.1.33");
225 SEC_CONST_DECL (kSecPolicyApplePCSEscrowService, "1.2.840.113635.100.1.34");
226 SEC_CONST_DECL (kSecPolicyApplePPQSigning, "1.2.840.113635.100.1.35");
227 SEC_CONST_DECL (kSecPolicyAppleTestPPQSigning, "1.2.840.113635.100.1.36");
228 // Not in use. Use kSecPolicyAppleTVOSApplicationSigning instead.
229 // SEC_CONST_DECL (kSecPolicyAppleATVAppSigning, "1.2.840.113635.100.1.37");
230 // SEC_CONST_DECL (kSecPolicyAppleTestATVAppSigning, "1.2.840.113635.100.1.38");
231 SEC_CONST_DECL (kSecPolicyApplePayIssuerEncryption, "1.2.840.113635.100.1.39");
232 SEC_CONST_DECL (kSecPolicyAppleOSXProvisioningProfileSigning, "1.2.840.113635.100.1.40");
233 SEC_CONST_DECL (kSecPolicyAppleATVVPNProfileSigning, "1.2.840.113635.100.1.41");
234 SEC_CONST_DECL (kSecPolicyAppleAST2DiagnosticsServerAuth, "1.2.840.113635.100.1.42");
235 SEC_CONST_DECL (kSecPolicyAppleEscrowProxyServerAuth, "1.2.840.113635.100.1.43");
236 SEC_CONST_DECL (kSecPolicyAppleFMiPServerAuth, "1.2.840.113635.100.1.44");
237 SEC_CONST_DECL (kSecPolicyAppleMMCSService, "1.2.840.113635.100.1.45");
238 SEC_CONST_DECL (kSecPolicyAppleGSService, "1.2.840.113635.100.1.46");
239 SEC_CONST_DECL (kSecPolicyApplePPQService, "1.2.840.113635.100.1.47");
240 SEC_CONST_DECL (kSecPolicyAppleHomeKitServerAuth, "1.2.840.113635.100.1.48");
241 SEC_CONST_DECL (kSecPolicyAppleiPhoneActivation, "1.2.840.113635.100.1.49");
242 SEC_CONST_DECL (kSecPolicyAppleiPhoneDeviceCertificate, "1.2.840.113635.100.1.50");
243 SEC_CONST_DECL (kSecPolicyAppleFactoryDeviceCertificate, "1.2.840.113635.100.1.51");
244 SEC_CONST_DECL (kSecPolicyAppleiAP, "1.2.840.113635.100.1.52");
245 SEC_CONST_DECL (kSecPolicyAppleiTunesStoreURLBag, "1.2.840.113635.100.1.53");
246 SEC_CONST_DECL (kSecPolicyAppleiPhoneApplicationSigning, "1.2.840.113635.100.1.54");
247 SEC_CONST_DECL (kSecPolicyAppleiPhoneProfileApplicationSigning, "1.2.840.113635.100.1.55");
248 SEC_CONST_DECL (kSecPolicyAppleiPhoneProvisioningProfileSigning, "1.2.840.113635.100.1.56");
249 SEC_CONST_DECL (kSecPolicyAppleLockdownPairing, "1.2.840.113635.100.1.57");
250 SEC_CONST_DECL (kSecPolicyAppleURLBag, "1.2.840.113635.100.1.58");
251 SEC_CONST_DECL (kSecPolicyAppleOTATasking, "1.2.840.113635.100.1.59");
252 SEC_CONST_DECL (kSecPolicyAppleMobileAsset, "1.2.840.113635.100.1.60");
253 SEC_CONST_DECL (kSecPolicyAppleIDAuthority, "1.2.840.113635.100.1.61");
254 SEC_CONST_DECL (kSecPolicyAppleGenericApplePinned, "1.2.840.113635.100.1.62");
255 SEC_CONST_DECL (kSecPolicyAppleGenericAppleSSLPinned, "1.2.840.113635.100.1.63");
256 SEC_CONST_DECL (kSecPolicyAppleSoftwareSigning, "1.2.840.113635.100.1.64");
257 SEC_CONST_DECL (kSecPolicyAppleExternalDeveloper, "1.2.840.113635.100.1.65");
258 SEC_CONST_DECL (kSecPolicyAppleOCSPSigner, "1.2.840.113635.100.1.66");
259 SEC_CONST_DECL (kSecPolicyAppleIDSService, "1.2.840.113635.100.1.67");
260 SEC_CONST_DECL (kSecPolicyAppleIDSServiceContext, "1.2.840.113635.100.1.68");
261 SEC_CONST_DECL (kSecPolicyApplePushService, "1.2.840.113635.100.1.69");
262 SEC_CONST_DECL (kSecPolicyAppleLegacyPushService, "1.2.840.113635.100.1.70");
263 SEC_CONST_DECL (kSecPolicyAppleTVOSApplicationSigning, "1.2.840.113635.100.1.71");
264 SEC_CONST_DECL (kSecPolicyAppleUniqueDeviceIdentifierCertificate, "1.2.840.113635.100.1.72");
265 SEC_CONST_DECL (kSecPolicyAppleEscrowProxyCompatibilityServerAuth, "1.2.840.113635.100.1.73");
266 SEC_CONST_DECL (kSecPolicyAppleMMCSCompatibilityServerAuth, "1.2.840.113635.100.1.74");
267 SEC_CONST_DECL (kSecPolicyAppleSecureIOStaticAsset, "1.2.840.113635.100.1.75");
268 SEC_CONST_DECL (kSecPolicyAppleWarsaw, "1.2.840.113635.100.1.76");
269 SEC_CONST_DECL (kSecPolicyAppleiCloudSetupServerAuth, "1.2.840.113635.100.1.77");
270 SEC_CONST_DECL (kSecPolicyAppleiCloudSetupCompatibilityServerAuth, "1.2.840.113635.100.1.78");
271
272 SEC_CONST_DECL (kSecPolicyOid, "SecPolicyOid");
273 SEC_CONST_DECL (kSecPolicyName, "SecPolicyName");
274 SEC_CONST_DECL (kSecPolicyClient, "SecPolicyClient");
275 SEC_CONST_DECL (kSecPolicyRevocationFlags, "SecPolicyRevocationFlags");
276 SEC_CONST_DECL (kSecPolicyTeamIdentifier, "SecPolicyTeamIdentifier");
277 SEC_CONST_DECL (kSecPolicyContext, "SecPolicyContext");
278 SEC_CONST_DECL (kSecPolicyPolicyName, "SecPolicyPolicyName");
279 SEC_CONST_DECL (kSecPolicyIntermediateMarkerOid, "SecPolicyIntermediateMarkerOid");
280 SEC_CONST_DECL (kSecPolicyLeafMarkerOid, "SecPolicyLeafMarkerOid");
281 SEC_CONST_DECL (kSecPolicyRootDigest, "SecPolicyRootDigest");
282
283 SEC_CONST_DECL (kSecPolicyKU_DigitalSignature, "CE_KU_DigitalSignature");
284 SEC_CONST_DECL (kSecPolicyKU_NonRepudiation, "CE_KU_NonRepudiation");
285 SEC_CONST_DECL (kSecPolicyKU_KeyEncipherment, "CE_KU_KeyEncipherment");
286 SEC_CONST_DECL (kSecPolicyKU_DataEncipherment, "CE_KU_DataEncipherment");
287 SEC_CONST_DECL (kSecPolicyKU_KeyAgreement, "CE_KU_KeyAgreement");
288 SEC_CONST_DECL (kSecPolicyKU_KeyCertSign, "CE_KU_KeyCertSign");
289 SEC_CONST_DECL (kSecPolicyKU_CRLSign, "CE_KU_CRLSign");
290 SEC_CONST_DECL (kSecPolicyKU_EncipherOnly, "CE_KU_EncipherOnly");
291 SEC_CONST_DECL (kSecPolicyKU_DecipherOnly, "CE_KU_DecipherOnly");
292
293 /* Private policy names */
294 static CFStringRef kSecPolicyNameBasicX509 = CFSTR("basicX509");
295 static CFStringRef kSecPolicyNameSSLServer = CFSTR("sslServer");
296 static CFStringRef kSecPolicyNameSSLClient = CFSTR("sslClient");
297 static CFStringRef kSecPolicyNameiPhoneActivation = CFSTR("iPhoneActivation");
298 static CFStringRef kSecPolicyNameiPhoneDeviceCertificate =
299 CFSTR("iPhoneDeviceCertificate");
300 static CFStringRef kSecPolicyNameFactoryDeviceCertificate =
301 CFSTR("FactoryDeviceCertificate");
302 static CFStringRef kSecPolicyNameiAP = CFSTR("iAP");
303 static CFStringRef kSecPolicyNameiTunesStoreURLBag = CFSTR("iTunesStoreURLBag");
304 static CFStringRef kSecPolicyNameEAPServer = CFSTR("eapServer");
305 static CFStringRef kSecPolicyNameEAPClient = CFSTR("eapClient");
306 static CFStringRef kSecPolicyNameIPSecServer = CFSTR("ipsecServer");
307 static CFStringRef kSecPolicyNameIPSecClient = CFSTR("ipsecClient");
308 static CFStringRef kSecPolicyNameiPhoneApplicationSigning =
309 CFSTR("iPhoneApplicationSigning");
310 static CFStringRef kSecPolicyNameiPhoneProfileApplicationSigning =
311 CFSTR("iPhoneProfileApplicationSigning");
312 static CFStringRef kSecPolicyNameiPhoneProvisioningProfileSigning =
313 CFSTR("iPhoneProvisioningProfileSigning");
314 static CFStringRef kSecPolicyNameAppleSWUpdateSigning = CFSTR("AppleSWUpdateSigning");
315 static CFStringRef kSecPolicyNameAppleTVOSApplicationSigning =
316 CFSTR("AppleTVApplicationSigning");
317 static CFStringRef kSecPolicyNameRevocation = CFSTR("revocation");
318 static CFStringRef kSecPolicyNameOCSPSigner = CFSTR("OCSPSigner");
319 static CFStringRef kSecPolicyNameSMIME = CFSTR("SMIME");
320 static CFStringRef kSecPolicyNameCodeSigning = CFSTR("CodeSigning");
321 static CFStringRef kSecPolicyNamePackageSigning = CFSTR("PackageSigning");
322 static CFStringRef kSecPolicyNameLockdownPairing = CFSTR("LockdownPairing");
323 static CFStringRef kSecPolicyNameURLBag = CFSTR("URLBag");
324 static CFStringRef kSecPolicyNameOTATasking = CFSTR("OTATasking");
325 static CFStringRef kSecPolicyNameMobileAsset = CFSTR("MobileAsset");
326 static CFStringRef kSecPolicyNameAppleIDAuthority = CFSTR("AppleIDAuthority");
327 static CFStringRef kSecPolicyNameMacAppStoreReceipt = CFSTR("MacAppStoreReceipt");
328 static CFStringRef kSecPolicyNameAppleTimeStamping = CFSTR("AppleTimeStamping");
329 static CFStringRef kSecPolicyNameApplePassbook = CFSTR("ApplePassbook");
330 static CFStringRef kSecPolicyNameAppleMobileStore = CFSTR("AppleMobileStore");
331 static CFStringRef kSecPolicyNameAppleTestMobileStore = CFSTR("AppleTestMobileStore");
332 static CFStringRef kSecPolicyNameAppleEscrowService = CFSTR("AppleEscrowService");
333 static CFStringRef kSecPolicyNameApplePCSEscrowService = CFSTR("ApplePCSEscrowService");
334 static CFStringRef kSecPolicyNameAppleProfileSigner = CFSTR("AppleProfileSigner");
335 static CFStringRef kSecPolicyNameAppleQAProfileSigner = CFSTR("AppleQAProfileSigner");
336 static CFStringRef kSecPolicyNameAppleOTAPKIAssetSigner = CFSTR("AppleOTAPKIAssetSigner");
337 static CFStringRef kSecPolicyNameAppleTestOTAPKIAssetSigner = CFSTR("AppleTestOTAPKIAssetSigner");
338 static CFStringRef kSecPolicyNameAppleIDValidationRecordSigningPolicy = CFSTR("AppleIDValidationRecordSigningPolicy");
339 static CFStringRef kSecPolicyNameApplePayIssuerEncryption = CFSTR("ApplePayIssuerEncryption");
340 static CFStringRef kSecPolicyNameAppleOSXProvisioningProfileSigning = CFSTR("AppleOSXProvisioningProfileSigning");
341 static CFStringRef kSecPolicyNameAppleATVVPNProfileSigning = CFSTR("AppleATVVPNProfileSigning");
342 static CFStringRef kSecPolicyNameAppleAST2Service = CFSTR("AST2");
343 static CFStringRef kSecPolicyNameAppleEscrowProxyService = CFSTR("Escrow");
344 static CFStringRef kSecPolicyNameAppleFMiPService = CFSTR("FMiP");
345 static CFStringRef kSecPolicyNameAppleHomeKitServerAuth = CFSTR("HomeKit");
346 static CFStringRef kSecPolicyNameAppleExternalDeveloper = CFSTR("Developer");
347 static CFStringRef kSecPolicyNameAppleSoftwareSigning = CFSTR("SoftwareSigning");
348 static CFStringRef kSecPolicyNameAppleSMPEncryption = CFSTR("AppleSMPEncryption");
349 static CFStringRef kSecPolicyNameAppleTestSMPEncryption = CFSTR("AppleTestSMPEncryption");
350 static CFStringRef kSecPolicyNameApplePPQSigning = CFSTR("ApplePPQSigning");
351 static CFStringRef kSecPolicyNameAppleTestPPQSigning = CFSTR("AppleTestPPQSigning");
352 static CFStringRef kSecPolicyNameAppleLegacyPushService = CFSTR("AppleLegacyPushService");
353 static CFStringRef kSecPolicyNameAppleSSLService = CFSTR("AppleSSLService");
354 static CFStringRef kSecPolicyNameApplePushService = CFSTR("APN");
355 static CFStringRef kSecPolicyNameAppleIDSServiceContext = CFSTR("IDS");
356 static CFStringRef kSecPolicyNameAppleGSService = CFSTR("GS");
357 static CFStringRef kSecPolicyNameAppleMMCSService = CFSTR("MMCS");
358 static CFStringRef kSecPolicyNameApplePPQService = CFSTR("PPQ");
359 static CFStringRef kSecPolicyNameAppleUniqueDeviceCertificate = CFSTR("UCRT");
360 static CFStringRef kSecPolicyNameAppleSecureIOStaticAsset = CFSTR("SecureIOStaticAsset");
361 static CFStringRef kSecPolicyNameAppleWarsaw = CFSTR("Warsaw");
362 static CFStringRef kSecPolicyNameAppleiCloudSetupService = CFSTR("iCloudSetup");
363
364
365 /* Policies will now change to multiple categories of checks.
366
367 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.
368 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.
369
370 kSecPolicySLCheck Static Subscriber Certificate Checks
371 kSecPolicySICheck Static Subsidiary CA Checks
372 kSecPolicySACheck Static Anchor Checks
373
374 kSecPolicyDLCheck Dynamic Subscriber Certificate Checks
375 kSecPolicyDICheck Dynamic Subsidiary CA Checks
376 kSecPolicyDACheck Dynamic Anchor Checks ? not yet needed other than to
377 possibly exclude in a exception template (but those should still be per
378 certificate --- i.o.w. exceptions (or a database backed multiple role/user
379 trust store of some sort) and policies are 2 different things and this
380 text is about policies.
381
382 All static checks are only allowed to consider the certificate in isolation,
383 just given the position in the chain or the cert (leaf, intermidate, root).
384 dynamic checks can make determinations about the chain as a whole.
385
386 Static Subscriber Certificate Checks will be done up front before the
387 chainbuilder is even instantiated. If they fail and details aren't required
388 by the client (if no exceptions were present for this certificate) we could
389 short circuit fail the evaluation.
390 IDEA: These checks can dynamically add new checks...[needs work]
391 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
392 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
393 equivalent subtree from that level down. So SSL has EV as a subpolicy, but
394 EV dynamically enables the ocsp or crl or dcrl or any combination thereof subpolicies.
395
396 Static Subsidiary CA Checks will be used by the chain-builder to choose the
397 best parents to evaluate first. This feature is currently already implemented
398 but with a hardcoded is_valid(verifyTime) check. Instead we will evaluate all
399 Static Subsidiary CA Checks. The results of these checks for purposes of
400 generating details could be cached in the SecCertificatePathRefs themselves, or we can short circuit fail and recalc details on demand later.
401
402 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.
403
404 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.
405
406 Dynamic Subsidiary CA Checks might not be needed to have custom
407 implementations, since they are all done as part of the rfc5280 checks now.
408 This assumes that checks like issuer common name includes 'foo' are
409 implmented as Static Subscriber Certificate Checks instead.
410
411 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.
412
413
414 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.
415
416 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.
417
418 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.
419
420 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.
421
422 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.
423
424 We need to remember the best successful chain we find, where best is defined by: satisfies as many optional policies as possible.
425
426 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.
427
428 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.
429
430 Example sectrust operation in psuedocode:
431 */
432 /*
433 {
434 new builder(verifyTime, certificates, anchors, anchorsOnly, policies);
435 chain = builder.subscriber_only_chain;
436 foreach (policy in policies{kSecPolicySLCheck}) {
437 foreach(check in policy)
438 SecPolicyRunCheck(builder, chain, check, details);
439 foreach (subpolicy in policy) {
440 check_policy(builder, chain, subpolicy, details{subpolicy.name})
441 }
442 propagate_subpolicy_results(builder, chain, details);
443 }
444 while (chain = builder.next) {
445 for (depth = 0; p_d = policies.at_depth(depth),
446 d_p_d = dynamic_policies.at_depth(depth), p_d || d_p_d; ++depth)
447 {
448 // Modify SecPathBuilderIsPartial() to
449 // run builder_check(buildier, policies, kSecPolicySICheck) instead
450 // of SecCertificateIsValid. Also rename considerExpired to
451 // considerSIFailures.
452 foreach (policy in p_d) {
453 check_policy(builder, chain, policy, kSecPolicySICheck, depth);
454 }
455 /// Recalculate since the static checks might have added new dynamic
456 // policies.
457 d_p_d = dynamic_policies.at_depth(depth);
458 foreach (policy in d_p_d) {
459 check_policy(builder, chain, policy, kSecPolicySICheck, depth);
460 }
461 if (chain.is_anchored) {
462 foreach (policy in p_d) {
463 check_policy(builder, chain, policy, kSecPolicySACheck, depth);
464 }
465 foreach (policy in d_p_d) {
466 check_policy(builder, chain, policy, kSecPolicySACheck, depth);
467 }
468 foreach (policy in p_d) {
469 check_policy(builder, chain, policy, kSecPolicyDACheck, depth);
470 }
471 foreach (policy in d_p_d) {
472 check_policy(builder, chain, policy, kSecPolicyDACheck, depth);
473 }
474 }
475 foreach (policy in policies) {
476 check_policy(builder, chain, policy, kSecPolicySACheck, depth);
477 check_policy(builder, chain, policy, kSecPolicyDACheck, depth);
478 }
479 foreach (policy in policies{kSecPolicySDCheck}) {
480 }
481 }
482 }
483
484 check_policy(builder, chain, policy, check_class, details, depth) {
485 if (depth == 0) {
486 foreach(check in policy{check_class}) {
487 SecPolicyRunCheck(builder, chain, check, details);
488 }
489 } else {
490 depth--;
491 foreach (subpolicy in policy) {
492 if (!check_policy(builder, chain, subpolicy, check_class,
493 details{subpolicy.name}) && subpolicy.is_required, depth)
494 secpvcsetresult()
495 }
496 }
497 propagate_subpolicy_results(builder, chain, details);
498 }
499
500 */
501
502
503
504 #define kSecPolicySHA1Size 20
505 #define kSecPolicySHA256Size 32
506 __unused const UInt8 kAppleCASHA1[kSecPolicySHA1Size] = {
507 0x61, 0x1E, 0x5B, 0x66, 0x2C, 0x59, 0x3A, 0x08, 0xFF, 0x58,
508 0xD1, 0x4A, 0xE2, 0x24, 0x52, 0xD1, 0x98, 0xDF, 0x6C, 0x60
509 };
510
511 __unused static const UInt8 kAppleTESTCASHA1[kSecPolicySHA1Size] = {
512 0xbc, 0x30, 0x55, 0xc8, 0xc8, 0xd3, 0x48, 0x3f, 0xf4, 0x8d,
513 0xfe, 0x3d, 0x51, 0x75, 0x31, 0xc9, 0xf4, 0xd7, 0x4a, 0xf7
514 };
515
516 static const UInt8 kITMSCASHA1[kSecPolicySHA1Size] = {
517 0x1D, 0x33, 0x42, 0x46, 0x8B, 0x10, 0xBD, 0xE6, 0x45, 0xCE,
518 0x44, 0x6E, 0xBB, 0xE8, 0xF5, 0x03, 0x5D, 0xF8, 0x32, 0x22
519 };
520
521 static const UInt8 kFactoryDeviceCASHA1[kSecPolicySHA1Size] = {
522 0xef, 0x68, 0x73, 0x17, 0xa4, 0xf8, 0xf9, 0x4b, 0x7b, 0x21,
523 0xe2, 0x2f, 0x09, 0x8f, 0xfd, 0x6a, 0xae, 0xc0, 0x0d, 0x63
524 };
525
526 static const UInt8 kApplePKISettingsAuthority[kSecPolicySHA1Size] = {
527 0x1D, 0x0C, 0xBA, 0xAD, 0x17, 0xFD, 0x7E, 0x9E, 0x9F, 0xF1,
528 0xC9, 0xA2, 0x66, 0x79, 0x60, 0x00, 0x8B, 0xAE, 0x70, 0xB8
529 };
530
531 static const UInt8 kAppleTestPKISettingsAuthority[kSecPolicySHA1Size] = {
532 0xDB, 0xBA, 0x25, 0x0B, 0xD8, 0x62, 0x71, 0x87, 0x54, 0x7E,
533 0xD7, 0xEF, 0x11, 0x94, 0x7E, 0x82, 0xE6, 0xD8, 0x1C, 0x9A
534 };
535
536 static const UInt8 kTestAppleRootCA_ECC_SHA1[kSecPolicySHA1Size] = {
537 0x62, 0x0A, 0xED, 0x83, 0xD2, 0x97, 0x4A, 0x77, 0x56, 0x33,
538 0x83, 0xBE, 0xDB, 0xF9, 0xA1, 0xBD, 0x5F, 0xFE, 0x55, 0x7B
539 };
540
541 __unused static const UInt8 kAppleRootCA_ECC_SHA1[kSecPolicySHA1Size] = {
542 0xB5, 0x2C, 0xB0, 0x2F, 0xD5, 0x67, 0xE0, 0x35, 0x9F, 0xE8,
543 0xFA, 0x4D, 0x4C, 0x41, 0x03, 0x79, 0x70, 0xFE, 0x01, 0xB0
544 };
545
546 // MARK: -
547 // MARK: SecPolicy
548 /********************************************************
549 ****************** SecPolicy object ********************
550 ********************************************************/
551
552 static void SecPolicyDestroy(CFTypeRef cf) {
553 SecPolicyRef policy = (SecPolicyRef) cf;
554 CFRelease(policy->_oid);
555 CFReleaseSafe(policy->_name);
556 CFRelease(policy->_options);
557 }
558
559 static Boolean SecPolicyCompare(CFTypeRef cf1, CFTypeRef cf2) {
560 SecPolicyRef policy1 = (SecPolicyRef) cf1;
561 SecPolicyRef policy2 = (SecPolicyRef) cf2;
562 if (policy1->_name && policy2->_name) {
563 return CFEqual(policy1->_oid, policy2->_oid) &&
564 CFEqual(policy1->_name, policy2->_name) &&
565 CFEqual(policy1->_options, policy2->_options);
566 } else {
567 return CFEqual(policy1->_oid, policy2->_oid) &&
568 CFEqual(policy1->_options, policy2->_options);
569 }
570 }
571
572 static CFHashCode SecPolicyHash(CFTypeRef cf) {
573 SecPolicyRef policy = (SecPolicyRef) cf;
574 if (policy->_name) {
575 return CFHash(policy->_oid) + CFHash(policy->_name) + CFHash(policy->_options);
576 } else {
577 return CFHash(policy->_oid) + CFHash(policy->_options);
578 }
579 }
580
581 static CFStringRef SecPolicyCopyFormatDescription(CFTypeRef cf, CFDictionaryRef formatOptions) {
582 SecPolicyRef policy = (SecPolicyRef) cf;
583 CFMutableStringRef desc = CFStringCreateMutable(kCFAllocatorDefault, 0);
584 CFStringRef typeStr = CFCopyTypeIDDescription(CFGetTypeID(cf));
585 CFStringAppendFormat(desc, NULL,
586 CFSTR("<%@: oid: %@ name: %@ options %@"), typeStr,
587 policy->_oid, (policy->_name) ? policy->_name : CFSTR(""),
588 policy->_options);
589 CFRelease(typeStr);
590 CFStringAppend(desc, CFSTR(" >"));
591
592 return desc;
593 }
594
595 /* SecPolicy API functions. */
596 CFGiblisWithHashFor(SecPolicy);
597
598 /* AUDIT[securityd](done):
599 oid (ok) is a caller provided string, only its cf type has been checked.
600 options is a caller provided dictionary, only its cf type has been checked.
601 */
602 SecPolicyRef SecPolicyCreate(CFStringRef oid, CFStringRef name, CFDictionaryRef options) {
603 SecPolicyRef result = NULL;
604
605 require(oid, errOut);
606 require(options, errOut);
607 require(result =
608 (SecPolicyRef)_CFRuntimeCreateInstance(kCFAllocatorDefault,
609 SecPolicyGetTypeID(),
610 sizeof(struct __SecPolicy) - sizeof(CFRuntimeBase), 0), errOut);
611
612 CFRetain(oid);
613 result->_oid = oid;
614 CFRetainSafe(name);
615 result->_name = name;
616 CFRetain(options);
617 result->_options = options;
618
619 errOut:
620 return result;
621 }
622
623 #ifdef TARGET_OS_OSX
624 static void set_ku_from_properties(SecPolicyRef policy, CFDictionaryRef properties);
625 #endif
626
627 SecPolicyRef SecPolicyCreateWithProperties(CFTypeRef policyIdentifier,
628 CFDictionaryRef properties) {
629 // Creates a policy reference for a given policy object identifier.
630 // If policy-specific parameters can be supplied (e.g. hostname),
631 // attempt to obtain from input properties dictionary.
632 // Returns NULL if the given identifier is unsupported.
633
634 SecPolicyRef policy = NULL;
635 CFTypeRef name = NULL;
636 CFStringRef teamID = NULL;
637 Boolean client = false;
638 CFDictionaryRef context = NULL;
639 CFStringRef policyName = NULL, intermediateMarkerOid = NULL, leafMarkerOid = NULL;
640 CFDataRef rootDigest = NULL;
641 require(policyIdentifier && (CFStringGetTypeID() == CFGetTypeID(policyIdentifier)), errOut);
642
643 if (properties) {
644 name = CFDictionaryGetValue(properties, kSecPolicyName);
645 teamID = CFDictionaryGetValue(properties, kSecPolicyTeamIdentifier);
646
647 CFBooleanRef dictionaryClientValue;
648 client = (CFDictionaryGetValueIfPresent(properties, kSecPolicyClient, (const void **)&dictionaryClientValue) &&
649 (dictionaryClientValue != NULL) && CFEqual(kCFBooleanTrue, dictionaryClientValue));
650 context = CFDictionaryGetValue(properties, kSecPolicyContext);
651 policyName = CFDictionaryGetValue(properties, kSecPolicyPolicyName);
652 intermediateMarkerOid = CFDictionaryGetValue(properties, kSecPolicyIntermediateMarkerOid);
653 leafMarkerOid = CFDictionaryGetValue(properties, kSecPolicyLeafMarkerOid);
654 rootDigest = CFDictionaryGetValue(properties, kSecPolicyRootDigest);
655 }
656
657 /* only the EAP policy allows a non-string name */
658 if (name && !isString(name) && !CFEqual(policyIdentifier, kSecPolicyAppleEAP)) {
659 secerror("policy \"%@\" requires a string value for the %@ key", policyIdentifier, kSecPolicyName);
660 goto errOut;
661 }
662
663 /* These are in the same order as the constant declarations. */
664 /* @@@ This should be turned into a table. */
665 if (CFEqual(policyIdentifier, kSecPolicyAppleX509Basic)) {
666 policy = SecPolicyCreateBasicX509();
667 }
668 else if (CFEqual(policyIdentifier, kSecPolicyAppleSSL)) {
669 policy = SecPolicyCreateSSL(!client, name);
670 }
671 else if (CFEqual(policyIdentifier, kSecPolicyAppleSMIME)) {
672 policy = SecPolicyCreateSMIME(kSecSignSMIMEUsage | kSecAnyEncryptSMIME, name);
673 }
674 else if (CFEqual(policyIdentifier, kSecPolicyAppleEAP)) {
675 CFArrayRef array = NULL;
676 if (isString(name)) {
677 array = CFArrayCreate(kCFAllocatorDefault, (const void **)&name, 1, &kCFTypeArrayCallBacks);
678 } else if (isArray(name)) {
679 array = CFArrayCreateCopy(NULL, name);
680 }
681 policy = SecPolicyCreateEAP(!client, array);
682 CFReleaseSafe(array);
683 }
684 else if (CFEqual(policyIdentifier, kSecPolicyAppleSWUpdateSigning)) {
685 policy = SecPolicyCreateAppleSWUpdateSigning();
686 }
687 else if (CFEqual(policyIdentifier, kSecPolicyAppleIPsec)) {
688 policy = SecPolicyCreateIPSec(!client, name);
689 }
690 else if (CFEqual(policyIdentifier, kSecPolicyAppleCodeSigning)) {
691 policy = SecPolicyCreateCodeSigning();
692 }
693 else if (CFEqual(policyIdentifier, kSecPolicyApplePackageSigning)) {
694 policy = SecPolicyCreateApplePackageSigning();
695 }
696 else if (CFEqual(policyIdentifier, kSecPolicyAppleIDValidation)) {
697 policy = SecPolicyCreateAppleIDAuthorityPolicy();
698 }
699 else if (CFEqual(policyIdentifier, kSecPolicyMacAppStoreReceipt)) {
700 policy = SecPolicyCreateMacAppStoreReceipt();
701 }
702 else if (CFEqual(policyIdentifier, kSecPolicyAppleTimeStamping)) {
703 policy = SecPolicyCreateAppleTimeStamping();
704 }
705 else if (CFEqual(policyIdentifier, kSecPolicyAppleRevocation)) {
706 policy = SecPolicyCreateRevocation(kSecRevocationUseAnyAvailableMethod);
707 }
708 else if (CFEqual(policyIdentifier, kSecPolicyApplePassbookSigning)) {
709 policy = SecPolicyCreatePassbookCardSigner(name, teamID);
710 }
711 else if (CFEqual(policyIdentifier, kSecPolicyAppleMobileStore)) {
712 policy = SecPolicyCreateMobileStoreSigner();
713 }
714 else if (CFEqual(policyIdentifier, kSecPolicyAppleEscrowService)) {
715 policy = SecPolicyCreateEscrowServiceSigner();
716 }
717 else if (CFEqual(policyIdentifier, kSecPolicyAppleProfileSigner)) {
718 policy = SecPolicyCreateConfigurationProfileSigner();
719 }
720 else if (CFEqual(policyIdentifier, kSecPolicyAppleQAProfileSigner)) {
721 policy = SecPolicyCreateQAConfigurationProfileSigner();
722 }
723 else if (CFEqual(policyIdentifier, kSecPolicyAppleTestMobileStore)) {
724 policy = SecPolicyCreateTestMobileStoreSigner();
725 }
726 else if (CFEqual(policyIdentifier, kSecPolicyAppleOTAPKISigner)) {
727 policy = SecPolicyCreateOTAPKISigner();
728 }
729 else if (CFEqual(policyIdentifier, kSecPolicyAppleTestOTAPKISigner)) {
730 policy = SecPolicyCreateTestOTAPKISigner();
731 }
732 else if (CFEqual(policyIdentifier, kSecPolicyAppleIDValidationRecordSigning)) {
733 policy = SecPolicyCreateAppleIDValidationRecordSigningPolicy();
734 }
735 else if (CFEqual(policyIdentifier, kSecPolicyAppleSMPEncryption)) {
736 policy = SecPolicyCreateAppleSMPEncryption();
737 }
738 else if (CFEqual(policyIdentifier, kSecPolicyAppleTestSMPEncryption)) {
739 policy = SecPolicyCreateTestAppleSMPEncryption();
740 }
741 else if (CFEqual(policyIdentifier, kSecPolicyAppleServerAuthentication)) {
742 policy = SecPolicyCreateAppleSSLService(name);
743 }
744 else if (CFEqual(policyIdentifier, kSecPolicyApplePCSEscrowService)) {
745 policy = SecPolicyCreatePCSEscrowServiceSigner();
746 }
747 else if (CFEqual(policyIdentifier, kSecPolicyApplePPQSigning)) {
748 policy = SecPolicyCreateApplePPQSigning();
749 }
750 else if (CFEqual(policyIdentifier, kSecPolicyAppleTestPPQSigning)) {
751 policy = SecPolicyCreateTestApplePPQSigning();
752 }
753 else if (CFEqual(policyIdentifier, kSecPolicyApplePayIssuerEncryption)) {
754 policy = SecPolicyCreateApplePayIssuerEncryption();
755 }
756 else if (CFEqual(policyIdentifier, kSecPolicyAppleOSXProvisioningProfileSigning)) {
757 policy = SecPolicyCreateOSXProvisioningProfileSigning();
758 }
759 else if (CFEqual(policyIdentifier, kSecPolicyAppleATVVPNProfileSigning)) {
760 policy = SecPolicyCreateAppleATVVPNProfileSigning();
761 }
762 else if (CFEqual(policyIdentifier, kSecPolicyAppleAST2DiagnosticsServerAuth)) {
763 if (name) {
764 policy = SecPolicyCreateAppleAST2Service(name, context);
765 } else {
766 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier);
767 }
768 }
769 else if (CFEqual(policyIdentifier, kSecPolicyAppleEscrowProxyServerAuth)) {
770 if (name) {
771 policy = SecPolicyCreateAppleEscrowProxyService(name, context);
772 } else {
773 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier);
774 }
775 }
776 else if (CFEqual(policyIdentifier, kSecPolicyAppleFMiPServerAuth)) {
777 if (name) {
778 policy = SecPolicyCreateAppleFMiPService(name, context);
779 } else {
780 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier);
781 }
782 }
783 else if (CFEqual(policyIdentifier, kSecPolicyAppleMMCSService)) {
784 if (name) {
785 policy = SecPolicyCreateAppleMMCSService(name, context);
786 } else {
787 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier);
788 }
789 }
790 else if (CFEqual(policyIdentifier, kSecPolicyAppleGSService)) {
791 if (name) {
792 policy = SecPolicyCreateAppleGSService(name, context);
793 } else {
794 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier);
795 }
796 }
797 else if (CFEqual(policyIdentifier, kSecPolicyApplePPQService)) {
798 if (name) {
799 policy = SecPolicyCreateApplePPQService(name, context);
800 } else {
801 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier);
802 }
803 }
804 else if (CFEqual(policyIdentifier, kSecPolicyAppleHomeKitServerAuth)) {
805 policy = SecPolicyCreateAppleHomeKitServerAuth(name);
806 }
807 else if (CFEqual(policyIdentifier, kSecPolicyAppleiPhoneActivation)) {
808 policy = SecPolicyCreateiPhoneActivation();
809 }
810 else if (CFEqual(policyIdentifier, kSecPolicyAppleiPhoneDeviceCertificate)) {
811 policy = SecPolicyCreateiPhoneDeviceCertificate();
812 }
813 else if (CFEqual(policyIdentifier, kSecPolicyAppleFactoryDeviceCertificate)) {
814 policy = SecPolicyCreateFactoryDeviceCertificate();
815 }
816 else if (CFEqual(policyIdentifier, kSecPolicyAppleiAP)) {
817 policy = SecPolicyCreateiAP();
818 }
819 else if (CFEqual(policyIdentifier, kSecPolicyAppleiTunesStoreURLBag)) {
820 policy = SecPolicyCreateiTunesStoreURLBag();
821 }
822 else if (CFEqual(policyIdentifier, kSecPolicyAppleiPhoneApplicationSigning)) {
823 policy = SecPolicyCreateiPhoneApplicationSigning();
824 }
825 else if (CFEqual(policyIdentifier, kSecPolicyAppleiPhoneProfileApplicationSigning)) {
826 policy = SecPolicyCreateiPhoneProfileApplicationSigning();
827 }
828 else if (CFEqual(policyIdentifier, kSecPolicyAppleiPhoneProvisioningProfileSigning)) {
829 policy = SecPolicyCreateiPhoneProvisioningProfileSigning();
830 }
831 else if (CFEqual(policyIdentifier, kSecPolicyAppleLockdownPairing)) {
832 policy = SecPolicyCreateLockdownPairing();
833 }
834 else if (CFEqual(policyIdentifier, kSecPolicyAppleURLBag)) {
835 policy = SecPolicyCreateURLBag();
836 }
837 else if (CFEqual(policyIdentifier, kSecPolicyAppleOTATasking)) {
838 policy = SecPolicyCreateOTATasking();
839 }
840 else if (CFEqual(policyIdentifier, kSecPolicyAppleMobileAsset)) {
841 policy = SecPolicyCreateMobileAsset();
842 }
843 else if (CFEqual(policyIdentifier, kSecPolicyAppleIDAuthority)) {
844 policy = SecPolicyCreateAppleIDAuthorityPolicy();
845 }
846 else if (CFEqual(policyIdentifier, kSecPolicyAppleGenericApplePinned)) {
847 if (policyName) {
848 policy = SecPolicyCreateApplePinned(policyName, intermediateMarkerOid, leafMarkerOid);
849 } else {
850 secerror("policy \"%@\" requires kSecPolicyPolicyName input", policyIdentifier);
851 }
852 }
853 else if (CFEqual(policyIdentifier, kSecPolicyAppleGenericAppleSSLPinned)) {
854 if (policyName) {
855 policy = SecPolicyCreateAppleSSLPinned(policyName, name, intermediateMarkerOid, leafMarkerOid);
856 } else {
857 secerror("policy \"%@\" requires kSecPolicyPolicyName input", policyIdentifier);
858 }
859 }
860 else if (CFEqual(policyIdentifier, kSecPolicyAppleSoftwareSigning)) {
861 policy = SecPolicyCreateAppleSoftwareSigning();
862 }
863 else if (CFEqual(policyIdentifier, kSecPolicyAppleExternalDeveloper)) {
864 policy = SecPolicyCreateAppleExternalDeveloper();
865 }
866 else if (CFEqual(policyIdentifier, kSecPolicyAppleOCSPSigner)) {
867 policy = SecPolicyCreateOCSPSigner();
868 }
869 else if (CFEqual(policyIdentifier, kSecPolicyAppleIDSService)) {
870 policy = SecPolicyCreateAppleIDSService(name);
871 }
872 else if (CFEqual(policyIdentifier, kSecPolicyAppleIDSServiceContext)) {
873 if (name) {
874 policy = SecPolicyCreateAppleIDSServiceContext(name, context);
875 } else {
876 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier);
877 }
878 }
879 else if (CFEqual(policyIdentifier, kSecPolicyApplePushService)) {
880 if (name) {
881 policy = SecPolicyCreateApplePushService(name, context);
882 } else {
883 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier);
884 }
885 }
886 else if (CFEqual(policyIdentifier, kSecPolicyAppleLegacyPushService)) {
887 if (name) {
888 policy = SecPolicyCreateApplePushServiceLegacy(name);
889 } else {
890 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier);
891 }
892 }
893 else if (CFEqual(policyIdentifier, kSecPolicyAppleTVOSApplicationSigning)) {
894 policy = SecPolicyCreateAppleTVOSApplicationSigning();
895 }
896 else if (CFEqual(policyIdentifier, kSecPolicyAppleUniqueDeviceIdentifierCertificate)) {
897 policy = SecPolicyCreateAppleUniqueDeviceCertificate(rootDigest);
898 }
899 else if (CFEqual(policyIdentifier, kSecPolicyAppleEscrowProxyCompatibilityServerAuth)) {
900 if (name) {
901 policy = SecPolicyCreateAppleCompatibilityEscrowProxyService(name);
902 } else {
903 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier);
904 }
905 }
906 else if (CFEqual(policyIdentifier, kSecPolicyAppleMMCSCompatibilityServerAuth)) {
907 if (name) {
908 policy = SecPolicyCreateAppleCompatibilityMMCSService(name);
909 } else {
910 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier);
911 }
912 }
913 else if (CFEqual(policyIdentifier, kSecPolicyAppleSecureIOStaticAsset)) {
914 policy = SecPolicyCreateAppleSecureIOStaticAsset();
915 }
916 else if (CFEqual(policyIdentifier, kSecPolicyAppleWarsaw)) {
917 policy = SecPolicyCreateAppleWarsaw();
918 }
919 else if (CFEqual(policyIdentifier, kSecPolicyAppleiCloudSetupServerAuth)) {
920 if (name) {
921 policy = SecPolicyCreateAppleiCloudSetupService(name, context);
922 } else {
923 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier);
924 }
925 }
926 else if (CFEqual(policyIdentifier, kSecPolicyAppleiCloudSetupCompatibilityServerAuth)) {
927 if (name) {
928 policy = SecPolicyCreateAppleCompatibilityiCloudSetupService(name);
929 } else {
930 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier);
931 }
932 }
933 else {
934 secerror("ERROR: policy \"%@\" is unsupported", policyIdentifier);
935 }
936
937 #ifdef TARGET_OS_OSX
938 set_ku_from_properties(policy, properties);
939 #endif
940 errOut:
941 return policy;
942 }
943
944 CFDictionaryRef SecPolicyCopyProperties(SecPolicyRef policyRef) {
945 // Builds and returns a dictionary which the caller must release.
946
947 #pragma clang diagnostic push
948 #pragma clang diagnostic ignored "-Wnonnull"
949 // After introducing nullability annotations, policyRef is supposed to be nonnull, suppress the warning
950 if (!policyRef) return NULL;
951 #pragma clang diagnostic pop
952 CFMutableDictionaryRef properties = CFDictionaryCreateMutable(NULL, 0,
953 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
954 #pragma clang diagnostic push
955 #pragma clang diagnostic ignored "-Wnonnull"
956 // 'properties' is nonnull in reality suppress the warning
957 if (!properties) return NULL;
958 #pragma clang diagnostic pop
959 CFStringRef oid = (CFStringRef) CFRetain(policyRef->_oid);
960 CFTypeRef nameKey = NULL;
961
962 // Determine name key
963 if (policyRef->_options) {
964 if (CFDictionaryContainsKey(policyRef->_options, kSecPolicyCheckSSLHostname)) {
965 nameKey = kSecPolicyCheckSSLHostname;
966 } else if (CFDictionaryContainsKey(policyRef->_options, kSecPolicyCheckEAPTrustedServerNames)) {
967 nameKey = kSecPolicyCheckEAPTrustedServerNames;
968 } else if (CFDictionaryContainsKey(policyRef->_options, kSecPolicyCheckEmail)) {
969 nameKey = kSecPolicyCheckEmail;
970 }
971 }
972
973 // Set kSecPolicyOid
974 CFDictionarySetValue(properties, (const void *)kSecPolicyOid,
975 (const void *)oid);
976
977 // Set kSecPolicyName if we have one
978 if (nameKey && policyRef->_options) {
979 CFTypeRef name = (CFTypeRef) CFDictionaryGetValue(policyRef->_options,
980 nameKey);
981 if (name) {
982 CFDictionarySetValue(properties, (const void *)kSecPolicyName,
983 (const void *)name);
984 }
985 }
986
987 // Set kSecPolicyClient
988 CFStringRef policyName = (CFStringRef) CFRetainSafe(policyRef->_name);
989 if (policyName && (CFEqual(policyName, kSecPolicyNameSSLClient) ||
990 CFEqual(policyName, kSecPolicyNameIPSecClient) ||
991 CFEqual(policyName, kSecPolicyNameEAPClient))) {
992 CFDictionarySetValue(properties, (const void *)kSecPolicyClient,
993 (const void *)kCFBooleanTrue);
994 }
995
996 CFRelease(oid);
997 return properties;
998 }
999
1000 static void SecPolicySetOid(SecPolicyRef policy, CFStringRef oid) {
1001 if (!policy || !oid) return;
1002 CFStringRef temp = policy->_oid;
1003 CFRetain(oid);
1004 policy->_oid = oid;
1005 CFReleaseSafe(temp);
1006 }
1007
1008 static void SecPolicySetName(SecPolicyRef policy, CFStringRef policyName) {
1009 if (!policy || !policyName) return;
1010 CFStringRef temp = policy->_name;
1011 CFRetain(policyName);
1012 policy->_name= policyName;
1013 CFReleaseSafe(temp);
1014 }
1015
1016 CFStringRef SecPolicyGetOidString(SecPolicyRef policy) {
1017 return policy->_oid;
1018 }
1019
1020 CFStringRef SecPolicyGetName(SecPolicyRef policy) {
1021 return policy->_name;
1022 }
1023
1024 CFDictionaryRef SecPolicyGetOptions(SecPolicyRef policy) {
1025 return policy->_options;
1026 }
1027
1028 void SecPolicySetOptionsValue(SecPolicyRef policy, CFStringRef key, CFTypeRef value) {
1029 if (!policy || !key) return;
1030 CFMutableDictionaryRef options = (CFMutableDictionaryRef) policy->_options;
1031 if (!options) {
1032 options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
1033 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
1034 if (!options) return;
1035 policy->_options = options;
1036 }
1037 CFDictionarySetValue(options, key, value);
1038 }
1039
1040 /* Local forward declaration */
1041 static void set_ssl_ekus(CFMutableDictionaryRef options, bool server);
1042
1043 #if TARGET_OS_IPHONE
1044 // this is declared as NA for iPhone in SecPolicy.h, so declare here
1045 OSStatus SecPolicySetProperties(SecPolicyRef policyRef, CFDictionaryRef properties);
1046 #endif
1047
1048 OSStatus SecPolicySetProperties(SecPolicyRef policyRef, CFDictionaryRef properties) {
1049 // Set policy options based on the provided dictionary keys.
1050
1051 if (!(policyRef && properties && (CFDictionaryGetTypeID() == CFGetTypeID(properties)))) {
1052 return errSecParam;
1053 }
1054 CFStringRef oid = (CFStringRef) CFRetain(policyRef->_oid);
1055 OSStatus result = errSecSuccess;
1056
1057 // kSecPolicyName
1058 CFTypeRef name = NULL;
1059 if (CFDictionaryGetValueIfPresent(properties, (const void *)kSecPolicyName,
1060 (const void **)&name) && name) {
1061 CFTypeID typeID = CFGetTypeID(name);
1062 if (CFEqual(oid, kSecPolicyAppleSSL) ||
1063 CFEqual(oid, kSecPolicyAppleIPsec)) {
1064 if (CFStringGetTypeID() == typeID) {
1065 SecPolicySetOptionsValue(policyRef, kSecPolicyCheckSSLHostname, name);
1066 }
1067 else result = errSecParam;
1068 }
1069 else if (CFEqual(oid, kSecPolicyAppleEAP)) {
1070 if ((CFStringGetTypeID() == typeID) ||
1071 (CFArrayGetTypeID() == typeID)) {
1072 SecPolicySetOptionsValue(policyRef, kSecPolicyCheckEAPTrustedServerNames, name);
1073 }
1074 else result = errSecParam;
1075 }
1076 else if (CFEqual(oid, kSecPolicyAppleSMIME)) {
1077 if (CFStringGetTypeID() == typeID) {
1078 SecPolicySetOptionsValue(policyRef, kSecPolicyCheckEmail, name);
1079 }
1080 else result = errSecParam;
1081 }
1082 }
1083
1084 // kSecPolicyClient
1085 CFTypeRef client = NULL;
1086 if (CFDictionaryGetValueIfPresent(properties, (const void *)kSecPolicyClient,
1087 (const void **)&client) && client) {
1088 if (!(CFBooleanGetTypeID() == CFGetTypeID(client))) {
1089 result = errSecParam;
1090 }
1091 else if (CFEqual(client, kCFBooleanTrue)) {
1092 if (CFEqual(oid, kSecPolicyAppleSSL)) {
1093 SecPolicySetName(policyRef, kSecPolicyNameSSLClient);
1094 /* Set EKU checks for clients */
1095 CFMutableDictionaryRef newOptions = CFDictionaryCreateMutableCopy(NULL, 0, policyRef->_options);
1096 set_ssl_ekus(newOptions, false);
1097 CFReleaseSafe(policyRef->_options);
1098 policyRef->_options = newOptions;
1099 }
1100 else if (CFEqual(oid, kSecPolicyAppleIPsec)) {
1101 SecPolicySetName(policyRef, kSecPolicyNameIPSecClient);
1102 }
1103 else if (CFEqual(oid, kSecPolicyNameEAPServer)) {
1104 SecPolicySetName(policyRef, kSecPolicyNameEAPClient);
1105 /* Set EKU checks for clients */
1106 CFMutableDictionaryRef newOptions = CFDictionaryCreateMutableCopy(NULL, 0, policyRef->_options);
1107 set_ssl_ekus(newOptions, false);
1108 CFReleaseSafe(policyRef->_options);
1109 policyRef->_options = newOptions;
1110 }
1111 }
1112 else {
1113 if (CFEqual(oid, kSecPolicyAppleSSL)) {
1114 SecPolicySetName(policyRef, kSecPolicyNameSSLServer);
1115 /* Set EKU checks for servers */
1116 CFMutableDictionaryRef newOptions = CFDictionaryCreateMutableCopy(NULL, 0, policyRef->_options);
1117 set_ssl_ekus(newOptions, true);
1118 CFReleaseSafe(policyRef->_options);
1119 policyRef->_options = newOptions;
1120 }
1121 else if (CFEqual(oid, kSecPolicyAppleIPsec)) {
1122 SecPolicySetName(policyRef, kSecPolicyNameIPSecServer);
1123 }
1124 else if (CFEqual(oid, kSecPolicyAppleEAP)) {
1125 SecPolicySetName(policyRef, kSecPolicyNameEAPServer);
1126 /* Set EKU checks for servers */
1127 CFMutableDictionaryRef newOptions = CFDictionaryCreateMutableCopy(NULL, 0, policyRef->_options);
1128 set_ssl_ekus(newOptions, true);
1129 CFReleaseSafe(policyRef->_options);
1130 policyRef->_options = newOptions;
1131 }
1132 }
1133 }
1134
1135 #ifdef TARGET_OS_OSX
1136 set_ku_from_properties(policyRef, properties);
1137 #endif
1138 CFRelease(oid);
1139 return result;
1140 }
1141
1142 static xpc_object_t copy_xpc_policy_object(SecPolicyRef policy);
1143 static bool append_policy_to_xpc_array(SecPolicyRef policy, xpc_object_t xpc_policies);
1144 extern xpc_object_t copy_xpc_policies_array(CFArrayRef policies);
1145 extern OSStatus validate_array_of_items(CFArrayRef array, CFStringRef arrayItemType, CFTypeID itemTypeID, bool required);
1146
1147 static xpc_object_t copy_xpc_policy_object(SecPolicyRef policy) {
1148 xpc_object_t xpc_policy = NULL;
1149 xpc_object_t data[2] = { NULL, NULL };
1150 if (policy->_oid && (CFGetTypeID(policy->_oid) == CFStringGetTypeID()) &&
1151 policy->_name && (CFGetTypeID(policy->_name) == CFStringGetTypeID())) {
1152 /* These should really be different elements of the xpc array. But
1153 * SecPolicyCreateWithXPCObject previously checked the size via ==, which prevents
1154 * us from appending new information while maintaining backward compatibility.
1155 * Doing this makes the builders happy. */
1156 CFMutableStringRef oidAndName = NULL;
1157 oidAndName = CFStringCreateMutableCopy(NULL, 0, policy->_oid);
1158 if (oidAndName) {
1159 CFStringAppend(oidAndName, CFSTR("++"));
1160 CFStringAppend(oidAndName, policy->_name);
1161 data[0] = _CFXPCCreateXPCObjectFromCFObject(oidAndName);
1162 CFReleaseNull(oidAndName);
1163 } else {
1164 data[0] = _CFXPCCreateXPCObjectFromCFObject(policy->_oid);
1165 }
1166 } else if (policy->_oid && (CFGetTypeID(policy->_oid) == CFStringGetTypeID())) {
1167 data[0] = _CFXPCCreateXPCObjectFromCFObject(policy->_oid);
1168 } else {
1169 secerror("policy 0x%lX has no _oid", (uintptr_t)policy);
1170 }
1171 if (policy->_options && (CFGetTypeID(policy->_options) == CFDictionaryGetTypeID())) {
1172 data[1] = _CFXPCCreateXPCObjectFromCFObject(policy->_options);
1173 } else {
1174 secerror("policy 0x%lX has no _options", (uintptr_t)policy);
1175 }
1176 xpc_policy = xpc_array_create(data, array_size(data));
1177 if (data[0]) xpc_release(data[0]);
1178 if (data[1]) xpc_release(data[1]);
1179 return xpc_policy;
1180 }
1181
1182 static bool append_policy_to_xpc_array(SecPolicyRef policy, xpc_object_t xpc_policies) {
1183 if (!policy) {
1184 return true; // NOOP
1185 }
1186 xpc_object_t xpc_policy = copy_xpc_policy_object(policy);
1187 if (!xpc_policy) {
1188 return false;
1189 }
1190 xpc_array_append_value(xpc_policies, xpc_policy);
1191 xpc_release(xpc_policy);
1192 return true;
1193 }
1194
1195 xpc_object_t copy_xpc_policies_array(CFArrayRef policies) {
1196 xpc_object_t xpc_policies = xpc_array_create(NULL, 0);
1197 if (!xpc_policies) {
1198 return NULL;
1199 }
1200 validate_array_of_items(policies, CFSTR("policy"), SecPolicyGetTypeID(), true);
1201 CFIndex ix, count = CFArrayGetCount(policies);
1202 for (ix = 0; ix < count; ++ix) {
1203 SecPolicyRef policy = (SecPolicyRef) CFArrayGetValueAtIndex(policies, ix);
1204 #if SECTRUST_VERBOSE_DEBUG
1205 CFDictionaryRef props = SecPolicyCopyProperties(policy);
1206 secerror("idx=%d of %d; policy=0x%lX properties=%@", (int)ix, (int)count, (uintptr_t)policy, props);
1207 CFReleaseSafe(props);
1208 #endif
1209 if (!append_policy_to_xpc_array(policy, xpc_policies)) {
1210 xpc_release(xpc_policies);
1211 xpc_policies = NULL;
1212 break;
1213 }
1214 }
1215 return xpc_policies;
1216 }
1217
1218 static xpc_object_t SecPolicyCopyXPCObject(SecPolicyRef policy, CFErrorRef *error) {
1219 xpc_object_t xpc_policy = NULL;
1220 xpc_object_t data[2] = {};
1221 CFMutableStringRef oidAndName = NULL;
1222 oidAndName = CFStringCreateMutableCopy(NULL, 0, policy->_oid);
1223 if (oidAndName) {
1224 if (policy->_name) {
1225 CFStringAppend(oidAndName, CFSTR("++"));
1226 CFStringAppend(oidAndName, policy->_name);
1227 }
1228
1229 require_action_quiet(data[0] = _CFXPCCreateXPCObjectFromCFObject(oidAndName), exit,
1230 SecError(errSecParam, error,
1231 CFSTR("failed to create xpc_object from policy oid and name")));
1232 } else {
1233 require_action_quiet(data[0] = _CFXPCCreateXPCObjectFromCFObject(policy->_oid), exit,
1234 SecError(errSecParam, error, CFSTR("failed to create xpc_object from policy oid")));
1235 }
1236 require_action_quiet(data[1] = _CFXPCCreateXPCObjectFromCFObject(policy->_options), exit,
1237 SecError(errSecParam, error, CFSTR("failed to create xpc_object from policy options")));
1238 require_action_quiet(xpc_policy = xpc_array_create(data, array_size(data)), exit,
1239 SecError(errSecAllocate, error, CFSTR("failed to create xpc_array for policy")));
1240
1241 exit:
1242 if (data[0]) xpc_release(data[0]);
1243 if (data[1]) xpc_release(data[1]);
1244 CFReleaseNull(oidAndName);
1245 return xpc_policy;
1246 }
1247
1248 static bool SecPolicyAppendToXPCArray(SecPolicyRef policy, xpc_object_t policies, CFErrorRef *error) {
1249 if (!policy)
1250 return true; // NOOP
1251
1252 xpc_object_t xpc_policy = SecPolicyCopyXPCObject(policy, error);
1253 if (!xpc_policy)
1254 return false;
1255
1256 xpc_array_append_value(policies, xpc_policy);
1257 xpc_release(xpc_policy);
1258 return true;
1259 }
1260
1261 xpc_object_t SecPolicyArrayCopyXPCArray(CFArrayRef policies, CFErrorRef *error) {
1262 xpc_object_t xpc_policies;
1263 require_action_quiet(xpc_policies = xpc_array_create(NULL, 0), exit,
1264 SecError(errSecAllocate, error, CFSTR("failed to create xpc_array")));
1265 CFIndex ix, count = CFArrayGetCount(policies);
1266 for (ix = 0; ix < count; ++ix) {
1267 if (!SecPolicyAppendToXPCArray((SecPolicyRef)CFArrayGetValueAtIndex(policies, ix), xpc_policies, error)) {
1268 xpc_release(xpc_policies);
1269 return NULL;
1270 }
1271 }
1272 exit:
1273 return xpc_policies;
1274 }
1275
1276 static OSStatus parseOidAndName(CFStringRef oidAndName, CFStringRef *oid, CFStringRef *name) {
1277 OSStatus result = errSecSuccess;
1278 CFStringRef partial = NULL;
1279
1280 CFRange delimiter = CFStringFind(oidAndName, CFSTR("++"), 0);
1281 if (delimiter.length != 2) {
1282 return errSecParam;
1283 }
1284
1285 /* get first half: oid */
1286 partial = CFStringCreateWithSubstring(NULL, oidAndName, CFRangeMake(0, delimiter.location));
1287 if (oid) { *oid = CFRetainSafe(partial); }
1288 CFReleaseNull(partial);
1289
1290 /* get second half: name */
1291 if (delimiter.location + 2 >= CFStringGetLength(oidAndName)) {
1292 return errSecSuccess; // name is optional
1293 }
1294 CFRange nameRange = CFRangeMake(delimiter.location+2,
1295 CFStringGetLength(oidAndName) - delimiter.location - 2);
1296 partial = CFStringCreateWithSubstring(NULL, oidAndName, nameRange);
1297 if (name) { *name = CFRetainSafe(partial); }
1298 CFReleaseNull(partial);
1299 return result;
1300 }
1301
1302 static SecPolicyRef SecPolicyCreateWithXPCObject(xpc_object_t xpc_policy, CFErrorRef *error) {
1303 SecPolicyRef policy = NULL;
1304 CFTypeRef oidAndName = NULL;
1305 CFStringRef oid = NULL;
1306 CFStringRef name = NULL;
1307 CFTypeRef options = NULL;
1308
1309 require_action_quiet(xpc_policy, exit, SecError(errSecParam, error, CFSTR("policy xpc value is NULL")));
1310 require_action_quiet(xpc_get_type(xpc_policy) == XPC_TYPE_ARRAY, exit, SecError(errSecDecode, error, CFSTR("policy xpc value is not an array")));
1311 require_action_quiet(xpc_array_get_count(xpc_policy) >= 2, exit, SecError(errSecDecode, error, CFSTR("policy xpc array count < 2")));
1312 oidAndName = _CFXPCCreateCFObjectFromXPCObject(xpc_array_get_value(xpc_policy, 0));
1313 require_action_quiet(isString(oidAndName), exit,
1314 SecError(errSecParam, error, CFSTR("failed to convert xpc policy[0]=%@ to CFString"), oidAndName));
1315 options = _CFXPCCreateCFObjectFromXPCObject(xpc_array_get_value(xpc_policy, 1));
1316 require_action_quiet(isDictionary(options), exit,
1317 SecError(errSecParam, error, CFSTR("failed to convert xpc policy[1]=%@ to CFDictionary"), options));
1318 require_noerr_action_quiet(parseOidAndName(oidAndName, &oid, &name), exit,
1319 SecError(errSecParam, error, CFSTR("failed to convert combined %@ to name and oid"), oidAndName));
1320 require_action_quiet(policy = SecPolicyCreate(oid, name, options), exit,
1321 SecError(errSecDecode, error, CFSTR("Failed to create policy")));
1322
1323 exit:
1324 CFReleaseSafe(oidAndName);
1325 CFReleaseSafe(oid);
1326 CFReleaseSafe(name);
1327 CFReleaseSafe(options);
1328 return policy;
1329 }
1330
1331 CFArrayRef SecPolicyXPCArrayCopyArray(xpc_object_t xpc_policies, CFErrorRef *error) {
1332 CFMutableArrayRef policies = NULL;
1333 require_action_quiet(xpc_get_type(xpc_policies) == XPC_TYPE_ARRAY, exit,
1334 SecError(errSecParam, error, CFSTR("policies xpc value is not an array")));
1335 size_t count = xpc_array_get_count(xpc_policies);
1336 require_action_quiet(policies = CFArrayCreateMutable(kCFAllocatorDefault, count, &kCFTypeArrayCallBacks), exit,
1337 SecError(errSecAllocate, error, CFSTR("failed to create CFArray of capacity %zu"), count));
1338
1339 size_t ix;
1340 for (ix = 0; ix < count; ++ix) {
1341 SecPolicyRef policy = SecPolicyCreateWithXPCObject(xpc_array_get_value(xpc_policies, ix), error);
1342 if (!policy) {
1343 CFRelease(policies);
1344 return NULL;
1345 }
1346 CFArraySetValueAtIndex(policies, ix, policy);
1347 CFRelease(policy);
1348 }
1349
1350 exit:
1351 return policies;
1352
1353 }
1354
1355 static SEC_CONST_DECL (kSecPolicyOptions, "policyOptions");
1356
1357 static SecPolicyRef SecPolicyCreateWithDictionary(CFDictionaryRef dict) {
1358 SecPolicyRef policy = NULL;
1359 CFStringRef oid = (CFStringRef)CFDictionaryGetValue(dict, kSecPolicyOid);
1360 require_quiet(isString(oid), errOut);
1361 CFDictionaryRef options = (CFDictionaryRef)CFDictionaryGetValue(dict, kSecPolicyOptions);
1362 require_quiet(isDictionary(options), errOut);
1363 CFStringRef name = (CFStringRef)CFDictionaryGetValue(dict, kSecPolicyPolicyName);
1364 policy = SecPolicyCreate(oid, name, options);
1365 errOut:
1366 return policy;
1367 }
1368
1369 static void deserializePolicy(const void *value, void *context) {
1370 CFDictionaryRef policyDict = (CFDictionaryRef)value;
1371 if (isDictionary(policyDict)) {
1372 CFTypeRef deserializedPolicy = SecPolicyCreateWithDictionary(policyDict);
1373 if (deserializedPolicy) {
1374 CFArrayAppendValue((CFMutableArrayRef)context, deserializedPolicy);
1375 CFRelease(deserializedPolicy);
1376 }
1377 }
1378 }
1379
1380 CFArrayRef SecPolicyArrayCreateDeserialized(CFArrayRef serializedPolicies) {
1381 CFMutableArrayRef result = NULL;
1382 require_quiet(isArray(serializedPolicies), errOut);
1383 CFIndex count = CFArrayGetCount(serializedPolicies);
1384 result = CFArrayCreateMutable(kCFAllocatorDefault, count, &kCFTypeArrayCallBacks);
1385 CFRange all_policies = { 0, count };
1386 CFArrayApplyFunction(serializedPolicies, all_policies, deserializePolicy, result);
1387 errOut:
1388 return result;
1389 }
1390
1391 static CFDictionaryRef SecPolicyCreateDictionary(SecPolicyRef policy) {
1392 CFMutableDictionaryRef dict = NULL;
1393 dict = CFDictionaryCreateMutable(NULL, 3, &kCFTypeDictionaryKeyCallBacks,
1394 &kCFTypeDictionaryValueCallBacks);
1395 CFDictionaryAddValue(dict, kSecPolicyOid, policy->_oid);
1396 CFDictionaryAddValue(dict, kSecPolicyOptions, policy->_options);
1397 if (policy->_name) {
1398 CFDictionaryAddValue(dict, kSecPolicyPolicyName, policy->_name);
1399 }
1400 return dict;
1401 }
1402
1403 static void serializePolicy(const void *value, void *context) {
1404 SecPolicyRef policy = (SecPolicyRef)value;
1405 if (policy && SecPolicyGetTypeID() == CFGetTypeID(policy)) {
1406 CFDictionaryRef serializedPolicy = SecPolicyCreateDictionary(policy);
1407 if (serializedPolicy) {
1408 CFArrayAppendValue((CFMutableArrayRef)context, serializedPolicy);
1409 CFRelease(serializedPolicy);
1410 }
1411 }
1412 }
1413
1414 CFArrayRef SecPolicyArrayCreateSerialized(CFArrayRef policies) {
1415 CFMutableArrayRef result = NULL;
1416 require_quiet(isArray(policies), errOut);
1417 CFIndex count = CFArrayGetCount(policies);
1418 result = CFArrayCreateMutable(NULL, count, &kCFTypeArrayCallBacks);
1419 CFRange all_policies = { 0, count};
1420 CFArrayApplyFunction(policies, all_policies, serializePolicy, result);
1421 errOut:
1422 return result;
1423 }
1424
1425 static void add_element(CFMutableDictionaryRef options, CFStringRef key,
1426 CFTypeRef value) {
1427 CFTypeRef old_value = CFDictionaryGetValue(options, key);
1428 if (old_value) {
1429 CFMutableArrayRef array;
1430 if (CFGetTypeID(old_value) == CFArrayGetTypeID()) {
1431 array = (CFMutableArrayRef)old_value;
1432 } else {
1433 array = CFArrayCreateMutable(kCFAllocatorDefault, 0,
1434 &kCFTypeArrayCallBacks);
1435 CFArrayAppendValue(array, old_value);
1436 CFDictionarySetValue(options, key, array);
1437 CFRelease(array);
1438 }
1439 CFArrayAppendValue(array, value);
1440 } else {
1441 CFDictionaryAddValue(options, key, value);
1442 }
1443 }
1444
1445 static void add_eku(CFMutableDictionaryRef options, const DERItem *ekuOid) {
1446 CFDataRef eku = CFDataCreate(kCFAllocatorDefault,
1447 ekuOid ? ekuOid->data : NULL,
1448 ekuOid ? ekuOid->length : 0);
1449 if (eku) {
1450 add_element(options, kSecPolicyCheckExtendedKeyUsage, eku);
1451 CFRelease(eku);
1452 }
1453 }
1454
1455 static void add_eku_string(CFMutableDictionaryRef options, CFStringRef ekuOid) {
1456 if (ekuOid) {
1457 add_element(options, kSecPolicyCheckExtendedKeyUsage, ekuOid);
1458 }
1459 }
1460
1461 static void set_ssl_ekus(CFMutableDictionaryRef options, bool server) {
1462 CFDictionaryRemoveValue(options, kSecPolicyCheckExtendedKeyUsage);
1463
1464 /* If server and EKU ext present then EKU ext should contain one of
1465 ServerAuth or ExtendedKeyUsageAny or NetscapeSGC or MicrosoftSGC.
1466 else if !server and EKU ext present then EKU ext should contain one of
1467 ClientAuth or ExtendedKeyUsageAny. */
1468
1469 /* We always allow certificates that specify oidAnyExtendedKeyUsage. */
1470 add_eku(options, NULL); /* eku extension is optional */
1471 add_eku(options, &oidAnyExtendedKeyUsage);
1472 if (server) {
1473 add_eku(options, &oidExtendedKeyUsageServerAuth);
1474 add_eku(options, &oidExtendedKeyUsageMicrosoftSGC);
1475 add_eku(options, &oidExtendedKeyUsageNetscapeSGC);
1476 } else {
1477 add_eku(options, &oidExtendedKeyUsageClientAuth);
1478 }
1479 }
1480
1481 static void add_ku(CFMutableDictionaryRef options, SecKeyUsage keyUsage) {
1482 SInt32 dku = keyUsage;
1483 CFNumberRef ku = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type,
1484 &dku);
1485 if (ku) {
1486 add_element(options, kSecPolicyCheckKeyUsage, ku);
1487 CFRelease(ku);
1488 }
1489 }
1490
1491 #ifdef TARGET_OS_OSX
1492 static void set_ku_from_properties(SecPolicyRef policy, CFDictionaryRef properties) {
1493 if (!policy || !properties) {
1494 return;
1495 }
1496
1497 CFStringRef keyNames[] = { kSecPolicyKU_DigitalSignature, kSecPolicyKU_NonRepudiation, kSecPolicyKU_KeyEncipherment, kSecPolicyKU_DataEncipherment,
1498 kSecPolicyKU_KeyAgreement, kSecPolicyKU_KeyCertSign, kSecPolicyKU_CRLSign, kSecPolicyKU_EncipherOnly, kSecPolicyKU_DecipherOnly };
1499
1500 uint32_t keyUsageValues[] = { kSecKeyUsageDigitalSignature, kSecKeyUsageNonRepudiation, kSecKeyUsageKeyEncipherment, kSecKeyUsageDataEncipherment,
1501 kSecKeyUsageKeyAgreement, kSecKeyUsageKeyCertSign, kSecKeyUsageCRLSign, kSecKeyUsageEncipherOnly, kSecKeyUsageDecipherOnly };
1502
1503 bool haveKeyUsage = false;
1504 CFTypeRef keyUsageBoolean;
1505 for (uint32_t i = 0; i < sizeof(keyNames) / sizeof(CFStringRef); ++i) {
1506 if (CFDictionaryGetValueIfPresent(properties, keyNames[i], (const void**)&keyUsageBoolean)) {
1507 if (CFEqual(keyUsageBoolean, kCFBooleanTrue)) {
1508 haveKeyUsage = true;
1509 break;
1510 }
1511 }
1512 }
1513
1514 if (!haveKeyUsage) {
1515 return;
1516 }
1517
1518 CFMutableDictionaryRef options = (CFMutableDictionaryRef) policy->_options;
1519 if (!options) {
1520 options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
1521 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
1522 if (!options) return;
1523 policy->_options = options;
1524 } else {
1525 CFDictionaryRemoveValue(options, kSecPolicyCheckKeyUsage);
1526 }
1527
1528 for (uint32_t i = 0; i < sizeof(keyNames) / sizeof(CFStringRef); ++i) {
1529 if (CFDictionaryGetValueIfPresent(properties, keyNames[i], (const void**)&keyUsageBoolean)) {
1530 if (CFEqual(keyUsageBoolean, kCFBooleanTrue)) {
1531 add_ku(options, keyUsageValues[i]);
1532 }
1533 }
1534 }
1535 }
1536 #endif
1537
1538 static void add_oid(CFMutableDictionaryRef options, CFStringRef policy_key, const DERItem *oid) {
1539 CFDataRef oid_data = CFDataCreate(kCFAllocatorDefault,
1540 oid ? oid->data : NULL,
1541 oid ? oid->length : 0);
1542 if (oid_data) {
1543 add_element(options, policy_key, oid_data);
1544 CFRelease(oid_data);
1545 }
1546 }
1547
1548 static void add_leaf_marker_value(CFMutableDictionaryRef options, const DERItem *markerOid, CFStringRef string_value) {
1549
1550 CFTypeRef policyData = NULL;
1551
1552 if (NULL == string_value) {
1553 policyData = CFDataCreate(kCFAllocatorDefault,
1554 markerOid ? markerOid->data : NULL,
1555 markerOid ? markerOid->length : 0);
1556 } else {
1557 CFStringRef oid_as_string = SecDERItemCopyOIDDecimalRepresentation(kCFAllocatorDefault, markerOid);
1558
1559 const void *key[1] = { oid_as_string };
1560 const void *value[1] = { string_value };
1561 policyData = CFDictionaryCreate(kCFAllocatorDefault,
1562 key, value, 1,
1563 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
1564 CFReleaseNull(oid_as_string);
1565 }
1566
1567 add_element(options, kSecPolicyCheckLeafMarkerOid, policyData);
1568
1569 CFReleaseNull(policyData);
1570
1571 }
1572
1573 static void add_leaf_marker(CFMutableDictionaryRef options, const DERItem *markerOid) {
1574 add_leaf_marker_value(options, markerOid, NULL);
1575 }
1576
1577 static void add_leaf_marker_value_string(CFMutableDictionaryRef options, CFStringRef markerOid, CFStringRef string_value) {
1578 if (NULL == string_value) {
1579 add_element(options, kSecPolicyCheckLeafMarkerOid, markerOid);
1580 } else {
1581 CFDictionaryRef policyData = NULL;
1582 const void *key[1] = { markerOid };
1583 const void *value[1] = { string_value };
1584 policyData = CFDictionaryCreate(kCFAllocatorDefault,
1585 key, value, 1,
1586 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
1587 add_element(options, kSecPolicyCheckLeafMarkerOid, policyData);
1588
1589 CFReleaseNull(policyData);
1590 }
1591 }
1592
1593 static void add_leaf_marker_string(CFMutableDictionaryRef options, CFStringRef markerOid) {
1594 add_leaf_marker_value_string(options, markerOid, NULL);
1595 }
1596
1597 static void add_leaf_prod_qa_element(CFMutableDictionaryRef options, CFTypeRef prodValue, CFTypeRef qaValue)
1598 {
1599 CFMutableDictionaryRef prodAndQADictionary = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks,
1600 &kCFTypeDictionaryValueCallBacks);
1601 CFDictionaryRef old_value = CFDictionaryGetValue(options, kSecPolicyCheckLeafMarkersProdAndQA);
1602 if (old_value) {
1603 CFMutableArrayRef prodArray = NULL, qaArray = NULL;
1604 CFTypeRef old_prod_value = CFDictionaryGetValue(old_value, kSecPolicyLeafMarkerProd);
1605 CFTypeRef old_qa_value = CFDictionaryGetValue(old_value, kSecPolicyLeafMarkerQA);
1606 if (isArray(old_prod_value) && isArray(old_qa_value)) {
1607 prodArray = (CFMutableArrayRef)CFRetainSafe(old_prod_value);
1608 qaArray = (CFMutableArrayRef)CFRetainSafe(old_qa_value);
1609 } else {
1610 prodArray = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
1611 qaArray = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
1612 CFArrayAppendValue(prodArray, old_prod_value);
1613 CFArrayAppendValue(qaArray, old_qa_value);
1614 }
1615 CFArrayAppendValue(prodArray, prodValue);
1616 CFArrayAppendValue(qaArray, qaValue);
1617 CFDictionaryAddValue(prodAndQADictionary, kSecPolicyLeafMarkerProd, prodArray);
1618 CFDictionaryAddValue(prodAndQADictionary, kSecPolicyLeafMarkerQA, qaArray);
1619 CFReleaseNull(prodArray);
1620 CFReleaseNull(qaArray);
1621
1622 } else {
1623 CFDictionaryAddValue(prodAndQADictionary, kSecPolicyLeafMarkerProd, prodValue);
1624 CFDictionaryAddValue(prodAndQADictionary, kSecPolicyLeafMarkerQA, qaValue);
1625 }
1626 CFDictionarySetValue(options, kSecPolicyCheckLeafMarkersProdAndQA, prodAndQADictionary);
1627 CFReleaseNull(prodAndQADictionary);
1628
1629 }
1630
1631 static void add_leaf_prod_qa_markers(CFMutableDictionaryRef options, const DERItem *prodMarkerOid, const DERItem *qaMarkerOid)
1632 {
1633 CFDataRef prodData = NULL, qaData = NULL;
1634 prodData = CFDataCreate(NULL, prodMarkerOid ? prodMarkerOid->data : NULL,
1635 prodMarkerOid ? prodMarkerOid->length : 0);
1636 qaData = CFDataCreate(NULL, qaMarkerOid ? qaMarkerOid->data : NULL,
1637 qaMarkerOid ? qaMarkerOid->length : 0);
1638 add_leaf_prod_qa_element(options, prodData, qaData);
1639 CFReleaseNull(prodData);
1640 CFReleaseNull(qaData);
1641 }
1642
1643 static void add_leaf_prod_qa_markers_string(CFMutableDictionaryRef options, CFStringRef prodMarkerOid, CFStringRef qaMarkerOid)
1644 {
1645 add_leaf_prod_qa_element(options, prodMarkerOid, qaMarkerOid);
1646 }
1647
1648 static void add_leaf_prod_qa_markers_value_string(CFMutableDictionaryRef options,
1649 CFStringRef prodMarkerOid, CFStringRef prod_value,
1650 CFStringRef qaMarkerOid, CFStringRef qa_value)
1651 {
1652 if (!prod_value && !qa_value) {
1653 add_leaf_prod_qa_element(options, prodMarkerOid, qaMarkerOid);
1654 } else {
1655 CFDictionaryRef prodData = NULL, qaData = NULL;
1656 const void *prodKey[1] = { prodMarkerOid }, *qaKey[1] = { qaMarkerOid };
1657 const void *prodValue[1] = { prod_value }, *qaValue[1] = { qa_value };
1658 prodData = CFDictionaryCreate(NULL, prodKey, prodValue, 1, &kCFTypeDictionaryKeyCallBacks,
1659 &kCFTypeDictionaryValueCallBacks);
1660 qaData = CFDictionaryCreate(NULL, qaKey, qaValue, 1, &kCFTypeDictionaryKeyCallBacks,
1661 &kCFTypeDictionaryValueCallBacks);
1662 add_leaf_prod_qa_element(options, prodData, qaData);
1663 CFReleaseNull(prodData);
1664 CFReleaseNull(qaData);
1665 }
1666 }
1667
1668 static void add_intermediate_marker_value_string(CFMutableDictionaryRef options, CFStringRef markerOid, CFStringRef string_value) {
1669 if (NULL == string_value) {
1670 add_element(options, kSecPolicyCheckIntermediateMarkerOid, markerOid);
1671 } else {
1672 CFDictionaryRef policyData = NULL;
1673 const void *key[1] = { markerOid };
1674 const void *value[1] = { string_value };
1675 policyData = CFDictionaryCreate(kCFAllocatorDefault,
1676 key, value, 1,
1677 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
1678 add_element(options, kSecPolicyCheckIntermediateMarkerOid, policyData);
1679
1680 CFReleaseNull(policyData);
1681 }
1682 }
1683
1684 static void add_certificate_policy_oid(CFMutableDictionaryRef options, const DERItem *certificatePolicyOid) {
1685 CFTypeRef certificatePolicyData = NULL;
1686 certificatePolicyData = CFDataCreate(kCFAllocatorDefault,
1687 certificatePolicyOid ? certificatePolicyOid->data : NULL,
1688 certificatePolicyOid ? certificatePolicyOid->length : 0);
1689 if (certificatePolicyData) {
1690 add_element(options, kSecPolicyCheckCertificatePolicy, certificatePolicyData);
1691 CFRelease(certificatePolicyData);
1692 }
1693 }
1694
1695 static void add_certificate_policy_oid_string(CFMutableDictionaryRef options, CFStringRef certificatePolicyOid) {
1696 if (certificatePolicyOid) {
1697 add_element(options, kSecPolicyCheckCertificatePolicy, certificatePolicyOid);
1698 }
1699 }
1700
1701 //
1702 // Routines for adding dictionary entries for policies.
1703 //
1704
1705 // X.509, but missing validity requirements.
1706 static void SecPolicyAddBasicCertOptions(CFMutableDictionaryRef options)
1707 {
1708 //CFDictionaryAddValue(options, kSecPolicyCheckBasicCertificateProcessing, kCFBooleanTrue);
1709 // Happens automatically in SecPVCPathChecks
1710 CFDictionaryAddValue(options, kSecPolicyCheckCriticalExtensions, kCFBooleanTrue);
1711 CFDictionaryAddValue(options, kSecPolicyCheckIdLinkage, kCFBooleanTrue);
1712 CFDictionaryAddValue(options, kSecPolicyCheckBasicConstraints, kCFBooleanTrue);
1713 CFDictionaryAddValue(options, kSecPolicyCheckNonEmptySubject, kCFBooleanTrue);
1714 CFDictionaryAddValue(options, kSecPolicyCheckQualifiedCertStatements, kCFBooleanTrue);
1715 CFDictionaryAddValue(options, kSecPolicyCheckWeakIntermediates, kCFBooleanTrue);
1716 CFDictionaryAddValue(options, kSecPolicyCheckWeakLeaf, kCFBooleanTrue);
1717 CFDictionaryAddValue(options, kSecPolicyCheckWeakRoot, kCFBooleanTrue);
1718 }
1719
1720 static void SecPolicyAddBasicX509Options(CFMutableDictionaryRef options)
1721 {
1722 SecPolicyAddBasicCertOptions(options);
1723 CFDictionaryAddValue(options, kSecPolicyCheckValidIntermediates, kCFBooleanTrue);
1724 CFDictionaryAddValue(options, kSecPolicyCheckValidLeaf, kCFBooleanTrue);
1725 CFDictionaryAddValue(options, kSecPolicyCheckValidRoot, kCFBooleanTrue);
1726
1727 // Make sure that black and gray leaf checks are performed for basic X509 chain building
1728 CFDictionaryAddValue(options, kSecPolicyCheckBlackListedLeaf, kCFBooleanTrue);
1729 CFDictionaryAddValue(options, kSecPolicyCheckGrayListedLeaf, kCFBooleanTrue);
1730 }
1731
1732 static bool SecPolicyAddChainLengthOptions(CFMutableDictionaryRef options, CFIndex length)
1733 {
1734 bool result = false;
1735 CFNumberRef lengthAsCF = NULL;
1736
1737 require(lengthAsCF = CFNumberCreate(kCFAllocatorDefault,
1738 kCFNumberCFIndexType, &length), errOut);
1739 CFDictionaryAddValue(options, kSecPolicyCheckChainLength, lengthAsCF);
1740
1741 result = true;
1742
1743 errOut:
1744 CFReleaseSafe(lengthAsCF);
1745 return result;
1746 }
1747
1748 static bool SecPolicyAddAnchorSHA1Options(CFMutableDictionaryRef options,
1749 const UInt8 anchorSha1[kSecPolicySHA1Size])
1750 {
1751 bool success = false;
1752 CFDataRef anchorData = NULL;
1753
1754 require(anchorData = CFDataCreate(kCFAllocatorDefault, anchorSha1, kSecPolicySHA1Size), errOut);
1755 add_element(options, kSecPolicyCheckAnchorSHA1, anchorData);
1756
1757 success = true;
1758
1759 errOut:
1760 CFReleaseSafe(anchorData);
1761 return success;
1762 }
1763
1764 static bool SecPolicyAddAnchorSHA256Options(CFMutableDictionaryRef options,
1765 const UInt8 anchorSha1[kSecPolicySHA256Size])
1766 {
1767 bool success = false;
1768 CFDataRef anchorData = NULL;
1769
1770 require(anchorData = CFDataCreate(kCFAllocatorDefault, anchorSha1, kSecPolicySHA256Size), errOut);
1771 add_element(options, kSecPolicyCheckAnchorSHA256, anchorData);
1772
1773 success = true;
1774
1775 errOut:
1776 CFReleaseSafe(anchorData);
1777 return success;
1778 }
1779
1780 static bool SecPolicyAddStrongKeySizeOptions(CFMutableDictionaryRef options) {
1781 bool success = false;
1782 CFDictionaryRef keySizes = NULL;
1783 CFNumberRef rsaSize = NULL, ecSize = NULL;
1784
1785 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
1786 require(rsaSize = CFNumberCreateWithCFIndex(NULL, 2048), errOut);
1787 require(ecSize = CFNumberCreateWithCFIndex(NULL, 256), errOut);
1788 const void *keys[] = { kSecAttrKeyTypeRSA, kSecAttrKeyTypeEC };
1789 const void *values[] = { rsaSize, ecSize };
1790 require(keySizes = CFDictionaryCreate(NULL, keys, values, 2,
1791 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut);
1792 add_element(options, kSecPolicyCheckKeySize, keySizes);
1793
1794 success = true;
1795
1796 errOut:
1797 CFReleaseSafe(keySizes);
1798 CFReleaseSafe(rsaSize);
1799 CFReleaseSafe(ecSize);
1800 return success;
1801 }
1802
1803 static bool isAppleOid(CFStringRef oid) {
1804 if (!SecCertificateIsOidString(oid)) {
1805 return false;
1806 }
1807 if (CFStringHasPrefix(oid, CFSTR("1.2.840.113635"))) {
1808 return true;
1809 }
1810 return false;
1811 }
1812
1813 static bool isCFPreferenceInSecurityDomain(CFStringRef setting) {
1814 /* For backwards compatibility reasons we have to check both "com.apple.security"
1815 and "com.apple.Security". */
1816 if (CFPreferencesGetAppBooleanValue(setting, CFSTR("com.apple.Security"), NULL)) {
1817 secwarning("DEPRECATION WARNING: Preference set in \"com.apple.Security\" domain. This domain is deprecated. Please use \"com.apple.security\" instead");
1818 }
1819 return (CFPreferencesGetAppBooleanValue(setting, CFSTR("com.apple.security"), NULL) ||
1820 CFPreferencesGetAppBooleanValue(setting, CFSTR("com.apple.Security"), NULL));
1821 }
1822
1823 static bool allowTestHierarchyForPolicy(CFStringRef policyName, bool isSSL) {
1824 bool allow = false;
1825
1826 CFStringRef setting = CFStringCreateWithFormat(NULL, NULL, CFSTR("ApplePinningAllowTestCerts%@"), policyName);
1827 require(setting, fail);
1828 if (isCFPreferenceInSecurityDomain(setting)) {
1829 allow = true;
1830 } else {
1831 secnotice("pinningQA", "could not enable test hierarchy: %@ not true", setting);
1832 }
1833 CFRelease(setting);
1834
1835 if (!allow && isSSL) {
1836 if (isCFPreferenceInSecurityDomain(CFSTR("AppleServerAuthenticationAllowUAT"))) {
1837 allow = true;
1838 } else {
1839 secnotice("pinningQA", "could not enable test hierarchy: AppleServerAuthenticationAllowUAT not true");
1840 }
1841 }
1842
1843 fail:
1844 return allow;
1845 }
1846
1847 static bool SecPolicyAddAppleAnchorOptions(CFMutableDictionaryRef options, CFStringRef policyName)
1848 {
1849 CFMutableDictionaryRef appleAnchorOptions = NULL;
1850 appleAnchorOptions = CFDictionaryCreateMutableForCFTypes(NULL);
1851 if (!appleAnchorOptions) {
1852 return false;
1853 }
1854
1855 if (allowTestHierarchyForPolicy(policyName, false)) {
1856 CFDictionarySetValue(appleAnchorOptions,
1857 kSecPolicyAppleAnchorIncludeTestRoots, kCFBooleanTrue);
1858 }
1859 add_element(options, kSecPolicyCheckAnchorApple, appleAnchorOptions);
1860 CFReleaseSafe(appleAnchorOptions);
1861 return true;
1862 }
1863
1864 //
1865 // MARK: Policy Creation Functions
1866 //
1867 SecPolicyRef SecPolicyCreateBasicX509(void) {
1868 CFMutableDictionaryRef options = NULL;
1869 SecPolicyRef result = NULL;
1870
1871 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
1872 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut);
1873
1874 SecPolicyAddBasicX509Options(options);
1875 CFDictionaryAddValue(options, kSecPolicyCheckNoNetworkAccess,
1876 kCFBooleanTrue);
1877
1878 require(result = SecPolicyCreate(kSecPolicyAppleX509Basic, kSecPolicyNameBasicX509, options), errOut);
1879
1880 errOut:
1881 CFReleaseSafe(options);
1882 return (SecPolicyRef _Nonnull)result;
1883 }
1884
1885 SecPolicyRef SecPolicyCreateSSL(Boolean server, CFStringRef hostname) {
1886 CFMutableDictionaryRef options = NULL;
1887 SecPolicyRef result = NULL;
1888
1889 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
1890 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut);
1891
1892 SecPolicyAddBasicX509Options(options);
1893
1894 if (hostname) {
1895 CFDictionaryAddValue(options, kSecPolicyCheckSSLHostname, hostname);
1896 }
1897
1898 CFDictionaryAddValue(options, kSecPolicyCheckBlackListedLeaf, kCFBooleanTrue);
1899 CFDictionaryAddValue(options, kSecPolicyCheckGrayListedLeaf, kCFBooleanTrue);
1900
1901 if (server) {
1902 CFDictionaryAddValue(options, kSecPolicyCheckSystemTrustedWeakHash, kCFBooleanTrue);
1903 }
1904
1905 set_ssl_ekus(options, server);
1906
1907 require(result = SecPolicyCreate(kSecPolicyAppleSSL,
1908 server ? kSecPolicyNameSSLServer : kSecPolicyNameSSLClient,
1909 options), errOut);
1910
1911 errOut:
1912 CFReleaseSafe(options);
1913 return (SecPolicyRef _Nonnull)result;
1914 }
1915
1916 SecPolicyRef SecPolicyCreateApplePinned(CFStringRef policyName, CFStringRef intermediateMarkerOID, CFStringRef leafMarkerOID) {
1917 CFMutableDictionaryRef options = NULL;
1918 SecPolicyRef result = NULL;
1919
1920 if (!policyName || !intermediateMarkerOID || !leafMarkerOID) {
1921 goto errOut;
1922 }
1923
1924 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
1925 &kCFTypeDictionaryKeyCallBacks,
1926 &kCFTypeDictionaryValueCallBacks), errOut);
1927
1928 SecPolicyAddBasicX509Options(options);
1929
1930 /* Anchored to the Apple Roots */
1931 require(SecPolicyAddAppleAnchorOptions(options, policyName), errOut);
1932
1933 /* Exactly 3 certs in the chain */
1934 require(SecPolicyAddChainLengthOptions(options, 3), errOut);
1935
1936 /* Intermediate marker OID matches input OID */
1937 if (!isAppleOid(intermediateMarkerOID)) {
1938 secwarning("creating an Apple pinning policy with a non-Apple OID: %@", intermediateMarkerOID);
1939 }
1940 add_element(options, kSecPolicyCheckIntermediateMarkerOid, intermediateMarkerOID);
1941
1942 /* Leaf marker OID matches input OID */
1943 if (!isAppleOid(leafMarkerOID)) {
1944 secwarning("creating an Apple pinning policy with a non-Apple OID: %@", leafMarkerOID);
1945 }
1946 add_leaf_marker_string(options, leafMarkerOID);
1947
1948 /* Check revocation using any available method */
1949 add_element(options, kSecPolicyCheckRevocation, kSecPolicyCheckRevocationAny);
1950
1951 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
1952 require(SecPolicyAddStrongKeySizeOptions(options), errOut);
1953
1954 /* Check for weak hashes */
1955 CFDictionaryAddValue(options, kSecPolicyCheckSystemTrustedWeakHash, kCFBooleanTrue);
1956 require(result = SecPolicyCreate(kSecPolicyAppleGenericApplePinned,
1957 policyName, options), errOut);
1958
1959 errOut:
1960 CFReleaseSafe(options);
1961 return result;
1962 }
1963
1964 static bool
1965 requireUATPinning(CFStringRef service)
1966 {
1967 bool pinningRequired = true;
1968
1969 if (SecIsInternalRelease()) {
1970 CFStringRef setting = CFStringCreateWithFormat(NULL, NULL, CFSTR("AppleServerAuthenticationNoPinning%@"), service);
1971 require(setting, fail);
1972 if(isCFPreferenceInSecurityDomain(setting)) {
1973 pinningRequired = false;
1974 } else {
1975 secnotice("pinningQA", "could not disable pinning: %@ not true", setting);
1976 }
1977 CFRelease(setting);
1978
1979 if (!pinningRequired) {
1980 goto fail;
1981 }
1982
1983 if(isCFPreferenceInSecurityDomain(CFSTR("AppleServerAuthenticationNoPinning"))) {
1984 pinningRequired = false;
1985 } else {
1986 secnotice("pinningQA", "could not disable pinning: AppleServerAuthenticationNoPinning not true");
1987 }
1988 } else {
1989 secnotice("pinningQA", "could not disable pinning: not an internal release");
1990 }
1991 fail:
1992 return pinningRequired;
1993 }
1994
1995 SecPolicyRef SecPolicyCreateAppleSSLPinned(CFStringRef policyName, CFStringRef hostname,
1996 CFStringRef intermediateMarkerOID, CFStringRef leafMarkerOID) {
1997 CFMutableDictionaryRef options = NULL, appleAnchorOptions = NULL;
1998 SecPolicyRef result = NULL;
1999
2000 if (!policyName || !hostname || !leafMarkerOID) {
2001 goto errOut;
2002 }
2003
2004 if (requireUATPinning(policyName)) {
2005 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
2006 &kCFTypeDictionaryKeyCallBacks,
2007 &kCFTypeDictionaryValueCallBacks), errOut);
2008
2009 SecPolicyAddBasicX509Options(options);
2010
2011 /* Anchored to the Apple Roots */
2012 require_quiet(appleAnchorOptions = CFDictionaryCreateMutableForCFTypes(NULL), errOut);
2013 if (allowTestHierarchyForPolicy(policyName, true)) {
2014 CFDictionarySetValue(appleAnchorOptions,
2015 kSecPolicyAppleAnchorIncludeTestRoots, kCFBooleanTrue);
2016 }
2017 add_element(options, kSecPolicyCheckAnchorApple, appleAnchorOptions);
2018
2019 /* Exactly 3 certs in the chain */
2020 require(SecPolicyAddChainLengthOptions(options, 3), errOut);
2021
2022 if (intermediateMarkerOID) {
2023 /* Intermediate marker OID matches input OID */
2024 if (!isAppleOid(intermediateMarkerOID)) {
2025 secwarning("creating an Apple pinning policy with a non-Apple OID: %@", intermediateMarkerOID);
2026 }
2027 add_element(options, kSecPolicyCheckIntermediateMarkerOid, intermediateMarkerOID);
2028 } else {
2029 add_element(options, kSecPolicyCheckIntermediateMarkerOid, CFSTR("1.2.840.113635.100.6.2.12"));
2030 }
2031
2032 /* Leaf marker OID matches input OID */
2033 if (!isAppleOid(leafMarkerOID)) {
2034 secwarning("creating an Apple pinning policy with a non-Apple OID: %@", leafMarkerOID);
2035 }
2036 add_leaf_marker_string(options, leafMarkerOID);
2037
2038 /* New leaf marker OID format */
2039 add_leaf_marker_value_string(options, CFSTR("1.2.840.113635.100.6.48.1"), leafMarkerOID);
2040
2041 /* ServerAuth EKU is in leaf cert */
2042 add_eku_string(options, CFSTR("1.3.6.1.5.5.7.3.1"));
2043
2044 /* Hostname is in leaf cert */
2045 add_element(options, kSecPolicyCheckSSLHostname, hostname);
2046
2047 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
2048 require(SecPolicyAddStrongKeySizeOptions(options), errOut);
2049
2050 /* Check for weak hashes */
2051 CFDictionaryAddValue(options, kSecPolicyCheckSystemTrustedWeakHash, kCFBooleanTrue);
2052
2053 /* Check revocation using any available method */
2054 add_element(options, kSecPolicyCheckRevocation, kSecPolicyCheckRevocationAny);
2055
2056 require(result = SecPolicyCreate(kSecPolicyAppleGenericAppleSSLPinned,
2057 policyName, options), errOut);
2058
2059 } else {
2060 result = SecPolicyCreateSSL(true, hostname);
2061 SecPolicySetOid(result, kSecPolicyAppleGenericAppleSSLPinned);
2062 }
2063
2064 errOut:
2065 CFReleaseSafe(options);
2066 CFReleaseSafe(appleAnchorOptions);
2067 return result;
2068 }
2069
2070 SecPolicyRef SecPolicyCreateiPhoneActivation(void) {
2071 CFMutableDictionaryRef options = NULL;
2072 SecPolicyRef result = NULL;
2073
2074 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
2075 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut);
2076
2077 SecPolicyAddBasicCertOptions(options);
2078
2079 #if 0
2080 CFDictionaryAddValue(options, kSecPolicyCheckKeyUsage,
2081 kCFBooleanTrue);
2082 CFDictionaryAddValue(options, kSecPolicyCheckExtendedKeyUsage,
2083 kCFBooleanTrue);
2084 #endif
2085
2086 /* Basic X.509 policy with the additional requirements that the chain
2087 length is 3, it's anchored at the AppleCA and the leaf certificate
2088 has issuer "Apple iPhone Certification Authority" and
2089 subject "Apple iPhone Activation" for the common name. */
2090 CFDictionaryAddValue(options, kSecPolicyCheckIssuerCommonName,
2091 CFSTR("Apple iPhone Certification Authority"));
2092 CFDictionaryAddValue(options, kSecPolicyCheckSubjectCommonName,
2093 CFSTR("Apple iPhone Activation"));
2094
2095 require(SecPolicyAddChainLengthOptions(options, 3), errOut);
2096 require(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameiPhoneActivation), errOut);
2097
2098 require(result = SecPolicyCreate(kSecPolicyAppleiPhoneActivation,
2099 kSecPolicyNameiPhoneActivation, options),
2100 errOut);
2101
2102 errOut:
2103 CFReleaseSafe(options);
2104 return result;
2105 }
2106
2107 SecPolicyRef SecPolicyCreateiPhoneDeviceCertificate(void) {
2108 CFMutableDictionaryRef options = NULL;
2109 SecPolicyRef result = NULL;
2110
2111 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
2112 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut);
2113
2114 SecPolicyAddBasicCertOptions(options);
2115
2116 #if 0
2117 CFDictionaryAddValue(options, kSecPolicyCheckKeyUsage,
2118 kCFBooleanTrue);
2119 CFDictionaryAddValue(options, kSecPolicyCheckExtendedKeyUsage,
2120 kCFBooleanTrue);
2121 #endif
2122
2123 /* Basic X.509 policy with the additional requirements that the chain
2124 length is 4, it's anchored at the AppleCA and the first intermediate
2125 has the subject "Apple iPhone Device CA". */
2126 CFDictionaryAddValue(options, kSecPolicyCheckIssuerCommonName,
2127 CFSTR("Apple iPhone Device CA"));
2128
2129 require(SecPolicyAddChainLengthOptions(options, 4), errOut);
2130 require(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameiPhoneDeviceCertificate), errOut);
2131
2132 require(result = SecPolicyCreate(kSecPolicyAppleiPhoneDeviceCertificate,
2133 kSecPolicyNameiPhoneDeviceCertificate, options),
2134 errOut);
2135
2136 errOut:
2137 CFReleaseSafe(options);
2138 return result;
2139 }
2140
2141 SecPolicyRef SecPolicyCreateFactoryDeviceCertificate(void) {
2142 CFMutableDictionaryRef options = NULL;
2143 SecPolicyRef result = NULL;
2144
2145 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
2146 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut);
2147
2148 SecPolicyAddBasicCertOptions(options);
2149
2150 #if 0
2151 CFDictionaryAddValue(options, kSecPolicyCheckKeyUsage,
2152 kCFBooleanTrue);
2153 CFDictionaryAddValue(options, kSecPolicyCheckExtendedKeyUsage,
2154 kCFBooleanTrue);
2155 #endif
2156
2157 /* Basic X.509 policy with the additional requirements that the chain
2158 is anchored at the factory device certificate issuer. */
2159 require(SecPolicyAddAnchorSHA1Options(options, kFactoryDeviceCASHA1), errOut);
2160
2161 require(result = SecPolicyCreate(kSecPolicyAppleFactoryDeviceCertificate,
2162 kSecPolicyNameFactoryDeviceCertificate, options),
2163 errOut);
2164
2165 errOut:
2166 CFReleaseSafe(options);
2167 return result;
2168 }
2169
2170 SecPolicyRef SecPolicyCreateiAP(void) {
2171 CFMutableDictionaryRef options = NULL;
2172 SecPolicyRef result = NULL;
2173 CFTimeZoneRef tz = NULL;
2174 CFDateRef date = NULL;
2175
2176 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
2177 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut);
2178
2179 SecPolicyAddBasicCertOptions(options);
2180
2181 CFDictionaryAddValue(options, kSecPolicyCheckSubjectCommonNamePrefix,
2182 CFSTR("IPA_"));
2183
2184 date = CFDateCreateForGregorianZuluDay(NULL, 2006, 5, 31);
2185 CFDictionaryAddValue(options, kSecPolicyCheckNotValidBefore, date);
2186
2187 require(result = SecPolicyCreate(kSecPolicyAppleiAP,
2188 kSecPolicyNameiAP, options),
2189 errOut);
2190
2191 errOut:
2192 CFReleaseSafe(date);
2193 CFReleaseSafe(tz);
2194 CFReleaseSafe(options);
2195 return result;
2196 }
2197
2198 SecPolicyRef SecPolicyCreateiTunesStoreURLBag(void) {
2199 CFMutableDictionaryRef options = NULL;
2200 SecPolicyRef result = NULL;
2201
2202
2203 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
2204 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut);
2205
2206 SecPolicyAddBasicCertOptions(options);
2207
2208 CFDictionaryAddValue(options, kSecPolicyCheckSubjectOrganization,
2209 CFSTR("Apple Inc."));
2210 CFDictionaryAddValue(options, kSecPolicyCheckSubjectCommonName,
2211 CFSTR("iTunes Store URL Bag"));
2212
2213 require(SecPolicyAddChainLengthOptions(options, 2), errOut);
2214 require(SecPolicyAddAnchorSHA1Options(options, kITMSCASHA1), errOut);
2215
2216 require(result = SecPolicyCreate(kSecPolicyAppleiTunesStoreURLBag,
2217 kSecPolicyNameiTunesStoreURLBag, options), errOut);
2218
2219 errOut:
2220 CFReleaseSafe(options);
2221 return result;
2222 }
2223
2224 SecPolicyRef SecPolicyCreateEAP(Boolean server, CFArrayRef trustedServerNames) {
2225 CFMutableDictionaryRef options = NULL;
2226 SecPolicyRef result = NULL;
2227
2228 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
2229 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut);
2230
2231 SecPolicyAddBasicX509Options(options);
2232
2233 /* Since EAP is used to setup the network we don't want evaluation
2234 using this policy to access the network. */
2235 CFDictionaryAddValue(options, kSecPolicyCheckNoNetworkAccess,
2236 kCFBooleanTrue);
2237
2238 if (trustedServerNames) {
2239 CFDictionaryAddValue(options, kSecPolicyCheckEAPTrustedServerNames, trustedServerNames);
2240 }
2241
2242 if (server) {
2243 /* Check for weak hashes */
2244 CFDictionaryAddValue(options, kSecPolicyCheckSystemTrustedWeakHash, kCFBooleanTrue);
2245 }
2246
2247 /* We need to check for EKU per rdar://22206018 */
2248 set_ssl_ekus(options, server);
2249
2250 require(result = SecPolicyCreate(kSecPolicyAppleEAP,
2251 server ? kSecPolicyNameEAPServer : kSecPolicyNameEAPClient,
2252 options), errOut);
2253
2254 errOut:
2255 CFReleaseSafe(options);
2256 return result;
2257 }
2258
2259 SecPolicyRef SecPolicyCreateIPSec(Boolean server, CFStringRef hostname) {
2260 CFMutableDictionaryRef options = NULL;
2261 SecPolicyRef result = NULL;
2262
2263 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
2264 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut);
2265
2266 SecPolicyAddBasicX509Options(options);
2267
2268 if (hostname) {
2269 CFDictionaryAddValue(options, kSecPolicyCheckSSLHostname, hostname);
2270 }
2271
2272 /* Require oidExtendedKeyUsageIPSec if Extended Keyusage Extention is
2273 present. */
2274 /* Per <rdar://problem/6843827> Cisco VPN Certificate compatibility issue.
2275 We don't check the EKU for IPSec certs for now. If we do add eku
2276 checking back in the future, we should probably also accept the
2277 following EKUs:
2278 ipsecEndSystem 1.3.6.1.5.5.7.3.5
2279 and possibly even
2280 ipsecTunnel 1.3.6.1.5.5.7.3.6
2281 ipsecUser 1.3.6.1.5.5.7.3.7
2282 */
2283 //add_eku(options, NULL); /* eku extension is optional */
2284 //add_eku(options, &oidAnyExtendedKeyUsage);
2285 //add_eku(options, &oidExtendedKeyUsageIPSec);
2286
2287 require(result = SecPolicyCreate(kSecPolicyAppleIPsec,
2288 server ? kSecPolicyNameIPSecServer : kSecPolicyNameIPSecClient,
2289 options), errOut);
2290
2291 errOut:
2292 CFReleaseSafe(options);
2293 return result;
2294 }
2295
2296 SecPolicyRef SecPolicyCreateiPhoneApplicationSigning(void) {
2297 CFMutableDictionaryRef options = NULL, appleAnchorOptions = NULL;
2298 SecPolicyRef result = NULL;
2299
2300 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
2301 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut);
2302
2303 SecPolicyAddBasicCertOptions(options);
2304
2305 appleAnchorOptions = CFDictionaryCreateMutableForCFTypes(NULL);
2306 require(appleAnchorOptions, errOut);
2307
2308 if (allowTestHierarchyForPolicy(kSecPolicyNameiPhoneApplicationSigning, false)) {
2309 /* Allow a test hierarchy-signed cert with prod name/OIDs */
2310 CFDictionarySetValue(appleAnchorOptions,
2311 kSecPolicyAppleAnchorIncludeTestRoots, kCFBooleanTrue);
2312 }
2313
2314 /* Leaf checks */
2315 if (SecIsInternalRelease()) {
2316 /* Allow a prod hierarchy-signed test cert */
2317 CFDictionaryAddValue(options, kSecPolicyCheckSubjectCommonNameTEST,
2318 CFSTR("Apple iPhone OS Application Signing"));
2319 add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.6.1.3.1"));
2320 add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.6.1.6.1"));
2321
2322 /* or a test hierarchy-signed test cert */
2323 CFDictionarySetValue(appleAnchorOptions,
2324 kSecPolicyAppleAnchorIncludeTestRoots, kCFBooleanTrue);
2325 }
2326 else {
2327 CFDictionaryAddValue(options, kSecPolicyCheckSubjectCommonName,
2328 CFSTR("Apple iPhone OS Application Signing"));
2329 }
2330 add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.6.1.3"));
2331 add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.6.1.6"));
2332
2333 add_eku(options, NULL); /* eku extension is optional */
2334 add_eku(options, &oidAnyExtendedKeyUsage);
2335 add_eku(options, &oidExtendedKeyUsageCodeSigning);
2336
2337 /* Intermediate check */
2338 CFDictionaryAddValue(options, kSecPolicyCheckIssuerCommonName,
2339 CFSTR("Apple iPhone Certification Authority"));
2340
2341 /* Chain length check */
2342 require(SecPolicyAddChainLengthOptions(options, 3), errOut);
2343
2344 /* Anchored to the Apple Roots */
2345 add_element(options, kSecPolicyCheckAnchorApple, appleAnchorOptions);
2346
2347 require(result = SecPolicyCreate(kSecPolicyAppleiPhoneApplicationSigning,
2348 kSecPolicyNameiPhoneApplicationSigning, options),
2349 errOut);
2350
2351 errOut:
2352 CFReleaseSafe(options);
2353 CFReleaseSafe(appleAnchorOptions);
2354 return result;
2355 }
2356
2357 SecPolicyRef SecPolicyCreateiPhoneProfileApplicationSigning(void) {
2358 CFMutableDictionaryRef options = NULL;
2359 SecPolicyRef result = NULL;
2360
2361 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
2362 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut);
2363 CFDictionaryAddValue(options, kSecPolicyCheckRevocation, kSecPolicyCheckRevocationAny);
2364 CFDictionaryAddValue(options, kSecPolicyCheckValidLeaf, kCFBooleanFalse);
2365
2366 require(result = SecPolicyCreate(kSecPolicyAppleiPhoneProfileApplicationSigning,
2367 kSecPolicyNameiPhoneProfileApplicationSigning,
2368 options), errOut);
2369
2370 errOut:
2371 CFReleaseSafe(options);
2372 return result;
2373 }
2374
2375 SecPolicyRef SecPolicyCreateiPhoneProvisioningProfileSigning(void) {
2376 CFMutableDictionaryRef options = NULL;
2377 SecPolicyRef result = NULL;
2378
2379 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
2380 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut);
2381
2382 SecPolicyAddBasicCertOptions(options);
2383
2384 /* Basic X.509 policy with the additional requirements that the chain
2385 length is 3, it's anchored at the AppleCA and the leaf certificate
2386 has issuer "Apple iPhone Certification Authority" and
2387 subject "Apple iPhone OS Provisioning Profile Signing" for the common name. */
2388 CFDictionaryAddValue(options, kSecPolicyCheckIssuerCommonName,
2389 CFSTR("Apple iPhone Certification Authority"));
2390 if (SecIsInternalRelease()) {
2391 CFDictionaryAddValue(options, kSecPolicyCheckSubjectCommonNameTEST,
2392 CFSTR("Apple iPhone OS Provisioning Profile Signing"));
2393 }
2394 else {
2395 CFDictionaryAddValue(options, kSecPolicyCheckSubjectCommonName,
2396 CFSTR("Apple iPhone OS Provisioning Profile Signing"));
2397 }
2398
2399 require(SecPolicyAddChainLengthOptions(options, 3), errOut);
2400 require(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameiPhoneProvisioningProfileSigning), errOut);
2401
2402 require(result = SecPolicyCreate(kSecPolicyAppleiPhoneProvisioningProfileSigning,
2403 kSecPolicyNameiPhoneProvisioningProfileSigning, options),
2404 errOut);
2405
2406 /* 1.2.840.113635.100.6.2.2.1, non-critical: DER:05:00 - provisioning profile */
2407
2408 errOut:
2409 CFReleaseSafe(options);
2410 return result;
2411 }
2412
2413 SecPolicyRef SecPolicyCreateAppleTVOSApplicationSigning(void) {
2414 CFMutableDictionaryRef options = NULL;
2415 SecPolicyRef result = NULL;
2416 CFDataRef atvProdOid = NULL;
2417 CFDataRef atvTestOid = NULL;
2418 CFArrayRef oids = NULL;
2419
2420 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
2421 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut);
2422
2423 SecPolicyAddBasicCertOptions(options);
2424
2425 require(SecPolicyAddChainLengthOptions(options, 3), errOut);
2426
2427 require_quiet(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameAppleTVOSApplicationSigning),
2428 errOut);
2429
2430 /* Check for intermediate: Apple Worldwide Developer Relations */
2431 /* 1.2.840.113635.100.6.2.1 */
2432 add_oid(options, kSecPolicyCheckIntermediateMarkerOid, &oidAppleIntmMarkerAppleWWDR);
2433
2434 add_ku(options, kSecKeyUsageDigitalSignature);
2435
2436 /* Check for prod or test AppleTV Application Signing OIDs */
2437 /* Prod: 1.2.840.113635.100.6.1.24 */
2438 /* ProdQA: 1.2.840.113635.100.6.1.24.1 */
2439 add_leaf_marker(options, &oidAppleTVOSApplicationSigningProd);
2440 add_leaf_marker(options, &oidAppleTVOSApplicationSigningProdQA);
2441
2442 require(result = SecPolicyCreate(kSecPolicyAppleTVOSApplicationSigning,
2443 kSecPolicyNameAppleTVOSApplicationSigning, options),
2444 errOut);
2445
2446 errOut:
2447 CFReleaseSafe(options);
2448 CFReleaseSafe(oids);
2449 CFReleaseSafe(atvProdOid);
2450 CFReleaseSafe(atvTestOid);
2451 return result;
2452 }
2453
2454 SecPolicyRef SecPolicyCreateOCSPSigner(void) {
2455 CFMutableDictionaryRef options = NULL;
2456 SecPolicyRef result = NULL;
2457
2458 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
2459 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut);
2460
2461 SecPolicyAddBasicX509Options(options);
2462
2463 /* Require id-kp-OCSPSigning extendedKeyUsage to be present, not optional. */
2464 add_eku(options, &oidExtendedKeyUsageOCSPSigning);
2465
2466 require(result = SecPolicyCreate(kSecPolicyAppleOCSPSigner,
2467 kSecPolicyNameOCSPSigner, options), errOut);
2468
2469 errOut:
2470 CFReleaseSafe(options);
2471 return result;
2472 }
2473
2474 const CFOptionFlags kSecRevocationOnlineCheck = (1 << 5);
2475
2476 SecPolicyRef SecPolicyCreateRevocation(CFOptionFlags revocationFlags) {
2477 CFMutableDictionaryRef options = NULL;
2478 SecPolicyRef result = NULL;
2479
2480 require(revocationFlags != 0, errOut);
2481
2482 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
2483 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut);
2484
2485 if (revocationFlags & kSecRevocationOCSPMethod && revocationFlags & kSecRevocationCRLMethod) {
2486 CFDictionaryAddValue(options, kSecPolicyCheckRevocation, kSecPolicyCheckRevocationAny);
2487 }
2488 else if (revocationFlags & kSecRevocationOCSPMethod) {
2489 CFDictionaryAddValue(options, kSecPolicyCheckRevocation, kSecPolicyCheckRevocationOCSP);
2490 }
2491 else if (revocationFlags & kSecRevocationCRLMethod) {
2492 CFDictionaryAddValue(options, kSecPolicyCheckRevocation, kSecPolicyCheckRevocationCRL);
2493 }
2494
2495 if (revocationFlags & kSecRevocationRequirePositiveResponse) {
2496 CFDictionaryAddValue(options, kSecPolicyCheckRevocationResponseRequired, kCFBooleanTrue);
2497 }
2498
2499 if (revocationFlags & kSecRevocationNetworkAccessDisabled) {
2500 CFDictionaryAddValue(options, kSecPolicyCheckNoNetworkAccess, kCFBooleanTrue);
2501 } else {
2502 /* If the caller didn't explicitly disable network access, the revocation policy
2503 * should override any other policy's network setting.
2504 * In particular, pairing a revocation policy with BasicX509 should result in
2505 * allowing network access for revocation unless explicitly disabled.
2506 * Note that SecTrustSetNetworkFetchAllowed can override even this. */
2507 CFDictionaryAddValue(options, kSecPolicyCheckNoNetworkAccess, kCFBooleanFalse);
2508 }
2509
2510 if (revocationFlags & kSecRevocationOnlineCheck) {
2511 CFDictionaryAddValue(options, kSecPolicyCheckRevocationOnline, kCFBooleanTrue);
2512 }
2513
2514 /* Only flag bits 0-5 are currently defined */
2515 require(((revocationFlags >> 6) == 0), errOut);
2516
2517 require(result = SecPolicyCreate(kSecPolicyAppleRevocation,
2518 kSecPolicyNameRevocation, options), errOut);
2519
2520 errOut:
2521 CFReleaseSafe(options);
2522 return result;
2523 }
2524
2525 SecPolicyRef SecPolicyCreateSMIME(CFIndex smimeUsage, CFStringRef email) {
2526 CFMutableDictionaryRef options = NULL;
2527 SecPolicyRef result = NULL;
2528
2529 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
2530 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut);
2531
2532 SecPolicyAddBasicX509Options(options);
2533
2534 /* We call add_ku for each combination of bits we are willing to allow. */
2535 if (smimeUsage & kSecSignSMIMEUsage) {
2536 add_ku(options, kSecKeyUsageUnspecified);
2537 add_ku(options, kSecKeyUsageDigitalSignature);
2538 add_ku(options, kSecKeyUsageNonRepudiation);
2539 }
2540 if (smimeUsage & kSecKeyEncryptSMIMEUsage) {
2541 add_ku(options, kSecKeyUsageKeyEncipherment);
2542 }
2543 if (smimeUsage & kSecDataEncryptSMIMEUsage) {
2544 add_ku(options, kSecKeyUsageDataEncipherment);
2545 }
2546 if (smimeUsage & kSecKeyExchangeDecryptSMIMEUsage) {
2547 add_ku(options, kSecKeyUsageKeyAgreement | kSecKeyUsageDecipherOnly);
2548 }
2549 if (smimeUsage & kSecKeyExchangeEncryptSMIMEUsage) {
2550 add_ku(options, kSecKeyUsageKeyAgreement | kSecKeyUsageEncipherOnly);
2551 }
2552 if (smimeUsage & kSecKeyExchangeBothSMIMEUsage) {
2553 add_ku(options, kSecKeyUsageKeyAgreement | kSecKeyUsageEncipherOnly | kSecKeyUsageDecipherOnly);
2554 }
2555
2556 if (email) {
2557 CFDictionaryAddValue(options, kSecPolicyCheckEmail, email);
2558 }
2559
2560 /* RFC 3850 paragraph 4.4.4
2561
2562 If the extended key usage extension is present in the certificate
2563 then interpersonal message S/MIME receiving agents MUST check that it
2564 contains either the emailProtection or the anyExtendedKeyUsage OID as
2565 defined in [KEYM]. S/MIME uses other than interpersonal messaging
2566 MAY require the explicit presence of the extended key usage extension
2567 or other OIDs to be present in the extension or both.
2568 */
2569 add_eku(options, NULL); /* eku extension is optional */
2570 add_eku(options, &oidAnyExtendedKeyUsage);
2571 add_eku(options, &oidExtendedKeyUsageEmailProtection);
2572
2573 #if !TARGET_OS_IPHONE
2574 // Check revocation on OS X
2575 CFDictionaryAddValue(options, kSecPolicyCheckRevocation, kSecPolicyCheckRevocationAny);
2576 #endif
2577
2578 require(result = SecPolicyCreate(kSecPolicyAppleSMIME, kSecPolicyNameSMIME, options), errOut);
2579
2580 errOut:
2581 CFReleaseSafe(options);
2582 return result;
2583 }
2584
2585 SecPolicyRef SecPolicyCreateApplePackageSigning(void) {
2586 CFMutableDictionaryRef options = NULL;
2587 SecPolicyRef result = NULL;
2588
2589 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
2590 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut);
2591
2592 SecPolicyAddBasicCertOptions(options);
2593
2594 require(SecPolicyAddChainLengthOptions(options, 3), errOut);
2595 require(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNamePackageSigning), errOut);
2596
2597 add_ku(options, kSecKeyUsageDigitalSignature);
2598 add_eku(options, &oidExtendedKeyUsageCodeSigning);
2599
2600 require(result = SecPolicyCreate(kSecPolicyApplePackageSigning,
2601 kSecPolicyNamePackageSigning, options),
2602 errOut);
2603
2604 errOut:
2605 CFReleaseSafe(options);
2606 return result;
2607
2608 }
2609
2610 SecPolicyRef SecPolicyCreateAppleSWUpdateSigning(void) {
2611 CFMutableDictionaryRef options = NULL;
2612 SecPolicyRef result = NULL;
2613 /*
2614 * OS X rules for this policy:
2615 * -- Must have one intermediate cert
2616 * -- intermediate must have basic constraints with path length 0
2617 * -- intermediate has CSSMOID_APPLE_EKU_CODE_SIGNING EKU
2618 * -- leaf cert has either CODE_SIGNING or CODE_SIGN_DEVELOPMENT EKU (the latter of
2619 * which triggers a CSSMERR_APPLETP_CODE_SIGN_DEVELOPMENT error)
2620 */
2621 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
2622 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut);
2623
2624 SecPolicyAddBasicX509Options(options);
2625
2626 require(SecPolicyAddChainLengthOptions(options, 3), errOut);
2627 require(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameAppleSWUpdateSigning), errOut);
2628
2629 add_eku(options, &oidAppleExtendedKeyUsageCodeSigning);
2630 add_oid(options, kSecPolicyCheckIntermediateEKU, &oidAppleExtendedKeyUsageCodeSigning);
2631
2632 require(result = SecPolicyCreate(kSecPolicyAppleSWUpdateSigning,
2633 kSecPolicyNameAppleSWUpdateSigning, options),
2634 errOut);
2635
2636 errOut:
2637 CFReleaseSafe(options);
2638 return result;
2639
2640 }
2641
2642 SecPolicyRef SecPolicyCreateCodeSigning(void) {
2643 CFMutableDictionaryRef options = NULL;
2644 SecPolicyRef result = NULL;
2645
2646 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
2647 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut);
2648
2649 SecPolicyAddBasicX509Options(options);
2650
2651 /* If the key usage extension is present, we accept it having either of
2652 these values. */
2653 add_ku(options, kSecKeyUsageDigitalSignature);
2654 add_ku(options, kSecKeyUsageNonRepudiation);
2655
2656 /* We require an extended key usage extension with the codesigning
2657 eku purpose. (The Apple codesigning eku is not accepted here
2658 since it's valid only for SecPolicyCreateAppleSWUpdateSigning.) */
2659 add_eku(options, &oidExtendedKeyUsageCodeSigning);
2660 #if TARGET_OS_IPHONE
2661 /* Accept the 'any' eku on iOS only to match prior behavior.
2662 This may be further restricted in future releases. */
2663 add_eku(options, &oidAnyExtendedKeyUsage);
2664 #endif
2665
2666 require(result = SecPolicyCreate(kSecPolicyAppleCodeSigning,
2667 kSecPolicyNameCodeSigning, options),
2668 errOut);
2669
2670 errOut:
2671 CFReleaseSafe(options);
2672 return result;
2673 }
2674
2675 /* Explicitly leave out empty subject/subjectaltname check */
2676 SecPolicyRef SecPolicyCreateLockdownPairing(void) {
2677 CFMutableDictionaryRef options = NULL;
2678 SecPolicyRef result = NULL;
2679
2680 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
2681 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut);
2682 //CFDictionaryAddValue(options, kSecPolicyCheckBasicCertificateProcessing,
2683 // kCFBooleanTrue); // Happens automatically in SecPVCPathChecks
2684 CFDictionaryAddValue(options, kSecPolicyCheckCriticalExtensions,
2685 kCFBooleanTrue);
2686 CFDictionaryAddValue(options, kSecPolicyCheckIdLinkage,
2687 kCFBooleanTrue);
2688 CFDictionaryAddValue(options, kSecPolicyCheckBasicConstraints,
2689 kCFBooleanTrue);
2690 CFDictionaryAddValue(options, kSecPolicyCheckQualifiedCertStatements,
2691 kCFBooleanTrue);
2692 CFDictionaryAddValue(options, kSecPolicyCheckWeakIntermediates, kCFBooleanTrue);
2693 CFDictionaryAddValue(options, kSecPolicyCheckWeakLeaf, kCFBooleanTrue);
2694 CFDictionaryAddValue(options, kSecPolicyCheckWeakRoot, kCFBooleanTrue);
2695
2696 require(result = SecPolicyCreate(kSecPolicyAppleLockdownPairing,
2697 kSecPolicyNameLockdownPairing, options), errOut);
2698
2699 errOut:
2700 CFReleaseSafe(options);
2701 return result;
2702 }
2703
2704 SecPolicyRef SecPolicyCreateURLBag(void) {
2705 CFMutableDictionaryRef options = NULL;
2706 SecPolicyRef result = NULL;
2707
2708 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
2709 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut);
2710
2711 SecPolicyAddBasicCertOptions(options);
2712
2713 add_eku(options, &oidExtendedKeyUsageCodeSigning);
2714
2715 require(result = SecPolicyCreate(kSecPolicyAppleURLBag,
2716 kSecPolicyNameURLBag, options), errOut);
2717
2718 errOut:
2719 CFReleaseSafe(options);
2720 return result;
2721 }
2722
2723 static bool SecPolicyAddAppleCertificationAuthorityOptions(CFMutableDictionaryRef options, bool honorValidity, CFStringRef policyName)
2724 {
2725 bool success = false;
2726
2727 if (honorValidity)
2728 SecPolicyAddBasicX509Options(options);
2729 else
2730 SecPolicyAddBasicCertOptions(options);
2731
2732 #if 0
2733 CFDictionaryAddValue(options, kSecPolicyCheckKeyUsage,
2734 kCFBooleanTrue);
2735 CFDictionaryAddValue(options, kSecPolicyCheckExtendedKeyUsage,
2736 kCFBooleanTrue);
2737 #endif
2738
2739 /* Basic X.509 policy with the additional requirements that the chain
2740 length is 3, it's anchored at the AppleCA and the leaf certificate
2741 has issuer "Apple iPhone Certification Authority". */
2742 CFDictionaryAddValue(options, kSecPolicyCheckIssuerCommonName,
2743 CFSTR("Apple iPhone Certification Authority"));
2744
2745 require(SecPolicyAddChainLengthOptions(options, 3), errOut);
2746 require(SecPolicyAddAppleAnchorOptions(options, policyName), errOut);
2747
2748 success = true;
2749
2750 errOut:
2751 return success;
2752 }
2753
2754 static SecPolicyRef SecPolicyCreateAppleCertificationAuthorityPolicy(CFStringRef policyOID, CFStringRef policyName,
2755 CFStringRef leafName, bool honorValidity)
2756 {
2757 CFMutableDictionaryRef options = NULL;
2758 SecPolicyRef result = NULL;
2759
2760 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
2761 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks), errOut);
2762
2763 require(SecPolicyAddAppleCertificationAuthorityOptions(options, honorValidity, policyName), errOut);
2764
2765 CFDictionaryAddValue(options, kSecPolicyCheckSubjectCommonName, leafName);
2766
2767 require(result = SecPolicyCreate(policyOID, policyName, options),
2768 errOut);
2769
2770 errOut:
2771 CFReleaseSafe(options);
2772 return result;
2773 }
2774
2775
2776 SecPolicyRef SecPolicyCreateOTATasking(void)
2777 {
2778 return SecPolicyCreateAppleCertificationAuthorityPolicy(kSecPolicyAppleOTATasking,
2779 kSecPolicyNameOTATasking,
2780 CFSTR("OTA Task Signing"), true);
2781 }
2782
2783 SecPolicyRef SecPolicyCreateMobileAsset(void)
2784 {
2785 return SecPolicyCreateAppleCertificationAuthorityPolicy(kSecPolicyAppleMobileAsset,
2786 kSecPolicyNameMobileAsset,
2787 CFSTR("Asset Manifest Signing"), false);
2788 }
2789
2790 SecPolicyRef SecPolicyCreateAppleIDAuthorityPolicy(void)
2791 {
2792 SecPolicyRef result = NULL;
2793 CFMutableDictionaryRef options = NULL;
2794 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
2795 &kCFTypeDictionaryKeyCallBacks,
2796 &kCFTypeDictionaryValueCallBacks), out);
2797
2798 //Leaf appears to be a SSL only cert, so policy should expand on that policy
2799 SecPolicyAddBasicX509Options(options);
2800
2801 // Apple CA anchored
2802 require(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameAppleIDAuthority), out);
2803
2804 // with the addition of the existence check of an extension with "Apple ID Sharing Certificate" oid (1.2.840.113635.100.4.7)
2805 // NOTE: this obviously intended to have gone into Extended Key Usage, but evidence of existing certs proves the contrary.
2806 add_leaf_marker(options, &oidAppleExtendedKeyUsageAppleID);
2807
2808 // 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.
2809 add_oid(options, kSecPolicyCheckIntermediateMarkerOid, &oidAppleIntmMarkerAppleID);
2810 add_oid(options, kSecPolicyCheckIntermediateMarkerOid, &oidAppleIntmMarkerAppleID2);
2811
2812 require(result = SecPolicyCreate(kSecPolicyAppleIDAuthority,
2813 kSecPolicyNameAppleIDAuthority, options), out);
2814
2815 out:
2816 CFReleaseSafe(options);
2817 return result;
2818 }
2819
2820 SecPolicyRef SecPolicyCreateMacAppStoreReceipt(void)
2821 {
2822 SecPolicyRef result = NULL;
2823 CFMutableDictionaryRef options = NULL;
2824 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
2825 &kCFTypeDictionaryKeyCallBacks,
2826 &kCFTypeDictionaryValueCallBacks), out);
2827
2828 SecPolicyAddBasicX509Options(options);
2829
2830 // Apple CA anchored
2831 require(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameMacAppStoreReceipt), out);
2832
2833 // Chain length of 3
2834 require(SecPolicyAddChainLengthOptions(options, 3), out);
2835
2836 // MacAppStoreReceipt policy OID
2837 add_certificate_policy_oid_string(options, CFSTR("1.2.840.113635.100.5.6.1"));
2838
2839 // Intermediate marker OID
2840 add_element(options, kSecPolicyCheckIntermediateMarkerOid, CFSTR("1.2.840.113635.100.6.2.1"));
2841
2842 // Leaf marker OID
2843 add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.6.11.1"));
2844
2845 // Check revocation
2846 CFDictionaryAddValue(options, kSecPolicyCheckRevocation, kSecPolicyCheckRevocationAny);
2847
2848 require(result = SecPolicyCreate(kSecPolicyMacAppStoreReceipt,
2849 kSecPolicyNameMacAppStoreReceipt, options), out);
2850
2851 out:
2852 CFReleaseSafe(options);
2853 return result;
2854
2855 }
2856
2857 static SecPolicyRef _SecPolicyCreatePassbookCardSigner(CFStringRef cardIssuer, CFStringRef teamIdentifier, bool requireTeamID)
2858 {
2859 SecPolicyRef result = NULL;
2860 CFMutableDictionaryRef options = NULL;
2861 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
2862 &kCFTypeDictionaryKeyCallBacks,
2863 &kCFTypeDictionaryValueCallBacks), out);
2864
2865 SecPolicyAddBasicX509Options(options);
2866 SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameApplePassbook);
2867
2868 // Chain length of 3
2869 require(SecPolicyAddChainLengthOptions(options, 3), out);
2870
2871 if (teamIdentifier) {
2872 // If supplied, teamIdentifier must match subject OU field
2873 CFDictionaryAddValue(options, kSecPolicyCheckSubjectOrganizationalUnit, teamIdentifier);
2874 }
2875 else {
2876 // If not supplied, and it was required, fail
2877 require(!requireTeamID, out);
2878 }
2879
2880 // Must be both push and 3rd party package signing
2881 add_leaf_marker_value(options, &oidAppleInstallerPackagingSigningExternal, cardIssuer);
2882
2883 // We should check that it also has push marker, but we don't support requiring both, only either.
2884 // add_independent_oid(options, kSecPolicyCheckLeafMarkerOid, &oidApplePushServiceClient);
2885
2886 //WWDR Intermediate marker OID
2887 add_element(options, kSecPolicyCheckIntermediateMarkerOid, CFSTR("1.2.840.113635.100.6.2.1"));
2888
2889 // And Passbook signing eku
2890 add_eku(options, &oidAppleExtendedKeyUsagePassbook);
2891
2892 require(result = SecPolicyCreate(kSecPolicyApplePassbookSigning,
2893 kSecPolicyNameApplePassbook, options), out);
2894
2895 out:
2896 CFReleaseSafe(options);
2897 return result;
2898 }
2899
2900 SecPolicyRef SecPolicyCreatePassbookCardSigner(CFStringRef cardIssuer, CFStringRef teamIdentifier)
2901 {
2902 return _SecPolicyCreatePassbookCardSigner(cardIssuer, teamIdentifier, true);
2903 }
2904
2905
2906 static SecPolicyRef CreateMobileStoreSigner(Boolean forTest)
2907 {
2908
2909 SecPolicyRef result = NULL;
2910 CFMutableDictionaryRef options = NULL;
2911 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
2912 &kCFTypeDictionaryKeyCallBacks,
2913 &kCFTypeDictionaryValueCallBacks), errOut);
2914 SecPolicyAddBasicX509Options(options);
2915 SecPolicyAddAppleAnchorOptions(options,
2916 ((forTest) ? kSecPolicyNameAppleTestMobileStore :
2917 kSecPolicyNameAppleMobileStore));
2918
2919 require(SecPolicyAddChainLengthOptions(options, 3), errOut);
2920
2921 CFDictionaryAddValue(options, kSecPolicyCheckIssuerCommonName,
2922 CFSTR("Apple System Integration 2 Certification Authority"));
2923
2924 add_ku(options, kSecKeyUsageDigitalSignature);
2925
2926 const DERItem* pOID = (forTest) ? &oidApplePolicyMobileStoreProdQA : &oidApplePolicyMobileStore;
2927
2928 add_certificate_policy_oid(options, pOID);
2929
2930 require(result = SecPolicyCreate((forTest) ? kSecPolicyAppleTestMobileStore : kSecPolicyAppleMobileStore,
2931 (forTest) ? kSecPolicyNameAppleTestMobileStore : kSecPolicyNameAppleMobileStore,
2932 options), errOut);
2933
2934 errOut:
2935 CFReleaseSafe(options);
2936 return result;
2937 }
2938
2939 SecPolicyRef SecPolicyCreateMobileStoreSigner(void)
2940 {
2941 return CreateMobileStoreSigner(false);
2942 }
2943
2944 SecPolicyRef SecPolicyCreateTestMobileStoreSigner(void)
2945 {
2946 return CreateMobileStoreSigner(true);
2947 }
2948
2949
2950 CF_RETURNS_RETAINED SecPolicyRef SecPolicyCreateEscrowServiceSigner(void)
2951 {
2952 SecPolicyRef result = NULL;
2953 CFMutableDictionaryRef options = NULL;
2954 CFArrayRef anArray = NULL;
2955 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
2956 &kCFTypeDictionaryKeyCallBacks,
2957 &kCFTypeDictionaryValueCallBacks), errOut);
2958
2959 // X509, ignoring date validity
2960 SecPolicyAddBasicCertOptions(options);
2961
2962
2963 add_ku(options, kSecKeyUsageKeyEncipherment);
2964
2965 //add_leaf_marker(options, &oidApplePolicyEscrowService);
2966 require(SecPolicyAddChainLengthOptions(options, 2), errOut);
2967
2968
2969 Boolean anchorAdded = false;
2970 // Get the roots by calling the SecCertificateCopyEscrowRoots
2971 anArray = SecCertificateCopyEscrowRoots(kSecCertificateProductionEscrowRoot);
2972 CFIndex numRoots = 0;
2973 if (NULL == anArray || 0 == (numRoots = CFArrayGetCount(anArray)))
2974 {
2975 goto errOut;
2976 }
2977
2978 for (CFIndex iCnt = 0; iCnt < numRoots; iCnt++)
2979 {
2980 SecCertificateRef aCert = (SecCertificateRef)CFArrayGetValueAtIndex(anArray, iCnt);
2981
2982 if (NULL != aCert)
2983 {
2984 CFDataRef sha_data = SecCertificateGetSHA1Digest(aCert);
2985 if (NULL != sha_data)
2986 {
2987 const UInt8* pSHAData = CFDataGetBytePtr(sha_data);
2988 if (NULL != pSHAData)
2989 {
2990 SecPolicyAddAnchorSHA1Options(options, pSHAData);
2991 anchorAdded = true;
2992 }
2993 }
2994 }
2995 }
2996 CFReleaseNull(anArray);
2997
2998 if (!anchorAdded)
2999 {
3000 goto errOut;
3001 }
3002
3003
3004 require(result = SecPolicyCreate(kSecPolicyAppleEscrowService,
3005 kSecPolicyNameAppleEscrowService, options), errOut);
3006
3007 errOut:
3008 CFReleaseSafe(anArray);
3009 CFReleaseSafe(options);
3010 return result;
3011 }
3012
3013 CF_RETURNS_RETAINED SecPolicyRef SecPolicyCreatePCSEscrowServiceSigner(void)
3014 {
3015 SecPolicyRef result = NULL;
3016 CFMutableDictionaryRef options = NULL;
3017 CFArrayRef anArray = NULL;
3018 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
3019 &kCFTypeDictionaryKeyCallBacks,
3020 &kCFTypeDictionaryValueCallBacks), errOut);
3021
3022 SecPolicyAddBasicX509Options(options);
3023
3024
3025 add_ku(options, kSecKeyUsageKeyEncipherment);
3026
3027 //add_leaf_marker(options, &oidApplePolicyEscrowService);
3028 require(SecPolicyAddChainLengthOptions(options, 2), errOut);
3029
3030
3031 Boolean anchorAdded = false;
3032 anArray = SecCertificateCopyEscrowRoots(kSecCertificateProductionPCSEscrowRoot);
3033 CFIndex numRoots = 0;
3034 if (NULL == anArray || 0 == (numRoots = CFArrayGetCount(anArray)))
3035 {
3036 goto errOut;
3037 }
3038
3039 for (CFIndex iCnt = 0; iCnt < numRoots; iCnt++)
3040 {
3041 SecCertificateRef aCert = (SecCertificateRef)CFArrayGetValueAtIndex(anArray, iCnt);
3042
3043 if (NULL != aCert)
3044 {
3045 CFDataRef sha_data = SecCertificateGetSHA1Digest(aCert);
3046 if (NULL != sha_data)
3047 {
3048 const UInt8* pSHAData = CFDataGetBytePtr(sha_data);
3049 if (NULL != pSHAData)
3050 {
3051 SecPolicyAddAnchorSHA1Options(options, pSHAData);
3052 anchorAdded = true;
3053 }
3054 }
3055 }
3056 }
3057 CFReleaseNull(anArray);
3058
3059 if (!anchorAdded)
3060 {
3061 goto errOut;
3062 }
3063
3064
3065 require(result = SecPolicyCreate(kSecPolicyApplePCSEscrowService,
3066 kSecPolicyNameApplePCSEscrowService, options), errOut);
3067
3068 errOut:
3069 CFReleaseSafe(anArray);
3070 CFReleaseSafe(options);
3071 return result;
3072 }
3073
3074 static SecPolicyRef CreateConfigurationProfileSigner(bool forTest) {
3075 SecPolicyRef result = NULL;
3076 CFMutableDictionaryRef options = NULL;
3077 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
3078 &kCFTypeDictionaryKeyCallBacks,
3079 &kCFTypeDictionaryValueCallBacks), errOut);
3080
3081 SecPolicyAddBasicX509Options(options);
3082 SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameAppleProfileSigner);
3083
3084 //Chain length 3
3085 require(SecPolicyAddChainLengthOptions(options, 3), errOut);
3086
3087 // Require the profile signing EKU
3088 const DERItem* pOID = (forTest) ? &oidAppleExtendedKeyUsageQAProfileSigning :&oidAppleExtendedKeyUsageProfileSigning;
3089 add_eku(options, pOID);
3090
3091 // Require the Apple Application Integration CA marker OID
3092 add_element(options, kSecPolicyCheckIntermediateMarkerOid, CFSTR("1.2.840.113635.100.6.2.3"));
3093
3094 require(result = SecPolicyCreate((forTest) ? kSecPolicyAppleQAProfileSigner: kSecPolicyAppleProfileSigner,
3095 (forTest) ? kSecPolicyNameAppleQAProfileSigner : kSecPolicyNameAppleProfileSigner,
3096 options), errOut);
3097
3098 errOut:
3099 CFReleaseSafe(options);
3100 return result;
3101 }
3102
3103 SecPolicyRef SecPolicyCreateConfigurationProfileSigner(void)
3104 {
3105 return CreateConfigurationProfileSigner(false);
3106 }
3107
3108
3109 SecPolicyRef SecPolicyCreateQAConfigurationProfileSigner(void)
3110 {
3111 if (SecIsInternalRelease()) {
3112 return CreateConfigurationProfileSigner(true);
3113 } else {
3114 return CreateConfigurationProfileSigner(false);
3115 }
3116 }
3117
3118 SecPolicyRef SecPolicyCreateOSXProvisioningProfileSigning(void)
3119 {
3120 SecPolicyRef result = NULL;
3121 CFMutableDictionaryRef options = NULL;
3122 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
3123 &kCFTypeDictionaryKeyCallBacks,
3124 &kCFTypeDictionaryValueCallBacks), errOut);
3125 // Require valid chain from the Apple root
3126 SecPolicyAddBasicX509Options(options);
3127 SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameAppleOSXProvisioningProfileSigning);
3128
3129 // Require provisioning profile leaf marker OID (1.2.840.113635.100.4.11)
3130 add_leaf_marker(options, &oidAppleCertExtOSXProvisioningProfileSigning);
3131
3132 // Require intermediate marker OID (1.2.840.113635.100.6.2.1)
3133 add_oid(options, kSecPolicyCheckIntermediateMarkerOid, &oidAppleIntmMarkerAppleWWDR);
3134
3135 // Require key usage that allows signing
3136 add_ku(options, kSecKeyUsageDigitalSignature);
3137
3138 // Ensure that revocation is checked (OCSP)
3139 CFDictionaryAddValue(options, kSecPolicyCheckRevocation, kSecPolicyCheckRevocationOCSP);
3140
3141 require(result = SecPolicyCreate(kSecPolicyAppleOSXProvisioningProfileSigning,
3142 kSecPolicyNameAppleOSXProvisioningProfileSigning, options), errOut);
3143
3144 errOut:
3145 CFReleaseSafe(options);
3146 return result;
3147 }
3148
3149
3150 SecPolicyRef SecPolicyCreateOTAPKISigner(void)
3151 {
3152 SecPolicyRef result = NULL;
3153 CFMutableDictionaryRef options = NULL;
3154 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
3155 &kCFTypeDictionaryKeyCallBacks,
3156 &kCFTypeDictionaryValueCallBacks), errOut);
3157 SecPolicyAddBasicX509Options(options);
3158
3159 SecPolicyAddAnchorSHA1Options(options, kApplePKISettingsAuthority);
3160 require(SecPolicyAddChainLengthOptions(options, 2), errOut);
3161
3162 require(result = SecPolicyCreate(kSecPolicyAppleOTAPKISigner,
3163 kSecPolicyNameAppleOTAPKIAssetSigner, options), errOut);
3164
3165 errOut:
3166 CFReleaseSafe(options);
3167 return result;
3168
3169 }
3170
3171
3172 SecPolicyRef SecPolicyCreateTestOTAPKISigner(void)
3173 {
3174 /* Guard against use on production devices */
3175 if (!SecIsInternalRelease()) {
3176 return SecPolicyCreateOTAPKISigner();
3177 }
3178
3179 SecPolicyRef result = NULL;
3180 CFMutableDictionaryRef options = NULL;
3181 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
3182 &kCFTypeDictionaryKeyCallBacks,
3183 &kCFTypeDictionaryValueCallBacks), errOut);
3184 SecPolicyAddBasicX509Options(options);
3185
3186 SecPolicyAddAnchorSHA1Options(options, kAppleTestPKISettingsAuthority);
3187 require(SecPolicyAddChainLengthOptions(options, 2), errOut);
3188
3189 require(result = SecPolicyCreate(kSecPolicyAppleTestOTAPKISigner,
3190 kSecPolicyNameAppleTestOTAPKIAssetSigner, options), errOut);
3191
3192 errOut:
3193 CFReleaseSafe(options);
3194 return result;
3195 }
3196
3197 /*!
3198 @function SecPolicyCreateAppleSMPEncryption
3199 @abstract Check for intermediate certificate 'Apple System Integration CA - G3' by name,
3200 and root certificate 'Apple Root CA - G3' by hash.
3201 Leaf cert must have Key Encipherment usage.
3202 Leaf cert must have Apple SMP Encryption marker OID (1.2.840.113635.100.6.30).
3203 Intermediate must have marker OID (1.2.840.113635.100.6.2.13).
3204 */
3205 SecPolicyRef SecPolicyCreateAppleSMPEncryption(void)
3206 {
3207 SecPolicyRef result = NULL;
3208 CFMutableDictionaryRef options = NULL;
3209 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
3210 &kCFTypeDictionaryKeyCallBacks,
3211 &kCFTypeDictionaryValueCallBacks), errOut);
3212 SecPolicyAddBasicCertOptions(options);
3213
3214 require(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameAppleSMPEncryption),
3215 errOut);
3216 require(SecPolicyAddChainLengthOptions(options, 3), errOut);
3217
3218 CFDictionaryAddValue(options, kSecPolicyCheckIssuerCommonName,
3219 CFSTR("Apple System Integration CA - G3"));
3220
3221 // Check that leaf has extension with "Apple SMP Encryption" oid (1.2.840.113635.100.6.30)
3222 add_leaf_marker(options, &oidAppleCertExtAppleSMPEncryption);
3223
3224 // Check that intermediate has extension (1.2.840.113635.100.6.2.13)
3225 add_oid(options, kSecPolicyCheckIntermediateMarkerOid, &oidAppleIntmMarkerAppleSystemIntgG3);
3226
3227 add_ku(options, kSecKeyUsageKeyEncipherment);
3228
3229 // Ensure that revocation is checked (OCSP)
3230 CFDictionaryAddValue(options, kSecPolicyCheckRevocation, kSecPolicyCheckRevocationOCSP);
3231
3232 require(result = SecPolicyCreate(kSecPolicyAppleSMPEncryption,
3233 kSecPolicyNameAppleSMPEncryption, options), errOut);
3234
3235 errOut:
3236 CFReleaseSafe(options);
3237 return result;
3238 }
3239
3240 /*!
3241 @function SecPolicyCreateTestAppleSMPEncryption
3242 @abstract Check for intermediate certificate 'Test Apple System Integration CA - ECC' by name,
3243 and root certificate 'Test Apple Root CA - ECC' by hash.
3244 Leaf cert must have Key Encipherment usage. Other checks TBD.
3245 */
3246 SecPolicyRef SecPolicyCreateTestAppleSMPEncryption(void)
3247 {
3248 SecPolicyRef result = NULL;
3249 CFMutableDictionaryRef options = NULL;
3250 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
3251 &kCFTypeDictionaryKeyCallBacks,
3252 &kCFTypeDictionaryValueCallBacks), errOut);
3253 SecPolicyAddBasicCertOptions(options);
3254
3255 SecPolicyAddAnchorSHA1Options(options, kTestAppleRootCA_ECC_SHA1);
3256 require(SecPolicyAddChainLengthOptions(options, 3), errOut);
3257
3258 CFDictionaryAddValue(options, kSecPolicyCheckIssuerCommonName,
3259 CFSTR("Test Apple System Integration CA - ECC"));
3260
3261 add_ku(options, kSecKeyUsageKeyEncipherment);
3262
3263 // Ensure that revocation is checked (OCSP)
3264 CFDictionaryAddValue(options, kSecPolicyCheckRevocation, kSecPolicyCheckRevocationOCSP);
3265
3266 require(result = SecPolicyCreate(kSecPolicyAppleTestSMPEncryption,
3267 kSecPolicyNameAppleTestSMPEncryption, options), errOut);
3268
3269 errOut:
3270 CFReleaseSafe(options);
3271 return result;
3272 }
3273
3274
3275 SecPolicyRef SecPolicyCreateAppleIDValidationRecordSigningPolicy(void)
3276 {
3277 SecPolicyRef result = NULL;
3278 CFMutableDictionaryRef options = NULL;
3279 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
3280 &kCFTypeDictionaryKeyCallBacks,
3281 &kCFTypeDictionaryValueCallBacks), errOut);
3282
3283 //Leaf appears to be a SSL only cert, so policy should expand on that policy
3284 SecPolicyAddBasicX509Options(options);
3285
3286 // Apple CA anchored
3287 require(SecPolicyAddAppleAnchorOptions(options,
3288 kSecPolicyNameAppleIDValidationRecordSigningPolicy),
3289 errOut);
3290
3291 // Check for an extension with " Apple ID Validation Record Signing" oid (1.2.840.113635.100.6.25)
3292 add_leaf_marker(options, &oidAppleCertExtensionAppleIDRecordValidationSigning);
3293
3294 // and validate that intermediate has extension
3295 // Application Integration Intermediate Certificate (1.2.840.113635.100.6.2.3)
3296 // and also validate that intermediate has extension
3297 // System Integration 2 Intermediate Certificate (1.2.840.113635.100.6.2.10)
3298 add_oid(options, kSecPolicyCheckIntermediateMarkerOid, &oidAppleIntmMarkerAppleID);
3299 add_oid(options, kSecPolicyCheckIntermediateMarkerOid, &oidAppleIntmMarkerAppleSystemIntg2);
3300
3301 // Ensure that revocation is checked (OCSP)
3302 CFDictionaryAddValue(options, kSecPolicyCheckRevocation, kSecPolicyCheckRevocationOCSP);
3303
3304 require(result = SecPolicyCreate(kSecPolicyAppleIDValidationRecordSigning,
3305 kSecPolicyNameAppleIDValidationRecordSigningPolicy, options), errOut);
3306
3307 errOut:
3308 CFReleaseSafe(options);
3309 return result;
3310 }
3311
3312 static bool
3313 allowUATRoot(CFStringRef service, CFDictionaryRef context)
3314 {
3315 bool UATAllowed = false;
3316 CFStringRef setting = NULL;
3317 setting = CFStringCreateWithFormat(NULL, NULL, CFSTR("AppleServerAuthenticationAllowUAT%@"), service);
3318 CFTypeRef value = NULL;
3319 require(setting, fail);
3320
3321 if (context &&
3322 CFDictionaryGetValueIfPresent(context, setting, &value) &&
3323 isBoolean(value) &&
3324 CFBooleanGetValue(value))
3325 {
3326 UATAllowed = true;
3327 }
3328
3329 /* CFPreference for this service */
3330 if (isCFPreferenceInSecurityDomain(setting)) {
3331 UATAllowed = true;
3332 }
3333
3334 if (!UATAllowed) {
3335 secnotice("pinningQA", "could not enable test cert: %@ not true", setting);
3336 } else {
3337 goto fail;
3338 }
3339
3340 /* Generic CFPreference */
3341 if (isCFPreferenceInSecurityDomain(CFSTR("AppleServerAuthenticationAllowUAT"))) {
3342 UATAllowed = true;
3343 } else {
3344 secnotice("pinningQA", "could not enable test hierarchy: AppleServerAuthenticationAllowUAT not true");
3345 }
3346
3347 fail:
3348 CFReleaseNull(setting);
3349 return UATAllowed;
3350 }
3351
3352 /*!
3353 @function SecPolicyCreateAppleServerAuthCommon
3354 @abstract Generic policy for server authentication Sub CAs
3355
3356 Allows control for both if pinning is required at all and if UAT environments should be added
3357 to the trust policy.
3358
3359 No pinning is for developer/QA that needs to use proxy to debug the protocol, while UAT
3360 environment is for QA/internal developer that have no need allow fake servers.
3361
3362 Both the noPinning and allowUAT are gated on that you run on internal hardware.
3363
3364 */
3365
3366 static SecPolicyRef
3367 SecPolicyCreateAppleServerAuthCommon(CFStringRef hostname,
3368 CFDictionaryRef __unused context,
3369 CFStringRef policyOID, CFStringRef service,
3370 const DERItem *leafMarkerOID,
3371 const DERItem *UATLeafMarkerOID)
3372 {
3373 CFMutableDictionaryRef appleAnchorOptions = NULL;
3374 CFMutableDictionaryRef options = NULL;
3375 SecPolicyRef result = NULL;
3376 CFDataRef oid = NULL, uatoid = NULL;
3377
3378 options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
3379 require(options, errOut);
3380
3381 SecPolicyAddBasicX509Options(options);
3382
3383 require(hostname, errOut);
3384 CFDictionaryAddValue(options, kSecPolicyCheckSSLHostname, hostname);
3385
3386 CFDictionaryAddValue(options, kSecPolicyCheckBlackListedLeaf, kCFBooleanTrue);
3387 CFDictionaryAddValue(options, kSecPolicyCheckGrayListedLeaf, kCFBooleanTrue);
3388
3389 add_eku(options, &oidExtendedKeyUsageServerAuth);
3390
3391 if (requireUATPinning(service)) {
3392 bool allowUAT = allowUATRoot(service, context);
3393
3394 /*
3395 * Require pinning to the Apple CA's (and if UAT environment,
3396 * include the Apple Test CA's as anchors).
3397 */
3398 appleAnchorOptions = CFDictionaryCreateMutableForCFTypes(NULL);
3399 require(appleAnchorOptions, errOut);
3400
3401 if (allowUAT || allowTestHierarchyForPolicy(service, true)) {
3402 /* Note: SecPolicyServer won't allow the test roots for non-internal devices */
3403 CFDictionarySetValue(appleAnchorOptions,
3404 kSecPolicyAppleAnchorIncludeTestRoots, kCFBooleanTrue);
3405 }
3406
3407 add_element(options, kSecPolicyCheckAnchorApple, appleAnchorOptions);
3408
3409 /*
3410 * Check if we also should allow the UAT variant of the leafs
3411 * as some variants of the UAT environment uses that instead
3412 * of the test Apple CA's.
3413 */
3414 if (allowUAT && UATLeafMarkerOID) {
3415 add_leaf_prod_qa_markers(options, leafMarkerOID, UATLeafMarkerOID);
3416 } else {
3417 add_leaf_marker(options, leafMarkerOID);
3418 }
3419
3420 /* new-style leaf marker OIDs */
3421 CFStringRef leafMarkerOIDStr = NULL, UATLeafMarkerOIDStr = NULL;
3422 leafMarkerOIDStr = SecDERItemCopyOIDDecimalRepresentation(NULL, leafMarkerOID);
3423 if (UATLeafMarkerOID) {
3424 UATLeafMarkerOIDStr = SecDERItemCopyOIDDecimalRepresentation(NULL, UATLeafMarkerOID);
3425 }
3426
3427 if (allowUAT && leafMarkerOIDStr && UATLeafMarkerOIDStr) {
3428 add_leaf_prod_qa_markers_value_string(options,
3429 CFSTR("1.2.840.113635.100.6.48.1"), leafMarkerOIDStr,
3430 CFSTR("1.2.840.113635.100.6.48.1"), UATLeafMarkerOIDStr);
3431 } else if (leafMarkerOIDStr) {
3432 add_leaf_marker_value_string(options, CFSTR("1.2.840.113635.100.6.48.1"), leafMarkerOIDStr);
3433 }
3434
3435 CFReleaseNull(leafMarkerOIDStr);
3436 CFReleaseNull(UATLeafMarkerOIDStr);
3437
3438 add_oid(options, kSecPolicyCheckIntermediateMarkerOid, &oidAppleIntmMarkerAppleServerAuthentication);
3439 }
3440
3441 /* Check for weak hashes */
3442 CFDictionaryAddValue(options, kSecPolicyCheckSystemTrustedWeakHash, kCFBooleanTrue);
3443
3444 CFDictionaryAddValue(options, kSecPolicyCheckRevocation, kSecPolicyCheckRevocationAny);
3445
3446 result = SecPolicyCreate(policyOID, service, options);
3447 require(result, errOut);
3448
3449 errOut:
3450 CFReleaseSafe(appleAnchorOptions);
3451 CFReleaseSafe(options);
3452 CFReleaseSafe(oid);
3453 CFReleaseSafe(uatoid);
3454 return result;
3455 }
3456
3457 /*!
3458 @function SecPolicyCreateAppleIDSService
3459 @abstract Ensure we're appropriately pinned to the IDS service (SSL + Apple restrictions)
3460 */
3461 SecPolicyRef SecPolicyCreateAppleIDSService(CFStringRef hostname)
3462 {
3463 SecPolicyRef result = SecPolicyCreateSSL(true, hostname);
3464
3465 SecPolicySetOid(result, kSecPolicyAppleIDSService);
3466 SecPolicySetName(result, kSecPolicyNameAppleIDSServiceContext);
3467
3468 return result;
3469 }
3470
3471 /*!
3472 @function SecPolicyCreateAppleIDSService
3473 @abstract Ensure we're appropriately pinned to the IDS service (SSL + Apple restrictions)
3474 */
3475 SecPolicyRef SecPolicyCreateAppleIDSServiceContext(CFStringRef hostname, CFDictionaryRef context)
3476 {
3477 return SecPolicyCreateAppleServerAuthCommon(hostname, context, kSecPolicyAppleIDSServiceContext,
3478 kSecPolicyNameAppleIDSServiceContext,
3479 &oidAppleCertExtAppleServerAuthenticationIDSProd,
3480 &oidAppleCertExtAppleServerAuthenticationIDSProdQA);
3481 }
3482
3483 /*!
3484 @function SecPolicyCreateAppleGSService
3485 @abstract Ensure we're appropriately pinned to the GS service
3486 */
3487 SecPolicyRef SecPolicyCreateAppleGSService(CFStringRef hostname, CFDictionaryRef context)
3488 {
3489 return SecPolicyCreateAppleServerAuthCommon(hostname, context, kSecPolicyAppleGSService,
3490 kSecPolicyNameAppleGSService,
3491 &oidAppleCertExtAppleServerAuthenticationGS,
3492 NULL);
3493 }
3494
3495 /*!
3496 @function SecPolicyCreateApplePushService
3497 @abstract Ensure we're appropriately pinned to the Push service (SSL + Apple restrictions)
3498 */
3499 SecPolicyRef SecPolicyCreateApplePushService(CFStringRef hostname, CFDictionaryRef context)
3500 {
3501 return SecPolicyCreateAppleServerAuthCommon(hostname, context, kSecPolicyApplePushService,
3502 kSecPolicyNameApplePushService,
3503 &oidAppleCertExtAppleServerAuthenticationAPNProd,
3504 &oidAppleCertExtAppleServerAuthenticationAPNProdQA);
3505 }
3506
3507 /*!
3508 @function SecPolicyCreateApplePPQService
3509 @abstract Ensure we're appropriately pinned to the PPQ service (SSL + Apple restrictions)
3510 */
3511 SecPolicyRef SecPolicyCreateApplePPQService(CFStringRef hostname, CFDictionaryRef context)
3512 {
3513 return SecPolicyCreateAppleServerAuthCommon(hostname, context, kSecPolicyApplePPQService,
3514 kSecPolicyNameApplePPQService,
3515 &oidAppleCertExtAppleServerAuthenticationPPQProd ,
3516 &oidAppleCertExtAppleServerAuthenticationPPQProdQA);
3517 }
3518
3519 /*!
3520 @function SecPolicyCreateAppleAST2Service
3521 @abstract Ensure we're appropriately pinned to the AST2 Diagnostic service (SSL + Apple restrictions)
3522 */
3523 SecPolicyRef SecPolicyCreateAppleAST2Service(CFStringRef hostname, CFDictionaryRef context)
3524 {
3525 return SecPolicyCreateAppleServerAuthCommon(hostname, context, kSecPolicyAppleAST2DiagnosticsServerAuth,
3526 kSecPolicyNameAppleAST2Service,
3527 &oidAppleCertExtAST2DiagnosticsServerAuthProd,
3528 &oidAppleCertExtAST2DiagnosticsServerAuthProdQA);
3529 }
3530
3531 /*!
3532 @function SecPolicyCreateAppleEscrowProxyService
3533 @abstract Ensure we're appropriately pinned to the iCloud Escrow Proxy service (SSL + Apple restrictions)
3534 */
3535 SecPolicyRef SecPolicyCreateAppleEscrowProxyService(CFStringRef hostname, CFDictionaryRef context)
3536 {
3537 return SecPolicyCreateAppleServerAuthCommon(hostname, context, kSecPolicyAppleEscrowProxyServerAuth,
3538 kSecPolicyNameAppleEscrowProxyService,
3539 &oidAppleCertExtEscrowProxyServerAuthProd,
3540 &oidAppleCertExtEscrowProxyServerAuthProdQA);
3541 }
3542
3543 /* subject:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA */
3544 /* SKID: C0:7A:98:68:8D:89:FB:AB:05:64:0C:11:7D:AA:7D:65:B8:CA:CC:4E */
3545 /* Not Before: May 21 04:00:00 2002 GMT, Not After : May 21 04:00:00 2022 GMT */
3546 /* Signature Algorithm: sha1WithRSAEncryption */
3547 unsigned char GeoTrust_Global_CA_sha256[kSecPolicySHA256Size] = {
3548 0xff, 0x85, 0x6a, 0x2d, 0x25, 0x1d, 0xcd, 0x88, 0xd3, 0x66, 0x56, 0xf4, 0x50, 0x12, 0x67, 0x98,
3549 0xcf, 0xab, 0xaa, 0xde, 0x40, 0x79, 0x9c, 0x72, 0x2d, 0xe4, 0xd2, 0xb5, 0xdb, 0x36, 0xa7, 0x3a
3550 };
3551
3552 static SecPolicyRef SecPolicyCreateAppleGeoTrustServerAuthCommon(CFStringRef hostname, CFStringRef policyOid,
3553 CFStringRef policyName,
3554 CFStringRef leafMarkerOid,
3555 CFStringRef qaLeafMarkerOid) {
3556 CFMutableDictionaryRef options = NULL;
3557 CFDataRef spkiDigest = NULL;
3558 SecPolicyRef result = NULL;
3559
3560 require(options = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks,
3561 &kCFTypeDictionaryValueCallBacks), errOut);
3562
3563 /* basic SSL */
3564 SecPolicyAddBasicX509Options(options);
3565
3566 require(hostname, errOut);
3567 CFDictionaryAddValue(options, kSecPolicyCheckSSLHostname, hostname);
3568
3569 add_eku(options, &oidExtendedKeyUsageServerAuth);
3570
3571 /* pinning */
3572 if (requireUATPinning(policyName)) {
3573 /* GeoTrust root */
3574 SecPolicyAddAnchorSHA256Options(options, GeoTrust_Global_CA_sha256);
3575
3576 /* Issued to Apple Inc. in the US */
3577 add_element(options, kSecPolicyCheckIntermediateCountry, CFSTR("US"));
3578 add_element(options, kSecPolicyCheckIntermediateOrganization, CFSTR("Apple Inc."));
3579
3580 require_action(SecPolicyAddChainLengthOptions(options, 3), errOut, CFReleaseNull(result));
3581
3582 /* Marker OIDs in both formats */
3583 if (qaLeafMarkerOid && allowUATRoot(policyName, NULL)) {
3584 add_leaf_prod_qa_markers_string(options, leafMarkerOid, qaLeafMarkerOid);
3585 add_leaf_prod_qa_markers_value_string(options,
3586 CFSTR("1.2.840.113635.100.6.48.1"), leafMarkerOid,
3587 CFSTR("1.2.840.113635.100.6.48.1"), qaLeafMarkerOid);
3588 } else {
3589 add_leaf_marker_string(options, leafMarkerOid);
3590 add_leaf_marker_value_string(options, CFSTR("1.2.840.113635.100.6.48.1"), leafMarkerOid);
3591 }
3592 }
3593
3594 /* Check for weak hashes */
3595 CFDictionaryAddValue(options, kSecPolicyCheckSystemTrustedWeakHash, kCFBooleanTrue);
3596
3597 /* See <rdar://25344801> for more details */
3598
3599 result = SecPolicyCreate(policyOid, policyName, options);
3600
3601 errOut:
3602 CFReleaseSafe(options);
3603 CFReleaseSafe(spkiDigest);
3604 return result;
3605 }
3606
3607 SecPolicyRef SecPolicyCreateAppleCompatibilityEscrowProxyService(CFStringRef hostname) {
3608 return SecPolicyCreateAppleGeoTrustServerAuthCommon(hostname, kSecPolicyAppleEscrowProxyCompatibilityServerAuth,
3609 kSecPolicyNameAppleEscrowProxyService,
3610 CFSTR("1.2.840.113635.100.6.27.7.2"),
3611 CFSTR("1.2.840.113635.100.6.27.7.1"));
3612 }
3613
3614 /*!
3615 @function SecPolicyCreateAppleFMiPService
3616 @abstract Ensure we're appropriately pinned to the Find My iPhone service (SSL + Apple restrictions)
3617 */
3618 SecPolicyRef SecPolicyCreateAppleFMiPService(CFStringRef hostname, CFDictionaryRef context)
3619 {
3620 return SecPolicyCreateAppleServerAuthCommon(hostname, context, kSecPolicyAppleFMiPServerAuth,
3621 kSecPolicyNameAppleFMiPService,
3622 &oidAppleCertExtFMiPServerAuthProd,
3623 &oidAppleCertExtFMiPServerAuthProdQA);
3624 }
3625
3626
3627 /* should use verbatim copy, but since this is the deprecated way, don't care right now */
3628 static const UInt8 entrustSPKIL1C[kSecPolicySHA256Size] = {
3629 0x54, 0x5b, 0xf9, 0x35, 0xe9, 0xad, 0xa1, 0xda,
3630 0x11, 0x7e, 0xdc, 0x3c, 0x2a, 0xcb, 0xc5, 0x6f,
3631 0xc0, 0x28, 0x09, 0x6c, 0x0e, 0x24, 0xbe, 0x9b,
3632 0x38, 0x94, 0xbe, 0x52, 0x2d, 0x1b, 0x43, 0xde
3633 };
3634
3635 /*!
3636 @function SecPolicyCreateApplePushServiceLegacy
3637 @abstract Ensure we're appropriately pinned to the Push service (via Entrust)
3638 */
3639 SecPolicyRef SecPolicyCreateApplePushServiceLegacy(CFStringRef hostname)
3640 {
3641 CFMutableDictionaryRef options = NULL;
3642 SecPolicyRef result = NULL;
3643 CFDataRef digest = NULL;
3644
3645 digest = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, entrustSPKIL1C, sizeof(entrustSPKIL1C), kCFAllocatorNull);
3646 require(digest, errOut);
3647
3648 options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
3649 require(options, errOut);
3650
3651 SecPolicyAddBasicX509Options(options);
3652
3653 CFDictionaryAddValue(options, kSecPolicyCheckSSLHostname, hostname);
3654
3655 CFDictionaryAddValue(options, kSecPolicyCheckBlackListedLeaf, kCFBooleanTrue);
3656 CFDictionaryAddValue(options, kSecPolicyCheckGrayListedLeaf, kCFBooleanTrue);
3657
3658 CFDictionaryAddValue(options, kSecPolicyCheckIntermediateSPKISHA256, digest);
3659
3660 add_eku(options, &oidExtendedKeyUsageServerAuth);
3661
3662 CFDictionaryAddValue(options, kSecPolicyCheckRevocation, kSecPolicyCheckRevocationAny);
3663
3664 result = SecPolicyCreate(kSecPolicyAppleLegacyPushService,
3665 kSecPolicyNameAppleLegacyPushService, options);
3666 require(result, errOut);
3667
3668 errOut:
3669 CFReleaseSafe(digest);
3670 CFReleaseSafe(options);
3671 return result;
3672 }
3673
3674 /*!
3675 @function SecPolicyCreateAppleMMCSService
3676 @abstract Ensure we're appropriately pinned to the IDS service (SSL + Apple restrictions)
3677 */
3678 SecPolicyRef SecPolicyCreateAppleMMCSService(CFStringRef hostname, CFDictionaryRef context)
3679 {
3680 return SecPolicyCreateAppleServerAuthCommon(hostname, context, kSecPolicyAppleMMCSService,
3681 kSecPolicyNameAppleMMCSService,
3682 &oidAppleCertExtAppleServerAuthenticationMMCSProd,
3683 &oidAppleCertExtAppleServerAuthenticationMMCSProdQA);
3684 }
3685
3686 SecPolicyRef SecPolicyCreateAppleCompatibilityMMCSService(CFStringRef hostname) {
3687 return SecPolicyCreateAppleGeoTrustServerAuthCommon(hostname, kSecPolicyAppleMMCSCompatibilityServerAuth,
3688 kSecPolicyNameAppleMMCSService,
3689 CFSTR("1.2.840.113635.100.6.27.11.2"),
3690 CFSTR("1.2.840.113635.100.6.27.11.1"));
3691 }
3692
3693
3694 SecPolicyRef SecPolicyCreateAppleiCloudSetupService(CFStringRef hostname, CFDictionaryRef context)
3695 {
3696 return SecPolicyCreateAppleServerAuthCommon(hostname, context, kSecPolicyAppleiCloudSetupServerAuth,
3697 kSecPolicyNameAppleiCloudSetupService,
3698 &oidAppleCertExtAppleServerAuthenticationiCloudSetupProd,
3699 &oidAppleCertExtAppleServerAuthenticationiCloudSetupProdQA);
3700 }
3701
3702 SecPolicyRef SecPolicyCreateAppleCompatibilityiCloudSetupService(CFStringRef hostname)
3703 {
3704 return SecPolicyCreateAppleGeoTrustServerAuthCommon(hostname, kSecPolicyAppleiCloudSetupCompatibilityServerAuth,
3705 kSecPolicyNameAppleiCloudSetupService,
3706 CFSTR("1.2.840.113635.100.6.27.15.2"),
3707 CFSTR("1.2.840.113635.100.6.27.15.1"));
3708 }
3709
3710 /*!
3711 @function SecPolicyCreateAppleSSLService
3712 @abstract Ensure we're appropriately pinned to an Apple server (SSL + Apple restrictions)
3713 */
3714 SecPolicyRef SecPolicyCreateAppleSSLService(CFStringRef hostname)
3715 {
3716 // SSL server, pinned to an Apple intermediate
3717 SecPolicyRef policy = SecPolicyCreateSSL(true, hostname);
3718 CFMutableDictionaryRef options = NULL;
3719 require(policy, errOut);
3720
3721 // change options for SSL policy evaluation
3722 require((options=(CFMutableDictionaryRef)policy->_options) != NULL, errOut);
3723
3724 // Apple CA anchored
3725 require(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameAppleSSLService), errOut);
3726
3727 // Check leaf for Apple Server Authentication marker oid (1.2.840.113635.100.6.27.1)
3728 add_leaf_marker(options, &oidAppleCertExtAppleServerAuthentication);
3729
3730 // Check intermediate for Apple Server Authentication intermediate marker (1.2.840.113635.100.6.2.12)
3731 add_oid(options, kSecPolicyCheckIntermediateMarkerOid, &oidAppleIntmMarkerAppleServerAuthentication);
3732
3733 /* Check for weak hashes */
3734 CFDictionaryAddValue(options, kSecPolicyCheckSystemTrustedWeakHash, kCFBooleanTrue);
3735
3736 CFDictionaryAddValue(options, kSecPolicyCheckRevocation, kSecPolicyCheckRevocationAny);
3737
3738 SecPolicySetOid(policy, kSecPolicyAppleServerAuthentication);
3739 SecPolicySetName(policy, kSecPolicyNameAppleSSLService);
3740
3741 return policy;
3742
3743 errOut:
3744 CFReleaseSafe(options);
3745 CFReleaseSafe(policy);
3746 return NULL;
3747 }
3748
3749 /*!
3750 @function SecPolicyCreateApplePPQSigning
3751 @abstract Check for intermediate certificate 'Apple System Integration 2 Certification Authority' by name,
3752 and apple anchor.
3753 Leaf cert must have Digital Signature usage.
3754 Leaf cert must have Apple PPQ Signing marker OID (1.2.840.113635.100.6.38.2).
3755 Intermediate must have marker OID (1.2.840.113635.100.6.2.10).
3756 */
3757 SecPolicyRef SecPolicyCreateApplePPQSigning(void)
3758 {
3759 SecPolicyRef result = NULL;
3760 CFMutableDictionaryRef options = NULL;
3761 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
3762 &kCFTypeDictionaryKeyCallBacks,
3763 &kCFTypeDictionaryValueCallBacks), errOut);
3764 SecPolicyAddBasicCertOptions(options);
3765
3766 SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameApplePPQSigning);
3767 require(SecPolicyAddChainLengthOptions(options, 3), errOut);
3768
3769 CFDictionaryAddValue(options, kSecPolicyCheckIssuerCommonName,
3770 CFSTR("Apple System Integration 2 Certification Authority"));
3771
3772 // Check that leaf has extension with "Apple PPQ Signing" prod oid (1.2.840.113635.100.6.38.2)
3773 add_leaf_marker(options, &oidAppleCertExtApplePPQSigningProd);
3774
3775 // Check that intermediate has extension (1.2.840.113635.100.6.2.10)
3776 add_oid(options, kSecPolicyCheckIntermediateMarkerOid, &oidAppleIntmMarkerAppleSystemIntg2);
3777
3778 add_ku(options, kSecKeyUsageDigitalSignature);
3779
3780 require(result = SecPolicyCreate(kSecPolicyApplePPQSigning,
3781 kSecPolicyNameApplePPQSigning, options), errOut);
3782
3783 errOut:
3784 CFReleaseSafe(options);
3785 return result;
3786 }
3787
3788 /*!
3789 @function SecPolicyCreateTestApplePPQSigning
3790 @abstract Check for intermediate certificate 'Apple System Integration 2 Certification Authority' by name,
3791 and apple anchor.
3792 Leaf cert must have Digital Signature usage.
3793 Leaf cert must have Apple PPQ Signing Test marker OID (1.2.840.113635.100.6.38.1).
3794 Intermediate must have marker OID (1.2.840.113635.100.6.2.10).
3795 */
3796 SecPolicyRef SecPolicyCreateTestApplePPQSigning(void)
3797 {
3798 /* Guard against use of test policy on production devices */
3799 if (!SecIsInternalRelease()) {
3800 return SecPolicyCreateApplePPQSigning();
3801 }
3802
3803 SecPolicyRef result = NULL;
3804 CFMutableDictionaryRef options = NULL;
3805 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
3806 &kCFTypeDictionaryKeyCallBacks,
3807 &kCFTypeDictionaryValueCallBacks), errOut);
3808 SecPolicyAddBasicCertOptions(options);
3809
3810 SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameAppleTestPPQSigning);
3811 require(SecPolicyAddChainLengthOptions(options, 3), errOut);
3812
3813 CFDictionaryAddValue(options, kSecPolicyCheckIssuerCommonName,
3814 CFSTR("Apple System Integration 2 Certification Authority"));
3815
3816 // Check that leaf has extension with "Apple PPQ Signing" test oid (1.2.840.113635.100.6.38.1)
3817 add_leaf_marker(options, &oidAppleCertExtApplePPQSigningProdQA);
3818
3819 // Check that intermediate has extension (1.2.840.113635.100.6.2.10)
3820 add_oid(options, kSecPolicyCheckIntermediateMarkerOid, &oidAppleIntmMarkerAppleSystemIntg2);
3821
3822 add_ku(options, kSecKeyUsageDigitalSignature);
3823
3824 require(result = SecPolicyCreate(kSecPolicyAppleTestPPQSigning,
3825 kSecPolicyNameAppleTestPPQSigning, options), errOut);
3826
3827 errOut:
3828 CFReleaseSafe(options);
3829 return result;
3830 }
3831 /*!
3832 @function SecPolicyCreateAppleTimeStamping
3833 @abstract Check for RFC3161 timestamping EKU.
3834 */
3835 SecPolicyRef SecPolicyCreateAppleTimeStamping(void)
3836 {
3837 SecPolicyRef result = NULL;
3838 CFMutableDictionaryRef options = NULL;
3839 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
3840 &kCFTypeDictionaryKeyCallBacks,
3841 &kCFTypeDictionaryValueCallBacks), errOut);
3842
3843 SecPolicyAddBasicX509Options(options);
3844
3845 /* Require id-kp-timeStamping extendedKeyUsage to be present. */
3846 add_eku(options, &oidExtendedKeyUsageTimeStamping);
3847
3848 require(result = SecPolicyCreate(kSecPolicyAppleTimeStamping,
3849 kSecPolicyNameAppleTimeStamping, options), errOut);
3850
3851 errOut:
3852 CFReleaseSafe(options);
3853 return result;
3854 }
3855
3856 /*!
3857 @function SecPolicyCreateApplePayIssuerEncryption
3858 @abstract Check for intermediate certificate 'Apple Worldwide Developer Relations CA - G2' by name,
3859 and ECC apple anchor.
3860 Leaf cert must have Key Encipherment and Key Agreement usage.
3861 Leaf cert must have Apple Pay Issuer Encryption marker OID (1.2.840.113635.100.6.39).
3862 */
3863 SecPolicyRef SecPolicyCreateApplePayIssuerEncryption(void)
3864 {
3865 SecPolicyRef result = NULL;
3866 CFMutableDictionaryRef options = NULL;
3867 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
3868 &kCFTypeDictionaryKeyCallBacks,
3869 &kCFTypeDictionaryValueCallBacks), errOut);
3870 SecPolicyAddBasicCertOptions(options);
3871
3872 require(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameApplePayIssuerEncryption),
3873 errOut);
3874 require(SecPolicyAddChainLengthOptions(options, 3), errOut);
3875
3876 CFDictionaryAddValue(options, kSecPolicyCheckIssuerCommonName,
3877 CFSTR("Apple Worldwide Developer Relations CA - G2"));
3878
3879 // Check that leaf has extension with "Apple Pay Issuer Encryption" oid (1.2.840.113635.100.6.39)
3880 add_leaf_marker(options, &oidAppleCertExtCryptoServicesExtEncryption);
3881
3882 add_ku(options, kSecKeyUsageKeyEncipherment);
3883
3884 require(result = SecPolicyCreate(kSecPolicyApplePayIssuerEncryption,
3885 kSecPolicyNameApplePayIssuerEncryption, options), errOut);
3886
3887 errOut:
3888 CFReleaseSafe(options);
3889 return result;
3890 }
3891
3892 /*!
3893 @function SecPolicyCreateAppleATVVPNProfileSigning
3894 @abstract Check for leaf marker OID 1.2.840.113635.100.6.43,
3895 intermediate marker OID 1.2.840.113635.100.6.2.10,
3896 chains to Apple Root CA, path length 3
3897 */
3898 SecPolicyRef SecPolicyCreateAppleATVVPNProfileSigning(void)
3899 {
3900 SecPolicyRef result = NULL;
3901 CFMutableDictionaryRef options = NULL;
3902 CFMutableDictionaryRef appleAnchorOptions = NULL;
3903 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
3904 &kCFTypeDictionaryKeyCallBacks,
3905 &kCFTypeDictionaryValueCallBacks), errOut);
3906
3907 SecPolicyAddBasicCertOptions(options);
3908
3909 // Require pinning to the Apple CAs (including test CA for internal releases)
3910 appleAnchorOptions = CFDictionaryCreateMutableForCFTypes(NULL);
3911 require(appleAnchorOptions, errOut);
3912
3913 if (SecIsInternalRelease()) {
3914 CFDictionarySetValue(appleAnchorOptions,
3915 kSecPolicyAppleAnchorIncludeTestRoots, kCFBooleanTrue);
3916 }
3917
3918 add_element(options, kSecPolicyCheckAnchorApple, appleAnchorOptions);
3919
3920 // Cert chain length 3
3921 require(SecPolicyAddChainLengthOptions(options, 3), errOut);
3922
3923 // Check leaf for Apple ATV VPN Profile Signing OID (1.2.840.113635.100.6.43)
3924 add_leaf_marker(options, &oidAppleCertExtATVVPNProfileSigning);
3925
3926 // Check intermediate for Apple System Integration 2 CA intermediate marker (1.2.840.113635.100.6.2.10)
3927 add_oid(options, kSecPolicyCheckIntermediateMarkerOid, &oidAppleIntmMarkerAppleSystemIntg2);
3928
3929 // Ensure that revocation is checked (OCSP only)
3930 CFDictionaryAddValue(options, kSecPolicyCheckRevocation, kSecPolicyCheckRevocationOCSP);
3931
3932 require(result = SecPolicyCreate(kSecPolicyAppleATVVPNProfileSigning,
3933 kSecPolicyNameAppleATVVPNProfileSigning, options), errOut);
3934
3935 errOut:
3936 CFReleaseSafe(options);
3937 CFReleaseSafe(appleAnchorOptions);
3938 return result;
3939 }
3940
3941 SecPolicyRef SecPolicyCreateAppleHomeKitServerAuth(CFStringRef hostname) {
3942 CFMutableDictionaryRef appleAnchorOptions = NULL;
3943 CFMutableDictionaryRef options = NULL;
3944 SecPolicyRef result = NULL;
3945 CFDataRef oid = NULL;
3946
3947 options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
3948 require(options, errOut);
3949
3950 SecPolicyAddBasicX509Options(options);
3951
3952 CFDictionaryAddValue(options, kSecPolicyCheckSSLHostname, hostname);
3953
3954 add_eku(options, &oidExtendedKeyUsageServerAuth);
3955
3956 if (requireUATPinning(kSecPolicyNameAppleHomeKitServerAuth)) {
3957 bool allowUAT = allowUATRoot(kSecPolicyNameAppleHomeKitServerAuth, NULL);
3958
3959 // Cert chain length 3
3960 require(SecPolicyAddChainLengthOptions(options, 3), errOut);
3961
3962 // Apple anchors, allowing test anchors for internal releases properly configured
3963 appleAnchorOptions = CFDictionaryCreateMutableForCFTypes(NULL);
3964 require(appleAnchorOptions, errOut);
3965 if (allowUAT || allowTestHierarchyForPolicy(kSecPolicyNameAppleHomeKitServerAuth, true)) {
3966 CFDictionarySetValue(appleAnchorOptions,
3967 kSecPolicyAppleAnchorIncludeTestRoots, kCFBooleanTrue);
3968 }
3969 add_element(options, kSecPolicyCheckAnchorApple, appleAnchorOptions);
3970
3971 add_leaf_marker(options, &oidAppleCertExtHomeKitServerAuth);
3972
3973 add_oid(options, kSecPolicyCheckIntermediateMarkerOid, &oidAppleIntmMarkerAppleHomeKitServerCA);
3974 }
3975
3976 /* Check for weak hashes */
3977 CFDictionaryAddValue(options, kSecPolicyCheckSystemTrustedWeakHash, kCFBooleanTrue);
3978
3979 CFDictionaryAddValue(options, kSecPolicyCheckRevocation, kSecPolicyCheckRevocationAny);
3980
3981 result = SecPolicyCreate(kSecPolicyAppleHomeKitServerAuth,
3982 kSecPolicyNameAppleHomeKitServerAuth, options);
3983 require(result, errOut);
3984
3985 errOut:
3986 CFReleaseSafe(appleAnchorOptions);
3987 CFReleaseSafe(options);
3988 CFReleaseSafe(oid);
3989 return result;
3990 }
3991
3992 SecPolicyRef SecPolicyCreateAppleExternalDeveloper(void) {
3993 CFMutableDictionaryRef options = NULL;
3994 SecPolicyRef result = NULL;
3995
3996 /* Create basic Apple pinned policy */
3997 require(result = SecPolicyCreateApplePinned(kSecPolicyNameAppleExternalDeveloper,
3998 CFSTR("1.2.840.113635.100.6.2.1"), // WWDR Intermediate OID
3999 CFSTR("1.2.840.113635.100.6.1.2")), // "iPhone Developer" leaf OID
4000 errOut);
4001
4002 require_action(options = CFDictionaryCreateMutableCopy(NULL, 0, result->_options), errOut, CFReleaseNull(result));
4003
4004 /* Additional intermediate OIDs */
4005 add_element(options, kSecPolicyCheckIntermediateMarkerOid,
4006 CFSTR("1.2.840.113635.100.6.2.6")); // "Developer ID" Intermediate OID
4007
4008 /* Addtional leaf OIDS */
4009 add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.6.1.4")); // "iPhone Distribution" leaf OID
4010 add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.6.1.5")); // "Safari Developer" leaf OID
4011 add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.6.1.7")); // "3rd Party Mac Developer Application" leaf OID
4012 add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.6.1.8")); // "3rd Party Mac Developer Installer" leaf OID
4013 add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.6.1.12")); // "Mac Developer" leaf OID
4014 add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.6.1.13")); // "Developer ID Application" leaf OID
4015 add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.6.1.14")); // "Developer ID Installer" leaf OID
4016
4017 /* Restrict EKUs */
4018 add_eku_string(options, CFSTR("1.3.6.1.5.5.7.3.3")); // CodeSigning EKU
4019 add_eku_string(options, CFSTR("1.2.840.113635.100.4.8")); // "Safari Developer" EKU
4020 add_eku_string(options, CFSTR("1.2.840.113635.100.4.9")); // "3rd Party Mac Developer Installer" EKU
4021 add_eku_string(options, CFSTR("1.2.840.113635.100.4.13")); // "Developer ID Installer" EKU
4022
4023 CFReleaseSafe(result->_options);
4024 result->_options = CFRetainSafe(options);
4025
4026 SecPolicySetOid(result, kSecPolicyAppleExternalDeveloper);
4027
4028 errOut:
4029 CFReleaseSafe(options);
4030 return result;
4031 }
4032
4033 /* This one is special because the intermediate has no marker OID */
4034 SecPolicyRef SecPolicyCreateAppleSoftwareSigning(void) {
4035 CFMutableDictionaryRef options = NULL;
4036 CFDictionaryRef keySizes = NULL;
4037 CFNumberRef rsaSize = NULL, ecSize = NULL;
4038 SecPolicyRef result = NULL;
4039
4040 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
4041 &kCFTypeDictionaryKeyCallBacks,
4042 &kCFTypeDictionaryValueCallBacks), errOut);
4043
4044 SecPolicyAddBasicX509Options(options);
4045
4046 /* Anchored to the Apple Roots */
4047 require_quiet(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameAppleSoftwareSigning),
4048 errOut);
4049
4050 /* Exactly 3 certs in the chain */
4051 require(SecPolicyAddChainLengthOptions(options, 3), errOut);
4052
4053 /* Intermediate Common Name matches */
4054 add_element(options, kSecPolicyCheckIssuerCommonName, CFSTR("Apple Code Signing Certification Authority"));
4055
4056 /* Leaf marker OID matches */
4057 add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.6.22"));
4058
4059 /* Leaf has CodeSigning EKU */
4060 add_eku_string(options, CFSTR("1.3.6.1.5.5.7.3.3"));
4061
4062 /* Check revocation using any available method */
4063 add_element(options, kSecPolicyCheckRevocation, kSecPolicyCheckRevocationAny);
4064
4065 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
4066 require(SecPolicyAddStrongKeySizeOptions(options), errOut);
4067
4068 require(result = SecPolicyCreate(kSecPolicyAppleSoftwareSigning,
4069 kSecPolicyNameAppleSoftwareSigning, options), errOut);
4070
4071 errOut:
4072 CFReleaseSafe(options);
4073 CFReleaseSafe(keySizes);
4074 CFReleaseSafe(rsaSize);
4075 CFReleaseSafe(ecSize);
4076 return result;
4077 }
4078
4079 /* subject:/CN=SEP Root CA/O=Apple Inc./ST=California */
4080 /* SKID: 58:EF:D6:BE:C5:82:B0:54:CD:18:A6:84:AD:A2:F6:7B:7B:3A:7F:CF */
4081 /* Not Before: Jun 24 21:43:24 2014 GMT, Not After : Jun 24 21:43:24 2029 GMT */
4082 /* Signature Algorithm: ecdsa-with-SHA384 */
4083 const uint8_t SEPRootCA_SHA256[kSecPolicySHA256Size] = {
4084 0xd1, 0xdf, 0x82, 0x00, 0xf3, 0x89, 0x4e, 0xe9, 0x96, 0xf3, 0x77, 0xdf, 0x76, 0x3b, 0x0a, 0x16,
4085 0x8f, 0xd9, 0x6c, 0x58, 0xc0, 0x3e, 0xc9, 0xb0, 0x5f, 0xa5, 0x64, 0x79, 0xc0, 0xe8, 0xc9, 0xe7
4086 };
4087
4088 SecPolicyRef SecPolicyCreateAppleUniqueDeviceCertificate(CFDataRef testRootHash) {
4089 CFMutableDictionaryRef options = NULL;
4090 CFDictionaryRef keySizes = NULL;
4091 CFNumberRef ecSize = NULL;
4092 SecPolicyRef result = NULL;
4093
4094 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
4095 &kCFTypeDictionaryKeyCallBacks,
4096 &kCFTypeDictionaryValueCallBacks), errOut);
4097
4098 /* Device certificate should never expire */
4099 SecPolicyAddBasicCertOptions(options);
4100
4101 /* Anchored to the SEP Root CA. Allow alternative root for developers */
4102 require(SecPolicyAddAnchorSHA256Options(options, SEPRootCA_SHA256),errOut);
4103 if (testRootHash && SecIsInternalRelease() &&
4104 allowTestHierarchyForPolicy(kSecPolicyNameAppleUniqueDeviceCertificate, false)
4105 && (kSecPolicySHA256Size == CFDataGetLength(testRootHash))) {
4106 add_element(options, kSecPolicyCheckAnchorSHA256, testRootHash);
4107 }
4108
4109 /* Exactly 3 certs in the chain */
4110 require(SecPolicyAddChainLengthOptions(options, 3), errOut);
4111
4112 /* Intermediate has marker OID with value */
4113 add_intermediate_marker_value_string(options, CFSTR("1.2.840.113635.100.6.44"), CFSTR("ucrt"));
4114
4115 /* Leaf has marker OID with varying value that can't be pre-determined */
4116 add_element(options, kSecPolicyCheckLeafMarkerOidWithoutValueCheck, CFSTR("1.2.840.113635.100.10.1"));
4117
4118 /* RSA key sizes are disallowed. EC key sizes are P-256 or larger. */
4119 require(ecSize = CFNumberCreateWithCFIndex(NULL, 256), errOut);
4120 require(keySizes = CFDictionaryCreate(NULL, (const void**)&kSecAttrKeyTypeEC,
4121 (const void**)&ecSize, 1,
4122 &kCFTypeDictionaryKeyCallBacks,
4123 &kCFTypeDictionaryValueCallBacks), errOut);
4124 add_element(options, kSecPolicyCheckKeySize, keySizes);
4125
4126
4127 require(result = SecPolicyCreate(kSecPolicyAppleUniqueDeviceIdentifierCertificate,
4128 kSecPolicyNameAppleUniqueDeviceCertificate, options), errOut);
4129
4130 errOut:
4131 CFReleaseSafe(options);
4132 CFReleaseSafe(keySizes);
4133 CFReleaseSafe(ecSize);
4134 return result;
4135 }
4136
4137 SecPolicyRef SecPolicyCreateAppleWarsaw(void) {
4138 CFMutableDictionaryRef options = NULL;
4139 CFDictionaryRef keySizes = NULL;
4140 CFNumberRef rsaSize = NULL, ecSize = NULL;
4141 SecPolicyRef result = NULL;
4142 #if TARGET_OS_BRIDGE
4143 CFMutableDictionaryRef appleAnchorOptions = NULL;
4144 #endif
4145
4146 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
4147 &kCFTypeDictionaryKeyCallBacks,
4148 &kCFTypeDictionaryValueCallBacks), errOut);
4149
4150 SecPolicyAddBasicX509Options(options);
4151
4152 /* Anchored to the Apple Roots. */
4153 #if TARGET_OS_BRIDGE
4154 /* On the bridge, test roots are gated in the trust and policy servers. */
4155 require_quiet(appleAnchorOptions = CFDictionaryCreateMutableForCFTypes(NULL), errOut);
4156 CFDictionarySetValue(appleAnchorOptions,
4157 kSecPolicyAppleAnchorIncludeTestRoots, kCFBooleanTrue);
4158 add_element(options, kSecPolicyCheckAnchorApple, appleAnchorOptions);
4159 CFReleaseSafe(appleAnchorOptions);
4160 #else
4161 require_quiet(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameAppleWarsaw),
4162 errOut);
4163 #endif
4164
4165 /* Exactly 3 certs in the chain */
4166 require(SecPolicyAddChainLengthOptions(options, 3), errOut);
4167
4168 /* Intermediate marker OID matches input OID */
4169 add_element(options, kSecPolicyCheckIntermediateMarkerOid, CFSTR("1.2.840.113635.100.6.2.14"));
4170
4171 /* Leaf marker OID matches input OID */
4172 add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.6.29"));
4173
4174 /* Check revocation using any available method */
4175 add_element(options, kSecPolicyCheckRevocation, kSecPolicyCheckRevocationAny);
4176
4177 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
4178 require(SecPolicyAddStrongKeySizeOptions(options), errOut);
4179
4180 require(result = SecPolicyCreate(kSecPolicyAppleWarsaw,
4181 kSecPolicyNameAppleWarsaw, options), errOut);
4182
4183 errOut:
4184 CFReleaseSafe(options);
4185 CFReleaseSafe(keySizes);
4186 CFReleaseSafe(rsaSize);
4187 CFReleaseSafe(ecSize);
4188 return result;
4189 }
4190
4191 SecPolicyRef SecPolicyCreateAppleSecureIOStaticAsset(void) {
4192 CFMutableDictionaryRef options = NULL;
4193 CFDictionaryRef keySizes = NULL;
4194 CFNumberRef rsaSize = NULL, ecSize = NULL;
4195 SecPolicyRef result = NULL;
4196 #if TARGET_OS_BRIDGE
4197 CFMutableDictionaryRef appleAnchorOptions = NULL;
4198 #endif
4199
4200 require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
4201 &kCFTypeDictionaryKeyCallBacks,
4202 &kCFTypeDictionaryValueCallBacks), errOut);
4203
4204 /* This certificate cannot expire so that assets always load */
4205 SecPolicyAddBasicCertOptions(options);
4206
4207 /* Anchored to the Apple Roots. */
4208 #if TARGET_OS_BRIDGE
4209 /* On the bridge, test roots are gated in the trust and policy servers. */
4210 require_quiet(appleAnchorOptions = CFDictionaryCreateMutableForCFTypes(NULL), errOut);
4211 CFDictionarySetValue(appleAnchorOptions,
4212 kSecPolicyAppleAnchorIncludeTestRoots, kCFBooleanTrue);
4213 add_element(options, kSecPolicyCheckAnchorApple, appleAnchorOptions);
4214 CFReleaseSafe(appleAnchorOptions);
4215 #else
4216 require_quiet(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameAppleSecureIOStaticAsset),
4217 errOut);
4218 #endif
4219
4220 /* Exactly 3 certs in the chain */
4221 require(SecPolicyAddChainLengthOptions(options, 3), errOut);
4222
4223 /* Intermediate marker OID matches input OID */
4224 add_element(options, kSecPolicyCheckIntermediateMarkerOid, CFSTR("1.2.840.113635.100.6.2.10"));
4225
4226 /* Leaf marker OID matches input OID */
4227 add_leaf_marker_string(options, CFSTR("1.2.840.113635.100.6.50"));
4228
4229 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
4230 require(SecPolicyAddStrongKeySizeOptions(options), errOut);
4231
4232 require(result = SecPolicyCreate(kSecPolicyAppleSecureIOStaticAsset,
4233 kSecPolicyNameAppleSecureIOStaticAsset, options), errOut);
4234
4235 errOut:
4236 CFReleaseSafe(options);
4237 CFReleaseSafe(keySizes);
4238 CFReleaseSafe(rsaSize);
4239 CFReleaseSafe(ecSize);
4240 return result;
4241 }