security/nss/cmd/symkeyutil/symkeyutil.c

Wed, 31 Dec 2014 06:55:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:55:50 +0100
changeset 2
7e26c7da4463
permissions
-rw-r--r--

Added tag UPSTREAM_283F7C6 for changeset ca08bd8f51b2

michael@0 1 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 2 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 4
michael@0 5 /*
michael@0 6 ** symkeyutil.c
michael@0 7 **
michael@0 8 ** utility for managing symetric keys in the database or the token
michael@0 9 **
michael@0 10 */
michael@0 11
michael@0 12 /*
michael@0 13 * Wish List for this utility:
michael@0 14 * 1) Display and Set the CKA_ operation flags for the key.
michael@0 15 * 2) Modify existing keys
michael@0 16 * 3) Copy keys
michael@0 17 * 4) Read CKA_ID and display for keys.
michael@0 18 * 5) Option to store CKA_ID in a file on key creation.
michael@0 19 * 6) Encrypt, Decrypt, Hash, and Mac with generated keys.
michael@0 20 * 7) Use asymetric keys to wrap and unwrap keys.
michael@0 21 * 8) Derive.
michael@0 22 * 9) PBE keys.
michael@0 23 */
michael@0 24
michael@0 25 #include <stdio.h>
michael@0 26 #include <string.h>
michael@0 27
michael@0 28 #include "secutil.h"
michael@0 29
michael@0 30 #include "nspr.h"
michael@0 31
michael@0 32 #include "pk11func.h"
michael@0 33 #include "secasn1.h"
michael@0 34 #include "cert.h"
michael@0 35 #include "cryptohi.h"
michael@0 36 #include "secoid.h"
michael@0 37 #include "certdb.h"
michael@0 38 #include "nss.h"
michael@0 39
michael@0 40 typedef struct _KeyTypes {
michael@0 41 CK_KEY_TYPE keyType;
michael@0 42 CK_MECHANISM_TYPE mechType;
michael@0 43 CK_MECHANISM_TYPE wrapMech;
michael@0 44 char *label;
michael@0 45 } KeyTypes;
michael@0 46
michael@0 47 static KeyTypes keyArray[] = {
michael@0 48 #ifdef RECOGNIZE_ASYMETRIC_TYPES
michael@0 49 { CKK_RSA, CKM_RSA_PKCS, CKM_RSA_PKCS, "rsa" },
michael@0 50 { CKK_DSA, CKM_DSA, CKM_INVALID_MECHANISM, "dsa" },
michael@0 51 { CKK_DH, CKM_DH_PKCS_DERIVE, CKM_INVALID_MECHANISM, "dh" },
michael@0 52 { CKK_EC, CKM_ECDSA, CKM_INVALID_MECHANISM, "ec" },
michael@0 53 { CKK_X9_42_DH, CKM_X9_42_DH_DERIVE, CKM_INVALID_MECHANISM, "x9.42dh" },
michael@0 54 { CKK_KEA, CKM_KEA_KEY_DERIVE, CKM_INVALID_MECHANISM, "kea" },
michael@0 55 #endif
michael@0 56 { CKK_GENERIC_SECRET, CKM_SHA_1_HMAC, CKM_INVALID_MECHANISM, "generic" },
michael@0 57 { CKK_RC2, CKM_RC2_CBC, CKM_RC2_ECB,"rc2" },
michael@0 58 /* don't define a wrap mech for RC-4 since it's note really safe */
michael@0 59 { CKK_RC4, CKM_RC4, CKM_INVALID_MECHANISM, "rc4" },
michael@0 60 { CKK_DES, CKM_DES_CBC, CKM_DES_ECB,"des" },
michael@0 61 { CKK_DES2, CKM_DES2_KEY_GEN, CKM_DES3_ECB, "des2" },
michael@0 62 { CKK_DES3, CKM_DES3_KEY_GEN, CKM_DES3_ECB, "des3" },
michael@0 63 { CKK_CAST, CKM_CAST_CBC, CKM_CAST_ECB, "cast" },
michael@0 64 { CKK_CAST3, CKM_CAST3_CBC, CKM_CAST3_ECB, "cast3" },
michael@0 65 { CKK_CAST5, CKM_CAST5_CBC, CKM_CAST5_ECB, "cast5" },
michael@0 66 { CKK_CAST128, CKM_CAST128_CBC, CKM_CAST128_ECB, "cast128" },
michael@0 67 { CKK_RC5, CKM_RC5_CBC, CKM_RC5_ECB, "rc5" },
michael@0 68 { CKK_IDEA, CKM_IDEA_CBC, CKM_IDEA_ECB, "idea" },
michael@0 69 { CKK_SKIPJACK, CKM_SKIPJACK_CBC64, CKM_SKIPJACK_WRAP, "skipjack" },
michael@0 70 { CKK_BATON, CKM_BATON_CBC128, CKM_BATON_WRAP, "baton" },
michael@0 71 { CKK_JUNIPER, CKM_JUNIPER_CBC128, CKM_JUNIPER_WRAP, "juniper" },
michael@0 72 { CKK_CDMF, CKM_CDMF_CBC, CKM_CDMF_ECB, "cdmf" },
michael@0 73 { CKK_AES, CKM_AES_CBC, CKM_AES_ECB, "aes" },
michael@0 74 { CKK_CAMELLIA, CKM_CAMELLIA_CBC, CKM_CAMELLIA_ECB, "camellia" },
michael@0 75 };
michael@0 76
michael@0 77 static int keyArraySize = sizeof(keyArray)/sizeof(keyArray[0]);
michael@0 78
michael@0 79 int
michael@0 80 GetLen(PRFileDesc* fd)
michael@0 81 {
michael@0 82 PRFileInfo info;
michael@0 83
michael@0 84 if (PR_SUCCESS != PR_GetOpenFileInfo(fd, &info)) {
michael@0 85 return -1;
michael@0 86 }
michael@0 87
michael@0 88 return info.size;
michael@0 89 }
michael@0 90
michael@0 91 int
michael@0 92 ReadBuf(char *inFile, SECItem *item)
michael@0 93 {
michael@0 94 int len;
michael@0 95 int ret;
michael@0 96 PRFileDesc* fd = PR_Open(inFile, PR_RDONLY, 0);
michael@0 97 if (NULL == fd) {
michael@0 98 SECU_PrintError("symkeyutil", "PR_Open failed");
michael@0 99 return -1;
michael@0 100 }
michael@0 101
michael@0 102 len = GetLen(fd);
michael@0 103 if (len < 0) {
michael@0 104 SECU_PrintError("symkeyutil", "PR_GetOpenFileInfo failed");
michael@0 105 return -1;
michael@0 106 }
michael@0 107 item->data = (unsigned char *)PORT_Alloc(len);
michael@0 108 if (item->data == NULL) {
michael@0 109 fprintf(stderr,"Failed to allocate %d to read file %s\n",len,inFile);
michael@0 110 return -1;
michael@0 111 }
michael@0 112
michael@0 113 ret = PR_Read(fd,item->data,item->len);
michael@0 114 if (ret < 0) {
michael@0 115 SECU_PrintError("symkeyutil", "PR_Read failed");
michael@0 116 PORT_Free(item->data);
michael@0 117 item->data = NULL;
michael@0 118 return -1;
michael@0 119 }
michael@0 120 PR_Close(fd);
michael@0 121 item->len = len;
michael@0 122 return 0;
michael@0 123 }
michael@0 124
michael@0 125 int
michael@0 126 WriteBuf(char *inFile, SECItem *item)
michael@0 127 {
michael@0 128 int ret;
michael@0 129 PRFileDesc* fd = PR_Open(inFile, PR_WRONLY|PR_CREATE_FILE, 0x200);
michael@0 130 if (NULL == fd) {
michael@0 131 SECU_PrintError("symkeyutil", "PR_Open failed");
michael@0 132 return -1;
michael@0 133 }
michael@0 134
michael@0 135 ret = PR_Write(fd,item->data,item->len);
michael@0 136 if (ret < 0) {
michael@0 137 SECU_PrintError("symkeyutil", "PR_Write failed");
michael@0 138 return -1;
michael@0 139 }
michael@0 140 PR_Close(fd);
michael@0 141 return 0;
michael@0 142 }
michael@0 143
michael@0 144 CK_KEY_TYPE
michael@0 145 GetKeyTypeFromString(const char *keyString)
michael@0 146 {
michael@0 147 int i;
michael@0 148 for (i=0; i < keyArraySize; i++) {
michael@0 149 if (PL_strcasecmp(keyString,keyArray[i].label) == 0) {
michael@0 150 return keyArray[i].keyType;
michael@0 151 }
michael@0 152 }
michael@0 153 return (CK_KEY_TYPE)-1;
michael@0 154 }
michael@0 155
michael@0 156 CK_MECHANISM_TYPE
michael@0 157 GetKeyMechFromString(const char *keyString)
michael@0 158 {
michael@0 159 int i;
michael@0 160 for (i=0; i < keyArraySize; i++) {
michael@0 161 if (PL_strcasecmp(keyString,keyArray[i].label) == 0) {
michael@0 162 return keyArray[i].mechType;
michael@0 163 }
michael@0 164 }
michael@0 165 return (CK_MECHANISM_TYPE)-1;
michael@0 166 }
michael@0 167
michael@0 168 const char *
michael@0 169 GetStringFromKeyType(CK_KEY_TYPE type)
michael@0 170 {
michael@0 171 int i;
michael@0 172 for (i=0; i < keyArraySize; i++) {
michael@0 173 if (keyArray[i].keyType == type) {
michael@0 174 return keyArray[i].label;
michael@0 175 }
michael@0 176 }
michael@0 177 return "unmatched";
michael@0 178 }
michael@0 179
michael@0 180 CK_MECHANISM_TYPE
michael@0 181 GetWrapFromKeyType(CK_KEY_TYPE type)
michael@0 182 {
michael@0 183 int i;
michael@0 184 for (i=0; i < keyArraySize; i++) {
michael@0 185 if (keyArray[i].keyType == type) {
michael@0 186 return keyArray[i].wrapMech;
michael@0 187 }
michael@0 188 }
michael@0 189 return CKM_INVALID_MECHANISM;
michael@0 190 }
michael@0 191
michael@0 192 CK_MECHANISM_TYPE
michael@0 193 GetWrapMechanism(PK11SymKey *symKey)
michael@0 194 {
michael@0 195 CK_KEY_TYPE type = PK11_GetSymKeyType(symKey);
michael@0 196
michael@0 197 return GetWrapFromKeyType(type);
michael@0 198 }
michael@0 199
michael@0 200 int
michael@0 201 GetDigit(char c)
michael@0 202 {
michael@0 203 if (c == 0) {
michael@0 204 return -1;
michael@0 205 }
michael@0 206 if (c <= '9' && c >= '0') {
michael@0 207 return c - '0';
michael@0 208 }
michael@0 209 if (c <= 'f' && c >= 'a') {
michael@0 210 return c - 'a' + 0xa;
michael@0 211 }
michael@0 212 if (c <= 'F' && c >= 'A') {
michael@0 213 return c - 'A' + 0xa;
michael@0 214 }
michael@0 215 return -1;
michael@0 216 }
michael@0 217
michael@0 218 char
michael@0 219 ToDigit(unsigned char c)
michael@0 220 {
michael@0 221 c = c & 0xf;
michael@0 222 if (c <= 9) {
michael@0 223 return (char) (c+'0');
michael@0 224 }
michael@0 225 return (char) (c+'a'-0xa);
michael@0 226 }
michael@0 227
michael@0 228 char *
michael@0 229 BufToHex(SECItem *outbuf)
michael@0 230 {
michael@0 231 int len = outbuf->len * 2 +1;
michael@0 232 char *string, *ptr;
michael@0 233 unsigned int i;
michael@0 234
michael@0 235 string = PORT_Alloc(len);
michael@0 236
michael@0 237 ptr = string;
michael@0 238 for (i=0; i < outbuf->len; i++) {
michael@0 239 *ptr++ = ToDigit(outbuf->data[i] >> 4);
michael@0 240 *ptr++ = ToDigit(outbuf->data[i] & 0xf);
michael@0 241 }
michael@0 242 *ptr = 0;
michael@0 243 return string;
michael@0 244 }
michael@0 245
michael@0 246
michael@0 247 int
michael@0 248 HexToBuf(char *inString, SECItem *outbuf)
michael@0 249 {
michael@0 250 int len = strlen(inString);
michael@0 251 int outlen = len+1/2;
michael@0 252 int trueLen = 0;
michael@0 253
michael@0 254 outbuf->data = PORT_Alloc(outlen);
michael@0 255 if (outbuf->data) {
michael@0 256 return -1;
michael@0 257 }
michael@0 258
michael@0 259 while (*inString) {
michael@0 260 int digit1, digit2;
michael@0 261 digit1 = GetDigit(*inString++);
michael@0 262 digit2 = GetDigit(*inString++);
michael@0 263 if ((digit1 == -1) || (digit2 == -1)) {
michael@0 264 PORT_Free(outbuf->data);
michael@0 265 outbuf->data = NULL;
michael@0 266 return -1;
michael@0 267 }
michael@0 268 outbuf->data[trueLen++] = digit1 << 4 | digit2;
michael@0 269 }
michael@0 270 outbuf->len = trueLen;
michael@0 271 return 0;
michael@0 272 }
michael@0 273
michael@0 274 void
michael@0 275 printBuf(unsigned char *data, int len)
michael@0 276 {
michael@0 277 int i;
michael@0 278
michael@0 279 for (i=0; i < len; i++) {
michael@0 280 printf("%02x",data[i]);
michael@0 281 }
michael@0 282 }
michael@0 283
michael@0 284 void
michael@0 285 PrintKey(PK11SymKey *symKey)
michael@0 286 {
michael@0 287 char *name = PK11_GetSymKeyNickname(symKey);
michael@0 288 int len = PK11_GetKeyLength(symKey);
michael@0 289 int strength = PK11_GetKeyStrength(symKey, NULL);
michael@0 290 SECItem *value = NULL;
michael@0 291 CK_KEY_TYPE type = PK11_GetSymKeyType(symKey);
michael@0 292 (void) PK11_ExtractKeyValue(symKey);
michael@0 293
michael@0 294 value = PK11_GetKeyData(symKey);
michael@0 295
michael@0 296 printf("%-20s %3d %4d %10s ", name ? name: " ", len, strength,
michael@0 297 GetStringFromKeyType(type));
michael@0 298 if (value && value->data) {
michael@0 299 printBuf(value->data, value->len);
michael@0 300 } else {
michael@0 301 printf("<restricted>");
michael@0 302 }
michael@0 303 printf("\n");
michael@0 304 }
michael@0 305
michael@0 306 SECStatus
michael@0 307 ListKeys(PK11SlotInfo *slot, int *printLabel, void *pwd) {
michael@0 308 PK11SymKey *keyList;
michael@0 309 SECStatus rv = PK11_Authenticate(slot, PR_FALSE, pwd);
michael@0 310 if (rv != SECSuccess) {
michael@0 311 return rv;;
michael@0 312 }
michael@0 313
michael@0 314 keyList = PK11_ListFixedKeysInSlot(slot, NULL, pwd);
michael@0 315 if (keyList) {
michael@0 316 if (*printLabel) {
michael@0 317 printf(" Name Len Strength Type Data\n");
michael@0 318 *printLabel = 0;
michael@0 319 }
michael@0 320 printf("%s:\n",PK11_GetTokenName(slot));
michael@0 321 }
michael@0 322 while (keyList) {
michael@0 323 PK11SymKey *freeKey = keyList;
michael@0 324 PrintKey(keyList);
michael@0 325 keyList = PK11_GetNextSymKey(keyList);
michael@0 326 PK11_FreeSymKey(freeKey);
michael@0 327 }
michael@0 328 return SECSuccess;
michael@0 329 }
michael@0 330
michael@0 331 PK11SymKey *
michael@0 332 FindKey(PK11SlotInfo *slot, char *name, SECItem *id, void *pwd)
michael@0 333 {
michael@0 334 PK11SymKey *key = NULL;
michael@0 335 SECStatus rv = PK11_Authenticate(slot, PR_FALSE, pwd);
michael@0 336
michael@0 337 if (rv != SECSuccess) {
michael@0 338 return NULL;
michael@0 339 }
michael@0 340
michael@0 341
michael@0 342 if (id->data) {
michael@0 343 key = PK11_FindFixedKey(slot,CKM_INVALID_MECHANISM, id, pwd);
michael@0 344 }
michael@0 345 if (name && !key) {
michael@0 346 key = PK11_ListFixedKeysInSlot(slot,name, pwd);
michael@0 347 }
michael@0 348
michael@0 349 if (key) {
michael@0 350 printf("Found a key\n");
michael@0 351 PrintKey(key);
michael@0 352 }
michael@0 353 return key;
michael@0 354 }
michael@0 355
michael@0 356 PRBool
michael@0 357 IsKeyList(PK11SymKey *symKey)
michael@0 358 {
michael@0 359 return (PRBool) (PK11_GetNextSymKey(symKey) != NULL);
michael@0 360 }
michael@0 361
michael@0 362 void
michael@0 363 FreeKeyList(PK11SymKey *symKey)
michael@0 364 {
michael@0 365 PK11SymKey *next,*current;
michael@0 366
michael@0 367 for (current = symKey; current; current = next) {
michael@0 368 next = PK11_GetNextSymKey(current);
michael@0 369 PK11_FreeSymKey(current);
michael@0 370 }
michael@0 371 return;
michael@0 372 }
michael@0 373
michael@0 374 static void
michael@0 375 Usage(char *progName)
michael@0 376 {
michael@0 377 #define FPS fprintf(stderr,
michael@0 378 FPS "Type %s -H for more detailed descriptions\n", progName);
michael@0 379 FPS "Usage:");
michael@0 380 FPS "\t%s -L [std_opts] [-r]\n", progName);
michael@0 381 FPS "\t%s -K [-n name] -t type [-s size] [-i id |-j id_file] [std_opts]\n", progName);
michael@0 382 FPS "\t%s -D <[-n name | -i id | -j id_file> [std_opts]\n", progName);
michael@0 383 FPS "\t%s -I [-n name] [-t type] [-i id | -j id_file] -k data_file [std_opts]\n", progName);
michael@0 384 FPS "\t%s -E <-nname | -i id | -j id_file> [-t type] -k data_file [-r] [std_opts]\n", progName);
michael@0 385 FPS "\t%s -U [-n name] [-t type] [-i id | -j id_file] -k data_file <wrap_opts> [std_opts]\n", progName);
michael@0 386 FPS "\t%s -W <-n name | -i id | -j id_file> [-t type] -k data_file [-r] <wrap_opts> [std_opts]\n", progName);
michael@0 387 FPS "\t%s -M <-n name | -i id | -j id_file> -g target_token [std_opts]\n", progName);
michael@0 388 FPS "\t\t std_opts -> [-d certdir] [-P dbprefix] [-p password] [-f passwordFile] [-h token]\n");
michael@0 389 FPS "\t\t wrap_opts -> <-w wrap_name | -x wrap_id | -y id_file>\n");
michael@0 390 exit(1);
michael@0 391 }
michael@0 392
michael@0 393 static void LongUsage(char *progName)
michael@0 394 {
michael@0 395 int i;
michael@0 396 FPS "%-15s List all the keys.\n", "-L");
michael@0 397 FPS "%-15s Generate a new key.\n", "-K");
michael@0 398 FPS "%-20s Specify the nickname of the new key\n",
michael@0 399 " -n name");
michael@0 400 FPS "%-20s Specify the id in hex of the new key\n",
michael@0 401 " -i key id");
michael@0 402 FPS "%-20s Specify a file to read the id of the new key\n",
michael@0 403 " -j key id file");
michael@0 404 FPS "%-20s Specify the keyType of the new key\n",
michael@0 405 " -t type");
michael@0 406 FPS "%-20s", " valid types: ");
michael@0 407 for (i=0; i < keyArraySize ; i++) {
michael@0 408 FPS "%s%c", keyArray[i].label, i == keyArraySize-1? '\n':',');
michael@0 409 }
michael@0 410 FPS "%-20s Specify the size of the new key in bytes (required by some types)\n",
michael@0 411 " -s size");
michael@0 412 FPS "%-15s Delete a key.\n", "-D");
michael@0 413 FPS "%-20s Specify the nickname of the key to delete\n",
michael@0 414 " -n name");
michael@0 415 FPS "%-20s Specify the id in hex of the key to delete\n",
michael@0 416 " -i key id");
michael@0 417 FPS "%-20s Specify a file to read the id of the key to delete\n",
michael@0 418 " -j key id file");
michael@0 419 FPS "%-15s Import a new key from a data file.\n", "-I");
michael@0 420 FPS "%-20s Specify the data file to read the key from.\n",
michael@0 421 " -k key file");
michael@0 422 FPS "%-20s Specify the nickname of the new key\n",
michael@0 423 " -n name");
michael@0 424 FPS "%-20s Specify the id in hex of the new key\n",
michael@0 425 " -i key id");
michael@0 426 FPS "%-20s Specify a file to read the id of the new key\n",
michael@0 427 " -j key id file");
michael@0 428 FPS "%-20s Specify the keyType of the new key\n",
michael@0 429 " -t type");
michael@0 430 FPS "%-20s", " valid types: ");
michael@0 431 for (i=0; i < keyArraySize ; i++) {
michael@0 432 FPS "%s%c", keyArray[i].label, i == keyArraySize-1? '\n':',');
michael@0 433 }
michael@0 434 FPS "%-15s Export a key to a data file.\n", "-E");
michael@0 435 FPS "%-20s Specify the data file to write the key to.\n",
michael@0 436 " -k key file");
michael@0 437 FPS "%-20s Specify the nickname of the key to export\n",
michael@0 438 " -n name");
michael@0 439 FPS "%-20s Specify the id in hex of the key to export\n",
michael@0 440 " -i key id");
michael@0 441 FPS "%-20s Specify a file to read the id of the key to export\n",
michael@0 442 " -j key id file");
michael@0 443 FPS "%-15s Move a key to a new token.\n", "-M");
michael@0 444 FPS "%-20s Specify the nickname of the key to move\n",
michael@0 445 " -n name");
michael@0 446 FPS "%-20s Specify the id in hex of the key to move\n",
michael@0 447 " -i key id");
michael@0 448 FPS "%-20s Specify a file to read the id of the key to move\n",
michael@0 449 " -j key id file");
michael@0 450 FPS "%-20s Specify the token to move the key to\n",
michael@0 451 " -g target token");
michael@0 452 FPS "%-15s Unwrap a new key from a data file.\n", "-U");
michael@0 453 FPS "%-20s Specify the data file to read the encrypted key from.\n",
michael@0 454 " -k key file");
michael@0 455 FPS "%-20s Specify the nickname of the new key\n",
michael@0 456 " -n name");
michael@0 457 FPS "%-20s Specify the id in hex of the new key\n",
michael@0 458 " -i key id");
michael@0 459 FPS "%-20s Specify a file to read the id of the new key\n",
michael@0 460 " -j key id file");
michael@0 461 FPS "%-20s Specify the keyType of the new key\n",
michael@0 462 " -t type");
michael@0 463 FPS "%-20s", " valid types: ");
michael@0 464 for (i=0; i < keyArraySize ; i++) {
michael@0 465 FPS "%s%c", keyArray[i].label, i == keyArraySize-1? '\n':',');
michael@0 466 }
michael@0 467 FPS "%-20s Specify the nickname of the wrapping key\n",
michael@0 468 " -w wrap name");
michael@0 469 FPS "%-20s Specify the id in hex of the wrapping key\n",
michael@0 470 " -x wrap key id");
michael@0 471 FPS "%-20s Specify a file to read the id of the wrapping key\n",
michael@0 472 " -y wrap key id file");
michael@0 473 FPS "%-15s Wrap a new key to a data file. [not yet implemented]\n", "-W");
michael@0 474 FPS "%-20s Specify the data file to write the encrypted key to.\n",
michael@0 475 " -k key file");
michael@0 476 FPS "%-20s Specify the nickname of the key to wrap\n",
michael@0 477 " -n name");
michael@0 478 FPS "%-20s Specify the id in hex of the key to wrap\n",
michael@0 479 " -i key id");
michael@0 480 FPS "%-20s Specify a file to read the id of the key to wrap\n",
michael@0 481 " -j key id file");
michael@0 482 FPS "%-20s Specify the nickname of the wrapping key\n",
michael@0 483 " -w wrap name");
michael@0 484 FPS "%-20s Specify the id in hex of the wrapping key\n",
michael@0 485 " -x wrap key id");
michael@0 486 FPS "%-20s Specify a file to read the id of the wrapping key\n",
michael@0 487 " -y wrap key id file");
michael@0 488 FPS "%-15s Options valid for all commands\n", "std_opts");
michael@0 489 FPS "%-20s The directory where the NSS db's reside\n",
michael@0 490 " -d certdir");
michael@0 491 FPS "%-20s Prefix for the NSS db's\n",
michael@0 492 " -P db prefix");
michael@0 493 FPS "%-20s Specify password on the command line\n",
michael@0 494 " -p password");
michael@0 495 FPS "%-20s Specify password file on the command line\n",
michael@0 496 " -f password file");
michael@0 497 FPS "%-20s Specify token to act on\n",
michael@0 498 " -h token");
michael@0 499 exit(1);
michael@0 500 #undef FPS
michael@0 501 }
michael@0 502
michael@0 503 /* Certutil commands */
michael@0 504 enum {
michael@0 505 cmd_CreateNewKey = 0,
michael@0 506 cmd_DeleteKey,
michael@0 507 cmd_ImportKey,
michael@0 508 cmd_ExportKey,
michael@0 509 cmd_WrapKey,
michael@0 510 cmd_UnwrapKey,
michael@0 511 cmd_MoveKey,
michael@0 512 cmd_ListKeys,
michael@0 513 cmd_PrintHelp
michael@0 514 };
michael@0 515
michael@0 516 /* Certutil options */
michael@0 517 enum {
michael@0 518 opt_CertDir = 0,
michael@0 519 opt_PasswordFile,
michael@0 520 opt_TargetToken,
michael@0 521 opt_TokenName,
michael@0 522 opt_KeyID,
michael@0 523 opt_KeyIDFile,
michael@0 524 opt_KeyType,
michael@0 525 opt_Nickname,
michael@0 526 opt_KeyFile,
michael@0 527 opt_Password,
michael@0 528 opt_dbPrefix,
michael@0 529 opt_RW,
michael@0 530 opt_KeySize,
michael@0 531 opt_WrapKeyName,
michael@0 532 opt_WrapKeyID,
michael@0 533 opt_WrapKeyIDFile,
michael@0 534 opt_NoiseFile
michael@0 535 };
michael@0 536
michael@0 537 static secuCommandFlag symKeyUtil_commands[] =
michael@0 538 {
michael@0 539 { /* cmd_CreateNewKey */ 'K', PR_FALSE, 0, PR_FALSE },
michael@0 540 { /* cmd_DeleteKey */ 'D', PR_FALSE, 0, PR_FALSE },
michael@0 541 { /* cmd_ImportKey */ 'I', PR_FALSE, 0, PR_FALSE },
michael@0 542 { /* cmd_ExportKey */ 'E', PR_FALSE, 0, PR_FALSE },
michael@0 543 { /* cmd_WrapKey */ 'W', PR_FALSE, 0, PR_FALSE },
michael@0 544 { /* cmd_UnwrapKey */ 'U', PR_FALSE, 0, PR_FALSE },
michael@0 545 { /* cmd_MoveKey */ 'M', PR_FALSE, 0, PR_FALSE },
michael@0 546 { /* cmd_ListKeys */ 'L', PR_FALSE, 0, PR_FALSE },
michael@0 547 { /* cmd_PrintHelp */ 'H', PR_FALSE, 0, PR_FALSE },
michael@0 548 };
michael@0 549
michael@0 550 static secuCommandFlag symKeyUtil_options[] =
michael@0 551 {
michael@0 552 { /* opt_CertDir */ 'd', PR_TRUE, 0, PR_FALSE },
michael@0 553 { /* opt_PasswordFile */ 'f', PR_TRUE, 0, PR_FALSE },
michael@0 554 { /* opt_TargetToken */ 'g', PR_TRUE, 0, PR_FALSE },
michael@0 555 { /* opt_TokenName */ 'h', PR_TRUE, 0, PR_FALSE },
michael@0 556 { /* opt_KeyID */ 'i', PR_TRUE, 0, PR_FALSE },
michael@0 557 { /* opt_KeyIDFile */ 'j', PR_TRUE, 0, PR_FALSE },
michael@0 558 { /* opt_KeyType */ 't', PR_TRUE, 0, PR_FALSE },
michael@0 559 { /* opt_Nickname */ 'n', PR_TRUE, 0, PR_FALSE },
michael@0 560 { /* opt_KeyFile */ 'k', PR_TRUE, 0, PR_FALSE },
michael@0 561 { /* opt_Password */ 'p', PR_TRUE, 0, PR_FALSE },
michael@0 562 { /* opt_dbPrefix */ 'P', PR_TRUE, 0, PR_FALSE },
michael@0 563 { /* opt_RW */ 'r', PR_FALSE, 0, PR_FALSE },
michael@0 564 { /* opt_KeySize */ 's', PR_TRUE, 0, PR_FALSE },
michael@0 565 { /* opt_WrapKeyName */ 'w', PR_TRUE, 0, PR_FALSE },
michael@0 566 { /* opt_WrapKeyID */ 'x', PR_TRUE, 0, PR_FALSE },
michael@0 567 { /* opt_WrapKeyIDFile */ 'y', PR_TRUE, 0, PR_FALSE },
michael@0 568 { /* opt_NoiseFile */ 'z', PR_TRUE, 0, PR_FALSE },
michael@0 569 };
michael@0 570
michael@0 571 int
michael@0 572 main(int argc, char **argv)
michael@0 573 {
michael@0 574 PK11SlotInfo *slot = NULL;
michael@0 575 char * slotname = "internal";
michael@0 576 char * certPrefix = "";
michael@0 577 CK_MECHANISM_TYPE keyType = CKM_SHA_1_HMAC;
michael@0 578 int keySize = 0;
michael@0 579 char * name = NULL;
michael@0 580 char * wrapName = NULL;
michael@0 581 secuPWData pwdata = { PW_NONE, 0 };
michael@0 582 PRBool readOnly = PR_FALSE;
michael@0 583 SECItem key;
michael@0 584 SECItem keyID;
michael@0 585 SECItem wrapKeyID;
michael@0 586 int commandsEntered = 0;
michael@0 587 int commandToRun = 0;
michael@0 588 char *progName;
michael@0 589 int i;
michael@0 590 SECStatus rv = SECFailure;
michael@0 591
michael@0 592 secuCommand symKeyUtil;
michael@0 593 symKeyUtil.numCommands=sizeof(symKeyUtil_commands)/sizeof(secuCommandFlag);
michael@0 594 symKeyUtil.numOptions=sizeof(symKeyUtil_options)/sizeof(secuCommandFlag);
michael@0 595 symKeyUtil.commands = symKeyUtil_commands;
michael@0 596 symKeyUtil.options = symKeyUtil_options;
michael@0 597
michael@0 598 key.data = NULL; key.len = 0;
michael@0 599 keyID.data = NULL; keyID.len = 0;
michael@0 600 wrapKeyID.data = NULL; wrapKeyID.len = 0;
michael@0 601
michael@0 602 progName = strrchr(argv[0], '/');
michael@0 603 progName = progName ? progName+1 : argv[0];
michael@0 604
michael@0 605 rv = SECU_ParseCommandLine(argc, argv, progName, &symKeyUtil);
michael@0 606
michael@0 607 if (rv != SECSuccess)
michael@0 608 Usage(progName);
michael@0 609
michael@0 610 rv = SECFailure;
michael@0 611
michael@0 612 /* -H print help */
michael@0 613 if (symKeyUtil.commands[cmd_PrintHelp].activated)
michael@0 614 LongUsage(progName);
michael@0 615
michael@0 616 /* -f password file, -p password */
michael@0 617 if (symKeyUtil.options[opt_PasswordFile].arg) {
michael@0 618 pwdata.source = PW_FROMFILE;
michael@0 619 pwdata.data = symKeyUtil.options[opt_PasswordFile].arg;
michael@0 620 } else if (symKeyUtil.options[opt_Password].arg) {
michael@0 621 pwdata.source = PW_PLAINTEXT;
michael@0 622 pwdata.data = symKeyUtil.options[opt_Password].arg;
michael@0 623 }
michael@0 624
michael@0 625 /* -d directory */
michael@0 626 if (symKeyUtil.options[opt_CertDir].activated)
michael@0 627 SECU_ConfigDirectory(symKeyUtil.options[opt_CertDir].arg);
michael@0 628
michael@0 629 /* -s key size */
michael@0 630 if (symKeyUtil.options[opt_KeySize].activated) {
michael@0 631 keySize = PORT_Atoi(symKeyUtil.options[opt_KeySize].arg);
michael@0 632 }
michael@0 633
michael@0 634 /* -h specify token name */
michael@0 635 if (symKeyUtil.options[opt_TokenName].activated) {
michael@0 636 if (PL_strcmp(symKeyUtil.options[opt_TokenName].arg, "all") == 0)
michael@0 637 slotname = NULL;
michael@0 638 else
michael@0 639 slotname = PL_strdup(symKeyUtil.options[opt_TokenName].arg);
michael@0 640 }
michael@0 641
michael@0 642 /* -t key type */
michael@0 643 if (symKeyUtil.options[opt_KeyType].activated) {
michael@0 644 keyType = GetKeyMechFromString(symKeyUtil.options[opt_KeyType].arg);
michael@0 645 if (keyType == (CK_MECHANISM_TYPE)-1) {
michael@0 646 PR_fprintf(PR_STDERR,
michael@0 647 "%s unknown key type (%s).\n",
michael@0 648 progName, symKeyUtil.options[opt_KeyType].arg);
michael@0 649 return 255;
michael@0 650 }
michael@0 651 }
michael@0 652
michael@0 653 /* -k for import and unwrap, it specifies an input file to read from,
michael@0 654 * for export and wrap it specifies an output file to write to */
michael@0 655 if (symKeyUtil.options[opt_KeyFile].activated) {
michael@0 656 if (symKeyUtil.commands[cmd_ImportKey].activated ||
michael@0 657 symKeyUtil.commands[cmd_UnwrapKey].activated ) {
michael@0 658 int ret = ReadBuf(symKeyUtil.options[opt_KeyFile].arg, &key);
michael@0 659 if (ret < 0) {
michael@0 660 PR_fprintf(PR_STDERR,
michael@0 661 "%s Couldn't read key file (%s).\n",
michael@0 662 progName, symKeyUtil.options[opt_KeyFile].arg);
michael@0 663 return 255;
michael@0 664 }
michael@0 665 }
michael@0 666 }
michael@0 667
michael@0 668 /* -i specify the key ID */
michael@0 669 if (symKeyUtil.options[opt_KeyID].activated) {
michael@0 670 int ret = HexToBuf(symKeyUtil.options[opt_KeyID].arg, &keyID);
michael@0 671 if (ret < 0) {
michael@0 672 PR_fprintf(PR_STDERR,
michael@0 673 "%s invalid key ID (%s).\n",
michael@0 674 progName, symKeyUtil.options[opt_KeyID].arg);
michael@0 675 return 255;
michael@0 676 }
michael@0 677 }
michael@0 678
michael@0 679 /* -i & -j are mutually exclusive */
michael@0 680 if ((symKeyUtil.options[opt_KeyID].activated) &&
michael@0 681 (symKeyUtil.options[opt_KeyIDFile].activated)) {
michael@0 682 PR_fprintf(PR_STDERR,
michael@0 683 "%s -i and -j options are mutually exclusive.\n", progName);
michael@0 684 return 255;
michael@0 685 }
michael@0 686
michael@0 687 /* -x specify the Wrap key ID */
michael@0 688 if (symKeyUtil.options[opt_WrapKeyID].activated) {
michael@0 689 int ret = HexToBuf(symKeyUtil.options[opt_WrapKeyID].arg, &wrapKeyID);
michael@0 690 if (ret < 0) {
michael@0 691 PR_fprintf(PR_STDERR,
michael@0 692 "%s invalid key ID (%s).\n",
michael@0 693 progName, symKeyUtil.options[opt_WrapKeyID].arg);
michael@0 694 return 255;
michael@0 695 }
michael@0 696 }
michael@0 697
michael@0 698 /* -x & -y are mutually exclusive */
michael@0 699 if ((symKeyUtil.options[opt_KeyID].activated) &&
michael@0 700 (symKeyUtil.options[opt_KeyIDFile].activated)) {
michael@0 701 PR_fprintf(PR_STDERR,
michael@0 702 "%s -i and -j options are mutually exclusive.\n", progName);
michael@0 703 return 255;
michael@0 704 }
michael@0 705
michael@0 706
michael@0 707 /* -y specify the key ID */
michael@0 708 if (symKeyUtil.options[opt_WrapKeyIDFile].activated) {
michael@0 709 int ret = ReadBuf(symKeyUtil.options[opt_WrapKeyIDFile].arg,
michael@0 710 &wrapKeyID);
michael@0 711 if (ret < 0) {
michael@0 712 PR_fprintf(PR_STDERR,
michael@0 713 "%s Couldn't read key ID file (%s).\n",
michael@0 714 progName, symKeyUtil.options[opt_WrapKeyIDFile].arg);
michael@0 715 return 255;
michael@0 716 }
michael@0 717 }
michael@0 718
michael@0 719 /* -P certdb name prefix */
michael@0 720 if (symKeyUtil.options[opt_dbPrefix].activated)
michael@0 721 certPrefix = symKeyUtil.options[opt_dbPrefix].arg;
michael@0 722
michael@0 723 /* Check number of commands entered. */
michael@0 724 commandsEntered = 0;
michael@0 725 for (i=0; i< symKeyUtil.numCommands; i++) {
michael@0 726 if (symKeyUtil.commands[i].activated) {
michael@0 727 commandToRun = symKeyUtil.commands[i].flag;
michael@0 728 commandsEntered++;
michael@0 729 }
michael@0 730 if (commandsEntered > 1)
michael@0 731 break;
michael@0 732 }
michael@0 733 if (commandsEntered > 1) {
michael@0 734 PR_fprintf(PR_STDERR, "%s: only one command at a time!\n", progName);
michael@0 735 PR_fprintf(PR_STDERR, "You entered: ");
michael@0 736 for (i=0; i< symKeyUtil.numCommands; i++) {
michael@0 737 if (symKeyUtil.commands[i].activated)
michael@0 738 PR_fprintf(PR_STDERR, " -%c", symKeyUtil.commands[i].flag);
michael@0 739 }
michael@0 740 PR_fprintf(PR_STDERR, "\n");
michael@0 741 return 255;
michael@0 742 }
michael@0 743 if (commandsEntered == 0) {
michael@0 744 PR_fprintf(PR_STDERR, "%s: you must enter a command!\n", progName);
michael@0 745 Usage(progName);
michael@0 746 }
michael@0 747
michael@0 748 if (symKeyUtil.commands[cmd_ListKeys].activated ||
michael@0 749 symKeyUtil.commands[cmd_PrintHelp].activated ||
michael@0 750 symKeyUtil.commands[cmd_ExportKey].activated ||
michael@0 751 symKeyUtil.commands[cmd_WrapKey].activated) {
michael@0 752 readOnly = !symKeyUtil.options[opt_RW].activated;
michael@0 753 }
michael@0 754
michael@0 755 if ((symKeyUtil.commands[cmd_ImportKey].activated ||
michael@0 756 symKeyUtil.commands[cmd_ExportKey].activated ||
michael@0 757 symKeyUtil.commands[cmd_WrapKey].activated ||
michael@0 758 symKeyUtil.commands[cmd_UnwrapKey].activated ) &&
michael@0 759 !symKeyUtil.options[opt_KeyFile].activated) {
michael@0 760 PR_fprintf(PR_STDERR,
michael@0 761 "%s -%c: keyfile is required for this command (-k).\n",
michael@0 762 progName, commandToRun);
michael@0 763 return 255;
michael@0 764 }
michael@0 765
michael@0 766 /* -E, -D, -W, and all require -n, -i, or -j to identify the key */
michael@0 767 if ((symKeyUtil.commands[cmd_ExportKey].activated ||
michael@0 768 symKeyUtil.commands[cmd_DeleteKey].activated ||
michael@0 769 symKeyUtil.commands[cmd_WrapKey].activated) &&
michael@0 770 !(symKeyUtil.options[opt_Nickname].activated ||
michael@0 771 symKeyUtil.options[opt_KeyID].activated ||
michael@0 772 symKeyUtil.options[opt_KeyIDFile].activated)) {
michael@0 773 PR_fprintf(PR_STDERR,
michael@0 774 "%s -%c: nickname or id is required for this command (-n, -i, -j).\n",
michael@0 775 progName, commandToRun);
michael@0 776 return 255;
michael@0 777 }
michael@0 778
michael@0 779 /* -W, -U, and all -w, -x, or -y to identify the wrapping key */
michael@0 780 if (( symKeyUtil.commands[cmd_WrapKey].activated ||
michael@0 781 symKeyUtil.commands[cmd_UnwrapKey].activated) &&
michael@0 782 !(symKeyUtil.options[opt_WrapKeyName].activated ||
michael@0 783 symKeyUtil.options[opt_WrapKeyID].activated ||
michael@0 784 symKeyUtil.options[opt_WrapKeyIDFile].activated)) {
michael@0 785 PR_fprintf(PR_STDERR,
michael@0 786 "%s -%c: wrap key is required for this command (-w, -x, or -y).\n",
michael@0 787 progName, commandToRun);
michael@0 788 return 255;
michael@0 789 }
michael@0 790
michael@0 791 /* -M needs the target slot (-g) */
michael@0 792 if (symKeyUtil.commands[cmd_MoveKey].activated &&
michael@0 793 !symKeyUtil.options[opt_TargetToken].activated) {
michael@0 794 PR_fprintf(PR_STDERR,
michael@0 795 "%s -%c: target token is required for this command (-g).\n",
michael@0 796 progName, commandToRun);
michael@0 797 return 255;
michael@0 798 }
michael@0 799
michael@0 800 /* Using slotname == NULL for listing keys and certs on all slots,
michael@0 801 * but only that. */
michael@0 802 if (!(symKeyUtil.commands[cmd_ListKeys].activated) && slotname == NULL) {
michael@0 803 PR_fprintf(PR_STDERR,
michael@0 804 "%s -%c: cannot use \"-h all\" for this command.\n",
michael@0 805 progName, commandToRun);
michael@0 806 return 255;
michael@0 807 }
michael@0 808
michael@0 809 name = SECU_GetOptionArg(&symKeyUtil, opt_Nickname);
michael@0 810 wrapName = SECU_GetOptionArg(&symKeyUtil, opt_WrapKeyName);
michael@0 811
michael@0 812 PK11_SetPasswordFunc(SECU_GetModulePassword);
michael@0 813
michael@0 814 /* Initialize NSPR and NSS. */
michael@0 815 PR_Init(PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1);
michael@0 816 rv = NSS_Initialize(SECU_ConfigDirectory(NULL), certPrefix, certPrefix,
michael@0 817 "secmod.db", readOnly ? NSS_INIT_READONLY: 0);
michael@0 818 if (rv != SECSuccess) {
michael@0 819 SECU_PrintPRandOSError(progName);
michael@0 820 goto shutdown;
michael@0 821 }
michael@0 822 rv = SECFailure;
michael@0 823
michael@0 824 if (PL_strcmp(slotname, "internal") == 0)
michael@0 825 slot = PK11_GetInternalKeySlot();
michael@0 826 else if (slotname != NULL)
michael@0 827 slot = PK11_FindSlotByName(slotname);
michael@0 828
michael@0 829 /* generating a new key */
michael@0 830 if (symKeyUtil.commands[cmd_CreateNewKey].activated) {
michael@0 831 PK11SymKey *symKey;
michael@0 832
michael@0 833 symKey = PK11_TokenKeyGen(slot, keyType, NULL, keySize,
michael@0 834 NULL, PR_TRUE, &pwdata);
michael@0 835 if (!symKey) {
michael@0 836 PR_fprintf(PR_STDERR, "%s: Token Key Gen Failed\n", progName);
michael@0 837 goto shutdown;
michael@0 838 }
michael@0 839 if (symKeyUtil.options[opt_Nickname].activated) {
michael@0 840 rv = PK11_SetSymKeyNickname(symKey, name);
michael@0 841 if (rv != SECSuccess) {
michael@0 842 PK11_DeleteTokenSymKey(symKey);
michael@0 843 PK11_FreeSymKey(symKey);
michael@0 844 PR_fprintf(PR_STDERR, "%s: Couldn't set nickname on key\n",
michael@0 845 progName);
michael@0 846 goto shutdown;
michael@0 847 }
michael@0 848 }
michael@0 849 rv = SECSuccess;
michael@0 850 PrintKey(symKey);
michael@0 851 PK11_FreeSymKey(symKey);
michael@0 852 }
michael@0 853 if (symKeyUtil.commands[cmd_DeleteKey].activated) {
michael@0 854 PK11SymKey *symKey = FindKey(slot,name,&keyID,&pwdata);
michael@0 855
michael@0 856 if (!symKey) {
michael@0 857 char *keyName = keyID.data ? BufToHex(&keyID) : PORT_Strdup(name);
michael@0 858 PR_fprintf(PR_STDERR, "%s: Couldn't find key %s on %s\n",
michael@0 859 progName, keyName, PK11_GetTokenName(slot));
michael@0 860 PORT_Free(keyName);
michael@0 861 goto shutdown;
michael@0 862 }
michael@0 863
michael@0 864 rv = PK11_DeleteTokenSymKey(symKey);
michael@0 865 FreeKeyList(symKey);
michael@0 866 if (rv != SECSuccess) {
michael@0 867 PR_fprintf(PR_STDERR, "%s: Couldn't Delete Key \n", progName);
michael@0 868 goto shutdown;
michael@0 869 }
michael@0 870 }
michael@0 871 if (symKeyUtil.commands[cmd_UnwrapKey].activated) {
michael@0 872 PK11SymKey *wrapKey = FindKey(slot,wrapName,&wrapKeyID,&pwdata);
michael@0 873 PK11SymKey *symKey;
michael@0 874 CK_MECHANISM_TYPE mechanism;
michael@0 875
michael@0 876 if (!wrapKey) {
michael@0 877 char *keyName = wrapKeyID.data ? BufToHex(&wrapKeyID)
michael@0 878 : PORT_Strdup(wrapName);
michael@0 879 PR_fprintf(PR_STDERR, "%s: Couldn't find key %s on %s\n",
michael@0 880 progName, keyName, PK11_GetTokenName(slot));
michael@0 881 PORT_Free(keyName);
michael@0 882 goto shutdown;
michael@0 883 }
michael@0 884 mechanism = GetWrapMechanism(wrapKey);
michael@0 885 if (mechanism == CKM_INVALID_MECHANISM) {
michael@0 886 char *keyName = wrapKeyID.data ? BufToHex(&wrapKeyID)
michael@0 887 : PORT_Strdup(wrapName);
michael@0 888 PR_fprintf(PR_STDERR, "%s: %s on %s is an invalid wrapping key\n",
michael@0 889 progName, keyName, PK11_GetTokenName(slot));
michael@0 890 PORT_Free(keyName);
michael@0 891 PK11_FreeSymKey(wrapKey);
michael@0 892 goto shutdown;
michael@0 893 }
michael@0 894
michael@0 895 symKey = PK11_UnwrapSymKeyWithFlagsPerm(wrapKey, mechanism, NULL,
michael@0 896 &key, keyType, CKA_ENCRYPT, keySize, 0, PR_TRUE);
michael@0 897 PK11_FreeSymKey(wrapKey);
michael@0 898 if (!symKey) {
michael@0 899 PR_fprintf(PR_STDERR, "%s: Unwrap Key Failed\n", progName);
michael@0 900 goto shutdown;
michael@0 901 }
michael@0 902
michael@0 903 if (symKeyUtil.options[opt_Nickname].activated) {
michael@0 904 rv = PK11_SetSymKeyNickname(symKey, name);
michael@0 905 if (rv != SECSuccess) {
michael@0 906 PR_fprintf(PR_STDERR, "%s: Couldn't set name on key\n",
michael@0 907 progName);
michael@0 908 PK11_DeleteTokenSymKey(symKey);
michael@0 909 PK11_FreeSymKey(symKey);
michael@0 910 goto shutdown;
michael@0 911 }
michael@0 912 }
michael@0 913 rv = SECSuccess;
michael@0 914 PrintKey(symKey);
michael@0 915 PK11_FreeSymKey(symKey);
michael@0 916 }
michael@0 917
michael@0 918 #define MAX_KEY_SIZE 4098
michael@0 919 if (symKeyUtil.commands[cmd_WrapKey].activated) {
michael@0 920 PK11SymKey *symKey = FindKey(slot, name, &keyID, &pwdata);
michael@0 921 PK11SymKey *wrapKey;
michael@0 922 CK_MECHANISM_TYPE mechanism;
michael@0 923 SECItem data;
michael@0 924 unsigned char buf[MAX_KEY_SIZE];
michael@0 925 int ret;
michael@0 926
michael@0 927 if (!symKey) {
michael@0 928 char *keyName = keyID.data ? BufToHex(&keyID) : PORT_Strdup(name);
michael@0 929 PR_fprintf(PR_STDERR, "%s: Couldn't find key %s on %s\n",
michael@0 930 progName, keyName, PK11_GetTokenName(slot));
michael@0 931 PORT_Free(keyName);
michael@0 932 goto shutdown;
michael@0 933 }
michael@0 934
michael@0 935 wrapKey = FindKey(slot, wrapName, &wrapKeyID, &pwdata);
michael@0 936 if (!wrapKey) {
michael@0 937 char *keyName = wrapKeyID.data ? BufToHex(&wrapKeyID)
michael@0 938 : PORT_Strdup(wrapName);
michael@0 939 PR_fprintf(PR_STDERR, "%s: Couldn't find key %s on %s\n",
michael@0 940 progName, keyName, PK11_GetTokenName(slot));
michael@0 941 PORT_Free(keyName);
michael@0 942 PK11_FreeSymKey(symKey);
michael@0 943 goto shutdown;
michael@0 944 }
michael@0 945
michael@0 946 mechanism = GetWrapMechanism(wrapKey);
michael@0 947 if (mechanism == CKM_INVALID_MECHANISM) {
michael@0 948 char *keyName = wrapKeyID.data ? BufToHex(&wrapKeyID)
michael@0 949 : PORT_Strdup(wrapName);
michael@0 950 PR_fprintf(PR_STDERR, "%s: %s on %s is an invalid wrapping key\n",
michael@0 951 progName, keyName, PK11_GetTokenName(slot));
michael@0 952 PORT_Free(keyName);
michael@0 953 PK11_FreeSymKey(symKey);
michael@0 954 PK11_FreeSymKey(wrapKey);
michael@0 955 goto shutdown;
michael@0 956 }
michael@0 957
michael@0 958 data.data = buf;
michael@0 959 data.len = sizeof(buf);
michael@0 960 rv = PK11_WrapSymKey(mechanism, NULL, wrapKey, symKey, &data);
michael@0 961 PK11_FreeSymKey(symKey);
michael@0 962 PK11_FreeSymKey(wrapKey);
michael@0 963 if (rv != SECSuccess) {
michael@0 964 PR_fprintf(PR_STDERR, "%s: Couldn't wrap key\n",progName);
michael@0 965 goto shutdown;
michael@0 966 }
michael@0 967
michael@0 968 /* WriteBuf outputs it's own error using SECU_PrintError */
michael@0 969 ret = WriteBuf(symKeyUtil.options[opt_KeyFile].arg, &data);
michael@0 970 if (ret < 0) {
michael@0 971 goto shutdown;
michael@0 972 }
michael@0 973 }
michael@0 974
michael@0 975 if (symKeyUtil.commands[cmd_ImportKey].activated) {
michael@0 976 PK11SymKey *symKey = PK11_ImportSymKey(slot, keyType,
michael@0 977 PK11_OriginUnwrap, CKA_ENCRYPT, &key,&pwdata);
michael@0 978 if (!symKey) {
michael@0 979 PR_fprintf(PR_STDERR, "%s: Import Key Failed\n", progName);
michael@0 980 goto shutdown;
michael@0 981 }
michael@0 982 if (symKeyUtil.options[opt_Nickname].activated) {
michael@0 983 rv = PK11_SetSymKeyNickname(symKey, name);
michael@0 984 if (rv != SECSuccess) {
michael@0 985 PR_fprintf(PR_STDERR, "%s: Couldn't set name on key\n",
michael@0 986 progName);
michael@0 987 PK11_DeleteTokenSymKey(symKey);
michael@0 988 PK11_FreeSymKey(symKey);
michael@0 989 goto shutdown;
michael@0 990 }
michael@0 991 }
michael@0 992 rv = SECSuccess;
michael@0 993 PrintKey(symKey);
michael@0 994 PK11_FreeSymKey(symKey);
michael@0 995 }
michael@0 996
michael@0 997 /* List certs (-L) */
michael@0 998 if (symKeyUtil.commands[cmd_ListKeys].activated) {
michael@0 999 int printLabel = 1;
michael@0 1000 if (slot) {
michael@0 1001 rv = ListKeys(slot,&printLabel,&pwdata);
michael@0 1002 } else {
michael@0 1003 /* loop over all the slots */
michael@0 1004 PK11SlotList *slotList = PK11_GetAllTokens(CKM_INVALID_MECHANISM,
michael@0 1005 PR_FALSE, PR_FALSE, &pwdata);
michael@0 1006 if (slotList == NULL) {
michael@0 1007 PR_fprintf(PR_STDERR, "%s: No tokens found\n",progName);
michael@0 1008 } else {
michael@0 1009 PK11SlotListElement *se;
michael@0 1010 for (se = PK11_GetFirstSafe(slotList); se;
michael@0 1011 se=PK11_GetNextSafe(slotList,se, PR_FALSE)) {
michael@0 1012 rv = ListKeys(se->slot,&printLabel,&pwdata);
michael@0 1013 if (rv !=SECSuccess) {
michael@0 1014 break;
michael@0 1015 }
michael@0 1016 }
michael@0 1017 if (se) {
michael@0 1018 SECStatus rv2 = PK11_FreeSlotListElement(slotList, se);
michael@0 1019 PORT_Assert(SECSuccess == rv2);
michael@0 1020 }
michael@0 1021 PK11_FreeSlotList(slotList);
michael@0 1022 }
michael@0 1023 }
michael@0 1024 }
michael@0 1025
michael@0 1026 /* Move key (-M) */
michael@0 1027 if (symKeyUtil.commands[cmd_MoveKey].activated) {
michael@0 1028 PK11SlotInfo *target;
michael@0 1029 char *targetName = symKeyUtil.options[opt_TargetToken].arg;
michael@0 1030 PK11SymKey *newKey;
michael@0 1031 PK11SymKey *symKey = FindKey(slot,name,&keyID,&pwdata);
michael@0 1032 char *keyName = PK11_GetSymKeyNickname(symKey);
michael@0 1033
michael@0 1034 if (!symKey) {
michael@0 1035 char *keyName = keyID.data ? BufToHex(&keyID) : PORT_Strdup(name);
michael@0 1036 PR_fprintf(PR_STDERR, "%s: Couldn't find key %s on %s\n",
michael@0 1037 progName, keyName, PK11_GetTokenName(slot));
michael@0 1038 PORT_Free(keyName);
michael@0 1039 goto shutdown;
michael@0 1040 }
michael@0 1041 target = PK11_FindSlotByName(targetName);
michael@0 1042 if (!target) {
michael@0 1043 PR_fprintf(PR_STDERR, "%s: Couldn't find slot %s\n",
michael@0 1044 progName, targetName);
michael@0 1045 goto shutdown;
michael@0 1046 }
michael@0 1047 rv = PK11_Authenticate(target, PR_FALSE, &pwdata);
michael@0 1048 if (rv != SECSuccess) {
michael@0 1049 PR_fprintf(PR_STDERR, "%s: Failed to log into %s\n",
michael@0 1050 progName, targetName);
michael@0 1051 goto shutdown;
michael@0 1052 }
michael@0 1053 rv = SECFailure;
michael@0 1054 newKey = PK11_MoveSymKey(target, CKA_ENCRYPT, 0, PR_TRUE, symKey);
michael@0 1055 if (!newKey) {
michael@0 1056 PR_fprintf(PR_STDERR, "%s: Couldn't move the key \n",progName);
michael@0 1057 goto shutdown;
michael@0 1058 }
michael@0 1059 if (keyName) {
michael@0 1060 rv = PK11_SetSymKeyNickname(newKey, keyName);
michael@0 1061 if (rv != SECSuccess) {
michael@0 1062 PK11_DeleteTokenSymKey(newKey);
michael@0 1063 PK11_FreeSymKey(newKey);
michael@0 1064 PR_fprintf(PR_STDERR, "%s: Couldn't set nickname on key\n",
michael@0 1065 progName);
michael@0 1066 goto shutdown;
michael@0 1067 }
michael@0 1068 }
michael@0 1069 PK11_FreeSymKey(newKey);
michael@0 1070 rv = SECSuccess;
michael@0 1071 }
michael@0 1072
michael@0 1073 shutdown:
michael@0 1074 if (rv != SECSuccess) {
michael@0 1075 PR_fprintf(PR_STDERR, "%s: %s\n", progName,
michael@0 1076 SECU_Strerror(PORT_GetError()));
michael@0 1077 }
michael@0 1078
michael@0 1079 if (key.data) {
michael@0 1080 PORT_Free(key.data);
michael@0 1081 }
michael@0 1082
michael@0 1083 if (keyID.data) {
michael@0 1084 PORT_Free(keyID.data);
michael@0 1085 }
michael@0 1086
michael@0 1087 if (slot) {
michael@0 1088 PK11_FreeSlot(slot);
michael@0 1089 }
michael@0 1090
michael@0 1091 if (NSS_Shutdown() != SECSuccess) {
michael@0 1092 exit(1);
michael@0 1093 }
michael@0 1094
michael@0 1095 if (rv == SECSuccess) {
michael@0 1096 return 0;
michael@0 1097 } else {
michael@0 1098 return 255;
michael@0 1099 }
michael@0 1100 }
michael@0 1101
michael@0 1102
michael@0 1103

mercurial