The CryptMsgControl function performs a special control function after the final CryptMsgUpdate call on a decoded cryptographic message. The controls include decryption, signature and hash verification, and the addition and deletion of certificates, CRLs, signers, and unauthenticated attributes.
Important changes have been made to the CryptoAPI in order to support S/MIME e-mail interoperability, which affect the handling of enveloped messages. See the Remarks for CryptMsgOpenToEncode for details.
#include <wincrypt.h>
BOOL WINAPI CryptMsgControl(
HCRYPTMSG hCryptMsg, // in
DWORD dwFlags, // in
DWORD dwCtrlType, // in
const void *pvCtrlPara // in
);
Message Control type | Value |
---|---|
CMSG_CTRL_VERIFY_SIGNATURE | 1 |
CMSG_CTRL_DECRYPT | 2 |
CMSG_CTRL_VERIFY_HASH | 5 |
CMSG_CTRL_ADD_SIGNER | 6 |
CMSG_CTRL_DEL_SIGNER | 7 |
CMSG_CTRL_ADD_SIGNER_UNAUTH_ATTR | 8 |
CMSG_CTRL_DEL_SIGNER_UNAUTH_ATTR | 9 |
CMSG_CTRL_ADD_CERT | 10 |
CMSG_CTRL_DEL_CERT | 11 |
CMSG_CTRL_ADD_CRL | 12 |
CMSG_CTRL_DEL_CRL | 13 |
For a value of CMSG_CTRL_DECRYPT in dwCtrlType, pvCtrlPara points to a CMSG_CTRL_DECRYPT_PARA structure used to decrypt the message for the specified recipient. For the case of decoding an streamed enveloped message, this value will initiate the decryption of the streamed content. If any encrypted streamed content has accumulated prior to this call, some or all of the plaintext resulting from the decryption of the ciphertext is passed back to the application through the callback function specified in the call to CryptMsgOpenToDecode. Note that when streaming an enveloped message, CryptMsgControl should not be called until the polling for the availability of the CMSG_ENVELOPE_ALGORITHM_PARAM succeeds or an error will result. See CryptMsgOpenToDecode for a description of that polling.
For a value of CMSG_CTRL_VERIFY_HASH in dwCtrlType, pvCtrlPara is not used, and should be set to NULL. The hash that was computed from the content of the message is compared against the hash that is contained in the message.
For a value of CMSG_CTRL_ADD_SIGNER in dwCtrlType, pvCtrlPara points to a CMSG_SIGNER_ENCODE_INFO structure containing the signer information to be added to the message.
For a value of CMSG_CTRL_DEL_SIGNER in dwCtrlType, pvCtrlPara points to a DWORD containing the index of the signer to be deleted. Note that once a deletion is made, any other signer indices in use for this message are invalidated and will need to be reacquired by calling CryptMsgGetParam.
For a value of CMSG_CTRL_ADD_SIGNER_UNAUTH_ATTR in dwCtrlType, pvCtrlPara points to a CMSG_CTRL_ADD_SIGNER_UNAUTH_ATTR_PARA structure containing the index of the signer and a blob containing the unauthenticated attribute information to be added to the message.
For a value of CMSG_CTRL_DEL_SIGNER_UNAUTH_ATTR in dwCtrlType, pvCtrlPara points to a CMSG_CTRL_DEL_SIGNER_UNAUTH_ATTR_PARA structure which contains the index specifying the signer and the index specifying the unauthenticated attribute (for that signer) to be deleted. Note that once a deletion is made, any other unauthenticated attribute indices in use for this signer are invalidated and will need to be reacquired by calling CryptMsgGetParam.
For a value of CMSG_CTRL_ADD_CERT in dwCtrlType, pvCtrlPara points to a BLOB Structure structure named CRYPT_DATA_BLOB that contains the encoded bytes of the certificate to be added to the message.
For a value of CMSG_CTRL_DEL_CERT in dwCtrlType, pvCtrlPara points to a DWORD containing the index of the certificate to be deleted from the message. Note that once a deletion is made, any other certificate indices in use for this message are invalidated and will need to be reacquired by calling CryptMsgGetParam.
For a value of CMSG_CTRL_ADD_CRL in dwCtrlType, pvCtrlPara points to a BLOB Structure named CRYPT_DATA_BLOB that contains the encoded bytes of the CRL to be added to the message.
For a value of CMSG_CTRL_DEL_CRL in dwCtrlType, pvCtrlPara points to a DWORD containing the index of the CRL to be deleted from the message. Note that once a deletion is made, any other CRL indices in use for this message are invalidated and will need to be reacquired by calling CryptMsgGetParam.
If the function being performed per the dwCtrlType fails, the return value is FALSE (zero). If it succeeds, the return value is true (non-zero).
When an streamed enveloped message is being decoded, errors encountered in the application defined callback function specified by pStreamInfo in CryptMsgOpenToDecode may be propagated to CryptMsgControl. If this happens, SetLastError is not called by CryptMsgControl after the callback returns, which preserves any errors encountered under the control of the application. It is the responsibility of the callback function (or one of the APIs that it calls) to call SetLastError if an error occurs while the application is processing the streamed data.
To retrieve extended error information, use the GetLastError function.
The following table lists the error codes most commonly returned by the GetLastError function.
Error code | Description |
---|---|
CRYPT_E_CONTROL_TYPE | The control type is not valid. |
for dwCtrlType == CMSG_CTRL_VERIFY_SIGNATURE | |
CRYPT_E_AUTH_ATTR_MISSING | The message does not contain an expected authenticated attribute. |
CRYPT_E_BAD_ENCODE | An error was encountered while encoding or decoding. |
CRYPT_E_HASH_VALUE | The hash value is not correct. |
CRYPT_E_INVALID_MSG_TYPE | The message type is invalid. |
CRYPT_E_OSS_ERROR | OSS Certificate encode/decode error code base. Note, to get the OSS error subtract CRYPT_E_OSS_ERROR from the returned error and see asn1code.h for details on the error. |
CRYPT_E_SIGNER_NOT_FOUND | The specified signer for the message was not found. |
CRYPT_E_UNEXPECTED_ENCODING | The message is not encoded as expected. |
CRYPT_E_UNKNOWN_ALGO | The cryptographic algorithm is unknown. |
E_OUTOFMEMORY | Ran out of memory. |
Propagated errors that may be encountered: | An error can be propagated from: CryptCreateHash CryptHashData CryptGetHashParam CryptImportKey CryptVerifySignature |
for dwCtrlType == CMSG_CTRL_DECRYPT | |
CRYPT_E_ALREADY_DECRYPTED | The message content has already been decrypted. |
CRYPT_E_INVALID_INDEX | The index value is not valid. |
CRYPT_E_INVALID_MSG_TYPE | The message type is invalid. |
CRYPT_E_RECIPIENT_NOT_FOUND | The enveloped data message does not contain the specified recipient. |
CRYPT_E_UNKNOWN_ALGO | The cryptographic algorithm is unknown. |
E_INVALIDARG | One or more arguments are invalid. |
E_OUTOFMEMORY | Ran out of memory. |
Propagated errors that may be encountered: | An error can be propagated from: CryptGetUserKey CryptImportKey CryptDecrypt |
for dwCtrlType == CMSG_CTRL_VERIFY_HASH | |
CRYPT_E_HASH_VALUE | The hash value is not correct. |
CRYPT_E_INVALID_MSG_TYPE | The message type is invalid. |
E_OUTOFMEMORY | Ran out of memory. |
Propagated errors that may be encountered: | An error can be propagated from: CryptGetHashParam |
for dwCtrlType == CMSG_CTRL_ADD_SIGNER | |
CRYPT_E_OID_FORMAT | The object identifier is badly formatted. |
CRYPT_E_OSS_ERROR | OSS Certificate encode/decode error code base. Note, to get the OSS error subtract CRYPT_E_OSS_ERROR from the returned error and see asn1code.h for details on the error. |
CRYPT_E_UNKNOWN_ALGO | The cryptographic algorithm is unknown. |
E_OUTOFMEMORY | Ran out of memory. |
Propagated errors that may be encountered: | An error can be propagated from: CryptCreateHash CryptHashData CryptGetHashParam CryptSignHash |
for dwCtrlType == CMSG_CTRL_ADD_SIGNER_UNAUTH_ATTR | |
CRYPT_E_INVALID_INDEX | The index value is not valid. |
CRYPT_E_OSS_ERROR | OSS Certificate encode/decode error code base. Note, to get the OSS error subtract CRYPT_E_OSS_ERROR from the returned error and see asn1code.h for details on the error. |
E_OUTOFMEMORY | Ran out of memory. |
See Signed Message Example Code.
See Enveloped Message Example 1.
See Hashed Message Example Code.
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.