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