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 "SOSRegressionUtilities.h"
62 #include <Security/SecuritydXPC.h>
63 #include <SOSPeerInfoDER.h>
64 #include <SOSCloudKeychainClient.h>
66 const char * kSOSCCCircleChangedNotification
= "com.apple.security.secureobjectsync.circlechanged";
67 const char * kSOSCCViewMembershipChangedNotification
= "com.apple.security.secureobjectsync.viewschanged";
68 const char * kSOSCCInitialSyncChangedNotification
= "com.apple.security.secureobjectsync.initialsyncchanged";
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 CFArrayRef
simple_array_error_request(enum SecXPCOperation op
, CFErrorRef
* error
)
189 __block CFArrayRef result
= NULL
;
191 secdebug("sosops","enter - operation: %d", op
);
192 if (securityd_send_sync_and_do(op
, error
, NULL
, ^bool(xpc_object_t response
, CFErrorRef
*error
) {
193 xpc_object_t temp_result
= xpc_dictionary_get_value(response
, kSecXPCKeyResult
);
194 result
= _CFXPCCreateCFObjectFromXPCObject(temp_result
);
195 return result
!= NULL
;
197 if (!isArray(result
)) {
198 SOSErrorCreate(kSOSErrorUnexpectedType
, error
, NULL
, CFSTR("Expected array, got: %@"), result
);
199 CFReleaseNull(result
);
205 static int simple_int_error_request(enum SecXPCOperation op
, CFErrorRef
* error
)
207 __block
int result
= 0;
209 secdebug("sosops","enter - operation: %d", op
);
210 securityd_send_sync_and_do(op
, error
, NULL
, ^bool(xpc_object_t response
, __unused CFErrorRef
*error
) {
211 int64_t temp_result
= xpc_dictionary_get_int64(response
, kSecXPCKeyResult
);
212 if ((temp_result
>= INT32_MIN
) && (temp_result
<= INT32_MAX
)) {
213 result
= (int)temp_result
;
220 static SOSPeerInfoRef
peer_info_error_request(enum SecXPCOperation op
, CFErrorRef
* error
)
222 SOSPeerInfoRef result
= NULL
;
223 __block CFDataRef data
= NULL
;
225 secdebug("sosops","enter - operation: %d", op
);
226 securityd_send_sync_and_do(op
, error
, NULL
, ^bool(xpc_object_t response
, CFErrorRef
*error
) {
227 xpc_object_t temp_result
= xpc_dictionary_get_value(response
, kSecXPCKeyResult
);
228 if (response
&& (NULL
!= temp_result
)) {
229 data
= _CFXPCCreateCFObjectFromXPCObject(temp_result
);
235 SOSErrorCreate(kSOSErrorUnexpectedType
, error
, NULL
, CFSTR("Expected CFData, got: %@"), result
);
239 result
= SOSPeerInfoCreateFromData(kCFAllocatorDefault
, error
, data
);
245 static CFArrayRef
array_of_info_error_request(enum SecXPCOperation op
, CFErrorRef
* error
)
247 __block CFArrayRef result
= NULL
;
249 secdebug("sosops","enter - operation: %d", op
);
250 securityd_send_sync_and_do(op
, error
, NULL
, ^bool(xpc_object_t response
, CFErrorRef
*error
) {
251 xpc_object_t encoded_array
= xpc_dictionary_get_value(response
, kSecXPCKeyResult
);
252 if (response
&& (NULL
!= encoded_array
)) {
253 result
= CreateArrayOfPeerInfoWithXPCObject(encoded_array
, error
);
255 return result
!= NULL
;
258 if (!isArray(result
)) {
259 SOSErrorCreate(kSOSErrorUnexpectedType
, error
, NULL
, CFSTR("Expected array, got: %@"), result
);
260 CFReleaseNull(result
);
265 static SOSPeerInfoRef
data_to_peer_info_error_request(enum SecXPCOperation op
, CFDataRef secret
, CFErrorRef
* error
)
267 __block SOSPeerInfoRef result
= false;
268 __block CFDataRef data
= NULL
;
270 secdebug("sosops", "enter - operation: %d", op
);
271 securityd_send_sync_and_do(op
, error
, ^bool(xpc_object_t message
, CFErrorRef
*error
) {
272 xpc_object_t xsecretData
= _CFXPCCreateXPCObjectFromCFObject(secret
);
273 bool success
= false;
275 xpc_dictionary_set_value(message
, kSecXPCKeyNewPublicBackupKey
, xsecretData
);
277 xpc_release(xsecretData
);
280 }, ^bool(xpc_object_t response
, __unused CFErrorRef
*error
) {
281 xpc_object_t temp_result
= xpc_dictionary_get_value(response
, kSecXPCKeyResult
);
282 if (response
&& (NULL
!= temp_result
)) {
283 data
= _CFXPCCreateCFObjectFromXPCObject(temp_result
);
285 return result
!= NULL
;
289 SOSErrorCreate(kSOSErrorUnexpectedType
, error
, NULL
, CFSTR("Expected CFData, got: %@"), result
);
293 result
= SOSPeerInfoCreateFromData(kCFAllocatorDefault
, error
, data
);
299 static bool keybag_and_bool_to_bool_error_request(enum SecXPCOperation op
, CFDataRef data
, bool include
, CFErrorRef
* error
)
301 secdebug("sosops", "enter - operation: %d", op
);
302 return securityd_send_sync_and_do(op
, error
, ^bool(xpc_object_t message
, CFErrorRef
*error
) {
303 xpc_object_t xData
= _CFXPCCreateXPCObjectFromCFObject(data
);
304 bool success
= false;
306 xpc_dictionary_set_value(message
, kSecXPCKeyKeybag
, xData
);
310 xpc_dictionary_set_bool(message
, kSecXPCKeyIncludeV0
, include
);
312 }, ^bool(xpc_object_t response
, __unused CFErrorRef
*error
) {
313 return xpc_dictionary_get_bool(response
, kSecXPCKeyResult
);
318 static bool info_array_to_bool_error_request(enum SecXPCOperation op
, CFArrayRef peer_infos
, CFErrorRef
* error
)
320 __block
bool result
= false;
322 secdebug("sosops", "enter - operation: %d", op
);
323 securityd_send_sync_and_do(op
, error
, ^bool(xpc_object_t message
, CFErrorRef
*error
) {
324 xpc_object_t encoded_peers
= CreateXPCObjectWithArrayOfPeerInfo(peer_infos
, error
);
326 xpc_dictionary_set_value(message
, kSecXPCKeyPeerInfos
, encoded_peers
);
327 return encoded_peers
!= NULL
;
328 }, ^bool(xpc_object_t response
, __unused CFErrorRef
*error
) {
329 result
= xpc_dictionary_get_bool(response
, kSecXPCKeyResult
);
335 static bool uint64_t_to_bool_error_request(enum SecXPCOperation op
,
339 __block
bool result
= false;
341 securityd_send_sync_and_do(op
, error
, ^bool(xpc_object_t message
, CFErrorRef
*error
) {
342 xpc_dictionary_set_uint64(message
, kSecXPCLimitInMinutes
, number
);
344 }, ^bool(xpc_object_t response
, __unused CFErrorRef
*error
) {
345 result
= xpc_dictionary_get_bool(response
, kSecXPCKeyResult
);
352 static bool set_hsa2_autoaccept_error_request(enum SecXPCOperation op
, CFDataRef pubKey
, CFErrorRef
*error
)
354 __block
bool result
= false;
356 sec_trace_enter_api(NULL
);
357 securityd_send_sync_and_do(op
, error
, ^(xpc_object_t message
,
359 xpc_object_t xpubkey
= _CFXPCCreateXPCObjectFromCFObject(pubKey
);
360 bool success
= false;
362 xpc_dictionary_set_value(message
,
363 kSecXPCKeyHSA2AutoAcceptInfo
, xpubkey
);
365 xpc_release(xpubkey
);
369 }, ^(xpc_object_t response
, __unused CFErrorRef
*error
) {
370 result
= xpc_dictionary_get_bool(response
, kSecXPCKeyResult
);
377 bool SOSCCRequestToJoinCircle(CFErrorRef
* error
)
379 sec_trace_enter_api(NULL
);
380 sec_trace_return_bool_api(^{
381 do_if_registered(soscc_RequestToJoinCircle
, error
);
383 return simple_bool_error_request(kSecXPCOpRequestToJoin
, error
);
387 bool SOSCCRequestToJoinCircleAfterRestore(CFErrorRef
* error
)
389 sec_trace_enter_api(NULL
);
390 sec_trace_return_bool_api(^{
391 do_if_registered(soscc_RequestToJoinCircleAfterRestore
, error
);
393 return simple_bool_error_request(kSecXPCOpRequestToJoinAfterRestore
, error
);
398 bool SOSCCWaitForInitialSync(CFErrorRef
* error
)
400 sec_trace_enter_api(NULL
);
401 sec_trace_return_bool_api(^{
402 do_if_registered(soscc_WaitForInitialSync
, error
);
404 return simple_bool_error_request(kSecXPCOpWaitForInitialSync
, error
);
408 CFArrayRef
SOSCCCopyYetToSyncViewsList(CFErrorRef
* error
)
410 sec_trace_enter_api(NULL
);
411 sec_trace_return_api(CFArrayRef
, ^{
412 do_if_registered(soscc_CopyYetToSyncViewsList
, error
);
414 return simple_array_error_request(kSecXPCOpCopyYetToSyncViews
, error
);
418 bool SOSCCRequestEnsureFreshParameters(CFErrorRef
* error
)
420 sec_trace_enter_api(NULL
);
421 sec_trace_return_bool_api(^{
422 do_if_registered(soscc_RequestEnsureFreshParameters
, error
);
424 return simple_bool_error_request(kSecXPCOpRequestEnsureFreshParameters
, error
);
428 CFStringRef
SOSCCGetAllTheRings(CFErrorRef
*error
){
429 sec_trace_enter_api(NULL
);
430 sec_trace_return_api(CFStringRef
, ^{
431 do_if_registered(soscc_GetAllTheRings
, error
);
434 return simple_cfstring_error_request(kSecXPCOpGetAllTheRings
, error
);
437 bool SOSCCApplyToARing(CFStringRef ringName
, CFErrorRef
* error
)
439 sec_trace_enter_api(NULL
);
440 sec_trace_return_bool_api(^{
441 do_if_registered(soscc_ApplyToARing
, ringName
, error
);
443 return cfstring_to_error_request(kSecXPCOpApplyToARing
, ringName
, error
);
447 bool SOSCCWithdrawlFromARing(CFStringRef ringName
, CFErrorRef
* error
)
449 sec_trace_enter_api(NULL
);
450 sec_trace_return_bool_api(^{
451 do_if_registered(soscc_WithdrawlFromARing
, ringName
, error
);
453 return cfstring_to_error_request(kSecXPCOpWithdrawlFromARing
, ringName
, error
);
457 SOSRingStatus
SOSCCRingStatus(CFStringRef ringName
, CFErrorRef
* error
)
459 sec_trace_enter_api(NULL
);
460 sec_trace_return_api(SOSRingStatus
, ^{
461 do_if_registered(soscc_RingStatus
, ringName
, error
);
463 return cfstring_to_uint64_request(kSecXPCOpRingStatus
, ringName
, error
);
464 }, CFSTR("SOSCCStatus=%d"))
467 bool SOSCCEnableRing(CFStringRef ringName
, CFErrorRef
* error
)
469 sec_trace_enter_api(NULL
);
470 sec_trace_return_bool_api(^{
471 do_if_registered(soscc_EnableRing
, ringName
, error
);
473 return cfstring_to_error_request(kSecXPCOpEnableRing
, ringName
, error
);
477 bool SOSCCAccountSetToNew(CFErrorRef
*error
)
479 secwarning("SOSCCAccountSetToNew called");
480 sec_trace_enter_api(NULL
);
481 sec_trace_return_bool_api(^{
482 do_if_registered(soscc_SetToNew
, error
);
483 return simple_bool_error_request(kSecXPCOpAccountSetToNew
, error
);
487 bool SOSCCResetToOffering(CFErrorRef
* error
)
489 secwarning("SOSCCResetToOffering called");
490 sec_trace_enter_api(NULL
);
491 sec_trace_return_bool_api(^{
492 do_if_registered(soscc_ResetToOffering
, error
);
494 return simple_bool_error_request(kSecXPCOpResetToOffering
, error
);
498 bool SOSCCResetToEmpty(CFErrorRef
* error
)
500 secwarning("SOSCCResetToEmpty called");
501 sec_trace_enter_api(NULL
);
502 sec_trace_return_bool_api(^{
503 do_if_registered(soscc_ResetToEmpty
, error
);
505 return simple_bool_error_request(kSecXPCOpResetToEmpty
, error
);
509 bool SOSCCRemoveThisDeviceFromCircle(CFErrorRef
* error
)
511 sec_trace_enter_api(NULL
);
512 sec_trace_return_bool_api(^{
513 do_if_registered(soscc_RemoveThisDeviceFromCircle
, error
);
515 return simple_bool_error_request(kSecXPCOpRemoveThisDeviceFromCircle
, error
);
519 bool SOSCCLoggedOutOfAccount(CFErrorRef
* error
)
521 sec_trace_enter_api(NULL
);
522 sec_trace_return_bool_api(^{
523 do_if_registered(soscc_LoggedOutOfAccount
, error
);
525 return simple_bool_error_request(kSecXPCOpLoggedOutOfAccount
, error
);
529 bool SOSCCBailFromCircle_BestEffort(uint64_t limit_in_seconds
, CFErrorRef
* error
)
531 sec_trace_enter_api(NULL
);
532 sec_trace_return_bool_api(^{
533 do_if_registered(soscc_BailFromCircle
, limit_in_seconds
, error
);
535 return uint64_t_to_bool_error_request(kSecXPCOpBailFromCircle
, limit_in_seconds
, error
);
539 bool SOSCCSignedOut(bool immediate
, CFErrorRef
* error
)
541 uint64_t limit
= strtoul(optarg
, NULL
, 10);
544 return SOSCCRemoveThisDeviceFromCircle(error
);
546 return SOSCCBailFromCircle_BestEffort(limit
, error
);
550 CFArrayRef
SOSCCCopyPeerPeerInfo(CFErrorRef
* error
)
552 sec_trace_enter_api(NULL
);
553 sec_trace_return_api(CFArrayRef
, ^{
554 do_if_registered(soscc_CopyPeerInfo
, error
);
556 return array_of_info_error_request(kSecXPCOpCopyPeerPeerInfo
, error
);
557 }, CFSTR("return=%@"));
560 bool SOSCCSetAutoAcceptInfo(CFDataRef autoaccept
, CFErrorRef
*error
)
562 sec_trace_return_bool_api(^{
563 do_if_registered(soscc_SetHSA2AutoAcceptInfo
, autoaccept
, error
);
565 return set_hsa2_autoaccept_error_request(kSecXPCOpSetHSA2AutoAcceptInfo
, autoaccept
, error
);
569 CFArrayRef
SOSCCCopyConcurringPeerPeerInfo(CFErrorRef
* error
)
571 sec_trace_enter_api(NULL
);
572 sec_trace_return_api(CFArrayRef
, ^{
573 do_if_registered(soscc_CopyConcurringPeerInfo
, error
);
575 return array_of_info_error_request(kSecXPCOpCopyConcurringPeerPeerInfo
, error
);
576 }, CFSTR("return=%@"));
579 CFArrayRef
SOSCCCopyGenerationPeerInfo(CFErrorRef
* error
)
581 sec_trace_enter_api(NULL
);
582 sec_trace_return_api(CFArrayRef
, ^{
583 do_if_registered(soscc_CopyGenerationPeerInfo
, error
);
585 return simple_array_error_request(kSecXPCOpCopyGenerationPeerInfo
, error
);
586 }, CFSTR("return=%@"));
589 CFArrayRef
SOSCCCopyApplicantPeerInfo(CFErrorRef
* error
)
591 sec_trace_enter_api(NULL
);
592 sec_trace_return_api(CFArrayRef
, ^{
593 do_if_registered(soscc_CopyApplicantPeerInfo
, error
);
595 return array_of_info_error_request(kSecXPCOpCopyApplicantPeerInfo
, error
);
596 }, CFSTR("return=%@"));
599 bool SOSCCValidateUserPublic(CFErrorRef
* error
){
600 sec_trace_enter_api(NULL
);
601 sec_trace_return_api(bool, ^{
602 do_if_registered(soscc_ValidateUserPublic
, error
);
604 return simple_bool_error_request(kSecXPCOpValidateUserPublic
, error
);
608 CFArrayRef
SOSCCCopyValidPeerPeerInfo(CFErrorRef
* error
)
610 sec_trace_enter_api(NULL
);
611 sec_trace_return_api(CFArrayRef
, ^{
612 do_if_registered(soscc_CopyValidPeerPeerInfo
, error
);
614 return array_of_info_error_request(kSecXPCOpCopyValidPeerPeerInfo
, error
);
615 }, CFSTR("return=%@"));
618 CFArrayRef
SOSCCCopyNotValidPeerPeerInfo(CFErrorRef
* error
)
620 sec_trace_enter_api(NULL
);
621 sec_trace_return_api(CFArrayRef
, ^{
622 do_if_registered(soscc_CopyNotValidPeerPeerInfo
, error
);
624 return array_of_info_error_request(kSecXPCOpCopyNotValidPeerPeerInfo
, error
);
625 }, CFSTR("return=%@"));
628 CFArrayRef
SOSCCCopyRetirementPeerInfo(CFErrorRef
* error
)
630 sec_trace_enter_api(NULL
);
631 sec_trace_return_api(CFArrayRef
, ^{
632 do_if_registered(soscc_CopyRetirementPeerInfo
, error
);
634 return array_of_info_error_request(kSecXPCOpCopyRetirementPeerInfo
, error
);
635 }, CFSTR("return=%@"));
638 SOSPeerInfoRef
SOSCCCopyMyPeerInfo(CFErrorRef
*error
)
640 sec_trace_enter_api(NULL
);
641 sec_trace_return_api(SOSPeerInfoRef
, ^{
642 do_if_registered(soscc_CopyMyPeerInfo
, error
);
644 return peer_info_error_request(kSecXPCOpCopyMyPeerInfo
, error
);
645 }, CFSTR("return=%@"));
648 CFArrayRef
SOSCCCopyEngineState(CFErrorRef
* error
)
650 sec_trace_enter_api(NULL
);
651 sec_trace_return_api(CFArrayRef
, ^{
652 do_if_registered(soscc_CopyEngineState
, error
);
654 return simple_array_error_request(kSecXPCOpCopyEngineState
, error
);
655 }, CFSTR("return=%@"));
658 bool SOSCCAcceptApplicants(CFArrayRef applicants
, CFErrorRef
* error
)
660 sec_trace_enter_api(NULL
);
661 sec_trace_return_bool_api(^{
662 do_if_registered(soscc_AcceptApplicants
, applicants
, error
);
664 return info_array_to_bool_error_request(kSecXPCOpAcceptApplicants
, applicants
, error
);
668 bool SOSCCRejectApplicants(CFArrayRef applicants
, CFErrorRef
*error
)
670 sec_trace_enter_api(CFSTR("applicants=%@"), applicants
);
671 sec_trace_return_bool_api(^{
672 do_if_registered(soscc_RejectApplicants
, applicants
, error
);
674 return info_array_to_bool_error_request(kSecXPCOpRejectApplicants
, applicants
, error
);
678 static SOSPeerInfoRef
SOSSetNewPublicBackupKey(CFDataRef pubKey
, CFErrorRef
*error
)
680 sec_trace_enter_api(NULL
);
681 sec_trace_return_api(SOSPeerInfoRef
, ^{
682 do_if_registered(soscc_SetNewPublicBackupKey
, pubKey
, error
);
684 return data_to_peer_info_error_request(kSecXPCOpSetNewPublicBackupKey
, pubKey
, error
);
685 }, CFSTR("return=%@"));
688 SOSPeerInfoRef
SOSCCCopyMyPeerWithNewDeviceRecoverySecret(CFDataRef secret
, CFErrorRef
*error
){
689 CFDataRef publicKeyData
= SOSCopyDeviceBackupPublicKey(secret
, error
);
691 return SOSSetNewPublicBackupKey(publicKeyData
, error
);
694 bool SOSCCRegisterSingleRecoverySecret(CFDataRef aks_bag
, bool includeV0Backups
, CFErrorRef
*error
){
695 sec_trace_enter_api(NULL
);
696 sec_trace_return_bool_api(^{
697 do_if_registered(soscc_RegisterSingleRecoverySecret
, aks_bag
, includeV0Backups
, error
);
698 return keybag_and_bool_to_bool_error_request(kSecXPCOpSetBagForAllSlices
, aks_bag
, includeV0Backups
, error
);
703 static bool label_and_password_to_bool_error_request(enum SecXPCOperation op
,
704 CFStringRef user_label
, CFDataRef user_password
,
707 __block
bool result
= false;
709 securityd_send_sync_and_do(op
, error
, ^bool(xpc_object_t message
, CFErrorRef
*error
) {
710 CFStringPerformWithCString(user_label
, ^(const char *utf8Str
) {
711 xpc_dictionary_set_string(message
, kSecXPCKeyUserLabel
, utf8Str
);
713 xpc_dictionary_set_data(message
, kSecXPCKeyUserPassword
, CFDataGetBytePtr(user_password
), CFDataGetLength(user_password
));
715 }, ^bool(xpc_object_t response
, __unused CFErrorRef
*error
) {
716 result
= xpc_dictionary_get_bool(response
, kSecXPCKeyResult
);
723 static bool label_and_password_and_dsid_to_bool_error_request(enum SecXPCOperation op
,
724 CFStringRef user_label
, CFDataRef user_password
,
725 CFStringRef dsid
, CFErrorRef
* error
)
727 __block
bool result
= false;
729 securityd_send_sync_and_do(op
, error
, ^bool(xpc_object_t message
, CFErrorRef
*error
) {
730 CFStringPerformWithCString(user_label
, ^(const char *utf8Str
) {
731 xpc_dictionary_set_string(message
, kSecXPCKeyUserLabel
, utf8Str
);
733 CFStringPerformWithCString(dsid
, ^(const char *utr8StrDSID
) {
734 xpc_dictionary_set_string(message
, kSecXPCKeyDSID
, utr8StrDSID
);
736 xpc_dictionary_set_data(message
, kSecXPCKeyUserPassword
, CFDataGetBytePtr(user_password
), CFDataGetLength(user_password
));
738 }, ^bool(xpc_object_t response
, __unused CFErrorRef
*error
) {
739 result
= xpc_dictionary_get_bool(response
, kSecXPCKeyResult
);
746 static bool deviceid_to_bool_error_request(enum SecXPCOperation op
,
750 __block
bool result
= false;
752 securityd_send_sync_and_do(op
, error
, ^bool(xpc_object_t message
, CFErrorRef
*error
) {
753 CFStringPerformWithCString(IDS
, ^(const char *utf8Str
) {
754 xpc_dictionary_set_string(message
, kSecXPCKeyDeviceID
, utf8Str
);
757 }, ^bool(xpc_object_t response
, CFErrorRef
*error
) {
758 result
= xpc_dictionary_get_bool(response
, kSecXPCKeyResult
);
760 xpc_object_t xpc_error
= xpc_dictionary_get_value(response
, kSecXPCKeyError
);
761 if (xpc_error
&& error
) {
762 *error
= SecCreateCFErrorWithXPCObject(xpc_error
);
771 static int idsDict_to_bool_error_request(enum SecXPCOperation op
,
775 __block
int result
= false;
777 securityd_send_sync_and_do(op
, error
, ^bool(xpc_object_t message
, CFErrorRef
*error
) {
778 SecXPCDictionarySetPListOptional(message
, kSecXPCKeyIDSMessage
, IDS
, error
);
780 }, ^bool(xpc_object_t response
, __unused CFErrorRef
*error
) {
781 int64_t temp_result
= xpc_dictionary_get_int64(response
, kSecXPCKeyResult
);
782 if ((temp_result
>= INT32_MIN
) && (temp_result
<= INT32_MAX
)) {
783 result
= (int)temp_result
;
791 static bool idscommand_to_bool_error_request(enum SecXPCOperation op
,
792 CFStringRef idsMessage
,
795 __block
bool result
= false;
797 securityd_send_sync_and_do(op
, error
, ^bool(xpc_object_t message
, CFErrorRef
*error
) {
798 CFStringPerformWithCString(idsMessage
, ^(const char *utf8Str
) {
799 xpc_dictionary_set_string(message
, kSecXPCKeySendIDSMessage
, utf8Str
);
802 }, ^bool(xpc_object_t response
, __unused CFErrorRef
*error
) {
803 result
= xpc_dictionary_get_bool(response
, kSecXPCKeyResult
);
810 bool SOSCCRegisterUserCredentials(CFStringRef user_label
, CFDataRef user_password
, CFErrorRef
* error
)
812 secnotice("sosops", "SOSCCRegisterUserCredentials - calling SOSCCSetUserCredentials!! %@\n", user_label
);
813 return SOSCCSetUserCredentials(user_label
, user_password
, error
);
816 bool SOSCCSetUserCredentials(CFStringRef user_label
, CFDataRef user_password
, CFErrorRef
* error
)
818 secnotice("sosops", "SOSCCSetUserCredentials!! %@\n", user_label
);
819 sec_trace_enter_api(CFSTR("user_label=%@"), user_label
);
820 sec_trace_return_bool_api(^{
821 do_if_registered(soscc_SetUserCredentials
, user_label
, user_password
, error
);
823 return label_and_password_to_bool_error_request(kSecXPCOpSetUserCredentials
, user_label
, user_password
, error
);
827 bool SOSCCSetUserCredentialsAndDSID(CFStringRef user_label
, CFDataRef user_password
, CFStringRef dsid
, CFErrorRef
*error
)
829 secnotice("sosops", "SOSCCSetUserCredentialsAndDSID!! %@\n", user_label
);
830 sec_trace_enter_api(CFSTR("user_label=%@"), user_label
);
831 sec_trace_return_bool_api(^{
832 do_if_registered(soscc_SetUserCredentialsAndDSID
, user_label
, user_password
, dsid
, error
);
834 return label_and_password_and_dsid_to_bool_error_request(kSecXPCOpSetUserCredentialsAndDSID
, user_label
, user_password
, CFSTR(""), error
);
837 return label_and_password_and_dsid_to_bool_error_request(kSecXPCOpSetUserCredentialsAndDSID
, user_label
, user_password
, dsid
, error
);
842 bool SOSCCSetDeviceID(CFStringRef IDS
, CFErrorRef
* error
)
844 secnotice("sosops", "SOSCCSetDeviceID!! %@\n", IDS
);
845 sec_trace_enter_api(NULL
);
846 sec_trace_return_bool_api(^{
847 CFErrorRef localError
= NULL
;
848 do_if_registered(soscc_SetDeviceID
, IDS
, &localError
);
849 bool result
= deviceid_to_bool_error_request(kSecXPCOpSetDeviceID
, IDS
, &localError
);
851 *error
= CFRetainSafe(localError
);
857 bool SOSCCIDSServiceRegistrationTest(CFStringRef message
, CFErrorRef
*error
)
859 secnotice("sosops", "SOSCCSendIDSTestMessage!! %@\n", message
);
860 sec_trace_enter_api(NULL
);
861 sec_trace_return_bool_api(^{
862 do_if_registered(soscc_CheckIDSRegistration
, message
, error
);
863 return idscommand_to_bool_error_request(kSecXPCOpSendIDSMessage
, message
, error
);
867 bool SOSCCIDSPingTest(CFStringRef message
, CFErrorRef
*error
)
869 secnotice("sosops", "SOSCCSendIDSTestMessage!! %@\n", message
);
870 sec_trace_enter_api(NULL
);
871 sec_trace_return_bool_api(^{
872 do_if_registered(soscc_PingTest
, message
, error
);
873 return idscommand_to_bool_error_request(kSecXPCOpPingTest
, message
, error
);
877 bool SOSCCIDSDeviceIDIsAvailableTest(CFErrorRef
*error
)
879 secnotice("sosops", "SOSCCIDSDeviceIDIsAvailableTest!!\n");
880 sec_trace_enter_api(NULL
);
881 sec_trace_return_bool_api(^{
882 do_if_registered(soscc_GetIDSIDFromIDS
, error
);
883 return simple_bool_error_request(kSecXPCOpIDSDeviceID
, error
);
887 HandleIDSMessageReason
SOSCCHandleIDSMessage(CFDictionaryRef IDS
, CFErrorRef
* error
)
889 secnotice("sosops", "SOSCCHandleIDSMessage!! %@\n", IDS
);
890 sec_trace_enter_api(NULL
);
891 sec_trace_return_api(HandleIDSMessageReason
, ^{
892 do_if_registered(soscc_HandleIDSMessage
, IDS
, error
);
893 return (HandleIDSMessageReason
) idsDict_to_bool_error_request(kSecXPCOpHandleIDSMessage
, IDS
, error
);
897 bool SOSCCTryUserCredentials(CFStringRef user_label
, CFDataRef user_password
, CFErrorRef
* error
)
899 sec_trace_enter_api(CFSTR("user_label=%@"), user_label
);
900 sec_trace_return_bool_api(^{
901 do_if_registered(soscc_TryUserCredentials
, user_label
, user_password
, error
);
903 return label_and_password_to_bool_error_request(kSecXPCOpTryUserCredentials
, user_label
, user_password
, error
);
908 bool SOSCCCanAuthenticate(CFErrorRef
* error
) {
909 sec_trace_enter_api(NULL
);
910 sec_trace_return_bool_api(^{
911 do_if_registered(soscc_CanAuthenticate
, error
);
913 return simple_bool_error_request(kSecXPCOpCanAuthenticate
, error
);
917 bool SOSCCPurgeUserCredentials(CFErrorRef
* error
) {
918 sec_trace_enter_api(NULL
);
919 sec_trace_return_bool_api(^{
920 do_if_registered(soscc_PurgeUserCredentials
, error
);
922 return simple_bool_error_request(kSecXPCOpPurgeUserCredentials
, error
);
926 enum DepartureReason
SOSCCGetLastDepartureReason(CFErrorRef
*error
) {
927 sec_trace_enter_api(NULL
);
928 sec_trace_return_api(enum DepartureReason
, ^{
929 do_if_registered(soscc_GetLastDepartureReason
, error
);
931 return (enum DepartureReason
) simple_int_error_request(kSecXPCOpGetLastDepartureReason
, error
);
935 bool SOSCCSetLastDepartureReason(enum DepartureReason reason
, CFErrorRef
*error
) {
936 sec_trace_enter_api(NULL
);
937 sec_trace_return_api(bool, ^{
938 do_if_registered(soscc_SetLastDepartureReason
, reason
, error
);
939 return securityd_send_sync_and_do(kSecXPCOpSetLastDepartureReason
, error
,
940 ^bool(xpc_object_t message
, CFErrorRef
*error
) {
941 xpc_dictionary_set_int64(message
, kSecXPCKeyReason
, reason
);
944 ^bool(xpc_object_t response
, __unused CFErrorRef
*error
) {
945 return xpc_dictionary_get_bool(response
, kSecXPCKeyResult
);
951 CFStringRef
SOSCCCopyIncompatibilityInfo(CFErrorRef
* error
) {
952 sec_trace_enter_api(NULL
);
953 sec_trace_return_api(CFStringRef
, ^{
954 do_if_registered(soscc_CopyIncompatibilityInfo
, error
);
956 return simple_cfstring_error_request(kSecXPCOpCopyIncompatibilityInfo
, error
);
960 CFStringRef
SOSCCRequestDeviceID(CFErrorRef
* error
)
962 sec_trace_enter_api(NULL
);
963 sec_trace_return_api(CFStringRef
, ^{
964 do_if_registered(soscc_RequestDeviceID
, error
);
965 CFStringRef deviceID
= simple_cfstring_error_request(kSecXPCOpRequestDeviceID
, error
);
970 bool SOSCCProcessEnsurePeerRegistration(CFErrorRef
* error
){
971 secnotice("updates", "enter SOSCCProcessEnsurePeerRegistration");
972 sec_trace_enter_api(NULL
);
973 sec_trace_return_bool_api(^{
974 do_if_registered(soscc_EnsurePeerRegistration
, error
);
976 return simple_bool_error_request(soscc_EnsurePeerRegistration_id
, error
);
981 SyncWithAllPeersReason
SOSCCProcessSyncWithAllPeers(CFErrorRef
* error
)
983 sec_trace_enter_api(NULL
);
984 sec_trace_return_api(SyncWithAllPeersReason
, ^{
985 do_if_registered(soscc_ProcessSyncWithAllPeers
, error
);
987 return (SyncWithAllPeersReason
) simple_int_error_request(kSecXPCOpProcessSyncWithAllPeers
, error
);
991 CFStringRef
SOSCCGetStatusDescription(SOSCCStatus status
)
995 return CFSTR("InCircle");
996 case kSOSCCNotInCircle
:
997 return CFSTR("NotInCircle");
998 case kSOSCCRequestPending
:
999 return CFSTR("RequestPending");
1000 case kSOSCCCircleAbsent
:
1001 return CFSTR("CircleAbsent");
1003 return CFSTR("InternalError");
1005 return CFSTR("Unknown Status (%d)");
1010 kSOSCCGeneralViewError
= -1,
1011 kSOSCCViewMember
= 0,
1012 kSOSCCViewNotMember
= 1,
1013 kSOSCCViewNotQualified
= 2,
1014 kSOSCCNoSuchView
= 3,
1017 static int64_t name_action_to_code_request(enum SecXPCOperation op
, uint16_t error_result
,
1018 CFStringRef name
, uint64_t action
, CFErrorRef
*error
) {
1019 __block
int64_t result
= error_result
;
1021 securityd_send_sync_and_do(op
, error
, ^bool(xpc_object_t message
, CFErrorRef
*error
) {
1022 CFStringPerformWithCString(name
, ^(const char *utf8Str
) {
1023 xpc_dictionary_set_string(message
, kSecXPCKeyViewName
, utf8Str
);
1025 xpc_dictionary_set_int64(message
, kSecXPCKeyViewActionCode
, action
);
1027 }, ^bool(xpc_object_t response
, __unused CFErrorRef
*error
) {
1028 if (response
&& xpc_dictionary_entry_is_type(response
, kSecXPCKeyResult
, XPC_TYPE_INT64
)) {
1029 result
= xpc_dictionary_get_int64(response
, kSecXPCKeyResult
);
1031 return result
!= error_result
;
1037 SOSViewResultCode
SOSCCView(CFStringRef view
, SOSViewActionCode actionCode
, CFErrorRef
*error
) {
1038 sec_trace_enter_api(NULL
);
1039 sec_trace_return_api(SOSViewResultCode
, ^{
1040 do_if_registered(soscc_View
, view
, actionCode
, error
);
1042 return (SOSViewResultCode
) name_action_to_code_request(kSecXPCOpView
, kSOSCCGeneralViewError
, view
, actionCode
, error
);
1043 }, CFSTR("SOSViewResultCode=%d"))
1047 bool SOSCCViewSet(CFSetRef enabledViews
, CFSetRef disabledViews
) {
1048 CFErrorRef
*error
= NULL
;
1049 __block
bool result
= false;
1051 sec_trace_enter_api(NULL
);
1052 sec_trace_return_bool_api(^{
1053 do_if_registered(soscc_ViewSet
, enabledViews
, disabledViews
);
1054 return securityd_send_sync_and_do(kSecXPCOpViewSet
, error
, ^bool(xpc_object_t message
, CFErrorRef
*error
) {
1055 xpc_object_t enabledSetXpc
= CreateXPCObjectWithCFSetRef(enabledViews
, error
);
1056 xpc_object_t disabledSetXpc
= CreateXPCObjectWithCFSetRef(disabledViews
, error
);
1057 if (enabledSetXpc
) xpc_dictionary_set_value(message
, kSecXPCKeyEnabledViewsKey
, enabledSetXpc
);
1058 if (disabledSetXpc
) xpc_dictionary_set_value(message
, kSecXPCKeyDisabledViewsKey
, disabledSetXpc
);
1059 return (enabledSetXpc
!= NULL
) || (disabledSetXpc
!= NULL
) ;
1060 }, ^bool(xpc_object_t response
, __unused CFErrorRef
*error
) {
1061 result
= xpc_dictionary_get_bool(response
, kSecXPCKeyResult
);
1067 SOSSecurityPropertyResultCode
SOSCCSecurityProperty(CFStringRef property
, SOSSecurityPropertyActionCode actionCode
, CFErrorRef
*error
) {
1068 sec_trace_enter_api(NULL
);
1069 sec_trace_return_api(SOSSecurityPropertyResultCode
, ^{
1070 SOSSecurityPropertyResultCode result
= kSOSCCGeneralSecurityPropertyError
;
1071 do_if_registered(soscc_SecurityProperty
, property
, actionCode
, error
);
1072 xpc_object_t message
= securityd_create_message(kSecXPCOpSecurityProperty
, error
);
1074 int64_t bigac
= actionCode
;
1075 xpc_dictionary_set_string(message
, kSecXPCKeyViewName
, CFStringGetCStringPtr(property
, kCFStringEncodingUTF8
));
1076 xpc_dictionary_set_int64(message
, kSecXPCKeyViewActionCode
, bigac
);
1078 xpc_object_t response
= securityd_message_with_reply_sync(message
, error
);
1080 if (response
&& xpc_dictionary_entry_is_type(response
, kSecXPCKeyResult
, XPC_TYPE_INT64
)) {
1081 result
= (SOSSecurityPropertyResultCode
) xpc_dictionary_get_int64(response
, kSecXPCKeyResult
);
1084 if (result
== kSOSCCGeneralSecurityPropertyError
) {
1085 if (response
&& securityd_message_no_error(response
, error
)) {
1086 char *desc
= xpc_copy_description(response
);
1087 SecCFCreateErrorWithFormat(0, sSecXPCErrorDomain
, NULL
, error
, NULL
, CFSTR("Remote error occurred/no info: %s"), desc
);
1092 xpc_release(response
);
1094 xpc_release(message
);
1098 }, CFSTR("SOSSecurityPropertyResultCode=%d"))
1102 static bool sosIsViewSetSyncing(size_t n
, CFStringRef
*views
) {
1103 __block
bool retval
= true;
1105 SOSCCStatus cstatus
= SOSCCThisDeviceIsInCircle(NULL
);
1106 if(cstatus
== kSOSCCInCircle
) {
1107 for(size_t i
= 0; i
< n
; i
++) {
1108 SOSViewResultCode vstatus
= SOSCCView(views
[i
], kSOSCCViewQuery
, NULL
);
1109 if(vstatus
!= kSOSCCViewMember
) retval
= false;
1117 bool SOSCCIsIcloudKeychainSyncing(void) {
1118 CFStringRef views
[] = { kSOSViewKeychainV0
};
1119 return sosIsViewSetSyncing(1, views
);
1122 bool SOSCCIsSafariSyncing(void) {
1123 CFStringRef views
[] = { kSOSViewAutofillPasswords
, kSOSViewSafariCreditCards
};
1124 return sosIsViewSetSyncing(2, views
);
1127 bool SOSCCIsAppleTVSyncing(void) {
1128 CFStringRef views
[] = { kSOSViewAppleTV
};
1129 return sosIsViewSetSyncing(1, views
);
1132 bool SOSCCIsHomeKitSyncing(void) {
1133 CFStringRef views
[] = { kSOSViewHomeKit
};
1134 return sosIsViewSetSyncing(1, views
);
1137 bool SOSCCIsWiFiSyncing(void) {
1138 CFStringRef views
[] = { kSOSViewWiFi
};
1139 return sosIsViewSetSyncing(1, views
);