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>
28 #include "SOSRingUtils.h"
29 #include "SOSRingTypes.h"
31 // MARK: Basic Ring Ops
33 SOSRingRef SOSRingCreate_Basic(CFStringRef name, CFStringRef myPeerID, CFErrorRef *error) {
34 return SOSRingCreate_ForType(name, kSOSRingBase, myPeerID, error);
37 bool SOSRingResetToEmpty_Basic(SOSRingRef ring, CFStringRef myPeerID, CFErrorRef *error) {
38 return SOSRingResetToEmpty_Internal(ring, error) && SOSRingSetLastModifier(ring, myPeerID);
41 bool SOSRingResetToOffering_Basic(SOSRingRef ring, SecKeyRef user_privkey, SOSFullPeerInfoRef requestor, CFErrorRef *error) {
42 CFStringRef myPeerID = SOSPeerInfoGetPeerID(SOSFullPeerInfoGetPeerInfo(requestor));
43 SecKeyRef priv = SOSFullPeerInfoCopyDeviceKey(requestor, error);
44 bool retval = priv && myPeerID &&
45 SOSRingResetToEmpty_Internal(ring, error) &&
46 SOSRingAddPeerID(ring, myPeerID) &&
47 SOSRingSetLastModifier(ring, myPeerID) &&
48 SOSRingGenerationSign_Internal(ring, priv, error);
49 if(user_privkey) SOSRingConcordanceSign_Internal(ring, user_privkey, error);
54 SOSRingStatus SOSRingDeviceIsInRing_Basic(SOSRingRef ring, CFStringRef peerID) {
55 if(SOSRingHasPeerID(ring, peerID)) return kSOSRingMember;
56 if(SOSRingHasApplicant(ring, peerID)) return kSOSRingApplicant;
57 if(SOSRingHasRejection(ring, peerID)) return kSOSRingReject;
58 return kSOSRingNotInRing;
61 bool SOSRingApply_Basic(SOSRingRef ring, SecKeyRef user_pubkey, SOSFullPeerInfoRef requestor, CFErrorRef *error) {
63 CFStringRef myPeerID = SOSPeerInfoGetPeerID(SOSFullPeerInfoGetPeerInfo(requestor));
64 SecKeyRef priv = SOSFullPeerInfoCopyDeviceKey(requestor, error);
65 require_action_quiet(SOSRingDeviceIsInRing_Basic(ring, myPeerID) == kSOSRingNotInRing, errOut, secnotice("ring", "Already associated with ring"));
66 retval = priv && myPeerID &&
67 SOSRingAddPeerID(ring, myPeerID) &&
68 SOSRingSetLastModifier(ring, myPeerID) &&
69 SOSRingGenerationSign_Internal(ring, priv, error);
76 bool SOSRingWithdraw_Basic(SOSRingRef ring, SecKeyRef user_privkey, SOSFullPeerInfoRef requestor, CFErrorRef *error) {
77 CFStringRef myPeerID = SOSPeerInfoGetPeerID(SOSFullPeerInfoGetPeerInfo(requestor));
78 if(SOSRingHasPeerID(ring, myPeerID)) {
79 SOSRingRemovePeerID(ring, myPeerID);
80 } else if(SOSRingHasApplicant(ring, myPeerID)) {
81 SOSRingRemoveApplicant(ring, myPeerID);
82 } else if(SOSRingHasRejection(ring, myPeerID)) {
83 SOSRingRemoveRejection(ring, myPeerID);
85 SOSCreateError(kSOSErrorPeerNotFound, CFSTR("Not associated with Ring"), NULL, error);
88 SOSRingSetLastModifier(ring, myPeerID);
90 SecKeyRef priv = SOSFullPeerInfoCopyDeviceKey(requestor, error);
91 SOSRingGenerationSign_Internal(ring, priv, error);
92 if(user_privkey) SOSRingConcordanceSign_Internal(ring, user_privkey, error);
97 bool SOSRingGenerationSign_Basic(SOSRingRef ring, SecKeyRef user_privkey, SOSFullPeerInfoRef requestor, CFErrorRef *error) {
98 CFStringRef myPeerID = SOSPeerInfoGetPeerID(SOSFullPeerInfoGetPeerInfo(requestor));
99 SecKeyRef priv = SOSFullPeerInfoCopyDeviceKey(requestor, error);
100 bool retval = priv && myPeerID &&
101 SOSRingSetLastModifier(ring, myPeerID) &&
102 SOSRingGenerationSign_Internal(ring, priv, error);
103 if(user_privkey) SOSRingConcordanceSign_Internal(ring, user_privkey, error);
108 bool SOSRingConcordanceSign_Basic(SOSRingRef ring, SOSFullPeerInfoRef requestor, CFErrorRef *error) {
109 CFStringRef myPeerID = SOSPeerInfoGetPeerID(SOSFullPeerInfoGetPeerInfo(requestor));
110 SecKeyRef priv = SOSFullPeerInfoCopyDeviceKey(requestor, error);
111 bool retval = priv && myPeerID &&
112 SOSRingSetLastModifier(ring, myPeerID) &&
113 SOSRingConcordanceSign_Internal(ring, priv, error);
118 bool SOSRingSetPayload_Basic(SOSRingRef ring, SecKeyRef user_privkey, CFDataRef payload, SOSFullPeerInfoRef requestor, CFErrorRef *error) {
119 CFStringRef myPeerID = SOSPeerInfoGetPeerID(SOSFullPeerInfoGetPeerInfo(requestor));
120 SecKeyRef priv = SOSFullPeerInfoCopyDeviceKey(requestor, error);
121 bool retval = priv && myPeerID &&
122 SOSRingSetLastModifier(ring, myPeerID) &&
123 SOSRingSetPayload_Internal(ring, payload) &&
124 SOSRingGenerationSign_Internal(ring, priv, error);
125 if(user_privkey) SOSRingConcordanceSign_Internal(ring, user_privkey, error);
130 CFDataRef SOSRingGetPayload_Basic(SOSRingRef ring, CFErrorRef *error) {
131 return SOSRingGetPayload_Internal(ring);
135 ringFuncStruct basic = {
139 SOSRingResetToEmpty_Basic,
140 SOSRingResetToOffering_Basic,
141 SOSRingDeviceIsInRing_Basic,
143 SOSRingWithdraw_Basic,
144 SOSRingGenerationSign_Basic,
145 SOSRingConcordanceSign_Basic,
146 SOSRingPeerKeyConcordanceTrust,
149 SOSRingSetPayload_Basic,
150 SOSRingGetPayload_Basic,