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