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