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

📄 smwrite.c

📁 voltage 公司提供的一个开发Ibe的工具包
💻 C
📖 第 1 页 / 共 3 页
字号:
        status = AppendToVtItem (
          libCtx, writeCtx->itemArray[VOLT_WRITE_SM_ITEM_SUBJECT].data,
          writeCtx->itemArray[VOLT_WRITE_SM_ITEM_SUBJECT].len,
          newLine, newLineLen, report);
        if (status != 0)
          break;
      }
      status = AppendToVtItem (
        libCtx, newLine, newLineLen, (unsigned char *)0, 0, report);
      if (status != 0)
        break;

      reportLen = report->len;
    }
    else if (obj->formatType == VOLT_MESSAGE_FORMAT_SECURE_MAIL_2)
    {
      reportLen += (2 * newLineLen);

      status = VT_ERROR_MEMORY;
      report->data = (unsigned char *)Z2Realloc (report->data, reportLen);
      if (report->data == (unsigned char *)0)
        break;

      /* For SecureMail 2, the headers inside the PKCS7 blob consist of some
       * XML data (instead of the MIME-style headers used with V1. So we don't
       * need to prepend the content-type label before writing the header data.
       */
      Z2Memcpy(report->data, obj->contentInfo.data, obj->contentInfo.len);
      offset = obj->contentInfo.len;
      /* A blank line indicates the end of the headers, so add 2 new lines */
      Z2Memcpy (report->data + offset, newLine, newLineLen);
      offset += newLineLen;
      Z2Memcpy (report->data + offset, newLine, newLineLen);
      report->len = reportLen;
    }
    else
    {
      /* Build the content-type: ...; file-name= line. Add in the label
       * and 2 new lines.
       */
      if (reportLen != 0)
      {
        contentType = (char *)(obj->contentInfo.data);
        asciiNumLen = obj->contentInfo.len;
      }
      else
      {
        reportLen = VOLT_SECURE_FILE_CONTENT_LEN;
        asciiNumLen = VOLT_SECURE_FILE_CONTENT_LEN;
      }

      reportLen +=
        VOLT_CONTENT_TYPE_LABEL_LEN + VOLT_FILE_NAME_LABEL_LEN +
        writeCtx->fileName.len + 3 + (2 * newLineLen);

      status = VT_ERROR_MEMORY;
      asciiNum = (unsigned char *)Z2Malloc (reportLen, 0);
      if (asciiNum == (unsigned char *)0)
        break;

      /* Build the content descriptor buffer, content type for file
       * label, then the file name, new line, and new line.
       */
      Z2Memcpy (
        asciiNum, VOLT_CONTENT_TYPE_LABEL, VOLT_CONTENT_TYPE_LABEL_LEN);
      offset = VOLT_CONTENT_TYPE_LABEL_LEN;
      Z2Memcpy (asciiNum + offset, contentType, asciiNumLen);
      offset += asciiNumLen;
      Z2Memcpy (asciiNum + offset, "; ", 2);
      offset += 2;
      Z2Memcpy (
        asciiNum + offset, VOLT_FILE_NAME_LABEL, VOLT_FILE_NAME_LABEL_LEN);
      offset += VOLT_FILE_NAME_LABEL_LEN;
      Z2Memcpy (
        asciiNum + offset, writeCtx->fileName.data, writeCtx->fileName.len);
      offset += writeCtx->fileName.len;
      Z2Memcpy (asciiNum + offset, ";", 1);
      offset += 1;
      /* After the file name, newLine, then a blank line.
       */
      Z2Memcpy (asciiNum + offset, newLine, newLineLen);
      offset += newLineLen;
      Z2Memcpy (asciiNum + offset, newLine, newLineLen);

      if (report->data != (unsigned char *)0)
        Z2Free (report->data);
      report->data = (unsigned char *)asciiNum;
      report->len = reportLen;
      asciiNum = (char *)0;
    }

    /* Set the length of the SignedData. The length is the reportLen
     * plus the dataLen plus the content footerLen.
     */
    reportLen += (obj->dataLen + footerLen);
    status = VtSetPkcs7Param (
      obj->p7SignedData, VtPkcs7ParamDataLen, (Pointer)&reportLen);
    if (status != 0)
      break;

    /* Call Final with no output to determine length.
     */
    status = VtPkcs7WriteFinal (
      obj->p7SignedData, random, (unsigned char *)0, reportLen,
      (unsigned char *)0, 0, &(writeCtx->signedDataLen));
    if (status == 0)
      status = VT_ERROR_GENERAL;
    if (status != VT_ERROR_BUFFER_TOO_SMALL)
      break;

    /* We now know how many bytes we're going to pass to the enveloper.
     */
    status = VtSetPkcs7Param (
      obj->p7EnvelopedData, VtPkcs7ParamDataLen,
      (Pointer)&(writeCtx->signedDataLen));
    if (status != 0)
      break;

    /* How big is the enveloped data going to be?
     */
    status = VtPkcs7WriteFinal (
      obj->p7EnvelopedData, random,
      (unsigned char *)0, (writeCtx->signedDataLen),
      (unsigned char *)0, 0, &(writeCtx->envelopedDataLen));
    if (status == 0)
      status = VT_ERROR_GENERAL;
    if (status != VT_ERROR_BUFFER_TOO_SMALL)
      break;

    /* Call Final to determine the length.
     */
    status = obj->GetEncodeDecodeSize (
      obj->base64, (VtRandomObject)0, VOLT_CALLER_ENCODE_FINAL,
      (unsigned char *)0, writeCtx->envelopedDataLen + preP7->len,
      &(writeCtx->base64Len));
    if (status == 0)
      status = VT_ERROR_GENERAL;
    if (status != VT_ERROR_BUFFER_TOO_SMALL)
      break;

    /* If this is ZDM, we may need to add padding.
     */
    if ((obj->formatType & VOLT_MESSAGE_FORMAT_ZDM) != 0)
    {
      status = VoltAddZDMPad (obj, writeCtx, writeCtx->base64Len);
      if (status != 0)
        break;
    }

    status = 0;
    obj->state = VOLT_SECURE_MAIL_STATE_WRITE_INIT_LEN;

  } while (0);

  if (asciiNum != (char *)0)
    Z2Free (asciiNum);

  return (status);
}

