📄 readenv.c
字号:
status = VT_ERROR_CHOOSE_RECIPIENT;
if (readCtx->chosenRecipient < 0)
{
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
if (readCtx->priKeyRef == (VtKeyObject)0)
break;
/* We have a private key. Which identity belongs to that
* private key? We have to go through the recipInfos to find
* the ID matching the one passed in with the private key.
*/
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = VoltFindIdInList (
libCtx, readCtx->specifiedIdentity, readCtx->recipList, &index);
if (status != 0)
break;
/* Set the chosen recipient.
*/
readCtx->chosenRecipient = (int)index;
}
/* Build the symmetric decryption alg object and the symmetric
* key. This call will need to decrypt the session key in the
* RecipientInfo of the chosen recipient.
*/
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = DecryptSessionKeyData (libCtx, obj, readCtx);
if (status != 0)
break;
/* We have the session key data, set the state so we'll read
* encrypted content. Then check to see if there's any message to
* read.
*/
obj->state = VOLT_P7_STATE_ENV_READ_ENC_CONTENT;
if (messageLen == 0)
break;
case VOLT_P7_STATE_ENV_READ_ENC_CONTENT:
/* The first part of encrypted content is the SEQUENCE then an
* OID. "Cheat" by reading the SEQUENCE as the explicitTag.
*/
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = VoltGetNextDerElement (
libCtx, message, messageLen, VOLT_SEQUENCE_TAG, VOLT_OID_TAG, 1,
derElement, &messageRead);
if (status != 0)
break;
*bytesRead += messageRead;
if (derElement->complete == 0)
break;
/* Is this the Data OID?
* First, set the buffer containing the OID to hold the Data OID.
*/
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_UNSUPPORTED;
p7Oid[VoltP7SignDataOidBytesLen - 1] = VOLT_P7_OID_BYTE_DATA;
if (derElement->valueLen != VoltP7EnvDataOidBytesLen)
break;
if (Z2Memcmp (
p7Oid, derElement->element + 2, VoltP7EnvDataOidBytesLen) != 0)
break;
/* Move on to the next element.
*/
status = 0;
obj->state = VOLT_P7_STATE_ENV_READ_SYM_ALG_ID;
message += messageRead;
messageLen -= messageRead;
VoltResetDerElement (derElement);
if (messageLen == 0)
break;
case VOLT_P7_STATE_ENV_READ_SYM_ALG_ID:
/* Read the symmetric algID.
*/
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = VoltGetNextDerElement (
libCtx, message, messageLen, 0, VOLT_SEQUENCE_TAG, 1,
derElement, &messageRead);
if (status != 0)
break;
*bytesRead += messageRead;
if (derElement->complete == 0)
break;
/* Build an algorithm object using the algId in the RecipientInfo.
*/
algIdInfo.derCoders = readCtx->DerCoders;
algIdInfo.derCoderCount = readCtx->derCoderCount;
algIdInfo.berEncoding = derElement->element;
algIdInfo.maxEncodingLen = derElement->elementLen;
VOLT_SET_FNCT_LINE (fnctLine)
status = VtCreateAlgorithmObject (
(VtLibCtx)libCtx, VtAlgorithmImplAlgId, (Pointer)&algIdInfo,
&(readCtx->decryptor));
if (status != 0)
break;
/* Copy the algId into the object in case we need it later.
*/
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_MEMORY;
readCtx->symAlgID = (unsigned char *)Z2Realloc (
readCtx->symAlgID, derElement->elementLen);
if (readCtx->symAlgID == (unsigned char *)0)
break;
Z2Memcpy (
readCtx->symAlgID, derElement->element, derElement->elementLen);
readCtx->symAlgIDLen = derElement->elementLen;
/* Get the KeyParam to use when building a key object. Do this by
* calling the DerCoder's asking for the algorithm.
*/
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
offset = derElement->elementLen - (unsigned int)(derElement->valueLen);
status = VoltDecodeTagAndLen (
libCtx, derElement->element + offset, derElement->elementLen - offset,
&theTag, &lengthLen, &lenLo, &lenHi, sizeof (unsigned int));
if (status != 0)
break;
valueLen = (unsigned int)lenLo;
coderInfo.info.getAlgData.libCtx = libCtx;
coderInfo.info.getAlgData.oid =
derElement->element + offset + lengthLen + 1;
coderInfo.info.getAlgData.oidLen = valueLen;
coderInfo.info.getAlgData.algorithm = &algorithm;
coderInfo.info.getAlgData.SymKeyParam = (VtKeyParam *)0;
coderInfo.info.getAlgData.DigestImpl = (VtAlgorithmImpl *)0;
for (index = 0; index < readCtx->derCoderCount; ++index)
{
/* Call the DerCoder. If successful, we found what we were
* looking for.
*/
status = readCtx->DerCoders[index] (
&coderInfo, (Pointer)0, VOLT_DER_TYPE_GET_ALG_FLAG);
if (status == 0)
break;
}
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_UNKNOWN_BER;
if (index >= readCtx->derCoderCount)
break;
/* Build a key object using the decrypted key data.
*/
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = VtCreateKeyObject (
(VtLibCtx)libCtx, VtKeyImplDefault, (Pointer)0, &symKey);
if (status != 0)
break;
VOLT_SET_FNCT_LINE (fnctLine)
status = VtSetKeyParam (
symKey, coderInfo.info.getAlgData.SymKeyParam,
(Pointer)&(readCtx->symKeyData));
if (status != 0)
break;
/* DecryptInit to start the process.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = VtDecryptInit (readCtx->decryptor, symKey);
if (status != 0)
break;
/* Move on to the next element.
*/
obj->state = VOLT_P7_STATE_ENV_READ_ENC_DATA_LEN;
message += messageRead;
messageLen -= messageRead;
VoltResetDerElement (derElement);
if (messageLen == 0)
break;
case VOLT_P7_STATE_ENV_READ_ENC_DATA_LEN:
/* The length of the encrypted data is specified in the IMPLICIT
* OCTET STRING.
*/
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = VoltGetNextDerElement (
libCtx, message, messageLen, 0, 0x80, 0,
derElement, &messageRead);
if (status != 0)
break;
*bytesRead += messageRead;
if (derElement->complete == 0)
break;
/* Keep the length so we can count off the data as it is input.
*/
readCtx->dataLen = derElement->valueLen;
/* Move on to the next element.
*/
obj->state = VOLT_P7_STATE_ENV_READ_ENC_DATA;
message += messageRead;
messageLen -= messageRead;
VoltResetDerElement (derElement);
if (messageLen == 0)
break;
case VOLT_P7_STATE_ENV_READ_ENC_DATA:
/* If the length of the message is > the length of the
* currentLen, ignore the "extra" stuff.
*/
#if VT_64_BIT_LENGTH == 64
valueLen = 0xffffffff;
if (readCtx->dataLen < (VtUInt64)0xffffffff)
valueLen = (unsigned int)(readCtx->dataLen);
#else
valueLen = readCtx->dataLen;
#endif
if (messageLen <= valueLen)
valueLen = messageLen;
/* If we won't process all the data, call EncryptUpdate. Return
* all errors, even if BUFFER_TOO_SMALL.
* If this is the last chunk of data, call DecryptFinal.
*/
#if VT_64_BIT_LENGTH == 64
if ((readCtx->dataLen - (VtUInt64)valueLen) != 0)
#else
if ((readCtx->dataLen - valueLen) != 0)
#endif
{
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = VtDecryptUpdate (
readCtx->decryptor, (VtRandomObject)0, message, valueLen,
outputData, bufferSize, outputDataLen);
if (status != 0)
break;
}
else
{
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = VtDecryptFinal (
readCtx->decryptor, (VtRandomObject)0, message, valueLen,
outputData, bufferSize, outputDataLen);
if (status != 0)
break;
}
/* If the Decrypt succeeded, move bytesRead up and currentLen
* down.
*/
#if VT_64_BIT_LENGTH == 64
readCtx->dataLen -= (VtUInt64)valueLen;
#else
readCtx->dataLen -= valueLen;
#endif
*bytesRead += valueLen;
/* If there's no more data to read, change the state.
*/
if (readCtx->dataLen == 0)
obj->state = VOLT_P7_STATE_ENV_READ_COMPLETE;
status = 0;
}
VtDestroyKeyObject (&symKey);
VOLT_LOG_ERROR_INFO_COMPARE (
status, 0, pkcs7Obj, status, 0, errorType,
(char *)0, "VoltP7ReadEnvelopedUpdate", fnctLine, (char *)0)
return (status);
}
int VoltP7ReadEnvelopedFinal (
VtPkcs7Object pkcs7Obj,
unsigned char *message,
unsigned int messageLen,
unsigned int *bytesRead,
unsigned char *outputData,
unsigned int bufferSize,
unsigned int *outputDataLen
)
{
int status;
VoltPkcs7Object *obj = (VoltPkcs7Object *)pkcs7Obj;
VOLT_DECLARE_ERROR_TYPE (errorType)
VOLT_DECLARE_FNCT_LINE (fnctLine)
*bytesRead = 0;
*outputDataLen = 0;
do
{
/* If we're done, there's nothing to do.
*/
if (obj->state == VOLT_P7_STATE_ENV_READ_COMPLETE)
{
obj->state = VOLT_P7_STATE_ENV_READ_FINAL;
status = 0;
break;
}
/* If we're not done, try to finish.
*/
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_INVALID_INPUT_LENGTH;
if (messageLen == 0)
break;
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = VoltP7ReadEnvelopedUpdate (
pkcs7Obj, message, messageLen, bytesRead,
outputData, bufferSize, outputDataLen);
if (status != 0)
break;
/* Are we finished now?
*/
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_INVALID_INPUT_LENGTH;
if (obj->state != VOLT_P7_STATE_ENV_READ_COMPLETE)
break;
obj->state = VOLT_P7_STATE_ENV_READ_FINAL;
status = 0;
} while (0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -