⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 writesign.c

📁 IBE是一种非对称密码技术
💻 C
📖 第 1 页 / 共 4 页
字号:
/* Copyright 2003-2006, Voltage Security, all rights reserved.
 */
#include "vibe.h"
#include "environment.h"
#include "base.h"
#include "libctx.h"
#include "p7obj.h"
#include "idobj.h"
#include "derhelp.h"
#include "oidlist.h"
#include "vcert.h"
#include "digest.h"
#include "vtime.h"
#include "surrender.h"
#include "errorctx.h"

/* Set up the OpenSSL ASN.1 templates.
 */
ASN1_SEQUENCE (Asn1P9Attribute) =
{
  ASN1_SIMPLE (Asn1P9Attribute, attrType, Asn1ObjectId),
  ASN1_SET_OF (Asn1P9Attribute, attrValues, Asn1Encoded)
} ASN1_SEQUENCE_END (Asn1P9Attribute);

IMPLEMENT_ASN1_FUNCTIONS (Asn1P9Attribute)

ASN1_SEQUENCE (Asn1IssuerSerial) =
{
  ASN1_SIMPLE (Asn1IssuerSerial, issuerName, Asn1Encoded),
  ASN1_SIMPLE (Asn1IssuerSerial, serialNumber, ASN1_INTEGER)
} ASN1_SEQUENCE_END (Asn1IssuerSerial);

IMPLEMENT_ASN1_FUNCTIONS (Asn1IssuerSerial)

ASN1_SEQUENCE (Asn1SignerInfo) =
{
  ASN1_SIMPLE (Asn1SignerInfo, version, ASN1_INTEGER),
  ASN1_SIMPLE (Asn1SignerInfo, issuerSerial, Asn1IssuerSerial),
  ASN1_SIMPLE (Asn1SignerInfo, digestAlg, Asn1Encoded),
  ASN1_OPT (Asn1SignerInfo, authAttributes, Asn1Encoded),
  ASN1_SIMPLE (Asn1SignerInfo, signatureAlg, Asn1Encoded),
  ASN1_SIMPLE (Asn1SignerInfo, signature, ASN1_OCTET_STRING),
  ASN1_IMP_SET_OF_OPT (Asn1SignerInfo, unauthAttributes, Asn1P9Attribute, 1),
} ASN1_SEQUENCE_END (Asn1SignerInfo);

IMPLEMENT_ASN1_FUNCTIONS (Asn1SignerInfo)

/* Create an Asn1SignerInfo object, then set it with the information
 * found in the signerInfo struct.
 * <p>The caller passes in a VoltP7SignerInfo struct containing key and
 * cert defining the signer. The struct also contains the field where
 * the function will place the created Asn1 object.
 * <p>The struct also contains a filed for the length of the
 * signerInfo. This is the length of the encoded SignerInfo. This length
 * will be an upper bound, the actual length may be shorter.
 *
 * @param p7Obj The object containing the signCtx and other info.
 * @param surrCtx If not NULL a surrender ctx to pass on to subordinate
 * objects.
 * @param random A random object, if needed.
 * @param signerInfo The struct containing the key and cert, also the
 * place where the created Asn1 object and length will be deposited.
 * @return an int, 0 if the function completed successfully or a
 * non-zero error code.
 */
static int VOLT_CALLING_CONV BuildSignerInfoCreate VOLT_PROTO_LIST ((
   VoltPkcs7Object *p7Obj,
   VoltSurrenderCtx *surrCtx,
   VtRandomObject random,
   unsigned char *digestBuf,
   unsigned int digestLen,
   VoltP7SignerInfo *signerInfo
));

