]> git.saurik.com Git - apple/security.git/blob - OSX/sec/ProjectHeaders/Security/SecureObjectSync/SOSTransportKeyParameterKVS.c
Security-57336.1.9.tar.gz
[apple/security.git] / OSX / sec / ProjectHeaders / Security / 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
91 CFMutableStringRef timeDescription = CFStringCreateMutableCopy(kCFAllocatorDefault, 0, CFSTR("["));
92 CFAbsoluteTime currentTimeAndDate = CFAbsoluteTimeGetCurrent();
93
94 withStringOfAbsoluteTime(currentTimeAndDate, ^(CFStringRef decription) {
95 CFStringAppend(timeDescription, decription);
96 });
97 CFStringAppend(timeDescription, CFSTR("]"));
98
99 timeData = CFStringCreateExternalRepresentation(NULL,timeDescription,
100 kCFStringEncodingUTF8, '?');
101
102 CFMutableDataRef timeAndKeyParametersMutable = CFDataCreateMutable(kCFAllocatorDefault, CFDataGetLength(timeData) + CFDataGetLength(newParameters));
103 CFDataAppend(timeAndKeyParametersMutable, timeData);
104 CFDataAppend(timeAndKeyParametersMutable, newParameters);
105 CFDataRef timeAndKeyParameters = CFDataCreateCopy(kCFAllocatorDefault, timeAndKeyParametersMutable);
106
107 CFStringRef ourPeerID = SOSAccountGetMyPeerID(a);
108
109 if(ourPeerID != NULL){
110 CFStringRef keyParamKey = SOSLastKeyParametersPushedKeyCreateWithPeerID(ourPeerID);
111
112 changes = CFDictionaryCreateForCFTypes(kCFAllocatorDefault,
113 kSOSKVSKeyParametersKey, newParameters,
114 keyParamKey, timeAndKeyParameters,
115 NULL);
116 CFReleaseNull(keyParamKey);
117 }
118 else
119 {
120 CFStringRef keyParamKeyWithAccount = SOSLastKeyParametersPushedKeyCreateWithAccountGestalt(a);
121 changes = CFDictionaryCreateForCFTypes(kCFAllocatorDefault,
122 kSOSKVSKeyParametersKey, newParameters,
123 keyParamKeyWithAccount, timeAndKeyParameters,
124 NULL);
125 CFReleaseNull(keyParamKeyWithAccount);
126
127 }
128 bool success = SOSTransportKeyParameterKVSUpdateKVS(changes, error);
129
130 sync_the_last_data_to_kvs(a);
131
132 CFReleaseNull(changes);
133 CFReleaseNull(timeAndKeyParametersMutable);
134 CFReleaseNull(timeAndKeyParameters);
135 CFReleaseNull(timeData);
136 CFReleaseNull(timeDescription);
137 return success;
138 }