SOSRingV0.m
1 // 2 // SOSRingV0.c 3 // sec 4 // 5 // Created by Richard Murphy on 3/5/15. 6 // 7 // 8 9 #include "SOSRingV0.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: V0 Ring Ops - same operation as V0 Circles 31 32 static SOSRingRef SOSRingCreate_V0(CFStringRef name, CFStringRef myPeerID, CFErrorRef *error) { 33 SOSRingRef retval = NULL; 34 retval = SOSRingCreate_Internal(name, 0, error); 35 if(!retval) return NULL; 36 SOSRingSetLastModifier(retval, myPeerID); 37 return retval; 38 } 39 40 static bool SOSRingResetToEmpty_V0(SOSRingRef ring, CFStringRef myPeerID, CFErrorRef *error) { 41 return SOSRingResetToEmpty_Internal(ring, error) && SOSRingSetLastModifier(ring, myPeerID); 42 } 43 44 static bool SOSRingResetToOffering_V0(SOSRingRef ring, SecKeyRef user_privkey, SOSFullPeerInfoRef requestor, CFErrorRef *error) { 45 CFStringRef myPeerID = SOSPeerInfoGetPeerID(SOSFullPeerInfoGetPeerInfo(requestor)); 46 SecKeyRef priv = SOSFullPeerInfoCopyDeviceKey(requestor, error); 47 bool retval = priv && myPeerID && 48 SOSRingResetToEmpty_Internal(ring, error) && 49 SOSRingAddPeerID(ring, myPeerID) && 50 SOSRingSetLastModifier(ring, myPeerID) && 51 SOSRingGenerationSign_Internal(ring, user_privkey, error); 52 SOSRingConcordanceSign_Internal(ring, priv, error); 53 CFReleaseNull(priv); 54 return retval; 55 } 56 57 static SOSRingStatus SOSRingDeviceIsInRing_V0(SOSRingRef ring, CFStringRef peerID) { 58 if(SOSRingHasPeerID(ring, peerID)) return kSOSRingMember; 59 if(SOSRingHasApplicant(ring, peerID)) return kSOSRingApplicant; 60 if(SOSRingHasRejection(ring, peerID)) return kSOSRingReject; 61 return kSOSRingNotInRing; 62 } 63 64 static bool SOSRingApply_V0(SOSRingRef ring, SecKeyRef user_privkey, SOSFullPeerInfoRef requestor, CFErrorRef *error) { 65 bool retval = false; 66 CFStringRef myPeerID = SOSPeerInfoGetPeerID(SOSFullPeerInfoGetPeerInfo(requestor)); 67 if(SOSRingDeviceIsInRing_V0(ring, myPeerID) == kSOSRingReject) SOSRingRemoveRejection(ring, myPeerID); 68 require_action_quiet(SOSRingDeviceIsInRing_V0(ring, myPeerID) == kSOSRingNotInRing, errOut, secnotice("ring", "Already associated with ring")); 69 retval = myPeerID && 70 SOSRingAddApplicant(ring, myPeerID) && 71 SOSRingSetLastModifier(ring, myPeerID); 72 errOut: 73 return retval; 74 } 75 76 static bool SOSRingWithdraw_V0(SOSRingRef ring, SecKeyRef user_privkey, SOSFullPeerInfoRef requestor, CFErrorRef *error) { 77 CFStringRef myPeerID = SOSPeerInfoGetPeerID(SOSFullPeerInfoGetPeerInfo(requestor)); 78 SOSRingSetLastModifier(ring, myPeerID); 79 if(SOSRingHasPeerID(ring, myPeerID)) { 80 SOSRingRemovePeerID(ring, myPeerID);// Maybe we need a retired peerID list? 81 SecKeyRef priv = SOSFullPeerInfoCopyDeviceKey(requestor, error); 82 SOSRingGenerationSign_Internal(ring, priv, error); 83 if(user_privkey) SOSRingGenerationSign_Internal(ring, user_privkey, error); 84 CFReleaseNull(priv); 85 } else if(SOSRingHasApplicant(ring, myPeerID)) { 86 SOSRingRemoveApplicant(ring, myPeerID); 87 } else if(SOSRingHasRejection(ring, myPeerID)) { 88 SOSRingRemoveRejection(ring, myPeerID); 89 } else { 90 SOSCreateError(kSOSErrorPeerNotFound, CFSTR("Not associated with Ring"), NULL, error); 91 return false; 92 } 93 94 return true; 95 } 96 97 static bool SOSRingGenerationSign_V0(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) SOSRingGenerationSign_Internal(ring, user_privkey, error); 104 CFReleaseNull(priv); 105 return retval; 106 } 107 108 static bool SOSRingConcordanceSign_V0(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); 114 CFReleaseNull(priv); 115 return retval; 116 } 117 118 119 ringFuncStruct ringsV0 = { 120 "V0", 121 1, 122 SOSRingCreate_V0, 123 SOSRingResetToEmpty_V0, 124 SOSRingResetToOffering_V0, 125 SOSRingDeviceIsInRing_V0, 126 SOSRingApply_V0, 127 SOSRingWithdraw_V0, 128 SOSRingGenerationSign_V0, 129 SOSRingConcordanceSign_V0, 130 SOSRingUserKeyConcordanceTrust, 131 NULL, 132 NULL 133 };