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 * keychain_backup.c 24 */ 25 26#include <TargetConditionals.h> 27#if TARGET_OS_EMBEDDED 28 29#include "Securitycommands.h" 30 31#include <AssertMacros.h> 32#include <Security/SecItemPriv.h> 33 34#include <utilities/SecCFWrappers.h> 35 36#include <SecurityTool/readline.h> 37#include <SecurityTool/tool_errors.h> 38 39 40static int 41do_keychain_import(const char *backupPath, const char *keybagPath, const char *passwordString) 42{ 43 CFDataRef backup=NULL; 44 CFDataRef keybag=NULL; 45 CFDataRef password=NULL; 46 bool ok=false; 47 48 if(passwordString) { 49 require(password = CFDataCreate(NULL, (UInt8 *)passwordString, strlen(passwordString)), out); 50 } 51 require(keybag=copyFileContents(keybagPath), out); 52 require(backup=copyFileContents(backupPath), out); 53 54 ok=_SecKeychainRestoreBackup(backup, keybag, password); 55 56out: 57 CFReleaseSafe(backup); 58 CFReleaseSafe(keybag); 59 CFReleaseSafe(password); 60 61 return ok?0:1; 62} 63 64static int 65do_keychain_export(const char *backupPath, const char *keybagPath, const char *passwordString) 66{ 67 CFDataRef backup=NULL; 68 CFDataRef keybag=NULL; 69 CFDataRef password=NULL; 70 bool ok=false; 71 72 if(passwordString) { 73 require(password = CFDataCreate(NULL, (UInt8 *)passwordString, strlen(passwordString)), out); 74 } 75 require(keybag=copyFileContents(keybagPath), out); 76 require(backup=_SecKeychainCopyBackup(keybag, password), out); 77 78 ok=writeFileContents(backupPath, backup); 79 80out: 81 CFReleaseSafe(backup); 82 CFReleaseSafe(keybag); 83 CFReleaseSafe(password); 84 85 return ok?0:1; 86} 87 88 89int 90keychain_import(int argc, char * const *argv) 91{ 92 int ch; 93 int verbose=0; 94 const char *keybag=NULL; 95 const char *password=NULL; 96 97 while ((ch = getopt(argc, argv, "vk:p:")) != -1) 98 { 99 switch (ch) 100 { 101 case 'v': 102 verbose++; 103 break; 104 case 'k': 105 keybag=optarg; 106 break; 107 case 'p': 108 password=optarg; 109 break; 110 default: 111 return 2; /* Trigger usage message. */ 112 } 113 } 114 115 argc -= optind; 116 argv += optind; 117 118 if(keybag==NULL) { 119 sec_error("-k is required\n"); 120 return 2; 121 } 122 123 if (argc != 1) { 124 sec_error("<backup> is required\n"); 125 return 2; /* Trigger usage message. */ 126 } 127 128 return do_keychain_import(argv[0], keybag, password); 129} 130 131int 132keychain_export(int argc, char * const *argv) 133{ 134 int ch; 135 int verbose=0; 136 const char *keybag=NULL; 137 const char *password=NULL; 138 139 while ((ch = getopt(argc, argv, "vk:p:")) != -1) 140 { 141 switch (ch) 142 { 143 case 'v': 144 verbose++; 145 break; 146 case 'k': 147 keybag=optarg; 148 break; 149 case 'p': 150 password=optarg; 151 break; 152 default: 153 return 2; /* Trigger usage message. */ 154 } 155 } 156 157 argc -= optind; 158 argv += optind; 159 160 if(keybag==NULL) { 161 sec_error("-k is required\n"); 162 return 2; 163 } 164 165 if (argc != 1) { 166 sec_error("<backup> is required\n"); 167 return 2; /* Trigger usage message. */ 168 } 169 170 return do_keychain_export(argv[0], keybag, password); 171} 172 173#endif /* TARGET_OS_EMBEDDED */ 174