可以使用此函數從SIP接口對應的文件中提取簽名信息
CryptSIPVerifyIndirectData:將當前文件的哈希結果做為“指紋”,并與從CryptSIPGetSignedDataMsg中提取的簽名信息進行比較。
如果哈希結果相同,則意味著當前文件與之前簽名的文件相同;如果沒有,這意味著文件在傳輸或復制過程中被破壞。
第一部分:
BOOL WINAPI CryptSIPVerifyIndirectData(? ? IN SIP_SUBJECTINFO? ? ? *pSubjectInfo,
IN SIP_INDIRECT_DATA? ? *psData)
{
if (!(pSubjectInfo))
{
SetLastError((DWORD)ERROR_INVALID_PARAMETER);
return(FALSE);
}
? ? SIPObject_? ? ? ? ? *pSubjectObj;
? ? if (!(WVT_IS_CBSTRUCT_GT_MEMBEROFFSET(SIP_SUBJECTINFO, pSubjectInfo->cbSize, dwEncodingType)))
{
SetLastError((DWORD)ERROR_INVALID_PARAMETER);
return(FALSE);
}
? ? pSubjectObj = mssip_CreateSubjectObject(pSubjectInfo->pgSubjectType);
? ? if (!(pSubjectObj))
{
return(FALSE);
}
? ? //
//? if we are a catalog member, set the version number to whatever
//? was set when the catalog file was created...
//
if ((WVT_IS_CBSTRUCT_GT_MEMBEROFFSET(SIP_SUBJECTINFO, pSubjectInfo->cbSize, dwUnionChoice)) &&
(pSubjectInfo->dwUnionChoice == MSSIP_ADDINFO_CATMEMBER) &&
(pSubjectInfo->psCatMember))
{
if (pSubjectInfo->psCatMember->cbStruct == sizeof(MS_ADDINFO_CATALOGMEMBER))
{
if ((pSubjectInfo->psCatMember->pMember) &&
(pSubjectInfo->psCatMember->pMember->cbStruct == sizeof(CRYPTCATMEMBER)))
{
pSubjectInfo->dwIntVersion = pSubjectInfo->psCatMember->pMember->dwCertVersion;
}
}
}
? ? pSubjectObj->set_CertVersion(pSubjectInfo->dwIntVersion);
? ? if (pSubjectObj->get_CertVersion() < WIN_CERT_REVISION_2_0)
{
DWORD? ?dwCAPIFlags;
? ? ? ? CryptSIPGetRegWorkingFlags(&dwCAPIFlags);
? ? ? ? if (dwCAPIFlags & WTPF_VERIFY_V1_OFF)
{
delete pSubjectObj;
? ? ? ? ? ? SetLastError((DWORD)CRYPT_E_SECURITY_SETTINGS);
? ? ? ? ? ? return(FALSE);
}
}
? ? BOOL? ? bRet;
? ? bRet = pSubjectObj->VerifyIndirectData(pSubjectInfo, psData);
? ? delete pSubjectObj;
? ? return(bRet);
}
第二部分:
BOOL SIPObject_::VerifyIndirectData(SIP_SUBJECTINFO *pSI,
SIP_INDIRECT_DATA *psData)
{
if (!(psData))
{
if (this->FileHandleFromSubject(pSI))? ?// if the file exists, set bad parameter!
{
SetLastError((DWORD)ERROR_INVALID_PARAMETER);
}
return(FALSE);
}
? ? if (this->FileHandleFromSubject(pSI))
{
DWORD? ?cbDigest;
BYTE? ? *pbDigest;
? ? ? ? if (!(pbDigest = this->DigestFile(? pSI->hProv,
this->GetDigestFlags(pSI),
psData->DigestAlgorithm.pszObjId,
&cbDigest)))
{
return(FALSE);
}
if ((cbDigest != psData->Digest.cbData) ||
(memcmp(pbDigest,psData->Digest.pbData,cbDigest) != 0))
{
delete pbDigest;
? ? ? ? ? ? SetLastError(TRUST_E_BAD_DIGEST);
return(FALSE);
}
? ? ? ? delete pbDigest;
? ? ? ? return(TRUE);
}
? ? return(FALSE);
}
第三部分:
BYTE *SIPObject_::DigestFile(HCRYPTPROV hProv, DWORD dwFlags, char *pszObjId, DWORD *pcbDigest)
{
DIGEST_DATA? ? ? ? ? ? ?DigestData;
A_SHA_CTX? ? ? ? ? ? ? ?sShaCtx;
MD5_CTX? ? ? ? ? ? ? ? ?sMd5Ctx;
? ? *pcbDigest = 0;
? ? if ((DigestData.dwAlgId = CertOIDToAlgId(pszObjId)) == 0)
{
SetLastError((DWORD)NTE_BAD_ALGID);
return(NULL);
}
? ? DigestData.cbCache? ? ? ? ? = 0;
DigestData.hHash? ? ? ? ? ? = 0;
? ? switch (DigestData.dwAlgId)
{
case CALG_MD5:
DigestData.pvSHA1orMD5Ctx = &sMd5Ctx;
break;
? ? ? ? case CALG_SHA1:
DigestData.pvSHA1orMD5Ctx = &sShaCtx;
break;
? ? ? ? default:
DigestData.pvSHA1orMD5Ctx? ?= NULL;
}
? ? if (!(SipCreateHash(hProv, &DigestData)))
{
return(NULL);
}
? ? if (!(this->GetDigestStream(&DigestData, (DIGEST_FUNCTION)DigestFileData, dwFlags)))
{
return(NULL);
}
? ? // Data left over ?
if (DigestData.cbCache > 0)
{
if (!(SipHashData(&DigestData, DigestData.pbCache, DigestData.cbCache)))
{
SipDestroyHash(&DigestData);
return(NULL);
}
}
第四部分:
BOOL SipHashData(DIGEST_DATA *psDigestData, BYTE *pbData, DWORD cbData)
{
switch (psDigestData->dwAlgId)
{
case CALG_MD5:
MD5Update((MD5_CTX *)psDigestData->pvSHA1orMD5Ctx, pbData, cbData);
return(TRUE);
? ? ? ? case CALG_SHA1:
A_SHAUpdate((A_SHA_CTX *)psDigestData->pvSHA1orMD5Ctx, pbData, cbData);
return(TRUE);
}
? ? return(CryptHashData(psDigestData->hHash, pbData, cbData, 0));
}