6 #ifndef sec_SOSAccountPriv_h
7 #define sec_SOSAccountPriv_h
9 #include "SOSAccount.h"
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>
18 #include <Security/SecKeyPriv.h>
20 #include <utilities/der_plist.h>
21 #include <utilities/der_plist_internal.h>
22 #include <corecrypto/ccder.h>
24 #include <AssertMacros.h>
29 #include <Security/SecureObjectSync/SOSInternal.h>
30 #include <Security/SecureObjectSync/SOSCircle.h>
31 #include <Security/SecureObjectSync/SOSCircleV2.h>
32 #include <Security/SecureObjectSync/SOSRing.h>
33 #include <Security/SecureObjectSync/SOSRingUtils.h>
34 #include <Security/SecureObjectSync/SOSCloudCircle.h>
35 #include <securityd/SOSCloudCircleServer.h>
36 #include <Security/SecureObjectSync/SOSEngine.h>
37 #include <Security/SecureObjectSync/SOSPeer.h>
38 #include <Security/SecureObjectSync/SOSFullPeerInfo.h>
39 #include <Security/SecureObjectSync/SOSPeerInfo.h>
40 #include <Security/SecureObjectSync/SOSPeerInfoInternal.h>
41 #include <Security/SecureObjectSync/SOSUserKeygen.h>
42 #include <Security/SecureObjectSync/SOSAccountTransaction.h>
43 #include <utilities/iCloudKeychainTrace.h>
45 #include <Security/SecItemPriv.h>
47 extern const CFStringRef kSOSRecoveryRing
;
49 struct __OpaqueSOSAccount
{
52 CFDictionaryRef gestalt
;
56 SOSFullPeerInfoRef my_identity
;
57 SOSCircleRef trusted_circle
;
61 CFMutableDictionaryRef backups
;
63 CFMutableSetRef retirees
;
65 bool user_public_trusted
;
66 CFDataRef user_key_parameters
;
67 SecKeyRef user_public
;
68 SecKeyRef previous_public
;
69 enum DepartureReason departure_code
;
70 CFMutableDictionaryRef expansion
; // All CFTypes and Keys
72 // Non-persistent data
73 dispatch_queue_t queue
;
75 SOSDataSourceFactoryRef factory
;
76 SecKeyRef _user_private
;
77 CFDataRef _password_tmp
;
79 bool isListeningForSync
;
81 dispatch_source_t user_private_timer
;
82 int lock_notification_token
;
84 SOSTransportKeyParameterRef key_transport
;
85 SOSTransportCircleRef circle_transport
;
86 SOSTransportMessageRef kvs_message_transport
;
87 SOSTransportMessageRef ids_message_transport
;
89 //indicates if changes in circle, rings, or retirements need to be pushed
90 bool circle_rings_retirements_need_attention
;
91 bool engine_peer_state_needs_repair
;
92 bool key_interests_need_updating
;
95 CFMutableArrayRef change_blocks
;
96 CFMutableDictionaryRef waitForInitialSync_blocks
;
98 SOSAccountSaveBlock saveBlock
;
100 extern const CFStringRef kSOSEscrowRecord
;
101 extern const CFStringRef kSOSTestV2Settings
;
103 SOSAccountRef
SOSAccountCreateBasic(CFAllocatorRef allocator
,
104 CFDictionaryRef gestalt
,
105 SOSDataSourceFactoryRef factory
);
107 bool SOSAccountEnsureFactoryCircles(SOSAccountRef a
);
109 void SOSAccountSetToNew(SOSAccountRef a
);
111 bool SOSAccountIsMyPeerActive(SOSAccountRef account
, CFErrorRef
* error
);
113 // MARK: Notifications
115 #define kSecServerPeerInfoAvailable "com.apple.security.fpiAvailable"
118 // MARK: Getters and Setters
120 // UUID, no setter just getter and ensuring value.
121 void SOSAccountEnsureUUID(SOSAccountRef account
);
122 CFStringRef
SOSAccountCopyUUID(SOSAccountRef account
);
125 // MARK: Transactional
127 void SOSAccountWithTransaction_Locked(SOSAccountRef account
, void (^action
)(SOSAccountRef account
, SOSAccountTransactionRef txn
));
129 void SOSAccountWithTransaction(SOSAccountRef account
, bool sync
, void (^action
)(SOSAccountRef account
, SOSAccountTransactionRef txn
));
130 void SOSAccountWithTransactionSync(SOSAccountRef account
, void (^action
)(SOSAccountRef account
, SOSAccountTransactionRef txn
));
131 void SOSAccountWithTransactionAsync(SOSAccountRef account
, bool sync
, void (^action
)(SOSAccountRef account
, SOSAccountTransactionRef txn
));
133 void SOSAccountRecordRetiredPeersInCircle(SOSAccountRef account
);
135 // MARK: In Sync checking
137 CF_RETURNS_RETAINED CFStringRef
SOSAccountCallWhenInSync(SOSAccountRef account
, SOSAccountWaitForInitialSyncBlock syncBlock
);
138 bool SOSAccountUnregisterCallWhenInSync(SOSAccountRef account
, CFStringRef id
);
140 bool SOSAccountHandleOutOfSyncUpdate(SOSAccountRef account
, CFSetRef oldOOSViews
, CFSetRef newOOSViews
);
142 void SOSAccountUpdateOutOfSyncViews(SOSAccountTransactionRef aTxn
, CFSetRef viewsInSync
);
144 void SOSAccountEnsureSyncChecking(SOSAccountRef account
);
145 void SOSAccountCancelSyncChecking(SOSAccountRef account
);
147 bool SOSAccountCheckForAlwaysOnViews(SOSAccountRef account
);
149 CFMutableSetRef
SOSAccountCopyOutstandingViews(SOSAccountRef account
);
150 CFMutableSetRef
SOSAccountCopyIntersectionWithOustanding(SOSAccountRef account
, CFSetRef inSet
);
151 bool SOSAccountIntersectsWithOutstanding(SOSAccountRef account
, CFSetRef views
);
152 bool SOSAccountIsViewOutstanding(SOSAccountRef account
, CFStringRef view
);
153 bool SOSAccountHasOustandingViews(SOSAccountRef account
);
159 size_t der_sizeof_data_or_null(CFDataRef data
, CFErrorRef
* error
);
161 uint8_t* der_encode_data_or_null(CFDataRef data
, CFErrorRef
* error
, const uint8_t* der
, uint8_t* der_end
);
163 const uint8_t* der_decode_data_or_null(CFAllocatorRef allocator
, CFDataRef
* data
,
165 const uint8_t* der
, const uint8_t* der_end
);
167 size_t der_sizeof_fullpeer_or_null(SOSFullPeerInfoRef data
, CFErrorRef
* error
);
169 uint8_t* der_encode_fullpeer_or_null(SOSFullPeerInfoRef data
, CFErrorRef
* error
, const uint8_t* der
, uint8_t* der_end
);
171 const uint8_t* der_decode_fullpeer_or_null(CFAllocatorRef allocator
, SOSFullPeerInfoRef
* data
,
173 const uint8_t* der
, const uint8_t* der_end
);
176 size_t der_sizeof_public_bytes(SecKeyRef publicKey
, CFErrorRef
* error
);
178 uint8_t* der_encode_public_bytes(SecKeyRef publicKey
, CFErrorRef
* error
, const uint8_t* der
, uint8_t* der_end
);
180 const uint8_t* der_decode_public_bytes(CFAllocatorRef allocator
, CFIndex algorithmID
, SecKeyRef
* publicKey
, CFErrorRef
* error
, const uint8_t* der
, const uint8_t* der_end
);
185 SOSAccountRef
SOSAccountCreateFromDER(CFAllocatorRef allocator
,
186 SOSDataSourceFactoryRef factory
,
188 const uint8_t** der_p
, const uint8_t *der_end
);
190 SOSAccountRef
SOSAccountCreateFromData(CFAllocatorRef allocator
, CFDataRef circleData
,
191 SOSDataSourceFactoryRef factory
,
194 size_t SOSAccountGetDEREncodedSize(SOSAccountRef account
, CFErrorRef
*error
);
196 uint8_t* SOSAccountEncodeToDER(SOSAccountRef account
, CFErrorRef
* error
, const uint8_t* der
, uint8_t* der_end
);
198 CFDataRef
SOSAccountCopyEncodedData(SOSAccountRef account
, CFAllocatorRef allocator
, CFErrorRef
*error
);
202 bool SOSAccountHandleCircleMessage(SOSAccountRef account
,
203 CFStringRef circleName
, CFDataRef encodedCircleMessage
, CFErrorRef
*error
);
206 CFDictionaryRef
SOSAccountHandleRetirementMessages(SOSAccountRef account
, CFDictionaryRef circle_retirement_messages
, CFErrorRef
*error
);
209 bool SOSAccountHandleUpdateCircle(SOSAccountRef account
,
210 SOSCircleRef prospective_circle
,
214 void SOSAccountNotifyEngines(SOSAccountRef account
);
216 bool SOSAccountSyncingV0(SOSAccountRef account
);
219 bool SOSAccountHasFullPeerInfo(SOSAccountRef account
, CFErrorRef
* error
);
220 SOSPeerInfoRef
SOSAccountGetMyPeerInfo(SOSAccountRef account
);
221 SOSFullPeerInfoRef
SOSAccountGetMyFullPeerInfo(SOSAccountRef account
);
222 CFStringRef
SOSAccountGetMyPeerID(SOSAccountRef a
);
223 bool SOSAccountIsMyPeerInBackupAndCurrentInView(SOSAccountRef account
, CFStringRef viewname
);
224 bool SOSAccountUpdateOurPeerInBackup(SOSAccountRef account
, SOSRingRef oldRing
, CFErrorRef
*error
);
225 bool SOSAccountIsPeerInBackupAndCurrentInView(SOSAccountRef account
, SOSPeerInfoRef testPeer
, CFStringRef viewname
);
226 bool SOSDeleteV0Keybag(CFErrorRef
*error
);
227 void SOSAccountForEachBackupView(SOSAccountRef account
, void (^operation
)(const void *value
));
228 bool SOSAccountUpdatePeerInfo(SOSAccountRef account
, CFStringRef updateDescription
, CFErrorRef
*error
, bool (^update
)(SOSFullPeerInfoRef fpi
, CFErrorRef
*error
));
230 // Currently permitted backup rings.
231 void SOSAccountForEachRingName(SOSAccountRef account
, void (^operation
)(CFStringRef value
));
234 bool SOSAccountHasCircle(SOSAccountRef account
, CFErrorRef
* error
);
235 SOSCircleRef
SOSAccountGetCircle(SOSAccountRef a
, CFErrorRef
*error
);
236 SOSCircleRef
SOSAccountEnsureCircle(SOSAccountRef a
, CFStringRef name
, CFErrorRef
*error
);
238 bool SOSAccountUpdateCircleFromRemote(SOSAccountRef account
, SOSCircleRef newCircle
, CFErrorRef
*error
);
239 bool SOSAccountUpdateCircle(SOSAccountRef account
, SOSCircleRef newCircle
, CFErrorRef
*error
);
240 bool SOSAccountModifyCircle(SOSAccountRef account
,
242 bool (^action
)(SOSCircleRef circle
));
243 CFSetRef
SOSAccountCopyPeerSetMatching(SOSAccountRef account
, bool (^action
)(SOSPeerInfoRef peer
));
245 void AppendCircleKeyName(CFMutableArrayRef array
, CFStringRef name
);
247 CFStringRef
SOSInterestListCopyDescription(CFArrayRef interests
);
250 // FullPeerInfos - including Cloud Identity
251 SOSFullPeerInfoRef
CopyCloudKeychainIdentity(SOSPeerInfoRef cloudPeer
, CFErrorRef
*error
);
253 SecKeyRef
GeneratePermanentFullECKey(int keySize
, CFStringRef name
, CFErrorRef
* error
);
255 bool SOSAccountEnsureFullPeerAvailable(SOSAccountRef account
, CFErrorRef
* error
);
257 bool SOSAccountIsAccountIdentity(SOSAccountRef account
, SOSPeerInfoRef peer_info
, CFErrorRef
*error
);
258 bool SOSAccountFullPeerInfoVerify(SOSAccountRef account
, SecKeyRef privKey
, CFErrorRef
*error
);
259 SOSPeerInfoRef
GenerateNewCloudIdentityPeerInfo(CFErrorRef
*error
);
262 bool SOSAccountHasPublicKey(SOSAccountRef account
, CFErrorRef
* error
);
263 void SOSAccountSetPreviousPublic(SOSAccountRef account
);
264 bool SOSAccountPublishCloudParameters(SOSAccountRef account
, CFErrorRef
* error
);
265 bool SOSAccountRetrieveCloudParameters(SOSAccountRef account
, SecKeyRef
*newKey
,
267 CFDataRef
*newParameters
, CFErrorRef
* error
);
270 void SOSAccountAssertDSID(SOSAccountRef account
, CFStringRef dsid
);
276 SecKeyRef
SOSAccountCopyDeviceKey(SOSAccountRef account
, CFErrorRef
*error
);
277 SecKeyRef
SOSAccountCopyPublicKeyForPeer(SOSAccountRef account
, CFStringRef peer_id
, CFErrorRef
*error
);
280 void SOSAccountSetLastDepartureReason(SOSAccountRef account
, enum DepartureReason reason
);
281 void SOSAccountSetUserPublicTrustedForTesting(SOSAccountRef account
);
282 void SOSAccountPeerGotInSync(SOSAccountTransactionRef aTxn
, CFStringRef peerID
, CFSetRef views
);
284 static inline void CFArrayAppendValueIfNot(CFMutableArrayRef array
, CFTypeRef value
, CFTypeRef excludedValue
)
286 if (!CFEqualSafe(value
, excludedValue
))
287 CFArrayAppendValue(array
, value
);
290 static inline CFMutableDictionaryRef
CFDictionaryEnsureCFDictionaryAndGetCurrentValue(CFMutableDictionaryRef dict
, CFTypeRef key
)
292 CFMutableDictionaryRef result
= (CFMutableDictionaryRef
) CFDictionaryGetValue(dict
, key
);
294 if (!isDictionary(result
)) {
295 result
= CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault
);
296 CFDictionarySetValue(dict
, key
, result
);
297 CFReleaseSafe(result
);
303 static inline CFMutableArrayRef
CFDictionaryEnsureCFArrayAndGetCurrentValue(CFMutableDictionaryRef dict
, CFTypeRef key
)
305 CFMutableArrayRef result
= (CFMutableArrayRef
) CFDictionaryGetValue(dict
, key
);
307 if (!isArray(result
)) {
308 result
= CFArrayCreateMutableForCFTypes(kCFAllocatorDefault
);
309 CFDictionarySetValue(dict
, key
, result
);
310 CFReleaseSafe(result
);
316 void SOSAccountPurgeIdentity(SOSAccountRef account
);
317 bool sosAccountLeaveCircle(SOSAccountRef account
, SOSCircleRef circle
, CFErrorRef
* error
);
318 bool sosAccountLeaveRing(SOSAccountRef account
, SOSRingRef ring
, CFErrorRef
* error
);
319 void SOSAccountAddRingDictionary(SOSAccountRef a
);
320 bool SOSAccountForEachRing(SOSAccountRef account
, SOSRingRef (^action
)(CFStringRef name
, SOSRingRef ring
));
321 CFMutableDictionaryRef
SOSAccountGetBackups(SOSAccountRef a
, CFErrorRef
*error
);
322 bool SOSAccountUpdateBackUp(SOSAccountRef account
, CFStringRef viewname
, CFErrorRef
*error
);
323 bool SOSAccountEnsureInBackupRings(SOSAccountRef account
);
325 bool SOSAccountEnsurePeerRegistration(SOSAccountRef account
, CFErrorRef
*error
);
327 extern const CFStringRef kSOSDSIDKey
;
328 extern const CFStringRef SOSTransportMessageTypeIDSV2
;
329 extern const CFStringRef SOSTransportMessageTypeKVS
;
331 extern const CFStringRef kSOSUnsyncedViewsKey
;
332 extern const CFStringRef kSOSPendingEnableViewsToBeSetKey
;
333 extern const CFStringRef kSOSPendingDisableViewsToBeSetKey
;
334 extern const CFStringRef kSOSRecoveryKey
;
335 extern const CFStringRef kSOSAccountUUID
;
338 kSOSTransportNone
= 0,
339 kSOSTransportIDS
= 1,
340 kSOSTransportKVS
= 2,
341 kSOSTransportFuture
= 3,
342 kSOSTransportPresent
= 4
345 SOSPeerInfoRef
SOSAccountCopyPeerWithID(SOSAccountRef account
, CFStringRef peerid
, CFErrorRef
*error
);
347 // MARK: Value setting/clearing
348 bool SOSAccountSetValue(SOSAccountRef account
, CFStringRef key
, CFTypeRef value
, CFErrorRef
*error
);
349 bool SOSAccountClearValue(SOSAccountRef account
, CFStringRef key
, CFErrorRef
*error
);
350 CFTypeRef
SOSAccountGetValue(SOSAccountRef account
, CFStringRef key
, CFErrorRef
*error
);
352 // MARK: Value as Set
353 bool SOSAccountValueSetContainsValue(SOSAccountRef account
, CFStringRef key
, CFTypeRef value
);
354 void SOSAccountValueUnionWith(SOSAccountRef account
, CFStringRef key
, CFSetRef valuesToUnion
);
355 void SOSAccountValueSubtractFrom(SOSAccountRef account
, CFStringRef key
, CFSetRef valuesToSubtract
);
358 bool SOSAccountAddEscrowToPeerInfo(SOSAccountRef account
, SOSFullPeerInfoRef myPeer
, CFErrorRef
*error
);
359 bool SOSAccountAddEscrowRecords(SOSAccountRef account
, CFStringRef dsid
, CFDictionaryRef record
, CFErrorRef
*error
);
360 bool SOSAccountCheckForRings(SOSAccountRef a
, CFErrorRef
*error
);
361 bool SOSAccountHandleUpdateRing(SOSAccountRef account
, SOSRingRef prospective_ring
, bool writeUpdate
, CFErrorRef
*error
);
362 SOSRingRef
SOSAccountCopyRing(SOSAccountRef a
, CFStringRef ringName
, CFErrorRef
*error
);
363 bool SOSAccountSetRing(SOSAccountRef a
, SOSRingRef ring
, CFStringRef ringName
, CFErrorRef
*error
);
364 void SOSAccountRemoveRing(SOSAccountRef a
, CFStringRef ringName
);
365 SOSRingRef
SOSAccountCopyRingNamed(SOSAccountRef a
, CFStringRef ringName
, CFErrorRef
*error
);
366 SOSRingRef
SOSAccountRingCreateForName(SOSAccountRef a
, CFStringRef ringName
, CFErrorRef
*error
);
367 bool SOSAccountUpdateRingFromRemote(SOSAccountRef account
, SOSRingRef newRing
, CFErrorRef
*error
);
368 bool SOSAccountUpdateRing(SOSAccountRef account
, SOSRingRef newRing
, CFErrorRef
*error
);
369 bool SOSAccountModifyRing(SOSAccountRef account
, CFStringRef ringName
,
371 bool (^action
)(SOSRingRef ring
));
372 CFDataRef
SOSAccountRingCopyPayload(SOSAccountRef account
, CFStringRef ringName
, CFErrorRef
*error
);
373 SOSRingRef
SOSAccountRingCopyWithPayload(SOSAccountRef account
, CFStringRef ringName
, CFDataRef payload
, CFErrorRef
*error
);
374 bool SOSAccountRemoveBackupPeers(SOSAccountRef account
, CFArrayRef peerIDs
, CFErrorRef
*error
);
375 bool SOSAccountResetRing(SOSAccountRef account
, CFStringRef ringName
, CFErrorRef
*error
);
376 bool SOSAccountResetAllRings(SOSAccountRef account
, CFErrorRef
*error
);
377 bool SOSAccountCheckPeerAvailability(SOSAccountRef account
, CFErrorRef
*error
);
378 bool SOSAccountUpdateNamedRing(SOSAccountRef account
, CFStringRef ringName
, CFErrorRef
*error
,
379 SOSRingRef (^create
)(CFStringRef ringName
, CFErrorRef
*error
),
380 SOSRingRef (^copyModified
)(SOSRingRef existing
, CFErrorRef
*error
));
383 // MARK: Backup translation functions
386 CFStringRef
SOSBackupCopyRingNameForView(CFStringRef viewName
);
389 // Security tool test/debug functions
392 CFDataRef
SOSAccountCopyAccountStateFromKeychain(CFErrorRef
*error
);
393 bool SOSAccountDeleteAccountStateFromKeychain(CFErrorRef
*error
);
394 CFDataRef
SOSAccountCopyEngineStateFromKeychain(CFErrorRef
*error
);
395 bool SOSAccountDeleteEngineStateFromKeychain(CFErrorRef
*error
);
397 bool SOSAccountIsNew(SOSAccountRef account
, CFErrorRef
*error
);