#include "key_create.h"
#include "keychain_utilities.h"
#include <Security/SecKey.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int
do_key_create_pair(const char *keychainName, CSSM_ALGORITHMS algorithm, uint32 keySizeInBits)
{
SecKeychainRef keychain = NULL;
OSStatus status;
int result = 0;
CSSM_CC_HANDLE contextHandle = 0;
CSSM_KEYUSE publicKeyUsage = CSSM_KEYUSE_ENCRYPT | CSSM_KEYUSE_VERIFY | CSSM_KEYUSE_WRAP | CSSM_KEYUSE_DERIVE;
uint32 publicKeyAttr = CSSM_KEYATTR_PERMANENT | CSSM_KEYATTR_EXTRACTABLE;
CSSM_KEYUSE privateKeyUsage = CSSM_KEYUSE_DECRYPT | CSSM_KEYUSE_SIGN | CSSM_KEYUSE_UNWRAP | CSSM_KEYUSE_DERIVE;
uint32 privateKeyAttr = CSSM_KEYATTR_PERMANENT | CSSM_KEYATTR_SENSITIVE | CSSM_KEYATTR_EXTRACTABLE;
SecAccessRef initialAccess = NULL;
SecKeyRef publicKey = NULL;
SecKeyRef privateKey = NULL;
if (keychainName)
{
keychain = keychain_open(keychainName);
if (!keychain)
{
result = 1;
goto loser;
}
}
status = SecKeyCreatePair(keychain, algorithm, keySizeInBits, contextHandle,
publicKeyUsage,
publicKeyAttr,
privateKeyUsage,
privateKeyAttr,
initialAccess,
&publicKey,
&privateKey);
if (status)
{
fprintf(stderr, "SecKeyCreatePair %s returned %ld(0x%lx)\n", keychainName ? keychainName : "<NULL>", status, status);
result = 1;
}
loser:
if (keychain)
CFRelease(keychain);
return result;
}
static int
parse_algorithm(const char *name, CSSM_ALGORITHMS *algorithm)
{
size_t len = strlen(name);
if (!strncmp("rsa", name, len))
*algorithm = CSSM_ALGID_RSA;
else if (!strncmp("dsa", name, len))
*algorithm = CSSM_ALGID_DSA;
else if (!strncmp("dh", name, len))
*algorithm = CSSM_ALGID_DH;
else if (!strncmp("fee", name, len))
*algorithm = CSSM_ALGID_FEE;
else
{
fprintf(stderr, "Invalid algorithm: %s\n", name);
return 2;
}
return 0;
}
int
key_create_pair(int argc, char * const *argv)
{
const char *keychainName = NULL;
CSSM_ALGORITHMS algorithm = CSSM_ALGID_RSA;
uint32 keySizeInBits = 512;
int ch, result = 0;
while ((ch = getopt(argc, argv, "a:s:f:t:v:k:AT:h")) != -1)
{
switch (ch)
{
case 'a':
result = parse_algorithm(optarg, &algorithm);
if (result)
goto loser;
break;
case 's':
keySizeInBits = atoi(optarg);
break;
case 'f':
case 't':
case 'v':
case 'k':
case 'A':
case 'T':
case '?':
default:
return 2;
}
}
argc -= optind;
argv += optind;
if (argc == 1)
{
keychainName = argv[0];
if (*keychainName == '\0')
{
result = 2;
goto loser;
}
}
else if (argc != 0)
return 2;
result = do_key_create_pair(keychainName, algorithm, keySizeInBits);
loser:
return result;
}