5 // Created by Richard Murphy on 3/3/15.
9 #include "SOSRingBasic.h"
11 #include <AssertMacros.h>
13 #include "keychain/SecureObjectSync/SOSInternal.h"
14 #include "keychain/SecureObjectSync/SOSPeerInfoInternal.h"
15 #include "keychain/SecureObjectSync/SOSPeerInfoCollections.h"
16 #include "keychain/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>
27 #include "SOSRingUtils.h"
28 #include "SOSRingTypes.h"
30 // MARK: Basic Ring Ops
32 SOSRingRef SOSRingCreate_Basic(CFStringRef name, CFStringRef myPeerID, CFErrorRef *error) {
33 return SOSRingCreate_ForType(name, kSOSRingBase, myPeerID, error);
36 bool SOSRingResetToEmpty_Basic(SOSRingRef ring, CFStringRef myPeerID, CFErrorRef *error) {
37 return SOSRingResetToEmpty_Internal(ring, error) && SOSRingSetLastModifier(ring, myPeerID);
40 bool SOSRingResetToOffering_Basic(SOSRingRef ring, SecKeyRef user_privkey, SOSFullPeerInfoRef requestor, CFErrorRef *error) {
41 CFStringRef myPeerID = SOSPeerInfoGetPeerID(SOSFullPeerInfoGetPeerInfo(requestor));
42 SecKeyRef priv = SOSFullPeerInfoCopyDeviceKey(requestor, error);
43 bool retval = priv && myPeerID &&
44 SOSRingResetToEmpty_Internal(ring, error) &&
45 SOSRingAddPeerID(ring, myPeerID) &&
46 SOSRingSetLastModifier(ring, myPeerID) &&
47 SOSRingGenerationSign_Internal(ring, priv, error);
48 if(user_privkey) SOSRingConcordanceSign_Internal(ring, user_privkey, error);
53 SOSRingStatus SOSRingDeviceIsInRing_Basic(SOSRingRef ring, CFStringRef peerID) {
54 if(SOSRingHasPeerID(ring, peerID)) return kSOSRingMember;
55 if(SOSRingHasApplicant(ring, peerID)) return kSOSRingApplicant;
56 if(SOSRingHasRejection(ring, peerID)) return kSOSRingReject;
57 return kSOSRingNotInRing;
60 bool SOSRingApply_Basic(SOSRingRef ring, SecKeyRef user_pubkey, SOSFullPeerInfoRef requestor, CFErrorRef *error) {
62 CFStringRef myPeerID = SOSPeerInfoGetPeerID(SOSFullPeerInfoGetPeerInfo(requestor));
63 SecKeyRef priv = SOSFullPeerInfoCopyDeviceKey(requestor, error);
64 require_action_quiet(SOSRingDeviceIsInRing_Basic(ring, myPeerID) == kSOSRingNotInRing, errOut, secnotice("ring", "Already associated with ring"));
65 retval = priv && myPeerID &&
66 SOSRingAddPeerID(ring, myPeerID) &&
67 SOSRingSetLastModifier(ring, myPeerID) &&
68 SOSRingGenerationSign_Internal(ring, priv, error);
75 bool SOSRingWithdraw_Basic(SOSRingRef ring, SecKeyRef user_privkey, SOSFullPeerInfoRef requestor, CFErrorRef *error) {
76 CFStringRef myPeerID = SOSPeerInfoGetPeerID(SOSFullPeerInfoGetPeerInfo(requestor));
77 if(SOSRingHasPeerID(ring, myPeerID)) {
78 SOSRingRemovePeerID(ring, myPeerID);
79 } else if(SOSRingHasApplicant(ring, myPeerID)) {
80 SOSRingRemoveApplicant(ring, myPeerID);
81 } else if(SOSRingHasRejection(ring, myPeerID)) {
82 SOSRingRemoveRejection(ring, myPeerID);
84 SOSCreateError(kSOSErrorPeerNotFound, CFSTR("Not associated with Ring"), NULL, error);
87 SOSRingSetLastModifier(ring, myPeerID);
89 SecKeyRef priv = SOSFullPeerInfoCopyDeviceKey(requestor, error);
90 SOSRingGenerationSign_Internal(ring, priv, error);
91 if(user_privkey) SOSRingConcordanceSign_Internal(ring, user_privkey, error);
96 bool SOSRingGenerationSign_Basic(SOSRingRef ring, SecKeyRef user_privkey, SOSFullPeerInfoRef requestor, CFErrorRef *error) {
97 CFStringRef myPeerID = SOSPeerInfoGetPeerID(SOSFullPeerInfoGetPeerInfo(requestor));
98 SecKeyRef priv = SOSFullPeerInfoCopyDeviceKey(requestor, error);
99 bool retval = priv && myPeerID &&
100 SOSRingSetLastModifier(ring, myPeerID) &&
101 SOSRingGenerationSign_Internal(ring, priv, error);
102 if(user_privkey) SOSRingConcordanceSign_Internal(ring, user_privkey, error);
107 bool SOSRingConcordanceSign_Basic(SOSRingRef ring, SOSFullPeerInfoRef requestor, CFErrorRef *error) {
108 CFStringRef myPeerID = SOSPeerInfoGetPeerID(SOSFullPeerInfoGetPeerInfo(requestor));
109 SecKeyRef priv = SOSFullPeerInfoCopyDeviceKey(requestor, error);
110 bool retval = priv && myPeerID &&
111 SOSRingSetLastModifier(ring, myPeerID) &&
112 SOSRingConcordanceSign_Internal(ring, priv, error);
117 bool SOSRingSetPayload_Basic(SOSRingRef ring, SecKeyRef user_privkey, CFDataRef payload, SOSFullPeerInfoRef requestor, CFErrorRef *error) {
118 CFStringRef myPeerID = SOSPeerInfoGetPeerID(SOSFullPeerInfoGetPeerInfo(requestor));
119 SecKeyRef priv = SOSFullPeerInfoCopyDeviceKey(requestor, error);
120 bool retval = priv && myPeerID &&
121 SOSRingSetLastModifier(ring, myPeerID) &&
122 SOSRingSetPayload_Internal(ring, payload) &&
123 SOSRingGenerationSign_Internal(ring, priv, error);
124 if(user_privkey) SOSRingConcordanceSign_Internal(ring, user_privkey, error);
129 CFDataRef SOSRingGetPayload_Basic(SOSRingRef ring, CFErrorRef *error) {
130 return SOSRingGetPayload_Internal(ring);
134 ringFuncStruct basic = {
138 SOSRingResetToEmpty_Basic,
139 SOSRingResetToOffering_Basic,
140 SOSRingDeviceIsInRing_Basic,
142 SOSRingWithdraw_Basic,
143 SOSRingGenerationSign_Basic,
144 SOSRingConcordanceSign_Basic,
145 SOSRingPeerKeyConcordanceTrust,
148 SOSRingSetPayload_Basic,
149 SOSRingGetPayload_Basic,