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

📄 defcertvfy.c

📁 voltage 公司提供的一个开发Ibe的工具包
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Copyright 2003-2005, Voltage Security, all rights reserved.
 */
#include "vibe.h"
#include "environment.h"
#include "base.h"
#include "libctx.h"
#include "certvfyctx.h"
#include "certobj.h"
#include "vcert.h"
#include "vtime.h"
#include "algobj.h"
#include "sign.h"
#include "digest.h"
#include "surrender.h"

/* Implements VVerifyCertElements.
 */
int VOLT_CALLING_CONV DefaultVerifyCertElements VOLT_PROTO_LIST ((
   VtCertVerifyCtx verifyCtx,
   Pointer verifyInfo,
   VtCertObject certToVerify,
   unsigned int *verifyResult
));

/* Implements VVerifyCertSignature.
 */
int VOLT_CALLING_CONV DefaultVerifyCertSignature VOLT_PROTO_LIST ((
   VtCertVerifyCtx verifyCtx,
   Pointer verifyInfo,
   VtCertObject certToVerify,
   VtStorageCtx storageCtx,
   VtCertObjectList *trustedCerts,
   VtCertObjectList *untrustedCerts,
   VtDerCoder **derCoders,
   unsigned int derCoderCount,
   unsigned int *verifyResult
));

/* The caller passed in verifyInfo. Check to make sure it is valid
 * VtBasicCertVerifyInfo.
 * <p>This function will also build the internal ASN.1 object if it is
 * not already built.
 *
 * @param libCtx The libCtx to use.
 * @param obj The cert object being verified.
 * @param info The info the caller passed in, the data to check.
 * @return an int, 0 if the function completed successfully or a
 * non-zero error code.
 */
static int VOLT_CALLING_CONV CheckBasicVerifyInfo VOLT_PROTO_LIST ((
   VoltLibCtx *libCtx,
   VoltCertObject *obj,
   Pointer info
));

/* Check to see if there is a cert in the given list that verifies the
 * given signature.
 * <p>The caller passes in the issuer name of a cert. This function
 * will go through the list to find a cert that has that name as its
 * subject name. It will then try to verify.
 * <p>The caller passes in the digest, signature, and verification
 * object, the function will verify the signature using the public key
 * found in the cert found.
 * <p>The routine will cycle through the list. If it finds a match, it
 * will check the cert against the verifyInfo. It will then verify the
 * signature. If everything succeeds, the function will return with the
 * cert that verifies.
 * <p>If the subroutine finds a matching name but the basic info or
 * signature does not verify, it will continue with the list. If it
 * goes through the entire list without a match, it will return no cert.
 * <p>If the function returns a cert, that cert verified the signature.
 * If it does not return a cert, there was no cert discovered.
 * <p>The cert returned is a reference to the cert found, this function
 * does not create a new object.
 */
static int VOLT_CALLING_CONV CheckCertList VOLT_PROTO_LIST ((
   VoltLibCtx *libCtx,
   VoltMpIntCtx *mpCtx,
   VtCertVerifyCtx verifyCtx,
   VtBasicCertVerifyInfo *verifyInfo,
   VtCertInfo *certInfo,
   VtAlgorithmObject verifier,
   unsigned char *name,
   unsigned int nameLen,
   unsigned int digestAlg,
   unsigned char *digest,
   unsigned int digestLen,
   unsigned char *signature,
   unsigned int signatureLen,
   VtCertObject *certList,
   unsigned int certListCount,
   VtCertObject *verifyingCert
));

int VtCertVerifyImplBasic (
   VtCertVerifyCtx *certVerifyCtx,
   Pointer info,
   unsigned int flag
   )
{
  int status;
  VoltCertVerifyCtx *ctx = (VoltCertVerifyCtx *)(*certVerifyCtx);

  do
  {
    /* Check the flag, it should be VOLT_CERT_VFY_CTX_SET_TYPE_FLAG.
     */
    status = VT_ERROR_INVALID_TYPE;
    if (flag != VOLT_CERT_VFY_CTX_SET_TYPE_FLAG)
      break;

    /* The associated info should be a null pointer.
     */
    status = VT_ERROR_INVALID_ASSOCIATED_INFO;
    if (info != (Pointer)0)
      break;

    /* This ctx needs no local ctx, so just fill the ctx function
     * pointer fields.
     */
    ctx->LocalCtxDestroy = VoltDefaultCtxDestroy;
    ctx->VerifyCertElements = DefaultVerifyCertElements;
    ctx->VerifyCertSignature = DefaultVerifyCertSignature;

    status = 0;

  } while (0);

  return (status);
}

