1 #include <Security/SecureObjectSync/SOSAccountPriv.h>
2 #include <Security/SecureObjectSync/SOSTransport.h>
3 #include <Security/SecureObjectSync/SOSTransportKeyParameter.h>
4 #include <Security/SecureObjectSync/SOSTransportKeyParameterKVS.h>
5 #include <Security/SecureObjectSync/SOSKVSKeys.h>
6 #include <SOSCloudKeychainClient.h>
7 #include <utilities/SecCFWrappers.h>
8 #include <SOSCloudCircleServer.h>
10 static bool SOSTransportKeyParameterKVSPublishCloudParameters(SOSTransportKeyParameterKVSRef transport
, CFDataRef newParameters
, CFErrorRef
*error
);
11 static bool publishCloudParameters(SOSTransportKeyParameterRef transport
, CFDataRef data
, CFErrorRef
* error
);
12 static bool SOSTransportKeyParameterKVSUpdateKVS(CFDictionaryRef changes
, CFErrorRef
*error
);
13 static void destroy(SOSTransportKeyParameterRef transport
);
14 static inline CFIndex
getTransportType(SOSTransportKeyParameterRef transport
, CFErrorRef
*error
);
16 struct __OpaqueSOSTransportKeyParameterKVS
{
17 struct __OpaqueSOSTransportKeyParameter k
;
20 static bool handleKeyParameterChanges(SOSTransportKeyParameterRef transport
, CFDataRef data
, CFErrorRef error
){
21 SOSAccountRef account
= transport
->account
;
22 return SOSAccountHandleParametersChange(account
, data
, &error
);
26 static inline CFIndex
getTransportType(SOSTransportKeyParameterRef transport
, CFErrorRef
*error
){
31 static bool setToNewAccount(SOSTransportKeyParameterRef transport
, SOSAccountRef account
){
32 SOSAccountSetToNew(account
);
36 SOSTransportKeyParameterKVSRef
SOSTransportKeyParameterKVSCreate(SOSAccountRef account
, CFErrorRef
*error
) {
37 SOSTransportKeyParameterKVSRef tkvs
= (SOSTransportKeyParameterKVSRef
) SOSTransportKeyParameterCreateForSubclass(sizeof(struct __OpaqueSOSTransportKeyParameterKVS
) - sizeof(CFRuntimeBase
), account
, error
);
39 tkvs
->k
.publishCloudParameters
= publishCloudParameters
;
40 tkvs
->k
.handleKeyParameterChanges
= handleKeyParameterChanges
;
41 tkvs
->k
.setToNewAccount
= setToNewAccount
;
42 tkvs
->k
.destroy
= destroy
;
43 tkvs
->k
.getTransportType
= getTransportType
;
44 SOSRegisterTransportKeyParameter((SOSTransportKeyParameterRef
)tkvs
);
49 static void destroy(SOSTransportKeyParameterRef transport
){
50 SOSUnregisterTransportKeyParameter(transport
);
53 bool SOSTransportKeyParameterKVSHandleCloudParameterChange(SOSTransportKeyParameterRef transport
, CFDataRef data
, CFErrorRef
* error
){
54 SOSTransportKeyParameterKVSRef tkvs
= (SOSTransportKeyParameterKVSRef
)transport
;
55 SOSAccountRef account
= tkvs
->k
.account
;
57 return SOSAccountHandleParametersChange(account
, data
, error
);
61 bool SOSTransportKeyParameterKVSAppendKeyInterests(SOSTransportKeyParameterKVSRef transport
, CFMutableArrayRef alwaysKeys
, CFMutableArrayRef afterFirstUnlockKeys
, CFMutableArrayRef unlockedKeys
, CFErrorRef
*error
){
62 CFArrayAppendValue(alwaysKeys
, kSOSKVSKeyParametersKey
);
67 static bool publishCloudParameters(SOSTransportKeyParameterRef transport
, CFDataRef data
, CFErrorRef
* error
)
69 return SOSTransportKeyParameterKVSPublishCloudParameters((SOSTransportKeyParameterKVSRef
)transport
, data
, error
);
72 static bool SOSTransportKeyParameterKVSUpdateKVS(CFDictionaryRef changes
, CFErrorRef
*error
){
73 CloudKeychainReplyBlock log_error
= ^(CFDictionaryRef returnedValues __unused
, CFErrorRef block_error
) {
75 secerror("Error putting: %@", block_error
);
79 SOSCloudKeychainPutObjectsInCloud(changes
, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT
, 0), log_error
);
83 static bool SOSTransportKeyParameterKVSPublishCloudParameters(SOSTransportKeyParameterKVSRef transport
, CFDataRef newParameters
, CFErrorRef
*error
)
85 SOSAccountRef a
= SOSTransportKeyParameterGetAccount((SOSTransportKeyParameterRef
)transport
);
86 CFDictionaryRef changes
= NULL
;
87 CFDataRef timeData
= NULL
;
88 bool waitForeverForSynchronization
= true;
90 CFMutableStringRef timeDescription
= CFStringCreateMutableCopy(kCFAllocatorDefault
, 0, CFSTR("["));
91 CFAbsoluteTime currentTimeAndDate
= CFAbsoluteTimeGetCurrent();
93 withStringOfAbsoluteTime(currentTimeAndDate
, ^(CFStringRef decription
) {
94 CFStringAppend(timeDescription
, decription
);
96 CFStringAppend(timeDescription
, CFSTR("]"));
98 timeData
= CFStringCreateExternalRepresentation(NULL
,timeDescription
,
99 kCFStringEncodingUTF8
, '?');
101 CFMutableDataRef timeAndKeyParametersMutable
= CFDataCreateMutable(kCFAllocatorDefault
, CFDataGetLength(timeData
) + CFDataGetLength(newParameters
));
102 CFDataAppend(timeAndKeyParametersMutable
, timeData
);
103 CFDataAppend(timeAndKeyParametersMutable
, newParameters
);
104 CFDataRef timeAndKeyParameters
= CFDataCreateCopy(kCFAllocatorDefault
, timeAndKeyParametersMutable
);
106 CFStringRef ourPeerID
= SOSAccountGetMyPeerID(a
);
108 if(ourPeerID
!= NULL
){
109 CFStringRef keyParamKey
= SOSLastKeyParametersPushedKeyCreateWithPeerID(ourPeerID
);
111 changes
= CFDictionaryCreateForCFTypes(kCFAllocatorDefault
,
112 kSOSKVSKeyParametersKey
, newParameters
,
113 keyParamKey
, timeAndKeyParameters
,
115 CFReleaseNull(keyParamKey
);
119 CFStringRef keyParamKeyWithAccount
= SOSLastKeyParametersPushedKeyCreateWithAccountGestalt(a
);
120 changes
= CFDictionaryCreateForCFTypes(kCFAllocatorDefault
,
121 kSOSKVSKeyParametersKey
, newParameters
,
122 keyParamKeyWithAccount
, timeAndKeyParameters
,
124 CFReleaseNull(keyParamKeyWithAccount
);
127 bool success
= SOSTransportKeyParameterKVSUpdateKVS(changes
, error
);
129 sync_the_last_data_to_kvs(a
, waitForeverForSynchronization
);
131 CFReleaseNull(changes
);
132 CFReleaseNull(timeAndKeyParametersMutable
);
133 CFReleaseNull(timeAndKeyParameters
);
134 CFReleaseNull(timeData
);
135 CFReleaseNull(timeDescription
);