/ keychain / SecureObjectSync / SOSRingBasic.m
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  };