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

📄 smwrite.c

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

/* Call this function when obj->dataLen is set, but that info has not
 * been passed down to the P7 and B64 objects.
 * <p>Once we know the total length of data that will be passed to the
 * SecureMail object, we can figure out how many bytes will be passed
 * to the P7 signer object. We can then figure out how big the
 * SignedData will be, which will be passed to the P7 enveloper. The
 * result of that will be passed to the Base64 encoder.
 * <p>This function will set the fields inside the writeCtx that hold
 * the lengths of these elements.
 *
 * @param obj The SecureMail object set with the info.
 * @param writeCtx The context with the objects and fields to set.
 * @param random The random object, calls to P7 functions will have
 * this as an arg.
 * @return an int, 0 if the function completed successfully or a
 * non-zero error code.
 */
static int VOLT_CALLING_CONV SetTotalLengths VOLT_PROTO_LIST ((
   VoltSecureMailObject *obj,
   VoltSecureMailWriteCtx *writeCtx,
   VtRandomObject random
));

/* Append the given data to the given VtItem.
 * <p>This function will allocate the data to hold the old info and the
 * new info, copy the old info into the new buffer, then copy the new
 * info after the old info. It will then place any trailingCharacters.
 * <p>The trailingCharacters might be NULL (nothing to append), or
 * maybe they are new line characters, or maybe they are
 * NULL-terminating characters.
 * <p>This function assumes theItem points to a vaild VtItem.
 * <p>The data field of theItem can be NULL. In other words, the call
 * to Append can place the first block of data into theItem.
 * <p>If dataToAppend or trailingCharacters is NULL, then the
 * affiliated length arg (dataToAppendLen and trailingCharactersLen)
 * must be 0.
 * <p>This function does not check the args, it is the responsibility
 * of the caller not to make mistakes.
 */
static int VOLT_CALLING_CONV AppendToVtItem VOLT_PROTO_LIST ((
   VoltLibCtx *libCtx,
   unsigned char *dataToAppend,
   unsigned int dataToAppendLen,
   unsigned char *trailingCharacters,
   unsigned int trailingCharactersLen,
   VtItem *theItem
));

/* This creates an ASCII string (NULL-terminated) version of theNum in
 * decimal.
 * <p>For example, the number 0x0000006B is converted to a string of
 * length 4: 0x31, 0x30, 0x37, 0x00. That is the string "107".
 */
int VOLT_CALLING_CONV ConvertNumToAsciiAlloc VOLT_PROTO_LIST ((
   VoltLibCtx *libCtx,
   UInt32 theNumLo,
   UInt32 theNumHi,
   char **asciiNum,
   unsigned int *asciiNumLen
));

