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

📄 zdm2read.c

📁 IBE是一种非对称密码技术
💻 C
📖 第 1 页 / 共 3 页
字号:
/* Copyright 2003-2006, Voltage Security, all rights reserved.
 */
 
#include "vibe.h"
#include "environment.h"
#include "base.h"
#include "libctx.h"
#include "securearchive.h"
#include "errorctx.h"
#include "vtassert.h"
#include "datanode.h"
#include "compress.h"
#include "archive.h"
#include "sacommon.h"
#include "zdm2common.h"
#include "stringutil.h"
#include "securemail.h"
#include "zdm.h"

typedef struct VoltZDM2ReadLocalCtx {
  VtSecureArchiveObject       mSecureArchive;
  VtBufferTypeInfo            mBufferTypeInfo;
  unsigned int                mMessageFormat;
  VtZDMEmailRecipientList     mPrimaryRecipientList;
  VtZDMEmailRecipientList     mCCRecipientList;
  int                         mCurrentEntryType;
  VtDataNodeObject            mInsecureAttributes;
  VtStreamObject              mInputStream;
  unsigned char               mOwnsInputStream;
  unsigned char               mReadInitCalled;
  unsigned char               mMessageUnwrapped;
  unsigned char               mEmailRecipientsInited;
  unsigned char               mSecureArchiveInited;
} VoltZDM2ReadLocalCtx;

static void VoltZDM2ReadLocalCtxDestroy(Pointer obj, Pointer ctx)
{
  VtZDMObject zdmObj = (VtZDMObject)obj;
  VoltZDM2ReadLocalCtx* readCtx;
  VtLibCtx libCtx = (VtLibCtx)0;
  
  if ((obj == (Pointer)0) || (ctx == (Pointer)0))
    return;
  
  readCtx = (VoltZDM2ReadLocalCtx*)ctx;
  VT_ASSERT(readCtx != (VoltZDM2ReadLocalCtx*)0);
  libCtx = zdmObj->voltObject.libraryCtx;
  VT_ASSERT(libCtx != (VtLibCtx)0);
  
  VtDestroySecureArchiveObject(&readCtx->mSecureArchive);
  VtDestroyDataNodeObject(&readCtx->mInsecureAttributes);
  if (readCtx->mOwnsInputStream)
    VtDestroyStreamObject(&readCtx->mInputStream);
  Z2Free(readCtx->mPrimaryRecipientList.emailList);
  Z2Free(readCtx->mCCRecipientList.emailList);
  
  Z2Free(readCtx);
}

static int VoltZDM2InitEmailRecipients(
  VtZDMObject zdmObj
)
{
  int status = 0;
  VtLibCtx libCtx = (VtLibCtx)0;
  VoltZDM2ReadLocalCtx* readCtx;
  VtDataNodeObject attributesNode;
  VtDataNodeObject recipientsNode;
  VtDataNodeObject recipientNode;
  VtDataNodeObject node;
  const unsigned char* recipientAddress;
  long recipientFlags;
  int recipientCount;
  int i;
  VOLT_DECLARE_FNCT_LINE(fnctLine)
  VOLT_DECLARE_ERROR_TYPE(errorType)
  
  VT_ASSERT(zdmObj != (VtZDMObject)0);

  libCtx = zdmObj->voltObject.libraryCtx;
  VT_ASSERT(libCtx != (VtLibCtx)0);
  readCtx = (VoltZDM2ReadLocalCtx*) zdmObj->localCtx;
  VT_ASSERT(readCtx != (VoltZDM2ReadLocalCtx*)0);
  VT_ASSERT(readCtx->mSecureArchive != (VtSecureArchiveObject)0);
  
  VOLT_SET_ERROR_TYPE(errorType, 0)
  
  do
  {
    if (readCtx->mEmailRecipientsInited)
      break;
      
    /* Access the attributes node maintained by the secure archive.
     * This is sort of a hack and we could get around it by getting
     * all the information through the public attribute API, but it
     * would be inconvenient.
     */
    VOLT_SET_FNCT_LINE(fnctLine)
    status = VtGetSecureArchiveParam(readCtx->mSecureArchive,
      VtSecureArchiveParamAttributesNode, (Pointer*)&attributesNode);
    if (status != 0)
      break;
    
    VOLT_SET_FNCT_LINE(fnctLine)
    status = VtDataNodeResolveChild(attributesNode,
      VoltZDM2RecipientsAttributeName, 0, &recipientsNode);
    if (status != 0)
      break;
    
    /* Figure out how many total recipients there are. This count will
     * include both primary and CC recipients. We use this total to
     * allocate the email address array for both the primary and CC
     * recipients even though we probably won't fill them up, but it's
     * not that wasteful and it avoid having to make a preliminary pass
     * over the recipients to determine the counts.
     */
    VOLT_SET_FNCT_LINE(fnctLine)
    status = VtDataNodeGetChildCount(recipientsNode, &recipientCount);
    if (status != 0)
      break;
    
    readCtx->mPrimaryRecipientList.emailList = (const unsigned char**)
      Z3Malloc(recipientCount * sizeof(unsigned char*));
    readCtx->mCCRecipientList.emailList = (const unsigned char**)
      Z3Malloc(recipientCount * sizeof(unsigned char*));
    if ((readCtx->mPrimaryRecipientList.emailList == (const unsigned char**)0) ||
        (readCtx->mCCRecipientList.emailList == (const unsigned char**)0))
    {
      VOLT_SET_ERROR_TYPE(errorType, VT_ERROR_TYPE_PRIMARY)
      VOLT_SET_FNCT_LINE(fnctLine)
      status = VT_ERROR_MEMORY;
      break;
    }
    
    /* Loop over the recipients, extracting the recipient email
     * address and flags.
     */
    for (i = 0; i < recipientCount; i++)
    {
      VOLT_SET_FNCT_LINE(fnctLine)
      status = VtDataNodeGetChild(recipientsNode, i, &recipientNode);
      if (status != 0)
        break;
      
      VOLT_SET_FNCT_LINE(fnctLine)
      status = VtDataNodeLookupChild(recipientNode,
        VoltZDM2AddressAttributeName, &node);
      if (status != 0)
        break;
      
      VOLT_SET_FNCT_LINE(fnctLine)
      status = VtDataNodeGetStringValue(node, &recipientAddress);
      if (status != 0)
        break;
        
      VOLT_SET_FNCT_LINE(fnctLine)
      status = VtDataNodeLookupChild(recipientNode,
        VoltZDM2FlagsAttributeName, &node);
      if (status != 0)
        break;
      
      VOLT_SET_FNCT_LINE(fnctLine)
      status = VtDataNodeGetIntegerValue(node, &recipientFlags);
      if (status != 0)
        break;
      
      /* If the primary recipient flag is set then add it to the
       * primary recipient list.
       */
      if ((recipientFlags & VOLT_ZDM_RECIPIENT_FLAGS_PRIMARY) != 0)
      {
        readCtx->mPrimaryRecipientList.emailList[
          readCtx->mPrimaryRecipientList.count++] = recipientAddress;
      }
      
      /* If the CC recipient flag is set then add it to the
       * CC recipient list.
       */
      if ((recipientFlags & VOLT_ZDM_RECIPIENT_FLAGS_CC) != 0)
      {
        readCtx->mCCRecipientList.emailList[
          readCtx->mCCRecipientList.count++] = recipientAddress;
      }
    }
    
    readCtx->mEmailRecipientsInited = 1;
  }
  while (0);
  
  VOLT_LOG_ERROR_COMPARE(status, libCtx, status, errorType,
    fnctLine,"VoltZDM2InitEmailRecipients", (unsigned char*)0)
    
  return status;
}

