SOSRingBasic.m
1 // 2 // SOSRingBasic.c 3 // sec 4 // 5 // Created by Richard Murphy on 3/3/15. 6 // 7 // 8 9 #include "SOSRingBasic.h" 10 11 #include <AssertMacros.h> 12 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> 18 19 #include <Security/SecKey.h> 20 #include <Security/SecKeyPriv.h> 21 #include <CoreFoundation/CoreFoundation.h> 22 23 #include <utilities/SecCFWrappers.h> 24 25 #include <stdlib.h> 26 27 #include "SOSRingUtils.h" 28 #include "SOSRingTypes.h" 29 30 // MARK: Basic Ring Ops 31 32 SOSRingRef SOSRingCreate_Basic(CFStringRef name, CFStringRef myPeerID, CFErrorRef *error) { 33 return SOSRingCreate_ForType(name, kSOSRingBase, myPeerID, error); 34 } 35 36 bool SOSRingResetToEmpty_Basic(SOSRingRef ring, CFStringRef myPeerID, CFErrorRef *error) { 37 return SOSRingResetToEmpty_Internal(ring, error) && SOSRingSetLastModifier(ring, myPeerID); 38 } 39 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); 49 CFReleaseNull(priv); 50 return retval; 51 } 52 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; 58 } 59 60 bool SOSRingApply_Basic(SOSRingRef ring, SecKeyRef user_pubkey, SOSFullPeerInfoRef requestor, CFErrorRef *error) { 61 bool retval = false; 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); 69 errOut: 70 CFReleaseNull(priv); 71 return retval; 72 73 } 74 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); 83 } else { 84 SOSCreateError(kSOSErrorPeerNotFound, CFSTR("Not associated with Ring"), NULL, error); 85 return false; 86 } 87 SOSRingSetLastModifier(ring, myPeerID); 88 89 SecKeyRef priv = SOSFullPeerInfoCopyDeviceKey(requestor, error); 90 SOSRingGenerationSign_Internal(ring, priv, error); 91 if(user_privkey) SOSRingConcordanceSign_Internal(ring, user_privkey, error); 92 CFReleaseNull(priv); 93 return true; 94 } 95 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); 103 CFReleaseNull(priv); 104 return retval; 105 } 106 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); 113 CFReleaseNull(priv); 114 return retval; 115 } 116 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); 125 CFReleaseNull(priv); 126 return retval; 127 } 128 129 CFDataRef SOSRingGetPayload_Basic(SOSRingRef ring, CFErrorRef *error) { 130 return SOSRingGetPayload_Internal(ring); 131 } 132 133 134 ringFuncStruct basic = { 135 "Basic", 136 1, 137 SOSRingCreate_Basic, 138 SOSRingResetToEmpty_Basic, 139 SOSRingResetToOffering_Basic, 140 SOSRingDeviceIsInRing_Basic, 141 SOSRingApply_Basic, 142 SOSRingWithdraw_Basic, 143 SOSRingGenerationSign_Basic, 144 SOSRingConcordanceSign_Basic, 145 SOSRingPeerKeyConcordanceTrust, 146 NULL, 147 NULL, 148 SOSRingSetPayload_Basic, 149 SOSRingGetPayload_Basic, 150 };