?? smwrite.c
字號:
index <= VOLT_WRITE_SM_FOOT_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;
}
obj->inputLen += inputDataLen;
obj->state = VOLT_SECURE_MAIL_STATE_WRITE_FINAL;
} 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, "VoltSecureMailWriteFinal", fnctLine, (char *)0)
return (status);
}
#define VOLT_CONTENT_TYPE_LABEL "content-type: "
#define VOLT_CONTENT_TYPE_LABEL_LEN 14
#define VOLT_CONTENT_LENGTH_LABEL "content-length: "
#define VOLT_CONTENT_LENGTH_LABEL_LEN 16
#define VOLT_FILE_NAME_LABEL "file-name="
#define VOLT_FILE_NAME_LABEL_LEN 10
#define VOLT_CONTENT_ZDR_UTC "ZDR-Utc: "
#define VOLT_CONTENT_ZDR_UTC_LEN 9
#define VOLT_CONTENT_ZDR_FROM "ZDR-From: "
#define VOLT_CONTENT_ZDR_FROM_LEN 10
#define VOLT_CONTENT_ZDR_TO "ZDR-To: "
#define VOLT_CONTENT_ZDR_TO_LEN 8
#define VOLT_CONTENT_ZDR_SUBJECT "ZDR-Subject: "
#define VOLT_CONTENT_ZDR_SUBJECT_LEN 13
#define VOLT_CONTENT_COMMA_SPACE ", "
#define VOLT_CONTENT_COMMA_SPACE_LEN 2
static int SetTotalLengths (
VoltSecureMailObject *obj,
VoltSecureMailWriteCtx *writeCtx,
VtRandomObject random
)
{
int status;
unsigned int asciiNumLen, offset, index, count, maxIndex;
#if VT_64_BIT_LENGTH == 64
VtUInt64 reportLen, currentLen;
#else
unsigned int reportLen, currentLen;
#endif
UInt32 numLo, numHi;
unsigned int newLineLen =
writeCtx->itemArray[VOLT_WRITE_SM_ITEM_NEW_LINE].len;
unsigned int footerLen =
writeCtx->itemArray[VOLT_WRITE_SM_ITEM_CONTENT_FOOTER].len;
VoltLibCtx *libCtx = (VoltLibCtx *)(obj->voltObject.libraryCtx);
VtIdentityObject getId;
char *contentTypeLabel = VOLT_CONTENT_TYPE_LABEL;
char *contentType = VOLT_SECURE_FILE_CONTENT;
char *contentLengthLabel = VOLT_CONTENT_LENGTH_LABEL;
char *zdrUtcLine = VOLT_CONTENT_ZDR_UTC;
char *zdrFromLine = VOLT_CONTENT_ZDR_FROM;
char *zdrToLine = VOLT_CONTENT_ZDR_TO;
char *zdrSubjectLine = VOLT_CONTENT_ZDR_SUBJECT;
char *asciiNum = (char *)0;
unsigned char *newLine =
writeCtx->itemArray[VOLT_WRITE_SM_ITEM_NEW_LINE].data;
VtItem *preP7 = &(writeCtx->itemArray[VOLT_WRITE_SM_PRE_PKCS7]);
VtItem *report = &(writeCtx->itemArray[VOLT_WRITE_SM_ITEM_CONTENT_REPORT]);
VtItem *getName;
VtItem tempItem;
VtTime theTime;
unsigned char utcTime[VOLT_UTC_LEN];
char *commaSpace = VOLT_CONTENT_COMMA_SPACE;
VoltEncodeDecodeSizeInfo encodeDecodeSizeInfo;
VOLT_DECLARE_ERROR_TYPE (errorType)
VOLT_DECLARE_FNCT_LINE (fnctLine)
do
{
/* Build the content descriptor VtItem.
*/
#if VT_64_BIT_LENGTH == 64
reportLen = (VtUInt64)(obj->contentInfo.len);
#else
reportLen = obj->contentInfo.len;
#endif
if ( (obj->formatType == VOLT_MESSAGE_FORMAT_SECURE_MAIL) ||
(obj->formatType == VOLT_MESSAGE_FORMAT_ZDM_MAIL) )
{
/* Build the content-type: and content-length: lines. First, get
* the length as ASCII characters.
*/
#if VT_64_BIT_LENGTH == 64
currentLen = obj->dataLen64 + (VtUInt64)footerLen;
numLo = (UInt32)currentLen;
numHi = (UInt32)(currentLen >> 32);
#else
currentLen = obj->dataLen + footerLen;
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_INVALID_INPUT_LENGTH;
if (currentLen < footerLen)
break;
numLo = (UInt32)currentLen;
numHi = (UInt32)0;
#endif
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = ConvertNumToAsciiAlloc (
libCtx, numLo, numHi, &asciiNum, &asciiNumLen);
if (status != 0)
break;
/* Build the content descriptor buffer, content type label, then
* the content type, new line, content len label, then length,
* new line.
* If this is ZDM there's more to add.
* Finally, one last new line.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = AppendToVtItem (
libCtx, contentTypeLabel, VOLT_CONTENT_TYPE_LABEL_LEN,
(unsigned char *)0, 0, report);
if (status != 0)
break;
VOLT_SET_FNCT_LINE (fnctLine)
status = AppendToVtItem (
libCtx, obj->contentInfo.data, obj->contentInfo.len,
newLine, newLineLen, report);
if (status != 0)
break;
VOLT_SET_FNCT_LINE (fnctLine)
status = AppendToVtItem (
libCtx, contentLengthLabel, VOLT_CONTENT_LENGTH_LABEL_LEN,
(unsigned char *)0, 0, report);
if (status != 0)
break;
VOLT_SET_FNCT_LINE (fnctLine)
status = AppendToVtItem (
libCtx, asciiNum, asciiNumLen, newLine, newLineLen, report);
if (status != 0)
break;
if (obj->formatType == VOLT_MESSAGE_FORMAT_ZDM_MAIL)
{
VOLT_SET_FNCT_LINE (fnctLine)
status = AppendToVtItem (
libCtx, zdrUtcLine, VOLT_CONTENT_ZDR_UTC_LEN,
(unsigned char *)0, 0, report);
if (status != 0)
break;
VtGetTime ((VtLibCtx)libCtx, &theTime);
VoltConvertVtTimeToUTC (&theTime, utcTime);
VOLT_SET_FNCT_LINE (fnctLine)
status = AppendToVtItem (
libCtx, utcTime, VOLT_UTC_LEN, newLine, newLineLen, report);
if (status != 0)
break;
VOLT_SET_FNCT_LINE (fnctLine)
status = AppendToVtItem (
libCtx, zdrFromLine, VOLT_CONTENT_ZDR_FROM_LEN,
(unsigned char *)0, 0, report);
if (status != 0)
break;
/* Get the email address of the sender.
* If we can't get the email address out, don't quit, just
* print a blank line.
*/
tempItem.data = (unsigned char *)0;
tempItem.len = 0;
VOLT_SET_FNCT_LINE (fnctLine)
status = VtGetIdentityParam (
writeCtx->senderIdRef, VtIdentityParamCommonName,
(Pointer *)&getName);
if (status == 0)
tempItem = *getName;
VOLT_SET_FNCT_LINE (fnctLine)
status = AppendToVtItem (
libCtx, tempItem.data, tempItem.len, newLine, newLineLen, report);
if (status != 0)
break;
/* Print out the list of recipients.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = AppendToVtItem (
libCtx, zdrToLine, VOLT_CONTENT_ZDR_TO_LEN,
(unsigned char *)0, 0, report);
if (status != 0)
break;
VOLT_SET_FNCT_LINE (fnctLine)
status = VtGetIdentityListCount (
writeCtx->recipListRef, &count, &maxIndex);
if (status != 0)
break;
for (index = 0; index <= maxIndex; ++index)
{
VOLT_SET_FNCT_LINE (fnctLine)
status = VtGetIdentityListIdentity (
writeCtx->recipListRef, index, &getId);
if (status == VT_ERROR_NO_ID_AT_INDEX)
continue;
if (status != 0)
break;
tempItem.data = (unsigned char *)0;
tempItem.len = 0;
VOLT_SET_FNCT_LINE (fnctLine)
status = VtGetIdentityParam (
getId, VtIdentityParamCommonName, (Pointer *)&getName);
if (status == 0)
tempItem = *getName;
if (index != maxIndex)
{
/* If this is not the last email, we'll need a comma after
* the address.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = AppendToVtItem (
libCtx, tempItem.data, tempItem.len,
commaSpace, VOLT_CONTENT_COMMA_SPACE_LEN, report);
if (status != 0)
break;
}
else
{
/* If this is the last email, start a new line after the
* address.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = AppendToVtItem (
libCtx, tempItem.data, tempItem.len, newLine, newLineLen,
report);
if (status != 0)
break;
}
}
if (status != 0)
break;
/* Finally, the subject.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = AppendToVtItem (
libCtx, zdrSubjectLine, VOLT_CONTENT_ZDR_SUBJECT_LEN,
(unsigned char *)0, 0, report);
if (status != 0)
break;
VOLT_SET_FNCT_LINE (fnctLine)
status = AppendToVtItem (
libCtx, writeCtx->itemArray[VOLT_WRITE_SM_ITEM_SUBJECT].data,
writeCtx->itemArray[VOLT_WRITE_SM_ITEM_SUBJECT].len,
newLine, newLineLen, report);
if (status != 0)
break;
}
VOLT_SET_FNCT_LINE (fnctLine)
status = AppendToVtItem (
libCtx, newLine, newLineLen, (unsigned char *)0, 0, report);
if (status != 0)
break;
reportLen = report->len;
}
else if (obj->formatType == VOLT_MESSAGE_FORMAT_SECURE_MAIL_2)
{
reportLen += (2 * newLineLen);
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_MEMORY;
report->data = (unsigned char *)Z2Realloc (report->data, reportLen);
if (report->data == (unsigned char *)0)
break;
/* For SecureMail 2, the headers inside the PKCS7 blob consist of some
* XML data (instead of the MIME-style headers used with V1. So we don't
* need to prepend the content-type label before writing the header data.
*/
Z2Memcpy(report->data, obj->contentInfo.data, obj->contentInfo.len);
offset = obj->contentInfo.len;
/* A blank line indicates the end of the headers, so add 2 new lines */
Z2Memcpy (report->data + offset, newLine, newLineLen);
offset += newLineLen;
Z2Memcpy (report->data + offset, newLine, newLineLen);
report->len = (unsigned int)reportLen;
}
else
{
/* Build the content-type: ...; file-name= line. Add in the label
* and 2 new lines.
*/
if (reportLen != 0)
{
contentType = (char *)(obj->contentInfo.data);
asciiNumLen = obj->contentInfo.len;
}
else
{
reportLen = VOLT_SECURE_FILE_CONTENT_LEN;
asciiNumLen = VOLT_SECURE_FILE_CONTENT_LEN;
}
#if VT_64_BIT_LENGTH == 64
reportLen += (VtUInt64)
(VOLT_CONTENT_TYPE_LABEL_LEN + VOLT_FILE_NAME_LABEL_LEN +
writeCtx->fileName.len + 3 + (2 * newLineLen));
#else
reportLen +=
VOLT_CONTENT_TYPE_LABEL_LEN + VOLT_FILE_NAME_LABEL_LEN +
writeCtx->fileName.len + 3 + (2 * newLineLen);
#endif
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_MEMORY;
asciiNum = (unsigned char *)Z2Malloc ((unsigned int)reportLen, 0);
if (asciiNum == (unsigned char *)0)
break;
/* Build the content descriptor buffer, content type for file
* label, then the file name, new line, and new line.
*/
Z2Memcpy (
asciiNum, VOLT_CONTENT_TYPE_LABEL, VOLT_CONTENT_TYPE_LABEL_LEN);
offset = VOLT_CONTENT_TYPE_LABEL_LEN;
Z2Memcpy (asciiNum + offset, contentType, asciiNumLen);
offset += asciiNumLen;
Z2Memcpy (asciiNum + offset, "; ", 2);
offset += 2;
Z2Memcpy (
asciiNum + offset, VOLT_FILE_NAME_LABEL, VOLT_FILE_NAME_LABEL_LEN);
offset += VOLT_FILE_NAME_LABEL_LEN;
Z2Memcpy (
asciiNum + offset, writeCtx->fileName.data, writeCtx->fileName.len);
offset += writeCtx->fileName.len;
Z2Memcpy (asciiNum + offset, ";", 1);
offset += 1;
/* After the file name, newLine, then a blank line.
*/
Z2Memcpy (asciiNum + offset, newLine, newLineLen);
offset += newLineLen;
Z2Memcpy (asciiNum + offset, newLine, newLineLen);
if (report->data != (unsigned char *)0)
Z2Free (report->data);
report->data = (unsigned char *)asciiNum;
report->len = (unsigned int)reportLen;
asciiNum = (char *)0;
}
/* Set the length of the SignedData. The length is the reportLen
* plus the dataLen plus the content footerLen.
*/
#if VT_64_BIT_LENGTH == 64
reportLen += obj->dataLen64;
reportLen += (VtUInt64)footerLen;
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = VtSetPkcs7Param (
obj->p7SignedData, VtPkcs7ParamDataLen64, (Pointer)&reportLen);
if (status != 0)
break;
#else
reportLen += (obj->dataLen + footerLen);
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = VtSetPkcs7Param (
obj->p7SignedData, VtPkcs7ParamDataLen, (Pointer)&reportLen);
if (status != 0)
break;
#endif
#if VT_64_BIT_LENGTH == 64
/* Call VtGetTotalOutputLen64 to determine how big the SignedData
* will be.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = VtGetTotalOutputLen64 (
(VtLibCtx)libCtx, VtGetOutputLen64ImplPkcs7,
(Pointer)(obj->p7SignedData), &(writeCtx->signedDataLen));
if (status != 0)
break;
#else
/* Call Final with no output to determine length.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = VtPkcs7WriteFinal (
obj->p7SignedData, random, (unsigned char *)0, reportLen,
(unsigned char *)0, 0, &(writeCtx->signedDataLen));
if (status == 0)
status = VT_ERROR_GENERAL;
if (status != VT_ERROR_BUFFER_TOO_SMALL)
break;
#endif
/* We now know how many bytes we're going to pass to the enveloper.
*/
#if VT_64_BIT_LENGTH == 64
VOLT_SET_FNCT_LINE (fnctLine)
status = VtSetPkcs7Param (
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -