📄 smwrite.c
字号:
VOLT_SET_FNCT_LINE (fnctLine)
if ( (inputData == (unsigned char *)0) && (inputDataLen != 0) )
break;
/* Start writing out the message.
*/
offset = 0;
if (obj->state == VOLT_SECURE_MAIL_STATE_WRITE_INIT_LEN)
{
/* If the state is INIT_LEN, we have not written out the
* preliminaries yet.
*/
newLine = writeCtx->itemArray[VOLT_WRITE_SM_ITEM_NEW_LINE].data;
newLineLen = writeCtx->itemArray[VOLT_WRITE_SM_ITEM_NEW_LINE].len;
for (index = VOLT_WRITE_SM_HEAD_INDEX_START;
index <= VOLT_WRITE_SM_HEAD_INDEX_END; ++index)
{
/* Add in the length of the actual data to write out.
* If there is data to write out, add a newLine.
*/
elementLen = writeCtx->itemArray[index].len;
if (elementLen == 0)
continue;
Z2Memcpy (
message + offset, writeCtx->itemArray[index].data, elementLen);
offset += elementLen;
Z2Memcpy (message + offset, newLine, newLineLen);
offset += newLineLen;
}
/* Now that we've written out the preliminaries, the state can be
* regular UPDATE.
*/
obj->state = VOLT_SECURE_MAIL_STATE_WRITE_UPDATE;
}
/* Allocate a buffer to hold the signed data.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_MEMORY;
sBuffer = (unsigned char *)Z2Malloc (signedDataLen, 0);
if (sBuffer == (unsigned char *)0)
break;
/* Write out the SignedData.
* Use index as a temp variable.
*/
index = 0;
VOLT_SET_ERROR_TYPE (errorType, 0)
if (contentReportLen != 0)
{
/* If we haven't written out the content report, do it now. Get
* the number of bytes written in index.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = VtPkcs7WriteUpdate (
obj->p7SignedData, random,
writeCtx->itemArray[VOLT_WRITE_SM_ITEM_CONTENT_REPORT].data,
contentReportLen, sBuffer, signedDataLen, &index);
if (status != 0)
break;
}
/* If we wrote out something based on contentReport, index is how
* many bytes written. If we did not write out something based on
* contentReport, index is 0.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = VtPkcs7WriteUpdate (
obj->p7SignedData, random, inputData, inputDataLen,
sBuffer + index, signedDataLen - index, &signedDataLen);
if (status != 0)
break;
signedDataLen += index;
/* Allocate a buffer to hold the enveloped data.
*/
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_MEMORY;
eBuffer = (unsigned char *)Z2Malloc (envelopedDataLen, 0);
if (eBuffer == (unsigned char *)0)
break;
/* Envelope the signed data.
*/
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = VtPkcs7WriteUpdate (
obj->p7EnvelopedData, random, sBuffer, signedDataLen,
eBuffer, envelopedDataLen, &envelopedDataLen);
if (status != 0)
break;
/* If there's any preP7 data, encode it. Then Base64 encode the
* enveloped data.
*/
if (preP7->len != 0)
{
VOLT_SET_FNCT_LINE (fnctLine)
status = VtEncodeUpdate (
obj->base64, (VtRandomObject)0, preP7->data, preP7->len,
message + offset, bufferSize - offset, &b64Len);
if (status != 0)
break;
offset += b64Len;
preP7->len = 0;
}
VOLT_SET_FNCT_LINE (fnctLine)
status = VtEncodeUpdate (
obj->base64, (VtRandomObject)0, eBuffer, envelopedDataLen,
message + offset, bufferSize - offset, &b64Len);
if (status != 0)
break;
obj->inputLen += inputDataLen;
obj->state = VOLT_SECURE_MAIL_STATE_WRITE_UPDATE;
} while (0);
if (sBuffer != (unsigned char *)0)
Z2Free (sBuffer);
if (eBuffer != (unsigned char *)0)
Z2Free (eBuffer);
VOLT_LOG_ERROR_INFO_COMPARE (
status, 0, secureMailObj, status, 0, errorType,
(char *)0, "VoltSecureMailWriteUpdate", fnctLine, (char *)0)
return (status);
}
int VoltSecureMailWriteFinal (
VtSecureMailObject secureMailObj,
VtRandomObject random,
unsigned char *inputData,
unsigned int inputDataLen,
unsigned char *message,
unsigned int bufferSize,
unsigned int *messageLen
)
{
int status;
unsigned int inputLen, updateLen, signedDataLen, envelopedDataLen, b64Len;
unsigned int index, offset, totalLen, elementLen, newLineLen;
unsigned char *input, *newLine;
unsigned char *sBuffer = (unsigned char *)0;
unsigned char *eBuffer = (unsigned char *)0;
VoltSecureMailObject *obj = (VoltSecureMailObject *)secureMailObj;
VoltSecureMailWriteCtx *writeCtx = (VoltSecureMailWriteCtx *)(obj->localCtx);
VoltLibCtx *libCtx = (VoltLibCtx *)(obj->voltObject.libraryCtx);
unsigned int footerLen =
writeCtx->itemArray[VOLT_WRITE_SM_ITEM_CONTENT_FOOTER].len;
unsigned char *footer =
writeCtx->itemArray[VOLT_WRITE_SM_ITEM_CONTENT_FOOTER].data;
VtItem *preP7 = &(writeCtx->itemArray[VOLT_WRITE_SM_PRE_PKCS7]);
VoltEncodeDecodeSizeInfo encodeDecodeSizeInfo;
VOLT_DECLARE_ERROR_TYPE (errorType)
VOLT_DECLARE_FNCT_LINE (fnctLine)
do
{
/* If a dataLen is not yet set, the inputLen from this call is that
* value.
*/
#if VT_64_BIT_LENGTH == 64
if (obj->dataLen64 == 0)
obj->dataLen64 = (VtUInt64)inputDataLen;
#else
if (obj->dataLen == 0)
obj->dataLen = inputDataLen;
#endif
input = inputData;
inputLen = inputDataLen;
totalLen = 0;
/* Make sure the total len of input equals the "predicted" len.
*/
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_INVALID_INPUT_LENGTH;
#if VT_64_BIT_LENGTH == 64
if ((obj->inputLen64 + (VtUInt64)inputDataLen) > obj->dataLen64)
#else
if ((obj->inputLen + inputDataLen) > obj->dataLen)
#endif
break;
/* If the state is INIT, get the lengths.
*/
if (obj->state == VOLT_SECURE_MAIL_STATE_WRITE_INIT)
{
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = SetTotalLengths (obj, writeCtx, random);
if (status != 0)
break;
}
/* If the state is INIT_LEN, we're processing the data all at once.
*/
if (obj->state == VOLT_SECURE_MAIL_STATE_WRITE_INIT_LEN)
{
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_INVALID_INPUT_LENGTH;
#if VT_64_BIT_LENGTH == 64
if (writeCtx->base64Len > 0xffffffff)
break;
#endif
/* We know the total length of the output. Is the buffer big
* enough?
*/
totalLen = writeCtx->prelimLen + (unsigned int)(writeCtx->base64Len);
if (totalLen < writeCtx->prelimLen)
break;
totalLen += writeCtx->trailLen;
if (totalLen < writeCtx->trailLen)
break;
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_BUFFER_TOO_SMALL;
*messageLen = totalLen;
if (bufferSize < *messageLen)
break;
/* If the caller passed NULL input with non-zero inputLen, they
* just wanted the length, don't process.
*/
VOLT_SET_FNCT_LINE (fnctLine)
if ( (inputData == (unsigned char *)0) && (inputDataLen != 0) )
break;
/* The buffer is big enough, call Update to write out the
* preliminary data and what data we can process.
*/
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = VoltSecureMailWriteUpdate (
secureMailObj, random, inputData, inputDataLen,
message, bufferSize, &updateLen);
if (status != 0)
break;
message += updateLen;
bufferSize -= updateLen;
input = (unsigned char *)0;
inputLen = 0;
}
if (obj->state == VOLT_SECURE_MAIL_STATE_WRITE_UPDATE)
{
/* We've called Update, we'll need to call all the Finals.
*/
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_INVALID_INPUT_LENGTH;
signedDataLen = inputLen + footerLen;
if (signedDataLen < inputLen)
break;
/* How much space is needed for the last chunk of input.
*/
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = VtPkcs7WriteFinal (
obj->p7SignedData, random, (unsigned char *)0, signedDataLen,
(unsigned char *)0, 0, &signedDataLen);
if (status == 0)
status = VT_ERROR_GENERAL;
if (status != VT_ERROR_BUFFER_TOO_SMALL)
break;
VOLT_SET_FNCT_LINE (fnctLine)
status = VtPkcs7WriteFinal (
obj->p7EnvelopedData, random, (unsigned char *)0, signedDataLen,
(unsigned char *)0, 0, &envelopedDataLen);
if (status == 0)
status = VT_ERROR_GENERAL;
if (status != VT_ERROR_BUFFER_TOO_SMALL)
break;
/* How long will the Base64 be?
*/
encodeDecodeSizeInfo.dataToProcess = (unsigned char *)0;
encodeDecodeSizeInfo.dataToProcessLen = envelopedDataLen;
VOLT_SET_FNCT_LINE (fnctLine)
status = obj->GetEncodeDecodeSize (
obj->base64, (VtRandomObject)0, VOLT_CALLER_ENCODE_FINAL,
&encodeDecodeSizeInfo);
if (status != VT_ERROR_BUFFER_TOO_SMALL)
break;
#if VT_64_BIT_LENGTH == 64
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_INVALID_INPUT_LENGTH;
if (encodeDecodeSizeInfo.processedDataLen > 0xffffffff)
break;
#endif
b64Len = (unsigned int)(encodeDecodeSizeInfo.processedDataLen);
/* We know the total length of the output. Is the buffer big
* enough?
* If totalLen is already set, we've already made the check.
*/
if (totalLen == 0)
{
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_INVALID_INPUT_LENGTH;
*messageLen = b64Len + writeCtx->trailLen;
if (*messageLen < b64Len)
break;
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_BUFFER_TOO_SMALL;
if (bufferSize < *messageLen)
break;
/* If the caller passed NULL input with non-zero inputLen, they
* just wanted the length, don't process.
*/
VOLT_SET_FNCT_LINE (fnctLine)
if ( (inputData == (unsigned char *)0) && (inputDataLen != 0) )
break;
}
}
else
{
/* If we reach this point, the state was not INIT or UPDATE. We
* can call Final only after Init or Update.
*/
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_INVALID_CALL_ORDER;
break;
}
/* Allocate a buffer to hold the signed data.
*/
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_MEMORY;
sBuffer = (unsigned char *)Z2Malloc (signedDataLen, 0);
if (sBuffer == (unsigned char *)0)
break;
/* Write out the SignedData.
*/
updateLen = 0;
VOLT_SET_ERROR_TYPE (errorType, 0)
if (inputLen != 0)
{
VOLT_SET_FNCT_LINE (fnctLine)
status = VtPkcs7WriteUpdate (
obj->p7SignedData, random, input, inputLen,
sBuffer, signedDataLen, &updateLen);
if (status != 0)
break;
}
/* Add the contentFooter. If there's no footer, we still want to
* call Final.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = VtPkcs7WriteFinal (
obj->p7SignedData, random, footer, footerLen,
sBuffer + updateLen, signedDataLen - updateLen, &signedDataLen);
if (status != 0)
break;
signedDataLen += updateLen;
/* Allocate a buffer to hold the enveloped data.
*/
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_MEMORY;
eBuffer = (unsigned char *)Z2Malloc (envelopedDataLen, 0);
if (eBuffer == (unsigned char *)0)
break;
/* Envelope the signed data.
*/
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = VtPkcs7WriteFinal (
obj->p7EnvelopedData, random, sBuffer, signedDataLen,
eBuffer, envelopedDataLen, &envelopedDataLen);
if (status != 0)
break;
/* Write out the Base64 into the app-supplied buffer.
*/
offset = 0;
if (preP7->len != 0)
{
VOLT_SET_FNCT_LINE (fnctLine)
status = VtEncodeFinal (
obj->base64, (VtRandomObject)0, preP7->data, preP7->len,
message, bufferSize, &b64Len);
if (status != 0)
break;
offset = b64Len;
preP7->len = 0;
}
VOLT_SET_FNCT_LINE (fnctLine)
status = VtEncodeFinal (
obj->base64, (VtRandomObject)0, eBuffer, envelopedDataLen,
message + offset, bufferSize - offset, &b64Len);
if (status != 0)
break;
offset += b64Len;
/* Write out any trailing info.
*/
newLine = writeCtx->itemArray[VOLT_WRITE_SM_ITEM_NEW_LINE].data;
newLineLen = writeCtx->itemArray[VOLT_WRITE_SM_ITEM_NEW_LINE].len;
for (index = VOLT_WRITE_SM_FOOT_INDEX_START;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -