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

📄 ibekeyber.c

📁 IBE是一种非对称密码技术
💻 C
字号:
/* Copyright 2003-2006, Voltage Security, all rights reserved.
 */
#include "vibe.h"
#include "environment.h"
#include "base.h"
#include "libctx.h"
#include "keyobj.h"
#include "oidlist.h"
#include "algid.h"
#include "ibe.h"
#include "ibekeyber.h"
#include "prikeyder.h"
#include "errorctx.h"

/* Set up the OpenSSL ASN.1 templates.
 */
ASN1_SEQUENCE (Asn1IBEPrivateData) =
{
  ASN1_SIMPLE (Asn1IBEPrivateData, format, Asn1ObjectId),
  ASN1_SIMPLE (Asn1IBEPrivateData, value, ASN1_OCTET_STRING)
} ASN1_SEQUENCE_END (Asn1IBEPrivateData);

IMPLEMENT_ASN1_FUNCTIONS (Asn1IBEPrivateData)

ASN1_SEQUENCE (Asn1IBEPrivateKey) =
{
  ASN1_OPT (Asn1IBEPrivateKey, version, ASN1_INTEGER),
  ASN1_SIMPLE (Asn1IBEPrivateKey, privateData, Asn1IBEPrivateData),
  ASN1_OPT (Asn1IBEPrivateKey, pubKey, Asn1Encoded),
  ASN1_EXP_OPT (Asn1IBEPrivateKey, pubKeyDigest, Asn1Encoded, 0),
} ASN1_SEQUENCE_END (Asn1IBEPrivateKey);

IMPLEMENT_ASN1_FUNCTIONS (Asn1IBEPrivateKey)

int VoltEncodeIBEPrivateKeyData (
   VoltKeyObject *obj,
   VoltIBEPriKeyData *keyData
   )
{
  int status;
  unsigned int pointLen, offset, encodingLen;
  unsigned char *buffer = (unsigned char *)0;
  unsigned char *temp;
  VoltLibCtx *libCtx = (VoltLibCtx *)(obj->voltObject.libraryCtx);
  Asn1IBEPrivateKey *priKey = (Asn1IBEPrivateKey *)0;
  unsigned char keyOid[VoltIBEPriKeyForm2OidBytesLen] =
    { VoltIBEPriKeyForm2OidBytes };
  VOLT_DECLARE_FNCT_LINE (fnctLine)

  /* If it's already computed, do nothing.
   */
  if (obj->keyDer.data != (unsigned char *)0)
    return (0);

  do
  {
    /* Create the point, it needs to be
     *    04 <xcoord> <ycoord>
     * with both coordinates equal to the prime size.
     */
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VT_ERROR_MEMORY;
    pointLen = (keyData->primeLen * 2) + 1;
    buffer = (unsigned char *)Z2Malloc (pointLen, VOLT_MEMORY_SENSITIVE);
    if (buffer == (unsigned char *)0)
      break;
    Z2Memset (buffer, 0, pointLen);
    buffer[0] = 4;
    /* If the xCoord is not as big as the prime, make sure we have
     * leading 00 bytes.
     */
    offset = keyData->primeLen - keyData->bfKeyInfo.privatePoint.xCoord.len;
    offset++;
    Z2Memcpy (
      buffer + offset, keyData->bfKeyInfo.privatePoint.xCoord.data,
      keyData->bfKeyInfo.privatePoint.xCoord.len);

    /* Place the y-coordinate after x, leading 00 bytes if necessary.
     */
    offset += keyData->bfKeyInfo.privatePoint.xCoord.len;
    offset += (keyData->primeLen - keyData->bfKeyInfo.privatePoint.yCoord.len);
    Z2Memcpy (
      buffer + offset, keyData->bfKeyInfo.privatePoint.yCoord.data,
      keyData->bfKeyInfo.privatePoint.yCoord.len);

    /* Create the template.
     */
    VOLT_SET_FNCT_LINE (fnctLine)
    priKey = Asn1IBEPrivateKey_new ();
    if (priKey == (Asn1IBEPrivateKey *)0)
      break;

    VOLT_SET_FNCT_LINE (fnctLine)
    priKey->version = ASN1_INTEGER_new ();
    if (priKey->version == (ASN1_INTEGER *)0)
      break;

    /* Set the fields.
     */
    VOLT_SET_FNCT_LINE (fnctLine)
    if (ASN1_INTEGER_set (priKey->version, 2) != 1)
      break;

    VOLT_SET_FNCT_LINE (fnctLine)
    if (Asn1ObjectId_set (
      priKey->privateData->format, keyOid, VoltIBEPriKeyForm2OidBytesLen) != 1)
      break;

    VOLT_SET_FNCT_LINE (fnctLine)
    if (ASN1_OCTET_STRING_set (
      priKey->privateData->value, buffer, pointLen) != 1)
      break;

    /* Because it's optional, we have to create the pubKey.
     */
    VOLT_SET_FNCT_LINE (fnctLine)
    priKey->pubKey = Asn1Encoded_new ();
    if (priKey->pubKey == (Asn1Encoded *)0)
      break;

    // Add code to differentiate between v1 and v2 (v2 is EXPLICIT)
    VOLT_SET_FNCT_LINE (fnctLine)
    if (Asn1Encoded_set (
      priKey->pubKey, keyData->bfKeyInfo.encodedId.data,
      keyData->bfKeyInfo.encodedId.len) != 1)
      break;

    /* How big does the buffer need to be?
     */
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VT_ERROR_INVALID_INPUT;
    encodingLen = i2d_Asn1IBEPrivateKey (priKey, (unsigned char **)0);
    if (encodingLen == 0)
      break;

    VOLT_SET_FNCT_LINE (fnctLine)
    status = VT_ERROR_MEMORY;
    Z2Free (buffer);
    buffer = (unsigned char *)Z2Malloc (encodingLen, VOLT_MEMORY_SENSITIVE);
    if (buffer == (unsigned char *)0)
      break;

    /* Now encode into the buffer.
     */
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VT_ERROR_INVALID_INPUT;
    temp = buffer;
    encodingLen = i2d_Asn1IBEPrivateKey (priKey, &temp);
    if (encodingLen == 0)
      break;

    /* If successful, set the keyDer field.
     */
    obj->keyDer.data = buffer;
    obj->keyDer.len = encodingLen;

    status = 0;

  } while (0);

  if (priKey != (Asn1IBEPrivateKey *)0)
    Asn1IBEPrivateKey_free (priKey);

  /* If successful, we're done.
   */
  if (status == 0)
    return (0);

  /* If there was an error, free the buffer.
   */
  if (buffer != (unsigned char *)0)
    Z2Free (buffer);

  VOLT_LOG_ERROR_INFO (
    0, obj, status, 0, VT_ERROR_TYPE_PRIMARY,
    (char *)0, "VoltEncodeIBEPrivateKeyData", fnctLine, (char *)0)

  return (status);
}

