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");
80 SEC_CONST_DECL (kSecPolicyAppleAST2DiagnosticsServerAuth
, "1.2.840.113625.100.1.42");
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 SEC_CONST_DECL (kSecPolicyKU_DigitalSignature
, "CE_KU_DigitalSignature");
89 SEC_CONST_DECL (kSecPolicyKU_NonRepudiation
, "CE_KU_NonRepudiation");
90 SEC_CONST_DECL (kSecPolicyKU_KeyEncipherment
, "CE_KU_KeyEncipherment");
91 SEC_CONST_DECL (kSecPolicyKU_DataEncipherment
, "CE_KU_DataEncipherment");
92 SEC_CONST_DECL (kSecPolicyKU_KeyAgreement
, "CE_KU_KeyAgreement");
93 SEC_CONST_DECL (kSecPolicyKU_KeyCertSign
, "CE_KU_KeyCertSign");
94 SEC_CONST_DECL (kSecPolicyKU_CRLSign
, "CE_KU_CRLSign");
95 SEC_CONST_DECL (kSecPolicyKU_EncipherOnly
, "CE_KU_EncipherOnly");
96 SEC_CONST_DECL (kSecPolicyKU_DecipherOnly
, "CE_KU_DecipherOnly");
101 CFArrayRef
SecPolicyCopyEscrowRootCertificates(void);
103 CFStringRef
SecPolicyGetOidString(SecPolicyRef policy
);
104 CFDictionaryRef
SecPolicyGetOptions(SecPolicyRef policy
);
105 void SecPolicySetOptionsValue(SecPolicyRef policy
, CFStringRef key
, CFTypeRef value
);
109 // String to CSSM_OID mapping
111 struct oidmap_entry_s
{
112 const CFTypeRef oidstr
;
113 const SecAsn1Oid
*oidptr
;
115 typedef struct oidmap_entry_s oidmap_entry_t
;
117 // policies enumerated by SecPolicySearch (PolicyCursor.cpp)
119 static_cast<const CssmOid *>(&CSSMOID_APPLE_ISIGN), // no longer supported
120 static_cast<const CssmOid *>(&CSSMOID_APPLE_X509_BASIC),
121 static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_SSL),
122 static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_SMIME),
123 static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_EAP),
124 static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_SW_UPDATE_SIGNING),
125 static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_IP_SEC),
126 static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_ICHAT), // no longer supported
127 static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_RESOURCE_SIGN),
128 static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_PKINIT_CLIENT),
129 static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_PKINIT_SERVER),
130 static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_CODE_SIGNING),
131 static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_PACKAGE_SIGNING),
132 static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_REVOCATION_CRL),
133 static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_REVOCATION_OCSP),
134 static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_MACAPPSTORE_RECEIPT),
135 static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_APPLEID_SHARING),
136 static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_TIMESTAMPING),
138 const oidmap_entry_t oidmap
[] = {
139 { kSecPolicyAppleX509Basic
, &CSSMOID_APPLE_X509_BASIC
},
140 { kSecPolicyAppleSSL
, &CSSMOID_APPLE_TP_SSL
},
141 { kSecPolicyAppleSMIME
, &CSSMOID_APPLE_TP_SMIME
},
142 { kSecPolicyAppleEAP
, &CSSMOID_APPLE_TP_EAP
},
143 { kSecPolicyAppleSWUpdateSigning
, &CSSMOID_APPLE_TP_SW_UPDATE_SIGNING
},
144 { kSecPolicyAppleIPsec
, &CSSMOID_APPLE_TP_IP_SEC
},
145 { kSecPolicyAppleiChat
, &CSSMOID_APPLE_TP_ICHAT
},
146 { kSecPolicyApplePKINITClient
, &CSSMOID_APPLE_TP_PKINIT_CLIENT
},
147 { kSecPolicyApplePKINITServer
, &CSSMOID_APPLE_TP_PKINIT_SERVER
},
148 { kSecPolicyAppleCodeSigning
, &CSSMOID_APPLE_TP_CODE_SIGNING
},
149 { kSecPolicyApplePackageSigning
, &CSSMOID_APPLE_TP_PACKAGE_SIGNING
},
150 { kSecPolicyAppleIDValidation
, &CSSMOID_APPLE_TP_APPLEID_SHARING
},
151 { kSecPolicyMacAppStoreReceipt
, &CSSMOID_APPLE_TP_MACAPPSTORE_RECEIPT
},
152 { kSecPolicyAppleTimeStamping
, &CSSMOID_APPLE_TP_TIMESTAMPING
},
153 { kSecPolicyAppleRevocation
, &CSSMOID_APPLE_TP_REVOCATION
},
154 { kSecPolicyAppleRevocation
, &CSSMOID_APPLE_TP_REVOCATION_OCSP
},
155 { kSecPolicyAppleRevocation
, &CSSMOID_APPLE_TP_REVOCATION_CRL
},
156 { kSecPolicyApplePassbookSigning
, &CSSMOID_APPLE_TP_PASSBOOK_SIGNING
},
157 { kSecPolicyAppleMobileStore
, &CSSMOID_APPLE_TP_MOBILE_STORE
},
158 { kSecPolicyAppleEscrowService
, &CSSMOID_APPLE_TP_ESCROW_SERVICE
},
159 { kSecPolicyAppleProfileSigner
, &CSSMOID_APPLE_TP_PROFILE_SIGNING
},
160 { kSecPolicyAppleQAProfileSigner
, &CSSMOID_APPLE_TP_QA_PROFILE_SIGNING
},
161 { kSecPolicyAppleTestMobileStore
, &CSSMOID_APPLE_TP_TEST_MOBILE_STORE
},
162 { kSecPolicyApplePCSEscrowService
, &CSSMOID_APPLE_TP_PCS_ESCROW_SERVICE
},
163 { kSecPolicyAppleOSXProvisioningProfileSigning
, &CSSMOID_APPLE_TP_PROVISIONING_PROFILE_SIGNING
},
171 SecPolicyGetTypeID(void)
174 return gTypes().Policy
.typeID
;
175 END_SECAPI1(_kCFRuntimeNotATypeID
)
180 // Sec API bridge functions
182 /* OS X only: __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2, __MAC_10_7, __IPHONE_NA, __IPHONE_NA) */
184 SecPolicyGetOID(SecPolicyRef policyRef
, CSSM_OID
* oid
)
188 Required(oid
) = Policy::required(policyRef
)->oid();
191 /* bridge to support old functionality */
195 CFStringRef oidStr
= (CFStringRef
) SecPolicyGetOidString(policyRef
);
196 if (!oidStr
|| !oid
) {
197 return errSecParam
; // bad policy ref?
199 CSSM_OID
*oidptr
= NULL
;
200 unsigned int i
, oidmaplen
= sizeof(oidmap
) / sizeof(oidmap_entry_t
);
201 for (i
=0; i
<oidmaplen
; i
++) {
202 CFStringRef str
= (CFStringRef
) oidmap
[i
].oidstr
;
203 if (CFStringCompare(str
, oidStr
, 0) == kCFCompareEqualTo
) {
204 oidptr
= (CSSM_OID
*)oidmap
[i
].oidptr
;
209 // Check private iOS policy names.
210 oidmaplen
= sizeof(oidmap_priv
) / sizeof(oidmap_entry_t
);
211 for (i
=0; i
<oidmaplen
; i
++) {
212 CFStringRef str
= (CFStringRef
) oidmap_priv
[i
].oidstr
;
213 if (CFStringCompare(str
, oidStr
, 0) == kCFCompareEqualTo
) {
214 oidptr
= (CSSM_OID
*)oidmap_priv
[i
].oidptr
;
220 oid
->Data
= oidptr
->Data
;
221 oid
->Length
= oidptr
->Length
;
222 return errSecSuccess
;
225 syslog(LOG_ERR
, "WARNING: SecPolicyGetOID failed to return an OID. This function was deprecated in 10.7. Please use SecPolicyCopyProperties instead.");
226 return errSecServiceNotAvailable
;
230 // TODO: use a version of this function from a utility library
231 static CSSM_BOOL
compareOids(
232 const CSSM_OID
*oid1
,
233 const CSSM_OID
*oid2
)
235 if((oid1
== NULL
) || (oid2
== NULL
)) {
238 if(oid1
->Length
!= oid2
->Length
) {
241 if(memcmp(oid1
->Data
, oid2
->Data
, oid1
->Length
)) {
250 CFStringRef
SecPolicyGetStringForOID(CSSM_OID
* oid
)
255 // given a CSSM_OID pointer, return corresponding string in oidmap
256 unsigned int i
, oidmaplen
= sizeof(oidmap
) / sizeof(oidmap_entry_t
);
257 for (i
=0; i
<oidmaplen
; i
++) {
258 CSSM_OID
* oidptr
= (CSSM_OID
*)oidmap
[i
].oidptr
;
259 if (compareOids(oid
, oidptr
)) {
260 return (CFStringRef
) oidmap
[i
].oidstr
;
267 static bool SecPolicyGetCSSMDataValueForString(SecPolicyRef policyRef
, CFStringRef stringRef
, CSSM_DATA
* value
)
269 // Old API expects to vend a pointer and length for a policy value.
270 // The API contract says this pointer is good for the life of the policy.
271 // However, the new policy values are CF objects, and we need a separate
272 // buffer to get their UTF8 bytes. This buffer needs to be released when
273 // the policy object is released.
275 CFDataRef data
= NULL
;
276 CFIndex maxLength
= CFStringGetMaximumSizeForEncoding(CFStringGetLength(stringRef
), kCFStringEncodingUTF8
) + 1;
277 char* buf
= (char*) malloc(maxLength
);
281 if (CFStringGetCString(stringRef
, buf
, (CFIndex
)maxLength
, kCFStringEncodingUTF8
)) {
282 CFIndex length
= strlen(buf
);
283 data
= CFDataCreate(NULL
, (const UInt8
*)buf
, length
);
287 value
->Data
= (uint8
*)((data
) ? CFDataGetBytePtr(data
) : NULL
);
288 value
->Length
= (CSSM_SIZE
)((data
) ? CFDataGetLength(data
) : 0);
291 // stash this in a place where it will be released when the policy is destroyed
293 SecPolicySetOptionsValue(policyRef
, CFSTR("policy_data"), data
);
297 syslog(LOG_ERR
, "WARNING: policy dictionary not found to store returned data; will leak!");
304 /* OS X only: __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2, __MAC_10_7, __IPHONE_NA, __IPHONE_NA) */
306 SecPolicyGetValue(SecPolicyRef policyRef
, CSSM_DATA
* value
)
310 Required(value
) = Policy::required(policyRef
)->value();
313 /* bridge to support old functionality */
314 #if SECTRUST_DEPRECATION_WARNINGS
315 syslog(LOG_ERR
, "WARNING: SecPolicyGetValue was deprecated in 10.7. Please use SecPolicyCopyProperties instead.");
317 if (!(policyRef
&& value
)) {
320 CFDictionaryRef options
= SecPolicyGetOptions(policyRef
);
321 if (!(options
&& (CFDictionaryGetTypeID() == CFGetTypeID(options
)))) {
324 CFTypeRef name
= NULL
;
326 if (CFDictionaryGetValueIfPresent(options
, CFSTR("SSLHostname") /*kSecPolicyCheckSSLHostname*/,
327 (const void **)&name
) && name
) {
330 if (CFDictionaryGetValueIfPresent(options
, CFSTR("EAPTrustedServerNames") /*kSecPolicyCheckEAPTrustedServerNames*/,
331 (const void **)&name
) && name
) {
334 if (CFDictionaryGetValueIfPresent(options
, CFSTR("email") /*kSecPolicyCheckEmail*/,
335 (const void **)&name
) && name
) {
340 CFTypeID typeID
= CFGetTypeID(name
);
341 if (CFArrayGetTypeID() == typeID
) {
342 name
= (CFStringRef
) CFArrayGetValueAtIndex((CFArrayRef
)name
, 0);
344 SecPolicyGetCSSMDataValueForString(policyRef
, (CFStringRef
)name
, value
);
350 return errSecSuccess
;
356 SecPolicyCopyProperties(SecPolicyRef policyRef
)
358 /* can't use SECAPI macros, since this function does not return OSStatus */
359 CFDictionaryRef result
= NULL
;
361 result
= Policy::required(policyRef
)->properties();
373 /* OS X only: __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2, __MAC_10_7, __IPHONE_NA, __IPHONE_NA) */
375 SecPolicySetValue(SecPolicyRef policyRef
, const CSSM_DATA
*value
)
380 const CssmData
newValue(value
->Data
, value
->Length
);
381 Policy::required(policyRef
)->setValue(newValue
);
384 /* bridge to support old functionality */
385 #if SECTRUST_DEPRECATION_WARNINGS
386 syslog(LOG_ERR
, "WARNING: SecPolicySetValue was deprecated in 10.7. Please use SecPolicySetProperties instead.");
388 if (!(policyRef
&& value
)) {
391 OSStatus status
= errSecSuccess
;
392 CFDataRef data
= NULL
;
393 CFStringRef name
= NULL
;
394 CFNumberRef cnum
= NULL
;
395 CFStringRef oid
= (CFStringRef
) SecPolicyGetOidString(policyRef
);
397 syslog(LOG_ERR
, "SecPolicySetValue: unknown policy OID");
398 return errSecParam
; // bad policy ref?
400 if (CFEqual(oid
, CFSTR("sslServer") /*kSecPolicyOIDSSLServer*/) ||
401 CFEqual(oid
, CFSTR("sslClient") /*kSecPolicyOIDSSLClient*/) ||
402 CFEqual(oid
, CFSTR("ipsecServer") /*kSecPolicyOIDIPSecServer*/) ||
403 CFEqual(oid
, CFSTR("ipsecClient") /*kSecPolicyOIDIPSecClient*/) ||
404 CFEqual(oid
, kSecPolicyAppleSSL
) ||
405 CFEqual(oid
, kSecPolicyAppleIPsec
) ||
406 CFEqual(oid
, kSecPolicyAppleIDValidation
)
408 CSSM_APPLE_TP_SSL_OPTIONS
*opts
= (CSSM_APPLE_TP_SSL_OPTIONS
*)value
->Data
;
409 if (opts
->Version
== CSSM_APPLE_TP_SSL_OPTS_VERSION
) {
410 if (opts
->ServerNameLen
> 0) {
411 data
= CFDataCreate(NULL
, (const UInt8
*)opts
->ServerName
, opts
->ServerNameLen
);
412 name
= (data
) ? CFStringCreateFromExternalRepresentation(NULL
, data
, kCFStringEncodingUTF8
) : NULL
;
416 SecPolicySetOptionsValue(policyRef
, CFSTR("SSLHostname") /*kSecPolicyCheckSSLHostname*/, name
);
419 status
= errSecParam
;
422 else if (CFEqual(oid
, CFSTR("eapServer") /*kSecPolicyOIDEAPServer*/) ||
423 CFEqual(oid
, CFSTR("eapClient") /*kSecPolicyOIDEAPClient*/) ||
424 CFEqual(oid
, kSecPolicyAppleEAP
)
426 CSSM_APPLE_TP_SSL_OPTIONS
*opts
= (CSSM_APPLE_TP_SSL_OPTIONS
*)value
->Data
;
427 if (opts
->Version
== CSSM_APPLE_TP_SSL_OPTS_VERSION
) {
428 if (opts
->ServerNameLen
> 0) {
429 data
= CFDataCreate(NULL
, (const UInt8
*)opts
->ServerName
, opts
->ServerNameLen
);
430 name
= (data
) ? CFStringCreateFromExternalRepresentation(NULL
, data
, kCFStringEncodingUTF8
) : NULL
;
434 SecPolicySetOptionsValue(policyRef
, CFSTR("EAPTrustedServerNames") /*kSecPolicyCheckEAPTrustedServerNames*/, name
);
437 status
= errSecParam
;
440 else if (CFEqual(oid
, CFSTR("SMIME") /*kSecPolicyOIDSMIME*/) ||
441 CFEqual(oid
, CFSTR("AppleShoebox") /*kSecPolicyOIDAppleShoebox*/) ||
442 CFEqual(oid
, CFSTR("ApplePassbook") /*kSecPolicyOIDApplePassbook*/) ||
443 CFEqual(oid
, kSecPolicyAppleSMIME
) ||
444 CFEqual(oid
, kSecPolicyApplePassbookSigning
)
446 CSSM_APPLE_TP_SMIME_OPTIONS
*opts
= (CSSM_APPLE_TP_SMIME_OPTIONS
*)value
->Data
;
447 if (opts
->Version
== CSSM_APPLE_TP_SMIME_OPTS_VERSION
) {
448 if (opts
->SenderEmailLen
> 0) {
449 data
= CFDataCreate(NULL
, (const UInt8
*)opts
->SenderEmail
, opts
->SenderEmailLen
);
450 name
= (data
) ? CFStringCreateFromExternalRepresentation(NULL
, data
, kCFStringEncodingUTF8
) : NULL
;
454 SecPolicySetOptionsValue(policyRef
, CFSTR("email") /*kSecPolicyCheckEmail*/, name
);
457 status
= errSecParam
;
460 else if (CFEqual(oid
, CFSTR("revocation") /* kSecPolicyOIDRevocation */) ||
461 CFEqual(oid
, kSecPolicyAppleRevocation
)
463 CSSM_APPLE_TP_CRL_OPTIONS
*opts
= (CSSM_APPLE_TP_CRL_OPTIONS
*)value
->Data
;
464 if (opts
->Version
== CSSM_APPLE_TP_CRL_OPTS_VERSION
) {
465 CSSM_APPLE_TP_CRL_OPT_FLAGS crlFlags
= opts
->CrlFlags
;
466 CFOptionFlags revocationFlags
= 0;
467 if ((crlFlags
& CSSM_TP_ACTION_FETCH_CRL_FROM_NET
) == 0) {
468 /* disable network access */
469 revocationFlags
|= kSecRevocationNetworkAccessDisabled
;
471 if ((crlFlags
& CSSM_TP_ACTION_CRL_SUFFICIENT
) == 0) {
472 /* if OCSP method is not sufficient, must use CRL */
473 revocationFlags
|= (kSecRevocationCRLMethod
| kSecRevocationPreferCRL
);
475 /* either method is sufficient */
476 revocationFlags
|= kSecRevocationUseAnyAvailableMethod
;
478 if ((crlFlags
& CSSM_TP_ACTION_REQUIRE_CRL_PER_CERT
) != 0) {
479 /* require a response */
480 revocationFlags
|= kSecRevocationRequirePositiveResponse
;
482 cnum
= CFNumberCreate(kCFAllocatorDefault
, kCFNumberCFIndexType
, &revocationFlags
);
484 SecPolicySetOptionsValue(policyRef
, kSecPolicyRevocationFlags
, cnum
);
489 syslog(LOG_ERR
, "SecPolicySetValue: unrecognized policy OID");
490 status
= errSecParam
;
492 if (data
) { CFRelease(data
); }
493 if (name
) { CFRelease(name
); }
494 if (cnum
) { CFRelease(cnum
); }
501 SecPolicySetProperties(SecPolicyRef policyRef
, CFDictionaryRef properties
)
504 Policy::required(policyRef
)->setProperties(properties
);
509 /* OS X only: __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2, __MAC_10_7, __IPHONE_NA, __IPHONE_NA) */
511 SecPolicyGetTPHandle(SecPolicyRef policyRef
, CSSM_TP_HANDLE
* tpHandle
)
515 Required(tpHandle
) = Policy::required(policyRef
)->tp()->handle();
518 /* this function is unsupported in unified SecTrust */
519 #if SECTRUST_DEPRECATION_WARNINGS
520 syslog(LOG_ERR
, "WARNING: SecPolicyGetTPHandle was deprecated in 10.7, and does nothing in 10.11. Please stop using it.");
522 return errSecServiceNotAvailable
;
526 /* OS X only: __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_3, __MAC_10_7, __IPHONE_NA, __IPHONE_NA) */
528 SecPolicyCopyAll(CSSM_CERT_TYPE certificateType
, CFArrayRef
* policies
)
533 CFMutableArrayRef currPolicies
= NULL
;
534 currPolicies
= CFArrayCreateMutable(NULL
, 0, NULL
);
537 SecPointer
<PolicyCursor
> cursor(new PolicyCursor(NULL
, NULL
));
538 SecPointer
<Policy
> policy
;
539 while ( cursor
->next(policy
) ) /* copies the next policy */
541 CFArrayAppendValue(currPolicies
, policy
->handle()); /* 'SecPolicyRef' appended */
542 CFRelease(policy
->handle()); /* refcount bumped up when appended to array */
544 *policies
= CFArrayCreateCopy(NULL
, currPolicies
);
545 CFRelease(currPolicies
);
546 CFRelease(cursor
->handle());
550 /* bridge to support old functionality */
551 #if SECTRUST_DEPRECATION_WARNINGS
552 syslog(LOG_ERR
, "WARNING: SecPolicyCopyAll was deprecated in 10.7. Please use SecPolicy creation functions instead.");
557 CFMutableArrayRef curPolicies
= CFArrayCreateMutable(NULL
, 0, NULL
);
559 return errSecAllocate
;
561 /* build the subset of policies which were supported on OS X,
562 and which are also implemented on iOS */
563 CFStringRef supportedPolicies
[] = {
564 kSecPolicyAppleX509Basic
, /* CSSMOID_APPLE_X509_BASIC */
565 kSecPolicyAppleSSL
, /* CSSMOID_APPLE_TP_SSL */
566 kSecPolicyAppleSMIME
, /* CSSMOID_APPLE_TP_SMIME */
567 kSecPolicyAppleEAP
, /*CSSMOID_APPLE_TP_EAP */
568 kSecPolicyAppleSWUpdateSigning
, /* CSSMOID_APPLE_TP_SW_UPDATE_SIGNING */
569 kSecPolicyAppleIPsec
, /* CSSMOID_APPLE_TP_IP_SEC */
570 kSecPolicyAppleCodeSigning
, /* CSSMOID_APPLE_TP_CODE_SIGNING */
571 kSecPolicyMacAppStoreReceipt
, /* CSSMOID_APPLE_TP_MACAPPSTORE_RECEIPT */
572 kSecPolicyAppleIDValidation
, /* CSSMOID_APPLE_TP_APPLEID_SHARING */
573 kSecPolicyAppleTimeStamping
, /* CSSMOID_APPLE_TP_TIMESTAMPING */
574 kSecPolicyAppleRevocation
, /* CSSMOID_APPLE_TP_REVOCATION_{CRL,OCSP} */
579 CFStringRef policyID
= supportedPolicies
[ix
++];
583 SecPolicyRef curPolicy
= SecPolicyCreateWithProperties(policyID
, NULL
);
585 CFArrayAppendValue(curPolicies
, curPolicy
);
586 CFRelease(curPolicy
);
589 *policies
= CFArrayCreateCopy(NULL
, curPolicies
);
590 CFRelease(curPolicies
);
591 return errSecSuccess
;
595 /* OS X only: __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_3, __MAC_10_7, __IPHONE_NA, __IPHONE_NA) */
597 SecPolicyCopy(CSSM_CERT_TYPE certificateType
, const CSSM_OID
*policyOID
, SecPolicyRef
* policy
)
603 if (!policyOID
|| !policy
) {
607 SecPolicySearchRef srchRef
= NULL
;
610 ortn
= SecPolicySearchCreate(certificateType
, policyOID
, NULL
, &srchRef
);
614 ortn
= SecPolicySearchCopyNext(srchRef
, policy
);
619 /* OS X only: convert a new-world SecPolicyRef to an old-world ItemImpl instance */
621 SecPolicyCreateItemImplInstance(SecPolicyRef policy
)
624 return (SecPolicyRef
)(policy
? CFRetain(policy
) : NULL
);
630 OSStatus status
= SecPolicyGetOID(policy
, &oid
);
634 SecPolicyRef policyRef
= NULL
;
635 CFDictionaryRef properties
= SecPolicyCopyProperties(policy
);
637 SecPointer
<Policy
> policyObj
;
638 PolicyCursor::policy(&oid
, policyObj
);
639 policyRef
= policyObj
->handle();
640 Policy::required(policyRef
)->setProperties(properties
);
646 CFRelease(properties
);
655 SecPolicyCreateBasicX509(void)
657 // return a SecPolicyRef object for the X.509 Basic policy
658 SecPolicyRef policy
= nil
;
659 SecPolicySearchRef policySearch
= nil
;
660 OSStatus status
= SecPolicySearchCreate(CSSM_CERT_X_509v3
, &CSSMOID_APPLE_X509_BASIC
, NULL
, &policySearch
);
662 status
= SecPolicySearchCopyNext(policySearch
, &policy
);
665 CFRelease(policySearch
);
674 SecPolicyCreateSSL(Boolean server
, CFStringRef hostname
)
676 // return a SecPolicyRef object for the SSL policy, given hostname and client options
677 SecPolicyRef policy
= nil
;
678 SecPolicySearchRef policySearch
= nil
;
679 OSStatus status
= SecPolicySearchCreate(CSSM_CERT_X_509v3
, &CSSMOID_APPLE_TP_SSL
, NULL
, &policySearch
);
681 status
= SecPolicySearchCopyNext(policySearch
, &policy
);
683 if (!status
&& policy
) {
684 // set options for client-side or server-side policy evaluation
686 const char *hostnamestr
= NULL
;
688 hostnamestr
= CFStringGetCStringPtr(hostname
, kCFStringEncodingUTF8
);
689 if (hostnamestr
== NULL
) {
690 CFIndex maxLen
= CFStringGetMaximumSizeForEncoding(CFStringGetLength(hostname
), kCFStringEncodingUTF8
) + 1;
691 strbuf
= (char *)malloc(maxLen
);
692 if (CFStringGetCString(hostname
, strbuf
, maxLen
, kCFStringEncodingUTF8
)) {
693 hostnamestr
= strbuf
;
697 uint32 hostnamelen
= (hostnamestr
) ? (uint32
)strlen(hostnamestr
) : 0;
698 uint32 flags
= (!server
) ? CSSM_APPLE_TP_SSL_CLIENT
: 0;
699 CSSM_APPLE_TP_SSL_OPTIONS opts
= {CSSM_APPLE_TP_SSL_OPTS_VERSION
, hostnamelen
, hostnamestr
, flags
};
700 CSSM_DATA data
= {sizeof(opts
), (uint8
*)&opts
};
701 SecPolicySetValue(policy
, &data
);
708 CFRelease(policySearch
);
717 SecPolicyCreateWithSecAsn1Oid(SecAsn1Oid
*oidPtr
)
719 SecPolicyRef policy
= NULL
;
721 SecPointer
<Policy
> policyObj
;
722 PolicyCursor::policy(oidPtr
, policyObj
);
723 policy
= policyObj
->handle();
732 _SecPolicyCreateWithOID(CFTypeRef policyOID
)
734 // for now, we only accept the policy constants that are defined in SecPolicy.h
735 CFStringRef oidStr
= (CFStringRef
)policyOID
;
736 CSSM_OID
*oidPtr
= NULL
;
737 SecPolicyRef policy
= NULL
;
741 unsigned int i
, oidmaplen
= sizeof(oidmap
) / sizeof(oidmap_entry_t
);
742 for (i
=0; i
<oidmaplen
; i
++) {
743 CFStringRef str
= (CFStringRef
) oidmap
[i
].oidstr
;
744 if (CFStringCompare(str
, oidStr
, 0) == kCFCompareEqualTo
) {
745 oidPtr
= (CSSM_OID
*)oidmap
[i
].oidptr
;
749 if (CFEqual(oidStr
, kSecPolicyAppleServerAuthentication
)) {
750 return SecPolicyCreateAppleSSLService(NULL
);
753 SecPolicySearchRef policySearch
= NULL
;
754 OSStatus status
= SecPolicySearchCreate(CSSM_CERT_X_509v3
, oidPtr
, NULL
, &policySearch
);
755 if (!status
&& policySearch
) {
756 status
= SecPolicySearchCopyNext(policySearch
, &policy
);
757 if (status
!= errSecSuccess
) {
760 CFRelease(policySearch
);
762 if (!policy
&& CFEqual(policyOID
, kSecPolicyAppleRevocation
)) {
763 policy
= SecPolicyCreateRevocation(kSecRevocationUseAnyAvailableMethod
);
767 policy
= SecPolicyCreateWithSecAsn1Oid((SecAsn1Oid
*)oidPtr
);
774 /* OS X only: __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_7, __MAC_10_9, __IPHONE_NA, __IPHONE_NA) */
776 SecPolicyCreateWithOID(CFTypeRef policyOID
)
778 SecPolicyRef policy
= _SecPolicyCreateWithOID(policyOID
);
780 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.");
788 SecPolicyCreateWithProperties(CFTypeRef policyIdentifier
, CFDictionaryRef properties
)
790 SecPolicyRef policy
= _SecPolicyCreateWithOID(policyIdentifier
);
791 SecPolicySetProperties(policy
, properties
);
800 SecPolicyCreateRevocation(CFOptionFlags revocationFlags
)
802 // return a SecPolicyRef object for the unified revocation policy
803 SecAsn1Oid
*oidPtr
= (SecAsn1Oid
*)&CSSMOID_APPLE_TP_REVOCATION
;
804 SecPolicyRef policy
= SecPolicyCreateWithSecAsn1Oid(oidPtr
);
806 CSSM_DATA policyData
= { (CSSM_SIZE
)sizeof(CFOptionFlags
), (uint8
*)&revocationFlags
};
807 SecPolicySetValue(policy
, &policyData
);
813 /* OS X only: deprecated SPI entry point */
814 /* new in 10.9 ***FIXME*** TO BE REMOVED */
815 CFArrayRef
SecPolicyCopyEscrowRootCertificates(void)
817 return SecCertificateCopyEscrowRoots(kSecCertificateProductionEscrowRoot
);
820 SecPolicyRef
SecPolicyCreateAppleIDSService(CFStringRef hostname
)
822 return SecPolicyCreateSSL(true, hostname
);
825 SecPolicyRef
SecPolicyCreateAppleIDSServiceContext(CFStringRef hostname
, CFDictionaryRef __unused context
)
827 return SecPolicyCreateSSL(true, hostname
);
830 SecPolicyRef
SecPolicyCreateApplePushService(CFStringRef hostname
, CFDictionaryRef __unused context
)
832 return SecPolicyCreateSSL(true, hostname
);
835 SecPolicyRef
SecPolicyCreateApplePushServiceLegacy(CFStringRef hostname
)
837 return SecPolicyCreateSSL(true, hostname
);
840 SecPolicyRef
SecPolicyCreateAppleMMCSService(CFStringRef hostname
, CFDictionaryRef __unused context
)
842 return SecPolicyCreateSSL(true, hostname
);
845 SecPolicyRef
SecPolicyCreateAppleGSService(CFStringRef hostname
, CFDictionaryRef __unused context
)
847 return SecPolicyCreateSSL(true, hostname
);
850 SecPolicyRef
SecPolicyCreateApplePPQService(CFStringRef hostname
, CFDictionaryRef __unused context
)
852 return SecPolicyCreateSSL(true, hostname
);
855 SecPolicyRef
SecPolicyCreateAppleAST2Service(CFStringRef hostname
, CFDictionaryRef __unused context
)
857 return SecPolicyCreateSSL(true, hostname
);
860 SecPolicyRef
SecPolicyCreateAppleHomeKitServerAuth(CFStringRef hostname
)
862 return SecPolicyCreateSSL(true, hostname
);
867 SecPolicyRef
SecPolicyCreateAppleATVAppSigning(void)
869 return _SecPolicyCreateWithOID(kSecPolicyAppleX509Basic
);
875 SecPolicyRef
SecPolicyCreateTestAppleATVAppSigning(void)
877 return _SecPolicyCreateWithOID(kSecPolicyAppleX509Basic
);
883 SecPolicyRef
SecPolicyCreateApplePayIssuerEncryption(void)
885 return _SecPolicyCreateWithOID(kSecPolicyAppleX509Basic
);
891 SecPolicyRef
SecPolicyCreateOSXProvisioningProfileSigning(void)
893 return _SecPolicyCreateWithOID(kSecPolicyAppleOSXProvisioningProfileSigning
);
900 SecPolicyRef
SecPolicyCreateAppleATVVPNProfileSigning(void)
902 return _SecPolicyCreateWithOID(kSecPolicyAppleX509Basic
);
907 SecPolicyRef
SecPolicyCreateAppleSSLService(CFStringRef hostname
)
909 // SSL server, pinned to an Apple intermediate
910 SecPolicyRef policy
= SecPolicyCreateSSL(true, hostname
);
912 // change options for policy evaluation
914 const char *hostnamestr
= NULL
;
916 hostnamestr
= CFStringGetCStringPtr(hostname
, kCFStringEncodingUTF8
);
917 if (hostnamestr
== NULL
) {
918 CFIndex maxLen
= CFStringGetMaximumSizeForEncoding(CFStringGetLength(hostname
), kCFStringEncodingUTF8
) + 1;
919 strbuf
= (char *)malloc(maxLen
);
920 if (CFStringGetCString(hostname
, strbuf
, maxLen
, kCFStringEncodingUTF8
)) {
921 hostnamestr
= strbuf
;
925 uint32 hostnamelen
= (hostnamestr
) ? (uint32
)strlen(hostnamestr
) : 0;
926 uint32 flags
= 0x00000002; // 2nd-lowest bit set to require Apple intermediate pin
927 CSSM_APPLE_TP_SSL_OPTIONS opts
= {CSSM_APPLE_TP_SSL_OPTS_VERSION
, hostnamelen
, hostnamestr
, flags
};
928 CSSM_DATA data
= {sizeof(opts
), (uint8
*)&opts
};
929 SecPolicySetValue(policy
, &data
);
936 #include <security_utilities/cfutilities.h>
938 // Takes the "context" policies to extract the revocation and apply it to timeStamp.
940 SecPolicyCreateAppleTimeStampingAndRevocationPolicies(CFTypeRef policyOrArray
)
943 /* can't use SECAPI macros, since this function does not return OSStatus */
944 CFArrayRef resultPolicyArray
=NULL
;
946 // Set default policy
947 CFRef
<CFArrayRef
> policyArray
= cfArrayize(policyOrArray
);
948 CFRef
<SecPolicyRef
> defaultPolicy
= _SecPolicyCreateWithOID(kSecPolicyAppleTimeStamping
);
949 CFRef
<CFMutableArrayRef
> appleTimeStampingPolicies
= makeCFMutableArray(1,defaultPolicy
.get());
951 // Parse the policy and add revocation related ones
952 CFIndex numPolicies
= CFArrayGetCount(policyArray
);
953 for(CFIndex dex
=0; dex
<numPolicies
; dex
++) {
954 SecPolicyRef secPol
= (SecPolicyRef
)CFArrayGetValueAtIndex(policyArray
, dex
);
955 SecPointer
<Policy
> pol
= Policy::required(SecPolicyRef(secPol
));
956 const CssmOid
&oid
= pol
->oid();
957 if ((oid
== CssmOid::overlay(CSSMOID_APPLE_TP_REVOCATION
))
958 || (oid
== CssmOid::overlay(CSSMOID_APPLE_TP_REVOCATION_CRL
))
959 || (oid
== CssmOid::overlay(CSSMOID_APPLE_TP_REVOCATION_OCSP
)))
961 CFArrayAppendValue(appleTimeStampingPolicies
, secPol
);
964 // Transfer of ownership
965 resultPolicyArray
=appleTimeStampingPolicies
.yield();
968 CFReleaseNull(resultPolicyArray
);
971 /* implement with unified SecPolicyRef instances */
972 /* %%% FIXME revisit this since SecPolicyCreateWithOID is OSX-only; */
973 /* should use SecPolicyCreateWithProperties instead */
974 SecPolicyRef policy
= NULL
;
975 CFMutableArrayRef resultPolicyArray
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
976 policy
= SecPolicyCreateWithOID(kSecPolicyAppleTimeStamping
);
978 CFArrayAppendValue(resultPolicyArray
, policy
);
979 CFReleaseNull(policy
);
981 policy
= SecPolicyCreateWithOID(kSecPolicyAppleRevocation
);
983 CFArrayAppendValue(resultPolicyArray
, policy
);
984 CFReleaseNull(policy
);
987 return resultPolicyArray
;