]> git.saurik.com Git - apple/security.git/blob - OSX/sec/SOSCircle/SecureObjectSync/SOSCloudCircle.c
Security-57337.20.44.tar.gz
[apple/security.git] / OSX / sec / SOSCircle / SecureObjectSync / SOSCloudCircle.c
1 /*
2 * Copyright (c) 2012-2014 Apple Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
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
11 * file.
12 *
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.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24 //
25 // SOSCloudCircle.m
26 //
27
28 #include <stdio.h>
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>
40
41 #include <Security/SecKeyPriv.h>
42 #include <Security/SecFramework.h>
43 #include <CoreFoundation/CFXPCBridge.h>
44
45 #include <securityd/SecItemServer.h>
46
47 #include <utilities/SecDispatchRelease.h>
48 #include <utilities/SecCFRelease.h>
49 #include <utilities/SecCFWrappers.h>
50 #include <utilities/SecXPCError.h>
51
52 #include <utilities/debugging.h>
53
54 #include <CoreFoundation/CoreFoundation.h>
55
56 #include <xpc/xpc.h>
57 #define MINIMIZE_INCLUDES MINIMIZE_INCLUDES
58 #include <ipc/securityd_client.h>
59 #include <securityd/spi.h>
60
61 #include "SOSRegressionUtilities.h"
62 #include <Security/SecuritydXPC.h>
63 #include <SOSPeerInfoDER.h>
64 #include <SOSCloudKeychainClient.h>
65
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";
69 const char * kSOSCCHoldLockForInitialSync = "com.apple.security.secureobjectsync.holdlock";
70 const char * kSOSCCPeerAvailable = "com.apple.security.secureobjectsync.peeravailable";
71
72 #define do_if_registered(sdp, ...) if (gSecurityd && gSecurityd->sdp) { return gSecurityd->sdp(__VA_ARGS__); }
73
74 static bool xpc_dictionary_entry_is_type(xpc_object_t dictionary, const char *key, xpc_type_t type)
75 {
76 xpc_object_t value = xpc_dictionary_get_value(dictionary, key);
77
78 return value && (xpc_get_type(value) == type);
79 }
80
81 SOSCCStatus SOSCCThisDeviceIsInCircle(CFErrorRef *error)
82 {
83 sec_trace_enter_api(NULL);
84 sec_trace_return_api(SOSCCStatus, ^{
85 SOSCCStatus result = kSOSCCError;
86
87 do_if_registered(soscc_ThisDeviceIsInCircle, error);
88
89 xpc_object_t message = securityd_create_message(kSecXPCOpDeviceInCircle, error);
90 if (message) {
91 xpc_object_t response = securityd_message_with_reply_sync(message, error);
92
93 if (response && xpc_dictionary_entry_is_type(response, kSecXPCKeyResult, XPC_TYPE_INT64)) {
94 result = (SOSCCStatus) xpc_dictionary_get_int64(response, kSecXPCKeyResult);
95 } else {
96 result = kSOSCCError;
97 }
98
99 if (result < 0) {
100 if (response && securityd_message_no_error(response, error))
101 {
102 char *desc = xpc_copy_description(response);
103 SecCFCreateErrorWithFormat(0, sSecXPCErrorDomain, NULL, error, NULL, CFSTR("Remote error occurred/no info: %s"), desc);
104 free((void *)desc);
105 }
106 }
107 if(response)
108 xpc_release(response);
109 if(message)
110 xpc_release(message);
111 }
112
113
114 return result;
115 }, CFSTR("SOSCCStatus=%d"))
116 }
117
118 static bool cfstring_to_error_request(enum SecXPCOperation op, CFStringRef string, CFErrorRef* error)
119 {
120 __block bool result = false;
121
122 secdebug("sosops","enter - operation: %d", op);
123 securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
124 xpc_object_t xString = _CFXPCCreateXPCObjectFromCFObject(string);
125 bool success = false;
126 if (xString){
127 xpc_dictionary_set_value(message, kSecXPCKeyString, xString);
128 success = true;
129 xpc_release(xString);
130 }
131 return success;
132 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
133 result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
134 return result;
135 });
136 return result;
137 }
138
139 static SOSRingStatus cfstring_to_uint64_request(enum SecXPCOperation op, CFStringRef string, CFErrorRef* error)
140 {
141 __block bool result = false;
142
143 secdebug("sosops","enter - operation: %d", op);
144 securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
145 xpc_object_t xString = _CFXPCCreateXPCObjectFromCFObject(string);
146 bool success = false;
147 if (xString){
148 xpc_dictionary_set_value(message, kSecXPCKeyString, xString);
149 success = true;
150 xpc_release(xString);
151 }
152 return success;
153 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
154 result = xpc_dictionary_get_int64(response, kSecXPCKeyResult);
155 return result;
156 });
157 return result;
158 }
159
160 static CFStringRef simple_cfstring_error_request(enum SecXPCOperation op, CFErrorRef* error)
161 {
162 __block CFStringRef result = NULL;
163
164 secdebug("sosops","enter - operation: %d", op);
165 securityd_send_sync_and_do(op, error, NULL, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
166 const char *c_string = xpc_dictionary_get_string(response, kSecXPCKeyResult);
167
168 if (c_string) {
169 result = CFStringCreateWithBytes(kCFAllocatorDefault, (const UInt8*)c_string, strlen(c_string), kCFStringEncodingUTF8, false);
170 }
171
172 return c_string != NULL;
173 });
174 return result;
175 }
176
177 static bool simple_bool_error_request(enum SecXPCOperation op, CFErrorRef* error)
178 {
179 __block bool result = false;
180
181 secdebug("sosops","enter - operation: %d", op);
182 securityd_send_sync_and_do(op, error, NULL, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
183 result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
184 return result;
185 });
186 return result;
187 }
188
189 static bool escrow_to_bool_error_request(enum SecXPCOperation op, CFStringRef escrow_label, uint64_t tries, CFErrorRef* error)
190 {
191 __block bool result = false;
192
193 securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
194
195 bool success = false;
196 xpc_object_t xEscrowLabel = _CFXPCCreateXPCObjectFromCFObject(escrow_label);
197 if (xEscrowLabel){
198 xpc_dictionary_set_value(message, kSecXPCKeyEscrowLabel, xEscrowLabel);
199 success = true;
200 xpc_release(xEscrowLabel);
201 }
202 if(tries){
203 xpc_dictionary_set_int64(message, kSecXPCKeyTriesLabel, tries);
204 success = true;
205 }
206
207 return success;
208 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
209 result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
210 return result;
211 });
212 return result;
213 }
214
215 static CFArrayRef simple_array_error_request(enum SecXPCOperation op, CFErrorRef* error)
216 {
217 __block CFArrayRef result = NULL;
218
219 secdebug("sosops","enter - operation: %d", op);
220 if (securityd_send_sync_and_do(op, error, NULL, ^bool(xpc_object_t response, CFErrorRef *error) {
221 xpc_object_t temp_result = xpc_dictionary_get_value(response, kSecXPCKeyResult);
222 result = _CFXPCCreateCFObjectFromXPCObject(temp_result);
223 return result != NULL;
224 })) {
225 if (!isArray(result)) {
226 SOSErrorCreate(kSOSErrorUnexpectedType, error, NULL, CFSTR("Expected array, got: %@"), result);
227 CFReleaseNull(result);
228 }
229 }
230 return result;
231 }
232
233 static CFDictionaryRef strings_to_dictionary_error_request(enum SecXPCOperation op, CFErrorRef* error)
234 {
235 __block CFDictionaryRef result = NULL;
236
237 secdebug("sosops","enter - operation: %d", op);
238
239 if (securityd_send_sync_and_do(op, error, NULL, ^bool(xpc_object_t response, CFErrorRef *error) {
240 xpc_object_t temp_result = xpc_dictionary_get_value(response, kSecXPCKeyResult);
241 if(temp_result)
242 result = _CFXPCCreateCFObjectFromXPCObject(temp_result);
243 return result != NULL;
244 })){
245
246 if (!isDictionary(result)) {
247 SOSErrorCreate(kSOSErrorUnexpectedType, error, NULL, CFSTR("Expected dictionary, got: %@"), result);
248 CFReleaseNull(result);
249 }
250
251 }
252 return result;
253 }
254
255 static int simple_int_error_request(enum SecXPCOperation op, CFErrorRef* error)
256 {
257 __block int result = 0;
258
259 secdebug("sosops","enter - operation: %d", op);
260 securityd_send_sync_and_do(op, error, NULL, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
261 int64_t temp_result = xpc_dictionary_get_int64(response, kSecXPCKeyResult);
262 if ((temp_result >= INT32_MIN) && (temp_result <= INT32_MAX)) {
263 result = (int)temp_result;
264 }
265 return result;
266 });
267 return result;
268 }
269
270 static SOSPeerInfoRef peer_info_error_request(enum SecXPCOperation op, CFErrorRef* error)
271 {
272 SOSPeerInfoRef result = NULL;
273 __block CFDataRef data = NULL;
274
275 secdebug("sosops","enter - operation: %d", op);
276 securityd_send_sync_and_do(op, error, NULL, ^bool(xpc_object_t response, CFErrorRef *error) {
277 xpc_object_t temp_result = xpc_dictionary_get_value(response, kSecXPCKeyResult);
278 if (response && (NULL != temp_result)) {
279 data = _CFXPCCreateCFObjectFromXPCObject(temp_result);
280 }
281 return data != NULL;
282 });
283
284 if (!isData(data)) {
285 SOSErrorCreate(kSOSErrorUnexpectedType, error, NULL, CFSTR("Expected CFData, got: %@"), result);
286 }
287
288 if (data) {
289 result = SOSPeerInfoCreateFromData(kCFAllocatorDefault, error, data);
290 }
291 CFReleaseNull(data);
292 return result;
293 }
294
295 static CFArrayRef array_of_info_error_request(enum SecXPCOperation op, CFErrorRef* error)
296 {
297 __block CFArrayRef result = NULL;
298
299 secdebug("sosops","enter - operation: %d", op);
300 securityd_send_sync_and_do(op, error, NULL, ^bool(xpc_object_t response, CFErrorRef *error) {
301 xpc_object_t encoded_array = xpc_dictionary_get_value(response, kSecXPCKeyResult);
302 if (response && (NULL != encoded_array)) {
303 result = CreateArrayOfPeerInfoWithXPCObject(encoded_array, error);
304 }
305 return result != NULL;
306 });
307
308 if (!isArray(result)) {
309 SOSErrorCreate(kSOSErrorUnexpectedType, error, NULL, CFSTR("Expected array, got: %@"), result);
310 CFReleaseNull(result);
311 }
312 return result;
313 }
314
315 static SOSPeerInfoRef data_to_peer_info_error_request(enum SecXPCOperation op, CFDataRef secret, CFErrorRef* error)
316 {
317 __block SOSPeerInfoRef result = false;
318 __block CFDataRef data = NULL;
319
320 secdebug("sosops", "enter - operation: %d", op);
321 securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
322 xpc_object_t xsecretData = _CFXPCCreateXPCObjectFromCFObject(secret);
323 bool success = false;
324 if (xsecretData){
325 xpc_dictionary_set_value(message, kSecXPCKeyNewPublicBackupKey, xsecretData);
326 success = true;
327 xpc_release(xsecretData);
328 }
329 return success;
330 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
331 xpc_object_t temp_result = xpc_dictionary_get_value(response, kSecXPCKeyResult);
332 if (response && (NULL != temp_result)) {
333 data = _CFXPCCreateCFObjectFromXPCObject(temp_result);
334 }
335 return result != NULL;
336 });
337
338 if (!isData(data)) {
339 SOSErrorCreate(kSOSErrorUnexpectedType, error, NULL, CFSTR("Expected CFData, got: %@"), result);
340 }
341
342 if (data) {
343 result = SOSPeerInfoCreateFromData(kCFAllocatorDefault, error, data);
344 }
345 CFReleaseNull(data);
346 return result;
347 }
348
349 static bool keybag_and_bool_to_bool_error_request(enum SecXPCOperation op, CFDataRef data, bool include, CFErrorRef* error)
350 {
351 secdebug("sosops", "enter - operation: %d", op);
352 return securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
353 xpc_object_t xData = _CFXPCCreateXPCObjectFromCFObject(data);
354 bool success = false;
355 if (xData){
356 xpc_dictionary_set_value(message, kSecXPCKeyKeybag, xData);
357 xpc_release(xData);
358 success = true;
359 }
360 xpc_dictionary_set_bool(message, kSecXPCKeyIncludeV0, include);
361 return success;
362 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
363 return xpc_dictionary_get_bool(response, kSecXPCKeyResult);
364 });
365 }
366
367
368 static bool info_array_to_bool_error_request(enum SecXPCOperation op, CFArrayRef peer_infos, CFErrorRef* error)
369 {
370 __block bool result = false;
371
372 secdebug("sosops", "enter - operation: %d", op);
373 securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
374 xpc_object_t encoded_peers = CreateXPCObjectWithArrayOfPeerInfo(peer_infos, error);
375 if (encoded_peers)
376 xpc_dictionary_set_value(message, kSecXPCKeyPeerInfos, encoded_peers);
377 return encoded_peers != NULL;
378 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
379 result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
380 return result;
381 });
382 return result;
383 }
384
385 static bool uint64_t_to_bool_error_request(enum SecXPCOperation op,
386 uint64_t number,
387 CFErrorRef* error)
388 {
389 __block bool result = false;
390
391 securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
392 xpc_dictionary_set_uint64(message, kSecXPCLimitInMinutes, number);
393 return true;
394 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
395 result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
396 return result;
397 });
398
399 return result;
400 }
401
402 static bool set_hsa2_autoaccept_error_request(enum SecXPCOperation op, CFDataRef pubKey, CFErrorRef *error)
403 {
404 __block bool result = false;
405
406 sec_trace_enter_api(NULL);
407 securityd_send_sync_and_do(op, error, ^(xpc_object_t message,
408 CFErrorRef *error) {
409 xpc_object_t xpubkey = _CFXPCCreateXPCObjectFromCFObject(pubKey);
410 bool success = false;
411 if (xpubkey) {
412 xpc_dictionary_set_value(message,
413 kSecXPCKeyHSA2AutoAcceptInfo, xpubkey);
414 success = true;
415 xpc_release(xpubkey);
416 }
417
418 return success;
419 }, ^(xpc_object_t response, __unused CFErrorRef *error) {
420 result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
421 return (bool)true;
422 });
423
424 return result;
425 }
426
427 bool SOSCCRequestToJoinCircle(CFErrorRef* error)
428 {
429 sec_trace_enter_api(NULL);
430 sec_trace_return_bool_api(^{
431 do_if_registered(soscc_RequestToJoinCircle, error);
432
433 return simple_bool_error_request(kSecXPCOpRequestToJoin, error);
434 }, NULL)
435 }
436
437 bool SOSCCRequestToJoinCircleAfterRestore(CFErrorRef* error)
438 {
439 sec_trace_enter_api(NULL);
440 sec_trace_return_bool_api(^{
441 do_if_registered(soscc_RequestToJoinCircleAfterRestore, error);
442
443 return simple_bool_error_request(kSecXPCOpRequestToJoinAfterRestore, error);
444 }, NULL)
445 }
446
447
448 bool SOSCCWaitForInitialSync(CFErrorRef* error)
449 {
450 sec_trace_enter_api(NULL);
451 sec_trace_return_bool_api(^{
452 do_if_registered(soscc_WaitForInitialSync, error);
453
454 return simple_bool_error_request(kSecXPCOpWaitForInitialSync, error);
455 }, NULL)
456 }
457
458 CFArrayRef SOSCCCopyYetToSyncViewsList(CFErrorRef* error)
459 {
460 sec_trace_enter_api(NULL);
461 sec_trace_return_api(CFArrayRef, ^{
462 do_if_registered(soscc_CopyYetToSyncViewsList, error);
463
464 return simple_array_error_request(kSecXPCOpCopyYetToSyncViews, error);
465 }, NULL)
466 }
467
468 bool SOSCCRequestEnsureFreshParameters(CFErrorRef* error)
469 {
470 sec_trace_enter_api(NULL);
471 sec_trace_return_bool_api(^{
472 do_if_registered(soscc_RequestEnsureFreshParameters, error);
473
474 return simple_bool_error_request(kSecXPCOpRequestEnsureFreshParameters, error);
475 }, NULL)
476 }
477
478 CFStringRef SOSCCGetAllTheRings(CFErrorRef *error){
479 sec_trace_enter_api(NULL);
480 sec_trace_return_api(CFStringRef, ^{
481 do_if_registered(soscc_GetAllTheRings, error);
482
483
484 return simple_cfstring_error_request(kSecXPCOpGetAllTheRings, error);
485 }, NULL)
486 }
487 bool SOSCCApplyToARing(CFStringRef ringName, CFErrorRef* error)
488 {
489 sec_trace_enter_api(NULL);
490 sec_trace_return_bool_api(^{
491 do_if_registered(soscc_ApplyToARing, ringName, error);
492
493 return cfstring_to_error_request(kSecXPCOpApplyToARing, ringName, error);
494 }, NULL)
495 }
496
497 bool SOSCCWithdrawlFromARing(CFStringRef ringName, CFErrorRef* error)
498 {
499 sec_trace_enter_api(NULL);
500 sec_trace_return_bool_api(^{
501 do_if_registered(soscc_WithdrawlFromARing, ringName, error);
502
503 return cfstring_to_error_request(kSecXPCOpWithdrawlFromARing, ringName, error);
504 }, NULL)
505 }
506
507 SOSRingStatus SOSCCRingStatus(CFStringRef ringName, CFErrorRef* error)
508 {
509 sec_trace_enter_api(NULL);
510 sec_trace_return_api(SOSRingStatus, ^{
511 do_if_registered(soscc_RingStatus, ringName, error);
512
513 return cfstring_to_uint64_request(kSecXPCOpRingStatus, ringName, error);
514 }, CFSTR("SOSCCStatus=%d"))
515 }
516
517 bool SOSCCEnableRing(CFStringRef ringName, CFErrorRef* error)
518 {
519 sec_trace_enter_api(NULL);
520 sec_trace_return_bool_api(^{
521 do_if_registered(soscc_EnableRing, ringName, error);
522
523 return cfstring_to_error_request(kSecXPCOpEnableRing, ringName, error);
524 }, NULL)
525 }
526
527 bool SOSCCAccountSetToNew(CFErrorRef *error)
528 {
529 secwarning("SOSCCAccountSetToNew called");
530 sec_trace_enter_api(NULL);
531 sec_trace_return_bool_api(^{
532 do_if_registered(soscc_SetToNew, error);
533 return simple_bool_error_request(kSecXPCOpAccountSetToNew, error);
534 }, NULL)
535 }
536
537 bool SOSCCResetToOffering(CFErrorRef* error)
538 {
539 secwarning("SOSCCResetToOffering called");
540 sec_trace_enter_api(NULL);
541 sec_trace_return_bool_api(^{
542 do_if_registered(soscc_ResetToOffering, error);
543
544 return simple_bool_error_request(kSecXPCOpResetToOffering, error);
545 }, NULL)
546 }
547
548 bool SOSCCResetToEmpty(CFErrorRef* error)
549 {
550 secwarning("SOSCCResetToEmpty called");
551 sec_trace_enter_api(NULL);
552 sec_trace_return_bool_api(^{
553 do_if_registered(soscc_ResetToEmpty, error);
554
555 return simple_bool_error_request(kSecXPCOpResetToEmpty, error);
556 }, NULL)
557 }
558
559 bool SOSCCRemovePeersFromCircle(CFArrayRef peers, CFErrorRef* error)
560 {
561 sec_trace_enter_api(NULL);
562 sec_trace_return_bool_api(^{
563 do_if_registered(soscc_RemovePeersFromCircle, peers, error);
564
565 return info_array_to_bool_error_request(kSecXPCOpRemovePeersFromCircle, peers, error);
566 }, NULL)
567 }
568
569 bool SOSCCRemoveThisDeviceFromCircle(CFErrorRef* error)
570 {
571 sec_trace_enter_api(NULL);
572 sec_trace_return_bool_api(^{
573 do_if_registered(soscc_RemoveThisDeviceFromCircle, error);
574
575 return simple_bool_error_request(kSecXPCOpRemoveThisDeviceFromCircle, error);
576 }, NULL)
577 }
578
579 bool SOSCCLoggedOutOfAccount(CFErrorRef* error)
580 {
581 sec_trace_enter_api(NULL);
582 sec_trace_return_bool_api(^{
583 do_if_registered(soscc_LoggedOutOfAccount, error);
584
585 return simple_bool_error_request(kSecXPCOpLoggedOutOfAccount, error);
586 }, NULL)
587 }
588
589 bool SOSCCBailFromCircle_BestEffort(uint64_t limit_in_seconds, CFErrorRef* error)
590 {
591 sec_trace_enter_api(NULL);
592 sec_trace_return_bool_api(^{
593 do_if_registered(soscc_BailFromCircle, limit_in_seconds, error);
594
595 return uint64_t_to_bool_error_request(kSecXPCOpBailFromCircle, limit_in_seconds, error);
596 }, NULL)
597 }
598
599 bool SOSCCSignedOut(bool immediate, CFErrorRef* error)
600 {
601 uint64_t limit = strtoul(optarg, NULL, 10);
602
603 if(immediate)
604 return SOSCCRemoveThisDeviceFromCircle(error);
605 else
606 return SOSCCBailFromCircle_BestEffort(limit, error);
607
608 }
609
610 CFArrayRef SOSCCCopyPeerPeerInfo(CFErrorRef* error)
611 {
612 sec_trace_enter_api(NULL);
613 sec_trace_return_api(CFArrayRef, ^{
614 do_if_registered(soscc_CopyPeerInfo, error);
615
616 return array_of_info_error_request(kSecXPCOpCopyPeerPeerInfo, error);
617 }, CFSTR("return=%@"));
618 }
619
620 bool SOSCCSetAutoAcceptInfo(CFDataRef autoaccept, CFErrorRef *error)
621 {
622 sec_trace_return_bool_api(^{
623 do_if_registered(soscc_SetHSA2AutoAcceptInfo, autoaccept, error);
624
625 return set_hsa2_autoaccept_error_request(kSecXPCOpSetHSA2AutoAcceptInfo, autoaccept, error);
626 }, NULL)
627 }
628
629 CFArrayRef SOSCCCopyConcurringPeerPeerInfo(CFErrorRef* error)
630 {
631 sec_trace_enter_api(NULL);
632 sec_trace_return_api(CFArrayRef, ^{
633 do_if_registered(soscc_CopyConcurringPeerInfo, error);
634
635 return array_of_info_error_request(kSecXPCOpCopyConcurringPeerPeerInfo, error);
636 }, CFSTR("return=%@"));
637 }
638
639 CFArrayRef SOSCCCopyGenerationPeerInfo(CFErrorRef* error)
640 {
641 sec_trace_enter_api(NULL);
642 sec_trace_return_api(CFArrayRef, ^{
643 do_if_registered(soscc_CopyGenerationPeerInfo, error);
644
645 return simple_array_error_request(kSecXPCOpCopyGenerationPeerInfo, error);
646 }, CFSTR("return=%@"));
647 }
648
649 CFArrayRef SOSCCCopyApplicantPeerInfo(CFErrorRef* error)
650 {
651 sec_trace_enter_api(NULL);
652 sec_trace_return_api(CFArrayRef, ^{
653 do_if_registered(soscc_CopyApplicantPeerInfo, error);
654
655 return array_of_info_error_request(kSecXPCOpCopyApplicantPeerInfo, error);
656 }, CFSTR("return=%@"));
657 }
658
659 bool SOSCCValidateUserPublic(CFErrorRef* error){
660 sec_trace_enter_api(NULL);
661 sec_trace_return_api(bool, ^{
662 do_if_registered(soscc_ValidateUserPublic, error);
663
664 return simple_bool_error_request(kSecXPCOpValidateUserPublic, error);
665 }, NULL);
666 }
667
668 CFArrayRef SOSCCCopyValidPeerPeerInfo(CFErrorRef* error)
669 {
670 sec_trace_enter_api(NULL);
671 sec_trace_return_api(CFArrayRef, ^{
672 do_if_registered(soscc_CopyValidPeerPeerInfo, error);
673
674 return array_of_info_error_request(kSecXPCOpCopyValidPeerPeerInfo, error);
675 }, CFSTR("return=%@"));
676 }
677
678 CFArrayRef SOSCCCopyNotValidPeerPeerInfo(CFErrorRef* error)
679 {
680 sec_trace_enter_api(NULL);
681 sec_trace_return_api(CFArrayRef, ^{
682 do_if_registered(soscc_CopyNotValidPeerPeerInfo, error);
683
684 return array_of_info_error_request(kSecXPCOpCopyNotValidPeerPeerInfo, error);
685 }, CFSTR("return=%@"));
686 }
687
688 CFArrayRef SOSCCCopyRetirementPeerInfo(CFErrorRef* error)
689 {
690 sec_trace_enter_api(NULL);
691 sec_trace_return_api(CFArrayRef, ^{
692 do_if_registered(soscc_CopyRetirementPeerInfo, error);
693
694 return array_of_info_error_request(kSecXPCOpCopyRetirementPeerInfo, error);
695 }, CFSTR("return=%@"));
696 }
697
698 CFArrayRef SOSCCCopyViewUnawarePeerInfo(CFErrorRef* error)
699 {
700 sec_trace_enter_api(NULL);
701 sec_trace_return_api(CFArrayRef, ^{
702 do_if_registered(soscc_CopyViewUnawarePeerInfo, error);
703
704 return array_of_info_error_request(kSecXPCOpCopyViewUnawarePeerInfo, error);
705 }, CFSTR("return=%@"));
706 }
707
708 SOSPeerInfoRef SOSCCCopyMyPeerInfo(CFErrorRef *error)
709 {
710 sec_trace_enter_api(NULL);
711 sec_trace_return_api(SOSPeerInfoRef, ^{
712 do_if_registered(soscc_CopyMyPeerInfo, error);
713
714 return peer_info_error_request(kSecXPCOpCopyMyPeerInfo, error);
715 }, CFSTR("return=%@"));
716 }
717
718 CFArrayRef SOSCCCopyEngineState(CFErrorRef* error)
719 {
720 sec_trace_enter_api(NULL);
721 sec_trace_return_api(CFArrayRef, ^{
722 do_if_registered(soscc_CopyEngineState, error);
723
724 return simple_array_error_request(kSecXPCOpCopyEngineState, error);
725 }, CFSTR("return=%@"));
726 }
727
728 bool SOSCCAcceptApplicants(CFArrayRef applicants, CFErrorRef* error)
729 {
730 sec_trace_enter_api(NULL);
731 sec_trace_return_bool_api(^{
732 do_if_registered(soscc_AcceptApplicants, applicants, error);
733
734 return info_array_to_bool_error_request(kSecXPCOpAcceptApplicants, applicants, error);
735 }, NULL)
736 }
737
738 bool SOSCCRejectApplicants(CFArrayRef applicants, CFErrorRef *error)
739 {
740 sec_trace_enter_api(CFSTR("applicants=%@"), applicants);
741 sec_trace_return_bool_api(^{
742 do_if_registered(soscc_RejectApplicants, applicants, error);
743
744 return info_array_to_bool_error_request(kSecXPCOpRejectApplicants, applicants, error);
745 }, NULL)
746 }
747
748 static SOSPeerInfoRef SOSSetNewPublicBackupKey(CFDataRef pubKey, CFErrorRef *error)
749 {
750 sec_trace_enter_api(NULL);
751 sec_trace_return_api(SOSPeerInfoRef, ^{
752 do_if_registered(soscc_SetNewPublicBackupKey, pubKey, error);
753
754 return data_to_peer_info_error_request(kSecXPCOpSetNewPublicBackupKey, pubKey, error);
755 }, CFSTR("return=%@"));
756 }
757
758 SOSPeerInfoRef SOSCCCopyMyPeerWithNewDeviceRecoverySecret(CFDataRef secret, CFErrorRef *error){
759 CFDataRef publicKeyData = SOSCopyDeviceBackupPublicKey(secret, error);
760
761 return SOSSetNewPublicBackupKey(publicKeyData, error);
762 }
763
764 bool SOSCCRegisterSingleRecoverySecret(CFDataRef aks_bag, bool forV0Only, CFErrorRef *error){
765 sec_trace_enter_api(NULL);
766 sec_trace_return_bool_api(^{
767 do_if_registered(soscc_RegisterSingleRecoverySecret, aks_bag, forV0Only, error);
768 return keybag_and_bool_to_bool_error_request(kSecXPCOpSetBagForAllSlices, aks_bag, forV0Only, error);
769 }, NULL);
770 }
771
772
773 static bool label_and_password_to_bool_error_request(enum SecXPCOperation op,
774 CFStringRef user_label, CFDataRef user_password,
775 CFErrorRef* error)
776 {
777 __block bool result = false;
778
779 securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
780 CFStringPerformWithCString(user_label, ^(const char *utf8Str) {
781 xpc_dictionary_set_string(message, kSecXPCKeyUserLabel, utf8Str);
782 });
783 xpc_dictionary_set_data(message, kSecXPCKeyUserPassword, CFDataGetBytePtr(user_password), CFDataGetLength(user_password));
784 return true;
785 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
786 result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
787 return result;
788 });
789
790 return result;
791 }
792
793 static bool label_and_password_and_dsid_to_bool_error_request(enum SecXPCOperation op,
794 CFStringRef user_label, CFDataRef user_password,
795 CFStringRef dsid, CFErrorRef* error)
796 {
797 __block bool result = false;
798
799 securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
800 CFStringPerformWithCString(user_label, ^(const char *utf8Str) {
801 xpc_dictionary_set_string(message, kSecXPCKeyUserLabel, utf8Str);
802 });
803 CFStringPerformWithCString(dsid, ^(const char *utr8StrDSID) {
804 xpc_dictionary_set_string(message, kSecXPCKeyDSID, utr8StrDSID);
805 });
806 xpc_dictionary_set_data(message, kSecXPCKeyUserPassword, CFDataGetBytePtr(user_password), CFDataGetLength(user_password));
807 return true;
808 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
809 result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
810 return result;
811 });
812
813 return result;
814 }
815
816 static bool deviceid_to_bool_error_request(enum SecXPCOperation op,
817 CFStringRef IDS,
818 CFErrorRef* error)
819 {
820 __block bool result = false;
821
822 securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
823 CFStringPerformWithCString(IDS, ^(const char *utf8Str) {
824 xpc_dictionary_set_string(message, kSecXPCKeyDeviceID, utf8Str);
825 });
826 return true;
827 }, ^bool(xpc_object_t response, CFErrorRef *error) {
828 result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
829 if(result == false){
830 xpc_object_t xpc_error = xpc_dictionary_get_value(response, kSecXPCKeyError);
831 if (xpc_error && error) {
832 *error = SecCreateCFErrorWithXPCObject(xpc_error);
833 }
834 }
835 return result;
836 });
837
838 return result;
839 }
840
841 static int idsDict_to_bool_error_request(enum SecXPCOperation op,
842 CFDictionaryRef IDS,
843 CFErrorRef* error)
844 {
845 __block int result = false;
846
847 securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
848 SecXPCDictionarySetPListOptional(message, kSecXPCKeyIDSMessage, IDS, error);
849 return true;
850 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
851 int64_t temp_result = xpc_dictionary_get_int64(response, kSecXPCKeyResult);
852 if ((temp_result >= INT32_MIN) && (temp_result <= INT32_MAX)) {
853 result = (int)temp_result;
854 }
855 return result;
856 });
857
858 return result;
859 }
860
861 static bool idscommand_to_bool_error_request(enum SecXPCOperation op,
862 CFStringRef idsMessage,
863 CFErrorRef* error)
864 {
865 __block bool result = false;
866
867 securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
868 CFStringPerformWithCString(idsMessage, ^(const char *utf8Str) {
869 xpc_dictionary_set_string(message, kSecXPCKeySendIDSMessage, utf8Str);
870 });
871 return true;
872 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
873 result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
874 return result;
875 });
876
877 return result;
878 }
879
880 bool SOSCCRegisterUserCredentials(CFStringRef user_label, CFDataRef user_password, CFErrorRef* error)
881 {
882 secnotice("sosops", "SOSCCRegisterUserCredentials - calling SOSCCSetUserCredentials!! %@\n", user_label);
883 return SOSCCSetUserCredentials(user_label, user_password, error);
884 }
885
886 bool SOSCCSetUserCredentials(CFStringRef user_label, CFDataRef user_password, CFErrorRef* error)
887 {
888 secnotice("sosops", "SOSCCSetUserCredentials!! %@\n", user_label);
889 sec_trace_enter_api(CFSTR("user_label=%@"), user_label);
890 sec_trace_return_bool_api(^{
891 do_if_registered(soscc_SetUserCredentials, user_label, user_password, error);
892
893 return label_and_password_to_bool_error_request(kSecXPCOpSetUserCredentials, user_label, user_password, error);
894 }, NULL)
895 }
896
897 bool SOSCCSetUserCredentialsAndDSID(CFStringRef user_label, CFDataRef user_password, CFStringRef dsid, CFErrorRef *error)
898 {
899 secnotice("sosops", "SOSCCSetUserCredentialsAndDSID!! %@\n", user_label);
900 sec_trace_enter_api(CFSTR("user_label=%@"), user_label);
901 sec_trace_return_bool_api(^{
902 do_if_registered(soscc_SetUserCredentialsAndDSID, user_label, user_password, dsid, error);
903 if(dsid == NULL){
904 return label_and_password_and_dsid_to_bool_error_request(kSecXPCOpSetUserCredentialsAndDSID, user_label, user_password, CFSTR(""), error);
905 }
906 else{
907 return label_and_password_and_dsid_to_bool_error_request(kSecXPCOpSetUserCredentialsAndDSID, user_label, user_password, dsid, error);
908 }
909 }, NULL)
910
911 }
912 bool SOSCCSetDeviceID(CFStringRef IDS, CFErrorRef* error)
913 {
914 secnotice("sosops", "SOSCCSetDeviceID!! %@\n", IDS);
915 sec_trace_enter_api(NULL);
916 sec_trace_return_bool_api(^{
917 CFErrorRef localError = NULL;
918 do_if_registered(soscc_SetDeviceID, IDS, &localError);
919 bool result = deviceid_to_bool_error_request(kSecXPCOpSetDeviceID, IDS, &localError);
920 if(localError){
921 *error = CFRetainSafe(localError);
922 }
923 return result;
924 }, NULL)
925 }
926
927 bool SOSCCIDSServiceRegistrationTest(CFStringRef message, CFErrorRef *error)
928 {
929 secnotice("sosops", "SOSCCSendIDSTestMessage!! %@\n", message);
930 sec_trace_enter_api(NULL);
931 sec_trace_return_bool_api(^{
932 do_if_registered(soscc_CheckIDSRegistration, message, error);
933 return idscommand_to_bool_error_request(kSecXPCOpSendIDSMessage, message, error);
934 }, NULL)
935 }
936
937 bool SOSCCIDSPingTest(CFStringRef message, CFErrorRef *error)
938 {
939 secnotice("sosops", "SOSCCSendIDSTestMessage!! %@\n", message);
940 sec_trace_enter_api(NULL);
941 sec_trace_return_bool_api(^{
942 do_if_registered(soscc_PingTest, message, error);
943 return idscommand_to_bool_error_request(kSecXPCOpPingTest, message, error);
944 }, NULL)
945 }
946
947 bool SOSCCIDSDeviceIDIsAvailableTest(CFErrorRef *error)
948 {
949 secnotice("sosops", "SOSCCIDSDeviceIDIsAvailableTest!!\n");
950 sec_trace_enter_api(NULL);
951 sec_trace_return_bool_api(^{
952 do_if_registered(soscc_GetIDSIDFromIDS, error);
953 return simple_bool_error_request(kSecXPCOpIDSDeviceID, error);
954 }, NULL)
955 }
956
957 HandleIDSMessageReason SOSCCHandleIDSMessage(CFDictionaryRef IDS, CFErrorRef* error)
958 {
959 secnotice("sosops", "SOSCCHandleIDSMessage!! %@\n", IDS);
960 sec_trace_enter_api(NULL);
961 sec_trace_return_api(HandleIDSMessageReason, ^{
962 do_if_registered(soscc_HandleIDSMessage, IDS, error);
963 return (HandleIDSMessageReason) idsDict_to_bool_error_request(kSecXPCOpHandleIDSMessage, IDS, error);
964 }, NULL)
965 }
966
967 bool SOSCCTryUserCredentials(CFStringRef user_label, CFDataRef user_password, CFErrorRef* error)
968 {
969 sec_trace_enter_api(CFSTR("user_label=%@"), user_label);
970 sec_trace_return_bool_api(^{
971 do_if_registered(soscc_TryUserCredentials, user_label, user_password, error);
972
973 return label_and_password_to_bool_error_request(kSecXPCOpTryUserCredentials, user_label, user_password, error);
974 }, NULL)
975 }
976
977
978 bool SOSCCCanAuthenticate(CFErrorRef* error) {
979 sec_trace_enter_api(NULL);
980 sec_trace_return_bool_api(^{
981 do_if_registered(soscc_CanAuthenticate, error);
982
983 return simple_bool_error_request(kSecXPCOpCanAuthenticate, error);
984 }, NULL)
985 }
986
987 bool SOSCCPurgeUserCredentials(CFErrorRef* error) {
988 sec_trace_enter_api(NULL);
989 sec_trace_return_bool_api(^{
990 do_if_registered(soscc_PurgeUserCredentials, error);
991
992 return simple_bool_error_request(kSecXPCOpPurgeUserCredentials, error);
993 }, NULL)
994 }
995
996 enum DepartureReason SOSCCGetLastDepartureReason(CFErrorRef *error) {
997 sec_trace_enter_api(NULL);
998 sec_trace_return_api(enum DepartureReason, ^{
999 do_if_registered(soscc_GetLastDepartureReason, error);
1000
1001 return (enum DepartureReason) simple_int_error_request(kSecXPCOpGetLastDepartureReason, error);
1002 }, NULL)
1003 }
1004
1005 bool SOSCCSetLastDepartureReason(enum DepartureReason reason, CFErrorRef *error) {
1006 sec_trace_enter_api(NULL);
1007 sec_trace_return_api(bool, ^{
1008 do_if_registered(soscc_SetLastDepartureReason, reason, error);
1009 return securityd_send_sync_and_do(kSecXPCOpSetLastDepartureReason, error,
1010 ^bool(xpc_object_t message, CFErrorRef *error) {
1011 xpc_dictionary_set_int64(message, kSecXPCKeyReason, reason);
1012 return true;
1013 },
1014 ^bool(xpc_object_t response, __unused CFErrorRef *error) {
1015 return xpc_dictionary_get_bool(response, kSecXPCKeyResult);
1016 }
1017 );
1018 }, NULL)
1019 }
1020
1021 CFStringRef SOSCCCopyIncompatibilityInfo(CFErrorRef* error) {
1022 sec_trace_enter_api(NULL);
1023 sec_trace_return_api(CFStringRef, ^{
1024 do_if_registered(soscc_CopyIncompatibilityInfo, error);
1025
1026 return simple_cfstring_error_request(kSecXPCOpCopyIncompatibilityInfo, error);
1027 }, NULL)
1028 }
1029
1030 CFStringRef SOSCCCopyDeviceID(CFErrorRef* error)
1031 {
1032 sec_trace_enter_api(NULL);
1033 sec_trace_return_api(CFStringRef, ^{
1034 do_if_registered(soscc_CopyDeviceID, error);
1035 CFStringRef deviceID = simple_cfstring_error_request(kSecXPCOpRequestDeviceID, error);
1036 return deviceID;
1037 }, NULL)
1038 }
1039
1040 bool SOSCCProcessEnsurePeerRegistration(CFErrorRef* error){
1041 secnotice("updates", "enter SOSCCProcessEnsurePeerRegistration");
1042 sec_trace_enter_api(NULL);
1043 sec_trace_return_bool_api(^{
1044 do_if_registered(soscc_EnsurePeerRegistration, error);
1045
1046 return simple_bool_error_request(soscc_EnsurePeerRegistration_id, error);
1047 }, NULL)
1048 }
1049
1050
1051 SyncWithAllPeersReason SOSCCProcessSyncWithAllPeers(CFErrorRef* error)
1052 {
1053 sec_trace_enter_api(NULL);
1054 sec_trace_return_api(SyncWithAllPeersReason, ^{
1055 do_if_registered(soscc_ProcessSyncWithAllPeers, error);
1056
1057 return (SyncWithAllPeersReason) simple_int_error_request(kSecXPCOpProcessSyncWithAllPeers, error);
1058 }, NULL)
1059 }
1060
1061 CFStringRef SOSCCGetStatusDescription(SOSCCStatus status)
1062 {
1063 switch (status) {
1064 case kSOSCCInCircle:
1065 return CFSTR("InCircle");
1066 case kSOSCCNotInCircle:
1067 return CFSTR("NotInCircle");
1068 case kSOSCCRequestPending:
1069 return CFSTR("RequestPending");
1070 case kSOSCCCircleAbsent:
1071 return CFSTR("CircleAbsent");
1072 case kSOSCCError:
1073 return CFSTR("InternalError");
1074 default:
1075 return CFSTR("Unknown Status (%d)");
1076 };
1077 }
1078
1079 #if 0
1080 kSOSCCGeneralViewError = -1,
1081 kSOSCCViewMember = 0,
1082 kSOSCCViewNotMember = 1,
1083 kSOSCCViewNotQualified = 2,
1084 kSOSCCNoSuchView = 3,
1085 #endif
1086
1087 static int64_t name_action_to_code_request(enum SecXPCOperation op, uint16_t error_result,
1088 CFStringRef name, uint64_t action, CFErrorRef *error) {
1089 __block int64_t result = error_result;
1090
1091 securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
1092 CFStringPerformWithCString(name, ^(const char *utf8Str) {
1093 xpc_dictionary_set_string(message, kSecXPCKeyViewName, utf8Str);
1094 });
1095 xpc_dictionary_set_int64(message, kSecXPCKeyViewActionCode, action);
1096 return true;
1097 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
1098 if (response && xpc_dictionary_entry_is_type(response, kSecXPCKeyResult, XPC_TYPE_INT64)) {
1099 result = xpc_dictionary_get_int64(response, kSecXPCKeyResult);
1100 }
1101 return result != error_result;
1102 });
1103
1104 return result;
1105 }
1106
1107 SOSViewResultCode SOSCCView(CFStringRef view, SOSViewActionCode actionCode, CFErrorRef *error) {
1108 sec_trace_enter_api(NULL);
1109 sec_trace_return_api(SOSViewResultCode, ^{
1110 do_if_registered(soscc_View, view, actionCode, error);
1111
1112 return (SOSViewResultCode) name_action_to_code_request(kSecXPCOpView, kSOSCCGeneralViewError, view, actionCode, error);
1113 }, CFSTR("SOSViewResultCode=%d"))
1114 }
1115
1116
1117 bool SOSCCViewSet(CFSetRef enabledViews, CFSetRef disabledViews) {
1118 CFErrorRef *error = NULL;
1119 __block bool result = false;
1120
1121 sec_trace_enter_api(NULL);
1122 sec_trace_return_bool_api(^{
1123 do_if_registered(soscc_ViewSet, enabledViews, disabledViews);
1124 return securityd_send_sync_and_do(kSecXPCOpViewSet, error, ^bool(xpc_object_t message, CFErrorRef *error) {
1125 xpc_object_t enabledSetXpc = CreateXPCObjectWithCFSetRef(enabledViews, error);
1126 xpc_object_t disabledSetXpc = CreateXPCObjectWithCFSetRef(disabledViews, error);
1127 if (enabledSetXpc) xpc_dictionary_set_value(message, kSecXPCKeyEnabledViewsKey, enabledSetXpc);
1128 if (disabledSetXpc) xpc_dictionary_set_value(message, kSecXPCKeyDisabledViewsKey, disabledSetXpc);
1129 return (enabledSetXpc != NULL) || (disabledSetXpc != NULL) ;
1130 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
1131 result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
1132 return result;
1133 });
1134 }, NULL)
1135 }
1136
1137 SOSSecurityPropertyResultCode SOSCCSecurityProperty(CFStringRef property, SOSSecurityPropertyActionCode actionCode, CFErrorRef *error) {
1138 sec_trace_enter_api(NULL);
1139 sec_trace_return_api(SOSSecurityPropertyResultCode, ^{
1140 SOSSecurityPropertyResultCode result = kSOSCCGeneralSecurityPropertyError;
1141 do_if_registered(soscc_SecurityProperty, property, actionCode, error);
1142 xpc_object_t message = securityd_create_message(kSecXPCOpSecurityProperty, error);
1143 if (message) {
1144 int64_t bigac = actionCode;
1145 xpc_dictionary_set_string(message, kSecXPCKeyViewName, CFStringGetCStringPtr(property, kCFStringEncodingUTF8));
1146 xpc_dictionary_set_int64(message, kSecXPCKeyViewActionCode, bigac);
1147
1148 xpc_object_t response = securityd_message_with_reply_sync(message, error);
1149
1150 if (response && xpc_dictionary_entry_is_type(response, kSecXPCKeyResult, XPC_TYPE_INT64)) {
1151 result = (SOSSecurityPropertyResultCode) xpc_dictionary_get_int64(response, kSecXPCKeyResult);
1152 }
1153
1154 if (result == kSOSCCGeneralSecurityPropertyError) {
1155 if (response && securityd_message_no_error(response, error)) {
1156 char *desc = xpc_copy_description(response);
1157 SecCFCreateErrorWithFormat(0, sSecXPCErrorDomain, NULL, error, NULL, CFSTR("Remote error occurred/no info: %s"), desc);
1158 free((void *)desc);
1159 }
1160 }
1161 if(response)
1162 xpc_release(response);
1163 if(message)
1164 xpc_release(message);
1165 }
1166
1167 return result;
1168 }, CFSTR("SOSSecurityPropertyResultCode=%d"))
1169 }
1170
1171
1172 static bool sosIsViewSetSyncing(size_t n, CFStringRef *views) {
1173 __block bool retval = true;
1174
1175 SOSCCStatus cstatus = SOSCCThisDeviceIsInCircle(NULL);
1176 if(cstatus == kSOSCCInCircle) {
1177 for(size_t i = 0; i < n; i++) {
1178 SOSViewResultCode vstatus = SOSCCView(views[i], kSOSCCViewQuery, NULL);
1179 if(vstatus != kSOSCCViewMember) retval = false;
1180 }
1181 } else {
1182 retval = false;
1183 }
1184 return retval;
1185 }
1186
1187 bool SOSCCIsIcloudKeychainSyncing(void) {
1188 CFStringRef views[] = { kSOSViewKeychainV0 };
1189 return sosIsViewSetSyncing(1, views);
1190 }
1191
1192 bool SOSCCIsSafariSyncing(void) {
1193 CFStringRef views[] = { kSOSViewAutofillPasswords, kSOSViewSafariCreditCards };
1194 return sosIsViewSetSyncing(2, views);
1195 }
1196
1197 bool SOSCCIsAppleTVSyncing(void) {
1198 CFStringRef views[] = { kSOSViewAppleTV };
1199 return sosIsViewSetSyncing(1, views);
1200 }
1201
1202 bool SOSCCIsHomeKitSyncing(void) {
1203 CFStringRef views[] = { kSOSViewHomeKit };
1204 return sosIsViewSetSyncing(1, views);
1205 }
1206
1207 bool SOSCCIsWiFiSyncing(void) {
1208 CFStringRef views[] = { kSOSViewWiFi };
1209 return sosIsViewSetSyncing(1, views);
1210 }
1211
1212 bool SOSCCSetEscrowRecord(CFStringRef escrow_label, uint64_t tries, CFErrorRef *error ){
1213 secnotice("escrow", "enter SOSCCSetEscrowRecord");
1214 sec_trace_enter_api(NULL);
1215 sec_trace_return_bool_api(^{
1216 do_if_registered(soscc_SetEscrowRecords, escrow_label, tries, error);
1217
1218 return escrow_to_bool_error_request(kSecXPCOpSetEscrowRecord, escrow_label, tries, error);
1219 }, NULL)
1220 }
1221
1222 CFDictionaryRef SOSCCCopyEscrowRecord(CFErrorRef *error){
1223 secnotice("escrow", "enter SOSCCCopyEscrowRecord");
1224 sec_trace_enter_api(NULL);
1225 sec_trace_return_api(CFDictionaryRef, ^{
1226 do_if_registered(soscc_CopyEscrowRecords, error);
1227
1228 return strings_to_dictionary_error_request(kSecXPCOpGetEscrowRecord, error);
1229 }, CFSTR("return=%@"))
1230
1231 }
1232
1233 bool SOSCCCheckPeerAvailability(CFErrorRef *error){
1234 secnotice("peer", "enter SOSCCCheckPeerAvailability");
1235 sec_trace_enter_api(NULL);
1236 sec_trace_return_bool_api(^{
1237 do_if_registered(soscc_PeerAvailability, error);
1238
1239 return simple_bool_error_request(kSecXPCOpCheckPeerAvailability, error);
1240 }, NULL)
1241
1242 }
1243
1244