int VoltDecodeIBEPriKeyDataCreate (
   VoltLibCtx *libCtx,
   unsigned char *encoding,
   unsigned int maxEncodingLen,
   Asn1IBEPrivateKey **ibeKey
   )
{
  int status;
  Asn1IBEPrivateKey *newIBEKey = (Asn1IBEPrivateKey *)0;
  unsigned char *temp;
  VOLT_DECLARE_FNCT_LINE (fnctLine)

  do
  {
    /* Create the Asn1 object.
     */
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VT_ERROR_MEMORY;
    newIBEKey = Asn1IBEPrivateKey_new ();

    /* Try to decode.
     */
    status = VT_ERROR_UNKNOWN_BER;
    temp = encoding;
    d2i_Asn1IBEPrivateKey (&newIBEKey, &temp, maxEncodingLen);

    /* Did it work?
     */
    VOLT_SET_FNCT_LINE (fnctLine)
    if (newIBEKey == (Asn1IBEPrivateKey *)0)
      break;

    /* If successful, return the object.
     */
    *ibeKey = newIBEKey;
    status = 0;

  } while (0);

  /* If no error, we're done.
   */
  if (status == 0)
    return (0);

  /* If there was an error, destroy what we created.
   */
  if (newIBEKey != (Asn1IBEPrivateKey *)0)
    Asn1IBEPrivateKey_free (newIBEKey);

  VOLT_LOG_ERROR_INFO (
    libCtx, 0, status, 0, VT_ERROR_TYPE_PRIMARY,
    (char *)0, "VoltDecodeIBEPriKeyDataCreate", fnctLine, (char *)0)

  return (status);
}

