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@
29 #include <AssertMacros.h>
30 #include <Security/SecureObjectSync/SOSCloudCircle.h>
31 #include <Security/SecureObjectSync/SOSCloudCircleInternal.h>
32 #include <Security/SecureObjectSync/SOSCircle.h>
33 #include <Security/SecureObjectSync/SOSAccount.h>
34 #include <Security/SecureObjectSync/SOSAccountPriv.h>
35 #include <Security/SecureObjectSync/SOSFullPeerInfo.h>
36 #include <Security/SecureObjectSync/SOSPeerInfoCollections.h>
37 #include <Security/SecureObjectSync/SOSInternal.h>
38 #include <Security/SecureObjectSync/SOSRing.h>
39 #include <Security/SecureObjectSync/SOSBackupSliceKeyBag.h>
41 #include <Security/SecKeyPriv.h>
42 #include <Security/SecFramework.h>
43 #include <CoreFoundation/CFXPCBridge.h>
45 #include <securityd/SecItemServer.h>
47 #include <utilities/SecDispatchRelease.h>
48 #include <utilities/SecCFRelease.h>
49 #include <utilities/SecCFWrappers.h>
50 #include <utilities/SecXPCError.h>
52 #include <utilities/debugging.h>
54 #include <CoreFoundation/CoreFoundation.h>
57 #define MINIMIZE_INCLUDES MINIMIZE_INCLUDES
58 #include <ipc/securityd_client.h>
59 #include <securityd/spi.h>
61 #include <Security/SecuritydXPC.h>
62 #include "SOSPeerInfoDER.h"
64 const char * kSOSCCCircleChangedNotification
= "com.apple.security.secureobjectsync.circlechanged";
65 const char * kSOSCCViewMembershipChangedNotification
= "com.apple.security.secureobjectsync.viewschanged";
66 const char * kSOSCCInitialSyncChangedNotification
= "com.apple.security.secureobjectsync.initialsyncchanged";
67 const char * kSOSCCHoldLockForInitialSync
= "com.apple.security.secureobjectsync.holdlock";
68 const char * kSOSCCPeerAvailable
= "com.apple.security.secureobjectsync.peeravailable";
70 #define do_if_registered(sdp, ...) if (gSecurityd && gSecurityd->sdp) { return gSecurityd->sdp(__VA_ARGS__); }
72 static bool xpc_dictionary_entry_is_type(xpc_object_t dictionary
, const char *key
, xpc_type_t type
)
74 xpc_object_t value
= xpc_dictionary_get_value(dictionary
, key
);
76 return value
&& (xpc_get_type(value
) == type
);
79 SOSCCStatus
SOSCCThisDeviceIsInCircle(CFErrorRef
*error
)
81 sec_trace_enter_api(NULL
);
82 sec_trace_return_api(SOSCCStatus
, ^{
83 SOSCCStatus result
= kSOSCCError
;
85 do_if_registered(soscc_ThisDeviceIsInCircle
, error
);
87 xpc_object_t message
= securityd_create_message(kSecXPCOpDeviceInCircle
, error
);
89 xpc_object_t response
= securityd_message_with_reply_sync(message
, error
);
91 if (response
&& xpc_dictionary_entry_is_type(response
, kSecXPCKeyResult
, XPC_TYPE_INT64
)) {
92 result
= (SOSCCStatus
) xpc_dictionary_get_int64(response
, kSecXPCKeyResult
);
98 if (response
&& securityd_message_no_error(response
, error
))
100 char *desc
= xpc_copy_description(response
);
101 SecCFCreateErrorWithFormat(0, sSecXPCErrorDomain
, NULL
, error
, NULL
, CFSTR("Remote error occurred/no info: %s"), desc
);
106 xpc_release(response
);
108 xpc_release(message
);
113 }, CFSTR("SOSCCStatus=%d"))
116 static bool cfstring_to_error_request(enum SecXPCOperation op
, CFStringRef string
, CFErrorRef
* error
)
118 __block
bool result
= false;
120 secdebug("sosops","enter - operation: %d", op
);
121 securityd_send_sync_and_do(op
, error
, ^bool(xpc_object_t message
, CFErrorRef
*error
) {
122 xpc_object_t xString
= _CFXPCCreateXPCObjectFromCFObject(string
);
123 bool success
= false;
125 xpc_dictionary_set_value(message
, kSecXPCKeyString
, xString
);
127 xpc_release(xString
);
130 }, ^bool(xpc_object_t response
, __unused CFErrorRef
*error
) {
131 result
= xpc_dictionary_get_bool(response
, kSecXPCKeyResult
);
137 static SOSRingStatus
cfstring_to_uint64_request(enum SecXPCOperation op
, CFStringRef string
, CFErrorRef
* error
)
139 __block
bool result
= false;
141 secdebug("sosops","enter - operation: %d", op
);
142 securityd_send_sync_and_do(op
, error
, ^bool(xpc_object_t message
, CFErrorRef
*error
) {
143 xpc_object_t xString
= _CFXPCCreateXPCObjectFromCFObject(string
);
144 bool success
= false;
146 xpc_dictionary_set_value(message
, kSecXPCKeyString
, xString
);
148 xpc_release(xString
);
151 }, ^bool(xpc_object_t response
, __unused CFErrorRef
*error
) {
152 result
= xpc_dictionary_get_int64(response
, kSecXPCKeyResult
);
158 static CFStringRef
simple_cfstring_error_request(enum SecXPCOperation op
, CFErrorRef
* error
)
160 __block CFStringRef result
= NULL
;
162 secdebug("sosops","enter - operation: %d", op
);
163 securityd_send_sync_and_do(op
, error
, NULL
, ^bool(xpc_object_t response
, __unused CFErrorRef
*error
) {
164 const char *c_string
= xpc_dictionary_get_string(response
, kSecXPCKeyResult
);
167 result
= CFStringCreateWithBytes(kCFAllocatorDefault
, (const UInt8
*)c_string
, strlen(c_string
), kCFStringEncodingUTF8
, false);
170 return c_string
!= NULL
;
175 static bool simple_bool_error_request(enum SecXPCOperation op
, CFErrorRef
* error
)
177 __block
bool result
= false;
179 secdebug("sosops","enter - operation: %d", op
);
180 securityd_send_sync_and_do(op
, error
, NULL
, ^bool(xpc_object_t response
, __unused CFErrorRef
*error
) {
181 result
= xpc_dictionary_get_bool(response
, kSecXPCKeyResult
);
187 static CFBooleanRef
cfarray_to_cfboolean_error_request(enum SecXPCOperation op
, CFArrayRef views
, CFErrorRef
* error
)
189 __block
bool result
= false;
191 secdebug("sosops","enter - operation: %d", op
);
192 bool noError
= securityd_send_sync_and_do(op
, error
, ^bool(xpc_object_t message
, CFErrorRef
*error
) {
193 return SecXPCDictionarySetPList(message
, kSecXPCKeyArray
, views
, error
);
194 }, ^bool(xpc_object_t response
, __unused CFErrorRef
*error
) {
195 result
= xpc_dictionary_get_bool(response
, kSecXPCKeyResult
);
198 return noError
? (result
? kCFBooleanTrue
: kCFBooleanFalse
) : NULL
;
202 static bool escrow_to_bool_error_request(enum SecXPCOperation op
, CFStringRef escrow_label
, uint64_t tries
, CFErrorRef
* error
)
204 __block
bool result
= false;
206 securityd_send_sync_and_do(op
, error
, ^bool(xpc_object_t message
, CFErrorRef
*error
) {
208 bool success
= false;
209 xpc_object_t xEscrowLabel
= _CFXPCCreateXPCObjectFromCFObject(escrow_label
);
211 xpc_dictionary_set_value(message
, kSecXPCKeyEscrowLabel
, xEscrowLabel
);
213 xpc_release(xEscrowLabel
);
216 xpc_dictionary_set_int64(message
, kSecXPCKeyTriesLabel
, tries
);
221 }, ^bool(xpc_object_t response
, __unused CFErrorRef
*error
) {
222 result
= xpc_dictionary_get_bool(response
, kSecXPCKeyResult
);
228 static CF_RETURNS_RETAINED CFArrayRef
simple_array_error_request(enum SecXPCOperation op
, CFErrorRef
* error
)
230 __block CFArrayRef result
= NULL
;
232 secdebug("sosops","enter - operation: %d", op
);
233 if (securityd_send_sync_and_do(op
, error
, NULL
, ^bool(xpc_object_t response
, CFErrorRef
*error
) {
234 xpc_object_t temp_result
= xpc_dictionary_get_value(response
, kSecXPCKeyResult
);
235 result
= _CFXPCCreateCFObjectFromXPCObject(temp_result
);
236 return result
!= NULL
;
238 if (!isArray(result
)) {
239 SOSErrorCreate(kSOSErrorUnexpectedType
, error
, NULL
, CFSTR("Expected array, got: %@"), result
);
240 CFReleaseNull(result
);
246 static CFDictionaryRef
strings_to_dictionary_error_request(enum SecXPCOperation op
, CFErrorRef
* error
)
248 __block CFDictionaryRef result
= NULL
;
250 secdebug("sosops","enter - operation: %d", op
);
252 if (securityd_send_sync_and_do(op
, error
, NULL
, ^bool(xpc_object_t response
, CFErrorRef
*error
) {
253 xpc_object_t temp_result
= xpc_dictionary_get_value(response
, kSecXPCKeyResult
);
255 result
= _CFXPCCreateCFObjectFromXPCObject(temp_result
);
256 return result
!= NULL
;
259 if (!isDictionary(result
)) {
260 SOSErrorCreate(kSOSErrorUnexpectedType
, error
, NULL
, CFSTR("Expected dictionary, got: %@"), result
);
261 CFReleaseNull(result
);
268 static int simple_int_error_request(enum SecXPCOperation op
, CFErrorRef
* error
)
270 __block
int result
= 0;
272 secdebug("sosops","enter - operation: %d", op
);
273 securityd_send_sync_and_do(op
, error
, NULL
, ^bool(xpc_object_t response
, __unused CFErrorRef
*error
) {
274 int64_t temp_result
= xpc_dictionary_get_int64(response
, kSecXPCKeyResult
);
275 if ((temp_result
>= INT32_MIN
) && (temp_result
<= INT32_MAX
)) {
276 result
= (int)temp_result
;
283 static SOSPeerInfoRef
peer_info_error_request(enum SecXPCOperation op
, CFErrorRef
* error
)
285 SOSPeerInfoRef result
= NULL
;
286 __block CFDataRef data
= NULL
;
288 secdebug("sosops","enter - operation: %d", op
);
289 securityd_send_sync_and_do(op
, error
, NULL
, ^bool(xpc_object_t response
, CFErrorRef
*error
) {
290 xpc_object_t temp_result
= xpc_dictionary_get_value(response
, kSecXPCKeyResult
);
291 if (response
&& (NULL
!= temp_result
)) {
292 data
= _CFXPCCreateCFObjectFromXPCObject(temp_result
);
298 SOSErrorCreate(kSOSErrorUnexpectedType
, error
, NULL
, CFSTR("Expected CFData, got: %@"), result
);
302 result
= SOSPeerInfoCreateFromData(kCFAllocatorDefault
, error
, data
);
308 static CFDataRef
data_to_error_request(enum SecXPCOperation op
, CFErrorRef
*error
)
310 __block CFDataRef result
= NULL
;
312 secdebug("sosops", "enter -- operation: %d", op
);
313 secdebug("sosops","enter - operation: %d", op
);
314 securityd_send_sync_and_do(op
, error
, NULL
, ^bool(xpc_object_t response
, CFErrorRef
*error
) {
315 xpc_object_t temp_result
= xpc_dictionary_get_value(response
, kSecXPCKeyResult
);
316 if (response
&& (NULL
!= temp_result
)) {
317 result
= _CFXPCCreateCFObjectFromXPCObject(temp_result
);
319 return result
!= NULL
;
322 if (!isData(result
)) {
323 SOSErrorCreate(kSOSErrorUnexpectedType
, error
, NULL
, CFSTR("Expected CFData, got: %@"), result
);
330 static CFArrayRef
array_of_info_error_request(enum SecXPCOperation op
, CFErrorRef
* error
)
332 __block CFArrayRef result
= NULL
;
334 secdebug("sosops","enter - operation: %d", op
);
335 securityd_send_sync_and_do(op
, error
, NULL
, ^bool(xpc_object_t response
, CFErrorRef
*error
) {
336 xpc_object_t encoded_array
= xpc_dictionary_get_value(response
, kSecXPCKeyResult
);
337 if (response
&& (NULL
!= encoded_array
)) {
338 result
= CreateArrayOfPeerInfoWithXPCObject(encoded_array
, error
);
340 return result
!= NULL
;
343 if (!isArray(result
)) {
344 SOSErrorCreate(kSOSErrorUnexpectedType
, error
, NULL
, CFSTR("Expected array, got: %@"), result
);
345 CFReleaseNull(result
);
350 static SOSPeerInfoRef
data_to_peer_info_error_request(enum SecXPCOperation op
, CFDataRef secret
, CFErrorRef
* error
)
352 __block SOSPeerInfoRef result
= false;
353 __block CFDataRef data
= NULL
;
355 secdebug("sosops", "enter - operation: %d", op
);
356 securityd_send_sync_and_do(op
, error
, ^bool(xpc_object_t message
, CFErrorRef
*error
) {
357 xpc_object_t xsecretData
= _CFXPCCreateXPCObjectFromCFObject(secret
);
358 bool success
= false;
360 xpc_dictionary_set_value(message
, kSecXPCKeyNewPublicBackupKey
, xsecretData
);
362 xpc_release(xsecretData
);
365 }, ^bool(xpc_object_t response
, __unused CFErrorRef
*error
) {
366 xpc_object_t temp_result
= xpc_dictionary_get_value(response
, kSecXPCKeyResult
);
367 if (response
&& (NULL
!= temp_result
)) {
368 data
= _CFXPCCreateCFObjectFromXPCObject(temp_result
);
370 return result
!= NULL
;
374 SOSErrorCreate(kSOSErrorUnexpectedType
, error
, NULL
, CFSTR("Expected CFData, got: %@"), result
);
378 result
= SOSPeerInfoCreateFromData(kCFAllocatorDefault
, error
, data
);
384 static bool keybag_and_bool_to_bool_error_request(enum SecXPCOperation op
, CFDataRef data
, bool include
, CFErrorRef
* error
)
386 secdebug("sosops", "enter - operation: %d", op
);
387 return securityd_send_sync_and_do(op
, error
, ^bool(xpc_object_t message
, CFErrorRef
*error
) {
388 xpc_object_t xData
= _CFXPCCreateXPCObjectFromCFObject(data
);
389 bool success
= false;
391 xpc_dictionary_set_value(message
, kSecXPCKeyKeybag
, xData
);
395 xpc_dictionary_set_bool(message
, kSecXPCKeyIncludeV0
, include
);
397 }, ^bool(xpc_object_t response
, __unused CFErrorRef
*error
) {
398 return xpc_dictionary_get_bool(response
, kSecXPCKeyResult
);
403 static bool info_array_to_bool_error_request(enum SecXPCOperation op
, CFArrayRef peer_infos
, CFErrorRef
* error
)
405 __block
bool result
= false;
407 secdebug("sosops", "enter - operation: %d", op
);
408 securityd_send_sync_and_do(op
, error
, ^bool(xpc_object_t message
, CFErrorRef
*error
) {
409 xpc_object_t encoded_peers
= CreateXPCObjectWithArrayOfPeerInfo(peer_infos
, error
);
411 xpc_dictionary_set_value(message
, kSecXPCKeyPeerInfos
, encoded_peers
);
412 return encoded_peers
!= NULL
;
413 }, ^bool(xpc_object_t response
, __unused CFErrorRef
*error
) {
414 result
= xpc_dictionary_get_bool(response
, kSecXPCKeyResult
);
420 static bool uint64_t_to_bool_error_request(enum SecXPCOperation op
,
424 __block
bool result
= false;
426 securityd_send_sync_and_do(op
, error
, ^bool(xpc_object_t message
, CFErrorRef
*error
) {
427 xpc_dictionary_set_uint64(message
, kSecXPCLimitInMinutes
, number
);
429 }, ^bool(xpc_object_t response
, __unused CFErrorRef
*error
) {
430 result
= xpc_dictionary_get_bool(response
, kSecXPCKeyResult
);
437 static bool cfstring_and_cfdata_to_cfdata_cfdata_error_request(enum SecXPCOperation op
, CFStringRef viewName
, CFDataRef input
, CFDataRef
* data
, CFDataRef
* data2
, CFErrorRef
* error
) {
438 secdebug("sosops", "enter - operation: %d", op
);
439 __block
bool result
= false;
440 securityd_send_sync_and_do(op
, error
, ^bool(xpc_object_t message
, CFErrorRef
*error
) {
441 xpc_object_t xviewname
= _CFXPCCreateXPCObjectFromCFObject(viewName
);
442 xpc_object_t xinput
= _CFXPCCreateXPCObjectFromCFObject(input
);
443 bool success
= false;
444 if (xviewname
&& xinput
){
445 xpc_dictionary_set_value(message
, kSecXPCKeyViewName
, xviewname
);
446 xpc_dictionary_set_value(message
, kSecXPCData
, xinput
);
448 xpc_release(xviewname
);
452 }, ^bool(xpc_object_t response
, __unused CFErrorRef
*error
) {
453 result
= xpc_dictionary_get_bool(response
, kSecXPCKeyResult
);
455 xpc_object_t temp_result
= xpc_dictionary_get_value(response
, kSecXPCData
);
456 if (response
&& (NULL
!= temp_result
) && data
) {
457 *data
= _CFXPCCreateCFObjectFromXPCObject(temp_result
);
459 temp_result
= xpc_dictionary_get_value(response
, kSecXPCKeyKeybag
);
460 if (response
&& (NULL
!= temp_result
) && data2
) {
461 *data2
= _CFXPCCreateCFObjectFromXPCObject(temp_result
);
467 if (data
&&!isData(*data
)) {
468 SOSErrorCreate(kSOSErrorUnexpectedType
, error
, NULL
, CFSTR("Expected CFData, got: %@"), *data
);
470 if (data2
&&!isData(*data2
)) {
471 SOSErrorCreate(kSOSErrorUnexpectedType
, error
, NULL
, CFSTR("Expected CFData, got: %@"), *data2
);
477 static bool set_hsa2_autoaccept_error_request(enum SecXPCOperation op
, CFDataRef pubKey
, CFErrorRef
*error
)
479 __block
bool result
= false;
481 sec_trace_enter_api(NULL
);
482 securityd_send_sync_and_do(op
, error
, ^(xpc_object_t message
,
484 xpc_object_t xpubkey
= _CFXPCCreateXPCObjectFromCFObject(pubKey
);
485 bool success
= false;
487 xpc_dictionary_set_value(message
,
488 kSecXPCKeyHSA2AutoAcceptInfo
, xpubkey
);
490 xpc_release(xpubkey
);
494 }, ^(xpc_object_t response
, __unused CFErrorRef
*error
) {
495 result
= xpc_dictionary_get_bool(response
, kSecXPCKeyResult
);
504 static bool cfdata_error_request_returns_bool(enum SecXPCOperation op
, CFDataRef thedata
, CFErrorRef
*error
) {
505 __block
bool result
= false;
507 sec_trace_enter_api(NULL
);
508 securityd_send_sync_and_do(op
, error
, ^(xpc_object_t message
, CFErrorRef
*error
) {
509 xpc_object_t xdata
= _CFXPCCreateXPCObjectFromCFObject(thedata
);
510 bool success
= false;
512 xpc_dictionary_set_value(message
, kSecXPCData
, xdata
);
518 }, ^(xpc_object_t response
, __unused CFErrorRef
*error
) {
519 result
= xpc_dictionary_get_bool(response
, kSecXPCKeyResult
);
527 static CFDataRef
cfdata_error_request_returns_cfdata(enum SecXPCOperation op
, CFDataRef thedata
, CFErrorRef
*error
) {
528 __block CFDataRef result
= NULL
;
530 sec_trace_enter_api(NULL
);
531 securityd_send_sync_and_do(op
, error
, ^(xpc_object_t message
, CFErrorRef
*error
) {
532 xpc_object_t xdata
= _CFXPCCreateXPCObjectFromCFObject(thedata
);
533 bool success
= false;
535 xpc_dictionary_set_value(message
, kSecXPCData
, xdata
);
540 }, ^(xpc_object_t response
, __unused CFErrorRef
*error
) {
541 xpc_object_t temp_result
= xpc_dictionary_get_value(response
, kSecXPCKeyResult
);
542 if (response
&& (NULL
!= temp_result
)) {
543 CFTypeRef object
= _CFXPCCreateCFObjectFromXPCObject(temp_result
);
544 result
= asData(object
, error
);
546 CFReleaseNull(object
);
549 return (bool) (result
!= NULL
);
556 bool SOSCCRequestToJoinCircle(CFErrorRef
* error
)
558 sec_trace_enter_api(NULL
);
559 sec_trace_return_bool_api(^{
560 do_if_registered(soscc_RequestToJoinCircle
, error
);
562 return simple_bool_error_request(kSecXPCOpRequestToJoin
, error
);
566 bool SOSCCRequestToJoinCircleAfterRestore(CFErrorRef
* error
)
568 sec_trace_enter_api(NULL
);
569 sec_trace_return_bool_api(^{
570 do_if_registered(soscc_RequestToJoinCircleAfterRestore
, error
);
572 return simple_bool_error_request(kSecXPCOpRequestToJoinAfterRestore
, error
);
576 bool SOSCCAccountHasPublicKey(CFErrorRef
*error
)
579 sec_trace_enter_api(NULL
);
580 sec_trace_return_bool_api(^{
581 do_if_registered(soscc_AccountHasPublicKey
, error
);
583 return simple_bool_error_request(kSecXPCOpAccountHasPublicKey
, error
);
588 bool SOSCCAccountIsNew(CFErrorRef
*error
)
590 sec_trace_enter_api(NULL
);
591 sec_trace_return_bool_api(^{
592 do_if_registered(soscc_AccountIsNew
, error
);
594 return simple_bool_error_request(kSecXPCOpAccountIsNew
, error
);
598 bool SOSCCWaitForInitialSync(CFErrorRef
* error
)
600 sec_trace_enter_api(NULL
);
601 sec_trace_return_bool_api(^{
602 do_if_registered(soscc_WaitForInitialSync
, error
);
604 return simple_bool_error_request(kSecXPCOpWaitForInitialSync
, error
);
608 CFArrayRef
SOSCCCopyYetToSyncViewsList(CFErrorRef
* error
)
610 sec_trace_enter_api(NULL
);
611 sec_trace_return_api(CFArrayRef
, ^{
612 do_if_registered(soscc_CopyYetToSyncViewsList
, error
);
614 return simple_array_error_request(kSecXPCOpCopyYetToSyncViews
, error
);
618 bool SOSCCRequestEnsureFreshParameters(CFErrorRef
* error
)
620 sec_trace_enter_api(NULL
);
621 sec_trace_return_bool_api(^{
622 do_if_registered(soscc_RequestEnsureFreshParameters
, error
);
624 return simple_bool_error_request(kSecXPCOpRequestEnsureFreshParameters
, error
);
628 CFStringRef
SOSCCGetAllTheRings(CFErrorRef
*error
){
629 sec_trace_enter_api(NULL
);
630 sec_trace_return_api(CFStringRef
, ^{
631 do_if_registered(soscc_GetAllTheRings
, error
);
634 return simple_cfstring_error_request(kSecXPCOpGetAllTheRings
, error
);
637 bool SOSCCApplyToARing(CFStringRef ringName
, CFErrorRef
* error
)
639 sec_trace_enter_api(NULL
);
640 sec_trace_return_bool_api(^{
641 do_if_registered(soscc_ApplyToARing
, ringName
, error
);
643 return cfstring_to_error_request(kSecXPCOpApplyToARing
, ringName
, error
);
647 bool SOSCCWithdrawlFromARing(CFStringRef ringName
, CFErrorRef
* error
)
649 sec_trace_enter_api(NULL
);
650 sec_trace_return_bool_api(^{
651 do_if_registered(soscc_WithdrawlFromARing
, ringName
, error
);
653 return cfstring_to_error_request(kSecXPCOpWithdrawlFromARing
, ringName
, error
);
657 SOSRingStatus
SOSCCRingStatus(CFStringRef ringName
, CFErrorRef
* error
)
659 sec_trace_enter_api(NULL
);
660 sec_trace_return_api(SOSRingStatus
, ^{
661 do_if_registered(soscc_RingStatus
, ringName
, error
);
663 return cfstring_to_uint64_request(kSecXPCOpRingStatus
, ringName
, error
);
664 }, CFSTR("SOSCCStatus=%d"))
667 bool SOSCCEnableRing(CFStringRef ringName
, CFErrorRef
* error
)
669 sec_trace_enter_api(NULL
);
670 sec_trace_return_bool_api(^{
671 do_if_registered(soscc_EnableRing
, ringName
, error
);
673 return cfstring_to_error_request(kSecXPCOpEnableRing
, ringName
, error
);
677 bool SOSCCAccountSetToNew(CFErrorRef
*error
)
679 secwarning("SOSCCAccountSetToNew called");
680 sec_trace_enter_api(NULL
);
681 sec_trace_return_bool_api(^{
682 do_if_registered(soscc_SetToNew
, error
);
683 return simple_bool_error_request(kSecXPCOpAccountSetToNew
, error
);
687 bool SOSCCResetToOffering(CFErrorRef
* error
)
689 secwarning("SOSCCResetToOffering called");
690 sec_trace_enter_api(NULL
);
691 sec_trace_return_bool_api(^{
692 do_if_registered(soscc_ResetToOffering
, error
);
694 return simple_bool_error_request(kSecXPCOpResetToOffering
, error
);
698 bool SOSCCResetToEmpty(CFErrorRef
* error
)
700 secwarning("SOSCCResetToEmpty called");
701 sec_trace_enter_api(NULL
);
702 sec_trace_return_bool_api(^{
703 do_if_registered(soscc_ResetToEmpty
, error
);
705 return simple_bool_error_request(kSecXPCOpResetToEmpty
, error
);
709 bool SOSCCRemovePeersFromCircle(CFArrayRef peers
, CFErrorRef
* error
)
711 sec_trace_enter_api(NULL
);
712 sec_trace_return_bool_api(^{
713 do_if_registered(soscc_RemovePeersFromCircle
, peers
, error
);
715 return info_array_to_bool_error_request(kSecXPCOpRemovePeersFromCircle
, peers
, error
);
719 bool SOSCCRemoveThisDeviceFromCircle(CFErrorRef
* error
)
721 sec_trace_enter_api(NULL
);
722 sec_trace_return_bool_api(^{
723 do_if_registered(soscc_RemoveThisDeviceFromCircle
, error
);
725 return simple_bool_error_request(kSecXPCOpRemoveThisDeviceFromCircle
, error
);
729 bool SOSCCLoggedOutOfAccount(CFErrorRef
* error
)
731 sec_trace_enter_api(NULL
);
732 sec_trace_return_bool_api(^{
733 do_if_registered(soscc_LoggedOutOfAccount
, error
);
735 return simple_bool_error_request(kSecXPCOpLoggedOutOfAccount
, error
);
739 bool SOSCCBailFromCircle_BestEffort(uint64_t limit_in_seconds
, CFErrorRef
* error
)
741 sec_trace_enter_api(NULL
);
742 sec_trace_return_bool_api(^{
743 do_if_registered(soscc_BailFromCircle
, limit_in_seconds
, error
);
745 return uint64_t_to_bool_error_request(kSecXPCOpBailFromCircle
, limit_in_seconds
, error
);
749 bool SOSCCSignedOut(bool immediate
, CFErrorRef
* error
)
751 uint64_t limit
= strtoul(optarg
, NULL
, 10);
754 return SOSCCRemoveThisDeviceFromCircle(error
);
756 return SOSCCBailFromCircle_BestEffort(limit
, error
);
760 CFArrayRef
SOSCCCopyPeerPeerInfo(CFErrorRef
* error
)
762 sec_trace_enter_api(NULL
);
763 sec_trace_return_api(CFArrayRef
, ^{
764 do_if_registered(soscc_CopyPeerInfo
, error
);
766 return array_of_info_error_request(kSecXPCOpCopyPeerPeerInfo
, error
);
767 }, CFSTR("return=%@"));
770 bool SOSCCSetAutoAcceptInfo(CFDataRef autoaccept
, CFErrorRef
*error
)
772 sec_trace_return_bool_api(^{
773 do_if_registered(soscc_SetHSA2AutoAcceptInfo
, autoaccept
, error
);
775 return set_hsa2_autoaccept_error_request(kSecXPCOpSetHSA2AutoAcceptInfo
, autoaccept
, error
);
779 CFArrayRef
SOSCCCopyConcurringPeerPeerInfo(CFErrorRef
* error
)
781 sec_trace_enter_api(NULL
);
782 sec_trace_return_api(CFArrayRef
, ^{
783 do_if_registered(soscc_CopyConcurringPeerInfo
, error
);
785 return array_of_info_error_request(kSecXPCOpCopyConcurringPeerPeerInfo
, error
);
786 }, CFSTR("return=%@"));
789 CFArrayRef
SOSCCCopyGenerationPeerInfo(CFErrorRef
* error
)
791 sec_trace_enter_api(NULL
);
792 sec_trace_return_api(CFArrayRef
, ^{
793 do_if_registered(soscc_CopyGenerationPeerInfo
, error
);
795 return simple_array_error_request(kSecXPCOpCopyGenerationPeerInfo
, error
);
796 }, CFSTR("return=%@"));
799 CFArrayRef
SOSCCCopyApplicantPeerInfo(CFErrorRef
* error
)
801 sec_trace_enter_api(NULL
);
802 sec_trace_return_api(CFArrayRef
, ^{
803 do_if_registered(soscc_CopyApplicantPeerInfo
, error
);
805 return array_of_info_error_request(kSecXPCOpCopyApplicantPeerInfo
, error
);
806 }, CFSTR("return=%@"));
809 bool SOSCCValidateUserPublic(CFErrorRef
* error
){
810 sec_trace_enter_api(NULL
);
811 sec_trace_return_api(bool, ^{
812 do_if_registered(soscc_ValidateUserPublic
, error
);
814 return simple_bool_error_request(kSecXPCOpValidateUserPublic
, error
);
818 CFArrayRef
SOSCCCopyValidPeerPeerInfo(CFErrorRef
* error
)
820 sec_trace_enter_api(NULL
);
821 sec_trace_return_api(CFArrayRef
, ^{
822 do_if_registered(soscc_CopyValidPeerPeerInfo
, error
);
824 return array_of_info_error_request(kSecXPCOpCopyValidPeerPeerInfo
, error
);
825 }, CFSTR("return=%@"));
828 CFArrayRef
SOSCCCopyNotValidPeerPeerInfo(CFErrorRef
* error
)
830 sec_trace_enter_api(NULL
);
831 sec_trace_return_api(CFArrayRef
, ^{
832 do_if_registered(soscc_CopyNotValidPeerPeerInfo
, error
);
834 return array_of_info_error_request(kSecXPCOpCopyNotValidPeerPeerInfo
, error
);
835 }, CFSTR("return=%@"));
838 CFArrayRef
SOSCCCopyRetirementPeerInfo(CFErrorRef
* error
)
840 sec_trace_enter_api(NULL
);
841 sec_trace_return_api(CFArrayRef
, ^{
842 do_if_registered(soscc_CopyRetirementPeerInfo
, error
);
844 return array_of_info_error_request(kSecXPCOpCopyRetirementPeerInfo
, error
);
845 }, CFSTR("return=%@"));
848 CFArrayRef
SOSCCCopyViewUnawarePeerInfo(CFErrorRef
* error
)
850 sec_trace_enter_api(NULL
);
851 sec_trace_return_api(CFArrayRef
, ^{
852 do_if_registered(soscc_CopyViewUnawarePeerInfo
, error
);
854 return array_of_info_error_request(kSecXPCOpCopyViewUnawarePeerInfo
, error
);
855 }, CFSTR("return=%@"));
858 CFDataRef
SOSCCCopyAccountState(CFErrorRef
* error
)
860 sec_trace_enter_api(NULL
);
861 sec_trace_return_api(CFDataRef
, ^{
862 do_if_registered(soscc_CopyAccountState
, error
);
864 return data_to_error_request(kSecXPCOpCopyAccountData
, error
);
865 }, CFSTR("return=%@"));
868 bool SOSCCDeleteAccountState(CFErrorRef
*error
)
870 sec_trace_enter_api(NULL
);
871 sec_trace_return_api(bool, ^{
872 do_if_registered(soscc_DeleteAccountState
, error
);
873 return simple_bool_error_request(kSecXPCOpDeleteAccountData
, error
);
876 CFDataRef
SOSCCCopyEngineData(CFErrorRef
* error
)
878 sec_trace_enter_api(NULL
);
879 sec_trace_return_api(CFDataRef
, ^{
880 do_if_registered(soscc_CopyEngineData
, error
);
882 return data_to_error_request(kSecXPCOpCopyEngineData
, error
);
883 }, CFSTR("return=%@"));
886 bool SOSCCDeleteEngineState(CFErrorRef
*error
)
888 sec_trace_enter_api(NULL
);
889 sec_trace_return_api(bool, ^{
890 do_if_registered(soscc_DeleteEngineState
, error
);
891 return simple_bool_error_request(kSecXPCOpDeleteEngineData
, error
);
895 SOSPeerInfoRef
SOSCCCopyMyPeerInfo(CFErrorRef
*error
)
897 sec_trace_enter_api(NULL
);
898 sec_trace_return_api(SOSPeerInfoRef
, ^{
899 do_if_registered(soscc_CopyMyPeerInfo
, error
);
901 return peer_info_error_request(kSecXPCOpCopyMyPeerInfo
, error
);
902 }, CFSTR("return=%@"));
905 CFArrayRef
SOSCCCopyEngineState(CFErrorRef
* error
)
907 sec_trace_enter_api(NULL
);
908 sec_trace_return_api(CFArrayRef
, ^{
909 do_if_registered(soscc_CopyEngineState
, error
);
911 return simple_array_error_request(kSecXPCOpCopyEngineState
, error
);
912 }, CFSTR("return=%@"));
915 bool SOSCCAcceptApplicants(CFArrayRef applicants
, CFErrorRef
* error
)
917 sec_trace_enter_api(NULL
);
918 sec_trace_return_bool_api(^{
919 do_if_registered(soscc_AcceptApplicants
, applicants
, error
);
921 return info_array_to_bool_error_request(kSecXPCOpAcceptApplicants
, applicants
, error
);
925 bool SOSCCRejectApplicants(CFArrayRef applicants
, CFErrorRef
*error
)
927 sec_trace_enter_api(CFSTR("applicants=%@"), applicants
);
928 sec_trace_return_bool_api(^{
929 do_if_registered(soscc_RejectApplicants
, applicants
, error
);
931 return info_array_to_bool_error_request(kSecXPCOpRejectApplicants
, applicants
, error
);
935 static SOSPeerInfoRef
SOSSetNewPublicBackupKey(CFDataRef pubKey
, CFErrorRef
*error
)
937 sec_trace_enter_api(NULL
);
938 sec_trace_return_api(SOSPeerInfoRef
, ^{
939 do_if_registered(soscc_SetNewPublicBackupKey
, pubKey
, error
);
941 return data_to_peer_info_error_request(kSecXPCOpSetNewPublicBackupKey
, pubKey
, error
);
942 }, CFSTR("return=%@"));
945 SOSPeerInfoRef
SOSCCCopyMyPeerWithNewDeviceRecoverySecret(CFDataRef secret
, CFErrorRef
*error
){
946 CFDataRef publicKeyData
= SOSCopyDeviceBackupPublicKey(secret
, error
);
948 return publicKeyData
? SOSSetNewPublicBackupKey(publicKeyData
, error
) : NULL
;
951 bool SOSCCRegisterSingleRecoverySecret(CFDataRef aks_bag
, bool forV0Only
, CFErrorRef
*error
){
952 sec_trace_enter_api(NULL
);
953 sec_trace_return_bool_api(^{
954 do_if_registered(soscc_RegisterSingleRecoverySecret
, aks_bag
, forV0Only
, error
);
955 return keybag_and_bool_to_bool_error_request(kSecXPCOpSetBagForAllSlices
, aks_bag
, forV0Only
, error
);
960 static bool label_and_password_to_bool_error_request(enum SecXPCOperation op
,
961 CFStringRef user_label
, CFDataRef user_password
,
964 __block
bool result
= false;
966 securityd_send_sync_and_do(op
, error
, ^bool(xpc_object_t message
, CFErrorRef
*error
) {
967 CFStringPerformWithCString(user_label
, ^(const char *utf8Str
) {
968 xpc_dictionary_set_string(message
, kSecXPCKeyUserLabel
, utf8Str
);
970 xpc_dictionary_set_data(message
, kSecXPCKeyUserPassword
, CFDataGetBytePtr(user_password
), CFDataGetLength(user_password
));
972 }, ^bool(xpc_object_t response
, __unused CFErrorRef
*error
) {
973 result
= xpc_dictionary_get_bool(response
, kSecXPCKeyResult
);
980 static bool label_and_password_and_dsid_to_bool_error_request(enum SecXPCOperation op
,
981 CFStringRef user_label
, CFDataRef user_password
,
982 CFStringRef dsid
, CFErrorRef
* error
)
984 __block
bool result
= false;
986 securityd_send_sync_and_do(op
, error
, ^bool(xpc_object_t message
, CFErrorRef
*error
) {
987 CFStringPerformWithCString(user_label
, ^(const char *utf8Str
) {
988 xpc_dictionary_set_string(message
, kSecXPCKeyUserLabel
, utf8Str
);
990 CFStringPerformWithCString(dsid
, ^(const char *utr8StrDSID
) {
991 xpc_dictionary_set_string(message
, kSecXPCKeyDSID
, utr8StrDSID
);
993 xpc_dictionary_set_data(message
, kSecXPCKeyUserPassword
, CFDataGetBytePtr(user_password
), CFDataGetLength(user_password
));
995 }, ^bool(xpc_object_t response
, __unused CFErrorRef
*error
) {
996 result
= xpc_dictionary_get_bool(response
, kSecXPCKeyResult
);
1003 static bool deviceid_to_bool_error_request(enum SecXPCOperation op
,
1007 __block
bool result
= false;
1009 securityd_send_sync_and_do(op
, error
, ^bool(xpc_object_t message
, CFErrorRef
*error
) {
1010 CFStringPerformWithCString(IDS
, ^(const char *utf8Str
) {
1011 xpc_dictionary_set_string(message
, kSecXPCKeyDeviceID
, utf8Str
);
1014 }, ^bool(xpc_object_t response
, CFErrorRef
*error
) {
1015 result
= xpc_dictionary_get_bool(response
, kSecXPCKeyResult
);
1022 static int idsDict_to_int_error_request(enum SecXPCOperation op
,
1023 CFDictionaryRef IDS
,
1026 __block
int result
= 0;
1028 securityd_send_sync_and_do(op
, error
, ^bool(xpc_object_t message
, CFErrorRef
*error
) {
1029 SecXPCDictionarySetPListOptional(message
, kSecXPCKeyIDSMessage
, IDS
, error
);
1031 }, ^bool(xpc_object_t response
, __unused CFErrorRef
*error
) {
1032 int64_t temp_result
= xpc_dictionary_get_int64(response
, kSecXPCKeyResult
);
1033 if ((temp_result
>= INT32_MIN
) && (temp_result
<= INT32_MAX
)) {
1034 result
= (int)temp_result
;
1042 static bool idscommand_to_bool_error_request(enum SecXPCOperation op
,
1043 CFStringRef idsMessage
,
1046 __block
bool result
= false;
1048 securityd_send_sync_and_do(op
, error
, ^bool(xpc_object_t message
, CFErrorRef
*error
) {
1049 CFStringPerformWithCString(idsMessage
, ^(const char *utf8Str
) {
1050 xpc_dictionary_set_string(message
, kSecXPCKeySendIDSMessage
, utf8Str
);
1053 }, ^bool(xpc_object_t response
, __unused CFErrorRef
*error
) {
1054 result
= xpc_dictionary_get_bool(response
, kSecXPCKeyResult
);
1061 bool SOSCCRegisterUserCredentials(CFStringRef user_label
, CFDataRef user_password
, CFErrorRef
* error
)
1063 secnotice("sosops", "SOSCCRegisterUserCredentials - calling SOSCCSetUserCredentials!! %@\n", user_label
);
1064 return SOSCCSetUserCredentials(user_label
, user_password
, error
);
1067 bool SOSCCSetUserCredentials(CFStringRef user_label
, CFDataRef user_password
, CFErrorRef
* error
)
1069 secnotice("sosops", "SOSCCSetUserCredentials!! %@\n", user_label
);
1070 sec_trace_enter_api(CFSTR("user_label=%@"), user_label
);
1071 sec_trace_return_bool_api(^{
1072 do_if_registered(soscc_SetUserCredentials
, user_label
, user_password
, error
);
1074 return label_and_password_to_bool_error_request(kSecXPCOpSetUserCredentials
, user_label
, user_password
, error
);
1078 bool SOSCCSetUserCredentialsAndDSID(CFStringRef user_label
, CFDataRef user_password
, CFStringRef dsid
, CFErrorRef
*error
)
1080 secnotice("sosops", "SOSCCSetUserCredentialsAndDSID!! %@\n", user_label
);
1081 sec_trace_enter_api(CFSTR("user_label=%@"), user_label
);
1082 sec_trace_return_bool_api(^{
1083 do_if_registered(soscc_SetUserCredentialsAndDSID
, user_label
, user_password
, dsid
, error
);
1085 return label_and_password_and_dsid_to_bool_error_request(kSecXPCOpSetUserCredentialsAndDSID
, user_label
, user_password
, CFSTR(""), error
);
1088 return label_and_password_and_dsid_to_bool_error_request(kSecXPCOpSetUserCredentialsAndDSID
, user_label
, user_password
, dsid
, error
);
1093 bool SOSCCSetDeviceID(CFStringRef IDS
, CFErrorRef
* error
)
1095 secnotice("sosops", "SOSCCSetDeviceID!! %@\n", IDS
);
1096 sec_trace_enter_api(NULL
);
1097 sec_trace_return_bool_api(^{
1098 do_if_registered(soscc_SetDeviceID
, IDS
, error
);
1099 bool result
= deviceid_to_bool_error_request(kSecXPCOpSetDeviceID
, IDS
, error
);
1104 bool SOSCCIDSServiceRegistrationTest(CFStringRef message
, CFErrorRef
*error
)
1106 secnotice("sosops", "SOSCCSendIDSTestMessage!! %@\n", message
);
1107 sec_trace_enter_api(NULL
);
1108 sec_trace_return_bool_api(^{
1109 do_if_registered(soscc_CheckIDSRegistration
, message
, error
);
1110 return idscommand_to_bool_error_request(kSecXPCOpSendIDSMessage
, message
, error
);
1114 bool SOSCCIDSPingTest(CFStringRef message
, CFErrorRef
*error
)
1116 secnotice("sosops", "SOSCCSendIDSTestMessage!! %@\n", message
);
1117 sec_trace_enter_api(NULL
);
1118 sec_trace_return_bool_api(^{
1119 do_if_registered(soscc_PingTest
, message
, error
);
1120 return idscommand_to_bool_error_request(kSecXPCOpPingTest
, message
, error
);
1124 bool SOSCCIDSDeviceIDIsAvailableTest(CFErrorRef
*error
)
1126 secnotice("sosops", "SOSCCIDSDeviceIDIsAvailableTest!!\n");
1127 sec_trace_enter_api(NULL
);
1128 sec_trace_return_bool_api(^{
1129 do_if_registered(soscc_GetIDSIDFromIDS
, error
);
1130 return simple_bool_error_request(kSecXPCOpIDSDeviceID
, error
);
1134 HandleIDSMessageReason
SOSCCHandleIDSMessage(CFDictionaryRef IDS
, CFErrorRef
* error
)
1136 secnotice("sosops", "SOSCCHandleIDSMessage!! %@\n", IDS
);
1137 sec_trace_enter_api(NULL
);
1138 sec_trace_return_api(HandleIDSMessageReason
, ^{
1139 do_if_registered(soscc_HandleIDSMessage
, IDS
, error
);
1140 return (HandleIDSMessageReason
) idsDict_to_int_error_request(kSecXPCOpHandleIDSMessage
, IDS
, error
);
1144 bool SOSCCRequestSyncWithPeerOverKVS(CFStringRef peerID
, CFErrorRef
*error
)
1146 secnotice("sosops", "SOSCCRequestSyncWithPeerOverKVS!! %@\n", peerID
);
1147 sec_trace_enter_api(NULL
);
1148 sec_trace_return_bool_api(^{
1149 do_if_registered(soscc_requestSyncWithPeerOverKVS
, peerID
, error
);
1150 return deviceid_to_bool_error_request(kSecXPCOpSyncWithKVSPeer
, peerID
, error
);
1154 bool SOSCCRequestSyncWithPeerOverIDS(CFStringRef deviceID
, CFErrorRef
*error
)
1156 secnotice("sosops", "SOSCCRequestSyncWithPeerOverIDS!! %@\n", deviceID
);
1157 sec_trace_enter_api(NULL
);
1158 sec_trace_return_bool_api(^{
1159 do_if_registered(soscc_requestSyncWithPeerOverIDS
, deviceID
, error
);
1160 return deviceid_to_bool_error_request(kSecXPCOpSyncWithIDSPeer
, deviceID
, error
);
1164 bool SOSCCTryUserCredentials(CFStringRef user_label
, CFDataRef user_password
, CFErrorRef
* error
)
1166 sec_trace_enter_api(CFSTR("user_label=%@"), user_label
);
1167 sec_trace_return_bool_api(^{
1168 do_if_registered(soscc_TryUserCredentials
, user_label
, user_password
, error
);
1170 return label_and_password_to_bool_error_request(kSecXPCOpTryUserCredentials
, user_label
, user_password
, error
);
1175 bool SOSCCCanAuthenticate(CFErrorRef
* error
) {
1176 sec_trace_enter_api(NULL
);
1177 sec_trace_return_bool_api(^{
1178 do_if_registered(soscc_CanAuthenticate
, error
);
1180 return simple_bool_error_request(kSecXPCOpCanAuthenticate
, error
);
1184 bool SOSCCPurgeUserCredentials(CFErrorRef
* error
) {
1185 sec_trace_enter_api(NULL
);
1186 sec_trace_return_bool_api(^{
1187 do_if_registered(soscc_PurgeUserCredentials
, error
);
1189 return simple_bool_error_request(kSecXPCOpPurgeUserCredentials
, error
);
1193 enum DepartureReason
SOSCCGetLastDepartureReason(CFErrorRef
*error
) {
1194 sec_trace_enter_api(NULL
);
1195 sec_trace_return_api(enum DepartureReason
, ^{
1196 do_if_registered(soscc_GetLastDepartureReason
, error
);
1198 return (enum DepartureReason
) simple_int_error_request(kSecXPCOpGetLastDepartureReason
, error
);
1202 bool SOSCCSetLastDepartureReason(enum DepartureReason reason
, CFErrorRef
*error
) {
1203 sec_trace_enter_api(NULL
);
1204 sec_trace_return_api(bool, ^{
1205 do_if_registered(soscc_SetLastDepartureReason
, reason
, error
);
1206 return securityd_send_sync_and_do(kSecXPCOpSetLastDepartureReason
, error
,
1207 ^bool(xpc_object_t message
, CFErrorRef
*error
) {
1208 xpc_dictionary_set_int64(message
, kSecXPCKeyReason
, reason
);
1211 ^bool(xpc_object_t response
, __unused CFErrorRef
*error
) {
1212 return xpc_dictionary_get_bool(response
, kSecXPCKeyResult
);
1218 CFStringRef
SOSCCCopyIncompatibilityInfo(CFErrorRef
* error
) {
1219 sec_trace_enter_api(NULL
);
1220 sec_trace_return_api(CFStringRef
, ^{
1221 do_if_registered(soscc_CopyIncompatibilityInfo
, error
);
1223 return simple_cfstring_error_request(kSecXPCOpCopyIncompatibilityInfo
, error
);
1227 CFStringRef
SOSCCCopyDeviceID(CFErrorRef
* error
)
1229 sec_trace_enter_api(NULL
);
1230 sec_trace_return_api(CFStringRef
, ^{
1231 do_if_registered(soscc_CopyDeviceID
, error
);
1232 CFStringRef deviceID
= simple_cfstring_error_request(kSecXPCOpRequestDeviceID
, error
);
1237 bool SOSCCProcessEnsurePeerRegistration(CFErrorRef
* error
){
1238 secnotice("updates", "enter SOSCCProcessEnsurePeerRegistration");
1239 sec_trace_enter_api(NULL
);
1240 sec_trace_return_bool_api(^{
1241 do_if_registered(soscc_EnsurePeerRegistration
, error
);
1243 return simple_bool_error_request(soscc_EnsurePeerRegistration_id
, error
);
1248 SyncWithAllPeersReason
SOSCCProcessSyncWithAllPeers(CFErrorRef
* error
)
1250 sec_trace_enter_api(NULL
);
1251 sec_trace_return_api(SyncWithAllPeersReason
, ^{
1252 do_if_registered(soscc_ProcessSyncWithAllPeers
, error
);
1254 return (SyncWithAllPeersReason
) simple_int_error_request(kSecXPCOpProcessSyncWithAllPeers
, error
);
1258 CFStringRef
SOSCCGetStatusDescription(SOSCCStatus status
)
1261 case kSOSCCInCircle
:
1262 return CFSTR("InCircle");
1263 case kSOSCCNotInCircle
:
1264 return CFSTR("NotInCircle");
1265 case kSOSCCRequestPending
:
1266 return CFSTR("RequestPending");
1267 case kSOSCCCircleAbsent
:
1268 return CFSTR("CircleAbsent");
1270 return CFSTR("InternalError");
1272 return CFSTR("Unknown Status (%d)");
1277 kSOSCCGeneralViewError
= -1,
1278 kSOSCCViewMember
= 0,
1279 kSOSCCViewNotMember
= 1,
1280 kSOSCCViewNotQualified
= 2,
1281 kSOSCCNoSuchView
= 3,
1284 static int64_t name_action_to_code_request(enum SecXPCOperation op
, uint16_t error_result
,
1285 CFStringRef name
, uint64_t action
, CFErrorRef
*error
) {
1286 __block
int64_t result
= error_result
;
1288 securityd_send_sync_and_do(op
, error
, ^bool(xpc_object_t message
, CFErrorRef
*error
) {
1289 CFStringPerformWithCString(name
, ^(const char *utf8Str
) {
1290 xpc_dictionary_set_string(message
, kSecXPCKeyViewName
, utf8Str
);
1292 xpc_dictionary_set_int64(message
, kSecXPCKeyViewActionCode
, action
);
1294 }, ^bool(xpc_object_t response
, __unused CFErrorRef
*error
) {
1295 if (response
&& xpc_dictionary_entry_is_type(response
, kSecXPCKeyResult
, XPC_TYPE_INT64
)) {
1296 result
= xpc_dictionary_get_int64(response
, kSecXPCKeyResult
);
1298 return result
!= error_result
;
1304 SOSViewResultCode
SOSCCView(CFStringRef view
, SOSViewActionCode actionCode
, CFErrorRef
*error
) {
1305 sec_trace_enter_api(NULL
);
1306 sec_trace_return_api(SOSViewResultCode
, ^{
1307 do_if_registered(soscc_View
, view
, actionCode
, error
);
1309 return (SOSViewResultCode
) name_action_to_code_request(kSecXPCOpView
, kSOSCCGeneralViewError
, view
, actionCode
, error
);
1310 }, CFSTR("SOSViewResultCode=%d"))
1314 bool SOSCCViewSet(CFSetRef enabledViews
, CFSetRef disabledViews
) {
1315 CFErrorRef
*error
= NULL
;
1316 __block
bool result
= false;
1318 sec_trace_enter_api(NULL
);
1319 sec_trace_return_bool_api(^{
1320 do_if_registered(soscc_ViewSet
, enabledViews
, disabledViews
);
1321 return securityd_send_sync_and_do(kSecXPCOpViewSet
, error
, ^bool(xpc_object_t message
, CFErrorRef
*error
) {
1322 xpc_object_t enabledSetXpc
= CreateXPCObjectWithCFSetRef(enabledViews
, error
);
1323 xpc_object_t disabledSetXpc
= CreateXPCObjectWithCFSetRef(disabledViews
, error
);
1324 if (enabledSetXpc
) xpc_dictionary_set_value(message
, kSecXPCKeyEnabledViewsKey
, enabledSetXpc
);
1325 if (disabledSetXpc
) xpc_dictionary_set_value(message
, kSecXPCKeyDisabledViewsKey
, disabledSetXpc
);
1326 return (enabledSetXpc
!= NULL
) || (disabledSetXpc
!= NULL
) ;
1327 }, ^bool(xpc_object_t response
, __unused CFErrorRef
*error
) {
1328 result
= xpc_dictionary_get_bool(response
, kSecXPCKeyResult
);
1334 SOSSecurityPropertyResultCode
SOSCCSecurityProperty(CFStringRef property
, SOSSecurityPropertyActionCode actionCode
, CFErrorRef
*error
) {
1335 sec_trace_enter_api(NULL
);
1336 sec_trace_return_api(SOSSecurityPropertyResultCode
, ^{
1337 SOSSecurityPropertyResultCode result
= kSOSCCGeneralSecurityPropertyError
;
1338 do_if_registered(soscc_SecurityProperty
, property
, actionCode
, error
);
1339 xpc_object_t message
= securityd_create_message(kSecXPCOpSecurityProperty
, error
);
1341 int64_t bigac
= actionCode
;
1342 xpc_dictionary_set_string(message
, kSecXPCKeyViewName
, CFStringGetCStringPtr(property
, kCFStringEncodingUTF8
));
1343 xpc_dictionary_set_int64(message
, kSecXPCKeyViewActionCode
, bigac
);
1345 xpc_object_t response
= securityd_message_with_reply_sync(message
, error
);
1347 if (response
&& xpc_dictionary_entry_is_type(response
, kSecXPCKeyResult
, XPC_TYPE_INT64
)) {
1348 result
= (SOSSecurityPropertyResultCode
) xpc_dictionary_get_int64(response
, kSecXPCKeyResult
);
1351 if (result
== kSOSCCGeneralSecurityPropertyError
) {
1352 if (response
&& securityd_message_no_error(response
, error
)) {
1353 char *desc
= xpc_copy_description(response
);
1354 SecCFCreateErrorWithFormat(0, sSecXPCErrorDomain
, NULL
, error
, NULL
, CFSTR("Remote error occurred/no info: %s"), desc
);
1359 xpc_release(response
);
1361 xpc_release(message
);
1365 }, CFSTR("SOSSecurityPropertyResultCode=%d"))
1369 static bool sosIsViewSetSyncing(size_t n
, CFStringRef
*views
) {
1370 __block
bool retval
= true;
1372 SOSCCStatus cstatus
= SOSCCThisDeviceIsInCircle(NULL
);
1373 if(cstatus
== kSOSCCInCircle
) {
1374 for(size_t i
= 0; i
< n
; i
++) {
1375 SOSViewResultCode vstatus
= SOSCCView(views
[i
], kSOSCCViewQuery
, NULL
);
1376 if(vstatus
!= kSOSCCViewMember
) retval
= false;
1384 bool SOSCCIsIcloudKeychainSyncing(void) {
1385 CFStringRef views
[] = { kSOSViewWiFi
, kSOSViewAutofillPasswords
, kSOSViewSafariCreditCards
, kSOSViewOtherSyncable
};
1386 return sosIsViewSetSyncing(sizeof(views
)/sizeof(views
[0]), views
);
1389 bool SOSCCIsSafariSyncing(void) {
1390 CFStringRef views
[] = { kSOSViewAutofillPasswords
, kSOSViewSafariCreditCards
};
1391 return sosIsViewSetSyncing(sizeof(views
)/sizeof(views
[0]), views
);
1394 bool SOSCCIsAppleTVSyncing(void) {
1395 CFStringRef views
[] = { kSOSViewAppleTV
};
1396 return sosIsViewSetSyncing(sizeof(views
)/sizeof(views
[0]), views
);
1399 bool SOSCCIsHomeKitSyncing(void) {
1400 CFStringRef views
[] = { kSOSViewHomeKit
};
1401 return sosIsViewSetSyncing(sizeof(views
)/sizeof(views
[0]), views
);
1404 bool SOSCCIsWiFiSyncing(void) {
1405 CFStringRef views
[] = { kSOSViewWiFi
};
1406 return sosIsViewSetSyncing(sizeof(views
)/sizeof(views
[0]), views
);
1409 bool SOSCCIsContinuityUnlockSyncing(void) {
1410 CFStringRef views
[] = { kSOSViewContinuityUnlock
};
1411 return sosIsViewSetSyncing(sizeof(views
)/sizeof(views
[0]), views
);
1415 bool SOSCCSetEscrowRecord(CFStringRef escrow_label
, uint64_t tries
, CFErrorRef
*error
){
1416 secnotice("escrow", "enter SOSCCSetEscrowRecord");
1417 sec_trace_enter_api(NULL
);
1418 sec_trace_return_bool_api(^{
1419 do_if_registered(soscc_SetEscrowRecords
, escrow_label
, tries
, error
);
1421 return escrow_to_bool_error_request(kSecXPCOpSetEscrowRecord
, escrow_label
, tries
, error
);
1425 CFDictionaryRef
SOSCCCopyEscrowRecord(CFErrorRef
*error
){
1426 secnotice("escrow", "enter SOSCCCopyEscrowRecord");
1427 sec_trace_enter_api(NULL
);
1428 sec_trace_return_api(CFDictionaryRef
, ^{
1429 do_if_registered(soscc_CopyEscrowRecords
, error
);
1431 return strings_to_dictionary_error_request(kSecXPCOpGetEscrowRecord
, error
);
1432 }, CFSTR("return=%@"))
1436 bool SOSCCCheckPeerAvailability(CFErrorRef
*error
){
1437 secnotice("peer", "enter SOSCCCheckPeerAvailability");
1438 sec_trace_enter_api(NULL
);
1439 sec_trace_return_bool_api(^{
1440 do_if_registered(soscc_PeerAvailability
, error
);
1442 return simple_bool_error_request(kSecXPCOpCheckPeerAvailability
, error
);
1448 bool SOSWrapToBackupSliceKeyBagForView(CFStringRef viewName
, CFDataRef input
, CFDataRef
* output
, CFDataRef
* bskbEncoded
, CFErrorRef
* error
) {
1449 sec_trace_enter_api(NULL
);
1450 sec_trace_return_bool_api(^{
1451 do_if_registered(sosbskb_WrapToBackupSliceKeyBagForView
, viewName
, input
, output
, bskbEncoded
, error
);
1453 return cfstring_and_cfdata_to_cfdata_cfdata_error_request(kSecXPCOpWrapToBackupSliceKeyBagForView
, viewName
, input
, output
, bskbEncoded
, error
);
1458 SOSPeerInfoRef
SOSCCCopyApplication(CFErrorRef
*error
) {
1459 secnotice("hsa2PB", "enter SOSCCCopyApplication applicant");
1460 sec_trace_enter_api(NULL
);
1462 sec_trace_return_api(SOSPeerInfoRef
, ^{
1463 do_if_registered(soscc_CopyApplicant
, error
);
1464 return peer_info_error_request(kSecXPCOpCopyApplication
, error
);
1465 }, CFSTR("return=%@"));
1468 CFDataRef
SOSCCCopyCircleJoiningBlob(SOSPeerInfoRef applicant
, CFErrorRef
*error
) {
1469 secnotice("hsa2PB", "enter SOSCCCopyCircleJoiningBlob approver");
1470 sec_trace_enter_api(NULL
);
1472 sec_trace_return_api(CFDataRef
, ^{
1473 CFDataRef result
= NULL
;
1474 do_if_registered(soscc_CopyCircleJoiningBlob
, applicant
, error
);
1475 CFDataRef piData
= SOSPeerInfoCopyEncodedData(applicant
, kCFAllocatorDefault
, error
);
1476 result
= cfdata_error_request_returns_cfdata(kSecXPCOpCopyCircleJoiningBlob
, piData
, error
);
1477 CFReleaseNull(piData
);
1479 }, CFSTR("return=%@"));
1482 bool SOSCCJoinWithCircleJoiningBlob(CFDataRef joiningBlob
, CFErrorRef
*error
) {
1483 secnotice("hsa2PB", "enter SOSCCJoinWithCircleJoiningBlob applicant");
1484 sec_trace_enter_api(NULL
);
1485 sec_trace_return_bool_api(^{
1486 do_if_registered(soscc_JoinWithCircleJoiningBlob
, joiningBlob
, error
);
1488 return cfdata_error_request_returns_bool(kSecXPCOpJoinWithCircleJoiningBlob
, joiningBlob
, error
);
1494 bool SOSCCIsThisDeviceLastBackup(CFErrorRef
*error
) {
1495 secnotice("peer", "enter SOSCCIsThisDeviceLastBackup");
1496 sec_trace_enter_api(NULL
);
1497 sec_trace_return_bool_api(^{
1498 do_if_registered(soscc_IsThisDeviceLastBackup
, error
);
1500 return simple_bool_error_request(kSecXPCOpIsThisDeviceLastBackup
, error
);
1504 CFBooleanRef
SOSCCPeersHaveViewsEnabled(CFArrayRef viewNames
, CFErrorRef
*error
) {
1505 secnotice("view-enabled", "enter SOSCCPeersHaveViewsEnabled");
1506 sec_trace_enter_api(NULL
);
1507 sec_trace_return_api(CFBooleanRef
, ^{
1508 do_if_registered(soscc_SOSCCPeersHaveViewsEnabled
, viewNames
, error
);
1510 return cfarray_to_cfboolean_error_request(kSecXPCOpPeersHaveViewsEnabled
, viewNames
, error
);
1511 }, CFSTR("return=%@"))