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

📄 p7getkeys.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 "certobj.h"
#include "errorctx.h"

/* Make sure the private key and the public key in the cert match.
 * <p>This function will get the public key data out of the objects.
 * The private key must be a type that allows returning the public key
 * data. A hardware key, or a key that does not hold the public key
 * data, for example, might not allow this.
 */
static int VOLT_CALLING_CONV CheckDSASigningKeys VOLT_PROTO_LIST ((
   VtLibCtx libraryCtx,
   VtKeyObject priKey,
   VtCertObject cert
));

int VoltP7GetKeysAndCert (
   VoltSurrenderCtx *surrCtx,
   VtIdentityObject identity,
   VtRandomObject random,
   VtPolicyCtx policyCtx,
   VtStorageCtx storageCtx,
   VtTransportCtx transportCtx,
   VtCertObject *signingCert,
   VtKeyObject *ibePriKey,
   VtKeyObject *dsaPriKey
   )
{
  int status;
  unsigned int encodingLen;
  VoltIdentityObject *obj = (VoltIdentityObject *)identity;
  VtLibCtx libraryCtx = obj->voltObject.libraryCtx;
  VtMpIntCtx mpCtx = (VtMpIntCtx)0;
  VtMpIntCtx getMpCtx = (VtMpIntCtx)0;
  VtCertRequestObject certReq = (VtCertRequestObject)0;
  VtCertObject newCert = (VtCertObject)0;
  VtKeyObject newIbePri = (VtKeyObject)0;
  VtKeyObject newDsaPub = (VtKeyObject)0;
  VtKeyObject newDsaPri = (VtKeyObject)0;
  VtParameterObject dsaParams = (VtParameterObject)0;
  VtSurrenderCallback surrenderCtx;
  VtSurrenderCallback *surrenderToUse = (VtSurrenderCallback *)0;
  VOLT_DECLARE_FNCT_LINE (fnctLine)

  do
  {
    /* Make sure the ID is encoded. If no output buffer is given, the
     * function will encode it internally only. We're expecting
     * BUFFER_TOO_SMALL error.
     */
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VtEncodeIdentity (
      identity, VT_ENCODE_IBCS_2_V_DISTRICT | VT_ENCODE_FOR_SIGNING,
      policyCtx, storageCtx, transportCtx,
      (unsigned char *)0, 0, &encodingLen);
    if (status == 0)
      status = VT_ERROR_GENERAL;
    if (status != VT_ERROR_BUFFER_TOO_SMALL)
      break;

    /* We'll need an mpCtx.
     */
    getMpCtx = (VtMpIntCtx)(obj->mpCtx);
    if (getMpCtx == (VtMpIntCtx)0)
    {
      getMpCtx = (VtMpIntCtx)VoltGetLibCtxInfo (
        libraryCtx, VOLT_LIB_CTX_INFO_TYPE_MP_CTX);

      if (getMpCtx == (VtMpIntCtx)0)
      {
        VOLT_SET_FNCT_LINE (fnctLine)
        status = VtCreateMpIntCtx (
          libraryCtx, VtMpIntImplOpenSSL, (Pointer)0, &mpCtx);
        if (status != 0)
          break;

        getMpCtx = mpCtx;
      }
    }

    /* If there's a surrender ctx, use it.
     */
    if (surrCtx != (VoltSurrenderCtx *)0)
    {
      /* Set the key 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;
      surrenderToUse = &surrenderCtx;
    }

    /* Create "empty" objects into which we'll place the data from
     * storage (if the data is in storage).
     */
    if (ibePriKey != (VtKeyObject *)0)
    {
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VtCreateKeyObject (
        libraryCtx, VtKeyImplMpCtx, (Pointer)getMpCtx, &newIbePri);
      if (status != 0)
        break;
    }

    if (dsaPriKey != (VtKeyObject *)0)
    {
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VtCreateKeyObject (
        libraryCtx, VtKeyImplMpCtx, (Pointer)getMpCtx, &newDsaPri);
      if (status != 0)
        break;

      VOLT_SET_FNCT_LINE (fnctLine)
      status = VtCreateCertObject (
        libraryCtx, VtCertImplMpCtx, (Pointer)getMpCtx, &newCert);
      if (status != 0)
        break;
    }

    /* Try to get the keys and cert from storage. Because we're passing
     * the STORAGE_ONLY flag, this function will look only in storage.
     * If the return is 0, we found the values, we're done. If the
     * return is ENTRY_NOT_FOUND, the values were not in storage, we'll
     * generate and download new values.
     * Any other return is an error we want to pass along.
     */
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VtObtainPrivateKeysAndCert (
      identity, random, VT_OBTAIN_KEYS_FLAG_STORAGE_ONLY, policyCtx,
      storageCtx, (VtTransportCtx)0, newDsaPri, newCert, newIbePri);
    if (status == 0)
    {
      /* If we have a key pair, make sure they match.
       */
      if (newDsaPri != (VtKeyObject)0)
      {
        VOLT_SET_FNCT_LINE (fnctLine)
        status = CheckDSASigningKeys (libraryCtx, newDsaPri, newCert);
        if (status == VT_ERROR_UNMATCHED_KEY_PAIR)
          status = VT_ERROR_ENTRY_NOT_FOUND;
      }
    }
    if (status != VT_ERROR_ENTRY_NOT_FOUND)
      break;

    if (ibePriKey != (VtKeyObject *)0)
    {
      VtDestroyKeyObject (&newIbePri);

      VOLT_SET_FNCT_LINE (fnctLine)
      status = VtCreateKeyObject (
        libraryCtx, VtKeyImplMpCtx, (Pointer)getMpCtx, &newIbePri);
      if (status != 0)
        break;
    }

    if (dsaPriKey != (VtKeyObject *)0)
    {
      VtDestroyKeyObject (&newDsaPri);
      VtDestroyCertObject (&newCert);

      VOLT_SET_FNCT_LINE (fnctLine)
      status = VtCreateKeyObject (
        libraryCtx, VtKeyImplMpCtx, (Pointer)getMpCtx, &newDsaPri);
      if (status != 0)
        break;

      VOLT_SET_FNCT_LINE (fnctLine)
      status = VtCreateCertObject (
        libraryCtx, VtCertImplMpCtx, (Pointer)getMpCtx, &newCert);
      if (status != 0)
        break;

      /* This function will build a DSA parameter object either from the
       * district's params or from a default set. We don't care which,
       * so we'll ignore the returned flag. Just use encodingLen for the
       * return flag.
       */
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VoltGetDsaParamsCreate (
        identity, (VtDistrictObject)0, getMpCtx, &encodingLen, &dsaParams);
      if (status != 0)
        break;

      /* If there's a surrender ctx, use it.
       */
      if (surrCtx != (VoltSurrenderCtx *)0)
      {
        VOLT_SET_FNCT_LINE (fnctLine)
        status = VtSetKeyParam (
          newDsaPri, VtKeyParamSurrenderCallback, (Pointer)surrenderToUse);
        if (status != 0)
          break;
      }

      VOLT_SET_FNCT_LINE (fnctLine)
      status = VtCreateKeyObject (
        libraryCtx, VtKeyImplMpCtx, (Pointer)getMpCtx, &newDsaPub);
      if (status != 0)
        break;

      /* Now that we have params, generate a key pair.
       */
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VtGenerateKeyPair (
        VtKeyPairGenDSA, (Pointer)dsaParams, random, newDsaPub, newDsaPri);
      if (status != 0)
        break;

      /* We need a cert request to send to the key server.
       */
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VtCreateCertRequestObject (
        libraryCtx, VtCertRequestImplMpCtx, (Pointer)getMpCtx,
        &certReq);
      if (status != 0)
        break;

      /* If there's a surrender ctx, use it.
       */
      if (surrCtx != (VoltSurrenderCtx *)0)
      {
        VOLT_SET_FNCT_LINE (fnctLine)
        status = VtSetCertRequestParam (
          certReq, VtCertRequestParamSurrenderCallback, (Pointer)surrenderToUse);
        if (status != 0)
          break;
      }

      VOLT_SET_FNCT_LINE (fnctLine)
      status = VtGenerateCertRequest (
        identity, newDsaPub, newDsaPri, VtCertRequestTypeP10DSA,
        (Pointer)random, certReq);
      if (status != 0)
        break;
    }

    /* Get the private key and signing cert.
     * This call will store the private IBE key and the cert, but not
     * the private DSA key.
     */
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VtDownloadIBEPrivateKeyAndCert (
      identity, policyCtx, storageCtx, transportCtx,
      certReq, newCert, newIbePri);
    if (status != 0)
      break;

    if (storageCtx == (VtStorageCtx)0)
      break;

    if (dsaPriKey != (VtKeyObject *)0)
    {
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VtStoreEntry (
        libraryCtx, VT_ENTRY_TYPE_SIGNING_PRI_KEY,
        (Pointer)identity, (Pointer)newDsaPri, storageCtx);
      if (status != 0)
        break;
    }

    if (signingCert != (VtCertObject *)0)
    {
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VtStoreEntry (
        libraryCtx, VT_ENTRY_TYPE_CERTIFICATE, (Pointer)identity,
        (Pointer)newCert, storageCtx);
      if (status != 0)
        break;
    }

    if (ibePriKey != (VtKeyObject *)0)
    {
      VOLT_SET_FNCT_LINE (fnctLine)
      status = VtStoreEntry (
        libraryCtx, VT_ENTRY_TYPE_IBE_PRI_KEY, (Pointer)identity,
        (Pointer)newIbePri, storageCtx);
    }

  } while (0);

  VtDestroyParameterObject (&dsaParams);
  VtDestroyKeyObject (&newDsaPub);
  VtDestroyCertRequestObject (&certReq);
  VtDestroyMpIntCtx (&mpCtx);

  /* If status is 0, we've got our values, return them. Well, return
   * the values the caller wanted, destroy the others.
   */
  if (status == 0)
  {
    if (signingCert != (VtCertObject *)0)
      *signingCert = newCert;
    else
      VtDestroyCertObject (&newCert);

    if (ibePriKey != (VtKeyObject *)0)
      *ibePriKey = newIbePri;
    else
      VtDestroyKeyObject (&newIbePri);

    if (dsaPriKey != (VtKeyObject *)0)
      *dsaPriKey = newDsaPri;
    else
      VtDestroyKeyObject (&newDsaPri);

    return (0);
  }

  /* If there was an error, we need to destroy these objects.
   */
  VtDestroyKeyObject (&newIbePri);
  VtDestroyKeyObject (&newDsaPri);
  VtDestroyCertObject (&newCert);

  VOLT_LOG_ERROR_INFO (
    0, identity, status, 0, 0,
    (char *)0, "VoltP7GetKeysAndCert", fnctLine, (char *)0)

  return (status);
}

int VoltGetSignerInfoCount (
   VoltPkcs7Object *obj,
   unsigned int *signerInfoCount
   )
{
  int status;
  VoltPkcs7ReadSignCtx *readCtx;
  VOLT_DECLARE_FNCT_LINE (fnctLine)

  /* If the object is "Read Signed" and done, return the count from a
   * VoltPkcs7ReadSignCtx localCtx.
   */
  if (obj->state == VOLT_P7_STATE_SIGN_READ_FINAL)
  {
    readCtx = (VoltPkcs7ReadSignCtx *)(obj->localCtx);
    *signerInfoCount = readCtx->signerInfosCount;
    return (0);
  }

  /* The object is not "Read Signed" and done, maybe it's "Read Signed"
   * and just not done.
   */
  *signerInfoCount = 0;
  VOLT_SET_FNCT_LINE (fnctLine)
  status = VT_ERROR_INVALID_P7_OBJ;
  if (obj->contentType == VOLT_PKCS7_SIGNED_DATA_READ)
  {
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VT_ERROR_INVALID_CALL_ORDER;
  }

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

  return (status);
}

static int CheckDSASigningKeys (
   VtLibCtx libraryCtx,
   VtKeyObject priKey,
   VtCertObject cert
   )
{
  int status;
  VtDSAPubKeyInfo *getInfoFromPri, *getInfoFromPub;
  VtKeyObject pubKey = (VtKeyObject)0;
  VoltCertObject *obj = (VoltCertObject *)cert;
  VoltMpIntCtx *mpCtx = obj->mpCtx;
  VoltLibCtx *libCtx = (VoltLibCtx *)libraryCtx;
  VOLT_DECLARE_ERROR_TYPE (errorType)
  VOLT_DECLARE_FNCT_LINE (fnctLine)

  do
  {
    /* Build a public key from the cert.
     */
    VOLT_SET_ERROR_TYPE (errorType, 0)
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VtCreateKeyObject (
      libraryCtx, VtKeyImplMpCtx, (Pointer)mpCtx, &pubKey);
    if (status != 0)
      break;

    VOLT_SET_FNCT_LINE (fnctLine)
    status = VtSetKeyParam (
      pubKey, VtKeyParamX509CertObject, (Pointer)cert);
    if (status != 0)
      break;

    /* Now get the public key data out of each key object.
     */
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VtGetKeyParam (
      pubKey, VtKeyParamDSAPublic, (Pointer *)&getInfoFromPub);
    if (status != 0)
      break;

    VOLT_SET_FNCT_LINE (fnctLine)
    status = VtGetKeyParam (
      priKey, VtKeyParamDSAPublic, (Pointer *)&getInfoFromPri);
    if (status != 0)
      break;

    /* Compare the pubValY.
     */
    VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VT_ERROR_UNMATCHED_KEY_PAIR;
    if (getInfoFromPri->pubValY.len != getInfoFromPub->pubValY.len)
      break;

    VOLT_SET_FNCT_LINE (fnctLine)
    if (Z2Memcmp (
      getInfoFromPri->pubValY.data, getInfoFromPub->pubValY.data,
      getInfoFromPri->pubValY.len) != 0)
      break;

    /* If we reach this far, the public vlues are the same, we can
     * safely assume the keys are the same.
     */
    status = 0;

  } while (0);

  VtDestroyKeyObject (&pubKey);

  VOLT_LOG_ERROR_INFO_COMPARE (
    status, libraryCtx, 0, status, 0, errorType,
    (char *)0, "CheckDSASigningKeys", fnctLine, (char *)0)

  return (status);
}

⌨️ 快捷键说明

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