]> git.saurik.com Git - apple/security.git/blob - OSX/libsecurity_keychain/lib/SecPolicy.cpp
Security-59754.41.1.tar.gz
[apple/security.git] / OSX / libsecurity_keychain / lib / SecPolicy.cpp
1
2 /*
3 * Copyright (c) 2002-2015 Apple Inc. All Rights Reserved.
4 *
5 * @APPLE_LICENSE_HEADER_START@
6 *
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
12 * file.
13 *
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.
21 *
22 * @APPLE_LICENSE_HEADER_END@
23 */
24
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"
37 #include <syslog.h>
38
39
40 // String constant declarations
41
42 #define SEC_CONST_DECL(k,v) const CFStringRef k = CFSTR(v);
43
44 /* Some of these aren't defined in SecPolicy.c, but used here. */
45 SEC_CONST_DECL (kSecPolicyAppleiChat, "1.2.840.113635.100.1.12");
46
47 // Private functions
48
49 extern "C" {
50 CFDictionaryRef SecPolicyGetOptions(SecPolicyRef policy);
51 void SecPolicySetOptionsValue(SecPolicyRef policy, CFStringRef key, CFTypeRef value);
52 }
53
54 // String to CSSM_OID mapping
55
56 struct oidmap_entry_s {
57 const CFTypeRef oidstr;
58 const SecAsn1Oid *oidptr;
59 };
60 typedef struct oidmap_entry_s oidmap_entry_t;
61
62 // policies enumerated by SecPolicySearch (PolicyCursor.cpp)
63 /*
64 static_cast<const CssmOid *>(&CSSMOID_APPLE_ISIGN), // no longer supported
65 static_cast<const CssmOid *>(&CSSMOID_APPLE_X509_BASIC),
66 static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_SSL),
67 static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_SMIME),
68 static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_EAP),
69 static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_SW_UPDATE_SIGNING),
70 static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_IP_SEC),
71 static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_ICHAT), // no longer supported
72 static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_RESOURCE_SIGN),
73 static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_PKINIT_CLIENT),
74 static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_PKINIT_SERVER),
75 static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_CODE_SIGNING),
76 static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_PACKAGE_SIGNING),
77 static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_REVOCATION_CRL),
78 static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_REVOCATION_OCSP),
79 static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_MACAPPSTORE_RECEIPT),
80 static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_APPLEID_SHARING),
81 static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_TIMESTAMPING),
82 */
83
84 static const size_t OIDMAP_LENGTH = 25;
85 static const oidmap_entry_t* oidmap_f() {
86 static const oidmap_entry_t oidmap_array[] = {
87 { kSecPolicyAppleX509Basic, &CSSMOID_APPLE_X509_BASIC },
88 { kSecPolicyAppleSSL, &CSSMOID_APPLE_TP_SSL },
89 { kSecPolicyAppleSMIME, &CSSMOID_APPLE_TP_SMIME },
90 { kSecPolicyAppleEAP, &CSSMOID_APPLE_TP_EAP },
91 { kSecPolicyAppleSWUpdateSigning, &CSSMOID_APPLE_TP_SW_UPDATE_SIGNING },
92 { kSecPolicyAppleIPsec, &CSSMOID_APPLE_TP_IP_SEC },
93 { kSecPolicyAppleiChat, &CSSMOID_APPLE_TP_ICHAT },
94 { kSecPolicyApplePKINITClient, &CSSMOID_APPLE_TP_PKINIT_CLIENT },
95 { kSecPolicyApplePKINITServer, &CSSMOID_APPLE_TP_PKINIT_SERVER },
96 { kSecPolicyAppleCodeSigning, &CSSMOID_APPLE_TP_CODE_SIGNING },
97 { kSecPolicyApplePackageSigning, &CSSMOID_APPLE_TP_PACKAGE_SIGNING },
98 { kSecPolicyAppleIDValidation, &CSSMOID_APPLE_TP_APPLEID_SHARING },
99 { kSecPolicyMacAppStoreReceipt, &CSSMOID_APPLE_TP_MACAPPSTORE_RECEIPT },
100 { kSecPolicyAppleTimeStamping, &CSSMOID_APPLE_TP_TIMESTAMPING },
101 { kSecPolicyAppleRevocation, &CSSMOID_APPLE_TP_REVOCATION },
102 { kSecPolicyAppleRevocation, &CSSMOID_APPLE_TP_REVOCATION_OCSP },
103 { kSecPolicyAppleRevocation, &CSSMOID_APPLE_TP_REVOCATION_CRL },
104 { kSecPolicyApplePassbookSigning, &CSSMOID_APPLE_TP_PASSBOOK_SIGNING },
105 { kSecPolicyAppleMobileStore, &CSSMOID_APPLE_TP_MOBILE_STORE },
106 { kSecPolicyAppleEscrowService, &CSSMOID_APPLE_TP_ESCROW_SERVICE },
107 { kSecPolicyAppleProfileSigner, &CSSMOID_APPLE_TP_PROFILE_SIGNING },
108 { kSecPolicyAppleQAProfileSigner, &CSSMOID_APPLE_TP_QA_PROFILE_SIGNING },
109 { kSecPolicyAppleTestMobileStore, &CSSMOID_APPLE_TP_TEST_MOBILE_STORE },
110 { kSecPolicyApplePCSEscrowService, &CSSMOID_APPLE_TP_PCS_ESCROW_SERVICE },
111 { kSecPolicyAppleOSXProvisioningProfileSigning, &CSSMOID_APPLE_TP_PROVISIONING_PROFILE_SIGNING },
112 };
113 static_assert(OIDMAP_LENGTH == (sizeof(oidmap_array)/sizeof(oidmap_entry_t)), "OIDMAP_LENGTH is incorrect; must match oidmap_array");
114
115 return oidmap_array;
116 };
117
118 static const size_t OIDMAP_PRIV_LENGTH = 23;
119 static const oidmap_entry_t* oidmap_priv_f() {
120 static const oidmap_entry_t oidmap_priv_array[] = {
121 { CFSTR("basicX509"), &CSSMOID_APPLE_X509_BASIC },
122 { CFSTR("sslServer"), &CSSMOID_APPLE_TP_SSL },
123 { CFSTR("sslClient"), &CSSMOID_APPLE_TP_SSL },
124 { CFSTR("SMIME"), &CSSMOID_APPLE_TP_SMIME },
125 { CFSTR("eapServer"), &CSSMOID_APPLE_TP_EAP },
126 { CFSTR("eapClient"), &CSSMOID_APPLE_TP_EAP },
127 { CFSTR("AppleSWUpdateSigning"), &CSSMOID_APPLE_TP_SW_UPDATE_SIGNING },
128 { CFSTR("ipsecServer"), &CSSMOID_APPLE_TP_IP_SEC },
129 { CFSTR("ipsecClient"), &CSSMOID_APPLE_TP_IP_SEC },
130 { CFSTR("CodeSigning"), &CSSMOID_APPLE_TP_CODE_SIGNING },
131 { CFSTR("PackageSigning"), &CSSMOID_APPLE_TP_PACKAGE_SIGNING },
132 { CFSTR("AppleIDAuthority"), &CSSMOID_APPLE_TP_APPLEID_SHARING },
133 { CFSTR("MacAppStoreReceipt"), &CSSMOID_APPLE_TP_MACAPPSTORE_RECEIPT },
134 { CFSTR("AppleTimeStamping"), &CSSMOID_APPLE_TP_TIMESTAMPING },
135 { CFSTR("revocation"), &CSSMOID_APPLE_TP_REVOCATION },
136 { CFSTR("ApplePassbook"), &CSSMOID_APPLE_TP_PASSBOOK_SIGNING },
137 { CFSTR("AppleMobileStore"), &CSSMOID_APPLE_TP_MOBILE_STORE },
138 { CFSTR("AppleEscrowService"), &CSSMOID_APPLE_TP_ESCROW_SERVICE },
139 { CFSTR("AppleProfileSigner"), &CSSMOID_APPLE_TP_PROFILE_SIGNING },
140 { CFSTR("AppleQAProfileSigner"), &CSSMOID_APPLE_TP_QA_PROFILE_SIGNING },
141 { CFSTR("AppleTestMobileStore"), &CSSMOID_APPLE_TP_TEST_MOBILE_STORE },
142 { CFSTR("ApplePCSEscrowService"), &CSSMOID_APPLE_TP_PCS_ESCROW_SERVICE },
143 { CFSTR("AppleOSXProvisioningProfileSigning"), &CSSMOID_APPLE_TP_PROVISIONING_PROFILE_SIGNING },
144 };
145 static_assert(OIDMAP_PRIV_LENGTH == (sizeof(oidmap_priv_array)/sizeof(oidmap_entry_t)), "OIDMAP_PRIV_LENGTH is incorrect; must match oidmap_priv_array");
146
147 return oidmap_priv_array;
148 }
149
150 //
151 // Sec API bridge functions
152 //
153 /* OS X only: __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2, __MAC_10_7, __IPHONE_NA, __IPHONE_NA) */
154 OSStatus
155 SecPolicyGetOID(SecPolicyRef policyRef, CSSM_OID* oid)
156 {
157 /* bridge to support old functionality */
158 if (!policyRef) {
159 return errSecParam;
160 }
161 CFStringRef oidStr = (CFStringRef) SecPolicyGetOidString(policyRef);
162 if (!oidStr || !oid) {
163 return errSecParam; // bad policy ref?
164 }
165 CSSM_OID *oidptr = NULL;
166 unsigned int i;
167 for (i=0; i<OIDMAP_LENGTH; i++) {
168 CFStringRef str = (CFStringRef) oidmap_f()[i].oidstr;
169 if (CFStringCompare(str, oidStr, 0) == kCFCompareEqualTo) {
170 oidptr = (CSSM_OID*)oidmap_f()[i].oidptr;
171 break;
172 }
173 }
174 if (!oidptr) {
175 // Check private iOS policy names.
176
177 for (i=0; i<OIDMAP_PRIV_LENGTH; i++) {
178 CFStringRef str = (CFStringRef) oidmap_priv_f()[i].oidstr;
179 if (CFStringCompare(str, oidStr, 0) == kCFCompareEqualTo) {
180 oidptr = (CSSM_OID*)oidmap_priv_f()[i].oidptr;
181 break;
182 }
183 }
184 }
185 if (oidptr) {
186 oid->Data = oidptr->Data;
187 oid->Length = oidptr->Length;
188 return errSecSuccess;
189 }
190 CFShow(oidStr);
191 syslog(LOG_ERR, "WARNING: SecPolicyGetOID failed to return an OID. This function was deprecated in 10.7. Please use SecPolicyCopyProperties instead.");
192 return errSecServiceNotAvailable;
193 }
194
195 // TODO: use a version of this function from a utility library
196 static CSSM_BOOL compareOids(
197 const CSSM_OID *oid1,
198 const CSSM_OID *oid2)
199 {
200 if((oid1 == NULL) || (oid2 == NULL)) {
201 return CSSM_FALSE;
202 }
203 if(oid1->Length != oid2->Length) {
204 return CSSM_FALSE;
205 }
206 if(memcmp(oid1->Data, oid2->Data, oid1->Length)) {
207 return CSSM_FALSE;
208 }
209 else {
210 return CSSM_TRUE;
211 }
212 }
213
214 /* OS X only: */
215 CFStringRef SecPolicyGetStringForOID(CSSM_OID* oid)
216 {
217 if (!oid) {
218 return NULL;
219 }
220 // given a CSSM_OID pointer, return corresponding string in oidmap
221 unsigned int i;
222 for (i=0; i<OIDMAP_LENGTH; i++) {
223 CSSM_OID* oidptr = (CSSM_OID*)oidmap_f()[i].oidptr;
224 if (compareOids(oid, oidptr)) {
225 return (CFStringRef) oidmap_f()[i].oidstr;
226 }
227 }
228 return NULL;
229 }
230
231 static bool SecPolicyGetCSSMDataValueForString(SecPolicyRef policyRef, CFStringRef stringRef, CSSM_DATA* value)
232 {
233 // Old API expects to vend a pointer and length for a policy value.
234 // The API contract says this pointer is good for the life of the policy.
235 // However, the new policy values are CF objects, and we need a separate
236 // buffer to get their UTF8 bytes. This buffer needs to be released when
237 // the policy object is released.
238
239 CFDataRef data = NULL;
240 CFIndex maxLength = CFStringGetMaximumSizeForEncoding(CFStringGetLength(stringRef), kCFStringEncodingUTF8) + 1;
241 char* buf = (char*) malloc(maxLength);
242 if (!buf) {
243 return false;
244 }
245 if (CFStringGetCString(stringRef, buf, (CFIndex)maxLength, kCFStringEncodingUTF8)) {
246 CFIndex length = strlen(buf);
247 data = CFDataCreate(NULL, (const UInt8 *)buf, length);
248 }
249 free(buf);
250 if (value) {
251 value->Data = (uint8*)((data) ? CFDataGetBytePtr(data) : NULL);
252 value->Length = (CSSM_SIZE)((data) ? CFDataGetLength(data) : 0);
253 }
254 if (data) {
255 // stash this in a place where it will be released when the policy is destroyed
256 if (policyRef) {
257 SecPolicySetOptionsValue(policyRef, CFSTR("policy_data"), data);
258 }
259 else {
260 syslog(LOG_ERR, "WARNING: policy dictionary not found to store returned data; will leak!");
261 }
262 }
263 CFReleaseNull(data);
264 return true;
265 }
266
267 /* OS X only: __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2, __MAC_10_7, __IPHONE_NA, __IPHONE_NA) */
268 OSStatus
269 SecPolicyGetValue(SecPolicyRef policyRef, CSSM_DATA* value)
270 {
271 /* bridge to support old functionality */
272 #if SECTRUST_DEPRECATION_WARNINGS
273 syslog(LOG_ERR, "WARNING: SecPolicyGetValue was deprecated in 10.7. Please use SecPolicyCopyProperties instead.");
274 #endif
275 if (!(policyRef && value)) {
276 return errSecParam;
277 }
278 CFDictionaryRef options = SecPolicyGetOptions(policyRef);
279 if (!(options && (CFDictionaryGetTypeID() == CFGetTypeID(options)))) {
280 return errSecParam;
281 }
282 CFTypeRef name = NULL;
283 do {
284 if (CFDictionaryGetValueIfPresent(options, CFSTR("SSLHostname") /*kSecPolicyCheckSSLHostname*/,
285 (const void **)&name) && name) {
286 break;
287 }
288 if (CFDictionaryGetValueIfPresent(options, CFSTR("EAPTrustedServerNames") /*kSecPolicyCheckEAPTrustedServerNames*/,
289 (const void **)&name) && name) {
290 break;
291 }
292 if (CFDictionaryGetValueIfPresent(options, CFSTR("Email") /*kSecPolicyCheckEmail*/,
293 (const void **)&name) && name) {
294 break;
295 }
296 } while (0);
297 if (name) {
298 CFTypeID typeID = CFGetTypeID(name);
299 if (CFArrayGetTypeID() == typeID) {
300 name = (CFStringRef) CFArrayGetValueAtIndex((CFArrayRef)name, 0);
301 }
302 SecPolicyGetCSSMDataValueForString(policyRef, (CFStringRef)name, value);
303 }
304 else {
305 value->Data = NULL;
306 value->Length = 0;
307 }
308 return errSecSuccess;
309 }
310
311 /* OS X only: __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2, __MAC_10_7, __IPHONE_NA, __IPHONE_NA) */
312 OSStatus
313 SecPolicySetValue(SecPolicyRef policyRef, const CSSM_DATA *value)
314 {
315 /* bridge to support old functionality */
316 #if SECTRUST_DEPRECATION_WARNINGS
317 syslog(LOG_ERR, "WARNING: SecPolicySetValue was deprecated in 10.7. Please use SecPolicySetProperties instead.");
318 #endif
319 if (!(policyRef && value)) {
320 return errSecParam;
321 }
322 OSStatus status = errSecSuccess;
323 CFDataRef data = NULL;
324 CFStringRef name = NULL;
325 CFStringRef oid = (CFStringRef) SecPolicyGetOidString(policyRef);
326 if (!oid) {
327 syslog(LOG_ERR, "SecPolicySetValue: unknown policy OID");
328 return errSecParam; // bad policy ref?
329 }
330 if (CFEqual(oid, CFSTR("sslServer") /*kSecPolicyOIDSSLServer*/) ||
331 CFEqual(oid, CFSTR("sslClient") /*kSecPolicyOIDSSLClient*/) ||
332 CFEqual(oid, CFSTR("ipsecServer") /*kSecPolicyOIDIPSecServer*/) ||
333 CFEqual(oid, CFSTR("ipsecClient") /*kSecPolicyOIDIPSecClient*/) ||
334 CFEqual(oid, kSecPolicyAppleSSL) ||
335 CFEqual(oid, kSecPolicyAppleIPsec) ||
336 CFEqual(oid, kSecPolicyAppleIDValidation)
337 ) {
338 CSSM_APPLE_TP_SSL_OPTIONS *opts = (CSSM_APPLE_TP_SSL_OPTIONS *)value->Data;
339 if (opts->Version == CSSM_APPLE_TP_SSL_OPTS_VERSION) {
340 if (opts->ServerNameLen > 0) {
341 data = CFDataCreate(NULL, (const UInt8 *)opts->ServerName, opts->ServerNameLen);
342 name = (data) ? CFStringCreateFromExternalRepresentation(NULL, data, kCFStringEncodingUTF8) : NULL;
343 }
344 }
345 if (name) {
346 SecPolicySetOptionsValue(policyRef, CFSTR("SSLHostname") /*kSecPolicyCheckSSLHostname*/, name);
347 }
348 else {
349 status = errSecParam;
350 }
351 }
352 else if (CFEqual(oid, CFSTR("eapServer") /*kSecPolicyOIDEAPServer*/) ||
353 CFEqual(oid, CFSTR("eapClient") /*kSecPolicyOIDEAPClient*/) ||
354 CFEqual(oid, kSecPolicyAppleEAP)
355 ) {
356 CSSM_APPLE_TP_SSL_OPTIONS *opts = (CSSM_APPLE_TP_SSL_OPTIONS *)value->Data;
357 if (opts->Version == CSSM_APPLE_TP_SSL_OPTS_VERSION) {
358 if (opts->ServerNameLen > 0) {
359 data = CFDataCreate(NULL, (const UInt8 *)opts->ServerName, opts->ServerNameLen);
360 name = (data) ? CFStringCreateFromExternalRepresentation(NULL, data, kCFStringEncodingUTF8) : NULL;
361 }
362 }
363 if (name) {
364 SecPolicySetOptionsValue(policyRef, CFSTR("EAPTrustedServerNames") /*kSecPolicyCheckEAPTrustedServerNames*/, name);
365 }
366 else {
367 status = errSecParam;
368 }
369 }
370 else if (CFEqual(oid, CFSTR("SMIME") /*kSecPolicyOIDSMIME*/) ||
371 CFEqual(oid, CFSTR("AppleShoebox") /*kSecPolicyOIDAppleShoebox*/) ||
372 CFEqual(oid, CFSTR("ApplePassbook") /*kSecPolicyOIDApplePassbook*/) ||
373 CFEqual(oid, kSecPolicyAppleSMIME) ||
374 CFEqual(oid, kSecPolicyApplePassbookSigning)
375 ) {
376 CSSM_APPLE_TP_SMIME_OPTIONS *opts = (CSSM_APPLE_TP_SMIME_OPTIONS *)value->Data;
377 if (opts->Version == CSSM_APPLE_TP_SMIME_OPTS_VERSION) {
378 if (opts->SenderEmailLen > 0) {
379 data = CFDataCreate(NULL, (const UInt8 *)opts->SenderEmail, opts->SenderEmailLen);
380 name = (data) ? CFStringCreateFromExternalRepresentation(NULL, data, kCFStringEncodingUTF8) : NULL;
381 }
382 }
383 if (name) {
384 SecPolicySetOptionsValue(policyRef, CFSTR("email") /*kSecPolicyCheckEmail*/, name);
385 }
386 else {
387 status = errSecParam;
388 }
389 }
390 else if (CFEqual(oid, CFSTR("revocation") /* kSecPolicyOIDRevocation */) ||
391 CFEqual(oid, kSecPolicyAppleRevocation)
392 ) {
393 CSSM_APPLE_TP_CRL_OPTIONS *opts = (CSSM_APPLE_TP_CRL_OPTIONS *)value->Data;
394 if (opts->Version == CSSM_APPLE_TP_CRL_OPTS_VERSION) {
395 CSSM_APPLE_TP_CRL_OPT_FLAGS crlFlags = opts->CrlFlags;
396 if ((crlFlags & CSSM_TP_ACTION_FETCH_CRL_FROM_NET) == 0) {
397 /* disable network access */
398 SecPolicySetOptionsValue(policyRef, CFSTR("NoNetworkAccess") /*kSecPolicyCheckNoNetworkAccess*/, kCFBooleanTrue);
399 }
400 if ((crlFlags & CSSM_TP_ACTION_CRL_SUFFICIENT) == 0) {
401 /* if CRL method is not sufficient, must use OCSP */
402 SecPolicySetOptionsValue(policyRef, CFSTR("Revocation") /*kSecPolicyCheckRevocation*/,
403 CFSTR("OCSP")/*kSecPolicyCheckRevocationOCSP*/);
404 } else {
405 /* either method is sufficient */
406 SecPolicySetOptionsValue(policyRef, CFSTR("Revocation") /*kSecPolicyCheckRevocation*/,
407 CFSTR("AnyRevocationMethod") /*kSecPolicyCheckRevocationAny*/);
408 }
409
410 if ((crlFlags & CSSM_TP_ACTION_REQUIRE_CRL_PER_CERT) != 0) {
411 /* require a response */
412 SecPolicySetOptionsValue(policyRef,
413 CFSTR("RevocationResponseRequired") /*kSecPolicyCheckRevocationResponseRequired*/,
414 kCFBooleanTrue);
415 }
416 }
417 }
418 else {
419 syslog(LOG_ERR, "SecPolicySetValue: unrecognized policy OID");
420 status = errSecParam;
421 }
422 if (data) { CFRelease(data); }
423 if (name) { CFRelease(name); }
424 return status;
425 }
426
427 /* OS X only: __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2, __MAC_10_7, __IPHONE_NA, __IPHONE_NA) */
428 OSStatus
429 SecPolicyGetTPHandle(SecPolicyRef policyRef, CSSM_TP_HANDLE* tpHandle)
430 {
431 /* this function is unsupported in unified SecTrust */
432 #if SECTRUST_DEPRECATION_WARNINGS
433 syslog(LOG_ERR, "WARNING: SecPolicyGetTPHandle was deprecated in 10.7, and does nothing in 10.11. Please stop using it.");
434 #endif
435 return errSecServiceNotAvailable;
436 }
437
438 /* OS X only: __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_3, __MAC_10_7, __IPHONE_NA, __IPHONE_NA) */
439 OSStatus
440 SecPolicyCopy(CSSM_CERT_TYPE certificateType, const CSSM_OID *policyOID, SecPolicyRef* policy)
441 {
442 if (!policyOID || !policy) {
443 return errSecParam;
444 }
445
446 SecPolicySearchRef srchRef = NULL;
447 OSStatus ortn;
448
449 ortn = SecPolicySearchCreate(certificateType, policyOID, NULL, &srchRef);
450 if(ortn) {
451 return ortn;
452 }
453 ortn = SecPolicySearchCopyNext(srchRef, policy);
454 CFRelease(srchRef);
455 return ortn;
456 }
457
458 /* OS X only: convert a new-world SecPolicyRef to an old-world ItemImpl instance */
459 SecPolicyRef
460 SecPolicyCreateItemImplInstance(SecPolicyRef policy)
461 {
462 if (!policy) {
463 return NULL;
464 }
465 CSSM_OID oid;
466 OSStatus status = SecPolicyGetOID(policy, &oid);
467 if (status) {
468 return NULL;
469 }
470 SecPolicyRef policyRef = NULL;
471 CFDictionaryRef properties = SecPolicyCopyProperties(policy);
472 try {
473 SecPointer<Policy> policyObj;
474 PolicyCursor::policy(&oid, policyObj);
475 policyRef = policyObj->handle();
476 Policy::required(policyRef)->setProperties(properties);
477 }
478 catch (...) {
479 policyRef = NULL;
480 }
481 if (properties) {
482 CFRelease(properties);
483 }
484 return policyRef;
485 }
486
487 static SecPolicyRef
488 _SecPolicyCreateWithOID(CFTypeRef policyOID)
489 {
490 // for now, we only accept the policy constants that are defined in SecPolicy.h
491 CFStringRef oidStr = (CFStringRef)policyOID;
492 CSSM_OID *oidPtr = NULL;
493 SecPolicyRef policy = NULL;
494 if (!oidStr) {
495 return policy;
496 }
497 unsigned int i;
498 for (i=0; i<OIDMAP_LENGTH; i++) {
499 CFStringRef str = (CFStringRef) oidmap_f()[i].oidstr;
500 if (CFStringCompare(str, oidStr, 0) == kCFCompareEqualTo) {
501 oidPtr = (CSSM_OID*)oidmap_f()[i].oidptr;
502 break;
503 }
504 }
505 if (CFEqual(oidStr, kSecPolicyAppleServerAuthentication)) {
506 return SecPolicyCreateAppleSSLService(NULL);
507 }
508 if (oidPtr) {
509 SecPolicySearchRef policySearch = NULL;
510 OSStatus status = SecPolicySearchCreate(CSSM_CERT_X_509v3, oidPtr, NULL, &policySearch);
511 if (!status && policySearch) {
512 status = SecPolicySearchCopyNext(policySearch, &policy);
513 if (status != errSecSuccess) {
514 policy = NULL;
515 }
516 CFRelease(policySearch);
517 }
518 if (!policy && CFEqual(policyOID, kSecPolicyAppleRevocation)) {
519 policy = SecPolicyCreateRevocation(kSecRevocationUseAnyAvailableMethod);
520 }
521 }
522 return policy;
523 }
524
525 /* OS X only: __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_7, __MAC_10_9, __IPHONE_NA, __IPHONE_NA) */
526 SecPolicyRef
527 SecPolicyCreateWithOID(CFTypeRef policyOID)
528 {
529 SecPolicyRef policy = _SecPolicyCreateWithOID(policyOID);
530 if (!policy) {
531 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.");
532 }
533 return policy;
534 }
535
536 /* OS X only: TBD */
537 #include <security_utilities/cfutilities.h>
538 /* New in 10.10 */
539 // Takes the "context" policies to extract the revocation and apply it to timeStamp.
540 CFArrayRef
541 SecPolicyCreateAppleTimeStampingAndRevocationPolicies(CFTypeRef policyOrArray)
542 {
543 CFMutableArrayRef resultPolicyArray = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
544 if (!resultPolicyArray) {
545 return NULL;
546 }
547 SecPolicyRef tsPolicy = SecPolicyCreateWithProperties(kSecPolicyAppleTimeStamping, NULL);
548 if (tsPolicy) {
549 CFArrayAppendValue(resultPolicyArray, tsPolicy);
550 CFReleaseNull(tsPolicy);
551 }
552
553 /* check the provided argument for a revocation policy */
554 CFMutableArrayRef policies = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
555 if (policies && policyOrArray) {
556 if (CFGetTypeID(policyOrArray) == SecPolicyGetTypeID()) {
557 CFArrayAppendValue(policies, policyOrArray);
558 } else if (CFGetTypeID(policyOrArray) == CFArrayGetTypeID()) {
559 CFIndex arrayLength = CFArrayGetCount((CFArrayRef)policyOrArray);
560 CFArrayAppendArray(policies, (CFArrayRef)policyOrArray, CFRangeMake(0, arrayLength));
561 }
562 }
563 CFIndex numPolicies = (policies) ? CFArrayGetCount(policies) : 0;
564 for (CFIndex index=0; index<numPolicies; index++) {
565 SecPolicyRef policy = (SecPolicyRef)CFArrayGetValueAtIndex(policies, index);
566 CFStringRef policyName = (policy) ? SecPolicyGetName(policy) : NULL;
567 if (policyName && CFEqual(CFSTR("revocation"), policyName)) {
568 CFArrayAppendValue(resultPolicyArray, policy);
569 }
570 }
571 CFReleaseNull(policies);
572 return resultPolicyArray;
573 }
574