/* Build the AuthenticatedAttributes for a SignedData message.
 * <p>Actually, this builds only the following three attributes:
 * pkcs-9-at-contentType, pkcs-9-at-messageDigest, and
 * pkcs-9-at-signingTime.
 * <p>If using AuthenticatedAttributes in a P7 SignedData message, the
 * contentType and messageDigest are required.
 * <p>The input flag contentType must be one of the following.
 * <code>
 * <pre>
 *     VT_PKCS7_DATA
 *     VT_PKCS7_SIGNED_DATA
 *     VT_PKCS7_ENVELOPED_DATA
 *     VT_PKCS7_SIGN_ENV_DATA
 *     VT_PKCS7_DIGESTED_DATA
 *     VT_PKCS7_ENCRYPTED_DATA
 * </pre>
 * </code>
 * <p>This routine will create the DER encoding of the Attributes:
 * <code>
 * <pre>
 *    Attributes ::= SET OF {
 *      Attribute }
 *
 *    Attribute ::= SEQUENCE {
 *      type    OID,
 *      values  SET OF ANY }
 * </pre>
 * </code>
 * <p>For SignedData, the Attributes are Implicit, so the function will
 * make sure the appropriate tag is used.
 * <p>This routine will fill the provided buffer. If no buffer is given
 * or if the buffer is too small, the function will return
 * VT_ERROR_BUFFER_TOO_SMALL and set the authAttrsLen to the needed
 * size.
 *
 * @param p7Obj The object containing info needed, such as signCtx and
 * libCtx.
 * @param contentType A flag indicating what contentType is being
 * signed (Data, SignedData, EnvelopedData, etc.).
 * @param contentDigest The digest of the content, this is what will be
 * the value of the messageDigest attribute.
 * @param contentDigestLen The length, in bytes, of the contentDigest.
 * @param theTime The time to use for signingTime.
 * @param authAttrs The buffer the function will fill with the
 * attributes.
 * @param bufferSize The size, in bytes of the output buffer.
 * @param authAttrsLen The address where this function will deposit the
 * length, in bytes, of the encoding of the attributes.
 * @return an int, 0 if the function completed successfully or a
 * non-zero error code.
 */
static int VOLT_CALLING_CONV BuildAuthAttributes VOLT_PROTO_LIST ((
   VoltPkcs7Object *p7Obj,
   unsigned int contentType,
   unsigned char *contentDigest,
   unsigned int contentDigestLen,
   VtTime *theTime,
   unsigned char *authAttrs,
   unsigned int bufferSize,
   unsigned int *authAttrsLen
));

/* Fix the signature so that the signatureLen is the same as
 * sigBufSize. Do this by prepending 00 bytes in the appropriate
 * places.
 * <p>This particular function operates on DSA signatures only. In the
 * future, we'll have to be able to fix any signature. This function
 * also expects r and s to be 20 bytes. In other words, the signature
 * was created using DSA with a subprime of 160 bits.
 * <p>This function expects the signature to be in the buffer and that the
 * buffer is sigBufSize bytes big. It will go to the address given by
 * signatureLen to find the actual signatureLen, and it will set that
 * value to the new signatureLen.
 *
 * @param libCtx
 * @param signature
 * @param sigBufSize
 * @param signatureLen
 * @return none
 */
static void VOLT_CALLING_CONV FixDsaSignature VOLT_PROTO_LIST ((
   VoltLibCtx *libCtx,
   unsigned char *signature,
   unsigned int sigBufSize,
   unsigned int *signatureLen
));

