Vanara/PInvoke/Security/AdvApi32/WinCrypt.cs

7423 lines
360 KiB
C#
Raw Normal View History

2018-08-17 09:38:58 -04:00
using System;
2020-03-13 17:45:15 -04:00
using System.Collections.Generic;
2018-08-17 09:38:58 -04:00
using System.Runtime.InteropServices;
2020-03-13 17:45:15 -04:00
using System.Text;
using Vanara.InteropServices;
using static Vanara.PInvoke.Crypt32;
2018-08-17 09:38:58 -04:00
namespace Vanara.PInvoke
{
public static partial class AdvApi32
{
2020-03-13 17:45:15 -04:00
private delegate bool CryptGetValueMethod<THandle, TEnum>(THandle hKey, TEnum dwParam, IntPtr pbData, ref uint pdwDataLen, uint dwFlags) where THandle : struct where TEnum : Enum;
/// <summary>
/// The PROV_RSA_FULL provider type supports both digital signatures and data encryption. It is considered a general purpose CSP. The
/// RSA public key algorithm is used for all public key operations.
/// </summary>
public const uint PROV_RSA_FULL = 1;
/// <summary>
/// The PROV_RSA_SIG provider type is a subset of PROV_RSA_FULL. It supports only those functions and algorithms required for hashes
/// and digital signatures.
/// </summary>
public const uint PROV_RSA_SIG = 2;
/// <summary>
/// Supports hashes and digital signatures. The signature algorithm specified by the PROV_DSS provider type is the Digital Signature
/// Algorithm (DSA).
/// </summary>
public const uint PROV_DSS = 3;
/// <summary>
/// The PROV_FORTEZZA provider type contains a set of cryptographic protocols and algorithms owned by the National Institute of
/// Standards and Technology (NIST).
/// </summary>
public const uint PROV_FORTEZZA = 4;
/// <summary>
/// Designed for the cryptographic needs of the Exchange mail application and other applications compatible with Microsoft Mail.
/// </summary>
public const uint PROV_MS_EXCHANGE = 5;
/// <summary>The PROV_SSL provider type supports the Secure Sockets Layer (SSL) protocol.</summary>
public const uint PROV_SSL = 6;
/// <summary>Supports both RSA and Schannel protocols.</summary>
public const uint PROV_RSA_SCHANNEL = 12;
/// <summary>A superset of the PROV_DSS provider type with Diffie-Hellman key exchange.</summary>
public const uint PROV_DSS_DH = 13;
/// <summary></summary>
public const uint PROV_EC_ECDSA_SIG = 14;
/// <summary></summary>
public const uint PROV_EC_ECNRA_SIG = 15;
/// <summary></summary>
public const uint PROV_EC_ECDSA_FULL = 16;
/// <summary></summary>
public const uint PROV_EC_ECNRA_FULL = 17;
/// <summary>Supports both Diffie-Hellman and Schannel protocols.</summary>
public const uint PROV_DH_SCHANNEL = 18;
/// <summary></summary>
public const uint PROV_SPYRUS_LYNKS = 20;
/// <summary></summary>
public const uint PROV_RNG = 21;
/// <summary></summary>
public const uint PROV_INTEL_SEC = 22;
/// <summary></summary>
public const uint PROV_REPLACE_OWF = 23;
/// <summary>Supports the same as PROV_RSA_FULL with additional AES encryption capability.</summary>
public const uint PROV_RSA_AES = 24;
/// <summary></summary>
public const uint PROV_STT_MER = 7;
/// <summary></summary>
public const uint PROV_STT_ACQ = 8;
/// <summary></summary>
public const uint PROV_STT_BRND = 9;
/// <summary></summary>
public const uint PROV_STT_ROOT = 10;
/// <summary></summary>
public const uint PROV_STT_ISS = 11;
2020-03-13 17:45:15 -04:00
/// <summary>Flag values for <see cref="CryptAcquireContext"/>.</summary>
[PInvokeData("wincrypt.h", MSDNShortId = "57e13662-3189-4f8d-b90a-d1fbdc09b63c")]
[Flags]
public enum CryptAcquireContextFlags : uint
{
/// <summary>
/// This option is intended for applications that are using ephemeral keys, or applications that do not require access to
/// persisted private keys, such as applications that perform only hashing, encryption, and digital signature verification. Only
/// applications that create signatures or decrypt messages need access to a private key. In most cases, this flag should be
/// set. For file-based CSPs, when this flag is set, the pszContainer parameter must be set to NULL. The application has no
/// access to the persisted private keys of public/private key pairs. When this flag is set, temporary public/private key pairs
/// can be created, but they are not persisted. For hardware-based CSPs, such as a smart card CSP, if the pszContainer parameter
/// is NULL or blank, this flag implies that no access to any keys is required, and that no UI should be presented to the user.
/// This form is used to connect to the CSP to query its capabilities but not to actually use its keys. If the pszContainer
/// parameter is not NULL and not blank, then this flag implies that access to only the publicly available information within
/// the specified container is required. The CSP should not ask for a PIN. Attempts to access private information (for example,
/// the CryptSignHash function) will fail. When CryptAcquireContext is called, many CSPs require input from the owning user
/// before granting access to the private keys in the key container. For example, the private keys can be encrypted, requiring a
/// password from the user before they can be used. However, if the CRYPT_VERIFYCONTEXT flag is specified, access to the private
/// keys is not required and the user interface can be bypassed.
/// </summary>
CRYPT_VERIFYCONTEXT = 0xF0000000,
/// <summary>
/// Creates a new key container with the name specified by pszContainer. If pszContainer is NULL, a key container with the
/// default name is created.
/// </summary>
CRYPT_NEWKEYSET = 0x00000008,
/// <summary>
/// Delete the key container specified by pszContainer. If pszContainer is NULL, the key container with the default name is
/// deleted. All key pairs in the key container are also destroyed. When this flag is set, the value returned in phProv is
/// undefined, and thus, the CryptReleaseContext function need not be called afterward.
/// </summary>
CRYPT_DELETEKEYSET = 0x00000010,
/// <summary>
/// By default, keys and key containers are stored as user keys. For Base Providers, this means that user key containers are
/// stored in the user's profile. A key container created without this flag by an administrator can be accessed only by the user
/// creating the key container and a user with administration privileges. Windows XP: A key container created without this flag
/// by an administrator can be accessed only by the user creating the key container and the local system account. A key
/// container created without this flag by a user that is not an administrator can be accessed only by the user creating the key
/// container and the local system account. The CRYPT_MACHINE_KEYSET flag can be combined with all of the other flags to
/// indicate that the key container of interest is a computer key container and the CSP treats it as such. For Base Providers,
/// this means that the keys are stored locally on the computer that created the key container. If a key container is to be a
/// computer container, the CRYPT_MACHINE_KEYSET flag must be used with all calls to CryptAcquireContext that reference the
/// computer container. The key container created with CRYPT_MACHINE_KEYSET by an administrator can be accessed only by its
/// creator and by a user with administrator privileges unless access rights to the container are granted using
/// CryptSetProvParam. Windows XP: The key container created with CRYPT_MACHINE_KEYSET by an administrator can be accessed only
/// by its creator and by the local system account unless access rights to the container are granted using CryptSetProvParam.
/// The key container created with CRYPT_MACHINE_KEYSET by a user that is not an administrator can be accessed only by its
/// creator and by the local system account unless access rights to the container are granted using CryptSetProvParam. The
/// CRYPT_MACHINE_KEYSET flag is useful when the user is accessing from a service or user account that did not log on
/// interactively. When key containers are created, most CSPs do not automatically create any public/private key pairs. These
/// keys must be created as a separate step with the CryptGenKey function.
/// </summary>
CRYPT_MACHINE_KEYSET = 0x00000020,
/// <summary>
/// The application requests that the CSP not display any user interface (UI) for this context. If the CSP must display the UI
/// to operate, the call fails and the NTE_SILENT_CONTEXT error code is set as the last error. In addition, if calls are made to
/// CryptGenKey with the CRYPT_USER_PROTECTED flag with a context that has been acquired with the CRYPT_SILENT flag, the calls
/// fail and the CSP sets NTE_SILENT_CONTEXT. CRYPT_SILENT is intended for use with applications for which the UI cannot be
/// displayed by the CSP.
/// </summary>
CRYPT_SILENT = 0x00000040,
/// <summary>
/// Obtains a context for a smart card CSP that can be used for hashing and symmetric key operations but cannot be used for any
/// operation that requires authentication to a smart card using a PIN. This type of context is most often used to perform
/// operations on an empty smart card, such as setting the PIN by using CryptSetProvParam. This flag can only be used with smart
/// card CSPs. Windows Server 2003 and Windows XP: This flag is not supported.
/// </summary>
CRYPT_DEFAULT_CONTAINER_OPTIONAL = 0x00000080,
}
/// <summary>Flags for CryptDecrypt.</summary>
[PInvokeData("wincrypt.h", MSDNShortId = "7c3d2838-6fd1-4f6c-9586-8b94b459a31a")]
[Flags]
public enum CryptDecryptFlags
{
/// <summary>
/// Use Optimal Asymmetric Encryption Padding (OAEP) (PKCS #1 version 2). This flag is only supported by the Microsoft Enhanced
/// Cryptographic Provider with RSA encryption/decryption. This flag cannot be combined with the
/// CRYPT_DECRYPT_RSA_NO_PADDING_CHECK flag.
/// </summary>
CRYPT_OAEP = 0x00000040,
/// <summary>
/// Perform the decryption on the BLOB without checking the padding. This flag is only supported by the Microsoft Enhanced
/// Cryptographic Provider with RSA encryption/decryption. This flag cannot be combined with the CRYPT_OAEP flag.
/// </summary>
CRYPT_DECRYPT_RSA_NO_PADDING_CHECK = 0x00000020,
}
/// <summary>Flags for CryptEncrypt.</summary>
[PInvokeData("wincrypt.h", MSDNShortId = "697c4960-552b-4c3a-95cf-4632af56945b")]
[Flags]
public enum CryptEncryptFlags
{
/// <summary>
/// Use Optimal Asymmetric Encryption Padding (OAEP) (PKCS #1 version 2). This flag is only supported by the Microsoft Enhanced
/// Cryptographic Provider with RSA encryption/decryption. This flag cannot be combined with the
/// CRYPT_DECRYPT_RSA_NO_PADDING_CHECK flag.
/// </summary>
CRYPT_OAEP = 0x00000040,
}
2022-06-28 18:02:29 -04:00
/// <summary>Flags for <see cref="CryptExportKey(HCRYPTKEY, HCRYPTKEY, BlobType, CryptExportKeyFlags, IntPtr, ref uint)"/>.</summary>
2020-03-13 17:45:15 -04:00
[PInvokeData("wincrypt.h", MSDNShortId = "8a7c7b46-3bea-4043-b568-6d91d6335737")]
[Flags]
public enum CryptExportKeyFlags
{
/// <summary>This flag causes this function to export version 3 of a BLOB type.</summary>
CRYPT_BLOB_VER3 = 0x00000080,
/// <summary>This flag destroys the original key in the OPAQUEKEYBLOB. This flag is available in Schannel CSPs only.</summary>
CRYPT_DESTROYKEY = 0x00000004,
/// <summary>
/// This flag causes PKCS #1 version 2 formatting to be created with the RSA encryption and decryption when exporting SIMPLEBLOBs.
/// </summary>
CRYPT_OAEP = 0x00000040,
/// <summary>
/// The first eight bytes of the RSA encryption block padding must be set to 0x03 rather than to random data. This prevents
/// version rollback attacks and is discussed in the SSL3 specification. This flag is available for Schannel CSPs only.
/// </summary>
CRYPT_SSL2_FALLBACK = 0x00000002,
/// <summary>This flag is not used.</summary>
CRYPT_Y_ONLY = 0x00000001,
/// <summary></summary>
CRYPT_IPSEC_HMAC_KEY = 0x00000100,
}
/// <summary>Flags for <see cref="CryptDeriveKey"/> and <see cref="CryptGenKey"/>.</summary>
[PInvokeData("wincrypt.h", MSDNShortId = "b65dd856-2dfa-4cda-9b2f-b32f3c291470")]
[Flags]
public enum CryptGenKeyFlags : uint
{
/// <summary>
/// If this flag is set, the session key can be transferred out of the CSP into a key BLOB through the CryptExportKey function.
/// Because keys generally must be exportable, this flag should usually be set.
/// <para>
/// If this flag is not set, then the session key is not exportable. This means the key is available only within the current
/// session and only the application that created it is able to use it.
/// </para>
/// <para>This flag does not apply to public/private key pairs.</para>
/// </summary>
CRYPT_EXPORTABLE = 0x00000001,
/// <summary>
/// If this flag is set, the user is notified through a dialog box or another method when certain actions are attempting to use
/// this key. The precise behavior is specified by the CSP being used. If the provider context was opened with the CRYPT_SILENT
/// flag set, using this flag causes a failure and the last error is set to NTE_SILENT_CONTEXT.
/// </summary>
CRYPT_USER_PROTECTED = 0x00000002,
/// <summary>
/// Typically, when a session key is made from a hash value, there are a number of leftover bits. For example, if the hash value
/// is 128 bits and the session key is 40 bits, there will be 88 bits left over.
/// <para>
/// If this flag is set, then the key is assigned a salt value based on the unused hash value bits. You can retrieve this salt
/// value by using the CryptGetKeyParam function with the dwParam parameter set to KP_SALT.
/// </para>
/// <para>If this flag is not set, then the key is given a salt value of zero.</para>
/// <para>
/// When keys with nonzero salt values are exported (by using CryptExportKey), the salt value must also be obtained and kept
/// with the key BLOB.
/// </para>
/// </summary>
CRYPT_CREATE_SALT = 0x00000004,
/// <summary>
/// Some CSPs use session keys that are derived from multiple hash values. When this is the case, CryptDeriveKey must be called
/// multiple times.
/// <para>
/// If this flag is set, a new session key is not generated.Instead, the key specified by phKey is modified.The precise behavior
/// of this flag is dependent on the type of key being generated and on the particular CSP being used.
/// </para>
/// <para>Microsoft cryptographic service providers ignore this flag.</para>
/// </summary>
CRYPT_UPDATE_KEY = 0x00000008,
/// <summary>
/// This flag specifies that a no salt value gets allocated for a 40-bit symmetric key. For more information, see Salt Value Functionality.
/// </summary>
CRYPT_NO_SALT = 0x00000010,
/// <summary>
/// This flag specifies an initial Diffie-Hellman or DSS key generation. This flag is useful only with Diffie-Hellman and DSS
/// CSPs. When used, a default key length will be used unless a key length is specified in the upper 16 bits of the dwFlags
/// parameter. If parameters that involve key lengths are set on a PREGEN Diffie-Hellman or DSS key using CryptSetKeyParam, the
/// key lengths must be compatible with the key length set here.
/// </summary>
CRYPT_PREGEN = 0x00000040,
/// <summary>This flag is not used.</summary>
CRYPT_RECIPIENT = 0x00000010,
/// <summary>This flag is not used.</summary>
CRYPT_INITIATOR = 0x00000040,
/// <summary>This flag is not used.</summary>
CRYPT_ONLINE = 0x00000080,
/// <summary>This flag is not used.</summary>
CRYPT_SF = 0x00000100,
/// <summary>This flag is not used.</summary>
CRYPT_CREATE_IV = 0x00000200,
/// <summary>This flag is not used.</summary>
CRYPT_KEK = 0x00000400,
/// <summary>This flag is not used.</summary>
CRYPT_DATA_KEY = 0x00000800,
/// <summary>This flag is not used.</summary>
CRYPT_VOLATILE = 0x00001000,
/// <summary>This flag is not used.</summary>
CRYPT_SGCKEY = 0x00002000,
/// <summary>This flag is not used.</summary>
CRYPT_USER_PROTECTED_STRONG = 0x00100000,
/// <summary>
/// If this flag is set, the key can be exported until its handle is closed by a call to CryptDestroyKey. This allows newly
/// generated keys to be exported upon creation for archiving or key recovery. After the handle is closed, the key is no longer exportable.
/// </summary>
CRYPT_ARCHIVABLE = 0x00004000,
/// <summary>
/// <para>
/// This flag specifies strong key protection. When this flag is set, the user is prompted to enter a password for the key when
/// the key is created. The user will be prompted to enter the password whenever this key is used.
/// </para>
/// <para>
/// This flag is only used by the CSPs that are provided by Microsoft. Third party CSPs will define their own behavior for
/// strong key protection.
/// </para>
/// <para>
/// Specifying this flag causes the same result as calling this function with the CRYPT_USER_PROTECTED flag when strong key
/// protection is specified in the system registry.
/// </para>
/// <para>
/// If this flag is specified and the provider handle in the hProv parameter was created by using the CRYPT_VERIFYCONTEXT or
/// CRYPT_SILENT flag, this function will set the last error to NTE_SILENT_CONTEXT and return zero.
/// </para>
/// <para>Windows Server 2003 and Windows XP: This flag is not supported.</para>
/// </summary>
CRYPT_FORCE_KEY_PROTECTION_HIGH = 0x00008000,
/// <summary>
/// This flag is used only with Schannel providers. If this flag is set, the key to be generated is a server-write key;
/// otherwise, it is a client-write key.
/// </summary>
CRYPT_SERVER = 0x400,
}
/// <summary>Flags for <see cref="CryptHashSessionKey"/>.</summary>
[Flags]
public enum CryptHashSessionKeyFlags
{
/// <summary>
/// When this flag is set, the bytes of the key are hashed in little-endian form. Note that by default (when dwFlags is zero),
/// the bytes of the key are hashed in big-endian form.
/// </summary>
CRYPT_LITTLE_ENDIAN = 1
}
/// <summary>Flags for <see cref="CryptGetDefaultProvider"/> and <see cref="CryptSetProviderEx"/>.</summary>
[PInvokeData("wincrypt.h", MSDNShortId = "5d15641e-1ad7-441d-9423-65fd51de9812")]
[Flags]
public enum CryptProviderFlags
{
/// <summary>Returns the user-context default CSP of the specified type.</summary>
CRYPT_USER_DEFAULT = 0x00000002,
/// <summary>Returns the computer default CSP of the specified type.</summary>
CRYPT_MACHINE_DEFAULT = 0x00000001,
/// <summary>Can be used in conjunction with CRYPT_MACHINE_DEFAULT or CRYPT_USER_DEFAULT to delete the default.</summary>
CRYPT_DELETE_DEFAULT = 0x00000004,
}
/// <summary>Flags for <see cref="CryptSignHash"/> and <see cref="CryptVerifySignature"/>.</summary>
[PInvokeData("wincrypt.h", MSDNShortId = "3119eabc-90ff-42c6-b3fa-e8be625f6d1e")]
[Flags]
public enum CryptSignFlags
{
/// <summary>
/// This flag is used with RSA providers. When verifying the signature, the hash object identifier (OID) is not expected to be
/// present or checked. If this flag is not set, the hash OID in the default signature is verified as specified in the
/// definition of DigestInfo in PKCS #7.
/// </summary>
CRYPT_NOHASHOID = 0x00000001,
/// <summary>This flag is not used.</summary>
CRYPT_TYPE2_FORMAT = 0x00000002,
/// <summary>Use X.931 support for the FIPS 186-2compliant version of RSA (rDSA).</summary>
CRYPT_X931_FORMAT = 0x00000004,
}
/// <summary>Query type.</summary>
[PInvokeData("wincrypt.h", MSDNShortId = "ed008c07-1a40-4075-bdaa-eb7f7e12d9c3")]
public enum HashParam
{
/// <summary>
/// An ALG_ID that indicates the algorithm specified when the hash object was created. For a list of hash algorithms, see CryptCreateHash.
/// </summary>
[CorrespondingType(typeof(ALG_ID), CorrespondingAction.Get)]
[CorrespondingType(typeof(uint))]
HP_ALGID = 0x0001,
/// <summary>
/// The hash value or message hash for the hash object specified by hHash. This value is generated based on the data supplied to
/// the hash object earlier through the CryptHashData and CryptHashSessionKey functions.
/// <para>
/// The CryptGetHashParam function completes the hash. After CryptGetHashParam has been called, no more data can be added to the
/// hash. Additional calls to CryptHashData or CryptHashSessionKey fail. After the application is done with the hash,
/// CryptDestroyHash should be called to destroy the hash object.
/// </para>
/// </summary>
[CorrespondingType(typeof(byte[]))]
[CorrespondingType(typeof(IntPtr))]
HP_HASHVAL = 0x0002,
/// <summary>
/// DWORD value indicating the number of bytes in the hash value. This value will vary depending on the hash algorithm.
/// Applications must retrieve this value just before the HP_HASHVAL value so the correct amount of memory can be allocated.
/// </summary>
[CorrespondingType(typeof(uint), CorrespondingAction.Get)]
HP_HASHSIZE = 0x0004,
/// <summary>
/// A pointer to an HMAC_INFO structure that specifies the cryptographic hash algorithm and the inner and outer strings to be used.
/// </summary>
[CorrespondingType(typeof(HMAC_INFO), CorrespondingAction.Set)]
HP_HMAC_INFO = 0x0005,
/// <summary>
/// Component of the function argument GOSTR3411_PRF. It takes various values in client and server messages when implementing
/// the TLS Handshake Protocol.
/// </summary>
[CorrespondingType(typeof(CRYPTOAPI_BLOB), CorrespondingAction.Set)]
HP_TLS1PRF_LABEL = 0x0006,
/// <summary>
/// Component of the function argument GOSTR3411_PRF. It takes various values in client and server messages when implementing
/// the TLS Handshake Protocol.
/// </summary>
[CorrespondingType(typeof(CRYPTOAPI_BLOB), CorrespondingAction.Set)]
HP_TLS1PRF_SEED = 0x0007,
}
/// <summary>Specifies the type of query being made.</summary>
[PInvokeData("wincrypt.h", MSDNShortId = "07956d74-0e22-484b-9bf1-e0184a2ff32f")]
public enum KeyParam
{
/// <summary>
/// Retrieve the initialization vector of the key. The pbData parameter is a pointer to a BYTE array that receives the
/// initialization vector. The size of this array is the block size, in bytes. For example, if the block length is 64 bits, the
/// initialization vector consists of 8 bytes.
/// </summary>
KP_IV = 1,
/// <summary>
/// Retrieve the salt value of the key. The pbData parameter is a pointer to a BYTE array that receives the salt value in
/// little-endian form. The size of the salt value varies depending on the CSP and algorithm being used. Salt values do not
/// apply to public/private key pairs.
/// </summary>
KP_SALT = 2,
/// <summary>
/// <para>
/// Retrieve the padding mode. The pbData parameter is a pointer to a DWORD value that receives a numeric identifier that
/// identifies the padding method used by the cipher. This can be one of the following values.
/// </para>
/// <para>
/// PKCS5_PADDING <br/> Specifies the PKCS 5 (sec 6.2) padding method. <br/> RANDOM_PADDING <br/> The padding uses random
/// numbers. This padding method is not supported by the Microsoft supplied CSPs. <br/> ZERO_PADDING <br/> The padding uses
/// zeros. This padding method is not supported by the Microsoft supplied CSPs.
/// </para>
/// </summary>
KP_PADDING = 3,
/// <summary>
/// <para>
/// Retrieve the cipher mode. The pbData parameter is a pointer to a DWORD value that receives a cipher mode identifier. For
/// more information about cipher modes, see Data Encryption and Decryption.
/// </para>
/// <para>The following cipher mode identifiers are currently defined.</para>
/// <para>
/// CRYPT_MODE_CBC <br/> The cipher mode is cipher block chaining. <br/> CRYPT_MODE_CFB <br/> The cipher mode is cipher feedback
/// (CFB). Microsoft CSPs currently support only 8-bit feedback in cipher feedback mode. <br/> CRYPT_MODE_ECB <br/> The cipher
/// mode is electronic codebook. <br/> CRYPT_MODE_OFB <br/> The cipher mode is Output Feedback (OFB). Microsoft CSPs currently
/// do not support Output Feedback Mode. <br/> CRYPT_MODE_CTS <br/> The cipher mode is ciphertext stealing mode.
/// </para>
/// </summary>
KP_MODE = 4,
/// <summary>
/// Retrieve the number of bits to feed back. The pbData parameter is a pointer to a DWORD value that receives the number of
/// bits that are processed per cycle when the OFB or CFB cipher modes are used.
/// </summary>
KP_MODE_BITS = 5,
/// <summary>
/// <para>
/// Retrieve the key permissions. The pbData parameter is a pointer to a DWORD value that receives the permission flags for the key.
/// </para>
/// <para>
/// The following permission identifiers are currently defined. The key permissions can be zero or a combination of one or more
/// of the following values.
/// </para>
/// <para>
/// CRYPT_ARCHIVE <br/> Allow export during the lifetime of the handle of the key. This permission can be set only if it is
/// already set in the internal permissions field of the key. Attempts to clear this permission are ignored. <br/> CRYPT_DECRYPT
/// <br/> Allow decryption. <br/> CRYPT_ENCRYPT <br/> Allow encryption. <br/> CRYPT_EXPORT <br/> Allow the key to be exported.
/// <br/> CRYPT_EXPORT_KEY <br/> Allow the key to be used for exporting keys. <br/> CRYPT_IMPORT_KEY <br/> Allow the key to be
/// used for importing keys. <br/> CRYPT_MAC <br/> Allow Message Authentication Codes (MACs) to be used with key. <br/>
/// CRYPT_READ <br/> Allow values to be read. <br/> CRYPT_WRITE <br/> Allow values to be set.
/// </para>
/// </summary>
KP_PERMISSIONS = 6,
/// <summary>
/// Retrieve the key algorithm. The pbData parameter is a pointer to an ALG_ID value that receives the identifier of the
/// algorithm that was specified when the key was created.
/// <para>
/// When AT_KEYEXCHANGE or AT_SIGNATURE is specified for the Algid parameter of the CryptGenKey function, the algorithm
/// identifiers that are used to generate the key depend on the provider used. For more information, see ALG_ID.
/// </para>
/// </summary>
KP_ALGID = 7,
/// <summary>
/// If a session key is specified by the hKey parameter, retrieve the block length of the key cipher. The pbData parameter is a
/// pointer to a DWORD value that receives the block length, in bits. For stream ciphers, this value is always zero.
/// <para>
/// If a public/private key pair is specified by hKey, retrieve the encryption granularity of the key pair.The pbData parameter
/// is a pointer to a DWORD value that receives the encryption granularity, in bits.For example, the Microsoft Base
/// Cryptographic Provider generates 512-bit RSA key pairs, so a value of 512 is returned for these keys. If the public key
/// algorithm does not support encryption, the value retrieved is undefined.
/// </para>
/// </summary>
KP_BLOCKLEN = 8,
/// <summary>
/// Retrieve the actual length of the key. The pbData parameter is a pointer to a DWORD value that receives the key length, in
/// bits. KP_KEYLEN can be used to get the length of any key type. Microsoft cryptographic service providers (CSPs) return a key
/// length of 64 bits for CALG_DES, 128 bits for CALG_3DES_112, and 192 bits for CALG_3DES. These lengths are different from the
/// lengths returned when you are enumerating algorithms with the dwParam value of the CryptGetProvParam function set to
/// PP_ENUMALGS. The length returned by this call is the actual size of the key, including the parity bits included in the key.
/// <para>
/// Microsoft CSPs that support the CALG_CYLINK_MEK ALG_ID return 64 bits for that algorithm. CALG_CYLINK_MEK is a 40-bit key
/// but has parity and zeroed key bits to make the key length 64 bits.
/// </para>
/// </summary>
KP_KEYLEN = 9,
/// <summary></summary>
KP_SALT_EX = 10,
/// <summary>
/// Retrieve the modulus prime number P of the DSS key. The pbData parameter is a pointer to a buffer that receives the value in
/// little-endian form. The pdwDataLen parameter contains the size of the buffer, in bytes.
/// </summary>
KP_P = 11,
/// <summary>
/// Retrieve the generator G of the DSS key. The pbData parameter is a pointer to a buffer that receives the value in
/// little-endian form. The pdwDataLen parameter contains the size of the buffer, in bytes.
/// </summary>
KP_G = 12,
/// <summary>
/// Retrieve the modulus prime number Q of the DSS key. The pbData parameter is a pointer to a buffer that receives the value in
/// little-endian form. The pdwDataLen parameter contains the size of the buffer, in bytes.
/// </summary>
KP_Q = 13,
/// <summary></summary>
KP_X = 14,
/// <summary></summary>
KP_Y = 15,
/// <summary></summary>
KP_RA = 16,
/// <summary></summary>
KP_RB = 17,
/// <summary></summary>
KP_INFO = 18,
/// <summary>
/// Retrieve the effective key length of an RC2 key. The pbData parameter is a pointer to a DWORD value that receives the
/// effective key length.
/// </summary>
KP_EFFECTIVE_KEYLEN = 19,
/// <summary></summary>
KP_SCHANNEL_ALG = 20,
/// <summary></summary>
KP_CLIENT_RANDOM = 21,
/// <summary></summary>
KP_SERVER_RANDOM = 22,
/// <summary></summary>
KP_RP = 23,
/// <summary></summary>
KP_PRECOMP_MD5 = 24,
/// <summary></summary>
KP_PRECOMP_SHA = 25,
/// <summary>
/// pbData is the address of a buffer that receives the X.509 certificate that has been encoded by using Distinguished Encoding
/// Rules (DER). The public key in the certificate must match the corresponding signature or exchange key.
/// </summary>
KP_CERTIFICATE = 26,
/// <summary></summary>
KP_CLEAR_KEY = 27,
/// <summary></summary>
KP_PUB_EX_LEN = 28,
/// <summary></summary>
KP_PUB_EX_VAL = 29,
/// <summary>
/// This value is not used.
/// <para>
/// Windows Vista, Windows Server 2003 and Windows XP: Retrieve the secret agreement value from an imported Diffie-Hellman
/// algorithm key of type CALG_AGREEDKEY_ANY. The pbData parameter is the address of a buffer that receives the secret agreement
/// value, in little-endian format. This buffer must be the same length as the key. The dwFlags parameter must be set to
/// 0xF42A19B6. This property can only be retrieved by a thread running under the local system account.This property is
/// available for use in the operating systems listed above. It may be altered or unavailable in subsequent versions.
/// </para>
/// </summary>
KP_KEYVAL = 30,
/// <summary></summary>
KP_ADMIN_PIN = 31,
/// <summary></summary>
KP_KEYEXCHANGE_PIN = 32,
/// <summary></summary>
KP_SIGNATURE_PIN = 33,
/// <summary></summary>
KP_PREHASH = 34,
/// <summary></summary>
KP_ROUNDS = 35,
/// <summary></summary>
KP_OAEP_PARAMS = 36,
/// <summary></summary>
KP_CMS_KEY_INFO = 37,
/// <summary></summary>
KP_CMS_DH_KEY_INFO = 38,
/// <summary></summary>
KP_PUB_PARAMS = 39,
/// <summary>
/// Verifies the parameters of a Diffie-Hellman algorithm or DSA key. The pbData parameter is not used, and the value pointed to
/// by pdwDataLen receives zero.
/// <para>This function returns a nonzero value if the key parameters are valid or zero otherwise.</para>
/// </summary>
KP_VERIFY_PARAMS = 40,
/// <summary></summary>
KP_HIGHEST_VERSION = 41,
/// <summary>This value is not used.</summary>
KP_GET_USE_COUNT = 42,
/// <summary></summary>
KP_PIN_ID = 43,
/// <summary></summary>
KP_PIN_INFO = 44,
}
/// <summary>The nature of the query.</summary>
[PInvokeData("wincrypt.h", MSDNShortId = "c0b7c1c8-aa42-4d40-a7f7-99c0821c8977")]
public enum ProvParam
{
/// <summary>Returns the administrator personal identification number (PIN) in the pbData parameter as a LPSTR.</summary>
PP_ADMIN_PIN = 0x1F,
/// <summary>This constant is not used.</summary>
PP_APPLI_CERT = 0x12,
/// <summary>This constant is not used.</summary>
PP_CHANGE_PASSWORD = 0x7,
/// <summary>
/// Returns the certificate chain associated with the hProv handle. The returned certificate chain is X509_ASN_ENCODING encoded.
/// </summary>
PP_CERTCHAIN = 0x9,
/// <summary>
/// The name of the current key container as a null-terminated CHAR string. This string is exactly the same as the one passed in
/// the pszContainer parameter of the CryptAcquireContext function to specify the key container to use. The pszContainer
/// parameter can be read to determine the name of the default key container.
/// </summary>
PP_CONTAINER = 0x6,
/// <summary>
/// Not implemented by Microsoft CSPs. This behavior may be implemented by other CSPs.
/// <para>Windows XP: This parameter is not supported.</para>
/// </summary>
PP_CRYPT_COUNT_KEY_USE = 0x29,
/// <summary>
/// A PROV_ENUMALGS structure that contains information about one algorithm supported by the CSP being queried.
/// <para>
/// The first time this value is read, the dwFlags parameter must contain the CRYPT_FIRST flag. Doing so causes this function to
/// retrieve the first element in the enumeration. The subsequent elements can then be retrieved by setting the CRYPT_NEXT flag
/// in the dwFlags parameter. When this function fails with the ERROR_NO_MORE_ITEMS error code, the end of the enumeration has
/// been reached.
/// </para>
/// <para>
/// This function is not thread safe, and all of the available algorithms might not be enumerated if this function is used in a
/// multithreaded context.
/// </para>
/// </summary>
PP_ENUMALGS = 0x1,
/// <summary>
/// A PROV_ENUMALGS_EX structure that contains information about one algorithm supported by the CSP being queried. The structure
/// returned contains more information about the algorithm than the structure returned for PP_ENUMALGS.
/// <para>
/// The first time this value is read, the dwFlags parameter must contain the CRYPT_FIRST flag. Doing so causes this function to
/// retrieve the first element in the enumeration. The subsequent elements can then be retrieved by setting the CRYPT_NEXT flag
/// in the dwFlags parameter. When this function fails with the ERROR_NO_MORE_ITEMS error code, the end of the enumeration has
/// been reached.
/// </para>
/// <para>
/// This function is not thread safe and all of the available algorithms might not be enumerated if this function is used in a
/// multithreaded context.
/// </para>
/// </summary>
PP_ENUMALGS_EX = 0x16,
/// <summary>
/// The name of one of the key containers maintained by the CSP in the form of a null-terminated CHAR string.
/// <para>
/// The first time this value is read, the dwFlags parameter must contain the CRYPT_FIRST flag. Doing so causes this function to
/// retrieve the first element in the enumeration. The subsequent elements can then be retrieved by setting the CRYPT_NEXT flag
/// in the dwFlags parameter. When this function fails with the ERROR_NO_MORE_ITEMS error code, the end of the enumeration has
/// been reached.
/// </para>
/// <para>
/// To enumerate key containers associated with a computer, first call CryptAcquireContext using the CRYPT_MACHINE_KEYSET flag,
/// and then use the handle returned from CryptAcquireContext as the hProv parameter in the call to CryptGetProvParam.
/// </para>
/// <para>
/// This function is not thread safe and all of the available algorithms might not be enumerated if this function is used in a
/// multithreaded context.
/// </para>
/// </summary>
PP_ENUMCONTAINERS = 0x2,
/// <summary>This constant is not used.</summary>
PP_ENUMELECTROOTS = 0x1A,
/// <summary>
/// Indicates that the current CSP supports the dwProtocols member of the PROV_ENUMALGS_EX structure. If this function succeeds,
/// the CSP supports the dwProtocols member of the PROV_ENUMALGS_EX structure. If this function fails with an NTE_BAD_TYPE error
/// code, the CSP does not support the dwProtocols member.
/// </summary>
PP_ENUMEX_SIGNING_PROT = 0x28,
/// <summary>This constant is not used.</summary>
PP_ENUMMANDROOTS = 0x19,
/// <summary>A DWORD value that indicates how the CSP is implemented. For a table of possible values, see Remarks.</summary>
PP_IMPTYPE = 0x3,
/// <summary>This query is not used.</summary>
PP_KEY_TYPE_SUBTYPE = 0xA,
/// <summary>
/// Specifies that the key exchange PIN is contained in pbData. The PIN is represented as a null-terminated ASCII string.
/// </summary>
PP_KEYEXCHANGE_PIN = 0x20,
/// <summary>
/// Retrieves the security descriptor for the key storage container. The pbData parameter is the address of a
/// SECURITY_DESCRIPTOR structure that receives the security descriptor for the key storage container. The security descriptor
/// is returned in self-relative format.
/// </summary>
PP_KEYSET_SEC_DESCR = 0x8,
/// <summary>
/// Determines whether the hProv parameter is a computer key set. The pbData parameter must be a DWORD; the DWORD will be set to
/// the CRYPT_MACHINE_KEYSET flag if that flag was passed to the CryptAcquireContext function.
/// </summary>
PP_KEYSET_TYPE = 0x1B,
/// <summary>
/// Returns information about the key specifier values that the CSP supports. Key specifier values are joined in a logical OR
/// and returned in the pbData parameter of the call as a DWORD. For example, the Microsoft Base Cryptographic Provider version
/// 1.0 returns a DWORD value of AT_SIGNATURE | AT_KEYEXCHANGE.
/// </summary>
PP_KEYSPEC = 0x27,
/// <summary>Returns a DWORD value of CRYPT_SEC_DESCR.</summary>
PP_KEYSTORAGE = 0x11,
/// <summary>
/// The number of bits for the increment length of AT_KEYEXCHANGE. This information is used with information returned in the
/// PP_ENUMALGS_EX value. With the information returned when using PP_ENUMALGS_EX and PP_KEYX_KEYSIZE_INC, the valid key lengths
/// for AT_KEYEXCHANGE can be determined. These key lengths can then be used with CryptGenKey. For example if a CSP enumerates
/// CALG_RSA_KEYX (AT_KEYEXCHANGE) with a minimum key length of 512 bits and a maximum of 1024 bits, and returns the increment
/// length as 64 bits, then valid key lengths are 512, 576, 640,… 1024.
/// </summary>
PP_KEYX_KEYSIZE_INC = 0x23,
/// <summary>
/// The name of the CSP in the form of a null-terminated CHAR string. This string is identical to the one passed in the
/// pszProvider parameter of the CryptAcquireContext function to specify that the current CSP be used.
/// </summary>
PP_NAME = 0x4,
/// <summary>A DWORD value that indicates the provider type of the CSP.</summary>
PP_PROVTYPE = 0x10,
/// <summary>
/// Obtains the root certificate store for the smart card. This certificate store contains all of the root certificates that are
/// stored on the smart card.
/// <para>
/// The pbData parameter is the address of an HCERTSTORE variable that receives the handle of the certificate store. When this
/// handle is no longer needed, the caller must close it by using the CertCloseStore function.
/// </para>
/// <para>Windows Server 2003 and Windows XP: This parameter is not supported.</para>
/// </summary>
PP_ROOT_CERTSTORE = 0x2E,
/// <summary>The size, in bits, of the session key.</summary>
PP_SESSION_KEYSIZE = 0x14,
/// <summary>Used with server gated cryptography.</summary>
PP_SGC_INFO = 0x25,
/// <summary>
/// The number of bits for the increment length of AT_SIGNATURE. This information is used with information returned in the
/// PP_ENUMALGS_EX value. With the information returned when using PP_ENUMALGS_EX and PP_SIG_KEYSIZE_INC, the valid key lengths
/// for AT_SIGNATURE can be determined. These key lengths can then be used with CryptGenKey.
/// <para>
/// For example, if a CSP enumerates CALG_RSA_SIGN (AT_SIGNATURE) with a minimum key length of 512 bits and a maximum of 1024
/// bits, and returns the increment length as 64 bits, then valid key lengths are 512, 576, 640,… 1024.
/// </para>
/// </summary>
PP_SIG_KEYSIZE_INC = 0x22,
/// <summary>
/// Specifies that the key signature PIN is contained in pbData. The PIN is represented as a null-terminated ASCII string.
/// </summary>
PP_SIGNATURE_PIN = 0x21,
/// <summary>
/// Obtains the identifier of the smart card. The pbData parameter is the address of a GUID structure that receives the
/// identifier of the smart card.
/// <para>Windows Server 2003 and Windows XP: This parameter is not supported.</para>
/// </summary>
PP_SMARTCARD_GUID = 0x2D,
/// <summary>
/// Obtains the name of the smart card reader. The pbData parameter is the address of an ANSI character array that receives a
/// null-terminated ANSI string that contains the name of the smart card reader. The size of this buffer, contained in the
/// variable pointed to by the pdwDataLen parameter, must include the NULL terminator.
/// <para>Windows Server 2003 and Windows XP: This parameter is not supported.</para>
/// </summary>
PP_SMARTCARD_READER = 0x2B,
/// <summary/>
PP_SMARTCARD_READER_ICON = 47,
/// <summary>The size of the symmetric key.</summary>
PP_SYM_KEYSIZE = 0x13,
/// <summary>This query is not used.</summary>
PP_UI_PROMPT = 0x15,
/// <summary>
/// The unique container name of the current key container in the form of a null-terminated CHAR string. For many CSPs, this
/// name is the same name returned when the PP_CONTAINER value is used. The CryptAcquireContext function must work with this
/// container name.
/// </summary>
PP_UNIQUE_CONTAINER = 0x24,
/// <summary>
/// Indicates whether a hardware random number generator (RNG) is supported. When PP_USE_HARDWARE_RNG is specified, the function
/// succeeds and returns TRUE if a hardware RNG is supported. The function fails and returns FALSE if a hardware RNG is not
/// supported. If a RNG is supported, PP_USE_HARDWARE_RNG can be set in CryptSetProvParam to indicate that the CSP must
/// exclusively use the hardware RNG for this provider context. When PP_USE_HARDWARE_RNG is used, the pbData parameter must be
/// NULL and dwFlags must be zero.
/// <para>None of the Microsoft CSPs currently support using a hardware RNG.</para>
/// </summary>
PP_USE_HARDWARE_RNG = 0x26,
/// <summary>
/// Obtains the user certificate store for the smart card. This certificate store contains all of the user certificates that are
/// stored on the smart card. The certificates in this store are encoded by using PKCS_7_ASN_ENCODING or X509_ASN_ENCODING
/// encoding and should contain the CERT_KEY_PROV_INFO_PROP_ID property.
/// <para>
/// The pbData parameter is the address of an HCERTSTORE variable that receives the handle of an in-memory certificate store.
/// When this handle is no longer needed, the caller must close it by using the CertCloseStore function.
/// </para>
/// <para>Windows Server 2003 and Windows XP: This parameter is not supported.</para>
/// </summary>
PP_USER_CERTSTORE = 0x2A,
/// <summary>
/// The version number of the CSP. The least significant byte contains the minor version number and the next most significant
/// byte the major version number. Version 2.0 is represented as 0x00000200. To maintain backward compatibility with earlier
/// versions of the Microsoft Base Cryptographic Provider and the Microsoft Enhanced Cryptographic Provider, the provider names
/// retain the "v1.0" designation in later versions.
/// </summary>
PP_VERSION = 0x5,
}
/// <summary>
/// <para>
/// The CryptAcquireContext function is used to acquire a handle to a particular key container within a particular cryptographic
/// service provider (CSP). This returned handle is used in calls to CryptoAPI functions that use the selected CSP.
/// </para>
/// <para>
/// This function first attempts to find a CSP with the characteristics described in the dwProvType and pszProvider parameters. If
/// the CSP is found, the function attempts to find a key container within the CSP that matches the name specified by the
/// pszContainer parameter. To acquire the context and the key container of a private key associated with the public key of a
/// certificate, use CryptAcquireCertificatePrivateKey.
/// </para>
/// <para>
/// With the appropriate setting of dwFlags, this function can also create and destroy key containers and can provide access to a
/// CSP with a temporary key container if access to a private key is not required.
/// </para>
/// </summary>
/// <param name="phProv">
/// A pointer to a handle of a CSP. When you have finished using the CSP, release the handle by calling the CryptReleaseContext function.
/// </param>
/// <param name="szContainer">
/// <para>
/// The key container name. This is a null-terminated string that identifies the key container to the CSP. This name is independent
/// of the method used to store the keys. Some CSPs store their key containers internally (in hardware), some use the system
/// registry, and others use the file system. In most cases, when dwFlags is set to CRYPT_VERIFYCONTEXT, pszContainer must be set to
/// <c>NULL</c>. However, for hardware-based CSPs, such as a smart card CSP, can be access publically available information in the
/// specfied container.
/// </para>
/// <para>For more information about the usage of the pszContainer parameter, see Remarks.</para>
/// </param>
/// <param name="szProvider">
/// <para>A null-terminated string that contains the name of the CSP to be used.</para>
/// <para>
/// If this parameter is <c>NULL</c>, the user default provider is used. For more information, see Cryptographic Service Provider
/// Contexts. For a list of available cryptographic providers, see Cryptographic Provider Names.
/// </para>
/// <para>
/// An application can obtain the name of the CSP in use by using the CryptGetProvParam function to read the PP_NAME CSP value in
/// the dwParam parameter.
/// </para>
/// <para>
/// The default CSP can change between operating system releases. To ensure interoperability on different operating system
/// platforms, the CSP should be explicitly set by using this parameter instead of using the default CSP.
/// </para>
/// </param>
/// <param name="dwProvType">
/// Specifies the type of provider to acquire. Defined provider types are discussed in Cryptographic Provider Types.
/// </param>
/// <param name="dwFlags">
/// <para>Flag values. This parameter is usually set to zero, but some applications set one or more of the following flags.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>CRYPT_VERIFYCONTEXT</term>
/// <term>
/// This option is intended for applications that are using ephemeral keys, or applications that do not require access to persisted
/// private keys, such as applications that perform only hashing, encryption, and digital signature verification. Only applications
/// that create signatures or decrypt messages need access to a private key. In most cases, this flag should be set. For file-based
/// CSPs, when this flag is set, the pszContainer parameter must be set to NULL. The application has no access to the persisted
/// private keys of public/private key pairs. When this flag is set, temporary public/private key pairs can be created, but they are
/// not persisted. For hardware-based CSPs, such as a smart card CSP, if the pszContainer parameter is NULL or blank, this flag
/// implies that no access to any keys is required, and that no UI should be presented to the user. This form is used to connect to
/// the CSP to query its capabilities but not to actually use its keys. If the pszContainer parameter is not NULL and not blank,
/// then this flag implies that access to only the publicly available information within the specified container is required. The
/// CSP should not ask for a PIN. Attempts to access private information (for example, the CryptSignHash function) will fail. When
/// CryptAcquireContext is called, many CSPs require input from the owning user before granting access to the private keys in the
/// key container. For example, the private keys can be encrypted, requiring a password from the user before they can be used.
/// However, if the CRYPT_VERIFYCONTEXT flag is specified, access to the private keys is not required and the user interface can be bypassed.
/// </term>
/// </item>
/// <item>
/// <term>CRYPT_NEWKEYSET</term>
/// <term>
/// Creates a new key container with the name specified by pszContainer. If pszContainer is NULL, a key container with the default
/// name is created.
/// </term>
/// </item>
/// <item>
/// <term>CRYPT_MACHINE_KEYSET</term>
/// <term>
/// By default, keys and key containers are stored as user keys. For Base Providers, this means that user key containers are stored
/// in the user's profile. A key container created without this flag by an administrator can be accessed only by the user creating
/// the key container and a user with administration privileges. Windows XP: A key container created without this flag by an
/// administrator can be accessed only by the user creating the key container and the local system account. A key container created
/// without this flag by a user that is not an administrator can be accessed only by the user creating the key container and the
/// local system account. The CRYPT_MACHINE_KEYSET flag can be combined with all of the other flags to indicate that the key
/// container of interest is a computer key container and the CSP treats it as such. For Base Providers, this means that the keys
/// are stored locally on the computer that created the key container. If a key container is to be a computer container, the
/// CRYPT_MACHINE_KEYSET flag must be used with all calls to CryptAcquireContext that reference the computer container. The key
/// container created with CRYPT_MACHINE_KEYSET by an administrator can be accessed only by its creator and by a user with
/// administrator privileges unless access rights to the container are granted using CryptSetProvParam. Windows XP: The key
/// container created with CRYPT_MACHINE_KEYSET by an administrator can be accessed only by its creator and by the local system
/// account unless access rights to the container are granted using CryptSetProvParam. The key container created with
/// CRYPT_MACHINE_KEYSET by a user that is not an administrator can be accessed only by its creator and by the local system account
/// unless access rights to the container are granted using CryptSetProvParam. The CRYPT_MACHINE_KEYSET flag is useful when the user
/// is accessing from a service or user account that did not log on interactively. When key containers are created, most CSPs do not
/// automatically create any public/private key pairs. These keys must be created as a separate step with the CryptGenKey function.
/// </term>
/// </item>
/// <item>
/// <term>CRYPT_DELETEKEYSET</term>
/// <term>
/// Delete the key container specified by pszContainer. If pszContainer is NULL, the key container with the default name is deleted.
/// All key pairs in the key container are also destroyed. When this flag is set, the value returned in phProv is undefined, and
/// thus, the CryptReleaseContext function need not be called afterward.
/// </term>
/// </item>
/// <item>
/// <term>CRYPT_SILENT</term>
/// <term>
/// The application requests that the CSP not display any user interface (UI) for this context. If the CSP must display the UI to
/// operate, the call fails and the NTE_SILENT_CONTEXT error code is set as the last error. In addition, if calls are made to
/// CryptGenKey with the CRYPT_USER_PROTECTED flag with a context that has been acquired with the CRYPT_SILENT flag, the calls fail
/// and the CSP sets NTE_SILENT_CONTEXT. CRYPT_SILENT is intended for use with applications for which the UI cannot be displayed by
/// the CSP.
/// </term>
/// </item>
/// <item>
/// <term>CRYPT_DEFAULT_CONTAINER_OPTIONAL</term>
/// <term>
/// Obtains a context for a smart card CSP that can be used for hashing and symmetric key operations but cannot be used for any
/// operation that requires authentication to a smart card using a PIN. This type of context is most often used to perform
/// operations on an empty smart card, such as setting the PIN by using CryptSetProvParam. This flag can only be used with smart
/// card CSPs. Windows Server 2003 and Windows XP: This flag is not supported.
/// </term>
/// </item>
/// </list>
/// </param>
/// <returns>
/// <para>If the function succeeds, the function returns nonzero ( <c>TRUE</c>).</para>
/// <para>If the function fails, it returns zero ( <c>FALSE</c>). For extended error information, call GetLastError.</para>
/// <para>
/// The error codes prefaced by NTE are generated by the particular CSP being used. Some possible error codes defined in Winerror.h follow.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code/value</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>ERROR_BUSY 107L</term>
/// <term>Some CSPs set this error if the CRYPT_DELETEKEYSET flag value is set and another thread or process is using this key container.</term>
/// </item>
/// <item>
/// <term>ERROR_FILE_NOT_FOUND 2L</term>
/// <term>
/// The profile of the user is not loaded and cannot be found. This happens when the application impersonates a user, for example,
/// the IUSR_ComputerName account.
/// </term>
/// </item>
/// <item>
/// <term>ERROR_INVALID_PARAMETER 87L</term>
/// <term>One of the parameters contains a value that is not valid. This is most often a pointer that is not valid.</term>
/// </item>
/// <item>
/// <term>ERROR_NOT_ENOUGH_MEMORY 8L</term>
/// <term>The operating system ran out of memory during the operation.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_FLAGS 0x80090009L</term>
/// <term>The dwFlags parameter has a value that is not valid.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_KEY_STATE 0x8009000BL</term>
/// <term>The user password has changed since the private keys were encrypted.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_KEYSET 0x80090016L</term>
/// <term>
/// The key container could not be opened. A common cause of this error is that the key container does not exist. To create a key
/// container, call CryptAcquireContext using the CRYPT_NEWKEYSET flag. This error code can also indicate that access to an existing
/// key container is denied. Access rights to the container can be granted by the key set creator by using CryptSetProvParam.
/// </term>
/// </item>
/// <item>
/// <term>NTE_BAD_KEYSET_PARAM 0x8009001FL</term>
/// <term>The pszContainer or pszProvider parameter is set to a value that is not valid.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_PROV_TYPE 0x80090014L</term>
/// <term>The value of the dwProvType parameter is out of range. All provider types must be from 1 through 999, inclusive.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_SIGNATURE 0x80090006L</term>
/// <term>The provider DLL signature could not be verified. Either the DLL or the digital signature has been tampered with.</term>
/// </item>
/// <item>
/// <term>NTE_EXISTS 0x8009000FL</term>
/// <term>The dwFlags parameter is CRYPT_NEWKEYSET, but the key container already exists.</term>
/// </item>
/// <item>
/// <term>NTE_KEYSET_ENTRY_BAD 0x8009001AL</term>
/// <term>The pszContainer key container was found but is corrupt.</term>
/// </item>
/// <item>
/// <term>NTE_KEYSET_NOT_DEF 0x80090019L</term>
/// <term>The requested provider does not exist.</term>
/// </item>
/// <item>
/// <term>NTE_NO_MEMORY 0x8009000EL</term>
/// <term>The CSP ran out of memory during the operation.</term>
/// </item>
/// <item>
/// <term>NTE_PROV_DLL_NOT_FOUND 0x8009001EL</term>
/// <term>The provider DLL file does not exist or is not on the current path.</term>
/// </item>
/// <item>
/// <term>NTE_PROV_TYPE_ENTRY_BAD 0x80090018L</term>
/// <term>
/// The provider type specified by dwProvType is corrupt. This error can relate to either the user default CSP list or the computer
/// default CSP list.
/// </term>
/// </item>
/// <item>
/// <term>NTE_PROV_TYPE_NO_MATCH 0x8009001BL</term>
/// <term>
/// The provider type specified by dwProvType does not match the provider type found. Note that this error can only occur when
/// pszProvider specifies an actual CSP name.
/// </term>
/// </item>
/// <item>
/// <term>NTE_PROV_TYPE_NOT_DEF 0x80090017L</term>
/// <term>No entry exists for the provider type specified by dwProvType.</term>
/// </item>
/// <item>
/// <term>NTE_PROVIDER_DLL_FAIL 0x8009001DL</term>
/// <term>The provider DLL file could not be loaded or failed to initialize.</term>
/// </item>
/// <item>
/// <term>NTE_SIGNATURE_FILE_BAD 0x8009001CL</term>
/// <term>An error occurred while loading the DLL file image, prior to verifying its signature.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The pszContainer parameter specifies the name of the container that is used to hold the key. Each container can contain one key.
/// If you specify the name of an existing container when creating keys, the new key will overwrite a previous one.
/// </para>
/// <para>
/// The combination of the CSP name and the key container name uniquely identifies a single key on the system. If one application
/// tries to modify a key container while another application is using it, unpredictable behavior may result.
/// </para>
/// <para>
/// If you set the pszContainer parameter to <c>NULL</c>, the default key container name is used. When the Microsoft software CSPs
/// are called in this manner, a new container is created each time the <c>CryptAcquireContext</c> function is called. However,
/// different CSPs may behave differently in this regard. In particular, a CSP may have a single default container that is shared by
/// all applications accessing the CSP. Therefore, applications must not use the default key container to store private keys.
/// Instead, either prevent key storage by passing the <c>CRYPT_VERIFYCONTEXT</c> flag in the dwFlags parameter, or use an
/// application-specific container that is unlikely to be used by another application.
/// </para>
/// <para>
/// An application can obtain the name of the key container in use by using the CryptGetProvParam function to read the PP_CONTAINER value.
/// </para>
/// <para>
/// For performance reasons, we recommend that you set the pszContainer parameter to <c>NULL</c> and the dwFlags parameter to
/// <c>CRYPT_VERIFYCONTEXT</c> in all situations where you do not require a persisted key. In particular, consider setting the
/// pszContainer parameter to <c>NULL</c> and the dwFlags parameter to <c>CRYPT_VERIFYCONTEXT</c> for the following scenarios:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>You are creating a hash.</term>
/// </item>
/// <item>
/// <term>You are generating a symmetric key to encrypt or decrypt data.</term>
/// </item>
/// <item>
/// <term>You are deriving a symmetric key from a hash to encrypt or decrypt data.</term>
/// </item>
/// <item>
/// <term>
/// You are verifying a signature. It is possible to import a public key from a PUBLICKEYBLOB or from a certificate by using
/// CryptImportKey or CryptImportPublicKeyInfo. A context can be acquired by using the <c>CRYPT_VERIFYCONTEXT</c> flag if you only
/// plan to import the public key.
/// </term>
/// </item>
/// <item>
/// <term>
/// You plan to export a symmetric key, but not import it within the crypto context's lifetime. A context can be acquired by using
/// the <c>CRYPT_VERIFYCONTEXT</c> flag if you only plan to import the public key for the last two scenarios.
/// </term>
/// </item>
/// <item>
/// <term>You are performing private key operations, but you are not using a persisted private key that is stored in a key container.</term>
/// </item>
/// </list>
/// <para>
/// If you plan to perform private key operations, the best way to acquire a context is to try to open the container. If this
/// attempt fails with NTE_BAD_KEYSET, then create the container by using the <c>CRYPT_NEWKEYSET</c> flag.
/// </para>
/// <para>Examples</para>
/// <para>
/// The following example shows acquiring a cryptographic context and access to public/private key pairs in a key container. If the
/// requested key container does not exist, it is created.
/// </para>
/// <para>
/// For an example that includes the complete context for this example, see Example C Program: Creating a Key Container and
/// Generating Keys. For additional examples, see Example C Program: Using CryptAcquireContext.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptacquirecontexta BOOL CryptAcquireContextA(
// HCRYPTPROV *phProv, LPCSTR szContainer, LPCSTR szProvider, DWORD dwProvType, DWORD dwFlags );
[DllImport(Lib.AdvApi32, SetLastError = true, CharSet = CharSet.Auto)]
[PInvokeData("wincrypt.h", MSDNShortId = "57e13662-3189-4f8d-b90a-d1fbdc09b63c")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptAcquireContext(out SafeHCRYPTPROV phProv, [Optional, MarshalAs(UnmanagedType.LPTStr)] string szContainer, [Optional, MarshalAs(UnmanagedType.LPTStr)] string szProvider, uint dwProvType, CryptAcquireContextFlags dwFlags);
/// <summary>
/// The CryptContextAddRef function adds one to the reference count of an HCRYPTPROV cryptographic service provider (CSP) handle.
/// This function should be used if the CSP handle is included as a member of any structure passed to another function. The
/// CryptReleaseContext function should be called when the CSP handle is no longer needed.
/// </summary>
/// <param name="hProv">
/// HCRYPTPROV handle for which the reference count is being incremented. This handle must have already been created using CryptAcquireContext.
/// </param>
/// <param name="pdwReserved">Reserved for future use and must be <c>NULL</c>.</param>
/// <param name="dwFlags">Reserved for future use and must be zero.</param>
/// <returns>
/// <para>If the function succeeds, the return value is nonzero (TRUE).</para>
/// <para>
/// If the function fails, the return value is zero (FALSE). For extended error information, call GetLastError. One possible error
/// code is the following.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>ERROR_INVALID_PARAMETER</term>
/// <term>One of the parameters contains a value that is not valid. This is most often a pointer that is not valid.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// This function increases the reference count on a HCRYPTPROV handle so that multiple calls to CryptReleaseContext are required to
/// actually release the handle.
/// </para>
/// <para>Examples</para>
/// <para>The following example increments the reference count on an acquired CSP handle.</para>
/// <para>For another example that uses this function, see Example C Program: Using CryptAcquireContext.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptcontextaddref BOOL CryptContextAddRef( HCRYPTPROV
// hProv, DWORD *pdwReserved, DWORD dwFlags );
[DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "074666a7-369c-43bc-97d9-3bcc9703976b")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptContextAddRef(HCRYPTPROV hProv, IntPtr pdwReserved = default, uint dwFlags = 0);
/// <summary>
/// The CryptCreateHash function initiates the hashing of a stream of data. It creates and returns to the calling application a
/// handle to a cryptographic service provider (CSP) hash object. This handle is used in subsequent calls to CryptHashData and
/// CryptHashSessionKey to hash session keys and other streams of data.
/// </summary>
/// <param name="hProv">A handle to a CSP created by a call to CryptAcquireContext.</param>
/// <param name="Algid">
/// <para>An ALG_ID value that identifies the hash algorithm to use.</para>
/// <para>Valid values for this parameter vary, depending on the CSP that is used. For a list of default algorithms, see Remarks.</para>
/// </param>
/// <param name="hKey">
/// <para>
/// If the type of hash algorithm is a keyed hash, such as the Hash-Based Message Authentication Code (HMAC) or Message
/// Authentication Code (MAC) algorithm, the key for the hash is passed in this parameter. For nonkeyed algorithms, this parameter
/// must be set to zero.
/// </para>
/// <para>
/// For keyed algorithms, the key must be to a block cipher key, such as RC2, that has a cipher mode of Cipher Block Chaining (CBC).
/// </para>
/// </param>
/// <param name="dwFlags">
/// <para>The following flag value is defined.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>CRYPT_SECRETDIGEST 0x00000001</term>
/// <term>This flag is not used.</term>
/// </item>
/// </list>
/// </param>
/// <param name="phHash">
/// The address to which the function copies a handle to the new hash object. When you have finished using the hash object, release
/// the handle by calling the CryptDestroyHash function.
/// </param>
/// <returns>
/// <para>If the function succeeds, the function returns <c>TRUE</c>.</para>
/// <para>If the function fails, it returns <c>FALSE</c>. For extended error information, call GetLastError.</para>
/// <para>
/// The error codes prefaced by NTE are generated by the particular CSP you are using. The following table shows some of the
/// possible error codes.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>ERROR_INVALID_HANDLE</term>
/// <term>One of the parameters specifies a handle that is not valid.</term>
/// </item>
/// <item>
/// <term>ERROR_INVALID_PARAMETER</term>
/// <term>One of the parameters contains a value that is not valid. This is most often a pointer that is not valid.</term>
/// </item>
/// <item>
/// <term>ERROR_NOT_ENOUGH_MEMORY</term>
/// <term>The operating system ran out of memory during the operation.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_ALGID</term>
/// <term>The Algid parameter specifies an algorithm that this CSP does not support.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_FLAGS</term>
/// <term>The dwFlags parameter is nonzero.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_KEY</term>
/// <term>
/// A keyed hash algorithm, such as CALG_MAC, is specified by Algid, and the hKey parameter is either zero or it specifies a key
/// handle that is not valid. This error code is also returned if the key is to a stream cipher or if the cipher mode is anything
/// other than CBC.
/// </term>
/// </item>
/// <item>
/// <term>NTE_NO_MEMORY</term>
/// <term>The CSP ran out of memory during the operation.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>For a list of Microsoft service providers and the algorithms they implement, see Microsoft Cryptographic Service Providers.</para>
/// <para>
/// The computation of the actual hash is done with the CryptHashData and CryptHashSessionKey functions. These require a handle to
/// the hash object. After all the data has been added to the hash object, any of the following operations can be performed:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>The hash value can be retrieved by using CryptGetHashParam.</term>
/// </item>
/// <item>
/// <term>A session key can be derived by using CryptDeriveKey.</term>
/// </item>
/// <item>
/// <term>The hash can be signed by using CryptSignHash.</term>
/// </item>
/// <item>
/// <term>A signature can be verified by using CryptVerifySignature.</term>
/// </item>
/// </list>
/// <para>After one of the functions from this list has been called, CryptHashData and CryptHashSessionKey cannot be called.</para>
/// <para>Examples</para>
/// <para>
/// The following example shows initiating the hashing of a stream of data. It creates and returns to the calling application a
/// handle to a hash object. This handle is used in subsequent calls to CryptHashData and CryptHashSessionKey to hash any stream of
/// data. For an example that includes the complete context for this example, see Example C Program: Creating and Hashing a Session
/// Key. For another example that uses this function, see Example C Program: Signing a Hash and Verifying the Hash Signature.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptcreatehash BOOL CryptCreateHash( HCRYPTPROV hProv,
// ALG_ID Algid, HCRYPTKEY hKey, DWORD dwFlags, HCRYPTHASH *phHash );
[DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "05e3db57-8d83-48e2-8590-68039ea27253")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptCreateHash(HCRYPTPROV hProv, ALG_ID Algid, HCRYPTKEY hKey, [Optional] uint dwFlags, out SafeHCRYPTHASH phHash);
/// <summary>
/// <para>The CryptDecrypt function decrypts data previously encrypted by using the CryptEncrypt function.</para>
/// <para>
/// Important changes to support Secure/Multipurpose Internet Mail Extensions (S/MIME) email interoperability have been made to
/// CryptoAPI that affect the handling of enveloped messages. For more information, see the Remarks section of CryptMsgOpenToEncode.
/// </para>
/// </summary>
/// <param name="hKey">
/// <para>
/// A handle to the key to use for the decryption. An application obtains this handle by using either the CryptGenKey or
/// CryptImportKey function.
/// </para>
/// <para>This key specifies the decryption algorithm to be used.</para>
/// </param>
/// <param name="hHash">
/// <para>
/// A handle to a hash object. If data is to be decrypted and hashed simultaneously, a handle to a hash object is passed in this
/// parameter. The hash value is updated with the decrypted plaintext. This option is useful when simultaneously decrypting and
/// verifying a signature.
/// </para>
/// <para>
/// Before calling <c>CryptDecrypt</c>, the application must obtain a handle to the hash object by calling the CryptCreateHash
/// function. After the decryption is complete, the hash value can be obtained by using the CryptGetHashParam function, it can also
/// be signed by using the CryptSignHash function, or it can be used to verify a digital signature by using the CryptVerifySignature function.
/// </para>
/// <para>If no hash is to be done, this parameter must be zero.</para>
/// </param>
/// <param name="Final">
/// A Boolean value that specifies whether this is the last section in a series being decrypted. This value is <c>TRUE</c> if this
/// is the last or only block. If this is not the last block, this value is <c>FALSE</c>. For more information, see Remarks.
/// </param>
/// <param name="dwFlags">
/// <para>The following flag values are defined.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>CRYPT_OAEP 0x00000040</term>
/// <term>
/// Use Optimal Asymmetric Encryption Padding (OAEP) (PKCS #1 version 2). This flag is only supported by the Microsoft Enhanced
/// Cryptographic Provider with RSA encryption/decryption. This flag cannot be combined with the CRYPT_DECRYPT_RSA_NO_PADDING_CHECK flag.
/// </term>
/// </item>
/// <item>
/// <term>CRYPT_DECRYPT_RSA_NO_PADDING_CHECK 0x00000020</term>
/// <term>
/// Perform the decryption on the BLOB without checking the padding. This flag is only supported by the Microsoft Enhanced
/// Cryptographic Provider with RSA encryption/decryption. This flag cannot be combined with the CRYPT_OAEP flag.
/// </term>
/// </item>
/// </list>
/// </param>
/// <param name="pbData">
/// <para>
/// A pointer to a buffer that contains the data to be decrypted. After the decryption has been performed, the plaintext is placed
/// back into this same buffer.
/// </para>
/// <para>The number of encrypted bytes in this buffer is specified by pdwDataLen.</para>
/// </param>
/// <param name="pdwDataLen">
/// <para>
/// A pointer to a <c>DWORD</c> value that indicates the length of the pbData buffer. Before calling this function, the calling
/// application sets the <c>DWORD</c> value to the number of bytes to be decrypted. Upon return, the <c>DWORD</c> value contains the
/// number of bytes of the decrypted plaintext.
/// </para>
/// <para>
/// When a block cipher is used, this data length must be a multiple of the block size unless this is the final section of data to
/// be decrypted and the Final parameter is <c>TRUE</c>.
/// </para>
/// </param>
/// <returns>
/// <para>If the function succeeds, the function returns nonzero ( <c>TRUE</c>).</para>
/// <para>If the function fails, it returns zero ( <c>FALSE</c>). For extended error information, call GetLastError.</para>
/// <para>The error codes prefaced by NTE are generated by the particular CSP being used. Some possible error codes follow.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>ERROR_INVALID_HANDLE</term>
/// <term>One of the parameters specifies a handle that is not valid.</term>
/// </item>
/// <item>
/// <term>ERROR_INVALID_PARAMETER</term>
/// <term>One of the parameters contains a value that is not valid. This is most often a pointer that is not valid.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_ALGID</term>
/// <term>The hKey session key specifies an algorithm that this CSP does not support.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_DATA</term>
/// <term>
/// The data to be decrypted is not valid. For example, when a block cipher is used and the Final flag is FALSE, the value specified
/// by pdwDataLen must be a multiple of the block size. This error can also be returned when the padding is found to be not valid.
/// </term>
/// </item>
/// <item>
/// <term>NTE_BAD_FLAGS</term>
/// <term>The dwFlags parameter is nonzero.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_HASH</term>
/// <term>The hHash parameter contains a handle that is not valid.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_KEY</term>
/// <term>The hKey parameter does not contain a valid handle to a key.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_LEN</term>
/// <term>The size of the output buffer is too small to hold the generated plaintext.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_UID</term>
/// <term>The CSP context that was specified when the key was created cannot be found.</term>
/// </item>
/// <item>
/// <term>NTE_DOUBLE_ENCRYPT</term>
/// <term>The application attempted to decrypt the same data twice.</term>
/// </item>
/// <item>
/// <term>NTE_FAIL</term>
/// <term>The function failed in some unexpected way.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// If a large amount of data is to be decrypted, it can be done in sections by calling <c>CryptDecrypt</c> repeatedly. The Final
/// parameter must be set to <c>TRUE</c> only on the last call to <c>CryptDecrypt</c>, so that the decryption engine can properly
/// finish the decryption process. The following extra actions are performed when Final is <c>TRUE</c>:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>
/// If the key is a block cipher key, the data is padded to a multiple of the block size of the cipher. To find the block size of a
/// cipher, use CryptGetKeyParam to get the KP_BLOCKLEN value of the key.
/// </term>
/// </item>
/// <item>
/// <term>
/// If the cipher is operating in a chaining mode, the next <c>CryptDecrypt</c> operation resets the cipher's feedback register to
/// the KP_IV value of the key.
/// </term>
/// </item>
/// <item>
/// <term>If the cipher is a stream cipher, the next <c>CryptDecrypt</c> call resets the cipher to its initial state.</term>
/// </item>
/// </list>
/// <para>
/// There is no way to set the cipher's feedback register to the KP_IV value of the key without setting the Final parameter to
/// <c>TRUE</c>. If this is necessary, as in the case where you do not want to add an additional padding block or change the size of
/// each block, you can simulate this by creating a duplicate of the original key by using the CryptDuplicateKey function, and
/// passing the duplicate key to the <c>CryptDecrypt</c> function. This causes the KP_IV of the original key to be placed in the
/// duplicate key. After you create or import the original key, you cannot use the original key for encryption because the feedback
/// register of the key will be changed. The following pseudocode shows how this can be done.
/// </para>
/// <para>
/// The Microsoft Enhanced Cryptographic Provider supports direct encryption with RSA public keys and decryption with RSA private
/// keys. The encryption uses PKCS #1 padding. On decryption, this padding is verified. The length of ciphertext data to be
/// decrypted must be the same length as the modulus of the RSA key used to decrypt the data. If the ciphertext has zeros in the
/// most significant bytes, these bytes must be included in the input data buffer and in the input buffer length. The ciphertext
/// must be in little-endian format.
/// </para>
/// <para>Examples</para>
/// <para>For an example that uses this function, see Example C Program: Decrypting a File.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptdecrypt BOOL CryptDecrypt( HCRYPTKEY hKey,
// HCRYPTHASH hHash, BOOL Final, DWORD dwFlags, BYTE *pbData, DWORD *pdwDataLen );
[DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "7c3d2838-6fd1-4f6c-9586-8b94b459a31a")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptDecrypt(HCRYPTKEY hKey, HCRYPTHASH hHash, [MarshalAs(UnmanagedType.Bool)] bool Final, CryptDecryptFlags dwFlags, [In, Out] IntPtr pbData, ref uint pdwDataLen);
/// <summary>
/// <para>The CryptDecrypt function decrypts data previously encrypted by using the CryptEncrypt function.</para>
/// <para>
/// Important changes to support Secure/Multipurpose Internet Mail Extensions (S/MIME) email interoperability have been made to
/// CryptoAPI that affect the handling of enveloped messages. For more information, see the Remarks section of CryptMsgOpenToEncode.
/// </para>
/// </summary>
/// <param name="hKey">
/// <para>
/// A handle to the key to use for the decryption. An application obtains this handle by using either the CryptGenKey or
/// CryptImportKey function.
/// </para>
/// <para>This key specifies the decryption algorithm to be used.</para>
/// </param>
/// <param name="hHash">
/// <para>
/// A handle to a hash object. If data is to be decrypted and hashed simultaneously, a handle to a hash object is passed in this
/// parameter. The hash value is updated with the decrypted plaintext. This option is useful when simultaneously decrypting and
/// verifying a signature.
/// </para>
/// <para>
/// Before calling <c>CryptDecrypt</c>, the application must obtain a handle to the hash object by calling the CryptCreateHash
/// function. After the decryption is complete, the hash value can be obtained by using the CryptGetHashParam function, it can also
/// be signed by using the CryptSignHash function, or it can be used to verify a digital signature by using the CryptVerifySignature function.
/// </para>
/// <para>If no hash is to be done, this parameter must be zero.</para>
/// </param>
/// <param name="Final">
/// A Boolean value that specifies whether this is the last section in a series being decrypted. This value is <c>TRUE</c> if this
/// is the last or only block. If this is not the last block, this value is <c>FALSE</c>. For more information, see Remarks.
/// </param>
/// <param name="dwFlags">
/// <para>The following flag values are defined.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>CRYPT_OAEP 0x00000040</term>
/// <term>
/// Use Optimal Asymmetric Encryption Padding (OAEP) (PKCS #1 version 2). This flag is only supported by the Microsoft Enhanced
/// Cryptographic Provider with RSA encryption/decryption. This flag cannot be combined with the CRYPT_DECRYPT_RSA_NO_PADDING_CHECK flag.
/// </term>
/// </item>
/// <item>
/// <term>CRYPT_DECRYPT_RSA_NO_PADDING_CHECK 0x00000020</term>
/// <term>
/// Perform the decryption on the BLOB without checking the padding. This flag is only supported by the Microsoft Enhanced
/// Cryptographic Provider with RSA encryption/decryption. This flag cannot be combined with the CRYPT_OAEP flag.
/// </term>
/// </item>
/// </list>
/// </param>
/// <param name="pbData">
/// <para>
/// A pointer to a buffer that contains the data to be decrypted. After the decryption has been performed, the plaintext is placed
/// back into this same buffer.
/// </para>
/// <para>The number of encrypted bytes in this buffer is specified by pdwDataLen.</para>
/// </param>
/// <param name="pdwDataLen">
/// <para>
/// A pointer to a <c>DWORD</c> value that indicates the length of the pbData buffer. Before calling this function, the calling
/// application sets the <c>DWORD</c> value to the number of bytes to be decrypted. Upon return, the <c>DWORD</c> value contains the
/// number of bytes of the decrypted plaintext.
/// </para>
/// <para>
/// When a block cipher is used, this data length must be a multiple of the block size unless this is the final section of data to
/// be decrypted and the Final parameter is <c>TRUE</c>.
/// </para>
/// </param>
/// <returns>
/// <para>If the function succeeds, the function returns nonzero ( <c>TRUE</c>).</para>
/// <para>If the function fails, it returns zero ( <c>FALSE</c>). For extended error information, call GetLastError.</para>
/// <para>The error codes prefaced by NTE are generated by the particular CSP being used. Some possible error codes follow.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>ERROR_INVALID_HANDLE</term>
/// <term>One of the parameters specifies a handle that is not valid.</term>
/// </item>
/// <item>
/// <term>ERROR_INVALID_PARAMETER</term>
/// <term>One of the parameters contains a value that is not valid. This is most often a pointer that is not valid.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_ALGID</term>
/// <term>The hKey session key specifies an algorithm that this CSP does not support.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_DATA</term>
/// <term>
/// The data to be decrypted is not valid. For example, when a block cipher is used and the Final flag is FALSE, the value specified
/// by pdwDataLen must be a multiple of the block size. This error can also be returned when the padding is found to be not valid.
/// </term>
/// </item>
/// <item>
/// <term>NTE_BAD_FLAGS</term>
/// <term>The dwFlags parameter is nonzero.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_HASH</term>
/// <term>The hHash parameter contains a handle that is not valid.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_KEY</term>
/// <term>The hKey parameter does not contain a valid handle to a key.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_LEN</term>
/// <term>The size of the output buffer is too small to hold the generated plaintext.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_UID</term>
/// <term>The CSP context that was specified when the key was created cannot be found.</term>
/// </item>
/// <item>
/// <term>NTE_DOUBLE_ENCRYPT</term>
/// <term>The application attempted to decrypt the same data twice.</term>
/// </item>
/// <item>
/// <term>NTE_FAIL</term>
/// <term>The function failed in some unexpected way.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// If a large amount of data is to be decrypted, it can be done in sections by calling <c>CryptDecrypt</c> repeatedly. The Final
/// parameter must be set to <c>TRUE</c> only on the last call to <c>CryptDecrypt</c>, so that the decryption engine can properly
/// finish the decryption process. The following extra actions are performed when Final is <c>TRUE</c>:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>
/// If the key is a block cipher key, the data is padded to a multiple of the block size of the cipher. To find the block size of a
/// cipher, use CryptGetKeyParam to get the KP_BLOCKLEN value of the key.
/// </term>
/// </item>
/// <item>
/// <term>
/// If the cipher is operating in a chaining mode, the next <c>CryptDecrypt</c> operation resets the cipher's feedback register to
/// the KP_IV value of the key.
/// </term>
/// </item>
/// <item>
/// <term>If the cipher is a stream cipher, the next <c>CryptDecrypt</c> call resets the cipher to its initial state.</term>
/// </item>
/// </list>
/// <para>
/// There is no way to set the cipher's feedback register to the KP_IV value of the key without setting the Final parameter to
/// <c>TRUE</c>. If this is necessary, as in the case where you do not want to add an additional padding block or change the size of
/// each block, you can simulate this by creating a duplicate of the original key by using the CryptDuplicateKey function, and
/// passing the duplicate key to the <c>CryptDecrypt</c> function. This causes the KP_IV of the original key to be placed in the
/// duplicate key. After you create or import the original key, you cannot use the original key for encryption because the feedback
/// register of the key will be changed. The following pseudocode shows how this can be done.
/// </para>
/// <para>
/// The Microsoft Enhanced Cryptographic Provider supports direct encryption with RSA public keys and decryption with RSA private
/// keys. The encryption uses PKCS #1 padding. On decryption, this padding is verified. The length of ciphertext data to be
/// decrypted must be the same length as the modulus of the RSA key used to decrypt the data. If the ciphertext has zeros in the
/// most significant bytes, these bytes must be included in the input data buffer and in the input buffer length. The ciphertext
/// must be in little-endian format.
/// </para>
/// <para>Examples</para>
/// <para>For an example that uses this function, see Example C Program: Decrypting a File.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptdecrypt BOOL CryptDecrypt( HCRYPTKEY hKey,
// HCRYPTHASH hHash, BOOL Final, DWORD dwFlags, BYTE *pbData, DWORD *pdwDataLen );
[DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "7c3d2838-6fd1-4f6c-9586-8b94b459a31a")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptDecrypt(HCRYPTKEY hKey, HCRYPTHASH hHash, [MarshalAs(UnmanagedType.Bool)] bool Final, CryptDecryptFlags dwFlags, [In, Out] byte[] pbData, ref int pdwDataLen);
/// <summary>
/// <para>
/// The CryptDeriveKey function generates cryptographic session keys derived from a base data value. This function guarantees that
/// when the same cryptographic service provider (CSP) and algorithms are used, the keys generated from the same base data are
/// identical. The base data can be a password or any other user data.
/// </para>
/// <para>
/// This function is the same as CryptGenKey, except that the generated session keys are derived from base data instead of being
/// random. <c>CryptDeriveKey</c> can only be used to generate session keys. It cannot generate public/private key pairs.
/// </para>
/// <para>
/// A handle to the session key is returned in the phKey parameter. This handle can be used with any CryptoAPI function that
/// requires a key handle.
/// </para>
/// </summary>
/// <param name="hProv">A HCRYPTPROV handle of a CSP created by a call to CryptAcquireContext.</param>
/// <param name="Algid">
/// <para>
/// An ALG_ID structure that identifies the symmetric encryption algorithm for which the key is to be generated. The algorithms
/// available will most likely be different for each CSP. For more information about which algorithm identifier is used by the
/// different providers for the key specs AT_KEYEXCHANGE and AT_SIGNATURE, see <c>ALG_ID</c>.
/// </para>
/// <para>
/// For more information about ALG_ID values to use with the Microsoft Base Cryptographic Provider, see Base Provider Algorithms.
/// For more information about <c>ALG_ID</c> values to use with the Microsoft Strong Cryptographic Provider or the Microsoft
/// Enhanced Cryptographic Provider, see Enhanced Provider Algorithms.
/// </para>
/// </param>
/// <param name="hBaseData">
/// <para>A handle to a hash object that has been fed the exact base data.</para>
/// <para>
/// To obtain this handle, an application must first create a hash object with CryptCreateHash and then add the base data to the
/// hash object with CryptHashData. This process is described in detail in Hashes and Digital Signatures.
/// </para>
/// </param>
/// <param name="dwFlags">
/// <para>Specifies the type of key generated.</para>
/// <para>
/// The sizes of a session key can be set when the key is generated. The key size, representing the length of the key modulus in
/// bits, is set with the upper 16 bits of this parameter. Thus, if a 128-bit RC4 session key is to be generated, the value
/// 0x00800000 is combined with any other dwFlags predefined value with a bitwise- <c>OR</c> operation. Due to changing export
/// control restrictions, the default CSP and default key length may change between operating system releases. It is important that
/// both the encryption and decryption use the same CSP and that the key length be explicitly set using the dwFlags parameter to
/// ensure interoperability on different operating system platforms.
/// </para>
/// <para>
/// The lower 16 bits of this parameter can be zero or you can specify one or more of the following flags by using the bitwise-
/// <c>OR</c> operator to combine them.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>CRYPT_CREATE_SALT</term>
/// <term>
/// Typically, when a session key is made from a hash value, there are a number of leftover bits. For example, if the hash value is
/// 128 bits and the session key is 40 bits, there will be 88 bits left over. If this flag is set, then the key is assigned a salt
/// value based on the unused hash value bits. You can retrieve this salt value by using the CryptGetKeyParam function with the
/// dwParam parameter set to KP_SALT. If this flag is not set, then the key is given a salt value of zero. When keys with nonzero
/// salt values are exported (by using CryptExportKey), the salt value must also be obtained and kept with the key BLOB.
/// </term>
/// </item>
/// <item>
/// <term>CRYPT_EXPORTABLE</term>
/// <term>
/// If this flag is set, the session key can be transferred out of the CSP into a key BLOB through the CryptExportKey function.
/// Because keys generally must be exportable, this flag should usually be set. If this flag is not set, then the session key is not
/// exportable. This means the key is available only within the current session and only the application that created it is able to
/// use it. This flag does not apply to public/private key pairs.
/// </term>
/// </item>
/// <item>
/// <term>CRYPT_NO_SALT</term>
/// <term>
/// This flag specifies that a no salt value gets allocated for a 40-bit symmetric key. For more information, see Salt Value Functionality.
/// </term>
/// </item>
/// <item>
/// <term>CRYPT_UPDATE_KEY</term>
/// <term>
/// Some CSPs use session keys that are derived from multiple hash values. When this is the case, CryptDeriveKey must be called
/// multiple times. If this flag is set, a new session key is not generated. Instead, the key specified by phKey is modified. The
/// precise behavior of this flag is dependent on the type of key being generated and on the particular CSP being used. Microsoft
/// cryptographic service providers ignore this flag.
/// </term>
/// </item>
/// <item>
/// <term>CRYPT_SERVER 1024 (0x400)</term>
/// <term>
/// This flag is used only with Schannel providers. If this flag is set, the key to be generated is a server-write key; otherwise,
/// it is a client-write key.
/// </term>
/// </item>
/// </list>
/// </param>
/// <param name="phKey">
/// A pointer to a HCRYPTKEY variable to receive the address of the handle of the newly generated key. When you have finished using
/// the key, release the handle by calling the CryptDestroyKey function.
/// </param>
/// <returns>
/// <para>If the function succeeds, the function returns nonzero ( <c>TRUE</c>).</para>
/// <para>If the function fails, it returns zero ( <c>FALSE</c>). For extended error information, call GetLastError.</para>
/// <para>
/// The error codes prefaced by "NTE" are generated by the particular CSP being used. Some possible error codes are listed in the
/// following table.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>ERROR_INVALID_HANDLE</term>
/// <term>One of the parameters specifies a handle that is not valid.</term>
/// </item>
/// <item>
/// <term>ERROR_INVALID_PARAMETER</term>
/// <term>One of the parameters contains a value that is not valid. This is most often a pointer that is not valid.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_ALGID</term>
/// <term>The Algid parameter specifies an algorithm that this CSP does not support.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_FLAGS</term>
/// <term>The dwFlags parameter contains a value that is not valid.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_HASH</term>
/// <term>The hBaseData parameter does not contain a valid handle to a hash object.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_HASH_STATE</term>
/// <term>An attempt was made to add data to a hash object that is already marked "finished."</term>
/// </item>
/// <item>
/// <term>NTE_BAD_UID</term>
/// <term>The hProv parameter does not contain a valid context handle.</term>
/// </item>
/// <item>
/// <term>NTE_FAIL</term>
/// <term>The function failed in some unexpected way.</term>
/// </item>
/// <item>
/// <term>NTE_SILENT_CONTEXT</term>
/// <term>The provider could not perform the action because the context was acquired as silent.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// When keys are generated for symmetric block ciphers, the key by default is set up in cipher block chaining (CBC) mode with an
/// initialization vector of zero. This cipher mode provides a good default method for bulk-encrypting data. To change these
/// parameters, use the CryptSetKeyParam function.
/// </para>
/// <para>
/// The <c>CryptDeriveKey</c> function completes the hash. After <c>CryptDeriveKey</c> has been called, no more data can be added to
/// the hash. Additional calls to CryptHashData or CryptHashSessionKey fail. After the application is done with the hash,
/// CryptDestroyHash must be called to destroy the hash object.
/// </para>
/// <para>To choose an appropriate key length, the following methods are recommended.</para>
/// <list type="bullet">
/// <item>
/// <term>
/// To enumerate the algorithms that the CSP supports and to get maximum and minimum key lengths for each algorithm, call
/// CryptGetProvParam with PP_ENUMALGS_EX.
/// </term>
/// </item>
/// <item>
/// <term>
/// Use the minimum and maximum lengths to choose an appropriate key length. It is not always advisable to choose the maximum length
/// because this can lead to performance issues.
/// </term>
/// </item>
/// <item>
/// <term>After the desired key length has been chosen, use the upper 16 bits of the dwFlags parameter to specify the key length.</term>
/// </item>
/// </list>
/// <para>
/// Let <c>n</c> be the required derived key length, in bytes. The derived key is the first <c>n</c> bytes of the hash value after
/// the hash computation has been completed by <c>CryptDeriveKey</c>. If the hash is not a member of the SHA-2 family and the
/// required key is for either 3DES or AES, the key is derived as follows:
/// </para>
/// <list type="number">
/// <item>
/// <term>
/// Form a 64-byte buffer by repeating the constant <c>0x36</c> 64 times. Let <c>k</c> be the length of the hash value that is
/// represented by the input parameter hBaseData. Set the first <c>k</c> bytes of the buffer to the result of an <c>XOR</c>
/// operation of the first <c>k</c> bytes of the buffer with the hash value that is represented by the input parameter hBaseData.
/// </term>
/// </item>
/// <item>
/// <term>
/// Form a 64-byte buffer by repeating the constant <c>0x5C</c> 64 times. Set the first <c>k</c> bytes of the buffer to the result
/// of an <c>XOR</c> operation of the first <c>k</c> bytes of the buffer with the hash value that is represented by the input
/// parameter hBaseData.
/// </term>
/// </item>
/// <item>
/// <term>
/// Hash the result of step 1 by using the same hash algorithm as that used to compute the hash value that is represented by the
/// hBaseData parameter.
/// </term>
/// </item>
/// <item>
/// <term>
/// Hash the result of step 2 by using the same hash algorithm as that used to compute the hash value that is represented by the
/// hBaseData parameter.
/// </term>
/// </item>
/// <item>
/// <term>Concatenate the result of step 3 with the result of step 4.</term>
/// </item>
/// <item>
/// <term>Use the first <c>n</c> bytes of the result of step 5 as the derived key.</term>
/// </item>
/// </list>
/// <para>
/// The default RSA Full Cryptographic Service Provider is the Microsoft RSA Strong Cryptographic Provider. The default DSS
/// Signature Diffie-Hellman Cryptographic Service Provider is the Microsoft Enhanced DSS Diffie-Hellman Cryptographic Provider.
/// Each of these CSPs has a default 128-bit symmetric key length for RC2 and RC4.
/// </para>
/// <para>The following table lists minimum, default, and maximum key lengths for session key by algorithm and provider.</para>
/// <list type="table">
/// <listheader>
/// <term>Provider</term>
/// <term>Algorithms</term>
/// <term>Minimum key length</term>
/// <term>Default key length</term>
/// <term>Maximum key length</term>
/// </listheader>
/// <item>
/// <term>MS Base</term>
/// <term>RC4 and RC2</term>
/// <term>40</term>
/// <term>40</term>
/// <term>56</term>
/// </item>
/// <item>
/// <term>MS Base</term>
/// <term>DES</term>
/// <term>56</term>
/// <term>56</term>
/// <term>56</term>
/// </item>
/// <item>
/// <term>MS Enhanced</term>
/// <term>RC4 and RC2</term>
/// <term>40</term>
/// <term>128</term>
/// <term>128</term>
/// </item>
/// <item>
/// <term>MS Enhanced</term>
/// <term>DES</term>
/// <term>56</term>
/// <term>56</term>
/// <term>56</term>
/// </item>
/// <item>
/// <term>MS Enhanced</term>
/// <term>3DES 112</term>
/// <term>112</term>
/// <term>112</term>
/// <term>112</term>
/// </item>
/// <item>
/// <term>MS Enhanced</term>
/// <term>3DES</term>
/// <term>168</term>
/// <term>168</term>
/// <term>168</term>
/// </item>
/// <item>
/// <term>MS Strong</term>
/// <term>RC4 and RC2</term>
/// <term>40</term>
/// <term>128</term>
/// <term>128</term>
/// </item>
/// <item>
/// <term>MS Strong</term>
/// <term>DES</term>
/// <term>56</term>
/// <term>56</term>
/// <term>56</term>
/// </item>
/// <item>
/// <term>MS Strong</term>
/// <term>3DES 112</term>
/// <term>112</term>
/// <term>112</term>
/// <term>112</term>
/// </item>
/// <item>
/// <term>MS Strong</term>
/// <term>3DES</term>
/// <term>168</term>
/// <term>168</term>
/// <term>168</term>
/// </item>
/// <item>
/// <term>DSS/DH Base</term>
/// <term>RC4 and RC2</term>
/// <term>40</term>
/// <term>40</term>
/// <term>56</term>
/// </item>
/// <item>
/// <term>DSS/DH Base</term>
/// <term>Cylink MEK</term>
/// <term>40</term>
/// <term>40</term>
/// <term>40</term>
/// </item>
/// <item>
/// <term>DSS/DH Base</term>
/// <term>DES</term>
/// <term>56</term>
/// <term>56</term>
/// <term>56</term>
/// </item>
/// <item>
/// <term>DSS/DH Enh</term>
/// <term>RC4 and RC2</term>
/// <term>40</term>
/// <term>128</term>
/// <term>128</term>
/// </item>
/// <item>
/// <term>DSS/DH Enh</term>
/// <term>Cylink MEK</term>
/// <term>40</term>
/// <term>40</term>
/// <term>40</term>
/// </item>
/// <item>
/// <term>DSS/DH Enh</term>
/// <term>DES</term>
/// <term>56</term>
/// <term>56</term>
/// <term>56</term>
/// </item>
/// <item>
/// <term>DSS/DH Enh</term>
/// <term>3DES 112</term>
/// <term>112</term>
/// <term>112</term>
/// <term>112</term>
/// </item>
/// <item>
/// <term>DSS/DH Enh</term>
/// <term>3DES</term>
/// <term>168</term>
/// <term>168</term>
/// <term>168</term>
/// </item>
/// </list>
/// <para>Examples</para>
/// <para>For an example that uses this function, see Example C Program: Deriving a Session Key from a Password.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptderivekey BOOL CryptDeriveKey( HCRYPTPROV hProv,
// ALG_ID Algid, HCRYPTHASH hBaseData, DWORD dwFlags, HCRYPTKEY *phKey );
[DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "b031e3b4-0102-400e-96db-019d31402adc")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptDeriveKey(HCRYPTPROV hProv, ALG_ID Algid, HCRYPTHASH hBaseData, CryptGenKeyFlags dwFlags, out SafeHCRYPTKEY phKey);
/// <summary>
/// The CryptDestroyHash function destroys the hash object referenced by the hHash parameter. After a hash object has been
/// destroyed, it can no longer be used.
/// <para>To help ensure security, we recommend that hash objects be destroyed after they have been used.</para>
/// </summary>
/// <param name="hHash">The handle of the hash object to be destroyed.</param>
/// <returns>
/// <para>If the function succeeds, the return value is nonzero.</para>
/// <para>If the function fails, the return value is zero. For extended error information, call GetLastError.</para>
/// <para>
/// The error codes prefaced by "NTE" are generated by the particular cryptographic service provider (CSP) you are using. Some
/// possible error codes follow.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>ERROR_BUSY</term>
/// <term>The hash object specified by hHash is currently being used and cannot be destroyed.</term>
/// </item>
/// <item>
/// <term>ERROR_INVALID_HANDLE</term>
/// <term>The hHash parameter specifies a handle that is not valid.</term>
/// </item>
/// <item>
/// <term>ERROR_INVALID_PARAMETER</term>
/// <term>The hHash parameter contains a value that is not valid.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_ALGID</term>
/// <term>The hHash handle specifies an algorithm that this CSP does not support.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_HASH</term>
/// <term>The hash object specified by the hHash parameter is not valid.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_UID</term>
/// <term>The CSP context that was specified when the hash object was created cannot be found.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// When a hash object is destroyed, many CSPs overwrite the memory in the CSP where the hash object was held. The CSP memory is
/// then freed.
/// </para>
/// <para>There should be a one-to-one correspondence between calls to CryptCreateHash and <c>CryptDestroyHash</c>.</para>
/// <para>
/// All hash objects that have been created by using a specific CSP must be destroyed before that CSP handle is released with the
/// CryptReleaseContext function.
/// </para>
/// <para>Examples</para>
/// <para>For an example that uses the <c>CryptDestroyHash</c> function, see Example C Program: Creating and Hashing a Session Key.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptdestroyhash BOOL CryptDestroyHash( HCRYPTHASH hHash );
[DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "0a4d6086-5c4c-4e1e-9ab9-b35ee49ffcae")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptDestroyHash(HCRYPTHASH hHash);
/// <summary>
/// The CryptDestroyKey function releases the handle referenced by the hKey parameter. After a key handle has been released, it is
/// no longer valid and cannot be used again.
/// <para>
/// If the handle refers to a session key, or to a public key that has been imported into the cryptographic service provider (CSP)
/// through CryptImportKey, this function destroys the key and frees the memory that the key used. Many CSPs overwrite the memory
/// where the key was held before freeing it. However, the underlying public/private key pair is not destroyed by this function.
/// Only the handle is destroyed.
/// </para>
/// </summary>
/// <param name="hKey">The handle of the key to be destroyed.</param>
/// <returns>
/// <para>If the function succeeds, the return value is nonzero.</para>
/// <para>If the function fails, the return value is zero. For extended error information, call GetLastError.</para>
/// <para>
/// The error codes prefaced by "NTE" are generated by the particular CSP being used. Some possible error codes are listed in the
/// following table.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>ERROR_BUSY</term>
/// <term>The key object specified by hKey is currently being used and cannot be destroyed.</term>
/// </item>
/// <item>
/// <term>ERROR_INVALID_HANDLE</term>
/// <term>The hKey parameter specifies a handle that is not valid.</term>
/// </item>
/// <item>
/// <term>ERROR_INVALID_PARAMETER</term>
/// <term>The hKey parameter contains a value that is not valid.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_KEY</term>
/// <term>The hKey parameter does not contain a valid handle to a key.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_UID</term>
/// <term>The CSP context that was specified when the key was created cannot be found.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// Keys take up both operating system's memory space and the CSP's memory space. Some CSPs are implemented in hardware with limited
/// memory resources. Applications must destroy all keys with the <c>CryptDestroyKey</c> function when they are finished with them.
/// </para>
/// <para>
/// All key handles that have been created or imported by using a specific CSP must be destroyed before that CSP handle is released
/// with the CryptReleaseContext function.
/// </para>
/// <para>Examples</para>
/// <para>For an example that uses the <c>CryptDestroyKey</c> function, see Example C Program: Creating and Hashing a Session Key.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptdestroykey BOOL CryptDestroyKey( HCRYPTKEY hKey );
[DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "ed5d8047-c9fd-4765-915f-a6a014004b30")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptDestroyKey(HCRYPTKEY hKey);
/// <summary>
/// <para>
/// The <c>CryptDuplicateHash</c> function makes an exact copy of a hash to the point when the duplication is done. The duplicate
/// hash includes the state of the hash.
/// </para>
/// <para>
/// A hash can be created in a piece-by-piece way. The <c>CryptDuplicateHash</c> function can be used to create separate hashes of
/// two different contents that begin with the same content.
/// </para>
/// </summary>
/// <param name="hHash">Handle of the hash to be duplicated.</param>
/// <param name="pdwReserved">Reserved for future use and must be zero.</param>
/// <param name="dwFlags">Reserved for future use and must be zero.</param>
/// <param name="phHash">
/// Address of the handle of the duplicated hash. When you have finished using the hash, release the handle by calling the
/// CryptDestroyHash function.
/// </param>
/// <returns>
/// <para>If the function succeeds, the function returns <c>TRUE</c>.</para>
/// <para>If the function fails, it returns <c>FALSE</c>. For extended error information, call GetLastError.</para>
/// <para>
/// The error code prefaced by "NTE" is generated by the particular cryptographic service provider (CSP) that you are using. Some
/// possible error codes follow.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>ERROR_CALL_NOT_IMPLEMENTED</term>
/// <term>
/// Because this is a new function, existing CSPs cannot implement it. This error is returned if the CSP does not support this function.
/// </term>
/// </item>
/// <item>
/// <term>ERROR_INVALID_PARAMETER</term>
/// <term>One of the parameters contains a value that is not valid. This is most often a pointer that is not valid.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_HASH</term>
/// <term>A handle to the original hash is not valid.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// <c>CryptDuplicateHash</c> makes a copy of a hash and the exact state of the hash. This function might be used if a calling
/// application needed to generate two hashes but both hashes had to start with some common data hashed. For example, a hash might
/// be created, the common data hashed, a duplicate made with the <c>CryptDuplicateHash</c> function, and then the data unique to
/// each hash would be added.
/// </para>
/// <para>
/// The CryptDestroyHash function must be called to destroy any hashes that are created with <c>CryptDuplicateHash</c>. Destroying
/// the original hash does not cause the duplicate hash to be destroyed. After a duplicate hash is made, it is separate from the
/// original hash. There is no shared state between the two hashes.
/// </para>
/// <para>Examples</para>
/// <para>
/// The following example shows making an exact copy of a hash. For an example that includes the complete context for this example,
/// see Example C Program: Duplicating a Hash.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptduplicatehash BOOL CryptDuplicateHash( HCRYPTHASH
// hHash, DWORD *pdwReserved, DWORD dwFlags, HCRYPTHASH *phHash );
[DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "527fce4d-8d42-437b-9692-42583092efbb")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptDuplicateHash(HCRYPTHASH hHash, [Optional] IntPtr pdwReserved, [Optional] uint dwFlags, out SafeHCRYPTHASH phHash);
/// <summary>The CryptDuplicateKey function makes an exact copy of a key and the state of the key.</summary>
/// <param name="hKey">A handle to the key to be duplicated.</param>
/// <param name="pdwReserved">Reserved for future use and must be <c>NULL</c>.</param>
/// <param name="dwFlags">Reserved for future use and must be zero.</param>
/// <param name="phKey">
/// Address of the handle to the duplicated key. When you have finished using the key, release the handle by calling the
/// CryptDestroyKey function.
/// </param>
/// <returns>
/// <para>If the function succeeds, the return value is nonzero (TRUE).</para>
/// <para>If the function fails, the return value is zero (FALSE). For extended error information, call GetLastError.</para>
/// <para>
/// The error code prefaced by "NTE" is generated by the particular CSP being used. Some possible error codes are listed in the
/// following table.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>ERROR_CALL_NOT_IMPLEMENTED</term>
/// <term>
/// Because this is a new function, existing CSPs might not implement it. This error is returned if the CSP does not support this function.
/// </term>
/// </item>
/// <item>
/// <term>ERROR_INVALID_PARAMETER</term>
/// <term>One of the parameters contains a value that is not valid. This is most often a pointer that is not valid.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_KEY</term>
/// <term>A handle to the original key is not valid.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// <c>CryptDuplicateKey</c> makes a copy of a key and the exact state of the key. One scenario when this function can be used is
/// when an application needs to encrypt two separate messages with the same key but with different salt values. The original key is
/// generated and then a duplicate key is made by using the <c>CryptDuplicateKey</c> function. The different salt values are then
/// set on the original and duplicate keys with separate calls to the CryptSetKeyParam function.
/// </para>
/// <para>
/// CryptDestroyKey must be called to destroy any keys that are created by using <c>CryptDuplicateKey</c>. Destroying the original
/// key does not cause the duplicate key to be destroyed. After a duplicate key is made, it is separate from the original key. There
/// is no shared state between the two keys.
/// </para>
/// <para>Examples</para>
/// <para>
/// The following example shows the creation of a session key that is a duplicate of an existing session key. For an example that
/// includes the complete context for this example, see Example C Program: Duplicating a Session Key.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptduplicatekey BOOL CryptDuplicateKey( HCRYPTKEY hKey,
// DWORD *pdwReserved, DWORD dwFlags, HCRYPTKEY *phKey );
[DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "c5658008-7c92-4877-871a-a764884efd79")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptDuplicateKey(HCRYPTKEY hKey, [Optional] IntPtr pdwReserved, [Optional] uint dwFlags, out SafeHCRYPTKEY phKey);
/// <summary>
/// <para>
/// The CryptEncrypt function encrypts data. The algorithm used to encrypt the data is designated by the key held by the CSP module
/// and is referenced by the hKey parameter.
/// </para>
/// <para>
/// Important changes to support Secure/Multipurpose Internet Mail Extensions (S/MIME) email interoperability have been made to
/// CryptoAPI that affect the handling of enveloped messages. For more information, see the Remarks section of CryptMsgOpenToEncode.
/// </para>
/// <para>
/// <c>Important</c> The <c>CryptEncrypt</c> function is not guaranteed to be thread safe and may return incorrect results if
/// invoked simultaneously by multiple callers.
/// </para>
/// </summary>
/// <param name="hKey">
/// <para>
/// A handle to the encryption key. An application obtains this handle by using either the CryptGenKey or the CryptImportKey function.
/// </para>
/// <para>The key specifies the encryption algorithm used.</para>
/// </param>
/// <param name="hHash">
/// <para>
/// A handle to a hash object. If data is to be hashed and encrypted simultaneously, a handle to a hash object can be passed in the
/// hHash parameter. The hash value is updated with the plaintext passed in. This option is useful when generating signed and
/// encrypted text.
/// </para>
/// <para>
/// Before calling <c>CryptEncrypt</c>, the application must obtain a handle to the hash object by calling the CryptCreateHash
/// function. After the encryption is complete, the hash value can be obtained by using the CryptGetHashParam function, or the hash
/// can be signed by using the CryptSignHash function.
/// </para>
/// <para>If no hash is to be done, this parameter must be <c>NULL</c>.</para>
/// </param>
/// <param name="Final">
/// A Boolean value that specifies whether this is the last section in a series being encrypted. Final is set to <c>TRUE</c> for the
/// last or only block and to <c>FALSE</c> if there are more blocks to be encrypted. For more information, see Remarks.
/// </param>
/// <param name="dwFlags">
/// <para>The following dwFlags value is defined but reserved for future use.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>CRYPT_OAEP</term>
/// <term>
/// Use Optimal Asymmetric Encryption Padding (OAEP) (PKCS #1 version 2). This flag is only supported by the Microsoft Enhanced
/// Cryptographic Provider with RSA encryption/decryption.
/// </term>
/// </item>
/// </list>
/// </param>
/// <param name="pbData">
/// <para>
/// A pointer to a buffer that contains the plaintext to be encrypted. The plaintext in this buffer is overwritten with the
/// ciphertext created by this function.
/// </para>
/// <para>
/// The pdwDataLen parameter points to a variable that contains the length, in bytes, of the plaintext. The dwBufLen parameter
/// contains the total size, in bytes, of this buffer.
/// </para>
/// <para>
/// If this parameter contains <c>NULL</c>, this function will calculate the required size for the ciphertext and place that in the
/// value pointed to by the pdwDataLen parameter.
/// </para>
/// </param>
/// <param name="pdwDataLen">
/// <para>
/// A pointer to a <c>DWORD</c> value that , on entry, contains the length, in bytes, of the plaintext in the pbData buffer. On
/// exit, this <c>DWORD</c> contains the length, in bytes, of the ciphertext written to the pbData buffer.
/// </para>
/// <para>
/// If the buffer allocated for pbData is not large enough to hold the encrypted data, GetLastError returns <c>ERROR_MORE_DATA</c>
/// and stores the required buffer size, in bytes, in the <c>DWORD</c> value pointed to by pdwDataLen.
/// </para>
/// <para>
/// If pbData is <c>NULL</c>, no error is returned, and the function stores the size of the encrypted data, in bytes, in the
/// <c>DWORD</c> value pointed to by pdwDataLen. This allows an application to determine the correct buffer size.
/// </para>
/// <para>
/// When a block cipher is used, this data length must be a multiple of the block size unless this is the final section of data to
/// be encrypted and the Final parameter is <c>TRUE</c>.
/// </para>
/// </param>
/// <param name="dwBufLen">
/// <para>Specifies the total size, in bytes, of the input pbData buffer.</para>
/// <para>
/// Note that, depending on the algorithm used, the encrypted text can be larger than the original plaintext. In this case, the
/// pbData buffer needs to be large enough to contain the encrypted text and any padding.
/// </para>
/// <para>
/// As a rule, if a stream cipher is used, the ciphertext is the same size as the plaintext. If a block cipher is used, the
/// ciphertext is up to a block length larger than the plaintext.
/// </para>
/// </param>
/// <returns>
/// <para>If the function succeeds, the function returns nonzero ( <c>TRUE</c>).</para>
/// <para>If the function fails, it returns zero ( <c>FALSE</c>). For extended error information, call GetLastError.</para>
/// <para>The error codes prefaced by NTE are generated by the particular CSP being used. Some possible error codes follow.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>ERROR_INVALID_HANDLE</term>
/// <term>One of the parameters specifies a handle that is not valid.</term>
/// </item>
/// <item>
/// <term>ERROR_INVALID_PARAMETER</term>
/// <term>One of the parameters contains a value that is not valid. This is most often a pointer that is not valid.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_ALGID</term>
/// <term>The hKey session key specifies an algorithm that this CSP does not support.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_DATA</term>
/// <term>
/// The data to be encrypted is not valid. For example, when a block cipher is used and the Final flag is FALSE, the value specified
/// by pdwDataLen must be a multiple of the block size.
/// </term>
/// </item>
/// <item>
/// <term>NTE_BAD_FLAGS</term>
/// <term>The dwFlags parameter is nonzero.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_HASH</term>
/// <term>The hHash parameter contains a handle that is not valid.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_HASH_STATE</term>
/// <term>An attempt was made to add data to a hash object that is already marked "finished."</term>
/// </item>
/// <item>
/// <term>NTE_BAD_KEY</term>
/// <term>The hKey parameter does not contain a valid handle to a key.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_LEN</term>
/// <term>The size of the output buffer is too small to hold the generated ciphertext.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_UID</term>
/// <term>The CSP context that was specified when the key was created cannot be found.</term>
/// </item>
/// <item>
/// <term>NTE_DOUBLE_ENCRYPT</term>
/// <term>The application attempted to encrypt the same data twice.</term>
/// </item>
/// <item>
/// <term>NTE_FAIL</term>
/// <term>The function failed in some unexpected way.</term>
/// </item>
/// <item>
/// <term>NTE_NO_MEMORY</term>
/// <term>The CSP ran out of memory during the operation.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// If a large amount of data is to be encrypted, it can be done in sections by calling <c>CryptEncrypt</c> repeatedly. The Final
/// parameter must be set to <c>TRUE</c> on the last call to <c>CryptEncrypt</c>, so that the encryption engine can properly finish
/// the encryption process. The following extra actions are performed when Final is <c>TRUE</c>:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>
/// If the key is a block cipher key, the data is padded to a multiple of the block size of the cipher. If the data length equals
/// the block size of the cipher, one additional block of padding is appended to the data. To find the block size of a cipher, use
/// CryptGetKeyParam to get the KP_BLOCKLEN value of the key.
/// </term>
/// </item>
/// <item>
/// <term>
/// If the cipher is operating in a chaining mode, the next <c>CryptEncrypt</c> operation resets the cipher's feedback register to
/// the KP_IV value of the key.
/// </term>
/// </item>
/// <item>
/// <term>If the cipher is a stream cipher, the next <c>CryptEncrypt</c> resets the cipher to its initial state.</term>
/// </item>
/// </list>
/// <para>
/// There is no way to set the cipher's feedback register to the KP_IV value of the key without setting the Final parameter to
/// <c>TRUE</c>. If this is necessary, as in the case where you do not want to add an additional padding block or change the size of
/// each block, you can simulate this by creating a duplicate of the original key by using the CryptDuplicateKey function, and
/// passing the duplicate key to the <c>CryptEncrypt</c> function. This causes the KP_IV of the original key to be placed in the
/// duplicate key. After you create or import the original key, you cannot use the original key for encryption because the feedback
/// register of the key will be changed. The following pseudocode shows how this can be done.
/// </para>
/// <para>
/// The Microsoft Enhanced Cryptographic Provider supports direct encryption with RSA public keys and decryption with RSA private
/// keys. The encryption uses PKCS #1 padding. On decryption, this padding is verified. The length of plaintext data that can be
/// encrypted with a call to <c>CryptEncrypt</c> with an RSA key is the length of the key modulus minus eleven bytes. The eleven
/// bytes is the chosen minimum for PKCS #1 padding. The ciphertext is returned in little-endian format.
/// </para>
/// <para>Examples</para>
/// <para>For examples that use this function, see Example C Program: Encrypting a File and Example C Program: Decrypting a File.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptencrypt BOOL CryptEncrypt( HCRYPTKEY hKey,
// HCRYPTHASH hHash, BOOL Final, DWORD dwFlags, BYTE *pbData, DWORD *pdwDataLen, DWORD dwBufLen );
[DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "697c4960-552b-4c3a-95cf-4632af56945b")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptEncrypt(HCRYPTKEY hKey, HCRYPTHASH hHash, [MarshalAs(UnmanagedType.Bool)] bool Final, CryptEncryptFlags dwFlags, [In, Out] IntPtr pbData, ref uint pdwDataLen, uint dwBufLen);
/// <summary>
/// <para>
/// The CryptEncrypt function encrypts data. The algorithm used to encrypt the data is designated by the key held by the CSP module
/// and is referenced by the hKey parameter.
/// </para>
/// <para>
/// Important changes to support Secure/Multipurpose Internet Mail Extensions (S/MIME) email interoperability have been made to
/// CryptoAPI that affect the handling of enveloped messages. For more information, see the Remarks section of CryptMsgOpenToEncode.
/// </para>
/// <para>
/// <c>Important</c> The <c>CryptEncrypt</c> function is not guaranteed to be thread safe and may return incorrect results if
/// invoked simultaneously by multiple callers.
/// </para>
/// </summary>
/// <param name="hKey">
/// <para>
/// A handle to the encryption key. An application obtains this handle by using either the CryptGenKey or the CryptImportKey function.
/// </para>
/// <para>The key specifies the encryption algorithm used.</para>
/// </param>
/// <param name="hHash">
/// <para>
/// A handle to a hash object. If data is to be hashed and encrypted simultaneously, a handle to a hash object can be passed in the
/// hHash parameter. The hash value is updated with the plaintext passed in. This option is useful when generating signed and
/// encrypted text.
/// </para>
/// <para>
/// Before calling <c>CryptEncrypt</c>, the application must obtain a handle to the hash object by calling the CryptCreateHash
/// function. After the encryption is complete, the hash value can be obtained by using the CryptGetHashParam function, or the hash
/// can be signed by using the CryptSignHash function.
/// </para>
/// <para>If no hash is to be done, this parameter must be <c>NULL</c>.</para>
/// </param>
/// <param name="Final">
/// A Boolean value that specifies whether this is the last section in a series being encrypted. Final is set to <c>TRUE</c> for the
/// last or only block and to <c>FALSE</c> if there are more blocks to be encrypted. For more information, see Remarks.
/// </param>
/// <param name="dwFlags">
/// <para>The following dwFlags value is defined but reserved for future use.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>CRYPT_OAEP</term>
/// <term>
/// Use Optimal Asymmetric Encryption Padding (OAEP) (PKCS #1 version 2). This flag is only supported by the Microsoft Enhanced
/// Cryptographic Provider with RSA encryption/decryption.
/// </term>
/// </item>
/// </list>
/// </param>
/// <param name="pbData">
/// <para>
/// A pointer to a buffer that contains the plaintext to be encrypted. The plaintext in this buffer is overwritten with the
/// ciphertext created by this function.
/// </para>
/// <para>
/// The pdwDataLen parameter points to a variable that contains the length, in bytes, of the plaintext. The dwBufLen parameter
/// contains the total size, in bytes, of this buffer.
/// </para>
/// <para>
/// If this parameter contains <c>NULL</c>, this function will calculate the required size for the ciphertext and place that in the
/// value pointed to by the pdwDataLen parameter.
/// </para>
/// </param>
/// <param name="pdwDataLen">
/// <para>
/// A pointer to a <c>DWORD</c> value that , on entry, contains the length, in bytes, of the plaintext in the pbData buffer. On
/// exit, this <c>DWORD</c> contains the length, in bytes, of the ciphertext written to the pbData buffer.
/// </para>
/// <para>
/// If the buffer allocated for pbData is not large enough to hold the encrypted data, GetLastError returns <c>ERROR_MORE_DATA</c>
/// and stores the required buffer size, in bytes, in the <c>DWORD</c> value pointed to by pdwDataLen.
/// </para>
/// <para>
/// If pbData is <c>NULL</c>, no error is returned, and the function stores the size of the encrypted data, in bytes, in the
/// <c>DWORD</c> value pointed to by pdwDataLen. This allows an application to determine the correct buffer size.
/// </para>
/// <para>
/// When a block cipher is used, this data length must be a multiple of the block size unless this is the final section of data to
/// be encrypted and the Final parameter is <c>TRUE</c>.
/// </para>
/// </param>
/// <param name="dwBufLen">
/// <para>Specifies the total size, in bytes, of the input pbData buffer.</para>
/// <para>
/// Note that, depending on the algorithm used, the encrypted text can be larger than the original plaintext. In this case, the
/// pbData buffer needs to be large enough to contain the encrypted text and any padding.
/// </para>
/// <para>
/// As a rule, if a stream cipher is used, the ciphertext is the same size as the plaintext. If a block cipher is used, the
/// ciphertext is up to a block length larger than the plaintext.
/// </para>
/// </param>
/// <returns>
/// <para>If the function succeeds, the function returns nonzero ( <c>TRUE</c>).</para>
/// <para>If the function fails, it returns zero ( <c>FALSE</c>). For extended error information, call GetLastError.</para>
/// <para>The error codes prefaced by NTE are generated by the particular CSP being used. Some possible error codes follow.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>ERROR_INVALID_HANDLE</term>
/// <term>One of the parameters specifies a handle that is not valid.</term>
/// </item>
/// <item>
/// <term>ERROR_INVALID_PARAMETER</term>
/// <term>One of the parameters contains a value that is not valid. This is most often a pointer that is not valid.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_ALGID</term>
/// <term>The hKey session key specifies an algorithm that this CSP does not support.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_DATA</term>
/// <term>
/// The data to be encrypted is not valid. For example, when a block cipher is used and the Final flag is FALSE, the value specified
/// by pdwDataLen must be a multiple of the block size.
/// </term>
/// </item>
/// <item>
/// <term>NTE_BAD_FLAGS</term>
/// <term>The dwFlags parameter is nonzero.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_HASH</term>
/// <term>The hHash parameter contains a handle that is not valid.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_HASH_STATE</term>
/// <term>An attempt was made to add data to a hash object that is already marked "finished."</term>
/// </item>
/// <item>
/// <term>NTE_BAD_KEY</term>
/// <term>The hKey parameter does not contain a valid handle to a key.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_LEN</term>
/// <term>The size of the output buffer is too small to hold the generated ciphertext.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_UID</term>
/// <term>The CSP context that was specified when the key was created cannot be found.</term>
/// </item>
/// <item>
/// <term>NTE_DOUBLE_ENCRYPT</term>
/// <term>The application attempted to encrypt the same data twice.</term>
/// </item>
/// <item>
/// <term>NTE_FAIL</term>
/// <term>The function failed in some unexpected way.</term>
/// </item>
/// <item>
/// <term>NTE_NO_MEMORY</term>
/// <term>The CSP ran out of memory during the operation.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// If a large amount of data is to be encrypted, it can be done in sections by calling <c>CryptEncrypt</c> repeatedly. The Final
/// parameter must be set to <c>TRUE</c> on the last call to <c>CryptEncrypt</c>, so that the encryption engine can properly finish
/// the encryption process. The following extra actions are performed when Final is <c>TRUE</c>:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>
/// If the key is a block cipher key, the data is padded to a multiple of the block size of the cipher. If the data length equals
/// the block size of the cipher, one additional block of padding is appended to the data. To find the block size of a cipher, use
/// CryptGetKeyParam to get the KP_BLOCKLEN value of the key.
/// </term>
/// </item>
/// <item>
/// <term>
/// If the cipher is operating in a chaining mode, the next <c>CryptEncrypt</c> operation resets the cipher's feedback register to
/// the KP_IV value of the key.
/// </term>
/// </item>
/// <item>
/// <term>If the cipher is a stream cipher, the next <c>CryptEncrypt</c> resets the cipher to its initial state.</term>
/// </item>
/// </list>
/// <para>
/// There is no way to set the cipher's feedback register to the KP_IV value of the key without setting the Final parameter to
/// <c>TRUE</c>. If this is necessary, as in the case where you do not want to add an additional padding block or change the size of
/// each block, you can simulate this by creating a duplicate of the original key by using the CryptDuplicateKey function, and
/// passing the duplicate key to the <c>CryptEncrypt</c> function. This causes the KP_IV of the original key to be placed in the
/// duplicate key. After you create or import the original key, you cannot use the original key for encryption because the feedback
/// register of the key will be changed. The following pseudocode shows how this can be done.
/// </para>
/// <para>
/// The Microsoft Enhanced Cryptographic Provider supports direct encryption with RSA public keys and decryption with RSA private
/// keys. The encryption uses PKCS #1 padding. On decryption, this padding is verified. The length of plaintext data that can be
/// encrypted with a call to <c>CryptEncrypt</c> with an RSA key is the length of the key modulus minus eleven bytes. The eleven
/// bytes is the chosen minimum for PKCS #1 padding. The ciphertext is returned in little-endian format.
/// </para>
/// <para>Examples</para>
/// <para>For examples that use this function, see Example C Program: Encrypting a File and Example C Program: Decrypting a File.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptencrypt BOOL CryptEncrypt( HCRYPTKEY hKey,
// HCRYPTHASH hHash, BOOL Final, DWORD dwFlags, BYTE *pbData, DWORD *pdwDataLen, DWORD dwBufLen );
[DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "697c4960-552b-4c3a-95cf-4632af56945b")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptEncrypt(HCRYPTKEY hKey, HCRYPTHASH hHash, [MarshalAs(UnmanagedType.Bool)] bool Final, CryptEncryptFlags dwFlags, [In, Out] byte[] pbData, ref int pdwDataLen, int dwBufLen);
/// <summary>
/// The CryptEnumProviders function retrieves the first or next available cryptographic service providers (CSPs). Used in a loop,
/// this function can retrieve in sequence all of the CSPs available on a computer.
/// <para>
/// Possible CSPs include Microsoft Base Cryptographic Provider version 1.0 and Microsoft Enhanced Cryptographic Provider version 1.0.
/// </para>
/// </summary>
/// <param name="dwIndex">Index of the next provider to be enumerated.</param>
/// <param name="pdwReserved">Reserved for future use and must be <c>NULL</c>.</param>
/// <param name="dwFlags">Reserved for future use and must be zero.</param>
/// <param name="pdwProvType">Address of the <c>DWORD</c> value designating the type of the enumerated provider.</param>
/// <param name="szProvName">
/// <para>
/// A pointer to a buffer that receives the data from the enumerated provider. This is a string including the terminating null character.
/// </para>
/// <para>
/// This parameter can be <c>NULL</c> to set the size of the name for memory allocation purposes. For more information, see
/// Retrieving Data of Unknown Length.
/// </para>
/// </param>
/// <param name="pcbProvName">
/// <para>
/// A pointer to a <c>DWORD</c> value specifying the size, in bytes, of the buffer pointed to by the pszProvName parameter. When the
/// function returns, the <c>DWORD</c> value contains the number of bytes stored in the buffer.
/// </para>
/// <para>
/// <c>Note</c> 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 fits 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.
/// </para>
/// </param>
/// <returns>
/// <para>If the function succeeds, the return value is nonzero ( <c>TRUE</c>).</para>
/// <para>If the function fails, the return value is zero ( <c>FALSE</c>). For extended error information, call GetLastError.</para>
/// <para>The error codes prefaced by NTE are generated by the particular CSP being used. Some possible error codes follow.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>ERROR_MORE_DATA</term>
/// <term>The pszProvName buffer was not large enough to hold the provider name.</term>
/// </item>
/// <item>
/// <term>ERROR_NO_MORE_ITEMS</term>
/// <term>There are no more items to enumerate.</term>
/// </item>
/// <item>
/// <term>ERROR_NOT_ENOUGH_MEMORY</term>
/// <term>The operating system ran out of memory.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_FLAGS</term>
/// <term>The dwFlags parameter has an unrecognized value.</term>
/// </item>
/// <item>
/// <term>NTE_FAIL</term>
/// <term>Something was wrong with the type registration.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>This function enumerates the providers available on a computer. The provider types can be enumerated by using CryptEnumProviderTypes.</para>
/// <para>Examples</para>
/// <para>
/// The following example shows a loop listing all available cryptographic service providers. For another example that uses the
/// <c>CryptEnumProviders</c> function, see Example C Program: Enumerating CSP Providers and Provider Types.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptenumprovidersa BOOL CryptEnumProvidersA( DWORD
// dwIndex, DWORD *pdwReserved, DWORD dwFlags, DWORD *pdwProvType, LPSTR szProvName, DWORD *pcbProvName );
[DllImport(Lib.AdvApi32, SetLastError = true, CharSet = CharSet.Auto)]
[PInvokeData("wincrypt.h", MSDNShortId = "2d93ef0f-b48f-481b-ba62-c535476fde08")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptEnumProviders(uint dwIndex, [Optional] IntPtr pdwReserved, [Optional] uint dwFlags, out uint pdwProvType,
[Optional, MarshalAs(UnmanagedType.LPTStr)] StringBuilder szProvName, ref uint pcbProvName);
2020-03-13 17:45:15 -04:00
/// <summary>
/// The CryptEnumProviders function retrieves the first or next available cryptographic service providers (CSPs). Used in a loop,
/// this function can retrieve in sequence all of the CSPs available on a computer.
/// <para>
/// Possible CSPs include Microsoft Base Cryptographic Provider version 1.0 and Microsoft Enhanced Cryptographic Provider version 1.0.
/// </para>
/// </summary>
/// <returns>A sequence of provider names and types.</returns>
2020-03-13 17:45:15 -04:00
[PInvokeData("wincrypt.h", MSDNShortId = "2d93ef0f-b48f-481b-ba62-c535476fde08")]
public static IEnumerable<(uint provType, string provName)> CryptEnumProviders()
2020-03-13 17:45:15 -04:00
{
var idx = 0U;
uint type;
var sb = new StringBuilder(1024);
var sz = 0U;
while (CryptEnumProviders(idx, default, 0, out type, null, ref sz))
{
sb.EnsureCapacity((int)sz);
if (CryptEnumProviders(idx, default, 0, out type, sb, ref sz))
{
yield return (type, sb.ToString());
2020-03-13 17:45:15 -04:00
++idx;
}
else
Win32Error.ThrowLastError();
}
}
/// <summary>
/// The CryptEnumProviderTypes function retrieves the first or next types of cryptographic service provider (CSP) supported on the
/// computer. Used in a loop, this function retrieves in sequence all of the CSP types available on a computer.
/// <para>Provider types include PROV_RSA_FULL, PROV_RSA_SCHANNEL, and PROV_DSS.</para>
/// </summary>
/// <param name="dwIndex">Index of the next provider type to be enumerated.</param>
/// <param name="pdwReserved">Reserved for future use and must be <c>NULL</c>.</param>
/// <param name="dwFlags">Reserved for future use and must be zero.</param>
/// <param name="pdwProvType">Address of the <c>DWORD</c> value designating the enumerated provider type.</param>
/// <param name="szTypeName">
/// <para>
/// A pointer to a buffer that receives the data from the enumerated provider type. This is a string including the terminating
/// <c>NULL</c> character. Some provider types do not have display names, and in this case no name is returned and the returned
/// value pointed to by pcbTypeName is zero.
/// </para>
/// <para>
/// This parameter can be <c>NULL</c> to get the size of the name for memory allocation purposes. For more information, see
/// Retrieving Data of Unknown Length.
/// </para>
/// </param>
/// <param name="pcbTypeName">
/// <para>
/// A pointer to a <c>DWORD</c> value specifying the size, in bytes, of the buffer pointed to by the pszTypeName parameter. When the
/// function returns, the <c>DWORD</c> value contains the number of bytes stored or to be stored in the buffer. Some provider types
/// do not have display names, and in this case no name is returned and the returned value pointed to by pcbTypeName is zero.
/// </para>
/// <para>
/// <c>Note</c> 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 fits 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.
/// </para>
/// </param>
/// <returns>
/// <para>If the function succeeds, the return value is nonzero ( <c>TRUE</c>).</para>
/// <para>If the function fails, the return value is zero ( <c>FALSE</c>). For extended error information, call GetLastError.</para>
/// <para>The error codes prefaced by NTE are generated by the particular CSP being used. Some possible error codes follow.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>ERROR_NO_MORE_ITEMS</term>
/// <term>There are no more items to enumerate.</term>
/// </item>
/// <item>
/// <term>ERROR_NOT_ENOUGH_MEMORY</term>
/// <term>The operating system ran out of memory.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_FLAGS</term>
/// <term>The dwFlags parameter has an unrecognized value.</term>
/// </item>
/// <item>
/// <term>NTE_FAIL</term>
/// <term>Something was wrong with the type registration.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// This function enumerates the provider types available on a computer. Providers for any specific provider type can be enumerated
/// using CryptEnumProviders.
/// </para>
/// <para>Examples</para>
/// <para>The following example shows a loop listing all available cryptographic service provider types.</para>
/// <para>
/// For another example that uses the <c>CryptEnumProviderTypes</c> function, see Example C Program: Enumerating CSP Providers and
/// Provider Types.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptenumprovidertypesa BOOL CryptEnumProviderTypesA(
// DWORD dwIndex, DWORD *pdwReserved, DWORD dwFlags, DWORD *pdwProvType, LPSTR szTypeName, DWORD *pcbTypeName );
[DllImport(Lib.AdvApi32, SetLastError = true, CharSet = CharSet.Auto)]
[PInvokeData("wincrypt.h", MSDNShortId = "7568c963-4d06-4af0-bd15-240402425046")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptEnumProviderTypes(uint dwIndex, [Optional] IntPtr pdwReserved, [Optional] uint dwFlags, out uint pdwProvType,
[Optional, MarshalAs(UnmanagedType.LPTStr)] StringBuilder szTypeName, ref uint pcbTypeName);
2020-03-13 17:45:15 -04:00
/// <summary>
/// The CryptEnumProviderTypes function retrieves the first or next types of cryptographic service provider (CSP) supported on the
/// computer. Used in a loop, this function retrieves in sequence all of the CSP types available on a computer.
/// <para>Provider types include PROV_RSA_FULL, PROV_RSA_SCHANNEL, and PROV_DSS.</para>
/// </summary>
/// <returns>A sequence of provider type names and types.</returns>
2020-03-13 17:45:15 -04:00
[PInvokeData("wincrypt.h", MSDNShortId = "7568c963-4d06-4af0-bd15-240402425046")]
public static IEnumerable<(uint provType, string typeName)> CryptEnumProviderTypes()
2020-03-13 17:45:15 -04:00
{
var idx = 0U;
var sb = new StringBuilder(1024);
var sz = 0U;
while (CryptEnumProviderTypes(idx, default, 0, out _, null, ref sz))
2020-03-13 17:45:15 -04:00
{
sb.EnsureCapacity((int)sz);
if (CryptEnumProviderTypes(idx, default, 0, out var type, sb, ref sz))
2020-03-13 17:45:15 -04:00
{
yield return (type, sb.ToString());
2020-03-13 17:45:15 -04:00
++idx;
}
else
Win32Error.ThrowLastError();
}
}
/// <summary>
/// A handle to the key to be exported is passed to the function, and the function returns a key BLOB. This key BLOB can be sent over
/// a nonsecure transport or stored in a nonsecure storage location. This function can export an Schannel session key, regular
/// session key, public key, or public/private key pair. The key BLOB to export is useless until the intended recipient uses the
/// CryptImportKey function on it to import the key or key pair into a recipient's CSP.
/// </summary>
/// <param name="hKey">A handle to the key to be exported.</param>
/// <param name="hExpKey">
/// <para>
/// A handle to a cryptographic key of the destination user. The key data within the exported key BLOB is encrypted using this key.
/// This ensures that only the destination user is able to make use of the key BLOB. Both <c>hExpKey</c> and <c>hKey</c> must come
/// from the same CSP.
/// </para>
/// <para>
/// Most often, this is the key exchange public key of the destination user. However, certain protocols in some CSPs require that a
/// session key belonging to the destination user be used for this purpose.
/// </para>
/// <para>
/// If the key BLOB type specified by <c>dwBlobType</c> is <c>PUBLICKEYBLOB</c>, this parameter is unused and must be set to zero.
/// </para>
/// <para>
/// If the key BLOB type specified by <c>dwBlobType</c> is <c>PRIVATEKEYBLOB</c>, this is typically a handle to a session key that is
/// to be used to encrypt the key BLOB. Some CSPs allow this parameter to be zero, in which case the application must encrypt the
/// private key BLOB manually so as to protect it.
/// </para>
/// <para>
/// To determine how Microsoft cryptographic service providers respond to this parameter, see the private key BLOB sections of
/// Microsoft Cryptographic Service Providers.
/// </para>
/// <para>
/// <c>Note</c> Some CSPs may modify this parameter as a result of the operation. Applications that subsequently use this key for
/// other purposes should call the CryptDuplicateKey function to create a duplicate key handle. When the application has finished
/// using the handle, release it by calling the CryptDestroyKey function.
/// </para>
/// </param>
/// <param name="dwBlobType">
/// <para>
/// Specifies the type of key BLOB to be exported in <c>pbData</c>. This must be one of the following constants as discussed in
/// Cryptographic Key Storage and Exchange.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term><c>OPAQUEKEYBLOB</c></term>
/// <term>
/// Used to store session keys in an Schannel CSP or any other vendor-specific format. OPAQUEKEYBLOBs are nontransferable and must be
/// used within the CSP that generated the BLOB.
/// </term>
/// </item>
/// <item>
/// <term><c>PRIVATEKEYBLOB</c></term>
/// <term>Used to transport public/private key pairs.</term>
/// </item>
/// <item>
/// <term><c>PUBLICKEYBLOB</c></term>
/// <term>Used to transport public keys.</term>
/// </item>
/// <item>
/// <term><c>SIMPLEBLOB</c></term>
/// <term>Used to transport session keys.</term>
/// </item>
/// <item>
/// <term><c>PLAINTEXTKEYBLOB</c></term>
/// <term>A PLAINTEXTKEYBLOB used to export any key supported by the CSP in use.</term>
/// </item>
/// <item>
/// <term><c>SYMMETRICWRAPKEYBLOB</c></term>
/// <term>
/// Used to export and import a symmetric key wrapped with another symmetric key. The actual wrapped key is in the format specified
/// in the IETF RFC 3217 standard.
/// </term>
/// </item>
/// </list>
/// </param>
/// <param name="dwFlags">
2020-03-13 17:45:15 -04:00
/// <para>
/// Specifies additional options for the function. This parameter can be zero or a combination of one or more of the following values.
2020-03-13 17:45:15 -04:00
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term><c>CRYPT_BLOB_VER3</c> 0x00000080</term>
/// <term>This flag causes this function to export version 3 of a BLOB type.</term>
/// </item>
/// <item>
/// <term><c>CRYPT_DESTROYKEY</c> 0x00000004</term>
/// <term>This flag destroys the original key in the OPAQUEKEYBLOB. This flag is available in Schannel CSPs only.</term>
/// </item>
/// <item>
/// <term><c>CRYPT_OAEP</c> 0x00000040</term>
/// <term>This flag causes PKCS #1 version 2 formatting to be created with the RSA encryption and decryption when exporting SIMPLEBLOBs.</term>
/// </item>
/// <item>
/// <term><c>CRYPT_SSL2_FALLBACK</c> 0x00000002</term>
/// <term>
/// The first eight bytes of the RSA encryption block padding must be set to 0x03 rather than to random data. This prevents version
/// rollback attacks and is discussed in the SSL3 specification. This flag is available for Schannel CSPs only.
/// </term>
/// </item>
/// <item>
/// <term><c>CRYPT_Y_ONLY</c> 0x00000001</term>
/// <term>This flag is not used.</term>
/// </item>
/// </list>
/// </param>
/// <param name="pbData">
2020-03-13 17:45:15 -04:00
/// <para>
/// A pointer to a buffer that receives the key BLOB data. The format of this BLOB varies depending on the BLOB type requested in the
/// <c>dwBlobType</c> parameter. For the format for PRIVATEKEYBLOBs, PUBLICKEYBLOBs, and SIMPLEBLOBs, see Base Provider Key BLOBs.
/// </para>
/// <para>
/// If this parameter is <c>NULL</c>, the required buffer size is placed in the value pointed to by the <c>pdwDataLen</c> parameter.
/// For more information, see Retrieving Data of Unknown Length.
/// </para>
/// </param>
/// <param name="pdwDataLen">
/// <para>
/// A pointer to a <c>DWORD</c> value that, on entry, contains the size, in bytes, of the buffer pointed to by the <c>pbData</c>
/// parameter. When the function returns, this value contains the number of bytes stored in the buffer.
/// </para>
/// <para>
/// <c>Note</c> 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 fits 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.
/// </para>
/// <para>To retrieve the required size of the <c>pbData</c> buffer, pass <c>NULL</c> for <c>pbData</c>.The required buffer size will
/// be placed in the value pointed to by this parameter.</para>
/// </param>
/// <returns>
/// <para>If the function succeeds, the function returns nonzero ( <c>TRUE</c>).</para>
/// <para>If the function fails, it returns zero ( <c>FALSE</c>). For extended error information, call GetLastError.</para>
/// <para>
/// The error codes prefaced by "NTE" are generated by the particular CSP being used. The following table shows some of the possible
/// error codes.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term><c>ERROR_INVALID_HANDLE</c></term>
/// <term>One of the parameters specifies a handle that is not valid.</term>
/// </item>
/// <item>
/// <term><c>ERROR_INVALID_PARAMETER</c></term>
/// <term>One of the parameters contains a value that is not valid. This is most often a pointer that is not valid.</term>
/// </item>
/// <item>
/// <term><c>ERROR_MORE_DATA</c></term>
/// <term>
/// If the buffer specified by the <c>pbData</c> 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 <c>pdwDataLen</c>.
/// </term>
/// </item>
/// <item>
/// <term><c>NTE_BAD_DATA</c></term>
/// <term>
/// Either the algorithm that works with the public key to be exported is not supported by this CSP, or an attempt was made to export
/// a session key that was encrypted with something other than one of your public keys.
/// </term>
/// </item>
/// <item>
/// <term><c>NTE_BAD_FLAGS</c></term>
/// <term>The <c>dwFlags</c> parameter is nonzero.</term>
/// </item>
/// <item>
/// <term><c>NTE_BAD_KEY</c></term>
/// <term>One or both of the keys specified by <c>hKey</c> and <c>hExpKey</c> are not valid.</term>
/// </item>
/// <item>
/// <term><c>NTE_BAD_KEY_STATE</c></term>
/// <term>
/// You do not have permission to export the key. That is, when the <c>hKey</c> key was created, the CRYPT_EXPORTABLE flag was not specified.
/// </term>
/// </item>
/// <item>
/// <term><c>NTE_BAD_PUBLIC_KEY</c></term>
/// <term>The key BLOB type specified by <c>dwBlobType</c> is PUBLICKEYBLOB, but <c>hExpKey</c> does not contain a public key handle.</term>
/// </item>
/// <item>
/// <term><c>NTE_BAD_TYPE</c></term>
/// <term>The <c>dwBlobType</c> parameter specifies an unknown BLOB type.</term>
/// </item>
/// <item>
/// <term><c>NTE_BAD_UID</c></term>
/// <term>The CSP context that was specified when the <c>hKey</c> key was created cannot be found.</term>
/// </item>
/// <item>
/// <term><c>NTE_NO_KEY</c></term>
/// <term>A session key is being exported, and the <c>hExpKey</c> parameter does not specify a public key.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// For any of the DES key permutations that use a PLAINTEXTKEYBLOB, only the full key size, including parity bit, may be exported.
/// The following key sizes are supported.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Algorithm</term>
/// <term>Supported key size</term>
/// </listheader>
/// <item>
/// <term>CALG_DES</term>
/// <term>64 bits</term>
/// </item>
/// <item>
/// <term>CALG_3DES_112</term>
/// <term>128 bits</term>
/// </item>
/// <item>
/// <term>CALG_3DES</term>
/// <term>192 bits</term>
/// </item>
/// </list>
/// <para>Examples</para>
/// <para>
/// The following example shows how to export a cryptographic key or a key pair in a more secure manner. This example assumes that a
/// cryptographic context has been acquired and that a public key is available for export. For an example that includes the complete
/// context for using this function, see Example C Program: Signing a Hash and Verifying the Hash Signature. For another example that
/// uses this function, see Example C Program: Exporting a Session Key.
/// </para>
/// <para><code>#include &lt;windows.h&gt;
/// #include &lt;stdio.h&gt;
/// #include &lt;Wincrypt.h&gt;
///
/// BOOL GetExportedKey( HCRYPTKEY hKey, DWORD dwBlobType, LPBYTE *ppbKeyBlob, LPDWORD pdwBlobLen) {
/// DWORD dwBlobLength;
/// *ppbKeyBlob = NULL;
/// *pdwBlobLen = 0;
/// // Export the public key. Here the public key is exported to a
/// // PUBLICKEYBLOB. This BLOB can be written to a file and
/// // sent to another user.
/// if(CryptExportKey( hKey, NULL, dwBlobType, 0, NULL, &amp;dwBlobLength)) {
/// printf("Size of the BLOB for the public key determined. \n");
/// } else {
/// printf("Error computing BLOB length.\n");
/// return FALSE;
/// }
/// // Allocate memory for the pbKeyBlob.
/// if(*ppbKeyBlob = (LPBYTE)malloc(dwBlobLength)) {
/// printf("Memory has been allocated for the BLOB. \n"); }
/// else {
/// printf("Out of memory. \n");
/// return FALSE;
/// }
/// // Do the actual exporting into the key BLOB.
/// if(CryptExportKey( hKey, NULL, dwBlobType, 0, *ppbKeyBlob, &amp;dwBlobLength)) {
/// printf("Contents have been written to the BLOB. \n");
/// *pdwBlobLen = dwBlobLength; }
/// else {
/// printf("Error exporting key.\n");
/// free(*ppbKeyBlob);
/// *ppbKeyBlob = NULL;
/// return FALSE;
/// }
/// return TRUE;
/// }</code></para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptexportkey
// BOOL CryptExportKey( [in] HCRYPTKEY hKey, [in] HCRYPTKEY hExpKey, [in] DWORD dwBlobType, [in] DWORD dwFlags, [out] BYTE *pbData, [in, out] DWORD *pdwDataLen );
[DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "NF:wincrypt.CryptExportKey")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptExportKey(HCRYPTKEY hKey, HCRYPTKEY hExpKey, BlobType dwBlobType, CryptExportKeyFlags dwFlags, [Out, Optional] IntPtr pbData, ref uint pdwDataLen);
/// <summary>
/// A handle to the key to be exported is passed to the function, and the function returns a key BLOB. This key BLOB can be sent over
/// a nonsecure transport or stored in a nonsecure storage location. This function can export an Schannel session key, regular
2020-03-13 17:45:15 -04:00
/// session key, public key, or public/private key pair. The key BLOB to export is useless until the intended recipient uses the
/// CryptImportKey function on it to import the key or key pair into a recipient's CSP.
/// </summary>
/// <param name="hKey">A handle to the key to be exported.</param>
/// <param name="hExpKey">
/// <para>
/// A handle to a cryptographic key of the destination user. The key data within the exported key BLOB is encrypted using this key.
/// This ensures that only the destination user is able to make use of the key BLOB. Both <c>hExpKey</c> and <c>hKey</c> must come
/// from the same CSP.
2020-03-13 17:45:15 -04:00
/// </para>
/// <para>
/// Most often, this is the key exchange public key of the destination user. However, certain protocols in some CSPs require that a
/// session key belonging to the destination user be used for this purpose.
/// </para>
/// <para>
/// If the key BLOB type specified by <c>dwBlobType</c> is <c>PUBLICKEYBLOB</c>, this parameter is unused and must be set to zero.
/// </para>
/// <para>
/// If the key BLOB type specified by <c>dwBlobType</c> is <c>PRIVATEKEYBLOB</c>, this is typically a handle to a session key that is
/// to be used to encrypt the key BLOB. Some CSPs allow this parameter to be zero, in which case the application must encrypt the
/// private key BLOB manually so as to protect it.
2020-03-13 17:45:15 -04:00
/// </para>
/// <para>
/// To determine how Microsoft cryptographic service providers respond to this parameter, see the private key BLOB sections of
/// Microsoft Cryptographic Service Providers.
/// </para>
/// <para>
/// <c>Note</c> Some CSPs may modify this parameter as a result of the operation. Applications that subsequently use this key for
/// other purposes should call the CryptDuplicateKey function to create a duplicate key handle. When the application has finished
/// using the handle, release it by calling the CryptDestroyKey function.
/// </para>
/// </param>
/// <param name="dwBlobType">
/// <para>
/// Specifies the type of key BLOB to be exported in <c>pbData</c>. This must be one of the following constants as discussed in
2020-03-13 17:45:15 -04:00
/// Cryptographic Key Storage and Exchange.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term><c>OPAQUEKEYBLOB</c></term>
2020-03-13 17:45:15 -04:00
/// <term>
/// Used to store session keys in an Schannel CSP or any other vendor-specific format. OPAQUEKEYBLOBs are nontransferable and must be
/// used within the CSP that generated the BLOB.
2020-03-13 17:45:15 -04:00
/// </term>
/// </item>
/// <item>
/// <term><c>PRIVATEKEYBLOB</c></term>
2020-03-13 17:45:15 -04:00
/// <term>Used to transport public/private key pairs.</term>
/// </item>
/// <item>
/// <term><c>PUBLICKEYBLOB</c></term>
2020-03-13 17:45:15 -04:00
/// <term>Used to transport public keys.</term>
/// </item>
/// <item>
/// <term><c>SIMPLEBLOB</c></term>
2020-03-13 17:45:15 -04:00
/// <term>Used to transport session keys.</term>
/// </item>
/// <item>
/// <term><c>PLAINTEXTKEYBLOB</c></term>
2020-03-13 17:45:15 -04:00
/// <term>A PLAINTEXTKEYBLOB used to export any key supported by the CSP in use.</term>
/// </item>
/// <item>
/// <term><c>SYMMETRICWRAPKEYBLOB</c></term>
2020-03-13 17:45:15 -04:00
/// <term>
/// Used to export and import a symmetric key wrapped with another symmetric key. The actual wrapped key is in the format specified
/// in the IETF RFC 3217 standard.
/// </term>
/// </item>
/// </list>
/// </param>
/// <param name="dwFlags">
/// <para>
/// Specifies additional options for the function. This parameter can be zero or a combination of one or more of the following values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term><c>CRYPT_BLOB_VER3</c> 0x00000080</term>
2020-03-13 17:45:15 -04:00
/// <term>This flag causes this function to export version 3 of a BLOB type.</term>
/// </item>
/// <item>
/// <term><c>CRYPT_DESTROYKEY</c> 0x00000004</term>
2020-03-13 17:45:15 -04:00
/// <term>This flag destroys the original key in the OPAQUEKEYBLOB. This flag is available in Schannel CSPs only.</term>
/// </item>
/// <item>
/// <term><c>CRYPT_OAEP</c> 0x00000040</term>
2020-03-13 17:45:15 -04:00
/// <term>This flag causes PKCS #1 version 2 formatting to be created with the RSA encryption and decryption when exporting SIMPLEBLOBs.</term>
/// </item>
/// <item>
/// <term><c>CRYPT_SSL2_FALLBACK</c> 0x00000002</term>
2020-03-13 17:45:15 -04:00
/// <term>
/// The first eight bytes of the RSA encryption block padding must be set to 0x03 rather than to random data. This prevents version
/// rollback attacks and is discussed in the SSL3 specification. This flag is available for Schannel CSPs only.
/// </term>
/// </item>
/// <item>
/// <term><c>CRYPT_Y_ONLY</c> 0x00000001</term>
2020-03-13 17:45:15 -04:00
/// <term>This flag is not used.</term>
/// </item>
/// </list>
/// </param>
/// <param name="pbData">
/// <para>
/// A pointer to a buffer that receives the key BLOB data. The format of this BLOB varies depending on the BLOB type requested in the
/// <c>dwBlobType</c> parameter. For the format for PRIVATEKEYBLOBs, PUBLICKEYBLOBs, and SIMPLEBLOBs, see Base Provider Key BLOBs.
2020-03-13 17:45:15 -04:00
/// </para>
/// <para>
/// If this parameter is <c>NULL</c>, the required buffer size is placed in the value pointed to by the <c>pdwDataLen</c> parameter.
/// For more information, see Retrieving Data of Unknown Length.
2020-03-13 17:45:15 -04:00
/// </para>
/// </param>
/// <param name="pdwDataLen">
/// <para>
/// A pointer to a <c>DWORD</c> value that, on entry, contains the size, in bytes, of the buffer pointed to by the <c>pbData</c>
/// parameter. When the function returns, this value contains the number of bytes stored in the buffer.
2020-03-13 17:45:15 -04:00
/// </para>
/// <para>
/// <c>Note</c> 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 fits 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.
/// </para>
/// <para>To retrieve the required size of the <c>pbData</c> buffer, pass <c>NULL</c> for <c>pbData</c>.The required buffer size will
/// be placed in the value pointed to by this parameter.</para>
2020-03-13 17:45:15 -04:00
/// </param>
/// <returns>
/// <para>If the function succeeds, the function returns nonzero ( <c>TRUE</c>).</para>
/// <para>If the function fails, it returns zero ( <c>FALSE</c>). For extended error information, call GetLastError.</para>
/// <para>
/// The error codes prefaced by "NTE" are generated by the particular CSP being used. The following table shows some of the possible
/// error codes.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term><c>ERROR_INVALID_HANDLE</c></term>
2020-03-13 17:45:15 -04:00
/// <term>One of the parameters specifies a handle that is not valid.</term>
/// </item>
/// <item>
/// <term><c>ERROR_INVALID_PARAMETER</c></term>
2020-03-13 17:45:15 -04:00
/// <term>One of the parameters contains a value that is not valid. This is most often a pointer that is not valid.</term>
/// </item>
/// <item>
/// <term><c>ERROR_MORE_DATA</c></term>
2020-03-13 17:45:15 -04:00
/// <term>
/// If the buffer specified by the <c>pbData</c> 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 <c>pdwDataLen</c>.
2020-03-13 17:45:15 -04:00
/// </term>
/// </item>
/// <item>
/// <term><c>NTE_BAD_DATA</c></term>
2020-03-13 17:45:15 -04:00
/// <term>
/// Either the algorithm that works with the public key to be exported is not supported by this CSP, or an attempt was made to export
/// a session key that was encrypted with something other than one of your public keys.
2020-03-13 17:45:15 -04:00
/// </term>
/// </item>
/// <item>
/// <term><c>NTE_BAD_FLAGS</c></term>
/// <term>The <c>dwFlags</c> parameter is nonzero.</term>
2020-03-13 17:45:15 -04:00
/// </item>
/// <item>
/// <term><c>NTE_BAD_KEY</c></term>
/// <term>One or both of the keys specified by <c>hKey</c> and <c>hExpKey</c> are not valid.</term>
2020-03-13 17:45:15 -04:00
/// </item>
/// <item>
/// <term><c>NTE_BAD_KEY_STATE</c></term>
2020-03-13 17:45:15 -04:00
/// <term>
/// You do not have permission to export the key. That is, when the <c>hKey</c> key was created, the CRYPT_EXPORTABLE flag was not specified.
2020-03-13 17:45:15 -04:00
/// </term>
/// </item>
/// <item>
/// <term><c>NTE_BAD_PUBLIC_KEY</c></term>
/// <term>The key BLOB type specified by <c>dwBlobType</c> is PUBLICKEYBLOB, but <c>hExpKey</c> does not contain a public key handle.</term>
2020-03-13 17:45:15 -04:00
/// </item>
/// <item>
/// <term><c>NTE_BAD_TYPE</c></term>
/// <term>The <c>dwBlobType</c> parameter specifies an unknown BLOB type.</term>
2020-03-13 17:45:15 -04:00
/// </item>
/// <item>
/// <term><c>NTE_BAD_UID</c></term>
/// <term>The CSP context that was specified when the <c>hKey</c> key was created cannot be found.</term>
2020-03-13 17:45:15 -04:00
/// </item>
/// <item>
/// <term><c>NTE_NO_KEY</c></term>
/// <term>A session key is being exported, and the <c>hExpKey</c> parameter does not specify a public key.</term>
2020-03-13 17:45:15 -04:00
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// For any of the DES key permutations that use a PLAINTEXTKEYBLOB, only the full key size, including parity bit, may be exported.
/// The following key sizes are supported.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Algorithm</term>
/// <term>Supported key size</term>
/// </listheader>
/// <item>
/// <term>CALG_DES</term>
/// <term>64 bits</term>
/// </item>
/// <item>
/// <term>CALG_3DES_112</term>
/// <term>128 bits</term>
/// </item>
/// <item>
/// <term>CALG_3DES</term>
/// <term>192 bits</term>
/// </item>
/// </list>
/// <para>Examples</para>
/// <para>
/// The following example shows how to export a cryptographic key or a key pair in a more secure manner. This example assumes that a
/// cryptographic context has been acquired and that a public key is available for export. For an example that includes the complete
/// context for using this function, see Example C Program: Signing a Hash and Verifying the Hash Signature. For another example that
/// uses this function, see Example C Program: Exporting a Session Key.
/// </para>
/// <para><code>#include &lt;windows.h&gt;
/// #include &lt;stdio.h&gt;
/// #include &lt;Wincrypt.h&gt;
///
/// BOOL GetExportedKey( HCRYPTKEY hKey, DWORD dwBlobType, LPBYTE *ppbKeyBlob, LPDWORD pdwBlobLen) {
/// DWORD dwBlobLength;
/// *ppbKeyBlob = NULL;
/// *pdwBlobLen = 0;
/// // Export the public key. Here the public key is exported to a
/// // PUBLICKEYBLOB. This BLOB can be written to a file and
/// // sent to another user.
/// if(CryptExportKey( hKey, NULL, dwBlobType, 0, NULL, &amp;dwBlobLength)) {
/// printf("Size of the BLOB for the public key determined. \n");
/// } else {
/// printf("Error computing BLOB length.\n");
/// return FALSE;
/// }
/// // Allocate memory for the pbKeyBlob.
/// if(*ppbKeyBlob = (LPBYTE)malloc(dwBlobLength)) {
/// printf("Memory has been allocated for the BLOB. \n"); }
/// else {
/// printf("Out of memory. \n");
/// return FALSE;
/// }
/// // Do the actual exporting into the key BLOB.
/// if(CryptExportKey( hKey, NULL, dwBlobType, 0, *ppbKeyBlob, &amp;dwBlobLength)) {
/// printf("Contents have been written to the BLOB. \n");
/// *pdwBlobLen = dwBlobLength; }
/// else {
/// printf("Error exporting key.\n");
/// free(*ppbKeyBlob);
/// *ppbKeyBlob = NULL;
/// return FALSE;
/// }
/// return TRUE;
/// }</code></para>
2020-03-13 17:45:15 -04:00
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptexportkey
// BOOL CryptExportKey( [in] HCRYPTKEY hKey, [in] HCRYPTKEY hExpKey, [in] DWORD dwBlobType, [in] DWORD dwFlags, [out] BYTE *pbData, [in, out] DWORD *pdwDataLen );
2020-03-13 17:45:15 -04:00
[DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "NF:wincrypt.CryptExportKey")]
2020-03-13 17:45:15 -04:00
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptExportKey(HCRYPTKEY hKey, HCRYPTKEY hExpKey, BlobType dwBlobType, CryptExportKeyFlags dwFlags, [Out, Optional] byte[] pbData, ref uint pdwDataLen);
2020-03-13 17:45:15 -04:00
/// <summary>
/// <para>
/// The CryptGenKey function generates a random cryptographic session key or a public/private key pair. A handle to the key or key
/// pair is returned in phKey. This handle can then be used as needed with any CryptoAPI function that requires a key handle.
/// </para>
/// <para>
/// The calling application must specify the algorithm when calling this function. Because this algorithm type is kept bundled with
/// the key, the application does not need to specify the algorithm later when the actual cryptographic operations are performed.
/// </para>
/// </summary>
/// <param name="hProv">A handle to a cryptographic service provider (CSP) created by a call to CryptAcquireContext.</param>
/// <param name="Algid">
/// <para>
/// An ALG_ID value that identifies the algorithm for which the key is to be generated. Values for this parameter vary depending on
/// the CSP used.
/// </para>
/// <para>For <c>ALG_ID</c> values to use with the Microsoft Base Cryptographic Provider, see Base Provider Algorithms.</para>
/// <para>
/// For <c>ALG_ID</c> values to use with the Microsoft Strong Cryptographic Provider or the Microsoft Enhanced Cryptographic
/// Provider, see Enhanced Provider Algorithms.
/// </para>
/// <para>For a Diffie-Hellman CSP, use one of the following values.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>CALG_DH_EPHEM</term>
/// <term>Specifies an "Ephemeral" Diffie-Hellman key.</term>
/// </item>
/// <item>
/// <term>CALG_DH_SF</term>
/// <term>Specifies a "Store and Forward" Diffie-Hellman key.</term>
/// </item>
/// </list>
/// <para>
/// In addition to generating session keys for symmetric algorithms, this function can also generate public/private key pairs. Each
/// CryptoAPI client generally possesses two public/private key pairs. To generate one of these key pairs, set the Algid parameter
/// to one of the following values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>AT_KEYEXCHANGE</term>
/// <term>Key exchange</term>
/// </item>
/// <item>
/// <term>AT_SIGNATURE</term>
/// <term>Digital signature</term>
/// </item>
/// </list>
/// <para>
/// <c>Note</c> When key specifications AT_KEYEXCHANGE and AT_SIGNATURE are specified, the algorithm identifiers that are used to
/// generate the key depend on the provider used. As a result, for these key specifications, the values returned from
/// CryptGetKeyParam (when the KP_ALGID parameter is specified) depend on the provider used. To determine which algorithm identifier
/// is used by the different providers for the key specs AT_KEYEXCHANGE and AT_SIGNATURE, see ALG_ID.
/// </para>
/// </param>
/// <param name="dwFlags">
/// <para>
/// Specifies the type of key generated. The sizes of a session key, RSA signature key, and RSA key exchange keys can be set when
/// the key is generated. The key size, representing the length of the key modulus in bits, is set with the upper 16 bits of this
/// parameter. Thus, if a 2,048-bit RSA signature key is to be generated, the value 0x08000000 is combined with any other dwFlags
/// predefined value with a bitwise- <c>OR</c> operation. The upper 16 bits of 0x08000000 is 0x0800, or decimal 2,048. The
/// <c>RSA1024BIT_KEY</c> value can be used to specify a 1024-bit RSA key.
/// </para>
/// <para>
/// Due to changing export control restrictions, the default CSP and default key length may change between operating system
/// versions. It is important that both the encryption and decryption use the same CSP and that the key length be explicitly set
/// using the dwFlags parameter to ensure interoperability on different operating system platforms.
/// </para>
/// <para>
/// In particular, the default RSA Full Cryptographic Service Provider is the Microsoft RSA Strong Cryptographic Provider. The
/// default DSS Signature Diffie-Hellman Cryptographic Service Provider is the Microsoft Enhanced DSS Diffie-Hellman Cryptographic
/// Provider. Each of these CSPs has a default 128-bit symmetric key length for RC2 and RC4 and a 1,024-bit default key length for
/// public key algorithms.
/// </para>
/// <para>
/// If the upper 16 bits is zero, the default key size is generated. If a key larger than the maximum or smaller than the minimum is
/// specified, the call fails with the ERROR_INVALID_PARAMETER code.
/// </para>
/// <para>The following table lists minimum, default, and maximum signature and exchange key lengths beginning with Windows XP.</para>
/// <list type="table">
/// <listheader>
/// <term>Key type and provider</term>
/// <term>Minimum length</term>
/// <term>Default length</term>
/// <term>Maximum length</term>
/// </listheader>
/// <item>
/// <term>RSA Base Provider Signature and ExchangeKeys</term>
/// <term>384</term>
/// <term>512</term>
/// <term>16,384</term>
/// </item>
/// <item>
/// <term>RSA Strong and Enhanced Providers Signature and Exchange Keys</term>
/// <term>384</term>
/// <term>1,024</term>
/// <term>16,384</term>
/// </item>
/// <item>
/// <term>DSS Base Providers Signature Keys</term>
/// <term>512</term>
/// <term>1,024</term>
/// <term>1,024</term>
/// </item>
/// <item>
/// <term>DSS Base Providers Exchange Keys</term>
/// <term>Not applicable</term>
/// <term>Not applicable</term>
/// <term>Not applicable</term>
/// </item>
/// <item>
/// <term>DSS/DH Base Providers Signature Keys</term>
/// <term>512</term>
/// <term>1,024</term>
/// <term>1,024</term>
/// </item>
/// <item>
/// <term>DSS/DH Base Providers Exchange Keys</term>
/// <term>512</term>
/// <term>512</term>
/// <term>1,024</term>
/// </item>
/// <item>
/// <term>DSS/DH Enhanced Providers Signature Keys</term>
/// <term>512</term>
/// <term>1,024</term>
/// <term>1,024</term>
/// </item>
/// <item>
/// <term>DSS/DH Enhanced Providers Exchange Keys</term>
/// <term>512</term>
/// <term>1,024</term>
/// <term>4,096</term>
/// </item>
/// </list>
/// <para>For session key lengths, see CryptDeriveKey.</para>
/// <para>For more information about keys generated using Microsoft providers, see Microsoft Cryptographic Service Providers.</para>
/// <para>The lower 16-bits of this parameter can be zero or a combination of one or more of the following values.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>CRYPT_ARCHIVABLE</term>
/// <term>
/// If this flag is set, the key can be exported until its handle is closed by a call to CryptDestroyKey. This allows newly
/// generated keys to be exported upon creation for archiving or key recovery. After the handle is closed, the key is no longer exportable.
/// </term>
/// </item>
/// <item>
/// <term>CRYPT_CREATE_IV</term>
/// <term>This flag is not used.</term>
/// </item>
/// <item>
/// <term>CRYPT_CREATE_SALT</term>
/// <term>
/// If this flag is set, then the key is assigned a random salt value automatically. You can retrieve this salt value by using the
/// CryptGetKeyParam function with the dwParam parameter set to KP_SALT. If this flag is not set, then the key is given a salt value
/// of zero. When keys with nonzero salt values are exported (through CryptExportKey), then the salt value must also be obtained and
/// kept with the key BLOB.
/// </term>
/// </item>
/// <item>
/// <term>CRYPT_DATA_KEY</term>
/// <term>This flag is not used.</term>
/// </item>
/// <item>
/// <term>CRYPT_EXPORTABLE</term>
/// <term>
/// If this flag is set, then the key can be transferred out of the CSP into a key BLOB by using the CryptExportKey function.
/// Because session keys generally must be exportable, this flag should usually be set when they are created. If this flag is not
/// set, then the key is not exportable. For a session key, this means that the key is available only within the current session and
/// only the application that created it will be able to use it. For a public/private key pair, this means that the private key
/// cannot be transported or backed up. This flag applies only to session key and private key BLOBs. It does not apply to public
/// keys, which are always exportable.
/// </term>
/// </item>
/// <item>
/// <term>CRYPT_FORCE_KEY_PROTECTION_HIGH</term>
/// <term>
/// This flag specifies strong key protection. When this flag is set, the user is prompted to enter a password for the key when the
/// key is created. The user will be prompted to enter the password whenever this key is used. This flag is only used by the CSPs
/// that are provided by Microsoft. Third party CSPs will define their own behavior for strong key protection. Specifying this flag
/// causes the same result as calling this function with the CRYPT_USER_PROTECTED flag when strong key protection is specified in
/// the system registry. If this flag is specified and the provider handle in the hProv parameter was created by using the
/// CRYPT_VERIFYCONTEXT or CRYPT_SILENT flag, this function will set the last error to NTE_SILENT_CONTEXT and return zero. Windows
/// Server 2003 and Windows XP: This flag is not supported.
/// </term>
/// </item>
/// <item>
/// <term>CRYPT_KEK</term>
/// <term>This flag is not used.</term>
/// </item>
/// <item>
/// <term>CRYPT_INITIATOR</term>
/// <term>This flag is not used.</term>
/// </item>
/// <item>
/// <term>CRYPT_NO_SALT</term>
/// <term>
/// This flag specifies that a no salt value gets allocated for a forty-bit symmetric key. For more information, see Salt Value Functionality.
/// </term>
/// </item>
/// <item>
/// <term>CRYPT_ONLINE</term>
/// <term>This flag is not used.</term>
/// </item>
/// <item>
/// <term>CRYPT_PREGEN</term>
/// <term>
/// This flag specifies an initial Diffie-Hellman or DSS key generation. This flag is useful only with Diffie-Hellman and DSS CSPs.
/// When used, a default key length will be used unless a key length is specified in the upper 16 bits of the dwFlags parameter. If
/// parameters that involve key lengths are set on a PREGEN Diffie-Hellman or DSS key using CryptSetKeyParam, the key lengths must
/// be compatible with the key length set here.
/// </term>
/// </item>
/// <item>
/// <term>CRYPT_RECIPIENT</term>
/// <term>This flag is not used.</term>
/// </item>
/// <item>
/// <term>CRYPT_SF</term>
/// <term>This flag is not used.</term>
/// </item>
/// <item>
/// <term>CRYPT_SGCKEY</term>
/// <term>This flag is not used.</term>
/// </item>
/// <item>
/// <term>CRYPT_USER_PROTECTED</term>
/// <term>
/// If this flag is set, the user is notified through a dialog box or another method when certain actions are attempting to use this
/// key. The precise behavior is specified by the CSP being used. If the provider context was opened with the CRYPT_SILENT flag set,
/// using this flag causes a failure and the last error is set to NTE_SILENT_CONTEXT.
/// </term>
/// </item>
/// <item>
/// <term>CRYPT_VOLATILE</term>
/// <term>This flag is not used.</term>
/// </item>
/// </list>
/// </param>
/// <param name="phKey">
/// Address to which the function copies the handle of the newly generated key. When you have finished using the key, delete the
/// handle to the key by calling the CryptDestroyKey function.
/// </param>
/// <returns>
/// <para>Returns nonzero if successful or zero otherwise.</para>
/// <para>For extended error information, call GetLastError.</para>
/// <para>
/// The error codes prefaced by "NTE" are generated by the particular CSP being used. Some possible error codes are listed in the
/// following table.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>ERROR_INVALID_HANDLE</term>
/// <term>One of the parameters specifies a handle that is not valid.</term>
/// </item>
/// <item>
/// <term>ERROR_INVALID_PARAMETER</term>
/// <term>One of the parameters contains a value that is not valid. This is most often a pointer that is not valid.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_ALGID</term>
/// <term>The Algid parameter specifies an algorithm that this CSP does not support.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_FLAGS</term>
/// <term>The dwFlags parameter contains a value that is not valid.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_UID</term>
/// <term>The hProv parameter does not contain a valid context handle.</term>
/// </item>
/// <item>
/// <term>NTE_FAIL</term>
/// <term>The function failed in some unexpected way.</term>
/// </item>
/// <item>
/// <term>NTE_SILENT_CONTEXT</term>
/// <term>The provider could not perform the action because the context was acquired as silent.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// If keys are generated for symmetric block ciphers, the key, by default, is set up in cipher block chaining (CBC) mode with an
/// initialization vector of zero. This cipher mode provides a good default method for bulk encrypting data. To change these
/// parameters, use the CryptSetKeyParam function.
/// </para>
/// <para>To choose an appropriate key length, the following methods are recommended:</para>
/// <list type="bullet">
/// <item>
/// <term>
/// Enumerate the algorithms that the CSP supports and get maximum and minimum key lengths for each algorithm. To do this, call
/// CryptGetProvParam with PP_ENUMALGS_EX.
/// </term>
/// </item>
/// <item>
/// <term>
/// Use the minimum and maximum lengths to choose an appropriate key length. It is not always advisable to choose the maximum length
/// because this can lead to performance issues.
/// </term>
/// </item>
/// <item>
/// <term>After the desired key length has been chosen, use the upper 16 bits of the dwFlags parameter to specify the key length.</term>
/// </item>
/// </list>
/// <para>Examples</para>
/// <para>
/// The following example shows the creation of a random session key. For an example that includes the complete context for this
/// example, see Example C Program: Encrypting a File. For another example that uses this function, see Example C Program:
/// Decrypting a File.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptgenkey BOOL CryptGenKey( HCRYPTPROV hProv, ALG_ID
// Algid, DWORD dwFlags, HCRYPTKEY *phKey );
[DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "b65dd856-2dfa-4cda-9b2f-b32f3c291470")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptGenKey(HCRYPTPROV hProv, ALG_ID Algid, CryptGenKeyFlags dwFlags, out SafeHCRYPTKEY phKey);
/// <summary>The CryptGenRandom function fills a buffer with cryptographically random bytes.</summary>
/// <param name="hProv">Handle of a cryptographic service provider (CSP) created by a call to CryptAcquireContext.</param>
/// <param name="dwLen">Number of bytes of random data to be generated.</param>
/// <param name="pbBuffer">
/// <para>Buffer to receive the returned data. This buffer must be at least dwLen bytes in length.</para>
/// <para>Optionally, the application can fill this buffer with data to use as an auxiliary random seed.</para>
/// </param>
/// <returns>
/// <para>If the function succeeds, the return value is nonzero (TRUE).</para>
/// <para>If the function fails, the return value is zero (FALSE). For extended error information, call GetLastError.</para>
/// <para>
/// The error codes prefaced by "NTE" are generated by the particular CSP being used. Some possible error codes are listed in the
/// following table.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>ERROR_INVALID_HANDLE</term>
/// <term>One of the parameters specifies a handle that is not valid.</term>
/// </item>
/// <item>
/// <term>ERROR_INVALID_PARAMETER</term>
/// <term>One of the parameters contains a value that is not valid. This is most often a pointer that is not valid.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_UID</term>
/// <term>The hProv parameter does not contain a valid context handle.</term>
/// </item>
/// <item>
/// <term>NTE_FAIL</term>
/// <term>The function failed in some unexpected way.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The data produced by this function is cryptographically random. It is far more random than the data generated by the typical
/// random number generator such as the one shipped with your C compiler.
/// </para>
/// <para>This function is often used to generate random initialization vectors and salt values.</para>
/// <para>
/// Software random number generators work in fundamentally the same way. They start with a random number, known as the seed, and
/// then use an algorithm to generate a pseudo-random sequence of bits based on it. The most difficult part of this process is to
/// get a seed that is truly random. This is usually based on user input latency, or the jitter from one or more hardware components.
/// </para>
/// <para>
/// With Microsoft CSPs, <c>CryptGenRandom</c> uses the same random number generator used by other security components. This allows
/// numerous processes to contribute to a system-wide seed. CryptoAPI stores an intermediate random seed with every user. To form
/// the seed for the random number generator, a calling application supplies bits it might have—for instance, mouse or keyboard
/// timing input—that are then combined with both the stored seed and various system data and user data such as the process ID and
/// thread ID, the system clock, the system time, the system counter, memory status, free disk clusters, the hashed user environment
/// block. This result is used to seed the pseudorandom number generator (PRNG). In Windows Vista with Service Pack 1 (SP1) and
/// later, an implementation of the AES counter-mode based PRNG specified in NIST Special Publication 800-90 is used. In Windows
/// Vista, Windows Storage Server 2003, and Windows XP, the PRNG specified in Federal Information Processing Standard (FIPS) 186-2
/// is used. If an application has access to a good random source, it can fill the pbBuffer buffer with some random data before
/// calling <c>CryptGenRandom</c>. The CSP then uses this data to further randomize its internal seed. It is acceptable to omit the
/// step of initializing the pbBuffer buffer before calling <c>CryptGenRandom</c>.
/// </para>
/// <para>Examples</para>
/// <para>
/// The following example shows the generation of 8 random bytes. These can be used to create cryptographic keys or for any
/// application that uses random numbers. For an example that includes the complete context for this example, see Example C Program:
/// Duplicating a Session Key.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptgenrandom BOOL CryptGenRandom( HCRYPTPROV hProv,
// DWORD dwLen, BYTE *pbBuffer );
[DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "3e5a437f-7439-43c9-a191-2908d2df0eb6")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptGenRandom(HCRYPTPROV hProv, uint dwLen, [In, Out] IntPtr pbBuffer);
/// <summary>
/// The CryptGetDefaultProvider function finds the default cryptographic service provider (CSP) of a specified provider type for the
/// local computer or current user. The name of the default CSP for the provider type specified in the dwProvType parameter is
/// returned in the pszProvName buffer.
/// </summary>
/// <param name="dwProvType">
/// <para>The provider type for which the default CSP name is to be found.</para>
/// <para>Defined provider types are as follows:</para>
/// <list type="bullet">
/// <item>
/// <term>PROV_RSA_FULL</term>
/// </item>
/// <item>
/// <term>PROV_RSA_SIG</term>
/// </item>
/// <item>
/// <term>PROV_DSS</term>
/// </item>
/// <item>
/// <term>PROV_DSS_DH</term>
/// </item>
/// <item>
/// <term>PROV_DH_SCHANNEL</term>
/// </item>
/// <item>
/// <term>PROV_FORTEZZA</term>
/// </item>
/// <item>
/// <term>PROV_MS_EXCHANGE</term>
/// </item>
/// <item>
/// <term>PROV_RSA_SCHANNEL</term>
/// </item>
/// <item>
/// <term>PROV_SSL</term>
/// </item>
/// </list>
/// </param>
/// <param name="pdwReserved">This parameter is reserved for future use and must be <c>NULL</c>.</param>
/// <param name="dwFlags">
/// <para>The following flag values are defined.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>CRYPT_USER_DEFAULT 0x00000002</term>
/// <term>Returns the user-context default CSP of the specified type.</term>
/// </item>
/// <item>
/// <term>CRYPT_MACHINE_DEFAULT 0x00000001</term>
/// <term>Returns the computer default CSP of the specified type.</term>
/// </item>
/// </list>
/// </param>
/// <param name="pszProvName">
/// <para>A pointer to a null-terminated character string buffer to receive the name of the default CSP.</para>
/// <para>
/// To find the size of the buffer for memory allocation purposes, this parameter can be <c>NULL</c>. For more information, see
/// Retrieving Data of Unknown Length.
/// </para>
/// </param>
/// <param name="pcbProvName">
/// <para>
/// A pointer to a <c>DWORD</c> value that specifies the size, in bytes, of the buffer pointed to by the pszProvName parameter. When
/// the function returns, the <c>DWORD</c> value contains the number of bytes stored or to be stored in the buffer.
/// </para>
/// <para>
/// <c>Note</c> 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 fits 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.
/// </para>
/// </param>
/// <returns>
/// <para>If the function succeeds, the return value is nonzero ( <c>TRUE</c>).</para>
/// <para>If the function fails, the return value is zero ( <c>FALSE</c>). For extended error information, call GetLastError.</para>
/// <para>The error code prefaced by NTE is generated by the particular CSP being used. Possible error codes include the following.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>ERROR_INVALID_PARAMETER</term>
/// <term>One of the parameters contains a value that is not valid. This is most often a pointer that is not valid.</term>
/// </item>
/// <item>
/// <term>ERROR_MORE_DATA</term>
/// <term>The buffer for the name is not large enough.</term>
/// </item>
/// <item>
/// <term>ERROR_NOT_ENOUGH_MEMORY</term>
/// <term>The operating system ran out of memory.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_FLAGS</term>
/// <term>The dwFlags parameter has an unrecognized value.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// This function determines which installed CSP is currently set as the default for the local computer or current user. This
/// information is often displayed to the user.
/// </para>
/// <para>Examples</para>
/// <para>
/// The following example retrieves the name of the default CSP for the PROV_RSA_FULL provider type. For another example that uses
/// this function, see Example C Program: Enumerating CSP Providers and Provider Types.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptgetdefaultprovidera BOOL CryptGetDefaultProviderA(
// DWORD dwProvType, DWORD *pdwReserved, DWORD dwFlags, LPSTR pszProvName, DWORD *pcbProvName );
[DllImport(Lib.AdvApi32, SetLastError = true, CharSet = CharSet.Auto)]
[PInvokeData("wincrypt.h", MSDNShortId = "5d15641e-1ad7-441d-9423-65fd51de9812")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptGetDefaultProvider(uint dwProvType, [Optional] IntPtr pdwReserved, CryptProviderFlags dwFlags, [MarshalAs(UnmanagedType.LPTStr)] StringBuilder pszProvName, ref uint pcbProvName);
/// <summary>
/// The CryptGetHashParam function retrieves data that governs the operations of a hash object. The actual hash value can be
/// retrieved by using this function.
/// </summary>
/// <param name="hHash">Handle of the hash object to be queried.</param>
/// <param name="dwParam">
/// <para>Query type. This parameter can be set to one of the following queries.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>HP_ALGID Hash algorithm</term>
/// <term>
/// An ALG_ID that indicates the algorithm specified when the hash object was created. For a list of hash algorithms, see CryptCreateHash.
/// </term>
/// </item>
/// <item>
/// <term>HP_HASHSIZE Hash value size</term>
/// <term>
/// DWORD value indicating the number of bytes in the hash value. This value will vary depending on the hash algorithm. Applications
/// must retrieve this value just before the HP_HASHVAL value so the correct amount of memory can be allocated.
/// </term>
/// </item>
/// <item>
/// <term>HP_HASHVAL Hash value</term>
/// <term>
/// The hash value or message hash for the hash object specified by hHash. This value is generated based on the data supplied to the
/// hash object earlier through the CryptHashData and CryptHashSessionKey functions. The CryptGetHashParam function completes the
/// hash. After CryptGetHashParam has been called, no more data can be added to the hash. Additional calls to CryptHashData or
/// CryptHashSessionKey fail. After the application is done with the hash, CryptDestroyHash should be called to destroy the hash object.
/// </term>
/// </item>
/// </list>
/// <para><c>Note</c> CSPs can add more values that this function can query.</para>
/// </param>
/// <param name="pbData">
/// <para>A pointer to a buffer that receives the specified value data. The form of this data varies, depending on the value number.</para>
/// <para>This parameter can be <c>NULL</c> to determine the memory size required.</para>
/// </param>
/// <param name="pdwDataLen">
/// <para>
/// A pointer to a <c>DWORD</c> value specifying the size, in bytes, of the pbData buffer. When the function returns, the
/// <c>DWORD</c> value contains the number of bytes stored in the buffer.
/// </para>
/// <para>If pbData is <c>NULL</c>, set the value of pdwDataLen to zero.</para>
/// <para>
/// <c>Note</c> 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 fits 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.
/// </para>
/// </param>
/// <param name="dwFlags">Reserved for future use and must be zero.</param>
/// <returns>
/// <para>If the function succeeds, the return value is <c>TRUE</c>.</para>
/// <para>If the function fails, the return value is <c>FALSE</c>. For extended error information, call GetLastError.</para>
/// <para>The error codes prefaced by "NTE" are generated by the particular CSP you are using. Some possible error codes follow.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>ERROR_INVALID_HANDLE</term>
/// <term>One of the parameters specifies a handle that is not valid.</term>
/// </item>
/// <item>
/// <term>ERROR_INVALID_PARAMETER</term>
/// <term>One of the parameters contains a value that is not valid. This is most often a pointer that is not valid.</term>
/// </item>
/// <item>
/// <term>ERROR_MORE_DATA</term>
/// <term>
/// If the buffer specified by the pbData 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 pdwDataLen.
/// </term>
/// </item>
/// <item>
/// <term>NTE_BAD_FLAGS</term>
/// <term>The dwFlags parameter is nonzero.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_HASH</term>
/// <term>The hash object specified by the hHash parameter is not valid.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_TYPE</term>
/// <term>The dwParam parameter specifies an unknown value number.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_UID</term>
/// <term>The CSP context that was specified when the hash was created cannot be found.</term>
/// </item>
/// </list>
/// </returns>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptgethashparam BOOL CryptGetHashParam( HCRYPTHASH
// hHash, DWORD dwParam, BYTE *pbData, DWORD *pdwDataLen, DWORD dwFlags );
[DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "ed008c07-1a40-4075-bdaa-eb7f7e12d9c3")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptGetHashParam(HCRYPTHASH hHash, HashParam dwParam, [Out, Optional] IntPtr pbData, ref uint pdwDataLen, uint dwFlags = 0);
/// <summary>
/// The CryptGetHashParam function retrieves data that governs the operations of a hash object. The actual hash value can be
/// retrieved by using this function.
/// </summary>
/// <typeparam name="T">The expected return type.</typeparam>
/// <param name="hHash">Handle of the hash object to be queried.</param>
/// <param name="dwParam">
/// <para>Query type. This parameter can be set to one of the following queries.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>HP_ALGID Hash algorithm</term>
/// <term>
/// An ALG_ID that indicates the algorithm specified when the hash object was created. For a list of hash algorithms, see CryptCreateHash.
/// </term>
/// </item>
/// <item>
/// <term>HP_HASHSIZE Hash value size</term>
/// <term>
/// DWORD value indicating the number of bytes in the hash value. This value will vary depending on the hash algorithm. Applications
/// must retrieve this value just before the HP_HASHVAL value so the correct amount of memory can be allocated.
/// </term>
/// </item>
/// <item>
/// <term>HP_HASHVAL Hash value</term>
/// <term>
/// The hash value or message hash for the hash object specified by hHash. This value is generated based on the data supplied to the
/// hash object earlier through the CryptHashData and CryptHashSessionKey functions. The CryptGetHashParam function completes the
/// hash. After CryptGetHashParam has been called, no more data can be added to the hash. Additional calls to CryptHashData or
/// CryptHashSessionKey fail. After the application is done with the hash, CryptDestroyHash should be called to destroy the hash object.
/// </term>
/// </item>
/// </list>
/// <para><c>Note</c> CSPs can add more values that this function can query.</para>
/// </param>
/// <returns>The specified value data. The form of this data varies, depending on the value number.</returns>
public static T CryptGetHashParam<T>(HCRYPTHASH hHash, HashParam dwParam) => CryptGetValue<HCRYPTHASH, HashParam, T>(CryptGetHashParam, hHash, dwParam);
/// <summary>
/// The CryptGetKeyParam function retrieves data that governs the operations of a key. If the Microsoft Cryptographic Service
/// Provider is used, the base symmetric keying material is not obtainable by this or any other function.
/// </summary>
/// <param name="hKey">The handle of the key being queried.</param>
/// <param name="dwParam">
/// <para>Specifies the type of query being made.</para>
/// <para>For all key types, this parameter can contain one of the following values.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>KP_ALGID</term>
/// <term>
/// Retrieve the key algorithm. The pbData parameter is a pointer to an ALG_ID value that receives the identifier of the algorithm
/// that was specified when the key was created. When AT_KEYEXCHANGE or AT_SIGNATURE is specified for the Algid parameter of the
/// CryptGenKey function, the algorithm identifiers that are used to generate the key depend on the provider used. For more
/// information, see ALG_ID.
/// </term>
/// </item>
/// <item>
/// <term>KP_BLOCKLEN</term>
/// <term>
/// If a session key is specified by the hKey parameter, retrieve the block length of the key cipher. The pbData parameter is a
/// pointer to a DWORD value that receives the block length, in bits. For stream ciphers, this value is always zero. If a
/// public/private key pair is specified by hKey, retrieve the encryption granularity of the key pair. The pbData parameter is a
/// pointer to a DWORD value that receives the encryption granularity, in bits. For example, the Microsoft Base Cryptographic
/// Provider generates 512-bit RSA key pairs, so a value of 512 is returned for these keys. If the public key algorithm does not
/// support encryption, the value retrieved is undefined.
/// </term>
/// </item>
/// <item>
/// <term>KP_CERTIFICATE</term>
/// <term>
/// pbData is the address of a buffer that receives the X.509 certificate that has been encoded by using Distinguished Encoding
/// Rules (DER). The public key in the certificate must match the corresponding signature or exchange key.
/// </term>
/// </item>
/// <item>
/// <term>KP_GET_USE_COUNT</term>
/// <term>This value is not used.</term>
/// </item>
/// <item>
/// <term>KP_KEYLEN</term>
/// <term>
/// Retrieve the actual length of the key. The pbData parameter is a pointer to a DWORD value that receives the key length, in bits.
/// KP_KEYLEN can be used to get the length of any key type. Microsoft cryptographic service providers (CSPs) return a key length of
/// 64 bits for CALG_DES, 128 bits for CALG_3DES_112, and 192 bits for CALG_3DES. These lengths are different from the lengths
/// returned when you are enumerating algorithms with the dwParam value of the CryptGetProvParam function set to PP_ENUMALGS. The
/// length returned by this call is the actual size of the key, including the parity bits included in the key. Microsoft CSPs that
/// support the CALG_CYLINK_MEK ALG_ID return 64 bits for that algorithm. CALG_CYLINK_MEK is a 40-bit key but has parity and zeroed
/// key bits to make the key length 64 bits.
/// </term>
/// </item>
/// <item>
/// <term>KP_SALT</term>
/// <term>
/// Retrieve the salt value of the key. The pbData parameter is a pointer to a BYTE array that receives the salt value in
/// little-endian form. The size of the salt value varies depending on the CSP and algorithm being used. Salt values do not apply to
/// public/private key pairs.
/// </term>
/// </item>
/// <item>
/// <term>KP_PERMISSIONS</term>
/// <term>
/// Retrieve the key permissions. The pbData parameter is a pointer to a DWORD value that receives the permission flags for the key.
/// The following permission identifiers are currently defined. The key permissions can be zero or a combination of one or more of
/// the following values. CRYPT_ARCHIVE Allow export during the lifetime of the handle of the key. This permission can be set only
/// if it is already set in the internal permissions field of the key. Attempts to clear this permission are ignored. CRYPT_DECRYPT
/// Allow decryption. CRYPT_ENCRYPT Allow encryption. CRYPT_EXPORT Allow the key to be exported. CRYPT_EXPORT_KEY Allow the key to
/// be used for exporting keys. CRYPT_IMPORT_KEY Allow the key to be used for importing keys. CRYPT_MAC Allow Message Authentication
/// Codes (MACs) to be used with key. CRYPT_READ Allow values to be read. CRYPT_WRITE Allow values to be set.
/// </term>
/// </item>
/// </list>
/// <para>
/// If a Digital Signature Standard (DSS) key is specified by the hKey parameter, the dwParam value can also be set to one of the
/// following values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>KP_P</term>
/// <term>
/// Retrieve the modulus prime number P of the DSS key. The pbData parameter is a pointer to a buffer that receives the value in
/// little-endian form. The pdwDataLen parameter contains the size of the buffer, in bytes.
/// </term>
/// </item>
/// <item>
/// <term>KP_Q</term>
/// <term>
/// Retrieve the modulus prime number Q of the DSS key. The pbData parameter is a pointer to a buffer that receives the value in
/// little-endian form. The pdwDataLen parameter contains the size of the buffer, in bytes.
/// </term>
/// </item>
/// <item>
/// <term>KP_G</term>
/// <term>
/// Retrieve the generator G of the DSS key. The pbData parameter is a pointer to a buffer that receives the value in little-endian
/// form. The pdwDataLen parameter contains the size of the buffer, in bytes.
/// </term>
/// </item>
/// </list>
/// <para>
/// If a block cipher session key is specified by the hKey parameter, the dwParam value can also be set to one of the following values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>KP_EFFECTIVE_KEYLEN</term>
/// <term>
/// Retrieve the effective key length of an RC2 key. The pbData parameter is a pointer to a DWORD value that receives the effective
/// key length.
/// </term>
/// </item>
/// <item>
/// <term>KP_IV</term>
/// <term>
/// Retrieve the initialization vector of the key. The pbData parameter is a pointer to a BYTE array that receives the
/// initialization vector. The size of this array is the block size, in bytes. For example, if the block length is 64 bits, the
/// initialization vector consists of 8 bytes.
/// </term>
/// </item>
/// <item>
/// <term>KP_PADDING</term>
/// <term>
/// Retrieve the padding mode. The pbData parameter is a pointer to a DWORD value that receives a numeric identifier that identifies
/// the padding method used by the cipher. This can be one of the following values. PKCS5_PADDING Specifies the PKCS 5 (sec 6.2)
/// padding method. RANDOM_PADDING The padding uses random numbers. This padding method is not supported by the Microsoft supplied
/// CSPs. ZERO_PADDING The padding uses zeros. This padding method is not supported by the Microsoft supplied CSPs.
/// </term>
/// </item>
/// <item>
/// <term>KP_MODE</term>
/// <term>
/// Retrieve the cipher mode. The pbData parameter is a pointer to a DWORD value that receives a cipher mode identifier. For more
/// information about cipher modes, see Data Encryption and Decryption. The following cipher mode identifiers are currently defined.
/// CRYPT_MODE_CBC The cipher mode is cipher block chaining. CRYPT_MODE_CFB The cipher mode is cipher feedback (CFB). Microsoft CSPs
/// currently support only 8-bit feedback in cipher feedback mode. CRYPT_MODE_ECB The cipher mode is electronic codebook.
/// CRYPT_MODE_OFB The cipher mode is Output Feedback (OFB). Microsoft CSPs currently do not support Output Feedback Mode.
/// CRYPT_MODE_CTS The cipher mode is ciphertext stealing mode.
/// </term>
/// </item>
/// <item>
/// <term>KP_MODE_BITS</term>
/// <term>
/// Retrieve the number of bits to feed back. The pbData parameter is a pointer to a DWORD value that receives the number of bits
/// that are processed per cycle when the OFB or CFB cipher modes are used.
/// </term>
/// </item>
/// </list>
/// <para>
/// If a Diffie-Hellman algorithm or Digital Signature Algorithm (DSA) key is specified by hKey, the dwParam value can also be set
/// to the following value.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>KP_VERIFY_PARAMS</term>
/// <term>
/// Verifies the parameters of a Diffie-Hellman algorithm or DSA key. The pbData parameter is not used, and the value pointed to by
/// pdwDataLen receives zero. This function returns a nonzero value if the key parameters are valid or zero otherwise.
/// </term>
/// </item>
/// <item>
/// <term>KP_KEYVAL</term>
/// <term>
/// This value is not used. Windows Vista, Windows Server 2003 and Windows XP: Retrieve the secret agreement value from an imported
/// Diffie-Hellman algorithm key of type CALG_AGREEDKEY_ANY. The pbData parameter is the address of a buffer that receives the
/// secret agreement value, in little-endian format. This buffer must be the same length as the key. The dwFlags parameter must be
/// set to 0xF42A19B6. This property can only be retrieved by a thread running under the local system account.This property is
/// available for use in the operating systems listed above. It may be altered or unavailable in subsequent versions.
/// </term>
/// </item>
/// </list>
/// <para>If a certificate is specified by hKey, the dwParam value can also be set to the following value.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>KP_CERTIFICATE</term>
/// <term>
/// A buffer that contains the DER-encoded X.509 certificate. The pbData parameter is not used, and the value pointed to by
/// pdwDataLen receives zero. This function returns a nonzero value if the key parameters are valid or zero otherwise.
/// </term>
/// </item>
/// </list>
/// </param>
/// <param name="pbData">
/// <para>A pointer to a buffer that receives the data. The form of this data depends on the value of dwParam.</para>
/// <para>
/// If the size of this buffer is not known, the required size can be retrieved at run time by passing <c>NULL</c> for this
/// parameter and setting the value pointed to by pdwDataLen to zero. This function will place the required size of the buffer, in
/// bytes, in the value pointed to by pdwDataLen. For more information, see Retrieving Data of Unknown Length.
/// </para>
/// </param>
/// <param name="pdwDataLen">
/// <para>
/// A pointer to a <c>DWORD</c> value that, on entry, contains the size, in bytes, of the buffer pointed to by the pbData parameter.
/// When the function returns, the <c>DWORD</c> value contains the number of bytes stored in the buffer.
/// </para>
/// <para>
/// <c>Note</c> When processing the data returned in the buffer, applications must use the actual size of the data returned. The
/// actual size may be slightly smaller than the size of the buffer specified on input. On input, buffer sizes are sometimes
/// specified large enough to ensure that the largest possible output data fits 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.
/// </para>
/// </param>
/// <param name="dwFlags">This parameter is reserved for future use and must be set to zero.</param>
/// <returns>
/// <para>If the function succeeds, the function returns nonzero.</para>
/// <para>If the function fails, it returns zero. For extended error information, call GetLastError.</para>
/// <para>
/// The error codes prefaced by "NTE" are generated by the particular CSP being used. Some possible error codes include the following.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>ERROR_INVALID_HANDLE</term>
/// <term>One of the parameters specifies a handle that is not valid.</term>
/// </item>
/// <item>
/// <term>ERROR_INVALID_PARAMETER</term>
/// <term>One of the parameters contains a value that is not valid. This is most often a pointer that is not valid.</term>
/// </item>
/// <item>
/// <term>ERROR_MORE_DATA</term>
/// <term>
/// If the buffer specified by the pbData 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 pdwDataLen.
/// </term>
/// </item>
/// <item>
/// <term>NTE_BAD_FLAGS</term>
/// <term>The dwFlags parameter is nonzero.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_KEY or NTE_NO_KEY</term>
/// <term>The key specified by the hKey parameter is not valid.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_TYPE</term>
/// <term>The dwParam parameter specifies an unknown value number.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_UID</term>
/// <term>The CSP context that was specified when the key was created cannot be found.</term>
/// </item>
/// </list>
/// </returns>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptgetkeyparam BOOL CryptGetKeyParam( HCRYPTKEY hKey,
// DWORD dwParam, BYTE *pbData, DWORD *pdwDataLen, DWORD dwFlags );
[DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "07956d74-0e22-484b-9bf1-e0184a2ff32f")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptGetKeyParam(HCRYPTKEY hKey, KeyParam dwParam, [Out, Optional] IntPtr pbData, ref uint pdwDataLen, uint dwFlags = 0);
/// <summary>
/// The CryptGetKeyParam function retrieves data that governs the operations of a key. If the Microsoft Cryptographic Service
/// Provider is used, the base symmetric keying material is not obtainable by this or any other function.
/// </summary>
/// <typeparam name="T">The expected return type.</typeparam>
/// <param name="hKey">The handle of the key being queried.</param>
/// <param name="dwParam">
/// <para>Specifies the type of query being made.</para>
/// <para>For all key types, this parameter can contain one of the following values.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>KP_ALGID</term>
/// <term>
/// Retrieve the key algorithm. The pbData parameter is a pointer to an ALG_ID value that receives the identifier of the algorithm
/// that was specified when the key was created. When AT_KEYEXCHANGE or AT_SIGNATURE is specified for the Algid parameter of the
/// CryptGenKey function, the algorithm identifiers that are used to generate the key depend on the provider used. For more
/// information, see ALG_ID.
/// </term>
/// </item>
/// <item>
/// <term>KP_BLOCKLEN</term>
/// <term>
/// If a session key is specified by the hKey parameter, retrieve the block length of the key cipher. The pbData parameter is a
/// pointer to a DWORD value that receives the block length, in bits. For stream ciphers, this value is always zero. If a
/// public/private key pair is specified by hKey, retrieve the encryption granularity of the key pair. The pbData parameter is a
/// pointer to a DWORD value that receives the encryption granularity, in bits. For example, the Microsoft Base Cryptographic
/// Provider generates 512-bit RSA key pairs, so a value of 512 is returned for these keys. If the public key algorithm does not
/// support encryption, the value retrieved is undefined.
/// </term>
/// </item>
/// <item>
/// <term>KP_CERTIFICATE</term>
/// <term>
/// pbData is the address of a buffer that receives the X.509 certificate that has been encoded by using Distinguished Encoding
/// Rules (DER). The public key in the certificate must match the corresponding signature or exchange key.
/// </term>
/// </item>
/// <item>
/// <term>KP_GET_USE_COUNT</term>
/// <term>This value is not used.</term>
/// </item>
/// <item>
/// <term>KP_KEYLEN</term>
/// <term>
/// Retrieve the actual length of the key. The pbData parameter is a pointer to a DWORD value that receives the key length, in bits.
/// KP_KEYLEN can be used to get the length of any key type. Microsoft cryptographic service providers (CSPs) return a key length of
/// 64 bits for CALG_DES, 128 bits for CALG_3DES_112, and 192 bits for CALG_3DES. These lengths are different from the lengths
/// returned when you are enumerating algorithms with the dwParam value of the CryptGetProvParam function set to PP_ENUMALGS. The
/// length returned by this call is the actual size of the key, including the parity bits included in the key. Microsoft CSPs that
/// support the CALG_CYLINK_MEK ALG_ID return 64 bits for that algorithm. CALG_CYLINK_MEK is a 40-bit key but has parity and zeroed
/// key bits to make the key length 64 bits.
/// </term>
/// </item>
/// <item>
/// <term>KP_SALT</term>
/// <term>
/// Retrieve the salt value of the key. The pbData parameter is a pointer to a BYTE array that receives the salt value in
/// little-endian form. The size of the salt value varies depending on the CSP and algorithm being used. Salt values do not apply to
/// public/private key pairs.
/// </term>
/// </item>
/// <item>
/// <term>KP_PERMISSIONS</term>
/// <term>
/// Retrieve the key permissions. The pbData parameter is a pointer to a DWORD value that receives the permission flags for the key.
/// The following permission identifiers are currently defined. The key permissions can be zero or a combination of one or more of
/// the following values. CRYPT_ARCHIVE Allow export during the lifetime of the handle of the key. This permission can be set only
/// if it is already set in the internal permissions field of the key. Attempts to clear this permission are ignored. CRYPT_DECRYPT
/// Allow decryption. CRYPT_ENCRYPT Allow encryption. CRYPT_EXPORT Allow the key to be exported. CRYPT_EXPORT_KEY Allow the key to
/// be used for exporting keys. CRYPT_IMPORT_KEY Allow the key to be used for importing keys. CRYPT_MAC Allow Message Authentication
/// Codes (MACs) to be used with key. CRYPT_READ Allow values to be read. CRYPT_WRITE Allow values to be set.
/// </term>
/// </item>
/// </list>
/// <para>
/// If a Digital Signature Standard (DSS) key is specified by the hKey parameter, the dwParam value can also be set to one of the
/// following values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>KP_P</term>
/// <term>
/// Retrieve the modulus prime number P of the DSS key. The pbData parameter is a pointer to a buffer that receives the value in
/// little-endian form. The pdwDataLen parameter contains the size of the buffer, in bytes.
/// </term>
/// </item>
/// <item>
/// <term>KP_Q</term>
/// <term>
/// Retrieve the modulus prime number Q of the DSS key. The pbData parameter is a pointer to a buffer that receives the value in
/// little-endian form. The pdwDataLen parameter contains the size of the buffer, in bytes.
/// </term>
/// </item>
/// <item>
/// <term>KP_G</term>
/// <term>
/// Retrieve the generator G of the DSS key. The pbData parameter is a pointer to a buffer that receives the value in little-endian
/// form. The pdwDataLen parameter contains the size of the buffer, in bytes.
/// </term>
/// </item>
/// </list>
/// <para>
/// If a block cipher session key is specified by the hKey parameter, the dwParam value can also be set to one of the following values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>KP_EFFECTIVE_KEYLEN</term>
/// <term>
/// Retrieve the effective key length of an RC2 key. The pbData parameter is a pointer to a DWORD value that receives the effective
/// key length.
/// </term>
/// </item>
/// <item>
/// <term>KP_IV</term>
/// <term>
/// Retrieve the initialization vector of the key. The pbData parameter is a pointer to a BYTE array that receives the
/// initialization vector. The size of this array is the block size, in bytes. For example, if the block length is 64 bits, the
/// initialization vector consists of 8 bytes.
/// </term>
/// </item>
/// <item>
/// <term>KP_PADDING</term>
/// <term>
/// Retrieve the padding mode. The pbData parameter is a pointer to a DWORD value that receives a numeric identifier that identifies
/// the padding method used by the cipher. This can be one of the following values. PKCS5_PADDING Specifies the PKCS 5 (sec 6.2)
/// padding method. RANDOM_PADDING The padding uses random numbers. This padding method is not supported by the Microsoft supplied
/// CSPs. ZERO_PADDING The padding uses zeros. This padding method is not supported by the Microsoft supplied CSPs.
/// </term>
/// </item>
/// <item>
/// <term>KP_MODE</term>
/// <term>
/// Retrieve the cipher mode. The pbData parameter is a pointer to a DWORD value that receives a cipher mode identifier. For more
/// information about cipher modes, see Data Encryption and Decryption. The following cipher mode identifiers are currently defined.
/// CRYPT_MODE_CBC The cipher mode is cipher block chaining. CRYPT_MODE_CFB The cipher mode is cipher feedback (CFB). Microsoft CSPs
/// currently support only 8-bit feedback in cipher feedback mode. CRYPT_MODE_ECB The cipher mode is electronic codebook.
/// CRYPT_MODE_OFB The cipher mode is Output Feedback (OFB). Microsoft CSPs currently do not support Output Feedback Mode.
/// CRYPT_MODE_CTS The cipher mode is ciphertext stealing mode.
/// </term>
/// </item>
/// <item>
/// <term>KP_MODE_BITS</term>
/// <term>
/// Retrieve the number of bits to feed back. The pbData parameter is a pointer to a DWORD value that receives the number of bits
/// that are processed per cycle when the OFB or CFB cipher modes are used.
/// </term>
/// </item>
/// </list>
/// <para>
/// If a Diffie-Hellman algorithm or Digital Signature Algorithm (DSA) key is specified by hKey, the dwParam value can also be set
/// to the following value.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>KP_VERIFY_PARAMS</term>
/// <term>
/// Verifies the parameters of a Diffie-Hellman algorithm or DSA key. The pbData parameter is not used, and the value pointed to by
/// pdwDataLen receives zero. This function returns a nonzero value if the key parameters are valid or zero otherwise.
/// </term>
/// </item>
/// <item>
/// <term>KP_KEYVAL</term>
/// <term>
/// This value is not used. Windows Vista, Windows Server 2003 and Windows XP: Retrieve the secret agreement value from an imported
/// Diffie-Hellman algorithm key of type CALG_AGREEDKEY_ANY. The pbData parameter is the address of a buffer that receives the
/// secret agreement value, in little-endian format. This buffer must be the same length as the key. The dwFlags parameter must be
/// set to 0xF42A19B6. This property can only be retrieved by a thread running under the local system account.This property is
/// available for use in the operating systems listed above. It may be altered or unavailable in subsequent versions.
/// </term>
/// </item>
/// </list>
/// <para>If a certificate is specified by hKey, the dwParam value can also be set to the following value.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>KP_CERTIFICATE</term>
/// <term>
/// A buffer that contains the DER-encoded X.509 certificate. The pbData parameter is not used, and the value pointed to by
/// pdwDataLen receives zero. This function returns a nonzero value if the key parameters are valid or zero otherwise.
/// </term>
/// </item>
/// </list>
/// </param>
/// <returns>The specified value data. The form of this data varies, depending on the value number.</returns>
public static T CryptGetKeyParam<T>(HCRYPTKEY hKey, KeyParam dwParam) => CryptGetValue<HCRYPTKEY, KeyParam, T>(CryptGetKeyParam, hKey, dwParam);
/// <summary>
/// The CryptGetProvParam function retrieves parameters that govern the operations of a cryptographic service provider (CSP).
/// </summary>
/// <param name="hProv">
/// A handle of the CSP target of the query. This handle must have been created by using the CryptAcquireContext function.
/// </param>
/// <param name="dwParam">
/// <para>The nature of the query. The following queries are defined.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>PP_ADMIN_PIN 31 (0x1F)</term>
/// <term>Returns the administrator personal identification number (PIN) in the pbData parameter as a LPSTR.</term>
/// </item>
/// <item>
/// <term>PP_APPLI_CERT 18 (0x12)</term>
/// <term>This constant is not used.</term>
/// </item>
/// <item>
/// <term>PP_CHANGE_PASSWORD 7 (0x7)</term>
/// <term>This constant is not used.</term>
/// </item>
/// <item>
/// <term>PP_CERTCHAIN 9 (0x9)</term>
/// <term>Returns the certificate chain associated with the hProv handle. The returned certificate chain is X509_ASN_ENCODING encoded.</term>
/// </item>
/// <item>
/// <term>PP_CONTAINER 6 (0x6)</term>
/// <term>
/// The name of the current key container as a null-terminated CHAR string. This string is exactly the same as the one passed in the
/// pszContainer parameter of the CryptAcquireContext function to specify the key container to use. The pszContainer parameter can
/// be read to determine the name of the default key container.
/// </term>
/// </item>
/// <item>
/// <term>PP_CRYPT_COUNT_KEY_USE 41 (0x29)</term>
/// <term>Not implemented by Microsoft CSPs. This behavior may be implemented by other CSPs. Windows XP: This parameter is not supported.</term>
/// </item>
/// <item>
/// <term>PP_ENUMALGS 1 (0x1)</term>
/// <term>
/// A PROV_ENUMALGS structure that contains information about one algorithm supported by the CSP being queried. The first time this
/// value is read, the dwFlags parameter must contain the CRYPT_FIRST flag. Doing so causes this function to retrieve the first
/// element in the enumeration. The subsequent elements can then be retrieved by setting the CRYPT_NEXT flag in the dwFlags
/// parameter. When this function fails with the ERROR_NO_MORE_ITEMS error code, the end of the enumeration has been reached. This
/// function is not thread safe, and all of the available algorithms might not be enumerated if this function is used in a
/// multithreaded context.
/// </term>
/// </item>
/// <item>
/// <term>PP_ENUMALGS_EX 22 (0x16)</term>
/// <term>
/// A PROV_ENUMALGS_EX structure that contains information about one algorithm supported by the CSP being queried. The structure
/// returned contains more information about the algorithm than the structure returned for PP_ENUMALGS. The first time this value is
/// read, the dwFlags parameter must contain the CRYPT_FIRST flag. Doing so causes this function to retrieve the first element in
/// the enumeration. The subsequent elements can then be retrieved by setting the CRYPT_NEXT flag in the dwFlags parameter. When
/// this function fails with the ERROR_NO_MORE_ITEMS error code, the end of the enumeration has been reached. This function is not
/// thread safe and all of the available algorithms might not be enumerated if this function is used in a multithreaded context.
/// </term>
/// </item>
/// <item>
/// <term>PP_ENUMCONTAINERS 2 (0x2)</term>
/// <term>
/// The name of one of the key containers maintained by the CSP in the form of a null-terminated CHAR string. The first time this
/// value is read, the dwFlags parameter must contain the CRYPT_FIRST flag. Doing so causes this function to retrieve the first
/// element in the enumeration. The subsequent elements can then be retrieved by setting the CRYPT_NEXT flag in the dwFlags
/// parameter. When this function fails with the ERROR_NO_MORE_ITEMS error code, the end of the enumeration has been reached. To
/// enumerate key containers associated with a computer, first call CryptAcquireContext using the CRYPT_MACHINE_KEYSET flag, and
/// then use the handle returned from CryptAcquireContext as the hProv parameter in the call to CryptGetProvParam. This function is
/// not thread safe and all of the available algorithms might not be enumerated if this function is used in a multithreaded context.
/// </term>
/// </item>
/// <item>
/// <term>PP_ENUMELECTROOTS 26 (0x1A)</term>
/// <term>This constant is not used.</term>
/// </item>
/// <item>
/// <term>PP_ENUMEX_SIGNING_PROT 40 (0x28)</term>
/// <term>
/// Indicates that the current CSP supports the dwProtocols member of the PROV_ENUMALGS_EX structure. If this function succeeds, the
/// CSP supports the dwProtocols member of the PROV_ENUMALGS_EX structure. If this function fails with an NTE_BAD_TYPE error code,
/// the CSP does not support the dwProtocols member.
/// </term>
/// </item>
/// <item>
/// <term>PP_ENUMMANDROOTS 25 (0x19)</term>
/// <term>This constant is not used.</term>
/// </item>
/// <item>
/// <term>PP_IMPTYPE 3 (0x3)</term>
/// <term>A DWORD value that indicates how the CSP is implemented. For a table of possible values, see Remarks.</term>
/// </item>
/// <item>
/// <term>PP_KEY_TYPE_SUBTYPE 10 (0xA)</term>
/// <term>This query is not used.</term>
/// </item>
/// <item>
/// <term>PP_KEYEXCHANGE_PIN 32 (0x20)</term>
/// <term>Specifies that the key exchange PIN is contained in pbData. The PIN is represented as a null-terminated ASCII string.</term>
/// </item>
/// <item>
/// <term>PP_KEYSET_SEC_DESCR 8 (0x8)</term>
/// <term>
/// Retrieves the security descriptor for the key storage container. The pbData parameter is the address of a SECURITY_DESCRIPTOR
/// structure that receives the security descriptor for the key storage container. The security descriptor is returned in
/// self-relative format.
/// </term>
/// </item>
/// <item>
/// <term>PP_KEYSET_TYPE 27 (0x1B)</term>
/// <term>
/// Determines whether the hProv parameter is a computer key set. The pbData parameter must be a DWORD; the DWORD will be set to the
/// CRYPT_MACHINE_KEYSET flag if that flag was passed to the CryptAcquireContext function.
/// </term>
/// </item>
/// <item>
/// <term>PP_KEYSPEC 39 (0x27)</term>
/// <term>
/// Returns information about the key specifier values that the CSP supports. Key specifier values are joined in a logical OR and
/// returned in the pbData parameter of the call as a DWORD. For example, the Microsoft Base Cryptographic Provider version 1.0
/// returns a DWORD value of AT_SIGNATURE | AT_KEYEXCHANGE.
/// </term>
/// </item>
/// <item>
/// <term>PP_KEYSTORAGE 17 (0x11)</term>
/// <term>Returns a DWORD value of CRYPT_SEC_DESCR.</term>
/// </item>
/// <item>
/// <term>PP_KEYX_KEYSIZE_INC 35 (0x23)</term>
/// <term>
/// The number of bits for the increment length of AT_KEYEXCHANGE. This information is used with information returned in the
/// PP_ENUMALGS_EX value. With the information returned when using PP_ENUMALGS_EX and PP_KEYX_KEYSIZE_INC, the valid key lengths for
/// AT_KEYEXCHANGE can be determined. These key lengths can then be used with CryptGenKey. For example if a CSP enumerates
/// CALG_RSA_KEYX (AT_KEYEXCHANGE) with a minimum key length of 512 bits and a maximum of 1024 bits, and returns the increment
/// length as 64 bits, then valid key lengths are 512, 576, 640,… 1024.
/// </term>
/// </item>
/// <item>
/// <term>PP_NAME 4 (0x4)</term>
/// <term>
/// The name of the CSP in the form of a null-terminated CHAR string. This string is identical to the one passed in the pszProvider
/// parameter of the CryptAcquireContext function to specify that the current CSP be used.
/// </term>
/// </item>
/// <item>
/// <term>PP_PROVTYPE 16 (0x10)</term>
/// <term>A DWORD value that indicates the provider type of the CSP.</term>
/// </item>
/// <item>
/// <term>PP_ROOT_CERTSTORE 46 (0x2E)</term>
/// <term>
/// Obtains the root certificate store for the smart card. This certificate store contains all of the root certificates that are
/// stored on the smart card. The pbData parameter is the address of an HCERTSTORE variable that receives the handle of the
/// certificate store. When this handle is no longer needed, the caller must close it by using the CertCloseStore function. Windows
/// Server 2003 and Windows XP: This parameter is not supported.
/// </term>
/// </item>
/// <item>
/// <term>PP_SESSION_KEYSIZE 20 (0x14)</term>
/// <term>The size, in bits, of the session key.</term>
/// </item>
/// <item>
/// <term>PP_SGC_INFO 37 (0x25)</term>
/// <term>Used with server gated cryptography.</term>
/// </item>
/// <item>
/// <term>PP_SIG_KEYSIZE_INC 34 (0x22)</term>
/// <term>
/// The number of bits for the increment length of AT_SIGNATURE. This information is used with information returned in the
/// PP_ENUMALGS_EX value. With the information returned when using PP_ENUMALGS_EX and PP_SIG_KEYSIZE_INC, the valid key lengths for
/// AT_SIGNATURE can be determined. These key lengths can then be used with CryptGenKey. For example, if a CSP enumerates
/// CALG_RSA_SIGN (AT_SIGNATURE) with a minimum key length of 512 bits and a maximum of 1024 bits, and returns the increment length
/// as 64 bits, then valid key lengths are 512, 576, 640,… 1024.
/// </term>
/// </item>
/// <item>
/// <term>PP_SIGNATURE_PIN 33 (0x21)</term>
/// <term>Specifies that the key signature PIN is contained in pbData. The PIN is represented as a null-terminated ASCII string.</term>
/// </item>
/// <item>
/// <term>PP_SMARTCARD_GUID 45 (0x2D)</term>
/// <term>
/// Obtains the identifier of the smart card. The pbData parameter is the address of a GUID structure that receives the identifier
/// of the smart card. Windows Server 2003 and Windows XP: This parameter is not supported.
/// </term>
/// </item>
/// <item>
/// <term>PP_SMARTCARD_READER 43 (0x2B)</term>
/// <term>
/// Obtains the name of the smart card reader. The pbData parameter is the address of an ANSI character array that receives a
/// null-terminated ANSI string that contains the name of the smart card reader. The size of this buffer, contained in the variable
/// pointed to by the pdwDataLen parameter, must include the NULL terminator. Windows Server 2003 and Windows XP: This parameter is
/// not supported.
/// </term>
/// </item>
/// <item>
/// <term>PP_SYM_KEYSIZE 19 (0x13)</term>
/// <term>The size of the symmetric key.</term>
/// </item>
/// <item>
/// <term>PP_UI_PROMPT 21 (0x15)</term>
/// <term>This query is not used.</term>
/// </item>
/// <item>
/// <term>PP_UNIQUE_CONTAINER 36 (0x24)</term>
/// <term>
/// The unique container name of the current key container in the form of a null-terminated CHAR string. For many CSPs, this name is
/// the same name returned when the PP_CONTAINER value is used. The CryptAcquireContext function must work with this container name.
/// </term>
/// </item>
/// <item>
/// <term>PP_USE_HARDWARE_RNG 38 (0x26)</term>
/// <term>
/// Indicates whether a hardware random number generator (RNG) is supported. When PP_USE_HARDWARE_RNG is specified, the function
/// succeeds and returns TRUE if a hardware RNG is supported. The function fails and returns FALSE if a hardware RNG is not
/// supported. If a RNG is supported, PP_USE_HARDWARE_RNG can be set in CryptSetProvParam to indicate that the CSP must exclusively
/// use the hardware RNG for this provider context. When PP_USE_HARDWARE_RNG is used, the pbData parameter must be NULL and dwFlags
/// must be zero. None of the Microsoft CSPs currently support using a hardware RNG.
/// </term>
/// </item>
/// <item>
/// <term>PP_USER_CERTSTORE 42 (0x2A)</term>
/// <term>
/// Obtains the user certificate store for the smart card. This certificate store contains all of the user certificates that are
/// stored on the smart card. The certificates in this store are encoded by using PKCS_7_ASN_ENCODING or X509_ASN_ENCODING encoding
/// and should contain the CERT_KEY_PROV_INFO_PROP_ID property. The pbData parameter is the address of an HCERTSTORE variable that
/// receives the handle of an in-memory certificate store. When this handle is no longer needed, the caller must close it by using
/// the CertCloseStore function. Windows Server 2003 and Windows XP: This parameter is not supported.
/// </term>
/// </item>
/// <item>
/// <term>PP_VERSION 5 (0x5)</term>
/// <term>
/// The version number of the CSP. The least significant byte contains the minor version number and the next most significant byte
/// the major version number. Version 2.0 is represented as 0x00000200. To maintain backward compatibility with earlier versions of
/// the Microsoft Base Cryptographic Provider and the Microsoft Enhanced Cryptographic Provider, the provider names retain the
/// "v1.0" designation in later versions.
/// </term>
/// </item>
/// </list>
/// </param>
/// <param name="pbData">
/// <para>
/// A pointer to a buffer to receive the data. The form of this data varies depending on the value of dwParam. When dwParam is set
/// to PP_USE_HARDWARE_RNG, pbData must be set to <c>NULL</c>.
/// </para>
/// <para>
/// This parameter can be <c>NULL</c> to set the size of this information for memory allocation purposes. For more information, see
/// Retrieving Data of Unknown Length.
/// </para>
/// </param>
/// <param name="pdwDataLen">
/// <para>
/// A pointer to a <c>DWORD</c> value that specifies the size, in bytes, of the buffer pointed to by the pbData parameter. When the
/// function returns, the <c>DWORD</c> value contains the number of bytes stored or to be stored in the buffer.
/// </para>
/// <para>
/// <c>Note</c> 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 fits 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 PP_ENUMALGS, or PP_ENUMALGS_EX is
/// set, the pdwDataLen parameter works somewhat differently. If pbData is <c>NULL</c> or the value pointed to by pdwDataLen is too
/// small, the value returned in this parameter is the size of the largest item in the enumeration list instead of the size of the
/// item currently being read. If PP_ENUMCONTAINERS is set, the first call to the function returns the size of the maximum
/// key-container allowed by the current provider. This is in contrast to other possible behaviors, like returning the length of the
/// longest existing container, or the length of the current container. Subsequent enumerating calls will not change the dwLen
/// parameter. For each enumerated container, the caller can determine the length of the <c>null</c>-terminated string
/// programmatically, if desired. If one of the enumeration values is read and the pbData parameter is <c>NULL</c>, the CRYPT_FIRST
/// flag must be specified for the size information to be correctly retrieved.
/// </para>
/// </param>
/// <param name="dwFlags">
/// <para>
/// If dwParam is <c>PP_KEYSET_SEC_DESCR</c>, the security descriptor on the key container where the keys are stored is retrieved.
/// For this case, dwFlags is used to pass in the <c>SECURITY_INFORMATION</c> bit flags that indicate the requested security
/// information, as defined in the Platform SDK. <c>SECURITY_INFORMATION</c> bit flags can be combined with a bitwise- <c>OR</c> operation.
/// </para>
/// <para>The following values are defined for use with <c>PP_KEYSET_SEC_DESCR</c>.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>OWNER_SECURITY_INFORMATION</term>
/// <term>Owner identifier of the object is being referenced.</term>
/// </item>
/// <item>
/// <term>GROUP_SECURITY_INFORMATION</term>
/// <term>Primary group identifier of the object is being referenced.</term>
/// </item>
/// <item>
/// <term>DACL_SECURITY_INFORMATION</term>
/// <term>Discretionary ACL of the object is being referenced.</term>
/// </item>
/// <item>
/// <term>SACL_SECURITY_INFORMATION</term>
/// <term>System ACL of the object is being referenced.</term>
/// </item>
/// </list>
/// <para>The following values are defined for use with <c>PP_ENUMALGS</c>, <c>PP_ENUMALGS_EX</c>, and <c>PP_ENUMCONTAINERS</c>.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>CRYPT_FIRST 1 (0x1)</term>
/// <term>Retrieve the first element in the enumeration. This has the same effect as resetting the enumerator.</term>
/// </item>
/// <item>
/// <term>CRYPT_NEXT 2 (0x2)</term>
/// <term>
/// Retrieve the next element in the enumeration. When there are no more elements to retrieve, this function will fail and set the
/// last error to ERROR_NO_MORE_ITEMS.
/// </term>
/// </item>
/// <item>
/// <term>CRYPT_SGC_ENUM 4 (0x4)</term>
/// <term>
/// Retrieve server-gated cryptography (SGC) enabled certificates. SGC enabled certificates are no longer supported. For more
/// information, see Microsoft Support Article 875450.
/// </term>
/// </item>
/// <item>
/// <term>CRYPT_SGC</term>
/// <term>This flag is not used.</term>
/// </item>
/// <item>
/// <term>CRYPT_FASTSGC</term>
/// <term>This flag is not used.</term>
/// </item>
/// </list>
/// </param>
/// <returns>
/// <para>If the function succeeds, the return value is nonzero ( <c>TRUE</c>).</para>
/// <para>If the function fails, the return value is zero ( <c>FALSE</c>). For extended error information, call GetLastError.</para>
/// <para>The error codes prefaced by NTE are generated by the particular CSP being used. Some possible error codes follow.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>ERROR_INVALID_HANDLE</term>
/// <term>One of the parameters specifies a handle that is not valid.</term>
/// </item>
/// <item>
/// <term>ERROR_INVALID_PARAMETER</term>
/// <term>One of the parameters contains a value that is not valid. This is most often a pointer that is not valid.</term>
/// </item>
/// <item>
/// <term>ERROR_MORE_DATA</term>
/// <term>
/// If the buffer specified by the pbData 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 pdwDataLen.
/// </term>
/// </item>
/// <item>
/// <term>ERROR_NO_MORE_ITEMS</term>
/// <term>
/// The end of the enumeration list has been reached. No valid data has been placed in the pbData buffer. This error code is
/// returned only when dwParam equals PP_ENUMALGS or PP_ENUMCONTAINERS.
/// </term>
/// </item>
/// <item>
/// <term>NTE_BAD_FLAGS</term>
/// <term>The dwFlags parameter specifies a flag that is not valid.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_TYPE</term>
/// <term>The dwParam parameter specifies an unknown value number.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_UID</term>
/// <term>The CSP context specified by hProv is not valid.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>This function must not be used on a thread of a multithreaded program.</para>
/// <para>The following values are returned in pbData if dwParam is PP_IMPTYPE.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>CRYPT_IMPL_HARDWARE1</term>
/// <term>Implementation is in hardware.</term>
/// </item>
/// <item>
/// <term>CRYPT_IMPL_SOFTWARE2</term>
/// <term>Implementation is in software.</term>
/// </item>
/// <item>
/// <term>CRYPT_IMPL_MIXED3</term>
/// <term>Implementation involves both hardware and software.</term>
/// </item>
/// <item>
/// <term>CRYPT_IMPL_UNKNOWN4</term>
/// <term>Implementation type is unknown.</term>
/// </item>
/// <item>
/// <term>CRYPT_IMPL_REMOVABLE8</term>
/// <term>Implementation is in removable media.</term>
/// </item>
/// </list>
/// <para>
/// The dwFlags parameter is used to pass in the <c>SECURITY_INFORMATION</c> bit flags that indicate the requested security
/// information. The pointer to the security descriptor is returned in the pbData parameter and the length of the security
/// descriptor is returned in the pdwDataLen parameter. Key-container security is handled with SetFileSecurity and GetFileSecurity.
/// </para>
/// <para>
/// The class of an algorithm enumerated with dwParam set to PP_ENUMALGS or PP_ENUMALGS_EX can be determined. This might be done to
/// display a list of encryption algorithms supported and to disregard the rest. The <c>GET_ALG_CLASS(</c> x <c>)</c> macro takes an
/// algorithm identifier as an argument and returns a code indicating the general class of that algorithm. Possible return values include:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>ALG_CLASS_DATA_ENCRYPT</term>
/// </item>
/// <item>
/// <term>ALG_CLASS_HASH</term>
/// </item>
/// <item>
/// <term>ALG_CLASS_KEY_EXCHANGE</term>
/// </item>
/// <item>
/// <term>ALG_CLASS_SIGNATURE</term>
/// </item>
/// </list>
/// <para>
/// The following table lists the algorithms supported by the Microsoft Base Cryptographic Provider along with the class of each algorithm.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Name</term>
/// <term>Identifier</term>
/// <term>Class</term>
/// </listheader>
/// <item>
/// <term>"MD2"</term>
/// <term>CALG_MD2</term>
/// <term>ALG_CLASS_HASH</term>
/// </item>
/// <item>
/// <term>"MD5"</term>
/// <term>CALG_MD5</term>
/// <term>ALG_CLASS_HASH</term>
/// </item>
/// <item>
/// <term>"SHA"</term>
/// <term>CALG_SHA</term>
/// <term>ALG_CLASS_HASH</term>
/// </item>
/// <item>
/// <term>"MAC"</term>
/// <term>CALG_MAC</term>
/// <term>ALG_CLASS_HASH</term>
/// </item>
/// <item>
/// <term>"RSA_SIGN"</term>
/// <term>CALG_RSA_SIGN</term>
/// <term>ALG_CLASS_SIGNATURE</term>
/// </item>
/// <item>
/// <term>"RSA_KEYX"</term>
/// <term>CALG_RSA_KEYX</term>
/// <term>ALG_CLASS_KEY_EXCHANGE</term>
/// </item>
/// <item>
/// <term>"RC2"</term>
/// <term>CALG_RC2</term>
/// <term>ALG_CLASS_DATA_ENCRYPT</term>
/// </item>
/// <item>
/// <term>"RC4"</term>
/// <term>CALG_RC4</term>
/// <term>ALG_CLASS_DATA_ENCRYPT</term>
/// </item>
/// </list>
/// <para>
/// Applications must not use an algorithm with an algorithm identifier that is not recognized. Using an unknown cryptographic
/// algorithm can produce unpredictable results.
/// </para>
/// <para>Examples</para>
/// <para>
/// The following example shows finding the name of the CSP associated with a cryptographic service provider handle and the name of
/// the key container associated with the handle. For the complete context for this example, see Example C Program: Using CryptAcquireContext.
/// </para>
/// <para>For another example that uses this function, see Example C Program: Enumerating CSP Providers and Provider Types.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptgetprovparam BOOL CryptGetProvParam( HCRYPTPROV
// hProv, DWORD dwParam, BYTE *pbData, DWORD *pdwDataLen, DWORD dwFlags );
[DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "c0b7c1c8-aa42-4d40-a7f7-99c0821c8977")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptGetProvParam(HCRYPTPROV hProv, ProvParam dwParam, [Out, Optional] IntPtr pbData, ref uint pdwDataLen, uint dwFlags);
/// <summary>
/// The CryptGetProvParam function retrieves parameters that govern the operations of a cryptographic service provider (CSP).
/// </summary>
/// <typeparam name="T">The expected return type.</typeparam>
/// <param name="hProv">
/// A handle of the CSP target of the query. This handle must have been created by using the CryptAcquireContext function.
/// </param>
/// <param name="dwParam">
/// <para>The nature of the query. The following queries are defined.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>PP_ADMIN_PIN 31 (0x1F)</term>
/// <term>Returns the administrator personal identification number (PIN) in the pbData parameter as a LPSTR.</term>
/// </item>
/// <item>
/// <term>PP_APPLI_CERT 18 (0x12)</term>
/// <term>This constant is not used.</term>
/// </item>
/// <item>
/// <term>PP_CHANGE_PASSWORD 7 (0x7)</term>
/// <term>This constant is not used.</term>
/// </item>
/// <item>
/// <term>PP_CERTCHAIN 9 (0x9)</term>
/// <term>Returns the certificate chain associated with the hProv handle. The returned certificate chain is X509_ASN_ENCODING encoded.</term>
/// </item>
/// <item>
/// <term>PP_CONTAINER 6 (0x6)</term>
/// <term>
/// The name of the current key container as a null-terminated CHAR string. This string is exactly the same as the one passed in the
/// pszContainer parameter of the CryptAcquireContext function to specify the key container to use. The pszContainer parameter can
/// be read to determine the name of the default key container.
/// </term>
/// </item>
/// <item>
/// <term>PP_CRYPT_COUNT_KEY_USE 41 (0x29)</term>
/// <term>Not implemented by Microsoft CSPs. This behavior may be implemented by other CSPs. Windows XP: This parameter is not supported.</term>
/// </item>
/// <item>
/// <term>PP_ENUMALGS 1 (0x1)</term>
/// <term>
/// A PROV_ENUMALGS structure that contains information about one algorithm supported by the CSP being queried. The first time this
/// value is read, the dwFlags parameter must contain the CRYPT_FIRST flag. Doing so causes this function to retrieve the first
/// element in the enumeration. The subsequent elements can then be retrieved by setting the CRYPT_NEXT flag in the dwFlags
/// parameter. When this function fails with the ERROR_NO_MORE_ITEMS error code, the end of the enumeration has been reached. This
/// function is not thread safe, and all of the available algorithms might not be enumerated if this function is used in a
/// multithreaded context.
/// </term>
/// </item>
/// <item>
/// <term>PP_ENUMALGS_EX 22 (0x16)</term>
/// <term>
/// A PROV_ENUMALGS_EX structure that contains information about one algorithm supported by the CSP being queried. The structure
/// returned contains more information about the algorithm than the structure returned for PP_ENUMALGS. The first time this value is
/// read, the dwFlags parameter must contain the CRYPT_FIRST flag. Doing so causes this function to retrieve the first element in
/// the enumeration. The subsequent elements can then be retrieved by setting the CRYPT_NEXT flag in the dwFlags parameter. When
/// this function fails with the ERROR_NO_MORE_ITEMS error code, the end of the enumeration has been reached. This function is not
/// thread safe and all of the available algorithms might not be enumerated if this function is used in a multithreaded context.
/// </term>
/// </item>
/// <item>
/// <term>PP_ENUMCONTAINERS 2 (0x2)</term>
/// <term>
/// The name of one of the key containers maintained by the CSP in the form of a null-terminated CHAR string. The first time this
/// value is read, the dwFlags parameter must contain the CRYPT_FIRST flag. Doing so causes this function to retrieve the first
/// element in the enumeration. The subsequent elements can then be retrieved by setting the CRYPT_NEXT flag in the dwFlags
/// parameter. When this function fails with the ERROR_NO_MORE_ITEMS error code, the end of the enumeration has been reached. To
/// enumerate key containers associated with a computer, first call CryptAcquireContext using the CRYPT_MACHINE_KEYSET flag, and
/// then use the handle returned from CryptAcquireContext as the hProv parameter in the call to CryptGetProvParam. This function is
/// not thread safe and all of the available algorithms might not be enumerated if this function is used in a multithreaded context.
/// </term>
/// </item>
/// <item>
/// <term>PP_ENUMELECTROOTS 26 (0x1A)</term>
/// <term>This constant is not used.</term>
/// </item>
/// <item>
/// <term>PP_ENUMEX_SIGNING_PROT 40 (0x28)</term>
/// <term>
/// Indicates that the current CSP supports the dwProtocols member of the PROV_ENUMALGS_EX structure. If this function succeeds, the
/// CSP supports the dwProtocols member of the PROV_ENUMALGS_EX structure. If this function fails with an NTE_BAD_TYPE error code,
/// the CSP does not support the dwProtocols member.
/// </term>
/// </item>
/// <item>
/// <term>PP_ENUMMANDROOTS 25 (0x19)</term>
/// <term>This constant is not used.</term>
/// </item>
/// <item>
/// <term>PP_IMPTYPE 3 (0x3)</term>
/// <term>A DWORD value that indicates how the CSP is implemented. For a table of possible values, see Remarks.</term>
/// </item>
/// <item>
/// <term>PP_KEY_TYPE_SUBTYPE 10 (0xA)</term>
/// <term>This query is not used.</term>
/// </item>
/// <item>
/// <term>PP_KEYEXCHANGE_PIN 32 (0x20)</term>
/// <term>Specifies that the key exchange PIN is contained in pbData. The PIN is represented as a null-terminated ASCII string.</term>
/// </item>
/// <item>
/// <term>PP_KEYSET_SEC_DESCR 8 (0x8)</term>
/// <term>
/// Retrieves the security descriptor for the key storage container. The pbData parameter is the address of a SECURITY_DESCRIPTOR
/// structure that receives the security descriptor for the key storage container. The security descriptor is returned in
/// self-relative format.
/// </term>
/// </item>
/// <item>
/// <term>PP_KEYSET_TYPE 27 (0x1B)</term>
/// <term>
/// Determines whether the hProv parameter is a computer key set. The pbData parameter must be a DWORD; the DWORD will be set to the
/// CRYPT_MACHINE_KEYSET flag if that flag was passed to the CryptAcquireContext function.
/// </term>
/// </item>
/// <item>
/// <term>PP_KEYSPEC 39 (0x27)</term>
/// <term>
/// Returns information about the key specifier values that the CSP supports. Key specifier values are joined in a logical OR and
/// returned in the pbData parameter of the call as a DWORD. For example, the Microsoft Base Cryptographic Provider version 1.0
/// returns a DWORD value of AT_SIGNATURE | AT_KEYEXCHANGE.
/// </term>
/// </item>
/// <item>
/// <term>PP_KEYSTORAGE 17 (0x11)</term>
/// <term>Returns a DWORD value of CRYPT_SEC_DESCR.</term>
/// </item>
/// <item>
/// <term>PP_KEYX_KEYSIZE_INC 35 (0x23)</term>
/// <term>
/// The number of bits for the increment length of AT_KEYEXCHANGE. This information is used with information returned in the
/// PP_ENUMALGS_EX value. With the information returned when using PP_ENUMALGS_EX and PP_KEYX_KEYSIZE_INC, the valid key lengths for
/// AT_KEYEXCHANGE can be determined. These key lengths can then be used with CryptGenKey. For example if a CSP enumerates
/// CALG_RSA_KEYX (AT_KEYEXCHANGE) with a minimum key length of 512 bits and a maximum of 1024 bits, and returns the increment
/// length as 64 bits, then valid key lengths are 512, 576, 640,… 1024.
/// </term>
/// </item>
/// <item>
/// <term>PP_NAME 4 (0x4)</term>
/// <term>
/// The name of the CSP in the form of a null-terminated CHAR string. This string is identical to the one passed in the pszProvider
/// parameter of the CryptAcquireContext function to specify that the current CSP be used.
/// </term>
/// </item>
/// <item>
/// <term>PP_PROVTYPE 16 (0x10)</term>
/// <term>A DWORD value that indicates the provider type of the CSP.</term>
/// </item>
/// <item>
/// <term>PP_ROOT_CERTSTORE 46 (0x2E)</term>
/// <term>
/// Obtains the root certificate store for the smart card. This certificate store contains all of the root certificates that are
/// stored on the smart card. The pbData parameter is the address of an HCERTSTORE variable that receives the handle of the
/// certificate store. When this handle is no longer needed, the caller must close it by using the CertCloseStore function. Windows
/// Server 2003 and Windows XP: This parameter is not supported.
/// </term>
/// </item>
/// <item>
/// <term>PP_SESSION_KEYSIZE 20 (0x14)</term>
/// <term>The size, in bits, of the session key.</term>
/// </item>
/// <item>
/// <term>PP_SGC_INFO 37 (0x25)</term>
/// <term>Used with server gated cryptography.</term>
/// </item>
/// <item>
/// <term>PP_SIG_KEYSIZE_INC 34 (0x22)</term>
/// <term>
/// The number of bits for the increment length of AT_SIGNATURE. This information is used with information returned in the
/// PP_ENUMALGS_EX value. With the information returned when using PP_ENUMALGS_EX and PP_SIG_KEYSIZE_INC, the valid key lengths for
/// AT_SIGNATURE can be determined. These key lengths can then be used with CryptGenKey. For example, if a CSP enumerates
/// CALG_RSA_SIGN (AT_SIGNATURE) with a minimum key length of 512 bits and a maximum of 1024 bits, and returns the increment length
/// as 64 bits, then valid key lengths are 512, 576, 640,… 1024.
/// </term>
/// </item>
/// <item>
/// <term>PP_SIGNATURE_PIN 33 (0x21)</term>
/// <term>Specifies that the key signature PIN is contained in pbData. The PIN is represented as a null-terminated ASCII string.</term>
/// </item>
/// <item>
/// <term>PP_SMARTCARD_GUID 45 (0x2D)</term>
/// <term>
/// Obtains the identifier of the smart card. The pbData parameter is the address of a GUID structure that receives the identifier
/// of the smart card. Windows Server 2003 and Windows XP: This parameter is not supported.
/// </term>
/// </item>
/// <item>
/// <term>PP_SMARTCARD_READER 43 (0x2B)</term>
/// <term>
/// Obtains the name of the smart card reader. The pbData parameter is the address of an ANSI character array that receives a
/// null-terminated ANSI string that contains the name of the smart card reader. The size of this buffer, contained in the variable
/// pointed to by the pdwDataLen parameter, must include the NULL terminator. Windows Server 2003 and Windows XP: This parameter is
/// not supported.
/// </term>
/// </item>
/// <item>
/// <term>PP_SYM_KEYSIZE 19 (0x13)</term>
/// <term>The size of the symmetric key.</term>
/// </item>
/// <item>
/// <term>PP_UI_PROMPT 21 (0x15)</term>
/// <term>This query is not used.</term>
/// </item>
/// <item>
/// <term>PP_UNIQUE_CONTAINER 36 (0x24)</term>
/// <term>
/// The unique container name of the current key container in the form of a null-terminated CHAR string. For many CSPs, this name is
/// the same name returned when the PP_CONTAINER value is used. The CryptAcquireContext function must work with this container name.
/// </term>
/// </item>
/// <item>
/// <term>PP_USE_HARDWARE_RNG 38 (0x26)</term>
/// <term>
/// Indicates whether a hardware random number generator (RNG) is supported. When PP_USE_HARDWARE_RNG is specified, the function
/// succeeds and returns TRUE if a hardware RNG is supported. The function fails and returns FALSE if a hardware RNG is not
/// supported. If a RNG is supported, PP_USE_HARDWARE_RNG can be set in CryptSetProvParam to indicate that the CSP must exclusively
/// use the hardware RNG for this provider context. When PP_USE_HARDWARE_RNG is used, the pbData parameter must be NULL and dwFlags
/// must be zero. None of the Microsoft CSPs currently support using a hardware RNG.
/// </term>
/// </item>
/// <item>
/// <term>PP_USER_CERTSTORE 42 (0x2A)</term>
/// <term>
/// Obtains the user certificate store for the smart card. This certificate store contains all of the user certificates that are
/// stored on the smart card. The certificates in this store are encoded by using PKCS_7_ASN_ENCODING or X509_ASN_ENCODING encoding
/// and should contain the CERT_KEY_PROV_INFO_PROP_ID property. The pbData parameter is the address of an HCERTSTORE variable that
/// receives the handle of an in-memory certificate store. When this handle is no longer needed, the caller must close it by using
/// the CertCloseStore function. Windows Server 2003 and Windows XP: This parameter is not supported.
/// </term>
/// </item>
/// <item>
/// <term>PP_VERSION 5 (0x5)</term>
/// <term>
/// The version number of the CSP. The least significant byte contains the minor version number and the next most significant byte
/// the major version number. Version 2.0 is represented as 0x00000200. To maintain backward compatibility with earlier versions of
/// the Microsoft Base Cryptographic Provider and the Microsoft Enhanced Cryptographic Provider, the provider names retain the
/// "v1.0" designation in later versions.
/// </term>
/// </item>
/// </list>
/// </param>
/// <param name="dwFlags">
/// <para>
/// If dwParam is <c>PP_KEYSET_SEC_DESCR</c>, the security descriptor on the key container where the keys are stored is retrieved.
/// For this case, dwFlags is used to pass in the <c>SECURITY_INFORMATION</c> bit flags that indicate the requested security
/// information, as defined in the Platform SDK. <c>SECURITY_INFORMATION</c> bit flags can be combined with a bitwise- <c>OR</c> operation.
/// </para>
/// <para>The following values are defined for use with <c>PP_KEYSET_SEC_DESCR</c>.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>OWNER_SECURITY_INFORMATION</term>
/// <term>Owner identifier of the object is being referenced.</term>
/// </item>
/// <item>
/// <term>GROUP_SECURITY_INFORMATION</term>
/// <term>Primary group identifier of the object is being referenced.</term>
/// </item>
/// <item>
/// <term>DACL_SECURITY_INFORMATION</term>
/// <term>Discretionary ACL of the object is being referenced.</term>
/// </item>
/// <item>
/// <term>SACL_SECURITY_INFORMATION</term>
/// <term>System ACL of the object is being referenced.</term>
/// </item>
/// </list>
/// <para>The following values are defined for use with <c>PP_ENUMALGS</c>, <c>PP_ENUMALGS_EX</c>, and <c>PP_ENUMCONTAINERS</c>.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>CRYPT_FIRST 1 (0x1)</term>
/// <term>Retrieve the first element in the enumeration. This has the same effect as resetting the enumerator.</term>
/// </item>
/// <item>
/// <term>CRYPT_NEXT 2 (0x2)</term>
/// <term>
/// Retrieve the next element in the enumeration. When there are no more elements to retrieve, this function will fail and set the
/// last error to ERROR_NO_MORE_ITEMS.
/// </term>
/// </item>
/// <item>
/// <term>CRYPT_SGC_ENUM 4 (0x4)</term>
/// <term>
/// Retrieve server-gated cryptography (SGC) enabled certificates. SGC enabled certificates are no longer supported. For more
/// information, see Microsoft Support Article 875450.
/// </term>
/// </item>
/// <item>
/// <term>CRYPT_SGC</term>
/// <term>This flag is not used.</term>
/// </item>
/// <item>
/// <term>CRYPT_FASTSGC</term>
/// <term>This flag is not used.</term>
/// </item>
/// </list>
/// </param>
/// <returns>The specified value data. The form of this data varies, depending on the value number.</returns>
public static T CryptGetProvParam<T>(HCRYPTPROV hProv, ProvParam dwParam, uint dwFlags) => CryptGetValue<HCRYPTPROV, ProvParam, T>(CryptGetProvParam, hProv, dwParam, dwFlags);
/// <summary>
/// The CryptGetUserKey function retrieves a handle of one of a user's two public/private key pairs. This function is used only by
/// the owner of the public/private key pairs and only when the handle of a cryptographic service provider (CSP) and its associated
/// key container is available. If the CSP handle is not available and the user's certificate is, use CryptAcquireCertificatePrivateKey.
/// </summary>
/// <param name="hProv"><c>HCRYPTPROV</c> handle of a cryptographic service provider (CSP) created by a call to CryptAcquireContext.</param>
/// <param name="dwKeySpec">
/// <para>Identifies the private key to use from the key container. It can be AT_KEYEXCHANGE or AT_SIGNATURE.</para>
/// <para>
/// Additionally, some providers allow access to other user-specific keys through this function. For details, see the documentation
/// on the specific provider.
/// </para>
/// </param>
/// <param name="phUserKey">
/// A pointer to the HCRYPTKEY handle of the retrieved keys. When you have finished using the key, delete the handle by calling the
/// CryptDestroyKey function.
/// </param>
/// <returns>
/// <para>If the function succeeds, the return value is nonzero (TRUE).</para>
/// <para>If the function fails, the return value is zero (FALSE). For extended error information, call GetLastError.</para>
/// <para>The error codes prefaced by "NTE" are generated by the particular CSP being used. Some possible error codes follow.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>ERROR_INVALID_HANDLE</term>
/// <term>One of the parameters specifies a handle that is not valid.</term>
/// </item>
/// <item>
/// <term>ERROR_INVALID_PARAMETER</term>
/// <term>One of the parameters contains a value that is not valid. This is most often a pointer that is not valid.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_KEY</term>
/// <term>The dwKeySpec parameter contains a value that is not valid.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_UID</term>
/// <term>The hProv parameter does not contain a valid context handle.</term>
/// </item>
/// <item>
/// <term>NTE_NO_KEY</term>
/// <term>The key requested by the dwKeySpec parameter does not exist.</term>
/// </item>
/// </list>
/// </returns>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptgetuserkey
// BOOL CryptGetUserKey( HCRYPTPROV hProv, DWORD dwKeySpec, HCRYPTKEY *phUserKey );
[DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "d9166b98-e5f1-4e5c-b6f1-2a086b102e0f")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptGetUserKey(HCRYPTPROV hProv, CertKeySpec dwKeySpec, out SafeHCRYPTKEY phUserKey);
/// <summary>
/// The CryptHashData function adds data to a specified hash object. This function and CryptHashSessionKey can be called multiple
/// times to compute the hash of long or discontinuous data streams.
/// <para>Before calling this function, CryptCreateHash must be called to create a handle of a hash object.</para>
/// </summary>
/// <param name="hHash">Handle of the hash object.</param>
/// <param name="pbData">A pointer to a buffer that contains the data to be added to the hash object.</param>
/// <param name="dwDataLen">Number of bytes of data to be added. This must be zero if the CRYPT_USERDATA flag is set.</param>
/// <param name="dwFlags">
/// <para>The following flag values are defined.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>CRYPT_OWF_REPL_LM_HASH 0x00000001</term>
/// <term>This flag is not used.</term>
/// </item>
/// <item>
/// <term>CRYPT_USERDATA 1 (0x1)</term>
/// <term>
/// All Microsoft Cryptographic Providers ignore this parameter. For any CSP that does not ignore this parameter, if this flag is
/// set, the CSP prompts the user to input data directly. This data is added to the hash. The application is not allowed access to
/// the data. This flag can be used to allow the user to enter a PIN into the system.
/// </term>
/// </item>
/// </list>
/// </param>
/// <returns>
/// <para>If the function succeeds, the return value is <c>TRUE</c>.</para>
/// <para>If the function fails, the return value is <c>FALSE</c>. For extended error information, call GetLastError.</para>
/// <para>The error codes prefaced by "NTE" are generated by the particular CSP you are using. Some possible error codes follow.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>ERROR_INVALID_HANDLE</term>
/// <term>One of the parameters specifies a handle that is not valid.</term>
/// </item>
/// <item>
/// <term>ERROR_INVALID_PARAMETER</term>
/// <term>One of the parameters contains a value that is not valid. This is most often a pointer that is not valid.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_ALGID</term>
/// <term>The hHash handle specifies an algorithm that this CSP does not support.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_FLAGS</term>
/// <term>The dwFlags parameter contains a value that is not valid.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_HASH</term>
/// <term>The hash object specified by the hHash parameter is not valid.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_HASH_STATE</term>
/// <term>An attempt was made to add data to a hash object that is already marked "finished."</term>
/// </item>
/// <item>
/// <term>NTE_BAD_KEY</term>
/// <term>
/// A keyed hash algorithm is being used, but the session key is no longer valid. This error is generated if the session key is
/// destroyed before the hashing operation is complete.
/// </term>
/// </item>
/// <item>
/// <term>NTE_BAD_LEN</term>
/// <term>The CSP does not ignore the CRYPT_USERDATA flag, the flag is set, and the dwDataLen parameter has a nonzero value.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_UID</term>
/// <term>The CSP context that was specified when the hash object was created cannot be found.</term>
/// </item>
/// <item>
/// <term>NTE_FAIL</term>
/// <term>The function failed in some unexpected way.</term>
/// </item>
/// <item>
/// <term>NTE_NO_MEMORY</term>
/// <term>The CSP ran out of memory during the operation.</term>
/// </item>
/// </list>
/// </returns>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-crypthashdata BOOL CryptHashData( HCRYPTHASH hHash, const
// BYTE *pbData, DWORD dwDataLen, DWORD dwFlags );
[DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "ec1482a2-c2cb-4c5f-af9c-d493134413d6")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptHashData(HCRYPTHASH hHash, [In] IntPtr pbData, uint dwDataLen, uint dwFlags);
/// <summary>
/// The CryptHashSessionKey function computes the cryptographic hash of a session key object. This function can be called multiple
/// times with the same hash handle to compute the hash of multiple keys. Calls to CryptHashSessionKey can be interspersed with
/// calls to CryptHashData.
/// <para>Before calling this function, CryptCreateHash must be called to create the handle of a hash object.</para>
/// </summary>
/// <param name="hHash">A handle to the hash object.</param>
/// <param name="hKey">A handle to the key object to be hashed.</param>
/// <param name="dwFlags">
/// <para>The following flag value is defined.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>CRYPT_LITTLE_ENDIAN 0x00000001</term>
/// <term>
/// When this flag is set, the bytes of the key are hashed in little-endian form. Note that by default (when dwFlags is zero), the
/// bytes of the key are hashed in big-endian form.
/// </term>
/// </item>
/// </list>
/// </param>
/// <returns>
/// <para>If the function succeeds, the return value is <c>TRUE</c>.</para>
/// <para>If the function fails, the return value is <c>FALSE</c>. For extended error information, call GetLastError.</para>
/// <para>The error codes prefaced by "NTE" are generated by the particular CSP you are using. Some possible error codes follow.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>ERROR_INVALID_HANDLE</term>
/// <term>One of the parameters specifies a handle that is not valid.</term>
/// </item>
/// <item>
/// <term>ERROR_INVALID_PARAMETER</term>
/// <term>One of the parameters contains a value that is not valid. This is most often a pointer that is not valid.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_ALGID</term>
/// <term>The hHash handle specifies an algorithm that this CSP does not support.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_FLAGS</term>
/// <term>The dwFlags parameter is nonzero.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_HASH</term>
/// <term>The hash object specified by the hHash parameter is not valid.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_HASH_STATE</term>
/// <term>An attempt was made to add data to a hash object that is already marked "finished."</term>
/// </item>
/// <item>
/// <term>NTE_BAD_KEY</term>
/// <term>
/// A keyed hash algorithm is being used, but the session key is no longer valid. This error is generated if the session key is
/// destroyed before the hashing operation is complete.
/// </term>
/// </item>
/// <item>
/// <term>NTE_BAD_UID</term>
/// <term>The CSP context that was specified when the hash object was created cannot be found.</term>
/// </item>
/// <item>
/// <term>NTE_FAIL</term>
/// <term>The function failed in some unexpected way.</term>
/// </item>
/// </list>
/// </returns>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-crypthashsessionkey BOOL CryptHashSessionKey( HCRYPTHASH
// hHash, HCRYPTKEY hKey, DWORD dwFlags );
[DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "75781993-7faf-4149-80cc-ae50dbd4de2a")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptHashSessionKey(HCRYPTHASH hHash, HCRYPTKEY hKey, CryptHashSessionKeyFlags dwFlags);
/// <summary>
/// The CryptImportKey function transfers a cryptographic key from a key BLOB into a cryptographic service provider (CSP). This
/// function can be used to import an Schannel session key, regular session key, public key, or public/private key pair. For all but
/// the public key, the key or key pair is encrypted.
/// </summary>
/// <param name="hProv">The handle of a CSP obtained with the CryptAcquireContext function.</param>
/// <param name="pbData">
/// A <c>BYTE</c> array that contains a PUBLICKEYSTRUC BLOB header followed by the encrypted key. This key BLOB is created by the
/// CryptExportKey function, either in this application or by another application possibly running on a different computer.
/// </param>
/// <param name="dwDataLen">Contains the length, in bytes, of the key BLOB.</param>
/// <param name="hPubKey">
/// <para>
/// A handle to the cryptographic key that decrypts the key stored in pbData. This key must come from the same CSP to which hProv
/// refers. The meaning of this parameter differs depending on the CSP type and the type of key BLOB being imported:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>
/// If the key BLOB is encrypted with the key exchange key pair, for example, a <c>SIMPLEBLOB</c>, this parameter can be the handle
/// to the key exchange key.
/// </term>
/// </item>
/// <item>
/// <term>
/// If the key BLOB is encrypted with a session key, for example, an encrypted <c>PRIVATEKEYBLOB</c>, this parameter contains the
/// handle of this session key.
/// </term>
/// </item>
/// <item>
/// <term>If the key BLOB is not encrypted, for example, a <c>PUBLICKEYBLOB</c>, this parameter is not used and must be zero.</term>
/// </item>
/// <item>
/// <term>
/// If the key BLOB is encrypted with a session key in an Schannel CSP, for example, an encrypted <c>OPAQUEKEYBLOB</c> or any other
/// vendor-specific <c>OPAQUEKEYBLOB</c>, this parameter is not used and must be set to zero.
/// </term>
/// </item>
/// </list>
/// <para>
/// <c>Note</c> Some CSPs may modify this parameter as a result of the operation. Applications that subsequently use this key for
/// other purposes should call the CryptDuplicateKey function to create a duplicate key handle. When the application has finished
/// using the handle, release it by calling the CryptDestroyKey function.
/// </para>
/// </param>
/// <param name="dwFlags">
/// Currently used only when a public/private key pair in the form of a <c>PRIVATEKEYBLOB</c> is imported into the CSP.
/// <para>This parameter can be one of the following values.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>CRYPT_EXPORTABLE</term>
/// <term>
/// The key being imported is eventually to be reexported. If this flag is not used, then calls to CryptExportKey with the key
/// handle fail.
/// </term>
/// </item>
/// <item>
/// <term>CRYPT_OAEP</term>
/// <term>This flag causes PKCS #1 version 2 formatting to be checked with RSA encryption and decryption when importing SIMPLEBLOBs.</term>
/// </item>
/// <item>
/// <term>CRYPT_NO_SALT</term>
/// <term>A no-salt value gets allocated for a 40-bit symmetric key. For more information, see Salt Value Functionality.</term>
/// </item>
/// <item>
/// <term>CRYPT_USER_PROTECTED</term>
/// <term>
/// If this flag is set, the CSP notifies the user through a dialog box or some other method when certain actions are attempted
/// using this key. The precise behavior is specified by the CSP or the CSP type used. If the provider context was acquired with
/// CRYPT_SILENT set, using this flag causes a failure and the last error is set to NTE_SILENT_CONTEXT.
/// </term>
/// </item>
/// <item>
/// <term>CRYPT_IPSEC_HMAC_KEY</term>
/// <term>
/// Allows for the import of an RC2 key that is larger than 16 bytes. If this flag is not set, calls to the CryptImportKey function
/// with RC2 keys that are greater than 16 bytes fail, and a call to GetLastError will return NTE_BAD_DATA.
/// </term>
/// </item>
/// </list>
/// </param>
/// <param name="phKey">
/// A pointer to a <c>HCRYPTKEY</c> value that receives the handle of the imported key. When you have finished using the key,
/// release the handle by calling the CryptDestroyKey function.
/// </param>
/// <returns>
/// <para>If the function succeeds, the function returns nonzero.</para>
/// <para>If the function fails, it returns zero. For extended error information, call GetLastError.</para>
/// <para>Error codes prefaced by "NTE" are generated by the particular CSP being used. Some possible error codes follow.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>ERROR_BUSY</term>
/// <term>Some CSPs set this error if a private key is imported into a container while another thread or process is using this key.</term>
/// </item>
/// <item>
/// <term>ERROR_INVALID_HANDLE</term>
/// <term>One of the parameters specifies a handle that is not valid.</term>
/// </item>
/// <item>
/// <term>ERROR_INVALID_PARAMETER</term>
/// <term>One of the parameters contains a value that is not valid. This is most often a pointer that is not valid.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_ALGID</term>
/// <term>The simple key BLOB to be imported is not encrypted with the expected key exchange algorithm.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_DATA</term>
/// <term>
/// Either the algorithm that works with the public key to be imported is not supported by this CSP, or an attempt was made to
/// import a session key that was encrypted with something other than one of your public keys.
/// </term>
/// </item>
/// <item>
/// <term>NTE_BAD_FLAGS</term>
/// <term>The dwFlags parameter specified is not valid.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_TYPE</term>
/// <term>The key BLOB type is not supported by this CSP and is possibly not valid.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_UID</term>
/// <term>The hProv parameter does not contain a valid context handle.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_VER</term>
/// <term>The version number of the key BLOB does not match the CSP version. This usually indicates that the CSP needs to be upgraded.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// When importing a Hash-Based Message Authentication Code (HMAC) key, the caller must identify the imported key as a
/// <c>PLAINTEXTKEYBLOB</c> type and set the appropriate algorithm identifier in the <c>aiKeyAlg</c> field of the PUBLICKEYSTRUC
/// BLOB header.
/// </para>
/// <para>
/// The <c>CryptImportKey</c> function can be used to import a plaintext key for symmetric algorithms; however, we recommend that,
/// for ease of use, you use the CryptGenKey function instead. When you import a plaintext key, the structure of the key BLOB that
/// is passed in the pbData parameter is a PLAINTEXTKEYBLOB.
/// </para>
/// <para>You can use the <c>PLAINTEXTKEYBLOB</c> type with any algorithm or type of key combination supported by the CSP in use.</para>
/// <para>For an example of importing a plaintext key, see Example C Program: Importing a Plaintext Key.</para>
/// <para>The following example shows how you can set the header fields.</para>
/// <para>The length of the key is specified in keyBlob.keyLength, which is followed by the actual key data.</para>
/// <para>
/// <c>Note</c> The HMAC algorithms do not have their own algorithm identifiers; use CALG_RC2 instead. <c>CRYPT_IPSEC_HMAC_KEY</c>
/// allows the import of RC2 keys longer than 16 bytes.
/// </para>
/// <para>
/// For any of the Data Encryption Standard (DES) key permutations that use <c>PLAINTEXTKEYBLOB</c>, only the full key size,
/// including parity bit, can be imported.
/// </para>
/// <para>The following key sizes are supported.</para>
/// <list type="table">
/// <listheader>
/// <term>Algorithm</term>
/// <term>Supported key size</term>
/// </listheader>
/// <item>
/// <term>CALG_DES</term>
/// <term>64 bits</term>
/// </item>
/// <item>
/// <term>CALG_3DES_112</term>
/// <term>128 bits</term>
/// </item>
/// <item>
/// <term>CALG_3DES</term>
/// <term>192 bits</term>
/// </item>
/// </list>
/// <para>Examples</para>
/// <para>
/// The following example shows how to import a key from a key BLOB. For a full example for this function, see Example C Program:
/// Signing a Hash and Verifying the Hash Signature. For additional code that uses this function, see Example C Program: Decrypting
/// a File.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptimportkey BOOL CryptImportKey( HCRYPTPROV hProv,
// const BYTE *pbData, DWORD dwDataLen, HCRYPTKEY hPubKey, DWORD dwFlags, HCRYPTKEY *phKey );
[DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "f48b6ec9-e03b-43b0-9f22-120ae93d934c")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptImportKey(HCRYPTPROV hProv, [In] IntPtr pbData, uint dwDataLen, HCRYPTKEY hPubKey, uint dwFlags, out SafeHCRYPTKEY phKey);
/// <summary>
/// The CryptImportKey function transfers a cryptographic key from a key BLOB into a cryptographic service provider (CSP). This
/// function can be used to import an Schannel session key, regular session key, public key, or public/private key pair. For all but
/// the public key, the key or key pair is encrypted.
/// </summary>
/// <param name="hProv">The handle of a CSP obtained with the CryptAcquireContext function.</param>
/// <param name="pbData">
/// A <c>BYTE</c> array that contains a PUBLICKEYSTRUC BLOB header followed by the encrypted key. This key BLOB is created by the
/// CryptExportKey function, either in this application or by another application possibly running on a different computer.
/// </param>
/// <param name="dwDataLen">Contains the length, in bytes, of the key BLOB.</param>
/// <param name="hPubKey">
/// <para>
/// A handle to the cryptographic key that decrypts the key stored in pbData. This key must come from the same CSP to which hProv
/// refers. The meaning of this parameter differs depending on the CSP type and the type of key BLOB being imported:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>
/// If the key BLOB is encrypted with the key exchange key pair, for example, a <c>SIMPLEBLOB</c>, this parameter can be the handle
/// to the key exchange key.
/// </term>
/// </item>
/// <item>
/// <term>
/// If the key BLOB is encrypted with a session key, for example, an encrypted <c>PRIVATEKEYBLOB</c>, this parameter contains the
/// handle of this session key.
/// </term>
/// </item>
/// <item>
/// <term>If the key BLOB is not encrypted, for example, a <c>PUBLICKEYBLOB</c>, this parameter is not used and must be zero.</term>
/// </item>
/// <item>
/// <term>
/// If the key BLOB is encrypted with a session key in an Schannel CSP, for example, an encrypted <c>OPAQUEKEYBLOB</c> or any other
/// vendor-specific <c>OPAQUEKEYBLOB</c>, this parameter is not used and must be set to zero.
/// </term>
/// </item>
/// </list>
/// <para>
/// <c>Note</c> Some CSPs may modify this parameter as a result of the operation. Applications that subsequently use this key for
/// other purposes should call the CryptDuplicateKey function to create a duplicate key handle. When the application has finished
/// using the handle, release it by calling the CryptDestroyKey function.
/// </para>
/// </param>
/// <param name="dwFlags">
/// Currently used only when a public/private key pair in the form of a <c>PRIVATEKEYBLOB</c> is imported into the CSP.
/// <para>This parameter can be one of the following values.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>CRYPT_EXPORTABLE</term>
/// <term>
/// The key being imported is eventually to be reexported. If this flag is not used, then calls to CryptExportKey with the key
/// handle fail.
/// </term>
/// </item>
/// <item>
/// <term>CRYPT_OAEP</term>
/// <term>This flag causes PKCS #1 version 2 formatting to be checked with RSA encryption and decryption when importing SIMPLEBLOBs.</term>
/// </item>
/// <item>
/// <term>CRYPT_NO_SALT</term>
/// <term>A no-salt value gets allocated for a 40-bit symmetric key. For more information, see Salt Value Functionality.</term>
/// </item>
/// <item>
/// <term>CRYPT_USER_PROTECTED</term>
/// <term>
/// If this flag is set, the CSP notifies the user through a dialog box or some other method when certain actions are attempted
/// using this key. The precise behavior is specified by the CSP or the CSP type used. If the provider context was acquired with
/// CRYPT_SILENT set, using this flag causes a failure and the last error is set to NTE_SILENT_CONTEXT.
/// </term>
/// </item>
/// <item>
/// <term>CRYPT_IPSEC_HMAC_KEY</term>
/// <term>
/// Allows for the import of an RC2 key that is larger than 16 bytes. If this flag is not set, calls to the CryptImportKey function
/// with RC2 keys that are greater than 16 bytes fail, and a call to GetLastError will return NTE_BAD_DATA.
/// </term>
/// </item>
/// </list>
/// </param>
/// <param name="phKey">
/// A pointer to a <c>HCRYPTKEY</c> value that receives the handle of the imported key. When you have finished using the key,
/// release the handle by calling the CryptDestroyKey function.
/// </param>
/// <returns>
/// <para>If the function succeeds, the function returns nonzero.</para>
/// <para>If the function fails, it returns zero. For extended error information, call GetLastError.</para>
/// <para>Error codes prefaced by "NTE" are generated by the particular CSP being used. Some possible error codes follow.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>ERROR_BUSY</term>
/// <term>Some CSPs set this error if a private key is imported into a container while another thread or process is using this key.</term>
/// </item>
/// <item>
/// <term>ERROR_INVALID_HANDLE</term>
/// <term>One of the parameters specifies a handle that is not valid.</term>
/// </item>
/// <item>
/// <term>ERROR_INVALID_PARAMETER</term>
/// <term>One of the parameters contains a value that is not valid. This is most often a pointer that is not valid.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_ALGID</term>
/// <term>The simple key BLOB to be imported is not encrypted with the expected key exchange algorithm.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_DATA</term>
/// <term>
/// Either the algorithm that works with the public key to be imported is not supported by this CSP, or an attempt was made to
/// import a session key that was encrypted with something other than one of your public keys.
/// </term>
/// </item>
/// <item>
/// <term>NTE_BAD_FLAGS</term>
/// <term>The dwFlags parameter specified is not valid.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_TYPE</term>
/// <term>The key BLOB type is not supported by this CSP and is possibly not valid.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_UID</term>
/// <term>The hProv parameter does not contain a valid context handle.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_VER</term>
/// <term>The version number of the key BLOB does not match the CSP version. This usually indicates that the CSP needs to be upgraded.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// When importing a Hash-Based Message Authentication Code (HMAC) key, the caller must identify the imported key as a
/// <c>PLAINTEXTKEYBLOB</c> type and set the appropriate algorithm identifier in the <c>aiKeyAlg</c> field of the PUBLICKEYSTRUC
/// BLOB header.
/// </para>
/// <para>
/// The <c>CryptImportKey</c> function can be used to import a plaintext key for symmetric algorithms; however, we recommend that,
/// for ease of use, you use the CryptGenKey function instead. When you import a plaintext key, the structure of the key BLOB that
/// is passed in the pbData parameter is a PLAINTEXTKEYBLOB.
/// </para>
/// <para>You can use the <c>PLAINTEXTKEYBLOB</c> type with any algorithm or type of key combination supported by the CSP in use.</para>
/// <para>For an example of importing a plaintext key, see Example C Program: Importing a Plaintext Key.</para>
/// <para>The following example shows how you can set the header fields.</para>
/// <para>The length of the key is specified in keyBlob.keyLength, which is followed by the actual key data.</para>
/// <para>
/// <c>Note</c> The HMAC algorithms do not have their own algorithm identifiers; use CALG_RC2 instead. <c>CRYPT_IPSEC_HMAC_KEY</c>
/// allows the import of RC2 keys longer than 16 bytes.
/// </para>
/// <para>
/// For any of the Data Encryption Standard (DES) key permutations that use <c>PLAINTEXTKEYBLOB</c>, only the full key size,
/// including parity bit, can be imported.
/// </para>
/// <para>The following key sizes are supported.</para>
/// <list type="table">
/// <listheader>
/// <term>Algorithm</term>
/// <term>Supported key size</term>
/// </listheader>
/// <item>
/// <term>CALG_DES</term>
/// <term>64 bits</term>
/// </item>
/// <item>
/// <term>CALG_3DES_112</term>
/// <term>128 bits</term>
/// </item>
/// <item>
/// <term>CALG_3DES</term>
/// <term>192 bits</term>
/// </item>
/// </list>
/// <para>Examples</para>
/// <para>
/// The following example shows how to import a key from a key BLOB. For a full example for this function, see Example C Program:
/// Signing a Hash and Verifying the Hash Signature. For additional code that uses this function, see Example C Program: Decrypting
/// a File.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptimportkey BOOL CryptImportKey( HCRYPTPROV hProv,
// const BYTE *pbData, DWORD dwDataLen, HCRYPTKEY hPubKey, DWORD dwFlags, HCRYPTKEY *phKey );
[DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "f48b6ec9-e03b-43b0-9f22-120ae93d934c")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptImportKey(HCRYPTPROV hProv, [In] byte[] pbData, int dwDataLen, HCRYPTKEY hPubKey, uint dwFlags, out SafeHCRYPTKEY phKey);
/// <summary>
/// <para>
/// The CryptReleaseContext function releases the handle of a cryptographic service provider (CSP) and a key container. At each call
/// to this function, the reference count on the CSP is reduced by one. When the reference count reaches zero, the context is fully
/// released and it can no longer be used by any function in the application.
/// </para>
/// <para>
/// An application calls this function after finishing the use of the CSP. After this function is called, the released CSP handle is
/// no longer valid. This function does not destroy key containers or key pairs.
/// </para>
/// </summary>
/// <param name="hProv">Handle of a cryptographic service provider (CSP) created by a call to CryptAcquireContext.</param>
/// <param name="dwFlags">
/// Reserved for future use and must be zero. If dwFlags is not set to zero, this function returns <c>FALSE</c> but the CSP is released.
/// </param>
/// <returns>
/// <para>If the function succeeds, the return value is nonzero ( <c>TRUE</c>).</para>
/// <para>
/// If the function fails, the return value is zero ( <c>FALSE</c>). For extended error information, call GetLastError. Some
/// possible error codes are listed in the following table.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>ERROR_BUSY</term>
/// <term>The CSP context specified by hProv is currently being used by another process.</term>
/// </item>
/// <item>
/// <term>ERROR_INVALID_HANDLE</term>
/// <term>One of the parameters specifies a handle that is not valid.</term>
/// </item>
/// <item>
/// <term>ERROR_INVALID_PARAMETER</term>
/// <term>One of the parameters contains a value that is not valid. This is most often a pointer that is not valid.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_FLAGS</term>
/// <term>The dwFlags parameter is nonzero.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_UID</term>
/// <term>The hProv parameter does not contain a valid context handle.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// After this function has been called, the CSP session is finished and all existing session keys and hash objects created by using
/// the hProv handle are no longer valid. In practice, all of these objects should be destroyed with calls to CryptDestroyKey and
/// CryptDestroyHash before <c>CryptReleaseContext</c> is called.
/// </para>
/// <para>Examples</para>
/// <para>For an example that uses this function, see Example C Program: Creating and Hashing a Session Key.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptreleasecontext BOOL CryptReleaseContext( HCRYPTPROV
// hProv, DWORD dwFlags );
[DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "c1e3e708-b543-4e87-8638-a9946a83e614")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptReleaseContext(HCRYPTPROV hProv, uint dwFlags = 0);
/// <summary>
/// The CryptSetHashParam function customizes the operations of a hash object, including setting up initial hash contents and
/// selecting a specific hashing algorithm.
/// </summary>
/// <param name="hHash">A handle to the hash object on which to set parameters.</param>
/// <param name="dwParam">
/// <para>This parameter can be one of the following values.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>HP_HMAC_INFO.</term>
/// <term>
/// A pointer to an HMAC_INFO structure that specifies the cryptographic hash algorithm and the inner and outer strings to be used.
/// </term>
/// </item>
/// <item>
/// <term>HP_HASHVAL.</term>
/// <term>
/// A byte array that contains a hash value to place directly into the hash object. Before setting this value, the size of the hash
/// value must be determined by using the CryptGetHashParam function to read the HP_HASHSIZE value. Some cryptographic service
/// providers (CSPs) do not support this capability.
/// </term>
/// </item>
/// </list>
/// <para><c>Note</c> Some CSP types can add additional values that can be set by using this function.</para>
/// </param>
/// <param name="pbData">
/// A value data buffer. Place the value data in this buffer before calling <c>CryptSetHashParam</c>. The form of this data varies,
/// depending on the value number.
/// </param>
/// <param name="dwFlags">This parameter is reserved for future use and must be set to zero.</param>
/// <returns>
/// <para>If the function succeeds, the function returns <c>TRUE</c>.</para>
/// <para>If the function fails, it returns <c>FALSE</c>. For extended error information, call GetLastError.</para>
/// <para>The error codes prefaced by "NTE" are generated by the particular CSP you are using. Some possible error codes follow.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>ERROR_INVALID_HANDLE</term>
/// <term>One of the parameters specifies a handle that is not valid.</term>
/// </item>
/// <item>
/// <term>ERROR_BUSY</term>
/// <term>The CSP context is currently being used by another process.</term>
/// </item>
/// <item>
/// <term>ERROR_INVALID_PARAMETER</term>
/// <term>One of the parameters contains a value that is not valid. This is most often a pointer that is not valid.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_FLAGS</term>
/// <term>The dwFlags parameter is nonzero or the pbData buffer contains a value that is not valid.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_HASH</term>
/// <term>The hash object specified by the hHash parameter is not valid.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_TYPE</term>
/// <term>The dwParam parameter specifies an unknown value.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_UID</term>
/// <term>The CSP context that was specified when the hKey key was created cannot be found.</term>
/// </item>
/// <item>
/// <term>NTE_FAIL</term>
/// <term>The function failed in some unexpected way.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// Occasionally, a hash value that has been generated elsewhere must be signed. This can be done by using the following sequence of operations:
/// </para>
/// <list type="number">
/// <item>
/// <term>Create a hash object by using CryptCreateHash.</term>
/// </item>
/// <item>
/// <term>Set the HP_HASHVAL value.</term>
/// </item>
/// <item>
/// <term>Sign the hash value by using CryptSignHash and obtain a digital signature block.</term>
/// </item>
/// <item>
/// <term>Destroy the hash object by using CryptDestroyHash.</term>
/// </item>
/// </list>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptsethashparam BOOL CryptSetHashParam( HCRYPTHASH
// hHash, DWORD dwParam, const BYTE *pbData, DWORD dwFlags );
[DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "0c8d3ef9-e7b5-4e49-a2f8-9c85b16549da")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptSetHashParam(HCRYPTHASH hHash, HashParam dwParam, [In] IntPtr pbData, uint dwFlags = 0);
/// <summary>
/// The CryptSetKeyParam function customizes various aspects of a session key's operations. The values set by this function are not
/// persisted to memory and can only be used with in a single session.
/// <para>
/// The Microsoft Base Cryptographic Provider does not permit setting values for key exchange or signature keys; however, custom
/// providers can define values that can be set for its keys.
/// </para>
/// </summary>
/// <param name="hKey">A handle to the key for which values are to be set.</param>
/// <param name="dwParam">
/// <para>The following tables contain predefined values that can be used.</para>
/// <para>For all key types, this parameter can contain one of the following values.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>KP_ALGID</term>
/// <term>
/// pbData points to an appropriate ALG_ID. This is used when exchanging session keys with the Microsoft Base Digital Signature
/// Standard (DSS), Diffie-Hellman Cryptographic Provider, or compatible CSPs. After a key is agreed upon with the CryptImportKey
/// function, the session key is enabled for use by setting its algorithm type.
/// </term>
/// </item>
/// <item>
/// <term>KP_CERTIFICATE</term>
/// <term>
/// pbData is the address of a buffer that contains the X.509 certificate that has been encoded by using Distinguished Encoding
/// Rules (DER). The public key in the certificate must match the corresponding signature or exchange key.
/// </term>
/// </item>
/// <item>
/// <term>KP_PERMISSIONS</term>
/// <term>pbData points to a DWORD value that specifies zero or more permission flags. For a description of these flags, see CryptGetKeyParam.</term>
/// </item>
/// <item>
/// <term>KP_SALT</term>
/// <term>
/// pbData points to a BYTE array that specifies a new salt value to be made part of the session key. The size of the salt value
/// varies depending on the CSP being used. Before setting this value, determine the size of the salt value by calling the
/// CryptGetKeyParam function. Salt values are used to make the session keys more unique, which makes dictionary attacks more
/// difficult. The salt value is zero by default for Microsoft Base Cryptographic Provider.
/// </term>
/// </item>
/// <item>
/// <term>KP_SALT_EX</term>
/// <term>pbData points to a CRYPT_INTEGER_BLOB structure that contains the salt. For more information, see Specifying a Salt Value.</term>
/// </item>
/// </list>
/// <para>
/// If a Digital Signature Standard (DSS) key is specified by the hKey parameter, the dwParam value can also be set to one of the
/// following values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>KP_G</term>
/// <term>
/// pbData points to the generator G from the DSS key BLOB. The data is in the form of a CRYPT_INTEGER_BLOB structure, where the
/// pbData member is the value, and the cbData member is the length of the value. The value is expected with no header information
/// and in little-endian form.
/// </term>
/// </item>
/// <item>
/// <term>KP_P</term>
/// <term>
/// pbData points to the prime modulus P of a DSS key BLOB. The data is in the form of a CRYPT_INTEGER_BLOB structure. The pbData
/// member is the value, and the cbData member is the length of the value. The value is expected with no header information and in
/// little-endian form.
/// </term>
/// </item>
/// <item>
/// <term>KP_Q</term>
/// <term>
/// pbData points to the prime Q of a DSS key BLOB. The data is in the form of a CRYPT_INTEGER_BLOB structure where the pbData
/// member is the value, and the cbData member is the length of the value. The value is expected with no header information and in
/// little-endian form.
/// </term>
/// </item>
/// <item>
/// <term>KP_X</term>
/// <term>
/// After the P, Q, and G values have been set, a call that specifies the KP_X value for dwParam and NULL for the pbData parameter
/// can be made to the CryptSetKeyParam function. This causes the X and Y values to be generated.
/// </term>
/// </item>
/// </list>
/// <para>
/// If a Diffie-Hellman algorithm or Digital Signature Algorithm (DSA) key is specified by hKey, the dwParam value can also be set
/// to one of the following values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>KP_CMS_DH_KEY_INFO</term>
/// <term>
/// Sets the information for an imported Diffie-Hellman key. The pbData parameter is the address of a CMS_DH_KEY_INFO structure that
/// contains the key information to be set.
/// </term>
/// </item>
/// <item>
/// <term>KP_PUB_PARAMS</term>
/// <term>
/// Sets the public parameters (P, Q, G, and so on) of a DSS or Diffie-Hellman key. The key handle for this key must be in the
/// PREGEN state, generated with the CRYPT_PREGEN flag. The pbData parameter must be a pointer to a DATA_BLOB structure where the
/// data in this structure is a DHPUBKEY_VER3 or DSSPUBKEY_VER3 BLOB. The function copies the public parameters from this
/// CRYPT_INTEGER_BLOB structure to the key handle. After this call is made, the KP_X parameter value should be used with
/// CryptSetKeyParam to create the actual private key. The KP_PUB_PARAMS parameter is used as one call rather than multiple calls
/// with the parameter values KP_P, KP_Q, and KP_G.
/// </term>
/// </item>
/// </list>
/// <para>
/// If a block cipher session key is specified by the hKey parameter, the dwParam value can also be set to one of the following values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>KP_EFFECTIVE_KEYLEN</term>
/// <term>
/// This value type can only be used with RC2 keys and has been added because of the implementation of the CryptSetKeyParam function
/// in the Microsoft Enhanced Cryptographic Provider prior to Windows 2000. In the previous implementation, the RC2 keys in the
/// Enhanced Provider were 128 bits in strength, but the effective key length used to expand keys into the key table was only 40
/// bits. This reduced the strength of the algorithm to 40 bits. To maintain backward compatibility, the previous implementation
/// will remain as is. However, the effective key length can be set to be greater than 40 bits by using KP_EFFECTIVE_KEYLEN in the
/// CryptSetKeyParam call. The effective key length is passed in the pbData parameter as a pointer to a DWORD value with the
/// effective key length value. The minimum effective key length on the Microsoft Base Cryptographic Provider is one, and the
/// maximum is 40. In the Microsoft Enhanced Cryptographic Provider, the minimum is one and the maximum is 1,024. The key length
/// must be set prior to encrypting or decrypting with the key.
/// </term>
/// </item>
/// <item>
/// <term>KP_HIGHEST_VERSION</term>
/// <term>
/// Sets the highest Transport Layer Security (TLS) version allowed. This property only applies to SSL and TLS keys. The pbData
/// parameter is the address of a DWORD variable that contains the highest TLS version number supported.
/// </term>
/// </item>
/// <item>
/// <term>KP_IV</term>
/// <term>
/// pbData points to a BYTE array that specifies the initialization vector. This array must contain BlockLength/8 elements. For
/// example, if the block length is 64 bits, the initialization vector consists of 8 bytes. The initialization vector is set to zero
/// by default for the Microsoft Base Cryptographic Provider.
/// </term>
/// </item>
/// <item>
/// <term>KP_KEYVAL</term>
/// <term>
/// Set the key value for a Data Encryption Standard (DES) key. The pbData parameter is the address of a buffer that contains the
/// key. This buffer must be the same length as the key. This property only applies to DES keys.
/// </term>
/// </item>
/// <item>
/// <term>KP_PADDING</term>
/// <term>
/// Set the padding mode. The pbData parameter is a pointer to a DWORD value that receives a numeric identifier that identifies the
/// padding method used by the cipher. This can be one of the following values. PKCS5_PADDING Specifies the PKCS 5 (sec 6.2) padding
/// method. RANDOM_PADDING The padding uses a random number. This padding method is not supported by the Microsoft supplied CSPs.
/// ZERO_PADDING The padding uses zeros. This padding method is not supported by the Microsoft supplied CSPs.
/// </term>
/// </item>
/// <item>
/// <term>KP_MODE</term>
/// <term>
/// pbData points to a DWORD value that specifies the cipher mode to be used. For a list of the defined cipher modes, see
/// CryptGetKeyParam. The cipher mode is set to CRYPT_MODE_CBC by default for the Microsoft Base Cryptographic Provider.
/// </term>
/// </item>
/// <item>
/// <term>KP_MODE_BITS</term>
/// <term>
/// pbData points to a DWORD value that indicates the number of bits processed per cycle when the Output Feedback (OFB) or Cipher
/// Feedback (CFB) cipher mode is used. The number of bits processed per cycle is set to 8 by default for the Microsoft Base
/// Cryptographic Provider.
/// </term>
/// </item>
/// </list>
/// <para>If an RSA key is specified in the hKey parameter, the dwParam parameter value can be the following value.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>KP_OAEP_PARAMS</term>
/// <term>
/// Set the Optimal Asymmetric Encryption Padding (OAEP) (PKCS #1 version 2) parameters for the key. The pbData parameter is the
/// address of a CRYPT_DATA_BLOB structure that contains the OAEP label. This property only applies to RSA keys.
/// </term>
/// </item>
/// </list>
/// <para>Note that the following values are not used:</para>
/// <list type="bullet">
/// <item>
/// <term>KP_ADMIN_PIN</term>
/// </item>
/// <item>
/// <term>KP_CMS_KEY_INFO</term>
/// </item>
/// <item>
/// <term>KP_INFO</term>
/// </item>
/// <item>
/// <term>KP_KEYEXCHANGE_PIN</term>
/// </item>
/// <item>
/// <term>KP_PRECOMP_MD5</term>
/// </item>
/// <item>
/// <term>KP_PRECOMP_SHA</term>
/// </item>
/// <item>
/// <term>KP_PREHASH</term>
/// </item>
/// <item>
/// <term>KP_PUB_EX_LEN</term>
/// </item>
/// <item>
/// <term>KP_PUB_EX_VAL</term>
/// </item>
/// <item>
/// <term>KP_RA</term>
/// </item>
/// <item>
/// <term>KP_RB</term>
/// </item>
/// <item>
/// <term>KP_ROUNDS</term>
/// </item>
/// <item>
/// <term>KP_RP</term>
/// </item>
/// <item>
/// <term>KP_SIGNATURE_PIN</term>
/// </item>
/// <item>
/// <term>KP_Y</term>
/// </item>
/// </list>
/// </param>
/// <param name="pbData">
/// A pointer to a buffer initialized with the value to be set before calling <c>CryptSetKeyParam</c>. The form of this data varies
/// depending on the value of dwParam.
/// </param>
/// <param name="dwFlags">
/// Used only when dwParam is KP_ALGID. The dwFlags parameter is used to pass in flag values for the enabled key. The dwFlags
/// parameter can hold values such as the key size and the other flag values allowed when generating the same type of key with
/// CryptGenKey. For information about allowable flag values, see <c>CryptGenKey</c>.
/// </param>
/// <returns>
/// <para>If the function succeeds, the return value is nonzero (TRUE).</para>
/// <para>If the function fails, the return value is zero (FALSE). For extended error information, call GetLastError.</para>
/// <para>The error codes prefaced by "NTE" are generated by the particular CSP being used. Some possible error codes follow.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>ERROR_BUSY</term>
/// <term>The CSP context is currently being used by another process.</term>
/// </item>
/// <item>
/// <term>ERROR_INVALID_HANDLE</term>
/// <term>One of the parameters specifies a handle that is not valid.</term>
/// </item>
/// <item>
/// <term>ERROR_INVALID_PARAMETER</term>
/// <term>One of the parameters contains a value that is not valid. This is most often a pointer that is not valid.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_FLAGS</term>
/// <term>The dwFlags parameter is nonzero, or the pbData buffer contains a value that is not valid.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_TYPE</term>
/// <term>The dwParam parameter specifies an unknown parameter.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_UID</term>
/// <term>The CSP context that was specified when the hKey key was created cannot be found.</term>
/// </item>
/// <item>
/// <term>NTE_FAIL</term>
/// <term>The function failed in some unexpected way.</term>
/// </item>
/// <item>
/// <term>NTE_FIXEDPARAMETER</term>
/// <term>
/// Some CSPs have hard-coded P, Q, and G values. If this is the case, then using KP_P, KP_Q, and KP_G for the value of dwParam
/// causes this error.
/// </term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// If the KP_Q, KP_P, or KP_X parameters are set on a PREGEN Diffie-Hellman or DSS key, the key lengths must be compatible with the
/// key length set using the upper 16 bits of the dwFlags parameter when the key was created using CryptGenKey. If no key length was
/// set in <c>CryptGenKey</c>, the default key length was used. This will create an error if a nondefault key length is used to set
/// P, Q, or X.
/// </para>
/// <para>Examples</para>
/// <para>
/// For an example that uses this function, see Example C Program: Duplicating a Session Key. For more code that uses this function,
/// see Example C Program: Setting and Getting Session Key Parameters .
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptsetkeyparam BOOL CryptSetKeyParam( HCRYPTKEY hKey,
// DWORD dwParam, const BYTE *pbData, DWORD dwFlags );
[DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "e99a84a2-c23e-4251-8062-dd286ccc29b7")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptSetKeyParam(HCRYPTKEY hKey, KeyParam dwParam, [In] IntPtr pbData, uint dwFlags);
/// <summary>
/// <para>The CryptSetProvider function specifies the current user's default cryptographic service provider (CSP).</para>
/// <para>
/// If a current user's default provider is set, that default provider is acquired by any call by that user to CryptAcquireContext
/// specifying a dwProvType provider type but not a CSP name.
/// </para>
/// <para>An enhanced version of this function, CryptSetProviderEx, is also available.</para>
/// <para><c>Note</c> Typical applications do not use this function. It is intended for use solely by administrative applications.</para>
/// </summary>
/// <param name="pszProvName">
/// Name of the new default CSP. The named CSP must be installed on the computer. For a list of available cryptographic providers,
/// see Cryptographic Provider Names.
/// </param>
/// <param name="dwProvType">Provider type of the CSP specified by pszProvName.</param>
/// <returns>
/// <para>If the function succeeds, the return value is nonzero (TRUE).</para>
/// <para>
/// If the function fails, the return value is zero (FALSE). For extended error information, call GetLastError. Some possible error
/// codes are listed in the following table.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>ERROR_INVALID_HANDLE</term>
/// <term>One of the parameters specifies a handle that is not valid.</term>
/// </item>
/// <item>
/// <term>ERROR_INVALID_PARAMETER</term>
/// <term>One of the parameters contains a value that is not valid. This is most often a pointer that is not valid.</term>
/// </item>
/// <item>
/// <term>ERROR_NOT_ENOUGH_MEMORY</term>
/// <term>The operating system ran out of memory during the operation.</term>
/// </item>
/// </list>
/// <para>Errors can also be propagated from internal calls to RegCreateKeyEx and RegSetValueEx.</para>
/// </returns>
/// <remarks>
/// <para>
/// Typical applications do not specify a CSP name when calling CryptAcquireContext; however, an application does have the option of
/// selecting a specific CSP. This gives a user the freedom to select a CSP with an appropriate level of security.
/// </para>
/// <para>
/// Since calling <c>CryptSetProvider</c> determines the CSP of a specified type used by all applications that run from that point
/// on, this function must not be called without users' consent.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptsetprovidera BOOL CryptSetProviderA( LPCSTR
// pszProvName, DWORD dwProvType );
[DllImport(Lib.AdvApi32, SetLastError = true, CharSet = CharSet.Auto)]
[PInvokeData("wincrypt.h", MSDNShortId = "44023a0c-3fb4-4746-a676-1671c3ad901b")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptSetProvider([MarshalAs(UnmanagedType.LPTStr)] string pszProvName, uint dwProvType);
/// <summary>
/// <para>
/// The CryptSetProviderEx function specifies the default cryptographic service provider (CSP) of a specified provider type for the
/// local computer or current user.
/// </para>
/// <note>Typical applications do not use this function. It is intended for use solely by administrative applications.</note>
/// </summary>
/// <param name="pszProvName">
/// The name of the new default CSP. This must be a CSP installed on the computer. For a list of available cryptographic providers,
/// see Cryptographic Provider Names.
/// </param>
/// <param name="dwProvType">The provider type of the CSP specified by pszProvName.</param>
/// <param name="pdwReserved">This parameter is reserved for future use and must be <c>NULL</c>.</param>
/// <param name="dwFlags">
/// <para>The following flag values are defined.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>CRYPT_DELETE_DEFAULT 0x00000004</term>
/// <term>Can be used in conjunction with CRYPT_MACHINE_DEFAULT or CRYPT_USER_DEFAULT to delete the default.</term>
/// </item>
/// <item>
/// <term>CRYPT_USER_DEFAULT 0x00000002</term>
/// <term>Causes the user-context default CSP of the specified type to be set.</term>
/// </item>
/// <item>
/// <term>CRYPT_MACHINE_DEFAULT 0x00000001</term>
/// <term>Causes the computer default CSP of the specified type to be set.</term>
/// </item>
/// </list>
/// </param>
/// <returns>
/// <para>If the function succeeds, the return value is nonzero ( <c>TRUE</c>).</para>
/// <para>
/// If the function fails, the return value is zero ( <c>FALSE</c>). For extended error information, call GetLastError. Possible
/// error codes include those shown in the following table.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>ERROR_INVALID_PARAMETER</term>
/// <term>One of the parameters contains a value that is not valid. This is most often a pointer that is not valid.</term>
/// </item>
/// <item>
/// <term>ERROR_NOT_ENOUGH_MEMORY</term>
/// <term>The operating system ran out of memory.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// Most applications do not specify a CSP name when calling the CryptAcquireContext function; however, an application can specify a
/// CSP name and thereby select a CSP with an appropriate level of security. Because calls to <c>CryptSetProviderEx</c> determine
/// the CSP of a specified type used by all applications from that point on, <c>CryptSetProviderEx</c> must never be called without
/// a user's consent.
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptsetproviderexa BOOL CryptSetProviderExA( LPCSTR
// pszProvName, DWORD dwProvType, DWORD *pdwReserved, DWORD dwFlags );
[DllImport(Lib.AdvApi32, SetLastError = true, CharSet = CharSet.Auto)]
[PInvokeData("wincrypt.h", MSDNShortId = "5f0c2724-5144-4a22-a7da-2a5162f06f5d")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptSetProviderEx([MarshalAs(UnmanagedType.LPTStr)] string pszProvName, uint dwProvType, [Optional] IntPtr pdwReserved, CryptProviderFlags dwFlags);
/// <summary>
/// The CryptSetProvParam function customizes the operations of a cryptographic service provider (CSP). This function is commonly
/// used to set a security descriptor on the key container associated with a CSP to control access to the private keys in that key container.
/// </summary>
/// <param name="hProv">
/// The handle of a CSP for which to set values. This handle must have already been created by using the CryptAcquireContext function.
/// </param>
/// <param name="dwParam">
/// <para>Specifies the parameter to set. This can be one of the following values.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>PP_CLIENT_HWND 1 (0x1)</term>
/// <term>
/// Set the window handle that the provider uses as the parent of any dialog boxes it creates. pbData contains a pointer to an HWND
/// that contains the parent window handle. This parameter must be set before calling CryptAcquireContext because many CSPs will
/// display a user interface when CryptAcquireContext is called. You can pass NULL for the hProv parameter to set this window handle
/// for all cryptographic contexts subsequently acquired within this process.
/// </term>
/// </item>
/// <item>
/// <term>PP_DELETEKEY 24 (0x18)</term>
/// <term>
/// Delete the ephemeral key associated with a hash, encryption, or verification context. This will free memory and clear registry
/// settings associated with the key.
/// </term>
/// </item>
/// <item>
/// <term>PP_KEYEXCHANGE_ALG</term>
/// <term>This constant is not used.</term>
/// </item>
/// <item>
/// <term>PP_KEYEXCHANGE_PIN 32 (0x20)</term>
/// <term>Specifies that the key exchange PIN is contained in pbData. The PIN is represented as a null-terminated ASCII string.</term>
/// </item>
/// <item>
/// <term>PP_KEYEXCHANGE_KEYSIZE</term>
/// <term>This constant is not used.</term>
/// </item>
/// <item>
/// <term>PP_KEYSET_SEC_DESCR 8 (0x8)</term>
/// <term>
/// Sets the security descriptor on the key storage container. The pbData parameter is the address of a SECURITY_DESCRIPTOR
/// structure that contains the new security descriptor for the key storage container.
/// </term>
/// </item>
/// <item>
/// <term>PP_PIN_PROMPT_STRING 44 (0x2C)</term>
/// <term>
/// Sets an alternate prompt string to display to the user when the user's PIN is requested. The pbData parameter is a pointer to a
/// null-terminated Unicode string.
/// </term>
/// </item>
/// <item>
/// <term>PP_ROOT_CERTSTORE 46 (0x2E)</term>
/// <term>
/// Sets the root certificate store for the smart card. The provider will copy the root certificates from this store onto the smart
/// card. The pbData parameter is an HCERTSTORE variable that contains the handle of the new certificate store. The provider will
/// copy the certificates from the store during this call, so it is safe to close this store after this function is called. Windows
/// XP and Windows Server 2003: This parameter is not supported.
/// </term>
/// </item>
/// <item>
/// <term>PP_SIGNATURE_ALG</term>
/// <term>This constant is not used.</term>
/// </item>
/// <item>
/// <term>PP_SIGNATURE_PIN 33 (0x21)</term>
/// <term>Specifies the signature PIN. The pbData parameter is a null-terminated ASCII string that represents the PIN.</term>
/// </item>
/// <item>
/// <term>PP_SIGNATURE_KEYSIZE</term>
/// <term>This constant is not used.</term>
/// </item>
/// <item>
/// <term>PP_UI_PROMPT 21 (0x15)</term>
/// <term>
/// For a smart card provider, sets the search string that is displayed to the user as a prompt to insert the smart card. This
/// string is passed as the lpstrSearchDesc member of the OPENCARDNAME_EX structure that is passed to the SCardUIDlgSelectCard
/// function. This string is used for the lifetime of the calling process. The pbData parameter is a pointer to a null-terminated
/// Unicode string.
/// </term>
/// </item>
/// <item>
/// <term>PP_USE_HARDWARE_RNG 38 (0x26)</term>
/// <term>
/// Specifies that the CSP must exclusively use the hardware random number generator (RNG). When PP_USE_HARDWARE_RNG is set, random
/// values are taken exclusively from the hardware RNG and no other sources are used. If a hardware RNG is supported by the CSP and
/// it can be exclusively used, the function succeeds and returns TRUE; otherwise, the function fails and returns FALSE. The pbData
/// parameter must be NULL and dwFlags must be zero when using this value. None of the Microsoft CSPs currently support using a
/// hardware RNG.
/// </term>
/// </item>
/// <item>
/// <term>PP_USER_CERTSTORE 42 (0x2A)</term>
/// <term>
/// Specifies the user certificate store for the smart card. This certificate store contains all of the user certificates that are
/// stored on the smart card. The certificates in this store are encoded by using PKCS_7_ASN_ENCODING or X509_ASN_ENCODING encoding
/// and should contain the CERT_KEY_PROV_INFO_PROP_ID property. The pbData parameter is an HCERTSTORE variable that receives the
/// handle of an in-memory certificate store. When this handle is no longer needed, the caller must close it by using the
/// CertCloseStore function. Windows Server 2003 and Windows XP: This parameter is not supported.
/// </term>
/// </item>
/// <item>
/// <term>PP_SECURE_KEYEXCHANGE_PIN 47 (0x2F)</term>
/// <term>Specifies that an encrypted key exchange PIN is contained in pbData. The pbData parameter contains a DATA_BLOB.</term>
/// </item>
/// <item>
/// <term>PP_SECURE_SIGNATURE_PIN 48 (0x30)</term>
/// <term>Specifies that an encrypted signature PIN is contained in pbData. The pbData parameter contains a DATA_BLOB.</term>
/// </item>
/// <item>
/// <term>PP_SMARTCARD_READER 43 (0x2B)</term>
/// <term>
/// Specifies the name of the smart card reader. The pbData parameter is the address of an ANSI character array that contains a
/// null-terminated ANSI string that contains the name of the smart card reader. Windows Server 2003 and Windows XP: This parameter
/// is not supported.
/// </term>
/// </item>
/// <item>
/// <term>PP_SMARTCARD_GUID 45 (0x2D)</term>
/// <term>
/// Specifies the identifier of the smart card. The pbData parameter is the address of a GUID structure that contains the identifier
/// of the smart card. Windows Server 2003 and Windows XP: This parameter is not supported.
/// </term>
/// </item>
/// </list>
/// </param>
/// <param name="pbData">
/// A pointer to a data buffer that contains the value to be set as a provider parameter. The form of this data varies depending on
/// the dwParam value. If dwParam contains <c>PP_USE_HARDWARE_RNG</c>, this parameter must be <c>NULL</c>.
/// </param>
/// <param name="dwFlags">
/// <para>
/// If dwParam contains <c>PP_KEYSET_SEC_DESCR</c>, dwFlags contains the <c>SECURITY_INFORMATION</c> applicable bit flags, as
/// defined in the Platform SDK. Key-container security is handled by using SetFileSecurity and GetFileSecurity.
/// </para>
/// <para>These bit flags can be combined by using a bitwise- <c>OR</c> operation. For more information, see CryptGetProvParam.</para>
/// <para>If dwParam is <c>PP_USE_HARDWARE_RNG</c> or <c>PP_DELETEKEY</c>, dwFlags must be set to zero.</para>
/// </param>
/// <returns>
/// <para>If the function succeeds, the return value is nonzero ( <c>TRUE</c>).</para>
/// <para>If the function fails, the return value is zero ( <c>FALSE</c>). For extended error information, call GetLastError.</para>
/// <para>The error codes prefaced by "NTE" are generated by the particular CSP being used. Error codes include the following.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>ERROR_BUSY</term>
/// <term>The CSP context is currently being used by another process.</term>
/// </item>
/// <item>
/// <term>ERROR_INVALID_HANDLE</term>
/// <term>One of the parameters specifies a handle that is not valid.</term>
/// </item>
/// <item>
/// <term>ERROR_INVALID_PARAMETER</term>
/// <term>One of the parameters contains a value that is not valid. This is most often a pointer that is not valid.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_FLAGS</term>
/// <term>The dwFlags parameter is nonzero or the pbData buffer contains a value that is not valid.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_TYPE</term>
/// <term>The dwParam parameter specifies an unknown parameter.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_UID</term>
/// <term>The CSP context that was specified when the hKey key was created cannot be found.</term>
/// </item>
/// <item>
/// <term>NTE_FAIL</term>
/// <term>The function failed in some unexpected way.</term>
/// </item>
/// </list>
/// </returns>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptsetprovparam BOOL CryptSetProvParam( HCRYPTPROV
// hProv, DWORD dwParam, const BYTE *pbData, DWORD dwFlags );
[DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "98306a7b-b218-4eb4-99f0-0b5bcc632a13")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptSetProvParam(HCRYPTPROV hProv, ProvParam dwParam, [In] IntPtr pbData, uint dwFlags);
/// <summary>
/// The CryptSignHash function signs data. Because all signature algorithms are asymmetric and thus slow, CryptoAPI does not allow
/// data to be signed directly. Instead, data is first hashed, and CryptSignHash is used to sign the hash.
/// </summary>
/// <param name="hHash">Handle of the hash object to be signed.</param>
/// <param name="dwKeySpec">
/// <para>Identifies the private key to use from the provider's container. It can be AT_KEYEXCHANGE or AT_SIGNATURE.</para>
/// <para>The signature algorithm used is specified when the key pair is originally created.</para>
/// <para>The only signature algorithm that the Microsoft Base Cryptographic Provider supports is the RSA Public Key algorithm.</para>
/// </param>
/// <param name="szDescription">
/// This parameter is no longer used and must be set to <c>NULL</c> to prevent security vulnerabilities. However, it is still
/// supported for backward compatibility in the Microsoft Base Cryptographic Provider.
/// </param>
/// <param name="dwFlags">
/// <para>The following flag values are defined.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>CRYPT_NOHASHOID 0x00000001</term>
/// <term>
/// Used with RSA providers. The hash object identifier (OID) is not placed in the RSA public key encryption. If this flag is not
/// set, the hash OID in the default signature is as specified in the definition of DigestInfo in PKCS #1.
/// </term>
/// </item>
/// <item>
/// <term>CRYPT_TYPE2_FORMAT 0x00000002</term>
/// <term>This flag is not used.</term>
/// </item>
/// <item>
/// <term>CRYPT_X931_FORMAT 0x00000004</term>
/// <term>Use the RSA signature padding method specified in the ANSI X9.31 standard.</term>
/// </item>
/// </list>
/// </param>
/// <param name="pbSignature">
/// <para>A pointer to a buffer receiving the signature data.</para>
/// <para>
/// This parameter can be <c>NULL</c> to set the buffer size for memory allocation purposes. For more information, see Retrieving
/// Data of Unknown Length.
/// </para>
/// </param>
/// <param name="pdwSigLen">
/// <para>
/// A pointer to a <c>DWORD</c> value that specifies the size, in bytes, of the pbSignature buffer. When the function returns, the
/// <c>DWORD</c> value contains the number of bytes stored in the buffer.
/// </para>
/// <para>
/// <c>Note</c> 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 fits 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.
/// </para>
/// </param>
/// <returns>
/// <para>If the function succeeds, the function returns <c>TRUE</c>.</para>
/// <para>If the function fails, it returns <c>FALSE</c>. For extended error information, call GetLastError.</para>
/// <para>The error codes prefaced by "NTE" are generated by the particular CSP you are using. Some possible error codes follow.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>ERROR_INVALID_HANDLE</term>
/// <term>One of the parameters specifies a handle that is not valid.</term>
/// </item>
/// <item>
/// <term>ERROR_INVALID_PARAMETER</term>
/// <term>One of the parameters contains a value that is not valid. This is most often a pointer that is not valid.</term>
/// </item>
/// <item>
/// <term>ERROR_MORE_DATA</term>
/// <term>
/// The buffer specified by the pbSignature parameter is not large enough to hold the returned data. The required buffer size, in
/// bytes, is in the pdwSigLenDWORD value.
/// </term>
/// </item>
/// <item>
/// <term>NTE_BAD_ALGID</term>
/// <term>The hHash handle specifies an algorithm that this CSP does not support, or the dwKeySpec parameter has an incorrect value.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_FLAGS</term>
/// <term>The dwFlags parameter is nonzero.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_HASH</term>
/// <term>The hash object specified by the hHash parameter is not valid.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_UID</term>
/// <term>The CSP context that was specified when the hash object was created cannot be found.</term>
/// </item>
/// <item>
/// <term>NTE_NO_KEY</term>
/// <term>The private key specified by dwKeySpec does not exist.</term>
/// </item>
/// <item>
/// <term>NTE_NO_MEMORY</term>
/// <term>The CSP ran out of memory during the operation.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// Before calling this function, the CryptCreateHash function must be called to get a handle to a hash object. The CryptHashData or
/// CryptHashSessionKey function is then used to add the data or session keys to the hash object. The <c>CryptSignHash</c> function
/// completes the hash.
/// </para>
/// <para>
/// While the DSS CSP supports hashing with both the MD5 and the SHA hash algorithms, the DSS CSP only supports signing SHA hashes.
/// </para>
/// <para>
/// After this function is called, no more data can be added to the hash. Additional calls to CryptHashData or CryptHashSessionKey fail.
/// </para>
/// <para>After the application finishes using the hash, destroy the hash object by calling the CryptDestroyHash function.</para>
/// <para>
/// By default, the Microsoft RSA providers use the PKCS #1 padding method for the signature. The hash OID in the <c>DigestInfo</c>
/// element of the signature is automatically set to the algorithm OID associated with the hash object. Using the
/// <c>CRYPT_NOHASHOID</c> flag will cause this OID to be omitted from the signature.
/// </para>
/// <para>
/// Occasionally, a hash value that has been generated elsewhere must be signed. This can be done by using the following sequence of operations:
/// </para>
/// <list type="number">
/// <item>
/// <term>Create a hash object by using CryptCreateHash.</term>
/// </item>
/// <item>
/// <term>Set the hash value in the hash object by using the <c>HP_HASHVAL</c> value of the dwParam parameter in CryptSetHashParam.</term>
/// </item>
/// <item>
/// <term>Sign the hash value by using <c>CryptSignHash</c> and obtain a digital signature block.</term>
/// </item>
/// <item>
/// <term>Destroy the hash object by using CryptDestroyHash.</term>
/// </item>
/// </list>
/// <para>Examples</para>
/// <para>
/// The following example shows signing data by first hashing the data to be signed and then signing the hash by using the
/// <c>CryptSignHash</c> function.
/// </para>
/// <para>
/// For a complete example including the context for this code, see Example C Program: Signing a Hash and Verifying the Hash Signature.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptsignhasha BOOL CryptSignHashA( HCRYPTHASH hHash,
// DWORD dwKeySpec, LPCSTR szDescription, DWORD dwFlags, BYTE *pbSignature, DWORD *pdwSigLen );
[DllImport(Lib.AdvApi32, SetLastError = true, CharSet = CharSet.Auto)]
[PInvokeData("wincrypt.h", MSDNShortId = "9cf0de04-fdad-457d-8137-16d98f915cd5")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptSignHash(HCRYPTHASH hHash, CertKeySpec dwKeySpec, [Optional, MarshalAs(UnmanagedType.LPTStr)] string szDescription, CryptSignFlags dwFlags, [Out, Optional] IntPtr pbSignature, ref uint pdwSigLen);
/// <summary>
/// <para>The CryptVerifySignature function verifies the signature of a hash object.</para>
/// <para>
/// Before calling this function, CryptCreateHash must be called to create the handle of a hash object. CryptHashData or
/// CryptHashSessionKey is then used to add data or session keys to the hash object.
/// </para>
/// <para>After <c>CryptVerifySignature</c> completes, only CryptDestroyHash can be called by using the hHash handle.</para>
/// </summary>
/// <param name="hHash">A handle to the hash object to verify.</param>
/// <param name="pbSignature">The address of the signature data to be verified.</param>
/// <param name="dwSigLen">The number of bytes in the pbSignature signature data.</param>
/// <param name="hPubKey">
/// A handle to the public key to use to authenticate the signature. This public key must belong to the key pair that was originally
/// used to create the digital signature.
/// </param>
/// <param name="szDescription">
/// This parameter should no longer be used and must be set to <c>NULL</c> to prevent security vulnerabilities. However, it is still
/// supported for backward compatibility in the Microsoft Base Cryptographic Provider.
/// </param>
/// <param name="dwFlags">
/// <para>The following flag values are defined.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>CRYPT_NOHASHOID 0x00000001</term>
/// <term>
/// This flag is used with RSA providers. When verifying the signature, the hash object identifier (OID) is not expected to be
/// present or checked. If this flag is not set, the hash OID in the default signature is verified as specified in the definition of
/// DigestInfo in PKCS #7.
/// </term>
/// </item>
/// <item>
/// <term>CRYPT_TYPE2_FORMAT 0x00000002</term>
/// <term>This flag is not used.</term>
/// </item>
/// <item>
/// <term>CRYPT_X931_FORMAT 0x00000004</term>
/// <term>Use X.931 support for the FIPS 186-2compliant version of RSA (rDSA).</term>
/// </item>
/// </list>
/// </param>
/// <returns>
/// <para>If the function succeeds, the return value is <c>TRUE</c>.</para>
/// <para>If the function fails, the return value is <c>FALSE</c>. For extended error information, call GetLastError.</para>
/// <para>The error codes prefaced by "NTE" are generated by the particular CSP you are using. Some possible error codes follow.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>ERROR_INVALID_HANDLE</term>
/// <term>One of the parameters specifies a handle that is not valid.</term>
/// </item>
/// <item>
/// <term>ERROR_INVALID_PARAMETER</term>
/// <term>One of the parameters contains a value that is not valid. This is most often a pointer that is not valid.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_FLAGS</term>
/// <term>The dwFlags parameter is nonzero.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_HASH</term>
/// <term>The hash object specified by the hHash parameter is not valid.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_KEY</term>
/// <term>The hPubKey parameter does not contain a handle to a valid public key.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_SIGNATURE</term>
/// <term>
/// The signature was not valid. This might be because the data itself has changed, the description string did not match, or the
/// wrong public key was specified by hPubKey. This error can also be returned if the hashing or signature algorithms do not match
/// the ones used to create the signature.
/// </term>
/// </item>
/// <item>
/// <term>NTE_BAD_UID</term>
/// <term>The cryptographic service provider (CSP) context that was specified when the hash object was created cannot be found.</term>
/// </item>
/// <item>
/// <term>NTE_NO_MEMORY</term>
/// <term>The CSP ran out of memory during the operation.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The <c>CryptVerifySignature</c> function completes the hash. After this call, no more data can be added to the hash. Additional
/// calls to CryptHashData or CryptHashSessionKey fail. After the application is done with the hash, CryptDestroyHash should be
/// called to destroy the hash object.
/// </para>
/// <para>
/// If you generate a signature by using the .NET Framework APIs and try to verify it by using the <c>CryptVerifySignature</c>
/// function, the function will fail and GetLastError will return <c>NTE_BAD_SIGNATURE</c>. This is due to the different byte orders
/// between the native Win32 API and the .NET Framework API.
/// </para>
/// <para>
/// The native cryptography API uses little-endian byte order while the .NET Framework API uses big-endian byte order. If you are
/// verifying a signature generated by using a .NET Framework API, you must swap the order of signature bytes before calling the
/// <c>CryptVerifySignature</c> function to verify the signature.
/// </para>
/// <para>Examples</para>
/// <para>
/// For an example that uses the <c>CryptVerifySignature</c> function, see Example C Program: Signing a Hash and Verifying the Hash Signature.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptverifysignaturea BOOL CryptVerifySignatureA(
// HCRYPTHASH hHash, const BYTE *pbSignature, DWORD dwSigLen, HCRYPTKEY hPubKey, LPCSTR szDescription, DWORD dwFlags );
[DllImport(Lib.AdvApi32, SetLastError = true, CharSet = CharSet.Auto)]
[PInvokeData("wincrypt.h", MSDNShortId = "3119eabc-90ff-42c6-b3fa-e8be625f6d1e")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptVerifySignature(HCRYPTHASH hHash, [In] IntPtr pbSignature, uint dwSigLen, HCRYPTKEY hPubKey, [Optional, MarshalAs(UnmanagedType.LPTStr)] string szDescription, CryptSignFlags dwFlags);
private static TRet CryptGetValue<THandle, TEnum, TRet>(CryptGetValueMethod<THandle, TEnum> func, THandle hKey, TEnum dwParam, uint dwFlags = 0) where THandle : struct where TEnum : Enum
{
var len = 0U;
if (!func(hKey, dwParam, default, ref len, dwFlags))
Win32Error.ThrowLastError();
using var mem = new SafeHGlobalHandle(len);
if (!func(hKey, dwParam, mem, ref len, dwFlags))
Win32Error.ThrowLastError();
return mem.DangerousGetHandle().Convert<TRet>(mem.Size);
}
/// <summary>
/// The <c>HMAC_INFO</c> structure specifies the hash algorithm and the inner and outer strings that are to be used to calculate the
/// HMAC hash.
/// </summary>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/ns-wincrypt-hmac_info typedef struct _HMAC_Info { ALG_ID HashAlgid;
// BYTE *pbInnerString; DWORD cbInnerString; BYTE *pbOuterString; DWORD cbOuterString; } HMAC_INFO, *PHMAC_INFO;
[PInvokeData("wincrypt.h", MSDNShortId = "0c9a9b60-077d-48c0-a5a6-01640cfc0c4e")]
[StructLayout(LayoutKind.Sequential)]
public struct HMAC_INFO
{
/// <summary>Specifies the hash algorithm to be used.</summary>
public ALG_ID HashAlgid;
/// <summary>
/// A pointer to the inner string to be used in the HMAC calculation. The default inner string is defined as the byte 0x36
/// repeated 64 times.
/// </summary>
public IntPtr pbInnerString;
/// <summary>
/// The count of bytes in <c>pbInnerString</c>. The CSP uses the default inner string if <c>cbInnerString</c> is equal to zero.
/// </summary>
public uint cbInnerString;
/// <summary>
/// A pointer to the outer string to be used in the HMAC calculation. The default outer string is defined as the byte 0x5C
/// repeated 64 times.
/// </summary>
public IntPtr pbOuterString;
/// <summary>
/// The count of bytes in <c>pbOuterString</c>. The CSP uses the default outer string if <c>cbOuterString</c> is equal to zero.
/// </summary>
public uint cbOuterString;
}
/// <summary>
/// The <c>PROV_ENUMALGS</c> structure is used with the CryptGetProvParam function when the <c>PP_ENUMALGS</c> parameter is retrieved to
/// contain information about an algorithm supported by a cryptographic service provider (CSP).
/// </summary>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/ns-wincrypt-prov_enumalgs
// typedef struct _PROV_ENUMALGS { ALG_ID aiAlgid; DWORD dwBitLen; DWORD dwNameLen; CHAR szName[20]; } PROV_ENUMALGS;
[PInvokeData("wincrypt.h", MSDNShortId = "8301d07f-88aa-49b4-9091-8f515b585c57")]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
2020-03-13 17:45:15 -04:00
public struct PROV_ENUMALGS
{
/// <summary>One of the ALG_ID values that identifies the algorithm.</summary>
public ALG_ID aiAlgid;
/// <summary>The default key length, in bits, of the algorithm.</summary>
public uint dwBitLen;
/// <summary>The length, in <c>CHAR</c>s, of the <c>szName</c> string. This length includes the terminating null character.</summary>
public uint dwNameLen;
/// <summary>A null-terminated ANSI string that contains the name of the algorithm.</summary>
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]
public string szName;
2020-03-13 17:45:15 -04:00
}
/// <summary>
/// The <c>PROV_ENUMALGS_EX</c> structure is used with the CryptGetProvParam function when the <c>PP_ENUMALGS_EX</c> parameter is
/// retrieved to contain information about an algorithm supported by a cryptographic service provider (CSP).
/// </summary>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/ns-wincrypt-prov_enumalgs_ex typedef struct _PROV_ENUMALGS_EX {
// ALG_ID aiAlgid; DWORD dwDefaultLen; DWORD dwMinLen; DWORD dwMaxLen; DWORD dwProtocols; DWORD dwNameLen; CHAR szName[20]; DWORD
// dwLongNameLen; CHAR szLongName[40]; } PROV_ENUMALGS_EX;
[PInvokeData("wincrypt.h", MSDNShortId = "239dbc6f-c3fa-4f97-aa9a-4993fe726a98")]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct PROV_ENUMALGS_EX
{
/// <summary>One of the ALG_ID values that identifies the algorithm.</summary>
public ALG_ID aiAlgid;
/// <summary>The default key length, in bits, of the algorithm.</summary>
public uint dwDefaultLen;
/// <summary>The minimum key length, in bits, of the algorithm.</summary>
public uint dwMinLen;
/// <summary>The maximum key length, in bits, of the algorithm.</summary>
public uint dwMaxLen;
/// <summary>
/// Zero or a combination of one or more of the Protocol Flags values that identifies the protocols supported by the algorithm.
/// </summary>
public uint dwProtocols;
/// <summary>The length, in <c>CHAR</c> s, of the <c>szName</c> string. This length includes the terminating null character.</summary>
public uint dwNameLen;
/// <summary>A null-terminated ANSI string that contains the name of the algorithm.</summary>
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]
public string szName;
/// <summary>The length, in <c>CHAR</c> s, of the <c>szLongName</c> string. This length includes the terminating null character.</summary>
public uint dwLongNameLen;
/// <summary>A null-terminated ANSI string that contains the long name of the algorithm.</summary>
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 40)]
public string szLongName;
}
/// <summary>Provides a <see cref="SafeHandle"/> for <see cref="HCRYPTHASH"/> that is disposed using <see cref="CryptDestroyHash"/>.</summary>
public class SafeHCRYPTHASH : SafeHANDLE
{
/// <summary>Represents a NULL handle for <see cref="SafeHCRYPTHASH"/>. This must be used instead of <see langword="null"/>.</summary>
public static readonly SafeHCRYPTHASH Null = new SafeHCRYPTHASH(IntPtr.Zero, false);
2020-03-13 17:45:15 -04:00
/// <summary>Initializes a new instance of the <see cref="SafeHCRYPTHASH"/> class and assigns an existing handle.</summary>
/// <param name="preexistingHandle">An <see cref="IntPtr"/> object that represents the pre-existing handle to use.</param>
/// <param name="ownsHandle">
/// <see langword="true"/> to reliably release the handle during the finalization phase; otherwise, <see langword="false"/> (not recommended).
/// </param>
public SafeHCRYPTHASH(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { }
/// <summary>Initializes a new instance of the <see cref="SafeHCRYPTHASH"/> class.</summary>
private SafeHCRYPTHASH() : base() { }
/// <summary>Performs an implicit conversion from <see cref="SafeHCRYPTHASH"/> to <see cref="HCRYPTHASH"/>.</summary>
/// <param name="h">The safe handle instance.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator HCRYPTHASH(SafeHCRYPTHASH h) => h.handle;
/// <inheritdoc/>
protected override bool InternalReleaseHandle() => CryptDestroyHash(handle);
}
/// <summary>Provides a <see cref="SafeHandle"/> for <see cref="HCRYPTPROV"/> that is disposed using <see cref="CryptReleaseContext"/>.</summary>
public class SafeHCRYPTPROV : SafeHANDLE
{
/// <summary>Represents a NULL handle for <see cref="SafeHCRYPTPROV"/>. This must be used instead of <see langword="null"/>.</summary>
public static readonly SafeHCRYPTPROV Null = new SafeHCRYPTPROV(IntPtr.Zero, false);
2020-03-13 17:45:15 -04:00
/// <summary>Initializes a new instance of the <see cref="SafeHCRYPTPROV"/> class and assigns an existing handle.</summary>
/// <param name="preexistingHandle">An <see cref="IntPtr"/> object that represents the pre-existing handle to use.</param>
/// <param name="ownsHandle">
/// <see langword="true"/> to reliably release the handle during the finalization phase; otherwise, <see langword="false"/> (not recommended).
/// </param>
public SafeHCRYPTPROV(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { }
/// <summary>Initializes a new instance of the <see cref="SafeHCRYPTPROV"/> class.</summary>
private SafeHCRYPTPROV() : base() { }
/// <summary>Performs an implicit conversion from <see cref="SafeHCRYPTPROV"/> to <see cref="HCRYPTPROV"/>.</summary>
/// <param name="h">The safe handle instance.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator HCRYPTPROV(SafeHCRYPTPROV h) => h.handle;
/// <inheritdoc/>
protected override bool InternalReleaseHandle() => CryptReleaseContext(handle);
}
/// <summary>
/// The following cryptographic service provider (CSP) names are defined in Wincrypt.h. These constants are used with the
/// <c>CryptAcquireContext</c> and <c>CryptSetProvider</c> functions.
/// </summary>
// https://docs.microsoft.com/en-us/windows/win32/seccrypto/cryptographic-provider-names
[PInvokeData("wincrypt.h", MSDNShortId = "97e9a708-83b5-48b3-9d16-f7b54367dc4e")]
public static class CryptProviderName
{
/// <summary>The Microsoft DSS and Diffie-Hellman/Schannel Cryptographic Provider.</summary>
public const string MS_DEF_DH_SCHANNEL_PROV = "Microsoft DH Schannel Cryptographic Provider";
/// <summary>The Microsoft Base DSS and Diffie-Hellman Cryptographic Provider.</summary>
public const string MS_DEF_DSS_DH_PROV = "Microsoft Base DSS and Diffie-Hellman Cryptographic Provider";
/// <summary>The Microsoft DSS Cryptographic Provider.</summary>
public const string MS_DEF_DSS_PROV = "Microsoft Base DSS Cryptographic Provider";
/// <summary>The Microsoft Base Cryptographic Provider.</summary>
public const string MS_DEF_PROV = "Microsoft Base Cryptographic Provider v1.0";
/// <summary>The Microsoft RSA/Schannel Cryptographic Provider.</summary>
public const string MS_DEF_RSA_SCHANNEL_PROV = "Microsoft RSA Schannel Cryptographic Provider";
/// <summary>The Microsoft RSA Signature Cryptographic Provider is not supported.</summary>
public const string MS_DEF_RSA_SIG_PROV = "Microsoft RSA Signature Cryptographic Provider";
/// <summary>The Microsoft Enhanced DSS and Diffie-Hellman Cryptographic Provider.</summary>
public const string MS_ENH_DSS_DH_PROV = "Microsoft Enhanced DSS and Diffie-Hellman Cryptographic Provider";
/// <summary>
/// The Microsoft AES Cryptographic Provider.
/// <para>**Windows XP: **"Microsoft Enhanced RSA and AES Cryptographic Provider (Prototype)"</para>
/// </summary>
public const string MS_ENH_RSA_AES_PROV = "Microsoft Enhanced RSA and AES Cryptographic Provider";
/// <summary>The Microsoft Enhanced Cryptographic Provider.</summary>
public const string MS_ENHANCED_PROV = "Microsoft Enhanced Cryptographic Provider v1.0";
/// <summary>The Microsoft Base Smart Card Cryptographic Service Provider.</summary>
public const string MS_SCARD_PROV = "Microsoft Base Smart Card Crypto Provider";
/// <summary>The Microsoft Strong Cryptographic Provider.</summary>
public const string MS_STRONG_PROV = "Microsoft Strong Cryptographic Provider";
}
2018-08-17 09:38:58 -04:00
}
2019-06-04 14:16:41 -04:00
}