processmsg.c

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

C
2,164
字号
/* -*- 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 "ctrlconn.h"#include "dataconn.h"#include "sslconn.h"#include "servimpl.h"#include "serv.h"#include "ssmerrs.h"#include "certt.h"#include "keyres.h"#include "crmfres.h"#include "kgenctxt.h"#include "processmsg.h"#include "signtextres.h"#include "textgen.h"#include "secmod.h"#include "cert.h"#include "newproto.h"#include "messages.h"#include "signtextres.h"#include "advisor.h"#include "ssl.h"#include "protocolshr.h"#include "msgthread.h"#include "pk11sdr.h"#include "sdrres.h"#define SSL_SC_RSA              0x00000001L#define SSL_SC_MD2              0x00000010L#define SSL_SC_MD5              0x00000020L#define SSL_SC_RC2_CBC          0x00001000L#define SSL_SC_RC4              0x00002000L#define SSL_SC_DES_CBC          0x00004000L#define SSL_SC_DES_EDE3_CBC     0x00008000L#define SSL_SC_IDEA_CBC         0x00010000L/* The ONLY reason why we can use these macros for both control and   data connections is that they inherit from the same superclass.   Do NOT try this at home. */#define SSMCONNECTION(c) (&(c)->super)#define SSMRESOURCE(c) (&(c)->super.super)SSMStatusSSMControlConnection_ProcessGenKeyOldStyleToken(SSMControlConnection * ctrl,                                                 SECItem * msg){    GenKeyOldStyleTokenReply reply;    SSMResource * res;    SSMStatus rv = PR_FAILURE;    /* message contains token name to use for KEYGEN */    if (CMT_DecodeMessage(GenKeyOldStyleTokenReplyTemplate, &reply,                           (CMTItem*)msg) != CMTSuccess)       goto loser;        rv = SSMControlConnection_GetResource(ctrl, reply.rid, &res);    if (rv != SSM_SUCCESS || !res)        goto loser;        if (!reply.cancel)         res->m_uiData = (void *)PK11_FindSlotByName(reply.tokenName);    SSM_NotifyUIEvent(res);    /* now generate the key */    rv = SSM_ERR_DEFER_RESPONSE; loser:    if (res)  /* release reference */        SSM_FreeResource(res);    return rv;}SSMStatusSSMControlConnection_ProcessGenKeyPassword(SSMControlConnection * ctrl,                                           SECItem * msg){    GenKeyOldStylePasswordReply passwordreply;    SSMStatus rv = SSM_FAILURE;    SSMResource * res = NULL;    PK11SlotInfo *slot = NULL;    if (CMT_DecodeMessage(GenKeyOldStylePasswordReplyTemplate, &passwordreply,                           (CMTItem*)msg) != CMTSuccess)         goto loser;      rv = SSMControlConnection_GetResource(ctrl, passwordreply.rid, &res);    if (rv != SSM_SUCCESS)         goto loser;        if (!SSM_IsAKindOf(res, SSM_RESTYPE_KEYGEN_CONTEXT))        goto loser;        slot = ((SSMKeyGenContext *)res)->slot;    /* we are here because there is no password on the slot */    if (!passwordreply.cancel)        PK11_InitPin(slot, NULL, passwordreply.password);    SSM_NotifyUIEvent(res);    rv = SSM_ERR_DEFER_RESPONSE;     loser:    return rv;}/* Thread functions for SDR_ENCRYPT */static SSMStatussdrencrypt(SSMControlConnection *ctrl, SECItem *msg){  SSMStatus rv = SSM_SUCCESS;  CMTStatus crv;  PK11SlotInfo *slot = PK11_GetInternalKeySlot();  EncryptRequestMessage request;  EncryptReplyMessage reply;  SECStatus s;  SSMResourceID id;  SSMResource *res = NULL;  SSM_DEBUG("sdrEncrypt\n");  request.keyid.data = NULL;  request.data.data = NULL;  request.ctx.data = NULL;  reply.item.data = NULL;  /* Decode the message (frees message data) */  crv = CMT_DecodeMessage(EncryptRequestTemplate, &request, (CMTItem*)msg);  if (crv != CMTSuccess) { rv = SSM_FAILURE; goto loser; }  /* Create a resource for handling UI events */  rv = SSM_CreateResource(SSM_RESTYPE_SDR_CONTEXT, 0, ctrl, &id, &res);  if (rv != SSM_SUCCESS) goto loser;  /* Set client context field for UI events   * NOTE: the resource will be deleted before the request data   * is freed   */  res->m_clientContext = request.ctx;  /* Make sure user has initialized database password */  if (PK11_NeedUserInit(slot)) {    SSM_DEBUG("Calling SSM_SetUserPassword\n");    rv = SSM_SetUserPassword(slot, res);    SSM_DEBUG("SSM_SetUserPassword returns %d\n", rv);    if (rv != SSM_SUCCESS) { rv = SSM_ERR_NEED_USER_INIT_DB; goto loser; }  }  if (PK11_Authenticate(PK11_GetInternalKeySlot(), PR_TRUE, res) != SECSuccess) {    rv = SSM_ERR_BAD_DB_PASSWORD;    goto loser;  }  s = PK11SDR_Encrypt((SECItem*)&request.keyid, (SECItem*)&request.data,           (SECItem*)&reply.item, res);  SSM_DEBUG("Encrypt returns %d\n", s);  SSM_DEBUG("  -> Item: %lx (%d)\n", reply.item.data, reply.item.len);  /* Generate response */  msg->type = SSM_SDR_ENCRYPT_REPLY;  crv = CMT_EncodeMessage(EncryptReplyTemplate, (CMTItem*)msg, &reply);  if (crv != CMTSuccess) { rv = SSM_FAILURE; goto loser;  /* Unknown error */ }loser:  if (res) SSM_FreeResource(res);  if (request.keyid.data) PR_Free(request.keyid.data);  if (request.data.data) PR_Free(request.data.data);  if (request.ctx.data) PR_Free(request.ctx.data);  if (reply.item.data) PR_Free(reply.item.data);  return rv;}static SSMStatussdrdecrypt(SSMControlConnection *ctrl, SECItem *msg){  SSMStatus rv = SSM_SUCCESS;  CMTStatus crv;  SECStatus s;  DecryptRequestMessage request;  DecryptReplyMessage reply;  SSMResourceID id;  SSMResource *res = NULL;  request.data.data = NULL;  request.ctx.data = NULL;  reply.item.data = NULL;  SSM_DEBUG("sdrDecrypt\n");  crv = CMT_DecodeMessage(DecryptRequestTemplate, &request, (CMTItem*)msg);  if (crv != CMTSuccess) { rv = SSM_FAILURE; goto loser; }  /* Create a resource for handling UI events */  rv = SSM_CreateResource(SSM_RESTYPE_SDR_CONTEXT, 0, ctrl, &id, &res);  if (rv != SSM_SUCCESS) goto loser;  /* Set client context field for UI events   * NOTE: the resource will be deleted before the request data   * is freed   */  res->m_clientContext = request.ctx;  if (PK11_Authenticate(PK11_GetInternalKeySlot(), PR_TRUE, res) != SECSuccess) {    rv = SSM_ERR_BAD_DB_PASSWORD;    goto loser;  }  s = PK11SDR_Decrypt((SECItem*)&request.data, (SECItem*)&reply.item, res);  if (s != SECSuccess) { rv = SSM_FAILURE; goto loser; }  msg->type = SSM_SDR_DECRYPT_REPLY;  crv = CMT_EncodeMessage(DecryptReplyTemplate, (CMTItem*)msg, &reply);  if (crv != CMTSuccess) { rv = SSM_FAILURE; goto loser;  /* Unknown error */ }loser:  if (res) SSM_FreeResource(res);  if (request.data.data) PR_Free(request.data.data);  if (request.ctx.data) PR_Free(request.ctx.data);  if (reply.item.data) PR_Free(reply.item.data);  return rv;}static SSMStatussdrChangePassword(SSMControlConnection *ctrl, SECItem *msg){  SSMStatus rv = SSM_SUCCESS;  SingleItemMessage req;  PK11SlotInfo *slot = PK11_GetInternalKeySlot();  SSMResourceID id;  SSMResource *res = NULL;  SSM_DEBUG("sdrChangePassword\n");  req.item.data = 0;  if (CMT_DecodeMessage(SingleItemMessageTemplate, &req, (CMTItem*)msg) != CMTSuccess) {    rv = SSM_FAILURE;    goto loser;  }  /* Create a resource for handling UI events */  rv = SSM_CreateResource(SSM_RESTYPE_SDR_CONTEXT, 0, ctrl, &id, &res);  if (rv != SSM_SUCCESS) goto loser;  /* Set client context field for UI events   * NOTE: the resource will be deleted before the request data   * is freed   */  res->m_clientContext = req.item;    /* Invoke the UI for setting password */  rv = SSM_SetUserPassword(slot, res);loser:  if (res) SSM_FreeResource(res);  if (req.item.data) PR_Free(req.item.data);  return rv;}static SSMStatusProcessMiscUI(SSMControlConnection *ctrl, SECItem *msg){  SSMStatus rv;  rv = SSM_ProcessMsgOnThreadReply(sdrChangePassword, ctrl, msg);  msg->type = (SSM_REPLY_OK_MESSAGE|SSM_MISC_ACTION|SSM_MISC_UI|SSM_UI_CHANGE_PASSWORD);  return rv;}SSMStatus SSMControlConnection_ProcessMiscRequest(SSMControlConnection * ctrl,                                         SECItem * msg){    SingleNumMessage req;    SingleItemMessage reply;    char *buf = NULL;    SSMStatus rv = SSM_SUCCESS;    SECStatus srv;      SSM_DEBUG("Got a misc request.\n");    switch (msg->type & SSM_SUBTYPE_MASK)     {    case SSM_MISC_GET_RNG_DATA:        if (CMT_DecodeMessage(SingleNumMessageTemplate, &req,                               (CMTItem*)msg) != CMTSuccess)             goto loser;          /* Generate as much random data as they want. */        SSM_DEBUG("The client wants %ld bytes of random data.\n", req.value);        buf = (char *) PR_CALLOC(req.value);        if (!buf)            goto loser;        srv = RNG_GenerateGlobalRandomBytes(buf, req.value);        if (srv != SECSuccess)            goto loser;        /* Presumably we have random bytes now. Send them back. */        reply.item.len = req.value;        reply.item.data = (unsigned char *) buf;        if (CMT_EncodeMessage(SingleItemMessageTemplate, (CMTItem*)msg, &reply) != CMTSuccess)            goto loser;        if (msg->data == NULL || msg->len == 0)             goto loser;        msg->type = (SECItemType) (SSM_REPLY_OK_MESSAGE | SSM_MISC_ACTION | SSM_MISC_GET_RNG_DATA);        goto done;    case SSM_MISC_SDR_ENCRYPT:	rv = SSM_ProcessMsgOnThread(sdrencrypt, ctrl, msg);	if (rv != PR_SUCCESS) goto loser;        rv = SSM_ERR_DEFER_RESPONSE;        goto done;    case SSM_MISC_SDR_DECRYPT:	rv = SSM_ProcessMsgOnThread(sdrdecrypt, ctrl, msg);        if (rv != PR_SUCCESS) goto loser;        rv = SSM_ERR_DEFER_RESPONSE;        goto done;    case SSM_MISC_UI:        rv = ProcessMiscUI(ctrl, msg);        if (rv != PR_SUCCESS) goto loser;/*         rv = SSM_ERR_DEFER_RESPONSE; */        goto done;    case SSM_MISC_PUT_RNG_DATA:    default:        SSM_DEBUG("Unknown misc request (%lx).\n", (msg->type & SSM_SUBTYPE_MASK));        goto loser;    }    goto done; loser:    SSM_DEBUG("ProcessMiscRequest: loser hit, rv = %ld.\n",              rv);    if (msg->data)    {        PR_Free(msg->data);        msg->data = NULL;        msg->len = 0;    }    if (rv == PR_SUCCESS) rv = PR_FAILURE; done:    if (buf)        PR_Free(buf);    return rv;}SSMStatus SSMControlConnection_ProcessCertRequest(SSMControlConnection * ctrl,                                         SECItem * msg){  SSMStatus rv = PR_SUCCESS;    SSM_DEBUG("Got a cert-related request.\n");  switch (msg->type & SSM_SUBTYPE_MASK) {  case SSM_VERIFY_CERT:    rv = SSMControlConnection_ProcessVerifyCertRequest(ctrl, msg);    break;  case SSM_IMPORT_CERT:    rv = SSMControlConnection_ProcessImportCertRequest(ctrl, msg);    break;  case SSM_DECODE_CERT:    rv = SSMControlConnection_ProcessDecodeCertRequest(ctrl, msg);    break;  case SSM_FIND_BY_NICKNAME:    rv = SSMControlConnection_ProcessFindCertByNickname(ctrl, msg);    break;  case SSM_FIND_BY_KEY:    rv = SSMControlConnection_ProcessFindCertByKey(ctrl, msg);    break;  case SSM_FIND_BY_EMAILADDR:    rv = SSMControlConnection_ProcessFindCertByEmailAddr(ctrl, msg);    break;  case SSM_ADD_TO_DB:    rv = SSMControlConnection_ProcessAddCertToDB(ctrl, msg);    break;  case SSM_MATCH_USER_CERT:    rv = SSMControlConnection_ProcessMatchUserCert(ctrl, msg);    break;  case SSM_DESTROY_CERT:    rv = SSMControlConnection_ProcessDestroyCert(ctrl, msg);    break;  case SSM_DECODE_TEMP_CERT:    rv = SSMControlConnection_ProcessDecodeAndCreateTempCert(ctrl, msg);    break;  case SSM_REDIRECT_COMPARE:    rv = SSMControlConnection_ProcessRedirectCompare(ctrl, msg);    break;  case SSM_DECODE_CRL:    rv = SSMControlConnection_ProcessDecodeCRLRequest(ctrl, msg);    break;  case SSM_EXTENSION_VALUE:    rv = SSMControlConnection_ProcessGetExtensionRequest(ctrl, msg);    break;

⌨️ 快捷键说明

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