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

📄 defcertvfy.c

📁 voltage 公司提供的一个开发Ibe的工具包
💻 C
📖 第 1 页 / 共 2 页
字号:
    status = VtCreateAlgorithmObject (
      libCtx, coderInfo.info.getAlgData.DigestImpl, (Pointer)0,
      &digester);
    if (status != 0)
      break;
    
    /* Isolate the TBS portion of the cert.
     */
    status = VT_ERROR_MEMORY;
    x509ToVerify = Asn1X509CertToVerify_new ();
    if (x509ToVerify == (Asn1X509CertToVerify *)0)
      break;

    Asn1SetObjectCopyFlag (
      (VoltAsn1String *)(x509ToVerify->innerCert), VOLT_ASN1_COPY_REFERENCE);

    status = VT_ERROR_UNKNOWN_BER;
    temp = obj->certificate.data;
    d2i_Asn1X509CertToVerify (&x509ToVerify, &temp, obj->certificate.len);

    /* Did it work?
     */
    if (x509ToVerify == (Asn1X509CertToVerify *)0)
      break;

    /* Digest the data.
     */
    status = VtDigestInit (digester);
    if (status != 0)
      break;

    /* First call, get the size. We expect to get BUFFER_TOO_SMALL.
     */
    status = VtDigestFinal (
      digester, x509ToVerify->innerCert->base.data,
      (unsigned int)(x509ToVerify->innerCert->base.length),
      (unsigned char *)0, 0, &bufferSize);
    if (status == 0)
      status = VT_ERROR_GENERAL;
    if (status != VT_ERROR_BUFFER_TOO_SMALL)
      break;

    /* Allocate a buffer to hold the digest.
     */
    status = VT_ERROR_MEMORY;
    digest = (unsigned char *)Z2Malloc (bufferSize, 0);
    if (digest == (unsigned char *)0)
      break;

    status = VtDigestFinal (
      digester, x509ToVerify->innerCert->base.data,
      (unsigned int)(x509ToVerify->innerCert->base.length),
      digest, bufferSize, &digestLen);
    if (status != 0)
      break;

    digestAlg = ((VoltDigestClassCtx *)
      (((VoltAlgorithmObject *)digester)->classCtx))->algorithm;

    /* Isolate the signature.
     */
    signature = x509ToVerify->signature->data;
    signatureLen = (unsigned int)(x509ToVerify->signature->length);

    /* Find the issuer. First, what is the issuerName in the leaf cert?
     */
    issuerName = obj->certAsn1->innerCert->issuer->base.data;
    issuerNameLen =
      (unsigned int)(obj->certAsn1->innerCert->issuer->base.length);

    /* Build the verifyInfo to check a cert signing cert.
     */
    newVerifyInfo.keyUsage = VT_KEY_USAGE_KEY_CERT_SIGN;
    newVerifyInfo.usageTime = vInfo->usageTime;

    /* Use this to build keys from certs.
     */
    certInfo.derCoders = derCoders;
    certInfo.derCoderCount = derCoderCount;

    /* Look through the trusted certs inside the ctx to see if we can
     * find the issuer cert.
     */
    status = CheckCertList (
      libCtx, obj->mpCtx, verifyCtx, &newVerifyInfo, &certInfo, verifier,
      issuerName, issuerNameLen, digestAlg, digest, digestLen,
      signature, signatureLen,
      ctx->trustedCerts.certObjects, ctx->trustedCerts.count,
      &verifyingCert);
    if (status != 0)
      break;

    /* If we found a verifying cert among this list, we're done.
     */
    if (verifyingCert != (VtCertObject)0)
      break;

    /* Couldn't find it yet, check the trusted certs passed in.
     */
    if (trustedCerts != (VtCertObjectList *)0)
    {
      status = CheckCertList (
        libCtx, obj->mpCtx, verifyCtx, &newVerifyInfo, &certInfo, verifier,
        issuerName, issuerNameLen, digestAlg, digest, digestLen,
        signature, signatureLen,
        trustedCerts->certObjects, trustedCerts->count, &verifyingCert);
      if (status != 0)
        break;
    }

    /* If we found a verifying cert among this list, we're done.
     */
    if (verifyingCert != (VtCertObject)0)
      break;

    /* Try the list of untrusted certs inside the ctx.
     */
    status = CheckCertList (
      libCtx, obj->mpCtx, verifyCtx, &newVerifyInfo, &certInfo, verifier,
      issuerName, issuerNameLen, digestAlg, digest, digestLen,
      signature, signatureLen,
      ctx->untrustedCerts.certObjects, ctx->untrustedCerts.count,
      &verifyingCert);
    if (status != 0)
      break;

    /* If we found the cert, we now need to verify it. The
     * CheckCertList already verified the elements, verify the
     * signature.
     */
    if (verifyingCert != (VtCertObject)0)
    {
      /* Whatever the result, return it.
       */
      status = DefaultVerifyCertSignature (
        verifyCtx, (Pointer)&newVerifyInfo, verifyingCert,
        storageCtx, trustedCerts, untrustedCerts,
        derCoders, derCoderCount, verifyResult);
      break;
    }

    /* Still no cert, try the untrusted certs passed in.
     */
    if (untrustedCerts != (VtCertObjectList *)0)
    {
      status = CheckCertList (
        libCtx, obj->mpCtx, verifyCtx, &newVerifyInfo, &certInfo, verifier,
        issuerName, issuerNameLen, digestAlg, digest, digestLen,
        signature, signatureLen,
        untrustedCerts->certObjects, untrustedCerts->count, &verifyingCert);
      if (status != 0)
        break;

      /* If we found the cert, we now need to verify it. The
       * CheckCertList already verified the elements, verify the
       * signature.
       */
      if (verifyingCert != (VtCertObject)0)
      {
        /* Whatever the result, return it.
         */
        status = DefaultVerifyCertSignature (
          verifyCtx, (Pointer)&newVerifyInfo, verifyingCert,
          storageCtx, trustedCerts, untrustedCerts,
          derCoders, derCoderCount, verifyResult);
        break;
      }
    }

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

  } while (0);

  if (digest != (unsigned char *)0)
    Z2Free (digest);
  if (x509ToVerify != (Asn1X509CertToVerify *)0)
    Asn1X509CertToVerify_free (x509ToVerify);
  VtDestroyAlgorithmObject (&verifier);
  VtDestroyAlgorithmObject (&digester);

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

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

  return (status);
}

static int CheckBasicVerifyInfo (
   VoltLibCtx *libCtx,
   VoltCertObject *obj,
   Pointer info
   )
{
  int status;
  unsigned int keyUsage;
  VtBasicCertVerifyInfo *vInfo;
  unsigned char *temp;

  do
  {
    /* We must have verifyInfo.
     */
    status = VT_ERROR_INVALID_INPUT;
    if (info == (Pointer)0)
      break;

    vInfo = (VtBasicCertVerifyInfo *)info;
    status = VoltIsValidTime (&(vInfo->usageTime));
    if (status != 0)
      break;

    /* Check to see if any stray keyUsage bits are set.
     */
    status = VT_ERROR_INVALID_INPUT;
    keyUsage =
      VT_KEY_USAGE_DIGITAL_SIGNATURE | VT_KEY_USAGE_NON_REPUDIATION |
      VT_KEY_USAGE_KEY_ENCIPHERMENT | VT_KEY_USAGE_DATA_ENCIPHERMENT |
      VT_KEY_USAGE_KEY_AGREEMENT | VT_KEY_USAGE_KEY_CERT_SIGN |
      VT_KEY_USAGE_CRL_SIGN | VT_KEY_USAGE_ENCIPHER | VT_KEY_USAGE_DECIPHER;
    keyUsage = ~keyUsage;
    keyUsage &= vInfo->keyUsage;
    if (keyUsage != 0)
      break;

    /* If the object does not contain the ASN.1 structure yet, build
     * it. If it does contain the structure, we're done.
     */
    status = 0;
    if (obj->certAsn1 != (Asn1X509Cert *)0)
      break;

    status = VT_ERROR_MEMORY;
    obj->certAsn1 = Asn1X509Cert_new ();
    if (obj->certAsn1 == (Asn1X509Cert *)0)
      break;

    status = VT_ERROR_UNKNOWN_BER;
    temp = obj->certificate.data;
    d2i_Asn1X509Cert (&(obj->certAsn1), &temp, obj->certificate.len);
    if (obj->certAsn1 == (Asn1X509Cert *)0)
      break;

    status = 0;

  } while (0);

  return (status);
}

static int CheckCertList (
   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 status, iStatus;
  unsigned int index, verifyResult, checkNameLen;
  VoltCertObject *currentCert = (VoltCertObject *)0;
  VtKeyObject verifyKey = (VtKeyObject)0;
  unsigned char *checkName;

  verifyResult = 0;
  *verifyingCert = (VtCertObject)0;

  status = 0;
  for (index = 0; index < certListCount; ++index)
  {
    currentCert = (VoltCertObject *)(certList[index]);

    /* Check the info, this will build the certAsn1 if it's not
     * already built. If this doesn't work, just move on to the next
     * cert.
     */
    iStatus = CheckBasicVerifyInfo (libCtx, currentCert, (Pointer)verifyInfo);
    if (iStatus != 0)
      continue;

    /* Is this cert's subject name the same as the issuer name of the
     * leaf cert we're checking?
     */
    checkName = currentCert->certAsn1->innerCert->subject->base.data;
    checkNameLen =
      (unsigned int)(currentCert->certAsn1->innerCert->subject->base.length);

    if (checkNameLen != nameLen)
      continue;
    if (Z2Memcmp (checkName, name, nameLen) != 0)
      continue;

    /* We found a cert with a subject name matching the issuer name of
     * the leaf. Verify the elements of this cert.
     */
    iStatus = DefaultVerifyCertElements (
      verifyCtx, (Pointer)verifyInfo, (VtCertObject)currentCert,
      &verifyResult);
    if ( (iStatus != 0) || (verifyResult == 0) )
      continue;

    /* This cert's elements verify. Build a public key from this cert.
     */
    VtDestroyKeyObject (&verifyKey);
    status = VtCreateKeyObject (
      (VtLibCtx)libCtx, VtKeyImplMpCtx, (Pointer)mpCtx, &verifyKey);
    if (status != 0)
      break;

    certInfo->cert = currentCert->certificate.data;
    certInfo->certLen = currentCert->certificate.len;
    iStatus = VtSetKeyParam (
      verifyKey, VtKeyParamX509Cert, (Pointer)certInfo);
    if (iStatus != 0)
      continue;

    /* Try to verify the cert using this key.
     */
    status = VtVerifySignature (
      verifier, verifyKey, (VtRandomObject)0, digestAlg,
      digest, digestLen, signature, signatureLen, &verifyResult);
    if (status != 0)
      break;

    /* If it did not verify, try the next cert.
     */
    if (verifyResult == 0)
      continue;

    /* We found the cert, return it
     */
    *verifyingCert = (VtCertObject)currentCert;
    break;
  }

  VtDestroyKeyObject (&verifyKey);

  return (status);
}

⌨️ 快捷键说明

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