2 * Copyright (c) 2002-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@
24 #include <CoreFoundation/CFString.h>
25 #include <CoreFoundation/CFNumber.h>
26 #include <CoreFoundation/CFArray.h>
27 #include <Security/SecItem.h>
28 #include <Security/SecPolicy.h>
29 #include <Security/SecPolicyPriv.h>
30 #include <Security/SecCertificate.h>
31 #include <Security/SecCertificatePriv.h>
32 #include <security_keychain/Policies.h>
33 #include <security_keychain/PolicyCursor.h>
34 #include "SecBridge.h"
35 #include "utilities/SecCFRelease.h"
39 // String constant declarations
41 #define SEC_CONST_DECL(k,v) const CFStringRef k = CFSTR(v);
43 SEC_CONST_DECL (kSecPolicyAppleX509Basic
, "1.2.840.113635.100.1.2");
44 SEC_CONST_DECL (kSecPolicyAppleSSL
, "1.2.840.113635.100.1.3");
45 SEC_CONST_DECL (kSecPolicyAppleSMIME
, "1.2.840.113635.100.1.8");
46 SEC_CONST_DECL (kSecPolicyAppleEAP
, "1.2.840.113635.100.1.9");
47 SEC_CONST_DECL (kSecPolicyAppleSWUpdateSigning
, "1.2.840.113635.100.1.10");
48 SEC_CONST_DECL (kSecPolicyAppleIPsec
, "1.2.840.113635.100.1.11");
49 SEC_CONST_DECL (kSecPolicyAppleiChat
, "1.2.840.113635.100.1.12");
50 SEC_CONST_DECL (kSecPolicyApplePKINITClient
, "1.2.840.113635.100.1.14");
51 SEC_CONST_DECL (kSecPolicyApplePKINITServer
, "1.2.840.113635.100.1.15");
52 SEC_CONST_DECL (kSecPolicyAppleCodeSigning
, "1.2.840.113635.100.1.16");
53 SEC_CONST_DECL (kSecPolicyApplePackageSigning
, "1.2.840.113635.100.1.17");
54 SEC_CONST_DECL (kSecPolicyAppleIDValidation
, "1.2.840.113635.100.1.18");
55 SEC_CONST_DECL (kSecPolicyMacAppStoreReceipt
, "1.2.840.113635.100.1.19");
56 SEC_CONST_DECL (kSecPolicyAppleTimeStamping
, "1.2.840.113635.100.1.20");
57 SEC_CONST_DECL (kSecPolicyAppleRevocation
, "1.2.840.113635.100.1.21");
58 SEC_CONST_DECL (kSecPolicyApplePassbookSigning
, "1.2.840.113635.100.1.22");
59 SEC_CONST_DECL (kSecPolicyAppleMobileStore
, "1.2.840.113635.100.1.23");
60 SEC_CONST_DECL (kSecPolicyAppleEscrowService
, "1.2.840.113635.100.1.24");
61 SEC_CONST_DECL (kSecPolicyAppleProfileSigner
, "1.2.840.113635.100.1.25");
62 SEC_CONST_DECL (kSecPolicyAppleQAProfileSigner
, "1.2.840.113635.100.1.26");
63 SEC_CONST_DECL (kSecPolicyAppleTestMobileStore
, "1.2.840.113635.100.1.27");
65 SEC_CONST_DECL (kSecPolicyAppleOTAPKISigner
, "1.2.840.113635.100.1.28");
66 SEC_CONST_DECL (kSecPolicyAppleTestOTAPKISigner
, "1.2.840.113635.100.1.29");
67 /* FIXME: this policy name should be deprecated and replaced with "kSecPolicyAppleIDValidationRecordSigning" */
68 SEC_CONST_DECL (kSecPolicyAppleIDValidationRecordSigningPolicy
, "1.2.840.113625.100.1.30");
69 SEC_CONST_DECL (kSecPolicyAppleSMPEncryption
, "1.2.840.113625.100.1.31");
70 SEC_CONST_DECL (kSecPolicyAppleTestSMPEncryption
, "1.2.840.113625.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.113625.100.1.35");
75 SEC_CONST_DECL (kSecPolicyAppleTestPPQSigning
, "1.2.840.113625.100.1.36");
76 SEC_CONST_DECL (kSecPolicyAppleATVAppSigning
, "1.2.840.113625.100.1.37");
77 SEC_CONST_DECL (kSecPolicyAppleTestATVAppSigning
, "1.2.840.113625.100.1.38");
78 SEC_CONST_DECL (kSecPolicyApplePayIssuerEncryption
, "1.2.840.113625.100.1.39");
79 SEC_CONST_DECL (kSecPolicyAppleOSXProvisioningProfileSigning
, "1.2.840.113625.100.1.40");
81 SEC_CONST_DECL (kSecPolicyOid
, "SecPolicyOid");
82 SEC_CONST_DECL (kSecPolicyName
, "SecPolicyName");
83 SEC_CONST_DECL (kSecPolicyClient
, "SecPolicyClient");
84 SEC_CONST_DECL (kSecPolicyRevocationFlags
, "SecPolicyRevocationFlags");
85 SEC_CONST_DECL (kSecPolicyTeamIdentifier
, "SecPolicyTeamIdentifier");
87 SEC_CONST_DECL (kSecPolicyKU_DigitalSignature
, "CE_KU_DigitalSignature");
88 SEC_CONST_DECL (kSecPolicyKU_NonRepudiation
, "CE_KU_NonRepudiation");
89 SEC_CONST_DECL (kSecPolicyKU_KeyEncipherment
, "CE_KU_KeyEncipherment");
90 SEC_CONST_DECL (kSecPolicyKU_DataEncipherment
, "CE_KU_DataEncipherment");
91 SEC_CONST_DECL (kSecPolicyKU_KeyAgreement
, "CE_KU_KeyAgreement");
92 SEC_CONST_DECL (kSecPolicyKU_KeyCertSign
, "CE_KU_KeyCertSign");
93 SEC_CONST_DECL (kSecPolicyKU_CRLSign
, "CE_KU_CRLSign");
94 SEC_CONST_DECL (kSecPolicyKU_EncipherOnly
, "CE_KU_EncipherOnly");
95 SEC_CONST_DECL (kSecPolicyKU_DecipherOnly
, "CE_KU_DecipherOnly");
100 CFArrayRef
SecPolicyCopyEscrowRootCertificates(void);
102 CFStringRef
SecPolicyGetOidString(SecPolicyRef policy
);
103 CFDictionaryRef
SecPolicyGetOptions(SecPolicyRef policy
);
104 void SecPolicySetOptionsValue(SecPolicyRef policy
, CFStringRef key
, CFTypeRef value
);
108 // String to CSSM_OID mapping
110 struct oidmap_entry_s
{
111 const CFTypeRef oidstr
;
112 const SecAsn1Oid
*oidptr
;
114 typedef struct oidmap_entry_s oidmap_entry_t
;
116 // policies enumerated by SecPolicySearch (PolicyCursor.cpp)
118 static_cast<const CssmOid *>(&CSSMOID_APPLE_ISIGN), // no longer supported
119 static_cast<const CssmOid *>(&CSSMOID_APPLE_X509_BASIC),
120 static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_SSL),
121 static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_SMIME),
122 static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_EAP),
123 static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_SW_UPDATE_SIGNING),
124 static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_IP_SEC),
125 static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_ICHAT), // no longer supported
126 static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_RESOURCE_SIGN),
127 static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_PKINIT_CLIENT),
128 static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_PKINIT_SERVER),
129 static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_CODE_SIGNING),
130 static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_PACKAGE_SIGNING),
131 static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_REVOCATION_CRL),
132 static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_REVOCATION_OCSP),
133 static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_MACAPPSTORE_RECEIPT),
134 static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_APPLEID_SHARING),
135 static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_TIMESTAMPING),
137 const oidmap_entry_t oidmap
[] = {
138 { kSecPolicyAppleX509Basic
, &CSSMOID_APPLE_X509_BASIC
},
139 { kSecPolicyAppleSSL
, &CSSMOID_APPLE_TP_SSL
},
140 { kSecPolicyAppleSMIME
, &CSSMOID_APPLE_TP_SMIME
},
141 { kSecPolicyAppleEAP
, &CSSMOID_APPLE_TP_EAP
},
142 { kSecPolicyAppleSWUpdateSigning
, &CSSMOID_APPLE_TP_SW_UPDATE_SIGNING
},
143 { kSecPolicyAppleIPsec
, &CSSMOID_APPLE_TP_IP_SEC
},
144 { kSecPolicyAppleiChat
, &CSSMOID_APPLE_TP_ICHAT
},
145 { kSecPolicyApplePKINITClient
, &CSSMOID_APPLE_TP_PKINIT_CLIENT
},
146 { kSecPolicyApplePKINITServer
, &CSSMOID_APPLE_TP_PKINIT_SERVER
},
147 { kSecPolicyAppleCodeSigning
, &CSSMOID_APPLE_TP_CODE_SIGNING
},
148 { kSecPolicyApplePackageSigning
, &CSSMOID_APPLE_TP_PACKAGE_SIGNING
},
149 { kSecPolicyAppleIDValidation
, &CSSMOID_APPLE_TP_APPLEID_SHARING
},
150 { kSecPolicyMacAppStoreReceipt
, &CSSMOID_APPLE_TP_MACAPPSTORE_RECEIPT
},
151 { kSecPolicyAppleTimeStamping
, &CSSMOID_APPLE_TP_TIMESTAMPING
},
152 { kSecPolicyAppleRevocation
, &CSSMOID_APPLE_TP_REVOCATION
},
153 { kSecPolicyAppleRevocation
, &CSSMOID_APPLE_TP_REVOCATION_OCSP
},
154 { kSecPolicyAppleRevocation
, &CSSMOID_APPLE_TP_REVOCATION_CRL
},
155 { kSecPolicyApplePassbookSigning
, &CSSMOID_APPLE_TP_PASSBOOK_SIGNING
},
156 { kSecPolicyAppleMobileStore
, &CSSMOID_APPLE_TP_MOBILE_STORE
},
157 { kSecPolicyAppleEscrowService
, &CSSMOID_APPLE_TP_ESCROW_SERVICE
},
158 { kSecPolicyAppleProfileSigner
, &CSSMOID_APPLE_TP_PROFILE_SIGNING
},
159 { kSecPolicyAppleQAProfileSigner
, &CSSMOID_APPLE_TP_QA_PROFILE_SIGNING
},
160 { kSecPolicyAppleTestMobileStore
, &CSSMOID_APPLE_TP_TEST_MOBILE_STORE
},
161 { kSecPolicyApplePCSEscrowService
, &CSSMOID_APPLE_TP_PCS_ESCROW_SERVICE
},
162 { kSecPolicyAppleOSXProvisioningProfileSigning
, &CSSMOID_APPLE_TP_PROVISIONING_PROFILE_SIGNING
},
165 // TBD: have only one set of policy identifiers in SecPolicy.c so we can get rid of this
166 const oidmap_entry_t oidmap_priv
[] = {
167 { CFSTR("basicX509"), &CSSMOID_APPLE_X509_BASIC
},
168 { CFSTR("sslServer"), &CSSMOID_APPLE_TP_SSL
},
169 { CFSTR("sslClient"), &CSSMOID_APPLE_TP_SSL
},
170 { CFSTR("SMIME"), &CSSMOID_APPLE_TP_SMIME
},
171 { CFSTR("eapServer"), &CSSMOID_APPLE_TP_EAP
},
172 { CFSTR("eapClient"), &CSSMOID_APPLE_TP_EAP
},
173 { CFSTR("AppleSWUpdateSigning"), &CSSMOID_APPLE_TP_SW_UPDATE_SIGNING
},
174 { CFSTR("ipsecServer"), &CSSMOID_APPLE_TP_IP_SEC
},
175 { CFSTR("ipsecClient"), &CSSMOID_APPLE_TP_IP_SEC
},
176 { CFSTR("CodeSigning"), &CSSMOID_APPLE_TP_CODE_SIGNING
},
177 { CFSTR("PackageSigning"), &CSSMOID_APPLE_TP_PACKAGE_SIGNING
},
178 { CFSTR("AppleIDAuthority"), &CSSMOID_APPLE_TP_APPLEID_SHARING
},
179 { CFSTR("MacAppStoreReceipt"), &CSSMOID_APPLE_TP_MACAPPSTORE_RECEIPT
},
180 { CFSTR("AppleTimeStamping"), &CSSMOID_APPLE_TP_TIMESTAMPING
},
181 { CFSTR("revocation"), &CSSMOID_APPLE_TP_REVOCATION
},
182 { CFSTR("ApplePassbook"), &CSSMOID_APPLE_TP_PASSBOOK_SIGNING
},
183 { CFSTR("AppleMobileStore"), &CSSMOID_APPLE_TP_MOBILE_STORE
},
184 { CFSTR("AppleEscrowService"), &CSSMOID_APPLE_TP_ESCROW_SERVICE
},
185 { CFSTR("AppleProfileSigner"), &CSSMOID_APPLE_TP_PROFILE_SIGNING
},
186 { CFSTR("AppleQAProfileSigner"), &CSSMOID_APPLE_TP_QA_PROFILE_SIGNING
},
187 { CFSTR("AppleTestMobileStore"), &CSSMOID_APPLE_TP_TEST_MOBILE_STORE
},
188 { CFSTR("ApplePCSEscrowService"), &CSSMOID_APPLE_TP_PCS_ESCROW_SERVICE
},
189 { CFSTR("AppleOSXProvisioningProfileSigning"), &CSSMOID_APPLE_TP_PROVISIONING_PROFILE_SIGNING
},
197 SecPolicyGetTypeID(void)
200 return gTypes().Policy
.typeID
;
201 END_SECAPI1(_kCFRuntimeNotATypeID
)
206 // Sec API bridge functions
208 /* OS X only: __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2, __MAC_10_7, __IPHONE_NA, __IPHONE_NA) */
210 SecPolicyGetOID(SecPolicyRef policyRef
, CSSM_OID
* oid
)
214 Required(oid
) = Policy::required(policyRef
)->oid();
217 /* bridge to support old functionality */
221 CFStringRef oidStr
= (CFStringRef
) SecPolicyGetOidString(policyRef
);
222 if (!oidStr
|| !oid
) {
223 return errSecParam
; // bad policy ref?
225 CSSM_OID
*oidptr
= NULL
;
226 unsigned int i
, oidmaplen
= sizeof(oidmap
) / sizeof(oidmap_entry_t
);
227 for (i
=0; i
<oidmaplen
; i
++) {
228 CFStringRef str
= (CFStringRef
) oidmap
[i
].oidstr
;
229 if (CFStringCompare(str
, oidStr
, 0) == kCFCompareEqualTo
) {
230 oidptr
= (CSSM_OID
*)oidmap
[i
].oidptr
;
235 // Check private iOS policy names.
236 oidmaplen
= sizeof(oidmap_priv
) / sizeof(oidmap_entry_t
);
237 for (i
=0; i
<oidmaplen
; i
++) {
238 CFStringRef str
= (CFStringRef
) oidmap_priv
[i
].oidstr
;
239 if (CFStringCompare(str
, oidStr
, 0) == kCFCompareEqualTo
) {
240 oidptr
= (CSSM_OID
*)oidmap_priv
[i
].oidptr
;
246 oid
->Data
= oidptr
->Data
;
247 oid
->Length
= oidptr
->Length
;
248 return errSecSuccess
;
251 syslog(LOG_ERR
, "WARNING: SecPolicyGetOID failed to return an OID. This function was deprecated in 10.7. Please use SecPolicyCopyProperties instead.");
252 return errSecServiceNotAvailable
;
256 // TODO: use a version of this function from a utility library
257 static CSSM_BOOL
compareOids(
258 const CSSM_OID
*oid1
,
259 const CSSM_OID
*oid2
)
261 if((oid1
== NULL
) || (oid2
== NULL
)) {
264 if(oid1
->Length
!= oid2
->Length
) {
267 if(memcmp(oid1
->Data
, oid2
->Data
, oid1
->Length
)) {
276 CFStringRef
SecPolicyGetStringForOID(CSSM_OID
* oid
)
281 // given a CSSM_OID pointer, return corresponding string in oidmap
282 unsigned int i
, oidmaplen
= sizeof(oidmap
) / sizeof(oidmap_entry_t
);
283 for (i
=0; i
<oidmaplen
; i
++) {
284 CSSM_OID
* oidptr
= (CSSM_OID
*)oidmap
[i
].oidptr
;
285 if (compareOids(oid
, oidptr
)) {
286 return (CFStringRef
) oidmap
[i
].oidstr
;
293 static bool SecPolicyGetCSSMDataValueForString(SecPolicyRef policyRef
, CFStringRef stringRef
, CSSM_DATA
* value
)
295 // Old API expects to vend a pointer and length for a policy value.
296 // The API contract says this pointer is good for the life of the policy.
297 // However, the new policy values are CF objects, and we need a separate
298 // buffer to get their UTF8 bytes. This buffer needs to be released when
299 // the policy object is released.
301 CFDataRef data
= NULL
;
302 CFIndex maxLength
= CFStringGetMaximumSizeForEncoding(CFStringGetLength(stringRef
), kCFStringEncodingUTF8
) + 1;
303 char* buf
= (char*) malloc(maxLength
);
307 if (CFStringGetCString(stringRef
, buf
, (CFIndex
)maxLength
, kCFStringEncodingUTF8
)) {
308 CFIndex length
= strlen(buf
);
309 data
= CFDataCreate(NULL
, (const UInt8
*)buf
, length
);
313 value
->Data
= (uint8
*)((data
) ? CFDataGetBytePtr(data
) : NULL
);
314 value
->Length
= (CSSM_SIZE
)((data
) ? CFDataGetLength(data
) : 0);
317 // stash this in a place where it will be released when the policy is destroyed
319 SecPolicySetOptionsValue(policyRef
, CFSTR("policy_data"), data
);
323 syslog(LOG_ERR
, "WARNING: policy dictionary not found to store returned data; will leak!");
330 /* OS X only: __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2, __MAC_10_7, __IPHONE_NA, __IPHONE_NA) */
332 SecPolicyGetValue(SecPolicyRef policyRef
, CSSM_DATA
* value
)
336 Required(value
) = Policy::required(policyRef
)->value();
339 /* bridge to support old functionality */
340 #if SECTRUST_DEPRECATION_WARNINGS
341 syslog(LOG_ERR
, "WARNING: SecPolicyGetValue was deprecated in 10.7. Please use SecPolicyCopyProperties instead.");
343 if (!(policyRef
&& value
)) {
346 CFDictionaryRef options
= SecPolicyGetOptions(policyRef
);
347 if (!(options
&& (CFDictionaryGetTypeID() == CFGetTypeID(options
)))) {
350 CFTypeRef name
= NULL
;
352 if (CFDictionaryGetValueIfPresent(options
, CFSTR("SSLHostname") /*kSecPolicyCheckSSLHostname*/,
353 (const void **)&name
) && name
) {
356 if (CFDictionaryGetValueIfPresent(options
, CFSTR("EAPTrustedServerNames") /*kSecPolicyCheckEAPTrustedServerNames*/,
357 (const void **)&name
) && name
) {
360 if (CFDictionaryGetValueIfPresent(options
, CFSTR("email") /*kSecPolicyCheckEmail*/,
361 (const void **)&name
) && name
) {
366 CFTypeID typeID
= CFGetTypeID(name
);
367 if (CFArrayGetTypeID() == typeID
) {
368 name
= (CFStringRef
) CFArrayGetValueAtIndex((CFArrayRef
)name
, 0);
370 SecPolicyGetCSSMDataValueForString(policyRef
, (CFStringRef
)name
, value
);
376 return errSecSuccess
;
382 SecPolicyCopyProperties(SecPolicyRef policyRef
)
384 /* can't use SECAPI macros, since this function does not return OSStatus */
385 CFDictionaryRef result
= NULL
;
387 result
= Policy::required(policyRef
)->properties();
399 /* OS X only: __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2, __MAC_10_7, __IPHONE_NA, __IPHONE_NA) */
401 SecPolicySetValue(SecPolicyRef policyRef
, const CSSM_DATA
*value
)
406 const CssmData
newValue(value
->Data
, value
->Length
);
407 Policy::required(policyRef
)->setValue(newValue
);
410 /* bridge to support old functionality */
411 #if SECTRUST_DEPRECATION_WARNINGS
412 syslog(LOG_ERR
, "WARNING: SecPolicySetValue was deprecated in 10.7. Please use SecPolicySetProperties instead.");
414 if (!(policyRef
&& value
)) {
417 OSStatus status
= errSecSuccess
;
418 CFDataRef data
= NULL
;
419 CFStringRef name
= NULL
;
420 CFNumberRef cnum
= NULL
;
421 CFStringRef oid
= (CFStringRef
) SecPolicyGetOidString(policyRef
);
423 syslog(LOG_ERR
, "SecPolicySetValue: unknown policy OID");
424 return errSecParam
; // bad policy ref?
426 if (CFEqual(oid
, CFSTR("sslServer") /*kSecPolicyOIDSSLServer*/) ||
427 CFEqual(oid
, CFSTR("sslClient") /*kSecPolicyOIDSSLClient*/) ||
428 CFEqual(oid
, CFSTR("ipsecServer") /*kSecPolicyOIDIPSecServer*/) ||
429 CFEqual(oid
, CFSTR("ipsecClient") /*kSecPolicyOIDIPSecClient*/) ||
430 CFEqual(oid
, kSecPolicyAppleSSL
) ||
431 CFEqual(oid
, kSecPolicyAppleIPsec
) ||
432 CFEqual(oid
, kSecPolicyAppleIDValidation
)
434 CSSM_APPLE_TP_SSL_OPTIONS
*opts
= (CSSM_APPLE_TP_SSL_OPTIONS
*)value
->Data
;
435 if (opts
->Version
== CSSM_APPLE_TP_SSL_OPTS_VERSION
) {
436 if (opts
->ServerNameLen
> 0) {
437 data
= CFDataCreate(NULL
, (const UInt8
*)opts
->ServerName
, opts
->ServerNameLen
);
438 name
= (data
) ? CFStringCreateFromExternalRepresentation(NULL
, data
, kCFStringEncodingUTF8
) : NULL
;
442 SecPolicySetOptionsValue(policyRef
, CFSTR("SSLHostname") /*kSecPolicyCheckSSLHostname*/, name
);
445 status
= errSecParam
;
448 else if (CFEqual(oid
, CFSTR("eapServer") /*kSecPolicyOIDEAPServer*/) ||
449 CFEqual(oid
, CFSTR("eapClient") /*kSecPolicyOIDEAPClient*/) ||
450 CFEqual(oid
, kSecPolicyAppleEAP
)
452 CSSM_APPLE_TP_SSL_OPTIONS
*opts
= (CSSM_APPLE_TP_SSL_OPTIONS
*)value
->Data
;
453 if (opts
->Version
== CSSM_APPLE_TP_SSL_OPTS_VERSION
) {
454 if (opts
->ServerNameLen
> 0) {
455 data
= CFDataCreate(NULL
, (const UInt8
*)opts
->ServerName
, opts
->ServerNameLen
);
456 name
= (data
) ? CFStringCreateFromExternalRepresentation(NULL
, data
, kCFStringEncodingUTF8
) : NULL
;
460 SecPolicySetOptionsValue(policyRef
, CFSTR("EAPTrustedServerNames") /*kSecPolicyCheckEAPTrustedServerNames*/, name
);
463 status
= errSecParam
;
466 else if (CFEqual(oid
, CFSTR("SMIME") /*kSecPolicyOIDSMIME*/) ||
467 CFEqual(oid
, CFSTR("AppleShoebox") /*kSecPolicyOIDAppleShoebox*/) ||
468 CFEqual(oid
, CFSTR("ApplePassbook") /*kSecPolicyOIDApplePassbook*/) ||
469 CFEqual(oid
, kSecPolicyAppleSMIME
) ||
470 CFEqual(oid
, kSecPolicyApplePassbookSigning
)
472 CSSM_APPLE_TP_SMIME_OPTIONS
*opts
= (CSSM_APPLE_TP_SMIME_OPTIONS
*)value
->Data
;
473 if (opts
->Version
== CSSM_APPLE_TP_SMIME_OPTS_VERSION
) {
474 if (opts
->SenderEmailLen
> 0) {
475 data
= CFDataCreate(NULL
, (const UInt8
*)opts
->SenderEmail
, opts
->SenderEmailLen
);
476 name
= (data
) ? CFStringCreateFromExternalRepresentation(NULL
, data
, kCFStringEncodingUTF8
) : NULL
;
480 SecPolicySetOptionsValue(policyRef
, CFSTR("email") /*kSecPolicyCheckEmail*/, name
);
483 status
= errSecParam
;
486 else if (CFEqual(oid
, CFSTR("revocation") /* kSecPolicyOIDRevocation */) ||
487 CFEqual(oid
, kSecPolicyAppleRevocation
)
489 CSSM_APPLE_TP_CRL_OPTIONS
*opts
= (CSSM_APPLE_TP_CRL_OPTIONS
*)value
->Data
;
490 if (opts
->Version
== CSSM_APPLE_TP_CRL_OPTS_VERSION
) {
491 CSSM_APPLE_TP_CRL_OPT_FLAGS crlFlags
= opts
->CrlFlags
;
492 CFOptionFlags revocationFlags
= 0;
493 if ((crlFlags
& CSSM_TP_ACTION_FETCH_CRL_FROM_NET
) == 0) {
494 /* disable network access */
495 revocationFlags
|= kSecRevocationNetworkAccessDisabled
;
497 if ((crlFlags
& CSSM_TP_ACTION_CRL_SUFFICIENT
) == 0) {
498 /* if OCSP method is not sufficient, must use CRL */
499 revocationFlags
|= (kSecRevocationCRLMethod
| kSecRevocationPreferCRL
);
501 /* either method is sufficient */
502 revocationFlags
|= kSecRevocationUseAnyAvailableMethod
;
504 if ((crlFlags
& CSSM_TP_ACTION_REQUIRE_CRL_PER_CERT
) != 0) {
505 /* require a response */
506 revocationFlags
|= kSecRevocationRequirePositiveResponse
;
508 cnum
= CFNumberCreate(kCFAllocatorDefault
, kCFNumberCFIndexType
, &revocationFlags
);
510 SecPolicySetOptionsValue(policyRef
, kSecPolicyRevocationFlags
, cnum
);
515 syslog(LOG_ERR
, "SecPolicySetValue: unrecognized policy OID");
516 status
= errSecParam
;
518 if (data
) { CFRelease(data
); }
519 if (name
) { CFRelease(name
); }
520 if (cnum
) { CFRelease(cnum
); }
527 SecPolicySetProperties(SecPolicyRef policyRef
, CFDictionaryRef properties
)
530 Policy::required(policyRef
)->setProperties(properties
);
535 /* OS X only: __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2, __MAC_10_7, __IPHONE_NA, __IPHONE_NA) */
537 SecPolicyGetTPHandle(SecPolicyRef policyRef
, CSSM_TP_HANDLE
* tpHandle
)
541 Required(tpHandle
) = Policy::required(policyRef
)->tp()->handle();
544 /* this function is unsupported in unified SecTrust */
545 #if SECTRUST_DEPRECATION_WARNINGS
546 syslog(LOG_ERR
, "WARNING: SecPolicyGetTPHandle was deprecated in 10.7, and does nothing in 10.11. Please stop using it.");
548 return errSecServiceNotAvailable
;
552 /* OS X only: __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_3, __MAC_10_7, __IPHONE_NA, __IPHONE_NA) */
554 SecPolicyCopyAll(CSSM_CERT_TYPE certificateType
, CFArrayRef
* policies
)
559 CFMutableArrayRef currPolicies
= NULL
;
560 currPolicies
= CFArrayCreateMutable(NULL
, 0, NULL
);
563 SecPointer
<PolicyCursor
> cursor(new PolicyCursor(NULL
, NULL
));
564 SecPointer
<Policy
> policy
;
565 while ( cursor
->next(policy
) ) /* copies the next policy */
567 CFArrayAppendValue(currPolicies
, policy
->handle()); /* 'SecPolicyRef' appended */
568 CFRelease(policy
->handle()); /* refcount bumped up when appended to array */
570 *policies
= CFArrayCreateCopy(NULL
, currPolicies
);
571 CFRelease(currPolicies
);
572 CFRelease(cursor
->handle());
576 /* bridge to support old functionality */
577 #if SECTRUST_DEPRECATION_WARNINGS
578 syslog(LOG_ERR
, "WARNING: SecPolicyCopyAll was deprecated in 10.7. Please use SecPolicy creation functions instead.");
583 CFMutableArrayRef curPolicies
= CFArrayCreateMutable(NULL
, 0, NULL
);
585 return errSecAllocate
;
587 /* build the subset of policies which were supported on OS X,
588 and which are also implemented on iOS */
589 CFStringRef supportedPolicies
[] = {
590 kSecPolicyAppleX509Basic
, /* CSSMOID_APPLE_X509_BASIC */
591 kSecPolicyAppleSSL
, /* CSSMOID_APPLE_TP_SSL */
592 kSecPolicyAppleSMIME
, /* CSSMOID_APPLE_TP_SMIME */
593 kSecPolicyAppleEAP
, /*CSSMOID_APPLE_TP_EAP */
594 kSecPolicyAppleSWUpdateSigning
, /* CSSMOID_APPLE_TP_SW_UPDATE_SIGNING */
595 kSecPolicyAppleIPsec
, /* CSSMOID_APPLE_TP_IP_SEC */
596 kSecPolicyAppleCodeSigning
, /* CSSMOID_APPLE_TP_CODE_SIGNING */
597 kSecPolicyMacAppStoreReceipt
, /* CSSMOID_APPLE_TP_MACAPPSTORE_RECEIPT */
598 kSecPolicyAppleIDValidation
, /* CSSMOID_APPLE_TP_APPLEID_SHARING */
599 kSecPolicyAppleTimeStamping
, /* CSSMOID_APPLE_TP_TIMESTAMPING */
600 kSecPolicyAppleRevocation
, /* CSSMOID_APPLE_TP_REVOCATION_{CRL,OCSP} */
605 CFStringRef policyID
= supportedPolicies
[ix
++];
609 SecPolicyRef curPolicy
= SecPolicyCreateWithProperties(policyID
, NULL
);
611 CFArrayAppendValue(curPolicies
, curPolicy
);
612 CFRelease(curPolicy
);
615 *policies
= CFArrayCreateCopy(NULL
, curPolicies
);
616 CFRelease(curPolicies
);
617 return errSecSuccess
;
621 /* OS X only: __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_3, __MAC_10_7, __IPHONE_NA, __IPHONE_NA) */
623 SecPolicyCopy(CSSM_CERT_TYPE certificateType
, const CSSM_OID
*policyOID
, SecPolicyRef
* policy
)
629 if (!policyOID
|| !policy
) {
633 SecPolicySearchRef srchRef
= NULL
;
636 ortn
= SecPolicySearchCreate(certificateType
, policyOID
, NULL
, &srchRef
);
640 ortn
= SecPolicySearchCopyNext(srchRef
, policy
);
645 /* OS X only: convert a new-world SecPolicyRef to an old-world ItemImpl instance */
647 SecPolicyCreateItemImplInstance(SecPolicyRef policy
)
650 return (SecPolicyRef
)(policy
? CFRetain(policy
) : NULL
);
656 OSStatus status
= SecPolicyGetOID(policy
, &oid
);
660 SecPolicyRef policyRef
= NULL
;
661 CFDictionaryRef properties
= SecPolicyCopyProperties(policy
);
663 SecPointer
<Policy
> policyObj
;
664 PolicyCursor::policy(&oid
, policyObj
);
665 policyRef
= policyObj
->handle();
666 Policy::required(policyRef
)->setProperties(properties
);
672 CFRelease(properties
);
681 SecPolicyCreateBasicX509(void)
683 // return a SecPolicyRef object for the X.509 Basic policy
684 SecPolicyRef policy
= nil
;
685 SecPolicySearchRef policySearch
= nil
;
686 OSStatus status
= SecPolicySearchCreate(CSSM_CERT_X_509v3
, &CSSMOID_APPLE_X509_BASIC
, NULL
, &policySearch
);
688 status
= SecPolicySearchCopyNext(policySearch
, &policy
);
691 CFRelease(policySearch
);
700 SecPolicyCreateSSL(Boolean server
, CFStringRef hostname
)
702 // return a SecPolicyRef object for the SSL policy, given hostname and client options
703 SecPolicyRef policy
= nil
;
704 SecPolicySearchRef policySearch
= nil
;
705 OSStatus status
= SecPolicySearchCreate(CSSM_CERT_X_509v3
, &CSSMOID_APPLE_TP_SSL
, NULL
, &policySearch
);
707 status
= SecPolicySearchCopyNext(policySearch
, &policy
);
709 if (!status
&& policy
) {
710 // set options for client-side or server-side policy evaluation
712 const char *hostnamestr
= NULL
;
714 hostnamestr
= CFStringGetCStringPtr(hostname
, kCFStringEncodingUTF8
);
715 if (hostnamestr
== NULL
) {
716 CFIndex maxLen
= CFStringGetMaximumSizeForEncoding(CFStringGetLength(hostname
), kCFStringEncodingUTF8
) + 1;
717 strbuf
= (char *)malloc(maxLen
);
718 if (CFStringGetCString(hostname
, strbuf
, maxLen
, kCFStringEncodingUTF8
)) {
719 hostnamestr
= strbuf
;
723 uint32 hostnamelen
= (hostnamestr
) ? (uint32
)strlen(hostnamestr
) : 0;
724 uint32 flags
= (!server
) ? CSSM_APPLE_TP_SSL_CLIENT
: 0;
725 CSSM_APPLE_TP_SSL_OPTIONS opts
= {CSSM_APPLE_TP_SSL_OPTS_VERSION
, hostnamelen
, hostnamestr
, flags
};
726 CSSM_DATA data
= {sizeof(opts
), (uint8
*)&opts
};
727 SecPolicySetValue(policy
, &data
);
734 CFRelease(policySearch
);
743 SecPolicyCreateWithSecAsn1Oid(SecAsn1Oid
*oidPtr
)
745 SecPolicyRef policy
= NULL
;
747 SecPointer
<Policy
> policyObj
;
748 PolicyCursor::policy(oidPtr
, policyObj
);
749 policy
= policyObj
->handle();
758 _SecPolicyCreateWithOID(CFTypeRef policyOID
)
760 // for now, we only accept the policy constants that are defined in SecPolicy.h
761 CFStringRef oidStr
= (CFStringRef
)policyOID
;
762 CSSM_OID
*oidPtr
= NULL
;
763 SecPolicyRef policy
= NULL
;
767 unsigned int i
, oidmaplen
= sizeof(oidmap
) / sizeof(oidmap_entry_t
);
768 for (i
=0; i
<oidmaplen
; i
++) {
769 CFStringRef str
= (CFStringRef
) oidmap
[i
].oidstr
;
770 if (CFStringCompare(str
, oidStr
, 0) == kCFCompareEqualTo
) {
771 oidPtr
= (CSSM_OID
*)oidmap
[i
].oidptr
;
775 if (CFEqual(oidStr
, kSecPolicyAppleServerAuthentication
)) {
776 return SecPolicyCreateAppleSSLService(NULL
);
779 SecPolicySearchRef policySearch
= NULL
;
780 OSStatus status
= SecPolicySearchCreate(CSSM_CERT_X_509v3
, oidPtr
, NULL
, &policySearch
);
781 if (!status
&& policySearch
) {
782 status
= SecPolicySearchCopyNext(policySearch
, &policy
);
783 if (status
!= errSecSuccess
) {
786 CFRelease(policySearch
);
788 if (!policy
&& CFEqual(policyOID
, kSecPolicyAppleRevocation
)) {
789 policy
= SecPolicyCreateRevocation(kSecRevocationUseAnyAvailableMethod
);
793 policy
= SecPolicyCreateWithSecAsn1Oid((SecAsn1Oid
*)oidPtr
);
800 /* OS X only: __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_7, __MAC_10_9, __IPHONE_NA, __IPHONE_NA) */
802 SecPolicyCreateWithOID(CFTypeRef policyOID
)
804 SecPolicyRef policy
= _SecPolicyCreateWithOID(policyOID
);
806 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.");
814 SecPolicyCreateWithProperties(CFTypeRef policyIdentifier
, CFDictionaryRef properties
)
816 SecPolicyRef policy
= _SecPolicyCreateWithOID(policyIdentifier
);
817 SecPolicySetProperties(policy
, properties
);
826 SecPolicyCreateRevocation(CFOptionFlags revocationFlags
)
828 // return a SecPolicyRef object for the unified revocation policy
829 SecAsn1Oid
*oidPtr
= (SecAsn1Oid
*)&CSSMOID_APPLE_TP_REVOCATION
;
830 SecPolicyRef policy
= SecPolicyCreateWithSecAsn1Oid(oidPtr
);
832 CSSM_DATA policyData
= { (CSSM_SIZE
)sizeof(CFOptionFlags
), (uint8
*)&revocationFlags
};
833 SecPolicySetValue(policy
, &policyData
);
839 /* OS X only: deprecated SPI entry point */
840 /* new in 10.9 ***FIXME*** TO BE REMOVED */
841 CFArrayRef
SecPolicyCopyEscrowRootCertificates(void)
843 return SecCertificateCopyEscrowRoots(kSecCertificateProductionEscrowRoot
);
846 SecPolicyRef
SecPolicyCreateAppleIDSService(CFStringRef hostname
)
848 return SecPolicyCreateSSL(true, hostname
);
851 SecPolicyRef
SecPolicyCreateAppleIDSServiceContext(CFStringRef hostname
, CFDictionaryRef __unused context
)
853 return SecPolicyCreateSSL(true, hostname
);
856 SecPolicyRef
SecPolicyCreateApplePushService(CFStringRef hostname
, CFDictionaryRef __unused context
)
858 return SecPolicyCreateSSL(true, hostname
);
861 SecPolicyRef
SecPolicyCreateApplePushServiceLegacy(CFStringRef hostname
)
863 return SecPolicyCreateSSL(true, hostname
);
866 SecPolicyRef
SecPolicyCreateAppleMMCSService(CFStringRef hostname
, CFDictionaryRef __unused context
)
868 return SecPolicyCreateSSL(true, hostname
);
871 SecPolicyRef
SecPolicyCreateAppleGSService(CFStringRef hostname
, CFDictionaryRef __unused context
)
873 return SecPolicyCreateSSL(true, hostname
);
876 SecPolicyRef
SecPolicyCreateApplePPQService(CFStringRef hostname
, CFDictionaryRef __unused context
)
878 return SecPolicyCreateSSL(true, hostname
);
883 SecPolicyRef
SecPolicyCreateAppleATVAppSigning(void)
885 return _SecPolicyCreateWithOID(kSecPolicyAppleX509Basic
);
891 SecPolicyRef
SecPolicyCreateTestAppleATVAppSigning(void)
893 return _SecPolicyCreateWithOID(kSecPolicyAppleX509Basic
);
899 SecPolicyRef
SecPolicyCreateApplePayIssuerEncryption(void)
901 return _SecPolicyCreateWithOID(kSecPolicyAppleX509Basic
);
907 SecPolicyRef
SecPolicyCreateOSXProvisioningProfileSigning(void)
909 return _SecPolicyCreateWithOID(kSecPolicyAppleOSXProvisioningProfileSigning
);
914 SecPolicyRef
SecPolicyCreateAppleSSLService(CFStringRef hostname
)
916 // SSL server, pinned to an Apple intermediate
917 SecPolicyRef policy
= SecPolicyCreateSSL(true, hostname
);
919 // change options for policy evaluation
921 const char *hostnamestr
= NULL
;
923 hostnamestr
= CFStringGetCStringPtr(hostname
, kCFStringEncodingUTF8
);
924 if (hostnamestr
== NULL
) {
925 CFIndex maxLen
= CFStringGetMaximumSizeForEncoding(CFStringGetLength(hostname
), kCFStringEncodingUTF8
) + 1;
926 strbuf
= (char *)malloc(maxLen
);
927 if (CFStringGetCString(hostname
, strbuf
, maxLen
, kCFStringEncodingUTF8
)) {
928 hostnamestr
= strbuf
;
932 uint32 hostnamelen
= (hostnamestr
) ? (uint32
)strlen(hostnamestr
) : 0;
933 uint32 flags
= 0x00000002; // 2nd-lowest bit set to require Apple intermediate pin
934 CSSM_APPLE_TP_SSL_OPTIONS opts
= {CSSM_APPLE_TP_SSL_OPTS_VERSION
, hostnamelen
, hostnamestr
, flags
};
935 CSSM_DATA data
= {sizeof(opts
), (uint8
*)&opts
};
936 SecPolicySetValue(policy
, &data
);
943 #include <security_utilities/cfutilities.h>
945 // Takes the "context" policies to extract the revocation and apply it to timeStamp.
947 SecPolicyCreateAppleTimeStampingAndRevocationPolicies(CFTypeRef policyOrArray
)
950 /* can't use SECAPI macros, since this function does not return OSStatus */
951 CFArrayRef resultPolicyArray
=NULL
;
953 // Set default policy
954 CFRef
<CFArrayRef
> policyArray
= cfArrayize(policyOrArray
);
955 CFRef
<SecPolicyRef
> defaultPolicy
= _SecPolicyCreateWithOID(kSecPolicyAppleTimeStamping
);
956 CFRef
<CFMutableArrayRef
> appleTimeStampingPolicies
= makeCFMutableArray(1,defaultPolicy
.get());
958 // Parse the policy and add revocation related ones
959 CFIndex numPolicies
= CFArrayGetCount(policyArray
);
960 for(CFIndex dex
=0; dex
<numPolicies
; dex
++) {
961 SecPolicyRef secPol
= (SecPolicyRef
)CFArrayGetValueAtIndex(policyArray
, dex
);
962 SecPointer
<Policy
> pol
= Policy::required(SecPolicyRef(secPol
));
963 const CssmOid
&oid
= pol
->oid();
964 if ((oid
== CssmOid::overlay(CSSMOID_APPLE_TP_REVOCATION
))
965 || (oid
== CssmOid::overlay(CSSMOID_APPLE_TP_REVOCATION_CRL
))
966 || (oid
== CssmOid::overlay(CSSMOID_APPLE_TP_REVOCATION_OCSP
)))
968 CFArrayAppendValue(appleTimeStampingPolicies
, secPol
);
971 // Transfer of ownership
972 resultPolicyArray
=appleTimeStampingPolicies
.yield();
975 CFReleaseNull(resultPolicyArray
);
978 /* implement with unified SecPolicyRef instances */
979 /* %%% FIXME revisit this since SecPolicyCreateWithOID is OSX-only; */
980 /* should use SecPolicyCreateWithProperties instead */
981 SecPolicyRef policy
= NULL
;
982 CFMutableArrayRef resultPolicyArray
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
983 policy
= SecPolicyCreateWithOID(kSecPolicyAppleTimeStamping
);
985 CFArrayAppendValue(resultPolicyArray
, policy
);
986 CFReleaseNull(policy
);
988 policy
= SecPolicyCreateWithOID(kSecPolicyAppleRevocation
);
990 CFArrayAppendValue(resultPolicyArray
, policy
);
991 CFReleaseNull(policy
);
994 return resultPolicyArray
;