]>
Commit | Line | Data |
---|---|---|
5c19dc3a A |
1 | // |
2 | // SOSAccountCircles.c | |
3 | // sec | |
4 | // | |
5 | ||
6 | #include "SOSAccountPriv.h" | |
6b200bc3 | 7 | #include <Security/SecureObjectSync/SOSPeerInfoCollections.h> |
5c19dc3a A |
8 | #include <Security/SecureObjectSync/SOSTransport.h> |
9 | #include <Security/SecureObjectSync/SOSTransportKeyParameterKVS.h> | |
10 | #include <Security/SecureObjectSync/SOSTransportCircleKVS.h> | |
11 | #include <Security/SecureObjectSync/SOSTransportMessageKVS.h> | |
12 | #include <Security/SecureObjectSync/SOSTransportMessageIDS.h> | |
13 | #include "SOSCloudKeychainClient.h" | |
14 | ||
15 | ||
16 | // | |
17 | // MARK: Circle management | |
18 | // | |
19 | ||
5c19dc3a A |
20 | SecKeyRef SOSAccountCopyPublicKeyForPeer(SOSAccountRef account, CFStringRef peer_id, CFErrorRef *error) { |
21 | SecKeyRef publicKey = NULL; | |
22 | SOSPeerInfoRef peer = NULL; | |
23 | ||
24 | require_action_quiet(account->trusted_circle, fail, SOSErrorCreate(kSOSErrorNoCircle, error, NULL, CFSTR("No circle to get peer key from"))); | |
25 | ||
26 | peer = SOSCircleCopyPeerWithID(account->trusted_circle, peer_id, error); | |
27 | require_quiet(peer, fail); | |
28 | ||
fa7225c8 | 29 | publicKey = SOSPeerInfoCopyPubKey(peer, error); |
5c19dc3a A |
30 | |
31 | fail: | |
32 | CFReleaseSafe(peer); | |
33 | return publicKey; | |
34 | } | |
35 | ||
36 | ||
37 | SOSCircleRef SOSAccountGetCircle(SOSAccountRef a, CFErrorRef *error) | |
38 | { | |
39 | CFTypeRef entry = a->trusted_circle; | |
40 | ||
41 | require_action_quiet(!isNull(entry), fail, | |
42 | SOSCreateError(kSOSErrorIncompatibleCircle, CFSTR("Incompatible circle in KVS"), NULL, error)); | |
43 | ||
44 | require_action_quiet(entry, fail, | |
45 | SOSCreateError(kSOSErrorNoCircle, CFSTR("No circle found"), NULL, error)); | |
46 | ||
47 | ||
48 | return (SOSCircleRef) entry; | |
49 | ||
50 | fail: | |
51 | return NULL; | |
52 | } | |
53 | ||
5c19dc3a A |
54 | static bool SOSAccountInflateTransportsForCircle(SOSAccountRef account, CFStringRef circleName, CFErrorRef *error){ |
55 | bool success = false; | |
56 | ||
57 | SOSTransportKeyParameterRef tKey = NULL; | |
58 | SOSTransportCircleRef tCircle = NULL; | |
59 | SOSTransportMessageRef tidsMessage = NULL; | |
60 | SOSTransportMessageRef tkvsMessage = NULL; | |
61 | ||
5c19dc3a A |
62 | tKey = (SOSTransportKeyParameterRef)SOSTransportKeyParameterKVSCreate(account, error); |
63 | tCircle = (SOSTransportCircleRef)SOSTransportCircleKVSCreate(account, circleName, error); | |
fa7225c8 | 64 | |
5c19dc3a A |
65 | require_quiet(tKey, fail); |
66 | require_quiet(tCircle, fail); | |
e0e0d90e A |
67 | |
68 | tidsMessage = (SOSTransportMessageRef)SOSTransportMessageIDSCreate(account, circleName, error); | |
69 | require_quiet(tidsMessage, fail); | |
70 | ||
71 | CFRetainAssign(account->ids_message_transport, tidsMessage); | |
fa7225c8 | 72 | |
5c19dc3a A |
73 | tkvsMessage = (SOSTransportMessageRef)SOSTransportMessageKVSCreate(account, circleName, error); |
74 | require_quiet(tkvsMessage, fail); | |
e0e0d90e | 75 | |
5c19dc3a | 76 | CFRetainAssign(account->kvs_message_transport, tkvsMessage); |
fa7225c8 | 77 | |
5c19dc3a A |
78 | CFRetainAssign(account->key_transport, (SOSTransportKeyParameterRef)tKey); |
79 | CFRetainAssign(account->circle_transport, tCircle); | |
80 | ||
81 | ||
82 | success = true; | |
83 | fail: | |
84 | CFReleaseNull(tKey); | |
85 | CFReleaseNull(tCircle); | |
86 | CFReleaseNull(tidsMessage); | |
87 | CFReleaseNull(tkvsMessage); | |
88 | return success; | |
89 | } | |
90 | ||
91 | SOSCircleRef SOSAccountEnsureCircle(SOSAccountRef a, CFStringRef name, CFErrorRef *error) | |
92 | { | |
93 | CFErrorRef localError = NULL; | |
94 | ||
95 | if (a->trusted_circle == NULL) { | |
96 | a->trusted_circle = SOSCircleCreate(NULL, name, NULL); | |
fa7225c8 | 97 | a->key_interests_need_updating = true; |
5c19dc3a A |
98 | } |
99 | ||
100 | ||
101 | SOSCircleRef circle = SOSAccountGetCircle(a, &localError); | |
102 | ||
103 | require_action_quiet(circle || !isSOSErrorCoded(localError, kSOSErrorIncompatibleCircle), fail, | |
104 | if (error) { *error = localError; localError = NULL; }); | |
105 | ||
106 | require_quiet(SOSAccountInflateTransportsForCircle(a, name, error), fail); | |
107 | ||
108 | fail: | |
109 | CFReleaseNull(localError); | |
110 | return circle; | |
111 | } | |
112 | ||
113 | ||
114 | bool SOSAccountUpdateCircleFromRemote(SOSAccountRef account, SOSCircleRef newCircle, CFErrorRef *error) | |
115 | { | |
116 | return SOSAccountHandleUpdateCircle(account, newCircle, false, error); | |
117 | } | |
118 | ||
119 | bool SOSAccountUpdateCircle(SOSAccountRef account, SOSCircleRef newCircle, CFErrorRef *error) | |
120 | { | |
121 | return SOSAccountHandleUpdateCircle(account, newCircle, true, error); | |
122 | } | |
123 | ||
124 | bool SOSAccountModifyCircle(SOSAccountRef account, | |
125 | CFErrorRef* error, | |
126 | bool (^action)(SOSCircleRef circle)) | |
127 | { | |
128 | bool success = false; | |
129 | ||
130 | SOSCircleRef circle = NULL; | |
131 | require_action_quiet(account->trusted_circle, fail, SOSErrorCreate(kSOSErrorNoCircle, error, NULL, CFSTR("No circle to get peer key from"))); | |
132 | ||
133 | circle = SOSCircleCopyCircle(kCFAllocatorDefault, account->trusted_circle, error); | |
134 | require_quiet(circle, fail); | |
135 | ||
136 | success = true; | |
137 | require_quiet(action(circle), fail); | |
138 | ||
139 | success = SOSAccountUpdateCircle(account, circle, error); | |
140 | ||
141 | fail: | |
142 | CFReleaseSafe(circle); | |
143 | return success; | |
144 | } | |
145 | ||
6b200bc3 A |
146 | CFSetRef SOSAccountCopyPeerSetMatching(SOSAccountRef account, bool (^action)(SOSPeerInfoRef peer)) { |
147 | CFMutableSetRef result = CFSetCreateMutableForSOSPeerInfosByID(kCFAllocatorDefault); | |
148 | ||
149 | if (account->trusted_circle) { | |
150 | SOSCircleForEachPeer(account->trusted_circle, ^(SOSPeerInfoRef peer) { | |
151 | if (action(peer)) { | |
152 | CFSetAddValue(result, peer); | |
153 | } | |
154 | }); | |
155 | } | |
156 | ||
157 | return result; | |
158 | } |