Decoding Enveloped Data
The general tasks required to decode an enveloped message are depicted in the following illustration and described in the list that follows it.

The sequence of events for decoding enveloped data, as depicted in the previous illustration, is as follows:
-
A pointer to the digitally enveloped message is retrieved.
-
A certificate store is opened.
-
From the message, the recipient ID (My ID) is retrieved.
-
The recipient ID is used to retrieve the certificate.
-
The private key from the certificate is retrieved.
-
The private key is used to decrypt the symmetric (session) key.
-
The encryption algorithm is retrieved from the message.
-
Using the private key and encryption algorithm, the data is decrypted.
To use low-level message functions to accomplish the tasks just listed, use the following procedure.
To decode an enveloped message using the CryptoAPI
-
Get a pointer to the encoded blob.
-
Call CryptMsgOpenToDecode, passing the necessary arguments.
-
Call CryptMsgUpdate once, passing in the handle retrieved in step 2, and a pointer to the data that is to be decoded. This causes the appropriate actions to be taken on the message, depending on the message type.
-
Call CryptMsgGetParam, passing in the handle retrieved in step 2, and CMSG_TYPE_PARAM to verify that the message is of the enveloped data type.
-
Again call CryptMsgGetParam, passing in CMSG_INNER_CONTENT_TYPE_PARAM, to get the data type of the inner content.
-
If the inner content data type is data, proceed to decrypt and decode the content. Otherwise, run a decode procedure appropriate for the content data type.
-
Assuming the inner content type is "data", initialize the CMSG_CTRL_DECRYPT_PARA data structure, and call CryptMsgControl, passing in CMSG_CTRL_DECRYPT and the address of the structure. The content will be decrypted.
-
Call CryptMsgGetParam, passing in CMSG_CONTENT_PARAM to get a pointer to the decoded content data blob (BYTE string).
-
Call CryptMsgClose to close the message.
The result of this procedure is that the message was decoded and decrypted, and a pointer was retrieved to the content data blob.