]> git.saurik.com Git - apple/security.git/blame - OSX/sec/SOSCircle/SecureObjectSync/SOSAccountCircles.c
Security-57740.60.18.tar.gz
[apple/security.git] / OSX / sec / SOSCircle / SecureObjectSync / SOSAccountCircles.c
CommitLineData
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
20SecKeyRef 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
31fail:
32 CFReleaseSafe(peer);
33 return publicKey;
34}
35
36
37SOSCircleRef 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
50fail:
51 return NULL;
52}
53
5c19dc3a
A
54static 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;
83fail:
84 CFReleaseNull(tKey);
85 CFReleaseNull(tCircle);
86 CFReleaseNull(tidsMessage);
87 CFReleaseNull(tkvsMessage);
88 return success;
89}
90
91SOSCircleRef 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
108fail:
109 CFReleaseNull(localError);
110 return circle;
111}
112
113
114bool SOSAccountUpdateCircleFromRemote(SOSAccountRef account, SOSCircleRef newCircle, CFErrorRef *error)
115{
116 return SOSAccountHandleUpdateCircle(account, newCircle, false, error);
117}
118
119bool SOSAccountUpdateCircle(SOSAccountRef account, SOSCircleRef newCircle, CFErrorRef *error)
120{
121 return SOSAccountHandleUpdateCircle(account, newCircle, true, error);
122}
123
124bool 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
141fail:
142 CFReleaseSafe(circle);
143 return success;
144}
145
6b200bc3
A
146CFSetRef 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}