Low-Level Message Functions Overview
The low-level message functions include the following:
-
CryptMsgCalculateEncodedLength. Calculates a length that is large enough (sometimes a little larger than necessary) to contain the returned value of the encoded message given the message type, encoding parameters, and total length of the data to be updated.
-
CryptMsgClose. Closes a cryptographic message handle.
-
CryptMsgControl. Performs a special control function after the final CryptMsgUpdate (see the description later in this list) of an encoded/decoded cryptographic message.
-
CryptMsgCountersign. Countersigns an unencoded signature that already exists in a message.
-
CryptMsgCountersignEncoded. Countersigns an already existing signature (encoded SignerInfo, as defined by PKCS #7).
-
CryptMsgGetParam. Gets a parameter (such as the content) after encoding/decoding a cryptographic message. Called after the final CryptMsgUpdate (see the description later in this list).
-
CryptMsgOpenToDecode. Opens a cryptographic message for decoding.
-
CryptMsgOpenToEncode. Opens a cryptographic message for encoding.
-
CryptMsgUpdate. Updates the content of a cryptographic message. Depending on how the message was opened, the content is either encoded or decoded.
-
CryptMsgVerifyCountersignatureEncoded. Verifies a countersignature in terms of the SignerInfo data structure (as defined by PKCS # 7).
One of the advantages of using these functions is that when a message is opened by using one of the open functions, it maintains state until it is closed. This allows a message to be constructed piecemeal by using the CryptMsgUpdate function. The disadvantage of using these functions, as opposed to the simplified message functions (described in Using Simplified Message Functions) is that more function calls are required—that is, you must do more of the work yourself. If the simplified message functions are used, more of the work is done for you.
Some of the additional work that you must do when using these functions involves making calls to functions in other categories, such as certificates or cryptographic functions. For example, to initialize some of the required data structures when using the low-level message functions, you must first call some of the certificate functions. The simplified message functions do some of this work for you.
The general procedures you use to encode or decode a message are as follows (The details will be covered in later sections):
To encode a message
-
Initialize the appropriate data structures for the desired data type.
-
Call CryptMsgOpenToEncode, passing the necessary arguments.
When calling CryptMsgOpenToEncode, and the data that is to be provided to CryptMsgUpdate has already been message-encoded, then the appropriate object identifier should be passed in pszInnerContentObjID (for example, "1.2.840.113549.1.7.2" for szOID_RSA_signedData). If pszInnerContentObjID is NULL, then the inner content type is assumed not to have been previously encoded, and is processed appropriately.
-
Call CryptMsgUpdate as many times as necessary to complete the message. On the last call, the fFinal parameter should be set TRUE (for the details, see CryptMsgUpdate).
-
Call CryptMsgGetParam to get a pointer to the desired parameters, such as the content.
-
Close the message by calling CryptMsgClose.
This procedure results in an encoded message of a type specified in the function calls.
To decode a message
-
Call CryptMsgOpenToDecode, passing the necessary arguments.
To maintain compatibility with Internet Explorer version 3.0, the dwMsgType parameter is provided. Signed data created in Internet Explorer version 3.0 does not contain header information. Therefore, if such a message is extracted from file signatures, the message type must be passed into the function. If zero is passed into the dwMsgType parameter, the function will read the message type from the header on the message. If the header is missing, the function call will fail. If successful, a handle to the opened message is returned.
-
Call CryptMsgUpdate once. This causes the appropriate actions to be taken on the message, depending on the message type.
-
If you want additional processing of the message, such as additional decryption or signature verification, call CryptMsgControl, passing the desired action in dwCtrlType.
-
Call CryptMsgGetParam to get a pointer to the desired parameters, such as the content.
-
Call CryptMsgClose to close the message.