int VoltSecureMailWriteInit (
   VtSecureMailObject secureMailObj,
   VtPolicyCtx policyCtx,
   VtStorageCtx storageCtx,
   VtTransportCtx transportCtx,
   VtRandomObject random
   )
{
  int status;
  unsigned int index, elementLen, newLineLen;
  VoltSecureMailObject *obj = (VoltSecureMailObject *)secureMailObj;
  VoltSecureMailWriteCtx *writeCtx = (VoltSecureMailWriteCtx *)(obj->localCtx);
  VoltLibCtx *libCtx = (VoltLibCtx *)(obj->voltObject.libraryCtx);
  VoltPolicyCtx *pCtx;
  VtItem *getItem = (VtItem *)0;
  char *contentType = VOLT_DEFAULT_CONTENT_TYPE;
  VtBase64Info b64Info;
  VOLT_DECLARE_ERROR_TYPE (errorType)
  VOLT_DECLARE_FNCT_LINE (fnctLine)

  do
  {
    /* Create the Base64 object. We couldn't create it until we had the
     * new line issue settled.
     */
    if (obj->base64 != (VtAlgorithmObject)0)
      VtDestroyAlgorithmObject (&(obj->base64));

    b64Info.base64BlockSize = 64;
    b64Info.newLineCharacter = VT_BASE64_NEW_LINE_LF;
    if (writeCtx->itemArray[VOLT_WRITE_SM_ITEM_NEW_LINE].len == 2)
      b64Info.newLineCharacter = VT_BASE64_NEW_LINE_CR_LF;
    b64Info.errorCheck = VT_BASE64_NO_ERROR_CHECK;
    VOLT_SET_ERROR_TYPE (errorType, 0)
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VtCreateAlgorithmObject (
      (VtLibCtx)libCtx, VtAlgorithmImplBase64, (Pointer)&b64Info,
      &(obj->base64));
    if (status != 0)
      break;

    /* Init the subordinate objects.
     */
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VtPkcs7WriteInit (
      obj->p7SignedData, policyCtx, storageCtx, transportCtx, random);
    if (status != 0)
      break;

    VOLT_SET_FNCT_LINE (fnctLine)
    status = VtPkcs7WriteInit (
      obj->p7EnvelopedData, policyCtx, storageCtx, transportCtx, random);
    if (status != 0)
      break;

    VOLT_SET_FNCT_LINE (fnctLine)
    status = VtEncodeInit (obj->base64);
    if (status != 0)
      break;

    /* If there's no content type, use the default.
     */
    if (obj->contentInfo.data == (unsigned char *)0)
    {
      VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VT_ERROR_MEMORY;
      obj->contentInfo.data = (unsigned char *)Z2Malloc (
        VOLT_DEFAULT_CONTENT_TYPE_LEN + 1, 0);
      if (obj->contentInfo.data == (unsigned char *)0)
        break;
      Z2Memcpy (
        obj->contentInfo.data, contentType, VOLT_DEFAULT_CONTENT_TYPE_LEN);
      obj->contentInfo.data[VOLT_DEFAULT_CONTENT_TYPE_LEN] = 0;
      obj->contentInfo.len = VOLT_DEFAULT_CONTENT_TYPE_LEN;
    }

    /* Get elements out of the policy ctx. If there is no policy ctx,
     * we're done.
     */
    if (policyCtx == (VtPolicyCtx)0)
      break;

    pCtx = (VoltPolicyCtx *)policyCtx;

    /* Get any header.
     */
    VOLT_SET_ERROR_TYPE (errorType, 0)
    VOLT_SET_FNCT_LINE (fnctLine)
    index = VOLT_POLICY_GET_SECURE_MAIL_HEADER;
    status = pCtx->PolicyGetInfoAlloc (
      policyCtx, VOLT_POLICY_GET_SECURE_MAIL_HEADER,
      (Pointer)&index, (Pointer *)&getItem);
    if (status != 0)
      break;

    if (getItem != (VtItem *)0)
    {
      if ( (getItem->data != (unsigned char *)0) && (getItem->len != 0) )
      {
        VOLT_SET_FNCT_LINE (fnctLine)
        status = VoltCopyItemDataAlloc (
          obj->voltObject.libraryCtx, 0, 0, getItem,
          &(writeCtx->itemArray[VOLT_WRITE_SM_ITEM_HEADER]));
        if (status != 0)
          break;
      }

      /* Free the getItem data so we can use the variable again.
       */
      pCtx->PolicyGetInfoFree (policyCtx, (Pointer)getItem);
      getItem = (VtItem *)0;
    }

    /* Get any footer.
     */
    // For now, leave this out. The current client does not work the
    // way we want it to, so we'll put this in when we decide how to do
    // everything just the way we want.
//    status = pCtx->PolicyGetInfoAlloc (
//      policyCtx, VOLT_POLICY_GET_CONTENT_FOOTER, (Pointer)0,
//      (Pointer *)&getItem);
//    if (status != 0)
//      break;

    newLineLen = writeCtx->itemArray[VOLT_WRITE_SM_ITEM_NEW_LINE].len;
    if (getItem != (VtItem *)0)
    {
      /* Copy the footer with a new line at the front.
       */
      if ( (getItem->data != (unsigned char *)0) && (getItem->len != 0) )
      {
        VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
        VOLT_SET_FNCT_LINE (fnctLine)
        status = VT_ERROR_MEMORY;
        writeCtx->itemArray[VOLT_WRITE_SM_ITEM_CONTENT_FOOTER].data =
          (unsigned char *)Z2Malloc (
          getItem->len + newLineLen, VOLT_MEMORY_SENSITIVE);
        if (writeCtx->itemArray[VOLT_WRITE_SM_ITEM_CONTENT_FOOTER].data ==
          (unsigned char *)0)
          break;
        Z2Memcpy (
          writeCtx->itemArray[VOLT_WRITE_SM_ITEM_CONTENT_FOOTER].data,
          writeCtx->itemArray[VOLT_WRITE_SM_ITEM_NEW_LINE].data, newLineLen);
        Z2Memcpy (
          writeCtx->itemArray[VOLT_WRITE_SM_ITEM_CONTENT_FOOTER].data +
          newLineLen, getItem->data, getItem->len);
        writeCtx->itemArray[VOLT_WRITE_SM_ITEM_CONTENT_FOOTER].len =
          getItem->len + newLineLen;
        status = 0;
      }
    }

    /* Sum up the preliminary and trailing lengths.
     */
    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)
        elementLen += newLineLen;
      writeCtx->prelimLen += elementLen;
    }

    for (index = VOLT_WRITE_SM_FOOT_INDEX_START;
         index <= VOLT_WRITE_SM_FOOT_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)
        elementLen += newLineLen;
      writeCtx->trailLen += elementLen;
    }

    obj->state = VOLT_SECURE_MAIL_STATE_WRITE_INIT;

  } while (0);

  if (getItem != (VtItem *)0)
    pCtx->PolicyGetInfoFree (policyCtx, (Pointer)getItem);

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

  return (status);
}

int VoltSecureMailWriteUpdate (
   VtSecureMailObject secureMailObj,
   VtRandomObject random,
   unsigned char *inputData,
   unsigned int inputDataLen,
   unsigned char *message,
   unsigned int bufferSize,
   unsigned int *messageLen
   )
{
  int status;
  unsigned int index, offset, elementLen, newLineLen, preliminaryLen;
  unsigned int contentReportLen, signedDataLen, envelopedDataLen, b64Len;
#if VT_64_BIT_LENGTH == 64
  VtUInt64 msgLen;
#else
  unsigned int msgLen;
#endif
  unsigned char *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);
  VtItem *preP7 = &(writeCtx->itemArray[VOLT_WRITE_SM_PRE_PKCS7]);
  VoltEncodeDecodeSizeInfo encodeDecodeSizeInfo;
  VOLT_DECLARE_ERROR_TYPE (errorType)
  VOLT_DECLARE_FNCT_LINE (fnctLine)

  do
  {
    /* How big is the output going to be?
     */
    if (obj->state == VOLT_SECURE_MAIL_STATE_WRITE_INIT)
    {
      /* If the state is INIT, we have not set the lengths of the P7
       * objects yet.
       */
      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've set the lengths of the P7
     * objects, but we still haven't written out any preliminary info.
     * We also need to send to the Sign object the content report.
     * If the state is not INIT_LEN, it must be UPDATE, we can call
     * UPDATE only after Init or another Update call.
     */
    VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VT_ERROR_INVALID_CALL_ORDER;
    preliminaryLen = 0;
    contentReportLen = 0;
    if (obj->state == VOLT_SECURE_MAIL_STATE_WRITE_INIT_LEN)
    {
      preliminaryLen = writeCtx->prelimLen;
      contentReportLen =
        writeCtx->itemArray[VOLT_WRITE_SM_ITEM_CONTENT_REPORT].len;
    }
    else if (obj->state != VOLT_SECURE_MAIL_STATE_WRITE_UPDATE)
    {
      break;
    }

    /* Make sure the inputLen is valid.
     */
    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;

    /* How long will the SignedData be?
     * The variable contentReportLen contains the length of
     * contentReport, unless we've already written it out, in which
     * case, that variable is set to 0.
     */
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VT_ERROR_INVALID_INPUT_LENGTH;
    signedDataLen = inputDataLen + contentReportLen;
    if (signedDataLen < inputDataLen)
      break;

    VOLT_SET_ERROR_TYPE (errorType, 0)
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VtPkcs7WriteUpdate (
      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;

    /* How long will the envelopedData be?
     */
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VtPkcs7WriteUpdate (
      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;
#if VT_64_BIT_LENGTH == 64
    encodeDecodeSizeInfo.dataToProcessLen =
      (VtUInt64)envelopedDataLen + (VtUInt64)(preP7->len);
#else
    encodeDecodeSizeInfo.dataToProcessLen = envelopedDataLen + preP7->len;
    VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VT_ERROR_INVALID_INPUT_LENGTH;
    if (encodeDecodeSizeInfo.dataToProcessLen < envelopedDataLen)
      break;
#endif

    VOLT_SET_ERROR_TYPE (errorType, 0)
    VOLT_SET_FNCT_LINE (fnctLine)
    status = obj->GetEncodeDecodeSize (
      obj->base64, (VtRandomObject)0, VOLT_CALLER_ENCODE_UPDATE,
      &encodeDecodeSizeInfo);
    if (status != VT_ERROR_BUFFER_TOO_SMALL)
      break;

    VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VT_ERROR_INVALID_INPUT_LENGTH;
    msgLen = encodeDecodeSizeInfo.processedDataLen;
#if VT_64_BIT_LENGTH == 64
    msgLen += (VtUInt64)preliminaryLen;
    if (msgLen > (VtUInt64)0xffffffff)
      break;

    *messageLen = (unsigned int)msgLen;
#else
    msgLen += preliminaryLen;
    if (msgLen < preliminaryLen)
      break;

    *messageLen = msgLen;
#endif

    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.
     */

⌨️ 快捷键说明

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