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 SOSCCStatus retval = SOSGetCachedCircleStatus(error);
90 if(retval != kSOSNoCachedValue) {
91 secnotice("circleOps", "Retrieved cached circle value %d", retval);
94 return SOSCCThisDeviceIsInCircleNonCached(error);
98 SOSCCStatus SOSCCThisDeviceIsInCircleNonCached(CFErrorRef *error)
100 sec_trace_enter_api(NULL);
101 sec_trace_return_api(SOSCCStatus, ^{
102 SOSCCStatus result = kSOSCCError;
104 do_if_registered(soscc_ThisDeviceIsInCircle, error);
106 xpc_object_t message = securityd_create_message(kSecXPCOpDeviceInCircle, error);
108 xpc_object_t response = securityd_message_with_reply_sync(message, error);
110 if (response && xpc_dictionary_entry_is_type(response, kSecXPCKeyResult, XPC_TYPE_INT64)) {
111 result = (SOSCCStatus) xpc_dictionary_get_int64(response, kSecXPCKeyResult);
113 result = kSOSCCError;
117 if (response && securityd_message_no_error(response, error))
119 char *desc = xpc_copy_description(response);
120 SecCFCreateErrorWithFormat(0, sSecXPCErrorDomain, NULL, error, NULL, CFSTR("Remote error occurred/no info: %s"), desc);
125 secnotice("circleOps", "Retrieved non-cached circle value %d", result);
128 }, CFSTR("SOSCCStatus=%d"))
131 static bool sfsigninanalytics_bool_error_request(enum SecXPCOperation op, CFDataRef parentEvent, CFErrorRef* error)
133 __block bool result = false;
135 secdebug("sosops","enter - operation: %d", op);
136 securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
137 return SecXPCDictionarySetData(message, kSecXPCKeySignInAnalytics, parentEvent, error);
138 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
139 result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
145 static bool cfstring_to_error_request(enum SecXPCOperation op, CFStringRef string, CFErrorRef* error)
147 __block bool result = false;
149 secdebug("sosops","enter - operation: %d", op);
150 securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
151 xpc_object_t xString = _CFXPCCreateXPCObjectFromCFObject(string);
152 bool success = false;
154 xpc_dictionary_set_value(message, kSecXPCKeyString, xString);
159 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
160 result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
166 static SOSRingStatus cfstring_to_uint64_request(enum SecXPCOperation op, CFStringRef string, CFErrorRef* error)
168 __block bool result = false;
170 secdebug("sosops","enter - operation: %d", op);
171 securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
172 xpc_object_t xString = _CFXPCCreateXPCObjectFromCFObject(string);
173 bool success = false;
175 xpc_dictionary_set_value(message, kSecXPCKeyString, xString);
180 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
181 result = xpc_dictionary_get_int64(response, kSecXPCKeyResult);
187 static CFStringRef simple_cfstring_error_request(enum SecXPCOperation op, CFErrorRef* error)
189 __block CFStringRef result = NULL;
191 secdebug("sosops","enter - operation: %d", op);
192 securityd_send_sync_and_do(op, error, NULL, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
193 const char *c_string = xpc_dictionary_get_string(response, kSecXPCKeyResult);
196 result = CFStringCreateWithBytes(kCFAllocatorDefault, (const UInt8*)c_string, strlen(c_string), kCFStringEncodingUTF8, false);
199 return c_string != NULL;
204 static bool simple_bool_error_request(enum SecXPCOperation op, CFErrorRef* error)
206 __block bool result = false;
208 secdebug("sosops","enter - operation: %d", op);
209 securityd_send_sync_and_do(op, error, NULL, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
210 result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
216 static bool SecXPCDictionarySetPeerInfoData(xpc_object_t message, const char *key, SOSPeerInfoRef peerInfo, CFErrorRef *error) {
217 bool success = false;
218 CFDataRef peerData = SOSPeerInfoCopyEncodedData(peerInfo, kCFAllocatorDefault, error);
220 success = SecXPCDictionarySetData(message, key, peerData, error);
222 CFReleaseNull(peerData);
226 static bool peer_info_to_bool_error_request(enum SecXPCOperation op, SOSPeerInfoRef peerInfo, CFErrorRef* error)
228 __block bool result = false;
230 secdebug("sosops","enter - operation: %d", op);
231 securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
232 return SecXPCDictionarySetPeerInfoData(message, kSecXPCKeyPeerInfo, peerInfo, error);
233 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
234 result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
240 static CFBooleanRef cfarray_to_cfboolean_error_request(enum SecXPCOperation op, CFArrayRef views, CFErrorRef* error)
242 __block bool result = false;
244 secdebug("sosops","enter - operation: %d", op);
245 bool noError = securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
246 return SecXPCDictionarySetPList(message, kSecXPCKeyArray, views, error);
247 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
248 result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
251 return noError ? (result ? kCFBooleanTrue : kCFBooleanFalse) : NULL;
255 static CFSetRef cfset_cfset_to_cfset_error_request(enum SecXPCOperation op, CFSetRef set1, CFSetRef set2, CFErrorRef* error)
257 __block CFSetRef result = NULL;
259 secdebug("sosops","enter - operation: %d", op);
260 bool noError = securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
261 return SecXPCDictionarySetPList(message, kSecXPCKeySet, set1, error) && SecXPCDictionarySetPList(message, kSecXPCKeySet2, set2, error);
262 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
263 result = SecXPCDictionaryCopySet(response, kSecXPCKeyResult, error);
268 CFReleaseNull(result);
274 static bool escrow_to_bool_error_request(enum SecXPCOperation op, CFStringRef escrow_label, uint64_t tries, CFErrorRef* error)
276 __block bool result = false;
278 securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
280 bool success = false;
281 xpc_object_t xEscrowLabel = _CFXPCCreateXPCObjectFromCFObject(escrow_label);
283 xpc_dictionary_set_value(message, kSecXPCKeyEscrowLabel, xEscrowLabel);
288 xpc_dictionary_set_int64(message, kSecXPCKeyTriesLabel, tries);
293 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
294 result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
300 static CF_RETURNS_RETAINED CFArrayRef simple_array_error_request(enum SecXPCOperation op, CFErrorRef* error)
302 __block CFArrayRef result = NULL;
304 secdebug("sosops","enter - operation: %d", op);
305 if (securityd_send_sync_and_do(op, error, NULL, ^bool(xpc_object_t response, CFErrorRef *error) {
306 xpc_object_t temp_result = xpc_dictionary_get_value(response, kSecXPCKeyResult);
307 result = _CFXPCCreateCFObjectFromXPCObject(temp_result);
308 return result != NULL;
310 if (!isArray(result)) {
311 SOSErrorCreate(kSOSErrorUnexpectedType, error, NULL, CFSTR("Expected array, got: %@"), result);
312 CFReleaseNull(result);
318 static CF_RETURNS_RETAINED CFArrayRef der_array_error_request(enum SecXPCOperation op, CFErrorRef* error)
320 __block CFArrayRef result = NULL;
322 secdebug("sosops","enter - operation: %d", op);
323 if (securityd_send_sync_and_do(op, error, NULL, ^bool(xpc_object_t response, CFErrorRef *error) {
325 const uint8_t* bytes = xpc_dictionary_get_data(response, kSecXPCKeyResult, &length);
326 der_decode_plist(kCFAllocatorDefault, 0, (CFPropertyListRef*) &result, error, bytes, bytes + length);
328 return result != NULL;
330 if (!isArray(result)) {
331 SOSErrorCreate(kSOSErrorUnexpectedType, error, NULL, CFSTR("Expected array, got: %@"), result);
332 CFReleaseNull(result);
338 static CFDictionaryRef strings_to_dictionary_error_request(enum SecXPCOperation op, CFErrorRef* error)
340 __block CFDictionaryRef result = NULL;
342 secdebug("sosops","enter - operation: %d", op);
344 if (securityd_send_sync_and_do(op, error, NULL, ^bool(xpc_object_t response, CFErrorRef *error) {
345 xpc_object_t temp_result = xpc_dictionary_get_value(response, kSecXPCKeyResult);
347 result = _CFXPCCreateCFObjectFromXPCObject(temp_result);
348 return result != NULL;
351 if (!isDictionary(result)) {
352 SOSErrorCreate(kSOSErrorUnexpectedType, error, NULL, CFSTR("Expected dictionary, got: %@"), result);
353 CFReleaseNull(result);
360 static int simple_int_error_request(enum SecXPCOperation op, CFErrorRef* error)
362 __block int result = 0;
364 secdebug("sosops","enter - operation: %d", op);
365 securityd_send_sync_and_do(op, error, NULL, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
366 int64_t temp_result = xpc_dictionary_get_int64(response, kSecXPCKeyResult);
367 if ((temp_result >= INT32_MIN) && (temp_result <= INT32_MAX)) {
368 result = (int)temp_result;
375 static CF_RETURNS_RETAINED SOSPeerInfoRef peer_info_error_request(enum SecXPCOperation op, CFErrorRef* error)
377 SOSPeerInfoRef result = NULL;
378 __block CFDataRef data = NULL;
380 secdebug("sosops","enter - operation: %d", op);
381 securityd_send_sync_and_do(op, error, NULL, ^bool(xpc_object_t response, CFErrorRef *error) {
382 xpc_object_t temp_result = xpc_dictionary_get_value(response, kSecXPCKeyResult);
383 if (response && (NULL != temp_result)) {
384 data = _CFXPCCreateCFObjectFromXPCObject(temp_result);
390 result = SOSPeerInfoCreateFromData(kCFAllocatorDefault, error, data);
392 SOSErrorCreate(kSOSErrorUnexpectedType, error, NULL, CFSTR("Expected CFData, got: %@"), data);
399 static CFDataRef data_to_error_request(enum SecXPCOperation op, CFErrorRef *error)
401 __block CFDataRef result = NULL;
403 secdebug("sosops", "enter -- operation: %d", op);
404 securityd_send_sync_and_do(op, error, NULL, ^bool(xpc_object_t response, CFErrorRef *error) {
405 xpc_object_t temp_result = xpc_dictionary_get_value(response, kSecXPCKeyResult);
406 if (response && (NULL != temp_result)) {
407 result = _CFXPCCreateCFObjectFromXPCObject(temp_result);
409 return result != NULL;
412 if (!isData(result)) {
413 SOSErrorCreate(kSOSErrorUnexpectedType, error, NULL, CFSTR("Expected CFData, got: %@"), result);
420 static CFArrayRef array_of_info_error_request(enum SecXPCOperation op, CFErrorRef* error)
422 __block CFArrayRef result = NULL;
424 secdebug("sosops","enter - operation: %d", op);
425 securityd_send_sync_and_do(op, error, NULL, ^bool(xpc_object_t response, CFErrorRef *error) {
426 xpc_object_t encoded_array = xpc_dictionary_get_value(response, kSecXPCKeyResult);
427 if (response && (NULL != encoded_array)) {
428 result = CreateArrayOfPeerInfoWithXPCObject(encoded_array, error);
430 return result != NULL;
433 if (!isArray(result)) {
434 SOSErrorCreate(kSOSErrorUnexpectedType, error, NULL, CFSTR("Expected array, got: %@"), result);
435 CFReleaseNull(result);
440 static CF_RETURNS_RETAINED SOSPeerInfoRef data_to_peer_info_error_request(enum SecXPCOperation op, CFDataRef secret, CFErrorRef* error)
442 __block SOSPeerInfoRef result = false;
443 __block CFDataRef data = NULL;
445 secdebug("sosops", "enter - operation: %d", op);
446 securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
447 xpc_object_t xsecretData = _CFXPCCreateXPCObjectFromCFObject(secret);
448 bool success = false;
450 xpc_dictionary_set_value(message, kSecXPCKeyNewPublicBackupKey, xsecretData);
455 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
456 xpc_object_t temp_result = xpc_dictionary_get_value(response, kSecXPCKeyResult);
457 if (response && (NULL != temp_result)) {
458 data = _CFXPCCreateCFObjectFromXPCObject(temp_result);
464 result = SOSPeerInfoCreateFromData(kCFAllocatorDefault, error, data);
466 SOSErrorCreate(kSOSErrorUnexpectedType, error, NULL, CFSTR("Expected CFData, got: %@"), data);
473 static bool keybag_and_bool_to_bool_error_request(enum SecXPCOperation op, CFDataRef data, bool include, CFErrorRef* error)
475 secdebug("sosops", "enter - operation: %d", op);
476 return securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
477 xpc_object_t xData = _CFXPCCreateXPCObjectFromCFObject(data);
478 bool success = false;
480 xpc_dictionary_set_value(message, kSecXPCKeyKeybag, xData);
484 xpc_dictionary_set_bool(message, kSecXPCKeyIncludeV0, include);
486 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
487 return xpc_dictionary_get_bool(response, kSecXPCKeyResult);
491 static bool recovery_and_bool_to_bool_error_request(enum SecXPCOperation op, CFDataRef data, CFErrorRef* error)
493 secdebug("sosops", "enter - operation: %d", op);
494 return securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
495 xpc_object_t xData = NULL;
497 xData = _CFXPCCreateXPCObjectFromCFObject(data);
500 CFDataRef nullData = CFDataCreate(kCFAllocatorDefault, &zero, 1);
501 xData = _CFXPCCreateXPCObjectFromCFObject(nullData);
502 CFReleaseNull(nullData);
504 bool success = false;
506 xpc_dictionary_set_value(message, kSecXPCKeyRecoveryPublicKey, xData);
511 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
512 return xpc_dictionary_get_bool(response, kSecXPCKeyResult);
516 static bool info_array_to_bool_error_request(enum SecXPCOperation op, CFArrayRef peer_infos, CFErrorRef* error)
518 __block bool result = false;
520 secdebug("sosops", "enter - operation: %d", op);
521 securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
522 xpc_object_t encoded_peers = CreateXPCObjectWithArrayOfPeerInfo(peer_infos, error);
524 xpc_dictionary_set_value(message, kSecXPCKeyPeerInfoArray, encoded_peers);
525 return encoded_peers != NULL;
526 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
527 result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
533 static bool info_array_data_to_bool_error_request(enum SecXPCOperation op, CFArrayRef peer_infos, CFDataRef parentEvent, CFErrorRef* error)
535 __block bool result = false;
537 secdebug("sosops", "enter - operation: %d", op);
538 securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
539 SecXPCDictionarySetData(message, kSecXPCKeySignInAnalytics, parentEvent, error);
540 xpc_object_t encoded_peers = CreateXPCObjectWithArrayOfPeerInfo(peer_infos, error);
542 xpc_dictionary_set_value(message, kSecXPCKeyPeerInfoArray, encoded_peers);
543 return encoded_peers != NULL;
544 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
545 result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
551 static bool uint64_t_to_bool_error_request(enum SecXPCOperation op,
555 __block bool result = false;
557 securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
558 xpc_dictionary_set_uint64(message, kSecXPCLimitInMinutes, number);
560 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
561 result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
568 static bool cfstring_and_cfdata_to_cfdata_cfdata_error_request(enum SecXPCOperation op, CFStringRef viewName, CFDataRef input, CFDataRef* data, CFDataRef* data2, CFErrorRef* error) {
569 secdebug("sosops", "enter - operation: %d", op);
570 __block bool result = false;
571 securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
572 xpc_object_t xviewname = _CFXPCCreateXPCObjectFromCFObject(viewName);
573 xpc_object_t xinput = _CFXPCCreateXPCObjectFromCFObject(input);
574 bool success = false;
575 if (xviewname && xinput){
576 xpc_dictionary_set_value(message, kSecXPCKeyViewName, xviewname);
577 xpc_dictionary_set_value(message, kSecXPCData, xinput);
583 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
584 result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
586 xpc_object_t temp_result = xpc_dictionary_get_value(response, kSecXPCData);
587 if ((NULL != temp_result) && data) {
588 *data = _CFXPCCreateCFObjectFromXPCObject(temp_result);
590 temp_result = xpc_dictionary_get_value(response, kSecXPCKeyKeybag);
591 if ((NULL != temp_result) && data2) {
592 *data2 = _CFXPCCreateCFObjectFromXPCObject(temp_result);
598 if (data &&!isData(*data)) {
599 SOSErrorCreate(kSOSErrorUnexpectedType, error, NULL, CFSTR("Expected CFData, got: %@"), *data);
601 if (data2 &&!isData(*data2)) {
602 SOSErrorCreate(kSOSErrorUnexpectedType, error, NULL, CFSTR("Expected CFData, got: %@"), *data2);
608 static bool cfdata_and_int_error_request_returns_bool(enum SecXPCOperation op, CFDataRef thedata,
609 PiggyBackProtocolVersion version, CFErrorRef *error) {
610 __block bool result = false;
612 sec_trace_enter_api(NULL);
613 securityd_send_sync_and_do(op, error, ^(xpc_object_t message, CFErrorRef *error) {
614 xpc_object_t xdata = _CFXPCCreateXPCObjectFromCFObject(thedata);
615 bool success = false;
617 xpc_dictionary_set_value(message, kSecXPCData, xdata);
618 xpc_dictionary_set_uint64(message, kSecXPCVersion, version);
624 }, ^(xpc_object_t response, __unused CFErrorRef *error) {
625 result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
632 static CFDataRef cfdata_error_request_returns_cfdata(enum SecXPCOperation op, CFDataRef thedata, CFErrorRef *error) {
633 __block CFDataRef result = NULL;
635 sec_trace_enter_api(NULL);
636 securityd_send_sync_and_do(op, error, ^(xpc_object_t message, CFErrorRef *error) {
637 xpc_object_t xdata = _CFXPCCreateXPCObjectFromCFObject(thedata);
638 bool success = false;
640 xpc_dictionary_set_value(message, kSecXPCData, xdata);
645 }, ^(xpc_object_t response, __unused CFErrorRef *error) {
646 xpc_object_t temp_result = xpc_dictionary_get_value(response, kSecXPCKeyResult);
647 if (response && (NULL != temp_result)) {
648 CFTypeRef object = _CFXPCCreateCFObjectFromXPCObject(temp_result);
649 result = copyIfData(object, error);
650 CFReleaseNull(object);
652 return (bool) (result != NULL);
658 bool SOSCCRequestToJoinCircle(CFErrorRef* error)
660 sec_trace_enter_api(NULL);
661 sec_trace_return_bool_api(^{
662 do_if_registered(soscc_RequestToJoinCircle, error);
664 return simple_bool_error_request(kSecXPCOpRequestToJoin, error);
668 bool SOSCCRequestToJoinCircleWithAnalytics(CFDataRef parentEvent, CFErrorRef* error)
670 sec_trace_enter_api(NULL);
671 sec_trace_return_bool_api(^{
672 do_if_registered(soscc_RequestToJoinCircleWithAnalytics, parentEvent, error);
674 return sfsigninanalytics_bool_error_request(kSecXPCOpRequestToJoinWithAnalytics, parentEvent, error);
678 bool SOSCCRequestToJoinCircleAfterRestore(CFErrorRef* error)
680 sec_trace_enter_api(NULL);
681 sec_trace_return_bool_api(^{
682 do_if_registered(soscc_RequestToJoinCircleAfterRestore, error);
684 return simple_bool_error_request(kSecXPCOpRequestToJoinAfterRestore, error);
688 bool SOSCCRequestToJoinCircleAfterRestoreWithAnalytics(CFDataRef parentEvent, CFErrorRef* error)
690 sec_trace_enter_api(NULL);
691 sec_trace_return_bool_api(^{
692 do_if_registered(soscc_RequestToJoinCircleAfterRestoreWithAnalytics, parentEvent, error);
694 return sfsigninanalytics_bool_error_request(kSecXPCOpRequestToJoinAfterRestoreWithAnalytics, parentEvent, error);
698 bool SOSCCAccountHasPublicKey(CFErrorRef *error)
701 sec_trace_enter_api(NULL);
702 sec_trace_return_bool_api(^{
703 do_if_registered(soscc_AccountHasPublicKey, error);
705 return simple_bool_error_request(kSecXPCOpAccountHasPublicKey, error);
710 bool SOSCCAccountIsNew(CFErrorRef *error)
712 sec_trace_enter_api(NULL);
713 sec_trace_return_bool_api(^{
714 do_if_registered(soscc_AccountIsNew, error);
716 return simple_bool_error_request(kSecXPCOpAccountIsNew, error);
720 bool SOSCCWaitForInitialSyncWithAnalytics(CFDataRef parentEvent, CFErrorRef* error)
722 sec_trace_enter_api(NULL);
723 sec_trace_return_bool_api(^{
724 do_if_registered(soscc_WaitForInitialSyncWithAnalytics, parentEvent, error);
726 return sfsigninanalytics_bool_error_request(kSecXPCOpWaitForInitialSyncWithAnalytics, parentEvent, error);
730 bool SOSCCWaitForInitialSync(CFErrorRef* error)
732 sec_trace_enter_api(NULL);
733 sec_trace_return_bool_api(^{
734 do_if_registered(soscc_WaitForInitialSync, error);
736 return simple_bool_error_request(kSecXPCOpWaitForInitialSync, error);
740 CFArrayRef SOSCCCopyYetToSyncViewsList(CFErrorRef* error)
742 sec_trace_enter_api(NULL);
743 sec_trace_return_api(CFArrayRef, ^{
744 do_if_registered(soscc_CopyYetToSyncViewsList, error);
746 return simple_array_error_request(kSecXPCOpCopyYetToSyncViews, error);
750 bool SOSCCRequestEnsureFreshParameters(CFErrorRef* error)
752 sec_trace_enter_api(NULL);
753 sec_trace_return_bool_api(^{
754 do_if_registered(soscc_RequestEnsureFreshParameters, error);
756 return simple_bool_error_request(kSecXPCOpRequestEnsureFreshParameters, error);
760 CFStringRef SOSCCGetAllTheRings(CFErrorRef *error){
761 sec_trace_enter_api(NULL);
762 sec_trace_return_api(CFStringRef, ^{
763 do_if_registered(soscc_GetAllTheRings, error);
766 return simple_cfstring_error_request(kSecXPCOpGetAllTheRings, error);
769 bool SOSCCApplyToARing(CFStringRef ringName, CFErrorRef* error)
771 sec_trace_enter_api(NULL);
772 sec_trace_return_bool_api(^{
773 do_if_registered(soscc_ApplyToARing, ringName, error);
775 return cfstring_to_error_request(kSecXPCOpApplyToARing, ringName, error);
779 bool SOSCCWithdrawlFromARing(CFStringRef ringName, CFErrorRef* error)
781 sec_trace_enter_api(NULL);
782 sec_trace_return_bool_api(^{
783 do_if_registered(soscc_WithdrawlFromARing, ringName, error);
785 return cfstring_to_error_request(kSecXPCOpWithdrawlFromARing, ringName, error);
789 SOSRingStatus SOSCCRingStatus(CFStringRef ringName, CFErrorRef* error)
791 sec_trace_enter_api(NULL);
792 sec_trace_return_api(SOSRingStatus, ^{
793 do_if_registered(soscc_RingStatus, ringName, error);
795 return cfstring_to_uint64_request(kSecXPCOpRingStatus, ringName, error);
796 }, CFSTR("SOSCCStatus=%d"))
799 bool SOSCCEnableRing(CFStringRef ringName, CFErrorRef* error)
801 sec_trace_enter_api(NULL);
802 sec_trace_return_bool_api(^{
803 do_if_registered(soscc_EnableRing, ringName, error);
805 return cfstring_to_error_request(kSecXPCOpEnableRing, ringName, error);
809 bool SOSCCAccountSetToNew(CFErrorRef *error)
811 secwarning("SOSCCAccountSetToNew called");
812 sec_trace_enter_api(NULL);
813 sec_trace_return_bool_api(^{
814 do_if_registered(soscc_SetToNew, error);
815 return simple_bool_error_request(kSecXPCOpAccountSetToNew, error);
819 bool SOSCCResetToOffering(CFErrorRef* error)
821 secwarning("SOSCCResetToOffering called");
822 sec_trace_enter_api(NULL);
823 sec_trace_return_bool_api(^{
824 do_if_registered(soscc_ResetToOffering, error);
826 return simple_bool_error_request(kSecXPCOpResetToOffering, error);
830 bool SOSCCResetToEmpty(CFErrorRef* error)
832 secwarning("SOSCCResetToEmpty called");
833 sec_trace_enter_api(NULL);
834 sec_trace_return_bool_api(^{
835 do_if_registered(soscc_ResetToEmpty, error);
837 return simple_bool_error_request(kSecXPCOpResetToEmpty, error);
841 bool SOSCCResetToEmptyWithAnalytics(CFDataRef parentEvent, CFErrorRef* error)
843 secwarning("SOSCCResetToEmptyWithAnalytics called");
844 sec_trace_enter_api(NULL);
845 sec_trace_return_bool_api(^{
846 do_if_registered(soscc_ResetToEmptyWithAnalytics, parentEvent, error);
848 return sfsigninanalytics_bool_error_request(kSecXPCOpResetToEmptyWithAnalytics, parentEvent, error);
851 bool SOSCCRemovePeersFromCircle(CFArrayRef peers, CFErrorRef* error)
853 sec_trace_enter_api(NULL);
854 sec_trace_return_bool_api(^{
855 do_if_registered(soscc_RemovePeersFromCircle, peers, error);
857 return info_array_to_bool_error_request(kSecXPCOpRemovePeersFromCircle, peers, error);
861 bool SOSCCRemovePeersFromCircleWithAnalytics(CFArrayRef peers, CFDataRef parentEvent, CFErrorRef* error)
863 sec_trace_enter_api(NULL);
864 sec_trace_return_bool_api(^{
865 do_if_registered(soscc_RemovePeersFromCircleWithAnalytics, peers, parentEvent, error);
867 return info_array_data_to_bool_error_request(kSecXPCOpRemovePeersFromCircleWithAnalytics, peers, parentEvent, error);
871 bool SOSCCRemoveThisDeviceFromCircleWithAnalytics(CFDataRef parentEvent, CFErrorRef* error)
873 sec_trace_enter_api(NULL);
874 sec_trace_return_bool_api(^{
875 do_if_registered(soscc_RemoveThisDeviceFromCircleWithAnalytics, parentEvent, error);
877 return sfsigninanalytics_bool_error_request(kSecXPCOpRemoveThisDeviceFromCircleWithAnalytics, parentEvent, error);
881 bool SOSCCRemoveThisDeviceFromCircle(CFErrorRef* error)
883 sec_trace_enter_api(NULL);
884 sec_trace_return_bool_api(^{
885 do_if_registered(soscc_RemoveThisDeviceFromCircle, error);
887 return simple_bool_error_request(kSecXPCOpRemoveThisDeviceFromCircle, error);
891 bool SOSCCLoggedOutOfAccount(CFErrorRef* error)
893 sec_trace_enter_api(NULL);
894 sec_trace_return_bool_api(^{
895 do_if_registered(soscc_LoggedOutOfAccount, error);
897 return simple_bool_error_request(kSecXPCOpLoggedOutOfAccount, error);
901 bool SOSCCBailFromCircle_BestEffort(uint64_t limit_in_seconds, CFErrorRef* error)
903 sec_trace_enter_api(NULL);
904 sec_trace_return_bool_api(^{
905 do_if_registered(soscc_BailFromCircle, limit_in_seconds, error);
907 return uint64_t_to_bool_error_request(kSecXPCOpBailFromCircle, limit_in_seconds, error);
911 bool SOSCCSignedOut(bool immediate, CFErrorRef* error)
913 uint64_t limit = strtoul(optarg, NULL, 10);
916 return SOSCCRemoveThisDeviceFromCircle(error);
918 return SOSCCBailFromCircle_BestEffort(limit, error);
922 CFArrayRef SOSCCCopyPeerPeerInfo(CFErrorRef* error)
924 sec_trace_enter_api(NULL);
925 sec_trace_return_api(CFArrayRef, ^{
926 do_if_registered(soscc_CopyPeerInfo, error);
928 return array_of_info_error_request(kSecXPCOpCopyPeerPeerInfo, error);
929 }, CFSTR("return=%@"));
932 CFArrayRef SOSCCCopyConcurringPeerPeerInfo(CFErrorRef* error)
934 sec_trace_enter_api(NULL);
935 sec_trace_return_api(CFArrayRef, ^{
936 do_if_registered(soscc_CopyConcurringPeerInfo, error);
938 return array_of_info_error_request(kSecXPCOpCopyConcurringPeerPeerInfo, error);
939 }, CFSTR("return=%@"));
942 CFArrayRef SOSCCCopyGenerationPeerInfo(CFErrorRef* error)
944 sec_trace_enter_api(NULL);
945 sec_trace_return_api(CFArrayRef, ^{
946 do_if_registered(soscc_CopyGenerationPeerInfo, error);
948 return simple_array_error_request(kSecXPCOpCopyGenerationPeerInfo, error);
949 }, CFSTR("return=%@"));
952 CFArrayRef SOSCCCopyApplicantPeerInfo(CFErrorRef* error)
954 sec_trace_enter_api(NULL);
955 sec_trace_return_api(CFArrayRef, ^{
956 do_if_registered(soscc_CopyApplicantPeerInfo, error);
958 return array_of_info_error_request(kSecXPCOpCopyApplicantPeerInfo, error);
959 }, CFSTR("return=%@"));
962 bool SOSCCValidateUserPublic(CFErrorRef* error){
963 sec_trace_enter_api(NULL);
964 sec_trace_return_api(bool, ^{
965 do_if_registered(soscc_ValidateUserPublic, error);
967 return simple_bool_error_request(kSecXPCOpValidateUserPublic, error);
971 CFArrayRef SOSCCCopyValidPeerPeerInfo(CFErrorRef* error)
973 sec_trace_enter_api(NULL);
974 sec_trace_return_api(CFArrayRef, ^{
975 do_if_registered(soscc_CopyValidPeerPeerInfo, error);
977 return array_of_info_error_request(kSecXPCOpCopyValidPeerPeerInfo, error);
978 }, CFSTR("return=%@"));
981 CFArrayRef SOSCCCopyNotValidPeerPeerInfo(CFErrorRef* error)
983 sec_trace_enter_api(NULL);
984 sec_trace_return_api(CFArrayRef, ^{
985 do_if_registered(soscc_CopyNotValidPeerPeerInfo, error);
987 return array_of_info_error_request(kSecXPCOpCopyNotValidPeerPeerInfo, error);
988 }, CFSTR("return=%@"));
991 CFArrayRef SOSCCCopyRetirementPeerInfo(CFErrorRef* error)
993 sec_trace_enter_api(NULL);
994 sec_trace_return_api(CFArrayRef, ^{
995 do_if_registered(soscc_CopyRetirementPeerInfo, error);
997 return array_of_info_error_request(kSecXPCOpCopyRetirementPeerInfo, error);
998 }, CFSTR("return=%@"));
1001 CFArrayRef SOSCCCopyViewUnawarePeerInfo(CFErrorRef* error)
1003 sec_trace_enter_api(NULL);
1004 sec_trace_return_api(CFArrayRef, ^{
1005 do_if_registered(soscc_CopyViewUnawarePeerInfo, error);
1007 return array_of_info_error_request(kSecXPCOpCopyViewUnawarePeerInfo, error);
1008 }, CFSTR("return=%@"));
1011 CFDataRef SOSCCCopyAccountState(CFErrorRef* error)
1013 sec_trace_enter_api(NULL);
1014 sec_trace_return_api(CFDataRef, ^{
1015 do_if_registered(soscc_CopyAccountState, error);
1017 return data_to_error_request(kSecXPCOpCopyAccountData, error);
1018 }, CFSTR("return=%@"));
1021 bool SOSCCDeleteAccountState(CFErrorRef *error)
1023 sec_trace_enter_api(NULL);
1024 sec_trace_return_api(bool, ^{
1025 do_if_registered(soscc_DeleteAccountState, error);
1026 return simple_bool_error_request(kSecXPCOpDeleteAccountData, error);
1029 CFDataRef SOSCCCopyEngineData(CFErrorRef* error)
1031 sec_trace_enter_api(NULL);
1032 sec_trace_return_api(CFDataRef, ^{
1033 do_if_registered(soscc_CopyEngineData, error);
1035 return data_to_error_request(kSecXPCOpCopyEngineData, error);
1036 }, CFSTR("return=%@"));
1039 bool SOSCCDeleteEngineState(CFErrorRef *error)
1041 sec_trace_enter_api(NULL);
1042 sec_trace_return_api(bool, ^{
1043 do_if_registered(soscc_DeleteEngineState, error);
1044 return simple_bool_error_request(kSecXPCOpDeleteEngineData, error);
1048 SOSPeerInfoRef SOSCCCopyMyPeerInfo(CFErrorRef *error)
1050 sec_trace_enter_api(NULL);
1051 sec_trace_return_api(SOSPeerInfoRef, ^{
1052 do_if_registered(soscc_CopyMyPeerInfo, error);
1054 return peer_info_error_request(kSecXPCOpCopyMyPeerInfo, error);
1055 }, CFSTR("return=%@"));
1058 static CFArrayRef SOSCCCopyEngineState(CFErrorRef* error)
1060 sec_trace_enter_api(NULL);
1061 sec_trace_return_api(CFArrayRef, ^{
1062 do_if_registered(soscc_CopyEngineState, error);
1064 return der_array_error_request(kSecXPCOpCopyEngineState, error);
1065 }, CFSTR("return=%@"));
1068 CFStringRef kSOSCCEngineStatePeerIDKey = CFSTR("PeerID");
1069 CFStringRef kSOSCCEngineStateManifestCountKey = CFSTR("ManifestCount");
1070 CFStringRef kSOSCCEngineStateSyncSetKey = CFSTR("SyncSet");
1071 CFStringRef kSOSCCEngineStateCoderKey = CFSTR("CoderDump");
1072 CFStringRef kSOSCCEngineStateManifestHashKey = CFSTR("ManifestHash");
1074 void SOSCCForEachEngineStateAsStringFromArray(CFArrayRef states, void (^block)(CFStringRef oneStateString)) {
1076 CFArrayForEach(states, ^(const void *value) {
1077 CFDictionaryRef dict = asDictionary(value, NULL);
1079 CFMutableStringRef description = CFStringCreateMutable(kCFAllocatorDefault, 0);
1081 CFStringRef id = asString(CFDictionaryGetValue(dict, kSOSCCEngineStatePeerIDKey), NULL);
1084 CFStringAppendFormat(description, NULL, CFSTR("remote %@ "), id);
1086 CFStringAppendFormat(description, NULL, CFSTR("local "));
1089 CFSetRef viewSet = asSet(CFDictionaryGetValue(dict, kSOSCCEngineStateSyncSetKey), NULL);
1091 CFStringSetPerformWithDescription(viewSet, ^(CFStringRef setDescription) {
1092 CFStringAppend(description, setDescription);
1095 CFStringAppendFormat(description, NULL, CFSTR("<Missing view set!>"));
1098 CFStringAppendFormat(description, NULL, CFSTR(" [%@]"),
1099 CFDictionaryGetValue(dict, kSOSCCEngineStateManifestCountKey));
1101 CFDataRef mainfestHash = asData(CFDictionaryGetValue(dict, kSOSCCEngineStateManifestHashKey), NULL);
1104 CFDataPerformWithHexString(mainfestHash, ^(CFStringRef dataString) {
1105 CFStringAppendFormat(description, NULL, CFSTR(" %@"), dataString);
1109 CFStringRef coderDescription = asString(CFDictionaryGetValue(dict, kSOSCCEngineStateCoderKey), NULL);
1110 if (coderDescription) {
1111 CFStringAppendFormat(description, NULL, CFSTR(" %@"), coderDescription);
1116 CFReleaseNull(description);
1121 bool SOSCCForEachEngineStateAsString(CFErrorRef* error, void (^block)(CFStringRef oneStateString)) {
1122 CFArrayRef states = SOSCCCopyEngineState(error);
1126 SOSCCForEachEngineStateAsStringFromArray(states, block);
1132 bool SOSCCAcceptApplicants(CFArrayRef applicants, CFErrorRef* error)
1134 sec_trace_enter_api(NULL);
1135 sec_trace_return_bool_api(^{
1136 do_if_registered(soscc_AcceptApplicants, applicants, error);
1138 return info_array_to_bool_error_request(kSecXPCOpAcceptApplicants, applicants, error);
1142 bool SOSCCRejectApplicants(CFArrayRef applicants, CFErrorRef *error)
1144 sec_trace_enter_api(CFSTR("applicants=%@"), applicants);
1145 sec_trace_return_bool_api(^{
1146 do_if_registered(soscc_RejectApplicants, applicants, error);
1148 return info_array_to_bool_error_request(kSecXPCOpRejectApplicants, applicants, error);
1152 static CF_RETURNS_RETAINED SOSPeerInfoRef SOSSetNewPublicBackupKey(CFDataRef pubKey, CFErrorRef *error)
1154 sec_trace_enter_api(NULL);
1155 sec_trace_return_api(SOSPeerInfoRef, ^{
1156 do_if_registered(soscc_SetNewPublicBackupKey, pubKey, error);
1158 return data_to_peer_info_error_request(kSecXPCOpSetNewPublicBackupKey, pubKey, error);
1159 }, CFSTR("return=%@"));
1162 SOSPeerInfoRef SOSCCCopyMyPeerWithNewDeviceRecoverySecret(CFDataRef secret, CFErrorRef *error){
1163 secnotice("devRecovery", "Enter SOSCCCopyMyPeerWithNewDeviceRecoverySecret()");
1164 CFDataRef publicKeyData = SOSCopyDeviceBackupPublicKey(secret, error);
1165 secnotice("devRecovery", "SOSCopyDeviceBackupPublicKey (%@)", publicKeyData);
1166 SOSPeerInfoRef copiedPeer = publicKeyData ? SOSSetNewPublicBackupKey(publicKeyData, error) : NULL;
1167 secnotice("devRecovery", "SOSSetNewPublicBackupKey (%@)", copiedPeer);
1168 CFReleaseNull(publicKeyData);
1172 bool SOSCCRegisterSingleRecoverySecret(CFDataRef aks_bag, bool forV0Only, CFErrorRef *error){
1173 sec_trace_enter_api(NULL);
1174 sec_trace_return_bool_api(^{
1175 do_if_registered(soscc_RegisterSingleRecoverySecret, aks_bag, forV0Only, error);
1176 return keybag_and_bool_to_bool_error_request(kSecXPCOpSetBagForAllSlices, aks_bag, forV0Only, error);
1181 bool SOSCCRegisterRecoveryPublicKey(CFDataRef recovery_key, CFErrorRef *error){
1182 sec_trace_enter_api(NULL);
1183 sec_trace_return_bool_api(^{
1184 bool retval = false;
1185 do_if_registered(soscc_RegisterRecoveryPublicKey, recovery_key, error);
1186 // NULL recovery_key is handled in recovery_and_bool_to_bool_error_request now.
1187 retval = recovery_and_bool_to_bool_error_request(kSecXPCOpRegisterRecoveryPublicKey, recovery_key, error);
1192 CFDataRef SOSCCCopyRecoveryPublicKey(CFErrorRef *error){
1193 sec_trace_enter_api(NULL);
1194 sec_trace_return_api(CFDataRef, ^{
1195 do_if_registered(soscc_CopyRecoveryPublicKey, error);
1196 return data_to_error_request(kSecXPCOpGetRecoveryPublicKey, error);
1197 }, CFSTR("return=%@"));
1199 static bool label_and_password_to_bool_error_request(enum SecXPCOperation op,
1200 CFStringRef user_label, CFDataRef user_password,
1203 __block bool result = false;
1205 securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
1206 CFStringPerformWithCString(user_label, ^(const char *utf8Str) {
1207 xpc_dictionary_set_string(message, kSecXPCKeyUserLabel, utf8Str);
1209 xpc_dictionary_set_data(message, kSecXPCKeyUserPassword, CFDataGetBytePtr(user_password), CFDataGetLength(user_password));
1211 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
1212 result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
1219 static bool label_and_password_and_dsid_to_bool_error_request(enum SecXPCOperation op,
1220 CFStringRef user_label, CFDataRef user_password,
1221 CFStringRef dsid, CFDataRef parentEvent, CFErrorRef* error)
1223 __block bool result = false;
1225 securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
1226 CFStringPerformWithCString(user_label, ^(const char *utf8Str) {
1227 xpc_dictionary_set_string(message, kSecXPCKeyUserLabel, utf8Str);
1229 CFStringPerformWithCString(dsid, ^(const char *utr8StrDSID) {
1230 xpc_dictionary_set_string(message, kSecXPCKeyDSID, utr8StrDSID);
1232 xpc_dictionary_set_data(message, kSecXPCKeyUserPassword, CFDataGetBytePtr(user_password), CFDataGetLength(user_password));
1234 SecXPCDictionarySetData(message, kSecXPCKeySignInAnalytics, parentEvent, error);
1237 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
1238 result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
1245 bool SOSCCRegisterUserCredentials(CFStringRef user_label, CFDataRef user_password, CFErrorRef* error)
1247 secnotice("circleOps", "SOSCCRegisterUserCredentials - calling SOSCCSetUserCredentials for %@\n", user_label);
1248 return SOSCCSetUserCredentials(user_label, user_password, error);
1251 bool SOSCCSetUserCredentials(CFStringRef user_label, CFDataRef user_password, CFErrorRef* error)
1253 secnotice("circleOps", "SOSCCSetUserCredentials for %@\n", user_label);
1254 sec_trace_enter_api(CFSTR("user_label=%@"), user_label);
1255 sec_trace_return_bool_api(^{
1256 do_if_registered(soscc_SetUserCredentials, user_label, user_password, error);
1258 return label_and_password_to_bool_error_request(kSecXPCOpSetUserCredentials, user_label, user_password, error);
1262 bool SOSCCSetUserCredentialsAndDSID(CFStringRef user_label, CFDataRef user_password, CFStringRef dsid, CFErrorRef *error)
1264 secnotice("circleOps", "SOSCCSetUserCredentialsAndDSID for %@\n", user_label);
1265 sec_trace_enter_api(CFSTR("user_label=%@"), user_label);
1266 sec_trace_return_bool_api(^{
1267 do_if_registered(soscc_SetUserCredentialsAndDSID, user_label, user_password, dsid, error);
1269 bool result = false;
1270 __block CFStringRef account_dsid = dsid;
1272 require_action_quiet(user_label, out, SOSErrorCreate(kSOSErrorParam, error, NULL, CFSTR("user_label is nil")));
1273 require_action_quiet(user_password, out, SOSErrorCreate(kSOSErrorParam, error, NULL, CFSTR("user_password is nil")));
1275 if(account_dsid == NULL){
1276 account_dsid = CFSTR("");
1278 return label_and_password_and_dsid_to_bool_error_request(kSecXPCOpSetUserCredentialsAndDSID, user_label, user_password, account_dsid, nil, error);
1285 bool SOSCCSetUserCredentialsAndDSIDWithAnalytics(CFStringRef user_label, CFDataRef user_password, CFStringRef dsid, CFDataRef parentEvent, CFErrorRef *error)
1287 secnotice("circleOps", "SOSCCSetUserCredentialsAndDSIDWithAnalytics for %@\n", user_label);
1288 sec_trace_enter_api(CFSTR("user_label=%@"), user_label);
1289 sec_trace_return_bool_api(^{
1290 do_if_registered(soscc_SetUserCredentialsAndDSIDWithAnalytics, user_label, user_password, dsid, parentEvent, error);
1292 bool result = false;
1293 __block CFStringRef account_dsid = dsid;
1295 require_action_quiet(user_label, out, SOSErrorCreate(kSOSErrorParam, error, NULL, CFSTR("user_label is nil")));
1296 require_action_quiet(user_password, out, SOSErrorCreate(kSOSErrorParam, error, NULL, CFSTR("user_password is nil")));
1298 if(account_dsid == NULL){
1299 account_dsid = CFSTR("");
1301 return label_and_password_and_dsid_to_bool_error_request(kSecXPCOpSetUserCredentialsAndDSIDWithAnalytics, user_label, user_password, account_dsid, parentEvent, error);
1308 static bool SOSCCTryUserCredentialsAndDSID_internal(CFStringRef user_label, CFDataRef user_password, CFStringRef dsid, CFErrorRef *error) {
1309 sec_trace_return_bool_api(^{
1310 do_if_registered(soscc_TryUserCredentials, user_label, user_password, dsid, error);
1312 bool result = false;
1313 __block CFStringRef account_dsid = dsid;
1315 require_action_quiet(user_label, out, SOSErrorCreate(kSOSErrorParam, error, NULL, CFSTR("user_label is nil")));
1316 require_action_quiet(user_password, out, SOSErrorCreate(kSOSErrorParam, error, NULL, CFSTR("user_password is nil")));
1318 if(account_dsid == NULL){
1319 account_dsid = CFSTR("");
1322 return label_and_password_and_dsid_to_bool_error_request(kSecXPCOpTryUserCredentials, user_label, user_password, account_dsid, nil, error);
1330 bool SOSCCTryUserCredentialsAndDSID(CFStringRef user_label, CFDataRef user_password, CFStringRef dsid, CFErrorRef *error)
1332 secnotice("sosops", "SOSCCTryUserCredentialsAndDSID!! %@\n", user_label);
1333 require_action_quiet(user_label, out, SOSErrorCreate(kSOSErrorParam, error, NULL, CFSTR("user_label is nil")));
1334 require_action_quiet(user_password, out, SOSErrorCreate(kSOSErrorParam, error, NULL, CFSTR("user_password is nil")));
1335 CFStringRef account_dsid = (dsid != NULL) ? dsid: CFSTR("");
1336 return SOSCCTryUserCredentialsAndDSID_internal(user_label, user_password, account_dsid, error);
1341 bool SOSCCTryUserCredentials(CFStringRef user_label, CFDataRef user_password, CFErrorRef* error) {
1342 return SOSCCTryUserCredentialsAndDSID_internal(user_label, user_password, NULL, error);
1346 bool SOSCCCanAuthenticate(CFErrorRef* error) {
1347 sec_trace_enter_api(NULL);
1348 sec_trace_return_bool_api(^{
1349 do_if_registered(soscc_CanAuthenticate, error);
1351 return simple_bool_error_request(kSecXPCOpCanAuthenticate, error);
1355 bool SOSCCPurgeUserCredentials(CFErrorRef* error) {
1356 sec_trace_enter_api(NULL);
1357 sec_trace_return_bool_api(^{
1358 do_if_registered(soscc_PurgeUserCredentials, error);
1360 return simple_bool_error_request(kSecXPCOpPurgeUserCredentials, error);
1364 enum DepartureReason SOSCCGetLastDepartureReason(CFErrorRef *error) {
1365 sec_trace_enter_api(NULL);
1366 sec_trace_return_api(enum DepartureReason, ^{
1367 do_if_registered(soscc_GetLastDepartureReason, error);
1369 return (enum DepartureReason) simple_int_error_request(kSecXPCOpGetLastDepartureReason, error);
1373 bool SOSCCSetLastDepartureReason(enum DepartureReason reason, CFErrorRef *error) {
1374 sec_trace_enter_api(NULL);
1375 sec_trace_return_api(bool, ^{
1376 do_if_registered(soscc_SetLastDepartureReason, reason, error);
1377 return securityd_send_sync_and_do(kSecXPCOpSetLastDepartureReason, error,
1378 ^bool(xpc_object_t message, CFErrorRef *error) {
1379 xpc_dictionary_set_int64(message, kSecXPCKeyReason, reason);
1382 ^bool(xpc_object_t response, __unused CFErrorRef *error) {
1383 return xpc_dictionary_get_bool(response, kSecXPCKeyResult);
1389 CFStringRef SOSCCCopyIncompatibilityInfo(CFErrorRef* error) {
1390 sec_trace_enter_api(NULL);
1391 sec_trace_return_api(CFStringRef, ^{
1392 do_if_registered(soscc_CopyIncompatibilityInfo, error);
1394 return simple_cfstring_error_request(kSecXPCOpCopyIncompatibilityInfo, error);
1398 bool SOSCCProcessEnsurePeerRegistration(CFErrorRef* error){
1399 secnotice("updates", "enter SOSCCProcessEnsurePeerRegistration");
1400 sec_trace_enter_api(NULL);
1401 sec_trace_return_bool_api(^{
1402 do_if_registered(soscc_EnsurePeerRegistration, error);
1404 return simple_bool_error_request(soscc_EnsurePeerRegistration_id, error);
1409 CFSetRef /* CFString */ SOSCCProcessSyncWithPeers(CFSetRef peers, CFSetRef backupPeers, CFErrorRef* error)
1411 sec_trace_enter_api(NULL);
1412 sec_trace_return_api(CFSetRef, ^{
1413 do_if_registered(soscc_ProcessSyncWithPeers, peers, backupPeers, error);
1415 return cfset_cfset_to_cfset_error_request(kSecXPCOpProcessSyncWithPeers, peers, backupPeers, error);
1420 SyncWithAllPeersReason SOSCCProcessSyncWithAllPeers(CFErrorRef* error)
1422 sec_trace_enter_api(NULL);
1423 sec_trace_return_api(SyncWithAllPeersReason, ^{
1424 do_if_registered(soscc_ProcessSyncWithAllPeers, error);
1426 return (SyncWithAllPeersReason) simple_int_error_request(kSecXPCOpProcessSyncWithAllPeers, error);
1430 CFStringRef SOSCCGetStatusDescription(SOSCCStatus status)
1433 case kSOSCCInCircle:
1434 return CFSTR("InCircle");
1435 case kSOSCCNotInCircle:
1436 return CFSTR("NotInCircle");
1437 case kSOSCCRequestPending:
1438 return CFSTR("RequestPending");
1439 case kSOSCCCircleAbsent:
1440 return CFSTR("CircleAbsent");
1442 return CFSTR("InternalError");
1444 return CFSTR("Unknown Status");
1449 kSOSCCGeneralViewError = -1,
1450 kSOSCCViewMember = 0,
1451 kSOSCCViewNotMember = 1,
1452 kSOSCCViewNotQualified = 2,
1453 kSOSCCNoSuchView = 3,
1457 CFStringRef SOSCCGetViewResultDescription(SOSViewResultCode vrc)
1460 case kSOSCCGeneralViewError:
1461 return CFSTR("GeneralViewError");
1462 case kSOSCCViewMember:
1463 return CFSTR("ViewMember");
1464 case kSOSCCViewNotMember:
1465 return CFSTR("ViewNotMember");
1466 case kSOSCCViewNotQualified:
1467 return CFSTR("ViewNotQualified");
1468 case kSOSCCNoSuchView:
1469 return CFSTR("ViewUndefined");
1471 return CFSTR("Unknown View Status");
1476 static int64_t name_action_to_code_request(enum SecXPCOperation op, uint16_t error_result,
1477 CFStringRef name, uint64_t action, CFErrorRef *error) {
1478 __block int64_t result = error_result;
1480 securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
1481 CFStringPerformWithCString(name, ^(const char *utf8Str) {
1482 xpc_dictionary_set_string(message, kSecXPCKeyViewName, utf8Str);
1484 xpc_dictionary_set_int64(message, kSecXPCKeyViewActionCode, action);
1486 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
1487 if (response && xpc_dictionary_entry_is_type(response, kSecXPCKeyResult, XPC_TYPE_INT64)) {
1488 result = xpc_dictionary_get_int64(response, kSecXPCKeyResult);
1490 return result != error_result;
1496 SOSViewResultCode SOSCCView(CFStringRef view, SOSViewActionCode actionCode, CFErrorRef *error) {
1497 if(actionCode == kSOSCCViewQuery) {
1498 uint64_t circleStat = SOSGetCachedCircleBitmask();
1499 if(circleStat & CC_STATISVALID) {
1500 SOSViewResultCode retval = kSOSCCViewNotMember;
1501 CFSetRef enabledViews = SOSCreateCachedViewStatus();
1503 if(CFSetContainsValue(enabledViews, view)) {
1504 retval = kSOSCCViewMember;
1506 retval = kSOSCCViewNotMember;
1508 CFReleaseNull(enabledViews);
1513 sec_trace_enter_api(NULL);
1514 sec_trace_return_api(SOSViewResultCode, ^{
1515 do_if_registered(soscc_View, view, actionCode, error);
1517 return (SOSViewResultCode) name_action_to_code_request(kSecXPCOpView, kSOSCCGeneralViewError, view, actionCode, error);
1518 }, CFSTR("SOSViewResultCode=%d"))
1522 bool SOSCCViewSet(CFSetRef enabledViews, CFSetRef disabledViews) {
1523 CFErrorRef *error = NULL;
1524 __block bool result = false;
1526 sec_trace_enter_api(NULL);
1527 sec_trace_return_bool_api(^{
1528 do_if_registered(soscc_ViewSet, enabledViews, disabledViews);
1529 return securityd_send_sync_and_do(kSecXPCOpViewSet, error, ^bool(xpc_object_t message, CFErrorRef *error) {
1530 xpc_object_t enabledSetXpc = CreateXPCObjectWithCFSetRef(enabledViews, error);
1531 xpc_object_t disabledSetXpc = CreateXPCObjectWithCFSetRef(disabledViews, error);
1532 if (enabledSetXpc) xpc_dictionary_set_value(message, kSecXPCKeyEnabledViewsKey, enabledSetXpc);
1533 if (disabledSetXpc) xpc_dictionary_set_value(message, kSecXPCKeyDisabledViewsKey, disabledSetXpc);
1534 return (enabledSetXpc != NULL) || (disabledSetXpc != NULL) ;
1535 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
1536 result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
1542 bool SOSCCViewSetWithAnalytics(CFSetRef enabledViews, CFSetRef disabledViews, CFDataRef parentEvent) {
1543 CFErrorRef *error = NULL;
1544 __block bool result = false;
1546 sec_trace_enter_api(NULL);
1547 sec_trace_return_bool_api(^{
1548 do_if_registered(soscc_ViewSetWithAnalytics, enabledViews, disabledViews, parentEvent);
1549 return securityd_send_sync_and_do(kSecXPCOpViewSetWithAnalytics, error, ^bool(xpc_object_t message, CFErrorRef *error) {
1550 xpc_object_t enabledSetXpc = CreateXPCObjectWithCFSetRef(enabledViews, error);
1551 xpc_object_t disabledSetXpc = CreateXPCObjectWithCFSetRef(disabledViews, error);
1552 if (enabledSetXpc) xpc_dictionary_set_value(message, kSecXPCKeyEnabledViewsKey, enabledSetXpc);
1553 if (disabledSetXpc) xpc_dictionary_set_value(message, kSecXPCKeyDisabledViewsKey, disabledSetXpc);
1554 if(parentEvent) SecXPCDictionarySetData(message, kSecXPCKeySignInAnalytics, parentEvent, error);
1555 return (enabledSetXpc != NULL) || (disabledSetXpc != NULL) ;
1556 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
1557 result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
1563 static CFStringRef copyViewNames(size_t n, CFStringRef *views) {
1564 CFMutableStringRef retval = CFStringCreateMutable(kCFAllocatorDefault, 0);
1565 CFStringAppend(retval, CFSTR("|"));
1566 for(size_t i = 0; i < n; i++) {
1567 CFStringAppend(retval, views[i]);
1568 CFStringAppend(retval, CFSTR("|"));
1573 static bool sosIsViewSetSyncing(size_t n, CFStringRef *views) {
1574 __block bool retval = true;
1575 CFErrorRef error = NULL;
1577 if(n == 0 || views == NULL) return false;
1578 CFStringRef viewString = copyViewNames(n, views);
1580 SOSCCStatus cstatus = SOSCCThisDeviceIsInCircle(&error);
1581 if(cstatus != kSOSCCInCircle) {
1582 secnotice("viewCheck", "Checking view / circle status for %@: SOSCCStatus: (%@) Error: (%@)", viewString, SOSCCGetStatusDescription(cstatus), error);
1586 if(retval == true) {
1588 // use cached values if valid
1589 uint64_t circleStat = SOSGetCachedCircleBitmask();
1590 if(circleStat & CC_STATISVALID) {
1591 CFSetRef enabledViews = SOSCreateCachedViewStatus();
1593 for(size_t i = 0; i < n; i++) {
1594 if(!CFSetContainsValue(enabledViews, views[i])) {
1598 CFReleaseNull(enabledViews);
1599 CFReleaseNull(viewString);
1604 // make the individual calls otherwise.
1605 for(size_t i = 0; i < n; i++) {
1606 SOSViewResultCode vstatus = SOSCCView(views[i], kSOSCCViewQuery, &error);
1607 if(vstatus != kSOSCCViewMember) {
1608 secnotice("viewCheck", "Checking view / circle status for %@: SOSCCStatus: (%@) SOSViewResultCode(%@) Error: (%@)", views[i],
1609 SOSCCGetStatusDescription(cstatus), SOSCCGetViewResultDescription(vstatus), error);
1615 if(retval == true) {
1616 secnotice("viewCheck", "Checking view / circle status for %@: ENABLED", viewString);
1618 CFReleaseNull(error);
1619 CFReleaseNull(viewString);
1623 bool SOSCCIsIcloudKeychainSyncing(void) {
1624 CFStringRef views[] = { kSOSViewWiFi, kSOSViewAutofillPasswords, kSOSViewSafariCreditCards, kSOSViewOtherSyncable };
1625 return sosIsViewSetSyncing(sizeof(views)/sizeof(views[0]), views);
1628 bool SOSCCIsSafariSyncing(void) {
1629 CFStringRef views[] = { kSOSViewAutofillPasswords, kSOSViewSafariCreditCards };
1630 return sosIsViewSetSyncing(sizeof(views)/sizeof(views[0]), views);
1633 bool SOSCCIsAppleTVSyncing(void) {
1634 CFStringRef views[] = { kSOSViewAppleTV };
1635 return sosIsViewSetSyncing(sizeof(views)/sizeof(views[0]), views);
1638 bool SOSCCIsHomeKitSyncing(void) {
1639 CFStringRef views[] = { kSOSViewHomeKit };
1640 return sosIsViewSetSyncing(sizeof(views)/sizeof(views[0]), views);
1643 bool SOSCCIsWiFiSyncing(void) {
1644 CFStringRef views[] = { kSOSViewWiFi };
1645 return sosIsViewSetSyncing(sizeof(views)/sizeof(views[0]), views);
1648 bool SOSCCIsContinuityUnlockSyncing(void) {
1649 CFStringRef views[] = { kSOSViewContinuityUnlock };
1650 return sosIsViewSetSyncing(sizeof(views)/sizeof(views[0]), views);
1654 bool SOSCCSetEscrowRecord(CFStringRef escrow_label, uint64_t tries, CFErrorRef *error ){
1655 secnotice("escrow", "enter SOSCCSetEscrowRecord");
1656 sec_trace_enter_api(NULL);
1657 sec_trace_return_bool_api(^{
1658 do_if_registered(soscc_SetEscrowRecords, escrow_label, tries, error);
1660 return escrow_to_bool_error_request(kSecXPCOpSetEscrowRecord, escrow_label, tries, error);
1664 CFDictionaryRef SOSCCCopyEscrowRecord(CFErrorRef *error){
1665 secnotice("escrow", "enter SOSCCCopyEscrowRecord");
1666 sec_trace_enter_api(NULL);
1667 sec_trace_return_api(CFDictionaryRef, ^{
1668 do_if_registered(soscc_CopyEscrowRecords, error);
1670 return strings_to_dictionary_error_request(kSecXPCOpGetEscrowRecord, error);
1671 }, CFSTR("return=%@"))
1675 CFDictionaryRef SOSCCCopyBackupInformation(CFErrorRef *error) {
1676 secnotice("escrow", "enter SOSCCCopyBackupInformation");
1677 sec_trace_enter_api(NULL);
1678 sec_trace_return_api(CFDictionaryRef, ^{
1679 do_if_registered(soscc_CopyBackupInformation, error);
1680 return strings_to_dictionary_error_request(kSecXPCOpCopyBackupInformation, error);
1681 }, CFSTR("return=%@"))
1684 bool SOSWrapToBackupSliceKeyBagForView(CFStringRef viewName, CFDataRef input, CFDataRef* output, CFDataRef* bskbEncoded, CFErrorRef* error) {
1685 sec_trace_enter_api(NULL);
1686 sec_trace_return_bool_api(^{
1687 do_if_registered(sosbskb_WrapToBackupSliceKeyBagForView, viewName, input, output, bskbEncoded, error);
1689 return cfstring_and_cfdata_to_cfdata_cfdata_error_request(kSecXPCOpWrapToBackupSliceKeyBagForView, viewName, input, output, bskbEncoded, error);
1694 SOSPeerInfoRef SOSCCCopyApplication(CFErrorRef *error) {
1695 secnotice("hsa2PB", "enter SOSCCCopyApplication applicant");
1696 sec_trace_enter_api(NULL);
1698 sec_trace_return_api(SOSPeerInfoRef, ^{
1699 do_if_registered(soscc_CopyApplicant, error);
1700 return peer_info_error_request(kSecXPCOpCopyApplication, error);
1701 }, CFSTR("return=%@"));
1704 bool SOSCCCleanupKVSKeys(CFErrorRef *error) {
1705 secnotice("cleanup-keys", "enter SOSCCCleanupKVSKeys");
1706 sec_trace_enter_api(NULL);
1707 sec_trace_return_bool_api(^{
1708 do_if_registered(soscc_SOSCCCleanupKVSKeys, error);
1710 return simple_bool_error_request(kSecXPCOpKVSKeyCleanup, error);
1716 bool SOSCCTestPopulateKVSWithBadKeys(CFErrorRef *error) {
1717 secnotice("cleanup-keys", "enter SOSCCPopulateKVSWithBadKeys");
1718 sec_trace_enter_api(NULL);
1719 sec_trace_return_bool_api(^{
1720 do_if_registered(soscc_SOSCCTestPopulateKVSWithBadKeys, error);
1722 return simple_bool_error_request(kSecXPCOpPopulateKVS, error);
1728 CFDataRef SOSCCCopyCircleJoiningBlob(SOSPeerInfoRef applicant, CFErrorRef *error) {
1729 secnotice("hsa2PB", "enter SOSCCCopyCircleJoiningBlob approver");
1730 sec_trace_enter_api(NULL);
1732 sec_trace_return_api(CFDataRef, ^{
1733 CFDataRef result = NULL;
1734 do_if_registered(soscc_CopyCircleJoiningBlob, applicant, error);
1735 CFDataRef piData = SOSPeerInfoCopyEncodedData(applicant, kCFAllocatorDefault, error);
1736 result = cfdata_error_request_returns_cfdata(kSecXPCOpCopyCircleJoiningBlob, piData, error);
1737 CFReleaseNull(piData);
1739 }, CFSTR("return=%@"));
1742 CFDataRef SOSCCCopyInitialSyncData(CFErrorRef *error) {
1743 secnotice("circleJoin", "enter SOSCCCopyInitialSyncData approver");
1744 sec_trace_enter_api(NULL);
1746 sec_trace_return_api(CFDataRef, ^{
1747 do_if_registered(soscc_CopyInitialSyncData, error);
1748 return data_to_error_request(kSecXPCOpCopyInitialSyncBlob, error);
1749 }, CFSTR("return=%@"));
1752 bool SOSCCJoinWithCircleJoiningBlob(CFDataRef joiningBlob, PiggyBackProtocolVersion version, CFErrorRef *error) {
1753 secnotice("hsa2PB", "enter SOSCCJoinWithCircleJoiningBlob applicant");
1754 sec_trace_enter_api(NULL);
1755 sec_trace_return_bool_api(^{
1756 do_if_registered(soscc_JoinWithCircleJoiningBlob, joiningBlob, version, error);
1758 return cfdata_and_int_error_request_returns_bool(kSecXPCOpJoinWithCircleJoiningBlob, joiningBlob, version, error);
1764 bool SOSCCIsThisDeviceLastBackup(CFErrorRef *error) {
1765 secnotice("peer", "enter SOSCCIsThisDeviceLastBackup");
1766 sec_trace_enter_api(NULL);
1767 sec_trace_return_bool_api(^{
1768 do_if_registered(soscc_IsThisDeviceLastBackup, error);
1770 return simple_bool_error_request(kSecXPCOpIsThisDeviceLastBackup, error);
1774 CFBooleanRef SOSCCPeersHaveViewsEnabled(CFArrayRef viewNames, CFErrorRef *error) {
1775 secnotice("view-enabled", "enter SOSCCPeersHaveViewsEnabled");
1776 sec_trace_enter_api(NULL);
1777 sec_trace_return_api(CFBooleanRef, ^{
1778 do_if_registered(soscc_SOSCCPeersHaveViewsEnabled, viewNames, error);
1780 return cfarray_to_cfboolean_error_request(kSecXPCOpPeersHaveViewsEnabled, viewNames, error);
1781 }, CFSTR("return=%@"))
1784 bool SOSCCMessageFromPeerIsPending(SOSPeerInfoRef peer, CFErrorRef *error) {
1785 secnotice("pending-check", "enter SOSCCMessageFromPeerIsPending");
1787 sec_trace_return_bool_api(^{
1788 do_if_registered(soscc_SOSCCMessageFromPeerIsPending, peer, error);
1790 return peer_info_to_bool_error_request(kSecXPCOpMessageFromPeerIsPending, peer, error);
1795 bool SOSCCSendToPeerIsPending(SOSPeerInfoRef peer, CFErrorRef *error) {
1796 sec_trace_return_bool_api(^{
1797 do_if_registered(soscc_SOSCCSendToPeerIsPending, peer, error);
1799 return peer_info_to_bool_error_request(kSecXPCOpSendToPeerIsPending, peer, error);
1804 * SecSOSStatus interfaces
1807 @interface SecSOSStatus : NSObject {
1808 NSXPCConnection* _connection;
1810 @property NSXPCConnection *connection;
1813 @implementation SecSOSStatus
1814 @synthesize connection = _connection;
1816 - (instancetype) init
1818 if ((self = [super init]) == NULL)
1821 NSXPCInterface *interface = [NSXPCInterface interfaceWithProtocol:@protocol(SOSControlProtocol)];
1822 _SOSControlSetupInterface(interface);
1824 self.connection = [[NSXPCConnection alloc] initWithMachServiceName:@(kSecuritydSOSServiceName) options:0];
1825 if (self.connection == NULL)
1828 self.connection.remoteObjectInterface = interface;
1830 [self.connection resume];
1837 static id<SOSControlProtocol>
1838 SOSCCGetStatusObject(CFErrorRef *error)
1840 if (gSecurityd && gSecurityd->soscc_status)
1841 return (__bridge id<SOSControlProtocol>)gSecurityd->soscc_status();
1843 static SecSOSStatus *control;
1844 static dispatch_once_t onceToken;
1845 dispatch_once(&onceToken, ^{
1846 control = [[SecSOSStatus alloc] init];
1848 return control.connection.remoteObjectProxy;
1852 SOSCCAccountGetPublicKey(void (^reply)(BOOL trusted, NSData *data, NSError *error))
1854 CFErrorRef error = NULL;
1855 id<SOSControlProtocol> status = SOSCCGetStatusObject(&error);
1856 if (status == NULL) {
1857 reply(false, NULL, (__bridge NSError *)error);
1858 CFReleaseNull(error);
1862 [status userPublicKey:reply];
1866 SOSCCAccountGetAccountPrivateCredential(void (^complete)(NSData *data, NSError *error))
1868 CFErrorRef error = NULL;
1869 id<SOSControlProtocol> status = SOSCCGetStatusObject(&error);
1870 if (status == NULL) {
1871 complete(NULL, (__bridge NSError *)error);
1872 CFReleaseNull(error);
1876 [status validatedStashedAccountCredential:complete];
1880 SOSCCAccountGetKeyCircleGeneration(void (^reply)(NSData *data, NSError *error))
1882 SOSCCAccountGetPublicKey(^(BOOL __unused trusted, NSData *data, NSError *error){
1886 NSMutableData *digest = [NSMutableData dataWithLength:CCSHA256_OUTPUT_SIZE];
1887 ccdigest(ccsha256_di(), [data length], [data bytes], [digest mutableBytes]);
1888 reply(digest, error);