1#include <SecureObjectSync/SOSAccountPriv.h> 2#include <SecureObjectSync/SOSTransport.h> 3#include <SecureObjectSync/SOSTransportKeyParameter.h> 4#include <SecureObjectSync/SOSTransportKeyParameterKVS.h> 5#include <SecureObjectSync/SOSKVSKeys.h> 6#include <SOSCloudKeychainClient.h> 7#include <utilities/SecCFWrappers.h> 8 9static bool SOSTransportKeyParameterKVSPublishCloudParameters(SOSTransportKeyParameterKVSRef transport, CFDataRef newParameters, CFErrorRef *error); 10static bool publishCloudParameters(SOSTransportKeyParameterRef transport, CFDataRef data, CFErrorRef* error); 11static bool SOSTransportKeyParameterKVSUpdateKVS(CFDictionaryRef changes, CFErrorRef *error); 12static void destroy(SOSTransportKeyParameterRef transport); 13 14struct __OpaqueSOSTransportKeyParameterKVS{ 15 struct __OpaqueSOSTransportKeyParameter k; 16}; 17 18static bool handleKeyParameterChanges(SOSTransportKeyParameterRef transport, CFDataRef data, CFErrorRef error){ 19 SOSAccountRef account = transport->account; 20 return SOSAccountHandleParametersChange(account, data, &error); 21 22} 23 24static bool setToNewAccount(SOSTransportKeyParameterRef transport){ 25 SOSAccountRef account = transport->account; 26 SOSAccountSetToNew(account); 27 return true; 28} 29 30SOSTransportKeyParameterKVSRef SOSTransportKeyParameterKVSCreate(SOSAccountRef account, CFErrorRef *error) { 31 SOSTransportKeyParameterKVSRef tkvs = (SOSTransportKeyParameterKVSRef) SOSTransportKeyParameterCreateForSubclass(sizeof(struct __OpaqueSOSTransportKeyParameterKVS) - sizeof(CFRuntimeBase), account, error); 32 if(tkvs){ 33 tkvs->k.publishCloudParameters = publishCloudParameters; 34 tkvs->k.handleKeyParameterChanges = handleKeyParameterChanges; 35 tkvs->k.setToNewAccount = setToNewAccount; 36 tkvs->k.destroy = destroy; 37 SOSRegisterTransportKeyParameter((SOSTransportKeyParameterRef)tkvs); 38 } 39 return tkvs; 40} 41 42static void destroy(SOSTransportKeyParameterRef transport){ 43 SOSUnregisterTransportKeyParameter(transport); 44} 45 46bool SOSTransportKeyParameterKVSHandleCloudParameterChange(SOSTransportKeyParameterRef transport, CFDataRef data, CFErrorRef* error){ 47 SOSTransportKeyParameterKVSRef tkvs = (SOSTransportKeyParameterKVSRef)transport; 48 SOSAccountRef account = tkvs->k.account; 49 50 return SOSAccountHandleParametersChange(account, data, error); 51} 52 53 54bool SOSTransportKeyParameterKVSAppendKeyInterests(SOSTransportKeyParameterKVSRef transport, CFMutableArrayRef alwaysKeys, CFMutableArrayRef afterFirstUnlockKeys, CFMutableArrayRef unlockedKeys, CFErrorRef*error){ 55 56 CFArrayAppendValue(alwaysKeys, kSOSKVSKeyParametersKey); 57 58 return true; 59} 60 61static bool publishCloudParameters(SOSTransportKeyParameterRef transport, CFDataRef data, CFErrorRef* error) 62{ 63 return SOSTransportKeyParameterKVSPublishCloudParameters((SOSTransportKeyParameterKVSRef)transport, data, error); 64} 65 66static bool SOSTransportKeyParameterKVSUpdateKVS(CFDictionaryRef changes, CFErrorRef *error){ 67 CloudKeychainReplyBlock log_error = ^(CFDictionaryRef returnedValues __unused, CFErrorRef error) { 68 if (error) { 69 secerror("Error putting: %@", error); 70 CFReleaseSafe(error); 71 } 72 }; 73 74 SOSCloudKeychainPutObjectsInCloud(changes, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), log_error); 75 return true; 76} 77 78static bool SOSTransportKeyParameterKVSPublishCloudParameters(SOSTransportKeyParameterKVSRef transport, CFDataRef newParameters, CFErrorRef *error) 79{ 80 CFDictionaryRef changes = CFDictionaryCreateForCFTypes(kCFAllocatorDefault, 81 kSOSKVSKeyParametersKey, newParameters, 82 NULL); 83 84 bool success = SOSTransportKeyParameterKVSUpdateKVS(changes, error); 85 86 CFReleaseNull(changes); 87 88 return success; 89} 90