📄 defcertvfy.c
字号:
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 + -