]> git.saurik.com Git - apple/security.git/blob - OSX/sec/SOSCircle/SecureObjectSync/SOSCloudCircle.c
1582415848a95fc50fc8d19fa2fa2ddb6a58ca59
[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 <Security/SecuritydXPC.h>
62 #include "SOSPeerInfoDER.h"
63
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";
69 const char * kSOSCCRecoveryKeyChanged = "com.apple.security.secureobjectsync.recoverykeychanged";
70 const CFStringRef kSOSErrorDomain = CFSTR("com.apple.security.sos.error");
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 bool deviceid_to_bool_error_request(enum SecXPCOperation op,
140 CFStringRef IDS,
141 CFErrorRef* error)
142 {
143 __block bool result = false;
144
145 securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
146 CFStringPerformWithCString(IDS, ^(const char *utf8Str) {
147 xpc_dictionary_set_string(message, kSecXPCKeyDeviceID, utf8Str);
148 });
149 return true;
150 }, ^bool(xpc_object_t response, CFErrorRef *error) {
151 result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
152 return result;
153 });
154
155 return result;
156 }
157
158 static SOSRingStatus cfstring_to_uint64_request(enum SecXPCOperation op, CFStringRef string, CFErrorRef* error)
159 {
160 __block bool result = false;
161
162 secdebug("sosops","enter - operation: %d", op);
163 securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
164 xpc_object_t xString = _CFXPCCreateXPCObjectFromCFObject(string);
165 bool success = false;
166 if (xString){
167 xpc_dictionary_set_value(message, kSecXPCKeyString, xString);
168 success = true;
169 xpc_release(xString);
170 }
171 return success;
172 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
173 result = xpc_dictionary_get_int64(response, kSecXPCKeyResult);
174 return result;
175 });
176 return result;
177 }
178
179 static CFStringRef simple_cfstring_error_request(enum SecXPCOperation op, CFErrorRef* error)
180 {
181 __block CFStringRef result = NULL;
182
183 secdebug("sosops","enter - operation: %d", op);
184 securityd_send_sync_and_do(op, error, NULL, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
185 const char *c_string = xpc_dictionary_get_string(response, kSecXPCKeyResult);
186
187 if (c_string) {
188 result = CFStringCreateWithBytes(kCFAllocatorDefault, (const UInt8*)c_string, strlen(c_string), kCFStringEncodingUTF8, false);
189 }
190
191 return c_string != NULL;
192 });
193 return result;
194 }
195
196 static bool simple_bool_error_request(enum SecXPCOperation op, CFErrorRef* error)
197 {
198 __block bool result = false;
199
200 secdebug("sosops","enter - operation: %d", op);
201 securityd_send_sync_and_do(op, error, NULL, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
202 result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
203 return result;
204 });
205 return result;
206 }
207
208 static bool SecXPCDictionarySetPeerInfoData(xpc_object_t message, const char *key, SOSPeerInfoRef peerInfo, CFErrorRef *error) {
209 bool success = false;
210 CFDataRef peerData = SOSPeerInfoCopyEncodedData(peerInfo, kCFAllocatorDefault, error);
211 if (peerData) {
212 success = SecXPCDictionarySetData(message, key, peerData, error);
213 }
214 CFReleaseNull(peerData);
215 return success;
216 }
217
218 static bool peer_info_to_bool_error_request(enum SecXPCOperation op, SOSPeerInfoRef peerInfo, CFErrorRef* error)
219 {
220 __block bool result = false;
221
222 secdebug("sosops","enter - operation: %d", op);
223 securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
224 return SecXPCDictionarySetPeerInfoData(message, kSecXPCKeyPeerInfo, peerInfo, error);
225 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
226 result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
227 return result;
228 });
229 return result;
230 }
231
232 static CFBooleanRef cfarray_to_cfboolean_error_request(enum SecXPCOperation op, CFArrayRef views, CFErrorRef* error)
233 {
234 __block bool result = false;
235
236 secdebug("sosops","enter - operation: %d", op);
237 bool noError = securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
238 return SecXPCDictionarySetPList(message, kSecXPCKeyArray, views, error);
239 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
240 result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
241 return true;
242 });
243 return noError ? (result ? kCFBooleanTrue : kCFBooleanFalse) : NULL;
244 }
245
246
247 static CFSetRef cfset_cfset_to_cfset_error_request(enum SecXPCOperation op, CFSetRef set1, CFSetRef set2, CFErrorRef* error)
248 {
249 __block CFSetRef result = NULL;
250
251 secdebug("sosops","enter - operation: %d", op);
252 bool noError = securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
253 return SecXPCDictionarySetPList(message, kSecXPCKeySet, set1, error) && SecXPCDictionarySetPList(message, kSecXPCKeySet2, set2, error);
254 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
255 result = SecXPCDictionaryCopySet(response, kSecXPCKeyResult, error);
256 return result;
257 });
258
259 if (!noError) {
260 CFReleaseNull(result);
261 }
262 return result;
263 }
264
265
266 static bool escrow_to_bool_error_request(enum SecXPCOperation op, CFStringRef escrow_label, uint64_t tries, CFErrorRef* error)
267 {
268 __block bool result = false;
269
270 securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
271
272 bool success = false;
273 xpc_object_t xEscrowLabel = _CFXPCCreateXPCObjectFromCFObject(escrow_label);
274 if (xEscrowLabel){
275 xpc_dictionary_set_value(message, kSecXPCKeyEscrowLabel, xEscrowLabel);
276 success = true;
277 xpc_release(xEscrowLabel);
278 }
279 if(tries){
280 xpc_dictionary_set_int64(message, kSecXPCKeyTriesLabel, tries);
281 success = true;
282 }
283
284 return success;
285 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
286 result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
287 return result;
288 });
289 return result;
290 }
291
292 static CF_RETURNS_RETAINED CFArrayRef simple_array_error_request(enum SecXPCOperation op, CFErrorRef* error)
293 {
294 __block CFArrayRef result = NULL;
295
296 secdebug("sosops","enter - operation: %d", op);
297 if (securityd_send_sync_and_do(op, error, NULL, ^bool(xpc_object_t response, CFErrorRef *error) {
298 xpc_object_t temp_result = xpc_dictionary_get_value(response, kSecXPCKeyResult);
299 result = _CFXPCCreateCFObjectFromXPCObject(temp_result);
300 return result != NULL;
301 })) {
302 if (!isArray(result)) {
303 SOSErrorCreate(kSOSErrorUnexpectedType, error, NULL, CFSTR("Expected array, got: %@"), result);
304 CFReleaseNull(result);
305 }
306 }
307 return result;
308 }
309
310 static CF_RETURNS_RETAINED CFArrayRef der_array_error_request(enum SecXPCOperation op, CFErrorRef* error)
311 {
312 __block CFArrayRef result = NULL;
313
314 secdebug("sosops","enter - operation: %d", op);
315 if (securityd_send_sync_and_do(op, error, NULL, ^bool(xpc_object_t response, CFErrorRef *error) {
316 size_t length = 0;
317 const uint8_t* bytes = xpc_dictionary_get_data(response, kSecXPCKeyResult, &length);
318 der_decode_plist(kCFAllocatorDefault, 0, (CFPropertyListRef*) &result, error, bytes, bytes + length);
319
320 return result != NULL;
321 })) {
322 if (!isArray(result)) {
323 SOSErrorCreate(kSOSErrorUnexpectedType, error, NULL, CFSTR("Expected array, got: %@"), result);
324 CFReleaseNull(result);
325 }
326 }
327 return result;
328 }
329
330 static CFDictionaryRef strings_to_dictionary_error_request(enum SecXPCOperation op, CFErrorRef* error)
331 {
332 __block CFDictionaryRef result = NULL;
333
334 secdebug("sosops","enter - operation: %d", op);
335
336 if (securityd_send_sync_and_do(op, error, NULL, ^bool(xpc_object_t response, CFErrorRef *error) {
337 xpc_object_t temp_result = xpc_dictionary_get_value(response, kSecXPCKeyResult);
338 if(temp_result)
339 result = _CFXPCCreateCFObjectFromXPCObject(temp_result);
340 return result != NULL;
341 })){
342
343 if (!isDictionary(result)) {
344 SOSErrorCreate(kSOSErrorUnexpectedType, error, NULL, CFSTR("Expected dictionary, got: %@"), result);
345 CFReleaseNull(result);
346 }
347
348 }
349 return result;
350 }
351
352 static int simple_int_error_request(enum SecXPCOperation op, CFErrorRef* error)
353 {
354 __block int result = 0;
355
356 secdebug("sosops","enter - operation: %d", op);
357 securityd_send_sync_and_do(op, error, NULL, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
358 int64_t temp_result = xpc_dictionary_get_int64(response, kSecXPCKeyResult);
359 if ((temp_result >= INT32_MIN) && (temp_result <= INT32_MAX)) {
360 result = (int)temp_result;
361 }
362 return result;
363 });
364 return result;
365 }
366
367 static SOSPeerInfoRef peer_info_error_request(enum SecXPCOperation op, CFErrorRef* error)
368 {
369 SOSPeerInfoRef result = NULL;
370 __block CFDataRef data = NULL;
371
372 secdebug("sosops","enter - operation: %d", op);
373 securityd_send_sync_and_do(op, error, NULL, ^bool(xpc_object_t response, CFErrorRef *error) {
374 xpc_object_t temp_result = xpc_dictionary_get_value(response, kSecXPCKeyResult);
375 if (response && (NULL != temp_result)) {
376 data = _CFXPCCreateCFObjectFromXPCObject(temp_result);
377 }
378 return data != NULL;
379 });
380
381 if (!isData(data)) {
382 SOSErrorCreate(kSOSErrorUnexpectedType, error, NULL, CFSTR("Expected CFData, got: %@"), result);
383 }
384
385 if (data) {
386 result = SOSPeerInfoCreateFromData(kCFAllocatorDefault, error, data);
387 }
388 CFReleaseNull(data);
389 return result;
390 }
391
392 static CFDataRef data_to_error_request(enum SecXPCOperation op, CFErrorRef *error)
393 {
394 __block CFDataRef result = NULL;
395
396 secdebug("sosops", "enter -- operation: %d", op);
397 securityd_send_sync_and_do(op, error, NULL, ^bool(xpc_object_t response, CFErrorRef *error) {
398 xpc_object_t temp_result = xpc_dictionary_get_value(response, kSecXPCKeyResult);
399 if (response && (NULL != temp_result)) {
400 result = _CFXPCCreateCFObjectFromXPCObject(temp_result);
401 }
402 return result != NULL;
403 });
404
405 if (!isData(result)) {
406 SOSErrorCreate(kSOSErrorUnexpectedType, error, NULL, CFSTR("Expected CFData, got: %@"), result);
407 return NULL;
408 }
409
410 return result;
411 }
412
413 static CFArrayRef array_of_info_error_request(enum SecXPCOperation op, CFErrorRef* error)
414 {
415 __block CFArrayRef result = NULL;
416
417 secdebug("sosops","enter - operation: %d", op);
418 securityd_send_sync_and_do(op, error, NULL, ^bool(xpc_object_t response, CFErrorRef *error) {
419 xpc_object_t encoded_array = xpc_dictionary_get_value(response, kSecXPCKeyResult);
420 if (response && (NULL != encoded_array)) {
421 result = CreateArrayOfPeerInfoWithXPCObject(encoded_array, error);
422 }
423 return result != NULL;
424 });
425
426 if (!isArray(result)) {
427 SOSErrorCreate(kSOSErrorUnexpectedType, error, NULL, CFSTR("Expected array, got: %@"), result);
428 CFReleaseNull(result);
429 }
430 return result;
431 }
432
433 static CF_RETURNS_RETAINED SOSPeerInfoRef data_to_peer_info_error_request(enum SecXPCOperation op, CFDataRef secret, CFErrorRef* error)
434 {
435 __block SOSPeerInfoRef result = false;
436 __block CFDataRef data = NULL;
437
438 secdebug("sosops", "enter - operation: %d", op);
439 securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
440 xpc_object_t xsecretData = _CFXPCCreateXPCObjectFromCFObject(secret);
441 bool success = false;
442 if (xsecretData){
443 xpc_dictionary_set_value(message, kSecXPCKeyNewPublicBackupKey, xsecretData);
444 success = true;
445 xpc_release(xsecretData);
446 }
447 return success;
448 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
449 xpc_object_t temp_result = xpc_dictionary_get_value(response, kSecXPCKeyResult);
450 if (response && (NULL != temp_result)) {
451 data = _CFXPCCreateCFObjectFromXPCObject(temp_result);
452 }
453 return result != NULL;
454 });
455
456 if (!isData(data)) {
457 SOSErrorCreate(kSOSErrorUnexpectedType, error, NULL, CFSTR("Expected CFData, got: %@"), result);
458 }
459
460 if (data) {
461 result = SOSPeerInfoCreateFromData(kCFAllocatorDefault, error, data);
462 }
463 CFReleaseNull(data);
464 return result;
465 }
466
467 static bool keybag_and_bool_to_bool_error_request(enum SecXPCOperation op, CFDataRef data, bool include, CFErrorRef* error)
468 {
469 secdebug("sosops", "enter - operation: %d", op);
470 return securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
471 xpc_object_t xData = _CFXPCCreateXPCObjectFromCFObject(data);
472 bool success = false;
473 if (xData){
474 xpc_dictionary_set_value(message, kSecXPCKeyKeybag, xData);
475 xpc_release(xData);
476 success = true;
477 }
478 xpc_dictionary_set_bool(message, kSecXPCKeyIncludeV0, include);
479 return success;
480 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
481 return xpc_dictionary_get_bool(response, kSecXPCKeyResult);
482 });
483 }
484
485 static bool recovery_and_bool_to_bool_error_request(enum SecXPCOperation op, CFDataRef data, CFErrorRef* error)
486 {
487 secdebug("sosops", "enter - operation: %d", op);
488 return securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
489 xpc_object_t xData = _CFXPCCreateXPCObjectFromCFObject(data);
490 bool success = false;
491 if (xData){
492 xpc_dictionary_set_value(message, kSecXPCKeyRecoveryPublicKey, xData);
493 xpc_release(xData);
494 success = true;
495 }
496 return success;
497 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
498 return xpc_dictionary_get_bool(response, kSecXPCKeyResult);
499 });
500 }
501
502 static bool info_array_to_bool_error_request(enum SecXPCOperation op, CFArrayRef peer_infos, CFErrorRef* error)
503 {
504 __block bool result = false;
505
506 secdebug("sosops", "enter - operation: %d", op);
507 securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
508 xpc_object_t encoded_peers = CreateXPCObjectWithArrayOfPeerInfo(peer_infos, error);
509 if (encoded_peers)
510 xpc_dictionary_set_value(message, kSecXPCKeyPeerInfoArray, encoded_peers);
511 return encoded_peers != NULL;
512 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
513 result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
514 return result;
515 });
516 return result;
517 }
518
519 static bool uint64_t_to_bool_error_request(enum SecXPCOperation op,
520 uint64_t number,
521 CFErrorRef* error)
522 {
523 __block bool result = false;
524
525 securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
526 xpc_dictionary_set_uint64(message, kSecXPCLimitInMinutes, number);
527 return true;
528 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
529 result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
530 return result;
531 });
532
533 return result;
534 }
535
536 static bool cfstring_and_cfdata_to_cfdata_cfdata_error_request(enum SecXPCOperation op, CFStringRef viewName, CFDataRef input, CFDataRef* data, CFDataRef* data2, CFErrorRef* error) {
537 secdebug("sosops", "enter - operation: %d", op);
538 __block bool result = false;
539 securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
540 xpc_object_t xviewname = _CFXPCCreateXPCObjectFromCFObject(viewName);
541 xpc_object_t xinput = _CFXPCCreateXPCObjectFromCFObject(input);
542 bool success = false;
543 if (xviewname && xinput){
544 xpc_dictionary_set_value(message, kSecXPCKeyViewName, xviewname);
545 xpc_dictionary_set_value(message, kSecXPCData, xinput);
546 success = true;
547 xpc_release(xviewname);
548 xpc_release(xinput);
549 }
550 return success;
551 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
552 result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
553
554 xpc_object_t temp_result = xpc_dictionary_get_value(response, kSecXPCData);
555 if (response && (NULL != temp_result) && data) {
556 *data = _CFXPCCreateCFObjectFromXPCObject(temp_result);
557 }
558 temp_result = xpc_dictionary_get_value(response, kSecXPCKeyKeybag);
559 if (response && (NULL != temp_result) && data2) {
560 *data2 = _CFXPCCreateCFObjectFromXPCObject(temp_result);
561 }
562
563 return result;
564 });
565
566 if (data &&!isData(*data)) {
567 SOSErrorCreate(kSOSErrorUnexpectedType, error, NULL, CFSTR("Expected CFData, got: %@"), *data);
568 }
569 if (data2 &&!isData(*data2)) {
570 SOSErrorCreate(kSOSErrorUnexpectedType, error, NULL, CFSTR("Expected CFData, got: %@"), *data2);
571 }
572
573 return result;
574 }
575
576 static bool set_hsa2_autoaccept_error_request(enum SecXPCOperation op, CFDataRef pubKey, CFErrorRef *error)
577 {
578 __block bool result = false;
579
580 sec_trace_enter_api(NULL);
581 securityd_send_sync_and_do(op, error, ^(xpc_object_t message,
582 CFErrorRef *error) {
583 xpc_object_t xpubkey = _CFXPCCreateXPCObjectFromCFObject(pubKey);
584 bool success = false;
585 if (xpubkey) {
586 xpc_dictionary_set_value(message,
587 kSecXPCKeyHSA2AutoAcceptInfo, xpubkey);
588 success = true;
589 xpc_release(xpubkey);
590 }
591
592 return success;
593 }, ^(xpc_object_t response, __unused CFErrorRef *error) {
594 result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
595 return (bool)true;
596 });
597
598 return result;
599 }
600
601
602
603 static bool cfdata_error_request_returns_bool(enum SecXPCOperation op, CFDataRef thedata, CFErrorRef *error) {
604 __block bool result = false;
605
606 sec_trace_enter_api(NULL);
607 securityd_send_sync_and_do(op, error, ^(xpc_object_t message, CFErrorRef *error) {
608 xpc_object_t xdata = _CFXPCCreateXPCObjectFromCFObject(thedata);
609 bool success = false;
610 if (xdata) {
611 xpc_dictionary_set_value(message, kSecXPCData, xdata);
612 success = true;
613 xpc_release(xdata);
614 }
615
616 return success;
617 }, ^(xpc_object_t response, __unused CFErrorRef *error) {
618 result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
619 return (bool)true;
620 });
621
622 return result;
623 }
624
625
626 static CFDataRef cfdata_error_request_returns_cfdata(enum SecXPCOperation op, CFDataRef thedata, CFErrorRef *error) {
627 __block CFDataRef result = NULL;
628
629 sec_trace_enter_api(NULL);
630 securityd_send_sync_and_do(op, error, ^(xpc_object_t message, CFErrorRef *error) {
631 xpc_object_t xdata = _CFXPCCreateXPCObjectFromCFObject(thedata);
632 bool success = false;
633 if (xdata) {
634 xpc_dictionary_set_value(message, kSecXPCData, xdata);
635 success = true;
636 xpc_release(xdata);
637 }
638 return success;
639 }, ^(xpc_object_t response, __unused CFErrorRef *error) {
640 xpc_object_t temp_result = xpc_dictionary_get_value(response, kSecXPCKeyResult);
641 if (response && (NULL != temp_result)) {
642 CFTypeRef object = _CFXPCCreateCFObjectFromXPCObject(temp_result);
643 result = copyIfData(object, error);
644 CFReleaseNull(object);
645 }
646 return (bool) (result != NULL);
647 });
648
649 return result;
650 }
651
652 bool SOSCCRequestToJoinCircle(CFErrorRef* error)
653 {
654 sec_trace_enter_api(NULL);
655 sec_trace_return_bool_api(^{
656 do_if_registered(soscc_RequestToJoinCircle, error);
657
658 return simple_bool_error_request(kSecXPCOpRequestToJoin, error);
659 }, NULL)
660 }
661
662 bool SOSCCRequestToJoinCircleAfterRestore(CFErrorRef* error)
663 {
664 sec_trace_enter_api(NULL);
665 sec_trace_return_bool_api(^{
666 do_if_registered(soscc_RequestToJoinCircleAfterRestore, error);
667
668 return simple_bool_error_request(kSecXPCOpRequestToJoinAfterRestore, error);
669 }, NULL)
670 }
671
672 bool SOSCCAccountHasPublicKey(CFErrorRef *error)
673 {
674
675 sec_trace_enter_api(NULL);
676 sec_trace_return_bool_api(^{
677 do_if_registered(soscc_AccountHasPublicKey, error);
678
679 return simple_bool_error_request(kSecXPCOpAccountHasPublicKey, error);
680 }, NULL)
681
682 }
683
684 bool SOSCCAccountIsNew(CFErrorRef *error)
685 {
686 sec_trace_enter_api(NULL);
687 sec_trace_return_bool_api(^{
688 do_if_registered(soscc_AccountIsNew, error);
689
690 return simple_bool_error_request(kSecXPCOpAccountIsNew, error);
691 }, NULL)
692 }
693
694 bool SOSCCWaitForInitialSync(CFErrorRef* error)
695 {
696 sec_trace_enter_api(NULL);
697 sec_trace_return_bool_api(^{
698 do_if_registered(soscc_WaitForInitialSync, error);
699
700 return simple_bool_error_request(kSecXPCOpWaitForInitialSync, error);
701 }, NULL)
702 }
703
704 CFArrayRef SOSCCCopyYetToSyncViewsList(CFErrorRef* error)
705 {
706 sec_trace_enter_api(NULL);
707 sec_trace_return_api(CFArrayRef, ^{
708 do_if_registered(soscc_CopyYetToSyncViewsList, error);
709
710 return simple_array_error_request(kSecXPCOpCopyYetToSyncViews, error);
711 }, NULL)
712 }
713
714 bool SOSCCRequestEnsureFreshParameters(CFErrorRef* error)
715 {
716 sec_trace_enter_api(NULL);
717 sec_trace_return_bool_api(^{
718 do_if_registered(soscc_RequestEnsureFreshParameters, error);
719
720 return simple_bool_error_request(kSecXPCOpRequestEnsureFreshParameters, error);
721 }, NULL)
722 }
723
724 CFStringRef SOSCCGetAllTheRings(CFErrorRef *error){
725 sec_trace_enter_api(NULL);
726 sec_trace_return_api(CFStringRef, ^{
727 do_if_registered(soscc_GetAllTheRings, error);
728
729
730 return simple_cfstring_error_request(kSecXPCOpGetAllTheRings, error);
731 }, NULL)
732 }
733 bool SOSCCApplyToARing(CFStringRef ringName, CFErrorRef* error)
734 {
735 sec_trace_enter_api(NULL);
736 sec_trace_return_bool_api(^{
737 do_if_registered(soscc_ApplyToARing, ringName, error);
738
739 return cfstring_to_error_request(kSecXPCOpApplyToARing, ringName, error);
740 }, NULL)
741 }
742
743 bool SOSCCWithdrawlFromARing(CFStringRef ringName, CFErrorRef* error)
744 {
745 sec_trace_enter_api(NULL);
746 sec_trace_return_bool_api(^{
747 do_if_registered(soscc_WithdrawlFromARing, ringName, error);
748
749 return cfstring_to_error_request(kSecXPCOpWithdrawlFromARing, ringName, error);
750 }, NULL)
751 }
752
753 SOSRingStatus SOSCCRingStatus(CFStringRef ringName, CFErrorRef* error)
754 {
755 sec_trace_enter_api(NULL);
756 sec_trace_return_api(SOSRingStatus, ^{
757 do_if_registered(soscc_RingStatus, ringName, error);
758
759 return cfstring_to_uint64_request(kSecXPCOpRingStatus, ringName, error);
760 }, CFSTR("SOSCCStatus=%d"))
761 }
762
763 bool SOSCCEnableRing(CFStringRef ringName, CFErrorRef* error)
764 {
765 sec_trace_enter_api(NULL);
766 sec_trace_return_bool_api(^{
767 do_if_registered(soscc_EnableRing, ringName, error);
768
769 return cfstring_to_error_request(kSecXPCOpEnableRing, ringName, error);
770 }, NULL)
771 }
772
773 bool SOSCCAccountSetToNew(CFErrorRef *error)
774 {
775 secwarning("SOSCCAccountSetToNew called");
776 sec_trace_enter_api(NULL);
777 sec_trace_return_bool_api(^{
778 do_if_registered(soscc_SetToNew, error);
779 return simple_bool_error_request(kSecXPCOpAccountSetToNew, error);
780 }, NULL)
781 }
782
783 bool SOSCCResetToOffering(CFErrorRef* error)
784 {
785 secwarning("SOSCCResetToOffering called");
786 sec_trace_enter_api(NULL);
787 sec_trace_return_bool_api(^{
788 do_if_registered(soscc_ResetToOffering, error);
789
790 return simple_bool_error_request(kSecXPCOpResetToOffering, error);
791 }, NULL)
792 }
793
794 bool SOSCCResetToEmpty(CFErrorRef* error)
795 {
796 secwarning("SOSCCResetToEmpty called");
797 sec_trace_enter_api(NULL);
798 sec_trace_return_bool_api(^{
799 do_if_registered(soscc_ResetToEmpty, error);
800
801 return simple_bool_error_request(kSecXPCOpResetToEmpty, error);
802 }, NULL)
803 }
804
805 bool SOSCCRemovePeersFromCircle(CFArrayRef peers, CFErrorRef* error)
806 {
807 sec_trace_enter_api(NULL);
808 sec_trace_return_bool_api(^{
809 do_if_registered(soscc_RemovePeersFromCircle, peers, error);
810
811 return info_array_to_bool_error_request(kSecXPCOpRemovePeersFromCircle, peers, error);
812 }, NULL)
813 }
814
815 bool SOSCCRemoveThisDeviceFromCircle(CFErrorRef* error)
816 {
817 sec_trace_enter_api(NULL);
818 sec_trace_return_bool_api(^{
819 do_if_registered(soscc_RemoveThisDeviceFromCircle, error);
820
821 return simple_bool_error_request(kSecXPCOpRemoveThisDeviceFromCircle, error);
822 }, NULL)
823 }
824
825 bool SOSCCLoggedOutOfAccount(CFErrorRef* error)
826 {
827 sec_trace_enter_api(NULL);
828 sec_trace_return_bool_api(^{
829 do_if_registered(soscc_LoggedOutOfAccount, error);
830
831 return simple_bool_error_request(kSecXPCOpLoggedOutOfAccount, error);
832 }, NULL)
833 }
834
835 bool SOSCCBailFromCircle_BestEffort(uint64_t limit_in_seconds, CFErrorRef* error)
836 {
837 sec_trace_enter_api(NULL);
838 sec_trace_return_bool_api(^{
839 do_if_registered(soscc_BailFromCircle, limit_in_seconds, error);
840
841 return uint64_t_to_bool_error_request(kSecXPCOpBailFromCircle, limit_in_seconds, error);
842 }, NULL)
843 }
844
845 bool SOSCCSignedOut(bool immediate, CFErrorRef* error)
846 {
847 uint64_t limit = strtoul(optarg, NULL, 10);
848
849 if(immediate)
850 return SOSCCRemoveThisDeviceFromCircle(error);
851 else
852 return SOSCCBailFromCircle_BestEffort(limit, error);
853
854 }
855
856 CFArrayRef SOSCCCopyPeerPeerInfo(CFErrorRef* error)
857 {
858 sec_trace_enter_api(NULL);
859 sec_trace_return_api(CFArrayRef, ^{
860 do_if_registered(soscc_CopyPeerInfo, error);
861
862 return array_of_info_error_request(kSecXPCOpCopyPeerPeerInfo, error);
863 }, CFSTR("return=%@"));
864 }
865
866 bool SOSCCSetAutoAcceptInfo(CFDataRef autoaccept, CFErrorRef *error)
867 {
868 sec_trace_return_bool_api(^{
869 do_if_registered(soscc_SetHSA2AutoAcceptInfo, autoaccept, error);
870
871 return set_hsa2_autoaccept_error_request(kSecXPCOpSetHSA2AutoAcceptInfo, autoaccept, error);
872 }, NULL)
873 }
874
875 CFArrayRef SOSCCCopyConcurringPeerPeerInfo(CFErrorRef* error)
876 {
877 sec_trace_enter_api(NULL);
878 sec_trace_return_api(CFArrayRef, ^{
879 do_if_registered(soscc_CopyConcurringPeerInfo, error);
880
881 return array_of_info_error_request(kSecXPCOpCopyConcurringPeerPeerInfo, error);
882 }, CFSTR("return=%@"));
883 }
884
885 CFArrayRef SOSCCCopyGenerationPeerInfo(CFErrorRef* error)
886 {
887 sec_trace_enter_api(NULL);
888 sec_trace_return_api(CFArrayRef, ^{
889 do_if_registered(soscc_CopyGenerationPeerInfo, error);
890
891 return simple_array_error_request(kSecXPCOpCopyGenerationPeerInfo, error);
892 }, CFSTR("return=%@"));
893 }
894
895 CFArrayRef SOSCCCopyApplicantPeerInfo(CFErrorRef* error)
896 {
897 sec_trace_enter_api(NULL);
898 sec_trace_return_api(CFArrayRef, ^{
899 do_if_registered(soscc_CopyApplicantPeerInfo, error);
900
901 return array_of_info_error_request(kSecXPCOpCopyApplicantPeerInfo, error);
902 }, CFSTR("return=%@"));
903 }
904
905 bool SOSCCValidateUserPublic(CFErrorRef* error){
906 sec_trace_enter_api(NULL);
907 sec_trace_return_api(bool, ^{
908 do_if_registered(soscc_ValidateUserPublic, error);
909
910 return simple_bool_error_request(kSecXPCOpValidateUserPublic, error);
911 }, NULL);
912 }
913
914 CFArrayRef SOSCCCopyValidPeerPeerInfo(CFErrorRef* error)
915 {
916 sec_trace_enter_api(NULL);
917 sec_trace_return_api(CFArrayRef, ^{
918 do_if_registered(soscc_CopyValidPeerPeerInfo, error);
919
920 return array_of_info_error_request(kSecXPCOpCopyValidPeerPeerInfo, error);
921 }, CFSTR("return=%@"));
922 }
923
924 CFArrayRef SOSCCCopyNotValidPeerPeerInfo(CFErrorRef* error)
925 {
926 sec_trace_enter_api(NULL);
927 sec_trace_return_api(CFArrayRef, ^{
928 do_if_registered(soscc_CopyNotValidPeerPeerInfo, error);
929
930 return array_of_info_error_request(kSecXPCOpCopyNotValidPeerPeerInfo, error);
931 }, CFSTR("return=%@"));
932 }
933
934 CFArrayRef SOSCCCopyRetirementPeerInfo(CFErrorRef* error)
935 {
936 sec_trace_enter_api(NULL);
937 sec_trace_return_api(CFArrayRef, ^{
938 do_if_registered(soscc_CopyRetirementPeerInfo, error);
939
940 return array_of_info_error_request(kSecXPCOpCopyRetirementPeerInfo, error);
941 }, CFSTR("return=%@"));
942 }
943
944 CFArrayRef SOSCCCopyViewUnawarePeerInfo(CFErrorRef* error)
945 {
946 sec_trace_enter_api(NULL);
947 sec_trace_return_api(CFArrayRef, ^{
948 do_if_registered(soscc_CopyViewUnawarePeerInfo, error);
949
950 return array_of_info_error_request(kSecXPCOpCopyViewUnawarePeerInfo, error);
951 }, CFSTR("return=%@"));
952 }
953
954 CFDataRef SOSCCCopyAccountState(CFErrorRef* error)
955 {
956 sec_trace_enter_api(NULL);
957 sec_trace_return_api(CFDataRef, ^{
958 do_if_registered(soscc_CopyAccountState, error);
959
960 return data_to_error_request(kSecXPCOpCopyAccountData, error);
961 }, CFSTR("return=%@"));
962 }
963
964 bool SOSCCDeleteAccountState(CFErrorRef *error)
965 {
966 sec_trace_enter_api(NULL);
967 sec_trace_return_api(bool, ^{
968 do_if_registered(soscc_DeleteAccountState, error);
969 return simple_bool_error_request(kSecXPCOpDeleteAccountData, error);
970 }, NULL);
971 }
972 CFDataRef SOSCCCopyEngineData(CFErrorRef* error)
973 {
974 sec_trace_enter_api(NULL);
975 sec_trace_return_api(CFDataRef, ^{
976 do_if_registered(soscc_CopyEngineData, error);
977
978 return data_to_error_request(kSecXPCOpCopyEngineData, error);
979 }, CFSTR("return=%@"));
980 }
981
982 bool SOSCCDeleteEngineState(CFErrorRef *error)
983 {
984 sec_trace_enter_api(NULL);
985 sec_trace_return_api(bool, ^{
986 do_if_registered(soscc_DeleteEngineState, error);
987 return simple_bool_error_request(kSecXPCOpDeleteEngineData, error);
988 }, NULL);
989 }
990
991 SOSPeerInfoRef SOSCCCopyMyPeerInfo(CFErrorRef *error)
992 {
993 sec_trace_enter_api(NULL);
994 sec_trace_return_api(SOSPeerInfoRef, ^{
995 do_if_registered(soscc_CopyMyPeerInfo, error);
996
997 return peer_info_error_request(kSecXPCOpCopyMyPeerInfo, error);
998 }, CFSTR("return=%@"));
999 }
1000
1001 static CFArrayRef SOSCCCopyEngineState(CFErrorRef* error)
1002 {
1003 sec_trace_enter_api(NULL);
1004 sec_trace_return_api(CFArrayRef, ^{
1005 do_if_registered(soscc_CopyEngineState, error);
1006
1007 return der_array_error_request(kSecXPCOpCopyEngineState, error);
1008 }, CFSTR("return=%@"));
1009 }
1010
1011 CFStringRef kSOSCCEngineStatePeerIDKey = CFSTR("PeerID");
1012 CFStringRef kSOSCCEngineStateManifestCountKey = CFSTR("ManifestCount");
1013 CFStringRef kSOSCCEngineStateSyncSetKey = CFSTR("SyncSet");
1014 CFStringRef kSOSCCEngineStateCoderKey = CFSTR("CoderDump");
1015 CFStringRef kSOSCCEngineStateManifestHashKey = CFSTR("ManifestHash");
1016
1017 void SOSCCForEachEngineStateAsStringFromArray(CFArrayRef states, void (^block)(CFStringRef oneStateString)) {
1018
1019 CFArrayForEach(states, ^(const void *value) {
1020 CFDictionaryRef dict = asDictionary(value, NULL);
1021 if (dict) {
1022 CFMutableStringRef description = CFStringCreateMutable(kCFAllocatorDefault, 0);
1023
1024 CFStringRef id = asString(CFDictionaryGetValue(dict, kSOSCCEngineStatePeerIDKey), NULL);
1025
1026 if (id) {
1027 CFStringAppendFormat(description, NULL, CFSTR("remote %@ "), id);
1028 } else {
1029 CFStringAppendFormat(description, NULL, CFSTR("local "));
1030 }
1031
1032 CFSetRef viewSet = asSet(CFDictionaryGetValue(dict, kSOSCCEngineStateSyncSetKey), NULL);
1033 if (viewSet) {
1034 CFStringSetPerformWithDescription(viewSet, ^(CFStringRef setDescription) {
1035 CFStringAppend(description, setDescription);
1036 });
1037 } else {
1038 CFStringAppendFormat(description, NULL, CFSTR("<Missing view set!>"));
1039 }
1040
1041 CFStringAppendFormat(description, NULL, CFSTR(" [%@]"),
1042 CFDictionaryGetValue(dict, kSOSCCEngineStateManifestCountKey));
1043
1044 CFDataRef mainfestHash = asData(CFDictionaryGetValue(dict, kSOSCCEngineStateManifestHashKey), NULL);
1045
1046 if (mainfestHash) {
1047 CFDataPerformWithHexString(mainfestHash, ^(CFStringRef dataString) {
1048 CFStringAppendFormat(description, NULL, CFSTR(" %@"), dataString);
1049 });
1050 }
1051
1052 CFStringRef coderDescription = asString(CFDictionaryGetValue(dict, kSOSCCEngineStateCoderKey), NULL);
1053 if (coderDescription) {
1054 CFStringAppendFormat(description, NULL, CFSTR(" %@"), coderDescription);
1055 }
1056
1057 block(description);
1058
1059 CFReleaseNull(description);
1060 }
1061 });
1062 }
1063
1064 bool SOSCCForEachEngineStateAsString(CFErrorRef* error, void (^block)(CFStringRef oneStateString)) {
1065 CFArrayRef states = SOSCCCopyEngineState(error);
1066 if (states == NULL)
1067 return false;
1068
1069 SOSCCForEachEngineStateAsStringFromArray(states, block);
1070
1071 return true;
1072 }
1073
1074
1075 bool SOSCCAcceptApplicants(CFArrayRef applicants, CFErrorRef* error)
1076 {
1077 sec_trace_enter_api(NULL);
1078 sec_trace_return_bool_api(^{
1079 do_if_registered(soscc_AcceptApplicants, applicants, error);
1080
1081 return info_array_to_bool_error_request(kSecXPCOpAcceptApplicants, applicants, error);
1082 }, NULL)
1083 }
1084
1085 bool SOSCCRejectApplicants(CFArrayRef applicants, CFErrorRef *error)
1086 {
1087 sec_trace_enter_api(CFSTR("applicants=%@"), applicants);
1088 sec_trace_return_bool_api(^{
1089 do_if_registered(soscc_RejectApplicants, applicants, error);
1090
1091 return info_array_to_bool_error_request(kSecXPCOpRejectApplicants, applicants, error);
1092 }, NULL)
1093 }
1094
1095 static CF_RETURNS_RETAINED SOSPeerInfoRef SOSSetNewPublicBackupKey(CFDataRef pubKey, CFErrorRef *error)
1096 {
1097 sec_trace_enter_api(NULL);
1098 sec_trace_return_api(SOSPeerInfoRef, ^{
1099 do_if_registered(soscc_SetNewPublicBackupKey, pubKey, error);
1100
1101 return data_to_peer_info_error_request(kSecXPCOpSetNewPublicBackupKey, pubKey, error);
1102 }, CFSTR("return=%@"));
1103 }
1104
1105 SOSPeerInfoRef SOSCCCopyMyPeerWithNewDeviceRecoverySecret(CFDataRef secret, CFErrorRef *error){
1106 CFDataRef publicKeyData = SOSCopyDeviceBackupPublicKey(secret, error);
1107
1108 SOSPeerInfoRef copiedPeer = publicKeyData ? SOSSetNewPublicBackupKey(publicKeyData, error) : NULL;
1109
1110 CFReleaseNull(publicKeyData);
1111
1112 return copiedPeer;
1113 }
1114
1115 bool SOSCCRegisterSingleRecoverySecret(CFDataRef aks_bag, bool forV0Only, CFErrorRef *error){
1116 sec_trace_enter_api(NULL);
1117 sec_trace_return_bool_api(^{
1118 do_if_registered(soscc_RegisterSingleRecoverySecret, aks_bag, forV0Only, error);
1119 return keybag_and_bool_to_bool_error_request(kSecXPCOpSetBagForAllSlices, aks_bag, forV0Only, error);
1120 }, NULL);
1121 }
1122
1123
1124 bool SOSCCRegisterRecoveryPublicKey(CFDataRef recovery_key, CFErrorRef *error){
1125 sec_trace_enter_api(NULL);
1126 sec_trace_return_bool_api(^{
1127 do_if_registered(soscc_RegisterRecoveryPublicKey, recovery_key, error);
1128 return recovery_and_bool_to_bool_error_request(kSecXPCOpRegisterRecoveryPublicKey, recovery_key, error);
1129 }, NULL);
1130 }
1131
1132 CFDataRef SOSCCCopyRecoveryPublicKey(CFErrorRef *error){
1133 sec_trace_enter_api(NULL);
1134 sec_trace_return_api(CFDataRef, ^{
1135 do_if_registered(soscc_CopyRecoveryPublicKey, error);
1136 return data_to_error_request(kSecXPCOpGetRecoveryPublicKey, error);
1137 }, CFSTR("return=%@"));
1138 }
1139 static bool label_and_password_to_bool_error_request(enum SecXPCOperation op,
1140 CFStringRef user_label, CFDataRef user_password,
1141 CFErrorRef* error)
1142 {
1143 __block bool result = false;
1144
1145 securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
1146 CFStringPerformWithCString(user_label, ^(const char *utf8Str) {
1147 xpc_dictionary_set_string(message, kSecXPCKeyUserLabel, utf8Str);
1148 });
1149 xpc_dictionary_set_data(message, kSecXPCKeyUserPassword, CFDataGetBytePtr(user_password), CFDataGetLength(user_password));
1150 return true;
1151 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
1152 result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
1153 return result;
1154 });
1155
1156 return result;
1157 }
1158
1159 static bool label_and_password_and_dsid_to_bool_error_request(enum SecXPCOperation op,
1160 CFStringRef user_label, CFDataRef user_password,
1161 CFStringRef dsid, CFErrorRef* error)
1162 {
1163 __block bool result = false;
1164
1165 securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
1166 CFStringPerformWithCString(user_label, ^(const char *utf8Str) {
1167 xpc_dictionary_set_string(message, kSecXPCKeyUserLabel, utf8Str);
1168 });
1169 CFStringPerformWithCString(dsid, ^(const char *utr8StrDSID) {
1170 xpc_dictionary_set_string(message, kSecXPCKeyDSID, utr8StrDSID);
1171 });
1172 xpc_dictionary_set_data(message, kSecXPCKeyUserPassword, CFDataGetBytePtr(user_password), CFDataGetLength(user_password));
1173 return true;
1174 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
1175 result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
1176 return result;
1177 });
1178
1179 return result;
1180 }
1181
1182 static bool cfstring_to_bool_error_request(enum SecXPCOperation op,
1183 CFStringRef string,
1184 CFErrorRef* error)
1185 {
1186 __block bool result = false;
1187
1188 securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
1189 CFStringPerformWithCString(string, ^(const char *utf8Str) {
1190 xpc_dictionary_set_string(message, kSecXPCKeyDeviceID, utf8Str);
1191 });
1192 return true;
1193 }, ^bool(xpc_object_t response, CFErrorRef *error) {
1194 result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
1195 return result;
1196 });
1197
1198 return result;
1199 }
1200
1201 static int idsDict_to_int_error_request(enum SecXPCOperation op,
1202 CFDictionaryRef IDS,
1203 CFErrorRef* error)
1204 {
1205 __block int result = 0;
1206
1207 securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
1208 SecXPCDictionarySetPListOptional(message, kSecXPCKeyIDSMessage, IDS, error);
1209 return true;
1210 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
1211 int64_t temp_result = xpc_dictionary_get_int64(response, kSecXPCKeyResult);
1212 if ((temp_result >= INT32_MIN) && (temp_result <= INT32_MAX)) {
1213 result = (int)temp_result;
1214 }
1215 return true;
1216 });
1217
1218 return result;
1219 }
1220
1221 static bool idsData_peerID_to_bool_error_request(enum SecXPCOperation op, CFStringRef peerID,
1222 CFDataRef IDSMessage,
1223 CFErrorRef* error)
1224 {
1225 __block bool result = 0;
1226
1227 securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
1228 SecXPCDictionarySetData(message, kSecXPCKeyIDSMessage, IDSMessage, error);
1229 SecXPCDictionarySetString(message, kSecXPCKeyDeviceID, peerID, error);
1230 return true;
1231 }, ^bool(xpc_object_t response, CFErrorRef *error) {
1232 result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
1233 return result;
1234 });
1235 return result;
1236 }
1237
1238 static bool idscommand_to_bool_error_request(enum SecXPCOperation op,
1239 CFStringRef idsMessage,
1240 CFErrorRef* error)
1241 {
1242 __block bool result = false;
1243
1244 securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
1245 CFStringPerformWithCString(idsMessage, ^(const char *utf8Str) {
1246 xpc_dictionary_set_string(message, kSecXPCKeySendIDSMessage, utf8Str);
1247 });
1248 return true;
1249 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
1250 result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
1251 return result;
1252 });
1253
1254 return result;
1255 }
1256
1257 bool SOSCCRegisterUserCredentials(CFStringRef user_label, CFDataRef user_password, CFErrorRef* error)
1258 {
1259 secnotice("sosops", "SOSCCRegisterUserCredentials - calling SOSCCSetUserCredentials!! %@\n", user_label);
1260 return SOSCCSetUserCredentials(user_label, user_password, error);
1261 }
1262
1263 bool SOSCCSetUserCredentials(CFStringRef user_label, CFDataRef user_password, CFErrorRef* error)
1264 {
1265 secnotice("sosops", "SOSCCSetUserCredentials!! %@\n", user_label);
1266 sec_trace_enter_api(CFSTR("user_label=%@"), user_label);
1267 sec_trace_return_bool_api(^{
1268 do_if_registered(soscc_SetUserCredentials, user_label, user_password, error);
1269
1270 return label_and_password_to_bool_error_request(kSecXPCOpSetUserCredentials, user_label, user_password, error);
1271 }, NULL)
1272 }
1273
1274 bool SOSCCSetUserCredentialsAndDSID(CFStringRef user_label, CFDataRef user_password, CFStringRef dsid, CFErrorRef *error)
1275 {
1276 secnotice("sosops", "SOSCCSetUserCredentialsAndDSID!! %@\n", user_label);
1277 sec_trace_enter_api(CFSTR("user_label=%@"), user_label);
1278 sec_trace_return_bool_api(^{
1279 do_if_registered(soscc_SetUserCredentialsAndDSID, user_label, user_password, dsid, error);
1280
1281 bool result = false;
1282 __block CFStringRef account_dsid = dsid;
1283
1284 require_action_quiet(user_label, out, SOSErrorCreate(kSOSErrorParam, error, NULL, CFSTR("user_label is nil")));
1285 require_action_quiet(user_password, out, SOSErrorCreate(kSOSErrorParam, error, NULL, CFSTR("user_password is nil")));
1286
1287 if(account_dsid == NULL){
1288 account_dsid = CFSTR("");
1289 }
1290 return label_and_password_and_dsid_to_bool_error_request(kSecXPCOpSetUserCredentialsAndDSID, user_label, user_password, account_dsid, error);
1291 out:
1292 return result;
1293
1294 }, NULL)
1295 }
1296 bool SOSCCSetDeviceID(CFStringRef IDS, CFErrorRef* error)
1297 {
1298 secnotice("sosops", "SOSCCSetDeviceID!! %@\n", IDS);
1299 sec_trace_enter_api(NULL);
1300 sec_trace_return_bool_api(^{
1301 do_if_registered(soscc_SetDeviceID, IDS, error);
1302 bool result = cfstring_to_bool_error_request(kSecXPCOpSetDeviceID, IDS, error);
1303 return result;
1304 }, NULL)
1305 }
1306
1307 bool SOSCCIDSServiceRegistrationTest(CFStringRef message, CFErrorRef *error)
1308 {
1309 secnotice("sosops", "SOSCCSendIDSTestMessage!! %@\n", message);
1310 sec_trace_enter_api(NULL);
1311 sec_trace_return_bool_api(^{
1312 do_if_registered(soscc_CheckIDSRegistration, message, error);
1313 return idscommand_to_bool_error_request(kSecXPCOpSendIDSMessage, message, error);
1314 }, NULL)
1315 }
1316
1317 bool SOSCCIDSPingTest(CFStringRef message, CFErrorRef *error)
1318 {
1319 secnotice("sosops", "SOSCCSendIDSTestMessage!! %@\n", message);
1320 sec_trace_enter_api(NULL);
1321 sec_trace_return_bool_api(^{
1322 do_if_registered(soscc_PingTest, message, error);
1323 return idscommand_to_bool_error_request(kSecXPCOpPingTest, message, error);
1324 }, NULL)
1325 }
1326
1327 bool SOSCCIDSDeviceIDIsAvailableTest(CFErrorRef *error)
1328 {
1329 secnotice("sosops", "SOSCCIDSDeviceIDIsAvailableTest!!\n");
1330 sec_trace_enter_api(NULL);
1331 sec_trace_return_bool_api(^{
1332 do_if_registered(soscc_GetIDSIDFromIDS, error);
1333 return simple_bool_error_request(kSecXPCOpIDSDeviceID, error);
1334 }, NULL)
1335 }
1336
1337 HandleIDSMessageReason SOSCCHandleIDSMessage(CFDictionaryRef IDS, CFErrorRef* error)
1338 {
1339 secnotice("sosops", "SOSCCHandleIDSMessage!! %@\n", IDS);
1340 sec_trace_enter_api(NULL);
1341 sec_trace_return_api(HandleIDSMessageReason, ^{
1342 do_if_registered(soscc_HandleIDSMessage, IDS, error);
1343 return (HandleIDSMessageReason) idsDict_to_int_error_request(kSecXPCOpHandleIDSMessage, IDS, error);
1344 }, NULL)
1345 }
1346
1347 bool SOSCCClearPeerMessageKeyInKVS(CFStringRef peerID, CFErrorRef *error)
1348 {
1349 secnotice("sosops", "SOSCCClearPeerMessageKeyInKVS!! %@\n", peerID);
1350 sec_trace_enter_api(NULL);
1351 sec_trace_return_bool_api(^{
1352 do_if_registered(socc_clearPeerMessageKeyInKVS, peerID, error);
1353 return cfstring_to_bool_error_request(kSecXPCOpClearKVSPeerMessage, peerID, error);
1354 }, NULL)
1355
1356 }
1357
1358 bool SOSCCRequestSyncWithPeerOverKVSUsingIDOnly(CFStringRef peerID, CFErrorRef *error)
1359 {
1360 secnotice("sosops", "SOSCCRequestSyncWithPeerOverKVSUsingIDOnly!! %@\n", peerID);
1361 sec_trace_enter_api(NULL);
1362 sec_trace_return_bool_api(^{
1363 do_if_registered(soscc_requestSyncWithPeerOverKVSIDOnly, peerID, error);
1364 return deviceid_to_bool_error_request(kSecXPCOpSyncWithKVSPeerIDOnly, peerID, error);
1365 }, NULL)
1366 }
1367
1368 bool SOSCCRequestSyncWithPeerOverKVS(CFStringRef peerID, CFDataRef message, CFErrorRef *error)
1369 {
1370 secnotice("sosops", "SOSCCRequestSyncWithPeerOverKVS!! %@\n", peerID);
1371 sec_trace_enter_api(NULL);
1372 sec_trace_return_bool_api(^{
1373 do_if_registered(soscc_requestSyncWithPeerOverKVS, peerID, message, error);
1374 return idsData_peerID_to_bool_error_request(kSecXPCOpSyncWithKVSPeer, peerID, message, error);
1375 }, NULL)
1376 }
1377
1378 bool SOSCCTryUserCredentials(CFStringRef user_label, CFDataRef user_password, CFErrorRef* error)
1379 {
1380 sec_trace_enter_api(CFSTR("user_label=%@"), user_label);
1381 sec_trace_return_bool_api(^{
1382 do_if_registered(soscc_TryUserCredentials, user_label, user_password, error);
1383
1384 return label_and_password_to_bool_error_request(kSecXPCOpTryUserCredentials, user_label, user_password, error);
1385 }, NULL)
1386 }
1387
1388
1389 bool SOSCCCanAuthenticate(CFErrorRef* error) {
1390 sec_trace_enter_api(NULL);
1391 sec_trace_return_bool_api(^{
1392 do_if_registered(soscc_CanAuthenticate, error);
1393
1394 return simple_bool_error_request(kSecXPCOpCanAuthenticate, error);
1395 }, NULL)
1396 }
1397
1398 bool SOSCCPurgeUserCredentials(CFErrorRef* error) {
1399 sec_trace_enter_api(NULL);
1400 sec_trace_return_bool_api(^{
1401 do_if_registered(soscc_PurgeUserCredentials, error);
1402
1403 return simple_bool_error_request(kSecXPCOpPurgeUserCredentials, error);
1404 }, NULL)
1405 }
1406
1407 enum DepartureReason SOSCCGetLastDepartureReason(CFErrorRef *error) {
1408 sec_trace_enter_api(NULL);
1409 sec_trace_return_api(enum DepartureReason, ^{
1410 do_if_registered(soscc_GetLastDepartureReason, error);
1411
1412 return (enum DepartureReason) simple_int_error_request(kSecXPCOpGetLastDepartureReason, error);
1413 }, NULL)
1414 }
1415
1416 bool SOSCCSetLastDepartureReason(enum DepartureReason reason, CFErrorRef *error) {
1417 sec_trace_enter_api(NULL);
1418 sec_trace_return_api(bool, ^{
1419 do_if_registered(soscc_SetLastDepartureReason, reason, error);
1420 return securityd_send_sync_and_do(kSecXPCOpSetLastDepartureReason, error,
1421 ^bool(xpc_object_t message, CFErrorRef *error) {
1422 xpc_dictionary_set_int64(message, kSecXPCKeyReason, reason);
1423 return true;
1424 },
1425 ^bool(xpc_object_t response, __unused CFErrorRef *error) {
1426 return xpc_dictionary_get_bool(response, kSecXPCKeyResult);
1427 }
1428 );
1429 }, NULL)
1430 }
1431
1432 CFStringRef SOSCCCopyIncompatibilityInfo(CFErrorRef* error) {
1433 sec_trace_enter_api(NULL);
1434 sec_trace_return_api(CFStringRef, ^{
1435 do_if_registered(soscc_CopyIncompatibilityInfo, error);
1436
1437 return simple_cfstring_error_request(kSecXPCOpCopyIncompatibilityInfo, error);
1438 }, NULL)
1439 }
1440
1441 CFStringRef SOSCCCopyDeviceID(CFErrorRef* error)
1442 {
1443 sec_trace_enter_api(NULL);
1444 sec_trace_return_api(CFStringRef, ^{
1445 do_if_registered(soscc_CopyDeviceID, error);
1446 CFStringRef deviceID = simple_cfstring_error_request(kSecXPCOpRequestDeviceID, error);
1447 return deviceID;
1448 }, NULL)
1449 }
1450
1451 bool SOSCCProcessEnsurePeerRegistration(CFErrorRef* error){
1452 secnotice("updates", "enter SOSCCProcessEnsurePeerRegistration");
1453 sec_trace_enter_api(NULL);
1454 sec_trace_return_bool_api(^{
1455 do_if_registered(soscc_EnsurePeerRegistration, error);
1456
1457 return simple_bool_error_request(soscc_EnsurePeerRegistration_id, error);
1458 }, NULL)
1459 }
1460
1461
1462 CFSetRef /* CFString */ SOSCCProcessSyncWithPeers(CFSetRef peers, CFSetRef backupPeers, CFErrorRef* error)
1463 {
1464 sec_trace_enter_api(NULL);
1465 sec_trace_return_api(CFSetRef, ^{
1466 do_if_registered(soscc_ProcessSyncWithPeers, peers, backupPeers, error);
1467
1468 return cfset_cfset_to_cfset_error_request(kSecXPCOpProcessSyncWithPeers, peers, backupPeers, error);
1469 }, NULL)
1470 }
1471
1472
1473 SyncWithAllPeersReason SOSCCProcessSyncWithAllPeers(CFErrorRef* error)
1474 {
1475 sec_trace_enter_api(NULL);
1476 sec_trace_return_api(SyncWithAllPeersReason, ^{
1477 do_if_registered(soscc_ProcessSyncWithAllPeers, error);
1478
1479 return (SyncWithAllPeersReason) simple_int_error_request(kSecXPCOpProcessSyncWithAllPeers, error);
1480 }, NULL)
1481 }
1482
1483 CFStringRef SOSCCGetStatusDescription(SOSCCStatus status)
1484 {
1485 switch (status) {
1486 case kSOSCCInCircle:
1487 return CFSTR("InCircle");
1488 case kSOSCCNotInCircle:
1489 return CFSTR("NotInCircle");
1490 case kSOSCCRequestPending:
1491 return CFSTR("RequestPending");
1492 case kSOSCCCircleAbsent:
1493 return CFSTR("CircleAbsent");
1494 case kSOSCCError:
1495 return CFSTR("InternalError");
1496 default:
1497 return CFSTR("Unknown Status (%d)");
1498 };
1499 }
1500
1501 #if 0
1502 kSOSCCGeneralViewError = -1,
1503 kSOSCCViewMember = 0,
1504 kSOSCCViewNotMember = 1,
1505 kSOSCCViewNotQualified = 2,
1506 kSOSCCNoSuchView = 3,
1507 #endif
1508
1509 static int64_t name_action_to_code_request(enum SecXPCOperation op, uint16_t error_result,
1510 CFStringRef name, uint64_t action, CFErrorRef *error) {
1511 __block int64_t result = error_result;
1512
1513 securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
1514 CFStringPerformWithCString(name, ^(const char *utf8Str) {
1515 xpc_dictionary_set_string(message, kSecXPCKeyViewName, utf8Str);
1516 });
1517 xpc_dictionary_set_int64(message, kSecXPCKeyViewActionCode, action);
1518 return true;
1519 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
1520 if (response && xpc_dictionary_entry_is_type(response, kSecXPCKeyResult, XPC_TYPE_INT64)) {
1521 result = xpc_dictionary_get_int64(response, kSecXPCKeyResult);
1522 }
1523 return result != error_result;
1524 });
1525
1526 return result;
1527 }
1528
1529 SOSViewResultCode SOSCCView(CFStringRef view, SOSViewActionCode actionCode, CFErrorRef *error) {
1530 sec_trace_enter_api(NULL);
1531 sec_trace_return_api(SOSViewResultCode, ^{
1532 do_if_registered(soscc_View, view, actionCode, error);
1533
1534 return (SOSViewResultCode) name_action_to_code_request(kSecXPCOpView, kSOSCCGeneralViewError, view, actionCode, error);
1535 }, CFSTR("SOSViewResultCode=%d"))
1536 }
1537
1538
1539 bool SOSCCViewSet(CFSetRef enabledViews, CFSetRef disabledViews) {
1540 CFErrorRef *error = NULL;
1541 __block bool result = false;
1542
1543 sec_trace_enter_api(NULL);
1544 sec_trace_return_bool_api(^{
1545 do_if_registered(soscc_ViewSet, enabledViews, disabledViews);
1546 return securityd_send_sync_and_do(kSecXPCOpViewSet, error, ^bool(xpc_object_t message, CFErrorRef *error) {
1547 xpc_object_t enabledSetXpc = CreateXPCObjectWithCFSetRef(enabledViews, error);
1548 xpc_object_t disabledSetXpc = CreateXPCObjectWithCFSetRef(disabledViews, error);
1549 if (enabledSetXpc) xpc_dictionary_set_value(message, kSecXPCKeyEnabledViewsKey, enabledSetXpc);
1550 if (disabledSetXpc) xpc_dictionary_set_value(message, kSecXPCKeyDisabledViewsKey, disabledSetXpc);
1551 return (enabledSetXpc != NULL) || (disabledSetXpc != NULL) ;
1552 }, ^bool(xpc_object_t response, __unused CFErrorRef *error) {
1553 result = xpc_dictionary_get_bool(response, kSecXPCKeyResult);
1554 return result;
1555 });
1556 }, NULL)
1557 }
1558
1559 SOSSecurityPropertyResultCode SOSCCSecurityProperty(CFStringRef property, SOSSecurityPropertyActionCode actionCode, CFErrorRef *error) {
1560 sec_trace_enter_api(NULL);
1561 sec_trace_return_api(SOSSecurityPropertyResultCode, ^{
1562 SOSSecurityPropertyResultCode result = kSOSCCGeneralSecurityPropertyError;
1563 do_if_registered(soscc_SecurityProperty, property, actionCode, error);
1564 xpc_object_t message = securityd_create_message(kSecXPCOpSecurityProperty, error);
1565 if (message) {
1566 int64_t bigac = actionCode;
1567 xpc_dictionary_set_string(message, kSecXPCKeyViewName, CFStringGetCStringPtr(property, kCFStringEncodingUTF8));
1568 xpc_dictionary_set_int64(message, kSecXPCKeyViewActionCode, bigac);
1569
1570 xpc_object_t response = securityd_message_with_reply_sync(message, error);
1571
1572 if (response && xpc_dictionary_entry_is_type(response, kSecXPCKeyResult, XPC_TYPE_INT64)) {
1573 result = (SOSSecurityPropertyResultCode) xpc_dictionary_get_int64(response, kSecXPCKeyResult);
1574 }
1575
1576 if (result == kSOSCCGeneralSecurityPropertyError) {
1577 if (response && securityd_message_no_error(response, error)) {
1578 char *desc = xpc_copy_description(response);
1579 SecCFCreateErrorWithFormat(0, sSecXPCErrorDomain, NULL, error, NULL, CFSTR("Remote error occurred/no info: %s"), desc);
1580 free((void *)desc);
1581 }
1582 }
1583 if(response)
1584 xpc_release(response);
1585 if(message)
1586 xpc_release(message);
1587 }
1588
1589 return result;
1590 }, CFSTR("SOSSecurityPropertyResultCode=%d"))
1591 }
1592
1593
1594 static bool sosIsViewSetSyncing(size_t n, CFStringRef *views) {
1595 __block bool retval = true;
1596
1597 SOSCCStatus cstatus = SOSCCThisDeviceIsInCircle(NULL);
1598 if(cstatus == kSOSCCInCircle) {
1599 for(size_t i = 0; i < n; i++) {
1600 SOSViewResultCode vstatus = SOSCCView(views[i], kSOSCCViewQuery, NULL);
1601 if(vstatus != kSOSCCViewMember) retval = false;
1602 }
1603 } else {
1604 retval = false;
1605 }
1606 return retval;
1607 }
1608
1609 bool SOSCCIsIcloudKeychainSyncing(void) {
1610 CFStringRef views[] = { kSOSViewWiFi, kSOSViewAutofillPasswords, kSOSViewSafariCreditCards, kSOSViewOtherSyncable };
1611 return sosIsViewSetSyncing(sizeof(views)/sizeof(views[0]), views);
1612 }
1613
1614 bool SOSCCIsSafariSyncing(void) {
1615 CFStringRef views[] = { kSOSViewAutofillPasswords, kSOSViewSafariCreditCards };
1616 return sosIsViewSetSyncing(sizeof(views)/sizeof(views[0]), views);
1617 }
1618
1619 bool SOSCCIsAppleTVSyncing(void) {
1620 CFStringRef views[] = { kSOSViewAppleTV };
1621 return sosIsViewSetSyncing(sizeof(views)/sizeof(views[0]), views);
1622 }
1623
1624 bool SOSCCIsHomeKitSyncing(void) {
1625 CFStringRef views[] = { kSOSViewHomeKit };
1626 return sosIsViewSetSyncing(sizeof(views)/sizeof(views[0]), views);
1627 }
1628
1629 bool SOSCCIsWiFiSyncing(void) {
1630 CFStringRef views[] = { kSOSViewWiFi };
1631 return sosIsViewSetSyncing(sizeof(views)/sizeof(views[0]), views);
1632 }
1633
1634 bool SOSCCIsContinuityUnlockSyncing(void) {
1635 CFStringRef views[] = { kSOSViewContinuityUnlock };
1636 return sosIsViewSetSyncing(sizeof(views)/sizeof(views[0]), views);
1637 }
1638
1639
1640 bool SOSCCSetEscrowRecord(CFStringRef escrow_label, uint64_t tries, CFErrorRef *error ){
1641 secnotice("escrow", "enter SOSCCSetEscrowRecord");
1642 sec_trace_enter_api(NULL);
1643 sec_trace_return_bool_api(^{
1644 do_if_registered(soscc_SetEscrowRecords, escrow_label, tries, error);
1645
1646 return escrow_to_bool_error_request(kSecXPCOpSetEscrowRecord, escrow_label, tries, error);
1647 }, NULL)
1648 }
1649
1650 CFDictionaryRef SOSCCCopyEscrowRecord(CFErrorRef *error){
1651 secnotice("escrow", "enter SOSCCCopyEscrowRecord");
1652 sec_trace_enter_api(NULL);
1653 sec_trace_return_api(CFDictionaryRef, ^{
1654 do_if_registered(soscc_CopyEscrowRecords, error);
1655
1656 return strings_to_dictionary_error_request(kSecXPCOpGetEscrowRecord, error);
1657 }, CFSTR("return=%@"))
1658
1659 }
1660
1661 CFDictionaryRef SOSCCCopyBackupInformation(CFErrorRef *error) {
1662 secnotice("escrow", "enter SOSCCCopyBackupInformation");
1663 sec_trace_enter_api(NULL);
1664 sec_trace_return_api(CFDictionaryRef, ^{
1665 do_if_registered(soscc_CopyBackupInformation, error);
1666 return strings_to_dictionary_error_request(kSecXPCOpCopyBackupInformation, error);
1667 }, CFSTR("return=%@"))
1668 }
1669
1670 bool SOSCCCheckPeerAvailability(CFErrorRef *error){
1671 secnotice("peer", "enter SOSCCCheckPeerAvailability");
1672 sec_trace_enter_api(NULL);
1673 sec_trace_return_bool_api(^{
1674 do_if_registered(soscc_PeerAvailability, error);
1675
1676 return simple_bool_error_request(kSecXPCOpCheckPeerAvailability, error);
1677 }, NULL)
1678
1679 }
1680
1681
1682 bool SOSWrapToBackupSliceKeyBagForView(CFStringRef viewName, CFDataRef input, CFDataRef* output, CFDataRef* bskbEncoded, CFErrorRef* error) {
1683 sec_trace_enter_api(NULL);
1684 sec_trace_return_bool_api(^{
1685 do_if_registered(sosbskb_WrapToBackupSliceKeyBagForView, viewName, input, output, bskbEncoded, error);
1686
1687 return cfstring_and_cfdata_to_cfdata_cfdata_error_request(kSecXPCOpWrapToBackupSliceKeyBagForView, viewName, input, output, bskbEncoded, error);
1688 }, NULL)
1689 }
1690
1691
1692 SOSPeerInfoRef SOSCCCopyApplication(CFErrorRef *error) {
1693 secnotice("hsa2PB", "enter SOSCCCopyApplication applicant");
1694 sec_trace_enter_api(NULL);
1695
1696 sec_trace_return_api(SOSPeerInfoRef, ^{
1697 do_if_registered(soscc_CopyApplicant, error);
1698 return peer_info_error_request(kSecXPCOpCopyApplication, error);
1699 }, CFSTR("return=%@"));
1700 }
1701
1702 CFDataRef SOSCCCopyCircleJoiningBlob(SOSPeerInfoRef applicant, CFErrorRef *error) {
1703 secnotice("hsa2PB", "enter SOSCCCopyCircleJoiningBlob approver");
1704 sec_trace_enter_api(NULL);
1705
1706 sec_trace_return_api(CFDataRef, ^{
1707 CFDataRef result = NULL;
1708 do_if_registered(soscc_CopyCircleJoiningBlob, applicant, error);
1709 CFDataRef piData = SOSPeerInfoCopyEncodedData(applicant, kCFAllocatorDefault, error);
1710 result = cfdata_error_request_returns_cfdata(kSecXPCOpCopyCircleJoiningBlob, piData, error);
1711 CFReleaseNull(piData);
1712 return result;
1713 }, CFSTR("return=%@"));
1714 }
1715
1716 bool SOSCCJoinWithCircleJoiningBlob(CFDataRef joiningBlob, CFErrorRef *error) {
1717 secnotice("hsa2PB", "enter SOSCCJoinWithCircleJoiningBlob applicant");
1718 sec_trace_enter_api(NULL);
1719 sec_trace_return_bool_api(^{
1720 do_if_registered(soscc_JoinWithCircleJoiningBlob, joiningBlob, error);
1721
1722 return cfdata_error_request_returns_bool(kSecXPCOpJoinWithCircleJoiningBlob, joiningBlob, error);
1723 }, NULL)
1724
1725 return false;
1726 }
1727
1728 bool SOSCCIsThisDeviceLastBackup(CFErrorRef *error) {
1729 secnotice("peer", "enter SOSCCIsThisDeviceLastBackup");
1730 sec_trace_enter_api(NULL);
1731 sec_trace_return_bool_api(^{
1732 do_if_registered(soscc_IsThisDeviceLastBackup, error);
1733
1734 return simple_bool_error_request(kSecXPCOpIsThisDeviceLastBackup, error);
1735 }, NULL)
1736 }
1737
1738 CFBooleanRef SOSCCPeersHaveViewsEnabled(CFArrayRef viewNames, CFErrorRef *error) {
1739 secnotice("view-enabled", "enter SOSCCPeersHaveViewsEnabled");
1740 sec_trace_enter_api(NULL);
1741 sec_trace_return_api(CFBooleanRef, ^{
1742 do_if_registered(soscc_SOSCCPeersHaveViewsEnabled, viewNames, error);
1743
1744 return cfarray_to_cfboolean_error_request(kSecXPCOpPeersHaveViewsEnabled, viewNames, error);
1745 }, CFSTR("return=%@"))
1746 }
1747
1748 bool SOSCCMessageFromPeerIsPending(SOSPeerInfoRef peer, CFErrorRef *error) {
1749 secnotice("pending-check", "enter SOSCCMessageFromPeerIsPending");
1750
1751 sec_trace_return_bool_api(^{
1752 do_if_registered(soscc_SOSCCMessageFromPeerIsPending, peer, error);
1753
1754 return peer_info_to_bool_error_request(kSecXPCOpMessageFromPeerIsPending, peer, error);
1755 }, NULL)
1756
1757 }
1758
1759 bool SOSCCSendToPeerIsPending(SOSPeerInfoRef peer, CFErrorRef *error) {
1760 sec_trace_return_bool_api(^{
1761 do_if_registered(soscc_SOSCCSendToPeerIsPending, peer, error);
1762
1763 return peer_info_to_bool_error_request(kSecXPCOpSendToPeerIsPending, peer, error);
1764 }, NULL)
1765
1766 }