diff --git a/PInvoke/Cryptography/Crypt32/Wincrypt.cs b/PInvoke/Cryptography/Crypt32/Wincrypt.cs index e652bd21..cf4db8dc 100644 --- a/PInvoke/Cryptography/Crypt32/Wincrypt.cs +++ b/PInvoke/Cryptography/Crypt32/Wincrypt.cs @@ -1674,6 +1674,150 @@ namespace Vanara.PInvoke protected override bool InternalReleaseHandle() => CertCloseStore(handle, Flag); } + /// Provides a handle to a CryptoAPI provider. + [StructLayout(LayoutKind.Sequential)] + public struct HCRYPTPROV : IHandle + { + private IntPtr handle; + + /// Initializes a new instance of the struct. + /// An object that represents the pre-existing handle to use. + public HCRYPTPROV(IntPtr preexistingHandle) => handle = preexistingHandle; + + /// Returns an invalid handle by instantiating a object with . + public static HCRYPTPROV NULL => new HCRYPTPROV(IntPtr.Zero); + + /// Gets a value indicating whether this instance is a null handle. + public bool IsNull => handle == IntPtr.Zero; + + /// Performs an explicit conversion from to . + /// The handle. + /// The result of the conversion. + public static explicit operator IntPtr(HCRYPTPROV h) => h.handle; + + /// Performs an implicit conversion from to . + /// The pointer to a handle. + /// The result of the conversion. + public static implicit operator HCRYPTPROV(IntPtr h) => new HCRYPTPROV(h); + + /// Implements the operator !=. + /// The first handle. + /// The second handle. + /// The result of the operator. + public static bool operator !=(HCRYPTPROV h1, HCRYPTPROV h2) => !(h1 == h2); + + /// Implements the operator ==. + /// The first handle. + /// The second handle. + /// The result of the operator. + public static bool operator ==(HCRYPTPROV h1, HCRYPTPROV h2) => h1.Equals(h2); + + /// + public override bool Equals(object obj) => obj is HCRYPTPROV h ? handle == h.handle : false; + + /// + public override int GetHashCode() => handle.GetHashCode(); + + /// + public IntPtr DangerousGetHandle() => handle; + } + + /// Provides a handle to a CryptoApi key. + [StructLayout(LayoutKind.Sequential)] + public struct HCRYPTKEY : IHandle + { + private IntPtr handle; + + /// Initializes a new instance of the struct. + /// An object that represents the pre-existing handle to use. + public HCRYPTKEY(IntPtr preexistingHandle) => handle = preexistingHandle; + + /// Returns an invalid handle by instantiating a object with . + public static HCRYPTKEY NULL => new HCRYPTKEY(IntPtr.Zero); + + /// Gets a value indicating whether this instance is a null handle. + public bool IsNull => handle == IntPtr.Zero; + + /// Performs an explicit conversion from to . + /// The handle. + /// The result of the conversion. + public static explicit operator IntPtr(HCRYPTKEY h) => h.handle; + + /// Performs an implicit conversion from to . + /// The pointer to a handle. + /// The result of the conversion. + public static implicit operator HCRYPTKEY(IntPtr h) => new HCRYPTKEY(h); + + /// Implements the operator !=. + /// The first handle. + /// The second handle. + /// The result of the operator. + public static bool operator !=(HCRYPTKEY h1, HCRYPTKEY h2) => !(h1 == h2); + + /// Implements the operator ==. + /// The first handle. + /// The second handle. + /// The result of the operator. + public static bool operator ==(HCRYPTKEY h1, HCRYPTKEY h2) => h1.Equals(h2); + + /// + public override bool Equals(object obj) => obj is HCRYPTKEY h ? handle == h.handle : false; + + /// + public override int GetHashCode() => handle.GetHashCode(); + + /// + public IntPtr DangerousGetHandle() => handle; + } + + /// Provides a handle to a CryptoApi hash. + [StructLayout(LayoutKind.Sequential)] + public struct HCRYPTHASH : IHandle + { + private IntPtr handle; + + /// Initializes a new instance of the struct. + /// An object that represents the pre-existing handle to use. + public HCRYPTHASH(IntPtr preexistingHandle) => handle = preexistingHandle; + + /// Returns an invalid handle by instantiating a object with . + public static HCRYPTHASH NULL => new HCRYPTHASH(IntPtr.Zero); + + /// Gets a value indicating whether this instance is a null handle. + public bool IsNull => handle == IntPtr.Zero; + + /// Performs an explicit conversion from to . + /// The handle. + /// The result of the conversion. + public static explicit operator IntPtr(HCRYPTHASH h) => h.handle; + + /// Performs an implicit conversion from to . + /// The pointer to a handle. + /// The result of the conversion. + public static implicit operator HCRYPTHASH(IntPtr h) => new HCRYPTHASH(h); + + /// Implements the operator !=. + /// The first handle. + /// The second handle. + /// The result of the operator. + public static bool operator !=(HCRYPTHASH h1, HCRYPTHASH h2) => !(h1 == h2); + + /// Implements the operator ==. + /// The first handle. + /// The second handle. + /// The result of the operator. + public static bool operator ==(HCRYPTHASH h1, HCRYPTHASH h2) => h1.Equals(h2); + + /// + public override bool Equals(object obj) => obj is HCRYPTHASH h ? handle == h.handle : false; + + /// + public override int GetHashCode() => handle.GetHashCode(); + + /// + public IntPtr DangerousGetHandle() => handle; + } + /*CertAddCertificateContextToStore CertAddCertificateLinkToStore CertAddCRLContextToStore diff --git a/PInvoke/Cryptography/NCrypt/NCrypt.cs b/PInvoke/Cryptography/NCrypt/NCrypt.cs index 7136a589..2a3ad86a 100644 --- a/PInvoke/Cryptography/NCrypt/NCrypt.cs +++ b/PInvoke/Cryptography/NCrypt/NCrypt.cs @@ -9,13 +9,146 @@ namespace Vanara.PInvoke /// Methods and data types found in NCrypt.dll. public static partial class NCrypt { + /// A custom function that can allocate memory. + /// Size of the memory to allocate. + /// Pointer to the allocated memory. + [PInvokeData("ncrypt.h")] [UnmanagedFunctionPointer(CallingConvention.Winapi)] public delegate IntPtr PFN_NCRYPT_ALLOC(SizeT cbSize); + /// A custom function that can free allocated memory. + /// Pointer to the allocated memory. + [PInvokeData("ncrypt.h")] [UnmanagedFunctionPointer(CallingConvention.Winapi)] public delegate void PFN_NCRYPT_FREE(IntPtr pv); - public enum BufferType + /// Flags used with NCryptCreatePersistedKey. + [PInvokeData("ncrypt.h")] + [Flags] + public enum CreatePersistedFlags + { + /// The key applies to the local computer. If this flag is not present, the key applies to the current user. + NCRYPT_MACHINE_KEY_FLAG = 0x00000020, + + /// + /// If a key already exists in the container with the specified name, the existing key will be overwritten. If this flag is not + /// specified and a key with the specified name already exists, this function will return NTE_EXISTS. + /// + NCRYPT_OVERWRITE_KEY_FLAG = 0x00000080, + } + + /// A set of flags that specify the export policy for a persisted key. This property only applies to keys. + [PInvokeData("ncrypt.h")] + [Flags] + public enum ExportPolicy + { + /// The private key can be exported. + NCRYPT_ALLOW_EXPORT_FLAG = 0x00000001, + + /// The private key can be exported in plaintext form. + NCRYPT_ALLOW_PLAINTEXT_EXPORT_FLAG = 0x00000002, + + /// + /// The private key can be exported once for archiving purposes. This flag only applies to the original key handle on which it is + /// set. This policy can only be applied to the original key handle. After the key handle has been closed, the key can no longer + /// be exported for archiving purposes. + /// + NCRYPT_ALLOW_ARCHIVING_FLAG = 0x00000004, + + /// + /// The private key can be exported once in plaintext form for archiving purposes. This flag only applies to the original key + /// handle on which it is set. This policy can only be applied to the original key handle. After the key handle has been closed, + /// the key can no longer be exported for archiving purposes. + /// + NCRYPT_ALLOW_PLAINTEXT_ARCHIVING_FLAG = 0x00000008, + } + + /// Flags for NCryptFinalizeKey. + [PInvokeData("ncrypt.h", MSDNShortId = "4386030d-4ce6-4b2e-adc5-a15ddc869349")] + [Flags] + public enum FinalizeKeyFlags + { + /// + /// Also save the key in legacy storage. This allows the key to be used with CryptoAPI. This flag only applies to RSA keys. + /// + NCRYPT_WRITE_KEY_TO_LEGACY_STORE_FLAG = 0x00000200, + + /// Do not validate the public portion of the key pair. This flag only applies to public/private key pairs. + NCRYPT_NO_KEY_VALIDATION = 0x00000008, + + /// + /// Requests that the key service provider (KSP) not display any user interface. If the provider must display the UI to operate, + /// the call fails and the KSP should set the NTE_SILENT_CONTEXT error code as the last error. + /// + NCRYPT_SILENT_FLAG = 0x00000040, + } + + /// Flags for NCryptGetProperty. + [PInvokeData("ncrypt.h", MSDNShortId = "7b857ce0-8525-489b-9987-ef40081a5577")] + [Flags] + public enum GetPropertyFlags : uint + { + /// + /// Ignore any built in values for this property and only retrieve the user-persisted properties of the key. The maximum size of + /// the data for any persisted property is NCRYPT_MAX_PROPERTY_DATA bytes. + /// + NCRYPT_PERSIST_ONLY_FLAG = 0x40000000, + + /// + /// Requests that the key service provider (KSP) not display any user interface. If the provider must display the UI to operate, + /// the call fails and the KSP should set the NTE_SILENT_CONTEXT error code as the last error. + /// + NCRYPT_SILENT_FLAG = 0x00000040, + + /// + /// Retrieve the security identifier (SID) of the object's owner. Use the GetSecurityDescriptorOwner function to obtain the owner + /// SID from the SECURITY_DESCRIPTOR structure. + /// + OWNER_SECURITY_INFORMATION = SECURITY_INFORMATION.OWNER_SECURITY_INFORMATION, + + /// + /// Retrieve the SID of the object's primary group. Use the GetSecurityDescriptorGroup function to obtain the group SID from the + /// SECURITY_DESCRIPTOR structure. + /// + GROUP_SECURITY_INFORMATION = SECURITY_INFORMATION.GROUP_SECURITY_INFORMATION, + + /// + /// Retrieve the discretionary access control list (DACL). Use the GetSecurityDescriptorSacl function to obtain the DACL from the + /// SECURITY_DESCRIPTOR structure. + /// + DACL_SECURITY_INFORMATION = SECURITY_INFORMATION.DACL_SECURITY_INFORMATION, + + /// + /// Retrieve the system access control list (SACL). Use the GetSecurityDescriptorDacl function to obtain the SACL from the + /// SECURITY_DESCRIPTOR structure. + /// + SACL_SECURITY_INFORMATION = SECURITY_INFORMATION.SACL_SECURITY_INFORMATION, + } + + /// A set of flags that define implementation details of the provider. This property only applies to key storage providers. + [PInvokeData("ncrypt.h")] + [Flags] + public enum ImplType + { + /// The provider is hardware based. + NCRYPT_IMPL_HARDWARE_FLAG = 0x00000001, + + /// The provider is software based. + NCRYPT_IMPL_SOFTWARE_FLAG = 0x00000002, + + /// The provider is removable. + NCRYPT_IMPL_REMOVABLE_FLAG = 0x00000008, + + /// The provider is a hardware based random number generator. + NCRYPT_IMPL_HARDWARE_RNG_FLAG = 0x00000010, + + /// Undocumented. + NCRYPT_IMPL_VIRTUAL_ISOLATION_FLAG = 0x00000020, + } + + /// Key derivation function buffer types. + [PInvokeData("bcrypt.h")] + public enum KeyDerivationBufferType { /// /// The buffer is a key derivation function (KDF) parameter that contains a null-terminated Unicode string that identifies the @@ -209,64 +342,16 @@ namespace Vanara.PInvoke NCRYPTBUFFER_TPM_PLATFORM_CLAIM_STATIC_CREATE = 82, } - /// Flags used with NCryptCreatePersistedKey. + /// Flags for NCryptKeyDerivation. + [PInvokeData("ncrypt.h", MSDNShortId = "5D2D61B1-022E-412F-A19E-11057930A615")] [Flags] - public enum CreatePersistedFlags - { - /// The key applies to the local computer. If this flag is not present, the key applies to the current user. - NCRYPT_MACHINE_KEY_FLAG = 0x00000020, - - /// - /// If a key already exists in the container with the specified name, the existing key will be overwritten. If this flag is not - /// specified and a key with the specified name already exists, this function will return NTE_EXISTS. - /// - NCRYPT_OVERWRITE_KEY_FLAG = 0x00000080, - } - - /// Flags for NCryptDeleteKey. - [Flags] - public enum DeleteKeyFlags : uint + public enum KeyDerivationFlags { /// - /// Requests that the key service provider (KSP) not display any user interface. If the provider must display the UI to operate, - /// the call fails and the KSP should set the NTE_SILENT_CONTEXT error code as the last error. + /// Specifies that the target algorithm is AES and that the key therefore must be double expanded. This flag is only valid with + /// the CAPI_KDF algorithm. /// - NCRYPT_SILENT_FLAG = 0x00000040, - } - - /// Flags for NCryptExportKey. - [PInvokeData("ncrypt.h", MSDNShortId = "1588eb29-4026-4d1c-8bee-a035df38444a")] - [Flags] - public enum ExportKeyFlags - { - /// - /// Requests that the key service provider (KSP) not display any user interface. If the provider must display the UI to operate, - /// the call fails and the KSP should set the NTE_SILENT_CONTEXT error code as the last error. - /// - NCRYPT_SILENT_FLAG = 0x00000040, - } - - [Flags] - public enum ExportPolicy - { - NCRYPT_ALLOW_EXPORT_FLAG = 0x00000001, - NCRYPT_ALLOW_PLAINTEXT_EXPORT_FLAG = 0x00000002, - NCRYPT_ALLOW_ARCHIVING_FLAG = 0x00000004, - NCRYPT_ALLOW_PLAINTEXT_ARCHIVING_FLAG = 0x00000008, - } - - /// Flags for NCryptFinalizeKey. - [PInvokeData("ncrypt.h", MSDNShortId = "4386030d-4ce6-4b2e-adc5-a15ddc869349")] - [Flags] - public enum FinalizeKeyFlags - { - /// - /// Also save the key in legacy storage. This allows the key to be used with CryptoAPI. This flag only applies to RSA keys. - /// - NCRYPT_WRITE_KEY_TO_LEGACY_STORE_FLAG = 0x00000200, - - /// Do not validate the public portion of the key pair. This flag only applies to public/private key pairs. - NCRYPT_NO_KEY_VALIDATION = 0x00000008, + BCRYPT_CAPI_AES_FLAG = 0x00000010, /// /// Requests that the key service provider (KSP) not display any user interface. If the provider must display the UI to operate, @@ -275,36 +360,79 @@ namespace Vanara.PInvoke NCRYPT_SILENT_FLAG = 0x00000040, } - [Flags] - public enum ImplType - { - NCRYPT_IMPL_HARDWARE_FLAG = 0x00000001, - NCRYPT_IMPL_SOFTWARE_FLAG = 0x00000002, - NCRYPT_IMPL_REMOVABLE_FLAG = 0x00000008, - NCRYPT_IMPL_HARDWARE_RNG_FLAG = 0x00000010, - NCRYPT_IMPL_VIRTUAL_ISOLATION_FLAG = 0x00000020, - } - - /// Flags for NCryptImportKey. - [PInvokeData("ncrypt.h", MSDNShortId = "ede0e7e0-cb2c-44c0-b724-58db3480b781")] - [Flags] - public enum ImportKeyFlags - { - /// - /// Requests that the key service provider (KSP) not display any user interface. If the provider must display the UI to operate, - /// the call fails and the KSP should set the NTE_SILENT_CONTEXT error code as the last error. - /// - NCRYPT_SILENT_FLAG = 0x00000040, - } - + /// A set of flags that define the usage details for a key. This property only applies to keys. + [PInvokeData("ncrypt.h")] [Flags] public enum KeyUsage { + /// The key can be used for decryption. NCRYPT_ALLOW_DECRYPT_FLAG = 0x00000001, + + /// The key can be used for signing. NCRYPT_ALLOW_SIGNING_FLAG = 0x00000002, + + /// The key can be used for secret agreement encryption. NCRYPT_ALLOW_KEY_AGREEMENT_FLAG = 0x00000004, - NCRYPT_ALLOW_KEY_IMPORT_FLAG = 0x00000008, + + /// The key can be used for any purpose. NCRYPT_ALLOW_ALL_USAGES = 0x00ffffff, + + /// Undocumented. + NCRYPT_ALLOW_KEY_IMPORT_FLAG = 0x00000008, + } + + /// Flags that modify function behavior. The allowed set of flags depends on the type of key specified by the hKey parameter. + [PInvokeData("ncrypt.h", MSDNShortId = "02c309bc-8c94-4c0f-901f-e024c83c824a")] + [Flags] + public enum NCryptDecryptFlag + { + /// No padding was used when the data was encrypted. The pPaddingInfo parameter is not used. + NCRYPT_NO_PADDING_FLAG = 0x00000001, + + /// + /// The data was padded with a random number to round out the block size when the data was encrypted. The pPaddingInfo parameter + /// is not used. + /// + NCRYPT_PAD_PKCS1_FLAG = 0x00000002, + + /// + /// The Optimal Asymmetric Encryption Padding (OAEP) scheme was used when the data was encrypted. The pPaddingInfo parameter is a + /// pointer to a BCRYPT_OAEP_PADDING_INFO structure. + /// + NCRYPT_PAD_OAEP_FLAG = 0x00000004, + + /// + /// The Probabilistic Signature Scheme (PSS) padding scheme was used when the signature was created. The pPaddingInfo parameter + /// is a pointer to a BCRYPT_PSS_PADDING_INFO structure. + /// + NCRYPT_PAD_PSS_FLAG = 0x00000008, + + /// + NCRYPT_PAD_CIPHER_FLAG = 0x00000010, + + /// + NCRYPT_ATTESTATION_FLAG = 0x00000020, + + /// + /// Requests that the key service provider (KSP) not display any user interface. If the provider must display the UI to operate, + /// the call fails and the KSP should set the NTE_SILENT_CONTEXT error code as the last error. + /// + NCRYPT_SILENT_FLAG = 0x00000040, + + /// + NCRYPT_SEALING_FLAG = 0x00000100, + } + + /// Flags for NCrypt functions that can show a UI. + [PInvokeData("ncrypt.h")] + [Flags] + public enum NCryptUIFlags : uint + { + /// + /// Requests that the key service provider (KSP) not display any user interface. If the provider must display the UI to operate, + /// the call fails and the KSP should set the NTE_SILENT_CONTEXT error code as the last error. + /// + NCRYPT_SILENT_FLAG = 0x00000040, } /// Flags used with NCryptOpenKey. @@ -321,18 +449,6 @@ namespace Vanara.PInvoke NCRYPT_MACHINE_KEY_FLAG = 0x00000020, } - /// Flags for NCryptSecretAgreement. - [PInvokeData("ncrypt.h")] - [Flags] - public enum SecretAgreementFlags - { - /// - /// Requests that the key service provider (KSP) not display any user interface. If the provider must display the UI to operate, - /// the call fails and the KSP should set the NTE_SILENT_CONTEXT error code as the last error. - /// - NCRYPT_SILENT_FLAG = 0x00000040, - } - /// Used by NCryptSetProperty. [PInvokeData("ncrypt.h", MSDNShortId = "ad1148aa-5f64-4867-9e17-6b41cc0c20b7")] [Flags] @@ -359,12 +475,24 @@ namespace Vanara.PInvoke NCRYPT_PERSIST_FLAG = 0x80000000, } + /// A set of flags that provide additional user interface information or requirements. + [PInvokeData("ncrypt.h")] [Flags] public enum UIPolicy { + /// Display the strong key user interface as needed. NCRYPT_UI_PROTECT_KEY_FLAG = 0x00000001, + + /// Force high protection. NCRYPT_UI_FORCE_HIGH_PROTECTION_FLAG = 0x00000002, + + /// Undocumented. NCRYPT_UI_FINGERPRINT_PROTECTION_FLAG = 0x00000004, + + /// + /// An app container has accessed a medium key that is not strongly protected. For example, a key that is for user consent only, + /// or is password or fingerprint protected. + /// NCRYPT_UI_APPCONTAINER_ACCESS_MEDIUM_FLAG = 0x00000008, } @@ -404,6 +532,29 @@ namespace Vanara.PInvoke NCRYPT_USE_PER_BOOT_KEY_FLAG = 0x00040000, } + /// + /// + /// [Some information relates to pre-released product which may be substantially modified before it's commercially released. + /// Microsoft makes no warranties, express or implied, with respect to the information provided here.] + /// + /// Creates a key attestation claim. + /// + /// The subject key handle that the claim is created for. + /// The authority key handle that the claim is based on. + /// The type of claim. + /// An optional parameter list. + /// Output of the created claim blob. + /// + /// The output of the created claim blob. + /// As of Windows 10, no flags are defined. This parameter should be set to 0. + /// Returns a status code that indicates the success or failure of the function. + // https://docs.microsoft.com/en-us/windows/win32/api/ncrypt/nf-ncrypt-ncryptcreateclaim SECURITY_STATUS NCryptCreateClaim( + // NCRYPT_KEY_HANDLE hSubjectKey, NCRYPT_KEY_HANDLE hAuthorityKey, DWORD dwClaimType, NCryptBufferDesc *pParameterList, PBYTE + // pbClaimBlob, DWORD cbClaimBlob, DWORD *pcbResult, DWORD dwFlags ); + [DllImport(Lib.Ncrypt, SetLastError = false, ExactSpelling = true)] + [PInvokeData("ncrypt.h", MSDNShortId = "EBEE3A67-0693-4B85-88B1-580CB2152703")] + public static extern HRESULT NCryptCreateClaim(NCRYPT_KEY_HANDLE hSubjectKey, NCRYPT_KEY_HANDLE hAuthorityKey, uint dwClaimType, [Optional] NCryptBufferDesc[] pParameterList, IntPtr pbClaimBlob, uint cbClaimBlob, out uint pcbResult, uint dwFlags = 0); + /// /// The NCryptCreatePersistedKey function creates a new key and stores it in the specified key storage provider. After you /// create a key by using this function, you can use the NCryptSetProperty function to set its properties; however, the key cannot be @@ -518,6 +669,123 @@ namespace Vanara.PInvoke [PInvokeData("ncrypt.h", MSDNShortId = "eeb1842f-fd9e-4edf-9db8-7b4e91760e9b")] public static extern HRESULT NCryptCreatePersistedKey(NCRYPT_PROV_HANDLE hProvider, out SafeNCRYPT_KEY_HANDLE phKey, string pszAlgId, [Optional] string pszKeyName, Crypt32.PrivateKeyType dwLegacyKeySpec = 0, CreatePersistedFlags dwFlags = 0); + /// The NCryptDecrypt function decrypts a block of encrypted data. + /// The handle of the key to use to decrypt the data. + /// + /// The address of a buffer that contains the data to be decrypted. The cbInput parameter contains the size of the data to decrypt. + /// For more information, see Remarks. + /// + /// The number of bytes in the pbInput buffer to decrypt. + /// + /// A pointer to a structure that contains padding information. The actual type of structure this parameter points to depends on the + /// value of the dwFlags parameter. This parameter is only used with asymmetric keys and must be NULL otherwise. + /// + /// + /// + /// The address of a buffer that will receive the decrypted data produced by this function. The cbOutput parameter contains the size + /// of this buffer. For more information, see Remarks. + /// + /// + /// If this parameter is NULL, this function will calculate the size needed for the decrypted data and return the size in the + /// location pointed to by the pcbResult parameter. + /// + /// + /// The size, in bytes, of the pbOutput buffer. This parameter is ignored if the pbOutput parameter is NULL. + /// + /// A pointer to a DWORD variable that receives the number of bytes copied to the pbOutput buffer. If pbOutput is NULL, + /// this receives the size, in bytes, required for the decrypted data. + /// + /// + /// Flags that modify function behavior. The allowed set of flags depends on the type of key specified by the hKey parameter. + /// If the key is an asymmetric key, this can be one of the following values. + /// + /// + /// Value + /// Meaning + /// + /// + /// NCRYPT_NO_PADDING_FLAG + /// No padding was used when the data was encrypted. The pPaddingInfo parameter is not used. + /// + /// + /// NCRYPT_PAD_OAEP_FLAG + /// + /// The Optimal Asymmetric Encryption Padding (OAEP) scheme was used when the data was encrypted. The pPaddingInfo parameter is a + /// pointer to a BCRYPT_OAEP_PADDING_INFO structure. + /// + /// + /// + /// NCRYPT_PAD_PKCS1_FLAG + /// + /// The data was padded with a random number to round out the block size when the data was encrypted. The pPaddingInfo parameter is + /// not used. + /// + /// + /// + /// The following value can be used for any key. + /// + /// + /// Value + /// Meaning + /// + /// + /// NCRYPT_SILENT_FLAG + /// + /// Requests that the key service provider (KSP) not display any user interface. If the provider must display the UI to operate, the + /// call fails and the KSP should set the NTE_SILENT_CONTEXT error code as the last error. + /// + /// + /// + /// + /// + /// Returns a status code that indicates the success or failure of the function. + /// Possible return codes include, but are not limited to, the following. + /// + /// + /// Return code + /// Description + /// + /// + /// ERROR_SUCCESS + /// The function was successful. + /// + /// + /// NTE_BAD_FLAGS + /// The dwFlags parameter contains a value that is not valid. + /// + /// + /// NTE_BUFFER_TOO_SMALL + /// The size specified by the cbOutput parameter is not large enough to hold the decrypted data. + /// + /// + /// NTE_INVALID_HANDLE + /// The hKey parameter is not valid. + /// + /// + /// NTE_INVALID_PARAMETER + /// One or more parameters are not valid. + /// + /// + /// NTE_PERM + /// The key identified by the hKey parameter cannot be used for decryption. + /// + /// + /// + /// + /// + /// The pbInput and pbOutput parameters can point to the same buffer. In this case, this function will perform the decryption in place. + /// + /// + /// A service must not call this function from its StartService Function. If a service calls this function from its StartService + /// function, a deadlock can occur, and the service may stop responding. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/api/ncrypt/nf-ncrypt-ncryptdecrypt SECURITY_STATUS NCryptDecrypt( NCRYPT_KEY_HANDLE + // hKey, PBYTE pbInput, DWORD cbInput, VOID *pPaddingInfo, PBYTE pbOutput, DWORD cbOutput, DWORD *pcbResult, DWORD dwFlags ); + [DllImport(Lib.Ncrypt, SetLastError = false, ExactSpelling = true)] + [PInvokeData("ncrypt.h", MSDNShortId = "02c309bc-8c94-4c0f-901f-e024c83c824a")] + public static extern HRESULT NCryptDecrypt(NCRYPT_KEY_HANDLE hKey, IntPtr pbInput, uint cbInput, IntPtr pPaddingInfo, IntPtr pbOutput, uint cbOutput, out uint pcbResult, NCryptDecryptFlag dwFlags); + /// The NCryptDeleteKey function deletes a CNG key. /// /// The handle of the key to delete. This handle is obtained by using the NCryptOpenKey function. @@ -574,7 +842,7 @@ namespace Vanara.PInvoke // NCRYPT_KEY_HANDLE hKey, DWORD dwFlags ); [DllImport(Lib.Ncrypt, SetLastError = false, ExactSpelling = true)] [PInvokeData("ncrypt.h", MSDNShortId = "2e1958a7-51e0-4731-b4cf-a90d6c1f9ae0")] - public static extern HRESULT NCryptDeleteKey(NCRYPT_KEY_HANDLE hKey, DeleteKeyFlags dwFlags = 0); + public static extern HRESULT NCryptDeleteKey(NCRYPT_KEY_HANDLE hKey, NCryptUIFlags dwFlags = 0); /// /// @@ -1094,175 +1362,168 @@ namespace Vanara.PInvoke public static extern HRESULT NCryptDeriveKey(NCRYPT_SECRET_HANDLE hSharedSecret, [MarshalAs(UnmanagedType.LPWStr)] string pwszKDF, [Optional] NCryptBufferDesc pParameterList, [Optional] IntPtr pbDerivedKey, [Optional] uint cbDerivedKey, out uint pcbResult, BCrypt.DeriveKeyFlags dwFlags); - /// - /// The NCryptExportKey function exports a CNG key to a memory BLOB. - /// - /// - /// A handle of the key to export. + /// The NCryptEncrypt function encrypts a block of data. + /// The handle of the key to use to encrypt the data. + /// + /// The address of a buffer that contains the data to be encrypted. The cbInput parameter contains the size of the data to encrypt. + /// For more information, see Remarks. /// - /// - /// - /// A handle to a cryptographic key of the destination user. The key data within the exported key BLOB is encrypted by using this - /// key. This ensures that only the destination user is able to make use of the key BLOB. - /// - /// - /// - /// - /// A null-terminated Unicode string that contains an identifier that specifies the type of BLOB to export. This can be one of the - /// following values. - /// - /// BCRYPT_DH_PRIVATE_BLOB - /// - /// Export a Diffie-Hellman public/private key pair. The pbOutput buffer receives a BCRYPT_DH_KEY_BLOB structure immediately followed - /// by the key data. - /// - /// BCRYPT_DH_PUBLIC_BLOB - /// - /// Export a Diffie-Hellman public key. The pbOutput buffer receives a BCRYPT_DH_KEY_BLOB structure immediately followed by the key data. - /// - /// BCRYPT_DSA_PRIVATE_BLOB - /// - /// Export a DSA public/private key pair. The pbOutput buffer receives a BCRYPT_DSA_KEY_BLOB structure immediately followed by the - /// key data. - /// - /// BCRYPT_DSA_PUBLIC_BLOB - /// - /// Export a DSA public key. The pbOutput buffer receives a BCRYPT_DSA_KEY_BLOB structure immediately followed by the key data. - /// - /// BCRYPT_ECCPRIVATE_BLOB - /// - /// Export an elliptic curve cryptography (ECC) private key. The pbOutput buffer receives a BCRYPT_ECCKEY_BLOB structure immediately - /// followed by the key data. - /// - /// BCRYPT_ECCPUBLIC_BLOB - /// - /// Export an ECC public key. The pbOutput buffer receives a BCRYPT_ECCKEY_BLOB structure immediately followed by the key data. - /// - /// BCRYPT_PUBLIC_KEY_BLOB - /// - /// Export a generic public key of any type. The type of key in this BLOB is determined by the Magic member of the - /// BCRYPT_KEY_BLOB structure. - /// - /// BCRYPT_PRIVATE_KEY_BLOB - /// - /// Export a generic private key of any type. The private key does not necessarily contain the public key. The type of key in this - /// BLOB is determined by the Magic member of the BCRYPT_KEY_BLOB structure. - /// - /// BCRYPT_RSAFULLPRIVATE_BLOB - /// - /// Export a full RSA public/private key pair. The pbOutput buffer receives a BCRYPT_RSAKEY_BLOB structure immediately followed by - /// the key data. This BLOB will include additional key material compared to the BCRYPT_RSAPRIVATE_BLOB type. - /// - /// BCRYPT_RSAPRIVATE_BLOB - /// - /// Export an RSA public/private key pair. The pbOutput buffer receives a BCRYPT_RSAKEY_BLOB structure immediately followed by the - /// key data. - /// - /// BCRYPT_RSAPUBLIC_BLOB - /// - /// Export an RSA public key. The pbOutput buffer receives a BCRYPT_RSAKEY_BLOB structure immediately followed by the key data. - /// - /// LEGACY_DH_PRIVATE_BLOB - /// - /// Export a legacy Diffie-Hellman Version 3 Private Key BLOB that contains a Diffie-Hellman public/private key pair that can be - /// imported by using CryptoAPI. - /// - /// LEGACY_DH_PUBLIC_BLOB - /// - /// Export a legacy Diffie-Hellman Version 3 Private Key BLOB that contains a Diffie-Hellman public key that can be imported by using CryptoAPI. - /// - /// LEGACY_DSA_PRIVATE_BLOB - /// Export a DSA public/private key pair in a form that can be imported by using CryptoAPI. - /// LEGACY_DSA_PUBLIC_BLOB - /// Export a DSA public key in a form that can be imported by using CryptoAPI. - /// LEGACY_RSAPRIVATE_BLOB - /// Export an RSA public/private key pair in a form that can be imported by using CryptoAPI. - /// LEGACY_RSAPUBLIC_BLOB - /// Export an RSA public key in a form that can be imported by using CryptoAPI. - /// NCRYPT_CIPHER_KEY_BLOB - /// Export a cipher key in a NCRYPT_KEY_BLOB_HEADER structure. - /// Windows 8 and Windows Server 2012: Support for this value begins. - /// NCRYPT_OPAQUETRANSPORT_BLOB - /// - /// Export a key in a format that is specific to a single CSP and is suitable for transport. Opaque BLOBs are not transferable and - /// must be imported by using the same CSP that generated the BLOB. - /// - /// NCRYPT_PKCS7_ENVELOPE_BLOB - /// - /// Export a PKCS #7 envelope BLOB. The parameters identified by the pParameterList parameter either can or must contain the - /// following parameters, as indicated by the Required or optional column. - /// - /// - /// - /// Parameter - /// Required or optional - /// - /// - /// NCRYPTBUFFER_CERT_BLOB - /// Required - /// - /// - /// NCRYPTBUFFER_PKCS_ALG_OID - /// Required - /// - /// - /// NCRYPTBUFFER_PKCS_ALG_PARAM - /// Optional - /// - /// - /// NCRYPT_PKCS8_PRIVATE_KEY_BLOB - /// - /// Export a PKCS #8 private key BLOB. The parameters identified by the pParameterList parameter either can or must contain the - /// following parameters, as indicated by the Required or optional column. - /// - /// - /// - /// Parameter - /// Required or optional - /// - /// - /// NCRYPTBUFFER_PKCS_ALG_OID - /// Optional - /// - /// - /// NCRYPTBUFFER_PKCS_ALG_PARAM - /// Optional - /// - /// - /// NCRYPTBUFFER_PKCS_SECRET - /// Optional - /// - /// - /// NCRYPT_PROTECTED_KEY_BLOB - /// Export a protected key in a NCRYPT_KEY_BLOB_HEADER structure. - /// Windows 8 and Windows Server 2012: Support for this value begins. - /// - /// - /// - /// The address of an NCryptBufferDesc structure that receives parameter information for the key. This parameter can be NULL - /// if this information is not needed. - /// + /// The number of bytes in the pbInput buffer to encrypt. + /// + /// A pointer to a structure that contains padding information. The actual type of structure this parameter points to depends on the + /// value of the dwFlags parameter. This parameter is only used with asymmetric keys and must be NULL otherwise. /// /// /// - /// The address of a buffer that receives the key BLOB. The cbOutput parameter contains the size of this buffer. If this parameter is - /// NULL, this function will place the required size, in bytes, in the DWORD pointed to by the pcbResult parameter. + /// The address of a buffer that will receive the encrypted data produced by this function. The cbOutput parameter contains the size + /// of this buffer. For more information, see Remarks. /// - /// - /// - /// The size, in bytes, of the pbOutput buffer. - /// - /// /// - /// The address of a DWORD variable that receives the number of bytes copied to the pbOutput buffer. If the pbOutput parameter - /// is NULL, this function will place the required size, in bytes, in the DWORD pointed to by this parameter. + /// If this parameter is NULL, this function will calculate the size needed for the encrypted data and return the size in the + /// location pointed to by the pcbResult parameter. /// /// + /// The size, in bytes, of the pbOutput buffer. This parameter is ignored if the pbOutput parameter is NULL. + /// + /// A pointer to a DWORD variable that receives the number of bytes copied to the pbOutput buffer. If pbOutput is NULL, + /// this receives the size, in bytes, required for the ciphertext. + /// /// + /// Flags that modify function behavior. The allowed set of flags depends on the type of key specified by the hKey parameter. + /// If the key is an asymmetric key, this can be one of the following values. + /// + /// + /// Value + /// Meaning + /// + /// + /// NCRYPT_NO_PADDING_FLAG + /// + /// Do not use any padding. The pPaddingInfo parameter is not used. If you specify the NCRYPT_NO_PADDING_FLAG, then the NCryptEncrypt + /// function only encrypts the first N bits, where N is the length of the key that was passed as the hKey parameter. Any bits after + /// the first N bits are ignored. + /// + /// + /// + /// NCRYPT_PAD_OAEP_FLAG + /// + /// Use the Optimal Asymmetric Encryption Padding (OAEP) scheme. The pPaddingInfo parameter is a pointer to a + /// BCRYPT_OAEP_PADDING_INFO structure. + /// + /// + /// + /// NCRYPT_PAD_PKCS1_FLAG + /// The data will be padded with a random number to round out the block size. The pPaddingInfo parameter is not used. + /// + /// + /// NCRYPT_SILENT_FLAG + /// + /// Requests that the key service provider (KSP) not display any user interface. If the provider must display the UI to operate, the + /// call fails and the KSP should set the NTE_SILENT_CONTEXT error code as the last error. + /// + /// + /// + /// + /// + /// Returns a status code that indicates the success or failure of the function. + /// Possible return codes include, but are not limited to, the following. + /// + /// + /// Return code + /// Description + /// + /// + /// ERROR_SUCCESS + /// The function was successful. + /// + /// + /// NTE_BAD_FLAGS + /// The dwFlags parameter contains a value that is not valid. + /// + /// + /// NTE_BAD_KEY_STATE + /// The key identified by the hKey parameter has not been finalized or is incomplete. + /// + /// + /// NTE_BUFFER_TOO_SMALL + /// The size specified by the cbOutput parameter is not large enough to hold the encrypted data. + /// + /// + /// NTE_INVALID_HANDLE + /// The hKey parameter is not valid. + /// + /// + /// NTE_INVALID_PARAMETER + /// One or more parameters are not valid. + /// + /// + /// + /// /// - /// Flags that modify function behavior. This can be zero or a combination of one or more of the following values. The set of valid - /// flags is specific to each key storage provider. The following flag applies to all providers. + /// The pbInput and pbOutput parameters can point to the same buffer. In this case, this function will perform the encryption in + /// place. It is possible that the encrypted data size will be larger than the unencrypted data size, so the buffer must be large + /// enough to hold the encrypted data. /// + /// + /// A service must not call this function from its StartService Function. If a service calls this function from its StartService + /// function, a deadlock can occur, and the service may stop responding. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/api/ncrypt/nf-ncrypt-ncryptencrypt SECURITY_STATUS NCryptEncrypt( NCRYPT_KEY_HANDLE + // hKey, PBYTE pbInput, DWORD cbInput, VOID *pPaddingInfo, PBYTE pbOutput, DWORD cbOutput, DWORD *pcbResult, DWORD dwFlags ); + [DllImport(Lib.Ncrypt, SetLastError = false, ExactSpelling = true)] + [PInvokeData("ncrypt.h", MSDNShortId = "837fc720-2167-4ead-86ea-2c3d438f2530")] + public static extern HRESULT NCryptEncrypt(NCRYPT_KEY_HANDLE hKey, IntPtr pbInput, uint cbInput, IntPtr pPaddingInfo, IntPtr pbOutput, uint cbOutput, out uint pcbResult, NCryptDecryptFlag dwFlags); + + /// + /// The NCryptEnumAlgorithms function obtains the names of the algorithms that are supported by the specified key storage provider. + /// + /// + /// The handle of the key storage provider to enumerate the algorithms for. This handle is obtained with the + /// NCryptOpenStorageProvider function. + /// + /// + /// + /// A set of values that determine which algorithm classes to enumerate. This can be zero or a combination of one or more of the + /// following values. If dwAlgOperations is zero, all algorithms are enumerated. + /// + /// + /// + /// Value + /// Meaning + /// + /// + /// NCRYPT_CIPHER_OPERATION 0x00000001 + /// Enumerate the cipher (symmetric encryption) algorithms. + /// + /// + /// NCRYPT_HASH_OPERATION 0x00000002 + /// Enumerate the hashing algorithms. + /// + /// + /// NCRYPT_ASYMMETRIC_ENCRYPTION_OPERATION 0x00000004 + /// Enumerate the asymmetric encryption algorithms. + /// + /// + /// NCRYPT_SECRET_AGREEMENT_OPERATION 0x00000008 + /// Enumerate the secret agreement algorithms. + /// + /// + /// NCRYPT_SIGNATURE_OPERATION 0x00000010 + /// Enumerate the digital signature algorithms. + /// + /// + /// + /// The address of a DWORD that receives the number of elements in the ppAlgList array. + /// + /// + /// The address of an NCryptAlgorithmName structure pointer that receives an array of the registered algorithm names. The variable + /// pointed to by the pdwAlgCount parameter receives the number of elements in this array. + /// + /// When this memory is no longer needed, it must be freed by passing this pointer to the NCryptFreeBuffer function. + /// + /// + /// Flags that modify function behavior. This can be zero (0) or the following value. /// /// /// Value @@ -1294,38 +1555,184 @@ namespace Vanara.PInvoke /// The dwFlags parameter contains a value that is not valid. /// /// - /// NTE_BAD_KEY_STATE - /// - /// The key specified by the hKey parameter is not valid. The most common cause of this error is that the key was not completed by - /// using the NCryptFinalizeKey function. - /// - /// - /// - /// NTE_BAD_TYPE - /// The key specified by the hKey parameter cannot be exported into the BLOB type specified by the pszBlobType parameter. - /// - /// /// NTE_INVALID_HANDLE - /// The hKey or the hExportKey parameter is not valid. + /// The hProvider parameter is not valid. /// /// /// NTE_INVALID_PARAMETER /// One or more parameters are not valid. /// + /// + /// NTE_NO_MEMORY + /// A memory allocation failure occurred. + /// /// /// /// + /// A service must not call this function from its StartService Function. If a service calls this function from its StartService + /// function, a deadlock can occur, and the service may stop responding. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/ncrypt/nf-ncrypt-ncryptenumalgorithms SECURITY_STATUS NCryptEnumAlgorithms( + // NCRYPT_PROV_HANDLE hProvider, DWORD dwAlgOperations, DWORD *pdwAlgCount, NCryptAlgorithmName **ppAlgList, DWORD dwFlags ); + [DllImport(Lib.Ncrypt, SetLastError = false, ExactSpelling = true)] + [PInvokeData("ncrypt.h", MSDNShortId = "ea4f270b-c556-4f52-892a-199c9cfced26")] + public static extern HRESULT NCryptEnumAlgorithms(NCRYPT_PROV_HANDLE hProvider, BCrypt.AlgOperations dwAlgOperations, out uint pdwAlgCount, out SafeNCryptBuffer ppAlgList, NCryptDecryptFlag dwFlags); + + /// The NCryptEnumKeys function obtains the names of the keys that are stored by the provider. + /// + /// The handle of the key storage provider to enumerate the keys for. This handle is obtained with the NCryptOpenStorageProvider function. + /// + /// This parameter is not currently used and must be NULL. + /// + /// The address of a pointer to an NCryptKeyName structure that receives the name of the retrieved key. When the application has + /// finished using this memory, free it by calling the NCryptFreeBuffer function. + /// + /// + /// + /// The address of a VOID pointer that receives enumeration state information that is used in subsequent calls to this + /// function. This information only has meaning to the key storage provider and is opaque to the caller. The key storage provider + /// uses this information to determine which item is next in the enumeration. If the variable pointed to by this parameter contains + /// NULL, the enumeration is started from the beginning. + /// + /// When this memory is no longer needed, it must be freed by passing this pointer to the NCryptFreeBuffer function. + /// + /// + /// Flags that modify function behavior. This can be zero or a combination of one or more of the following values. + /// + /// + /// Value + /// Meaning + /// + /// + /// NCRYPT_MACHINE_KEY_FLAG + /// Enumerate the keys for the local computer. If this flag is not present, the current user keys are enumerated. + /// + /// + /// NCRYPT_SILENT_FLAG + /// + /// Requests that the key service provider (KSP) not display any user interface. If the provider must display the UI to operate, the + /// call fails and the KSP should set the NTE_SILENT_CONTEXT error code as the last error. + /// + /// + /// + /// + /// + /// Returns a status code that indicates the success or failure of the function. + /// Possible return codes include, but are not limited to, the following. + /// + /// + /// Return code + /// Description + /// + /// + /// ERROR_SUCCESS + /// The function was successful. + /// + /// + /// NTE_BAD_FLAGS + /// The dwFlags parameter contains a value that is not valid. + /// + /// + /// NTE_INVALID_HANDLE + /// The hProvider parameter is not valid. + /// + /// + /// NTE_INVALID_PARAMETER + /// One or more parameters are not valid. + /// + /// + /// NTE_NO_MEMORY + /// A memory allocation failure occurred. + /// + /// + /// NTE_NO_MORE_ITEMS + /// The end of the enumeration has been reached. + /// + /// + /// NTE_SILENT_CONTEXT + /// The dwFlags parameter contains the NCRYPT_SILENT_FLAG flag, but the key being enumerated requires user interaction. + /// + /// + /// + /// + /// + /// This function retrieves only one item each time it is called. The state of the enumeration is stored in the variable pointed to + /// by the ppEnumState parameter, so this must be preserved between calls to this function. When the last key stored by the provider + /// has been retrieved, this function will return NTE_NO_MORE_ITEMS the next time it is called. To start the enumeration over, + /// set the variable pointed to by the ppEnumState parameter to NULL, free the memory pointed to by the ppKeyName parameter, + /// if it is not NULL, and call this function again. + /// /// /// A service must not call this function from its StartService Function. If a service calls this function from its StartService /// function, a deadlock can occur, and the service may stop responding. /// /// - // https://docs.microsoft.com/en-us/windows/desktop/api/ncrypt/nf-ncrypt-ncryptexportkey SECURITY_STATUS NCryptExportKey( - // NCRYPT_KEY_HANDLE hKey, NCRYPT_KEY_HANDLE hExportKey, LPCWSTR pszBlobType, NCryptBufferDesc *pParameterList, PBYTE pbOutput, DWORD - // cbOutput, DWORD *pcbResult, DWORD dwFlags ); + // https://docs.microsoft.com/en-us/windows/win32/api/ncrypt/nf-ncrypt-ncryptenumkeys SECURITY_STATUS NCryptEnumKeys( + // NCRYPT_PROV_HANDLE hProvider, LPCWSTR pszScope, NCryptKeyName **ppKeyName, PVOID *ppEnumState, DWORD dwFlags ); [DllImport(Lib.Ncrypt, SetLastError = false, ExactSpelling = true)] - [PInvokeData("ncrypt.h", MSDNShortId = "1588eb29-4026-4d1c-8bee-a035df38444a")] - public static extern HRESULT NCryptExportKey(NCRYPT_KEY_HANDLE hKey, NCRYPT_KEY_HANDLE hExportKey, [MarshalAs(UnmanagedType.LPWStr)] string pszBlobType, [Optional] NCryptBufferDesc pParameterList, SafeAllocatedMemoryHandle pbOutput, uint cbOutput, out uint pcbResult, ExportKeyFlags dwFlags = 0); + [PInvokeData("ncrypt.h", MSDNShortId = "ca8c5b70-ea5e-4fb9-82d3-1de839f0d244")] + public static extern HRESULT NCryptEnumKeys(NCRYPT_PROV_HANDLE hProvider, [MarshalAs(UnmanagedType.LPWStr), Optional] string pszScope, out SafeNCryptBuffer ppKeyName, ref IntPtr ppEnumState, OpenKeyFlags dwFlags); + + /// The NCryptEnumStorageProviders function obtains the names of the registered key storage providers. + /// The address of a DWORD to receive the number of elements in the ppProviderList array. + /// + /// + /// The address of an NCryptProviderName structure pointer to receive an array of the registered key storage provider names. The + /// variable pointed to by the pdwProviderCount parameter receives the number of elements in this array. + /// + /// When this memory is no longer needed, free it by passing this pointer to the NCryptFreeBuffer function. + /// + /// + /// Flags that modify function behavior. This can be zero (0) or the following value. + /// + /// + /// Value + /// Meaning + /// + /// + /// NCRYPT_SILENT_FLAG + /// + /// Requests that the key service provider (KSP) not display any user interface. If the provider must display the UI to operate, the + /// call fails and the KSP should set the NTE_SILENT_CONTEXT error code as the last error. + /// + /// + /// + /// + /// + /// Returns a status code that indicates the success or failure of the function. + /// Possible return codes include, but are not limited to, the following. + /// + /// + /// Return code + /// Description + /// + /// + /// ERROR_SUCCESS + /// The function was successful. + /// + /// + /// NTE_BAD_FLAGS + /// The dwFlags parameter contains a value that is not valid. + /// + /// + /// NTE_INVALID_PARAMETER + /// One or more parameters are not valid. + /// + /// + /// NTE_NO_MEMORY + /// A memory allocation failure occurred. + /// + /// + /// + /// + /// A service must not call this function from its StartService Function. If a service calls this function from its StartService + /// function, a deadlock can occur, and the service may stop responding. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/ncrypt/nf-ncrypt-ncryptenumstorageproviders SECURITY_STATUS + // NCryptEnumStorageProviders( DWORD *pdwProviderCount, NCryptProviderName **ppProviderList, DWORD dwFlags ); + [DllImport(Lib.Ncrypt, SetLastError = false, ExactSpelling = true)] + [PInvokeData("ncrypt.h", MSDNShortId = "24a8ee01-b716-4f36-9df5-b6476b1df4f0")] + public static extern HRESULT NCryptEnumStorageProviders(out uint pdwProviderCount, out SafeNCryptBuffer ppProviderList, NCryptUIFlags dwFlags); /// /// The NCryptExportKey function exports a CNG key to a memory BLOB. @@ -1558,7 +1965,240 @@ namespace Vanara.PInvoke // cbOutput, DWORD *pcbResult, DWORD dwFlags ); [DllImport(Lib.Ncrypt, SetLastError = false, ExactSpelling = true)] [PInvokeData("ncrypt.h", MSDNShortId = "1588eb29-4026-4d1c-8bee-a035df38444a")] - public static extern HRESULT NCryptExportKey(NCRYPT_KEY_HANDLE hKey, NCRYPT_KEY_HANDLE hExportKey, [MarshalAs(UnmanagedType.LPWStr)] string pszBlobType, [Optional] NCryptBufferDesc pParameterList, [Optional] IntPtr pbOutput, [Optional] uint cbOutput, out uint pcbResult, ExportKeyFlags dwFlags = 0); + public static extern HRESULT NCryptExportKey(NCRYPT_KEY_HANDLE hKey, NCRYPT_KEY_HANDLE hExportKey, [MarshalAs(UnmanagedType.LPWStr)] string pszBlobType, [Optional] NCryptBufferDesc pParameterList, SafeAllocatedMemoryHandle pbOutput, uint cbOutput, out uint pcbResult, NCryptUIFlags dwFlags = 0); + + /// + /// The NCryptExportKey function exports a CNG key to a memory BLOB. + /// + /// + /// A handle of the key to export. + /// + /// + /// + /// A handle to a cryptographic key of the destination user. The key data within the exported key BLOB is encrypted by using this + /// key. This ensures that only the destination user is able to make use of the key BLOB. + /// + /// + /// + /// + /// A null-terminated Unicode string that contains an identifier that specifies the type of BLOB to export. This can be one of the + /// following values. + /// + /// BCRYPT_DH_PRIVATE_BLOB + /// + /// Export a Diffie-Hellman public/private key pair. The pbOutput buffer receives a BCRYPT_DH_KEY_BLOB structure immediately followed + /// by the key data. + /// + /// BCRYPT_DH_PUBLIC_BLOB + /// + /// Export a Diffie-Hellman public key. The pbOutput buffer receives a BCRYPT_DH_KEY_BLOB structure immediately followed by the key data. + /// + /// BCRYPT_DSA_PRIVATE_BLOB + /// + /// Export a DSA public/private key pair. The pbOutput buffer receives a BCRYPT_DSA_KEY_BLOB structure immediately followed by the + /// key data. + /// + /// BCRYPT_DSA_PUBLIC_BLOB + /// + /// Export a DSA public key. The pbOutput buffer receives a BCRYPT_DSA_KEY_BLOB structure immediately followed by the key data. + /// + /// BCRYPT_ECCPRIVATE_BLOB + /// + /// Export an elliptic curve cryptography (ECC) private key. The pbOutput buffer receives a BCRYPT_ECCKEY_BLOB structure immediately + /// followed by the key data. + /// + /// BCRYPT_ECCPUBLIC_BLOB + /// + /// Export an ECC public key. The pbOutput buffer receives a BCRYPT_ECCKEY_BLOB structure immediately followed by the key data. + /// + /// BCRYPT_PUBLIC_KEY_BLOB + /// + /// Export a generic public key of any type. The type of key in this BLOB is determined by the Magic member of the + /// BCRYPT_KEY_BLOB structure. + /// + /// BCRYPT_PRIVATE_KEY_BLOB + /// + /// Export a generic private key of any type. The private key does not necessarily contain the public key. The type of key in this + /// BLOB is determined by the Magic member of the BCRYPT_KEY_BLOB structure. + /// + /// BCRYPT_RSAFULLPRIVATE_BLOB + /// + /// Export a full RSA public/private key pair. The pbOutput buffer receives a BCRYPT_RSAKEY_BLOB structure immediately followed by + /// the key data. This BLOB will include additional key material compared to the BCRYPT_RSAPRIVATE_BLOB type. + /// + /// BCRYPT_RSAPRIVATE_BLOB + /// + /// Export an RSA public/private key pair. The pbOutput buffer receives a BCRYPT_RSAKEY_BLOB structure immediately followed by the + /// key data. + /// + /// BCRYPT_RSAPUBLIC_BLOB + /// + /// Export an RSA public key. The pbOutput buffer receives a BCRYPT_RSAKEY_BLOB structure immediately followed by the key data. + /// + /// LEGACY_DH_PRIVATE_BLOB + /// + /// Export a legacy Diffie-Hellman Version 3 Private Key BLOB that contains a Diffie-Hellman public/private key pair that can be + /// imported by using CryptoAPI. + /// + /// LEGACY_DH_PUBLIC_BLOB + /// + /// Export a legacy Diffie-Hellman Version 3 Private Key BLOB that contains a Diffie-Hellman public key that can be imported by using CryptoAPI. + /// + /// LEGACY_DSA_PRIVATE_BLOB + /// Export a DSA public/private key pair in a form that can be imported by using CryptoAPI. + /// LEGACY_DSA_PUBLIC_BLOB + /// Export a DSA public key in a form that can be imported by using CryptoAPI. + /// LEGACY_RSAPRIVATE_BLOB + /// Export an RSA public/private key pair in a form that can be imported by using CryptoAPI. + /// LEGACY_RSAPUBLIC_BLOB + /// Export an RSA public key in a form that can be imported by using CryptoAPI. + /// NCRYPT_CIPHER_KEY_BLOB + /// Export a cipher key in a NCRYPT_KEY_BLOB_HEADER structure. + /// Windows 8 and Windows Server 2012: Support for this value begins. + /// NCRYPT_OPAQUETRANSPORT_BLOB + /// + /// Export a key in a format that is specific to a single CSP and is suitable for transport. Opaque BLOBs are not transferable and + /// must be imported by using the same CSP that generated the BLOB. + /// + /// NCRYPT_PKCS7_ENVELOPE_BLOB + /// + /// Export a PKCS #7 envelope BLOB. The parameters identified by the pParameterList parameter either can or must contain the + /// following parameters, as indicated by the Required or optional column. + /// + /// + /// + /// Parameter + /// Required or optional + /// + /// + /// NCRYPTBUFFER_CERT_BLOB + /// Required + /// + /// + /// NCRYPTBUFFER_PKCS_ALG_OID + /// Required + /// + /// + /// NCRYPTBUFFER_PKCS_ALG_PARAM + /// Optional + /// + /// + /// NCRYPT_PKCS8_PRIVATE_KEY_BLOB + /// + /// Export a PKCS #8 private key BLOB. The parameters identified by the pParameterList parameter either can or must contain the + /// following parameters, as indicated by the Required or optional column. + /// + /// + /// + /// Parameter + /// Required or optional + /// + /// + /// NCRYPTBUFFER_PKCS_ALG_OID + /// Optional + /// + /// + /// NCRYPTBUFFER_PKCS_ALG_PARAM + /// Optional + /// + /// + /// NCRYPTBUFFER_PKCS_SECRET + /// Optional + /// + /// + /// NCRYPT_PROTECTED_KEY_BLOB + /// Export a protected key in a NCRYPT_KEY_BLOB_HEADER structure. + /// Windows 8 and Windows Server 2012: Support for this value begins. + /// + /// + /// + /// The address of an NCryptBufferDesc structure that receives parameter information for the key. This parameter can be NULL + /// if this information is not needed. + /// + /// + /// + /// + /// The address of a buffer that receives the key BLOB. The cbOutput parameter contains the size of this buffer. If this parameter is + /// NULL, this function will place the required size, in bytes, in the DWORD pointed to by the pcbResult parameter. + /// + /// + /// + /// The size, in bytes, of the pbOutput buffer. + /// + /// + /// + /// The address of a DWORD variable that receives the number of bytes copied to the pbOutput buffer. If the pbOutput parameter + /// is NULL, this function will place the required size, in bytes, in the DWORD pointed to by this parameter. + /// + /// + /// + /// + /// Flags that modify function behavior. This can be zero or a combination of one or more of the following values. The set of valid + /// flags is specific to each key storage provider. The following flag applies to all providers. + /// + /// + /// + /// Value + /// Meaning + /// + /// + /// NCRYPT_SILENT_FLAG + /// + /// Requests that the key service provider (KSP) not display any user interface. If the provider must display the UI to operate, the + /// call fails and the KSP should set the NTE_SILENT_CONTEXT error code as the last error. + /// + /// + /// + /// + /// + /// Returns a status code that indicates the success or failure of the function. + /// Possible return codes include, but are not limited to, the following. + /// + /// + /// Return code + /// Description + /// + /// + /// ERROR_SUCCESS + /// The function was successful. + /// + /// + /// NTE_BAD_FLAGS + /// The dwFlags parameter contains a value that is not valid. + /// + /// + /// NTE_BAD_KEY_STATE + /// + /// The key specified by the hKey parameter is not valid. The most common cause of this error is that the key was not completed by + /// using the NCryptFinalizeKey function. + /// + /// + /// + /// NTE_BAD_TYPE + /// The key specified by the hKey parameter cannot be exported into the BLOB type specified by the pszBlobType parameter. + /// + /// + /// NTE_INVALID_HANDLE + /// The hKey or the hExportKey parameter is not valid. + /// + /// + /// NTE_INVALID_PARAMETER + /// One or more parameters are not valid. + /// + /// + /// + /// + /// + /// A service must not call this function from its StartService Function. If a service calls this function from its StartService + /// function, a deadlock can occur, and the service may stop responding. + /// + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/ncrypt/nf-ncrypt-ncryptexportkey SECURITY_STATUS NCryptExportKey( + // NCRYPT_KEY_HANDLE hKey, NCRYPT_KEY_HANDLE hExportKey, LPCWSTR pszBlobType, NCryptBufferDesc *pParameterList, PBYTE pbOutput, DWORD + // cbOutput, DWORD *pcbResult, DWORD dwFlags ); + [DllImport(Lib.Ncrypt, SetLastError = false, ExactSpelling = true)] + [PInvokeData("ncrypt.h", MSDNShortId = "1588eb29-4026-4d1c-8bee-a035df38444a")] + public static extern HRESULT NCryptExportKey(NCRYPT_KEY_HANDLE hKey, NCRYPT_KEY_HANDLE hExportKey, [MarshalAs(UnmanagedType.LPWStr)] string pszBlobType, [Optional] NCryptBufferDesc pParameterList, [Optional] IntPtr pbOutput, [Optional] uint cbOutput, out uint pcbResult, NCryptUIFlags dwFlags = 0); /// /// @@ -1626,6 +2266,36 @@ namespace Vanara.PInvoke [PInvokeData("ncrypt.h", MSDNShortId = "4386030d-4ce6-4b2e-adc5-a15ddc869349")] public static extern HRESULT NCryptFinalizeKey(NCRYPT_KEY_HANDLE hKey, FinalizeKeyFlags dwFlags = 0); + /// The NCryptFreeBuffer function releases a block of memory allocated by a CNG key storage provider. + /// The address of the memory to be released. + /// + /// Returns a status code that indicates the success or failure of the function. + /// Possible return codes include, but are not limited to, the following. + /// + /// + /// Return code + /// Description + /// + /// + /// ERROR_SUCCESS + /// The function was successful. + /// + /// + /// NTE_INVALID_PARAMETER + /// The pvInput parameter is not valid. + /// + /// + /// + /// + /// A service must not call this function from its StartService Function. If a service calls this function from its StartService + /// function, a deadlock can occur, and the service may stop responding. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/ncrypt/nf-ncrypt-ncryptfreebuffer SECURITY_STATUS NCryptFreeBuffer( PVOID + // pvInput ); + [DllImport(Lib.Ncrypt, SetLastError = false, ExactSpelling = true)] + [PInvokeData("ncrypt.h", MSDNShortId = "15f19999-cf64-4a30-b38d-9372066add0a")] + public static extern HRESULT NCryptFreeBuffer(IntPtr pvInput); + /// /// The NCryptFreeObject function frees a CNG key storage object. /// @@ -1664,46 +2334,54 @@ namespace Vanara.PInvoke [PInvokeData("ncrypt.h", MSDNShortId = "a5535cf9-ba8c-4212-badd-f1dc88903624")] public static extern HRESULT NCryptFreeObject(IntPtr hObject); - /// - /// The NCryptImportKey function imports a Cryptography API: Next Generation (CNG) key from a memory BLOB. - /// - /// - /// The handle of the key storage provider. + /// The NCryptGetProperty function retrieves the value of a named property for a key storage object. + /// + /// The handle of the object to get the property for. This can be a provider handle ( NCRYPT_PROV_HANDLE) or a key handle ( NCRYPT_KEY_HANDLE). /// - /// + /// + /// A pointer to a null-terminated Unicode string that contains the name of the property to retrieve. This can be one of the + /// predefined Key Storage Property Identifiers or a custom property identifier. + /// + /// + /// The address of a buffer that receives the property value. The cbOutput parameter contains the size of this buffer. /// - /// The handle of the cryptographic key with which the key data within the imported key BLOB was encrypted. This must be a handle to - /// the same key that was passed in the hExportKey parameter of the NCryptExportKey function. If this parameter is NULL, the - /// key BLOB is assumed to not be encrypted. + /// To calculate the size required for the buffer, set this parameter to NULL. The size, in bytes, required is returned in the + /// location pointed to by the pcbResult parameter. /// /// - /// + /// The size, in bytes, of the pbOutput buffer. + /// + /// A pointer to a DWORD variable that receives the number of bytes that were copied to the pbOutput buffer. /// - /// A null-terminated Unicode string that contains an identifier that specifies the format of the key BLOB. These formats are - /// specific to a particular key storage provider. For the BLOB formats supported by Microsoft providers, see Remarks. + /// If the pbOutput parameter is NULL, the size, in bytes, required for the buffer is placed in the location pointed to by + /// this parameter. /// /// - /// - /// - /// The address of an NCryptBufferDesc structure that points to an array of buffers that contain parameter information for the key. - /// - /// - /// - /// - /// The address of an NCRYPT_KEY_HANDLE variable that receives the handle of the key. When you have finished using this - /// handle, release it by passing it to the NCryptFreeObject function. - /// - /// - /// - /// The address of a buffer that contains the key BLOB to be imported. The cbData parameter contains the size of this buffer. - /// - /// - /// The size, in bytes, of the pbData buffer. - /// /// + /// Flags that modify function behavior. This can be zero or the following value. + /// + /// + /// Value + /// Meaning + /// + /// + /// NCRYPT_PERSIST_ONLY_FLAG + /// + /// Ignore any built in values for this property and only retrieve the user-persisted properties of the key. The maximum size of the + /// data for any persisted property is NCRYPT_MAX_PROPERTY_DATA bytes. + /// + /// + /// + /// NCRYPT_SILENT_FLAG + /// + /// Requests that the key service provider (KSP) not display any user interface. If the provider must display the UI to operate, the + /// call fails and the KSP should set the NTE_SILENT_CONTEXT error code as the last error. + /// + /// + /// /// - /// Flags that modify function behavior. This can be zero or a combination of one or more of the following values. The set of valid - /// flags is specific to each key storage provider. + /// For the NCRYPT_SECURITY_DESCR_PROPERTY property, this parameter must also contain one of the following values, which + /// identifies the part of the security descriptor to retrieve. /// /// /// @@ -1711,10 +2389,31 @@ namespace Vanara.PInvoke /// Meaning /// /// - /// NCRYPT_SILENT_FLAG + /// OWNER_SECURITY_INFORMATION /// - /// Requests that the key service provider (KSP) not display any user interface. If the provider must display the UI to operate, the - /// call fails and the KSP should set the NTE_SILENT_CONTEXT error code as the last error. + /// Retrieve the security identifier (SID) of the object's owner. Use the GetSecurityDescriptorOwner function to obtain the owner SID + /// from the SECURITY_DESCRIPTOR structure. + /// + /// + /// + /// GROUP_SECURITY_INFORMATION + /// + /// Retrieve the SID of the object's primary group. Use the GetSecurityDescriptorGroup function to obtain the group SID from the + /// SECURITY_DESCRIPTOR structure. + /// + /// + /// + /// DACL_SECURITY_INFORMATION + /// + /// Retrieve the discretionary access control list (DACL). Use the GetSecurityDescriptorSacl function to obtain the DACL from the + /// SECURITY_DESCRIPTOR structure. + /// + /// + /// + /// SACL_SECURITY_INFORMATION + /// + /// Retrieve the system access control list (SACL). Use the GetSecurityDescriptorDacl function to obtain the SACL from the + /// SECURITY_DESCRIPTOR structure. /// /// /// @@ -1736,12 +2435,8 @@ namespace Vanara.PInvoke /// The dwFlags parameter contains a value that is not valid. /// /// - /// NTE_EXISTS - /// A key with the specified name already exists and the NCRYPT_OVERWRITE_KEY_FLAG was not specified. - /// - /// /// NTE_INVALID_HANDLE - /// The hProvider parameter is not valid. + /// The hObject parameter is not valid. /// /// /// NTE_INVALID_PARAMETER @@ -1751,106 +2446,21 @@ namespace Vanara.PInvoke /// NTE_NO_MEMORY /// A memory allocation failure occurred. /// + /// + /// NTE_NOT_SUPPORTED + /// The specified property is not supported for the object. + /// /// /// /// - /// /// A service must not call this function from its StartService Function. If a service calls this function from its StartService /// function, a deadlock can occur, and the service may stop responding. - /// - /// The following sections describe behaviors specific to the Microsoft key storage providers: - /// - /// - /// Microsoft Software KSP - /// - /// - /// Microsoft Smart Card KSP - /// - /// - /// Microsoft Software KSP - /// The following constants are supported by the Microsoft software KSP for the pszBlobType parameter. - /// - /// If a key name is not supplied, the Microsoft Software KSP treats the key as ephemeral and does not store it persistently. For the - /// NCRYPT_OPAQUETRANSPORT_BLOB type, the key name is stored within the BLOB when it is exported. For other BLOB formats, the - /// name can be supplied in an NCRYPTBUFFER_PKCS_KEY_NAME buffer parameter within the pParameterList parameter. - /// - /// - /// On Windows Server 2008 and Windows Vista, only keys imported as PKCS #7 envelope BLOBs ( NCRYPT_PKCS7_ENVELOPE_BLOB) or - /// PKCS #8 private key BLOBs ( NCRYPT_PKCS8_PRIVATE_KEY_BLOB) can be persisted by using the above method. To persist keys - /// imported through other BLOB types on these platforms, use the method documented in Key Import and Export. - /// - /// The following flags are supported by this KSP. - /// - /// - /// Term - /// Description - /// - /// - /// NCRYPT_NO_KEY_VALIDATION - /// Do not validate the public portion of the key pair. This flag only applies to public/private key pairs. - /// - /// - /// NCRYPT_DO_NOT_FINALIZE_FLAG - /// - /// Do not finalize the key. This option is useful when you need to add or modify properties of the key after importing it. You must - /// finalize the key before it can be used by passing the key handle to the NCryptFinalizeKey function. This flag is supported for - /// the private keys PKCS #7 and PKCS #8 but not public keys. - /// - /// - /// - /// NCRYPT_MACHINE_KEY_FLAG - /// The key applies to the local computer. If this flag is not present, the key applies to the current user. - /// - /// - /// NCRYPT_OVERWRITE_KEY_FLAG - /// - /// If a key already exists in the container with the specified name, the existing key will be overwritten. If this flag is not - /// specified and a key with the specified name already exists, this function will return NTE_EXISTS. - /// - /// - /// - /// NCRYPT_WRITE_KEY_TO_LEGACY_STORE_FLAG - /// - /// Also save the key in legacy storage. This allows the key to be used with the CryptoAPI. This flag only applies to RSA keys. - /// - /// - /// - /// Microsoft Smart Card KSP - /// - /// The set of key BLOB formats and flags supported by this KSP is identical to the set supported by the Microsoft Software KSP. - /// - /// - /// On Windows Server 2008 and Windows Vista, the Microsoft Smart Card KSP imports all keys into the Microsoft Software KSP. Thus, - /// keys cannot be persisted on to a smart card by using this API, and the guidance in the above section applies when trying to - /// persist keys within the Microsoft Software KSP. - /// - /// - /// On Windows Server 2008 R2 and Windows 7, the Microsoft Smart Card Key Storage Provider can import a private key to a smart card, - /// provided the following conditions are met: - /// - /// - /// - /// The key container name on the card is valid. - /// - /// - /// Importing private keys is supported by the smart card. - /// - /// - /// The following two registry keys are set to a DWORD of 0x1: - /// - /// - /// - /// If the key container name is NULL, the Microsoft Smart Card KSP treats the key as ephemeral and imports it into the - /// Microsoft Software KSP. - /// /// - // https://docs.microsoft.com/en-us/windows/desktop/api/ncrypt/nf-ncrypt-ncryptimportkey SECURITY_STATUS NCryptImportKey( - // NCRYPT_PROV_HANDLE hProvider, NCRYPT_KEY_HANDLE hImportKey, LPCWSTR pszBlobType, NCryptBufferDesc *pParameterList, - // NCRYPT_KEY_HANDLE *phKey, PBYTE pbData, DWORD cbData, DWORD dwFlags ); + // https://docs.microsoft.com/en-us/windows/win32/api/ncrypt/nf-ncrypt-ncryptgetproperty SECURITY_STATUS NCryptGetProperty( + // NCRYPT_HANDLE hObject, LPCWSTR pszProperty, PBYTE pbOutput, DWORD cbOutput, DWORD *pcbResult, DWORD dwFlags ); [DllImport(Lib.Ncrypt, SetLastError = false, ExactSpelling = true)] - [PInvokeData("ncrypt.h", MSDNShortId = "ede0e7e0-cb2c-44c0-b724-58db3480b781")] - public static extern HRESULT NCryptImportKey(NCRYPT_PROV_HANDLE hProvider, NCRYPT_KEY_HANDLE hImportKey, [MarshalAs(UnmanagedType.LPWStr)] string pszBlobType, NCryptBufferDesc pParameterList, - out SafeNCRYPT_KEY_HANDLE phKey, SafeAllocatedMemoryHandle pbData, uint cbData, ImportKeyFlags dwFlags = 0); + [PInvokeData("ncrypt.h", MSDNShortId = "7b857ce0-8525-489b-9987-ef40081a5577")] + public static extern HRESULT NCryptGetProperty(NCRYPT_HANDLE hObject, [MarshalAs(UnmanagedType.LPWStr)] string pszProperty, IntPtr pbOutput, uint cbOutput, out uint pcbResult, GetPropertyFlags dwFlags); /// /// The NCryptImportKey function imports a Cryptography API: Next Generation (CNG) key from a memory BLOB. @@ -2038,7 +2648,767 @@ namespace Vanara.PInvoke [DllImport(Lib.Ncrypt, SetLastError = false, ExactSpelling = true)] [PInvokeData("ncrypt.h", MSDNShortId = "ede0e7e0-cb2c-44c0-b724-58db3480b781")] public static extern HRESULT NCryptImportKey(NCRYPT_PROV_HANDLE hProvider, NCRYPT_KEY_HANDLE hImportKey, [MarshalAs(UnmanagedType.LPWStr)] string pszBlobType, NCryptBufferDesc pParameterList, - out SafeNCRYPT_KEY_HANDLE phKey, [Optional] IntPtr pbData, [Optional] uint cbData, ImportKeyFlags dwFlags = 0); + out SafeNCRYPT_KEY_HANDLE phKey, SafeAllocatedMemoryHandle pbData, uint cbData, NCryptUIFlags dwFlags = 0); + + /// + /// The NCryptImportKey function imports a Cryptography API: Next Generation (CNG) key from a memory BLOB. + /// + /// + /// The handle of the key storage provider. + /// + /// + /// + /// The handle of the cryptographic key with which the key data within the imported key BLOB was encrypted. This must be a handle to + /// the same key that was passed in the hExportKey parameter of the NCryptExportKey function. If this parameter is NULL, the + /// key BLOB is assumed to not be encrypted. + /// + /// + /// + /// + /// A null-terminated Unicode string that contains an identifier that specifies the format of the key BLOB. These formats are + /// specific to a particular key storage provider. For the BLOB formats supported by Microsoft providers, see Remarks. + /// + /// + /// + /// + /// The address of an NCryptBufferDesc structure that points to an array of buffers that contain parameter information for the key. + /// + /// + /// + /// + /// The address of an NCRYPT_KEY_HANDLE variable that receives the handle of the key. When you have finished using this + /// handle, release it by passing it to the NCryptFreeObject function. + /// + /// + /// + /// The address of a buffer that contains the key BLOB to be imported. The cbData parameter contains the size of this buffer. + /// + /// + /// The size, in bytes, of the pbData buffer. + /// + /// + /// + /// Flags that modify function behavior. This can be zero or a combination of one or more of the following values. The set of valid + /// flags is specific to each key storage provider. + /// + /// + /// + /// Value + /// Meaning + /// + /// + /// NCRYPT_SILENT_FLAG + /// + /// Requests that the key service provider (KSP) not display any user interface. If the provider must display the UI to operate, the + /// call fails and the KSP should set the NTE_SILENT_CONTEXT error code as the last error. + /// + /// + /// + /// + /// + /// Returns a status code that indicates the success or failure of the function. + /// Possible return codes include, but are not limited to, the following. + /// + /// + /// Return code + /// Description + /// + /// + /// ERROR_SUCCESS + /// The function was successful. + /// + /// + /// NTE_BAD_FLAGS + /// The dwFlags parameter contains a value that is not valid. + /// + /// + /// NTE_EXISTS + /// A key with the specified name already exists and the NCRYPT_OVERWRITE_KEY_FLAG was not specified. + /// + /// + /// NTE_INVALID_HANDLE + /// The hProvider parameter is not valid. + /// + /// + /// NTE_INVALID_PARAMETER + /// One or more parameters are not valid. + /// + /// + /// NTE_NO_MEMORY + /// A memory allocation failure occurred. + /// + /// + /// + /// + /// + /// A service must not call this function from its StartService Function. If a service calls this function from its StartService + /// function, a deadlock can occur, and the service may stop responding. + /// + /// The following sections describe behaviors specific to the Microsoft key storage providers: + /// + /// + /// Microsoft Software KSP + /// + /// + /// Microsoft Smart Card KSP + /// + /// + /// Microsoft Software KSP + /// The following constants are supported by the Microsoft software KSP for the pszBlobType parameter. + /// + /// If a key name is not supplied, the Microsoft Software KSP treats the key as ephemeral and does not store it persistently. For the + /// NCRYPT_OPAQUETRANSPORT_BLOB type, the key name is stored within the BLOB when it is exported. For other BLOB formats, the + /// name can be supplied in an NCRYPTBUFFER_PKCS_KEY_NAME buffer parameter within the pParameterList parameter. + /// + /// + /// On Windows Server 2008 and Windows Vista, only keys imported as PKCS #7 envelope BLOBs ( NCRYPT_PKCS7_ENVELOPE_BLOB) or + /// PKCS #8 private key BLOBs ( NCRYPT_PKCS8_PRIVATE_KEY_BLOB) can be persisted by using the above method. To persist keys + /// imported through other BLOB types on these platforms, use the method documented in Key Import and Export. + /// + /// The following flags are supported by this KSP. + /// + /// + /// Term + /// Description + /// + /// + /// NCRYPT_NO_KEY_VALIDATION + /// Do not validate the public portion of the key pair. This flag only applies to public/private key pairs. + /// + /// + /// NCRYPT_DO_NOT_FINALIZE_FLAG + /// + /// Do not finalize the key. This option is useful when you need to add or modify properties of the key after importing it. You must + /// finalize the key before it can be used by passing the key handle to the NCryptFinalizeKey function. This flag is supported for + /// the private keys PKCS #7 and PKCS #8 but not public keys. + /// + /// + /// + /// NCRYPT_MACHINE_KEY_FLAG + /// The key applies to the local computer. If this flag is not present, the key applies to the current user. + /// + /// + /// NCRYPT_OVERWRITE_KEY_FLAG + /// + /// If a key already exists in the container with the specified name, the existing key will be overwritten. If this flag is not + /// specified and a key with the specified name already exists, this function will return NTE_EXISTS. + /// + /// + /// + /// NCRYPT_WRITE_KEY_TO_LEGACY_STORE_FLAG + /// + /// Also save the key in legacy storage. This allows the key to be used with the CryptoAPI. This flag only applies to RSA keys. + /// + /// + /// + /// Microsoft Smart Card KSP + /// + /// The set of key BLOB formats and flags supported by this KSP is identical to the set supported by the Microsoft Software KSP. + /// + /// + /// On Windows Server 2008 and Windows Vista, the Microsoft Smart Card KSP imports all keys into the Microsoft Software KSP. Thus, + /// keys cannot be persisted on to a smart card by using this API, and the guidance in the above section applies when trying to + /// persist keys within the Microsoft Software KSP. + /// + /// + /// On Windows Server 2008 R2 and Windows 7, the Microsoft Smart Card Key Storage Provider can import a private key to a smart card, + /// provided the following conditions are met: + /// + /// + /// + /// The key container name on the card is valid. + /// + /// + /// Importing private keys is supported by the smart card. + /// + /// + /// The following two registry keys are set to a DWORD of 0x1: + /// + /// + /// + /// If the key container name is NULL, the Microsoft Smart Card KSP treats the key as ephemeral and imports it into the + /// Microsoft Software KSP. + /// + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/ncrypt/nf-ncrypt-ncryptimportkey SECURITY_STATUS NCryptImportKey( + // NCRYPT_PROV_HANDLE hProvider, NCRYPT_KEY_HANDLE hImportKey, LPCWSTR pszBlobType, NCryptBufferDesc *pParameterList, + // NCRYPT_KEY_HANDLE *phKey, PBYTE pbData, DWORD cbData, DWORD dwFlags ); + [DllImport(Lib.Ncrypt, SetLastError = false, ExactSpelling = true)] + [PInvokeData("ncrypt.h", MSDNShortId = "ede0e7e0-cb2c-44c0-b724-58db3480b781")] + public static extern HRESULT NCryptImportKey(NCRYPT_PROV_HANDLE hProvider, NCRYPT_KEY_HANDLE hImportKey, [MarshalAs(UnmanagedType.LPWStr)] string pszBlobType, NCryptBufferDesc pParameterList, + out SafeNCRYPT_KEY_HANDLE phKey, [Optional] IntPtr pbData, [Optional] uint cbData, NCryptUIFlags dwFlags = 0); + + /// + /// The NCryptIsAlgSupported function determines if a CNG key storage provider supports a specific cryptographic algorithm. + /// + /// + /// The handle of the key storage provider. This handle is obtained with the NCryptOpenStorageProvider function. + /// + /// + /// A pointer to a null-terminated Unicode string that identifies the cryptographic algorithm in question. This can be one of the + /// standard CNG Algorithm Identifiers or the identifier for another registered algorithm. + /// + /// + /// Flags that modify function behavior. This can be zero (0) or the following value. + /// + /// + /// Value + /// Meaning + /// + /// + /// NCRYPT_SILENT_FLAG + /// + /// Requests that the key service provider (KSP) not display any user interface. If the provider must display the UI to operate, the + /// call fails and the KSP should set the NTE_SILENT_CONTEXT error code as the last error. + /// + /// + /// + /// + /// + /// Returns a status code that indicates the success or failure of the function. + /// Possible return codes include, but are not limited to, the following. + /// + /// + /// Return code + /// Description + /// + /// + /// ERROR_SUCCESS + /// The provider supports the specified algorithm. + /// + /// + /// NTE_BAD_FLAGS + /// The dwFlags parameter contains one or more flags that are not supported. + /// + /// + /// NTE_INVALID_HANDLE + /// The handle specified by the hProvider parameter is not valid. + /// + /// + /// NTE_INVALID_PARAMETER + /// One or more parameters are not valid. + /// + /// + /// NTE_NOT_SUPPORTED + /// The provider does not support the specified algorithm. + /// + /// + /// + /// + /// + /// If the provider supports the algorithm, this function returns ERROR_SUCCESS. If the provider does not support the + /// algorithm, and no other errors occurred, this function returns NTE_NOT_SUPPORTED. + /// + /// + /// A service must not call this function from its StartService Function. If a service calls this function from its StartService + /// function, a deadlock can occur, and the service may stop responding. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/api/ncrypt/nf-ncrypt-ncryptisalgsupported SECURITY_STATUS NCryptIsAlgSupported( + // NCRYPT_PROV_HANDLE hProvider, LPCWSTR pszAlgId, DWORD dwFlags ); + [DllImport(Lib.Ncrypt, SetLastError = false, ExactSpelling = true)] + [PInvokeData("ncrypt.h", MSDNShortId = "99563293-662f-4478-b8da-8526b832012d")] + public static extern HRESULT NCryptIsAlgSupported(NCRYPT_PROV_HANDLE hProvider, [MarshalAs(UnmanagedType.LPWStr)] string pszAlgId, NCryptUIFlags dwFlags); + + /// The NCryptIsKeyHandle function determines if the specified handle is a CNG key handle. + /// The handle of the key to test. + /// Returns a nonzero value if the handle is a key handle or zero otherwise. + /// + /// A service must not call this function from its StartService Function. If a service calls this function from its StartService + /// function, a deadlock can occur, and the service may stop responding. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/ncrypt/nf-ncrypt-ncryptiskeyhandle BOOL NCryptIsKeyHandle( NCRYPT_KEY_HANDLE + // hKey ); + [DllImport(Lib.Ncrypt, SetLastError = false, ExactSpelling = true)] + [PInvokeData("ncrypt.h", MSDNShortId = "ad841c2e-8097-4b07-914e-8e7240d55585")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool NCryptIsKeyHandle(NCRYPT_KEY_HANDLE hKey); + + /// + /// The NCryptKeyDerivation function creates a key from another key by using the specified key derivation function. The + /// function returns the key in a byte array. + /// + /// Handle of the key derivation function (KDF) key. + /// + /// + /// The address of a NCryptBufferDesc structure that contains the KDF parameters. The parameters can be specific to a KDF or generic. + /// The following table shows the required and optional parameters for specific KDFs implemented by the Microsoft software key + /// storage provider. + /// + /// + /// + /// KDF + /// Parameter + /// Required + /// + /// + /// SP800-108 HMAC in counter mode + /// KDF_LABEL + /// yes + /// + /// + /// + /// KDF_CONTEXT + /// yes + /// + /// + /// + /// KDF_HASH_ALGORITHM + /// yes + /// + /// + /// SP800-56A + /// KDF_ALGORITHMID + /// yes + /// + /// + /// + /// KDF_PARTYUINFO + /// yes + /// + /// + /// + /// KDF_PARTYVINFO + /// yes + /// + /// + /// + /// KDF_HASH_ALGORITHM + /// yes + /// + /// + /// + /// KDF_SUPPPUBINFO + /// no + /// + /// + /// + /// KDF_SUPPPRIVINFO + /// no + /// + /// + /// PBKDF2 + /// KDF_HASH_ALGORITHM + /// yes + /// + /// + /// + /// KDF_SALT + /// yes + /// + /// + /// + /// KDF_ITERATION_COUNT + /// no + /// + /// + /// CAPI_KDF + /// KDF_HASH_ALGORITHM + /// yes + /// + /// + /// The following generic parameter can be used: + /// + /// + /// KDF_GENERIC_PARAMETER + /// + /// + /// Generic parameters map to KDF specific parameters in the following manner: + /// SP800-108 HMAC in counter mode: + /// + /// + /// KDF_GENERIC_PARAMETER = KDF_LABEL||0x00||KDF_CONTEXT + /// + /// + /// SP800-56A + /// + /// + /// + /// KDF_GENERIC_PARAMETER = KDF_ALGORITHMID || KDF_PARTYUINFO || KDF_PARTYVINFO {|| KDF_SUPPPUBINFO } {|| KDF_SUPPPRIVINFO } + /// + /// + /// + /// PBKDF2 + /// + /// + /// KDF_GENERIC_PARAMETER = KDF_SALT + /// + /// + /// KDF_ITERATION_COUNT – defaults to 10000 + /// + /// + /// CAPI_KDF + /// + /// + /// KDF_GENERIC_PARAMETER = Not Used + /// + /// + /// + /// + /// Address of a buffer that receives the key. The cbDerivedKey parameter contains the size, in bytes, of the key buffer. + /// + /// Size, in bytes, of the buffer pointed to by the pbDerivedKey parameter. + /// + /// Pointer to a DWORD that receives the number of bytes copied to the buffer pointed to by the pbDerivedKey parameter. + /// + /// + /// Flags that modify function behavior. The following value can be used with the Microsoft software key storage provider. + /// + /// + /// Value + /// Meaning + /// + /// + /// BCRYPT_CAPI_AES_FLAG + /// + /// Specifies that the target algorithm is AES and that the key therefore must be double expanded. This flag is only valid with the + /// CAPI_KDF algorithm. + /// + /// + /// + /// NCRYPT_SILENT_FLAG + /// + /// Requests that the key service provider (KSP) not display any user interface. If the provider must display the UI to operate, the + /// call fails and the KSP should set the NTE_SILENT_CONTEXT error code as the last error. + /// + /// + /// + /// + /// + /// Returns a status code that indicates the success or failure of the function. + /// Possible return codes include, but are not limited to, the following. + /// + /// + /// Return code + /// Description + /// + /// + /// ERROR_SUCCESS + /// The function was successful. + /// + /// + /// NTE_INVALID_HANDLE + /// The hProvider or hKey handles are not valid. + /// + /// + /// NTE_INVALID_PARAMETER + /// The pwszDerivedKeyAlg and pParameterList parameters cannot be NULL. + /// + /// + /// NTE_NO_MEMORY + /// There was not enough memory to create the key. + /// + /// + /// NTE_NOT_SUPPORTED + /// This function is not supported by the key storage provider. + /// + /// + /// + /// + /// You can use the following algorithm identifiers in the NCryptCreatePersistedKey function before calling NCryptKeyDerivation: + /// + /// + /// BCRYPT_CAPI_KDF_ALGORITHM + /// + /// + /// BCRYPT_SP800108_CTR_HMAC_ALGORITHM + /// + /// + /// BCRYPT_SP80056A_CONCAT_ALGORITHM + /// + /// + /// BCRYPT_PBKDF2_ALGORITHM + /// + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/api/ncrypt/nf-ncrypt-ncryptkeyderivation SECURITY_STATUS NCryptKeyDerivation( + // NCRYPT_KEY_HANDLE hKey, NCryptBufferDesc *pParameterList, PUCHAR pbDerivedKey, DWORD cbDerivedKey, DWORD *pcbResult, ULONG dwFlags ); + [DllImport(Lib.Ncrypt, SetLastError = false, ExactSpelling = true)] + [PInvokeData("ncrypt.h", MSDNShortId = "5D2D61B1-022E-412F-A19E-11057930A615")] + public static extern HRESULT NCryptKeyDerivation(NCRYPT_KEY_HANDLE hKey, in NCryptBufferDesc pParameterList, IntPtr pbDerivedKey, uint cbDerivedKey, out uint pcbResult, KeyDerivationFlags dwFlags); + + /// + /// The NCryptKeyDerivation function creates a key from another key by using the specified key derivation function. The + /// function returns the key in a byte array. + /// + /// Handle of the key derivation function (KDF) key. + /// + /// + /// The address of a NCryptBufferDesc structure that contains the KDF parameters. The parameters can be specific to a KDF or generic. + /// The following table shows the required and optional parameters for specific KDFs implemented by the Microsoft software key + /// storage provider. + /// + /// + /// + /// KDF + /// Parameter + /// Required + /// + /// + /// SP800-108 HMAC in counter mode + /// KDF_LABEL + /// yes + /// + /// + /// + /// KDF_CONTEXT + /// yes + /// + /// + /// + /// KDF_HASH_ALGORITHM + /// yes + /// + /// + /// SP800-56A + /// KDF_ALGORITHMID + /// yes + /// + /// + /// + /// KDF_PARTYUINFO + /// yes + /// + /// + /// + /// KDF_PARTYVINFO + /// yes + /// + /// + /// + /// KDF_HASH_ALGORITHM + /// yes + /// + /// + /// + /// KDF_SUPPPUBINFO + /// no + /// + /// + /// + /// KDF_SUPPPRIVINFO + /// no + /// + /// + /// PBKDF2 + /// KDF_HASH_ALGORITHM + /// yes + /// + /// + /// + /// KDF_SALT + /// yes + /// + /// + /// + /// KDF_ITERATION_COUNT + /// no + /// + /// + /// CAPI_KDF + /// KDF_HASH_ALGORITHM + /// yes + /// + /// + /// The following generic parameter can be used: + /// + /// + /// KDF_GENERIC_PARAMETER + /// + /// + /// Generic parameters map to KDF specific parameters in the following manner: + /// SP800-108 HMAC in counter mode: + /// + /// + /// KDF_GENERIC_PARAMETER = KDF_LABEL||0x00||KDF_CONTEXT + /// + /// + /// SP800-56A + /// + /// + /// + /// KDF_GENERIC_PARAMETER = KDF_ALGORITHMID || KDF_PARTYUINFO || KDF_PARTYVINFO {|| KDF_SUPPPUBINFO } {|| KDF_SUPPPRIVINFO } + /// + /// + /// + /// PBKDF2 + /// + /// + /// KDF_GENERIC_PARAMETER = KDF_SALT + /// + /// + /// KDF_ITERATION_COUNT – defaults to 10000 + /// + /// + /// CAPI_KDF + /// + /// + /// KDF_GENERIC_PARAMETER = Not Used + /// + /// + /// + /// + /// Address of a buffer that receives the key. The cbDerivedKey parameter contains the size, in bytes, of the key buffer. + /// + /// Size, in bytes, of the buffer pointed to by the pbDerivedKey parameter. + /// + /// Pointer to a DWORD that receives the number of bytes copied to the buffer pointed to by the pbDerivedKey parameter. + /// + /// + /// Flags that modify function behavior. The following value can be used with the Microsoft software key storage provider. + /// + /// + /// Value + /// Meaning + /// + /// + /// BCRYPT_CAPI_AES_FLAG + /// + /// Specifies that the target algorithm is AES and that the key therefore must be double expanded. This flag is only valid with the + /// CAPI_KDF algorithm. + /// + /// + /// + /// NCRYPT_SILENT_FLAG + /// + /// Requests that the key service provider (KSP) not display any user interface. If the provider must display the UI to operate, the + /// call fails and the KSP should set the NTE_SILENT_CONTEXT error code as the last error. + /// + /// + /// + /// + /// + /// Returns a status code that indicates the success or failure of the function. + /// Possible return codes include, but are not limited to, the following. + /// + /// + /// Return code + /// Description + /// + /// + /// ERROR_SUCCESS + /// The function was successful. + /// + /// + /// NTE_INVALID_HANDLE + /// The hProvider or hKey handles are not valid. + /// + /// + /// NTE_INVALID_PARAMETER + /// The pwszDerivedKeyAlg and pParameterList parameters cannot be NULL. + /// + /// + /// NTE_NO_MEMORY + /// There was not enough memory to create the key. + /// + /// + /// NTE_NOT_SUPPORTED + /// This function is not supported by the key storage provider. + /// + /// + /// + /// + /// You can use the following algorithm identifiers in the NCryptCreatePersistedKey function before calling NCryptKeyDerivation: + /// + /// + /// BCRYPT_CAPI_KDF_ALGORITHM + /// + /// + /// BCRYPT_SP800108_CTR_HMAC_ALGORITHM + /// + /// + /// BCRYPT_SP80056A_CONCAT_ALGORITHM + /// + /// + /// BCRYPT_PBKDF2_ALGORITHM + /// + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/api/ncrypt/nf-ncrypt-ncryptkeyderivation SECURITY_STATUS NCryptKeyDerivation( + // NCRYPT_KEY_HANDLE hKey, NCryptBufferDesc *pParameterList, PUCHAR pbDerivedKey, DWORD cbDerivedKey, DWORD *pcbResult, ULONG dwFlags ); + [DllImport(Lib.Ncrypt, SetLastError = false, ExactSpelling = true)] + [PInvokeData("ncrypt.h", MSDNShortId = "5D2D61B1-022E-412F-A19E-11057930A615")] + public static extern HRESULT NCryptKeyDerivation(NCRYPT_KEY_HANDLE hKey, [Optional] IntPtr pParameterList, IntPtr pbDerivedKey, uint cbDerivedKey, out uint pcbResult, KeyDerivationFlags dwFlags); + + /// + /// The NCryptNotifyChangeKey function creates or removes a key change notification. + /// + /// The handle provided by this function is the same handle that is returned by the FindFirstChangeNotification function. You use the + /// wait functions to wait for the notification handle to be signaled. + /// + /// + /// + /// The handle of the key storage provider. This handle is obtained by using the NCryptOpenStorageProvider function. + /// + /// + /// The address of a HANDLE variable that either receives or contains the key change notification event handle. This is the + /// same handle that is returned by the FindFirstChangeNotification function. For more information, see the dwFlags parameter description. + /// + /// + /// + /// A set of flags that modify the behavior of this function. This parameter contains a combination of one or more of the following values. + /// + /// + /// + /// Value + /// Meaning + /// + /// + /// NCRYPT_REGISTER_NOTIFY_FLAG 0x00000001 + /// Create a new change notification. The phEvent parameter will receive the key change notification handle. + /// + /// + /// NCRYPT_UNREGISTER_NOTIFY_FLAG 0x00000002 + /// + /// Remove an existing change notification. The phEvent parameter must contain a valid key change notification handle. This handle is + /// no longer valid after this function is called with this flag and the INVALID_HANDLE_VALUE value is placed in this handle. + /// + /// + /// + /// NCRYPT_MACHINE_KEY_FLAG 0x00000020 + /// + /// Receive change notifications for keys in the machine key store. If this flag is not specified, the change notification events + /// will only occur for keys in the calling user's key store. This flag is only valid when combined with the + /// NCRYPT_REGISTER_NOTIFY_FLAG flag. + /// + /// + /// + /// + /// + /// Returns a status code that indicates the success or failure of the function. + /// Possible return codes include, but are not limited to, the following. + /// + /// + /// Return code + /// Description + /// + /// + /// ERROR_SUCCESS + /// The function was successful. + /// + /// + /// NTE_BAD_FLAGS + /// The dwFlags parameter contains a value that is not valid. + /// + /// + /// NTE_INVALID_HANDLE + /// The hProvider parameter is not valid. + /// + /// + /// NTE_INVALID_PARAMETER + /// One or more parameters are not valid. + /// + /// + /// + /// + /// A service must not call this function from its StartService Function. If a service calls this function from its StartService + /// function, a deadlock can occur, and the service may stop responding. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/ncrypt/nf-ncrypt-ncryptnotifychangekey SECURITY_STATUS NCryptNotifyChangeKey( + // NCRYPT_PROV_HANDLE hProvider, HANDLE *phEvent, DWORD dwFlags ); + [DllImport(Lib.Ncrypt, SetLastError = false, ExactSpelling = true)] + [PInvokeData("ncrypt.h", MSDNShortId = "2d2ddb55-ef32-4227-b901-ee11e961d0e6")] + public static extern HRESULT NCryptNotifyChangeKey(NCRYPT_PROV_HANDLE hProvider, ref IntPtr phEvent, XXX dwFlags); /// /// The NCryptOpenKey function opens a key that exists in the specified CNG key storage provider. @@ -2298,7 +3668,7 @@ namespace Vanara.PInvoke // NCRYPT_KEY_HANDLE hPrivKey, NCRYPT_KEY_HANDLE hPubKey, NCRYPT_SECRET_HANDLE *phAgreedSecret, DWORD dwFlags ); [DllImport(Lib.Ncrypt, SetLastError = false, ExactSpelling = true)] [PInvokeData("ncrypt.h", MSDNShortId = "b5bf3eac-1fae-43e2-84b6-e8e5e255d7c5")] - public static extern HRESULT NCryptSecretAgreement(NCRYPT_KEY_HANDLE hPrivKey, NCRYPT_KEY_HANDLE hPubKey, out SafeNCRYPT_SECRET_HANDLE phAgreedSecret, SecretAgreementFlags dwFlags = 0); + public static extern HRESULT NCryptSecretAgreement(NCRYPT_KEY_HANDLE hPrivKey, NCRYPT_KEY_HANDLE hPubKey, out SafeNCRYPT_SECRET_HANDLE phAgreedSecret, NCryptUIFlags dwFlags = 0); /// /// The NCryptSetProperty function sets the value for a named property for a CNG key storage object. @@ -2580,6 +3950,332 @@ namespace Vanara.PInvoke [PInvokeData("ncrypt.h", MSDNShortId = "ad1148aa-5f64-4867-9e17-6b41cc0c20b7")] public static extern HRESULT NCryptSetProperty(NCRYPT_HANDLE hObject, [MarshalAs(UnmanagedType.LPWStr)] string pszProperty, byte[] pbInput, uint cbInput, SetPropFlags dwFlags); + /// The NCryptSignHash function creates a signature of a hash value. + /// The handle of the key to use to sign the hash. + /// + /// A pointer to a structure that contains padding information. The actual type of structure this parameter points to depends on the + /// value of the dwFlags parameter. This parameter is only used with asymmetric keys and must be NULL otherwise. + /// + /// + /// A pointer to a buffer that contains the hash value to sign. The cbInput parameter contains the size of this buffer. + /// + /// The number of bytes in the pbHashValue buffer to sign. + /// + /// + /// The address of a buffer to receive the signature produced by this function. The cbSignature parameter contains the size of this buffer. + /// + /// + /// If this parameter is NULL, this function will calculate the size required for the signature and return the size in the + /// location pointed to by the pcbResult parameter. + /// + /// + /// + /// The size, in bytes, of the pbSignature buffer. This parameter is ignored if the pbSignature parameter is NULL. + /// + /// + /// A pointer to a DWORD variable that receives the number of bytes copied to the pbSignature buffer. + /// If pbSignature is NULL, this receives the size, in bytes, required for the signature. + /// + /// + /// Flags that modify function behavior. The allowed set of flags depends on the type of key specified by the hKey parameter. + /// If the key is a symmetric key, this parameter is not used and should be set to zero. + /// If the key is an asymmetric key, this can be one of the following values. + /// + /// + /// Value + /// Meaning + /// + /// + /// BCRYPT_PAD_PKCS1 + /// Use the PKCS1 padding scheme. The pPaddingInfo parameter is a pointer to a BCRYPT_PKCS1_PADDING_INFO structure. + /// + /// + /// BCRYPT_PAD_PSS + /// + /// Use the Probabilistic Signature Scheme (PSS) padding scheme. The pPaddingInfo parameter is a pointer to a BCRYPT_PSS_PADDING_INFO structure. + /// + /// + /// + /// NCRYPT_SILENT_FLAG + /// + /// Requests that the key service provider (KSP) not display any user interface. If the provider must display the UI to operate, the + /// call fails and the KSP should set the NTE_SILENT_CONTEXT error code as the last error. + /// + /// + /// + /// + /// + /// Returns a status code that indicates the success or failure of the function. + /// Possible return codes include, but are not limited to, the following. + /// + /// + /// Return code + /// Description + /// + /// + /// ERROR_SUCCESS + /// The function was successful. + /// + /// + /// NTE_BAD_ALGID + /// The key represented by the hKey parameter does not support signing. + /// + /// + /// NTE_BAD_FLAGS + /// The dwFlags parameter contains a value that is not valid. + /// + /// + /// NTE_INVALID_HANDLE + /// The hKey parameter is not valid. + /// + /// + /// NTE_INVALID_PARAMETER + /// One or more parameters are not valid. + /// + /// + /// NTE_NO_MEMORY + /// A memory allocation failure occurred. + /// + /// + /// + /// + /// A service must not call this function from its StartService Function. If a service calls this function from its StartService + /// function, a deadlock can occur, and the service may stop responding. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/ncrypt/nf-ncrypt-ncryptsignhash SECURITY_STATUS NCryptSignHash( + // NCRYPT_KEY_HANDLE hKey, VOID *pPaddingInfo, PBYTE pbHashValue, DWORD cbHashValue, PBYTE pbSignature, DWORD cbSignature, DWORD + // *pcbResult, DWORD dwFlags ); + [DllImport(Lib.Ncrypt, SetLastError = false, ExactSpelling = true)] + [PInvokeData("ncrypt.h", MSDNShortId = "7404e37a-d7c6-49ed-b951-6081dd2b921a")] + public static extern HRESULT NCryptSignHash(NCRYPT_KEY_HANDLE hKey, [In, Optional] IntPtr pPaddingInfo, [In] IntPtr pbHashValue, uint cbHashValue, [In, Out] IntPtr pbSignature, uint cbSignature, out uint pcbResult, NCryptDecryptFlag dwFlags); + + /// The NCryptTranslateHandle function translates a CryptoAPI handle into a CNG key handle. + /// + /// A pointer to an NCRYPT_PROV_HANDLE variable that receives the handle of the CNG key storage provider that owns the CNG key + /// placed in the phKey parameter. This parameter can be NULL if this handle is not needed. + /// + /// A pointer to a NCRYPT_KEY_HANDLE variable that receives the CNG key handle. + /// + /// The handle of the CryptoAPI provider that contains the key to translate. This function will translate the CryptoAPI key that is + /// in the container in this provider. + /// + /// + /// + /// The handle of a CryptoAPI key to use to help determine the key specification for the returned key. This parameter is ignored if + /// the dwLegacyKeySpec parameter contains a value other than zero. + /// + /// + /// If hLegacyKey is NULL and dwLegacyKeySpec is zero, this function will attempt to determine the key specification from the + /// hLegacyProv handle. + /// + /// + /// + /// Specifies the key specification for the key. This can be one of the following values. + /// + /// + /// Value + /// Meaning + /// + /// + /// 0 + /// The key is none of the types below. + /// + /// + /// AT_KEYEXCHANGE 1 + /// The key is a key exchange key. + /// + /// + /// AT_SIGNATURE 2 + /// The key is a signature key. + /// + /// + /// + /// If hLegacyKey is NULL and dwLegacyKeySpec is zero, this function will attempt to determine the key specification from the + /// hLegacyProv handle. + /// + /// + /// A set of flags that modify the behavior of this function. No flags are defined for this function. + /// + /// Returns a status code that indicates the success or failure of the function. + /// Possible return codes include, but are not limited to, the following. + /// + /// + /// Return code + /// Description + /// + /// + /// ERROR_SUCCESS + /// The function was successful. + /// + /// + /// NTE_BAD_FLAGS + /// The dwFlags parameter contains a value that is not valid. + /// + /// + /// NTE_INVALID_PARAMETER + /// One or more parameters are not valid. + /// + /// + /// NTE_NO_MEMORY + /// A memory allocation failure occurred. + /// + /// + /// + /// + /// + /// This is a helper function intended to help applications and system components that currently use the CryptoAPI to make a graceful + /// transition to using CNG. + /// + /// + /// This function will only be successful if a CNG key storage provider is registered with a name or alias that is identical to the + /// name of the cryptographic service provider (CSP) referred to by the hLegacyProv parameter. + /// + /// This function will perform the following steps to translate the CSP handle into a CNG key handle: + /// + /// + /// Obtain the name of the CSP from the hLegacyProv handle. + /// + /// + /// Open the CNG provider whose name or alias is identical to the CSP name. + /// + /// + /// Obtain the name of the current key container in the CSP. + /// + /// + /// Obtain the CryptoAPI key, translate it into a CNG key, and return it in the phKey parameter. + /// + /// + /// + /// A service must not call this function from its StartService Function. If a service calls this function from its StartService + /// function, a deadlock can occur, and the service may stop responding. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/api/ncrypt/nf-ncrypt-ncrypttranslatehandle SECURITY_STATUS NCryptTranslateHandle( + // NCRYPT_PROV_HANDLE *phProvider, NCRYPT_KEY_HANDLE *phKey, HCRYPTPROV hLegacyProv, HCRYPTKEY hLegacyKey, DWORD dwLegacyKeySpec, + // DWORD dwFlags ); + [DllImport(Lib.Ncrypt, SetLastError = false, ExactSpelling = true)] + [PInvokeData("ncrypt.h", MSDNShortId = "0c339864-b598-430c-a597-09d3571fdbb2")] + public static extern HRESULT NCryptTranslateHandle(out SafeNCRYPT_PROV_HANDLE phProvider, out SafeNCRYPT_KEY_HANDLE phKey, Crypt32.HCRYPTPROV hLegacyProv, Crypt32.HCRYPTKEY hLegacyKey, Crypt32.PrivateKeyType dwLegacyKeySpec, uint dwFlags = 0); + + /// + /// + /// [Some information relates to pre-released product which may be substantially modified before it's commercially released. + /// Microsoft makes no warranties, express or implied, with respect to the information provided here.] + /// + /// Verifies a key attestation claim. + /// + /// The subject key handle for the claim. + /// + /// The authority key handle to use when verifying the claim. This parameter is optional because the authority key is self-contained + /// for certain claim types. + /// + /// The type of claim. + /// An optional parameter list. + /// The input claim blob. + /// + /// The output blob. + /// As of Windows 10, no flags are defined. This parameter should be set to 0. + /// Returns a status code that indicates the success or failure of the function. + // https://docs.microsoft.com/en-us/windows/win32/api/ncrypt/nf-ncrypt-ncryptverifyclaim SECURITY_STATUS NCryptVerifyClaim( + // NCRYPT_KEY_HANDLE hSubjectKey, NCRYPT_KEY_HANDLE hAuthorityKey, DWORD dwClaimType, NCryptBufferDesc *pParameterList, PBYTE + // pbClaimBlob, DWORD cbClaimBlob, NCryptBufferDesc *pOutput, DWORD dwFlags ); + [DllImport(Lib.Ncrypt, SetLastError = false, ExactSpelling = true)] + [PInvokeData("ncrypt.h", MSDNShortId = "D3C837A5-49D7-4099-B8FE-37364A275A73")] + public static extern HRESULT NCryptVerifyClaim(NCRYPT_KEY_HANDLE hSubjectKey, [Optional] NCRYPT_KEY_HANDLE hAuthorityKey, uint dwClaimType, [Optional] NCryptBufferDesc[] pParameterList, [In] IntPtr pbClaimBlob, uint cbClaimBlob, out NCryptBufferDesc pOutput, uint dwFlags = 0); + + /// The NCryptVerifySignature function verifies that the specified signature matches the specified hash. + /// + /// The handle of the key to use to decrypt the signature. This must be an identical key or the public key portion of the key pair + /// used to sign the data with the NCryptSignHash function. + /// + /// + /// A pointer to a structure that contains padding information. The actual type of structure this parameter points to depends on the + /// value of the dwFlags parameter. This parameter is only used with asymmetric keys and must be NULL otherwise. + /// + /// + /// The address of a buffer that contains the hash of the data. The cbHash parameter contains the size of this buffer. + /// + /// The size, in bytes, of the pbHash buffer. + /// + /// The address of a buffer that contains the signed hash of the data. The NCryptSignHash function is used to create the signature. + /// The cbSignature parameter contains the size of this buffer. + /// + /// + /// The size, in bytes, of the pbSignature buffer. The NCryptSignHash function is used to create the signature. + /// + /// + /// Flags that modify function behavior. The allowed set of flags depends on the type of key specified by the hKey parameter. + /// If the key is a symmetric key, this parameter is not used and should be zero. + /// If the key is an asymmetric key, this can be one of the following values. + /// + /// + /// Value + /// Meaning + /// + /// + /// NCRYPT_PAD_PKCS1_FLAG + /// + /// The PKCS1 padding scheme was used when the signature was created. The pPaddingInfo parameter is a pointer to a + /// BCRYPT_PKCS1_PADDING_INFO structure. + /// + /// + /// + /// NCRYPT_PAD_PSS_FLAG + /// + /// The Probabilistic Signature Scheme (PSS) padding scheme was used when the signature was created. The pPaddingInfo parameter is a + /// pointer to a BCRYPT_PSS_PADDING_INFO structure. + /// + /// + /// + /// NCRYPT_SILENT_FLAG + /// + /// Requests that the key service provider (KSP) not display any user interface. If the provider must display the UI to operate, the + /// call fails and the KSP should set the NTE_SILENT_CONTEXT error code as the last error. + /// + /// + /// + /// + /// + /// Returns a status code that indicates the success or failure of the function. + /// Possible return codes include, but are not limited to, the following. + /// + /// + /// Return code + /// Description + /// + /// + /// ERROR_SUCCESS + /// The function was successful. + /// + /// + /// NTE_BAD_SIGNATURE + /// The signature was not verified. + /// + /// + /// NTE_INVALID_HANDLE + /// The hKey parameter is not valid. + /// + /// + /// NTE_NO_MEMORY + /// A memory allocation failure occurred. + /// + /// + /// NTE_NOT_SUPPORTED + /// The algorithm provider used to create the key handle specified by the hKey parameter is not a signing algorithm. + /// + /// + /// + /// + /// A service must not call this function from its StartService Function. If a service calls this function from its StartService + /// function, a deadlock can occur, and the service may stop responding. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/ncrypt/nf-ncrypt-ncryptverifysignature SECURITY_STATUS NCryptVerifySignature( + // NCRYPT_KEY_HANDLE hKey, VOID *pPaddingInfo, PBYTE pbHashValue, DWORD cbHashValue, PBYTE pbSignature, DWORD cbSignature, DWORD + // dwFlags ); + [DllImport(Lib.Ncrypt, SetLastError = false, ExactSpelling = true)] + [PInvokeData("ncrypt.h", MSDNShortId = "9a839d99-4e9a-4114-982c-51dee38d2949")] + public static extern HRESULT NCryptVerifySignature(NCRYPT_KEY_HANDLE hKey, [In, Optional] IntPtr pPaddingInfo, [In] IntPtr pbHashValue, uint cbHashValue, [In] IntPtr pbSignature, uint cbSignature, NCryptDecryptFlag dwFlags); + /// /// /// The NCRYPT_ALLOC_PARA structure enables you to specify custom functions that can be used to allocate and free data. This @@ -2805,6 +4501,75 @@ namespace Vanara.PInvoke public IntPtr DangerousGetHandle() => handle; } + /// The NCryptAlgorithmName structure is used to contain information about a CNG algorithm. + // https://docs.microsoft.com/en-us/windows/win32/api/ncrypt/ns-ncrypt-ncryptalgorithmname typedef struct _NCryptAlgorithmName { + // LPWSTR pszName; DWORD dwClass; DWORD dwAlgOperations; DWORD dwFlags; } NCryptAlgorithmName; + [PInvokeData("ncrypt.h", MSDNShortId = "79b0193e-3be8-46ce-a422-40ed9698363f")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + public struct NCryptAlgorithmName + { + /// + /// A pointer to a null-terminated Unicode string that contains the name of the algorithm. This can be one of the standard CNG + /// Algorithm Identifiers or the identifier for another registered algorithm. + /// + [MarshalAs(UnmanagedType.LPWStr)] + public string pszName; + + /// + /// + /// A DWORD value that defines which algorithm class this algorithm belongs to. This can be one of the following values. + /// + /// + /// + /// Value + /// Meaning + /// + /// + /// NCRYPT_ASYMMETRIC_ENCRYPTION_INTERFACE 0x00000003 + /// The algorithm belongs to the asymmetric encryption class of algorithms. + /// + /// + /// NCRYPT_SECRET_AGREEMENT_INTERFACE 0x00000004 + /// The algorithm belongs to the secret agreement (Diffie-Hellman) class of algorithms. + /// + /// + /// NCRYPT_SIGNATURE_INTERFACE 0x00000005 + /// The algorithm belongs to the signature class of algorithms. + /// + /// + /// + public BCrypt.InterfaceId dwClass; + + /// + /// + /// A DWORD value that defines which operational classes this algorithm belongs to. This can be a combination of one or + /// more of the following values. + /// + /// + /// + /// Value + /// Meaning + /// + /// + /// NCRYPT_ASYMMETRIC_ENCRYPTION_OPERATION 0x00000004 + /// The algorithm is an asymmetric encryption algorithm. + /// + /// + /// NCRYPT_SECRET_AGREEMENT_OPERATION 0x00000008 + /// The algorithm is a secret agreement (Diffie-Hellman) algorithm. + /// + /// + /// NCRYPT_SIGNATURE_OPERATION 0x00000010 + /// The algorithm is a digital signature algorithm. + /// + /// + /// + public BCrypt.AlgOperations dwAlgOperations; + + /// A set of flags that provide more information about the algorithm. + public uint dwFlags; + } + /// The NCryptBuffer structure is used to identify a variable-length memory buffer. /// BCryptBuffer is an alias for this structure. // https://docs.microsoft.com/en-us/windows/desktop/api/bcrypt/ns-bcrypt-_bcryptbuffer typedef struct _BCryptBuffer { ULONG cbBuffer; @@ -2961,7 +4726,7 @@ namespace Vanara.PInvoke /// /// /// - public BufferType BufferType; + public KeyDerivationBufferType BufferType; /// /// The buffer. @@ -2972,7 +4737,7 @@ namespace Vanara.PInvoke /// Initializes a new instance of the struct. /// Type of the buffer. /// The buffer. - public NCryptBuffer(BufferType bufferType, byte[] buffer) + public NCryptBuffer(KeyDerivationBufferType bufferType, byte[] buffer) { BufferType = bufferType; pvBuffer = buffer; @@ -2981,116 +4746,217 @@ namespace Vanara.PInvoke /// Initializes a new instance of the struct. /// Type of the buffer. /// The buffer. - public NCryptBuffer(BufferType bufferType, string buffer) + public NCryptBuffer(KeyDerivationBufferType bufferType, string buffer) { BufferType = bufferType; pvBuffer = System.Text.Encoding.Unicode.GetBytes(buffer); } } + /// NCrypt known storage providers. public static class KnownStorageProvider { + /// The Microsoft Software Key Storage Provider public const string MS_KEY_STORAGE_PROVIDER = "Microsoft Software Key Storage Provider"; + + /// The Microsoft Passport Key Storage Provider public const string MS_NGC_KEY_STORAGE_PROVIDER = "Microsoft Passport Key Storage Provider"; + + /// The Microsoft Platform Crypto Provider public const string MS_PLATFORM_KEY_STORAGE_PROVIDER = "Microsoft Platform Crypto Provider"; + + /// The Microsoft Smart Card Key Storage Provider public const string MS_SMART_CARD_KEY_STORAGE_PROVIDER = "Microsoft Smart Card Key Storage Provider"; } /// The following values are used with the NCryptGetProperty and NCryptSetProperty functions to identify a property. public static class PropertyName { + /// Algorithm Group public const string NCRYPT_ALGORITHM_GROUP_PROPERTY = "Algorithm Group"; + /// Algorithm Name public const string NCRYPT_ALGORITHM_PROPERTY = "Algorithm Name"; + /// SmartCardAssociatedECDHKey public const string NCRYPT_ASSOCIATED_ECDH_KEY = "SmartCardAssociatedECDHKey"; + /// AuthTagLength public const string NCRYPT_AUTH_TAG_LENGTH = "AuthTagLength"; + /// Block Length public const string NCRYPT_BLOCK_LENGTH_PROPERTY = "Block Length"; + /// SmartCardKeyCertificate public const string NCRYPT_CERTIFICATE_PROPERTY = "SmartCardKeyCertificate"; + /// Chaining Mode public const string NCRYPT_CHAINING_MODE_PROPERTY = "Chaining Mode"; + /// SmartCardDismissUITimeoutSeconds public const string NCRYPT_DISMISS_UI_TIMEOUT_SEC_PROPERTY = "SmartCardDismissUITimeoutSeconds"; + /// public const string NCRYPT_ECC_CURVE_NAME_LIST_PROPERTY = BCrypt.PropertyName.BCRYPT_ECC_CURVE_NAME_LIST; + /// public const string NCRYPT_ECC_CURVE_NAME_PROPERTY = BCrypt.PropertyName.BCRYPT_ECC_CURVE_NAME; + /// public const string NCRYPT_ECC_PARAMETERS_PROPERTY = BCrypt.PropertyName.BCRYPT_ECC_PARAMETERS; + /// Export Policy public const string NCRYPT_EXPORT_POLICY_PROPERTY = "Export Policy"; + /// Impl Type public const string NCRYPT_IMPL_TYPE_PROPERTY = "Impl Type"; + /// KDFKeySecret public const string NCRYPT_KDF_SECRET_VALUE = "KDFKeySecret"; + /// Key Type public const string NCRYPT_KEY_TYPE_PROPERTY = "Key Type"; + /// Key Usage public const string NCRYPT_KEY_USAGE_PROPERTY = "Key Usage"; + /// Modified public const string NCRYPT_LAST_MODIFIED_PROPERTY = "Modified"; + /// Length public const string NCRYPT_LENGTH_PROPERTY = "Length"; + /// Lengths public const string NCRYPT_LENGTHS_PROPERTY = "Lengths"; + /// Max Name Length public const string NCRYPT_MAX_NAME_LENGTH_PROPERTY = "Max Name Length"; + /// Name public const string NCRYPT_NAME_PROPERTY = "Name"; + /// PCP_ALTERNATE_KEY_STORAGE_LOCATION public const string NCRYPT_PCP_ALTERNATE_KEY_STORAGE_LOCATION_PROPERTY = "PCP_ALTERNATE_KEY_STORAGE_LOCATION"; + /// PCP_CHANGEPASSWORD public const string NCRYPT_PCP_CHANGEPASSWORD_PROPERTY = "PCP_CHANGEPASSWORD"; + /// PCP_ECC_EKCERT public const string NCRYPT_PCP_ECC_EKCERT_PROPERTY = "PCP_ECC_EKCERT"; + /// PCP_ECC_EKNVCERT public const string NCRYPT_PCP_ECC_EKNVCERT_PROPERTY = "PCP_ECC_EKNVCERT"; + /// PCP_ECC_EKPUB public const string NCRYPT_PCP_ECC_EKPUB_PROPERTY = "PCP_ECC_EKPUB"; + /// PCP_EKCERT public const string NCRYPT_PCP_EKCERT_PROPERTY = "PCP_EKCERT"; + /// PCP_EKNVCERT public const string NCRYPT_PCP_EKNVCERT_PROPERTY = "PCP_EKNVCERT"; + /// PCP_EKPUB public const string NCRYPT_PCP_EKPUB_PROPERTY = "PCP_EKPUB"; + /// PCP_EXPORT_ALLOWED public const string NCRYPT_PCP_EXPORT_ALLOWED_PROPERTY = "PCP_EXPORT_ALLOWED"; + /// PCP_HMAC_AUTH_NONCE public const string NCRYPT_PCP_HMAC_AUTH_NONCE = "PCP_HMAC_AUTH_NONCE"; + /// PCP_HMAC_AUTH_POLICYINFO public const string NCRYPT_PCP_HMAC_AUTH_POLICYINFO = "PCP_HMAC_AUTH_POLICYINFO"; + /// PCP_HMAC_AUTH_POLICYREF public const string NCRYPT_PCP_HMAC_AUTH_POLICYREF = "PCP_HMAC_AUTH_POLICYREF"; + /// PCP_HMAC_AUTH_SIGNATURE public const string NCRYPT_PCP_HMAC_AUTH_SIGNATURE = "PCP_HMAC_AUTH_SIGNATURE"; + /// PCP_HMAC_AUTH_TICKET public const string NCRYPT_PCP_HMAC_AUTH_TICKET = "PCP_HMAC_AUTH_TICKET"; + /// PCP_KEY_CREATIONHASH public const string NCRYPT_PCP_KEY_CREATIONHASH_PROPERTY = "PCP_KEY_CREATIONHASH"; + /// PCP_KEY_CREATIONTICKET public const string NCRYPT_PCP_KEY_CREATIONTICKET_PROPERTY = "PCP_KEY_CREATIONTICKET"; + /// PCP_KEY_USAGE_POLICY public const string NCRYPT_PCP_KEY_USAGE_POLICY_PROPERTY = "PCP_KEY_USAGE_POLICY"; + /// PCP_TPM12_KEYATTESTATION public const string NCRYPT_PCP_KEYATTESTATION_PROPERTY = "PCP_TPM12_KEYATTESTATION"; + /// PCP_MIGRATIONPASSWORD public const string NCRYPT_PCP_MIGRATIONPASSWORD_PROPERTY = "PCP_MIGRATIONPASSWORD"; + /// PCP_NO_DA_PROTECTION public const string NCRYPT_PCP_NO_DA_PROTECTION_PROPERTY = "PCP_NO_DA_PROTECTION"; + /// PCP_PASSWORD_REQUIRED public const string NCRYPT_PCP_PASSWORD_REQUIRED_PROPERTY = "PCP_PASSWORD_REQUIRED"; + /// PCP_PCRTABLE public const string NCRYPT_PCP_PCRTABLE_PROPERTY = "PCP_PCRTABLE"; + /// PCP_PLATFORM_BINDING_PCRDIGEST public const string NCRYPT_PCP_PLATFORM_BINDING_PCRDIGEST_PROPERTY = "PCP_PLATFORM_BINDING_PCRDIGEST"; + /// PCP_PLATFORM_BINDING_PCRDIGESTLIST public const string NCRYPT_PCP_PLATFORM_BINDING_PCRDIGESTLIST_PROPERTY = "PCP_PLATFORM_BINDING_PCRDIGESTLIST"; + /// PCP_PLATFORM_BINDING_PCRMASK public const string NCRYPT_PCP_PLATFORM_BINDING_PCRMASK_PROPERTY = "PCP_PLATFORM_BINDING_PCRMASK"; + /// PCP_PLATFORM_TYPE public const string NCRYPT_PCP_PLATFORM_TYPE_PROPERTY = "PCP_PLATFORM_TYPE"; + /// PCP_PLATFORMHANDLE public const string NCRYPT_PCP_PLATFORMHANDLE_PROPERTY = "PCP_PLATFORMHANDLE"; + /// PCP_PROVIDER_VERSION public const string NCRYPT_PCP_PROVIDER_VERSION_PROPERTY = "PCP_PROVIDER_VERSION"; + /// PCP_PROVIDERMHANDLE public const string NCRYPT_PCP_PROVIDERHANDLE_PROPERTY = "PCP_PROVIDERMHANDLE"; + /// PCP_RAW_POLICYDIGEST public const string NCRYPT_PCP_RAW_POLICYDIGEST_PROPERTY = "PCP_RAW_POLICYDIGEST"; + /// PCP_RSA_EKCERT public const string NCRYPT_PCP_RSA_EKCERT_PROPERTY = "PCP_RSA_EKCERT"; + /// PCP_RSA_EKNVCERT public const string NCRYPT_PCP_RSA_EKNVCERT_PROPERTY = "PCP_RSA_EKNVCERT"; + /// PCP_RSA_EKPUB public const string NCRYPT_PCP_RSA_EKPUB_PROPERTY = "PCP_RSA_EKPUB"; + /// PCP_RSA_SCHEME_HASH_ALG public const string NCRYPT_PCP_RSA_SCHEME_HASH_ALG_PROPERTY = "PCP_RSA_SCHEME_HASH_ALG"; + /// PCP_RSA_SCHEME public const string NCRYPT_PCP_RSA_SCHEME_PROPERTY = "PCP_RSA_SCHEME"; + /// PCP_SESSIONID public const string NCRYPT_PCP_SESSIONID_PROPERTY = "PCP_SESSIONID"; + /// PCP_SRKPUB public const string NCRYPT_PCP_SRKPUB_PROPERTY = "PCP_SRKPUB"; + /// PCP_STORAGEPARENT public const string NCRYPT_PCP_STORAGEPARENT_PROPERTY = "PCP_STORAGEPARENT"; + /// PCP_TPM_FW_VERSION public const string NCRYPT_PCP_TPM_FW_VERSION_PROPERTY = "PCP_TPM_FW_VERSION"; + /// PCP_TPM_IFX_RSA_KEYGEN_PROHIBITED public const string NCRYPT_PCP_TPM_IFX_RSA_KEYGEN_PROHIBITED_PROPERTY = "PCP_TPM_IFX_RSA_KEYGEN_PROHIBITED"; + /// PCP_TPM_IFX_RSA_KEYGEN_VULNERABILITY public const string NCRYPT_PCP_TPM_IFX_RSA_KEYGEN_VULNERABILITY_PROPERTY = "PCP_TPM_IFX_RSA_KEYGEN_VULNERABILITY"; + /// PCP_TPM_MANUFACTURER_ID public const string NCRYPT_PCP_TPM_MANUFACTURER_ID_PROPERTY = "PCP_TPM_MANUFACTURER_ID"; + /// PCP_TPM_VERSION public const string NCRYPT_PCP_TPM_VERSION_PROPERTY = "PCP_TPM_VERSION"; + /// PCP_TPM12_IDACTIVATION public const string NCRYPT_PCP_TPM12_IDACTIVATION_PROPERTY = "PCP_TPM12_IDACTIVATION"; + /// PCP_TPM12_IDBINDING_DYNAMIC public const string NCRYPT_PCP_TPM12_IDBINDING_DYNAMIC_PROPERTY = "PCP_TPM12_IDBINDING_DYNAMIC"; + /// PCP_TPM12_IDBINDING public const string NCRYPT_PCP_TPM12_IDBINDING_PROPERTY = "PCP_TPM12_IDBINDING"; + /// PCP_TPM2BNAME public const string NCRYPT_PCP_TPM2BNAME_PROPERTY = "PCP_TPM2BNAME"; + /// PCP_USAGEAUTH public const string NCRYPT_PCP_USAGEAUTH_PROPERTY = "PCP_USAGEAUTH"; + /// SmartCardPinPrompt public const string NCRYPT_PIN_PROMPT_PROPERTY = "SmartCardPinPrompt"; + /// SmartCardPin public const string NCRYPT_PIN_PROPERTY = "SmartCardPin"; + /// Provider Handle public const string NCRYPT_PROVIDER_HANDLE_PROPERTY = "Provider Handle"; + /// public const string NCRYPT_PUBLIC_LENGTH_PROPERTY = BCrypt.PropertyName.BCRYPT_PUBLIC_KEY_LENGTH; + /// SmartCardReaderIcon public const string NCRYPT_READER_ICON_PROPERTY = "SmartCardReaderIcon"; + /// SmartCardReader public const string NCRYPT_READER_PROPERTY = "SmartCardReader"; + /// SmartcardRootCertStore public const string NCRYPT_ROOT_CERTSTORE_PROPERTY = "SmartcardRootCertStore"; + /// SmartCardPinId public const string NCRYPT_SCARD_PIN_ID = "SmartCardPinId"; + /// SmartCardPinInfo public const string NCRYPT_SCARD_PIN_INFO = "SmartCardPinInfo"; + /// SmartCardSecurePin public const string NCRYPT_SECURE_PIN_PROPERTY = "SmartCardSecurePin"; + /// Security Descr public const string NCRYPT_SECURITY_DESCR_PROPERTY = "Security Descr"; + /// Security Descr Support public const string NCRYPT_SECURITY_DESCR_SUPPORT_PROPERTY = "Security Descr Support"; + /// public const string NCRYPT_SIGNATURE_LENGTH_PROPERTY = BCrypt.PropertyName.BCRYPT_SIGNATURE_LENGTH; + /// SmartCardGuid public const string NCRYPT_SMARTCARD_GUID_PROPERTY = "SmartCardGuid"; + /// UI Policy public const string NCRYPT_UI_POLICY_PROPERTY = "UI Policy"; + /// Unique Name public const string NCRYPT_UNIQUE_NAME_PROPERTY = "Unique Name"; + /// Use Context public const string NCRYPT_USE_CONTEXT_PROPERTY = "Use Context"; + /// Enabled Use Count public const string NCRYPT_USE_COUNT_ENABLED_PROPERTY = "Enabled Use Count"; + /// Use Count public const string NCRYPT_USE_COUNT_PROPERTY = "Use Count"; + /// Per Boot Key public const string NCRYPT_USE_PER_BOOT_KEY_PROPERTY = "Per Boot Key"; + /// Virtual Iso public const string NCRYPT_USE_VIRTUAL_ISOLATION_PROPERTY = "Virtual Iso"; + /// SmartCardUserCertStore public const string NCRYPT_USER_CERTSTORE_PROPERTY = "SmartCardUserCertStore"; + /// Version public const string NCRYPT_VERSION_PROPERTY = "Version"; + /// HWND Handle public const string NCRYPT_WINDOW_HANDLE_PROPERTY = "HWND Handle"; } @@ -3162,7 +5028,7 @@ namespace Vanara.PInvoke public uint cbBuffer; /// A value that identifies the type of data that is contained by the buffer. - public BufferType BufferType; + public KeyDerivationBufferType BufferType; /// /// The address of the buffer. The size of this buffer is contained in the cbBuffer member. @@ -3257,23 +5123,32 @@ namespace Vanara.PInvoke protected override bool InternalReleaseHandle() => NCryptFreeObject(handle).Succeeded; } - /* - NCryptCreateClaim - NCryptDecrypt - NCryptEncrypt - NCryptEnumAlgorithms - NCryptEnumKeys - NCryptEnumStorageProviders - NCryptFreeBuffer - NCryptGetProperty - NCryptIsAlgSupported - NCryptIsKeyHandle - NCryptKeyDerivation - NCryptNotifyChangeKey - NCryptSignHash - NCryptTranslateHandle - NCryptVerifyClaim - NCryptVerifySignature - */ + /// Provides a for buffers allocated by the NCrypt library that is disposed using . + public class SafeNCryptBuffer : 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 SafeNCryptBuffer(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { } + + /// Initializes a new instance of the class. + private SafeNCryptBuffer() : base() { } + + /// Converts an that points to a C-style array into a CLI array. + /// Type of native structure used by the C-style array. + /// The number of items in the native array. + /// An array of type containing the elements of the native array. + public T[] ToArray(uint count) => handle.ToArray((int)count); + + /// Marshals data to a newly allocated managed object of the type specified by a generic type parameter. + /// The type of the object to which the data is to be copied. This must be a structure. + /// A managed object that contains the data pointed to by this object. + public T ToStructure() => handle.ToStructure(); + + /// + protected override bool InternalReleaseHandle() => NCryptFreeBuffer(handle).Succeeded; + } } } \ No newline at end of file diff --git a/UnitTests/PInvoke/Cryptography/BCryptTests.cs b/UnitTests/PInvoke/Cryptography/BCryptTests.cs index 6cbfd43d..3195c691 100644 --- a/UnitTests/PInvoke/Cryptography/BCryptTests.cs +++ b/UnitTests/PInvoke/Cryptography/BCryptTests.cs @@ -261,9 +261,9 @@ namespace Vanara.PInvoke.Tests var ParameterList = new NCryptBufferDesc { pBuffers = new[] { - new NCryptBuffer(BufferType.KDF_HASH_ALGORITHM, StandardAlgorithmId.BCRYPT_SHA256_ALGORITHM), - new NCryptBuffer(BufferType.KDF_SECRET_APPEND, SecretAppendArray), - new NCryptBuffer(BufferType.KDF_SECRET_PREPEND, SecretPrependArray) } + new NCryptBuffer(KeyDerivationBufferType.KDF_HASH_ALGORITHM, StandardAlgorithmId.BCRYPT_SHA256_ALGORITHM), + new NCryptBuffer(KeyDerivationBufferType.KDF_SECRET_APPEND, SecretAppendArray), + new NCryptBuffer(KeyDerivationBufferType.KDF_SECRET_PREPEND, SecretPrependArray) } }; hr = NCryptDeriveKey(AgreedSecretHandleA, KDF.BCRYPT_KDF_HMAC, ParameterList, IntPtr.Zero, 0, out var AgreedSecretLengthA, DeriveKeyFlags.KDF_USE_SECRET_AS_HMAC_KEY_FLAG);