Blame nss/cmd/symkeyutil/symkeyutil.c

Packit 40b132
/* This Source Code Form is subject to the terms of the Mozilla Public
Packit 40b132
 * License, v. 2.0. If a copy of the MPL was not distributed with this
Packit 40b132
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
Packit 40b132
Packit 40b132
/*
Packit 40b132
** symkeyutil.c
Packit 40b132
**
Packit 40b132
** utility for managing symetric keys in the database or the token
Packit 40b132
**
Packit 40b132
*/
Packit 40b132
Packit 40b132
/*
Packit 40b132
 * Wish List for this utility:
Packit 40b132
 *  1) Display and Set the CKA_ operation flags for the key.
Packit 40b132
 *  2) Modify existing keys
Packit 40b132
 *  3) Copy keys
Packit 40b132
 *  4) Read CKA_ID and display for keys.
Packit 40b132
 *  5) Option to store CKA_ID in a file on key creation.
Packit 40b132
 *  6) Encrypt, Decrypt, Hash, and Mac with generated keys.
Packit 40b132
 *  7) Use asymetric keys to wrap and unwrap keys.
Packit 40b132
 *  8) Derive.
Packit 40b132
 *  9) PBE keys.
Packit 40b132
 */
Packit 40b132
Packit 40b132
#include <stdio.h>
Packit 40b132
#include <string.h>
Packit 40b132
Packit 40b132
#include "secutil.h"
Packit 40b132
Packit 40b132
#include "nspr.h"
Packit 40b132
Packit 40b132
#include "pk11func.h"
Packit 40b132
#include "secasn1.h"
Packit 40b132
#include "cert.h"
Packit 40b132
#include "cryptohi.h"
Packit 40b132
#include "secoid.h"
Packit 40b132
#include "certdb.h"
Packit 40b132
#include "nss.h"
Packit 40b132
Packit 40b132
typedef struct _KeyTypes {
Packit 40b132
    CK_KEY_TYPE	keyType;
Packit 40b132
    CK_MECHANISM_TYPE mechType;
Packit 40b132
    CK_MECHANISM_TYPE wrapMech;
Packit 40b132
    char *label;
Packit 40b132
} KeyTypes;
Packit 40b132
Packit 40b132
static KeyTypes keyArray[] = {
Packit 40b132
#ifdef RECOGNIZE_ASYMETRIC_TYPES
Packit 40b132
    { CKK_RSA, CKM_RSA_PKCS, CKM_RSA_PKCS, "rsa" },
Packit 40b132
    { CKK_DSA, CKM_DSA, CKM_INVALID_MECHANISM, "dsa" },
Packit 40b132
    { CKK_DH, CKM_DH_PKCS_DERIVE, CKM_INVALID_MECHANISM, "dh" },
Packit 40b132
    { CKK_EC, CKM_ECDSA, CKM_INVALID_MECHANISM, "ec" },
Packit 40b132
    { CKK_X9_42_DH, CKM_X9_42_DH_DERIVE, CKM_INVALID_MECHANISM, "x9.42dh" },
Packit 40b132
    { CKK_KEA, CKM_KEA_KEY_DERIVE, CKM_INVALID_MECHANISM, "kea" },
Packit 40b132
#endif
Packit 40b132
    { CKK_GENERIC_SECRET, CKM_SHA_1_HMAC, CKM_INVALID_MECHANISM, "generic" },
Packit 40b132
    { CKK_RC2, CKM_RC2_CBC, CKM_RC2_ECB,"rc2" },
Packit 40b132
    /* don't define a wrap mech for RC-4 since it's note really safe */
Packit 40b132
    { CKK_RC4, CKM_RC4, CKM_INVALID_MECHANISM, "rc4" }, 
Packit 40b132
    { CKK_DES, CKM_DES_CBC, CKM_DES_ECB,"des" },
Packit 40b132
    { CKK_DES2, CKM_DES2_KEY_GEN, CKM_DES3_ECB, "des2" },
Packit 40b132
    { CKK_DES3, CKM_DES3_KEY_GEN, CKM_DES3_ECB, "des3" },
Packit 40b132
    { CKK_CAST, CKM_CAST_CBC, CKM_CAST_ECB, "cast" },
Packit 40b132
    { CKK_CAST3, CKM_CAST3_CBC, CKM_CAST3_ECB, "cast3" },
Packit 40b132
    { CKK_CAST5, CKM_CAST5_CBC, CKM_CAST5_ECB, "cast5" },
Packit 40b132
    { CKK_CAST128, CKM_CAST128_CBC, CKM_CAST128_ECB, "cast128" },
Packit 40b132
    { CKK_RC5, CKM_RC5_CBC, CKM_RC5_ECB, "rc5" },
Packit 40b132
    { CKK_IDEA, CKM_IDEA_CBC, CKM_IDEA_ECB, "idea" },
Packit 40b132
    { CKK_SKIPJACK, CKM_SKIPJACK_CBC64, CKM_SKIPJACK_WRAP, "skipjack" },
Packit 40b132
    { CKK_BATON, CKM_BATON_CBC128, CKM_BATON_WRAP, "baton" },
Packit 40b132
    { CKK_JUNIPER, CKM_JUNIPER_CBC128, CKM_JUNIPER_WRAP, "juniper" },
Packit 40b132
    { CKK_CDMF, CKM_CDMF_CBC, CKM_CDMF_ECB, "cdmf" },
Packit 40b132
    { CKK_AES, CKM_AES_CBC, CKM_AES_ECB, "aes" },
Packit 40b132
    { CKK_CAMELLIA, CKM_CAMELLIA_CBC, CKM_CAMELLIA_ECB, "camellia" },
Packit 40b132
};
Packit 40b132
Packit 40b132
static int keyArraySize = sizeof(keyArray)/sizeof(keyArray[0]);
Packit 40b132
Packit 40b132
int
Packit 40b132
GetLen(PRFileDesc* fd)
Packit 40b132
{
Packit 40b132
    PRFileInfo info;
Packit 40b132
Packit 40b132
    if (PR_SUCCESS != PR_GetOpenFileInfo(fd, &info)) {
Packit 40b132
        return -1;
Packit 40b132
    }
Packit 40b132
Packit 40b132
    return info.size;
Packit 40b132
}
Packit 40b132
Packit 40b132
int
Packit 40b132
ReadBuf(char *inFile, SECItem *item)
Packit 40b132
{
Packit 40b132
    int len;
Packit 40b132
    int ret;
Packit 40b132
    PRFileDesc* fd = PR_Open(inFile, PR_RDONLY, 0);
Packit 40b132
    if (NULL == fd) {
Packit 40b132
        SECU_PrintError("symkeyutil", "PR_Open failed");
Packit 40b132
	return -1;
Packit 40b132
    }
Packit 40b132
Packit 40b132
    len = GetLen(fd);
Packit 40b132
    if (len < 0) {
Packit 40b132
	SECU_PrintError("symkeyutil", "PR_GetOpenFileInfo failed");
Packit 40b132
	return -1;
Packit 40b132
    }
Packit 40b132
    item->data = (unsigned char *)PORT_Alloc(len);
Packit 40b132
    if (item->data == NULL) {
Packit 40b132
	fprintf(stderr,"Failed to allocate %d to read file %s\n",len,inFile);
Packit 40b132
	return -1;
Packit 40b132
    }
Packit 40b132
Packit 40b132
    ret = PR_Read(fd,item->data,item->len);
Packit 40b132
    if (ret < 0) {
Packit 40b132
	SECU_PrintError("symkeyutil", "PR_Read failed");
Packit 40b132
	PORT_Free(item->data);
Packit 40b132
	item->data = NULL;
Packit 40b132
	return -1;
Packit 40b132
    }
Packit 40b132
    PR_Close(fd);
Packit 40b132
    item->len = len;
Packit 40b132
    return 0;
Packit 40b132
}
Packit 40b132
Packit 40b132
int
Packit 40b132
WriteBuf(char *inFile, SECItem *item)
Packit 40b132
{
Packit 40b132
    int ret;
Packit 40b132
    PRFileDesc* fd = PR_Open(inFile, PR_WRONLY|PR_CREATE_FILE, 0x200);
Packit 40b132
    if (NULL == fd) {
Packit 40b132
        SECU_PrintError("symkeyutil", "PR_Open failed");
Packit 40b132
	return -1;
Packit 40b132
    }
Packit 40b132
Packit 40b132
    ret = PR_Write(fd,item->data,item->len);
Packit 40b132
    if (ret < 0) {
Packit 40b132
	SECU_PrintError("symkeyutil", "PR_Write failed");
Packit 40b132
	return -1;
Packit 40b132
    }
Packit 40b132
    PR_Close(fd);
Packit 40b132
    return 0;
Packit 40b132
}
Packit 40b132
Packit 40b132
CK_KEY_TYPE
Packit 40b132
GetKeyTypeFromString(const char *keyString)
Packit 40b132
{
Packit 40b132
    int i;
Packit 40b132
    for (i=0; i < keyArraySize; i++) {
Packit 40b132
	if (PL_strcasecmp(keyString,keyArray[i].label) == 0) {
Packit 40b132
	    return keyArray[i].keyType;
Packit 40b132
	}
Packit 40b132
    }
Packit 40b132
    return (CK_KEY_TYPE)-1;
Packit 40b132
}
Packit 40b132
Packit 40b132
CK_MECHANISM_TYPE
Packit 40b132
GetKeyMechFromString(const char *keyString)
Packit 40b132
{
Packit 40b132
    int i;
Packit 40b132
    for (i=0; i < keyArraySize; i++) {
Packit 40b132
	if (PL_strcasecmp(keyString,keyArray[i].label) == 0) {
Packit 40b132
	    return keyArray[i].mechType;
Packit 40b132
	}
Packit 40b132
    }
Packit 40b132
    return (CK_MECHANISM_TYPE)-1;
Packit 40b132
}
Packit 40b132
Packit 40b132
const char *
Packit 40b132
GetStringFromKeyType(CK_KEY_TYPE type)
Packit 40b132
{
Packit 40b132
    int i;
Packit 40b132
    for (i=0; i < keyArraySize; i++) {
Packit 40b132
	if (keyArray[i].keyType == type) {
Packit 40b132
	    return keyArray[i].label;
Packit 40b132
	}
Packit 40b132
    }
Packit 40b132
    return "unmatched";
Packit 40b132
}
Packit 40b132
Packit 40b132
CK_MECHANISM_TYPE
Packit 40b132
GetWrapFromKeyType(CK_KEY_TYPE type)
Packit 40b132
{
Packit 40b132
    int i;
Packit 40b132
    for (i=0; i < keyArraySize; i++) {
Packit 40b132
	if (keyArray[i].keyType == type) {
Packit 40b132
	    return keyArray[i].wrapMech;
Packit 40b132
	}
Packit 40b132
    }
Packit 40b132
    return CKM_INVALID_MECHANISM;
Packit 40b132
}
Packit 40b132
Packit 40b132
CK_MECHANISM_TYPE
Packit 40b132
GetWrapMechanism(PK11SymKey *symKey)
Packit 40b132
{
Packit 40b132
    CK_KEY_TYPE type = PK11_GetSymKeyType(symKey);
Packit 40b132
Packit 40b132
    return GetWrapFromKeyType(type);
Packit 40b132
}
Packit 40b132
Packit 40b132
int
Packit 40b132
GetDigit(char c)
Packit 40b132
{
Packit 40b132
    if (c == 0) {
Packit 40b132
	return -1;
Packit 40b132
    }
Packit 40b132
    if (c <= '9' && c >= '0') {
Packit 40b132
	return c - '0';
Packit 40b132
    }
Packit 40b132
    if (c <= 'f' && c >= 'a') {
Packit 40b132
	return c - 'a' + 0xa;
Packit 40b132
    }
Packit 40b132
    if (c <= 'F' && c >= 'A') {
Packit 40b132
	return c - 'A' + 0xa;
Packit 40b132
    }
Packit 40b132
    return -1;
Packit 40b132
}
Packit 40b132
Packit 40b132
char
Packit 40b132
ToDigit(unsigned char c)
Packit 40b132
{
Packit 40b132
    c = c & 0xf;
Packit 40b132
    if (c <= 9) {
Packit 40b132
	return (char) (c+'0');
Packit 40b132
    }
Packit 40b132
    return (char) (c+'a'-0xa);
Packit 40b132
}
Packit 40b132
Packit 40b132
char *
Packit 40b132
BufToHex(SECItem *outbuf)
Packit 40b132
{
Packit 40b132
    int len = outbuf->len * 2 +1;
Packit 40b132
    char *string, *ptr;
Packit 40b132
    unsigned int i;
Packit 40b132
Packit 40b132
    string = PORT_Alloc(len);
Packit 40b132
Packit 40b132
    ptr = string;
Packit 40b132
    for (i=0; i < outbuf->len; i++) {
Packit 40b132
	*ptr++ = ToDigit(outbuf->data[i] >> 4);
Packit 40b132
	*ptr++ = ToDigit(outbuf->data[i] & 0xf);
Packit 40b132
    }
Packit 40b132
    *ptr = 0;
Packit 40b132
    return string;
Packit 40b132
}
Packit 40b132
Packit 40b132
Packit 40b132
int
Packit 40b132
HexToBuf(char *inString, SECItem *outbuf)
Packit 40b132
{
Packit 40b132
    int len = strlen(inString);
Packit 40b132
    int outlen = len+1/2;
Packit 40b132
    int trueLen = 0;
Packit 40b132
Packit 40b132
    outbuf->data = PORT_Alloc(outlen);
Packit 40b132
    if (outbuf->data) {
Packit 40b132
	return -1;
Packit 40b132
    }
Packit 40b132
Packit 40b132
    while (*inString) {
Packit 40b132
	int digit1, digit2;
Packit 40b132
	digit1 = GetDigit(*inString++);
Packit 40b132
	digit2 = GetDigit(*inString++);
Packit 40b132
	if ((digit1 == -1) || (digit2 == -1)) {
Packit 40b132
	    PORT_Free(outbuf->data);
Packit 40b132
	    outbuf->data = NULL;
Packit 40b132
	    return -1;
Packit 40b132
	}
Packit 40b132
	outbuf->data[trueLen++] = digit1 << 4 | digit2;
Packit 40b132
    }
Packit 40b132
    outbuf->len = trueLen;
Packit 40b132
    return 0;
Packit 40b132
}
Packit 40b132
Packit 40b132
void
Packit 40b132
printBuf(unsigned char *data, int len)
Packit 40b132
{
Packit 40b132
    int i;
Packit 40b132
Packit 40b132
    for (i=0; i < len; i++) {
Packit 40b132
	printf("%02x",data[i]);
Packit 40b132
    }
Packit 40b132
}
Packit 40b132
Packit 40b132
void
Packit 40b132
PrintKey(PK11SymKey *symKey)
Packit 40b132
{
Packit 40b132
    char *name = PK11_GetSymKeyNickname(symKey);
Packit 40b132
    int len = PK11_GetKeyLength(symKey);
Packit 40b132
    int strength = PK11_GetKeyStrength(symKey, NULL);
Packit 40b132
    SECItem *value = NULL;
Packit 40b132
    CK_KEY_TYPE type = PK11_GetSymKeyType(symKey);
Packit 40b132
    (void) PK11_ExtractKeyValue(symKey);
Packit 40b132
Packit 40b132
    value = PK11_GetKeyData(symKey);
Packit 40b132
Packit 40b132
    printf("%-20s %3d   %4d   %10s  ", name ? name: " ", len, strength, 
Packit 40b132
				GetStringFromKeyType(type));
Packit 40b132
    if (value && value->data) {
Packit 40b132
	printBuf(value->data, value->len);
Packit 40b132
    } else {
Packit 40b132
	printf("<restricted>");
Packit 40b132
    }
Packit 40b132
    printf("\n");
Packit 40b132
}
Packit 40b132
Packit 40b132
SECStatus
Packit 40b132
ListKeys(PK11SlotInfo *slot, int *printLabel, void *pwd) {
Packit 40b132
    PK11SymKey *keyList;
Packit 40b132
    SECStatus rv = PK11_Authenticate(slot, PR_FALSE, pwd);
Packit 40b132
    if (rv != SECSuccess) {
Packit 40b132
        return rv;;
Packit 40b132
    }
Packit 40b132
Packit 40b132
    keyList = PK11_ListFixedKeysInSlot(slot, NULL, pwd);
Packit 40b132
    if (keyList) {
Packit 40b132
	if (*printLabel) {
Packit 40b132
            printf("     Name            Len Strength     Type    Data\n");
Packit 40b132
	    *printLabel = 0;
Packit 40b132
	}
Packit 40b132
	printf("%s:\n",PK11_GetTokenName(slot));
Packit 40b132
    }
Packit 40b132
    while (keyList) {
Packit 40b132
        PK11SymKey *freeKey = keyList;
Packit 40b132
        PrintKey(keyList);
Packit 40b132
        keyList = PK11_GetNextSymKey(keyList);
Packit 40b132
        PK11_FreeSymKey(freeKey);
Packit 40b132
    }
Packit 40b132
    return SECSuccess;
Packit 40b132
}
Packit 40b132
Packit 40b132
PK11SymKey *
Packit 40b132
FindKey(PK11SlotInfo *slot, char *name, SECItem *id, void *pwd)
Packit 40b132
{
Packit 40b132
    PK11SymKey *key = NULL;
Packit 40b132
    SECStatus rv = PK11_Authenticate(slot, PR_FALSE, pwd);
Packit 40b132
Packit 40b132
    if (rv != SECSuccess) {
Packit 40b132
	return NULL;
Packit 40b132
    }
Packit 40b132
Packit 40b132
Packit 40b132
    if (id->data) {
Packit 40b132
	key = PK11_FindFixedKey(slot,CKM_INVALID_MECHANISM, id, pwd);
Packit 40b132
    }
Packit 40b132
    if (name && !key) {
Packit 40b132
	key = PK11_ListFixedKeysInSlot(slot,name, pwd);
Packit 40b132
    }
Packit 40b132
Packit 40b132
    if (key) {
Packit 40b132
	printf("Found a key\n");
Packit 40b132
	PrintKey(key);
Packit 40b132
    }
Packit 40b132
    return key;
Packit 40b132
}
Packit 40b132
Packit 40b132
PRBool
Packit 40b132
IsKeyList(PK11SymKey *symKey)
Packit 40b132
{
Packit 40b132
   return (PRBool) (PK11_GetNextSymKey(symKey) != NULL);
Packit 40b132
}
Packit 40b132
Packit 40b132
void
Packit 40b132
FreeKeyList(PK11SymKey *symKey)
Packit 40b132
{
Packit 40b132
   PK11SymKey *next,*current;
Packit 40b132
Packit 40b132
   for (current = symKey; current; current = next) {
Packit 40b132
	next = PK11_GetNextSymKey(current);
Packit 40b132
	PK11_FreeSymKey(current);
Packit 40b132
   }
Packit 40b132
   return;
Packit 40b132
}
Packit 40b132
	   
