]> git.saurik.com Git - apple/security.git/blob - OSX/libsecurity_keychain/lib/SecPolicy.cpp
Security-57336.1.9.tar.gz
[apple/security.git] / OSX / libsecurity_keychain / lib / SecPolicy.cpp
1 /*
2 * Copyright (c) 2002-2015 Apple Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
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
11 * file.
12 *
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.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
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"
36 #include <syslog.h>
37
38
39 // String constant declarations
40
41 #define SEC_CONST_DECL(k,v) const CFStringRef k = CFSTR(v);
42
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");
64 #if TARGET_OS_IPHONE
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");
71 #endif
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
79 SEC_CONST_DECL (kSecPolicyOid, "SecPolicyOid");
80 SEC_CONST_DECL (kSecPolicyName, "SecPolicyName");
81 SEC_CONST_DECL (kSecPolicyClient, "SecPolicyClient");
82 SEC_CONST_DECL (kSecPolicyRevocationFlags, "SecPolicyRevocationFlags");
83 SEC_CONST_DECL (kSecPolicyTeamIdentifier, "SecPolicyTeamIdentifier");
84
85 SEC_CONST_DECL (kSecPolicyKU_DigitalSignature, "CE_KU_DigitalSignature");
86 SEC_CONST_DECL (kSecPolicyKU_NonRepudiation, "CE_KU_NonRepudiation");
87 SEC_CONST_DECL (kSecPolicyKU_KeyEncipherment, "CE_KU_KeyEncipherment");
88 SEC_CONST_DECL (kSecPolicyKU_DataEncipherment, "CE_KU_DataEncipherment");
89 SEC_CONST_DECL (kSecPolicyKU_KeyAgreement, "CE_KU_KeyAgreement");
90 SEC_CONST_DECL (kSecPolicyKU_KeyCertSign, "CE_KU_KeyCertSign");
91 SEC_CONST_DECL (kSecPolicyKU_CRLSign, "CE_KU_CRLSign");
92 SEC_CONST_DECL (kSecPolicyKU_EncipherOnly, "CE_KU_EncipherOnly");
93 SEC_CONST_DECL (kSecPolicyKU_DecipherOnly, "CE_KU_DecipherOnly");
94
95 // Private functions
96
97 extern "C" {
98 CFArrayRef SecPolicyCopyEscrowRootCertificates(void);
99 #if SECTRUST_OSX
100 CFStringRef SecPolicyGetOidString(SecPolicyRef policy);
101 CFDictionaryRef SecPolicyGetOptions(SecPolicyRef policy);
102 void SecPolicySetOptionsValue(SecPolicyRef policy, CFStringRef key, CFTypeRef value);
103 #endif
104 }
105
106 // String to CSSM_OID mapping
107
108 struct oidmap_entry_s {
109 const CFTypeRef oidstr;
110 const SecAsn1Oid *oidptr;
111 };
112 typedef struct oidmap_entry_s oidmap_entry_t;
113
114 // policies enumerated by SecPolicySearch (PolicyCursor.cpp)
115 /*
116 static_cast<const CssmOid *>(&CSSMOID_APPLE_ISIGN), // no longer supported
117 static_cast<const CssmOid *>(&CSSMOID_APPLE_X509_BASIC),
118 static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_SSL),
119 static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_SMIME),
120 static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_EAP),
121 static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_SW_UPDATE_SIGNING),
122 static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_IP_SEC),
123 static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_ICHAT), // no longer supported
124 static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_RESOURCE_SIGN),
125 static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_PKINIT_CLIENT),
126 static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_PKINIT_SERVER),
127 static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_CODE_SIGNING),
128 static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_PACKAGE_SIGNING),
129 static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_REVOCATION_CRL),
130 static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_REVOCATION_OCSP),
131 static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_MACAPPSTORE_RECEIPT),
132 static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_APPLEID_SHARING),
133 static_cast<const CssmOid *>(&CSSMOID_APPLE_TP_TIMESTAMPING),
134 */
135 const oidmap_entry_t oidmap[] = {
136 { kSecPolicyAppleX509Basic, &CSSMOID_APPLE_X509_BASIC },
137 { kSecPolicyAppleSSL, &CSSMOID_APPLE_TP_SSL },
138 { kSecPolicyAppleSMIME, &CSSMOID_APPLE_TP_SMIME },
139 { kSecPolicyAppleEAP, &CSSMOID_APPLE_TP_EAP },
140 { kSecPolicyAppleSWUpdateSigning, &CSSMOID_APPLE_TP_SW_UPDATE_SIGNING },
141 { kSecPolicyAppleIPsec, &CSSMOID_APPLE_TP_IP_SEC },
142 { kSecPolicyAppleiChat, &CSSMOID_APPLE_TP_ICHAT },
143 { kSecPolicyApplePKINITClient, &CSSMOID_APPLE_TP_PKINIT_CLIENT },
144 { kSecPolicyApplePKINITServer, &CSSMOID_APPLE_TP_PKINIT_SERVER },
145 { kSecPolicyAppleCodeSigning, &CSSMOID_APPLE_TP_CODE_SIGNING },
146 { kSecPolicyApplePackageSigning, &CSSMOID_APPLE_TP_PACKAGE_SIGNING },
147 { kSecPolicyAppleIDValidation, &CSSMOID_APPLE_TP_APPLEID_SHARING },
148 { kSecPolicyMacAppStoreReceipt, &CSSMOID_APPLE_TP_MACAPPSTORE_RECEIPT },
149 { kSecPolicyAppleTimeStamping, &CSSMOID_APPLE_TP_TIMESTAMPING },
150 { kSecPolicyAppleRevocation, &CSSMOID_APPLE_TP_REVOCATION },
151 { kSecPolicyAppleRevocation, &CSSMOID_APPLE_TP_REVOCATION_OCSP },
152 { kSecPolicyAppleRevocation, &CSSMOID_APPLE_TP_REVOCATION_CRL },
153 { kSecPolicyApplePassbookSigning, &CSSMOID_APPLE_TP_PASSBOOK_SIGNING },
154 { kSecPolicyAppleMobileStore, &CSSMOID_APPLE_TP_MOBILE_STORE },
155 { kSecPolicyAppleEscrowService, &CSSMOID_APPLE_TP_ESCROW_SERVICE },
156 { kSecPolicyAppleProfileSigner, &CSSMOID_APPLE_TP_PROFILE_SIGNING },
157 { kSecPolicyAppleQAProfileSigner, &CSSMOID_APPLE_TP_QA_PROFILE_SIGNING },
158 { kSecPolicyAppleTestMobileStore, &CSSMOID_APPLE_TP_TEST_MOBILE_STORE },
159 { kSecPolicyApplePCSEscrowService, &CSSMOID_APPLE_TP_PCS_ESCROW_SERVICE },
160 };
161
162 // TBD: have only one set of policy identifiers in SecPolicy.c so we can get rid of this
163 const oidmap_entry_t oidmap_priv[] = {
164 { CFSTR("basicX509"), &CSSMOID_APPLE_X509_BASIC },
165 { CFSTR("sslServer"), &CSSMOID_APPLE_TP_SSL },
166 { CFSTR("sslClient"), &CSSMOID_APPLE_TP_SSL },
167 { CFSTR("SMIME"), &CSSMOID_APPLE_TP_SMIME },
168 { CFSTR("eapServer"), &CSSMOID_APPLE_TP_EAP },
169 { CFSTR("eapClient"), &CSSMOID_APPLE_TP_EAP },
170 { CFSTR("AppleSWUpdateSigning"), &CSSMOID_APPLE_TP_SW_UPDATE_SIGNING },
171 { CFSTR("ipsecServer"), &CSSMOID_APPLE_TP_IP_SEC },
172 { CFSTR("ipsecClient"), &CSSMOID_APPLE_TP_IP_SEC },
173 { CFSTR("CodeSigning"), &CSSMOID_APPLE_TP_CODE_SIGNING },
174 { CFSTR("PackageSigning"), &CSSMOID_APPLE_TP_PACKAGE_SIGNING },
175 { CFSTR("AppleIDAuthority"), &CSSMOID_APPLE_TP_APPLEID_SHARING },
176 { CFSTR("MacAppStoreReceipt"), &CSSMOID_APPLE_TP_MACAPPSTORE_RECEIPT },
177 { CFSTR("AppleTimeStamping"), &CSSMOID_APPLE_TP_TIMESTAMPING },
178 { CFSTR("revocation"), &CSSMOID_APPLE_TP_REVOCATION },
179 { CFSTR("ApplePassbook"), &CSSMOID_APPLE_TP_PASSBOOK_SIGNING },
180 { CFSTR("AppleMobileStore"), &CSSMOID_APPLE_TP_MOBILE_STORE },
181 { CFSTR("AppleEscrowService"), &CSSMOID_APPLE_TP_ESCROW_SERVICE },
182 { CFSTR("AppleProfileSigner"), &CSSMOID_APPLE_TP_PROFILE_SIGNING },
183 { CFSTR("AppleQAProfileSigner"), &CSSMOID_APPLE_TP_QA_PROFILE_SIGNING },
184 { CFSTR("AppleTestMobileStore"), &CSSMOID_APPLE_TP_TEST_MOBILE_STORE },
185 { CFSTR("ApplePCSEscrowService"), &CSSMOID_APPLE_TP_PCS_ESCROW_SERVICE },
186 };
187
188 //
189 // CF boilerplate
190 //
191 #if !SECTRUST_OSX
192 CFTypeID
193 SecPolicyGetTypeID(void)
194 {
195 BEGIN_SECAPI
196 return gTypes().Policy.typeID;
197 END_SECAPI1(_kCFRuntimeNotATypeID)
198 }
199 #endif
200
201 //
202 // Sec API bridge functions
203 //
204 /* OS X only: __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2, __MAC_10_7, __IPHONE_NA, __IPHONE_NA) */
205 OSStatus
206 SecPolicyGetOID(SecPolicyRef policyRef, CSSM_OID* oid)
207 {
208 #if !SECTRUST_OSX
209 BEGIN_SECAPI
210 Required(oid) = Policy::required(policyRef)->oid();
211 END_SECAPI
212 #else
213 /* bridge to support old functionality */
214 if (!policyRef) {
215 return errSecParam;
216 }
217 CFStringRef oidStr = (CFStringRef) SecPolicyGetOidString(policyRef);
218 if (!oidStr || !oid) {
219 return errSecParam; // bad policy ref?
220 }
221 CSSM_OID *oidptr = NULL;
222 unsigned int i, oidmaplen = sizeof(oidmap) / sizeof(oidmap_entry_t);
223 for (i=0; i<oidmaplen; i++) {
224 CFStringRef str = (CFStringRef) oidmap[i].oidstr;
225 if (CFStringCompare(str, oidStr, 0) == kCFCompareEqualTo) {
226 oidptr = (CSSM_OID*)oidmap[i].oidptr;
227 break;
228 }
229 }
230 if (!oidptr) {
231 // Check private iOS policy names.
232 oidmaplen = sizeof(oidmap_priv) / sizeof(oidmap_entry_t);
233 for (i=0; i<oidmaplen; i++) {
234 CFStringRef str = (CFStringRef) oidmap_priv[i].oidstr;
235 if (CFStringCompare(str, oidStr, 0) == kCFCompareEqualTo) {
236 oidptr = (CSSM_OID*)oidmap_priv[i].oidptr;
237 break;
238 }
239 }
240 }
241 if (oidptr) {
242 oid->Data = oidptr->Data;
243 oid->Length = oidptr->Length;
244 return errSecSuccess;
245 }
246 CFShow(oidStr);
247 syslog(LOG_ERR, "WARNING: SecPolicyGetOID failed to return an OID. This function was deprecated in 10.7. Please use SecPolicyCopyProperties instead.");
248 return errSecServiceNotAvailable;
249 #endif
250 }
251
252 // TODO: use a version of this function from a utility library
253 static CSSM_BOOL compareOids(
254 const CSSM_OID *oid1,
255 const CSSM_OID *oid2)
256 {
257 if((oid1 == NULL) || (oid2 == NULL)) {
258 return CSSM_FALSE;
259 }
260 if(oid1->Length != oid2->Length) {
261 return CSSM_FALSE;
262 }
263 if(memcmp(oid1->Data, oid2->Data, oid1->Length)) {
264 return CSSM_FALSE;
265 }
266 else {
267 return CSSM_TRUE;
268 }
269 }
270
271 /* OS X only: */
272 CFStringRef SecPolicyGetStringForOID(CSSM_OID* oid)
273 {
274 if (!oid) {
275 return NULL;
276 }
277 // given a CSSM_OID pointer, return corresponding string in oidmap
278 unsigned int i, oidmaplen = sizeof(oidmap) / sizeof(oidmap_entry_t);
279 for (i=0; i<oidmaplen; i++) {
280 CSSM_OID* oidptr = (CSSM_OID*)oidmap[i].oidptr;
281 if (compareOids(oid, oidptr)) {
282 return (CFStringRef) oidmap[i].oidstr;
283 }
284 }
285 return NULL;
286 }
287
288 #if SECTRUST_OSX
289 static bool SecPolicyGetCSSMDataValueForString(SecPolicyRef policyRef, CFStringRef stringRef, CSSM_DATA* value)
290 {
291 // Old API expects to vend a pointer and length for a policy value.
292 // The API contract says this pointer is good for the life of the policy.
293 // However, the new policy values are CF objects, and we need a separate
294 // buffer to get their UTF8 bytes. This buffer needs to be released when
295 // the policy object is released.
296
297 CFDataRef data = NULL;
298 CFIndex maxLength = CFStringGetMaximumSizeForEncoding(CFStringGetLength(stringRef), kCFStringEncodingUTF8) + 1;
299 char* buf = (char*) malloc(maxLength);
300 if (!buf) {
301 return false;
302 }
303 if (CFStringGetCString(stringRef, buf, (CFIndex)maxLength, kCFStringEncodingUTF8)) {
304 CFIndex length = strlen(buf);
305 data = CFDataCreate(NULL, (const UInt8 *)buf, length);
306 }
307 free(buf);
308 if (value) {
309 value->Data = (uint8*)((data) ? CFDataGetBytePtr(data) : NULL);
310 value->Length = (CSSM_SIZE)((data) ? CFDataGetLength(data) : 0);
311 }
312 if (data) {
313 // stash this in a place where it will be released when the policy is destroyed
314 if (policyRef) {
315 SecPolicySetOptionsValue(policyRef, CFSTR("policy_data"), data);
316 CFRelease(data);
317 }
318 else {
319 syslog(LOG_ERR, "WARNING: policy dictionary not found to store returned data; will leak!");
320 }
321 }
322 return true;
323 }
324 #endif
325
326 /* OS X only: __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2, __MAC_10_7, __IPHONE_NA, __IPHONE_NA) */
327 OSStatus
328 SecPolicyGetValue(SecPolicyRef policyRef, CSSM_DATA* value)
329 {
330 #if !SECTRUST_OSX
331 BEGIN_SECAPI
332 Required(value) = Policy::required(policyRef)->value();
333 END_SECAPI
334 #else
335 /* bridge to support old functionality */
336 #if SECTRUST_DEPRECATION_WARNINGS
337 syslog(LOG_ERR, "WARNING: SecPolicyGetValue was deprecated in 10.7. Please use SecPolicyCopyProperties instead.");
338 #endif
339 if (!(policyRef && value)) {
340 return errSecParam;
341 }
342 CFDictionaryRef options = SecPolicyGetOptions(policyRef);
343 if (!(options && (CFDictionaryGetTypeID() == CFGetTypeID(options)))) {
344 return errSecParam;
345 }
346 CFTypeRef name = NULL;
347 do {
348 if (CFDictionaryGetValueIfPresent(options, CFSTR("SSLHostname") /*kSecPolicyCheckSSLHostname*/,
349 (const void **)&name) && name) {
350 break;
351 }
352 if (CFDictionaryGetValueIfPresent(options, CFSTR("EAPTrustedServerNames") /*kSecPolicyCheckEAPTrustedServerNames*/,
353 (const void **)&name) && name) {
354 break;
355 }
356 if (CFDictionaryGetValueIfPresent(options, CFSTR("email") /*kSecPolicyCheckEmail*/,
357 (const void **)&name) && name) {
358 break;
359 }
360 } while (0);
361 if (name) {
362 CFTypeID typeID = CFGetTypeID(name);
363 if (CFArrayGetTypeID() == typeID) {
364 name = (CFStringRef) CFArrayGetValueAtIndex((CFArrayRef)name, 0);
365 }
366 SecPolicyGetCSSMDataValueForString(policyRef, (CFStringRef)name, value);
367 }
368 else {
369 value->Data = NULL;
370 value->Length = 0;
371 }
372 return errSecSuccess;
373 #endif
374 }
375
376 #if !SECTRUST_OSX
377 CFDictionaryRef
378 SecPolicyCopyProperties(SecPolicyRef policyRef)
379 {
380 /* can't use SECAPI macros, since this function does not return OSStatus */
381 CFDictionaryRef result = NULL;
382 try {
383 result = Policy::required(policyRef)->properties();
384 }
385 catch (...) {
386 if (result) {
387 CFRelease(result);
388 result = NULL;
389 }
390 };
391 return result;
392 }
393 #endif
394
395 /* OS X only: __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2, __MAC_10_7, __IPHONE_NA, __IPHONE_NA) */
396 OSStatus
397 SecPolicySetValue(SecPolicyRef policyRef, const CSSM_DATA *value)
398 {
399 #if !SECTRUST_OSX
400 BEGIN_SECAPI
401 Required(value);
402 const CssmData newValue(value->Data, value->Length);
403 Policy::required(policyRef)->setValue(newValue);
404 END_SECAPI
405 #else
406 /* bridge to support old functionality */
407 #if SECTRUST_DEPRECATION_WARNINGS
408 syslog(LOG_ERR, "WARNING: SecPolicySetValue was deprecated in 10.7. Please use SecPolicySetProperties instead.");
409 #endif
410 if (!(policyRef && value)) {
411 return errSecParam;
412 }
413 OSStatus status = errSecSuccess;
414 CFDataRef data = NULL;
415 CFStringRef name = NULL;
416 CFNumberRef cnum = NULL;
417 CFStringRef oid = (CFStringRef) SecPolicyGetOidString(policyRef);
418 if (!oid) {
419 syslog(LOG_ERR, "SecPolicySetValue: unknown policy OID");
420 return errSecParam; // bad policy ref?
421 }
422 if (CFEqual(oid, CFSTR("sslServer") /*kSecPolicyOIDSSLServer*/) ||
423 CFEqual(oid, CFSTR("sslClient") /*kSecPolicyOIDSSLClient*/) ||
424 CFEqual(oid, CFSTR("ipsecServer") /*kSecPolicyOIDIPSecServer*/) ||
425 CFEqual(oid, CFSTR("ipsecClient") /*kSecPolicyOIDIPSecClient*/) ||
426 CFEqual(oid, kSecPolicyAppleSSL) ||
427 CFEqual(oid, kSecPolicyAppleIPsec) ||
428 CFEqual(oid, kSecPolicyAppleIDValidation)
429 ) {
430 CSSM_APPLE_TP_SSL_OPTIONS *opts = (CSSM_APPLE_TP_SSL_OPTIONS *)value->Data;
431 if (opts->Version == CSSM_APPLE_TP_SSL_OPTS_VERSION) {
432 if (opts->ServerNameLen > 0) {
433 data = CFDataCreate(NULL, (const UInt8 *)opts->ServerName, opts->ServerNameLen);
434 name = (data) ? CFStringCreateFromExternalRepresentation(NULL, data, kCFStringEncodingUTF8) : NULL;
435 }
436 }
437 if (name) {
438 SecPolicySetOptionsValue(policyRef, CFSTR("SSLHostname") /*kSecPolicyCheckSSLHostname*/, name);
439 }
440 else {
441 status = errSecParam;
442 }
443 }
444 else if (CFEqual(oid, CFSTR("eapServer") /*kSecPolicyOIDEAPServer*/) ||
445 CFEqual(oid, CFSTR("eapClient") /*kSecPolicyOIDEAPClient*/) ||
446 CFEqual(oid, kSecPolicyAppleEAP)
447 ) {
448 CSSM_APPLE_TP_SSL_OPTIONS *opts = (CSSM_APPLE_TP_SSL_OPTIONS *)value->Data;
449 if (opts->Version == CSSM_APPLE_TP_SSL_OPTS_VERSION) {
450 if (opts->ServerNameLen > 0) {
451 data = CFDataCreate(NULL, (const UInt8 *)opts->ServerName, opts->ServerNameLen);
452 name = (data) ? CFStringCreateFromExternalRepresentation(NULL, data, kCFStringEncodingUTF8) : NULL;
453 }
454 }
455 if (name) {
456 SecPolicySetOptionsValue(policyRef, CFSTR("EAPTrustedServerNames") /*kSecPolicyCheckEAPTrustedServerNames*/, name);
457 }
458 else {
459 status = errSecParam;
460 }
461 }
462 else if (CFEqual(oid, CFSTR("SMIME") /*kSecPolicyOIDSMIME*/) ||
463 CFEqual(oid, CFSTR("AppleShoebox") /*kSecPolicyOIDAppleShoebox*/) ||
464 CFEqual(oid, CFSTR("ApplePassbook") /*kSecPolicyOIDApplePassbook*/) ||
465 CFEqual(oid, kSecPolicyAppleSMIME) ||
466 CFEqual(oid, kSecPolicyApplePassbookSigning)
467 ) {
468 CSSM_APPLE_TP_SMIME_OPTIONS *opts = (CSSM_APPLE_TP_SMIME_OPTIONS *)value->Data;
469 if (opts->Version == CSSM_APPLE_TP_SMIME_OPTS_VERSION) {
470 if (opts->SenderEmailLen > 0) {
471 data = CFDataCreate(NULL, (const UInt8 *)opts->SenderEmail, opts->SenderEmailLen);
472 name = (data) ? CFStringCreateFromExternalRepresentation(NULL, data, kCFStringEncodingUTF8) : NULL;
473 }
474 }
475 if (name) {
476 SecPolicySetOptionsValue(policyRef, CFSTR("email") /*kSecPolicyCheckEmail*/, name);
477 }
478 else {
479 status = errSecParam;
480 }
481 }
482 else if (CFEqual(oid, CFSTR("revocation") /* kSecPolicyOIDRevocation */) ||
483 CFEqual(oid, kSecPolicyAppleRevocation)
484 ) {
485 CSSM_APPLE_TP_CRL_OPTIONS *opts = (CSSM_APPLE_TP_CRL_OPTIONS *)value->Data;
486 if (opts->Version == CSSM_APPLE_TP_CRL_OPTS_VERSION) {
487 CSSM_APPLE_TP_CRL_OPT_FLAGS crlFlags = opts->CrlFlags;
488 CFOptionFlags revocationFlags = 0;
489 if ((crlFlags & CSSM_TP_ACTION_FETCH_CRL_FROM_NET) == 0) {
490 /* disable network access */
491 revocationFlags |= kSecRevocationNetworkAccessDisabled;
492 }
493 if ((crlFlags & CSSM_TP_ACTION_CRL_SUFFICIENT) == 0) {
494 /* if OCSP method is not sufficient, must use CRL */
495 revocationFlags |= (kSecRevocationCRLMethod | kSecRevocationPreferCRL);
496 } else {
497 /* either method is sufficient */
498 revocationFlags |= kSecRevocationUseAnyAvailableMethod;
499 }
500 if ((crlFlags & CSSM_TP_ACTION_REQUIRE_CRL_PER_CERT) != 0) {
501 /* require a response */
502 revocationFlags |= kSecRevocationRequirePositiveResponse;
503 }
504 cnum = CFNumberCreate(kCFAllocatorDefault, kCFNumberCFIndexType, &revocationFlags);
505 if (cnum) {
506 SecPolicySetOptionsValue(policyRef, kSecPolicyRevocationFlags, cnum);
507 }
508 }
509 }
510 else {
511 syslog(LOG_ERR, "SecPolicySetValue: unrecognized policy OID");
512 status = errSecParam;
513 }
514 if (data) { CFRelease(data); }
515 if (name) { CFRelease(name); }
516 if (cnum) { CFRelease(cnum); }
517 return status;
518 #endif
519 }
520
521 #if !SECTRUST_OSX
522 OSStatus
523 SecPolicySetProperties(SecPolicyRef policyRef, CFDictionaryRef properties)
524 {
525 BEGIN_SECAPI
526 Policy::required(policyRef)->setProperties(properties);
527 END_SECAPI
528 }
529 #endif
530
531 /* OS X only: __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2, __MAC_10_7, __IPHONE_NA, __IPHONE_NA) */
532 OSStatus
533 SecPolicyGetTPHandle(SecPolicyRef policyRef, CSSM_TP_HANDLE* tpHandle)
534 {
535 #if !SECTRUST_OSX
536 BEGIN_SECAPI
537 Required(tpHandle) = Policy::required(policyRef)->tp()->handle();
538 END_SECAPI
539 #else
540 /* this function is unsupported in unified SecTrust */
541 #if SECTRUST_DEPRECATION_WARNINGS
542 syslog(LOG_ERR, "WARNING: SecPolicyGetTPHandle was deprecated in 10.7, and does nothing in 10.11. Please stop using it.");
543 #endif
544 return errSecServiceNotAvailable;
545 #endif
546 }
547
548 /* OS X only: __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_3, __MAC_10_7, __IPHONE_NA, __IPHONE_NA) */
549 OSStatus
550 SecPolicyCopyAll(CSSM_CERT_TYPE certificateType, CFArrayRef* policies)
551 {
552 #if !SECTRUST_OSX
553 BEGIN_SECAPI
554 Required(policies);
555 CFMutableArrayRef currPolicies = NULL;
556 currPolicies = CFArrayCreateMutable(NULL, 0, NULL);
557 if ( currPolicies )
558 {
559 SecPointer<PolicyCursor> cursor(new PolicyCursor(NULL, NULL));
560 SecPointer<Policy> policy;
561 while ( cursor->next(policy) ) /* copies the next policy */
562 {
563 CFArrayAppendValue(currPolicies, policy->handle()); /* 'SecPolicyRef' appended */
564 CFRelease(policy->handle()); /* refcount bumped up when appended to array */
565 }
566 *policies = CFArrayCreateCopy(NULL, currPolicies);
567 CFRelease(currPolicies);
568 CFRelease(cursor->handle());
569 }
570 END_SECAPI
571 #else
572 /* bridge to support old functionality */
573 #if SECTRUST_DEPRECATION_WARNINGS
574 syslog(LOG_ERR, "WARNING: SecPolicyCopyAll was deprecated in 10.7. Please use SecPolicy creation functions instead.");
575 #endif
576 if (!policies) {
577 return errSecParam;
578 }
579 CFMutableArrayRef curPolicies = CFArrayCreateMutable(NULL, 0, NULL);
580 if (!curPolicies) {
581 return errSecAllocate;
582 }
583 /* build the subset of policies which were supported on OS X,
584 and which are also implemented on iOS */
585 CFStringRef supportedPolicies[] = {
586 kSecPolicyAppleX509Basic, /* CSSMOID_APPLE_X509_BASIC */
587 kSecPolicyAppleSSL, /* CSSMOID_APPLE_TP_SSL */
588 kSecPolicyAppleSMIME, /* CSSMOID_APPLE_TP_SMIME */
589 kSecPolicyAppleEAP, /*CSSMOID_APPLE_TP_EAP */
590 kSecPolicyAppleSWUpdateSigning, /* CSSMOID_APPLE_TP_SW_UPDATE_SIGNING */
591 kSecPolicyAppleIPsec, /* CSSMOID_APPLE_TP_IP_SEC */
592 kSecPolicyAppleCodeSigning, /* CSSMOID_APPLE_TP_CODE_SIGNING */
593 kSecPolicyMacAppStoreReceipt, /* CSSMOID_APPLE_TP_MACAPPSTORE_RECEIPT */
594 kSecPolicyAppleIDValidation, /* CSSMOID_APPLE_TP_APPLEID_SHARING */
595 kSecPolicyAppleTimeStamping, /* CSSMOID_APPLE_TP_TIMESTAMPING */
596 kSecPolicyAppleRevocation, /* CSSMOID_APPLE_TP_REVOCATION_{CRL,OCSP} */
597 NULL
598 };
599 CFIndex ix = 0;
600 while (true) {
601 CFStringRef policyID = supportedPolicies[ix++];
602 if (!policyID) {
603 break;
604 }
605 SecPolicyRef curPolicy = SecPolicyCreateWithProperties(policyID, NULL);
606 if (curPolicy) {
607 CFArrayAppendValue(curPolicies, curPolicy);
608 CFRelease(curPolicy);
609 }
610 }
611 *policies = CFArrayCreateCopy(NULL, curPolicies);
612 CFRelease(curPolicies);
613 return errSecSuccess;
614 #endif
615 }
616
617 /* OS X only: __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_3, __MAC_10_7, __IPHONE_NA, __IPHONE_NA) */
618 OSStatus
619 SecPolicyCopy(CSSM_CERT_TYPE certificateType, const CSSM_OID *policyOID, SecPolicyRef* policy)
620 {
621 #if !SECTRUST_OSX
622 Required(policy);
623 Required(policyOID);
624 #else
625 if (!policyOID || !policy) {
626 return errSecParam;
627 }
628 #endif
629 SecPolicySearchRef srchRef = NULL;
630 OSStatus ortn;
631
632 ortn = SecPolicySearchCreate(certificateType, policyOID, NULL, &srchRef);
633 if(ortn) {
634 return ortn;
635 }
636 ortn = SecPolicySearchCopyNext(srchRef, policy);
637 CFRelease(srchRef);
638 return ortn;
639 }
640
641 /* OS X only: convert a new-world SecPolicyRef to an old-world ItemImpl instance */
642 SecPolicyRef
643 SecPolicyCreateItemImplInstance(SecPolicyRef policy)
644 {
645 #if !SECTRUST_OSX
646 return (SecPolicyRef)(policy ? CFRetain(policy) : NULL);
647 #else
648 if (!policy) {
649 return NULL;
650 }
651 CSSM_OID oid;
652 OSStatus status = SecPolicyGetOID(policy, &oid);
653 if (status) {
654 return NULL;
655 }
656 SecPolicyRef policyRef = NULL;
657 CFDictionaryRef properties = SecPolicyCopyProperties(policy);
658 try {
659 SecPointer<Policy> policyObj;
660 PolicyCursor::policy(&oid, policyObj);
661 policyRef = policyObj->handle();
662 Policy::required(policyRef)->setProperties(properties);
663 }
664 catch (...) {
665 policyRef = NULL;
666 }
667 if (properties) {
668 CFRelease(properties);
669 }
670 return policyRef;
671 #endif
672 }
673
674 #if !SECTRUST_OSX
675 /* new in 10.6 */
676 SecPolicyRef
677 SecPolicyCreateBasicX509(void)
678 {
679 // return a SecPolicyRef object for the X.509 Basic policy
680 SecPolicyRef policy = nil;
681 SecPolicySearchRef policySearch = nil;
682 OSStatus status = SecPolicySearchCreate(CSSM_CERT_X_509v3, &CSSMOID_APPLE_X509_BASIC, NULL, &policySearch);
683 if (!status) {
684 status = SecPolicySearchCopyNext(policySearch, &policy);
685 }
686 if (policySearch) {
687 CFRelease(policySearch);
688 }
689 return policy;
690 }
691 #endif
692
693 #if !SECTRUST_OSX
694 /* new in 10.6 */
695 SecPolicyRef
696 SecPolicyCreateSSL(Boolean server, CFStringRef hostname)
697 {
698 // return a SecPolicyRef object for the SSL policy, given hostname and client options
699 SecPolicyRef policy = nil;
700 SecPolicySearchRef policySearch = nil;
701 OSStatus status = SecPolicySearchCreate(CSSM_CERT_X_509v3, &CSSMOID_APPLE_TP_SSL, NULL, &policySearch);
702 if (!status) {
703 status = SecPolicySearchCopyNext(policySearch, &policy);
704 }
705 if (!status && policy) {
706 // set options for client-side or server-side policy evaluation
707 char *strbuf = NULL;
708 const char *hostnamestr = NULL;
709 if (hostname) {
710 hostnamestr = CFStringGetCStringPtr(hostname, kCFStringEncodingUTF8);
711 if (hostnamestr == NULL) {
712 CFIndex maxLen = CFStringGetMaximumSizeForEncoding(CFStringGetLength(hostname), kCFStringEncodingUTF8) + 1;
713 strbuf = (char *)malloc(maxLen);
714 if (CFStringGetCString(hostname, strbuf, maxLen, kCFStringEncodingUTF8)) {
715 hostnamestr = strbuf;
716 }
717 }
718 }
719 uint32 hostnamelen = (hostnamestr) ? (uint32)strlen(hostnamestr) : 0;
720 uint32 flags = (!server) ? CSSM_APPLE_TP_SSL_CLIENT : 0;
721 CSSM_APPLE_TP_SSL_OPTIONS opts = {CSSM_APPLE_TP_SSL_OPTS_VERSION, hostnamelen, hostnamestr, flags};
722 CSSM_DATA data = {sizeof(opts), (uint8*)&opts};
723 SecPolicySetValue(policy, &data);
724
725 if (strbuf) {
726 free(strbuf);
727 }
728 }
729 if (policySearch) {
730 CFRelease(policySearch);
731 }
732 return policy;
733 }
734 #endif
735
736 #if !SECTRUST_OSX
737 /* not exported */
738 static SecPolicyRef
739 SecPolicyCreateWithSecAsn1Oid(SecAsn1Oid *oidPtr)
740 {
741 SecPolicyRef policy = NULL;
742 try {
743 SecPointer<Policy> policyObj;
744 PolicyCursor::policy(oidPtr, policyObj);
745 policy = policyObj->handle();
746 }
747 catch (...) {}
748
749 return policy;
750 }
751 #endif
752
753 /* OS X only: __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_7, __MAC_10_9, __IPHONE_NA, __IPHONE_NA) */
754 SecPolicyRef
755 SecPolicyCreateWithOID(CFTypeRef policyOID)
756 {
757 // for now, we only accept the policy constants that are defined in SecPolicy.h
758 CFStringRef oidStr = (CFStringRef)policyOID;
759 CSSM_OID *oidPtr = NULL;
760 SecPolicyRef policy = NULL;
761 if (!oidStr) {
762 return policy;
763 }
764 unsigned int i, oidmaplen = sizeof(oidmap) / sizeof(oidmap_entry_t);
765 for (i=0; i<oidmaplen; i++) {
766 CFStringRef str = (CFStringRef) oidmap[i].oidstr;
767 if (CFStringCompare(str, oidStr, 0) == kCFCompareEqualTo) {
768 oidPtr = (CSSM_OID*)oidmap[i].oidptr;
769 break;
770 }
771 }
772 if (CFEqual(oidStr, kSecPolicyAppleServerAuthentication)) {
773 return SecPolicyCreateAppleSSLService(NULL);
774 }
775 if (oidPtr) {
776 SecPolicySearchRef policySearch = NULL;
777 OSStatus status = SecPolicySearchCreate(CSSM_CERT_X_509v3, oidPtr, NULL, &policySearch);
778 if (!status && policySearch) {
779 status = SecPolicySearchCopyNext(policySearch, &policy);
780 CFRelease(policySearch);
781 }
782 if (!policy && CFEqual(policyOID, kSecPolicyAppleRevocation)) {
783 policy = SecPolicyCreateRevocation(kSecRevocationUseAnyAvailableMethod);
784 }
785 #if !SECTRUST_OSX
786 if (!policy) {
787 policy = SecPolicyCreateWithSecAsn1Oid((SecAsn1Oid*)oidPtr);
788 }
789 #endif
790 }
791 if (!policy) {
792 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.");
793 }
794 return policy;
795 }
796
797 #if !SECTRUST_OSX
798 /* new in 10.9 */
799 SecPolicyRef
800 SecPolicyCreateWithProperties(CFTypeRef policyIdentifier, CFDictionaryRef properties)
801 {
802 SecPolicyRef policy = SecPolicyCreateWithOID(policyIdentifier);
803 SecPolicySetProperties(policy, properties);
804
805 return policy;
806 }
807 #endif
808
809 #if !SECTRUST_OSX
810 /* new in 10.9 */
811 SecPolicyRef
812 SecPolicyCreateRevocation(CFOptionFlags revocationFlags)
813 {
814 // return a SecPolicyRef object for the unified revocation policy
815 SecAsn1Oid *oidPtr = (SecAsn1Oid*)&CSSMOID_APPLE_TP_REVOCATION;
816 SecPolicyRef policy = SecPolicyCreateWithSecAsn1Oid(oidPtr);
817 if (policy) {
818 CSSM_DATA policyData = { (CSSM_SIZE)sizeof(CFOptionFlags), (uint8*)&revocationFlags };
819 SecPolicySetValue(policy, &policyData);
820 }
821 return policy;
822 }
823 #endif
824
825 /* OS X only: deprecated SPI entry point */
826 /* new in 10.9 ***FIXME*** TO BE REMOVED */
827 CFArrayRef SecPolicyCopyEscrowRootCertificates(void)
828 {
829 return SecCertificateCopyEscrowRoots(kSecCertificateProductionEscrowRoot);
830 }
831
832 SecPolicyRef SecPolicyCreateAppleIDSService(CFStringRef hostname)
833 {
834 return SecPolicyCreateSSL(true, hostname);
835 }
836
837 SecPolicyRef SecPolicyCreateAppleIDSServiceContext(CFStringRef hostname, CFDictionaryRef __unused context)
838 {
839 return SecPolicyCreateSSL(true, hostname);
840 }
841
842 SecPolicyRef SecPolicyCreateApplePushService(CFStringRef hostname, CFDictionaryRef __unused context)
843 {
844 return SecPolicyCreateSSL(true, hostname);
845 }
846
847 SecPolicyRef SecPolicyCreateApplePushServiceLegacy(CFStringRef hostname)
848 {
849 return SecPolicyCreateSSL(true, hostname);
850 }
851
852 SecPolicyRef SecPolicyCreateAppleMMCSService(CFStringRef hostname, CFDictionaryRef __unused context)
853 {
854 return SecPolicyCreateSSL(true, hostname);
855 }
856
857 SecPolicyRef SecPolicyCreateAppleGSService(CFStringRef hostname, CFDictionaryRef __unused context)
858 {
859 return SecPolicyCreateSSL(true, hostname);
860 }
861
862 SecPolicyRef SecPolicyCreateApplePPQService(CFStringRef hostname, CFDictionaryRef __unused context)
863 {
864 return SecPolicyCreateSSL(true, hostname);
865 }
866
867 SecPolicyRef SecPolicyCreateAppleATVAppSigning(void)
868 {
869 return SecPolicyCreateWithOID(kSecPolicyAppleX509Basic);
870 }
871
872 SecPolicyRef SecPolicyCreateTestAppleATVAppSigning(void)
873 {
874 return SecPolicyCreateWithOID(kSecPolicyAppleX509Basic);
875 }
876
877 SecPolicyRef SecPolicyCreateApplePayIssuerEncryption(void)
878 {
879 return SecPolicyCreateWithOID(kSecPolicyAppleX509Basic);
880 }
881
882 #if !SECTRUST_OSX
883 SecPolicyRef SecPolicyCreateAppleSSLService(CFStringRef hostname)
884 {
885 // SSL server, pinned to an Apple intermediate
886 SecPolicyRef policy = SecPolicyCreateSSL(true, hostname);
887 if (policy) {
888 // change options for policy evaluation
889 char *strbuf = NULL;
890 const char *hostnamestr = NULL;
891 if (hostname) {
892 hostnamestr = CFStringGetCStringPtr(hostname, kCFStringEncodingUTF8);
893 if (hostnamestr == NULL) {
894 CFIndex maxLen = CFStringGetMaximumSizeForEncoding(CFStringGetLength(hostname), kCFStringEncodingUTF8) + 1;
895 strbuf = (char *)malloc(maxLen);
896 if (CFStringGetCString(hostname, strbuf, maxLen, kCFStringEncodingUTF8)) {
897 hostnamestr = strbuf;
898 }
899 }
900 }
901 uint32 hostnamelen = (hostnamestr) ? (uint32)strlen(hostnamestr) : 0;
902 uint32 flags = 0x00000002; // 2nd-lowest bit set to require Apple intermediate pin
903 CSSM_APPLE_TP_SSL_OPTIONS opts = {CSSM_APPLE_TP_SSL_OPTS_VERSION, hostnamelen, hostnamestr, flags};
904 CSSM_DATA data = {sizeof(opts), (uint8*)&opts};
905 SecPolicySetValue(policy, &data);
906 }
907 return policy;
908 }
909 #endif
910
911 /* OS X only: TBD */
912 #include <security_utilities/cfutilities.h>
913 /* New in 10.10 */
914 // Takes the "context" policies to extract the revocation and apply it to timeStamp.
915 CFArrayRef
916 SecPolicyCreateAppleTimeStampingAndRevocationPolicies(CFTypeRef policyOrArray)
917 {
918 #if !SECTRUST_OSX
919 /* can't use SECAPI macros, since this function does not return OSStatus */
920 CFArrayRef resultPolicyArray=NULL;
921 try {
922 // Set default policy
923 CFRef<CFArrayRef> policyArray = cfArrayize(policyOrArray);
924 CFRef<SecPolicyRef> defaultPolicy = SecPolicyCreateWithOID(kSecPolicyAppleTimeStamping);
925 CFRef<CFMutableArrayRef> appleTimeStampingPolicies = makeCFMutableArray(1,defaultPolicy.get());
926
927 // Parse the policy and add revocation related ones
928 CFIndex numPolicies = CFArrayGetCount(policyArray);
929 for(CFIndex dex=0; dex<numPolicies; dex++) {
930 SecPolicyRef secPol = (SecPolicyRef)CFArrayGetValueAtIndex(policyArray, dex);
931 SecPointer<Policy> pol = Policy::required(SecPolicyRef(secPol));
932 const CssmOid &oid = pol->oid();
933 if ((oid == CssmOid::overlay(CSSMOID_APPLE_TP_REVOCATION))
934 || (oid == CssmOid::overlay(CSSMOID_APPLE_TP_REVOCATION_CRL))
935 || (oid == CssmOid::overlay(CSSMOID_APPLE_TP_REVOCATION_OCSP)))
936 {
937 CFArrayAppendValue(appleTimeStampingPolicies, secPol);
938 }
939 }
940 // Transfer of ownership
941 resultPolicyArray=appleTimeStampingPolicies.yield();
942 }
943 catch (...) {
944 CFReleaseNull(resultPolicyArray);
945 };
946 #else
947 /* implement with unified SecPolicyRef instances */
948 SecPolicyRef policy = NULL;
949 CFMutableArrayRef resultPolicyArray = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
950 policy = SecPolicyCreateWithOID(kSecPolicyAppleTimeStamping);
951 if (policy) {
952 CFArrayAppendValue(resultPolicyArray, policy);
953 CFReleaseNull(policy);
954 }
955 policy = SecPolicyCreateWithOID(kSecPolicyAppleRevocation);
956 if (policy) {
957 CFArrayAppendValue(resultPolicyArray, policy);
958 CFReleaseNull(policy);
959 }
960 #endif
961 return resultPolicyArray;
962 }
963