CryptMsgOpenToEncode

The CryptMsgOpenToEncode function opens a cryptographic message for encoding and returns a handle to the opened message. The message remains open until CryptMsgClose is called.

#include <wincrypt.h>
HCRYPTMSG WINAPI CryptMsgOpenToEncode(
  DWORD dwMsgEncodingType,         // in
  DWORD dwFlags,                   // in
  DWORD dwMsgType,                 // in
  const void *pvMsgEncodeInfo,     // in
  LPSTR pszInnerContentObjID,      // in/optional
  PCMSG_STREAM_INFO pStreamInfo    // in/optional
);
 

Parameters

dwMsgEncodingType
The type of message encoding used. Note that it is always acceptable to specify both the certificate and message encoding types, by combining them with a bitwise OR operation, as shown in the following example:
CRYPT_ASN_ENCODING | PKCS_7_ASN_ENCODING
 

However, it is required only to specify the message encoding here. Currently defined encoding types are shown in the following table.
Encoding type Value
CRYPT_ASN_ENCODING 0x00000001
PKCS_7_ASN_ENCODING 0x00010000

dwFlags
Flag values. Currently defined flags are shown in the following table:
Flag Value
CMSG_BARE_CONTENT_FLAG 0x00000001
CMSG_DETACHED_FLAG 0x00000004
CMSG_AUTHENTICATED_ATTRIBUTES_FLAG 0x00000008

