📄 processmsg.c
字号:
/* -*- 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"/* The ONLY reason why we can use these macros for both control and data connections is that they inherit from the same superclass. */#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;}SSMStatus SSMControlConnection_ProcessMiscRequest(SSMControlConnection * ctrl, SECItem * msg){ SingleNumMessage req; SingleItemMessage reply; char *buf; 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; /* REMOVED CALL */; 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_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; case SSM_HTML_INFO: rv = SSMControlConnection_ProcessHTMLCertInfoRequest(ctrl, msg); break; default: SSM_DEBUG("Unknown cert request (%lx).\n", (msg->type & SSM_SUBTYPE_MASK)); goto loser; } goto done; loser: SSM_DEBUG("ProcessCertRequest: 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: return rv;}PRStatusSSMControlConnection_ProcessKeygenTag(SSMControlConnection * ctrl, SECItem * msg){ SSMStatus rv = PR_SUCCESS; SSM_DEBUG("Got a KEYGEN form tag processing request.\n"); switch (msg->type & SSM_SUBTYPE_MASK) { case SSM_GET_KEY_CHOICE: rv = SSMControlConnection_ProcessGetKeyChoiceList(ctrl, msg); break; case SSM_KEYGEN_TOKEN: rv = SSMControlConnection_ProcessGenKeyOldStyleToken(ctrl, msg); break; case SSM_KEYGEN_PASSWORD: rv = SSMControlConnection_ProcessGenKeyPassword(ctrl, msg); break; case SSM_KEYGEN_START: /* We might need to do another message exchange before * we complete this request, to get slot password. * Therefore, generate keys on a separate thread, * and let this thread service other messages. */ { genKeyArg * arg = (genKeyArg *) PR_Malloc(sizeof(genKeyArg)); if (!arg) SSM_DEBUG("Memory allocation error!\n"); arg->ctrl = ctrl; arg->msg = SECITEM_DupItem(msg); if (SSM_CreateAndRegisterThread(PR_USER_THREAD, SSMControlConnection_ProcessGenKeyOldStyle, (void *)arg, PR_PRIORITY_NORMAL, PR_LOCAL_THREAD, PR_UNJOINABLE_THREAD, 0)== NULL) { SSM_DEBUG("Can't start a new thread for old-style keygen!\n"); rv = SSM_FAILURE; } else rv = SSM_ERR_DEFER_RESPONSE; } break; default: SSM_DEBUG("Unknown KEYGEN request (%lx).\n", (msg->type & SSM_SUBTYPE_MASK)); goto loser; } goto done;loser: SSM_DEBUG("ProcessKeygenTag: 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: return (PRStatus) rv;} SSMStatus SSMControlConnection_ProcessVerifyCertRequest(SSMControlConnection * ctrl, SECItem * msg){ SSMResource *obj; SSMStatus rv; VerifyCertRequest request; SingleNumMessage reply; SSM_DEBUG("Got a Cert Verify request.\n"); /* Decode message and get resource/field ID */ if (CMT_DecodeMessage(VerifyCertRequestTemplate, &request, (CMTItem*)msg) != CMTSuccess) { goto loser; } msg->data = NULL; SSM_DEBUG("Rsrc ID %ld, certUsage %d.\n", request.resID, request.certUsage); rv = SSMControlConnection_GetResource(ctrl, request.resID, &obj); if (rv != PR_SUCCESS) goto loser; PR_ASSERT(obj != NULL); /* getting this far means success, send the result of verification */ rv = SSM_VerifyCert((SSMResourceCert *)obj, (SECCertUsage) request.certUsage); msg->data = NULL; msg->len = 0; msg->type = (SECItemType) (SSM_CERT_ACTION | SSM_VERIFY_CERT | SSM_REPLY_OK_MESSAGE); reply.value = rv; if (CMT_EncodeMessage(SingleNumMessageTemplate, (CMTItem*)msg, &reply) != CMTSuccess) { goto loser; } if (msg->data == NULL || msg->len == 0) goto loser; return PR_SUCCESS; /* something went wrong, could not perform cert verification */loser: return PR_FAILURE;}SSMStatusSSMControlConnection_ProcessDecodeCertRequest(SSMControlConnection * ctrl, SECItem * msg){ SSMStatus rv; CERTCertificate * cert; SSMResourceID certID; SSMResource * certRes; SingleItemMessage request; SingleNumMessage reply; SSM_DEBUG("Got an DecodeCert request.\n"); /* Decode message */ if (CMT_DecodeMessage(SingleItemMessageTemplate, &request, (CMTItem*)msg) != CMTSuccess) { goto loser; } msg->data = NULL; msg->len = 0; /* decode the cert */ cert = CERT_DecodeCertFromPackage((char *) request.item.data, (int) request.item.len); if (!cert) { SSM_DEBUG("Can't decode a cert from the buffer!\n"); goto loser; } /* create cert resource for this new cert */ rv = SSM_CreateResource(SSM_RESTYPE_CERTIFICATE, cert, ctrl, &certID, &certRes); if (rv != PR_SUCCESS) { SSM_DEBUG("In decode cert: can't create certificate resource.\n"); goto loser; } SSM_ClientGetResourceReference(certRes, NULL); msg->type = (SECItemType) (SSM_REPLY_OK_MESSAGE | SSM_CERT_ACTION | SSM_DECODE_CERT); reply.value = certID; if (CMT_EncodeMessage(SingleNumMessageTemplate, (CMTItem*)msg, &reply) != CMTSuccess) { goto loser; } if (!msg->data || msg->len == 0) goto loser; return PR_SUCCESS;loser: /* compose error reply */ msg->type = (SECItemType) (SSM_REPLY_ERR_MESSAGE | SSM_CERT_ACTION | SSM_DECODE_CERT); if (msg->data) PR_Free(msg->data); msg->data = NULL; msg->len = 0; return PR_FAILURE;}char *SSMControlConnection_GenerateKeyOldStyle(SSMControlConnection * ctrl, char * choiceString, char * challenge, char * typeString, char * pqgString);void SSMControlConnection_ProcessGenKeyOldStyle(void * arg) { char * choiceString = NULL; char * challenge = NULL; char * typeString = NULL; char * pqgString = NULL; char * keydata = NULL; GenKeyOldStyleRequest request; SingleStringMessage reply; genKeyArg * myarg = (genKeyArg *)arg; CMTItem * msg = (CMTItem*)myarg->msg; SSMControlConnection * ctrl = myarg->ctrl; SSMStatus rv = SSM_FAILURE; if (CMT_DecodeMessage(GenKeyOldStyleRequestTemplate, &request, (CMTItem*)msg) != CMTSuccess) { goto loser; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -