1/* 2 * Copyright (c) 2013-2014 Apple Inc. All Rights Reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23 24#include <CoreFoundation/CoreFoundation.h> 25#include <TargetConditionals.h> 26#include <stdio.h> 27 28#include "keychain_regressions.h" 29#include <Security/SecBase.h> 30#include <Security/SecItem.h> 31#include <Security/SecItemPriv.h> 32#include <libaks.h> 33#include <AssertMacros.h> 34 35 36static CFDataRef create_keybag(keybag_handle_t bag_type, CFDataRef password) 37{ 38 keybag_handle_t handle = bad_keybag_handle; 39 40 if (aks_create_bag(NULL, 0, bag_type, &handle) == 0) { 41 void * keybag = NULL; 42 int keybag_size = 0; 43 if (aks_save_bag(handle, &keybag, &keybag_size) == 0) { 44 return CFDataCreate(kCFAllocatorDefault, keybag, keybag_size); 45 } 46 } 47 48 return CFDataCreate(kCFAllocatorDefault, NULL, 0); 49} 50 51/* Test low level keychain migration from device to device interface. */ 52static void tests(void) 53{ 54 int v_eighty = 80; 55 CFNumberRef eighty = CFNumberCreate(NULL, kCFNumberSInt32Type, &v_eighty); 56 const char *v_data = "test"; 57 CFDataRef pwdata = CFDataCreate(NULL, (UInt8 *)v_data, strlen(v_data)); 58 CFMutableDictionaryRef query = CFDictionaryCreateMutable(NULL, 0, NULL, NULL); 59 CFTypeRef result = NULL; 60 CFDictionaryAddValue(query, kSecClass, kSecClassInternetPassword); 61 CFDictionaryAddValue(query, kSecAttrServer, CFSTR("members.spamcop.net")); 62 CFDictionaryAddValue(query, kSecAttrAccount, CFSTR("smith")); 63 CFDictionaryAddValue(query, kSecAttrPort, eighty); 64 CFDictionaryAddValue(query, kSecAttrProtocol, kSecAttrProtocolHTTP); 65 CFDictionaryAddValue(query, kSecAttrAuthenticationType, kSecAttrAuthenticationTypeDefault); 66 CFDictionaryAddValue(query, kSecValueData, pwdata); 67 CFDictionaryAddValue(query, kSecAttrSynchronizable, kCFBooleanTrue); 68 69 CFDataRef keybag = NULL, password = NULL; 70 71 keybag = create_keybag(kAppleKeyStoreAsymmetricBackupBag, password); 72 73 SecItemDelete(query); 74 75 // add syncable item 76 ok_status(SecItemAdd(query, NULL), "add internet password"); 77 78 ok_status(SecItemCopyMatching(query, &result), "find item we are about to destroy"); 79 if (result) { CFRelease(result); result = NULL; } 80 81 CFDictionaryRef backup = NULL; 82 83 ok_status(_SecKeychainBackupSyncable(keybag, password, NULL, &backup), "export items"); 84 85 ok_status(SecItemDelete(query), "delete item we backed up"); 86 is_status(SecItemCopyMatching(query, &result), errSecItemNotFound, "find item we are about to destroy"); 87 if (result) { CFRelease(result); result = NULL; } 88 89 ok_status(_SecKeychainRestoreSyncable(keybag, password, backup), "import items"); 90 91 ok_status(SecItemCopyMatching(query, &result), "find restored item"); 92 if (result) { CFRelease(result); result = NULL; } 93 94 ok_status(SecItemDelete(query), "delete restored item"); 95 96 if (backup) { CFRelease(backup); } 97} 98 99int si_33_keychain_backup(int argc, char *const *argv) 100{ 101 plan_tests(8); 102 103 104 tests(); 105 106 return 0; 107} 108