pk12util.c

来自「支持SSL v2/v3, TLS, PKCS #5, PKCS #7, PKCS」· C语言 代码 · 共 1,236 行 · 第 1/2 页

C
1,236
字号
/* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ *  * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. *  * The Original Code is the Netscape security libraries. *  * The Initial Developer of the Original Code is Netscape * Communications Corporation.  Portions created by Netscape are  * Copyright (C) 1994-2000 Netscape Communications Corporation.  All * Rights Reserved. *  * Contributor(s): *  * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL"), in which case the provisions of the GPL are applicable  * instead of those above.  If you wish to allow use of your  * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by * the GPL.  If you do not delete the provisions above, a recipient * may use your version of this file under either the MPL or the * GPL. */#include "nspr.h"#include "cdbhdl.h"#include "secutil.h"#include "pk11func.h"#include "pkcs12.h"#include "p12plcy.h"#include "pk12util.h"#define PKCS12_IN_BUFFER_SIZE	200char *progName;PRIntn pk12uErrno = 0;static void Usage(char *progName){#define FPS PR_fprintf(PR_STDERR,     FPS "Usage:  %s -i importfile [-d certdir] [-h tokenname]\n", progName);	FPS "\t\t [-k slotpwfile | -K slotpw] [-w p12filepwfile | -W p12filepw]\n");    FPS "Usage:  %s -o exportfile -n certname [-d certdir] [-h tokenname]\n", progName);	FPS "\t\t [-k slotpwfile | -K slotpw] [-w p12filepwfile | -W p12filepw]\n");	exit(PK12UERR_USAGE);}static PRBoolp12u_OpenExportFile(p12uContext *p12cxt, PRBool fileRead){	if(!p12cxt || !p12cxt->filename) {		return PR_FALSE;	}	if(fileRead) {		p12cxt->file = PR_Open(p12cxt->filename,		                         PR_RDONLY, 0400);	} else {		p12cxt->file = PR_Open(p12cxt->filename,		                         PR_CREATE_FILE | PR_RDWR | PR_TRUNCATE,		                         0600);	}	if(!p12cxt->file) {		p12cxt->error = PR_TRUE;		PR_SetError(SEC_ERROR_NO_MEMORY, 0);		return PR_FALSE;	}		return PR_TRUE;}static voidp12u_DestroyExportFileInfo(p12uContext **exp_ptr, PRBool removeFile){	if(!exp_ptr || !(*exp_ptr)) {		return;	}	if((*exp_ptr)->file != NULL) {		PR_Close((*exp_ptr)->file);	}	if((*exp_ptr)->data != NULL) {		SECITEM_ZfreeItem((*exp_ptr)->data, PR_FALSE);	}	if((*exp_ptr)->filename != NULL) {		if(removeFile) {			PR_Delete((*exp_ptr)->filename);		}		PR_Free((*exp_ptr)->filename);	}	PR_Free(*exp_ptr);	*exp_ptr = NULL;}static p12uContext *p12u_InitFile(PRBool fileImport, char *filename){	p12uContext *p12cxt;	PRBool fileExist;	if(fileImport)		fileExist = PR_TRUE;	else		fileExist = PR_FALSE;			p12cxt = (p12uContext *)PR_CALLOC(sizeof(p12uContext));	if(!p12cxt) {		PR_SetError(SEC_ERROR_NO_MEMORY, 0);		return NULL;	}	p12cxt->error = PR_FALSE;	p12cxt->errorValue = 0;	p12cxt->filename = filename;	if(!p12u_OpenExportFile(p12cxt, fileImport)) {		PR_SetError(p12cxt->errorValue, 0);		p12u_DestroyExportFileInfo(&p12cxt, PR_FALSE);		return NULL;	}	return p12cxt;}								 static p12uContext *p12u_CreateTemporaryDigestFile(void){	p12uContext *p12cxt;	p12cxt = (p12uContext *)PR_CALLOC(sizeof(p12uContext));	if(!p12cxt) {		PR_SetError(SEC_ERROR_NO_MEMORY, 0);		return NULL;	}	p12cxt->filename = "Pk12uTemp"/*WH_TempName(xpTemporary, NULL)*/;	if(!p12cxt->filename) {		PR_SetError(SEC_ERROR_NO_MEMORY, 0);		p12u_DestroyExportFileInfo(&p12cxt, PR_FALSE);		return NULL;	}	p12cxt->file = PR_Open(p12cxt->filename, PR_RDONLY, 0400);	if (!p12cxt->filename) {		p12u_DestroyExportFileInfo(&p12cxt, PR_FALSE);		return NULL;	}	return p12cxt;}static intp12u_ReadFromImportFile(p12uContext *p12cxt, unsigned char *buf,                         unsigned long len){	int readLen;	if(!p12cxt || (p12cxt->error!=0)) {		return PR_FALSE;	}	if(p12cxt->file == NULL) {		p12cxt->errorValue = SEC_ERROR_PKCS12_UNABLE_TO_READ;		p12cxt->error = PR_TRUE;		return - 1;	}	readLen = PR_Read(p12cxt->file, (char *)buf, (int32)len);	if(readLen == -1) {		p12cxt->errorValue = SEC_ERROR_PKCS12_UNABLE_TO_READ;		p12cxt->error = PR_TRUE;	}	return readLen;}static SECStatusp12u_DigestOpen(void *arg, PRBool readData) {	p12uContext *p12cxt = arg;	if(!p12cxt || p12cxt->error || !p12cxt->filename) {		return SECFailure;	}	if(readData) {		p12cxt->file = PR_Open(p12cxt->filename, PR_RDONLY, 0400);	} else {		p12cxt->file = PR_Open(p12cxt->filename,		                           PR_CREATE_FILE | PR_RDWR | PR_TRUNCATE,		                           0600);	}			if(p12cxt->file == NULL) {		p12cxt->error = PR_TRUE;		return SECFailure;	}	return SECSuccess;}static SECStatusp12u_DigestClose(void *arg, PRBool removeFile){	p12uContext *p12cxt = arg;	if(!p12cxt || p12cxt->error || 	   !p12cxt->filename || !p12cxt->file) {		return SECFailure;	}	PR_Close(p12cxt->file);	p12cxt->file = NULL;	if(removeFile) {		PR_Delete(p12cxt->filename);		PR_Free(p12cxt->filename);		p12cxt->filename = NULL;	}	return SECSuccess;}static intp12u_DigestRead(void *arg, unsigned char *buf, unsigned long len){	p12uContext *p12cxt = arg;	if(!p12cxt || p12cxt->error || 	   !p12cxt->filename || !p12cxt->file) {		return -1;	}	if(!buf || len == 0) {		return -1;	}	return PR_Read(p12cxt->file, buf, len);}static intp12u_DigestWrite(void *arg, unsigned char *buf, unsigned long len){	p12uContext *p12cxt = arg;	if(!p12cxt || p12cxt->error || 	   !p12cxt->filename || !p12cxt->file) {		return -1;	}	if(!buf || len == 0) {		return -1;	}	return PR_Write(p12cxt->file, buf, len);}SECItem *P12U_NicknameCollisionCallback(SECItem *old_nick, PRBool *cancel, void *wincx){	char *nick = NULL;	SECItem *ret_nick = NULL;	if(cancel == NULL) {	  pk12uErrno = PK12UERR_USER_CANCELLED;	  return NULL;	}	if (!old_nick)	  fprintf(stdout, "pk12util: no nickname for cert...not handled\n");	/* XXX not handled yet  */	*cancel = PR_TRUE;	return NULL;#if 0	nick = strdup( DEFAULT_CERT_NICKNAME );	if(old_nick && !PORT_Strcmp((char *)old_nick->data, nick)) {		PORT_Free(nick);		return NULL;	}	ret_nick = (SECItem *)PORT_ZAlloc(sizeof(SECItem));	if(ret_nick == NULL) {		PORT_Free(nick);		return NULL;	}	ret_nick->data = (unsigned char *)nick;	ret_nick->len = PORT_Strlen(nick);	return ret_nick;#endif}/* *  Not implemented. */static SECItem *p12u_ConvertToUnicode(SECItem *textItem){	return NULL;}/* *  Not implemented. */static SECItem *p12u_ConvertFromUnicode(SECItem *textItem){	return NULL;}static SECStatusp12u_SwapUnicodeBytes(SECItem *uniItem){	unsigned int i;	unsigned char a;	if((uniItem == NULL) || (uniItem->len % 2)) {		return SECFailure;	}	for(i = 0; i < uniItem->len; i += 2) {		a = uniItem->data[i];		uniItem->data[i] = uniItem->data[i+1];		uniItem->data[i+1] = a;	}	return SECSuccess;}PRBool P12U_UCS2_ASCIIConversion(PRBool toUnicode, unsigned char *inBuf,                          unsigned int inBufLen, unsigned char *outBuf,                          unsigned int maxOutBufLen, unsigned int *outBufLen,                           PRBool swapBytes){	SECItem *(*convertFunc)(SECItem *);	SECItem *dupSrc, src, *returnItem;#ifdef DEBUG	int i;	char theChar;#endif	if(!inBuf || !outBuf || !outBufLen) {		return PR_FALSE;	}	src.data = inBuf;	src.len = inBufLen;	*outBufLen = 0;	dupSrc = SECITEM_DupItem(&src);	if(!dupSrc) {		PORT_SetError(SEC_ERROR_NO_MEMORY);		return PR_FALSE;	}	if (toUnicode) {		convertFunc = p12u_ConvertToUnicode;	} else {		if(swapBytes && p12u_SwapUnicodeBytes(dupSrc) != SECSuccess) {			SECITEM_ZfreeItem(dupSrc, PR_TRUE);			return PR_FALSE;		}		convertFunc = p12u_ConvertFromUnicode;	}	returnItem = (*convertFunc)(dupSrc);	SECITEM_ZfreeItem(dupSrc, PR_TRUE);	if(!returnItem) {		return PR_FALSE;	}#ifdef WHY	if(returnItem->len > maxOutBufLen) {		SECITEM_ZfreeItem(returnItem, PR_TRUE);		return PR_FALSE;	}#endif /* WHY */	if(toUnicode && swapBytes && 		(p12u_SwapUnicodeBytes(returnItem) != SECSuccess)) {		SECITEM_ZfreeItem(returnItem, PR_TRUE);		return PR_FALSE;	}	*outBufLen = returnItem->len;	PORT_Memcpy(outBuf, returnItem->data, returnItem->len);#ifdef DEBUG	printf("P12U_UCS2_ASCIIConversion: outBuf=");	for(i=0;i<returnItem->len;i++) {	  theChar = (char)outBuf[i];	  printf("%c",theChar);	}	printf("\ni=%d\n",i);#endif /* DEBUG */	SECITEM_ZfreeItem(returnItem, PR_TRUE);	return PR_TRUE;}SECStatusP12U_UnicodeConversion(PRArenaPool *arena, SECItem *dest, SECItem *src,                       PRBool toUnicode, PRBool swapBytes){	unsigned int allocLen;	if(!dest || !src) {		return SECFailure;	}	allocLen = ((toUnicode) ? (src->len << 2) : src->len);	if(arena) {		dest->data = PORT_ArenaZAlloc(arena, allocLen);	} else {		dest->data = PORT_ZAlloc(allocLen);	}	if(P12U_UCS2_ASCIIConversion(toUnicode, src->data, src->len,	                             dest->data, allocLen, &dest->len, 	                             swapBytes) == PR_FALSE) {		if(!arena) {			PORT_Free(dest->data);		}		dest->data = NULL;		return SECFailure;	}	return SECSuccess;}/* *  Not implemented. */static PRBool p12u_UCS2ToUTF8(unsigned char *inBuf, unsigned int inBufLen,                unsigned char *outBuf, unsigned int maxOutBufLen,                unsigned int *outBufLen){	return PR_FALSE;}/* *  Not implemented. */static PRBool p12u_UTF8ToUCS2(unsigned char *inBuf, unsigned int inBufLen,                unsigned char *outBuf, unsigned int maxOutBufLen,                unsigned int *outBufLen){	return PR_FALSE;}PRBool P12U_UCS2_UTF8Conversion(PRBool toUnicode, unsigned char *inBuf,						   unsigned int inBufLen,unsigned char *outBuf,						   unsigned int maxOutBufLen, unsigned int *outBufLen){	PRBool retval;#ifdef DEBUG	unsigned int i;#endif	if(!inBuf || !outBuf || !outBufLen) {		return PR_FALSE;	}	*outBufLen = 0;#ifdef DEBUG	printf("---UCS2_UTF8Conversion (%s) ---\nInput: ",		(toUnicode?"to UCS2":"to UTF8"));	for(i=0; i< inBufLen; i++) {		printf("%c", (char) inBuf[i]);	}	printf("\n");	for(i=0; i< inBufLen; i++) {		printf("%2x ", (char) inBuf[i]);	}	printf("\n");#endif	if(toUnicode) {		retval = p12u_UTF8ToUCS2(inBuf, inBufLen, outBuf, maxOutBufLen, 								 outBufLen);	} else {		retval = p12u_UCS2ToUTF8(inBuf, inBufLen, outBuf, maxOutBufLen, outBufLen);	}#ifdef DEBUG	printf("Output: ");	for(i=0; i< *outBufLen; i++) {		printf("%c", (char) outBuf[i]);	}	printf("\n");	for(i=0; i< *outBufLen; i++) {		printf("%2x ", (char) outBuf[i]);	}	printf("\n\n");#endif	return retval;}static PRBool p12u_UCS4ToUTF8(unsigned char *inBuf, unsigned int inBufLen,                unsigned char *outBuf, unsigned int maxOutBufLen,                unsigned int *outBufLen){	uint16 *ucs2String, i;	unsigned char *ucs2Buf, *utf8Buf;	ucs2Buf = PORT_ZAlloc(inBufLen * 8);	if(!ucs2Buf) {	  		return PR_FALSE;	}	for(i = 0; i < inBufLen; i+=4) {#ifdef IS_LITTLE_ENDIAN		ucs2Buf[i/2+1] = inBuf[i+2];		ucs2Buf[i/2] = inBuf[i+3];#else		ucs2Buf[i/2] = inBuf[i+2];		ucs2Buf[i/2+1] = inBuf[i+3];#endif	}	ucs2String = (uint16 *)ucs2Buf;		/*  Not implemented.  */	return PR_FALSE;	/*	utf8Buf = XXXX_UCS2ToUTF8(ucs2String, (inBufLen >> 1));	*/	utf8Buf = NULL;	PORT_Free(ucs2Buf);	if(!utf8Buf) {		return PR_FALSE;	}	*outBufLen = PORT_Strlen((const char *)utf8Buf) + 1;	if(*outBufLen > maxOutBufLen) {		*outBufLen = 0;		PORT_Free(utf8Buf);		return PR_FALSE;	}	PORT_Memcpy(outBuf, utf8Buf, *outBufLen);	outBuf[*outBufLen] = 0;	PORT_Free(utf8Buf);	return PR_TRUE;}static PRBool p12u_UTF8ToUCS4(unsigned char *inBuf, unsigned int inBufLen,				  unsigned char *outBuf, unsigned int maxOutBufLen,				  unsigned int *outBufLen){	uint16 *ucs2String = NULL, i;	unsigned char *ucs2Buf;	int32 numChars = 0;	/*  Not Implemented */	return PR_FALSE;	/*	ucs2String = XXXX_UTF8ToUCS2(inBuf, &numChars);	*/	ucs2String = NULL;	if(!ucs2String) {		return PR_FALSE;	}	if((4 * numChars) > (int32)maxOutBufLen) {		PORT_Free(ucs2String);		return PR_FALSE;	}	ucs2Buf = (unsigned char *)ucs2String;	for(i = 0; i < numChars; i++) {#ifdef IS_LITTLE_ENDIAN		outBuf[4*i] = outBuf[4*i+1] = 0;		outBuf[4*i+2] = ucs2Buf[2*i+1];		outBuf[4*i+3] = ucs2Buf[2*i];#else 		outBuf[4*i] = outBuf[4*i+1] = 0;		outBuf[4*i+2] = ucs2Buf[2*i];		outBuf[4*i+3] = ucs2Buf[2*i+1];#endif	} 	*outBufLen = (4 * numChars);	PORT_Free(ucs2String);	return PR_TRUE;}PRBool P12U_UCS4_UTF8Conversion(PRBool toUnicode, unsigned char *inBuf,                         unsigned int inBufLen,unsigned char *outBuf,                         unsigned int maxOutBufLen, unsigned int *outBufLen){

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?