3 * Copyright (c) 2002-2015 Apple Inc. All Rights Reserved.
5 * @APPLE_LICENSE_HEADER_START@
7 * This file contains Original Code and/or Modifications of Original Code
8 * as defined in and that are subject to the Apple Public Source License
9 * Version 2.0 (the 'License'). You may not use this file except in
10 * compliance with the License. Please obtain a copy of the License at
11 * http://www.opensource.apple.com/apsl/ and read it before using this
14 * The Original Code and all software distributed under the License are
15 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
19 * Please see the License for the specific language governing rights and
20 * limitations under the License.
22 * @APPLE_LICENSE_HEADER_END@
25 #include <CoreFoundation/CFString.h>
26 #include <CoreFoundation/CFNumber.h>
27 #include <CoreFoundation/CFArray.h>
28 #include <Security/SecItem.h>
29 #include <Security/SecPolicy.h>
30 #include <Security/SecPolicyPriv.h>
31 #include <Security/SecCertificate.h>
32 #include <Security/SecCertificatePriv.h>
33 #include <security_keychain/Policies.h>
34 #include <security_keychain/PolicyCursor.h>
35 #include "SecBridge.h"
36 #include "utilities/SecCFRelease.h"
40 // String constant declarations
42 #define SEC_CONST_DECL(k,v) const CFStringRef k = CFSTR(v);
45 SEC_CONST_DECL (kSecPolicyAppleX509Basic
, "1.2.840.113635.100.1.2");
46 SEC_CONST_DECL (kSecPolicyAppleSSL
, "1.2.840.113635.100.1.3");
47 SEC_CONST_DECL (kSecPolicyAppleSMIME
, "1.2.840.113635.100.1.8");
48 SEC_CONST_DECL (kSecPolicyAppleEAP
, "1.2.840.113635.100.1.9");
49 SEC_CONST_DECL (kSecPolicyAppleSWUpdateSigning
, "1.2.840.113635.100.1.10");
50 SEC_CONST_DECL (kSecPolicyAppleIPsec
, "1.2.840.113635.100.1.11");
51 SEC_CONST_DECL (kSecPolicyAppleiChat
, "1.2.840.113635.100.1.12");
52 SEC_CONST_DECL (kSecPolicyApplePKINITClient
, "1.2.840.113635.100.1.14");
53 SEC_CONST_DECL (kSecPolicyApplePKINITServer
, "1.2.840.113635.100.1.15");
54 SEC_CONST_DECL (kSecPolicyAppleCodeSigning
, "1.2.840.113635.100.1.16");
55 SEC_CONST_DECL (kSecPolicyApplePackageSigning
, "1.2.840.113635.100.1.17");
56 SEC_CONST_DECL (kSecPolicyAppleIDValidation
, "1.2.840.113635.100.1.18");
57 SEC_CONST_DECL (kSecPolicyMacAppStoreReceipt
, "1.2.840.113635.100.1.19");
58 SEC_CONST_DECL (kSecPolicyAppleTimeStamping
, "1.2.840.113635.100.1.20");
59 SEC_CONST_DECL (kSecPolicyAppleRevocation
, "1.2.840.113635.100.1.21");
60 SEC_CONST_DECL (kSecPolicyApplePassbookSigning
, "1.2.840.113635.100.1.22");
61 SEC_CONST_DECL (kSecPolicyAppleMobileStore
, "1.2.840.113635.100.1.23");
62 SEC_CONST_DECL (kSecPolicyAppleEscrowService
, "1.2.840.113635.100.1.24");
63 SEC_CONST_DECL (kSecPolicyAppleProfileSigner
, "1.2.840.113635.100.1.25");
64 SEC_CONST_DECL (kSecPolicyAppleQAProfileSigner
, "1.2.840.113635.100.1.26");
65 SEC_CONST_DECL (kSecPolicyAppleTestMobileStore
, "1.2.840.113635.100.1.27");
66 SEC_CONST_DECL (kSecPolicyAppleOTAPKISigner
, "1.2.840.113635.100.1.28");
67 SEC_CONST_DECL (kSecPolicyAppleTestOTAPKISigner
, "1.2.840.113635.100.1.29");
68 /* FIXME: this policy name should be deprecated and replaced with "kSecPolicyAppleIDValidationRecordSigning" */
69 SEC_CONST_DECL (kSecPolicyAppleIDValidationRecordSigningPolicy
, "1.2.840.113635.100.1.30");
70 SEC_CONST_DECL (kSecPolicyAppleSMPEncryption
, "1.2.840.113635.100.1.31");
71 SEC_CONST_DECL (kSecPolicyAppleTestSMPEncryption
, "1.2.840.113635.100.1.32");
72 SEC_CONST_DECL (kSecPolicyAppleServerAuthentication
, "1.2.840.113635.100.1.33");
73 SEC_CONST_DECL (kSecPolicyApplePCSEscrowService
, "1.2.840.113635.100.1.34");
74 SEC_CONST_DECL (kSecPolicyApplePPQSigning
, "1.2.840.113635.100.1.35");
75 SEC_CONST_DECL (kSecPolicyAppleTestPPQSigning
, "1.2.840.113635.100.1.36");
76 SEC_CONST_DECL (kSecPolicyApplePayIssuerEncryption
, "1.2.840.113635.100.1.39");
77 SEC_CONST_DECL (kSecPolicyAppleOSXProvisioningProfileSigning
, "1.2.840.113635.100.1.40");
78 SEC_CONST_DECL (kSecPolicyAppleAST2DiagnosticsServerAuth
, "1.2.840.113635.100.1.42");
79 SEC_CONST_DECL (kSecPolicyAppleEscrowProxyServerAuth
, "1.2.840.113635.100.1.43");
80 SEC_CONST_DECL (kSecPolicyAppleFMiPServerAuth
, "1.2.840.113635.100.1.44");
82 SEC_CONST_DECL (kSecPolicyOid
, "SecPolicyOid");
83 SEC_CONST_DECL (kSecPolicyName
, "SecPolicyName");
84 SEC_CONST_DECL (kSecPolicyClient
, "SecPolicyClient");
85 SEC_CONST_DECL (kSecPolicyRevocationFlags
, "SecPolicyRevocationFlags");
86 SEC_CONST_DECL (kSecPolicyTeamIdentifier
, "SecPolicyTeamIdentifier");
88 /* Some of these aren't defined in SecPolicy.c, but used here. */
89 SEC_CONST_DECL (kSecPolicyAppleiChat
, "1.2.840.113635.100.1.12");
96 CFDictionaryRef
SecPolicyGetOptions(SecPolicyRef policy
);
97 void SecPolicySetOptionsValue(SecPolicyRef policy
, CFStringRef key
, CFTypeRef value
);
101 // String to CSSM_OID mapping
103 struct oidmap_entry_s
{
104 const CFTypeRef oidstr
;
105 const SecAsn1Oid
*oidptr
;
107 typedef struct oidmap_entry_s oidmap_entry_t
;
109 // policies enumerated by SecPolicySearch (PolicyCursor.cpp)
111 static_cast<const CssmOid *>(&CSSMOID_APPLE_ISIGN), // no longer supported
112 static_cast<const CssmOid *>(&CSSMOID_APPLE_X509_BASIC),
113 static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_SSL),
114 static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_SMIME),
115 static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_EAP),
116 static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_SW_UPDATE_SIGNING),
117 static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_IP_SEC),
118 static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_ICHAT), // no longer supported
119 static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_RESOURCE_SIGN),
120 static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_PKINIT_CLIENT),
121 static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_PKINIT_SERVER),
122 static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_CODE_SIGNING),
123 static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_PACKAGE_SIGNING),
124 static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_REVOCATION_CRL),
125 static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_REVOCATION_OCSP),
126 static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_MACAPPSTORE_RECEIPT),
127 static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_APPLEID_SHARING),
128 static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_TIMESTAMPING),
130 const oidmap_entry_t oidmap
[] = {
131 { kSecPolicyAppleX509Basic
, &CSSMOID_APPLE_X509_BASIC
},
132 { kSecPolicyAppleSSL
, &CSSMOID_APPLE_TP_SSL
},
133 { kSecPolicyAppleSMIME
, &CSSMOID_APPLE_TP_SMIME
},
134 { kSecPolicyAppleEAP
, &CSSMOID_APPLE_TP_EAP
},
135 { kSecPolicyAppleSWUpdateSigning
, &CSSMOID_APPLE_TP_SW_UPDATE_SIGNING
},
136 { kSecPolicyAppleIPsec
, &CSSMOID_APPLE_TP_IP_SEC
},
137 { kSecPolicyAppleiChat
, &CSSMOID_APPLE_TP_ICHAT
},
138 { kSecPolicyApplePKINITClient
, &CSSMOID_APPLE_TP_PKINIT_CLIENT
},
139 { kSecPolicyApplePKINITServer
, &CSSMOID_APPLE_TP_PKINIT_SERVER
},
140 { kSecPolicyAppleCodeSigning
, &CSSMOID_APPLE_TP_CODE_SIGNING
},
141 { kSecPolicyApplePackageSigning
, &CSSMOID_APPLE_TP_PACKAGE_SIGNING
},
142 { kSecPolicyAppleIDValidation
, &CSSMOID_APPLE_TP_APPLEID_SHARING
},
143 { kSecPolicyMacAppStoreReceipt
, &CSSMOID_APPLE_TP_MACAPPSTORE_RECEIPT
},
144 { kSecPolicyAppleTimeStamping
, &CSSMOID_APPLE_TP_TIMESTAMPING
},
145 { kSecPolicyAppleRevocation
, &CSSMOID_APPLE_TP_REVOCATION
},
146 { kSecPolicyAppleRevocation
, &CSSMOID_APPLE_TP_REVOCATION_OCSP
},
147 { kSecPolicyAppleRevocation
, &CSSMOID_APPLE_TP_REVOCATION_CRL
},
148 { kSecPolicyApplePassbookSigning
, &CSSMOID_APPLE_TP_PASSBOOK_SIGNING
},
149 { kSecPolicyAppleMobileStore
, &CSSMOID_APPLE_TP_MOBILE_STORE
},
150 { kSecPolicyAppleEscrowService
, &CSSMOID_APPLE_TP_ESCROW_SERVICE
},
151 { kSecPolicyAppleProfileSigner
, &CSSMOID_APPLE_TP_PROFILE_SIGNING
},
152 { kSecPolicyAppleQAProfileSigner
, &CSSMOID_APPLE_TP_QA_PROFILE_SIGNING
},
153 { kSecPolicyAppleTestMobileStore
, &CSSMOID_APPLE_TP_TEST_MOBILE_STORE
},
154 { kSecPolicyApplePCSEscrowService
, &CSSMOID_APPLE_TP_PCS_ESCROW_SERVICE
},
155 { kSecPolicyAppleOSXProvisioningProfileSigning
, &CSSMOID_APPLE_TP_PROVISIONING_PROFILE_SIGNING
},
159 const oidmap_entry_t oidmap_priv
[] = {
160 { CFSTR("basicX509"), &CSSMOID_APPLE_X509_BASIC
},
161 { CFSTR("sslServer"), &CSSMOID_APPLE_TP_SSL
},
162 { CFSTR("sslClient"), &CSSMOID_APPLE_TP_SSL
},
163 { CFSTR("SMIME"), &CSSMOID_APPLE_TP_SMIME
},
164 { CFSTR("eapServer"), &CSSMOID_APPLE_TP_EAP
},
165 { CFSTR("eapClient"), &CSSMOID_APPLE_TP_EAP
},
166 { CFSTR("AppleSWUpdateSigning"), &CSSMOID_APPLE_TP_SW_UPDATE_SIGNING
},
167 { CFSTR("ipsecServer"), &CSSMOID_APPLE_TP_IP_SEC
},
168 { CFSTR("ipsecClient"), &CSSMOID_APPLE_TP_IP_SEC
},
169 { CFSTR("CodeSigning"), &CSSMOID_APPLE_TP_CODE_SIGNING
},
170 { CFSTR("PackageSigning"), &CSSMOID_APPLE_TP_PACKAGE_SIGNING
},
171 { CFSTR("AppleIDAuthority"), &CSSMOID_APPLE_TP_APPLEID_SHARING
},
172 { CFSTR("MacAppStoreReceipt"), &CSSMOID_APPLE_TP_MACAPPSTORE_RECEIPT
},
173 { CFSTR("AppleTimeStamping"), &CSSMOID_APPLE_TP_TIMESTAMPING
},
174 { CFSTR("revocation"), &CSSMOID_APPLE_TP_REVOCATION
},
175 { CFSTR("ApplePassbook"), &CSSMOID_APPLE_TP_PASSBOOK_SIGNING
},
176 { CFSTR("AppleMobileStore"), &CSSMOID_APPLE_TP_MOBILE_STORE
},
177 { CFSTR("AppleEscrowService"), &CSSMOID_APPLE_TP_ESCROW_SERVICE
},
178 { CFSTR("AppleProfileSigner"), &CSSMOID_APPLE_TP_PROFILE_SIGNING
},
179 { CFSTR("AppleQAProfileSigner"), &CSSMOID_APPLE_TP_QA_PROFILE_SIGNING
},
180 { CFSTR("AppleTestMobileStore"), &CSSMOID_APPLE_TP_TEST_MOBILE_STORE
},
181 { CFSTR("ApplePCSEscrowService"), &CSSMOID_APPLE_TP_PCS_ESCROW_SERVICE
},
182 { CFSTR("AppleOSXProvisioningProfileSigning"), &CSSMOID_APPLE_TP_PROVISIONING_PROFILE_SIGNING
},
191 SecPolicyGetTypeID(void)
194 return gTypes().Policy
.typeID
;
195 END_SECAPI1(_kCFRuntimeNotATypeID
)
200 // Sec API bridge functions
202 /* OS X only: __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2, __MAC_10_7, __IPHONE_NA, __IPHONE_NA) */
204 SecPolicyGetOID(SecPolicyRef policyRef
, CSSM_OID
* oid
)
208 Required(oid
) = Policy::required(policyRef
)->oid();
211 /* bridge to support old functionality */
215 CFStringRef oidStr
= (CFStringRef
) SecPolicyGetOidString(policyRef
);
216 if (!oidStr
|| !oid
) {
217 return errSecParam
; // bad policy ref?
219 CSSM_OID
*oidptr
= NULL
;
220 unsigned int i
, oidmaplen
= sizeof(oidmap
) / sizeof(oidmap_entry_t
);
221 for (i
=0; i
<oidmaplen
; i
++) {
222 CFStringRef str
= (CFStringRef
) oidmap
[i
].oidstr
;
223 if (CFStringCompare(str
, oidStr
, 0) == kCFCompareEqualTo
) {
224 oidptr
= (CSSM_OID
*)oidmap
[i
].oidptr
;
229 // Check private iOS policy names.
230 oidmaplen
= sizeof(oidmap_priv
) / sizeof(oidmap_entry_t
);
231 for (i
=0; i
<oidmaplen
; i
++) {
232 CFStringRef str
= (CFStringRef
) oidmap_priv
[i
].oidstr
;
233 if (CFStringCompare(str
, oidStr
, 0) == kCFCompareEqualTo
) {
234 oidptr
= (CSSM_OID
*)oidmap_priv
[i
].oidptr
;
240 oid
->Data
= oidptr
->Data
;
241 oid
->Length
= oidptr
->Length
;
242 return errSecSuccess
;
245 syslog(LOG_ERR
, "WARNING: SecPolicyGetOID failed to return an OID. This function was deprecated in 10.7. Please use SecPolicyCopyProperties instead.");
246 return errSecServiceNotAvailable
;
250 // TODO: use a version of this function from a utility library
251 static CSSM_BOOL
compareOids(
252 const CSSM_OID
*oid1
,
253 const CSSM_OID
*oid2
)
255 if((oid1
== NULL
) || (oid2
== NULL
)) {
258 if(oid1
->Length
!= oid2
->Length
) {
261 if(memcmp(oid1
->Data
, oid2
->Data
, oid1
->Length
)) {
270 CFStringRef
SecPolicyGetStringForOID(CSSM_OID
* oid
)
275 // given a CSSM_OID pointer, return corresponding string in oidmap
276 unsigned int i
, oidmaplen
= sizeof(oidmap
) / sizeof(oidmap_entry_t
);
277 for (i
=0; i
<oidmaplen
; i
++) {
278 CSSM_OID
* oidptr
= (CSSM_OID
*)oidmap
[i
].oidptr
;
279 if (compareOids(oid
, oidptr
)) {
280 return (CFStringRef
) oidmap
[i
].oidstr
;
287 static bool SecPolicyGetCSSMDataValueForString(SecPolicyRef policyRef
, CFStringRef stringRef
, CSSM_DATA
* value
)
289 // Old API expects to vend a pointer and length for a policy value.
290 // The API contract says this pointer is good for the life of the policy.
291 // However, the new policy values are CF objects, and we need a separate
292 // buffer to get their UTF8 bytes. This buffer needs to be released when
293 // the policy object is released.
295 CFDataRef data
= NULL
;
296 CFIndex maxLength
= CFStringGetMaximumSizeForEncoding(CFStringGetLength(stringRef
), kCFStringEncodingUTF8
) + 1;
297 char* buf
= (char*) malloc(maxLength
);
301 if (CFStringGetCString(stringRef
, buf
, (CFIndex
)maxLength
, kCFStringEncodingUTF8
)) {
302 CFIndex length
= strlen(buf
);
303 data
= CFDataCreate(NULL
, (const UInt8
*)buf
, length
);
307 value
->Data
= (uint8
*)((data
) ? CFDataGetBytePtr(data
) : NULL
);
308 value
->Length
= (CSSM_SIZE
)((data
) ? CFDataGetLength(data
) : 0);
311 // stash this in a place where it will be released when the policy is destroyed
313 SecPolicySetOptionsValue(policyRef
, CFSTR("policy_data"), data
);
317 syslog(LOG_ERR
, "WARNING: policy dictionary not found to store returned data; will leak!");
324 /* OS X only: __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2, __MAC_10_7, __IPHONE_NA, __IPHONE_NA) */
326 SecPolicyGetValue(SecPolicyRef policyRef
, CSSM_DATA
* value
)
330 Required(value
) = Policy::required(policyRef
)->value();
333 /* bridge to support old functionality */
334 #if SECTRUST_DEPRECATION_WARNINGS
335 syslog(LOG_ERR
, "WARNING: SecPolicyGetValue was deprecated in 10.7. Please use SecPolicyCopyProperties instead.");
337 if (!(policyRef
&& value
)) {
340 CFDictionaryRef options
= SecPolicyGetOptions(policyRef
);
341 if (!(options
&& (CFDictionaryGetTypeID() == CFGetTypeID(options
)))) {
344 CFTypeRef name
= NULL
;
346 if (CFDictionaryGetValueIfPresent(options
, CFSTR("SSLHostname") /*kSecPolicyCheckSSLHostname*/,
347 (const void **)&name
) && name
) {
350 if (CFDictionaryGetValueIfPresent(options
, CFSTR("EAPTrustedServerNames") /*kSecPolicyCheckEAPTrustedServerNames*/,
351 (const void **)&name
) && name
) {
354 if (CFDictionaryGetValueIfPresent(options
, CFSTR("email") /*kSecPolicyCheckEmail*/,
355 (const void **)&name
) && name
) {
360 CFTypeID typeID
= CFGetTypeID(name
);
361 if (CFArrayGetTypeID() == typeID
) {
362 name
= (CFStringRef
) CFArrayGetValueAtIndex((CFArrayRef
)name
, 0);
364 SecPolicyGetCSSMDataValueForString(policyRef
, (CFStringRef
)name
, value
);
370 return errSecSuccess
;
376 SecPolicyCopyProperties(SecPolicyRef policyRef
)
378 /* can't use SECAPI macros, since this function does not return OSStatus */
379 CFDictionaryRef result
= NULL
;
381 result
= Policy::required(policyRef
)->properties();
393 /* OS X only: __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2, __MAC_10_7, __IPHONE_NA, __IPHONE_NA) */
395 SecPolicySetValue(SecPolicyRef policyRef
, const CSSM_DATA
*value
)
400 const CssmData
newValue(value
->Data
, value
->Length
);
401 Policy::required(policyRef
)->setValue(newValue
);
404 /* bridge to support old functionality */
405 #if SECTRUST_DEPRECATION_WARNINGS
406 syslog(LOG_ERR
, "WARNING: SecPolicySetValue was deprecated in 10.7. Please use SecPolicySetProperties instead.");
408 if (!(policyRef
&& value
)) {
411 OSStatus status
= errSecSuccess
;
412 CFDataRef data
= NULL
;
413 CFStringRef name
= NULL
;
414 CFStringRef oid
= (CFStringRef
) SecPolicyGetOidString(policyRef
);
416 syslog(LOG_ERR
, "SecPolicySetValue: unknown policy OID");
417 return errSecParam
; // bad policy ref?
419 if (CFEqual(oid
, CFSTR("sslServer") /*kSecPolicyOIDSSLServer*/) ||
420 CFEqual(oid
, CFSTR("sslClient") /*kSecPolicyOIDSSLClient*/) ||
421 CFEqual(oid
, CFSTR("ipsecServer") /*kSecPolicyOIDIPSecServer*/) ||
422 CFEqual(oid
, CFSTR("ipsecClient") /*kSecPolicyOIDIPSecClient*/) ||
423 CFEqual(oid
, kSecPolicyAppleSSL
) ||
424 CFEqual(oid
, kSecPolicyAppleIPsec
) ||
425 CFEqual(oid
, kSecPolicyAppleIDValidation
)
427 CSSM_APPLE_TP_SSL_OPTIONS
*opts
= (CSSM_APPLE_TP_SSL_OPTIONS
*)value
->Data
;
428 if (opts
->Version
== CSSM_APPLE_TP_SSL_OPTS_VERSION
) {
429 if (opts
->ServerNameLen
> 0) {
430 data
= CFDataCreate(NULL
, (const UInt8
*)opts
->ServerName
, opts
->ServerNameLen
);
431 name
= (data
) ? CFStringCreateFromExternalRepresentation(NULL
, data
, kCFStringEncodingUTF8
) : NULL
;
435 SecPolicySetOptionsValue(policyRef
, CFSTR("SSLHostname") /*kSecPolicyCheckSSLHostname*/, name
);
438 status
= errSecParam
;
441 else if (CFEqual(oid
, CFSTR("eapServer") /*kSecPolicyOIDEAPServer*/) ||
442 CFEqual(oid
, CFSTR("eapClient") /*kSecPolicyOIDEAPClient*/) ||
443 CFEqual(oid
, kSecPolicyAppleEAP
)
445 CSSM_APPLE_TP_SSL_OPTIONS
*opts
= (CSSM_APPLE_TP_SSL_OPTIONS
*)value
->Data
;
446 if (opts
->Version
== CSSM_APPLE_TP_SSL_OPTS_VERSION
) {
447 if (opts
->ServerNameLen
> 0) {
448 data
= CFDataCreate(NULL
, (const UInt8
*)opts
->ServerName
, opts
->ServerNameLen
);
449 name
= (data
) ? CFStringCreateFromExternalRepresentation(NULL
, data
, kCFStringEncodingUTF8
) : NULL
;
453 SecPolicySetOptionsValue(policyRef
, CFSTR("EAPTrustedServerNames") /*kSecPolicyCheckEAPTrustedServerNames*/, name
);
456 status
= errSecParam
;
459 else if (CFEqual(oid
, CFSTR("SMIME") /*kSecPolicyOIDSMIME*/) ||
460 CFEqual(oid
, CFSTR("AppleShoebox") /*kSecPolicyOIDAppleShoebox*/) ||
461 CFEqual(oid
, CFSTR("ApplePassbook") /*kSecPolicyOIDApplePassbook*/) ||
462 CFEqual(oid
, kSecPolicyAppleSMIME
) ||
463 CFEqual(oid
, kSecPolicyApplePassbookSigning
)
465 CSSM_APPLE_TP_SMIME_OPTIONS
*opts
= (CSSM_APPLE_TP_SMIME_OPTIONS
*)value
->Data
;
466 if (opts
->Version
== CSSM_APPLE_TP_SMIME_OPTS_VERSION
) {
467 if (opts
->SenderEmailLen
> 0) {
468 data
= CFDataCreate(NULL
, (const UInt8
*)opts
->SenderEmail
, opts
->SenderEmailLen
);
469 name
= (data
) ? CFStringCreateFromExternalRepresentation(NULL
, data
, kCFStringEncodingUTF8
) : NULL
;
473 SecPolicySetOptionsValue(policyRef
, CFSTR("email") /*kSecPolicyCheckEmail*/, name
);
476 status
= errSecParam
;
479 else if (CFEqual(oid
, CFSTR("revocation") /* kSecPolicyOIDRevocation */) ||
480 CFEqual(oid
, kSecPolicyAppleRevocation
)
482 CSSM_APPLE_TP_CRL_OPTIONS
*opts
= (CSSM_APPLE_TP_CRL_OPTIONS
*)value
->Data
;
483 if (opts
->Version
== CSSM_APPLE_TP_CRL_OPTS_VERSION
) {
484 CSSM_APPLE_TP_CRL_OPT_FLAGS crlFlags
= opts
->CrlFlags
;
485 if ((crlFlags
& CSSM_TP_ACTION_FETCH_CRL_FROM_NET
) == 0) {
486 /* disable network access */
487 SecPolicySetOptionsValue(policyRef
, CFSTR("NoNetworkAccess") /*kSecPolicyCheckNoNetworkAccess*/, kCFBooleanTrue
);
489 if ((crlFlags
& CSSM_TP_ACTION_CRL_SUFFICIENT
) == 0) {
490 /* if CRL method is not sufficient, must use OCSP */
491 SecPolicySetOptionsValue(policyRef
, CFSTR("Revocation") /*kSecPolicyCheckRevocation*/,
492 CFSTR("OCSP")/*kSecPolicyCheckRevocationOCSP*/);
494 /* either method is sufficient */
495 SecPolicySetOptionsValue(policyRef
, CFSTR("Revocation") /*kSecPolicyCheckRevocation*/,
496 CFSTR("AnyRevocationMethod") /*kSecPolicyCheckRevocationAny*/);
499 if ((crlFlags
& CSSM_TP_ACTION_REQUIRE_CRL_PER_CERT
) != 0) {
500 /* require a response */
501 SecPolicySetOptionsValue(policyRef
,
502 CFSTR("RevocationResponseRequired") /*kSecPolicyCheckRevocationResponseRequired*/,
508 syslog(LOG_ERR
, "SecPolicySetValue: unrecognized policy OID");
509 status
= errSecParam
;
511 if (data
) { CFRelease(data
); }
512 if (name
) { CFRelease(name
); }
519 SecPolicySetProperties(SecPolicyRef policyRef
, CFDictionaryRef properties
)
522 Policy::required(policyRef
)->setProperties(properties
);
527 /* OS X only: __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2, __MAC_10_7, __IPHONE_NA, __IPHONE_NA) */
529 SecPolicyGetTPHandle(SecPolicyRef policyRef
, CSSM_TP_HANDLE
* tpHandle
)
533 Required(tpHandle
) = Policy::required(policyRef
)->tp()->handle();
536 /* this function is unsupported in unified SecTrust */
537 #if SECTRUST_DEPRECATION_WARNINGS
538 syslog(LOG_ERR
, "WARNING: SecPolicyGetTPHandle was deprecated in 10.7, and does nothing in 10.11. Please stop using it.");
540 return errSecServiceNotAvailable
;
544 /* OS X only: __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_3, __MAC_10_7, __IPHONE_NA, __IPHONE_NA) */
546 SecPolicyCopyAll(CSSM_CERT_TYPE certificateType
, CFArrayRef
* policies
)
551 CFMutableArrayRef currPolicies
= NULL
;
552 currPolicies
= CFArrayCreateMutable(NULL
, 0, NULL
);
555 SecPointer
<PolicyCursor
> cursor(new PolicyCursor(NULL
, NULL
));
556 SecPointer
<Policy
> policy
;
557 while ( cursor
->next(policy
) ) /* copies the next policy */
559 CFArrayAppendValue(currPolicies
, policy
->handle()); /* 'SecPolicyRef' appended */
560 CFRelease(policy
->handle()); /* refcount bumped up when appended to array */
562 *policies
= CFArrayCreateCopy(NULL
, currPolicies
);
563 CFRelease(currPolicies
);
564 CFRelease(cursor
->handle());
568 /* bridge to support old functionality */
569 #if SECTRUST_DEPRECATION_WARNINGS
570 syslog(LOG_ERR
, "WARNING: SecPolicyCopyAll was deprecated in 10.7. Please use SecPolicy creation functions instead.");
575 CFMutableArrayRef curPolicies
= CFArrayCreateMutable(NULL
, 0, NULL
);
577 return errSecAllocate
;
579 /* build the subset of policies which were supported on OS X,
580 and which are also implemented on iOS */
581 CFStringRef supportedPolicies
[] = {
582 kSecPolicyAppleX509Basic
, /* CSSMOID_APPLE_X509_BASIC */
583 kSecPolicyAppleSSL
, /* CSSMOID_APPLE_TP_SSL */
584 kSecPolicyAppleSMIME
, /* CSSMOID_APPLE_TP_SMIME */
585 kSecPolicyAppleEAP
, /*CSSMOID_APPLE_TP_EAP */
586 kSecPolicyAppleSWUpdateSigning
, /* CSSMOID_APPLE_TP_SW_UPDATE_SIGNING */
587 kSecPolicyAppleIPsec
, /* CSSMOID_APPLE_TP_IP_SEC */
588 kSecPolicyAppleCodeSigning
, /* CSSMOID_APPLE_TP_CODE_SIGNING */
589 kSecPolicyMacAppStoreReceipt
, /* CSSMOID_APPLE_TP_MACAPPSTORE_RECEIPT */
590 kSecPolicyAppleIDValidation
, /* CSSMOID_APPLE_TP_APPLEID_SHARING */
591 kSecPolicyAppleTimeStamping
, /* CSSMOID_APPLE_TP_TIMESTAMPING */
592 kSecPolicyAppleRevocation
, /* CSSMOID_APPLE_TP_REVOCATION_{CRL,OCSP} */
597 CFStringRef policyID
= supportedPolicies
[ix
++];
601 SecPolicyRef curPolicy
= SecPolicyCreateWithProperties(policyID
, NULL
);
603 CFArrayAppendValue(curPolicies
, curPolicy
);
604 CFRelease(curPolicy
);
607 *policies
= CFArrayCreateCopy(NULL
, curPolicies
);
608 CFRelease(curPolicies
);
609 return errSecSuccess
;
613 /* OS X only: __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_3, __MAC_10_7, __IPHONE_NA, __IPHONE_NA) */
615 SecPolicyCopy(CSSM_CERT_TYPE certificateType
, const CSSM_OID
*policyOID
, SecPolicyRef
* policy
)
621 if (!policyOID
|| !policy
) {
625 SecPolicySearchRef srchRef
= NULL
;
628 ortn
= SecPolicySearchCreate(certificateType
, policyOID
, NULL
, &srchRef
);
632 ortn
= SecPolicySearchCopyNext(srchRef
, policy
);
637 /* OS X only: convert a new-world SecPolicyRef to an old-world ItemImpl instance */
639 SecPolicyCreateItemImplInstance(SecPolicyRef policy
)
642 return (SecPolicyRef
)(policy
? CFRetain(policy
) : NULL
);
648 OSStatus status
= SecPolicyGetOID(policy
, &oid
);
652 SecPolicyRef policyRef
= NULL
;
653 CFDictionaryRef properties
= SecPolicyCopyProperties(policy
);
655 SecPointer
<Policy
> policyObj
;
656 PolicyCursor::policy(&oid
, policyObj
);
657 policyRef
= policyObj
->handle();
658 Policy::required(policyRef
)->setProperties(properties
);
664 CFRelease(properties
);
673 SecPolicyCreateBasicX509(void)
675 // return a SecPolicyRef object for the X.509 Basic policy
676 SecPolicyRef policy
= nil
;
677 SecPolicySearchRef policySearch
= nil
;
678 OSStatus status
= SecPolicySearchCreate(CSSM_CERT_X_509v3
, &CSSMOID_APPLE_X509_BASIC
, NULL
, &policySearch
);
680 status
= SecPolicySearchCopyNext(policySearch
, &policy
);
683 CFRelease(policySearch
);
692 SecPolicyCreateSSL(Boolean server
, CFStringRef hostname
)
694 // return a SecPolicyRef object for the SSL policy, given hostname and client options
695 SecPolicyRef policy
= nil
;
696 SecPolicySearchRef policySearch
= nil
;
697 OSStatus status
= SecPolicySearchCreate(CSSM_CERT_X_509v3
, &CSSMOID_APPLE_TP_SSL
, NULL
, &policySearch
);
699 status
= SecPolicySearchCopyNext(policySearch
, &policy
);
701 if (!status
&& policy
) {
702 // set options for client-side or server-side policy evaluation
704 const char *hostnamestr
= NULL
;
706 hostnamestr
= CFStringGetCStringPtr(hostname
, kCFStringEncodingUTF8
);
707 if (hostnamestr
== NULL
) {
708 CFIndex maxLen
= CFStringGetMaximumSizeForEncoding(CFStringGetLength(hostname
), kCFStringEncodingUTF8
) + 1;
709 strbuf
= (char *)malloc(maxLen
);
710 if (CFStringGetCString(hostname
, strbuf
, maxLen
, kCFStringEncodingUTF8
)) {
711 hostnamestr
= strbuf
;
715 uint32 hostnamelen
= (hostnamestr
) ? (uint32
)strlen(hostnamestr
) : 0;
716 uint32 flags
= (!server
) ? CSSM_APPLE_TP_SSL_CLIENT
: 0;
717 CSSM_APPLE_TP_SSL_OPTIONS opts
= {CSSM_APPLE_TP_SSL_OPTS_VERSION
, hostnamelen
, hostnamestr
, flags
};
718 CSSM_DATA data
= {sizeof(opts
), (uint8
*)&opts
};
719 SecPolicySetValue(policy
, &data
);
726 CFRelease(policySearch
);
735 SecPolicyCreateWithSecAsn1Oid(SecAsn1Oid
*oidPtr
)
737 SecPolicyRef policy
= NULL
;
739 SecPointer
<Policy
> policyObj
;
740 PolicyCursor::policy(oidPtr
, policyObj
);
741 policy
= policyObj
->handle();
750 _SecPolicyCreateWithOID(CFTypeRef policyOID
)
752 // for now, we only accept the policy constants that are defined in SecPolicy.h
753 CFStringRef oidStr
= (CFStringRef
)policyOID
;
754 CSSM_OID
*oidPtr
= NULL
;
755 SecPolicyRef policy
= NULL
;
759 unsigned int i
, oidmaplen
= sizeof(oidmap
) / sizeof(oidmap_entry_t
);
760 for (i
=0; i
<oidmaplen
; i
++) {
761 CFStringRef str
= (CFStringRef
) oidmap
[i
].oidstr
;
762 if (CFStringCompare(str
, oidStr
, 0) == kCFCompareEqualTo
) {
763 oidPtr
= (CSSM_OID
*)oidmap
[i
].oidptr
;
767 if (CFEqual(oidStr
, kSecPolicyAppleServerAuthentication
)) {
768 return SecPolicyCreateAppleSSLService(NULL
);
771 SecPolicySearchRef policySearch
= NULL
;
772 OSStatus status
= SecPolicySearchCreate(CSSM_CERT_X_509v3
, oidPtr
, NULL
, &policySearch
);
773 if (!status
&& policySearch
) {
774 status
= SecPolicySearchCopyNext(policySearch
, &policy
);
775 if (status
!= errSecSuccess
) {
778 CFRelease(policySearch
);
780 if (!policy
&& CFEqual(policyOID
, kSecPolicyAppleRevocation
)) {
781 policy
= SecPolicyCreateRevocation(kSecRevocationUseAnyAvailableMethod
);
785 policy
= SecPolicyCreateWithSecAsn1Oid((SecAsn1Oid
*)oidPtr
);
792 /* OS X only: __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_7, __MAC_10_9, __IPHONE_NA, __IPHONE_NA) */
794 SecPolicyCreateWithOID(CFTypeRef policyOID
)
796 SecPolicyRef policy
= _SecPolicyCreateWithOID(policyOID
);
798 syslog(LOG_ERR
, "WARNING: SecPolicyCreateWithOID was unable to return the requested policy. This function was deprecated in 10.9. Please use supported SecPolicy creation functions instead.");
806 SecPolicyCreateWithProperties(CFTypeRef policyIdentifier
, CFDictionaryRef properties
)
808 SecPolicyRef policy
= _SecPolicyCreateWithOID(policyIdentifier
);
809 SecPolicySetProperties(policy
, properties
);
818 SecPolicyCreateRevocation(CFOptionFlags revocationFlags
)
820 // return a SecPolicyRef object for the unified revocation policy
821 SecAsn1Oid
*oidPtr
= (SecAsn1Oid
*)&CSSMOID_APPLE_TP_REVOCATION
;
822 SecPolicyRef policy
= SecPolicyCreateWithSecAsn1Oid(oidPtr
);
824 CSSM_DATA policyData
= { (CSSM_SIZE
)sizeof(CFOptionFlags
), (uint8
*)&revocationFlags
};
825 SecPolicySetValue(policy
, &policyData
);
832 SecPolicyRef
SecPolicyCreateAppleIDSService(CFStringRef hostname
)
834 return SecPolicyCreateSSL(true, hostname
);
839 SecPolicyRef
SecPolicyCreateAppleIDSServiceContext(CFStringRef hostname
, CFDictionaryRef __unused context
)
841 return SecPolicyCreateSSL(true, hostname
);
846 SecPolicyRef
SecPolicyCreateApplePushService(CFStringRef hostname
, CFDictionaryRef __unused context
)
848 return SecPolicyCreateSSL(true, hostname
);
853 SecPolicyRef
SecPolicyCreateApplePushServiceLegacy(CFStringRef hostname
)
855 return SecPolicyCreateSSL(true, hostname
);
860 SecPolicyRef
SecPolicyCreateAppleMMCSService(CFStringRef hostname
, CFDictionaryRef __unused context
)
862 return SecPolicyCreateSSL(true, hostname
);
867 SecPolicyRef
SecPolicyCreateAppleGSService(CFStringRef hostname
, CFDictionaryRef __unused context
)
869 return SecPolicyCreateSSL(true, hostname
);
874 SecPolicyRef
SecPolicyCreateApplePPQService(CFStringRef hostname
, CFDictionaryRef __unused context
)
876 return SecPolicyCreateSSL(true, hostname
);
882 SecPolicyRef
SecPolicyCreateAppleAST2Service(CFStringRef hostname
, CFDictionaryRef __unused context
)
884 return SecPolicyCreateSSL(true, hostname
);
890 SecPolicyRef
SecPolicyCreateAppleEscrowProxyService(CFStringRef hostname
, CFDictionaryRef __unused context
)
892 return SecPolicyCreateSSL(true, hostname
);
898 SecPolicyRef
SecPolicyCreateAppleFMiPService(CFStringRef hostname
, CFDictionaryRef __unused context
)
900 return SecPolicyCreateSSL(true, hostname
);
906 SecPolicyRef
SecPolicyCreateAppleHomeKitServerAuth(CFStringRef hostname
)
908 return SecPolicyCreateSSL(true, hostname
);
914 SecPolicyRef
SecPolicyCreateApplePayIssuerEncryption(void)
916 return _SecPolicyCreateWithOID(kSecPolicyAppleX509Basic
);
922 SecPolicyRef
SecPolicyCreateOSXProvisioningProfileSigning(void)
924 return _SecPolicyCreateWithOID(kSecPolicyAppleOSXProvisioningProfileSigning
);
931 SecPolicyRef
SecPolicyCreateAppleATVVPNProfileSigning(void)
933 return _SecPolicyCreateWithOID(kSecPolicyAppleX509Basic
);
938 SecPolicyRef
SecPolicyCreateAppleSSLService(CFStringRef hostname
)
940 // SSL server, pinned to an Apple intermediate
941 SecPolicyRef policy
= SecPolicyCreateSSL(true, hostname
);
943 // change options for policy evaluation
945 const char *hostnamestr
= NULL
;
947 hostnamestr
= CFStringGetCStringPtr(hostname
, kCFStringEncodingUTF8
);
948 if (hostnamestr
== NULL
) {
949 CFIndex maxLen
= CFStringGetMaximumSizeForEncoding(CFStringGetLength(hostname
), kCFStringEncodingUTF8
) + 1;
950 strbuf
= (char *)malloc(maxLen
);
951 if (CFStringGetCString(hostname
, strbuf
, maxLen
, kCFStringEncodingUTF8
)) {
952 hostnamestr
= strbuf
;
956 uint32 hostnamelen
= (hostnamestr
) ? (uint32
)strlen(hostnamestr
) : 0;
957 uint32 flags
= 0x00000002; // 2nd-lowest bit set to require Apple intermediate pin
958 CSSM_APPLE_TP_SSL_OPTIONS opts
= {CSSM_APPLE_TP_SSL_OPTS_VERSION
, hostnamelen
, hostnamestr
, flags
};
959 CSSM_DATA data
= {sizeof(opts
), (uint8
*)&opts
};
960 SecPolicySetValue(policy
, &data
);
967 #include <security_utilities/cfutilities.h>
969 // Takes the "context" policies to extract the revocation and apply it to timeStamp.
971 SecPolicyCreateAppleTimeStampingAndRevocationPolicies(CFTypeRef policyOrArray
)
974 /* can't use SECAPI macros, since this function does not return OSStatus */
975 CFArrayRef resultPolicyArray
=NULL
;
977 // Set default policy
978 CFRef
<CFArrayRef
> policyArray
= cfArrayize(policyOrArray
);
979 CFRef
<SecPolicyRef
> defaultPolicy
= _SecPolicyCreateWithOID(kSecPolicyAppleTimeStamping
);
980 CFRef
<CFMutableArrayRef
> appleTimeStampingPolicies
= makeCFMutableArray(1,defaultPolicy
.get());
982 // Parse the policy and add revocation related ones
983 CFIndex numPolicies
= CFArrayGetCount(policyArray
);
984 for(CFIndex dex
=0; dex
<numPolicies
; dex
++) {
985 SecPolicyRef secPol
= (SecPolicyRef
)CFArrayGetValueAtIndex(policyArray
, dex
);
986 SecPointer
<Policy
> pol
= Policy::required(SecPolicyRef(secPol
));
987 const CssmOid
&oid
= pol
->oid();
988 if ((oid
== CssmOid::overlay(CSSMOID_APPLE_TP_REVOCATION
))
989 || (oid
== CssmOid::overlay(CSSMOID_APPLE_TP_REVOCATION_CRL
))
990 || (oid
== CssmOid::overlay(CSSMOID_APPLE_TP_REVOCATION_OCSP
)))
992 CFArrayAppendValue(appleTimeStampingPolicies
, secPol
);
995 // Transfer of ownership
996 resultPolicyArray
=appleTimeStampingPolicies
.yield();
999 CFReleaseNull(resultPolicyArray
);
1002 /* implement with unified SecPolicyRef instances */
1003 SecPolicyRef policy
= NULL
;
1004 CFMutableArrayRef resultPolicyArray
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
1005 if (!resultPolicyArray
) {
1008 policy
= SecPolicyCreateWithProperties(kSecPolicyAppleTimeStamping
, NULL
);
1010 CFArrayAppendValue(resultPolicyArray
, policy
);
1011 CFReleaseNull(policy
);
1013 policy
= SecPolicyCreateWithProperties(kSecPolicyAppleRevocation
, NULL
);
1015 CFArrayAppendValue(resultPolicyArray
, policy
);
1016 CFReleaseNull(policy
);
1019 return resultPolicyArray
;