The CryptVerifyDetachedMessageSignature function verifies a signed message containing a detached signature or signatures.
#include <wincrypt.h>
BOOL WINAPI CryptVerifyDetachedMessageSignature(
CRYPT_VERIFY_MESSAGE_PARA pVerifyPara, // in
DWORD dwSignerIndex, // in
const BYTE * pbDetachedSignBlob, // in
DWORD cbDetachedSignBlob, // in
DWORD cToBeSigned, // in
const BYTE *rgpbToBeSigned[ ], // in
DWORD *rgcbToBeSigned[ ], // in
PCCERT_CONTEXT *ppSignerCert // out, optional
);
TRUE if the function succeeded and the detached signature was verified. FALSE if the function failed to verify the signature.
Call GetLastError to see the reason for any failures. Note that errors from the called functions CryptCreateHash, CryptHashData, CryptVerifySignature, and CryptImportKey may be propagated to this function. This function has the following error codes:
Error code | Description |
---|---|
E_INVALIDARG | Invalid message and certificate encoding types. Currently only PKCS_7_ASN_ENCODING and X509_ASN_ENCODING_TYPE are supported. Invalid cbSize in *pVerifyPara. |
CRYPT_E_OSS_ERROR | Message ASN.1 decoding error. Note, to get the OSS error subtract CRYPT_E_OSS_ERROR from the returned error and see asn1code.h for details on the error. |
CRYPT_E_UNEXPECTED_MSG_TYPE | Not a signed cryptographic message. |
CRYPT_E_NO_SIGNER | The message doesn't have any signers or a signer for the specified dwSignerIndex. |
NTE_BAD_ALGID | The message was hashed and signed using an algorithm we don't know about or support. |
NTE_BAD_SIGNATURE | The message's signature was not verified. |
// EXAMPLE CODE FOR USING CryptVerifyDetachedMessageSignature() to
// verify a message's signatures. The signer's certificates are not
// required and won't be returned.
// Assume that the application already knows the address of the
// target detached signature blob (pbDetachedSignBlob) and its size
// (cbDetachedsignBlob), the address of the array of signatures to be
// verified (rgpbToBeSigned[]), the number of elements in the array
// (cToBeSigned), and the size of each of the elements
// (rgcbToBeSigned[]).
// Set up the variables.
CRYPT_VERIFY_MESSAGE_PARA VerifyPara; // Struct initialized elsewhere
DWORD dwSignerIndex = 0;
const BYTE* pbDetachedSignBlob; // Initialized elsewhere
DWORD cbDetachedSignBlob; // Initialized elsewhere
DWORD cToBeSigned = 3; // Initialized elsewhere
const BYTE* rgpbToBeSigned[3]; // Initialized elsewhere
DWORD rgcbToBeSigned[3]; // Initialized elsewhere
BOOL fReturn = FALSE;
DWORD dwErrorCode;
// Call CryptVerifyDetachedMessageSignature to verify the detached
// signatures.
while(TRUE)
{
fReturn = CryptVerifyDetachedMessageSignature(&VerifyPara,
dwSignerIndex, pbDetachedSignBlob,
cbDetachedSignBlob, cToBeSigned,
rgpbToBeSigned,rgcbToBeSigned, NULL);
if(fReturn != TRUE)
{
dwErrorCode = GetLastError();
if(dwErrorCode == CRYPT_E_NO_SIGNER)
{
cout << "Done verifying signatures";
break;
}
else
{
// A signer was not verified or an error occurred.
// Handle the condition.
}
}
dwSignerIndex ++;
}
// If dwErrorCode = CRYPT_E_NO_SIGNER at this point, the function succeeded,
// and all the signatures were verified.
Windows NT: Requires version 4.0 SP3 or later. Available also in IE 3.02 and later.
Windows: Requires Windows 98 (or Windows 95 with IE 3.02 or later).
Windows CE: Unsupported.
Header: Declared in wincrypt.h.
Import Library: Use crypt32.lib.