The following example code implements the procedure described in the previous section. Comments show which code fragments pertain to each step in the procedure. The details of the functions and structures can be found in Simplified Message Functions and Data Structures.
//-------------------------------------------------------------
//-------------------------------------------------------------
// EXAMPLE CODE TO VERIFY THE SIGNED MESSAGE JUST CREATED, BY
// USING THE CryptVerifyMessageSignature FUNCTION.
//-------------------------------------------------------------
//-------------------------------------------------------------
//-------------------------------------------------------------
// Get a pointer to and the size of the signed data. The pointer
// to the signed data blob, pbSignedMessageBlob, and the size,
// cbSignedMessageBlob, created in the previous code are used
// (Steps 1 and 2).
//-------------------------------------------------------------
//-------------------------------------------------------------
// Get a handle to a cryptographic provider. The handle,
// hCryptProv, created in the previous code is used (Step 3).
//-------------------------------------------------------------
//-------------------------------------------------------------
// Initialize the CRYPT_VERIFY_MESSAGE_PARA structure (Step 4).
// Also, see the GetSignerCertificate() function at the end of
// this code fragment.
//-------------------------------------------------------------
char VerifyArgs[] = "Arguments";
CRYPT_VERIFY_MESSAGE_PARA VerifyParams;
DWORD VerifyParamsSize = sizeof(VerifyParams);
memset(&VerifyParams, 0, VerifyParamsSize); // Initialize to zero.
// Then set the
// necessary fields.
VerifyParams.cbSize = VerifyParamsSize;
VerifyParams.dwMsgAndCertEncodingType = MY_ENCODING_TYPE;
VerifyParams.hCryptProv = hCryptProv;
VerifyParams.pfnGetSignerCertificate = GetSignerCertificate;
VerifyParams.pvGetArg = VerifyArgs;
//-------------------------------------------------------------
// Call CryptVerifyMessageSignature (Step 5).
//-------------------------------------------------------------
fReturn = CryptVerifyMessageSignature(
&VerifyParams, // Verify parameters
0, // Signer index
pbSignedMessageBlob, // Pointer to signed blob
cbSignedMessageBlob, // Size of signed blob
NULL, // Buffer for decoded msg
NULL, // Size of buffer
NULL); // Pointer to signer cert
if(FALSE == fReturn)
AfxMessageBox("Could Not Verify Message Signature");
else
AfxMessageBox("Signature Verified");
//-------------------------------------------------------------
// Clean up, free memory, and so forth.
//-------------------------------------------------------------
free(pbSignedMessageBlob);
//************************************************************
// GetSignerCertificate() - A callback function to get a certificate
// from a store.
//************************************************************
static PCCERT_CONTEXT WINAPI GetSignerCertificate(
IN void *pvVerifyArg,
IN DWORD dwCertEncodingType,
IN PCERT_INFO pSignerId, // Only the Issuer and SerialNumber
// fields are used
IN HCERTSTORE hMsgCertStore)
{
return CertGetSubjectCertificateFromStore( hMsgCertStore,
dwCertEncodingType,
pSignerId);
}