int ConvertNumToAsciiAlloc (
   VoltLibCtx *libCtx,
   unsigned int theNum,
   char **asciiNum,
   unsigned int *asciiNumLen
   )
{
  unsigned int value, current, radix;
  unsigned int places, index;
  char *buffer = (unsigned char *)0;

  *asciiNum = (char *)0;

  /* First, count the size.
   */
  radix = 10;
  places = 1;
  while (theNum >= radix)
  {
    places++;
    radix *= 10;
  }

  /* Allocate the buffer to hold the result.
   */
  buffer = (char *)Z2Malloc (places + 1, 0);
  if (buffer == (char *)0)
    return (VT_ERROR_MEMORY);
  Z2Memset ((Pointer)buffer, 0x30, places);
  buffer[places] = 0;

  value = theNum;
  index = places - 1;
  do
  {
    current = value % 10;
    buffer[index] |= (char)current;
    value -= current;
    value = value / 10;
    index--;
  } while (value != 0);

  *asciiNum = buffer;
  *asciiNumLen = places;

  return (0);
}

static int AppendToVtItem (
   VoltLibCtx *libCtx,
   unsigned char *dataToAppend,
   unsigned int dataToAppendLen,
   unsigned char *trailingCharacters,
   unsigned int trailingCharactersLen,
   VtItem *theItem
   )
{
  int status;
  unsigned int totalLen;
  unsigned char *newBuffer = (unsigned char *)0;

  do
  {
    /* Allocate space for old an new.
     */
    status = VT_ERROR_MEMORY;
    totalLen = 0;
    if (theItem->data != (unsigned char *)0)
      totalLen = theItem->len;

    totalLen += dataToAppendLen + trailingCharactersLen;

    newBuffer = (unsigned char *)Z2Malloc (totalLen, VOLT_MEMORY_SENSITIVE);
    if (newBuffer == (unsigned char *)0)
      break;

    /* Copy the old into the new.
     */
    Z2Memcpy (newBuffer, theItem->data, theItem->len);

    /* Copy the new.
     */
    Z2Memcpy (newBuffer + theItem->len, dataToAppend, dataToAppendLen);

    /* Any trailing characters?
     */
    Z2Memcpy (
      newBuffer + theItem->len + dataToAppendLen, trailingCharacters,
      trailingCharactersLen);

    /* Free the old.
     */
    Z2Free (theItem->data);

    /* Set theItem with the new.
     */
    theItem->data = newBuffer;
    theItem->len = totalLen;

    status = 0;

  } while (0);

  /* If no errors, we're done.
   */
  if (status == 0)
    return (0);

  /* If error, free up what we allocated.
   */
  if (newBuffer != (unsigned char *)0)
    Z2Free (newBuffer);

  return (status);
}

