using System;
using System.Runtime.InteropServices;
namespace Vanara.PInvoke
{
/// Methods and data types found in Crypt32.dll.
public static partial class Crypt32
{
/// Flags for and
[PInvokeData("wincrypt.h", MSDNShortId = "003602c6-d6c9-4695-9c60-ffaf0aa02266")]
[Flags]
public enum PFXExportFlags : uint
{
///
/// If a certificate is encountered that has no associated private key, the function returns FALSE with the last error set to
/// either CRYPT_E_NOT_FOUND or NTE_NO_KEY.
///
REPORT_NO_PRIVATE_KEY = 0x0001,
///
/// If a certificate is encountered that has a non-exportable private key, the function returns FALSE and the last error set to
/// NTE_BAD_KEY, NTE_BAD_KEY_STATE, or NTE_PERM.
///
REPORT_NOT_ABLE_TO_EXPORT_PRIVATE_KEY = 0x0002,
/// Private keys are exported as well as the certificates.
EXPORT_PRIVATE_KEYS = 0x0004,
///
/// Export all extended properties on the certificate.
/// Windows Server 2003 and Windows XP: This value is not supported.
///
PKCS12_INCLUDE_EXTENDED_PROPERTIES = 0x0010,
///
/// The PFX BLOB contains an embedded password that will be protected to the Active Directory (AD) protection descriptor pointed
/// to by the pvPara parameter. If the szPassword parameter is not NULL or empty, the specified password is protected. If,
/// however, the szPassword parameter is NULL or an empty string, a random forty (40) character password is created and protected.
///
/// PFXImportCertStore uses the specified protection descriptor to decrypt the embedded password, whether specified by the user
/// or randomly generated, and then uses the password to decrypt the PFX BLOB.
///
/// Windows 8 and Windows Server 2012: Support for this flag begins.
///
PKCS12_PROTECT_TO_DOMAIN_SIDS = 0x0020,
///
PKCS12_EXPORT_SILENT = 0x0040,
///
PKCS12_EXPORT_PBES2_PARAMS = 0x0080,
///
PKCS12_DISABLE_ENCRYPT_CERTIFICATES = 0x0100,
///
PKCS12_ENCRYPT_CERTIFICATES = 0x0200,
///
PKCS12_EXPORT_ECC_CURVE_PARAMETERS = 0x1000,
///
PKCS12_EXPORT_ECC_CURVE_OID = 0x2000,
///
PKCS12_EXPORT_RESERVED_MASK = 0xffff0000,
}
/// Flags for .
[PInvokeData("wincrypt.h", MSDNShortId = "2c83774a-f2df-4d28-9abd-e39aa507ba88")]
[Flags]
public enum PFXImportFlags : uint
{
///
/// Imported keys are marked as exportable. If this flag is not used, calls to the CryptExportKey function with the key handle fail.
///
CRYPT_EXPORTABLE = 0x00000001,
///
/// The user is to be notified through a dialog box or other method when certain attempts to use this key are made. The precise
/// behavior is specified by the cryptographic service provider (CSP) being used.
///
/// Prior to Internet Explorer 4.0, Microsoft cryptographic service providers ignored this flag. Starting with Internet Explorer
/// 4.0, Microsoft providers support this flag.
///
///
/// If the provider context was opened with the CRYPT_SILENT flag set, using this flag causes a failure and the last error is
/// set to NTE_SILENT_CONTEXT.
///
///
CRYPT_USER_PROTECTED = 0x00000002,
/// The private keys are stored under the local computer and not under the current user.
CRYPT_MACHINE_KEYSET = 0x00000020,
///
/// The private keys are stored under the current user and not under the local computer even if the PFX BLOB specifies that they
/// should go into the local computer.
///
CRYPT_USER_KEYSET = 0x00001000,
///
/// Indicates that the CNG key storage provider (KSP) is preferred. If the CSP is specified in the PFX file, then the CSP is
/// used, otherwise the KSP is preferred. If the CNG KSP is unavailable, the PFXImportCertStore function will fail.
/// Windows Server 2003 and Windows XP: This value is not supported.
///
PKCS12_PREFER_CNG_KSP = 0x00000100,
///
/// Indicates that the CNG KSP is always used. When specified, PFXImportCertStore attempts to use the CNG KSP irrespective of
/// provider information in the PFX file. If the CNG KSP is unavailable, the import will not fail.
/// Windows Server 2003 and Windows XP: This value is not supported.
///
PKCS12_ALWAYS_CNG_KSP = 0x00000200,
///
/// Allow overwrite of the existing key. Specify this flag when you encounter a scenario in which you must import a PFX file
/// that contains a key name that already exists. For example, when you import a PFX file, it is possible that a container of
/// the same name is already present because there is no unique namespace for key containers. If you have created a "TestKey" on
/// your computer, and then you import a PFX file that also has "TestKey" as the key container, the PKCS12_ALLOW_OVERWRITE_KEY
/// setting allows the key to be overwritten.
/// Windows Server 2003 and Windows XP: This value is not supported.
///
PKCS12_ALLOW_OVERWRITE_KEY = 0x00004000,
///
/// Do not persist the key. Specify this flag when you do not want to persist the key. For example, if it is not necessary to
/// store the key after verification, then instead of creating a container and then deleting it, you can specify this flag to
/// dispose of the key immediately.
///
/// Note If the PKCS12_NO_PERSIST_KEY flag is not set, keys are persisted on disk. If you do not want to persist the keys beyond
/// their usage, you must delete them by calling the CryptAcquireContext function with the CRYPT_DELETEKEYSET flag set in the
/// dwFlags parameter.
///
/// Windows Server 2003 and Windows XP: This value is not supported.
///
PKCS12_NO_PERSIST_KEY = 0x00008000,
///
/// Import all extended properties on the certificate that were saved on the certificate when it was exported.
/// Windows Server 2003 and Windows XP: This value is not supported.
///
PKCS12_INCLUDE_EXTENDED_PROPERTIES = 0x0010,
/// Unpack but do not persist the results.
PKCS12_UNPACK_RESULTS_ONLY = 0x10000000,
///
CRYPT_USER_PROTECTED_STRONG = 0x00100000,
///
PKCS12_IMPORT_SILENT = 0x00000040,
///
PKCS12_ONLY_CERTIFICATES = 0x00000400,
///
PKCS12_ONLY_NOT_ENCRYPTED_CERTIFICATES = 0x00000800,
///
PKCS12_VIRTUAL_ISOLATION_KEY = 0x00010000,
///
PKCS12_IMPORT_RESERVED_MASK = 0xffff0000,
///
PKCS12_OBJECT_LOCATOR_ALL_IMPORT_FLAGS = (PKCS12_ALWAYS_CNG_KSP | PKCS12_NO_PERSIST_KEY | PKCS12_IMPORT_SILENT | PKCS12_INCLUDE_EXTENDED_PROPERTIES),
}
///
/// The PFXExportCertStore function exports the certificates and, if available, the associated private keys from the
/// referenced certificate store. This is an old function kept for compatibility with Internet Explorer 4.0 clients. New
/// applications should use the PfxExportCertStoreEx function that provides enhanced private key security.
///
/// Handle of the certificate store containing the certificates to be exported.
///
/// A pointer to a CRYPT_DATA_BLOB structure to contain the PFX packet with the exported certificates and keys. If pPFX->pbData
/// is NULL, the function calculates the number of bytes needed for the encoded BLOB and returns this in pPFX->cbData.
/// When the function is called with pPFX->pbData pointing to an allocated buffer of the needed size, the function copies the
/// encoded bytes into the buffer and updates pPFX->cbData with the encode byte length.
///
///
/// String password used to encrypt and verify the PFX packet. When you have finished using the password, clear the password from
/// memory by calling the SecureZeroMemory function. For more information about protecting passwords, see Handling Passwords.
///
///
/// Flag values can be set to any combination of the following.
///
///
/// Value
/// Meaning
///
/// -
/// EXPORT_PRIVATE_KEYS
/// Private keys are exported as well as the certificates.
///
/// -
/// REPORT_NO_PRIVATE_KEY
///
/// If a certificate is encountered that has no associated private key, the function returns FALSE with the last error set to either
/// CRYPT_E_NOT_FOUND or NTE_NO_KEY.
///
///
/// -
/// REPORT_NOT_ABLE_TO_EXPORT_PRIVATE_KEY
///
/// If a certificate is encountered that has a non-exportable private key, the function returns FALSE and the last error set to
/// NTE_BAD_KEY, NTE_BAD_KEY_STATE, or NTE_PERM.
///
///
///
///
///
/// Returns TRUE (nonzero) if the function succeeds, and FALSE (zero) if the function fails. For extended error
/// information, call GetLastError.
///
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-pfxexportcertstore BOOL PFXExportCertStore( HCERTSTORE
// hStore, CRYPT_DATA_BLOB *pPFX, LPCWSTR szPassword, DWORD dwFlags );
[DllImport(Lib.Crypt32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "003602c6-d6c9-4695-9c60-ffaf0aa02266")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool PFXExportCertStore([In] HCERTSTORE hStore, ref CRYPTOAPI_BLOB pPFX, [MarshalAs(UnmanagedType.LPWStr)] string szPassword, PFXExportFlags dwFlags);
///
/// The PFXExportCertStoreEx function exports the certificates and, if available, their associated private keys from the
/// referenced certificate store. This function replaces the older PfxExportCertStore function. It should be used for its enhanced
/// private key security. The PFX BLOB created by this function is protected by a password.
///
/// Handle of the certificate store containing the certificates to be exported.
///
/// A pointer to a CRYPT_DATA_BLOB structure to contain the PFX packet with the exported certificates and keys. If pPFX->pbData
/// is NULL, the function calculates the number of bytes needed for the encoded BLOB and returns this in pPFX->cbData.
/// When the function is called with pPFX->pbData pointing to an allocated buffer of the needed size, the function copies the
/// encoded bytes into the buffer and updates pPFX->cbData with the encode byte length.
///
///
/// String password used to encrypt and verify the PFX packet. When you have finished using the password, clear the password from
/// memory by calling the SecureZeroMemory function. For more information about protecting passwords, see Handling Passwords.
///
///
///
/// This parameter must be NULL if the dwFlags parameter does not contain PKCS12_PROTECT_TO_DOMAIN_SIDS. Prior to
/// Windows 8 and Windows Server 2012, therefore, this parameter must be NULL.
///
///
/// Beginning with Windows 8 and Windows Server 2012, if the dwFlags parameter contains PKCS12_PROTECT_TO_DOMAIN_SIDS, you
/// can set the pvPara parameter to point to an NCRYPT_DESCRIPTOR_HANDLE value to identify which Active Directory principal
/// the PFX password will be protected to inside of the PFX BLOB. Currently, the password can be protected to an Active Directory
/// user, computer, or group. For more information about protection descriptors, see NCryptCreateProtectionDescriptor.
///
///
///
/// Flag values can be set to any combination of the following.
///
///
/// Value
/// Meaning
///
/// -
/// EXPORT_PRIVATE_KEYS 0x0004
/// Private keys are exported as well as the certificates.
///
/// -
/// REPORT_NO_PRIVATE_KEY 0x0001
///
/// If a certificate is encountered that has no associated private key, the function returns FALSE with the last error set to either
/// CRYPT_E_NOT_FOUND or NTE_NO_KEY.
///
///
/// -
/// REPORT_NOT_ABLE_TO_EXPORT_PRIVATE_KEY 0x0002
///
/// If a certificate is encountered that has a non-exportable private key, the function returns FALSE and the last error set to
/// NTE_BAD_KEY, NTE_BAD_KEY_STATE, or NTE_PERM.
///
///
/// -
/// PKCS12_INCLUDE_EXTENDED_PROPERTIES 0x0010
/// Export all extended properties on the certificate. Windows Server 2003 and Windows XP: This value is not supported.
///
/// -
/// PKCS12_PROTECT_TO_DOMAIN_SIDS 0x0020
///
/// The PFX BLOB contains an embedded password that will be protected to the Active Directory (AD) protection descriptor pointed to
/// by the pvPara parameter. If the szPassword parameter is not NULL or empty, the specified password is protected. If, however, the
/// szPassword parameter is NULL or an empty string, a random forty (40) character password is created and protected.
/// PFXImportCertStore uses the specified protection descriptor to decrypt the embedded password, whether specified by the user or
/// randomly generated, and then uses the password to decrypt the PFX BLOB. Windows 8 and Windows Server 2012: Support for this flag begins.
///
///
///
///
///
/// Returns TRUE (nonzero) if the function succeeds, and FALSE (zero) if the function fails. For extended error
/// information, call GetLastError.
///
///
/// Beginning with Windows 8 and Windows Server 2012, you can protect the PFX password to an Active Directory user, computer, or
/// group. If you choose to do so but do not create a password, a temporary password will be randomly selected. The password is
/// encrypted by using the Active Directory principal and then embedded in the PFX BLOB. For more information, see the pvPara
/// parameter and the PKCS12_PROTECT_TO_DOMAIN_SIDS flag.
///
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-pfxexportcertstoreex BOOL PFXExportCertStoreEx(
// HCERTSTORE hStore, CRYPT_DATA_BLOB *pPFX, LPCWSTR szPassword, void *pvPara, DWORD dwFlags );
[DllImport(Lib.Crypt32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "e8bd54b1-946f-4c65-8a86-96f0dbec07ff")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool PFXExportCertStoreEx([In] HCERTSTORE hStore, ref CRYPTOAPI_BLOB pPFX, [MarshalAs(UnmanagedType.LPWStr)] string szPassword, [In] IntPtr pvPara, PFXExportFlags dwFlags);
///
/// The PFXImportCertStore function imports a PFX BLOB and returns the handle of a store that contains certificates and any
/// associated private keys.
///
///
/// A pointer to a CRYPT_DATA_BLOB structure that contains a PFX packet with the exported and encrypted certificates and keys.
///
///
///
/// A string password used to decrypt and verify the PFX packet. Whether set to a string of length greater than zero or set to an
/// empty string or to NULL, this value must be exactly the same as the value that was used to encrypt the packet.
///
///
/// Beginning with Windows 8 and Windows Server 2012, if the PFX packet was created in the PFXExportCertStoreEx function by using
/// the PKCS12_PROTECT_TO_DOMAIN_SIDS flag, the PFXImportCertStore function attempts to decrypt the password by using
/// the Active Directory (AD) principal that was used to encrypt it. The AD principal is specified in the pvPara parameter. If the
/// szPassword parameter in the PFXExportCertStoreEx function was an empty string or NULL and the dwFlags parameter
/// was set to PKCS12_PROTECT_TO_DOMAIN_SIDS, that function randomly generated a password and encrypted it to the AD
/// principal specified in the pvPara parameter. In that case you should set the password to the value, empty string or NULL,
/// that was used when the PFX packet was created. The PFXImportCertStore function will use the AD principal to decrypt the
/// random password, and the randomly generated password will be used to decrypt the PFX certificate.
///
///
/// When you have finished using the password, clear it from memory by calling the SecureZeroMemory function. For more information
/// about protecting passwords, see Handling Passwords.
///
///
///
/// This parameter can be one of the following values.
///
///
/// Value
/// Meaning
///
/// -
/// CRYPT_EXPORTABLE 0x00000001
///
/// Imported keys are marked as exportable. If this flag is not used, calls to the CryptExportKey function with the key handle fail.
///
///
/// -
/// CRYPT_USER_PROTECTED 0x00000002
///
/// The user is to be notified through a dialog box or other method when certain attempts to use this key are made. The precise
/// behavior is specified by the cryptographic service provider (CSP) being used. Prior to Internet Explorer 4.0, Microsoft
/// cryptographic service providers ignored this flag. Starting with Internet Explorer 4.0, Microsoft providers support this flag.
/// If the provider context was opened with the CRYPT_SILENT flag set, using this flag causes a failure and the last error is set to NTE_SILENT_CONTEXT.
///
///
/// -
/// CRYPT_MACHINE_KEYSET 0x00000020
/// The private keys are stored under the local computer and not under the current user.
///
/// -
/// CRYPT_USER_KEYSET 0x00001000
///
/// The private keys are stored under the current user and not under the local computer even if the PFX BLOB specifies that they
/// should go into the local computer.
///
///
/// -
/// PKCS12_PREFER_CNG_KSP 0x00000100
///
/// Indicates that the CNG key storage provider (KSP) is preferred. If the CSP is specified in the PFX file, then the CSP is used,
/// otherwise the KSP is preferred. If the CNG KSP is unavailable, the PFXImportCertStore function will fail. Windows Server 2003
/// and Windows XP: This value is not supported.
///
///
/// -
/// PKCS12_ALWAYS_CNG_KSP 0x00000200
///
/// Indicates that the CNG KSP is always used. When specified, PFXImportCertStore attempts to use the CNG KSP irrespective of
/// provider information in the PFX file. If the CNG KSP is unavailable, the import will not fail. Windows Server 2003 and Windows
/// XP: This value is not supported.
///
///
/// -
/// PKCS12_ALLOW_OVERWRITE_KEY 0x00004000
///
/// Allow overwrite of the existing key. Specify this flag when you encounter a scenario in which you must import a PFX file that
/// contains a key name that already exists. For example, when you import a PFX file, it is possible that a container of the same
/// name is already present because there is no unique namespace for key containers. If you have created a "TestKey" on your
/// computer, and then you import a PFX file that also has "TestKey" as the key container, the PKCS12_ALLOW_OVERWRITE_KEY setting
/// allows the key to be overwritten. Windows Server 2003 and Windows XP: This value is not supported.
///
///
/// -
/// PKCS12_NO_PERSIST_KEY 0x00008000
///
/// Do not persist the key. Specify this flag when you do not want to persist the key. For example, if it is not necessary to store
/// the key after verification, then instead of creating a container and then deleting it, you can specify this flag to dispose of
/// the key immediately. Windows Server 2003 and Windows XP: This value is not supported.
///
///
/// -
/// PKCS12_INCLUDE_EXTENDED_PROPERTIES 0x0010
///
/// Import all extended properties on the certificate that were saved on the certificate when it was exported. Windows Server 2003
/// and Windows XP: This value is not supported.
///
///
/// -
/// 0x10000000
/// Unpack but do not persist the results.
///
///
///
///
///
/// If the function succeeds, the function returns a handle to a certificate store that contains the imported certificates,
/// including available private keys.
///
///
/// If the function fails, that is, if the password parameter does not contain an exact match with the password used to encrypt the
/// exported packet or if there were any other problems decoding the PFX BLOB, the function returns NULL, and an error code
/// can be found by calling the GetLastError function.
///
///
///
///
/// The PFXImportCertStore function opens a temporary store. If the function succeeds, you should close the handle to the
/// store by calling the CertCloseStore function.
///
///
/// When you import a certificate from the PFX packet, the CSP/KSP container name is determined by using the AttributeId with OID
/// 1.3.6.1.4.1.311.17.1 of the PKCS8ShroudedKeyBag SafeBag [bagId: 1.2.840.113549.1.12.10.1.2] (see PKCS #12 for details about the
/// ASN.1 structure of this).
///
///
/// If the AttributeId is not present and the PREFER_CNG flag is passed, MS_KEY_STORAGE_PROVIDER is picked. If the AttributeId is
/// not present and the PREFER_CNG flag is not passed, the provider name is determined based on the public key algorithm (that is,
/// the public key algorithm is determined by the AlgorithmIdentifier in PKCS #8):
///
/// Similarly, the key specification is determined by using the AttributeId with OID 2.5.29.15 (szOID_KEY_USAGE) as follows:
///
/// If the AttributeId is not present, then the CAPI key value is set to AT_KEYEXCHANGE for RSA or DH and the algorithm is
/// determined by the AlgorithmIdentifier in PKCS #8; otherwise, the algorithm is set to AT_SIGNATURE. For the CNG key value, all
/// ncrypt key usage is set.
///
///
/// Note If an invalid provider name is present in the PFX packet, or the base or enhanced cryptography provider is not
/// present in this registry key: HKEY_LOCAL_MACHINE\ SOFTWARE\ Microsoft\ Cryptography\
/// Defaults\ Provider, then a provider lookup is performed by the provider type using this registry subkey:
/// HKEY_LOCAL_MACHINE\ SOFTWARE\ Microsoft\ Cryptography\ Defaults\ Provider Types.
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-pfximportcertstore HCERTSTORE PFXImportCertStore(
// CRYPT_DATA_BLOB *pPFX, LPCWSTR szPassword, DWORD dwFlags );
[DllImport(Lib.Crypt32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "2c83774a-f2df-4d28-9abd-e39aa507ba88")]
public static extern HCERTSTORE PFXImportCertStore(in CRYPTOAPI_BLOB pPFX, [MarshalAs(UnmanagedType.LPWStr)] string szPassword, PFXImportFlags dwFlags);
/// The PFXIsPFXBlob function attempts to decode the outer layer of a BLOB as a PFX packet.
/// A pointer to a CRYPT_DATA_BLOB structure that the function will attempt to decode as a PFX packet.
///
/// The function returns TRUE if the BLOB can be decoded as a PFX packet. If the outer layer of the BLOB cannot be decoded as
/// a PFX packet, the function returns FALSE.
///
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-pfxispfxblob BOOL PFXIsPFXBlob( CRYPT_DATA_BLOB *pPFX );
[DllImport(Lib.Crypt32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "28984407-0a28-48e1-9d67-37a6e9db7601")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool PFXIsPFXBlob(in CRYPTOAPI_BLOB pPFX);
///
///
/// The PFXVerifyPassword function attempts to decode the outer layer of a BLOB as a Personal Information Exchange (PFX)
/// packet and to decrypt it with the given password. No data from the BLOB is imported.
///
/// The PFX format is also known as the Public-Key Cryptography Standards #12 (PKCS #12) format.
///
/// A pointer to a CRYPT_DATA_BLOB structure that the function will attempt to decode as a PFX packet.
///
///
/// String password to be checked. For this function to succeed, this password must be exactly the same as the password used to
/// encrypt the packet.
///
///
/// If you set this value to an empty string or NULL, this function typically attempts to decrypt the password embedded in
/// the PFX BLOB by using the empty string or NULL.
///
///
/// However, beginning with Windows 8 and Windows Server 2012, if a NULL or empty password was specified when the PFX BLOB
/// was created and the application also specified that the password should be protected to an Active Directory (AD) principal, the
/// Cryptography API (CAPI) randomly generates a password, encrypts it to the AD principal and embeds it in the PFX BLOB. The
/// PFXVerifyPassword function will then try to use the specified AD principal (current user, computer, or AD group member)
/// to decrypt the password. For more information about protecting PFX to an AD principal, see the pvPara parameter and the
/// PKCS12_PROTECT_TO_DOMAIN_SIDS flag of the PFXExportCertStoreEx function.
///
///
/// When you have finished using the password, clear the password from memory by calling the SecureZeroMemory function. For more
/// information about protecting passwords, see Handling Passwords.
///
///
/// Reserved for future use.
/// The function return TRUE if the password appears correct; otherwise, it returns FALSE.
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-pfxverifypassword BOOL PFXVerifyPassword( CRYPT_DATA_BLOB
// *pPFX, LPCWSTR szPassword, DWORD dwFlags );
[DllImport(Lib.Crypt32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "47560192-547e-4440-9f10-43327355e1a0")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool PFXVerifyPassword(in CRYPTOAPI_BLOB pPFX, [MarshalAs(UnmanagedType.LPWStr)] string szPassword, uint dwFlags = 0);
}
}