可以使用此函数从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));
}