CryptDecodeMessage

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
);
 

Parameters

dwMsgTypeFlags
Flags that control what message types get decoded. The following types are defined, and may be combined with the bitwise OR operator:
pDecryptPara
Pointer to the decryption parameters. For details, see Simplified Message Data Structures. Applicable to the message types: CMSG_ENVELOPED or CMSG_SIGNED_AND_ENVELOPED.
pVerifyPara
Pointer to the verification parameters. For details, see Simplified Message Data Structures. Applicable to the message types: CMSG_SIGNED, CMSG_SIGNED_AND_ENVELOPED and CMSG_HASHED.
dwSignerIndex
Message might have more than one signer, so 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. Only applicable to the message types: CMSG_SIGNED_AND_ENVELOPED or CMSG_SIGNED.
pbEncodedBlob
Pointer to the encoded blob that is to be decoded.
cbEncodedBlob
The size, in bytes, of the encoded blob.
dwPrevInnerContentType
Only applicable when processing nested cryptographic messages. When processing an outer cryptographic message, it must be set to zero. When decoding a nested cryptographic message, it should be set to the value returned at pdwInnerContentType by a previous calling of CryptDecodeMessage for the outer message. It can be any of the CMSG types listed in pdwMsgType. Set to zero for backward compatibility.
pdwMsgType
An optional parameter. Specifies the address where the message type is returned. Possible message types are:

CMSG_DATA
CMSG_SIGNED
CMSG_ENVELOPED
CMSG_SIGNED_AND_ENVELOPED
CMSG_HASHED

pdwInnerContentType
An optional parameter that is updated with the type of the inner message. Unless there is cryptographic message nesting, CMSG_DATA is returned. Set to NULL for backward compatibility.
pbDecoded
Optional parameter. Pointer to a buffer that receives the decoded message.

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.

pcbDecoded
An optional parameter. Pointer to a variable that specifies the size, in bytes, of the buffer pointed to by the pbDecoded parameter. When the function returns, this variable contains the size of the decoded message copied to *pbDecoded. A decoded 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's a pointer to the certificate context pointer corresponding to the exchange (private) key used to decode the message. Only updated for CMSG_ENVELOPED or CMSG_SIGNED_AND_ENVELOPED.
ppSignerCert
An optional parameter. It is a pointer to the certificate context pointer of the signer. Only updated for CMSG_SIGNED or CMSG_SIGNED_AND_ENVELOPED.

Return Values

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.

Remarks

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

// 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);
 

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, CryptVerifyMessageHash, CryptVerifyMessageSignature