Packit 40b132
static void 
Packit 40b132
Usage(char *progName)
Packit 40b132
{
Packit 40b132
#define FPS fprintf(stderr, 
Packit 40b132
    FPS "Type %s -H for more detailed descriptions\n", progName);
Packit 40b132
    FPS "Usage:");
Packit 40b132
    FPS "\t%s -L [std_opts] [-r]\n", progName);
Packit 40b132
    FPS "\t%s -K [-n name] -t type [-s size] [-i id |-j id_file] [std_opts]\n", progName);
Packit 40b132
    FPS "\t%s -D <[-n name | -i id | -j id_file> [std_opts]\n", progName);
Packit 40b132
    FPS "\t%s -I [-n name] [-t type] [-i id | -j id_file] -k data_file [std_opts]\n", progName);
Packit 40b132
    FPS "\t%s -E  <-nname | -i id | -j id_file> [-t type] -k data_file [-r] [std_opts]\n", progName);
Packit 40b132
    FPS "\t%s -U [-n name] [-t type] [-i id | -j id_file] -k data_file <wrap_opts> [std_opts]\n", progName);
Packit 40b132
    FPS "\t%s -W <-n name | -i id | -j id_file> [-t type] -k data_file [-r] <wrap_opts> [std_opts]\n", progName);
Packit 40b132
    FPS "\t%s -M <-n name | -i id | -j id_file> -g target_token [std_opts]\n", progName);
Packit 40b132
    FPS "\t\t std_opts -> [-d certdir] [-P dbprefix] [-p password] [-f passwordFile] [-h token]\n");
Packit 40b132
    FPS "\t\t wrap_opts -> <-w wrap_name | -x wrap_id | -y id_file>\n");
Packit 40b132
    exit(1);
Packit 40b132
}
Packit 40b132
Packit 40b132
static void LongUsage(char *progName)
Packit 40b132
{
Packit 40b132
    int i;
Packit 40b132
    FPS "%-15s List all the keys.\n", "-L");
Packit 40b132
    FPS "%-15s Generate a new key.\n", "-K");
Packit 40b132
    FPS "%-20s Specify the nickname of the new key\n",
Packit 40b132
	"   -n name");
Packit 40b132
    FPS "%-20s Specify the id in hex of the new key\n",
Packit 40b132
	"   -i key id");
Packit 40b132
    FPS "%-20s Specify a file to read the id of the new key\n",
Packit 40b132
	"   -j key id file");
Packit 40b132
    FPS "%-20s Specify the keyType of the new key\n",
Packit 40b132
	"   -t type");
Packit 40b132
    FPS "%-20s", "  valid types: ");
Packit 40b132
    for (i=0; i < keyArraySize ; i++) {
Packit 40b132
	FPS "%s%c", keyArray[i].label, i == keyArraySize-1? '\n':',');
Packit 40b132
    }
Packit 40b132
    FPS "%-20s Specify the size of the new key in bytes (required by some types)\n",
Packit 40b132
	"   -s size");
Packit 40b132
    FPS "%-15s Delete a key.\n", "-D");
Packit 40b132
    FPS "%-20s Specify the nickname of the key to delete\n",
Packit 40b132
	"   -n name");
Packit 40b132
    FPS "%-20s Specify the id in hex of the key to delete\n",
Packit 40b132
	"   -i key id");
Packit 40b132
    FPS "%-20s Specify a file to read the id of the key to delete\n",
Packit 40b132
	"   -j key id file");
Packit 40b132
    FPS "%-15s Import a new key from a data file.\n", "-I");
Packit 40b132
    FPS "%-20s Specify the data file to read the key from.\n",
Packit 40b132
	"   -k key file");
Packit 40b132
    FPS "%-20s Specify the nickname of the new key\n",
Packit 40b132
	"   -n name");
Packit 40b132
    FPS "%-20s Specify the id in hex of the new key\n",
Packit 40b132
	"   -i key id");
Packit 40b132
    FPS "%-20s Specify a file to read the id of the new key\n",
Packit 40b132
	"   -j key id file");
Packit 40b132
    FPS "%-20s Specify the keyType of the new key\n",
Packit 40b132
	"   -t type");
Packit 40b132
    FPS "%-20s", "  valid types: ");
Packit 40b132
    for (i=0; i < keyArraySize ; i++) {
Packit 40b132
	FPS "%s%c", keyArray[i].label, i == keyArraySize-1? '\n':',');
Packit 40b132
    }
Packit 40b132
    FPS "%-15s Export a key to a data file.\n", "-E");
Packit 40b132
    FPS "%-20s Specify the data file to write the key to.\n",
Packit 40b132
	"   -k key file");
Packit 40b132
    FPS "%-20s Specify the nickname of the key to export\n",
Packit 40b132
	"   -n name");
Packit 40b132
    FPS "%-20s Specify the id in hex of the key to export\n",
Packit 40b132
	"   -i key id");
Packit 40b132
    FPS "%-20s Specify a file to read the id of the key to export\n",
Packit 40b132
	"   -j key id file");
Packit 40b132
    FPS "%-15s Move a key to a new token.\n", "-M");
Packit 40b132
    FPS "%-20s Specify the nickname of the key to move\n",
