p12res.c

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

C
1,026
字号
        }        keySafe = SEC_PKCS12CreateUnencryptedSafe(p12ecx);        if (!SEC_PKCS12IsEncryptionAllowed() || PK11_IsFIPS()) {            certSafe = keySafe;        } else {            certSafe = SEC_PKCS12CreatePasswordPrivSafe(p12ecx, &pwitem,                          SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC);        }        if (certSafe == NULL || keySafe == NULL) {            rv = SSM_FAILURE;            goto loser;        }        if (SEC_PKCS12AddCertAndKey(p12ecx, certSafe, NULL, certArr[i],                                    SSMRESOURCE(cxt)->m_connection->m_certdb,                                    keySafe, NULL, PR_TRUE, &pwitem,                      SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC)            != SECSuccess) {            rv = SSM_FAILURE;            goto loser;        }    }    /* Done with the password, free it */    PR_Free(cxt->m_password);    cxt->m_password = NULL;    rv = SSM_RequestFilePathFromUser(SSMRESOURCE(cxt),                                     "pkcs12_export_file_prompt",                                     "*.p12",                                     PR_FALSE);    if (rv != SSM_SUCCESS || cxt->super.m_fileName == NULL) {        rv = SSM_ERR_BAD_FILENAME;        goto loser;    }#ifdef XP_MAC	cxt->super.m_fileName = SSM_ConvertMacPathToUnix(cxt->super.m_fileName);#endif        cxt->m_file = PR_Open (cxt->super.m_fileName,                           PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE,                           0600);    if (cxt->m_file == NULL) {        rv = SSM_ERR_BAD_FILENAME;        goto loser;    }    if (SEC_PKCS12Encode(p12ecx, ssmpkcs12context_writetoexportfile, cxt)        != SECSuccess) {        rv = SSM_FAILURE;        goto loser;    }    PR_Close(cxt->m_file);    if (slotToUse) {        PK11_FreeSlot(slotToUse);    }    SEC_PKCS12DestroyExportContext(p12ecx);    return SSM_SUCCESS; loser:    if (p12ecx != NULL) {        SEC_PKCS12DestroyExportContext(p12ecx);    }    if (slot && cxt->m_cert && (slot != cxt->m_cert->slot)) {        PK11_FreeSlot(slot);    }    PR_FREEIF(cxt->m_password);    cxt->m_password = NULL;    return rv;}void ssm_switch_endian(unsigned char *buf, unsigned int len){    unsigned int i;    unsigned char tmp;    for (i=0; i<len; i+=2) {        tmp      = buf[i];        buf[i]   = buf[i+1];        buf[i+1] = tmp;    }}/* This function converts ASCII strings to UCS2 strings in Network Byte Order.** The "swapBytes" argument is ignored.  ** The PKCS#12 code only makes it true on Little Endian systems, ** where it was intended to force the output into NBO.*/PRBool SSM_UCS2_ASCIIConversion(PRBool toUnicode,                          unsigned char *inBuf,                         unsigned int inBufLen,                         unsigned char *outBuf,                         unsigned int maxOutBufLen,                          unsigned int *outBufLen,                          PRBool swapBytes){    if (!inBuf || !outBuf || !outBufLen) {        return PR_FALSE;    }    if (toUnicode) {    	PRBool rv;#ifdef DEBUG	unsigned int outLen;	unsigned int i;	fprintf(stderr,"\n---ssm_ConvertAsciiToUCS2---\nInput: inBuf= ");	for (i = 0; i < inBufLen; i++) {	    fprintf(stderr, "%c", inBuf[i]);	}	fprintf(stderr,"\ninBufLen=%d\n", inBufLen);#endif	rv = nlsASCIIToUnicode(inBuf, inBufLen, 				    outBuf, maxOutBufLen, outBufLen);    if (swapBytes) {        ssm_switch_endian(outBuf, *outBufLen);    }#ifdef DEBUG	outLen = *outBufLen;	fprintf(stderr,"output: outBuf= ");	for(i = 0; i < outLen; i++) {	    fprintf(stderr, "%c ", outBuf[i]);	}	fprintf(stderr,"\noutBuf= ");	for(i = 0; i < outLen; i++) {	    fprintf(stderr,"%2x ", outBuf[i]);	}	fprintf(stderr,"\noutLen = %d\n", outLen);#endif /* DEBUG */	return rv;    }    PR_ASSERT(PR_FALSE); /* not supported yet */    return PR_FALSE;}PRBool SSM_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    char *newbuf=NULL;    if(!inBuf || !outBuf || !outBufLen) {        return PR_FALSE;    }    *outBufLen = 0;#ifdef DEBUG    fprintf(stderr,"---UCS2_UTF8Conversion (%s) ---\nInput: \n",		(toUnicode?"to UCS2":"to UTF8"));	for(i=0; i< inBufLen; i++) {		fprintf(stderr,"%c", (char) inBuf[i]);	}	fprintf(stderr,"\n");   	for(i=0; i< inBufLen; i++) {		fprintf(stderr,"%2x ", (char) inBuf[i]);	}	fprintf(stderr,"\n");#endif    if(toUnicode) {        retval = nlsUTF8ToUnicode(inBuf, inBufLen, outBuf, maxOutBufLen,                                  outBufLen);#if IS_LITTLE_ENDIAN        /* Our converter gives us back the buffer in host order,         * so let's convert to network byte order         */        ssm_switch_endian(outBuf, *outBufLen);#endif    } else {#if IS_LITTLE_ENDIAN        /* NSS is the only place where this function gets called.  It gives         * us the bytes in Network Byte Order, but the conversion functions         * expect the bytes in host order.  So we'll switch the bytes around         * before passing them to the translator.         */                /* The buffer that comes won't necessarily have the trailing ending         * zero bytes, which our converter assumes. So we'll add them         * here.         */        /* Do a check to make sure it is in Network Byte Order first. */        if (inBuf[0] == 0) {            newbuf = SSM_NEW_ARRAY(char, inBufLen+2);            memcpy(newbuf, inBuf, inBufLen);            newbuf[inBufLen] = newbuf[inBufLen+1] = 0;            inBuf = newbuf;            ssm_switch_endian(inBuf, inBufLen);        }#endif    	retval = nlsUnicodeToUTF8(inBuf, inBufLen, outBuf, maxOutBufLen,                                  outBufLen);	}#ifdef DEBUG    fprintf(stderr,"Output: \n");   	for(i=0; i< *outBufLen; i++) {		fprintf(stderr,"%c", (char) outBuf[i]);	}	fprintf(stderr,"\n");   	for(i=0; i< *outBufLen; i++) {		fprintf(stderr,"%2x ", (char) outBuf[i]);	}	fprintf(stderr,"\n\n");#endif    PR_FREEIF(newbuf);	return retval;}static SECStatusssmpkcs12context_digestopen(void *arg, PRBool readData){    char *tmpFileName=NULL;    char *filePathSep;    SSMPKCS12Context *cxt = (SSMPKCS12Context *)arg;#if defined(XP_UNIX)    filePathSep = "/";#elif defined(WIN32)    filePathSep = "\\";#elif defined(XP_MAC)	filePathSep = "";#else#error Tell me what the file path separator is of this platform.#endif    tmpFileName = PR_smprintf("%s%s%s",                               SSMRESOURCE(cxt)->m_connection->m_dirRoot,                              filePathSep,                              ".nsm_p12_tmp");    if (tmpFileName == NULL) {        return SECFailure;    }#ifdef XP_MAC	tmpFileName = SSM_ConvertMacPathToUnix(tmpFileName);#endif        if (readData) {        cxt->m_digestFile = PR_Open(tmpFileName,                                    PR_RDONLY, 0400);    } else {        cxt->m_digestFile = PR_Open(tmpFileName,                                    PR_CREATE_FILE | PR_RDWR | PR_TRUNCATE,                                    0600);    }    cxt->m_tempFilePath = tmpFileName;    if (cxt->m_digestFile == NULL) {        cxt->m_error = PR_TRUE;        return SECFailure;    }    return SECSuccess;}static SECStatusssmpkcs12context_digestclose(void *arg, PRBool removeFile){    SSMPKCS12Context *cxt = (SSMPKCS12Context*)arg;        if (cxt == NULL || cxt->m_digestFile == NULL) {        return SECFailure;    }    PR_Close(cxt->m_digestFile);    cxt->m_digestFile = NULL;    if (removeFile) {        PR_Delete(cxt->m_tempFilePath);        PR_Free(cxt->m_tempFilePath);        cxt->m_tempFilePath = NULL;    }    return SECSuccess;}static intssmpkcs12context_digestread(void *arg, unsigned char *buf, unsigned long len){    SSMPKCS12Context *cxt = (SSMPKCS12Context*)arg;        if (cxt == NULL || cxt->m_digestFile == NULL) {        return -1;    }    if (buf == NULL || len == 0) {        return -1;    }    return PR_Read(cxt->m_digestFile, buf, len);}static intssmpkcs12context_digestwrite(void *arg, unsigned char *buf, unsigned long len){    SSMPKCS12Context *cxt = (SSMPKCS12Context *)arg;    if (cxt == NULL || cxt->m_digestFile == NULL) {        return -1;    }    if (buf == NULL || len == 0) {        return -1;    }    return PR_Write(cxt->m_digestFile, buf, len);}SECItem*SSM_NicknameCollisionCallback(SECItem *old_nick, PRBool *cancel,                              void *wincx){    /* We don't handle this yet */    *cancel = PR_TRUE;    return NULL;}static PK11SlotInfo*SSMPKCS12Context_ChooseSlotForImport(SSMPKCS12Context *cxt,                                     PK11SlotList     *slotList){    char mech[20];    SSMStatus rv;    PR_snprintf(mech, 20, "mech=%d&task=import&unused=unused", CKM_RSA_PKCS);    SSM_LockUIEvent(&cxt->super);    rv = SSMControlConnection_SendUIEvent(cxt->super.m_connection,                                           "get",                                           "select_token",                                          &cxt->super,                                          mech,                                           &SSMRESOURCE(cxt)->m_clientContext,                                          PR_TRUE);    if (rv != SSM_SUCCESS) {        SSM_UnlockResource(&cxt->super);        return NULL;    }    SSM_WaitUIEvent(&cxt->super, PR_INTERVAL_NO_TIMEOUT);    /* Wait so damn window goes away without swallowing up     * the password prompt that will come up next.     */    PR_Sleep(PR_TicksPerSecond());    return (PK11SlotInfo*)cxt->super.m_uiData;}static PK11SlotInfo*SSMPKCS12Context_GetSlotForImport(SSMPKCS12Context *cxt){    PK11SlotList *slotList;    PK11SlotInfo *slot = NULL;    slotList = PK11_GetAllTokens(CKM_RSA_PKCS, PR_TRUE, PR_TRUE,                                 cxt->super.m_connection);    if (slotList == NULL || slotList->head == NULL) {

⌨️ 快捷键说明

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