/ keychain / SecureObjectSync / SOSTransportKeyParameter.m
SOSTransportKeyParameter.m
  1  
  2  #include "keychain/SecureObjectSync/SOSTransport.h"
  3  #include "keychain/SecureObjectSync/SOSTransportKeyParameter.h"
  4  #include "keychain/SecureObjectSync/SOSKVSKeys.h"
  5  #include "keychain/securityd/SOSCloudCircleServer.h"
  6  #include <utilities/SecCFWrappers.h>
  7  #include "keychain/SecureObjectSync/SOSAccountPriv.h"
  8  #include "keychain/SecureObjectSync/CKBridge/SOSCloudKeychainClient.h"
  9  
 10  @implementation CKKeyParameter
 11  
 12  @synthesize account = account;
 13  
 14  -(bool) SOSTransportKeyParameterHandleKeyParameterChanges:(CKKeyParameter*) transport  data:(CFDataRef) data err:(CFErrorRef) error
 15  {
 16      return SOSAccountHandleParametersChange(account, data, &error);
 17  }
 18  
 19  -(SOSAccount*) SOSTransportKeyParameterGetAccount:(CKKeyParameter*) transport
 20  {
 21      return account;
 22  }
 23  
 24  
 25  -(CFIndex) SOSTransportKeyParameterGetTransportType:(CKKeyParameter*) transport err:(CFErrorRef *)error
 26  {
 27      return kKVS;
 28  }
 29  
 30  
 31  -(void) SOSTransportKeyParameterHandleNewAccount:(CKKeyParameter*) transport acct:(SOSAccount*) acct
 32  {
 33      SOSAccountSetToNew(acct);
 34  }
 35  
 36  -(id) initWithAccount:(SOSAccount*) acct
 37  {
 38      if ((self = [super init])) {
 39          self.account = acct;
 40          SOSRegisterTransportKeyParameter(self);
 41      }
 42      return self;
 43  }
 44  
 45  -(bool) SOSTransportKeyParameterKVSAppendKeyInterests:(CKKeyParameter*)transport ak:(CFMutableArrayRef)alwaysKeys firstUnLock:(CFMutableArrayRef)afterFirstUnlockKeys unlocked:(CFMutableArrayRef) unlockedKeys err:(CFErrorRef *)error
 46  {
 47      CFArrayAppendValue(alwaysKeys, kSOSKVSKeyParametersKey);
 48  
 49      return true;
 50  }
 51  
 52  static bool SOSTransportKeyParameterKVSUpdateKVS(CFDictionaryRef changes, CFErrorRef *error){
 53      CloudKeychainReplyBlock log_error = ^(CFDictionaryRef returnedValues __unused, CFErrorRef block_error) {
 54          if (block_error) {
 55              secerror("Error putting: %@", block_error);
 56          }
 57      };
 58  
 59      SOSCloudKeychainPutObjectsInCloud(changes, dispatch_get_global_queue(SOS_TRANSPORT_PRIORITY, 0), log_error);
 60      return true;
 61  }
 62  
 63  -(bool) SOSTransportKeyParameterPublishCloudParameters:(CKKeyParameter*) transport data:(CFDataRef)newParameters err:(CFErrorRef*) error
 64  {
 65      if(newParameters) {
 66          secnotice("circleOps", "Publishing Cloud Parameters");
 67      } else {
 68          secnotice("circleOps", "Tried to publish nil Cloud Parameters");
 69          (void) SecRequirementError(newParameters != NULL, error, CFSTR("Tried to publish nil Cloud Parameters"));
 70          return false;
 71      }
 72  
 73      bool waitForeverForSynchronization = true;
 74      CFDictionaryRef changes = NULL;
 75      CFDataRef timeData = NULL;
 76      CFMutableStringRef timeDescription = CFStringCreateMutableCopy(kCFAllocatorDefault, 0, CFSTR("["));
 77      CFAbsoluteTime currentTimeAndDate = CFAbsoluteTimeGetCurrent();
 78  
 79      withStringOfAbsoluteTime(currentTimeAndDate, ^(CFStringRef decription) {
 80          CFStringAppend(timeDescription, decription);
 81      });
 82      CFStringAppend(timeDescription, CFSTR("]"));
 83  
 84      timeData = CFStringCreateExternalRepresentation(NULL,timeDescription,
 85                                                      kCFStringEncodingUTF8, '?');
 86  
 87      CFMutableDataRef timeAndKeyParametersMutable = CFDataCreateMutable(kCFAllocatorDefault, CFDataGetLength(timeData) + CFDataGetLength(newParameters));
 88      CFDataAppend(timeAndKeyParametersMutable, timeData);
 89      CFDataAppend(timeAndKeyParametersMutable, newParameters);
 90      CFDataRef timeAndKeyParameters = CFDataCreateCopy(kCFAllocatorDefault, timeAndKeyParametersMutable);
 91  
 92      CFStringRef ourPeerID = (__bridge CFStringRef)account.peerID;
 93  
 94      if(ourPeerID != NULL){
 95          CFStringRef keyParamKey = SOSLastKeyParametersPushedKeyCreateWithPeerID(ourPeerID);
 96  
 97          changes = CFDictionaryCreateForCFTypes(kCFAllocatorDefault,
 98                                                 kSOSKVSKeyParametersKey, newParameters,
 99                                                 keyParamKey, timeAndKeyParameters,
100                                                 NULL);
101          CFReleaseNull(keyParamKey);
102      }
103      else
104      {
105          CFStringRef keyParamKeyWithAccount = SOSLastKeyParametersPushedKeyCreateWithAccountGestalt(account);
106          changes = CFDictionaryCreateForCFTypes(kCFAllocatorDefault,
107                                                 kSOSKVSKeyParametersKey, newParameters,
108                                                 keyParamKeyWithAccount, timeAndKeyParameters,
109                                                 NULL);
110          CFReleaseNull(keyParamKeyWithAccount);
111      }
112      bool success = SOSTransportKeyParameterKVSUpdateKVS(changes, error);
113  
114      sync_the_last_data_to_kvs((__bridge CFTypeRef)(account), waitForeverForSynchronization);
115      CFReleaseNull(changes);
116      CFReleaseNull(timeData);
117      CFReleaseNull(timeAndKeyParameters);
118      CFReleaseNull(timeAndKeyParametersMutable);
119      CFReleaseNull(timeDescription);
120  
121      return success;
122  }
123  
124  @end
125