int DefaultVerifyCertElements (
   VtCertVerifyCtx verifyCtx,
   Pointer verifyInfo,
   VtCertObject certToVerify,
   unsigned int *verifyResult
   )
{
  int status, count, index;
  unsigned int compareResult, value, valueLen;
  VoltCertObject *obj = (VoltCertObject *)certToVerify;
  VoltLibCtx *libCtx = (VoltLibCtx *)(obj->voltObject.libraryCtx);
  VtBasicCertVerifyInfo *vInfo;
  Asn1X509Extension *extension;
  unsigned char keyUsageOid[VoltCertExtKeyUsageOidBytesLen] =
    { VoltCertExtKeyUsageOidBytes };

  do
  {
    /* Check to see if the verifyInfo passed in is what we expect.
     */
    status = CheckBasicVerifyInfo (libCtx, obj, verifyInfo);
    if (status != 0)
      break;

    vInfo = (VtBasicCertVerifyInfo *)verifyInfo;

    /* Get the validity dates. Compare to the value in the verifyInfo.
     */
    *verifyResult = 0;
    status = VoltCompareTimeValidity (
      &(vInfo->usageTime), obj->certAsn1->innerCert->validity->base.data,
      (unsigned int)(obj->certAsn1->innerCert->validity->base.length),
      &compareResult);
    if ( (status != 0) || (compareResult != 0) )
      break;

    /* Now check the keyUsage extension.
     * First, if there are no extensions, there's nothing to check.
     */
    *verifyResult = 1;
    if (obj->certAsn1->innerCert->extensions == (STACK *)0)
      break;

    count = sk_num (obj->certAsn1->innerCert->extensions);

    /* Cycle through the extensions.
     */
    for (index = 0; index < count; ++index)
    {
      extension = (Asn1X509Extension *)sk_value (
        obj->certAsn1->innerCert->extensions, index);
      if (extension->oid->base.length != VoltCertExtKeyUsageOidBytesLen)
        continue;
      if (Z2Memcmp (
        extension->oid->base.data, keyUsageOid,
        VoltCertExtKeyUsageOidBytesLen) == 0)
        break;
    }

    /* If we ran through the list with no matches, this cert has no
     * keyUsage extension.
     */
    if (index >= count)
      break;

    /* The extension is keyUsage. Get the value, it's a bit string. It
     * will be either
     *   03 02 unused x
     *   03 03 unused x x
     */
    valueLen = (unsigned int)(extension->value->data[1]);
    value = (unsigned int)(extension->value->data[3]);
    value <<= 8;
    if (valueLen == 3)
      value += (unsigned int)(extension->value->data[4]);

    /* Are the bits the input keyUsage want to be set, set in the cert?
     */
    value &= vInfo->keyUsage;
    if (value == vInfo->keyUsage)
      break;

    /* Some bit in the cert extension was not set.
     */
    *verifyResult = 0;
  } while (0);

  if (status == 0)
    return (0);

  /* If error, make sure the verifyResult is did not verify.
   */
  *verifyResult = 0;

  return (status);
}

int DefaultVerifyCertSignature (
   VtCertVerifyCtx verifyCtx,
   Pointer verifyInfo,
   VtCertObject certToVerify,
   VtStorageCtx storageCtx,
   VtCertObjectList *trustedCerts,
   VtCertObjectList *untrustedCerts,
   VtDerCoder **derCoders,
   unsigned int derCoderCount,
   unsigned int *verifyResult
   )
{
  int status;
  unsigned int index, offset, lengthLen, valueLen, issuerNameLen, algorithm;
  unsigned int bufferSize, digestAlg, digestLen, signatureLen;
  VoltCertVerifyCtx *ctx = (VoltCertVerifyCtx *)verifyCtx;
  VoltCertObject *obj = (VoltCertObject *)certToVerify;
  VtCertObject verifyingCert = (VtCertObject)0;
  VtAlgorithmObject digester = (VtAlgorithmObject)0;
  VtAlgorithmObject verifier = (VtAlgorithmObject)0;
  VoltLibCtx *libCtx = (VoltLibCtx *)(obj->voltObject.libraryCtx);
  Asn1X509CertToVerify *x509ToVerify = (Asn1X509CertToVerify *)0;
  VtBasicCertVerifyInfo *vInfo;
  unsigned char *issuerName;
  unsigned char *temp;
  unsigned char *signature;
  unsigned char *digest = (unsigned char *)0;
  VoltSurrenderCtx *surrCtx = (VoltSurrenderCtx *)0;
  VtSurrenderCallback surrenderCtx;
  VtBasicCertVerifyInfo newVerifyInfo;
  VtSetAlgIdInfo algIdInfo;
  VtCertInfo certInfo;
  VtDerCoderInfo coderInfo;

  *verifyResult = 1;

  do
  {
    /* Check to see if the verifyInfo passed in is what we expect.
     */
    status = CheckBasicVerifyInfo (libCtx, obj, verifyInfo);
    if (status != 0)
      break;

    vInfo = (VtBasicCertVerifyInfo *)verifyInfo;

    /* Build the verification object from the signing algID.
     */
    algIdInfo.derCoders = derCoders;
    algIdInfo.derCoderCount = derCoderCount;
    algIdInfo.berEncoding = obj->certAsn1->innerCert->sigAlgId->base.data;
    algIdInfo.maxEncodingLen =
      (unsigned int)(obj->certAsn1->innerCert->sigAlgId->base.length);
    status = VtCreateAlgorithmObject (
      (VtLibCtx)libCtx, VtAlgorithmImplAlgId, (Pointer)&algIdInfo, &verifier);
    if (status != 0)
      break;

    /* If there's a surrender ctx, get it to pass along to verifiers.
     */
    if ( ((ctx->voltObject.objectType & VOLT_OBJECT_TYPE_SURRENDER) != 0) &&
          (ctx->voltObject.surrenderCtx != (Pointer)0) )
    {
      surrCtx = (VoltSurrenderCtx *)(ctx->voltObject.surrenderCtx);
      /* Set the verifying object with the surrender ctx, but don't copy
       * the appData, just copy a reference, so we're still using the
       * cert request object's appData.
       */
      surrenderCtx.Surrender = surrCtx->Surrender;
      surrenderCtx.appData = surrCtx->appData;
      surrenderCtx.AppDataCopy = (VtSurrenderAppDataCopy)0;
      surrenderCtx.AppDataFree = (VtSurrenderAppDataFree)0;
      status = VtSetAlgorithmParam (
        verifier, VtAlgorithmParamSurrenderCallback, (Pointer)&surrenderCtx);
      if (status != 0)
        break;
    }

    /* Get the digest object from the verification object.
     *
     * This feature currently does not work with the FIPS version of
     * the toolkit.
     */
/*    status = VtGetAlgorithmParam (
      verifier, VtAlgorithmParamSigDigestAlgObj, (Pointer *)&getDigester);
    if (status != 0)
      break;
 */

    /* Until the above code is fixed, run through the DerCoder's to get
     * the digest algorithm.
     * First, isolate the OID.
     */
    status = VoltDecodeDerLength (
      algIdInfo.berEncoding, algIdInfo.maxEncodingLen,
      &lengthLen, &valueLen);
    if (status != 0)
      break;

    offset = 1 + lengthLen;
    status = VoltDecodeDerLength (
      algIdInfo.berEncoding + offset, algIdInfo.maxEncodingLen - offset,
      &lengthLen, &valueLen);
    if (status != 0)
      break;

    offset += 1 + lengthLen;

    coderInfo.info.getAlgData.libCtx = libCtx;
    coderInfo.info.getAlgData.oid = algIdInfo.berEncoding + offset;
    coderInfo.info.getAlgData.oidLen = valueLen;
    coderInfo.info.getAlgData.algorithm = &algorithm;
    coderInfo.info.getAlgData.SymKeyParam = (VtKeyParam *)0;
    coderInfo.info.getAlgData.DigestImpl = (VtAlgorithmImpl *)0;
    for (index = 0; index < derCoderCount; ++index)
    {
      /* Call the DerCoder. If successful, we found what we were
       * looking for.
       */
      status = derCoders[index] (
        &coderInfo, (Pointer)0, VOLT_DER_TYPE_GET_ALG_FLAG);
      if (status == 0)
        break;
    }
    status = VT_ERROR_UNKNOWN_BER;
    if (index >= derCoderCount)
      break;

⌨️ 快捷键说明

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