CryptDecryptAndVerifyMessageSignature

The CryptDecryptAndVerifyMessageSignature function decrypts the message and verifies the signer.

#include <wincrypt.h>
BOOL WINAPI CryptDecryptAndVerifyMessageSignature(
  PCRYPT_DECRYPT_MESSAGE_PARA pDecryptPara,      // in
  PCRYPT_VERIFY_MESSAGE_PARA pVerifyPara,        // in
  DWORD dwSignerIndex,                           // in
  const BYTE *pbEncryptedBlob,                   // in
  DWORD cbEncryptedBlob,                         // in
  BYTE *pbDecrypted,                             // out, optional
  DWORD *pcbDecrypted,                           // in/out, optional
  PCCERT_CONTEXT *ppXchgCert,                    // out, optional
  PCCERT_CONTEXT *ppSignerCert                   // out, optional
);
 

Parameters

pDecryptPara
Pointer to the decryption parameters. For details, see Simplified Message Data Structures.
pVerifyPara
Pointer to the verification parameters. For details, see Simplified Message Data Structures.
dwSignerIndex
A message might have more than one signer. dwSignerIndex is an index to a particular signer, and can be iterated with multiple calls to the function. It should be set to zero for the first signer, or, as is the usual case, for a single signer. If the function returns FALSE, and GetLastError returns CRYPT_E_NO_SIGNER, the previous call got the last signer of the message.
pbEncryptedBlob
Pointer to the signed, encoded, and encrypted message that is to be decrypted and verified.
cbEncryptedBlob
Size, in bytes, of the encrypted message.
pbDecrypted
An optional parameter. Pointer to a buffer that receives the decrypted message.

This parameter can be NULL if the decrypted message is not required, or to set the size of the decrypted message for memory allocation purposes. For more information, see Common In/Out Parameter Conventions.

pcbDecrypted
An optional parameter. Pointer to a variable that specifies the size, in bytes, of the buffer pointed to by the pbDecrypted parameter. When the function returns, this variable contains the size of the decrypted message copied to *pbDecrypted. A decrypted message will not be returned if this parameter is NULL.

Note that when processing the data returned in the buffer, applications need to use the actual size of the data returned. The actual size may be slightly smaller than the size of the buffer specified on input. (On input, buffer sizes are usually specified large enough to insure that the largest possible output data will fit in the buffer.) On output, the variable pointed to by this parameter is updated to reflect the actual size of the data copied to the buffer.

ppXchgCert
An optional parameter. It is a pointer to the certificate context pointer corresponding to the exchange (private) key used to decrypt the message.
ppSignerCert
An optional parameter. It is a pointer to the certificate context pointer of the signer.

Return Values

TRUE if the function succeeded—the message was decrypted and the signer was verified. FALSE if the signer was not verified or if the function failed.

Call GetLastError to see the reason for any failures. Note that errors from the called functions CryptDecryptMessage and CryptVerifyMessageSignature may be propagated to this function.

This function has the following error codes.

Error code Description
ERROR_MORE_DATA If the buffer specified by the pbDecrypted parameter is not large enough to hold the returned data, the function sets the ERROR_MORE_DATA code, and stores the required buffer size, in bytes, into the variable pointed to by pcbDecrypted.

Remarks

For a successfully decrypted and verified message, the certificate context pointers pointed to by ppXchgCert and ppSignerCert are updated. They must be freed by calling CertFreeCertificateContext. If the function fails, they are set to NULL.

ppXchgCert and/or ppSignerCert can be NULL, indicating the caller isn't interested in getting the exchange certificate or the signer certificate context.

Example

// EXAMPLE CODE FOR USING CryptDecryptAndVerifyMessageSignature() to
// decrypt a message and verify the signer(s). In this example, the 
// caller is not interested in getting the certificate contexts,
// and therefore sets ppXchgCert and ppSignerCert to NULL.

// Assume that the application has a pointer (pbEncryptedBlob) to
// the received message string, and its size (cbEncryptedBlob).

// Set up the variables.
CRYPT_DECRYPT_MESSAGE_PARA  DecryptPara;  //Struct initialized
                                          //   elsewhere
CRYPT_VERIFY_MESSAGE_PARA   VerifyPara;   //Struct initialized
                                          //   elsewhere
DWORD                       dwSignerIndex = 0;
DWORD                       cbDecrypted;

// Call CryptDecryptAndVerifyMessageSignature() to verify the signers. 
BOOL        fReturn =            FALSE;
DWORD       dwReturn;
BOOL        fSignersVerified =   FALSE;

while(TRUE)
{

    fReturn = CryptDecryptAndVerifyMessageSignature(&DecryptPara, 
              &VerifyPara, dwSignerIndex, pbEncryptedBlob, 
              cbEncryptedBlob,    NULL, NULL, NULL, NULL);
    if(fReturn != TRUE)    // Function call failed.
    {    
        dwReturn = GetLastError();

        if (dwReturn == CRYPT_E_NO_SIGNER)
        {
            fSignersVerified = TRUE;
            break;
        }
        else
        {
            // A signer was not verified or an error occurred.
            // Handle the condition. 
        }
    }
    dwSignerIndex ++;
}

// If fSignersVerified = TRUE at this point all signers were
// verified.

// Call CryptDecryptAndVerifyMessageSignature() to get the size of the 
// decrypted message.
fReturn =    FALSE;
dwSignerIndex = 0;

fReturn = CryptDecryptAndVerifyMessageSignature(&DecryptPara, 
          &VerifyPara, dwSignerIndex, pbEncryptedBlob, 
          cbEncryptedBlob, NULL, &cbDecrypted, NULL, NULL);
if(fReturn != TRUE)
    ;// Function call failed.  Handle the error.

// If the call succeeded, the size of the message, in bytes, 
// now resides in cbDecrypted.

// Malloc memory for the size of the message.
BYTE* pbDecrypted;

pbDecrypted = (BYTE*)malloc(cbDecrypted);
if(pbDecrypted == NULL)
    ;// Handle the memory allocation error.

// Call CryptDecryptAndVerifyMessageSignature() again to decrypt 
// and return the message.
fReturn = CryptDecryptAndVerifyMessageSignature(&DecryptPara, 
          &VerifyPara, dwSignerIndex, pbEncryptedBlob, 
          cbEncryptedBlob, pbDecrypted, &cbDecrypted, NULL, NULL);
if(fReturn != TRUE)
    ;// The function call failed.  Handle the error.

// If the function succeeded, the decrypted message is now
// at the location pointed to by pbDecrypted.

// Perform local processing on the message.
...

// Free memory.
free (pbDecrypted);
 

QuickInfo

  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.

See Also

CryptDecryptMessage