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

📄 smread.c

📁 IBE是一种非对称密码技术
💻 C
📖 第 1 页 / 共 4 页
字号:
          (unsigned char *)0, 0, &p7OutputLen);

        /* 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;
        }

        retFlag = 1;
        if (status != VT_ERROR_BUFFER_TOO_SMALL)
          break;

        /* The error was BUFFER, meaning we've hit data for the first
         * time. That data will begin with a series of content
         * descriptors.
         */
        retFlag = 0;
        readCtx->contentMaterialState = VOLT_CONTENT_MATERIAL_STATE_ELEMENT;

      case VOLT_CONTENT_MATERIAL_STATE_ELEMENT:
        /* Create a new element in the link list and place it at the end
         * of the list.
         */
        VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
        VOLT_SET_FNCT_LINE (fnctLine)
        status = VT_ERROR_MEMORY;
        newElement = (VoltContentMaterial *)Z2Malloc (
          sizeof (VoltContentMaterial), 0);
        if (newElement == (VoltContentMaterial *)0)
          break;
        Z2Memset (newElement, 0, sizeof (VoltContentMaterial));

        /* Find the last element in the list. Append this new element to
         * the end of the list.
         */
        currentElement = readCtx->contentMaterial;
        if (currentElement == (VoltContentMaterial *)0)
        {
          readCtx->contentMaterial = newElement;
        }
        else
        {
          while (currentElement->nextElement != (Pointer)0)
            currentElement = (VoltContentMaterial *)(currentElement->nextElement);

          currentElement->nextElement = (Pointer)newElement;
        }

        /* Set currentElement to this new one, so we can NULL the
         * newElement variable. It will be freed if not NULL.
         */
        currentElement = newElement;
        newElement = (VoltContentMaterial *)0;
        status = 0;
        break;

      case VOLT_CONTENT_MATERIAL_STATE_PARTIAL:
        /* Find the last element, it's the one we're in the middle of.
         */
        VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
        VOLT_SET_FNCT_LINE (fnctLine)
        status = VT_ERROR_INVALID_SECURE_MAIL_OBJ;
        currentElement = readCtx->contentMaterial;
        if (currentElement == (VoltContentMaterial *)0)
          break;
        nextElement = (VoltContentMaterial *)(currentElement->nextElement);
        while (nextElement != (VoltContentMaterial *)0)
        {
          currentElement = nextElement;
          nextElement = (VoltContentMaterial *)(currentElement->nextElement);
        }

        status = 0;
    }

    /* If newElement is not NULL, free it. If there was no error, either
     * there was no newElement, or the variable was set to NULL.
     */
    if (newElement != (VoltContentMaterial *)0)
      Z2Free (newElement);

    /* End of part 1. If retFlag is not 0, we're done. If there's an
     * error, we're done.
     */
    if ( (retFlag != 0) || (status != 0) )
      break;

    /* Begin part 2.
     */

    /* At this point we are trying to read a content descriptor.
     */
    VOLT_SET_ERROR_TYPE (errorType, 0)
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VoltSMGetNextBlock (
      obj, &(currentElement->material), readCtx->unprocessedData.data,
      readCtx->unprocessedData.len, 1, &signRead, &completeFlag, &newLineLen);
    if (status != 0)
      break;

    VOLT_SET_FNCT_LINE (fnctLine)
    status = ProcessContentDescriptor (
      obj, readCtx, &(currentElement->material), completeFlag, signRead);
    if (status != 0)
      break;

    /* If the state is now PARTIAL, there's nothing more we can do.
     */
    if (readCtx->contentMaterialState == VOLT_CONTENT_MATERIAL_STATE_PARTIAL)
      break;

    /* Resurse, call VoltSMDoSignedDataRead as long as there's data to
     * read.
     */
    if (readCtx->unprocessedData.len != 0)
    {
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VoltSMDoSignedDataRead (
        obj, readCtx, 1, output, outputSize, outputLen);
    }

  } while (0);

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

  return (status);
}

