⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 p12res.c

📁 安全开发库。含客户端建立ssl连接、签名、证书验证、证书发布和撤销等。编译用到nss
💻 C
📖 第 1 页 / 共 2 页
字号:
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- *//*  * 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 "p12res.h"#include "minihttp.h"#include "pk11func.h"#include "secmod.h"#include "p12.h"#include "p12plcy.h"#include "secerr.h"#include "newproto.h"#include "messages.h"#include "advisor.h"#define SSMRESOURCE(object) (&object->super)#define PKCS12_IN_BUFFER_SIZE 2048static SSMStatusssmpkcs12context_createpkcs12file(SSMPKCS12Context *cx,                                  PRBool forceAuthenticate,                                  CERTCertificate **certArr,                                  PRIntn numCerts);SECStatusSSM_UnicodeConversion(SECItem *dest, SECItem *src,                      PRBool toUnicode, PRBool swapBytes){    unsigned int allocLen;    if(!dest || !src) {        return SECFailure;    }    allocLen = ((toUnicode) ? (src->len << 2) : src->len);    if (allocLen == 0) {        /* empty string: we need to pad it by 2 bytes */        allocLen = 2;    }    dest->data = SSM_ZNEW_ARRAY(unsigned char, allocLen);    if(!SSM_UCS2_ASCIIConversion(toUnicode, src->data, src->len,                                 dest->data, allocLen, &dest->len,                                 swapBytes)) {        PR_Free(dest->data);        dest->data = NULL;        return SECFailure;    }    return SECSuccess;}SSMStatusSSMPKCS12Context_Create(void *arg, SSMControlConnection *ctrl,                        SSMResource **res){    SSMPKCS12Context *cxt = NULL;    SSMPKCS12CreateArg *createArg = (SSMPKCS12CreateArg*)arg;    SSMStatus rv;      cxt = SSM_ZNEW(SSMPKCS12Context);    if (cxt == NULL) {        return SSM_ERR_OUT_OF_MEMORY;    }    rv = SSMPKCS12Context_Init(ctrl,cxt,SSM_RESTYPE_PKCS12_CONTEXT ,                               createArg->isExportContext);    if (rv != PR_SUCCESS) {        goto loser;    }    *res = SSMRESOURCE(cxt);    return PR_SUCCESS; loser:    if (cxt != NULL) {        SSM_FreeResource(SSMRESOURCE(cxt));    }    *res = NULL;    return rv;}SSMStatusSSMPKCS12Context_Init(SSMControlConnection *ctrl, SSMPKCS12Context *res,                      SSMResourceType type, PRBool isExportContext){    res->m_isExportContext = isExportContext;    res->m_password        = NULL;    res->m_inputProcessed  = PR_FALSE;    res->m_file            = NULL;    res->m_digestFile      = NULL;    res->m_error           = PR_FALSE;    return SSMResource_Init(ctrl, SSMRESOURCE(res), type);}SSMStatusSSMPKCS12Context_Destroy(SSMResource *res, PRBool doFree) {    SSMPKCS12Context *cxt = (SSMPKCS12Context*)res;        SSMResource_Destroy(res, PR_FALSE);    if (cxt->m_password != NULL) {        PR_Free(cxt->m_password);        cxt->m_password = NULL;    }    if (cxt->m_cert != NULL) {        CERT_DestroyCertificate(cxt->m_cert);        cxt->m_cert = NULL;    }    if (doFree) {        PR_Free(res);    }    return PR_SUCCESS;}static SSMStatusSSMPKCS12Context_HandlePasswordRequest(SSMResource *res,                                       HTTPRequest *req)    {    char *password, *confirmPassword;    SSMPKCS12Context *p12Cxt = (SSMPKCS12Context*)res;     SSMStatus rv = SSM_FAILURE;        /* Let's get the password out of the dialog. */    if (res->m_buttonType != SSM_BUTTON_OK) {        goto loser;    }    rv = SSM_HTTPParamValue(req, "passwd", &password);    if (rv != SSM_SUCCESS) {        goto loser;    }    rv = SSM_HTTPParamValue(req, "confirmPasswd", &confirmPassword);    if (rv != SSM_SUCCESS) {        goto loser;    }    if (strcmp(password, confirmPassword) != 0) {        /* Should re-prompt, but for now we fail. */        rv = SSM_FAILURE;        goto loser;    }    p12Cxt->m_password = PL_strdup(password);    goto done; loser:    p12Cxt->m_password = NULL; done:    SSM_LockResource(res);    SSM_NotifyResource(res);    SSM_UnlockResource(res);    SSM_HTTPDefaultCommandHandler(req);    p12Cxt->m_inputProcessed = PR_TRUE;    return rv;}SSMStatusSSMPKCS12Context_FormSubmitHandler(SSMResource *res, HTTPRequest *req){    char *formName;    SSMStatus rv=SSM_FAILURE;        rv = SSM_HTTPParamValue(req, "formName", &formName);    if (rv != SSM_SUCCESS) {        goto loser;    }    if (!strcmp(formName, "cert_backup_form")) {        rv = SSMPKCS12Context_HandlePasswordRequest(res, req);    } else if (!strcmp(formName, "set_db_password")) {      rv = SSM_SetDBPasswordHandler(req);    } else {        goto loser;    }    return rv; loser:    SSM_HTTPDefaultCommandHandler(req);    return SSM_FAILURE;}static voidssmpkcs12context_writetoexportfile(void *arg, const char *buf,                                    unsigned long len){    SSMPKCS12Context *p12Cxt = (SSMPKCS12Context*)arg;    PRInt32 bytesWritten;    if (p12Cxt == NULL) {        return;    }    if (p12Cxt->m_file == NULL) {        p12Cxt->m_error = PR_TRUE;        return;    }    bytesWritten = PR_Write(p12Cxt->m_file, buf, len);    if (bytesWritten != len) {        p12Cxt->m_error = PR_TRUE;    }}SSMStatusSSMPKCS12Context_CreatePKCS12FileForMultipleCerts(SSMPKCS12Context *p12Cxt,                                                   PRBool forceAuthenticate,                                                  CERTCertificate **certArr,                                                  PRIntn numCerts){    return ssmpkcs12context_createpkcs12file(p12Cxt, forceAuthenticate,                                              certArr, numCerts);}SSMStatusSSMPKCS12Context_CreatePKCS12File(SSMPKCS12Context *cxt,                                   PRBool forceAuthenticate){    return ssmpkcs12context_createpkcs12file(cxt, forceAuthenticate,                                              &cxt->m_cert, 1);}static SSMStatusssmpkcs12context_createpkcs12file(SSMPKCS12Context *cxt,                                  PRBool forceAuthenticate,                                  CERTCertificate **certArr,                                  PRIntn numCerts){    SEC_PKCS12ExportContext *p12ecx  = NULL;    SEC_PKCS12SafeInfo      *keySafe = NULL, *certSafe = NULL;    SECItem                  pwitem  = { siBuffer, NULL, 0 };    PK11SlotInfo            *slot    = NULL;    PK11SlotInfo            *slotToUse = NULL;    SSMControlConnection    *ctrl;     SSMStatus                rv=SSM_FAILURE;    int                      i;        if (cxt == NULL || certArr == NULL || numCerts == 0) {        return SSM_ERR_BAD_REQUEST;    }    /*     * We're about to send the UI event requesting the password to use     * when encrypting      */    SSM_LockResource(&cxt->super);    cxt->m_inputProcessed = PR_FALSE;    rv = SSMControlConnection_SendUIEvent(SSMRESOURCE(cxt)->m_connection,                                          "get", "cert_backup",                                          SSMRESOURCE(cxt),                                           (numCerts > 1) ? "multipleCerts=1" :                                                           NULL,                                           &SSMRESOURCE(cxt)->m_clientContext);    if (rv != SSM_SUCCESS) {        SSM_UnlockResource(SSMRESOURCE(cxt));        goto loser;    }    /*     * Wait until the form is submitted to proceed. We'll get notified.     */    SSM_WaitResource(SSMRESOURCE(cxt), PR_INTERVAL_NO_TIMEOUT);    SSM_UnlockResource(SSMRESOURCE(cxt));    if (cxt->m_password == NULL ||         cxt->super.m_buttonType == SSM_BUTTON_CANCEL) {        rv = SSM_ERR_NO_PASSWORD;        goto loser;    }    /* Wait for the dialog box to go down so that when it disappears,     * the window doesn't take away the password prompt.     */    PR_Sleep(PR_TicksPerSecond());    ctrl = SSMRESOURCE(cxt)->m_connection;    pwitem.data = (unsigned char *) cxt->m_password;    pwitem.len  = strlen(cxt->m_password);    PK11_FindObjectForCert(certArr[0], ctrl, &slot);    if (slot == NULL) {        rv = SSM_FAILURE;        goto loser;    }    slotToUse = slot;    if (forceAuthenticate) {        PK11_Logout(slot);    }    if (PK11_Authenticate(slot, PR_TRUE, ctrl) != SECSuccess) {        rv = SSM_ERR_BAD_DB_PASSWORD;        goto loser;    }    p12ecx = SEC_PKCS12CreateExportContext(NULL, NULL, slot, ctrl);    if (p12ecx == NULL) {        rv = SSM_FAILURE;        goto loser;    }    if (SEC_PKCS12AddPasswordIntegrity(p12ecx, &pwitem, SEC_OID_SHA1)         != SECSuccess) {        rv = SSM_ERR_BAD_PASSWORD;        goto loser;    }    for (i=0; i <numCerts; i++) {        PK11_FindObjectForCert(certArr[i], ctrl, &slot);        if (slot != slotToUse) {            continue;        }        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;    }    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;}/* 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;	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 = ssm_ConvertAsciiToUCS2(inBuf, inBufLen, 				    outBuf, maxOutBufLen, 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    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 = ssm_UTF8ToUCS2(inBuf, inBufLen, outBuf, maxOutBufLen,                                  outBufLen);    } else {    	retval = ssm_UCS2ToUTF8(inBuf, inBufLen, outBuf, maxOutBufLen,                                  outBufLen);	}#ifdef DEBUG    fprintf(stderr,"Output: \n");   	for(i=0; i< *outBufLen; i++) {		fprintf(stderr,"%c", (char) outBuf[i]);

⌨️ 快捷键说明

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