The CryptDecodeMessage function decodes, decrypts, and verifies a cryptographic message.
This function may be used when the type of cryptographic message is unknown. The constants for dwMsgTypeFlags may be combined with a bitwise OR operation so that the function will try to find one of the types. When one of the types is found, the function will report the type found, and return the data appropriate for the type found (see the pbDecoded parameter).
In a single pass, the function cracks only the first level of encryption or encoding. For additional cracking, the function needs to be called again, or one of the other Simplified Message Functions used for the additional cracking must be called.
#include <wincrypt.h>
BOOL WINAPI CryptDecodeMessage(
DWORD dwMsgTypeFlags, // in
PCRYPT_DECRYPT_MESSAGE_PARA pDecryptPara, // in
PCRYPT_VERIFY_MESSAGE_PARA pVerifyPara, // in
DWORD dwSignerIndex, // in
const BYTE *pbEncodedBlob, // in
DWORD cbEncodedBlob, // in
DWORD dwPrevInnerContentType, // in
DWORD *pdwMsgType, // out/optional
DWORD *pdwInnerContentType, // out/optional
BYTE *pbDecoded, // out/optional
DWORD *pcbDecoded, // in/out/optional
PCCERT_CONTEXT *ppXchgCert, // out/optional
PCCERT_CONTEXT *ppSignerCert // out/optional
);
CMSG_DATA
CMSG_SIGNED
CMSG_ENVELOPED
CMSG_SIGNED_AND_ENVELOPED
CMSG_HASHED
This parameter can be NULL if the decoded message is not required, or to set the size of the decoded message for memory allocation purposes. For more information, see Common In/Out Parameter Conventions.
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.
TRUE if the function succeeded. FALSE if the function failed.
Call GetLastError to see the reason for any failures. Note that errors from the called functions CryptDecryptMessage, CryptVerifyMessageSignature, or CryptVerifyMessageHash 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 pbDecoded 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 pcbDecoded. |
The dwMsgTypeFlags parameter specifies the set of allowable messages. For example, to decode either SIGNED or ENVELOPED messages, set dwMsgTypeFlags to CMSG_SIGNED_FLAG | CMSG_ENVELOPED_FLAG. Either or both of the pDecryptPara or pVerifyPara parameters must be specified.
Note that *pdwMsgType is updated with the type of the message.
For a successfully decoded or 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 or ppSignerCert can be NULL, indicating the caller isn't interested in getting the exchange certificate or the signer certificate context.
// EXAMPLE CODE FOR USING CryptDecodeMessage().
// Decodes, decrypts, and verifies a cryptographic message.
// Assume that pointers to the decription paramaters
// (pDecryptPara), the verification paramaters (pVerifyPara),
// and the encoded blob (pbEncodedBlob) have already been defined.
// Set up the variables.
DWORD dwMsgTypeFlags = CMSG_DATA_FLAG | CMSG_SIGNED_FLAG;
// Type of message flag
PCRYPT_DECRYPT_MESSAGE_PARA pDecryptPara;
// Struct initialized elsewhere -
// Pointer to decryption
// paramaters
PCRYPT_VERIFY_MESSAGE_PARA pVerifyPara;
// Struct initialized elsewhere -
// Pointer to verification
// paramaters
DWORD dwSignerIndex = 0; // Signer index - 0 for the first
// signer
const BYTE *pbEncodedBlob; // Initialized elsewhere -
// Pointer to the encoded blob
DWORD cbEncodedBlob = 128; // Size of encoded blob
DWORD dwPrevInnerContentType = 0; // Previous content type (eg.
// CMSG_DATA) - set to 0 for outer
// nested messages
DWORD *pdwMsgType; // Pointer to the message type
DWORD *pdwInnerContentType; // Pointer to type of inner message
// for outer message set to NULL
BYTE *pbDecoded; // Pointer to decoded message buffer
DWORD cbDecoded; // Size of decoded message
PCCERT_CONTEXT *ppXchgCert; // Pointer to certificate context
// pointer of the exchange key
PCCERT_CONTEXT *ppSignerCert; // Pointer to certificate context
// pointer of the signer
BOOL fResult; // Return TRUE if function succeeds
// FALSE if function fails
// Function called the first time to get the
// size of the decoded message (cbDecoded)
fResult= CryptDecodeMessage(
dwMsgTypeFlags,
pDecryptPara,
pVerifyPara,
dwSignerIndex,
pbEncodedBlob,
cbEncodedBlob,
dwPrevInnerContentType,
pdwMsgType,
pdwInnerContentType,
NULL, // NULL on first call
&cbDecoded,
ppXchgCert,
ppSignerCert);
if (!fResult){
cout<< "first call to CryptDecodeMessage failed"<< endl;
}
else {
cout<< "first call to CryptDecodeMessage successful"<< endl;
pbDecoded = (BYTE*) malloc (cbDecoded);
cout<< "memory allocated"<< endl;
}
// Function call decode the first level of encryption
fResult= CryptDecodeMessage(
dwMsgTypeFlags, // in
pDecryptPara, // in
pVerifyPara, // in
dwSignerIndex, // in
pbEncodedBlob, // in
cbEncodedBlob, // in
dwPrevInnerContentType, // in
pdwMsgType, // out/optional
pdwInnerContentType, // out/optional
pbDecoded, // out/optional
&cbDecoded, // in/out/optional
ppXchgCert, // out/optional
ppSignerCert); // out/optional
if (!fResult) { // FALSE
cout<< "Function failed"<< endl
<< "error code = "<< GetLastError()<< endl;
}
else { // TRUE
cout<< "Function succeeded"<< endl
<< "message type = "<< &pdwMsgType<< endl
<< "inner message type (NULL) = "<< &pdwInnerContentType<< endl
<< "size = "<< cbDecoded<< endl
<< "located at = "<< pbDecoded<< endl;
}
free (pbDecoded);
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.
CryptDecryptMessage, CryptVerifyMessageHash, CryptVerifyMessageSignature