SecTrustStore.c
1 /* 2 * Copyright (c) 2007-2020 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 /* 25 * SecTrustStore.c - CertificateSource API to a system root certificate store 26 */ 27 #include <Security/SecTrustStore.h> 28 29 #include <Security/SecCertificateInternal.h> 30 #include <Security/SecInternal.h> 31 #include <Security/SecuritydXPC.h> 32 #include <Security/SecPolicyPriv.h> 33 #include <Security/SecPolicyInternal.h> 34 #include <CoreFoundation/CFString.h> 35 #include <AssertMacros.h> 36 #include <ipc/securityd_client.h> 37 #include "SecFramework.h" 38 #include <sys/stat.h> 39 #include <stdio.h> 40 #include <os/activity.h> 41 #include <dirent.h> 42 #include <Security/SecTrustPriv.h> 43 #include <Security/SecTrustSettingsPriv.h> 44 #include <utilities/SecCFError.h> 45 #include <utilities/SecCFWrappers.h> 46 #include "utilities/SecDb.h" 47 #include "SecTrustInternal.h" 48 49 static CFStringRef kSecTrustStoreUserName = CFSTR("user"); 50 static CFStringRef kSecTrustStoreAdminName = CFSTR("admin"); 51 static CFStringRef kSecTrustStoreSystemName = CFSTR("system"); 52 53 SecTrustStoreRef SecTrustStoreForDomain(SecTrustStoreDomain domain) { 54 CFStringRef domainName = NULL; 55 switch (domain) { 56 case kSecTrustStoreDomainUser: 57 domainName = kSecTrustStoreUserName; 58 break; 59 case kSecTrustStoreDomainAdmin: 60 domainName = kSecTrustStoreAdminName; 61 break; 62 case kSecTrustStoreDomainSystem: 63 domainName = kSecTrustStoreSystemName; 64 break; 65 default: 66 return NULL; 67 } 68 69 if (gTrustd) { 70 return gTrustd->sec_trust_store_for_domain(domainName, NULL); 71 } else { 72 return (SecTrustStoreRef)domainName; 73 } 74 } 75 76 static bool SecXPCDictionarySetCertificate(xpc_object_t message, const char *key, SecCertificateRef certificate, CFErrorRef *error) { 77 if (certificate) { 78 xpc_dictionary_set_data(message, key, SecCertificateGetBytePtr(certificate), 79 SecCertificateGetLength(certificate)); 80 return true; 81 } 82 return SecError(errSecParam, error, CFSTR("NULL certificate")); 83 } 84 85 static bool string_cert_to_bool_error(enum SecXPCOperation op, SecTrustStoreRef ts, SecCertificateRef cert, CFErrorRef *error) 86 { 87 return securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *blockError) { 88 return SecXPCDictionarySetString(message, kSecXPCKeyDomain, (CFStringRef)ts, blockError) && 89 SecXPCDictionarySetCertificate(message, kSecXPCKeyCertificate, cert, blockError); 90 }, NULL); 91 } 92 93 static bool string_cert_to_bool_bool_error(enum SecXPCOperation op, SecTrustStoreRef ts, SecCertificateRef cert, bool *result, CFErrorRef *error) 94 { 95 os_activity_t activity = os_activity_create("SecTrustStoreContains", OS_ACTIVITY_CURRENT, OS_ACTIVITY_FLAG_DEFAULT); 96 os_activity_scope(activity); 97 bool status = securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *blockError) { 98 return SecXPCDictionarySetString(message, kSecXPCKeyDomain, (CFStringRef)ts, blockError) && 99 SecXPCDictionarySetCertificate(message, kSecXPCKeyCertificate, cert, blockError); 100 }, ^bool(xpc_object_t response, CFErrorRef *blockError) { 101 if (result) 102 *result = xpc_dictionary_get_bool(response, kSecXPCKeyResult); 103 return true; 104 }); 105 os_release(activity); 106 return status; 107 } 108 109 Boolean SecTrustStoreContains(SecTrustStoreRef ts, 110 SecCertificateRef certificate) { 111 bool ok = false; 112 __block bool contains = false; 113 require(ts, errOut); 114 ok = (SecOSStatusWith(^bool (CFErrorRef *error) { 115 return TRUSTD_XPC(sec_trust_store_contains, string_cert_to_bool_bool_error, ts, certificate, &contains, error); 116 }) == errSecSuccess); 117 118 errOut: 119 return ok && contains; 120 } 121 122 123 static bool string_cert_cftype_to_error(enum SecXPCOperation op, SecTrustStoreRef ts, SecCertificateRef certificate, CFTypeRef trustSettingsDictOrArray, CFErrorRef *error) 124 { 125 return securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *blockError) { 126 bool ok = false; 127 ok = SecXPCDictionarySetString(message, kSecXPCKeyDomain, (CFStringRef)ts, blockError) && 128 SecXPCDictionarySetCertificate(message, kSecXPCKeyCertificate, certificate, blockError) && 129 (!trustSettingsDictOrArray || SecXPCDictionarySetPList(message, kSecXPCKeySettings, trustSettingsDictOrArray, blockError)); 130 return ok; 131 }, NULL); 132 } 133 134 static OSStatus validateConstraint(Boolean isSelfSigned, CFMutableDictionaryRef trustSettingsDict) { 135 OSStatus result = errSecSuccess; 136 137 /* Check "TrustRoot"/"TrustAsRoot" */ 138 CFNumberRef resultNumber = NULL; 139 resultNumber = (CFNumberRef)CFDictionaryGetValue(trustSettingsDict, kSecTrustSettingsResult); 140 uint32_t resultValue = kSecTrustSettingsResultInvalid; 141 if (!isNumber(resultNumber) && !isSelfSigned) { 142 /* only self-signed certs get default of TrustAsRoot */ 143 return errSecParam; 144 } 145 if (isNumber(resultNumber) && CFNumberGetValue(resultNumber, kCFNumberSInt32Type, &resultValue)) { 146 if (isSelfSigned && resultValue == kSecTrustSettingsResultTrustAsRoot) { 147 return errSecParam; 148 } 149 if (!isSelfSigned && resultValue == kSecTrustSettingsResultTrustRoot) { 150 return errSecParam; 151 } 152 } 153 154 /* If there's a policy specified, change the contents */ 155 SecPolicyRef policy = NULL; 156 policy = (SecPolicyRef)CFDictionaryGetValue(trustSettingsDict, kSecTrustSettingsPolicy); 157 if (policy) { 158 CFStringRef policyOid = NULL, policyName = NULL; 159 policyOid = SecPolicyGetOidString(policy); 160 policyName = SecPolicyGetName(policy); 161 CFDictionarySetValue(trustSettingsDict, kSecTrustSettingsPolicy, policyOid); 162 if (policyName) { CFDictionaryAddValue(trustSettingsDict, kSecTrustSettingsPolicyName, policyName); } 163 } 164 165 return result; 166 } 167 168 static OSStatus validateTrustSettings(Boolean isSelfSigned, 169 CFTypeRef trustSettingsDictOrArray, 170 CFTypeRef * CF_RETURNS_RETAINED modifiedTrustSettings) { 171 OSStatus status = errSecParam; 172 CFTypeRef result = NULL; 173 174 /* NULL is a valid input */ 175 if (!trustSettingsDictOrArray && isSelfSigned) { 176 return errSecSuccess; 177 } else if (!trustSettingsDictOrArray && !isSelfSigned) { 178 return errSecParam; 179 } 180 181 if (CFDictionaryGetTypeID() == CFGetTypeID(trustSettingsDictOrArray)) { 182 result = CFDictionaryCreateMutableCopy(NULL, 0, trustSettingsDictOrArray); 183 status = validateConstraint(isSelfSigned, (CFMutableDictionaryRef)result); 184 } else if (CFArrayGetTypeID() == CFGetTypeID(trustSettingsDictOrArray)) { 185 require_action_quiet(result = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks), 186 out, status = errSecAllocate); 187 CFIndex ix, count = CFArrayGetCount(trustSettingsDictOrArray); 188 for (ix = 0; ix < count; ix++) { 189 CFDictionaryRef constraint = CFArrayGetValueAtIndex(trustSettingsDictOrArray, ix); 190 CFDictionaryRef modifiedConstraint = NULL; 191 require_noerr_quiet(status = validateTrustSettings(isSelfSigned, constraint, (CFTypeRef *)&modifiedConstraint), out); 192 CFArrayAppendValue((CFMutableArrayRef)result, modifiedConstraint); 193 CFReleaseNull(modifiedConstraint); /* constraint now owned by array */ 194 } 195 } 196 197 out: 198 if (errSecSuccess == status && modifiedTrustSettings) { 199 *modifiedTrustSettings = CFRetainSafe(result); 200 } 201 CFReleaseNull(result); 202 return status; 203 } 204 205 OSStatus SecTrustStoreSetTrustSettings(SecTrustStoreRef ts, 206 SecCertificateRef certificate, 207 CFTypeRef trustSettingsDictOrArray) { 208 __block OSStatus result; 209 __block CFTypeRef validatedTrustSettings = NULL; 210 211 Boolean isSelfSigned = false; 212 require_noerr_quiet(result = SecCertificateIsSelfSigned(certificate, &isSelfSigned), out); 213 require_noerr_quiet(result = validateTrustSettings(isSelfSigned, trustSettingsDictOrArray, &validatedTrustSettings), out); 214 215 os_activity_initiate("SecTrustStoreSetTrustSettings", OS_ACTIVITY_FLAG_DEFAULT, ^{ 216 result = SecOSStatusWith(^bool (CFErrorRef *error) { 217 return TRUSTD_XPC(sec_trust_store_set_trust_settings, string_cert_cftype_to_error, ts, certificate, validatedTrustSettings, error); 218 }); 219 }); 220 221 out: 222 CFReleaseNull(validatedTrustSettings); 223 return result; 224 } 225 226 OSStatus SecTrustStoreRemoveCertificate(SecTrustStoreRef ts, 227 SecCertificateRef certificate) 228 { 229 __block OSStatus status = errSecParam; 230 231 os_activity_t activity = os_activity_create("SecTrustStoreRemoveCertificate", OS_ACTIVITY_CURRENT, OS_ACTIVITY_FLAG_DEFAULT); 232 os_activity_scope(activity); 233 require(ts, errOut); 234 235 status = SecOSStatusWith(^bool (CFErrorRef *error) { 236 return TRUSTD_XPC(sec_trust_store_remove_certificate, string_cert_to_bool_error, ts, certificate, error); 237 }); 238 239 errOut: 240 os_release(activity); 241 return status; 242 } 243 244 OSStatus SecTrustStoreGetSettingsVersionNumber(SecTrustSettingsVersionNumber* p_settings_version_number) 245 { 246 if (NULL == p_settings_version_number) { 247 return errSecParam; 248 } 249 250 OSStatus status = errSecSuccess; 251 CFErrorRef error = nil; 252 uint64_t versionNumber = SecTrustGetTrustStoreVersionNumber(&error); 253 *p_settings_version_number = (SecTrustSettingsVersionNumber)versionNumber; 254 255 if (error) { 256 status = (OSStatus)CFErrorGetCode(error); 257 } 258 CFReleaseSafe(error); 259 return status; 260 } 261 262 OSStatus SecTrustStoreGetSettingsAssetVersionNumber(SecTrustSettingsAssetVersionNumber* p_settings_asset_version_number) 263 { 264 if (NULL == p_settings_asset_version_number) { 265 return errSecParam; 266 } 267 268 OSStatus status = errSecSuccess; 269 CFErrorRef error = nil; 270 uint64_t versionNumber = SecTrustGetAssetVersionNumber(&error); 271 *p_settings_asset_version_number = (SecTrustSettingsAssetVersionNumber)versionNumber; 272 273 if (error) { 274 status = (OSStatus)CFErrorGetCode(error); 275 } 276 CFReleaseSafe(error); 277 return status; 278 } 279 280 static bool string_to_array_error(enum SecXPCOperation op, SecTrustStoreRef ts, CFArrayRef *trustStoreContents, CFErrorRef *error) 281 { 282 return securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *blockError) { 283 return SecXPCDictionarySetString(message, kSecXPCKeyDomain, (CFStringRef)ts, blockError); 284 }, ^bool(xpc_object_t response, CFErrorRef *blockError) { 285 if (trustStoreContents) { 286 *trustStoreContents = SecXPCDictionaryCopyArray(response, kSecXPCKeyResult, blockError); 287 if (!*trustStoreContents) return false; 288 } 289 return true; 290 }); 291 } 292 293 OSStatus SecTrustStoreCopyAll(SecTrustStoreRef ts, CFArrayRef *trustStoreContents) 294 { 295 __block CFArrayRef results = NULL; 296 OSStatus status = errSecParam; 297 298 os_activity_t activity = os_activity_create("SecTrustStoreCopyAll", OS_ACTIVITY_CURRENT, OS_ACTIVITY_FLAG_DEFAULT); 299 os_activity_scope(activity); 300 require(ts, errOut); 301 302 status = SecOSStatusWith(^bool (CFErrorRef *error) { 303 return TRUSTD_XPC(sec_trust_store_copy_all, string_to_array_error, ts, &results, error); 304 }); 305 306 *trustStoreContents = results; 307 308 errOut: 309 os_release(activity); 310 return status; 311 } 312 313 static bool string_cert_to_array_error(enum SecXPCOperation op, SecTrustStoreRef ts, SecCertificateRef cert, CFArrayRef *usageConstraints, CFErrorRef *error) 314 { 315 return securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *blockError) { 316 return SecXPCDictionarySetString(message, kSecXPCKeyDomain, (CFStringRef)ts, blockError) && 317 SecXPCDictionarySetCertificate(message, kSecXPCKeyCertificate, cert, blockError); 318 }, ^bool(xpc_object_t response, CFErrorRef *blockError) { 319 return SecXPCDictionaryCopyArrayOptional(response, kSecXPCKeyResult, usageConstraints, blockError); 320 }); 321 } 322 323 OSStatus SecTrustStoreCopyUsageConstraints(SecTrustStoreRef ts, SecCertificateRef certificate, CFArrayRef *usageConstraints) 324 { 325 __block CFArrayRef results = NULL; 326 OSStatus status = errSecParam; 327 328 os_activity_t activity = os_activity_create("SecTrustStoreCopyUsageConstraints", OS_ACTIVITY_CURRENT, OS_ACTIVITY_FLAG_DEFAULT); 329 os_activity_scope(activity); 330 require(ts, errOut); 331 require(certificate, errOut); 332 require(usageConstraints, errOut); 333 334 status = SecOSStatusWith(^bool (CFErrorRef *error) { 335 return TRUSTD_XPC(sec_trust_store_copy_usage_constraints, string_cert_to_array_error, ts, certificate, &results, error); 336 }); 337 338 *usageConstraints = results; 339 340 errOut: 341 os_release(activity); 342 return status; 343 } 344 345 #define do_if_registered(sdp, ...) if (gTrustd && gTrustd->sdp) { return gTrustd->sdp(__VA_ARGS__); } 346 347 const CFStringRef kSecTrustStoreSPKIHashKey = CFSTR("SubjectPublicKeyInfoHash"); 348 const CFStringRef kSecTrustStoreHashAlgorithmKey = CFSTR("HashAlgorithm"); 349 350 /* MARK: CT Enforcement Exceptions */ 351 352 const CFStringRef kSecCTExceptionsCAsKey = CFSTR("DisabledForCAs"); 353 const CFStringRef kSecCTExceptionsDomainsKey = CFSTR("DisabledForDomains"); 354 const CFStringRef kSecCTExceptionsHashAlgorithmKey = kSecTrustStoreHashAlgorithmKey; 355 const CFStringRef kSecCTExceptionsSPKIHashKey = kSecTrustStoreSPKIHashKey; 356 357 bool SecTrustStoreSetCTExceptions(CFStringRef applicationIdentifier, CFDictionaryRef exceptions, CFErrorRef *error) { 358 #if !TARGET_OS_BRIDGE 359 if (applicationIdentifier && gTrustd && gTrustd->sec_trust_store_set_ct_exceptions) { 360 return gTrustd->sec_trust_store_set_ct_exceptions(applicationIdentifier, exceptions, error); 361 } else if (gTrustd && gTrustd->sec_trust_store_set_ct_exceptions) { 362 /* When calling from the TrustTests, we need to pass the appID for the tests. Ordinarily, 363 * this is done by trustd using the client's entitlements. */ 364 return gTrustd->sec_trust_store_set_ct_exceptions(CFSTR("com.apple.trusttests"), exceptions, error); 365 } 366 367 os_activity_t activity = os_activity_create("SecTrustStoreSetCTExceptions", OS_ACTIVITY_CURRENT, OS_ACTIVITY_FLAG_DEFAULT); 368 os_activity_scope(activity); 369 370 __block bool result = false; 371 securityd_send_sync_and_do(kSecXPCOpSetCTExceptions, error, ^bool(xpc_object_t message, CFErrorRef *block_error) { 372 SecXPCDictionarySetPListOptional(message, kSecTrustExceptionsKey, exceptions, block_error); 373 SecXPCDictionarySetStringOptional(message, kSecTrustEventApplicationID, applicationIdentifier, block_error); 374 return true; 375 }, ^bool(xpc_object_t response, CFErrorRef *block_error) { 376 result = SecXPCDictionaryGetBool(response, kSecXPCKeyResult, block_error); 377 return true; 378 }); 379 380 os_release(activity); 381 return result; 382 #else // TARGET_OS_BRIDGE 383 return SecError(errSecReadOnly, error, CFSTR("SecTrustStoreSetCTExceptions not supported on bridgeOS")); 384 #endif // TARGET_OS_BRIDGE 385 } 386 387 CFDictionaryRef SecTrustStoreCopyCTExceptions(CFStringRef applicationIdentifier, CFErrorRef *error) { 388 #if !TARGET_OS_BRIDGE 389 do_if_registered(sec_trust_store_copy_ct_exceptions, applicationIdentifier, error); 390 391 os_activity_t activity = os_activity_create("SecTrustStoreCopyCTExceptions", OS_ACTIVITY_CURRENT, OS_ACTIVITY_FLAG_DEFAULT); 392 os_activity_scope(activity); 393 394 __block CFDictionaryRef result = NULL; 395 securityd_send_sync_and_do(kSecXPCOpCopyCTExceptions, error, ^bool(xpc_object_t message, CFErrorRef *block_error) { 396 SecXPCDictionarySetStringOptional(message, kSecTrustEventApplicationID, applicationIdentifier, block_error); 397 return true; 398 }, ^bool(xpc_object_t response, CFErrorRef *block_error) { 399 (void)SecXPCDictionaryCopyDictionaryOptional(response, kSecTrustExceptionsKey, &result, block_error); 400 return true; 401 }); 402 403 os_release(activity); 404 return result; 405 #else // TARGET_OS_BRIDGE 406 SecError(errSecReadOnly, error, CFSTR("SecTrustStoreCopyCTExceptions not supported on bridgeOS")); 407 return NULL; 408 #endif // TARGET_OS_BRIDGE 409 } 410 411 /* MARK: CA Revocation Additions */ 412 413 /* Specify explicit additions to the list of known CAs for which revocation will be checked. 414 * Input: dictionary with following key and value: 415 * Key = kSecCARevocationAdditionsKey; Value = Array of dictionaries 416 * For revocation checking to be enabled for certificates issued by a CA, the CA must be specified as a 417 * dictionary entry containing the hash of the subjectPublicKeyInfo that appears in the CA certificate: 418 * Key = kSecCARevocationHashAlgorithmKey; Value = String. Currently, must be ”sha256”. 419 * Key = kSecCARevocationSPKIHashKey; Value = Data. Created by applying the specified hash algorithm 420 * to the DER encoding of the certificate's subjectPublicKeyInfo. 421 */ 422 423 const CFStringRef kSecCARevocationAdditionsKey = CFSTR("EnabledForCAs"); 424 const CFStringRef kSecCARevocationHashAlgorithmKey = kSecTrustStoreHashAlgorithmKey; 425 const CFStringRef kSecCARevocationSPKIHashKey = kSecTrustStoreSPKIHashKey; 426 427 bool SecTrustStoreSetCARevocationAdditions(CFStringRef applicationIdentifier, CFDictionaryRef additions, CFErrorRef *error) { 428 #if !TARGET_OS_BRIDGE 429 if (applicationIdentifier && gTrustd && gTrustd->sec_trust_store_set_ca_revocation_additions) { 430 return gTrustd->sec_trust_store_set_ca_revocation_additions(applicationIdentifier, additions, error); 431 } else if (gTrustd && gTrustd->sec_trust_store_set_ca_revocation_additions) { 432 /* When calling from the TrustTests, we need to pass the appID for the tests. Ordinarily, 433 * this is done by trustd using the client's entitlements. */ 434 return gTrustd->sec_trust_store_set_ca_revocation_additions(CFSTR("com.apple.trusttests"), additions, error); 435 } 436 437 os_activity_t activity = os_activity_create("SecTrustStoreSetCARevocationAdditions", OS_ACTIVITY_CURRENT, OS_ACTIVITY_FLAG_DEFAULT); 438 os_activity_scope(activity); 439 440 __block bool result = false; 441 securityd_send_sync_and_do(kSecXPCOpSetCARevocationAdditions, error, ^bool(xpc_object_t message, CFErrorRef *block_error) { 442 SecXPCDictionarySetPListOptional(message, kSecTrustRevocationAdditionsKey, additions, block_error); 443 SecXPCDictionarySetStringOptional(message, kSecTrustEventApplicationID, applicationIdentifier, block_error); 444 return true; 445 }, ^bool(xpc_object_t response, CFErrorRef *block_error) { 446 result = SecXPCDictionaryGetBool(response, kSecXPCKeyResult, block_error); 447 return true; 448 }); 449 450 os_release(activity); 451 return result; 452 #else // TARGET_OS_BRIDGE 453 return SecError(errSecReadOnly, error, CFSTR("SecTrustStoreSetCARevocationAdditions not supported on bridgeOS")); 454 #endif // TARGET_OS_BRIDGE 455 } 456 457 CFDictionaryRef SecTrustStoreCopyCARevocationAdditions(CFStringRef applicationIdentifier, CFErrorRef *error) { 458 #if !TARGET_OS_BRIDGE 459 do_if_registered(sec_trust_store_copy_ca_revocation_additions, applicationIdentifier, error); 460 461 os_activity_t activity = os_activity_create("SecTrustStoreCopyCARevocationAdditions", OS_ACTIVITY_CURRENT, OS_ACTIVITY_FLAG_DEFAULT); 462 os_activity_scope(activity); 463 464 __block CFDictionaryRef result = NULL; 465 securityd_send_sync_and_do(kSecXPCOpCopyCARevocationAdditions, error, ^bool(xpc_object_t message, CFErrorRef *block_error) { 466 SecXPCDictionarySetStringOptional(message, kSecTrustEventApplicationID, applicationIdentifier, block_error); 467 return true; 468 }, ^bool(xpc_object_t response, CFErrorRef *block_error) { 469 (void)SecXPCDictionaryCopyDictionaryOptional(response, kSecTrustRevocationAdditionsKey, &result, block_error); 470 return true; 471 }); 472 473 os_release(activity); 474 return result; 475 #else // TARGET_OS_BRIDGE 476 SecError(errSecReadOnly, error, CFSTR("SecTrustStoreCopyCARevocationAdditions not supported on bridgeOS")); 477 return NULL; 478 #endif // TARGET_OS_BRIDGE 479 } 480 481 /* MARK: Transparent Connection Pins */ 482 483 bool SecTrustStoreSetTransparentConnectionPins(CFStringRef applicationIdentifier, CFArrayRef pins, CFErrorRef *error) { 484 #if !TARGET_OS_BRIDGE 485 if (applicationIdentifier && gTrustd && gTrustd->sec_trust_store_set_transparent_connection_pins) { 486 return gTrustd->sec_trust_store_set_transparent_connection_pins(applicationIdentifier, pins, error); 487 } else if (gTrustd && gTrustd->sec_trust_store_set_transparent_connection_pins) { 488 /* When calling from the TrustTests, we need to pass the appID for the tests. Ordinarily, 489 * this is done by trustd using the client's entitlements. */ 490 return gTrustd->sec_trust_store_set_transparent_connection_pins(CFSTR("com.apple.trusttests"), pins, error); 491 } 492 493 os_activity_t activity = os_activity_create("SecTrustStoreSetTransparentConnectionPins", OS_ACTIVITY_CURRENT, OS_ACTIVITY_FLAG_DEFAULT); 494 os_activity_scope(activity); 495 496 __block bool result = false; 497 securityd_send_sync_and_do(kSecXPCOpSetTransparentConnectionPins, error, ^bool(xpc_object_t message, CFErrorRef *block_error) { 498 SecXPCDictionarySetPListOptional(message, kSecTrustAnchorsKey, pins, block_error); 499 SecXPCDictionarySetStringOptional(message, kSecTrustEventApplicationID, applicationIdentifier, block_error); 500 return true; 501 }, ^bool(xpc_object_t response, CFErrorRef *block_error) { 502 result = SecXPCDictionaryGetBool(response, kSecXPCKeyResult, block_error); 503 return true; 504 }); 505 506 os_release(activity); 507 return result; 508 #else // TARGET_OS_BRIDGE 509 return SecError(errSecReadOnly, error, CFSTR("SecTrustStoreSetTransparentConnectionPins not supported on bridgeOS")); 510 #endif // TARGET_OS_BRIDGE 511 } 512 513 CF_RETURNS_RETAINED CFArrayRef SecTrustStoreCopyTransparentConnectionPins(CFStringRef applicationIdentifier, CFErrorRef *error) { 514 #if !TARGET_OS_BRIDGE 515 do_if_registered(sec_trust_store_copy_transparent_connection_pins, applicationIdentifier, error); 516 517 os_activity_t activity = os_activity_create("SecTrustStoreCopyTransparentConnectionPins", OS_ACTIVITY_CURRENT, OS_ACTIVITY_FLAG_DEFAULT); 518 os_activity_scope(activity); 519 520 __block CFArrayRef result = NULL; 521 securityd_send_sync_and_do(kSecXPCOpCopyTransparentConnectionPins, error, ^bool(xpc_object_t message, CFErrorRef *block_error) { 522 SecXPCDictionarySetStringOptional(message, kSecTrustEventApplicationID, applicationIdentifier, block_error); 523 return true; 524 }, ^bool(xpc_object_t response, CFErrorRef *block_error) { 525 (void)SecXPCDictionaryCopyArrayOptional(response, kSecTrustAnchorsKey, &result, block_error); 526 return true; 527 }); 528 529 os_release(activity); 530 return result; 531 #else // TARGET_OS_BRIDGE 532 SecError(errSecReadOnly, error, CFSTR("SecTrustStoreCopyTransparentConnectionPins not supported on bridgeOS")); 533 return NULL; 534 #endif // TARGET_OS_BRIDGE 535 }