📄 writesign.c
字号:
unsigned char signedDataOid[VoltP7SignDataOidBytesLen] =
{ VoltP7SignDataOidBytes };
unsigned char dataOid[VoltP7DataOidBytesLen] = { VoltP7DataOidBytes };
VOLT_DECLARE_ERROR_TYPE (errorType)
VOLT_DECLARE_FNCT_LINE (fnctLine)
do
{
/* The state must be INIT or UPDATE.
*/
if (obj->state == VOLT_P7_STATE_SIGN_WRITE_INIT)
{
/* Check to see if the inputDataLen exceeds the amount specified
* by calling SetPkcs7Param with the DataLen param.
*/
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 ((VtUInt64)inputDataLen > obj->dataLen64)
#else
if (inputDataLen > obj->dataLen)
#endif
break;
/* Determine outputLen. It will be the length of the "prefix"
* plus the length of the input data.
* The prefix is the following
* 30 len contentInfo
* 06 len <SignedData OID> contentType
* A0 len EXPLICIT content
* 30 len SignedData
* 02 01 01 version
* 31 len digestAlgorithms
* <digest algID>
* 30 len contentInfo
* 06 len <Data OID> contentType
* A0 len EXPLICIT content
* 04 len Data
*/
/* Work up from the bottom. Start with the 04 len, how many bytes
* make up the length octets? Then add in the length of the data
* itself.
* Later on, we'll need to subtract the number of bytes not
* passed in during this call. We're counting the total bytes
* that will be passed in (obj->dataLen) in order to get the
* lengths in the encoding correct. However, we may not have all
* the data now, inputDataLen might be smaller.
*/
#if VT_64_BIT_LENGTH == 64
outputLen = (VtUInt64)VoltDetermineDerLengthLen (
(UInt32)(obj->dataLen64), (UInt32)(obj->dataLen64 >> 32));
outputLen += (1 + obj->dataLen64);
#else
outputLen = VoltDetermineDerLengthLen (
(UInt32)(obj->dataLen), (UInt32)0);
outputLen += (1 + obj->dataLen);
#endif
/* Now add in the length of the A0 len. Then add in the number of
* bytes that make up the OID for the Data itself.
*/
contentLen = outputLen;
#if VT_64_BIT_LENGTH == 64
outputLen += (VtUInt64)VoltDetermineDerLengthLen (
(UInt32)contentLen, (UInt32)(contentLen >> 32));
#else
outputLen += VoltDetermineDerLengthLen ((UInt32)contentLen, (UInt32)0);
#endif
outputLen += VoltP7DataOidBytesLen + 3;
/* Now determine the length of the 30 len of the contentInfo of
* the SignedData (this is the content that is being signed, so
* it is the Data construct).
*/
contentInfoLen = outputLen;
#if VT_64_BIT_LENGTH == 64
outputLen += (VtUInt64)VoltDetermineDerLengthLen (
(UInt32)contentInfoLen, (UInt32)(contentInfoLen >> 32));
#else
outputLen += VoltDetermineDerLengthLen (
(UInt32)contentInfoLen, (UInt32)0);
#endif
outputLen++;
/* Add in the length of the SET OF digest algID's. We're assuming
* here that lengths will never be longer than 127 bytes. This
* implementation works with only one digest algorithm, so the
* SET OF is actually a SET OF one algID.
* Then add in the version (3 bytes).
*/
#if VT_64_BIT_LENGTH == 64
outputLen += (VtUInt64)(signCtx->digestAlgId.len + 5);
#else
outputLen += signCtx->digestAlgId.len + 5;
#endif
/* Figure out the 30 len of the SignedData content. This includes
* the certs and signerInfo's. Use offset as a temp variable.
*/
#if VT_64_BIT_LENGTH == 64
signedDataLen = (VtUInt64)VoltDetermineDerLengthLen (
(UInt32)(signCtx->totalCertLen), (UInt32)0);
signedDataLen += (VtUInt64)VoltDetermineDerLengthLen (
(UInt32)(signCtx->totalSignerInfoLen), (UInt32)0);
signedDataLen += outputLen;
signedDataLen +=
(VtUInt64)(signCtx->totalCertLen + signCtx->totalSignerInfoLen + 2);
offset = VoltDetermineDerLengthLen (
(UInt32)signedDataLen, (UInt32)(signedDataLen >> 32));
outputLen += (VtUInt64)(offset + 1);
#else
signedDataLen = VoltDetermineDerLengthLen (
(UInt32)(signCtx->totalCertLen), (UInt32)0);
signedDataLen += VoltDetermineDerLengthLen (
(UInt32)(signCtx->totalSignerInfoLen), (UInt32)0);
signedDataLen +=
outputLen + signCtx->totalCertLen + signCtx->totalSignerInfoLen + 2;
offset = VoltDetermineDerLengthLen ((UInt32)signedDataLen, (UInt32)0);
outputLen += offset + 1;
#endif
/* Figure out the A0 len of the EXPLICIT. Use offset as a temp
* variable.
*/
#if VT_64_BIT_LENGTH == 64
explicitLen = signedDataLen + (VtUInt64)(offset + 1);
offset = VoltDetermineDerLengthLen (
(UInt32)explicitLen, (UInt32)(explicitLen >> 32));
outputLen += (VtUInt64)(offset + 1);
#else
explicitLen = signedDataLen + offset + 1;
offset = VoltDetermineDerLengthLen ((UInt32)explicitLen, (UInt32)0);
outputLen += offset + 1;
#endif
/* Add in the SignedData OID.
*/
outputLen += VoltP7SignDataOidBytesLen + 2;
/* What is the 30 len of the total contentInfo?
*/
#if VT_64_BIT_LENGTH == 64
/* Use offset as a variable to add to both outputLen and
* obj->outputLen64.
*/
totalLen =
explicitLen + (VtUInt64)(offset + VoltP7SignDataOidBytesLen + 3);
offset = VoltDetermineDerLengthLen (
(UInt32)totalLen, (UInt32)(totalLen >> 32));
/* Add in the tag octet.
*/
offset++;
outputLen += (VtUInt64)offset;
#else
totalLen = explicitLen + offset + VoltP7SignDataOidBytesLen + 3;
outputLen += VoltDetermineDerLengthLen ((UInt32)totalLen, (UInt32)0);
outputLen++;
#endif
#if VT_64_BIT_LENGTH == 64
/* Save the output len so we can return it if need be.
*/
obj->outputLen64 = totalLen + (VtUInt64)offset;
#endif
/* outputLen counts the total input length. However, this call to
* Update may not have all the data.
*/
#if VT_64_BIT_LENGTH == 64
outputLen -= (obj->dataLen64 - (VtUInt64)inputDataLen);
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_INVALID_INPUT_LENGTH;
if (outputLen > (VtUInt64)0xffffffff)
break;
*messageLen = (UInt32)outputLen;
#else
outputLen -= (obj->dataLen - inputDataLen);
*messageLen = outputLen;
#endif
/* Is the buffer big enough?
*/
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
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;
/* The buffer is big enough. Place the prefix.
* First, the 30 len of the overall contentInfo.
*/
#if VT_64_BIT_LENGTH == 64
offset = VoltWriteDerTagAndLen (
message, 0x30, (UInt32)totalLen, (UInt32)(totalLen >> 32));
#else
offset = VoltWriteDerTagAndLen (
message, 0x30, (UInt32)totalLen, (UInt32)0);
#endif
/* Write out the SignedData OID.
*/
offset += VoltWriteDerTagAndLen (
message + offset, 0x06, (UInt32)VoltP7SignDataOidBytesLen, (UInt32)0);
Z2Memcpy (message + offset, signedDataOid, VoltP7SignDataOidBytesLen);
offset += VoltP7SignDataOidBytesLen;
/* Write out the EXPLICIT and the SignedData's SEQUENCE.
*/
#if VT_64_BIT_LENGTH == 64
offset += VoltWriteDerTagAndLen (
message + offset, 0xA0, (UInt32)explicitLen,
(UInt32)(explicitLen >> 32));
offset += VoltWriteDerTagAndLen (
message + offset, 0x30, (UInt32)signedDataLen,
(UInt32)(signedDataLen >> 32));
#else
offset += VoltWriteDerTagAndLen (
message + offset, 0xA0, (UInt32)explicitLen, (UInt32)0);
offset += VoltWriteDerTagAndLen (
message + offset, 0x30, (UInt32)signedDataLen, (UInt32)0);
#endif
/* Now it's the version.
*/
message[offset] = 0x02;
offset++;
message[offset] = 0x01;
offset++;
message[offset] = 0x01;
offset++;
/* Write out the SET of digestAlgorithms.
*/
offset += VoltWriteDerTagAndLen (
message + offset, 0x31, (UInt32)(signCtx->digestAlgId.len), (UInt32)0);
Z2Memcpy (
message + offset, signCtx->digestAlgId.data, signCtx->digestAlgId.len);
offset += signCtx->digestAlgId.len;
/* Next is contentInfo of the signed data.
*/
#if VT_64_BIT_LENGTH == 64
offset += VoltWriteDerTagAndLen (
message + offset, 0x30, (UInt32)contentInfoLen,
(UInt32)(contentInfoLen >> 32));
#else
offset += VoltWriteDerTagAndLen (
message + offset, 0x30, (UInt32)contentInfoLen, (UInt32)0);
#endif
/* Place the Data OID.
*/
offset += VoltWriteDerTagAndLen (
message + offset, 0x06, (UInt32)VoltP7DataOidBytesLen, (UInt32)0);
Z2Memcpy (message + offset, dataOid, VoltP7DataOidBytesLen);
offset += VoltP7DataOidBytesLen;
/* Now comes the data itself. First, the EXPLICIT, then the OCTET
* STRING.
*/
#if VT_64_BIT_LENGTH == 64
offset += VoltWriteDerTagAndLen (
message + offset, 0xA0, (UInt32)contentLen,
(UInt32)(contentLen >> 32));
offset += VoltWriteDerTagAndLen (
message + offset, 0x04, (UInt32)(obj->dataLen64),
(UInt32)(obj->dataLen64 >> 32));
#else
offset += VoltWriteDerTagAndLen (
message + offset, 0xA0, (UInt32)contentLen, (UInt32)0);
offset += VoltWriteDerTagAndLen (
message + offset, 0x04, (UInt32)(obj->dataLen), (UInt32)0);
#endif
/* We'll start digesting data now.
*/
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = VtDigestInit (signCtx->digester);
if (status != 0)
break;
}
else if (obj->state == VOLT_P7_STATE_SIGN_WRITE_UPDATE)
{
/* If Update, make sure the amount of input does not exceed the
* dataLen.
*/
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 (((VtUInt64)inputDataLen + obj->inputLen64) > obj->dataLen64)
#else
if ((inputDataLen + obj->inputLen) > obj->dataLen)
#endif
break;
/* Is the output buffer big enough?
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_BUFFER_TOO_SMALL;
*messageLen = inputDataLen;
if (bufferSize < inputDataLen)
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;
offset = 0;
}
else
{
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_INVALID_CALL_ORDER;
break;
}
/* Digest the input data.
*/
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = VtDigestUpdate (signCtx->digester, inputData, inputDataLen);
if (status != 0)
break;
/* Write out the input.
*/
Z2Memcpy (message + offset, inputData, inputDataLen);
#if VT_64_BIT_LENGTH == 64
obj->inputLen64 += (VtUInt64)inputDataLen;
#else
obj->inputLen += inputDataLen;
#endif
obj->state = VOLT_P7_STATE_SIGN_WRITE_UPDATE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -