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

📄 smwrite.c

📁 IBE是一种非对称密码技术
💻 C
📖 第 1 页 / 共 4 页
字号:
    VOLT_SET_FNCT_LINE (fnctLine)
    if ( (inputData == (unsigned char *)0) && (inputDataLen != 0) )
      break;

    /* Start writing out the message.
     */
    offset = 0;

    if (obj->state == VOLT_SECURE_MAIL_STATE_WRITE_INIT_LEN)
    {
      /* If the state is INIT_LEN, we have not written out the
       * preliminaries yet.
       */
      newLine = writeCtx->itemArray[VOLT_WRITE_SM_ITEM_NEW_LINE].data;
      newLineLen = writeCtx->itemArray[VOLT_WRITE_SM_ITEM_NEW_LINE].len;
      for (index = VOLT_WRITE_SM_HEAD_INDEX_START;
           index <= VOLT_WRITE_SM_HEAD_INDEX_END; ++index)
      {
        /* Add in the length of the actual data to write out.
         * If there is data to write out, add a newLine.
         */
        elementLen = writeCtx->itemArray[index].len;
        if (elementLen == 0)
          continue;

        Z2Memcpy (
          message + offset, writeCtx->itemArray[index].data, elementLen);
        offset += elementLen;
        Z2Memcpy (message + offset, newLine, newLineLen);
        offset += newLineLen;
      }

      /* Now that we've written out the preliminaries, the state can be
       * regular UPDATE.
       */
      obj->state = VOLT_SECURE_MAIL_STATE_WRITE_UPDATE;
    }

    /* Allocate a buffer to hold the signed data.
     */
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VT_ERROR_MEMORY;
    sBuffer = (unsigned char *)Z2Malloc (signedDataLen, 0);
    if (sBuffer == (unsigned char *)0)
      break;

    /* Write out the SignedData.
     * Use index as a temp variable.
     */
    index = 0;
    VOLT_SET_ERROR_TYPE (errorType, 0)
    if (contentReportLen != 0)
    {
      /* If we haven't written out the content report, do it now. Get
       * the number of bytes written in index.
       */
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VtPkcs7WriteUpdate (
        obj->p7SignedData, random,
        writeCtx->itemArray[VOLT_WRITE_SM_ITEM_CONTENT_REPORT].data,
        contentReportLen, sBuffer, signedDataLen, &index);
      if (status != 0)
        break;
    }

    /* If we wrote out something based on contentReport, index is how
     * many bytes written. If we did not write out something based on
     * contentReport, index is 0.
     */
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VtPkcs7WriteUpdate (
      obj->p7SignedData, random, inputData, inputDataLen,
      sBuffer + index, signedDataLen - index, &signedDataLen);
    if (status != 0)
      break;
    signedDataLen += index;

    /* Allocate a buffer to hold the enveloped data.
     */
    VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VT_ERROR_MEMORY;
    eBuffer = (unsigned char *)Z2Malloc (envelopedDataLen, 0);
    if (eBuffer == (unsigned char *)0)
      break;

    /* Envelope the signed data.
     */
    VOLT_SET_ERROR_TYPE (errorType, 0)
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VtPkcs7WriteUpdate (
      obj->p7EnvelopedData, random, sBuffer, signedDataLen,
      eBuffer, envelopedDataLen, &envelopedDataLen);
    if (status != 0)
      break;

    /* If there's any preP7 data, encode it. Then Base64 encode the
     * enveloped data.
     */
    if (preP7->len != 0)
    {
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VtEncodeUpdate (
        obj->base64, (VtRandomObject)0, preP7->data, preP7->len,
        message + offset, bufferSize - offset, &b64Len);
      if (status != 0)
        break;

      offset += b64Len;
      preP7->len = 0;
    }
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VtEncodeUpdate (
      obj->base64, (VtRandomObject)0, eBuffer, envelopedDataLen,
      message + offset, bufferSize - offset, &b64Len);
    if (status != 0)
      break;

    obj->inputLen += inputDataLen;
    obj->state = VOLT_SECURE_MAIL_STATE_WRITE_UPDATE;

  } while (0);

  if (sBuffer != (unsigned char *)0)
    Z2Free (sBuffer);
  if (eBuffer != (unsigned char *)0)
    Z2Free (eBuffer);

  VOLT_LOG_ERROR_INFO_COMPARE (
    status, 0, secureMailObj, status, 0, errorType,
    (char *)0, "VoltSecureMailWriteUpdate", fnctLine, (char *)0)

  return (status);
}

