2 * Copyright (c) 2012-2014 Apple Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
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
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.
21 * @APPLE_LICENSE_HEADER_END@
25 SOSCloudTransport.c - Implementation of the transport layer from CKBridge to SOSAccount/SOSCircle
26 These are the exported functions from CloudKeychainProxy
30 This XPC service is essentially just a proxy to iCloud KVS, which exists since
31 at one time the main security code could not link against Foundation.
33 See sendTSARequestWithXPC in tsaSupport.c for how to call the service
35 The client of an XPC service does not get connection events, nor does it
36 need to deal with transactions.
39 #include <AssertMacros.h>
42 #include <CoreFoundation/CoreFoundation.h>
43 #include <CoreFoundation/CFXPCBridge.h>
46 #include <os/activity.h>
47 #include <CoreFoundation/CFUserNotification.h>
48 #include <Security/SecureObjectSync/SOSInternal.h>
51 #include <utilities/debugging.h>
52 #include <utilities/SecCFWrappers.h>
53 #include <utilities/SecXPCError.h>
55 #include "SOSCloudKeychainConstants.h"
56 #include "SOSCloudKeychainClient.h"
57 #include "SOSUserKeygen.h"
58 #include "SecOTRSession.h"
60 #include <os/activity.h>
61 #include <os/state_private.h>
64 static CFStringRef sErrorDomain
= CFSTR("com.apple.security.sos.transport.error");
66 #define SOSCKCSCOPE "sync"
68 // MARK: ---------- SOSCloudTransport ----------
70 /* SOSCloudTransport, a statically initialized transport singleton. */
71 static SOSCloudTransportRef sTransport
= NULL
;
73 static SOSCloudTransportRef
SOSCloudTransportCreateXPCTransport(void);
75 void SOSCloudKeychainSetTransport(SOSCloudTransportRef transport
) {
76 sTransport
= transport
;
79 void SOSCloudTransportGet(SOSCloudTransportRef transport
, CFArrayRef keysToGet
, dispatch_queue_t processQueue
, CloudKeychainReplyBlock replyBlock
);
83 /* Return the singleton cloud transport instance. */
84 CFDictionaryRef
SOSCloudCopyKVSState(void) {
85 __block CFDictionaryRef retval
= NULL
;
87 static dispatch_queue_t processQueue
= NULL
;
88 static dispatch_once_t onceToken
;
89 dispatch_once(&onceToken
, ^{
90 processQueue
= dispatch_queue_create("KVSStateCapture", DISPATCH_QUEUE_SERIAL
);
93 if (processQueue
== NULL
)
96 dispatch_semaphore_t waitSemaphore
= NULL
;
98 waitSemaphore
= dispatch_semaphore_create(0);
100 CloudKeychainReplyBlock replyBlock
= ^ (CFDictionaryRef returnedValues
, CFErrorRef error
) {
101 retval
= returnedValues
;
102 if (retval
) CFRetain(retval
);
103 dispatch_semaphore_signal(waitSemaphore
);
106 SOSCloudKeychainGetAllObjectsFromCloud(processQueue
, replyBlock
);
108 dispatch_semaphore_wait(waitSemaphore
, DISPATCH_TIME_FOREVER
);
109 dispatch_release(waitSemaphore
);
115 os_state_block_t kvsStateBlock
= ^os_state_data_t(os_state_hints_t hints
) {
116 os_state_data_t retval
= NULL
;
117 __block CFDictionaryRef kvsdict
= NULL
;
118 CFDataRef serializedKVS
= NULL
;
120 require_quiet(hints
->osh_api
== 3, errOut
); // only grab on sysdiagnose or command lin
122 kvsdict
= SOSCloudCopyKVSState();
124 require_quiet(kvsdict
, errOut
);
125 serializedKVS
= CFPropertyListCreateData(kCFAllocatorDefault
, kvsdict
, kCFPropertyListBinaryFormat_v1_0
, 0, NULL
);
126 size_t statelen
= CFDataGetLength(serializedKVS
);
127 retval
= (os_state_data_t
)calloc(1, OS_STATE_DATA_SIZE_NEEDED(statelen
));
128 require_quiet(retval
, errOut
);
130 retval
->osd_type
= OS_STATE_DATA_SERIALIZED_NSCF_OBJECT
;
131 memcpy(retval
->osd_data
, CFDataGetBytePtr(serializedKVS
), statelen
);
132 retval
->osd_size
= statelen
;
133 strcpy(retval
->osd_title
, "CloudCircle KVS Object");
135 CFReleaseNull(kvsdict
);
136 CFReleaseNull(serializedKVS
);
141 static SOSCloudTransportRef
SOSCloudTransportDefaultTransport(void)
143 static dispatch_once_t sTransportOnce
;
144 dispatch_once(&sTransportOnce
, ^{
146 SOSCloudKeychainSetTransport(SOSCloudTransportCreateXPCTransport());
147 // provide state handler to sysdiagnose and logging
148 os_state_add_handler(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT
, 0), kvsStateBlock
);
154 // MARK: ----- utilities -----
156 static CFErrorRef
makeError(CFIndex which
)
158 CFDictionaryRef userInfo
= NULL
;
159 return CFErrorCreate(kCFAllocatorDefault
, sErrorDomain
, which
, userInfo
);
162 // MARK: ----- DEBUG Utilities -----
164 //------------------------------------------------------------------------------------------------
166 //------------------------------------------------------------------------------------------------
168 static void describeXPCObject(char *prefix
, xpc_object_t object
)
171 // This is useful for debugging.
174 char *desc
= xpc_copy_description(object
);
175 secdebug(SOSCKCSCOPE
, "%s%s\n", prefix
, desc
);
179 secdebug(SOSCKCSCOPE
, "%s<NULL>\n", prefix
);
183 static void describeXPCType(char *prefix
, xpc_type_t xtype
)
185 // Add others as necessary, e.g. XPC_TYPE_DOUBLE
187 // This is useful for debugging.
189 if (XPC_TYPE_CONNECTION
== xtype
)
190 strcpy(msg
, "XPC_TYPE_CONNECTION");
191 else if (XPC_TYPE_ERROR
== xtype
)
192 strcpy(msg
, "XPC_TYPE_ERROR");
193 else if (XPC_TYPE_DICTIONARY
== xtype
)
194 strcpy(msg
, "XPC_TYPE_DICTIONARY");
196 strcpy(msg
, "<unknown>");
198 secdebug(SOSCKCSCOPE
, "%s type:%s\n", prefix
, msg
);
202 // MARK: ---------- SOSXPCCloudTransport ----------
204 typedef struct SOSXPCCloudTransport
*SOSXPCCloudTransportRef
;
205 struct SOSXPCCloudTransport
207 struct SOSCloudTransport transport
;
208 xpc_connection_t serviceConnection
;
209 xpc_connection_t idsProxyServiceConnection
;
210 dispatch_queue_t xpc_queue
;
213 static bool xpc_event_filter(const xpc_connection_t peer
, xpc_object_t event
, CFErrorRef
*error
)
215 // return true if the type is XPC_TYPE_DICTIONARY (and therefore something more to process)
216 secdebug(SOSCKCSCOPE
, "handle_connection_event\n");
217 xpc_type_t xtype
= xpc_get_type(event
);
218 describeXPCType("handle_xpc_event", xtype
);
219 if (XPC_TYPE_CONNECTION
== xtype
)
221 secdebug(SOSCKCSCOPE
, "handle_xpc_event: XPC_TYPE_CONNECTION (unexpected)");
222 // The client of an XPC service does not get connection events
223 // For now, we log this and keep going
224 describeXPCObject("handle_xpc_event: XPC_TYPE_CONNECTION, obj : ", event
);
227 *error
= makeError(kSOSOUnexpectedConnectionEvent
); // FIX
232 if (XPC_TYPE_ERROR
== xtype
)
235 const char *estr
= xpc_dictionary_get_string(event
, XPC_ERROR_KEY_DESCRIPTION
);
237 secdebug(SOSCKCSCOPE
, "default: xpc error: %s\n", estr
);
238 #if 0 // just log for now
239 CFStringRef errStr
= CFStringCreateWithCString(kCFAllocatorDefault
, estr
, kCFStringEncodingUTF8
);
240 CFMutableDictionaryRef userInfo
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0, &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
242 CFDictionaryAddValue(userInfo
, kCFErrorLocalizedDescriptionKey
, errStr
);
244 *error
= CFErrorCreate(kCFAllocatorDefault
, sErrorDomain
, kSOSOXPCErrorEvent
, userInfo
);
245 CFReleaseSafe(errStr
);
246 CFReleaseSafe(userInfo
);
250 if (XPC_TYPE_DICTIONARY
== xtype
)
252 secdebug(SOSCKCSCOPE
, "received dictionary event %p\n", event
);
257 secdebug(SOSCKCSCOPE
, "default: unexpected connection event %p\n", event
);
258 describeXPCObject("handle_xpc_event: obj : ", event
);
260 *error
= makeError(kSOSOUnexpectedXPCEvent
);
265 static void setupIDSProxyServiceConnection(SOSXPCCloudTransportRef transport
)
267 secnotice(SOSCKCSCOPE
, "IDS Transport: setting up xpc connection");
268 transport
->idsProxyServiceConnection
= xpc_connection_create_mach_service(xpcIDSServiceName
, transport
->xpc_queue
, 0);
270 secdebug(SOSCKCSCOPE
, "ids service connection: %p\n", transport
->idsProxyServiceConnection
);
272 xpc_connection_set_event_handler(transport
->idsProxyServiceConnection
, ^(xpc_object_t event
) {
273 secdebug(SOSCKCSCOPE
, "IDS Transport, xpc_connection_set_event_handler\n");
274 if(event
== XPC_ERROR_CONNECTION_INVALID
){
275 secnotice(SOSCKCSCOPE
, "IDS Transport: xpc connection invalid. Oh well.");
279 xpc_connection_activate(transport
->idsProxyServiceConnection
);
280 xpc_retain(transport
->idsProxyServiceConnection
);
283 static void teardownIDSProxyServiceConnection(SOSXPCCloudTransportRef transport
)
285 secnotice(SOSCKCSCOPE
, "IDS Transport: tearing down xpc connection");
286 xpc_release(transport
->idsProxyServiceConnection
);
287 transport
->idsProxyServiceConnection
= NULL
;
290 static void setupServiceConnection(SOSXPCCloudTransportRef transport
)
292 secnotice(SOSCKCSCOPE
, "CKP Transport: setting up xpc connection");
293 transport
->serviceConnection
= xpc_connection_create_mach_service(xpcServiceName
, transport
->xpc_queue
, 0);
295 secdebug(SOSCKCSCOPE
, "serviceConnection: %p\n", transport
->serviceConnection
);
297 xpc_connection_set_event_handler(transport
->serviceConnection
, ^(xpc_object_t event
) {
298 secdebug(SOSCKCSCOPE
, "CKP Transport, xpc_connection_set_event_handler\n");
299 if(event
== XPC_ERROR_CONNECTION_INVALID
){
300 secnotice(SOSCKCSCOPE
, "CKP Transport: xpc connection invalid. Oh well.");
304 xpc_connection_activate(transport
->serviceConnection
);
305 xpc_retain(transport
->serviceConnection
);
308 static void teardownServiceConnection(SOSXPCCloudTransportRef transport
)
310 secnotice(SOSCKCSCOPE
, "CKP Transport: tearing down xpc connection");
311 xpc_release(transport
->serviceConnection
);
312 transport
->serviceConnection
= NULL
;
315 static void SOSXPCCloudTransportInit(SOSXPCCloudTransportRef transport
)
317 secdebug(SOSCKCSCOPE
, "initXPCConnection\n");
319 transport
->xpc_queue
= dispatch_queue_create(xpcServiceName
, DISPATCH_QUEUE_SERIAL
);
321 setupServiceConnection(transport
);
322 setupIDSProxyServiceConnection(transport
);
324 // Any time a new session starts, reestablish the XPC connections.
326 notify_register_dispatch("com.apple.system.loginwindow.desktopUp", &token
, transport
->xpc_queue
, ^(int token2
) {
327 secnotice(SOSCKCSCOPE
, "CKP/IDS Transport: desktopUp happened, reestablishing xpc connections");
328 teardownServiceConnection(transport
);
329 setupServiceConnection(transport
);
330 teardownIDSProxyServiceConnection(transport
);
331 setupIDSProxyServiceConnection(transport
);
335 static void talkWithIDS(SOSXPCCloudTransportRef transport
, xpc_object_t message
, dispatch_queue_t processQueue
, CloudKeychainReplyBlock replyBlock
)
337 CFErrorRef connectionError
= NULL
;
339 os_activity_t trace_activity
= os_activity_start("talkWithIDS", OS_ACTIVITY_FLAG_DEFAULT
);
340 require_action(transport
->idsProxyServiceConnection
, xit
, connectionError
= makeError(kSOSConnectionNotOpen
));
341 require_action(message
, xit
, connectionError
= makeError(kSOSObjectNotFoundError
));
342 dispatch_retain(processQueue
);
344 xpc_connection_send_message_with_reply(transport
->idsProxyServiceConnection
, message
, transport
->xpc_queue
, ^(xpc_object_t reply
)
346 CFErrorRef serverError
= NULL
;
347 CFTypeRef object
= NULL
;
348 if (xpc_event_filter(transport
->idsProxyServiceConnection
, reply
, &serverError
) && reply
)
350 describeXPCObject("IDS Proxy: reply : ", reply
);
352 secerror("Error from xpc_event_filter: %@", serverError
);
353 xpc_object_t xrv
= xpc_dictionary_get_value(reply
, kMessageKeyValue
);
356 describeXPCObject("talkwithIDS: xrv: ", xrv
);
358 * The given XPC object must be one that was previously returned by
359 * _CFXPCCreateXPCMessageWithCFObject().
361 object
= _CFXPCCreateCFObjectFromXPCObject(xrv
); // CF object is retained; release in callback
362 secnotice("talkwithIDS", "converted CF object: %@", object
);
365 secerror("missing value reply");
367 xpc_object_t xerror
= xpc_dictionary_get_value(reply
, kMessageKeyError
);
369 serverError
= SecCreateCFErrorWithXPCObject(xerror
); // use SecCFCreateErrorWithFormat?
371 dispatch_async(processQueue
, ^{
373 replyBlock(object
, serverError
);
374 CFReleaseSafe(object
);
377 secerror("talkwithIDS callback error: %@", serverError
);
378 CFReleaseSafe(serverError
);
380 dispatch_release(processQueue
);
386 secerror("talkWithIDS error: %@", connectionError
);
387 dispatch_async(processQueue
, ^{
389 replyBlock(NULL
, connectionError
);
390 CFReleaseSafe(connectionError
);
391 dispatch_release(processQueue
);
394 os_activity_end(trace_activity
);
397 typedef void (^ProxyReplyBlock
)(xpc_object_t reply
);
399 static bool messageToProxy(SOSXPCCloudTransportRef transport
, xpc_object_t message
, CFErrorRef
*error
, dispatch_queue_t processQueue
, ProxyReplyBlock replyBlock
) {
400 CFErrorRef connectionError
= NULL
;
402 require_action(transport
->serviceConnection
, xit
, connectionError
= makeError(kSOSConnectionNotOpen
));
403 require_action(message
, xit
, connectionError
= makeError(kSOSObjectNotFoundError
));
405 xpc_connection_send_message_with_reply(transport
->serviceConnection
, message
, processQueue
, replyBlock
);
407 return CFErrorPropagate(connectionError
, error
);
410 static void talkWithKVS(SOSXPCCloudTransportRef transport
, xpc_object_t message
, dispatch_queue_t processQueue
, CloudKeychainReplyBlock replyBlock
)
412 CFErrorRef messagingError
= NULL
;
413 dispatch_retain(processQueue
);
414 bool messaged
= messageToProxy(transport
, message
, &messagingError
, transport
->xpc_queue
, ^(xpc_object_t reply
)
416 CFErrorRef serverError
= NULL
;
417 CFTypeRef object
= NULL
;
418 if (xpc_event_filter(transport
->serviceConnection
, reply
, &serverError
) && reply
)
420 describeXPCObject("getValuesFromKVS: reply : ", reply
);
422 secerror("Error from xpc_event_filter: %@", serverError
);
423 xpc_object_t xrv
= xpc_dictionary_get_value(reply
, kMessageKeyValue
);
426 describeXPCObject("talkWithKVS: xrv: ", xrv
);
428 * The given XPC object must be one that was previously returned by
429 * _CFXPCCreateXPCMessageWithCFObject().
431 object
= _CFXPCCreateCFObjectFromXPCObject(xrv
); // CF object is retained; release in callback
432 secnotice("talkwithkvs", "converted CF object: %@", object
);
435 secerror("missing value reply");
437 xpc_object_t xerror
= xpc_dictionary_get_value(reply
, kMessageKeyError
);
439 serverError
= SecCreateCFErrorWithXPCObject(xerror
); // use SecCFCreateErrorWithFormat?
441 dispatch_async(processQueue
, ^{
443 replyBlock(object
, serverError
);
444 CFReleaseSafe(object
);
447 secerror("callback error: %@", serverError
);
448 CFReleaseSafe(serverError
);
450 dispatch_release(processQueue
);
455 secerror("talkWithKVS error: %@", messagingError
);
456 dispatch_async(processQueue
, ^{
458 replyBlock(NULL
, messagingError
);
459 CFReleaseSafe(messagingError
);
460 dispatch_release(processQueue
);
465 // MARK: ---------- SOSXPCCloudTransport Client Calls ----------
467 /* Concrete function backend implementations. */
468 static void SOSCloudTransportSetItemsChangedBlock(SOSCloudTransportRef transport
,
469 CloudItemsChangedBlock itemsChangedBlock
) {
470 if (transport
->itemsChangedBlock
!= itemsChangedBlock
)
472 secnotice(SOSCKCSCOPE
, "Changing itemsChangedBlock");
473 if (transport
->itemsChangedBlock
)
474 Block_release(transport
->itemsChangedBlock
);
475 transport
->itemsChangedBlock
= Block_copy(itemsChangedBlock
);
479 /* Virtual function backend implementations. */
480 static void SOSCloudTransportPut(SOSCloudTransportRef transport
, CFDictionaryRef values
, dispatch_queue_t processQueue
, CloudKeychainReplyBlock replyBlock
)
482 SOSXPCCloudTransportRef xpcTransport
= (SOSXPCCloudTransportRef
)transport
;
483 secdebug(SOSCKCSCOPE
, "%@", values
);
484 CFErrorRef error
= NULL
;
485 xpc_object_t message
= NULL
;
486 xpc_object_t xobject
= NULL
;
487 require_action(values
, xit
, error
= makeError(kSOSObjectNotFoundError
));
489 message
= xpc_dictionary_create(NULL
, NULL
, 0);
490 xpc_dictionary_set_uint64(message
, kMessageKeyVersion
, kCKDXPCVersion
);
491 xpc_dictionary_set_string(message
, kMessageKeyOperation
, kOperationPUTDictionary
);
493 xobject
= _CFXPCCreateXPCObjectFromCFObject(values
);
494 require_action(xobject
, xit
, error
= makeError(kSOSObjectCantBeConvertedToXPCObject
));
495 xpc_dictionary_set_value(message
, kMessageKeyValue
, xobject
);
496 xpc_release(xobject
);
498 talkWithKVS(xpcTransport
, message
, processQueue
, replyBlock
);
499 xpc_release(message
);
504 replyBlock(NULL
, error
);
505 CFReleaseSafe(error
);
509 void SOSCloudTransportGet(SOSCloudTransportRef transport
, CFArrayRef keysToGet
, dispatch_queue_t processQueue
, CloudKeychainReplyBlock replyBlock
)
511 SOSXPCCloudTransportRef xpcTransport
= (SOSXPCCloudTransportRef
)transport
;
512 secdebug(SOSCKCSCOPE
, "%@", keysToGet
);
513 CFErrorRef error
= NULL
;
514 xpc_object_t xkeysOfInterest
= xpc_dictionary_create(NULL
, NULL
, 0);
515 xpc_object_t xkeysToGet
= keysToGet
? _CFXPCCreateXPCObjectFromCFObject(keysToGet
) : xpc_null_create();
517 require_action(xkeysToGet
, xit
, error
= makeError(kSOSObjectNotFoundError
));
519 if (keysToGet
) // don't add if nulll; will call getall
520 xpc_dictionary_set_value(xkeysOfInterest
, kMessageKeyKeysToGet
, xkeysToGet
);
522 xpc_object_t message
= xpc_dictionary_create(NULL
, NULL
, 0);
523 xpc_dictionary_set_uint64(message
, kMessageKeyVersion
, kCKDXPCVersion
);
524 xpc_dictionary_set_string(message
, kMessageKeyOperation
, kOperationGETv2
);
525 xpc_dictionary_set_value(message
, kMessageKeyValue
, xkeysOfInterest
);
527 talkWithKVS(xpcTransport
, message
, processQueue
, replyBlock
);
528 xpc_release(xkeysToGet
);
529 xpc_release(xkeysOfInterest
);
530 xpc_release(message
);
535 xpc_release(xkeysOfInterest
);
537 xpc_release(xkeysToGet
);
539 replyBlock(NULL
, error
);
540 CFReleaseSafe(error
);
544 // Handles NULL by seting xpc_null.
545 static void SecXPCDictionarySetCFObject(xpc_object_t xdict
, const char *key
, CFTypeRef object
)
547 xpc_object_t xpc_obj
= object
? _CFXPCCreateXPCObjectFromCFObject(object
) : xpc_null_create();
548 xpc_dictionary_set_value(xdict
, key
, xpc_obj
);
549 xpc_release(xpc_obj
);
552 static void SOSCloudTransportGetIDSDeviceID(SOSCloudTransportRef transport
, CloudKeychainReplyBlock replyBlock
)
554 dispatch_queue_t processQueue
= dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT
, 0);
556 SOSXPCCloudTransportRef xpcTransport
= (SOSXPCCloudTransportRef
)transport
;
558 xpc_object_t message
= xpc_dictionary_create(NULL
, NULL
, 0);
559 xpc_dictionary_set_uint64(message
, kMessageKeyVersion
, kCKDXPCVersion
);
560 xpc_dictionary_set_string(message
, kMessageKeyOperation
, kOperationGetDeviceID
);
562 talkWithIDS(xpcTransport
, message
, processQueue
, replyBlock
);
563 xpc_release(message
);
566 static void SOSCloudTransportGetPerformanceStats(SOSCloudTransportRef transport
, dispatch_queue_t processQueue
, CloudKeychainReplyBlock replyBlock
)
568 SOSXPCCloudTransportRef xpcTransport
= (SOSXPCCloudTransportRef
)transport
;
570 xpc_object_t message
= xpc_dictionary_create(NULL
, NULL
, 0);
571 xpc_dictionary_set_uint64(message
, kMessageKeyVersion
, kCKDXPCVersion
);
572 xpc_dictionary_set_string(message
, kMessageKeyOperation
, kOperationGetIDSPerfCounters
);
574 talkWithIDS(xpcTransport
, message
, processQueue
, replyBlock
);
575 xpc_release(message
);
578 static void SOSCloudTransportSendFragmentedIDSMessage(SOSCloudTransportRef transport
, CFDictionaryRef messageData
, CFStringRef deviceName
, CFStringRef peerID
, dispatch_queue_t processQueue
, CloudKeychainReplyBlock replyBlock
){
580 SOSXPCCloudTransportRef xpcTransport
= (SOSXPCCloudTransportRef
)transport
;
581 xpc_object_t xmessageData
= _CFXPCCreateXPCObjectFromCFObject(messageData
);
583 xpc_object_t message
= xpc_dictionary_create(NULL
, NULL
, 0);
584 xpc_dictionary_set_uint64(message
, kMessageKeyVersion
, kCKDXPCVersion
);
585 xpc_dictionary_set_string(message
, kMessageKeyOperation
, kOperationSendFragmentedIDSMessage
);
587 xpc_dictionary_set_value(message
, kMessageKeyValue
, xmessageData
);
588 SecXPCDictionarySetCFObject(message
, kMessageKeyDeviceName
, deviceName
);
589 SecXPCDictionarySetCFObject(message
, kMessageKeyPeerID
, peerID
);
590 talkWithIDS(xpcTransport
, message
, processQueue
, replyBlock
);
592 xpc_release(xmessageData
);
593 xpc_release(message
);
596 static void SOSCloudTransportRetrievePendingMessagesInFlight(SOSCloudTransportRef transport
, dispatch_queue_t processQueue
, CloudKeychainReplyBlock replyBlock
){
598 SOSXPCCloudTransportRef xpcTransport
= (SOSXPCCloudTransportRef
)transport
;
600 xpc_object_t message
= xpc_dictionary_create(NULL
, NULL
, 0);
601 xpc_dictionary_set_uint64(message
, kMessageKeyVersion
, kCKDXPCVersion
);
602 xpc_dictionary_set_string(message
, kMessageKeyOperation
, kOperationGetPendingMesages
);
604 talkWithIDS(xpcTransport
, message
, processQueue
, replyBlock
);
606 xpc_release(message
);
609 static void SOSCloudTransportCheckIDSDeviceIDAvailability(SOSCloudTransportRef transport
, CFArrayRef ids
, CFStringRef peerID
, dispatch_queue_t processQueue
, CloudKeychainReplyBlock replyBlock
)
611 secdebug(SOSCKCSCOPE
, "start");
612 SOSXPCCloudTransportRef xpcTransport
= (SOSXPCCloudTransportRef
)transport
;
614 xpc_object_t xIDSArray
= _CFXPCCreateXPCObjectFromCFObject(ids
);
616 xpc_object_t message
= xpc_dictionary_create(NULL
, NULL
, 0);
617 xpc_dictionary_set_uint64(message
, kMessageKeyVersion
, kCKDXPCVersion
);
618 xpc_dictionary_set_string(message
, kMessageKeyOperation
, kOperationSendDeviceList
);
620 SecXPCDictionarySetCFObject(message
, kMessageKeyPeerID
, peerID
);
621 xpc_dictionary_set_value(message
, kMessageKeyValue
, xIDSArray
);
623 talkWithIDS(xpcTransport
, message
, processQueue
, replyBlock
);
625 xpc_release(xIDSArray
);
626 xpc_release(message
);
630 static void SOSCloudTransportSendIDSMessage(SOSCloudTransportRef transport
, CFDictionaryRef messageData
, CFStringRef deviceName
, CFStringRef peerID
, dispatch_queue_t processQueue
, CloudKeychainReplyBlock replyBlock
){
632 SOSXPCCloudTransportRef xpcTransport
= (SOSXPCCloudTransportRef
)transport
;
633 xpc_object_t xmessageData
= _CFXPCCreateXPCObjectFromCFObject(messageData
);
635 xpc_object_t message
= xpc_dictionary_create(NULL
, NULL
, 0);
636 xpc_dictionary_set_uint64(message
, kMessageKeyVersion
, kCKDXPCVersion
);
637 xpc_dictionary_set_string(message
, kMessageKeyOperation
, kOperationSendIDSMessage
);
639 xpc_dictionary_set_value(message
, kMessageKeyValue
, xmessageData
);
640 SecXPCDictionarySetCFObject(message
, kMessageKeyDeviceName
, deviceName
);
641 SecXPCDictionarySetCFObject(message
, kMessageKeyPeerID
, peerID
);
642 talkWithIDS(xpcTransport
, message
, processQueue
, replyBlock
);
644 xpc_release(xmessageData
);
645 xpc_release(message
);
648 static void SOSCloudTransportUpdateKeys(SOSCloudTransportRef transport
,
649 CFDictionaryRef keys
,
650 CFStringRef accountUUID
,
651 dispatch_queue_t processQueue
,
652 CloudKeychainReplyBlock replyBlock
)
654 SOSXPCCloudTransportRef xpcTransport
= (SOSXPCCloudTransportRef
)transport
;
656 xpc_object_t xkeysOfInterest
= xpc_dictionary_create(NULL
, NULL
, 0);
657 SecXPCDictionarySetCFObject(xkeysOfInterest
, kMessageAllKeys
, keys
);
659 xpc_object_t message
= xpc_dictionary_create(NULL
, NULL
, 0);
660 xpc_dictionary_set_uint64(message
, kMessageKeyVersion
, kCKDXPCVersion
);
661 xpc_dictionary_set_string(message
, kMessageKeyOperation
, kOperationRegisterKeys
);
662 xpc_dictionary_set_value(message
, kMessageKeyValue
, xkeysOfInterest
);
663 SecXPCDictionarySetCFObject(message
, kMessageKeyAccountUUID
, accountUUID
);
665 talkWithKVS(xpcTransport
, message
, processQueue
, replyBlock
);
666 xpc_release(message
);
667 xpc_release(xkeysOfInterest
);
670 static void SOSCloudTransportRemoveKeys(SOSCloudTransportRef transport
,
672 CFStringRef accountUUID
,
673 dispatch_queue_t processQueue
,
674 CloudKeychainReplyBlock replyBlock
)
676 SOSXPCCloudTransportRef xpcTransport
= (SOSXPCCloudTransportRef
)transport
;
678 xpc_object_t message
= xpc_dictionary_create(NULL
, NULL
, 0);
679 xpc_dictionary_set_uint64(message
, kMessageKeyVersion
, kCKDXPCVersion
);
681 xpc_dictionary_set_string(message
, kMessageKeyOperation
, kOperationRemoveKeys
);
682 SecXPCDictionarySetCFObject(message
, kMessageKeyAccountUUID
, accountUUID
);
683 SecXPCDictionarySetCFObject(message
, kMessageKeyValue
, keys
);
685 talkWithKVS(xpcTransport
, message
, processQueue
, replyBlock
);
686 xpc_release(message
);
689 static void SOSCloudTransportGetAll(SOSCloudTransportRef transport
, dispatch_queue_t processQueue
, CloudKeychainReplyBlock replyBlock
)
691 secdebug(SOSCKCSCOPE
, "start");
692 SOSCloudTransportGet(transport
, NULL
, processQueue
, replyBlock
);
695 static void SOSCloudTransportSync(SOSCloudTransportRef transport
, dispatch_queue_t processQueue
, CloudKeychainReplyBlock replyBlock
)
697 SOSXPCCloudTransportRef xpcTransport
= (SOSXPCCloudTransportRef
)transport
;
698 secdebug(SOSCKCSCOPE
, "start");
699 xpc_object_t message
= xpc_dictionary_create(NULL
, NULL
, 0);
700 xpc_dictionary_set_uint64(message
, kMessageKeyVersion
, kCKDXPCVersion
);
701 xpc_dictionary_set_string(message
, kMessageKeyOperation
, kOperationSynchronize
);
702 talkWithKVS(xpcTransport
, message
, processQueue
, replyBlock
);
703 xpc_release(message
);
706 static void SOSCloudTransportSyncAndWait(SOSCloudTransportRef transport
, dispatch_queue_t processQueue
, CloudKeychainReplyBlock replyBlock
)
708 SOSXPCCloudTransportRef xpcTransport
= (SOSXPCCloudTransportRef
)transport
;
709 secnotice(SOSCKCSCOPE
, "%s XPC request to CKD: %s", kWAIT2MINID
, kOperationSynchronizeAndWait
);
711 xpc_object_t message
= xpc_dictionary_create(NULL
, NULL
, 0);
712 xpc_dictionary_set_uint64(message
, kMessageKeyVersion
, kCKDXPCVersion
);
713 xpc_dictionary_set_string(message
, kMessageKeyOperation
, kOperationSynchronizeAndWait
);
715 talkWithKVS(xpcTransport
, message
, processQueue
, replyBlock
);
716 xpc_release(message
);
719 static void SOSCloudTransportClearAll(SOSCloudTransportRef transport
, dispatch_queue_t processQueue
, CloudKeychainReplyBlock replyBlock
)
721 SOSXPCCloudTransportRef xpcTransport
= (SOSXPCCloudTransportRef
)transport
;
722 secdebug(SOSCKCSCOPE
, "start");
723 xpc_object_t message
= xpc_dictionary_create(NULL
, NULL
, 0);
724 xpc_dictionary_set_uint64(message
, kMessageKeyVersion
, kCKDXPCVersion
);
725 xpc_dictionary_set_string(message
, kMessageKeyOperation
, kOperationClearStore
);
726 talkWithKVS(xpcTransport
, message
, processQueue
, replyBlock
);
727 xpc_release(message
);
730 static void SOSCloudTransportRequestSyncWithPeers(SOSCloudTransportRef transport
, CFArrayRef
/* CFStringRef */ peers
, CFArrayRef
/* CFStringRef */ backupPeers
, dispatch_queue_t processQueue
, CloudKeychainReplyBlock replyBlock
)
732 secdebug(SOSCKCSCOPE
, "start");
733 SOSXPCCloudTransportRef xpcTransport
= (SOSXPCCloudTransportRef
)transport
;
735 xpc_object_t xpcmessage
= xpc_dictionary_create(NULL
, NULL
, 0);
737 xpc_dictionary_set_uint64(xpcmessage
, kMessageKeyVersion
, kCKDXPCVersion
);
738 xpc_dictionary_set_string(xpcmessage
, kMessageKeyOperation
, kOperationRequestSyncWithPeers
);
740 SecXPCDictionarySetCFObject(xpcmessage
, kMessageKeyPeerIDList
, peers
);
741 SecXPCDictionarySetCFObject(xpcmessage
, kMesssgeKeyBackupPeerIDList
, backupPeers
);
743 talkWithKVS(xpcTransport
, xpcmessage
, processQueue
, replyBlock
);
745 xpc_release(xpcmessage
);
749 static bool SOSCloudTransportHasPeerSyncPending(SOSCloudTransportRef transport
, CFStringRef peerID
, CFErrorRef
* error
)
751 secdebug(SOSCKCSCOPE
, "start");
752 SOSXPCCloudTransportRef xpcTransport
= (SOSXPCCloudTransportRef
)transport
;
754 __block
bool isSyncing
= false;
756 xpc_object_t xpcmessage
= xpc_dictionary_create(NULL
, NULL
, 0);
758 xpc_dictionary_set_uint64(xpcmessage
, kMessageKeyVersion
, kCKDXPCVersion
);
759 xpc_dictionary_set_string(xpcmessage
, kMessageKeyOperation
, kOperationHasPendingSyncWithPeer
);
761 SecXPCDictionarySetCFObject(xpcmessage
, kMessageKeyPeerID
, peerID
);
763 dispatch_semaphore_t wait
= dispatch_semaphore_create(0);
764 bool sent
= messageToProxy(xpcTransport
, xpcmessage
, error
, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT
, 0), ^(xpc_object_t reply
) {
765 isSyncing
= xpc_dictionary_get_bool(reply
, kMessageKeyValue
);
766 dispatch_semaphore_signal(wait
);
770 dispatch_semaphore_wait(wait
, DISPATCH_TIME_FOREVER
);
773 dispatch_release(wait
);
775 return sent
&& isSyncing
;
779 static bool SOSCloudTransportHasPendingKey(SOSCloudTransportRef transport
, CFStringRef keyName
, CFErrorRef
* error
)
781 secdebug(SOSCKCSCOPE
, "start");
782 SOSXPCCloudTransportRef xpcTransport
= (SOSXPCCloudTransportRef
)transport
;
784 __block
bool kvsHasMessage
= false;
786 xpc_object_t xpcmessage
= xpc_dictionary_create(NULL
, NULL
, 0);
788 xpc_dictionary_set_uint64(xpcmessage
, kMessageKeyVersion
, kCKDXPCVersion
);
789 xpc_dictionary_set_string(xpcmessage
, kMessageKeyOperation
, kOperationHasPendingKey
);
791 SecXPCDictionarySetCFObject(xpcmessage
, kMessageKeyKey
, keyName
);
793 dispatch_semaphore_t kvsWait
= dispatch_semaphore_create(0);
794 bool kvsSent
= messageToProxy(xpcTransport
, xpcmessage
, error
, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT
, 0), ^(xpc_object_t reply
) {
795 kvsHasMessage
= xpc_dictionary_get_bool(reply
, kMessageKeyValue
);
796 dispatch_semaphore_signal(kvsWait
);
800 dispatch_semaphore_wait(kvsWait
, DISPATCH_TIME_FOREVER
);
803 dispatch_release(kvsWait
);
805 return kvsSent
&& kvsHasMessage
;
809 static void SOSCloudTransportRequestEnsurePeerRegistration(SOSCloudTransportRef transport
, dispatch_queue_t processQueue
, CloudKeychainReplyBlock replyBlock
)
811 secdebug(SOSCKCSCOPE
, "start");
812 SOSXPCCloudTransportRef xpcTransport
= (SOSXPCCloudTransportRef
)transport
;
814 xpc_object_t xpcmessage
= xpc_dictionary_create(NULL
, NULL
, 0);
815 xpc_dictionary_set_uint64(xpcmessage
, kMessageKeyVersion
, kCKDXPCVersion
);
816 xpc_dictionary_set_string(xpcmessage
, kMessageKeyOperation
, kOperationRequestEnsurePeerRegistration
);
818 talkWithKVS(xpcTransport
, xpcmessage
, processQueue
, replyBlock
);
820 xpc_release(xpcmessage
);
823 static void SOSCloudTransportRequestPerfCounters(SOSCloudTransportRef transport
, dispatch_queue_t processQueue
, CloudKeychainReplyBlock replyBlock
)
825 secdebug(SOSCKCSCOPE
, "start");
826 SOSXPCCloudTransportRef xpcTransport
= (SOSXPCCloudTransportRef
)transport
;
828 xpc_object_t xpcmessage
= xpc_dictionary_create(NULL
, NULL
, 0);
829 xpc_dictionary_set_uint64(xpcmessage
, kMessageKeyVersion
, kCKDXPCVersion
);
830 xpc_dictionary_set_string(xpcmessage
, kMessageKeyOperation
, kOperationPerfCounters
);
832 talkWithKVS(xpcTransport
, xpcmessage
, processQueue
, replyBlock
);
834 xpc_release(xpcmessage
);
838 static void SOSCloudTransportFlush(SOSCloudTransportRef transport
, dispatch_queue_t processQueue
, CloudKeychainReplyBlock replyBlock
)
840 secdebug(SOSCKCSCOPE
, "start");
841 SOSXPCCloudTransportRef xpcTransport
= (SOSXPCCloudTransportRef
)transport
;
843 xpc_object_t xpcmessage
= xpc_dictionary_create(NULL
, NULL
, 0);
844 xpc_dictionary_set_uint64(xpcmessage
, kMessageKeyVersion
, kCKDXPCVersion
);
845 xpc_dictionary_set_string(xpcmessage
, kMessageKeyOperation
, kOperationFlush
);
847 talkWithKVS(xpcTransport
, xpcmessage
, processQueue
, replyBlock
);
849 xpc_release(xpcmessage
);
852 static SOSCloudTransportRef
SOSCloudTransportCreateXPCTransport(void)
854 SOSXPCCloudTransportRef st
;
855 st
= calloc(1, sizeof(*st
));
856 st
->transport
.put
= SOSCloudTransportPut
;
857 st
->transport
.updateKeys
= SOSCloudTransportUpdateKeys
;
858 st
->transport
.sendIDSMessage
= SOSCloudTransportSendIDSMessage
;
859 st
->transport
.sendFragmentedIDSMessage
= SOSCloudTransportSendFragmentedIDSMessage
;
860 st
->transport
.retrieveMessages
= SOSCloudTransportRetrievePendingMessagesInFlight
;
862 st
->transport
.getDeviceID
= SOSCloudTransportGetIDSDeviceID
;
863 st
->transport
.get
= SOSCloudTransportGet
;
864 st
->transport
.getAll
= SOSCloudTransportGetAll
;
865 st
->transport
.synchronize
= SOSCloudTransportSync
;
866 st
->transport
.synchronizeAndWait
= SOSCloudTransportSyncAndWait
;
867 st
->transport
.clearAll
= SOSCloudTransportClearAll
;
868 st
->transport
.requestSyncWithPeers
= SOSCloudTransportRequestSyncWithPeers
;
869 st
->transport
.hasPeerSyncPending
= SOSCloudTransportHasPeerSyncPending
;
870 st
->transport
.hasPendingKey
= SOSCloudTransportHasPendingKey
;
871 st
->transport
.requestEnsurePeerRegistration
= SOSCloudTransportRequestEnsurePeerRegistration
;
872 st
->transport
.requestPerfCounters
= SOSCloudTransportRequestPerfCounters
;
873 st
->transport
.getIDSDeviceAvailability
= SOSCloudTransportCheckIDSDeviceIDAvailability
;
874 st
->transport
.flush
= SOSCloudTransportFlush
;
875 st
->transport
.removeKeys
= SOSCloudTransportRemoveKeys
;
876 st
->transport
.counters
= SOSCloudTransportGetPerformanceStats
;
877 st
->transport
.itemsChangedBlock
= Block_copy(^CFArrayRef(CFDictionaryRef changes
) {
878 secerror("Calling default itemsChangedBlock - fatal: %@", changes
);
882 SOSXPCCloudTransportInit(st
);
883 return &st
->transport
;
886 // MARK: ---------- SOSCloudKeychain concrete client APIs ----------
887 void SOSCloudKeychainSetItemsChangedBlock(CloudItemsChangedBlock itemsChangedBlock
)
889 secdebug(SOSCKCSCOPE
, "start");
890 SOSCloudTransportSetItemsChangedBlock(SOSCloudTransportDefaultTransport(),
894 // MARK: ---------- SOSCloudKeychain virtual client APIs ----------
896 void SOSCloudKeychainPutObjectsInCloud(CFDictionaryRef objects
, dispatch_queue_t processQueue
, CloudKeychainReplyBlock replyBlock
)
898 SOSCloudTransportRef cTransportRef
= SOSCloudTransportDefaultTransport();
900 cTransportRef
->put(cTransportRef
, objects
, processQueue
, replyBlock
);
903 void SOSCloudKeychainUpdateKeys(CFDictionaryRef keys
, CFStringRef accountUUID
, dispatch_queue_t processQueue
, CloudKeychainReplyBlock replyBlock
)
905 SOSCloudTransportRef cTransportRef
= SOSCloudTransportDefaultTransport();
907 cTransportRef
->updateKeys(cTransportRef
, keys
, accountUUID
, processQueue
, replyBlock
);
911 void SOSCloudKeychainRemoveKeys(CFArrayRef keys
, CFStringRef accountUUID
, dispatch_queue_t processQueue
, CloudKeychainReplyBlock replyBlock
)
913 SOSCloudTransportRef cTransportRef
= SOSCloudTransportDefaultTransport();
915 cTransportRef
->removeKeys(cTransportRef
, keys
, accountUUID
, processQueue
, replyBlock
);
918 void SOSCloudKeychainSendIDSMessage(CFDictionaryRef message
, CFStringRef deviceName
, CFStringRef peerID
, dispatch_queue_t processQueue
, CFBooleanRef fragmentation
, CloudKeychainReplyBlock replyBlock
)
920 SOSCloudTransportRef cTransportRef
= SOSCloudTransportDefaultTransport();
922 if(cTransportRef
&& fragmentation
== kCFBooleanTrue
)
923 cTransportRef
->sendFragmentedIDSMessage(cTransportRef
, message
, deviceName
, peerID
, processQueue
, replyBlock
);
924 else if(cTransportRef
)
925 cTransportRef
->sendIDSMessage(cTransportRef
, message
, deviceName
, peerID
, processQueue
, replyBlock
);
929 void SOSCloudKeychainRetrievePendingMessageFromProxy(dispatch_queue_t processQueue
, CloudKeychainReplyBlock replyBlock
)
931 SOSCloudTransportRef cTransportRef
= SOSCloudTransportDefaultTransport();
934 cTransportRef
->retrieveMessages(cTransportRef
, processQueue
, replyBlock
);
937 void SOSCloudKeychainRetrieveCountersFromIDSProxy(dispatch_queue_t processQueue
, CloudKeychainReplyBlock replyBlock
)
939 SOSCloudTransportRef cTransportRef
= SOSCloudTransportDefaultTransport();
942 cTransportRef
->counters(cTransportRef
, processQueue
, replyBlock
);
945 void SOSCloudKeychainGetIDSDeviceID(CloudKeychainReplyBlock replyBlock
)
947 SOSCloudTransportRef cTransportRef
= SOSCloudTransportDefaultTransport();
949 cTransportRef
->getDeviceID(cTransportRef
, replyBlock
);
952 void SOSCloudKeychainGetIDSDeviceAvailability(CFArrayRef ids
, CFStringRef peerID
, dispatch_queue_t processQueue
, CloudKeychainReplyBlock replyBlock
){
954 SOSCloudTransportRef cTransportRef
= SOSCloudTransportDefaultTransport();
957 cTransportRef
->getIDSDeviceAvailability(cTransportRef
, ids
, peerID
, processQueue
, replyBlock
);
959 CF_RETURNS_RETAINED CFArrayRef
SOSCloudKeychainHandleUpdateMessage(CFDictionaryRef updates
)
961 CFArrayRef result
= NULL
;
962 SOSCloudTransportRef cTransportRef
= SOSCloudTransportDefaultTransport();
963 if (cTransportRef
->itemsChangedBlock
)
964 result
= ((CloudItemsChangedBlock
)cTransportRef
->itemsChangedBlock
)(updates
);
968 void SOSCloudKeychainGetObjectsFromCloud(CFArrayRef keysToGet
, dispatch_queue_t processQueue
, CloudKeychainReplyBlock replyBlock
)
970 SOSCloudTransportRef cTransportRef
= SOSCloudTransportDefaultTransport();
972 cTransportRef
->get(cTransportRef
, keysToGet
, processQueue
, replyBlock
);
975 void SOSCloudKeychainGetAllObjectsFromCloud(dispatch_queue_t processQueue
, CloudKeychainReplyBlock replyBlock
)
977 SOSCloudTransportRef cTransportRef
= SOSCloudTransportDefaultTransport();
979 cTransportRef
->getAll(cTransportRef
, processQueue
, replyBlock
);
982 void SOSCloudKeychainSynchronizeAndWait(dispatch_queue_t processQueue
, CloudKeychainReplyBlock replyBlock
)
984 SOSCloudTransportRef cTransportRef
= SOSCloudTransportDefaultTransport();
986 cTransportRef
->synchronizeAndWait(cTransportRef
, processQueue
, replyBlock
);
990 void SOSCloudKeychainSynchronize(dispatch_queue_t processQueue
, CloudKeychainReplyBlock replyBlock
)
992 SOSCloudTransportRef cTransportRef
= SOSCloudTransportDefaultTransport();
994 cTransportRef
->synchronize(cTransportRef
, processQueue
, replyBlock
);
998 void SOSCloudKeychainClearAll(dispatch_queue_t processQueue
, CloudKeychainReplyBlock replyBlock
)
1000 SOSCloudTransportRef cTransportRef
= SOSCloudTransportDefaultTransport();
1002 cTransportRef
->clearAll(cTransportRef
, processQueue
, replyBlock
);
1005 void SOSCloudKeychainRequestSyncWithPeers(CFArrayRef
/* CFStringRef */ peers
, CFArrayRef
/* CFStringRef */ backupPeers
, dispatch_queue_t processQueue
, CloudKeychainReplyBlock replyBlock
)
1007 SOSCloudTransportRef cTransportRef
= SOSCloudTransportDefaultTransport();
1009 cTransportRef
->requestSyncWithPeers(cTransportRef
, peers
, backupPeers
, processQueue
, replyBlock
);
1012 bool SOSCloudKeychainHasPendingKey(CFStringRef keyName
, CFErrorRef
* error
) {
1013 SOSCloudTransportRef cTransportRef
= SOSCloudTransportDefaultTransport();
1015 return cTransportRef
&& cTransportRef
->hasPendingKey(cTransportRef
, keyName
, error
);
1018 bool SOSCloudKeychainHasPendingSyncWithPeer(CFStringRef peerID
, CFErrorRef
* error
) {
1019 SOSCloudTransportRef cTransportRef
= SOSCloudTransportDefaultTransport();
1021 return cTransportRef
&& cTransportRef
->hasPeerSyncPending(cTransportRef
, peerID
, error
);
1024 void SOSCloudKeychainRequestEnsurePeerRegistration(dispatch_queue_t processQueue
, CloudKeychainReplyBlock replyBlock
)
1026 SOSCloudTransportRef cTransportRef
= SOSCloudTransportDefaultTransport();
1028 cTransportRef
->requestEnsurePeerRegistration(cTransportRef
, processQueue
, replyBlock
);
1031 void SOSCloudKeychainRequestPerfCounters(dispatch_queue_t processQueue
, CloudKeychainReplyBlock replyBlock
)
1033 SOSCloudTransportRef cTransportRef
= SOSCloudTransportDefaultTransport();
1035 cTransportRef
->requestPerfCounters(cTransportRef
, processQueue
, replyBlock
);
1039 void SOSCloudKeychainFlush(dispatch_queue_t processQueue
, CloudKeychainReplyBlock replyBlock
)
1041 SOSCloudTransportRef cTransportRef
= SOSCloudTransportDefaultTransport();
1043 cTransportRef
->flush(cTransportRef
, processQueue
, replyBlock
);