1// 2// si-33-keychain-backup.c 3// libsecurity_keychain 4// 5// Created by Wade Benson on 4/16/13. 6// 7// 8 9#include <TargetConditionals.h> 10#include <stdio.h> 11 12#include "keychain_regressions.h" 13#include <Security/SecBase.h> 14#include <Security/SecItem.h> 15#include <Security/SecItemPriv.h> 16#include <libaks.h> 17#include <AssertMacros.h> 18 19 20static CFDataRef create_keybag(keybag_handle_t bag_type, CFDataRef password) 21{ 22 keybag_handle_t handle = bad_keybag_handle; 23 24 if (aks_create_bag(NULL, 0, bag_type, &handle) == 0) { 25 void * keybag = NULL; 26 int keybag_size = 0; 27 if (aks_save_bag(handle, &keybag, &keybag_size) == 0) { 28 return CFDataCreate(kCFAllocatorDefault, keybag, keybag_size); 29 } 30 } 31 32 return CFDataCreate(kCFAllocatorDefault, NULL, 0); 33} 34 35/* Test low level keychain migration from device to device interface. */ 36static void tests(void) 37{ 38 int v_eighty = 80; 39 CFNumberRef eighty = CFNumberCreate(NULL, kCFNumberSInt32Type, &v_eighty); 40 const char *v_data = "test"; 41 CFDataRef pwdata = CFDataCreate(NULL, (UInt8 *)v_data, strlen(v_data)); 42 CFMutableDictionaryRef query = CFDictionaryCreateMutable(NULL, 0, NULL, NULL); 43 CFTypeRef result = NULL; 44 CFDictionaryAddValue(query, kSecClass, kSecClassInternetPassword); 45 CFDictionaryAddValue(query, kSecAttrServer, CFSTR("members.spamcop.net")); 46 CFDictionaryAddValue(query, kSecAttrAccount, CFSTR("smith")); 47 CFDictionaryAddValue(query, kSecAttrPort, eighty); 48 CFDictionaryAddValue(query, kSecAttrProtocol, kSecAttrProtocolHTTP); 49 CFDictionaryAddValue(query, kSecAttrAuthenticationType, kSecAttrAuthenticationTypeDefault); 50 CFDictionaryAddValue(query, kSecValueData, pwdata); 51 CFDictionaryAddValue(query, kSecAttrSynchronizable, kCFBooleanTrue); 52 53 CFDataRef keybag = NULL, password = NULL; 54 55 keybag = create_keybag(kAppleKeyStoreAsymmetricBackupBag, password); 56 57 SecItemDelete(query); 58 59 // add syncable item 60 ok_status(SecItemAdd(query, NULL), "add internet password"); 61 62 ok_status(SecItemCopyMatching(query, &result), "find item we are about to destroy"); 63 if (result) { CFRelease(result); result = NULL; } 64 65 CFDictionaryRef backup = NULL; 66 67 ok_status(_SecKeychainBackupSyncable(keybag, password, NULL, &backup), "export items"); 68 69 ok_status(SecItemDelete(query), "delete item we backed up"); 70 is_status(SecItemCopyMatching(query, &result), errSecItemNotFound, "find item we are about to destroy"); 71 if (result) { CFRelease(result); result = NULL; } 72 73 ok_status(_SecKeychainRestoreSyncable(keybag, password, backup), "import items"); 74 75 ok_status(SecItemCopyMatching(query, &result), "find restored item"); 76 if (result) { CFRelease(result); result = NULL; } 77 78 ok_status(SecItemDelete(query), "delete restored item"); 79 80 if (backup) { CFRelease(backup); } 81} 82 83int si_33_keychain_backup(int argc, char *const *argv) 84{ 85 plan_tests(8); 86 87 88 tests(); 89 90 return 0; 91} 92