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

📄 writesign.c

📁 IBE是一种非对称密码技术
💻 C
📖 第 1 页 / 共 4 页
字号:

  } while (0);

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

  return (status);
}

int VoltP7SignWriteFinal (
   VtPkcs7Object pkcs7Obj,
   VtRandomObject random,
   unsigned char *inputData,
   unsigned int inputDataLen,
   unsigned char *message,
   unsigned int bufferSize,
   unsigned int *messageLen
   )
{
  int status;
  unsigned int index, bufSize;
  unsigned int signatureLen, lastMessageLen, digestLen, totalLen;
  VoltPkcs7Object *obj = (VoltPkcs7Object *)pkcs7Obj;
  VoltPkcs7WriteSignCtx *signCtx = (VoltPkcs7WriteSignCtx *)(obj->localCtx);
  VoltLibCtx *libCtx = (VoltLibCtx *)(obj->voltObject.libraryCtx);
  VoltDigestClassCtx *digestCtx = (VoltDigestClassCtx *)
    (((VoltAlgorithmObject *)(signCtx->digester))->classCtx);
  unsigned char *buffer, *temp;
  unsigned char *digest = (unsigned char *)0;
  Asn1SignerInfo *nextSignerInfo;
  VOLT_DECLARE_ERROR_TYPE (errorType)
  VOLT_DECLARE_FNCT_LINE (fnctLine)

  do
  {
    /* If no dataLen is set, the inputDataLen is that value.
     */
#if VT_64_BIT_LENGTH == 64
    if (obj->dataLen64 == 0)
      obj->dataLen64 = (VtUInt64)inputDataLen;
#else
    if (obj->dataLen == 0)
      obj->dataLen = inputDataLen;
#endif

    /* The state must be INIT or UPDATE.
     */
    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_INIT) &&
         (obj->state != VOLT_P7_STATE_SIGN_WRITE_UPDATE) )
      break;

    /* Make sure the total len of input equals the "predicted" len.
     */
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VT_ERROR_INVALID_INPUT_LENGTH;
#if VT_64_BIT_LENGTH == 64
    if (((VtUInt64)inputDataLen + obj->inputLen64) != obj->dataLen64)
#else
    if ((inputDataLen + obj->inputLen) != obj->dataLen)
