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

📄 dsakeyber.c

📁 IBE是一种非对称密码技术
💻 C
📖 第 1 页 / 共 2 页
字号:
/* 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 "prikeyder.h"
#include "pubkeyder.h"
#include "dsaparamsder.h"
#include "errorctx.h"

/* Set up the OpenSSL ASN.1 templates.
 */
ASN1_SEQUENCE (Asn1DsaParams) =
{
  ASN1_SIMPLE (Asn1DsaParams, prime, ASN1_INTEGER),
  ASN1_SIMPLE (Asn1DsaParams, subprime, ASN1_INTEGER),
  ASN1_SIMPLE (Asn1DsaParams, base, ASN1_INTEGER)
} ASN1_SEQUENCE_END (Asn1DsaParams);

IMPLEMENT_ASN1_FUNCTIONS (Asn1DsaParams)

ASN1_SEQUENCE (Asn1DsaPubAndParams) =
{
  ASN1_SIMPLE (Asn1DsaPubAndParams, pubVal, ASN1_INTEGER),
  ASN1_SIMPLE (Asn1DsaPubAndParams, prime, ASN1_INTEGER),
  ASN1_SIMPLE (Asn1DsaPubAndParams, subprime, ASN1_INTEGER),
  ASN1_SIMPLE (Asn1DsaPubAndParams, base, ASN1_INTEGER)
} ASN1_SEQUENCE_END (Asn1DsaPubAndParams);

IMPLEMENT_ASN1_FUNCTIONS (Asn1DsaPubAndParams)

/* Build the params for the algID. The params for a DSA key (both
 * public and private) are encoded as follows.
 *    SEQUENCE {
 *      prime        INTEGER,
 *      subprime     INTEGER,
 *      base         INTEGER }
 * <p>This function will allocate the memory needed to hold the
 * encoding, it is the responsibility of the caller to free it (hence
 * the word "Alloc" in the name).
 *
 * @param obj The object with the data to encode. It also contains the
 * libCtx to use.
 * @param paramData The param data (if hardware key, the data might not
 * be in the object).
 * @param encoding The address where the function will deposit the
 * pointer to the allocated memory.
 * @param encodingLen The address where this function will deposit the
 * length, in bytes, of the encoding.
 * @return an int, 0 if the function completed successfully or a
 * non-zero error code (e.g., key and object don't match).
 */
static int VOLT_CALLING_CONV EncodeDsaParamsAlloc VOLT_PROTO_LIST ((
   VoltKeyObject *obj,
   VtDSAParamInfo *paramInfo,
   unsigned char **encoding,
   unsigned int *encodingLen
));

int VtDerCoderDSAPrivateKey (
   VtDerCoderInfo *coderInfo,
   Pointer object,
   unsigned int flag
   )
{
  int status;
  unsigned int bufferSize, paramsDerLen, keyValueLen;
  VoltLibCtx *libCtx;
  VoltKeyObject *obj = (VoltKeyObject *)object;
  VoltDerCoderEncodeData *encodeData = &(coderInfo->info.encodeData);
  VoltDerCoderGetAlgData *getAlgData = &(coderInfo->info.getAlgData);
  VoltDerCoderDecodeData *decodeData = &(coderInfo->info.decodeData);
  VtDSAPriKeyInfo *dsaKeyInfo;
  Asn1PrivateKeyInfo *priKeyInfo;
  unsigned char *paramsDer = (unsigned char *)0;
  unsigned char *keyValue = (unsigned char *)0;
  unsigned char *temp;
  ASN1_INTEGER *value = (ASN1_INTEGER *)0;
  Asn1DsaParams *dsaParams = (Asn1DsaParams *)0;
  VtSetKeyBerInfo *setBerInfo;
  VtDSAPriKeyInfo dsaPriKeyInfo;
  unsigned char dsaKeyOid[VoltDsaKeyOidBytesLen] =  { VoltDsaKeyOidBytes };
  VOLT_DECLARE_ERROR_TYPE (errorType)
  VOLT_DECLARE_FNCT_LINE (fnctLine)

  switch (flag)
  {
    default:
      VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VT_ERROR_INVALID_TYPE;
      break;

    case VOLT_DER_TYPE_ENCODE_FLAG:
      /* If the flag is ENCODE, return the DSA Private Key inside a
       * PKCS #8 PrivateKeyInfo.
       */

      /* Check the args.
       */
      VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VT_ERROR_NON_NULL_ARG;
      if (object != (Pointer)0)
        break;

      /* We need a place to drop the length.
       */
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VT_ERROR_NULL_ARG;
      if (encodeData->encodingLen == (unsigned int *)0)
        break;

      /* The info should be a key object.
       */
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VT_ERROR_NULL_ARG;
      if (encodeData->info == (Pointer)0)
        break;

      obj = (VoltKeyObject *)(encodeData->info);

      /* We need the key data.
       */
      VOLT_SET_ERROR_TYPE (errorType, 0)
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VtGetKeyParam (
        (VtKeyObject)obj, VtKeyParamDSAPrivate, (Pointer *)&dsaKeyInfo);
      if (status != 0)
        break;

      /* If the previous call worked, we have a valid key object.
       */
      libCtx = (VoltLibCtx *)(obj->voltObject.libraryCtx);

      bufferSize = encodeData->bufferSize;
      if (encodeData->encoding == (unsigned char *)0)
        bufferSize = 0;

      /* Create the encoding of the params. The dsaKeyInfo will look
       * like paramInfo when cast.
       */
      VOLT_SET_FNCT_LINE (fnctLine)
      status = EncodeDsaParamsAlloc (
        obj, (VtDSAParamInfo *)dsaKeyInfo, &paramsDer, &paramsDerLen);
      if (status != 0)
        break;

      /* Build the encoding of the PrivateKey. For DSA private it is an
       * INTEGER, the private value.
       */
      VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VT_ERROR_MEMORY;
      value = ASN1_INTEGER_new ();
      if (value == (ASN1_INTEGER *)0)
        break;

      VOLT_SET_FNCT_LINE (fnctLine)
      if (ASN1_STRING_set (
        value, dsaKeyInfo->priValX.data, dsaKeyInfo->priValX.len) != 1)
        break;

      /* The length of the encoding will likely be priValX.len plus 3
       * bytes: 02 15 00 <priValX>.
       * To be safe, allocate space for the priValX and for 7 extra
       * bytes: 02 84 len len len len 00 <priValX>. This will probably
       * never happen in the real world, but it saves coordinating code
       * to max lengths of subprime.
       */
      VOLT_SET_FNCT_LINE (fnctLine)
      keyValue = (unsigned char *)Z2Malloc (
        dsaKeyInfo->priValX.len + 7, VOLT_MEMORY_SENSITIVE);
      if (keyValue == (unsigned char *)0)
        break;

      /* Encode.
       */
      VOLT_SET_FNCT_LINE (fnctLine)
      temp = keyValue;
      keyValueLen = i2d_ASN1_INTEGER (value, &temp);
      if (keyValueLen == 0)
        break;

      /* Encode PrivateKeyData.
       */
      VOLT_SET_ERROR_TYPE (errorType, 0)
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VoltEncodePrivateKeyInfoDer (
        libCtx, dsaKeyOid, VoltDsaKeyOidBytesLen, paramsDer, paramsDerLen,
        keyValue, keyValueLen, encodeData->encoding, bufferSize,
        encodeData->encodingLen);

      break;

    case VOLT_DER_TYPE_DECODE_FLAG:
      /* If the flag is decode, set the key object with the private key
       * info.
       */

      /* Check the args, the type should be VOLT_DER_TYPE_PRI_KEY_FLAG.
       */
      VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VT_ERROR_UNKNOWN_BER;
      if (decodeData->type != VOLT_DER_TYPE_PRI_KEY_FLAG)
        break;

      /* Make sure this is the algId for DSA private key.
       */
      VOLT_SET_FNCT_LINE (fnctLine)
      priKeyInfo = (Asn1PrivateKeyInfo *)(decodeData->asn1Object);
      if (priKeyInfo->algId->oid->base.length != VoltDsaKeyOidBytesLen)
        break;

      VOLT_SET_FNCT_LINE (fnctLine)
      libCtx = (VoltLibCtx *)(obj->voltObject.libraryCtx);
      if (Z2Memcmp (
        priKeyInfo->algId->oid->base.data, dsaKeyOid,
        VoltDsaKeyOidBytesLen) != 0)
        break;

      /* Decode the params if they're in the algID.
       */
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VT_ERROR_MEMORY;
      dsaParams = Asn1DsaParams_new ();
      if (dsaParams == (Asn1DsaParams *)0)
        break;

      /* Decode.
       */
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VT_ERROR_UNKNOWN_BER;
      temp = priKeyInfo->algId->params->base.data;
      d2i_Asn1DsaParams (
        &dsaParams, &temp, priKeyInfo->algId->params->base.length);

      /* Did it work?
       */
      VOLT_SET_FNCT_LINE (fnctLine)
      if (dsaParams == (Asn1DsaParams *)0)
        break;

      /* The encodedKey in the priKeyInfo should be an INTEGER.
       */
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VT_ERROR_MEMORY;
      value = ASN1_INTEGER_new ();
      if (value == (ASN1_INTEGER *)0)
        break;

      VOLT_SET_FNCT_LINE (fnctLine)
      status = VT_ERROR_UNKNOWN_BER;
      temp = priKeyInfo->encodedKey->data;
      d2i_ASN1_INTEGER (&value, &temp, priKeyInfo->encodedKey->length);

      /* Did it work?
       */
      VOLT_SET_FNCT_LINE (fnctLine)
      if (value == (ASN1_INTEGER *)0)
        break;

      setBerInfo = (VtSetKeyBerInfo *)(decodeData->info);

      /* Build the struct needed to set a key object,
       */
      dsaPriKeyInfo.primeP.data = dsaParams->prime->data;
      dsaPriKeyInfo.primeP.len = dsaParams->prime->length;
      dsaPriKeyInfo.subprimeQ.data = dsaParams->subprime->data;
      dsaPriKeyInfo.subprimeQ.len = dsaParams->subprime->length;
      dsaPriKeyInfo.baseG.data = dsaParams->base->data;
      dsaPriKeyInfo.baseG.len = dsaParams->base->length;
      dsaPriKeyInfo.pubValY.data = (unsigned char *)0;
      dsaPriKeyInfo.pubValY.len = 0;
      dsaPriKeyInfo.priValX.data = value->data;
      dsaPriKeyInfo.priValX.len = value->length;
      VOLT_SET_ERROR_TYPE (errorType, 0)
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VtSetKeyParam (
        (VtKeyObject)obj, VtKeyParamDSAPrivate, (Pointer)&dsaPriKeyInfo);

      break;

    case VOLT_DER_TYPE_GET_ALG_FLAG:
      /* If the flag is get alg, check the input to see if it's the
       * DSA private key OID.
       */

      /* Check the args.
       */
      VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VT_ERROR_NON_NULL_ARG;
      if (object != (Pointer)0)
        break;

      VOLT_SET_FNCT_LINE (fnctLine)
      status = VT_ERROR_NULL_ARG;
      if ( (getAlgData->algorithm == (unsigned int *)0) ||
           (getAlgData->oid == (unsigned char *)0) )
        break;

      VOLT_SET_FNCT_LINE (fnctLine)
      status = VT_ERROR_UNKNOWN_BER;
      if (getAlgData->encodingType != VOLT_ENCODING_TYPE_PRI_KEY)
        break;

      VOLT_SET_FNCT_LINE (fnctLine)
      if (getAlgData->oidLen != VoltDsaKeyOidBytesLen)
        break;

      VOLT_SET_FNCT_LINE (fnctLine)
      libCtx = getAlgData->libCtx;
      if (Z2Memcmp (
        getAlgData->oid, dsaKeyOid, VoltDsaKeyOidBytesLen) != 0)
        break;

      /* The OID matches, the algorithm is DSA private key.
       */
      *(getAlgData->algorithm) = VT_KEY_BER_DSA_PRIVATE;
      getAlgData->SymKeyParam = (VtKeyParam *)0;
      getAlgData->DigestImpl = (VtAlgorithmImpl *)0;

      status = 0;
  }

  if (keyValue != (unsigned char *)0)
    Z2Free (keyValue);
  if (paramsDer != (unsigned char *)0)
    Z2Free (paramsDer);
  if (value != (ASN1_INTEGER *)0)
    ASN1_INTEGER_free (value);
  if (dsaParams != (Asn1DsaParams *)0)
    Asn1DsaParams_free (dsaParams);

  VOLT_LOG_ERROR_INFO_COMPARE (
    status, 0, object, status, 0, errorType,
    (char *)0, "VtDerCoderDSAPrivateKey", fnctLine, (char *)0)

  return (status);
}

