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