diff --git a/PInvoke/Security/AdvApi32/WinCrypt.cs b/PInvoke/Security/AdvApi32/WinCrypt.cs index 1a4029fc..9630800b 100644 --- a/PInvoke/Security/AdvApi32/WinCrypt.cs +++ b/PInvoke/Security/AdvApi32/WinCrypt.cs @@ -1,9 +1,7005 @@ using System; +using System.Collections.Generic; using System.Runtime.InteropServices; +using System.Text; +using Vanara.InteropServices; +using static Vanara.PInvoke.Crypt32; namespace Vanara.PInvoke { public static partial class AdvApi32 { + private delegate bool CryptGetValueMethod(THandle hKey, TEnum dwParam, IntPtr pbData, ref uint pdwDataLen, uint dwFlags) where THandle : struct where TEnum : Enum; + + /// Flag values for . + [PInvokeData("wincrypt.h", MSDNShortId = "57e13662-3189-4f8d-b90a-d1fbdc09b63c")] + [Flags] + public enum CryptAcquireContextFlags : uint + { + /// + /// 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. + /// + CRYPT_VERIFYCONTEXT = 0xF0000000, + + /// + /// Creates a new key container with the name specified by pszContainer. If pszContainer is NULL, a key container with the + /// default name is created. + /// + CRYPT_NEWKEYSET = 0x00000008, + + /// + /// 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. + /// + CRYPT_DELETEKEYSET = 0x00000010, + + /// + /// 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. + /// + CRYPT_MACHINE_KEYSET = 0x00000020, + + /// + /// 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. + /// + CRYPT_SILENT = 0x00000040, + + /// + /// 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. + /// + CRYPT_DEFAULT_CONTAINER_OPTIONAL = 0x00000080, + } + + /// Flags for CryptDecrypt. + [PInvokeData("wincrypt.h", MSDNShortId = "7c3d2838-6fd1-4f6c-9586-8b94b459a31a")] + [Flags] + public enum CryptDecryptFlags + { + /// + /// 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. + /// + CRYPT_OAEP = 0x00000040, + + /// + /// 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. + /// + CRYPT_DECRYPT_RSA_NO_PADDING_CHECK = 0x00000020, + } + + /// Flags for CryptEncrypt. + [PInvokeData("wincrypt.h", MSDNShortId = "697c4960-552b-4c3a-95cf-4632af56945b")] + [Flags] + public enum CryptEncryptFlags + { + /// + /// 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. + /// + CRYPT_OAEP = 0x00000040, + } + + /// Flags for . + [PInvokeData("wincrypt.h", MSDNShortId = "8a7c7b46-3bea-4043-b568-6d91d6335737")] + [Flags] + public enum CryptExportKeyFlags + { + /// This flag causes this function to export version 3 of a BLOB type. + CRYPT_BLOB_VER3 = 0x00000080, + + /// This flag destroys the original key in the OPAQUEKEYBLOB. This flag is available in Schannel CSPs only. + CRYPT_DESTROYKEY = 0x00000004, + + /// + /// This flag causes PKCS #1 version 2 formatting to be created with the RSA encryption and decryption when exporting SIMPLEBLOBs. + /// + CRYPT_OAEP = 0x00000040, + + /// + /// 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. + /// + CRYPT_SSL2_FALLBACK = 0x00000002, + + /// This flag is not used. + CRYPT_Y_ONLY = 0x00000001, + + /// + CRYPT_IPSEC_HMAC_KEY = 0x00000100, + } + + /// Flags for and . + [PInvokeData("wincrypt.h", MSDNShortId = "b65dd856-2dfa-4cda-9b2f-b32f3c291470")] + [Flags] + public enum CryptGenKeyFlags : uint + { + /// + /// 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. + /// + CRYPT_EXPORTABLE = 0x00000001, + + /// + /// 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. + /// + CRYPT_USER_PROTECTED = 0x00000002, + + /// + /// 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. + /// + /// + CRYPT_CREATE_SALT = 0x00000004, + + /// + /// 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. + /// + CRYPT_UPDATE_KEY = 0x00000008, + + /// + /// This flag specifies that a no salt value gets allocated for a 40-bit symmetric key. For more information, see Salt Value Functionality. + /// + CRYPT_NO_SALT = 0x00000010, + + /// + /// 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. + /// + CRYPT_PREGEN = 0x00000040, + + /// This flag is not used. + CRYPT_RECIPIENT = 0x00000010, + + /// This flag is not used. + CRYPT_INITIATOR = 0x00000040, + + /// This flag is not used. + CRYPT_ONLINE = 0x00000080, + + /// This flag is not used. + CRYPT_SF = 0x00000100, + + /// This flag is not used. + CRYPT_CREATE_IV = 0x00000200, + + /// This flag is not used. + CRYPT_KEK = 0x00000400, + + /// This flag is not used. + CRYPT_DATA_KEY = 0x00000800, + + /// This flag is not used. + CRYPT_VOLATILE = 0x00001000, + + /// This flag is not used. + CRYPT_SGCKEY = 0x00002000, + + /// This flag is not used. + CRYPT_USER_PROTECTED_STRONG = 0x00100000, + + /// + /// 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. + /// + CRYPT_ARCHIVABLE = 0x00004000, + + /// + /// + /// 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. + /// + CRYPT_FORCE_KEY_PROTECTION_HIGH = 0x00008000, + + /// + /// 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. + /// + CRYPT_SERVER = 0x400, + } + + /// Flags for . + [Flags] + public enum CryptHashSessionKeyFlags + { + /// + /// 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. + /// + CRYPT_LITTLE_ENDIAN = 1 + } + + /// Flags for and . + [PInvokeData("wincrypt.h", MSDNShortId = "5d15641e-1ad7-441d-9423-65fd51de9812")] + [Flags] + public enum CryptProviderFlags + { + /// Returns the user-context default CSP of the specified type. + CRYPT_USER_DEFAULT = 0x00000002, + + /// Returns the computer default CSP of the specified type. + CRYPT_MACHINE_DEFAULT = 0x00000001, + + /// Can be used in conjunction with CRYPT_MACHINE_DEFAULT or CRYPT_USER_DEFAULT to delete the default. + CRYPT_DELETE_DEFAULT = 0x00000004, + } + + /// Flags for and . + [PInvokeData("wincrypt.h", MSDNShortId = "3119eabc-90ff-42c6-b3fa-e8be625f6d1e")] + [Flags] + public enum CryptSignFlags + { + /// + /// 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. + /// + CRYPT_NOHASHOID = 0x00000001, + + /// This flag is not used. + CRYPT_TYPE2_FORMAT = 0x00000002, + + /// Use X.931 support for the FIPS 186-2–compliant version of RSA (rDSA). + CRYPT_X931_FORMAT = 0x00000004, + } + + /// Query type. + [PInvokeData("wincrypt.h", MSDNShortId = "ed008c07-1a40-4075-bdaa-eb7f7e12d9c3")] + public enum HashParam + { + /// + /// An ALG_ID that indicates the algorithm specified when the hash object was created. For a list of hash algorithms, see CryptCreateHash. + /// + [CorrespondingType(typeof(ALG_ID), CorrespondingAction.Get)] + [CorrespondingType(typeof(uint))] + HP_ALGID = 0x0001, + + /// + /// 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. + /// + /// + [CorrespondingType(typeof(byte[]))] + [CorrespondingType(typeof(IntPtr))] + HP_HASHVAL = 0x0002, + + /// + /// 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. + /// + [CorrespondingType(typeof(uint), CorrespondingAction.Get)] + HP_HASHSIZE = 0x0004, + + /// + /// A pointer to an HMAC_INFO structure that specifies the cryptographic hash algorithm and the inner and outer strings to be used. + /// + [CorrespondingType(typeof(HMAC_INFO), CorrespondingAction.Set)] + HP_HMAC_INFO = 0x0005, + + /// + /// Component of the function argument GOSTR3411_PRF. It takes various values ​​in client and server messages when implementing + /// the TLS Handshake Protocol. + /// + [CorrespondingType(typeof(CRYPTOAPI_BLOB), CorrespondingAction.Set)] + HP_TLS1PRF_LABEL = 0x0006, + + /// + /// Component of the function argument GOSTR3411_PRF. It takes various values ​​in client and server messages when implementing + /// the TLS Handshake Protocol. + /// + [CorrespondingType(typeof(CRYPTOAPI_BLOB), CorrespondingAction.Set)] + HP_TLS1PRF_SEED = 0x0007, + } + + /// Specifies the type of query being made. + [PInvokeData("wincrypt.h", MSDNShortId = "07956d74-0e22-484b-9bf1-e0184a2ff32f")] + public enum KeyParam + { + /// + /// 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. + /// + KP_IV = 1, + + /// + /// 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. + /// + KP_SALT = 2, + + /// + /// + /// 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. + ///
+ ///
+ KP_PADDING = 3, + + /// + /// + /// 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. + ///
+ ///
+ KP_MODE = 4, + + /// + /// 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. + /// + KP_MODE_BITS = 5, + + /// + /// + /// 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. + ///
+ ///
+ KP_PERMISSIONS = 6, + + /// + /// 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. + /// + /// + KP_ALGID = 7, + + /// + /// 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. + /// + /// + KP_BLOCKLEN = 8, + + /// + /// 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. + /// + /// + KP_KEYLEN = 9, + + /// + KP_SALT_EX = 10, + + /// + /// 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. + /// + KP_P = 11, + + /// + /// 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. + /// + KP_G = 12, + + /// + /// 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. + /// + KP_Q = 13, + + /// + KP_X = 14, + + /// + KP_Y = 15, + + /// + KP_RA = 16, + + /// + KP_RB = 17, + + /// + KP_INFO = 18, + + /// + /// 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. + /// + KP_EFFECTIVE_KEYLEN = 19, + + /// + KP_SCHANNEL_ALG = 20, + + /// + KP_CLIENT_RANDOM = 21, + + /// + KP_SERVER_RANDOM = 22, + + /// + KP_RP = 23, + + /// + KP_PRECOMP_MD5 = 24, + + /// + KP_PRECOMP_SHA = 25, + + /// + /// 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. + /// + KP_CERTIFICATE = 26, + + /// + KP_CLEAR_KEY = 27, + + /// + KP_PUB_EX_LEN = 28, + + /// + KP_PUB_EX_VAL = 29, + + /// + /// 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. + /// + /// + KP_KEYVAL = 30, + + /// + KP_ADMIN_PIN = 31, + + /// + KP_KEYEXCHANGE_PIN = 32, + + /// + KP_SIGNATURE_PIN = 33, + + /// + KP_PREHASH = 34, + + /// + KP_ROUNDS = 35, + + /// + KP_OAEP_PARAMS = 36, + + /// + KP_CMS_KEY_INFO = 37, + + /// + KP_CMS_DH_KEY_INFO = 38, + + /// + KP_PUB_PARAMS = 39, + + /// + /// 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. + /// + KP_VERIFY_PARAMS = 40, + + /// + KP_HIGHEST_VERSION = 41, + + /// This value is not used. + KP_GET_USE_COUNT = 42, + + /// + KP_PIN_ID = 43, + + /// + KP_PIN_INFO = 44, + } + + /// The nature of the query. + [PInvokeData("wincrypt.h", MSDNShortId = "c0b7c1c8-aa42-4d40-a7f7-99c0821c8977")] + public enum ProvParam + { + /// Returns the administrator personal identification number (PIN) in the pbData parameter as a LPSTR. + PP_ADMIN_PIN = 0x1F, + + /// This constant is not used. + PP_APPLI_CERT = 0x12, + + /// This constant is not used. + PP_CHANGE_PASSWORD = 0x7, + + /// + /// Returns the certificate chain associated with the hProv handle. The returned certificate chain is X509_ASN_ENCODING encoded. + /// + PP_CERTCHAIN = 0x9, + + /// + /// 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. + /// + PP_CONTAINER = 0x6, + + /// + /// Not implemented by Microsoft CSPs. This behavior may be implemented by other CSPs. + /// Windows XP: This parameter is not supported. + /// + PP_CRYPT_COUNT_KEY_USE = 0x29, + + /// + /// 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. + /// + /// + PP_ENUMALGS = 0x1, + + /// + /// 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. + /// + /// + PP_ENUMALGS_EX = 0x16, + + /// + /// 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. + /// + /// + PP_ENUMCONTAINERS = 0x2, + + /// This constant is not used. + PP_ENUMELECTROOTS = 0x1A, + + /// + /// 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. + /// + PP_ENUMEX_SIGNING_PROT = 0x28, + + /// This constant is not used. + PP_ENUMMANDROOTS = 0x19, + + /// A DWORD value that indicates how the CSP is implemented. For a table of possible values, see Remarks. + PP_IMPTYPE = 0x3, + + /// This query is not used. + PP_KEY_TYPE_SUBTYPE = 0xA, + + /// + /// Specifies that the key exchange PIN is contained in pbData. The PIN is represented as a null-terminated ASCII string. + /// + PP_KEYEXCHANGE_PIN = 0x20, + + /// + /// 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. + /// + PP_KEYSET_SEC_DESCR = 0x8, + + /// + /// 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. + /// + PP_KEYSET_TYPE = 0x1B, + + /// + /// 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. + /// + PP_KEYSPEC = 0x27, + + /// Returns a DWORD value of CRYPT_SEC_DESCR. + PP_KEYSTORAGE = 0x11, + + /// + /// 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. + /// + PP_KEYX_KEYSIZE_INC = 0x23, + + /// + /// 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. + /// + PP_NAME = 0x4, + + /// A DWORD value that indicates the provider type of the CSP. + PP_PROVTYPE = 0x10, + + /// + /// 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. + /// + PP_ROOT_CERTSTORE = 0x2E, + + /// The size, in bits, of the session key. + PP_SESSION_KEYSIZE = 0x14, + + /// Used with server gated cryptography. + PP_SGC_INFO = 0x25, + + /// + /// 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. + /// + /// + PP_SIG_KEYSIZE_INC = 0x22, + + /// + /// Specifies that the key signature PIN is contained in pbData. The PIN is represented as a null-terminated ASCII string. + /// + PP_SIGNATURE_PIN = 0x21, + + /// + /// 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. + /// + PP_SMARTCARD_GUID = 0x2D, + + /// + /// 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. + /// + PP_SMARTCARD_READER = 0x2B, + + /// + PP_SMARTCARD_READER_ICON = 47, + + /// The size of the symmetric key. + PP_SYM_KEYSIZE = 0x13, + + /// This query is not used. + PP_UI_PROMPT = 0x15, + + /// + /// 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. + /// + PP_UNIQUE_CONTAINER = 0x24, + + /// + /// 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. + /// + PP_USE_HARDWARE_RNG = 0x26, + + /// + /// 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. + /// + PP_USER_CERTSTORE = 0x2A, + + /// + /// 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. + /// + PP_VERSION = 0x5, + } + + /// + /// + /// 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. + /// + /// + /// 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. + /// + /// + /// 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. + /// + /// + /// + /// A pointer to a handle of a CSP. When you have finished using the CSP, release the handle by calling the CryptReleaseContext function. + /// + /// + /// + /// 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 + /// NULL. However, for hardware-based CSPs, such as a smart card CSP, can be access publically available information in the + /// specfied container. + /// + /// For more information about the usage of the pszContainer parameter, see Remarks. + /// + /// + /// A null-terminated string that contains the name of the CSP to be used. + /// + /// If this parameter is NULL, 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. + /// + /// + /// 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. + /// + /// + /// 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. + /// + /// + /// + /// Specifies the type of provider to acquire. Defined provider types are discussed in Cryptographic Provider Types. + /// + /// + /// Flag values. This parameter is usually set to zero, but some applications set one or more of the following flags. + /// + /// + /// Value + /// Meaning + /// + /// + /// CRYPT_VERIFYCONTEXT + /// + /// 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. + /// + /// + /// + /// CRYPT_NEWKEYSET + /// + /// Creates a new key container with the name specified by pszContainer. If pszContainer is NULL, a key container with the default + /// name is created. + /// + /// + /// + /// CRYPT_MACHINE_KEYSET + /// + /// 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. + /// + /// + /// + /// CRYPT_DELETEKEYSET + /// + /// 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. + /// + /// + /// + /// CRYPT_SILENT + /// + /// 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. + /// + /// + /// + /// CRYPT_DEFAULT_CONTAINER_OPTIONAL + /// + /// 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. + /// + /// + /// + /// + /// + /// If the function succeeds, the function returns nonzero ( TRUE). + /// If the function fails, it returns zero ( FALSE). For extended error information, call GetLastError. + /// + /// The error codes prefaced by NTE are generated by the particular CSP being used. Some possible error codes defined in Winerror.h follow. + /// + /// + /// + /// Return code/value + /// Description + /// + /// + /// ERROR_BUSY 107L + /// Some CSPs set this error if the CRYPT_DELETEKEYSET flag value is set and another thread or process is using this key container. + /// + /// + /// ERROR_FILE_NOT_FOUND 2L + /// + /// 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. + /// + /// + /// + /// ERROR_INVALID_PARAMETER 87L + /// One of the parameters contains a value that is not valid. This is most often a pointer that is not valid. + /// + /// + /// ERROR_NOT_ENOUGH_MEMORY 8L + /// The operating system ran out of memory during the operation. + /// + /// + /// NTE_BAD_FLAGS 0x80090009L + /// The dwFlags parameter has a value that is not valid. + /// + /// + /// NTE_BAD_KEY_STATE 0x8009000BL + /// The user password has changed since the private keys were encrypted. + /// + /// + /// NTE_BAD_KEYSET 0x80090016L + /// + /// 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. + /// + /// + /// + /// NTE_BAD_KEYSET_PARAM 0x8009001FL + /// The pszContainer or pszProvider parameter is set to a value that is not valid. + /// + /// + /// NTE_BAD_PROV_TYPE 0x80090014L + /// The value of the dwProvType parameter is out of range. All provider types must be from 1 through 999, inclusive. + /// + /// + /// NTE_BAD_SIGNATURE 0x80090006L + /// The provider DLL signature could not be verified. Either the DLL or the digital signature has been tampered with. + /// + /// + /// NTE_EXISTS 0x8009000FL + /// The dwFlags parameter is CRYPT_NEWKEYSET, but the key container already exists. + /// + /// + /// NTE_KEYSET_ENTRY_BAD 0x8009001AL + /// The pszContainer key container was found but is corrupt. + /// + /// + /// NTE_KEYSET_NOT_DEF 0x80090019L + /// The requested provider does not exist. + /// + /// + /// NTE_NO_MEMORY 0x8009000EL + /// The CSP ran out of memory during the operation. + /// + /// + /// NTE_PROV_DLL_NOT_FOUND 0x8009001EL + /// The provider DLL file does not exist or is not on the current path. + /// + /// + /// NTE_PROV_TYPE_ENTRY_BAD 0x80090018L + /// + /// 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. + /// + /// + /// + /// NTE_PROV_TYPE_NO_MATCH 0x8009001BL + /// + /// 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. + /// + /// + /// + /// NTE_PROV_TYPE_NOT_DEF 0x80090017L + /// No entry exists for the provider type specified by dwProvType. + /// + /// + /// NTE_PROVIDER_DLL_FAIL 0x8009001DL + /// The provider DLL file could not be loaded or failed to initialize. + /// + /// + /// NTE_SIGNATURE_FILE_BAD 0x8009001CL + /// An error occurred while loading the DLL file image, prior to verifying its signature. + /// + /// + /// + /// + /// + /// 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. + /// + /// + /// 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. + /// + /// + /// If you set the pszContainer parameter to NULL, 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 CryptAcquireContext 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 CRYPT_VERIFYCONTEXT flag in the dwFlags parameter, or use an + /// application-specific container that is unlikely to be used by another application. + /// + /// + /// An application can obtain the name of the key container in use by using the CryptGetProvParam function to read the PP_CONTAINER value. + /// + /// + /// For performance reasons, we recommend that you set the pszContainer parameter to NULL and the dwFlags parameter to + /// CRYPT_VERIFYCONTEXT in all situations where you do not require a persisted key. In particular, consider setting the + /// pszContainer parameter to NULL and the dwFlags parameter to CRYPT_VERIFYCONTEXT for the following scenarios: + /// + /// + /// + /// You are creating a hash. + /// + /// + /// You are generating a symmetric key to encrypt or decrypt data. + /// + /// + /// You are deriving a symmetric key from a hash to encrypt or decrypt data. + /// + /// + /// + /// 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 CRYPT_VERIFYCONTEXT flag if you only + /// plan to import the public key. + /// + /// + /// + /// + /// 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 CRYPT_VERIFYCONTEXT flag if you only plan to import the public key for the last two scenarios. + /// + /// + /// + /// You are performing private key operations, but you are not using a persisted private key that is stored in a key container. + /// + /// + /// + /// 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 CRYPT_NEWKEYSET flag. + /// + /// Examples + /// + /// 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. + /// + /// + /// 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. + /// + /// + // 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); + + /// + /// 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. + /// + /// + /// HCRYPTPROV handle for which the reference count is being incremented. This handle must have already been created using CryptAcquireContext. + /// + /// Reserved for future use and must be NULL. + /// Reserved for future use and must be zero. + /// + /// If the function succeeds, the return value is nonzero (TRUE). + /// + /// If the function fails, the return value is zero (FALSE). For extended error information, call GetLastError. One possible error + /// code is the following. + /// + /// + /// + /// Return code + /// Description + /// + /// + /// ERROR_INVALID_PARAMETER + /// One of the parameters contains a value that is not valid. This is most often a pointer that is not valid. + /// + /// + /// + /// + /// + /// This function increases the reference count on a HCRYPTPROV handle so that multiple calls to CryptReleaseContext are required to + /// actually release the handle. + /// + /// Examples + /// The following example increments the reference count on an acquired CSP handle. + /// For another example that uses this function, see Example C Program: Using CryptAcquireContext. + /// + // 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); + + /// + /// 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. + /// + /// A handle to a CSP created by a call to CryptAcquireContext. + /// + /// An ALG_ID value that identifies the hash algorithm to use. + /// Valid values for this parameter vary, depending on the CSP that is used. For a list of default algorithms, see Remarks. + /// + /// + /// + /// 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. + /// + /// + /// 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). + /// + /// + /// + /// The following flag value is defined. + /// + /// + /// Value + /// Meaning + /// + /// + /// CRYPT_SECRETDIGEST 0x00000001 + /// This flag is not used. + /// + /// + /// + /// + /// 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. + /// + /// + /// If the function succeeds, the function returns TRUE. + /// If the function fails, it returns FALSE. For extended error information, call GetLastError. + /// + /// 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. + /// + /// + /// + /// Return code + /// Description + /// + /// + /// ERROR_INVALID_HANDLE + /// One of the parameters specifies a handle that is not valid. + /// + /// + /// ERROR_INVALID_PARAMETER + /// One of the parameters contains a value that is not valid. This is most often a pointer that is not valid. + /// + /// + /// ERROR_NOT_ENOUGH_MEMORY + /// The operating system ran out of memory during the operation. + /// + /// + /// NTE_BAD_ALGID + /// The Algid parameter specifies an algorithm that this CSP does not support. + /// + /// + /// NTE_BAD_FLAGS + /// The dwFlags parameter is nonzero. + /// + /// + /// NTE_BAD_KEY + /// + /// 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. + /// + /// + /// + /// NTE_NO_MEMORY + /// The CSP ran out of memory during the operation. + /// + /// + /// + /// + /// For a list of Microsoft service providers and the algorithms they implement, see Microsoft Cryptographic Service Providers. + /// + /// 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: + /// + /// + /// + /// The hash value can be retrieved by using CryptGetHashParam. + /// + /// + /// A session key can be derived by using CryptDeriveKey. + /// + /// + /// The hash can be signed by using CryptSignHash. + /// + /// + /// A signature can be verified by using CryptVerifySignature. + /// + /// + /// After one of the functions from this list has been called, CryptHashData and CryptHashSessionKey cannot be called. + /// Examples + /// + /// 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. + /// + /// + // 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); + + /// + /// The CryptDecrypt function decrypts data previously encrypted by using the CryptEncrypt function. + /// + /// 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. + /// + /// + /// + /// + /// A handle to the key to use for the decryption. An application obtains this handle by using either the CryptGenKey or + /// CryptImportKey function. + /// + /// This key specifies the decryption algorithm to be used. + /// + /// + /// + /// 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. + /// + /// + /// Before calling CryptDecrypt, 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. + /// + /// If no hash is to be done, this parameter must be zero. + /// + /// + /// A Boolean value that specifies whether this is the last section in a series being decrypted. This value is TRUE if this + /// is the last or only block. If this is not the last block, this value is FALSE. For more information, see Remarks. + /// + /// + /// The following flag values are defined. + /// + /// + /// Value + /// Meaning + /// + /// + /// CRYPT_OAEP 0x00000040 + /// + /// 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. + /// + /// + /// + /// CRYPT_DECRYPT_RSA_NO_PADDING_CHECK 0x00000020 + /// + /// 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. + /// + /// + /// + /// + /// + /// + /// 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. + /// + /// The number of encrypted bytes in this buffer is specified by pdwDataLen. + /// + /// + /// + /// A pointer to a DWORD value that indicates the length of the pbData buffer. Before calling this function, the calling + /// application sets the DWORD value to the number of bytes to be decrypted. Upon return, the DWORD value contains the + /// number of bytes of the decrypted plaintext. + /// + /// + /// 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 TRUE. + /// + /// + /// + /// If the function succeeds, the function returns nonzero ( TRUE). + /// If the function fails, it returns zero ( FALSE). For extended error information, call GetLastError. + /// The error codes prefaced by NTE are generated by the particular CSP being used. Some possible error codes follow. + /// + /// + /// Value + /// Description + /// + /// + /// ERROR_INVALID_HANDLE + /// One of the parameters specifies a handle that is not valid. + /// + /// + /// ERROR_INVALID_PARAMETER + /// One of the parameters contains a value that is not valid. This is most often a pointer that is not valid. + /// + /// + /// NTE_BAD_ALGID + /// The hKey session key specifies an algorithm that this CSP does not support. + /// + /// + /// NTE_BAD_DATA + /// + /// 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. + /// + /// + /// + /// NTE_BAD_FLAGS + /// The dwFlags parameter is nonzero. + /// + /// + /// NTE_BAD_HASH + /// The hHash parameter contains a handle that is not valid. + /// + /// + /// NTE_BAD_KEY + /// The hKey parameter does not contain a valid handle to a key. + /// + /// + /// NTE_BAD_LEN + /// The size of the output buffer is too small to hold the generated plaintext. + /// + /// + /// NTE_BAD_UID + /// The CSP context that was specified when the key was created cannot be found. + /// + /// + /// NTE_DOUBLE_ENCRYPT + /// The application attempted to decrypt the same data twice. + /// + /// + /// NTE_FAIL + /// The function failed in some unexpected way. + /// + /// + /// + /// + /// + /// If a large amount of data is to be decrypted, it can be done in sections by calling CryptDecrypt repeatedly. The Final + /// parameter must be set to TRUE only on the last call to CryptDecrypt, so that the decryption engine can properly + /// finish the decryption process. The following extra actions are performed when Final is TRUE: + /// + /// + /// + /// + /// 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. + /// + /// + /// + /// + /// If the cipher is operating in a chaining mode, the next CryptDecrypt operation resets the cipher's feedback register to + /// the KP_IV value of the key. + /// + /// + /// + /// If the cipher is a stream cipher, the next CryptDecrypt call resets the cipher to its initial state. + /// + /// + /// + /// 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 + /// TRUE. 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 CryptDecrypt 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. + /// + /// + /// 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. + /// + /// Examples + /// For an example that uses this function, see Example C Program: Decrypting a File. + /// + // 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); + + /// + /// The CryptDecrypt function decrypts data previously encrypted by using the CryptEncrypt function. + /// + /// 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. + /// + /// + /// + /// + /// A handle to the key to use for the decryption. An application obtains this handle by using either the CryptGenKey or + /// CryptImportKey function. + /// + /// This key specifies the decryption algorithm to be used. + /// + /// + /// + /// 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. + /// + /// + /// Before calling CryptDecrypt, 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. + /// + /// If no hash is to be done, this parameter must be zero. + /// + /// + /// A Boolean value that specifies whether this is the last section in a series being decrypted. This value is TRUE if this + /// is the last or only block. If this is not the last block, this value is FALSE. For more information, see Remarks. + /// + /// + /// The following flag values are defined. + /// + /// + /// Value + /// Meaning + /// + /// + /// CRYPT_OAEP 0x00000040 + /// + /// 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. + /// + /// + /// + /// CRYPT_DECRYPT_RSA_NO_PADDING_CHECK 0x00000020 + /// + /// 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. + /// + /// + /// + /// + /// + /// + /// 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. + /// + /// The number of encrypted bytes in this buffer is specified by pdwDataLen. + /// + /// + /// + /// A pointer to a DWORD value that indicates the length of the pbData buffer. Before calling this function, the calling + /// application sets the DWORD value to the number of bytes to be decrypted. Upon return, the DWORD value contains the + /// number of bytes of the decrypted plaintext. + /// + /// + /// 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 TRUE. + /// + /// + /// + /// If the function succeeds, the function returns nonzero ( TRUE). + /// If the function fails, it returns zero ( FALSE). For extended error information, call GetLastError. + /// The error codes prefaced by NTE are generated by the particular CSP being used. Some possible error codes follow. + /// + /// + /// Value + /// Description + /// + /// + /// ERROR_INVALID_HANDLE + /// One of the parameters specifies a handle that is not valid. + /// + /// + /// ERROR_INVALID_PARAMETER + /// One of the parameters contains a value that is not valid. This is most often a pointer that is not valid. + /// + /// + /// NTE_BAD_ALGID + /// The hKey session key specifies an algorithm that this CSP does not support. + /// + /// + /// NTE_BAD_DATA + /// + /// 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. + /// + /// + /// + /// NTE_BAD_FLAGS + /// The dwFlags parameter is nonzero. + /// + /// + /// NTE_BAD_HASH + /// The hHash parameter contains a handle that is not valid. + /// + /// + /// NTE_BAD_KEY + /// The hKey parameter does not contain a valid handle to a key. + /// + /// + /// NTE_BAD_LEN + /// The size of the output buffer is too small to hold the generated plaintext. + /// + /// + /// NTE_BAD_UID + /// The CSP context that was specified when the key was created cannot be found. + /// + /// + /// NTE_DOUBLE_ENCRYPT + /// The application attempted to decrypt the same data twice. + /// + /// + /// NTE_FAIL + /// The function failed in some unexpected way. + /// + /// + /// + /// + /// + /// If a large amount of data is to be decrypted, it can be done in sections by calling CryptDecrypt repeatedly. The Final + /// parameter must be set to TRUE only on the last call to CryptDecrypt, so that the decryption engine can properly + /// finish the decryption process. The following extra actions are performed when Final is TRUE: + /// + /// + /// + /// + /// 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. + /// + /// + /// + /// + /// If the cipher is operating in a chaining mode, the next CryptDecrypt operation resets the cipher's feedback register to + /// the KP_IV value of the key. + /// + /// + /// + /// If the cipher is a stream cipher, the next CryptDecrypt call resets the cipher to its initial state. + /// + /// + /// + /// 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 + /// TRUE. 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 CryptDecrypt 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. + /// + /// + /// 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. + /// + /// Examples + /// For an example that uses this function, see Example C Program: Decrypting a File. + /// + // 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); + + /// + /// + /// 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. + /// + /// + /// This function is the same as CryptGenKey, except that the generated session keys are derived from base data instead of being + /// random. CryptDeriveKey can only be used to generate session keys. It cannot generate public/private key pairs. + /// + /// + /// 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. + /// + /// + /// A HCRYPTPROV handle of a CSP created by a call to CryptAcquireContext. + /// + /// + /// 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 ALG_ID. + /// + /// + /// For more information about ALG_ID values to use with the Microsoft Base Cryptographic Provider, see Base Provider Algorithms. + /// For more information about ALG_ID values to use with the Microsoft Strong Cryptographic Provider or the Microsoft + /// Enhanced Cryptographic Provider, see Enhanced Provider Algorithms. + /// + /// + /// + /// A handle to a hash object that has been fed the exact base data. + /// + /// 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. + /// + /// + /// + /// Specifies the type of key generated. + /// + /// 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- OR 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. + /// + /// + /// 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- + /// OR operator to combine them. + /// + /// + /// + /// Value + /// Meaning + /// + /// + /// CRYPT_CREATE_SALT + /// + /// 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. + /// + /// + /// + /// CRYPT_EXPORTABLE + /// + /// 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. + /// + /// + /// + /// CRYPT_NO_SALT + /// + /// This flag specifies that a no salt value gets allocated for a 40-bit symmetric key. For more information, see Salt Value Functionality. + /// + /// + /// + /// CRYPT_UPDATE_KEY + /// + /// 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. + /// + /// + /// + /// CRYPT_SERVER 1024 (0x400) + /// + /// 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. + /// + /// + /// + /// + /// + /// 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. + /// + /// + /// If the function succeeds, the function returns nonzero ( TRUE). + /// If the function fails, it returns zero ( FALSE). For extended error information, call GetLastError. + /// + /// The error codes prefaced by "NTE" are generated by the particular CSP being used. Some possible error codes are listed in the + /// following table. + /// + /// + /// + /// Return code + /// Description + /// + /// + /// ERROR_INVALID_HANDLE + /// One of the parameters specifies a handle that is not valid. + /// + /// + /// ERROR_INVALID_PARAMETER + /// One of the parameters contains a value that is not valid. This is most often a pointer that is not valid. + /// + /// + /// NTE_BAD_ALGID + /// The Algid parameter specifies an algorithm that this CSP does not support. + /// + /// + /// NTE_BAD_FLAGS + /// The dwFlags parameter contains a value that is not valid. + /// + /// + /// NTE_BAD_HASH + /// The hBaseData parameter does not contain a valid handle to a hash object. + /// + /// + /// NTE_BAD_HASH_STATE + /// An attempt was made to add data to a hash object that is already marked "finished." + /// + /// + /// NTE_BAD_UID + /// The hProv parameter does not contain a valid context handle. + /// + /// + /// NTE_FAIL + /// The function failed in some unexpected way. + /// + /// + /// NTE_SILENT_CONTEXT + /// The provider could not perform the action because the context was acquired as silent. + /// + /// + /// + /// + /// + /// 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. + /// + /// + /// The CryptDeriveKey function completes the hash. After CryptDeriveKey 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. + /// + /// To choose an appropriate key length, the following methods are recommended. + /// + /// + /// + /// 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. + /// + /// + /// + /// + /// 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. + /// + /// + /// + /// After the desired key length has been chosen, use the upper 16 bits of the dwFlags parameter to specify the key length. + /// + /// + /// + /// Let n be the required derived key length, in bytes. The derived key is the first n bytes of the hash value after + /// the hash computation has been completed by CryptDeriveKey. 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: + /// + /// + /// + /// + /// Form a 64-byte buffer by repeating the constant 0x36 64 times. Let k be the length of the hash value that is + /// represented by the input parameter hBaseData. Set the first k bytes of the buffer to the result of an XOR + /// operation of the first k bytes of the buffer with the hash value that is represented by the input parameter hBaseData. + /// + /// + /// + /// + /// Form a 64-byte buffer by repeating the constant 0x5C 64 times. Set the first k bytes of the buffer to the result + /// of an XOR operation of the first k bytes of the buffer with the hash value that is represented by the input + /// parameter hBaseData. + /// + /// + /// + /// + /// 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. + /// + /// + /// + /// + /// 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. + /// + /// + /// + /// Concatenate the result of step 3 with the result of step 4. + /// + /// + /// Use the first n bytes of the result of step 5 as the derived key. + /// + /// + /// + /// 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. + /// + /// The following table lists minimum, default, and maximum key lengths for session key by algorithm and provider. + /// + /// + /// Provider + /// Algorithms + /// Minimum key length + /// Default key length + /// Maximum key length + /// + /// + /// MS Base + /// RC4 and RC2 + /// 40 + /// 40 + /// 56 + /// + /// + /// MS Base + /// DES + /// 56 + /// 56 + /// 56 + /// + /// + /// MS Enhanced + /// RC4 and RC2 + /// 40 + /// 128 + /// 128 + /// + /// + /// MS Enhanced + /// DES + /// 56 + /// 56 + /// 56 + /// + /// + /// MS Enhanced + /// 3DES 112 + /// 112 + /// 112 + /// 112 + /// + /// + /// MS Enhanced + /// 3DES + /// 168 + /// 168 + /// 168 + /// + /// + /// MS Strong + /// RC4 and RC2 + /// 40 + /// 128 + /// 128 + /// + /// + /// MS Strong + /// DES + /// 56 + /// 56 + /// 56 + /// + /// + /// MS Strong + /// 3DES 112 + /// 112 + /// 112 + /// 112 + /// + /// + /// MS Strong + /// 3DES + /// 168 + /// 168 + /// 168 + /// + /// + /// DSS/DH Base + /// RC4 and RC2 + /// 40 + /// 40 + /// 56 + /// + /// + /// DSS/DH Base + /// Cylink MEK + /// 40 + /// 40 + /// 40 + /// + /// + /// DSS/DH Base + /// DES + /// 56 + /// 56 + /// 56 + /// + /// + /// DSS/DH Enh + /// RC4 and RC2 + /// 40 + /// 128 + /// 128 + /// + /// + /// DSS/DH Enh + /// Cylink MEK + /// 40 + /// 40 + /// 40 + /// + /// + /// DSS/DH Enh + /// DES + /// 56 + /// 56 + /// 56 + /// + /// + /// DSS/DH Enh + /// 3DES 112 + /// 112 + /// 112 + /// 112 + /// + /// + /// DSS/DH Enh + /// 3DES + /// 168 + /// 168 + /// 168 + /// + /// + /// Examples + /// For an example that uses this function, see Example C Program: Deriving a Session Key from a Password. + /// + // 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); + + /// + /// 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. + /// To help ensure security, we recommend that hash objects be destroyed after they have been used. + /// + /// The handle of the hash object to be destroyed. + /// + /// If the function succeeds, the return value is nonzero. + /// If the function fails, the return value is zero. For extended error information, call GetLastError. + /// + /// The error codes prefaced by "NTE" are generated by the particular cryptographic service provider (CSP) you are using. Some + /// possible error codes follow. + /// + /// + /// + /// Return code + /// Description + /// + /// + /// ERROR_BUSY + /// The hash object specified by hHash is currently being used and cannot be destroyed. + /// + /// + /// ERROR_INVALID_HANDLE + /// The hHash parameter specifies a handle that is not valid. + /// + /// + /// ERROR_INVALID_PARAMETER + /// The hHash parameter contains a value that is not valid. + /// + /// + /// NTE_BAD_ALGID + /// The hHash handle specifies an algorithm that this CSP does not support. + /// + /// + /// NTE_BAD_HASH + /// The hash object specified by the hHash parameter is not valid. + /// + /// + /// NTE_BAD_UID + /// The CSP context that was specified when the hash object was created cannot be found. + /// + /// + /// + /// + /// + /// 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. + /// + /// There should be a one-to-one correspondence between calls to CryptCreateHash and CryptDestroyHash. + /// + /// 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. + /// + /// Examples + /// For an example that uses the CryptDestroyHash function, see Example C Program: Creating and Hashing a Session Key. + /// + // 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); + + /// + /// 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. + /// + /// 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. + /// + /// + /// The handle of the key to be destroyed. + /// + /// If the function succeeds, the return value is nonzero. + /// If the function fails, the return value is zero. For extended error information, call GetLastError. + /// + /// The error codes prefaced by "NTE" are generated by the particular CSP being used. Some possible error codes are listed in the + /// following table. + /// + /// + /// + /// Return code + /// Description + /// + /// + /// ERROR_BUSY + /// The key object specified by hKey is currently being used and cannot be destroyed. + /// + /// + /// ERROR_INVALID_HANDLE + /// The hKey parameter specifies a handle that is not valid. + /// + /// + /// ERROR_INVALID_PARAMETER + /// The hKey parameter contains a value that is not valid. + /// + /// + /// NTE_BAD_KEY + /// The hKey parameter does not contain a valid handle to a key. + /// + /// + /// NTE_BAD_UID + /// The CSP context that was specified when the key was created cannot be found. + /// + /// + /// + /// + /// + /// 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 CryptDestroyKey function when they are finished with them. + /// + /// + /// 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. + /// + /// Examples + /// For an example that uses the CryptDestroyKey function, see Example C Program: Creating and Hashing a Session Key. + /// + // 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); + + /// + /// + /// The CryptDuplicateHash 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. + /// + /// + /// A hash can be created in a piece-by-piece way. The CryptDuplicateHash function can be used to create separate hashes of + /// two different contents that begin with the same content. + /// + /// + /// Handle of the hash to be duplicated. + /// Reserved for future use and must be zero. + /// Reserved for future use and must be zero. + /// + /// Address of the handle of the duplicated hash. When you have finished using the hash, release the handle by calling the + /// CryptDestroyHash function. + /// + /// + /// If the function succeeds, the function returns TRUE. + /// If the function fails, it returns FALSE. For extended error information, call GetLastError. + /// + /// The error code prefaced by "NTE" is generated by the particular cryptographic service provider (CSP) that you are using. Some + /// possible error codes follow. + /// + /// + /// + /// Return code + /// Description + /// + /// + /// ERROR_CALL_NOT_IMPLEMENTED + /// + /// Because this is a new function, existing CSPs cannot implement it. This error is returned if the CSP does not support this function. + /// + /// + /// + /// ERROR_INVALID_PARAMETER + /// One of the parameters contains a value that is not valid. This is most often a pointer that is not valid. + /// + /// + /// NTE_BAD_HASH + /// A handle to the original hash is not valid. + /// + /// + /// + /// + /// + /// CryptDuplicateHash 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 CryptDuplicateHash function, and then the data unique to + /// each hash would be added. + /// + /// + /// The CryptDestroyHash function must be called to destroy any hashes that are created with CryptDuplicateHash. 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. + /// + /// Examples + /// + /// 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. + /// + /// + // 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); + + /// The CryptDuplicateKey function makes an exact copy of a key and the state of the key. + /// A handle to the key to be duplicated. + /// Reserved for future use and must be NULL. + /// Reserved for future use and must be zero. + /// + /// Address of the handle to the duplicated key. When you have finished using the key, release the handle by calling the + /// CryptDestroyKey function. + /// + /// + /// If the function succeeds, the return value is nonzero (TRUE). + /// If the function fails, the return value is zero (FALSE). For extended error information, call GetLastError. + /// + /// The error code prefaced by "NTE" is generated by the particular CSP being used. Some possible error codes are listed in the + /// following table. + /// + /// + /// + /// Return code + /// Description + /// + /// + /// ERROR_CALL_NOT_IMPLEMENTED + /// + /// Because this is a new function, existing CSPs might not implement it. This error is returned if the CSP does not support this function. + /// + /// + /// + /// ERROR_INVALID_PARAMETER + /// One of the parameters contains a value that is not valid. This is most often a pointer that is not valid. + /// + /// + /// NTE_BAD_KEY + /// A handle to the original key is not valid. + /// + /// + /// + /// + /// + /// CryptDuplicateKey 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 CryptDuplicateKey function. The different salt values are then + /// set on the original and duplicate keys with separate calls to the CryptSetKeyParam function. + /// + /// + /// CryptDestroyKey must be called to destroy any keys that are created by using CryptDuplicateKey. 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. + /// + /// Examples + /// + /// 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. + /// + /// + // 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); + + /// + /// + /// 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. + /// + /// + /// 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. + /// + /// + /// Important The CryptEncrypt function is not guaranteed to be thread safe and may return incorrect results if + /// invoked simultaneously by multiple callers. + /// + /// + /// + /// + /// A handle to the encryption key. An application obtains this handle by using either the CryptGenKey or the CryptImportKey function. + /// + /// The key specifies the encryption algorithm used. + /// + /// + /// + /// 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. + /// + /// + /// Before calling CryptEncrypt, 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. + /// + /// If no hash is to be done, this parameter must be NULL. + /// + /// + /// A Boolean value that specifies whether this is the last section in a series being encrypted. Final is set to TRUE for the + /// last or only block and to FALSE if there are more blocks to be encrypted. For more information, see Remarks. + /// + /// + /// The following dwFlags value is defined but reserved for future use. + /// + /// + /// Value + /// Meaning + /// + /// + /// CRYPT_OAEP + /// + /// 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. + /// + /// + /// + /// + /// + /// + /// 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. + /// + /// + /// 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. + /// + /// + /// If this parameter contains NULL, this function will calculate the required size for the ciphertext and place that in the + /// value pointed to by the pdwDataLen parameter. + /// + /// + /// + /// + /// A pointer to a DWORD value that , on entry, contains the length, in bytes, of the plaintext in the pbData buffer. On + /// exit, this DWORD contains the length, in bytes, of the ciphertext written to the pbData buffer. + /// + /// + /// If the buffer allocated for pbData is not large enough to hold the encrypted data, GetLastError returns ERROR_MORE_DATA + /// and stores the required buffer size, in bytes, in the DWORD value pointed to by pdwDataLen. + /// + /// + /// If pbData is NULL, no error is returned, and the function stores the size of the encrypted data, in bytes, in the + /// DWORD value pointed to by pdwDataLen. This allows an application to determine the correct buffer size. + /// + /// + /// 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 TRUE. + /// + /// + /// + /// Specifies the total size, in bytes, of the input pbData buffer. + /// + /// 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. + /// + /// + /// 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. + /// + /// + /// + /// If the function succeeds, the function returns nonzero ( TRUE). + /// If the function fails, it returns zero ( FALSE). For extended error information, call GetLastError. + /// The error codes prefaced by NTE are generated by the particular CSP being used. Some possible error codes follow. + /// + /// + /// Value + /// Description + /// + /// + /// ERROR_INVALID_HANDLE + /// One of the parameters specifies a handle that is not valid. + /// + /// + /// ERROR_INVALID_PARAMETER + /// One of the parameters contains a value that is not valid. This is most often a pointer that is not valid. + /// + /// + /// NTE_BAD_ALGID + /// The hKey session key specifies an algorithm that this CSP does not support. + /// + /// + /// NTE_BAD_DATA + /// + /// 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. + /// + /// + /// + /// NTE_BAD_FLAGS + /// The dwFlags parameter is nonzero. + /// + /// + /// NTE_BAD_HASH + /// The hHash parameter contains a handle that is not valid. + /// + /// + /// NTE_BAD_HASH_STATE + /// An attempt was made to add data to a hash object that is already marked "finished." + /// + /// + /// NTE_BAD_KEY + /// The hKey parameter does not contain a valid handle to a key. + /// + /// + /// NTE_BAD_LEN + /// The size of the output buffer is too small to hold the generated ciphertext. + /// + /// + /// NTE_BAD_UID + /// The CSP context that was specified when the key was created cannot be found. + /// + /// + /// NTE_DOUBLE_ENCRYPT + /// The application attempted to encrypt the same data twice. + /// + /// + /// NTE_FAIL + /// The function failed in some unexpected way. + /// + /// + /// NTE_NO_MEMORY + /// The CSP ran out of memory during the operation. + /// + /// + /// + /// + /// + /// If a large amount of data is to be encrypted, it can be done in sections by calling CryptEncrypt repeatedly. The Final + /// parameter must be set to TRUE on the last call to CryptEncrypt, so that the encryption engine can properly finish + /// the encryption process. The following extra actions are performed when Final is TRUE: + /// + /// + /// + /// + /// 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. + /// + /// + /// + /// + /// If the cipher is operating in a chaining mode, the next CryptEncrypt operation resets the cipher's feedback register to + /// the KP_IV value of the key. + /// + /// + /// + /// If the cipher is a stream cipher, the next CryptEncrypt resets the cipher to its initial state. + /// + /// + /// + /// 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 + /// TRUE. 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 CryptEncrypt 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. + /// + /// + /// 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 CryptEncrypt 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. + /// + /// Examples + /// For examples that use this function, see Example C Program: Encrypting a File and Example C Program: Decrypting a File. + /// + // 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); + + /// + /// + /// 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. + /// + /// + /// 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. + /// + /// + /// Important The CryptEncrypt function is not guaranteed to be thread safe and may return incorrect results if + /// invoked simultaneously by multiple callers. + /// + /// + /// + /// + /// A handle to the encryption key. An application obtains this handle by using either the CryptGenKey or the CryptImportKey function. + /// + /// The key specifies the encryption algorithm used. + /// + /// + /// + /// 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. + /// + /// + /// Before calling CryptEncrypt, 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. + /// + /// If no hash is to be done, this parameter must be NULL. + /// + /// + /// A Boolean value that specifies whether this is the last section in a series being encrypted. Final is set to TRUE for the + /// last or only block and to FALSE if there are more blocks to be encrypted. For more information, see Remarks. + /// + /// + /// The following dwFlags value is defined but reserved for future use. + /// + /// + /// Value + /// Meaning + /// + /// + /// CRYPT_OAEP + /// + /// 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. + /// + /// + /// + /// + /// + /// + /// 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. + /// + /// + /// 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. + /// + /// + /// If this parameter contains NULL, this function will calculate the required size for the ciphertext and place that in the + /// value pointed to by the pdwDataLen parameter. + /// + /// + /// + /// + /// A pointer to a DWORD value that , on entry, contains the length, in bytes, of the plaintext in the pbData buffer. On + /// exit, this DWORD contains the length, in bytes, of the ciphertext written to the pbData buffer. + /// + /// + /// If the buffer allocated for pbData is not large enough to hold the encrypted data, GetLastError returns ERROR_MORE_DATA + /// and stores the required buffer size, in bytes, in the DWORD value pointed to by pdwDataLen. + /// + /// + /// If pbData is NULL, no error is returned, and the function stores the size of the encrypted data, in bytes, in the + /// DWORD value pointed to by pdwDataLen. This allows an application to determine the correct buffer size. + /// + /// + /// 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 TRUE. + /// + /// + /// + /// Specifies the total size, in bytes, of the input pbData buffer. + /// + /// 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. + /// + /// + /// 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. + /// + /// + /// + /// If the function succeeds, the function returns nonzero ( TRUE). + /// If the function fails, it returns zero ( FALSE). For extended error information, call GetLastError. + /// The error codes prefaced by NTE are generated by the particular CSP being used. Some possible error codes follow. + /// + /// + /// Value + /// Description + /// + /// + /// ERROR_INVALID_HANDLE + /// One of the parameters specifies a handle that is not valid. + /// + /// + /// ERROR_INVALID_PARAMETER + /// One of the parameters contains a value that is not valid. This is most often a pointer that is not valid. + /// + /// + /// NTE_BAD_ALGID + /// The hKey session key specifies an algorithm that this CSP does not support. + /// + /// + /// NTE_BAD_DATA + /// + /// 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. + /// + /// + /// + /// NTE_BAD_FLAGS + /// The dwFlags parameter is nonzero. + /// + /// + /// NTE_BAD_HASH + /// The hHash parameter contains a handle that is not valid. + /// + /// + /// NTE_BAD_HASH_STATE + /// An attempt was made to add data to a hash object that is already marked "finished." + /// + /// + /// NTE_BAD_KEY + /// The hKey parameter does not contain a valid handle to a key. + /// + /// + /// NTE_BAD_LEN + /// The size of the output buffer is too small to hold the generated ciphertext. + /// + /// + /// NTE_BAD_UID + /// The CSP context that was specified when the key was created cannot be found. + /// + /// + /// NTE_DOUBLE_ENCRYPT + /// The application attempted to encrypt the same data twice. + /// + /// + /// NTE_FAIL + /// The function failed in some unexpected way. + /// + /// + /// NTE_NO_MEMORY + /// The CSP ran out of memory during the operation. + /// + /// + /// + /// + /// + /// If a large amount of data is to be encrypted, it can be done in sections by calling CryptEncrypt repeatedly. The Final + /// parameter must be set to TRUE on the last call to CryptEncrypt, so that the encryption engine can properly finish + /// the encryption process. The following extra actions are performed when Final is TRUE: + /// + /// + /// + /// + /// 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. + /// + /// + /// + /// + /// If the cipher is operating in a chaining mode, the next CryptEncrypt operation resets the cipher's feedback register to + /// the KP_IV value of the key. + /// + /// + /// + /// If the cipher is a stream cipher, the next CryptEncrypt resets the cipher to its initial state. + /// + /// + /// + /// 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 + /// TRUE. 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 CryptEncrypt 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. + /// + /// + /// 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 CryptEncrypt 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. + /// + /// Examples + /// For examples that use this function, see Example C Program: Encrypting a File and Example C Program: Decrypting a File. + /// + // 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); + + /// + /// 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. + /// + /// Possible CSPs include Microsoft Base Cryptographic Provider version 1.0 and Microsoft Enhanced Cryptographic Provider version 1.0. + /// + /// + /// Index of the next provider to be enumerated. + /// Reserved for future use and must be NULL. + /// Reserved for future use and must be zero. + /// Address of the DWORD value designating the type of the enumerated provider. + /// + /// + /// A pointer to a buffer that receives the data from the enumerated provider. This is a string including the terminating null character. + /// + /// + /// This parameter can be NULL to set the size of the name for memory allocation purposes. For more information, see + /// Retrieving Data of Unknown Length. + /// + /// + /// + /// + /// A pointer to a DWORD value specifying the size, in bytes, of the buffer pointed to by the pszProvName parameter. When the + /// function returns, the DWORD value contains the number of bytes stored in the buffer. + /// + /// + /// Note When processing the data returned in the buffer, applications must use the actual size of the data returned. The + /// actual size can be slightly smaller than the size of the buffer specified on input. (On input, buffer sizes are usually + /// specified large enough to ensure that the largest possible output data 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 the function succeeds, the return value is nonzero ( TRUE). + /// If the function fails, the return value is zero ( FALSE). For extended error information, call GetLastError. + /// The error codes prefaced by NTE are generated by the particular CSP being used. Some possible error codes follow. + /// + /// + /// Return code + /// Description + /// + /// + /// ERROR_MORE_DATA + /// The pszProvName buffer was not large enough to hold the provider name. + /// + /// + /// ERROR_NO_MORE_ITEMS + /// There are no more items to enumerate. + /// + /// + /// ERROR_NOT_ENOUGH_MEMORY + /// The operating system ran out of memory. + /// + /// + /// NTE_BAD_FLAGS + /// The dwFlags parameter has an unrecognized value. + /// + /// + /// NTE_FAIL + /// Something was wrong with the type registration. + /// + /// + /// + /// + /// This function enumerates the providers available on a computer. The provider types can be enumerated by using CryptEnumProviderTypes. + /// Examples + /// + /// The following example shows a loop listing all available cryptographic service providers. For another example that uses the + /// CryptEnumProviders function, see Example C Program: Enumerating CSP Providers and Provider Types. + /// + /// + // 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); + + /// + /// 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. + /// + /// Possible CSPs include Microsoft Base Cryptographic Provider version 1.0 and Microsoft Enhanced Cryptographic Provider version 1.0. + /// + /// + /// A sequence of tuples with a provider name and type. + [PInvokeData("wincrypt.h", MSDNShortId = "2d93ef0f-b48f-481b-ba62-c535476fde08")] + public static IEnumerable> CryptEnumProviders() + { + 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 new Tuple(type, sb.ToString()); + ++idx; + } + else + Win32Error.ThrowLastError(); + } + } + + /// + /// 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. + /// Provider types include PROV_RSA_FULL, PROV_RSA_SCHANNEL, and PROV_DSS. + /// + /// Index of the next provider type to be enumerated. + /// Reserved for future use and must be NULL. + /// Reserved for future use and must be zero. + /// Address of the DWORD value designating the enumerated provider type. + /// + /// + /// A pointer to a buffer that receives the data from the enumerated provider type. This is a string including the terminating + /// NULL 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. + /// + /// + /// This parameter can be NULL to get the size of the name for memory allocation purposes. For more information, see + /// Retrieving Data of Unknown Length. + /// + /// + /// + /// + /// A pointer to a DWORD value specifying the size, in bytes, of the buffer pointed to by the pszTypeName parameter. When the + /// function returns, the DWORD 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. + /// + /// + /// Note When processing the data returned in the buffer, applications must use the actual size of the data returned. The + /// actual size can be slightly smaller than the size of the buffer specified on input. (On input, buffer sizes are usually + /// specified large enough to ensure that the largest possible output data 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 the function succeeds, the return value is nonzero ( TRUE). + /// If the function fails, the return value is zero ( FALSE). For extended error information, call GetLastError. + /// The error codes prefaced by NTE are generated by the particular CSP being used. Some possible error codes follow. + /// + /// + /// Return code + /// Description + /// + /// + /// ERROR_NO_MORE_ITEMS + /// There are no more items to enumerate. + /// + /// + /// ERROR_NOT_ENOUGH_MEMORY + /// The operating system ran out of memory. + /// + /// + /// NTE_BAD_FLAGS + /// The dwFlags parameter has an unrecognized value. + /// + /// + /// NTE_FAIL + /// Something was wrong with the type registration. + /// + /// + /// + /// + /// + /// This function enumerates the provider types available on a computer. Providers for any specific provider type can be enumerated + /// using CryptEnumProviders. + /// + /// Examples + /// The following example shows a loop listing all available cryptographic service provider types. + /// + /// For another example that uses the CryptEnumProviderTypes function, see Example C Program: Enumerating CSP Providers and + /// Provider Types. + /// + /// + // 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); + + /// + /// 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. + /// Provider types include PROV_RSA_FULL, PROV_RSA_SCHANNEL, and PROV_DSS. + /// + /// A sequence of tuples with a provider type name and type. + [PInvokeData("wincrypt.h", MSDNShortId = "7568c963-4d06-4af0-bd15-240402425046")] + public static IEnumerable> CryptEnumProviderTypes() + { + var idx = 0U; + uint type; + var sb = new StringBuilder(1024); + var sz = 0U; + while (CryptEnumProviderTypes(idx, default, 0, out type, null, ref sz)) + { + sb.EnsureCapacity((int)sz); + if (CryptEnumProviderTypes(idx, default, 0, out type, sb, ref sz)) + { + yield return new Tuple(type, sb.ToString()); + ++idx; + } + else + Win32Error.ThrowLastError(); + } + } + + /// + /// + /// The CryptExportKey function exports a cryptographic key or a key pair from a cryptographic service provider (CSP) in a secure manner. + /// + /// + /// 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. + /// + /// + /// A handle to the key to be exported. + /// + /// + /// 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 hExpKey and hKey must come from the same CSP. + /// + /// + /// 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. + /// + /// If the key BLOB type specified by dwBlobType is PUBLICKEYBLOB, this parameter is unused and must be set to zero. + /// + /// If the key BLOB type specified by dwBlobType is PRIVATEKEYBLOB, 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. + /// + /// + /// To determine how Microsoft cryptographic service providers respond to this parameter, see the private key BLOB sections of + /// Microsoft Cryptographic Service Providers. + /// + /// + /// Note 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. + /// + /// + /// + /// + /// Specifies the type of key BLOB to be exported in pbData. This must be one of the following constants as discussed in + /// Cryptographic Key Storage and Exchange. + /// + /// + /// + /// Value + /// Meaning + /// + /// + /// OPAQUEKEYBLOB + /// + /// 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. + /// + /// + /// + /// PRIVATEKEYBLOB + /// Used to transport public/private key pairs. + /// + /// + /// PUBLICKEYBLOB + /// Used to transport public keys. + /// + /// + /// SIMPLEBLOB + /// Used to transport session keys. + /// + /// + /// PLAINTEXTKEYBLOB + /// A PLAINTEXTKEYBLOB used to export any key supported by the CSP in use. + /// + /// + /// SYMMETRICWRAPKEYBLOB + /// + /// 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. + /// + /// + /// + /// + /// + /// + /// Specifies additional options for the function. This parameter can be zero or a combination of one or more of the following values. + /// + /// + /// + /// Value + /// Meaning + /// + /// + /// CRYPT_BLOB_VER3 0x00000080 + /// This flag causes this function to export version 3 of a BLOB type. + /// + /// + /// CRYPT_DESTROYKEY 0x00000004 + /// This flag destroys the original key in the OPAQUEKEYBLOB. This flag is available in Schannel CSPs only. + /// + /// + /// CRYPT_OAEP 0x00000040 + /// This flag causes PKCS #1 version 2 formatting to be created with the RSA encryption and decryption when exporting SIMPLEBLOBs. + /// + /// + /// CRYPT_SSL2_FALLBACK 0x00000002 + /// + /// 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. + /// + /// + /// + /// CRYPT_Y_ONLY 0x00000001 + /// This flag is not used. + /// + /// + /// + /// + /// + /// 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 dwBlobType parameter. For the format for PRIVATEKEYBLOBs, PUBLICKEYBLOBs, and SIMPLEBLOBs, see Base Provider Key BLOBs. + /// + /// + /// If this parameter is NULL, the required buffer size is placed in the value pointed to by the pdwDataLen parameter. For + /// more information, see Retrieving Data of Unknown Length. + /// + /// + /// + /// + /// A pointer to a DWORD value that, on entry, contains the size, in bytes, of the buffer pointed to by the pbData parameter. + /// When the function returns, this value contains the number of bytes stored in the buffer. + /// + /// + /// Note When processing the data returned in the buffer, applications must use the actual size of the data returned. The + /// actual size can be slightly smaller than the size of the buffer specified on input. On input, buffer sizes are usually specified + /// large enough to ensure that the largest possible output data 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. + /// + /// To retrieve the required size of the + /// pbData + /// buffer, pass + /// NULL + /// for + /// pbData + /// . The required buffer size will be placed in the value pointed to by this parameter. + /// + /// + /// If the function succeeds, the function returns nonzero ( TRUE). + /// If the function fails, it returns zero ( FALSE). For extended error information, call GetLastError. + /// + /// The error codes prefaced by "NTE" are generated by the particular CSP being used. The following table shows some of the possible + /// error codes. + /// + /// + /// + /// Return code + /// Description + /// + /// + /// ERROR_INVALID_HANDLE + /// One of the parameters specifies a handle that is not valid. + /// + /// + /// ERROR_INVALID_PARAMETER + /// One of the parameters contains a value that is not valid. This is most often a pointer that is not valid. + /// + /// + /// ERROR_MORE_DATA + /// + /// 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. + /// + /// + /// + /// NTE_BAD_DATA + /// + /// 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. + /// + /// + /// + /// NTE_BAD_FLAGS + /// The dwFlags parameter is nonzero. + /// + /// + /// NTE_BAD_KEY + /// One or both of the keys specified by hKey and hExpKey are not valid. + /// + /// + /// NTE_BAD_KEY_STATE + /// + /// You do not have permission to export the key. That is, when the hKey key was created, the CRYPT_EXPORTABLE flag was not specified. + /// + /// + /// + /// NTE_BAD_PUBLIC_KEY + /// The key BLOB type specified by dwBlobType is PUBLICKEYBLOB, but hExpKey does not contain a public key handle. + /// + /// + /// NTE_BAD_TYPE + /// The dwBlobType parameter specifies an unknown BLOB type. + /// + /// + /// NTE_BAD_UID + /// The CSP context that was specified when the hKey key was created cannot be found. + /// + /// + /// NTE_NO_KEY + /// A session key is being exported, and the hExpKey parameter does not specify a public key. + /// + /// + /// + /// + /// + /// 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. + /// + /// + /// + /// Algorithm + /// Supported key size + /// + /// + /// CALG_DES + /// 64 bits + /// + /// + /// CALG_3DES_112 + /// 128 bits + /// + /// + /// CALG_3DES + /// 192 bits + /// + /// + /// Examples + /// + /// 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. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptexportkey BOOL CryptExportKey( HCRYPTKEY hKey, + // HCRYPTKEY hExpKey, DWORD dwBlobType, DWORD dwFlags, BYTE *pbData, DWORD *pdwDataLen ); + [DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)] + [PInvokeData("wincrypt.h", MSDNShortId = "8a7c7b46-3bea-4043-b568-6d91d6335737")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool CryptExportKey(HCRYPTKEY hKey, HCRYPTKEY hExpKey, [MarshalAs(UnmanagedType.U4)] BlobType dwBlobType, CryptExportKeyFlags dwFlags, [Out, Optional] IntPtr pbData, ref uint pdwDataLen); + + /// + /// + /// 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. + /// + /// + /// 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. + /// + /// + /// A handle to a cryptographic service provider (CSP) created by a call to CryptAcquireContext. + /// + /// + /// 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. + /// + /// For ALG_ID values to use with the Microsoft Base Cryptographic Provider, see Base Provider Algorithms. + /// + /// For ALG_ID values to use with the Microsoft Strong Cryptographic Provider or the Microsoft Enhanced Cryptographic + /// Provider, see Enhanced Provider Algorithms. + /// + /// For a Diffie-Hellman CSP, use one of the following values. + /// + /// + /// Value + /// Meaning + /// + /// + /// CALG_DH_EPHEM + /// Specifies an "Ephemeral" Diffie-Hellman key. + /// + /// + /// CALG_DH_SF + /// Specifies a "Store and Forward" Diffie-Hellman key. + /// + /// + /// + /// 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. + /// + /// + /// + /// Value + /// Meaning + /// + /// + /// AT_KEYEXCHANGE + /// Key exchange + /// + /// + /// AT_SIGNATURE + /// Digital signature + /// + /// + /// + /// Note 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. + /// + /// + /// + /// + /// 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- OR operation. The upper 16 bits of 0x08000000 is 0x0800, or decimal 2,048. The + /// RSA1024BIT_KEY value can be used to specify a 1024-bit RSA key. + /// + /// + /// 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. + /// + /// + /// 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. + /// + /// + /// 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. + /// + /// The following table lists minimum, default, and maximum signature and exchange key lengths beginning with Windows XP. + /// + /// + /// Key type and provider + /// Minimum length + /// Default length + /// Maximum length + /// + /// + /// RSA Base Provider Signature and ExchangeKeys + /// 384 + /// 512 + /// 16,384 + /// + /// + /// RSA Strong and Enhanced Providers Signature and Exchange Keys + /// 384 + /// 1,024 + /// 16,384 + /// + /// + /// DSS Base Providers Signature Keys + /// 512 + /// 1,024 + /// 1,024 + /// + /// + /// DSS Base Providers Exchange Keys + /// Not applicable + /// Not applicable + /// Not applicable + /// + /// + /// DSS/DH Base Providers Signature Keys + /// 512 + /// 1,024 + /// 1,024 + /// + /// + /// DSS/DH Base Providers Exchange Keys + /// 512 + /// 512 + /// 1,024 + /// + /// + /// DSS/DH Enhanced Providers Signature Keys + /// 512 + /// 1,024 + /// 1,024 + /// + /// + /// DSS/DH Enhanced Providers Exchange Keys + /// 512 + /// 1,024 + /// 4,096 + /// + /// + /// For session key lengths, see CryptDeriveKey. + /// For more information about keys generated using Microsoft providers, see Microsoft Cryptographic Service Providers. + /// The lower 16-bits of this parameter can be zero or a combination of one or more of the following values. + /// + /// + /// Value + /// Meaning + /// + /// + /// CRYPT_ARCHIVABLE + /// + /// 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. + /// + /// + /// + /// CRYPT_CREATE_IV + /// This flag is not used. + /// + /// + /// CRYPT_CREATE_SALT + /// + /// 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. + /// + /// + /// + /// CRYPT_DATA_KEY + /// This flag is not used. + /// + /// + /// CRYPT_EXPORTABLE + /// + /// 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. + /// + /// + /// + /// CRYPT_FORCE_KEY_PROTECTION_HIGH + /// + /// 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. + /// + /// + /// + /// CRYPT_KEK + /// This flag is not used. + /// + /// + /// CRYPT_INITIATOR + /// This flag is not used. + /// + /// + /// CRYPT_NO_SALT + /// + /// This flag specifies that a no salt value gets allocated for a forty-bit symmetric key. For more information, see Salt Value Functionality. + /// + /// + /// + /// CRYPT_ONLINE + /// This flag is not used. + /// + /// + /// CRYPT_PREGEN + /// + /// 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. + /// + /// + /// + /// CRYPT_RECIPIENT + /// This flag is not used. + /// + /// + /// CRYPT_SF + /// This flag is not used. + /// + /// + /// CRYPT_SGCKEY + /// This flag is not used. + /// + /// + /// CRYPT_USER_PROTECTED + /// + /// 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. + /// + /// + /// + /// CRYPT_VOLATILE + /// This flag is not used. + /// + /// + /// + /// + /// 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. + /// + /// + /// Returns nonzero if successful or zero otherwise. + /// For extended error information, call GetLastError. + /// + /// The error codes prefaced by "NTE" are generated by the particular CSP being used. Some possible error codes are listed in the + /// following table. + /// + /// + /// + /// Return code + /// Description + /// + /// + /// ERROR_INVALID_HANDLE + /// One of the parameters specifies a handle that is not valid. + /// + /// + /// ERROR_INVALID_PARAMETER + /// One of the parameters contains a value that is not valid. This is most often a pointer that is not valid. + /// + /// + /// NTE_BAD_ALGID + /// The Algid parameter specifies an algorithm that this CSP does not support. + /// + /// + /// NTE_BAD_FLAGS + /// The dwFlags parameter contains a value that is not valid. + /// + /// + /// NTE_BAD_UID + /// The hProv parameter does not contain a valid context handle. + /// + /// + /// NTE_FAIL + /// The function failed in some unexpected way. + /// + /// + /// NTE_SILENT_CONTEXT + /// The provider could not perform the action because the context was acquired as silent. + /// + /// + /// + /// + /// + /// 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. + /// + /// To choose an appropriate key length, the following methods are recommended: + /// + /// + /// + /// 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. + /// + /// + /// + /// + /// 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. + /// + /// + /// + /// After the desired key length has been chosen, use the upper 16 bits of the dwFlags parameter to specify the key length. + /// + /// + /// Examples + /// + /// 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. + /// + /// + // 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); + + /// The CryptGenRandom function fills a buffer with cryptographically random bytes. + /// Handle of a cryptographic service provider (CSP) created by a call to CryptAcquireContext. + /// Number of bytes of random data to be generated. + /// + /// Buffer to receive the returned data. This buffer must be at least dwLen bytes in length. + /// Optionally, the application can fill this buffer with data to use as an auxiliary random seed. + /// + /// + /// If the function succeeds, the return value is nonzero (TRUE). + /// If the function fails, the return value is zero (FALSE). For extended error information, call GetLastError. + /// + /// The error codes prefaced by "NTE" are generated by the particular CSP being used. Some possible error codes are listed in the + /// following table. + /// + /// + /// + /// Return code + /// Description + /// + /// + /// ERROR_INVALID_HANDLE + /// One of the parameters specifies a handle that is not valid. + /// + /// + /// ERROR_INVALID_PARAMETER + /// One of the parameters contains a value that is not valid. This is most often a pointer that is not valid. + /// + /// + /// NTE_BAD_UID + /// The hProv parameter does not contain a valid context handle. + /// + /// + /// NTE_FAIL + /// The function failed in some unexpected way. + /// + /// + /// + /// + /// + /// 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. + /// + /// This function is often used to generate random initialization vectors and salt values. + /// + /// 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. + /// + /// + /// With Microsoft CSPs, CryptGenRandom 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 CryptGenRandom. 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 CryptGenRandom. + /// + /// Examples + /// + /// 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. + /// + /// + // 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); + + /// + /// 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. + /// + /// + /// The provider type for which the default CSP name is to be found. + /// Defined provider types are as follows: + /// + /// + /// PROV_RSA_FULL + /// + /// + /// PROV_RSA_SIG + /// + /// + /// PROV_DSS + /// + /// + /// PROV_DSS_DH + /// + /// + /// PROV_DH_SCHANNEL + /// + /// + /// PROV_FORTEZZA + /// + /// + /// PROV_MS_EXCHANGE + /// + /// + /// PROV_RSA_SCHANNEL + /// + /// + /// PROV_SSL + /// + /// + /// + /// This parameter is reserved for future use and must be NULL. + /// + /// The following flag values are defined. + /// + /// + /// Value + /// Meaning + /// + /// + /// CRYPT_USER_DEFAULT 0x00000002 + /// Returns the user-context default CSP of the specified type. + /// + /// + /// CRYPT_MACHINE_DEFAULT 0x00000001 + /// Returns the computer default CSP of the specified type. + /// + /// + /// + /// + /// A pointer to a null-terminated character string buffer to receive the name of the default CSP. + /// + /// To find the size of the buffer for memory allocation purposes, this parameter can be NULL. For more information, see + /// Retrieving Data of Unknown Length. + /// + /// + /// + /// + /// A pointer to a DWORD value that specifies the size, in bytes, of the buffer pointed to by the pszProvName parameter. When + /// the function returns, the DWORD value contains the number of bytes stored or to be stored in the buffer. + /// + /// + /// Note When processing the data returned in the buffer, applications must use the actual size of the data returned. The + /// actual size can be slightly smaller than the size of the buffer specified on input. (On input, buffer sizes are usually + /// specified large enough to ensure that the largest possible output data 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 the function succeeds, the return value is nonzero ( TRUE). + /// If the function fails, the return value is zero ( FALSE). For extended error information, call GetLastError. + /// The error code prefaced by NTE is generated by the particular CSP being used. Possible error codes include the following. + /// + /// + /// Return code + /// Description + /// + /// + /// ERROR_INVALID_PARAMETER + /// One of the parameters contains a value that is not valid. This is most often a pointer that is not valid. + /// + /// + /// ERROR_MORE_DATA + /// The buffer for the name is not large enough. + /// + /// + /// ERROR_NOT_ENOUGH_MEMORY + /// The operating system ran out of memory. + /// + /// + /// NTE_BAD_FLAGS + /// The dwFlags parameter has an unrecognized value. + /// + /// + /// + /// + /// + /// 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. + /// + /// Examples + /// + /// 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. + /// + /// + // 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); + + /// + /// The CryptGetHashParam function retrieves data that governs the operations of a hash object. The actual hash value can be + /// retrieved by using this function. + /// + /// Handle of the hash object to be queried. + /// + /// Query type. This parameter can be set to one of the following queries. + /// + /// + /// Value + /// Meaning + /// + /// + /// HP_ALGID Hash algorithm + /// + /// An ALG_ID that indicates the algorithm specified when the hash object was created. For a list of hash algorithms, see CryptCreateHash. + /// + /// + /// + /// HP_HASHSIZE Hash value size + /// + /// 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. + /// + /// + /// + /// HP_HASHVAL Hash value + /// + /// 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. + /// + /// + /// + /// Note CSPs can add more values that this function can query. + /// + /// + /// A pointer to a buffer that receives the specified value data. The form of this data varies, depending on the value number. + /// This parameter can be NULL to determine the memory size required. + /// + /// + /// + /// A pointer to a DWORD value specifying the size, in bytes, of the pbData buffer. When the function returns, the + /// DWORD value contains the number of bytes stored in the buffer. + /// + /// If pbData is NULL, set the value of pdwDataLen to zero. + /// + /// Note When processing the data returned in the buffer, applications must use the actual size of the data returned. The + /// actual size can be slightly smaller than the size of the buffer specified on input. (On input, buffer sizes are usually + /// specified large enough to ensure that the largest possible output data 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. + /// + /// + /// Reserved for future use and must be zero. + /// + /// If the function succeeds, the return value is TRUE. + /// If the function fails, the return value is FALSE. For extended error information, call GetLastError. + /// The error codes prefaced by "NTE" are generated by the particular CSP you are using. Some possible error codes follow. + /// + /// + /// Return code + /// Description + /// + /// + /// ERROR_INVALID_HANDLE + /// One of the parameters specifies a handle that is not valid. + /// + /// + /// ERROR_INVALID_PARAMETER + /// One of the parameters contains a value that is not valid. This is most often a pointer that is not valid. + /// + /// + /// ERROR_MORE_DATA + /// + /// 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. + /// + /// + /// + /// NTE_BAD_FLAGS + /// The dwFlags parameter is nonzero. + /// + /// + /// NTE_BAD_HASH + /// The hash object specified by the hHash parameter is not valid. + /// + /// + /// NTE_BAD_TYPE + /// The dwParam parameter specifies an unknown value number. + /// + /// + /// NTE_BAD_UID + /// The CSP context that was specified when the hash was created cannot be found. + /// + /// + /// + // 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); + + /// + /// The CryptGetHashParam function retrieves data that governs the operations of a hash object. The actual hash value can be + /// retrieved by using this function. + /// + /// The expected return type. + /// Handle of the hash object to be queried. + /// + /// Query type. This parameter can be set to one of the following queries. + /// + /// + /// Value + /// Meaning + /// + /// + /// HP_ALGID Hash algorithm + /// + /// An ALG_ID that indicates the algorithm specified when the hash object was created. For a list of hash algorithms, see CryptCreateHash. + /// + /// + /// + /// HP_HASHSIZE Hash value size + /// + /// 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. + /// + /// + /// + /// HP_HASHVAL Hash value + /// + /// 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. + /// + /// + /// + /// Note CSPs can add more values that this function can query. + /// + /// The specified value data. The form of this data varies, depending on the value number. + public static T CryptGetHashParam(HCRYPTHASH hHash, HashParam dwParam) => CryptGetValue(CryptGetHashParam, hHash, dwParam); + + /// + /// 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. + /// + /// The handle of the key being queried. + /// + /// Specifies the type of query being made. + /// For all key types, this parameter can contain one of the following values. + /// + /// + /// Value + /// Meaning + /// + /// + /// KP_ALGID + /// + /// 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. + /// + /// + /// + /// KP_BLOCKLEN + /// + /// 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. + /// + /// + /// + /// KP_CERTIFICATE + /// + /// 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. + /// + /// + /// + /// KP_GET_USE_COUNT + /// This value is not used. + /// + /// + /// KP_KEYLEN + /// + /// 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. + /// + /// + /// + /// KP_SALT + /// + /// 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. + /// + /// + /// + /// KP_PERMISSIONS + /// + /// 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. + /// + /// + /// + /// + /// 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. + /// + /// + /// + /// Value + /// Meaning + /// + /// + /// KP_P + /// + /// 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. + /// + /// + /// + /// KP_Q + /// + /// 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. + /// + /// + /// + /// KP_G + /// + /// 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. + /// + /// + /// + /// + /// 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. + /// + /// + /// + /// Value + /// Meaning + /// + /// + /// KP_EFFECTIVE_KEYLEN + /// + /// 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. + /// + /// + /// + /// KP_IV + /// + /// 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. + /// + /// + /// + /// KP_PADDING + /// + /// 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. + /// + /// + /// + /// KP_MODE + /// + /// 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. + /// + /// + /// + /// KP_MODE_BITS + /// + /// 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. + /// + /// + /// + /// + /// 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. + /// + /// + /// + /// Value + /// Meaning + /// + /// + /// KP_VERIFY_PARAMS + /// + /// 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. + /// + /// + /// + /// KP_KEYVAL + /// + /// 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. + /// + /// + /// + /// If a certificate is specified by hKey, the dwParam value can also be set to the following value. + /// + /// + /// Value + /// Meaning + /// + /// + /// KP_CERTIFICATE + /// + /// 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. + /// + /// + /// + /// + /// + /// A pointer to a buffer that receives the data. The form of this data depends on the value of dwParam. + /// + /// If the size of this buffer is not known, the required size can be retrieved at run time by passing NULL 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. + /// + /// + /// + /// + /// A pointer to a DWORD value that, on entry, contains the size, in bytes, of the buffer pointed to by the pbData parameter. + /// When the function returns, the DWORD value contains the number of bytes stored in the buffer. + /// + /// + /// Note 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. + /// + /// + /// This parameter is reserved for future use and must be set to zero. + /// + /// If the function succeeds, the function returns nonzero. + /// If the function fails, it returns zero. For extended error information, call GetLastError. + /// + /// The error codes prefaced by "NTE" are generated by the particular CSP being used. Some possible error codes include the following. + /// + /// + /// + /// Return code + /// Description + /// + /// + /// ERROR_INVALID_HANDLE + /// One of the parameters specifies a handle that is not valid. + /// + /// + /// ERROR_INVALID_PARAMETER + /// One of the parameters contains a value that is not valid. This is most often a pointer that is not valid. + /// + /// + /// ERROR_MORE_DATA + /// + /// 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. + /// + /// + /// + /// NTE_BAD_FLAGS + /// The dwFlags parameter is nonzero. + /// + /// + /// NTE_BAD_KEY or NTE_NO_KEY + /// The key specified by the hKey parameter is not valid. + /// + /// + /// NTE_BAD_TYPE + /// The dwParam parameter specifies an unknown value number. + /// + /// + /// NTE_BAD_UID + /// The CSP context that was specified when the key was created cannot be found. + /// + /// + /// + // 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); + + /// + /// 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. + /// + /// The expected return type. + /// The handle of the key being queried. + /// + /// Specifies the type of query being made. + /// For all key types, this parameter can contain one of the following values. + /// + /// + /// Value + /// Meaning + /// + /// + /// KP_ALGID + /// + /// 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. + /// + /// + /// + /// KP_BLOCKLEN + /// + /// 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. + /// + /// + /// + /// KP_CERTIFICATE + /// + /// 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. + /// + /// + /// + /// KP_GET_USE_COUNT + /// This value is not used. + /// + /// + /// KP_KEYLEN + /// + /// 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. + /// + /// + /// + /// KP_SALT + /// + /// 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. + /// + /// + /// + /// KP_PERMISSIONS + /// + /// 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. + /// + /// + /// + /// + /// 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. + /// + /// + /// + /// Value + /// Meaning + /// + /// + /// KP_P + /// + /// 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. + /// + /// + /// + /// KP_Q + /// + /// 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. + /// + /// + /// + /// KP_G + /// + /// 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. + /// + /// + /// + /// + /// 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. + /// + /// + /// + /// Value + /// Meaning + /// + /// + /// KP_EFFECTIVE_KEYLEN + /// + /// 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. + /// + /// + /// + /// KP_IV + /// + /// 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. + /// + /// + /// + /// KP_PADDING + /// + /// 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. + /// + /// + /// + /// KP_MODE + /// + /// 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. + /// + /// + /// + /// KP_MODE_BITS + /// + /// 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. + /// + /// + /// + /// + /// 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. + /// + /// + /// + /// Value + /// Meaning + /// + /// + /// KP_VERIFY_PARAMS + /// + /// 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. + /// + /// + /// + /// KP_KEYVAL + /// + /// 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. + /// + /// + /// + /// If a certificate is specified by hKey, the dwParam value can also be set to the following value. + /// + /// + /// Value + /// Meaning + /// + /// + /// KP_CERTIFICATE + /// + /// 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. + /// + /// + /// + /// + /// The specified value data. The form of this data varies, depending on the value number. + public static T CryptGetKeyParam(HCRYPTKEY hKey, KeyParam dwParam) => CryptGetValue(CryptGetKeyParam, hKey, dwParam); + + /// + /// The CryptGetProvParam function retrieves parameters that govern the operations of a cryptographic service provider (CSP). + /// + /// + /// A handle of the CSP target of the query. This handle must have been created by using the CryptAcquireContext function. + /// + /// + /// The nature of the query. The following queries are defined. + /// + /// + /// Value + /// Meaning + /// + /// + /// PP_ADMIN_PIN 31 (0x1F) + /// Returns the administrator personal identification number (PIN) in the pbData parameter as a LPSTR. + /// + /// + /// PP_APPLI_CERT 18 (0x12) + /// This constant is not used. + /// + /// + /// PP_CHANGE_PASSWORD 7 (0x7) + /// This constant is not used. + /// + /// + /// PP_CERTCHAIN 9 (0x9) + /// Returns the certificate chain associated with the hProv handle. The returned certificate chain is X509_ASN_ENCODING encoded. + /// + /// + /// PP_CONTAINER 6 (0x6) + /// + /// 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. + /// + /// + /// + /// PP_CRYPT_COUNT_KEY_USE 41 (0x29) + /// Not implemented by Microsoft CSPs. This behavior may be implemented by other CSPs. Windows XP: This parameter is not supported. + /// + /// + /// PP_ENUMALGS 1 (0x1) + /// + /// 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. + /// + /// + /// + /// PP_ENUMALGS_EX 22 (0x16) + /// + /// 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. + /// + /// + /// + /// PP_ENUMCONTAINERS 2 (0x2) + /// + /// 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. + /// + /// + /// + /// PP_ENUMELECTROOTS 26 (0x1A) + /// This constant is not used. + /// + /// + /// PP_ENUMEX_SIGNING_PROT 40 (0x28) + /// + /// 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. + /// + /// + /// + /// PP_ENUMMANDROOTS 25 (0x19) + /// This constant is not used. + /// + /// + /// PP_IMPTYPE 3 (0x3) + /// A DWORD value that indicates how the CSP is implemented. For a table of possible values, see Remarks. + /// + /// + /// PP_KEY_TYPE_SUBTYPE 10 (0xA) + /// This query is not used. + /// + /// + /// PP_KEYEXCHANGE_PIN 32 (0x20) + /// Specifies that the key exchange PIN is contained in pbData. The PIN is represented as a null-terminated ASCII string. + /// + /// + /// PP_KEYSET_SEC_DESCR 8 (0x8) + /// + /// 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. + /// + /// + /// + /// PP_KEYSET_TYPE 27 (0x1B) + /// + /// 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. + /// + /// + /// + /// PP_KEYSPEC 39 (0x27) + /// + /// 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. + /// + /// + /// + /// PP_KEYSTORAGE 17 (0x11) + /// Returns a DWORD value of CRYPT_SEC_DESCR. + /// + /// + /// PP_KEYX_KEYSIZE_INC 35 (0x23) + /// + /// 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. + /// + /// + /// + /// PP_NAME 4 (0x4) + /// + /// 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. + /// + /// + /// + /// PP_PROVTYPE 16 (0x10) + /// A DWORD value that indicates the provider type of the CSP. + /// + /// + /// PP_ROOT_CERTSTORE 46 (0x2E) + /// + /// 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. + /// + /// + /// + /// PP_SESSION_KEYSIZE 20 (0x14) + /// The size, in bits, of the session key. + /// + /// + /// PP_SGC_INFO 37 (0x25) + /// Used with server gated cryptography. + /// + /// + /// PP_SIG_KEYSIZE_INC 34 (0x22) + /// + /// 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. + /// + /// + /// + /// PP_SIGNATURE_PIN 33 (0x21) + /// Specifies that the key signature PIN is contained in pbData. The PIN is represented as a null-terminated ASCII string. + /// + /// + /// PP_SMARTCARD_GUID 45 (0x2D) + /// + /// 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. + /// + /// + /// + /// PP_SMARTCARD_READER 43 (0x2B) + /// + /// 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. + /// + /// + /// + /// PP_SYM_KEYSIZE 19 (0x13) + /// The size of the symmetric key. + /// + /// + /// PP_UI_PROMPT 21 (0x15) + /// This query is not used. + /// + /// + /// PP_UNIQUE_CONTAINER 36 (0x24) + /// + /// 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. + /// + /// + /// + /// PP_USE_HARDWARE_RNG 38 (0x26) + /// + /// 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. + /// + /// + /// + /// PP_USER_CERTSTORE 42 (0x2A) + /// + /// 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. + /// + /// + /// + /// PP_VERSION 5 (0x5) + /// + /// 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. + /// + /// + /// + /// + /// + /// + /// 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 NULL. + /// + /// + /// This parameter can be NULL to set the size of this information for memory allocation purposes. For more information, see + /// Retrieving Data of Unknown Length. + /// + /// + /// + /// + /// A pointer to a DWORD value that specifies the size, in bytes, of the buffer pointed to by the pbData parameter. When the + /// function returns, the DWORD value contains the number of bytes stored or to be stored in the buffer. + /// + /// + /// Note When processing the data returned in the buffer, applications must use the actual size of the data returned. The + /// actual size can be slightly smaller than the size of the buffer specified on input. (On input, buffer sizes are usually + /// specified large enough to ensure that the largest possible output data 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 NULL 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 null-terminated string + /// programmatically, if desired. If one of the enumeration values is read and the pbData parameter is NULL, the CRYPT_FIRST + /// flag must be specified for the size information to be correctly retrieved. + /// + /// + /// + /// + /// If dwParam is PP_KEYSET_SEC_DESCR, the security descriptor on the key container where the keys are stored is retrieved. + /// For this case, dwFlags is used to pass in the SECURITY_INFORMATION bit flags that indicate the requested security + /// information, as defined in the Platform SDK. SECURITY_INFORMATION bit flags can be combined with a bitwise- OR operation. + /// + /// The following values are defined for use with PP_KEYSET_SEC_DESCR. + /// + /// + /// Value + /// Meaning + /// + /// + /// OWNER_SECURITY_INFORMATION + /// Owner identifier of the object is being referenced. + /// + /// + /// GROUP_SECURITY_INFORMATION + /// Primary group identifier of the object is being referenced. + /// + /// + /// DACL_SECURITY_INFORMATION + /// Discretionary ACL of the object is being referenced. + /// + /// + /// SACL_SECURITY_INFORMATION + /// System ACL of the object is being referenced. + /// + /// + /// The following values are defined for use with PP_ENUMALGS, PP_ENUMALGS_EX, and PP_ENUMCONTAINERS. + /// + /// + /// Value + /// Meaning + /// + /// + /// CRYPT_FIRST 1 (0x1) + /// Retrieve the first element in the enumeration. This has the same effect as resetting the enumerator. + /// + /// + /// CRYPT_NEXT 2 (0x2) + /// + /// 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. + /// + /// + /// + /// CRYPT_SGC_ENUM 4 (0x4) + /// + /// Retrieve server-gated cryptography (SGC) enabled certificates. SGC enabled certificates are no longer supported. For more + /// information, see Microsoft Support Article 875450. + /// + /// + /// + /// CRYPT_SGC + /// This flag is not used. + /// + /// + /// CRYPT_FASTSGC + /// This flag is not used. + /// + /// + /// + /// + /// If the function succeeds, the return value is nonzero ( TRUE). + /// If the function fails, the return value is zero ( FALSE). For extended error information, call GetLastError. + /// The error codes prefaced by NTE are generated by the particular CSP being used. Some possible error codes follow. + /// + /// + /// Return code + /// Description + /// + /// + /// ERROR_INVALID_HANDLE + /// One of the parameters specifies a handle that is not valid. + /// + /// + /// ERROR_INVALID_PARAMETER + /// One of the parameters contains a value that is not valid. This is most often a pointer that is not valid. + /// + /// + /// ERROR_MORE_DATA + /// + /// 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. + /// + /// + /// + /// ERROR_NO_MORE_ITEMS + /// + /// 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. + /// + /// + /// + /// NTE_BAD_FLAGS + /// The dwFlags parameter specifies a flag that is not valid. + /// + /// + /// NTE_BAD_TYPE + /// The dwParam parameter specifies an unknown value number. + /// + /// + /// NTE_BAD_UID + /// The CSP context specified by hProv is not valid. + /// + /// + /// + /// + /// This function must not be used on a thread of a multithreaded program. + /// The following values are returned in pbData if dwParam is PP_IMPTYPE. + /// + /// + /// Value + /// Meaning + /// + /// + /// CRYPT_IMPL_HARDWARE1 + /// Implementation is in hardware. + /// + /// + /// CRYPT_IMPL_SOFTWARE2 + /// Implementation is in software. + /// + /// + /// CRYPT_IMPL_MIXED3 + /// Implementation involves both hardware and software. + /// + /// + /// CRYPT_IMPL_UNKNOWN4 + /// Implementation type is unknown. + /// + /// + /// CRYPT_IMPL_REMOVABLE8 + /// Implementation is in removable media. + /// + /// + /// + /// The dwFlags parameter is used to pass in the SECURITY_INFORMATION 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. + /// + /// + /// 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 GET_ALG_CLASS( x ) macro takes an + /// algorithm identifier as an argument and returns a code indicating the general class of that algorithm. Possible return values include: + /// + /// + /// + /// ALG_CLASS_DATA_ENCRYPT + /// + /// + /// ALG_CLASS_HASH + /// + /// + /// ALG_CLASS_KEY_EXCHANGE + /// + /// + /// ALG_CLASS_SIGNATURE + /// + /// + /// + /// The following table lists the algorithms supported by the Microsoft Base Cryptographic Provider along with the class of each algorithm. + /// + /// + /// + /// Name + /// Identifier + /// Class + /// + /// + /// "MD2" + /// CALG_MD2 + /// ALG_CLASS_HASH + /// + /// + /// "MD5" + /// CALG_MD5 + /// ALG_CLASS_HASH + /// + /// + /// "SHA" + /// CALG_SHA + /// ALG_CLASS_HASH + /// + /// + /// "MAC" + /// CALG_MAC + /// ALG_CLASS_HASH + /// + /// + /// "RSA_SIGN" + /// CALG_RSA_SIGN + /// ALG_CLASS_SIGNATURE + /// + /// + /// "RSA_KEYX" + /// CALG_RSA_KEYX + /// ALG_CLASS_KEY_EXCHANGE + /// + /// + /// "RC2" + /// CALG_RC2 + /// ALG_CLASS_DATA_ENCRYPT + /// + /// + /// "RC4" + /// CALG_RC4 + /// ALG_CLASS_DATA_ENCRYPT + /// + /// + /// + /// Applications must not use an algorithm with an algorithm identifier that is not recognized. Using an unknown cryptographic + /// algorithm can produce unpredictable results. + /// + /// Examples + /// + /// 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. + /// + /// For another example that uses this function, see Example C Program: Enumerating CSP Providers and Provider Types. + /// + // 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); + + /// + /// The CryptGetProvParam function retrieves parameters that govern the operations of a cryptographic service provider (CSP). + /// + /// The expected return type. + /// + /// A handle of the CSP target of the query. This handle must have been created by using the CryptAcquireContext function. + /// + /// + /// The nature of the query. The following queries are defined. + /// + /// + /// Value + /// Meaning + /// + /// + /// PP_ADMIN_PIN 31 (0x1F) + /// Returns the administrator personal identification number (PIN) in the pbData parameter as a LPSTR. + /// + /// + /// PP_APPLI_CERT 18 (0x12) + /// This constant is not used. + /// + /// + /// PP_CHANGE_PASSWORD 7 (0x7) + /// This constant is not used. + /// + /// + /// PP_CERTCHAIN 9 (0x9) + /// Returns the certificate chain associated with the hProv handle. The returned certificate chain is X509_ASN_ENCODING encoded. + /// + /// + /// PP_CONTAINER 6 (0x6) + /// + /// 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. + /// + /// + /// + /// PP_CRYPT_COUNT_KEY_USE 41 (0x29) + /// Not implemented by Microsoft CSPs. This behavior may be implemented by other CSPs. Windows XP: This parameter is not supported. + /// + /// + /// PP_ENUMALGS 1 (0x1) + /// + /// 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. + /// + /// + /// + /// PP_ENUMALGS_EX 22 (0x16) + /// + /// 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. + /// + /// + /// + /// PP_ENUMCONTAINERS 2 (0x2) + /// + /// 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. + /// + /// + /// + /// PP_ENUMELECTROOTS 26 (0x1A) + /// This constant is not used. + /// + /// + /// PP_ENUMEX_SIGNING_PROT 40 (0x28) + /// + /// 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. + /// + /// + /// + /// PP_ENUMMANDROOTS 25 (0x19) + /// This constant is not used. + /// + /// + /// PP_IMPTYPE 3 (0x3) + /// A DWORD value that indicates how the CSP is implemented. For a table of possible values, see Remarks. + /// + /// + /// PP_KEY_TYPE_SUBTYPE 10 (0xA) + /// This query is not used. + /// + /// + /// PP_KEYEXCHANGE_PIN 32 (0x20) + /// Specifies that the key exchange PIN is contained in pbData. The PIN is represented as a null-terminated ASCII string. + /// + /// + /// PP_KEYSET_SEC_DESCR 8 (0x8) + /// + /// 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. + /// + /// + /// + /// PP_KEYSET_TYPE 27 (0x1B) + /// + /// 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. + /// + /// + /// + /// PP_KEYSPEC 39 (0x27) + /// + /// 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. + /// + /// + /// + /// PP_KEYSTORAGE 17 (0x11) + /// Returns a DWORD value of CRYPT_SEC_DESCR. + /// + /// + /// PP_KEYX_KEYSIZE_INC 35 (0x23) + /// + /// 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. + /// + /// + /// + /// PP_NAME 4 (0x4) + /// + /// 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. + /// + /// + /// + /// PP_PROVTYPE 16 (0x10) + /// A DWORD value that indicates the provider type of the CSP. + /// + /// + /// PP_ROOT_CERTSTORE 46 (0x2E) + /// + /// 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. + /// + /// + /// + /// PP_SESSION_KEYSIZE 20 (0x14) + /// The size, in bits, of the session key. + /// + /// + /// PP_SGC_INFO 37 (0x25) + /// Used with server gated cryptography. + /// + /// + /// PP_SIG_KEYSIZE_INC 34 (0x22) + /// + /// 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. + /// + /// + /// + /// PP_SIGNATURE_PIN 33 (0x21) + /// Specifies that the key signature PIN is contained in pbData. The PIN is represented as a null-terminated ASCII string. + /// + /// + /// PP_SMARTCARD_GUID 45 (0x2D) + /// + /// 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. + /// + /// + /// + /// PP_SMARTCARD_READER 43 (0x2B) + /// + /// 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. + /// + /// + /// + /// PP_SYM_KEYSIZE 19 (0x13) + /// The size of the symmetric key. + /// + /// + /// PP_UI_PROMPT 21 (0x15) + /// This query is not used. + /// + /// + /// PP_UNIQUE_CONTAINER 36 (0x24) + /// + /// 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. + /// + /// + /// + /// PP_USE_HARDWARE_RNG 38 (0x26) + /// + /// 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. + /// + /// + /// + /// PP_USER_CERTSTORE 42 (0x2A) + /// + /// 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. + /// + /// + /// + /// PP_VERSION 5 (0x5) + /// + /// 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. + /// + /// + /// + /// + /// + /// + /// If dwParam is PP_KEYSET_SEC_DESCR, the security descriptor on the key container where the keys are stored is retrieved. + /// For this case, dwFlags is used to pass in the SECURITY_INFORMATION bit flags that indicate the requested security + /// information, as defined in the Platform SDK. SECURITY_INFORMATION bit flags can be combined with a bitwise- OR operation. + /// + /// The following values are defined for use with PP_KEYSET_SEC_DESCR. + /// + /// + /// Value + /// Meaning + /// + /// + /// OWNER_SECURITY_INFORMATION + /// Owner identifier of the object is being referenced. + /// + /// + /// GROUP_SECURITY_INFORMATION + /// Primary group identifier of the object is being referenced. + /// + /// + /// DACL_SECURITY_INFORMATION + /// Discretionary ACL of the object is being referenced. + /// + /// + /// SACL_SECURITY_INFORMATION + /// System ACL of the object is being referenced. + /// + /// + /// The following values are defined for use with PP_ENUMALGS, PP_ENUMALGS_EX, and PP_ENUMCONTAINERS. + /// + /// + /// Value + /// Meaning + /// + /// + /// CRYPT_FIRST 1 (0x1) + /// Retrieve the first element in the enumeration. This has the same effect as resetting the enumerator. + /// + /// + /// CRYPT_NEXT 2 (0x2) + /// + /// 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. + /// + /// + /// + /// CRYPT_SGC_ENUM 4 (0x4) + /// + /// Retrieve server-gated cryptography (SGC) enabled certificates. SGC enabled certificates are no longer supported. For more + /// information, see Microsoft Support Article 875450. + /// + /// + /// + /// CRYPT_SGC + /// This flag is not used. + /// + /// + /// CRYPT_FASTSGC + /// This flag is not used. + /// + /// + /// + /// The specified value data. The form of this data varies, depending on the value number. + public static T CryptGetProvParam(HCRYPTPROV hProv, ProvParam dwParam, uint dwFlags) => CryptGetValue(CryptGetProvParam, hProv, dwParam, dwFlags); + + /// + /// 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. + /// + /// HCRYPTPROV handle of a cryptographic service provider (CSP) created by a call to CryptAcquireContext. + /// + /// Identifies the private key to use from the key container. It can be AT_KEYEXCHANGE or AT_SIGNATURE. + /// + /// Additionally, some providers allow access to other user-specific keys through this function. For details, see the documentation + /// on the specific provider. + /// + /// + /// + /// 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. + /// + /// + /// If the function succeeds, the return value is nonzero (TRUE). + /// If the function fails, the return value is zero (FALSE). For extended error information, call GetLastError. + /// The error codes prefaced by "NTE" are generated by the particular CSP being used. Some possible error codes follow. + /// + /// + /// Return code + /// Description + /// + /// + /// ERROR_INVALID_HANDLE + /// One of the parameters specifies a handle that is not valid. + /// + /// + /// ERROR_INVALID_PARAMETER + /// One of the parameters contains a value that is not valid. This is most often a pointer that is not valid. + /// + /// + /// NTE_BAD_KEY + /// The dwKeySpec parameter contains a value that is not valid. + /// + /// + /// NTE_BAD_UID + /// The hProv parameter does not contain a valid context handle. + /// + /// + /// NTE_NO_KEY + /// The key requested by the dwKeySpec parameter does not exist. + /// + /// + /// + // 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); + + /// + /// 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. + /// Before calling this function, CryptCreateHash must be called to create a handle of a hash object. + /// + /// Handle of the hash object. + /// A pointer to a buffer that contains the data to be added to the hash object. + /// Number of bytes of data to be added. This must be zero if the CRYPT_USERDATA flag is set. + /// + /// The following flag values are defined. + /// + /// + /// Value + /// Meaning + /// + /// + /// CRYPT_OWF_REPL_LM_HASH 0x00000001 + /// This flag is not used. + /// + /// + /// CRYPT_USERDATA 1 (0x1) + /// + /// 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. + /// + /// + /// + /// + /// + /// If the function succeeds, the return value is TRUE. + /// If the function fails, the return value is FALSE. For extended error information, call GetLastError. + /// The error codes prefaced by "NTE" are generated by the particular CSP you are using. Some possible error codes follow. + /// + /// + /// Return code + /// Description + /// + /// + /// ERROR_INVALID_HANDLE + /// One of the parameters specifies a handle that is not valid. + /// + /// + /// ERROR_INVALID_PARAMETER + /// One of the parameters contains a value that is not valid. This is most often a pointer that is not valid. + /// + /// + /// NTE_BAD_ALGID + /// The hHash handle specifies an algorithm that this CSP does not support. + /// + /// + /// NTE_BAD_FLAGS + /// The dwFlags parameter contains a value that is not valid. + /// + /// + /// NTE_BAD_HASH + /// The hash object specified by the hHash parameter is not valid. + /// + /// + /// NTE_BAD_HASH_STATE + /// An attempt was made to add data to a hash object that is already marked "finished." + /// + /// + /// NTE_BAD_KEY + /// + /// 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. + /// + /// + /// + /// NTE_BAD_LEN + /// The CSP does not ignore the CRYPT_USERDATA flag, the flag is set, and the dwDataLen parameter has a nonzero value. + /// + /// + /// NTE_BAD_UID + /// The CSP context that was specified when the hash object was created cannot be found. + /// + /// + /// NTE_FAIL + /// The function failed in some unexpected way. + /// + /// + /// NTE_NO_MEMORY + /// The CSP ran out of memory during the operation. + /// + /// + /// + // 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); + + /// + /// 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. + /// Before calling this function, CryptCreateHash must be called to create the handle of a hash object. + /// + /// A handle to the hash object. + /// A handle to the key object to be hashed. + /// + /// The following flag value is defined. + /// + /// + /// Value + /// Meaning + /// + /// + /// CRYPT_LITTLE_ENDIAN 0x00000001 + /// + /// 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. + /// + /// + /// + /// + /// + /// If the function succeeds, the return value is TRUE. + /// If the function fails, the return value is FALSE. For extended error information, call GetLastError. + /// The error codes prefaced by "NTE" are generated by the particular CSP you are using. Some possible error codes follow. + /// + /// + /// Return code + /// Description + /// + /// + /// ERROR_INVALID_HANDLE + /// One of the parameters specifies a handle that is not valid. + /// + /// + /// ERROR_INVALID_PARAMETER + /// One of the parameters contains a value that is not valid. This is most often a pointer that is not valid. + /// + /// + /// NTE_BAD_ALGID + /// The hHash handle specifies an algorithm that this CSP does not support. + /// + /// + /// NTE_BAD_FLAGS + /// The dwFlags parameter is nonzero. + /// + /// + /// NTE_BAD_HASH + /// The hash object specified by the hHash parameter is not valid. + /// + /// + /// NTE_BAD_HASH_STATE + /// An attempt was made to add data to a hash object that is already marked "finished." + /// + /// + /// NTE_BAD_KEY + /// + /// 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. + /// + /// + /// + /// NTE_BAD_UID + /// The CSP context that was specified when the hash object was created cannot be found. + /// + /// + /// NTE_FAIL + /// The function failed in some unexpected way. + /// + /// + /// + // 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); + + /// + /// 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. + /// + /// The handle of a CSP obtained with the CryptAcquireContext function. + /// + /// A BYTE 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. + /// + /// Contains the length, in bytes, of the key BLOB. + /// + /// + /// 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: + /// + /// + /// + /// + /// If the key BLOB is encrypted with the key exchange key pair, for example, a SIMPLEBLOB, this parameter can be the handle + /// to the key exchange key. + /// + /// + /// + /// + /// If the key BLOB is encrypted with a session key, for example, an encrypted PRIVATEKEYBLOB, this parameter contains the + /// handle of this session key. + /// + /// + /// + /// If the key BLOB is not encrypted, for example, a PUBLICKEYBLOB, this parameter is not used and must be zero. + /// + /// + /// + /// If the key BLOB is encrypted with a session key in an Schannel CSP, for example, an encrypted OPAQUEKEYBLOB or any other + /// vendor-specific OPAQUEKEYBLOB, this parameter is not used and must be set to zero. + /// + /// + /// + /// + /// Note 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. + /// + /// + /// + /// Currently used only when a public/private key pair in the form of a PRIVATEKEYBLOB is imported into the CSP. + /// This parameter can be one of the following values. + /// + /// + /// Value + /// Meaning + /// + /// + /// CRYPT_EXPORTABLE + /// + /// The key being imported is eventually to be reexported. If this flag is not used, then calls to CryptExportKey with the key + /// handle fail. + /// + /// + /// + /// CRYPT_OAEP + /// This flag causes PKCS #1 version 2 formatting to be checked with RSA encryption and decryption when importing SIMPLEBLOBs. + /// + /// + /// CRYPT_NO_SALT + /// A no-salt value gets allocated for a 40-bit symmetric key. For more information, see Salt Value Functionality. + /// + /// + /// CRYPT_USER_PROTECTED + /// + /// 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. + /// + /// + /// + /// CRYPT_IPSEC_HMAC_KEY + /// + /// 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. + /// + /// + /// + /// + /// + /// A pointer to a HCRYPTKEY value that receives the handle of the imported key. When you have finished using the key, + /// release the handle by calling the CryptDestroyKey function. + /// + /// + /// If the function succeeds, the function returns nonzero. + /// If the function fails, it returns zero. For extended error information, call GetLastError. + /// Error codes prefaced by "NTE" are generated by the particular CSP being used. Some possible error codes follow. + /// + /// + /// Return code + /// Description + /// + /// + /// ERROR_BUSY + /// Some CSPs set this error if a private key is imported into a container while another thread or process is using this key. + /// + /// + /// ERROR_INVALID_HANDLE + /// One of the parameters specifies a handle that is not valid. + /// + /// + /// ERROR_INVALID_PARAMETER + /// One of the parameters contains a value that is not valid. This is most often a pointer that is not valid. + /// + /// + /// NTE_BAD_ALGID + /// The simple key BLOB to be imported is not encrypted with the expected key exchange algorithm. + /// + /// + /// NTE_BAD_DATA + /// + /// 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. + /// + /// + /// + /// NTE_BAD_FLAGS + /// The dwFlags parameter specified is not valid. + /// + /// + /// NTE_BAD_TYPE + /// The key BLOB type is not supported by this CSP and is possibly not valid. + /// + /// + /// NTE_BAD_UID + /// The hProv parameter does not contain a valid context handle. + /// + /// + /// NTE_BAD_VER + /// The version number of the key BLOB does not match the CSP version. This usually indicates that the CSP needs to be upgraded. + /// + /// + /// + /// + /// + /// When importing a Hash-Based Message Authentication Code (HMAC) key, the caller must identify the imported key as a + /// PLAINTEXTKEYBLOB type and set the appropriate algorithm identifier in the aiKeyAlg field of the PUBLICKEYSTRUC + /// BLOB header. + /// + /// + /// The CryptImportKey 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. + /// + /// You can use the PLAINTEXTKEYBLOB type with any algorithm or type of key combination supported by the CSP in use. + /// For an example of importing a plaintext key, see Example C Program: Importing a Plaintext Key. + /// The following example shows how you can set the header fields. + /// The length of the key is specified in keyBlob.keyLength, which is followed by the actual key data. + /// + /// Note The HMAC algorithms do not have their own algorithm identifiers; use CALG_RC2 instead. CRYPT_IPSEC_HMAC_KEY + /// allows the import of RC2 keys longer than 16 bytes. + /// + /// + /// For any of the Data Encryption Standard (DES) key permutations that use PLAINTEXTKEYBLOB, only the full key size, + /// including parity bit, can be imported. + /// + /// The following key sizes are supported. + /// + /// + /// Algorithm + /// Supported key size + /// + /// + /// CALG_DES + /// 64 bits + /// + /// + /// CALG_3DES_112 + /// 128 bits + /// + /// + /// CALG_3DES + /// 192 bits + /// + /// + /// Examples + /// + /// 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. + /// + /// + // 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); + + /// + /// 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. + /// + /// The handle of a CSP obtained with the CryptAcquireContext function. + /// + /// A BYTE 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. + /// + /// Contains the length, in bytes, of the key BLOB. + /// + /// + /// 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: + /// + /// + /// + /// + /// If the key BLOB is encrypted with the key exchange key pair, for example, a SIMPLEBLOB, this parameter can be the handle + /// to the key exchange key. + /// + /// + /// + /// + /// If the key BLOB is encrypted with a session key, for example, an encrypted PRIVATEKEYBLOB, this parameter contains the + /// handle of this session key. + /// + /// + /// + /// If the key BLOB is not encrypted, for example, a PUBLICKEYBLOB, this parameter is not used and must be zero. + /// + /// + /// + /// If the key BLOB is encrypted with a session key in an Schannel CSP, for example, an encrypted OPAQUEKEYBLOB or any other + /// vendor-specific OPAQUEKEYBLOB, this parameter is not used and must be set to zero. + /// + /// + /// + /// + /// Note 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. + /// + /// + /// + /// Currently used only when a public/private key pair in the form of a PRIVATEKEYBLOB is imported into the CSP. + /// This parameter can be one of the following values. + /// + /// + /// Value + /// Meaning + /// + /// + /// CRYPT_EXPORTABLE + /// + /// The key being imported is eventually to be reexported. If this flag is not used, then calls to CryptExportKey with the key + /// handle fail. + /// + /// + /// + /// CRYPT_OAEP + /// This flag causes PKCS #1 version 2 formatting to be checked with RSA encryption and decryption when importing SIMPLEBLOBs. + /// + /// + /// CRYPT_NO_SALT + /// A no-salt value gets allocated for a 40-bit symmetric key. For more information, see Salt Value Functionality. + /// + /// + /// CRYPT_USER_PROTECTED + /// + /// 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. + /// + /// + /// + /// CRYPT_IPSEC_HMAC_KEY + /// + /// 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. + /// + /// + /// + /// + /// + /// A pointer to a HCRYPTKEY value that receives the handle of the imported key. When you have finished using the key, + /// release the handle by calling the CryptDestroyKey function. + /// + /// + /// If the function succeeds, the function returns nonzero. + /// If the function fails, it returns zero. For extended error information, call GetLastError. + /// Error codes prefaced by "NTE" are generated by the particular CSP being used. Some possible error codes follow. + /// + /// + /// Return code + /// Description + /// + /// + /// ERROR_BUSY + /// Some CSPs set this error if a private key is imported into a container while another thread or process is using this key. + /// + /// + /// ERROR_INVALID_HANDLE + /// One of the parameters specifies a handle that is not valid. + /// + /// + /// ERROR_INVALID_PARAMETER + /// One of the parameters contains a value that is not valid. This is most often a pointer that is not valid. + /// + /// + /// NTE_BAD_ALGID + /// The simple key BLOB to be imported is not encrypted with the expected key exchange algorithm. + /// + /// + /// NTE_BAD_DATA + /// + /// 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. + /// + /// + /// + /// NTE_BAD_FLAGS + /// The dwFlags parameter specified is not valid. + /// + /// + /// NTE_BAD_TYPE + /// The key BLOB type is not supported by this CSP and is possibly not valid. + /// + /// + /// NTE_BAD_UID + /// The hProv parameter does not contain a valid context handle. + /// + /// + /// NTE_BAD_VER + /// The version number of the key BLOB does not match the CSP version. This usually indicates that the CSP needs to be upgraded. + /// + /// + /// + /// + /// + /// When importing a Hash-Based Message Authentication Code (HMAC) key, the caller must identify the imported key as a + /// PLAINTEXTKEYBLOB type and set the appropriate algorithm identifier in the aiKeyAlg field of the PUBLICKEYSTRUC + /// BLOB header. + /// + /// + /// The CryptImportKey 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. + /// + /// You can use the PLAINTEXTKEYBLOB type with any algorithm or type of key combination supported by the CSP in use. + /// For an example of importing a plaintext key, see Example C Program: Importing a Plaintext Key. + /// The following example shows how you can set the header fields. + /// The length of the key is specified in keyBlob.keyLength, which is followed by the actual key data. + /// + /// Note The HMAC algorithms do not have their own algorithm identifiers; use CALG_RC2 instead. CRYPT_IPSEC_HMAC_KEY + /// allows the import of RC2 keys longer than 16 bytes. + /// + /// + /// For any of the Data Encryption Standard (DES) key permutations that use PLAINTEXTKEYBLOB, only the full key size, + /// including parity bit, can be imported. + /// + /// The following key sizes are supported. + /// + /// + /// Algorithm + /// Supported key size + /// + /// + /// CALG_DES + /// 64 bits + /// + /// + /// CALG_3DES_112 + /// 128 bits + /// + /// + /// CALG_3DES + /// 192 bits + /// + /// + /// Examples + /// + /// 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. + /// + /// + // 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); + + /// + /// + /// 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. + /// + /// + /// 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. + /// + /// + /// Handle of a cryptographic service provider (CSP) created by a call to CryptAcquireContext. + /// + /// Reserved for future use and must be zero. If dwFlags is not set to zero, this function returns FALSE but the CSP is released. + /// + /// + /// If the function succeeds, the return value is nonzero ( TRUE). + /// + /// If the function fails, the return value is zero ( FALSE). For extended error information, call GetLastError. Some + /// possible error codes are listed in the following table. + /// + /// + /// + /// Return code + /// Description + /// + /// + /// ERROR_BUSY + /// The CSP context specified by hProv is currently being used by another process. + /// + /// + /// ERROR_INVALID_HANDLE + /// One of the parameters specifies a handle that is not valid. + /// + /// + /// ERROR_INVALID_PARAMETER + /// One of the parameters contains a value that is not valid. This is most often a pointer that is not valid. + /// + /// + /// NTE_BAD_FLAGS + /// The dwFlags parameter is nonzero. + /// + /// + /// NTE_BAD_UID + /// The hProv parameter does not contain a valid context handle. + /// + /// + /// + /// + /// + /// 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 CryptReleaseContext is called. + /// + /// Examples + /// For an example that uses this function, see Example C Program: Creating and Hashing a Session Key. + /// + // 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); + + /// + /// The CryptSetHashParam function customizes the operations of a hash object, including setting up initial hash contents and + /// selecting a specific hashing algorithm. + /// + /// A handle to the hash object on which to set parameters. + /// + /// This parameter can be one of the following values. + /// + /// + /// Value + /// Meaning + /// + /// + /// HP_HMAC_INFO. + /// + /// A pointer to an HMAC_INFO structure that specifies the cryptographic hash algorithm and the inner and outer strings to be used. + /// + /// + /// + /// HP_HASHVAL. + /// + /// 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. + /// + /// + /// + /// Note Some CSP types can add additional values that can be set by using this function. + /// + /// + /// A value data buffer. Place the value data in this buffer before calling CryptSetHashParam. The form of this data varies, + /// depending on the value number. + /// + /// This parameter is reserved for future use and must be set to zero. + /// + /// If the function succeeds, the function returns TRUE. + /// If the function fails, it returns FALSE. For extended error information, call GetLastError. + /// The error codes prefaced by "NTE" are generated by the particular CSP you are using. Some possible error codes follow. + /// + /// + /// Return code + /// Description + /// + /// + /// ERROR_INVALID_HANDLE + /// One of the parameters specifies a handle that is not valid. + /// + /// + /// ERROR_BUSY + /// The CSP context is currently being used by another process. + /// + /// + /// ERROR_INVALID_PARAMETER + /// One of the parameters contains a value that is not valid. This is most often a pointer that is not valid. + /// + /// + /// NTE_BAD_FLAGS + /// The dwFlags parameter is nonzero or the pbData buffer contains a value that is not valid. + /// + /// + /// NTE_BAD_HASH + /// The hash object specified by the hHash parameter is not valid. + /// + /// + /// NTE_BAD_TYPE + /// The dwParam parameter specifies an unknown value. + /// + /// + /// NTE_BAD_UID + /// The CSP context that was specified when the hKey key was created cannot be found. + /// + /// + /// NTE_FAIL + /// The function failed in some unexpected way. + /// + /// + /// + /// + /// + /// Occasionally, a hash value that has been generated elsewhere must be signed. This can be done by using the following sequence of operations: + /// + /// + /// + /// Create a hash object by using CryptCreateHash. + /// + /// + /// Set the HP_HASHVAL value. + /// + /// + /// Sign the hash value by using CryptSignHash and obtain a digital signature block. + /// + /// + /// Destroy the hash object by using CryptDestroyHash. + /// + /// + /// + // 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); + + /// + /// 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. + /// + /// 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. + /// + /// + /// A handle to the key for which values are to be set. + /// + /// The following tables contain predefined values that can be used. + /// For all key types, this parameter can contain one of the following values. + /// + /// + /// Value + /// Meaning + /// + /// + /// KP_ALGID + /// + /// 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. + /// + /// + /// + /// KP_CERTIFICATE + /// + /// 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. + /// + /// + /// + /// KP_PERMISSIONS + /// pbData points to a DWORD value that specifies zero or more permission flags. For a description of these flags, see CryptGetKeyParam. + /// + /// + /// KP_SALT + /// + /// 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. + /// + /// + /// + /// KP_SALT_EX + /// pbData points to a CRYPT_INTEGER_BLOB structure that contains the salt. For more information, see Specifying a Salt Value. + /// + /// + /// + /// 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. + /// + /// + /// + /// Value + /// Meaning + /// + /// + /// KP_G + /// + /// 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. + /// + /// + /// + /// KP_P + /// + /// 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. + /// + /// + /// + /// KP_Q + /// + /// 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. + /// + /// + /// + /// KP_X + /// + /// 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. + /// + /// + /// + /// + /// 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. + /// + /// + /// + /// Value + /// Meaning + /// + /// + /// KP_CMS_DH_KEY_INFO + /// + /// 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. + /// + /// + /// + /// KP_PUB_PARAMS + /// + /// 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. + /// + /// + /// + /// + /// 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. + /// + /// + /// + /// Value + /// Meaning + /// + /// + /// KP_EFFECTIVE_KEYLEN + /// + /// 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. + /// + /// + /// + /// KP_HIGHEST_VERSION + /// + /// 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. + /// + /// + /// + /// KP_IV + /// + /// 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. + /// + /// + /// + /// KP_KEYVAL + /// + /// 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. + /// + /// + /// + /// KP_PADDING + /// + /// 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. + /// + /// + /// + /// KP_MODE + /// + /// 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. + /// + /// + /// + /// KP_MODE_BITS + /// + /// 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. + /// + /// + /// + /// If an RSA key is specified in the hKey parameter, the dwParam parameter value can be the following value. + /// + /// + /// Value + /// Meaning + /// + /// + /// KP_OAEP_PARAMS + /// + /// 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. + /// + /// + /// + /// Note that the following values are not used: + /// + /// + /// KP_ADMIN_PIN + /// + /// + /// KP_CMS_KEY_INFO + /// + /// + /// KP_INFO + /// + /// + /// KP_KEYEXCHANGE_PIN + /// + /// + /// KP_PRECOMP_MD5 + /// + /// + /// KP_PRECOMP_SHA + /// + /// + /// KP_PREHASH + /// + /// + /// KP_PUB_EX_LEN + /// + /// + /// KP_PUB_EX_VAL + /// + /// + /// KP_RA + /// + /// + /// KP_RB + /// + /// + /// KP_ROUNDS + /// + /// + /// KP_RP + /// + /// + /// KP_SIGNATURE_PIN + /// + /// + /// KP_Y + /// + /// + /// + /// + /// A pointer to a buffer initialized with the value to be set before calling CryptSetKeyParam. The form of this data varies + /// depending on the value of dwParam. + /// + /// + /// 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 CryptGenKey. + /// + /// + /// If the function succeeds, the return value is nonzero (TRUE). + /// If the function fails, the return value is zero (FALSE). For extended error information, call GetLastError. + /// The error codes prefaced by "NTE" are generated by the particular CSP being used. Some possible error codes follow. + /// + /// + /// Return code + /// Description + /// + /// + /// ERROR_BUSY + /// The CSP context is currently being used by another process. + /// + /// + /// ERROR_INVALID_HANDLE + /// One of the parameters specifies a handle that is not valid. + /// + /// + /// ERROR_INVALID_PARAMETER + /// One of the parameters contains a value that is not valid. This is most often a pointer that is not valid. + /// + /// + /// NTE_BAD_FLAGS + /// The dwFlags parameter is nonzero, or the pbData buffer contains a value that is not valid. + /// + /// + /// NTE_BAD_TYPE + /// The dwParam parameter specifies an unknown parameter. + /// + /// + /// NTE_BAD_UID + /// The CSP context that was specified when the hKey key was created cannot be found. + /// + /// + /// NTE_FAIL + /// The function failed in some unexpected way. + /// + /// + /// NTE_FIXEDPARAMETER + /// + /// 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. + /// + /// + /// + /// + /// + /// + /// 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 CryptGenKey, the default key length was used. This will create an error if a nondefault key length is used to set + /// P, Q, or X. + /// + /// Examples + /// + /// 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 . + /// + /// + // 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); + + /// + /// The CryptSetProvider function specifies the current user's default cryptographic service provider (CSP). + /// + /// 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. + /// + /// An enhanced version of this function, CryptSetProviderEx, is also available. + /// Note Typical applications do not use this function. It is intended for use solely by administrative applications. + /// + /// + /// 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. + /// + /// Provider type of the CSP specified by pszProvName. + /// + /// If the function succeeds, the return value is nonzero (TRUE). + /// + /// If the function fails, the return value is zero (FALSE). For extended error information, call GetLastError. Some possible error + /// codes are listed in the following table. + /// + /// + /// + /// Return code + /// Description + /// + /// + /// ERROR_INVALID_HANDLE + /// One of the parameters specifies a handle that is not valid. + /// + /// + /// ERROR_INVALID_PARAMETER + /// One of the parameters contains a value that is not valid. This is most often a pointer that is not valid. + /// + /// + /// ERROR_NOT_ENOUGH_MEMORY + /// The operating system ran out of memory during the operation. + /// + /// + /// Errors can also be propagated from internal calls to RegCreateKeyEx and RegSetValueEx. + /// + /// + /// + /// 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. + /// + /// + /// Since calling CryptSetProvider 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. + /// + /// + // 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); + + /// + /// + /// The CryptSetProviderEx function specifies the default cryptographic service provider (CSP) of a specified provider type for the + /// local computer or current user. + /// + /// Typical applications do not use this function. It is intended for use solely by administrative applications. + /// + /// + /// 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. + /// + /// The provider type of the CSP specified by pszProvName. + /// This parameter is reserved for future use and must be NULL. + /// + /// The following flag values are defined. + /// + /// + /// Value + /// Meaning + /// + /// + /// CRYPT_DELETE_DEFAULT 0x00000004 + /// Can be used in conjunction with CRYPT_MACHINE_DEFAULT or CRYPT_USER_DEFAULT to delete the default. + /// + /// + /// CRYPT_USER_DEFAULT 0x00000002 + /// Causes the user-context default CSP of the specified type to be set. + /// + /// + /// CRYPT_MACHINE_DEFAULT 0x00000001 + /// Causes the computer default CSP of the specified type to be set. + /// + /// + /// + /// + /// If the function succeeds, the return value is nonzero ( TRUE). + /// + /// If the function fails, the return value is zero ( FALSE). For extended error information, call GetLastError. Possible + /// error codes include those shown in the following table. + /// + /// + /// + /// Return code + /// Description + /// + /// + /// ERROR_INVALID_PARAMETER + /// One of the parameters contains a value that is not valid. This is most often a pointer that is not valid. + /// + /// + /// ERROR_NOT_ENOUGH_MEMORY + /// The operating system ran out of memory. + /// + /// + /// + /// + /// 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 CryptSetProviderEx determine + /// the CSP of a specified type used by all applications from that point on, CryptSetProviderEx must never be called without + /// a user's consent. + /// + // 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); + + /// + /// 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. + /// + /// + /// The handle of a CSP for which to set values. This handle must have already been created by using the CryptAcquireContext function. + /// + /// + /// Specifies the parameter to set. This can be one of the following values. + /// + /// + /// Value + /// Meaning + /// + /// + /// PP_CLIENT_HWND 1 (0x1) + /// + /// 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. + /// + /// + /// + /// PP_DELETEKEY 24 (0x18) + /// + /// Delete the ephemeral key associated with a hash, encryption, or verification context. This will free memory and clear registry + /// settings associated with the key. + /// + /// + /// + /// PP_KEYEXCHANGE_ALG + /// This constant is not used. + /// + /// + /// PP_KEYEXCHANGE_PIN 32 (0x20) + /// Specifies that the key exchange PIN is contained in pbData. The PIN is represented as a null-terminated ASCII string. + /// + /// + /// PP_KEYEXCHANGE_KEYSIZE + /// This constant is not used. + /// + /// + /// PP_KEYSET_SEC_DESCR 8 (0x8) + /// + /// 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. + /// + /// + /// + /// PP_PIN_PROMPT_STRING 44 (0x2C) + /// + /// 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. + /// + /// + /// + /// PP_ROOT_CERTSTORE 46 (0x2E) + /// + /// 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. + /// + /// + /// + /// PP_SIGNATURE_ALG + /// This constant is not used. + /// + /// + /// PP_SIGNATURE_PIN 33 (0x21) + /// Specifies the signature PIN. The pbData parameter is a null-terminated ASCII string that represents the PIN. + /// + /// + /// PP_SIGNATURE_KEYSIZE + /// This constant is not used. + /// + /// + /// PP_UI_PROMPT 21 (0x15) + /// + /// 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. + /// + /// + /// + /// PP_USE_HARDWARE_RNG 38 (0x26) + /// + /// 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. + /// + /// + /// + /// PP_USER_CERTSTORE 42 (0x2A) + /// + /// 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. + /// + /// + /// + /// PP_SECURE_KEYEXCHANGE_PIN 47 (0x2F) + /// Specifies that an encrypted key exchange PIN is contained in pbData. The pbData parameter contains a DATA_BLOB. + /// + /// + /// PP_SECURE_SIGNATURE_PIN 48 (0x30) + /// Specifies that an encrypted signature PIN is contained in pbData. The pbData parameter contains a DATA_BLOB. + /// + /// + /// PP_SMARTCARD_READER 43 (0x2B) + /// + /// 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. + /// + /// + /// + /// PP_SMARTCARD_GUID 45 (0x2D) + /// + /// 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. + /// + /// + /// + /// + /// + /// 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 PP_USE_HARDWARE_RNG, this parameter must be NULL. + /// + /// + /// + /// If dwParam contains PP_KEYSET_SEC_DESCR, dwFlags contains the SECURITY_INFORMATION applicable bit flags, as + /// defined in the Platform SDK. Key-container security is handled by using SetFileSecurity and GetFileSecurity. + /// + /// These bit flags can be combined by using a bitwise- OR operation. For more information, see CryptGetProvParam. + /// If dwParam is PP_USE_HARDWARE_RNG or PP_DELETEKEY, dwFlags must be set to zero. + /// + /// + /// If the function succeeds, the return value is nonzero ( TRUE). + /// If the function fails, the return value is zero ( FALSE). For extended error information, call GetLastError. + /// The error codes prefaced by "NTE" are generated by the particular CSP being used. Error codes include the following. + /// + /// + /// Return code + /// Description + /// + /// + /// ERROR_BUSY + /// The CSP context is currently being used by another process. + /// + /// + /// ERROR_INVALID_HANDLE + /// One of the parameters specifies a handle that is not valid. + /// + /// + /// ERROR_INVALID_PARAMETER + /// One of the parameters contains a value that is not valid. This is most often a pointer that is not valid. + /// + /// + /// NTE_BAD_FLAGS + /// The dwFlags parameter is nonzero or the pbData buffer contains a value that is not valid. + /// + /// + /// NTE_BAD_TYPE + /// The dwParam parameter specifies an unknown parameter. + /// + /// + /// NTE_BAD_UID + /// The CSP context that was specified when the hKey key was created cannot be found. + /// + /// + /// NTE_FAIL + /// The function failed in some unexpected way. + /// + /// + /// + // 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); + + /// + /// 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. + /// + /// Handle of the hash object to be signed. + /// + /// Identifies the private key to use from the provider's container. It can be AT_KEYEXCHANGE or AT_SIGNATURE. + /// The signature algorithm used is specified when the key pair is originally created. + /// The only signature algorithm that the Microsoft Base Cryptographic Provider supports is the RSA Public Key algorithm. + /// + /// + /// This parameter is no longer used and must be set to NULL to prevent security vulnerabilities. However, it is still + /// supported for backward compatibility in the Microsoft Base Cryptographic Provider. + /// + /// + /// The following flag values are defined. + /// + /// + /// Value + /// Meaning + /// + /// + /// CRYPT_NOHASHOID 0x00000001 + /// + /// 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. + /// + /// + /// + /// CRYPT_TYPE2_FORMAT 0x00000002 + /// This flag is not used. + /// + /// + /// CRYPT_X931_FORMAT 0x00000004 + /// Use the RSA signature padding method specified in the ANSI X9.31 standard. + /// + /// + /// + /// + /// A pointer to a buffer receiving the signature data. + /// + /// This parameter can be NULL to set the buffer size for memory allocation purposes. For more information, see Retrieving + /// Data of Unknown Length. + /// + /// + /// + /// + /// A pointer to a DWORD value that specifies the size, in bytes, of the pbSignature buffer. When the function returns, the + /// DWORD value contains the number of bytes stored in the buffer. + /// + /// + /// Note When processing the data returned in the buffer, applications must use the actual size of the data returned. The + /// actual size can be slightly smaller than the size of the buffer specified on input. (On input, buffer sizes are usually + /// specified large enough to ensure that the largest possible output data 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 the function succeeds, the function returns TRUE. + /// If the function fails, it returns FALSE. For extended error information, call GetLastError. + /// The error codes prefaced by "NTE" are generated by the particular CSP you are using. Some possible error codes follow. + /// + /// + /// Return code + /// Description + /// + /// + /// ERROR_INVALID_HANDLE + /// One of the parameters specifies a handle that is not valid. + /// + /// + /// ERROR_INVALID_PARAMETER + /// One of the parameters contains a value that is not valid. This is most often a pointer that is not valid. + /// + /// + /// ERROR_MORE_DATA + /// + /// 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. + /// + /// + /// + /// NTE_BAD_ALGID + /// The hHash handle specifies an algorithm that this CSP does not support, or the dwKeySpec parameter has an incorrect value. + /// + /// + /// NTE_BAD_FLAGS + /// The dwFlags parameter is nonzero. + /// + /// + /// NTE_BAD_HASH + /// The hash object specified by the hHash parameter is not valid. + /// + /// + /// NTE_BAD_UID + /// The CSP context that was specified when the hash object was created cannot be found. + /// + /// + /// NTE_NO_KEY + /// The private key specified by dwKeySpec does not exist. + /// + /// + /// NTE_NO_MEMORY + /// The CSP ran out of memory during the operation. + /// + /// + /// + /// + /// + /// 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 CryptSignHash function + /// completes the hash. + /// + /// + /// While the DSS CSP supports hashing with both the MD5 and the SHA hash algorithms, the DSS CSP only supports signing SHA hashes. + /// + /// + /// After this function is called, no more data can be added to the hash. Additional calls to CryptHashData or CryptHashSessionKey fail. + /// + /// After the application finishes using the hash, destroy the hash object by calling the CryptDestroyHash function. + /// + /// By default, the Microsoft RSA providers use the PKCS #1 padding method for the signature. The hash OID in the DigestInfo + /// element of the signature is automatically set to the algorithm OID associated with the hash object. Using the + /// CRYPT_NOHASHOID flag will cause this OID to be omitted from the signature. + /// + /// + /// Occasionally, a hash value that has been generated elsewhere must be signed. This can be done by using the following sequence of operations: + /// + /// + /// + /// Create a hash object by using CryptCreateHash. + /// + /// + /// Set the hash value in the hash object by using the HP_HASHVAL value of the dwParam parameter in CryptSetHashParam. + /// + /// + /// Sign the hash value by using CryptSignHash and obtain a digital signature block. + /// + /// + /// Destroy the hash object by using CryptDestroyHash. + /// + /// + /// Examples + /// + /// The following example shows signing data by first hashing the data to be signed and then signing the hash by using the + /// CryptSignHash function. + /// + /// + /// For a complete example including the context for this code, see Example C Program: Signing a Hash and Verifying the Hash Signature. + /// + /// + // 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); + + /// + /// The CryptVerifySignature function verifies the signature of a hash object. + /// + /// 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. + /// + /// After CryptVerifySignature completes, only CryptDestroyHash can be called by using the hHash handle. + /// + /// A handle to the hash object to verify. + /// The address of the signature data to be verified. + /// The number of bytes in the pbSignature signature data. + /// + /// 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. + /// + /// + /// This parameter should no longer be used and must be set to NULL to prevent security vulnerabilities. However, it is still + /// supported for backward compatibility in the Microsoft Base Cryptographic Provider. + /// + /// + /// The following flag values are defined. + /// + /// + /// Value + /// Meaning + /// + /// + /// CRYPT_NOHASHOID 0x00000001 + /// + /// 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. + /// + /// + /// + /// CRYPT_TYPE2_FORMAT 0x00000002 + /// This flag is not used. + /// + /// + /// CRYPT_X931_FORMAT 0x00000004 + /// Use X.931 support for the FIPS 186-2–compliant version of RSA (rDSA). + /// + /// + /// + /// + /// If the function succeeds, the return value is TRUE. + /// If the function fails, the return value is FALSE. For extended error information, call GetLastError. + /// The error codes prefaced by "NTE" are generated by the particular CSP you are using. Some possible error codes follow. + /// + /// + /// Return code + /// Description + /// + /// + /// ERROR_INVALID_HANDLE + /// One of the parameters specifies a handle that is not valid. + /// + /// + /// ERROR_INVALID_PARAMETER + /// One of the parameters contains a value that is not valid. This is most often a pointer that is not valid. + /// + /// + /// NTE_BAD_FLAGS + /// The dwFlags parameter is nonzero. + /// + /// + /// NTE_BAD_HASH + /// The hash object specified by the hHash parameter is not valid. + /// + /// + /// NTE_BAD_KEY + /// The hPubKey parameter does not contain a handle to a valid public key. + /// + /// + /// NTE_BAD_SIGNATURE + /// + /// 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. + /// + /// + /// + /// NTE_BAD_UID + /// The cryptographic service provider (CSP) context that was specified when the hash object was created cannot be found. + /// + /// + /// NTE_NO_MEMORY + /// The CSP ran out of memory during the operation. + /// + /// + /// + /// + /// + /// The CryptVerifySignature 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. + /// + /// + /// If you generate a signature by using the .NET Framework APIs and try to verify it by using the CryptVerifySignature + /// function, the function will fail and GetLastError will return NTE_BAD_SIGNATURE. This is due to the different byte orders + /// between the native Win32 API and the .NET Framework API. + /// + /// + /// 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 + /// CryptVerifySignature function to verify the signature. + /// + /// Examples + /// + /// For an example that uses the CryptVerifySignature function, see Example C Program: Signing a Hash and Verifying the Hash Signature. + /// + /// + // 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(CryptGetValueMethod 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(mem.Size); + } + + /// + /// The HMAC_INFO structure specifies the hash algorithm and the inner and outer strings that are to be used to calculate the + /// HMAC hash. + /// + // 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 + { + /// Specifies the hash algorithm to be used. + public ALG_ID HashAlgid; + + /// + /// 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. + /// + public IntPtr pbInnerString; + + /// + /// The count of bytes in pbInnerString. The CSP uses the default inner string if cbInnerString is equal to zero. + /// + public uint cbInnerString; + + /// + /// 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. + /// + public IntPtr pbOuterString; + + /// + /// The count of bytes in pbOuterString. The CSP uses the default outer string if cbOuterString is equal to zero. + /// + public uint cbOuterString; + } + + /// + /// The PROV_ENUMALGS structure is used with the CryptGetProvParam function when the PP_ENUMALGS parameter is retrieved to + /// contain information about an algorithm supported by a cryptographic service provider (CSP). + /// + // 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, Size = 32, Pack = 4)] + public struct PROV_ENUMALGS + { + /// One of the ALG_ID values that identifies the algorithm. + public ALG_ID aiAlgid; + + /// The default key length, in bits, of the algorithm. + public uint dwBitLen; + + /// The length, in CHARs, of the szName string. This length includes the terminating null character. + public uint dwNameLen; + + /// A null-terminated ANSI string that contains the name of the algorithm. + public StrPtrAnsi szName; + } + + /// + /// The PROV_ENUMALGS_EX structure is used with the CryptGetProvParam function when the PP_ENUMALGS_EX parameter is + /// retrieved to contain information about an algorithm supported by a cryptographic service provider (CSP). + /// + // 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 + { + /// One of the ALG_ID values that identifies the algorithm. + public ALG_ID aiAlgid; + /// The default key length, in bits, of the algorithm. + public uint dwDefaultLen; + /// The minimum key length, in bits, of the algorithm. + public uint dwMinLen; + /// The maximum key length, in bits, of the algorithm. + public uint dwMaxLen; + /// + /// Zero or a combination of one or more of the Protocol Flags values that identifies the protocols supported by the algorithm. + /// + public uint dwProtocols; + /// The length, in CHAR s, of the szName string. This length includes the terminating null character. + public uint dwNameLen; + /// A null-terminated ANSI string that contains the name of the algorithm. + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)] + public string szName; + /// The length, in CHAR s, of the szLongName string. This length includes the terminating null character. + public uint dwLongNameLen; + /// A null-terminated ANSI string that contains the long name of the algorithm. + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 40)] + public string szLongName; + } + + /// Provides a for that is disposed using . + public class SafeHCRYPTHASH : SafeHANDLE + { + /// Initializes a new instance of the class and assigns an existing handle. + /// An object that represents the pre-existing handle to use. + /// + /// to reliably release the handle during the finalization phase; otherwise, (not recommended). + /// + public SafeHCRYPTHASH(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { } + + /// Initializes a new instance of the class. + private SafeHCRYPTHASH() : base() { } + + /// Performs an implicit conversion from to . + /// The safe handle instance. + /// The result of the conversion. + public static implicit operator HCRYPTHASH(SafeHCRYPTHASH h) => h.handle; + + /// + protected override bool InternalReleaseHandle() => CryptDestroyHash(handle); + } + + /// Provides a for that is disposed using . + public class SafeHCRYPTPROV : SafeHANDLE + { + /// Initializes a new instance of the class and assigns an existing handle. + /// An object that represents the pre-existing handle to use. + /// + /// to reliably release the handle during the finalization phase; otherwise, (not recommended). + /// + public SafeHCRYPTPROV(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { } + + /// Initializes a new instance of the class. + private SafeHCRYPTPROV() : base() { } + + /// Performs an implicit conversion from to . + /// The safe handle instance. + /// The result of the conversion. + public static implicit operator HCRYPTPROV(SafeHCRYPTPROV h) => h.handle; + + /// + protected override bool InternalReleaseHandle() => CryptReleaseContext(handle); + } } } \ No newline at end of file