]> git.saurik.com Git - apple/security.git/blob - OSX/sec/SOSCircle/SecureObjectSync/SOSTransportKeyParameterKVS.c
Security-57337.40.85.tar.gz
[apple/security.git] / OSX / sec / SOSCircle / SecureObjectSync / SOSTransportKeyParameterKVS.c
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>
9
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);
15
16 struct __OpaqueSOSTransportKeyParameterKVS{
17 struct __OpaqueSOSTransportKeyParameter k;
18 };
19
20 static bool handleKeyParameterChanges(SOSTransportKeyParameterRef transport, CFDataRef data, CFErrorRef error){
21 SOSAccountRef account = transport->account;
22 return SOSAccountHandleParametersChange(account, data, &error);
23
24 }
25
26 static inline CFIndex getTransportType(SOSTransportKeyParameterRef transport, CFErrorRef *error){
27 return kKVS;
28 }
29
30
31 static bool setToNewAccount(SOSTransportKeyParameterRef transport, SOSAccountRef account){
32 SOSAccountSetToNew(account);
33 return true;
34 }
35
36 SOSTransportKeyParameterKVSRef SOSTransportKeyParameterKVSCreate(SOSAccountRef account, CFErrorRef *error) {
37 SOSTransportKeyParameterKVSRef tkvs = (SOSTransportKeyParameterKVSRef) SOSTransportKeyParameterCreateForSubclass(sizeof(struct __OpaqueSOSTransportKeyParameterKVS) - sizeof(CFRuntimeBase), account, error);
38 if(tkvs){
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);
45 }
46 return tkvs;
47 }
48
49 static void destroy(SOSTransportKeyParameterRef transport){
50 SOSUnregisterTransportKeyParameter(transport);
51 }
52
53 bool SOSTransportKeyParameterKVSHandleCloudParameterChange(SOSTransportKeyParameterRef transport, CFDataRef data, CFErrorRef* error){
54 SOSTransportKeyParameterKVSRef tkvs = (SOSTransportKeyParameterKVSRef)transport;
55 SOSAccountRef account = tkvs->k.account;
56
57 return SOSAccountHandleParametersChange(account, data, error);
58 }
59
60
61 bool SOSTransportKeyParameterKVSAppendKeyInterests(SOSTransportKeyParameterKVSRef transport, CFMutableArrayRef alwaysKeys, CFMutableArrayRef afterFirstUnlockKeys, CFMutableArrayRef unlockedKeys, CFErrorRef*error){
62
63 CFArrayAppendValue(alwaysKeys, kSOSKVSKeyParametersKey);
64
65 return true;
66 }
67
68 static bool publishCloudParameters(SOSTransportKeyParameterRef transport, CFDataRef data, CFErrorRef* error)
69 {
70 return SOSTransportKeyParameterKVSPublishCloudParameters((SOSTransportKeyParameterKVSRef)transport, data, error);
71 }
72
73 static bool SOSTransportKeyParameterKVSUpdateKVS(CFDictionaryRef changes, CFErrorRef *error){
74 CloudKeychainReplyBlock log_error = ^(CFDictionaryRef returnedValues __unused, CFErrorRef error) {
75 if (error) {
76 secerror("Error putting: %@", error);
77 CFReleaseSafe(error);
78 }
79 };
80
81 SOSCloudKeychainPutObjectsInCloud(changes, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), log_error);
82 return true;
83 }
84
85 static bool SOSTransportKeyParameterKVSPublishCloudParameters(SOSTransportKeyParameterKVSRef transport, CFDataRef newParameters, CFErrorRef *error)
86 {
87 SOSAccountRef a = SOSTransportKeyParameterGetAccount((SOSTransportKeyParameterRef)transport);
88 CFDictionaryRef changes = NULL;
89 CFDataRef timeData = NULL;
90 bool waitForeverForSynchronization = true;
91
92 CFMutableStringRef timeDescription = CFStringCreateMutableCopy(kCFAllocatorDefault, 0, CFSTR("["));
93 CFAbsoluteTime currentTimeAndDate = CFAbsoluteTimeGetCurrent();
94
95 withStringOfAbsoluteTime(currentTimeAndDate, ^(CFStringRef decription) {
96 CFStringAppend(timeDescription, decription);
97 });
98 CFStringAppend(timeDescription, CFSTR("]"));
99
100 timeData = CFStringCreateExternalRepresentation(NULL,timeDescription,
101 kCFStringEncodingUTF8, '?');
102
103 CFMutableDataRef timeAndKeyParametersMutable = CFDataCreateMutable(kCFAllocatorDefault, CFDataGetLength(timeData) + CFDataGetLength(newParameters));
104 CFDataAppend(timeAndKeyParametersMutable, timeData);
105 CFDataAppend(timeAndKeyParametersMutable, newParameters);
106 CFDataRef timeAndKeyParameters = CFDataCreateCopy(kCFAllocatorDefault, timeAndKeyParametersMutable);
107
108 CFStringRef ourPeerID = SOSAccountGetMyPeerID(a);
109
110 if(ourPeerID != NULL){
111 CFStringRef keyParamKey = SOSLastKeyParametersPushedKeyCreateWithPeerID(ourPeerID);
112
113 changes = CFDictionaryCreateForCFTypes(kCFAllocatorDefault,
114 kSOSKVSKeyParametersKey, newParameters,
115 keyParamKey, timeAndKeyParameters,
116 NULL);
117 CFReleaseNull(keyParamKey);
118 }
119 else
120 {
121 CFStringRef keyParamKeyWithAccount = SOSLastKeyParametersPushedKeyCreateWithAccountGestalt(a);
122 changes = CFDictionaryCreateForCFTypes(kCFAllocatorDefault,
123 kSOSKVSKeyParametersKey, newParameters,
124 keyParamKeyWithAccount, timeAndKeyParameters,
125 NULL);
126 CFReleaseNull(keyParamKeyWithAccount);
127
128 }
129 bool success = SOSTransportKeyParameterKVSUpdateKVS(changes, error);
130
131 sync_the_last_data_to_kvs(a, waitForeverForSynchronization);
132
133 CFReleaseNull(changes);
134 CFReleaseNull(timeAndKeyParametersMutable);
135 CFReleaseNull(timeAndKeyParameters);
136 CFReleaseNull(timeData);
137 CFReleaseNull(timeDescription);
138 return success;
139 }