int VoltSecureMailWriteFinal (
   VtSecureMailObject secureMailObj,
   VtRandomObject random,
   unsigned char *inputData,
   unsigned int inputDataLen,
   unsigned char *message,
   unsigned int bufferSize,
   unsigned int *messageLen
   )
{
  int status;
  unsigned int inputLen, updateLen, signedDataLen, envelopedDataLen, b64Len;
  unsigned int index, offset, totalLen, elementLen, newLineLen;
  unsigned char *input, *newLine;
  unsigned char *sBuffer = (unsigned char *)0;
  unsigned char *eBuffer = (unsigned char *)0;
  VoltSecureMailObject *obj = (VoltSecureMailObject *)secureMailObj;
  VoltSecureMailWriteCtx *writeCtx = (VoltSecureMailWriteCtx *)(obj->localCtx);
  VoltLibCtx *libCtx = (VoltLibCtx *)(obj->voltObject.libraryCtx);
  unsigned int footerLen =
    writeCtx->itemArray[VOLT_WRITE_SM_ITEM_CONTENT_FOOTER].len;
  unsigned char *footer =
    writeCtx->itemArray[VOLT_WRITE_SM_ITEM_CONTENT_FOOTER].data;
  VtItem *preP7 = &(writeCtx->itemArray[VOLT_WRITE_SM_PRE_PKCS7]);
  VoltEncodeDecodeSizeInfo encodeDecodeSizeInfo;
  VOLT_DECLARE_ERROR_TYPE (errorType)
  VOLT_DECLARE_FNCT_LINE (fnctLine)

  do
  {
    /* If a dataLen is not yet set, the inputLen from this call 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

    input = inputData;
    inputLen = inputDataLen;
    totalLen = 0;

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

    /* If the state is INIT, get the lengths.
     */
    if (obj->state == VOLT_SECURE_MAIL_STATE_WRITE_INIT)
    {
      VOLT_SET_ERROR_TYPE (errorType, 0)
      VOLT_SET_FNCT_LINE (fnctLine)
      status = SetTotalLengths (obj, writeCtx, random);
      if (status != 0)
        break;
    }

    /* If the state is INIT_LEN, we're processing the data all at once.
     */
    if (obj->state == VOLT_SECURE_MAIL_STATE_WRITE_INIT_LEN)
    {
      VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VT_ERROR_INVALID_INPUT_LENGTH;
#if VT_64_BIT_LENGTH == 64
      if (writeCtx->base64Len > 0xffffffff)
        break;
#endif
      /* We know the total length of the output. Is the buffer big
       * enough?
       */
      totalLen = writeCtx->prelimLen + (unsigned int)(writeCtx->base64Len);
      if (totalLen < writeCtx->prelimLen)
        break;
      totalLen += writeCtx->trailLen;
      if (totalLen < writeCtx->trailLen)
        break;

      VOLT_SET_FNCT_LINE (fnctLine)
      status = VT_ERROR_BUFFER_TOO_SMALL;
      *messageLen = totalLen;
      if (bufferSize < *messageLen)
        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, call Update to write out the
       * preliminary data and what data we can process.
       */
      VOLT_SET_ERROR_TYPE (errorType, 0)
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VoltSecureMailWriteUpdate (
        secureMailObj, random, inputData, inputDataLen,
        message, bufferSize, &updateLen);
      if (status != 0)
        break;

      message += updateLen;
      bufferSize -= updateLen;
      input = (unsigned char *)0;
      inputLen = 0;
    }

    if (obj->state == VOLT_SECURE_MAIL_STATE_WRITE_UPDATE)
    {
      /* We've called Update, we'll need to call all the Finals.
       */
      VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VT_ERROR_INVALID_INPUT_LENGTH;
      signedDataLen = inputLen + footerLen;
      if (signedDataLen < inputLen)
        break;

      /* How much space is needed for the last chunk of input.
       */
      VOLT_SET_ERROR_TYPE (errorType, 0)
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VtPkcs7WriteFinal (
        obj->p7SignedData, random, (unsigned char *)0, signedDataLen,
        (unsigned char *)0, 0, &signedDataLen);
      if (status == 0)
        status = VT_ERROR_GENERAL;
      if (status != VT_ERROR_BUFFER_TOO_SMALL)
        break;

      VOLT_SET_FNCT_LINE (fnctLine)
      status = VtPkcs7WriteFinal (
        obj->p7EnvelopedData, random, (unsigned char *)0, signedDataLen,
        (unsigned char *)0, 0, &envelopedDataLen);
      if (status == 0)
        status = VT_ERROR_GENERAL;
      if (status != VT_ERROR_BUFFER_TOO_SMALL)
        break;

      /* How long will the Base64 be?
       */
      encodeDecodeSizeInfo.dataToProcess = (unsigned char *)0;
      encodeDecodeSizeInfo.dataToProcessLen = envelopedDataLen;
      VOLT_SET_FNCT_LINE (fnctLine)
      status = obj->GetEncodeDecodeSize (
        obj->base64, (VtRandomObject)0, VOLT_CALLER_ENCODE_FINAL,
        &encodeDecodeSizeInfo);
      if (status != VT_ERROR_BUFFER_TOO_SMALL)
        break;

#if VT_64_BIT_LENGTH == 64
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VT_ERROR_INVALID_INPUT_LENGTH;
      if (encodeDecodeSizeInfo.processedDataLen > 0xffffffff)
        break;
#endif
      b64Len = (unsigned int)(encodeDecodeSizeInfo.processedDataLen);

      /* We know the total length of the output. Is the buffer big
       * enough?
       * If totalLen is already set, we've already made the check.
       */
      if (totalLen == 0)
      {
        VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
        VOLT_SET_FNCT_LINE (fnctLine)
        status = VT_ERROR_INVALID_INPUT_LENGTH;
        *messageLen = b64Len + writeCtx->trailLen;
        if (*messageLen < b64Len)
          break;

        VOLT_SET_FNCT_LINE (fnctLine)
        status = VT_ERROR_BUFFER_TOO_SMALL;
        if (bufferSize < *messageLen)
          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;
      }
    }
    else
    {
      /* If we reach this point, the state was not INIT or UPDATE. We
       * can call Final only after Init or Update.
       */
      VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VT_ERROR_INVALID_CALL_ORDER;
      break;
    }

    /* Allocate a buffer to hold the signed data.
     */
    VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VT_ERROR_MEMORY;
    sBuffer = (unsigned char *)Z2Malloc (signedDataLen, 0);
    if (sBuffer == (unsigned char *)0)
      break;

    /* Write out the SignedData.
     */
    updateLen = 0;
    VOLT_SET_ERROR_TYPE (errorType, 0)
    if (inputLen != 0)
    {
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VtPkcs7WriteUpdate (
        obj->p7SignedData, random, input, inputLen,
        sBuffer, signedDataLen, &updateLen);
      if (status != 0)
        break;
    }

    /* Add the contentFooter. If there's no footer, we still want to
     * call Final.
     */
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VtPkcs7WriteFinal (
      obj->p7SignedData, random, footer, footerLen,
      sBuffer + updateLen, signedDataLen - updateLen, &signedDataLen);
    if (status != 0)
      break;
    signedDataLen += updateLen;

    /* Allocate a buffer to hold the enveloped data.
     */
    VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VT_ERROR_MEMORY;
    eBuffer = (unsigned char *)Z2Malloc (envelopedDataLen, 0);
    if (eBuffer == (unsigned char *)0)
      break;

    /* Envelope the signed data.
     */
    VOLT_SET_ERROR_TYPE (errorType, 0)
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VtPkcs7WriteFinal (
      obj->p7EnvelopedData, random, sBuffer, signedDataLen,
      eBuffer, envelopedDataLen, &envelopedDataLen);
    if (status != 0)
      break;

    /* Write out the Base64 into the app-supplied buffer.
     */
    offset = 0;
    if (preP7->len != 0)
    {
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VtEncodeFinal (
        obj->base64, (VtRandomObject)0, preP7->data, preP7->len,
        message, bufferSize, &b64Len);
      if (status != 0)
        break;

      offset = b64Len;
      preP7->len = 0;
    }
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VtEncodeFinal (
      obj->base64, (VtRandomObject)0, eBuffer, envelopedDataLen,
      message + offset, bufferSize - offset, &b64Len);
    if (status != 0)
      break;

    offset += b64Len;

    /* Write out any trailing info.
     */
    newLine = writeCtx->itemArray[VOLT_WRITE_SM_ITEM_NEW_LINE].data;
    newLineLen = writeCtx->itemArray[VOLT_WRITE_SM_ITEM_NEW_LINE].len;
    for (index = VOLT_WRITE_SM_FOOT_INDEX_START;

⌨️ 快捷键说明

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