📄 signtextres.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 "serv.h"#include "minihttp.h"#include "signtextres.h"#include "protocolf.h"#include "base64.h"#include "secmime.h"#include "newproto.h"#include "messages.h"#include "certres.h"#define SSMRESOURCE(object) (&(object)->super)SSMStatusSSM_CreateSignTextRequest(SECItem *msg, SSMControlConnection *conn) { SSMStatus rv; signTextRequestData *signTextData = NULL; SSMSignTextResource *signTextRes = NULL; int i; SignTextRequest request; /* Decode the sign text protocol message */ if (CMT_DecodeMessage(SignTextRequestTemplate, &request, (CMTItem*)msg) != CMTSuccess) { goto loser; } /* Get the resource */ rv = SSMControlConnection_GetResource(conn, (SSMResourceID)request.resID, (SSMResource**)&signTextRes); if ((rv != PR_SUCCESS) || (signTextRes == NULL)) { goto loser; } /* Get a reference to it */ SSM_GetResourceReference(SSMRESOURCE(signTextRes)); if (!SSM_IsAKindOf(SSMRESOURCE(signTextRes), SSM_RESTYPE_SIGNTEXT)) { goto loser; } /* Set the request data */ signTextRes->m_stringToSign = PL_strdup(request.stringToSign); signTextRes->m_hostName = PL_strdup(request.hostName); if (PL_strcasecmp(request.caOption, "auto") == 0) { signTextRes->m_autoFlag = PR_TRUE; } else if (PL_strcasecmp(request.caOption, "ask") == 0) { signTextRes->m_autoFlag = PR_FALSE; } else { goto loser; } signTextRes->m_numCAs = request.numCAs; if (signTextRes->m_numCAs > 0) { signTextRes->m_caNames = (char **) PR_CALLOC(sizeof(char*)*(signTextRes->m_numCAs)); if (!signTextRes->m_caNames) { goto loser; } for (i=0;i<signTextRes->m_numCAs;i++) { signTextRes->m_caNames[i] = PL_strdup(request.caNames[i]); } } signTextRes->m_conn = conn; signTextRes->m_action = SIGN_TEXT_WAITING; signTextRes->m_thread = SSM_CreateAndRegisterThread(PR_USER_THREAD, SSMSignTextResource_ServiceThread, (void*)signTextRes, PR_PRIORITY_NORMAL, PR_LOCAL_THREAD, PR_UNJOINABLE_THREAD, 0); if (!signTextRes->m_thread) { goto loser; } return PR_SUCCESS;loser: /* XXX Free request */ return PR_FAILURE;}SSMStatusSSMSignTextResource_Create(void *arg, SSMControlConnection * conn, SSMResource **res){ SSMSignTextResource *signTextRes; SSMStatus rv; signTextRes = PR_NEWZAP(SSMSignTextResource); if (!signTextRes) { goto loser; } rv = SSMSignTextResource_Init(conn, signTextRes, SSM_RESTYPE_SIGNTEXT); if (rv != PR_SUCCESS) { goto loser; } *res = SSMRESOURCE(signTextRes); return PR_SUCCESS;loser: if (signTextRes != NULL) { SSM_FreeResource(SSMRESOURCE(signTextRes)); } *res = NULL; return PR_FAILURE;}SSMStatusSSMSignTextResource_Init(SSMControlConnection *conn, SSMSignTextResource *in, SSMResourceType type){ SSMStatus rv; rv = SSMResource_Init(conn, SSMRESOURCE(in), type); if (rv != PR_SUCCESS) { goto loser; } /* Set all our data to zero */ in->m_stringToSign = NULL; in->m_hostName = NULL; in->m_autoFlag = PR_FALSE; in->m_numCAs = 0; in->m_caNames = NULL; in->m_conn = conn; in->m_thread = NULL; in->m_certs = NULL; in->m_action = SIGN_TEXT_INIT; in->m_nickname = NULL; in->m_resultString = NULL; return PR_SUCCESS;loser: return PR_FAILURE;}SSMStatus SSMSignTextResource_Destroy(SSMResource *res, PRBool doFree){ SSMSignTextResource *signTextRes = (SSMSignTextResource*)res; if (res == NULL) { return PR_FAILURE; } PR_ASSERT(res->m_threadCount == 0); /* Free our data */ /* Destroy the super class */ SSMResource_Destroy(res, PR_FALSE); /* Free our memory */ if (doFree) { PR_DELETE(signTextRes); } return PR_SUCCESS;}SSMStatus SSMSignTextResource_Shutdown(SSMResource *arg, SSMStatus status){ return PR_SUCCESS;}voidSSMSignTextResource_SendTaskCompletedEvent(SSMSignTextResource *res){ SECItem msg; SSMStatus rv; TaskCompletedEvent event; /* Assemble the event. */ SSM_DEBUG("Sign Text Resource Task completed event: id %ld, status %d\n", SSMRESOURCE(res)->m_id, SSMRESOURCE(res)->m_status); event.resourceID = SSMRESOURCE(res)->m_id; event.numTasks = 0; event.result = SSMRESOURCE(res)->m_status; if (CMT_EncodeMessage(TaskCompletedEventTemplate, (CMTItem*)&msg, &event) != CMTSuccess) { return; } if (msg.data) { /* Send the event to the control queue. */ rv = SSM_SendQMessage(SSMRESOURCE(res)->m_connection->m_controlOutQ, SSM_PRIORITY_NORMAL, SSM_EVENT_MESSAGE | SSM_TASK_COMPLETED_EVENT, (int) msg.len, (char *) msg.data, PR_FALSE); SSM_DEBUG("Sent message, rv = %d.\n", rv); }}voidSSMSignTextResource_ServiceThread(void *arg){ SSMSignTextResource *signTextRes = (SSMSignTextResource*)arg; SSMStatus rv; unsigned char hashVal[SHA1_LENGTH]; SECItem digest, signedResult, *tmpItem; SEC_PKCS7ContentInfo *ci = NULL; CERTCertificate *cert = NULL; CERTCertListNode *node; int i,numCerts; SSM_LockResource(SSMRESOURCE(signTextRes)); PR_ASSERT(signTextRes); PR_ASSERT(SSM_IsAKindOf(SSMRESOURCE(signTextRes), SSM_RESTYPE_SIGNTEXT)); memset(&signedResult, 0, sizeof(SECItem)); /* Get the certificates */ signTextRes->m_certs = CERT_MatchUserCert(signTextRes->m_conn->m_certdb, certUsageEmailSigner, signTextRes->m_numCAs, signTextRes->m_caNames, signTextRes->m_conn); numCerts = SSM_CertListCount(signTextRes->m_certs); if((signTextRes->m_certs == NULL) || (numCerts == 0)) { signTextRes->m_resultString = strdup("error:noMatchingCert"); goto loser; } /* Send UI event to client */ if (signTextRes->m_autoFlag == PR_TRUE) { rv = SSMControlConnection_SendUIEvent(signTextRes->m_conn, "get", "signtext_auto", SSMRESOURCE(signTextRes), NULL, &SSMRESOURCE(signTextRes)->m_clientContext); } else { rv = SSMControlConnection_SendUIEvent(signTextRes->m_conn, "get", "signtext_ask", SSMRESOURCE(signTextRes), NULL, &SSMRESOURCE(signTextRes)->m_clientContext); } if (rv != PR_SUCCESS) { goto loser; } /* Here we wait for the user to confirm or deny the signing */ SSM_WaitResource(SSMRESOURCE(signTextRes), PR_INTERVAL_NO_TIMEOUT); switch (SSMRESOURCE(signTextRes)->m_buttonType) { case SSM_BUTTON_OK: /* Get the signing cert */ node = (CERTCertListNode *)PR_LIST_HEAD(&signTextRes->m_certs->list); if (signTextRes->m_nickname == NULL ) { /* this is the "auto" case */ cert = node->cert; } else { /* this is the "ask" case */ for ( i = 0; i < numCerts; i++ ) { if ( PL_strcasecmp(signTextRes->m_nickname, node->cert->nickname) == 0 ) { cert = node->cert; break; } node = (struct CERTCertListNodeStr *) node->links.next; } } /* Hash the string to be signed */ rv = HASH_HashBuf(HASH_AlgSHA1, hashVal, (unsigned char *) signTextRes->m_stringToSign, strlen(signTextRes->m_stringToSign)); if (rv != SECSuccess) { goto loser; } digest.len = SHA1_LENGTH; digest.data = hashVal; /* Sign the hash */ ci = SECMIME_CreateSigned(cert, cert, cert->dbhandle, SEC_OID_SHA1,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -