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

📄 saread.c

📁 IBE是一种非对称密码技术
💻 C
📖 第 1 页 / 共 5 页
字号:
/* 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 "stringutil.h"
#include "surrender.h"

typedef struct VoltSecureArchiveReadLocalCtx
{
  VtDerCoder**                mCoders;
  unsigned int                mCoderCount;
  VtIdentitySchemaDecode**    mDecoders;
  unsigned int                mDecoderCount;
  VtMpIntCtx                  mMpIntCtx;
  VtBufferTypeInfo            mBufferTypeInfo;
  VtStreamObject              mOutputStream;
  VtStreamObject              mInputStream;
  VtStreamObject              mIndexDataStream;
  VtPkcs7Object               mEnvelopedData;
  VtPkcs7Object               mSignedData;
  VtArchiveObject             mArchive;
  VtCompressObject            mCompress;
  int                         mCurrentEntryType;
  int                         mCurrentEntryIndex;
  VtPkcs7RecipientIndexInfo   mRecipientIndexInfo;
  int                         mRecipientIndexInfoValid;
  int                         mDestroyInputStream;
  VtDataNodeObject            mAttributes;
} VoltSecureArchiveReadLocalCtx;

static void VoltSecureArchiveReadLocalCtxDestroy(Pointer obj, Pointer ctx)
{
  VoltSecureArchiveObject* secureArchiveObj = (VoltSecureArchiveObject*)obj;
  VoltSecureArchiveReadLocalCtx* readCtx;
  VtLibCtx libCtx = (VtLibCtx)0;
  
  if ((obj == (Pointer)0) || (ctx == (Pointer)0))
    return;
  
  readCtx = (VoltSecureArchiveReadLocalCtx*)ctx;
  VT_ASSERT(readCtx != (VoltSecureArchiveReadLocalCtx*)0);
  libCtx = secureArchiveObj->voltObject.libraryCtx;
  VT_ASSERT(libCtx != (VtLibCtx)0);
  
  Z2Free(readCtx->mCoders);
  Z2Free(readCtx->mDecoders);
  VtDestroyMpIntCtx(&readCtx->mMpIntCtx);
  VtDestroyPkcs7Object(&readCtx->mEnvelopedData);
  VtDestroyPkcs7Object(&readCtx->mSignedData);
  VtDestroyArchiveObject(&readCtx->mArchive);
  VtDestroyCompressObject(&readCtx->mCompress);
  VtDestroyDataNodeObject(&readCtx->mAttributes);
  if (readCtx->mDestroyInputStream)
    VtDestroyStreamObject(&readCtx->mInputStream);
  VtDestroyStreamObject(&readCtx->mIndexDataStream);
  VtDestroyStreamObject(&readCtx->mOutputStream);
  
  Z2Free(readCtx);
}

int VoltSecureArchiveArchiveInit(
  VtSecureArchiveObject secureArchiveObj
)
{
  int status = 0;
  VtLibCtx libCtx = (VtLibCtx)0;
  VoltSecureArchiveReadLocalCtx* readCtx;
  VtBufferTypeInfo bufferTypeInfo;
  VOLT_DECLARE_FNCT_LINE(fnctLine)
  VOLT_DECLARE_ERROR_TYPE(errorType)
  
  VT_ASSERT(secureArchiveObj != (VoltSecureArchiveObject*)0);

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

  VOLT_SET_ERROR_TYPE(errorType, 0)
  
  do
  {
    /* Create the archive object if necessary */
    if (readCtx->mArchive == (VtArchiveObject)0)
    {
      if (readCtx->mInputStream == (VtStreamObject)0)
      {
        VOLT_SET_FNCT_LINE(fnctLine)
        VOLT_SET_ERROR_TYPE(errorType, VT_ERROR_TYPE_PRIMARY)
        status = VT_ERROR_INVALID_CALL_ORDER;
        break;
      }
      
      VOLT_SET_FNCT_LINE(fnctLine)
      status = VtCreateArchiveObject(libCtx, VtArchiveImplZipRead,
        (Pointer)0, &readCtx->mArchive);
      if (status != 0)
        break;
      
      /* Set it to use the input stream as its data source */
      bufferTypeInfo.bufferType = VT_BUFFER_TYPE_STREAM;
      bufferTypeInfo.streamObj = readCtx->mInputStream;
      
      VOLT_SET_FNCT_LINE(fnctLine)
      status = VtSetArchiveParam(readCtx->mArchive,
        VtArchiveParamBufferType, (Pointer)&bufferTypeInfo);
      if (status != 0)
        break;
      
      VOLT_SET_FNCT_LINE(fnctLine)
      status = VtArchiveReadInit(readCtx->mArchive);
      if (status != 0)
        break;
    }
  }
  while (0);
  
  VOLT_LOG_ERROR_COMPARE(status, libCtx, status, errorType,
    fnctLine,"VoltSecureArchiveArchiveInit", (unsigned char*)0)
    
  return status;
}

