]> git.saurik.com Git - apple/security.git/blobdiff - OSX/sec/SOSCircle/SecureObjectSync/SOSAccountBackup.m
Security-59306.11.20.tar.gz
[apple/security.git] / OSX / sec / SOSCircle / SecureObjectSync / SOSAccountBackup.m
diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountBackup.m b/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountBackup.m
deleted file mode 100644 (file)
index 4e861bc..0000000
+++ /dev/null
@@ -1,602 +0,0 @@
-//
-//  SOSAccountCircles.c
-//  sec
-//
-
-#include "SOSAccount.h"
-#include "SOSCloudKeychainClient.h"
-
-#include <Security/SecureObjectSync/SOSBackupSliceKeyBag.h>
-#include <Security/SecureObjectSync/SOSPeerInfoCollections.h>
-#include <Security/SecureObjectSync/SOSPeerInfoV2.h>
-#include <Security/SecureObjectSync/SOSViews.h>
-#include <Security/SecureObjectSync/SOSAccountTrustClassic+Circle.h>
-#include <Security/SecureObjectSync/SOSAccountTrustClassic+Expansion.h>
-
-#include "SOSInternal.h"
-
-
-
-//
-// MARK: V0 Keybag keychain stuff
-//
-static bool SecItemUpdateOrAdd(CFDictionaryRef query, CFDictionaryRef update, CFErrorRef *error)
-{
-    OSStatus saveStatus = SecItemUpdate(query, update);
-    
-    if (errSecItemNotFound == saveStatus) {
-        CFMutableDictionaryRef add = CFDictionaryCreateMutableCopy(kCFAllocatorDefault, 0, query);
-        CFDictionaryForEach(update, ^(const void *key, const void *value) {
-            CFDictionaryAddValue(add, key, value);
-        });
-        saveStatus = SecItemAdd(add, NULL);
-        CFReleaseNull(add);
-    }
-    
-    return SecError(saveStatus, error, CFSTR("Error saving %@"), query);
-}
-
-static CFDictionaryRef SOSCopyV0Attributes() {
-    return  CFDictionaryCreateForCFTypes(kCFAllocatorDefault,
-                                         kSecClass,           kSecClassGenericPassword,
-                                         kSecAttrAccessGroup, CFSTR("com.apple.sbd"),
-                                         kSecAttrAccessible,  kSecAttrAccessibleWhenUnlocked,
-                                         kSecAttrAccount,     CFSTR("SecureBackupPublicKeybag"),
-                                         kSecAttrService,     CFSTR("SecureBackupService"),
-                                         kSecAttrSynchronizable, kCFBooleanTrue,
-                                         NULL);
-}
-
-bool SOSDeleteV0Keybag(CFErrorRef *error) {
-    CFDictionaryRef attributes = SOSCopyV0Attributes();
-    
-    OSStatus result = SecItemDelete(attributes);
-    
-    CFReleaseNull(attributes);
-    
-    return SecError(result != errSecItemNotFound ? result : errSecSuccess, error, CFSTR("Deleting V0 Keybag failed - %d"), (int)result);
-}
-
-static bool SOSSaveV0Keybag(CFDataRef v0Keybag, CFErrorRef *error) {
-    CFDictionaryRef attributes = SOSCopyV0Attributes();
-    
-    CFDictionaryRef update = CFDictionaryCreateForCFTypes(kCFAllocatorDefault,
-                                                          kSecValueData,           v0Keybag,
-                                                          NULL);
-    
-    
-    bool result = SecItemUpdateOrAdd(attributes, update, error);
-    CFReleaseNull(attributes);
-    CFReleaseNull(update);
-    
-    return result;
-}
-
-
-static bool SOSPeerInfoIsViewBackupEnabled(SOSPeerInfoRef peerInfo, CFStringRef viewName) {
-    if (CFEqualSafe(kSOSViewKeychainV0, viewName))
-        return false;
-
-    return SOSPeerInfoHasBackupKey(peerInfo) && SOSPeerInfoIsViewPermitted(peerInfo, viewName);
-}
-
-static CFSetRef SOSAccountCopyBackupPeersForView(SOSAccount*  account, CFStringRef viewName) {
-    CFMutableSetRef backupPeers = CFSetCreateMutableForSOSPeerInfosByID(kCFAllocatorDefault);
-
-    SOSCircleRef circle = [account.trust getCircle:NULL];
-
-    require_quiet(circle, exit);
-
-    SOSCircleForEachValidPeer(circle, account.accountKey, ^(SOSPeerInfoRef peer) {
-        if (SOSPeerInfoIsViewBackupEnabled(peer, viewName))
-            CFSetAddValue(backupPeers, peer);
-    });
-
-exit:
-    return backupPeers;
-}
-
-static void SOSAccountWithBackupPeersForView(SOSAccount*  account, CFStringRef viewName, void (^action)(CFSetRef peers)) {
-    CFSetRef backupPeersForView = SOSAccountCopyBackupPeersForView(account, viewName);
-
-    action(backupPeersForView);
-
-    CFReleaseNull(backupPeersForView);
-}
-
-
-static bool SOSAccountWithBSKBForView(SOSAccount*  account, CFStringRef viewName, CFErrorRef *error,
-                                      bool (^action)(SOSBackupSliceKeyBagRef bskb, CFErrorRef *error)) {
-    __block SOSBackupSliceKeyBagRef bskb = NULL;
-    bool result = false;
-    CFDataRef rkbg = SOSAccountCopyRecoveryPublic(kCFAllocatorDefault, account, NULL);
-
-    SOSAccountWithBackupPeersForView(account, viewName, ^(CFSetRef peers) {
-        if(! rkbg) {
-            bskb = SOSBackupSliceKeyBagCreate(kCFAllocatorDefault, peers, error);
-        } else {
-            CFMutableDictionaryRef additionalKeys = CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault);
-            CFDictionaryAddValue(additionalKeys, bskbRkbgPrefix, rkbg);
-            bskb = SOSBackupSliceKeyBagCreateWithAdditionalKeys(kCFAllocatorDefault, peers, additionalKeys, error);
-            CFReleaseNull(additionalKeys);
-        }
-    });
-    CFReleaseNull(rkbg);
-
-    require_quiet(bskb, exit);
-
-    action(bskb, error);
-
-    result = true;
-
-exit:
-    CFReleaseNull(bskb);
-    return result;
-}
-
-CFStringRef SOSBackupCopyRingNameForView(CFStringRef viewName) {
-    return CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%@-tomb"), viewName);
-}
-
-static bool SOSAccountUpdateBackupRing(SOSAccount*  account, CFStringRef viewName, CFErrorRef *error,
-                                       SOSRingRef (^modify)(SOSRingRef existing, CFErrorRef *error)) {
-
-    CFStringRef ringName = SOSBackupCopyRingNameForView(viewName);
-
-    bool result = SOSAccountUpdateNamedRing(account, ringName, error, ^SOSRingRef(CFStringRef ringName, CFErrorRef *error) {
-        return SOSRingCreate(ringName, (__bridge CFStringRef) account.peerID, kSOSRingBackup, error);
-    }, modify);
-
-    CFReleaseNull(ringName);
-
-    return result;
-}
-
-
-
-static bool SOSAccountSetKeybagForViewBackupRing(SOSAccount*  account, CFStringRef viewName, SOSBackupSliceKeyBagRef keyBag, CFErrorRef *error) {
-    CFMutableSetRef backupViewSet = CFSetCreateMutableForCFTypes(NULL);
-    bool result = false;
-
-    if(!SecAllocationError(backupViewSet, error, CFSTR("No backup view set created"))){
-        secnotice("backupring", "Got error setting keybag for backup view '%@': %@", viewName, error ? (CFTypeRef) *error : (CFTypeRef) CFSTR("No error space."));
-        
-        return result;
-    }
-    CFSetAddValue(backupViewSet, viewName);
-
-    result = SOSAccountUpdateBackupRing(account, viewName, error, ^SOSRingRef(SOSRingRef existing, CFErrorRef *error) {
-        SOSRingRef newRing = NULL;
-        CFSetRef viewPeerSet = [account.trust copyPeerSetForView:viewName];
-        CFMutableSetRef cleared = CFSetCreateMutableForCFTypes(NULL);
-
-        SOSRingSetPeerIDs(existing, cleared);
-        SOSRingAddAll(existing, viewPeerSet);
-
-        require_quiet(SOSRingSetBackupKeyBag(existing, account.fullPeerInfo, backupViewSet, keyBag, error), exit);
-
-        newRing = CFRetainSafe(existing);
-    exit:
-        CFReleaseNull(viewPeerSet);
-        CFReleaseNull(cleared);
-        return newRing;
-    });
-
-    if (result && NULL != error && NULL != *error) {
-        secerror("Got Success and Error (dropping error): %@", *error);
-        CFReleaseNull(*error);
-    }
-    
-    if (!result) {
-        secnotice("backupring", "Got error setting keybag for backup view '%@': %@", viewName, error ? (CFTypeRef) *error : (CFTypeRef) CFSTR("No error space."));
-    }
-
-    CFReleaseNull(backupViewSet);
-    return result;
-}
-
-bool SOSAccountNewBKSBForView(SOSAccount* account, CFStringRef viewName, CFErrorRef *error)
-{
-    return SOSAccountWithBSKBForView(account, viewName, error, ^(SOSBackupSliceKeyBagRef bskb, CFErrorRef *error) {
-        bool result = SOSAccountSetKeybagForViewBackupRing(account, viewName, bskb, error);
-        return result;
-    });
-}
-
-bool SOSAccountIsBackupRingEmpty(SOSAccount*  account, CFStringRef viewName) {
-    CFStringRef backupRing = SOSBackupCopyRingNameForView(viewName);
-    SOSRingRef ring = [account.trust copyRing:backupRing err:NULL];
-    CFReleaseNull(backupRing);
-    int peercnt = 0;
-    if(ring) peercnt = SOSRingCountPeers(ring);
-    CFReleaseNull(ring);
-    return peercnt == 0;
-}
-
-bool SOSAccountIsMyPeerInBackupAndCurrentInView(SOSAccount*  account, CFStringRef viewname){
-    bool result = false;
-    CFErrorRef bsError = NULL;
-    CFDataRef backupSliceData = NULL;
-    SOSRingRef ring = NULL;
-    SOSBackupSliceKeyBagRef backupSlice = NULL;
-    
-    require_quiet(SOSPeerInfoIsViewBackupEnabled(account.peerInfo, viewname), errOut);
-    
-    CFStringRef ringName = SOSBackupCopyRingNameForView(viewname);
-    ring = [account.trust copyRing:ringName err:&bsError];
-    CFReleaseNull(ringName);
-    
-    require_quiet(ring, errOut);
-    
-    //grab the backup slice from the ring
-    backupSliceData = SOSRingGetPayload(ring, &bsError);
-    require_quiet(backupSliceData, errOut);
-
-    backupSlice = SOSBackupSliceKeyBagCreateFromData(kCFAllocatorDefault, backupSliceData, &bsError);
-    require_quiet(backupSlice, errOut);
-    
-    CFSetRef peers = SOSBSKBGetPeers(backupSlice);
-    SOSPeerInfoRef myPeer = account.peerInfo;
-    
-    SOSPeerInfoRef myPeerInBSKB = (SOSPeerInfoRef) CFSetGetValue(peers, myPeer);
-    require_quiet(isSOSPeerInfo(myPeerInBSKB), errOut);
-    
-    CFDataRef myBK = SOSPeerInfoCopyBackupKey(myPeer);
-    CFDataRef myPeerInBSKBBK = SOSPeerInfoCopyBackupKey(myPeerInBSKB);
-    result = CFEqualSafe(myBK, myPeerInBSKBBK);
-    CFReleaseNull(myBK);
-    CFReleaseNull(myPeerInBSKBBK);
-    
-errOut:
-    CFReleaseNull(ring);
-    CFReleaseNull(backupSlice);
-
-    if (bsError) {
-        secnotice("backup", "Failed to find BKSB: %@, %@ (%@)", backupSliceData, backupSlice, bsError);
-    }
-    CFReleaseNull(bsError);
-    return result;
-}
-
-bool SOSAccountIsPeerInBackupAndCurrentInView(SOSAccount*  account, SOSPeerInfoRef testPeer, CFStringRef viewname){
-    bool result = false;
-    CFErrorRef bsError = NULL;
-    CFDataRef backupSliceData = NULL;
-    SOSRingRef ring = NULL;
-    SOSBackupSliceKeyBagRef backupSlice = NULL;
-
-    require_quiet(testPeer, errOut);
-
-    CFStringRef ringName = SOSBackupCopyRingNameForView(viewname);
-    
-    ring = [account.trust copyRing:ringName err:&bsError];
-    CFReleaseNull(ringName);
-    
-    require_quiet(ring, errOut);
-    
-    //grab the backup slice from the ring
-    backupSliceData = SOSRingGetPayload(ring, &bsError);
-    require_quiet(backupSliceData, errOut);
-
-    backupSlice = SOSBackupSliceKeyBagCreateFromData(kCFAllocatorDefault, backupSliceData, &bsError);
-    require_quiet(backupSlice, errOut);
-    
-    CFSetRef peers = SOSBSKBGetPeers(backupSlice);
-    
-    SOSPeerInfoRef peerInBSKB = (SOSPeerInfoRef) CFSetGetValue(peers, testPeer);
-    require_quiet(isSOSPeerInfo(peerInBSKB), errOut);
-
-    result = CFEqualSafe(testPeer, peerInBSKB);
-    
-errOut:
-    CFReleaseNull(ring);
-    CFReleaseNull(backupSlice);
-
-    if (bsError) {
-        secnotice("backup", "Failed to find BKSB: %@, %@ (%@)", backupSliceData, backupSlice, bsError);
-    }
-    CFReleaseNull(bsError);
-    return result;
-
-}
-
-bool SOSAccountUpdateOurPeerInBackup(SOSAccount*  account, SOSRingRef oldRing, CFErrorRef *error){
-    bool result = false;
-    CFSetRef viewNames = SOSBackupRingGetViews(oldRing, error);
-    __block CFStringRef viewName = NULL;
-    require_quiet(viewNames, fail);
-    require_quiet(SecRequirementError(1 == CFSetGetCount(viewNames), error, CFSTR("Only support single view backup rings")), fail);
-
-    CFSetForEach(viewNames, ^(const void *value) {
-        if (isString(value)) {
-            viewName = CFRetainSafe((CFStringRef) value);
-        }
-    });
-
-    result = SOSAccountNewBKSBForView(account, viewName, error);
-
-fail:
-    CFReleaseNull(viewName);
-    return result;
-}
-
-void SOSAccountForEachBackupRingName(SOSAccount*  account, void (^operation)(CFStringRef value)) {
-    SOSPeerInfoRef myPeer = account.peerInfo;
-    if (myPeer) {
-        CFSetRef allViews = SOSViewCopyViewSet(kViewSetAll); // All non virtual views.
-
-        CFSetForEach(allViews, ^(const void *value) {
-            CFStringRef viewName = asString(value, NULL);
-
-            if (viewName) {
-                CFStringRef ringName = SOSBackupCopyRingNameForView(viewName);
-                operation(ringName);
-                CFReleaseNull(ringName);
-            }
-        });
-        CFReleaseNull(allViews);
-        // Only one "ring" now (other than backup rings) when there's more this will need to be modified.
-        operation(kSOSRecoveryRing);
-    }
-}
-
-
-void SOSAccountForEachRingName(SOSAccount* account, void (^operation)(CFStringRef value)) {
-    SOSPeerInfoRef myPeer = account.peerInfo;
-    if (myPeer) {
-        CFSetRef allViews = SOSViewCopyViewSet(kViewSetAll); // All non virtual views.
-
-        CFSetForEach(allViews, ^(const void *value) {
-            CFStringRef viewName = asString(value, NULL);
-
-            if (viewName) {
-                CFStringRef ringName = SOSBackupCopyRingNameForView(viewName);
-                operation(ringName);
-                CFReleaseNull(ringName);
-            }
-        });
-        CFReleaseNull(allViews);
-        // Only one "ring" now (other than backup rings) when there's more this will need to be modified.
-        operation(kSOSRecoveryRing);
-    }
-}
-
-void SOSAccountForEachBackupView(SOSAccount*  account,  void (^operation)(const void *value)) {
-    SOSPeerInfoRef myPeer = account.peerInfo;
-    
-    if (myPeer) {
-        CFMutableSetRef myBackupViews = CFSetCreateMutableCopy(kCFAllocatorDefault, 0, SOSPeerInfoGetPermittedViews(myPeer));
-        CFSetRemoveValue(myBackupViews, kSOSViewKeychainV0);
-        CFSetForEach(myBackupViews, operation);
-        CFReleaseNull(myBackupViews);
-    }
-}
-
-
-bool SOSAccountSetBackupPublicKey(SOSAccountTransaction* aTxn, CFDataRef cfBackupKey, CFErrorRef *error)
-{
-    SOSAccount*  account = aTxn.account;
-    NSData* backupKey = [[NSData alloc]initWithData:(__bridge NSData * _Nonnull)(cfBackupKey)];
-    __block bool result = false;
-
-    if(![account isInCircle:error]) {
-        return result;
-    }
-
-    CFDataPerformWithHexString((__bridge CFDataRef)(backupKey), ^(CFStringRef backupKeyString) {
-        CFDataPerformWithHexString((__bridge CFDataRef)((account.backup_key)), ^(CFStringRef oldBackupKey) {
-            secnotice("backup", "SetBackupPublic: %@ from %@", backupKeyString, oldBackupKey);
-        });
-    });
-
-    if ([backupKey isEqual:account.backup_key])
-        return true;
-
-    account.backup_key = [[NSData alloc] initWithData:backupKey];
-
-    account.circle_rings_retirements_need_attention = true;
-
-    result = true;
-    
-    if (!result) {
-        secnotice("backupkey", "SetBackupPublic Failed: %@", error ? (CFTypeRef) *error : (CFTypeRef) CFSTR("No error space"));
-    }
-    return result;
-}
-
-static bool SOSAccountWithBSKBAndPeerInfosForView(SOSAccount*  account, CFArrayRef retiree, CFStringRef viewName, CFErrorRef *error,
-                                                  bool (^action)(SOSBackupSliceKeyBagRef bskb, CFErrorRef *error)) {
-    __block SOSBackupSliceKeyBagRef bskb = NULL;
-    bool result = false;
-    
-    SOSAccountWithBackupPeersForView(account, viewName, ^(CFSetRef peers) {
-        CFMutableSetRef newPeerList = CFSetCreateMutableCopy(kCFAllocatorDefault, CFSetGetCount(peers), peers);
-        CFArrayForEach(retiree, ^(const void *value) {
-            if (!isSOSPeerInfo(value)) {
-                secerror("Peer list contains a non-peerInfo element");
-            } else {
-                SOSPeerInfoRef retiringPeer = (SOSPeerInfoRef)value;
-                CFStringRef retiringPeerID = SOSPeerInfoGetPeerID(retiringPeer);
-
-                CFSetForEach(newPeerList, ^(const void *peerFromAccount) {
-                    CFStringRef peerFromAccountID = SOSPeerInfoGetPeerID((SOSPeerInfoRef)peerFromAccount);
-                    if (peerFromAccountID && retiringPeerID && CFStringCompare(peerFromAccountID, retiringPeerID, 0) == 0){
-                        CFSetRemoveValue(newPeerList, peerFromAccount);
-                    }
-                });
-            }
-        });
-        bskb = SOSBackupSliceKeyBagCreate(kCFAllocatorDefault, newPeerList, error);
-        CFReleaseNull(newPeerList);
-    });
-    
-    require_quiet(bskb, exit);
-    
-    action(bskb, error);
-    
-    result = true;
-    
-exit:
-    CFReleaseNull(bskb);
-    return result;
-}
-
-bool SOSAccountRemoveBackupPublickey(SOSAccountTransaction* aTxn, CFErrorRef *error)
-{
-    SOSAccount*  account = aTxn.account;
-
-    __block bool result = false;
-    __block CFArrayRef removals = NULL;
-
-    account.backup_key = nil;
-
-    if(!SOSAccountUpdatePeerInfo(account, CFSTR("Backup public key"), error,
-                                 ^bool(SOSFullPeerInfoRef fpi, CFErrorRef *error) {
-                                     return SOSFullPeerInfoUpdateBackupKey(fpi, NULL, error);
-                                 })){
-                                     return result;
-                                 }
-    
-    removals = CFArrayCreateForCFTypes(kCFAllocatorDefault,
-                                       account.peerInfo, NULL);
-
-    SOSAccountForEachBackupView(account, ^(const void *value) {
-        CFStringRef viewName = (CFStringRef)value;
-        result = SOSAccountWithBSKBAndPeerInfosForView(account, removals, viewName, error, ^(SOSBackupSliceKeyBagRef bskb, CFErrorRef *error) {
-            bool result = SOSAccountSetKeybagForViewBackupRing(account, viewName, bskb, error);
-            return result;
-        });
-    });
-   
-
-    result = true;
-
-    return result;
-    
-}
-
-bool SOSAccountSetBSKBagForAllSlices(SOSAccount*  account, CFDataRef aks_bag, bool setupV0Only, CFErrorRef *error){
-    __block bool result = false;
-    SOSBackupSliceKeyBagRef backup_slice = NULL;
-    
-    if(![account isInCircle:error]) {
-        return result;
-    }
-
-    if (setupV0Only) {
-        result = SOSSaveV0Keybag(aks_bag, error);
-        require_action_quiet(result, exit, secnotice("keybag", "failed to set V0 keybag (%@)", *error));
-    } else {
-        result = true;
-
-        backup_slice = SOSBackupSliceKeyBagCreateDirect(kCFAllocatorDefault, aks_bag, error);
-
-        SOSAccountForEachBackupView(account, ^(const void *value) {
-            CFStringRef viewname = (CFStringRef) value;
-            result &= SOSAccountSetKeybagForViewBackupRing(account, viewname, backup_slice, error);
-        });
-    }
-
-exit:
-    CFReleaseNull(backup_slice);
-    return result;
-}
-
-static CF_RETURNS_RETAINED CFMutableArrayRef SOSAccountIsRetiredPeerIDInBackupPeerList(SOSAccount*  account, CFArrayRef peers, CFSetRef peersInBackup){
-    CFMutableArrayRef removals = CFArrayCreateMutableForCFTypes(kCFAllocatorDefault);
-    
-    CFSetForEach(peersInBackup, ^(const void *value) {
-        SOSPeerInfoRef peer = (SOSPeerInfoRef)value;
-        CFArrayForEach(peers, ^(const void *value) {
-            CFStringRef peerID = SOSPeerInfoGetPeerID((SOSPeerInfoRef)value);
-            CFStringRef piPeerID = SOSPeerInfoGetPeerID(peer);
-            if (peerID && piPeerID && CFStringCompare(piPeerID, peerID, 0) == 0){
-                CFArrayAppendValue(removals, peer);
-            }
-        });
-        
-    });
-    
-    return removals;
-
-}
-
-bool SOSAccountRemoveBackupPeers(SOSAccount*  account, CFArrayRef peers, CFErrorRef *error){
-    __block bool result = true;
-
-    SOSFullPeerInfoRef fpi = account.fullPeerInfo;
-    SOSPeerInfoRef myPeer = SOSFullPeerInfoGetPeerInfo(fpi);
-    
-    CFSetRef permittedViews = SOSPeerInfoGetPermittedViews(myPeer);
-    CFSetForEach(permittedViews, ^(const void *value) {
-        CFStringRef viewName = (CFStringRef)value;
-        if(SOSPeerInfoIsViewBackupEnabled(myPeer, viewName)){
-            //grab current peers list
-            CFSetRef peersInBackup = SOSAccountCopyBackupPeersForView(account, viewName);
-            //get peer infos that have retired but are still in the backup peer list
-            CFMutableArrayRef removals = SOSAccountIsRetiredPeerIDInBackupPeerList(account, peers, peersInBackup);
-            result = SOSAccountWithBSKBAndPeerInfosForView(account, removals, viewName, error, ^(SOSBackupSliceKeyBagRef bskb, CFErrorRef *error) {
-                bool result = SOSAccountSetKeybagForViewBackupRing(account, viewName, bskb, error);
-                return result;
-            });
-            CFReleaseNull(removals);
-            CFReleaseNull(peersInBackup);
-        }
-    });
-    
-    return result;
-    
-}
-
-SOSBackupSliceKeyBagRef SOSAccountBackupSliceKeyBagForView(SOSAccount*  account, CFStringRef viewName, CFErrorRef* error){
-    CFDataRef backupSliceData = NULL;
-    CFStringRef ringName = NULL;
-    SOSRingRef ring = NULL;
-    SOSBackupSliceKeyBagRef bskb = NULL;
-
-    ringName = SOSBackupCopyRingNameForView(viewName);
-    ring = [account.trust copyRing:ringName err:NULL];
-    require_action_quiet(ring, exit, SOSCreateErrorWithFormat(kSOSErrorNoCircle, NULL, error, NULL, CFSTR("failed to get ring")));
-
-    //grab the backup slice from the ring
-    backupSliceData = SOSRingGetPayload(ring, error);
-    require_action_quiet(backupSliceData, exit, secnotice("backup", "failed to get backup slice (%@)", *error));
-
-    bskb = SOSBackupSliceKeyBagCreateFromData(kCFAllocatorDefault, backupSliceData, error);
-
-exit:
-    CFReleaseNull(ring);
-    CFReleaseNull(ringName);
-
-    return bskb;
-}
-
-bool SOSAccountIsLastBackupPeer(SOSAccount*  account, CFErrorRef *error) {
-    __block bool retval = false;
-    SOSPeerInfoRef pi = account.peerInfo;
-
-    if(![account isInCircle:error]) {
-        return retval;
-    }
-
-    if(!SOSPeerInfoHasBackupKey(pi))
-        return retval;
-
-    SOSCircleRef circle = [account.trust getCircle:error];
-
-    if(SOSCircleCountValidSyncingPeers(circle, SOSAccountGetTrustedPublicCredential(account, error)) == 1){
-        retval = true;
-        return retval;
-    }
-    // We're in a circle with more than 1 ActiveValidPeers - are they in the backups?
-    SOSAccountForEachBackupView(account, ^(const void *value) {
-        CFStringRef viewname = (CFStringRef) value;
-        SOSBackupSliceKeyBagRef keybag = SOSAccountBackupSliceKeyBagForView(account, viewname, error);
-        require_quiet(keybag, inner_errOut);
-        retval |= ((SOSBSKBCountPeers(keybag) == 1) && (SOSBSKBPeerIsInKeyBag(keybag, pi)));
-    inner_errOut:
-        CFReleaseNull(keybag);
-    });
-
-    return retval;
-}