1 /* ***** BEGIN LICENSE BLOCK *****
2 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 * The contents of this file are subject to the Mozilla Public License Version
5 * 1.1 (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 * http://www.mozilla.org/MPL/
9 * Software distributed under the License is distributed on an "AS IS" basis,
10 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11 * for the specific language governing rights and limitations under the
14 * The Original Code is the Netscape security libraries.
16 * The Initial Developer of the Original Code is
17 * Netscape Communications Corporation.
18 * Portions created by the Initial Developer are Copyright (C) 1994-2000
19 * the Initial Developer. All Rights Reserved.
23 * Alternatively, the contents of this file may be used under the terms of
24 * either the GNU General Public License Version 2 or later (the "GPL"), or
25 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
26 * in which case the provisions of the GPL or the LGPL are applicable instead
27 * of those above. If you wish to allow use of your version of this file only
28 * under the terms of either the GPL or the LGPL, and not to allow others to
29 * use your version of this file under the terms of the MPL, indicate your
30 * decision by deleting the provisions above and replace them with the notice
31 * and other provisions required by the GPL or the LGPL. If you do not delete
32 * the provisions above, a recipient may use your version of this file under
33 * the terms of any one of the MPL, the GPL or the LGPL.
35 * ***** END LICENSE BLOCK ***** */
40 ** utility for managing symetric keys in the database or the token
45 * Wish List for this utility:
46 * 1) Display and Set the CKA_ operation flags for the key.
47 * 2) Modify existing keys
49 * 4) Read CKA_ID and display for keys.
50 * 5) Option to store CKA_ID in a file on key creation.
51 * 6) Encrypt, Decrypt, Hash, and Mac with generated keys.
52 * 7) Use asymetric keys to wrap and unwrap keys.
72 typedef struct _KeyTypes
{
74 CK_MECHANISM_TYPE mechType
;
75 CK_MECHANISM_TYPE wrapMech
;
79 static KeyTypes keyArray
[] = {
80 #ifdef RECOGNIZE_ASYMETRIC_TYPES
81 { CKK_RSA
, CKM_RSA_PKCS
, CKM_RSA_PKCS
, "rsa" },
82 { CKK_DSA
, CKM_DSA
, CKM_INVALID_MECHANISM
, "dsa" },
83 { CKK_DH
, CKM_DH_PKCS_DERIVE
, CKM_INVALID_MECHANISM
, "dh" },
84 { CKK_EC
, CKM_ECDSA
, CKM_INVALID_MECHANISM
, "ec" },
85 { CKK_X9_42_DH
, CKM_X9_42_DH_DERIVE
, CKM_INVALID_MECHANISM
, "x9.42dh" },
86 { CKK_KEA
, CKM_KEA_KEY_DERIVE
, CKM_INVALID_MECHANISM
, "kea" },
88 { CKK_GENERIC_SECRET
, CKM_SHA_1_HMAC
, CKM_INVALID_MECHANISM
, "generic" },
89 { CKK_RC2
, CKM_RC2_CBC
, CKM_RC2_ECB
,"rc2" },
90 /* don't define a wrap mech for RC-4 since it's note really safe */
91 { CKK_RC4
, CKM_RC4
, CKM_INVALID_MECHANISM
, "rc4" },
92 { CKK_DES
, CKM_DES_CBC
, CKM_DES_ECB
,"des" },
93 { CKK_DES2
, CKM_DES2_KEY_GEN
, CKM_DES3_ECB
, "des2" },
94 { CKK_DES3
, CKM_DES3_KEY_GEN
, CKM_DES3_ECB
, "des3" },
95 { CKK_CAST
, CKM_CAST_CBC
, CKM_CAST_ECB
, "cast" },
96 { CKK_CAST3
, CKM_CAST3_CBC
, CKM_CAST3_ECB
, "cast3" },
97 { CKK_CAST5
, CKM_CAST5_CBC
, CKM_CAST5_ECB
, "cast5" },
98 { CKK_CAST128
, CKM_CAST128_CBC
, CKM_CAST128_ECB
, "cast128" },
99 { CKK_RC5
, CKM_RC5_CBC
, CKM_RC5_ECB
, "rc5" },
100 { CKK_IDEA
, CKM_IDEA_CBC
, CKM_IDEA_ECB
, "idea" },
101 { CKK_SKIPJACK
, CKM_SKIPJACK_CBC64
, CKM_SKIPJACK_WRAP
, "skipjack" },
102 { CKK_BATON
, CKM_BATON_CBC128
, CKM_BATON_WRAP
, "baton" },
103 { CKK_JUNIPER
, CKM_JUNIPER_CBC128
, CKM_JUNIPER_WRAP
, "juniper" },
104 { CKK_CDMF
, CKM_CDMF_CBC
, CKM_CDMF_ECB
, "cdmf" },
105 { CKK_AES
, CKM_AES_CBC
, CKM_AES_ECB
, "aes" },
106 { CKK_CAMELLIA
, CKM_CAMELLIA_CBC
, CKM_CAMELLIA_ECB
, "camellia" },
109 static int keyArraySize
= sizeof(keyArray
)/sizeof(keyArray
[0]);
112 GetLen(PRFileDesc
* fd
)
116 if (PR_SUCCESS
!= PR_GetOpenFileInfo(fd
, &info
)) {
124 ReadBuf(char *inFile
, SECItem
*item
)
128 PRFileDesc
* fd
= PR_Open(inFile
, PR_RDONLY
, 0);
130 SECU_PrintError("symkeyutil", "PR_Open failed");
136 SECU_PrintError("symkeyutil", "PR_GetOpenFileInfo failed");
139 item
->data
= (unsigned char *)PORT_Alloc(len
);
140 if (item
->data
== NULL
) {
141 fprintf(stderr
,"Failed to allocate %d to read file %s\n",len
,inFile
);
145 ret
= PR_Read(fd
,item
->data
,item
->len
);
147 SECU_PrintError("symkeyutil", "PR_Read failed");
148 PORT_Free(item
->data
);
158 WriteBuf(char *inFile
, SECItem
*item
)
161 PRFileDesc
* fd
= PR_Open(inFile
, PR_WRONLY
|PR_CREATE_FILE
, 0x200);
163 SECU_PrintError("symkeyutil", "PR_Open failed");
167 ret
= PR_Write(fd
,item
->data
,item
->len
);
169 SECU_PrintError("symkeyutil", "PR_Write failed");
177 GetKeyTypeFromString(const char *keyString
)
180 for (i
=0; i
< keyArraySize
; i
++) {
181 if (PL_strcasecmp(keyString
,keyArray
[i
].label
) == 0) {
182 return keyArray
[i
].keyType
;
185 return (CK_KEY_TYPE
)-1;
189 GetKeyMechFromString(const char *keyString
)
192 for (i
=0; i
< keyArraySize
; i
++) {
193 if (PL_strcasecmp(keyString
,keyArray
[i
].label
) == 0) {
194 return keyArray
[i
].mechType
;
197 return (CK_MECHANISM_TYPE
)-1;
201 GetStringFromKeyType(CK_KEY_TYPE type
)
204 for (i
=0; i
< keyArraySize
; i
++) {
205 if (keyArray
[i
].keyType
== type
) {
206 return keyArray
[i
].label
;
213 GetWrapFromKeyType(CK_KEY_TYPE type
)
216 for (i
=0; i
< keyArraySize
; i
++) {
217 if (keyArray
[i
].keyType
== type
) {
218 return keyArray
[i
].wrapMech
;
221 return CKM_INVALID_MECHANISM
;
225 GetWrapMechanism(PK11SymKey
*symKey
)
227 CK_KEY_TYPE type
= PK11_GetSymKeyType(symKey
);
229 return GetWrapFromKeyType(type
);
238 if (c
<= '9' && c
>= '0') {
241 if (c
<= 'f' && c
>= 'a') {
242 return c
- 'a' + 0xa;
244 if (c
<= 'F' && c
>= 'A') {
245 return c
- 'A' + 0xa;
251 ToDigit(unsigned char c
)
255 return (char) (c
+'0');
257 return (char) (c
+'a'-0xa);
261 BufToHex(SECItem
*outbuf
)
263 int len
= outbuf
->len
* 2 +1;
267 string
= PORT_Alloc(len
);
270 for (i
=0; i
< outbuf
->len
; i
++) {
271 *ptr
++ = ToDigit(outbuf
->data
[i
] >> 4);
272 *ptr
++ = ToDigit(outbuf
->data
[i
] & 0xf);
280 HexToBuf(char *inString
, SECItem
*outbuf
)
282 int len
= strlen(inString
);
283 int outlen
= len
+1/2;
286 outbuf
->data
= PORT_Alloc(outlen
);
293 digit1
= GetDigit(*inString
++);
294 digit2
= GetDigit(*inString
++);
295 if ((digit1
== -1) || (digit2
== -1)) {
296 PORT_Free(outbuf
->data
);
300 outbuf
->data
[trueLen
++] = digit1
<< 4 | digit2
;
302 outbuf
->len
= trueLen
;
307 printBuf(unsigned char *data
, int len
)
311 for (i
=0; i
< len
; i
++) {
312 printf("%02x",data
[i
]);
317 PrintKey(PK11SymKey
*symKey
)
319 char *name
= PK11_GetSymKeyNickname(symKey
);
320 int len
= PK11_GetKeyLength(symKey
);
321 int strength
= PK11_GetKeyStrength(symKey
, NULL
);
322 SECItem
*value
= NULL
;
323 CK_KEY_TYPE type
= PK11_GetSymKeyType(symKey
);
324 (void) PK11_ExtractKeyValue(symKey
);
326 value
= PK11_GetKeyData(symKey
);
328 printf("%-20s %3d %4d %10s ", name
? name
: " ", len
, strength
,
329 GetStringFromKeyType(type
));
330 if (value
&& value
->data
) {
331 printBuf(value
->data
, value
->len
);
333 printf("<restricted>");
339 ListKeys(PK11SlotInfo
*slot
, int *printLabel
, void *pwd
) {
341 SECStatus rv
= PK11_Authenticate(slot
, PR_FALSE
, pwd
);
342 if (rv
!= SECSuccess
) {
346 keyList
= PK11_ListFixedKeysInSlot(slot
, NULL
, pwd
);
349 printf(" Name Len Strength Type Data\n");
352 printf("%s:\n",PK11_GetTokenName(slot
));
355 PK11SymKey
*freeKey
= keyList
;
357 keyList
= PK11_GetNextSymKey(keyList
);
358 PK11_FreeSymKey(freeKey
);
364 FindKey(PK11SlotInfo
*slot
, char *name
, SECItem
*id
, void *pwd
)
366 PK11SymKey
*key
= NULL
;
367 SECStatus rv
= PK11_Authenticate(slot
, PR_FALSE
, pwd
);
369 if (rv
!= SECSuccess
) {
375 key
= PK11_FindFixedKey(slot
,CKM_INVALID_MECHANISM
, id
, pwd
);
378 key
= PK11_ListFixedKeysInSlot(slot
,name
, pwd
);
382 printf("Found a key\n");
389 IsKeyList(PK11SymKey
*symKey
)
391 return (PRBool
) (PK11_GetNextSymKey(symKey
) != NULL
);
395 FreeKeyList(PK11SymKey
*symKey
)
397 PK11SymKey
*next
,*current
;
399 for (current
= symKey
; current
; current
= next
) {
400 next
= PK11_GetNextSymKey(current
);
401 PK11_FreeSymKey(current
);
407 Usage(char *progName
)
409 #define FPS fprintf(stderr,
410 FPS
"Type %s -H for more detailed descriptions\n", progName
);
412 FPS
"\t%s -L [std_opts] [-r]\n", progName
);
413 FPS
"\t%s -K [-n name] -t type [-s size] [-i id |-j id_file] [std_opts]\n", progName
);
414 FPS
"\t%s -D <[-n name | -i id | -j id_file> [std_opts]\n", progName
);
415 FPS
"\t%s -I [-n name] [-t type] [-i id | -j id_file] -k data_file [std_opts]\n", progName
);
416 FPS
"\t%s -E <-nname | -i id | -j id_file> [-t type] -k data_file [-r] [std_opts]\n", progName
);
417 FPS
"\t%s -U [-n name] [-t type] [-i id | -j id_file] -k data_file <wrap_opts> [std_opts]\n", progName
);
418 FPS
"\t%s -W <-n name | -i id | -j id_file> [-t type] -k data_file [-r] <wrap_opts> [std_opts]\n", progName
);
419 FPS
"\t%s -M <-n name | -i id | -j id_file> -g target_token [std_opts]\n", progName
);
420 FPS
"\t\t std_opts -> [-d certdir] [-P dbprefix] [-p password] [-f passwordFile] [-h token]\n");
421 FPS
"\t\t wrap_opts -> <-w wrap_name | -x wrap_id | -y id_file>\n");
425 static void LongUsage(char *progName
)
428 FPS
"%-15s List all the keys.\n", "-L");
429 FPS
"%-15s Generate a new key.\n", "-K");
430 FPS
"%-20s Specify the nickname of the new key\n",
432 FPS
"%-20s Specify the id in hex of the new key\n",
434 FPS
"%-20s Specify a file to read the id of the new key\n",
436 FPS
"%-20s Specify the keyType of the new key\n",
438 FPS
"%-20s", " valid types: ");
439 for (i
=0; i
< keyArraySize
; i
++) {
440 FPS
"%s%c", keyArray
[i
].label
, i
== keyArraySize
-1? '\n':',');
442 FPS
"%-20s Specify the size of the new key in bytes (required by some types)\n",
444 FPS
"%-15s Delete a key.\n", "-D");
445 FPS
"%-20s Specify the nickname of the key to delete\n",
447 FPS
"%-20s Specify the id in hex of the key to delete\n",
449 FPS
"%-20s Specify a file to read the id of the key to delete\n",
451 FPS
"%-15s Import a new key from a data file.\n", "-I");
452 FPS
"%-20s Specify the data file to read the key from.\n",
454 FPS
"%-20s Specify the nickname of the new key\n",
456 FPS
"%-20s Specify the id in hex of the new key\n",
458 FPS
"%-20s Specify a file to read the id of the new key\n",
460 FPS
"%-20s Specify the keyType of the new key\n",
462 FPS
"%-20s", " valid types: ");
463 for (i
=0; i
< keyArraySize
; i
++) {
464 FPS
"%s%c", keyArray
[i
].label
, i
== keyArraySize
-1? '\n':',');
466 FPS
"%-15s Export a key to a data file.\n", "-E");
467 FPS
"%-20s Specify the data file to write the key to.\n",
469 FPS
"%-20s Specify the nickname of the key to export\n",
471 FPS
"%-20s Specify the id in hex of the key to export\n",
473 FPS
"%-20s Specify a file to read the id of the key to export\n",
475 FPS
"%-15s Move a key to a new token.\n", "-M");
476 FPS
"%-20s Specify the nickname of the key to move\n",
478 FPS
"%-20s Specify the id in hex of the key to move\n",
480 FPS
"%-20s Specify a file to read the id of the key to move\n",
482 FPS
"%-20s Specify the token to move the key to\n",
484 FPS
"%-15s Unwrap a new key from a data file.\n", "-U");
485 FPS
"%-20s Specify the data file to read the encrypted key from.\n",
487 FPS
"%-20s Specify the nickname of the new key\n",
489 FPS
"%-20s Specify the id in hex of the new key\n",
491 FPS
"%-20s Specify a file to read the id of the new key\n",
493 FPS
"%-20s Specify the keyType of the new key\n",
495 FPS
"%-20s", " valid types: ");
496 for (i
=0; i
< keyArraySize
; i
++) {
497 FPS
"%s%c", keyArray
[i
].label
, i
== keyArraySize
-1? '\n':',');
499 FPS
"%-20s Specify the nickname of the wrapping key\n",
501 FPS
"%-20s Specify the id in hex of the wrapping key\n",
503 FPS
"%-20s Specify a file to read the id of the wrapping key\n",
504 " -y wrap key id file");
505 FPS
"%-15s Wrap a new key to a data file. [not yet implemented]\n", "-W");
506 FPS
"%-20s Specify the data file to write the encrypted key to.\n",
508 FPS
"%-20s Specify the nickname of the key to wrap\n",
510 FPS
"%-20s Specify the id in hex of the key to wrap\n",
512 FPS
"%-20s Specify a file to read the id of the key to wrap\n",
514 FPS
"%-20s Specify the nickname of the wrapping key\n",
516 FPS
"%-20s Specify the id in hex of the wrapping key\n",
518 FPS
"%-20s Specify a file to read the id of the wrapping key\n",
519 " -y wrap key id file");
520 FPS
"%-15s Options valid for all commands\n", "std_opts");
521 FPS
"%-20s The directory where the NSS db's reside\n",
523 FPS
"%-20s Prefix for the NSS db's\n",
525 FPS
"%-20s Specify password on the command line\n",
527 FPS
"%-20s Specify password file on the command line\n",
528 " -f password file");
529 FPS
"%-20s Specify token to act on\n",
535 /* Certutil commands */
537 cmd_CreateNewKey
= 0,
548 /* Certutil options */
569 static secuCommandFlag symKeyUtil_commands
[] =
571 { /* cmd_CreateNewKey */ 'K', PR_FALSE
, 0, PR_FALSE
},
572 { /* cmd_DeleteKey */ 'D', PR_FALSE
, 0, PR_FALSE
},
573 { /* cmd_ImportKey */ 'I', PR_FALSE
, 0, PR_FALSE
},
574 { /* cmd_ExportKey */ 'E', PR_FALSE
, 0, PR_FALSE
},
575 { /* cmd_WrapKey */ 'W', PR_FALSE
, 0, PR_FALSE
},
576 { /* cmd_UnwrapKey */ 'U', PR_FALSE
, 0, PR_FALSE
},
577 { /* cmd_MoveKey */ 'M', PR_FALSE
, 0, PR_FALSE
},
578 { /* cmd_ListKeys */ 'L', PR_FALSE
, 0, PR_FALSE
},
579 { /* cmd_PrintHelp */ 'H', PR_FALSE
, 0, PR_FALSE
},
582 static secuCommandFlag symKeyUtil_options
[] =
584 { /* opt_CertDir */ 'd', PR_TRUE
, 0, PR_FALSE
},
585 { /* opt_PasswordFile */ 'f', PR_TRUE
, 0, PR_FALSE
},
586 { /* opt_TargetToken */ 'g', PR_TRUE
, 0, PR_FALSE
},
587 { /* opt_TokenName */ 'h', PR_TRUE
, 0, PR_FALSE
},
588 { /* opt_KeyID */ 'i', PR_TRUE
, 0, PR_FALSE
},
589 { /* opt_KeyIDFile */ 'j', PR_TRUE
, 0, PR_FALSE
},
590 { /* opt_KeyType */ 't', PR_TRUE
, 0, PR_FALSE
},
591 { /* opt_Nickname */ 'n', PR_TRUE
, 0, PR_FALSE
},
592 { /* opt_KeyFile */ 'k', PR_TRUE
, 0, PR_FALSE
},
593 { /* opt_Password */ 'p', PR_TRUE
, 0, PR_FALSE
},
594 { /* opt_dbPrefix */ 'P', PR_TRUE
, 0, PR_FALSE
},
595 { /* opt_RW */ 'r', PR_FALSE
, 0, PR_FALSE
},
596 { /* opt_KeySize */ 's', PR_TRUE
, 0, PR_FALSE
},
597 { /* opt_WrapKeyName */ 'w', PR_TRUE
, 0, PR_FALSE
},
598 { /* opt_WrapKeyID */ 'x', PR_TRUE
, 0, PR_FALSE
},
599 { /* opt_WrapKeyIDFile */ 'y', PR_TRUE
, 0, PR_FALSE
},
600 { /* opt_NoiseFile */ 'z', PR_TRUE
, 0, PR_FALSE
},
604 main(int argc
, char **argv
)
606 PK11SlotInfo
*slot
= NULL
;
607 char * slotname
= "internal";
608 char * certPrefix
= "";
609 CK_MECHANISM_TYPE keyType
= CKM_SHA_1_HMAC
;
612 char * wrapName
= NULL
;
613 secuPWData pwdata
= { PW_NONE
, 0 };
614 PRBool readOnly
= PR_FALSE
;
618 int commandsEntered
= 0;
619 int commandToRun
= 0;
622 SECStatus rv
= SECFailure
;
624 secuCommand symKeyUtil
;
625 symKeyUtil
.numCommands
=sizeof(symKeyUtil_commands
)/sizeof(secuCommandFlag
);
626 symKeyUtil
.numOptions
=sizeof(symKeyUtil_options
)/sizeof(secuCommandFlag
);
627 symKeyUtil
.commands
= symKeyUtil_commands
;
628 symKeyUtil
.options
= symKeyUtil_options
;
630 key
.data
= NULL
; key
.len
= 0;
631 keyID
.data
= NULL
; keyID
.len
= 0;
632 wrapKeyID
.data
= NULL
; wrapKeyID
.len
= 0;
634 progName
= strrchr(argv
[0], '/');
635 progName
= progName
? progName
+1 : argv
[0];
637 rv
= SECU_ParseCommandLine(argc
, argv
, progName
, &symKeyUtil
);
639 if (rv
!= SECSuccess
)
645 if (symKeyUtil
.commands
[cmd_PrintHelp
].activated
)
648 /* -f password file, -p password */
649 if (symKeyUtil
.options
[opt_PasswordFile
].arg
) {
650 pwdata
.source
= PW_FROMFILE
;
651 pwdata
.data
= symKeyUtil
.options
[opt_PasswordFile
].arg
;
652 } else if (symKeyUtil
.options
[opt_Password
].arg
) {
653 pwdata
.source
= PW_PLAINTEXT
;
654 pwdata
.data
= symKeyUtil
.options
[opt_Password
].arg
;
658 if (symKeyUtil
.options
[opt_CertDir
].activated
)
659 SECU_ConfigDirectory(symKeyUtil
.options
[opt_CertDir
].arg
);
662 if (symKeyUtil
.options
[opt_KeySize
].activated
) {
663 keySize
= PORT_Atoi(symKeyUtil
.options
[opt_KeySize
].arg
);
666 /* -h specify token name */
667 if (symKeyUtil
.options
[opt_TokenName
].activated
) {
668 if (PL_strcmp(symKeyUtil
.options
[opt_TokenName
].arg
, "all") == 0)
671 slotname
= PL_strdup(symKeyUtil
.options
[opt_TokenName
].arg
);
675 if (symKeyUtil
.options
[opt_KeyType
].activated
) {
676 keyType
= GetKeyMechFromString(symKeyUtil
.options
[opt_KeyType
].arg
);
677 if (keyType
== (CK_MECHANISM_TYPE
)-1) {
678 PR_fprintf(PR_STDERR
,
679 "%s unknown key type (%s).\n",
680 progName
, symKeyUtil
.options
[opt_KeyType
].arg
);
685 /* -k for import and unwrap, it specifies an input file to read from,
686 * for export and wrap it specifies an output file to write to */
687 if (symKeyUtil
.options
[opt_KeyFile
].activated
) {
688 if (symKeyUtil
.commands
[cmd_ImportKey
].activated
||
689 symKeyUtil
.commands
[cmd_UnwrapKey
].activated
) {
690 int ret
= ReadBuf(symKeyUtil
.options
[opt_KeyFile
].arg
, &key
);
692 PR_fprintf(PR_STDERR
,
693 "%s Couldn't read key file (%s).\n",
694 progName
, symKeyUtil
.options
[opt_KeyFile
].arg
);
700 /* -i specify the key ID */
701 if (symKeyUtil
.options
[opt_KeyID
].activated
) {
702 int ret
= HexToBuf(symKeyUtil
.options
[opt_KeyID
].arg
, &keyID
);
704 PR_fprintf(PR_STDERR
,
705 "%s invalid key ID (%s).\n",
706 progName
, symKeyUtil
.options
[opt_KeyID
].arg
);
711 /* -i & -j are mutually exclusive */
712 if ((symKeyUtil
.options
[opt_KeyID
].activated
) &&
713 (symKeyUtil
.options
[opt_KeyIDFile
].activated
)) {
714 PR_fprintf(PR_STDERR
,
715 "%s -i and -j options are mutually exclusive.\n", progName
);
719 /* -x specify the Wrap key ID */
720 if (symKeyUtil
.options
[opt_WrapKeyID
].activated
) {
721 int ret
= HexToBuf(symKeyUtil
.options
[opt_WrapKeyID
].arg
, &wrapKeyID
);
723 PR_fprintf(PR_STDERR
,
724 "%s invalid key ID (%s).\n",
725 progName
, symKeyUtil
.options
[opt_WrapKeyID
].arg
);
730 /* -x & -y are mutually exclusive */
731 if ((symKeyUtil
.options
[opt_KeyID
].activated
) &&
732 (symKeyUtil
.options
[opt_KeyIDFile
].activated
)) {
733 PR_fprintf(PR_STDERR
,
734 "%s -i and -j options are mutually exclusive.\n", progName
);
739 /* -y specify the key ID */
740 if (symKeyUtil
.options
[opt_WrapKeyIDFile
].activated
) {
741 int ret
= ReadBuf(symKeyUtil
.options
[opt_WrapKeyIDFile
].arg
,
744 PR_fprintf(PR_STDERR
,
745 "%s Couldn't read key ID file (%s).\n",
746 progName
, symKeyUtil
.options
[opt_WrapKeyIDFile
].arg
);
751 /* -P certdb name prefix */
752 if (symKeyUtil
.options
[opt_dbPrefix
].activated
)
753 certPrefix
= strdup(symKeyUtil
.options
[opt_dbPrefix
].arg
);
755 /* Check number of commands entered. */
757 for (i
=0; i
< symKeyUtil
.numCommands
; i
++) {
758 if (symKeyUtil
.commands
[i
].activated
) {
759 commandToRun
= symKeyUtil
.commands
[i
].flag
;
762 if (commandsEntered
> 1)
765 if (commandsEntered
> 1) {
766 PR_fprintf(PR_STDERR
, "%s: only one command at a time!\n", progName
);
767 PR_fprintf(PR_STDERR
, "You entered: ");
768 for (i
=0; i
< symKeyUtil
.numCommands
; i
++) {
769 if (symKeyUtil
.commands
[i
].activated
)
770 PR_fprintf(PR_STDERR
, " -%c", symKeyUtil
.commands
[i
].flag
);
772 PR_fprintf(PR_STDERR
, "\n");
775 if (commandsEntered
== 0) {
776 PR_fprintf(PR_STDERR
, "%s: you must enter a command!\n", progName
);
780 if (symKeyUtil
.commands
[cmd_ListKeys
].activated
||
781 symKeyUtil
.commands
[cmd_PrintHelp
].activated
||
782 symKeyUtil
.commands
[cmd_ExportKey
].activated
||
783 symKeyUtil
.commands
[cmd_WrapKey
].activated
) {
784 readOnly
= !symKeyUtil
.options
[opt_RW
].activated
;
787 if ((symKeyUtil
.commands
[cmd_ImportKey
].activated
||
788 symKeyUtil
.commands
[cmd_ExportKey
].activated
||
789 symKeyUtil
.commands
[cmd_WrapKey
].activated
||
790 symKeyUtil
.commands
[cmd_UnwrapKey
].activated
) &&
791 !symKeyUtil
.options
[opt_KeyFile
].activated
) {
792 PR_fprintf(PR_STDERR
,
793 "%s -%c: keyfile is required for this command (-k).\n",
794 progName
, commandToRun
);
798 /* -E, -D, -W, and all require -n, -i, or -j to identify the key */
799 if ((symKeyUtil
.commands
[cmd_ExportKey
].activated
||
800 symKeyUtil
.commands
[cmd_DeleteKey
].activated
||
801 symKeyUtil
.commands
[cmd_WrapKey
].activated
) &&
802 !(symKeyUtil
.options
[opt_Nickname
].activated
||
803 symKeyUtil
.options
[opt_KeyID
].activated
||
804 symKeyUtil
.options
[opt_KeyIDFile
].activated
)) {
805 PR_fprintf(PR_STDERR
,
806 "%s -%c: nickname or id is required for this command (-n, -i, -j).\n",
807 progName
, commandToRun
);
811 /* -W, -U, and all -w, -x, or -y to identify the wrapping key */
812 if (( symKeyUtil
.commands
[cmd_WrapKey
].activated
||
813 symKeyUtil
.commands
[cmd_UnwrapKey
].activated
) &&
814 !(symKeyUtil
.options
[opt_WrapKeyName
].activated
||
815 symKeyUtil
.options
[opt_WrapKeyID
].activated
||
816 symKeyUtil
.options
[opt_WrapKeyIDFile
].activated
)) {
817 PR_fprintf(PR_STDERR
,
818 "%s -%c: wrap key is required for this command (-w, -x, or -y).\n",
819 progName
, commandToRun
);
823 /* -M needs the target slot (-g) */
824 if (symKeyUtil
.commands
[cmd_MoveKey
].activated
&&
825 !symKeyUtil
.options
[opt_TargetToken
].activated
) {
826 PR_fprintf(PR_STDERR
,
827 "%s -%c: target token is required for this command (-g).\n",
828 progName
, commandToRun
);
832 /* Using slotname == NULL for listing keys and certs on all slots,
834 if (!(symKeyUtil
.commands
[cmd_ListKeys
].activated
) && slotname
== NULL
) {
835 PR_fprintf(PR_STDERR
,
836 "%s -%c: cannot use \"-h all\" for this command.\n",
837 progName
, commandToRun
);
841 name
= SECU_GetOptionArg(&symKeyUtil
, opt_Nickname
);
842 wrapName
= SECU_GetOptionArg(&symKeyUtil
, opt_WrapKeyName
);
844 PK11_SetPasswordFunc(SECU_GetModulePassword
);
846 /* Initialize NSPR and NSS. */
847 PR_Init(PR_SYSTEM_THREAD
, PR_PRIORITY_NORMAL
, 1);
848 rv
= NSS_Initialize(SECU_ConfigDirectory(NULL
), certPrefix
, certPrefix
,
849 "secmod.db", readOnly
? NSS_INIT_READONLY
: 0);
850 if (rv
!= SECSuccess
) {
851 SECU_PrintPRandOSError(progName
);
856 if (PL_strcmp(slotname
, "internal") == 0)
857 slot
= PK11_GetInternalKeySlot();
858 else if (slotname
!= NULL
)
859 slot
= PK11_FindSlotByName(slotname
);
861 /* generating a new key */
862 if (symKeyUtil
.commands
[cmd_CreateNewKey
].activated
) {
865 symKey
= PK11_TokenKeyGen(slot
, keyType
, NULL
, keySize
,
866 NULL
, PR_TRUE
, &pwdata
);
868 PR_fprintf(PR_STDERR
, "%s: Token Key Gen Failed\n", progName
);
871 if (symKeyUtil
.options
[opt_Nickname
].activated
) {
872 rv
= PK11_SetSymKeyNickname(symKey
, name
);
873 if (rv
!= SECSuccess
) {
874 PK11_DeleteTokenSymKey(symKey
);
875 PK11_FreeSymKey(symKey
);
876 PR_fprintf(PR_STDERR
, "%s: Couldn't set nickname on key\n",
883 PK11_FreeSymKey(symKey
);
885 if (symKeyUtil
.commands
[cmd_DeleteKey
].activated
) {
886 PK11SymKey
*symKey
= FindKey(slot
,name
,&keyID
,&pwdata
);
889 char *keyName
= keyID
.data
? BufToHex(&keyID
) : PORT_Strdup(name
);
890 PR_fprintf(PR_STDERR
, "%s: Couldn't find key %s on %s\n",
891 progName
, keyName
, PK11_GetTokenName(slot
));
896 rv
= PK11_DeleteTokenSymKey(symKey
);
898 if (rv
!= SECSuccess
) {
899 PR_fprintf(PR_STDERR
, "%s: Couldn't Delete Key \n", progName
);
903 if (symKeyUtil
.commands
[cmd_UnwrapKey
].activated
) {
904 PK11SymKey
*wrapKey
= FindKey(slot
,wrapName
,&wrapKeyID
,&pwdata
);
906 CK_MECHANISM_TYPE mechanism
;
909 char *keyName
= wrapKeyID
.data
? BufToHex(&wrapKeyID
)
910 : PORT_Strdup(wrapName
);
911 PR_fprintf(PR_STDERR
, "%s: Couldn't find key %s on %s\n",
912 progName
, keyName
, PK11_GetTokenName(slot
));
916 mechanism
= GetWrapMechanism(wrapKey
);
917 if (mechanism
== CKM_INVALID_MECHANISM
) {
918 char *keyName
= wrapKeyID
.data
? BufToHex(&wrapKeyID
)
919 : PORT_Strdup(wrapName
);
920 PR_fprintf(PR_STDERR
, "%s: %s on %s is an invalid wrapping key\n",
921 progName
, keyName
, PK11_GetTokenName(slot
));
923 PK11_FreeSymKey(wrapKey
);
927 symKey
= PK11_UnwrapSymKeyWithFlagsPerm(wrapKey
, mechanism
, NULL
,
928 &key
, keyType
, CKA_ENCRYPT
, keySize
, 0, PR_TRUE
);
929 PK11_FreeSymKey(wrapKey
);
931 PR_fprintf(PR_STDERR
, "%s: Unwrap Key Failed\n", progName
);
935 if (symKeyUtil
.options
[opt_Nickname
].activated
) {
936 rv
= PK11_SetSymKeyNickname(symKey
, name
);
937 if (rv
!= SECSuccess
) {
938 PR_fprintf(PR_STDERR
, "%s: Couldn't set name on key\n",
940 PK11_DeleteTokenSymKey(symKey
);
941 PK11_FreeSymKey(symKey
);
947 PK11_FreeSymKey(symKey
);
950 #define MAX_KEY_SIZE 4098
951 if (symKeyUtil
.commands
[cmd_WrapKey
].activated
) {
952 PK11SymKey
*symKey
= FindKey(slot
, name
, &keyID
, &pwdata
);
954 CK_MECHANISM_TYPE mechanism
;
956 unsigned char buf
[MAX_KEY_SIZE
];
960 char *keyName
= keyID
.data
? BufToHex(&keyID
) : PORT_Strdup(name
);
961 PR_fprintf(PR_STDERR
, "%s: Couldn't find key %s on %s\n",
962 progName
, keyName
, PK11_GetTokenName(slot
));
967 wrapKey
= FindKey(slot
, wrapName
, &wrapKeyID
, &pwdata
);
969 char *keyName
= wrapKeyID
.data
? BufToHex(&wrapKeyID
)
970 : PORT_Strdup(wrapName
);
971 PR_fprintf(PR_STDERR
, "%s: Couldn't find key %s on %s\n",
972 progName
, keyName
, PK11_GetTokenName(slot
));
974 PK11_FreeSymKey(symKey
);
978 mechanism
= GetWrapMechanism(wrapKey
);
979 if (mechanism
== CKM_INVALID_MECHANISM
) {
980 char *keyName
= wrapKeyID
.data
? BufToHex(&wrapKeyID
)
981 : PORT_Strdup(wrapName
);
982 PR_fprintf(PR_STDERR
, "%s: %s on %s is an invalid wrapping key\n",
983 progName
, keyName
, PK11_GetTokenName(slot
));
985 PK11_FreeSymKey(symKey
);
986 PK11_FreeSymKey(wrapKey
);
991 data
.len
= sizeof(buf
);
992 rv
= PK11_WrapSymKey(mechanism
, NULL
, wrapKey
, symKey
, &data
);
993 PK11_FreeSymKey(symKey
);
994 PK11_FreeSymKey(wrapKey
);
995 if (rv
!= SECSuccess
) {
996 PR_fprintf(PR_STDERR
, "%s: Couldn't wrap key\n",progName
);
1000 /* WriteBuf outputs it's own error using SECU_PrintError */
1001 ret
= WriteBuf(symKeyUtil
.options
[opt_KeyFile
].arg
, &data
);
1007 if (symKeyUtil
.commands
[cmd_ImportKey
].activated
) {
1008 PK11SymKey
*symKey
= PK11_ImportSymKey(slot
, keyType
,
1009 PK11_OriginUnwrap
, CKA_ENCRYPT
, &key
,&pwdata
);
1011 PR_fprintf(PR_STDERR
, "%s: Import Key Failed\n", progName
);
1014 if (symKeyUtil
.options
[opt_Nickname
].activated
) {
1015 rv
= PK11_SetSymKeyNickname(symKey
, name
);
1016 if (rv
!= SECSuccess
) {
1017 PR_fprintf(PR_STDERR
, "%s: Couldn't set name on key\n",
1019 PK11_DeleteTokenSymKey(symKey
);
1020 PK11_FreeSymKey(symKey
);
1026 PK11_FreeSymKey(symKey
);
1029 /* List certs (-L) */
1030 if (symKeyUtil
.commands
[cmd_ListKeys
].activated
) {
1033 rv
= ListKeys(slot
,&printLabel
,&pwdata
);
1035 /* loop over all the slots */
1036 PK11SlotList
*slotList
= PK11_GetAllTokens(CKM_INVALID_MECHANISM
,
1037 PR_FALSE
, PR_FALSE
, &pwdata
);
1038 PK11SlotListElement
*se
;
1040 if (slotList
== NULL
) {
1041 PR_fprintf(PR_STDERR
, "%s: No tokens found\n",progName
);
1043 for (se
= PK11_GetFirstSafe(slotList
); se
;
1044 se
=PK11_GetNextSafe(slotList
,se
, PR_FALSE
)) {
1045 rv
= ListKeys(se
->slot
,&printLabel
,&pwdata
);
1046 if (rv
!=SECSuccess
) {
1054 if (symKeyUtil
.commands
[cmd_MoveKey
].activated
) {
1055 PK11SlotInfo
*target
;
1056 char *targetName
= symKeyUtil
.options
[opt_TargetToken
].arg
;
1058 PK11SymKey
*symKey
= FindKey(slot
,name
,&keyID
,&pwdata
);
1059 char *keyName
= PK11_GetSymKeyNickname(symKey
);
1062 char *keyName
= keyID
.data
? BufToHex(&keyID
) : PORT_Strdup(name
);
1063 PR_fprintf(PR_STDERR
, "%s: Couldn't find key %s on %s\n",
1064 progName
, keyName
, PK11_GetTokenName(slot
));
1068 target
= PK11_FindSlotByName(targetName
);
1070 PR_fprintf(PR_STDERR
, "%s: Couldn't find slot %s\n",
1071 progName
, targetName
);
1074 rv
= PK11_Authenticate(target
, PR_FALSE
, &pwdata
);
1075 if (rv
!= SECSuccess
) {
1076 PR_fprintf(PR_STDERR
, "%s: Failed to log into %s\n",
1077 progName
, targetName
);
1081 newKey
= PK11_MoveSymKey(target
, CKA_ENCRYPT
, 0, PR_TRUE
, symKey
);
1083 PR_fprintf(PR_STDERR
, "%s: Couldn't move the key \n",progName
);
1087 rv
= PK11_SetSymKeyNickname(newKey
, keyName
);
1088 if (rv
!= SECSuccess
) {
1089 PK11_DeleteTokenSymKey(newKey
);
1090 PK11_FreeSymKey(newKey
);
1091 PR_fprintf(PR_STDERR
, "%s: Couldn't set nickname on key\n",
1096 PK11_FreeSymKey(newKey
);
1101 if (rv
!= SECSuccess
) {
1102 PR_fprintf(PR_STDERR
, "%s: %s\n", progName
,
1103 SECU_Strerror(PORT_GetError()));
1107 PORT_Free(key
.data
);
1111 PORT_Free(keyID
.data
);
1115 PK11_FreeSlot(slot
);
1118 if (NSS_Shutdown() != SECSuccess
) {
1122 if (rv
== SECSuccess
) {