]> git.saurik.com Git - apple/security.git/blobdiff - OSX/sec/ProjectHeaders/Security/SecureObjectSync/SOSAccountCircles.c
Security-57336.1.9.tar.gz
[apple/security.git] / OSX / sec / ProjectHeaders / Security / SecureObjectSync / SOSAccountCircles.c
diff --git a/OSX/sec/ProjectHeaders/Security/SecureObjectSync/SOSAccountCircles.c b/OSX/sec/ProjectHeaders/Security/SecureObjectSync/SOSAccountCircles.c
new file mode 100644 (file)
index 0000000..de74758
--- /dev/null
@@ -0,0 +1,181 @@
+//
+//  SOSAccountCircles.c
+//  sec
+//
+
+#include "SOSAccountPriv.h"
+#include <Security/SecureObjectSync/SOSTransport.h>
+#include <Security/SecureObjectSync/SOSTransportKeyParameterKVS.h>
+#include <Security/SecureObjectSync/SOSTransportCircleKVS.h>
+#include <Security/SecureObjectSync/SOSTransportMessageKVS.h>
+#include <Security/SecureObjectSync/SOSTransportMessageIDS.h>
+#include "SOSCloudKeychainClient.h"
+
+
+//
+// MARK: Circle management
+//
+
+CFIndex whichTransportType;
+
+
+SecKeyRef SOSAccountCopyPublicKeyForPeer(SOSAccountRef account, CFStringRef peer_id, CFErrorRef *error) {
+    SecKeyRef publicKey = NULL;
+    SOSPeerInfoRef peer = NULL;
+
+    require_action_quiet(account->trusted_circle, fail, SOSErrorCreate(kSOSErrorNoCircle, error, NULL, CFSTR("No circle to get peer key from")));
+
+    peer = SOSCircleCopyPeerWithID(account->trusted_circle, peer_id, error);
+    require_quiet(peer, fail);
+
+    publicKey = SOSPeerInfoCopyPubKey(peer);
+
+fail:
+    CFReleaseSafe(peer);
+    return publicKey;
+}
+
+
+SOSCircleRef SOSAccountGetCircle(SOSAccountRef a, CFErrorRef *error)
+{
+    CFTypeRef entry = a->trusted_circle;
+
+    require_action_quiet(!isNull(entry), fail,
+                         SOSCreateError(kSOSErrorIncompatibleCircle, CFSTR("Incompatible circle in KVS"), NULL, error));
+    
+    require_action_quiet(entry, fail,
+                         SOSCreateError(kSOSErrorNoCircle, CFSTR("No circle found"), NULL, error));
+    
+    
+    return (SOSCircleRef) entry;
+    
+fail:
+    return NULL;
+}
+
+static void setup_defaults_settings(){
+
+    Boolean keyExistsAndHasValue = false;
+    
+    whichTransportType = CFPreferencesGetAppIntegerValue(CFSTR("Transport"), CFSTR("com.apple.security"), &keyExistsAndHasValue);
+    if(whichTransportType == kSOSTransportFuture)
+        secdebug("IDS", "Successfully retrieved value: %d, We are a Galarch + 1 device: %ld", keyExistsAndHasValue, whichTransportType);
+    else if (whichTransportType == kSOSTransportPresent)
+        secdebug("IDS", "Successfully retrieved value: %d, We are a Galarch device: %ld", keyExistsAndHasValue, whichTransportType);
+    
+    else if (whichTransportType == kSOSTransportIDS)
+        secdebug("IDS", "Successfully retrieved value: %d, We are an IDS device: %ld", keyExistsAndHasValue, whichTransportType);
+    
+    else if (whichTransportType == kSOSTransportKVS)
+        secdebug("IDS", "Successfully retrieved value: %d, We are a KVS device: %ld", keyExistsAndHasValue, whichTransportType);
+    else
+        secdebug("IDS", "Successfully retrieved value: %d, We are a KVS device: %ld", keyExistsAndHasValue, whichTransportType);
+
+}
+
+static void SOSTransportInit(void) {
+    static dispatch_once_t sdOnceToken;
+    dispatch_once(&sdOnceToken, ^{
+        setup_defaults_settings();
+    });
+}
+
+static bool SOSAccountInflateTransportsForCircle(SOSAccountRef account, CFStringRef circleName, CFErrorRef *error){
+    bool success = false;
+
+    SOSTransportKeyParameterRef tKey = NULL;
+    SOSTransportCircleRef tCircle = NULL;
+    SOSTransportMessageRef tidsMessage = NULL;
+    SOSTransportMessageRef tkvsMessage = NULL;
+    
+    SOSTransportInit();
+
+    tKey = (SOSTransportKeyParameterRef)SOSTransportKeyParameterKVSCreate(account, error);
+    tCircle = (SOSTransportCircleRef)SOSTransportCircleKVSCreate(account, circleName, error);
+
+    require_quiet(tKey, fail);
+    require_quiet(tCircle, fail);
+
+
+    if (whichTransportType == kSOSTransportIDS || whichTransportType == kSOSTransportFuture || whichTransportType == kSOSTransportPresent) {
+        tidsMessage = (SOSTransportMessageRef)SOSTransportMessageIDSCreate(account, circleName, error);
+        require_quiet(tidsMessage, fail);
+
+        CFRetainAssign(account->ids_message_transport, tidsMessage);
+        
+        secnotice("transport", "We are going to use an IDS transport");
+    }
+
+    tkvsMessage = (SOSTransportMessageRef)SOSTransportMessageKVSCreate(account, circleName, error);
+    require_quiet(tkvsMessage, fail);
+        
+    CFRetainAssign(account->kvs_message_transport, tkvsMessage);
+
+    CFRetainAssign(account->key_transport, (SOSTransportKeyParameterRef)tKey);
+    CFRetainAssign(account->circle_transport, tCircle);
+
+    
+    success = true;
+fail:
+    CFReleaseNull(tKey);
+    CFReleaseNull(tCircle);
+    CFReleaseNull(tidsMessage);
+    CFReleaseNull(tkvsMessage);
+    return success;
+}
+
+SOSCircleRef SOSAccountEnsureCircle(SOSAccountRef a, CFStringRef name, CFErrorRef *error)
+{
+    CFErrorRef localError = NULL;
+
+    if (a->trusted_circle == NULL) {
+        a->trusted_circle = SOSCircleCreate(NULL, name, NULL);
+        SOSUpdateKeyInterest();
+    }
+
+    
+    SOSCircleRef circle = SOSAccountGetCircle(a, &localError);
+    
+    require_action_quiet(circle || !isSOSErrorCoded(localError, kSOSErrorIncompatibleCircle), fail,
+                         if (error) { *error = localError; localError = NULL; });
+
+    require_quiet(SOSAccountInflateTransportsForCircle(a, name, error), fail);
+   
+fail:
+    CFReleaseNull(localError);
+    return circle;
+}
+
+
+bool SOSAccountUpdateCircleFromRemote(SOSAccountRef account, SOSCircleRef newCircle, CFErrorRef *error)
+{
+    return SOSAccountHandleUpdateCircle(account, newCircle, false, error);
+}
+
+bool SOSAccountUpdateCircle(SOSAccountRef account, SOSCircleRef newCircle, CFErrorRef *error)
+{
+    return SOSAccountHandleUpdateCircle(account, newCircle, true, error);
+}
+
+bool SOSAccountModifyCircle(SOSAccountRef account,
+                            CFErrorRef* error,
+                            bool (^action)(SOSCircleRef circle))
+{
+    bool success = false;
+    
+    SOSCircleRef circle = NULL;
+    require_action_quiet(account->trusted_circle, fail, SOSErrorCreate(kSOSErrorNoCircle, error, NULL, CFSTR("No circle to get peer key from")));
+
+    circle = SOSCircleCopyCircle(kCFAllocatorDefault, account->trusted_circle, error);
+    require_quiet(circle, fail);
+
+    success = true;
+    require_quiet(action(circle), fail);
+    
+    success = SOSAccountUpdateCircle(account, circle, error);
+    
+fail:
+    CFReleaseSafe(circle);
+    return success;
+}
+