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
){
63 CFArrayAppendValue(alwaysKeys
, kSOSKVSKeyParametersKey
);
68 static bool publishCloudParameters(SOSTransportKeyParameterRef transport
, CFDataRef data
, CFErrorRef
* error
)
70 return SOSTransportKeyParameterKVSPublishCloudParameters((SOSTransportKeyParameterKVSRef
)transport
, data
, error
);
73 static bool SOSTransportKeyParameterKVSUpdateKVS(CFDictionaryRef changes
, CFErrorRef
*error
){
74 CloudKeychainReplyBlock log_error
= ^(CFDictionaryRef returnedValues __unused
, CFErrorRef error
) {
76 secerror("Error putting: %@", error
);
81 SOSCloudKeychainPutObjectsInCloud(changes
, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT
, 0), log_error
);
85 static bool SOSTransportKeyParameterKVSPublishCloudParameters(SOSTransportKeyParameterKVSRef transport
, CFDataRef newParameters
, CFErrorRef
*error
)
87 SOSAccountRef a
= SOSTransportKeyParameterGetAccount((SOSTransportKeyParameterRef
)transport
);
88 CFDictionaryRef changes
= NULL
;
89 CFDataRef timeData
= NULL
;
91 CFMutableStringRef timeDescription
= CFStringCreateMutableCopy(kCFAllocatorDefault
, 0, CFSTR("["));
92 CFAbsoluteTime currentTimeAndDate
= CFAbsoluteTimeGetCurrent();
94 withStringOfAbsoluteTime(currentTimeAndDate
, ^(CFStringRef decription
) {
95 CFStringAppend(timeDescription
, decription
);
97 CFStringAppend(timeDescription
, CFSTR("]"));
99 timeData
= CFStringCreateExternalRepresentation(NULL
,timeDescription
,
100 kCFStringEncodingUTF8
, '?');
102 CFMutableDataRef timeAndKeyParametersMutable
= CFDataCreateMutable(kCFAllocatorDefault
, CFDataGetLength(timeData
) + CFDataGetLength(newParameters
));
103 CFDataAppend(timeAndKeyParametersMutable
, timeData
);
104 CFDataAppend(timeAndKeyParametersMutable
, newParameters
);
105 CFDataRef timeAndKeyParameters
= CFDataCreateCopy(kCFAllocatorDefault
, timeAndKeyParametersMutable
);
107 CFStringRef ourPeerID
= SOSAccountGetMyPeerID(a
);
109 if(ourPeerID
!= NULL
){
110 CFStringRef keyParamKey
= SOSLastKeyParametersPushedKeyCreateWithPeerID(ourPeerID
);
112 changes
= CFDictionaryCreateForCFTypes(kCFAllocatorDefault
,
113 kSOSKVSKeyParametersKey
, newParameters
,
114 keyParamKey
, timeAndKeyParameters
,
116 CFReleaseNull(keyParamKey
);
120 CFStringRef keyParamKeyWithAccount
= SOSLastKeyParametersPushedKeyCreateWithAccountGestalt(a
);
121 changes
= CFDictionaryCreateForCFTypes(kCFAllocatorDefault
,
122 kSOSKVSKeyParametersKey
, newParameters
,
123 keyParamKeyWithAccount
, timeAndKeyParameters
,
125 CFReleaseNull(keyParamKeyWithAccount
);
128 bool success
= SOSTransportKeyParameterKVSUpdateKVS(changes
, error
);
130 sync_the_last_data_to_kvs(a
);
132 CFReleaseNull(changes
);
133 CFReleaseNull(timeAndKeyParametersMutable
);
134 CFReleaseNull(timeAndKeyParameters
);
135 CFReleaseNull(timeData
);
136 CFReleaseNull(timeDescription
);