5 // Created by Richard Murphy on 3/5/15.
11 #include <AssertMacros.h>
13 #include <Security/SecureObjectSync/SOSInternal.h>
14 #include <Security/SecureObjectSync/SOSPeerInfoInternal.h>
15 #include <Security/SecureObjectSync/SOSPeerInfoCollections.h>
16 #include <Security/SecureObjectSync/SOSCircle.h>
17 #include <Security/SecFramework.h>
19 #include <Security/SecKey.h>
20 #include <Security/SecKeyPriv.h>
21 #include <CoreFoundation/CoreFoundation.h>
23 #include <utilities/SecCFWrappers.h>
28 #include "SOSRingUtils.h"
29 #include "SOSRingTypes.h"
31 // MARK: V0 Ring Ops - same operation as V0 Circles
33 static SOSRingRef
SOSRingCreate_V0(CFStringRef name
, CFStringRef myPeerID
, CFErrorRef
*error
) {
34 SOSRingRef retval
= NULL
;
35 retval
= SOSRingCreate_Internal(name
, 0, error
);
36 if(!retval
) return NULL
;
37 SOSRingSetLastModifier(retval
, myPeerID
);
41 static bool SOSRingResetToEmpty_V0(SOSRingRef ring
, CFStringRef myPeerID
, CFErrorRef
*error
) {
42 return SOSRingResetToEmpty_Internal(ring
, error
) && SOSRingSetLastModifier(ring
, myPeerID
);
45 static bool SOSRingResetToOffering_V0(SOSRingRef ring
, SecKeyRef user_privkey
, SOSFullPeerInfoRef requestor
, CFErrorRef
*error
) {
46 CFStringRef myPeerID
= SOSPeerInfoGetPeerID(SOSFullPeerInfoGetPeerInfo(requestor
));
47 SecKeyRef priv
= SOSFullPeerInfoCopyDeviceKey(requestor
, error
);
48 bool retval
= priv
&& myPeerID
&&
49 SOSRingResetToEmpty_Internal(ring
, error
) &&
50 SOSRingAddPeerID(ring
, myPeerID
) &&
51 SOSRingSetLastModifier(ring
, myPeerID
) &&
52 SOSRingGenerationSign_Internal(ring
, user_privkey
, error
);
53 SOSRingConcordanceSign_Internal(ring
, priv
, error
);
58 static SOSRingStatus
SOSRingDeviceIsInRing_V0(SOSRingRef ring
, CFStringRef peerID
) {
59 if(SOSRingHasPeerID(ring
, peerID
)) return kSOSRingMember
;
60 if(SOSRingHasApplicant(ring
, peerID
)) return kSOSRingApplicant
;
61 if(SOSRingHasRejection(ring
, peerID
)) return kSOSRingReject
;
62 return kSOSRingNotInRing
;
65 static bool SOSRingApply_V0(SOSRingRef ring
, SecKeyRef user_privkey
, SOSFullPeerInfoRef requestor
, CFErrorRef
*error
) {
67 CFStringRef myPeerID
= SOSPeerInfoGetPeerID(SOSFullPeerInfoGetPeerInfo(requestor
));
68 if(SOSRingDeviceIsInRing_V0(ring
, myPeerID
) == kSOSRingReject
) SOSRingRemoveRejection(ring
, myPeerID
);
69 require_action_quiet(SOSRingDeviceIsInRing_V0(ring
, myPeerID
) == kSOSRingNotInRing
, errOut
, secnotice("ring", "Already associated with ring"));
71 SOSRingAddApplicant(ring
, myPeerID
) &&
72 SOSRingSetLastModifier(ring
, myPeerID
);
77 static bool SOSRingWithdraw_V0(SOSRingRef ring
, SecKeyRef user_privkey
, SOSFullPeerInfoRef requestor
, CFErrorRef
*error
) {
78 CFStringRef myPeerID
= SOSPeerInfoGetPeerID(SOSFullPeerInfoGetPeerInfo(requestor
));
79 SOSRingSetLastModifier(ring
, myPeerID
);
80 if(SOSRingHasPeerID(ring
, myPeerID
)) {
81 SOSRingRemovePeerID(ring
, myPeerID
);// Maybe we need a retired peerID list?
82 SecKeyRef priv
= SOSFullPeerInfoCopyDeviceKey(requestor
, error
);
83 SOSRingGenerationSign_Internal(ring
, priv
, error
);
84 if(user_privkey
) SOSRingGenerationSign_Internal(ring
, user_privkey
, error
);
86 } else if(SOSRingHasApplicant(ring
, myPeerID
)) {
87 SOSRingRemoveApplicant(ring
, myPeerID
);
88 } else if(SOSRingHasRejection(ring
, myPeerID
)) {
89 SOSRingRemoveRejection(ring
, myPeerID
);
91 SOSCreateError(kSOSErrorPeerNotFound
, CFSTR("Not associated with Ring"), NULL
, error
);
98 static bool SOSRingGenerationSign_V0(SOSRingRef ring
, SecKeyRef user_privkey
, SOSFullPeerInfoRef requestor
, CFErrorRef
*error
) {
99 CFStringRef myPeerID
= SOSPeerInfoGetPeerID(SOSFullPeerInfoGetPeerInfo(requestor
));
100 SecKeyRef priv
= SOSFullPeerInfoCopyDeviceKey(requestor
, error
);
101 bool retval
= priv
&& myPeerID
&&
102 SOSRingSetLastModifier(ring
, myPeerID
) &&
103 SOSRingGenerationSign_Internal(ring
, priv
, error
);
104 if(user_privkey
) SOSRingGenerationSign_Internal(ring
, user_privkey
, error
);
109 static bool SOSRingConcordanceSign_V0(SOSRingRef ring
, SOSFullPeerInfoRef requestor
, CFErrorRef
*error
) {
110 CFStringRef myPeerID
= SOSPeerInfoGetPeerID(SOSFullPeerInfoGetPeerInfo(requestor
));
111 SecKeyRef priv
= SOSFullPeerInfoCopyDeviceKey(requestor
, error
);
112 bool retval
= priv
&& myPeerID
&&
113 SOSRingSetLastModifier(ring
, myPeerID
) &&
114 SOSRingConcordanceSign_Internal(ring
, priv
, error
);
120 __unused
static bool SOSRingSetPayload_V0(SOSRingRef ring
, SecKeyRef user_privkey
, CFDataRef payload
, SOSFullPeerInfoRef requestor
, CFErrorRef
*error
) {
121 CFStringRef myPeerID
= SOSPeerInfoGetPeerID(SOSFullPeerInfoGetPeerInfo(requestor
));
122 SecKeyRef priv
= SOSFullPeerInfoCopyDeviceKey(requestor
, error
);
123 bool retval
= priv
&& myPeerID
&&
124 SOSRingSetLastModifier(ring
, myPeerID
) &&
125 SOSRingSetPayload_Internal(ring
, payload
) &&
126 SOSRingGenerationSign_Internal(ring
, priv
, error
);
127 if(user_privkey
) SOSRingConcordanceSign_Internal(ring
, user_privkey
, error
);
132 __unused
static CFDataRef
SOSRingGetPayload_V0(SOSRingRef ring
, CFErrorRef
*error
) {
133 return SOSRingGetPayload_Internal(ring
);
137 ringFuncStruct basic
= {
141 SOSRingResetToEmpty_V0
,
142 SOSRingResetToOffering_V0
,
143 SOSRingDeviceIsInRing_V0
,
146 SOSRingGenerationSign_V0
,
147 SOSRingConcordanceSign_V0
,
148 SOSRingUserKeyConcordanceTrust
,