📄 writeenv.c
字号:
do
{
/* If there's no "predicted" len yet, the input len from this call
* is that length.
*/
if (obj->dataLen == 0)
obj->dataLen = inputDataLen;
/* The state must be INIT or UPDATE.
*/
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.
*/
status = VT_ERROR_INVALID_INPUT_LENGTH;
if ((inputDataLen + obj->inputLen) != obj->dataLen)
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.
*/
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);
return (status);
}
static int VoltBuildRecipientData (
VoltPkcs7Object *p7Obj,
VtRandomObject random,
VtAlgorithmObject base64,
unsigned char *symKeyData,
unsigned int symKeyDataLen,
VoltRecipientData *recipientData
)
{
int status;
unsigned int issuerSerialLen, encryptedKeyLen;
VoltLibCtx *libCtx = (VoltLibCtx *)(p7Obj->voltObject.libraryCtx);
VoltIdentityObject *idObj;
unsigned char *issuerSerial = (unsigned char *)0;
unsigned char *encryptedKey = (unsigned char *)0;
VoltSurrenderCtx *surrCtx = (VoltSurrenderCtx *)0;
VtSurrenderCallback surrenderCtx;
unsigned char ibeAlgId[VoltIBET1EncAlgIdBytesLen] =
{ VoltIBET1EncAlgIdBytes };
do
{
/* Build the IssuerSerial construct.
*/
status = VoltBuildIssuerSerialAlloc (
libCtx, recipientData->idRef, base64, &issuerSerial, &issuerSerialLen);
if (status != 0)
break;
idObj = (VoltIdentityObject *)(recipientData->idRef);
/* Build the algorithm object that will encrypt the key.
*/
status = VtCreateAlgorithmObject (
(VtLibCtx)libCtx, VtAlgorithmImplBFType1IBE, (Pointer)0,
&(recipientData->asymEncryptor));
if (status != 0)
break;
/* If there's a surrender ctx, pass it on to the encryptor.
*/
if ( ((p7Obj->voltObject.objectType & VOLT_OBJECT_TYPE_SURRENDER) != 0) &&
(p7Obj->voltObject.surrenderCtx != (Pointer)0) )
{
surrCtx = (VoltSurrenderCtx *)(p7Obj->voltObject.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;
status = VtSetAlgorithmParam (
recipientData->asymEncryptor, VtAlgorithmParamSurrenderCallback,
(Pointer)&surrenderCtx);
if (status != 0)
break;
}
/* Build the key object from the identity.
*/
status = VtCreateKeyObject (
(VtLibCtx)libCtx, VtKeyImplMpCtx, (Pointer)(idObj->mpCtx),
&(recipientData->asymKey));
if (status != 0)
break;
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.
*/
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.
*/
status = VT_ERROR_MEMORY;
encryptedKey = (unsigned char *)Z2Malloc (encryptedKeyLen, 0);
if (encryptedKey == (unsigned char *)0)
break;
status = VtEncryptFinal (
recipientData->asymEncryptor, random, symKeyData, symKeyDataLen,
encryptedKey, encryptedKeyLen, &encryptedKeyLen);
if (status != 0)
break;
/* Create the ASN.1 object that is the recipientInfo.
*/
status = VT_ERROR_MEMORY;
recipientData->recipInfo = Asn1RecipientInfo_new ();
if (recipientData->recipInfo == (Asn1RecipientInfo *)0)
break;
/* Set fields we can set.
*/
status = VT_ERROR_MEMORY;
if (ASN1_INTEGER_set (recipientData->recipInfo->version, 0) != 1)
break;
if (Asn1Encoded_set (
recipientData->recipInfo->issuerSerial,
issuerSerial, issuerSerialLen) != 1)
break;
if (Asn1Encoded_set (
recipientData->recipInfo->keyEncAlg, ibeAlgId,
VoltIBET1EncAlgIdBytesLen) != 1)
break;
if (ASN1_OCTET_STRING_set (
recipientData->recipInfo->encryptedKey,
encryptedKey, encryptedKeyLen) != 1)
break;
/* How long will the RecipientInfo be?
*/
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);
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 };
do
{
status = VtEncodeInit (base64);
if (status != 0)
break;
/* How big does the output buffer need to be?
*/
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 (encodingLen) + 1 + encodingLen;
/* How big will the Attribute sequence be?
* 30 len
* 06 03 55 04 29
* 0c len <data>
*/
attrLen = totalLen + 5;
totalLen += VoltDetermineDerLengthLen (attrLen) + 6;
/* How big will the SET OF be?
*/
setLen = totalLen;
totalLen += VoltDetermineDerLengthLen (setLen) + 1;
/* How big will the SEQUENCE OF RDN be?
*/
rdnLen = totalLen;
totalLen += VoltDetermineDerLengthLen (rdnLen) + 1;
/* The totalLen is the total SEQUENCE (which contains the SEQ OF
* and an INTEGER).
*/
seqLen = totalLen + 3;
totalLen += VoltDetermineDerLengthLen (seqLen) + 4;
/* Allocate the space.
*/
status = VT_ERROR_MEMORY;
buffer = (unsigned char *)Z2Malloc (totalLen, 0);
if (buffer == (unsigned char *)0)
break;
/* Place the first SEQ.
*/
offset = VoltWriteDerTagAndLen (buffer, 0x30, seqLen);
/* Place the RDN SEQ OF.
*/
offset += VoltWriteDerTagAndLen (buffer + offset, 0x30, rdnLen);
/* Place the SET OF.
*/
offset += VoltWriteDerTagAndLen (buffer + offset, 0x31, setLen);
/* Place the SEQUENCE (for Attribute).
*/
offset += VoltWriteDerTagAndLen (buffer + offset, 0x30, attrLen);
/* Place the OID.
*/
Z2Memcpy (buffer + offset, idAtNameOid, sizeof (idAtNameOid));
offset += sizeof (idAtNameOid);
/* Place the PrintableString tag and length.
*/
offset += VoltWriteDerTagAndLen (buffer + offset, 0x13, encodingLen);
/* Place the Base64 encoded ID.
*/
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);
return (status);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -