2 * Copyright (c) 2007-2015 Apple Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
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
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.
21 * @APPLE_LICENSE_HEADER_END@
25 * SecPolicy.c - Implementation of various X.509 certificate trust policies
28 #include <Security/SecPolicyInternal.h>
29 #include <Security/SecPolicyPriv.h>
30 #include <AssertMacros.h>
32 #include <utilities/debugging.h>
33 #include <Security/SecInternal.h>
34 #include <CoreFoundation/CFDictionary.h>
35 #include <CoreFoundation/CFNumber.h>
36 #include <CoreFoundation/CFRuntime.h>
37 #include <CoreFoundation/CFString.h>
38 #include <CoreFoundation/CFTimeZone.h>
39 #include <Security/SecCertificateInternal.h>
40 #include <Security/SecCertificatePriv.h>
41 #include <Security/SecItem.h>
42 #include <libDER/oidsPriv.h>
43 #include <utilities/SecCFError.h>
44 #include <utilities/SecCFWrappers.h>
45 #include <utilities/array_size.h>
46 #include <ipc/securityd_client.h>
47 #if TARGET_OS_EMBEDDED
48 #include <MobileGestalt.h>
50 #include <sys/utsname.h>
53 #include <utilities/SecInternalReleasePriv.h>
55 /********************************************************
56 **************** SecPolicy Constants *******************
57 ********************************************************/
59 // MARK: SecPolicy Constants
61 #define SEC_CONST_DECL(k,v) const CFStringRef k = CFSTR(v);
63 /********************************************************
64 ************** Unverified Leaf Checks ******************
65 ********************************************************/
66 SEC_CONST_DECL (kSecPolicyCheckSSLHostname
, "SSLHostname");
67 SEC_CONST_DECL (kSecPolicyCheckEmail
, "email");
69 /* Checks that the issuer of the leaf has exactly one Common Name and that it
70 matches the specified string. */
71 SEC_CONST_DECL (kSecPolicyCheckIssuerCommonName
, "IssuerCommonName");
73 /* Checks that the leaf has exactly one Common Name and that it
74 matches the specified string. */
75 SEC_CONST_DECL (kSecPolicyCheckSubjectCommonName
, "SubjectCommonName");
77 /* Checks that the leaf has exactly one Common Name and that it has the
78 specified string as a prefix. */
79 SEC_CONST_DECL (kSecPolicyCheckSubjectCommonNamePrefix
, "SubjectCommonNamePrefix");
81 /* Checks that the leaf has exactly one Common Name and that it
82 matches the specified "<string>" or "TEST <string> TEST". */
83 SEC_CONST_DECL (kSecPolicyCheckSubjectCommonNameTEST
, "SubjectCommonNameTEST");
85 /* Checks that the leaf has exactly one Organization and that it
86 matches the specified string. */
87 SEC_CONST_DECL (kSecPolicyCheckSubjectOrganization
, "SubjectOrganization");
89 /* Checks that the leaf has exactly one Organizational Unit and that it
90 matches the specified string. */
91 SEC_CONST_DECL (kSecPolicyCheckSubjectOrganizationalUnit
, "SubjectOrganizationalUnit");
93 /* Check that the leaf is not valid before the specified date (or verifyDate
94 if none is provided?). */
95 SEC_CONST_DECL (kSecPolicyCheckNotValidBefore
, "NotValidBefore");
97 SEC_CONST_DECL (kSecPolicyCheckEAPTrustedServerNames
, "EAPTrustedServerNames");
99 SEC_CONST_DECL (kSecPolicyCheckCertificatePolicy
, "CertificatePolicy");
102 /* Check for basic constraints on leaf to be valid. (rfc5280 check) */
103 SEC_CONST_DECL (kSecPolicyCheckLeafBasicConstraints
, "LeafBasicContraints");
106 /********************************************************
107 *********** Unverified Intermediate Checks *************
108 ********************************************************/
109 SEC_CONST_DECL (kSecPolicyCheckKeyUsage
, "KeyUsage"); /* (rfc5280 check) */
110 SEC_CONST_DECL (kSecPolicyCheckExtendedKeyUsage
, "ExtendedKeyUsage"); /* (rfc5280 check) */
111 SEC_CONST_DECL (kSecPolicyCheckBasicConstraints
, "BasicConstraints"); /* (rfc5280 check) */
112 SEC_CONST_DECL (kSecPolicyCheckQualifiedCertStatements
, "QualifiedCertStatements"); /* (rfc5280 check) */
113 SEC_CONST_DECL (kSecPolicyCheckIntermediateSPKISHA256
, "IntermediateSPKISHA256")
114 SEC_CONST_DECL (kSecPolicyCheckIntermediateEKU
, "IntermediateEKU")
116 /********************************************************
117 ************** Unverified Anchor Checks ****************
118 ********************************************************/
119 SEC_CONST_DECL (kSecPolicyCheckAnchorSHA1
, "AnchorSHA1");
120 SEC_CONST_DECL (kSecPolicyCheckAnchorSHA256
, "AnchorSHA256");
122 /* Fake key for isAnchored check. */
123 SEC_CONST_DECL (kSecPolicyCheckAnchorTrusted
, "AnchorTrusted");
125 /* Anchor is one of the apple trust anchors */
126 SEC_CONST_DECL (kSecPolicyCheckAnchorApple
, "AnchorApple");
128 /* options for kSecPolicyCheckAnchorApple */
129 SEC_CONST_DECL (kSecPolicyAppleAnchorIncludeTestRoots
, "AnchorAppleTestRoots");
131 /********************************************************
132 *********** Unverified Certificate Checks **************
133 ********************************************************/
134 /* Unverified Certificate Checks (any of the above) */
135 SEC_CONST_DECL (kSecPolicyCheckNonEmptySubject
, "NonEmptySubject");
136 SEC_CONST_DECL (kSecPolicyCheckIdLinkage
, "IdLinkage") /* (rfc5280 check) */
138 SEC_CONST_DECL (kSecPolicyCheckValidityStarted
, "ValidStarted");
139 SEC_CONST_DECL (kSecPolicyCheckValidityExpired
, "ValidExpired");
141 SEC_CONST_DECL (kSecPolicyCheckValidIntermediates
, "ValidIntermediates");
142 SEC_CONST_DECL (kSecPolicyCheckValidLeaf
, "ValidLeaf");
143 SEC_CONST_DECL (kSecPolicyCheckValidRoot
, "ValidRoot");
144 SEC_CONST_DECL (kSecPolicyCheckWeakIntermediates
, "WeakIntermediates");
145 SEC_CONST_DECL (kSecPolicyCheckWeakLeaf
, "WeakLeaf");
146 SEC_CONST_DECL (kSecPolicyCheckWeakRoot
, "WeakRoot");
147 SEC_CONST_DECL (kSecPolicyCheckKeySize
, "KeySize");
148 SEC_CONST_DECL (kSecPolicyCheckSignatureHashAlgorithms
, "SignatureHashAlgorithms");
152 /********************************************************
153 **************** Verified Path Checks ******************
154 ********************************************************/
155 /* (rfc5280 check) Ideally we should dynamically track all the extensions
156 we processed for each certificate and fail this test if any critical
157 extensions remain. */
158 SEC_CONST_DECL (kSecPolicyCheckCriticalExtensions
, "CriticalExtensions");
160 /* Check that the certificate chain length matches the specificed CFNumberRef
162 SEC_CONST_DECL (kSecPolicyCheckChainLength
, "ChainLength");
164 /* (rfc5280 check) */
165 SEC_CONST_DECL (kSecPolicyCheckBasicCertificateProcessing
, "BasicCertificateProcessing");
167 /********************************************************
168 ******************* Feature toggles ********************
169 ********************************************************/
171 /* Check revocation if specified. */
172 SEC_CONST_DECL (kSecPolicyCheckExtendedValidation
, "ExtendedValidation");
173 SEC_CONST_DECL (kSecPolicyCheckRevocation
, "Revocation");
174 SEC_CONST_DECL (kSecPolicyCheckRevocationResponseRequired
, "RevocationResponseRequired");
175 SEC_CONST_DECL (kSecPolicyCheckRevocationOCSP
, "OCSP");
176 SEC_CONST_DECL (kSecPolicyCheckRevocationCRL
, "CRL");
177 SEC_CONST_DECL (kSecPolicyCheckRevocationAny
, "AnyRevocationMethod");
179 /* Check Certificate Transparency if specified. */
180 SEC_CONST_DECL (kSecPolicyCheckCertificateTransparency
, "CertificateTransparency");
182 /* If present and true, we never go out to the network for anything
183 (OCSP, CRL or CA Issuer checking) but just used cached data instead. */
184 SEC_CONST_DECL (kSecPolicyCheckNoNetworkAccess
, "NoNetworkAccess");
186 /* Hack to quickly blacklist certain certs. */
187 SEC_CONST_DECL (kSecPolicyCheckBlackListedLeaf
, "BlackListedLeaf");
188 SEC_CONST_DECL (kSecPolicyCheckGrayListedLeaf
, "GrayListedLeaf");
189 SEC_CONST_DECL (kSecPolicyCheckGrayListedKey
, "GrayListedKey");
190 SEC_CONST_DECL (kSecPolicyCheckBlackListedKey
, "BlackListedKey");
192 SEC_CONST_DECL (kSecPolicyCheckLeafMarkerOid
, "CheckLeafMarkerOid");
193 SEC_CONST_DECL (kSecPolicyCheckLeafMarkerOidWithoutValueCheck
, "CheckLeafMarkerOidNoValueCheck");
194 SEC_CONST_DECL (kSecPolicyCheckIntermediateMarkerOid
, "CheckIntermediateMarkerOid");
196 SEC_CONST_DECL (kSecPolicyCheckUsageConstraints
, "UsageConstraints");
198 /* Public policy names. */
199 SEC_CONST_DECL (kSecPolicyAppleX509Basic
, "1.2.840.113635.100.1.2");
200 SEC_CONST_DECL (kSecPolicyAppleSSL
, "1.2.840.113635.100.1.3");
201 SEC_CONST_DECL (kSecPolicyAppleSMIME
, "1.2.840.113635.100.1.8");
202 SEC_CONST_DECL (kSecPolicyAppleEAP
, "1.2.840.113635.100.1.9");
203 SEC_CONST_DECL (kSecPolicyAppleSWUpdateSigning
, "1.2.840.113635.100.1.10");
204 SEC_CONST_DECL (kSecPolicyAppleIPsec
, "1.2.840.113635.100.1.11");
205 SEC_CONST_DECL (kSecPolicyApplePKINITClient
, "1.2.840.113635.100.1.14");
206 SEC_CONST_DECL (kSecPolicyApplePKINITServer
, "1.2.840.113635.100.1.15");
207 SEC_CONST_DECL (kSecPolicyAppleCodeSigning
, "1.2.840.113635.100.1.16");
208 SEC_CONST_DECL (kSecPolicyApplePackageSigning
, "1.2.840.113635.100.1.17");
209 SEC_CONST_DECL (kSecPolicyAppleIDValidation
, "1.2.840.113635.100.1.18");
210 SEC_CONST_DECL (kSecPolicyMacAppStoreReceipt
, "1.2.840.113635.100.1.19");
211 SEC_CONST_DECL (kSecPolicyAppleTimeStamping
, "1.2.840.113635.100.1.20");
212 SEC_CONST_DECL (kSecPolicyAppleRevocation
, "1.2.840.113635.100.1.21");
213 SEC_CONST_DECL (kSecPolicyApplePassbookSigning
, "1.2.840.113635.100.1.22");
214 SEC_CONST_DECL (kSecPolicyAppleMobileStore
, "1.2.840.113635.100.1.23");
215 SEC_CONST_DECL (kSecPolicyAppleEscrowService
, "1.2.840.113635.100.1.24");
216 SEC_CONST_DECL (kSecPolicyAppleProfileSigner
, "1.2.840.113635.100.1.25");
217 SEC_CONST_DECL (kSecPolicyAppleQAProfileSigner
, "1.2.840.113635.100.1.26");
218 SEC_CONST_DECL (kSecPolicyAppleTestMobileStore
, "1.2.840.113635.100.1.27");
219 SEC_CONST_DECL (kSecPolicyAppleOTAPKISigner
, "1.2.840.113635.100.1.28");
220 SEC_CONST_DECL (kSecPolicyAppleTestOTAPKISigner
, "1.2.840.113635.100.1.29");
221 SEC_CONST_DECL (kSecPolicyAppleIDValidationRecordSigningPolicy
, "1.2.840.113635.100.1.30");
222 SEC_CONST_DECL (kSecPolicyAppleIDValidationRecordSigning
, "1.2.840.113635.100.1.30");
223 SEC_CONST_DECL (kSecPolicyAppleSMPEncryption
, "1.2.840.113635.100.1.31");
224 SEC_CONST_DECL (kSecPolicyAppleTestSMPEncryption
, "1.2.840.113635.100.1.32");
225 SEC_CONST_DECL (kSecPolicyAppleServerAuthentication
, "1.2.840.113635.100.1.33");
226 SEC_CONST_DECL (kSecPolicyApplePCSEscrowService
, "1.2.840.113635.100.1.34");
227 SEC_CONST_DECL (kSecPolicyApplePPQSigning
, "1.2.840.113635.100.1.35");
228 SEC_CONST_DECL (kSecPolicyAppleTestPPQSigning
, "1.2.840.113635.100.1.36");
229 // Not in use. Use kSecPolicyAppleTVOSApplicationSigning instead.
230 // SEC_CONST_DECL (kSecPolicyAppleATVAppSigning, "1.2.840.113635.100.1.37");
231 // SEC_CONST_DECL (kSecPolicyAppleTestATVAppSigning, "1.2.840.113635.100.1.38");
232 SEC_CONST_DECL (kSecPolicyApplePayIssuerEncryption
, "1.2.840.113635.100.1.39");
233 SEC_CONST_DECL (kSecPolicyAppleOSXProvisioningProfileSigning
, "1.2.840.113635.100.1.40");
234 SEC_CONST_DECL (kSecPolicyAppleATVVPNProfileSigning
, "1.2.840.113635.100.1.41");
235 SEC_CONST_DECL (kSecPolicyAppleAST2DiagnosticsServerAuth
, "1.2.840.113635.100.1.42");
236 SEC_CONST_DECL (kSecPolicyAppleEscrowProxyServerAuth
, "1.2.840.113635.100.1.43");
237 SEC_CONST_DECL (kSecPolicyAppleFMiPServerAuth
, "1.2.840.113635.100.1.44");
238 SEC_CONST_DECL (kSecPolicyAppleMMCSService
, "1.2.840.113635.100.1.45");
239 SEC_CONST_DECL (kSecPolicyAppleGSService
, "1.2.840.113635.100.1.46");
240 SEC_CONST_DECL (kSecPolicyApplePPQService
, "1.2.840.113635.100.1.47");
241 SEC_CONST_DECL (kSecPolicyAppleHomeKitServerAuth
, "1.2.840.113635.100.1.48");
242 SEC_CONST_DECL (kSecPolicyAppleiPhoneActivation
, "1.2.840.113635.100.1.49");
243 SEC_CONST_DECL (kSecPolicyAppleiPhoneDeviceCertificate
, "1.2.840.113635.100.1.50");
244 SEC_CONST_DECL (kSecPolicyAppleFactoryDeviceCertificate
, "1.2.840.113635.100.1.51");
245 SEC_CONST_DECL (kSecPolicyAppleiAP
, "1.2.840.113635.100.1.52");
246 SEC_CONST_DECL (kSecPolicyAppleiTunesStoreURLBag
, "1.2.840.113635.100.1.53");
247 SEC_CONST_DECL (kSecPolicyAppleiPhoneApplicationSigning
, "1.2.840.113635.100.1.54");
248 SEC_CONST_DECL (kSecPolicyAppleiPhoneProfileApplicationSigning
, "1.2.840.113635.100.1.55");
249 SEC_CONST_DECL (kSecPolicyAppleiPhoneProvisioningProfileSigning
, "1.2.840.113635.100.1.56");
250 SEC_CONST_DECL (kSecPolicyAppleLockdownPairing
, "1.2.840.113635.100.1.57");
251 SEC_CONST_DECL (kSecPolicyAppleURLBag
, "1.2.840.113635.100.1.58");
252 SEC_CONST_DECL (kSecPolicyAppleOTATasking
, "1.2.840.113635.100.1.59");
253 SEC_CONST_DECL (kSecPolicyAppleMobileAsset
, "1.2.840.113635.100.1.60");
254 SEC_CONST_DECL (kSecPolicyAppleIDAuthority
, "1.2.840.113635.100.1.61");
255 SEC_CONST_DECL (kSecPolicyAppleGenericApplePinned
, "1.2.840.113635.100.1.62");
256 SEC_CONST_DECL (kSecPolicyAppleGenericAppleSSLPinned
, "1.2.840.113635.100.1.63");
257 SEC_CONST_DECL (kSecPolicyAppleSoftwareSigning
, "1.2.840.113635.100.1.64");
258 SEC_CONST_DECL (kSecPolicyAppleExternalDeveloper
, "1.2.840.113635.100.1.65");
259 SEC_CONST_DECL (kSecPolicyAppleOCSPSigner
, "1.2.840.113635.100.1.66");
260 SEC_CONST_DECL (kSecPolicyAppleIDSService
, "1.2.840.113635.100.1.67");
261 SEC_CONST_DECL (kSecPolicyAppleIDSServiceContext
, "1.2.840.113635.100.1.68");
262 SEC_CONST_DECL (kSecPolicyApplePushService
, "1.2.840.113635.100.1.69");
263 SEC_CONST_DECL (kSecPolicyAppleLegacyPushService
, "1.2.840.113635.100.1.70");
264 SEC_CONST_DECL (kSecPolicyAppleTVOSApplicationSigning
, "1.2.840.113635.100.1.71");
265 SEC_CONST_DECL (kSecPolicyAppleUniqueDeviceIdentifierCertificate
, "1.2.840.113635.100.1.72");
266 SEC_CONST_DECL (kSecPolicyAppleEscrowProxyCompatibilityServerAuth
, "1.2.840.113635.100.1.73");
267 SEC_CONST_DECL (kSecPolicyAppleMMCSCompatibilityServerAuth
, "1.2.840.113635.100.1.74");
269 SEC_CONST_DECL (kSecPolicyOid
, "SecPolicyOid");
270 SEC_CONST_DECL (kSecPolicyName
, "SecPolicyName");
271 SEC_CONST_DECL (kSecPolicyClient
, "SecPolicyClient");
272 SEC_CONST_DECL (kSecPolicyRevocationFlags
, "SecPolicyRevocationFlags");
273 SEC_CONST_DECL (kSecPolicyTeamIdentifier
, "SecPolicyTeamIdentifier");
274 SEC_CONST_DECL (kSecPolicyContext
, "SecPolicyContext");
275 SEC_CONST_DECL (kSecPolicyPolicyName
, "SecPolicyPolicyName");
276 SEC_CONST_DECL (kSecPolicyIntermediateMarkerOid
, "SecPolicyIntermediateMarkerOid");
277 SEC_CONST_DECL (kSecPolicyLeafMarkerOid
, "SecPolicyLeafMarkerOid");
278 SEC_CONST_DECL (kSecPolicyRootDigest
, "SecPolicyRootDigest");
280 SEC_CONST_DECL (kSecPolicyKU_DigitalSignature
, "CE_KU_DigitalSignature");
281 SEC_CONST_DECL (kSecPolicyKU_NonRepudiation
, "CE_KU_NonRepudiation");
282 SEC_CONST_DECL (kSecPolicyKU_KeyEncipherment
, "CE_KU_KeyEncipherment");
283 SEC_CONST_DECL (kSecPolicyKU_DataEncipherment
, "CE_KU_DataEncipherment");
284 SEC_CONST_DECL (kSecPolicyKU_KeyAgreement
, "CE_KU_KeyAgreement");
285 SEC_CONST_DECL (kSecPolicyKU_KeyCertSign
, "CE_KU_KeyCertSign");
286 SEC_CONST_DECL (kSecPolicyKU_CRLSign
, "CE_KU_CRLSign");
287 SEC_CONST_DECL (kSecPolicyKU_EncipherOnly
, "CE_KU_EncipherOnly");
288 SEC_CONST_DECL (kSecPolicyKU_DecipherOnly
, "CE_KU_DecipherOnly");
290 /* Private policy names */
291 static CFStringRef kSecPolicyNameBasicX509
= CFSTR("basicX509");
292 static CFStringRef kSecPolicyNameSSLServer
= CFSTR("sslServer");
293 static CFStringRef kSecPolicyNameSSLClient
= CFSTR("sslClient");
294 static CFStringRef kSecPolicyNameiPhoneActivation
= CFSTR("iPhoneActivation");
295 static CFStringRef kSecPolicyNameiPhoneDeviceCertificate
=
296 CFSTR("iPhoneDeviceCertificate");
297 static CFStringRef kSecPolicyNameFactoryDeviceCertificate
=
298 CFSTR("FactoryDeviceCertificate");
299 static CFStringRef kSecPolicyNameiAP
= CFSTR("iAP");
300 static CFStringRef kSecPolicyNameiTunesStoreURLBag
= CFSTR("iTunesStoreURLBag");
301 static CFStringRef kSecPolicyNameEAPServer
= CFSTR("eapServer");
302 static CFStringRef kSecPolicyNameEAPClient
= CFSTR("eapClient");
303 static CFStringRef kSecPolicyNameIPSecServer
= CFSTR("ipsecServer");
304 static CFStringRef kSecPolicyNameIPSecClient
= CFSTR("ipsecClient");
305 static CFStringRef kSecPolicyNameiPhoneApplicationSigning
=
306 CFSTR("iPhoneApplicationSigning");
307 static CFStringRef kSecPolicyNameiPhoneProfileApplicationSigning
=
308 CFSTR("iPhoneProfileApplicationSigning");
309 static CFStringRef kSecPolicyNameiPhoneProvisioningProfileSigning
=
310 CFSTR("iPhoneProvisioningProfileSigning");
311 static CFStringRef kSecPolicyNameAppleSWUpdateSigning
= CFSTR("AppleSWUpdateSigning");
312 static CFStringRef kSecPolicyNameAppleTVOSApplicationSigning
=
313 CFSTR("AppleTVApplicationSigning");
314 static CFStringRef kSecPolicyNameRevocation
= CFSTR("revocation");
315 static CFStringRef kSecPolicyNameOCSPSigner
= CFSTR("OCSPSigner");
316 static CFStringRef kSecPolicyNameSMIME
= CFSTR("SMIME");
317 static CFStringRef kSecPolicyNameCodeSigning
= CFSTR("CodeSigning");
318 static CFStringRef kSecPolicyNamePackageSigning
= CFSTR("PackageSigning");
319 static CFStringRef kSecPolicyNameLockdownPairing
= CFSTR("LockdownPairing");
320 static CFStringRef kSecPolicyNameURLBag
= CFSTR("URLBag");
321 static CFStringRef kSecPolicyNameOTATasking
= CFSTR("OTATasking");
322 static CFStringRef kSecPolicyNameMobileAsset
= CFSTR("MobileAsset");
323 static CFStringRef kSecPolicyNameAppleIDAuthority
= CFSTR("AppleIDAuthority");
324 static CFStringRef kSecPolicyNameMacAppStoreReceipt
= CFSTR("MacAppStoreReceipt");
325 static CFStringRef kSecPolicyNameAppleTimeStamping
= CFSTR("AppleTimeStamping");
326 static CFStringRef kSecPolicyNameApplePassbook
= CFSTR("ApplePassbook");
327 static CFStringRef kSecPolicyNameAppleMobileStore
= CFSTR("AppleMobileStore");
328 static CFStringRef kSecPolicyNameAppleTestMobileStore
= CFSTR("AppleTestMobileStore");
329 static CFStringRef kSecPolicyNameAppleEscrowService
= CFSTR("AppleEscrowService");
330 static CFStringRef kSecPolicyNameApplePCSEscrowService
= CFSTR("ApplePCSEscrowService");
331 static CFStringRef kSecPolicyNameAppleProfileSigner
= CFSTR("AppleProfileSigner");
332 static CFStringRef kSecPolicyNameAppleQAProfileSigner
= CFSTR("AppleQAProfileSigner");
333 static CFStringRef kSecPolicyNameAppleOTAPKIAssetSigner
= CFSTR("AppleOTAPKIAssetSigner");
334 static CFStringRef kSecPolicyNameAppleTestOTAPKIAssetSigner
= CFSTR("AppleTestOTAPKIAssetSigner");
335 static CFStringRef kSecPolicyNameAppleIDValidationRecordSigningPolicy
= CFSTR("AppleIDValidationRecordSigningPolicy");
336 static CFStringRef kSecPolicyNameApplePayIssuerEncryption
= CFSTR("ApplePayIssuerEncryption");
337 static CFStringRef kSecPolicyNameAppleOSXProvisioningProfileSigning
= CFSTR("AppleOSXProvisioningProfileSigning");
338 static CFStringRef kSecPolicyNameAppleATVVPNProfileSigning
= CFSTR("AppleATVVPNProfileSigning");
339 static CFStringRef kSecPolicyNameAppleAST2Service
= CFSTR("AST2");
340 static CFStringRef kSecPolicyNameAppleEscrowProxyService
= CFSTR("Escrow");
341 static CFStringRef kSecPolicyNameAppleFMiPService
= CFSTR("FMiP");
342 static CFStringRef kSecPolicyNameAppleHomeKitServerAuth
= CFSTR("HomeKit");
343 static CFStringRef kSecPolicyNameAppleExternalDeveloper
= CFSTR("Developer");
344 static CFStringRef kSecPolicyNameAppleSoftwareSigning
= CFSTR("SoftwareSigning");
345 static CFStringRef kSecPolicyNameAppleSMPEncryption
= CFSTR("AppleSMPEncryption");
346 static CFStringRef kSecPolicyNameAppleTestSMPEncryption
= CFSTR("AppleTestSMPEncryption");
347 static CFStringRef kSecPolicyNameApplePPQSigning
= CFSTR("ApplePPQSigning");
348 static CFStringRef kSecPolicyNameAppleTestPPQSigning
= CFSTR("AppleTestPPQSigning");
349 static CFStringRef kSecPolicyNameAppleLegacyPushService
= CFSTR("AppleLegacyPushService");
350 static CFStringRef kSecPolicyNameAppleSSLService
= CFSTR("AppleSSLService");
351 static CFStringRef kSecPolicyNameApplePushService
= CFSTR("APN");
352 static CFStringRef kSecPolicyNameAppleIDSServiceContext
= CFSTR("IDS");
353 static CFStringRef kSecPolicyNameAppleGSService
= CFSTR("GS");
354 static CFStringRef kSecPolicyNameAppleMMCSService
= CFSTR("MMCS");
355 static CFStringRef kSecPolicyNameApplePPQService
= CFSTR("PPQ");
356 static CFStringRef kSecPolicyNameAppleUniqueDeviceCertificate
= CFSTR("UCRT");
359 /* Policies will now change to multiple categories of checks.
361 IDEA Store partial valid policy tree in each chain? Result tree pruning might make this not feasible unless you can pretend to prune the tree without actually deleting nodes and somehow still have shable nodes with parent chains (this assumes that chains will be built as cached things from the root down), and we can build something equivalent to rfc5280 in a tree of certs. So we need to maintain a cache of leaf->chain with this certificate as any_ca_cert->tree. Revocation status caching can be done in this cache as well, so maybe the cache should be in sqlite3, or at least written there before exit and querying of the cache could be done first on the in core (possibly CF or custom tree like structure) and secondarly on the sqlite3 backed store. We should choose the lowest memory footprint solution in my mind, while choosing a sqlite3 cache size that gives us a resonable io usage pattern.
362 NOTE no certificate can be an intermediate unless it is X.509V3 and it has a basicConstraints extension with isCA set to true. This can be used to classify certs for caching purposes.
364 kSecPolicySLCheck Static Subscriber Certificate Checks
365 kSecPolicySICheck Static Subsidiary CA Checks
366 kSecPolicySACheck Static Anchor Checks
368 kSecPolicyDLCheck Dynamic Subscriber Certificate Checks
369 kSecPolicyDICheck Dynamic Subsidiary CA Checks
370 kSecPolicyDACheck Dynamic Anchor Checks ? not yet needed other than to
371 possibly exclude in a exception template (but those should still be per
372 certificate --- i.o.w. exceptions (or a database backed multiple role/user
373 trust store of some sort) and policies are 2 different things and this
374 text is about policies.
376 All static checks are only allowed to consider the certificate in isolation,
377 just given the position in the chain or the cert (leaf, intermidate, root).
378 dynamic checks can make determinations about the chain as a whole.
380 Static Subscriber Certificate Checks will be done up front before the
381 chainbuilder is even instantiated. If they fail and details aren't required
382 by the client (if no exceptions were present for this certificate) we could
383 short circuit fail the evaluation.
384 IDEA: These checks can dynamically add new checks...[needs work]
385 ALTERNATIVE: A policy can have one or more sub-policies. Each sub-policy will be evaluated only after the parent policy succeeds. Subpolicies can be either required (making the parent policy fail) or optional making the parent policy succeed, but allowing the chainbuilder to continue building chains after an optional subpolicy failure in search of a chain for which the subpolicy also succeeded. Subpolicies can be dynamically added to the policy evaluation context tree (a tree with a node for every node in the certificate path. This tree however is from the leaf up stored in the SecCertificatePathRef objects themselves possibly - requiring a separate shared subtree of nodes for the underlying certificate state tree.) by a parent policy at any stage, since the subpolicy evaluation only starts after
386 will have a key in the info (or even details and make info client side generated from info to indicate the success or failure of optional subpolicies) tree the value of which is an
387 equivalent subtree from that level down. So SSL has EV as a subpolicy, but
388 EV dynamically enables the ocsp or crl or dcrl or any combination thereof subpolicies.
390 Static Subsidiary CA Checks will be used by the chain-builder to choose the
391 best parents to evaluate first. This feature is currently already implemented
392 but with a hardcoded is_valid(verifyTime) check. Instead we will evaluate all
393 Static Subsidiary CA Checks. The results of these checks for purposes of
394 generating details could be cached in the SecCertificatePathRefs themselves, or we can short circuit fail and recalc details on demand later.
396 Static Anchor Checks can do things like populate the chainbuilder level context value of the initial_valid_policy_tree with a particular anchors list of ev policies it represents or modify inputs to the policy itself.
398 Dynamic Subscriber Certificate Checks These can do things like check for EV policy conformance based on the valid_policy_tree at the end of the certificate evaluation, or based on things like the pathlen, etc. in the chain validation context.
400 Dynamic Subsidiary CA Checks might not be needed to have custom
401 implementations, since they are all done as part of the rfc5280 checks now.
402 This assumes that checks like issuer common name includes 'foo' are
403 implmented as Static Subscriber Certificate Checks instead.
405 Dynamic Anchor Checks might include EV type checks or chain validation context seeding as well, allthough we might be able to do them as static checks to seed the chain validation context instead.
408 Questions/Notes: Do we need to dynamically add new policies? If policy static checks fail and policy is optional we don't even run policy dynamic checks nor do we compute subpolicy values. So if the static check of the leaf for EV fails we skip the rest of the EV style checks and instead don't run the revocation subpolicy of the ev policy.
410 If an optional subpolicy s_p has a required subpolicy r_s_p. Then success of s_p will cause the entire chain evaluation to fail if r_s_p fails.
412 All policies static revocation checks are run at the appropriate phase in the evaluation. static leaf checks are done before chainbuilding even starts. static intermediate checks are done in the chainbuilder for each cadidate parent certificate. If all policies pass we check the signatures. We reject the whole chain if that step fails. Otherwise we add the path to builder->candidatePaths. If the top level policy or a required subpolicy or a required subpolicy of a successful subpolicy fails we stick the chain at the end of the expiredPaths, if one of the optional subpolicies fail, we stick the chain at the start of expiredPaths so it's considered first after all real candidatePaths have been processed.
414 Static revocation policy checks could check the passed in ocspresponses or even the local cache, though the latter is probably best left for the dynamic phase.
416 The same rules that apply above to the adding paths to candidatePaths v/s expiredPaths apply to dynamicpolicy checks, except that we don't remember failures anymore, we reject them.
418 We need to remember the best successful chain we find, where best is defined by: satisfies as many optional policies as possible.
420 Chain building ends when either we find a chain that matches all optional and required policies, or we run out of chains to build. Another case is if we run out of candiate paths but we already have a chain that matches at least the top level and required subpolicies. In that case we don't even consider any expiredPaths. Example: we find a valid SSL chain (top level policy), but no partial chain we constructed satisfied the static checks of the ev subpolicy, or the required revocation sub-subpolicy of the ev policy.
422 In order for this to work well with exceptions on subpolicies, we'd need to move the validation of exceptions to the server, something we'd do anyway if we had full on truststore. In this case exceptions would be live in the failure callback for a trust check.
424 Example sectrust operation in psuedocode:
428 new builder(verifyTime, certificates, anchors, anchorsOnly, policies);
429 chain = builder.subscriber_only_chain;
430 foreach (policy in policies{kSecPolicySLCheck}) {
431 foreach(check in policy)
432 SecPolicyRunCheck(builder, chain, check, details);
433 foreach (subpolicy in policy) {
434 check_policy(builder, chain, subpolicy, details{subpolicy.name})
436 propagate_subpolicy_results(builder, chain, details);
438 while (chain = builder.next) {
439 for (depth = 0; p_d = policies.at_depth(depth),
440 d_p_d = dynamic_policies.at_depth(depth), p_d || d_p_d; ++depth)
442 // Modify SecPathBuilderIsPartial() to
443 // run builder_check(buildier, policies, kSecPolicySICheck) instead
444 // of SecCertificateIsValid. Also rename considerExpired to
445 // considerSIFailures.
446 foreach (policy in p_d) {
447 check_policy(builder, chain, policy, kSecPolicySICheck, depth);
449 /// Recalculate since the static checks might have added new dynamic
451 d_p_d = dynamic_policies.at_depth(depth);
452 foreach (policy in d_p_d) {
453 check_policy(builder, chain, policy, kSecPolicySICheck, depth);
455 if (chain.is_anchored) {
456 foreach (policy in p_d) {
457 check_policy(builder, chain, policy, kSecPolicySACheck, depth);
459 foreach (policy in d_p_d) {
460 check_policy(builder, chain, policy, kSecPolicySACheck, depth);
462 foreach (policy in p_d) {
463 check_policy(builder, chain, policy, kSecPolicyDACheck, depth);
465 foreach (policy in d_p_d) {
466 check_policy(builder, chain, policy, kSecPolicyDACheck, depth);
469 foreach (policy in policies) {
470 check_policy(builder, chain, policy, kSecPolicySACheck, depth);
471 check_policy(builder, chain, policy, kSecPolicyDACheck, depth);
473 foreach (policy in policies{kSecPolicySDCheck}) {
478 check_policy(builder, chain, policy, check_class, details, depth) {
480 foreach(check in policy{check_class}) {
481 SecPolicyRunCheck(builder, chain, check, details);
485 foreach (subpolicy in policy) {
486 if (!check_policy(builder, chain, subpolicy, check_class,
487 details{subpolicy.name}) && subpolicy.is_required, depth)
491 propagate_subpolicy_results(builder, chain, details);
498 #define kSecPolicySHA1Size 20
499 #define kSecPolicySHA256Size 32
500 __unused
const UInt8 kAppleCASHA1
[kSecPolicySHA1Size
] = {
501 0x61, 0x1E, 0x5B, 0x66, 0x2C, 0x59, 0x3A, 0x08, 0xFF, 0x58,
502 0xD1, 0x4A, 0xE2, 0x24, 0x52, 0xD1, 0x98, 0xDF, 0x6C, 0x60
505 __unused
static const UInt8 kAppleTESTCASHA1
[kSecPolicySHA1Size
] = {
506 0xbc, 0x30, 0x55, 0xc8, 0xc8, 0xd3, 0x48, 0x3f, 0xf4, 0x8d,
507 0xfe, 0x3d, 0x51, 0x75, 0x31, 0xc9, 0xf4, 0xd7, 0x4a, 0xf7
510 static const UInt8 kITMSCASHA1
[kSecPolicySHA1Size
] = {
511 0x1D, 0x33, 0x42, 0x46, 0x8B, 0x10, 0xBD, 0xE6, 0x45, 0xCE,
512 0x44, 0x6E, 0xBB, 0xE8, 0xF5, 0x03, 0x5D, 0xF8, 0x32, 0x22
515 static const UInt8 kFactoryDeviceCASHA1
[kSecPolicySHA1Size
] = {
516 0xef, 0x68, 0x73, 0x17, 0xa4, 0xf8, 0xf9, 0x4b, 0x7b, 0x21,
517 0xe2, 0x2f, 0x09, 0x8f, 0xfd, 0x6a, 0xae, 0xc0, 0x0d, 0x63
520 static const UInt8 kApplePKISettingsAuthority
[kSecPolicySHA1Size
] = {
521 0x1D, 0x0C, 0xBA, 0xAD, 0x17, 0xFD, 0x7E, 0x9E, 0x9F, 0xF1,
522 0xC9, 0xA2, 0x66, 0x79, 0x60, 0x00, 0x8B, 0xAE, 0x70, 0xB8
525 static const UInt8 kAppleTestPKISettingsAuthority
[kSecPolicySHA1Size
] = {
526 0xDB, 0xBA, 0x25, 0x0B, 0xD8, 0x62, 0x71, 0x87, 0x54, 0x7E,
527 0xD7, 0xEF, 0x11, 0x94, 0x7E, 0x82, 0xE6, 0xD8, 0x1C, 0x9A
530 static const UInt8 kTestAppleRootCA_ECC_SHA1
[kSecPolicySHA1Size
] = {
531 0x62, 0x0A, 0xED, 0x83, 0xD2, 0x97, 0x4A, 0x77, 0x56, 0x33,
532 0x83, 0xBE, 0xDB, 0xF9, 0xA1, 0xBD, 0x5F, 0xFE, 0x55, 0x7B
535 __unused
static const UInt8 kAppleRootCA_ECC_SHA1
[kSecPolicySHA1Size
] = {
536 0xB5, 0x2C, 0xB0, 0x2F, 0xD5, 0x67, 0xE0, 0x35, 0x9F, 0xE8,
537 0xFA, 0x4D, 0x4C, 0x41, 0x03, 0x79, 0x70, 0xFE, 0x01, 0xB0
542 /********************************************************
543 ****************** SecPolicy object ********************
544 ********************************************************/
546 static void SecPolicyDestroy(CFTypeRef cf
) {
547 SecPolicyRef policy
= (SecPolicyRef
) cf
;
548 CFRelease(policy
->_oid
);
549 CFReleaseSafe(policy
->_name
);
550 CFRelease(policy
->_options
);
553 static Boolean
SecPolicyCompare(CFTypeRef cf1
, CFTypeRef cf2
) {
554 SecPolicyRef policy1
= (SecPolicyRef
) cf1
;
555 SecPolicyRef policy2
= (SecPolicyRef
) cf2
;
556 if (policy1
->_name
&& policy2
->_name
) {
557 return CFEqual(policy1
->_oid
, policy2
->_oid
) &&
558 CFEqual(policy1
->_name
, policy2
->_name
) &&
559 CFEqual(policy1
->_options
, policy2
->_options
);
561 return CFEqual(policy1
->_oid
, policy2
->_oid
) &&
562 CFEqual(policy1
->_options
, policy2
->_options
);
566 static CFHashCode
SecPolicyHash(CFTypeRef cf
) {
567 SecPolicyRef policy
= (SecPolicyRef
) cf
;
569 return CFHash(policy
->_oid
) + CFHash(policy
->_name
) + CFHash(policy
->_options
);
571 return CFHash(policy
->_oid
) + CFHash(policy
->_options
);
575 static CFStringRef
SecPolicyCopyFormatDescription(CFTypeRef cf
, CFDictionaryRef formatOptions
) {
576 SecPolicyRef policy
= (SecPolicyRef
) cf
;
577 CFMutableStringRef desc
= CFStringCreateMutable(kCFAllocatorDefault
, 0);
578 CFStringRef typeStr
= CFCopyTypeIDDescription(CFGetTypeID(cf
));
579 CFStringAppendFormat(desc
, NULL
,
580 CFSTR("<%@: oid: %@ name: %@ options %@"), typeStr
,
581 policy
->_oid
, (policy
->_name
) ? policy
->_name
: CFSTR(""),
584 CFStringAppend(desc
, CFSTR(" >"));
589 /* SecPolicy API functions. */
590 CFGiblisWithHashFor(SecPolicy
);
592 /* AUDIT[securityd](done):
593 oid (ok) is a caller provided string, only its cf type has been checked.
594 options is a caller provided dictionary, only its cf type has been checked.
596 SecPolicyRef
SecPolicyCreate(CFStringRef oid
, CFStringRef name
, CFDictionaryRef options
) {
597 SecPolicyRef result
= NULL
;
599 require(oid
, errOut
);
600 require(options
, errOut
);
602 (SecPolicyRef
)_CFRuntimeCreateInstance(kCFAllocatorDefault
,
603 SecPolicyGetTypeID(),
604 sizeof(struct __SecPolicy
) - sizeof(CFRuntimeBase
), 0), errOut
);
609 result
->_name
= name
;
611 result
->_options
= options
;
617 SecPolicyRef
SecPolicyCreateWithProperties(CFTypeRef policyIdentifier
,
618 CFDictionaryRef properties
) {
619 // Creates a policy reference for a given policy object identifier.
620 // If policy-specific parameters can be supplied (e.g. hostname),
621 // attempt to obtain from input properties dictionary.
622 // Returns NULL if the given identifier is unsupported.
624 SecPolicyRef policy
= NULL
;
625 CFTypeRef name
= NULL
;
626 CFStringRef teamID
= NULL
;
627 Boolean client
= false;
628 CFDictionaryRef context
= NULL
;
629 CFStringRef policyName
= NULL
, intermediateMarkerOid
= NULL
, leafMarkerOid
= NULL
;
630 CFDataRef rootDigest
= NULL
;
631 require(policyIdentifier
&& (CFStringGetTypeID() == CFGetTypeID(policyIdentifier
)), errOut
);
634 name
= CFDictionaryGetValue(properties
, kSecPolicyName
);
635 teamID
= CFDictionaryGetValue(properties
, kSecPolicyTeamIdentifier
);
637 CFBooleanRef dictionaryClientValue
;
638 client
= (CFDictionaryGetValueIfPresent(properties
, kSecPolicyClient
, (const void **)&dictionaryClientValue
) &&
639 (dictionaryClientValue
!= NULL
) && CFEqual(kCFBooleanTrue
, dictionaryClientValue
));
640 context
= CFDictionaryGetValue(properties
, kSecPolicyContext
);
641 policyName
= CFDictionaryGetValue(properties
, kSecPolicyPolicyName
);
642 intermediateMarkerOid
= CFDictionaryGetValue(properties
, kSecPolicyIntermediateMarkerOid
);
643 leafMarkerOid
= CFDictionaryGetValue(properties
, kSecPolicyLeafMarkerOid
);
644 rootDigest
= CFDictionaryGetValue(properties
, kSecPolicyRootDigest
);
647 /* only the EAP policy allows a non-string name */
648 if (name
&& !isString(name
) && !CFEqual(policyIdentifier
, kSecPolicyAppleEAP
)) {
649 secerror("policy \"%@\" requires a string value for the %@ key", policyIdentifier
, kSecPolicyName
);
653 /* These are in the same order as the constant declarations. */
654 if (CFEqual(policyIdentifier
, kSecPolicyAppleX509Basic
)) {
655 policy
= SecPolicyCreateBasicX509();
657 else if (CFEqual(policyIdentifier
, kSecPolicyAppleSSL
)) {
658 policy
= SecPolicyCreateSSL(!client
, name
);
660 else if (CFEqual(policyIdentifier
, kSecPolicyAppleSMIME
)) {
661 policy
= SecPolicyCreateSMIME(kSecSignSMIMEUsage
| kSecAnyEncryptSMIME
, name
);
663 else if (CFEqual(policyIdentifier
, kSecPolicyAppleEAP
)) {
664 CFArrayRef array
= NULL
;
665 if (isString(name
)) {
666 array
= CFArrayCreate(kCFAllocatorDefault
, (const void **)&name
, 1, &kCFTypeArrayCallBacks
);
667 } else if (isArray(name
)) {
668 array
= CFArrayCreateCopy(NULL
, name
);
670 policy
= SecPolicyCreateEAP(!client
, array
);
671 CFReleaseSafe(array
);
673 else if (CFEqual(policyIdentifier
, kSecPolicyAppleSWUpdateSigning
)) {
674 policy
= SecPolicyCreateAppleSWUpdateSigning();
676 else if (CFEqual(policyIdentifier
, kSecPolicyAppleIPsec
)) {
677 policy
= SecPolicyCreateIPSec(!client
, name
);
679 else if (CFEqual(policyIdentifier
, kSecPolicyAppleCodeSigning
)) {
680 policy
= SecPolicyCreateCodeSigning();
682 else if (CFEqual(policyIdentifier
, kSecPolicyApplePackageSigning
)) {
683 policy
= SecPolicyCreateApplePackageSigning();
685 else if (CFEqual(policyIdentifier
, kSecPolicyAppleIDValidation
)) {
686 policy
= SecPolicyCreateAppleIDAuthorityPolicy();
688 else if (CFEqual(policyIdentifier
, kSecPolicyMacAppStoreReceipt
)) {
689 policy
= SecPolicyCreateMacAppStoreReceipt();
691 else if (CFEqual(policyIdentifier
, kSecPolicyAppleTimeStamping
)) {
692 policy
= SecPolicyCreateAppleTimeStamping();
694 else if (CFEqual(policyIdentifier
, kSecPolicyAppleRevocation
)) {
695 policy
= SecPolicyCreateRevocation(kSecRevocationUseAnyAvailableMethod
);
697 else if (CFEqual(policyIdentifier
, kSecPolicyApplePassbookSigning
)) {
698 policy
= SecPolicyCreatePassbookCardSigner(name
, teamID
);
700 else if (CFEqual(policyIdentifier
, kSecPolicyAppleMobileStore
)) {
701 policy
= SecPolicyCreateMobileStoreSigner();
703 else if (CFEqual(policyIdentifier
, kSecPolicyAppleEscrowService
)) {
704 policy
= SecPolicyCreateEscrowServiceSigner();
706 else if (CFEqual(policyIdentifier
, kSecPolicyAppleProfileSigner
)) {
707 policy
= SecPolicyCreateConfigurationProfileSigner();
709 else if (CFEqual(policyIdentifier
, kSecPolicyAppleQAProfileSigner
)) {
710 policy
= SecPolicyCreateQAConfigurationProfileSigner();
712 else if (CFEqual(policyIdentifier
, kSecPolicyAppleTestMobileStore
)) {
713 policy
= SecPolicyCreateTestMobileStoreSigner();
715 else if (CFEqual(policyIdentifier
, kSecPolicyAppleOTAPKISigner
)) {
716 policy
= SecPolicyCreateOTAPKISigner();
718 else if (CFEqual(policyIdentifier
, kSecPolicyAppleTestOTAPKISigner
)) {
719 policy
= SecPolicyCreateTestOTAPKISigner();
721 else if (CFEqual(policyIdentifier
, kSecPolicyAppleIDValidationRecordSigning
)) {
722 policy
= SecPolicyCreateAppleIDValidationRecordSigningPolicy();
724 else if (CFEqual(policyIdentifier
, kSecPolicyAppleSMPEncryption
)) {
725 policy
= SecPolicyCreateAppleSMPEncryption();
727 else if (CFEqual(policyIdentifier
, kSecPolicyAppleTestSMPEncryption
)) {
728 policy
= SecPolicyCreateTestAppleSMPEncryption();
730 else if (CFEqual(policyIdentifier
, kSecPolicyAppleServerAuthentication
)) {
731 policy
= SecPolicyCreateAppleSSLService(name
);
733 else if (CFEqual(policyIdentifier
, kSecPolicyApplePCSEscrowService
)) {
734 policy
= SecPolicyCreatePCSEscrowServiceSigner();
736 else if (CFEqual(policyIdentifier
, kSecPolicyApplePPQSigning
)) {
737 policy
= SecPolicyCreateApplePPQSigning();
739 else if (CFEqual(policyIdentifier
, kSecPolicyAppleTestPPQSigning
)) {
740 policy
= SecPolicyCreateTestApplePPQSigning();
742 else if (CFEqual(policyIdentifier
, kSecPolicyApplePayIssuerEncryption
)) {
743 policy
= SecPolicyCreateApplePayIssuerEncryption();
745 else if (CFEqual(policyIdentifier
, kSecPolicyAppleOSXProvisioningProfileSigning
)) {
746 policy
= SecPolicyCreateOSXProvisioningProfileSigning();
748 else if (CFEqual(policyIdentifier
, kSecPolicyAppleATVVPNProfileSigning
)) {
749 policy
= SecPolicyCreateAppleATVVPNProfileSigning();
751 else if (CFEqual(policyIdentifier
, kSecPolicyAppleAST2DiagnosticsServerAuth
)) {
753 policy
= SecPolicyCreateAppleAST2Service(name
, context
);
755 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier
);
758 else if (CFEqual(policyIdentifier
, kSecPolicyAppleEscrowProxyServerAuth
)) {
760 policy
= SecPolicyCreateAppleEscrowProxyService(name
, context
);
762 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier
);
765 else if (CFEqual(policyIdentifier
, kSecPolicyAppleFMiPServerAuth
)) {
767 policy
= SecPolicyCreateAppleFMiPService(name
, context
);
769 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier
);
772 else if (CFEqual(policyIdentifier
, kSecPolicyAppleMMCSService
)) {
774 policy
= SecPolicyCreateAppleMMCSService(name
, context
);
776 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier
);
779 else if (CFEqual(policyIdentifier
, kSecPolicyAppleGSService
)) {
781 policy
= SecPolicyCreateAppleGSService(name
, context
);
783 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier
);
786 else if (CFEqual(policyIdentifier
, kSecPolicyApplePPQService
)) {
788 policy
= SecPolicyCreateApplePPQService(name
, context
);
790 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier
);
793 else if (CFEqual(policyIdentifier
, kSecPolicyAppleHomeKitServerAuth
)) {
794 policy
= SecPolicyCreateAppleHomeKitServerAuth(name
);
796 else if (CFEqual(policyIdentifier
, kSecPolicyAppleiPhoneActivation
)) {
797 policy
= SecPolicyCreateiPhoneActivation();
799 else if (CFEqual(policyIdentifier
, kSecPolicyAppleiPhoneDeviceCertificate
)) {
800 policy
= SecPolicyCreateiPhoneDeviceCertificate();
802 else if (CFEqual(policyIdentifier
, kSecPolicyAppleFactoryDeviceCertificate
)) {
803 policy
= SecPolicyCreateFactoryDeviceCertificate();
805 else if (CFEqual(policyIdentifier
, kSecPolicyAppleiAP
)) {
806 policy
= SecPolicyCreateiAP();
808 else if (CFEqual(policyIdentifier
, kSecPolicyAppleiTunesStoreURLBag
)) {
809 policy
= SecPolicyCreateiTunesStoreURLBag();
811 else if (CFEqual(policyIdentifier
, kSecPolicyAppleiPhoneApplicationSigning
)) {
812 policy
= SecPolicyCreateiPhoneApplicationSigning();
814 else if (CFEqual(policyIdentifier
, kSecPolicyAppleiPhoneProfileApplicationSigning
)) {
815 policy
= SecPolicyCreateiPhoneProfileApplicationSigning();
817 else if (CFEqual(policyIdentifier
, kSecPolicyAppleiPhoneProvisioningProfileSigning
)) {
818 policy
= SecPolicyCreateiPhoneProvisioningProfileSigning();
820 else if (CFEqual(policyIdentifier
, kSecPolicyAppleLockdownPairing
)) {
821 policy
= SecPolicyCreateLockdownPairing();
823 else if (CFEqual(policyIdentifier
, kSecPolicyAppleURLBag
)) {
824 policy
= SecPolicyCreateURLBag();
826 else if (CFEqual(policyIdentifier
, kSecPolicyAppleOTATasking
)) {
827 policy
= SecPolicyCreateOTATasking();
829 else if (CFEqual(policyIdentifier
, kSecPolicyAppleMobileAsset
)) {
830 policy
= SecPolicyCreateMobileAsset();
832 else if (CFEqual(policyIdentifier
, kSecPolicyAppleIDAuthority
)) {
833 policy
= SecPolicyCreateAppleIDAuthorityPolicy();
835 else if (CFEqual(policyIdentifier
, kSecPolicyAppleGenericApplePinned
)) {
836 policy
= SecPolicyCreateApplePinned(policyName
, intermediateMarkerOid
, leafMarkerOid
);
838 else if (CFEqual(policyIdentifier
, kSecPolicyAppleGenericAppleSSLPinned
)) {
839 policy
= SecPolicyCreateAppleSSLPinned(policyName
, name
, intermediateMarkerOid
, leafMarkerOid
);
841 else if (CFEqual(policyIdentifier
, kSecPolicyAppleSoftwareSigning
)) {
842 policy
= SecPolicyCreateAppleSoftwareSigning();
844 else if (CFEqual(policyIdentifier
, kSecPolicyAppleExternalDeveloper
)) {
845 policy
= SecPolicyCreateAppleExternalDeveloper();
847 else if (CFEqual(policyIdentifier
, kSecPolicyAppleOCSPSigner
)) {
848 policy
= SecPolicyCreateOCSPSigner();
850 else if (CFEqual(policyIdentifier
, kSecPolicyAppleIDSService
)) {
851 policy
= SecPolicyCreateAppleIDSService(name
);
853 else if (CFEqual(policyIdentifier
, kSecPolicyAppleIDSServiceContext
)) {
855 policy
= SecPolicyCreateAppleIDSServiceContext(name
, context
);
857 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier
);
860 else if (CFEqual(policyIdentifier
, kSecPolicyApplePushService
)) {
862 policy
= SecPolicyCreateApplePushService(name
, context
);
864 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier
);
867 else if (name
&& CFEqual(policyIdentifier
, kSecPolicyAppleLegacyPushService
)) {
869 policy
= SecPolicyCreateApplePushServiceLegacy(name
);
871 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier
);
874 else if (CFEqual(policyIdentifier
, kSecPolicyAppleTVOSApplicationSigning
)) {
875 policy
= SecPolicyCreateAppleTVOSApplicationSigning();
877 else if (CFEqual(policyIdentifier
, kSecPolicyAppleUniqueDeviceIdentifierCertificate
)) {
878 policy
= SecPolicyCreateAppleUniqueDeviceCertificate(rootDigest
);
880 else if (name
&& CFEqual(policyIdentifier
, kSecPolicyAppleEscrowProxyCompatibilityServerAuth
)) {
882 policy
= SecPolicyCreateAppleCompatibilityEscrowProxyService(name
);
884 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier
);
887 else if (name
&& CFEqual(policyIdentifier
, kSecPolicyAppleMMCSCompatibilityServerAuth
)) {
889 policy
= SecPolicyCreateAppleCompatibilityMMCSService(name
);
891 secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier
);
895 secerror("ERROR: policy \"%@\" is unsupported", policyIdentifier
);
902 CFDictionaryRef
SecPolicyCopyProperties(SecPolicyRef policyRef
) {
903 // Builds and returns a dictionary which the caller must release.
905 #pragma clang diagnostic push
906 #pragma clang diagnostic ignored "-Wnonnull"
907 // After introducing nullability annotations, policyRef is supposed to be nonnull, suppress the warning
908 if (!policyRef
) return NULL
;
909 #pragma clang diagnostic pop
910 CFMutableDictionaryRef properties
= CFDictionaryCreateMutable(NULL
, 0,
911 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
912 #pragma clang diagnostic push
913 #pragma clang diagnostic ignored "-Wnonnull"
914 // 'properties' is nonnull in reality suppress the warning
915 if (!properties
) return NULL
;
916 #pragma clang diagnostic pop
917 CFStringRef oid
= (CFStringRef
) CFRetain(policyRef
->_oid
);
918 CFTypeRef nameKey
= NULL
;
920 // Determine name key
921 if (policyRef
->_options
) {
922 if (CFDictionaryContainsKey(policyRef
->_options
, kSecPolicyCheckSSLHostname
)) {
923 nameKey
= kSecPolicyCheckSSLHostname
;
924 } else if (CFDictionaryContainsKey(policyRef
->_options
, kSecPolicyCheckEAPTrustedServerNames
)) {
925 nameKey
= kSecPolicyCheckEAPTrustedServerNames
;
926 } else if (CFDictionaryContainsKey(policyRef
->_options
, kSecPolicyCheckEmail
)) {
927 nameKey
= kSecPolicyCheckEmail
;
932 CFDictionarySetValue(properties
, (const void *)kSecPolicyOid
,
935 // Set kSecPolicyName if we have one
936 if (nameKey
&& policyRef
->_options
) {
937 CFTypeRef name
= (CFTypeRef
) CFDictionaryGetValue(policyRef
->_options
,
940 CFDictionarySetValue(properties
, (const void *)kSecPolicyName
,
945 // Set kSecPolicyClient
946 CFStringRef policyName
= (CFStringRef
) CFRetainSafe(policyRef
->_name
);
947 if (policyName
&& (CFEqual(policyName
, kSecPolicyNameSSLClient
) ||
948 CFEqual(policyName
, kSecPolicyNameIPSecClient
) ||
949 CFEqual(policyName
, kSecPolicyNameEAPClient
))) {
950 CFDictionarySetValue(properties
, (const void *)kSecPolicyClient
,
951 (const void *)kCFBooleanTrue
);
958 static void SecPolicySetOid(SecPolicyRef policy
, CFStringRef oid
) {
959 if (!policy
|| !oid
) return;
960 CFStringRef temp
= policy
->_oid
;
966 static void SecPolicySetName(SecPolicyRef policy
, CFStringRef policyName
) {
967 if (!policy
|| !policyName
) return;
968 CFStringRef temp
= policy
->_name
;
969 CFRetain(policyName
);
970 policy
->_name
= policyName
;
974 CFStringRef
SecPolicyGetOidString(SecPolicyRef policy
) {
978 CFStringRef
SecPolicyGetName(SecPolicyRef policy
) {
979 return policy
->_name
;
982 CFDictionaryRef
SecPolicyGetOptions(SecPolicyRef policy
) {
983 return policy
->_options
;
986 void SecPolicySetOptionsValue(SecPolicyRef policy
, CFStringRef key
, CFTypeRef value
) {
987 if (!policy
|| !key
) return;
988 CFMutableDictionaryRef options
= (CFMutableDictionaryRef
) policy
->_options
;
990 options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
991 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
992 if (!options
) return;
993 policy
->_options
= options
;
995 CFDictionarySetValue(options
, key
, value
);
998 /* Local forward declaration */
999 static void set_ssl_ekus(CFMutableDictionaryRef options
, bool server
);
1002 // this is declared as NA for iPhone in SecPolicy.h, so declare here
1003 OSStatus
SecPolicySetProperties(SecPolicyRef policyRef
, CFDictionaryRef properties
);
1006 OSStatus
SecPolicySetProperties(SecPolicyRef policyRef
, CFDictionaryRef properties
) {
1007 // Set policy options based on the provided dictionary keys.
1009 if (!(policyRef
&& properties
&& (CFDictionaryGetTypeID() == CFGetTypeID(properties
)))) {
1012 CFStringRef oid
= (CFStringRef
) CFRetain(policyRef
->_oid
);
1013 OSStatus result
= errSecSuccess
;
1016 CFTypeRef name
= NULL
;
1017 if (CFDictionaryGetValueIfPresent(properties
, (const void *)kSecPolicyName
,
1018 (const void **)&name
) && name
) {
1019 CFTypeID typeID
= CFGetTypeID(name
);
1020 if (CFEqual(oid
, kSecPolicyAppleSSL
) ||
1021 CFEqual(oid
, kSecPolicyAppleIPsec
)) {
1022 if (CFStringGetTypeID() == typeID
) {
1023 SecPolicySetOptionsValue(policyRef
, kSecPolicyCheckSSLHostname
, name
);
1025 else result
= errSecParam
;
1027 else if (CFEqual(oid
, kSecPolicyAppleEAP
)) {
1028 if ((CFStringGetTypeID() == typeID
) ||
1029 (CFArrayGetTypeID() == typeID
)) {
1030 SecPolicySetOptionsValue(policyRef
, kSecPolicyCheckEAPTrustedServerNames
, name
);
1032 else result
= errSecParam
;
1034 else if (CFEqual(oid
, kSecPolicyAppleSMIME
)) {
1035 if (CFStringGetTypeID() == typeID
) {
1036 SecPolicySetOptionsValue(policyRef
, kSecPolicyCheckEmail
, name
);
1038 else result
= errSecParam
;
1043 CFTypeRef client
= NULL
;
1044 if (CFDictionaryGetValueIfPresent(properties
, (const void *)kSecPolicyClient
,
1045 (const void **)&client
) && client
) {
1046 if (!(CFBooleanGetTypeID() == CFGetTypeID(client
))) {
1047 result
= errSecParam
;
1049 else if (CFEqual(client
, kCFBooleanTrue
)) {
1050 if (CFEqual(oid
, kSecPolicyAppleSSL
)) {
1051 SecPolicySetName(policyRef
, kSecPolicyNameSSLClient
);
1052 /* Set EKU checks for clients */
1053 CFMutableDictionaryRef newOptions
= CFDictionaryCreateMutableCopy(NULL
, 0, policyRef
->_options
);
1054 set_ssl_ekus(newOptions
, false);
1055 CFReleaseSafe(policyRef
->_options
);
1056 policyRef
->_options
= newOptions
;
1058 else if (CFEqual(oid
, kSecPolicyAppleIPsec
)) {
1059 SecPolicySetName(policyRef
, kSecPolicyNameIPSecClient
);
1061 else if (CFEqual(oid
, kSecPolicyNameEAPServer
)) {
1062 SecPolicySetName(policyRef
, kSecPolicyNameEAPClient
);
1063 /* Set EKU checks for clients */
1064 CFMutableDictionaryRef newOptions
= CFDictionaryCreateMutableCopy(NULL
, 0, policyRef
->_options
);
1065 set_ssl_ekus(newOptions
, false);
1066 CFReleaseSafe(policyRef
->_options
);
1067 policyRef
->_options
= newOptions
;
1071 if (CFEqual(oid
, kSecPolicyAppleSSL
)) {
1072 SecPolicySetName(policyRef
, kSecPolicyNameSSLServer
);
1073 /* Set EKU checks for servers */
1074 CFMutableDictionaryRef newOptions
= CFDictionaryCreateMutableCopy(NULL
, 0, policyRef
->_options
);
1075 set_ssl_ekus(newOptions
, true);
1076 CFReleaseSafe(policyRef
->_options
);
1077 policyRef
->_options
= newOptions
;
1079 else if (CFEqual(oid
, kSecPolicyAppleIPsec
)) {
1080 SecPolicySetName(policyRef
, kSecPolicyNameIPSecServer
);
1082 else if (CFEqual(oid
, kSecPolicyAppleEAP
)) {
1083 SecPolicySetName(policyRef
, kSecPolicyNameEAPServer
);
1084 /* Set EKU checks for servers */
1085 CFMutableDictionaryRef newOptions
= CFDictionaryCreateMutableCopy(NULL
, 0, policyRef
->_options
);
1086 set_ssl_ekus(newOptions
, true);
1087 CFReleaseSafe(policyRef
->_options
);
1088 policyRef
->_options
= newOptions
;
1097 static xpc_object_t
copy_xpc_policy_object(SecPolicyRef policy
);
1098 static bool append_policy_to_xpc_array(SecPolicyRef policy
, xpc_object_t xpc_policies
);
1099 extern xpc_object_t
copy_xpc_policies_array(CFArrayRef policies
);
1100 extern OSStatus
validate_array_of_items(CFArrayRef array
, CFStringRef arrayItemType
, CFTypeID itemTypeID
, bool required
);
1102 static xpc_object_t
copy_xpc_policy_object(SecPolicyRef policy
) {
1103 xpc_object_t xpc_policy
= NULL
;
1104 xpc_object_t data
[2] = { NULL
, NULL
};
1105 if (policy
->_oid
&& (CFGetTypeID(policy
->_oid
) == CFStringGetTypeID()) &&
1106 policy
->_name
&& (CFGetTypeID(policy
->_name
) == CFStringGetTypeID())) {
1107 /* These should really be different elements of the xpc array. But
1108 * SecPolicyCreateWithXPCObject previously checked the size via ==, which prevents
1109 * us from appending new information while maintaining backward compatibility.
1110 * Doing this makes the builders happy. */
1111 CFMutableStringRef oidAndName
= NULL
;
1112 oidAndName
= CFStringCreateMutableCopy(NULL
, 0, policy
->_oid
);
1114 CFStringAppend(oidAndName
, CFSTR("++"));
1115 CFStringAppend(oidAndName
, policy
->_name
);
1116 data
[0] = _CFXPCCreateXPCObjectFromCFObject(oidAndName
);
1117 CFReleaseNull(oidAndName
);
1119 data
[0] = _CFXPCCreateXPCObjectFromCFObject(policy
->_oid
);
1121 } else if (policy
->_oid
&& (CFGetTypeID(policy
->_oid
) == CFStringGetTypeID())) {
1122 data
[0] = _CFXPCCreateXPCObjectFromCFObject(policy
->_oid
);
1124 secerror("policy 0x%lX has no _oid", (uintptr_t)policy
);
1126 if (policy
->_options
&& (CFGetTypeID(policy
->_options
) == CFDictionaryGetTypeID())) {
1127 data
[1] = _CFXPCCreateXPCObjectFromCFObject(policy
->_options
);
1129 secerror("policy 0x%lX has no _options", (uintptr_t)policy
);
1131 xpc_policy
= xpc_array_create(data
, array_size(data
));
1132 if (data
[0]) xpc_release(data
[0]);
1133 if (data
[1]) xpc_release(data
[1]);
1137 static bool append_policy_to_xpc_array(SecPolicyRef policy
, xpc_object_t xpc_policies
) {
1139 return true; // NOOP
1141 xpc_object_t xpc_policy
= copy_xpc_policy_object(policy
);
1145 xpc_array_append_value(xpc_policies
, xpc_policy
);
1146 xpc_release(xpc_policy
);
1150 xpc_object_t
copy_xpc_policies_array(CFArrayRef policies
) {
1151 xpc_object_t xpc_policies
= xpc_array_create(NULL
, 0);
1152 if (!xpc_policies
) {
1155 validate_array_of_items(policies
, CFSTR("policy"), SecPolicyGetTypeID(), true);
1156 CFIndex ix
, count
= CFArrayGetCount(policies
);
1157 for (ix
= 0; ix
< count
; ++ix
) {
1158 SecPolicyRef policy
= (SecPolicyRef
) CFArrayGetValueAtIndex(policies
, ix
);
1159 #if SECTRUST_VERBOSE_DEBUG
1160 CFDictionaryRef props
= SecPolicyCopyProperties(policy
);
1161 secerror("idx=%d of %d; policy=0x%lX properties=%@", (int)ix
, (int)count
, (uintptr_t)policy
, props
);
1162 CFReleaseSafe(props
);
1164 if (!append_policy_to_xpc_array(policy
, xpc_policies
)) {
1165 xpc_release(xpc_policies
);
1166 xpc_policies
= NULL
;
1170 return xpc_policies
;
1173 static xpc_object_t
SecPolicyCopyXPCObject(SecPolicyRef policy
, CFErrorRef
*error
) {
1174 xpc_object_t xpc_policy
= NULL
;
1175 xpc_object_t data
[2] = {};
1176 CFMutableStringRef oidAndName
= NULL
;
1177 oidAndName
= CFStringCreateMutableCopy(NULL
, 0, policy
->_oid
);
1179 if (policy
->_name
) {
1180 CFStringAppend(oidAndName
, CFSTR("++"));
1181 CFStringAppend(oidAndName
, policy
->_name
);
1184 require_action_quiet(data
[0] = _CFXPCCreateXPCObjectFromCFObject(oidAndName
), exit
,
1185 SecError(errSecParam
, error
,
1186 CFSTR("failed to create xpc_object from policy oid and name")));
1188 require_action_quiet(data
[0] = _CFXPCCreateXPCObjectFromCFObject(policy
->_oid
), exit
,
1189 SecError(errSecParam
, error
, CFSTR("failed to create xpc_object from policy oid")));
1191 require_action_quiet(data
[1] = _CFXPCCreateXPCObjectFromCFObject(policy
->_options
), exit
,
1192 SecError(errSecParam
, error
, CFSTR("failed to create xpc_object from policy options")));
1193 require_action_quiet(xpc_policy
= xpc_array_create(data
, array_size(data
)), exit
,
1194 SecError(errSecAllocate
, error
, CFSTR("failed to create xpc_array for policy")));
1197 if (data
[0]) xpc_release(data
[0]);
1198 if (data
[1]) xpc_release(data
[1]);
1199 CFReleaseNull(oidAndName
);
1203 static bool SecPolicyAppendToXPCArray(SecPolicyRef policy
, xpc_object_t policies
, CFErrorRef
*error
) {
1205 return true; // NOOP
1207 xpc_object_t xpc_policy
= SecPolicyCopyXPCObject(policy
, error
);
1211 xpc_array_append_value(policies
, xpc_policy
);
1212 xpc_release(xpc_policy
);
1216 xpc_object_t
SecPolicyArrayCopyXPCArray(CFArrayRef policies
, CFErrorRef
*error
) {
1217 xpc_object_t xpc_policies
;
1218 require_action_quiet(xpc_policies
= xpc_array_create(NULL
, 0), exit
,
1219 SecError(errSecAllocate
, error
, CFSTR("failed to create xpc_array")));
1220 CFIndex ix
, count
= CFArrayGetCount(policies
);
1221 for (ix
= 0; ix
< count
; ++ix
) {
1222 if (!SecPolicyAppendToXPCArray((SecPolicyRef
)CFArrayGetValueAtIndex(policies
, ix
), xpc_policies
, error
)) {
1223 xpc_release(xpc_policies
);
1228 return xpc_policies
;
1231 static OSStatus
parseOidAndName(CFStringRef oidAndName
, CFStringRef
*oid
, CFStringRef
*name
) {
1232 OSStatus result
= errSecSuccess
;
1233 CFStringRef partial
= NULL
;
1235 CFRange delimiter
= CFStringFind(oidAndName
, CFSTR("++"), 0);
1236 if (delimiter
.length
!= 2) {
1240 /* get first half: oid */
1241 partial
= CFStringCreateWithSubstring(NULL
, oidAndName
, CFRangeMake(0, delimiter
.location
));
1242 if (oid
) { *oid
= CFRetainSafe(partial
); }
1243 CFReleaseNull(partial
);
1245 /* get second half: name */
1246 if (delimiter
.location
+ 2 >= CFStringGetLength(oidAndName
)) {
1247 return errSecSuccess
; // name is optional
1249 CFRange nameRange
= CFRangeMake(delimiter
.location
+2,
1250 CFStringGetLength(oidAndName
) - delimiter
.location
- 2);
1251 partial
= CFStringCreateWithSubstring(NULL
, oidAndName
, nameRange
);
1252 if (name
) { *name
= CFRetainSafe(partial
); }
1253 CFReleaseNull(partial
);
1257 static SecPolicyRef
SecPolicyCreateWithXPCObject(xpc_object_t xpc_policy
, CFErrorRef
*error
) {
1258 SecPolicyRef policy
= NULL
;
1259 CFTypeRef oidAndName
= NULL
;
1260 CFStringRef oid
= NULL
;
1261 CFStringRef name
= NULL
;
1262 CFTypeRef options
= NULL
;
1264 require_action_quiet(xpc_policy
, exit
, SecError(errSecParam
, error
, CFSTR("policy xpc value is NULL")));
1265 require_action_quiet(xpc_get_type(xpc_policy
) == XPC_TYPE_ARRAY
, exit
, SecError(errSecDecode
, error
, CFSTR("policy xpc value is not an array")));
1266 require_action_quiet(xpc_array_get_count(xpc_policy
) >= 2, exit
, SecError(errSecDecode
, error
, CFSTR("policy xpc array count < 2")));
1267 oidAndName
= _CFXPCCreateCFObjectFromXPCObject(xpc_array_get_value(xpc_policy
, 0));
1268 require_action_quiet(isString(oidAndName
), exit
,
1269 SecError(errSecParam
, error
, CFSTR("failed to convert xpc policy[0]=%@ to CFString"), oidAndName
));
1270 options
= _CFXPCCreateCFObjectFromXPCObject(xpc_array_get_value(xpc_policy
, 1));
1271 require_action_quiet(isDictionary(options
), exit
,
1272 SecError(errSecParam
, error
, CFSTR("failed to convert xpc policy[1]=%@ to CFDictionary"), options
));
1273 require_noerr_action_quiet(parseOidAndName(oidAndName
, &oid
, &name
), exit
,
1274 SecError(errSecParam
, error
, CFSTR("failed to convert combined %@ to name and oid"), oidAndName
));
1275 require_action_quiet(policy
= SecPolicyCreate(oid
, name
, options
), exit
,
1276 SecError(errSecDecode
, error
, CFSTR("Failed to create policy")));
1279 CFReleaseSafe(oidAndName
);
1281 CFReleaseSafe(name
);
1282 CFReleaseSafe(options
);
1286 CFArrayRef
SecPolicyXPCArrayCopyArray(xpc_object_t xpc_policies
, CFErrorRef
*error
) {
1287 CFMutableArrayRef policies
= NULL
;
1288 require_action_quiet(xpc_get_type(xpc_policies
) == XPC_TYPE_ARRAY
, exit
,
1289 SecError(errSecParam
, error
, CFSTR("policies xpc value is not an array")));
1290 size_t count
= xpc_array_get_count(xpc_policies
);
1291 require_action_quiet(policies
= CFArrayCreateMutable(kCFAllocatorDefault
, count
, &kCFTypeArrayCallBacks
), exit
,
1292 SecError(errSecAllocate
, error
, CFSTR("failed to create CFArray of capacity %zu"), count
));
1295 for (ix
= 0; ix
< count
; ++ix
) {
1296 SecPolicyRef policy
= SecPolicyCreateWithXPCObject(xpc_array_get_value(xpc_policies
, ix
), error
);
1298 CFRelease(policies
);
1301 CFArraySetValueAtIndex(policies
, ix
, policy
);
1310 static SEC_CONST_DECL (kSecPolicyOptions
, "policyOptions");
1312 static SecPolicyRef
SecPolicyCreateWithDictionary(CFDictionaryRef dict
) {
1313 SecPolicyRef policy
= NULL
;
1314 CFStringRef oid
= (CFStringRef
)CFDictionaryGetValue(dict
, kSecPolicyOid
);
1315 require_quiet(isString(oid
), errOut
);
1316 CFDictionaryRef options
= (CFDictionaryRef
)CFDictionaryGetValue(dict
, kSecPolicyOptions
);
1317 require_quiet(isDictionary(options
), errOut
);
1318 CFStringRef name
= (CFStringRef
)CFDictionaryGetValue(dict
, kSecPolicyPolicyName
);
1319 policy
= SecPolicyCreate(oid
, name
, options
);
1324 static void deserializePolicy(const void *value
, void *context
) {
1325 CFDictionaryRef policyDict
= (CFDictionaryRef
)value
;
1326 if (isDictionary(policyDict
)) {
1327 CFTypeRef deserializedPolicy
= SecPolicyCreateWithDictionary(policyDict
);
1328 if (deserializedPolicy
) {
1329 CFArrayAppendValue((CFMutableArrayRef
)context
, deserializedPolicy
);
1330 CFRelease(deserializedPolicy
);
1335 CFArrayRef
SecPolicyArrayCreateDeserialized(CFArrayRef serializedPolicies
) {
1336 CFMutableArrayRef result
= NULL
;
1337 require_quiet(isArray(serializedPolicies
), errOut
);
1338 CFIndex count
= CFArrayGetCount(serializedPolicies
);
1339 result
= CFArrayCreateMutable(kCFAllocatorDefault
, count
, &kCFTypeArrayCallBacks
);
1340 CFRange all_policies
= { 0, count
};
1341 CFArrayApplyFunction(serializedPolicies
, all_policies
, deserializePolicy
, result
);
1346 static CFDictionaryRef
SecPolicyCreateDictionary(SecPolicyRef policy
) {
1347 CFMutableDictionaryRef dict
= NULL
;
1348 dict
= CFDictionaryCreateMutable(NULL
, 3, &kCFTypeDictionaryKeyCallBacks
,
1349 &kCFTypeDictionaryValueCallBacks
);
1350 CFDictionaryAddValue(dict
, kSecPolicyOid
, policy
->_oid
);
1351 CFDictionaryAddValue(dict
, kSecPolicyOptions
, policy
->_options
);
1352 if (policy
->_name
) {
1353 CFDictionaryAddValue(dict
, kSecPolicyPolicyName
, policy
->_name
);
1358 static void serializePolicy(const void *value
, void *context
) {
1359 SecPolicyRef policy
= (SecPolicyRef
)value
;
1360 if (policy
&& SecPolicyGetTypeID() == CFGetTypeID(policy
)) {
1361 CFDictionaryRef serializedPolicy
= SecPolicyCreateDictionary(policy
);
1362 if (serializedPolicy
) {
1363 CFArrayAppendValue((CFMutableArrayRef
)context
, serializedPolicy
);
1364 CFRelease(serializedPolicy
);
1369 CFArrayRef
SecPolicyArrayCreateSerialized(CFArrayRef policies
) {
1370 CFMutableArrayRef result
= NULL
;
1371 require_quiet(isArray(policies
), errOut
);
1372 CFIndex count
= CFArrayGetCount(policies
);
1373 result
= CFArrayCreateMutable(NULL
, count
, &kCFTypeArrayCallBacks
);
1374 CFRange all_policies
= { 0, count
};
1375 CFArrayApplyFunction(policies
, all_policies
, serializePolicy
, result
);
1380 static void add_element(CFMutableDictionaryRef options
, CFStringRef key
,
1382 CFTypeRef old_value
= CFDictionaryGetValue(options
, key
);
1384 CFMutableArrayRef array
;
1385 if (CFGetTypeID(old_value
) == CFArrayGetTypeID()) {
1386 array
= (CFMutableArrayRef
)old_value
;
1388 array
= CFArrayCreateMutable(kCFAllocatorDefault
, 0,
1389 &kCFTypeArrayCallBacks
);
1390 CFArrayAppendValue(array
, old_value
);
1391 CFDictionarySetValue(options
, key
, array
);
1394 CFArrayAppendValue(array
, value
);
1396 CFDictionaryAddValue(options
, key
, value
);
1400 static void add_eku(CFMutableDictionaryRef options
, const DERItem
*ekuOid
) {
1401 CFDataRef eku
= CFDataCreate(kCFAllocatorDefault
,
1402 ekuOid
? ekuOid
->data
: NULL
,
1403 ekuOid
? ekuOid
->length
: 0);
1405 add_element(options
, kSecPolicyCheckExtendedKeyUsage
, eku
);
1410 static void add_eku_string(CFMutableDictionaryRef options
, CFStringRef ekuOid
) {
1412 add_element(options
, kSecPolicyCheckExtendedKeyUsage
, ekuOid
);
1416 static void set_ssl_ekus(CFMutableDictionaryRef options
, bool server
) {
1417 CFDictionaryRemoveValue(options
, kSecPolicyCheckExtendedKeyUsage
);
1419 /* If server and EKU ext present then EKU ext should contain one of
1420 ServerAuth or ExtendedKeyUsageAny or NetscapeSGC or MicrosoftSGC.
1421 else if !server and EKU ext present then EKU ext should contain one of
1422 ClientAuth or ExtendedKeyUsageAny. */
1424 /* We always allow certificates that specify oidAnyExtendedKeyUsage. */
1425 add_eku(options
, NULL
); /* eku extension is optional */
1426 add_eku(options
, &oidAnyExtendedKeyUsage
);
1428 add_eku(options
, &oidExtendedKeyUsageServerAuth
);
1429 add_eku(options
, &oidExtendedKeyUsageMicrosoftSGC
);
1430 add_eku(options
, &oidExtendedKeyUsageNetscapeSGC
);
1432 add_eku(options
, &oidExtendedKeyUsageClientAuth
);
1436 static void add_ku(CFMutableDictionaryRef options
, SecKeyUsage keyUsage
) {
1437 SInt32 dku
= keyUsage
;
1438 CFNumberRef ku
= CFNumberCreate(kCFAllocatorDefault
, kCFNumberSInt32Type
,
1441 add_element(options
, kSecPolicyCheckKeyUsage
, ku
);
1446 static void add_oid(CFMutableDictionaryRef options
, CFStringRef policy_key
, const DERItem
*oid
) {
1447 CFDataRef oid_data
= CFDataCreate(kCFAllocatorDefault
,
1448 oid
? oid
->data
: NULL
,
1449 oid
? oid
->length
: 0);
1451 add_element(options
, policy_key
, oid_data
);
1452 CFRelease(oid_data
);
1456 static void add_leaf_marker_value(CFMutableDictionaryRef options
, const DERItem
*markerOid
, CFStringRef string_value
) {
1458 CFTypeRef policyData
= NULL
;
1460 if (NULL
== string_value
) {
1461 policyData
= CFDataCreate(kCFAllocatorDefault
,
1462 markerOid
? markerOid
->data
: NULL
,
1463 markerOid
? markerOid
->length
: 0);
1465 CFStringRef oid_as_string
= SecDERItemCopyOIDDecimalRepresentation(kCFAllocatorDefault
, markerOid
);
1467 const void *key
[1] = { oid_as_string
};
1468 const void *value
[1] = { string_value
};
1469 policyData
= CFDictionaryCreate(kCFAllocatorDefault
,
1471 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
1472 CFReleaseNull(oid_as_string
);
1475 add_element(options
, kSecPolicyCheckLeafMarkerOid
, policyData
);
1477 CFReleaseNull(policyData
);
1481 static void add_leaf_marker(CFMutableDictionaryRef options
, const DERItem
*markerOid
) {
1482 add_leaf_marker_value(options
, markerOid
, NULL
);
1485 static void add_leaf_marker_value_string(CFMutableDictionaryRef options
, CFStringRef markerOid
, CFStringRef string_value
) {
1486 if (NULL
== string_value
) {
1487 add_element(options
, kSecPolicyCheckLeafMarkerOid
, markerOid
);
1489 CFDictionaryRef policyData
= NULL
;
1490 const void *key
[1] = { markerOid
};
1491 const void *value
[1] = { string_value
};
1492 policyData
= CFDictionaryCreate(kCFAllocatorDefault
,
1494 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
1495 add_element(options
, kSecPolicyCheckLeafMarkerOid
, policyData
);
1497 CFReleaseNull(policyData
);
1501 static void add_leaf_marker_string(CFMutableDictionaryRef options
, CFStringRef markerOid
) {
1502 add_leaf_marker_value_string(options
, markerOid
, NULL
);
1505 static void add_intermediate_marker_value_string(CFMutableDictionaryRef options
, CFStringRef markerOid
, CFStringRef string_value
) {
1506 if (NULL
== string_value
) {
1507 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, markerOid
);
1509 CFDictionaryRef policyData
= NULL
;
1510 const void *key
[1] = { markerOid
};
1511 const void *value
[1] = { string_value
};
1512 policyData
= CFDictionaryCreate(kCFAllocatorDefault
,
1514 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
1515 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, policyData
);
1517 CFReleaseNull(policyData
);
1521 static void add_certificate_policy_oid(CFMutableDictionaryRef options
, const DERItem
*certificatePolicyOid
) {
1522 CFTypeRef certificatePolicyData
= NULL
;
1523 certificatePolicyData
= CFDataCreate(kCFAllocatorDefault
,
1524 certificatePolicyOid
? certificatePolicyOid
->data
: NULL
,
1525 certificatePolicyOid
? certificatePolicyOid
->length
: 0);
1526 if (certificatePolicyData
) {
1527 add_element(options
, kSecPolicyCheckCertificatePolicy
, certificatePolicyData
);
1528 CFRelease(certificatePolicyData
);
1532 static void add_certificate_policy_oid_string(CFMutableDictionaryRef options
, CFStringRef certificatePolicyOid
) {
1533 if (certificatePolicyOid
) {
1534 add_element(options
, kSecPolicyCheckCertificatePolicy
, certificatePolicyOid
);
1539 // Routines for adding dictionary entries for policies.
1542 // X.509, but missing validity requirements.
1543 static void SecPolicyAddBasicCertOptions(CFMutableDictionaryRef options
)
1545 //CFDictionaryAddValue(options, kSecPolicyCheckBasicCertificateProcessing, kCFBooleanTrue);
1546 // Happens automatically in SecPVCPathChecks
1547 CFDictionaryAddValue(options
, kSecPolicyCheckCriticalExtensions
, kCFBooleanTrue
);
1548 CFDictionaryAddValue(options
, kSecPolicyCheckIdLinkage
, kCFBooleanTrue
);
1549 CFDictionaryAddValue(options
, kSecPolicyCheckBasicConstraints
, kCFBooleanTrue
);
1550 CFDictionaryAddValue(options
, kSecPolicyCheckNonEmptySubject
, kCFBooleanTrue
);
1551 CFDictionaryAddValue(options
, kSecPolicyCheckQualifiedCertStatements
, kCFBooleanTrue
);
1552 CFDictionaryAddValue(options
, kSecPolicyCheckWeakIntermediates
, kCFBooleanTrue
);
1553 CFDictionaryAddValue(options
, kSecPolicyCheckWeakLeaf
, kCFBooleanTrue
);
1554 CFDictionaryAddValue(options
, kSecPolicyCheckWeakRoot
, kCFBooleanTrue
);
1557 static void SecPolicyAddBasicX509Options(CFMutableDictionaryRef options
)
1559 SecPolicyAddBasicCertOptions(options
);
1560 CFDictionaryAddValue(options
, kSecPolicyCheckValidIntermediates
, kCFBooleanTrue
);
1561 CFDictionaryAddValue(options
, kSecPolicyCheckValidLeaf
, kCFBooleanTrue
);
1562 CFDictionaryAddValue(options
, kSecPolicyCheckValidRoot
, kCFBooleanTrue
);
1564 // Make sure that black and gray leaf checks are performed for basic X509 chain building
1565 CFDictionaryAddValue(options
, kSecPolicyCheckBlackListedLeaf
, kCFBooleanTrue
);
1566 CFDictionaryAddValue(options
, kSecPolicyCheckGrayListedLeaf
, kCFBooleanTrue
);
1569 static bool SecPolicyAddChainLengthOptions(CFMutableDictionaryRef options
, CFIndex length
)
1571 bool result
= false;
1572 CFNumberRef lengthAsCF
= NULL
;
1574 require(lengthAsCF
= CFNumberCreate(kCFAllocatorDefault
,
1575 kCFNumberCFIndexType
, &length
), errOut
);
1576 CFDictionaryAddValue(options
, kSecPolicyCheckChainLength
, lengthAsCF
);
1581 CFReleaseSafe(lengthAsCF
);
1585 static bool SecPolicyAddAnchorSHA1Options(CFMutableDictionaryRef options
,
1586 const UInt8 anchorSha1
[kSecPolicySHA1Size
])
1588 bool success
= false;
1589 CFDataRef anchorData
= NULL
;
1591 require(anchorData
= CFDataCreate(kCFAllocatorDefault
, anchorSha1
, kSecPolicySHA1Size
), errOut
);
1592 add_element(options
, kSecPolicyCheckAnchorSHA1
, anchorData
);
1597 CFReleaseSafe(anchorData
);
1601 static bool SecPolicyAddAnchorSHA256Options(CFMutableDictionaryRef options
,
1602 const UInt8 anchorSha1
[kSecPolicySHA256Size
])
1604 bool success
= false;
1605 CFDataRef anchorData
= NULL
;
1607 require(anchorData
= CFDataCreate(kCFAllocatorDefault
, anchorSha1
, kSecPolicySHA256Size
), errOut
);
1608 add_element(options
, kSecPolicyCheckAnchorSHA256
, anchorData
);
1613 CFReleaseSafe(anchorData
);
1617 static bool isAppleOid(CFStringRef oid
) {
1618 if (!SecCertificateIsOidString(oid
)) {
1621 if (CFStringHasPrefix(oid
, CFSTR("1.2.840.113635"))) {
1627 static bool allowTestHierarchyForPolicy(CFStringRef policyName
) {
1629 CFStringRef setting
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("ApplePinningAllowTestCerts%@"), policyName
);
1630 require(setting
, fail
);
1631 if (CFPreferencesGetAppBooleanValue(setting
, CFSTR("com.apple.security"), NULL
)) {
1639 static bool SecPolicyAddAppleAnchorOptions(CFMutableDictionaryRef options
, CFStringRef policyName
)
1641 CFMutableDictionaryRef appleAnchorOptions
;
1642 appleAnchorOptions
= CFDictionaryCreateMutableForCFTypes(NULL
);
1643 if (!appleAnchorOptions
) {
1647 if (allowTestHierarchyForPolicy(policyName
)) {
1648 CFDictionarySetValue(appleAnchorOptions
,
1649 kSecPolicyAppleAnchorIncludeTestRoots
, kCFBooleanTrue
);
1651 add_element(options
, kSecPolicyCheckAnchorApple
, appleAnchorOptions
);
1652 CFReleaseSafe(appleAnchorOptions
);
1657 // MARK: Policy Creation Functions
1659 SecPolicyRef
SecPolicyCreateBasicX509(void) {
1660 CFMutableDictionaryRef options
= NULL
;
1661 SecPolicyRef result
= NULL
;
1663 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1664 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1666 SecPolicyAddBasicX509Options(options
);
1667 CFDictionaryAddValue(options
, kSecPolicyCheckNoNetworkAccess
,
1670 require(result
= SecPolicyCreate(kSecPolicyAppleX509Basic
, kSecPolicyNameBasicX509
, options
), errOut
);
1673 CFReleaseSafe(options
);
1674 return (SecPolicyRef _Nonnull
)result
;
1677 SecPolicyRef
SecPolicyCreateSSL(Boolean server
, CFStringRef hostname
) {
1678 CFMutableDictionaryRef options
= NULL
;
1679 SecPolicyRef result
= NULL
;
1681 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1682 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1684 SecPolicyAddBasicX509Options(options
);
1687 CFDictionaryAddValue(options
, kSecPolicyCheckSSLHostname
, hostname
);
1690 CFDictionaryAddValue(options
, kSecPolicyCheckBlackListedLeaf
, kCFBooleanTrue
);
1691 CFDictionaryAddValue(options
, kSecPolicyCheckGrayListedLeaf
, kCFBooleanTrue
);
1693 set_ssl_ekus(options
, server
);
1695 require(result
= SecPolicyCreate(kSecPolicyAppleSSL
,
1696 server
? kSecPolicyNameSSLServer
: kSecPolicyNameSSLClient
,
1700 CFReleaseSafe(options
);
1701 return (SecPolicyRef _Nonnull
)result
;
1704 SecPolicyRef
SecPolicyCreateApplePinned(CFStringRef policyName
, CFStringRef intermediateMarkerOID
, CFStringRef leafMarkerOID
) {
1705 CFMutableDictionaryRef options
= NULL
;
1706 CFDictionaryRef keySizes
= NULL
;
1707 CFNumberRef rsaSize
= NULL
, ecSize
= NULL
;
1708 SecPolicyRef result
= NULL
;
1710 if (!policyName
|| !intermediateMarkerOID
|| !leafMarkerOID
) {
1714 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1715 &kCFTypeDictionaryKeyCallBacks
,
1716 &kCFTypeDictionaryValueCallBacks
), errOut
);
1718 SecPolicyAddBasicX509Options(options
);
1720 /* Anchored to the Apple Roots */
1721 require(SecPolicyAddAppleAnchorOptions(options
, policyName
), errOut
);
1723 /* Exactly 3 certs in the chain */
1724 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1726 /* Intermediate marker OID matches input OID */
1727 if (!isAppleOid(intermediateMarkerOID
)) {
1728 secwarning("creating an Apple pinning policy with a non-Apple OID: %@", intermediateMarkerOID
);
1730 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, intermediateMarkerOID
);
1732 /* Leaf marker OID matches input OID */
1733 if (!isAppleOid(leafMarkerOID
)) {
1734 secwarning("creating an Apple pinning policy with a non-Apple OID: %@", leafMarkerOID
);
1736 add_leaf_marker_string(options
, leafMarkerOID
);
1738 /* Check revocation using any available method */
1739 add_element(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
1741 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
1742 require(rsaSize
= CFNumberCreateWithCFIndex(NULL
, 2048), errOut
);
1743 require(ecSize
= CFNumberCreateWithCFIndex(NULL
, 256), errOut
);
1744 const void *keys
[] = { kSecAttrKeyTypeRSA
, kSecAttrKeyTypeEC
};
1745 const void *values
[] = { rsaSize
, ecSize
};
1746 require(keySizes
= CFDictionaryCreate(NULL
, keys
, values
, 2,
1747 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1748 add_element(options
, kSecPolicyCheckKeySize
, keySizes
);
1750 require(result
= SecPolicyCreate(kSecPolicyAppleGenericApplePinned
,
1751 policyName
, options
), errOut
);
1754 CFReleaseSafe(options
);
1755 CFReleaseSafe(keySizes
);
1756 CFReleaseSafe(rsaSize
);
1757 CFReleaseSafe(ecSize
);
1762 requireUATPinning(CFStringRef service
)
1764 bool pinningRequired
= true;
1766 if (SecIsInternalRelease()) {
1767 CFStringRef setting
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("AppleServerAuthenticationNoPinning%@"), service
);
1768 require(setting
, fail
);
1769 if (CFPreferencesGetAppBooleanValue(setting
, CFSTR("com.apple.Security"), NULL
))
1770 pinningRequired
= false;
1774 return pinningRequired
;
1777 SecPolicyRef
SecPolicyCreateAppleSSLPinned(CFStringRef policyName
, CFStringRef hostname
,
1778 CFStringRef intermediateMarkerOID
, CFStringRef leafMarkerOID
) {
1779 CFMutableDictionaryRef options
= NULL
;
1780 SecPolicyRef result
= NULL
;
1782 if (!policyName
|| !hostname
|| !leafMarkerOID
) {
1786 if (requireUATPinning(policyName
)) {
1787 if (intermediateMarkerOID
) {
1788 require(result
= SecPolicyCreateApplePinned(policyName
, intermediateMarkerOID
, leafMarkerOID
), errOut
);
1790 require(result
= SecPolicyCreateApplePinned(policyName
, CFSTR("1.2.840.113635.100.6.2.12"), leafMarkerOID
), errOut
);
1793 require_action(options
= CFDictionaryCreateMutableCopy(NULL
, 0, result
->_options
), errOut
, CFReleaseNull(result
));
1795 /* ServerAuth EKU is in leaf cert */
1796 add_eku_string(options
, CFSTR("1.3.6.1.5.5.7.3.1"));
1798 /* Hostname is in leaf cert */
1799 add_element(options
, kSecPolicyCheckSSLHostname
, hostname
);
1801 /* New leaf marker OID format */
1802 add_leaf_marker_value_string(options
, CFSTR("1.2.840.113635.100.6.48.1"), leafMarkerOID
);
1804 CFReleaseSafe(result
->_options
);
1805 result
->_options
= CFRetainSafe(options
);
1807 result
= SecPolicyCreateSSL(true, hostname
);
1810 SecPolicySetOid(result
, kSecPolicyAppleGenericAppleSSLPinned
);
1813 CFReleaseSafe(options
);
1817 SecPolicyRef
SecPolicyCreateiPhoneActivation(void) {
1818 CFMutableDictionaryRef options
= NULL
;
1819 SecPolicyRef result
= NULL
;
1821 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1822 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1824 SecPolicyAddBasicCertOptions(options
);
1827 CFDictionaryAddValue(options
, kSecPolicyCheckKeyUsage
,
1829 CFDictionaryAddValue(options
, kSecPolicyCheckExtendedKeyUsage
,
1833 /* Basic X.509 policy with the additional requirements that the chain
1834 length is 3, it's anchored at the AppleCA and the leaf certificate
1835 has issuer "Apple iPhone Certification Authority" and
1836 subject "Apple iPhone Activation" for the common name. */
1837 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
1838 CFSTR("Apple iPhone Certification Authority"));
1839 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
,
1840 CFSTR("Apple iPhone Activation"));
1842 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
1843 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameiPhoneActivation
), errOut
);
1845 require(result
= SecPolicyCreate(kSecPolicyAppleiPhoneActivation
,
1846 kSecPolicyNameiPhoneActivation
, options
),
1850 CFReleaseSafe(options
);
1854 SecPolicyRef
SecPolicyCreateiPhoneDeviceCertificate(void) {
1855 CFMutableDictionaryRef options
= NULL
;
1856 SecPolicyRef result
= NULL
;
1858 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1859 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1861 SecPolicyAddBasicCertOptions(options
);
1864 CFDictionaryAddValue(options
, kSecPolicyCheckKeyUsage
,
1866 CFDictionaryAddValue(options
, kSecPolicyCheckExtendedKeyUsage
,
1870 /* Basic X.509 policy with the additional requirements that the chain
1871 length is 4, it's anchored at the AppleCA and the first intermediate
1872 has the subject "Apple iPhone Device CA". */
1873 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
1874 CFSTR("Apple iPhone Device CA"));
1876 require(SecPolicyAddChainLengthOptions(options
, 4), errOut
);
1877 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameiPhoneDeviceCertificate
), errOut
);
1879 require(result
= SecPolicyCreate(kSecPolicyAppleiPhoneDeviceCertificate
,
1880 kSecPolicyNameiPhoneDeviceCertificate
, options
),
1884 CFReleaseSafe(options
);
1888 SecPolicyRef
SecPolicyCreateFactoryDeviceCertificate(void) {
1889 CFMutableDictionaryRef options
= NULL
;
1890 SecPolicyRef result
= NULL
;
1892 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1893 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1895 SecPolicyAddBasicCertOptions(options
);
1898 CFDictionaryAddValue(options
, kSecPolicyCheckKeyUsage
,
1900 CFDictionaryAddValue(options
, kSecPolicyCheckExtendedKeyUsage
,
1904 /* Basic X.509 policy with the additional requirements that the chain
1905 is anchored at the factory device certificate issuer. */
1906 require(SecPolicyAddAnchorSHA1Options(options
, kFactoryDeviceCASHA1
), errOut
);
1908 require(result
= SecPolicyCreate(kSecPolicyAppleFactoryDeviceCertificate
,
1909 kSecPolicyNameFactoryDeviceCertificate
, options
),
1913 CFReleaseSafe(options
);
1917 SecPolicyRef
SecPolicyCreateiAP(void) {
1918 CFMutableDictionaryRef options
= NULL
;
1919 SecPolicyRef result
= NULL
;
1920 CFTimeZoneRef tz
= NULL
;
1921 CFDateRef date
= NULL
;
1923 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1924 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1926 SecPolicyAddBasicCertOptions(options
);
1928 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonNamePrefix
,
1931 date
= CFDateCreateForGregorianZuluDay(NULL
, 2006, 5, 31);
1932 CFDictionaryAddValue(options
, kSecPolicyCheckNotValidBefore
, date
);
1934 require(result
= SecPolicyCreate(kSecPolicyAppleiAP
,
1935 kSecPolicyNameiAP
, options
),
1939 CFReleaseSafe(date
);
1941 CFReleaseSafe(options
);
1945 SecPolicyRef
SecPolicyCreateiTunesStoreURLBag(void) {
1946 CFMutableDictionaryRef options
= NULL
;
1947 SecPolicyRef result
= NULL
;
1950 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1951 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1953 SecPolicyAddBasicCertOptions(options
);
1955 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectOrganization
,
1956 CFSTR("Apple Inc."));
1957 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
,
1958 CFSTR("iTunes Store URL Bag"));
1960 require(SecPolicyAddChainLengthOptions(options
, 2), errOut
);
1961 require(SecPolicyAddAnchorSHA1Options(options
, kITMSCASHA1
), errOut
);
1963 require(result
= SecPolicyCreate(kSecPolicyAppleiTunesStoreURLBag
,
1964 kSecPolicyNameiTunesStoreURLBag
, options
), errOut
);
1967 CFReleaseSafe(options
);
1971 SecPolicyRef
SecPolicyCreateEAP(Boolean server
, CFArrayRef trustedServerNames
) {
1972 CFMutableDictionaryRef options
= NULL
;
1973 SecPolicyRef result
= NULL
;
1975 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
1976 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
1978 SecPolicyAddBasicX509Options(options
);
1980 /* Since EAP is used to setup the network we don't want evaluation
1981 using this policy to access the network. */
1982 CFDictionaryAddValue(options
, kSecPolicyCheckNoNetworkAccess
,
1985 if (trustedServerNames
) {
1986 CFDictionaryAddValue(options
, kSecPolicyCheckEAPTrustedServerNames
, trustedServerNames
);
1989 /* We need to check for EKU per rdar://22206018 */
1990 set_ssl_ekus(options
, server
);
1992 require(result
= SecPolicyCreate(kSecPolicyAppleEAP
,
1993 server
? kSecPolicyNameEAPServer
: kSecPolicyNameEAPClient
,
1997 CFReleaseSafe(options
);
2001 SecPolicyRef
SecPolicyCreateIPSec(Boolean server
, CFStringRef hostname
) {
2002 CFMutableDictionaryRef options
= NULL
;
2003 SecPolicyRef result
= NULL
;
2005 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2006 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2008 SecPolicyAddBasicX509Options(options
);
2011 CFDictionaryAddValue(options
, kSecPolicyCheckSSLHostname
, hostname
);
2014 /* Require oidExtendedKeyUsageIPSec if Extended Keyusage Extention is
2016 /* Per <rdar://problem/6843827> Cisco VPN Certificate compatibility issue.
2017 We don't check the EKU for IPSec certs for now. If we do add eku
2018 checking back in the future, we should probably also accept the
2020 ipsecEndSystem 1.3.6.1.5.5.7.3.5
2022 ipsecTunnel 1.3.6.1.5.5.7.3.6
2023 ipsecUser 1.3.6.1.5.5.7.3.7
2025 //add_eku(options, NULL); /* eku extension is optional */
2026 //add_eku(options, &oidAnyExtendedKeyUsage);
2027 //add_eku(options, &oidExtendedKeyUsageIPSec);
2029 require(result
= SecPolicyCreate(kSecPolicyAppleIPsec
,
2030 server
? kSecPolicyNameIPSecServer
: kSecPolicyNameIPSecClient
,
2034 CFReleaseSafe(options
);
2038 SecPolicyRef
SecPolicyCreateiPhoneApplicationSigning(void) {
2039 CFMutableDictionaryRef options
= NULL
, appleAnchorOptions
= NULL
;
2040 SecPolicyRef result
= NULL
;
2042 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2043 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2045 SecPolicyAddBasicCertOptions(options
);
2047 appleAnchorOptions
= CFDictionaryCreateMutableForCFTypes(NULL
);
2048 require(appleAnchorOptions
, errOut
);
2050 if (allowTestHierarchyForPolicy(kSecPolicyNameiPhoneApplicationSigning
)) {
2051 /* Allow a test hierarchy-signed cert with prod name/OIDs */
2052 CFDictionarySetValue(appleAnchorOptions
,
2053 kSecPolicyAppleAnchorIncludeTestRoots
, kCFBooleanTrue
);
2057 if (SecIsInternalRelease() && !SecIsProductionFused()) {
2058 /* Allow a prod hierarchy-signed test cert */
2059 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonNameTEST
,
2060 CFSTR("Apple iPhone OS Application Signing"));
2061 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.3.1"));
2062 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.6.1"));
2064 /* or a test hierarchy-signed test cert */
2065 CFDictionarySetValue(appleAnchorOptions
,
2066 kSecPolicyAppleAnchorIncludeTestRoots
, kCFBooleanTrue
);
2069 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
,
2070 CFSTR("Apple iPhone OS Application Signing"));
2072 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.3"));
2073 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.6"));
2075 add_eku(options
, NULL
); /* eku extension is optional */
2076 add_eku(options
, &oidAnyExtendedKeyUsage
);
2077 add_eku(options
, &oidExtendedKeyUsageCodeSigning
);
2079 /* Intermediate check */
2080 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2081 CFSTR("Apple iPhone Certification Authority"));
2083 /* Chain length check */
2084 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2086 /* Anchored to the Apple Roots */
2087 add_element(options
, kSecPolicyCheckAnchorApple
, appleAnchorOptions
);
2089 require(result
= SecPolicyCreate(kSecPolicyAppleiPhoneApplicationSigning
,
2090 kSecPolicyNameiPhoneApplicationSigning
, options
),
2094 CFReleaseSafe(options
);
2095 CFReleaseSafe(appleAnchorOptions
);
2099 SecPolicyRef
SecPolicyCreateiPhoneProfileApplicationSigning(void) {
2100 CFMutableDictionaryRef options
= NULL
;
2101 SecPolicyRef result
= NULL
;
2103 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2104 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2105 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
2106 CFDictionaryAddValue(options
, kSecPolicyCheckValidLeaf
, kCFBooleanFalse
);
2108 require(result
= SecPolicyCreate(kSecPolicyAppleiPhoneProfileApplicationSigning
,
2109 kSecPolicyNameiPhoneProfileApplicationSigning
,
2113 CFReleaseSafe(options
);
2117 SecPolicyRef
SecPolicyCreateiPhoneProvisioningProfileSigning(void) {
2118 CFMutableDictionaryRef options
= NULL
;
2119 SecPolicyRef result
= NULL
;
2121 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2122 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2124 SecPolicyAddBasicCertOptions(options
);
2126 /* Basic X.509 policy with the additional requirements that the chain
2127 length is 3, it's anchored at the AppleCA and the leaf certificate
2128 has issuer "Apple iPhone Certification Authority" and
2129 subject "Apple iPhone OS Provisioning Profile Signing" for the common name. */
2130 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2131 CFSTR("Apple iPhone Certification Authority"));
2132 if (SecIsInternalRelease() && !SecIsProductionFused()) {
2133 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonNameTEST
,
2134 CFSTR("Apple iPhone OS Provisioning Profile Signing"));
2137 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
,
2138 CFSTR("Apple iPhone OS Provisioning Profile Signing"));
2141 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2142 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameiPhoneProvisioningProfileSigning
), errOut
);
2144 require(result
= SecPolicyCreate(kSecPolicyAppleiPhoneProvisioningProfileSigning
,
2145 kSecPolicyNameiPhoneProvisioningProfileSigning
, options
),
2148 /* 1.2.840.113635.100.6.2.2.1, non-critical: DER:05:00 - provisioning profile */
2151 CFReleaseSafe(options
);
2155 SecPolicyRef
SecPolicyCreateAppleTVOSApplicationSigning(void) {
2156 CFMutableDictionaryRef options
= NULL
;
2157 SecPolicyRef result
= NULL
;
2158 CFDataRef atvProdOid
= NULL
;
2159 CFDataRef atvTestOid
= NULL
;
2160 CFArrayRef oids
= NULL
;
2162 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2163 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2165 SecPolicyAddBasicCertOptions(options
);
2167 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2169 require_quiet(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameAppleTVOSApplicationSigning
),
2172 /* Check for intermediate: Apple Worldwide Developer Relations */
2173 /* 1.2.840.113635.100.6.2.1 */
2174 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleWWDR
);
2176 add_ku(options
, kSecKeyUsageDigitalSignature
);
2178 /* Check for prod or test AppleTV Application Signing OIDs */
2179 /* Prod: 1.2.840.113635.100.6.1.24 */
2180 /* Test: 1.2.840.113635.100.6.1.24.1 */
2181 add_leaf_marker(options
, &oidAppleTVOSApplicationSigningProd
);
2182 add_leaf_marker(options
, &oidAppleTVOSApplicationSigningTest
);
2184 require(result
= SecPolicyCreate(kSecPolicyAppleTVOSApplicationSigning
,
2185 kSecPolicyNameAppleTVOSApplicationSigning
, options
),
2189 CFReleaseSafe(options
);
2190 CFReleaseSafe(oids
);
2191 CFReleaseSafe(atvProdOid
);
2192 CFReleaseSafe(atvTestOid
);
2196 SecPolicyRef
SecPolicyCreateOCSPSigner(void) {
2197 CFMutableDictionaryRef options
= NULL
;
2198 SecPolicyRef result
= NULL
;
2200 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2201 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2203 SecPolicyAddBasicX509Options(options
);
2205 /* Require id-kp-OCSPSigning extendedKeyUsage to be present, not optional. */
2206 add_eku(options
, &oidExtendedKeyUsageOCSPSigning
);
2208 require(result
= SecPolicyCreate(kSecPolicyAppleOCSPSigner
,
2209 kSecPolicyNameOCSPSigner
, options
), errOut
);
2212 CFReleaseSafe(options
);
2216 SecPolicyRef
SecPolicyCreateRevocation(CFOptionFlags revocationFlags
) {
2217 CFMutableDictionaryRef options
= NULL
;
2218 SecPolicyRef result
= NULL
;
2220 require(revocationFlags
!= 0, errOut
);
2222 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2223 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2225 if (revocationFlags
& kSecRevocationOCSPMethod
&& revocationFlags
& kSecRevocationCRLMethod
) {
2226 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
2228 else if (revocationFlags
& kSecRevocationOCSPMethod
) {
2229 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationOCSP
);
2231 else if (revocationFlags
& kSecRevocationCRLMethod
) {
2232 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationCRL
);
2235 if (revocationFlags
& kSecRevocationRequirePositiveResponse
) {
2236 CFDictionaryAddValue(options
, kSecPolicyCheckRevocationResponseRequired
, kCFBooleanTrue
);
2239 if (revocationFlags
& kSecRevocationNetworkAccessDisabled
) {
2240 CFDictionaryAddValue(options
, kSecPolicyCheckNoNetworkAccess
, kCFBooleanTrue
);
2242 /* If the caller didn't explicitly disable network access, the revocation policy
2243 * should override any other policy's network setting.
2244 * In particular, pairing a revocation policy with BasicX509 should result in
2245 * allowing network access for revocation unless explicitly disabled.
2246 * Note that SecTrustSetNetworkFetchAllowed can override even this. */
2247 CFDictionaryAddValue(options
, kSecPolicyCheckNoNetworkAccess
, kCFBooleanFalse
);
2250 /* Only flag bits 0-4 are currently defined */
2251 require(((revocationFlags
>> 5) == 0), errOut
);
2253 require(result
= SecPolicyCreate(kSecPolicyAppleRevocation
,
2254 kSecPolicyNameRevocation
, options
), errOut
);
2257 CFReleaseSafe(options
);
2261 SecPolicyRef
SecPolicyCreateSMIME(CFIndex smimeUsage
, CFStringRef email
) {
2262 CFMutableDictionaryRef options
= NULL
;
2263 SecPolicyRef result
= NULL
;
2265 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2266 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2268 SecPolicyAddBasicX509Options(options
);
2270 /* We call add_ku for each combination of bits we are willing to allow. */
2271 if (smimeUsage
& kSecSignSMIMEUsage
) {
2272 add_ku(options
, kSecKeyUsageUnspecified
);
2273 add_ku(options
, kSecKeyUsageDigitalSignature
);
2274 add_ku(options
, kSecKeyUsageNonRepudiation
);
2276 if (smimeUsage
& kSecKeyEncryptSMIMEUsage
) {
2277 add_ku(options
, kSecKeyUsageKeyEncipherment
);
2279 if (smimeUsage
& kSecDataEncryptSMIMEUsage
) {
2280 add_ku(options
, kSecKeyUsageDataEncipherment
);
2282 if (smimeUsage
& kSecKeyExchangeDecryptSMIMEUsage
) {
2283 add_ku(options
, kSecKeyUsageKeyAgreement
| kSecKeyUsageDecipherOnly
);
2285 if (smimeUsage
& kSecKeyExchangeEncryptSMIMEUsage
) {
2286 add_ku(options
, kSecKeyUsageKeyAgreement
| kSecKeyUsageEncipherOnly
);
2288 if (smimeUsage
& kSecKeyExchangeBothSMIMEUsage
) {
2289 add_ku(options
, kSecKeyUsageKeyAgreement
| kSecKeyUsageEncipherOnly
| kSecKeyUsageDecipherOnly
);
2293 CFDictionaryAddValue(options
, kSecPolicyCheckEmail
, email
);
2296 /* RFC 3850 paragraph 4.4.4
2298 If the extended key usage extension is present in the certificate
2299 then interpersonal message S/MIME receiving agents MUST check that it
2300 contains either the emailProtection or the anyExtendedKeyUsage OID as
2301 defined in [KEYM]. S/MIME uses other than interpersonal messaging
2302 MAY require the explicit presence of the extended key usage extension
2303 or other OIDs to be present in the extension or both.
2305 add_eku(options
, NULL
); /* eku extension is optional */
2306 add_eku(options
, &oidAnyExtendedKeyUsage
);
2307 add_eku(options
, &oidExtendedKeyUsageEmailProtection
);
2309 #if !TARGET_OS_IPHONE
2310 // Check revocation on OS X
2311 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
2314 require(result
= SecPolicyCreate(kSecPolicyAppleSMIME
, kSecPolicyNameSMIME
, options
), errOut
);
2317 CFReleaseSafe(options
);
2321 SecPolicyRef
SecPolicyCreateApplePackageSigning(void) {
2322 CFMutableDictionaryRef options
= NULL
;
2323 SecPolicyRef result
= NULL
;
2325 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2326 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2328 SecPolicyAddBasicCertOptions(options
);
2330 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2331 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNamePackageSigning
), errOut
);
2333 add_ku(options
, kSecKeyUsageDigitalSignature
);
2334 add_eku(options
, &oidExtendedKeyUsageCodeSigning
);
2336 require(result
= SecPolicyCreate(kSecPolicyApplePackageSigning
,
2337 kSecPolicyNamePackageSigning
, options
),
2341 CFReleaseSafe(options
);
2346 SecPolicyRef
SecPolicyCreateAppleSWUpdateSigning(void) {
2347 CFMutableDictionaryRef options
= NULL
;
2348 SecPolicyRef result
= NULL
;
2350 * OS X rules for this policy:
2351 * -- Must have one intermediate cert
2352 * -- intermediate must have basic constraints with path length 0
2353 * -- intermediate has CSSMOID_APPLE_EKU_CODE_SIGNING EKU
2354 * -- leaf cert has either CODE_SIGNING or CODE_SIGN_DEVELOPMENT EKU (the latter of
2355 * which triggers a CSSMERR_APPLETP_CODE_SIGN_DEVELOPMENT error)
2357 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2358 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2360 SecPolicyAddBasicX509Options(options
);
2362 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2363 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameAppleSWUpdateSigning
), errOut
);
2365 add_eku(options
, &oidAppleExtendedKeyUsageCodeSigning
);
2366 add_oid(options
, kSecPolicyCheckIntermediateEKU
, &oidAppleExtendedKeyUsageCodeSigning
);
2368 require(result
= SecPolicyCreate(kSecPolicyAppleSWUpdateSigning
,
2369 kSecPolicyNameAppleSWUpdateSigning
, options
),
2373 CFReleaseSafe(options
);
2378 SecPolicyRef
SecPolicyCreateCodeSigning(void) {
2379 CFMutableDictionaryRef options
= NULL
;
2380 SecPolicyRef result
= NULL
;
2382 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2383 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2385 SecPolicyAddBasicX509Options(options
);
2387 /* If the key usage extension is present, we accept it having either of
2389 add_ku(options
, kSecKeyUsageDigitalSignature
);
2390 add_ku(options
, kSecKeyUsageNonRepudiation
);
2392 /* We require an extended key usage extension with the codesigning
2393 eku purpose. (The Apple codesigning eku is not accepted here
2394 since it's valid only for SecPolicyCreateAppleSWUpdateSigning.) */
2395 add_eku(options
, &oidExtendedKeyUsageCodeSigning
);
2396 #if TARGET_OS_IPHONE
2397 /* Accept the 'any' eku on iOS only to match prior behavior.
2398 This may be further restricted in future releases. */
2399 add_eku(options
, &oidAnyExtendedKeyUsage
);
2402 require(result
= SecPolicyCreate(kSecPolicyAppleCodeSigning
,
2403 kSecPolicyNameCodeSigning
, options
),
2407 CFReleaseSafe(options
);
2411 /* Explicitly leave out empty subject/subjectaltname check */
2412 SecPolicyRef
SecPolicyCreateLockdownPairing(void) {
2413 CFMutableDictionaryRef options
= NULL
;
2414 SecPolicyRef result
= NULL
;
2416 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2417 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2418 //CFDictionaryAddValue(options, kSecPolicyCheckBasicCertificateProcessing,
2419 // kCFBooleanTrue); // Happens automatically in SecPVCPathChecks
2420 CFDictionaryAddValue(options
, kSecPolicyCheckCriticalExtensions
,
2422 CFDictionaryAddValue(options
, kSecPolicyCheckIdLinkage
,
2424 CFDictionaryAddValue(options
, kSecPolicyCheckBasicConstraints
,
2426 CFDictionaryAddValue(options
, kSecPolicyCheckQualifiedCertStatements
,
2428 CFDictionaryAddValue(options
, kSecPolicyCheckWeakIntermediates
, kCFBooleanTrue
);
2429 CFDictionaryAddValue(options
, kSecPolicyCheckWeakLeaf
, kCFBooleanTrue
);
2430 CFDictionaryAddValue(options
, kSecPolicyCheckWeakRoot
, kCFBooleanTrue
);
2432 require(result
= SecPolicyCreate(kSecPolicyAppleLockdownPairing
,
2433 kSecPolicyNameLockdownPairing
, options
), errOut
);
2436 CFReleaseSafe(options
);
2440 SecPolicyRef
SecPolicyCreateURLBag(void) {
2441 CFMutableDictionaryRef options
= NULL
;
2442 SecPolicyRef result
= NULL
;
2444 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2445 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2447 SecPolicyAddBasicCertOptions(options
);
2449 add_eku(options
, &oidExtendedKeyUsageCodeSigning
);
2451 require(result
= SecPolicyCreate(kSecPolicyAppleURLBag
,
2452 kSecPolicyNameURLBag
, options
), errOut
);
2455 CFReleaseSafe(options
);
2459 static bool SecPolicyAddAppleCertificationAuthorityOptions(CFMutableDictionaryRef options
, bool honorValidity
, CFStringRef policyName
)
2461 bool success
= false;
2464 SecPolicyAddBasicX509Options(options
);
2466 SecPolicyAddBasicCertOptions(options
);
2469 CFDictionaryAddValue(options
, kSecPolicyCheckKeyUsage
,
2471 CFDictionaryAddValue(options
, kSecPolicyCheckExtendedKeyUsage
,
2475 /* Basic X.509 policy with the additional requirements that the chain
2476 length is 3, it's anchored at the AppleCA and the leaf certificate
2477 has issuer "Apple iPhone Certification Authority". */
2478 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2479 CFSTR("Apple iPhone Certification Authority"));
2481 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2482 require(SecPolicyAddAppleAnchorOptions(options
, policyName
), errOut
);
2490 static SecPolicyRef
SecPolicyCreateAppleCertificationAuthorityPolicy(CFStringRef policyOID
, CFStringRef policyName
,
2491 CFStringRef leafName
, bool honorValidity
)
2493 CFMutableDictionaryRef options
= NULL
;
2494 SecPolicyRef result
= NULL
;
2496 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2497 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
), errOut
);
2499 require(SecPolicyAddAppleCertificationAuthorityOptions(options
, honorValidity
, policyName
), errOut
);
2501 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectCommonName
, leafName
);
2503 require(result
= SecPolicyCreate(policyOID
, policyName
, options
),
2507 CFReleaseSafe(options
);
2512 SecPolicyRef
SecPolicyCreateOTATasking(void)
2514 return SecPolicyCreateAppleCertificationAuthorityPolicy(kSecPolicyAppleOTATasking
,
2515 kSecPolicyNameOTATasking
,
2516 CFSTR("OTA Task Signing"), true);
2519 SecPolicyRef
SecPolicyCreateMobileAsset(void)
2521 return SecPolicyCreateAppleCertificationAuthorityPolicy(kSecPolicyAppleMobileAsset
,
2522 kSecPolicyNameMobileAsset
,
2523 CFSTR("Asset Manifest Signing"), false);
2526 SecPolicyRef
SecPolicyCreateAppleIDAuthorityPolicy(void)
2528 SecPolicyRef result
= NULL
;
2529 CFMutableDictionaryRef options
= NULL
;
2530 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2531 &kCFTypeDictionaryKeyCallBacks
,
2532 &kCFTypeDictionaryValueCallBacks
), out
);
2534 //Leaf appears to be a SSL only cert, so policy should expand on that policy
2535 SecPolicyAddBasicX509Options(options
);
2537 // Apple CA anchored
2538 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameAppleIDAuthority
), out
);
2540 // with the addition of the existence check of an extension with "Apple ID Sharing Certificate" oid (1.2.840.113635.100.4.7)
2541 // NOTE: this obviously intended to have gone into Extended Key Usage, but evidence of existing certs proves the contrary.
2542 add_leaf_marker(options
, &oidAppleExtendedKeyUsageAppleID
);
2544 // and validate that intermediate has extension with CSSMOID_APPLE_EXTENSION_AAI_INTERMEDIATE oid (1.2.840.113635.100.6.2.3) and goes back to the Apple Root CA.
2545 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleID
);
2546 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleID2
);
2548 require(result
= SecPolicyCreate(kSecPolicyAppleIDAuthority
,
2549 kSecPolicyNameAppleIDAuthority
, options
), out
);
2552 CFReleaseSafe(options
);
2556 SecPolicyRef
SecPolicyCreateMacAppStoreReceipt(void)
2558 SecPolicyRef result
= NULL
;
2559 CFMutableDictionaryRef options
= NULL
;
2560 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2561 &kCFTypeDictionaryKeyCallBacks
,
2562 &kCFTypeDictionaryValueCallBacks
), out
);
2564 SecPolicyAddBasicX509Options(options
);
2566 // Apple CA anchored
2567 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameMacAppStoreReceipt
), out
);
2569 // Chain length of 3
2570 require(SecPolicyAddChainLengthOptions(options
, 3), out
);
2572 // MacAppStoreReceipt policy OID
2573 add_certificate_policy_oid_string(options
, CFSTR("1.2.840.113635.100.5.6.1"));
2575 // Intermediate marker OID
2576 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.1"));
2579 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.11.1"));
2582 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
2584 require(result
= SecPolicyCreate(kSecPolicyMacAppStoreReceipt
,
2585 kSecPolicyNameMacAppStoreReceipt
, options
), out
);
2588 CFReleaseSafe(options
);
2593 static SecPolicyRef
_SecPolicyCreatePassbookCardSigner(CFStringRef cardIssuer
, CFStringRef teamIdentifier
, bool requireTeamID
)
2595 SecPolicyRef result
= NULL
;
2596 CFMutableDictionaryRef options
= NULL
;
2597 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2598 &kCFTypeDictionaryKeyCallBacks
,
2599 &kCFTypeDictionaryValueCallBacks
), out
);
2601 SecPolicyAddBasicX509Options(options
);
2602 SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameApplePassbook
);
2604 // Chain length of 3
2605 require(SecPolicyAddChainLengthOptions(options
, 3), out
);
2607 if (teamIdentifier
) {
2608 // If supplied, teamIdentifier must match subject OU field
2609 CFDictionaryAddValue(options
, kSecPolicyCheckSubjectOrganizationalUnit
, teamIdentifier
);
2612 // If not supplied, and it was required, fail
2613 require(!requireTeamID
, out
);
2616 // Must be both push and 3rd party package signing
2617 add_leaf_marker_value(options
, &oidAppleInstallerPackagingSigningExternal
, cardIssuer
);
2619 // We should check that it also has push marker, but we don't support requiring both, only either.
2620 // add_independent_oid(options, kSecPolicyCheckLeafMarkerOid, &oidApplePushServiceClient);
2622 //WWDR Intermediate marker OID
2623 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.1"));
2625 // And Passbook signing eku
2626 add_eku(options
, &oidAppleExtendedKeyUsagePassbook
);
2628 require(result
= SecPolicyCreate(kSecPolicyApplePassbookSigning
,
2629 kSecPolicyNameApplePassbook
, options
), out
);
2632 CFReleaseSafe(options
);
2636 SecPolicyRef
SecPolicyCreatePassbookCardSigner(CFStringRef cardIssuer
, CFStringRef teamIdentifier
)
2638 return _SecPolicyCreatePassbookCardSigner(cardIssuer
, teamIdentifier
, true);
2642 static SecPolicyRef
CreateMobileStoreSigner(Boolean forTest
)
2645 SecPolicyRef result
= NULL
;
2646 CFMutableDictionaryRef options
= NULL
;
2647 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2648 &kCFTypeDictionaryKeyCallBacks
,
2649 &kCFTypeDictionaryValueCallBacks
), errOut
);
2650 SecPolicyAddBasicX509Options(options
);
2651 SecPolicyAddAppleAnchorOptions(options
,
2652 ((forTest
) ? kSecPolicyNameAppleTestMobileStore
:
2653 kSecPolicyNameAppleMobileStore
));
2655 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2657 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2658 CFSTR("Apple System Integration 2 Certification Authority"));
2660 add_ku(options
, kSecKeyUsageDigitalSignature
);
2662 const DERItem
* pOID
= (forTest
) ? &oidApplePolicyTestMobileStore
: &oidApplePolicyMobileStore
;
2664 add_certificate_policy_oid(options
, pOID
);
2666 require(result
= SecPolicyCreate((forTest
) ? kSecPolicyAppleTestMobileStore
: kSecPolicyAppleMobileStore
,
2667 (forTest
) ? kSecPolicyNameAppleTestMobileStore
: kSecPolicyNameAppleMobileStore
,
2671 CFReleaseSafe(options
);
2675 SecPolicyRef
SecPolicyCreateMobileStoreSigner(void)
2677 return CreateMobileStoreSigner(false);
2680 SecPolicyRef
SecPolicyCreateTestMobileStoreSigner(void)
2682 return CreateMobileStoreSigner(true);
2686 CF_RETURNS_RETAINED SecPolicyRef
SecPolicyCreateEscrowServiceSigner(void)
2688 SecPolicyRef result
= NULL
;
2689 CFMutableDictionaryRef options
= NULL
;
2690 CFArrayRef anArray
= NULL
;
2691 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2692 &kCFTypeDictionaryKeyCallBacks
,
2693 &kCFTypeDictionaryValueCallBacks
), errOut
);
2695 // X509, ignoring date validity
2696 SecPolicyAddBasicCertOptions(options
);
2699 add_ku(options
, kSecKeyUsageKeyEncipherment
);
2701 //add_leaf_marker(options, &oidApplePolicyEscrowService);
2702 require(SecPolicyAddChainLengthOptions(options
, 2), errOut
);
2705 Boolean anchorAdded
= false;
2706 // Get the roots by calling the SecCertificateCopyEscrowRoots
2707 anArray
= SecCertificateCopyEscrowRoots(kSecCertificateProductionEscrowRoot
);
2708 CFIndex numRoots
= 0;
2709 if (NULL
== anArray
|| 0 == (numRoots
= CFArrayGetCount(anArray
)))
2714 for (CFIndex iCnt
= 0; iCnt
< numRoots
; iCnt
++)
2716 SecCertificateRef aCert
= (SecCertificateRef
)CFArrayGetValueAtIndex(anArray
, iCnt
);
2720 CFDataRef sha_data
= SecCertificateGetSHA1Digest(aCert
);
2721 if (NULL
!= sha_data
)
2723 const UInt8
* pSHAData
= CFDataGetBytePtr(sha_data
);
2724 if (NULL
!= pSHAData
)
2726 SecPolicyAddAnchorSHA1Options(options
, pSHAData
);
2732 CFReleaseNull(anArray
);
2740 require(result
= SecPolicyCreate(kSecPolicyAppleEscrowService
,
2741 kSecPolicyNameAppleEscrowService
, options
), errOut
);
2744 CFReleaseSafe(anArray
);
2745 CFReleaseSafe(options
);
2749 CF_RETURNS_RETAINED SecPolicyRef
SecPolicyCreatePCSEscrowServiceSigner(void)
2751 SecPolicyRef result
= NULL
;
2752 CFMutableDictionaryRef options
= NULL
;
2753 CFArrayRef anArray
= NULL
;
2754 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2755 &kCFTypeDictionaryKeyCallBacks
,
2756 &kCFTypeDictionaryValueCallBacks
), errOut
);
2758 SecPolicyAddBasicX509Options(options
);
2761 add_ku(options
, kSecKeyUsageKeyEncipherment
);
2763 //add_leaf_marker(options, &oidApplePolicyEscrowService);
2764 require(SecPolicyAddChainLengthOptions(options
, 2), errOut
);
2767 Boolean anchorAdded
= false;
2768 anArray
= SecCertificateCopyEscrowRoots(kSecCertificateProductionPCSEscrowRoot
);
2769 CFIndex numRoots
= 0;
2770 if (NULL
== anArray
|| 0 == (numRoots
= CFArrayGetCount(anArray
)))
2775 for (CFIndex iCnt
= 0; iCnt
< numRoots
; iCnt
++)
2777 SecCertificateRef aCert
= (SecCertificateRef
)CFArrayGetValueAtIndex(anArray
, iCnt
);
2781 CFDataRef sha_data
= SecCertificateGetSHA1Digest(aCert
);
2782 if (NULL
!= sha_data
)
2784 const UInt8
* pSHAData
= CFDataGetBytePtr(sha_data
);
2785 if (NULL
!= pSHAData
)
2787 SecPolicyAddAnchorSHA1Options(options
, pSHAData
);
2793 CFReleaseNull(anArray
);
2801 require(result
= SecPolicyCreate(kSecPolicyApplePCSEscrowService
,
2802 kSecPolicyNameApplePCSEscrowService
, options
), errOut
);
2805 CFReleaseSafe(anArray
);
2806 CFReleaseSafe(options
);
2810 static SecPolicyRef
CreateConfigurationProfileSigner(bool forTest
) {
2811 SecPolicyRef result
= NULL
;
2812 CFMutableDictionaryRef options
= NULL
;
2813 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2814 &kCFTypeDictionaryKeyCallBacks
,
2815 &kCFTypeDictionaryValueCallBacks
), errOut
);
2817 SecPolicyAddBasicX509Options(options
);
2818 SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameAppleProfileSigner
);
2821 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2823 // Require the profile signing EKU
2824 const DERItem
* pOID
= (forTest
) ? &oidAppleExtendedKeyUsageQAProfileSigning
:&oidAppleExtendedKeyUsageProfileSigning
;
2825 add_eku(options
, pOID
);
2827 // Require the Apple Application Integration CA marker OID
2828 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
, CFSTR("1.2.840.113635.100.6.2.3"));
2830 require(result
= SecPolicyCreate((forTest
) ? kSecPolicyAppleQAProfileSigner
: kSecPolicyAppleProfileSigner
,
2831 (forTest
) ? kSecPolicyNameAppleQAProfileSigner
: kSecPolicyNameAppleProfileSigner
,
2835 CFReleaseSafe(options
);
2839 SecPolicyRef
SecPolicyCreateConfigurationProfileSigner(void)
2841 return CreateConfigurationProfileSigner(false);
2845 SecPolicyRef
SecPolicyCreateQAConfigurationProfileSigner(void)
2847 if (SecIsInternalRelease()) {
2848 return CreateConfigurationProfileSigner(true);
2850 return CreateConfigurationProfileSigner(false);
2854 SecPolicyRef
SecPolicyCreateOSXProvisioningProfileSigning(void)
2856 SecPolicyRef result
= NULL
;
2857 CFMutableDictionaryRef options
= NULL
;
2858 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2859 &kCFTypeDictionaryKeyCallBacks
,
2860 &kCFTypeDictionaryValueCallBacks
), errOut
);
2861 // Require valid chain from the Apple root
2862 SecPolicyAddBasicX509Options(options
);
2863 SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameAppleOSXProvisioningProfileSigning
);
2865 // Require provisioning profile leaf marker OID (1.2.840.113635.100.4.11)
2866 add_leaf_marker(options
, &oidAppleCertExtOSXProvisioningProfileSigning
);
2868 // Require intermediate marker OID (1.2.840.113635.100.6.2.1)
2869 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleWWDR
);
2871 // Require key usage that allows signing
2872 add_ku(options
, kSecKeyUsageDigitalSignature
);
2874 // Ensure that revocation is checked (OCSP)
2875 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationOCSP
);
2877 require(result
= SecPolicyCreate(kSecPolicyAppleOSXProvisioningProfileSigning
,
2878 kSecPolicyNameAppleOSXProvisioningProfileSigning
, options
), errOut
);
2881 CFReleaseSafe(options
);
2886 SecPolicyRef
SecPolicyCreateOTAPKISigner(void)
2888 SecPolicyRef result
= NULL
;
2889 CFMutableDictionaryRef options
= NULL
;
2890 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2891 &kCFTypeDictionaryKeyCallBacks
,
2892 &kCFTypeDictionaryValueCallBacks
), errOut
);
2893 SecPolicyAddBasicX509Options(options
);
2895 SecPolicyAddAnchorSHA1Options(options
, kApplePKISettingsAuthority
);
2896 require(SecPolicyAddChainLengthOptions(options
, 2), errOut
);
2898 require(result
= SecPolicyCreate(kSecPolicyAppleOTAPKISigner
,
2899 kSecPolicyNameAppleOTAPKIAssetSigner
, options
), errOut
);
2902 CFReleaseSafe(options
);
2908 SecPolicyRef
SecPolicyCreateTestOTAPKISigner(void)
2910 /* Guard against use on production devices */
2911 if (!SecIsInternalRelease()) {
2912 return SecPolicyCreateOTAPKISigner();
2915 SecPolicyRef result
= NULL
;
2916 CFMutableDictionaryRef options
= NULL
;
2917 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2918 &kCFTypeDictionaryKeyCallBacks
,
2919 &kCFTypeDictionaryValueCallBacks
), errOut
);
2920 SecPolicyAddBasicX509Options(options
);
2922 SecPolicyAddAnchorSHA1Options(options
, kAppleTestPKISettingsAuthority
);
2923 require(SecPolicyAddChainLengthOptions(options
, 2), errOut
);
2925 require(result
= SecPolicyCreate(kSecPolicyAppleTestOTAPKISigner
,
2926 kSecPolicyNameAppleTestOTAPKIAssetSigner
, options
), errOut
);
2929 CFReleaseSafe(options
);
2934 @function SecPolicyCreateAppleSMPEncryption
2935 @abstract Check for intermediate certificate 'Apple System Integration CA - G3' by name,
2936 and root certificate 'Apple Root CA - G3' by hash.
2937 Leaf cert must have Key Encipherment usage.
2938 Leaf cert must have Apple SMP Encryption marker OID (1.2.840.113635.100.6.30).
2939 Intermediate must have marker OID (1.2.840.113635.100.6.2.13).
2941 SecPolicyRef
SecPolicyCreateAppleSMPEncryption(void)
2943 SecPolicyRef result
= NULL
;
2944 CFMutableDictionaryRef options
= NULL
;
2945 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2946 &kCFTypeDictionaryKeyCallBacks
,
2947 &kCFTypeDictionaryValueCallBacks
), errOut
);
2948 SecPolicyAddBasicCertOptions(options
);
2950 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameAppleSMPEncryption
),
2952 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2954 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2955 CFSTR("Apple System Integration CA - G3"));
2957 // Check that leaf has extension with "Apple SMP Encryption" oid (1.2.840.113635.100.6.30)
2958 add_leaf_marker(options
, &oidAppleCertExtAppleSMPEncryption
);
2960 // Check that intermediate has extension (1.2.840.113635.100.6.2.13)
2961 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleSystemIntgG3
);
2963 add_ku(options
, kSecKeyUsageKeyEncipherment
);
2965 // Ensure that revocation is checked (OCSP)
2966 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationOCSP
);
2968 require(result
= SecPolicyCreate(kSecPolicyAppleSMPEncryption
,
2969 kSecPolicyNameAppleSMPEncryption
, options
), errOut
);
2972 CFReleaseSafe(options
);
2977 @function SecPolicyCreateTestAppleSMPEncryption
2978 @abstract Check for intermediate certificate 'Test Apple System Integration CA - ECC' by name,
2979 and root certificate 'Test Apple Root CA - ECC' by hash.
2980 Leaf cert must have Key Encipherment usage. Other checks TBD.
2982 SecPolicyRef
SecPolicyCreateTestAppleSMPEncryption(void)
2984 SecPolicyRef result
= NULL
;
2985 CFMutableDictionaryRef options
= NULL
;
2986 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
2987 &kCFTypeDictionaryKeyCallBacks
,
2988 &kCFTypeDictionaryValueCallBacks
), errOut
);
2989 SecPolicyAddBasicCertOptions(options
);
2991 SecPolicyAddAnchorSHA1Options(options
, kTestAppleRootCA_ECC_SHA1
);
2992 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
2994 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
2995 CFSTR("Test Apple System Integration CA - ECC"));
2997 add_ku(options
, kSecKeyUsageKeyEncipherment
);
2999 // Ensure that revocation is checked (OCSP)
3000 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationOCSP
);
3002 require(result
= SecPolicyCreate(kSecPolicyAppleTestSMPEncryption
,
3003 kSecPolicyNameAppleTestSMPEncryption
, options
), errOut
);
3006 CFReleaseSafe(options
);
3011 SecPolicyRef
SecPolicyCreateAppleIDValidationRecordSigningPolicy(void)
3013 SecPolicyRef result
= NULL
;
3014 CFMutableDictionaryRef options
= NULL
;
3015 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3016 &kCFTypeDictionaryKeyCallBacks
,
3017 &kCFTypeDictionaryValueCallBacks
), errOut
);
3019 //Leaf appears to be a SSL only cert, so policy should expand on that policy
3020 SecPolicyAddBasicX509Options(options
);
3022 // Apple CA anchored
3023 require(SecPolicyAddAppleAnchorOptions(options
,
3024 kSecPolicyNameAppleIDValidationRecordSigningPolicy
),
3027 // Check for an extension with " Apple ID Validation Record Signing" oid (1.2.840.113635.100.6.25)
3028 add_leaf_marker(options
, &oidAppleCertExtensionAppleIDRecordValidationSigning
);
3030 // and validate that intermediate has extension
3031 // Application Integration Intermediate Certificate (1.2.840.113635.100.6.2.3)
3032 // and also validate that intermediate has extension
3033 // System Integration 2 Intermediate Certificate (1.2.840.113635.100.6.2.10)
3034 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleID
);
3035 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleSystemIntg2
);
3037 // Ensure that revocation is checked (OCSP)
3038 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationOCSP
);
3040 require(result
= SecPolicyCreate(kSecPolicyAppleIDValidationRecordSigning
,
3041 kSecPolicyNameAppleIDValidationRecordSigningPolicy
, options
), errOut
);
3044 CFReleaseSafe(options
);
3049 allowUATRoot(bool allowNonProd
, CFStringRef service
, CFDictionaryRef context
)
3051 bool UATAllowed
= false;
3052 if (SecIsInternalRelease() || allowNonProd
) {
3053 CFStringRef setting
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("AppleServerAuthenticationAllowUAT%@"), service
);
3054 CFTypeRef value
= NULL
;
3055 require(setting
, fail
);
3058 CFDictionaryGetValueIfPresent(context
, setting
, &value
) &&
3060 CFBooleanGetValue(value
))
3065 if (CFPreferencesGetAppBooleanValue(setting
, CFSTR("com.apple.Security"), NULL
)) {
3075 @function SecPolicyCreateAppleServerAuthCommon
3076 @abstract Generic policy for server authentication Sub CAs
3078 Allows control for both if pinning is required at all and if UAT environments should be added
3079 to the trust policy.
3081 No pinning is for developer/QA that needs to use proxy to debug the protocol, while UAT
3082 environment is for QA/internal developer that have no need allow fake servers.
3084 Both the noPinning and allowUAT are gated on that you run on internal hardware.
3089 SecPolicyCreateAppleServerAuthCommon(CFStringRef hostname
,
3090 CFDictionaryRef __unused context
,
3091 CFStringRef policyOID
, CFStringRef service
, bool allowNonProd
,
3092 const DERItem
*leafMarkerOID
,
3093 const DERItem
*UATLeafMarkerOID
)
3095 CFMutableDictionaryRef appleAnchorOptions
= NULL
;
3096 CFMutableDictionaryRef options
= NULL
;
3097 SecPolicyRef result
= NULL
;
3098 CFDataRef oid
= NULL
, uatoid
= NULL
;
3100 options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0, &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
3101 require(options
, errOut
);
3103 SecPolicyAddBasicX509Options(options
);
3105 require(hostname
, errOut
);
3106 CFDictionaryAddValue(options
, kSecPolicyCheckSSLHostname
, hostname
);
3108 CFDictionaryAddValue(options
, kSecPolicyCheckBlackListedLeaf
, kCFBooleanTrue
);
3109 CFDictionaryAddValue(options
, kSecPolicyCheckGrayListedLeaf
, kCFBooleanTrue
);
3111 add_eku(options
, &oidExtendedKeyUsageServerAuth
);
3113 if (requireUATPinning(service
)) {
3114 bool allowUAT
= allowUATRoot(allowNonProd
, service
, context
);
3117 * Require pinning to the Apple CA's (and if UAT environment,
3118 * include the Apple Test CA's as anchors).
3121 appleAnchorOptions
= CFDictionaryCreateMutableForCFTypes(NULL
);
3122 require(appleAnchorOptions
, errOut
);
3124 if (allowUAT
|| allowTestHierarchyForPolicy(service
)) {
3125 /* Note: SecPolicyServer won't allow the test roots for non-internal devices */
3126 CFDictionarySetValue(appleAnchorOptions
,
3127 kSecPolicyAppleAnchorIncludeTestRoots
, kCFBooleanTrue
);
3130 add_element(options
, kSecPolicyCheckAnchorApple
, appleAnchorOptions
);
3133 * Check if we also should allow the UAT variant of the leafs
3134 * as some variants of the UAT environment uses that instead
3135 * of the test Apple CA's.
3137 add_leaf_marker(options
, leafMarkerOID
);
3138 if (allowUAT
&& UATLeafMarkerOID
) {
3139 add_leaf_marker(options
, UATLeafMarkerOID
);
3142 /* new-style leaf marker OIDs */
3143 CFStringRef leafMarkerOIDStr
= NULL
, UATLeafMarkerOIDStr
= NULL
;
3144 leafMarkerOIDStr
= SecDERItemCopyOIDDecimalRepresentation(NULL
, leafMarkerOID
);
3145 if (UATLeafMarkerOID
) {
3146 UATLeafMarkerOIDStr
= SecDERItemCopyOIDDecimalRepresentation(NULL
, UATLeafMarkerOID
);
3149 if (leafMarkerOIDStr
) {
3150 add_leaf_marker_value_string(options
, CFSTR("1.2.840.113635.100.6.48.1"), leafMarkerOIDStr
);
3152 if (allowUAT
&& UATLeafMarkerOIDStr
) {
3153 add_leaf_marker_value_string(options
, CFSTR("1.2.840.113635.100.6.48.1"), UATLeafMarkerOIDStr
);
3156 CFReleaseNull(leafMarkerOIDStr
);
3157 CFReleaseNull(UATLeafMarkerOIDStr
);
3159 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleServerAuthentication
);
3163 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
3165 result
= SecPolicyCreate(policyOID
, service
, options
);
3166 require(result
, errOut
);
3169 CFReleaseSafe(appleAnchorOptions
);
3170 CFReleaseSafe(options
);
3172 CFReleaseSafe(uatoid
);
3177 @function SecPolicyCreateAppleIDSService
3178 @abstract Ensure we're appropriately pinned to the IDS service (SSL + Apple restrictions)
3180 SecPolicyRef
SecPolicyCreateAppleIDSService(CFStringRef hostname
)
3182 SecPolicyRef result
= SecPolicyCreateSSL(true, hostname
);
3184 SecPolicySetOid(result
, kSecPolicyAppleIDSService
);
3185 SecPolicySetName(result
, kSecPolicyNameAppleIDSServiceContext
);
3191 @function SecPolicyCreateAppleIDSService
3192 @abstract Ensure we're appropriately pinned to the IDS service (SSL + Apple restrictions)
3194 SecPolicyRef
SecPolicyCreateAppleIDSServiceContext(CFStringRef hostname
, CFDictionaryRef context
)
3196 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyAppleIDSServiceContext
,
3197 kSecPolicyNameAppleIDSServiceContext
, false,
3198 &oidAppleCertExtAppleServerAuthenticationIDSProd
,
3199 &oidAppleCertExtAppleServerAuthenticationIDSTest
);
3203 @function SecPolicyCreateAppleGSService
3204 @abstract Ensure we're appropriately pinned to the GS service
3206 SecPolicyRef
SecPolicyCreateAppleGSService(CFStringRef hostname
, CFDictionaryRef context
)
3208 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyAppleGSService
,
3209 kSecPolicyNameAppleGSService
, false,
3210 &oidAppleCertExtAppleServerAuthenticationGS
,
3215 @function SecPolicyCreateApplePushService
3216 @abstract Ensure we're appropriately pinned to the Push service (SSL + Apple restrictions)
3218 SecPolicyRef
SecPolicyCreateApplePushService(CFStringRef hostname
, CFDictionaryRef context
)
3220 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyApplePushService
,
3221 kSecPolicyNameApplePushService
, false,
3222 &oidAppleCertExtAppleServerAuthenticationAPNProd
,
3223 &oidAppleCertExtAppleServerAuthenticationAPNTest
);
3227 @function SecPolicyCreateApplePPQService
3228 @abstract Ensure we're appropriately pinned to the PPQ service (SSL + Apple restrictions)
3230 SecPolicyRef
SecPolicyCreateApplePPQService(CFStringRef hostname
, CFDictionaryRef context
)
3232 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyApplePPQService
,
3233 kSecPolicyNameApplePPQService
, false,
3234 &oidAppleCertExtAppleServerAuthenticationPPQProd
,
3235 &oidAppleCertExtAppleServerAuthenticationPPQTest
);
3239 @function SecPolicyCreateAppleAST2Service
3240 @abstract Ensure we're appropriately pinned to the AST2 Diagnostic service (SSL + Apple restrictions)
3242 SecPolicyRef
SecPolicyCreateAppleAST2Service(CFStringRef hostname
, CFDictionaryRef context
)
3244 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyAppleAST2DiagnosticsServerAuth
,
3245 kSecPolicyNameAppleAST2Service
, true,
3246 &oidAppleCertExtAST2DiagnosticsServerAuthProd
,
3247 &oidAppleCertExtAST2DiagnosticsServerAuthTest
);
3251 @function SecPolicyCreateAppleEscrowProxyService
3252 @abstract Ensure we're appropriately pinned to the iCloud Escrow Proxy service (SSL + Apple restrictions)
3254 SecPolicyRef
SecPolicyCreateAppleEscrowProxyService(CFStringRef hostname
, CFDictionaryRef context
)
3256 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyAppleEscrowProxyServerAuth
,
3257 kSecPolicyNameAppleEscrowProxyService
, false,
3258 &oidAppleCertExtEscrowProxyServerAuthProd
,
3259 &oidAppleCertExtEscrowProxyServerAuthTest
);
3262 /* subject:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA */
3263 /* SKID: C0:7A:98:68:8D:89:FB:AB:05:64:0C:11:7D:AA:7D:65:B8:CA:CC:4E */
3264 /* Not Before: May 21 04:00:00 2002 GMT, Not After : May 21 04:00:00 2022 GMT */
3265 /* Signature Algorithm: sha1WithRSAEncryption */
3266 unsigned char GeoTrust_Global_CA_sha256
[kSecPolicySHA256Size
] = {
3267 0xff, 0x85, 0x6a, 0x2d, 0x25, 0x1d, 0xcd, 0x88, 0xd3, 0x66, 0x56, 0xf4, 0x50, 0x12, 0x67, 0x98,
3268 0xcf, 0xab, 0xaa, 0xde, 0x40, 0x79, 0x9c, 0x72, 0x2d, 0xe4, 0xd2, 0xb5, 0xdb, 0x36, 0xa7, 0x3a
3271 /* SKID: D8:7A:94:44:7C:90:70:90:16:9E:DD:17:9C:01:44:03:86:D6:2A:29 */
3272 unsigned char AppleISTCA2G1_spki_sha256
[kSecPolicySHA256Size
] = {
3273 0xb5, 0xcf, 0x82, 0xd4, 0x7e, 0xf9, 0x82, 0x3f, 0x9a, 0xa7, 0x8f, 0x12, 0x31, 0x86, 0xc5, 0x2e,
3274 0x88, 0x79, 0xea, 0x84, 0xb0, 0xf8, 0x22, 0xc9, 0x1d, 0x83, 0xe0, 0x42, 0x79, 0xb7, 0x8f, 0xd5
3277 static SecPolicyRef
SecPolicyCreateAppleGeoTrustServerAuthCommon(CFStringRef hostname
, CFStringRef policyOid
,
3278 CFStringRef policyName
, bool allowNonProd
,
3279 CFStringRef leafMarkerOid
,
3280 CFStringRef testLeafMarkerOid
) {
3281 CFMutableDictionaryRef options
= NULL
;
3282 CFDataRef spkiDigest
= NULL
;
3283 SecPolicyRef result
= NULL
;
3285 require(options
= CFDictionaryCreateMutable(NULL
, 0, &kCFTypeDictionaryKeyCallBacks
,
3286 &kCFTypeDictionaryValueCallBacks
), errOut
);
3289 SecPolicyAddBasicX509Options(options
);
3291 require(hostname
, errOut
);
3292 CFDictionaryAddValue(options
, kSecPolicyCheckSSLHostname
, hostname
);
3294 add_eku(options
, &oidExtendedKeyUsageServerAuth
);
3297 if (requireUATPinning(policyName
)) {
3299 SecPolicyAddAnchorSHA256Options(options
, GeoTrust_Global_CA_sha256
);
3301 /* Public key for Apple IST CA 2 */
3302 spkiDigest
= CFDataCreateWithBytesNoCopy(NULL
, AppleISTCA2G1_spki_sha256
,
3303 kSecPolicySHA256Size
, kCFAllocatorNull
);
3304 require_action(spkiDigest
, errOut
, CFReleaseNull(result
));
3305 CFDictionaryAddValue(options
, kSecPolicyCheckIntermediateSPKISHA256
, spkiDigest
);
3307 require_action(SecPolicyAddChainLengthOptions(options
, 3), errOut
, CFReleaseNull(result
));
3309 /* Marker OIDs in both formats */
3310 add_leaf_marker_string(options
, leafMarkerOid
);
3311 add_leaf_marker_value_string(options
, CFSTR("1.2.840.113635.100.6.48.1"), leafMarkerOid
);
3312 if (testLeafMarkerOid
&& allowUATRoot(allowNonProd
, policyName
, NULL
)) {
3313 add_leaf_marker_string(options
, testLeafMarkerOid
);
3314 add_leaf_marker_value_string(options
, CFSTR("1.2.840.113635.100.6.48.1"), testLeafMarkerOid
);
3318 /* See <rdar://25344801> for more details */
3320 result
= SecPolicyCreate(policyOid
, policyName
, options
);
3323 CFReleaseSafe(options
);
3324 CFReleaseSafe(spkiDigest
);
3328 SecPolicyRef
SecPolicyCreateAppleCompatibilityEscrowProxyService(CFStringRef hostname
) {
3329 return SecPolicyCreateAppleGeoTrustServerAuthCommon(hostname
, kSecPolicyAppleEscrowProxyCompatibilityServerAuth
,
3330 kSecPolicyNameAppleEscrowProxyService
, false,
3331 CFSTR("1.2.840.113635.100.6.27.7.2"),
3332 CFSTR("1.2.840.113635.100.6.27.7.1"));
3336 @function SecPolicyCreateAppleFMiPService
3337 @abstract Ensure we're appropriately pinned to the Find My iPhone service (SSL + Apple restrictions)
3339 SecPolicyRef
SecPolicyCreateAppleFMiPService(CFStringRef hostname
, CFDictionaryRef context
)
3341 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyAppleFMiPServerAuth
,
3342 kSecPolicyNameAppleFMiPService
, false,
3343 &oidAppleCertExtFMiPServerAuthProd
,
3344 &oidAppleCertExtFMiPServerAuthTest
);
3348 /* should use verbatim copy, but since this is the deprecated way, don't care right now */
3349 static const UInt8 entrustSPKIL1C
[kSecPolicySHA256Size
] = {
3350 0x54, 0x5b, 0xf9, 0x35, 0xe9, 0xad, 0xa1, 0xda,
3351 0x11, 0x7e, 0xdc, 0x3c, 0x2a, 0xcb, 0xc5, 0x6f,
3352 0xc0, 0x28, 0x09, 0x6c, 0x0e, 0x24, 0xbe, 0x9b,
3353 0x38, 0x94, 0xbe, 0x52, 0x2d, 0x1b, 0x43, 0xde
3357 @function SecPolicyCreateApplePushServiceLegacy
3358 @abstract Ensure we're appropriately pinned to the Push service (via Entrust)
3360 SecPolicyRef
SecPolicyCreateApplePushServiceLegacy(CFStringRef hostname
)
3362 CFMutableDictionaryRef options
= NULL
;
3363 SecPolicyRef result
= NULL
;
3364 CFDataRef digest
= NULL
;
3366 digest
= CFDataCreateWithBytesNoCopy(kCFAllocatorDefault
, entrustSPKIL1C
, sizeof(entrustSPKIL1C
), kCFAllocatorNull
);
3367 require(digest
, errOut
);
3369 options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0, &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
3370 require(options
, errOut
);
3372 SecPolicyAddBasicX509Options(options
);
3374 CFDictionaryAddValue(options
, kSecPolicyCheckSSLHostname
, hostname
);
3376 CFDictionaryAddValue(options
, kSecPolicyCheckBlackListedLeaf
, kCFBooleanTrue
);
3377 CFDictionaryAddValue(options
, kSecPolicyCheckGrayListedLeaf
, kCFBooleanTrue
);
3379 CFDictionaryAddValue(options
, kSecPolicyCheckIntermediateSPKISHA256
, digest
);
3381 add_eku(options
, &oidExtendedKeyUsageServerAuth
);
3383 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
3385 result
= SecPolicyCreate(kSecPolicyAppleLegacyPushService
,
3386 kSecPolicyNameAppleLegacyPushService
, options
);
3387 require(result
, errOut
);
3390 CFReleaseSafe(digest
);
3391 CFReleaseSafe(options
);
3396 @function SecPolicyCreateAppleMMCSService
3397 @abstract Ensure we're appropriately pinned to the IDS service (SSL + Apple restrictions)
3399 SecPolicyRef
SecPolicyCreateAppleMMCSService(CFStringRef hostname
, CFDictionaryRef context
)
3401 return SecPolicyCreateAppleServerAuthCommon(hostname
, context
, kSecPolicyAppleMMCSService
,
3402 kSecPolicyNameAppleMMCSService
, false,
3403 &oidAppleCertExtAppleServerAuthenticationMMCSProd
,
3404 &oidAppleCertExtAppleServerAuthenticationMMCSTest
);
3407 SecPolicyRef
SecPolicyCreateAppleCompatibilityMMCSService(CFStringRef hostname
) {
3408 return SecPolicyCreateAppleGeoTrustServerAuthCommon(hostname
, kSecPolicyAppleMMCSCompatibilityServerAuth
,
3409 kSecPolicyNameAppleMMCSService
, false,
3410 CFSTR("1.2.840.113635.100.6.27.11.2"),
3411 CFSTR("1.2.840.113635.100.6.27.11.1"));
3415 @function SecPolicyCreateAppleSSLService
3416 @abstract Ensure we're appropriately pinned to an Apple server (SSL + Apple restrictions)
3418 SecPolicyRef
SecPolicyCreateAppleSSLService(CFStringRef hostname
)
3420 // SSL server, pinned to an Apple intermediate
3421 SecPolicyRef policy
= SecPolicyCreateSSL(true, hostname
);
3422 CFMutableDictionaryRef options
= NULL
;
3423 require(policy
, errOut
);
3425 // change options for SSL policy evaluation
3426 require((options
=(CFMutableDictionaryRef
)policy
->_options
) != NULL
, errOut
);
3428 // Apple CA anchored
3429 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameAppleSSLService
), errOut
);
3431 // Check leaf for Apple Server Authentication marker oid (1.2.840.113635.100.6.27.1)
3432 add_leaf_marker(options
, &oidAppleCertExtAppleServerAuthentication
);
3434 // Check intermediate for Apple Server Authentication intermediate marker (1.2.840.113635.100.6.2.12)
3435 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleServerAuthentication
);
3437 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
3439 SecPolicySetOid(policy
, kSecPolicyAppleServerAuthentication
);
3440 SecPolicySetName(policy
, kSecPolicyNameAppleSSLService
);
3445 CFReleaseSafe(options
);
3446 CFReleaseSafe(policy
);
3451 @function SecPolicyCreateApplePPQSigning
3452 @abstract Check for intermediate certificate 'Apple System Integration 2 Certification Authority' by name,
3454 Leaf cert must have Digital Signature usage.
3455 Leaf cert must have Apple PPQ Signing marker OID (1.2.840.113635.100.6.38.2).
3456 Intermediate must have marker OID (1.2.840.113635.100.6.2.10).
3458 SecPolicyRef
SecPolicyCreateApplePPQSigning(void)
3460 SecPolicyRef result
= NULL
;
3461 CFMutableDictionaryRef options
= NULL
;
3462 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3463 &kCFTypeDictionaryKeyCallBacks
,
3464 &kCFTypeDictionaryValueCallBacks
), errOut
);
3465 SecPolicyAddBasicCertOptions(options
);
3467 SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameApplePPQSigning
);
3468 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3470 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
3471 CFSTR("Apple System Integration 2 Certification Authority"));
3473 // Check that leaf has extension with "Apple PPQ Signing" prod oid (1.2.840.113635.100.6.38.2)
3474 add_leaf_marker(options
, &oidAppleCertExtApplePPQSigningProd
);
3476 // Check that intermediate has extension (1.2.840.113635.100.6.2.10)
3477 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleSystemIntg2
);
3479 add_ku(options
, kSecKeyUsageDigitalSignature
);
3481 require(result
= SecPolicyCreate(kSecPolicyApplePPQSigning
,
3482 kSecPolicyNameApplePPQSigning
, options
), errOut
);
3485 CFReleaseSafe(options
);
3490 @function SecPolicyCreateTestApplePPQSigning
3491 @abstract Check for intermediate certificate 'Apple System Integration 2 Certification Authority' by name,
3493 Leaf cert must have Digital Signature usage.
3494 Leaf cert must have Apple PPQ Signing Test marker OID (1.2.840.113635.100.6.38.1).
3495 Intermediate must have marker OID (1.2.840.113635.100.6.2.10).
3497 SecPolicyRef
SecPolicyCreateTestApplePPQSigning(void)
3499 /* Guard against use of test policy on production devices */
3500 if (!SecIsInternalRelease()) {
3501 return SecPolicyCreateApplePPQSigning();
3504 SecPolicyRef result
= NULL
;
3505 CFMutableDictionaryRef options
= NULL
;
3506 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3507 &kCFTypeDictionaryKeyCallBacks
,
3508 &kCFTypeDictionaryValueCallBacks
), errOut
);
3509 SecPolicyAddBasicCertOptions(options
);
3511 SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameAppleTestPPQSigning
);
3512 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3514 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
3515 CFSTR("Apple System Integration 2 Certification Authority"));
3517 // Check that leaf has extension with "Apple PPQ Signing" test oid (1.2.840.113635.100.6.38.1)
3518 add_leaf_marker(options
, &oidAppleCertExtApplePPQSigningTest
);
3520 // Check that intermediate has extension (1.2.840.113635.100.6.2.10)
3521 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleSystemIntg2
);
3523 add_ku(options
, kSecKeyUsageDigitalSignature
);
3525 require(result
= SecPolicyCreate(kSecPolicyAppleTestPPQSigning
,
3526 kSecPolicyNameAppleTestPPQSigning
, options
), errOut
);
3529 CFReleaseSafe(options
);
3533 @function SecPolicyCreateAppleTimeStamping
3534 @abstract Check for RFC3161 timestamping EKU.
3536 SecPolicyRef
SecPolicyCreateAppleTimeStamping(void)
3538 SecPolicyRef result
= NULL
;
3539 CFMutableDictionaryRef options
= NULL
;
3540 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3541 &kCFTypeDictionaryKeyCallBacks
,
3542 &kCFTypeDictionaryValueCallBacks
), errOut
);
3544 SecPolicyAddBasicX509Options(options
);
3546 /* Require id-kp-timeStamping extendedKeyUsage to be present. */
3547 add_eku(options
, &oidExtendedKeyUsageTimeStamping
);
3549 require(result
= SecPolicyCreate(kSecPolicyAppleTimeStamping
,
3550 kSecPolicyNameAppleTimeStamping
, options
), errOut
);
3553 CFReleaseSafe(options
);
3558 @function SecPolicyCreateApplePayIssuerEncryption
3559 @abstract Check for intermediate certificate 'Apple Worldwide Developer Relations CA - G2' by name,
3560 and ECC apple anchor.
3561 Leaf cert must have Key Encipherment and Key Agreement usage.
3562 Leaf cert must have Apple Pay Issuer Encryption marker OID (1.2.840.113635.100.6.39).
3564 SecPolicyRef
SecPolicyCreateApplePayIssuerEncryption(void)
3566 SecPolicyRef result
= NULL
;
3567 CFMutableDictionaryRef options
= NULL
;
3568 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3569 &kCFTypeDictionaryKeyCallBacks
,
3570 &kCFTypeDictionaryValueCallBacks
), errOut
);
3571 SecPolicyAddBasicCertOptions(options
);
3573 require(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameApplePayIssuerEncryption
),
3575 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3577 CFDictionaryAddValue(options
, kSecPolicyCheckIssuerCommonName
,
3578 CFSTR("Apple Worldwide Developer Relations CA - G2"));
3580 // Check that leaf has extension with "Apple Pay Issuer Encryption" oid (1.2.840.113635.100.6.39)
3581 add_leaf_marker(options
, &oidAppleCertExtCryptoServicesExtEncryption
);
3583 add_ku(options
, kSecKeyUsageKeyEncipherment
);
3585 require(result
= SecPolicyCreate(kSecPolicyApplePayIssuerEncryption
,
3586 kSecPolicyNameApplePayIssuerEncryption
, options
), errOut
);
3589 CFReleaseSafe(options
);
3594 @function SecPolicyCreateAppleATVVPNProfileSigning
3595 @abstract Check for leaf marker OID 1.2.840.113635.100.6.43,
3596 intermediate marker OID 1.2.840.113635.100.6.2.10,
3597 chains to Apple Root CA, path length 3
3599 SecPolicyRef
SecPolicyCreateAppleATVVPNProfileSigning(void)
3601 SecPolicyRef result
= NULL
;
3602 CFMutableDictionaryRef options
= NULL
;
3603 CFMutableDictionaryRef appleAnchorOptions
= NULL
;
3604 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3605 &kCFTypeDictionaryKeyCallBacks
,
3606 &kCFTypeDictionaryValueCallBacks
), errOut
);
3608 SecPolicyAddBasicCertOptions(options
);
3610 // Require pinning to the Apple CAs (including test CA for internal releases)
3611 appleAnchorOptions
= CFDictionaryCreateMutableForCFTypes(NULL
);
3612 require(appleAnchorOptions
, errOut
);
3614 if (SecIsInternalRelease()) {
3615 CFDictionarySetValue(appleAnchorOptions
,
3616 kSecPolicyAppleAnchorIncludeTestRoots
, kCFBooleanTrue
);
3619 add_element(options
, kSecPolicyCheckAnchorApple
, appleAnchorOptions
);
3621 // Cert chain length 3
3622 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3624 // Check leaf for Apple ATV VPN Profile Signing OID (1.2.840.113635.100.6.43)
3625 add_leaf_marker(options
, &oidAppleCertExtATVVPNProfileSigning
);
3627 // Check intermediate for Apple System Integration 2 CA intermediate marker (1.2.840.113635.100.6.2.10)
3628 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleSystemIntg2
);
3630 // Ensure that revocation is checked (OCSP only)
3631 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationOCSP
);
3633 require(result
= SecPolicyCreate(kSecPolicyAppleATVVPNProfileSigning
,
3634 kSecPolicyNameAppleATVVPNProfileSigning
, options
), errOut
);
3637 CFReleaseSafe(options
);
3638 CFReleaseSafe(appleAnchorOptions
);
3642 SecPolicyRef
SecPolicyCreateAppleHomeKitServerAuth(CFStringRef hostname
) {
3643 CFMutableDictionaryRef appleAnchorOptions
= NULL
;
3644 CFMutableDictionaryRef options
= NULL
;
3645 SecPolicyRef result
= NULL
;
3646 CFDataRef oid
= NULL
;
3648 options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0, &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
3649 require(options
, errOut
);
3651 SecPolicyAddBasicX509Options(options
);
3653 CFDictionaryAddValue(options
, kSecPolicyCheckSSLHostname
, hostname
);
3655 add_eku(options
, &oidExtendedKeyUsageServerAuth
);
3657 if (requireUATPinning(kSecPolicyNameAppleHomeKitServerAuth
)) {
3658 bool allowUAT
= allowUATRoot(false, kSecPolicyNameAppleHomeKitServerAuth
, NULL
);
3660 // Cert chain length 3
3661 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3663 // Apple anchors, allowing test anchors for internal releases properly configured
3664 appleAnchorOptions
= CFDictionaryCreateMutableForCFTypes(NULL
);
3665 require(appleAnchorOptions
, errOut
);
3666 if (allowUAT
|| allowTestHierarchyForPolicy(kSecPolicyNameAppleHomeKitServerAuth
)) {
3667 CFDictionarySetValue(appleAnchorOptions
,
3668 kSecPolicyAppleAnchorIncludeTestRoots
, kCFBooleanTrue
);
3670 add_element(options
, kSecPolicyCheckAnchorApple
, appleAnchorOptions
);
3672 add_leaf_marker(options
, &oidAppleCertExtHomeKitServerAuth
);
3674 add_oid(options
, kSecPolicyCheckIntermediateMarkerOid
, &oidAppleIntmMarkerAppleHomeKitServerCA
);
3678 CFDictionaryAddValue(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
3680 result
= SecPolicyCreate(kSecPolicyAppleHomeKitServerAuth
,
3681 kSecPolicyNameAppleHomeKitServerAuth
, options
);
3682 require(result
, errOut
);
3685 CFReleaseSafe(appleAnchorOptions
);
3686 CFReleaseSafe(options
);
3691 SecPolicyRef
SecPolicyCreateAppleExternalDeveloper(void) {
3692 CFMutableDictionaryRef options
= NULL
;
3693 SecPolicyRef result
= NULL
;
3695 /* Create basic Apple pinned policy */
3696 require(result
= SecPolicyCreateApplePinned(kSecPolicyNameAppleExternalDeveloper
,
3697 CFSTR("1.2.840.113635.100.6.2.1"), // WWDR Intermediate OID
3698 CFSTR("1.2.840.113635.100.6.1.2")), // "iPhone Developer" leaf OID
3701 require_action(options
= CFDictionaryCreateMutableCopy(NULL
, 0, result
->_options
), errOut
, CFReleaseNull(result
));
3703 /* Additional intermediate OIDs */
3704 add_element(options
, kSecPolicyCheckIntermediateMarkerOid
,
3705 CFSTR("1.2.840.113635.100.6.2.6")); // "Developer ID" Intermediate OID
3707 /* Addtional leaf OIDS */
3708 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.4")); // "iPhone Distribution" leaf OID
3709 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.5")); // "Safari Developer" leaf OID
3710 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.7")); // "3rd Party Mac Developer Application" leaf OID
3711 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.8")); // "3rd Party Mac Developer Installer" leaf OID
3712 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.12")); // "Mac Developer" leaf OID
3713 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.13")); // "Developer ID Application" leaf OID
3714 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.1.14")); // "Developer ID Installer" leaf OID
3717 add_eku_string(options
, CFSTR("1.3.6.1.5.5.7.3.3")); // CodeSigning EKU
3718 add_eku_string(options
, CFSTR("1.2.840.113635.100.4.8")); // "Safari Developer" EKU
3719 add_eku_string(options
, CFSTR("1.2.840.113635.100.4.9")); // "3rd Party Mac Developer Installer" EKU
3720 add_eku_string(options
, CFSTR("1.2.840.113635.100.4.13")); // "Developer ID Installer" EKU
3722 CFReleaseSafe(result
->_options
);
3723 result
->_options
= CFRetainSafe(options
);
3725 SecPolicySetOid(result
, kSecPolicyAppleExternalDeveloper
);
3728 CFReleaseSafe(options
);
3732 /* This one is special because the intermediate has no marker OID */
3733 SecPolicyRef
SecPolicyCreateAppleSoftwareSigning(void) {
3734 CFMutableDictionaryRef options
= NULL
;
3735 CFDictionaryRef keySizes
= NULL
;
3736 CFNumberRef rsaSize
= NULL
, ecSize
= NULL
;
3737 SecPolicyRef result
= NULL
;
3739 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3740 &kCFTypeDictionaryKeyCallBacks
,
3741 &kCFTypeDictionaryValueCallBacks
), errOut
);
3743 SecPolicyAddBasicX509Options(options
);
3745 /* Anchored to the Apple Roots */
3746 require_quiet(SecPolicyAddAppleAnchorOptions(options
, kSecPolicyNameAppleSoftwareSigning
),
3749 /* Exactly 3 certs in the chain */
3750 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3752 /* Intermediate Common Name matches */
3753 add_element(options
, kSecPolicyCheckIssuerCommonName
, CFSTR("Apple Code Signing Certification Authority"));
3755 /* Leaf marker OID matches */
3756 add_leaf_marker_string(options
, CFSTR("1.2.840.113635.100.6.22"));
3758 /* Leaf has CodeSigning EKU */
3759 add_eku_string(options
, CFSTR("1.3.6.1.5.5.7.3.3"));
3761 /* Check revocation using any available method */
3762 add_element(options
, kSecPolicyCheckRevocation
, kSecPolicyCheckRevocationAny
);
3764 /* RSA key sizes are 2048-bit or larger. EC key sizes are P-256 or larger. */
3765 require(rsaSize
= CFNumberCreateWithCFIndex(NULL
, 2048), errOut
);
3766 require(ecSize
= CFNumberCreateWithCFIndex(NULL
, 256), errOut
);
3767 const void *keys
[] = { kSecAttrKeyTypeRSA
, kSecAttrKeyTypeEC
};
3768 const void *values
[] = { rsaSize
, ecSize
};
3769 require(keySizes
= CFDictionaryCreate(NULL
, keys
, values
, 2,
3770 &kCFTypeDictionaryKeyCallBacks
,
3771 &kCFTypeDictionaryValueCallBacks
), errOut
);
3772 add_element(options
, kSecPolicyCheckKeySize
, keySizes
);
3775 require(result
= SecPolicyCreate(kSecPolicyAppleSoftwareSigning
,
3776 kSecPolicyNameAppleSoftwareSigning
, options
), errOut
);
3779 CFReleaseSafe(options
);
3780 CFReleaseSafe(keySizes
);
3781 CFReleaseSafe(rsaSize
);
3782 CFReleaseSafe(ecSize
);
3786 /* subject:/CN=SEP Root CA/O=Apple Inc./ST=California */
3787 /* SKID: 58:EF:D6:BE:C5:82:B0:54:CD:18:A6:84:AD:A2:F6:7B:7B:3A:7F:CF */
3788 /* Not Before: Jun 24 21:43:24 2014 GMT, Not After : Jun 24 21:43:24 2029 GMT */
3789 /* Signature Algorithm: ecdsa-with-SHA384 */
3790 const uint8_t SEPRootCA_SHA256
[kSecPolicySHA256Size
] = {
3791 0xd1, 0xdf, 0x82, 0x00, 0xf3, 0x89, 0x4e, 0xe9, 0x96, 0xf3, 0x77, 0xdf, 0x76, 0x3b, 0x0a, 0x16,
3792 0x8f, 0xd9, 0x6c, 0x58, 0xc0, 0x3e, 0xc9, 0xb0, 0x5f, 0xa5, 0x64, 0x79, 0xc0, 0xe8, 0xc9, 0xe7
3795 SecPolicyRef
SecPolicyCreateAppleUniqueDeviceCertificate(CFDataRef testRootHash
) {
3796 CFMutableDictionaryRef options
= NULL
;
3797 CFDictionaryRef keySizes
= NULL
;
3798 CFNumberRef ecSize
= NULL
;
3799 SecPolicyRef result
= NULL
;
3801 require(options
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
3802 &kCFTypeDictionaryKeyCallBacks
,
3803 &kCFTypeDictionaryValueCallBacks
), errOut
);
3805 /* Device certificate should never expire */
3806 SecPolicyAddBasicCertOptions(options
);
3808 /* Anchored to the SEP Root CA. Allow alternative root for developers */
3809 require(SecPolicyAddAnchorSHA256Options(options
, SEPRootCA_SHA256
),errOut
);
3810 if (testRootHash
&& SecIsInternalRelease() && !SecIsProductionFused() &&
3811 allowTestHierarchyForPolicy(kSecPolicyNameAppleUniqueDeviceCertificate
)
3812 && (kSecPolicySHA256Size
== CFDataGetLength(testRootHash
))) {
3813 add_element(options
, kSecPolicyCheckAnchorSHA256
, testRootHash
);
3816 /* Exactly 3 certs in the chain */
3817 require(SecPolicyAddChainLengthOptions(options
, 3), errOut
);
3819 /* Intermediate has marker OID with value */
3820 add_intermediate_marker_value_string(options
, CFSTR("1.2.840.113635.100.6.44"), CFSTR("ucrt"));
3822 /* Leaf has marker OID with varying value that can't be pre-determined */
3823 add_element(options
, kSecPolicyCheckLeafMarkerOidWithoutValueCheck
, CFSTR("1.2.840.113635.100.10.1"));
3825 /* RSA key sizes are disallowed. EC key sizes are P-256 or larger. */
3826 require(ecSize
= CFNumberCreateWithCFIndex(NULL
, 256), errOut
);
3827 require(keySizes
= CFDictionaryCreate(NULL
, (const void**)&kSecAttrKeyTypeEC
,
3828 (const void**)&ecSize
, 1,
3829 &kCFTypeDictionaryKeyCallBacks
,
3830 &kCFTypeDictionaryValueCallBacks
), errOut
);
3831 add_element(options
, kSecPolicyCheckKeySize
, keySizes
);
3834 require(result
= SecPolicyCreate(kSecPolicyAppleUniqueDeviceIdentifierCertificate
,
3835 kSecPolicyNameAppleUniqueDeviceCertificate
, options
), errOut
);
3838 CFReleaseSafe(options
);
3839 CFReleaseSafe(keySizes
);
3840 CFReleaseSafe(ecSize
);