📄 saread.c
字号:
/* 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 + -