int VoltIBEPriPointFromEncodingAlloc (
   VoltLibCtx *libCtx,
   VoltParameterObject *pObj,
   Asn1IBEPrivateData *priData,
   VtBFType1IBEPoint **ibePoint
   )
{
  int status;
  unsigned int primeLen, bufferSize, offset, coordCount, xFlag;
  unsigned char *buffer = (unsigned char *)0;
  VoltBFType1IBEParams *theParams = (VoltBFType1IBEParams *)(pObj->paramData);
  unsigned char f1Oid[VoltIBEPriKeyForm1OidBytesLen] =
    { VoltIBEPriKeyForm1OidBytes };
  unsigned char f2Oid[VoltIBEPriKeyForm2OidBytesLen] =
    { VoltIBEPriKeyForm2OidBytes };
  VtBFType1IBEPoint *newPoint = (VtBFType1IBEPoint *)0;
  VOLT_DECLARE_FNCT_LINE (fnctLine)

  do
  {
    /* Initialize coordCount to 1, meaning only one coordinate is
     * given in the encoding. If two coordinates are given, change it.
     */
    coordCount = 1;

    /* How big is the prime?
     */
    primeLen = theParams->paramInfo.curve.primeP.len;

    VOLT_SET_FNCT_LINE (fnctLine)
    status = VT_ERROR_UNKNOWN_BER;

    /* Make sure the OID is recognized.
     * If xFlag is 1, only xCoord is given.
     * If 2, only yCoord is given.
     * If 3, both.
     */
    if (priData->format->base.length == VoltIBEPriKeyForm1OidBytesLen)
    {
      if (Z2Memcmp (
        priData->format->base.data, f1Oid, VoltIBEPriKeyForm1OidBytesLen) == 0)
      {
        /* If v.1, the length should be primeLen + 1, but it might be
         * primeLen.
         */
        xFlag = 1;
        if ((unsigned int)(priData->value->length) == primeLen)
          xFlag = 2;
        else if ((unsigned int)(priData->value->length) != (primeLen + 1))
          break;

        status = 0;
      }
    }

    /* If it wasn't Format v.1, check for v.2.
     */
    if (status != 0)
    {
      /* If we reach this point, status is VT_ERROR_UNKNOWN_BER and the
       * OID is not v.1. If not v.2, error.
       */
      if (priData->format->base.length != VoltIBEPriKeyForm2OidBytesLen)
        break;

      if (Z2Memcmp (
        priData->format->base.data, f2Oid, VoltIBEPriKeyForm2OidBytesLen) != 0)
        break;

      /* If v.2, the length should be (2 * primeLen) + 1.
       */
      if ((unsigned int)(priData->value->length) != ((2 * primeLen) + 1))
        break;

      coordCount = 2;
      xFlag = 3;
    }

    /* Build a buffer to hold the Point struct and either one or two
     * coordinates, depending on how many are given. Add an extra byte
     * in case of format 1.
     */
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VT_ERROR_MEMORY;
    bufferSize = sizeof (VtBFType1IBEPoint) + (coordCount * primeLen) + 1;
    buffer = (unsigned char *)Z2Malloc (bufferSize, VOLT_MEMORY_SENSITIVE);
    if (buffer == (unsigned char *)0)
      break;
    newPoint = (VtBFType1IBEPoint *)buffer;
    Z2Memset (buffer, 0, bufferSize);
    offset = sizeof (VtBFType1IBEPoint);

    /* Locate the pointers.
     */
    if ((xFlag & 1) == 1)
    {
      newPoint->xCoord.data = buffer + offset;
      offset += primeLen + 1;
    }
    if ((xFlag & 2) == 2)
    {
      newPoint->yCoord.data = buffer + offset;
    }

    if (coordCount == 1)
    {
      if (xFlag == 1)
      {
        Z2Memcpy (newPoint->xCoord.data, priData->value->data, primeLen + 1);
        newPoint->xCoord.len = primeLen + 1;
      }
      else
      {
        Z2Memcpy (newPoint->yCoord.data, priData->value->data, primeLen);
        newPoint->yCoord.len = primeLen;
      }
    }
    else
    {
      /* Just copy the coordinates.
       */
      Z2Memcpy (newPoint->xCoord.data, priData->value->data + 1, primeLen);
      newPoint->xCoord.len = primeLen;
      Z2Memcpy (
        newPoint->yCoord.data, priData->value->data + primeLen + 1, primeLen);
      newPoint->yCoord.len = primeLen;
    }

    *ibePoint = newPoint;
    status = 0;

  } while (0);

  /* If success, we're done.
   */
  if (status == 0)
    return (0);

  /* If error, free what we allocated.
   */
  if (newPoint != (VtBFType1IBEPoint *)0)
    Z2Free (newPoint);

  VOLT_LOG_ERROR_INFO (
    libCtx, pObj, status, 0, VT_ERROR_TYPE_PRIMARY,
    (char *)0, "VoltIBEPriPointFromEncodingAlloc", fnctLine, (char *)0)

  return (status);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -