]> git.saurik.com Git - apple/security.git/blob - OSX/sec/SOSCircle/SecureObjectSync/SOSAccountPeers.c
Security-57740.60.18.tar.gz
[apple/security.git] / OSX / sec / SOSCircle / SecureObjectSync / SOSAccountPeers.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
25 #include <stdio.h>
26 #include "SOSAccountPriv.h"
27 #include <Security/SecureObjectSync/SOSPeerInfoCollections.h>
28 #include <Security/SecureObjectSync/SOSTransportMessage.h>
29 #include <Security/SecureObjectSync/SOSPeerInfoV2.h>
30
31
32 bool SOSAccountIsMyPeerActive(SOSAccountRef account, CFErrorRef* error) {
33 SOSPeerInfoRef me = SOSFullPeerInfoGetPeerInfo(account->my_identity);
34 return me ? SOSCircleHasActivePeer(account->trusted_circle, me, error) : false;
35 }
36
37 //
38 // MARK: Peer Querying
39 //
40
41
42 static void sosArrayAppendPeerCopy(CFMutableArrayRef appendPeersTo, SOSPeerInfoRef peer) {
43 SOSPeerInfoRef peerInfo = SOSPeerInfoCreateCopy(kCFAllocatorDefault, peer, NULL);
44 CFArrayAppendValue(appendPeersTo, peerInfo);
45 CFRelease(peerInfo);
46 }
47
48 static CFArrayRef SOSAccountCopySortedPeerArray(SOSAccountRef account,
49 CFErrorRef *error,
50 void (^action)(SOSCircleRef circle, CFMutableArrayRef appendPeersTo)) {
51 if (!SOSAccountHasPublicKey(account, error))
52 return NULL;
53
54 CFMutableArrayRef peers = CFArrayCreateMutableForCFTypes(kCFAllocatorDefault);
55
56 action(account->trusted_circle, peers);
57
58 CFArrayOfSOSPeerInfosSortByID(peers);
59
60 return peers;
61 }
62
63
64 CFArrayRef SOSAccountCopyNotValidPeers(SOSAccountRef account, CFErrorRef *error) {
65 return SOSAccountCopySortedPeerArray(account, error, ^(SOSCircleRef circle, CFMutableArrayRef appendPeersTo) {
66 SOSCircleForEachPeer(circle, ^(SOSPeerInfoRef peer) {
67 if(!SOSPeerInfoApplicationVerify(peer, account->user_public, NULL)) {
68 sosArrayAppendPeerCopy(appendPeersTo, peer);
69 }
70 });
71 });
72 }
73
74
75 CFArrayRef SOSAccountCopyValidPeers(SOSAccountRef account, CFErrorRef *error) {
76 return SOSAccountCopySortedPeerArray(account, error, ^(SOSCircleRef circle, CFMutableArrayRef appendPeersTo) {
77 SOSCircleForEachPeer(circle, ^(SOSPeerInfoRef peer) {
78 if(SOSPeerInfoApplicationVerify(peer, account->user_public, NULL)) {
79 sosArrayAppendPeerCopy(appendPeersTo, peer);
80 }
81 });
82 });
83 }
84
85 void SOSAccountForEachCirclePeerExceptMe(SOSAccountRef account, void (^action)(SOSPeerInfoRef peer)) {
86 SOSPeerInfoRef myPi = SOSAccountGetMyPeerInfo(account);
87 if (account->trusted_circle && myPi) {
88 CFStringRef myPi_id = SOSPeerInfoGetPeerID(myPi);
89 SOSCircleForEachPeer(account->trusted_circle, ^(SOSPeerInfoRef peer) {
90 CFStringRef peerID = SOSPeerInfoGetPeerID(peer);
91 if (peerID && !CFEqual(peerID, myPi_id)) {
92 action(peer);
93 }
94 });
95 }
96 }
97
98 CFArrayRef SOSAccountCopyPeersToListenTo(SOSAccountRef account, CFErrorRef *error) {
99 SOSPeerInfoRef myPeerInfo = SOSFullPeerInfoGetPeerInfo(account->my_identity);
100 CFStringRef myID = myPeerInfo ? SOSPeerInfoGetPeerID(myPeerInfo) : NULL;
101 return SOSAccountCopySortedPeerArray(account, error, ^(SOSCircleRef circle, CFMutableArrayRef appendPeersTo) {
102 SOSCircleForEachPeer(circle, ^(SOSPeerInfoRef peer) {
103 if(!CFEqualSafe(myID, SOSPeerInfoGetPeerID(peer)) &&
104 SOSPeerInfoApplicationVerify(peer, account->user_public, NULL) &&
105 !SOSPeerInfoIsRetirementTicket(peer)) {
106 CFArrayAppendValue(appendPeersTo, peer);
107 }
108 });
109 });
110 }
111
112 CFArrayRef SOSAccountCopyRetired(SOSAccountRef account, CFErrorRef *error) {
113 return SOSAccountCopySortedPeerArray(account, error, ^(SOSCircleRef circle, CFMutableArrayRef appendPeersTo) {
114 SOSCircleForEachRetiredPeer(circle, ^(SOSPeerInfoRef peer) {
115 sosArrayAppendPeerCopy(appendPeersTo, peer);
116 });
117 });
118 }
119
120 CFArrayRef SOSAccountCopyViewUnaware(SOSAccountRef account, CFErrorRef *error) {
121 return SOSAccountCopySortedPeerArray(account, error, ^(SOSCircleRef circle, CFMutableArrayRef appendPeersTo) {
122 SOSCircleForEachPeer(circle, ^(SOSPeerInfoRef peer) {
123 if (!SOSPeerInfoVersionHasV2Data(peer) ) {
124 sosArrayAppendPeerCopy(appendPeersTo, peer);
125 } else {
126 CFSetRef peerEnabledViews = SOSPeerInfoCopyEnabledViews(peer);
127 CFSetRef enabledV0Views = CFSetCreateIntersection(kCFAllocatorDefault, peerEnabledViews, SOSViewsGetV0ViewSet());
128 if(CFSetGetCount(enabledV0Views) != 0) {
129 sosArrayAppendPeerCopy(appendPeersTo, peer);
130 }
131 CFReleaseNull(peerEnabledViews);
132 CFReleaseNull(enabledV0Views);
133 }
134 });
135 });
136 }
137
138 CFArrayRef SOSAccountCopyApplicants(SOSAccountRef account, CFErrorRef *error) {
139 return SOSAccountCopySortedPeerArray(account, error, ^(SOSCircleRef circle, CFMutableArrayRef appendPeersTo) {
140 SOSCircleForEachApplicant(circle, ^(SOSPeerInfoRef peer) {
141 sosArrayAppendPeerCopy(appendPeersTo, peer);
142 });
143 });
144 }
145
146 CFArrayRef SOSAccountCopyPeers(SOSAccountRef account, CFErrorRef *error) {
147 return SOSAccountCopySortedPeerArray(account, error, ^(SOSCircleRef circle, CFMutableArrayRef appendPeersTo) {
148 SOSCircleForEachPeer(circle, ^(SOSPeerInfoRef peer) {
149 sosArrayAppendPeerCopy(appendPeersTo, peer);
150 });
151 });
152 }
153
154 CFDataRef SOSAccountCopyAccountStateFromKeychain(CFErrorRef *error){
155 CFMutableDictionaryRef query = CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault);
156 CFTypeRef result = NULL;
157 CFDictionaryAddValue(query, kSecClass, kSecClassGenericPassword);
158 CFDictionaryAddValue(query, kSecAttrAccessGroup, CFSTR("com.apple.security.sos"));
159 CFDictionaryAddValue(query, kSecAttrAccessible, CFSTR("dku"));
160 CFDictionaryAddValue(query, kSecAttrTombstone, kCFBooleanFalse);
161 CFDictionaryAddValue(query, kSecAttrSynchronizable, kCFBooleanFalse);
162 CFDictionaryAddValue(query, kSecReturnData, kCFBooleanTrue);
163
164 SecItemCopyMatching(query, &result);
165
166 if(!isData(result)){
167 SOSErrorCreate(kSOSErrorUnexpectedType, error, NULL, CFSTR("Expected CFData, got: %@"), result);
168 CFReleaseNull(result);
169 return NULL;
170 }
171 return result;
172 }
173
174 bool SOSAccountDeleteAccountStateFromKeychain(CFErrorRef *error){
175 CFMutableDictionaryRef query = CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault);
176 bool result = false;
177 CFDictionaryAddValue(query, kSecClass, kSecClassGenericPassword);
178 CFDictionaryAddValue(query, kSecAttrAccessGroup, CFSTR("com.apple.security.sos"));
179 CFDictionaryAddValue(query, kSecAttrAccessible, CFSTR("dku"));
180 CFDictionaryAddValue(query, kSecAttrTombstone, kCFBooleanFalse);
181 CFDictionaryAddValue(query, kSecAttrSynchronizable, kCFBooleanFalse);
182
183 result = SecItemDelete(query);
184 return result;
185 }
186
187 CFDataRef SOSAccountCopyEngineStateFromKeychain(CFErrorRef *error){
188 CFMutableDictionaryRef query = CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault);
189 CFTypeRef result = NULL;
190 CFDictionaryAddValue(query, kSecClass, kSecClassGenericPassword);
191 CFDictionaryAddValue(query, kSecAttrAccount, CFSTR("engine-state"));
192 CFDictionaryAddValue(query, kSecAttrAccessGroup, CFSTR("com.apple.security.sos"));
193 CFDictionaryAddValue(query, kSecAttrAccessible, CFSTR("dk"));
194 CFDictionaryAddValue(query, kSecAttrService, CFSTR("SOSDataSource-ak"));
195 CFDictionaryAddValue(query, kSecAttrTombstone, kCFBooleanFalse);
196 CFDictionaryAddValue(query, kSecAttrSynchronizable, kCFBooleanFalse);
197 CFDictionaryAddValue(query, kSecReturnData, kCFBooleanTrue);
198
199 SecItemCopyMatching(query, &result);
200
201 if(!isData(result)){
202 SOSErrorCreate(kSOSErrorUnexpectedType, error, NULL, CFSTR("Expected CFData, got: %@"), result);
203 CFReleaseNull(result);
204 return NULL;
205 }
206 return result;
207 }
208
209 bool SOSAccountDeleteEngineStateFromKeychain(CFErrorRef *error){
210 CFMutableDictionaryRef query = CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault);
211 bool result = false;
212 CFDictionaryAddValue(query, kSecClass, kSecClassGenericPassword);
213 CFDictionaryAddValue(query, kSecAttrAccount, CFSTR("engine-state"));
214 CFDictionaryAddValue(query, kSecAttrAccessGroup, CFSTR("com.apple.security.sos"));
215 CFDictionaryAddValue(query, kSecAttrAccessible, CFSTR("dk"));
216 CFDictionaryAddValue(query, kSecAttrService, CFSTR("SOSDataSource-ak"));
217 CFDictionaryAddValue(query, kSecAttrTombstone, kCFBooleanFalse);
218 CFDictionaryAddValue(query, kSecAttrSynchronizable, kCFBooleanFalse);
219
220 result = SecItemDelete(query);
221 return result;
222 }
223
224
225 CFArrayRef SOSAccountCopyActivePeers(SOSAccountRef account, CFErrorRef *error) {
226 return SOSAccountCopySortedPeerArray(account, error, ^(SOSCircleRef circle, CFMutableArrayRef appendPeersTo) {
227 SOSCircleForEachActivePeer(circle, ^(SOSPeerInfoRef peer) {
228 sosArrayAppendPeerCopy(appendPeersTo, peer);
229 });
230 });
231 }
232
233 CFArrayRef SOSAccountCopyActiveValidPeers(SOSAccountRef account, CFErrorRef *error) {
234 return SOSAccountCopySortedPeerArray(account, error, ^(SOSCircleRef circle, CFMutableArrayRef appendPeersTo) {
235 SOSCircleForEachActiveValidPeer(circle, account->user_public, ^(SOSPeerInfoRef peer) {
236 sosArrayAppendPeerCopy(appendPeersTo, peer);
237 });
238 });
239 }
240
241 CFArrayRef SOSAccountCopyConcurringPeers(SOSAccountRef account, CFErrorRef *error)
242 {
243 return SOSAccountCopySortedPeerArray(account, error, ^(SOSCircleRef circle, CFMutableArrayRef appendPeersTo) {
244 SOSCircleAppendConcurringPeers(circle, appendPeersTo, NULL);
245 });
246 }
247
248 SOSPeerInfoRef SOSAccountCopyPeerWithID(SOSAccountRef account, CFStringRef peerid, CFErrorRef *error) {
249 if(!account->trusted_circle) return NULL;
250 return SOSCircleCopyPeerWithID(account->trusted_circle, peerid, error);
251 }
252
253 CFBooleanRef SOSAccountPeersHaveViewsEnabled(SOSAccountRef account, CFArrayRef viewNames, CFErrorRef *error) {
254 CFBooleanRef result = NULL;
255 CFMutableSetRef viewsRemaining = NULL;
256 CFSetRef viewsToLookFor = NULL;
257
258 require_quiet(SOSAccountHasPublicKey(account, error), done);
259 require_quiet(SOSAccountIsInCircle(account, error), done);
260
261 viewsToLookFor = CFSetCreateCopyOfArrayForCFTypes(viewNames);
262 viewsRemaining = CFSetCreateMutableCopy(kCFAllocatorDefault, 0, viewsToLookFor);
263 CFReleaseNull(viewsToLookFor);
264
265 SOSAccountForEachCirclePeerExceptMe(account, ^(SOSPeerInfoRef peer) {
266 if (SOSPeerInfoApplicationVerify(peer, account->user_public, NULL)) {
267 CFSetRef peerViews = SOSPeerInfoCopyEnabledViews(peer);
268 CFSetSubtract(viewsRemaining, peerViews);
269 CFReleaseNull(peerViews);
270 }
271 });
272
273 result = CFSetIsEmpty(viewsRemaining) ? kCFBooleanTrue : kCFBooleanFalse;
274
275 done:
276 CFReleaseNull(viewsToLookFor);
277 CFReleaseNull(viewsRemaining);
278
279 return result;
280 }
281