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