📄 smread.c
字号:
/* Set the state to indicate that we're done reading the message.
* Next up, do Envelope ReadFinal.
*/
VoltSecureMailStateReadEnvFinal:
status = 0;
readCtx->unprocessedData.len = 0;
obj->state = VOLT_SECURE_MAIL_STATE_READ_ENV_FINAL;
if (currentMessageLen != 0)
goto VoltSecureMailStateReadComplete;
}
VOLT_LOG_ERROR_INFO_COMPARE (
status, 0, secureMailObj, status, 0, errorType,
(char *)0, "VoltSecureMailReadUpdate", fnctLine, (char *)0)
return (status);
}
int VoltSecureMailReadFinal (
VtSecureMailObject secureMailObj,
unsigned char *message,
unsigned int messageLen,
unsigned int *bytesRead,
unsigned char *outputData,
unsigned int bufferSize,
unsigned int *outputDataLen
)
{
int status;
unsigned int outputSign;
VoltSecureMailObject *obj = (VoltSecureMailObject *)secureMailObj;
VoltSecureMailReadCtx *readCtx = (VoltSecureMailReadCtx *)(obj->localCtx);
VOLT_DECLARE_ERROR_TYPE (errorType)
VOLT_DECLARE_FNCT_LINE (fnctLine)
*bytesRead = 0;
*outputDataLen = 0;
/* We're in ReadFinal, set the readFinal field to 1 so anyone we call
* can know we're really inside ReadFinal
*/
readCtx->readFinal = 1;
switch (obj->state)
{
case VOLT_SECURE_MAIL_STATE_READ_COMPLETE:
status = 0;
break;
default:
/* This is SecureMailReadFinal, so this should be the last of the
* message to read.
* The return can be CHOOSE, BUFFER_TOO_SMALL, success or another
* error. If CHOOSE, pass that on to the caller. If BUFFER, pass
* it on to the caller, because any output from this call to
* Update should go to the caller-supplied buffer, and there
* should be no more output after this. Any other error pass on
* to the caller.
*/
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = VoltSecureMailReadUpdate (
secureMailObj, message, messageLen, bytesRead,
outputData, bufferSize, outputDataLen);
if (status != 0)
break;
/* At this point, because we're in ReadFinal, the state should be
* ENV_FINAL.
*/
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_INVALID_INPUT_LENGTH;
if (obj->state != VOLT_SECURE_MAIL_STATE_READ_ENV_FINAL)
break;
case VOLT_SECURE_MAIL_STATE_READ_ENV_FINAL:
/* Call EnvelopeFinal.
*/
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = DoEnvelopeRead (obj, readCtx, 0);
if (status != 0)
break;
case VOLT_SECURE_MAIL_STATE_READ_SIGN_FINAL:
/* There should be no output from this call, so the error should
* not be BUFFER.
*/
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = VoltSMDoSignedDataRead (
obj, readCtx, 0, (unsigned char *)0, 0, &outputSign);
if (status != 0)
break;
case VOLT_SECURE_MAIL_STATE_READ_P7_FINAL:
obj->state = VOLT_SECURE_MAIL_STATE_READ_COMPLETE;
}
/* Reset the readFinal flag to 0, we're no longer in ReadFinal. This
* is so we don't have to set the field in every other routine.
*/
readCtx->readFinal = 0;
VOLT_LOG_ERROR_INFO_COMPARE (
status, 0, secureMailObj, status, 0, errorType,
(char *)0, "VoltSecureMailReadFinal", fnctLine, (char *)0)
return (status);
}
int VoltSecureMailVerify (
VtSecureMailObject secureMailObj,
VtPolicyCtx policyCtx,
VtStorageCtx storageCtx,
VtTransportCtx transportCtx,
VtCertVerifyCtx certVerifyCtx,
Pointer verifyCtxInfo,
VtVerifyFailureList vfyFailList,
unsigned int *verifyResult
)
{
int status;
VoltSecureMailObject *obj = (VoltSecureMailObject *)secureMailObj;
VOLT_DECLARE_FNCT_LINE (fnctLine)
VOLT_SET_FNCT_LINE (fnctLine)
status = VtPkcs7VerifyAll (
obj->p7SignedData, policyCtx, storageCtx, transportCtx,
certVerifyCtx, verifyCtxInfo, vfyFailList, verifyResult);
VOLT_LOG_ERROR_INFO_COMPARE (
status, 0, secureMailObj, status, 0, 0,
(char *)0, "VoltSecureMailVerify", fnctLine, (char *)0)
return (status);
}
static int DoDecodeUpdateOrFinal (
VoltSecureMailObject *obj,
VoltSecureMailReadCtx *readCtx,
unsigned int flag,
unsigned char *dataToDecode,
unsigned int dataToDecodeLen
)
{
int status;
unsigned int outputLen;
VoltLibCtx *libCtx = (VoltLibCtx *)(obj->voltObject.libraryCtx);
VOLT_DECLARE_ERROR_TYPE (errorType)
VOLT_DECLARE_FNCT_LINE (fnctLine)
do
{
VOLT_SET_ERROR_TYPE (errorType, 0)
if (flag != 0)
{
VOLT_SET_FNCT_LINE (fnctLine)
status = VtDecodeUpdate (
obj->base64, (VtRandomObject)0, dataToDecode, dataToDecodeLen,
readCtx->unprocessedData.data, readCtx->unprocessedData.size,
&outputLen);
}
else
{
VOLT_SET_FNCT_LINE (fnctLine)
status = VtDecodeFinal (
obj->base64, (VtRandomObject)0, dataToDecode, dataToDecodeLen,
readCtx->unprocessedData.data, readCtx->unprocessedData.size,
&outputLen);
}
/* If successful, just make sure unprocessedData.len is correct and
* we're done.
*/
if (status == 0)
{
/* If there's any data in the unprocessedData buffer, set the state
* to READ_ENV. We'll want to read the data in the buffer as
* EnvelopedData.
*/
if (outputLen != 0)
obj->state = VOLT_SECURE_MAIL_STATE_READ_ENV;
readCtx->unprocessedData.len = outputLen;
break;
}
/* Any error other than BUFFER_TOO_SMALL, return.
*/
if (status != VT_ERROR_BUFFER_TOO_SMALL)
break;
/* Expand the unprocessedData buffer.
*/
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);
readCtx->unprocessedData.size = 0;
if (readCtx->unprocessedData.data == (unsigned char *)0)
break;
readCtx->unprocessedData.size = outputLen;
/* Call again with the expanded buffer.
*/
VOLT_SET_ERROR_TYPE (errorType, 0)
if (flag != 0)
{
VOLT_SET_FNCT_LINE (fnctLine)
status = VtDecodeUpdate (
obj->base64, (VtRandomObject)0, dataToDecode, dataToDecodeLen,
readCtx->unprocessedData.data, readCtx->unprocessedData.size,
&(readCtx->unprocessedData.len));
}
else
{
VOLT_SET_FNCT_LINE (fnctLine)
status = VtDecodeFinal (
obj->base64, (VtRandomObject)0, dataToDecode, dataToDecodeLen,
readCtx->unprocessedData.data, readCtx->unprocessedData.size,
&(readCtx->unprocessedData.len));
}
/* If successful, we have some data in the unprocessedData buffer
* that needs to be read as EnvelopedData.
*/
if (status == 0)
obj->state = VOLT_SECURE_MAIL_STATE_READ_ENV;
} while (0);
VOLT_LOG_ERROR_INFO_COMPARE (
status, 0, obj, status, 0, errorType,
(char *)0, "DoDecodeUpdateOrFinal", fnctLine, (char *)0)
return (status);
}
static int DoEnvelopeRead (
VoltSecureMailObject *obj,
VoltSecureMailReadCtx *readCtx,
unsigned int flag
)
{
int status;
unsigned int envRead, outputLen;
VoltLibCtx *libCtx = (VoltLibCtx *)(obj->voltObject.libraryCtx);
unsigned char *eBuffer = (unsigned char *)0;
VOLT_DECLARE_ERROR_TYPE (errorType)
VOLT_DECLARE_FNCT_LINE (fnctLine)
do
{
VOLT_SET_ERROR_TYPE (errorType, 0)
if (flag == 0)
{
/* If we're calling EnvelopeFinal, we know there is no more data
* to process and there should be no more data to output.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = VtPkcs7ReadFinal (
obj->p7EnvelopedData, (unsigned char *)0, 0, &envRead,
(unsigned char *)0, 0, &outputLen);
if (status != 0)
status = VT_ERROR_INVALID_SECURE_MAIL_MSG;
obj->state = VOLT_SECURE_MAIL_STATE_READ_SIGN_FINAL;
break;
}
VOLT_SET_FNCT_LINE (fnctLine)
status = VtPkcs7ReadUpdate (
obj->p7EnvelopedData, readCtx->unprocessedData.data,
readCtx->unprocessedData.len, &envRead,
(unsigned char *)0, 0, &outputLen);
/* Move the unprocessedData if necessary.
*/
if (envRead != 0)
{
if (envRead != readCtx->unprocessedData.len)
{
Z2Memmove (
readCtx->unprocessedData.data,
readCtx->unprocessedData.data + envRead,
readCtx->unprocessedData.len - envRead);
}
readCtx->unprocessedData.len -= envRead;
}
/* If we're doing Update and status is 0, all the data was read,
* there was no output, we need to set the state to READ_B64.
* If status is CHOOSE, just pass it along to the caller, the state
* stays READ_ENV because we still have some data to read.
* Any error other than BUFFER_TOO_SMALL, pass on.
*/
if (status == 0)
obj->state = VOLT_SECURE_MAIL_STATE_READ_B64;
if (status != VT_ERROR_BUFFER_TOO_SMALL)
break;
/* Allocate space to hold the output.
*/
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_MEMORY;
eBuffer = (unsigned char *)Z2Malloc (outputLen, VOLT_MEMORY_SENSITIVE);
if (eBuffer == (unsigned char *)0)
break;
/* Call again with the output buffer.
*/
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = VtPkcs7ReadUpdate (
obj->p7EnvelopedData, readCtx->unprocessedData.data,
readCtx->unprocessedData.len, &envRead,
eBuffer, outputLen, &outputLen);
if (status != 0)
break;
/* Copy this data into the unprocessedData buffer.
*/
readCtx->unprocessedData.len = 0;
VOLT_SET_FNCT_LINE (fnctLine)
status = StoreUnprocessedData (
obj, &(readCtx->unprocessedData), eBuffer, outputLen);
if (status != 0)
break;
/* If we're doing Update, set the state to indicate that we need to
* read the data in the unprocessedData buffer as SignedData.
*/
obj->state = VOLT_SECURE_MAIL_STATE_READ_SIGNED;
} while (0);
if (eBuffer != (unsigned char *)0)
Z2Free (eBuffer);
VOLT_LOG_ERROR_INFO_COMPARE (
status, 0, obj, status, 0, errorType,
(char *)0, "DoEnvelopeRead", fnctLine, (char *)0)
return (status);
}
int VoltSMDoSignedDataRead (
VoltSecureMailObject *obj,
VoltSecureMailReadCtx *readCtx,
unsigned int flag,
unsigned char *output,
unsigned int outputSize,
unsigned int *outputLen
)
{
int status;
unsigned int signRead, completeFlag, p7OutputLen, retFlag;
VoltLibCtx *libCtx = (VoltLibCtx *)(obj->voltObject.libraryCtx);
VoltContentMaterial *newElement = (VoltContentMaterial *)0;
VoltContentMaterial *currentElement, *nextElement;
unsigned int newLineLen;
VOLT_DECLARE_ERROR_TYPE (errorType)
VOLT_DECLARE_FNCT_LINE (fnctLine)
/* If retFlag is 0, don't return after part 1. If it is 1, return
* after part 1, error or no error.
*/
retFlag = 0;
do
{
VOLT_SET_ERROR_TYPE (errorType, 0)
if (flag == 0)
{
/* If we're calling SignedDataFinal, we know there is no more data
* to process and there should be no more data to output.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = VtPkcs7ReadFinal (
obj->p7SignedData, (unsigned char *)0, 0, &signRead,
(unsigned char *)0, 0, &p7OutputLen);
if (status != 0)
status = VT_ERROR_INVALID_SECURE_MAIL_MSG;
obj->state = VOLT_SECURE_MAIL_STATE_READ_P7_FINAL;
retFlag = 1;
break;
}
/* We're going to do a ReadUpdate. Based on the contentMaterialState,
* we're either going to read data but output nothing (prefix stuff),
* read data, process it, but not output it to the app's buffer
* (content descriptors), or read data and output any result to the
* app's buffer (data after the content descriptors).
*/
signRead = 0;
switch (readCtx->contentMaterialState)
{
case VOLT_CONTENT_MATERIAL_STATE_COMPLETE:
default:
VOLT_SET_FNCT_LINE (fnctLine)
status = VtPkcs7ReadUpdate (
obj->p7SignedData, readCtx->unprocessedData.data,
readCtx->unprocessedData.len, &signRead,
output, outputSize, outputLen);
/* Move the unprocessedData if necessary.
*/
if (signRead != 0)
{
if (signRead != readCtx->unprocessedData.len)
{
Z2Memmove (
readCtx->unprocessedData.data,
readCtx->unprocessedData.data + signRead,
readCtx->unprocessedData.len - signRead);
}
readCtx->unprocessedData.len -= signRead;
}
/* If Update and successful, set the state to indicate we're ready
* to read Base64 data again.
*/
retFlag = 1;
if (status == 0)
obj->state = VOLT_SECURE_MAIL_STATE_READ_B64;
break;
case VOLT_CONTENT_MATERIAL_STATE_NONE:
/* Read data with NULL output. If the return is 0, there was no
* output, so the function read everything and there's nothing
* more to do. If there is an error other than BUFFER, pass it on.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = VtPkcs7ReadUpdate (
obj->p7SignedData, readCtx->unprocessedData.data,
readCtx->unprocessedData.len, &signRead,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -