📄 writeenv.c
字号:
/* The state must be INIT or UPDATE.
*/
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_INVALID_CALL_ORDER;
if ( (obj->state != VOLT_P7_STATE_ENV_WRITE_INIT) &&
(obj->state != VOLT_P7_STATE_ENV_WRITE_UPDATE) )
break;
/* Make sure the total input len is the same as the "predicted" len.
*/
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;
/* If we reach this point and there is data to process, it is of
* the appropriate length. How big is WriteUpdate, then how big is
* DecryptFinal?
*/
if (inputDataLen != 0)
{
/* If the return from this call is not 0, it might be
* BUFFER_TOO_SMALL. But we'll pass that one along as well.
*/
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = VoltP7EnvWriteUpdate (
pkcs7Obj, random, inputData, inputDataLen,
message, bufferSize, messageLen);
if (status != 0)
break;
}
/* If we hit this point, we successfully finished writing the
* message.
*/
status = 0;
obj->state = VOLT_P7_STATE_ENV_WRITE_FINAL;
} while (0);
VOLT_LOG_ERROR_INFO_COMPARE (
status, 0, pkcs7Obj, status, 0, errorType,
(char *)0, "VoltP7EnvWriteFinal", fnctLine, (char *)0)
return (status);
}
int VoltBuildRecipientData (
VoltObject *obj,
VtRandomObject random,
VtAlgorithmObject base64,
VtDerCoder *ibeAlg,
unsigned char *symKeyData,
unsigned int symKeyDataLen,
VoltRecipientData *recipientData
)
{
int status;
unsigned int issuerSerialLen, encryptedKeyLen, encodingLen;
VoltLibCtx *libCtx = (VoltLibCtx *)(obj->libraryCtx);
VoltIdentityObject *idObj;
Asn1AlgorithmId *algIdObj = (Asn1AlgorithmId *)0;
unsigned char *issuerSerial = (unsigned char *)0;
unsigned char *encryptedKey = (unsigned char *)0;
VoltSurrenderCtx *surrCtx = (VoltSurrenderCtx *)0;
VtSurrenderCallback surrenderCtx;
VtDerCoderInfo coderInfo;
unsigned char ibeAlgId[VoltMaxIBEAlgIDLen];
VOLT_DECLARE_ERROR_TYPE (errorType)
VOLT_DECLARE_FNCT_LINE (fnctLine)
do
{
/* Build the IssuerSerial construct.
*/
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = VoltBuildIssuerSerialAlloc (
libCtx, recipientData->idRef, base64, &issuerSerial, &issuerSerialLen);
if (status != 0)
break;
idObj = (VoltIdentityObject *)(recipientData->idRef);
/* Which IBE alg should we use?
*/
coderInfo.info.encodeData.libCtx = libCtx;
coderInfo.info.encodeData.info = (Pointer)0;
coderInfo.info.encodeData.encoding = ibeAlgId;
coderInfo.info.encodeData.bufferSize = sizeof (ibeAlgId);
coderInfo.info.encodeData.encodingLen = &encodingLen;
VOLT_SET_FNCT_LINE (fnctLine)
status = ibeAlg (&coderInfo, (Pointer)0, VOLT_DER_TYPE_ENCODE_FLAG);
if (status != 0)
break;
/* To build an object using a DerCoder, we need the algId in the
* form of an Asn1AlgorithmId.
*/
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_MEMORY;
algIdObj = Asn1AlgorithmId_new ();
if (algIdObj == (Asn1AlgorithmId *)0)
break;
VOLT_SET_FNCT_LINE (fnctLine)
if (Asn1ObjectId_set (algIdObj->oid, ibeAlgId + 4, encodingLen - 6) != 1)
break;
/* To build an object using a DerCoder, we need to start with an
* empty object.
*/
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = VoltCreateObject (
(VtLibCtx)libCtx, (VoltObject **)&(recipientData->asymEncryptor),
sizeof (VoltAlgorithmObject), VOLT_OBJECT_TYPE_ALGORITHM);
if (status != 0)
break;
coderInfo.info.decodeData.type = VOLT_DER_TYPE_ALG_ID_FLAG;
coderInfo.info.decodeData.asn1Object = (Pointer)algIdObj;
coderInfo.info.decodeData.info = (Pointer)0;
VOLT_SET_FNCT_LINE (fnctLine)
status = ibeAlg (
&coderInfo, (Pointer)&(recipientData->asymEncryptor),
VOLT_DER_TYPE_DECODE_FLAG);
if (status != 0)
break;
/* If there's a surrender ctx, pass it on to the encryptor.
*/
if ( ((obj->objectType & VOLT_OBJECT_TYPE_SURRENDER) != 0) &&
(obj->surrenderCtx != (Pointer)0) )
{
surrCtx = (VoltSurrenderCtx *)(obj->surrenderCtx);
/* Set the encryption object with the surrender ctx, but don't copy
* the appData, just copy a reference, so we're still using the
* P7 object's appData.
*/
surrenderCtx.Surrender = surrCtx->Surrender;
surrenderCtx.appData = surrCtx->appData;
surrenderCtx.AppDataCopy = (VtSurrenderAppDataCopy)0;
surrenderCtx.AppDataFree = (VtSurrenderAppDataFree)0;
VOLT_SET_FNCT_LINE (fnctLine)
status = VtSetAlgorithmParam (
recipientData->asymEncryptor, VtAlgorithmParamSurrenderCallback,
(Pointer)&surrenderCtx);
if (status != 0)
break;
}
/* Build the key object from the identity.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = VtCreateKeyObject (
(VtLibCtx)libCtx, VtKeyImplMpCtx, (Pointer)(idObj->mpCtx),
&(recipientData->asymKey));
if (status != 0)
break;
VOLT_SET_FNCT_LINE (fnctLine)
status = VtBuildIBEPublicKey (
(VtIdentityObject)idObj, VT_ENCODE_IBCS_2_V_DISTRICT, (VtPolicyCtx)0,
(VtStorageCtx)0, (VtTransportCtx)0, recipientData->asymKey);
if (status != 0)
break;
/* Encrypt the key data.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = VtEncryptInit (
recipientData->asymEncryptor, recipientData->asymKey);
if (status != 0)
break;
/* First, how big is the output.
* Don't call this routine for now. The function will encrypt the
* data when determining size, then encrypt again when encrypting
* into caller-supplied buffer. So calculate "by hand".
* The length is primeLen + SHA-1 len + dataToEncryptLen. Use max
* prime len.
*/
/* status = VtEncryptFinal (
recipientData->asymEncryptor, random, symKeyData, symKeyDataLen,
(unsigned char *)0, 0, &encryptedKeyLen);
if (status == 0)
status = VT_ERROR_GENERAL;
if (status != VT_ERROR_BUFFER_TOO_SMALL)
break;
*/
encryptedKeyLen = 276 + symKeyDataLen;
/* Build the buffer into which we'll place the encrypted key.
*/
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_MEMORY;
encryptedKey = (unsigned char *)Z2Malloc (encryptedKeyLen, 0);
if (encryptedKey == (unsigned char *)0)
break;
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = VtEncryptFinal (
recipientData->asymEncryptor, random, symKeyData, symKeyDataLen,
encryptedKey, encryptedKeyLen, &encryptedKeyLen);
if (status != 0)
break;
/* Create the ASN.1 object that is the recipientInfo.
*/
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_MEMORY;
recipientData->recipInfo = Asn1RecipientInfo_new ();
if (recipientData->recipInfo == (Asn1RecipientInfo *)0)
break;
/* Set fields we can set.
*/
VOLT_SET_FNCT_LINE (fnctLine)
if (ASN1_INTEGER_set (recipientData->recipInfo->version, 0) != 1)
break;
VOLT_SET_FNCT_LINE (fnctLine)
if (Asn1Encoded_set (
recipientData->recipInfo->issuerSerial,
issuerSerial, issuerSerialLen) != 1)
break;
VOLT_SET_FNCT_LINE (fnctLine)
if (Asn1Encoded_set (
recipientData->recipInfo->keyEncAlg, ibeAlgId,
encodingLen) != 1)
break;
VOLT_SET_FNCT_LINE (fnctLine)
if (ASN1_OCTET_STRING_set (
recipientData->recipInfo->encryptedKey,
encryptedKey, encryptedKeyLen) != 1)
break;
/* How long will the RecipientInfo be?
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_INVALID_INPUT;
recipientData->recipInfoLen = i2d_Asn1RecipientInfo (
recipientData->recipInfo, (unsigned char **)0);
if (recipientData->recipInfoLen == 0)
break;
status = 0;
} while (0);
if (issuerSerial != (unsigned char *)0)
Z2Free (issuerSerial);
if (encryptedKey != (unsigned char *)0)
Z2Free (encryptedKey);
VOLT_LOG_ERROR_INFO_COMPARE (
status, 0, obj, status, 0, errorType,
(char *)0, "VoltBuildRecipientData", fnctLine, (char *)0)
return (status);
}
static int VoltBuildIssuerSerialAlloc (
VoltLibCtx *libCtx,
VtIdentityObject identity,
VtAlgorithmObject base64,
unsigned char **issuerSerial,
unsigned int *issuerSerialLen
)
{
int status;
unsigned int offset, totalLen;
unsigned int encodingLen, attrLen, setLen, rdnLen, seqLen;
VoltIdentityObject *idObj = (VoltIdentityObject *)identity;
unsigned char *buffer = (unsigned char *)0;
unsigned char idAtNameOid[VoltIdAtNameOidBytesLen + 2] =
{ 0x06, VoltIdAtNameOidBytesLen, VoltIdAtNameOidBytes };
VOLT_DECLARE_ERROR_TYPE (errorType)
VOLT_DECLARE_FNCT_LINE (fnctLine)
do
{
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = VtEncodeInit (base64);
if (status != 0)
break;
/* How big does the output buffer need to be?
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = VtEncodeFinal (
base64, (VtRandomObject)0, idObj->encoding.data,
idObj->encoding.len, (unsigned char *)0, 0, &encodingLen);
if (status == 0)
status = VT_ERROR_INVALID_INPUT;
if (status != VT_ERROR_BUFFER_TOO_SMALL)
break;
/* How big will the 0c len <data> be?
*/
totalLen =
VoltDetermineDerLengthLen ((UInt32)encodingLen, (UInt32)0) +
1 + encodingLen;
/* How big will the Attribute sequence be?
* 30 len
* 06 03 55 04 29
* 0c len <data>
*/
attrLen = totalLen + 5;
totalLen += VoltDetermineDerLengthLen ((UInt32)attrLen, (UInt32)0) + 6;
/* How big will the SET OF be?
*/
setLen = totalLen;
totalLen += VoltDetermineDerLengthLen ((UInt32)setLen, (UInt32)0) + 1;
/* How big will the SEQUENCE OF RDN be?
*/
rdnLen = totalLen;
totalLen += VoltDetermineDerLengthLen ((UInt32)rdnLen, (UInt32)0) + 1;
/* The totalLen is the total SEQUENCE (which contains the SEQ OF
* and an INTEGER).
*/
seqLen = totalLen + 3;
totalLen += VoltDetermineDerLengthLen ((UInt32)seqLen, (UInt32)0) + 4;
/* Allocate the space.
*/
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_MEMORY;
buffer = (unsigned char *)Z2Malloc (totalLen, 0);
if (buffer == (unsigned char *)0)
break;
/* Place the first SEQ.
*/
offset = VoltWriteDerTagAndLen (buffer, 0x30, (UInt32)seqLen, (UInt32)0);
/* Place the RDN SEQ OF.
*/
offset += VoltWriteDerTagAndLen (
buffer + offset, 0x30, (UInt32)rdnLen, (UInt32)0);
/* Place the SET OF.
*/
offset += VoltWriteDerTagAndLen (
buffer + offset, 0x31, (UInt32)setLen, (UInt32)0);
/* Place the SEQUENCE (for Attribute).
*/
offset += VoltWriteDerTagAndLen (
buffer + offset, 0x30, (UInt32)attrLen, (UInt32)0);
/* Place the OID.
*/
Z2Memcpy (buffer + offset, idAtNameOid, sizeof (idAtNameOid));
offset += sizeof (idAtNameOid);
/* Place the PrintableString tag and length.
*/
offset += VoltWriteDerTagAndLen (
buffer + offset, 0x13, (UInt32)encodingLen, (UInt32)0);
/* Place the Base64 encoded ID.
*/
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VtEncodeFinal (
base64, (VtRandomObject)0, idObj->encoding.data,
idObj->encoding.len, buffer + offset, totalLen - offset, &encodingLen);
if (status == VT_ERROR_BUFFER_TOO_SMALL)
status = VT_ERROR_INVALID_INPUT;
if (status != 0)
break;
offset += encodingLen;
/* Finally, place the 02 01 01.
*/
buffer[offset] = 2;
buffer[offset + 1] = 1;
buffer[offset + 2] = 1;
*issuerSerial = buffer;
*issuerSerialLen = totalLen;
} while (0);
/* If success, we're done.
*/
if (status == 0)
return (0);
/* If error, free up any memory.
*/
if (buffer != (unsigned char *)0)
Z2Free (buffer);
VOLT_LOG_ERROR_INFO (
libCtx, identity, status, 0, errorType,
(char *)0, "VoltBuildIssuerSerialAlloc", fnctLine, (char *)0)
return (status);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -