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

📄 smread.c

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

      /* Set the state to indicate that we're done reading the message.
       * Next up, do Envelope ReadFinal.
       */
VoltSecureMailStateReadEnvFinal:
      status = 0;
      readCtx->unprocessedData.len = 0;
      obj->state = VOLT_SECURE_MAIL_STATE_READ_ENV_FINAL;
      if (currentMessageLen != 0)
        goto VoltSecureMailStateReadComplete;
  }

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

  return (status);
}

int VoltSecureMailReadFinal (
   VtSecureMailObject secureMailObj,
   unsigned char *message,
   unsigned int messageLen,
   unsigned int *bytesRead,
   unsigned char *outputData,
   unsigned int bufferSize,
   unsigned int *outputDataLen
   )
{
  int status;
  unsigned int outputSign;
  VoltSecureMailObject *obj = (VoltSecureMailObject *)secureMailObj;
  VoltSecureMailReadCtx *readCtx = (VoltSecureMailReadCtx *)(obj->localCtx);
  VOLT_DECLARE_ERROR_TYPE (errorType)
  VOLT_DECLARE_FNCT_LINE (fnctLine)

  *bytesRead = 0;
  *outputDataLen = 0;

  /* We're in ReadFinal, set the readFinal field to 1 so anyone we call
   * can know we're really inside ReadFinal
   */
  readCtx->readFinal = 1;

  switch (obj->state)
  {
    case VOLT_SECURE_MAIL_STATE_READ_COMPLETE:
      status = 0;
      break;

    default:
      /* This is SecureMailReadFinal, so this should be the last of the
       * message to read.
       * The return can be CHOOSE, BUFFER_TOO_SMALL, success or another
       * error. If CHOOSE, pass that on to the caller. If BUFFER, pass
       * it on to the caller, because any output from this call to
       * Update should go to the caller-supplied buffer, and there
       * should be no more output after this. Any other error pass on
       * to the caller.
       */
      VOLT_SET_ERROR_TYPE (errorType, 0)
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VoltSecureMailReadUpdate (
        secureMailObj, message, messageLen, bytesRead,
        outputData, bufferSize, outputDataLen);
      if (status != 0)
        break;

      /* At this point, because we're in ReadFinal, the state should be
       * ENV_FINAL.
       */
      VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VT_ERROR_INVALID_INPUT_LENGTH;
      if (obj->state != VOLT_SECURE_MAIL_STATE_READ_ENV_FINAL)
        break;

    case VOLT_SECURE_MAIL_STATE_READ_ENV_FINAL:
      /* Call EnvelopeFinal.
       */
      VOLT_SET_ERROR_TYPE (errorType, 0)
      VOLT_SET_FNCT_LINE (fnctLine)
      status = DoEnvelopeRead (obj, readCtx, 0);
      if (status != 0)
        break;

    case VOLT_SECURE_MAIL_STATE_READ_SIGN_FINAL:
      /* There should be no output from this call, so the error should
       * not be BUFFER.
       */
      VOLT_SET_ERROR_TYPE (errorType, 0)
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VoltSMDoSignedDataRead (
        obj, readCtx, 0, (unsigned char *)0, 0, &outputSign);
      if (status != 0)
        break;

    case VOLT_SECURE_MAIL_STATE_READ_P7_FINAL:
      obj->state = VOLT_SECURE_MAIL_STATE_READ_COMPLETE;
  }

  /* Reset the readFinal flag to 0, we're no longer in ReadFinal. This
   * is so we don't have to set the field in every other routine.
   */
  readCtx->readFinal = 0;

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

  return (status);
}

int VoltSecureMailVerify (
   VtSecureMailObject secureMailObj,
   VtPolicyCtx policyCtx,
   VtStorageCtx storageCtx,
   VtTransportCtx transportCtx,
   VtCertVerifyCtx certVerifyCtx,
   Pointer verifyCtxInfo,
   VtVerifyFailureList vfyFailList,
   unsigned int *verifyResult
   )
{
  int status;
  VoltSecureMailObject *obj = (VoltSecureMailObject *)secureMailObj;
  VOLT_DECLARE_FNCT_LINE (fnctLine)

  VOLT_SET_FNCT_LINE (fnctLine)
  status = VtPkcs7VerifyAll (
    obj->p7SignedData, policyCtx, storageCtx, transportCtx,
    certVerifyCtx, verifyCtxInfo, vfyFailList, verifyResult);

  VOLT_LOG_ERROR_INFO_COMPARE (
    status, 0, secureMailObj, status, 0, 0,
    (char *)0, "VoltSecureMailVerify", fnctLine, (char *)0)

  return (status);
}

static int DoDecodeUpdateOrFinal (
   VoltSecureMailObject *obj,
   VoltSecureMailReadCtx *readCtx,
   unsigned int flag,
   unsigned char *dataToDecode,
   unsigned int dataToDecodeLen
   )
{
  int status;
  unsigned int outputLen;
  VoltLibCtx *libCtx = (VoltLibCtx *)(obj->voltObject.libraryCtx);
  VOLT_DECLARE_ERROR_TYPE (errorType)
  VOLT_DECLARE_FNCT_LINE (fnctLine)

  do
  {
    VOLT_SET_ERROR_TYPE (errorType, 0)
    if (flag != 0)
    {
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VtDecodeUpdate (
        obj->base64, (VtRandomObject)0, dataToDecode, dataToDecodeLen,
        readCtx->unprocessedData.data, readCtx->unprocessedData.size,
        &outputLen);
    }
    else
    {
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VtDecodeFinal (
        obj->base64, (VtRandomObject)0, dataToDecode, dataToDecodeLen,
        readCtx->unprocessedData.data, readCtx->unprocessedData.size,
        &outputLen);
    }

    /* If successful, just make sure unprocessedData.len is correct and
     * we're done.
     */
    if (status == 0)
    {
      /* If there's any data in the unprocessedData buffer, set the state
       * to READ_ENV. We'll want to read the data in the buffer as
       * EnvelopedData.
       */
      if (outputLen != 0)
        obj->state = VOLT_SECURE_MAIL_STATE_READ_ENV;
      readCtx->unprocessedData.len = outputLen;
      break;
    }

    /* Any error other than BUFFER_TOO_SMALL, return.
     */
    if (status != VT_ERROR_BUFFER_TOO_SMALL)
      break;

    /* Expand the unprocessedData buffer.
     */
    VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VT_ERROR_MEMORY;
    readCtx->unprocessedData.data = (unsigned char *)Z2Realloc (
      readCtx->unprocessedData.data, outputLen);
    readCtx->unprocessedData.size = 0;
    if (readCtx->unprocessedData.data == (unsigned char *)0)
      break;
    readCtx->unprocessedData.size = outputLen;

    /* Call again with the expanded buffer.
     */
    VOLT_SET_ERROR_TYPE (errorType, 0)
    if (flag != 0)
    {
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VtDecodeUpdate (
        obj->base64, (VtRandomObject)0, dataToDecode, dataToDecodeLen,
        readCtx->unprocessedData.data, readCtx->unprocessedData.size,
        &(readCtx->unprocessedData.len));
    }
    else
    {
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VtDecodeFinal (
        obj->base64, (VtRandomObject)0, dataToDecode, dataToDecodeLen,
        readCtx->unprocessedData.data, readCtx->unprocessedData.size,
        &(readCtx->unprocessedData.len));
    }

    /* If successful, we have some data in the unprocessedData buffer
     * that needs to be read as EnvelopedData.
     */
    if (status == 0)
      obj->state = VOLT_SECURE_MAIL_STATE_READ_ENV;

  } while (0);

  VOLT_LOG_ERROR_INFO_COMPARE (
    status, 0, obj, status, 0, errorType,
    (char *)0, "DoDecodeUpdateOrFinal", fnctLine, (char *)0)

  return (status);
}

static int DoEnvelopeRead (
   VoltSecureMailObject *obj,
   VoltSecureMailReadCtx *readCtx,
   unsigned int flag
   )
{
  int status;
  unsigned int envRead, outputLen;
  VoltLibCtx *libCtx = (VoltLibCtx *)(obj->voltObject.libraryCtx);
  unsigned char *eBuffer = (unsigned char *)0;
  VOLT_DECLARE_ERROR_TYPE (errorType)
  VOLT_DECLARE_FNCT_LINE (fnctLine)

  do
  {
    VOLT_SET_ERROR_TYPE (errorType, 0)
    if (flag == 0)
    {
      /* If we're calling EnvelopeFinal, we know there is no more data
       * to process and there should be no more data to output.
       */
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VtPkcs7ReadFinal (
        obj->p7EnvelopedData, (unsigned char *)0, 0, &envRead,
        (unsigned char *)0, 0, &outputLen);
      if (status != 0)
        status = VT_ERROR_INVALID_SECURE_MAIL_MSG;
      obj->state = VOLT_SECURE_MAIL_STATE_READ_SIGN_FINAL;
      break;
    }

    VOLT_SET_FNCT_LINE (fnctLine)
    status = VtPkcs7ReadUpdate (
      obj->p7EnvelopedData, readCtx->unprocessedData.data,
      readCtx->unprocessedData.len, &envRead,
      (unsigned char *)0, 0, &outputLen);

    /* Move the unprocessedData if necessary.
     */
    if (envRead != 0)
    {
      if (envRead != readCtx->unprocessedData.len)
      {
        Z2Memmove (
          readCtx->unprocessedData.data,
          readCtx->unprocessedData.data + envRead,
          readCtx->unprocessedData.len - envRead);
      }
      readCtx->unprocessedData.len -= envRead;
    }

    /* If we're doing Update and status is 0, all the data was read,
     * there was no output, we need to set the state to READ_B64.
     * If status is CHOOSE, just pass it along to the caller, the state
     * stays READ_ENV because we still have some data to read.
     * Any error other than BUFFER_TOO_SMALL, pass on.
     */
    if (status == 0)
      obj->state = VOLT_SECURE_MAIL_STATE_READ_B64;

    if (status != VT_ERROR_BUFFER_TOO_SMALL)
      break;

    /* Allocate space to hold the output.
     */
    VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VT_ERROR_MEMORY;
    eBuffer = (unsigned char *)Z2Malloc (outputLen, VOLT_MEMORY_SENSITIVE);
    if (eBuffer == (unsigned char *)0)
      break;

    /* Call again with the output buffer.
     */
    VOLT_SET_ERROR_TYPE (errorType, 0)
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VtPkcs7ReadUpdate (
      obj->p7EnvelopedData, readCtx->unprocessedData.data,
      readCtx->unprocessedData.len, &envRead,
      eBuffer, outputLen, &outputLen);
    if (status != 0)
      break;

    /* Copy this data into the unprocessedData buffer.
     */
    readCtx->unprocessedData.len = 0;
    VOLT_SET_FNCT_LINE (fnctLine)
    status = StoreUnprocessedData (
      obj, &(readCtx->unprocessedData), eBuffer, outputLen);
    if (status != 0)
      break;

    /* If we're doing Update, set the state to indicate that we need to
     * read the data in the unprocessedData buffer as SignedData.
     */
    obj->state = VOLT_SECURE_MAIL_STATE_READ_SIGNED;

  } while (0);

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

  VOLT_LOG_ERROR_INFO_COMPARE (
    status, 0, obj, status, 0, errorType,
    (char *)0, "DoEnvelopeRead", fnctLine, (char *)0)

  return (status);
}

int VoltSMDoSignedDataRead (
   VoltSecureMailObject *obj,
   VoltSecureMailReadCtx *readCtx,
   unsigned int flag,
   unsigned char *output,
   unsigned int outputSize,
   unsigned int *outputLen
   )
{
  int status;
  unsigned int signRead, completeFlag, p7OutputLen, retFlag;
  VoltLibCtx *libCtx = (VoltLibCtx *)(obj->voltObject.libraryCtx);
  VoltContentMaterial *newElement = (VoltContentMaterial *)0;
  VoltContentMaterial *currentElement, *nextElement;
  unsigned int newLineLen;
  VOLT_DECLARE_ERROR_TYPE (errorType)
  VOLT_DECLARE_FNCT_LINE (fnctLine)

  /* If retFlag is 0, don't return after part 1. If it is 1, return
   * after part 1, error or no error.
   */
  retFlag = 0;

  do
  {
    VOLT_SET_ERROR_TYPE (errorType, 0)
    if (flag == 0)
    {
      /* If we're calling SignedDataFinal, we know there is no more data
       * to process and there should be no more data to output.
       */
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VtPkcs7ReadFinal (
        obj->p7SignedData, (unsigned char *)0, 0, &signRead,
        (unsigned char *)0, 0, &p7OutputLen);
      if (status != 0)
        status = VT_ERROR_INVALID_SECURE_MAIL_MSG;
      obj->state = VOLT_SECURE_MAIL_STATE_READ_P7_FINAL;
      retFlag = 1;
      break;
    }

    /* We're going to do a ReadUpdate. Based on the contentMaterialState,
     * we're either going to read data but output nothing (prefix stuff),
     * read data, process it, but not output it to the app's buffer
     * (content descriptors), or read data and output any result to the
     * app's buffer (data after the content descriptors).
     */
    signRead = 0;
    switch (readCtx->contentMaterialState)
    {
      case VOLT_CONTENT_MATERIAL_STATE_COMPLETE:
      default:
        VOLT_SET_FNCT_LINE (fnctLine)
        status = VtPkcs7ReadUpdate (
          obj->p7SignedData, readCtx->unprocessedData.data,
          readCtx->unprocessedData.len, &signRead,
          output, outputSize, outputLen);

        /* Move the unprocessedData if necessary.
         */
        if (signRead != 0)
        {
          if (signRead != readCtx->unprocessedData.len)
          {
            Z2Memmove (
              readCtx->unprocessedData.data,
              readCtx->unprocessedData.data + signRead,
              readCtx->unprocessedData.len - signRead);
          }
          readCtx->unprocessedData.len -= signRead;
        }

        /* If Update and successful, set the state to indicate we're ready
         * to read Base64 data again.
         */
        retFlag = 1;
        if (status == 0)
          obj->state = VOLT_SECURE_MAIL_STATE_READ_B64;
        break;

      case VOLT_CONTENT_MATERIAL_STATE_NONE:
        /* Read data with NULL output. If the return is 0, there was no
         * output, so the function read everything and there's nothing
         * more to do. If there is an error other than BUFFER, pass it on.
         */
        VOLT_SET_FNCT_LINE (fnctLine)
        status = VtPkcs7ReadUpdate (
          obj->p7SignedData, readCtx->unprocessedData.data,
          readCtx->unprocessedData.len, &signRead,

⌨️ 快捷键说明

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