📄 smgenread.c
字号:
/* Copyright 2005-2006, Voltage Security, all rights reserved.
*/
#include "vibe.h"
#include "environment.h"
#include "base.h"
#include "libctx.h"
#include "securemail.h"
#include "errorctx.h"
#include "vtassert.h"
#include "stringutil.h"
static VtSecureMailImpl* VoltSecureMailImplList[] = {
VtSecureMailImplRead,
VtSecureMail2ImplRead
};
int VoltGetTargetObjectForGenericSecureMailReader(
VtSecureMailObject secureMailObj,
VtSecureMailObject* target
)
{
int status = 0;
VoltSecureMailGenericReadCtx* readCtx = (VoltSecureMailGenericReadCtx*)0;
VtLibCtx libCtx = (VtLibCtx)0;
unsigned int i;
VtSecureMailObject sm;
VOLT_DECLARE_FNCT_LINE(fnctLine)
VT_ASSERT(secureMailObj != (VtSecureMailObject)0);
VT_ASSERT(target != (VtSecureMailObject*)0);
*target = (VtSecureMailObject)0;
readCtx = (VoltSecureMailGenericReadCtx*)secureMailObj->localCtx;
VT_ASSERT(readCtx != (VoltSecureMailGenericReadCtx*)0);
VT_ASSERT(readCtx->implList != (VoltSecureMailGenericImplInfo*)0);
libCtx = secureMailObj->voltObject.libraryCtx;
VT_ASSERT(libCtx != (VtLibCtx)0);
do
{
for (i = 0; i < readCtx->implCount; i++)
{
sm = readCtx->implList[i].secureMailObj;
if (sm != (VtSecureMailObject)0)
{
if (*target != (VtSecureMailObject)0)
{
VOLT_SET_FNCT_LINE(fnctLine)
status = VT_ERROR_INVALID_CALL_ORDER;
break;
}
*target = sm;
}
}
if (status != 0)
break;
if (*target == (VtSecureMailObject)0)
{
VOLT_SET_FNCT_LINE(fnctLine)
status = VT_ERROR_INVALID_SECURE_MAIL_MSG;
break;
}
}
while (0);
VOLT_LOG_ERROR_COMPARE(status, libCtx, status, 0, fnctLine,
"VoltGetTargetObjectForGenericSecureMailReader", (unsigned char*)0)
return status;
}
static int VoltSecureMailGenericReadInit (
VtSecureMailObject secureMailObj
)
{
int status = 0;
VoltSecureMailGenericReadCtx* readCtx = (VoltSecureMailGenericReadCtx*)0;
VtLibCtx libCtx = (VtLibCtx)0;
VtSecureMailObject sm;
unsigned int i;
int implStatus;
int succeeded = 0;
VOLT_DECLARE_FNCT_LINE(fnctLine)
VOLT_DECLARE_ERROR_TYPE(errorType)
VT_ASSERT(secureMailObj != (VtSecureMailObject)0);
readCtx = (VoltSecureMailGenericReadCtx*)secureMailObj->localCtx;
VT_ASSERT(readCtx != (VoltSecureMailGenericReadCtx*)0);
libCtx = secureMailObj->voltObject.libraryCtx;
VT_ASSERT(libCtx != (VtLibCtx)0);
do
{
/* The state must be VOLT_SECURE_MAIL_STATE_READ_SET, if not,
* we're not allowed to call ReadInit.
*/
if (secureMailObj->state != VOLT_SECURE_MAIL_STATE_READ_SET)
{
VOLT_SET_ERROR_TYPE(errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE(fnctLine)
status = VT_ERROR_INVALID_CALL_ORDER;
break;
}
VOLT_SET_ERROR_TYPE(errorType, 0)
for (i = 0; i < readCtx->implCount; i++)
{
sm = readCtx->implList[i].secureMailObj;
if (sm != (VtSecureMailObject)0)
{
VOLT_SET_FNCT_LINE(fnctLine)
implStatus = VtSecureMailReadInit(sm);
if (implStatus == 0)
{
/* Keep track of the fact that least one of the
* implementations is still valid.
*/
succeeded = 1;
}
else
{
/* If the Init call failed for this object, then just
* delete the object. We remember the last error code
* returned in case all of the Init calls fail.
*/
VtDestroySecureMailObject(&readCtx->implList[i].secureMailObj);
}
}
}
if (!succeeded)
{
VOLT_SET_FNCT_LINE(fnctLine)
VOLT_SET_ERROR_TYPE(errorType, VT_ERROR_TYPE_PRIMARY)
status = VT_ERROR_INVALID_SECURE_MAIL_OBJ;
}
secureMailObj->state = VOLT_SECURE_MAIL_STATE_READ_INIT;
}
while (0);
VOLT_LOG_ERROR_COMPARE(status, libCtx, status, errorType,
fnctLine, "VoltSecureMailGenericReadInit", (unsigned char*)0)
return status;
}
static int VoltIsNotFatalError(int status)
{
return (status == VT_ERROR_BUFFER_TOO_SMALL) ||
(status == VT_ERROR_CHOOSE_RECIPIENT) ||
(status == VT_ERROR_ASYNC_DOWNLOAD) ||
(status == VT_ERROR_DOWNLOAD_PENDING) ||
(status == VT_ERROR_DOWNLOAD_PREVIOUS);
}
static int VoltSecureMailGenericReadUpdate(
VtSecureMailObject secureMailObj,
unsigned char *message,
unsigned int messageLen,
unsigned int *bytesRead,
unsigned char *outputData,
unsigned int bufferSize,
unsigned int *outputDataLen
)
{
int status = 0;
VoltSecureMailGenericReadCtx* readCtx = (VoltSecureMailGenericReadCtx*)0;
VtLibCtx libCtx = (VtLibCtx)0;
VtSecureMailObject targetImpl = (VtSecureMailObject)0;
VoltSecureMailGenericImplInfo* implInfo;
int implStatus;
unsigned char* implMessage;
unsigned int implMessageLength;
unsigned int implBytesRead;
unsigned int implOutputDataLen;
unsigned char* mergedMessage = (unsigned char*)0;
int succeeded = 0;
unsigned int i;
VOLT_DECLARE_FNCT_LINE(fnctLine)
VOLT_DECLARE_ERROR_TYPE(errorType)
VOLT_SET_ERROR_TYPE(errorType, 0)
VT_ASSERT(secureMailObj != (VtSecureMailObject)0);
readCtx = (VoltSecureMailGenericReadCtx*)secureMailObj->localCtx;
VT_ASSERT(readCtx != (VoltSecureMailGenericReadCtx*)0);
libCtx = secureMailObj->voltObject.libraryCtx;
VT_ASSERT(libCtx != (VtLibCtx)0);
*bytesRead = messageLen;
*outputDataLen = 0;
do
{
/* There may be multiple valid impls remaining, so we iterate over the
* impls and forward the update call to each of them. Since we can only
* return a single bytesRead and outputDataLen value, we must make sure
* there are no conflicts in the way the impls want to set these values.
* For bytesRead we just buffer any unread input so that the generic
* read impl always returns a bytesRead equal to messageLen.
* For outputDataLen, there should only be one impl that gets to the
* point where it starts to generate output, so there shouldn't be a
* conflict (and if there is, then it's an error).
*/
for (i = 0; i < readCtx->implCount; i++)
{
implInfo = &readCtx->implList[i];
if (implInfo->secureMailObj != (VtSecureMailObject)0)
{
if (implInfo->bufferedMessageLength > 0)
{
VT_ASSERT(implInfo->bufferedMessage != (unsigned char*)0);
VT_ASSERT(mergedMessage == (unsigned char*)0);
implMessageLength = implInfo->bufferedMessageLength + messageLen;
mergedMessage = Z3Malloc(implMessageLength);
if (mergedMessage == (unsigned char*)0)
{
VOLT_SET_FNCT_LINE(fnctLine)
VOLT_SET_ERROR_TYPE(errorType, VT_ERROR_TYPE_PRIMARY)
status = VT_ERROR_MEMORY;
break;
}
Z2Memcpy(mergedMessage, implInfo->bufferedMessage, implInfo->bufferedMessageLength);
Z2Memcpy(mergedMessage + implInfo->bufferedMessageLength, message, messageLen);
Z2Free(implInfo->bufferedMessage);
implInfo->bufferedMessage = (unsigned char*)0;
implInfo->bufferedMessageLength = 0;
implMessage = mergedMessage;
}
else
{
implMessage = message;
implMessageLength = messageLen;
}
VOLT_SET_FNCT_LINE(fnctLine)
implStatus = VtSecureMailReadUpdate(implInfo->secureMailObj,
implMessage, implMessageLength, &implBytesRead, outputData,
bufferSize, &implOutputDataLen);
if ((implStatus == 0) || VoltIsNotFatalError(implStatus))
{
if (implOutputDataLen > 0)
{
/* There should only be one impl that generates output. The
* other impls should fail before they get to the point where
* they're decrypting the ciphertext.
*/
if (*outputDataLen > 0)
{
VOLT_SET_FNCT_LINE(fnctLine)
VOLT_SET_ERROR_TYPE(errorType, VT_ERROR_TYPE_PRIMARY)
status = VT_ERROR_INVALID_SECURE_MAIL_MSG;
break;
}
*outputDataLen = implOutputDataLen;
}
if (implBytesRead < implMessageLength)
{
VT_ASSERT(implInfo->bufferedMessage == (unsigned char*)0);
VT_ASSERT(implInfo->bufferedMessageLength == 0);
implInfo->bufferedMessage = Z3Malloc(implMessageLength - implBytesRead);
if (implInfo->bufferedMessage == (unsigned char*)0)
{
VOLT_SET_FNCT_LINE(fnctLine)
VOLT_SET_ERROR_TYPE(errorType, VT_ERROR_TYPE_PRIMARY)
status = VT_ERROR_MEMORY;
break;
}
implInfo->bufferedMessageLength = implMessageLength - implBytesRead;
Z2Memcpy(implInfo->bufferedMessage, implMessage + implBytesRead,
implInfo->bufferedMessageLength);
}
succeeded = 1;
status = implStatus;
}
else
{
/* If the Update call failed, then just delete the object. */
VtDestroySecureMailObject(&readCtx->implList[i].secureMailObj);
}
Z2Free(mergedMessage);
mergedMessage = (unsigned char*)0;
}
}
}
while (0);
if (!succeeded)
{
VOLT_SET_FNCT_LINE(fnctLine)
VOLT_SET_ERROR_TYPE(errorType, VT_ERROR_TYPE_PRIMARY)
status = VT_ERROR_INVALID_SECURE_MAIL_MSG;
}
Z2Free(mergedMessage);
VOLT_LOG_ERROR_COMPARE(status, libCtx, status, errorType,
fnctLine, "VoltSecureMailGenericReadUpdate", (unsigned char*)0)
return status;
}
static int VoltSecureMailGenericReadFinal (
VtSecureMailObject secureMailObj,
unsigned char *message,
unsigned int messageLen,
unsigned int *bytesRead,
unsigned char *outputData,
unsigned int bufferSize,
unsigned int *outputDataLen
)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -