📄 sfread.c
字号:
/* Copyright 2003-2006, Voltage Security, all rights reserved.
*/
#include "vibe.h"
#include "environment.h"
#include "base.h"
#include "libctx.h"
#include "securemail.h"
#include "derhelp.h"
#include "errorctx.h"
int VoltSecureFileReadInit (
VtSecureMailObject secureMailObj
)
{
int status;
VoltSecureMailObject *obj = (VoltSecureMailObject *)secureMailObj;
VOLT_DECLARE_ERROR_TYPE (errorType)
VOLT_DECLARE_FNCT_LINE (fnctLine)
do
{
/* The state must be VOLT_SECURE_MAIL_STATE_READ_SET, if not,
* we're not allowed to call ReadInit.
*/
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_INVALID_CALL_ORDER;
if (obj->state != VOLT_SECURE_MAIL_STATE_READ_SET)
break;
/* Init the subordinate objects.
*/
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = VtPkcs7ReadInit (obj->p7SignedData);
if (status != 0)
break;
VOLT_SET_FNCT_LINE (fnctLine)
status = VtPkcs7ReadInit (obj->p7EnvelopedData);
if (status != 0)
break;
obj->state = VOLT_SECURE_FILE_STATE_READ_INIT;
} while (0);
VOLT_LOG_ERROR_INFO_COMPARE (
status, 0, secureMailObj, status, 0, errorType,
(char *)0, "VoltSecureFileReadInit", fnctLine, (char *)0)
return (status);
}
int VoltSecureFileReadUpdate (
VtSecureMailObject secureMailObj,
unsigned char *message,
unsigned int messageLen,
unsigned int *bytesRead,
unsigned char *outputData,
unsigned int bufferSize,
unsigned int *outputDataLen
)
{
int status;
unsigned int currentMessageLen, newLineLen, amountRead, outputLen;
unsigned int completeFlag;
VoltSecureMailObject *obj = (VoltSecureMailObject *)secureMailObj;
VoltLibCtx *libCtx = (VoltLibCtx *)(obj->voltObject.libraryCtx);
VoltSecureMailReadCtx *readCtx = (VoltSecureMailReadCtx *)(obj->localCtx);
unsigned char *currentMessage;
unsigned char *beginMsg = VOLT_SECURE_FILE_BEGIN_MSG;
VOLT_DECLARE_ERROR_TYPE (errorType)
VOLT_DECLARE_FNCT_LINE (fnctLine)
*bytesRead = 0;
*outputDataLen = 0;
currentMessage = message;
currentMessageLen = messageLen;
switch (obj->state)
{
default:
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_INVALID_CALL_ORDER;
break;
case VOLT_SECURE_FILE_STATE_READ_ENV_FINAL:
case VOLT_SECURE_FILE_STATE_READ_SIGN_FINAL:
case VOLT_SECURE_FILE_STATE_READ_COMPLETE:
/* If we're done, don't read anything.
*/
status = 0;
break;
case VOLT_SECURE_FILE_STATE_READ_INIT:
/* The first thing to do will be to read the header.
*/
obj->state = VOLT_SECURE_FILE_STATE_READ_HEADER;
case VOLT_SECURE_FILE_STATE_READ_HEADER:
/* We're just starting to read the message. The first thing up
* might be
* version: 1
*/
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = VoltSMGetNextBlock (
obj, &(readCtx->unprocessedData), currentMessage, currentMessageLen,
1, &amountRead, &completeFlag, &newLineLen);
if (status != 0)
break;
*bytesRead += amountRead;
if (completeFlag == 0)
break;
currentMessage = message + *bytesRead;
currentMessageLen = messageLen - *bytesRead;
/* We have the next block in the unprocessedData buffer, is this
* the version block? If not, it's P7 message, read it. If it is,
* skip it.
*/
if (readCtx->unprocessedData.data[0] != 'v')
{
VOLT_SET_FNCT_LINE (fnctLine)
status = VtPkcs7ReadUpdate (
obj->p7EnvelopedData, readCtx->unprocessedData.data,
readCtx->unprocessedData.len, &amountRead,
readCtx->unprocessedData.data, readCtx->unprocessedData.size,
&outputLen);
readCtx->unprocessedData.len -= amountRead;
if (status != 0)
break;
goto VoltSecureMailReadEnvelope;
}
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_INVALID_SECURE_FILE_MSG;
if (readCtx->unprocessedData.len !=
VOLT_SECURE_FILE_BEGIN_MSG_LEN + newLineLen)
break;
if (Z2Memcmp (
readCtx->unprocessedData.data, beginMsg,
VOLT_SECURE_FILE_BEGIN_MSG_LEN) != 0)
break;
/* Set up the context for the next block.
*/
status = 0;
readCtx->unprocessedData.len = 0;
obj->state = VOLT_SECURE_FILE_STATE_READ_NEW_LINE;
/* If there's no more message to read, return.
*/
if (currentMessageLen == 0)
break;
case VOLT_SECURE_FILE_STATE_READ_NEW_LINE:
/* We expect to see a new line here.
*/
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = VoltSMGetNextBlock (
obj, &(readCtx->unprocessedData), currentMessage, currentMessageLen,
1, &amountRead, &completeFlag, &newLineLen);
if (status != 0)
break;
*bytesRead += amountRead;
if (completeFlag == 0)
break;
currentMessage = message + *bytesRead;
currentMessageLen = messageLen - *bytesRead;
/* Make sure we have a valid new line.
*/
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_INVALID_SECURE_FILE_MSG;
if (readCtx->unprocessedData.len != newLineLen)
break;
/* Set up the context for the next block.
*/
status = 0;
readCtx->unprocessedData.len = 0;
obj->state = VOLT_SECURE_FILE_STATE_READ_ENVELOPE;
/* If there's no more message to read, return.
*/
if (currentMessageLen == 0)
break;
VoltSecureMailReadEnvelope:
case VOLT_SECURE_FILE_STATE_READ_ENVELOPE:
/* At this point we have data to pass to the P7 Envelope object.
* Place any output into the unprocessedData buffer.
*/
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = VtPkcs7ReadUpdate (
obj->p7EnvelopedData, currentMessage, currentMessageLen, &amountRead,
readCtx->unprocessedData.data, readCtx->unprocessedData.size,
&outputLen);
currentMessage += amountRead;
currentMessageLen -= amountRead;
*bytesRead += amountRead;
if (status == VT_ERROR_BUFFER_TOO_SMALL)
{
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_MEMORY;
readCtx->unprocessedData.data = (unsigned char *)Z2Realloc (
readCtx->unprocessedData.data, outputLen);
if (readCtx->unprocessedData.data == (unsigned char *)0)
break;
readCtx->unprocessedData.size = outputLen;
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = VtPkcs7ReadUpdate (
obj->p7EnvelopedData, currentMessage, currentMessageLen, &amountRead,
readCtx->unprocessedData.data, readCtx->unprocessedData.size,
&outputLen);
currentMessage += amountRead;
currentMessageLen -= amountRead;
*bytesRead += amountRead;
}
/* If there'a any error other than BUFFER, pass it on.
*/
if (status != 0)
break;
/* There's no error, either there's no data in the
* unprocessedData buffer (no data to pass on to SignedData) in
* which case we're done, or the data we have we need to give to
* the SignedData P7 object.
*/
if (outputLen == 0)
break;
readCtx->unprocessedData.len = outputLen;
obj->state = VOLT_SECURE_FILE_STATE_READ_SIGNED;
case VOLT_SECURE_FILE_STATE_READ_SIGNED:
/* At this point we have data to pass to the P7 SignedData object.
* Place any output into the app-supplied buffer.
* Return any error, including BUFFER_TOO_SMALL.
*/
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = VoltSMDoSignedDataRead (
obj, readCtx, 1, outputData, bufferSize, outputDataLen);
if (status != 0)
break;
/* If we have no error, we read all the data., the next call will
* need to be to ENVELOPE.
*/
obj->state = VOLT_SECURE_FILE_STATE_READ_ENVELOPE;
/* If there's no more message to read, return.
*/
if (currentMessageLen == 0)
break;
goto VoltSecureMailReadEnvelope;
}
VOLT_LOG_ERROR_INFO_COMPARE (
status, 0, secureMailObj, status, 0, errorType,
(char *)0, "VoltSecureFileReadUpdate", fnctLine, (char *)0)
return (status);
}
int VoltSecureFileReadFinal (
VtSecureMailObject secureMailObj,
unsigned char *message,
unsigned int messageLen,
unsigned int *bytesRead,
unsigned char *outputData,
unsigned int bufferSize,
unsigned int *outputDataLen
)
{
int status;
unsigned int amountRead, outputLen;
VoltSecureMailObject *obj = (VoltSecureMailObject *)secureMailObj;
VoltSecureMailReadCtx *readCtx = (VoltSecureMailReadCtx *)(obj->localCtx);
VOLT_DECLARE_ERROR_TYPE (errorType)
VOLT_DECLARE_FNCT_LINE (fnctLine)
*bytesRead = 0;
*outputDataLen = 0;
switch (obj->state)
{
default:
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_INVALID_CALL_ORDER;
break;
case VOLT_SECURE_FILE_STATE_READ_COMPLETE:
status = 0;
break;
case VOLT_SECURE_FILE_STATE_READ_INIT:
case VOLT_SECURE_FILE_STATE_READ_HEADER:
case VOLT_SECURE_FILE_STATE_READ_NEW_LINE:
case VOLT_SECURE_FILE_STATE_READ_ENVELOPE:
case VOLT_SECURE_FILE_STATE_READ_SIGNED:
/* Call Update on the last amount of data.
*/
if ( ((message != (unsigned char *)0) && (messageLen != 0)) ||
(readCtx->unprocessedData.len != 0) )
{
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = VoltSecureFileReadUpdate (
secureMailObj, message, messageLen, bytesRead,
outputData, bufferSize, outputDataLen);
if (status != 0)
break;
}
/* At this point, we should have had all the input data, so we
* can call the P7 Final functions.
*/
obj->state = VOLT_SECURE_FILE_STATE_READ_ENV_FINAL;
case VOLT_SECURE_FILE_STATE_READ_ENV_FINAL:
/* There should be no output. So if the error is
* BUFFER_TOO_SMALL, convert it to INVALID_INPUT.
*/
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = VtPkcs7ReadFinal (
obj->p7EnvelopedData, (unsigned char *)0, 0, &amountRead,
(unsigned char *)0, 0, &outputLen);
if (status == VT_ERROR_BUFFER_TOO_SMALL)
status = VT_ERROR_INVALID_INPUT;
if (status != 0)
break;
obj->state = VOLT_SECURE_FILE_STATE_READ_SIGN_FINAL;
case VOLT_SECURE_FILE_STATE_READ_SIGN_FINAL:
/* There should be no output. So if the error is
* BUFFER_TOO_SMALL, convert it to INVALID_INPUT.
*/
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = VtPkcs7ReadFinal (
obj->p7SignedData, (unsigned char *)0, 0, &amountRead,
(unsigned char *)0, 0, &outputLen);
if (status == VT_ERROR_BUFFER_TOO_SMALL)
status = VT_ERROR_INVALID_INPUT;
if (status != 0)
break;
obj->state = VOLT_SECURE_FILE_STATE_READ_COMPLETE;
}
VOLT_LOG_ERROR_INFO_COMPARE (
status, 0, secureMailObj, status, 0, errorType,
(char *)0, "VoltSecureFileReadFinal", fnctLine, (char *)0)
return (status);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -