#include <TargetConditionals.h>
#if TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR
#include "SecurityCommands.h"
#include <AssertMacros.h>
#include <Security/SecItemPriv.h>
#include <utilities/SecCFWrappers.h>
#include "SecurityTool/sharedTool/readline.h"
#include "SecurityTool/sharedTool/tool_errors.h"
static int
do_keychain_import(const char *backupPath, const char *keybagPath, const char *passwordString)
{
CFDataRef backup=NULL;
CFDataRef keybag=NULL;
CFDataRef password=NULL;
bool ok=false;
if(passwordString) {
require(password = CFDataCreate(NULL, (UInt8 *)passwordString, strlen(passwordString)), out);
}
require(keybag=copyFileContents(keybagPath), out);
require(backup=copyFileContents(backupPath), out);
ok=_SecKeychainRestoreBackup(backup, keybag, password);
out:
CFReleaseSafe(backup);
CFReleaseSafe(keybag);
CFReleaseSafe(password);
return ok?0:1;
}
static int
do_keychain_export(const char *backupPath, const char *keybagPath, const char *passwordString)
{
CFDataRef backup=NULL;
CFDataRef keybag=NULL;
CFDataRef password=NULL;
bool ok=false;
if(passwordString) {
require(password = CFDataCreate(NULL, (UInt8 *)passwordString, strlen(passwordString)), out);
}
require(keybag=copyFileContents(keybagPath), out);
require(backup=_SecKeychainCopyBackup(keybag, password), out);
ok=writeFileContents(backupPath, backup);
out:
CFReleaseSafe(backup);
CFReleaseSafe(keybag);
CFReleaseSafe(password);
return ok?0:1;
}
int
keychain_import(int argc, char * const *argv)
{
int ch;
int verbose=0;
const char *keybag=NULL;
const char *password=NULL;
while ((ch = getopt(argc, argv, "vk:p:")) != -1)
{
switch (ch)
{
case 'v':
verbose++;
break;
case 'k':
keybag=optarg;
break;
case 'p':
password=optarg;
break;
default:
return SHOW_USAGE_MESSAGE;
}
}
argc -= optind;
argv += optind;
if(keybag==NULL) {
sec_error("-k is required\n");
return SHOW_USAGE_MESSAGE;
}
if (argc != 1) {
sec_error("<backup> is required\n");
return SHOW_USAGE_MESSAGE;
}
return do_keychain_import(argv[0], keybag, password);
}
int
keychain_export(int argc, char * const *argv)
{
int ch;
int verbose=0;
const char *keybag=NULL;
const char *password=NULL;
while ((ch = getopt(argc, argv, "vk:p:")) != -1)
{
switch (ch)
{
case 'v':
verbose++;
break;
case 'k':
keybag=optarg;
break;
case 'p':
password=optarg;
break;
default:
return SHOW_USAGE_MESSAGE;
}
}
argc -= optind;
argv += optind;
if(keybag==NULL) {
sec_error("-k is required\n");
return SHOW_USAGE_MESSAGE;
}
if (argc != 1) {
sec_error("<backup> is required\n");
return SHOW_USAGE_MESSAGE;
}
return do_keychain_export(argv[0], keybag, password);
}
#endif