static int VoltZDM2InitInsecureAttributes(
  VtZDMObject zdmObj
)
{
  int status = 0;
  VtLibCtx libCtx = (VtLibCtx)0;
  VoltZDM2ReadLocalCtx* readCtx;
  VtSecureArchiveCurrentEntryInfo currentEntryInfo;
  unsigned char buffer[1000];
  unsigned int size;
  VtStreamSize streamSize;
  unsigned char* attributesXML = (unsigned char*)0;
  VtStreamObject attributesStream = (VtStreamObject)0;
  VtStreamImplMemoryInfo memoryInfo;
  VOLT_DECLARE_FNCT_LINE(fnctLine)
  VOLT_DECLARE_ERROR_TYPE(errorType)
  
  VT_ASSERT(zdmObj != (VtZDMObject)0);

  libCtx = zdmObj->voltObject.libraryCtx;
  VT_ASSERT(libCtx != (VtLibCtx)0);
  readCtx = (VoltZDM2ReadLocalCtx*) zdmObj->localCtx;
  VT_ASSERT(readCtx != (VoltZDM2ReadLocalCtx*)0);
  VT_ASSERT(readCtx->mSecureArchive != (VtSecureArchiveObject)0);
  
  VOLT_SET_ERROR_TYPE(errorType, 0)
  
  do
  {
    if (readCtx->mInsecureAttributes != (VtDataNodeObject)0)
      break;
      
    /* Create a stream to hold the contents of the insecure
     * attributes entry. Since we're going to access the buffer
     * directly below to pass to the data node call, the stream
     * needs to be a memory-based stream, so we always create the
     * stream using the VtStreamImplMemory instead of using the
     * buffer type specified by the user. The insecure attributes
     * entry will typically be pretty small, so there shouldn't be
     * much of a memory overhead from using the memory-based stream.
     */
    VOLT_SET_FNCT_LINE(fnctLine)
    Z2Memset(&memoryInfo, 0, sizeof(memoryInfo));
    memoryInfo.flags = VT_STREAM_OPEN_ON_ACCESS;
    memoryInfo.openMode = VT_STREAM_OPEN_READ_WRITE;
    status = VtCreateStreamObject(libCtx, VtStreamImplMemory,
      (Pointer)&memoryInfo, &attributesStream);
    if (status != 0)
      break;
    
    /* Set the current entry in the secure archive */
    currentEntryInfo.type = VT_SECURE_ARCHIVE_CURRENT_ENTRY_INSECURE;
    currentEntryInfo.name = VoltZDM2InsecureAttributesFilePathName;
    
    VOLT_SET_FNCT_LINE(fnctLine)
    status = VtSetSecureArchiveParam(readCtx->mSecureArchive,
      VtSecureArchiveParamCurrentEntry, (Pointer)&currentEntryInfo);
    if (status != 0)
      break;
    
    /* Copy over the contents to the stream */
    for (;;)
    {
      VOLT_SET_FNCT_LINE(fnctLine)
      status = VtSecureArchiveReadUpdate(readCtx->mSecureArchive,
        (unsigned char*)0, 0, (unsigned int*)0, buffer,
        sizeof(buffer), &size);
      if ((status != 0) || (size == 0))
      {
        if (status == VT_ERROR_END_OF_STREAM)
          status = 0;
        break;
      }
      
      VOLT_SET_FNCT_LINE(fnctLine)
      status = VtStreamWrite(attributesStream, buffer, size);
      if (status != 0)
        break;
    }
    
    if (status != 0)
      break;
    
    /* Add a null-terminator, so we can use the memory buffer
     * as a C string to pass to the data node call.
     */
    VOLT_SET_FNCT_LINE(fnctLine)
    status = VtStreamWrite(attributesStream, "", 1);
    if (status != 0)
      break;
    
    /* Get a pointer to the stream's underlying buffer. This buffer
     * is still owned by the stream, so we don't need to delete it
     */
    VOLT_SET_FNCT_LINE(fnctLine)
    status = VtStreamGetBuffer(attributesStream, &attributesXML, &streamSize);
    if (status != 0)
      break;
    
    VOLT_SET_FNCT_LINE(fnctLine)
    status = VtCreateDataNodeObjectFromXML(libCtx, attributesXML,
      &readCtx->mInsecureAttributes);
    if (status != 0)
      break;
  }
  while (0);
  
  VtDestroyStreamObject(&attributesStream);
  
  VOLT_LOG_ERROR_COMPARE(status, libCtx, status, errorType,
    fnctLine,"VoltZDM2InitInsecureAttributes", (unsigned char*)0)
    
  return status;
}

