📄 writeenv.c
字号:
break;
*/
/* Currently, this code supports only block ciphers in CBC mode
* with P5 padding. So this is how to compute outputLen.
*/
#if VT_64_BIT_LENGTH == 64
encryptedDataLen = obj->dataLen64 / ((VtUInt64)(envCtx->blockSize));
#else
encryptedDataLen = obj->dataLen / envCtx->blockSize;
#endif
if (envCtx->blockSize != 1)
encryptedDataLen++;
#if VT_64_BIT_LENGTH == 64
encryptedDataLen *= (VtUInt64)(envCtx->blockSize);
#else
encryptedDataLen *= envCtx->blockSize;
#endif
/* Add in the total length of encrypted data so all other lengths
* will be computed correctly. Then later on, subtract the amount
* of encryptedData we will not output.
*/
#if VT_64_BIT_LENGTH == 64
outputLen = (VtUInt64)VoltDetermineDerLengthLen (
(UInt32)encryptedDataLen, (UInt32)(encryptedDataLen >> 32));
outputLen += (1 + encryptedDataLen);
#else
outputLen = VoltDetermineDerLengthLen (
(UInt32)encryptedDataLen, (UInt32)0);
outputLen += (1 + encryptedDataLen);
#endif
/* Add in the symmetric encryption algID and the Data OID.
* Don't add amounts twice.
*/
#if VT_64_BIT_LENGTH == 64
encContentInfoLen =
(VtUInt64)(envCtx->symEncryptorAlgId.len + VoltP7DataOidBytesLen + 2);
encContentInfoLen += outputLen;
outputLen = (VtUInt64)VoltDetermineDerLengthLen (
(UInt32)encContentInfoLen, (UInt32)(encContentInfoLen >> 32));
outputLen += encContentInfoLen + 1;
#else
encContentInfoLen =
outputLen + envCtx->symEncryptorAlgId.len + VoltP7DataOidBytesLen + 2;
outputLen = VoltDetermineDerLengthLen (
(UInt32)encContentInfoLen, (UInt32)0);
outputLen += encContentInfoLen + 1;
#endif
/* What is the SET OF for RecipientInfos going to be? Add in the
* version.
*/
#if VT_64_BIT_LENGTH == 64
outputLen += (VtUInt64)VoltDetermineDerLengthLen (
(UInt32)(envCtx->totalRecipInfoLen), (UInt32)0);
outputLen += (VtUInt64)(envCtx->totalRecipInfoLen + 4);
#else
outputLen += VoltDetermineDerLengthLen (
(UInt32)(envCtx->totalRecipInfoLen), (UInt32)0);
outputLen += envCtx->totalRecipInfoLen + 4;
#endif
/* Now add in the SEQUENCE that is the EnvelopedData.
*/
seqLen = outputLen;
#if VT_64_BIT_LENGTH == 64
outputLen += (VtUInt64)VoltDetermineDerLengthLen (
(UInt32)outputLen, (UInt32)(outputLen >> 32));
#else
outputLen += VoltDetermineDerLengthLen ((UInt32)outputLen, (UInt32)0);
#endif
outputLen++;
/* Next is the EXPLICIT.
*/
expLen = outputLen;
#if VT_64_BIT_LENGTH == 64
outputLen += (VtUInt64)VoltDetermineDerLengthLen (
(UInt32)outputLen, (UInt32)(outputLen >> 32));
#else
outputLen += VoltDetermineDerLengthLen ((UInt32)outputLen, (UInt32)0);
#endif
outputLen++;
/* Add in the EnvelopedData OID.
*/
outputLen += VoltP7EnvDataOidBytesLen + 2;
/* Now comes the overall SEQUENCE.
*/
totalLen = outputLen;
#if VT_64_BIT_LENGTH == 64
outputLen += (VtUInt64)VoltDetermineDerLengthLen (
(UInt32)outputLen, (UInt32)(outputLen >> 32));
#else
outputLen += VoltDetermineDerLengthLen ((UInt32)outputLen, (UInt32)0);
#endif
outputLen++;
#if VT_64_BIT_LENGTH == 64
/* Save the output len so we can return it if need be.
*/
obj->outputLen64 = outputLen;
#endif
/* If the actual inputLen is not the same as what the total input
* len is going to be, subtract off the encryptedDataLen, then add
* the actual inputLen.
*/
#if VT_64_BIT_LENGTH == 64
if ((VtUInt64)inputDataLen != obj->dataLen64)
{
outputLen -= encryptedDataLen;
index = inputDataLen / envCtx->blockSize;
tempLen = index * envCtx->blockSize;
outputLen += (VtUInt64)tempLen;
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
if (inputDataLen != obj->dataLen)
{
outputLen -= encryptedDataLen;
index = inputDataLen / envCtx->blockSize;
tempLen = index * envCtx->blockSize;
outputLen += tempLen;
}
*messageLen = (UInt32)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 < outputLen)
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, write out 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 EnvelopedData OID.
*/
offset += VoltWriteDerTagAndLen (
message + offset, 0x06, (UInt32)VoltP7EnvDataOidBytesLen, (UInt32)0);
Z2Memcpy (message + offset, envDataOid, VoltP7EnvDataOidBytesLen);
offset += VoltP7EnvDataOidBytesLen;
/* EXPLICIT and SEQUENCE
*/
#if VT_64_BIT_LENGTH == 64
offset += VoltWriteDerTagAndLen (
message + offset, 0xA0, (UInt32)expLen, (UInt32)(expLen >> 32));
offset += VoltWriteDerTagAndLen (
message + offset, 0x30, (UInt32)seqLen, (UInt32)(seqLen >> 32));
#else
offset += VoltWriteDerTagAndLen (
message + offset, 0xA0, (UInt32)expLen, (UInt32)0);
offset += VoltWriteDerTagAndLen (
message + offset, 0x30, (UInt32)seqLen, (UInt32)0);
#endif
/* version (we support only version 0).
*/
message[offset] = 0x02;
offset++;
message[offset] = 0x01;
offset++;
message[offset] = 0x00;
offset++;
/* SET OF.
*/
offset += VoltWriteDerTagAndLen (
message + offset, 0x31,
(UInt32)(envCtx->totalRecipInfoLen), (UInt32)0);
/* Write out each of the RecipientInfos.
*/
for (index = 0; index < envCtx->recipientsCount; ++index)
{
if (envCtx->recipients[index].recipInfoLen == 0)
continue;
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_INVALID_INPUT;
temp = message + offset;
recipOutLen = i2d_Asn1RecipientInfo (
envCtx->recipients[index].recipInfo, &temp);
if (recipOutLen != envCtx->recipients[index].recipInfoLen)
break;
offset += recipOutLen;
status = 0;
}
if (status != 0)
break;
/* Next is the EncryptedContentInfo.
*/
#if VT_64_BIT_LENGTH == 64
offset += VoltWriteDerTagAndLen (
message + offset, 0x30, (UInt32)encContentInfoLen,
(UInt32)(encContentInfoLen >> 32));
#else
offset += VoltWriteDerTagAndLen (
message + offset, 0x30, (UInt32)encContentInfoLen, (UInt32)0);
#endif
/* The OID of the data being encrypted: Data.
*/
offset += VoltWriteDerTagAndLen (
message + offset, 0x06, (UInt32)VoltP7DataOidBytesLen, (UInt32)0);
Z2Memcpy (message + offset, dataOid, VoltP7DataOidBytesLen);
offset += VoltP7DataOidBytesLen;
/* The symmetric algorithm ID.
*/
Z2Memcpy (
message + offset, envCtx->symEncryptorAlgId.data,
envCtx->symEncryptorAlgId.len);
offset += envCtx->symEncryptorAlgId.len;
/* EncryptedContent, IMPLICIT.
*/
#if VT_64_BIT_LENGTH == 64
offset += VoltWriteDerTagAndLen (
message + offset, 0x80, (UInt32)encryptedDataLen,
(UInt32)(encryptedDataLen >> 32));
#else
offset += VoltWriteDerTagAndLen (
message + offset, 0x80, (UInt32)encryptedDataLen, (UInt32)0);
#endif
}
else if (obj->state == VOLT_P7_STATE_ENV_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?
*/
*messageLen = 0;
status = 0;
if (inputDataLen == 0)
break;
tempLen = inputDataLen + envCtx->unprocessedDataLen;
/* If this is the last of the input data, we'll call
* EncryptFinal, if not, we'll call EncryptUpdate.
*/
#if VT_64_BIT_LENGTH == 64
if (((VtUInt64)inputDataLen + obj->inputLen64) < obj->dataLen64)
#else
if ((inputDataLen + obj->inputLen) < obj->dataLen)
#endif
{
/* For the moment, this does not work with NULL input, so
* compute the required output size explicitly.
*/
/* status = VtEncryptUpdate (
envCtx->symEncryptor, random, (unsigned char *)0, inputDataLen,
(unsigned char *)0, 0, &tempLen);
*/
index = tempLen / envCtx->blockSize;
tempLen = index * envCtx->blockSize;
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_BUFFER_TOO_SMALL;
}
else
{
/* For the moment, this does not work with NULL input, so
* compute the required output size explicitly.
*/
/* status = VtEncryptFinal (
envCtx->symEncryptor, random, inputData, inputDataLen,
(unsigned char *)0, 0, &tempLen);
*/
index = tempLen / envCtx->blockSize;
if (envCtx->blockSize != 1)
index++;
tempLen = index * envCtx->blockSize;
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_BUFFER_TOO_SMALL;
}
if (status == 0)
status = VT_ERROR_GENERAL;
if (status != VT_ERROR_BUFFER_TOO_SMALL)
break;
*messageLen = tempLen;
if (bufferSize < tempLen)
break;
/* If the caller passed NULL input with non-zero inputLen, they
* just wanted the length, don't process.
*/
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
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;
}
/* Encrypt the bytes given.
*/
#if VT_64_BIT_LENGTH == 64
if (((VtUInt64)inputDataLen + obj->inputLen64) < obj->dataLen64)
#else
if ((inputDataLen + obj->inputLen) < obj->dataLen)
#endif
{
/* For the moment we need to compute unprocessedDataLen. When we
* fix the NULL input issue, we can get rid of this.
*/
tempLen = inputDataLen + envCtx->unprocessedDataLen;
index = tempLen / envCtx->blockSize;
envCtx->unprocessedDataLen = tempLen - (index * envCtx->blockSize);
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = VtEncryptUpdate (
envCtx->symEncryptor, random, inputData, inputDataLen,
message + offset, bufferSize - offset, &tempLen);
}
else
{
envCtx->unprocessedDataLen = 0;
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = VtEncryptFinal (
envCtx->symEncryptor, random, inputData, inputDataLen,
message + offset, bufferSize - offset, &tempLen);
}
if (status != 0)
break;
#if VT_64_BIT_LENGTH == 64
obj->inputLen64 += (VtUInt64)inputDataLen;
#else
obj->inputLen += inputDataLen;
#endif
obj->state = VOLT_P7_STATE_ENV_WRITE_UPDATE;
} while (0);
VOLT_LOG_ERROR_INFO_COMPARE (
status, 0, pkcs7Obj, status, 0, errorType,
(char *)0, "VoltP7EnvWriteUpdate", fnctLine, (char *)0)
return (status);
}
int VoltP7EnvWriteFinal (
VtPkcs7Object pkcs7Obj,
VtRandomObject random,
unsigned char *inputData,
unsigned int inputDataLen,
unsigned char *message,
unsigned int bufferSize,
unsigned int *messageLen
)
{
int status;
VoltPkcs7Object *obj = (VoltPkcs7Object *)pkcs7Obj;
VOLT_DECLARE_ERROR_TYPE (errorType)
VOLT_DECLARE_FNCT_LINE (fnctLine)
*messageLen = 0;
do
{
/* If there's no "predicted" len yet, the input len from this call
* is that length.
*/
#if VT_64_BIT_LENGTH == 64
if (obj->dataLen64 == 0)
obj->dataLen64 = (VtUInt64)inputDataLen;
#else
if (obj->dataLen == 0)
obj->dataLen = inputDataLen;
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -