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