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