?? defcertvfy.c
字號:
/* Copyright 2003-2006, 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 "vfylist.h"
#include "vtime.h"
#include "algobj.h"
#include "sign.h"
#include "digest.h"
#include "surrender.h"
#include "errorctx.h"
/* Implements VVerifyCertElements.
*/
int VOLT_CALLING_CONV DefaultVerifyCertElements VOLT_PROTO_LIST ((
VtCertVerifyCtx verifyCtx,
Pointer verifyInfo,
VtCertObject certToVerify,
VtVerifyFailureList vfyFailList,
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,
VtVerifyFailureList vfyFailList,
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 the given cert is the one we're looking for.
* <p>First, check the name, if it doesn't match, forget it.
* <p>If the name matches, check the signature. The caller passes in a
* signature and digest, the function will extract the public key from
* the cert and check the signature. If it does not verify, forget it.
* <p>If the signature verifies, set the sigVerify arg to True (1).
* <p>Next, check the elements of the cert. If the elements don't
* verify, set the elementVerify arg to False (0).
* <p>The caller passes in a candidate cert. If sigVerify is returned
* set to True, then the cert matches name and signature. If not,
* forget about this cert. If elementVerify is returned set to True,
* the cert is the one we're looking for. If sigVerify is True but
* elementVerify is False, the caller has to decide what to do with it.
* Accept it nonetheless? Reject it outright?
*/
static int VOLT_CALLING_CONV IsIssuerCert VOLT_PROTO_LIST ((
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,
VoltCertObject *candidateCert,
unsigned int *sigVerify,
unsigned int *elementVerify
));
int VtCertVerifyImplBasic (
VtCertVerifyCtx *certVerifyCtx,
Pointer info,
unsigned int flag
)
{
int status;
VoltCertVerifyCtx *ctx = (VoltCertVerifyCtx *)(*certVerifyCtx);
VOLT_DECLARE_FNCT_LINE (fnctLine)
do
{
/* Check the flag, it should be VOLT_CERT_VFY_CTX_SET_TYPE_FLAG.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_INVALID_TYPE;
if (flag != VOLT_CERT_VFY_CTX_SET_TYPE_FLAG)
break;
/* The associated info should be a null pointer.
*/
VOLT_SET_FNCT_LINE (fnctLine)
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);
VOLT_LOG_ERROR_INFO_COMPARE (
status, 0, *certVerifyCtx, status, 0, VT_ERROR_TYPE_PRIMARY,
(char *)0, "VtCertVerifyImplBasic", fnctLine, (char *)0)
return (status);
}
int DefaultVerifyCertElements (
VtCertVerifyCtx verifyCtx,
Pointer verifyInfo,
VtCertObject certToVerify,
VtVerifyFailureList vfyFailList,
unsigned int *verifyResult
)
{
int status, count, index;
unsigned int compareResult, value, valueLen;
VoltCertVerifyCtx *ctx = (VoltCertVerifyCtx *)verifyCtx;
VoltCertObject *obj = (VoltCertObject *)certToVerify;
VoltLibCtx *libCtx = (VoltLibCtx *)(obj->voltObject.libraryCtx);
VtBasicCertVerifyInfo *vInfo;
Asn1X509Extension *extension;
unsigned char keyUsageOid[VoltCertExtKeyUsageOidBytesLen] =
{ VoltCertExtKeyUsageOidBytes };
VOLT_DECLARE_FNCT_LINE (fnctLine)
do
{
*verifyResult = 1;
/* Check to see if the verifyInfo passed in is what we expect.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = CheckBasicVerifyInfo (libCtx, obj, verifyInfo);
if (status != 0)
break;
vInfo = (VtBasicCertVerifyInfo *)verifyInfo;
/* Get the validity dates. Compare to the value in the verifyInfo.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = VoltCompareTimeValidity (
libCtx, &(vInfo->usageTime),
obj->certAsn1->innerCert->validity->base.data,
(unsigned int)(obj->certAsn1->innerCert->validity->base.length),
&compareResult);
if (status != 0)
break;
/* If the cert is not within the validity period, put that info
* into the list.
*/
if (compareResult != 0)
{
*verifyResult = 0;
VOLT_SET_FNCT_LINE (fnctLine)
status = VoltAddVerifyListEntry (
(VoltVerifyFailureList *)vfyFailList,
VT_VFY_FAIL_REASON_CERT_VALIDITY, certToVerify);
if (status != 0)
break;
}
/* Now check the keyUsage extension.
* First, if there are no extensions, there's nothing to check.
*/
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)
{
/* Some bit in the cert extension was not set.
*/
*verifyResult = 0;
VOLT_SET_FNCT_LINE (fnctLine)
status = VoltAddVerifyListEntry (
(VoltVerifyFailureList *)vfyFailList,
VT_VFY_FAIL_REASON_CERT_KEY_USAGE, certToVerify);
if (status != 0)
break;
}
/* Do we need to check current district?
*/
if (ctx->checkInfo.flag == VT_CURRENT_DISTRICT_CHECK_IGNORE)
break;
VOLT_SET_FNCT_LINE (fnctLine)
status = VoltCheckCertCurrentDistrict (
ctx, obj, vfyFailList, &compareResult);
if (status != 0)
break;
if (compareResult == 0)
*verifyResult = 0;
} while (0);
if (status == 0)
return (0);
/* If error, make sure the verifyResult is did not verify.
*/
*verifyResult = 0;
VOLT_LOG_ERROR_INFO (
0, verifyCtx, status, 0, 0,
(char *)0, "DefaultVerifyCertElements", fnctLine, (char *)0)
return (status);
}
int DefaultVerifyCertSignature (
VtCertVerifyCtx verifyCtx,
Pointer verifyInfo,
VtCertObject certToVerify,
VtStorageCtx storageCtx,
VtCertObjectList *trustedCerts,
VtCertObjectList *untrustedCerts,
VtDerCoder **derCoders,
unsigned int derCoderCount,
VtVerifyFailureList vfyFailList,
unsigned int *verifyResult
)
{
int status;
unsigned int index, offset, theTag, lengthLen, valueLen, issuerNameLen;
unsigned int algorithm, bufferSize, digestAlg, digestLen, signatureLen;
unsigned int indexA, indexB, indexC, indexD, tCount, uCount;
unsigned int trusted, sigVerify, elementVerify, saveTrusted;
UInt32 lenLo, lenHi;
VoltCertVerifyCtx *ctx = (VoltCertVerifyCtx *)verifyCtx;
VoltCertObject *obj = (VoltCertObject *)certToVerify;
VoltCertObject *candidate;
VoltCertObject *saveCert = (VoltCertObject *)0;
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;
VOLT_DECLARE_ERROR_TYPE (errorType)
VOLT_DECLARE_FNCT_LINE (fnctLine)
*verifyResult = 0;
tCount = 0;
if (trustedCerts != (VtCertObjectList *)0)
tCount = trustedCerts->count;
uCount = 0;
if (untrustedCerts != (VtCertObjectList *)0)
uCount = untrustedCerts->count;
do
{
/* Check to see if the verifyInfo passed in is what we expect.
*/
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
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);
VOLT_SET_FNCT_LINE (fnctLine)
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;
VOLT_SET_FNCT_LINE (fnctLine)
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.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = VoltDecodeTagAndLen (
libCtx, algIdInfo.berEncoding, algIdInfo.maxEncodingLen,
&theTag, &lengthLen, &lenLo, &lenHi, sizeof (unsigned int));
if (status != 0)
break;
valueLen = (unsigned int)lenLo;
offset = 1 + lengthLen;
VOLT_SET_FNCT_LINE (fnctLine)
status = VoltDecodeTagAndLen (
libCtx, algIdInfo.berEncoding + offset, algIdInfo.maxEncodingLen - offset,
&theTag, &lengthLen, &lenLo, &lenHi, sizeof (unsigned int));
if (status != 0)
break;
valueLen = (unsigned int)lenLo;
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;
}
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_UNKNOWN_BER;
if (index >= derCoderCount)
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -