p12res.c

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

C
1,026
字号
/* -*- 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"#include "nlslayer.h"#define SSMRESOURCE(object) (&object->super)#define PKCS12_IN_BUFFER_SIZE 2048static SSMStatusssmpkcs12context_createpkcs12file(SSMPKCS12Context *cx,                                  PRBool forceAuthenticate,                                  CERTCertificate **certArr,                                  PRIntn numCerts);#ifdef XP_MACchar* SSM_ConvertMacPathToUnix(char *path){	char *cursor;	int len;			len = PL_strlen(path);	cursor = PR_Realloc(path, len+2);	memmove(cursor+1, cursor, len+1);	path = cursor;	*cursor = '/';	while ((cursor = PL_strchr(cursor, ':')) != NULL) {		*cursor = '/';		cursor++;	}	return path;}#endifSECStatusSSM_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;    PRUint32 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,                                          PR_TRUE);    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_NeedLogin(slot)) {        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;

⌨️ 快捷键说明

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