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 <Security/SecureObjectSync/SOSCloudCircle.h>
34 #include <Security/SecureObjectSync/SOSCloudCircleInternal.h>
35 #include <Security/SecureObjectSync/SOSCircle.h>
36 #include <Security/SecureObjectSync/SOSAccount.h>
37 #include <Security/SecureObjectSync/SOSFullPeerInfo.h>
38 #include <Security/SecureObjectSync/SOSPeerInfoCollections.h>
39 #include <Security/SecureObjectSync/SOSInternal.h>
40 #include <Security/SecureObjectSync/SOSRing.h>
41 #include <Security/SecureObjectSync/SOSBackupSliceKeyBag.h>
42 #include <Security/SecureObjectSync/SOSViews.h>
43 #include <Security/SecureObjectSync/SOSControlHelper.h>
45 #include <Security/SecKeyPriv.h>
46 #include <Security/SecFramework.h>
47 #include <CoreFoundation/CFXPCBridge.h>
49 #include <securityd/SecItemServer.h>
51 #include <utilities/SecDispatchRelease.h>
52 #include <utilities/SecCFRelease.h>
53 #include <utilities/SecCFWrappers.h>
54 #include <utilities/SecXPCError.h>
56 #include <corecrypto/ccsha2.h>
58 #include <utilities/debugging.h>
60 #include <CoreFoundation/CoreFoundation.h>
63 #define MINIMIZE_INCLUDES MINIMIZE_INCLUDES
64 #include <ipc/securityd_client.h>
65 #include <securityd/spi.h>
67 #include <Security/SecuritydXPC.h>
68 #include "SOSPeerInfoDER.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 sec_trace_enter_api(NULL);
90 sec_trace_return_api(SOSCCStatus, ^{
91 SOSCCStatus result = kSOSCCError;
93 do_if_registered(soscc_ThisDeviceIsInCircle, error);
95 xpc_object_t message = securityd_create_message(kSecXPCOpDeviceInCircle, error);
97 xpc_object_t response = securityd_message_with_reply_sync(message, error);
99 if (response && xpc_dictionary_entry_is_type(response, kSecXPCKeyResult, XPC_TYPE_INT64)) {
100 result = (SOSCCStatus) xpc_dictionary_get_int64(response, kSecXPCKeyResult);
102 result = kSOSCCError;
106 if (response && securityd_message_no_error(response, error))
108 char *desc = xpc_copy_description(response);
109 SecCFCreateErrorWithFormat(0, sSecXPCErrorDomain, NULL, error, NULL, CFSTR("Remote error occurred/no info: %s"), desc);
116 }, CFSTR("SOSCCStatus=%d"))
119 static bool cfstring_to_error_request(enum SecXPCOperation op, CFStringRef string, CFErrorRef* error)
121 __block bool result = false;
123 secdebug("sosops","enter - operation: %d", op);
124 securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
125 xpc_object_t xString = _CFXPCCreateXPCObjectFromCFObject(string);
126 bool success = false;
128 xpc_dictionary_set_value(message, kSecXPCKeyString, xString);
133 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
134 result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
140 static bool deviceid_to_bool_error_request(enum SecXPCOperation op,
144 __block bool result = false;
146 securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
147 CFStringPerformWithCString(IDS, ^(const char *utf8Str) {
148 xpc_dictionary_set_string(message, kSecXPCKeyDeviceID, utf8Str);
151 }, ^bool(xpc_object_t response, CFErrorRef *error) {
152 result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
159 static SOSRingStatus cfstring_to_uint64_request(enum SecXPCOperation op, CFStringRef string, CFErrorRef* error)
161 __block bool result = false;
163 secdebug("sosops","enter - operation: %d", op);
164 securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
165 xpc_object_t xString = _CFXPCCreateXPCObjectFromCFObject(string);
166 bool success = false;
168 xpc_dictionary_set_value(message, kSecXPCKeyString, xString);
173 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
174 result = xpc_dictionary_get_int64(response, kSecXPCKeyResult);
180 static CFStringRef simple_cfstring_error_request(enum SecXPCOperation op, CFErrorRef* error)
182 __block CFStringRef result = NULL;
184 secdebug("sosops","enter - operation: %d", op);
185 securityd_send_sync_and_do(op, error, NULL, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
186 const char *c_string = xpc_dictionary_get_string(response, kSecXPCKeyResult);
189 result = CFStringCreateWithBytes(kCFAllocatorDefault, (const UInt8*)c_string, strlen(c_string), kCFStringEncodingUTF8, false);
192 return c_string != NULL;
197 static bool simple_bool_error_request(enum SecXPCOperation op, CFErrorRef* error)
199 __block bool result = false;
201 secdebug("sosops","enter - operation: %d", op);
202 securityd_send_sync_and_do(op, error, NULL, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
203 result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
209 static bool SecXPCDictionarySetPeerInfoData(xpc_object_t message, const char *key, SOSPeerInfoRef peerInfo, CFErrorRef *error) {
210 bool success = false;
211 CFDataRef peerData = SOSPeerInfoCopyEncodedData(peerInfo, kCFAllocatorDefault, error);
213 success = SecXPCDictionarySetData(message, key, peerData, error);
215 CFReleaseNull(peerData);
219 static bool peer_info_to_bool_error_request(enum SecXPCOperation op, SOSPeerInfoRef peerInfo, CFErrorRef* error)
221 __block bool result = false;
223 secdebug("sosops","enter - operation: %d", op);
224 securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
225 return SecXPCDictionarySetPeerInfoData(message, kSecXPCKeyPeerInfo, peerInfo, error);
226 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
227 result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
233 static CFBooleanRef cfarray_to_cfboolean_error_request(enum SecXPCOperation op, CFArrayRef views, CFErrorRef* error)
235 __block bool result = false;
237 secdebug("sosops","enter - operation: %d", op);
238 bool noError = securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
239 return SecXPCDictionarySetPList(message, kSecXPCKeyArray, views, error);
240 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
241 result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
244 return noError ? (result ? kCFBooleanTrue : kCFBooleanFalse) : NULL;
248 static CFSetRef cfset_cfset_to_cfset_error_request(enum SecXPCOperation op, CFSetRef set1, CFSetRef set2, CFErrorRef* error)
250 __block CFSetRef result = NULL;
252 secdebug("sosops","enter - operation: %d", op);
253 bool noError = securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
254 return SecXPCDictionarySetPList(message, kSecXPCKeySet, set1, error) && SecXPCDictionarySetPList(message, kSecXPCKeySet2, set2, error);
255 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
256 result = SecXPCDictionaryCopySet(response, kSecXPCKeyResult, error);
261 CFReleaseNull(result);
267 static bool escrow_to_bool_error_request(enum SecXPCOperation op, CFStringRef escrow_label, uint64_t tries, CFErrorRef* error)
269 __block bool result = false;
271 securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
273 bool success = false;
274 xpc_object_t xEscrowLabel = _CFXPCCreateXPCObjectFromCFObject(escrow_label);
276 xpc_dictionary_set_value(message, kSecXPCKeyEscrowLabel, xEscrowLabel);
281 xpc_dictionary_set_int64(message, kSecXPCKeyTriesLabel, tries);
286 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
287 result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
293 static CF_RETURNS_RETAINED CFArrayRef simple_array_error_request(enum SecXPCOperation op, CFErrorRef* error)
295 __block CFArrayRef result = NULL;
297 secdebug("sosops","enter - operation: %d", op);
298 if (securityd_send_sync_and_do(op, error, NULL, ^bool(xpc_object_t response, CFErrorRef *error) {
299 xpc_object_t temp_result = xpc_dictionary_get_value(response, kSecXPCKeyResult);
300 result = _CFXPCCreateCFObjectFromXPCObject(temp_result);
301 return result != NULL;
303 if (!isArray(result)) {
304 SOSErrorCreate(kSOSErrorUnexpectedType, error, NULL, CFSTR("Expected array, got: %@"), result);
305 CFReleaseNull(result);
311 static CF_RETURNS_RETAINED CFArrayRef der_array_error_request(enum SecXPCOperation op, CFErrorRef* error)
313 __block CFArrayRef result = NULL;
315 secdebug("sosops","enter - operation: %d", op);
316 if (securityd_send_sync_and_do(op, error, NULL, ^bool(xpc_object_t response, CFErrorRef *error) {
318 const uint8_t* bytes = xpc_dictionary_get_data(response, kSecXPCKeyResult, &length);
319 der_decode_plist(kCFAllocatorDefault, 0, (CFPropertyListRef*) &result, error, bytes, bytes + length);
321 return result != NULL;
323 if (!isArray(result)) {
324 SOSErrorCreate(kSOSErrorUnexpectedType, error, NULL, CFSTR("Expected array, got: %@"), result);
325 CFReleaseNull(result);
331 static CFDictionaryRef strings_to_dictionary_error_request(enum SecXPCOperation op, CFErrorRef* error)
333 __block CFDictionaryRef result = NULL;
335 secdebug("sosops","enter - operation: %d", op);
337 if (securityd_send_sync_and_do(op, error, NULL, ^bool(xpc_object_t response, CFErrorRef *error) {
338 xpc_object_t temp_result = xpc_dictionary_get_value(response, kSecXPCKeyResult);
340 result = _CFXPCCreateCFObjectFromXPCObject(temp_result);
341 return result != NULL;
344 if (!isDictionary(result)) {
345 SOSErrorCreate(kSOSErrorUnexpectedType, error, NULL, CFSTR("Expected dictionary, got: %@"), result);
346 CFReleaseNull(result);
353 static int simple_int_error_request(enum SecXPCOperation op, CFErrorRef* error)
355 __block int result = 0;
357 secdebug("sosops","enter - operation: %d", op);
358 securityd_send_sync_and_do(op, error, NULL, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
359 int64_t temp_result = xpc_dictionary_get_int64(response, kSecXPCKeyResult);
360 if ((temp_result >= INT32_MIN) && (temp_result <= INT32_MAX)) {
361 result = (int)temp_result;
368 static SOSPeerInfoRef peer_info_error_request(enum SecXPCOperation op, CFErrorRef* error)
370 SOSPeerInfoRef result = NULL;
371 __block CFDataRef data = NULL;
373 secdebug("sosops","enter - operation: %d", op);
374 securityd_send_sync_and_do(op, error, NULL, ^bool(xpc_object_t response, CFErrorRef *error) {
375 xpc_object_t temp_result = xpc_dictionary_get_value(response, kSecXPCKeyResult);
376 if (response && (NULL != temp_result)) {
377 data = _CFXPCCreateCFObjectFromXPCObject(temp_result);
383 result = SOSPeerInfoCreateFromData(kCFAllocatorDefault, error, data);
385 SOSErrorCreate(kSOSErrorUnexpectedType, error, NULL, CFSTR("Expected CFData, got: %@"), data);
392 static CFDataRef data_to_error_request(enum SecXPCOperation op, CFErrorRef *error)
394 __block CFDataRef result = NULL;
396 secdebug("sosops", "enter -- operation: %d", op);
397 securityd_send_sync_and_do(op, error, NULL, ^bool(xpc_object_t response, CFErrorRef *error) {
398 xpc_object_t temp_result = xpc_dictionary_get_value(response, kSecXPCKeyResult);
399 if (response && (NULL != temp_result)) {
400 result = _CFXPCCreateCFObjectFromXPCObject(temp_result);
402 return result != NULL;
405 if (!isData(result)) {
406 SOSErrorCreate(kSOSErrorUnexpectedType, error, NULL, CFSTR("Expected CFData, got: %@"), result);
413 static CFArrayRef array_of_info_error_request(enum SecXPCOperation op, CFErrorRef* error)
415 __block CFArrayRef result = NULL;
417 secdebug("sosops","enter - operation: %d", op);
418 securityd_send_sync_and_do(op, error, NULL, ^bool(xpc_object_t response, CFErrorRef *error) {
419 xpc_object_t encoded_array = xpc_dictionary_get_value(response, kSecXPCKeyResult);
420 if (response && (NULL != encoded_array)) {
421 result = CreateArrayOfPeerInfoWithXPCObject(encoded_array, error);
423 return result != NULL;
426 if (!isArray(result)) {
427 SOSErrorCreate(kSOSErrorUnexpectedType, error, NULL, CFSTR("Expected array, got: %@"), result);
428 CFReleaseNull(result);
433 static CF_RETURNS_RETAINED SOSPeerInfoRef data_to_peer_info_error_request(enum SecXPCOperation op, CFDataRef secret, CFErrorRef* error)
435 __block SOSPeerInfoRef result = false;
436 __block CFDataRef data = NULL;
438 secdebug("sosops", "enter - operation: %d", op);
439 securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
440 xpc_object_t xsecretData = _CFXPCCreateXPCObjectFromCFObject(secret);
441 bool success = false;
443 xpc_dictionary_set_value(message, kSecXPCKeyNewPublicBackupKey, xsecretData);
448 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
449 xpc_object_t temp_result = xpc_dictionary_get_value(response, kSecXPCKeyResult);
450 if (response && (NULL != temp_result)) {
451 data = _CFXPCCreateCFObjectFromXPCObject(temp_result);
457 result = SOSPeerInfoCreateFromData(kCFAllocatorDefault, error, data);
459 SOSErrorCreate(kSOSErrorUnexpectedType, error, NULL, CFSTR("Expected CFData, got: %@"), data);
466 static bool keybag_and_bool_to_bool_error_request(enum SecXPCOperation op, CFDataRef data, bool include, CFErrorRef* error)
468 secdebug("sosops", "enter - operation: %d", op);
469 return securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
470 xpc_object_t xData = _CFXPCCreateXPCObjectFromCFObject(data);
471 bool success = false;
473 xpc_dictionary_set_value(message, kSecXPCKeyKeybag, xData);
477 xpc_dictionary_set_bool(message, kSecXPCKeyIncludeV0, include);
479 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
480 return xpc_dictionary_get_bool(response, kSecXPCKeyResult);
484 static bool recovery_and_bool_to_bool_error_request(enum SecXPCOperation op, CFDataRef data, CFErrorRef* error)
486 secdebug("sosops", "enter - operation: %d", op);
487 return securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
488 xpc_object_t xData = NULL;
490 xData = _CFXPCCreateXPCObjectFromCFObject(data);
493 CFDataRef nullData = CFDataCreate(kCFAllocatorDefault, &zero, 1);
494 xData = _CFXPCCreateXPCObjectFromCFObject(nullData);
495 CFReleaseNull(nullData);
497 bool success = false;
499 xpc_dictionary_set_value(message, kSecXPCKeyRecoveryPublicKey, xData);
504 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
505 return xpc_dictionary_get_bool(response, kSecXPCKeyResult);
509 static bool info_array_to_bool_error_request(enum SecXPCOperation op, CFArrayRef peer_infos, CFErrorRef* error)
511 __block bool result = false;
513 secdebug("sosops", "enter - operation: %d", op);
514 securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
515 xpc_object_t encoded_peers = CreateXPCObjectWithArrayOfPeerInfo(peer_infos, error);
517 xpc_dictionary_set_value(message, kSecXPCKeyPeerInfoArray, encoded_peers);
518 return encoded_peers != NULL;
519 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
520 result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
526 static bool uint64_t_to_bool_error_request(enum SecXPCOperation op,
530 __block bool result = false;
532 securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
533 xpc_dictionary_set_uint64(message, kSecXPCLimitInMinutes, number);
535 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
536 result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
543 static bool cfstring_and_cfdata_to_cfdata_cfdata_error_request(enum SecXPCOperation op, CFStringRef viewName, CFDataRef input, CFDataRef* data, CFDataRef* data2, CFErrorRef* error) {
544 secdebug("sosops", "enter - operation: %d", op);
545 __block bool result = false;
546 securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
547 xpc_object_t xviewname = _CFXPCCreateXPCObjectFromCFObject(viewName);
548 xpc_object_t xinput = _CFXPCCreateXPCObjectFromCFObject(input);
549 bool success = false;
550 if (xviewname && xinput){
551 xpc_dictionary_set_value(message, kSecXPCKeyViewName, xviewname);
552 xpc_dictionary_set_value(message, kSecXPCData, xinput);
558 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
559 result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
561 xpc_object_t temp_result = xpc_dictionary_get_value(response, kSecXPCData);
562 if (response && (NULL != temp_result) && data) {
563 *data = _CFXPCCreateCFObjectFromXPCObject(temp_result);
565 temp_result = xpc_dictionary_get_value(response, kSecXPCKeyKeybag);
566 if (response && (NULL != temp_result) && data2) {
567 *data2 = _CFXPCCreateCFObjectFromXPCObject(temp_result);
573 if (data &&!isData(*data)) {
574 SOSErrorCreate(kSOSErrorUnexpectedType, error, NULL, CFSTR("Expected CFData, got: %@"), *data);
576 if (data2 &&!isData(*data2)) {
577 SOSErrorCreate(kSOSErrorUnexpectedType, error, NULL, CFSTR("Expected CFData, got: %@"), *data2);
583 static bool cfdata_and_int_error_request_returns_bool(enum SecXPCOperation op, CFDataRef thedata,
584 PiggyBackProtocolVersion version, CFErrorRef *error) {
585 __block bool result = false;
587 sec_trace_enter_api(NULL);
588 securityd_send_sync_and_do(op, error, ^(xpc_object_t message, CFErrorRef *error) {
589 xpc_object_t xdata = _CFXPCCreateXPCObjectFromCFObject(thedata);
590 bool success = false;
592 xpc_dictionary_set_value(message, kSecXPCData, xdata);
593 xpc_dictionary_set_uint64(message, kSecXPCVersion, version);
599 }, ^(xpc_object_t response, __unused CFErrorRef *error) {
600 result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
607 static CFDataRef cfdata_error_request_returns_cfdata(enum SecXPCOperation op, CFDataRef thedata, CFErrorRef *error) {
608 __block CFDataRef result = NULL;
610 sec_trace_enter_api(NULL);
611 securityd_send_sync_and_do(op, error, ^(xpc_object_t message, CFErrorRef *error) {
612 xpc_object_t xdata = _CFXPCCreateXPCObjectFromCFObject(thedata);
613 bool success = false;
615 xpc_dictionary_set_value(message, kSecXPCData, xdata);
620 }, ^(xpc_object_t response, __unused CFErrorRef *error) {
621 xpc_object_t temp_result = xpc_dictionary_get_value(response, kSecXPCKeyResult);
622 if (response && (NULL != temp_result)) {
623 CFTypeRef object = _CFXPCCreateCFObjectFromXPCObject(temp_result);
624 result = copyIfData(object, error);
625 CFReleaseNull(object);
627 return (bool) (result != NULL);
633 bool SOSCCRequestToJoinCircle(CFErrorRef* error)
635 sec_trace_enter_api(NULL);
636 sec_trace_return_bool_api(^{
637 do_if_registered(soscc_RequestToJoinCircle, error);
639 return simple_bool_error_request(kSecXPCOpRequestToJoin, error);
643 bool SOSCCRequestToJoinCircleAfterRestore(CFErrorRef* error)
645 sec_trace_enter_api(NULL);
646 sec_trace_return_bool_api(^{
647 do_if_registered(soscc_RequestToJoinCircleAfterRestore, error);
649 return simple_bool_error_request(kSecXPCOpRequestToJoinAfterRestore, error);
653 bool SOSCCAccountHasPublicKey(CFErrorRef *error)
656 sec_trace_enter_api(NULL);
657 sec_trace_return_bool_api(^{
658 do_if_registered(soscc_AccountHasPublicKey, error);
660 return simple_bool_error_request(kSecXPCOpAccountHasPublicKey, error);
665 bool SOSCCAccountIsNew(CFErrorRef *error)
667 sec_trace_enter_api(NULL);
668 sec_trace_return_bool_api(^{
669 do_if_registered(soscc_AccountIsNew, error);
671 return simple_bool_error_request(kSecXPCOpAccountIsNew, error);
675 bool SOSCCWaitForInitialSync(CFErrorRef* error)
677 sec_trace_enter_api(NULL);
678 sec_trace_return_bool_api(^{
679 do_if_registered(soscc_WaitForInitialSync, error);
681 return simple_bool_error_request(kSecXPCOpWaitForInitialSync, error);
685 CFArrayRef SOSCCCopyYetToSyncViewsList(CFErrorRef* error)
687 sec_trace_enter_api(NULL);
688 sec_trace_return_api(CFArrayRef, ^{
689 do_if_registered(soscc_CopyYetToSyncViewsList, error);
691 return simple_array_error_request(kSecXPCOpCopyYetToSyncViews, error);
695 bool SOSCCRequestEnsureFreshParameters(CFErrorRef* error)
697 sec_trace_enter_api(NULL);
698 sec_trace_return_bool_api(^{
699 do_if_registered(soscc_RequestEnsureFreshParameters, error);
701 return simple_bool_error_request(kSecXPCOpRequestEnsureFreshParameters, error);
705 CFStringRef SOSCCGetAllTheRings(CFErrorRef *error){
706 sec_trace_enter_api(NULL);
707 sec_trace_return_api(CFStringRef, ^{
708 do_if_registered(soscc_GetAllTheRings, error);
711 return simple_cfstring_error_request(kSecXPCOpGetAllTheRings, error);
714 bool SOSCCApplyToARing(CFStringRef ringName, CFErrorRef* error)
716 sec_trace_enter_api(NULL);
717 sec_trace_return_bool_api(^{
718 do_if_registered(soscc_ApplyToARing, ringName, error);
720 return cfstring_to_error_request(kSecXPCOpApplyToARing, ringName, error);
724 bool SOSCCWithdrawlFromARing(CFStringRef ringName, CFErrorRef* error)
726 sec_trace_enter_api(NULL);
727 sec_trace_return_bool_api(^{
728 do_if_registered(soscc_WithdrawlFromARing, ringName, error);
730 return cfstring_to_error_request(kSecXPCOpWithdrawlFromARing, ringName, error);
734 SOSRingStatus SOSCCRingStatus(CFStringRef ringName, CFErrorRef* error)
736 sec_trace_enter_api(NULL);
737 sec_trace_return_api(SOSRingStatus, ^{
738 do_if_registered(soscc_RingStatus, ringName, error);
740 return cfstring_to_uint64_request(kSecXPCOpRingStatus, ringName, error);
741 }, CFSTR("SOSCCStatus=%d"))
744 bool SOSCCEnableRing(CFStringRef ringName, CFErrorRef* error)
746 sec_trace_enter_api(NULL);
747 sec_trace_return_bool_api(^{
748 do_if_registered(soscc_EnableRing, ringName, error);
750 return cfstring_to_error_request(kSecXPCOpEnableRing, ringName, error);
754 bool SOSCCAccountSetToNew(CFErrorRef *error)
756 secwarning("SOSCCAccountSetToNew called");
757 sec_trace_enter_api(NULL);
758 sec_trace_return_bool_api(^{
759 do_if_registered(soscc_SetToNew, error);
760 return simple_bool_error_request(kSecXPCOpAccountSetToNew, error);
764 bool SOSCCResetToOffering(CFErrorRef* error)
766 secwarning("SOSCCResetToOffering called");
767 sec_trace_enter_api(NULL);
768 sec_trace_return_bool_api(^{
769 do_if_registered(soscc_ResetToOffering, error);
771 return simple_bool_error_request(kSecXPCOpResetToOffering, error);
775 bool SOSCCResetToEmpty(CFErrorRef* error)
777 secwarning("SOSCCResetToEmpty called");
778 sec_trace_enter_api(NULL);
779 sec_trace_return_bool_api(^{
780 do_if_registered(soscc_ResetToEmpty, error);
782 return simple_bool_error_request(kSecXPCOpResetToEmpty, error);
786 bool SOSCCRemovePeersFromCircle(CFArrayRef peers, CFErrorRef* error)
788 sec_trace_enter_api(NULL);
789 sec_trace_return_bool_api(^{
790 do_if_registered(soscc_RemovePeersFromCircle, peers, error);
792 return info_array_to_bool_error_request(kSecXPCOpRemovePeersFromCircle, peers, error);
796 bool SOSCCRemoveThisDeviceFromCircle(CFErrorRef* error)
798 sec_trace_enter_api(NULL);
799 sec_trace_return_bool_api(^{
800 do_if_registered(soscc_RemoveThisDeviceFromCircle, error);
802 return simple_bool_error_request(kSecXPCOpRemoveThisDeviceFromCircle, error);
806 bool SOSCCLoggedOutOfAccount(CFErrorRef* error)
808 sec_trace_enter_api(NULL);
809 sec_trace_return_bool_api(^{
810 do_if_registered(soscc_LoggedOutOfAccount, error);
812 return simple_bool_error_request(kSecXPCOpLoggedOutOfAccount, error);
816 bool SOSCCBailFromCircle_BestEffort(uint64_t limit_in_seconds, CFErrorRef* error)
818 sec_trace_enter_api(NULL);
819 sec_trace_return_bool_api(^{
820 do_if_registered(soscc_BailFromCircle, limit_in_seconds, error);
822 return uint64_t_to_bool_error_request(kSecXPCOpBailFromCircle, limit_in_seconds, error);
826 bool SOSCCSignedOut(bool immediate, CFErrorRef* error)
828 uint64_t limit = strtoul(optarg, NULL, 10);
831 return SOSCCRemoveThisDeviceFromCircle(error);
833 return SOSCCBailFromCircle_BestEffort(limit, error);
837 CFArrayRef SOSCCCopyPeerPeerInfo(CFErrorRef* error)
839 sec_trace_enter_api(NULL);
840 sec_trace_return_api(CFArrayRef, ^{
841 do_if_registered(soscc_CopyPeerInfo, error);
843 return array_of_info_error_request(kSecXPCOpCopyPeerPeerInfo, error);
844 }, CFSTR("return=%@"));
847 CFArrayRef SOSCCCopyConcurringPeerPeerInfo(CFErrorRef* error)
849 sec_trace_enter_api(NULL);
850 sec_trace_return_api(CFArrayRef, ^{
851 do_if_registered(soscc_CopyConcurringPeerInfo, error);
853 return array_of_info_error_request(kSecXPCOpCopyConcurringPeerPeerInfo, error);
854 }, CFSTR("return=%@"));
857 CFArrayRef SOSCCCopyGenerationPeerInfo(CFErrorRef* error)
859 sec_trace_enter_api(NULL);
860 sec_trace_return_api(CFArrayRef, ^{
861 do_if_registered(soscc_CopyGenerationPeerInfo, error);
863 return simple_array_error_request(kSecXPCOpCopyGenerationPeerInfo, error);
864 }, CFSTR("return=%@"));
867 CFArrayRef SOSCCCopyApplicantPeerInfo(CFErrorRef* error)
869 sec_trace_enter_api(NULL);
870 sec_trace_return_api(CFArrayRef, ^{
871 do_if_registered(soscc_CopyApplicantPeerInfo, error);
873 return array_of_info_error_request(kSecXPCOpCopyApplicantPeerInfo, error);
874 }, CFSTR("return=%@"));
877 bool SOSCCValidateUserPublic(CFErrorRef* error){
878 sec_trace_enter_api(NULL);
879 sec_trace_return_api(bool, ^{
880 do_if_registered(soscc_ValidateUserPublic, error);
882 return simple_bool_error_request(kSecXPCOpValidateUserPublic, error);
886 CFArrayRef SOSCCCopyValidPeerPeerInfo(CFErrorRef* error)
888 sec_trace_enter_api(NULL);
889 sec_trace_return_api(CFArrayRef, ^{
890 do_if_registered(soscc_CopyValidPeerPeerInfo, error);
892 return array_of_info_error_request(kSecXPCOpCopyValidPeerPeerInfo, error);
893 }, CFSTR("return=%@"));
896 CFArrayRef SOSCCCopyNotValidPeerPeerInfo(CFErrorRef* error)
898 sec_trace_enter_api(NULL);
899 sec_trace_return_api(CFArrayRef, ^{
900 do_if_registered(soscc_CopyNotValidPeerPeerInfo, error);
902 return array_of_info_error_request(kSecXPCOpCopyNotValidPeerPeerInfo, error);
903 }, CFSTR("return=%@"));
906 CFArrayRef SOSCCCopyRetirementPeerInfo(CFErrorRef* error)
908 sec_trace_enter_api(NULL);
909 sec_trace_return_api(CFArrayRef, ^{
910 do_if_registered(soscc_CopyRetirementPeerInfo, error);
912 return array_of_info_error_request(kSecXPCOpCopyRetirementPeerInfo, error);
913 }, CFSTR("return=%@"));
916 CFArrayRef SOSCCCopyViewUnawarePeerInfo(CFErrorRef* error)
918 sec_trace_enter_api(NULL);
919 sec_trace_return_api(CFArrayRef, ^{
920 do_if_registered(soscc_CopyViewUnawarePeerInfo, error);
922 return array_of_info_error_request(kSecXPCOpCopyViewUnawarePeerInfo, error);
923 }, CFSTR("return=%@"));
926 CFDataRef SOSCCCopyAccountState(CFErrorRef* error)
928 sec_trace_enter_api(NULL);
929 sec_trace_return_api(CFDataRef, ^{
930 do_if_registered(soscc_CopyAccountState, error);
932 return data_to_error_request(kSecXPCOpCopyAccountData, error);
933 }, CFSTR("return=%@"));
936 bool SOSCCDeleteAccountState(CFErrorRef *error)
938 sec_trace_enter_api(NULL);
939 sec_trace_return_api(bool, ^{
940 do_if_registered(soscc_DeleteAccountState, error);
941 return simple_bool_error_request(kSecXPCOpDeleteAccountData, error);
944 CFDataRef SOSCCCopyEngineData(CFErrorRef* error)
946 sec_trace_enter_api(NULL);
947 sec_trace_return_api(CFDataRef, ^{
948 do_if_registered(soscc_CopyEngineData, error);
950 return data_to_error_request(kSecXPCOpCopyEngineData, error);
951 }, CFSTR("return=%@"));
954 bool SOSCCDeleteEngineState(CFErrorRef *error)
956 sec_trace_enter_api(NULL);
957 sec_trace_return_api(bool, ^{
958 do_if_registered(soscc_DeleteEngineState, error);
959 return simple_bool_error_request(kSecXPCOpDeleteEngineData, error);
963 SOSPeerInfoRef SOSCCCopyMyPeerInfo(CFErrorRef *error)
965 sec_trace_enter_api(NULL);
966 sec_trace_return_api(SOSPeerInfoRef, ^{
967 do_if_registered(soscc_CopyMyPeerInfo, error);
969 return peer_info_error_request(kSecXPCOpCopyMyPeerInfo, error);
970 }, CFSTR("return=%@"));
973 static CFArrayRef SOSCCCopyEngineState(CFErrorRef* error)
975 sec_trace_enter_api(NULL);
976 sec_trace_return_api(CFArrayRef, ^{
977 do_if_registered(soscc_CopyEngineState, error);
979 return der_array_error_request(kSecXPCOpCopyEngineState, error);
980 }, CFSTR("return=%@"));
983 CFStringRef kSOSCCEngineStatePeerIDKey = CFSTR("PeerID");
984 CFStringRef kSOSCCEngineStateManifestCountKey = CFSTR("ManifestCount");
985 CFStringRef kSOSCCEngineStateSyncSetKey = CFSTR("SyncSet");
986 CFStringRef kSOSCCEngineStateCoderKey = CFSTR("CoderDump");
987 CFStringRef kSOSCCEngineStateManifestHashKey = CFSTR("ManifestHash");
989 void SOSCCForEachEngineStateAsStringFromArray(CFArrayRef states, void (^block)(CFStringRef oneStateString)) {
991 CFArrayForEach(states, ^(const void *value) {
992 CFDictionaryRef dict = asDictionary(value, NULL);
994 CFMutableStringRef description = CFStringCreateMutable(kCFAllocatorDefault, 0);
996 CFStringRef id = asString(CFDictionaryGetValue(dict, kSOSCCEngineStatePeerIDKey), NULL);
999 CFStringAppendFormat(description, NULL, CFSTR("remote %@ "), id);
1001 CFStringAppendFormat(description, NULL, CFSTR("local "));
1004 CFSetRef viewSet = asSet(CFDictionaryGetValue(dict, kSOSCCEngineStateSyncSetKey), NULL);
1006 CFStringSetPerformWithDescription(viewSet, ^(CFStringRef setDescription) {
1007 CFStringAppend(description, setDescription);
1010 CFStringAppendFormat(description, NULL, CFSTR("<Missing view set!>"));
1013 CFStringAppendFormat(description, NULL, CFSTR(" [%@]"),
1014 CFDictionaryGetValue(dict, kSOSCCEngineStateManifestCountKey));
1016 CFDataRef mainfestHash = asData(CFDictionaryGetValue(dict, kSOSCCEngineStateManifestHashKey), NULL);
1019 CFDataPerformWithHexString(mainfestHash, ^(CFStringRef dataString) {
1020 CFStringAppendFormat(description, NULL, CFSTR(" %@"), dataString);
1024 CFStringRef coderDescription = asString(CFDictionaryGetValue(dict, kSOSCCEngineStateCoderKey), NULL);
1025 if (coderDescription) {
1026 CFStringAppendFormat(description, NULL, CFSTR(" %@"), coderDescription);
1031 CFReleaseNull(description);
1036 bool SOSCCForEachEngineStateAsString(CFErrorRef* error, void (^block)(CFStringRef oneStateString)) {
1037 CFArrayRef states = SOSCCCopyEngineState(error);
1041 SOSCCForEachEngineStateAsStringFromArray(states, block);
1047 bool SOSCCAcceptApplicants(CFArrayRef applicants, CFErrorRef* error)
1049 sec_trace_enter_api(NULL);
1050 sec_trace_return_bool_api(^{
1051 do_if_registered(soscc_AcceptApplicants, applicants, error);
1053 return info_array_to_bool_error_request(kSecXPCOpAcceptApplicants, applicants, error);
1057 bool SOSCCRejectApplicants(CFArrayRef applicants, CFErrorRef *error)
1059 sec_trace_enter_api(CFSTR("applicants=%@"), applicants);
1060 sec_trace_return_bool_api(^{
1061 do_if_registered(soscc_RejectApplicants, applicants, error);
1063 return info_array_to_bool_error_request(kSecXPCOpRejectApplicants, applicants, error);
1067 static CF_RETURNS_RETAINED SOSPeerInfoRef SOSSetNewPublicBackupKey(CFDataRef pubKey, CFErrorRef *error)
1069 sec_trace_enter_api(NULL);
1070 sec_trace_return_api(SOSPeerInfoRef, ^{
1071 do_if_registered(soscc_SetNewPublicBackupKey, pubKey, error);
1073 return data_to_peer_info_error_request(kSecXPCOpSetNewPublicBackupKey, pubKey, error);
1074 }, CFSTR("return=%@"));
1077 SOSPeerInfoRef SOSCCCopyMyPeerWithNewDeviceRecoverySecret(CFDataRef secret, CFErrorRef *error){
1078 CFDataRef publicKeyData = SOSCopyDeviceBackupPublicKey(secret, error);
1079 SOSPeerInfoRef copiedPeer = publicKeyData ? SOSSetNewPublicBackupKey(publicKeyData, error) : NULL;
1080 CFReleaseNull(publicKeyData);
1084 bool SOSCCRegisterSingleRecoverySecret(CFDataRef aks_bag, bool forV0Only, CFErrorRef *error){
1085 sec_trace_enter_api(NULL);
1086 sec_trace_return_bool_api(^{
1087 do_if_registered(soscc_RegisterSingleRecoverySecret, aks_bag, forV0Only, error);
1088 return keybag_and_bool_to_bool_error_request(kSecXPCOpSetBagForAllSlices, aks_bag, forV0Only, error);
1093 bool SOSCCRegisterRecoveryPublicKey(CFDataRef recovery_key, CFErrorRef *error){
1094 sec_trace_enter_api(NULL);
1095 sec_trace_return_bool_api(^{
1096 bool retval = false;
1097 do_if_registered(soscc_RegisterRecoveryPublicKey, recovery_key, error);
1098 // NULL recovery_key is handled in recovery_and_bool_to_bool_error_request now.
1099 retval = recovery_and_bool_to_bool_error_request(kSecXPCOpRegisterRecoveryPublicKey, recovery_key, error);
1104 CFDataRef SOSCCCopyRecoveryPublicKey(CFErrorRef *error){
1105 sec_trace_enter_api(NULL);
1106 sec_trace_return_api(CFDataRef, ^{
1107 do_if_registered(soscc_CopyRecoveryPublicKey, error);
1108 return data_to_error_request(kSecXPCOpGetRecoveryPublicKey, error);
1109 }, CFSTR("return=%@"));
1111 static bool label_and_password_to_bool_error_request(enum SecXPCOperation op,
1112 CFStringRef user_label, CFDataRef user_password,
1115 __block bool result = false;
1117 securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
1118 CFStringPerformWithCString(user_label, ^(const char *utf8Str) {
1119 xpc_dictionary_set_string(message, kSecXPCKeyUserLabel, utf8Str);
1121 xpc_dictionary_set_data(message, kSecXPCKeyUserPassword, CFDataGetBytePtr(user_password), CFDataGetLength(user_password));
1123 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
1124 result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
1131 static bool label_and_password_and_dsid_to_bool_error_request(enum SecXPCOperation op,
1132 CFStringRef user_label, CFDataRef user_password,
1133 CFStringRef dsid, CFErrorRef* error)
1135 __block bool result = false;
1137 securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
1138 CFStringPerformWithCString(user_label, ^(const char *utf8Str) {
1139 xpc_dictionary_set_string(message, kSecXPCKeyUserLabel, utf8Str);
1141 CFStringPerformWithCString(dsid, ^(const char *utr8StrDSID) {
1142 xpc_dictionary_set_string(message, kSecXPCKeyDSID, utr8StrDSID);
1144 xpc_dictionary_set_data(message, kSecXPCKeyUserPassword, CFDataGetBytePtr(user_password), CFDataGetLength(user_password));
1146 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
1147 result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
1154 static bool cfstring_to_bool_error_request(enum SecXPCOperation op,
1158 __block bool result = false;
1160 securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
1161 CFStringPerformWithCString(string, ^(const char *utf8Str) {
1162 xpc_dictionary_set_string(message, kSecXPCKeyDeviceID, utf8Str);
1165 }, ^bool(xpc_object_t response, CFErrorRef *error) {
1166 result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
1173 static int idsDict_to_int_error_request(enum SecXPCOperation op,
1174 CFDictionaryRef IDS,
1177 __block int result = 0;
1179 securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
1180 SecXPCDictionarySetPListOptional(message, kSecXPCKeyIDSMessage, IDS, error);
1182 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
1183 int64_t temp_result = xpc_dictionary_get_int64(response, kSecXPCKeyResult);
1184 if ((temp_result >= INT32_MIN) && (temp_result <= INT32_MAX)) {
1185 result = (int)temp_result;
1193 static bool idsData_peerID_to_bool_error_request(enum SecXPCOperation op, CFStringRef peerID,
1194 CFDataRef IDSMessage,
1197 __block bool result = 0;
1199 securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
1200 SecXPCDictionarySetData(message, kSecXPCKeyIDSMessage, IDSMessage, error);
1201 SecXPCDictionarySetString(message, kSecXPCKeyDeviceID, peerID, error);
1203 }, ^bool(xpc_object_t response, CFErrorRef *error) {
1204 result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
1210 static bool idscommand_to_bool_error_request(enum SecXPCOperation op,
1211 CFStringRef idsMessage,
1214 __block bool result = false;
1216 securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
1217 CFStringPerformWithCString(idsMessage, ^(const char *utf8Str) {
1218 xpc_dictionary_set_string(message, kSecXPCKeySendIDSMessage, utf8Str);
1221 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
1222 result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
1229 bool SOSCCRegisterUserCredentials(CFStringRef user_label, CFDataRef user_password, CFErrorRef* error)
1231 secnotice("sosops", "SOSCCRegisterUserCredentials - calling SOSCCSetUserCredentials!! %@\n", user_label);
1232 return SOSCCSetUserCredentials(user_label, user_password, error);
1235 bool SOSCCSetUserCredentials(CFStringRef user_label, CFDataRef user_password, CFErrorRef* error)
1237 secnotice("sosops", "SOSCCSetUserCredentials!! %@\n", user_label);
1238 sec_trace_enter_api(CFSTR("user_label=%@"), user_label);
1239 sec_trace_return_bool_api(^{
1240 do_if_registered(soscc_SetUserCredentials, user_label, user_password, error);
1242 return label_and_password_to_bool_error_request(kSecXPCOpSetUserCredentials, user_label, user_password, error);
1246 bool SOSCCSetUserCredentialsAndDSID(CFStringRef user_label, CFDataRef user_password, CFStringRef dsid, CFErrorRef *error)
1248 secnotice("sosops", "SOSCCSetUserCredentialsAndDSID!! %@\n", user_label);
1249 sec_trace_enter_api(CFSTR("user_label=%@"), user_label);
1250 sec_trace_return_bool_api(^{
1251 do_if_registered(soscc_SetUserCredentialsAndDSID, user_label, user_password, dsid, error);
1253 bool result = false;
1254 __block CFStringRef account_dsid = dsid;
1256 require_action_quiet(user_label, out, SOSErrorCreate(kSOSErrorParam, error, NULL, CFSTR("user_label is nil")));
1257 require_action_quiet(user_password, out, SOSErrorCreate(kSOSErrorParam, error, NULL, CFSTR("user_password is nil")));
1259 if(account_dsid == NULL){
1260 account_dsid = CFSTR("");
1262 return label_and_password_and_dsid_to_bool_error_request(kSecXPCOpSetUserCredentialsAndDSID, user_label, user_password, account_dsid, error);
1268 bool SOSCCSetDeviceID(CFStringRef IDS, CFErrorRef* error)
1270 secnotice("sosops", "SOSCCSetDeviceID!! %@\n", IDS);
1271 sec_trace_enter_api(NULL);
1272 sec_trace_return_bool_api(^{
1273 do_if_registered(soscc_SetDeviceID, IDS, error);
1274 bool result = cfstring_to_bool_error_request(kSecXPCOpSetDeviceID, IDS, error);
1279 bool SOSCCIDSServiceRegistrationTest(CFStringRef message, CFErrorRef *error)
1281 secnotice("sosops", "SOSCCSendIDSTestMessage!! %@\n", message);
1282 sec_trace_enter_api(NULL);
1283 sec_trace_return_bool_api(^{
1284 do_if_registered(soscc_CheckIDSRegistration, message, error);
1285 return idscommand_to_bool_error_request(kSecXPCOpSendIDSMessage, message, error);
1289 bool SOSCCIDSPingTest(CFStringRef message, CFErrorRef *error)
1291 secnotice("sosops", "SOSCCSendIDSTestMessage!! %@\n", message);
1292 sec_trace_enter_api(NULL);
1293 sec_trace_return_bool_api(^{
1294 do_if_registered(soscc_PingTest, message, error);
1295 return idscommand_to_bool_error_request(kSecXPCOpPingTest, message, error);
1299 bool SOSCCIDSDeviceIDIsAvailableTest(CFErrorRef *error)
1301 secnotice("sosops", "SOSCCIDSDeviceIDIsAvailableTest!!\n");
1302 sec_trace_enter_api(NULL);
1303 sec_trace_return_bool_api(^{
1304 do_if_registered(soscc_GetIDSIDFromIDS, error);
1305 return simple_bool_error_request(kSecXPCOpIDSDeviceID, error);
1309 HandleIDSMessageReason SOSCCHandleIDSMessage(CFDictionaryRef IDS, CFErrorRef* error)
1311 secnotice("sosops", "SOSCCHandleIDSMessage!! %@\n", IDS);
1312 sec_trace_enter_api(NULL);
1313 sec_trace_return_api(HandleIDSMessageReason, ^{
1314 do_if_registered(soscc_HandleIDSMessage, IDS, error);
1315 return (HandleIDSMessageReason) idsDict_to_int_error_request(kSecXPCOpHandleIDSMessage, IDS, error);
1319 bool SOSCCClearPeerMessageKeyInKVS(CFStringRef peerID, CFErrorRef *error)
1321 secnotice("sosops", "SOSCCClearPeerMessageKeyInKVS!! %@\n", peerID);
1322 sec_trace_enter_api(NULL);
1323 sec_trace_return_bool_api(^{
1324 do_if_registered(socc_clearPeerMessageKeyInKVS, peerID, error);
1325 return cfstring_to_bool_error_request(kSecXPCOpClearKVSPeerMessage, peerID, error);
1330 bool SOSCCRequestSyncWithPeerOverKVSUsingIDOnly(CFStringRef peerID, CFErrorRef *error)
1332 secnotice("sosops", "SOSCCRequestSyncWithPeerOverKVSUsingIDOnly!! %@\n", peerID);
1333 sec_trace_enter_api(NULL);
1334 sec_trace_return_bool_api(^{
1335 do_if_registered(soscc_requestSyncWithPeerOverKVSIDOnly, peerID, error);
1336 return deviceid_to_bool_error_request(kSecXPCOpSyncWithKVSPeerIDOnly, peerID, error);
1340 bool SOSCCRequestSyncWithPeerOverKVS(CFStringRef peerID, CFDataRef message, CFErrorRef *error)
1342 secnotice("sosops", "SOSCCRequestSyncWithPeerOverKVS!! %@\n", peerID);
1343 sec_trace_enter_api(NULL);
1344 sec_trace_return_bool_api(^{
1345 do_if_registered(soscc_requestSyncWithPeerOverKVS, peerID, message, error);
1346 return idsData_peerID_to_bool_error_request(kSecXPCOpSyncWithKVSPeer, peerID, message, error);
1350 bool SOSCCTryUserCredentials(CFStringRef user_label, CFDataRef user_password, CFErrorRef* error)
1352 sec_trace_enter_api(CFSTR("user_label=%@"), user_label);
1353 sec_trace_return_bool_api(^{
1354 do_if_registered(soscc_TryUserCredentials, user_label, user_password, error);
1356 return label_and_password_to_bool_error_request(kSecXPCOpTryUserCredentials, user_label, user_password, error);
1361 bool SOSCCCanAuthenticate(CFErrorRef* error) {
1362 sec_trace_enter_api(NULL);
1363 sec_trace_return_bool_api(^{
1364 do_if_registered(soscc_CanAuthenticate, error);
1366 return simple_bool_error_request(kSecXPCOpCanAuthenticate, error);
1370 bool SOSCCPurgeUserCredentials(CFErrorRef* error) {
1371 sec_trace_enter_api(NULL);
1372 sec_trace_return_bool_api(^{
1373 do_if_registered(soscc_PurgeUserCredentials, error);
1375 return simple_bool_error_request(kSecXPCOpPurgeUserCredentials, error);
1379 enum DepartureReason SOSCCGetLastDepartureReason(CFErrorRef *error) {
1380 sec_trace_enter_api(NULL);
1381 sec_trace_return_api(enum DepartureReason, ^{
1382 do_if_registered(soscc_GetLastDepartureReason, error);
1384 return (enum DepartureReason) simple_int_error_request(kSecXPCOpGetLastDepartureReason, error);
1388 bool SOSCCSetLastDepartureReason(enum DepartureReason reason, CFErrorRef *error) {
1389 sec_trace_enter_api(NULL);
1390 sec_trace_return_api(bool, ^{
1391 do_if_registered(soscc_SetLastDepartureReason, reason, error);
1392 return securityd_send_sync_and_do(kSecXPCOpSetLastDepartureReason, error,
1393 ^bool(xpc_object_t message, CFErrorRef *error) {
1394 xpc_dictionary_set_int64(message, kSecXPCKeyReason, reason);
1397 ^bool(xpc_object_t response, __unused CFErrorRef *error) {
1398 return xpc_dictionary_get_bool(response, kSecXPCKeyResult);
1404 CFStringRef SOSCCCopyIncompatibilityInfo(CFErrorRef* error) {
1405 sec_trace_enter_api(NULL);
1406 sec_trace_return_api(CFStringRef, ^{
1407 do_if_registered(soscc_CopyIncompatibilityInfo, error);
1409 return simple_cfstring_error_request(kSecXPCOpCopyIncompatibilityInfo, error);
1413 CFStringRef SOSCCCopyDeviceID(CFErrorRef* error)
1415 sec_trace_enter_api(NULL);
1416 sec_trace_return_api(CFStringRef, ^{
1417 do_if_registered(soscc_CopyDeviceID, error);
1418 CFStringRef deviceID = simple_cfstring_error_request(kSecXPCOpRequestDeviceID, error);
1423 bool SOSCCProcessEnsurePeerRegistration(CFErrorRef* error){
1424 secnotice("updates", "enter SOSCCProcessEnsurePeerRegistration");
1425 sec_trace_enter_api(NULL);
1426 sec_trace_return_bool_api(^{
1427 do_if_registered(soscc_EnsurePeerRegistration, error);
1429 return simple_bool_error_request(soscc_EnsurePeerRegistration_id, error);
1434 CFSetRef /* CFString */ SOSCCProcessSyncWithPeers(CFSetRef peers, CFSetRef backupPeers, CFErrorRef* error)
1436 sec_trace_enter_api(NULL);
1437 sec_trace_return_api(CFSetRef, ^{
1438 do_if_registered(soscc_ProcessSyncWithPeers, peers, backupPeers, error);
1440 return cfset_cfset_to_cfset_error_request(kSecXPCOpProcessSyncWithPeers, peers, backupPeers, error);
1445 SyncWithAllPeersReason SOSCCProcessSyncWithAllPeers(CFErrorRef* error)
1447 sec_trace_enter_api(NULL);
1448 sec_trace_return_api(SyncWithAllPeersReason, ^{
1449 do_if_registered(soscc_ProcessSyncWithAllPeers, error);
1451 return (SyncWithAllPeersReason) simple_int_error_request(kSecXPCOpProcessSyncWithAllPeers, error);
1455 CFStringRef SOSCCGetStatusDescription(SOSCCStatus status)
1458 case kSOSCCInCircle:
1459 return CFSTR("InCircle");
1460 case kSOSCCNotInCircle:
1461 return CFSTR("NotInCircle");
1462 case kSOSCCRequestPending:
1463 return CFSTR("RequestPending");
1464 case kSOSCCCircleAbsent:
1465 return CFSTR("CircleAbsent");
1467 return CFSTR("InternalError");
1469 return CFSTR("Unknown Status");
1474 kSOSCCGeneralViewError = -1,
1475 kSOSCCViewMember = 0,
1476 kSOSCCViewNotMember = 1,
1477 kSOSCCViewNotQualified = 2,
1478 kSOSCCNoSuchView = 3,
1482 CFStringRef SOSCCGetViewResultDescription(SOSViewResultCode vrc)
1485 case kSOSCCGeneralViewError:
1486 return CFSTR("GeneralViewError");
1487 case kSOSCCViewMember:
1488 return CFSTR("ViewMember");
1489 case kSOSCCViewNotMember:
1490 return CFSTR("ViewNotMember");
1491 case kSOSCCViewNotQualified:
1492 return CFSTR("ViewNotQualified");
1493 case kSOSCCNoSuchView:
1494 return CFSTR("ViewUndefined");
1496 return CFSTR("Unknown View Status");
1501 static int64_t name_action_to_code_request(enum SecXPCOperation op, uint16_t error_result,
1502 CFStringRef name, uint64_t action, CFErrorRef *error) {
1503 __block int64_t result = error_result;
1505 securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
1506 CFStringPerformWithCString(name, ^(const char *utf8Str) {
1507 xpc_dictionary_set_string(message, kSecXPCKeyViewName, utf8Str);
1509 xpc_dictionary_set_int64(message, kSecXPCKeyViewActionCode, action);
1511 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
1512 if (response && xpc_dictionary_entry_is_type(response, kSecXPCKeyResult, XPC_TYPE_INT64)) {
1513 result = xpc_dictionary_get_int64(response, kSecXPCKeyResult);
1515 return result != error_result;
1521 SOSViewResultCode SOSCCView(CFStringRef view, SOSViewActionCode actionCode, CFErrorRef *error) {
1522 sec_trace_enter_api(NULL);
1523 sec_trace_return_api(SOSViewResultCode, ^{
1524 do_if_registered(soscc_View, view, actionCode, error);
1526 return (SOSViewResultCode) name_action_to_code_request(kSecXPCOpView, kSOSCCGeneralViewError, view, actionCode, error);
1527 }, CFSTR("SOSViewResultCode=%d"))
1531 bool SOSCCViewSet(CFSetRef enabledViews, CFSetRef disabledViews) {
1532 CFErrorRef *error = NULL;
1533 __block bool result = false;
1535 sec_trace_enter_api(NULL);
1536 sec_trace_return_bool_api(^{
1537 do_if_registered(soscc_ViewSet, enabledViews, disabledViews);
1538 return securityd_send_sync_and_do(kSecXPCOpViewSet, error, ^bool(xpc_object_t message, CFErrorRef *error) {
1539 xpc_object_t enabledSetXpc = CreateXPCObjectWithCFSetRef(enabledViews, error);
1540 xpc_object_t disabledSetXpc = CreateXPCObjectWithCFSetRef(disabledViews, error);
1541 if (enabledSetXpc) xpc_dictionary_set_value(message, kSecXPCKeyEnabledViewsKey, enabledSetXpc);
1542 if (disabledSetXpc) xpc_dictionary_set_value(message, kSecXPCKeyDisabledViewsKey, disabledSetXpc);
1543 return (enabledSetXpc != NULL) || (disabledSetXpc != NULL) ;
1544 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
1545 result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
1551 SOSSecurityPropertyResultCode SOSCCSecurityProperty(CFStringRef property, SOSSecurityPropertyActionCode actionCode, CFErrorRef *error) {
1552 sec_trace_enter_api(NULL);
1553 sec_trace_return_api(SOSSecurityPropertyResultCode, ^{
1554 SOSSecurityPropertyResultCode result = kSOSCCGeneralSecurityPropertyError;
1555 do_if_registered(soscc_SecurityProperty, property, actionCode, error);
1556 xpc_object_t message = securityd_create_message(kSecXPCOpSecurityProperty, error);
1558 int64_t bigac = actionCode;
1559 xpc_dictionary_set_string(message, kSecXPCKeyViewName, CFStringGetCStringPtr(property, kCFStringEncodingUTF8));
1560 xpc_dictionary_set_int64(message, kSecXPCKeyViewActionCode, bigac);
1562 xpc_object_t response = securityd_message_with_reply_sync(message, error);
1564 if (response && xpc_dictionary_entry_is_type(response, kSecXPCKeyResult, XPC_TYPE_INT64)) {
1565 result = (SOSSecurityPropertyResultCode) xpc_dictionary_get_int64(response, kSecXPCKeyResult);
1568 if (result == kSOSCCGeneralSecurityPropertyError) {
1569 if (response && securityd_message_no_error(response, error)) {
1570 char *desc = xpc_copy_description(response);
1571 SecCFCreateErrorWithFormat(0, sSecXPCErrorDomain, NULL, error, NULL, CFSTR("Remote error occurred/no info: %s"), desc);
1582 }, CFSTR("SOSSecurityPropertyResultCode=%d"))
1585 static CFStringRef copyViewNames(size_t n, CFStringRef *views) {
1586 CFMutableStringRef retval = CFStringCreateMutable(kCFAllocatorDefault, 0);
1587 CFStringAppend(retval, CFSTR("|"));
1588 for(size_t i = 0; i < n; i++) {
1589 CFStringAppend(retval, views[i]);
1590 CFStringAppend(retval, CFSTR("|"));
1595 static bool sosIsViewSetSyncing(size_t n, CFStringRef *views) {
1596 __block bool retval = true;
1597 CFErrorRef error = NULL;
1599 if(n == 0 || views == NULL) return false;
1600 CFStringRef viewString = copyViewNames(n, views);
1602 SOSCCStatus cstatus = SOSCCThisDeviceIsInCircle(&error);
1603 if(cstatus != kSOSCCInCircle) {
1604 secnotice("viewCheck", "Checking view / circle status for %@: SOSCCStatus: (%@) Error: (%@)", viewString, SOSCCGetStatusDescription(cstatus), error);
1608 if(retval == true) {
1609 for(size_t i = 0; i < n; i++) {
1610 SOSViewResultCode vstatus = SOSCCView(views[i], kSOSCCViewQuery, &error);
1611 if(vstatus != kSOSCCViewMember) {
1612 secnotice("viewCheck", "Checking view / circle status for %@: SOSCCStatus: (%@) SOSViewResultCode(%@) Error: (%@)", views[i],
1613 SOSCCGetStatusDescription(cstatus), SOSCCGetViewResultDescription(vstatus), error);
1619 if(retval == true) {
1620 secnotice("viewCheck", "Checking view / circle status for %@: ENABLED", viewString);
1622 CFReleaseNull(error);
1623 CFReleaseNull(viewString);
1627 bool SOSCCIsIcloudKeychainSyncing(void) {
1628 CFStringRef views[] = { kSOSViewWiFi, kSOSViewAutofillPasswords, kSOSViewSafariCreditCards, kSOSViewOtherSyncable };
1629 return sosIsViewSetSyncing(sizeof(views)/sizeof(views[0]), views);
1632 bool SOSCCIsSafariSyncing(void) {
1633 CFStringRef views[] = { kSOSViewAutofillPasswords, kSOSViewSafariCreditCards };
1634 return sosIsViewSetSyncing(sizeof(views)/sizeof(views[0]), views);
1637 bool SOSCCIsAppleTVSyncing(void) {
1638 CFStringRef views[] = { kSOSViewAppleTV };
1639 return sosIsViewSetSyncing(sizeof(views)/sizeof(views[0]), views);
1642 bool SOSCCIsHomeKitSyncing(void) {
1643 CFStringRef views[] = { kSOSViewHomeKit };
1644 return sosIsViewSetSyncing(sizeof(views)/sizeof(views[0]), views);
1647 bool SOSCCIsWiFiSyncing(void) {
1648 CFStringRef views[] = { kSOSViewWiFi };
1649 return sosIsViewSetSyncing(sizeof(views)/sizeof(views[0]), views);
1652 bool SOSCCIsContinuityUnlockSyncing(void) {
1653 CFStringRef views[] = { kSOSViewContinuityUnlock };
1654 return sosIsViewSetSyncing(sizeof(views)/sizeof(views[0]), views);
1658 bool SOSCCSetEscrowRecord(CFStringRef escrow_label, uint64_t tries, CFErrorRef *error ){
1659 secnotice("escrow", "enter SOSCCSetEscrowRecord");
1660 sec_trace_enter_api(NULL);
1661 sec_trace_return_bool_api(^{
1662 do_if_registered(soscc_SetEscrowRecords, escrow_label, tries, error);
1664 return escrow_to_bool_error_request(kSecXPCOpSetEscrowRecord, escrow_label, tries, error);
1668 CFDictionaryRef SOSCCCopyEscrowRecord(CFErrorRef *error){
1669 secnotice("escrow", "enter SOSCCCopyEscrowRecord");
1670 sec_trace_enter_api(NULL);
1671 sec_trace_return_api(CFDictionaryRef, ^{
1672 do_if_registered(soscc_CopyEscrowRecords, error);
1674 return strings_to_dictionary_error_request(kSecXPCOpGetEscrowRecord, error);
1675 }, CFSTR("return=%@"))
1679 CFDictionaryRef SOSCCCopyBackupInformation(CFErrorRef *error) {
1680 secnotice("escrow", "enter SOSCCCopyBackupInformation");
1681 sec_trace_enter_api(NULL);
1682 sec_trace_return_api(CFDictionaryRef, ^{
1683 do_if_registered(soscc_CopyBackupInformation, error);
1684 return strings_to_dictionary_error_request(kSecXPCOpCopyBackupInformation, error);
1685 }, CFSTR("return=%@"))
1688 bool SOSCCCheckPeerAvailability(CFErrorRef *error){
1689 secnotice("peer", "enter SOSCCCheckPeerAvailability");
1690 sec_trace_enter_api(NULL);
1691 sec_trace_return_bool_api(^{
1692 do_if_registered(soscc_PeerAvailability, error);
1694 return simple_bool_error_request(kSecXPCOpCheckPeerAvailability, error);
1700 bool SOSWrapToBackupSliceKeyBagForView(CFStringRef viewName, CFDataRef input, CFDataRef* output, CFDataRef* bskbEncoded, CFErrorRef* error) {
1701 sec_trace_enter_api(NULL);
1702 sec_trace_return_bool_api(^{
1703 do_if_registered(sosbskb_WrapToBackupSliceKeyBagForView, viewName, input, output, bskbEncoded, error);
1705 return cfstring_and_cfdata_to_cfdata_cfdata_error_request(kSecXPCOpWrapToBackupSliceKeyBagForView, viewName, input, output, bskbEncoded, error);
1710 SOSPeerInfoRef SOSCCCopyApplication(CFErrorRef *error) {
1711 secnotice("hsa2PB", "enter SOSCCCopyApplication applicant");
1712 sec_trace_enter_api(NULL);
1714 sec_trace_return_api(SOSPeerInfoRef, ^{
1715 do_if_registered(soscc_CopyApplicant, error);
1716 return peer_info_error_request(kSecXPCOpCopyApplication, error);
1717 }, CFSTR("return=%@"));
1720 bool SOSCCCleanupKVSKeys(CFErrorRef *error) {
1721 secnotice("cleanup-keys", "enter SOSCCCleanupKVSKeys");
1722 sec_trace_enter_api(NULL);
1723 sec_trace_return_bool_api(^{
1724 do_if_registered(soscc_SOSCCCleanupKVSKeys, error);
1726 return simple_bool_error_request(kSecXPCOpKVSKeyCleanup, error);
1732 bool SOSCCTestPopulateKVSWithBadKeys(CFErrorRef *error) {
1733 secnotice("cleanup-keys", "enter SOSCCPopulateKVSWithBadKeys");
1734 sec_trace_enter_api(NULL);
1735 sec_trace_return_bool_api(^{
1736 do_if_registered(soscc_SOSCCTestPopulateKVSWithBadKeys, error);
1738 return simple_bool_error_request(kSecXPCOpPopulateKVS, error);
1744 CFDataRef SOSCCCopyCircleJoiningBlob(SOSPeerInfoRef applicant, CFErrorRef *error) {
1745 secnotice("hsa2PB", "enter SOSCCCopyCircleJoiningBlob approver");
1746 sec_trace_enter_api(NULL);
1748 sec_trace_return_api(CFDataRef, ^{
1749 CFDataRef result = NULL;
1750 do_if_registered(soscc_CopyCircleJoiningBlob, applicant, error);
1751 CFDataRef piData = SOSPeerInfoCopyEncodedData(applicant, kCFAllocatorDefault, error);
1752 result = cfdata_error_request_returns_cfdata(kSecXPCOpCopyCircleJoiningBlob, piData, error);
1753 CFReleaseNull(piData);
1755 }, CFSTR("return=%@"));
1758 CFDataRef SOSCCCopyInitialSyncData(CFErrorRef *error) {
1759 secnotice("circleJoin", "enter SOSCCCopyInitialSyncData approver");
1760 sec_trace_enter_api(NULL);
1762 sec_trace_return_api(CFDataRef, ^{
1763 do_if_registered(soscc_CopyInitialSyncData, error);
1764 return data_to_error_request(kSecXPCOpCopyInitialSyncBlob, error);
1765 }, CFSTR("return=%@"));
1768 bool SOSCCJoinWithCircleJoiningBlob(CFDataRef joiningBlob, PiggyBackProtocolVersion version, CFErrorRef *error) {
1769 secnotice("hsa2PB", "enter SOSCCJoinWithCircleJoiningBlob applicant");
1770 sec_trace_enter_api(NULL);
1771 sec_trace_return_bool_api(^{
1772 do_if_registered(soscc_JoinWithCircleJoiningBlob, joiningBlob, version, error);
1774 return cfdata_and_int_error_request_returns_bool(kSecXPCOpJoinWithCircleJoiningBlob, joiningBlob, version, error);
1780 bool SOSCCIsThisDeviceLastBackup(CFErrorRef *error) {
1781 secnotice("peer", "enter SOSCCIsThisDeviceLastBackup");
1782 sec_trace_enter_api(NULL);
1783 sec_trace_return_bool_api(^{
1784 do_if_registered(soscc_IsThisDeviceLastBackup, error);
1786 return simple_bool_error_request(kSecXPCOpIsThisDeviceLastBackup, error);
1790 CFBooleanRef SOSCCPeersHaveViewsEnabled(CFArrayRef viewNames, CFErrorRef *error) {
1791 secnotice("view-enabled", "enter SOSCCPeersHaveViewsEnabled");
1792 sec_trace_enter_api(NULL);
1793 sec_trace_return_api(CFBooleanRef, ^{
1794 do_if_registered(soscc_SOSCCPeersHaveViewsEnabled, viewNames, error);
1796 return cfarray_to_cfboolean_error_request(kSecXPCOpPeersHaveViewsEnabled, viewNames, error);
1797 }, CFSTR("return=%@"))
1800 bool SOSCCMessageFromPeerIsPending(SOSPeerInfoRef peer, CFErrorRef *error) {
1801 secnotice("pending-check", "enter SOSCCMessageFromPeerIsPending");
1803 sec_trace_return_bool_api(^{
1804 do_if_registered(soscc_SOSCCMessageFromPeerIsPending, peer, error);
1806 return peer_info_to_bool_error_request(kSecXPCOpMessageFromPeerIsPending, peer, error);
1811 bool SOSCCSendToPeerIsPending(SOSPeerInfoRef peer, CFErrorRef *error) {
1812 sec_trace_return_bool_api(^{
1813 do_if_registered(soscc_SOSCCSendToPeerIsPending, peer, error);
1815 return peer_info_to_bool_error_request(kSecXPCOpSendToPeerIsPending, peer, error);
1820 * SecSOSStatus interfaces
1823 @interface SecSOSStatus : NSObject {
1824 NSXPCConnection* _connection;
1826 @property NSXPCConnection *connection;
1829 @implementation SecSOSStatus
1830 @synthesize connection = _connection;
1832 - (instancetype) initWithEndpoint:(xpc_endpoint_t)endpoint
1834 if ((self = [super init]) == NULL)
1837 NSXPCInterface *interface = [NSXPCInterface interfaceWithProtocol:@protocol(SOSControlProtocol)];
1838 _SOSControlSetupInterface(interface);
1839 NSXPCListenerEndpoint *listenerEndpoint = [[NSXPCListenerEndpoint alloc] init];
1841 [listenerEndpoint _setEndpoint:endpoint];
1843 self.connection = [[NSXPCConnection alloc] initWithListenerEndpoint:listenerEndpoint];
1844 if (self.connection == NULL)
1847 self.connection.remoteObjectInterface = interface;
1849 [self.connection resume];
1856 static id<SOSControlProtocol>
1857 SOSCCGetStatusObject(CFErrorRef *error)
1859 if (gSecurityd && gSecurityd->soscc_status)
1860 return (__bridge id<SOSControlProtocol>)gSecurityd->soscc_status();
1862 static SecSOSStatus *control;
1863 static dispatch_once_t onceToken;
1864 dispatch_once(&onceToken, ^{
1865 xpc_endpoint_t endpoint = _SecSecuritydCopySOSStatusEndpoint(error);
1866 if (endpoint == NULL)
1869 control = [[SecSOSStatus alloc] initWithEndpoint:endpoint];
1871 return control.connection.remoteObjectProxy;
1875 SOSCCAccountGetPublicKey(void (^reply)(BOOL trusted, NSData *data, NSError *error))
1877 CFErrorRef error = NULL;
1878 id<SOSControlProtocol> status = SOSCCGetStatusObject(&error);
1879 if (status == NULL) {
1880 reply(false, NULL, (__bridge NSError *)error);
1881 CFReleaseNull(error);
1885 [status userPublicKey:reply];
1889 SOSCCAccountGetAccountPrivateCredential(void (^complete)(NSData *data, NSError *error))
1891 CFErrorRef error = NULL;
1892 id<SOSControlProtocol> status = SOSCCGetStatusObject(&error);
1893 if (status == NULL) {
1894 complete(NULL, (__bridge NSError *)error);
1895 CFReleaseNull(error);
1899 [status validatedStashedAccountCredential:complete];
1903 SOSCCAccountGetKeyCircleGeneration(void (^reply)(NSData *data, NSError *error))
1905 SOSCCAccountGetPublicKey(^(BOOL __unused trusted, NSData *data, NSError *error){
1909 NSMutableData *digest = [NSMutableData dataWithLength:CCSHA256_OUTPUT_SIZE];
1910 ccdigest(ccsha256_di(), [data length], [data bytes], [digest mutableBytes]);
1911 reply(digest, error);