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