Packit 40b132
	"   -n name");
Packit 40b132
    FPS "%-20s Specify the id in hex of the key to move\n",
Packit 40b132
	"   -i key id");
Packit 40b132
    FPS "%-20s Specify a file to read the id of the key to move\n",
Packit 40b132
	"   -j key id file");
Packit 40b132
    FPS "%-20s Specify the token to move the key to\n",
Packit 40b132
	"   -g target token");
Packit 40b132
    FPS "%-15s Unwrap a new key from a data file.\n", "-U");
Packit 40b132
    FPS "%-20s Specify the data file to read the encrypted key from.\n",
Packit 40b132
	"   -k key file");
Packit 40b132
    FPS "%-20s Specify the nickname of the new key\n",
Packit 40b132
	"   -n name");
Packit 40b132
    FPS "%-20s Specify the id in hex of the new key\n",
Packit 40b132
	"   -i key id");
Packit 40b132
    FPS "%-20s Specify a file to read the id of the new key\n",
Packit 40b132
	"   -j key id file");
Packit 40b132
    FPS "%-20s Specify the keyType of the new key\n",
Packit 40b132
	"   -t type");
Packit 40b132
    FPS "%-20s", "  valid types: ");
Packit 40b132
    for (i=0; i < keyArraySize ; i++) {
Packit 40b132
	FPS "%s%c", keyArray[i].label, i == keyArraySize-1? '\n':',');
Packit 40b132
    }
Packit 40b132
    FPS "%-20s Specify the nickname of the wrapping key\n",
Packit 40b132
	"   -w wrap name");
Packit 40b132
    FPS "%-20s Specify the id in hex of the wrapping key\n",
Packit 40b132
	"   -x wrap key id");
Packit 40b132
    FPS "%-20s Specify a file to read the id of the wrapping key\n",
Packit 40b132
	"   -y wrap key id file");
Packit 40b132
    FPS "%-15s Wrap a new key to a data file. [not yet implemented]\n", "-W");
Packit 40b132
    FPS "%-20s Specify the data file to write the encrypted key to.\n",
Packit 40b132
	"   -k key file");
Packit 40b132
    FPS "%-20s Specify the nickname of the key to wrap\n",
Packit 40b132
	"   -n name");
Packit 40b132
    FPS "%-20s Specify the id in hex of the key to wrap\n",
Packit 40b132
	"   -i key id");
Packit 40b132
    FPS "%-20s Specify a file to read the id of the key to wrap\n",
Packit 40b132
	"   -j key id file");
Packit 40b132
    FPS "%-20s Specify the nickname of the wrapping key\n",
Packit 40b132
	"   -w wrap name");
Packit 40b132
    FPS "%-20s Specify the id in hex of the wrapping key\n",
Packit 40b132
	"   -x wrap key id");
Packit 40b132
    FPS "%-20s Specify a file to read the id of the wrapping key\n",
Packit 40b132
	"   -y wrap key id file");
Packit 40b132
    FPS "%-15s Options valid for all commands\n", "std_opts");
Packit 40b132
    FPS "%-20s The directory where the NSS db's reside\n",
Packit 40b132
	"   -d certdir");
Packit 40b132
    FPS "%-20s Prefix for the NSS db's\n",
Packit 40b132
	"   -P db prefix");
Packit 40b132
    FPS "%-20s Specify password on the command line\n",
Packit 40b132
	"   -p password");
Packit 40b132
    FPS "%-20s Specify password file on the command line\n",
Packit 40b132
	"   -f password file");
Packit 40b132
    FPS "%-20s Specify token to act on\n",
Packit 40b132
	"   -h token");
Packit 40b132
    exit(1);