#endif
      break;

    /* How much space is needed for the last chunk of data?
     * If there's no input data, the outputLen might be 0, which is
     * fine. So if the return is 0, reset status to BUFFER_TOO_SMALL
     * just to make it easier to break out on a different error.
     */
    VOLT_SET_ERROR_TYPE (errorType, 0)
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VoltP7SignWriteUpdate (
      pkcs7Obj, random, (unsigned char *)0, inputDataLen,
      (unsigned char *)0, 0, &lastMessageLen);
    if (status == 0)
      status = VT_ERROR_BUFFER_TOO_SMALL;
    if (status != VT_ERROR_BUFFER_TOO_SMALL)
      break;

    /* We now know how long each of the components will be, determine
     * the total length.
     *    last of the message
     *    A0 len
     *       <certs>
     *    --no CRL's for this implementation--
     *    31 len
     *       <SignerInfo's>
     */
    totalLen = VoltDetermineDerLengthLen (
      (UInt32)(signCtx->totalCertLen), (UInt32)0);
    totalLen += 1 + signCtx->totalCertLen;
    totalLen += VoltDetermineDerLengthLen (
      (UInt32)(signCtx->totalSignerInfoLen), (UInt32)0);
    totalLen += 1 + signCtx->totalSignerInfoLen;
    totalLen += lastMessageLen;

    /* Make sure totalLen is < 2^32.
     */
    VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VT_ERROR_INVALID_INPUT_LENGTH;
    if (totalLen < lastMessageLen)
      break;

    VOLT_SET_FNCT_LINE (fnctLine)
    status = VT_ERROR_BUFFER_TOO_SMALL;
    *messageLen = totalLen;
    if (bufferSize < totalLen)
      break;

    /* If the caller passed NULL input with non-zero inputLen, they
     * just wanted the length, don't process.
     */
    VOLT_SET_FNCT_LINE (fnctLine)
    if ( (inputData == (unsigned char *)0) && (inputDataLen != 0) )
      break;

    /* The buffer is big enough, place data into the output.
     */
    totalLen = 0;
    VOLT_SET_ERROR_TYPE (errorType, 0)
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VoltP7SignWriteUpdate (
      pkcs7Obj, random, inputData, inputDataLen,
      message, bufferSize, &lastMessageLen);
    if (status != 0)
      break;

    bufferSize -= lastMessageLen;
    totalLen += lastMessageLen;

    /* Call DigestFinal to get the digest of the data.
     */
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VtDigestFinal (
      signCtx->digester, (unsigned char *)0, 0,
      signCtx->digest, signCtx->digestSize, &digestLen);
    if (status != 0)
      break;

    /* Place the certs. IMPLICIT SET OF.
     */
    totalLen += VoltWriteDerTagAndLen (
      message + totalLen, 0xA0, (UInt32)(signCtx->totalCertLen), (UInt32)0);

    for (index = 0; index < signCtx->signerInfosCount; ++index)
    {
      Z2Memcpy (
        message + totalLen, signCtx->signerInfos[index].cert.data,
        signCtx->signerInfos[index].cert.len);
      totalLen += signCtx->signerInfos[index].cert.len;
    }

    for (index = 0; index < signCtx->extraCertsCount; ++index)
    {
      Z2Memcpy (
        message + totalLen, signCtx->extraCerts[index].data,
        signCtx->extraCerts[index].len);
      totalLen += signCtx->extraCerts[index].len;
    }

    /* Next is SingerInfos, that's a SET OF.
     */
    totalLen += VoltWriteDerTagAndLen (
      message + totalLen, 0x31,
      (UInt32)(signCtx->totalSignerInfoLen), (UInt32)0);

    /* We need a buffer to hold the digest of auth attrs.
     */
    VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VT_ERROR_MEMORY;
    digest = (unsigned char *)Z2Malloc (signCtx->digestSize, 0);
    if (digest == (unsigned char *)0)
      break;

    /* For each of the signer's, place the correct digest into the
     * authAttributes, then create the signature of the authAttributes.
     */
    for (index = 0; index < signCtx->signerInfosCount; ++index)
    {
      nextSignerInfo = signCtx->signerInfos[index].asn1SignerInfo;

      /* We set the Asn1Encoded inside the asn1SignerInfo object with a
       * placeholder. We'll fill the buffer inside the object with the
       * actual data now.
       */
      buffer = nextSignerInfo->authAttributes->base.data;
      bufSize = (unsigned int)(nextSignerInfo->authAttributes->base.length);

      VOLT_SET_ERROR_TYPE (errorType, 0)
      VOLT_SET_FNCT_LINE (fnctLine)
      status = BuildAuthAttributes (
        obj, VT_PKCS7_DATA, signCtx->digest, signCtx->digestSize,
        &(signCtx->signingTime), buffer, bufSize, &bufSize);
      if (status != 0)
        break;

      /* Digest the auth attrs for the signature.
       */
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VtDigestInit (signCtx->digester);
      if (status != 0)
        break;

      /* P7 says to sign the auth attrs as SET OF. However, we built
       * the authAttrs as IMPLICIT. So for the digesting, change the A0
       * to 31. Then when the digesting is done, change it back.
       */
      buffer[0] = 0x31;
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VtDigestFinal (
        signCtx->digester, buffer, bufSize,
        digest, signCtx->digestSize, &digestLen);
      if (status != 0)
        break;
      buffer[0] = 0xA0;

      /* Create a signature for that data.
       */
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VtSign (
        signCtx->signerInfos[index].signObj,
        signCtx->signerInfos[index].priKeyRef,
        random, digestCtx->algorithm, digest, digestLen,
        signCtx->signerInfos[index].signature,
        signCtx->signerInfos[index].sigBufSize, &signatureLen);
      if (status != 0)
        break;

      /* If the signature is smaller than the sigBufSize, fix it
       * (prepend 00 bytes in appropriate places) to make it work.
       */
      if (signatureLen != signCtx->signerInfos[index].sigBufSize)
        FixDsaSignature (
          libCtx, signCtx->signerInfos[index].signature,
          signCtx->signerInfos[index].sigBufSize, &signatureLen);

      /* Place the signature into the SignerInfo.
       */
      VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VT_ERROR_MEMORY;
      if (ASN1_OCTET_STRING_set (
        nextSignerInfo->signature,
        signCtx->signerInfos[index].signature, (int)signatureLen) != 1)
        break;

      /* Encode the SignerInfo into the message buffer.
       */
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VT_ERROR_INVALID_INPUT;
      temp = message + totalLen;
      signCtx->signerInfos[index].signerInfoLen = i2d_Asn1SignerInfo (
        signCtx->signerInfos[index].asn1SignerInfo, &temp);
      if (temp == (unsigned char *)0)
        break;

      totalLen += signCtx->signerInfos[index].signerInfoLen;

      status = 0;
    }
    if (status != 0)
      break;

  } while (0);

  if (digest != (unsigned char *)0)
    Z2Free (digest);

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

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

  return (status);
}

static int BuildSignerInfoCreate (
   VoltPkcs7Object *p7Obj,
   VoltSurrenderCtx *surrCtx,
   VtRandomObject random,
   unsigned char *digestBuf,
   unsigned int digestLen,
   VoltP7SignerInfo *signerInfo
   )
{
  int status;
  unsigned int authAttrsLen, signatureLen;
  VoltLibCtx *libCtx = (VoltLibCtx *)(p7Obj->voltObject.libraryCtx);
  VoltPkcs7WriteSignCtx *signCtx = (VoltPkcs7WriteSignCtx *)(p7Obj->localCtx);
  VoltDigestClassCtx *digestCtx = (VoltDigestClassCtx *)
    (((VoltAlgorithmObject *)(signCtx->digester))->classCtx);
  Asn1SignerInfo *newObj = (Asn1SignerInfo *)0;
  Asn1X509Cert *x509Cert = (Asn1X509Cert *)0;
  unsigned char *authAttrs = (unsigned char *)0;
  VtSurrenderCallback surrenderCtx;
  VOLT_DECLARE_ERROR_TYPE (errorType)
  VOLT_DECLARE_FNCT_LINE (fnctLine)

  /* If there's already an object in the struct, do nothing.
   */
  if (signerInfo->asn1SignerInfo != (Asn1SignerInfo *)0)
    return (0);

  do
  {
    /* Create the object.
     */
    VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VT_ERROR_MEMORY;
    newObj = Asn1SignerInfo_new ();
    if (newObj == (Asn1SignerInfo *)0)
      break;

    /* Set the fields.
     */
    VOLT_SET_FNCT_LINE (fnctLine)
    if (ASN1_INTEGER_set (newObj->version, 0) != 1)
      break;

    VOLT_SET_FNCT_LINE (fnctLine)
    if (Asn1Encoded_set (
      newObj->digestAlg, signCtx->digestAlgId.data,
      signCtx->digestAlgId.len) != 1)
      break;

    VOLT_SET_FNCT_LINE (fnctLine)
    if (Asn1Encoded_set (
      newObj->signatureAlg, signCtx->sigAlgId.data,
      signCtx->sigAlgId.len) != 1)

⌨️ 快捷键说明

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