cmtpkcs7.c
上传用户:lyxiangda
上传日期:2007-01-12
资源大小:3042k
文件大小:18k
- /* -*- 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.
- */
- #if defined(XP_UNIX) || defined(XP_BEOS) || defined(XP_OS2)
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <sys/time.h>
- #else
- #ifdef XP_MAC
- #include "macsocket.h"
- #else /* Windows */
- #include <windows.h>
- #include <winsock.h>
- #endif
- #endif
- #include <errno.h>
- #include "cmtcmn.h"
- #include "cmtutils.h"
- #include "messages.h"
- #include "rsrcids.h"
- typedef struct _CMTP7Private {
- CMTPrivate priv;
- CMTP7ContentCallback cb;
- void *cb_arg;
- } CMTP7Private;
- CMTStatus CMT_PKCS7DecoderStart(PCMT_CONTROL control, void* clientContext, CMUint32 * connectionID, CMInt32 * result,
- CMTP7ContentCallback cb, void *cb_arg)
- {
- CMTItem message;
- CMTStatus rv;
- CMTP7Private *priv=NULL;
- SingleItemMessage request;
- DataConnectionReply reply;
- /* Check passed in parameters */
- if (!control) {
- goto loser;
- }
- request.item = CMT_CopyPtrToItem(clientContext);
- /* Encode message */
- if (CMT_EncodeMessage(SingleItemMessageTemplate, &message, &request) != CMTSuccess) {
- goto loser;
- }
- /* Set the message request type */
- message.type = SSM_REQUEST_MESSAGE | SSM_DATA_CONNECTION | SSM_PKCS7DECODE_STREAM;
- /* Send the message. */
- if (CMT_SendMessage(control, &message) == CMTFailure) {
- goto loser;
- }
- /* Validate the message reply type */
- if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_DATA_CONNECTION | SSM_PKCS7DECODE_STREAM)) {
- goto loser;
- }
- /* Decode the reply */
- if (CMT_DecodeMessage(DataConnectionReplyTemplate, &reply, &message) != CMTSuccess) {
- goto loser;
- }
- /* Success */
- if (reply.result == 0) {
- CMTSocket sock;
- priv = (CMTP7Private *)malloc(sizeof(CMTP7Private));
- if (priv == NULL)
- goto loser;
- priv->priv.dest = (CMTReclaimFunc) free;
- priv->cb = cb;
- priv->cb_arg = cb_arg;
- sock = control->sockFuncs.socket(0);
- if (sock == NULL) {
- goto loser;
- }
-
- if (control->sockFuncs.connect(sock, (short)reply.port,
- NULL) != CMTSuccess) {
- goto loser;
- }
-
- if (control->sockFuncs.send(sock, control->nonce.data,
- control->nonce.len) != control->nonce.len){
- goto loser;
- }
- /* Save connection info */
- if (CMT_AddDataConnection(control, sock, reply.connID)
- != CMTSuccess) {
- goto loser;
- }
- *connectionID = reply.connID;
- rv = CMT_SetPrivate(control, reply.connID, &priv->priv);
- if (rv != CMTSuccess)
- goto loser;
- return CMTSuccess;
- }
- loser:
- if (priv) {
- free(priv);
- }
- *result = reply.result;
- return CMTFailure;
- }
- CMTStatus CMT_PKCS7DecoderUpdate(PCMT_CONTROL control, CMUint32 connectionID, const char * buf, CMUint32 len)
- {
- CMUint32 sent;
- CMTP7Private *priv;
- unsigned long nbytes;
- char read_buf[128];
- CMTSocket sock, ctrlsock, selSock, sockArr[2];
- /* Do some parameter checking */
- if (!control || !buf) {
- goto loser;
- }
- /* Get the data socket */
- if (CMT_GetDataSocket(control, connectionID, &sock) == CMTFailure) {
- goto loser;
- }
- priv = (CMTP7Private *)CMT_GetPrivate(control, connectionID);
- if (priv == NULL)
- goto loser;
- /* Write the data to the socket */
- sent = CMT_WriteThisMany(control, sock, (void*)buf, len);
- if (sent != len) {
- goto loser;
- }
- ctrlsock = control->sock;
- sockArr[0] = ctrlsock;
- sockArr[1] = sock;
- while ((selSock = control->sockFuncs.select(sockArr,2,1)))
- {
- if (selSock == ctrlsock) {
- CMT_ProcessEvent(control);
- } else {
- nbytes = control->sockFuncs.recv(sock, read_buf, sizeof(read_buf));
- if (nbytes == -1) {
- goto loser;
- }
- if (nbytes == 0) {
- break;
- }
- priv->cb(priv->cb_arg, read_buf, nbytes);
- }
- }
- return CMTSuccess;
- loser:
- return CMTFailure;
- }
-
- CMTStatus CMT_PKCS7DecoderFinish(PCMT_CONTROL control, CMUint32 connectionID,
- CMUint32 * resourceID)
- {
- CMTP7Private *priv;
- long nbytes;
- char buf[128];
- CMTSocket sock, ctrlsock, selSock, sockArr[2];
- #ifndef XP_MAC
- int numTries = 0;
- #endif
- /* Do some parameter checking */
- if (!control) {
- goto loser;
- }
- priv = (CMTP7Private *)CMT_GetPrivate(control, connectionID);
- if (priv == NULL)
- goto loser;
- if (CMT_GetDataSocket(control, connectionID, &sock) == CMTFailure) {
- goto loser;
- }
- ctrlsock = control->sock;
- /* drain socket before we close it */
- control->sockFuncs.shutdown(sock);
- sockArr[0] = sock;
- sockArr[1] = ctrlsock;
- /* Let's see if doing a poll first gets rid of a weird bug where we
- * lock up the client.
- * There are some cases where the server doesn't put up data fast
- * enough, so we should loop on this poll instead of just trying it
- * once.
- */
- #ifndef XP_MAC
- poll_sockets:
- if (control->sockFuncs.select(sockArr,2,1) != NULL)
- #endif
- {
- while (1) {
- selSock = control->sockFuncs.select(sockArr,2,0);
- if (selSock == ctrlsock) {
- CMT_ProcessEvent(control);
- } else if (selSock == sock) {
- nbytes = control->sockFuncs.recv(sock, buf, sizeof(buf));
- if (nbytes < 0) {
- goto loser;
- } else if (nbytes == 0) {
- break;
- }
- if (priv->cb)
- priv->cb(priv->cb_arg, buf, nbytes);
- }
- }
- }
- #ifndef XP_MAC
- else {
- #ifdef WIN32
- if (numTries < 20) {
- Sleep(100);
- numTries++;
- goto poll_sockets;
- }
- #endif
- #ifdef XP_UNIX
- if (numTries < 25) {
- numTries += sleep(1);
- goto poll_sockets;
- }
- #endif
- }
- #endif
-
- if (CMT_CloseDataConnection(control, connectionID) == CMTFailure) {
- goto loser;
- }
- /* Get the PKCS7 content info */
- if (CMT_GetRIDAttribute(control, connectionID, SSM_FID_P7CONN_CONTENT_INFO,
- resourceID) == CMTFailure) {
- goto loser;
- }
- return CMTSuccess;
- loser:
- if (control) {
- CMT_CloseDataConnection(control, connectionID);
- }
-
- return CMTFailure;
- }
- CMTStatus CMT_PKCS7DestroyContentInfo(PCMT_CONTROL control, CMUint32 resourceID)
- {
- if (!control) {
- goto loser;
- }
- /* Delete the resource */
- if (CMT_DestroyResource(control, resourceID, SSM_FID_P7CONN_CONTENT_INFO) == CMTFailure) {
- goto loser;
- }
- return CMTSuccess;
- loser:
- return CMTFailure;
- }
- CMTStatus CMT_PKCS7VerifyDetachedSignature(PCMT_CONTROL control, CMUint32 resourceID, CMUint32 certUsage, CMUint32 hashAlgID, CMUint32 keepCerts, CMTItem* digest, CMInt32 * result)
- {
- CMTItem message;
- VerifyDetachedSigRequest request;
- SingleNumMessage reply;
- /* Do some parameter checking */
- if (!control || !digest || !result) {
- goto loser;
- }
- /* Set the request */
- request.pkcs7ContentID = resourceID;
- request.certUsage = certUsage;
- request.hashAlgID = hashAlgID;
- request.keepCert = (CMBool) keepCerts;
- request.hash = *digest;
- /* Encode the request */
- if (CMT_EncodeMessage(VerifyDetachedSigRequestTemplate, &message, &request) != CMTSuccess) {
- goto loser;
- }
- /* Set the message request type */
- message.type = SSM_REQUEST_MESSAGE | SSM_OBJECT_SIGNING | SSM_VERIFY_DETACHED_SIG;
- /* Send the message */
- if (CMT_SendMessage(control, &message) == CMTFailure) {
- goto loser;
- }
- /* Validate the message reply type */
- if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_OBJECT_SIGNING |SSM_VERIFY_DETACHED_SIG)) {
- goto loser;
- }
- /* Decode the reply */
- if (CMT_DecodeMessage(SingleNumMessageTemplate, &reply, &message) != CMTSuccess) {
- goto loser;
- }
- *result = reply.value;
- return CMTSuccess;
- loser:
- *result = reply.value;
- return CMTFailure;
- }
- CMTStatus CMT_PKCS7VerifySignature(PCMT_CONTROL control, CMUint32 pubKeyAlgID,
- CMTItem *pubKeyParams, CMTItem *signerPubKey,
- CMTItem *computedHash, CMTItem *signature,
- CMInt32 *result)
- {
- return CMTFailure;
- }
- CMTStatus CMT_CreateSigned(PCMT_CONTROL control, CMUint32 scertRID,
- CMUint32 ecertRID, CMUint32 dig_alg,
- CMTItem *digest, CMUint32 *ciRID, CMInt32 *errCode)
- {
- CMTItem message;
- CreateSignedRequest request;
- CreateContentInfoReply reply;
- char checkMessageForError = 0;
- /* Do some parameter checking */
- if (!control || !scertRID || !digest || !ciRID) {
- goto loser;
- }
- /* Set the request */
- request.scertRID = scertRID;
- request.ecertRID = ecertRID;
- request.dig_alg = dig_alg;
- request.digest = *digest;
- /* Encode the request */
- if (CMT_EncodeMessage(CreateSignedRequestTemplate, &message, &request) != CMTSuccess) {
- goto loser;
- }
- /* Set the message request type */
- message.type = SSM_REQUEST_MESSAGE | SSM_OBJECT_SIGNING | SSM_CREATE_SIGNED;
- /* Send the message */
- if (CMT_SendMessage(control, &message) == CMTFailure) {
- goto loser;
- }
- checkMessageForError = 1;
- /* Validate the message reply type */
- if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_OBJECT_SIGNING | SSM_CREATE_SIGNED)) {
- goto loser;
- }
- /* Decode the reply */
- if (CMT_DecodeMessage(CreateContentInfoReplyTemplate, &reply, &message) != CMTSuccess) {
- goto loser;
- }
- *ciRID = reply.ciRID;
- if (reply.result == 0) {
- return CMTSuccess;
- }
- loser:
- if (checkMessageForError &&
- CMT_DecodeMessage(SingleNumMessageTemplate,
- &reply, &message) == CMTSuccess) {
- *errCode = reply.errorCode;
- } else {
- *errCode = 0;
- }
- return CMTFailure;
- }
- CMTStatus CMT_CreateEncrypted(PCMT_CONTROL control, CMUint32 scertRID,
- CMUint32 *rcertRIDs, CMUint32 *ciRID)
- {
- CMTItem message;
- CMInt32 nrcerts;
- CreateEncryptedRequest request;
- CreateContentInfoReply reply;
- /* Do some parameter checking */
- if (!control || !scertRID || !rcertRIDs || !ciRID) {
- goto loser;
- }
- /* Calculate the number of certs */
- for (nrcerts =0; rcertRIDs[nrcerts] != 0; nrcerts++) {
- /* Nothing */
- ;
- }
- /* Set up the request */
- request.scertRID = scertRID;
- request.nrcerts = nrcerts;
- request.rcertRIDs = (long *) rcertRIDs;
- /* Encode the request */
- if (CMT_EncodeMessage(CreateEncryptedRequestTemplate, &message, &request) != CMTSuccess) {
- goto loser;
- }
- /* Set the message request type */
- message.type = SSM_REQUEST_MESSAGE | SSM_OBJECT_SIGNING | SSM_CREATE_ENCRYPTED;
- /* Send the message */
- if (CMT_SendMessage(control, &message) == CMTFailure) {
- goto loser;
- }
- /* Validate the message response type */
- if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_OBJECT_SIGNING | SSM_CREATE_ENCRYPTED)) {
- goto loser;
- }
- /* Decode the reply */
- if (CMT_DecodeMessage(CreateContentInfoReplyTemplate, &reply, &message) != CMTSuccess) {
- goto loser;
- }
- *ciRID = reply.ciRID;
- if (reply.result == 0) {
- return CMTSuccess;
- }
- loser:
- return CMTFailure;
- }
- CMTStatus CMT_PKCS7EncoderStart(PCMT_CONTROL control, CMUint32 ciRID,
- CMUint32 *connectionID, CMTP7ContentCallback cb,
- void *cb_arg)
- {
- CMTItem message;
- CMTStatus rv;
- CMTP7Private *priv;
- PKCS7DataConnectionRequest request;
- DataConnectionReply reply;
- /* Check passed in parameters */
- if (!control || !ciRID) {
- goto loser;
- }
- /* Set up the request */
- request.resID = ciRID;
- request.clientContext.len = 0;
- request.clientContext.data = NULL;
- /* Encode the request */
- if (CMT_EncodeMessage(PKCS7DataConnectionRequestTemplate, &message, &request) != CMTSuccess) {
- goto loser;
- }
- /* Set the message request type */
- message.type = SSM_REQUEST_MESSAGE | SSM_DATA_CONNECTION | SSM_PKCS7ENCODE_STREAM;
- /* Send the message */
- if (CMT_SendMessage(control, &message) == CMTFailure) {
- goto loser;
- }
- /* Validate the message reply type */
- if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_DATA_CONNECTION | SSM_PKCS7ENCODE_STREAM)) {
- goto loser;
- }
- /* Decode the reply */
- if (CMT_DecodeMessage(DataConnectionReplyTemplate, &reply, &message) != CMTSuccess) {
- goto loser;
- }
- /* Success */
- if (reply.result == 0) {
- CMTSocket sock;
- priv = (CMTP7Private *)malloc(sizeof(CMTP7Private));
- if (priv == NULL)
- goto loser;
- priv->priv.dest = (CMTReclaimFunc) free;
- priv->cb = cb;
- priv->cb_arg = cb_arg;
- sock = control->sockFuncs.socket(0);
- if (sock == NULL) {
- goto loser;
- }
- if (control->sockFuncs.connect(sock, (short)reply.port,
- NULL) != CMTSuccess) {
- goto loser;
- }
- if (control->sockFuncs.send(sock, control->nonce.data,
- control->nonce.len) != control->nonce.len) {
- goto loser;
- }
- /* Save connection info */
- if (CMT_AddDataConnection(control, sock, reply.connID)
- != CMTSuccess) {
- goto loser;
- }
- *connectionID = reply.connID;
- rv = CMT_SetPrivate(control, reply.connID, &priv->priv);
- if (rv != CMTSuccess)
- goto loser;
- return CMTSuccess;
- }
- loser:
- return CMTFailure;
- }
- CMTStatus CMT_PKCS7EncoderUpdate(PCMT_CONTROL control, CMUint32 connectionID,
- const char *buf, CMUint32 len)
- {
- CMUint32 sent;
- CMTP7Private *priv;
- unsigned long nbytes;
- char read_buf[128];
- CMTSocket sock, ctrlsock, sockArr[2], selSock;
- /* Do some parameter checking */
- if (!control || !connectionID || !buf) {
- goto loser;
- }
- /* Get the data socket */
- if (CMT_GetDataSocket(control, connectionID, &sock) == CMTFailure) {
- goto loser;
- }
- priv = (CMTP7Private *)CMT_GetPrivate(control, connectionID);
- if (priv == NULL)
- goto loser;
- /* Write the data to the socket */
- sent = CMT_WriteThisMany(control, sock, (void*)buf, len);
- if (sent != len) {
- goto loser;
- }
- ctrlsock = control->sock;
- sockArr[0] = ctrlsock;
- sockArr[1] = sock;
- while ((selSock = control->sockFuncs.select(sockArr, 2, 1)) != NULL)
- {
- if (selSock == ctrlsock) {
- CMT_ProcessEvent(control);
- } else {
- nbytes = control->sockFuncs.recv(sock, read_buf, sizeof(read_buf));
- if (nbytes == -1) {
- goto loser;
- } else if (nbytes == 0) {
- break;
- } else {
- priv->cb(priv->cb_arg, read_buf, nbytes);
- }
- }
- }
- return CMTSuccess;
- loser:
- return CMTFailure;
- }
- CMTStatus CMT_PKCS7EncoderFinish(PCMT_CONTROL control, CMUint32 connectionID)
- {
- CMTP7Private *priv;
- CMInt32 nbytes;
- char buf[128];
- CMTSocket sock, ctrlsock, sockArr[2], selSock;
- /* Do some parameter checking */
- if (!control) {
- goto loser;
- }
- priv = (CMTP7Private *)CMT_GetPrivate(control, connectionID);
- if (priv == NULL)
- goto loser;
- if (CMT_GetDataSocket(control, connectionID, &sock) == CMTFailure) {
- goto loser;
- }
- ctrlsock = control->sock;
- sockArr[0] = ctrlsock;
- sockArr[1] = sock;
- control->sockFuncs.shutdown(sock);
- while (1) {
- selSock = control->sockFuncs.select(sockArr, 2, 0);
- if (selSock == ctrlsock) {
- CMT_ProcessEvent(control);
- } else if (selSock == sock) {
- nbytes = control->sockFuncs.recv(sock, buf, sizeof(buf));
- if (nbytes < 0) {
- goto loser;
- } else if (nbytes == 0) {
- break;
- } else {
- priv->cb(priv->cb_arg, buf, nbytes);
- }
- }
- }
- if (CMT_CloseDataConnection(control, connectionID) == CMTFailure) {
- goto loser;
- }
- return CMTSuccess;
- loser:
- if (control) {
- CMT_CloseDataConnection(control, connectionID);
- }
-
- return CMTFailure;
- }