static int ProcessContentDescriptor (
   VoltSecureMailObject *obj,
   VoltSecureMailReadCtx *readCtx,
   VoltByteArrayObj *byteArrayObj,
   unsigned int completeFlag,
   unsigned int signRead
   )
{
  int status;
  unsigned int index;
  VoltLibCtx *libCtx = (VoltLibCtx *)(obj->voltObject.libraryCtx);
  VOLT_DECLARE_FNCT_LINE (fnctLine)

  do
  {
    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 not complete, just set the contentMaterialState.
     */
    if (completeFlag == 0)
    {
      status = 0;
      readCtx->contentMaterialState = VOLT_CONTENT_MATERIAL_STATE_PARTIAL;
      break;
    }

    /* Read the data. The P7 object needs to read this data, but we don't
     * want to give it to the app's buffer. Use index as a temp variable,
     * it will be passed for the bytesRead arg, but we're going to ignore
     * it.
     */
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VtPkcs7ReadUpdate (
      obj->p7SignedData, byteArrayObj->data, byteArrayObj->len,
      &index, byteArrayObj->data, byteArrayObj->size,
      &(byteArrayObj->len));
    if (status != 0)
      break;

    /* Is this the last one? It is if it is just new line.
     */
    if (byteArrayObj->len > 2)
    {
      /* Replace the new line character with a NULL-terminating character.
       * We have to do this after calling ReadUpdate, the newline
       * characters are part of the data to sign.
       */
      index = byteArrayObj->len - 2;
      if (byteArrayObj->data[index] != 0x0D)
        index++;
      byteArrayObj->data[index] = 0;

      readCtx->contentMaterialState = VOLT_CONTENT_MATERIAL_STATE_ELEMENT;
      readCtx->contentMaterialCount++;
      break;
    }

    readCtx->contentMaterialState = VOLT_CONTENT_MATERIAL_STATE_COMPLETE;

  } while (0);

  VOLT_LOG_ERROR_INFO_COMPARE (
    status, 0, obj, status, 0, 0,
    (char *)0, "ProcessContentDescriptor", fnctLine, (char *)0)

  return (status);
} 

int VoltSMGetNextBlock (
   VoltSecureMailObject *obj,
   VoltByteArrayObj *byteArrayObj,
   unsigned char *message,
   unsigned int messageLen,
   unsigned int flag,
   unsigned int *bytesRead,
   unsigned int *completeFlag,
   unsigned int *newLineCharCount
   )
{
  int status; 
  unsigned int index, nullIndex, copyCount;
  unsigned char spaceChar, tabChar;
  VoltLibCtx *libCtx = (VoltLibCtx *)(obj->voltObject.libraryCtx);    
  VOLT_DECLARE_FNCT_LINE (fnctLine)

  *bytesRead = 0;
  *completeFlag = 0;
  *newLineCharCount = 0;
  status = 0;

  do
  {
    if (messageLen == 0)
      break;

    /* First check if the last read of the data found a partial 
     * new line. That is, the last char during the last call was 0x0D.
     */
    if (byteArrayObj->len > 0)
    {
      if (byteArrayObj->data[byteArrayObj->len - 1] == 0x0D)
      {
        /* If the next character is not 0x0A, that means the previous
         * call to GetNextBlock stopped on a 0x0D, it didn't know if the
         * next character was a 0x0A or not, so it called with the next
         * bytes. It wasn't. So the line is complete.
         */
        *completeFlag = 1;
        *newLineCharCount = 1;
        if (message[0] != 0x0A)
          break;

        /* The next char is 0x0A, read it and a line is done.
         */
        nullIndex = byteArrayObj->len - 1;
        *bytesRead = 1;   
        *newLineCharCount = 2;
        VOLT_SET_FNCT_LINE (fnctLine)
        status = StoreUnprocessedData (obj, byteArrayObj, message, 1);
        if (status != 0)
          break;

        if ((flag & 1) == 0)
          byteArrayObj->data[nullIndex] = 0;

        break;
      }
    }

    /* Search until finding a new line character.
     */
    index = 0;
    do
    {
      if ( (message[index] == 0x0D) || (message[index] == 0x0A) )
        break;
      index++;
    } while (index < messageLen);

    /* If index < messageLen, we broke out early, we found the new line
     * char, index is the index of this new line, so the copyCount is
     * one more than index. If index >= messageLen, we went through the
     * line and found no new line. Index is one beyond the search, so
     * the copyCount is index.
     */
    copyCount = index;
    if (index < messageLen)
      copyCount++;

    *bytesRead = copyCount;
    nullIndex = index + byteArrayObj->len;

    /* Store the bytes we read.
     */
    VOLT_SET_FNCT_LINE (fnctLine)
    status = StoreUnprocessedData (obj, byteArrayObj, message, copyCount);
    if (status != 0)
      break;

    /* If index >= messageLen, we searched all input and found no new
     * line. We can't complete a line. We stored the characters we
     * read, so there's nothing left to do.
     */
    if (index >= messageLen)
      break;

    /* If we broke out early, we found a new line character. If that
     * char is 0x0D, there might be a 0x0A.
     */
    *completeFlag = 1;
    *newLineCharCount = 1;
    if (message[index] == 0x0D)
    {
      /* If there are no more bytes, we can't read beyond the end.
       */
      if (index == (messageLen - 1))
      {
        /* If this is not the last block, we can't complete a line.
         */
        *completeFlag = 0;
        if ((flag & 0x10) == 0)
          break;

        /* This is the last of the total message, so this is a complete
         * line.
         */
        *completeFlag = 1;
      }
      else
      {
        /* Is the next character 0x0A? If so, the line is one more char.
         */
        if (message[index + 1] == 0x0A)
        {
          index++;
          *newLineCharCount = 2;
          *bytesRead = index + 1;

          VOLT_SET_FNCT_LINE (fnctLine)
          status = StoreUnprocessedData (
            obj, byteArrayObj, message + index, 1);
          if (status != 0)
            break;
        }
      }
    }

    if ((flag & 1) == 0)
      byteArrayObj->data[nullIndex] = 0;

  } while (0);

  /* If we're done and the caller wants to skip spaces and tabs, do a
   * Memmove.
   */
  if (*completeFlag == 1)
  {
    if ((flag & 8) != 0)
    {
      spaceChar = ' ';
      tabChar = '\t';
      index = 0;
      while ( (byteArrayObj->data[index] == spaceChar) ||
        (byteArrayObj->data[index] == tabChar) )
        index++;
      if (index != 0)
      {
        Z2Memmove (
          byteArrayObj->data, byteArrayObj->data + index,
          byteArrayObj->len - index);
        byteArrayObj->len -= index;
      }
    }
  }

  VOLT_LOG_ERROR_INFO_COMPARE (
    status, 0, obj, status, 0, 0,
    (char *)0, "VoltSMGetNextBlock", fnctLine, (char *)0)

  return (status);
}

static int StoreUnprocessedData (
   VoltSecureMailObject *obj,
   VoltByteArrayObj *byteArrayObj,
   unsigned char *data,
   unsigned int dataLen
   )
{
  int status;
  unsigned int totalLen;
  VoltLibCtx *libCtx = (VoltLibCtx *)(obj->voltObject.libraryCtx);
  VOLT_DECLARE_FNCT_LINE (fnctLine)

  do
  {
    /* How big will the buffer need to be?
     */
    totalLen = dataLen + byteArrayObj->len;
    if (totalLen > byteArrayObj->size)
    {
      /* We need more space.
       */
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VT_ERROR_MEMORY;
      byteArrayObj->data = (unsigned char *)Z2Realloc (
        byteArrayObj->data, totalLen);
      if (byteArrayObj->data == (unsigned char *)0)
        break;

      byteArrayObj->size = totalLen;
    }

    /* Append any new data to the end of any old data.
     */
    Z2Memcpy (byteArrayObj->data + byteArrayObj->len, data, dataLen);
    byteArrayObj->len = totalLen;

    status = 0;

  } while (0);

  VOLT_LOG_ERROR_INFO_COMPARE (
    status, 0, obj, status, 0, VT_ERROR_TYPE_PRIMARY,
    (char *)0, "StoreUnprocessedData", fnctLine, (char *)0)

  return (status);
}

⌨️ 快捷键说明

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