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