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