using System;
using System.Runtime.InteropServices;
using Vanara.InteropServices;
using FILETIME = System.Runtime.InteropServices.ComTypes.FILETIME;
namespace Vanara.PInvoke
{
/// Methods and data types found in Crypt32.dll.
public static partial class Crypt32
{
/// A callback function used to read from and write data to a disk when processing large messages.
/// The arguments specified by CMSG_STREAM_INFO.
/// A pointer to a block of processed data that is available to the application.
/// The size, in bytes, of the block of processed data at pbData.
///
/// Specifies that the last block of data is being processed and that this is the last time the callback will be executed.
///
/// on success; on failure.
[PInvokeData("wincrypt.h", MSDNShortId = "a4e7f6e8-351f-4981-b223-50b65f503394")]
public delegate bool PFN_CMSG_STREAM_OUTPUT([In] IntPtr pvArg, [In] IntPtr pbData, uint cbData, [MarshalAs(UnmanagedType.Bool)] bool fFinal);
///
/// The CryptGetSignerCertificateCallback user supplied callback function is used with the CRYPT_VERIFY_MESSAGE_PARA
/// structure to get and verify a message signer's certificate.
///
///
///
///
/// Specifies the type of encoding used. 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:
///
/// X509_ASN_ENCODING | PKCS_7_ASN_ENCODING
/// Currently defined encoding types are:
///
/// -
/// X509_ASN_ENCODING
///
/// -
/// PKCS_7_ASN_ENCODING
///
///
///
///
/// A pointer to a CERT_INFO structure containing the issuer and serial number. Can be NULL if there is no content or signer.
///
/// A handle to the certificate store containing all the certificates and CRLs in the signed message.
///
/// If a signer certificate is found, the function returns a pointer to a read-only CERT_CONTEXT. The returned CERT_CONTEXT
/// was obtained either from a certificate store or was created using CertCreateCertificateContext. In either case, it must be freed
/// using CertFreeCertificateContext. If this function fails, the return value is NULL.
///
/// If the message does not contain content or signers, the function is called with pSignerId set to NULL.
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nc-wincrypt-pfn_crypt_get_signer_certificate
// PFN_CRYPT_GET_SIGNER_CERTIFICATE PfnCryptGetSignerCertificate; PCCERT_CONTEXT PfnCryptGetSignerCertificate( void *pvGetArg, DWORD
// dwCertEncodingType, PCERT_INFO pSignerId, HCERTSTORE hMsgCertStore ) {...}
[PInvokeData("wincrypt.h", MSDNShortId = "557ebb26-cce0-4c41-b49c-769b2831cf35")]
public delegate PCCERT_CONTEXT PFN_CRYPT_GET_SIGNER_CERTIFICATE([In, Out] IntPtr pvGetArg, CertEncodingType dwCertEncodingType, in CERT_INFO pSignerId, HCERTSTORE hMsgCertStore);
/// Flags for various structure behaviors.
[PInvokeData("wincrypt.h", MSDNShortId = "1601d860-6054-4650-a033-ea088655b7e4")]
[Flags]
public enum CryptMsgActionFlags
{
///
/// If the encoded output is to be a CMSG_SIGNED inner content of an outer cryptographic message such as a CMSG_ENVELOPED
/// message, the CRYPT_MESSAGE_BARE_CONTENT_OUT_FLAG must be set.
///
CRYPT_MESSAGE_BARE_CONTENT_OUT_FLAG = 0x00000001,
/// CRYPT_MESSAGE_ENCAPSULATED_CONTENT_OUT_FLAG can be set to encapsulate non-data inner content into an OCTET STRING.
CRYPT_MESSAGE_ENCAPSULATED_CONTENT_OUT_FLAG = 0x00000002,
///
/// CRYPT_MESSAGE_KEYID_SIGNER_FLAG can be set to identify signers by their Key Identifier and not their Issuer and Serial Number.
///
CRYPT_MESSAGE_KEYID_SIGNER_FLAG = 0x00000004,
///
/// CRYPT_MESSAGE_SILENT_KEYSET_FLAG can be set to suppress any UI by the CSP. For more information about the CRYPT_SILENT flag,
/// see CryptAcquireContext.
///
CRYPT_MESSAGE_SILENT_KEYSET_FLAG = 0x00000040,
}
/// Message control types.
[PInvokeData("wincrypt.h", MSDNShortId = "a990d44d-2993-429f-b817-2a834105ecef")]
public enum CryptMsgControlType
{
/// A BLOB that contains the encoded bytes of attribute certificate.
[CorrespondingType(typeof(CRYPTOAPI_BLOB))]
CMSG_CTRL_ADD_ATTR_CERT = 14,
/// A CRYPT_INTEGER_BLOB structure that contains the encoded bytes of the certificate to be added to the message.
[CorrespondingType(typeof(CRYPTOAPI_BLOB))]
CMSG_CTRL_ADD_CERT = 10,
///
/// A CMSG_CMS_SIGNER_INFO structure that contains signer information. This operation differs from CMSG_CTRL_ADD_SIGNER because
/// the signer information contains the signature.
///
[CorrespondingType(typeof(CMSG_CMS_SIGNER_INFO))]
CMSG_CTRL_ADD_CMS_SIGNER_INFO = 20,
/// A BLOB that contains the encoded bytes of the CRL to be added to the message.
[CorrespondingType(typeof(CRYPTOAPI_BLOB))]
CMSG_CTRL_ADD_CRL = 12,
/// A CMSG_SIGNER_ENCODE_INFO structure that contains the signer information to be added to the message.
[CorrespondingType(typeof(CMSG_SIGNER_ENCODE_INFO))]
CMSG_CTRL_ADD_SIGNER = 6,
///
/// A CMSG_CTRL_ADD_SIGNER_UNAUTH_ATTR_PARA structure that contains the index of the signer and a BLOB that contains the
/// unauthenticated attribute information to be added to the message.
///
[CorrespondingType(typeof(CMSG_CTRL_ADD_SIGNER_UNAUTH_ATTR_PARA))]
CMSG_CTRL_ADD_SIGNER_UNAUTH_ATTR = 8,
///
/// A CMSG_CTRL_DECRYPT_PARA structure used to decrypt the message for the specified key transport recipient. This value is
/// applicable to RSA recipients. This operation specifies that the CryptMsgControl function search the recipient index to
/// obtain the key transport recipient information. If the function fails, GetLastError will return CRYPT_E_INVALID_INDEX if no
/// key transport recipient is found.
///
[CorrespondingType(typeof(CMSG_CTRL_DECRYPT_PARA))]
CMSG_CTRL_DECRYPT = 2,
/// The index of the attribute certificate to be removed.
[CorrespondingType(typeof(uint))]
CMSG_CTRL_DEL_ATTR_CERT = 15,
/// The index of the certificate to be deleted from the message.
[CorrespondingType(typeof(uint))]
CMSG_CTRL_DEL_CERT = 11,
/// The index of the CRL to be deleted from the message.
[CorrespondingType(typeof(uint))]
CMSG_CTRL_DEL_CRL = 13,
/// The index of the signer to be deleted.
[CorrespondingType(typeof(uint))]
CMSG_CTRL_DEL_SIGNER = 7,
///
/// A CMSG_CTRL_DEL_SIGNER_UNAUTH_ATTR_PARA structure that contains an index that specifies the signer and the index that
/// specifies the signer's unauthenticated attribute to be deleted.
///
[CorrespondingType(typeof(CMSG_CTRL_DEL_SIGNER_UNAUTH_ATTR_PARA))]
CMSG_CTRL_DEL_SIGNER_UNAUTH_ATTR = 9,
///
/// A CERT_STRONG_SIGN_PARA structure used to perform strong signature checking.
///
/// To check for a strong signature, specify this control type before calling CryptMsgGetAndVerifySigner or before calling
/// CryptMsgControl with the following control types set:
///
/// CMSG_CTRL_VERIFY_SIGNATURE
/// CMSG_CTRL_VERIFY_SIGNATURE_EX
///
/// After the signature is successfully verified, this function checks for a strong signature. If the signature is not strong,
/// the operation will fail and the GetLastError value will be set to NTE_BAD_ALGID.
///
///
[CorrespondingType(typeof(CERT_STRONG_SIGN_PARA))]
CMSG_CTRL_ENABLE_STRONG_SIGNATURE = 21,
///
/// A CMSG_CTRL_KEY_AGREE_DECRYPT_PARA structure used to decrypt the message for the specified key agreement session key. Key
/// agreement is used with Diffie-Hellman encryption/decryption.
///
[CorrespondingType(typeof(CMSG_CTRL_KEY_AGREE_DECRYPT_PARA))]
CMSG_CTRL_KEY_AGREE_DECRYPT = 17,
///
/// A CMSG_CTRL_KEY_TRANS_DECRYPT_PARA structure used to decrypt the message for the specified key transport recipient. Key
/// transport is used with RSA encryption/decryption.
///
[CorrespondingType(typeof(CMSG_CTRL_KEY_TRANS_DECRYPT_PARA))]
CMSG_CTRL_KEY_TRANS_DECRYPT = 16,
///
/// A CMSG_CTRL_MAIL_LIST_DECRYPT_PARA structure used to decrypt the message for the specified recipient using a previously
/// distributed key-encryption key (KEK).
///
[CorrespondingType(typeof(CMSG_CTRL_MAIL_LIST_DECRYPT_PARA))]
CMSG_CTRL_MAIL_LIST_DECRYPT = 18,
/// This value is not used.
CMSG_CTRL_VERIFY_HASH = 5,
/// A CERT_INFO structure that identifies the signer of the message whose signature is to be verified.
[CorrespondingType(typeof(CERT_INFO))]
CMSG_CTRL_VERIFY_SIGNATURE = 1,
///
/// A CMSG_CTRL_VERIFY_SIGNATURE_EX_PARA structure that specifies the signer index and public key to verify the message
/// signature. The signer public key can be a CERT_PUBLIC_KEY_INFO structure, a certificate context, or a certificate chain context.
///
[CorrespondingType(typeof(CMSG_CTRL_VERIFY_SIGNATURE_EX_PARA))]
CMSG_CTRL_VERIFY_SIGNATURE_EX = 19,
}
/// Flags for message functions.
[PInvokeData("wincrypt.h", MSDNShortId = "1c12003a-c2f3-4069-8bd6-b8f2875b0c98")]
[Flags]
public enum CryptMsgFlags
{
///
/// Indicates that 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.
///
CMSG_BARE_CONTENT_FLAG = 0x00000001,
///
CMSG_LENGTH_ONLY_FLAG = 0x00000002,
/// Indicates that there is detached data being supplied for the subsequent calls to CryptMsgUpdate.
CMSG_DETACHED_FLAG = 0x00000004,
///
/// Authenticated attributes are forced to be included in the SignerInfo (as defined by PKCS #7) in cases where they would not
/// otherwise be required.
///
CMSG_AUTHENTICATED_ATTRIBUTES_FLAG = 0x00000008,
///
/// Used to calculate the size of a DER encoding of a message to be nested inside an enveloped message. This is particularly
/// useful when streaming is being performed.
///
CMSG_CONTENTS_OCTETS_FLAG = 0x00000010,
///
CMSG_MAX_LENGTH_FLAG = 0x00000020,
///
/// Non-Data type inner content is encapsulated within an OCTET STRING. This flag is applicable for both Signed and Enveloped messages.
///
CMSG_CMS_ENCAPSULATED_CONTENT_FLAG = 0x00000040,
///
CMSG_SIGNED_DATA_NO_SIGN_FLAG = 0x00000080,
///
/// If set, the hCryptProv that is passed to this function is released on the final CryptMsgUpdate. The handle is not released
/// if the function fails.
///
CMSG_CRYPT_RELEASE_CONTEXT_FLAG = 0x00008000,
}
/// Flags used by CMSG_KEY_AGREE_RECIPIENT_INFO.
[PInvokeData("wincrypt.h")]
public enum CryptMsgKeyOriginator
{
/// OriginatorCertId
CMSG_KEY_AGREE_ORIGINATOR_CERT = 1,
/// OriginatorPublicKeyInfo
CMSG_KEY_AGREE_ORIGINATOR_PUBLIC_KEY = 2,
}
///
/// Indicates the parameter types of data to be retrieved.
///
/// For an encoded message, only the CMSG_BARE_CONTENT, CMSG_ENCODE_SIGNER, CMSG_CONTENT_PARAM and CMSG_COMPUTED_HASH_PARAM
/// dwParamTypes are valid.
///
///
[PInvokeData("wincrypt.h", MSDNShortId = "5a05eb09-208f-4e94-abfa-c2f14c0a3164")]
public enum CryptMsgParamType
{
///
/// Returns the message type of a decoded message of unknown type. The retrieved message type can be compared to supported types
/// to determine whether processing can continued. For supported message types, see the dwMessageType parameter of CryptMsgOpenToDecode.
///
[CorrespondingType(typeof(uint))]
CMSG_TYPE_PARAM = 1,
///
/// Returns the whole PKCS #7 message from a message opened to encode. Retrieves the inner content of a message opened to
/// decode. If the message is enveloped, the inner type is data, and CryptMsgControl has been called to decrypt the message, the
/// decrypted content is returned. If the inner type is not data, the encoded BLOB that requires further decoding is returned.
/// If the message is not enveloped and the inner content is DATA, the returned data is the octets of the inner content. This
/// type is applicable to both encode and decode.
/// For decoding, if the type is CMSG_DATA, the content's octets are returned; else, the encoded inner content is returned.
///
[CorrespondingType(typeof(byte[]))]
[CorrespondingType(typeof(CRYPTOAPI_BLOB))]
CMSG_CONTENT_PARAM = 2,
///
/// Retrieves the encoded content of an encoded cryptographic message, without the outer layer of the CONTENT_INFO structure.
/// That is, only the encoding of the PKCS #7 defined ContentInfo.content field is returned.
///
[CorrespondingType(typeof(byte[]))]
CMSG_BARE_CONTENT_PARAM = 3,
/// Returns the inner content type of a received message. This type is not applicable to messages of type DATA.
[CorrespondingType(typeof(byte[]))]
CMSG_INNER_CONTENT_TYPE_PARAM = 4,
/// Returns the number of signers of a received SIGNED message.
[CorrespondingType(typeof(uint))]
CMSG_SIGNER_COUNT_PARAM = 5,
///
/// Returns information on a message signer. This includes the issuer and serial number of the signer's certificate and
/// authenticated and unauthenticated attributes of the signer's certificate. To retrieve signer information on all of the
/// signers of a message, call CryptMsgGetParam varying dwIndex from 0 to the number of signers minus one.
///
[CorrespondingType(typeof(byte[]))]
CMSG_SIGNER_INFO_PARAM = 6,
///
/// Returns information on a message signer needed to identify the signer's certificate. A certificate's Issuer and SerialNumber
/// can be used to uniquely identify a certificate for retrieval. To retrieve information for all the signers, repetitively call
/// CryptMsgGetParam varying dwIndex from 0 to the number of signers minus one. Only the Issuer and SerialNumber fields in the
/// CERT_INFO structure returned contain available, valid data.
///
[CorrespondingType(typeof(byte[]))]
CMSG_SIGNER_CERT_INFO_PARAM = 7,
///
/// Returns the hash algorithm used by a signer of the message. To get the hash algorithm for a specified signer, call
/// CryptMsgGetParam with dwIndex equal to that signer's index.
///
[CorrespondingType(typeof(byte[]))]
CMSG_SIGNER_HASH_ALGORITHM_PARAM = 8,
///
/// Returns the authenticated attributes of a message signer. To retrieve the authenticated attributes for a specified signer,
/// call CryptMsgGetParam with dwIndex equal to that signer's index.
///
[CorrespondingType(typeof(byte[]))]
CMSG_SIGNER_AUTH_ATTR_PARAM = 9,
///
/// Returns a message signer's unauthenticated attributes. To retrieve the unauthenticated attributes for a specified signer,
/// call CryptMsgGetParam with dwIndex equal to that signer's index.
///
[CorrespondingType(typeof(byte[]))]
CMSG_SIGNER_UNAUTH_ATTR_PARAM = 10,
/// Returns the number of certificates in a received SIGNED or ENVELOPED message.
[CorrespondingType(typeof(uint))]
CMSG_CERT_COUNT_PARAM = 11,
///
/// Returns a signer's certificate. To get all of the signer's certificates, call CryptMsgGetParam, varying dwIndex from 0 to
/// the number of available certificates minus one.
///
[CorrespondingType(typeof(byte[]))]
CMSG_CERT_PARAM = 12,
/// Returns the count of CRLs in a received, SIGNED or ENVELOPED message.
[CorrespondingType(typeof(uint))]
CMSG_CRL_COUNT_PARAM = 13,
///
/// Returns a CRL. To get all the CRLs, call CryptMsgGetParam, varying dwIndex from 0 to the number of available CRLs minus one.
///
[CorrespondingType(typeof(byte[]))]
CMSG_CRL_PARAM = 14,
/// Returns the encryption algorithm used to encrypt an ENVELOPED message.
[CorrespondingType(typeof(byte[]))]
CMSG_ENVELOPE_ALGORITHM_PARAM = 15,
/// Returns the number of key transport recipients of an ENVELOPED received message.
[CorrespondingType(typeof(uint))]
CMSG_RECIPIENT_COUNT_PARAM = 17,
///
/// Returns the index of the key transport recipient used to decrypt an ENVELOPED message. This value is available only after a
/// message has been decrypted.
///
[CorrespondingType(typeof(uint))]
CMSG_RECIPIENT_INDEX_PARAM = 18,
///
/// Returns certificate information about a key transport message's recipient. To get certificate information on all key
/// transport message's recipients, repetitively call CryptMsgGetParam, varying dwIndex from 0 to the number of recipients minus
/// one. Only the Issuer, SerialNumber, and PublicKeyAlgorithm members of the CERT_INFO structure returned are available and valid.
///
[CorrespondingType(typeof(byte[]))]
CMSG_RECIPIENT_INFO_PARAM = 19,
/// Returns the hash algorithm used to hash the message when it was created.
[CorrespondingType(typeof(byte[]))]
CMSG_HASH_ALGORITHM_PARAM = 20,
/// Returns the hash value stored in the message when it was created.
[CorrespondingType(typeof(byte[]))]
CMSG_HASH_DATA_PARAM = 21,
/// Returns the hash calculated of the data in the message. This type is applicable to both encode and decode.
[CorrespondingType(typeof(byte[]))]
CMSG_COMPUTED_HASH_PARAM = 22,
/// Returns the encryption algorithm used to encrypted the message.
[CorrespondingType(typeof(byte[]))]
CMSG_ENCRYPT_PARAM = 26,
/// Returns the encrypted hash of a signature. Typically used for performing time-stamping.
[CorrespondingType(typeof(byte[]))]
CMSG_ENCRYPTED_DIGEST = 27,
/// Returns the encoded CMSG_SIGNER_INFO signer information for a message signer.
[CorrespondingType(typeof(byte[]))]
CMSG_ENCODED_SIGNER = 28,
///
/// Changes the contents of an already encoded message. The message must first be decoded with a call to CryptMsgOpenToDecode.
/// Then the change to the message is made through a call to CryptMsgControl, CryptMsgCountersign, or
/// CryptMsgCountersignEncoded. The message is then encoded again with a call to CryptMsgGetParam, specifying
/// CMSG_ENCODED_MESSAGE to get a new encoding that reflects the changes made. This can be used, for instance, to add a
/// time-stamp attribute to a message.
///
[CorrespondingType(typeof(byte[]))]
CMSG_ENCODED_MESSAGE = 29,
/// Returns the version of the decoded message. For more information, see the table in the Remarks section.
[CorrespondingType(typeof(uint))]
CMSG_VERSION_PARAM = 30,
/// Returns the count of the attribute certificates in a SIGNED or ENVELOPED message.
[CorrespondingType(typeof(uint))]
CMSG_ATTR_CERT_COUNT_PARAM = 31,
///
/// Retrieves an attribute certificate. To get all the attribute certificates, call CryptMsgGetParam varying dwIndex set to 0
/// the number of attributes minus one.
///
[CorrespondingType(typeof(byte[]))]
CMSG_ATTR_CERT_PARAM = 32,
/// Returns the total count of all message recipients including key agreement and mail list recipients.
[CorrespondingType(typeof(uint))]
CMSG_CMS_RECIPIENT_COUNT_PARAM = 33,
/// Returns the index of the key transport, key agreement, or mail list recipient used to decrypt an ENVELOPED message.
[CorrespondingType(typeof(uint))]
CMSG_CMS_RECIPIENT_INDEX_PARAM = 34,
/// Returns the index of the encrypted key of a key agreement recipient used to decrypt an ENVELOPED message.
[CorrespondingType(typeof(uint))]
CMSG_CMS_RECIPIENT_ENCRYPTED_KEY_INDEX_PARAM = 35,
///
/// Returns information about a key transport, key agreement, or mail list recipient. It is not limited to key transport message
/// recipients. To get information on all of a message's recipients, repetitively call CryptMsgGetParam, varying dwIndex from 0
/// to the number of recipients minus one.
///
[CorrespondingType(typeof(byte[]))]
CMSG_CMS_RECIPIENT_INFO_PARAM = 36,
/// Returns the unprotected attributes in an enveloped message.
[CorrespondingType(typeof(byte[]))]
CMSG_UNPROTECTED_ATTR_PARAM = 37,
///
/// Returns information on a message signer needed to identify the signer's public key. This could be a certificate's Issuer and
/// SerialNumber, a KeyID, or a HashId. To retrieve information for all the signers, call CryptMsgGetParam varying dwIndex from
/// 0 to the number of signers minus one.
///
[CorrespondingType(typeof(byte[]))]
CMSG_SIGNER_CERT_ID_PARAM = 38,
///
/// Returns information on a message signer. This includes a signerId and authenticated and unauthenticated attributes. To
/// retrieve signer information on all of the signers of a message, call CryptMsgGetParam varying dwIndex from 0 to the number
/// of signers minus one.
///
[CorrespondingType(typeof(byte[]))]
CMSG_CMS_SIGNER_INFO_PARAM = 39,
}
/// Message signer type.
[PInvokeData("wincrypt.h", MSDNShortId = "56b73de8-c170-46f6-b488-096475b59c15")]
public enum CryptMsgSignerType
{
/// CERT_PUBLIC_KEY_INFO
[CorrespondingType(typeof(CERT_PUBLIC_KEY_INFO))]
CMSG_VERIFY_SIGNER_PUBKEY = 1,
/// CERT_CONTEXT
[CorrespondingType(typeof(CERT_CONTEXT))]
CMSG_VERIFY_SIGNER_CERT = 2,
/// CERT_CHAIN_CONTEXT
[CorrespondingType(typeof(CERT_CHAIN_CONTEXT))]
CMSG_VERIFY_SIGNER_CHAIN = 3,
/// The CMSG verify signer null
CMSG_VERIFY_SIGNER_NULL = 4,
}
/// Message types.
[PInvokeData("wincrypt.h", MSDNShortId = "1c12003a-c2f3-4069-8bd6-b8f2875b0c98")]
public enum CryptMsgType
{
/// An octet (BYTE) string.
CMSG_DATA = 1,
/// CMSG_SIGNED_ENCODE_INFO
CMSG_SIGNED = 2,
/// CMSG_ENVELOPED_ENCODE_INFO
CMSG_ENVELOPED = 3,
/// Not implemented.
CMSG_SIGNED_AND_ENVELOPED = 4,
/// CMSG_HASHED_ENCODE_INFO
CMSG_HASHED = 5,
/// Not implemented.
CMSG_ENCRYPTED = 6,
}
/// Flags that modify the function behavior.
[PInvokeData("wincrypt.h", MSDNShortId = "da756cd5-1dec-4d88-9c90-76dd263035eb")]
public enum CryptMsgVerifyCounterFlags
{
///
/// Performs a strong signature check after successful signature verification. Set the pvExtra parameter to point to a
/// CERT_STRONG_SIGN_PARA structure that contains the parameters needed to check the signature strength.. Windows 8 and Windows
/// Server 2012: Support for this flag begins.
///
CMSG_VERIFY_COUNTER_SIGN_ENABLE_STRONG_FLAG = 0x00000001
}
///
/// The CryptDecodeMessage function decodes, decrypts, and verifies a cryptographic message.
///
/// This function can be used when the type of cryptographic message is unknown. The dwMsgTypeFlags constants can be combined with a
/// bitwise- OR operation so that the function will try to find one of the types. When one of the types is found, the
/// function reports the type found and returns the data appropriate to that type.
///
///
/// In each pass, the function cracks only a single level of encryption or encoding. For additional cracking, this function, or one
/// of the other Simplified Message Functions, must be called again.
///
///
///
///
/// Indicates the message type. Message types can be combined with the bitwise- OR operator. This parameter can be one of the
/// following message types:
///
///
/// -
/// CMSG_DATA_FLAG
///
/// -
/// CMSG_SIGNED_FLAG
///
/// -
/// CMSG_ENVELOPED_FLAG
///
/// -
/// CMSG_SIGNED_AND_ENVELOPED_FLAG
///
/// -
/// CMSG_HASHED_FLAG
///
///
/// Note After return, the DWORD pointed to by pdwMsgType is set with the type of the message.
///
/// A pointer to a CRYPT_DECRYPT_MESSAGE_PARA structure that contains decryption parameters.
/// A pointer to a CRYPT_VERIFY_MESSAGE_PARA structure that contains verification parameters.
///
///
/// Indicates which signer, among the possible many signers of a message, is to be verified. This index can be changed in multiple
/// calls to the function to verify additional signers.
///
///
/// dwSignerIndex is set to zero for the first signer. If the function returns FALSE, and GetLastError returns
/// CRYPT_E_NO_SIGNER, the previous call returned the last signer of the message. This parameter is used only with messages of types
/// CMSG_SIGNED_AND_ENVELOPED or CMSG_SIGNED. For all other message types, it should be set to zero.
///
///
/// A pointer to the encoded BLOB that is to be decoded.
/// The size, in bytes, of the encoded BLOB.
///
/// Only applicable when processing nested cryptographic messages. When processing an outer cryptographic message, it must be set to
/// zero. When decoding a nested cryptographic message, it is set to the value returned at pdwInnerContentType by a previous calling
/// of CryptDecodeMessage for the outer message. It can be any of the CMSG types listed in pdwMsgType. For backward
/// compatibility, set dwPrevInnerContentType to zero.
///
///
///
/// A pointer to a DWORD that specifies the message type returned. This parameter can be one of the following message types:
///
///
/// -
/// CMSG_DATA
///
/// -
/// CMSG_SIGNED
///
/// -
/// CMSG_ENVELOPED
///
/// -
/// CMSG_SIGNED_AND_ENVELOPED
///
/// -
/// CMSG_HASHED
///
///
///
///
///
/// A pointer to a DWORD that specifies the type of an inner message. The message type codes used for pdwMsgType are used
/// here, also.
///
/// If there is no cryptographic nesting, CMSG_DATA is returned.
///
///
/// A pointer to a buffer to receive the decoded message.
///
/// This parameter can be NULL if the decoded message is not required or to set the size of the decoded message for memory
/// allocation purposes. A decoded message will not be returned if this parameter is NULL. For more information, see
/// Retrieving Data of Unknown Length.
///
///
///
///
/// A pointer to a variable that specifies the size, in bytes, of the buffer pointed to by the pbDecoded parameter. When the
/// function returns, this variable contains the size of the decoded message.
///
///
/// Note When processing the data returned in the buffer, applications must use the actual size of the data returned. The
/// actual size can be slightly smaller than the size of the buffer specified on input. (On input, buffer sizes are usually
/// specified large enough to ensure that the largest possible output data will fit in the buffer.) On output, the variable pointed
/// to by this parameter is updated to reflect the actual size of the data copied to the buffer.
///
///
///
/// A pointer to a pointer to a CERT_CONTEXT structure with a certificate that corresponds to the private exchange key needed to
/// decode the message. This parameter is only set for message types CMSG_ENVELOPED and CMSG_SIGNED_AND_ENVELOPED.
///
///
/// A pointer to a pointer to a CERT_CONTEXT structure of the certificate context of the signer. This parameter is only set for
/// message types CMSG_SIGNED and CMSG_SIGNED_AND_ENVELOPED.
///
///
/// If the function succeeds, the function returns nonzero ( TRUE).
/// If the function fails, it returns zero ( FALSE). For extended error information, call GetLastError.
/// The CryptDecryptMessage, CryptVerifyMessageSignature, or CryptVerifyMessageHash functions can be propagated to this function.
/// The following error code is most commonly returned by the GetLastError function.
///
///
/// Return code
/// Description
///
/// -
/// ERROR_MORE_DATA
///
/// If the buffer specified by the pbDecoded parameter is not large enough to hold the returned data, the function sets the
/// ERROR_MORE_DATA code and stores the required buffer size, in bytes, in the variable pointed to by pcbDecoded.
///
///
///
///
///
///
/// The dwMsgTypeFlags parameter specifies the set of allowable messages. For example, to decode either SIGNED or ENVELOPED
/// messages, set dwMsgTypeFlags to CMSG_SIGNED_FLAG | CMSG_ENVELOPED_FLAG. Either or both of the pDecryptPara or pVerifyPara
/// parameters must be specified.
///
///
/// For a successfully decoded or verified message, the certificate context pointers pointed to by ppXchgCert and ppSignerCert are
/// updated. They must be freed by calling CertFreeCertificateContext. If the function fails, they are set to NULL.
///
///
/// The ppXchgCert or ppSignerCert parameters can be set to NULL before the function is called, which indicates that the
/// caller is not interested in getting the exchange certificate or the signer certificate context.
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptdecodemessage BOOL CryptDecodeMessage( DWORD
// dwMsgTypeFlags, PCRYPT_DECRYPT_MESSAGE_PARA pDecryptPara, PCRYPT_VERIFY_MESSAGE_PARA pVerifyPara, DWORD dwSignerIndex, const BYTE
// *pbEncodedBlob, DWORD cbEncodedBlob, DWORD dwPrevInnerContentType, DWORD *pdwMsgType, DWORD *pdwInnerContentType, BYTE
// *pbDecoded, DWORD *pcbDecoded, PCCERT_CONTEXT *ppXchgCert, PCCERT_CONTEXT *ppSignerCert );
[DllImport(Lib.Crypt32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "25ffd058-8f75-4ba5-b075-e3efc09f5d9d")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptDecodeMessage(CryptMsgType dwMsgTypeFlags, in CRYPT_DECRYPT_MESSAGE_PARA pDecryptPara, in CRYPT_VERIFY_MESSAGE_PARA pVerifyPara,
uint dwSignerIndex, [In] IntPtr pbEncodedBlob, uint cbEncodedBlob, CryptMsgType dwPrevInnerContentType, out CryptMsgType pdwMsgType,
out CryptMsgType pdwInnerContentType, [Out] IntPtr pbDecoded, ref uint pcbDecoded, out SafePCCERT_CONTEXT ppXchgCert, out SafePCCERT_CONTEXT ppSignerCert);
/// The CryptDecryptAndVerifyMessageSignature function decrypts a message and verifies its signature.
/// A pointer to a CRYPT_DECRYPT_MESSAGE_PARA structure that contains decryption parameters.
/// A pointer to a CRYPT_VERIFY_MESSAGE_PARA structure that contains verification parameters.
///
/// Identifies a particular signer of the message. A message can be signed by more than one signer and this function can be called
/// multiple times changing this parameter to check for several signers. It is set to zero for the first signer. If the function
/// returns FALSE, and GetLastError returns CRYPT_E_NO_SIGNER, the previous call received the last signer of the message.
///
/// A pointer to the signed, encoded, and encrypted message to be decrypted and verified.
/// The size, in bytes, of the encrypted message.
///
/// A pointer to a buffer to receive the decrypted message.
///
/// This parameter can be NULL if the decrypted message is not required or to set the size of the decrypted message for
/// memory allocation purposes. A decrypted message will not be returned if this parameter is NULL. For more information, see
/// Retrieving Data of Unknown Length.
///
///
///
///
/// A pointer to a DWORD that specifies the size, in bytes, of the buffer pointed to by the pbDecrypted parameter. When the
/// function returns, it contains the size of the decrypted message copied to pbDecrypted.
///
///
/// Note When processing the data returned in the pbDecrypted buffer, applications must use the actual size of the data
/// returned. The actual size can be slightly smaller than the size of the buffer specified in pcbDecrypted on input. On output, the
/// variable pointed to by this parameter is set to reflect the actual size of the data copied to the buffer.
///
///
///
/// A pointer to a CERT_CONTEXT structure of the certificate that corresponds to the private exchange key needed to decrypt the message.
///
/// A pointer to a CERT_CONTEXT structure of the certificate of the signer.
///
/// If the function succeeds, the function returns nonzero ( TRUE).
/// If the function fails, it returns zero ( FALSE). For extended error information, call GetLastError.
///
/// Note Errors from the called functions CryptDecryptMessage and CryptVerifyMessageSignature might be propagated to this function.
///
/// The GetLastError function returns the following error code most often.
///
///
/// Return code
/// Description
///
/// -
/// ERROR_MORE_DATA
///
/// If the buffer specified by the pbDecrypted parameter is not large enough to hold the returned data, the function sets the
/// ERROR_MORE_DATA code, and stores the required buffer size, in bytes, in the variable pointed to by pcbDecrypted.
///
///
///
///
///
///
/// For a successfully decrypted and verified message, the certificate context pointers pointed to by ppXchgCert and ppSignerCert
/// are updated. They must be freed by calling CertFreeCertificateContext. If the function fails, they are set to NULL.
///
///
/// To indicate that the caller is not interested in the exchange certificate or the signer certificate context, set the ppXchgCert
/// and ppSignerCert parameters to NULL.
///
/// Examples
/// For an example that uses this function, see Example C Program: Sending and Receiving a Signed and Encrypted Message.
///
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptdecryptandverifymessagesignature BOOL
// CryptDecryptAndVerifyMessageSignature( PCRYPT_DECRYPT_MESSAGE_PARA pDecryptPara, PCRYPT_VERIFY_MESSAGE_PARA pVerifyPara, DWORD
// dwSignerIndex, const BYTE *pbEncryptedBlob, DWORD cbEncryptedBlob, BYTE *pbDecrypted, DWORD *pcbDecrypted, PCCERT_CONTEXT
// *ppXchgCert, PCCERT_CONTEXT *ppSignerCert );
[DllImport(Lib.Crypt32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "0864a187-617f-4a21-9809-d2dbbc54ab9c")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptDecryptAndVerifyMessageSignature(in CRYPT_DECRYPT_MESSAGE_PARA pDecryptPara, in CRYPT_VERIFY_MESSAGE_PARA pVerifyPara, uint dwSignerIndex,
[In] IntPtr pbEncryptedBlob, uint cbEncryptedBlob, [Out] IntPtr pbDecrypted, ref uint pcbDecrypted, out SafePCCERT_CONTEXT ppXchgCert, out SafePCCERT_CONTEXT ppSignerCert);
/// The CryptDecryptMessage function decodes and decrypts a message.
/// A pointer to a CRYPT_DECRYPT_MESSAGE_PARA structure that contains decryption parameters.
/// A pointer to a buffer that contains the encoded and encrypted message to be decrypted.
/// The size, in bytes, of the encoded and encrypted message.
///
/// A pointer to a buffer that receives the decrypted message.
///
/// To set the size of this information for memory allocation purposes, this parameter can be NULL. A decrypted message will
/// not be returned if this parameter is NULL. For more information, see Retrieving Data of Unknown Length.
///
///
///
///
/// A pointer to a DWORD that specifies the size, in bytes, of the buffer pointed to by the pbDecrypted parameter. When the
/// function returns, this variable contains the size, in bytes, of the decrypted message copied to pbDecrypted.
///
///
/// Note When processing the data returned in the pbDecrypted buffer, applications must use the actual size of the data
/// returned. The actual size can be slightly smaller than the size of the buffer specified in pcbDecrypted on input. On input,
/// buffer sizes are usually specified large enough to ensure that the largest possible output data will fit in the buffer. On
/// output, the DWORD is updated to the actual size of the data copied to the buffer.
///
///
///
/// A pointer to a CERT_CONTEXT structure of a certificate that corresponds to the private exchange key needed to decrypt the
/// message. To indicate that the function should not return the certificate context used to decrypt, set this parameter to NULL.
///
///
/// If the function succeeds, the function returns nonzero ( TRUE).
/// If the function fails, it returns zero ( FALSE). For extended error information, call GetLastError.
/// Note Errors from calls to CryptImportKey and CryptDecrypt might be propagated to this function.
/// The GetLastError function returns the following error codes most often.
///
///
/// Return code
/// Description
///
/// -
/// ERROR_MORE_DATA
///
/// If the buffer specified by the pbDecrypted parameter is not large enough to hold the returned data, the function sets the
/// ERROR_MORE_DATA code, and stores the required buffer size, in bytes, in the variable pointed to by pcbDecrypted.
///
///
/// -
/// E_INVALIDARG
///
/// Invalid message and certificate encoding types. Currently only PKCS_7_ASN_ENCODING and X509_ASN_ENCODING_TYPE are supported.
/// Invalid cbSize in *pDecryptPara.
///
///
/// -
/// CRYPT_E_UNEXPECTED_MSG_TYPE
/// Not an enveloped cryptographic message.
///
/// -
/// NTE_BAD_ALGID
/// The message was encrypted by using an unknown or unsupported algorithm.
///
/// -
/// CRYPT_E_NO_DECRYPT_CERT
/// No certificate was found having a private key property to use for decrypting.
///
///
///
/// If the function fails, GetLastError may return an Abstract Syntax Notation One (ASN.1) encoding/decoding error. For information
/// about these errors, see ASN.1 Encoding/Decoding Return Values.
///
///
///
///
/// When NULL is passed for pbDecrypted, and pcbDecrypted is not NULL, NULL is returned for the address passed
/// in ppXchgCert; otherwise, a pointer to a CERT_CONTEXT is returned. For a successfully decrypted message, this pointer to a
/// CERT_CONTEXT points to the certificate context used to decrypt the message. It must be freed by calling
/// CertFreeCertificateContext. If the function fails, the value at ppXchgCert is set to NULL.
///
/// Examples
/// For an example that uses this function, see Example C Program: Using CryptEncryptMessage and CryptDecryptMessage.
///
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptdecryptmessage BOOL CryptDecryptMessage(
// PCRYPT_DECRYPT_MESSAGE_PARA pDecryptPara, const BYTE *pbEncryptedBlob, DWORD cbEncryptedBlob, BYTE *pbDecrypted, DWORD
// *pcbDecrypted, PCCERT_CONTEXT *ppXchgCert );
[DllImport(Lib.Crypt32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "e540b816-64e1-4c78-9020-2b221e813acc")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptDecryptMessage(in CRYPT_DECRYPT_MESSAGE_PARA pDecryptPara, [In] IntPtr pbEncryptedBlob, uint cbEncryptedBlob, [Out] IntPtr pbDecrypted, ref uint pcbDecrypted, out SafePCCERT_CONTEXT ppXchgCert);
/// The CryptDecryptMessage function decodes and decrypts a message.
/// A pointer to a CRYPT_DECRYPT_MESSAGE_PARA structure that contains decryption parameters.
/// A pointer to a buffer that contains the encoded and encrypted message to be decrypted.
/// The size, in bytes, of the encoded and encrypted message.
///
/// A pointer to a buffer that receives the decrypted message.
///
/// To set the size of this information for memory allocation purposes, this parameter can be NULL. A decrypted message will
/// not be returned if this parameter is NULL. For more information, see Retrieving Data of Unknown Length.
///
///
///
///
/// A pointer to a DWORD that specifies the size, in bytes, of the buffer pointed to by the pbDecrypted parameter. When the
/// function returns, this variable contains the size, in bytes, of the decrypted message copied to pbDecrypted.
///
///
/// Note When processing the data returned in the pbDecrypted buffer, applications must use the actual size of the data
/// returned. The actual size can be slightly smaller than the size of the buffer specified in pcbDecrypted on input. On input,
/// buffer sizes are usually specified large enough to ensure that the largest possible output data will fit in the buffer. On
/// output, the DWORD is updated to the actual size of the data copied to the buffer.
///
///
///
/// A pointer to a CERT_CONTEXT structure of a certificate that corresponds to the private exchange key needed to decrypt the
/// message. To indicate that the function should not return the certificate context used to decrypt, set this parameter to NULL.
///
///
/// If the function succeeds, the function returns nonzero ( TRUE).
/// If the function fails, it returns zero ( FALSE). For extended error information, call GetLastError.
/// Note Errors from calls to CryptImportKey and CryptDecrypt might be propagated to this function.
/// The GetLastError function returns the following error codes most often.
///
///
/// Return code
/// Description
///
/// -
/// ERROR_MORE_DATA
///
/// If the buffer specified by the pbDecrypted parameter is not large enough to hold the returned data, the function sets the
/// ERROR_MORE_DATA code, and stores the required buffer size, in bytes, in the variable pointed to by pcbDecrypted.
///
///
/// -
/// E_INVALIDARG
///
/// Invalid message and certificate encoding types. Currently only PKCS_7_ASN_ENCODING and X509_ASN_ENCODING_TYPE are supported.
/// Invalid cbSize in *pDecryptPara.
///
///
/// -
/// CRYPT_E_UNEXPECTED_MSG_TYPE
/// Not an enveloped cryptographic message.
///
/// -
/// NTE_BAD_ALGID
/// The message was encrypted by using an unknown or unsupported algorithm.
///
/// -
/// CRYPT_E_NO_DECRYPT_CERT
/// No certificate was found having a private key property to use for decrypting.
///
///
///
/// If the function fails, GetLastError may return an Abstract Syntax Notation One (ASN.1) encoding/decoding error. For information
/// about these errors, see ASN.1 Encoding/Decoding Return Values.
///
///
///
///
/// When NULL is passed for pbDecrypted, and pcbDecrypted is not NULL, NULL is returned for the address passed
/// in ppXchgCert; otherwise, a pointer to a CERT_CONTEXT is returned. For a successfully decrypted message, this pointer to a
/// CERT_CONTEXT points to the certificate context used to decrypt the message. It must be freed by calling
/// CertFreeCertificateContext. If the function fails, the value at ppXchgCert is set to NULL.
///
/// Examples
/// For an example that uses this function, see Example C Program: Using CryptEncryptMessage and CryptDecryptMessage.
///
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptdecryptmessage BOOL CryptDecryptMessage(
// PCRYPT_DECRYPT_MESSAGE_PARA pDecryptPara, const BYTE *pbEncryptedBlob, DWORD cbEncryptedBlob, BYTE *pbDecrypted, DWORD
// *pcbDecrypted, PCCERT_CONTEXT *ppXchgCert );
[DllImport(Lib.Crypt32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "e540b816-64e1-4c78-9020-2b221e813acc")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptDecryptMessage(in CRYPT_DECRYPT_MESSAGE_PARA pDecryptPara, [In] IntPtr pbEncryptedBlob, uint cbEncryptedBlob, [Out] IntPtr pbDecrypted, ref uint pcbDecrypted, IntPtr ppXchgCert = default);
/// The CryptEncryptMessage function encrypts and encodes a message.
///
/// A pointer to a CRYPT_ENCRYPT_MESSAGE_PARA structure that contains the encryption parameters.
///
/// The CryptEncryptMessage function does not support the SHA2 OIDs, szOID_DH_SINGLE_PASS_STDDH_SHA256_KDF and szOID_DH_SINGLE_PASS_STDDH_SHA384_KDF.
///
///
/// Number of elements in the rgpRecipientCert array.
///
/// Array of pointers to CERT_CONTEXT structures that contain the certificates of intended recipients of the message.
///
/// A pointer to a buffer that contains the message that is to be encrypted.
/// The size, in bytes, of the message that is to be encrypted.
///
/// A pointer to BLOB that contains a buffer that receives the encrypted and encoded message.
///
/// To set the size of this information for memory allocation purposes, this parameter can be NULL. For more information, see
/// Retrieving Data of Unknown Length.
///
///
///
///
/// A pointer to a DWORD that specifies the size, in bytes, of the buffer pointed to by the pbEncryptedBlob parameter. When
/// the function returns, this variable contains the size, in bytes, of the encrypted and encoded message copied to pbEncryptedBlob.
///
///
/// Note When processing the data returned in the buffer of the pbEncryptedBlob, applications need to use the actual size of
/// the data returned. The actual size can be slightly smaller than the size of the buffer specified on input. (On input, buffer
/// sizes are usually specified large enough to ensure that the largest possible output data will fit in the buffer.) On output, the
/// variable pointed to by this parameter is updated to reflect the actual size of the data copied to the buffer.
///
///
///
/// If the function succeeds, the function returns nonzero ( TRUE).
/// If the function fails, it returns zero ( FALSE). For extended error information, call GetLastError.
///
/// Note Errors from calls to CryptGenKey, CryptEncrypt, CryptImportKey, and CryptExportKey can be propagated to this function.
///
/// The GetLastError function returns the following error codes most often.
///
///
/// Return code
/// Description
///
/// -
/// ERROR_MORE_DATA
///
/// If the buffer specified by the pbEncryptedBlob parameter is not large enough to hold the returned data, the function sets the
/// ERROR_MORE_DATA code and stores the required buffer size, in bytes, in the variable pointed to by pcbEncryptedBlob.
///
///
/// -
/// E_INVALIDARG
///
/// The message encoding type is not valid. Currently only PKCS_7_ASN_ENCODING is supported. The cbSize in *pEncryptPara is not valid.
///
///
///
///
/// If the function fails, GetLastError may return an Abstract Syntax Notation One (ASN.1) encoding/decoding error. For information
/// about these errors, see ASN.1 Encoding/Decoding Return Values.
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptencryptmessage BOOL CryptEncryptMessage(
// PCRYPT_ENCRYPT_MESSAGE_PARA pEncryptPara, DWORD cRecipientCert, PCCERT_CONTEXT [] rgpRecipientCert, const BYTE *pbToBeEncrypted,
// DWORD cbToBeEncrypted, BYTE *pbEncryptedBlob, DWORD *pcbEncryptedBlob );
[DllImport(Lib.Crypt32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "927f2e9a-96cf-4744-bd57-420b5034d28d")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptEncryptMessage(in CRYPT_ENCRYPT_MESSAGE_PARA pEncryptPara, uint cRecipientCert, [In, MarshalAs(UnmanagedType.LPArray)] PCCERT_CONTEXT[] rgpRecipientCert,
[In] IntPtr pbToBeEncrypted, uint cbToBeEncrypted, [Out] IntPtr pbEncryptedBlob, ref uint pcbEncryptedBlob);
///
/// The CryptGetMessageCertificates function returns the handle of an open certificate store containing the message's
/// certificates and CRLs. This function calls CertOpenStore using provider type CERT_STORE_PROV_PKCS7 as its lpszStoreProvider parameter.
///
///
///
/// Specifies the encoding type used. 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:
///
/// X509_ASN_ENCODING | PKCS_7_ASN_ENCODING
/// Currently defined encoding types are:
///
/// -
/// X509_ASN_ENCODING
///
/// -
/// PKCS_7_ASN_ENCODING
///
///
///
///
/// This parameter is not used and should be set to NULL.
///
/// Windows Server 2003 and Windows XP: Handle of the CSP passed to CertOpenStore. For more information, see
/// CertOpenStore.Unless there is a strong reason for passing a specific cryptographic provider in hCryptProv, pass zero to cause
/// the default RSA or DSS provider to be acquired.
///
/// This parameter's data type is HCRYPTPROV.
///
/// Flags passed to CertOpenStore. For more information, see CertOpenStore.
/// A pointer to a buffered CRYPT_INTEGER_BLOB structure that contains the signed message.
/// The size, in bytes, of the signed message.
///
/// Returns the certificate store containing the message's certificates and CRLs. For an error, NULL is returned.
/// The following lists the error code most commonly returned by the GetLastError function.
///
///
/// Return code
/// Description
///
/// -
/// E_INVALIDARG
/// Invalid message and certificate encoding types. Currently only PKCS_7_ASN_ENCODING and X509_ASN_ENCODING are supported.
///
///
///
/// If the function fails, GetLastError may return an Abstract Syntax Notation One (ASN.1) encoding/decoding error. For information
/// about these errors, see ASN.1 Encoding/Decoding Return Values.
///
///
///
/// Use GetLastError to determine the reason for any errors.
/// Examples
/// For an example that uses this function, see Example C Program: Setting and Getting Certificate Store Properties.
///
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptgetmessagecertificates HCERTSTORE
// CryptGetMessageCertificates( DWORD dwMsgAndCertEncodingType, HCRYPTPROV_LEGACY hCryptProv, DWORD dwFlags, const BYTE
// *pbSignedBlob, DWORD cbSignedBlob );
[DllImport(Lib.Crypt32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "d890f91f-bb45-463b-b7c0-56acc9367571")]
public static extern SafeHCERTSTORE CryptGetMessageCertificates(CertEncodingType dwMsgAndCertEncodingType, [Optional] HCRYPTPROV hCryptProv, CertStoreFlags dwFlags, [In] IntPtr pbSignedBlob, uint cbSignedBlob);
/// The CryptGetMessageSignerCount function returns the number of signers of a signed message.
///
///
/// Specifies the encoding type used. 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:
///
/// X509_ASN_ENCODING | PKCS_7_ASN_ENCODING
/// Currently defined encoding types are:
///
/// -
/// X509_ASN_ENCODING
///
/// -
/// PKCS_7_ASN_ENCODING
///
///
///
/// A pointer to a buffer containing the signed message.
/// The size, in bytes, of the signed message.
///
/// Returns the number of signers of a signed message, zero when there are no signers, and minus one (–1) for an error.
/// For extended error information, call GetLastError. The following error code is most commonly returned.
///
///
/// Return code
/// Description
///
/// -
/// E_INVALIDARG
/// Invalid message encoding type. Currently only PKCS_7_ASN_ENCODING is supported.
///
///
///
/// If the function fails, GetLastError may return an Abstract Syntax Notation One (ASN.1) encoding/decoding error. For information
/// about these errors, see ASN.1 Encoding/Decoding Return Values.
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptgetmessagesignercount LONG
// CryptGetMessageSignerCount( DWORD dwMsgEncodingType, const BYTE *pbSignedBlob, DWORD cbSignedBlob );
[DllImport(Lib.Crypt32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "d18bda8b-b333-4b1e-8ed5-f8eff04b3168")]
public static extern int CryptGetMessageSignerCount(CertEncodingType dwMsgEncodingType, [In] IntPtr pbSignedBlob, uint cbSignedBlob);
/// The CryptHashMessage function creates a hash of the message.
/// A pointer to a CRYPT_HASH_MESSAGE_PARA structure that contains the hash parameters.
///
/// If this parameter is set to TRUE, only pbComputedHash is encoded in pbHashedBlob. Otherwise, both rgpbToBeHashed and
/// pbComputedHash are encoded.
///
///
/// The number of array elements in rgpbToBeHashed and rgcbToBeHashed. This parameter can only be one unless fDetachedHash is set to TRUE.
///
/// An array of pointers to buffers that contain the contents to be hashed.
/// An array of sizes, in bytes, of the buffers pointed to by rgpbToBeHashed.
///
/// A pointer to a buffer to receive the hashed message encoded for transmission.
///
/// This parameter can be NULL if the hashed message is not needed for additional processing or to set the size of the hashed
/// message for memory allocation purposes. A hashed message will not be returned if this parameter is NULL. For more
/// information, see Retrieving Data of Unknown Length.
///
///
///
///
/// A pointer to a DWORD that specifies the size, in bytes, of the buffer pointed to by the pbHashedBlob parameter. When the
/// function returns, this variable contains the size, in bytes, of the decrypted message copied to pbHashedBlob. This parameter
/// must be the address of a DWORD and not NULL or the length of the buffer will not be returned.
///
///
/// Note When processing the data returned, applications must use the actual size of the data returned. The actual size can
/// be slightly smaller than the size of the buffer specified on input. On input, buffer sizes are usually specified large enough to
/// ensure that the largest possible output data will fit in the buffer. On output, the variable pointed to by this parameter is
/// updated to reflect the actual size of the data copied to the buffer.
///
///
///
/// A pointer to a buffer to receive the newly created hash value. This parameter can be NULL if the newly created hash is
/// not needed for additional processing, or to set the size of the hash for memory allocation purposes. For more information, see
/// Retrieving Data of Unknown Length.
///
///
///
/// A pointer to a DWORD that specifies the size, in bytes, of the buffer pointed to by the pbComputedHash parameter. When
/// the function returns, this DWORD contains the size, in bytes, of the newly created hash that was copied to pbComputedHash.
///
///
/// Note When processing the data returned, applications must use the actual size of the data returned. The actual size can
/// be slightly smaller than the size of the buffer specified on input. On input, buffer sizes are usually specified large enough to
/// ensure that the largest possible output data will fit in the buffer. On output, the variable pointed to by this parameter is
/// updated to reflect the actual size of the data copied to the buffer.
///
///
///
/// If the function succeeds, the function returns nonzero ( TRUE).
/// If the function fails, it returns zero ( FALSE). For extended error information, call GetLastError.
///
/// Note Errors from the called functions CryptCreateHash, CryptHashData, and CryptGetHashParam might be propagated to this function.
///
/// The GetLastError function returns the following error codes most often.
///
///
/// Return code
/// Description
///
/// -
/// E_INVALIDARG
///
/// The message encoding type is not valid. Currently only PKCS_7_ASN_ENCODING is supported. The cbSize in *pHashPara is not valid.
///
///
/// -
/// ERROR_MORE_DATA
///
/// If the buffer specified by the pbHashedBlob parameter is not large enough to hold the returned data, the function sets the
/// ERROR_MORE_DATA code and stores the required buffer size, in bytes, into the variable pointed to by pbHashedBlob.
///
///
///
///
/// If the function fails, GetLastError may return an Abstract Syntax Notation One (ASN.1) encoding/decoding error. For information
/// about these errors, see ASN.1 Encoding/Decoding Return Values.
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-crypthashmessage BOOL CryptHashMessage(
// PCRYPT_HASH_MESSAGE_PARA pHashPara, BOOL fDetachedHash, DWORD cToBeHashed, const BYTE * [] rgpbToBeHashed, DWORD []
// rgcbToBeHashed, BYTE *pbHashedBlob, DWORD *pcbHashedBlob, BYTE *pbComputedHash, DWORD *pcbComputedHash );
[DllImport(Lib.Crypt32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "85a04c01-fd7c-4d87-b6e1-a0f2aea45d16")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptHashMessage(in CRYPT_HASH_MESSAGE_PARA pHashPara, [MarshalAs(UnmanagedType.Bool)] bool fDetachedHash, uint cToBeHashed,
[In] IntPtr[] rgpbToBeHashed, [In] uint[] rgcbToBeHashed, [Out] IntPtr pbHashedBlob, ref uint pcbHashedBlob, [Out] IntPtr pbComputedHash, ref uint pcbComputedHash);
///
/// The CryptMsgCalculateEncodedLength function calculates the maximum number of bytes needed for an encoded cryptographic
/// message given the message type, encoding parameters, and total length of the data to be encoded. Note that the result will
/// always be greater than or equal to the actual number of bytes needed.
///
///
///
/// Specifies the encoding type used. 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:
///
/// X509_ASN_ENCODING | PKCS_7_ASN_ENCODING
/// Currently defined encoding types are:
///
/// -
/// X509_ASN_ENCODING
///
/// -
/// PKCS_7_ASN_ENCODING
///
///
///
///
/// Currently defined flags are shown in the following table.
///
///
/// Value
/// Meaning
///
/// -
/// CMSG_BARE_CONTENT_FLAG
///
/// Indicates that 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.
///
///
/// -
/// CMSG_DETACHED_FLAG
/// Indicates that there is detached data being supplied for the subsequent calls to CryptMsgUpdate.
///
/// -
/// CMSG_CONTENTS_OCTETS_FLAG
///
/// Used to calculate the size of a DER encoding of a message to be nested inside an enveloped message. This is particularly useful
/// when streaming is being performed.
///
///
/// -
/// CMSG_CMS_ENCAPSULATED_CONTENT_FLAG
///
/// Non-Data type inner content is encapsulated within an OCTET STRING. This flag is applicable for both Signed and Enveloped messages.
///
///
///
///
///
/// Currently defined message types are shown in the following table.
///
///
/// Value
/// Meaning
///
/// -
/// CMSG_DATA
/// An octet (BYTE) string.
///
/// -
/// CMSG_SIGNED
/// CMSG_SIGNED_ENCODE_INFO
///
/// -
/// CMSG_ENVELOPED
/// CMSG_ENVELOPED_ENCODE_INFO
///
/// -
/// CMSG_SIGNED_AND_ENVELOPED
/// Not implemented.
///
/// -
/// CMSG_HASHED
/// CMSG_HASHED_ENCODE_INFO
///
/// -
/// CMSG_ENCRYPTED
/// Not implemented.
///
///
///
///
/// A pointer to the data to be encoded. The type of data pointed to depends on the value of dwMsgType. For details, see the
/// dwMsgType table.
///
///
///
/// When calling CryptMsgCalculateEncodedLength with data provided to CryptMsgUpdate already encoded, the appropriate object
/// identifier is passed in pszInnerContentObjID. If pszInnerContentObjID is NULL, 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.
///
/// When streaming is being used, pszInnerContentObjID must be either NULL or szOID_RSA_data.
/// The following algorithm object identifiers are commonly used:
///
/// -
/// szOID_RSA_data
///
/// -
/// szOID_RSA_signedData
///
/// -
/// szOID_RSA_envelopedData
///
/// -
/// szOID_RSA_signEnvData
///
/// -
/// szOID_RSA_digestedData
///
/// -
/// szOID_RSA_encryptedData
///
/// -
/// SPC_INDIRECT_DATA_OBJID
///
///
///
/// A user can define new inner content usage. The user must ensure that the sender and receiver of the message agree upon the
/// semantics associated with the object identifier.
///
///
/// The size, in bytes, of the content.
///
///
/// Returns the required length for an encoded cryptographic message. This length might not be the exact length but it will not be
/// less than the required length. Zero is returned if the function fails.
///
///
/// To retrieve extended error information, use the GetLastError function. The following table lists the error codes most commonly returned.
///
///
///
/// Return code
/// Description
///
/// -
/// CRYPT_E_INVALID_MSG_TYPE
/// The message type is not valid.
///
/// -
/// CRYPT_E_UNKNOWN_ALGO
/// The cryptographic algorithm is unknown.
///
/// -
/// E_INVALIDARG
/// One or more arguments are not valid.
///
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptmsgcalculateencodedlength DWORD
// CryptMsgCalculateEncodedLength( DWORD dwMsgEncodingType, DWORD dwFlags, DWORD dwMsgType, void const *pvMsgEncodeInfo, LPSTR
// pszInnerContentObjID, DWORD cbData );
[DllImport(Lib.Crypt32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "1c12003a-c2f3-4069-8bd6-b8f2875b0c98")]
public static extern uint CryptMsgCalculateEncodedLength(CertEncodingType dwMsgEncodingType, CryptMsgFlags dwFlags, CryptMsgType dwMsgType, [In] IntPtr pvMsgEncodeInfo,
[Optional] SafeOID pszInnerContentObjID, uint cbData);
///
/// The CryptMsgClose function closes a cryptographic message handle. At each call to this function, the reference count on
/// the message is reduced by one. When the reference count reaches zero, the message is fully released.
///
/// Handle of the cryptographic message to be closed.
///
/// If the function succeeds, the function returns nonzero ( TRUE).
/// If the function fails, it returns zero ( FALSE). For extended error information, call GetLastError.
///
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptmsgclose BOOL CryptMsgClose( HCRYPTMSG hCryptMsg );
[DllImport(Lib.Crypt32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "2478dd60-233a-4ef3-86e9-62d2a59ab28a")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptMsgClose(HCRYPTMSG hCryptMsg);
///
///
/// The CryptMsgControl function performs a control operation after a message has been decoded by a final call to the
/// CryptMsgUpdate function. The control operations provided by this function are used for decryption, signature and hash
/// verification, and the addition and deletion of certificates, certificate revocation lists (CRLs), signers, and unauthenticated attributes.
///
///
/// Important changes that affect the handling of enveloped messages have been made to CryptoAPI to support Secure/Multipurpose
/// Internet Mail Extensions (S/MIME) email interoperability. For more information, see the Remarks for the CryptMsgOpenToEncode function.
///
///
/// A handle of a cryptographic message for which a control is to be applied.
///
/// The following value is defined when the dwCtrlType parameter is one of the following:
///
/// -
/// CMSG_CTRL_DECRYPT
///
/// -
/// CMSG_CTRL_KEY_TRANS_DECRYPT
///
/// -
/// CMSG_CTRL_KEY_AGREE_DECRYPT
///
/// -
/// CMSG_CTRL_MAIL_LIST_DECRYPT
///
///
///
///
/// Value
/// Meaning
///
/// -
/// CMSG_CRYPT_RELEASE_CONTEXT_FLAG
///
/// The handle to the cryptographic provider is released on the final call to the CryptMsgClose function. This handle is not
/// released if the CryptMsgControl function fails.
///
///
///
/// If the dwCtrlType parameter does not specify a decrypt operation, set this value to zero.
///
///
///
/// The type of operation to be performed. Currently defined message control types and the type of structure that should be passed
/// to the pvCtrlPara parameter are shown in the following table.
///
///
///
/// Value
/// Meaning
///
/// -
/// CMSG_CTRL_ADD_ATTR_CERT 14 (0xE)
/// A BLOB that contains the encoded bytes of attribute certificate.
///
/// -
/// CMSG_CTRL_ADD_CERT 10 (0xA)
/// A CRYPT_INTEGER_BLOB structure that contains the encoded bytes of the certificate to be added to the message.
///
/// -
/// CMSG_CTRL_ADD_CMS_SIGNER_INFO 20 (0x14)
///
/// A CMSG_CMS_SIGNER_INFO structure that contains signer information. This operation differs from CMSG_CTRL_ADD_SIGNER because the
/// signer information contains the signature.
///
///
/// -
/// CMSG_CTRL_ADD_CRL 12 (0xC)
/// A BLOB that contains the encoded bytes of the CRL to be added to the message.
///
/// -
/// CMSG_CTRL_ADD_SIGNER 6 (0x6)
/// A CMSG_SIGNER_ENCODE_INFO structure that contains the signer information to be added to the message.
///
/// -
/// CMSG_CTRL_ADD_SIGNER_UNAUTH_ATTR 8 (0x8)
///
/// A CMSG_CTRL_ADD_SIGNER_UNAUTH_ATTR_PARA structure that contains the index of the signer and a BLOB that contains the
/// unauthenticated attribute information to be added to the message.
///
///
/// -
/// CMSG_CTRL_DECRYPT 2 (0x2)
///
/// A CMSG_CTRL_DECRYPT_PARA structure used to decrypt the message for the specified key transport recipient. This value is
/// applicable to RSA recipients. This operation specifies that the CryptMsgControl function search the recipient index to obtain
/// the key transport recipient information. If the function fails, GetLastError will return CRYPT_E_INVALID_INDEX if no key
/// transport recipient is found.
///
///
/// -
/// CMSG_CTRL_DEL_ATTR_CERT 15 (0xF)
/// The index of the attribute certificate to be removed.
///
/// -
/// CMSG_CTRL_DEL_CERT 11 (0xB)
/// The index of the certificate to be deleted from the message.
///
/// -
/// CMSG_CTRL_DEL_CRL 13 (0xD)
/// The index of the CRL to be deleted from the message.
///
/// -
/// CMSG_CTRL_DEL_SIGNER 7 (0x7)
/// The index of the signer to be deleted.
///
/// -
/// CMSG_CTRL_DEL_SIGNER_UNAUTH_ATTR 9 (0x9)
///
/// A CMSG_CTRL_DEL_SIGNER_UNAUTH_ATTR_PARA structure that contains an index that specifies the signer and the index that specifies
/// the signer's unauthenticated attribute to be deleted.
///
///
/// -
/// CMSG_CTRL_ENABLE_STRONG_SIGNATURE 21 (0x15)
///
/// A CERT_STRONG_SIGN_PARA structure used to perform strong signature checking. To check for a strong signature, specify this
/// control type before calling CryptMsgGetAndVerifySigner or before calling CryptMsgControl with the following control types set:
/// After the signature is successfully verified, this function checks for a strong signature. If the signature is not strong, the
/// operation will fail and the GetLastError value will be set to NTE_BAD_ALGID.
///
///
/// -
/// CMSG_CTRL_KEY_AGREE_DECRYPT 17 (0x11)
///
/// A CMSG_CTRL_KEY_AGREE_DECRYPT_PARA structure used to decrypt the message for the specified key agreement session key. Key
/// agreement is used with Diffie-Hellman encryption/decryption.
///
///
/// -
/// CMSG_CTRL_KEY_TRANS_DECRYPT 16 (0x10)
///
/// A CMSG_CTRL_KEY_TRANS_DECRYPT_PARA structure used to decrypt the message for the specified key transport recipient. Key
/// transport is used with RSA encryption/decryption.
///
///
/// -
/// CMSG_CTRL_MAIL_LIST_DECRYPT 18 (0x12)
///
/// A CMSG_CTRL_MAIL_LIST_DECRYPT_PARA structure used to decrypt the message for the specified recipient using a previously
/// distributed key-encryption key (KEK).
///
///
/// -
/// CMSG_CTRL_VERIFY_HASH 5 (0x5)
/// This value is not used.
///
/// -
/// CMSG_CTRL_VERIFY_SIGNATURE 1 (0x1)
/// A CERT_INFO structure that identifies the signer of the message whose signature is to be verified.
///
/// -
/// CMSG_CTRL_VERIFY_SIGNATURE_EX 19 (0x13)
///
/// A CMSG_CTRL_VERIFY_SIGNATURE_EX_PARA structure that specifies the signer index and public key to verify the message signature.
/// The signer public key can be a CERT_PUBLIC_KEY_INFO structure, a certificate context, or a certificate chain context.
///
///
///
///
///
/// A pointer to a structure determined by the value of dwCtrlType.
///
///
/// dwCtrlType value
/// Meaning
///
/// -
///
/// CMSG_CTRL_DECRYPT, CMSG_CTRL_KEY_TRANS_DECRYPT, CMSG_CTRL_KEY_AGREE_DECRYPT, or CMSG_CTRL_MAIL_LIST_DECRYPT, and the streamed
/// enveloped message is being decoded
///
///
/// Decoding will be done as if the streamed content were being decrypted. If any encrypted streamed content has accumulated prior
/// to this call, some or all of the plaintext that results from the decryption of the cipher text is passed back to the application
/// through the callback function specified in the call to the CryptMsgOpenToDecode function.
///
///
/// -
/// CMSG_CTRL_VERIFY_HASH
/// The hash computed from the content of the message is compared against the hash contained in the message.
///
/// -
/// CMSG_CTRL_ADD_SIGNER
/// pvCtrlPara points to a CMSG_SIGNER_ENCODE_INFO structure that contains the signer information to be added to the message.
///
/// -
/// CMSG_CTRL_DEL_SIGNER
///
/// After a deletion is made, any other signer indices in use for this message are no longer valid and must be reacquired by calling
/// the CryptMsgGetParam function.
///
///
/// -
/// CMSG_CTRL_DEL_SIGNER_UNAUTH_ATTR
///
/// After a deletion is made, any other unauthenticated attribute indices in use for this signer are no longer valid and must be
/// reacquired by calling the CryptMsgGetParam function.
///
///
/// -
/// CMSG_CTRL_DEL_CERT
///
/// After a deletion is made, any other certificate indices in use for this message are no longer valid and must be reacquired by
/// calling the CryptMsgGetParam function.
///
///
/// -
/// CMSG_CTRL_DEL_CRL
///
/// After a deletion is made, any other CRL indices in use for this message are no longer valid and will need to be reacquired by
/// calling the CryptMsgGetParam function.
///
///
///
///
///
/// If the function succeeds, the return value is nonzero.
///
/// If the function fails, the return value is zero and the GetLastError function returns an Abstract Syntax Notation One (ASN.1)
/// encoding/decoding error. For information about these errors, see ASN.1 Encoding/Decoding Return Values.
///
///
/// When a streamed, enveloped message is being decoded, errors encountered in the application-defined callback function specified
/// by the pStreamInfo parameter of the CryptMsgOpenToDecode function might be propagated to the CryptMsgControl function. If
/// this happens, the SetLastError function is not called by the CryptMsgControl function after the callback function
/// returns. This 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 the SetLastError function if an error occurs while the application is
/// processing the streamed data.
///
/// Propagated errors might be encountered from the following functions:
///
/// -
/// CryptCreateHash
///
/// -
/// CryptDecrypt
///
/// -
/// CryptGetHashParam
///
/// -
/// CryptGetUserKey
///
/// -
/// CryptHashData
///
/// -
/// CryptImportKey
///
/// -
/// CryptSignHash
///
/// -
/// CryptVerifySignature
///
///
/// The following error codes are most commonly returned.
///
///
/// Return code
/// Description
///
/// -
/// CRYPT_E_ALREADY_DECRYPTED
/// The message content has already been decrypted. This error can be returned if the dwCtrlType parameter is set to CMSG_CTRL_DECRYPT.
///
/// -
/// CRYPT_E_AUTH_ATTR_MISSING
///
/// The message does not contain an expected authenticated attribute. This error can be returned if the dwCtrlType parameter is set
/// to CMSG_CTRL_VERIFY_SIGNATURE.
///
///
/// -
/// CRYPT_E_BAD_ENCODE
///
/// An error was encountered while encoding or decoding. This error can be returned if the dwCtrlType parameter is set to CMSG_CTRL_VERIFY_SIGNATURE.
///
///
/// -
/// CRYPT_E_CONTROL_TYPE
/// The control type is not valid.
///
/// -
/// CRYPT_E_HASH_VALUE
/// The hash value is incorrect.
///
/// -
/// CRYPT_E_INVALID_INDEX
/// The index value is not valid.
///
/// -
/// CRYPT_E_INVALID_MSG_TYPE
/// The message type is not valid.
///
/// -
/// CRYPT_E_OID_FORMAT
/// The object identifier is badly formatted. This error can be returned if the dwCtrlType parameter is set to CMSG_CTRL_ADD_SIGNER.
///
/// -
/// CRYPT_E_RECIPIENT_NOT_FOUND
///
/// The enveloped data message does not contain the specified recipient. This error can be returned if the dwCtrlType parameter is
/// set to CMSG_CTRL_DECRYPT.
///
///
/// -
/// CRYPT_E_SIGNER_NOT_FOUND
/// The specified signer for the message was not found. This error can be returned if the dwCtrlType parameter is set to CMSG_CTRL_VERIFY_SIGNATURE.
///
/// -
/// CRYPT_E_UNKNOWN_ALGO
/// The cryptographic algorithm is unknown.
///
/// -
/// CRYPT_E_UNEXPECTED_ENCODING
/// The message is not encoded as expected. This error can be returned if the dwCtrlType parameter is set to CMSG_CTRL_VERIFY_SIGNATURE.
///
/// -
/// E_INVALIDARG
/// One or more arguments are not valid. This error can be returned if the dwCtrlType parameter is set to CMSG_CTRL_DECRYPT.
///
/// -
/// E_OUTOFMEMORY
/// Not enough memory was available to complete the operation.
///
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptmsgcontrol BOOL CryptMsgControl( HCRYPTMSG
// hCryptMsg, DWORD dwFlags, DWORD dwCtrlType, void const *pvCtrlPara );
[DllImport(Lib.Crypt32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "a990d44d-2993-429f-b817-2a834105ecef")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptMsgControl(HCRYPTMSG hCryptMsg, CryptMsgFlags dwFlags, CryptMsgControlType dwCtrlType, [In, Optional] IntPtr pvCtrlPara);
///
/// The CryptMsgCountersign function countersigns an existing signature in a message. Countersignatures are used to sign an
/// existing signature's encrypted hash of the message. Countersignatures can be used for various purposes including time stamping a message.
///
/// Cryptographic message handle to be used.
/// Zero-based index of the signer in the signed or signed-and-enveloped message to be countersigned.
/// Number of countersigners in the rgCountersigners array.
/// Array of countersigners' CMSG_SIGNER_ENCODE_INFO structures.
///
/// If the function succeeds, the function returns nonzero ( TRUE).
/// If the function fails, it returns zero ( FALSE). For extended error information, call GetLastError.
/// An error can be propagated from CryptMsgCountersignEncoded.
/// The following error codes are returned most often.
///
///
/// Return code
/// Description
///
/// -
/// E_INVALIDARG
/// One or more arguments are not valid.
///
/// -
/// E_OUTOFMEMORY
/// Ran out of memory.
///
/// -
/// ERROR_MORE_DATA
/// The specified area is not large enough to hold the returned data.
///
///
///
/// If the function fails, GetLastError may return an Abstract Syntax Notation One (ASN.1) encoding/decoding error. For information
/// about these errors, see ASN.1 Encoding/Decoding Return Values.
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptmsgcountersign BOOL CryptMsgCountersign( HCRYPTMSG
// hCryptMsg, DWORD dwIndex, DWORD cCountersigners, PCMSG_SIGNER_ENCODE_INFO rgCountersigners );
[DllImport(Lib.Crypt32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "ebf76664-bca6-462d-b519-2b60f435d8ef")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptMsgCountersign(HCRYPTMSG hCryptMsg, uint dwIndex, uint cCountersigners, [In, MarshalAs(UnmanagedType.LPArray)] CMSG_SIGNER_ENCODE_INFO[] rgCountersigners);
///
/// The CryptMsgCountersignEncoded function countersigns an existing PKCS #7 message signature. The pbCountersignature
/// BYTE buffer it creates is a PKCS #7 encoded SignerInfo that can be used as an unauthenticated Countersignature attribute
/// of a PKCS #9 signed-data or signed-and-enveloped-data message.
///
///
///
/// Specifies the encoding type used. Currently, only X509_ASN_ENCODING and PKCS_7_ASN_ENCODING are being used; however, additional
/// encoding types may be added in the future. For either current encoding type, use:
///
/// X509_ASN_ENCODING | PKCS_7_ASN_ENCODING.
///
/// A pointer to the encoded SignerInfo that is to be countersigned.
/// Count, in bytes, of the encoded SignerInfo data.
/// Number of countersigners in the rgCountersigners array.
/// Array of countersigners' CMSG_SIGNER_ENCODE_INFO structures.
///
/// A pointer to a buffer to receive an encoded PKCS #9 countersignature attribute.
///
/// On input, this parameter can be NULL to set the size of this information for memory allocation purposes. For more
/// information, see Retrieving Data of Unknown Length.
///
///
///
/// A pointer to a variable that specifies the size, in bytes, of the buffer pointed to by the pbCountersignature parameter. When
/// the function returns, the variable pointed to by the pcbCountersignature parameter contains the number of bytes stored in the buffer.
///
///
/// If the function succeeds, the return value is nonzero ( TRUE).
/// If the function fails, the return value is zero ( FALSE). For extended error information, call GetLastError.
/// The following table lists the error codes most commonly returned by the GetLastError function.
///
///
/// Return code
/// Description
///
/// -
/// CRYPT_E_OID_FORMAT
/// The object identifier is badly formatted.
///
/// -
/// E_INVALIDARG
/// One or more arguments are not valid.
///
/// -
/// E_OUTOFMEMORY
/// Ran out of memory.
///
///
/// Propagated errors might be returned from one of the following functions:
///
/// -
/// CryptCreateHash
///
/// -
/// CryptHashData
///
/// -
/// CryptGetHashParam
///
/// -
/// CryptSignHash
///
/// -
/// CryptMsgOpenToEncode
///
/// -
/// CryptMsgUpdate
///
/// -
/// CryptMsgControl
///
///
///
/// If the function fails, GetLastError may return an Abstract Syntax Notation One (ASN.1) encoding/decoding error. For information
/// about these errors, see ASN.1 Encoding/Decoding Return Values.
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptmsgcountersignencoded BOOL
// CryptMsgCountersignEncoded( DWORD dwEncodingType, PBYTE pbSignerInfo, DWORD cbSignerInfo, DWORD cCountersigners,
// PCMSG_SIGNER_ENCODE_INFO rgCountersigners, PBYTE pbCountersignature, PDWORD pcbCountersignature );
[DllImport(Lib.Crypt32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "d9fd734b-e14d-4392-ac88-5565aefbedb4")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptMsgCountersignEncoded(CertEncodingType dwEncodingType, [In] IntPtr pbSignerInfo, uint cbSignerInfo, uint cCountersigners,
[In, MarshalAs(UnmanagedType.LPArray)] CMSG_SIGNER_ENCODE_INFO[] rgCountersigners, [Out] IntPtr pbCountersignature, ref uint pcbCountersignature);
/// The CryptMsgDuplicate function duplicates a cryptographic message handle by incrementing its reference count.
///
/// Handle of the cryptographic message to be duplicated. Duplication is done by incrementing the reference count of the message. A
/// copy of the message is not made.
///
///
/// The returned handle is the same as the handle input. A copy of the message is not created. When you have finished using the
/// duplicated message handle, decrease the reference count by calling the CryptMsgClose function.
///
///
///
/// CryptMsgDuplicate is used to increase the reference count on an HCRYPTMSG handle so that multiple calls to
/// CryptMsgClose are required to actually release the handle.
///
/// Examples
/// For an example that uses this function, see Example C Program: Encoding and Decoding a Hashed Message.
///
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptmsgduplicate HCRYPTMSG CryptMsgDuplicate( HCRYPTMSG
// hCryptMsg );
[DllImport(Lib.Crypt32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "9b1142b9-0caa-4304-bfe6-1c27c6a7b782")]
public static extern HCRYPTMSG CryptMsgDuplicate(HCRYPTMSG hCryptMsg);
///
/// The CryptMsgGetParam function acquires a message parameter after a cryptographic message has been encoded or decoded.
/// This function is called after the final CryptMsgUpdate call.
///
/// Handle of a cryptographic message.
///
///
/// Indicates the parameter types of data to be retrieved. The type of data to be retrieved determines the type of structure to use
/// for pvData.
///
///
/// For an encoded message, only the CMSG_BARE_CONTENT, CMSG_ENCODE_SIGNER, CMSG_CONTENT_PARAM and CMSG_COMPUTED_HASH_PARAM
/// dwParamTypes are valid.
///
///
///
/// Value
/// Meaning
///
/// -
/// CMSG_ATTR_CERT_COUNT_PARAM
/// pvData data type: pointer to a DWORD Returns the count of the attribute certificates in a SIGNED or ENVELOPED message.
///
/// -
/// CMSG_ATTR_CERT_PARAM
///
/// pvData data type: pointer to a BYTE array Retrieves an attribute certificate. To get all the attribute certificates, call
/// CryptMsgGetParam varying dwIndex set to 0 the number of attributes minus one.
///
///
/// -
/// CMSG_BARE_CONTENT_PARAM
///
/// pvData data type: pointer to a BYTE array Retrieves the encoded content of an encoded cryptographic message, without the outer
/// layer of the CONTENT_INFO structure. That is, only the encoding of the PKCS #7 defined ContentInfo.content field is returned.
///
///
/// -
/// CMSG_CERT_COUNT_PARAM
/// pvData data type: pointer to DWORD Returns the number of certificates in a received SIGNED or ENVELOPED message.
///
/// -
/// CMSG_CERT_PARAM
///
/// pvData data type: pointer to a BYTE array Returns a signer's certificate. To get all of the signer's certificates, call
/// CryptMsgGetParam, varying dwIndex from 0 to the number of available certificates minus one.
///
///
/// -
/// CMSG_COMPUTED_HASH_PARAM
///
/// pvData data type: pointer to a BYTE array Returns the hash calculated of the data in the message. This type is applicable to
/// both encode and decode.
///
///
/// -
/// CMSG_CONTENT_PARAM
///
/// pvData data type: pointer to a BYTE array Returns the whole PKCS #7 message from a message opened to encode. Retrieves the inner
/// content of a message opened to decode. If the message is enveloped, the inner type is data, and CryptMsgControl has been called
/// to decrypt the message, the decrypted content is returned. If the inner type is not data, the encoded BLOB that requires further
/// decoding is returned. If the message is not enveloped and the inner content is DATA, the returned data is the octets of the
/// inner content. This type is applicable to both encode and decode. For decoding, if the type is CMSG_DATA, the content's octets
/// are returned; else, the encoded inner content is returned.
///
///
/// -
/// CMSG_CRL_COUNT_PARAM
/// pvData data type: pointer to DWORD Returns the count of CRLs in a received, SIGNED or ENVELOPED message.
///
/// -
/// CMSG_CRL_PARAM
///
/// pvData data type: pointer to a BYTE array Returns a CRL. To get all the CRLs, call CryptMsgGetParam, varying dwIndex from 0 to
/// the number of available CRLs minus one.
///
///
/// -
/// CMSG_ENCODED_MESSAGE
///
/// pvData data type: pointer to a BYTE array Changes the contents of an already encoded message. The message must first be decoded
/// with a call to CryptMsgOpenToDecode. Then the change to the message is made through a call to CryptMsgControl,
/// CryptMsgCountersign, or CryptMsgCountersignEncoded. The message is then encoded again with a call to CryptMsgGetParam,
/// specifying CMSG_ENCODED_MESSAGE to get a new encoding that reflects the changes made. This can be used, for instance, to add a
/// time-stamp attribute to a message.
///
///
/// -
/// CMSG_ENCODED_SIGNER
/// pvData data type: pointer to a BYTE array Returns the encoded CMSG_SIGNER_INFO signer information for a message signer.
///
/// -
/// CMSG_ENCRYPTED_DIGEST
/// pvData data type: pointer to a BYTE array Returns the encrypted hash of a signature. Typically used for performing time-stamping.
///
/// -
/// CMSG_ENCRYPT_PARAM
///
/// pvData data type: pointer to a BYTE array for a CRYPT_ALGORITHM_IDENTIFIER structure. Returns the encryption algorithm used to
/// encrypted the message.
///
///
/// -
/// CMSG_ENVELOPE_ALGORITHM_PARAM
///
/// pvData data type: pointer to a BYTE array for a CRYPT_ALGORITHM_IDENTIFIER structure. Returns the encryption algorithm used to
/// encrypt an ENVELOPED message.
///
///
/// -
/// CMSG_HASH_ALGORITHM_PARAM
///
/// pvData data type: pointer to a BYTE array for a CRYPT_ALGORITHM_IDENTIFIER structure. Returns the hash algorithm used to hash
/// the message when it was created.
///
///
/// -
/// CMSG_HASH_DATA_PARAM
/// pvData data type: pointer to a BYTE array Returns the hash value stored in the message when it was created.
///
/// -
/// CMSG_INNER_CONTENT_TYPE_PARAM
///
/// pvData data type: pointer to a BYTE array to receive a null-terminated object identifier (OID) string. Returns the inner content
/// type of a received message. This type is not applicable to messages of type DATA.
///
///
/// -
/// CMSG_RECIPIENT_COUNT_PARAM
/// pvData data type: pointer to a DWORD Returns the number of key transport recipients of an ENVELOPED received message.
///
/// -
/// CMSG_CMS_RECIPIENT_COUNT_PARAM
///
/// pvData data type: pointer to DWORD Returns the total count of all message recipients including key agreement and mail list recipients.
///
///
/// -
/// CMSG_RECIPIENT_INDEX_PARAM
///
/// pvData data type: pointer to a DWORD Returns the index of the key transport recipient used to decrypt an ENVELOPED message. This
/// value is available only after a message has been decrypted.
///
///
/// -
/// CMSG_CMS_RECIPIENT_INDEX_PARAM
///
/// pvData data type: pointer to a DWORD Returns the index of the key transport, key agreement, or mail list recipient used to
/// decrypt an ENVELOPED message.
///
///
/// -
/// CMSG_CMS_RECIPIENT_ENCRYPTED_KEY_INDEX_PARAM
///
/// pvData data type: pointer to a DWORD Returns the index of the encrypted key of a key agreement recipient used to decrypt an
/// ENVELOPED message.
///
///
/// -
/// CMSG_RECIPIENT_INFO_PARAM
///
/// pvData data type: pointer to a BYTE array to receive a CERT_INFO structure. Returns certificate information about a key
/// transport message's recipient. To get certificate information on all key transport message's recipients, repetitively call
/// CryptMsgGetParam, varying dwIndex from 0 to the number of recipients minus one. Only the Issuer, SerialNumber, and
/// PublicKeyAlgorithm members of the CERT_INFO structure returned are available and valid.
///
///
/// -
/// CMSG_CMS_RECIPIENT_INFO_PARAM
///
/// pvData data type: pointer to a BYTE array to receive a CMSG_CMS_RECIPIENT_INFO structure. Returns information about a key
/// transport, key agreement, or mail list recipient. It is not limited to key transport message recipients. To get information on
/// all of a message's recipients, repetitively call CryptMsgGetParam, varying dwIndex from 0 to the number of recipients minus one.
///
///
/// -
/// CMSG_SIGNER_AUTH_ATTR_PARAM
///
/// pvData data type: pointer to a BYTE array to receive a CRYPT_ATTRIBUTES structure. Returns the authenticated attributes of a
/// message signer. To retrieve the authenticated attributes for a specified signer, call CryptMsgGetParam with dwIndex equal to
/// that signer's index.
///
///
/// -
/// CMSG_SIGNER_CERT_INFO_PARAM
///
/// pvData data type: pointer to a BYTE array to receive the CERT_INFO structure. Returns information on a message signer needed to
/// identify the signer's certificate. A certificate's Issuer and SerialNumber can be used to uniquely identify a certificate for
/// retrieval. To retrieve information for all the signers, repetitively call CryptMsgGetParam varying dwIndex from 0 to the number
/// of signers minus one. Only the Issuer and SerialNumber fields in the CERT_INFO structure returned contain available, valid data.
///
///
/// -
/// CMSG_SIGNER_CERT_ID_PARAM
///
/// pvData data type: pointer to a BYTE array to receive a CERT_ID structure. Returns information on a message signer needed to
/// identify the signer's public key. This could be a certificate's Issuer and SerialNumber, a KeyID, or a HashId. To retrieve
/// information for all the signers, call CryptMsgGetParam varying dwIndex from 0 to the number of signers minus one.
///
///
/// -
/// CMSG_SIGNER_COUNT_PARAM
/// pvData data type: pointer to a DWORD Returns the number of signers of a received SIGNED message.
///
/// -
/// CMSG_SIGNER_HASH_ALGORITHM_PARAM
///
/// pvData data type: pointer to a BYTE array to receive the CRYPT_ALGORITHM_IDENTIFIER structure. Returns the hash algorithm used
/// by a signer of the message. To get the hash algorithm for a specified signer, call CryptMsgGetParam with dwIndex equal to that
/// signer's index.
///
///
/// -
/// CMSG_SIGNER_INFO_PARAM
///
/// pvData data type: pointer to a BYTE array to receive a CMSG_SIGNER_INFO structure. Returns information on a message signer. This
/// includes the issuer and serial number of the signer's certificate and authenticated and unauthenticated attributes of the
/// signer's certificate. To retrieve signer information on all of the signers of a message, call CryptMsgGetParam varying dwIndex
/// from 0 to the number of signers minus one.
///
///
/// -
/// CMSG_CMS_SIGNER_INFO_PARAM
///
/// pvData data type: pointer to a BYTE array to receive a CMSG_CMS_SIGNER_INFO structure. Returns information on a message signer.
/// This includes a signerId and authenticated and unauthenticated attributes. To retrieve signer information on all of the signers
/// of a message, call CryptMsgGetParam varying dwIndex from 0 to the number of signers minus one.
///
///
/// -
/// CMSG_SIGNER_UNAUTH_ATTR_PARAM
///
/// pvData data type: pointer to a BYTE array to receive a CRYPT_ATTRIBUTES structure. Returns a message signer's unauthenticated
/// attributes. To retrieve the unauthenticated attributes for a specified signer, call CryptMsgGetParam with dwIndex equal to that
/// signer's index.
///
///
/// -
/// CMSG_TYPE_PARAM
///
/// pvData data type: pointer to a DWORD Returns the message type of a decoded message of unknown type. The retrieved message type
/// can be compared to supported types to determine whether processing can continued. For supported message types, see the
/// dwMessageType parameter of CryptMsgOpenToDecode.
///
///
/// -
/// CMSG_UNPROTECTED_ATTR_PARAM
///
/// pvData data type: pointer to a BYTE array to receive a CMSG_ATTR structure. Returns the unprotected attributes in an enveloped message.
///
///
/// -
/// CMSG_VERSION_PARAM
///
/// pvData data type: pointer to a DWORD Returns the version of the decoded message. For more information, see the table in the
/// Remarks section.
///
///
///
///
///
/// Index for the parameter being retrieved, where applicable. When a parameter is not being retrieved, this parameter is ignored
/// and is set to zero.
///
///
///
/// A pointer to a buffer that receives the data retrieved. The form of this data will vary depending on the value of the
/// dwParamType parameter.
///
///
/// This parameter can be NULL to set the size of this information for memory allocation purposes. For more information, see
/// Retrieving Data of Unknown Length.
///
///
/// When processing the data returned in this buffer, applications need to use the actual size of the data returned. The actual size
/// can be slightly smaller than the size of the buffer specified on input. (On input, buffer sizes are usually specified large
/// enough to ensure that the largest possible output data will fit in the buffer.) On output, the variable pointed to by this
/// parameter is updated to reflect the actual size of the data copied to the buffer.
///
///
///
/// A pointer to a variable that specifies the size, in bytes, of the buffer pointed to by the pvData parameter. When the function
/// returns, the variable pointed to by the pcbData parameter contains the number of bytes stored in the buffer.
///
///
/// If the function succeeds, the return value is nonzero (TRUE).
/// If the function fails, the return value is zero (FALSE). For extended error information, call GetLastError.
/// The following table lists the error codes most commonly returned by the GetLastError function.
///
///
/// Return code
/// Description
///
/// -
/// CRYPT_E_ATTRIBUTES_MISSING
/// The message does not contain the requested attributes.
///
/// -
/// CRYPT_E_INVALID_INDEX
/// The index value is not valid.
///
/// -
/// CRYPT_E_INVALID_MSG_TYPE
/// The message type is not valid.
///
/// -
/// CRYPT_E_NOT_DECRYPTED
/// The message content has not been decrypted yet.
///
/// -
/// CRYPT_E_OID_FORMAT
/// The object identifier is badly formatted.
///
/// -
/// CRYPT_E_UNEXPECTED_ENCODING
/// The message is not encoded as expected.
///
/// -
/// E_INVALIDARG
/// One or more arguments are not valid.
///
/// -
/// ERROR_MORE_DATA
/// The specified buffer is not large enough to hold the returned data.
///
///
/// For dwParamType CMSG_COMPUTED_HASH_PARAM, an error can be propagated from CryptGetHashParam.
///
/// If the function fails, GetLastError may return an Abstract Syntax Notation One (ASN.1) encoding/decoding error. For information
/// about these errors, see ASN.1 Encoding/Decoding Return Values.
///
///
///
///
/// The following version numbers are returned by calls to CryptMsgGetParam with dwParamType set to CMSG_VERSION_PARAM are defined:
///
///
/// -
/// CMSG_SIGNED_DATA_V1
///
/// -
/// CMSG_SIGNED_DATA_V3
///
/// -
/// CMSG_SIGNED_DATA_PKCS_1_5_VERSION
///
/// -
/// CMSG_SIGNED_DATA_CMS_VERSION
///
/// -
/// CMSG_SIGNER_INFO_V1
///
/// -
/// CMSG_SIGNER_INFO_V3
///
/// -
/// CMSG_SIGNER_INFO_PKCS_1_5_VERSION
///
/// -
/// CMSG_SIGNER_INFO_CMS_VERSION
///
/// -
/// CMSG_HASHED_DATA_V0
///
/// -
/// CMSG_HASHED_DATA_V2
///
/// -
/// CMSG_HASHED_DATA_PKCS_1_5_VERSION
///
/// -
/// CMSG_HASHED_DATA_CMS_VERSION
///
/// -
/// CMSG_ENVELOPED_DATA_V0
///
/// -
/// CMSG_ENVELOPED_DATA_V2
///
/// -
/// CMSG_ENVELOPED_DATA_PKCS_1_5_VERSION
///
/// -
/// CMSG_ENVELOPED_DATA_CMS_VERSION
///
///
/// Examples
///
/// For an example that uses this function, see Example C Program: Signing, Encoding, Decoding, and Verifying a Message, Alternate
/// Code for Encoding an Enveloped Message, Example C Program: Encoding an Enveloped, Signed Message, and Example C Program:
/// Encoding and Decoding a Hashed Message.
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptmsggetparam BOOL CryptMsgGetParam( HCRYPTMSG
// hCryptMsg, DWORD dwParamType, DWORD dwIndex, void *pvData, DWORD *pcbData );
[DllImport(Lib.Crypt32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "5a05eb09-208f-4e94-abfa-c2f14c0a3164")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptMsgGetParam(HCRYPTMSG hCryptMsg, CryptMsgParamType dwParamType, uint dwIndex, [Out] IntPtr pvData, ref uint pcbData);
///
///
/// The CryptMsgOpenToDecode function opens a cryptographic message for decoding and returns a handle of the opened message.
/// The message remains open until the CryptMsgClose function is called.
///
///
/// Important changes that affect the handling of enveloped messages have been made to CryptoAPI to support Secure/Multipurpose
/// Internet Mail Extensions (S/MIME) email interoperability. For details, see the Remarks section of CryptMsgOpenToEncode.
///
///
///
///
/// Specifies the encoding type used. 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:
///
/// X509_ASN_ENCODING | PKCS_7_ASN_ENCODING
/// Currently defined encoding types are:
///
/// -
/// X509_ASN_ENCODING
///
/// -
/// PKCS_7_ASN_ENCODING
///
///
///
///
/// This parameter can be one of the following flags.
///
///
/// Value
/// Meaning
///
/// -
/// CMSG_DETACHED_FLAG
/// Indicates that the message to be decoded is detached. If this flag is not set, the message is not detached.
///
/// -
/// CMSG_CRYPT_RELEASE_CONTEXT_FLAG
///
/// If set, the hCryptProv passed to this function is released on the final CryptMsgUpdate. The handle is not released if the
/// function fails.
///
///
///
///
///
///
/// Specifies the type of message to decode. In most cases, the message type is determined from the message header and zero is
/// passed for this parameter. In some cases, notably with Internet Explorer 3.0, messages do not have headers and the type of
/// message to be decoded must be supplied in this function call. If the header is missing and zero is passed for this parameter,
/// the function fails.
///
/// This parameter can be one of the following predefined message types.
///
///
/// Value
/// Meaning
///
/// -
/// CMSG_DATA
/// The message is encoded data.
///
/// -
/// CMSG_ENVELOPED
/// The message is an enveloped message.
///
/// -
/// CMSG_HASHED
/// The message is a hashed message.
///
/// -
/// CMSG_SIGNED
/// The message is a signed message.
///
/// -
/// CMSG_SIGNED_AND_ENVELOPED
/// The message is a signed and enveloped message.
///
///
///
///
/// This parameter is not used and should be set to NULL.
///
/// Windows Server 2003 and Windows XP: Specifies a handle for the cryptographic provider to use for hashing the message. For
/// signed messages, hCryptProv is used for signature verification.This parameter's data type is HCRYPTPROV.
///
///
/// Unless there is a strong reason for passing in a specific cryptographic provider in hCryptProv, set this parameter to
/// NULL. Passing in NULL causes the default RSA or DSS provider to be acquired before performing hash, signature
/// verification, or recipient encryption operations.
///
///
/// This parameter is reserved for future use and must be NULL.
///
/// When streaming is not being used, this parameter must be set to NULL.
///
/// Note Streaming is not used with CMSG_HASHED messages. When dealing with hashed data, this parameter must be set to NULL.
///
///
/// When streaming is being used, the pStreamInfo parameter is a pointer to a CMSG_STREAM_INFO structure that contains a pointer to
/// a callback to be called when CryptMsgUpdate is executed or when CryptMsgControl is executed when decoding a streamed enveloped message.
///
/// For a signed message, the callback is passed a block of the decoded bytes from the inner content of the message.
///
/// For an enveloped message, after each call to CryptMsgUpdate, you must check to determine whether the
/// CMSG_ENVELOPE_ALGORITHM_PARAM property is available by calling the CryptMsgGetParam function. CryptMsgGetParam will fail
/// and GetLastError will return CRYPT_E_STREAM_MSG_NOT_READY until CryptMsgUpdate has processed enough of the message to
/// make the CMSG_ENVELOPE_ALGORITHM_PARAM property available. When the CMSG_ENVELOPE_ALGORITHM_PARAM property is available, you can
/// iterate through the recipients, retrieving a CERT_INFO structure for each recipient by using the CryptMsgGetParam
/// function to retrieve the CMSG_RECIPIENT_INFO_PARAM property. To prevent a denial of service attack from an enveloped message
/// that has an artificially large header block, you must keep track of the amount of memory that has been passed to the
/// CryptMsgUpdate function during this process. If the amount of data exceeds an application defined limit before the
/// CMSG_ENVELOPE_ALGORITHM_PARAM property is available, you must stop processing the message and call the CryptMsgClose function to
/// cause the operating system to release any memory that has been allocated for the message. A suggested limit is the maximum
/// allowable size of a message. For example, if the maximum message size is 10 MB, the limit for this test should be 10 MB.
///
///
/// The CERT_INFO structure is used to find a matching certificate in a previously opened certificate store by using the
/// CertGetSubjectCertificateFromStore function. When the correct certificate is found, the CertGetCertificateContextProperty
/// function with a CERT_KEY_PROV_INFO_PROP_ID parameter is called to retrieve a CRYPT_KEY_PROV_INFO structure. The structure
/// contains the information necessary to acquire the recipient's private key by calling CryptAcquireContext, using the
/// pwszContainerName, pwszProvName, dwProvType, and dwFlags members of the CRYPT_KEY_PROV_INFO
/// structure. The hCryptProv acquired and the dwKeySpec member of the CRYPT_KEY_PROV_INFO structure are passed
/// to the CryptMsgControl structure as a member of the CMSG_CTRL_DECRYPT_PARA structure to permit the start of the decryption of
/// the inner content. The streaming code will then perform the decryption as the data is input. The resulting blocks of plaintext
/// are passed to the callback function specified by the pfnStreamOutput member of the CMSG_STREAM_INFO structure to handle
/// the output of the decrypted message.
///
///
/// Note Streamed decoding of an enveloped message queues the ciphertext in memory until CryptMsgControl is called to start
/// the decryption. The application must initiate decrypting in a timely manner so that the data can be saved to disk or routed
/// elsewhere before the accumulated ciphertext becomes too large and the system runs out of memory.
///
///
/// In the case of a signed message enclosed in an enveloped message, the plaintext output from the streaming decode of the
/// enveloped message can be fed into another streaming decode to process the signed message.
///
///
///
/// If the function succeeds, the function returns the handle of the opened message.
/// If the function fails, it returns NULL. For extended error information, call GetLastError.
/// The following table lists the error codes most commonly returned by the GetLastError function.
///
///
/// Value
/// Description
///
/// -
/// E_INVALIDARG
/// One or more arguments are not valid.
///
/// -
/// E_OUTOFMEMORY
/// A memory allocation failure occurred.
///
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptmsgopentodecode HCRYPTMSG CryptMsgOpenToDecode(
// DWORD dwMsgEncodingType, DWORD dwFlags, DWORD dwMsgType, HCRYPTPROV_LEGACY hCryptProv, PCERT_INFO pRecipientInfo,
// PCMSG_STREAM_INFO pStreamInfo );
[DllImport(Lib.Crypt32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "b3df6312-c866-4faa-8b89-bda67c697631")]
public static extern SafeHCRYPTMSG CryptMsgOpenToDecode(CertEncodingType dwMsgEncodingType, CryptMsgFlags dwFlags, CryptMsgType dwMsgType, [Optional] HCRYPTPROV hCryptProv, [Optional] IntPtr pRecipientInfo, in CMSG_STREAM_INFO pStreamInfo);
///
///
/// The CryptMsgOpenToDecode function opens a cryptographic message for decoding and returns a handle of the opened message.
/// The message remains open until the CryptMsgClose function is called.
///
///
/// Important changes that affect the handling of enveloped messages have been made to CryptoAPI to support Secure/Multipurpose
/// Internet Mail Extensions (S/MIME) email interoperability. For details, see the Remarks section of CryptMsgOpenToEncode.
///
///
///
///
/// Specifies the encoding type used. 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:
///
/// X509_ASN_ENCODING | PKCS_7_ASN_ENCODING
/// Currently defined encoding types are:
///
/// -
/// X509_ASN_ENCODING
///
/// -
/// PKCS_7_ASN_ENCODING
///
///
///
///
/// This parameter can be one of the following flags.
///
///
/// Value
/// Meaning
///
/// -
/// CMSG_DETACHED_FLAG
/// Indicates that the message to be decoded is detached. If this flag is not set, the message is not detached.
///
/// -
/// CMSG_CRYPT_RELEASE_CONTEXT_FLAG
///
/// If set, the hCryptProv passed to this function is released on the final CryptMsgUpdate. The handle is not released if the
/// function fails.
///
///
///
///
///
///
/// Specifies the type of message to decode. In most cases, the message type is determined from the message header and zero is
/// passed for this parameter. In some cases, notably with Internet Explorer 3.0, messages do not have headers and the type of
/// message to be decoded must be supplied in this function call. If the header is missing and zero is passed for this parameter,
/// the function fails.
///
/// This parameter can be one of the following predefined message types.
///
///
/// Value
/// Meaning
///
/// -
/// CMSG_DATA
/// The message is encoded data.
///
/// -
/// CMSG_ENVELOPED
/// The message is an enveloped message.
///
/// -
/// CMSG_HASHED
/// The message is a hashed message.
///
/// -
/// CMSG_SIGNED
/// The message is a signed message.
///
/// -
/// CMSG_SIGNED_AND_ENVELOPED
/// The message is a signed and enveloped message.
///
///
///
///
/// This parameter is not used and should be set to NULL.
///
/// Windows Server 2003 and Windows XP: Specifies a handle for the cryptographic provider to use for hashing the message. For
/// signed messages, hCryptProv is used for signature verification.This parameter's data type is HCRYPTPROV.
///
///
/// Unless there is a strong reason for passing in a specific cryptographic provider in hCryptProv, set this parameter to
/// NULL. Passing in NULL causes the default RSA or DSS provider to be acquired before performing hash, signature
/// verification, or recipient encryption operations.
///
///
/// This parameter is reserved for future use and must be NULL.
///
/// When streaming is not being used, this parameter must be set to NULL.
///
/// Note Streaming is not used with CMSG_HASHED messages. When dealing with hashed data, this parameter must be set to NULL.
///
///
/// When streaming is being used, the pStreamInfo parameter is a pointer to a CMSG_STREAM_INFO structure that contains a pointer to
/// a callback to be called when CryptMsgUpdate is executed or when CryptMsgControl is executed when decoding a streamed enveloped message.
///
/// For a signed message, the callback is passed a block of the decoded bytes from the inner content of the message.
///
/// For an enveloped message, after each call to CryptMsgUpdate, you must check to determine whether the
/// CMSG_ENVELOPE_ALGORITHM_PARAM property is available by calling the CryptMsgGetParam function. CryptMsgGetParam will fail
/// and GetLastError will return CRYPT_E_STREAM_MSG_NOT_READY until CryptMsgUpdate has processed enough of the message to
/// make the CMSG_ENVELOPE_ALGORITHM_PARAM property available. When the CMSG_ENVELOPE_ALGORITHM_PARAM property is available, you can
/// iterate through the recipients, retrieving a CERT_INFO structure for each recipient by using the CryptMsgGetParam
/// function to retrieve the CMSG_RECIPIENT_INFO_PARAM property. To prevent a denial of service attack from an enveloped message
/// that has an artificially large header block, you must keep track of the amount of memory that has been passed to the
/// CryptMsgUpdate function during this process. If the amount of data exceeds an application defined limit before the
/// CMSG_ENVELOPE_ALGORITHM_PARAM property is available, you must stop processing the message and call the CryptMsgClose function to
/// cause the operating system to release any memory that has been allocated for the message. A suggested limit is the maximum
/// allowable size of a message. For example, if the maximum message size is 10 MB, the limit for this test should be 10 MB.
///
///
/// The CERT_INFO structure is used to find a matching certificate in a previously opened certificate store by using the
/// CertGetSubjectCertificateFromStore function. When the correct certificate is found, the CertGetCertificateContextProperty
/// function with a CERT_KEY_PROV_INFO_PROP_ID parameter is called to retrieve a CRYPT_KEY_PROV_INFO structure. The structure
/// contains the information necessary to acquire the recipient's private key by calling CryptAcquireContext, using the
/// pwszContainerName, pwszProvName, dwProvType, and dwFlags members of the CRYPT_KEY_PROV_INFO
/// structure. The hCryptProv acquired and the dwKeySpec member of the CRYPT_KEY_PROV_INFO structure are passed
/// to the CryptMsgControl structure as a member of the CMSG_CTRL_DECRYPT_PARA structure to permit the start of the decryption of
/// the inner content. The streaming code will then perform the decryption as the data is input. The resulting blocks of plaintext
/// are passed to the callback function specified by the pfnStreamOutput member of the CMSG_STREAM_INFO structure to handle
/// the output of the decrypted message.
///
///
/// Note Streamed decoding of an enveloped message queues the ciphertext in memory until CryptMsgControl is called to start
/// the decryption. The application must initiate decrypting in a timely manner so that the data can be saved to disk or routed
/// elsewhere before the accumulated ciphertext becomes too large and the system runs out of memory.
///
///
/// In the case of a signed message enclosed in an enveloped message, the plaintext output from the streaming decode of the
/// enveloped message can be fed into another streaming decode to process the signed message.
///
///
///
/// If the function succeeds, the function returns the handle of the opened message.
/// If the function fails, it returns NULL. For extended error information, call GetLastError.
/// The following table lists the error codes most commonly returned by the GetLastError function.
///
///
/// Value
/// Description
///
/// -
/// E_INVALIDARG
/// One or more arguments are not valid.
///
/// -
/// E_OUTOFMEMORY
/// A memory allocation failure occurred.
///
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptmsgopentodecode HCRYPTMSG CryptMsgOpenToDecode(
// DWORD dwMsgEncodingType, DWORD dwFlags, DWORD dwMsgType, HCRYPTPROV_LEGACY hCryptProv, PCERT_INFO pRecipientInfo,
// PCMSG_STREAM_INFO pStreamInfo );
[DllImport(Lib.Crypt32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "b3df6312-c866-4faa-8b89-bda67c697631")]
public static extern SafeHCRYPTMSG CryptMsgOpenToDecode(CertEncodingType dwMsgEncodingType, CryptMsgFlags dwFlags, CryptMsgType dwMsgType, HCRYPTPROV hCryptProv = default, IntPtr pRecipientInfo = default, IntPtr pStreamInfo = default);
///
/// The CryptMsgOpenToEncode function opens a cryptographic message for encoding and returns a handle of the opened message.
/// The message remains open until CryptMsgClose is called.
///
///
///
/// Specifies the encoding type used. 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:
///
/// X509_ASN_ENCODING | PKCS_7_ASN_ENCODING
/// Currently defined encoding types are:
///
/// -
/// X509_ASN_ENCODING
///
/// -
/// PKCS_7_ASN_ENCODING
///
///
///
///
/// Currently defined dwFlags are shown in the following table.
///
///
/// Value
/// Meaning
///
/// -
/// CMSG_BARE_CONTENT_FLAG
///
/// 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.
///
///
/// -
/// CMSG_DETACHED_FLAG
/// There is detached data being supplied for the subsequent calls to CryptMsgUpdate.
///
/// -
/// CMSG_AUTHENTICATED_ATTRIBUTES_FLAG
///
/// Authenticated attributes are forced to be included in the SignerInfo (as defined by PKCS #7) in cases where they would not
/// otherwise be required.
///
///
/// -
/// CMSG_CONTENTS_OCTETS_FLAG
///
/// Used when calculating the size of a message that has been encoded by using Distinguished Encoding Rules (DER) and that is nested
/// inside an enveloped message. This is particularly useful when performing streaming.
///
///
/// -
/// CMSG_CMS_ENCAPSULATED_CONTENT_FLAG
///
/// When set, non-data type-inner content is encapsulated within an OCTET STRING. Applicable to both signed and enveloped messages.
///
///
/// -
/// CMSG_CRYPT_RELEASE_CONTEXT_FLAG
///
/// If set, the hCryptProv that is passed to this function is released on the final CryptMsgUpdate. The handle is not released if
/// the function fails.
///
///
///
///
///
/// Indicates the message type. This must be one of the following values.
///
///
/// Value
/// Meaning
///
/// -
/// CMSG_DATA
/// This value is not used.
///
/// -
/// CMSG_SIGNED
/// The pvMsgEncodeInfo parameter is the address of a CMSG_SIGNED_ENCODE_INFO structure that contains the encoding information.
///
/// -
/// CMSG_ENVELOPED
/// The pvMsgEncodeInfo parameter is the address of a CMSG_ENVELOPED_ENCODE_INFO structure that contains the encoding information.
///
/// -
/// CMSG_SIGNED_AND_ENVELOPED
/// This value is not currently implemented.
///
/// -
/// CMSG_HASHED
/// The pvMsgEncodeInfo parameter is the address of a CMSG_HASHED_ENCODE_INFO structure that contains the encoding information.
///
///
///
///
/// The address of a structure that contains the encoding information. The type of data depends on the value of the dwMsgType
/// parameter. For details, see dwMsgType.
///
///
///
/// If CryptMsgCalculateEncodedLength is called and the data for CryptMsgUpdate has already been message encoded, the appropriate
/// object identifier (OID) is passed in pszInnerContentObjID. If pszInnerContentObjID is NULL, then the inner content type
/// is assumed not to have been previously encoded and is therefore 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 OIDs are commonly used. A user can define new inner content usage by ensuring that the sender and
/// receiver of the message agree upon the semantics associated with the OID.
///
///
/// -
/// szOID_RSA_data
///
/// -
/// szOID_RSA_signedData
///
/// -
/// szOID_RSA_envelopedData
///
/// -
/// szOID_RSA_signEnvData
///
/// -
/// szOID_RSA_digestedData
///
/// -
/// szOID_RSA_encryptedData
///
/// -
/// SPC_INDIRECT_DATA_OBJID
///
///
///
///
///
/// When streaming is being used, this parameter is the address of a CMSG_STREAM_INFO structure. The callback function specified by
/// the pfnStreamOutput member of the CMSG_STREAM_INFO structure is called when CryptMsgUpdate is executed. The
/// callback is passed the encoded bytes that result from the encoding. For more information about how to use the callback, see CMSG_STREAM_INFO.
///
///
/// Note When streaming is being used, the application must not release any data handles that are passed in the
/// pvMsgEncodeInfo parameter, such as the provider handle in the hCryptProv member of the CMSG_SIGNER_ENCODE_INFO structure,
/// until after the message handle returned by this function is closed by using the CryptMsgClose function.
///
/// When streaming is not being used, this parameter is set to
/// NULL
/// .
///
/// Streaming is not used with the CMSG_HASHED message type. When dealing with hashed data, this parameter must be set to NULL.
///
///
/// Consider the case of a signed message being enclosed in an enveloped message. The encoded output from the streamed encoding of
/// the signed message feeds into another streaming encoding of the enveloped message. The callback for the streaming encoding calls
/// CryptMsgUpdate to encode the enveloped message. The callback for the enveloped message receives the encoded bytes of the nested
/// signed message.
///
///
///
///
/// If the function succeeds, it returns a handle to the opened message. This handle must be closed when it is no longer needed by
/// passing it to the CryptMsgClose function.
///
/// If this function fails, NULL is returned.
/// To retrieve extended error information, use the GetLastError function.
/// The following table lists the error codes most commonly returned by the GetLastError function.
///
///
/// Return code
/// Description
///
/// -
/// CRYPT_E_INVALID_MSG_TYPE
/// The message type is not valid.
///
/// -
/// CRYPT_E_OID_FORMAT
/// The OID is badly formatted.
///
/// -
/// CRYPT_E_UNKNOWN_ALGO
/// The cryptographic algorithm is unknown.
///
/// -
/// E_INVALIDARG
/// One or more arguments are not valid.
///
/// -
/// E_OUTOFMEMORY
/// There is not enough memory.
///
///
/// In addition, if dwMsgType is CMSG_SIGNED, errors can be propagated from CryptCreateHash.
/// If dwMsgType is CMSG_ENVELOPED, errors can be propagated from CryptGenKey, CryptImportKey, and CryptExportKey.
/// If dwMsgType is CMSG_HASHED, errors can be propagated from CryptCreateHash.
///
///
///
/// For functions that perform encryption, the encrypted symmetric keys are reversed from little-endian format to big-endian format
/// after CryptExportKey is called internally. For functions that perform decryption, the encrypted symmetric keys are reversed from
/// big-endian format to little-endian format before CryptImportKey is called.
///
/// CRYPT_NO_SALT is specified when symmetric keys are generated and imported with CryptGenKey and CryptImportKey.
///
/// Messages encrypted with the RC2 encryption algorithm use KP_EFFECTIVE_KEYLEN with CryptGetKeyParam to determine the effective
/// key length of the RC2 key importing or 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 member of the CMSG_ENVELOPED_ENCODE_INFO structure.
///
///
/// For messages encrypted with the RC4, DES, and 3DES encryption algorithms, encode and decode operations now handle the ASN IV
/// octet string parameter for the ContentEncryptionAlgorithm member of the CMSG_ENVELOPED_ENCODE_INFO structure.
///
/// Examples
///
/// For examples that use this function, see Example C Program: Signing, Encoding, Decoding, and Verifying a Message, Alternate Code
/// for Encoding an Enveloped Message, Example C Program: Encoding an Enveloped, Signed Message, and Example C Program: Encoding and
/// Decoding a Hashed Message.
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptmsgopentoencode HCRYPTMSG CryptMsgOpenToEncode(
// DWORD dwMsgEncodingType, DWORD dwFlags, DWORD dwMsgType, void const *pvMsgEncodeInfo, LPSTR pszInnerContentObjID,
// PCMSG_STREAM_INFO pStreamInfo );
[DllImport(Lib.Crypt32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "b0d2610b-05ba-4fb6-8f38-10f970a52091")]
public static extern SafeHCRYPTMSG CryptMsgOpenToEncode(CertEncodingType dwMsgEncodingType, CryptMsgFlags dwFlags, CryptMsgType dwMsgType, [In] IntPtr pvMsgEncodeInfo,
[Optional] SafeOID pszInnerContentObjID, in CMSG_STREAM_INFO pStreamInfo);
///
/// The CryptMsgOpenToEncode function opens a cryptographic message for encoding and returns a handle of the opened message.
/// The message remains open until CryptMsgClose is called.
///
///
///
/// Specifies the encoding type used. 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:
///
/// X509_ASN_ENCODING | PKCS_7_ASN_ENCODING
/// Currently defined encoding types are:
///
/// -
/// X509_ASN_ENCODING
///
/// -
/// PKCS_7_ASN_ENCODING
///
///
///
///
/// Currently defined dwFlags are shown in the following table.
///
///
/// Value
/// Meaning
///
/// -
/// CMSG_BARE_CONTENT_FLAG
///
/// 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.
///
///
/// -
/// CMSG_DETACHED_FLAG
/// There is detached data being supplied for the subsequent calls to CryptMsgUpdate.
///
/// -
/// CMSG_AUTHENTICATED_ATTRIBUTES_FLAG
///
/// Authenticated attributes are forced to be included in the SignerInfo (as defined by PKCS #7) in cases where they would not
/// otherwise be required.
///
///
/// -
/// CMSG_CONTENTS_OCTETS_FLAG
///
/// Used when calculating the size of a message that has been encoded by using Distinguished Encoding Rules (DER) and that is nested
/// inside an enveloped message. This is particularly useful when performing streaming.
///
///
/// -
/// CMSG_CMS_ENCAPSULATED_CONTENT_FLAG
///
/// When set, non-data type-inner content is encapsulated within an OCTET STRING. Applicable to both signed and enveloped messages.
///
///
/// -
/// CMSG_CRYPT_RELEASE_CONTEXT_FLAG
///
/// If set, the hCryptProv that is passed to this function is released on the final CryptMsgUpdate. The handle is not released if
/// the function fails.
///
///
///
///
///
/// Indicates the message type. This must be one of the following values.
///
///
/// Value
/// Meaning
///
/// -
/// CMSG_DATA
/// This value is not used.
///
/// -
/// CMSG_SIGNED
/// The pvMsgEncodeInfo parameter is the address of a CMSG_SIGNED_ENCODE_INFO structure that contains the encoding information.
///
/// -
/// CMSG_ENVELOPED
/// The pvMsgEncodeInfo parameter is the address of a CMSG_ENVELOPED_ENCODE_INFO structure that contains the encoding information.
///
/// -
/// CMSG_SIGNED_AND_ENVELOPED
/// This value is not currently implemented.
///
/// -
/// CMSG_HASHED
/// The pvMsgEncodeInfo parameter is the address of a CMSG_HASHED_ENCODE_INFO structure that contains the encoding information.
///
///
///
///
/// The address of a structure that contains the encoding information. The type of data depends on the value of the dwMsgType
/// parameter. For details, see dwMsgType.
///
///
///
/// If CryptMsgCalculateEncodedLength is called and the data for CryptMsgUpdate has already been message encoded, the appropriate
/// object identifier (OID) is passed in pszInnerContentObjID. If pszInnerContentObjID is NULL, then the inner content type
/// is assumed not to have been previously encoded and is therefore 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 OIDs are commonly used. A user can define new inner content usage by ensuring that the sender and
/// receiver of the message agree upon the semantics associated with the OID.
///
///
/// -
/// szOID_RSA_data
///
/// -
/// szOID_RSA_signedData
///
/// -
/// szOID_RSA_envelopedData
///
/// -
/// szOID_RSA_signEnvData
///
/// -
/// szOID_RSA_digestedData
///
/// -
/// szOID_RSA_encryptedData
///
/// -
/// SPC_INDIRECT_DATA_OBJID
///
///
///
///
///
/// When streaming is being used, this parameter is the address of a CMSG_STREAM_INFO structure. The callback function specified by
/// the pfnStreamOutput member of the CMSG_STREAM_INFO structure is called when CryptMsgUpdate is executed. The
/// callback is passed the encoded bytes that result from the encoding. For more information about how to use the callback, see CMSG_STREAM_INFO.
///
///
/// Note When streaming is being used, the application must not release any data handles that are passed in the
/// pvMsgEncodeInfo parameter, such as the provider handle in the hCryptProv member of the CMSG_SIGNER_ENCODE_INFO structure,
/// until after the message handle returned by this function is closed by using the CryptMsgClose function.
///
/// When streaming is not being used, this parameter is set to
/// NULL
/// .
///
/// Streaming is not used with the CMSG_HASHED message type. When dealing with hashed data, this parameter must be set to NULL.
///
///
/// Consider the case of a signed message being enclosed in an enveloped message. The encoded output from the streamed encoding of
/// the signed message feeds into another streaming encoding of the enveloped message. The callback for the streaming encoding calls
/// CryptMsgUpdate to encode the enveloped message. The callback for the enveloped message receives the encoded bytes of the nested
/// signed message.
///
///
///
///
/// If the function succeeds, it returns a handle to the opened message. This handle must be closed when it is no longer needed by
/// passing it to the CryptMsgClose function.
///
/// If this function fails, NULL is returned.
/// To retrieve extended error information, use the GetLastError function.
/// The following table lists the error codes most commonly returned by the GetLastError function.
///
///
/// Return code
/// Description
///
/// -
/// CRYPT_E_INVALID_MSG_TYPE
/// The message type is not valid.
///
/// -
/// CRYPT_E_OID_FORMAT
/// The OID is badly formatted.
///
/// -
/// CRYPT_E_UNKNOWN_ALGO
/// The cryptographic algorithm is unknown.
///
/// -
/// E_INVALIDARG
/// One or more arguments are not valid.
///
/// -
/// E_OUTOFMEMORY
/// There is not enough memory.
///
///
/// In addition, if dwMsgType is CMSG_SIGNED, errors can be propagated from CryptCreateHash.
/// If dwMsgType is CMSG_ENVELOPED, errors can be propagated from CryptGenKey, CryptImportKey, and CryptExportKey.
/// If dwMsgType is CMSG_HASHED, errors can be propagated from CryptCreateHash.
///
///
///
/// For functions that perform encryption, the encrypted symmetric keys are reversed from little-endian format to big-endian format
/// after CryptExportKey is called internally. For functions that perform decryption, the encrypted symmetric keys are reversed from
/// big-endian format to little-endian format before CryptImportKey is called.
///
/// CRYPT_NO_SALT is specified when symmetric keys are generated and imported with CryptGenKey and CryptImportKey.
///
/// Messages encrypted with the RC2 encryption algorithm use KP_EFFECTIVE_KEYLEN with CryptGetKeyParam to determine the effective
/// key length of the RC2 key importing or 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 member of the CMSG_ENVELOPED_ENCODE_INFO structure.
///
///
/// For messages encrypted with the RC4, DES, and 3DES encryption algorithms, encode and decode operations now handle the ASN IV
/// octet string parameter for the ContentEncryptionAlgorithm member of the CMSG_ENVELOPED_ENCODE_INFO structure.
///
/// Examples
///
/// For examples that use this function, see Example C Program: Signing, Encoding, Decoding, and Verifying a Message, Alternate Code
/// for Encoding an Enveloped Message, Example C Program: Encoding an Enveloped, Signed Message, and Example C Program: Encoding and
/// Decoding a Hashed Message.
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptmsgopentoencode HCRYPTMSG CryptMsgOpenToEncode(
// DWORD dwMsgEncodingType, DWORD dwFlags, DWORD dwMsgType, void const *pvMsgEncodeInfo, LPSTR pszInnerContentObjID,
// PCMSG_STREAM_INFO pStreamInfo );
[DllImport(Lib.Crypt32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "b0d2610b-05ba-4fb6-8f38-10f970a52091")]
public static extern SafeHCRYPTMSG CryptMsgOpenToEncode(CertEncodingType dwMsgEncodingType, CryptMsgFlags dwFlags, CryptMsgType dwMsgType, [In] IntPtr pvMsgEncodeInfo,
[Optional] SafeOID pszInnerContentObjID, IntPtr pStreamInfo = default);
///
/// The CryptMsgUpdate function adds contents to a cryptographic message. The use of this function allows messages to be
/// constructed piece by piece through repetitive calls of CryptMsgUpdate. The added message content is either encoded or
/// decoded depending on whether the message was opened with CryptMsgOpenToEncode or CryptMsgOpenToDecode.
///
/// Cryptographic message handle of the message to be updated.
/// A pointer to the buffer holding the data to be encoded or decoded.
/// Number of bytes of data in the pbData buffer.
///
///
/// Indicates that the last block of data for encoding or decoding is being processed. Correct usage of this flag is dependent upon
/// whether the message being processed has detached data. The inclusion of detached data in a message is indicated by setting
/// dwFlags to CMSG_DETACHED_FLAG in the call to the function that opened the message.
///
///
/// If CMSG_DETACHED_FLAG was not set and the message was opened using either CryptMsgOpenToDecode or CryptMsgOpenToEncode, fFinal
/// is set to TRUE, and CryptMsgUpdate is only called once.
///
///
/// If the CMSG_DETACHED_FLAG flag was set and a message is opened using CryptMsgOpenToEncode, fFinal is set to TRUE only on
/// the last call to CryptMsgUpdate.
///
///
/// If the CMSG_DETACHED_FLAG flag was set and a message is opened using CryptMsgOpenToDecode, fFinal is set to TRUE when the
/// header is processed by a single call to CryptMsgUpdate. It is set to FALSE while processing the detached data in
/// subsequent calls to CryptMsgUpdate until the last detached data block is to be processed. On the last call to
/// CryptMsgUpdate, it is set to TRUE.
///
///
/// When detached data is decoded, the header and the content of a message are contained in different BLOBs. Each BLOB requires that
/// fFinal be set to TRUE when the last call to the function is made for that BLOB.
///
///
///
/// If the function succeeds, the return value is nonzero ( TRUE).
/// If the function fails, the return value is zero ( FALSE). For extended error information, call GetLastError.
///
/// Errors encountered in the application defined callback function specified by pStreamInfo in CryptMsgOpenToDecode and
/// CryptMsgOpenToEncode might be propagated to CryptMsgUpdate if streaming is used. If this happens, SetLastError is not
/// called by CryptMsgUpdate after the callback function 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.
///
/// The following table lists the error codes most commonly returned by the GetLastError function.
///
///
/// Return code
/// Description
///
/// -
/// CRYPT_E_INVALID_MSG_TYPE
/// The message type is not valid.
///
/// -
/// CRYPT_E_MSG_ERROR
/// An error was encountered doing a cryptographic operation.
///
/// -
/// CRYPT_E_OID_FORMAT
/// The object identifier is badly formatted.
///
/// -
/// CRYPT_E_UNEXPECTED_ENCODING
/// The message is not encoded as expected.
///
/// -
/// CRYPT_E_UNKNOWN_ALGO
/// The cryptographic algorithm is unknown.
///
/// -
/// E_INVALIDARG
/// One or more arguments are not valid.
///
/// -
/// E_OUTOFMEMORY
/// Ran out of memory.
///
///
/// Propagated errors might be encountered from any of the following functions:
///
/// -
/// CryptHashData
///
/// -
/// CryptGetHashParam
///
/// -
/// CryptSignHash
///
/// -
/// CryptGetKeyParam
///
/// -
/// CryptEncrypt
///
/// -
/// CryptCreateHash
///
///
///
/// If the function fails, GetLastError may return an Abstract Syntax Notation One (ASN.1) encoding/decoding error. For information
/// about these errors, see ASN.1 Encoding/Decoding Return Values.
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptmsgupdate BOOL CryptMsgUpdate( HCRYPTMSG hCryptMsg,
// const BYTE *pbData, DWORD cbData, BOOL fFinal );
[DllImport(Lib.Crypt32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "d27d75f0-1646-4926-b375-59e52b00326c")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptMsgUpdate(HCRYPTMSG hCryptMsg, [In] IntPtr pbData, uint cbData, [MarshalAs(UnmanagedType.Bool)] bool fFinal);
///
/// The CryptMsgVerifyCountersignatureEncoded function verifies a countersignature in terms of the SignerInfo structure (as
/// defined by PKCS #7).
///
///
/// This parameter is not used and should be set to NULL.
///
/// Windows Server 2003 and Windows XP:NULL or the handle of the cryptographic provider to use to hash the
/// encryptedDigest field of pbSignerInfo.This parameter's data type is HCRYPTPROV.
///
///
/// Unless there is a strong reason for passing in a specific cryptographic provider in hCryptProv, pass NULL to cause the
/// default RSA or DSS provider to be used.
///
///
///
///
/// Specifies the encoding type used. Currently, only X509_ASN_ENCODING and PKCS_7_ASN_ENCODING are being used; however, additional
/// encoding types may be added in the future. For either current encoding type, use:
///
/// X509_ASN_ENCODING | PKCS_7_ASN_ENCODING.
///
/// A pointer to the encoded BLOB that contains the signer of the contents of a message to be countersigned.
/// Count, in bytes, of the encoded BLOB for the signer of the contents.
/// A pointer to the encoded BLOB containing the countersigner information.
/// Count, in bytes, of the encoded BLOB for the countersigner of the message.
///
/// A pointer to a CERT_INFO that includes with the issuer and serial number of the countersigner. For more information, see Remarks.
///
///
/// If the function succeeds, the return value is nonzero ( TRUE).
/// If the function fails, the return value is zero ( FALSE). For extended error information, call GetLastError.
/// The following table lists the error codes most commonly returned by the GetLastError function.
///
///
/// Return code
/// Description
///
/// -
/// CRYPT_E_AUTH_ATTR_MISSING
/// The message does not contain an expected authenticated attribute.
///
/// -
/// CRYPT_E_HASH_VALUE
/// The hash value is not correct.
///
/// -
/// CRYPT_E_UNEXPECTED_ENCODING
/// The message is not encoded as expected.
///
/// -
/// CRYPT_E_UNKNOWN_ALGO
/// The cryptographic algorithm is unknown.
///
/// -
/// E_INVALIDARG
/// One or more arguments are not valid.
///
/// -
/// E_OUTOFMEMORY
/// Ran out of memory.
///
///
/// Propagated errors from the following functions might be returned.
///
/// -
/// CryptHashData
///
/// -
/// CryptGetHashParam
///
/// -
/// CryptImportKey
///
/// -
/// CryptVerifySignature
///
/// -
/// CryptCreateHash
///
///
///
/// If the function fails, GetLastError may return an Abstract Syntax Notation One (ASN.1) encoding/decoding error. For information
/// about these errors, see ASN.1 Encoding/Decoding Return Values.
///
///
///
///
/// Countersigner verification is done using the PKCS #7 SIGNERINFO structure. The signature must contain the encrypted hash
/// of the encryptedDigest field of pbSignerInfo.
///
///
/// The issuer and serial number of the countersigner must match the countersigner information from pbSignerInfoCountersignature.
/// The only fields referenced from pciCountersigner are SerialNumber, Issuer, and SubjectPublicKeyInfo. The SubjectPublicKeyInfo is
/// used to access the public key that is then used to encrypt the hash from the pciCountersigner so compare it with the hash from
/// the pbSignerInfo.
///
/// Examples
/// For an example that uses this function, see Example C Program: Encoding and Decoding a CounterSigned Message.
///
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptmsgverifycountersignatureencoded BOOL
// CryptMsgVerifyCountersignatureEncoded( HCRYPTPROV_LEGACY hCryptProv, DWORD dwEncodingType, PBYTE pbSignerInfo, DWORD
// cbSignerInfo, PBYTE pbSignerInfoCountersignature, DWORD cbSignerInfoCountersignature, PCERT_INFO pciCountersigner );
[DllImport(Lib.Crypt32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "b0332360-a737-4b48-b592-0c55d493a02d")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptMsgVerifyCountersignatureEncoded([Optional] HCRYPTPROV hCryptProv, CertEncodingType dwEncodingType, [In] IntPtr pbSignerInfo, uint cbSignerInfo,
[In] IntPtr pbSignerInfoCountersignature, uint cbSignerInfoCountersignature, in CERT_INFO pciCountersigner);
///
/// The CryptMsgVerifyCountersignatureEncodedEx function verifies that the pbSignerInfoCounterSignature parameter contains
/// the encrypted hash of the encryptedDigest field of the pbSignerInfo parameter structure. The signer can be a
/// CERT_PUBLIC_KEY_INFO structure, a certificate context, or a chain context.
///
///
/// This parameter is not used and should be set to NULL.
///
/// Windows Server 2003 and Windows XP:NULL or the handle of the cryptographic provider to use to hash the
/// encryptedDigest field of pbSignerInfo.This parameter's data type is HCRYPTPROV.
///
///
/// Unless there is a strong reason for passing in a specific cryptographic provider in hCryptProv, pass NULL to cause the
/// default RSA or DSS provider to be used.
///
///
///
///
/// The encoding type used. Currently, only X509_ASN_ENCODING and PKCS_7_ASN_ENCODING are being used; however, additional encoding
/// types may be added in the future. For either current encoding type, use:
///
/// X509_ASN_ENCODING | PKCS_7_ASN_ENCODING.
///
/// A pointer to the encoded BLOB that contains the signer of the contents of a message to be countersigned.
/// The count, in bytes, of the encoded BLOB for the signer of the contents.
/// A pointer to the encoded BLOB containing the countersigner information.
/// The count, in bytes, of the encoded BLOB for the countersigner of the message.
///
///
/// The structure that contains the signer information. The following table shows the predefined values and the structures indicated.
///
///
///
/// Value
/// Meaning
///
/// -
/// CMSG_VERIFY_SIGNER_PUBKEY
/// pvSigner is a pointer to a CERT_PUBLIC_KEY_INFO structure.
///
/// -
/// CMSG_VERIFY_SIGNER_CERT
/// pvSigner is a pointer to a CERT_CONTEXT structure.
///
/// -
/// CMSG_VERIFY_SIGNER_CHAIN
/// pvSigner is a pointer to a CERT_CHAIN_CONTEXT structure.
///
///
///
///
/// A pointer to a CERT_PUBLIC_KEY_INFO structure, a certificate context, or a chain context depending on the value of dwSignerType.
///
///
/// Flags that modify the function behavior. This can be zero or the following value.
///
///
/// Value
/// Meaning
///
/// -
/// CMSG_VERIFY_COUNTER_SIGN_ENABLE_STRONG_FLAG 0x00000001
///
/// Performs a strong signature check after successful signature verification. Set the pvExtra parameter to point to a
/// CERT_STRONG_SIGN_PARA structure that contains the parameters needed to check the signature strength.. Windows 8 and Windows
/// Server 2012: Support for this flag begins.
///
///
///
///
///
/// If you set the dwFlags parameter to CMSG_VERIFY_COUNTER_SIGN_ENABLE_STRONG_FLAG, set this parameter (pvExtra) to point to
/// a CERT_STRONG_SIGN_PARA structure that contains the parameters used to check the signature strength.
///
///
/// If the function succeeds, the return value is nonzero ( TRUE).
/// If the function fails, the return value is zero ( FALSE). For extended error information, call GetLastError.
/// The following error codes are most commonly returned by the GetLastError function.
///
///
/// Return code
/// Description
///
/// -
/// CRYPT_E_AUTH_ATTR_MISSING
/// The message does not contain an expected authenticated attribute.
///
/// -
/// CRYPT_E_HASH_VALUE
/// The hash value is not correct.
///
/// -
/// CRYPT_E_UNEXPECTED_ENCODING
/// The message is not encoded as expected.
///
/// -
/// CRYPT_E_UNKNOWN_ALGO
/// The cryptographic algorithm is unknown.
///
/// -
/// E_INVALIDARG
/// One or more arguments are not valid.
///
/// -
/// E_OUTOFMEMORY
/// Ran out of memory.
///
///
/// Propagated errors from the following functions might be returned.
///
/// -
/// CryptHashData
///
/// -
/// CryptGetHashParam
///
/// -
/// CryptImportKey
///
/// -
/// CryptVerifySignature
///
/// -
/// CryptCreateHash
///
///
///
/// If the function fails, GetLastError may return an Abstract Syntax Notation One (ASN.1) encoding/decoding error. For information
/// about these errors, see ASN.1 Encoding/Decoding Return Values.
///
///
///
///
/// Countersigner verification is done using the PKCS #7 SIGNERINFO structure. The signature must contain the encrypted hash
/// of the encryptedDigest field of pbSignerInfo.
///
///
/// The issuer and serial number of the countersigner must match the countersigner information from pbSignerInfoCountersignature.
/// The only fields referenced from pciCountersigner are SerialNumber, Issuer, and SubjectPublicKeyInfo. The SubjectPublicKeyInfo is
/// used to access the public key that is then used to encrypt the hash from the pciCountersigner so compare it with the hash from
/// the pbSignerInfo.
///
/// Examples
/// For an example that uses this function, see Example C Program: Encoding and Decoding a CounterSigned Message.
///
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptmsgverifycountersignatureencodedex BOOL
// CryptMsgVerifyCountersignatureEncodedEx( HCRYPTPROV_LEGACY hCryptProv, DWORD dwEncodingType, PBYTE pbSignerInfo, DWORD
// cbSignerInfo, PBYTE pbSignerInfoCountersignature, DWORD cbSignerInfoCountersignature, DWORD dwSignerType, void *pvSigner, DWORD
// dwFlags, void *pvExtra );
[DllImport(Lib.Crypt32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "da756cd5-1dec-4d88-9c90-76dd263035eb")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptMsgVerifyCountersignatureEncodedEx([Optional] HCRYPTPROV hCryptProv, CertEncodingType dwEncodingType, [In] IntPtr pbSignerInfo, uint cbSignerInfo,
[In] IntPtr pbSignerInfoCountersignature, uint cbSignerInfoCountersignature, CryptMsgSignerType dwSignerType, IntPtr pvSigner, CryptMsgVerifyCounterFlags dwFlags, [Optional] IntPtr pvExtra);
///
/// The CryptSignAndEncryptMessage function creates a hash of the specified content, signs the hash, encrypts the content,
/// hashes the encrypted contents and the signed hash, and then encodes both the encrypted content and the signed hash. The result
/// is the same as if the hash were first signed and then encrypted.
///
/// A pointer to a CRYPT_SIGN_MESSAGE_PARA structure that contains the signature parameters.
/// A pointer to a CRYPT_ENCRYPT_MESSAGE_PARA structure containing encryption parameters.
/// Number of array elements in rgpRecipientCert.
///
/// Array of pointers to CERT_CONTEXT structures. Each structure is the certificate of an intended recipients of the message.
///
/// A pointer to a buffer containing the content to be signed and encrypted.
/// The size, in bytes, of the pbToBeSignedAndEncrypted buffer.
///
/// A pointer to a buffer to receive the encrypted and encoded message.
///
/// This parameter can be NULL to set the size of this information for memory allocation purposes. For more information, see
/// Retrieving Data of Unknown Length.
///
///
///
///
/// A pointer to DWORD specifying the size, in bytes, of the buffer pointed to by pbSignedAndEncryptedBlob. When the function
/// returns, this variable contains the size, in bytes, of the signed and encrypted message copied to *pbSignedAndEncryptedBlob.
///
///
/// Note When processing the data returned, applications must use the actual size of the data returned. The actual size can
/// be slightly smaller than the size of the buffer specified on input. (On input, buffer sizes are usually specified large enough
/// to ensure that the largest possible output data will fit in the buffer.) On output, the variable pointed to by this parameter is
/// updated to reflect the actual size of the data copied to the buffer.
///
///
///
/// If the function succeeds, the return value is nonzero (TRUE).
/// If the function fails, the return value is zero (FALSE).
/// For extended error information, call GetLastError.
/// The following lists the error code most commonly returned by the GetLastError function.
///
///
/// Return code
/// Description
///
/// -
/// ERROR_MORE_DATA
///
/// If the buffer specified by the pbSignedAndEncryptedBlob parameter is not large enough to hold the returned data, the function
/// sets the ERROR_MORE_DATA code, and stores the required buffer size, in bytes, into the variable pointed to by pcbSignedAndEncryptedBlob.
///
///
///
/// Note Errors from the called functions CryptSignMessage and CryptEncryptMessage might be propagated to this function.
///
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptsignandencryptmessage BOOL
// CryptSignAndEncryptMessage( PCRYPT_SIGN_MESSAGE_PARA pSignPara, PCRYPT_ENCRYPT_MESSAGE_PARA pEncryptPara, DWORD cRecipientCert,
// PCCERT_CONTEXT [] rgpRecipientCert, const BYTE *pbToBeSignedAndEncrypted, DWORD cbToBeSignedAndEncrypted, BYTE
// *pbSignedAndEncryptedBlob, DWORD *pcbSignedAndEncryptedBlob );
[DllImport(Lib.Crypt32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "0ab234f2-a681-463f-8ba8-b23b05cf2626")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptSignAndEncryptMessage(in CRYPT_SIGN_MESSAGE_PARA pSignPara, in CRYPT_ENCRYPT_MESSAGE_PARA pEncryptPara, uint cRecipientCert,
[In, MarshalAs(UnmanagedType.LPArray)] PCCERT_CONTEXT[] rgpRecipientCert, [In] IntPtr pbToBeSignedAndEncrypted, uint cbToBeSignedAndEncrypted,
[Out] IntPtr pbSignedAndEncryptedBlob, ref uint pcbSignedAndEncryptedBlob);
///
/// The CryptSignMessage function creates a hash of the specified content, signs the hash, and then encodes both the original
/// message content and the signed hash.
///
/// A pointer to CRYPT_SIGN_MESSAGE_PARA structure containing the signature parameters.
///
/// TRUE if this is to be a detached signature. Otherwise, FALSE. If this parameter is set to TRUE, only the
/// signed hash is encoded in pbSignedBlob. Otherwise, both rgpbToBeSigned and the signed hash are encoded.
///
///
/// Count of the number of array elements in rgpbToBeSigned and rgpbToBeSigned. This parameter must be set to one unless
/// fDetachedSignature is set to TRUE.
///
/// Array of pointers to buffers that contain the contents to be signed.
/// Array of sizes, in bytes, of the content buffers pointed to in rgpbToBeSigned.
///
///
/// A pointer to a buffer to receive the encoded signed hash, if fDetachedSignature is TRUE, or to both the encoded content
/// and signed hash if fDetachedSignature is FALSE.
///
///
/// This parameter can be NULL to set the size of this information for memory allocation purposes. For more information, see
/// Retrieving Data of Unknown Length.
///
///
///
///
/// A pointer to a DWORD specifying the size, in bytes, of the pbSignedBlob buffer. When the function returns, this variable
/// contains the size, in bytes, of the signed and encoded message.
///
///
/// Note When processing the data returned, applications must use the actual size of the data returned. The actual size can
/// be slightly smaller than the size of the buffer specified on input. (On input, buffer sizes are usually specified large enough
/// to ensure that the largest possible output data will fit in the buffer.) On output, the variable pointed to by this parameter is
/// updated to reflect the actual size of the data copied to the buffer.
///
///
///
/// If the function succeeds, the return value is nonzero ( TRUE).
/// If the function fails, the return value is zero ( FALSE).
/// For extended error information, call GetLastError.
/// The following lists the error codes most commonly returned by the GetLastError function.
///
///
/// Return code
/// Description
///
/// -
/// ERROR_MORE_DATA
///
/// If the buffer specified by the pbSignedBlob parameter is not large enough to hold the returned data, the function sets the
/// ERROR_MORE_DATA code, and stores the required buffer size, in bytes, into the variable pointed to by pcbSignedBlob.
///
///
/// -
/// E_INVALIDARG
///
/// The message encoding type is not valid. Currently only PKCS_7_ASN_ENCODING is supported. The cbSize in *pSignPara is not valid.
///
///
/// -
/// CRYPT_E_NO_KEY_PROPERTY
/// The pSigningCert in *pSignPara does not have a CERT_KEY_PROV_INFO_PROP_ID or CERT_KEY_CONTEXT_PROP_ID property.
///
///
///
/// Note Errors from the called functions CryptCreateHash, CryptHashData, and CryptSignHash might be propagated to this function.
///
///
/// If the function fails, GetLastError may return an Abstract Syntax Notation One (ASN.1) encoding/decoding error. For information
/// about these errors, see ASN.1 Encoding/Decoding Return Values.
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptsignmessage BOOL CryptSignMessage(
// PCRYPT_SIGN_MESSAGE_PARA pSignPara, BOOL fDetachedSignature, DWORD cToBeSigned, const BYTE * [] rgpbToBeSigned, DWORD []
// rgcbToBeSigned, BYTE *pbSignedBlob, DWORD *pcbSignedBlob );
[DllImport(Lib.Crypt32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "f14f7c7b-14ac-40a7-9a49-d1a899ecc52a")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptSignMessage(in CRYPT_SIGN_MESSAGE_PARA pSignPara, [MarshalAs(UnmanagedType.Bool)] bool fDetachedSignature, uint cToBeSigned,
[In, MarshalAs(UnmanagedType.LPArray)] IntPtr[] rgpbToBeSigned, [In] uint[] rgcbToBeSigned, [Out] IntPtr pbSignedBlob, ref uint pcbSignedBlob);
///
/// The CryptSignMessageWithKey function signs a message by using a CSP's private key specified in the parameters. A
/// placeholder SignerId is created and stored in the message.
///
/// A pointer to a CRYPT_KEY_SIGN_MESSAGE_PARA structure that contains the signature parameters.
/// A pointer to a buffer array that contains the message to be signed.
/// The number of array elements in the pbToBeSigned buffer array.
///
/// A pointer to a buffer to receive the encoded signed message.
///
/// This parameter can be NULL to set the size of this information for memory allocation purposes. For more information, see
/// Retrieving Data of Unknown Length.
///
///
///
///
/// A pointer to a DWORD value that indicates the size, in bytes, of the pbSignedBlob buffer. When the function returns, this
/// variable contains the size, in bytes, of the signed and encoded message.
///
///
/// Note When processing the data returned, applications must use the actual size of the data returned. The actual size can
/// be slightly smaller than the size of the buffer specified on input. (On input, buffer sizes are usually specified large enough
/// to ensure that the largest possible output data will fit in the buffer.) On output, the variable pointed to by this parameter is
/// updated to reflect the actual size of the data copied to the buffer.
///
///
///
/// If the function succeeds, the return value is nonzero (TRUE).
/// If the function fails, the return value is zero (FALSE).
/// For extended error information, call GetLastError.
/// The following lists the error codes most commonly returned by the GetLastError function.
///
///
/// Return code
/// Description
///
/// -
/// ERROR_MORE_DATA
///
/// If the buffer specified by the pbSignedBlob parameter is not large enough to hold the returned data, the function sets the
/// ERROR_MORE_DATA code and stores the required buffer size, in bytes, into the variable pointed to by pcbSignedBlob.
///
///
/// -
/// E_INVALIDARG
///
/// The message encoding type is not valid. Currently only PKCS_7_ASN_ENCODING is supported. The cbSize in *pSignPara is not valid.
///
///
/// -
/// CRYPT_E_NO_KEY_PROPERTY
/// The pSigningCert in *pSignPara does not have a CERT_KEY_PROV_INFO_PROP_ID or CERT_KEY_CONTEXT_PROP_ID property.
///
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptsignmessagewithkey BOOL CryptSignMessageWithKey(
// PCRYPT_KEY_SIGN_MESSAGE_PARA pSignPara, const BYTE *pbToBeSigned, DWORD cbToBeSigned, BYTE *pbSignedBlob, DWORD *pcbSignedBlob );
[DllImport(Lib.Crypt32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "d31024bf-7022-440b-8134-a02578510357")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptSignMessageWithKey(in CRYPT_KEY_SIGN_MESSAGE_PARA pSignPara, [In] IntPtr pbToBeSigned, uint cbToBeSigned, [Out] IntPtr pbSignedBlob, ref uint pcbSignedBlob);
/// The CryptVerifyDetachedMessageHash function verifies a detached hash.
/// A pointer to a CRYPT_HASH_MESSAGE_PARA structure containing the hash parameters.
/// A pointer to the encoded, detached hash.
/// The size, in bytes, of the detached hash.
/// Number of elements in the rgpbToBeHashed and rgcbToBeHashed arrays.
/// Array of pointers to content buffers to be hashed.
///
/// Array of sizes, in bytes, for the content buffers pointed to by the elements of the rgcbToBeHashed array.
///
///
/// A pointer to a buffer to receive the computed hash.
///
/// This parameter can be NULL if the newly created hash is not needed for additional processing, or to set the size of the
/// hash for memory allocation purposes. For more information, see Retrieving Data of Unknown Length.
///
///
///
///
/// A pointer to a DWORD specifying the size, in bytes, of the pbComputedHash buffer. When the function returns, this
/// DWORD contains the size, in bytes, of the created hash. The hash will not be returned if this parameter is NULL.
///
///
/// Note When processing the data returned , applications must use the actual size of the data returned. The actual size can
/// be slightly smaller than the size of the buffer specified on input. (On input, buffer sizes are usually specified large enough
/// to ensure that the largest possible output data will fit in the buffer.) On output, the variable pointed to by this parameter is
/// updated to reflect the actual size of the data copied to the buffer.
///
///
///
/// If the function succeeds, the return value is nonzero (TRUE).
/// If the function fails, the return value is zero (FALSE).
/// For extended error information, call GetLastError.
/// The following lists the error codes most commonly returned by the GetLastError function.
///
///
/// Return code
/// Description
///
/// -
/// CRYPT_E_UNEXPECTED_MSG_TYPE
/// Not a hashed cryptographic message.
///
/// -
/// E_INVALIDARG
///
/// The message encoding type is not valid. Currently only PKCS_7_ASN_ENCODING is supported. The cbSize in *pHashPara is not valid.
///
///
/// -
/// ERROR_MORE_DATA
///
/// If the buffer specified by the pbComputedHash parameter is not large enough to hold the returned data, the function sets the
/// ERROR_MORE_DATA code, and stores the required buffer size, in bytes, into the variable pointed to by pcbComputedHash.
///
///
///
///
/// Note Errors from the called functions CryptCreateHash, CryptHashData, and CryptGetHashParam might be propagated to this
/// function. If the function fails, GetLastError may return an Abstract Syntax Notation One (ASN.1) encoding/decoding error. For
/// information about these errors, see ASN.1 Encoding/Decoding Return Values.
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptverifydetachedmessagehash BOOL
// CryptVerifyDetachedMessageHash( PCRYPT_HASH_MESSAGE_PARA pHashPara, BYTE *pbDetachedHashBlob, DWORD cbDetachedHashBlob, DWORD
// cToBeHashed, const BYTE * [] rgpbToBeHashed, DWORD [] rgcbToBeHashed, BYTE *pbComputedHash, DWORD *pcbComputedHash );
[DllImport(Lib.Crypt32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "b529b9e2-9798-4548-a44f-c330524a3e6b")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptVerifyDetachedMessageHash(in CRYPT_HASH_MESSAGE_PARA pHashPara, [In] IntPtr pbDetachedHashBlob, uint cbDetachedHashBlob,
uint cToBeHashed, [In, MarshalAs(UnmanagedType.LPArray)] IntPtr[] rgpbToBeHashed, [In] uint[] rgcbToBeHashed, [Out] IntPtr pbComputedHash, ref uint pcbComputedHash);
///
/// The CryptVerifyDetachedMessageSignature function verifies a signed message containing a detached signature or signatures.
///
/// A pointer to a CRYPT_VERIFY_MESSAGE_PARA structure containing the verification parameters.
///
/// Index of the signature to be verified. A message might have several signers and this function can be called repeatedly, changing
/// dwSignerIndex to verify other signatures. If the function returns FALSE, and GetLastError returns CRYPT_E_NO_SIGNER, the
/// previous call received the last signer of the message.
///
/// A pointer to a BLOB containing the encoded message signatures.
/// The size, in bytes, of the detached signature.
/// Number of array elements in rgpbToBeSigned and rgcbToBeSigned.
/// Array of pointers to buffers containing the contents to be hashed.
/// Array of sizes, in bytes, for the content buffers pointed to in rgpbToBeSigned.
///
/// A pointer to a pointer to a CERT_CONTEXT structure of a signer certificate. When you have finished using the certificate
/// context, free it by calling the CertFreeCertificateContext function. A pointer to a CERT_CONTEXT structure will not be
/// returned if this parameter is NULL.
///
///
/// If the function succeeds, the return value is nonzero (TRUE).
/// If the function fails, the return value is zero ( FALSE).
/// For extended error information, call GetLastError.
/// The following lists the error codes most commonly returned by the GetLastError function.
///
///
/// Return code
/// Description
///
/// -
/// E_INVALIDARG
///
/// Invalid message and certificate encoding types. Currently only PKCS_7_ASN_ENCODING and X509_ASN_ENCODING_TYPE are supported.
/// Invalid cbSize in *pVerifyPara.
///
///
/// -
/// CRYPT_E_UNEXPECTED_MSG_TYPE
/// Not a signed cryptographic message.
///
/// -
/// CRYPT_E_NO_SIGNER
/// The message does not have any signers or a signer for the specified dwSignerIndex.
///
/// -
/// NTE_BAD_ALGID
/// The message was hashed and signed by using an unknown or unsupported algorithm.
///
/// -
/// NTE_BAD_SIGNATURE
/// The message's signature was not verified.
///
///
///
/// Note Errors from the called functions CryptCreateHash, CryptHashData, CryptVerifySignature, and CryptImportKey might be
/// propagated to this function.If the function fails, GetLastError may return an Abstract Syntax Notation One (ASN.1)
/// encoding/decoding error. For information about these errors, see ASN.1 Encoding/Decoding Return Values.
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptverifydetachedmessagesignature BOOL
// CryptVerifyDetachedMessageSignature( PCRYPT_VERIFY_MESSAGE_PARA pVerifyPara, DWORD dwSignerIndex, const BYTE *pbDetachedSignBlob,
// DWORD cbDetachedSignBlob, DWORD cToBeSigned, const BYTE * [] rgpbToBeSigned, DWORD [] rgcbToBeSigned, PCCERT_CONTEXT
// *ppSignerCert );
[DllImport(Lib.Crypt32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "d437f6bf-eb56-4d29-bb91-eb8487e50219")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptVerifyDetachedMessageSignature(in CRYPT_VERIFY_MESSAGE_PARA pVerifyPara, uint dwSignerIndex, [In] IntPtr pbDetachedSignBlob, uint cbDetachedSignBlob,
uint cToBeSigned, [In, MarshalAs(UnmanagedType.LPArray)] IntPtr[] rgpbToBeSigned, [In] uint[] rgcbToBeSigned, out SafePCCERT_CONTEXT ppSignerCert);
/// The CryptVerifyMessageHash function verifies the hash of specified content.
/// A pointer to a CRYPT_HASH_MESSAGE_PARA structure containing hash parameters.
/// A pointer to a buffer containing original content and its hash.
/// The size, in bytes, of the original hash buffer.
///
/// A pointer to a buffer to receive the original content that was hashed.
///
/// This parameter can be NULL if the original content is not needed for additional processing, or to set the size of the
/// original content for memory allocation purposes. For more information, see Retrieving Data of Unknown Length.
///
///
///
///
/// A pointer to a DWORD specifying the size, in bytes, of the pbToBeHashed buffer. When the function returns, this variable
/// contains the size, in bytes, of the original content copied to pbToBeHashed. The original content will not be returned if this
/// parameter is NULL.
///
///
/// Note When processing the data returned, applications must use the actual size of the data returned. The actual size can
/// be slightly smaller than the size of the buffer specified on input. (On input, buffer sizes are usually specified large enough
/// to ensure that the largest possible output data will fit in the buffer.) On output, the variable pointed to by this parameter is
/// updated to reflect the actual size of the data copied to the buffer.
///
///
///
/// A pointer to a buffer to receive the computed hash. This parameter can be NULL if the created hash is not needed for
/// additional processing, or to set the size of the original content for memory allocation purposes. For more information, see
/// Retrieving Data of Unknown Length.
///
///
///
/// A pointer to a DWORD specifying the size, in bytes, of the pbComputedHash buffer. When the function returns, this
/// variable contains the size, in bytes, of the created hash. The hash is not returned if this parameter is NULL.
///
///
/// Note When processing the data returned, applications must use the actual size of the data returned. The actual size can
/// be slightly smaller than the size of the buffer specified on input. (On input, buffer sizes are usually specified large enough
/// to ensure that the largest possible output data will fit in the buffer.) On output, the variable pointed to by this parameter is
/// updated to reflect the actual size of the data copied to the buffer.
///
///
///
/// If the function succeeds, the return value is nonzero (TRUE).
/// If the function fails, the return value is zero (FALSE).
/// For extended error information, call GetLastError.
/// The following lists the error codes most commonly returned by the GetLastError function.
///
///
/// Return code
/// Description
///
/// -
/// CRYPT_E_UNEXPECTED_MSG_TYPE
/// Not a hashed cryptographic message.
///
/// -
/// E_INVALIDARG
///
/// The message encoding type is not valid. Currently only PKCS_7_ASN_ENCODING is supported. The cbSize in *pHashPara is not valid.
///
///
/// -
/// ERROR_MORE_DATA
///
/// If the buffer specified by the pbToBeHashed parameter is not large enough to hold the returned data, the function sets the
/// ERROR_MORE_DATA code, and stores the required buffer size, in bytes, into the variable pointed to by pcbToBeHashed.
///
///
///
///
/// Note Errors from the called functions CryptCreateHash, CryptHashData, and CryptGetHashParam might be propagated to this
/// function. If the function fails, GetLastError may return an Abstract Syntax Notation One (ASN.1) encoding/decoding error. For
/// information about these errors, see ASN.1 Encoding/Decoding Return Values.
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptverifymessagehash BOOL CryptVerifyMessageHash(
// PCRYPT_HASH_MESSAGE_PARA pHashPara, BYTE *pbHashedBlob, DWORD cbHashedBlob, BYTE *pbToBeHashed, DWORD *pcbToBeHashed, BYTE
// *pbComputedHash, DWORD *pcbComputedHash );
[DllImport(Lib.Crypt32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "3b5185b9-e24b-4302-a60c-74ccbd19077c")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptVerifyMessageHash(in CRYPT_HASH_MESSAGE_PARA pHashPara, [In] IntPtr pbHashedBlob, uint cbHashedBlob, [Out] IntPtr pbToBeHashed,
ref uint pcbToBeHashed, [Out] IntPtr pbComputedHash, ref uint pcbComputedHash);
///
/// The CryptVerifyMessageSignature function verifies a signed message's signature.
///
/// This function should not be used to verify the signature of a detached message. You should use the
/// CryptVerifyDetachedMessageSignature function to verify the signature of a detached message.
///
///
/// A pointer to a CRYPT_VERIFY_MESSAGE_PARA structure that contains verification parameters.
///
/// The index of the desired signature. There can be more than one signature. CryptVerifyMessageSignature can be called
/// repeatedly, incrementing dwSignerIndex each time. Set this parameter to zero for the first signer, or if there is only one
/// signer. If the function returns FALSE, and GetLastError returns CRYPT_E_NO_SIGNER, the previous call processed the last
/// signer of the message.
///
/// A pointer to a buffer that contains the signed message.
/// The size, in bytes, of the signed message buffer.
///
/// A pointer to a buffer to receive the decoded message.
///
/// This parameter can be NULL if the decoded message is not needed for additional processing or to set the size of the
/// message for memory allocation purposes. For more information, see Retrieving Data of Unknown Length.
///
///
///
///
/// A pointer to a DWORD value that specifies the size, in bytes, of the pbDecoded buffer. When the function returns, this
/// DWORD contains the size, in bytes, of the decoded message. The decoded message will not be returned if this parameter is NULL.
///
///
/// Note When processing the data returned, applications must use the actual size of the data returned. The actual size can
/// be slightly smaller than the size of the buffer specified on input. (On input, buffer sizes are usually specified large enough
/// to ensure that the largest possible output data will fit in the buffer.) On output, the variable pointed to by this parameter is
/// updated to reflect the actual size of the data copied to the buffer.
///
///
///
/// The address of a CERT_CONTEXT structure pointer that receives the certificate of the signer. When you have finished using this
/// structure, free it by passing this pointer to the CertFreeCertificateContext function. This parameter can be NULL if the
/// signer's certificate is not needed.
///
///
///
/// If the function succeeds, the function returns nonzero. This does not necessarily mean that the signature was verified. In the
/// case of a detached message, the variable pointed to by pcbDecoded will contain zero. In this case, this function will return
/// nonzero, but the signature is not verified. To verify the signature of a detached message, use the
/// CryptVerifyDetachedMessageSignature function.
///
/// If the function fails, it returns zero. For extended error information, call GetLastError.
/// The following table shows the error codes most commonly returned by the GetLastError function.
///
///
/// Return code
/// Description
///
/// -
/// ERROR_MORE_DATA
///
/// If the buffer specified by the pbDecoded parameter is not large enough to hold the returned data, the function sets the
/// ERROR_MORE_DATA code, and stores the required buffer size, in bytes, in the variable pointed to by pcbDecoded.
///
///
/// -
/// E_INVALIDARG
///
/// Invalid message and certificate encoding types. Currently only PKCS_7_ASN_ENCODING and X509_ASN_ENCODING_TYPE are supported.
/// Invalid cbSize in *pVerifyPara.
///
///
/// -
/// CRYPT_E_UNEXPECTED_MSG_TYPE
/// Not a signed cryptographic message.
///
/// -
/// CRYPT_E_NO_SIGNER
/// The message does not have any signers or a signer for the specified dwSignerIndex.
///
/// -
/// NTE_BAD_ALGID
/// The message was hashed and signed by using an unknown or unsupported algorithm.
///
/// -
/// NTE_BAD_SIGNATURE
/// The message's signature was not verified.
///
///
///
/// Note Errors from the called functions CryptCreateHash, CryptHashData, CryptVerifySignature, and CryptImportKey can be
/// propagated to this function. If the function fails, GetLastError may return an Abstract Syntax Notation One (ASN.1)
/// encoding/decoding error. For information about these errors, see ASN.1 Encoding/Decoding Return Values.
///
///
///
///
/// For a verified signer and message, ppSignerCert is updated with the CERT_CONTEXT of the signer. It must be freed by calling
/// CertFreeCertificateContext. Otherwise, ppSignerCert is set to NULL.
///
/// For a message that contains only certificates and CRLs, pcbDecoded is set to NULL.
/// Examples
/// For an example that uses this function, see Example C Program: Signing a Message and Verifying a Message Signature.
///
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptverifymessagesignature BOOL
// CryptVerifyMessageSignature( PCRYPT_VERIFY_MESSAGE_PARA pVerifyPara, DWORD dwSignerIndex, const BYTE *pbSignedBlob, DWORD
// cbSignedBlob, BYTE *pbDecoded, DWORD *pcbDecoded, PCCERT_CONTEXT *ppSignerCert );
[DllImport(Lib.Crypt32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "03411e7a-b097-4059-a198-3d412ae40e38")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptVerifyMessageSignature(in CRYPT_VERIFY_MESSAGE_PARA pVerifyPara, uint dwSignerIndex, [In] IntPtr pbSignedBlob, uint cbSignedBlob,
[Out] IntPtr pbDecoded, ref uint pcbDecoded, out SafePCCERT_CONTEXT ppSignerCert);
///
/// The CryptVerifyMessageSignatureWithKey function verifies a signed message's signature by using specified public key information.
///
/// A pointer to a CRYPT_KEY_VERIFY_MESSAGE_PARA structure that contains verification parameters.
///
/// A pointer to a CERT_PUBLIC_KEY_INFO structure that contains the public key that is used to verify the signed message. If
/// NULL, the signature is not verified.
///
/// A pointer to a buffer that contains the signed message.
/// The size, in bytes, of the signed message buffer.
///
/// A pointer to a buffer to receive the decoded message.
///
/// This parameter can be NULL if the decoded message is not needed for additional processing or to set the size of the
/// message for memory allocation purposes. For more information, see Retrieving Data of Unknown Length.
///
///
///
///
/// A pointer to a DWORD value that specifies the size, in bytes, of the pbDecoded buffer. When the function returns, this
/// DWORD contains the size, in bytes, of the decoded message. The decoded message will not be returned if this parameter is NULL.
///
///
/// Note When processing the data returned, applications must use the actual size of the data returned. The actual size can
/// be slightly smaller than the size of the buffer specified on input. (On input, buffer sizes are usually specified large enough
/// to ensure that the largest possible output data will fit in the buffer.) On output, the variable pointed to by this parameter is
/// updated to reflect the actual size of the data copied to the buffer.
///
///
///
/// If the function succeeds, the function returns nonzero.
/// If the function fails, it returns zero. For extended error information, call GetLastError.
/// The following table shows the error codes most commonly returned by the GetLastError function.
///
///
/// Return code
/// Description
///
/// -
/// ERROR_MORE_DATA
///
/// If the buffer specified by the pbDecoded parameter is not large enough to hold the returned data, the function sets the
/// ERROR_MORE_DATA code, and stores the required buffer size, in bytes, in the variable pointed to by pcbDecoded.
///
///
/// -
/// E_INVALIDARG
///
/// Invalid message and certificate encoding types. Currently only PKCS_7_ASN_ENCODING and X509_ASN_ENCODING_TYPE are supported.
/// Invalid cbSize in *pVerifyPara.
///
///
/// -
/// CRYPT_E_UNEXPECTED_MSG_TYPE
/// Not a signed cryptographic message.
///
/// -
/// CRYPT_E_NO_SIGNER
/// The message does not have any signers or a signer for the specified dwSignerIndex.
///
/// -
/// NTE_BAD_ALGID
/// The message was hashed and signed by using an unknown or unsupported algorithm.
///
/// -
/// NTE_BAD_SIGNATURE
/// The message's signature was not verified.
///
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptverifymessagesignaturewithkey BOOL
// CryptVerifyMessageSignatureWithKey( PCRYPT_KEY_VERIFY_MESSAGE_PARA pVerifyPara, PCERT_PUBLIC_KEY_INFO pPublicKeyInfo, const BYTE
// *pbSignedBlob, DWORD cbSignedBlob, BYTE *pbDecoded, DWORD *pcbDecoded );
[DllImport(Lib.Crypt32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "6fe0f9ee-1838-4eb7-8254-05b878eb8f56")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptVerifyMessageSignatureWithKey(in CRYPT_KEY_VERIFY_MESSAGE_PARA pVerifyPara, in CERT_PUBLIC_KEY_INFO pPublicKeyInfo, [In] IntPtr pbSignedBlob,
uint cbSignedBlob, [Out] IntPtr pbDecoded, ref uint pcbDecoded);
///
/// The CryptVerifyMessageSignatureWithKey function verifies a signed message's signature by using specified public key information.
///
/// A pointer to a CRYPT_KEY_VERIFY_MESSAGE_PARA structure that contains verification parameters.
///
/// A pointer to a CERT_PUBLIC_KEY_INFO structure that contains the public key that is used to verify the signed message. If
/// NULL, the signature is not verified.
///
/// A pointer to a buffer that contains the signed message.
/// The size, in bytes, of the signed message buffer.
///
/// A pointer to a buffer to receive the decoded message.
///
/// This parameter can be NULL if the decoded message is not needed for additional processing or to set the size of the
/// message for memory allocation purposes. For more information, see Retrieving Data of Unknown Length.
///
///
///
///
/// A pointer to a DWORD value that specifies the size, in bytes, of the pbDecoded buffer. When the function returns, this
/// DWORD contains the size, in bytes, of the decoded message. The decoded message will not be returned if this parameter is NULL.
///
///
/// Note When processing the data returned, applications must use the actual size of the data returned. The actual size can
/// be slightly smaller than the size of the buffer specified on input. (On input, buffer sizes are usually specified large enough
/// to ensure that the largest possible output data will fit in the buffer.) On output, the variable pointed to by this parameter is
/// updated to reflect the actual size of the data copied to the buffer.
///
///
///
/// If the function succeeds, the function returns nonzero.
/// If the function fails, it returns zero. For extended error information, call GetLastError.
/// The following table shows the error codes most commonly returned by the GetLastError function.
///
///
/// Return code
/// Description
///
/// -
/// ERROR_MORE_DATA
///
/// If the buffer specified by the pbDecoded parameter is not large enough to hold the returned data, the function sets the
/// ERROR_MORE_DATA code, and stores the required buffer size, in bytes, in the variable pointed to by pcbDecoded.
///
///
/// -
/// E_INVALIDARG
///
/// Invalid message and certificate encoding types. Currently only PKCS_7_ASN_ENCODING and X509_ASN_ENCODING_TYPE are supported.
/// Invalid cbSize in *pVerifyPara.
///
///
/// -
/// CRYPT_E_UNEXPECTED_MSG_TYPE
/// Not a signed cryptographic message.
///
/// -
/// CRYPT_E_NO_SIGNER
/// The message does not have any signers or a signer for the specified dwSignerIndex.
///
/// -
/// NTE_BAD_ALGID
/// The message was hashed and signed by using an unknown or unsupported algorithm.
///
/// -
/// NTE_BAD_SIGNATURE
/// The message's signature was not verified.
///
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptverifymessagesignaturewithkey BOOL
// CryptVerifyMessageSignatureWithKey( PCRYPT_KEY_VERIFY_MESSAGE_PARA pVerifyPara, PCERT_PUBLIC_KEY_INFO pPublicKeyInfo, const BYTE
// *pbSignedBlob, DWORD cbSignedBlob, BYTE *pbDecoded, DWORD *pcbDecoded );
[DllImport(Lib.Crypt32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "6fe0f9ee-1838-4eb7-8254-05b878eb8f56")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptVerifyMessageSignatureWithKey(in CRYPT_KEY_VERIFY_MESSAGE_PARA pVerifyPara, [In, Optional] IntPtr pPublicKeyInfo, [In] IntPtr pbSignedBlob,
uint cbSignedBlob, [Out] IntPtr pbDecoded, ref uint pcbDecoded);
///
/// The CMSG_CMS_SIGNER_INFO structure contains the content of the defined SignerInfo in signed or signed and enveloped
/// messages. In decoding a received message, CryptMsgGetParam is called for each signer to get a CMSG_CMS_SIGNER_INFO structure.
///
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/ns-wincrypt-cmsg_cms_signer_info typedef struct _CMSG_CMS_SIGNER_INFO
// { DWORD dwVersion; CERT_ID SignerId; CRYPT_ALGORITHM_IDENTIFIER HashAlgorithm; CRYPT_ALGORITHM_IDENTIFIER
// HashEncryptionAlgorithm; CRYPT_DATA_BLOB EncryptedHash; CRYPT_ATTRIBUTES AuthAttrs; CRYPT_ATTRIBUTES UnauthAttrs; }
// CMSG_CMS_SIGNER_INFO, *PCMSG_CMS_SIGNER_INFO;
[PInvokeData("wincrypt.h", MSDNShortId = "177323ef-4e26-4681-a474-1a99fb6900af")]
[StructLayout(LayoutKind.Sequential)]
public struct CMSG_CMS_SIGNER_INFO
{
/// The version of this structure.
public uint dwVersion;
/// A CERT_ID structure that identifies the signer's certificate.
public CERT_ID SignerId;
/// A CRYPT_ALGORITHM_IDENTIFIER structure that specifies the algorithm used in generating the hash of a message.
public CRYPT_ALGORITHM_IDENTIFIER HashAlgorithm;
/// A CRYPT_ALGORITHM_IDENTIFIER structure that specifies the algorithm used to encrypt the hash.
public CRYPT_ALGORITHM_IDENTIFIER HashEncryptionAlgorithm;
/// A CRYPT_DATA_BLOB structure that contains the encrypted hash of the message, the signature.
public CRYPTOAPI_BLOB EncryptedHash;
/// A CRYPT_ATTRIBUTES structure that contains authenticated attributes of the signer.
public CRYPT_ATTRIBUTES AuthAttrs;
/// A CRYPT_ATTRIBUTES structure that contains unauthenticated attributes of the signer.
public CRYPT_ATTRIBUTES UnauthAttrs;
}
///
/// The CMSG_CTRL_ADD_SIGNER_UNAUTH_ATTR_PARA structure is used to add an unauthenticated attribute to a signer of a signed
/// message. This structure is passed to CryptMsgControl if the dwCtrlType parameter is set to CMSG_CTRL_ADD_SIGNER_UNAUTH_ATTR.
///
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/ns-wincrypt-cmsg_ctrl_add_signer_unauth_attr_para typedef struct
// _CMSG_CTRL_ADD_SIGNER_UNAUTH_ATTR_PARA { DWORD cbSize; DWORD dwSignerIndex; CRYPT_DATA_BLOB blob; }
// CMSG_CTRL_ADD_SIGNER_UNAUTH_ATTR_PARA, *PCMSG_CTRL_ADD_SIGNER_UNAUTH_ATTR_PARA;
[PInvokeData("wincrypt.h", MSDNShortId = "5e347a50-942e-4278-a9ae-ad4c30c55c6b")]
[StructLayout(LayoutKind.Sequential)]
public struct CMSG_CTRL_ADD_SIGNER_UNAUTH_ATTR_PARA
{
/// Size of this structure in bytes.
public uint cbSize;
///
/// Index of the signer in the rgSigners array of pointers of CMSG_SIGNER_ENCODE_INFO structures in a signed message's
/// CMSG_SIGNED_ENCODE_INFO structure. The unauthenticated attribute is to be added to this signer's information.
///
public uint dwSignerIndex;
///
public CRYPTOAPI_BLOB blob;
}
///
///
/// The CMSG_CTRL_DECRYPT_PARA structure contains information used to decrypt an enveloped message for a key transport
/// recipient. This structure is passed to CryptMsgControl if the dwCtrlType parameter is CMSG_CTRL_DECRYPT.
///
///
/// For information about how CryptoAPI supports Secure/Multipurpose Internet Mail Extensions (S/MIME) email interoperability, see
/// the Remarks section of CryptMsgOpenToEncode.
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/ns-wincrypt-cmsg_ctrl_decrypt_para typedef struct
// _CMSG_CTRL_DECRYPT_PARA { DWORD cbSize; union { HCRYPTPROV hCryptProv; NCRYPT_KEY_HANDLE hNCryptKey; } DUMMYUNIONNAME; DWORD
// dwKeySpec; DWORD dwRecipientIndex; } CMSG_CTRL_DECRYPT_PARA, *PCMSG_CTRL_DECRYPT_PARA;
[PInvokeData("wincrypt.h", MSDNShortId = "eb9b1daa-b04f-419a-88e3-7c772f9e62eb")]
[StructLayout(LayoutKind.Sequential)]
public struct CMSG_CTRL_DECRYPT_PARA
{
/// The size, in bytes, of this structure.
public uint cbSize;
///
public CMSG_CTRL_DECRYPT_PARA_HANDLES Handle;
///
[StructLayout(LayoutKind.Explicit)]
public struct CMSG_CTRL_DECRYPT_PARA_HANDLES
{
///
/// Cryptographic service provider (CSP) handle. The CNG function NCryptIsKeyHandle is called to determine the union choice.
///
[FieldOffset(0)]
public HCRYPTPROV hCryptProv;
///
/// A handle to the CNG Cryptographic service provider (CSP). The CNG function, NCryptIsKeyHandle, is called to determine
/// the union choice. New encrypt algorithms are only supported in CNG functions. The CNG function, NCryptTranslateHandle,
/// will be called to convert the CryptoAPI hCryptProv choice where necessary. We recommend that applications pass, to the
/// hNCryptKey member, the CNG CSP handle that is returned from the NCryptOpenKey function.
///
[FieldOffset(0)]
public NCrypt.NCRYPT_KEY_HANDLE hNCryptKey;
}
///
/// The private key to be used. This member is not used when the hNCryptKey member is used.
/// The following dwKeySpec values are defined for the default provider.
///
///
/// Value
/// Meaning
///
/// -
/// AT_KEYEXCHANGE
/// Keys used to encrypt and decrypt session keys.
///
/// -
/// AT_SIGNATURE
/// Keys used to create and verify digital signatures.
///
///
/// If dwKeySpec is zero, the default AT_KEYEXCHANGE is used.
///
public CertKeySpec dwKeySpec;
/// Index of the recipient in the message associated with the hCryptProv private key.
public uint dwRecipientIndex;
}
///
/// The CMSG_CTRL_DEL_SIGNER_UNAUTH_ATTR_PARA structure is used to delete an unauthenticated attribute of a signer of a
/// signed message. This structure is passed to CryptMsgControl if the dwCrlType parameter is CMSG_CTRL_DEL_SIGNER_UNAUTH_ATTR.
///
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/ns-wincrypt-cmsg_ctrl_del_signer_unauth_attr_para typedef struct
// _CMSG_CTRL_DEL_SIGNER_UNAUTH_ATTR_PARA { DWORD cbSize; DWORD dwSignerIndex; DWORD dwUnauthAttrIndex; }
// CMSG_CTRL_DEL_SIGNER_UNAUTH_ATTR_PARA, *PCMSG_CTRL_DEL_SIGNER_UNAUTH_ATTR_PARA;
[PInvokeData("wincrypt.h", MSDNShortId = "729fbbe0-40c6-41e7-851f-6f93f47e8f4d")]
[StructLayout(LayoutKind.Sequential)]
public struct CMSG_CTRL_DEL_SIGNER_UNAUTH_ATTR_PARA
{
/// Size of this structure in bytes.
public uint cbSize;
///
/// Index of the signer in the rgSigners array of pointers to CMSG_SIGNER_ENCODE_INFO structures in a signed message's
/// CMSG_SIGNED_ENCODE_INFO structure. The unauthenticated attribute for this signer is deleted.
///
public uint dwSignerIndex;
///
/// Index of the element in the rgUnauthAttr array of the CMSG_SIGNER_ENCODE_INFO structure holding the unauthenticated
/// attribute to be removed.
///
public uint dwUnauthAttrIndex;
}
/// The CMSG_CTRL_KEY_AGREE_DECRYPT_PARA structure contains information about a key agreement recipient.
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/ns-wincrypt-cmsg_ctrl_key_agree_decrypt_para typedef struct
// _CMSG_CTRL_KEY_AGREE_DECRYPT_PARA { DWORD cbSize; union { HCRYPTPROV hCryptProv; NCRYPT_KEY_HANDLE hNCryptKey; } DUMMYUNIONNAME;
// DWORD dwKeySpec; PCMSG_KEY_AGREE_RECIPIENT_INFO pKeyAgree; DWORD dwRecipientIndex; DWORD dwRecipientEncryptedKeyIndex;
// CRYPT_BIT_BLOB OriginatorPublicKey; } CMSG_CTRL_KEY_AGREE_DECRYPT_PARA, *PCMSG_CTRL_KEY_AGREE_DECRYPT_PARA;
[PInvokeData("wincrypt.h", MSDNShortId = "14e58281-4315-4ece-8ea8-92765cffd212")]
[StructLayout(LayoutKind.Sequential)]
public struct CMSG_CTRL_KEY_AGREE_DECRYPT_PARA
{
/// The size, in bytes, of this data structure.
public uint cbSize;
///
public CMSG_CTRL_KEY_AGREE_DECRYPT_PARA_HANDLES Handle;
///
[StructLayout(LayoutKind.Explicit)]
public struct CMSG_CTRL_KEY_AGREE_DECRYPT_PARA_HANDLES
{
///
/// A handle to the cryptographic service provider (CSP) used to do the recipient key encryption and export. If NULL,
/// the provider specified in CMSG_ENVELOPED_ENCODE_INFO is used. The CNG function NCryptIsKeyHandle is called to determine
/// the union choice.
///
[FieldOffset(0)]
public HCRYPTPROV hCryptProv;
///
/// A handle to the CNG CSP used to do the recipient key encryption and export. The CNG function NCryptIsKeyHandle is called
/// to determine the union choice. New encrypt algorithms are only supported in CNG functions. The CNG function
/// NCryptTranslateHandle will be called to convert the CryptoAPI CSP hCryptProv choice where necessary. We recommend that
/// applications pass, to the hNCryptKey member, the CNG CSP handle that is returned from the NCryptOpenKey function.
///
[FieldOffset(0)]
public NCrypt.NCRYPT_KEY_HANDLE hNCryptKey;
}
///
/// Specifies the encrypted key. The encrypted key is the result of encrypting the content-encryption key. This member is not
/// used when the hNCryptKey member is used.
///
public CertKeySpec dwKeySpec;
/// A pointer to a CMSG_KEY_AGREE_RECIPIENT_INFO structure.
public IntPtr pKeyAgree;
/// Indicates a specific recipient in an array of recipients.
public uint dwRecipientIndex;
/// Indicates a specific encrypted key in an array of encrypted keys.
public uint dwRecipientEncryptedKeyIndex;
/// A CRYPT_BIT_BLOB structure that contains the sender's public key information.
public CRYPTOAPI_BLOB OriginatorPublicKey;
}
/// The CMSG_CTRL_KEY_TRANS_DECRYPT_PARA structure contains information about a key transport message recipient.
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/ns-wincrypt-cmsg_ctrl_key_trans_decrypt_para typedef struct
// _CMSG_CTRL_KEY_TRANS_DECRYPT_PARA { DWORD cbSize; union { HCRYPTPROV hCryptProv; NCRYPT_KEY_HANDLE hNCryptKey; } DUMMYUNIONNAME;
// DWORD dwKeySpec; PCMSG_KEY_TRANS_RECIPIENT_INFO pKeyTrans; DWORD dwRecipientIndex; } CMSG_CTRL_KEY_TRANS_DECRYPT_PARA, *PCMSG_CTRL_KEY_TRANS_DECRYPT_PARA;
[PInvokeData("wincrypt.h", MSDNShortId = "5f3387c9-4ff0-42a0-8fc7-67d3bb8b6bef")]
[StructLayout(LayoutKind.Sequential)]
public struct CMSG_CTRL_KEY_TRANS_DECRYPT_PARA
{
/// The size, in bytes, of this data structure.
public uint cbSize;
///
public CMSG_CTRL_KEY_TRANS_DECRYPT_PARA_HANDLES Handle;
///
[StructLayout(LayoutKind.Explicit)]
public struct CMSG_CTRL_KEY_TRANS_DECRYPT_PARA_HANDLES
{
///
/// A handle to the cryptographic service provider (CSP) used to do the recipient key encryption and export. If NULL,
/// the provider specified in CMSG_ENVELOPED_ENCODE_INFO is used. The CNG function NCryptIsKeyHandle is called to determine
/// the union choice.
///
[FieldOffset(0)]
public HCRYPTPROV hCryptProv;
///
/// A handle to the CNG CSP used to do the recipient key encryption and export. The CNG function NCryptIsKeyHandle is called
/// to determine the union choice. New encrypt algorithms are only supported in CNG functions. The CNG function
/// NCryptTranslateHandle will be called to convert the CryptoAPI CSP hCryptProv choice where necessary. We recommend that
/// applications pass, to the hNCryptKey member, the CNG CSP handle that is returned from the NCryptOpenKey function.
///
[FieldOffset(0)]
public NCrypt.NCRYPT_KEY_HANDLE hNCryptKey;
}
///
/// Specifies the encrypted key. The encrypted key is the result of encrypting the content-encryption key for a specific
/// recipient by using that recipient's public key. This member is not used when the hNCryptKey member is used.
///
public uint dwKeySpec;
/// A pointer to a CMSG_KEY_TRANS_RECIPIENT_INFO structure.
public IntPtr pKeyTrans;
/// Indicates a specific recipient in any array of recipients.
public uint dwRecipientIndex;
}
/// The CMSG_CTRL_MAIL_LIST_DECRYPT_PARA structure contains information on a mail list message recipient.
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/ns-wincrypt-cmsg_ctrl_mail_list_decrypt_para typedef struct
// _CMSG_CTRL_MAIL_LIST_DECRYPT_PARA { DWORD cbSize; HCRYPTPROV hCryptProv; PCMSG_MAIL_LIST_RECIPIENT_INFO pMailList; DWORD
// dwRecipientIndex; DWORD dwKeyChoice; union { HCRYPTKEY hKeyEncryptionKey; void *pvKeyEncryptionKey; } DUMMYUNIONNAME; }
// CMSG_CTRL_MAIL_LIST_DECRYPT_PARA, *PCMSG_CTRL_MAIL_LIST_DECRYPT_PARA;
[PInvokeData("wincrypt.h", MSDNShortId = "30735e01-db6b-40fc-b4c8-cdc24e73defa")]
[StructLayout(LayoutKind.Sequential)]
public struct CMSG_CTRL_MAIL_LIST_DECRYPT_PARA
{
/// The size, in bytes, of this data structure.
public uint cbSize;
///
/// The provider used to do the recipient key encryption and export. If hCryptProv is NULL, the provider specified
/// in CMSG_ENVELOPED_ENCODE_INFO is used.
///
public HCRYPTPROV hCryptProv;
/// A pointer to a CMSG_MAIL_LIST_RECIPIENT_INFO structure.
public IntPtr pMailList;
/// Indicates a specific recipient in any array of recipients.
public uint dwRecipientIndex;
///
/// Indicates the member of the following union that will be used. Currently only CMSG_MAIL_LIST_HANDLE_KEY_CHOICE is defined.
///
public uint dwKeyChoice;
/// Handle of the key encryption key. Used with dwKeyChoice set to CMSG_MAIL_LIST_HANDLE_KEY_CHOICE.
public HCRYPTKEY hKeyEncryptionKey;
}
///
/// The CMSG_CTRL_VERIFY_SIGNATURE_EX_PARA structure contains information used to verify a message signature. It contains the
/// signer index and signer public key. The signer public key can be the signer's CERT_PUBLIC_KEY_INFO structure, certificate
/// context, or chain context.
///
///
/// If dwSignerType is CMSG_VERIFY_SIGNER_NULL, the signature is expected to contain only the unencrypted hash octets.
///
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/ns-wincrypt-cmsg_ctrl_verify_signature_ex_para typedef struct
// _CMSG_CTRL_VERIFY_SIGNATURE_EX_PARA { DWORD cbSize; HCRYPTPROV_LEGACY hCryptProv; DWORD dwSignerIndex; DWORD dwSignerType; void
// *pvSigner; } CMSG_CTRL_VERIFY_SIGNATURE_EX_PARA, *PCMSG_CTRL_VERIFY_SIGNATURE_EX_PARA;
[PInvokeData("wincrypt.h", MSDNShortId = "56b73de8-c170-46f6-b488-096475b59c15")]
[StructLayout(LayoutKind.Sequential)]
public struct CMSG_CTRL_VERIFY_SIGNATURE_EX_PARA
{
/// The size, in bytes, of this structure.
public uint cbSize;
///
/// This member is not used and should be set to NULL.
///
/// Windows Server 2003 and Windows XP: A handle to the cryptographic provider used to verify the signature. If
/// NULL, the cryptographic provider specified in CryptMsgOpenToDecode is used. If the hCryptProv in
/// CryptMsgOpenToDecode is also NULL, the default provider according to the signer's public key object identifier
/// (OID) is used.This member's data type is HCRYPTPROV.
///
///
public HCRYPTPROV hCryptProv;
/// The index of the signer in the message.
public uint dwSignerIndex;
///
///
/// The structure that contains the signer information. The following table shows the predefined values and the structures indicated.
///
///
///
/// Value
/// Meaning
///
/// -
/// CMSG_VERIFY_SIGNER_PUBKEY
/// CERT_PUBLIC_KEY_INFO
///
/// -
/// CMSG_VERIFY_SIGNER_CERT
/// CERT_CONTEXT
///
/// -
/// CMSG_VERIFY_SIGNER_CHAIN
/// CERT_CHAIN_CONTEXT
///
/// -
/// CMSG_VERIFY_SIGNER_NULL
/// NULL
///
///
///
public CryptMsgSignerType dwSignerType;
///
/// A pointer to a CERT_PUBLIC_KEY_INFO structure, a certificate context, a chain context, or NULL depending on the value
/// of dwSignerType.
///
public IntPtr pvSigner;
}
/// The CMSG_KEY_AGREE_RECIPIENT_INFO structure contains information used for key agreement algorithms.
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/ns-wincrypt-cmsg_key_agree_recipient_info typedef struct
// _CMSG_KEY_AGREE_RECIPIENT_INFO { DWORD dwVersion; DWORD dwOriginatorChoice; union { CERT_ID OriginatorCertId;
// CERT_PUBLIC_KEY_INFO OriginatorPublicKeyInfo; } DUMMYUNIONNAME; CRYPT_DATA_BLOB UserKeyingMaterial; CRYPT_ALGORITHM_IDENTIFIER
// KeyEncryptionAlgorithm; DWORD cRecipientEncryptedKeys; PCMSG_RECIPIENT_ENCRYPTED_KEY_INFO *rgpRecipientEncryptedKeys; }
// CMSG_KEY_AGREE_RECIPIENT_INFO, *PCMSG_KEY_AGREE_RECIPIENT_INFO;
[PInvokeData("wincrypt.h", MSDNShortId = "d29d04d6-065e-4bb7-843b-f563643eeb4c")]
[StructLayout(LayoutKind.Sequential)]
public struct CMSG_KEY_AGREE_RECIPIENT_INFO
{
/// A DWORD that indicates the version of the structure. Always set to three.
public uint dwVersion;
/// A DWORD that indicates the key identifier to use.
public CryptMsgKeyOriginator dwOriginatorChoice;
///
public CMSG_KEY_AGREE_RECIPIENT_INFO_UNION Originator;
///
[StructLayout(LayoutKind.Explicit)]
public struct CMSG_KEY_AGREE_RECIPIENT_INFO_UNION
{
/// A CERT_ID that identifies the public key of the message originator.
[FieldOffset(0)]
public CERT_ID OriginatorCertId;
/// A CERT_PUBLIC_KEY_INFO structure that contains the public key of the message originator.
[FieldOffset(0)]
public CERT_PUBLIC_KEY_INFO OriginatorPublicKeyInfo;
}
///
/// A CRYPT_DATA_BLOB that indicates that a different key is generated each time the same two parties generate a pair of keys.
/// The sender provides the bits of this BLOB with some key agreement algorithms. This member can be NULL.
///
public CRYPTOAPI_BLOB UserKeyingMaterial;
///
/// A CRYPT_ALGORITHM_IDENTIFIER that identifies the key-encryption algorithm and any associated parameters used to encrypt the
/// content encryption key.
///
public CRYPT_ALGORITHM_IDENTIFIER KeyEncryptionAlgorithm;
/// The number of elements in the rgpRecipientEncryptedKeys array.
public uint cRecipientEncryptedKeys;
///
/// The address of an array of CMSG_RECIPIENT_ENCRYPTED_KEY_INFO structures that contains information about the key recipients.
/// The cRecipientEncryptedKeys member contains the number of elements in this array.
///
public IntPtr rgpRecipientEncryptedKeys;
}
/// The CMSG_KEY_TRANS_RECIPIENT_INFO structure contains information used in key transport algorithms.
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/ns-wincrypt-cmsg_key_trans_recipient_info typedef struct
// _CMSG_KEY_TRANS_RECIPIENT_INFO { DWORD dwVersion; CERT_ID RecipientId; CRYPT_ALGORITHM_IDENTIFIER KeyEncryptionAlgorithm;
// CRYPT_DATA_BLOB EncryptedKey; } CMSG_KEY_TRANS_RECIPIENT_INFO, *PCMSG_KEY_TRANS_RECIPIENT_INFO;
[PInvokeData("wincrypt.h", MSDNShortId = "956b0646-50a5-46d1-aa9a-91194c35d2b2")]
[StructLayout(LayoutKind.Sequential)]
public struct CMSG_KEY_TRANS_RECIPIENT_INFO
{
///
/// Indicates the version of the structure. If RecipientId uses the ISSUER_SERIAL_NUMBER to identify the recipient,
/// dwVersion is set to zero. If RecipientId uses KEYID, dwVersion is set to two.
///
public uint dwVersion;
///
/// A CERT_ID that identifies the recipient. Currently, only ISSUER_SERIAL_NUMBER or KEYID choices in the CERT_ID are valid.
///
public CERT_ID RecipientId;
///
/// A CRYPT_ALGORITHM_IDENTIFIER that identifies the key-encryption algorithm and any associated parameters used to encrypt the
/// content encryption key.
///
public CRYPT_ALGORITHM_IDENTIFIER KeyEncryptionAlgorithm;
/// A CRYPT_DATA_BLOB that contains the bytes of the encrypted session key.
public CRYPTOAPI_BLOB EncryptedKey;
}
///
/// The CMSG_MAIL_LIST_RECIPIENT_INFO structure contains information used for previously distributed symmetric key-encryption
/// keys (KEK).
///
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/ns-wincrypt-cmsg_mail_list_recipient_info typedef struct
// _CMSG_MAIL_LIST_RECIPIENT_INFO { DWORD dwVersion; CRYPT_DATA_BLOB KeyId; CRYPT_ALGORITHM_IDENTIFIER KeyEncryptionAlgorithm;
// CRYPT_DATA_BLOB EncryptedKey; FILETIME Date; PCRYPT_ATTRIBUTE_TYPE_VALUE pOtherAttr; } CMSG_MAIL_LIST_RECIPIENT_INFO, *PCMSG_MAIL_LIST_RECIPIENT_INFO;
[PInvokeData("wincrypt.h", MSDNShortId = "e0946278-75e9-4990-af81-d9e61da9724b")]
[StructLayout(LayoutKind.Sequential)]
public struct CMSG_MAIL_LIST_RECIPIENT_INFO
{
/// Indicates the version of the structure. This member is always four.
public uint dwVersion;
///
/// A CRYPT_DATA_BLOB structure that identifies a symmetric key-encryption key previously distributed to the sender and one or
/// more recipients.
///
public CRYPTOAPI_BLOB KeyId;
///
/// CRYPT_ALGORITHM_IDENTIFIER that identifies the key-encryption algorithm and any associated parameters used to encrypt the
/// content encryption key.
///
public CRYPT_ALGORITHM_IDENTIFIER KeyEncryptionAlgorithm;
/// A CRYPT_DATA_BLOB structure that contains the encrypted content encryption key.
public CRYPTOAPI_BLOB EncryptedKey;
/// Optional. When present, this member specifies a single key-encryption key from a previously distributed set.
public FILETIME Date;
/// Optional pointer to a CRYPT_ATTRIBUTE_TYPE_VALUE structure containing additional information.
public IntPtr pOtherAttr;
}
///
/// The CMSG_RECIPIENT_ENCRYPTED_KEY_INFO structure contains information used for an individual key agreement recipient.
///
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/ns-wincrypt-cmsg_recipient_encrypted_key_info typedef struct
// _CMSG_RECIPIENT_ENCRYPTED_KEY_INFO { CERT_ID RecipientId; CRYPT_DATA_BLOB EncryptedKey; FILETIME Date;
// PCRYPT_ATTRIBUTE_TYPE_VALUE pOtherAttr; } CMSG_RECIPIENT_ENCRYPTED_KEY_INFO, *PCMSG_RECIPIENT_ENCRYPTED_KEY_INFO;
[PInvokeData("wincrypt.h", MSDNShortId = "1921f9b6-86d9-47a0-a36e-e20d481382a3")]
[StructLayout(LayoutKind.Sequential)]
public struct CMSG_RECIPIENT_ENCRYPTED_KEY_INFO
{
///
/// CERT_ID structure identifying the recipient. Currently, only the ISSUER_SERIAL_NUMBER or KEYID choices in the CERT_ID
/// structure are valid.
///
public CERT_ID RecipientId;
/// A CRYPT_DATA_BLOB structure that contains the encrypted content encryption key.
public CRYPTOAPI_BLOB EncryptedKey;
///
/// Optional. When present, this member specifies which of the recipient's previously distributed UKMs was used by the sender.
/// Only applicable to KEYID choice in the RecipientId CERT_ID structure.
///
public FILETIME Date;
///
/// Optional pointer to a CRYPT_ATTRIBUTE_TYPE_VALUE structure containing additional information. Only applicable to KEYID
/// choice in the RecipientId CERT_ID structure.
///
public IntPtr pOtherAttr;
}
///
/// The CMSG_SIGNER_ENCODE_INFO structure contains signer information. It is passed to CryptMsgCountersign,
/// CryptMsgCountersignEncoded, and optionally to CryptMsgOpenToEncode as a member of the CMSG_SIGNED_ENCODE_INFO structure, if the
/// dwMsgType parameter is CMSG_SIGNED.
///
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/ns-wincrypt-cmsg_signer_encode_info typedef struct
// _CMSG_SIGNER_ENCODE_INFO { DWORD cbSize; PCERT_INFO pCertInfo; union { HCRYPTPROV hCryptProv; NCRYPT_KEY_HANDLE hNCryptKey;
// BCRYPT_KEY_HANDLE hBCryptKey; } DUMMYUNIONNAME; DWORD dwKeySpec; CRYPT_ALGORITHM_IDENTIFIER HashAlgorithm; void *pvHashAuxInfo;
// DWORD cAuthAttr; PCRYPT_ATTRIBUTE rgAuthAttr; DWORD cUnauthAttr; PCRYPT_ATTRIBUTE rgUnauthAttr; CERT_ID SignerId;
// CRYPT_ALGORITHM_IDENTIFIER HashEncryptionAlgorithm; void *pvHashEncryptionAuxInfo; } CMSG_SIGNER_ENCODE_INFO, *PCMSG_SIGNER_ENCODE_INFO;
[PInvokeData("wincrypt.h", MSDNShortId = "f599226d-ddd7-455f-b650-74b91674d8f9")]
[StructLayout(LayoutKind.Sequential)]
public struct CMSG_SIGNER_ENCODE_INFO
{
/// The size, in bytes, of this structure.
public uint cbSize;
///
/// A pointer to a CERT_INFO structure that contains the
/// Issuer, SerialNumber, and SubjectPublicKeyInfo members.
///
/// The pbData members of the Issuer and SerialNumber structures combined uniquely identify a certificate.
/// The Algorithm member of the SubjectPublicKeyInfo structure specifies the hash encryption algorithm used.
///
///
public IntPtr pCertInfo;
///
public CMSG_SIGNER_ENCODE_INFO_HANDLES Handle;
///
[StructLayout(LayoutKind.Explicit)]
public struct CMSG_SIGNER_ENCODE_INFO_HANDLES
{
///
/// A handle to the cryptographic service provider (CSP). If HashEncryptionAlgorithm is set to
/// szOID_PKIX_NO_SIGNATURE, this handle can be the handle of a CSP acquired by using the dwFlags parameter set to
/// CRYPT_VERIFYCONTEXT. The CNG function NCryptIsKeyHandle is called to determine the union choice.
///
[FieldOffset(0)]
public HCRYPTPROV hCryptProv;
///
/// A handle to the CNG CSP. The CNG function NCryptIsKeyHandle is called to determine the union choice. New encrypt
/// algorithms are only supported in CNG functions. The CNG function NCryptTranslateHandle will be called to convert the
/// CryptoAPI hCryptProv choice where necessary. We recommend that applications pass, to the hNCryptKey member, the CNG CSP
/// handle that is returned from the NCryptOpenKey function.
///
[FieldOffset(0)]
public NCrypt.NCRYPT_KEY_HANDLE hNCryptKey;
///
[FieldOffset(0)]
public BCrypt.BCRYPT_KEY_HANDLE hBCryptKey;
}
///
/// Specifies the private key to be used. This member is not used when the hNCryptKey member is used.
/// If dwKeySpec is zero, then the default AT_KEYEXCHANGE value is used.
/// The following dwKeySpec values are defined for the default provider.
///
///
/// Value
/// Meaning
///
/// -
/// AT_KEYEXCHANGE
/// Keys used to encrypt/decrypt session keys.
///
/// -
/// AT_SIGNATURE
/// Keys used to create and verify digital signatures.
///
///
///
public CertKeySpec dwKeySpec;
/// A CRYPT_ALGORITHM_IDENTIFIER structure that specifies the hash algorithm.
public CRYPT_ALGORITHM_IDENTIFIER HashAlgorithm;
/// Not used. This member must be set to NULL.
public IntPtr pvHashAuxInfo;
///
/// The number of elements in the rgAuthAttr array. If no authenticated attributes are present in rgAuthAttr, then
/// cAuthAttr is zero.
///
public uint cAuthAttr;
///
/// An array of pointers to CRYPT_ATTRIBUTE structures, each of which contains authenticated attribute information.
///
/// The PKCS #9 standard dictates that if there are any attributes, there must be at least two: the content type object
/// identifier (OID) and the hash of the message. These attributes are automatically added by the system.
///
///
public IntPtr rgAuthAttr;
///
/// The number of elements in the rgUnauthAttr array. If there are no unauthenticated attributes, cUnauthAttr is zero.
///
public uint cUnauthAttr;
///
/// An array of pointers to CRYPT_ATTRIBUTE structures, each of which contains unauthenticated attribute information.
/// Unauthenticated attributes can contain countersignatures, among other uses.
///
public IntPtr rgUnauthAttr;
///
/// A CERT_ID structure that contains a unique identifier of the signer's certificate. This member can optionally be used with
/// PKCS #7 with Cryptographic Message Syntax (CMS). If this member is not NULL and its dwIdChoice member is not
/// zero, it is used to identify the certificate instead of the Issuer and SerialNumber members of the CERT_INFO
/// structure pointed to by pCertInfo. CMS supports the KEY_IDENTIFIER and ISSUER_SERIAL_NUMBER CERT_ID structures. PKCS
/// version 1.5 supports only the ISSUER_SERIAL_NUMBER CERT_ID choice. This member is used with CMS for PKCS #7 processing and
/// can be used only if CMSG_SIGNER_ENCODE_INFO_HAS_CMS_FIELDS is defined.
///
public CERT_ID SignerId;
///
///
/// A CRYPT_ALGORITHM_IDENTIFIER structure optionally used with PKCS #7 with CMS. If this member is not NULL, the
/// algorithm identified is used instead of the SubjectPublicKeyInfo.Algorithm algorithm. If this member is set to
/// szOID_PKIX_NO_SIGNATURE, the signature value contains only the hash octets.
///
///
/// For RSA, the hash encryption algorithm is normally the same as the public key algorithm. For DSA, the hash encryption
/// algorithm is normally a DSS signature algorithm.
///
///
/// This member is used with CMS for PKCS #7 processing and can be used only if CMSG_SIGNER_ENCODE_INFO_HAS_CMS_FIELDS is defined.
///
///
public CRYPT_ALGORITHM_IDENTIFIER HashEncryptionAlgorithm;
///
/// This member is not used. This member must be set to NULL if it is present in the data structure. This member is
/// present only if CMSG_SIGNER_ENCODE_INFO_HAS_CMS_FIELDS is defined.
///
public IntPtr pvHashEncryptionAuxInfo;
}
///
/// The CMSG_SIGNER_INFO structure contains the content of the PKCS #7 defined SignerInfo in signed messages. In decoding a
/// received message, CryptMsgGetParam is called for each signer to get a CMSG_SIGNER_INFO structure.
///
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/ns-wincrypt-cmsg_signer_info typedef struct _CMSG_SIGNER_INFO { DWORD
// dwVersion; CERT_NAME_BLOB Issuer; CRYPT_INTEGER_BLOB SerialNumber; CRYPT_ALGORITHM_IDENTIFIER HashAlgorithm;
// CRYPT_ALGORITHM_IDENTIFIER HashEncryptionAlgorithm; CRYPT_DATA_BLOB EncryptedHash; CRYPT_ATTRIBUTES AuthAttrs; CRYPT_ATTRIBUTES
// UnauthAttrs; } CMSG_SIGNER_INFO, *PCMSG_SIGNER_INFO;
[PInvokeData("wincrypt.h", MSDNShortId = "NS:wincrypt._CMSG_SIGNER_INFO")]
[StructLayout(LayoutKind.Sequential)]
public struct CMSG_SIGNER_INFO
{
/// The version of this structure.
public uint dwVersion;
/// A CERT_NAME_BLOB structure that contains the issuer of a certificate with the public key needed to verify a signature.
public CRYPTOAPI_BLOB Issuer;
///
/// A CRYPT_INTEGER_BLOB structure that contains the serial number of the certificate that contains the public key needed to
/// verify a signature. For more information, see CERT_INFO.
///
public CRYPTOAPI_BLOB SerialNumber;
/// CRYPT_ALGORITHM_IDENTIFIER structure specifying the algorithm used in generating the hash of a message.
public CRYPT_ALGORITHM_IDENTIFIER HashAlgorithm;
/// CRYPT_ALGORITHM_IDENTIFIER structure specifying the algorithm used to encrypt the hash.
public CRYPT_ALGORITHM_IDENTIFIER HashEncryptionAlgorithm;
/// A CRYPT_DATA_BLOB that contains the encrypted hash of the message, the signature.
public CRYPTOAPI_BLOB EncryptedHash;
/// CRYPT_ATTRIBUTES structure containing authenticated attributes of the signer.
public CRYPT_ATTRIBUTES AuthAttrs;
/// CRYPT_ATTRIBUTES structure containing unauthenticated attributes of the signer.
public CRYPT_ATTRIBUTES UnauthAttrs;
}
///
///
/// The CMSG_STREAM_INFO structure is used to enable stream processing of data rather than single block processing. Stream
/// processing is most often used when processing large messages. Stream-processed messages can originate from any serialized source
/// such as a file on a hard disk, a server, or a CD ROM.
///
/// This structure is passed to the CryptMsgOpenToEncode and CryptMsgOpenToDecode functions.
///
///
///
/// Messages can be so large that processing them all at once by storing the whole message in memory can be difficult, if not
/// impossible. It is possible to process large messages without encountering memory limitations by streaming the data that is to be
/// processed into manageable sized blocks. The low-level message functions can be used with streaming to encode or decode a
/// message. Any level of nesting of messages is supported when streaming to encode and streaming to decode.
///
///
/// The input message to be processed as a stream feeds into CryptMsgUpdate one block at a time, with the application determining
/// the size of the block. As the streamed message is processed for encoding or decoding, the resulting output data is passed back
/// to the application through an application-specified callback function that is specified by the pfnStreamOutput member.
///
///
/// No assumptions can be made about the block size of the output data because the size can vary for several reasons, such as the
/// jitter in output block size caused by the block size for the encryption algorithm when processing an enveloped message, or when
/// blocks that contain the message header and the SignerInfo as defined by PKCS # 7 are processed.
///
///
/// The size of the output block is passed to the callback function in its cbData parameter. The use of output data is determined in
/// the calling application. Typically, output from stream processing will not be persisted in memory as a whole due to memory
/// limitations; rather, it will be serialized to a disk or server file.
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/ns-wincrypt-cmsg_stream_info typedef struct _CMSG_STREAM_INFO { DWORD
// cbContent; PFN_CMSG_STREAM_OUTPUT pfnStreamOutput; void *pvArg; } CMSG_STREAM_INFO, *PCMSG_STREAM_INFO;
[PInvokeData("wincrypt.h", MSDNShortId = "a4e7f6e8-351f-4981-b223-50b65f503394")]
[StructLayout(LayoutKind.Sequential)]
public struct CMSG_STREAM_INFO
{
///
/// Specifies the size, in bytes, of the content. Normal Distinguished Encoding Rules (DER) encoding is used unless
/// CMSG_INDEFINITE_LENGTH(0xFFFFFFFF) is passed, indicating that the application is not specifying the content length.
/// This forces the use of indefinite-length Basic Encoding Rules (BER) encoding.
///
public uint cbContent;
///
/// The address of a callback function used to read from and write data to a disk when processing large messages.
/// The callback function must have the following signature and parameters:
///
public PFN_CMSG_STREAM_OUTPUT pfnStreamOutput;
///
/// A pointer to the argument to pass to the callback function. Typically, this is used for state data that includes the handle
/// to a more deeply nested message (when decoding) or a less deeply nested message (when encoding).
///
public IntPtr pvArg;
}
/// The CRYPT_DECRYPT_MESSAGE_PARA structure contains information for decrypting messages.
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/ns-wincrypt-crypt_decrypt_message_para typedef struct
// _CRYPT_DECRYPT_MESSAGE_PARA { DWORD cbSize; DWORD dwMsgAndCertEncodingType; DWORD cCertStore; HCERTSTORE *rghCertStore; DWORD
// dwFlags; } CRYPT_DECRYPT_MESSAGE_PARA, *PCRYPT_DECRYPT_MESSAGE_PARA;
[PInvokeData("wincrypt.h", MSDNShortId = "67e136cd-12e3-4a31-9d8b-b53e1129e940")]
[StructLayout(LayoutKind.Sequential)]
public struct CRYPT_DECRYPT_MESSAGE_PARA
{
/// Size of this structure in bytes.
public uint cbSize;
///
///
/// Type of encoding used. 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:
///
/// X509_ASN_ENCODING | PKCS_7_ASN_ENCODING
/// Currently defined encoding types are:
///
/// -
/// X509_ASN_ENCODING
///
/// -
/// PKCS_7_ASN_ENCODING
///
///
///
public CertEncodingType dwMsgAndCertEncodingType;
/// Number of elements in the rghCertStore array.
public uint cCertStore;
///
/// Array of certificate store handles.
///
/// These certificate store handles are used to obtain the certificate context to use for decrypting a message. For more
/// information, see the decryption functions CryptDecryptMessage, and CryptDecryptAndVerifyMessageSignature. An encrypted
/// message can have one or more recipients. The recipients are identified by a unique certificate identifier, often the hash of
/// the certificate issuer and serial number. The certificate stores are searched to find a certificate context corresponding to
/// the unique identifier.
///
///
/// Recipients can also be identified by their KeyId. Both Key Agreement (Diffie-Hellman) and Key Transport (RSA) recipients are supported.
///
///
/// Only certificate contexts in the store with one of the following properties, CERT_KEY_PROV_INFO_PROP_ID, or
/// CERT_KEY_CONTEXT_PROP_ID can be used. These properties specify the location of a needed private exchange key.
///
///
public IntPtr rghCertStore;
///
/// The CRYPT_MESSAGE_SILENT_KEYSET_FLAG can be set to suppress any UI by the CSP. For more information about the CRYPT_SILENT
/// flag, see CryptAcquireContext.
///
public CryptMsgActionFlags dwFlags;
}
/// The CRYPT_ENCRYPT_MESSAGE_PARA structure contains information used to encrypt messages.
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/ns-wincrypt-crypt_encrypt_message_para typedef struct
// _CRYPT_ENCRYPT_MESSAGE_PARA { DWORD cbSize; DWORD dwMsgEncodingType; HCRYPTPROV_LEGACY hCryptProv; CRYPT_ALGORITHM_IDENTIFIER
// ContentEncryptionAlgorithm; void *pvEncryptionAuxInfo; DWORD dwFlags; DWORD dwInnerContentType; } CRYPT_ENCRYPT_MESSAGE_PARA, *PCRYPT_ENCRYPT_MESSAGE_PARA;
[PInvokeData("wincrypt.h", MSDNShortId = "c683c515-3061-48e3-a64a-2798bd1245b0")]
[StructLayout(LayoutKind.Sequential)]
public struct CRYPT_ENCRYPT_MESSAGE_PARA
{
/// The size, in bytes, of this structure.
public uint cbSize;
///
///
/// The type of encoding used. 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:
///
/// X509_ASN_ENCODING | PKCS_7_ASN_ENCODING
/// Currently defined encoding types are:
///
/// -
/// X509_ASN_ENCODING
///
/// -
/// PKCS_7_ASN_ENCODING
///
///
///
public CertEncodingType dwMsgEncodingType;
///
/// This member is not used and should be set to NULL.
///
/// Windows Server 2003 and Windows XP: The handle to the cryptographic service provider (CSP) to be used for encryption.
/// The CSP identified by hCryptProv is used to do content encryption, recipient key encryption, and recipient key
/// export. Its private key is not used.
///
///
/// Unless there is a strong reason for passing in a specific cryptographic provider in hCryptProv, pass zero to use the
/// default RSA or DSS provider.
///
/// This member's data type is HCRYPTPROV.
///
public HCRYPTPROV hCryptProv;
///
///
/// A CRYPT_ALGORITHM_IDENTIFIER structure that contains the object identifier (OID) of the encryption algorithm to use. The CSP
/// specified by the hCryptProv must support this encryption algorithm.
///
///
/// The szOID_OIWSEC_desCBC (CALG_DES) and szOID_RSA_DES_EDE3_CBC (CALG_3DES) encryption algorithms require the
/// Parameters member of this structure to contain an encoded eight-byte initialization vector (IV). If the cbData
/// member of the Parameters member is zero, an Abstract Syntax Notation One (ASN.1)-encoded OCTET STRING that contains
/// the IV is generated using CryptGenRandom. For more information about the KP_IV parameter, see CryptSetKeyParam.
///
///
/// The szOID_NIST_AES128_CBC (BCRYPT_AES_ALGORITHM, 128 bit), szOID_NIST_AES192_CBC (BCRYPT_AES_ALGORITHM, 192
/// bit), and szOID_NIST_AES256_CBC (BCRYPT_AES_ALGORITHM, 256 bit) encryption algorithms require the Parameters
/// member of this structure to contain an encoded sixteen-byte initialization vector (IV). If the cbData member of the
/// Parameters member is zero, an Abstract Syntax Notation One (ASN.1)-encoded OCTET STRING that contains the IV is generated.
///
///
/// The szOID_RSA_RC2CBC (CALG_RC2) algorithm requires the pbData member of the Parameters member of this
/// structure to be a CRYPT_RC2_CBC_PARAMETERS structure. If the cbData member of the Parameters member is zero,
/// an ASN.1-encoded CRYPT_RC2_CBC_PARAMETERS structure that contains the IV is generated as the pbData member.
/// This generated pbData uses the default dwVersion that corresponds to the 40-bit key length. To override the
/// default 40-bit key length, pvEncryptionAuxInfo can be set to point to a CMSG_RC2_AUX_INFO structure that contains a
/// key bit length.
///
///
/// Note When a message is decrypted, if it has an initialization vector parameter, the cryptographic message functions
/// call CryptSetKeyParam with the initialization vector before decrypting.
///
///
public CRYPT_ALGORITHM_IDENTIFIER ContentEncryptionAlgorithm;
///
///
/// A pointer to a CMSG_RC2_AUX_INFO structure for RC2 encryption or a CMSG_SP3_COMPATIBLE_AUX_INFO structure for SP3-compatible
/// encryption. For other than RC2 or SP3-compatible encryption, this member must be set to NULL.
///
///
/// If the ContentEncryptionAlgorithm member contains szOID_RSA_RC4, this member points to a CMSG_RC4_AUX_INFO
/// structure that specifies the number of salt bytes to be included.
///
///
public IntPtr pvEncryptionAuxInfo;
///
///
/// Normally set to zero. However, if the encoded output is to be a CMSG_ENVELOPED inner content of an outer cryptographic
/// message, such as a CMSG_SIGNED message, the CRYPT_MESSAGE_BARE_CONTENT_OUT_FLAG must be set. If it is not set, content will
/// be encoded as an inner content type of CMSG_DATA.
///
///
/// CRYPT_MESSAGE_ENCAPSULATED_CONTENT_OUT_FLAG can be set to encapsulate non-data inner content within an OCTET STRING before encrypting.
///
///
/// CRYPT_MESSAGE_KEYID_RECIPIENT_FLAG can be set to identify recipients by their Key Identifier and not their Issuer and Serial Number.
///
///
public CryptMsgActionFlags dwFlags;
///
/// Normally set to zero. The dwInnerContentType member must be set to set the cryptographic message types if the input
/// to be encrypted is the encoded output of another cryptographic message such as CMSG_SIGNED.
///
public CryptMsgType dwInnerContentType;
}
/// The CRYPT_HASH_MESSAGE_PARA structure contains data for hashing messages.
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/ns-wincrypt-crypt_hash_message_para typedef struct
// _CRYPT_HASH_MESSAGE_PARA { DWORD cbSize; DWORD dwMsgEncodingType; HCRYPTPROV_LEGACY hCryptProv; CRYPT_ALGORITHM_IDENTIFIER
// HashAlgorithm; void *pvHashAuxInfo; } CRYPT_HASH_MESSAGE_PARA, *PCRYPT_HASH_MESSAGE_PARA;
[PInvokeData("wincrypt.h", MSDNShortId = "60415136-3ac0-4fab-bdbf-faa16e8e43e1")]
[StructLayout(LayoutKind.Sequential)]
public struct CRYPT_HASH_MESSAGE_PARA
{
/// Size of this structure in bytes.
public uint cbSize;
///
///
/// Type of encoding used. 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:
///
/// X509_ASN_ENCODING | PKCS_7_ASN_ENCODING
/// Currently defined encoding types are:
///
/// -
/// X509_ASN_ENCODING
///
/// -
/// PKCS_7_ASN_ENCODING
///
///
///
public CertEncodingType dwMsgEncodingType;
///
/// This member is not used and should be set to NULL.
///
/// Windows Server 2003 and Windows XP: A handle to the cryptographic service provider (CSP) to be used.Unless there is a
/// strong reason for passing in a specific cryptographic provider in hCryptProv, pass zero to use the default RSA or DSS provider.
///
/// This member's data type is HCRYPTPROV.
///
public HCRYPTPROV hCryptProv;
/// CRYPT_ALGORITHM_IDENTIFIER containing the algorithm for generating the hash of the message.
public CRYPT_ALGORITHM_IDENTIFIER HashAlgorithm;
/// Not currently used, and must be set to NULL.
public IntPtr pvHashAuxInfo;
}
///
/// The CRYPT_KEY_SIGN_MESSAGE_PARA structure contains information about the cryptographic service provider (CSP) and
/// algorithms used to sign a message.
///
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/ns-wincrypt-crypt_key_sign_message_para typedef struct
// _CRYPT_KEY_SIGN_MESSAGE_PARA { DWORD cbSize; DWORD dwMsgAndCertEncodingType; union { HCRYPTPROV hCryptProv; NCRYPT_KEY_HANDLE
// hNCryptKey; } DUMMYUNIONNAME; DWORD dwKeySpec; CRYPT_ALGORITHM_IDENTIFIER HashAlgorithm; void *pvHashAuxInfo;
// CRYPT_ALGORITHM_IDENTIFIER PubKeyAlgorithm; } CRYPT_KEY_SIGN_MESSAGE_PARA, *PCRYPT_KEY_SIGN_MESSAGE_PARA;
[PInvokeData("wincrypt.h", MSDNShortId = "d5426ad6-2181-42ce-99f2-cc6cc83e20a8")]
[StructLayout(LayoutKind.Sequential)]
public struct CRYPT_KEY_SIGN_MESSAGE_PARA
{
/// The size, in bytes, of this data structure.
public uint cbSize;
///
///
/// Specifies the type of message and certificate encoding used. This can be a combination of one or more of the following values.
///
///
///
/// Value
/// Meaning
///
/// -
/// X509_ASN_ENCODING
/// Specifies X.509 certificate encoding.
///
/// -
/// PKCS_7_ASN_ENCODING
/// Specifies PKCS 7 message encoding.
///
///
///
public CertEncodingType dwMsgAndCertEncodingType;
///
public CRYPT_KEY_SIGN_MESSAGE_PARA_HANDLE Handle;
///
[StructLayout(LayoutKind.Explicit)]
public struct CRYPT_KEY_SIGN_MESSAGE_PARA_HANDLE
{
///
/// The handle of the CSP to use to sign the message. The CryptAcquireContext function is called to obtain this handle.
///
[FieldOffset(0)]
public HCRYPTPROV hCryptProv;
///
/// The handle of the Cryptography API: Next Generation (CNG) CSP to use to sign the message. CNG signature algorithms are
/// only supported in CNG functions.
///
[FieldOffset(0)]
public NCrypt.NCRYPT_KEY_HANDLE hNCryptKey;
}
///
///
/// Identifies the type of private key to use to sign the message. This must be one of the following values. This member is
/// ignored if a CNG key is passed in the hNCryptKey member.
///
///
///
/// Value
/// Meaning
///
/// -
/// AT_KEYEXCHANGE
/// Use the key exchange key.
///
/// -
/// AT_SIGNATURE
/// Use the digital signature key.
///
///
///
public CertKeySpec dwKeySpec;
///
/// A CRYPT_ALGORITHM_IDENTIFIER structure that specifies the algorithm to use to generate the hash of the message. This must be
/// a hash algorithm.
///
public CRYPT_ALGORITHM_IDENTIFIER HashAlgorithm;
/// This member is not used and must be set to NULL.
public IntPtr pvHashAuxInfo;
///
/// A CRYPT_ALGORITHM_IDENTIFIER structure that specifies the algorithm to use to sign the message. This must be either a public
/// key or a signature algorithm.
///
public CRYPT_ALGORITHM_IDENTIFIER PubKeyAlgorithm;
}
///
/// The CRYPT_KEY_VERIFY_MESSAGE_PARA structure contains information needed to verify signed messages without a certificate
/// for the signer.
///
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/ns-wincrypt-crypt_key_verify_message_para typedef struct
// _CRYPT_KEY_VERIFY_MESSAGE_PARA { DWORD cbSize; DWORD dwMsgEncodingType; HCRYPTPROV_LEGACY hCryptProv; }
// CRYPT_KEY_VERIFY_MESSAGE_PARA, *PCRYPT_KEY_VERIFY_MESSAGE_PARA;
[PInvokeData("wincrypt.h", MSDNShortId = "4e0178fb-1f9f-4ee4-9a83-f37cf71d35ff")]
[StructLayout(LayoutKind.Sequential)]
public struct CRYPT_KEY_VERIFY_MESSAGE_PARA
{
/// The size, in bytes, of this structure.
public uint cbSize;
///
///
/// Type of encoding used. 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:
///
/// X509_ASN_ENCODING | PKCS_7_ASN_ENCODING
/// Currently defined encoding types are:
///
/// -
/// X509_ASN_ENCODING
///
/// -
/// PKCS_7_ASN_ENCODING
///
///
///
public CertEncodingType dwMsgEncodingType;
///
/// This member is not used and should be set to NULL.
///
/// Windows Server 2003 and Windows XP: A handle to the cryptographic service provider (CSP) to be used to verify a
/// signed message. The CSP identified by this handle is used for hashing and for signature verification.Unless there is a
/// strong reason for using a specific cryptographic provider, set this member to zero to use the default RSA or DSS provider.
///
/// This member's data type is HCRYPTPROV.
///
public HCRYPTPROV hCryptProv;
}
///
/// The CRYPT_SIGN_MESSAGE_PARA structure contains information for signing messages using a specified signing certificate context.
///
///
/// The HashEncryptionAlgorithm and pvHashEncryptionAuxInfo members can only be used if
/// CRYPT_SIGN_MESSAGE_PARA_HAS_CMS_FIELDS is defined.
///
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/ns-wincrypt-crypt_sign_message_para typedef struct
// _CRYPT_SIGN_MESSAGE_PARA { DWORD cbSize; DWORD dwMsgEncodingType; PCCERT_CONTEXT pSigningCert; CRYPT_ALGORITHM_IDENTIFIER
// HashAlgorithm; void *pvHashAuxInfo; DWORD cMsgCert; PCCERT_CONTEXT *rgpMsgCert; DWORD cMsgCrl; PCCRL_CONTEXT *rgpMsgCrl; DWORD
// cAuthAttr; PCRYPT_ATTRIBUTE rgAuthAttr; DWORD cUnauthAttr; PCRYPT_ATTRIBUTE rgUnauthAttr; DWORD dwFlags; DWORD
// dwInnerContentType; CRYPT_ALGORITHM_IDENTIFIER HashEncryptionAlgorithm; void *pvHashEncryptionAuxInfo; } CRYPT_SIGN_MESSAGE_PARA, *PCRYPT_SIGN_MESSAGE_PARA;
[PInvokeData("wincrypt.h", MSDNShortId = "1601d860-6054-4650-a033-ea088655b7e4")]
[StructLayout(LayoutKind.Sequential)]
public struct CRYPT_SIGN_MESSAGE_PARA
{
/// Size of this structure in bytes.
public uint cbSize;
///
///
/// Type of encoding used. 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:
///
/// X509_ASN_ENCODING | PKCS_7_ASN_ENCODING
/// Currently defined encoding types are:
///
/// -
/// X509_ASN_ENCODING
///
/// -
/// PKCS_7_ASN_ENCODING
///
///
///
public CertEncodingType dwMsgEncodingType;
///
/// A pointer to the CERT_CONTEXT to be used in the signing.
///
/// Either the CERT_KEY_PROV_INFO_PROP_ID, or CERT_KEY_CONTEXT_PROP_ID property must be set for the context to provide access to
/// the private signature key.
///
///
public PCCERT_CONTEXT pSigningCert;
/// CRYPT_ALGORITHM_IDENTIFIER containing the hashing algorithm used to hash the data to be signed.
public CRYPT_ALGORITHM_IDENTIFIER HashAlgorithm;
/// Not currently used, and must be set to NULL.
public IntPtr pvHashAuxInfo;
///
/// Number of elements in the rgpMsgCert array of CERT_CONTEXT structures. If set to zero no certificates are included in
/// the signed message.
///
public uint cMsgCert;
///
/// Array of pointers to CERT_CONTEXT structures to be included in the signed message. If the pSigningCert is to be
/// included, a pointer to it must be in the rgpMsgCert array.
///
public IntPtr rgpMsgCert;
///
/// Number of elements in the rgpMsgCrl array of pointers to CRL_CONTEXT structures. If set to zero, no
/// CRL_CONTEXT structures are included in the signed message.
///
public uint cMsgCrl;
/// Array of pointers to CRL_CONTEXT structures to be included in the signed message.
public IntPtr rgpMsgCrl;
///
/// Number of elements in the rgAuthAttr array. If no authenticated attributes are present in rgAuthAttr, this
/// member is set to zero.
///
public uint cAuthAttr;
///
/// Array of pointers to CRYPT_ATTRIBUTE structures, each holding authenticated attribute information. If there are
/// authenticated attributes present, the PKCS #9 standard dictates that there must be at least two attributes present, the
/// content type object identifier (OID), and the hash of the message itself. These attributes are automatically added by the system.
///
public IntPtr rgAuthAttr;
///
/// Number of elements in the rgUnauthAttr array. If no unauthenticated attributes are present in rgUnauthAttr,
/// this member is zero.
///
public uint cUnauthAttr;
///
/// Array of pointers to CRYPT_ATTRIBUTE structures each holding an unauthenticated attribute information. Unauthenticated
/// attributes can be used to contain countersignatures, among other uses.
///
public IntPtr rgUnauthAttr;
///
///
/// Normally zero. If the encoded output is to be a CMSG_SIGNED inner content of an outer cryptographic message such as a
/// CMSG_ENVELOPED message, the CRYPT_MESSAGE_BARE_CONTENT_OUT_FLAG must be set. If it is not set, the message will be encoded
/// as an inner content type of CMSG_DATA.
///
///
/// CRYPT_MESSAGE_ENCAPSULATED_CONTENT_OUT_FLAG can be set to encapsulate non-data inner content into an OCTET STRING.
/// CRYPT_MESSAGE_KEYID_SIGNER_FLAG can be set to identify signers by their Key Identifier and not their Issuer and Serial Number.
///
///
/// CRYPT_MESSAGE_SILENT_KEYSET_FLAG can be set to suppress any UI by the CSP. For more information about the CRYPT_SILENT flag,
/// see CryptAcquireContext.
///
///
public CryptMsgActionFlags dwFlags;
///
/// Normally zero. Set to the encoding type of the input message if that input to be signed is the encoded output of another
/// cryptographic message.
///
public uint dwInnerContentType;
///
/// A CRYPT_ALGORITHM_IDENTIFIER. If present and not NULL, it is used instead of the signer's certificate
/// PublicKeyInfo.Algorithm member. Note that for RSA, the hash encryption algorithm is normally the same as the public
/// key algorithm. For DSA, the hash encryption algorithm is normally a DSS signature algorithm. This member can only be used if
/// CRYPT_SIGN_MESSAGE_PARA_HAS_CMS_FIELDS is defined.
///
[MarshalAs(UnmanagedType.FunctionPtr)]
public CRYPT_ALGORITHM_IDENTIFIER HashEncryptionAlgorithm;
///
/// Currently not used and must be set to NULL. This member can only be used if CRYPT_SIGN_MESSAGE_PARA_HAS_CMS_FIELDS is defined.
///
public IntPtr pvHashEncryptionAuxInfo;
}
/// The CRYPT_VERIFY_MESSAGE_PARA structure contains information needed to verify signed messages.
///
/// This structure is passed to the following functions:
///
/// -
/// CryptDecodeMessage
///
/// -
/// CryptDecryptAndVerifyMessageSignature
///
/// -
/// CryptVerifyDetachedMessageSignature
///
/// -
/// CryptVerifyMessageSignature
///
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/ns-wincrypt-crypt_verify_message_para typedef struct
// _CRYPT_VERIFY_MESSAGE_PARA { DWORD cbSize; DWORD dwMsgAndCertEncodingType; HCRYPTPROV_LEGACY hCryptProv;
// PFN_CRYPT_GET_SIGNER_CERTIFICATE pfnGetSignerCertificate; void *pvGetArg; PCCERT_STRONG_SIGN_PARA pStrongSignPara; }
// CRYPT_VERIFY_MESSAGE_PARA, *PCRYPT_VERIFY_MESSAGE_PARA;
[PInvokeData("wincrypt.h", MSDNShortId = "bbd56b5e-2bbe-420f-8842-1be50dca779f")]
[StructLayout(LayoutKind.Sequential)]
public struct CRYPT_VERIFY_MESSAGE_PARA
{
/// Size of this structure in bytes.
public uint cbSize;
///
///
/// Type of encoding used. 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:
///
/// X509_ASN_ENCODING | PKCS_7_ASN_ENCODING
/// Currently defined encoding types are:
///
/// -
/// X509_ASN_ENCODING
///
/// -
/// PKCS_7_ASN_ENCODING
///
///
///
public CertEncodingType dwMsgAndCertEncodingType;
///
/// This member is not used and should be set to NULL.
///
/// Windows Server 2003 and Windows XP: A handle to the cryptographic service provider to be used to verify a signed
/// message. The CSP identified by this handle is used for hashing and for signature verification.Unless there is a strong
/// reason for using a specific cryptographic provider, set to zero to use the default RSA or DSS provider.
///
/// This member's data type is HCRYPTPROV.
///
public HCRYPTPROV hCryptProv;
///
///
/// A pointer to the callback function used to get the signer's certificate context. If NULL, the default callback is
/// used. The default callback tries to get the signer certificate context from the message's certificate store.
///
///
/// An application defined–callback function that gets the signer's certificate can be used in place of the default. It is
/// passed the certificate identifier of the signer (its issuer and serial number) and a handle to its cryptographic signed
/// message's certificate store.
///
/// See CryptGetSignerCertificateCallback for the callback functions signature and arguments.
///
public PFN_CRYPT_GET_SIGNER_CERTIFICATE pfnGetSignerCertificate;
/// Argument to pass to the callback function. Typically, this gets and verifies the message signer's certificate.
public IntPtr pvGetArg;
///
///
/// Optional pointer to a CERT_STRONG_SIGN_PARA structure that contains parameters used for strong signing. If you set this
/// member and the function successfully verifies the signature, the function will then check for a strong signature. If the
/// signature is not strong, the operation will fail and set the GetLastError value to NTE_BAD_ALGID.
///
///
/// Note You can use the pStrongSignPara member only if CRYPT_VERIFY_MESSAGE_PARA_HAS_EXTRA_FIELDS is
/// defined by using the #define directive before including Wincrypt.h. If
/// CRYPT_VERIFY_MESSAGE_PARA_HAS_EXTRA_FIELDS is defined, you must zero all unused fields.
///
/// Windows 8 and Windows Server 2012:
/// Support for this member begins.
///
public IntPtr pStrongSignPara;
}
/// Provides a for that is disposed using .
public class SafeHCRYPTMSG : SafeHANDLE
{
/// Initializes a new instance of the class and assigns an existing handle.
/// An object that represents the pre-existing handle to use.
///
/// to reliably release the handle during the finalization phase; otherwise, (not recommended).
///
public SafeHCRYPTMSG(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { }
/// Initializes a new instance of the class.
private SafeHCRYPTMSG() : base() { }
/// Performs an implicit conversion from to .
/// The safe handle instance.
/// The result of the conversion.
public static implicit operator HCRYPTMSG(SafeHCRYPTMSG h) => h.handle;
///
protected override bool InternalReleaseHandle() => CryptMsgClose(handle);
}
}
}