Encoding Enveloped Data
The tasks required to encode an enveloped message are depicted in the following illustration and described in the list that follows it.
The sequence of events for encoding enveloped data, as depicted in the previous illustration, is as follows:
-
A pointer to the plaintext message is retrieved.
-
A symmetric (session) key is generated.
-
The symmetric key and specified encryption algorithm are used to encrypt the message data.
-
A certificate store is opened.
-
The recipient's certificate is retrieved from the store.
-
The public key is retrieved from the recipient's certificate.
-
Using the recipient's public key, the symmetric key is encrypted.
-
From the recipients certificate, the recipient's ID is retrieved.
-
The following information is included in the digitally enveloped message: the data encryption algorithm, the encrypted data, the encrypted symmetric key, and the recipient information structure.
To use low-level message functions to accomplish the tasks just listed, use the following procedure.
To encode an enveloped message using CryptoAPI
-
Create or retrieve the content.
-
Get a cryptographic provider.
-
Get a recipient certificate.
-
Initialize the CMSG_ENVELOPED_ENCODE_INFO structure.
-
Call CryptMsgCalculateEncodedLength to get the size of the encoded message blob. Allocate memory for it.
-
Call CryptMsgOpenToEncode passing in CMSG_ENVELOPED for dwMsgType, and a pointer to CMSG_ENVELOPED_ENCODE_INFO for pvMsgEncodeInfo. As a result of this call, you will get a handle to the opened message.
-
Call CryptMsgUpdate passing in the handle retrieved in step 6, and a pointer to the data that is to be encrypted, enveloped, and encoded. This function can be called as many times as necessary to complete the encoding process.
-
Call CryptMsgGetParam, passing in the handle retrieved in step 6, and the appropriate parameter types to access the desired, encoded data. For example, pass in CMSG_CONTENT_PARAM to get a pointer to the entire PKCS #7 message.
If the result of this encoding is to be used as the inner data for another encoded message, such as an enveloped message, the CMSG_BARE_CONTENT_PARAM parameter must be passed. For example code showing this, see Enveloped Message Example 2.
-
Close the message by calling CryptMsgClose.
The result of this procedure is an encoded message that contains the encrypted data, the symmetric key that is encrypted with the recipient's public keys, and the recipient info data structures. The combination of encrypted content and an encrypted symmetric key for a recipient is a digital envelope for that recipient. Any type of content can be enveloped for multiple recipients.