int VtDerCoderDSAPublicKey (
   VtDerCoderInfo *coderInfo,
   Pointer object,
   unsigned int flag
   )
{
  int status;
  unsigned int bufferSize, paramsDerLen, keyValueLen;
  VoltLibCtx *libCtx;
  VoltKeyObject *obj = (VoltKeyObject *)object;
  VoltDerCoderEncodeData *encodeData = &(coderInfo->info.encodeData);
  VoltDerCoderGetAlgData *getAlgData = &(coderInfo->info.getAlgData);
  VoltDerCoderDecodeData *decodeData = &(coderInfo->info.decodeData);
  VtDSAPubKeyInfo *dsaKeyInfo;
  Asn1SubjectPublicKey *subjPubKey;
  unsigned char *paramsDer = (unsigned char *)0;
  unsigned char *keyValue = (unsigned char *)0;
  unsigned char *temp;
  ASN1_INTEGER *value = (ASN1_INTEGER *)0;
  Asn1DsaParams *dsaParams = (Asn1DsaParams *)0;
  Asn1DsaPubAndParams *dsaPubAndParams = (Asn1DsaPubAndParams *)0;
  VtSetKeyBerInfo *setBerInfo;
  VtDSAPubKeyInfo dsaPubKeyInfo;
  unsigned char dsaKeyOid[VoltDsaKeyOidBytesLen] =  { VoltDsaKeyOidBytes };
  VOLT_DECLARE_ERROR_TYPE (errorType)
  VOLT_DECLARE_FNCT_LINE (fnctLine)

  obj = (VoltKeyObject *)object;

  switch (flag)
  {
    default:
      VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
      VOLT_SET_FNCT_LINE (fnctLine)

⌨️ 快捷键说明

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