int VoltP7SignWriteInit (
   VtPkcs7Object pkcs7Obj,
   VtPolicyCtx policyCtx,
   VtStorageCtx storageCtx,
   VtTransportCtx transportCtx,
   VtRandomObject random
   )
{
  int status;
  unsigned int index;
  VoltPkcs7Object *obj = (VoltPkcs7Object *)pkcs7Obj;
  VoltPkcs7WriteSignCtx *signCtx = (VoltPkcs7WriteSignCtx *)(obj->localCtx);
  VoltLibCtx *libCtx = (VoltLibCtx *)(obj->voltObject.libraryCtx);
  VoltP7SignerInfo *currentSignerInfo;
  VtCertObject nextCert = (VtCertObject)0;
  VtItem *getCertData = (VtItem *)0;
  VtKeyObject *obtainKey;
  VtCertObject *obtainCert;
  VoltSurrenderCtx *surrCtx = (VoltSurrenderCtx *)0;
  VOLT_DECLARE_ERROR_TYPE (errorType)
  VOLT_DECLARE_FNCT_LINE (fnctLine)

  do
  {
    if ( ((obj->voltObject.objectType & VOLT_OBJECT_TYPE_SURRENDER) != 0) &&
         (obj->voltObject.surrenderCtx != (Pointer)0) )
      surrCtx = (VoltSurrenderCtx *)(obj->voltObject.surrenderCtx);

    /* The state must be VOLT_P7_STATE_SIGN_WRITE_SET, if not, we're
     * not allowed to call WriteInit.
     */
    VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VT_ERROR_INVALID_CALL_ORDER;
    if (obj->state != VOLT_P7_STATE_SIGN_WRITE_SET)
      break;

    /* This implementation does not work without signers.
     */
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VT_ERROR_INVALID_P7_OBJ;
    if (signCtx->signerInfosCount == 0)
      break;

    /* Get the signing time.
     */
    VtGetTime ((VtLibCtx)libCtx, &(signCtx->signingTime));

    /* For each of the signers, get the private key and cert. This
     * implementation of P7 requires a cert for each signer.
     */
    status = 0;
    for (index = 0; index < signCtx->signerInfosCount; ++index)
    {
      currentSignerInfo = &(signCtx->signerInfos[index]);

      if ( (currentSignerInfo->priKeyRef == (VtKeyObject)0) &&
           (currentSignerInfo->priKey != (VtKeyObject)0) )
        currentSignerInfo->priKeyRef = currentSignerInfo->priKey;

      /* Check to see if we already have a key and cert.
       */
      obtainKey = (VtKeyObject *)0;
      obtainCert = (VtCertObject *)0;
      if (currentSignerInfo->priKeyRef == (VtKeyObject)0)
        obtainKey = &(currentSignerInfo->priKey);
      if (currentSignerInfo->cert.data == (unsigned char *)0)
        obtainCert = &nextCert;

      /* If there's no DSA private key and/or cert, get them. If we
       * already have them, no need. We don't need the IBE private key.
       */
      if ( (obtainKey != (VtKeyObject *)0) ||
           (obtainCert != (VtCertObject *)0) )
      {
        VOLT_SET_ERROR_TYPE (errorType, 0)
        VOLT_SET_FNCT_LINE (fnctLine)
        status = VoltP7GetKeysAndCert (
          surrCtx, currentSignerInfo->signerId, random, policyCtx, storageCtx,
          transportCtx, obtainCert, (VtKeyObject *)0, obtainKey);
        if (status != 0)
          break;
      }

      /* Get the cert data.
       */
      if (obtainCert != (VtCertObject *)0)
      {
        VOLT_SET_ERROR_TYPE (errorType, 0)
        VOLT_SET_FNCT_LINE (fnctLine)
        status = VtGetCertParam (
          nextCert, VtCertParamX509DerData, (Pointer *)&getCertData);
        if (status != 0)
          break;

        /* Copy the cert data.
         */
        VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
        VOLT_SET_FNCT_LINE (fnctLine)
        status = VT_ERROR_MEMORY;
        if (currentSignerInfo->cert.data != (unsigned char *)0)
          Z2Free (currentSignerInfo->cert.data);
        currentSignerInfo->cert.data = Z2Malloc (getCertData->len, 0);
        if (currentSignerInfo->cert.data == (unsigned char *)0)
          break;
        Z2Memcpy (
          currentSignerInfo->cert.data, getCertData->data, getCertData->len);
        currentSignerInfo->cert.len = getCertData->len;
        status = 0;
      }

      if (obtainKey != (VtKeyObject *)0)
        currentSignerInfo->priKeyRef = currentSignerInfo->priKey;

      /* We only needed this object to get the data. Destroy it so
       * the next iteration will have a NULL.
       */
      VtDestroyCertObject (&nextCert);

      /* Now that we have the key and cert, build the Asn1SignerInfo
       * object.
       */
      VOLT_SET_ERROR_TYPE (errorType, 0)
      VOLT_SET_FNCT_LINE (fnctLine)
      status = BuildSignerInfoCreate (
        obj, surrCtx, random, signCtx->digest, signCtx->digestSize,
        currentSignerInfo);
      if (status != 0)
        break;

      signCtx->totalSignerInfoLen += currentSignerInfo->signerInfoLen;
      signCtx->totalCertLen += currentSignerInfo->cert.len;
    }

    /* Count up the extra certs.
     */
    for (index = 0; index < signCtx->extraCertsCount; ++index)
      signCtx->totalCertLen += signCtx->extraCerts[index].len;

  } while (0);

  if (status == 0)
    obj->state = VOLT_P7_STATE_SIGN_WRITE_INIT;

  VtDestroyCertObject (&nextCert);

  VOLT_LOG_ERROR_INFO_COMPARE (
    status, 0, pkcs7Obj, status, 0, errorType,
    (char *)0, "VoltP7SignWriteInit", fnctLine, (char *)0)

  return (status);
}

int VoltP7SignWriteUpdate (
   VtPkcs7Object pkcs7Obj,
   VtRandomObject random,
   unsigned char *inputData,
   unsigned int inputDataLen,
   unsigned char *message,
   unsigned int bufferSize,
   unsigned int *messageLen
   )
{
  int status;
  unsigned int offset;
#if VT_64_BIT_LENGTH == 64
  VtUInt64 outputLen, contentLen, contentInfoLen, signedDataLen;
  VtUInt64 explicitLen, totalLen;
#else
  unsigned int outputLen, contentLen, contentInfoLen, signedDataLen;
  unsigned int explicitLen, totalLen;
#endif
  VoltPkcs7Object *obj = (VoltPkcs7Object *)pkcs7Obj;
  VoltPkcs7WriteSignCtx *signCtx = (VoltPkcs7WriteSignCtx *)(obj->localCtx);
  VoltLibCtx *libCtx = (VoltLibCtx *)(obj->voltObject.libraryCtx);

⌨️ 快捷键说明

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