]> git.saurik.com Git - apple/security.git/blob - OSX/sec/SOSCircle/SecureObjectSync/SOSAccountCircles.c
Security-57336.1.9.tar.gz
[apple/security.git] / OSX / sec / SOSCircle / SecureObjectSync / SOSAccountCircles.c
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
19 CFIndex whichTransportType;
20
21
22 SecKeyRef SOSAccountCopyPublicKeyForPeer(SOSAccountRef account, CFStringRef peer_id, CFErrorRef *error) {
23 SecKeyRef publicKey = NULL;
24 SOSPeerInfoRef peer = NULL;
25
26 require_action_quiet(account->trusted_circle, fail, SOSErrorCreate(kSOSErrorNoCircle, error, NULL, CFSTR("No circle to get peer key from")));
27
28 peer = SOSCircleCopyPeerWithID(account->trusted_circle, peer_id, error);
29 require_quiet(peer, fail);
30
31 publicKey = SOSPeerInfoCopyPubKey(peer);
32
33 fail:
34 CFReleaseSafe(peer);
35 return publicKey;
36 }
37
38
39 SOSCircleRef SOSAccountGetCircle(SOSAccountRef a, CFErrorRef *error)
40 {
41 CFTypeRef entry = a->trusted_circle;
42
43 require_action_quiet(!isNull(entry), fail,
44 SOSCreateError(kSOSErrorIncompatibleCircle, CFSTR("Incompatible circle in KVS"), NULL, error));
45
46 require_action_quiet(entry, fail,
47 SOSCreateError(kSOSErrorNoCircle, CFSTR("No circle found"), NULL, error));
48
49
50 return (SOSCircleRef) entry;
51
52 fail:
53 return NULL;
54 }
55
56 static void setup_defaults_settings(){
57
58 Boolean keyExistsAndHasValue = false;
59
60 whichTransportType = CFPreferencesGetAppIntegerValue(CFSTR("Transport"), CFSTR("com.apple.security"), &keyExistsAndHasValue);
61 if(whichTransportType == kSOSTransportFuture)
62 secdebug("IDS", "Successfully retrieved value: %d, We are a Galarch + 1 device: %ld", keyExistsAndHasValue, whichTransportType);
63 else if (whichTransportType == kSOSTransportPresent)
64 secdebug("IDS", "Successfully retrieved value: %d, We are a Galarch device: %ld", keyExistsAndHasValue, whichTransportType);
65
66 else if (whichTransportType == kSOSTransportIDS)
67 secdebug("IDS", "Successfully retrieved value: %d, We are an IDS device: %ld", keyExistsAndHasValue, whichTransportType);
68
69 else if (whichTransportType == kSOSTransportKVS)
70 secdebug("IDS", "Successfully retrieved value: %d, We are a KVS device: %ld", keyExistsAndHasValue, whichTransportType);
71 else
72 secdebug("IDS", "Successfully retrieved value: %d, We are a KVS device: %ld", keyExistsAndHasValue, whichTransportType);
73
74 }
75
76 static void SOSTransportInit(void) {
77 static dispatch_once_t sdOnceToken;
78 dispatch_once(&sdOnceToken, ^{
79 setup_defaults_settings();
80 });
81 }
82
83 static bool SOSAccountInflateTransportsForCircle(SOSAccountRef account, CFStringRef circleName, CFErrorRef *error){
84 bool success = false;
85
86 SOSTransportKeyParameterRef tKey = NULL;
87 SOSTransportCircleRef tCircle = NULL;
88 SOSTransportMessageRef tidsMessage = NULL;
89 SOSTransportMessageRef tkvsMessage = NULL;
90
91 SOSTransportInit();
92
93 tKey = (SOSTransportKeyParameterRef)SOSTransportKeyParameterKVSCreate(account, error);
94 tCircle = (SOSTransportCircleRef)SOSTransportCircleKVSCreate(account, circleName, error);
95
96 require_quiet(tKey, fail);
97 require_quiet(tCircle, fail);
98
99
100 if (whichTransportType == kSOSTransportIDS || whichTransportType == kSOSTransportFuture || whichTransportType == kSOSTransportPresent) {
101 tidsMessage = (SOSTransportMessageRef)SOSTransportMessageIDSCreate(account, circleName, error);
102 require_quiet(tidsMessage, fail);
103
104 CFRetainAssign(account->ids_message_transport, tidsMessage);
105
106 secnotice("transport", "We are going to use an IDS transport");
107 }
108
109 tkvsMessage = (SOSTransportMessageRef)SOSTransportMessageKVSCreate(account, circleName, error);
110 require_quiet(tkvsMessage, fail);
111
112 CFRetainAssign(account->kvs_message_transport, tkvsMessage);
113
114 CFRetainAssign(account->key_transport, (SOSTransportKeyParameterRef)tKey);
115 CFRetainAssign(account->circle_transport, tCircle);
116
117
118 success = true;
119 fail:
120 CFReleaseNull(tKey);
121 CFReleaseNull(tCircle);
122 CFReleaseNull(tidsMessage);
123 CFReleaseNull(tkvsMessage);
124 return success;
125 }
126
127 SOSCircleRef SOSAccountEnsureCircle(SOSAccountRef a, CFStringRef name, CFErrorRef *error)
128 {
129 CFErrorRef localError = NULL;
130
131 if (a->trusted_circle == NULL) {
132 a->trusted_circle = SOSCircleCreate(NULL, name, NULL);
133 SOSUpdateKeyInterest();
134 }
135
136
137 SOSCircleRef circle = SOSAccountGetCircle(a, &localError);
138
139 require_action_quiet(circle || !isSOSErrorCoded(localError, kSOSErrorIncompatibleCircle), fail,
140 if (error) { *error = localError; localError = NULL; });
141
142 require_quiet(SOSAccountInflateTransportsForCircle(a, name, error), fail);
143
144 fail:
145 CFReleaseNull(localError);
146 return circle;
147 }
148
149
150 bool SOSAccountUpdateCircleFromRemote(SOSAccountRef account, SOSCircleRef newCircle, CFErrorRef *error)
151 {
152 return SOSAccountHandleUpdateCircle(account, newCircle, false, error);
153 }
154
155 bool SOSAccountUpdateCircle(SOSAccountRef account, SOSCircleRef newCircle, CFErrorRef *error)
156 {
157 return SOSAccountHandleUpdateCircle(account, newCircle, true, error);
158 }
159
160 bool SOSAccountModifyCircle(SOSAccountRef account,
161 CFErrorRef* error,
162 bool (^action)(SOSCircleRef circle))
163 {
164 bool success = false;
165
166 SOSCircleRef circle = NULL;
167 require_action_quiet(account->trusted_circle, fail, SOSErrorCreate(kSOSErrorNoCircle, error, NULL, CFSTR("No circle to get peer key from")));
168
169 circle = SOSCircleCopyCircle(kCFAllocatorDefault, account->trusted_circle, error);
170 require_quiet(circle, fail);
171
172 success = true;
173 require_quiet(action(circle), fail);
174
175 success = SOSAccountUpdateCircle(account, circle, error);
176
177 fail:
178 CFReleaseSafe(circle);
179 return success;
180 }
181