static int VoltZDM2UnwrapMessage(
  VtZDMObject zdmObj
)
{
  int status = 0;
  VtLibCtx libCtx = (VtLibCtx)0;
  VoltZDM2ReadLocalCtx* readCtx;
  const unsigned int messageBufferSize = 4096;
  unsigned char* messageBuffer = (unsigned char*)0;
  unsigned char* dataBuffer = (unsigned char*)0;
  unsigned int dataBufferSize = 0;
  unsigned int dataSize;
  VtAlgorithmObject base64Decoder = (VtAlgorithmObject)0;
  VtStreamSize dataLength;
  int copyDataLength = 0;
  unsigned char* copySrc;
  int foundStartTag = 0;
  int foundEndTag = 0;
  int maxStartTagLength;
  unsigned char* startData = 0;
  unsigned char* endData;
  unsigned int bytesConsumed;
  unsigned int startTagVersion;
  unsigned int tagStartOffset;
  unsigned int tagEndOffset;
  const char* startInputFieldValue = "value=\"";
  int startInputFieldLength;
  int inInputFieldTag = 0;
  unsigned char* p;
  VOLT_DECLARE_FNCT_LINE(fnctLine)
  VOLT_DECLARE_ERROR_TYPE(errorType)
  
  VT_ASSERT(zdmObj != (VtZDMObject)0);

  libCtx = zdmObj->voltObject.libraryCtx;
  VT_ASSERT(libCtx != (VtLibCtx)0);
  readCtx = (VoltZDM2ReadLocalCtx*) zdmObj->localCtx;
  VT_ASSERT(readCtx != (VoltZDM2ReadLocalCtx*)0);

  VOLT_SET_ERROR_TYPE(errorType, 0)
  
  do
  {
    if (readCtx->mMessageUnwrapped)
      break;
    
    startInputFieldLength = Z2Strlen(startInputFieldValue);
    maxStartTagLength = Z2Strlen(VoltZDM2SecureBlockStartTagPrefix) +
      Z2Strlen(VoltZDM2SecureBlockStartTagPrefix) +
      VOLT_ZDM2_MAX_VERSION_NUMBER_LENGTH;
    
    messageBuffer = (unsigned char*) Z3Malloc(messageBufferSize);
    if (messageBuffer == (unsigned char*)0)
    {
      VOLT_SET_FNCT_LINE(fnctLine)
      VOLT_SET_ERROR_TYPE(errorType, VT_ERROR_TYPE_PRIMARY)
      status = VT_ERROR_MEMORY;
      break;
    }
    
    do
    {
      VOLT_SET_FNCT_LINE(fnctLine)
      status = VtStreamRead(readCtx->mInputStream,
        messageBuffer + copyDataLength,
        messageBufferSize - copyDataLength, &dataLength);
      if (status != 0)
      {
        status = VT_ERROR_INVALID_ZDM_MSG;
        break;
      }
      
      startData = (unsigned char*)0;
      endData = (unsigned char*)0;
      
      dataLength += copyDataLength;
      
      //messageBuffer[dataLength] = 0;
      
      if (foundStartTag)
      {
        startData = messageBuffer;
      }
      else
      {
        foundStartTag = VoltZDM2FindMessageTag(libCtx,
          VoltZDM2SecureBlockStartTagPrefix,
          VoltZDM2SecureBlockStartTagSuffix, messageBuffer,
          dataLength, 2, VOLT_ZDM2_CURRENT_VERSION, &startTagVersion,
          &tagStartOffset, &tagEndOffset);
        if (foundStartTag)
        {
          startData = messageBuffer + tagEndOffset;
        }
      }
      
      if (foundStartTag)
      {
        copyDataLength = startInputFieldLength;
        endData = 0;
        p = startData;
        
        while ((p < messageBuffer + dataLength) && !foundEndTag)
        {
          if (inInputFieldTag)
          {
            if ((p + startInputFieldLength < messageBuffer + dataLength) &&
              (VoltCaseInsensitiveCompareBuffers(p, startInputFieldLength,
              startInputFieldValue, startInputFieldLength, libCtx) == 0))
            {
              p += startInputFieldLength;
              startData = p;
              inInputFieldTag = 0;
            }
            else
            {
              p++;
            }
          }
          else if (*p == '"')
          {
            endData = p++;
            inInputFieldTag = 1;
          }
          else if (*p == VoltZDM2SecureBlockEndTagPrefix[0])
          {
            endData = p;
            foundEndTag = 1;
          }
          else
          {
            p++;
            if (p == messageBuffer + dataLength)
              endData = p - copyDataLength;
          }

          if (endData > startData)
          {
            if (base64Decoder == (VtAlgorithmObject)0)
            {
              VOLT_SET_FNCT_LINE(fnctLine)
              status = VtCreateAlgorithmObject(libCtx, VtAlgorithmImplBase64,
                (Pointer)0, &base64Decoder);
              if (status != 0)
                break;
              
              VOLT_SET_FNCT_LINE(fnctLine)
              status = VtDecodeInit(base64Decoder);
              if (status != 0)
              break;
            }
            
            if (foundEndTag)
            {
              status = VtDecodeFinal(base64Decoder, (VtRandomObject)0,
                startData, endData - startData, dataBuffer,
                dataBufferSize, &dataSize);
            }
            else
            {
              status = VtDecodeUpdate(base64Decoder, (VtRandomObject)0,
                startData, endData - startData, dataBuffer,
                dataBufferSize, &dataSize);
            }
            
            if (status == VT_ERROR_BUFFER_TOO_SMALL)
            {
              Z2Free(dataBuffer);
              dataBuffer = (unsigned char*) Z3Malloc(dataSize);
              if (dataBuffer == (unsigned char*)0)
              {
                VOLT_SET_FNCT_LINE(fnctLine)
                VOLT_SET_ERROR_TYPE(errorType, VT_ERROR_TYPE_PRIMARY)
                status = VT_ERROR_MEMORY;
                break;
              }
              dataBufferSize = dataSize;

              if (foundEndTag)
              {
                VOLT_SET_FNCT_LINE(fnctLine)
                status = VtDecodeFinal(base64Decoder, (VtRandomObject)0,
                  startData, endData - startData, dataBuffer,
                  dataBufferSize, &dataSize);
              }
              else

⌨️ 快捷键说明

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