#define ZDM_REQUIRED_LEN    4096
#define ZDM_SEARCH_PATTERN  "\">"
#define ONE_LINE_LEN        64

int VoltAddZDMPad (
   VoltSecureMailObject *obj,
   VoltSecureMailWriteCtx *writeCtx,
   unsigned int messageLen
   )
{
  int status;
  unsigned int startLen, endLen, extraLen, totalLen, newLen, lineCount;
  unsigned int index, leftovers, offset;
  VoltLibCtx *libCtx = (VoltLibCtx *)(obj->voltObject.libraryCtx);
  char *start, *end;
  unsigned char *buffer = (unsigned char *)0;
  unsigned char oneLine[ONE_LINE_LEN];

  do
  {
    /* If messageLen is already > ZDM_REQUIRED_LEN, no need to go
     * further.
     */
    status = 0;
    if (messageLen >= ZDM_REQUIRED_LEN)
      break;

    /* In writeCtx->itemArray[VOLT_WRITE_SM_ITEM_END_MSG] is the place
     * where we stop counting towards the ZDM_REQUIRED_LEN. Find that
     * place.
     * Don't use Strstr because this buffer is not necessarily
     * NULL-terminated.
     */
    start = (char *)(writeCtx->itemArray[VOLT_WRITE_SM_ITEM_END_MSG].data);
    end = start;
    offset = 0;
    /* Set newLen to a max. If we search this many bytes, we didn't
     * find the target and we won't, so stop looking.
     */
    newLen = writeCtx->itemArray[VOLT_WRITE_SM_ITEM_END_MSG].len - 1;
    do
    {
      if (end[0] == '"')
      {
        if (end[1] == '>')
          break;
      }
      offset++;
      end++;

      /* If we haven't looked through the entire buffer, keep looking.
       * If there's no more buffer to search, stop looking, the answer
       * is NULL, which will later trigger an error.
       */
      if (offset < newLen)
        continue;

      end = (char *)0;
      break;

    } while (1);

    /* If we didn't find the location, it wasn't there, something's
     * wrong.
     */
    status = VT_ERROR_INVALID_INPUT;
    if (end == (char *)0)
      break;

    startLen = (unsigned int)end - (unsigned int)start;
    endLen = writeCtx->itemArray[VOLT_WRITE_SM_ITEM_END_MSG].len - startLen;
    /* Any bytes up to the target are counted toward the
     * ZDM_REQUIRED_LEN.
     */
    totalLen = startLen;
    /* The BEGIN MESSAGE, BEGIN BLOCK, and END BLOCK are included in
     * the ZDM_REQUIRED_LEN, if they exist.
     */
    totalLen += writeCtx->itemArray[VOLT_WRITE_SM_ITEM_END_BLK].len;
    totalLen += writeCtx->itemArray[VOLT_WRITE_SM_ITEM_BEGIN_BLK].len;
    totalLen += writeCtx->itemArray[VOLT_WRITE_SM_ITEM_HEADER].len;
    /* Finally, add the message length.
     */
    totalLen += messageLen;

    /* If there are at least ZDM_REQUIRED_LEN bytes, no need to pad,
     * we're done.
     */
    status = 0;
    if (totalLen >= ZDM_REQUIRED_LEN)
      break;

    /* How many pad bytes do we need?
     */
    extraLen = ZDM_REQUIRED_LEN - totalLen;

    /* We're going to add a series of lines, each line consisting of a
     * series of spaces, followed by new line character(s). First,
     * build a line with the appropriate new line character. The total
     * length of the line will be ONE_LINE_LEN.
     */
    Z2Memset (oneLine, ' ', ONE_LINE_LEN);
    Z2Memcpy (
      oneLine + ONE_LINE_LEN -
      writeCtx->itemArray[VOLT_WRITE_SM_ITEM_NEW_LINE].len,
      writeCtx->itemArray[VOLT_WRITE_SM_ITEM_NEW_LINE].data,
      writeCtx->itemArray[VOLT_WRITE_SM_ITEM_NEW_LINE].len);

    /* How many full lines do we add? How many leftovers after we have
     * printed out a bunch of lines?
     */
    lineCount = extraLen / ONE_LINE_LEN;
    leftovers = extraLen - (lineCount * ONE_LINE_LEN);

    /* Allocate a buffer to hold the contents of the data in
     * itemArray[VOLT_WRITE_SM_ITEM_END_MSG] along with the new lines.
     * The new data will be placed into the middle of the buffer, which
     * is why we don't do a Realloc (although we could with a Memmove,
     * but choose not to for efficiency).
     */
    status = VT_ERROR_MEMORY;
    newLen = writeCtx->itemArray[VOLT_WRITE_SM_ITEM_END_MSG].len + extraLen;
    buffer = (unsigned char *)Z2Malloc (newLen + 1, 0);
    if (buffer == (unsigned char *)0)
      break;

    Z2Memcpy (
      buffer, writeCtx->itemArray[VOLT_WRITE_SM_ITEM_END_MSG].data, startLen);
    offset = startLen;
    for (index = 0; index < lineCount; ++index)
    {
      Z2Memcpy (buffer + offset, oneLine, ONE_LINE_LEN);
      offset += ONE_LINE_LEN;
    }
    /* Print out leftovers. Get rid of the new line characters in case
     * leftovers is ONE_LINE_LEN - 1 and newLineChar length is 2.
     */
    Z2Memset (
      oneLine + ONE_LINE_LEN -
      writeCtx->itemArray[VOLT_WRITE_SM_ITEM_NEW_LINE].len, ' ',
      writeCtx->itemArray[VOLT_WRITE_SM_ITEM_NEW_LINE].len);
    Z2Memcpy (buffer + offset, oneLine, leftovers);
    offset += leftovers;
    Z2Memcpy (
      buffer + offset,
      writeCtx->itemArray[VOLT_WRITE_SM_ITEM_END_MSG].data + startLen, endLen);
    buffer[newLen] = 0;

    /* Free the old buffer.
     */
    Z2Free (writeCtx->itemArray[VOLT_WRITE_SM_ITEM_END_MSG].data);
    /* Replace it with the new.
     */
    writeCtx->itemArray[VOLT_WRITE_SM_ITEM_END_MSG].data = buffer;
    writeCtx->itemArray[VOLT_WRITE_SM_ITEM_END_MSG].len = newLen;
    writeCtx->trailLen += extraLen;

    status = 0;
  } while (0);

  if (status == 0)
    return (0);

  /* If there was an error, free the buffer we would have returned, but
   * didn't.
   */
  if (buffer != (unsigned char *)0)
    Z2Free (buffer);

  return (status);
}

⌨️ 快捷键说明

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