security/nss/cmd/symkeyutil/symkeyutil.c

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/security/nss/cmd/symkeyutil/symkeyutil.c	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,1103 @@
     1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.7 +
     1.8 +/*
     1.9 +** symkeyutil.c
    1.10 +**
    1.11 +** utility for managing symetric keys in the database or the token
    1.12 +**
    1.13 +*/
    1.14 +
    1.15 +/*
    1.16 + * Wish List for this utility:
    1.17 + *  1) Display and Set the CKA_ operation flags for the key.
    1.18 + *  2) Modify existing keys
    1.19 + *  3) Copy keys
    1.20 + *  4) Read CKA_ID and display for keys.
    1.21 + *  5) Option to store CKA_ID in a file on key creation.
    1.22 + *  6) Encrypt, Decrypt, Hash, and Mac with generated keys.
    1.23 + *  7) Use asymetric keys to wrap and unwrap keys.
    1.24 + *  8) Derive.
    1.25 + *  9) PBE keys.
    1.26 + */
    1.27 +
    1.28 +#include <stdio.h>
    1.29 +#include <string.h>
    1.30 +
    1.31 +#include "secutil.h"
    1.32 +
    1.33 +#include "nspr.h"
    1.34 +
    1.35 +#include "pk11func.h"
    1.36 +#include "secasn1.h"
    1.37 +#include "cert.h"
    1.38 +#include "cryptohi.h"
    1.39 +#include "secoid.h"
    1.40 +#include "certdb.h"
    1.41 +#include "nss.h"
    1.42 +
    1.43 +typedef struct _KeyTypes {
    1.44 +    CK_KEY_TYPE	keyType;
    1.45 +    CK_MECHANISM_TYPE mechType;
    1.46 +    CK_MECHANISM_TYPE wrapMech;
    1.47 +    char *label;
    1.48 +} KeyTypes;
    1.49 +
    1.50 +static KeyTypes keyArray[] = {
    1.51 +#ifdef RECOGNIZE_ASYMETRIC_TYPES
    1.52 +    { CKK_RSA, CKM_RSA_PKCS, CKM_RSA_PKCS, "rsa" },
    1.53 +    { CKK_DSA, CKM_DSA, CKM_INVALID_MECHANISM, "dsa" },
    1.54 +    { CKK_DH, CKM_DH_PKCS_DERIVE, CKM_INVALID_MECHANISM, "dh" },
    1.55 +    { CKK_EC, CKM_ECDSA, CKM_INVALID_MECHANISM, "ec" },
    1.56 +    { CKK_X9_42_DH, CKM_X9_42_DH_DERIVE, CKM_INVALID_MECHANISM, "x9.42dh" },
    1.57 +    { CKK_KEA, CKM_KEA_KEY_DERIVE, CKM_INVALID_MECHANISM, "kea" },
    1.58 +#endif
    1.59 +    { CKK_GENERIC_SECRET, CKM_SHA_1_HMAC, CKM_INVALID_MECHANISM, "generic" },
    1.60 +    { CKK_RC2, CKM_RC2_CBC, CKM_RC2_ECB,"rc2" },
    1.61 +    /* don't define a wrap mech for RC-4 since it's note really safe */
    1.62 +    { CKK_RC4, CKM_RC4, CKM_INVALID_MECHANISM, "rc4" }, 
    1.63 +    { CKK_DES, CKM_DES_CBC, CKM_DES_ECB,"des" },
    1.64 +    { CKK_DES2, CKM_DES2_KEY_GEN, CKM_DES3_ECB, "des2" },
    1.65 +    { CKK_DES3, CKM_DES3_KEY_GEN, CKM_DES3_ECB, "des3" },
    1.66 +    { CKK_CAST, CKM_CAST_CBC, CKM_CAST_ECB, "cast" },
    1.67 +    { CKK_CAST3, CKM_CAST3_CBC, CKM_CAST3_ECB, "cast3" },
    1.68 +    { CKK_CAST5, CKM_CAST5_CBC, CKM_CAST5_ECB, "cast5" },
    1.69 +    { CKK_CAST128, CKM_CAST128_CBC, CKM_CAST128_ECB, "cast128" },
    1.70 +    { CKK_RC5, CKM_RC5_CBC, CKM_RC5_ECB, "rc5" },
    1.71 +    { CKK_IDEA, CKM_IDEA_CBC, CKM_IDEA_ECB, "idea" },
    1.72 +    { CKK_SKIPJACK, CKM_SKIPJACK_CBC64, CKM_SKIPJACK_WRAP, "skipjack" },
    1.73 +    { CKK_BATON, CKM_BATON_CBC128, CKM_BATON_WRAP, "baton" },
    1.74 +    { CKK_JUNIPER, CKM_JUNIPER_CBC128, CKM_JUNIPER_WRAP, "juniper" },
    1.75 +    { CKK_CDMF, CKM_CDMF_CBC, CKM_CDMF_ECB, "cdmf" },
    1.76 +    { CKK_AES, CKM_AES_CBC, CKM_AES_ECB, "aes" },
    1.77 +    { CKK_CAMELLIA, CKM_CAMELLIA_CBC, CKM_CAMELLIA_ECB, "camellia" },
    1.78 +};
    1.79 +
    1.80 +static int keyArraySize = sizeof(keyArray)/sizeof(keyArray[0]);
    1.81 +
    1.82 +int
    1.83 +GetLen(PRFileDesc* fd)
    1.84 +{
    1.85 +    PRFileInfo info;
    1.86 +
    1.87 +    if (PR_SUCCESS != PR_GetOpenFileInfo(fd, &info)) {
    1.88 +        return -1;
    1.89 +    }
    1.90 +
    1.91 +    return info.size;
    1.92 +}
    1.93 +
    1.94 +int
    1.95 +ReadBuf(char *inFile, SECItem *item)
    1.96 +{
    1.97 +    int len;
    1.98 +    int ret;
    1.99 +    PRFileDesc* fd = PR_Open(inFile, PR_RDONLY, 0);
   1.100 +    if (NULL == fd) {
   1.101 +        SECU_PrintError("symkeyutil", "PR_Open failed");
   1.102 +	return -1;
   1.103 +    }
   1.104 +
   1.105 +    len = GetLen(fd);
   1.106 +    if (len < 0) {
   1.107 +	SECU_PrintError("symkeyutil", "PR_GetOpenFileInfo failed");
   1.108 +	return -1;
   1.109 +    }
   1.110 +    item->data = (unsigned char *)PORT_Alloc(len);
   1.111 +    if (item->data == NULL) {
   1.112 +	fprintf(stderr,"Failed to allocate %d to read file %s\n",len,inFile);
   1.113 +	return -1;
   1.114 +    }
   1.115 +
   1.116 +    ret = PR_Read(fd,item->data,item->len);
   1.117 +    if (ret < 0) {
   1.118 +	SECU_PrintError("symkeyutil", "PR_Read failed");
   1.119 +	PORT_Free(item->data);
   1.120 +	item->data = NULL;
   1.121 +	return -1;
   1.122 +    }
   1.123 +    PR_Close(fd);
   1.124 +    item->len = len;
   1.125 +    return 0;
   1.126 +}
   1.127 +
   1.128 +int
   1.129 +WriteBuf(char *inFile, SECItem *item)
   1.130 +{
   1.131 +    int ret;
   1.132 +    PRFileDesc* fd = PR_Open(inFile, PR_WRONLY|PR_CREATE_FILE, 0x200);
   1.133 +    if (NULL == fd) {
   1.134 +        SECU_PrintError("symkeyutil", "PR_Open failed");
   1.135 +	return -1;
   1.136 +    }
   1.137 +
   1.138 +    ret = PR_Write(fd,item->data,item->len);
   1.139 +    if (ret < 0) {
   1.140 +	SECU_PrintError("symkeyutil", "PR_Write failed");
   1.141 +	return -1;
   1.142 +    }
   1.143 +    PR_Close(fd);
   1.144 +    return 0;
   1.145 +}
   1.146 +
   1.147 +CK_KEY_TYPE
   1.148 +GetKeyTypeFromString(const char *keyString)
   1.149 +{
   1.150 +    int i;
   1.151 +    for (i=0; i < keyArraySize; i++) {
   1.152 +	if (PL_strcasecmp(keyString,keyArray[i].label) == 0) {
   1.153 +	    return keyArray[i].keyType;
   1.154 +	}
   1.155 +    }
   1.156 +    return (CK_KEY_TYPE)-1;
   1.157 +}
   1.158 +
   1.159 +CK_MECHANISM_TYPE
   1.160 +GetKeyMechFromString(const char *keyString)
   1.161 +{
   1.162 +    int i;
   1.163 +    for (i=0; i < keyArraySize; i++) {
   1.164 +	if (PL_strcasecmp(keyString,keyArray[i].label) == 0) {
   1.165 +	    return keyArray[i].mechType;
   1.166 +	}
   1.167 +    }
   1.168 +    return (CK_MECHANISM_TYPE)-1;
   1.169 +}
   1.170 +
   1.171 +const char *
   1.172 +GetStringFromKeyType(CK_KEY_TYPE type)
   1.173 +{
   1.174 +    int i;
   1.175 +    for (i=0; i < keyArraySize; i++) {
   1.176 +	if (keyArray[i].keyType == type) {
   1.177 +	    return keyArray[i].label;
   1.178 +	}
   1.179 +    }
   1.180 +    return "unmatched";
   1.181 +}
   1.182 +
   1.183 +CK_MECHANISM_TYPE
   1.184 +GetWrapFromKeyType(CK_KEY_TYPE type)
   1.185 +{
   1.186 +    int i;
   1.187 +    for (i=0; i < keyArraySize; i++) {
   1.188 +	if (keyArray[i].keyType == type) {
   1.189 +	    return keyArray[i].wrapMech;
   1.190 +	}
   1.191 +    }
   1.192 +    return CKM_INVALID_MECHANISM;
   1.193 +}
   1.194 +
   1.195 +CK_MECHANISM_TYPE
   1.196 +GetWrapMechanism(PK11SymKey *symKey)
   1.197 +{
   1.198 +    CK_KEY_TYPE type = PK11_GetSymKeyType(symKey);
   1.199 +
   1.200 +    return GetWrapFromKeyType(type);
   1.201 +}
   1.202 +
   1.203 +int
   1.204 +GetDigit(char c)
   1.205 +{
   1.206 +    if (c == 0) {
   1.207 +	return -1;
   1.208 +    }
   1.209 +    if (c <= '9' && c >= '0') {
   1.210 +	return c - '0';
   1.211 +    }
   1.212 +    if (c <= 'f' && c >= 'a') {
   1.213 +	return c - 'a' + 0xa;
   1.214 +    }
   1.215 +    if (c <= 'F' && c >= 'A') {
   1.216 +	return c - 'A' + 0xa;
   1.217 +    }
   1.218 +    return -1;
   1.219 +}
   1.220 +
   1.221 +char
   1.222 +ToDigit(unsigned char c)
   1.223 +{
   1.224 +    c = c & 0xf;
   1.225 +    if (c <= 9) {
   1.226 +	return (char) (c+'0');
   1.227 +    }
   1.228 +    return (char) (c+'a'-0xa);
   1.229 +}
   1.230 +
   1.231 +char *
   1.232 +BufToHex(SECItem *outbuf)
   1.233 +{
   1.234 +    int len = outbuf->len * 2 +1;
   1.235 +    char *string, *ptr;
   1.236 +    unsigned int i;
   1.237 +
   1.238 +    string = PORT_Alloc(len);
   1.239 +
   1.240 +    ptr = string;
   1.241 +    for (i=0; i < outbuf->len; i++) {
   1.242 +	*ptr++ = ToDigit(outbuf->data[i] >> 4);
   1.243 +	*ptr++ = ToDigit(outbuf->data[i] & 0xf);
   1.244 +    }
   1.245 +    *ptr = 0;
   1.246 +    return string;
   1.247 +}
   1.248 +
   1.249 +
   1.250 +int
   1.251 +HexToBuf(char *inString, SECItem *outbuf)
   1.252 +{
   1.253 +    int len = strlen(inString);
   1.254 +    int outlen = len+1/2;
   1.255 +    int trueLen = 0;
   1.256 +
   1.257 +    outbuf->data = PORT_Alloc(outlen);
   1.258 +    if (outbuf->data) {
   1.259 +	return -1;
   1.260 +    }
   1.261 +
   1.262 +    while (*inString) {
   1.263 +	int digit1, digit2;
   1.264 +	digit1 = GetDigit(*inString++);
   1.265 +	digit2 = GetDigit(*inString++);
   1.266 +	if ((digit1 == -1) || (digit2 == -1)) {
   1.267 +	    PORT_Free(outbuf->data);
   1.268 +	    outbuf->data = NULL;
   1.269 +	    return -1;
   1.270 +	}
   1.271 +	outbuf->data[trueLen++] = digit1 << 4 | digit2;
   1.272 +    }
   1.273 +    outbuf->len = trueLen;
   1.274 +    return 0;
   1.275 +}
   1.276 +
   1.277 +void
   1.278 +printBuf(unsigned char *data, int len)
   1.279 +{
   1.280 +    int i;
   1.281 +
   1.282 +    for (i=0; i < len; i++) {
   1.283 +	printf("%02x",data[i]);
   1.284 +    }
   1.285 +}
   1.286 +
   1.287 +void
   1.288 +PrintKey(PK11SymKey *symKey)
   1.289 +{
   1.290 +    char *name = PK11_GetSymKeyNickname(symKey);
   1.291 +    int len = PK11_GetKeyLength(symKey);
   1.292 +    int strength = PK11_GetKeyStrength(symKey, NULL);
   1.293 +    SECItem *value = NULL;
   1.294 +    CK_KEY_TYPE type = PK11_GetSymKeyType(symKey);
   1.295 +    (void) PK11_ExtractKeyValue(symKey);
   1.296 +
   1.297 +    value = PK11_GetKeyData(symKey);
   1.298 +
   1.299 +    printf("%-20s %3d   %4d   %10s  ", name ? name: " ", len, strength, 
   1.300 +				GetStringFromKeyType(type));
   1.301 +    if (value && value->data) {
   1.302 +	printBuf(value->data, value->len);
   1.303 +    } else {
   1.304 +	printf("<restricted>");
   1.305 +    }
   1.306 +    printf("\n");
   1.307 +}
   1.308 +
   1.309 +SECStatus
   1.310 +ListKeys(PK11SlotInfo *slot, int *printLabel, void *pwd) {
   1.311 +    PK11SymKey *keyList;
   1.312 +    SECStatus rv = PK11_Authenticate(slot, PR_FALSE, pwd);
   1.313 +    if (rv != SECSuccess) {
   1.314 +        return rv;;
   1.315 +    }
   1.316 +
   1.317 +    keyList = PK11_ListFixedKeysInSlot(slot, NULL, pwd);
   1.318 +    if (keyList) {
   1.319 +	if (*printLabel) {
   1.320 +            printf("     Name            Len Strength     Type    Data\n");
   1.321 +	    *printLabel = 0;
   1.322 +	}
   1.323 +	printf("%s:\n",PK11_GetTokenName(slot));
   1.324 +    }
   1.325 +    while (keyList) {
   1.326 +        PK11SymKey *freeKey = keyList;
   1.327 +        PrintKey(keyList);
   1.328 +        keyList = PK11_GetNextSymKey(keyList);
   1.329 +        PK11_FreeSymKey(freeKey);
   1.330 +    }
   1.331 +    return SECSuccess;
   1.332 +}
   1.333 +
   1.334 +PK11SymKey *
   1.335 +FindKey(PK11SlotInfo *slot, char *name, SECItem *id, void *pwd)
   1.336 +{
   1.337 +    PK11SymKey *key = NULL;
   1.338 +    SECStatus rv = PK11_Authenticate(slot, PR_FALSE, pwd);
   1.339 +
   1.340 +    if (rv != SECSuccess) {
   1.341 +	return NULL;
   1.342 +    }
   1.343 +
   1.344 +
   1.345 +    if (id->data) {
   1.346 +	key = PK11_FindFixedKey(slot,CKM_INVALID_MECHANISM, id, pwd);
   1.347 +    }
   1.348 +    if (name && !key) {
   1.349 +	key = PK11_ListFixedKeysInSlot(slot,name, pwd);
   1.350 +    }
   1.351 +
   1.352 +    if (key) {
   1.353 +	printf("Found a key\n");
   1.354 +	PrintKey(key);
   1.355 +    }
   1.356 +    return key;
   1.357 +}
   1.358 +
   1.359 +PRBool
   1.360 +IsKeyList(PK11SymKey *symKey)
   1.361 +{
   1.362 +   return (PRBool) (PK11_GetNextSymKey(symKey) != NULL);
   1.363 +}
   1.364 +
   1.365 +void
   1.366 +FreeKeyList(PK11SymKey *symKey)
   1.367 +{
   1.368 +   PK11SymKey *next,*current;
   1.369 +
   1.370 +   for (current = symKey; current; current = next) {
   1.371 +	next = PK11_GetNextSymKey(current);
   1.372 +	PK11_FreeSymKey(current);
   1.373 +   }
   1.374 +   return;
   1.375 +}
   1.376 +	   
   1.377 +static void 
   1.378 +Usage(char *progName)
   1.379 +{
   1.380 +#define FPS fprintf(stderr, 
   1.381 +    FPS "Type %s -H for more detailed descriptions\n", progName);
   1.382 +    FPS "Usage:");
   1.383 +    FPS "\t%s -L [std_opts] [-r]\n", progName);
   1.384 +    FPS "\t%s -K [-n name] -t type [-s size] [-i id |-j id_file] [std_opts]\n", progName);
   1.385 +    FPS "\t%s -D <[-n name | -i id | -j id_file> [std_opts]\n", progName);
   1.386 +    FPS "\t%s -I [-n name] [-t type] [-i id | -j id_file] -k data_file [std_opts]\n", progName);
   1.387 +    FPS "\t%s -E  <-nname | -i id | -j id_file> [-t type] -k data_file [-r] [std_opts]\n", progName);
   1.388 +    FPS "\t%s -U [-n name] [-t type] [-i id | -j id_file] -k data_file <wrap_opts> [std_opts]\n", progName);
   1.389 +    FPS "\t%s -W <-n name | -i id | -j id_file> [-t type] -k data_file [-r] <wrap_opts> [std_opts]\n", progName);
   1.390 +    FPS "\t%s -M <-n name | -i id | -j id_file> -g target_token [std_opts]\n", progName);
   1.391 +    FPS "\t\t std_opts -> [-d certdir] [-P dbprefix] [-p password] [-f passwordFile] [-h token]\n");
   1.392 +    FPS "\t\t wrap_opts -> <-w wrap_name | -x wrap_id | -y id_file>\n");
   1.393 +    exit(1);
   1.394 +}
   1.395 +
   1.396 +static void LongUsage(char *progName)
   1.397 +{
   1.398 +    int i;
   1.399 +    FPS "%-15s List all the keys.\n", "-L");
   1.400 +    FPS "%-15s Generate a new key.\n", "-K");
   1.401 +    FPS "%-20s Specify the nickname of the new key\n",
   1.402 +	"   -n name");
   1.403 +    FPS "%-20s Specify the id in hex of the new key\n",
   1.404 +	"   -i key id");
   1.405 +    FPS "%-20s Specify a file to read the id of the new key\n",
   1.406 +	"   -j key id file");
   1.407 +    FPS "%-20s Specify the keyType of the new key\n",
   1.408 +	"   -t type");
   1.409 +    FPS "%-20s", "  valid types: ");
   1.410 +    for (i=0; i < keyArraySize ; i++) {
   1.411 +	FPS "%s%c", keyArray[i].label, i == keyArraySize-1? '\n':',');
   1.412 +    }
   1.413 +    FPS "%-20s Specify the size of the new key in bytes (required by some types)\n",
   1.414 +	"   -s size");
   1.415 +    FPS "%-15s Delete a key.\n", "-D");
   1.416 +    FPS "%-20s Specify the nickname of the key to delete\n",
   1.417 +	"   -n name");
   1.418 +    FPS "%-20s Specify the id in hex of the key to delete\n",
   1.419 +	"   -i key id");
   1.420 +    FPS "%-20s Specify a file to read the id of the key to delete\n",
   1.421 +	"   -j key id file");
   1.422 +    FPS "%-15s Import a new key from a data file.\n", "-I");
   1.423 +    FPS "%-20s Specify the data file to read the key from.\n",
   1.424 +	"   -k key file");
   1.425 +    FPS "%-20s Specify the nickname of the new key\n",
   1.426 +	"   -n name");
   1.427 +    FPS "%-20s Specify the id in hex of the new key\n",
   1.428 +	"   -i key id");
   1.429 +    FPS "%-20s Specify a file to read the id of the new key\n",
   1.430 +	"   -j key id file");
   1.431 +    FPS "%-20s Specify the keyType of the new key\n",
   1.432 +	"   -t type");
   1.433 +    FPS "%-20s", "  valid types: ");
   1.434 +    for (i=0; i < keyArraySize ; i++) {
   1.435 +	FPS "%s%c", keyArray[i].label, i == keyArraySize-1? '\n':',');
   1.436 +    }
   1.437 +    FPS "%-15s Export a key to a data file.\n", "-E");
   1.438 +    FPS "%-20s Specify the data file to write the key to.\n",
   1.439 +	"   -k key file");
   1.440 +    FPS "%-20s Specify the nickname of the key to export\n",
   1.441 +	"   -n name");
   1.442 +    FPS "%-20s Specify the id in hex of the key to export\n",
   1.443 +	"   -i key id");
   1.444 +    FPS "%-20s Specify a file to read the id of the key to export\n",
   1.445 +	"   -j key id file");
   1.446 +    FPS "%-15s Move a key to a new token.\n", "-M");
   1.447 +    FPS "%-20s Specify the nickname of the key to move\n",
   1.448 +	"   -n name");
   1.449 +    FPS "%-20s Specify the id in hex of the key to move\n",
   1.450 +	"   -i key id");
   1.451 +    FPS "%-20s Specify a file to read the id of the key to move\n",
   1.452 +	"   -j key id file");
   1.453 +    FPS "%-20s Specify the token to move the key to\n",
   1.454 +	"   -g target token");
   1.455 +    FPS "%-15s Unwrap a new key from a data file.\n", "-U");
   1.456 +    FPS "%-20s Specify the data file to read the encrypted key from.\n",
   1.457 +	"   -k key file");
   1.458 +    FPS "%-20s Specify the nickname of the new key\n",
   1.459 +	"   -n name");
   1.460 +    FPS "%-20s Specify the id in hex of the new key\n",
   1.461 +	"   -i key id");
   1.462 +    FPS "%-20s Specify a file to read the id of the new key\n",
   1.463 +	"   -j key id file");
   1.464 +    FPS "%-20s Specify the keyType of the new key\n",
   1.465 +	"   -t type");
   1.466 +    FPS "%-20s", "  valid types: ");
   1.467 +    for (i=0; i < keyArraySize ; i++) {
   1.468 +	FPS "%s%c", keyArray[i].label, i == keyArraySize-1? '\n':',');
   1.469 +    }
   1.470 +    FPS "%-20s Specify the nickname of the wrapping key\n",
   1.471 +	"   -w wrap name");
   1.472 +    FPS "%-20s Specify the id in hex of the wrapping key\n",
   1.473 +	"   -x wrap key id");
   1.474 +    FPS "%-20s Specify a file to read the id of the wrapping key\n",
   1.475 +	"   -y wrap key id file");
   1.476 +    FPS "%-15s Wrap a new key to a data file. [not yet implemented]\n", "-W");
   1.477 +    FPS "%-20s Specify the data file to write the encrypted key to.\n",
   1.478 +	"   -k key file");
   1.479 +    FPS "%-20s Specify the nickname of the key to wrap\n",
   1.480 +	"   -n name");
   1.481 +    FPS "%-20s Specify the id in hex of the key to wrap\n",
   1.482 +	"   -i key id");
   1.483 +    FPS "%-20s Specify a file to read the id of the key to wrap\n",
   1.484 +	"   -j key id file");
   1.485 +    FPS "%-20s Specify the nickname of the wrapping key\n",
   1.486 +	"   -w wrap name");
   1.487 +    FPS "%-20s Specify the id in hex of the wrapping key\n",
   1.488 +	"   -x wrap key id");
   1.489 +    FPS "%-20s Specify a file to read the id of the wrapping key\n",
   1.490 +	"   -y wrap key id file");
   1.491 +    FPS "%-15s Options valid for all commands\n", "std_opts");
   1.492 +    FPS "%-20s The directory where the NSS db's reside\n",
   1.493 +	"   -d certdir");
   1.494 +    FPS "%-20s Prefix for the NSS db's\n",
   1.495 +	"   -P db prefix");
   1.496 +    FPS "%-20s Specify password on the command line\n",
   1.497 +	"   -p password");
   1.498 +    FPS "%-20s Specify password file on the command line\n",
   1.499 +	"   -f password file");
   1.500 +    FPS "%-20s Specify token to act on\n",
   1.501 +	"   -h token");
   1.502 +    exit(1);
   1.503 +#undef FPS
   1.504 +}
   1.505 +
   1.506 +/*  Certutil commands  */
   1.507 +enum {
   1.508 +    cmd_CreateNewKey = 0,
   1.509 +    cmd_DeleteKey,
   1.510 +    cmd_ImportKey,
   1.511 +    cmd_ExportKey,
   1.512 +    cmd_WrapKey,
   1.513 +    cmd_UnwrapKey,
   1.514 +    cmd_MoveKey,
   1.515 +    cmd_ListKeys,
   1.516 +    cmd_PrintHelp
   1.517 +};
   1.518 +
   1.519 +/*  Certutil options */
   1.520 +enum {
   1.521 +    opt_CertDir = 0,
   1.522 +    opt_PasswordFile,
   1.523 +    opt_TargetToken,
   1.524 +    opt_TokenName,
   1.525 +    opt_KeyID,
   1.526 +    opt_KeyIDFile,
   1.527 +    opt_KeyType,
   1.528 +    opt_Nickname,
   1.529 +    opt_KeyFile,
   1.530 +    opt_Password,
   1.531 +    opt_dbPrefix,
   1.532 +    opt_RW,
   1.533 +    opt_KeySize,
   1.534 +    opt_WrapKeyName,
   1.535 +    opt_WrapKeyID,
   1.536 +    opt_WrapKeyIDFile,
   1.537 +    opt_NoiseFile
   1.538 +};
   1.539 +
   1.540 +static secuCommandFlag symKeyUtil_commands[] =
   1.541 +{
   1.542 +	{ /* cmd_CreateNewKey        */  'K', PR_FALSE, 0, PR_FALSE },
   1.543 +	{ /* cmd_DeleteKey           */  'D', PR_FALSE, 0, PR_FALSE },
   1.544 +	{ /* cmd_ImportKey           */  'I', PR_FALSE, 0, PR_FALSE },
   1.545 +	{ /* cmd_ExportKey           */  'E', PR_FALSE, 0, PR_FALSE },
   1.546 +	{ /* cmd_WrapKey             */  'W', PR_FALSE, 0, PR_FALSE },
   1.547 +	{ /* cmd_UnwrapKey           */  'U', PR_FALSE, 0, PR_FALSE },
   1.548 +	{ /* cmd_MoveKey             */  'M', PR_FALSE, 0, PR_FALSE },
   1.549 +	{ /* cmd_ListKeys            */  'L', PR_FALSE, 0, PR_FALSE },
   1.550 +	{ /* cmd_PrintHelp           */  'H', PR_FALSE, 0, PR_FALSE },
   1.551 +};
   1.552 +
   1.553 +static secuCommandFlag symKeyUtil_options[] =
   1.554 +{
   1.555 +	{ /* opt_CertDir             */  'd', PR_TRUE,  0, PR_FALSE },
   1.556 +	{ /* opt_PasswordFile        */  'f', PR_TRUE,  0, PR_FALSE },
   1.557 +	{ /* opt_TargetToken         */  'g', PR_TRUE,  0, PR_FALSE },
   1.558 +	{ /* opt_TokenName           */  'h', PR_TRUE,  0, PR_FALSE },
   1.559 +	{ /* opt_KeyID               */  'i', PR_TRUE,  0, PR_FALSE },
   1.560 +	{ /* opt_KeyIDFile           */  'j', PR_TRUE,  0, PR_FALSE },
   1.561 +	{ /* opt_KeyType             */  't', PR_TRUE,  0, PR_FALSE },
   1.562 +	{ /* opt_Nickname            */  'n', PR_TRUE,  0, PR_FALSE },
   1.563 +	{ /* opt_KeyFile             */  'k', PR_TRUE,  0, PR_FALSE },
   1.564 +	{ /* opt_Password            */  'p', PR_TRUE,  0, PR_FALSE },
   1.565 +	{ /* opt_dbPrefix            */  'P', PR_TRUE,  0, PR_FALSE },
   1.566 +	{ /* opt_RW                  */  'r', PR_FALSE, 0, PR_FALSE },
   1.567 +	{ /* opt_KeySize             */  's', PR_TRUE,  0, PR_FALSE },
   1.568 +	{ /* opt_WrapKeyName         */  'w', PR_TRUE,  0, PR_FALSE },
   1.569 +	{ /* opt_WrapKeyID           */  'x', PR_TRUE,  0, PR_FALSE },
   1.570 +	{ /* opt_WrapKeyIDFile       */  'y', PR_TRUE,  0, PR_FALSE },
   1.571 +	{ /* opt_NoiseFile           */  'z', PR_TRUE,  0, PR_FALSE },
   1.572 +};
   1.573 +
   1.574 +int 
   1.575 +main(int argc, char **argv)
   1.576 +{
   1.577 +    PK11SlotInfo *slot = NULL;
   1.578 +    char *      slotname        = "internal";
   1.579 +    char *      certPrefix      = "";
   1.580 +    CK_MECHANISM_TYPE keyType   = CKM_SHA_1_HMAC;
   1.581 +    int         keySize		= 0;
   1.582 +    char *      name            = NULL;
   1.583 +    char *      wrapName        = NULL;
   1.584 +    secuPWData  pwdata          = { PW_NONE, 0 };
   1.585 +    PRBool 	readOnly	= PR_FALSE;
   1.586 +    SECItem	key;
   1.587 +    SECItem	keyID;
   1.588 +    SECItem	wrapKeyID;
   1.589 +    int commandsEntered = 0;
   1.590 +    int commandToRun = 0;
   1.591 +    char *progName;
   1.592 +    int i;
   1.593 +    SECStatus rv = SECFailure;
   1.594 +
   1.595 +    secuCommand symKeyUtil;
   1.596 +    symKeyUtil.numCommands=sizeof(symKeyUtil_commands)/sizeof(secuCommandFlag);
   1.597 +    symKeyUtil.numOptions=sizeof(symKeyUtil_options)/sizeof(secuCommandFlag);
   1.598 +    symKeyUtil.commands = symKeyUtil_commands;
   1.599 +    symKeyUtil.options = symKeyUtil_options;
   1.600 +
   1.601 +    key.data = NULL; key.len = 0;
   1.602 +    keyID.data = NULL; keyID.len = 0;
   1.603 +    wrapKeyID.data = NULL; wrapKeyID.len = 0;
   1.604 +
   1.605 +    progName = strrchr(argv[0], '/');
   1.606 +    progName = progName ? progName+1 : argv[0];
   1.607 +
   1.608 +    rv = SECU_ParseCommandLine(argc, argv, progName, &symKeyUtil);
   1.609 +
   1.610 +    if (rv != SECSuccess)
   1.611 +	Usage(progName);
   1.612 +
   1.613 +    rv = SECFailure;
   1.614 +
   1.615 +    /* -H print help */
   1.616 +    if (symKeyUtil.commands[cmd_PrintHelp].activated)
   1.617 +	LongUsage(progName);
   1.618 +
   1.619 +    /* -f password file, -p password */
   1.620 +    if (symKeyUtil.options[opt_PasswordFile].arg) {
   1.621 +	pwdata.source = PW_FROMFILE;
   1.622 +	pwdata.data = symKeyUtil.options[opt_PasswordFile].arg;
   1.623 +    } else if (symKeyUtil.options[opt_Password].arg) {
   1.624 +	pwdata.source = PW_PLAINTEXT;
   1.625 +	pwdata.data = symKeyUtil.options[opt_Password].arg;
   1.626 +    } 
   1.627 +
   1.628 +    /* -d directory */
   1.629 +    if (symKeyUtil.options[opt_CertDir].activated)
   1.630 +	SECU_ConfigDirectory(symKeyUtil.options[opt_CertDir].arg);
   1.631 +
   1.632 +    /* -s key size */
   1.633 +    if (symKeyUtil.options[opt_KeySize].activated) {
   1.634 +	keySize = PORT_Atoi(symKeyUtil.options[opt_KeySize].arg);
   1.635 +    }
   1.636 +
   1.637 +    /*  -h specify token name  */
   1.638 +    if (symKeyUtil.options[opt_TokenName].activated) {
   1.639 +	if (PL_strcmp(symKeyUtil.options[opt_TokenName].arg, "all") == 0)
   1.640 +	    slotname = NULL;
   1.641 +	else
   1.642 +	    slotname = PL_strdup(symKeyUtil.options[opt_TokenName].arg);
   1.643 +    }
   1.644 +
   1.645 +    /* -t key type */
   1.646 +    if  (symKeyUtil.options[opt_KeyType].activated) {
   1.647 +	keyType = GetKeyMechFromString(symKeyUtil.options[opt_KeyType].arg);
   1.648 +	if (keyType == (CK_MECHANISM_TYPE)-1) {
   1.649 +	    PR_fprintf(PR_STDERR, 
   1.650 +	          "%s unknown key type (%s).\n",
   1.651 +	           progName, symKeyUtil.options[opt_KeyType].arg);
   1.652 +	    return 255;
   1.653 +	}
   1.654 +    }
   1.655 +
   1.656 +    /* -k for import and unwrap, it specifies an input file to read from,
   1.657 +     * for export and wrap it specifies an output file to write to */
   1.658 +    if (symKeyUtil.options[opt_KeyFile].activated) {
   1.659 +        if (symKeyUtil.commands[cmd_ImportKey].activated ||
   1.660 +		symKeyUtil.commands[cmd_UnwrapKey].activated ) {
   1.661 +	    int ret = ReadBuf(symKeyUtil.options[opt_KeyFile].arg, &key);
   1.662 +	    if (ret < 0) {
   1.663 +	        PR_fprintf(PR_STDERR, 
   1.664 +	          "%s Couldn't read key file (%s).\n",
   1.665 +	           progName, symKeyUtil.options[opt_KeyFile].arg);
   1.666 +		return 255;
   1.667 +	    }
   1.668 +	}
   1.669 +    }
   1.670 +
   1.671 +    /* -i specify the key ID */
   1.672 +    if (symKeyUtil.options[opt_KeyID].activated) {
   1.673 +	int ret = HexToBuf(symKeyUtil.options[opt_KeyID].arg, &keyID);
   1.674 +	if (ret < 0) {
   1.675 +	    PR_fprintf(PR_STDERR, 
   1.676 +	          "%s invalid key ID (%s).\n",
   1.677 +	           progName, symKeyUtil.options[opt_KeyID].arg);
   1.678 +	    return 255;
   1.679 +	}
   1.680 +    }
   1.681 +
   1.682 +    /* -i & -j are mutually exclusive */
   1.683 +    if ((symKeyUtil.options[opt_KeyID].activated) &&
   1.684 +		 (symKeyUtil.options[opt_KeyIDFile].activated)) {
   1.685 +	PR_fprintf(PR_STDERR, 
   1.686 +	          "%s -i and -j options are mutually exclusive.\n", progName);
   1.687 +	return 255;
   1.688 +    }
   1.689 +
   1.690 +    /* -x specify the Wrap key ID */
   1.691 +    if (symKeyUtil.options[opt_WrapKeyID].activated) {
   1.692 +	int ret = HexToBuf(symKeyUtil.options[opt_WrapKeyID].arg, &wrapKeyID);
   1.693 +	if (ret < 0) {
   1.694 +	    PR_fprintf(PR_STDERR, 
   1.695 +	          "%s invalid key ID (%s).\n",
   1.696 +	           progName, symKeyUtil.options[opt_WrapKeyID].arg);
   1.697 +	    return 255;
   1.698 +	}
   1.699 +    }
   1.700 +
   1.701 +    /* -x & -y are mutually exclusive */
   1.702 +    if ((symKeyUtil.options[opt_KeyID].activated) &&
   1.703 +		 (symKeyUtil.options[opt_KeyIDFile].activated)) {
   1.704 +	PR_fprintf(PR_STDERR, 
   1.705 +	          "%s -i and -j options are mutually exclusive.\n", progName);
   1.706 +	return 255;
   1.707 +    }
   1.708 +	
   1.709 +
   1.710 +    /* -y specify the key ID */
   1.711 +    if (symKeyUtil.options[opt_WrapKeyIDFile].activated) {
   1.712 +	int ret = ReadBuf(symKeyUtil.options[opt_WrapKeyIDFile].arg,
   1.713 +								 &wrapKeyID);
   1.714 +	if (ret < 0) {
   1.715 +	    PR_fprintf(PR_STDERR, 
   1.716 +	          "%s Couldn't read key ID file (%s).\n",
   1.717 +	           progName, symKeyUtil.options[opt_WrapKeyIDFile].arg);
   1.718 +	    return 255;
   1.719 +	}
   1.720 +    }
   1.721 +
   1.722 +    /*  -P certdb name prefix */
   1.723 +    if (symKeyUtil.options[opt_dbPrefix].activated)
   1.724 +	certPrefix = symKeyUtil.options[opt_dbPrefix].arg;
   1.725 +
   1.726 +    /*  Check number of commands entered.  */
   1.727 +    commandsEntered = 0;
   1.728 +    for (i=0; i< symKeyUtil.numCommands; i++) {
   1.729 +	if (symKeyUtil.commands[i].activated) {
   1.730 +	    commandToRun = symKeyUtil.commands[i].flag;
   1.731 +	    commandsEntered++;
   1.732 +	}
   1.733 +	if (commandsEntered > 1)
   1.734 +	    break;
   1.735 +    }
   1.736 +    if (commandsEntered > 1) {
   1.737 +	PR_fprintf(PR_STDERR, "%s: only one command at a time!\n", progName);
   1.738 +	PR_fprintf(PR_STDERR, "You entered: ");
   1.739 +	for (i=0; i< symKeyUtil.numCommands; i++) {
   1.740 +	    if (symKeyUtil.commands[i].activated)
   1.741 +		PR_fprintf(PR_STDERR, " -%c", symKeyUtil.commands[i].flag);
   1.742 +	}
   1.743 +	PR_fprintf(PR_STDERR, "\n");
   1.744 +	return 255;
   1.745 +    }
   1.746 +    if (commandsEntered == 0) {
   1.747 +	PR_fprintf(PR_STDERR, "%s: you must enter a command!\n", progName);
   1.748 +	Usage(progName);
   1.749 +    }
   1.750 +
   1.751 +    if (symKeyUtil.commands[cmd_ListKeys].activated ||
   1.752 +         symKeyUtil.commands[cmd_PrintHelp].activated ||
   1.753 +         symKeyUtil.commands[cmd_ExportKey].activated ||
   1.754 +         symKeyUtil.commands[cmd_WrapKey].activated) {
   1.755 +	readOnly = !symKeyUtil.options[opt_RW].activated;
   1.756 +    }
   1.757 +
   1.758 +    if ((symKeyUtil.commands[cmd_ImportKey].activated ||
   1.759 +         symKeyUtil.commands[cmd_ExportKey].activated ||
   1.760 +         symKeyUtil.commands[cmd_WrapKey].activated ||
   1.761 +         symKeyUtil.commands[cmd_UnwrapKey].activated ) &&
   1.762 +        !symKeyUtil.options[opt_KeyFile].activated) {
   1.763 +	PR_fprintf(PR_STDERR, 
   1.764 +	          "%s -%c: keyfile is required for this command (-k).\n",
   1.765 +	           progName, commandToRun);
   1.766 +	return 255;
   1.767 +    }
   1.768 +
   1.769 +    /*  -E, -D, -W, and all require -n, -i, or -j to identify the key  */
   1.770 +    if ((symKeyUtil.commands[cmd_ExportKey].activated ||
   1.771 +         symKeyUtil.commands[cmd_DeleteKey].activated ||
   1.772 +         symKeyUtil.commands[cmd_WrapKey].activated) &&
   1.773 +        !(symKeyUtil.options[opt_Nickname].activated ||
   1.774 +	  symKeyUtil.options[opt_KeyID].activated ||
   1.775 +	  symKeyUtil.options[opt_KeyIDFile].activated)) {
   1.776 +	PR_fprintf(PR_STDERR, 
   1.777 +	  "%s -%c: nickname or id is required for this command (-n, -i, -j).\n",
   1.778 +	           progName, commandToRun);
   1.779 +	return 255;
   1.780 +    }
   1.781 +
   1.782 +    /*  -W, -U, and all  -w, -x, or -y to identify the wrapping key  */
   1.783 +    if (( symKeyUtil.commands[cmd_WrapKey].activated ||
   1.784 +         symKeyUtil.commands[cmd_UnwrapKey].activated) &&
   1.785 +        !(symKeyUtil.options[opt_WrapKeyName].activated ||
   1.786 +	  symKeyUtil.options[opt_WrapKeyID].activated ||
   1.787 +	  symKeyUtil.options[opt_WrapKeyIDFile].activated)) {
   1.788 +	PR_fprintf(PR_STDERR, 
   1.789 +	  "%s -%c: wrap key is required for this command (-w, -x, or -y).\n",
   1.790 +	           progName, commandToRun);
   1.791 +	return 255;
   1.792 +    }
   1.793 +
   1.794 +    /* -M needs the target slot  (-g) */
   1.795 +    if (symKeyUtil.commands[cmd_MoveKey].activated  &&
   1.796 +			!symKeyUtil.options[opt_TargetToken].activated) {
   1.797 +	PR_fprintf(PR_STDERR, 
   1.798 +	          "%s -%c: target token is required for this command (-g).\n",
   1.799 +	           progName, commandToRun);
   1.800 +	return 255;
   1.801 +    }
   1.802 +
   1.803 +    /*  Using slotname == NULL for listing keys and certs on all slots, 
   1.804 +     *  but only that. */
   1.805 +    if (!(symKeyUtil.commands[cmd_ListKeys].activated) && slotname == NULL) {
   1.806 +	PR_fprintf(PR_STDERR,
   1.807 +	           "%s -%c: cannot use \"-h all\" for this command.\n",
   1.808 +	           progName, commandToRun);
   1.809 +	return 255;
   1.810 +    }
   1.811 +
   1.812 +    name = SECU_GetOptionArg(&symKeyUtil, opt_Nickname);
   1.813 +    wrapName = SECU_GetOptionArg(&symKeyUtil, opt_WrapKeyName);
   1.814 +
   1.815 +    PK11_SetPasswordFunc(SECU_GetModulePassword);
   1.816 +
   1.817 +    /*  Initialize NSPR and NSS.  */
   1.818 +    PR_Init(PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1);
   1.819 +    rv = NSS_Initialize(SECU_ConfigDirectory(NULL), certPrefix, certPrefix,
   1.820 +                        "secmod.db", readOnly ? NSS_INIT_READONLY: 0);
   1.821 +    if (rv != SECSuccess) {
   1.822 +	SECU_PrintPRandOSError(progName);
   1.823 +	goto shutdown;
   1.824 +    }
   1.825 +    rv = SECFailure;
   1.826 +
   1.827 +    if (PL_strcmp(slotname, "internal") == 0)
   1.828 +	slot = PK11_GetInternalKeySlot();
   1.829 +    else if (slotname != NULL)
   1.830 +	slot = PK11_FindSlotByName(slotname);
   1.831 +
   1.832 +    /* generating a new key */
   1.833 +    if (symKeyUtil.commands[cmd_CreateNewKey].activated)  {
   1.834 +	PK11SymKey *symKey;
   1.835 +
   1.836 +	symKey = PK11_TokenKeyGen(slot, keyType, NULL, keySize, 
   1.837 +							NULL, PR_TRUE, &pwdata);
   1.838 +	if (!symKey) {
   1.839 +	    PR_fprintf(PR_STDERR, "%s: Token Key Gen Failed\n", progName);
   1.840 +	    goto shutdown;
   1.841 +	}
   1.842 +	if (symKeyUtil.options[opt_Nickname].activated) {
   1.843 +	    rv = PK11_SetSymKeyNickname(symKey, name);
   1.844 +	    if (rv != SECSuccess) {
   1.845 +		PK11_DeleteTokenSymKey(symKey);
   1.846 +		PK11_FreeSymKey(symKey);
   1.847 +	        PR_fprintf(PR_STDERR, "%s: Couldn't set nickname on key\n",
   1.848 +								 progName);
   1.849 +		goto shutdown;
   1.850 +	    }
   1.851 +	}
   1.852 +	rv = SECSuccess;
   1.853 +	PrintKey(symKey);
   1.854 +	PK11_FreeSymKey(symKey);
   1.855 +    }
   1.856 +    if (symKeyUtil.commands[cmd_DeleteKey].activated) {
   1.857 +	PK11SymKey *symKey = FindKey(slot,name,&keyID,&pwdata);
   1.858 +
   1.859 +	if (!symKey) {
   1.860 +	    char *keyName = keyID.data ? BufToHex(&keyID) : PORT_Strdup(name);
   1.861 +	    PR_fprintf(PR_STDERR, "%s: Couldn't find key %s on %s\n",
   1.862 +			progName, keyName, PK11_GetTokenName(slot));
   1.863 +	    PORT_Free(keyName);
   1.864 +	    goto shutdown;
   1.865 +	}
   1.866 +
   1.867 +	rv = PK11_DeleteTokenSymKey(symKey);
   1.868 +	FreeKeyList(symKey);
   1.869 +	if (rv != SECSuccess) {
   1.870 +	    PR_fprintf(PR_STDERR, "%s: Couldn't Delete Key \n", progName);
   1.871 +	    goto shutdown;
   1.872 +	}
   1.873 +    }
   1.874 +    if (symKeyUtil.commands[cmd_UnwrapKey].activated) {
   1.875 +	PK11SymKey *wrapKey = FindKey(slot,wrapName,&wrapKeyID,&pwdata);
   1.876 +	PK11SymKey *symKey;
   1.877 + 	CK_MECHANISM_TYPE mechanism;
   1.878 +
   1.879 +	if (!wrapKey) {
   1.880 +	    char *keyName = wrapKeyID.data ? BufToHex(&wrapKeyID) 
   1.881 +							: PORT_Strdup(wrapName);
   1.882 +	    PR_fprintf(PR_STDERR, "%s: Couldn't find key %s on %s\n",
   1.883 +			progName, keyName, PK11_GetTokenName(slot));
   1.884 +	    PORT_Free(keyName);
   1.885 +	    goto shutdown;
   1.886 +	}
   1.887 +	mechanism = GetWrapMechanism(wrapKey);
   1.888 +	if (mechanism == CKM_INVALID_MECHANISM) {
   1.889 +	    char *keyName = wrapKeyID.data ? BufToHex(&wrapKeyID) 
   1.890 +							: PORT_Strdup(wrapName);
   1.891 +	    PR_fprintf(PR_STDERR, "%s: %s on %s is an invalid wrapping key\n",
   1.892 +			progName, keyName, PK11_GetTokenName(slot));
   1.893 +	    PORT_Free(keyName);
   1.894 +	    PK11_FreeSymKey(wrapKey);
   1.895 +	    goto shutdown;
   1.896 +	}
   1.897 +
   1.898 +	symKey = PK11_UnwrapSymKeyWithFlagsPerm(wrapKey, mechanism, NULL,
   1.899 +			&key, keyType, CKA_ENCRYPT, keySize, 0, PR_TRUE);
   1.900 +	PK11_FreeSymKey(wrapKey);
   1.901 +	if (!symKey) {
   1.902 +	    PR_fprintf(PR_STDERR, "%s: Unwrap Key Failed\n", progName);
   1.903 +	    goto shutdown;
   1.904 +	}
   1.905 +
   1.906 +	if (symKeyUtil.options[opt_Nickname].activated) {
   1.907 +	    rv = PK11_SetSymKeyNickname(symKey, name);
   1.908 +	    if (rv != SECSuccess) {
   1.909 +	        PR_fprintf(PR_STDERR, "%s: Couldn't set name on key\n", 
   1.910 +								progName);
   1.911 +		PK11_DeleteTokenSymKey(symKey);
   1.912 +		PK11_FreeSymKey(symKey);
   1.913 +		goto shutdown;
   1.914 +	    }
   1.915 +	}
   1.916 +	rv = SECSuccess;
   1.917 +	PrintKey(symKey);
   1.918 +	PK11_FreeSymKey(symKey);
   1.919 +    }
   1.920 +
   1.921 +#define MAX_KEY_SIZE 4098
   1.922 +    if (symKeyUtil.commands[cmd_WrapKey].activated) {
   1.923 +	PK11SymKey *symKey = FindKey(slot, name, &keyID, &pwdata);
   1.924 +	PK11SymKey *wrapKey;
   1.925 +	CK_MECHANISM_TYPE mechanism;
   1.926 +	SECItem data;
   1.927 +	unsigned char buf[MAX_KEY_SIZE];
   1.928 +	int ret;
   1.929 +
   1.930 +	if (!symKey) {
   1.931 +	    char *keyName = keyID.data ? BufToHex(&keyID) : PORT_Strdup(name);
   1.932 +	    PR_fprintf(PR_STDERR, "%s: Couldn't find key %s on %s\n",
   1.933 +			progName, keyName, PK11_GetTokenName(slot));
   1.934 +	    PORT_Free(keyName);
   1.935 +	    goto shutdown;
   1.936 +	}
   1.937 +
   1.938 +	wrapKey = FindKey(slot, wrapName, &wrapKeyID, &pwdata);
   1.939 +	if (!wrapKey) {
   1.940 +	    char *keyName = wrapKeyID.data ? BufToHex(&wrapKeyID) 
   1.941 +							: PORT_Strdup(wrapName);
   1.942 +	    PR_fprintf(PR_STDERR, "%s: Couldn't find key %s on %s\n",
   1.943 +			progName, keyName, PK11_GetTokenName(slot));
   1.944 +	    PORT_Free(keyName);
   1.945 +	    PK11_FreeSymKey(symKey);
   1.946 +	    goto shutdown;
   1.947 +	}
   1.948 +
   1.949 +	mechanism = GetWrapMechanism(wrapKey);
   1.950 +	if (mechanism == CKM_INVALID_MECHANISM) {
   1.951 +	    char *keyName = wrapKeyID.data ? BufToHex(&wrapKeyID) 
   1.952 +							: PORT_Strdup(wrapName);
   1.953 +	    PR_fprintf(PR_STDERR, "%s: %s on %s is an invalid wrapping key\n",
   1.954 +			progName, keyName, PK11_GetTokenName(slot));
   1.955 +	    PORT_Free(keyName);
   1.956 +	    PK11_FreeSymKey(symKey);
   1.957 +	    PK11_FreeSymKey(wrapKey);
   1.958 +	    goto shutdown;
   1.959 +	}
   1.960 +
   1.961 +	data.data = buf;
   1.962 +	data.len = sizeof(buf);
   1.963 +	rv = PK11_WrapSymKey(mechanism, NULL,  wrapKey, symKey, &data);
   1.964 +	PK11_FreeSymKey(symKey);
   1.965 +	PK11_FreeSymKey(wrapKey);
   1.966 +	if (rv != SECSuccess) {
   1.967 +	    PR_fprintf(PR_STDERR, "%s: Couldn't wrap key\n",progName);
   1.968 +	    goto shutdown;
   1.969 +	}
   1.970 +
   1.971 +	/* WriteBuf outputs it's own error using SECU_PrintError */
   1.972 +	ret = WriteBuf(symKeyUtil.options[opt_KeyFile].arg, &data);
   1.973 +	if (ret < 0) {
   1.974 +	    goto shutdown;
   1.975 +	}
   1.976 +    }
   1.977 +
   1.978 +    if (symKeyUtil.commands[cmd_ImportKey].activated) {
   1.979 +	PK11SymKey *symKey = PK11_ImportSymKey(slot, keyType,
   1.980 +			 PK11_OriginUnwrap, CKA_ENCRYPT, &key,&pwdata);
   1.981 +	if (!symKey) {
   1.982 +	    PR_fprintf(PR_STDERR, "%s: Import Key Failed\n", progName);
   1.983 +	    goto shutdown;
   1.984 +	}
   1.985 +	if (symKeyUtil.options[opt_Nickname].activated) {
   1.986 +	    rv = PK11_SetSymKeyNickname(symKey, name);
   1.987 +	    if (rv != SECSuccess) {
   1.988 +	        PR_fprintf(PR_STDERR, "%s: Couldn't set name on key\n", 
   1.989 +								progName);
   1.990 +		PK11_DeleteTokenSymKey(symKey);
   1.991 +		PK11_FreeSymKey(symKey);
   1.992 +		goto shutdown;
   1.993 +	    }
   1.994 +	}
   1.995 +	rv = SECSuccess;
   1.996 +	PrintKey(symKey);
   1.997 +	PK11_FreeSymKey(symKey);
   1.998 +    }
   1.999 +
  1.1000 +    /*  List certs (-L)  */
  1.1001 +    if (symKeyUtil.commands[cmd_ListKeys].activated) {
  1.1002 +	int printLabel = 1;
  1.1003 +	if (slot) {
  1.1004 +	    rv = ListKeys(slot,&printLabel,&pwdata);
  1.1005 +	} else {
  1.1006 +	    /* loop over all the slots */
  1.1007 +	    PK11SlotList *slotList = PK11_GetAllTokens(CKM_INVALID_MECHANISM,
  1.1008 +					PR_FALSE, PR_FALSE, &pwdata);
  1.1009 +	    if (slotList == NULL) {
  1.1010 +	        PR_fprintf(PR_STDERR, "%s: No tokens found\n",progName);
  1.1011 +	    } else {
  1.1012 +                PK11SlotListElement *se;
  1.1013 +                for (se = PK11_GetFirstSafe(slotList); se; 
  1.1014 +                                    se=PK11_GetNextSafe(slotList,se, PR_FALSE)) {
  1.1015 +                    rv = ListKeys(se->slot,&printLabel,&pwdata);
  1.1016 +                    if (rv !=SECSuccess) {
  1.1017 +                        break;
  1.1018 +                    }
  1.1019 +                }
  1.1020 +                if (se) {
  1.1021 +                    SECStatus rv2 = PK11_FreeSlotListElement(slotList, se);
  1.1022 +                    PORT_Assert(SECSuccess == rv2);
  1.1023 +                }
  1.1024 +                PK11_FreeSlotList(slotList);
  1.1025 +            }
  1.1026 +	}
  1.1027 +    }
  1.1028 +
  1.1029 +    /*  Move key (-M)  */
  1.1030 +    if (symKeyUtil.commands[cmd_MoveKey].activated) {
  1.1031 +	PK11SlotInfo *target;
  1.1032 +	char *targetName = symKeyUtil.options[opt_TargetToken].arg;
  1.1033 +	PK11SymKey *newKey;
  1.1034 +	PK11SymKey *symKey = FindKey(slot,name,&keyID,&pwdata);
  1.1035 +	char *keyName = PK11_GetSymKeyNickname(symKey);
  1.1036 +
  1.1037 +	if (!symKey) {
  1.1038 +	    char *keyName = keyID.data ? BufToHex(&keyID) : PORT_Strdup(name);
  1.1039 +	    PR_fprintf(PR_STDERR, "%s: Couldn't find key %s on %s\n",
  1.1040 +			progName, keyName, PK11_GetTokenName(slot));
  1.1041 +	    PORT_Free(keyName);
  1.1042 +	    goto shutdown;
  1.1043 +	}
  1.1044 +	target = PK11_FindSlotByName(targetName);
  1.1045 +	if (!target) {
  1.1046 +	    PR_fprintf(PR_STDERR, "%s: Couldn't find slot %s\n",
  1.1047 +			progName, targetName);
  1.1048 +	    goto shutdown;
  1.1049 +	}
  1.1050 +	rv = PK11_Authenticate(target, PR_FALSE, &pwdata);
  1.1051 +	if (rv != SECSuccess) {
  1.1052 +	    PR_fprintf(PR_STDERR, "%s: Failed to log into %s\n",
  1.1053 +			progName, targetName);
  1.1054 +	    goto shutdown;
  1.1055 +	}
  1.1056 +	rv = SECFailure;
  1.1057 +	newKey = PK11_MoveSymKey(target, CKA_ENCRYPT, 0, PR_TRUE, symKey);
  1.1058 +	if (!newKey) {
  1.1059 +	    PR_fprintf(PR_STDERR, "%s: Couldn't move the key \n",progName);
  1.1060 +	    goto shutdown;
  1.1061 +	}
  1.1062 +	if (keyName) {
  1.1063 +	    rv = PK11_SetSymKeyNickname(newKey, keyName);
  1.1064 +	    if (rv != SECSuccess) {
  1.1065 +		PK11_DeleteTokenSymKey(newKey);
  1.1066 +		PK11_FreeSymKey(newKey);
  1.1067 +	        PR_fprintf(PR_STDERR, "%s: Couldn't set nickname on key\n",
  1.1068 +								 progName);
  1.1069 +		goto shutdown;
  1.1070 +	    }
  1.1071 +	}
  1.1072 +	PK11_FreeSymKey(newKey);
  1.1073 +	rv = SECSuccess;
  1.1074 +    }
  1.1075 +
  1.1076 +shutdown:
  1.1077 +    if (rv != SECSuccess) {
  1.1078 +	PR_fprintf(PR_STDERR, "%s: %s\n", progName,
  1.1079 +					SECU_Strerror(PORT_GetError()));
  1.1080 +    }
  1.1081 +
  1.1082 +    if (key.data) {
  1.1083 +	PORT_Free(key.data);
  1.1084 +    }
  1.1085 +
  1.1086 +    if (keyID.data) {
  1.1087 +	PORT_Free(keyID.data);
  1.1088 +    }
  1.1089 +
  1.1090 +    if (slot) {
  1.1091 +	PK11_FreeSlot(slot);
  1.1092 +    }
  1.1093 +
  1.1094 +    if (NSS_Shutdown() != SECSuccess) {
  1.1095 +        exit(1);
  1.1096 +    }
  1.1097 +
  1.1098 +    if (rv == SECSuccess) {
  1.1099 +	return 0;
  1.1100 +    } else {
  1.1101 +	return 255;
  1.1102 +    }
  1.1103 +}
  1.1104 +
  1.1105 +
  1.1106 +

mercurial