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