📄 readsign.c
字号:
)
{
int status;
unsigned int digestLen, newDigestLen, indexC;
unsigned int attrCount, contentOidLen, attrResult, sigResult, certResult;
VoltPkcs7Object *obj = (VoltPkcs7Object *)pkcs7Obj;
VoltLibCtx *libCtx = (VoltLibCtx *)(obj->voltObject.libraryCtx);
VoltPkcs7ReadSignCtx *readCtx;
VoltDigestClassCtx *digestCtx;
VtMpIntCtx mpCtx;
VtAlgorithmObject digestObj;
VtDistrictObject district = (VtDistrictObject)0;
Asn1SignerInfo *signerInfo;
unsigned char *digest;
unsigned char *contentOid;
VoltCertObject *signerCert;
VtCertObjectList *getCerts = (VtCertObjectList *)0;
VtCertObjectList trustedCerts;
VtCertObjectList untrustedCerts;
VtCertInfo certInfo;
VtSetAlgIdInfo algIdInfo;
VtKeyObject pubKey = (VtKeyObject)0;
VtAlgorithmObject verifier = (VtAlgorithmObject)0;
VoltSurrenderCtx *surrCtx = (VoltSurrenderCtx *)0;
unsigned char *newDigest = (unsigned char *)0;
Asn1P9Attribute **authAttrs;
VtSurrenderCallback surrenderCtx;
VOLT_DECLARE_ERROR_TYPE (errorType)
VOLT_DECLARE_FNCT_LINE (fnctLine)
*verifyResult = 0;
attrResult = 1;
sigResult = 0;
certResult = 0;
do
{
/* We can do this only after all the data has been read.
*/
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_INVALID_P7_OBJ;
if (obj->contentType != VOLT_PKCS7_SIGNED_DATA_READ)
break;
readCtx = (VoltPkcs7ReadSignCtx *)(obj->localCtx);
digestCtx = (VoltDigestClassCtx *)
(((VoltAlgorithmObject *)(readCtx->digestObj))->classCtx);
/* Get the requested SignerInfo.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_INVALID_P7_OBJ;
if (readCtx->signerInfosCount <= index)
break;
signerInfo = readCtx->signerInfos[index].signerInfo;
/* We'll need a digest object and MpCtx.
*/
digestObj = readCtx->digestObj;
mpCtx = readCtx->mpCtx;
/* Get the buffer that holds the digest of the data and the one
* that holds the contentOid.
*/
digest = readCtx->digest;
digestLen = readCtx->digestLen;
contentOid = readCtx->contentOid;
contentOidLen = readCtx->contentOidLen;
/* Put together a VtCertList of the untrusted certs (msgCerts).
*/
untrustedCerts.certObjects = readCtx->msgCerts;
untrustedCerts.count = readCtx->msgCertsCount;
trustedCerts.certObjects = (VtCertObject *)0;
trustedCerts.count = 0;
/* Get the DerCoders array.
*/
certInfo.derCoders = readCtx->DerCoders;
certInfo.derCoderCount = readCtx->derCoderCount;
/* Get the cert associated with this signer.
*/
indexC = 0;
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = VoltFindCertByReference (
libCtx, VOLT_FIND_CERT_BY_ISSUER_SERIAL,
signerInfo->issuerSerial->issuerName->base.data,
(unsigned int)(signerInfo->issuerSerial->issuerName->base.length),
signerInfo->issuerSerial->serialNumber->data,
(unsigned int)(signerInfo->issuerSerial->serialNumber->length),
&indexC, &untrustedCerts, (VtCertObject *)&signerCert);
if (status != 0)
{
if (status != VT_ERROR_ENTRY_NOT_FOUND)
break;
/* Couldn't find the signer cert, id does not verify.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = VoltAddVerifyListEntry (
(VoltVerifyFailureList *)vfyFailList,
VT_VFY_FAIL_REASON_NO_CERT, (VtCertObject)0);
break;
}
/* Build a key object from this cert.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = VtCreateKeyObject (
(VtLibCtx)libCtx, VtKeyImplMpCtx, (Pointer)mpCtx, &pubKey);
if (status != 0)
break;
certInfo.cert = signerCert->certificate.data;
certInfo.certLen = signerCert->certificate.len;
VOLT_SET_FNCT_LINE (fnctLine)
status = VtSetKeyParam (pubKey, VtKeyParamX509Cert, (Pointer)&certInfo);
if (status != 0)
break;
/* Build an object that verifies.
*/
algIdInfo.derCoders = certInfo.derCoders;
algIdInfo.derCoderCount = certInfo.derCoderCount;
algIdInfo.berEncoding = signerInfo->signatureAlg->base.data;
algIdInfo.maxEncodingLen =
(unsigned int)(signerInfo->signatureAlg->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 verifier.
*/
if ( ((obj->voltObject.objectType & VOLT_OBJECT_TYPE_SURRENDER) != 0) &&
(obj->voltObject.surrenderCtx != (Pointer)0) )
{
surrCtx = (VoltSurrenderCtx *)(obj->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;
}
/* Digest. First, get a buffer.
*/
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_MEMORY;
newDigestLen = digestLen;
newDigest = (unsigned char *)Z2Malloc (newDigestLen, 0);
if (newDigest == (unsigned char *)0)
break;
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = VtDigestInit (digestObj);
if (status != 0)
break;
/* The authenticatedAttributes are IMPLICIT, but the standard
* specifies digesting the regular tag (0x31) instead.
*/
newDigest[0] = 0x31;
VOLT_SET_FNCT_LINE (fnctLine)
status = VtDigestUpdate (digestObj, newDigest, 1);
if (status != 0)
break;
/* Digest the rest, without the leading IMPLICIT (0xA0) tag.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = VtDigestFinal (
digestObj, signerInfo->authAttributes->base.data + 1,
(unsigned int)(signerInfo->authAttributes->base.length - 1),
newDigest, newDigestLen, &newDigestLen);
if (status != 0)
break;
authAttrs = readCtx->signerInfos[index].authAttrs;
attrCount = readCtx->signerInfos[index].authAttrsCount;
/* Verify that the authenticated attribute messageDigest matches
* the messageDigest of the regular message.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = VerifyAuthAttribute (
libCtx, VOLT_P9_ATTRIBUTE_DIGEST, authAttrs, attrCount,
digest, digestLen, vfyFailList, &attrResult);
if (status != 0)
break;
/* Verify that the authenticated attribute contentType matches
* the contentType of the message.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = VerifyAuthAttribute (
libCtx, VOLT_P9_ATTRIBUTE_CONTENT_TYPE, authAttrs, attrCount,
contentOid, contentOidLen, vfyFailList, &attrResult);
if (status != 0)
break;
/* Now that we have the algorithm and key objects, perform the
* verification.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = VtVerifySignature (
verifier, pubKey, (VtRandomObject)0, digestCtx->algorithm,
newDigest, newDigestLen, signerInfo->signature->data,
(unsigned int)(signerInfo->signature->length), &sigResult);
if (status != 0)
break;
/* If the signature did not verify, log that info in the VerifyList.
*/
if (sigResult == 0)
{
VOLT_SET_FNCT_LINE (fnctLine)
status = VoltAddVerifyListEntry (
(VoltVerifyFailureList *)vfyFailList,
VT_VFY_FAIL_REASON_MSG_SIGNATURE, (VtCertObject)0);
if (status != 0)
break;
}
/* Now verify the cert. In order to do that, get the trusted certs
* from the district object. Get the district object based on the
* district name in the signer cert.
*/
status = VoltDistrictObjectFromCert (
libCtx, (VtCertObject)signerCert, policyCtx, storageCtx, transportCtx,
&district);
/* If the above function failed, continue without the certs. But if
* there is a district object, get the trusted certs out of it.
*/
if (district != (VtDistrictObject)0)
{
status = VtGetDistrictParam (
district, VtDistrictParamTrustedCerts, (Pointer *)&getCerts);
if (status == 0)
{
trustedCerts.certObjects = getCerts->certObjects;
trustedCerts.count = getCerts->count;
}
}
VOLT_SET_FNCT_LINE (fnctLine)
status = VtVerifyCert (
signerCert, certVerifyCtx, verifyCtxInfo,
readCtx->DerCoders, readCtx->derCoderCount,
&trustedCerts, &untrustedCerts, storageCtx, vfyFailList,
&certResult);
if (status != 0)
break;
/* If everything verified, set the return verifyResult to verifies.
*/
if ( (attrResult != 0) && (sigResult != 0) && (certResult != 0) )
*verifyResult = 1;
} while (0);
if (newDigest != (unsigned char *)0)
Z2Free (newDigest);
VtDestroyKeyObject (&pubKey);
VtDestroyAlgorithmObject (&verifier);
VtDestroyDistrictObject (&district);
VOLT_LOG_ERROR_INFO_COMPARE (
status, 0, pkcs7Obj, status, 0, errorType,
(char *)0, "VoltP7VerifySignerInfo", fnctLine, (char *)0)
return (status);
}
static int AddCertToList (
VoltLibCtx *libCtx,
VoltPkcs7ReadSignCtx *readCtx,
unsigned char *certDer,
unsigned int certDerLen
)
{
int status;
unsigned int bufferSize, index;
VtCertObject newCert = (VtCertObject)0;
VtCertObject *newList = (VtCertObject *)0;
VtCertInfo certInfo;
VOLT_DECLARE_ERROR_TYPE (errorType)
VOLT_DECLARE_FNCT_LINE (fnctLine)
do
{
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = VtCreateCertObject (
(VtLibCtx)libCtx, VtCertImplMpCtx, (Pointer)(readCtx->mpCtx),
&newCert);
if (status != 0)
break;
certInfo.derCoders = readCtx->DerCoders;
certInfo.derCoderCount = readCtx->derCoderCount;
certInfo.cert = certDer;
certInfo.certLen = certDerLen;
VOLT_SET_FNCT_LINE (fnctLine)
status = VtSetCertParam (
newCert, VtCertParamX509Der, (Pointer)&certInfo);
if (status != 0)
break;
/* Allocate enough to hold the certs currently in the list and this
* new cert.
*/
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_MEMORY;
bufferSize = (readCtx->msgCertsCount + 1) * sizeof (VtCertObject);
newList = (VtCertObject *)Z2Malloc (bufferSize, 0);
if (newList == (VtCertObject *)0)
break;
Z2Memset (newList, 0, bufferSize);
/* Copy the old into the new.
*/
for (index = 0; index < readCtx->msgCertsCount; ++index)
newList[index] = readCtx->msgCerts[index];
newList[index] = newCert;
/* Free the old.
*/
if (readCtx->msgCerts != (VtCertObject *)0)
Z2Free (readCtx->msgCerts);
/* Load the new.
*/
readCtx->msgCerts = newList;
readCtx->msgCertsCount++;
status = 0;
} while (0);
if (status == 0)
return (0);
/* If error, destroy what we created.
*/
VtDestroyCertObject (&newCert);
if (newList != (VtCertObject *)0)
Z2Free (newList);
VOLT_LOG_ERROR_INFO (
libCtx, 0, status, 0, errorType,
(char *)0, "AddCertToList", fnctLine, (char *)0)
return (status);
}
static int AddSignerInfoToList (
VoltLibCtx *libCtx,
VoltPkcs7ReadSignCtx *readCtx,
unsigned char *encoding,
unsigned int encodingLen
)
{
int status;
unsigned int bufferSize, index, indexA, authAttrsCount;
unsigned int theTag, lengthLen, valueLen;
UInt32 lenLo, lenHi;
VoltSignerInfoData *newList = (VoltSignerInfoData *)0;
Asn1SignerInfo *newSi = (Asn1SignerInfo *)0;
unsigned char *temp;
Asn1P9Attribute **authAttrs = (Asn1P9Attribute **)0;
Asn1Encoded *attrValue;
unsigned char signTimeOid[VoltP9AtSignTimeOidBytesLen] =
{ VoltP9AtSignTimeOidBytes };
VOLT_DECLARE_ERROR_TYPE (errorType)
VOLT_DECLARE_FNCT_LINE (fnctLine)
do
{
/* Create a new list.
*/
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_MEMORY;
bufferSize = (readCtx->signerInfosCount + 1) * sizeof (VoltSignerInfoData);
newList = (VoltSignerInfoData *)Z2Malloc (bufferSize, 0);
if (newList == (VoltSignerInfoData *)0)
break;
Z2Memset (newList, 0, bufferSize);
/* Copy the old into the new.
*/
for (index = 0; index < readCtx->signerInfosCount; ++index)
newList[index] = readCtx->signerInfos[index];
/* Get rid of the old.
*/
if (readCtx->signerInfos != (VoltSignerInfoData *)0)
Z2Free (readCtx->signerInfos);
readCtx->signerInfos = newList;
readCtx->signerInfosCount++;
VOLT_SET_FNCT_LINE (fnctLine)
newSi = Asn1SignerInfo_new ();
if (newSi == (Asn1SignerInfo *)0)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -