diff options
author | nelson%bolyard.com <devnull@localhost> | 2006-04-24 04:33:25 +0000 |
---|---|---|
committer | nelson%bolyard.com <devnull@localhost> | 2006-04-24 04:33:25 +0000 |
commit | 002230b0573a216100205b0e501fa8f5610ae7a6 (patch) | |
tree | 8695ccb4ae7da3eebfccc6699d9579402e21e96a | |
parent | 9e6ae90241b9cec334b61216970c0d7182239c4f (diff) | |
download | nss-hg-002230b0573a216100205b0e501fa8f5610ae7a6.tar.gz |
Backport fix for bug 277334 from trunk to NSS_3_11_BRANCH. r=nelson.
-rw-r--r-- | security/nss/cmd/lib/secpwd.c | 2 | ||||
-rw-r--r-- | security/nss/cmd/pk12util/pk12util.c | 290 |
2 files changed, 129 insertions, 163 deletions
diff --git a/security/nss/cmd/lib/secpwd.c b/security/nss/cmd/lib/secpwd.c index f1189e1c9..4d54d1ccf 100644 --- a/security/nss/cmd/lib/secpwd.c +++ b/security/nss/cmd/lib/secpwd.c @@ -96,7 +96,7 @@ char *SEC_GetPassword(FILE *input, FILE *output, char *prompt, int infd = fileno(input); int isTTY = isatty(infd); #endif - char phrase[200]; + char phrase[200] = {'\0'}; /* ensure EOF doesn't return junk */ for (;;) { /* Prompt for password */ diff --git a/security/nss/cmd/pk12util/pk12util.c b/security/nss/cmd/pk12util/pk12util.c index 1d15f1663..ade93d1c0 100644 --- a/security/nss/cmd/pk12util/pk12util.c +++ b/security/nss/cmd/pk12util/pk12util.c @@ -344,106 +344,156 @@ P12U_InitSlot(PK11SlotInfo *slot, secuPWData *slotPw) return SECSuccess; } -/* - * given a filename for pkcs12 file, imports certs and keys - * - * Change: altitude - * I've changed this function so that it takes the keydb and pkcs12 file - * passwords from files. The "pwdKeyDB" and "pwdP12File" - * variables have been added for this purpose. +/* This routine takes care of getting the PKCS12 file password, then reading and + * verifying the file. It returns the decoder context and a filled in password. + * (The password is needed by P12U_ImportPKCS12Object() to import the private + * key.) */ -PRIntn -P12U_ImportPKCS12Object(char *in_file, PK11SlotInfo *slot, - secuPWData *slotPw, secuPWData *p12FilePw) +SEC_PKCS12DecoderContext * +p12U_ReadPKCS12File(SECItem *uniPwp, char *in_file, PK11SlotInfo *slot, + secuPWData *slotPw, secuPWData *p12FilePw) { - p12uContext *p12cxt = NULL; SEC_PKCS12DecoderContext *p12dcx = NULL; - SECItem *pwitem = NULL, uniPwitem = { 0 }; + p12uContext *p12cxt = NULL; + SECItem *pwitem = NULL; SECItem p12file = { 0 }; SECStatus rv = SECFailure; PRBool swapUnicode = PR_FALSE; + PRBool trypw; int error; - + #ifdef IS_LITTLE_ENDIAN swapUnicode = PR_TRUE; #endif - rv = P12U_InitSlot(slot, slotPw); - if (rv != SECSuccess) { - SECU_PrintError(progName, "Failed to authenticate to \"%s\"", - PK11_GetSlotName(slot)); - pk12uErrno = PK12UERR_PK11GETSLOT; - goto loser; - } - p12cxt = p12u_InitContext(PR_TRUE, in_file); if(!p12cxt) { SECU_PrintError(progName,"File Open failed: %s", in_file); pk12uErrno = PK12UERR_INIT_FILE; - goto loser; + return NULL; } /* get the password */ pwitem = P12U_GetP12FilePassword(PR_FALSE, p12FilePw); if (!pwitem) { pk12uErrno = PK12UERR_USER_CANCELLED; - goto loser; + goto done; } - if(P12U_UnicodeConversion(NULL, &uniPwitem, pwitem, PR_TRUE, - swapUnicode) != SECSuccess) { + if(P12U_UnicodeConversion(NULL, uniPwp, pwitem, PR_TRUE, + swapUnicode) != SECSuccess) { SECU_PrintError(progName,"Unicode conversion failed"); pk12uErrno = PK12UERR_UNICODECONV; - goto loser; + goto done; } - - /* init the decoder context */ - p12dcx = SEC_PKCS12DecoderStart(&uniPwitem, slot, slotPw, - NULL, NULL, NULL, NULL, NULL); - if(!p12dcx) { - SECU_PrintError(progName,"PKCS12 decoder start failed"); - pk12uErrno = PK12UERR_PK12DECODESTART; - goto loser; + rv = SECU_FileToItem(&p12file, p12cxt->file); + if (rv != SECSuccess) { + SECU_PrintError(progName,"Failed to read from import file"); + goto done; } - /* decode the item */ - rv = SECU_FileToItem(&p12file, p12cxt->file); + do { + trypw = PR_FALSE; /* normally we do this once */ + rv = SECFailure; + /* init the decoder context */ + p12dcx = SEC_PKCS12DecoderStart(uniPwp, slot, slotPw, + NULL, NULL, NULL, NULL, NULL); + if(!p12dcx) { + SECU_PrintError(progName,"PKCS12 decoder start failed"); + pk12uErrno = PK12UERR_PK12DECODESTART; + break; + } + + /* decode the item */ + rv = SEC_PKCS12DecoderUpdate(p12dcx, p12file.data, p12file.len); + + if(rv != SECSuccess) { + error = PR_GetError(); + if(error == SEC_ERROR_DECRYPTION_DISALLOWED) { + PR_SetError(error, 0); + break; + } + SECU_PrintError(progName,"PKCS12 decoding failed"); + pk12uErrno = PK12UERR_DECODE; + } + + /* does the blob authenticate properly? */ + rv = SEC_PKCS12DecoderVerify(p12dcx); + if (rv != SECSuccess) { + if(uniPwp->len == 2) { + /* this is a null PW, try once more with a zero-length PW + instead of a null string */ + SEC_PKCS12DecoderFinish(p12dcx); + uniPwp->len = 0; + trypw = PR_TRUE; + } + else { + SECU_PrintError(progName,"PKCS12 decode not verified"); + pk12uErrno = PK12UERR_DECODEVERIFY; + break; + } + } + } while (trypw == PR_TRUE); + /* rv has been set at this point */ + + +done: if (rv != SECSuccess) { - SECU_PrintError(progName,"Failed to read from import file"); - goto loser; + if (p12dcx != NULL) { + SEC_PKCS12DecoderFinish(p12dcx); + p12dcx = NULL; + } + if (uniPwp->data) { + SECITEM_ZfreeItem(uniPwp, PR_FALSE); + uniPwp->data = NULL; + } } - rv = SEC_PKCS12DecoderUpdate(p12dcx, p12file.data, p12file.len); + PR_Close(p12cxt->file); + p12cxt->file = NULL; + /* PK11_FreeSlot(slot); */ + p12u_DestroyContext(&p12cxt, PR_FALSE); - if(rv != SECSuccess) { - error = PR_GetError(); - if(error == SEC_ERROR_DECRYPTION_DISALLOWED) { - PR_SetError(error, 0); - goto loser; - } -#ifdef EXTRA - /* unable to import as a new blob, it might be an old one */ - if(p12u_TryToImportOldPDU(p12cxt, pwitem, slot, import_arg->nickCb, - import_arg->proto_win) != SECSuccess) { - goto loser; - } - goto tried_pdu_import; -#endif /* EXTRA */ - SECU_PrintError(progName,"PKCS12 decoding failed"); - pk12uErrno = PK12UERR_DECODE; + if (pwitem) { + SECITEM_ZfreeItem(pwitem, PR_TRUE); } + return p12dcx; +} - rv = SECFailure; +/* + * given a filename for pkcs12 file, imports certs and keys + * + * Change: altitude + * I've changed this function so that it takes the keydb and pkcs12 file + * passwords from files. The "pwdKeyDB" and "pwdP12File" + * variables have been added for this purpose. + */ +PRIntn +P12U_ImportPKCS12Object(char *in_file, PK11SlotInfo *slot, + secuPWData *slotPw, secuPWData *p12FilePw) +{ + SEC_PKCS12DecoderContext *p12dcx = NULL; + SECItem uniPwitem = { 0 }; + SECStatus rv = SECFailure; + int error; - /* does the blob authenticate properly? */ - if(SEC_PKCS12DecoderVerify(p12dcx) != SECSuccess) { - SECU_PrintError(progName,"PKCS12 decode not verified"); - pk12uErrno = PK12UERR_DECODEVERIFY; - goto loser; + rv = P12U_InitSlot(slot, slotPw); + if (rv != SECSuccess) { + SECU_PrintError(progName, "Failed to authenticate to \"%s\"", + PK11_GetSlotName(slot)); + pk12uErrno = PK12UERR_PK11GETSLOT; + return rv; } + rv = SECFailure; + p12dcx = p12U_ReadPKCS12File(&uniPwitem, in_file, slot, slotPw, p12FilePw); + + if(p12dcx == NULL) { + goto loser; + } + /* make sure the bags are okey dokey -- nicknames correct, etc. */ - if (SEC_PKCS12DecoderValidateBags(p12dcx, P12U_NicknameCollisionCallback) - != SECSuccess) { + rv = SEC_PKCS12DecoderValidateBags(p12dcx, P12U_NicknameCollisionCallback); + if (rv != SECSuccess) { if (PORT_GetError() == SEC_ERROR_PKCS12_DUPLICATE_DATA) { pk12uErrno = PK12UERR_CERTALREADYEXISTS; } else { @@ -454,49 +504,25 @@ P12U_ImportPKCS12Object(char *in_file, PK11SlotInfo *slot, } /* stuff 'em in */ - if(SEC_PKCS12DecoderImportBags(p12dcx) != SECSuccess) { + rv = SEC_PKCS12DecoderImportBags(p12dcx); + if (rv != SECSuccess) { SECU_PrintError(progName,"PKCS12 decode import bags failed"); pk12uErrno = PK12UERR_DECODEIMPTBAGS; goto loser; } -#if 0 - /* important - to add the password hash into the key database */ - rv = PK11_CheckUserPassword(slot, pw_string); - if( rv != SECSuccess ) { - SECU_PrintError(progName,"Failed to CheckUserPassword"); - exit(-1); - } -#endif - - PR_Close(p12cxt->file); - p12cxt->file = NULL; - /* PK11_FreeSlot(slot); */ - fprintf(stdout, "%s: PKCS12 IMPORT SUCCESSFUL\n", progName); rv = SECSuccess; loser: - if (rv != SECSuccess) { - /* pk12u_report_failure */ - } else { - /* pk12u_report_success ? */ - } - if (p12dcx) { SEC_PKCS12DecoderFinish(p12dcx); } - p12u_DestroyContext(&p12cxt, PR_FALSE); - + if (uniPwitem.data) { SECITEM_ZfreeItem(&uniPwitem, PR_FALSE); } - - if (pwitem) { - SECITEM_ZfreeItem(pwitem, PR_TRUE); - } - - + return rv; } @@ -545,6 +571,7 @@ p12u_WriteToExportFile(void *arg, const char *buf, unsigned long len) } } + void P12U_ExportPKCS12Object(char *nn, char *outfile, PK11SlotInfo *inSlot, secuPWData *slotPw, secuPWData *p12FilePw) @@ -697,78 +724,22 @@ PRIntn P12U_ListPKCS12File(char *in_file, PK11SlotInfo *slot, secuPWData *slotPw, secuPWData *p12FilePw) { - p12uContext *p12cxt = NULL; SEC_PKCS12DecoderContext *p12dcx = NULL; - SECItem *pwitem = NULL, uniPwitem = { 0 }; - SECItem p12file = { 0 }; + SECItem uniPwitem = { 0 }; SECStatus rv = SECFailure; - PRBool swapUnicode = PR_FALSE; const SEC_PKCS12DecoderItem *dip; - int error; -#ifdef IS_LITTLE_ENDIAN - swapUnicode = PR_TRUE; -#endif - - p12cxt = p12u_InitContext(PR_TRUE, in_file); - if(!p12cxt) { - SECU_PrintError(progName,"File Open failed: %s", in_file); - pk12uErrno = PK12UERR_INIT_FILE; - goto loser; - } - - /* get the password */ - pwitem = P12U_GetP12FilePassword(PR_FALSE, p12FilePw); - if (!pwitem) { - pk12uErrno = PK12UERR_USER_CANCELLED; - goto loser; - } - - if(P12U_UnicodeConversion(NULL, &uniPwitem, pwitem, PR_TRUE, - swapUnicode) != SECSuccess) { - SECU_PrintError(progName,"Unicode conversion failed"); - pk12uErrno = PK12UERR_UNICODECONV; - goto loser; - } - - /* init the decoder context */ - p12dcx = SEC_PKCS12DecoderStart(&uniPwitem, slot, slotPw, - NULL, NULL, NULL, NULL, NULL); - if(!p12dcx) { - SECU_PrintError(progName,"PKCS12 decoder start failed"); - pk12uErrno = PK12UERR_PK12DECODESTART; - goto loser; - } - - /* read the item */ - rv = SECU_FileToItem(&p12file, p12cxt->file); - PR_Close(p12cxt->file); - p12cxt->file = NULL; - - if (rv != SECSuccess) { - SECU_PrintError(progName,"Failed to read from import file"); - goto loser; - } - - rv = SEC_PKCS12DecoderUpdate(p12dcx, p12file.data, p12file.len); - if(rv != SECSuccess) { - error = PR_GetError(); - if(error == SEC_ERROR_DECRYPTION_DISALLOWED) { - PR_SetError(error, 0); - goto loser; - } - SECU_PrintError(progName,"PKCS12 decoding failed"); - pk12uErrno = PK12UERR_DECODE; - } - - /* does the blob authenticate properly? */ - if(SEC_PKCS12DecoderVerify(p12dcx) != SECSuccess) { + p12dcx = p12U_ReadPKCS12File(&uniPwitem, in_file, slot, slotPw, + p12FilePw); + /* did the blob authenticate properly? */ + if(p12dcx == NULL) { SECU_PrintError(progName,"PKCS12 decode not verified"); pk12uErrno = PK12UERR_DECODEVERIFY; - rv = SECFailure; + goto loser; } - else if (SEC_PKCS12DecoderIterateInit(p12dcx) != SECSuccess) { + rv = SEC_PKCS12DecoderIterateInit(p12dcx); + if(rv != SECSuccess) { SECU_PrintError(progName,"PKCS12 decode iterate bags failed"); pk12uErrno = PK12UERR_DECODEIMPTBAGS; rv = SECFailure; @@ -813,16 +784,11 @@ loser: if (p12dcx) { SEC_PKCS12DecoderFinish(p12dcx); } - p12u_DestroyContext(&p12cxt, PR_FALSE); - + if (uniPwitem.data) { SECITEM_ZfreeItem(&uniPwitem, PR_FALSE); } - - if (pwitem) { - SECITEM_ZfreeItem(pwitem, PR_TRUE); - } - + return rv; } |