6 #include "SOSAccountPriv.h"
7 #include <Security/SecureObjectSync/SOSPeerInfoCollections.h>
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"
17 // MARK: Circle management
20 SecKeyRef
SOSAccountCopyPublicKeyForPeer(SOSAccountRef account
, CFStringRef peer_id
, CFErrorRef
*error
) {
21 SecKeyRef publicKey
= NULL
;
22 SOSPeerInfoRef peer
= NULL
;
24 require_action_quiet(account
->trusted_circle
, fail
, SOSErrorCreate(kSOSErrorNoCircle
, error
, NULL
, CFSTR("No circle to get peer key from")));
26 peer
= SOSCircleCopyPeerWithID(account
->trusted_circle
, peer_id
, error
);
27 require_quiet(peer
, fail
);
29 publicKey
= SOSPeerInfoCopyPubKey(peer
, error
);
37 SOSCircleRef
SOSAccountGetCircle(SOSAccountRef a
, CFErrorRef
*error
)
39 CFTypeRef entry
= a
->trusted_circle
;
41 require_action_quiet(!isNull(entry
), fail
,
42 SOSCreateError(kSOSErrorIncompatibleCircle
, CFSTR("Incompatible circle in KVS"), NULL
, error
));
44 require_action_quiet(entry
, fail
,
45 SOSCreateError(kSOSErrorNoCircle
, CFSTR("No circle found"), NULL
, error
));
48 return (SOSCircleRef
) entry
;
54 static bool SOSAccountInflateTransportsForCircle(SOSAccountRef account
, CFStringRef circleName
, CFErrorRef
*error
){
57 SOSTransportKeyParameterRef tKey
= NULL
;
58 SOSTransportCircleRef tCircle
= NULL
;
59 SOSTransportMessageRef tidsMessage
= NULL
;
60 SOSTransportMessageRef tkvsMessage
= NULL
;
62 tKey
= (SOSTransportKeyParameterRef
)SOSTransportKeyParameterKVSCreate(account
, error
);
63 tCircle
= (SOSTransportCircleRef
)SOSTransportCircleKVSCreate(account
, circleName
, error
);
65 require_quiet(tKey
, fail
);
66 require_quiet(tCircle
, fail
);
68 tidsMessage
= (SOSTransportMessageRef
)SOSTransportMessageIDSCreate(account
, circleName
, error
);
69 require_quiet(tidsMessage
, fail
);
71 CFRetainAssign(account
->ids_message_transport
, tidsMessage
);
73 tkvsMessage
= (SOSTransportMessageRef
)SOSTransportMessageKVSCreate(account
, circleName
, error
);
74 require_quiet(tkvsMessage
, fail
);
76 CFRetainAssign(account
->kvs_message_transport
, tkvsMessage
);
78 CFRetainAssign(account
->key_transport
, (SOSTransportKeyParameterRef
)tKey
);
79 CFRetainAssign(account
->circle_transport
, tCircle
);
85 CFReleaseNull(tCircle
);
86 CFReleaseNull(tidsMessage
);
87 CFReleaseNull(tkvsMessage
);
91 SOSCircleRef
SOSAccountEnsureCircle(SOSAccountRef a
, CFStringRef name
, CFErrorRef
*error
)
93 CFErrorRef localError
= NULL
;
95 if (a
->trusted_circle
== NULL
) {
96 a
->trusted_circle
= SOSCircleCreate(NULL
, name
, NULL
);
97 a
->key_interests_need_updating
= true;
101 SOSCircleRef circle
= SOSAccountGetCircle(a
, &localError
);
103 require_action_quiet(circle
|| !isSOSErrorCoded(localError
, kSOSErrorIncompatibleCircle
), fail
,
104 if (error
) { *error
= localError
; localError
= NULL
; });
106 require_quiet(SOSAccountInflateTransportsForCircle(a
, name
, error
), fail
);
109 CFReleaseNull(localError
);
114 bool SOSAccountUpdateCircleFromRemote(SOSAccountRef account
, SOSCircleRef newCircle
, CFErrorRef
*error
)
116 return SOSAccountHandleUpdateCircle(account
, newCircle
, false, error
);
119 bool SOSAccountUpdateCircle(SOSAccountRef account
, SOSCircleRef newCircle
, CFErrorRef
*error
)
121 return SOSAccountHandleUpdateCircle(account
, newCircle
, true, error
);
124 bool SOSAccountModifyCircle(SOSAccountRef account
,
126 bool (^action
)(SOSCircleRef circle
))
128 bool success
= false;
130 SOSCircleRef circle
= NULL
;
131 require_action_quiet(account
->trusted_circle
, fail
, SOSErrorCreate(kSOSErrorNoCircle
, error
, NULL
, CFSTR("No circle to get peer key from")));
133 circle
= SOSCircleCopyCircle(kCFAllocatorDefault
, account
->trusted_circle
, error
);
134 require_quiet(circle
, fail
);
137 require_quiet(action(circle
), fail
);
139 success
= SOSAccountUpdateCircle(account
, circle
, error
);
142 CFReleaseSafe(circle
);
146 CFSetRef
SOSAccountCopyPeerSetMatching(SOSAccountRef account
, bool (^action
)(SOSPeerInfoRef peer
)) {
147 CFMutableSetRef result
= CFSetCreateMutableForSOSPeerInfosByID(kCFAllocatorDefault
);
149 if (account
->trusted_circle
) {
150 SOSCircleForEachPeer(account
->trusted_circle
, ^(SOSPeerInfoRef peer
) {
152 CFSetAddValue(result
, peer
);