📄 sm2read.c
字号:
/* The headers start with a MIME-style label called
* "ZDMv2Headers:", so we need to skip past that label to
* reach the actual XML data.
*/
labelLength = Z2Strlen(VoltSecureArchiveHeadersName);
VT_ASSERT(labelLength < sizeof(label));
Z2Memcpy(label, VoltSecureArchiveHeadersName, labelLength);
label[labelLength] = ':';
labelLength++;
if (VoltCaseInsensitiveCompareBuffers(p, labelLength,
label, labelLength, libCtx) != 0)
{
VOLT_SET_FNCT_LINE(fnctLine)
VOLT_SET_ERROR_TYPE(errorType, VT_ERROR_TYPE_PRIMARY)
status = VT_ERROR_ARCHIVE_READ;
break;
}
p += labelLength;
VOLT_SET_FNCT_LINE(fnctLine)
status = VtCreateDataNodeObjectFromXML(libCtx, p, &attributesNode);
if (status != 0)
break;
/* Obtain the content type attribute */
VOLT_SET_FNCT_LINE(fnctLine)
status = VtDataNodeLookupChild(attributesNode,
VoltZDM2ContentTypeAttributeName, &node);
if (status == 0)
{
VOLT_SET_FNCT_LINE(fnctLine)
status = VtDataNodeGetStringValue(node, &str);
if (status != 0)
break;
VOLT_SET_FNCT_LINE(fnctLine)
status = Z2Strdup(str, &readCtx->contentType);
if (status != 0)
break;
}
/* Obtain the character set attribute */
VOLT_SET_FNCT_LINE(fnctLine)
status = VtDataNodeLookupChild(attributesNode,
VoltZDM2CharacterSetAttributeName, &node);
if (status == 0)
{
VOLT_SET_FNCT_LINE(fnctLine)
status = VtDataNodeGetStringValue(node, &str);
if (status != 0)
break;
VOLT_SET_FNCT_LINE(fnctLine)
status = Z2Strdup(str, &readCtx->characterSet);
if (status != 0)
break;
}
/* Obtain the original character set attribute */
VOLT_SET_FNCT_LINE(fnctLine)
status = VtDataNodeLookupChild(attributesNode,
VoltZDM2OriginalCharacterSetAttributeName, &node);
if (status == 0)
{
VOLT_SET_FNCT_LINE(fnctLine)
status = VtDataNodeGetStringValue(node, &str);
if (status != 0)
break;
VOLT_SET_FNCT_LINE(fnctLine)
status = Z2Strdup(str, &readCtx->originalCharacterSet);
if (status != 0)
break;
}
status = 0;
}
while (0);
VtDestroyDataNodeObject(&attributesNode);
VOLT_LOG_ERROR_COMPARE(status, libCtx, status, errorType,
fnctLine, "VoltSecureMail2ProcessHeaders", (unsigned char*)0)
return status;
}
static int VoltSecureMail2ParseHeaders(
VtSecureMailObject secureMailObj,
unsigned char* input,
unsigned int inputLength,
unsigned int* inputRead
)
{
int status = 0;
VoltSecureMail2ReadCtx* readCtx = (VoltSecureMail2ReadCtx*)0;
VtLibCtx libCtx = (VtLibCtx)0;
unsigned char* p;
unsigned char* end;
unsigned char c;
unsigned int eolCount = 0;
VOLT_DECLARE_FNCT_LINE(fnctLine)
VOLT_DECLARE_ERROR_TYPE(errorType)
VOLT_SET_ERROR_TYPE(errorType, 0)
VT_ASSERT(secureMailObj != (VtSecureMailObject)0);
readCtx = (VoltSecureMail2ReadCtx*)secureMailObj->localCtx;
VT_ASSERT(readCtx != (VoltSecureMail2ReadCtx*)0);
libCtx = secureMailObj->voltObject.libraryCtx;
VT_ASSERT(libCtx != (VtLibCtx)0);
do
{
p = input;
end = input + inputLength;
while (p < end)
{
c = *p++;
if ((c == '\r') || (c == '\n'))
{
/* Check for CRLF line endings, so we only treat it as 1 EOL */
if ((c == '\r') && (p < end) && (*p == '\n'))
p++;
eolCount++;
if (eolCount == 2)
{
p[-1] = 0;
VOLT_SET_FNCT_LINE(fnctLine)
status = VoltSecureMail2ProcessHeaders(secureMailObj, input);
if (status != 0)
break;
*inputRead = p - input;
readCtx->processedHeaders = 1;
break;
}
}
else
{
eolCount = 0;
}
}
}
while (0);
VOLT_LOG_ERROR_COMPARE(status, libCtx, status, errorType,
fnctLine, "VoltSecureMail2ParseHeaders", (unsigned char*)0)
return status;
}
static int VoltSecureMail2ReadBody(
VtSecureMailObject secureMailObj,
unsigned char *input,
unsigned int inputLength,
unsigned int* inputRead,
unsigned char* output,
unsigned int outputBufferSize,
unsigned int* outputLength
)
{
int status = 0;
VoltSecureMail2ReadCtx* readCtx = (VoltSecureMail2ReadCtx*)0;
VtLibCtx libCtx = (VtLibCtx)0;
unsigned char* p;
unsigned char* end;
int final = 0;
unsigned int decodedLength;
unsigned char* envelopedData = (unsigned char*)0;
unsigned char* signedData = (unsigned char*)0;
unsigned char* data = (unsigned char*)0;
unsigned int envelopedDataLength;
unsigned int signedDataLength;
unsigned int dataLength;
unsigned int newDataLength;
unsigned int dataRead, dataRead2, dataWritten;
VoltEncodeDecodeSizeInfo encodeDecodeSizeInfo;
VOLT_DECLARE_FNCT_LINE(fnctLine)
VOLT_DECLARE_ERROR_TYPE(errorType)
VOLT_SET_ERROR_TYPE(errorType, 0)
VT_ASSERT(secureMailObj != (VtSecureMailObject)0);
readCtx = (VoltSecureMail2ReadCtx*)secureMailObj->localCtx;
VT_ASSERT(readCtx != (VoltSecureMail2ReadCtx*)0);
libCtx = secureMailObj->voltObject.libraryCtx;
VT_ASSERT(libCtx != (VtLibCtx)0);
do
{
*outputLength = 0;
/* Find the end of the base64-encoded data. We look for the
* first character of the secure block end tag, which must
* be an invalid base 64 character (or else it would be
* interpreted as data.
*/
p = input;
end = input + inputLength;
while (p < end)
{
if (*p == VoltZDM2SecureBlockEndTagPrefix[0])
{
final = 1;
break;
}
p++;
}
/* We're going to consume all the input (or else hit an
* error we can't recover from, so we can set the inputRead param
*/
*inputRead = p - input;
decodedLength = 0;
if (final)
{
if (!readCtx->decodedFinal)
{
encodeDecodeSizeInfo.dataToProcess = input;
#if VT_64_BIT_LENGTH == 64
encodeDecodeSizeInfo.dataToProcessLen = (VtUInt64)(p - input);
#else
encodeDecodeSizeInfo.dataToProcessLen = (unsigned int)(p - input);
#endif
VOLT_SET_FNCT_LINE(fnctLine)
status = VoltBase64GetEncodeDecodeSize (
secureMailObj->base64, (VtRandomObject)0, VOLT_CALLER_DECODE_FINAL,
&encodeDecodeSizeInfo);
#if VT_64_BIT_LENGTH == 64
decodedLength = (unsigned int)(encodeDecodeSizeInfo.processedDataLen);
#else
decodedLength = encodeDecodeSizeInfo.processedDataLen;
#endif
}
}
else if (p > input)
{
encodeDecodeSizeInfo.dataToProcess = input;
#if VT_64_BIT_LENGTH == 64
encodeDecodeSizeInfo.dataToProcessLen = (VtUInt64)(p - input);
#else
encodeDecodeSizeInfo.dataToProcessLen = (unsigned int)(p - input);
#endif
VOLT_SET_FNCT_LINE(fnctLine)
status = VoltBase64GetEncodeDecodeSize (
secureMailObj->base64, (VtRandomObject)0, VOLT_CALLER_DECODE_UPDATE,
&encodeDecodeSizeInfo);
#if VT_64_BIT_LENGTH == 64
decodedLength = (unsigned int)(encodeDecodeSizeInfo.processedDataLen);
#else
decodedLength = encodeDecodeSizeInfo.processedDataLen;
#endif
}
if ((status != 0) && (status != VT_ERROR_BUFFER_TOO_SMALL))
break;
envelopedDataLength = readCtx->pendingDataLength + decodedLength;
envelopedData = (unsigned char*) Z3Malloc(envelopedDataLength);
if (envelopedData == (unsigned char*)0)
{
VOLT_SET_ERROR_TYPE(errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE(fnctLine)
status = VT_ERROR_MEMORY;
break;
}
Z2Memcpy(envelopedData, readCtx->pendingData, readCtx->pendingDataLength);
if (status == VT_ERROR_BUFFER_TOO_SMALL)
{
if (final)
{
VOLT_SET_FNCT_LINE(fnctLine)
status = VtDecodeFinal(secureMailObj->base64, (VtRandomObject)0,
input, p - input, envelopedData + readCtx->pendingDataLength,
decodedLength, &dataWritten);
if (status == 0)
readCtx->decodedFinal = 1;
}
else
{
VOLT_SET_FNCT_LINE(fnctLine)
status = VtDecodeUpdate(secureMailObj->base64, (VtRandomObject)0,
input, p - input, envelopedData + readCtx->pendingDataLength,
decodedLength, &dataWritten);
}
if (status != 0)
break;
envelopedDataLength = readCtx->pendingDataLength + dataWritten;
}
Z2Free(readCtx->pendingData);
readCtx->pendingData = (unsigned char*)0;
readCtx->pendingDataLength = 0;
/* At this point we've decoded the input data up until the end of
* the base 64 data and merged it with any pending enveloped data.
* Now we extract the signed data from the enveloped data.
*/
if (final)
{
VOLT_SET_FNCT_LINE(fnctLine)
status = VtPkcs7ReadFinal(secureMailObj->p7EnvelopedData, envelopedData,
envelopedDataLength, &dataRead, (unsigned char*)0, 0, &signedDataLength);
}
else if (envelopedDataLength > 0)
{
VOLT_SET_FNCT_LINE(fnctLine)
status = VtPkcs7ReadUpdate(secureMailObj->p7EnvelopedData, envelopedData,
envelopedDataLength, &dataRead, (unsigned char*)0, 0, &signedDataLength);
}
else
{
dataRead = 0;
signedDataLength = 0;
status = 0;
}
if (status == VT_ERROR_CHOOSE_RECIPIENT)
{
if (dataRead < envelopedDataLength)
{
VT_ASSERT(readCtx->pendingData == (unsigned char*)0);
readCtx->pendingDataLength = envelopedDataLength - dataRead;
readCtx->pendingData = (unsigned char*)
Z3Malloc(readCtx->pendingDataLength);
if (readCtx->pendingData == (unsigned char*)0)
{
VOLT_SET_ERROR_TYPE(errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE(fnctLine)
status = VT_ERROR_MEMORY;
break;
}
Z2Memcpy(readCtx->pendingData, envelopedData + dataRead,
readCtx->pendingDataLength);
}
break;
}
if (status == VT_ERROR_BUFFER_TOO_SMALL)
{
VT_ASSERT(signedDataLength > 0);
signedData = (unsigned char*) Z3Malloc(signedDataLength);
if (signedData == (unsigned char*)0)
{
VOLT_SET_ERROR_TYPE(errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE(fnctLine)
status = VT_ERROR_MEMORY;
break;
}
if (final)
{
VOLT_SET_FNCT_LINE(fnctLine)
status = VtPkcs7ReadFinal(secureMailObj->p7EnvelopedData,
envelopedData + dataRead, envelopedDataLength - dataRead,
&dataRead2, signedData, signedDataLength, &signedDataLength);
}
else
{
VOLT_SET_FNCT_LINE(fnctLine)
status = VtPkcs7ReadUpdate(secureMailObj->p7EnvelopedData,
envelopedData + dataRead, envelopedDataLength - dataRead,
&dataRead2, signedData, signedDataLength, &signedDataLength);
}
VT_ASSERT(dataRead + dataRead2 == envelopedDataLength);
}
if (status != 0)
break;
/* At this point we've extracted the signed data from the
* envelope. Now we extract the meesage data from the signed data.
*/
if (final)
{
VOLT_SET_FNCT_LINE(fnctLine)
status = VtPkcs7ReadFinal(secureMailObj->p7SignedData,
signedData, signedDataLength, &dataRead,
(unsigned char*)0, 0, &newDataLength);
}
else if (signedDataLength > 0)
{
VOLT_SET_FNCT_LINE(fnctLine)
status = VtPkcs7ReadUpdate(secureMailObj->p7SignedData,
signedData, signedDataLength, &dataRead,
(unsigned char*)0, 0, &newDataLength);
}
else
{
newDataLength = 0;
dataRead = 0;
status = 0;
}
if (status == VT_ERROR_BUFFER_TOO_SMALL)
{
data = (unsigned char*)
Z3Malloc(readCtx->pendingHeadersLength + newDataLength);
if (data == (unsigned char*)0)
{
VOLT_SET_ERROR_TYPE(errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE(fnctLine)
status = VT_ERROR_MEMORY;
break;
}
if (readCtx->pendingHeadersLength > 0)
{
VT_ASSERT(readCtx->pendingHeaders != (unsigned char*)0);
Z2Memcpy(data, readCtx->pendingHeaders, readCtx->pendingHeadersLength);
}
if (final)
{
VOLT_SET_FNCT_LINE(fnctLine)
status = VtPkcs7ReadFinal(secureMailObj->p7SignedData,
signedData + dataRead, signedDataLength - dataRead, &dataRead,
data + readCtx->pendingHeadersLength, newDataLength, &newDataLength);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -