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

📄 sfread.c

📁 IBE是一种非对称密码技术
💻 C
字号:
/* Copyright 2003-2006, Voltage Security, all rights reserved.
 */
#include "vibe.h"
#include "environment.h"
#include "base.h"
#include "libctx.h"
#include "securemail.h"
#include "derhelp.h"
#include "errorctx.h"

int VoltSecureFileReadInit (
   VtSecureMailObject secureMailObj
   )
{
  int status;
  VoltSecureMailObject *obj = (VoltSecureMailObject *)secureMailObj;
  VOLT_DECLARE_ERROR_TYPE (errorType)
  VOLT_DECLARE_FNCT_LINE (fnctLine)

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

    /* Init the subordinate objects.
     */
    VOLT_SET_ERROR_TYPE (errorType, 0)
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VtPkcs7ReadInit (obj->p7SignedData);
    if (status != 0)
      break;

    VOLT_SET_FNCT_LINE (fnctLine)
    status = VtPkcs7ReadInit (obj->p7EnvelopedData);
    if (status != 0)
      break;

    obj->state = VOLT_SECURE_FILE_STATE_READ_INIT;

  } while (0);

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

  return (status);
}

int VoltSecureFileReadUpdate (
   VtSecureMailObject secureMailObj,
   unsigned char *message,
   unsigned int messageLen,
   unsigned int *bytesRead,
   unsigned char *outputData,
   unsigned int bufferSize,
   unsigned int *outputDataLen
   )
{
  int status;
  unsigned int currentMessageLen, newLineLen, amountRead, outputLen;
  unsigned int completeFlag;
  VoltSecureMailObject *obj = (VoltSecureMailObject *)secureMailObj;
  VoltLibCtx *libCtx = (VoltLibCtx *)(obj->voltObject.libraryCtx);
  VoltSecureMailReadCtx *readCtx = (VoltSecureMailReadCtx *)(obj->localCtx);
  unsigned char *currentMessage;
  unsigned char *beginMsg = VOLT_SECURE_FILE_BEGIN_MSG;
  VOLT_DECLARE_ERROR_TYPE (errorType)
  VOLT_DECLARE_FNCT_LINE (fnctLine)

  *bytesRead = 0;
  *outputDataLen = 0;
  currentMessage = message;
  currentMessageLen = messageLen;

  switch (obj->state)
  {
    default:
      VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VT_ERROR_INVALID_CALL_ORDER;
      break;

    case VOLT_SECURE_FILE_STATE_READ_ENV_FINAL:
    case VOLT_SECURE_FILE_STATE_READ_SIGN_FINAL:
    case VOLT_SECURE_FILE_STATE_READ_COMPLETE:
      /* If we're done, don't read anything.
       */
      status = 0;
      break;

    case VOLT_SECURE_FILE_STATE_READ_INIT:
      /* The first thing to do will be to read the header.
       */
      obj->state = VOLT_SECURE_FILE_STATE_READ_HEADER;

    case VOLT_SECURE_FILE_STATE_READ_HEADER:
      /* We're just starting to read the message. The first thing up
       * might be
       *   version: 1
       */
      VOLT_SET_ERROR_TYPE (errorType, 0)
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VoltSMGetNextBlock (
        obj, &(readCtx->unprocessedData), currentMessage, currentMessageLen,
        1, &amountRead, &completeFlag, &newLineLen);
      if (status != 0)
        break;

      *bytesRead += amountRead;
      if (completeFlag == 0)
        break;

      currentMessage = message + *bytesRead;
      currentMessageLen = messageLen - *bytesRead;
     
      /* We have the next block in the unprocessedData buffer, is this
       * the version block? If not, it's P7 message, read it. If it is,
       * skip it.
       */
      if (readCtx->unprocessedData.data[0] != 'v')
      {
        VOLT_SET_FNCT_LINE (fnctLine)
        status = VtPkcs7ReadUpdate (
          obj->p7EnvelopedData, readCtx->unprocessedData.data,
          readCtx->unprocessedData.len, &amountRead,
          readCtx->unprocessedData.data, readCtx->unprocessedData.size,
          &outputLen);

        readCtx->unprocessedData.len -= amountRead;

        if (status != 0)
          break;

        goto VoltSecureMailReadEnvelope;
      }

      VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VT_ERROR_INVALID_SECURE_FILE_MSG;
      if (readCtx->unprocessedData.len !=
        VOLT_SECURE_FILE_BEGIN_MSG_LEN + newLineLen)
        break;
      if (Z2Memcmp (
        readCtx->unprocessedData.data, beginMsg,
        VOLT_SECURE_FILE_BEGIN_MSG_LEN) != 0)
        break;

      /* Set up the context for the next block.
       */
      status = 0;
      readCtx->unprocessedData.len = 0;
      obj->state = VOLT_SECURE_FILE_STATE_READ_NEW_LINE;

      /* If there's no more message to read, return.
       */
      if (currentMessageLen == 0)
        break;

    case VOLT_SECURE_FILE_STATE_READ_NEW_LINE:
      /* We expect to see a new line here.
       */
      VOLT_SET_ERROR_TYPE (errorType, 0)
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VoltSMGetNextBlock (
        obj, &(readCtx->unprocessedData), currentMessage, currentMessageLen,
        1, &amountRead, &completeFlag, &newLineLen);
      if (status != 0)
        break;

      *bytesRead += amountRead;
      if (completeFlag == 0)
        break;

      currentMessage = message + *bytesRead;
      currentMessageLen = messageLen - *bytesRead;

      /* Make sure we have a valid new line.
       */
      VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VT_ERROR_INVALID_SECURE_FILE_MSG;
      if (readCtx->unprocessedData.len != newLineLen)
        break;      

      /* Set up the context for the next block.
       */
      status = 0;
      readCtx->unprocessedData.len = 0;
      obj->state = VOLT_SECURE_FILE_STATE_READ_ENVELOPE;

      /* If there's no more message to read, return.
       */
      if (currentMessageLen == 0)
        break;

VoltSecureMailReadEnvelope:
    case VOLT_SECURE_FILE_STATE_READ_ENVELOPE:
      /* At this point we have data to pass to the P7 Envelope object.
       * Place any output into the unprocessedData buffer.
       */
      VOLT_SET_ERROR_TYPE (errorType, 0)
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VtPkcs7ReadUpdate (
        obj->p7EnvelopedData, currentMessage, currentMessageLen, &amountRead,
        readCtx->unprocessedData.data, readCtx->unprocessedData.size,
        &outputLen);
      currentMessage += amountRead;
      currentMessageLen -= amountRead;
      *bytesRead += amountRead;

      if (status == VT_ERROR_BUFFER_TOO_SMALL)
      {
        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);
        if (readCtx->unprocessedData.data == (unsigned char *)0)
          break;
        readCtx->unprocessedData.size = outputLen;

        VOLT_SET_ERROR_TYPE (errorType, 0)
        VOLT_SET_FNCT_LINE (fnctLine)
        status = VtPkcs7ReadUpdate (
          obj->p7EnvelopedData, currentMessage, currentMessageLen, &amountRead,
          readCtx->unprocessedData.data, readCtx->unprocessedData.size,
          &outputLen);

        currentMessage += amountRead;
        currentMessageLen -= amountRead;
        *bytesRead += amountRead;
      }

      /* If there'a any error other than BUFFER, pass it on.
       */
      if (status != 0)
        break;

      /* There's no error, either there's no data in the
       * unprocessedData buffer (no data to pass on to SignedData) in
       * which case we're done, or the data we have we need to give to
       * the SignedData P7 object.
       */
      if (outputLen == 0)
        break;

      readCtx->unprocessedData.len = outputLen;
      obj->state = VOLT_SECURE_FILE_STATE_READ_SIGNED;

    case VOLT_SECURE_FILE_STATE_READ_SIGNED:
      /* At this point we have data to pass to the P7 SignedData object.
       * Place any output into the app-supplied buffer.
       * Return any error, including BUFFER_TOO_SMALL.
       */
      VOLT_SET_ERROR_TYPE (errorType, 0)
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VoltSMDoSignedDataRead (
        obj, readCtx, 1, outputData, bufferSize, outputDataLen);
      if (status != 0)
        break;

      /* If we have no error, we read all the data., the next call will
       * need to be to ENVELOPE.
       */
      obj->state = VOLT_SECURE_FILE_STATE_READ_ENVELOPE;

      /* If there's no more message to read, return.
       */
      if (currentMessageLen == 0)
        break;

      goto VoltSecureMailReadEnvelope;
  }

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

  return (status);
}

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

  *bytesRead = 0;
  *outputDataLen = 0;

  switch (obj->state)
  {
    default:
      VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VT_ERROR_INVALID_CALL_ORDER;
      break;

    case VOLT_SECURE_FILE_STATE_READ_COMPLETE:
      status = 0;
      break;

    case VOLT_SECURE_FILE_STATE_READ_INIT:
    case VOLT_SECURE_FILE_STATE_READ_HEADER:
    case VOLT_SECURE_FILE_STATE_READ_NEW_LINE:
    case VOLT_SECURE_FILE_STATE_READ_ENVELOPE:
    case VOLT_SECURE_FILE_STATE_READ_SIGNED:
      /* Call Update on the last amount of data.
       */
      if ( ((message != (unsigned char *)0) && (messageLen != 0)) ||
           (readCtx->unprocessedData.len != 0) )
      {
        VOLT_SET_ERROR_TYPE (errorType, 0)
        VOLT_SET_FNCT_LINE (fnctLine)
        status = VoltSecureFileReadUpdate (
          secureMailObj, message, messageLen, bytesRead,
          outputData, bufferSize, outputDataLen);
        if (status != 0)
          break;
      }

      /* At this point, we should have had all the input data, so we
       * can call the P7 Final functions.
       */
      obj->state = VOLT_SECURE_FILE_STATE_READ_ENV_FINAL;

    case VOLT_SECURE_FILE_STATE_READ_ENV_FINAL:
      /* There should be no output. So if the error is
       * BUFFER_TOO_SMALL, convert it to INVALID_INPUT.
       */
      VOLT_SET_ERROR_TYPE (errorType, 0)
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VtPkcs7ReadFinal (
        obj->p7EnvelopedData, (unsigned char *)0, 0, &amountRead,
        (unsigned char *)0, 0, &outputLen);
      if (status == VT_ERROR_BUFFER_TOO_SMALL)
        status = VT_ERROR_INVALID_INPUT;

      if (status != 0)
        break;

      obj->state = VOLT_SECURE_FILE_STATE_READ_SIGN_FINAL;

    case VOLT_SECURE_FILE_STATE_READ_SIGN_FINAL:
      /* There should be no output. So if the error is
       * BUFFER_TOO_SMALL, convert it to INVALID_INPUT.
       */
      VOLT_SET_ERROR_TYPE (errorType, 0)
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VtPkcs7ReadFinal (
        obj->p7SignedData, (unsigned char *)0, 0, &amountRead,
        (unsigned char *)0, 0, &outputLen);
      if (status == VT_ERROR_BUFFER_TOO_SMALL)
        status = VT_ERROR_INVALID_INPUT;
      if (status != 0)
        break;

      obj->state = VOLT_SECURE_FILE_STATE_READ_COMPLETE;
  }

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

  return (status);
}

⌨️ 快捷键说明

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