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
;
53 PRIntn pk12uErrno
= 0;
58 #define FPS PR_fprintf(PR_STDERR,
59 FPS
"Usage: %s -i importfile [-d certdir] [-P dbprefix] [-h tokenname] [-v]\n",
61 FPS
"\t\t [-k slotpwfile | -K slotpw] [-w p12filepwfile | -W p12filepw]\n");
63 FPS
"Usage: %s -l listfile [-d certdir] [-P dbprefix] [-h tokenname] [-r]\n",
65 FPS
"\t\t [-k slotpwfile | -K slotpw] [-w p12filepwfile | -W p12filepw]\n");
67 FPS
"Usage: %s -o exportfile -n certname [-d certdir] [-P dbprefix] [-v]\n",
69 FPS
"\t\t [-k slotpwfile | -K slotpw] [-w p12filepwfile | -W p12filepw]\n");
75 p12u_OpenFile(p12uContext
*p12cxt
, PRBool fileRead
)
77 if(!p12cxt
|| !p12cxt
->filename
) {
82 p12cxt
->file
= PR_Open(p12cxt
->filename
,
85 p12cxt
->file
= PR_Open(p12cxt
->filename
,
86 PR_CREATE_FILE
| PR_RDWR
| PR_TRUNCATE
,
91 p12cxt
->error
= PR_TRUE
;
99 p12u_DestroyContext(p12uContext
**ppCtx
, PRBool removeFile
)
101 if(!ppCtx
|| !(*ppCtx
)) {
105 if((*ppCtx
)->file
!= NULL
) {
106 PR_Close((*ppCtx
)->file
);
109 if((*ppCtx
)->filename
!= NULL
) {
111 PR_Delete((*ppCtx
)->filename
);
113 PR_Free((*ppCtx
)->filename
);
121 p12u_InitContext(PRBool fileImport
, char *filename
)
126 fileExist
= fileImport
;
128 p12cxt
= PORT_ZNew(p12uContext
);
133 p12cxt
->error
= PR_FALSE
;
134 p12cxt
->errorValue
= 0;
135 p12cxt
->filename
= strdup(filename
);
137 if(!p12u_OpenFile(p12cxt
, fileImport
)) {
138 p12u_DestroyContext(&p12cxt
, PR_FALSE
);
146 P12U_NicknameCollisionCallback(SECItem
*old_nick
, PRBool
*cancel
, void *wincx
)
149 SECItem
*ret_nick
= NULL
;
150 CERTCertificate
* cert
= (CERTCertificate
*)wincx
;
152 if (!cancel
|| !cert
) {
153 pk12uErrno
= PK12UERR_USER_CANCELLED
;
158 fprintf(stdout
, "pk12util: no nickname for cert in PKCS12 file.\n");
161 /* XXX not handled yet */
167 nick
= CERT_MakeCANickname(cert
);
172 if(old_nick
&& old_nick
->data
&& old_nick
->len
&&
173 PORT_Strlen(nick
) == old_nick
->len
&&
174 !PORT_Strncmp((char *)old_nick
->data
, nick
, old_nick
->len
)) {
176 PORT_SetError(SEC_ERROR_IO
);
180 fprintf(stdout
, "pk12util: using nickname: %s\n", nick
);
181 ret_nick
= PORT_ZNew(SECItem
);
182 if(ret_nick
== NULL
) {
187 ret_nick
->data
= (unsigned char *)nick
;
188 ret_nick
->len
= PORT_Strlen(nick
);
195 p12u_SwapUnicodeBytes(SECItem
*uniItem
)
199 if((uniItem
== NULL
) || (uniItem
->len
% 2)) {
202 for(i
= 0; i
< uniItem
->len
; i
+= 2) {
203 a
= uniItem
->data
[i
];
204 uniItem
->data
[i
] = uniItem
->data
[i
+1];
205 uniItem
->data
[i
+1] = a
;
211 p12u_ucs2_ascii_conversion_function(PRBool toUnicode
,
212 unsigned char *inBuf
,
213 unsigned int inBufLen
,
214 unsigned char *outBuf
,
215 unsigned int maxOutBufLen
,
216 unsigned int *outBufLen
,
223 #ifdef DEBUG_CONVERSION
224 if (pk12_debugging
) {
226 printf("Converted from:\n");
227 for (i
=0; i
<inBufLen
; i
++) {
228 printf("%2x ", inBuf
[i
]);
229 /*if (i%60 == 0) printf("\n");*/
236 dup
= SECITEM_DupItem(&it
);
237 /* If converting Unicode to ASCII, swap bytes before conversion
240 if (!toUnicode
&& swapBytes
) {
241 if (p12u_SwapUnicodeBytes(dup
) != SECSuccess
) {
242 SECITEM_ZfreeItem(dup
, PR_TRUE
);
246 /* Perform the conversion. */
247 ret
= PORT_UCS2_UTF8Conversion(toUnicode
, dup
->data
, dup
->len
,
248 outBuf
, maxOutBufLen
, outBufLen
);
250 SECITEM_ZfreeItem(dup
, PR_TRUE
);
252 #ifdef DEBUG_CONVERSION
253 if (pk12_debugging
) {
255 printf("Converted to:\n");
256 for (i
=0; i
<*outBufLen
; i
++) {
257 printf("%2x ", outBuf
[i
]);
258 /*if (i%60 == 0) printf("\n");*/
267 P12U_UnicodeConversion(PRArenaPool
*arena
, SECItem
*dest
, SECItem
*src
,
268 PRBool toUnicode
, PRBool swapBytes
)
270 unsigned int allocLen
;
274 allocLen
= ((toUnicode
) ? (src
->len
<< 2) : src
->len
);
276 dest
->data
= PORT_ArenaZAlloc(arena
, allocLen
);
278 dest
->data
= PORT_ZAlloc(allocLen
);
280 if(PORT_UCS2_ASCIIConversion(toUnicode
, src
->data
, src
->len
,
281 dest
->data
, allocLen
, &dest
->len
,
282 swapBytes
) == PR_FALSE
) {
284 PORT_Free(dest
->data
);
296 P12U_GetP12FilePassword(PRBool confirmPw
, secuPWData
*p12FilePw
)
299 SECItem
*pwItem
= NULL
;
301 if (p12FilePw
== NULL
|| p12FilePw
->source
== PW_NONE
) {
305 p0
= SECU_GetPasswordString(NULL
,
306 "Enter password for PKCS12 file: ");
307 if (!confirmPw
|| p0
== NULL
)
309 p1
= SECU_GetPasswordString(NULL
, "Re-enter password: ");
311 PORT_ZFree(p0
, PL_strlen(p0
));
315 rc
= PL_strcmp(p0
, p1
);
316 PORT_ZFree(p1
, PL_strlen(p1
));
319 PORT_ZFree(p0
, PL_strlen(p0
));
321 } else if (p12FilePw
->source
== PW_FROMFILE
) {
322 p0
= SECU_FilePasswd(NULL
, PR_FALSE
, p12FilePw
->data
);
323 } else { /* Plaintext */
324 p0
= PORT_Strdup(p12FilePw
->data
);
330 pwItem
= SECITEM_AllocItem(NULL
, NULL
, PL_strlen(p0
) + 1);
331 memcpy(pwItem
->data
, p0
, pwItem
->len
);
333 PORT_ZFree(p0
, PL_strlen(p0
));
339 P12U_InitSlot(PK11SlotInfo
*slot
, secuPWData
*slotPw
)
343 /* New databases, initialize keydb password. */
344 if (PK11_NeedUserInit(slot
)) {
345 rv
= SECU_ChangePW(slot
,
346 (slotPw
->source
== PW_PLAINTEXT
) ? slotPw
->data
: 0,
347 (slotPw
->source
== PW_FROMFILE
) ? slotPw
->data
: 0);
348 if (rv
!= SECSuccess
) {
349 SECU_PrintError(progName
, "Failed to initialize slot \"%s\"",
350 PK11_GetSlotName(slot
));
355 if (PK11_Authenticate(slot
, PR_TRUE
, slotPw
) != SECSuccess
) {
356 SECU_PrintError(progName
,
357 "Failed to authenticate to PKCS11 slot");
358 PORT_SetError(SEC_ERROR_USER_CANCELLED
);
359 pk12uErrno
= PK12UERR_USER_CANCELLED
;
366 /* This routine takes care of getting the PKCS12 file password, then reading and
367 * verifying the file. It returns the decoder context and a filled in password.
368 * (The password is needed by P12U_ImportPKCS12Object() to import the private
371 SEC_PKCS12DecoderContext
*
372 p12U_ReadPKCS12File(SECItem
*uniPwp
, char *in_file
, PK11SlotInfo
*slot
,
373 secuPWData
*slotPw
, secuPWData
*p12FilePw
)
375 SEC_PKCS12DecoderContext
*p12dcx
= NULL
;
376 p12uContext
*p12cxt
= NULL
;
377 SECItem
*pwitem
= NULL
;
378 SECItem p12file
= { 0 };
379 SECStatus rv
= SECFailure
;
380 PRBool swapUnicode
= PR_FALSE
;
384 #ifdef IS_LITTLE_ENDIAN
385 swapUnicode
= PR_TRUE
;
388 p12cxt
= p12u_InitContext(PR_TRUE
, in_file
);
390 SECU_PrintError(progName
,"File Open failed: %s", in_file
);
391 pk12uErrno
= PK12UERR_INIT_FILE
;
395 /* get the password */
396 pwitem
= P12U_GetP12FilePassword(PR_FALSE
, p12FilePw
);
398 pk12uErrno
= PK12UERR_USER_CANCELLED
;
402 if(P12U_UnicodeConversion(NULL
, uniPwp
, pwitem
, PR_TRUE
,
403 swapUnicode
) != SECSuccess
) {
404 SECU_PrintError(progName
,"Unicode conversion failed");
405 pk12uErrno
= PK12UERR_UNICODECONV
;
408 rv
= SECU_FileToItem(&p12file
, p12cxt
->file
);
409 if (rv
!= SECSuccess
) {
410 SECU_PrintError(progName
,"Failed to read from import file");
415 trypw
= PR_FALSE
; /* normally we do this once */
417 /* init the decoder context */
418 p12dcx
= SEC_PKCS12DecoderStart(uniPwp
, slot
, slotPw
,
419 NULL
, NULL
, NULL
, NULL
, NULL
);
421 SECU_PrintError(progName
,"PKCS12 decoder start failed");
422 pk12uErrno
= PK12UERR_PK12DECODESTART
;
426 /* decode the item */
427 rv
= SEC_PKCS12DecoderUpdate(p12dcx
, p12file
.data
, p12file
.len
);
429 if(rv
!= SECSuccess
) {
430 error
= PR_GetError();
431 if(error
== SEC_ERROR_DECRYPTION_DISALLOWED
) {
432 PR_SetError(error
, 0);
435 SECU_PrintError(progName
,"PKCS12 decoding failed");
436 pk12uErrno
= PK12UERR_DECODE
;
439 /* does the blob authenticate properly? */
440 rv
= SEC_PKCS12DecoderVerify(p12dcx
);
441 if (rv
!= SECSuccess
) {
442 if(uniPwp
->len
== 2) {
443 /* this is a null PW, try once more with a zero-length PW
444 instead of a null string */
445 SEC_PKCS12DecoderFinish(p12dcx
);
450 SECU_PrintError(progName
,"PKCS12 decode not verified");
451 pk12uErrno
= PK12UERR_DECODEVERIFY
;
455 } while (trypw
== PR_TRUE
);
456 /* rv has been set at this point */
460 if (rv
!= SECSuccess
) {
461 if (p12dcx
!= NULL
) {
462 SEC_PKCS12DecoderFinish(p12dcx
);
466 SECITEM_ZfreeItem(uniPwp
, PR_FALSE
);
470 PR_Close(p12cxt
->file
);
472 /* PK11_FreeSlot(slot); */
473 p12u_DestroyContext(&p12cxt
, PR_FALSE
);
476 SECITEM_ZfreeItem(pwitem
, PR_TRUE
);
482 * given a filename for pkcs12 file, imports certs and keys
485 * I've changed this function so that it takes the keydb and pkcs12 file
486 * passwords from files. The "pwdKeyDB" and "pwdP12File"
487 * variables have been added for this purpose.
490 P12U_ImportPKCS12Object(char *in_file
, PK11SlotInfo
*slot
,
491 secuPWData
*slotPw
, secuPWData
*p12FilePw
)
493 SEC_PKCS12DecoderContext
*p12dcx
= NULL
;
494 SECItem uniPwitem
= { 0 };
495 SECStatus rv
= SECFailure
;
497 rv
= P12U_InitSlot(slot
, slotPw
);
498 if (rv
!= SECSuccess
) {
499 SECU_PrintError(progName
, "Failed to authenticate to \"%s\"",
500 PK11_GetSlotName(slot
));
501 pk12uErrno
= PK12UERR_PK11GETSLOT
;
506 p12dcx
= p12U_ReadPKCS12File(&uniPwitem
, in_file
, slot
, slotPw
, p12FilePw
);
512 /* make sure the bags are okey dokey -- nicknames correct, etc. */
513 rv
= SEC_PKCS12DecoderValidateBags(p12dcx
, P12U_NicknameCollisionCallback
);
514 if (rv
!= SECSuccess
) {
515 if (PORT_GetError() == SEC_ERROR_PKCS12_DUPLICATE_DATA
) {
516 pk12uErrno
= PK12UERR_CERTALREADYEXISTS
;
518 pk12uErrno
= PK12UERR_DECODEVALIBAGS
;
520 SECU_PrintError(progName
,"PKCS12 decode validate bags failed");
525 rv
= SEC_PKCS12DecoderImportBags(p12dcx
);
526 if (rv
!= SECSuccess
) {
527 SECU_PrintError(progName
,"PKCS12 decode import bags failed");
528 pk12uErrno
= PK12UERR_DECODEIMPTBAGS
;
532 fprintf(stdout
, "%s: PKCS12 IMPORT SUCCESSFUL\n", progName
);
537 SEC_PKCS12DecoderFinish(p12dcx
);
540 if (uniPwitem
.data
) {
541 SECITEM_ZfreeItem(&uniPwitem
, PR_FALSE
);
548 p12u_DoPKCS12ExportErrors()
552 error_value
= PORT_GetError();
553 if ((error_value
== SEC_ERROR_PKCS12_UNABLE_TO_EXPORT_KEY
) ||
554 (error_value
== SEC_ERROR_PKCS12_UNABLE_TO_LOCATE_OBJECT_BY_NAME
) ||
555 (error_value
== SEC_ERROR_PKCS12_UNABLE_TO_WRITE
)) {
556 fprintf(stderr
, SECU_ErrorStringRaw((int16
)error_value
));
557 } else if(error_value
== SEC_ERROR_USER_CANCELLED
) {
560 fprintf(stderr
, SECU_ErrorStringRaw(SEC_ERROR_EXPORTING_CERTIFICATES
));
565 p12u_WriteToExportFile(void *arg
, const char *buf
, unsigned long len
)
567 p12uContext
*p12cxt
= arg
;
570 if(!p12cxt
|| (p12cxt
->error
== PR_TRUE
)) {
574 if(p12cxt
->file
== NULL
) {
575 p12cxt
->errorValue
= SEC_ERROR_PKCS12_UNABLE_TO_WRITE
;
576 p12cxt
->error
= PR_TRUE
;
580 writeLen
= PR_Write(p12cxt
->file
, (unsigned char *)buf
, (int32
)len
);
582 if(writeLen
!= (int)len
) {
583 PR_Close(p12cxt
->file
);
584 PR_Free(p12cxt
->filename
);
585 p12cxt
->filename
= NULL
;
587 p12cxt
->errorValue
= SEC_ERROR_PKCS12_UNABLE_TO_WRITE
;
588 p12cxt
->error
= PR_TRUE
;
594 P12U_ExportPKCS12Object(char *nn
, char *outfile
, PK11SlotInfo
*inSlot
,
595 secuPWData
*slotPw
, secuPWData
*p12FilePw
)
597 SEC_PKCS12ExportContext
*p12ecx
= NULL
;
598 SEC_PKCS12SafeInfo
*keySafe
= NULL
, *certSafe
= NULL
;
599 SECItem
*pwitem
= NULL
;
600 p12uContext
*p12cxt
= NULL
;
601 CERTCertList
* certlist
= NULL
;
602 CERTCertListNode
* node
= NULL
;
603 PK11SlotInfo
* slot
= NULL
;
605 if (P12U_InitSlot(inSlot
, slotPw
) != SECSuccess
) {
606 SECU_PrintError(progName
,"Failed to authenticate to \"%s\"",
607 PK11_GetSlotName(inSlot
));
608 pk12uErrno
= PK12UERR_PK11GETSLOT
;
611 certlist
= PK11_FindCertsFromNickname(nn
, slotPw
);
613 SECU_PrintError(progName
,"find user certs from nickname failed");
614 pk12uErrno
= PK12UERR_FINDCERTBYNN
;
618 if ((SECSuccess
!= CERT_FilterCertListForUserCerts(certlist
)) ||
619 CERT_LIST_EMPTY(certlist
)) {
620 PR_fprintf(PR_STDERR
, "%s: no user certs from given nickname\n",
622 pk12uErrno
= PK12UERR_FINDCERTBYNN
;
626 /* Password to use for PKCS12 file. */
627 pwitem
= P12U_GetP12FilePassword(PR_TRUE
, p12FilePw
);
632 p12cxt
= p12u_InitContext(PR_FALSE
, outfile
);
634 SECU_PrintError(progName
,"Initialization failed: %s", outfile
);
635 pk12uErrno
= PK12UERR_INIT_FILE
;
640 CERTCertificate
* cert
= NULL
;
641 node
= CERT_LIST_HEAD(certlist
);
646 slot
= cert
->slot
; /* use the slot from the first matching
647 certificate to create the context . This is for keygen */
651 SECU_PrintError(progName
,"cert does not have a slot");
652 pk12uErrno
= PK12UERR_FINDCERTBYNN
;
655 p12ecx
= SEC_PKCS12CreateExportContext(NULL
, NULL
, slot
, slotPw
);
657 SECU_PrintError(progName
,"export context creation failed");
658 pk12uErrno
= PK12UERR_EXPORTCXCREATE
;
662 if(SEC_PKCS12AddPasswordIntegrity(p12ecx
, pwitem
, SEC_OID_SHA1
)
664 SECU_PrintError(progName
,"PKCS12 add password integrity failed");
665 pk12uErrno
= PK12UERR_PK12ADDPWDINTEG
;
669 for (node
= CERT_LIST_HEAD(certlist
);!CERT_LIST_END(node
,certlist
);node
=CERT_LIST_NEXT(node
))
671 CERTCertificate
* cert
= node
->cert
;
673 SECU_PrintError(progName
,"cert does not have a slot");
674 pk12uErrno
= PK12UERR_FINDCERTBYNN
;
678 keySafe
= SEC_PKCS12CreateUnencryptedSafe(p12ecx
);
679 if(/*!SEC_PKCS12IsEncryptionAllowed() || */ PK11_IsFIPS()) {
682 certSafe
= SEC_PKCS12CreatePasswordPrivSafe(p12ecx
, pwitem
,
683 SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC
);
686 if(!certSafe
|| !keySafe
) {
687 SECU_PrintError(progName
,"key or cert safe creation failed");
688 pk12uErrno
= PK12UERR_CERTKEYSAFE
;
692 if(SEC_PKCS12AddCertAndKey(p12ecx
, certSafe
, NULL
, cert
,
693 CERT_GetDefaultCertDB(), keySafe
, NULL
, PR_TRUE
, pwitem
,
694 SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC
)
696 SECU_PrintError(progName
,"add cert and key failed");
697 pk12uErrno
= PK12UERR_ADDCERTKEY
;
702 CERT_DestroyCertList(certlist
);
705 if(SEC_PKCS12Encode(p12ecx
, p12u_WriteToExportFile
, p12cxt
)
707 SECU_PrintError(progName
,"PKCS12 encode failed");
708 pk12uErrno
= PK12UERR_ENCODE
;
712 p12u_DestroyContext(&p12cxt
, PR_FALSE
);
713 SECITEM_ZfreeItem(pwitem
, PR_TRUE
);
714 fprintf(stdout
, "%s: PKCS12 EXPORT SUCCESSFUL\n", progName
);
715 SEC_PKCS12DestroyExportContext(p12ecx
);
720 SEC_PKCS12DestroyExportContext(p12ecx
);
723 CERT_DestroyCertList(certlist
);
727 p12u_DestroyContext(&p12cxt
, PR_TRUE
);
729 SECITEM_ZfreeItem(pwitem
, PR_TRUE
);
731 p12u_DoPKCS12ExportErrors();
737 P12U_ListPKCS12File(char *in_file
, PK11SlotInfo
*slot
,
738 secuPWData
*slotPw
, secuPWData
*p12FilePw
)
740 SEC_PKCS12DecoderContext
*p12dcx
= NULL
;
741 SECItem uniPwitem
= { 0 };
742 SECStatus rv
= SECFailure
;
743 const SEC_PKCS12DecoderItem
*dip
;
745 p12dcx
= p12U_ReadPKCS12File(&uniPwitem
, in_file
, slot
, slotPw
,
747 /* did the blob authenticate properly? */
749 SECU_PrintError(progName
,"PKCS12 decode not verified");
750 pk12uErrno
= PK12UERR_DECODEVERIFY
;
753 rv
= SEC_PKCS12DecoderIterateInit(p12dcx
);
754 if(rv
!= SECSuccess
) {
755 SECU_PrintError(progName
,"PKCS12 decode iterate bags failed");
756 pk12uErrno
= PK12UERR_DECODEIMPTBAGS
;
760 while (SEC_PKCS12DecoderIterateNext(p12dcx
, &dip
) == SECSuccess
) {
762 case SEC_OID_PKCS12_V1_CERT_BAG_ID
:
763 printf("Certificate");
767 sprintf(fileName
, "file%04d.der", ++fileCounter
);
768 fd
= PR_Open(fileName
,
769 PR_CREATE_FILE
| PR_RDWR
| PR_TRUNCATE
,
772 SECU_PrintError(progName
,
773 "Cannot create output file");
775 PR_Write(fd
, dip
->der
->data
, dip
->der
->len
);
779 if (SECU_PrintSignedData(stdout
, dip
->der
,
780 (dip
->hasKey
) ? "(has private key)" : "",
781 0, SECU_PrintCertificate
) != 0) {
782 SECU_PrintError(progName
,"PKCS12 print cert bag failed");
784 if (dip
->friendlyName
!= NULL
) {
785 printf(" Friendly Name: %s\n\n",
786 dip
->friendlyName
->data
);
789 case SEC_OID_PKCS12_V1_KEY_BAG_ID
:
790 case SEC_OID_PKCS12_V1_PKCS8_SHROUDED_KEY_BAG_ID
:
792 if (dip
->type
== SEC_OID_PKCS12_V1_PKCS8_SHROUDED_KEY_BAG_ID
)
793 printf("(shrouded)");
795 if (dip
->friendlyName
!= NULL
) {
796 printf(" Friendly Name: %s\n\n",
797 dip
->friendlyName
->data
);
801 printf("unknown bag type(%d): %s\n\n", dip
->type
,
802 SECOID_FindOIDTagDescription(dip
->type
));
812 SEC_PKCS12DecoderFinish(p12dcx
);
815 if (uniPwitem
.data
) {
816 SECITEM_ZfreeItem(&uniPwitem
, PR_FALSE
);
823 p12u_EnableAllCiphers()
825 SEC_PKCS12EnableCipher(PKCS12_RC4_40
, 1);
826 SEC_PKCS12EnableCipher(PKCS12_RC4_128
, 1);
827 SEC_PKCS12EnableCipher(PKCS12_RC2_CBC_40
, 1);
828 SEC_PKCS12EnableCipher(PKCS12_RC2_CBC_128
, 1);
829 SEC_PKCS12EnableCipher(PKCS12_DES_56
, 1);
830 SEC_PKCS12EnableCipher(PKCS12_DES_EDE3_168
, 1);
831 SEC_PKCS12SetPreferredCipher(PKCS12_DES_EDE3_168
, 1);
835 P12U_Init(char *dir
, char *dbprefix
, PRBool listonly
)
838 PK11_SetPasswordFunc(SECU_GetModulePassword
);
840 PR_Init(PR_SYSTEM_THREAD
, PR_PRIORITY_NORMAL
, 1);
841 if (listonly
&& NSS_NoDB_Init("") == SECSuccess
) {
845 rv
= NSS_Initialize(dir
,dbprefix
,dbprefix
,"secmod.db",0);
847 if (rv
!= SECSuccess
) {
848 SECU_PrintPRandOSError(progName
);
852 /* setup unicode callback functions */
853 PORT_SetUCS2_ASCIIConversionFunction(p12u_ucs2_ascii_conversion_function
);
854 /* use the defaults for UCS4-UTF8 and UCS2-UTF8 */
856 p12u_EnableAllCiphers();
877 static secuCommandFlag pk12util_options
[] =
879 { /* opt_CertDir */ 'd', PR_TRUE
, 0, PR_FALSE
},
880 { /* opt_TokenName */ 'h', PR_TRUE
, 0, PR_FALSE
},
881 { /* opt_Import */ 'i', PR_TRUE
, 0, PR_FALSE
},
882 { /* opt_SlotPWFile */ 'k', PR_TRUE
, 0, PR_FALSE
},
883 { /* opt_SlotPW */ 'K', PR_TRUE
, 0, PR_FALSE
},
884 { /* opt_List */ 'l', PR_TRUE
, 0, PR_FALSE
},
885 { /* opt_Nickname */ 'n', PR_TRUE
, 0, PR_FALSE
},
886 { /* opt_Export */ 'o', PR_TRUE
, 0, PR_FALSE
},
887 { /* opt_Raw */ 'r', PR_FALSE
, 0, PR_FALSE
},
888 { /* opt_P12FilePWFile */ 'w', PR_TRUE
, 0, PR_FALSE
},
889 { /* opt_P12FilePW */ 'W', PR_TRUE
, 0, PR_FALSE
},
890 { /* opt_DBPrefix */ 'P', PR_TRUE
, 0, PR_FALSE
},
891 { /* opt_Debug */ 'v', PR_FALSE
, 0, PR_FALSE
}
895 main(int argc
, char **argv
)
897 secuPWData slotPw
= { PW_NONE
, NULL
};
898 secuPWData p12FilePw
= { PW_NONE
, NULL
};
900 char *slotname
= NULL
;
901 char *import_file
= NULL
;
902 char *export_file
= NULL
;
906 secuCommand pk12util
;
907 pk12util
.numCommands
= 0;
908 pk12util
.commands
= 0;
909 pk12util
.numOptions
= sizeof(pk12util_options
) / sizeof(secuCommandFlag
);
910 pk12util
.options
= pk12util_options
;
912 progName
= strrchr(argv
[0], '/');
913 progName
= progName
? progName
+1 : argv
[0];
915 rv
= SECU_ParseCommandLine(argc
, argv
, progName
, &pk12util
);
917 if (rv
!= SECSuccess
)
920 pk12_debugging
= pk12util
.options
[opt_Debug
].activated
;
922 if ((pk12util
.options
[opt_Import
].activated
+
923 pk12util
.options
[opt_Export
].activated
+
924 pk12util
.options
[opt_List
].activated
) != 1) {
928 if (pk12util
.options
[opt_Export
].activated
&&
929 !pk12util
.options
[opt_Nickname
].activated
) {
933 slotname
= SECU_GetOptionArg(&pk12util
, opt_TokenName
);
935 import_file
= (pk12util
.options
[opt_List
].activated
) ?
936 SECU_GetOptionArg(&pk12util
, opt_List
) :
937 SECU_GetOptionArg(&pk12util
, opt_Import
);
938 export_file
= SECU_GetOptionArg(&pk12util
, opt_Export
);
940 if (pk12util
.options
[opt_P12FilePWFile
].activated
) {
941 p12FilePw
.source
= PW_FROMFILE
;
942 p12FilePw
.data
= PL_strdup(pk12util
.options
[opt_P12FilePWFile
].arg
);
945 if (pk12util
.options
[opt_P12FilePW
].activated
) {
946 p12FilePw
.source
= PW_PLAINTEXT
;
947 p12FilePw
.data
= PL_strdup(pk12util
.options
[opt_P12FilePW
].arg
);
950 if (pk12util
.options
[opt_SlotPWFile
].activated
) {
951 slotPw
.source
= PW_FROMFILE
;
952 slotPw
.data
= PL_strdup(pk12util
.options
[opt_SlotPWFile
].arg
);
955 if (pk12util
.options
[opt_SlotPW
].activated
) {
956 slotPw
.source
= PW_PLAINTEXT
;
957 slotPw
.data
= PL_strdup(pk12util
.options
[opt_SlotPW
].arg
);
960 if (pk12util
.options
[opt_CertDir
].activated
) {
961 SECU_ConfigDirectory(pk12util
.options
[opt_CertDir
].arg
);
963 if (pk12util
.options
[opt_DBPrefix
].activated
) {
964 dbprefix
= pk12util
.options
[opt_DBPrefix
].arg
;
966 if (pk12util
.options
[opt_Raw
].activated
) {
967 dumpRawFile
= PR_TRUE
;
969 P12U_Init(SECU_ConfigDirectory(NULL
), dbprefix
,
970 pk12util
.options
[opt_List
].activated
);
972 if (!slotname
|| PL_strcmp(slotname
, "internal") == 0)
973 slot
= PK11_GetInternalKeySlot();
975 slot
= PK11_FindSlotByName(slotname
);
978 SECU_PrintError(progName
,"Invalid slot \"%s\"", slotname
);
979 pk12uErrno
= PK12UERR_PK11GETSLOT
;
983 if (pk12util
.options
[opt_Import
].activated
) {
984 P12U_ImportPKCS12Object(import_file
, slot
, &slotPw
,
987 } else if (pk12util
.options
[opt_Export
].activated
) {
988 P12U_ExportPKCS12Object(pk12util
.options
[opt_Nickname
].arg
,
989 export_file
, slot
, &slotPw
, &p12FilePw
);
991 } else if (pk12util
.options
[opt_List
].activated
) {
992 P12U_ListPKCS12File(import_file
, slot
, &slotPw
, &p12FilePw
);
996 pk12uErrno
= PK12UERR_USAGE
;
1000 if (slotPw
.data
!= NULL
)
1001 PORT_ZFree(slotPw
.data
, PL_strlen(slotPw
.data
));
1002 if (p12FilePw
.data
!= NULL
)
1003 PORT_ZFree(p12FilePw
.data
, PL_strlen(p12FilePw
.data
));
1004 if (slot
) PK11_FreeSlot(slot
);
1005 if (NSS_Shutdown() != SECSuccess
) {