1//
2//  SOSAccountPriv.h
3//  sec
4//
5
6#ifndef sec_SOSAccountPriv_h
7#define sec_SOSAccountPriv_h
8
9#include "SOSAccount.h"
10
11#include <CoreFoundation/CoreFoundation.h>
12#include <CoreFoundation/CFRuntime.h>
13#include <utilities/SecCFWrappers.h>
14#include <utilities/SecCFError.h>
15#include <utilities/SecAKSWrappers.h>
16
17
18#include <Security/SecKeyPriv.h>
19
20#include <utilities/der_plist.h>
21#include <utilities/der_plist_internal.h>
22#include <corecrypto/ccder.h>
23
24#include <AssertMacros.h>
25#include <assert.h>
26
27#import <notify.h>
28
29#include <SecureObjectSync/SOSInternal.h>
30#include <SecureObjectSync/SOSCircle.h>
31#include <SecureObjectSync/SOSCloudCircle.h>
32#include <securityd/SOSCloudCircleServer.h>
33#include <SecureObjectSync/SOSEngine.h>
34#include <SecureObjectSync/SOSPeer.h>
35#include <SecureObjectSync/SOSFullPeerInfo.h>
36#include <SecureObjectSync/SOSPeerInfo.h>
37#include <SecureObjectSync/SOSPeerInfoInternal.h>
38#include <SecureObjectSync/SOSUserKeygen.h>
39#include <utilities/iCloudKeychainTrace.h>
40
41#include <Security/SecItemPriv.h>
42
43struct __OpaqueSOSAccount {
44    CFRuntimeBase           _base;
45
46    dispatch_queue_t        queue;
47
48    CFDictionaryRef         gestalt;
49
50    CFMutableDictionaryRef  circle_identities;
51    CFMutableDictionaryRef  circles;
52    CFMutableDictionaryRef  retired_peers;
53
54    bool      user_public_trusted;
55    CFDataRef user_key_parameters;
56    SecKeyRef user_public;
57    SecKeyRef previous_public;
58    enum DepartureReason    departure_code;
59
60    // Non-persistent data
61
62    SOSDataSourceFactoryRef factory;
63    SecKeyRef _user_private;
64    dispatch_source_t user_private_timer;
65    int               lock_notification_token;
66
67    SOSTransportKeyParameterRef key_transport;
68    CFMutableDictionaryRef circle_transports;
69    CFMutableDictionaryRef message_transports;
70
71    // Live Notification
72    CFMutableArrayRef       change_blocks;
73};
74
75SOSAccountRef SOSAccountCreateBasic(CFAllocatorRef allocator,
76                                    CFDictionaryRef gestalt,
77                                    SOSDataSourceFactoryRef factory);
78
79bool SOSAccountEnsureFactoryCircles(SOSAccountRef a);
80
81void SOSAccountSetToNew(SOSAccountRef a);
82
83void SOSAccountForEachKnownCircle(SOSAccountRef account,
84                                  void (^handle_incompatible)(CFStringRef name),
85                                  void (^handle_no_peer)(SOSCircleRef circle),
86                                  void (^handle_peer)(SOSCircleRef circle, SOSFullPeerInfoRef full_peer));
87
88bool SOSAccountIsMyPeerActiveInCircle(SOSAccountRef account, SOSCircleRef circle, CFErrorRef* error);
89bool SOSAccountIsMyPeerActiveInCircleNamed(SOSAccountRef account, CFStringRef circle_name, CFErrorRef* error);
90
91// DER Stuff
92
93
94size_t der_sizeof_data_or_null(CFDataRef data, CFErrorRef* error);
95
96uint8_t* der_encode_data_or_null(CFDataRef data, CFErrorRef* error, const uint8_t* der, uint8_t* der_end);
97
98const uint8_t* der_decode_data_or_null(CFAllocatorRef allocator, CFDataRef* data,
99                                       CFErrorRef* error,
100                                       const uint8_t* der, const uint8_t* der_end);
101
102size_t der_sizeof_public_bytes(SecKeyRef publicKey, CFErrorRef* error);
103
104uint8_t* der_encode_public_bytes(SecKeyRef publicKey, CFErrorRef* error, const uint8_t* der, uint8_t* der_end);
105
106const uint8_t* der_decode_public_bytes(CFAllocatorRef allocator, CFIndex algorithmID, SecKeyRef* publicKey, CFErrorRef* error, const uint8_t* der, const uint8_t* der_end);
107
108const uint8_t* ccder_decode_bool(bool* boolean, const uint8_t* der, const uint8_t *der_end);
109
110size_t ccder_sizeof_bool(bool value __unused, CFErrorRef *error);
111
112uint8_t* ccder_encode_bool(bool value, const uint8_t *der, uint8_t *der_end);
113
114// Persistence
115
116
117SOSAccountRef SOSAccountCreateFromDER_V1(CFAllocatorRef allocator,
118                                         SOSDataSourceFactoryRef factory,
119                                         CFErrorRef* error,
120                                         const uint8_t** der_p, const uint8_t *der_end);
121
122SOSAccountRef SOSAccountCreateFromDER_V2(CFAllocatorRef allocator,
123                                         SOSDataSourceFactoryRef factory,
124                                         CFErrorRef* error,
125                                         const uint8_t** der_p, const uint8_t *der_end);
126
127SOSAccountRef SOSAccountCreateFromDER_V3(CFAllocatorRef allocator,
128                                         SOSDataSourceFactoryRef factory,
129                                         CFErrorRef* error,
130                                         const uint8_t** der_p, const uint8_t *der_end);
131
132SOSAccountRef SOSAccountCreateFromDER(CFAllocatorRef allocator,
133                                      SOSDataSourceFactoryRef factory,
134                                      CFErrorRef* error,
135                                      const uint8_t** der_p, const uint8_t *der_end);
136
137SOSAccountRef SOSAccountCreateFromData(CFAllocatorRef allocator, CFDataRef circleData,
138                                       SOSDataSourceFactoryRef factory,
139                                       CFErrorRef* error);
140
141size_t SOSAccountGetDEREncodedSize(SOSAccountRef account, CFErrorRef *error);
142
143uint8_t* SOSAccountEncodeToDER(SOSAccountRef account, CFErrorRef* error, const uint8_t* der, uint8_t* der_end);
144
145size_t SOSAccountGetDEREncodedSize_V3(SOSAccountRef account, CFErrorRef *error);
146
147uint8_t* SOSAccountEncodeToDER_V3(SOSAccountRef account, CFErrorRef* error, const uint8_t* der, uint8_t* der_end);
148
149size_t SOSAccountGetDEREncodedSize_V2(SOSAccountRef account, CFErrorRef *error);
150
151uint8_t* SOSAccountEncodeToDER_V2(SOSAccountRef account, CFErrorRef* error, const uint8_t* der, uint8_t* der_end);
152
153size_t SOSAccountGetDEREncodedSize_V1(SOSAccountRef account, CFErrorRef *error);
154
155uint8_t* SOSAccountEncodeToDER_V1(SOSAccountRef account, CFErrorRef* error, const uint8_t* der, uint8_t* der_end);
156
157CFDataRef SOSAccountCopyEncodedData(SOSAccountRef account, CFAllocatorRef allocator, CFErrorRef *error);
158
159// Update
160
161bool SOSAccountHandleCircleMessage(SOSAccountRef account,
162                                   CFStringRef circleName, CFDataRef encodedCircleMessage, CFErrorRef *error);
163
164void SOSAccountRecordRetiredPeerInCircleNamed(SOSAccountRef account, CFStringRef circleName, SOSPeerInfoRef retiree);
165
166
167bool SOSAccountHandleUpdateCircle(SOSAccountRef account,
168                                  SOSCircleRef prospective_circle,
169                                  bool writeUpdate,
170                                  CFErrorRef *error);
171
172// Circles
173
174void SOSAccountForEachKnownCircle(SOSAccountRef account,
175                                  void (^handle_incompatible)(CFStringRef name),
176                                  void (^handle_no_peer)(SOSCircleRef circle),
177                                  void (^handle_peer)(SOSCircleRef circle, SOSFullPeerInfoRef full_peer));
178
179int SOSAccountCountCircles(SOSAccountRef a);
180
181SOSFullPeerInfoRef SOSAccountGetMyFullPeerInCircleNamed(SOSAccountRef account, CFStringRef name, CFErrorRef *error);
182
183bool SOSAccountDestroyCirclePeerInfoNamed(SOSAccountRef account, CFStringRef name, CFErrorRef* error);
184
185bool SOSAccountDestroyCirclePeerInfo(SOSAccountRef account, SOSCircleRef circle, CFErrorRef* error);
186
187SOSFullPeerInfoRef SOSAccountGetMyFullPeerInCircle(SOSAccountRef account, SOSCircleRef circle, CFErrorRef* error);
188
189SOSPeerInfoRef SOSAccountGetMyPeerInCircle(SOSAccountRef account, SOSCircleRef circle, CFErrorRef* error);
190
191SOSPeerInfoRef SOSAccountGetMyPeerInCircleNamed(SOSAccountRef account, CFStringRef name, CFErrorRef *error);
192
193bool SOSAccountIsActivePeerInCircleNamed(SOSAccountRef account, CFStringRef circle_name, CFStringRef peerid, CFErrorRef* error);
194
195bool SOSAccountIsMyPeerActiveInCircle(SOSAccountRef account, SOSCircleRef circle, CFErrorRef* error);
196
197SOSCircleRef SOSAccountFindCircle(SOSAccountRef a, CFStringRef name, CFErrorRef *error);
198
199SOSCircleRef SOSAccountEnsureCircle(SOSAccountRef a, CFStringRef name, CFErrorRef *error);
200
201bool SOSAccountUpdateCircleFromRemote(SOSAccountRef account, SOSCircleRef newCircle, CFErrorRef *error);
202
203bool SOSAccountUpdateCircle(SOSAccountRef account, SOSCircleRef newCircle, CFErrorRef *error);
204
205bool SOSAccountModifyCircle(SOSAccountRef account,
206                            CFStringRef circleName,
207                            CFErrorRef* error,
208                            bool (^action)(SOSCircleRef circle));
209
210SOSFullPeerInfoRef SOSAccountGetMyFullPeerInCircleNamedIfPresent(SOSAccountRef account, CFStringRef name, CFErrorRef *error);
211
212void AppendCircleKeyName(CFMutableArrayRef array, CFStringRef name);
213
214CFStringRef SOSInterestListCopyDescription(CFArrayRef interests);
215
216
217// Peers and PeerInfos
218bool SOSAccountDestroyCirclePeerInfoNamed(SOSAccountRef account, CFStringRef name, CFErrorRef* error);
219
220bool SOSAccountDestroyCirclePeerInfo(SOSAccountRef account, SOSCircleRef circle, CFErrorRef* error);
221
222SOSPeerInfoRef SOSAccountGetMyPeerInCircle(SOSAccountRef account, SOSCircleRef circle, CFErrorRef* error);
223
224SOSPeerInfoRef SOSAccountGetMyPeerInCircleNamed(SOSAccountRef account, CFStringRef name, CFErrorRef *error);
225
226bool SOSAccountIsActivePeerInCircleNamed(SOSAccountRef account, CFStringRef circle_name, CFStringRef peerid, CFErrorRef* error);
227
228bool SOSAccountIsMyPeerActiveInCircle(SOSAccountRef account, SOSCircleRef circle, CFErrorRef* error);
229
230// FullPeerInfos - including Cloud Identity
231SOSFullPeerInfoRef CopyCloudKeychainIdentity(SOSPeerInfoRef cloudPeer, CFErrorRef *error);
232
233SOSFullPeerInfoRef SOSAccountGetMyFullPeerInCircleNamedIfPresent(SOSAccountRef account, CFStringRef name, CFErrorRef *error);
234
235bool SOSAccountIsAccountIdentity(SOSAccountRef account, SOSPeerInfoRef peer_info, CFErrorRef *error);
236
237SOSFullPeerInfoRef SOSAccountGetMyFullPeerInCircleNamed(SOSAccountRef account, CFStringRef name, CFErrorRef *error);
238
239SOSFullPeerInfoRef SOSAccountGetMyFullPeerInCircle(SOSAccountRef account, SOSCircleRef circle, CFErrorRef* error);
240
241SOSPeerInfoRef GenerateNewCloudIdentityPeerInfo(CFErrorRef *error);
242
243// Credentials
244bool SOSAccountHasPublicKey(SOSAccountRef account, CFErrorRef* error);
245void SOSAccountSetPreviousPublic(SOSAccountRef account);
246bool SOSAccountPublishCloudParameters(SOSAccountRef account, CFErrorRef* error);
247bool SOSAccountRetrieveCloudParameters(SOSAccountRef account, SecKeyRef *newKey,
248                                       CFDataRef derparms,
249                                       CFDataRef *newParameters, CFErrorRef* error);
250
251//Testing
252void SOSAccountSetUserPublicTrustedForTesting(SOSAccountRef account);
253CFDictionaryRef SOSAccountGetMessageTransports(SOSAccountRef account);
254// Utility
255
256
257static inline void CFArrayAppendValueIfNot(CFMutableArrayRef array, CFTypeRef value, CFTypeRef excludedValue)
258{
259    if (!CFEqualSafe(value, excludedValue))
260        CFArrayAppendValue(array, value);
261}
262
263static inline CFMutableDictionaryRef CFDictionaryEnsureCFDictionaryAndGetCurrentValue(CFMutableDictionaryRef dict, CFTypeRef key)
264{
265    CFMutableDictionaryRef result = (CFMutableDictionaryRef) CFDictionaryGetValue(dict, key);
266
267    if (!isDictionary(result)) {
268        result = CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault);
269        CFDictionarySetValue(dict, key, result);
270        CFReleaseSafe(result);
271    }
272
273    return result;
274}
275
276static inline CFMutableArrayRef CFDictionaryEnsureCFArrayAndGetCurrentValue(CFMutableDictionaryRef dict, CFTypeRef key)
277{
278    CFMutableArrayRef result = (CFMutableArrayRef) CFDictionaryGetValue(dict, key);
279
280    if (!isArray(result)) {
281        result = CFArrayCreateMutableForCFTypes(kCFAllocatorDefault);
282        CFDictionarySetValue(dict, key, result);
283        CFReleaseSafe(result);
284    }
285
286    return result;
287}
288
289bool sosAccountLeaveCircle(SOSAccountRef account, SOSCircleRef circle, CFErrorRef* error);
290
291bool SOSAccountEnsurePeerRegistration(SOSAccountRef account, CFErrorRef *error);
292
293#endif
294