Packit 40b132
#undef FPS
Packit 40b132
}
Packit 40b132
Packit 40b132
/*  Certutil commands  */
Packit 40b132
enum {
Packit 40b132
    cmd_CreateNewKey = 0,
Packit 40b132
    cmd_DeleteKey,
Packit 40b132
    cmd_ImportKey,
Packit 40b132
    cmd_ExportKey,
Packit 40b132
    cmd_WrapKey,
Packit 40b132
    cmd_UnwrapKey,
Packit 40b132
    cmd_MoveKey,
Packit 40b132
    cmd_ListKeys,
Packit 40b132
    cmd_PrintHelp
Packit 40b132
};
Packit 40b132
Packit 40b132
/*  Certutil options */
Packit 40b132
enum {
Packit 40b132
    opt_CertDir = 0,
Packit 40b132
    opt_PasswordFile,
Packit 40b132
    opt_TargetToken,
Packit 40b132
    opt_TokenName,
Packit 40b132
    opt_KeyID,
Packit 40b132
    opt_KeyIDFile,
Packit 40b132
    opt_KeyType,
Packit 40b132
    opt_Nickname,
Packit 40b132
    opt_KeyFile,
Packit 40b132
    opt_Password,
Packit 40b132
    opt_dbPrefix,
Packit 40b132
    opt_RW,
Packit 40b132
    opt_KeySize,
Packit 40b132
    opt_WrapKeyName,
Packit 40b132
    opt_WrapKeyID,
Packit 40b132
    opt_WrapKeyIDFile,
Packit 40b132
    opt_NoiseFile
Packit 40b132
};
Packit 40b132
Packit 40b132
static secuCommandFlag symKeyUtil_commands[] =
Packit 40b132
{
Packit 40b132
	{ /* cmd_CreateNewKey        */  'K', PR_FALSE, 0, PR_FALSE },
Packit 40b132
	{ /* cmd_DeleteKey           */  'D', PR_FALSE, 0, PR_FALSE },
Packit 40b132
	{ /* cmd_ImportKey           */  'I', PR_FALSE, 0, PR_FALSE },
Packit 40b132
	{ /* cmd_ExportKey           */  'E', PR_FALSE, 0, PR_FALSE },
Packit 40b132
	{ /* cmd_WrapKey             */  'W', PR_FALSE, 0, PR_FALSE },
Packit 40b132
	{ /* cmd_UnwrapKey           */  'U', PR_FALSE, 0, PR_FALSE },
Packit 40b132
	{ /* cmd_MoveKey             */  'M', PR_FALSE, 0, PR_FALSE },
Packit 40b132
	{ /* cmd_ListKeys            */  'L', PR_FALSE, 0, PR_FALSE },
Packit 40b132
	{ /* cmd_PrintHelp           */  'H', PR_FALSE, 0, PR_FALSE },
Packit 40b132
};
Packit 40b132
Packit 40b132
static secuCommandFlag symKeyUtil_options[] =
Packit 40b132
{
Packit 40b132
	{ /* opt_CertDir             */  'd', PR_TRUE,  0, PR_FALSE },
Packit 40b132
	{ /* opt_PasswordFile        */  'f', PR_TRUE,  0, PR_FALSE },
Packit 40b132
	{ /* opt_TargetToken         */  'g', PR_TRUE,  0, PR_FALSE },
Packit 40b132
	{ /* opt_TokenName           */  'h', PR_TRUE,  0, PR_FALSE },
Packit 40b132
	{ /* opt_KeyID               */  'i', PR_TRUE,  0, PR_FALSE },
Packit 40b132
	{ /* opt_KeyIDFile           */  'j', PR_TRUE,  0, PR_FALSE },
Packit 40b132
	{ /* opt_KeyType             */  't', PR_TRUE,  0, PR_FALSE },
Packit 40b132
	{ /* opt_Nickname            */  'n', PR_TRUE,  0, PR_FALSE },
Packit 40b132
	{ /* opt_KeyFile             */  'k', PR_TRUE,  0, PR_FALSE },
Packit 40b132
	{ /* opt_Password            */  'p', PR_TRUE,  0, PR_FALSE },
Packit 40b132
	{ /* opt_dbPrefix            */  'P', PR_TRUE,  0, PR_FALSE },
Packit 40b132
	{ /* opt_RW                  */  'r', PR_FALSE, 0, PR_FALSE },
Packit 40b132
	{ /* opt_KeySize             */  's', PR_TRUE,  0, PR_FALSE },
Packit 40b132
	{ /* opt_WrapKeyName         */  'w', PR_TRUE,  0, PR_FALSE },
Packit 40b132
	{ /* opt_WrapKeyID           */  'x', PR_TRUE,  0, PR_FALSE },
Packit 40b132
	{ /* opt_WrapKeyIDFile       */  'y', PR_TRUE,  0, PR_FALSE },
Packit 40b132
	{ /* opt_NoiseFile           */  'z', PR_TRUE,  0, PR_FALSE },
Packit 40b132
};
Packit 40b132
Packit 40b132
int 
Packit 40b132
main(int argc, char **argv)
Packit 40b132
{
Packit 40b132
    PK11SlotInfo *slot = NULL;
Packit 40b132
    char *      slotname        = "internal";
Packit 40b132
    char *      certPrefix      = "";
Packit 40b132
    CK_MECHANISM_TYPE keyType   = CKM_SHA_1_HMAC;
Packit 40b132
    int         keySize		= 0;
Packit 40b132
    char *      name            = NULL;
Packit 40b132
    char *      wrapName        = NULL;
Packit 40b132
    secuPWData  pwdata          = { PW_NONE, 0 };
Packit 40b132
    PRBool 	readOnly	= PR_FALSE;
Packit 40b132
    SECItem	key;
Packit 40b132
    SECItem	keyID;
Packit 40b132
    SECItem	wrapKeyID;
Packit 40b132
    int commandsEntered = 0;
Packit 40b132
    int commandToRun = 0;
Packit 40b132
    char *progName;
Packit 40b132
    int i;
Packit 40b132
    SECStatus rv = SECFailure;
Packit 40b132
Packit 40b132
    secuCommand symKeyUtil;
Packit 40b132
    symKeyUtil.numCommands=sizeof(symKeyUtil_commands)/sizeof(secuCommandFlag);
Packit 40b132
    symKeyUtil.numOptions=sizeof(symKeyUtil_options)/sizeof(secuCommandFlag);
Packit 40b132
    symKeyUtil.commands = symKeyUtil_commands;
Packit 40b132
    symKeyUtil.options = symKeyUtil_options;
Packit 40b132
Packit 40b132
    key.data = NULL; key.len = 0;
Packit 40b132
    keyID.data = NULL; keyID.len = 0;
Packit 40b132
    wrapKeyID.data = NULL; wrapKeyID.len = 0;
Packit 40b132
Packit 40b132
    progName = strrchr(argv[0], '/');
Packit 40b132
    progName = progName ? progName+1 : argv[0];
Packit 40b132
Packit 40b132
    rv = SECU_ParseCommandLine(argc, argv, progName, &symKeyUtil);
Packit 40b132
Packit 40b132
    if (rv != SECSuccess)
Packit 40b132
	Usage(progName);
Packit 40b132
Packit 40b132
    rv = SECFailure;
Packit 40b132
Packit 40b132
    /* -H print help */
Packit 40b132
    if (symKeyUtil.commands[cmd_PrintHelp].activated)
Packit 40b132
	LongUsage(progName);
Packit 40b132
Packit 40b132
    /* -f password file, -p password */
Packit 40b132
    if (symKeyUtil.options[opt_PasswordFile].arg) {
Packit 40b132
	pwdata.source = PW_FROMFILE;
Packit 40b132
	pwdata.data = symKeyUtil.options[opt_PasswordFile].arg;
Packit 40b132
    } else if (symKeyUtil.options[opt_Password].arg) {
Packit 40b132
	pwdata.source = PW_PLAINTEXT;
Packit 40b132
	pwdata.data = symKeyUtil.options[opt_Password].arg;
Packit 40b132
    } 
Packit 40b132
Packit 40b132
    /* -d directory */
Packit 40b132
    if (symKeyUtil.options[opt_CertDir].activated)
Packit 40b132
	SECU_ConfigDirectory(symKeyUtil.options[opt_CertDir].arg);
Packit 40b132
Packit 40b132
    /* -s key size */
Packit 40b132
    if (symKeyUtil.options[opt_KeySize].activated) {
Packit 40b132
	keySize = PORT_Atoi(symKeyUtil.options[opt_KeySize].arg);
Packit 40b132
    }
Packit 40b132
Packit 40b132
    /*  -h specify token name  */
Packit 40b132
    if (symKeyUtil.options[opt_TokenName].activated) {
Packit 40b132
	if (PL_strcmp(symKeyUtil.options[opt_TokenName].arg, "all") == 0)
Packit 40b132
	    slotname = NULL;
Packit 40b132
	else
Packit 40b132
	    slotname = PL_strdup(symKeyUtil.options[opt_TokenName].arg);
Packit 40b132
    }
Packit 40b132
Packit 40b132
    /* -t key type */
Packit 40b132
    if  (symKeyUtil.options[opt_KeyType].activated) {
Packit 40b132
	keyType = GetKeyMechFromString(symKeyUtil.options[opt_KeyType].arg);
Packit 40b132
	if (keyType == (CK_MECHANISM_TYPE)-1) {
Packit 40b132
	    PR_fprintf(PR_STDERR, 
Packit 40b132
	          "%s unknown key type (%s).\n",
Packit 40b132
	           progName, symKeyUtil.options[opt_KeyType].arg);
Packit 40b132
	    return 255;
Packit 40b132
	}
Packit 40b132
    }
Packit 40b132
Packit 40b132
    /* -k for import and unwrap, it specifies an input file to read from,
Packit 40b132
     * for export and wrap it specifies an output file to write to */
Packit 40b132
    if (symKeyUtil.options[opt_KeyFile].activated) {
Packit 40b132
        if (symKeyUtil.commands[cmd_ImportKey].activated ||
Packit 40b132
		symKeyUtil.commands[cmd_UnwrapKey].activated ) {
Packit 40b132
	    int ret = ReadBuf(symKeyUtil.options[opt_KeyFile].arg, &key);
Packit 40b132
	    if (ret < 0) {
Packit 40b132
	        PR_fprintf(PR_STDERR, 
Packit 40b132
	          "%s Couldn't read key file (%s).\n",
Packit 40b132
	           progName, symKeyUtil.options[opt_KeyFile].arg);
Packit 40b132
		return 255;
Packit 40b132
	    }
Packit 40b132
	}
Packit 40b132
    }
Packit 40b132
Packit 40b132
    /* -i specify the key ID */
Packit 40b132
    if (symKeyUtil.options[opt_KeyID].activated) {
Packit 40b132
	int ret = HexToBuf(symKeyUtil.options[opt_KeyID].arg, &keyID);
Packit 40b132
	if (ret < 0) {
Packit 40b132
	    PR_fprintf(PR_STDERR, 
Packit 40b132
	          "%s invalid key ID (%s).\n",
Packit 40b132
	           progName, symKeyUtil.options[opt_KeyID].arg);
Packit 40b132
	    return 255;
Packit 40b132
	}
Packit 40b132
    }
Packit 40b132
Packit 40b132
    /* -i & -j are mutually exclusive */
Packit 40b132
    if ((symKeyUtil.options[opt_KeyID].activated) &&
Packit 40b132
		 (symKeyUtil.options[opt_KeyIDFile].activated)) {
Packit 40b132
	PR_fprintf(PR_STDERR, 
Packit 40b132
	          "%s -i and -j options are mutually exclusive.\n", progName);
Packit 40b132
	return 255;
Packit 40b132
    }
Packit 40b132
Packit 40b132
    /* -x specify the Wrap key ID */
Packit 40b132
    if (symKeyUtil.options[opt_WrapKeyID].activated) {
Packit 40b132
	int ret = HexToBuf(symKeyUtil.options[opt_WrapKeyID].arg, &wrapKeyID);
Packit 40b132
	if (ret < 0) {
Packit 40b132
	    PR_fprintf(PR_STDERR, 
Packit 40b132
	          "%s invalid key ID (%s).\n",
Packit 40b132
	           progName, symKeyUtil.options[opt_WrapKeyID].arg);
Packit 40b132
	    return 255;
Packit 40b132
	}
Packit 40b132
    }
Packit 40b132
Packit 40b132
    /* -x & -y are mutually exclusive */
Packit 40b132
    if ((symKeyUtil.options[opt_KeyID].activated) &&
Packit 40b132
		 (symKeyUtil.options[opt_KeyIDFile].activated)) {
Packit 40b132
	PR_fprintf(PR_STDERR, 
Packit 40b132
	          "%s -i and -j options are mutually exclusive.\n", progName);
Packit 40b132
	return 255;
Packit 40b132
    }
Packit 40b132
	
Packit 40b132
Packit 40b132
    /* -y specify the key ID */
Packit 40b132
    if (symKeyUtil.options[opt_WrapKeyIDFile].activated) {
Packit 40b132
	int ret = ReadBuf(symKeyUtil.options[opt_WrapKeyIDFile].arg,
Packit 40b132
								 &wrapKeyID);
Packit 40b132
	if (ret < 0) {
Packit 40b132
	    PR_fprintf(PR_STDERR, 
Packit 40b132
	          "%s Couldn't read key ID file (%s).\n",
Packit 40b132
	           progName, symKeyUtil.options[opt_WrapKeyIDFile].arg);
Packit 40b132
	    return 255;
Packit 40b132
	}
Packit 40b132
    }
Packit 40b132
Packit 40b132
    /*  -P certdb name prefix */
Packit 40b132
    if (symKeyUtil.options[opt_dbPrefix].activated)
Packit 40b132
	certPrefix = symKeyUtil.options[opt_dbPrefix].arg;
Packit 40b132
Packit 40b132
    /*  Check number of commands entered.  */
Packit 40b132
    commandsEntered = 0;
Packit 40b132
    for (i=0; i< symKeyUtil.numCommands; i++) {
Packit 40b132
	if (symKeyUtil.commands[i].activated) {
Packit 40b132
	    commandToRun = symKeyUtil.commands[i].flag;
Packit 40b132
	    commandsEntered++;
Packit 40b132
	}
Packit 40b132
	if (commandsEntered > 1)
Packit 40b132
	    break;
Packit 40b132
    }
Packit 40b132
    if (commandsEntered > 1) {
Packit 40b132
	PR_fprintf(PR_STDERR, "%s: only one command at a time!\n", progName);
Packit 40b132
	PR_fprintf(PR_STDERR, "You entered: ");
Packit 40b132
	for (i=0; i< symKeyUtil.numCommands; i++) {
Packit 40b132
	    if (symKeyUtil.commands[i].activated)
Packit 40b132
		PR_fprintf(PR_STDERR, " -%c", symKeyUtil.commands[i].flag);
Packit 40b132
	}
Packit 40b132
	PR_fprintf(PR_STDERR, "\n");
Packit 40b132
	return 255;
Packit 40b132
    }
Packit 40b132
    if (commandsEntered == 0) {
Packit 40b132
	PR_fprintf(PR_STDERR, "%s: you must enter a command!\n", progName);
Packit 40b132
	Usage(progName);
Packit 40b132
    }
Packit 40b132
Packit 40b132
    if (symKeyUtil.commands[cmd_ListKeys].activated ||
Packit 40b132
         symKeyUtil.commands[cmd_PrintHelp].activated ||
Packit 40b132
         symKeyUtil.commands[cmd_ExportKey].activated ||
Packit 40b132
         symKeyUtil.commands[cmd_WrapKey].activated) {
Packit 40b132
	readOnly = !symKeyUtil.options[opt_RW].activated;
Packit 40b132
    }
Packit 40b132
Packit 40b132
    if ((symKeyUtil.commands[cmd_ImportKey].activated ||
Packit 40b132
         symKeyUtil.commands[cmd_ExportKey].activated ||
Packit 40b132
         symKeyUtil.commands[cmd_WrapKey].activated ||
Packit 40b132
         symKeyUtil.commands[cmd_UnwrapKey].activated ) &&
Packit 40b132
        !symKeyUtil.options[opt_KeyFile].activated) {
Packit 40b132
	PR_fprintf(PR_STDERR, 
Packit 40b132
	          "%s -%c: keyfile is required for this command (-k).\n",
Packit 40b132
	           progName, commandToRun);
Packit 40b132
	return 255;
Packit 40b132
    }
Packit 40b132
Packit 40b132
    /*  -E, -D, -W, and all require -n, -i, or -j to identify the key  */
Packit 40b132
    if ((symKeyUtil.commands[cmd_ExportKey].activated ||
Packit 40b132
         symKeyUtil.commands[cmd_DeleteKey].activated ||
Packit 40b132
         symKeyUtil.commands[cmd_WrapKey].activated) &&
Packit 40b132
        !(symKeyUtil.options[opt_Nickname].activated ||
Packit 40b132
	  symKeyUtil.options[opt_KeyID].activated ||
Packit 40b132
	  symKeyUtil.options[opt_KeyIDFile].activated)) {
Packit 40b132
	PR_fprintf(PR_STDERR, 
Packit 40b132
	  "%s -%c: nickname or id is required for this command (-n, -i, -j).\n",
Packit 40b132
	           progName, commandToRun);
Packit 40b132
	return 255;
Packit 40b132
    }
Packit 40b132
Packit 40b132
    /*  -W, -U, and all  -w, -x, or -y to identify the wrapping key  */
Packit 40b132
    if (( symKeyUtil.commands[cmd_WrapKey].activated ||
Packit 40b132
         symKeyUtil.commands[cmd_UnwrapKey].activated) &&
Packit 40b132
        !(symKeyUtil.options[opt_WrapKeyName].activated ||
Packit 40b132
	  symKeyUtil.options[opt_WrapKeyID].activated ||
Packit 40b132
	  symKeyUtil.options[opt_WrapKeyIDFile].activated)) {
Packit 40b132
	PR_fprintf(PR_STDERR, 
Packit 40b132
	  "%s -%c: wrap key is required for this command (-w, -x, or -y).\n",
Packit 40b132
	           progName, commandToRun);
Packit 40b132
	return 255;
Packit 40b132
    }
Packit 40b132
Packit 40b132
    /* -M needs the target slot  (-g) */
Packit 40b132
    if (symKeyUtil.commands[cmd_MoveKey].activated  &&
Packit 40b132
			!symKeyUtil.options[opt_TargetToken].activated) {
Packit 40b132
	PR_fprintf(PR_STDERR, 
Packit 40b132
	          "%s -%c: target token is required for this command (-g).\n",
Packit 40b132
	           progName, commandToRun);
Packit 40b132
	return 255;
Packit 40b132
    }
Packit 40b132
Packit 40b132
    /*  Using slotname == NULL for listing keys and certs on all slots, 
Packit 40b132
     *  but only that. */
Packit 40b132
    if (!(symKeyUtil.commands[cmd_ListKeys].activated) && slotname == NULL) {
Packit 40b132
	PR_fprintf(PR_STDERR,
Packit 40b132
	           "%s -%c: cannot use \"-h all\" for this command.\n",
Packit 40b132
	           progName, commandToRun);
Packit 40b132
	return 255;
Packit 40b132
    }
Packit 40b132
Packit 40b132
    name = SECU_GetOptionArg(&symKeyUtil, opt_Nickname);
Packit 40b132
    wrapName = SECU_GetOptionArg(&symKeyUtil, opt_WrapKeyName);
Packit 40b132
Packit 40b132
    PK11_SetPasswordFunc(SECU_GetModulePassword);
Packit 40b132
Packit 40b132
    /*  Initialize NSPR and NSS.  */
Packit 40b132
    PR_Init(PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1);
Packit 40b132
    rv = NSS_Initialize(SECU_ConfigDirectory(NULL), certPrefix, certPrefix,
Packit 40b132
                        "secmod.db", readOnly ? NSS_INIT_READONLY: 0);
Packit 40b132
    if (rv != SECSuccess) {
Packit 40b132
	SECU_PrintPRandOSError(progName);
Packit 40b132
	goto shutdown;
Packit 40b132
    }
Packit 40b132
    rv = SECFailure;
Packit 40b132
Packit 40b132
    if (PL_strcmp(slotname, "internal") == 0)
Packit 40b132
	slot = PK11_GetInternalKeySlot();
Packit 40b132
    else if (slotname != NULL)
Packit 40b132
	slot = PK11_FindSlotByName(slotname);
Packit 40b132
Packit 40b132
    /* generating a new key */
Packit 40b132
    if (symKeyUtil.commands[cmd_CreateNewKey].activated)  {
Packit 40b132
	PK11SymKey *symKey;
Packit 40b132
Packit 40b132
	symKey = PK11_TokenKeyGen(slot, keyType, NULL, keySize, 
Packit 40b132
							NULL, PR_TRUE, &pwdata);
Packit 40b132
	if (!symKey) {
Packit 40b132
	    PR_fprintf(PR_STDERR, "%s: Token Key Gen Failed\n", progName);
Packit 40b132
	    goto shutdown;
Packit 40b132
	}
Packit 40b132
	if (symKeyUtil.options[opt_Nickname].activated) {
Packit 40b132
	    rv = PK11_SetSymKeyNickname(symKey, name);
Packit 40b132
	    if (rv != SECSuccess) {
Packit 40b132
		PK11_DeleteTokenSymKey(symKey);
Packit 40b132
		PK11_FreeSymKey(symKey);
Packit 40b132
	        PR_fprintf(PR_STDERR, "%s: Couldn't set nickname on key\n",
Packit 40b132
								 progName);
Packit 40b132
		goto shutdown;
Packit 40b132
	    }
Packit 40b132
	}
Packit 40b132
	rv = SECSuccess;
Packit 40b132
	PrintKey(symKey);
Packit 40b132
	PK11_FreeSymKey(symKey);
Packit 40b132
    }
Packit 40b132
    if (symKeyUtil.commands[cmd_DeleteKey].activated) {
Packit 40b132
	PK11SymKey *symKey = FindKey(slot,name,&keyID,&pwdata);
Packit 40b132
Packit 40b132
	if (!symKey) {
Packit 40b132
	    char *keyName = keyID.data ? BufToHex(&keyID) : PORT_Strdup(name);
Packit 40b132
	    PR_fprintf(PR_STDERR, "%s: Couldn't find key %s on %s\n",
Packit 40b132
			progName, keyName, PK11_GetTokenName(slot));
Packit 40b132
	    PORT_Free(keyName);
Packit 40b132
	    goto shutdown;
Packit 40b132
	}
Packit 40b132
Packit 40b132
	rv = PK11_DeleteTokenSymKey(symKey);
Packit 40b132
	FreeKeyList(symKey);
Packit 40b132
	if (rv != SECSuccess) {
Packit 40b132
	    PR_fprintf(PR_STDERR, "%s: Couldn't Delete Key \n", progName);
Packit 40b132
	    goto shutdown;
Packit 40b132
	}
Packit 40b132
    }
Packit 40b132
    if (symKeyUtil.commands[cmd_UnwrapKey].activated) {
Packit 40b132
	PK11SymKey *wrapKey = FindKey(slot,wrapName,&wrapKeyID,&pwdata);
Packit 40b132
	PK11SymKey *symKey;
Packit 40b132
 	CK_MECHANISM_TYPE mechanism;
Packit 40b132
Packit 40b132
	if (!wrapKey) {
Packit 40b132
	    char *keyName = wrapKeyID.data ? BufToHex(&wrapKeyID) 
Packit 40b132
							: PORT_Strdup(wrapName);
Packit 40b132
	    PR_fprintf(PR_STDERR, "%s: Couldn't find key %s on %s\n",
Packit 40b132
			progName, keyName, PK11_GetTokenName(slot));
Packit 40b132
	    PORT_Free(keyName);
Packit 40b132
	    goto shutdown;
Packit 40b132
	}
Packit 40b132
	mechanism = GetWrapMechanism(wrapKey);
Packit 40b132
	if (mechanism == CKM_INVALID_MECHANISM) {
Packit 40b132
	    char *keyName = wrapKeyID.data ? BufToHex(&wrapKeyID) 
Packit 40b132
							: PORT_Strdup(wrapName);
Packit 40b132
	    PR_fprintf(PR_STDERR, "%s: %s on %s is an invalid wrapping key\n",
Packit 40b132
			progName, keyName, PK11_GetTokenName(slot));
Packit 40b132
	    PORT_Free(keyName);
Packit 40b132
	    PK11_FreeSymKey(wrapKey);
Packit 40b132
	    goto shutdown;
Packit 40b132
	}
Packit 40b132
Packit 40b132
	symKey = PK11_UnwrapSymKeyWithFlagsPerm(wrapKey, mechanism, NULL,
Packit 40b132
			&key, keyType, CKA_ENCRYPT, keySize, 0, PR_TRUE);
Packit 40b132
	PK11_FreeSymKey(wrapKey);
Packit 40b132
	if (!symKey) {
Packit 40b132
	    PR_fprintf(PR_STDERR, "%s: Unwrap Key Failed\n", progName);
Packit 40b132
	    goto shutdown;
Packit 40b132
	}
Packit 40b132
Packit 40b132
	if (symKeyUtil.options[opt_Nickname].activated) {
Packit 40b132
	    rv = PK11_SetSymKeyNickname(symKey, name);
Packit 40b132
	    if (rv != SECSuccess) {
Packit 40b132
	        PR_fprintf(PR_STDERR, "%s: Couldn't set name on key\n", 
Packit 40b132
								progName);
Packit 40b132
		PK11_DeleteTokenSymKey(symKey);
Packit 40b132
		PK11_FreeSymKey(symKey);
Packit 40b132
		goto shutdown;
Packit 40b132
	    }
Packit 40b132
	}
Packit 40b132
	rv = SECSuccess;
Packit 40b132
	PrintKey(symKey);
Packit 40b132
	PK11_FreeSymKey(symKey);
Packit 40b132
    }
Packit 40b132
Packit 40b132
#define MAX_KEY_SIZE 4098
Packit 40b132
    if (symKeyUtil.commands[cmd_WrapKey].activated) {
Packit 40b132
	PK11SymKey *symKey = FindKey(slot, name, &keyID, &pwdata);
Packit 40b132
	PK11SymKey *wrapKey;
Packit 40b132
	CK_MECHANISM_TYPE mechanism;
Packit 40b132
	SECItem data;
Packit 40b132
	unsigned char buf[MAX_KEY_SIZE];
Packit 40b132
	int ret;
Packit 40b132
Packit 40b132
	if (!symKey) {
Packit 40b132
	    char *keyName = keyID.data ? BufToHex(&keyID) : PORT_Strdup(name);
Packit 40b132
	    PR_fprintf(PR_STDERR, "%s: Couldn't find key %s on %s\n",
Packit 40b132
			progName, keyName, PK11_GetTokenName(slot));
Packit 40b132
	    PORT_Free(keyName);
Packit 40b132
	    goto shutdown;
Packit 40b132
	}
Packit 40b132
Packit 40b132
	wrapKey = FindKey(slot, wrapName, &wrapKeyID, &pwdata);
Packit 40b132
	if (!wrapKey) {
Packit 40b132
	    char *keyName = wrapKeyID.data ? BufToHex(&wrapKeyID) 
Packit 40b132
							: PORT_Strdup(wrapName);
Packit 40b132
	    PR_fprintf(PR_STDERR, "%s: Couldn't find key %s on %s\n",
Packit 40b132
			progName, keyName, PK11_GetTokenName(slot));
Packit 40b132
	    PORT_Free(keyName);
Packit 40b132
	    PK11_FreeSymKey(symKey);
Packit 40b132
	    goto shutdown;
Packit 40b132
	}
Packit 40b132
Packit 40b132
	mechanism = GetWrapMechanism(wrapKey);
Packit 40b132
	if (mechanism == CKM_INVALID_MECHANISM) {
Packit 40b132
	    char *keyName = wrapKeyID.data ? BufToHex(&wrapKeyID) 
Packit 40b132
							: PORT_Strdup(wrapName);
Packit 40b132
	    PR_fprintf(PR_STDERR, "%s: %s on %s is an invalid wrapping key\n",
Packit 40b132
			progName, keyName, PK11_GetTokenName(slot));
Packit 40b132
	    PORT_Free(keyName);
Packit 40b132
	    PK11_FreeSymKey(symKey);
Packit 40b132
	    PK11_FreeSymKey(wrapKey);
Packit 40b132
	    goto shutdown;
Packit 40b132
	}
Packit 40b132
Packit 40b132
	data.data = buf;
Packit 40b132
	data.len = sizeof(buf);
Packit 40b132
	rv = PK11_WrapSymKey(mechanism, NULL,  wrapKey, symKey, &data);
Packit 40b132
	PK11_FreeSymKey(symKey);
Packit 40b132
	PK11_FreeSymKey(wrapKey);
Packit 40b132
	if (rv != SECSuccess) {
Packit 40b132
	    PR_fprintf(PR_STDERR, "%s: Couldn't wrap key\n",progName);
Packit 40b132
	    goto shutdown;
Packit 40b132
	}
Packit 40b132
Packit 40b132
	/* WriteBuf outputs it's own error using SECU_PrintError */
Packit 40b132
	ret = WriteBuf(symKeyUtil.options[opt_KeyFile].arg, &data);
Packit 40b132
	if (ret < 0) {
Packit 40b132
	    goto shutdown;
Packit 40b132
	}
Packit 40b132
    }
Packit 40b132
Packit 40b132
    if (symKeyUtil.commands[cmd_ImportKey].activated) {
Packit 40b132
	PK11SymKey *symKey = PK11_ImportSymKey(slot, keyType,
Packit 40b132
			 PK11_OriginUnwrap, CKA_ENCRYPT, &key,&pwdata);
Packit 40b132
	if (!symKey) {
Packit 40b132
	    PR_fprintf(PR_STDERR, "%s: Import Key Failed\n", progName);
Packit 40b132
	    goto shutdown;
Packit 40b132
	}
Packit 40b132
	if (symKeyUtil.options[opt_Nickname].activated) {
Packit 40b132
	    rv = PK11_SetSymKeyNickname(symKey, name);
Packit 40b132
	    if (rv != SECSuccess) {
Packit 40b132
	        PR_fprintf(PR_STDERR, "%s: Couldn't set name on key\n", 
Packit 40b132
								progName);
Packit 40b132
		PK11_DeleteTokenSymKey(symKey);
Packit 40b132
		PK11_FreeSymKey(symKey);
Packit 40b132
		goto shutdown;
Packit 40b132
	    }
Packit 40b132
	}
Packit 40b132
	rv = SECSuccess;
Packit 40b132
	PrintKey(symKey);
Packit 40b132
	PK11_FreeSymKey(symKey);
Packit 40b132
    }
Packit 40b132
Packit 40b132
    /*  List certs (-L)  */
Packit 40b132
    if (symKeyUtil.commands[cmd_ListKeys].activated) {
Packit 40b132
	int printLabel = 1;
Packit 40b132
	if (slot) {
Packit 40b132
	    rv = ListKeys(slot,&printLabel,&pwdata);
Packit 40b132
	} else {
Packit 40b132
	    /* loop over all the slots */
Packit 40b132
	    PK11SlotList *slotList = PK11_GetAllTokens(CKM_INVALID_MECHANISM,
Packit 40b132
					PR_FALSE, PR_FALSE, &pwdata);
Packit 40b132
	    if (slotList == NULL) {
Packit 40b132
	        PR_fprintf(PR_STDERR, "%s: No tokens found\n",progName);
Packit 40b132
	    } else {
Packit 40b132
                PK11SlotListElement *se;
Packit 40b132
                for (se = PK11_GetFirstSafe(slotList); se; 
Packit 40b132
                                    se=PK11_GetNextSafe(slotList,se, PR_FALSE)) {
Packit 40b132
                    rv = ListKeys(se->slot,&printLabel,&pwdata);
Packit 40b132
                    if (rv !=SECSuccess) {
Packit 40b132
                        break;
Packit 40b132
                    }
Packit 40b132
                }
Packit 40b132
                if (se) {
Packit 40b132
                    SECStatus rv2 = PK11_FreeSlotListElement(slotList, se);
Packit 40b132
                    PORT_Assert(SECSuccess == rv2);
Packit 40b132
                }
Packit 40b132
                PK11_FreeSlotList(slotList);
Packit 40b132
            }
Packit 40b132
	}
Packit 40b132
    }
Packit 40b132
Packit 40b132
    /*  Move key (-M)  */
Packit 40b132
    if (symKeyUtil.commands[cmd_MoveKey].activated) {
Packit 40b132
	PK11SlotInfo *target;
Packit 40b132
	char *targetName = symKeyUtil.options[opt_TargetToken].arg;
Packit 40b132
	PK11SymKey *newKey;
Packit 40b132
	PK11SymKey *symKey = FindKey(slot,name,&keyID,&pwdata);
Packit 40b132
	char *keyName = PK11_GetSymKeyNickname(symKey);
Packit 40b132
Packit 40b132
	if (!symKey) {
Packit 40b132
	    char *keyName = keyID.data ? BufToHex(&keyID) : PORT_Strdup(name);
Packit 40b132
	    PR_fprintf(PR_STDERR, "%s: Couldn't find key %s on %s\n",
Packit 40b132
			progName, keyName, PK11_GetTokenName(slot));
Packit 40b132
	    PORT_Free(keyName);
Packit 40b132
	    goto shutdown;
Packit 40b132
	}
Packit 40b132
	target = PK11_FindSlotByName(targetName);
Packit 40b132
	if (!target) {
Packit 40b132
	    PR_fprintf(PR_STDERR, "%s: Couldn't find slot %s\n",
Packit 40b132
			progName, targetName);
Packit 40b132
	    goto shutdown;
Packit 40b132
	}
Packit 40b132
	rv = PK11_Authenticate(target, PR_FALSE, &pwdata);
Packit 40b132
	if (rv != SECSuccess) {
Packit 40b132
	    PR_fprintf(PR_STDERR, "%s: Failed to log into %s\n",
Packit 40b132
			progName, targetName);
Packit 40b132
	    goto shutdown;
Packit 40b132
	}
Packit 40b132
	rv = SECFailure;
Packit 40b132
	newKey = PK11_MoveSymKey(target, CKA_ENCRYPT, 0, PR_TRUE, symKey);
Packit 40b132
	if (!newKey) {
Packit 40b132
	    PR_fprintf(PR_STDERR, "%s: Couldn't move the key \n",progName);
Packit 40b132
	    goto shutdown;
Packit 40b132
	}
Packit 40b132
	if (keyName) {
Packit 40b132
	    rv = PK11_SetSymKeyNickname(newKey, keyName);
Packit 40b132
	    if (rv != SECSuccess) {
Packit 40b132
		PK11_DeleteTokenSymKey(newKey);
Packit 40b132
		PK11_FreeSymKey(newKey);
Packit 40b132
	        PR_fprintf(PR_STDERR, "%s: Couldn't set nickname on key\n",
Packit 40b132
								 progName);
Packit 40b132
		goto shutdown;
Packit 40b132
	    }
Packit 40b132
	}
Packit 40b132
	PK11_FreeSymKey(newKey);
Packit 40b132
	rv = SECSuccess;
Packit 40b132
    }
Packit 40b132
Packit 40b132
shutdown:
Packit 40b132
    if (rv != SECSuccess) {
Packit 40b132
	PR_fprintf(PR_STDERR, "%s: %s\n", progName,
Packit 40b132
					SECU_Strerror(PORT_GetError()));
Packit 40b132
    }
Packit 40b132
Packit 40b132
    if (key.data) {
Packit 40b132
	PORT_Free(key.data);
Packit 40b132
    }
Packit 40b132
Packit 40b132
    if (keyID.data) {
Packit 40b132
	PORT_Free(keyID.data);
Packit 40b132
    }
Packit 40b132
Packit 40b132
    if (slot) {
Packit 40b132
	PK11_FreeSlot(slot);
Packit 40b132
    }
Packit 40b132
Packit 40b132
    if (NSS_Shutdown() != SECSuccess) {
Packit 40b132
        exit(1);
Packit 40b132
    }
Packit 40b132
Packit 40b132
    if (rv == SECSuccess) {
Packit 40b132
	return 0;
Packit 40b132
    } else {
Packit 40b132
	return 255;
Packit 40b132
    }
Packit 40b132
}
Packit 40b132
Packit 40b132
Packit 40b132