]> git.saurik.com Git - apple/security.git/blob - OSX/sec/SOSCircle/SecureObjectSync/SOSTransportKeyParameterKVS.c
Security-57740.60.18.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 CFArrayAppendValue(alwaysKeys, kSOSKVSKeyParametersKey);
63
64 return true;
65 }
66
67 static bool publishCloudParameters(SOSTransportKeyParameterRef transport, CFDataRef data, CFErrorRef* error)
68 {
69 return SOSTransportKeyParameterKVSPublishCloudParameters((SOSTransportKeyParameterKVSRef)transport, data, error);
70 }
71
72 static bool SOSTransportKeyParameterKVSUpdateKVS(CFDictionaryRef changes, CFErrorRef *error){
73 CloudKeychainReplyBlock log_error = ^(CFDictionaryRef returnedValues __unused, CFErrorRef block_error) {
74 if (block_error) {
75 secerror("Error putting: %@", block_error);
76 }
77 };
78
79 SOSCloudKeychainPutObjectsInCloud(changes, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), log_error);
80 return true;
81 }
82
83 static bool SOSTransportKeyParameterKVSPublishCloudParameters(SOSTransportKeyParameterKVSRef transport, CFDataRef newParameters, CFErrorRef *error)
84 {
85 SOSAccountRef a = SOSTransportKeyParameterGetAccount((SOSTransportKeyParameterRef)transport);
86 CFDictionaryRef changes = NULL;
87 CFDataRef timeData = NULL;
88 bool waitForeverForSynchronization = true;
89
90 CFMutableStringRef timeDescription = CFStringCreateMutableCopy(kCFAllocatorDefault, 0, CFSTR("["));
91 CFAbsoluteTime currentTimeAndDate = CFAbsoluteTimeGetCurrent();
92
93 withStringOfAbsoluteTime(currentTimeAndDate, ^(CFStringRef decription) {
94 CFStringAppend(timeDescription, decription);
95 });
96 CFStringAppend(timeDescription, CFSTR("]"));
97
98 timeData = CFStringCreateExternalRepresentation(NULL,timeDescription,
99 kCFStringEncodingUTF8, '?');
100
101 CFMutableDataRef timeAndKeyParametersMutable = CFDataCreateMutable(kCFAllocatorDefault, CFDataGetLength(timeData) + CFDataGetLength(newParameters));
102 CFDataAppend(timeAndKeyParametersMutable, timeData);
103 CFDataAppend(timeAndKeyParametersMutable, newParameters);
104 CFDataRef timeAndKeyParameters = CFDataCreateCopy(kCFAllocatorDefault, timeAndKeyParametersMutable);
105
106 CFStringRef ourPeerID = SOSAccountGetMyPeerID(a);
107
108 if(ourPeerID != NULL){
109 CFStringRef keyParamKey = SOSLastKeyParametersPushedKeyCreateWithPeerID(ourPeerID);
110
111 changes = CFDictionaryCreateForCFTypes(kCFAllocatorDefault,
112 kSOSKVSKeyParametersKey, newParameters,
113 keyParamKey, timeAndKeyParameters,
114 NULL);
115 CFReleaseNull(keyParamKey);
116 }
117 else
118 {
119 CFStringRef keyParamKeyWithAccount = SOSLastKeyParametersPushedKeyCreateWithAccountGestalt(a);
120 changes = CFDictionaryCreateForCFTypes(kCFAllocatorDefault,
121 kSOSKVSKeyParametersKey, newParameters,
122 keyParamKeyWithAccount, timeAndKeyParameters,
123 NULL);
124 CFReleaseNull(keyParamKeyWithAccount);
125
126 }
127 bool success = SOSTransportKeyParameterKVSUpdateKVS(changes, error);
128
129 sync_the_last_data_to_kvs(a, waitForeverForSynchronization);
130
131 CFReleaseNull(changes);
132 CFReleaseNull(timeAndKeyParametersMutable);
133 CFReleaseNull(timeAndKeyParameters);
134 CFReleaseNull(timeData);
135 CFReleaseNull(timeDescription);
136 return success;
137 }