CMSG_BARE_CONTENT_FLAG can be specified for a streamed message to indicate that the streamed output will not have an outer ContentInfo wrapper (as defined by PKCS #7). This makes it suitable to be streamed into an enclosing message.

The CMSG_DETACHED_FLAG indicates that there is detached data being supplied for the subsequent calls to CryptMsgUpdate.

The CMSG_AUTHENTICATED_ATTRIBUTES_FLAG indicates that authenticated attributes are forced to be included in the SignerInfo (as defined by PKCS #7) in cases where they would not otherwise be required.

dwMsgType
The message type. Currently defined types are shown in the following table.
Message type Associated structures Value
CMSG_DATA Raw data (no associated structure) 1
CMSG_SIGNED CMSG_SIGNER_ENCODE_INFO, CMSG_SIGNED_ENCODE_INFO 2
CMSG_ENVELOPED CMSG_ENVELOPED_ENCODE_INFO 3
CMSG_SIGNED_AND_
ENVELOPED
Not implemented. 4
CMSG_HASHED CMSG_HASHED_ENCODE_INFO 5
CMSG_ENCRYPTED Not implemented. 6

CMSG_DATA. An octet (BYTE) string.

CMSG_SIGNED. Consists of content of any type and encrypted message digests of the content for zero or more signers.

CMSG_ENVELOPED. Consists of encrypted content of any type and encrypted content-encryption keys for one or more recipients. The combination of encrypted content and encrypted content-encryption key for a recipient is a digital envelope for that recipient. See Remarks for issues concerning changes made to the CryptoAPI which affect the handling of enveloped messages in order to support S/MIME e-mail interoperability.

CMSG_SIGNED_AND_ENVELOPED. Consists of encrypted content of any type, encrypted content-encryption keys for one or more recipients, and doubly encrypted message digests for one or more signers. The double encryption consists of an encryption with a signer's private key followed by an encryption with the content-encryption key.

CMSG_HASHED. Consists of content of any type and a message digest of the content.

Note  Throughout the PKCS #7 specification, the terms "digest" and "digested" are used to refer to the value produced from applying a hashing algorithm to data. Throughout this document we have used the terms "hash" and "hashed" for the same purpose. For example, the data type used with the low-level message functions is called "hashed" rather than "digested." For the purposes of this document the two terms may be used interchangeably.

CMSG_ENCRYPTED. Consists of encrypted content of any type. Unlike the enveloped-data content type, the encrypted-data content type has neither recipients nor encrypted content-encryption keys. Keys are assumed to be managed by other means.

pvMsgEncodeInfo
Pointer to the data to be encoded. The type of data pointed to depends on the value of dwMsgType. The relationship between the dwMsgType and pvMsgEncodeInfo is given below:

When dwMsgType is CMSG_SIGNED, pvMsgEncodeInfo points to a CMSG_SIGNED_ENCODE_INFO structure which optionally contains an array of a CMSG_SIGNER_ENCODE_INFO structures.

When dwMsgType is CMSG_ENVELOPED, pvMsgEncodeInfo points to a CMSG_ENVELOPED_ENCODE_INFO structure.

When dwMsgType is CMSG_HASHED, pvMsgEncodeInfo points to a CMSG_HASHED_ENCODE_INFO structure.

pszInnerContentObjID
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 encoded as an octet string and given the type CMSG_DATA.

Note  When streaming is being used, pszInnerContentObjID must be either NULL or szOID_RSA_data.

The following algorithm object identifiers are commonly used, and they can be found in Wincrypt.h. The user may also define his own inner content usage. All that is required in this case is for the sender and receiver of the message to agree upon the semantics associated with the object identifier.
Name Base/Suffix Value
szOID_RSA_data szOID_PKCS_7 ".1" "1.2.840.113549.1.7.1"
szOID_RSA_signedData szOID_PKCS_7 ".2" "1.2.840.113549.1.7.2"
szOID_RSA_envelopedData szOID_PKCS_7 ".3" "1.2.840.113549.1.7.3"
szOID_RSA_signEnvData szOID_PKCS_7 ".4" "1.2.840.113549.1.7.4"
szOID_RSA_digestedData szOID_PKCS_7 ".5" "1.2.840.113549.1.7.5"
szOID_RSA_encryptedData szOID_PKCS_7 ".6" "1.2.840.113549.1.7.6"
SPC_INDIRECT_DATA_OBJID Not applicable "1.3.6.1.4.1.311.2.1.4"

pStreamInfo
When streaming is not being used, this parameter should be set to NULL.

When streaming is being used, this parameter should point to a CMSG_STREAM_INFO structure. The callback specified by pfnStreamOutput in the CMSG_STREAM_INFO structure is called when CryptMsgUpdate is executed. The callback is passed the encoded bytes resulting from the encoding. For more information on how to use the callback, see CMSG_STREAM_INFO.

Consider the case of a signed message being enclosed in an enveloped message. The encoded output from the streaming encode of the signed message can be fed into another streaming encode of the enveloped message, for example, the callback for the streaming encode of the signed message calls CryptMsgUpdate for the encode of the enveloped message. The callback for the enveloped message receives the encoded bytes of the nested signed message.

Return Values

A handle to the opened message is returned if successful. Returns NULL if the operation failed.

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_INVALID_MSG_TYPE The message type is invalid.
CRYPT_E_OID_FORMAT The object identifier is badly formatted.
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: For dwMsgType == CMSG_SIGNED an error can be propagated from
CryptCreateHash

For dwMsgType == CMSG_ENVELOPED an error can be propagated from
CryptGenKey
CryptImportKey
CryptExportKey

For dwMsgType ==CMSG_HASHED an error can be propagated from
CryptCreateHash


Remarks

Important changes have been made to the CryptoAPI which affects the handling of enveloped messages to support S/MIME e-mail interoperability. The changes take effect for products released after Service Pack 3, such as Microsoft® Internet Explorer 4.0 and Microsoft® Windows NT® 5.0. The following changes have been made:

For functions which perform encryption, the encrypted symmetric keys are reversed from little endian format to big endian format after CryptExportKey is called internally to the function. For functions which perform decryption, the encrypted symmetric keys are reversed from big endian format to little endian format before CryptImportKey is called internally to the function.

CRYPT_NO_SALT is specified when symmetric keys are generated and imported with CryptGenKey and CryptImportKey. Previously, 11 bytes of zero value salt was being used instead of using no salt.

For messages encrypted with the RC2 encryption algorithm, the KP_EFFECTIVE_KEYLEN is used with CryptGetKeyParam to determine the effective key length of the RC2 key being imported/exported (40, 64, or 128 bits). Previously, a default key length of 40 bits was always used when importing/exporting keys.

For messages encrypted with the RC2 encryption algorithm, encode and decode operations have been updated to handle ASN RC2 parameters for the contentEncryptionAlgorithm specified in the CMSG_ENVELOPED_ENCODE_INFO. Previously, the parameters were not supported. See the S/MIME documentation for more information.

For messages encrypted with the RC4, DES, and 3DES encryption algorithms, encode and decode operations have been updated to handle the ASN IV octet string parameter for the contentEncryptionAlgorithm specified in the CMSG_ENVELOPED_ENCODE_INFO. Previously, that parameter was not supported. See the S/MIME documentation for more information.

Example

See Signed Message Example Code.

See Enveloped Message Example 1.

See Hashed Message Example Code.

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

CryptMsgClose, CryptMsgUpdate, CryptMsgGetParam, CryptMsgOpenToDecode