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 ***** */
47
#define PKCS12_IN_BUFFER_SIZE 200
49
static char *progName;
50
PRBool pk12_debugging = PR_FALSE;
52
PRIntn pk12uErrno = 0;
57
#define FPS PR_fprintf(PR_STDERR,
58
FPS "Usage: %s -i importfile [-d certdir] [-P dbprefix] [-h tokenname]\n",
60
FPS "\t\t [-k slotpwfile | -K slotpw] [-w p12filepwfile | -W p12filepw]\n");
62
FPS "Usage: %s -l listfile [-d certdir] [-P dbprefix] [-h tokenname]\n",
64
FPS "\t\t [-k slotpwfile | -K slotpw] [-w p12filepwfile | -W p12filepw]\n");
65
FPS "Usage: %s -o exportfile -n certname [-d certdir] [-P dbprefix]\n", progName);
66
FPS "\t\t [-k slotpwfile | -K slotpw] [-w p12filepwfile | -W p12filepw]\n");
72
p12u_OpenFile(p12uContext *p12cxt, PRBool fileRead)
74
if(!p12cxt || !p12cxt->filename) {
79
p12cxt->file = PR_Open(p12cxt->filename,
82
p12cxt->file = PR_Open(p12cxt->filename,
83
PR_CREATE_FILE | PR_RDWR | PR_TRUNCATE,
88
p12cxt->error = PR_TRUE;
96
p12u_DestroyContext(p12uContext **ppCtx, PRBool removeFile)
98
if(!ppCtx || !(*ppCtx)) {
102
if((*ppCtx)->file != NULL) {
103
PR_Close((*ppCtx)->file);
106
if((*ppCtx)->filename != NULL) {
108
PR_Delete((*ppCtx)->filename);
110
PR_Free((*ppCtx)->filename);
118
p12u_InitContext(PRBool fileImport, char *filename)
123
fileExist = fileImport;
125
p12cxt = PORT_ZNew(p12uContext);
130
p12cxt->error = PR_FALSE;
131
p12cxt->errorValue = 0;
132
p12cxt->filename = strdup(filename);
134
if(!p12u_OpenFile(p12cxt, fileImport)) {
135
p12u_DestroyContext(&p12cxt, PR_FALSE);
143
P12U_NicknameCollisionCallback(SECItem *old_nick, PRBool *cancel, void *wincx)
146
pk12uErrno = PK12UERR_USER_CANCELLED;
151
fprintf(stdout, "pk12util: no nickname for cert...not handled\n");
153
/* XXX not handled yet */
159
SECItem *ret_nick = NULL;
161
nick = strdup( DEFAULT_CERT_NICKNAME );
163
if(old_nick && !PORT_Strcmp((char *)old_nick->data, nick)) {
168
ret_nick = (SECItem *)PORT_ZAlloc(sizeof(SECItem));
169
if(ret_nick == NULL) {
174
ret_nick->data = (unsigned char *)nick;
175
ret_nick->len = PORT_Strlen(nick);
182
p12u_SwapUnicodeBytes(SECItem *uniItem)
186
if((uniItem == NULL) || (uniItem->len % 2)) {
189
for(i = 0; i < uniItem->len; i += 2) {
190
a = uniItem->data[i];
191
uniItem->data[i] = uniItem->data[i+1];
192
uniItem->data[i+1] = a;
198
p12u_ucs2_ascii_conversion_function(PRBool toUnicode,
199
unsigned char *inBuf,
200
unsigned int inBufLen,
201
unsigned char *outBuf,
202
unsigned int maxOutBufLen,
203
unsigned int *outBufLen,
210
#ifdef DEBUG_CONVERSION
211
if (pk12_debugging) {
213
printf("Converted from:\n");
214
for (i=0; i<inBufLen; i++) {
215
printf("%2x ", inBuf[i]);
216
/*if (i%60 == 0) printf("\n");*/
223
dup = SECITEM_DupItem(&it);
224
/* If converting Unicode to ASCII, swap bytes before conversion
227
if (!toUnicode && swapBytes) {
228
if (p12u_SwapUnicodeBytes(dup) != SECSuccess) {
229
SECITEM_ZfreeItem(dup, PR_TRUE);
233
/* Perform the conversion. */
234
ret = PORT_UCS2_UTF8Conversion(toUnicode, dup->data, dup->len,
235
outBuf, maxOutBufLen, outBufLen);
237
SECITEM_ZfreeItem(dup, PR_TRUE);
239
#ifdef DEBUG_CONVERSION
240
if (pk12_debugging) {
242
printf("Converted to:\n");
243
for (i=0; i<*outBufLen; i++) {
244
printf("%2x ", outBuf[i]);
245
/*if (i%60 == 0) printf("\n");*/
254
P12U_UnicodeConversion(PRArenaPool *arena, SECItem *dest, SECItem *src,
255
PRBool toUnicode, PRBool swapBytes)
257
unsigned int allocLen;
261
allocLen = ((toUnicode) ? (src->len << 2) : src->len);
263
dest->data = PORT_ArenaZAlloc(arena, allocLen);
265
dest->data = PORT_ZAlloc(allocLen);
267
if(PORT_UCS2_ASCIIConversion(toUnicode, src->data, src->len,
268
dest->data, allocLen, &dest->len,
269
swapBytes) == PR_FALSE) {
271
PORT_Free(dest->data);
283
P12U_GetP12FilePassword(PRBool confirmPw, secuPWData *p12FilePw)
285
char *p0 = NULL, *p1 = NULL;
286
SECItem *pwItem = NULL;
288
if (p12FilePw == NULL || p12FilePw->source == PW_NONE) {
290
p0 = SECU_GetPasswordString(NULL,
291
"Enter password for PKCS12 file: ");
294
p1 = SECU_GetPasswordString(NULL, "Re-enter password: ");
295
if (PL_strcmp(p0, p1) == 0)
298
} else if (p12FilePw->source == PW_FROMFILE) {
299
p0 = SECU_FilePasswd(NULL, PR_FALSE, p12FilePw->data);
300
} else { /* Plaintext */
301
p0 = p12FilePw->data;
307
pwItem = SECITEM_AllocItem(NULL, NULL, PL_strlen(p0) + 1);
308
memcpy(pwItem->data, p0, pwItem->len);
310
PORT_Memset(p0, 0, PL_strlen(p0));
313
PORT_Memset(p1, 0, PL_strlen(p1));
320
P12U_InitSlot(PK11SlotInfo *slot, secuPWData *slotPw)
324
/* New databases, initialize keydb password. */
325
if (PK11_NeedUserInit(slot)) {
326
rv = SECU_ChangePW(slot,
327
(slotPw->source == PW_PLAINTEXT) ? slotPw->data : 0,
328
(slotPw->source == PW_FROMFILE) ? slotPw->data : 0);
329
if (rv != SECSuccess) {
330
SECU_PrintError(progName, "Failed to initialize slot \"%s\"",
331
PK11_GetSlotName(slot));
336
if (PK11_Authenticate(slot, PR_TRUE, slotPw) != SECSuccess) {
337
SECU_PrintError(progName,
338
"Failed to authenticate to PKCS11 slot");
339
PORT_SetError(SEC_ERROR_USER_CANCELLED);
340
pk12uErrno = PK12UERR_USER_CANCELLED;
347
/* This routine takes care of getting the PKCS12 file password, then reading and
348
* verifying the file. It returns the decoder context and a filled in password.
349
* (The password is needed by P12U_ImportPKCS12Object() to import the private
352
SEC_PKCS12DecoderContext *
353
p12U_ReadPKCS12File(SECItem *uniPwp, char *in_file, PK11SlotInfo *slot,
354
secuPWData *slotPw, secuPWData *p12FilePw)
356
SEC_PKCS12DecoderContext *p12dcx = NULL;
357
p12uContext *p12cxt = NULL;
358
SECItem *pwitem = NULL;
359
SECItem p12file = { 0 };
360
SECStatus rv = SECFailure;
361
PRBool swapUnicode = PR_FALSE;
365
#ifdef IS_LITTLE_ENDIAN
366
swapUnicode = PR_TRUE;
369
p12cxt = p12u_InitContext(PR_TRUE, in_file);
371
SECU_PrintError(progName,"File Open failed: %s", in_file);
372
pk12uErrno = PK12UERR_INIT_FILE;
376
/* get the password */
377
pwitem = P12U_GetP12FilePassword(PR_FALSE, p12FilePw);
379
pk12uErrno = PK12UERR_USER_CANCELLED;
383
if(P12U_UnicodeConversion(NULL, uniPwp, pwitem, PR_TRUE,
384
swapUnicode) != SECSuccess) {
385
SECU_PrintError(progName,"Unicode conversion failed");
386
pk12uErrno = PK12UERR_UNICODECONV;
389
rv = SECU_FileToItem(&p12file, p12cxt->file);
390
if (rv != SECSuccess) {
391
SECU_PrintError(progName,"Failed to read from import file");
396
trypw = PR_FALSE; /* normally we do this once */
398
/* init the decoder context */
399
p12dcx = SEC_PKCS12DecoderStart(uniPwp, slot, slotPw,
400
NULL, NULL, NULL, NULL, NULL);
402
SECU_PrintError(progName,"PKCS12 decoder start failed");
403
pk12uErrno = PK12UERR_PK12DECODESTART;
407
/* decode the item */
408
rv = SEC_PKCS12DecoderUpdate(p12dcx, p12file.data, p12file.len);
410
if(rv != SECSuccess) {
411
error = PR_GetError();
412
if(error == SEC_ERROR_DECRYPTION_DISALLOWED) {
413
PR_SetError(error, 0);
416
SECU_PrintError(progName,"PKCS12 decoding failed");
417
pk12uErrno = PK12UERR_DECODE;
420
/* does the blob authenticate properly? */
421
rv = SEC_PKCS12DecoderVerify(p12dcx);
422
if (rv != SECSuccess) {
423
if(uniPwp->len == 2) {
424
/* this is a null PW, try once more with a zero-length PW
425
instead of a null string */
426
SEC_PKCS12DecoderFinish(p12dcx);
431
SECU_PrintError(progName,"PKCS12 decode not verified");
432
pk12uErrno = PK12UERR_DECODEVERIFY;
436
} while (trypw == PR_TRUE);
437
/* rv has been set at this point */
441
if (rv != SECSuccess) {
442
if (p12dcx != NULL) {
443
SEC_PKCS12DecoderFinish(p12dcx);
447
SECITEM_ZfreeItem(uniPwp, PR_FALSE);
451
PR_Close(p12cxt->file);
453
/* PK11_FreeSlot(slot); */
454
p12u_DestroyContext(&p12cxt, PR_FALSE);
457
SECITEM_ZfreeItem(pwitem, PR_TRUE);
463
* given a filename for pkcs12 file, imports certs and keys
466
* I've changed this function so that it takes the keydb and pkcs12 file
467
* passwords from files. The "pwdKeyDB" and "pwdP12File"
468
* variables have been added for this purpose.
471
P12U_ImportPKCS12Object(char *in_file, PK11SlotInfo *slot,
472
secuPWData *slotPw, secuPWData *p12FilePw)
474
SEC_PKCS12DecoderContext *p12dcx = NULL;
475
SECItem uniPwitem = { 0 };
476
SECStatus rv = SECFailure;
479
rv = P12U_InitSlot(slot, slotPw);
480
if (rv != SECSuccess) {
481
SECU_PrintError(progName, "Failed to authenticate to \"%s\"",
482
PK11_GetSlotName(slot));
483
pk12uErrno = PK12UERR_PK11GETSLOT;
488
p12dcx = p12U_ReadPKCS12File(&uniPwitem, in_file, slot, slotPw, p12FilePw);
494
/* make sure the bags are okey dokey -- nicknames correct, etc. */
495
rv = SEC_PKCS12DecoderValidateBags(p12dcx, P12U_NicknameCollisionCallback);
496
if (rv != SECSuccess) {
497
if (PORT_GetError() == SEC_ERROR_PKCS12_DUPLICATE_DATA) {
498
pk12uErrno = PK12UERR_CERTALREADYEXISTS;
500
pk12uErrno = PK12UERR_DECODEVALIBAGS;
502
SECU_PrintError(progName,"PKCS12 decode validate bags failed");
507
rv = SEC_PKCS12DecoderImportBags(p12dcx);
508
if (rv != SECSuccess) {
509
SECU_PrintError(progName,"PKCS12 decode import bags failed");
510
pk12uErrno = PK12UERR_DECODEIMPTBAGS;
514
fprintf(stdout, "%s: PKCS12 IMPORT SUCCESSFUL\n", progName);
519
SEC_PKCS12DecoderFinish(p12dcx);
522
if (uniPwitem.data) {
523
SECITEM_ZfreeItem(&uniPwitem, PR_FALSE);
530
p12u_DoPKCS12ExportErrors()
534
error_value = PORT_GetError();
535
if ((error_value == SEC_ERROR_PKCS12_UNABLE_TO_EXPORT_KEY) ||
536
(error_value == SEC_ERROR_PKCS12_UNABLE_TO_LOCATE_OBJECT_BY_NAME) ||
537
(error_value == SEC_ERROR_PKCS12_UNABLE_TO_WRITE)) {
538
fprintf(stderr, SECU_ErrorStringRaw((int16)error_value));
539
} else if(error_value == SEC_ERROR_USER_CANCELLED) {
542
fprintf(stderr, SECU_ErrorStringRaw(SEC_ERROR_EXPORTING_CERTIFICATES));
547
p12u_WriteToExportFile(void *arg, const char *buf, unsigned long len)
549
p12uContext *p12cxt = arg;
552
if(!p12cxt || (p12cxt->error == PR_TRUE)) {
556
if(p12cxt->file == NULL) {
557
p12cxt->errorValue = SEC_ERROR_PKCS12_UNABLE_TO_WRITE;
558
p12cxt->error = PR_TRUE;
562
writeLen = PR_Write(p12cxt->file, (unsigned char *)buf, (int32)len);
564
if(writeLen != (int)len) {
565
PR_Close(p12cxt->file);
566
PR_Free(p12cxt->filename);
567
p12cxt->filename = NULL;
569
p12cxt->errorValue = SEC_ERROR_PKCS12_UNABLE_TO_WRITE;
570
p12cxt->error = PR_TRUE;
576
P12U_ExportPKCS12Object(char *nn, char *outfile, PK11SlotInfo *inSlot,
577
secuPWData *slotPw, secuPWData *p12FilePw)
579
SEC_PKCS12ExportContext *p12ecx = NULL;
580
SEC_PKCS12SafeInfo *keySafe = NULL, *certSafe = NULL;
581
SECItem *pwitem = NULL;
582
p12uContext *p12cxt = NULL;
583
CERTCertList* certlist = NULL;
584
CERTCertListNode* node = NULL;
585
PK11SlotInfo* slot = NULL;
587
if (P12U_InitSlot(inSlot, slotPw) != SECSuccess) {
588
SECU_PrintError(progName,"Failed to authenticate to \"%s\"",
589
PK11_GetSlotName(inSlot));
590
pk12uErrno = PK12UERR_PK11GETSLOT;
593
certlist = PK11_FindCertsFromNickname(nn, slotPw);
595
SECU_PrintError(progName,"find user certs from nickname failed");
596
pk12uErrno = PK12UERR_FINDCERTBYNN;
600
if ((SECSuccess != CERT_FilterCertListForUserCerts(certlist)) ||
601
CERT_LIST_EMPTY(certlist)) {
602
SECU_PrintError(progName,"no user certs from given nickname");
603
pk12uErrno = PK12UERR_FINDCERTBYNN;
607
/* Password to use for PKCS12 file. */
608
pwitem = P12U_GetP12FilePassword(PR_TRUE, p12FilePw);
613
p12cxt = p12u_InitContext(PR_FALSE, outfile);
615
SECU_PrintError(progName,"Initialization failed: %s", outfile);
616
pk12uErrno = PK12UERR_INIT_FILE;
621
CERTCertificate* cert = NULL;
622
node = CERT_LIST_HEAD(certlist);
627
slot = cert->slot; /* use the slot from the first matching
628
certificate to create the context . This is for keygen */
632
SECU_PrintError(progName,"cert does not have a slot");
633
pk12uErrno = PK12UERR_FINDCERTBYNN;
636
p12ecx = SEC_PKCS12CreateExportContext(NULL, NULL, slot, slotPw);
638
SECU_PrintError(progName,"export context creation failed");
639
pk12uErrno = PK12UERR_EXPORTCXCREATE;
643
if(SEC_PKCS12AddPasswordIntegrity(p12ecx, pwitem, SEC_OID_SHA1)
645
SECU_PrintError(progName,"PKCS12 add password integrity failed");
646
pk12uErrno = PK12UERR_PK12ADDPWDINTEG;
650
for (node = CERT_LIST_HEAD(certlist);!CERT_LIST_END(node,certlist);node=CERT_LIST_NEXT(node))
652
CERTCertificate* cert = node->cert;
654
SECU_PrintError(progName,"cert does not have a slot");
655
pk12uErrno = PK12UERR_FINDCERTBYNN;
659
keySafe = SEC_PKCS12CreateUnencryptedSafe(p12ecx);
660
if(/*!SEC_PKCS12IsEncryptionAllowed() || */ PK11_IsFIPS()) {
663
certSafe = SEC_PKCS12CreatePasswordPrivSafe(p12ecx, pwitem,
664
SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC);
667
if(!certSafe || !keySafe) {
668
SECU_PrintError(progName,"key or cert safe creation failed");
669
pk12uErrno = PK12UERR_CERTKEYSAFE;
673
if(SEC_PKCS12AddCertAndKey(p12ecx, certSafe, NULL, cert,
674
CERT_GetDefaultCertDB(), keySafe, NULL, PR_TRUE, pwitem,
675
SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC)
677
SECU_PrintError(progName,"add cert and key failed");
678
pk12uErrno = PK12UERR_ADDCERTKEY;
683
CERT_DestroyCertList(certlist);
686
if(SEC_PKCS12Encode(p12ecx, p12u_WriteToExportFile, p12cxt)
688
SECU_PrintError(progName,"PKCS12 encode failed");
689
pk12uErrno = PK12UERR_ENCODE;
693
p12u_DestroyContext(&p12cxt, PR_FALSE);
694
SECITEM_ZfreeItem(pwitem, PR_TRUE);
695
fprintf(stdout, "%s: PKCS12 EXPORT SUCCESSFUL\n", progName);
696
SEC_PKCS12DestroyExportContext(p12ecx);
701
SEC_PKCS12DestroyExportContext(p12ecx);
704
CERT_DestroyCertList(certlist);
709
PR_Free(slotPw->data);
712
PR_Free(p12FilePw->data);
714
p12u_DestroyContext(&p12cxt, PR_TRUE);
716
SECITEM_ZfreeItem(pwitem, PR_TRUE);
718
p12u_DoPKCS12ExportErrors();
724
P12U_ListPKCS12File(char *in_file, PK11SlotInfo *slot,
725
secuPWData *slotPw, secuPWData *p12FilePw)
727
SEC_PKCS12DecoderContext *p12dcx = NULL;
728
SECItem uniPwitem = { 0 };
729
SECStatus rv = SECFailure;
730
const SEC_PKCS12DecoderItem *dip;
733
p12dcx = p12U_ReadPKCS12File(&uniPwitem, in_file, slot, slotPw,
735
/* did the blob authenticate properly? */
737
SECU_PrintError(progName,"PKCS12 decode not verified");
738
pk12uErrno = PK12UERR_DECODEVERIFY;
741
rv = SEC_PKCS12DecoderIterateInit(p12dcx);
742
if(rv != SECSuccess) {
743
SECU_PrintError(progName,"PKCS12 decode iterate bags failed");
744
pk12uErrno = PK12UERR_DECODEIMPTBAGS;
748
while (SEC_PKCS12DecoderIterateNext(p12dcx, &dip) == SECSuccess) {
750
case SEC_OID_PKCS12_V1_CERT_BAG_ID:
751
printf("Certificate");
752
if (SECU_PrintSignedData(stdout, dip->der,
753
(dip->hasKey) ? "(has private key)" : "",
754
0, SECU_PrintCertificate) != 0) {
755
SECU_PrintError(progName,"PKCS12 print cert bag failed");
757
if (dip->friendlyName != NULL) {
758
printf(" Friendly Name: %s\n\n",
759
dip->friendlyName->data);
762
case SEC_OID_PKCS12_V1_KEY_BAG_ID:
763
case SEC_OID_PKCS12_V1_PKCS8_SHROUDED_KEY_BAG_ID:
765
if (dip->type == SEC_OID_PKCS12_V1_PKCS8_SHROUDED_KEY_BAG_ID)
766
printf("(shrouded)");
768
if (dip->friendlyName != NULL) {
769
printf(" Friendly Name: %s\n\n",
770
dip->friendlyName->data);
774
printf("unknown bag type(%d): %s\n\n", dip->type,
775
SECOID_FindOIDTagDescription(dip->type));
785
SEC_PKCS12DecoderFinish(p12dcx);
788
if (uniPwitem.data) {
789
SECITEM_ZfreeItem(&uniPwitem, PR_FALSE);
796
p12u_EnableAllCiphers()
798
SEC_PKCS12EnableCipher(PKCS12_RC4_40, 1);
799
SEC_PKCS12EnableCipher(PKCS12_RC4_128, 1);
800
SEC_PKCS12EnableCipher(PKCS12_RC2_CBC_40, 1);
801
SEC_PKCS12EnableCipher(PKCS12_RC2_CBC_128, 1);
802
SEC_PKCS12EnableCipher(PKCS12_DES_56, 1);
803
SEC_PKCS12EnableCipher(PKCS12_DES_EDE3_168, 1);
804
SEC_PKCS12SetPreferredCipher(PKCS12_DES_EDE3_168, 1);
808
P12U_Init(char *dir, char *dbprefix, PRBool listonly)
811
PK11_SetPasswordFunc(SECU_GetModulePassword);
813
PR_Init(PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1);
814
if (listonly && NSS_NoDB_Init("") == SECSuccess) {
818
rv = NSS_Initialize(dir,dbprefix,dbprefix,"secmod.db",0);
820
if (rv != SECSuccess) {
821
SECU_PrintPRandOSError(progName);
825
/* setup unicode callback functions */
826
PORT_SetUCS2_ASCIIConversionFunction(p12u_ucs2_ascii_conversion_function);
827
/* use the defaults for UCS4-UTF8 and UCS2-UTF8 */
829
p12u_EnableAllCiphers();
849
static secuCommandFlag pk12util_options[] =
851
{ /* opt_CertDir */ 'd', PR_TRUE, 0, PR_FALSE },
852
{ /* opt_TokenName */ 'h', PR_TRUE, 0, PR_FALSE },
853
{ /* opt_Import */ 'i', PR_TRUE, 0, PR_FALSE },
854
{ /* opt_SlotPWFile */ 'k', PR_TRUE, 0, PR_FALSE },
855
{ /* opt_SlotPW */ 'K', PR_TRUE, 0, PR_FALSE },
856
{ /* opt_List */ 'l', PR_TRUE, 0, PR_FALSE },
857
{ /* opt_Nickname */ 'n', PR_TRUE, 0, PR_FALSE },
858
{ /* opt_Export */ 'o', PR_TRUE, 0, PR_FALSE },
859
{ /* opt_P12FilePWFile */ 'w', PR_TRUE, 0, PR_FALSE },
860
{ /* opt_P12FilePW */ 'W', PR_TRUE, 0, PR_FALSE },
861
{ /* opt_DBPrefix */ 'P', PR_TRUE, 0, PR_FALSE },
862
{ /* opt_Debug */ 'v', PR_FALSE, 0, PR_FALSE }
866
main(int argc, char **argv)
868
secuPWData slotPw = { PW_NONE, NULL };
869
secuPWData p12FilePw = { PW_NONE, NULL };
871
char *slotname = NULL;
872
char *import_file = NULL;
873
char *export_file = NULL;
877
secuCommand pk12util;
878
pk12util.numCommands = 0;
879
pk12util.commands = 0;
880
pk12util.numOptions = sizeof(pk12util_options) / sizeof(secuCommandFlag);
881
pk12util.options = pk12util_options;
883
progName = strrchr(argv[0], '/');
884
progName = progName ? progName+1 : argv[0];
886
rv = SECU_ParseCommandLine(argc, argv, progName, &pk12util);
888
if (rv != SECSuccess)
891
pk12_debugging = pk12util.options[opt_Debug].activated;
893
if ((pk12util.options[opt_Import].activated +
894
pk12util.options[opt_Export].activated +
895
pk12util.options[opt_List].activated) != 1) {
899
if (pk12util.options[opt_Export].activated &&
900
!pk12util.options[opt_Nickname].activated) {
904
slotname = SECU_GetOptionArg(&pk12util, opt_TokenName);
906
import_file = (pk12util.options[opt_List].activated) ?
907
SECU_GetOptionArg(&pk12util, opt_List) :
908
SECU_GetOptionArg(&pk12util, opt_Import);
909
export_file = SECU_GetOptionArg(&pk12util, opt_Export);
911
if (pk12util.options[opt_P12FilePWFile].activated) {
912
p12FilePw.source = PW_FROMFILE;
913
p12FilePw.data = PL_strdup(pk12util.options[opt_P12FilePWFile].arg);
916
if (pk12util.options[opt_P12FilePW].activated) {
917
p12FilePw.source = PW_PLAINTEXT;
918
p12FilePw.data = PL_strdup(pk12util.options[opt_P12FilePW].arg);
921
if (pk12util.options[opt_SlotPWFile].activated) {
922
slotPw.source = PW_FROMFILE;
923
slotPw.data = PL_strdup(pk12util.options[opt_SlotPWFile].arg);
926
if (pk12util.options[opt_SlotPW].activated) {
927
slotPw.source = PW_PLAINTEXT;
928
slotPw.data = PL_strdup(pk12util.options[opt_SlotPW].arg);
931
if (pk12util.options[opt_CertDir].activated) {
932
SECU_ConfigDirectory(pk12util.options[opt_CertDir].arg);
934
if (pk12util.options[opt_DBPrefix].activated) {
935
dbprefix = pk12util.options[opt_DBPrefix].arg;
937
P12U_Init(SECU_ConfigDirectory(NULL), dbprefix,
938
pk12util.options[opt_List].activated);
940
if (!slotname || PL_strcmp(slotname, "internal") == 0)
941
slot = PK11_GetInternalKeySlot();
943
slot = PK11_FindSlotByName(slotname);
946
SECU_PrintError(progName,"Invalid slot \"%s\"", slotname);
947
pk12uErrno = PK12UERR_PK11GETSLOT;
951
if (pk12util.options[opt_Import].activated) {
952
P12U_ImportPKCS12Object(import_file, slot, &slotPw,
955
} else if (pk12util.options[opt_Export].activated) {
956
P12U_ExportPKCS12Object(pk12util.options[opt_Nickname].arg,
957
export_file, slot, &slotPw, &p12FilePw);
959
} else if (pk12util.options[opt_List].activated) {
960
P12U_ListPKCS12File(import_file, slot, &slotPw, &p12FilePw);
964
pk12uErrno = PK12UERR_USAGE;
968
if (slot) PK11_FreeSlot(slot);
969
if (NSS_Shutdown() != SECSuccess) {