⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 writeenvtype.c

📁 IBE是一种非对称密码技术
💻 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 + -