]> git.saurik.com Git - apple/security.git/blobdiff - Security/sec/SOSCircle/SecureObjectSync/SOSAccountPersistence.c
Security-57336.1.9.tar.gz
[apple/security.git] / Security / sec / SOSCircle / SecureObjectSync / SOSAccountPersistence.c
diff --git a/Security/sec/SOSCircle/SecureObjectSync/SOSAccountPersistence.c b/Security/sec/SOSCircle/SecureObjectSync/SOSAccountPersistence.c
deleted file mode 100644 (file)
index ebaed87..0000000
+++ /dev/null
@@ -1,710 +0,0 @@
-/*
- * Copyright (c) 2013-2014 Apple Inc. All Rights Reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- * 
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- * 
- * @APPLE_LICENSE_HEADER_END@
- */
-
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <assert.h>
-#include <AssertMacros.h>
-#include "SOSAccountPriv.h"
-
-#include <utilities/SecCFWrappers.h>
-#include <SecureObjectSync/SOSKVSKeys.h>
-
-SOSAccountRef SOSAccountCreateFromDER_V1(CFAllocatorRef allocator,
-                                         SOSDataSourceFactoryRef factory,
-                                         CFErrorRef* error,
-                                         const uint8_t** der_p, const uint8_t *der_end)
-{
-    SOSAccountRef account = NULL;
-    
-    const uint8_t *sequence_end;
-    *der_p = ccder_decode_constructed_tl(CCDER_CONSTRUCTED_SEQUENCE, &sequence_end, *der_p, der_end);
-    
-    {
-        CFDictionaryRef decoded_gestalt = NULL;
-        *der_p = der_decode_dictionary(kCFAllocatorDefault, kCFPropertyListImmutable, &decoded_gestalt, error,
-                                       *der_p, der_end);
-        
-        if (*der_p == 0)
-            return NULL;
-        
-        account = SOSAccountCreateBasic(allocator, decoded_gestalt, factory);
-        CFReleaseNull(decoded_gestalt);
-    }
-    
-    CFArrayRef array = NULL;
-    *der_p = der_decode_array(kCFAllocatorDefault, 0, &array, error, *der_p, sequence_end);
-    
-    *der_p = ccder_decode_bool(&account->user_public_trusted, *der_p, sequence_end);
-    *der_p = der_decode_public_bytes(kCFAllocatorDefault, kSecECDSAAlgorithmID, &account->user_public, error, *der_p, sequence_end);
-    *der_p = der_decode_data_or_null(kCFAllocatorDefault, &account->user_key_parameters, error, *der_p, sequence_end);
-    *der_p = der_decode_dictionary(kCFAllocatorDefault, kCFPropertyListMutableContainers, (CFDictionaryRef *) &account->retired_peers, error, *der_p, sequence_end);
-    if (*der_p != sequence_end)
-        *der_p = NULL;
-    
-    __block bool success = true;
-    
-    require_quiet(array && *der_p, fail);
-    
-    CFArrayForEach(array, ^(const void *value) {
-        if (success) {
-            if (isString(value)) {
-                CFDictionaryAddValue(account->circles, value, kCFNull);
-            } else {
-                CFDataRef circleData = NULL;
-                CFDataRef fullPeerInfoData = NULL;
-                
-                if (isData(value)) {
-                    circleData = (CFDataRef) value;
-                } else if (isArray(value)) {
-                    CFArrayRef pair = (CFArrayRef) value;
-                    
-                    CFTypeRef circleObject = CFArrayGetValueAtIndex(pair, 0);
-                    CFTypeRef fullPeerInfoObject = CFArrayGetValueAtIndex(pair, 1);
-                    
-                    if (CFArrayGetCount(pair) == 2 && isData(circleObject) && isData(fullPeerInfoObject)) {
-                        circleData = (CFDataRef) circleObject;
-                        fullPeerInfoData = (CFDataRef) fullPeerInfoObject;
-                    }
-                }
-                
-                if (circleData) {
-                    SOSCircleRef circle = SOSCircleCreateFromData(kCFAllocatorDefault, circleData, error);
-                    require_action_quiet(circle, fail, success = false);
-                    
-                    CFStringRef circleName = SOSCircleGetName(circle);
-                    CFDictionaryAddValue(account->circles, circleName, circle);
-                    
-                    if (fullPeerInfoData) {
-                        SOSFullPeerInfoRef full_peer = SOSFullPeerInfoCreateFromData(kCFAllocatorDefault, fullPeerInfoData, error);
-                        require_action_quiet(full_peer, fail, success = false);
-                        
-                        CFDictionaryAddValue(account->circle_identities, circleName, full_peer);
-                        CFReleaseNull(full_peer);
-                    }
-                fail:
-                    CFReleaseNull(circle);
-                }
-            }
-        }
-    });
-    CFReleaseNull(array);
-    
-    require_quiet(success, fail);
-    require_action_quiet(SOSAccountEnsureFactoryCircles(account), fail,
-                         SOSCreateError(kSOSErrorBadFormat, CFSTR("Cannot EnsureFactoryCircles"), (error != NULL) ? *error : NULL, error));
-    
-    return account;
-    
-fail:
-    // Create a default error if we don't have one:
-    SOSCreateError(kSOSErrorBadFormat, CFSTR("Bad Account DER"), NULL, error);
-    CFReleaseNull(account);
-    return NULL;
-}
-
-SOSAccountRef SOSAccountCreateFromDER_V2(CFAllocatorRef allocator,
-                                         SOSDataSourceFactoryRef factory,
-                                        CFErrorRef* error,
-                                         const uint8_t** der_p, const uint8_t *der_end)
-{
-    SOSAccountRef account = NULL;
-    const uint8_t *dersave = *der_p;
-    const uint8_t *derend = der_end;
-    
-    const uint8_t *sequence_end;
-    *der_p = ccder_decode_constructed_tl(CCDER_CONSTRUCTED_SEQUENCE, &sequence_end, *der_p, der_end);
-    
-    {
-        CFDictionaryRef decoded_gestalt = NULL;
-        *der_p = der_decode_dictionary(kCFAllocatorDefault, kCFPropertyListImmutable, &decoded_gestalt, error,
-                                       *der_p, der_end);
-        
-        if (*der_p == 0)
-            return NULL;
-        
-        account = SOSAccountCreateBasic(allocator, decoded_gestalt, factory);
-        CFReleaseNull(decoded_gestalt);
-    }
-    
-    CFArrayRef array = NULL;
-    *der_p = der_decode_array(kCFAllocatorDefault, 0, &array, error, *der_p, sequence_end);
-    
-    uint64_t tmp_departure_code = kSOSNeverAppliedToCircle;
-    *der_p = ccder_decode_uint64(&tmp_departure_code, *der_p, sequence_end);
-    *der_p = ccder_decode_bool(&account->user_public_trusted, *der_p, sequence_end);
-    *der_p = der_decode_public_bytes(kCFAllocatorDefault, kSecECDSAAlgorithmID, &account->user_public, error, *der_p, sequence_end);
-    *der_p = der_decode_data_or_null(kCFAllocatorDefault, &account->user_key_parameters, error, *der_p, sequence_end);
-    *der_p = der_decode_dictionary(kCFAllocatorDefault, kCFPropertyListMutableContainers, (CFDictionaryRef *) &account->retired_peers, error, *der_p, sequence_end);
-    if (*der_p != sequence_end)
-        *der_p = NULL;
-    account->departure_code = (enum DepartureReason) tmp_departure_code;
-    
-    __block bool success = true;
-    
-    require_quiet(array && *der_p, fail);
-    
-    CFArrayForEach(array, ^(const void *value) {
-        if (success) {
-            if (isString(value)) {
-                CFDictionaryAddValue(account->circles, value, kCFNull);
-            } else {
-                CFDataRef circleData = NULL;
-                CFDataRef fullPeerInfoData = NULL;
-                
-                if (isData(value)) {
-                    circleData = (CFDataRef) value;
-                } else if (isArray(value)) {
-                    CFArrayRef pair = (CFArrayRef) value;
-                    
-                    CFTypeRef circleObject = CFArrayGetValueAtIndex(pair, 0);
-                    CFTypeRef fullPeerInfoObject = CFArrayGetValueAtIndex(pair, 1);
-                    
-                    if (CFArrayGetCount(pair) == 2 && isData(circleObject) && isData(fullPeerInfoObject)) {
-                        circleData = (CFDataRef) circleObject;
-                        fullPeerInfoData = (CFDataRef) fullPeerInfoObject;
-                    }
-                }
-                
-                if (circleData) {
-                    SOSCircleRef circle = SOSCircleCreateFromData(kCFAllocatorDefault, circleData, error);
-                    require_action_quiet(circle, fail, success = false);
-                    
-                    CFStringRef circleName = SOSCircleGetName(circle);
-                    CFDictionaryAddValue(account->circles, circleName, circle);
-                    
-                    if (fullPeerInfoData) {
-                        SOSFullPeerInfoRef full_peer = SOSFullPeerInfoCreateFromData(kCFAllocatorDefault, fullPeerInfoData, error);
-                        require_action_quiet(full_peer, fail, success = false);
-                        
-                        CFDictionaryAddValue(account->circle_identities, circleName, full_peer);
-                        CFReleaseSafe(full_peer);
-                    }
-                fail:
-                    CFReleaseNull(circle);
-                }
-            }
-        }
-    });
-    CFReleaseNull(array);
-    
-    require_quiet(success, fail);
-    require_action_quiet(SOSAccountEnsureFactoryCircles(account), fail,
-                         SOSCreateError(kSOSErrorBadFormat, CFSTR("Cannot EnsureFactoryCircles"), (error != NULL) ? *error : NULL, error));
-    
-    return account;
-    
-fail:
-    // Create a default error if we don't have one:
-    account->factory = NULL; // give the factory back.
-    CFReleaseNull(account);
-    // Try the der inflater from the previous release.
-    account = SOSAccountCreateFromDER_V1(allocator, factory, error, &dersave, derend);
-    if(account) account->departure_code = kSOSNeverAppliedToCircle;
-    return account;
-}
-
-static void SOSAccountConvertKVSDictionaryToRetirementDictionary(SOSAccountRef account)
-{
-    CFMutableDictionaryRef old_retired_peers = account->retired_peers;
-    account->retired_peers = CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault);
-
-    CFDictionaryForEach(old_retired_peers, ^(const void *key, const void *value) {
-        if (isDictionary(value)) {
-            CFDictionaryAddValue(account->retired_peers, key, value);
-        } else if (isString(key) && isData(value)) {
-            CFDataRef retired_peer_data = (CFDataRef) value;
-            CFStringRef circle_name = NULL;
-            CFStringRef retired_peer_id = NULL;
-
-            if (kRetirementKey == SOSKVSKeyGetKeyTypeAndParse(key, &circle_name, &retired_peer_id, NULL)) {
-                CFMutableDictionaryRef circle_retirees = CFDictionaryEnsureCFDictionaryAndGetCurrentValue(account->retired_peers, circle_name);
-
-                CFDictionarySetValue(circle_retirees, retired_peer_id, retired_peer_data);
-            }
-
-            CFReleaseSafe(circle_name);
-            CFReleaseSafe(retired_peer_id);
-        }
-    });
-    CFReleaseSafe(old_retired_peers);
-}
-
-
-#define CURRENT_ACCOUNT_PERSISTENT_VERSION 6
-
-SOSAccountRef SOSAccountCreateFromDER(CFAllocatorRef allocator,
-                                      SOSDataSourceFactoryRef factory,
-                                      CFErrorRef* error,
-                                      const uint8_t** der_p, const uint8_t *der_end)
-{
-    SOSAccountRef account = NULL;
-#if UPGRADE_FROM_PREVIOUS_VERSION
-    const uint8_t *dersave = *der_p;
-    const uint8_t *derend = der_end;
-#endif
-    uint64_t version = 0;
-    
-    const uint8_t *sequence_end;
-    *der_p = ccder_decode_constructed_tl(CCDER_CONSTRUCTED_SEQUENCE, &sequence_end, *der_p, der_end);
-    *der_p = ccder_decode_uint64(&version, *der_p, sequence_end);
-    if(!(*der_p) || version < CURRENT_ACCOUNT_PERSISTENT_VERSION) {
-#if UPGRADE_FROM_PREVIOUS_VERSION
-        return SOSAccountCreateFromDER_V3(allocator, factory, error, &dersave, derend);
-#else
-        return NULL;
-#endif
-    }
-    
-    {
-        CFDictionaryRef decoded_gestalt = NULL;
-        *der_p = der_decode_dictionary(kCFAllocatorDefault, kCFPropertyListImmutable, &decoded_gestalt, error,
-                                       *der_p, der_end);
-        
-        if (*der_p == 0)
-            return NULL;
-        
-        account = SOSAccountCreateBasic(allocator, decoded_gestalt, factory);
-        CFReleaseNull(decoded_gestalt);
-    }
-    
-    CFArrayRef array = NULL;
-    *der_p = der_decode_array(kCFAllocatorDefault, 0, &array, error, *der_p, sequence_end);
-    
-    uint64_t tmp_departure_code = kSOSNeverAppliedToCircle;
-    *der_p = ccder_decode_uint64(&tmp_departure_code, *der_p, sequence_end);
-    *der_p = ccder_decode_bool(&account->user_public_trusted, *der_p, sequence_end);
-    *der_p = der_decode_public_bytes(kCFAllocatorDefault, kSecECDSAAlgorithmID, &account->user_public, error, *der_p, sequence_end);
-    *der_p = der_decode_public_bytes(kCFAllocatorDefault, kSecECDSAAlgorithmID, &account->previous_public, error, *der_p, sequence_end);
-    *der_p = der_decode_data_or_null(kCFAllocatorDefault, &account->user_key_parameters, error, *der_p, sequence_end);
-    *der_p = der_decode_dictionary(kCFAllocatorDefault, kCFPropertyListMutableContainers, (CFDictionaryRef *) &account->retired_peers, error, *der_p, sequence_end);
-    if (*der_p != sequence_end)
-        *der_p = NULL;
-    account->departure_code = (enum DepartureReason) tmp_departure_code;
-    
-    __block bool success = true;
-    
-    require_quiet(array && *der_p, fail);
-    
-    CFArrayForEach(array, ^(const void *value) {
-        if (success) {
-            if (isString(value)) {
-                CFDictionaryAddValue(account->circles, value, kCFNull);
-            } else {
-                CFDataRef circleData = NULL;
-                CFDataRef fullPeerInfoData = NULL;
-                
-                if (isData(value)) {
-                    circleData = (CFDataRef) value;
-                } else if (isArray(value)) {
-                    CFArrayRef pair = (CFArrayRef) value;
-                    
-                    CFTypeRef circleObject = CFArrayGetValueAtIndex(pair, 0);
-                    CFTypeRef fullPeerInfoObject = CFArrayGetValueAtIndex(pair, 1);
-                    
-                    if (CFArrayGetCount(pair) == 2 && isData(circleObject) && isData(fullPeerInfoObject)) {
-                        circleData = (CFDataRef) circleObject;
-                        fullPeerInfoData = (CFDataRef) fullPeerInfoObject;
-                    }
-                }
-                
-                if (circleData) {
-                    SOSCircleRef circle = SOSCircleCreateFromData(kCFAllocatorDefault, circleData, error);
-                    require_action_quiet(circle, fail, success = false);
-                    
-                    CFStringRef circleName = SOSCircleGetName(circle);
-                    CFDictionaryAddValue(account->circles, circleName, circle);
-                    
-                    if (fullPeerInfoData) {
-                        SOSFullPeerInfoRef full_peer = SOSFullPeerInfoCreateFromData(kCFAllocatorDefault, fullPeerInfoData, error);
-                        require_action_quiet(full_peer, fail, success = false);
-                    
-                        CFDictionaryAddValue(account->circle_identities, circleName, full_peer);
-                        CFReleaseNull(full_peer);
-                    }
-                fail:
-                    CFReleaseNull(circle);
-                }
-            }
-        }
-    });
-    CFReleaseNull(array);
-    
-    require_quiet(success, fail);
-    
-    require_action_quiet(SOSAccountEnsureFactoryCircles(account), fail,
-                         SOSCreateError(kSOSErrorBadFormat, CFSTR("Cannot EnsureFactoryCircles"), (error != NULL) ? *error : NULL, error));
-    
-    SOSAccountConvertKVSDictionaryToRetirementDictionary(account);
-
-    return account;
-    
-fail:
-    account->factory = NULL; // give the factory back.
-    CFReleaseNull(account);
-    return NULL;
-}
-
-
-SOSAccountRef SOSAccountCreateFromDER_V3(CFAllocatorRef allocator,
-                                         SOSDataSourceFactoryRef factory,
-                                         CFErrorRef* error,
-                                         const uint8_t** der_p, const uint8_t *der_end)
-{
-    SOSAccountRef account = NULL;
-    uint64_t version = 0;
-    
-    const uint8_t *sequence_end;
-    *der_p = ccder_decode_constructed_tl(CCDER_CONSTRUCTED_SEQUENCE, &sequence_end, *der_p, der_end);
-    *der_p = ccder_decode_uint64(&version, *der_p, sequence_end);
-    if(!(*der_p) || version != 3) {
-        // In this case we want to silently fail so that an account gets newly created.
-        return NULL;
-    }
-    
-    {
-        CFDictionaryRef decoded_gestalt = NULL;
-        *der_p = der_decode_dictionary(kCFAllocatorDefault, kCFPropertyListImmutable, &decoded_gestalt, error,
-                                       *der_p, der_end);
-        
-        if (*der_p == 0)
-            return NULL;
-        
-        account = SOSAccountCreateBasic(allocator, decoded_gestalt, factory);
-        CFReleaseNull(decoded_gestalt);
-    }
-    
-    CFArrayRef array = NULL;
-    *der_p = der_decode_array(kCFAllocatorDefault, 0, &array, error, *der_p, sequence_end);
-    
-    uint64_t tmp_departure_code = kSOSNeverAppliedToCircle;
-    *der_p = ccder_decode_uint64(&tmp_departure_code, *der_p, sequence_end);
-    *der_p = ccder_decode_bool(&account->user_public_trusted, *der_p, sequence_end);
-    *der_p = der_decode_public_bytes(kCFAllocatorDefault, kSecECDSAAlgorithmID, &account->user_public, error, *der_p, sequence_end);
-    *der_p = der_decode_data_or_null(kCFAllocatorDefault, &account->user_key_parameters, error, *der_p, sequence_end);
-    *der_p = der_decode_dictionary(kCFAllocatorDefault, kCFPropertyListMutableContainers, (CFDictionaryRef *) &account->retired_peers, error, *der_p, sequence_end);
-    if (*der_p != sequence_end)
-        *der_p = NULL;
-    account->departure_code = (enum DepartureReason) tmp_departure_code;
-    
-    __block bool success = true;
-    
-    require_quiet(array && *der_p, fail);
-    
-    CFArrayForEach(array, ^(const void *value) {
-        if (success) {
-            if (isString(value)) {
-                CFDictionaryAddValue(account->circles, value, kCFNull);
-            } else {
-                CFDataRef circleData = NULL;
-                CFDataRef fullPeerInfoData = NULL;
-                
-                if (isData(value)) {
-                    circleData = (CFDataRef) value;
-                } else if (isArray(value)) {
-                    CFArrayRef pair = (CFArrayRef) value;
-                    
-                    CFTypeRef circleObject = CFArrayGetValueAtIndex(pair, 0);
-                    CFTypeRef fullPeerInfoObject = CFArrayGetValueAtIndex(pair, 1);
-                    
-                    if (CFArrayGetCount(pair) == 2 && isData(circleObject) && isData(fullPeerInfoObject)) {
-                        circleData = (CFDataRef) circleObject;
-                        fullPeerInfoData = (CFDataRef) fullPeerInfoObject;
-                    }
-                }
-                
-                if (circleData) {
-                    SOSCircleRef circle = SOSCircleCreateFromData(kCFAllocatorDefault, circleData, error);
-                    require_action_quiet(circle, fail, success = false);
-                    
-                    CFStringRef circleName = SOSCircleGetName(circle);
-                    CFDictionaryAddValue(account->circles, circleName, circle);
-                    
-                    if (fullPeerInfoData) {
-                        SOSFullPeerInfoRef full_peer = SOSFullPeerInfoCreateFromData(kCFAllocatorDefault, fullPeerInfoData, error);
-                        require_action_quiet(full_peer, fail, success = false);
-                        
-                        CFDictionaryAddValue(account->circle_identities, circleName, full_peer);
-                        CFReleaseNull(full_peer);
-                    }
-                fail:
-                    CFReleaseNull(circle);
-                }
-            }
-        }
-    });
-    CFReleaseNull(array);
-    
-    require_quiet(success, fail);
-    require_action_quiet(SOSAccountEnsureFactoryCircles(account), fail,
-                         SOSCreateError(kSOSErrorBadFormat, CFSTR("Cannot EnsureFactoryCircles"), (error != NULL) ? *error : NULL, error));
-    
-    SOSAccountConvertKVSDictionaryToRetirementDictionary(account);
-
-    return account;
-    
-fail:
-    // Create a default error if we don't have one:
-    account->factory = NULL; // give the factory back.
-    CFReleaseNull(account);
-    // Don't try the der inflater from the previous release.
-    // account = SOSAccountCreateFromDER_V2(allocator, transport, factory, error, &dersave, derend);
-    if(account) account->departure_code = kSOSNeverAppliedToCircle;
-    return account;
-}
-
-SOSAccountRef SOSAccountCreateFromData(CFAllocatorRef allocator, CFDataRef circleData,
-                                       SOSDataSourceFactoryRef factory,
-                                       CFErrorRef* error)
-{
-    size_t size = CFDataGetLength(circleData);
-    const uint8_t *der = CFDataGetBytePtr(circleData);
-    SOSAccountRef account = SOSAccountCreateFromDER(allocator, factory,
-                                                    error,
-                                                    &der, der + size);
-    return account;
-}
-
-static CFMutableArrayRef SOSAccountCopyCircleArrayToEncode(SOSAccountRef account)
-{
-    CFMutableArrayRef arrayToEncode = CFArrayCreateMutableForCFTypes(kCFAllocatorDefault);
-    
-    CFDictionaryForEach(account->circles, ^(const void *key, const void *value) {
-        if (isNull(value)) {
-            CFArrayAppendValue(arrayToEncode, key); // Encode the name of the circle that's out of date.
-        } else {
-            SOSCircleRef circle = (SOSCircleRef) value;
-            CFDataRef encodedCircle = SOSCircleCopyEncodedData(circle, kCFAllocatorDefault, NULL);
-            CFTypeRef arrayEntry = encodedCircle;
-            CFRetainSafe(arrayEntry);
-            
-            SOSFullPeerInfoRef full_peer = (SOSFullPeerInfoRef) CFDictionaryGetValue(account->circle_identities, key);
-            
-            if (full_peer) {
-                CFDataRef encodedPeer = SOSFullPeerInfoCopyEncodedData(full_peer, kCFAllocatorDefault, NULL);
-                CFTypeRef originalArrayEntry = arrayEntry;
-                arrayEntry = CFArrayCreateForCFTypes(kCFAllocatorDefault, encodedCircle, encodedPeer, NULL);
-                
-                CFReleaseSafe(originalArrayEntry);
-                CFReleaseNull(encodedPeer);
-            }
-            
-            CFArrayAppendValue(arrayToEncode, arrayEntry);
-            
-            CFReleaseSafe(arrayEntry);
-            CFReleaseNull(encodedCircle);
-        }
-               
-    });
-    
-    return arrayToEncode;
-}
-
-size_t SOSAccountGetDEREncodedSize(SOSAccountRef account, CFErrorRef *error)
-{
-    size_t sequence_size = 0;
-    CFMutableArrayRef arrayToEncode = SOSAccountCopyCircleArrayToEncode(account);
-    uint64_t version = CURRENT_ACCOUNT_PERSISTENT_VERSION;
-    
-    require_quiet(accumulate_size(&sequence_size, ccder_sizeof_uint64(version)),                                    fail);
-    require_quiet(accumulate_size(&sequence_size, der_sizeof_dictionary(account->gestalt, error)),                  fail);
-    require_quiet(accumulate_size(&sequence_size, der_sizeof_array(arrayToEncode, error)),                          fail);
-    require_quiet(accumulate_size(&sequence_size, ccder_sizeof_uint64(account->departure_code)),                    fail);
-    require_quiet(accumulate_size(&sequence_size, ccder_sizeof_bool(account->user_public_trusted, error)),          fail);
-    require_quiet(accumulate_size(&sequence_size, der_sizeof_public_bytes(account->user_public, error)),            fail);
-    require_quiet(accumulate_size(&sequence_size, der_sizeof_public_bytes(account->previous_public, error)),        fail);
-    require_quiet(accumulate_size(&sequence_size, der_sizeof_data_or_null(account->user_key_parameters, error)),    fail);
-    require_quiet(accumulate_size(&sequence_size, der_sizeof_dictionary(account->retired_peers, error)),            fail);
-    
-    CFReleaseNull(arrayToEncode);
-    return ccder_sizeof(CCDER_CONSTRUCTED_SEQUENCE, sequence_size);
-    
-fail:
-    CFReleaseNull(arrayToEncode);
-    SecCFDERCreateError(kSecDERErrorUnknownEncoding, CFSTR("don't know how to encode"), NULL, error);
-    return 0;
-}
-
-uint8_t* SOSAccountEncodeToDER(SOSAccountRef account, CFErrorRef* error, const uint8_t* der, uint8_t* der_end)
-{
-    CFMutableArrayRef arrayToEncode = SOSAccountCopyCircleArrayToEncode(account);
-    uint64_t version = CURRENT_ACCOUNT_PERSISTENT_VERSION;
-    der_end =  ccder_encode_constructed_tl(CCDER_CONSTRUCTED_SEQUENCE, der_end, der,
-    ccder_encode_uint64(version, der,
-    der_encode_dictionary(account->gestalt, error, der,
-    der_encode_array(arrayToEncode, error, der,
-    ccder_encode_uint64(account->departure_code, der,
-    ccder_encode_bool(account->user_public_trusted, der,
-    der_encode_public_bytes(account->user_public, error, der,
-    der_encode_public_bytes(account->previous_public, error, der,
-    der_encode_data_or_null(account->user_key_parameters, error, der,
-    der_encode_dictionary(account->retired_peers, error, der, der_end))))))))));
-    
-    CFReleaseNull(arrayToEncode);
-    
-    return der_end;
-}
-
-
-
-size_t SOSAccountGetDEREncodedSize_V3(SOSAccountRef account, CFErrorRef *error)
-{
-    size_t sequence_size = 0;
-    CFMutableArrayRef arrayToEncode = SOSAccountCopyCircleArrayToEncode(account);
-    uint64_t version = CURRENT_ACCOUNT_PERSISTENT_VERSION;
-    
-    require_quiet(accumulate_size(&sequence_size, ccder_sizeof_uint64(version)),                                    fail);
-    require_quiet(accumulate_size(&sequence_size, der_sizeof_dictionary(account->gestalt, error)),                  fail);
-    require_quiet(accumulate_size(&sequence_size, der_sizeof_array(arrayToEncode, error)),                          fail);
-    require_quiet(accumulate_size(&sequence_size, ccder_sizeof_uint64(account->departure_code)),                    fail);
-    require_quiet(accumulate_size(&sequence_size, ccder_sizeof_bool(account->user_public_trusted, error)),          fail);
-    require_quiet(accumulate_size(&sequence_size, der_sizeof_public_bytes(account->user_public, error)),            fail);
-    require_quiet(accumulate_size(&sequence_size, der_sizeof_data_or_null(account->user_key_parameters, error)),    fail);
-    require_quiet(accumulate_size(&sequence_size, der_sizeof_dictionary(account->retired_peers, error)),            fail);
-    
-    CFReleaseNull(arrayToEncode);
-    return ccder_sizeof(CCDER_CONSTRUCTED_SEQUENCE, sequence_size);
-    
-fail:
-    CFReleaseNull(arrayToEncode);
-    SecCFDERCreateError(kSecDERErrorUnknownEncoding, CFSTR("don't know how to encode"), NULL, error);
-    return 0;
-}
-
-uint8_t* SOSAccountEncodeToDER_V3(SOSAccountRef account, CFErrorRef* error, const uint8_t* der, uint8_t* der_end)
-{
-    CFMutableArrayRef arrayToEncode = SOSAccountCopyCircleArrayToEncode(account);
-    uint64_t version = 3;
-    der_end =  ccder_encode_constructed_tl(CCDER_CONSTRUCTED_SEQUENCE, der_end, der,
-    ccder_encode_uint64(version, der,
-    der_encode_dictionary(account->gestalt, error, der,
-    der_encode_array(arrayToEncode, error, der,
-    ccder_encode_uint64(account->departure_code, der,
-    ccder_encode_bool(account->user_public_trusted, der,
-    der_encode_public_bytes(account->user_public, error, der,
-    der_encode_data_or_null(account->user_key_parameters, error, der,
-    der_encode_dictionary(account->retired_peers, error, der, der_end)))))))));
-    
-    CFReleaseNull(arrayToEncode);
-    
-    return der_end;
-}
-
-/* Original V2 encoders */
-
-size_t SOSAccountGetDEREncodedSize_V2(SOSAccountRef account, CFErrorRef *error)
-{
-    size_t sequence_size = 0;
-    CFMutableArrayRef arrayToEncode = SOSAccountCopyCircleArrayToEncode(account);
-    
-    require_quiet(accumulate_size(&sequence_size, der_sizeof_dictionary(account->gestalt, error)),                  fail);
-    require_quiet(accumulate_size(&sequence_size, der_sizeof_array(arrayToEncode, error)),                          fail);
-    require_quiet(accumulate_size(&sequence_size, ccder_sizeof_uint64(account->departure_code)), fail);
-    require_quiet(accumulate_size(&sequence_size, ccder_sizeof_bool(account->user_public_trusted, error)),          fail);
-    require_quiet(accumulate_size(&sequence_size, der_sizeof_public_bytes(account->user_public, error)),            fail);
-    require_quiet(accumulate_size(&sequence_size, der_sizeof_data_or_null(account->user_key_parameters, error)),    fail);
-    require_quiet(accumulate_size(&sequence_size, der_sizeof_dictionary(account->retired_peers, error)),            fail);
-    
-    CFReleaseNull(arrayToEncode);
-    return ccder_sizeof(CCDER_CONSTRUCTED_SEQUENCE, sequence_size);
-    
-fail:
-    CFReleaseNull(arrayToEncode);
-    SecCFDERCreateError(kSecDERErrorUnknownEncoding, CFSTR("don't know how to encode"), NULL, error);
-    return 0;
-}
-
-uint8_t* SOSAccountEncodeToDER_V2(SOSAccountRef account, CFErrorRef* error, const uint8_t* der, uint8_t* der_end)
-{
-    CFMutableArrayRef arrayToEncode = SOSAccountCopyCircleArrayToEncode(account);
-    
-    der_end =  ccder_encode_constructed_tl(CCDER_CONSTRUCTED_SEQUENCE, der_end, der,
-    der_encode_dictionary(account->gestalt, error, der,
-    der_encode_array(arrayToEncode, error, der,
-    ccder_encode_uint64(account->departure_code, der,
-    ccder_encode_bool(account->user_public_trusted, der,
-    der_encode_public_bytes(account->user_public, error, der,
-    der_encode_data_or_null(account->user_key_parameters, error, der,
-    der_encode_dictionary(account->retired_peers, error, der, der_end))))))));
-    
-    CFReleaseNull(arrayToEncode);
-    
-    return der_end;
-}
-
-
-/* Original V1 encoders */
-
-
-size_t SOSAccountGetDEREncodedSize_V1(SOSAccountRef account, CFErrorRef *error)
-{
-    size_t sequence_size = 0;
-    CFMutableArrayRef arrayToEncode = SOSAccountCopyCircleArrayToEncode(account);
-    
-    require_quiet(accumulate_size(&sequence_size, der_sizeof_dictionary(account->gestalt, error)),                  fail);
-    require_quiet(accumulate_size(&sequence_size, der_sizeof_array(arrayToEncode, error)),                          fail);
-    require_quiet(accumulate_size(&sequence_size, ccder_sizeof_bool(account->user_public_trusted, error)),          fail);
-    require_quiet(accumulate_size(&sequence_size, der_sizeof_public_bytes(account->user_public, error)),            fail);
-    require_quiet(accumulate_size(&sequence_size, der_sizeof_data_or_null(account->user_key_parameters, error)),    fail);
-    require_quiet(accumulate_size(&sequence_size, der_sizeof_dictionary(account->retired_peers, error)),            fail);
-    
-    CFReleaseNull(arrayToEncode);
-    return ccder_sizeof(CCDER_CONSTRUCTED_SEQUENCE, sequence_size);
-    
-fail:
-    CFReleaseNull(arrayToEncode);
-    SecCFDERCreateError(kSecDERErrorUnknownEncoding, CFSTR("don't know how to encode"), NULL, error);
-    return 0;
-}
-
-uint8_t* SOSAccountEncodeToDER_V1(SOSAccountRef account, CFErrorRef* error, const uint8_t* der, uint8_t* der_end)
-{
-    CFMutableArrayRef arrayToEncode = SOSAccountCopyCircleArrayToEncode(account);
-    
-    der_end =  ccder_encode_constructed_tl(CCDER_CONSTRUCTED_SEQUENCE, der_end, der,
-    der_encode_dictionary(account->gestalt, error, der,
-    der_encode_array(arrayToEncode, error, der,
-    ccder_encode_bool(account->user_public_trusted, der,
-    der_encode_public_bytes(account->user_public, error, der,
-    der_encode_data_or_null(account->user_key_parameters, error, der,
-    der_encode_dictionary(account->retired_peers, error, der, der_end)))))));
-    
-    CFReleaseNull(arrayToEncode);
-    
-    return der_end;
-}
-
-/************************/
-
-CFDataRef SOSAccountCopyEncodedData(SOSAccountRef account, CFAllocatorRef allocator, CFErrorRef *error)
-{
-    size_t size = SOSAccountGetDEREncodedSize(account, error);
-    if (size == 0)
-        return NULL;
-    uint8_t buffer[size];
-    uint8_t* start = SOSAccountEncodeToDER(account, error, buffer, buffer + sizeof(buffer));
-    CFDataRef result = CFDataCreate(kCFAllocatorDefault, start, size);
-    return result;
-}
-