]> git.saurik.com Git - apple/security.git/blob - Security/sec/SOSCircle/SecureObjectSync/SOSKVSKeys.c
Security-57031.1.35.tar.gz
[apple/security.git] / Security / sec / SOSCircle / SecureObjectSync / SOSKVSKeys.c
1 /*
2 * Copyright (c) 2013-2014 Apple Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24 #include <SecureObjectSync/SOSKVSKeys.h>
25 #include <utilities/SecCFWrappers.h>
26 #include <SecureObjectSync/SOSAccountPriv.h>
27
28
29 void AppendCircleKeyName(CFMutableArrayRef array, CFStringRef name) {
30 CFStringRef circle_key = SOSCircleKeyCreateWithName(name, NULL);
31 CFArrayAppendValue(array, circle_key);
32 CFReleaseNull(circle_key);
33 }
34
35 //
36 //
37 // MARK: KVS Keys
38 // TODO: Handle '|' and "¬" in other strings.
39 //
40 const CFStringRef kSOSKVSKeyParametersKey = CFSTR(">KeyParameters");
41 const CFStringRef kSOSKVSInitialSyncKey = CFSTR("^InitialSync");
42 const CFStringRef kSOSKVSAccountChangedKey = CFSTR("^AccountChanged");
43
44 const CFStringRef sWarningPrefix = CFSTR("!");
45 const CFStringRef sAncientCirclePrefix = CFSTR("@");
46 const CFStringRef sCirclePrefix = CFSTR("o");
47 const CFStringRef sRetirementPrefix = CFSTR("-");
48 const CFStringRef sCircleSeparator = CFSTR("|");
49 const CFStringRef sFromToSeparator = CFSTR(":");
50
51 static CFStringRef copyStringEndingIn(CFMutableStringRef in, CFStringRef token) {
52 if(token == NULL) return CFStringCreateCopy(NULL, in);
53 CFRange tokenAt = CFStringFind(in, token, 0);
54 if(tokenAt.location == kCFNotFound) return NULL;
55 CFStringRef retval = CFStringCreateWithSubstring(NULL, in, CFRangeMake(0, tokenAt.location));
56 CFStringDelete(in, CFRangeMake(0, tokenAt.location+1));
57 return retval;
58 }
59
60 SOSKVSKeyType SOSKVSKeyGetKeyTypeAndParse(CFStringRef key, CFStringRef *circle, CFStringRef *from, CFStringRef *to)
61 {
62 SOSKVSKeyType retval = kUnknownKey;
63
64 if(CFStringHasPrefix(key, sCirclePrefix)) retval = kCircleKey;
65 else if(CFStringHasPrefix(key, sRetirementPrefix)) retval = kRetirementKey;
66 else if(CFStringHasPrefix(key, kSOSKVSKeyParametersKey)) retval = kParametersKey;
67 else if(CFStringHasPrefix(key, kSOSKVSInitialSyncKey)) retval = kInitialSyncKey;
68 else if(CFStringHasPrefix(key, kSOSKVSAccountChangedKey)) retval = kAccountChangedKey;
69 else retval = kMessageKey;
70
71 switch(retval) {
72 case kCircleKey:
73 if (circle) {
74 CFRange fromRange = CFRangeMake(1, CFStringGetLength(key)-1);
75 *circle = CFStringCreateWithSubstring(NULL, key, fromRange);
76 }
77 break;
78 case kMessageKey: {
79 CFStringRef mCircle = NULL;
80 CFStringRef mFrom = NULL;
81 CFStringRef mTo = NULL;
82 CFMutableStringRef keycopy = CFStringCreateMutableCopy(NULL, 128, key);
83
84 if( ((mCircle = copyStringEndingIn(keycopy, sCircleSeparator)) != NULL) &&
85 ((mFrom = copyStringEndingIn(keycopy, sFromToSeparator)) != NULL) &&
86 (CFStringGetLength(mFrom) > 0) ) {
87 mTo = copyStringEndingIn(keycopy, NULL);
88 if (circle && mCircle) *circle = CFStringCreateCopy(NULL, mCircle);
89 if (from && mFrom) *from = CFStringCreateCopy(NULL, mFrom);
90 if (to && mTo) *to = CFStringCreateCopy(NULL, mTo);
91 } else {
92 retval = kUnknownKey;
93 }
94 CFReleaseNull(mCircle);
95 CFReleaseNull(mFrom);
96 CFReleaseNull(mTo);
97 CFReleaseNull(keycopy);
98 }
99 break;
100 case kRetirementKey: {
101 CFStringRef mCircle = NULL;
102 CFStringRef mPeer = NULL;
103 CFMutableStringRef keycopy = CFStringCreateMutableCopy(NULL, 128, key);
104 CFStringDelete(keycopy, CFRangeMake(0, 1));
105 if( ((mCircle = copyStringEndingIn(keycopy, sCircleSeparator)) != NULL) &&
106 ((mPeer = copyStringEndingIn(keycopy, NULL)) != NULL)) {
107 if (circle) *circle = CFStringCreateCopy(NULL, mCircle);
108 if (from) *from = CFStringCreateCopy(NULL, mPeer);
109 } else {
110 retval = kUnknownKey;
111 }
112 // TODO - Update our circle
113 CFReleaseNull(mCircle);
114 CFReleaseNull(mPeer);
115 CFReleaseNull(keycopy);
116 }
117 break;
118 case kAccountChangedKey:
119 case kParametersKey:
120 case kInitialSyncKey:
121 case kUnknownKey:
122 break;
123 }
124
125 return retval;
126 }
127
128
129 SOSKVSKeyType SOSKVSKeyGetKeyType(CFStringRef key)
130 {
131 return SOSKVSKeyGetKeyTypeAndParse(key, NULL, NULL, NULL);
132 }
133
134 CFStringRef SOSCircleKeyCreateWithCircle(SOSCircleRef circle, CFErrorRef *error)
135 {
136 return SOSCircleKeyCreateWithName(SOSCircleGetName(circle), error);
137 }
138
139
140 CFStringRef SOSCircleKeyCreateWithName(CFStringRef circleName, CFErrorRef *error)
141 {
142 if(!circleName) return NULL;
143 return CFStringCreateWithFormat(NULL, NULL, CFSTR("%@%@"), sCirclePrefix, circleName);
144 }
145
146 CFStringRef SOSCircleKeyCopyCircleName(CFStringRef key, CFErrorRef *error)
147 {
148 CFStringRef circleName = NULL;
149
150 if (kCircleKey != SOSKVSKeyGetKeyTypeAndParse(key, &circleName, NULL, NULL)) {
151 SOSCreateErrorWithFormat(kSOSErrorNoCircleName, NULL, error, NULL, CFSTR("Couldn't find circle name in key '%@'"), key);
152
153 CFReleaseNull(circleName);
154 }
155
156 return circleName;
157 }
158
159 CFStringRef SOSMessageKeyCopyCircleName(CFStringRef key, CFErrorRef *error)
160 {
161 CFStringRef circleName = NULL;
162
163 if (SOSKVSKeyGetKeyTypeAndParse(key, &circleName, NULL, NULL) != kMessageKey) {
164 SOSCreateErrorWithFormat(kSOSErrorNoCircleName, NULL, error, NULL, CFSTR("Couldn't find circle name in key '%@'"), key);
165
166 CFReleaseNull(circleName);
167 }
168 return circleName;
169 }
170
171 CFStringRef SOSMessageKeyCopyFromPeerName(CFStringRef messageKey, CFErrorRef *error)
172 {
173 CFStringRef fromPeer = NULL;
174
175 if (SOSKVSKeyGetKeyTypeAndParse(messageKey, NULL, &fromPeer, NULL) != kMessageKey) {
176 SOSCreateErrorWithFormat(kSOSErrorNoCircleName, NULL, error, NULL, CFSTR("Couldn't find from peer in key '%@'"), messageKey);
177
178 CFReleaseNull(fromPeer);
179 }
180 return fromPeer;
181 }
182
183 CFStringRef SOSMessageKeyCreateWithCircleNameAndPeerNames(CFStringRef circleName, CFStringRef from_peer_name, CFStringRef to_peer_name)
184 {
185 return CFStringCreateWithFormat(NULL, NULL, CFSTR("%@%@%@%@%@"),
186 circleName, sCircleSeparator, from_peer_name, sFromToSeparator, to_peer_name);
187 }
188
189 CFStringRef SOSMessageKeyCreateWithCircleAndPeerNames(SOSCircleRef circle, CFStringRef from_peer_name, CFStringRef to_peer_name)
190 {
191 return SOSMessageKeyCreateWithCircleNameAndPeerNames(SOSCircleGetName(circle), from_peer_name, to_peer_name);
192 }
193
194 CFStringRef SOSMessageKeyCreateWithCircleAndPeerInfos(SOSCircleRef circle, SOSPeerInfoRef from_peer, SOSPeerInfoRef to_peer)
195 {
196 return SOSMessageKeyCreateWithCircleAndPeerNames(circle, SOSPeerInfoGetPeerID(from_peer), SOSPeerInfoGetPeerID(to_peer));
197 }
198
199 CFStringRef SOSMessageKeyCreateFromPeerToTransport(SOSTransportMessageKVSRef transport, CFStringRef peer_name) {
200 CFErrorRef error = NULL;
201 SOSEngineRef engine = SOSTransportMessageGetEngine((SOSTransportMessageRef)transport);
202
203 CFStringRef circleName = SOSTransportMessageKVSGetCircleName(transport);
204 CFStringRef my_id = SOSEngineGetMyID(engine);
205
206 CFStringRef result = SOSMessageKeyCreateWithCircleNameAndPeerNames(circleName, peer_name, my_id);
207 CFReleaseSafe(error);
208 return result;
209 }
210
211 CFStringRef SOSMessageKeyCreateFromTransportToPeer(SOSTransportMessageKVSRef transport, CFStringRef peer_name) {
212 CFErrorRef error = NULL;
213 SOSEngineRef engine = SOSTransportMessageGetEngine((SOSTransportMessageRef)transport);
214
215 CFStringRef circleName = SOSTransportMessageKVSGetCircleName(transport);
216 CFStringRef my_id = SOSEngineGetMyID(engine);
217
218 CFStringRef result = SOSMessageKeyCreateWithCircleNameAndPeerNames(circleName, my_id, peer_name);
219 CFReleaseSafe(error);
220 return result;
221 }
222
223 CFStringRef SOSRetirementKeyCreateWithCircleNameAndPeer(CFStringRef circle_name, CFStringRef retirement_peer_name)
224 {
225 return CFStringCreateWithFormat(NULL, NULL, CFSTR("%@%@%@%@"),
226 sRetirementPrefix, circle_name, sCircleSeparator, retirement_peer_name);
227 }
228
229 CFStringRef SOSRetirementKeyCreateWithCircleAndPeer(SOSCircleRef circle, CFStringRef retirement_peer_name)
230 {
231 return SOSRetirementKeyCreateWithCircleNameAndPeer(SOSCircleGetName(circle), retirement_peer_name);
232 }
233