int VoltSecureArchiveDecryptDataInit(
  VtSecureArchiveObject secureArchiveObj
)
{
  int status = 0;
  VtLibCtx libCtx = (VtLibCtx)0;
  VoltSecureArchiveReadLocalCtx* readCtx;
  VtReadPkcs7Info info;
  VoltSurrenderCtx* surrenderCtx;
  VtSurrenderCallback surrenderCallback;
  VOLT_DECLARE_FNCT_LINE(fnctLine)
  
  VT_ASSERT(secureArchiveObj != (VoltSecureArchiveObject*)0);

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

  do
  {
    /* Destroy any existing objects */
    VtDestroyCompressObject(&readCtx->mCompress);
    VtDestroyPkcs7Object(&readCtx->mEnvelopedData);
    VtDestroyPkcs7Object(&readCtx->mSignedData);
    
    /* Create the archive object if necessary */
    VOLT_SET_FNCT_LINE(fnctLine)
    status = VoltSecureArchiveArchiveInit(secureArchiveObj);
    if (status != 0)
      break;

    /* Initialize the associated info for the PKCS7 objects */
    info.decoders = readCtx->mDecoders;
    info.decoderCount = readCtx->mDecoderCount;
    info.derCoders = readCtx->mCoders;
    info.derCoderCount = readCtx->mCoderCount;
    info.mpCtx = readCtx->mMpIntCtx;
    
    /* Create and initialize the PKCS7 enveloped data object */
    VOLT_SET_FNCT_LINE(fnctLine)
    status = VtCreatePkcs7Object(libCtx, VtPkcs7ImplReadEnvelopedData,
      (Pointer)&info, &readCtx->mEnvelopedData);
    if (status != 0)
      break;
    
    VT_ASSERT(readCtx->mEnvelopedData != (VtPkcs7Object)0);

    surrenderCtx = (VoltSurrenderCtx*) secureArchiveObj->voltObject.surrenderCtx;
    
    if (surrenderCtx != (VoltSurrenderCtx*)0)
    {
      surrenderCallback.appData = surrenderCtx->appData;
      surrenderCallback.AppDataCopy = surrenderCtx->AppDataCopy;
      surrenderCallback.AppDataFree = surrenderCtx->AppDataFree;
      surrenderCallback.Surrender = surrenderCtx->Surrender;
      
      VOLT_SET_FNCT_LINE(fnctLine)
      status = VtSetPkcs7Param(readCtx->mEnvelopedData,
        VtPkcs7ParamSurrenderCallback, (Pointer)&surrenderCallback);
      if (status != 0)
        break;
    }
    
    VOLT_SET_FNCT_LINE(fnctLine)
    status = VtPkcs7ReadInit(readCtx->mEnvelopedData);
    if (status != 0)
      break;
      
    /* Create and initialize the PKCS7 signed data object */
    VOLT_SET_FNCT_LINE(fnctLine)
    status = VtCreatePkcs7Object(libCtx, VtPkcs7ImplReadSignedData,
      (Pointer)&info, &readCtx->mSignedData);
    if (status != 0)
      break;
    
    VT_ASSERT(readCtx->mSignedData != (VtPkcs7Object)0);

    if (surrenderCtx != (VoltSurrenderCtx*)0)
    {
      VOLT_SET_FNCT_LINE(fnctLine)
      status = VtSetPkcs7Param(readCtx->mSignedData,
        VtPkcs7ParamSurrenderCallback, (Pointer)&surrenderCallback);
      if (status != 0)
        break;
    }
    
    VOLT_SET_FNCT_LINE(fnctLine)
    status = VtPkcs7ReadInit(readCtx->mSignedData);
    if (status != 0)
      break;
  }
  while (0);
  
  VOLT_LOG_ERROR_COMPARE(status, libCtx, status, 0,
    fnctLine,"VoltSecureArchiveDecryptDataInit", (unsigned char*)0)
    
  return status;
}
 
