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