2 * Copyright (c) 2012-2014 Apple Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
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
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.
21 * @APPLE_LICENSE_HEADER_END@
28 #import <Foundation/Foundation.h>
29 #import <Foundation/NSXPCConnection_Private.h>
32 #include <AssertMacros.h>
33 #include "keychain/SecureObjectSync/SOSCloudCircle.h"
34 #include "keychain/SecureObjectSync/SOSCloudCircleInternal.h"
35 #include "keychain/SecureObjectSync/SOSCircle.h"
36 #include "keychain/SecureObjectSync/SOSAccount.h"
37 #include "keychain/SecureObjectSync/SOSFullPeerInfo.h"
38 #include "keychain/SecureObjectSync/SOSPeerInfoCollections.h"
39 #include "keychain/SecureObjectSync/SOSInternal.h"
40 #include "keychain/SecureObjectSync/SOSRing.h"
41 #include <Security/SecureObjectSync/SOSBackupSliceKeyBag.h>
42 #include <Security/SecureObjectSync/SOSViews.h>
43 #include "keychain/SecureObjectSync/SOSControlHelper.h"
44 #include "keychain/SecureObjectSync/SOSPeerInfoDER.h"
46 #include <Security/SecKeyPriv.h>
47 #include <Security/SecFramework.h>
48 #include <CoreFoundation/CFXPCBridge.h>
50 #include "keychain/securityd/SecItemServer.h"
52 #include <utilities/SecDispatchRelease.h>
53 #include <utilities/SecCFRelease.h>
54 #include <utilities/SecCFWrappers.h>
55 #include <utilities/SecXPCError.h>
57 #include <corecrypto/ccsha2.h>
59 #include <utilities/debugging.h>
61 #include <CoreFoundation/CoreFoundation.h>
64 #define MINIMIZE_INCLUDES MINIMIZE_INCLUDES
65 #include <ipc/securityd_client.h>
66 #include "keychain/securityd/spi.h"
68 #include <Security/SecuritydXPC.h>
70 const char * kSOSCCCircleChangedNotification = "com.apple.security.secureobjectsync.circlechanged";
71 const char * kSOSCCViewMembershipChangedNotification = "com.apple.security.secureobjectsync.viewschanged";
72 const char * kSOSCCInitialSyncChangedNotification = "com.apple.security.secureobjectsync.initialsyncchanged";
73 const char * kSOSCCHoldLockForInitialSync = "com.apple.security.secureobjectsync.holdlock";
74 const char * kSOSCCPeerAvailable = "com.apple.security.secureobjectsync.peeravailable";
75 const char * kSOSCCRecoveryKeyChanged = "com.apple.security.secureobjectsync.recoverykeychanged";
76 const char * kSOSCCCircleOctagonKeysChangedNotification = "com.apple.security.sosoctagonbitschanged";
78 #define do_if_registered(sdp, ...) if (gSecurityd && gSecurityd->sdp) { return gSecurityd->sdp(__VA_ARGS__); }
80 static bool xpc_dictionary_entry_is_type(xpc_object_t dictionary, const char *key, xpc_type_t type)
82 xpc_object_t value = xpc_dictionary_get_value(dictionary, key);
84 return value && (xpc_get_type(value) == type);
87 SOSCCStatus SOSCCThisDeviceIsInCircle(CFErrorRef *error)
89 SOSCCStatus retval = SOSGetCachedCircleStatus(error);
90 if(retval != kSOSNoCachedValue) {
91 secdebug("circleOps", "Retrieved cached circle value %d", retval);
94 return SOSCCThisDeviceIsInCircleNonCached(error);
98 SOSCCStatus SOSCCThisDeviceIsInCircleNonCached(CFErrorRef *error)
100 sec_trace_enter_api(NULL);
101 sec_trace_return_api(SOSCCStatus, ^{
102 SOSCCStatus result = kSOSCCError;
104 do_if_registered(soscc_ThisDeviceIsInCircle, error);
106 xpc_object_t message = securityd_create_message(kSecXPCOpDeviceInCircle, error);
108 xpc_object_t response = securityd_message_with_reply_sync(message, error);
110 if (response && xpc_dictionary_entry_is_type(response, kSecXPCKeyResult, XPC_TYPE_INT64)) {
111 result = (SOSCCStatus) xpc_dictionary_get_int64(response, kSecXPCKeyResult);
113 result = kSOSCCError;
117 if (response && securityd_message_no_error(response, error))
119 char *desc = xpc_copy_description(response);
120 SecCFCreateErrorWithFormat(0, sSecXPCErrorDomain, NULL, error, NULL, CFSTR("Remote error occurred/no info: %s"), desc);
125 secnotice("circleOps", "Retrieved non-cached circle value %d", result);
128 }, CFSTR("SOSCCStatus=%d"))
131 static bool sfsigninanalytics_bool_error_request(enum SecXPCOperation op, CFDataRef parentEvent, CFErrorRef* error)
133 __block bool result = false;
135 secdebug("sosops","enter - operation: %d", op);
136 securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
137 return SecXPCDictionarySetData(message, kSecXPCKeySignInAnalytics, parentEvent, error);
138 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
139 result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
145 static bool cfstring_to_error_request(enum SecXPCOperation op, CFStringRef string, CFErrorRef* error)
147 __block bool result = false;
149 secdebug("sosops","enter - operation: %d", op);
150 securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
151 xpc_object_t xString = _CFXPCCreateXPCObjectFromCFObject(string);
152 bool success = false;
154 xpc_dictionary_set_value(message, kSecXPCKeyString, xString);
159 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
160 result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
166 static SOSRingStatus cfstring_to_uint64_request(enum SecXPCOperation op, CFStringRef string, CFErrorRef* error)
168 __block bool result = false;
170 secdebug("sosops","enter - operation: %d", op);
171 securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
172 xpc_object_t xString = _CFXPCCreateXPCObjectFromCFObject(string);
173 bool success = false;
175 xpc_dictionary_set_value(message, kSecXPCKeyString, xString);
180 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
181 result = xpc_dictionary_get_int64(response, kSecXPCKeyResult);
187 static CFStringRef simple_cfstring_error_request(enum SecXPCOperation op, CFErrorRef* error)
189 __block CFStringRef result = NULL;
191 secdebug("sosops","enter - operation: %d", op);
192 securityd_send_sync_and_do(op, error, NULL, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
193 const char *c_string = xpc_dictionary_get_string(response, kSecXPCKeyResult);
196 result = CFStringCreateWithBytes(kCFAllocatorDefault, (const UInt8*)c_string, strlen(c_string), kCFStringEncodingUTF8, false);
199 return c_string != NULL;
204 static bool simple_bool_error_request(enum SecXPCOperation op, CFErrorRef* error)
206 __block bool result = false;
208 secdebug("sosops","enter - operation: %d", op);
209 securityd_send_sync_and_do(op, error, NULL, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
210 result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
216 static bool SecXPCDictionarySetPeerInfoData(xpc_object_t message, const char *key, SOSPeerInfoRef peerInfo, CFErrorRef *error) {
217 bool success = false;
218 CFDataRef peerData = SOSPeerInfoCopyEncodedData(peerInfo, kCFAllocatorDefault, error);
220 success = SecXPCDictionarySetData(message, key, peerData, error);
222 CFReleaseNull(peerData);
226 static bool peer_info_to_bool_error_request(enum SecXPCOperation op, SOSPeerInfoRef peerInfo, CFErrorRef* error)
228 __block bool result = false;
230 secdebug("sosops","enter - operation: %d", op);
231 securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
232 return SecXPCDictionarySetPeerInfoData(message, kSecXPCKeyPeerInfo, peerInfo, error);
233 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
234 result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
240 static CFBooleanRef cfarray_to_cfboolean_error_request(enum SecXPCOperation op, CFArrayRef views, CFErrorRef* error)
242 __block bool result = false;
244 secdebug("sosops","enter - operation: %d", op);
245 bool noError = securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
246 return SecXPCDictionarySetPList(message, kSecXPCKeyArray, views, error);
247 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
248 result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
251 return noError ? (result ? kCFBooleanTrue : kCFBooleanFalse) : NULL;
255 static CFSetRef cfset_cfset_to_cfset_error_request(enum SecXPCOperation op, CFSetRef set1, CFSetRef set2, CFErrorRef* error)
257 __block CFSetRef result = NULL;
259 secdebug("sosops","enter - operation: %d", op);
260 bool noError = securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
261 return SecXPCDictionarySetPList(message, kSecXPCKeySet, set1, error) && SecXPCDictionarySetPList(message, kSecXPCKeySet2, set2, error);
262 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
263 result = SecXPCDictionaryCopySet(response, kSecXPCKeyResult, error);
268 CFReleaseNull(result);
274 static bool escrow_to_bool_error_request(enum SecXPCOperation op, CFStringRef escrow_label, uint64_t tries, CFErrorRef* error)
276 __block bool result = false;
278 securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
280 bool success = false;
281 xpc_object_t xEscrowLabel = _CFXPCCreateXPCObjectFromCFObject(escrow_label);
283 xpc_dictionary_set_value(message, kSecXPCKeyEscrowLabel, xEscrowLabel);
288 xpc_dictionary_set_int64(message, kSecXPCKeyTriesLabel, tries);
293 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
294 result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
300 static CF_RETURNS_RETAINED CFArrayRef simple_array_error_request(enum SecXPCOperation op, CFErrorRef* error)
302 __block CFArrayRef result = NULL;
304 secdebug("sosops","enter - operation: %d", op);
305 if (securityd_send_sync_and_do(op, error, NULL, ^bool(xpc_object_t response, CFErrorRef *error) {
306 xpc_object_t temp_result = xpc_dictionary_get_value(response, kSecXPCKeyResult);
307 result = _CFXPCCreateCFObjectFromXPCObject(temp_result);
308 return result != NULL;
310 if (!isArray(result)) {
311 SOSErrorCreate(kSOSErrorUnexpectedType, error, NULL, CFSTR("Expected array, got: %@"), result);
312 CFReleaseNull(result);
318 static CF_RETURNS_RETAINED CFArrayRef der_array_error_request(enum SecXPCOperation op, CFErrorRef* error)
320 __block CFArrayRef result = NULL;
322 secdebug("sosops","enter - operation: %d", op);
323 if (securityd_send_sync_and_do(op, error, NULL, ^bool(xpc_object_t response, CFErrorRef *error) {
325 const uint8_t* bytes = xpc_dictionary_get_data(response, kSecXPCKeyResult, &length);
326 der_decode_plist(kCFAllocatorDefault, 0, (CFPropertyListRef*) &result, error, bytes, bytes + length);
328 return result != NULL;
330 if (!isArray(result)) {
331 SOSErrorCreate(kSOSErrorUnexpectedType, error, NULL, CFSTR("Expected array, got: %@"), result);
332 CFReleaseNull(result);
338 static CFDictionaryRef strings_to_dictionary_error_request(enum SecXPCOperation op, CFErrorRef* error)
340 __block CFDictionaryRef result = NULL;
342 secdebug("sosops","enter - operation: %d", op);
344 if (securityd_send_sync_and_do(op, error, NULL, ^bool(xpc_object_t response, CFErrorRef *error) {
345 xpc_object_t temp_result = xpc_dictionary_get_value(response, kSecXPCKeyResult);
347 result = _CFXPCCreateCFObjectFromXPCObject(temp_result);
348 return result != NULL;
351 if (!isDictionary(result)) {
352 SOSErrorCreate(kSOSErrorUnexpectedType, error, NULL, CFSTR("Expected dictionary, got: %@"), result);
353 CFReleaseNull(result);
360 static int simple_int_error_request(enum SecXPCOperation op, CFErrorRef* error)
362 __block int result = 0;
364 secdebug("sosops","enter - operation: %d", op);
365 securityd_send_sync_and_do(op, error, NULL, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
366 int64_t temp_result = xpc_dictionary_get_int64(response, kSecXPCKeyResult);
367 if ((temp_result >= INT32_MIN) && (temp_result <= INT32_MAX)) {
368 result = (int)temp_result;
375 static CF_RETURNS_RETAINED SOSPeerInfoRef peer_info_error_request(enum SecXPCOperation op, CFErrorRef* error)
377 SOSPeerInfoRef result = NULL;
378 __block CFDataRef data = NULL;
380 secdebug("sosops","enter - operation: %d", op);
381 securityd_send_sync_and_do(op, error, NULL, ^bool(xpc_object_t response, CFErrorRef *error) {
382 xpc_object_t temp_result = xpc_dictionary_get_value(response, kSecXPCKeyResult);
383 if (response && (NULL != temp_result)) {
384 data = _CFXPCCreateCFObjectFromXPCObject(temp_result);
390 result = SOSPeerInfoCreateFromData(kCFAllocatorDefault, error, data);
392 SOSErrorCreate(kSOSErrorUnexpectedType, error, NULL, CFSTR("Expected CFData, got: %@"), data);
399 static CFDataRef flags_to_data_error_request(enum SecXPCOperation op, uint32_t flags, CFErrorRef *error)
401 __block CFDataRef result = NULL;
403 secdebug("sosops", "enter -- operation: %d", op);
404 securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
405 xpc_dictionary_set_uint64(message, kSecXPCKeyFlags, flags);
407 }, ^bool(xpc_object_t response, CFErrorRef *error) {
408 xpc_object_t temp_result = xpc_dictionary_get_value(response, kSecXPCKeyResult);
409 if (response && (NULL != temp_result)) {
410 result = _CFXPCCreateCFObjectFromXPCObject(temp_result);
412 return result != NULL;
415 if (!isData(result)) {
416 SOSErrorCreate(kSOSErrorUnexpectedType, error, NULL, CFSTR("Expected CFData, got: %@"), result);
424 static CFDataRef data_to_error_request(enum SecXPCOperation op, CFErrorRef *error)
426 __block CFDataRef result = NULL;
428 secdebug("sosops", "enter -- operation: %d", op);
429 securityd_send_sync_and_do(op, error, NULL, ^bool(xpc_object_t response, CFErrorRef *error) {
430 xpc_object_t temp_result = xpc_dictionary_get_value(response, kSecXPCKeyResult);
431 if (response && (NULL != temp_result)) {
432 result = _CFXPCCreateCFObjectFromXPCObject(temp_result);
434 return result != NULL;
437 if (!isData(result)) {
438 SOSErrorCreate(kSOSErrorUnexpectedType, error, NULL, CFSTR("Expected CFData, got: %@"), result);
445 static CFArrayRef array_of_info_error_request(enum SecXPCOperation op, CFErrorRef* error)
447 __block CFArrayRef result = NULL;
449 secdebug("sosops","enter - operation: %d", op);
450 securityd_send_sync_and_do(op, error, NULL, ^bool(xpc_object_t response, CFErrorRef *error) {
451 xpc_object_t encoded_array = xpc_dictionary_get_value(response, kSecXPCKeyResult);
452 if (response && (NULL != encoded_array)) {
453 result = CreateArrayOfPeerInfoWithXPCObject(encoded_array, error);
455 return result != NULL;
458 if (!isArray(result)) {
459 SOSErrorCreate(kSOSErrorUnexpectedType, error, NULL, CFSTR("Expected array, got: %@"), result);
460 CFReleaseNull(result);
465 static CF_RETURNS_RETAINED SOSPeerInfoRef data_to_peer_info_error_request(enum SecXPCOperation op, CFDataRef secret, CFErrorRef* error)
467 __block SOSPeerInfoRef result = false;
468 __block CFDataRef data = NULL;
470 secdebug("sosops", "enter - operation: %d", op);
471 securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
472 xpc_object_t xsecretData = _CFXPCCreateXPCObjectFromCFObject(secret);
473 bool success = false;
475 xpc_dictionary_set_value(message, kSecXPCKeyNewPublicBackupKey, xsecretData);
480 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
481 xpc_object_t temp_result = xpc_dictionary_get_value(response, kSecXPCKeyResult);
482 if (response && (NULL != temp_result)) {
483 data = _CFXPCCreateCFObjectFromXPCObject(temp_result);
489 result = SOSPeerInfoCreateFromData(kCFAllocatorDefault, error, data);
491 SOSErrorCreate(kSOSErrorUnexpectedType, error, NULL, CFSTR("Expected CFData, got: %@"), data);
498 static bool keybag_and_bool_to_bool_error_request(enum SecXPCOperation op, CFDataRef data, bool include, CFErrorRef* error)
500 secdebug("sosops", "enter - operation: %d", op);
501 return securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
502 xpc_object_t xData = _CFXPCCreateXPCObjectFromCFObject(data);
503 bool success = false;
505 xpc_dictionary_set_value(message, kSecXPCKeyKeybag, xData);
509 xpc_dictionary_set_bool(message, kSecXPCKeyIncludeV0, include);
511 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
512 return xpc_dictionary_get_bool(response, kSecXPCKeyResult);
516 static bool recovery_and_bool_to_bool_error_request(enum SecXPCOperation op, CFDataRef data, CFErrorRef* error)
518 secdebug("sosops", "enter - operation: %d", op);
519 return securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
520 xpc_object_t xData = NULL;
522 xData = _CFXPCCreateXPCObjectFromCFObject(data);
525 CFDataRef nullData = CFDataCreate(kCFAllocatorDefault, &zero, 1);
526 xData = _CFXPCCreateXPCObjectFromCFObject(nullData);
527 CFReleaseNull(nullData);
529 bool success = false;
531 xpc_dictionary_set_value(message, kSecXPCKeyRecoveryPublicKey, xData);
536 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
537 return xpc_dictionary_get_bool(response, kSecXPCKeyResult);
541 static bool info_array_to_bool_error_request(enum SecXPCOperation op, CFArrayRef peer_infos, CFErrorRef* error)
543 __block bool result = false;
545 secdebug("sosops", "enter - operation: %d", op);
546 securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
547 xpc_object_t encoded_peers = CreateXPCObjectWithArrayOfPeerInfo(peer_infos, error);
549 xpc_dictionary_set_value(message, kSecXPCKeyPeerInfoArray, encoded_peers);
550 return encoded_peers != NULL;
551 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
552 result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
558 static bool info_array_data_to_bool_error_request(enum SecXPCOperation op, CFArrayRef peer_infos, CFDataRef parentEvent, CFErrorRef* error)
560 __block bool result = false;
562 secdebug("sosops", "enter - operation: %d", op);
563 securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
564 SecXPCDictionarySetData(message, kSecXPCKeySignInAnalytics, parentEvent, error);
565 xpc_object_t encoded_peers = CreateXPCObjectWithArrayOfPeerInfo(peer_infos, error);
567 xpc_dictionary_set_value(message, kSecXPCKeyPeerInfoArray, encoded_peers);
568 return encoded_peers != NULL;
569 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
570 result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
576 static bool uint64_t_to_bool_error_request(enum SecXPCOperation op,
580 __block bool result = false;
582 securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
583 xpc_dictionary_set_uint64(message, kSecXPCLimitInMinutes, number);
585 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
586 result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
593 static bool cfstring_and_cfdata_to_cfdata_cfdata_error_request(enum SecXPCOperation op, CFStringRef viewName, CFDataRef input, CFDataRef* data, CFDataRef* data2, CFErrorRef* error) {
594 secdebug("sosops", "enter - operation: %d", op);
595 __block bool result = false;
596 securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
597 xpc_object_t xviewname = _CFXPCCreateXPCObjectFromCFObject(viewName);
598 xpc_object_t xinput = _CFXPCCreateXPCObjectFromCFObject(input);
599 bool success = false;
600 if (xviewname && xinput){
601 xpc_dictionary_set_value(message, kSecXPCKeyViewName, xviewname);
602 xpc_dictionary_set_value(message, kSecXPCData, xinput);
608 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
609 result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
611 xpc_object_t temp_result = xpc_dictionary_get_value(response, kSecXPCData);
612 if ((NULL != temp_result) && data) {
613 *data = _CFXPCCreateCFObjectFromXPCObject(temp_result);
615 temp_result = xpc_dictionary_get_value(response, kSecXPCKeyKeybag);
616 if ((NULL != temp_result) && data2) {
617 *data2 = _CFXPCCreateCFObjectFromXPCObject(temp_result);
623 if (data &&!isData(*data)) {
624 SOSErrorCreate(kSOSErrorUnexpectedType, error, NULL, CFSTR("Expected CFData, got: %@"), *data);
626 if (data2 &&!isData(*data2)) {
627 SOSErrorCreate(kSOSErrorUnexpectedType, error, NULL, CFSTR("Expected CFData, got: %@"), *data2);
633 static bool cfdata_and_int_error_request_returns_bool(enum SecXPCOperation op, CFDataRef thedata,
634 PiggyBackProtocolVersion version, CFErrorRef *error) {
635 __block bool result = false;
637 sec_trace_enter_api(NULL);
638 securityd_send_sync_and_do(op, error, ^(xpc_object_t message, CFErrorRef *error) {
639 xpc_object_t xdata = _CFXPCCreateXPCObjectFromCFObject(thedata);
640 bool success = false;
642 xpc_dictionary_set_value(message, kSecXPCData, xdata);
643 xpc_dictionary_set_uint64(message, kSecXPCVersion, version);
649 }, ^(xpc_object_t response, __unused CFErrorRef *error) {
650 result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
657 static CFDataRef cfdata_error_request_returns_cfdata(enum SecXPCOperation op, CFDataRef thedata, CFErrorRef *error) {
658 __block CFDataRef result = NULL;
660 sec_trace_enter_api(NULL);
661 securityd_send_sync_and_do(op, error, ^(xpc_object_t message, CFErrorRef *error) {
662 xpc_object_t xdata = _CFXPCCreateXPCObjectFromCFObject(thedata);
663 bool success = false;
665 xpc_dictionary_set_value(message, kSecXPCData, xdata);
670 }, ^(xpc_object_t response, __unused CFErrorRef *error) {
671 xpc_object_t temp_result = xpc_dictionary_get_value(response, kSecXPCKeyResult);
672 if (response && (NULL != temp_result)) {
673 CFTypeRef object = _CFXPCCreateCFObjectFromXPCObject(temp_result);
674 result = copyIfData(object, error);
675 CFReleaseNull(object);
677 return (bool) (result != NULL);
683 bool SOSCCRequestToJoinCircle(CFErrorRef* error)
685 sec_trace_enter_api(NULL);
686 sec_trace_return_bool_api(^{
687 do_if_registered(soscc_RequestToJoinCircle, error);
689 return simple_bool_error_request(kSecXPCOpRequestToJoin, error);
693 bool SOSCCRequestToJoinCircleWithAnalytics(CFDataRef parentEvent, CFErrorRef* error)
695 sec_trace_enter_api(NULL);
696 sec_trace_return_bool_api(^{
697 do_if_registered(soscc_RequestToJoinCircleWithAnalytics, parentEvent, error);
699 return sfsigninanalytics_bool_error_request(kSecXPCOpRequestToJoinWithAnalytics, parentEvent, error);
703 bool SOSCCRequestToJoinCircleAfterRestore(CFErrorRef* error)
705 sec_trace_enter_api(NULL);
706 sec_trace_return_bool_api(^{
707 do_if_registered(soscc_RequestToJoinCircleAfterRestore, error);
709 return simple_bool_error_request(kSecXPCOpRequestToJoinAfterRestore, error);
713 bool SOSCCRequestToJoinCircleAfterRestoreWithAnalytics(CFDataRef parentEvent, CFErrorRef* error)
715 sec_trace_enter_api(NULL);
716 sec_trace_return_bool_api(^{
717 do_if_registered(soscc_RequestToJoinCircleAfterRestoreWithAnalytics, parentEvent, error);
719 return sfsigninanalytics_bool_error_request(kSecXPCOpRequestToJoinAfterRestoreWithAnalytics, parentEvent, error);
723 bool SOSCCAccountHasPublicKey(CFErrorRef *error)
725 sec_trace_enter_api(NULL);
726 sec_trace_return_bool_api(^{
727 do_if_registered(soscc_AccountHasPublicKey, error);
729 return simple_bool_error_request(kSecXPCOpAccountHasPublicKey, error);
734 bool SOSCCAccountIsNew(CFErrorRef *error)
736 sec_trace_enter_api(NULL);
737 sec_trace_return_bool_api(^{
738 do_if_registered(soscc_AccountIsNew, error);
740 return simple_bool_error_request(kSecXPCOpAccountIsNew, error);
744 bool SOSCCWaitForInitialSyncWithAnalytics(CFDataRef parentEvent, CFErrorRef* error)
746 sec_trace_enter_api(NULL);
747 sec_trace_return_bool_api(^{
748 do_if_registered(soscc_WaitForInitialSyncWithAnalytics, parentEvent, error);
750 return sfsigninanalytics_bool_error_request(kSecXPCOpWaitForInitialSyncWithAnalytics, parentEvent, error);
754 bool SOSCCWaitForInitialSync(CFErrorRef* error)
756 sec_trace_enter_api(NULL);
757 sec_trace_return_bool_api(^{
758 do_if_registered(soscc_WaitForInitialSync, error);
760 return simple_bool_error_request(kSecXPCOpWaitForInitialSync, error);
764 CFArrayRef SOSCCCopyYetToSyncViewsList(CFErrorRef* error)
766 sec_trace_enter_api(NULL);
767 sec_trace_return_api(CFArrayRef, ^{
768 do_if_registered(soscc_CopyYetToSyncViewsList, error);
770 return simple_array_error_request(kSecXPCOpCopyYetToSyncViews, error);
774 bool SOSCCRequestEnsureFreshParameters(CFErrorRef* error)
776 sec_trace_enter_api(NULL);
777 sec_trace_return_bool_api(^{
778 do_if_registered(soscc_RequestEnsureFreshParameters, error);
780 return simple_bool_error_request(kSecXPCOpRequestEnsureFreshParameters, error);
784 CFStringRef SOSCCGetAllTheRings(CFErrorRef *error){
785 sec_trace_enter_api(NULL);
786 sec_trace_return_api(CFStringRef, ^{
787 do_if_registered(soscc_GetAllTheRings, error);
790 return simple_cfstring_error_request(kSecXPCOpGetAllTheRings, error);
793 bool SOSCCApplyToARing(CFStringRef ringName, CFErrorRef* error)
795 sec_trace_enter_api(NULL);
796 sec_trace_return_bool_api(^{
797 do_if_registered(soscc_ApplyToARing, ringName, error);
799 return cfstring_to_error_request(kSecXPCOpApplyToARing, ringName, error);
803 bool SOSCCWithdrawlFromARing(CFStringRef ringName, CFErrorRef* error)
805 sec_trace_enter_api(NULL);
806 sec_trace_return_bool_api(^{
807 do_if_registered(soscc_WithdrawlFromARing, ringName, error);
809 return cfstring_to_error_request(kSecXPCOpWithdrawlFromARing, ringName, error);
813 SOSRingStatus SOSCCRingStatus(CFStringRef ringName, CFErrorRef* error)
815 sec_trace_enter_api(NULL);
816 sec_trace_return_api(SOSRingStatus, ^{
817 do_if_registered(soscc_RingStatus, ringName, error);
819 return cfstring_to_uint64_request(kSecXPCOpRingStatus, ringName, error);
820 }, CFSTR("SOSCCStatus=%d"))
823 bool SOSCCEnableRing(CFStringRef ringName, CFErrorRef* error)
825 sec_trace_enter_api(NULL);
826 sec_trace_return_bool_api(^{
827 do_if_registered(soscc_EnableRing, ringName, error);
829 return cfstring_to_error_request(kSecXPCOpEnableRing, ringName, error);
833 bool SOSCCAccountSetToNew(CFErrorRef *error)
835 secwarning("SOSCCAccountSetToNew called");
836 sec_trace_enter_api(NULL);
837 sec_trace_return_bool_api(^{
838 do_if_registered(soscc_SetToNew, error);
839 return simple_bool_error_request(kSecXPCOpAccountSetToNew, error);
843 bool SOSCCResetToOffering(CFErrorRef* error)
845 secwarning("SOSCCResetToOffering called");
846 sec_trace_enter_api(NULL);
847 sec_trace_return_bool_api(^{
848 do_if_registered(soscc_ResetToOffering, error);
850 return simple_bool_error_request(kSecXPCOpResetToOffering, error);
854 bool SOSCCResetToEmpty(CFErrorRef* error)
856 secwarning("SOSCCResetToEmpty called");
857 sec_trace_enter_api(NULL);
858 sec_trace_return_bool_api(^{
859 do_if_registered(soscc_ResetToEmpty, error);
861 return simple_bool_error_request(kSecXPCOpResetToEmpty, error);
865 bool SOSCCResetToEmptyWithAnalytics(CFDataRef parentEvent, CFErrorRef* error)
867 secwarning("SOSCCResetToEmptyWithAnalytics called");
868 sec_trace_enter_api(NULL);
869 sec_trace_return_bool_api(^{
870 do_if_registered(soscc_ResetToEmptyWithAnalytics, parentEvent, error);
872 return sfsigninanalytics_bool_error_request(kSecXPCOpResetToEmptyWithAnalytics, parentEvent, error);
875 bool SOSCCRemovePeersFromCircle(CFArrayRef peers, CFErrorRef* error)
877 sec_trace_enter_api(NULL);
878 sec_trace_return_bool_api(^{
879 do_if_registered(soscc_RemovePeersFromCircle, peers, error);
881 return info_array_to_bool_error_request(kSecXPCOpRemovePeersFromCircle, peers, error);
885 bool SOSCCRemovePeersFromCircleWithAnalytics(CFArrayRef peers, CFDataRef parentEvent, CFErrorRef* error)
887 sec_trace_enter_api(NULL);
888 sec_trace_return_bool_api(^{
889 do_if_registered(soscc_RemovePeersFromCircleWithAnalytics, peers, parentEvent, error);
891 return info_array_data_to_bool_error_request(kSecXPCOpRemovePeersFromCircleWithAnalytics, peers, parentEvent, error);
895 bool SOSCCRemoveThisDeviceFromCircleWithAnalytics(CFDataRef parentEvent, CFErrorRef* error)
897 sec_trace_enter_api(NULL);
898 sec_trace_return_bool_api(^{
899 do_if_registered(soscc_RemoveThisDeviceFromCircleWithAnalytics, parentEvent, error);
901 return sfsigninanalytics_bool_error_request(kSecXPCOpRemoveThisDeviceFromCircleWithAnalytics, parentEvent, error);
905 bool SOSCCRemoveThisDeviceFromCircle(CFErrorRef* error)
907 sec_trace_enter_api(NULL);
908 sec_trace_return_bool_api(^{
909 do_if_registered(soscc_RemoveThisDeviceFromCircle, error);
911 return simple_bool_error_request(kSecXPCOpRemoveThisDeviceFromCircle, error);
915 bool SOSCCLoggedOutOfAccount(CFErrorRef* error)
917 sec_trace_enter_api(NULL);
918 sec_trace_return_bool_api(^{
919 do_if_registered(soscc_LoggedOutOfAccount, error);
921 return simple_bool_error_request(kSecXPCOpLoggedOutOfAccount, error);
925 bool SOSCCBailFromCircle_BestEffort(uint64_t limit_in_seconds, CFErrorRef* error)
927 sec_trace_enter_api(NULL);
928 sec_trace_return_bool_api(^{
929 do_if_registered(soscc_BailFromCircle, limit_in_seconds, error);
931 return uint64_t_to_bool_error_request(kSecXPCOpBailFromCircle, limit_in_seconds, error);
935 bool SOSCCSignedOut(bool immediate, CFErrorRef* error)
937 uint64_t limit = strtoul(optarg, NULL, 10);
940 return SOSCCRemoveThisDeviceFromCircle(error);
942 return SOSCCBailFromCircle_BestEffort(limit, error);
946 CFArrayRef SOSCCCopyPeerPeerInfo(CFErrorRef* error)
948 sec_trace_enter_api(NULL);
949 sec_trace_return_api(CFArrayRef, ^{
950 do_if_registered(soscc_CopyPeerInfo, error);
952 return array_of_info_error_request(kSecXPCOpCopyPeerPeerInfo, error);
953 }, CFSTR("return=%@"));
956 CFArrayRef SOSCCCopyConcurringPeerPeerInfo(CFErrorRef* error)
958 sec_trace_enter_api(NULL);
959 sec_trace_return_api(CFArrayRef, ^{
960 do_if_registered(soscc_CopyConcurringPeerInfo, error);
962 return array_of_info_error_request(kSecXPCOpCopyConcurringPeerPeerInfo, error);
963 }, CFSTR("return=%@"));
966 CFArrayRef SOSCCCopyGenerationPeerInfo(CFErrorRef* error)
968 sec_trace_enter_api(NULL);
969 sec_trace_return_api(CFArrayRef, ^{
970 do_if_registered(soscc_CopyGenerationPeerInfo, error);
972 return simple_array_error_request(kSecXPCOpCopyGenerationPeerInfo, error);
973 }, CFSTR("return=%@"));
976 CFArrayRef SOSCCCopyApplicantPeerInfo(CFErrorRef* error)
978 sec_trace_enter_api(NULL);
979 sec_trace_return_api(CFArrayRef, ^{
980 do_if_registered(soscc_CopyApplicantPeerInfo, error);
982 return array_of_info_error_request(kSecXPCOpCopyApplicantPeerInfo, error);
983 }, CFSTR("return=%@"));
986 bool SOSCCValidateUserPublic(CFErrorRef* error){
987 sec_trace_enter_api(NULL);
988 sec_trace_return_api(bool, ^{
989 do_if_registered(soscc_ValidateUserPublic, error);
991 return simple_bool_error_request(kSecXPCOpValidateUserPublic, error);
995 CFArrayRef SOSCCCopyValidPeerPeerInfo(CFErrorRef* error)
997 sec_trace_enter_api(NULL);
998 sec_trace_return_api(CFArrayRef, ^{
999 do_if_registered(soscc_CopyValidPeerPeerInfo, error);
1001 return array_of_info_error_request(kSecXPCOpCopyValidPeerPeerInfo, error);
1002 }, CFSTR("return=%@"));
1005 CFArrayRef SOSCCCopyNotValidPeerPeerInfo(CFErrorRef* error)
1007 sec_trace_enter_api(NULL);
1008 sec_trace_return_api(CFArrayRef, ^{
1009 do_if_registered(soscc_CopyNotValidPeerPeerInfo, error);
1011 return array_of_info_error_request(kSecXPCOpCopyNotValidPeerPeerInfo, error);
1012 }, CFSTR("return=%@"));
1015 CFArrayRef SOSCCCopyRetirementPeerInfo(CFErrorRef* error)
1017 sec_trace_enter_api(NULL);
1018 sec_trace_return_api(CFArrayRef, ^{
1019 do_if_registered(soscc_CopyRetirementPeerInfo, error);
1021 return array_of_info_error_request(kSecXPCOpCopyRetirementPeerInfo, error);
1022 }, CFSTR("return=%@"));
1025 CFArrayRef SOSCCCopyViewUnawarePeerInfo(CFErrorRef* error)
1027 sec_trace_enter_api(NULL);
1028 sec_trace_return_api(CFArrayRef, ^{
1029 do_if_registered(soscc_CopyViewUnawarePeerInfo, error);
1031 return array_of_info_error_request(kSecXPCOpCopyViewUnawarePeerInfo, error);
1032 }, CFSTR("return=%@"));
1035 CFDataRef SOSCCCopyAccountState(CFErrorRef* error)
1037 sec_trace_enter_api(NULL);
1038 sec_trace_return_api(CFDataRef, ^{
1039 do_if_registered(soscc_CopyAccountState, error);
1041 return data_to_error_request(kSecXPCOpCopyAccountData, error);
1042 }, CFSTR("return=%@"));
1045 bool SOSCCDeleteAccountState(CFErrorRef *error)
1047 sec_trace_enter_api(NULL);
1048 sec_trace_return_api(bool, ^{
1049 do_if_registered(soscc_DeleteAccountState, error);
1050 return simple_bool_error_request(kSecXPCOpDeleteAccountData, error);
1053 CFDataRef SOSCCCopyEngineData(CFErrorRef* error)
1055 sec_trace_enter_api(NULL);
1056 sec_trace_return_api(CFDataRef, ^{
1057 do_if_registered(soscc_CopyEngineData, error);
1059 return data_to_error_request(kSecXPCOpCopyEngineData, error);
1060 }, CFSTR("return=%@"));
1063 bool SOSCCDeleteEngineState(CFErrorRef *error)
1065 sec_trace_enter_api(NULL);
1066 sec_trace_return_api(bool, ^{
1067 do_if_registered(soscc_DeleteEngineState, error);
1068 return simple_bool_error_request(kSecXPCOpDeleteEngineData, error);
1072 SOSPeerInfoRef SOSCCCopyMyPeerInfo(CFErrorRef *error)
1074 sec_trace_enter_api(NULL);
1075 sec_trace_return_api(SOSPeerInfoRef, ^{
1076 do_if_registered(soscc_CopyMyPeerInfo, error);
1078 return peer_info_error_request(kSecXPCOpCopyMyPeerInfo, error);
1079 }, CFSTR("return=%@"));
1082 static CFArrayRef SOSCCCopyEngineState(CFErrorRef* error)
1084 sec_trace_enter_api(NULL);
1085 sec_trace_return_api(CFArrayRef, ^{
1086 do_if_registered(soscc_CopyEngineState, error);
1088 return der_array_error_request(kSecXPCOpCopyEngineState, error);
1089 }, CFSTR("return=%@"));
1092 CFStringRef kSOSCCEngineStatePeerIDKey = CFSTR("PeerID");
1093 CFStringRef kSOSCCEngineStateManifestCountKey = CFSTR("ManifestCount");
1094 CFStringRef kSOSCCEngineStateSyncSetKey = CFSTR("SyncSet");
1095 CFStringRef kSOSCCEngineStateCoderKey = CFSTR("CoderDump");
1096 CFStringRef kSOSCCEngineStateManifestHashKey = CFSTR("ManifestHash");
1098 void SOSCCForEachEngineStateAsStringFromArray(CFArrayRef states, void (^block)(CFStringRef oneStateString)) {
1100 CFArrayForEach(states, ^(const void *value) {
1101 CFDictionaryRef dict = asDictionary(value, NULL);
1103 CFMutableStringRef description = CFStringCreateMutable(kCFAllocatorDefault, 0);
1105 CFStringRef id = asString(CFDictionaryGetValue(dict, kSOSCCEngineStatePeerIDKey), NULL);
1108 CFStringAppendFormat(description, NULL, CFSTR("remote %@ "), id);
1110 CFStringAppendFormat(description, NULL, CFSTR("local "));
1113 CFSetRef viewSet = asSet(CFDictionaryGetValue(dict, kSOSCCEngineStateSyncSetKey), NULL);
1115 CFStringSetPerformWithDescription(viewSet, ^(CFStringRef setDescription) {
1116 CFStringAppend(description, setDescription);
1119 CFStringAppendFormat(description, NULL, CFSTR("<Missing view set!>"));
1122 CFStringAppendFormat(description, NULL, CFSTR(" [%@]"),
1123 CFDictionaryGetValue(dict, kSOSCCEngineStateManifestCountKey));
1125 CFDataRef mainfestHash = asData(CFDictionaryGetValue(dict, kSOSCCEngineStateManifestHashKey), NULL);
1128 CFDataPerformWithHexString(mainfestHash, ^(CFStringRef dataString) {
1129 CFStringAppendFormat(description, NULL, CFSTR(" %@"), dataString);
1133 CFStringRef coderDescription = asString(CFDictionaryGetValue(dict, kSOSCCEngineStateCoderKey), NULL);
1134 if (coderDescription) {
1135 CFStringAppendFormat(description, NULL, CFSTR(" %@"), coderDescription);
1140 CFReleaseNull(description);
1145 bool SOSCCForEachEngineStateAsString(CFErrorRef* error, void (^block)(CFStringRef oneStateString)) {
1146 CFArrayRef states = SOSCCCopyEngineState(error);
1150 SOSCCForEachEngineStateAsStringFromArray(states, block);
1152 CFReleaseNull(states);
1158 bool SOSCCAcceptApplicants(CFArrayRef applicants, CFErrorRef* error)
1160 sec_trace_enter_api(NULL);
1161 sec_trace_return_bool_api(^{
1162 do_if_registered(soscc_AcceptApplicants, applicants, error);
1164 return info_array_to_bool_error_request(kSecXPCOpAcceptApplicants, applicants, error);
1168 bool SOSCCRejectApplicants(CFArrayRef applicants, CFErrorRef *error)
1170 sec_trace_enter_api(CFSTR("applicants=%@"), applicants);
1171 sec_trace_return_bool_api(^{
1172 do_if_registered(soscc_RejectApplicants, applicants, error);
1174 return info_array_to_bool_error_request(kSecXPCOpRejectApplicants, applicants, error);
1178 static CF_RETURNS_RETAINED SOSPeerInfoRef SOSSetNewPublicBackupKey(CFDataRef pubKey, CFErrorRef *error)
1180 sec_trace_enter_api(NULL);
1181 sec_trace_return_api(SOSPeerInfoRef, ^{
1182 do_if_registered(soscc_SetNewPublicBackupKey, pubKey, error);
1184 return data_to_peer_info_error_request(kSecXPCOpSetNewPublicBackupKey, pubKey, error);
1185 }, CFSTR("return=%@"));
1188 SOSPeerInfoRef SOSCCCopyMyPeerWithNewDeviceRecoverySecret(CFDataRef secret, CFErrorRef *error){
1189 secnotice("devRecovery", "Enter SOSCCCopyMyPeerWithNewDeviceRecoverySecret()");
1190 CFDataRef publicKeyData = SOSCopyDeviceBackupPublicKey(secret, error);
1191 secnotice("devRecovery", "SOSCopyDeviceBackupPublicKey (%@)", publicKeyData);
1192 SOSPeerInfoRef copiedPeer = publicKeyData ? SOSSetNewPublicBackupKey(publicKeyData, error) : NULL;
1193 secnotice("devRecovery", "SOSSetNewPublicBackupKey (%@)", copiedPeer);
1194 CFReleaseNull(publicKeyData);
1198 bool SOSCCRegisterSingleRecoverySecret(CFDataRef aks_bag, bool forV0Only, CFErrorRef *error){
1199 sec_trace_enter_api(NULL);
1200 sec_trace_return_bool_api(^{
1201 do_if_registered(soscc_RegisterSingleRecoverySecret, aks_bag, forV0Only, error);
1202 return keybag_and_bool_to_bool_error_request(kSecXPCOpSetBagForAllSlices, aks_bag, forV0Only, error);
1207 bool SOSCCRegisterRecoveryPublicKey(CFDataRef recovery_key, CFErrorRef *error){
1208 sec_trace_enter_api(NULL);
1209 sec_trace_return_bool_api(^{
1210 bool retval = false;
1211 do_if_registered(soscc_RegisterRecoveryPublicKey, recovery_key, error);
1212 // NULL recovery_key is handled in recovery_and_bool_to_bool_error_request now.
1213 retval = recovery_and_bool_to_bool_error_request(kSecXPCOpRegisterRecoveryPublicKey, recovery_key, error);
1218 CFDataRef SOSCCCopyRecoveryPublicKey(CFErrorRef *error){
1219 sec_trace_enter_api(NULL);
1220 sec_trace_return_api(CFDataRef, ^{
1221 do_if_registered(soscc_CopyRecoveryPublicKey, error);
1222 return data_to_error_request(kSecXPCOpGetRecoveryPublicKey, error);
1223 }, CFSTR("return=%@"));
1225 static bool label_and_password_to_bool_error_request(enum SecXPCOperation op,
1226 CFStringRef user_label, CFDataRef user_password,
1229 __block bool result = false;
1231 securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
1232 CFStringPerformWithCString(user_label, ^(const char *utf8Str) {
1233 xpc_dictionary_set_string(message, kSecXPCKeyUserLabel, utf8Str);
1235 xpc_dictionary_set_data(message, kSecXPCKeyUserPassword, CFDataGetBytePtr(user_password), CFDataGetLength(user_password));
1237 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
1238 result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
1245 static bool label_and_password_and_dsid_to_bool_error_request(enum SecXPCOperation op,
1246 CFStringRef user_label, CFDataRef user_password,
1247 CFStringRef dsid, CFDataRef parentEvent, CFErrorRef* error)
1249 __block bool result = false;
1251 securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
1252 CFStringPerformWithCString(user_label, ^(const char *utf8Str) {
1253 xpc_dictionary_set_string(message, kSecXPCKeyUserLabel, utf8Str);
1255 CFStringPerformWithCString(dsid, ^(const char *utr8StrDSID) {
1256 xpc_dictionary_set_string(message, kSecXPCKeyDSID, utr8StrDSID);
1258 xpc_dictionary_set_data(message, kSecXPCKeyUserPassword, CFDataGetBytePtr(user_password), CFDataGetLength(user_password));
1260 SecXPCDictionarySetData(message, kSecXPCKeySignInAnalytics, parentEvent, error);
1263 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
1264 result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
1271 bool SOSCCRegisterUserCredentials(CFStringRef user_label, CFDataRef user_password, CFErrorRef* error)
1273 secnotice("circleOps", "SOSCCRegisterUserCredentials - calling SOSCCSetUserCredentials for %@\n", user_label);
1274 return SOSCCSetUserCredentials(user_label, user_password, error);
1277 bool SOSCCSetUserCredentials(CFStringRef user_label, CFDataRef user_password, CFErrorRef* error)
1279 secnotice("circleOps", "SOSCCSetUserCredentials for %@\n", user_label);
1280 sec_trace_enter_api(CFSTR("user_label=%@"), user_label);
1281 sec_trace_return_bool_api(^{
1282 do_if_registered(soscc_SetUserCredentials, user_label, user_password, error);
1284 return label_and_password_to_bool_error_request(kSecXPCOpSetUserCredentials, user_label, user_password, error);
1288 bool SOSCCSetUserCredentialsAndDSID(CFStringRef user_label, CFDataRef user_password, CFStringRef dsid, CFErrorRef *error)
1290 secnotice("circleOps", "SOSCCSetUserCredentialsAndDSID for %@\n", user_label);
1291 sec_trace_enter_api(CFSTR("user_label=%@"), user_label);
1292 sec_trace_return_bool_api(^{
1293 do_if_registered(soscc_SetUserCredentialsAndDSID, user_label, user_password, dsid, error);
1295 bool result = false;
1296 __block CFStringRef account_dsid = dsid;
1298 require_action_quiet(user_label, out, SOSErrorCreate(kSOSErrorParam, error, NULL, CFSTR("user_label is nil")));
1299 require_action_quiet(user_password, out, SOSErrorCreate(kSOSErrorParam, error, NULL, CFSTR("user_password is nil")));
1301 if(account_dsid == NULL){
1302 account_dsid = CFSTR("");
1304 return label_and_password_and_dsid_to_bool_error_request(kSecXPCOpSetUserCredentialsAndDSID, user_label, user_password, account_dsid, nil, error);
1311 bool SOSCCSetUserCredentialsAndDSIDWithAnalytics(CFStringRef user_label, CFDataRef user_password, CFStringRef dsid, CFDataRef parentEvent, CFErrorRef *error)
1313 secnotice("circleOps", "SOSCCSetUserCredentialsAndDSIDWithAnalytics for %@\n", user_label);
1314 sec_trace_enter_api(CFSTR("user_label=%@"), user_label);
1315 sec_trace_return_bool_api(^{
1316 do_if_registered(soscc_SetUserCredentialsAndDSIDWithAnalytics, user_label, user_password, dsid, parentEvent, error);
1318 bool result = false;
1319 __block CFStringRef account_dsid = dsid;
1321 require_action_quiet(user_label, out, SOSErrorCreate(kSOSErrorParam, error, NULL, CFSTR("user_label is nil")));
1322 require_action_quiet(user_password, out, SOSErrorCreate(kSOSErrorParam, error, NULL, CFSTR("user_password is nil")));
1324 if(account_dsid == NULL){
1325 account_dsid = CFSTR("");
1327 return label_and_password_and_dsid_to_bool_error_request(kSecXPCOpSetUserCredentialsAndDSIDWithAnalytics, user_label, user_password, account_dsid, parentEvent, error);
1334 static bool SOSCCTryUserCredentialsAndDSID_internal(CFStringRef user_label, CFDataRef user_password, CFStringRef dsid, CFErrorRef *error) {
1335 sec_trace_return_bool_api(^{
1336 do_if_registered(soscc_TryUserCredentials, user_label, user_password, dsid, error);
1338 bool result = false;
1339 __block CFStringRef account_dsid = dsid;
1341 require_action_quiet(user_label, out, SOSErrorCreate(kSOSErrorParam, error, NULL, CFSTR("user_label is nil")));
1342 require_action_quiet(user_password, out, SOSErrorCreate(kSOSErrorParam, error, NULL, CFSTR("user_password is nil")));
1344 if(account_dsid == NULL){
1345 account_dsid = CFSTR("");
1348 return label_and_password_and_dsid_to_bool_error_request(kSecXPCOpTryUserCredentials, user_label, user_password, account_dsid, nil, error);
1356 bool SOSCCTryUserCredentialsAndDSID(CFStringRef user_label, CFDataRef user_password, CFStringRef dsid, CFErrorRef *error)
1358 secnotice("sosops", "SOSCCTryUserCredentialsAndDSID!! %@\n", user_label);
1359 require_action_quiet(user_label, out, SOSErrorCreate(kSOSErrorParam, error, NULL, CFSTR("user_label is nil")));
1360 require_action_quiet(user_password, out, SOSErrorCreate(kSOSErrorParam, error, NULL, CFSTR("user_password is nil")));
1361 CFStringRef account_dsid = (dsid != NULL) ? dsid: CFSTR("");
1362 return SOSCCTryUserCredentialsAndDSID_internal(user_label, user_password, account_dsid, error);
1367 bool SOSCCTryUserCredentials(CFStringRef user_label, CFDataRef user_password, CFErrorRef* error) {
1368 return SOSCCTryUserCredentialsAndDSID_internal(user_label, user_password, NULL, error);
1372 bool SOSCCCanAuthenticate(CFErrorRef* error) {
1373 sec_trace_enter_api(NULL);
1374 sec_trace_return_bool_api(^{
1375 do_if_registered(soscc_CanAuthenticate, error);
1377 return simple_bool_error_request(kSecXPCOpCanAuthenticate, error);
1381 bool SOSCCPurgeUserCredentials(CFErrorRef* error) {
1382 sec_trace_enter_api(NULL);
1383 sec_trace_return_bool_api(^{
1384 do_if_registered(soscc_PurgeUserCredentials, error);
1386 return simple_bool_error_request(kSecXPCOpPurgeUserCredentials, error);
1390 enum DepartureReason SOSCCGetLastDepartureReason(CFErrorRef *error) {
1391 sec_trace_enter_api(NULL);
1392 sec_trace_return_api(enum DepartureReason, ^{
1393 do_if_registered(soscc_GetLastDepartureReason, error);
1395 return (enum DepartureReason) simple_int_error_request(kSecXPCOpGetLastDepartureReason, error);
1399 bool SOSCCSetLastDepartureReason(enum DepartureReason reason, CFErrorRef *error) {
1400 sec_trace_enter_api(NULL);
1401 sec_trace_return_api(bool, ^{
1402 do_if_registered(soscc_SetLastDepartureReason, reason, error);
1403 return securityd_send_sync_and_do(kSecXPCOpSetLastDepartureReason, error,
1404 ^bool(xpc_object_t message, CFErrorRef *error) {
1405 xpc_dictionary_set_int64(message, kSecXPCKeyReason, reason);
1408 ^bool(xpc_object_t response, __unused CFErrorRef *error) {
1409 return xpc_dictionary_get_bool(response, kSecXPCKeyResult);
1415 CFStringRef SOSCCCopyIncompatibilityInfo(CFErrorRef* error) {
1416 sec_trace_enter_api(NULL);
1417 sec_trace_return_api(CFStringRef, ^{
1418 do_if_registered(soscc_CopyIncompatibilityInfo, error);
1420 return simple_cfstring_error_request(kSecXPCOpCopyIncompatibilityInfo, error);
1424 bool SOSCCProcessEnsurePeerRegistration(CFErrorRef* error){
1425 secnotice("updates", "enter SOSCCProcessEnsurePeerRegistration");
1426 sec_trace_enter_api(NULL);
1427 sec_trace_return_bool_api(^{
1428 do_if_registered(soscc_EnsurePeerRegistration, error);
1430 return simple_bool_error_request(soscc_EnsurePeerRegistration_id, error);
1435 CFSetRef /* CFString */ SOSCCProcessSyncWithPeers(CFSetRef peers, CFSetRef backupPeers, CFErrorRef* error)
1437 sec_trace_enter_api(NULL);
1438 sec_trace_return_api(CFSetRef, ^{
1439 do_if_registered(soscc_ProcessSyncWithPeers, peers, backupPeers, error);
1441 return cfset_cfset_to_cfset_error_request(kSecXPCOpProcessSyncWithPeers, peers, backupPeers, error);
1446 SyncWithAllPeersReason SOSCCProcessSyncWithAllPeers(CFErrorRef* error)
1448 sec_trace_enter_api(NULL);
1449 sec_trace_return_api(SyncWithAllPeersReason, ^{
1450 do_if_registered(soscc_ProcessSyncWithAllPeers, error);
1452 return (SyncWithAllPeersReason) simple_int_error_request(kSecXPCOpProcessSyncWithAllPeers, error);
1456 CFStringRef SOSCCGetStatusDescription(SOSCCStatus status)
1459 case kSOSCCInCircle:
1460 return CFSTR("InCircle");
1461 case kSOSCCNotInCircle:
1462 return CFSTR("NotInCircle");
1463 case kSOSCCRequestPending:
1464 return CFSTR("RequestPending");
1465 case kSOSCCCircleAbsent:
1466 return CFSTR("CircleAbsent");
1468 return CFSTR("InternalError");
1470 return CFSTR("Unknown Status");
1475 CFStringRef SOSCCGetViewResultDescription(SOSViewResultCode vrc)
1478 case kSOSCCGeneralViewError:
1479 return CFSTR("GeneralViewError");
1480 case kSOSCCViewMember:
1481 return CFSTR("ViewMember");
1482 case kSOSCCViewNotMember:
1483 return CFSTR("ViewNotMember");
1484 case kSOSCCViewNotQualified:
1485 return CFSTR("ViewNotQualified");
1486 case kSOSCCNoSuchView:
1487 return CFSTR("ViewUndefined");
1489 return CFSTR("Unknown View Status");
1494 static int64_t name_action_to_code_request(enum SecXPCOperation op, uint16_t error_result,
1495 CFStringRef name, uint64_t action, CFErrorRef *error) {
1496 __block int64_t result = error_result;
1498 securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
1499 CFStringPerformWithCString(name, ^(const char *utf8Str) {
1500 xpc_dictionary_set_string(message, kSecXPCKeyViewName, utf8Str);
1502 xpc_dictionary_set_int64(message, kSecXPCKeyViewActionCode, action);
1504 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
1505 if (response && xpc_dictionary_entry_is_type(response, kSecXPCKeyResult, XPC_TYPE_INT64)) {
1506 result = xpc_dictionary_get_int64(response, kSecXPCKeyResult);
1508 return result != error_result;
1514 SOSViewResultCode SOSCCView(CFStringRef view, SOSViewActionCode actionCode, CFErrorRef *error) {
1515 if(actionCode == kSOSCCViewQuery) {
1516 uint64_t circleStat = SOSGetCachedCircleBitmask();
1517 if(circleStat & CC_STATISVALID) {
1518 SOSViewResultCode retval = kSOSCCViewNotMember;
1519 CFSetRef enabledViews = SOSCreateCachedViewStatus();
1521 if(CFSetContainsValue(enabledViews, view)) {
1522 retval = kSOSCCViewMember;
1524 retval = kSOSCCViewNotMember;
1526 CFReleaseNull(enabledViews);
1531 sec_trace_enter_api(NULL);
1532 sec_trace_return_api(SOSViewResultCode, ^{
1533 do_if_registered(soscc_View, view, actionCode, error);
1535 return (SOSViewResultCode) name_action_to_code_request(kSecXPCOpView, kSOSCCGeneralViewError, view, actionCode, error);
1536 }, CFSTR("SOSViewResultCode=%d"))
1540 bool SOSCCViewSet(CFSetRef enabledViews, CFSetRef disabledViews) {
1541 CFErrorRef *error = NULL;
1542 __block bool result = false;
1544 sec_trace_enter_api(NULL);
1545 sec_trace_return_bool_api(^{
1546 do_if_registered(soscc_ViewSet, enabledViews, disabledViews);
1547 return securityd_send_sync_and_do(kSecXPCOpViewSet, error, ^bool(xpc_object_t message, CFErrorRef *error) {
1548 xpc_object_t enabledSetXpc = CreateXPCObjectWithCFSetRef(enabledViews, error);
1549 xpc_object_t disabledSetXpc = CreateXPCObjectWithCFSetRef(disabledViews, error);
1550 if (enabledSetXpc) xpc_dictionary_set_value(message, kSecXPCKeyEnabledViewsKey, enabledSetXpc);
1551 if (disabledSetXpc) xpc_dictionary_set_value(message, kSecXPCKeyDisabledViewsKey, disabledSetXpc);
1552 return (enabledSetXpc != NULL) || (disabledSetXpc != NULL) ;
1553 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
1554 result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
1560 bool SOSCCViewSetWithAnalytics(CFSetRef enabledViews, CFSetRef disabledViews, CFDataRef parentEvent) {
1561 CFErrorRef *error = NULL;
1562 __block bool result = false;
1564 sec_trace_enter_api(NULL);
1565 sec_trace_return_bool_api(^{
1566 do_if_registered(soscc_ViewSetWithAnalytics, enabledViews, disabledViews, parentEvent);
1567 return securityd_send_sync_and_do(kSecXPCOpViewSetWithAnalytics, error, ^bool(xpc_object_t message, CFErrorRef *error) {
1568 xpc_object_t enabledSetXpc = CreateXPCObjectWithCFSetRef(enabledViews, error);
1569 xpc_object_t disabledSetXpc = CreateXPCObjectWithCFSetRef(disabledViews, error);
1570 if (enabledSetXpc) xpc_dictionary_set_value(message, kSecXPCKeyEnabledViewsKey, enabledSetXpc);
1571 if (disabledSetXpc) xpc_dictionary_set_value(message, kSecXPCKeyDisabledViewsKey, disabledSetXpc);
1572 if(parentEvent) SecXPCDictionarySetData(message, kSecXPCKeySignInAnalytics, parentEvent, error);
1573 return (enabledSetXpc != NULL) || (disabledSetXpc != NULL) ;
1574 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
1575 result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
1581 static CFStringRef copyViewNames(size_t n, CFStringRef *views) {
1582 CFMutableStringRef retval = CFStringCreateMutable(kCFAllocatorDefault, 0);
1583 CFStringAppend(retval, CFSTR("|"));
1584 for(size_t i = 0; i < n; i++) {
1585 CFStringAppend(retval, views[i]);
1586 CFStringAppend(retval, CFSTR("|"));
1591 static bool sosIsViewSetSyncing(size_t n, CFStringRef *views) {
1592 __block bool retval = true;
1593 CFErrorRef error = NULL;
1595 if(n == 0 || views == NULL) return false;
1596 CFStringRef viewString = copyViewNames(n, views);
1598 SOSCCStatus cstatus = SOSCCThisDeviceIsInCircle(&error);
1599 if(cstatus != kSOSCCInCircle) {
1600 secnotice("viewCheck", "Checking view / circle status for %@: SOSCCStatus: (%@) Error: (%@)", viewString, SOSCCGetStatusDescription(cstatus), error);
1604 if(retval == true) {
1605 // use cached values if valid
1606 uint64_t circleStat = SOSGetCachedCircleBitmask();
1607 if(circleStat & CC_STATISVALID) {
1608 CFSetRef enabledViews = SOSCreateCachedViewStatus();
1610 for(size_t i = 0; i < n; i++) {
1611 if(!CFSetContainsValue(enabledViews, views[i])) {
1615 CFReleaseNull(enabledViews);
1616 CFReleaseNull(viewString);
1621 // make the individual calls otherwise.
1622 for(size_t i = 0; i < n; i++) {
1623 SOSViewResultCode vstatus = SOSCCView(views[i], kSOSCCViewQuery, &error);
1624 if(vstatus != kSOSCCViewMember) {
1625 secnotice("viewCheck", "Checking view / circle status for %@: SOSCCStatus: (%@) SOSViewResultCode(%@) Error: (%@)", views[i],
1626 SOSCCGetStatusDescription(cstatus), SOSCCGetViewResultDescription(vstatus), error);
1632 if(retval == true) {
1633 secnotice("viewCheck", "Checking view / circle status for %@: ENABLED", viewString);
1635 CFReleaseNull(error);
1636 CFReleaseNull(viewString);
1640 bool SOSCCIsIcloudKeychainSyncing(void) {
1641 CFStringRef views[] = { kSOSViewWiFi, kSOSViewAutofillPasswords, kSOSViewSafariCreditCards, kSOSViewOtherSyncable };
1642 return sosIsViewSetSyncing(sizeof(views)/sizeof(views[0]), views);
1645 bool SOSCCIsSafariSyncing(void) {
1646 CFStringRef views[] = { kSOSViewAutofillPasswords, kSOSViewSafariCreditCards };
1647 return sosIsViewSetSyncing(sizeof(views)/sizeof(views[0]), views);
1650 bool SOSCCIsAppleTVSyncing(void) {
1651 CFStringRef views[] = { kSOSViewAppleTV };
1652 return sosIsViewSetSyncing(sizeof(views)/sizeof(views[0]), views);
1655 bool SOSCCIsHomeKitSyncing(void) {
1656 CFStringRef views[] = { kSOSViewHomeKit };
1657 return sosIsViewSetSyncing(sizeof(views)/sizeof(views[0]), views);
1660 bool SOSCCIsWiFiSyncing(void) {
1661 CFStringRef views[] = { kSOSViewWiFi };
1662 return sosIsViewSetSyncing(sizeof(views)/sizeof(views[0]), views);
1665 bool SOSCCIsContinuityUnlockSyncing(void) {
1666 CFStringRef views[] = { kSOSViewContinuityUnlock };
1667 return sosIsViewSetSyncing(sizeof(views)/sizeof(views[0]), views);
1671 bool SOSCCSetEscrowRecord(CFStringRef escrow_label, uint64_t tries, CFErrorRef *error ){
1672 secnotice("escrow", "enter SOSCCSetEscrowRecord");
1673 sec_trace_enter_api(NULL);
1674 sec_trace_return_bool_api(^{
1675 do_if_registered(soscc_SetEscrowRecords, escrow_label, tries, error);
1677 return escrow_to_bool_error_request(kSecXPCOpSetEscrowRecord, escrow_label, tries, error);
1681 CFDictionaryRef SOSCCCopyEscrowRecord(CFErrorRef *error){
1682 secnotice("escrow", "enter SOSCCCopyEscrowRecord");
1683 sec_trace_enter_api(NULL);
1684 sec_trace_return_api(CFDictionaryRef, ^{
1685 do_if_registered(soscc_CopyEscrowRecords, error);
1687 return strings_to_dictionary_error_request(kSecXPCOpGetEscrowRecord, error);
1688 }, CFSTR("return=%@"))
1692 CFDictionaryRef SOSCCCopyBackupInformation(CFErrorRef *error) {
1693 secnotice("escrow", "enter SOSCCCopyBackupInformation");
1694 sec_trace_enter_api(NULL);
1695 sec_trace_return_api(CFDictionaryRef, ^{
1696 do_if_registered(soscc_CopyBackupInformation, error);
1697 return strings_to_dictionary_error_request(kSecXPCOpCopyBackupInformation, error);
1698 }, CFSTR("return=%@"))
1701 bool SOSWrapToBackupSliceKeyBagForView(CFStringRef viewName, CFDataRef input, CFDataRef* output, CFDataRef* bskbEncoded, CFErrorRef* error) {
1702 sec_trace_enter_api(NULL);
1703 sec_trace_return_bool_api(^{
1704 do_if_registered(sosbskb_WrapToBackupSliceKeyBagForView, viewName, input, output, bskbEncoded, error);
1706 return cfstring_and_cfdata_to_cfdata_cfdata_error_request(kSecXPCOpWrapToBackupSliceKeyBagForView, viewName, input, output, bskbEncoded, error);
1711 SOSPeerInfoRef SOSCCCopyApplication(CFErrorRef *error) {
1712 secnotice("hsa2PB", "enter SOSCCCopyApplication applicant");
1713 sec_trace_enter_api(NULL);
1715 sec_trace_return_api(SOSPeerInfoRef, ^{
1716 do_if_registered(soscc_CopyApplicant, error);
1717 return peer_info_error_request(kSecXPCOpCopyApplication, error);
1718 }, CFSTR("return=%@"));
1721 bool SOSCCCleanupKVSKeys(CFErrorRef *error) {
1722 secnotice("cleanup-keys", "enter SOSCCCleanupKVSKeys");
1723 sec_trace_enter_api(NULL);
1724 sec_trace_return_bool_api(^{
1725 do_if_registered(soscc_SOSCCCleanupKVSKeys, error);
1727 return simple_bool_error_request(kSecXPCOpKVSKeyCleanup, error);
1733 bool SOSCCTestPopulateKVSWithBadKeys(CFErrorRef *error) {
1734 secnotice("cleanup-keys", "enter SOSCCPopulateKVSWithBadKeys");
1735 sec_trace_enter_api(NULL);
1736 sec_trace_return_bool_api(^{
1737 do_if_registered(soscc_SOSCCTestPopulateKVSWithBadKeys, error);
1739 return simple_bool_error_request(kSecXPCOpPopulateKVS, error);
1745 CFDataRef SOSCCCopyCircleJoiningBlob(SOSPeerInfoRef applicant, CFErrorRef *error) {
1746 secnotice("hsa2PB", "enter SOSCCCopyCircleJoiningBlob approver");
1747 sec_trace_enter_api(NULL);
1749 sec_trace_return_api(CFDataRef, ^{
1750 CFDataRef result = NULL;
1751 do_if_registered(soscc_CopyCircleJoiningBlob, applicant, error);
1752 CFDataRef piData = SOSPeerInfoCopyEncodedData(applicant, kCFAllocatorDefault, error);
1753 result = cfdata_error_request_returns_cfdata(kSecXPCOpCopyCircleJoiningBlob, piData, error);
1754 CFReleaseNull(piData);
1756 }, CFSTR("return=%@"));
1759 CFDataRef SOSCCCopyInitialSyncData(SOSInitialSyncFlags flags, CFErrorRef *error) {
1760 secnotice("circleJoin", "enter SOSCCCopyInitialSyncData approver");
1761 sec_trace_enter_api(NULL);
1763 sec_trace_return_api(CFDataRef, ^{
1764 do_if_registered(soscc_CopyInitialSyncData, flags, error);
1765 return flags_to_data_error_request(kSecXPCOpCopyInitialSyncBlob, flags, error);
1766 }, CFSTR("return=%@"));
1769 bool SOSCCJoinWithCircleJoiningBlob(CFDataRef joiningBlob, PiggyBackProtocolVersion version, CFErrorRef *error) {
1770 secnotice("hsa2PB", "enter SOSCCJoinWithCircleJoiningBlob applicant");
1771 sec_trace_enter_api(NULL);
1772 sec_trace_return_bool_api(^{
1773 do_if_registered(soscc_JoinWithCircleJoiningBlob, joiningBlob, version, error);
1775 return cfdata_and_int_error_request_returns_bool(kSecXPCOpJoinWithCircleJoiningBlob, joiningBlob, version, error);
1779 bool SOSCCIsThisDeviceLastBackup(CFErrorRef *error) {
1780 secnotice("peer", "enter SOSCCIsThisDeviceLastBackup");
1781 sec_trace_enter_api(NULL);
1782 sec_trace_return_bool_api(^{
1783 do_if_registered(soscc_IsThisDeviceLastBackup, error);
1785 return simple_bool_error_request(kSecXPCOpIsThisDeviceLastBackup, error);
1789 CFBooleanRef SOSCCPeersHaveViewsEnabled(CFArrayRef viewNames, CFErrorRef *error) {
1790 secnotice("view-enabled", "enter SOSCCPeersHaveViewsEnabled");
1791 sec_trace_enter_api(NULL);
1792 sec_trace_return_api(CFBooleanRef, ^{
1793 do_if_registered(soscc_SOSCCPeersHaveViewsEnabled, viewNames, error);
1795 return cfarray_to_cfboolean_error_request(kSecXPCOpPeersHaveViewsEnabled, viewNames, error);
1796 }, CFSTR("return=%@"))
1799 bool SOSCCMessageFromPeerIsPending(SOSPeerInfoRef peer, CFErrorRef *error) {
1800 secnotice("pending-check", "enter SOSCCMessageFromPeerIsPending");
1802 sec_trace_return_bool_api(^{
1803 do_if_registered(soscc_SOSCCMessageFromPeerIsPending, peer, error);
1805 return peer_info_to_bool_error_request(kSecXPCOpMessageFromPeerIsPending, peer, error);
1810 bool SOSCCSendToPeerIsPending(SOSPeerInfoRef peer, CFErrorRef *error) {
1811 sec_trace_return_bool_api(^{
1812 do_if_registered(soscc_SOSCCSendToPeerIsPending, peer, error);
1814 return peer_info_to_bool_error_request(kSecXPCOpSendToPeerIsPending, peer, error);
1819 * SecSOSStatus interfaces
1822 @interface SecSOSStatus : NSObject {
1823 NSXPCConnection* _connection;
1825 @property NSXPCConnection *connection;
1828 @implementation SecSOSStatus
1829 @synthesize connection = _connection;
1831 - (instancetype) init
1833 if ((self = [super init]) == NULL)
1836 NSXPCInterface *interface = [NSXPCInterface interfaceWithProtocol:@protocol(SOSControlProtocol)];
1837 _SOSControlSetupInterface(interface);
1839 self.connection = [[NSXPCConnection alloc] initWithMachServiceName:@(kSecuritydSOSServiceName) options:0];
1840 if (self.connection == NULL){
1843 self.connection.remoteObjectInterface = interface;
1845 [self.connection resume];
1852 static id<SOSControlProtocol>
1853 SOSCCGetStatusObject(CFErrorRef *error)
1855 if (gSecurityd && gSecurityd->soscc_status)
1856 return (__bridge id<SOSControlProtocol>)gSecurityd->soscc_status();
1858 static SecSOSStatus *control;
1859 static dispatch_once_t onceToken;
1860 dispatch_once(&onceToken, ^{
1861 control = [[SecSOSStatus alloc] init];
1863 return control.connection.remoteObjectProxy;
1867 static id<SOSControlProtocol>
1868 SOSCCGetSynchronousStatusObject(CFErrorRef *cferror) {
1869 if (gSecurityd && gSecurityd->soscc_status)
1870 return (__bridge id<SOSControlProtocol>)gSecurityd->soscc_status();
1872 static SecSOSStatus *control;
1873 static dispatch_once_t onceToken;
1874 dispatch_once(&onceToken, ^{
1875 control = [[SecSOSStatus alloc] init];
1878 __block NSError *localError = nil;
1879 id <SOSControlProtocol> synchronousRemoteObject = [control.connection synchronousRemoteObjectProxyWithErrorHandler:^(NSError *error) {
1880 secnotice("ghostbust", "An error occurred on the xpc connection to setup the background session: %@", error );
1885 if(cferror && localError) {
1886 *cferror = (__bridge CFErrorRef)(localError);
1888 return synchronousRemoteObject;
1894 SOSCCAccountGetPublicKey(void (^reply)(BOOL trusted, NSData *data, NSError *error))
1896 CFErrorRef error = NULL;
1897 id<SOSControlProtocol> status = SOSCCGetStatusObject(&error);
1898 if (status == NULL) {
1899 reply(false, NULL, (__bridge NSError *)error);
1900 CFReleaseNull(error);
1904 [status userPublicKey:reply];
1908 SOSCCAccountGetAccountPrivateCredential(void (^complete)(NSData *data, NSError *error))
1910 CFErrorRef error = NULL;
1911 id<SOSControlProtocol> status = SOSCCGetStatusObject(&error);
1912 if (status == NULL) {
1913 complete(NULL, (__bridge NSError *)error);
1914 CFReleaseNull(error);
1918 [status validatedStashedAccountCredential:complete];
1922 SOSCCAccountGetKeyCircleGeneration(void (^reply)(NSData *data, NSError *error))
1924 SOSCCAccountGetPublicKey(^(BOOL __unused trusted, NSData *data, NSError *error){
1928 NSMutableData *digest = [NSMutableData dataWithLength:CCSHA256_OUTPUT_SIZE];
1929 ccdigest(ccsha256_di(), [data length], [data bytes], [digest mutableBytes]);
1930 reply(digest, error);
1936 SOSCCCircleHash(NSError **error)
1938 CFErrorRef cferror = NULL;
1939 id<SOSControlProtocol> status = SOSCCGetSynchronousStatusObject(&cferror);
1940 if (status == NULL) {
1942 *error = (__bridge NSError *)cferror;
1944 CFReleaseNull(cferror);
1947 __block NSString *hash = NULL;
1948 [status circleHash:^(NSString *circleHash, NSError *error) {
1957 SOSCCGhostBust(SOSAccountGhostBustingOptions options, void (^complete)(bool ghostsBusted, NSError *error)) {
1958 CFErrorRef error = NULL;
1959 id<SOSControlProtocol> status = SOSCCGetSynchronousStatusObject(&error);
1960 if (status == NULL) {
1961 complete(false, (__bridge NSError *)error);
1962 CFReleaseNull(error);
1965 secnotice("ghostbust", "API Called");
1966 [status ghostBust:options complete:^(bool ghostBusted, NSError *error) {
1967 secnotice("ghostbust", "API returned: %d", ghostBusted);
1968 complete(ghostBusted, error);
1972 void SOSCCGhostBustTriggerTimed(SOSAccountGhostBustingOptions options, void (^complete)(bool ghostsBusted, NSError *error)) {
1973 CFErrorRef error = NULL;
1974 id<SOSControlProtocol> status = SOSCCGetSynchronousStatusObject(&error);
1975 if (status == NULL) {
1976 complete(false, (__bridge NSError *)error);
1977 CFReleaseNull(error);
1980 secnotice("ghostbust", "API Trigger Timed Called");
1981 [status ghostBustTriggerTimed:options complete:^(bool ghostBusted, NSError *error) {
1982 secnotice("ghostbust", "API Trigger Timed returned: %d", ghostBusted);
1983 complete(ghostBusted, error);
1987 void SOSCCGhostBustInfo(void (^complete)(NSData *json, NSError *error)) {
1988 CFErrorRef error = NULL;
1989 id<SOSControlProtocol> status = SOSCCGetSynchronousStatusObject(&error);
1990 if (status == NULL) {
1991 complete(false, (__bridge NSError *)error);
1992 CFReleaseNull(error);
1995 secnotice("ghostbust", "API Info Called");
1996 [status ghostBustInfo:^(NSData *json, NSError *error) {
1997 secnotice("ghostbust", "API Info returned");
1998 complete(json, error);