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