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 + -
显示快捷键?