static int VoltSecureArchiveDecryptData(
  VtSecureArchiveObject secureArchiveObj,
  VtStreamObject outputStream,
  int* final
)
{
  int status = 0;
  VtLibCtx libCtx = (VtLibCtx)0;
  unsigned char* envelopedDataBuffer = (unsigned char*)0;
  unsigned int envelopedDataBufferSize = 4096;
  unsigned int envelopedDataSize;
  unsigned char* signedDataBuffer = (unsigned char*)0;
  unsigned int signedDataBufferSize = 0;
  unsigned int signedDataSize;
  unsigned char* dataBuffer = (unsigned char*)0;
  unsigned int dataBufferSize = 0;
  unsigned int dataSize;
  unsigned int readSize;
  unsigned char* buffer;
  unsigned int bufferSize;
  VoltSecureArchiveReadLocalCtx* readCtx;
  VOLT_DECLARE_FNCT_LINE(fnctLine)
  VOLT_DECLARE_ERROR_TYPE(errorType)
  
  VT_ASSERT(secureArchiveObj != (VoltSecureArchiveObject*)0);
  VT_ASSERT(outputStream != (VtStreamObject)0);
  
  VOLT_SET_ERROR_TYPE(errorType, 0)
  
  libCtx = secureArchiveObj->voltObject.libraryCtx;
  VT_ASSERT(libCtx != (VtLibCtx)0);
  readCtx = (VoltSecureArchiveReadLocalCtx*) secureArchiveObj->localCtx;
  VT_ASSERT(readCtx != (VoltSecureArchiveReadLocalCtx*)0);

  do
  {
    *final = 0;
    
    envelopedDataBuffer = (unsigned char*) Z3Malloc(envelopedDataBufferSize);
    if (envelopedDataBuffer == (unsigned char*)0)
    {
      VOLT_SET_ERROR_TYPE(errorType, VT_ERROR_TYPE_PRIMARY)
      VOLT_SET_FNCT_LINE(fnctLine)
      status = VT_ERROR_MEMORY;
      break;
    }
    
    do
    {
      /* Read the data from the archive */
      VOLT_SET_FNCT_LINE(fnctLine)
      status = VtArchiveReadUpdate(readCtx->mArchive, (unsigned char*)0, 0,
        envelopedDataBuffer, envelopedDataBufferSize, &envelopedDataSize);
      if (status == VT_ERROR_END_OF_STREAM)
        status = 0;
      if (status != 0)
        break;
      
      /* If we read less than we requested, then that means we're at
       * the end of the current entry, so we should use the final calls
       * for the PKCS7 objects instead of the update calls.
       */
      if (envelopedDataSize < envelopedDataBufferSize)
        *final = 1;
        
      buffer = envelopedDataBuffer;
      bufferSize = envelopedDataSize;
      
      /* First figure out how big the signed data is going to be
       * after we decrypt, so we know how big the buffer needs to be.
       * This call may consume some of the input data, so we need to
       * check the readSize parameters and adjust the input buffer
       * when we call it again with the output buffer.
       */
      if (*final)
      {
        VOLT_SET_FNCT_LINE(fnctLine)
        status = VtPkcs7ReadFinal(readCtx->mEnvelopedData, buffer,
          bufferSize, &readSize, signedDataBuffer, signedDataBufferSize,
          &signedDataSize);
      }
      else
      {
        VOLT_SET_FNCT_LINE(fnctLine)
        status = VtPkcs7ReadUpdate(readCtx->mEnvelopedData, buffer,
          bufferSize, &readSize, signedDataBuffer, signedDataBufferSize,
          &signedDataSize);
      }
      
      /* After the PKCS7 object has parsed the RecipientInfo's, it
       * needs to be told which recipient to use to decrypt, so if
       * it returns this error, we either use the recipient index
       * info that's already been set or propagate the error to the
       * caller, so they can choose the recipient.
       */
      if (status == VT_ERROR_CHOOSE_RECIPIENT)
      {
        if (!readCtx->mRecipientIndexInfoValid)
          break;
        
        VOLT_SET_FNCT_LINE(fnctLine)
        status = VtSetPkcs7Param(readCtx->mEnvelopedData,
          VtPkcs7ParamRecipientIndex,
          (Pointer)&readCtx->mRecipientIndexInfo);
        if (status != 0)
          break;
        
        buffer += readSize;
        bufferSize -= readSize;
      
        /* Call the PKCS7 object again now that it has a recipient
         * to use and can continue.
         */
        if (*final)
        {
          VOLT_SET_FNCT_LINE(fnctLine)
          status = VtPkcs7ReadFinal(readCtx->mEnvelopedData, buffer,
            bufferSize, &readSize, signedDataBuffer, signedDataBufferSize,
            &signedDataSize);
        }
        else
        {
          VOLT_SET_FNCT_LINE(fnctLine)
          status = VtPkcs7ReadUpdate(readCtx->mEnvelopedData, buffer,
            bufferSize, &readSize, signedDataBuffer, signedDataBufferSize,
            &signedDataSize);
        }
        
        VT_ASSERT(status != VT_ERROR_CHOOSE_RECIPIENT);
      }
      
      if (status == VT_ERROR_BUFFER_TOO_SMALL)
      {
        VT_ASSERT(signedDataSize > signedDataBufferSize);
        
        /* Reallocate the signed data buffer. */
        Z2Free(signedDataBuffer);
        signedDataBuffer = (unsigned char*) Z3Malloc(signedDataSize);
        if (signedDataBuffer == (unsigned char*)0)
        {
          VOLT_SET_ERROR_TYPE(errorType, VT_ERROR_TYPE_PRIMARY)
          VOLT_SET_FNCT_LINE(fnctLine)
          status = VT_ERROR_MEMORY;
          break;
        }
        signedDataBufferSize = signedDataSize;
        
        buffer += readSize;
        bufferSize -= readSize;
        
        /* Now call it again with the resized buffer */
        if (*final)
        {
          VOLT_SET_FNCT_LINE(fnctLine)
          status = VtPkcs7ReadFinal(readCtx->mEnvelopedData, buffer,
            bufferSize, &readSize, signedDataBuffer, signedDataBufferSize,
            &signedDataSize);
        }
        else
        {
          VOLT_SET_FNCT_LINE(fnctLine)
          status = VtPkcs7ReadUpdate(readCtx->mEnvelopedData, buffer,
            bufferSize, &readSize, signedDataBuffer, signedDataBufferSize,
            &signedDataSize);
        }
      }
      
      if (status != 0)
        break;
      
      VT_ASSERT(readSize == bufferSize);
      
      buffer = signedDataBuffer;
      bufferSize = signedDataSize;
      
      /* Now we've got the signed data, so we need to run it through 
       * the signed data PKCS7 to determine the signer and extract
       * the original data.
       */

⌨️ 快捷键说明

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