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