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"
16 // MARK: Circle management
19 SecKeyRef
SOSAccountCopyPublicKeyForPeer(SOSAccountRef account
, CFStringRef peer_id
, CFErrorRef
*error
) {
20 SecKeyRef publicKey
= NULL
;
21 SOSPeerInfoRef peer
= NULL
;
23 require_action_quiet(account
->trusted_circle
, fail
, SOSErrorCreate(kSOSErrorNoCircle
, error
, NULL
, CFSTR("No circle to get peer key from")));
25 peer
= SOSCircleCopyPeerWithID(account
->trusted_circle
, peer_id
, error
);
26 require_quiet(peer
, fail
);
28 publicKey
= SOSPeerInfoCopyPubKey(peer
, error
);
36 SOSCircleRef
SOSAccountGetCircle(SOSAccountRef a
, CFErrorRef
*error
)
38 CFTypeRef entry
= a
->trusted_circle
;
40 require_action_quiet(!isNull(entry
), fail
,
41 SOSCreateError(kSOSErrorIncompatibleCircle
, CFSTR("Incompatible circle in KVS"), NULL
, error
));
43 require_action_quiet(entry
, fail
,
44 SOSCreateError(kSOSErrorNoCircle
, CFSTR("No circle found"), NULL
, error
));
47 return (SOSCircleRef
) entry
;
53 static bool SOSAccountInflateTransportsForCircle(SOSAccountRef account
, CFStringRef circleName
, CFErrorRef
*error
){
56 SOSTransportKeyParameterRef tKey
= NULL
;
57 SOSTransportCircleRef tCircle
= NULL
;
58 SOSTransportMessageRef tidsMessage
= NULL
;
59 SOSTransportMessageRef tkvsMessage
= NULL
;
61 tKey
= (SOSTransportKeyParameterRef
)SOSTransportKeyParameterKVSCreate(account
, error
);
62 tCircle
= (SOSTransportCircleRef
)SOSTransportCircleKVSCreate(account
, circleName
, error
);
64 require_quiet(tKey
, fail
);
65 require_quiet(tCircle
, fail
);
67 tidsMessage
= (SOSTransportMessageRef
)SOSTransportMessageIDSCreate(account
, circleName
, error
);
68 require_quiet(tidsMessage
, fail
);
70 CFRetainAssign(account
->ids_message_transport
, tidsMessage
);
72 tkvsMessage
= (SOSTransportMessageRef
)SOSTransportMessageKVSCreate(account
, circleName
, error
);
73 require_quiet(tkvsMessage
, fail
);
75 CFRetainAssign(account
->kvs_message_transport
, tkvsMessage
);
77 CFRetainAssign(account
->key_transport
, (SOSTransportKeyParameterRef
)tKey
);
78 CFRetainAssign(account
->circle_transport
, tCircle
);
84 CFReleaseNull(tCircle
);
85 CFReleaseNull(tidsMessage
);
86 CFReleaseNull(tkvsMessage
);
90 SOSCircleRef
SOSAccountEnsureCircle(SOSAccountRef a
, CFStringRef name
, CFErrorRef
*error
)
92 CFErrorRef localError
= NULL
;
94 if (a
->trusted_circle
== NULL
) {
95 a
->trusted_circle
= SOSCircleCreate(NULL
, name
, NULL
);
96 a
->key_interests_need_updating
= true;
100 SOSCircleRef circle
= SOSAccountGetCircle(a
, &localError
);
102 require_action_quiet(circle
|| !isSOSErrorCoded(localError
, kSOSErrorIncompatibleCircle
), fail
,
103 if (error
) { *error
= localError
; localError
= NULL
; });
105 require_quiet(SOSAccountInflateTransportsForCircle(a
, name
, error
), fail
);
108 CFReleaseNull(localError
);
113 bool SOSAccountUpdateCircleFromRemote(SOSAccountRef account
, SOSCircleRef newCircle
, CFErrorRef
*error
)
115 return SOSAccountHandleUpdateCircle(account
, newCircle
, false, error
);
118 bool SOSAccountUpdateCircle(SOSAccountRef account
, SOSCircleRef newCircle
, CFErrorRef
*error
)
120 return SOSAccountHandleUpdateCircle(account
, newCircle
, true, error
);
123 bool SOSAccountModifyCircle(SOSAccountRef account
,
125 bool (^action
)(SOSCircleRef circle
))
127 bool success
= false;
129 SOSCircleRef circle
= NULL
;
130 require_action_quiet(account
->trusted_circle
, fail
, SOSErrorCreate(kSOSErrorNoCircle
, error
, NULL
, CFSTR("No circle to get peer key from")));
132 circle
= SOSCircleCopyCircle(kCFAllocatorDefault
, account
->trusted_circle
, error
);
133 require_quiet(circle
, fail
);
136 require_quiet(action(circle
), fail
);
138 success
= SOSAccountUpdateCircle(account
, circle
, error
);
141 CFReleaseSafe(circle
);