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