?? defcertvfy.c
字號:
break;
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = VtCreateAlgorithmObject (
libCtx, coderInfo.info.getAlgData.DigestImpl, (Pointer)0,
&digester);
if (status != 0)
break;
/* Isolate the TBS portion of the cert.
*/
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_MEMORY;
x509ToVerify = Asn1X509CertToVerify_new ();
if (x509ToVerify == (Asn1X509CertToVerify *)0)
break;
Asn1SetObjectCopyFlag (
(VoltAsn1String *)(x509ToVerify->innerCert), VOLT_ASN1_COPY_REFERENCE);
VOLT_SET_FNCT_LINE (fnctLine)
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.
*/
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = VtDigestInit (digester);
if (status != 0)
break;
/* First call, get the size. We expect to get BUFFER_TOO_SMALL.
*/
VOLT_SET_FNCT_LINE (fnctLine)
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.
*/
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_MEMORY;
digest = (unsigned char *)Z2Malloc (bufferSize, 0);
if (digest == (unsigned char *)0)
break;
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
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;
/* Run through all the certs. Check to see if it is the issuer. If
* we find the issuer, we're done.
* If we don't find an issuer that passes signature and elements,
* we may find one that passes signature but not elements. We'll
* use that one, but set the VerifyFailureList.
*/
indexA = 0;
indexB = 0;
indexC = 0;
indexD = 0;
do
{
trusted = 0;
candidate = (VoltCertObject *)0;
sigVerify = 0;
elementVerify = 0;
if (indexA < ctx->trustedCerts.count)
{
candidate = (VoltCertObject *)(ctx->trustedCerts.certObjects[indexA]);
trusted = 1;
indexA++;
}
else if (indexB < tCount)
{
candidate = (VoltCertObject *)(trustedCerts->certObjects[indexB]);
trusted = 1;
indexB++;
}
else if (indexC < ctx->untrustedCerts.count)
{
candidate =
(VoltCertObject *)(ctx->untrustedCerts.certObjects[indexC]);
indexC++;
}
else if (indexD < uCount)
{
candidate = (VoltCertObject *)(untrustedCerts->certObjects[indexD]);
indexD++;
}
/* If we ran out of candidates, exit the loop.
*/
if (candidate == (VoltCertObject *)0)
break;
VOLT_SET_FNCT_LINE (fnctLine)
status = IsIssuerCert (
libCtx, obj->mpCtx, verifyCtx, &newVerifyInfo, vfyFailList,
&certInfo, verifier, issuerName, issuerNameLen,
digestAlg, digest, digestLen, signature, signatureLen,
candidate, &sigVerify, &elementVerify);
if (status != 0)
break;
/* If sigVerify is False, forget about that cert.
* If everything verified, we're done.
* If sigVerify is True but elementVerify is false, we may want
* to save the cert anyway.
*/
if (sigVerify == 0)
continue;
if (elementVerify != 0)
break;
/* If we reach this point, we found a cert that matched name and
* verified the signature, but that cert did not verify elements.
* Save it in case we find nothing that verifies all.
* If we find multiples, save only the first one.
*/
if (saveCert != (VoltCertObject *)0)
continue;
saveCert = candidate;
saveTrusted = trusted;
} while (1);
if (status != 0)
break;
/* If sigVerify and elementVerify are both True, we found a good
* cert. If it is trusted, we're done. If not, we'll have to check
* it.
*/
if ( (sigVerify != 0) && (elementVerify != 0) )
{
*verifyResult = 1;
if (trusted != 0)
break;
/* This is not a trusted cert, we'll have to verify this one.
*/
*verifyResult = 0;
saveCert = candidate;
saveTrusted = trusted;
}
/* If we reach this point, we need to check a saveCert. Well, if
* there is one. If not, we found no cert to verify the current
* cert, so log that in the VerifyList and exit.
*/
if (saveCert == (VoltCertObject *)0)
{
VOLT_SET_FNCT_LINE (fnctLine)
status = VoltAddVerifyListEntry (
(VoltVerifyFailureList *)vfyFailList,
VT_VFY_FAIL_REASON_CERT_CHAIN, certToVerify);
break;
}
/* If elementVerify is False, that means the saveCert verified the
* signature, but didn't verify the elements. If there's a verify
* failure list, we'll want to log those errors.
*/
if (elementVerify == 0)
{
if (vfyFailList != (VtVerifyFailureList)0)
{
VOLT_SET_FNCT_LINE (fnctLine)
status = DefaultVerifyCertElements (
verifyCtx, (Pointer)&newVerifyInfo, saveCert, vfyFailList,
&elementVerify);
if (status != 0)
break;
}
}
/* If this cert is not trusted, verify it.
*/
if (saveTrusted == 0)
{
VOLT_SET_FNCT_LINE (fnctLine)
status = DefaultVerifyCertSignature (
verifyCtx, (Pointer)&newVerifyInfo, saveCert,
storageCtx, trustedCerts, untrustedCerts,
derCoders, derCoderCount, vfyFailList, verifyResult);
break;
}
*verifyResult = elementVerify;
} while (0);
if (digest != (unsigned char *)0)
Z2Free (digest);
if (x509ToVerify != (Asn1X509CertToVerify *)0)
Asn1X509CertToVerify_free (x509ToVerify);
VtDestroyAlgorithmObject (&verifier);
VtDestroyAlgorithmObject (&digester);
VOLT_LOG_ERROR_INFO_COMPARE (
status, 0, verifyCtx, status, 0, errorType,
(char *)0, "DefaultVerifyCertSignature", fnctLine, (char *)0)
return (status);
}
static int CheckBasicVerifyInfo (
VoltLibCtx *libCtx,
VoltCertObject *obj,
Pointer info
)
{
int status;
unsigned int keyUsage;
VtBasicCertVerifyInfo *vInfo;
unsigned char *temp;
VOLT_DECLARE_ERROR_TYPE (errorType)
VOLT_DECLARE_FNCT_LINE (fnctLine)
do
{
/* We must have verifyInfo.
*/
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_INVALID_INPUT;
if (info == (Pointer)0)
break;
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
vInfo = (VtBasicCertVerifyInfo *)info;
status = VoltIsValidTime (libCtx, &(vInfo->usageTime));
if (status != 0)
break;
/* Check to see if any stray keyUsage bits are set.
*/
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
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;
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_MEMORY;
obj->certAsn1 = Asn1X509Cert_new ();
if (obj->certAsn1 == (Asn1X509Cert *)0)
break;
VOLT_SET_FNCT_LINE (fnctLine)
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);
VOLT_LOG_ERROR_INFO_COMPARE (
status, libCtx, obj, status, 0, errorType,
(char *)0, "CheckBasicVerifyInfo", fnctLine, (char *)0)
return (status);
}
static int IsIssuerCert (
VoltLibCtx *libCtx,
VoltMpIntCtx *mpCtx,
VtCertVerifyCtx verifyCtx,
VtBasicCertVerifyInfo *verifyInfo,
VtVerifyFailureList vfyFailList,
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 candidateCert,
unsigned int *sigVerify,
unsigned int *elementVerify
)
{
int status;
unsigned int checkNameLen;
VtKeyObject verifyKey = (VtKeyObject)0;
unsigned char *checkName;
VOLT_DECLARE_FNCT_LINE (fnctLine)
*sigVerify = 0;
*elementVerify = 0;
status = 0;
do
{
/* Check the info, this will build the certAsn1 if it's not
* already built.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = CheckBasicVerifyInfo (
libCtx, candidateCert, (Pointer)verifyInfo);
if (status != 0)
break;
/* Is this cert's subject name the same as the issuer name of the
* leaf cert we're checking?
*/
checkName = candidateCert->certAsn1->innerCert->subject->base.data;
checkNameLen =
(unsigned int)(candidateCert->certAsn1->innerCert->subject->base.length);
if (checkNameLen != nameLen)
break;
if (Z2Memcmp (checkName, name, nameLen) != 0)
break;
/* We found a cert with a subject name matching the issuer name of
* the leaf. Try to verify the signature.
* Build a public key from this cert.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = VtCreateKeyObject (
(VtLibCtx)libCtx, VtKeyImplMpCtx, (Pointer)mpCtx, &verifyKey);
if (status != 0)
break;
certInfo->cert = candidateCert->certificate.data;
certInfo->certLen = candidateCert->certificate.len;
VOLT_SET_FNCT_LINE (fnctLine)
status = VtSetKeyParam (
verifyKey, VtKeyParamX509Cert, (Pointer)certInfo);
if (status != 0)
break;
/* Try to verify the cert using this key.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = VtVerifySignature (
verifier, verifyKey, (VtRandomObject)0, digestAlg,
digest, digestLen, signature, signatureLen, sigVerify);
if (status != 0)
break;
/* If it did not verify, forget it.
*/
if (*sigVerify == 0)
break;
/* Verify the elements of this cert.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = DefaultVerifyCertElements (
verifyCtx, (Pointer)verifyInfo, (VtCertObject)candidateCert,
vfyFailList, elementVerify);
} while (0);
VtDestroyKeyObject (&verifyKey);
VOLT_LOG_ERROR_INFO_COMPARE (
status, libCtx, 0, status, 0, 0,
(char *)0, "CheckBasicVerifyInfo", fnctLine, (char *)0)
return (status);
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -