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 CF_RETURNS_RETAINED 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 ((NULL != temp_result) && data) {
563 *data = _CFXPCCreateCFObjectFromXPCObject(temp_result);
565 temp_result = xpc_dictionary_get_value(response, kSecXPCKeyKeybag);
566 if ((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 secnotice("devRecovery", "Enter SOSCCCopyMyPeerWithNewDeviceRecoverySecret()");
1079 CFDataRef publicKeyData = SOSCopyDeviceBackupPublicKey(secret, error);
1080 secnotice("devRecovery", "SOSCopyDeviceBackupPublicKey (%@)", publicKeyData);
1081 SOSPeerInfoRef copiedPeer = publicKeyData ? SOSSetNewPublicBackupKey(publicKeyData, error) : NULL;
1082 secnotice("devRecovery", "SOSSetNewPublicBackupKey (%@)", copiedPeer);
1083 CFReleaseNull(publicKeyData);
1087 bool SOSCCRegisterSingleRecoverySecret(CFDataRef aks_bag, bool forV0Only, CFErrorRef *error){
1088 sec_trace_enter_api(NULL);
1089 sec_trace_return_bool_api(^{
1090 do_if_registered(soscc_RegisterSingleRecoverySecret, aks_bag, forV0Only, error);
1091 return keybag_and_bool_to_bool_error_request(kSecXPCOpSetBagForAllSlices, aks_bag, forV0Only, error);
1096 bool SOSCCRegisterRecoveryPublicKey(CFDataRef recovery_key, CFErrorRef *error){
1097 sec_trace_enter_api(NULL);
1098 sec_trace_return_bool_api(^{
1099 bool retval = false;
1100 do_if_registered(soscc_RegisterRecoveryPublicKey, recovery_key, error);
1101 // NULL recovery_key is handled in recovery_and_bool_to_bool_error_request now.
1102 retval = recovery_and_bool_to_bool_error_request(kSecXPCOpRegisterRecoveryPublicKey, recovery_key, error);
1107 CFDataRef SOSCCCopyRecoveryPublicKey(CFErrorRef *error){
1108 sec_trace_enter_api(NULL);
1109 sec_trace_return_api(CFDataRef, ^{
1110 do_if_registered(soscc_CopyRecoveryPublicKey, error);
1111 return data_to_error_request(kSecXPCOpGetRecoveryPublicKey, error);
1112 }, CFSTR("return=%@"));
1114 static bool label_and_password_to_bool_error_request(enum SecXPCOperation op,
1115 CFStringRef user_label, CFDataRef user_password,
1118 __block bool result = false;
1120 securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
1121 CFStringPerformWithCString(user_label, ^(const char *utf8Str) {
1122 xpc_dictionary_set_string(message, kSecXPCKeyUserLabel, utf8Str);
1124 xpc_dictionary_set_data(message, kSecXPCKeyUserPassword, CFDataGetBytePtr(user_password), CFDataGetLength(user_password));
1126 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
1127 result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
1134 static bool label_and_password_and_dsid_to_bool_error_request(enum SecXPCOperation op,
1135 CFStringRef user_label, CFDataRef user_password,
1136 CFStringRef dsid, CFErrorRef* error)
1138 __block bool result = false;
1140 securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
1141 CFStringPerformWithCString(user_label, ^(const char *utf8Str) {
1142 xpc_dictionary_set_string(message, kSecXPCKeyUserLabel, utf8Str);
1144 CFStringPerformWithCString(dsid, ^(const char *utr8StrDSID) {
1145 xpc_dictionary_set_string(message, kSecXPCKeyDSID, utr8StrDSID);
1147 xpc_dictionary_set_data(message, kSecXPCKeyUserPassword, CFDataGetBytePtr(user_password), CFDataGetLength(user_password));
1149 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
1150 result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
1157 static bool cfstring_to_bool_error_request(enum SecXPCOperation op,
1161 __block bool result = false;
1163 securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
1164 CFStringPerformWithCString(string, ^(const char *utf8Str) {
1165 xpc_dictionary_set_string(message, kSecXPCKeyDeviceID, utf8Str);
1168 }, ^bool(xpc_object_t response, CFErrorRef *error) {
1169 result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
1176 static int idsDict_to_int_error_request(enum SecXPCOperation op,
1177 CFDictionaryRef IDS,
1180 __block int result = 0;
1182 securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
1183 SecXPCDictionarySetPListOptional(message, kSecXPCKeyIDSMessage, IDS, error);
1185 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
1186 int64_t temp_result = xpc_dictionary_get_int64(response, kSecXPCKeyResult);
1187 if ((temp_result >= INT32_MIN) && (temp_result <= INT32_MAX)) {
1188 result = (int)temp_result;
1196 static bool idsData_peerID_to_bool_error_request(enum SecXPCOperation op, CFStringRef peerID,
1197 CFDataRef IDSMessage,
1200 __block bool result = 0;
1202 securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
1203 SecXPCDictionarySetData(message, kSecXPCKeyIDSMessage, IDSMessage, error);
1204 SecXPCDictionarySetString(message, kSecXPCKeyDeviceID, peerID, error);
1206 }, ^bool(xpc_object_t response, CFErrorRef *error) {
1207 result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
1213 static bool idscommand_to_bool_error_request(enum SecXPCOperation op,
1214 CFStringRef idsMessage,
1217 __block bool result = false;
1219 securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
1220 CFStringPerformWithCString(idsMessage, ^(const char *utf8Str) {
1221 xpc_dictionary_set_string(message, kSecXPCKeySendIDSMessage, utf8Str);
1224 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
1225 result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
1232 bool SOSCCRegisterUserCredentials(CFStringRef user_label, CFDataRef user_password, CFErrorRef* error)
1234 secnotice("circleOps", "SOSCCRegisterUserCredentials - calling SOSCCSetUserCredentials for %@\n", user_label);
1235 return SOSCCSetUserCredentials(user_label, user_password, error);
1238 bool SOSCCSetUserCredentials(CFStringRef user_label, CFDataRef user_password, CFErrorRef* error)
1240 secnotice("circleOps", "SOSCCSetUserCredentials for %@\n", user_label);
1241 sec_trace_enter_api(CFSTR("user_label=%@"), user_label);
1242 sec_trace_return_bool_api(^{
1243 do_if_registered(soscc_SetUserCredentials, user_label, user_password, error);
1245 return label_and_password_to_bool_error_request(kSecXPCOpSetUserCredentials, user_label, user_password, error);
1249 bool SOSCCSetUserCredentialsAndDSID(CFStringRef user_label, CFDataRef user_password, CFStringRef dsid, CFErrorRef *error)
1251 secnotice("circleOps", "SOSCCSetUserCredentialsAndDSID for %@\n", user_label);
1252 sec_trace_enter_api(CFSTR("user_label=%@"), user_label);
1253 sec_trace_return_bool_api(^{
1254 do_if_registered(soscc_SetUserCredentialsAndDSID, user_label, user_password, dsid, error);
1256 bool result = false;
1257 __block CFStringRef account_dsid = dsid;
1259 require_action_quiet(user_label, out, SOSErrorCreate(kSOSErrorParam, error, NULL, CFSTR("user_label is nil")));
1260 require_action_quiet(user_password, out, SOSErrorCreate(kSOSErrorParam, error, NULL, CFSTR("user_password is nil")));
1262 if(account_dsid == NULL){
1263 account_dsid = CFSTR("");
1265 return label_and_password_and_dsid_to_bool_error_request(kSecXPCOpSetUserCredentialsAndDSID, user_label, user_password, account_dsid, error);
1273 bool SOSCCSetDeviceID(CFStringRef IDS, CFErrorRef* error)
1275 secnotice("sosops", "SOSCCSetDeviceID!! %@\n", IDS);
1276 sec_trace_enter_api(NULL);
1277 sec_trace_return_bool_api(^{
1278 do_if_registered(soscc_SetDeviceID, IDS, error);
1279 bool result = cfstring_to_bool_error_request(kSecXPCOpSetDeviceID, IDS, error);
1284 bool SOSCCIDSServiceRegistrationTest(CFStringRef message, CFErrorRef *error)
1286 secnotice("sosops", "SOSCCSendIDSTestMessage!! %@\n", message);
1287 sec_trace_enter_api(NULL);
1288 sec_trace_return_bool_api(^{
1289 do_if_registered(soscc_CheckIDSRegistration, message, error);
1290 return idscommand_to_bool_error_request(kSecXPCOpSendIDSMessage, message, error);
1294 bool SOSCCIDSPingTest(CFStringRef message, CFErrorRef *error)
1296 secnotice("sosops", "SOSCCSendIDSTestMessage!! %@\n", message);
1297 sec_trace_enter_api(NULL);
1298 sec_trace_return_bool_api(^{
1299 do_if_registered(soscc_PingTest, message, error);
1300 return idscommand_to_bool_error_request(kSecXPCOpPingTest, message, error);
1304 bool SOSCCIDSDeviceIDIsAvailableTest(CFErrorRef *error)
1306 secnotice("sosops", "SOSCCIDSDeviceIDIsAvailableTest!!\n");
1307 sec_trace_enter_api(NULL);
1308 sec_trace_return_bool_api(^{
1309 do_if_registered(soscc_GetIDSIDFromIDS, error);
1310 return simple_bool_error_request(kSecXPCOpIDSDeviceID, error);
1314 HandleIDSMessageReason SOSCCHandleIDSMessage(CFDictionaryRef IDS, CFErrorRef* error)
1316 secnotice("sosops", "SOSCCHandleIDSMessage!! %@\n", IDS);
1317 sec_trace_enter_api(NULL);
1318 sec_trace_return_api(HandleIDSMessageReason, ^{
1319 do_if_registered(soscc_HandleIDSMessage, IDS, error);
1320 return (HandleIDSMessageReason) idsDict_to_int_error_request(kSecXPCOpHandleIDSMessage, IDS, error);
1324 bool SOSCCClearPeerMessageKeyInKVS(CFStringRef peerID, CFErrorRef *error)
1326 secnotice("sosops", "SOSCCClearPeerMessageKeyInKVS!! %@\n", peerID);
1327 sec_trace_enter_api(NULL);
1328 sec_trace_return_bool_api(^{
1329 do_if_registered(socc_clearPeerMessageKeyInKVS, peerID, error);
1330 return cfstring_to_bool_error_request(kSecXPCOpClearKVSPeerMessage, peerID, error);
1335 bool SOSCCRequestSyncWithPeerOverKVSUsingIDOnly(CFStringRef peerID, CFErrorRef *error)
1337 secnotice("sosops", "SOSCCRequestSyncWithPeerOverKVSUsingIDOnly!! %@\n", peerID);
1338 sec_trace_enter_api(NULL);
1339 sec_trace_return_bool_api(^{
1340 do_if_registered(soscc_requestSyncWithPeerOverKVSIDOnly, peerID, error);
1341 return deviceid_to_bool_error_request(kSecXPCOpSyncWithKVSPeerIDOnly, peerID, error);
1345 bool SOSCCRequestSyncWithPeerOverKVS(CFStringRef peerID, CFDataRef message, CFErrorRef *error)
1347 secnotice("sosops", "SOSCCRequestSyncWithPeerOverKVS!! %@\n", peerID);
1348 sec_trace_enter_api(NULL);
1349 sec_trace_return_bool_api(^{
1350 do_if_registered(soscc_requestSyncWithPeerOverKVS, peerID, message, error);
1351 return idsData_peerID_to_bool_error_request(kSecXPCOpSyncWithKVSPeer, peerID, message, error);
1355 static bool SOSCCTryUserCredentialsAndDSID_internal(CFStringRef user_label, CFDataRef user_password, CFStringRef dsid, CFErrorRef *error) {
1356 sec_trace_return_bool_api(^{
1357 do_if_registered(soscc_TryUserCredentials, user_label, user_password, dsid, error);
1359 bool result = false;
1360 __block CFStringRef account_dsid = dsid;
1362 require_action_quiet(user_label, out, SOSErrorCreate(kSOSErrorParam, error, NULL, CFSTR("user_label is nil")));
1363 require_action_quiet(user_password, out, SOSErrorCreate(kSOSErrorParam, error, NULL, CFSTR("user_password is nil")));
1365 if(account_dsid == NULL){
1366 account_dsid = CFSTR("");
1369 return label_and_password_and_dsid_to_bool_error_request(kSecXPCOpTryUserCredentials, user_label, user_password, account_dsid, error);
1377 bool SOSCCTryUserCredentialsAndDSID(CFStringRef user_label, CFDataRef user_password, CFStringRef dsid, CFErrorRef *error)
1379 secnotice("sosops", "SOSCCTryUserCredentialsAndDSID!! %@\n", user_label);
1380 require_action_quiet(user_label, out, SOSErrorCreate(kSOSErrorParam, error, NULL, CFSTR("user_label is nil")));
1381 require_action_quiet(user_password, out, SOSErrorCreate(kSOSErrorParam, error, NULL, CFSTR("user_password is nil")));
1382 CFStringRef account_dsid = (dsid != NULL) ? dsid: CFSTR("");
1383 return SOSCCTryUserCredentialsAndDSID_internal(user_label, user_password, account_dsid, error);
1388 bool SOSCCTryUserCredentials(CFStringRef user_label, CFDataRef user_password, CFErrorRef* error) {
1389 return SOSCCTryUserCredentialsAndDSID_internal(user_label, user_password, NULL, error);
1393 bool SOSCCCanAuthenticate(CFErrorRef* error) {
1394 sec_trace_enter_api(NULL);
1395 sec_trace_return_bool_api(^{
1396 do_if_registered(soscc_CanAuthenticate, error);
1398 return simple_bool_error_request(kSecXPCOpCanAuthenticate, error);
1402 bool SOSCCPurgeUserCredentials(CFErrorRef* error) {
1403 sec_trace_enter_api(NULL);
1404 sec_trace_return_bool_api(^{
1405 do_if_registered(soscc_PurgeUserCredentials, error);
1407 return simple_bool_error_request(kSecXPCOpPurgeUserCredentials, error);
1411 enum DepartureReason SOSCCGetLastDepartureReason(CFErrorRef *error) {
1412 sec_trace_enter_api(NULL);
1413 sec_trace_return_api(enum DepartureReason, ^{
1414 do_if_registered(soscc_GetLastDepartureReason, error);
1416 return (enum DepartureReason) simple_int_error_request(kSecXPCOpGetLastDepartureReason, error);
1420 bool SOSCCSetLastDepartureReason(enum DepartureReason reason, CFErrorRef *error) {
1421 sec_trace_enter_api(NULL);
1422 sec_trace_return_api(bool, ^{
1423 do_if_registered(soscc_SetLastDepartureReason, reason, error);
1424 return securityd_send_sync_and_do(kSecXPCOpSetLastDepartureReason, error,
1425 ^bool(xpc_object_t message, CFErrorRef *error) {
1426 xpc_dictionary_set_int64(message, kSecXPCKeyReason, reason);
1429 ^bool(xpc_object_t response, __unused CFErrorRef *error) {
1430 return xpc_dictionary_get_bool(response, kSecXPCKeyResult);
1436 CFStringRef SOSCCCopyIncompatibilityInfo(CFErrorRef* error) {
1437 sec_trace_enter_api(NULL);
1438 sec_trace_return_api(CFStringRef, ^{
1439 do_if_registered(soscc_CopyIncompatibilityInfo, error);
1441 return simple_cfstring_error_request(kSecXPCOpCopyIncompatibilityInfo, error);
1445 CFStringRef SOSCCCopyDeviceID(CFErrorRef* error)
1447 sec_trace_enter_api(NULL);
1448 sec_trace_return_api(CFStringRef, ^{
1449 do_if_registered(soscc_CopyDeviceID, error);
1450 CFStringRef deviceID = simple_cfstring_error_request(kSecXPCOpRequestDeviceID, error);
1455 bool SOSCCProcessEnsurePeerRegistration(CFErrorRef* error){
1456 secnotice("updates", "enter SOSCCProcessEnsurePeerRegistration");
1457 sec_trace_enter_api(NULL);
1458 sec_trace_return_bool_api(^{
1459 do_if_registered(soscc_EnsurePeerRegistration, error);
1461 return simple_bool_error_request(soscc_EnsurePeerRegistration_id, error);
1466 CFSetRef /* CFString */ SOSCCProcessSyncWithPeers(CFSetRef peers, CFSetRef backupPeers, CFErrorRef* error)
1468 sec_trace_enter_api(NULL);
1469 sec_trace_return_api(CFSetRef, ^{
1470 do_if_registered(soscc_ProcessSyncWithPeers, peers, backupPeers, error);
1472 return cfset_cfset_to_cfset_error_request(kSecXPCOpProcessSyncWithPeers, peers, backupPeers, error);
1477 SyncWithAllPeersReason SOSCCProcessSyncWithAllPeers(CFErrorRef* error)
1479 sec_trace_enter_api(NULL);
1480 sec_trace_return_api(SyncWithAllPeersReason, ^{
1481 do_if_registered(soscc_ProcessSyncWithAllPeers, error);
1483 return (SyncWithAllPeersReason) simple_int_error_request(kSecXPCOpProcessSyncWithAllPeers, error);
1487 CFStringRef SOSCCGetStatusDescription(SOSCCStatus status)
1490 case kSOSCCInCircle:
1491 return CFSTR("InCircle");
1492 case kSOSCCNotInCircle:
1493 return CFSTR("NotInCircle");
1494 case kSOSCCRequestPending:
1495 return CFSTR("RequestPending");
1496 case kSOSCCCircleAbsent:
1497 return CFSTR("CircleAbsent");
1499 return CFSTR("InternalError");
1501 return CFSTR("Unknown Status");
1506 kSOSCCGeneralViewError = -1,
1507 kSOSCCViewMember = 0,
1508 kSOSCCViewNotMember = 1,
1509 kSOSCCViewNotQualified = 2,
1510 kSOSCCNoSuchView = 3,
1514 CFStringRef SOSCCGetViewResultDescription(SOSViewResultCode vrc)
1517 case kSOSCCGeneralViewError:
1518 return CFSTR("GeneralViewError");
1519 case kSOSCCViewMember:
1520 return CFSTR("ViewMember");
1521 case kSOSCCViewNotMember:
1522 return CFSTR("ViewNotMember");
1523 case kSOSCCViewNotQualified:
1524 return CFSTR("ViewNotQualified");
1525 case kSOSCCNoSuchView:
1526 return CFSTR("ViewUndefined");
1528 return CFSTR("Unknown View Status");
1533 static int64_t name_action_to_code_request(enum SecXPCOperation op, uint16_t error_result,
1534 CFStringRef name, uint64_t action, CFErrorRef *error) {
1535 __block int64_t result = error_result;
1537 securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
1538 CFStringPerformWithCString(name, ^(const char *utf8Str) {
1539 xpc_dictionary_set_string(message, kSecXPCKeyViewName, utf8Str);
1541 xpc_dictionary_set_int64(message, kSecXPCKeyViewActionCode, action);
1543 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
1544 if (response && xpc_dictionary_entry_is_type(response, kSecXPCKeyResult, XPC_TYPE_INT64)) {
1545 result = xpc_dictionary_get_int64(response, kSecXPCKeyResult);
1547 return result != error_result;
1553 SOSViewResultCode SOSCCView(CFStringRef view, SOSViewActionCode actionCode, CFErrorRef *error) {
1554 sec_trace_enter_api(NULL);
1555 sec_trace_return_api(SOSViewResultCode, ^{
1556 do_if_registered(soscc_View, view, actionCode, error);
1558 return (SOSViewResultCode) name_action_to_code_request(kSecXPCOpView, kSOSCCGeneralViewError, view, actionCode, error);
1559 }, CFSTR("SOSViewResultCode=%d"))
1563 bool SOSCCViewSet(CFSetRef enabledViews, CFSetRef disabledViews) {
1564 CFErrorRef *error = NULL;
1565 __block bool result = false;
1567 sec_trace_enter_api(NULL);
1568 sec_trace_return_bool_api(^{
1569 do_if_registered(soscc_ViewSet, enabledViews, disabledViews);
1570 return securityd_send_sync_and_do(kSecXPCOpViewSet, error, ^bool(xpc_object_t message, CFErrorRef *error) {
1571 xpc_object_t enabledSetXpc = CreateXPCObjectWithCFSetRef(enabledViews, error);
1572 xpc_object_t disabledSetXpc = CreateXPCObjectWithCFSetRef(disabledViews, error);
1573 if (enabledSetXpc) xpc_dictionary_set_value(message, kSecXPCKeyEnabledViewsKey, enabledSetXpc);
1574 if (disabledSetXpc) xpc_dictionary_set_value(message, kSecXPCKeyDisabledViewsKey, disabledSetXpc);
1575 return (enabledSetXpc != NULL) || (disabledSetXpc != NULL) ;
1576 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
1577 result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
1583 SOSSecurityPropertyResultCode SOSCCSecurityProperty(CFStringRef property, SOSSecurityPropertyActionCode actionCode, CFErrorRef *error) {
1584 sec_trace_enter_api(NULL);
1585 sec_trace_return_api(SOSSecurityPropertyResultCode, ^{
1586 SOSSecurityPropertyResultCode result = kSOSCCGeneralSecurityPropertyError;
1587 do_if_registered(soscc_SecurityProperty, property, actionCode, error);
1588 xpc_object_t message = securityd_create_message(kSecXPCOpSecurityProperty, error);
1590 int64_t bigac = actionCode;
1591 xpc_dictionary_set_string(message, kSecXPCKeyViewName, CFStringGetCStringPtr(property, kCFStringEncodingUTF8));
1592 xpc_dictionary_set_int64(message, kSecXPCKeyViewActionCode, bigac);
1594 xpc_object_t response = securityd_message_with_reply_sync(message, error);
1596 if (response && xpc_dictionary_entry_is_type(response, kSecXPCKeyResult, XPC_TYPE_INT64)) {
1597 result = (SOSSecurityPropertyResultCode) xpc_dictionary_get_int64(response, kSecXPCKeyResult);
1600 if (result == kSOSCCGeneralSecurityPropertyError) {
1601 if (response && securityd_message_no_error(response, error)) {
1602 char *desc = xpc_copy_description(response);
1603 SecCFCreateErrorWithFormat(0, sSecXPCErrorDomain, NULL, error, NULL, CFSTR("Remote error occurred/no info: %s"), desc);
1614 }, CFSTR("SOSSecurityPropertyResultCode=%d"))
1617 static CFStringRef copyViewNames(size_t n, CFStringRef *views) {
1618 CFMutableStringRef retval = CFStringCreateMutable(kCFAllocatorDefault, 0);
1619 CFStringAppend(retval, CFSTR("|"));
1620 for(size_t i = 0; i < n; i++) {
1621 CFStringAppend(retval, views[i]);
1622 CFStringAppend(retval, CFSTR("|"));
1627 static bool sosIsViewSetSyncing(size_t n, CFStringRef *views) {
1628 __block bool retval = true;
1629 CFErrorRef error = NULL;
1631 if(n == 0 || views == NULL) return false;
1632 CFStringRef viewString = copyViewNames(n, views);
1634 SOSCCStatus cstatus = SOSCCThisDeviceIsInCircle(&error);
1635 if(cstatus != kSOSCCInCircle) {
1636 secnotice("viewCheck", "Checking view / circle status for %@: SOSCCStatus: (%@) Error: (%@)", viewString, SOSCCGetStatusDescription(cstatus), error);
1640 if(retval == true) {
1641 for(size_t i = 0; i < n; i++) {
1642 SOSViewResultCode vstatus = SOSCCView(views[i], kSOSCCViewQuery, &error);
1643 if(vstatus != kSOSCCViewMember) {
1644 secnotice("viewCheck", "Checking view / circle status for %@: SOSCCStatus: (%@) SOSViewResultCode(%@) Error: (%@)", views[i],
1645 SOSCCGetStatusDescription(cstatus), SOSCCGetViewResultDescription(vstatus), error);
1651 if(retval == true) {
1652 secnotice("viewCheck", "Checking view / circle status for %@: ENABLED", viewString);
1654 CFReleaseNull(error);
1655 CFReleaseNull(viewString);
1659 bool SOSCCIsIcloudKeychainSyncing(void) {
1660 CFStringRef views[] = { kSOSViewWiFi, kSOSViewAutofillPasswords, kSOSViewSafariCreditCards, kSOSViewOtherSyncable };
1661 return sosIsViewSetSyncing(sizeof(views)/sizeof(views[0]), views);
1664 bool SOSCCIsSafariSyncing(void) {
1665 CFStringRef views[] = { kSOSViewAutofillPasswords, kSOSViewSafariCreditCards };
1666 return sosIsViewSetSyncing(sizeof(views)/sizeof(views[0]), views);
1669 bool SOSCCIsAppleTVSyncing(void) {
1670 CFStringRef views[] = { kSOSViewAppleTV };
1671 return sosIsViewSetSyncing(sizeof(views)/sizeof(views[0]), views);
1674 bool SOSCCIsHomeKitSyncing(void) {
1675 CFStringRef views[] = { kSOSViewHomeKit };
1676 return sosIsViewSetSyncing(sizeof(views)/sizeof(views[0]), views);
1679 bool SOSCCIsWiFiSyncing(void) {
1680 CFStringRef views[] = { kSOSViewWiFi };
1681 return sosIsViewSetSyncing(sizeof(views)/sizeof(views[0]), views);
1684 bool SOSCCIsContinuityUnlockSyncing(void) {
1685 CFStringRef views[] = { kSOSViewContinuityUnlock };
1686 return sosIsViewSetSyncing(sizeof(views)/sizeof(views[0]), views);
1690 bool SOSCCSetEscrowRecord(CFStringRef escrow_label, uint64_t tries, CFErrorRef *error ){
1691 secnotice("escrow", "enter SOSCCSetEscrowRecord");
1692 sec_trace_enter_api(NULL);
1693 sec_trace_return_bool_api(^{
1694 do_if_registered(soscc_SetEscrowRecords, escrow_label, tries, error);
1696 return escrow_to_bool_error_request(kSecXPCOpSetEscrowRecord, escrow_label, tries, error);
1700 CFDictionaryRef SOSCCCopyEscrowRecord(CFErrorRef *error){
1701 secnotice("escrow", "enter SOSCCCopyEscrowRecord");
1702 sec_trace_enter_api(NULL);
1703 sec_trace_return_api(CFDictionaryRef, ^{
1704 do_if_registered(soscc_CopyEscrowRecords, error);
1706 return strings_to_dictionary_error_request(kSecXPCOpGetEscrowRecord, error);
1707 }, CFSTR("return=%@"))
1711 CFDictionaryRef SOSCCCopyBackupInformation(CFErrorRef *error) {
1712 secnotice("escrow", "enter SOSCCCopyBackupInformation");
1713 sec_trace_enter_api(NULL);
1714 sec_trace_return_api(CFDictionaryRef, ^{
1715 do_if_registered(soscc_CopyBackupInformation, error);
1716 return strings_to_dictionary_error_request(kSecXPCOpCopyBackupInformation, error);
1717 }, CFSTR("return=%@"))
1720 bool SOSCCCheckPeerAvailability(CFErrorRef *error){
1721 secnotice("peer", "enter SOSCCCheckPeerAvailability");
1722 sec_trace_enter_api(NULL);
1723 sec_trace_return_bool_api(^{
1724 do_if_registered(soscc_PeerAvailability, error);
1726 return simple_bool_error_request(kSecXPCOpCheckPeerAvailability, error);
1732 bool SOSWrapToBackupSliceKeyBagForView(CFStringRef viewName, CFDataRef input, CFDataRef* output, CFDataRef* bskbEncoded, CFErrorRef* error) {
1733 sec_trace_enter_api(NULL);
1734 sec_trace_return_bool_api(^{
1735 do_if_registered(sosbskb_WrapToBackupSliceKeyBagForView, viewName, input, output, bskbEncoded, error);
1737 return cfstring_and_cfdata_to_cfdata_cfdata_error_request(kSecXPCOpWrapToBackupSliceKeyBagForView, viewName, input, output, bskbEncoded, error);
1742 SOSPeerInfoRef SOSCCCopyApplication(CFErrorRef *error) {
1743 secnotice("hsa2PB", "enter SOSCCCopyApplication applicant");
1744 sec_trace_enter_api(NULL);
1746 sec_trace_return_api(SOSPeerInfoRef, ^{
1747 do_if_registered(soscc_CopyApplicant, error);
1748 return peer_info_error_request(kSecXPCOpCopyApplication, error);
1749 }, CFSTR("return=%@"));
1752 bool SOSCCCleanupKVSKeys(CFErrorRef *error) {
1753 secnotice("cleanup-keys", "enter SOSCCCleanupKVSKeys");
1754 sec_trace_enter_api(NULL);
1755 sec_trace_return_bool_api(^{
1756 do_if_registered(soscc_SOSCCCleanupKVSKeys, error);
1758 return simple_bool_error_request(kSecXPCOpKVSKeyCleanup, error);
1764 bool SOSCCTestPopulateKVSWithBadKeys(CFErrorRef *error) {
1765 secnotice("cleanup-keys", "enter SOSCCPopulateKVSWithBadKeys");
1766 sec_trace_enter_api(NULL);
1767 sec_trace_return_bool_api(^{
1768 do_if_registered(soscc_SOSCCTestPopulateKVSWithBadKeys, error);
1770 return simple_bool_error_request(kSecXPCOpPopulateKVS, error);
1776 CFDataRef SOSCCCopyCircleJoiningBlob(SOSPeerInfoRef applicant, CFErrorRef *error) {
1777 secnotice("hsa2PB", "enter SOSCCCopyCircleJoiningBlob approver");
1778 sec_trace_enter_api(NULL);
1780 sec_trace_return_api(CFDataRef, ^{
1781 CFDataRef result = NULL;
1782 do_if_registered(soscc_CopyCircleJoiningBlob, applicant, error);
1783 CFDataRef piData = SOSPeerInfoCopyEncodedData(applicant, kCFAllocatorDefault, error);
1784 result = cfdata_error_request_returns_cfdata(kSecXPCOpCopyCircleJoiningBlob, piData, error);
1785 CFReleaseNull(piData);
1787 }, CFSTR("return=%@"));
1790 CFDataRef SOSCCCopyInitialSyncData(CFErrorRef *error) {
1791 secnotice("circleJoin", "enter SOSCCCopyInitialSyncData approver");
1792 sec_trace_enter_api(NULL);
1794 sec_trace_return_api(CFDataRef, ^{
1795 do_if_registered(soscc_CopyInitialSyncData, error);
1796 return data_to_error_request(kSecXPCOpCopyInitialSyncBlob, error);
1797 }, CFSTR("return=%@"));
1800 bool SOSCCJoinWithCircleJoiningBlob(CFDataRef joiningBlob, PiggyBackProtocolVersion version, CFErrorRef *error) {
1801 secnotice("hsa2PB", "enter SOSCCJoinWithCircleJoiningBlob applicant");
1802 sec_trace_enter_api(NULL);
1803 sec_trace_return_bool_api(^{
1804 do_if_registered(soscc_JoinWithCircleJoiningBlob, joiningBlob, version, error);
1806 return cfdata_and_int_error_request_returns_bool(kSecXPCOpJoinWithCircleJoiningBlob, joiningBlob, version, error);
1812 bool SOSCCIsThisDeviceLastBackup(CFErrorRef *error) {
1813 secnotice("peer", "enter SOSCCIsThisDeviceLastBackup");
1814 sec_trace_enter_api(NULL);
1815 sec_trace_return_bool_api(^{
1816 do_if_registered(soscc_IsThisDeviceLastBackup, error);
1818 return simple_bool_error_request(kSecXPCOpIsThisDeviceLastBackup, error);
1822 CFBooleanRef SOSCCPeersHaveViewsEnabled(CFArrayRef viewNames, CFErrorRef *error) {
1823 secnotice("view-enabled", "enter SOSCCPeersHaveViewsEnabled");
1824 sec_trace_enter_api(NULL);
1825 sec_trace_return_api(CFBooleanRef, ^{
1826 do_if_registered(soscc_SOSCCPeersHaveViewsEnabled, viewNames, error);
1828 return cfarray_to_cfboolean_error_request(kSecXPCOpPeersHaveViewsEnabled, viewNames, error);
1829 }, CFSTR("return=%@"))
1832 bool SOSCCMessageFromPeerIsPending(SOSPeerInfoRef peer, CFErrorRef *error) {
1833 secnotice("pending-check", "enter SOSCCMessageFromPeerIsPending");
1835 sec_trace_return_bool_api(^{
1836 do_if_registered(soscc_SOSCCMessageFromPeerIsPending, peer, error);
1838 return peer_info_to_bool_error_request(kSecXPCOpMessageFromPeerIsPending, peer, error);
1843 bool SOSCCSendToPeerIsPending(SOSPeerInfoRef peer, CFErrorRef *error) {
1844 sec_trace_return_bool_api(^{
1845 do_if_registered(soscc_SOSCCSendToPeerIsPending, peer, error);
1847 return peer_info_to_bool_error_request(kSecXPCOpSendToPeerIsPending, peer, error);
1852 * SecSOSStatus interfaces
1855 @interface SecSOSStatus : NSObject {
1856 NSXPCConnection* _connection;
1858 @property NSXPCConnection *connection;
1861 @implementation SecSOSStatus
1862 @synthesize connection = _connection;
1864 - (instancetype) init
1866 if ((self = [super init]) == NULL)
1869 NSXPCInterface *interface = [NSXPCInterface interfaceWithProtocol:@protocol(SOSControlProtocol)];
1870 _SOSControlSetupInterface(interface);
1872 self.connection = [[NSXPCConnection alloc] initWithMachServiceName:@(kSecuritydSOSServiceName) options:0];
1873 if (self.connection == NULL)
1876 self.connection.remoteObjectInterface = interface;
1878 [self.connection resume];
1885 static id<SOSControlProtocol>
1886 SOSCCGetStatusObject(CFErrorRef *error)
1888 if (gSecurityd && gSecurityd->soscc_status)
1889 return (__bridge id<SOSControlProtocol>)gSecurityd->soscc_status();
1891 static SecSOSStatus *control;
1892 static dispatch_once_t onceToken;
1893 dispatch_once(&onceToken, ^{
1894 control = [[SecSOSStatus alloc] init];
1896 return control.connection.remoteObjectProxy;
1900 SOSCCAccountGetPublicKey(void (^reply)(BOOL trusted, NSData *data, NSError *error))
1902 CFErrorRef error = NULL;
1903 id<SOSControlProtocol> status = SOSCCGetStatusObject(&error);
1904 if (status == NULL) {
1905 reply(false, NULL, (__bridge NSError *)error);
1906 CFReleaseNull(error);
1910 [status userPublicKey:reply];
1914 SOSCCAccountGetAccountPrivateCredential(void (^complete)(NSData *data, NSError *error))
1916 CFErrorRef error = NULL;
1917 id<SOSControlProtocol> status = SOSCCGetStatusObject(&error);
1918 if (status == NULL) {
1919 complete(NULL, (__bridge NSError *)error);
1920 CFReleaseNull(error);
1924 [status validatedStashedAccountCredential:complete];
1928 SOSCCAccountGetKeyCircleGeneration(void (^reply)(NSData *data, NSError *error))
1930 SOSCCAccountGetPublicKey(^(BOOL __unused trusted, NSData *data, NSError *error){
1934 NSMutableData *digest = [NSMutableData dataWithLength:CCSHA256_OUTPUT_SIZE];
1935 ccdigest(ccsha256_di(), [data length], [data bytes], [digest mutableBytes]);
1936 reply(digest, error);