📄 writeenvtype.c
字号:
/* Copyright 2003-2006, Voltage Security, all rights reserved.
*/
#include "vibe.h"
#include "environment.h"
#include "base.h"
#include "libctx.h"
#include "p7obj.h"
#include "idobj.h"
#include "derhelp.h"
#include "oidlist.h"
#include "errorctx.h"
/* Generate an init vector.
* <p>The caller has the option of passing in a random object to use
* when generating the IV. If the caller passes NULL, we'll look in the
* libCtx for a random object. If there's none there, we'll just use
* time of day as the seed.
* <p>This function will build a SHA-1 object, then digest some output
* from the caller-supplied random (if there is one), then the time of
* day. It will then place the first initVectorLen bytes of the digest
* into the initVector buffer.
* <p>If the init vector is longer than 20 bytes (no such IV's yet, but
* just in case), use the digest result as the first 20 bytes of IV,
* then digest the digest to get the next block of bytes. And so on.
*/
static int VOLT_CALLING_CONV GenerateInitVector VOLT_PROTO_LIST ((
VoltLibCtx *libCtx,
VtRandomObject random,
unsigned char *initVector,
unsigned int initVectorLen
));
int VtPkcs7ImplWriteEnvelopeIBE (
VtPkcs7Object *object,
Pointer info,
unsigned int flag
)
{
int status;
unsigned int bufferSize;
VoltPkcs7Object *obj = (VoltPkcs7Object *)(*object);
VoltLibCtx *libCtx = (VoltLibCtx *)(obj->voltObject.libraryCtx);
unsigned char *buffer = (unsigned char *)0;
VoltPkcs7WriteEnvCtx *envCtx = (VoltPkcs7WriteEnvCtx *)0;
VOLT_DECLARE_FNCT_LINE (fnctLine)
do
{
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_INVALID_TYPE;
if (flag != VOLT_PKCS7_SET_TYPE_FLAG)
break;
/* Make sure the object is empty.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_INVALID_P7_OBJ;
if ( (obj->contentType != 0) || (obj->localCtx != (Pointer)0) )
break;
/* Check the info, we're expecting NULL.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_INVALID_ASSOCIATED_INFO;
if (info != (Pointer)0)
break;
/* Build the local ctx.
*/
bufferSize = sizeof (VoltPkcs7WriteEnvCtx);
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_MEMORY;
buffer = (unsigned char *)Z2Malloc (bufferSize, 0);
if (buffer == (unsigned char *)0)
break;
Z2Memset (buffer, 0, bufferSize);
/* Locate the struct.
*/
envCtx = (VoltPkcs7WriteEnvCtx *)buffer;
/* Fill in fields.
*/
obj->state = VOLT_P7_STATE_ENV_WRITE_SET;
obj->localCtx = (Pointer)envCtx;
obj->LocalCtxDestroy = VoltWriteEnvCtxDestroy;
obj->contentType = VT_PKCS7_ENVELOPED_DATA;
obj->WriteInit = VoltP7EnvWriteInit;
obj->WriteUpdate = VoltP7EnvWriteUpdate;
obj->WriteFinal = VoltP7EnvWriteFinal;
status = 0;
} while (0);
/* If success, we're done.
*/
if (status == 0)
return (0);
/* If error, destroy what we created.
*/
if (buffer != (unsigned char *)0)
Z2Free (buffer);
VOLT_LOG_ERROR_INFO (
0, *object, status, 0, VT_ERROR_TYPE_PRIMARY,
(char *)0, "VtPkcs7ImplWriteEnvelopeIBE", fnctLine, (char *)0)
return (status);
}
void VoltWriteEnvCtxDestroy (
Pointer obj,
Pointer ctx
)
{
unsigned int index;
VoltObject *voltObj = (VoltObject *)obj;
VoltLibCtx *libCtx;
VoltPkcs7WriteEnvCtx *envCtx = (VoltPkcs7WriteEnvCtx *)ctx;
/* Anything to destroy?
*/
if ( (obj == (Pointer)0) || (ctx == (Pointer)0) )
return;
libCtx = (VoltLibCtx *)(voltObj->libraryCtx);
for (index = 0; index < envCtx->recipientsCount; ++index)
{
VtDestroyAlgorithmObject (&(envCtx->recipients[index].asymEncryptor));
VtDestroyKeyObject (&(envCtx->recipients[index].asymKey));
Asn1RecipientInfo_free (envCtx->recipients[index].recipInfo);
}
if (envCtx->recipients != (VoltRecipientData *)0)
Z2Free (envCtx->recipients);
if (envCtx->symEncryptorAlgId.data != (unsigned char *)0)
Z2Free (envCtx->symEncryptorAlgId.data);
VtDestroyKeyObject (&(envCtx->symKey));
VtDestroyAlgorithmObject (&(envCtx->symEncryptor));
VtDestroyIdentityList (&(envCtx->recipList));
Z2Free (ctx);
}
int VtPkcs7ParamEnv3DESCBC (
VtPkcs7Object pkcs7Obj,
Pointer info,
unsigned int flag
)
{
int status;
VoltPkcs7Object *obj = (VoltPkcs7Object *)pkcs7Obj;
VoltLibCtx *libCtx = (VoltLibCtx *)(obj->voltObject.libraryCtx);
VtRandomObject getRandom = (VtRandomObject)0;
VoltPkcs7WriteEnvCtx *envCtx = (VoltPkcs7WriteEnvCtx *)(obj->localCtx);
VtBlockCipherInfo blockCipherInfo;
VtItem ivItem;
unsigned char tdesAlgId[22] =
{
0x30, 0x14, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86,
0xf7, 0x0d, 0x03, 0x07, 0x04, 0x08, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
VOLT_DECLARE_ERROR_TYPE (errorType)
VOLT_DECLARE_FNCT_LINE (fnctLine)
do
{
/* This Param cannot get info.
*/
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_INVALID_GET;
if (flag == VOLT_PKCS7_GET_TYPE_FLAG)
break;
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_INVALID_TYPE;
if (flag != VOLT_PKCS7_SET_TYPE_FLAG)
break;
/* The P7 object must be set to write EnvelopedData.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_INVALID_P7_OBJ;
if (obj->contentType != VT_PKCS7_ENVELOPED_DATA)
break;
/* The P7 object must not be set with a symmetric algorithm yet.
*/
VOLT_SET_FNCT_LINE (fnctLine)
if (envCtx->symEncryptor != (VtAlgorithmObject)0)
break;
/* The info should be a random object or NULL.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_INVALID_ASSOCIATED_INFO;
if (info != (Pointer)0)
{
getRandom = (VtRandomObject)info;
if (VOLT_OBJECT_TYPE_NOT_EQUAL (info, VOLT_OBJECT_TYPE_RANDOM))
break;
}
else
{
status = VtGetLibCtxParam (
libCtx, VtLibCtxParamRandomObj, (Pointer *)&getRandom);
if (status != 0)
getRandom = (VtRandomObject)0;
}
/* Generate an IV.
*/
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = GenerateInitVector (libCtx, getRandom, tdesAlgId + 14, 8);
if (status != 0)
break;
ivItem.data = tdesAlgId + 14;
ivItem.len = 8;
/* Build the symmetric encryption object.
*/
blockCipherInfo.feedback = VtFeedbackCBC;
blockCipherInfo.feedbackInfo = (Pointer)&ivItem;
blockCipherInfo.padding = VtPaddingPkcs5;
blockCipherInfo.paddingInfo = (Pointer)0;
VOLT_SET_FNCT_LINE (fnctLine)
status = VtCreateAlgorithmObject (
(VtLibCtx)libCtx, VtAlgorithmImpl3DESEDE, (Pointer)&blockCipherInfo,
&(envCtx->symEncryptor));
if (status != 0)
break;
envCtx->blockSize = 8;
envCtx->SymKeyParam = VtKeyParamTripleDES;
envCtx->symKeyBits = 192;
/* Copy the algId.
*/
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_MEMORY;
envCtx->symEncryptorAlgId.data = (unsigned char *)Z2Realloc (
envCtx->symEncryptorAlgId.data, sizeof (tdesAlgId));
if (envCtx->symEncryptorAlgId.data == (unsigned char *)0)
break;
Z2Memcpy (envCtx->symEncryptorAlgId.data, tdesAlgId, sizeof (tdesAlgId));
envCtx->symEncryptorAlgId.len = sizeof (tdesAlgId);
status = 0;
} while (0);
VOLT_LOG_ERROR_INFO_COMPARE (
status, 0, pkcs7Obj, status, 0, errorType,
(char *)0, "VtPkcs7ParamEnv3DESCBC", fnctLine, (char *)0)
return (status);
}
int VtPkcs7ParamEnvAES128CBC (
VtPkcs7Object pkcs7Obj,
Pointer info,
unsigned int flag
)
{
int status;
VoltPkcs7Object *obj = (VoltPkcs7Object *)pkcs7Obj;
VoltLibCtx *libCtx = (VoltLibCtx *)(obj->voltObject.libraryCtx);
VtRandomObject getRandom = (VtRandomObject)0;
VoltPkcs7WriteEnvCtx *envCtx = (VoltPkcs7WriteEnvCtx *)(obj->localCtx);
VtBlockCipherInfo blockCipherInfo;
VtItem ivItem;
unsigned char aesAlgId[31] =
{
0x30, 0x1D, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
0x65, 0x03, 0x04, 0x01, 0x02, 0x04, 0x10, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
VOLT_DECLARE_ERROR_TYPE (errorType)
VOLT_DECLARE_FNCT_LINE (fnctLine)
do
{
/* This Param cannot get info.
*/
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_INVALID_GET;
if (flag == VOLT_PKCS7_GET_TYPE_FLAG)
break;
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_INVALID_TYPE;
if (flag != VOLT_PKCS7_SET_TYPE_FLAG)
break;
/* The P7 object must be set to write EnvelopedData.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_INVALID_P7_OBJ;
if (obj->contentType != VT_PKCS7_ENVELOPED_DATA)
break;
/* The P7 object must not be set with a symmetric algorithm yet.
*/
VOLT_SET_FNCT_LINE (fnctLine)
if (envCtx->symEncryptor != (VtAlgorithmObject)0)
break;
/* The info should be a random object or NULL.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_INVALID_ASSOCIATED_INFO;
if (info != (Pointer)0)
{
getRandom = (VtRandomObject)info;
if (VOLT_OBJECT_TYPE_NOT_EQUAL (info, VOLT_OBJECT_TYPE_RANDOM))
break;
}
else
{
status = VtGetLibCtxParam (
libCtx, VtLibCtxParamRandomObj, (Pointer *)&getRandom);
if (status != 0)
getRandom = (VtRandomObject)0;
}
/* Generate an IV.
*/
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = GenerateInitVector (libCtx, getRandom, aesAlgId + 15, 16);
if (status != 0)
break;
ivItem.data = aesAlgId + 15;
ivItem.len = 16;
/* Build the symmetric encryption object.
* Note that we're padding following PKCS #5. The symmetric algID
* contains the OID for AES-128-CBC which is an OID that says "do
* not pad". However, we're padding. That's because P7 specifies
* padding following P5.
*/
blockCipherInfo.feedback = VtFeedbackCBC;
blockCipherInfo.feedbackInfo = (Pointer)&ivItem;
blockCipherInfo.padding = VtPaddingPkcs5;
blockCipherInfo.paddingInfo = (Pointer)0;
VOLT_SET_FNCT_LINE (fnctLine)
status = VtCreateAlgorithmObject (
(VtLibCtx)libCtx, VtAlgorithmImplAES, (Pointer)&blockCipherInfo,
&(envCtx->symEncryptor));
if (status != 0)
break;
envCtx->blockSize = 16;
envCtx->SymKeyParam = VtKeyParamAES;
envCtx->symKeyBits = 128;
/* Copy the algId.
*/
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_MEMORY;
envCtx->symEncryptorAlgId.data = (unsigned char *)Z2Realloc (
envCtx->symEncryptorAlgId.data, sizeof (aesAlgId));
if (envCtx->symEncryptorAlgId.data == (unsigned char *)0)
break;
Z2Memcpy (envCtx->symEncryptorAlgId.data, aesAlgId, sizeof (aesAlgId));
envCtx->symEncryptorAlgId.len = sizeof (aesAlgId);
status = 0;
} while (0);
VOLT_LOG_ERROR_INFO_COMPARE (
status, 0, pkcs7Obj, status, 0, errorType,
(char *)0, "VtPkcs7ParamEnvAES128CBC", fnctLine, (char *)0)
return (status);
}
static int GenerateInitVector (
VoltLibCtx *libCtx,
VtRandomObject random,
unsigned char *initVector,
unsigned int initVectorLen
)
{
int status;
unsigned int offset, digestLen, currentLen;
VtAlgorithmObject sha1 = (VtAlgorithmObject)0;
unsigned char digest[20];
VtTime theTime;
VOLT_DECLARE_FNCT_LINE (fnctLine)
do
{
/* We need an IV for the CBC, CFB or OFB. Because the IV is public,
* there's no need to generate it from a strongly seeded random
* bytes. But we do want a different IV for each message. So we'll
* digest some output from the caller-supplied random and the time
* of day as a weak-seed PRNG.
*/
if (random != (VtRandomObject)0)
{
VOLT_SET_FNCT_LINE (fnctLine)
status = VtGenerateRandomBytes (random, digest, 20);
if (status != 0)
break;
}
VtGetTime ((VtLibCtx)libCtx, &theTime);
VOLT_SET_FNCT_LINE (fnctLine)
status = VtCreateAlgorithmObject (
(VtLibCtx)libCtx, VtAlgorithmImplSHA1, (Pointer)0, &sha1);
if (status != 0)
break;
/* This do-while loop will generate bytes until we have enough.
*/
offset = 0;
do
{
/* Generate 20 bytes of IV, unless we need fewer than 20 bytes.
*/
currentLen = 20;
if (initVectorLen <= 20)
currentLen = initVectorLen;
VOLT_SET_FNCT_LINE (fnctLine)
status = VtDigestInit (sha1);
if (status != 0)
break;
/* For the first loop, the digest buffer either contains the
* result of the GenerateRandomBytes, or whatever was on the
* stack at the time of the call (if no random is supplied).
* For subsequent loops, it contains the result of the previous
* digest.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = VtDigestUpdate (sha1, digest, 20);
if (status != 0)
break;
VOLT_SET_FNCT_LINE (fnctLine)
status = VtDigestFinal (
sha1, (unsigned char *)&theTime, sizeof (theTime),
digest, 20, &digestLen);
if (status != 0)
break;
Z2Memcpy (initVector + offset, digest, currentLen);
initVectorLen -= currentLen;
/* If there are no more bytes to generate, break out of this loop.
*/
if (initVectorLen == 0)
break;
/* Prepare for the next loop.
*/
offset += currentLen;
} while (1);
} while (0);
VtDestroyAlgorithmObject (&sha1);
VOLT_LOG_ERROR_INFO_COMPARE (
status, libCtx, 0, status, 0, 0,
(char *)0, "GenerateInitVector", fnctLine, (char *)0)
return (status);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -