Vanara/PInvoke/Cryptography/Crypt32/dpapi.cs

717 lines
39 KiB
C#

using System;
using System.Runtime.InteropServices;
namespace Vanara.PInvoke
{
/// <summary>Methods and data types found in Crypt32.dll.</summary>
public static partial class Crypt32
{
/// <summary>Flags for CryptProtectData.</summary>
[PInvokeData("dpapi.h", MSDNShortId = "765a68fd-f105-49fc-a738-4a8129eb0770")]
[Flags]
public enum CryptProtectFlags
{
/// <summary>
/// This flag is used for remote situations where presenting a user interface (UI) is not an option. When this flag is set and a
/// UI is specified for either the protect or unprotect operation, the operation fails and GetLastError returns the
/// ERROR_PASSWORD_RESTRICTION code.
/// </summary>
CRYPTPROTECT_UI_FORBIDDEN = 0x1,
/// <summary>
/// When this flag is set, it associates the data encrypted with the current computer instead of with an individual user. Any
/// user on the computer on which CryptProtectData is called can use CryptUnprotectData to decrypt the data.
/// </summary>
CRYPTPROTECT_LOCAL_MACHINE = 0x4,
/// <summary>
/// Force credential synchronize during CryptProtectData(). Synchronize is the only operation that occurs during this operation.
/// </summary>
CRYPTPROTECT_CRED_SYNC = 0x8,
/// <summary>Generate an Audit on protect and unprotect operations.</summary>
CRYPTPROTECT_AUDIT = 0x10,
/// <summary>Protect data with a non-recoverable key.</summary>
CRYPTPROTECT_NO_RECOVERY = 0x20,
/// <summary>Verify the protection of a protected blob.</summary>
CRYPTPROTECT_VERIFY_PROTECTION = 0x40,
/// <summary>Regenerate the local machine protection.</summary>
CRYPTPROTECT_CRED_REGENERATE = 0x80
}
/// <summary>Flags for CryptProtectMemory and CryptUnprotectMemory</summary>
[PInvokeData("dpapi.h", MSDNShortId = "6b372552-87d4-4047-afa5-0d1113348289")]
[Flags]
public enum CryptProtectMemoryFlags
{
/// <summary>
/// Encrypt and decrypt memory in the same process. An application running in a different process will not be able to decrypt
/// the data.
/// </summary>
CRYPTPROTECTMEMORY_SAME_PROCESS = 0x00,
/// <summary>
/// Encrypt and decrypt memory in different processes. An application running in a different process will be able to decrypt the data.
/// </summary>
CRYPTPROTECTMEMORY_CROSS_PROCESS = 0x01,
/// <summary>
/// Use the same logon credentials to encrypt and decrypt memory in different processes. An application running in a different
/// process will be able to decrypt the data. However, the process must run as the same user that encrypted the data and in the
/// same logon session.
/// </summary>
CRYPTPROTECTMEMORY_SAME_LOGON = 0x02,
}
/// <summary>Flags that indicate when prompts to the user are to be displayed.</summary>
[PInvokeData("dpapi.h", MSDNShortId = "412ce598-a7c9-446d-bd98-6583a20d6cd7")]
[Flags]
public enum CryptProtectPrompt : uint
{
/// <summary>
/// This flag can be combined with CRYPTPROTECT_PROMPT_ON_PROTECT to enforce the UI (user interface) policy of the caller. When
/// CryptUnprotectData is called, the dwPromptFlags specified in the CryptProtectData call are enforced.
/// </summary>
CRYPTPROTECT_PROMPT_ON_UNPROTECT = 0x1,
/// <summary>This flag is used to provide the prompt for the protect phase.</summary>
CRYPTPROTECT_PROMPT_ON_PROTECT = 0x2,
/// <summary>Reserved.</summary>
CRYPTPROTECT_PROMPT_RESERVED = 0x04,
/// <summary>Default to strong variant UI protection (user supplied password currently).</summary>
CRYPTPROTECT_PROMPT_STRONG = 0x08,
/// <summary>Require strong variant UI protection (user supplied password currently).</summary>
CRYPTPROTECT_PROMPT_REQUIRE_STRONG = 0x10,
}
/// <summary>
/// The <c>CryptProtectData</c> function performs encryption on the data in a DATA_BLOB structure. Typically, only a user with the
/// same logon credential as the user who encrypted the data can decrypt the data. In addition, the encryption and decryption
/// usually must be done on the same computer. For information about exceptions, see Remarks.
/// </summary>
/// <param name="pDataIn">A pointer to a DATA_BLOB structure that contains the plaintext to be encrypted.</param>
/// <param name="szDataDescr">
/// A string with a readable description of the data to be encrypted. This description string is included with the encrypted data.
/// This parameter is optional and can be set to <c>NULL</c>.
/// </param>
/// <param name="pOptionalEntropy">
/// A pointer to a DATA_BLOB structure that contains a password or other additional entropy used to encrypt the data. The
/// <c>DATA_BLOB</c> structure used in the encryption phase must also be used in the decryption phase. This parameter can be set to
/// <c>NULL</c> for no additional entropy. For information about protecting passwords, see Handling Passwords.
/// </param>
/// <param name="pvReserved">Reserved for future use and must be set to <c>NULL</c>.</param>
/// <param name="pPromptStruct">
/// A pointer to a CRYPTPROTECT_PROMPTSTRUCT structure that provides information about where and when prompts are to be displayed
/// and what the content of those prompts should be. This parameter can be set to <c>NULL</c> in both the encryption and decryption phases.
/// </param>
/// <param name="dwFlags">
/// <para>This parameter can be one of the following flags.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>CRYPTPROTECT_LOCAL_MACHINE</term>
/// <term>
/// When this flag is set, it associates the data encrypted with the current computer instead of with an individual user. Any user
/// on the computer on which CryptProtectData is called can use CryptUnprotectData to decrypt the data.
/// </term>
/// </item>
/// <item>
/// <term>CRYPTPROTECT_UI_FORBIDDEN</term>
/// <term>
/// This flag is used for remote situations where presenting a user interface (UI) is not an option. When this flag is set and a UI
/// is specified for either the protect or unprotect operation, the operation fails and GetLastError returns the
/// ERROR_PASSWORD_RESTRICTION code.
/// </term>
/// </item>
/// <item>
/// <term>CRYPTPROTECT_AUDIT</term>
/// <term>This flag generates an audit on protect and unprotect operations.</term>
/// </item>
/// </list>
/// </param>
/// <param name="pDataOut">
/// A pointer to a DATA_BLOB structure that receives the encrypted data. When you have finished using the <c>DATA_BLOB</c>
/// structure, free its <c>pbData</c> member by calling the LocalFree function.
/// </param>
/// <returns>
/// <para>If the function succeeds, the function returns <c>TRUE</c>.</para>
/// <para>If the function fails, it returns <c>FALSE</c>. For extended error information, call GetLastError.</para>
/// </returns>
/// <remarks>
/// <para>
/// Typically, only a user with logon credentials that match those of the user who encrypted the data can decrypt the data. In
/// addition, decryption usually can only be done on the computer where the data was encrypted. However, a user with a roaming
/// profile can decrypt the data from another computer on the network.
/// </para>
/// <para>
/// If the CRYPTPROTECT_LOCAL_MACHINE flag is set when the data is encrypted, any user on the computer where the encryption was done
/// can decrypt the data.
/// </para>
/// <para>
/// The function creates a session key to perform the encryption. The session key is derived again when the data is to be decrypted.
/// </para>
/// <para>
/// The function also adds a Message Authentication Code (MAC) (keyed integrity check) to the encrypted data to guard against data tampering.
/// </para>
/// <para>To encrypt memory for temporary use in the same process or across processes, call the CryptProtectMemory function.</para>
/// <para>Examples</para>
/// <para>
/// The following example shows encryption of the data in a DATA_BLOB structure. The <c>CryptProtectData</c> function does the
/// encryption by using a session key that the function creates by using the user's logon credentials. For another example that uses
/// this function, see Example C Program: Using CryptProtectData.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/dpapi/nf-dpapi-cryptprotectdata DPAPI_IMP BOOL CryptProtectData( DATA_BLOB
// *pDataIn, LPCWSTR szDataDescr, DATA_BLOB *pOptionalEntropy, PVOID pvReserved, CRYPTPROTECT_PROMPTSTRUCT *pPromptStruct, DWORD
// dwFlags, DATA_BLOB *pDataOut );
[DllImport(Lib.Crypt32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("dpapi.h", MSDNShortId = "765a68fd-f105-49fc-a738-4a8129eb0770")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptProtectData(in CRYPTOAPI_BLOB pDataIn, [Optional, MarshalAs(UnmanagedType.LPWStr)] string szDataDescr, in CRYPTOAPI_BLOB pOptionalEntropy,
[Optional] IntPtr pvReserved, in CRYPTPROTECT_PROMPTSTRUCT pPromptStruct, CryptProtectFlags dwFlags, IntPtr pDataOut);
/// <summary>
/// The <c>CryptProtectData</c> function performs encryption on the data in a DATA_BLOB structure. Typically, only a user with the
/// same logon credential as the user who encrypted the data can decrypt the data. In addition, the encryption and decryption
/// usually must be done on the same computer. For information about exceptions, see Remarks.
/// </summary>
/// <param name="pDataIn">A pointer to a DATA_BLOB structure that contains the plaintext to be encrypted.</param>
/// <param name="szDataDescr">
/// A string with a readable description of the data to be encrypted. This description string is included with the encrypted data.
/// This parameter is optional and can be set to <c>NULL</c>.
/// </param>
/// <param name="pOptionalEntropy">
/// A pointer to a DATA_BLOB structure that contains a password or other additional entropy used to encrypt the data. The
/// <c>DATA_BLOB</c> structure used in the encryption phase must also be used in the decryption phase. This parameter can be set to
/// <c>NULL</c> for no additional entropy. For information about protecting passwords, see Handling Passwords.
/// </param>
/// <param name="pvReserved">Reserved for future use and must be set to <c>NULL</c>.</param>
/// <param name="pPromptStruct">
/// A pointer to a CRYPTPROTECT_PROMPTSTRUCT structure that provides information about where and when prompts are to be displayed
/// and what the content of those prompts should be. This parameter can be set to <c>NULL</c> in both the encryption and decryption phases.
/// </param>
/// <param name="dwFlags">
/// <para>This parameter can be one of the following flags.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>CRYPTPROTECT_LOCAL_MACHINE</term>
/// <term>
/// When this flag is set, it associates the data encrypted with the current computer instead of with an individual user. Any user
/// on the computer on which CryptProtectData is called can use CryptUnprotectData to decrypt the data.
/// </term>
/// </item>
/// <item>
/// <term>CRYPTPROTECT_UI_FORBIDDEN</term>
/// <term>
/// This flag is used for remote situations where presenting a user interface (UI) is not an option. When this flag is set and a UI
/// is specified for either the protect or unprotect operation, the operation fails and GetLastError returns the
/// ERROR_PASSWORD_RESTRICTION code.
/// </term>
/// </item>
/// <item>
/// <term>CRYPTPROTECT_AUDIT</term>
/// <term>This flag generates an audit on protect and unprotect operations.</term>
/// </item>
/// </list>
/// </param>
/// <param name="pDataOut">
/// A pointer to a DATA_BLOB structure that receives the encrypted data. When you have finished using the <c>DATA_BLOB</c>
/// structure, free its <c>pbData</c> member by calling the LocalFree function.
/// </param>
/// <returns>
/// <para>If the function succeeds, the function returns <c>TRUE</c>.</para>
/// <para>If the function fails, it returns <c>FALSE</c>. For extended error information, call GetLastError.</para>
/// </returns>
/// <remarks>
/// <para>
/// Typically, only a user with logon credentials that match those of the user who encrypted the data can decrypt the data. In
/// addition, decryption usually can only be done on the computer where the data was encrypted. However, a user with a roaming
/// profile can decrypt the data from another computer on the network.
/// </para>
/// <para>
/// If the CRYPTPROTECT_LOCAL_MACHINE flag is set when the data is encrypted, any user on the computer where the encryption was done
/// can decrypt the data.
/// </para>
/// <para>
/// The function creates a session key to perform the encryption. The session key is derived again when the data is to be decrypted.
/// </para>
/// <para>
/// The function also adds a Message Authentication Code (MAC) (keyed integrity check) to the encrypted data to guard against data tampering.
/// </para>
/// <para>To encrypt memory for temporary use in the same process or across processes, call the CryptProtectMemory function.</para>
/// <para>Examples</para>
/// <para>
/// The following example shows encryption of the data in a DATA_BLOB structure. The <c>CryptProtectData</c> function does the
/// encryption by using a session key that the function creates by using the user's logon credentials. For another example that uses
/// this function, see Example C Program: Using CryptProtectData.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/dpapi/nf-dpapi-cryptprotectdata DPAPI_IMP BOOL CryptProtectData( DATA_BLOB
// *pDataIn, LPCWSTR szDataDescr, DATA_BLOB *pOptionalEntropy, PVOID pvReserved, CRYPTPROTECT_PROMPTSTRUCT *pPromptStruct, DWORD
// dwFlags, DATA_BLOB *pDataOut );
[DllImport(Lib.Crypt32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("dpapi.h", MSDNShortId = "765a68fd-f105-49fc-a738-4a8129eb0770")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptProtectData(in CRYPTOAPI_BLOB pDataIn, [Optional, MarshalAs(UnmanagedType.LPWStr)] string szDataDescr, [Optional] IntPtr pOptionalEntropy,
[Optional] IntPtr pvReserved, [Optional] IntPtr pPromptStruct, CryptProtectFlags dwFlags, IntPtr pDataOut);
/// <summary>
/// The <c>CryptProtectMemory</c> function encrypts memory to prevent others from viewing sensitive information in your process. For
/// example, use the <c>CryptProtectMemory</c> function to encrypt memory that contains a password. Encrypting the password prevents
/// others from viewing it when the process is paged out to the swap file. Otherwise, the password is in plaintext and viewable by others.
/// </summary>
/// <param name="pDataIn">
/// A pointer to the block of memory to encrypt. The cbData parameter specifies the number of bytes that will be encrypted. If the
/// data contained in the memory space is smaller than the number of bytes specified, data outside of the intended block will be
/// encrypted. If it is larger than cbData bytes, then only the first cbData bytes will be encrypted.
/// </param>
/// <param name="cbDataIn">
/// Number of bytes of memory pointed to by the pData parameter to encrypt. The number of bytes must be a multiple of the
/// <c>CRYPTPROTECTMEMORY_BLOCK_SIZE</c> constant defined in Wincrypt.h.
/// </param>
/// <param name="dwFlags">
/// <para>This parameter can be one of the following flags. You must specify the same flag when encrypting and decrypting the memory.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>CRYPTPROTECTMEMORY_SAME_PROCESS</term>
/// <term>
/// Encrypt and decrypt memory in the same process. An application running in a different process will not be able to decrypt the data.
/// </term>
/// </item>
/// <item>
/// <term>CRYPTPROTECTMEMORY_CROSS_PROCESS</term>
/// <term>
/// Encrypt and decrypt memory in different processes. An application running in a different process will be able to decrypt the data.
/// </term>
/// </item>
/// <item>
/// <term>CRYPTPROTECTMEMORY_SAME_LOGON</term>
/// <term>
/// Use the same logon credentials to encrypt and decrypt memory in different processes. An application running in a different
/// process will be able to decrypt the data. However, the process must run as the same user that encrypted the data and in the same
/// logon session.
/// </term>
/// </item>
/// </list>
/// </param>
/// <returns>
/// <para>If the function succeeds, the function returns <c>TRUE</c>.</para>
/// <para>If the function fails, it returns <c>FALSE</c>. For extended error information, call GetLastError.</para>
/// </returns>
/// <remarks>
/// <para>
/// Using CryptProtectMemory and CryptUnprotectMemory for password encryption is not secure because the data exists as plaintext in
/// memory before it is encrypted and at any time the caller decrypts it for use.
/// </para>
/// <para>
/// Typically, you use the <c>CryptProtectMemory</c> function to encrypt sensitive information that you are going to decrypt while
/// your process is running. Do not use this function to save data that you want to decrypt later; you will not be able to decrypt
/// the data if the computer is restarted. To save encrypted data to a file to decrypt later, use the CryptProtectData function.
/// </para>
/// <para>
/// Call the CryptUnprotectMemory function to decrypt memory encrypted with the <c>CryptProtectMemory</c> function. When you have
/// finished using the sensitive information, clear it from memory by calling the SecureZeroMemory function.
/// </para>
/// <para>
/// Use the CRYPTPROTECTMEMORY_CROSS_PROCESS or CRYPTPROTECTMEMORY_SAME_LOGON flag if you use RPC or LRPC to pass encrypted data to
/// another process. The receiving process must specify the same flag to decrypt the data. Also, use these flags if you use shared memory.
/// </para>
/// <para>
/// If the client uses the CRYPTPROTECTMEMORY_SAME_LOGON flag, the server must impersonate the client (RpcImpersonateClient) before
/// decrypting the memory.
/// </para>
/// <para>Examples</para>
/// <para>The following example calls the <c>CryptProtectMemory</c> function to encrypt data that is in memory.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/dpapi/nf-dpapi-cryptprotectmemory DPAPI_IMP BOOL CryptProtectMemory( LPVOID
// pDataIn, DWORD cbDataIn, DWORD dwFlags );
[DllImport(Lib.Crypt32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("dpapi.h", MSDNShortId = "6b372552-87d4-4047-afa5-0d1113348289")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptProtectMemory(IntPtr pDataIn, uint cbDataIn, CryptProtectMemoryFlags dwFlags);
/// <summary>
/// The <c>CryptUnprotectData</c> function decrypts and does an integrity check of the data in a DATA_BLOB structure. Usually, the
/// only user who can decrypt the data is a user with the same logon credentials as the user who encrypted the data. In addition,
/// the encryption and decryption must be done on the same computer. For information about exceptions, see the Remarks section of CryptProtectData.
/// </summary>
/// <param name="pDataIn">
/// A pointer to a DATA_BLOB structure that holds the encrypted data. The <c>DATA_BLOB</c> structure's <c>cbData</c> member holds
/// the length of the <c>pbData</c> member's byte string that contains the text to be encrypted.
/// </param>
/// <param name="ppszDataDescr">
/// A pointer to a string-readable description of the encrypted data included with the encrypted data. This parameter can be set to
/// <c>NULL</c>. When you have finished using ppszDataDescr, free it by calling the LocalFree function.
/// </param>
/// <param name="pOptionalEntropy">
/// A pointer to a DATA_BLOB structure that contains a password or other additional entropy used when the data was encrypted. This
/// parameter can be set to <c>NULL</c>; however, if an optional entropy <c>DATA_BLOB</c> structure was used in the encryption
/// phase, that same <c>DATA_BLOB</c> structure must be used for the decryption phase. For information about protecting passwords,
/// see Handling Passwords.
/// </param>
/// <param name="pvReserved">This parameter is reserved for future use and must be set to <c>NULL</c>.</param>
/// <param name="pPromptStruct">
/// A pointer to a CRYPTPROTECT_PROMPTSTRUCT structure that provides information about where and when prompts are to be displayed
/// and what the content of those prompts should be. This parameter can be set to <c>NULL</c>.
/// </param>
/// <param name="dwFlags">
/// <para>
/// A <c>DWORD</c> value that specifies options for this function. This parameter can be zero, in which case no option is set, or
/// the following flag.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>CRYPTPROTECT_UI_FORBIDDEN</term>
/// <term>
/// This flag is used for remote situations where the user interface (UI) is not an option. When this flag is set and UI is
/// specified for either the protect or unprotect operation, the operation fails and GetLastError returns the
/// ERROR_PASSWORD_RESTRICTION code.
/// </term>
/// </item>
/// <item>
/// <term>CRYPTPROTECT_VERIFY_PROTECTION</term>
/// <term>
/// This flag verifies the protection of a protected BLOB. If the default protection level configured of the host is higher than the
/// current protection level for the BLOB, the function returns CRYPT_I_NEW_PROTECTION_REQUIRED to advise the caller to again
/// protect the plaintext contained in the BLOB.
/// </term>
/// </item>
/// </list>
/// </param>
/// <param name="pDataOut">
/// A pointer to a DATA_BLOB structure where the function stores the decrypted data. When you have finished using the
/// <c>DATA_BLOB</c> structure, free its <c>pbData</c> member by calling the LocalFree function.
/// </param>
/// <returns>
/// <para>If the function succeeds, the function returns <c>TRUE</c>.</para>
/// <para>If the function fails, it returns <c>FALSE</c>.</para>
/// </returns>
/// <remarks>
/// <para>
/// The CryptProtectData function creates a session key when the data is encrypted. That key is derived again and used to decrypt
/// the data BLOB.
/// </para>
/// <para>
/// The Message Authentication Code (MAC) hash added to the encrypted data can be used to determine whether the encrypted data was
/// altered in any way. Any tampering results in the return of the ERROR_INVALID_DATA code.
/// </para>
/// <para>
/// When you have finished using the DATA_BLOB structure, free its <c>pbData</c> member by calling the LocalFree function. Any
/// ppszDataDescr that is not <c>NULL</c> must also be freed by using <c>LocalFree</c>.
/// </para>
/// <para>When you have finished using sensitive information, clear it from memory by calling the SecureZeroMemory function.</para>
/// <para>Examples</para>
/// <para>
/// The following example shows decrypting encrypted data in a DATA_BLOB structure. This function does the decryption by using a
/// session key that the function creates by using the user's logon credentials. For another example that uses this function, see
/// Example C Program: Using CryptProtectData.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/dpapi/nf-dpapi-cryptunprotectdata DPAPI_IMP BOOL CryptUnprotectData( DATA_BLOB
// *pDataIn, LPWSTR *ppszDataDescr, DATA_BLOB *pOptionalEntropy, PVOID pvReserved, CRYPTPROTECT_PROMPTSTRUCT *pPromptStruct, DWORD
// dwFlags, DATA_BLOB *pDataOut );
[DllImport(Lib.Crypt32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("dpapi.h", MSDNShortId = "54eab3b0-d341-47c6-9c32-79328d7a7155")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptUnprotectData(in CRYPTOAPI_BLOB pDataIn, [MarshalAs(UnmanagedType.LPWStr)] out IntPtr ppszDataDescr,
in CRYPTOAPI_BLOB pOptionalEntropy, [Optional] IntPtr pvReserved, in CRYPTPROTECT_PROMPTSTRUCT pPromptStruct, CryptProtectFlags dwFlags, [Out] IntPtr pDataOut);
/// <summary>
/// The <c>CryptUnprotectData</c> function decrypts and does an integrity check of the data in a DATA_BLOB structure. Usually, the
/// only user who can decrypt the data is a user with the same logon credentials as the user who encrypted the data. In addition,
/// the encryption and decryption must be done on the same computer. For information about exceptions, see the Remarks section of CryptProtectData.
/// </summary>
/// <param name="pDataIn">
/// A pointer to a DATA_BLOB structure that holds the encrypted data. The <c>DATA_BLOB</c> structure's <c>cbData</c> member holds
/// the length of the <c>pbData</c> member's byte string that contains the text to be encrypted.
/// </param>
/// <param name="ppszDataDescr">
/// A pointer to a string-readable description of the encrypted data included with the encrypted data. This parameter can be set to
/// <c>NULL</c>. When you have finished using ppszDataDescr, free it by calling the LocalFree function.
/// </param>
/// <param name="pOptionalEntropy">
/// A pointer to a DATA_BLOB structure that contains a password or other additional entropy used when the data was encrypted. This
/// parameter can be set to <c>NULL</c>; however, if an optional entropy <c>DATA_BLOB</c> structure was used in the encryption
/// phase, that same <c>DATA_BLOB</c> structure must be used for the decryption phase. For information about protecting passwords,
/// see Handling Passwords.
/// </param>
/// <param name="pvReserved">This parameter is reserved for future use and must be set to <c>NULL</c>.</param>
/// <param name="pPromptStruct">
/// A pointer to a CRYPTPROTECT_PROMPTSTRUCT structure that provides information about where and when prompts are to be displayed
/// and what the content of those prompts should be. This parameter can be set to <c>NULL</c>.
/// </param>
/// <param name="dwFlags">
/// <para>
/// A <c>DWORD</c> value that specifies options for this function. This parameter can be zero, in which case no option is set, or
/// the following flag.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>CRYPTPROTECT_UI_FORBIDDEN</term>
/// <term>
/// This flag is used for remote situations where the user interface (UI) is not an option. When this flag is set and UI is
/// specified for either the protect or unprotect operation, the operation fails and GetLastError returns the
/// ERROR_PASSWORD_RESTRICTION code.
/// </term>
/// </item>
/// <item>
/// <term>CRYPTPROTECT_VERIFY_PROTECTION</term>
/// <term>
/// This flag verifies the protection of a protected BLOB. If the default protection level configured of the host is higher than the
/// current protection level for the BLOB, the function returns CRYPT_I_NEW_PROTECTION_REQUIRED to advise the caller to again
/// protect the plaintext contained in the BLOB.
/// </term>
/// </item>
/// </list>
/// </param>
/// <param name="pDataOut">
/// A pointer to a DATA_BLOB structure where the function stores the decrypted data. When you have finished using the
/// <c>DATA_BLOB</c> structure, free its <c>pbData</c> member by calling the LocalFree function.
/// </param>
/// <returns>
/// <para>If the function succeeds, the function returns <c>TRUE</c>.</para>
/// <para>If the function fails, it returns <c>FALSE</c>.</para>
/// </returns>
/// <remarks>
/// <para>
/// The CryptProtectData function creates a session key when the data is encrypted. That key is derived again and used to decrypt
/// the data BLOB.
/// </para>
/// <para>
/// The Message Authentication Code (MAC) hash added to the encrypted data can be used to determine whether the encrypted data was
/// altered in any way. Any tampering results in the return of the ERROR_INVALID_DATA code.
/// </para>
/// <para>
/// When you have finished using the DATA_BLOB structure, free its <c>pbData</c> member by calling the LocalFree function. Any
/// ppszDataDescr that is not <c>NULL</c> must also be freed by using <c>LocalFree</c>.
/// </para>
/// <para>When you have finished using sensitive information, clear it from memory by calling the SecureZeroMemory function.</para>
/// <para>Examples</para>
/// <para>
/// The following example shows decrypting encrypted data in a DATA_BLOB structure. This function does the decryption by using a
/// session key that the function creates by using the user's logon credentials. For another example that uses this function, see
/// Example C Program: Using CryptProtectData.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/dpapi/nf-dpapi-cryptunprotectdata DPAPI_IMP BOOL CryptUnprotectData( DATA_BLOB
// *pDataIn, LPWSTR *ppszDataDescr, DATA_BLOB *pOptionalEntropy, PVOID pvReserved, CRYPTPROTECT_PROMPTSTRUCT *pPromptStruct, DWORD
// dwFlags, DATA_BLOB *pDataOut );
[DllImport(Lib.Crypt32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("dpapi.h", MSDNShortId = "54eab3b0-d341-47c6-9c32-79328d7a7155")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptUnprotectData(in CRYPTOAPI_BLOB pDataIn, [Optional] IntPtr ppszDataDescr,
[Optional] IntPtr pOptionalEntropy, [Optional] IntPtr pvReserved, [Optional] IntPtr pPromptStruct, CryptProtectFlags dwFlags, [Out] IntPtr pDataOut);
/// <summary>The <c>CryptUnprotectMemory</c> function decrypts memory that was encrypted using the CryptProtectMemory function.</summary>
/// <param name="pDataIn">
/// A pointer to the block of memory to decrypt. The cbData parameter specifies the number of bytes that the function will attempt
/// to decrypt. If the data contained in the memory space is smaller than the number of bytes specified, the function will attempt
/// to decrypt data outside of the intended block. If it is larger than cbData bytes, then only the first cbData bytes will be decrypted.
/// </param>
/// <param name="cbDataIn">
/// Number of bytes of memory pointed to by the pData parameter to decrypt. The number of bytes must be a multiple of the
/// <c>CRYPTPROTECTMEMORY_BLOCK_SIZE</c> constant defined in Wincrypt.h.
/// </param>
/// <param name="dwFlags">
/// <para>This parameter can be one of the following flags. You must specify the same flag when encrypting and decrypting the memory.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>CRYPTPROTECTMEMORY_SAME_PROCESS</term>
/// <term>
/// Encrypt and decrypt memory in the same process. An application running in a different process will not be able to decrypt the data.
/// </term>
/// </item>
/// <item>
/// <term>CRYPTPROTECTMEMORY_CROSS_PROCESS</term>
/// <term>
/// Encrypt and decrypt memory in different processes. An application running in a different process will be able to decrypt the data.
/// </term>
/// </item>
/// <item>
/// <term>CRYPTPROTECTMEMORY_SAME_LOGON</term>
/// <term>
/// Use the same logon credentials to encrypt and decrypt memory in different processes. An application running in a different
/// process will be able to decrypt the data. However, the process must run as the same user that encrypted the data and in the same
/// logon session.
/// </term>
/// </item>
/// </list>
/// </param>
/// <returns>
/// <para>If the function succeeds, the function returns <c>TRUE</c>.</para>
/// <para>If the function fails, it returns <c>FALSE</c>. For extended error information, call GetLastError.</para>
/// </returns>
/// <remarks>
/// <para>
/// Using CryptProtectMemory and CryptUnprotectMemory for password encryption is not secure because the data exists as plaintext in
/// memory before it is encrypted and at any time the caller decrypts it for use.
/// </para>
/// <para>
/// You must encrypt and decrypt the memory during the same boot session. If the computer is restarted before you call the
/// <c>CryptUnprotectMemory</c> function, you will not be able to decrypt the data.
/// </para>
/// <para>
/// You must pass the same flag to <c>CryptUnprotectMemory</c> and CryptProtectMemory. If you pass different flags, the
/// <c>CryptUnprotectMemory</c> function succeeds; however, the result is unpredictable.
/// </para>
/// <para>When you have finished using the sensitive information, clear it from memory by calling the SecureZeroMemory function.</para>
/// <para>Examples</para>
/// <para>
/// The following example calls the <c>CryptUnprotectMemory</c> function to decrypt data that is in memory. The example assumes the
/// variable pEncryptedText points to a string that has been encrypted using the CryptProtectMemory function.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/dpapi/nf-dpapi-cryptunprotectmemory DPAPI_IMP BOOL CryptUnprotectMemory(
// LPVOID pDataIn, DWORD cbDataIn, DWORD dwFlags );
[DllImport(Lib.Crypt32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("dpapi.h", MSDNShortId = "1c7980ac-4e9e-43fd-b6d7-c0d0a69c8040")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptUnprotectMemory(IntPtr pDataIn, uint cbDataIn, CryptProtectMemoryFlags dwFlags);
/// <summary>
/// The <c>CryptUpdateProtectedState</c> function migrates the current user's master keys after the user's security identifier (SID)
/// has changed. This function can be used to preserve encrypted data after a user has been moved from one domain to another.
/// </summary>
/// <param name="pOldSid">
/// <para>
/// The address of a SID structure that contains the user's previous SID. This SID is used to locate the old master keys. If this
/// parameter is <c>NULL</c>, the master keys for the current user SID are migrated.
/// </para>
/// <para>Either this parameter or the pwszOldPassword parameter may be <c>NULL</c>, but not both.</para>
/// </param>
/// <param name="pwszOldPassword">
/// <para>
/// A pointer to a null-terminated Unicode string that contains the user's password before the SID was changed. This password is
/// used to decrypt the old master keys. If this parameter is <c>NULL</c>, the password of the current user will be used.
/// </para>
/// <para>Either this parameter or the pOldSid parameter may be <c>NULL</c>, but not both.</para>
/// </param>
/// <param name="dwFlags">Not used. Must be zero.</param>
/// <param name="pdwSuccessCount">
/// The address of a <c>DWORD</c> variable that receives the number of master keys that were successfully migrated.
/// </param>
/// <param name="pdwFailureCount">
/// <para>The address of a <c>DWORD</c> variable that receives the number of master keys that could not be decrypted.</para>
/// <para>
/// It is not necessarily an error if one or more master keys cannot be decrypted. Some users may possess master keys that are
/// stagnant and could not have been decrypted for a long time. One way that this can happen is when the password of a local user
/// has been administratively reset.
/// </para>
/// </param>
/// <returns>
/// <para>If the function succeeds, the return value is <c>TRUE</c>.</para>
/// <para>
/// If the function fails, the return value is <c>FALSE</c>. For extended error information, call GetLastError. Some possible error
/// codes include the following.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>ERROR_INVALID_PARAMETER</term>
/// <term>One of the parameters contains a value that is not valid.</term>
/// </item>
/// <item>
/// <term>ERROR_OUTOFMEMORY</term>
/// <term>A memory allocation failure occurred.</term>
/// </item>
/// <item>
/// <term>ERROR_ENCRYPTION_FAILED</term>
/// <term>The old password could not be encrypted.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// This function decrypts all of the user's master keys in the old master key directory, using the previous password, and stores
/// them in the user's current master key directory, encrypted with the user's current password.
/// </para>
/// <para>This function must be called from the user account that the keys are being migrated to.</para>
/// <para>
/// If this function is able to successfully migrate an old master key, it will automatically delete the old master key. Master keys
/// that cannot be decrypted are not deleted.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/dpapi/nf-dpapi-cryptupdateprotectedstate DPAPI_IMP BOOL
// CryptUpdateProtectedState( PSID pOldSid, LPCWSTR pwszOldPassword, DWORD dwFlags, DWORD *pdwSuccessCount, DWORD *pdwFailureCount );
[DllImport(Lib.Crypt32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("dpapi.h", MSDNShortId = "f32e8fcd-6b5b-4a43-b3f9-77e17c84deca")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptUpdateProtectedState([Optional] PSID pOldSid, [Optional, MarshalAs(UnmanagedType.LPWStr)] string pwszOldPassword, [Optional] uint dwFlags, out uint pdwSuccessCount, out uint pdwFailureCount);
/// <summary>
/// The <c>CRYPTPROTECT_PROMPTSTRUCT</c> structure provides the text of a prompt and information about when and where that prompt is
/// to be displayed when using the CryptProtectData and CryptUnprotectData functions.
/// </summary>
// https://docs.microsoft.com/en-us/windows/win32/api/dpapi/ns-dpapi-cryptprotect_promptstruct typedef struct
// _CRYPTPROTECT_PROMPTSTRUCT { DWORD cbSize; DWORD dwPromptFlags; HWND hwndApp; LPCWSTR szPrompt; } CRYPTPROTECT_PROMPTSTRUCT, *PCRYPTPROTECT_PROMPTSTRUCT;
[PInvokeData("dpapi.h", MSDNShortId = "412ce598-a7c9-446d-bd98-6583a20d6cd7")]
[StructLayout(LayoutKind.Sequential)]
public struct CRYPTPROTECT_PROMPTSTRUCT
{
/// <summary>The size, in bytes, of this structure.</summary>
public uint cbSize;
/// <summary>
/// <para>
/// <c>DWORD</c> flags that indicate when prompts to the user are to be displayed. Current <c>dwPromptFlags</c> values are as follows.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>CRYPTPROTECT_PROMPT_ON_PROTECT</term>
/// <term>This flag is used to provide the prompt for the protect phase.</term>
/// </item>
/// <item>
/// <term>CRYPTPROTECT_PROMPT_ON_UNPROTECT</term>
/// <term>
/// This flag can be combined with CRYPTPROTECT_PROMPT_ON_PROTECT to enforce the UI (user interface) policy of the caller. When
/// CryptUnprotectData is called, the dwPromptFlags specified in the CryptProtectData call are enforced.
/// </term>
/// </item>
/// </list>
/// </summary>
public CryptProtectPrompt dwPromptFlags;
/// <summary>Window handle to the parent window.</summary>
public HWND hwndApp;
/// <summary>A string containing the text of a prompt to be displayed.</summary>
[MarshalAs(UnmanagedType.LPWStr)] public string szPrompt;
}
}
}