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 | } |