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