?? zdmsmwrite.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 "zdm.h"
#include "policy.h"
#include "stringutil.h"
#include "errorctx.h"
/* A SecureMail message looks like this.
* <code>
* <pre>
* -----BEGIN ... -----
* <app-supplied header>
* -----BEGIN ... -----
* <message data>
* -----END ... -----
* -----END ... -----
* </pre>
* </code>
* The ZDM From SecureMail object will copy only the message data (it
* replaces headers and footers with its own values).
* <p>The inputData for this function will be part or all of a
* SecureMail message. This function will determine the address of the
* beginning of the message data. If the SM headers have not yet been
* stripped, the routine will figure out what is header, skip it and
* return the beginning of the message data. If the pertinant address
* is not available (the inputData consists of only some of the
* SecureMail header and does not reach the message data), it will
* return NULL. If the SM headers have been stripped, the routine will
* consider the inputData to be the start of data. However, if the
* inputData is actually the start of the footer (the first byte of
* inputData is the first dash of the first -----END footer), the
* function will return a NULL dataStart result.
* <p>The obj->state variable will further define a NULL dataStart
* return. If the state is INIT or WRITE_HEADER, NULL means we have not
* yet reached the message data. If it is WRITE_BODY, a NULL means
* we've reached the footer.
*
* @param libCtx
* @param obj
* @param inputData
* @param inputDataLen
* @param dataStart The address where the routine will deposit the
* address of the beginning of the SecureMail data to copy.
* @return an int, 0 if the function completed successfully or a
* non-zero error code.
*/
static int VOLT_CALLING_CONV ComputeSMStartAddress VOLT_PROTO_LIST ((
VoltLibCtx *libCtx,
VoltSecureMailObject *obj,
VoltSecureMailWriteCtx *writeCtx,
unsigned char *inputData,
unsigned int inputDataLen,
unsigned char **dataStart
));
/* A SecureMail message looks like this.
* <code>
* <pre>
* -----BEGIN ... -----
* <app-supplied header>
* -----BEGIN ... -----
* <message data>
* -----END ... -----
* -----END ... -----
* </pre>
* </code>
* The ZDM From SecureMail object will copy only the message data (it
* replaces headers and footers with its own values).
* <p>The inputData for this function will be part or all of a
* SecureMail message. This function will determine the address of the
* beginning of the footer material (the first dash of the first
* -----END line).
* <p>The function will go to the addresses given for the result
* (footStart) and deposit the address. If the pertinant address is
* not available (the inputData consists of only message data), it will
* deposit NULL at footStart.
*
* @param libCtx
* @param obj
* @param msgData
* @param msgDataLen
* @param footStart The address where the routine will deposit the
* address of the beginning of the SecureMail footer material.
* @return an int, 0 if the function completed successfully or a
* non-zero error code.
*/
static int VOLT_CALLING_CONV ComputeSMFootAddress VOLT_PROTO_LIST ((
VoltLibCtx *libCtx,
VoltSecureMailObject *obj,
unsigned char *msgData,
unsigned int msgDataLen,
unsigned char **footStart
));
int VoltOldZDMFromSMWriteUpdate (
VtZDMObject zdmObj,
VtRandomObject random,
unsigned char *inputData,
unsigned int inputDataLen,
unsigned char *message,
unsigned int bufferSize,
unsigned int *messageLen
)
{
int status;
VoltZDMObject *zObj = (VoltZDMObject *)zdmObj;
VOLT_DECLARE_FNCT_LINE (fnctLine)
VOLT_SET_FNCT_LINE (fnctLine)
status = VoltZDMFromSMWriteUpdate (
(VtSecureMailObject)(zObj->localCtx), random, inputData, inputDataLen,
message, bufferSize, messageLen);
VOLT_LOG_ERROR_INFO_COMPARE (
status, 0, zdmObj, status, 0, 0,
(char *)0, "VoltOldZDMFromSMWriteUpdate", fnctLine, (char *)0)
return (status);
}
int VoltOldZDMFromSMWriteFinal (
VtZDMObject zdmObj,
VtRandomObject random,
unsigned char *inputData,
unsigned int inputDataLen,
unsigned char *message,
unsigned int bufferSize,
unsigned int *messageLen
)
{
int status;
VoltZDMObject *zObj = (VoltZDMObject *)zdmObj;
VOLT_DECLARE_FNCT_LINE (fnctLine)
VOLT_SET_FNCT_LINE (fnctLine)
status = VoltZDMFromSMWriteFinal (
(VtSecureMailObject)(zObj->localCtx), random, inputData, inputDataLen,
message, bufferSize, messageLen);
VOLT_LOG_ERROR_INFO_COMPARE (
status, 0, zdmObj, status, 0, 0,
(char *)0, "VoltOldZDMFromSMWriteFinal", fnctLine, (char *)0)
return (status);
}
int VoltZDMFromSMWriteUpdate (
VtSecureMailObject secureMailObj,
VtRandomObject random,
unsigned char *inputData,
unsigned int inputDataLen,
unsigned char *message,
unsigned int bufferSize,
unsigned int *messageLen
)
{
int status;
unsigned int index, dataLen, b64Len, newLineLen, elementLen, offset;
VoltSecureMailObject *obj = (VoltSecureMailObject *)(secureMailObj);
VoltLibCtx *libCtx = (VoltLibCtx *)(obj->voltObject.libraryCtx);
VoltZDMFromSecureMailCtx *zdmCtx =
(VoltZDMFromSecureMailCtx *)(obj->localCtx);
VoltSecureMailWriteCtx *writeCtx = &(zdmCtx->baseCtx);
unsigned char *newLine;
unsigned char *dataStart = (unsigned char *)0;
unsigned char *footStart = (unsigned char *)0;
VoltEncodeDecodeSizeInfo encodeDecodeSizeInfo;
VOLT_DECLARE_ERROR_TYPE (errorType)
VOLT_DECLARE_FNCT_LINE (fnctLine)
*messageLen = 0;
/* Writing the footer is the responsibility of Final.
*/
if (obj->state == VOLT_ZDM_FROM_SM_STATE_WRITE_FOOTER)
return (0);
if (obj->state == VOLT_ZDM_FROM_SM_STATE_WRITE_COMPLETE)
return (0);
if (inputDataLen == 0)
return (0);
do
{
/* If inputData is NULL, we won't know which of the data to throw
* away and which to copy, so assume it's all to be copied and the
* footer will not be reached.
* If prelimLen is not 0, we'll want to write out the ZDM header
* material as well.
*/
if (inputData == (unsigned char *)0)
{
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_BUFFER_TOO_SMALL;
*messageLen = inputDataLen + writeCtx->prelimLen;
break;
}
/* Where, in the inputData, is the message data we're going to copy?
*/
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = ComputeSMStartAddress (
libCtx, obj, writeCtx, inputData, inputDataLen, &dataStart);
if (status != 0)
break;
/* If we don't have a data start, figure out why.
* After the call to ComputeStartAddress, the state will be one of
* the following three.
* VOLT_ZDM_FROM_SM_STATE_WRITE_HEADER
* VOLT_ZDM_FROM_SM_STATE_WRITE_HEAD_2
* VOLT_ZDM_FROM_SM_STATE_WRITE_BODY
* If the state is HEADER or HEAD_2, we have not yet written out the
* ZDM header, then we know a NULL dataStart means the inputData has
* not yet reached the message data. So we'll want to output the ZDM
* header only.
* If the state is WRITE_BODY, a NULL dataStart means we've reached
* the end, we'll write out the ZDM footer in WriteFinal.
*
* If the dataStart is not NULL, see if we can find the start of
* the footer. If we find a footer, the dataLen is the number of
* bytes between the dataStart and footStart. If there is no
* footStart, the dataLen is everything after the dataStart.
*/
if (dataStart == (unsigned char *)0)
{
if (obj->state == VOLT_ZDM_FROM_SM_STATE_WRITE_BODY)
{
obj->state = VOLT_ZDM_FROM_SM_STATE_WRITE_FOOTER;
break;
}
dataLen = 0;
}
else
{
/* How many bytes are we skipping?
*/
dataLen = (unsigned int)(dataStart - inputData);
dataLen = inputDataLen - dataLen;
VOLT_SET_FNCT_LINE (fnctLine)
status = ComputeSMFootAddress (
libCtx, obj, dataStart, dataLen, &footStart);
if (status != 0)
break;
/* If there is no footStart, we'll write out all the dataLen
* bytes beginning at dataStart.
* If there is a footStart, we'll write out the bytes up to the
* footStart.
*/
if (footStart != (unsigned char *)0)
{
dataLen = (unsigned int)(footStart - dataStart);
/* We have a footer, which means we have all the input data,
* which means we can compute the ZDM pad.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = VoltAddZDMPad (
obj, writeCtx, (UInt32)(zdmCtx->fourKLen + dataLen), (UInt32)0);
if (status != 0)
break;
}
}
/* How many bytes will the Base64 encoded data be?
*/
encodeDecodeSizeInfo.dataToProcess = (unsigned char *)0;
#if VT_64_BIT_LENGTH == 64
encodeDecodeSizeInfo.dataToProcessLen = (VtUInt64)dataLen;
#else
encodeDecodeSizeInfo.dataToProcessLen = dataLen;
#endif
VOLT_SET_FNCT_LINE (fnctLine)
status = obj->GetEncodeDecodeSize (
obj->base64, (VtRandomObject)0, VOLT_CALLER_ENCODE_UPDATE,
&encodeDecodeSizeInfo);
if (status != VT_ERROR_BUFFER_TOO_SMALL)
break;
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 (encodeDecodeSizeInfo.processedDataLen > 0xffffffff)
break;
b64Len = (unsigned int)(encodeDecodeSizeInfo.processedDataLen);
#else
b64Len = encodeDecodeSizeInfo.processedDataLen;
#endif
/* Determine the totalLen. It is either the dataLen or the dataLen
* plus the prelimLen if the ZDM header has not yet be output. If
* the ZDM header has already been output, prelimLen will be 0.
*/
VOLT_SET_FNCT_LINE (fnctLine)
*messageLen = b64Len + writeCtx->prelimLen;
if (*messageLen < b64Len)
break;
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_BUFFER_TOO_SMALL;
if (bufferSize < *messageLen)
break;
offset = 0;
if (writeCtx->prelimLen != 0)
{
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 ZDM header material, set
* prelimLen to 0 so we'll never try to write it again.
*/
writeCtx->prelimLen = 0;
}
if (dataLen != 0)
{
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = VtEncodeUpdate (
obj->base64, (VtRandomObject)0, dataStart, dataLen,
message + offset, bufferSize - offset, &b64Len);
if (status != 0)
break;
zdmCtx->fourKLen += b64Len;
/* If there's a footStart, we'll move to state WRITE_FOOTER. If
* not, we'll be in WRITE_BODY.
*/
obj->state = VOLT_ZDM_FROM_SM_STATE_WRITE_FOOTER;
if (footStart == (unsigned char *)0)
obj->state = VOLT_ZDM_FROM_SM_STATE_WRITE_BODY;
}
status = 0;
} while (0);
VOLT_LOG_ERROR_INFO_COMPARE (
status, 0, secureMailObj, status, 0, errorType,
(char *)0, "VoltZDMFromSMWriteUpdate", fnctLine, (char *)0)
return (status);
}
int VoltZDMFromSMWriteFinal (
VtSecureMailObject secureMailObj,
VtRandomObject random,
unsigned char *inputData,
unsigned int inputDataLen,
unsigned char *message,
unsigned int bufferSize,
unsigned int *messageLen
)
{
int status;
unsigned int index, outputLenUpdate, b64Len, newLineLen, elementLen, offset;
VoltSecureMailObject *obj = (VoltSecureMailObject *)(secureMailObj);
VoltLibCtx *libCtx = (VoltLibCtx *)(obj->voltObject.libraryCtx);
VoltSecureMailWriteCtx *writeCtx = (VoltSecureMailWriteCtx *)(obj->localCtx);
unsigned char *newLine;
VoltEncodeDecodeSizeInfo encodeDecodeSizeInfo;
VOLT_DECLARE_ERROR_TYPE (errorType)
VOLT_DECLARE_FNCT_LINE (fnctLine)
if (obj->state == VOLT_ZDM_FROM_SM_STATE_WRITE_COMPLETE)
return (0);
offset = 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;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -