Vanara/PInvoke/Cryptography/Crypt32/Wincrypt.Cert.cs

3679 lines
196 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using Vanara.InteropServices;
namespace Vanara.PInvoke
{
/// <summary>Methods and data types found in Crypt32.dll.</summary>
public static partial class Crypt32
{
/// <summary>A set of flags that override the default behavior of this function.</summary>
[PInvokeData("wincrypt.h", MSDNShortId = "89028c4e-f896-4c50-9fa2-bcb4e1784244")]
[Flags]
public enum CertCreateSelfSignFlags
{
/// <summary>
/// By default, the returned PCCERT_CONTEXT references the private keys by setting the CERT_KEY_PROV_INFO_PROP_ID. If you do not
/// want the returned PCCERT_CONTEXT to reference private keys by setting the CERT_KEY_PROV_INFO_PROP_ID, specify CERT_CREATE_SELFSIGN_NO_KEY_INFO.
/// </summary>
CERT_CREATE_SELFSIGN_NO_KEY_INFO = 2,
/// <summary>
/// By default, the certificate being created is signed. If the certificate being created is only a dummy placeholder, the
/// certificate might not need to be signed. Signing of the certificate is skipped if CERT_CREATE_SELFSIGN_NO_SIGN is specified.
/// </summary>
CERT_CREATE_SELFSIGN_NO_SIGN = 1,
}
/// <summary>Specifies the type of selection criteria used for the <c>ppPara</c> member.</summary>
[PInvokeData("wincrypt.h", MSDNShortId = "246722a9-5db6-4a82-8f29-f60f0a2263e3")]
public enum CertSelectBy : uint
{
/// <summary>
/// Select certificates based on a specific enhanced key usage. When this flag is set, the ppPara must reference a
/// null-terminated object identifier (OID) ANSI string that specifies the enhanced key usage.
/// <para>This criteria is evaluated on the certificate.</para>
/// </summary>
CERT_SELECT_BY_ENHKEY_USAGE = 1,
/// <summary>
/// Select certificates based on a specific szOID_KEY_USAGE extension in the certificate. When this flag is set, the ppPara
/// member must reference a CERT_EXTENSION structure where the value of the extension is a DWORD that identifies the Key Usage bits.
/// <para>This criteria is evaluated on the certificate.</para>
/// </summary>
CERT_SELECT_BY_KEY_USAGE = 2,
/// <summary>
/// Select certificates based on a specific issuance policy. The ppPara member must reference a null-terminated OID ANSI string
/// of the desired issuance policy.
/// <para>This criteria is evaluated on the issuance policy of the certificate chain.</para>
/// </summary>
CERT_SELECT_BY_POLICY_OID = 3,
/// <summary>
/// Select certificates based on a specific private key provider. The ppPara member must reference a null-terminated Unicode
/// string that represents the name of the provider.
/// </summary>
CERT_SELECT_BY_PROV_NAME = 4,
/// <summary>
/// Select certificates based on the presence of a specified extension and an optional specified value. The ppPara member must
/// reference a CERT_EXTENSION structure that specifies the extension OID and the associated value.
/// </summary>
CERT_SELECT_BY_EXTENSION = 5,
/// <summary>
/// Select certificates based on the Subject DNS HOST Name. The ppPara member must reference a null-terminated Unicode string
/// that contains the subject host name. The selection performed based on this flag is the same as the evaluation of the
/// pwszServerName member of the SSL_EXTRA_CERT_CHAIN_POLICY_PARA structure during a call to the
/// CertVerifyCertificateChainPolicy function.
/// <para>This criteria is evaluated on the certificate.</para>
/// </summary>
CERT_SELECT_BY_SUBJECT_HOST_NAME = 6,
/// <summary>
/// Select certificates based on the relative distinguished name (RDN) element of the issuer of the certificate. The ppPara
/// member must reference a CERT_RDN structure that contains the RDN element of the issuer.
/// <para>This criteria is evaluated on the certificate chain.</para>
/// </summary>
CERT_SELECT_BY_ISSUER_ATTR = 7,
/// <summary>
/// Select certificates based on the RDN element in the Subject of the certificate. The ppPara member must be a reference to a
/// CERT_RDN structure that contains the RDN element of the Subject.
/// <para>This criteria is evaluated on the certificate.</para>
/// </summary>
CERT_SELECT_BY_SUBJECT_ATTR = 8,
/// <summary>
/// Select certificates based on the issuer of the certificate. The ppPara member must be a reference to a CERT_NAME_BLOB
/// structure that contains the name of the issuer.
/// <para>This criteria is evaluated on the certificate chain.</para>
/// </summary>
CERT_SELECT_BY_ISSUER_NAME = 9,
/// <summary>
/// Select certificates based on the public key of the certificate. The ppPara member must reference a pointer to a
/// CERT_PUBLIC_KEY_INFO structure that contains the public key.
/// <para>This criteria is evaluated on the certificate.</para>
/// </summary>
CERT_SELECT_BY_PUBLIC_KEY = 10,
/// <summary>
/// Select certificates based on the Transport Layer Security protocol (TLS) Signature requirement. The ppPara member must
/// reference a SecPkgContext_SupportedSignatures structure.
/// <para>This criteria is evaluated on the certificate.</para>
/// </summary>
CERT_SELECT_BY_TLS_SIGNATURES = 11,
}
/// <summary>Flags for controlling the certificate selection process.</summary>
[PInvokeData("wincrypt.h", MSDNShortId = "b740772b-d25b-4b3d-9acb-03f7018750d6")]
public enum CertSelection : uint
{
/// <summary>
/// Select expired certificates that meet selection criteria. By default expired certificates are rejected from selection.
/// </summary>
CERT_SELECT_ALLOW_EXPIRED = 0x00000001,
/// <summary>
/// Select certificates on which the error bit in the certificate chain trust status is not set to CERT_TRUST_IS_UNTRUSTED_ROOT,
/// CERT_TRUST_IS_PARTIAL_CHAIN, or CERT_TRUST_IS_NOT_TIME_VALID.
/// <para>In addition, certificates that have one of the following invalid constraint errors are not selected:</para>
/// <para>CERT_TRUST_INVALID_POLICY_CONSTRAINTS</para>
/// <para>CERT_TRUST_INVALID_BASIC_CONSTRAINTS</para>
/// <para>CERT_TRUST_INVALID_NAME_CONSTRAINTS</para>
/// </summary>
CERT_SELECT_TRUSTED_ROOT = 0x00000002,
/// <summary>Select certificates that are not self-issued and self-signed.</summary>
CERT_SELECT_DISALLOW_SELFSIGNED = 0x00000004,
/// <summary>Select certificates that have a value set for the CERT_KEY_PROV_INFO_PROP_ID property of the certificate.</summary>
CERT_SELECT_HAS_PRIVATE_KEY = 0x00000008,
/// <summary>
/// Select certificates on which the value of the dwKeySpec member of the CERT_KEY_PROV_INFO_PROP_ID property is set to AT_SIGNATURE.
/// <para>
/// If this function is being called as part of a CNG enabled application and the dwKeySpec member of the
/// CERT_KEY_PROV_INFO_PROP_ID property is set to -1, select certificates on which the value of the NCRYPT_KEY_USAGE_PROPERTY
/// property of the associated private key has the NCRYPT_ALLOW_SIGNING_FLAG set.
/// </para>
/// </summary>
CERT_SELECT_HAS_KEY_FOR_SIGNATURE = 0x00000010,
/// <summary>
/// Select certificates on which the value of the dwKeySpec member of the CERT_KEY_PROV_INFO_PROP_ID property is set to AT_KEYEXCHANGE.
/// <para>
/// If this function is being called as part of a CNG enabled application and the dwKeySpec member of the
/// CERT_KEY_PROV_INFO_PROP_ID property is set to -1, select certificates on which either NCRYPT_ALLOW_DECRYPT_FLAG or
/// NCRYPT_ALLOW_KEY_AGREEMENT_FLAG is set.
/// </para>
/// </summary>
CERT_SELECT_HAS_KEY_FOR_KEY_EXCHANGE = 0x00000020,
/// <summary>
/// Select certificates on which the value of the PP_IMPTYPE property of the associated private key provider is set to either
/// CRYPT_IMPL_HARDWARE or CRYPT_IMPL_REMOVABLE. (For CNG providers, NCRYPT_IMPL_TYPE_PROPERTY property value MUST have either
/// the NCRYPT_IMPL_HARDWARE_FLAG or NCRYPT_IMPL_REMOVABLE_FLAG bit set).
/// <para>
/// If this function is being called as part of a CNG enabled application, select certificates on which the
/// NCRYPT_IMPL_TYPE_PROPERTY property is set to NCRYPT_IMPL_HARDWARE_FLAG or NCRYPT_IMPL_REMOVABLE_FLAG.
/// </para>
/// </summary>
CERT_SELECT_HARDWARE_ONLY = 0x00000040,
/// <summary>
/// Allow the selection of certificates on which the Subject and Subject Alt Name contain the same information and the
/// certificate template extension value is equivalent. By default when certificates match this criteria, only the most recent
/// certificate is selected.
/// </summary>
CERT_SELECT_ALLOW_DUPLICATES = 0x00000080,
/// <summary/>
CERT_SELECT_IGNORE_AUTOSELECT = 0x00000100,
}
/// <summary>A set of flags that specify how the information should be retrieved.</summary>
[Flags]
public enum CryptRetrievalFlags
{
/// <summary>
/// Validates the content retrieved by a wire URL before writing the URL to the cache. The default provider does not support the
/// HTTPS protocol for AIA retrievals.
/// </summary>
CRYPT_AIA_RETRIEVAL = 0x00080000,
/// <summary>This value is not supported.</summary>
CRYPT_ASYNC_RETRIEVAL = 0x00000010,
/// <summary>Retrieves the encoded bits from the URL cache only. Do not use the wire to retrieve the URL.</summary>
CRYPT_CACHE_ONLY_RETRIEVAL = 0x00000002,
/// <summary>The crypt create new flush entry</summary>
CRYPT_CREATE_NEW_FLUSH_ENTRY = 0x10000000,
/// <summary>Does not store the retrieved encoded bits to the URL cache. If this flag is not set, the retrieved URL is cached.</summary>
CRYPT_DONT_CACHE_RESULT = 0x00000008,
/// <summary>The crypt enable file retrieval</summary>
CRYPT_ENABLE_FILE_RETRIEVAL = 0x08000000,
/// <summary>The crypt enable SSL revocation retrieval</summary>
CRYPT_ENABLE_SSL_REVOCATION_RETRIEVAL = 0x00800000,
/// <summary>
/// <para>Uses the POST method instead of the default GET method for HTTP retrievals.</para>
/// <para>In a POST URL, additional binary data and header strings are appended to the base URL in the following format:</para>
/// <para><em>BaseURL/OptionalURLEscaped&amp;Base64EncodedAdditionalData?OptionalAdditionalHTTPHeaders</em></para>
/// <para>
/// The following example shows the additional binary data delimited by the last slash mark (/) and a Content-Type header
/// delimited by a question mark (?) appended to a base URL.
/// </para>
/// <para>
/// <c>http://ocsp.openvalidation.org/MEIwQDA%2BMDwwOjAJBgUrDgMCGgUABBQdKNEwjytjKBQADcgM61jfflNpyQQUv1NDgnjQnsOA5RtnygUA37lIg6UCAQI%3D?Content-Type: application/ocsp-request</c>
/// </para>
/// <para>
/// When this flag is set, the <strong>CryptRetrieveObjectByUrl</strong> function parses the URL by using the last slash mark
/// (/) and question mark (?) delimiters. The string, which is delimited by a slash mark (/), contains an unescaped URL (that
/// is, a plain text URL without escape characters or escape sequences) and Base64 data decoded into binary form before being
/// passed to the WinHttpSendRequest function as the lpOptional parameter. The string delimited by a question mark (?) is passed
/// to the <strong>WinHttpSendRequest</strong> function as the pwszHeaders parameter.
/// </para>
/// </summary>
CRYPT_HTTP_POST_RETRIEVAL = 0x00100000,
/// <summary>
/// Performs A-Record-only DNS lookup on the supplied host string, preventing the generation of false DNS queries when resolving
/// host names. This flag should be used when passing a host name as opposed to a domain name.
/// </summary>
CRYPT_LDAP_AREC_EXCLUSIVE_RETRIEVAL = 0x00040000,
/// <summary>
/// Retrieves the entry index and attribute name for each LDAP object. The beginning of each returned BLOB contains the
/// following ANSI string:
/// <para><c>"entry index in decimal\0attribute name\0"</c></para>
/// <para>When this flag is set, pszObjectOid must be NULL so that a BLOB is returned. This flag only applies to the ldap scheme.</para>
/// </summary>
CRYPT_LDAP_INSERT_ENTRY_ATTRIBUTE = 0x00008000,
/// <summary>Fails if the LDAP search scope is not set to base in the URL. Use with LDAP only.</summary>
CRYPT_LDAP_SCOPE_BASE_ONLY_RETRIEVAL = 0x00002000,
/// <summary>
/// Digitally signs all of the LDAP traffic to and from a server by using the Kerberos authentication protocol. This feature
/// provides integrity required by some applications.
/// </summary>
CRYPT_LDAP_SIGN_RETRIEVAL = 0x00010000,
/// <summary>Inhibits automatic authentication handling.</summary>
CRYPT_NO_AUTH_RETRIEVAL = 0x00020000,
/// <summary>
/// Enables a conditional HTTP URL retrieval. When this flag is set, for a conditional retrieval that returns
/// HTTP_STATUS_NOT_MODIFIED, CryptRetrieveObjectByUrl returns TRUE and ppvObject is set to NULL. If pAuxInfo is not NULL,
/// dwHttpStatusCode is set to HTTP_STATUS_NOT_MODIFIED. Otherwise, ppvObject is updated for a successful retrieval.
/// </summary>
CRYPT_NOT_MODIFIED_RETRIEVAL = 0x00400000,
/// <summary>
/// Keeps track of offline failures and delays before hitting the wire on subsequent retrievals. This value is for wire
/// retrieval only.
/// </summary>
CRYPT_OFFLINE_CHECK_RETRIEVAL = 0x00004000,
/// <summary>
/// Enables proxy cache retrieval of an object. If a proxy cache was not explicitly bypassed, fProxyCacheRetrieval is set to
/// TRUE in pAuxInfo. This value only applies to HTTP URL retrievals.
/// </summary>
CRYPT_PROXY_CACHE_RETRIEVAL = 0x00200000,
/// <summary/>
CRYPT_RANDOM_QUERY_STRING_RETRIEVAL = 0x04000000,
/// <summary>
/// Retrieves multiple objects if available. All objects must be of a homogeneous object type as determined by the value of
/// pszObjectOid, unless the object identifier (OID) value is CONTEXT_OID_CAPI2_ANY.
/// </summary>
CRYPT_RETRIEVE_MULTIPLE_OBJECTS = 0x00000001,
/// <summary>Tags the URL as exempt from being flushed from the cache. For more information, see STICKY_CACHE_ENTRY in INTERNET_CACHE_ENTRY_INFO.</summary>
CRYPT_STICKY_CACHE_RETRIEVAL = 0x00001000,
/// <summary>Retrieves the encoded bits from the wire only. Does not use the URL cache.</summary>
CRYPT_WIRE_ONLY_RETRIEVAL = 0x00000004,
}
/// <summary>The <c>CertAddCertificateContextToStore</c> function adds a certificate context to the certificate store.</summary>
/// <param name="hCertStore">Handle of a certificate store.</param>
/// <param name="pCertContext">A pointer to the CERT_CONTEXT structure to be added to the store.</param>
/// <param name="dwAddDisposition">
/// <para>
/// Specifies the action to take if a matching certificate or a link to a matching certificate already exists in the store.
/// Currently defined disposition values and their uses are as follows.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>CERT_STORE_ADD_ALWAYS</term>
/// <term>
/// The function makes no check for an existing matching certificate or link to a matching certificate. A new certificate is always
/// added to the store. This can lead to duplicates in a store.
/// </term>
/// </item>
/// <item>
/// <term>CERT_STORE_ADD_NEW</term>
/// <term>
/// If a matching certificate or a link to a matching certificate exists, the operation fails. GetLastError returns the
/// CRYPT_E_EXISTS code.
/// </term>
/// </item>
/// <item>
/// <term>CERT_STORE_ADD_NEWER</term>
/// <term>
/// If a matching certificate or a link to a matching certificate exists and the NotBefore time of the existing context is equal to
/// or greater than the NotBefore time of the new context being added, the operation fails and GetLastError returns the
/// CRYPT_E_EXISTS code. If the NotBefore time of the existing context is less than the NotBefore time of the new context being
/// added, the existing certificate or link is deleted and a new certificate is created and added to the store. If a matching
/// certificate or a link to a matching certificate does not exist, a new link is added. If certificate revocation lists (CRLs) or
/// certificate trust list (CTLs) are being compared, the ThisUpdate time is used.
/// </term>
/// </item>
/// <item>
/// <term>CERT_STORE_ADD_NEWER_INHERIT_PROPERTIES</term>
/// <term>
/// If a matching certificate or a link to a matching certificate exists and the NotBefore time of the existing context is equal to
/// or greater than the NotBefore time of the new context being added, the operation fails and GetLastError returns the
/// CRYPT_E_EXISTS code. If the NotBefore time of the existing context is less than the NotBefore time of the new context being
/// added, the existing context is deleted before creating and adding the new context. The new added context inherits properties
/// from the existing certificate. If CRLs or CTLs are being compared, the ThisUpdate time is used.
/// </term>
/// </item>
/// <item>
/// <term>CERT_STORE_ADD_REPLACE_EXISTING</term>
/// <term>
/// If a link to a matching certificate exists, that existing certificate or link is deleted and a new certificate is created and
/// added to the store. If a matching certificate or a link to a matching certificate does not exist, a new link is added.
/// </term>
/// </item>
/// <item>
/// <term>CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES</term>
/// <term>
/// If a matching certificate exists in the store, the existing context is not replaced. The existing context inherits properties
/// from the new certificate.
/// </term>
/// </item>
/// <item>
/// <term>CERT_STORE_ADD_USE_EXISTING</term>
/// <term>
/// If a matching certificate or a link to a matching certificate exists, that existing certificate or link is used and properties
/// from the new certificate are added. The function does not fail, but it does not add a new context. If pCertContext is not NULL,
/// the existing context is duplicated. If a matching certificate or a link to a matching certificate does not exist, a new
/// certificate is added.
/// </term>
/// </item>
/// </list>
/// </param>
/// <param name="ppStoreContext">
/// <para>A pointer to a pointer to the copy to be made of the certificate that was added to the store.</para>
/// <para>
/// The ppStoreContext parameter can be <c>NULL</c>, indicating that the calling application does not require a copy of the added
/// certificate. If a copy is made, it must be freed by using CertFreeCertificateContext.
/// </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 follow.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>CRYPT_E_EXISTS</term>
/// <term>
/// This value is returned if CERT_STORE_ADD_NEW is set and the certificate already exists in the store, or if CERT_STORE_ADD_NEWER
/// is set and a certificate exists in the store with a NotBefore date greater than or equal to the NotBefore date on the
/// certificate to be added.
/// </term>
/// </item>
/// <item>
/// <term>E_INVALIDARG</term>
/// <term>A disposition value that is not valid was specified in the dwAddDisposition parameter.</term>
/// </item>
/// </list>
/// <para>
/// Errors from the called functions, CertAddEncodedCertificateToStore and CertSetCertificateContextProperty, can be propagated to
/// this function.
/// </para>
/// </returns>
/// <remarks>
/// <para>
/// The certificate context is not duplicated using CertDuplicateCertificateContext. Instead, the function creates a new copy of the
/// context and adds it to the store.
/// </para>
/// <para>
/// In addition to the encoded certificate, CertDuplicateCertificateContext also copies the context's properties, with the exception
/// of the CERT_KEY_PROV_HANDLE_PROP_ID and CERT_KEY_CONTEXT_PROP_ID properties.
/// </para>
/// <para>To remove the certificate context from the certificate store, use the CertDeleteCertificateFromStore function.</para>
/// <para>
/// <c>Note</c> The order of the certificate context may not be preserved within the store. To access a specific certificate you
/// must iterate across the certificates in the store.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-certaddcertificatecontexttostore BOOL
// CertAddCertificateContextToStore( HCERTSTORE hCertStore, PCCERT_CONTEXT pCertContext, DWORD dwAddDisposition, PCCERT_CONTEXT
// *ppStoreContext );
[DllImport(Lib.Crypt32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "5e4d8cae-1096-491f-9a04-92b7e9c020bb")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CertAddCertificateContextToStore(HCERTSTORE hCertStore, PCCERT_CONTEXT pCertContext, CertStoreAdd dwAddDisposition, out SafePCCERT_CONTEXT ppStoreContext);
/// <summary>The <c>CertAddCertificateContextToStore</c> function adds a certificate context to the certificate store.</summary>
/// <param name="hCertStore">Handle of a certificate store.</param>
/// <param name="pCertContext">A pointer to the CERT_CONTEXT structure to be added to the store.</param>
/// <param name="dwAddDisposition">
/// <para>
/// Specifies the action to take if a matching certificate or a link to a matching certificate already exists in the store.
/// Currently defined disposition values and their uses are as follows.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>CERT_STORE_ADD_ALWAYS</term>
/// <term>
/// The function makes no check for an existing matching certificate or link to a matching certificate. A new certificate is always
/// added to the store. This can lead to duplicates in a store.
/// </term>
/// </item>
/// <item>
/// <term>CERT_STORE_ADD_NEW</term>
/// <term>
/// If a matching certificate or a link to a matching certificate exists, the operation fails. GetLastError returns the
/// CRYPT_E_EXISTS code.
/// </term>
/// </item>
/// <item>
/// <term>CERT_STORE_ADD_NEWER</term>
/// <term>
/// If a matching certificate or a link to a matching certificate exists and the NotBefore time of the existing context is equal to
/// or greater than the NotBefore time of the new context being added, the operation fails and GetLastError returns the
/// CRYPT_E_EXISTS code. If the NotBefore time of the existing context is less than the NotBefore time of the new context being
/// added, the existing certificate or link is deleted and a new certificate is created and added to the store. If a matching
/// certificate or a link to a matching certificate does not exist, a new link is added. If certificate revocation lists (CRLs) or
/// certificate trust list (CTLs) are being compared, the ThisUpdate time is used.
/// </term>
/// </item>
/// <item>
/// <term>CERT_STORE_ADD_NEWER_INHERIT_PROPERTIES</term>
/// <term>
/// If a matching certificate or a link to a matching certificate exists and the NotBefore time of the existing context is equal to
/// or greater than the NotBefore time of the new context being added, the operation fails and GetLastError returns the
/// CRYPT_E_EXISTS code. If the NotBefore time of the existing context is less than the NotBefore time of the new context being
/// added, the existing context is deleted before creating and adding the new context. The new added context inherits properties
/// from the existing certificate. If CRLs or CTLs are being compared, the ThisUpdate time is used.
/// </term>
/// </item>
/// <item>
/// <term>CERT_STORE_ADD_REPLACE_EXISTING</term>
/// <term>
/// If a link to a matching certificate exists, that existing certificate or link is deleted and a new certificate is created and
/// added to the store. If a matching certificate or a link to a matching certificate does not exist, a new link is added.
/// </term>
/// </item>
/// <item>
/// <term>CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES</term>
/// <term>
/// If a matching certificate exists in the store, the existing context is not replaced. The existing context inherits properties
/// from the new certificate.
/// </term>
/// </item>
/// <item>
/// <term>CERT_STORE_ADD_USE_EXISTING</term>
/// <term>
/// If a matching certificate or a link to a matching certificate exists, that existing certificate or link is used and properties
/// from the new certificate are added. The function does not fail, but it does not add a new context. If pCertContext is not NULL,
/// the existing context is duplicated. If a matching certificate or a link to a matching certificate does not exist, a new
/// certificate is added.
/// </term>
/// </item>
/// </list>
/// </param>
/// <param name="ppStoreContext">
/// <para>A pointer to a pointer to the copy to be made of the certificate that was added to the store.</para>
/// <para>
/// The ppStoreContext parameter can be <c>NULL</c>, indicating that the calling application does not require a copy of the added
/// certificate. If a copy is made, it must be freed by using CertFreeCertificateContext.
/// </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 follow.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>CRYPT_E_EXISTS</term>
/// <term>
/// This value is returned if CERT_STORE_ADD_NEW is set and the certificate already exists in the store, or if CERT_STORE_ADD_NEWER
/// is set and a certificate exists in the store with a NotBefore date greater than or equal to the NotBefore date on the
/// certificate to be added.
/// </term>
/// </item>
/// <item>
/// <term>E_INVALIDARG</term>
/// <term>A disposition value that is not valid was specified in the dwAddDisposition parameter.</term>
/// </item>
/// </list>
/// <para>
/// Errors from the called functions, CertAddEncodedCertificateToStore and CertSetCertificateContextProperty, can be propagated to
/// this function.
/// </para>
/// </returns>
/// <remarks>
/// <para>
/// The certificate context is not duplicated using CertDuplicateCertificateContext. Instead, the function creates a new copy of the
/// context and adds it to the store.
/// </para>
/// <para>
/// In addition to the encoded certificate, CertDuplicateCertificateContext also copies the context's properties, with the exception
/// of the CERT_KEY_PROV_HANDLE_PROP_ID and CERT_KEY_CONTEXT_PROP_ID properties.
/// </para>
/// <para>To remove the certificate context from the certificate store, use the CertDeleteCertificateFromStore function.</para>
/// <para>
/// <c>Note</c> The order of the certificate context may not be preserved within the store. To access a specific certificate you
/// must iterate across the certificates in the store.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-certaddcertificatecontexttostore BOOL
// CertAddCertificateContextToStore( HCERTSTORE hCertStore, PCCERT_CONTEXT pCertContext, DWORD dwAddDisposition, PCCERT_CONTEXT
// *ppStoreContext );
[DllImport(Lib.Crypt32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "5e4d8cae-1096-491f-9a04-92b7e9c020bb")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CertAddCertificateContextToStore(HCERTSTORE hCertStore, PCCERT_CONTEXT pCertContext, CertStoreAdd dwAddDisposition, [Optional] IntPtr ppStoreContext);
/// <summary>
/// The <c>CertAddCertificateLinkToStore</c> function adds a link in a certificate store to a certificate context in a different
/// store. Instead of creating and adding a duplicate of the certificate context, this function adds a link to the original certificate.
/// </summary>
/// <param name="hCertStore">A handle to the certificate store where the link is to be added.</param>
/// <param name="pCertContext">A pointer to the CERT_CONTEXT structure to be linked.</param>
/// <param name="dwAddDisposition">
/// <para>
/// Specifies the action if a matching certificate or a link to a matching certificate already exists in the store. Currently
/// defined disposition values and their uses are as follows.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>CERT_STORE_ADD_ALWAYS</term>
/// <term>
/// The function makes no check for an existing matching certificate or link to a matching certificate. A new certificate is always
/// added to the store. This can lead to duplicates in a store.
/// </term>
/// </item>
/// <item>
/// <term>CERT_STORE_ADD_NEW</term>
/// <term>
/// If a matching certificate or a link to a matching certificate exists, the operation fails. GetLastError returns the
/// CRYPT_E_EXISTS code.
/// </term>
/// </item>
/// <item>
/// <term>CERT_STORE_ADD_REPLACE_EXISTING</term>
/// <term>
/// If a link to a matching certificate exists, that existing link is deleted and a new link is created and added to the store. If
/// no matching certificate or link to a matching certificate exists, one is added.
/// </term>
/// </item>
/// <item>
/// <term>CERT_STORE_ADD_USE_EXISTING</term>
/// <term>
/// If a matching certificate or a link to a matching certificate exists, the existing certificate is used. The function does not
/// fail, but no new link is added. If no matching certificate or link to a matching certificate exists, a new link is added.
/// </term>
/// </item>
/// </list>
/// </param>
/// <param name="ppStoreContext">
/// A pointer to a pointer to a copy of the link created. The ppStoreContext parameter can be <c>NULL</c> to indicate that a copy of
/// the link is not needed. If a copy of the link is created, that copy must be freed using the CertFreeCertificateContext function.
/// </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 follow.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>CRYPT_E_EXISTS</term>
/// <term>For a dwAddDisposition parameter of CERT_STORE_ADD_NEW, the certificate already exists in the store.</term>
/// </item>
/// <item>
/// <term>E_INVALIDARG</term>
/// <term>A disposition value that is not valid was specified in the dwAddDisposition parameter.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// Because the link provides access to the original certificate context, setting an extended property in the linked certificate
/// context changes that extended property in the certificate's original location and in any other links to that certificate.
/// </para>
/// <para>
/// Links cannot be added to a store opened as a collection. Stores opened as collections include all stores opened with
/// CertOpenSystemStore or CertOpenStore using CERT_STORE_PROV_SYSTEM or CERT_STORE_PROV_COLLECTION. For more information, see CertAddStoreToCollection.
/// </para>
/// <para>
/// If links are used and CertCloseStore is called with CERT_CLOSE_STORE_FORCE_FLAG, the store that uses links must be closed before
/// the store that contains the original contexts is closed. If CERT_CLOSE_STORE_FORCE_FLAG is not used, the two stores can be
/// closed in either order.
/// </para>
/// <para>To remove the certificate context link from the certificate store, use the CertDeleteCertificateFromStore function.</para>
/// <para>Examples</para>
/// <para>
/// For an example that uses this function, see Example C Program: Certificate Store Operations. For additional code that uses this
/// function, see Example C Program: Collection and Sibling Certificate Store Operations.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-certaddcertificatelinktostore BOOL
// CertAddCertificateLinkToStore( HCERTSTORE hCertStore, PCCERT_CONTEXT pCertContext, DWORD dwAddDisposition, PCCERT_CONTEXT
// *ppStoreContext );
[DllImport(Lib.Crypt32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "bcbf7755-d0ce-4dd5-8462-72760364fdc3")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CertAddCertificateLinkToStore(HCERTSTORE hCertStore, PCCERT_CONTEXT pCertContext, CertStoreAdd dwAddDisposition, out SafePCCERT_CONTEXT ppStoreContext);
/// <summary>
/// The <c>CertAddCertificateLinkToStore</c> function adds a link in a certificate store to a certificate context in a different
/// store. Instead of creating and adding a duplicate of the certificate context, this function adds a link to the original certificate.
/// </summary>
/// <param name="hCertStore">A handle to the certificate store where the link is to be added.</param>
/// <param name="pCertContext">A pointer to the CERT_CONTEXT structure to be linked.</param>
/// <param name="dwAddDisposition">
/// <para>
/// Specifies the action if a matching certificate or a link to a matching certificate already exists in the store. Currently
/// defined disposition values and their uses are as follows.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>CERT_STORE_ADD_ALWAYS</term>
/// <term>
/// The function makes no check for an existing matching certificate or link to a matching certificate. A new certificate is always
/// added to the store. This can lead to duplicates in a store.
/// </term>
/// </item>
/// <item>
/// <term>CERT_STORE_ADD_NEW</term>
/// <term>
/// If a matching certificate or a link to a matching certificate exists, the operation fails. GetLastError returns the
/// CRYPT_E_EXISTS code.
/// </term>
/// </item>
/// <item>
/// <term>CERT_STORE_ADD_REPLACE_EXISTING</term>
/// <term>
/// If a link to a matching certificate exists, that existing link is deleted and a new link is created and added to the store. If
/// no matching certificate or link to a matching certificate exists, one is added.
/// </term>
/// </item>
/// <item>
/// <term>CERT_STORE_ADD_USE_EXISTING</term>
/// <term>
/// If a matching certificate or a link to a matching certificate exists, the existing certificate is used. The function does not
/// fail, but no new link is added. If no matching certificate or link to a matching certificate exists, a new link is added.
/// </term>
/// </item>
/// </list>
/// </param>
/// <param name="ppStoreContext">
/// A pointer to a pointer to a copy of the link created. The ppStoreContext parameter can be <c>NULL</c> to indicate that a copy of
/// the link is not needed. If a copy of the link is created, that copy must be freed using the CertFreeCertificateContext function.
/// </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 follow.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>CRYPT_E_EXISTS</term>
/// <term>For a dwAddDisposition parameter of CERT_STORE_ADD_NEW, the certificate already exists in the store.</term>
/// </item>
/// <item>
/// <term>E_INVALIDARG</term>
/// <term>A disposition value that is not valid was specified in the dwAddDisposition parameter.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// Because the link provides access to the original certificate context, setting an extended property in the linked certificate
/// context changes that extended property in the certificate's original location and in any other links to that certificate.
/// </para>
/// <para>
/// Links cannot be added to a store opened as a collection. Stores opened as collections include all stores opened with
/// CertOpenSystemStore or CertOpenStore using CERT_STORE_PROV_SYSTEM or CERT_STORE_PROV_COLLECTION. For more information, see CertAddStoreToCollection.
/// </para>
/// <para>
/// If links are used and CertCloseStore is called with CERT_CLOSE_STORE_FORCE_FLAG, the store that uses links must be closed before
/// the store that contains the original contexts is closed. If CERT_CLOSE_STORE_FORCE_FLAG is not used, the two stores can be
/// closed in either order.
/// </para>
/// <para>To remove the certificate context link from the certificate store, use the CertDeleteCertificateFromStore function.</para>
/// <para>Examples</para>
/// <para>
/// For an example that uses this function, see Example C Program: Certificate Store Operations. For additional code that uses this
/// function, see Example C Program: Collection and Sibling Certificate Store Operations.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-certaddcertificatelinktostore BOOL
// CertAddCertificateLinkToStore( HCERTSTORE hCertStore, PCCERT_CONTEXT pCertContext, DWORD dwAddDisposition, PCCERT_CONTEXT
// *ppStoreContext );
[DllImport(Lib.Crypt32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "bcbf7755-d0ce-4dd5-8462-72760364fdc3")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CertAddCertificateLinkToStore(HCERTSTORE hCertStore, PCCERT_CONTEXT pCertContext, CertStoreAdd dwAddDisposition, [Optional] IntPtr ppStoreContext);
/// <summary>
/// <para>
/// The <c>CertAddEncodedCertificateToStore</c> function creates a certificate context from an encoded certificate and adds it to
/// the certificate store. The context created does not include any extended properties.
/// </para>
/// <para>
/// The <c>CertAddEncodedCertificateToStore</c> function also makes a copy of the encoded certificate before adding the certificate
/// to the store.
/// </para>
/// </summary>
/// <param name="hCertStore">A handle to the certificate store.</param>
/// <param name="dwCertEncodingType">
/// <para>
/// Specifies the type of encoding used. It is always acceptable to specify both the certificate and message encoding types by
/// combining them with a bitwise- <c>OR</c> operation as shown in the following example:
/// </para>
/// <para>X509_ASN_ENCODING | PKCS_7_ASN_ENCODING Currently defined encoding types are:</para>
/// <list type="bullet">
/// <item>
/// <term>X509_ASN_ENCODING</term>
/// </item>
/// <item>
/// <term>PKCS_7_ASN_ENCODING</term>
/// </item>
/// </list>
/// </param>
/// <param name="pbCertEncoded">
/// A pointer to a buffer containing the encoded certificate that is to be added to the certificate store.
/// </param>
/// <param name="cbCertEncoded">The size, in bytes, of the pbCertEncoded buffer.</param>
/// <param name="dwAddDisposition">
/// <para>
/// Specifies the action to take if a matching certificate or link to a matching certificate exists in the store. Currently defined
/// disposition values and their uses are as follows.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>CERT_STORE_ADD_ALWAYS</term>
/// <term>
/// The function makes no check for an existing matching certificate or link to a matching certificate. A new certificate is always
/// added to the store. This can lead to duplicates in a store.
/// </term>
/// </item>
/// <item>
/// <term>CERT_STORE_ADD_NEW</term>
/// <term>
/// If a matching certificate or a link to a matching certificate exists in the store, the operation fails. GetLastError returns the
/// CRYPT_E_EXISTS code.
/// </term>
/// </item>
/// <item>
/// <term>CERT_STORE_ADD_REPLACE_EXISTING</term>
/// <term>
/// If a matching certificate or link to a matching certificate exists in the store, the existing certificate or link is deleted and
/// a new certificate is created and added to the store. If a matching certificate or link to a matching certificate does not exist,
/// a new certificate is created and added to the store.
/// </term>
/// </item>
/// <item>
/// <term>CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES</term>
/// <term>
/// If a matching certificate exists in the store, that existing context is deleted before creating and adding the new context. The
/// new context inherits properties from the existing certificate.
/// </term>
/// </item>
/// <item>
/// <term>CERT_STORE_ADD_USE_EXISTING</term>
/// <term>
/// If a matching certificate or a link to a matching certificate exists, that existing certificate or link is used and properties
/// from the new certificate are added. The function does not fail, but it does not add a new context. If ppCertContext is not NULL,
/// the existing context is duplicated. If a matching certificate or link to a matching certificate does not exist, a new
/// certificate is added.
/// </term>
/// </item>
/// </list>
/// </param>
/// <param name="ppCertContext">
/// A pointer to a pointer to the decoded certificate context. This is an optional parameter that can be <c>NULL</c>, indicating
/// that the calling application does not require a copy of the new or existing certificate. When a copy is made, its context must
/// be freed by using CertFreeCertificateContext.
/// </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 follow.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>CRYPT_E_EXISTS</term>
/// <term>
/// This code is returned if CERT_STORE_ADD_NEW is set and the certificate already exists in the store, or if CERT_STORE_ADD_NEWER
/// is set and there is a certificate in the store with a NotBefore date greater than or equal to the NotBefore date on the
/// certificate to be added.
/// </term>
/// </item>
/// <item>
/// <term>E_INVALIDARG</term>
/// <term>
/// A disposition value that is not valid was specified in the dwAddDisposition parameter, or a certificate encoding type that is
/// not valid was specified. Currently, only the X509_ASN_ENCODING type is supported.
/// </term>
/// </item>
/// </list>
/// <para>
/// If the function fails, GetLastError returns an Abstract Syntax Notation One (ASN.1) encoding/decoding error. For information
/// about these errors, see ASN.1 Encoding/Decoding Return Values.
/// </para>
/// </returns>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-certaddencodedcertificatetostore BOOL
// CertAddEncodedCertificateToStore( HCERTSTORE hCertStore, DWORD dwCertEncodingType, const BYTE *pbCertEncoded, DWORD
// cbCertEncoded, DWORD dwAddDisposition, PCCERT_CONTEXT *ppCertContext );
[DllImport(Lib.Crypt32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "7c092bf5-f8b2-47d0-94ee-c8e0f4bca62d")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CertAddEncodedCertificateToStore(HCERTSTORE hCertStore, CertEncodingType dwCertEncodingType, [In] IntPtr pbCertEncoded, uint cbCertEncoded, CertStoreAdd dwAddDisposition, out SafePCCERT_CONTEXT ppCertContext);
/// <summary>
/// <para>
/// The <c>CertAddEncodedCertificateToStore</c> function creates a certificate context from an encoded certificate and adds it to
/// the certificate store. The context created does not include any extended properties.
/// </para>
/// <para>
/// The <c>CertAddEncodedCertificateToStore</c> function also makes a copy of the encoded certificate before adding the certificate
/// to the store.
/// </para>
/// </summary>
/// <param name="hCertStore">A handle to the certificate store.</param>
/// <param name="dwCertEncodingType">
/// <para>
/// Specifies the type of encoding used. It is always acceptable to specify both the certificate and message encoding types by
/// combining them with a bitwise- <c>OR</c> operation as shown in the following example:
/// </para>
/// <para>X509_ASN_ENCODING | PKCS_7_ASN_ENCODING Currently defined encoding types are:</para>
/// <list type="bullet">
/// <item>
/// <term>X509_ASN_ENCODING</term>
/// </item>
/// <item>
/// <term>PKCS_7_ASN_ENCODING</term>
/// </item>
/// </list>
/// </param>
/// <param name="pbCertEncoded">
/// A pointer to a buffer containing the encoded certificate that is to be added to the certificate store.
/// </param>
/// <param name="cbCertEncoded">The size, in bytes, of the pbCertEncoded buffer.</param>
/// <param name="dwAddDisposition">
/// <para>
/// Specifies the action to take if a matching certificate or link to a matching certificate exists in the store. Currently defined
/// disposition values and their uses are as follows.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>CERT_STORE_ADD_ALWAYS</term>
/// <term>
/// The function makes no check for an existing matching certificate or link to a matching certificate. A new certificate is always
/// added to the store. This can lead to duplicates in a store.
/// </term>
/// </item>
/// <item>
/// <term>CERT_STORE_ADD_NEW</term>
/// <term>
/// If a matching certificate or a link to a matching certificate exists in the store, the operation fails. GetLastError returns the
/// CRYPT_E_EXISTS code.
/// </term>
/// </item>
/// <item>
/// <term>CERT_STORE_ADD_REPLACE_EXISTING</term>
/// <term>
/// If a matching certificate or link to a matching certificate exists in the store, the existing certificate or link is deleted and
/// a new certificate is created and added to the store. If a matching certificate or link to a matching certificate does not exist,
/// a new certificate is created and added to the store.
/// </term>
/// </item>
/// <item>
/// <term>CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES</term>
/// <term>
/// If a matching certificate exists in the store, that existing context is deleted before creating and adding the new context. The
/// new context inherits properties from the existing certificate.
/// </term>
/// </item>
/// <item>
/// <term>CERT_STORE_ADD_USE_EXISTING</term>
/// <term>
/// If a matching certificate or a link to a matching certificate exists, that existing certificate or link is used and properties
/// from the new certificate are added. The function does not fail, but it does not add a new context. If ppCertContext is not NULL,
/// the existing context is duplicated. If a matching certificate or link to a matching certificate does not exist, a new
/// certificate is added.
/// </term>
/// </item>
/// </list>
/// </param>
/// <param name="ppCertContext">
/// A pointer to a pointer to the decoded certificate context. This is an optional parameter that can be <c>NULL</c>, indicating
/// that the calling application does not require a copy of the new or existing certificate. When a copy is made, its context must
/// be freed by using CertFreeCertificateContext.
/// </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 follow.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>CRYPT_E_EXISTS</term>
/// <term>
/// This code is returned if CERT_STORE_ADD_NEW is set and the certificate already exists in the store, or if CERT_STORE_ADD_NEWER
/// is set and there is a certificate in the store with a NotBefore date greater than or equal to the NotBefore date on the
/// certificate to be added.
/// </term>
/// </item>
/// <item>
/// <term>E_INVALIDARG</term>
/// <term>
/// A disposition value that is not valid was specified in the dwAddDisposition parameter, or a certificate encoding type that is
/// not valid was specified. Currently, only the X509_ASN_ENCODING type is supported.
/// </term>
/// </item>
/// </list>
/// <para>
/// If the function fails, GetLastError returns an Abstract Syntax Notation One (ASN.1) encoding/decoding error. For information
/// about these errors, see ASN.1 Encoding/Decoding Return Values.
/// </para>
/// </returns>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-certaddencodedcertificatetostore BOOL
// CertAddEncodedCertificateToStore( HCERTSTORE hCertStore, DWORD dwCertEncodingType, const BYTE *pbCertEncoded, DWORD
// cbCertEncoded, DWORD dwAddDisposition, PCCERT_CONTEXT *ppCertContext );
[DllImport(Lib.Crypt32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "7c092bf5-f8b2-47d0-94ee-c8e0f4bca62d")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CertAddEncodedCertificateToStore(HCERTSTORE hCertStore, CertEncodingType dwCertEncodingType, [In] IntPtr pbCertEncoded, uint cbCertEncoded, CertStoreAdd dwAddDisposition, [Optional] IntPtr ppCertContext);
/// <summary>
/// The <c>CertAddRefServerOcspResponse</c> function increments the reference count for an <c>HCERT_SERVER_OCSP_RESPONSE</c> handle.
/// </summary>
/// <param name="hServerOcspResponse">A handle to an <c>HCERT_SERVER_OCSP_RESPONSE</c> returned by CertOpenServerOcspResponse.</param>
/// <returns>This function has no return value.</returns>
/// <remarks>Each CertOpenServerOcspResponse and <c>CertAddRefServerOcspResponse</c> requires a corresponding CertCloseServerOcspResponse.</remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-certaddrefserverocspresponse void
// CertAddRefServerOcspResponse( HCERT_SERVER_OCSP_RESPONSE hServerOcspResponse );
[DllImport(Lib.Crypt32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "6ccc0e85-1fa0-480c-a5b4-b21ba811e5d0")]
public static extern void CertAddRefServerOcspResponse(HCERT_SERVER_OCSP_RESPONSE hServerOcspResponse);
/// <summary>
/// The <c>CertAddRefServerOcspResponseContext</c> function increments the reference count for a CERT_SERVER_OCSP_RESPONSE_CONTEXT structure.
/// </summary>
/// <param name="pServerOcspResponseContext">A pointer to a CERT_SERVER_OCSP_RESPONSE_CONTEXT returned by CertGetServerOcspResponseContext.</param>
/// <returns>The function has no return value.</returns>
/// <remarks>
/// Each call to CertGetServerOcspResponseContext and <c>CertAddRefServerOcspResponseContext</c> requires a corresponding call to CertFreeServerOcspResponseContext.
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-certaddrefserverocspresponsecontext void
// CertAddRefServerOcspResponseContext( PCCERT_SERVER_OCSP_RESPONSE_CONTEXT pServerOcspResponseContext );
[DllImport(Lib.Crypt32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "b7cdce9b-25fe-4fb9-b266-61989793699b")]
public static extern void CertAddRefServerOcspResponseContext(PCCERT_SERVER_OCSP_RESPONSE_CONTEXT pServerOcspResponseContext);
/// <summary>
/// The <c>CertCloseServerOcspResponse</c> function closes an online certificate status protocol (OCSP) server response handle.
/// </summary>
/// <param name="hServerOcspResponse">The handle to close for an OCSP server response.</param>
/// <param name="dwFlags">This parameter is not used and must be zero.</param>
/// <returns>This function does not return a value.</returns>
/// <remarks>
/// The <c>CertCloseServerOcspResponse</c> function closes a handle returned by either the CertOpenServerOcspResponse or
/// CertAddRefServerOcspResponse function.
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-certcloseserverocspresponse void
// CertCloseServerOcspResponse( HCERT_SERVER_OCSP_RESPONSE hServerOcspResponse, DWORD dwFlags );
[DllImport(Lib.Crypt32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "6247e8ca-ba12-432f-9bf8-a6c644f253e9")]
public static extern void CertCloseServerOcspResponse(HCERT_SERVER_OCSP_RESPONSE hServerOcspResponse, uint dwFlags = 0);
/// <summary>
/// The <c>CertCreateCertificateContext</c> function creates a certificate context from an encoded certificate. The created context
/// is not persisted to a certificate store. The function makes a copy of the encoded certificate within the created context.
/// </summary>
/// <param name="dwCertEncodingType">
/// <para>
/// Specifies the type of encoding used. It is always acceptable to specify both the certificate and message encoding types by
/// combining them with a bitwise- <c>OR</c> operation as shown in the following example:
/// </para>
/// <para>X509_ASN_ENCODING | PKCS_7_ASN_ENCODING Currently defined encoding types are:</para>
/// <list type="bullet">
/// <item>
/// <term>X509_ASN_ENCODING</term>
/// </item>
/// <item>
/// <term>PKCS_7_ASN_ENCODING</term>
/// </item>
/// </list>
/// </param>
/// <param name="pbCertEncoded">A pointer to a buffer that contains the encoded certificate from which the context is to be created.</param>
/// <param name="cbCertEncoded">The size, in bytes, of the pbCertEncoded buffer.</param>
/// <returns>
/// <para>
/// If the function succeeds, the function returns a pointer to a read-only CERT_CONTEXT. When you have finished using the
/// certificate context, free it by calling the CertFreeCertificateContext function.
/// </para>
/// <para>
/// If the function is unable to decode and create the certificate context, it returns <c>NULL</c>. For extended error information,
/// call GetLastError. Some possible error codes follow.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>E_INVALIDARG</term>
/// <term>A certificate encoding type that is not valid was specified. Currently, only the X509_ASN_ENCODING type is supported.</term>
/// </item>
/// </list>
/// <para>
/// If the function fails, GetLastError may return an Abstract Syntax Notation One (ASN.1) encoding/decoding error. For information
/// about these errors, see ASN.1 Encoding/Decoding Return Values.
/// </para>
/// </returns>
/// <remarks>
/// <para>
/// The CERT_CONTEXT must be freed by calling CertFreeCertificateContext. CertDuplicateCertificateContext can be called to make a
/// duplicate. CertSetCertificateContextProperty and CertGetCertificateContextProperty can be called to store and read properties
/// for the certificate.
/// </para>
/// <para>Examples</para>
/// <para>
/// The following example shows creating a certificate context from an encoded certificate. The created context is not put in a
/// certificate store. For another example that uses this function, see Example C Program: Certificate Store Operations.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-certcreatecertificatecontext PCCERT_CONTEXT
// CertCreateCertificateContext( DWORD dwCertEncodingType, const BYTE *pbCertEncoded, DWORD cbCertEncoded );
[DllImport(Lib.Crypt32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "a32714c4-ee88-48a8-a40a-bbbfec0613ac")]
public static extern SafePCCERT_CONTEXT CertCreateCertificateContext(CertEncodingType dwCertEncodingType, [In] IntPtr pbCertEncoded, uint cbCertEncoded);
/// <summary>
/// The <c>CertCreateSelfSignCertificate</c> function builds a self-signed certificate and returns a pointer to a CERT_CONTEXT
/// structure that represents the certificate.
/// </summary>
/// <param name="hCryptProvOrNCryptKey">
/// <para>
/// A handle of a cryptographic provider used to sign the certificate created. If <c>NULL</c>, information from the pKeyProvInfo
/// parameter is used to acquire the needed handle. If pKeyProvInfo is also <c>NULL</c>, the default provider type, PROV_RSA_FULL
/// provider type, the default key specification, AT_SIGNATURE, and a newly created key container with a unique container name are used.
/// </para>
/// <para>
/// This handle must be an HCRYPTPROV handle that has been created by using the CryptAcquireContext function or an
/// <c>NCRYPT_KEY_HANDLE</c> handle that has been created by using the NCryptOpenKey function. New applications should always pass
/// in the <c>NCRYPT_KEY_HANDLE</c> handle of a CNG cryptographic service provider (CSP).
/// </para>
/// </param>
/// <param name="pSubjectIssuerBlob">
/// A pointer to a BLOB that contains the distinguished name (DN) for the certificate subject. This parameter cannot be <c>NULL</c>.
/// Minimally, a pointer to an empty DN must be provided. This BLOB is normally created by using the CertStrToName function. It can
/// also be created by using the CryptEncodeObject function and specifying either the X509_NAME or X509_UNICODE_NAME StructType.
/// </param>
/// <param name="dwFlags">
/// <para>
/// A set of flags that override the default behavior of this function. This can be zero or a combination of one or more of the
/// following values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>CERT_CREATE_SELFSIGN_NO_KEY_INFO 2</term>
/// <term>
/// By default, the returned PCCERT_CONTEXT references the private keys by setting the CERT_KEY_PROV_INFO_PROP_ID. If you do not
/// want the returned PCCERT_CONTEXT to reference private keys by setting the CERT_KEY_PROV_INFO_PROP_ID, specify CERT_CREATE_SELFSIGN_NO_KEY_INFO.
/// </term>
/// </item>
/// <item>
/// <term>CERT_CREATE_SELFSIGN_NO_SIGN 1</term>
/// <term>
/// By default, the certificate being created is signed. If the certificate being created is only a dummy placeholder, the
/// certificate might not need to be signed. Signing of the certificate is skipped if CERT_CREATE_SELFSIGN_NO_SIGN is specified.
/// </term>
/// </item>
/// </list>
/// </param>
/// <param name="pKeyProvInfo">
/// <para>
/// A pointer to a CRYPT_KEY_PROV_INFO structure. Before a certificate is created, the CSP is queried for the key provider, key
/// provider type, and the key container name. If the CSP queried does not support these queries, the function fails. If the default
/// provider does not support these queries, a pKeyProvInfo value must be specified. The RSA BASE does support these queries.
/// </para>
/// <para>
/// If the pKeyProvInfo parameter is not <c>NULL</c>, the corresponding values are set in the <c>CERT_KEY_PROV_INFO_PROP_ID</c>
/// value of the generated certificate. You must ensure that all parameters of the supplied structure are correctly specified.
/// </para>
/// </param>
/// <param name="pSignatureAlgorithm">
/// A pointer to a CRYPT_ALGORITHM_IDENTIFIER structure. If <c>NULL</c>, the default algorithm, SHA1RSA, is used.
/// </param>
/// <param name="pStartTime">A pointer to a SYSTEMTIME structure. If <c>NULL</c>, the system current time is used by default.</param>
/// <param name="pEndTime">
/// A pointer to a SYSTEMTIME structure. If <c>NULL</c>, the pStartTime value plus one year will be used by default.
/// </param>
/// <param name="pExtensions">
/// A pointer to a CERT_EXTENSIONS array of CERT_EXTENSION structures. By default, the array is empty. An alternate subject name, if
/// desired, can be specified as one of these extensions.
/// </param>
/// <returns>
/// If the function succeeds, a PCCERT_CONTEXT variable that points to the created certificate is returned. If the function fails,
/// it returns <c>NULL</c>. For extended error information, call GetLastError.
/// </returns>
/// <remarks>
/// As the pEndTime must be a valid date, and is automatically generated if it is not supplied by the user, unexpected failures may
/// easily be caused when this API is called on a leap day without accompanying app logic to compensate. For more information,
/// please see leap year readiness.
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-certcreateselfsigncertificate PCCERT_CONTEXT
// CertCreateSelfSignCertificate( HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hCryptProvOrNCryptKey, PCERT_NAME_BLOB pSubjectIssuerBlob, DWORD
// dwFlags, PCRYPT_KEY_PROV_INFO pKeyProvInfo, PCRYPT_ALGORITHM_IDENTIFIER pSignatureAlgorithm, PSYSTEMTIME pStartTime, PSYSTEMTIME
// pEndTime, PCERT_EXTENSIONS pExtensions );
[DllImport(Lib.Crypt32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "89028c4e-f896-4c50-9fa2-bcb4e1784244")]
public static extern SafePCCERT_CONTEXT CertCreateSelfSignCertificate(IntPtr hCryptProvOrNCryptKey, in CRYPTOAPI_BLOB pSubjectIssuerBlob, CertCreateSelfSignFlags dwFlags, IntPtr pKeyProvInfo, IntPtr pSignatureAlgorithm, IntPtr pStartTime, IntPtr pEndTime, IntPtr pExtensions);
/// <summary>
/// The <c>CertCreateSelfSignCertificate</c> function builds a self-signed certificate and returns a pointer to a CERT_CONTEXT
/// structure that represents the certificate.
/// </summary>
/// <param name="hCryptProvOrNCryptKey">
/// <para>
/// A handle of a cryptographic provider used to sign the certificate created. If <c>NULL</c>, information from the pKeyProvInfo
/// parameter is used to acquire the needed handle. If pKeyProvInfo is also <c>NULL</c>, the default provider type, PROV_RSA_FULL
/// provider type, the default key specification, AT_SIGNATURE, and a newly created key container with a unique container name are used.
/// </para>
/// <para>
/// This handle must be an HCRYPTPROV handle that has been created by using the CryptAcquireContext function or an
/// <c>NCRYPT_KEY_HANDLE</c> handle that has been created by using the NCryptOpenKey function. New applications should always pass
/// in the <c>NCRYPT_KEY_HANDLE</c> handle of a CNG cryptographic service provider (CSP).
/// </para>
/// </param>
/// <param name="pSubjectIssuerBlob">
/// A pointer to a BLOB that contains the distinguished name (DN) for the certificate subject. This parameter cannot be <c>NULL</c>.
/// Minimally, a pointer to an empty DN must be provided. This BLOB is normally created by using the CertStrToName function. It can
/// also be created by using the CryptEncodeObject function and specifying either the X509_NAME or X509_UNICODE_NAME StructType.
/// </param>
/// <param name="dwFlags">
/// <para>
/// A set of flags that override the default behavior of this function. This can be zero or a combination of one or more of the
/// following values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>CERT_CREATE_SELFSIGN_NO_KEY_INFO 2</term>
/// <term>
/// By default, the returned PCCERT_CONTEXT references the private keys by setting the CERT_KEY_PROV_INFO_PROP_ID. If you do not
/// want the returned PCCERT_CONTEXT to reference private keys by setting the CERT_KEY_PROV_INFO_PROP_ID, specify CERT_CREATE_SELFSIGN_NO_KEY_INFO.
/// </term>
/// </item>
/// <item>
/// <term>CERT_CREATE_SELFSIGN_NO_SIGN 1</term>
/// <term>
/// By default, the certificate being created is signed. If the certificate being created is only a dummy placeholder, the
/// certificate might not need to be signed. Signing of the certificate is skipped if CERT_CREATE_SELFSIGN_NO_SIGN is specified.
/// </term>
/// </item>
/// </list>
/// </param>
/// <param name="pKeyProvInfo">
/// <para>
/// A pointer to a CRYPT_KEY_PROV_INFO structure. Before a certificate is created, the CSP is queried for the key provider, key
/// provider type, and the key container name. If the CSP queried does not support these queries, the function fails. If the default
/// provider does not support these queries, a pKeyProvInfo value must be specified. The RSA BASE does support these queries.
/// </para>
/// <para>
/// If the pKeyProvInfo parameter is not <c>NULL</c>, the corresponding values are set in the <c>CERT_KEY_PROV_INFO_PROP_ID</c>
/// value of the generated certificate. You must ensure that all parameters of the supplied structure are correctly specified.
/// </para>
/// </param>
/// <param name="pSignatureAlgorithm">
/// A pointer to a CRYPT_ALGORITHM_IDENTIFIER structure. If <c>NULL</c>, the default algorithm, SHA1RSA, is used.
/// </param>
/// <param name="pStartTime">A pointer to a SYSTEMTIME structure. If <c>NULL</c>, the system current time is used by default.</param>
/// <param name="pEndTime">
/// A pointer to a SYSTEMTIME structure. If <c>NULL</c>, the pStartTime value plus one year will be used by default.
/// </param>
/// <param name="pExtensions">
/// A pointer to a CERT_EXTENSIONS array of CERT_EXTENSION structures. By default, the array is empty. An alternate subject name, if
/// desired, can be specified as one of these extensions.
/// </param>
/// <returns>
/// If the function succeeds, a PCCERT_CONTEXT variable that points to the created certificate is returned. If the function fails,
/// it returns <c>NULL</c>. For extended error information, call GetLastError.
/// </returns>
/// <remarks>
/// As the pEndTime must be a valid date, and is automatically generated if it is not supplied by the user, unexpected failures may
/// easily be caused when this API is called on a leap day without accompanying app logic to compensate. For more information,
/// please see leap year readiness.
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-certcreateselfsigncertificate PCCERT_CONTEXT
// CertCreateSelfSignCertificate( HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hCryptProvOrNCryptKey, PCERT_NAME_BLOB pSubjectIssuerBlob, DWORD
// dwFlags, PCRYPT_KEY_PROV_INFO pKeyProvInfo, PCRYPT_ALGORITHM_IDENTIFIER pSignatureAlgorithm, PSYSTEMTIME pStartTime, PSYSTEMTIME
// pEndTime, PCERT_EXTENSIONS pExtensions );
[DllImport(Lib.Crypt32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "89028c4e-f896-4c50-9fa2-bcb4e1784244")]
public static extern SafePCCERT_CONTEXT CertCreateSelfSignCertificate(IntPtr hCryptProvOrNCryptKey, in CRYPTOAPI_BLOB pSubjectIssuerBlob, CertCreateSelfSignFlags dwFlags, in CRYPT_KEY_PROV_INFO pKeyProvInfo, in CRYPT_ALGORITHM_IDENTIFIER pSignatureAlgorithm, IntPtr pStartTime, IntPtr pEndTime, IntPtr pExtensions);
/// <summary>
/// The <c>CertCreateSelfSignCertificate</c> function builds a self-signed certificate and returns a pointer to a CERT_CONTEXT
/// structure that represents the certificate.
/// </summary>
/// <param name="hCryptProvOrNCryptKey">
/// <para>
/// A handle of a cryptographic provider used to sign the certificate created. If <c>NULL</c>, information from the pKeyProvInfo
/// parameter is used to acquire the needed handle. If pKeyProvInfo is also <c>NULL</c>, the default provider type, PROV_RSA_FULL
/// provider type, the default key specification, AT_SIGNATURE, and a newly created key container with a unique container name are used.
/// </para>
/// <para>
/// This handle must be an HCRYPTPROV handle that has been created by using the CryptAcquireContext function or an
/// <c>NCRYPT_KEY_HANDLE</c> handle that has been created by using the NCryptOpenKey function. New applications should always pass
/// in the <c>NCRYPT_KEY_HANDLE</c> handle of a CNG cryptographic service provider (CSP).
/// </para>
/// </param>
/// <param name="pSubjectIssuerBlob">
/// A pointer to a BLOB that contains the distinguished name (DN) for the certificate subject. This parameter cannot be <c>NULL</c>.
/// Minimally, a pointer to an empty DN must be provided. This BLOB is normally created by using the CertStrToName function. It can
/// also be created by using the CryptEncodeObject function and specifying either the X509_NAME or X509_UNICODE_NAME StructType.
/// </param>
/// <param name="dwFlags">
/// <para>
/// A set of flags that override the default behavior of this function. This can be zero or a combination of one or more of the
/// following values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>CERT_CREATE_SELFSIGN_NO_KEY_INFO 2</term>
/// <term>
/// By default, the returned PCCERT_CONTEXT references the private keys by setting the CERT_KEY_PROV_INFO_PROP_ID. If you do not
/// want the returned PCCERT_CONTEXT to reference private keys by setting the CERT_KEY_PROV_INFO_PROP_ID, specify CERT_CREATE_SELFSIGN_NO_KEY_INFO.
/// </term>
/// </item>
/// <item>
/// <term>CERT_CREATE_SELFSIGN_NO_SIGN 1</term>
/// <term>
/// By default, the certificate being created is signed. If the certificate being created is only a dummy placeholder, the
/// certificate might not need to be signed. Signing of the certificate is skipped if CERT_CREATE_SELFSIGN_NO_SIGN is specified.
/// </term>
/// </item>
/// </list>
/// </param>
/// <param name="pKeyProvInfo">
/// <para>
/// A pointer to a CRYPT_KEY_PROV_INFO structure. Before a certificate is created, the CSP is queried for the key provider, key
/// provider type, and the key container name. If the CSP queried does not support these queries, the function fails. If the default
/// provider does not support these queries, a pKeyProvInfo value must be specified. The RSA BASE does support these queries.
/// </para>
/// <para>
/// If the pKeyProvInfo parameter is not <c>NULL</c>, the corresponding values are set in the <c>CERT_KEY_PROV_INFO_PROP_ID</c>
/// value of the generated certificate. You must ensure that all parameters of the supplied structure are correctly specified.
/// </para>
/// </param>
/// <param name="pSignatureAlgorithm">
/// A pointer to a CRYPT_ALGORITHM_IDENTIFIER structure. If <c>NULL</c>, the default algorithm, SHA1RSA, is used.
/// </param>
/// <param name="pStartTime">A pointer to a SYSTEMTIME structure. If <c>NULL</c>, the system current time is used by default.</param>
/// <param name="pEndTime">
/// A pointer to a SYSTEMTIME structure. If <c>NULL</c>, the pStartTime value plus one year will be used by default.
/// </param>
/// <param name="pExtensions">
/// A pointer to a CERT_EXTENSIONS array of CERT_EXTENSION structures. By default, the array is empty. An alternate subject name, if
/// desired, can be specified as one of these extensions.
/// </param>
/// <returns>
/// If the function succeeds, a PCCERT_CONTEXT variable that points to the created certificate is returned. If the function fails,
/// it returns <c>NULL</c>. For extended error information, call GetLastError.
/// </returns>
/// <remarks>
/// As the pEndTime must be a valid date, and is automatically generated if it is not supplied by the user, unexpected failures may
/// easily be caused when this API is called on a leap day without accompanying app logic to compensate. For more information,
/// please see leap year readiness.
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-certcreateselfsigncertificate PCCERT_CONTEXT
// CertCreateSelfSignCertificate( HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hCryptProvOrNCryptKey, PCERT_NAME_BLOB pSubjectIssuerBlob, DWORD
// dwFlags, PCRYPT_KEY_PROV_INFO pKeyProvInfo, PCRYPT_ALGORITHM_IDENTIFIER pSignatureAlgorithm, PSYSTEMTIME pStartTime, PSYSTEMTIME
// pEndTime, PCERT_EXTENSIONS pExtensions );
[DllImport(Lib.Crypt32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "89028c4e-f896-4c50-9fa2-bcb4e1784244")]
public static extern SafePCCERT_CONTEXT CertCreateSelfSignCertificate(IntPtr hCryptProvOrNCryptKey, in CRYPTOAPI_BLOB pSubjectIssuerBlob, CertCreateSelfSignFlags dwFlags, in CRYPT_KEY_PROV_INFO pKeyProvInfo, in CRYPT_ALGORITHM_IDENTIFIER pSignatureAlgorithm, in SYSTEMTIME pStartTime, in SYSTEMTIME pEndTime, in CERT_EXTENSIONS pExtensions);
/// <summary>
/// The <c>CertDeleteCertificateFromStore</c> function deletes the specified certificate context from the certificate store.
/// </summary>
/// <param name="pCertContext">A pointer to the CERT_CONTEXT structure to be deleted.</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. One possible error
/// code is the following.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>E_ACCESSDENIED</term>
/// <term>Indicates the store was opened as read-only and a delete operation is not allowed.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// After a certificate is deleted from a store, all subsequent attempts to get or find that certificate in that store will fail.
/// However, memory allocated for the certificate is not freed until all duplicated contexts have also been freed.
/// </para>
/// <para>
/// The <c>CertDeleteCertificateFromStore</c> function always frees pCertContext by calling the CertFreeCertificateContext function,
/// even if an error is encountered. Freeing the context reduces the context's reference count by one. If the reference count
/// reaches zero, memory allocated for the certificate is freed.
/// </para>
/// <para>Examples</para>
/// <para>For an example that uses this function, see Example C Program: Deleting Certificates from a Certificate Store.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-certdeletecertificatefromstore BOOL
// CertDeleteCertificateFromStore( PCCERT_CONTEXT pCertContext );
[DllImport(Lib.Crypt32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "4390c8da-9c4d-47a4-9af4-d179829f77f3")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CertDeleteCertificateFromStore(PCCERT_CONTEXT pCertContext);
/// <summary>
/// The <c>CertDuplicateCertificateContext</c> function duplicates a certificate context by incrementing its reference count.
/// </summary>
/// <param name="pCertContext">A pointer to the CERT_CONTEXT structure for which the reference count is incremented.</param>
/// <returns>
/// Currently, a copy is not made of the context, and the returned pointer to a context has the same value as the pointer to a
/// context that was input. If the pointer passed into this function is <c>NULL</c>, <c>NULL</c> is returned. When you have finished
/// using the duplicate context, decrease its reference count by calling the CertFreeCertificateContext function.
/// </returns>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-certduplicatecertificatecontext PCCERT_CONTEXT
// CertDuplicateCertificateContext( PCCERT_CONTEXT pCertContext );
[DllImport(Lib.Crypt32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "589edd25-c8d0-4f93-83b2-9df2ed2e2812")]
public static extern PCCERT_CONTEXT CertDuplicateCertificateContext(PCCERT_CONTEXT pCertContext);
/// <summary>
/// The <c>CertEnumCertificatesInStore</c> function retrieves the first or next certificate in a certificate store. Used in a loop,
/// this function can retrieve in sequence all certificates in a certificate store.
/// </summary>
/// <param name="hCertStore">A handle of a certificate store.</param>
/// <param name="pPrevCertContext">
/// <para>A pointer to the CERT_CONTEXT of the previous certificate context found.</para>
/// <para>
/// This parameter must be <c>NULL</c> to begin the enumeration and get the first certificate in the store. Successive certificates
/// are enumerated by setting pPrevCertContext to the pointer returned by a previous call to the function. This function frees the
/// CERT_CONTEXT referenced by non- <c>NULL</c> values of this parameter.
/// </para>
/// <para>
/// For logical stores, including collection stores, a duplicate of the pCertContext returned by this function cannot be used to
/// begin a new subsequence of enumerations because the duplicated certificate loses the initial enumeration state. The enumeration
/// skips any certificate previously deleted by CertDeleteCertificateFromStore.
/// </para>
/// </param>
/// <returns>
/// <para>
/// If the function succeeds, the function returns a pointer to the next CERT_CONTEXT in the store. If no more certificates exist in
/// the store, the function returns <c>NULL</c>.
/// </para>
/// <para>For extended error information, call GetLastError. Some possible error codes follow.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>E_INVALIDARG</term>
/// <term>The handle in the hCertStore parameter is not the same as that in the certificate context pointed to by pPrevCertContext.</term>
/// </item>
/// <item>
/// <term>CRYPT_E_NOT_FOUND</term>
/// <term>No certificates were found. This happens if the store is empty or if the function reached the end of the store's list.</term>
/// </item>
/// <item>
/// <term>ERROR_NO_MORE_FILES</term>
/// <term>
/// Applies to external stores. No certificates were found. This happens if the store is empty or if the function reached the end of
/// the store's list.
/// </term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The returned pointer is freed when passed as the pPrevCertContext parameter on a subsequent call. Otherwise, the pointer must be
/// freed by calling CertFreeCertificateContext. A non- <c>NULL</c> pPrevCertContext passed to <c>CertEnumCertificatesInStore</c> is
/// always freed even for an error.
/// </para>
/// <para>A duplicate of the currently enumerated certificate can be made by calling CertDuplicateCertificateContext.</para>
/// <para>Examples</para>
/// <para>
/// The following example lists the certificate contexts in the certificate store. For another example that uses this function, see
/// Example C Program: Deleting Certificates from a Certificate Store.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-certenumcertificatesinstore PCCERT_CONTEXT
// CertEnumCertificatesInStore( HCERTSTORE hCertStore, PCCERT_CONTEXT pPrevCertContext );
[DllImport(Lib.Crypt32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "c5ab5b4c-dc0c-416b-aa9e-b939398cfa6d")]
public static extern PCCERT_CONTEXT CertEnumCertificatesInStore(HCERTSTORE hCertStore, PCCERT_CONTEXT pPrevCertContext);
/// <summary>
/// The <c>CertFindCertificateInStore</c> function finds the first or next certificate context in a certificate store that matches a
/// search criteria established by the dwFindType and its associated pvFindPara. This function can be used in a loop to find all of
/// the certificates in a certificate store that match the specified find criteria.
/// </summary>
/// <param name="hCertStore">A handle of the certificate store to be searched.</param>
/// <param name="dwCertEncodingType">
/// <para>
/// Specifies the type of encoding used. Both the certificate and message encoding types must be specified by combining them with a
/// bitwise- <c>OR</c> operation as shown in the following example:
/// </para>
/// <para>X509_ASN_ENCODING | PKCS_7_ASN_ENCODING Currently defined encoding types are:</para>
/// <list type="bullet">
/// <item>
/// <term>X509_ASN_ENCODING</term>
/// </item>
/// <item>
/// <term>PKCS_7_ASN_ENCODING</term>
/// </item>
/// </list>
/// </param>
/// <param name="dwFindFlags">
/// Used with some dwFindType values to modify the search criteria. For most dwFindType values, dwFindFlags is not used and should
/// be set to zero. For detailed information, see Remarks.
/// </param>
/// <param name="dwFindType">
/// <para>
/// Specifies the type of search being made. The search type determines the data type, contents, and the use of pvFindPara. This
/// parameter can be one of the following values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>CERT_FIND_ANY</term>
/// <term>Data type of pvFindPara: NULL, not used. No search criteria used. Returns the next certificate in the store.</term>
/// </item>
/// <item>
/// <term>CERT_FIND_CERT_ID</term>
/// <term>Data type of pvFindPara: CERT_ID structure. Find the certificate identified by the specified CERT_ID.</term>
/// </item>
/// <item>
/// <term>CERT_FIND_CTL_USAGE</term>
/// <term>
/// Data type of pvFindPara: CTL_USAGE structure. Searches for a certificate that has a szOID_ENHANCED_KEY_USAGE extension or a
/// CERT_CTL_PROP_ID that matches the pszUsageIdentifier member of the CTL_USAGE structure.
/// </term>
/// </item>
/// <item>
/// <term>CERT_FIND_ENHKEY_USAGE</term>
/// <term>
/// Data type of pvFindPara: CERT_ENHKEY_USAGE structure. Searches for a certificate in the store that has either an enhanced key
/// usage extension or an enhanced key usage property and a usage identifier that matches the cUsageIdentifier member in the
/// CERT_ENHKEY_USAGE structure. A certificate has an enhanced key usage extension if it has a CERT_EXTENSION structure with the
/// pszObjId member set to szOID_ENHANCED_KEY_USAGE. A certificate has an enhanced key usage property if its
/// CERT_ENHKEY_USAGE_PROP_ID identifier is set. If CERT_FIND_OPTIONAL_ENHKEY_USAGE_FLAG is set in dwFindFlags, certificates without
/// the key usage extension or property are also matches. Setting this flag takes precedence over passing NULL in pvFindPara. If
/// CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG is set, a match is done only on the key usage extension. For information about flag
/// modifications to search criteria, see Remarks.
/// </term>
/// </item>
/// <item>
/// <term>CERT_FIND_EXISTING</term>
/// <term>
/// Data type of pvFindPara: CERT_CONTEXT structure. Searches for a certificate that is an exact match of the specified certificate context.
/// </term>
/// </item>
/// <item>
/// <term>CERT_FIND_HASH</term>
/// <term>
/// Data type of pvFindPara: CRYPT_HASH_BLOB structure. Searches for a certificate with a SHA1 hash that matches the hash in the
/// CRYPT_HASH_BLOB structure.
/// </term>
/// </item>
/// <item>
/// <term>CERT_FIND_HAS_PRIVATE_KEY</term>
/// <term>
/// Data type of pvFindPara: NULL, not used. Searches for a certificate that has a private key. The key can be ephemeral or saved on
/// disk. The key can be a legacy Cryptography API (CAPI) key or a CNG key. Windows 8 and Windows Server 2012: Support for this flag begins.
/// </term>
/// </item>
/// <item>
/// <term>CERT_FIND_ISSUER_ATTR</term>
/// <term>
/// Data type of pvFindPara: CERT_RDN structure. Searches for a certificate with specified issuer attributes that match attributes
/// in the CERT_RDN structure. If these values are set, the function compares attributes of the issuer in a certificate with
/// elements of the CERT_RDN_ATTR array in this CERT_RDN structure. Comparisons iterate through the CERT_RDN_ATTR attributes looking
/// for a match with the certificate's issuer attributes. If the pszObjId member of CERT_RDN_ATTR is NULL, the attribute object
/// identifier is ignored. If the dwValueType member of CERT_RDN_ATTR is CERT_RDN_ANY_TYPE, the value type is ignored. If the pbData
/// member of CERT_RDN_VALUE_BLOB is NULL, any value is a match. Currently only an exact, case-sensitive match is supported. For
/// information about Unicode options, see Remarks. When these values are set, the search is restricted to certificates whose
/// encoding type matches dwCertEncodingType.
/// </term>
/// </item>
/// <item>
/// <term>CERT_FIND_ISSUER_NAME</term>
/// <term>
/// Data type of pvFindPara: CERT_NAME_BLOB structure. Search for a certificate with an exact match of the entire issuer name with
/// the name in CERT_NAME_BLOB The search is restricted to certificates that match the dwCertEncodingType.
/// </term>
/// </item>
/// <item>
/// <term>CERT_FIND_ISSUER_OF</term>
/// <term>
/// Data type of pvFindPara: CERT_CONTEXT structure. Searches for a certificate with an subject that matches the issuer in
/// CERT_CONTEXT. Instead of using CertFindCertificateInStore with this value, use the CertGetCertificateChain function.
/// </term>
/// </item>
/// <item>
/// <term>CERT_FIND_ISSUER_STR</term>
/// <term>
/// Data type of pvFindPara: Null-terminated Unicode string. Searches for a certificate that contains the specified issuer name
/// string. The certificate's issuer member is converted to a name string of the appropriate type using the appropriate form of
/// CertNameToStr formatted as CERT_SIMPLE_NAME_STR. Then a case-insensitive substring-within-a-string match is performed. When this
/// value is set, the search is restricted to certificates whose encoding type matches dwCertEncodingType. If the substring match
/// fails and the subject contains an email RDN with Punycode encoded string, CERT_NAME_STR_ENABLE_PUNYCODE_FLAG is used to convert
/// the subject to a Unicode string and the substring match is performed again.
/// </term>
/// </item>
/// <item>
/// <term>CERT_FIND_KEY_IDENTIFIER</term>
/// <term>
/// Data type of pvFindPara: CRYPT_HASH_BLOB structure. Searches for a certificate with a CERT_KEY_IDENTIFIER_PROP_ID property that
/// matches the key identifier in CRYPT_HASH_BLOB.
/// </term>
/// </item>
/// <item>
/// <term>CERT_FIND_KEY_SPEC</term>
/// <term>
/// Data type of pvFindPara: DWORD variable that contains a key specification. Searches for a certificate that has a
/// CERT_KEY_SPEC_PROP_ID property that matches the key specification in pvFindPara.
/// </term>
/// </item>
/// <item>
/// <term>CERT_FIND_MD5_HASH</term>
/// <term>
/// Data type of pvFindPara: CRYPT_HASH_BLOB structure. Searches for a certificate with an MD5 hash that matches the hash in CRYPT_HASH_BLOB.
/// </term>
/// </item>
/// <item>
/// <term>CERT_FIND_PROPERTY</term>
/// <term>
/// Data type of pvFindPara: DWORD variable that contains a property identifier. Searches for a certificate with a property that
/// matches the property identifier specified by the DWORD value in pvFindPara.
/// </term>
/// </item>
/// <item>
/// <term>CERT_FIND_PUBLIC_KEY</term>
/// <term>
/// Data type of pvFindPara: CERT_PUBLIC_KEY_INFO structure. Searches for a certificate with a public key that matches the public
/// key in the CERT_PUBLIC_KEY_INFO structure.
/// </term>
/// </item>
/// <item>
/// <term>CERT_FIND_SHA1_HASH</term>
/// <term>
/// Data type of pvFindPara: CRYPT_HASH_BLOB structure. Searches for a certificate with a SHA1 hash that matches the hash in the
/// CRYPT_HASH_BLOB structure.
/// </term>
/// </item>
/// <item>
/// <term>CERT_FIND_SIGNATURE_HASH</term>
/// <term>
/// Data type of pvFindPara: CRYPT_HASH_BLOB structure. Searches for a certificate with a signature hash that matches the signature
/// hash in the CRYPT_HASH_BLOB structure.
/// </term>
/// </item>
/// <item>
/// <term>CERT_FIND_SUBJECT_ATTR</term>
/// <term>
/// Data type of pvFindPara: CERT_RDN structure. Searches for a certificate with specified subject attributes that match attributes
/// in the CERT_RDN structure. If RDN values are set, the function compares attributes of the subject in a certificate with elements
/// of the CERT_RDN_ATTR array in this CERT_RDN structure. Comparisons iterate through the CERT_RDN_ATTR attributes looking for a
/// match with the certificate's subject's attributes. If the pszObjId member of CERT_RDN_ATTR is NULL, the attribute object
/// identifier is ignored. If the dwValueType member of CERT_RDN_ATTR is CERT_RDN_ANY_TYPE, the value type is ignored. If the pbData
/// member of CERT_RDN_VALUE_BLOB is NULL, any value is a match. Currently only an exact, case-sensitive match is supported. For
/// information about Unicode options, see Remarks. When these values are set, the search is restricted to certificates whose
/// encoding type matches dwCertEncodingType.
/// </term>
/// </item>
/// <item>
/// <term>CERT_FIND_SUBJECT_CERT</term>
/// <term>
/// Data type of pvFindPara: CERT_INFO structure. Searches for a certificate with both an issuer and a serial number that match the
/// issuer and serial number in the CERT_INFO structure.
/// </term>
/// </item>
/// <item>
/// <term>CERT_FIND_SUBJECT_NAME</term>
/// <term>
/// Data type of pvFindPara: CERT_NAME_BLOB structure. Searches for a certificate with an exact match of the entire subject name
/// with the name in the CERT_NAME_BLOB structure. The search is restricted to certificates that match the value of dwCertEncodingType.
/// </term>
/// </item>
/// <item>
/// <term>CERT_FIND_SUBJECT_STR</term>
/// <term>
/// Data type of pvFindPara: Null-terminated Unicode string. Searches for a certificate that contains the specified subject name
/// string. The certificate's subject member is converted to a name string of the appropriate type using the appropriate form of
/// CertNameToStr formatted as CERT_SIMPLE_NAME_STR. Then a case-insensitive substring-within-a-string match is performed. When this
/// value is set, the search is restricted to certificates whose encoding type matches dwCertEncodingType.
/// </term>
/// </item>
/// <item>
/// <term>CERT_FIND_CROSS_CERT_DIST_POINTS</term>
/// <term>
/// Data type of pvFindPara: Not used. Find a certificate that has either a cross certificate distribution point extension or property.
/// </term>
/// </item>
/// <item>
/// <term>CERT_FIND_PUBKEY_MD5_HASH</term>
/// <term>
/// Data type of pvFindPara: CRYPT_HASH_BLOB structure. Find a certificate whose MD5-hashed public key matches the specified hash.
/// </term>
/// </item>
/// </list>
/// <para>
/// <c>Note</c> There are alternate forms of the value of dwFindType that pass a string in pvFindPara. One form uses a Unicode
/// string, and the other an ASCII string. Values that end in "_W" or without a suffix use Unicode. Values that end with "_A" use
/// ASCII strings.
/// </para>
/// </param>
/// <param name="pvFindPara">Points to a data item or structure used with dwFindType.</param>
/// <param name="pPrevCertContext">
/// A pointer to the last CERT_CONTEXT structure returned by this function. This parameter must be <c>NULL</c> on the first call of
/// the function. To find successive certificates meeting the search criteria, set pPrevCertContext to the pointer returned by the
/// previous call to the function. This function frees the <c>CERT_CONTEXT</c> referenced by non- <c>NULL</c> values of this parameter.
/// </param>
/// <returns>
/// <para>If the function succeeds, the function returns a pointer to a read-only CERT_CONTEXT structure.</para>
/// <para>If the function fails and a certificate that matches the search criteria is not found, the return value is <c>NULL</c>.</para>
/// <para>
/// A non- <c>NULL</c> CERT_CONTEXT that <c>CertFindCertificateInStore</c> returns must be freed by CertFreeCertificateContext or by
/// being passed as the pPrevCertContext parameter on a subsequent call to <c>CertFindCertificateInStore</c>.
/// </para>
/// <para>For extended error information, call GetLastError. Some possible error codes follow.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>CRYPT_E_NOT_FOUND</term>
/// <term>
/// No certificate was found matching the search criteria. This can happen if the store is empty or the end of the store's list is reached.
/// </term>
/// </item>
/// <item>
/// <term>E_INVALIDARG</term>
/// <term>
/// The handle in the hCertStore parameter is not the same as that in the certificate context pointed to by the pPrevCertContext
/// parameter, or a value that is not valid was specified in the dwFindType parameter.
/// </term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>The dwFindFlags parameter is used to modify the criteria of some search types.</para>
/// <para>
/// The CERT_UNICODE_IS_RDN_ATTRS_FLAG dwFindFlags value is used only with the CERT_FIND_SUBJECT_ATTR and CERT_FIND_ISSUER_ATTR
/// values for dwFindType. CERT_UNICODE_IS_RDN_ATTRS_FLAG must be set if the CERT_RDN_ATTR structure pointed to by pvFindPara was
/// initialized with Unicode strings. Before any comparison is made, the string to be matched is converted by using
/// X509_UNICODE_NAME to provide for Unicode comparisons.
/// </para>
/// <para>The following dwFindFlags values are used only with the CERT_FIND_ENKEY_USAGE value for dwFindType:</para>
/// <para>
/// CertDuplicateCertificateContext can be called to make a duplicate of the returned context. The returned context can be added to
/// a different certificate store by using CertAddCertificateContextToStore, or a link to that certificate context can be added to a
/// store that is not a collection store by using CertAddCertificateLinkToStore.
/// </para>
/// <para>
/// The returned pointer is freed when passed as the pPrevCertContext parameter on a subsequent call to the function. Otherwise, the
/// pointer must be explicitly freed by calling CertFreeCertificateContext. A pPrevCertContext that is not <c>NULL</c> is always
/// freed by <c>CertFindCertificateInStore</c> using a call to <c>CertFreeCertificateContext</c>, even if there is an error in the function.
/// </para>
/// <para>Examples</para>
/// <para>
/// The following example shows finding a certificate context in the certificate store meeting a search criterion. For a complete
/// example that includes the context for this example, see Example C Program: Certificate Store Operations.
/// </para>
/// <para>For another example that uses this function, see Example C Program: Collection and Sibling Certificate Store Operations.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-certfindcertificateinstore PCCERT_CONTEXT
// CertFindCertificateInStore( HCERTSTORE hCertStore, DWORD dwCertEncodingType, DWORD dwFindFlags, DWORD dwFindType, const void
// *pvFindPara, PCCERT_CONTEXT pPrevCertContext );
[DllImport(Lib.Crypt32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "20b3fcfb-55df-46ff-80a5-70f31a3d03b2")]
public static extern SafePCCERT_CONTEXT CertFindCertificateInStore(HCERTSTORE hCertStore, CertEncodingType dwCertEncodingType, CertFindUsageFlags dwFindFlags,
CertFindType dwFindType, [In] IntPtr pvFindPara, PCCERT_CONTEXT pPrevCertContext);
/// <summary>
/// The <c>CertFindCertificateInStore</c> function finds the first or next certificate context in a certificate store that matches a
/// search criteria established by the dwFindType and its associated pvFindPara. This function can be used in a loop to find all of
/// the certificates in a certificate store that match the specified find criteria.
/// </summary>
/// <param name="hCertStore">A handle of the certificate store to be searched.</param>
/// <param name="dwCertEncodingType">
/// <para>
/// Specifies the type of encoding used. Both the certificate and message encoding types must be specified by combining them with a
/// bitwise- <c>OR</c> operation as shown in the following example:
/// </para>
/// <para>X509_ASN_ENCODING | PKCS_7_ASN_ENCODING Currently defined encoding types are:</para>
/// <list type="bullet">
/// <item>
/// <term>X509_ASN_ENCODING</term>
/// </item>
/// <item>
/// <term>PKCS_7_ASN_ENCODING</term>
/// </item>
/// </list>
/// </param>
/// <param name="dwFindFlags">
/// Used with some dwFindType values to modify the search criteria. For most dwFindType values, dwFindFlags is not used and should
/// be set to zero. For detailed information, see Remarks.
/// </param>
/// <param name="dwFindType">
/// <para>
/// Specifies the type of search being made. The search type determines the data type, contents, and the use of pvFindPara. This
/// parameter can be one of the following values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>CERT_FIND_ANY</term>
/// <term>Data type of pvFindPara: NULL, not used. No search criteria used. Returns the next certificate in the store.</term>
/// </item>
/// <item>
/// <term>CERT_FIND_CERT_ID</term>
/// <term>Data type of pvFindPara: CERT_ID structure. Find the certificate identified by the specified CERT_ID.</term>
/// </item>
/// <item>
/// <term>CERT_FIND_CTL_USAGE</term>
/// <term>
/// Data type of pvFindPara: CTL_USAGE structure. Searches for a certificate that has a szOID_ENHANCED_KEY_USAGE extension or a
/// CERT_CTL_PROP_ID that matches the pszUsageIdentifier member of the CTL_USAGE structure.
/// </term>
/// </item>
/// <item>
/// <term>CERT_FIND_ENHKEY_USAGE</term>
/// <term>
/// Data type of pvFindPara: CERT_ENHKEY_USAGE structure. Searches for a certificate in the store that has either an enhanced key
/// usage extension or an enhanced key usage property and a usage identifier that matches the cUsageIdentifier member in the
/// CERT_ENHKEY_USAGE structure. A certificate has an enhanced key usage extension if it has a CERT_EXTENSION structure with the
/// pszObjId member set to szOID_ENHANCED_KEY_USAGE. A certificate has an enhanced key usage property if its
/// CERT_ENHKEY_USAGE_PROP_ID identifier is set. If CERT_FIND_OPTIONAL_ENHKEY_USAGE_FLAG is set in dwFindFlags, certificates without
/// the key usage extension or property are also matches. Setting this flag takes precedence over passing NULL in pvFindPara. If
/// CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG is set, a match is done only on the key usage extension. For information about flag
/// modifications to search criteria, see Remarks.
/// </term>
/// </item>
/// <item>
/// <term>CERT_FIND_EXISTING</term>
/// <term>
/// Data type of pvFindPara: CERT_CONTEXT structure. Searches for a certificate that is an exact match of the specified certificate context.
/// </term>
/// </item>
/// <item>
/// <term>CERT_FIND_HASH</term>
/// <term>
/// Data type of pvFindPara: CRYPT_HASH_BLOB structure. Searches for a certificate with a SHA1 hash that matches the hash in the
/// CRYPT_HASH_BLOB structure.
/// </term>
/// </item>
/// <item>
/// <term>CERT_FIND_HAS_PRIVATE_KEY</term>
/// <term>
/// Data type of pvFindPara: NULL, not used. Searches for a certificate that has a private key. The key can be ephemeral or saved on
/// disk. The key can be a legacy Cryptography API (CAPI) key or a CNG key. Windows 8 and Windows Server 2012: Support for this flag begins.
/// </term>
/// </item>
/// <item>
/// <term>CERT_FIND_ISSUER_ATTR</term>
/// <term>
/// Data type of pvFindPara: CERT_RDN structure. Searches for a certificate with specified issuer attributes that match attributes
/// in the CERT_RDN structure. If these values are set, the function compares attributes of the issuer in a certificate with
/// elements of the CERT_RDN_ATTR array in this CERT_RDN structure. Comparisons iterate through the CERT_RDN_ATTR attributes looking
/// for a match with the certificate's issuer attributes. If the pszObjId member of CERT_RDN_ATTR is NULL, the attribute object
/// identifier is ignored. If the dwValueType member of CERT_RDN_ATTR is CERT_RDN_ANY_TYPE, the value type is ignored. If the pbData
/// member of CERT_RDN_VALUE_BLOB is NULL, any value is a match. Currently only an exact, case-sensitive match is supported. For
/// information about Unicode options, see Remarks. When these values are set, the search is restricted to certificates whose
/// encoding type matches dwCertEncodingType.
/// </term>
/// </item>
/// <item>
/// <term>CERT_FIND_ISSUER_NAME</term>
/// <term>
/// Data type of pvFindPara: CERT_NAME_BLOB structure. Search for a certificate with an exact match of the entire issuer name with
/// the name in CERT_NAME_BLOB The search is restricted to certificates that match the dwCertEncodingType.
/// </term>
/// </item>
/// <item>
/// <term>CERT_FIND_ISSUER_OF</term>
/// <term>
/// Data type of pvFindPara: CERT_CONTEXT structure. Searches for a certificate with an subject that matches the issuer in
/// CERT_CONTEXT. Instead of using CertFindCertificateInStore with this value, use the CertGetCertificateChain function.
/// </term>
/// </item>
/// <item>
/// <term>CERT_FIND_ISSUER_STR</term>
/// <term>
/// Data type of pvFindPara: Null-terminated Unicode string. Searches for a certificate that contains the specified issuer name
/// string. The certificate's issuer member is converted to a name string of the appropriate type using the appropriate form of
/// CertNameToStr formatted as CERT_SIMPLE_NAME_STR. Then a case-insensitive substring-within-a-string match is performed. When this
/// value is set, the search is restricted to certificates whose encoding type matches dwCertEncodingType. If the substring match
/// fails and the subject contains an email RDN with Punycode encoded string, CERT_NAME_STR_ENABLE_PUNYCODE_FLAG is used to convert
/// the subject to a Unicode string and the substring match is performed again.
/// </term>
/// </item>
/// <item>
/// <term>CERT_FIND_KEY_IDENTIFIER</term>
/// <term>
/// Data type of pvFindPara: CRYPT_HASH_BLOB structure. Searches for a certificate with a CERT_KEY_IDENTIFIER_PROP_ID property that
/// matches the key identifier in CRYPT_HASH_BLOB.
/// </term>
/// </item>
/// <item>
/// <term>CERT_FIND_KEY_SPEC</term>
/// <term>
/// Data type of pvFindPara: DWORD variable that contains a key specification. Searches for a certificate that has a
/// CERT_KEY_SPEC_PROP_ID property that matches the key specification in pvFindPara.
/// </term>
/// </item>
/// <item>
/// <term>CERT_FIND_MD5_HASH</term>
/// <term>
/// Data type of pvFindPara: CRYPT_HASH_BLOB structure. Searches for a certificate with an MD5 hash that matches the hash in CRYPT_HASH_BLOB.
/// </term>
/// </item>
/// <item>
/// <term>CERT_FIND_PROPERTY</term>
/// <term>
/// Data type of pvFindPara: DWORD variable that contains a property identifier. Searches for a certificate with a property that
/// matches the property identifier specified by the DWORD value in pvFindPara.
/// </term>
/// </item>
/// <item>
/// <term>CERT_FIND_PUBLIC_KEY</term>
/// <term>
/// Data type of pvFindPara: CERT_PUBLIC_KEY_INFO structure. Searches for a certificate with a public key that matches the public
/// key in the CERT_PUBLIC_KEY_INFO structure.
/// </term>
/// </item>
/// <item>
/// <term>CERT_FIND_SHA1_HASH</term>
/// <term>
/// Data type of pvFindPara: CRYPT_HASH_BLOB structure. Searches for a certificate with a SHA1 hash that matches the hash in the
/// CRYPT_HASH_BLOB structure.
/// </term>
/// </item>
/// <item>
/// <term>CERT_FIND_SIGNATURE_HASH</term>
/// <term>
/// Data type of pvFindPara: CRYPT_HASH_BLOB structure. Searches for a certificate with a signature hash that matches the signature
/// hash in the CRYPT_HASH_BLOB structure.
/// </term>
/// </item>
/// <item>
/// <term>CERT_FIND_SUBJECT_ATTR</term>
/// <term>
/// Data type of pvFindPara: CERT_RDN structure. Searches for a certificate with specified subject attributes that match attributes
/// in the CERT_RDN structure. If RDN values are set, the function compares attributes of the subject in a certificate with elements
/// of the CERT_RDN_ATTR array in this CERT_RDN structure. Comparisons iterate through the CERT_RDN_ATTR attributes looking for a
/// match with the certificate's subject's attributes. If the pszObjId member of CERT_RDN_ATTR is NULL, the attribute object
/// identifier is ignored. If the dwValueType member of CERT_RDN_ATTR is CERT_RDN_ANY_TYPE, the value type is ignored. If the pbData
/// member of CERT_RDN_VALUE_BLOB is NULL, any value is a match. Currently only an exact, case-sensitive match is supported. For
/// information about Unicode options, see Remarks. When these values are set, the search is restricted to certificates whose
/// encoding type matches dwCertEncodingType.
/// </term>
/// </item>
/// <item>
/// <term>CERT_FIND_SUBJECT_CERT</term>
/// <term>
/// Data type of pvFindPara: CERT_INFO structure. Searches for a certificate with both an issuer and a serial number that match the
/// issuer and serial number in the CERT_INFO structure.
/// </term>
/// </item>
/// <item>
/// <term>CERT_FIND_SUBJECT_NAME</term>
/// <term>
/// Data type of pvFindPara: CERT_NAME_BLOB structure. Searches for a certificate with an exact match of the entire subject name
/// with the name in the CERT_NAME_BLOB structure. The search is restricted to certificates that match the value of dwCertEncodingType.
/// </term>
/// </item>
/// <item>
/// <term>CERT_FIND_SUBJECT_STR</term>
/// <term>
/// Data type of pvFindPara: Null-terminated Unicode string. Searches for a certificate that contains the specified subject name
/// string. The certificate's subject member is converted to a name string of the appropriate type using the appropriate form of
/// CertNameToStr formatted as CERT_SIMPLE_NAME_STR. Then a case-insensitive substring-within-a-string match is performed. When this
/// value is set, the search is restricted to certificates whose encoding type matches dwCertEncodingType.
/// </term>
/// </item>
/// <item>
/// <term>CERT_FIND_CROSS_CERT_DIST_POINTS</term>
/// <term>
/// Data type of pvFindPara: Not used. Find a certificate that has either a cross certificate distribution point extension or property.
/// </term>
/// </item>
/// <item>
/// <term>CERT_FIND_PUBKEY_MD5_HASH</term>
/// <term>
/// Data type of pvFindPara: CRYPT_HASH_BLOB structure. Find a certificate whose MD5-hashed public key matches the specified hash.
/// </term>
/// </item>
/// </list>
/// <para>
/// <c>Note</c> There are alternate forms of the value of dwFindType that pass a string in pvFindPara. One form uses a Unicode
/// string, and the other an ASCII string. Values that end in "_W" or without a suffix use Unicode. Values that end with "_A" use
/// ASCII strings.
/// </para>
/// </param>
/// <param name="pvFindPara">Points to a data item or structure used with dwFindType.</param>
/// <param name="pPrevCertContext">
/// A pointer to the last CERT_CONTEXT structure returned by this function. This parameter must be <c>NULL</c> on the first call of
/// the function. To find successive certificates meeting the search criteria, set pPrevCertContext to the pointer returned by the
/// previous call to the function. This function frees the <c>CERT_CONTEXT</c> referenced by non- <c>NULL</c> values of this parameter.
/// </param>
/// <returns>
/// <para>If the function succeeds, the function returns a pointer to a read-only CERT_CONTEXT structure.</para>
/// <para>If the function fails and a certificate that matches the search criteria is not found, the return value is <c>NULL</c>.</para>
/// <para>
/// A non- <c>NULL</c> CERT_CONTEXT that <c>CertFindCertificateInStore</c> returns must be freed by CertFreeCertificateContext or by
/// being passed as the pPrevCertContext parameter on a subsequent call to <c>CertFindCertificateInStore</c>.
/// </para>
/// <para>For extended error information, call GetLastError. Some possible error codes follow.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>CRYPT_E_NOT_FOUND</term>
/// <term>
/// No certificate was found matching the search criteria. This can happen if the store is empty or the end of the store's list is reached.
/// </term>
/// </item>
/// <item>
/// <term>E_INVALIDARG</term>
/// <term>
/// The handle in the hCertStore parameter is not the same as that in the certificate context pointed to by the pPrevCertContext
/// parameter, or a value that is not valid was specified in the dwFindType parameter.
/// </term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>The dwFindFlags parameter is used to modify the criteria of some search types.</para>
/// <para>
/// The CERT_UNICODE_IS_RDN_ATTRS_FLAG dwFindFlags value is used only with the CERT_FIND_SUBJECT_ATTR and CERT_FIND_ISSUER_ATTR
/// values for dwFindType. CERT_UNICODE_IS_RDN_ATTRS_FLAG must be set if the CERT_RDN_ATTR structure pointed to by pvFindPara was
/// initialized with Unicode strings. Before any comparison is made, the string to be matched is converted by using
/// X509_UNICODE_NAME to provide for Unicode comparisons.
/// </para>
/// <para>The following dwFindFlags values are used only with the CERT_FIND_ENKEY_USAGE value for dwFindType:</para>
/// <para>
/// CertDuplicateCertificateContext can be called to make a duplicate of the returned context. The returned context can be added to
/// a different certificate store by using CertAddCertificateContextToStore, or a link to that certificate context can be added to a
/// store that is not a collection store by using CertAddCertificateLinkToStore.
/// </para>
/// <para>
/// The returned pointer is freed when passed as the pPrevCertContext parameter on a subsequent call to the function. Otherwise, the
/// pointer must be explicitly freed by calling CertFreeCertificateContext. A pPrevCertContext that is not <c>NULL</c> is always
/// freed by <c>CertFindCertificateInStore</c> using a call to <c>CertFreeCertificateContext</c>, even if there is an error in the function.
/// </para>
/// <para>Examples</para>
/// <para>
/// The following example shows finding a certificate context in the certificate store meeting a search criterion. For a complete
/// example that includes the context for this example, see Example C Program: Certificate Store Operations.
/// </para>
/// <para>For another example that uses this function, see Example C Program: Collection and Sibling Certificate Store Operations.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-certfindcertificateinstore PCCERT_CONTEXT
// CertFindCertificateInStore( HCERTSTORE hCertStore, DWORD dwCertEncodingType, DWORD dwFindFlags, DWORD dwFindType, const void
// *pvFindPara, PCCERT_CONTEXT pPrevCertContext );
[DllImport(Lib.Crypt32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "20b3fcfb-55df-46ff-80a5-70f31a3d03b2")]
public static extern SafePCCERT_CONTEXT CertFindCertificateInStore(HCERTSTORE hCertStore, CertEncodingType dwCertEncodingType, CertFindUsageFlags dwFindFlags,
CertFindType dwFindType, [In, MarshalAs(UnmanagedType.LPWStr)] string pvFindPara, PCCERT_CONTEXT pPrevCertContext);
/// <summary>
/// The <c>CertFreeServerOcspResponseContext</c> function decrements the reference count for a CERT_SERVER_OCSP_RESPONSE_CONTEXT
/// structure. If the reference count becomes zero, memory allocated for the structure is released.
/// </summary>
/// <param name="pServerOcspResponseContext">
/// A pointer to a CERT_SERVER_OCSP_RESPONSE_CONTEXT structure that contains a value returned by the
/// CertGetServerOcspResponseContext function.
/// </param>
/// <returns>This function has no return value.</returns>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-certfreeserverocspresponsecontext void
// CertFreeServerOcspResponseContext( PCCERT_SERVER_OCSP_RESPONSE_CONTEXT pServerOcspResponseContext );
[DllImport(Lib.Crypt32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "a07fc1e0-6f06-4336-b33c-d4d6a838b609")]
public static extern void CertFreeServerOcspResponseContext(PCCERT_SERVER_OCSP_RESPONSE_CONTEXT pServerOcspResponseContext);
/// <summary>
/// The <c>CertGetIssuerCertificateFromStore</c> function retrieves the certificate context from the certificate store for the first
/// or next issuer of the specified subject certificate. The new Certificate Chain Verification Functions are recommended instead of
/// the use of this function.
/// </summary>
/// <param name="hCertStore">Handle of a certificate store.</param>
/// <param name="pSubjectContext">
/// A pointer to a CERT_CONTEXT structure that contains the subject information. This parameter can be obtained from any certificate
/// store or can be created by the calling application using the CertCreateCertificateContext function.
/// </param>
/// <param name="pPrevIssuerContext">
/// <para>
/// A pointer to a CERT_CONTEXT structure that contains the issuer information. An issuer can have multiple certificates, especially
/// when a validity period is about to change. This parameter must be <c>NULL</c> on the call to get the first issuer certificate.
/// To get the next certificate for the issuer, set pPrevIssuerContext to the <c>CERT_CONTEXT</c> structure returned by the previous call.
/// </para>
/// <para>This function frees the CERT_CONTEXT referenced by non- <c>NULL</c> values of this parameter.</para>
/// </param>
/// <param name="pdwFlags">
/// <para>
/// The following flags enable verification checks on the returned certificate. They can be combined using a bitwise- <c>OR</c>
/// operation to enable multiple verifications.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>CERT_STORE_NO_CRL_FLAG</term>
/// <term>Indicates no matching CRL was found.</term>
/// </item>
/// <item>
/// <term>CERT_STORE_NO_ISSUER_FLAG</term>
/// <term>Indicates no issuer certificate was found.</term>
/// </item>
/// <item>
/// <term>CERT_STORE_REVOCATION_FLAG</term>
/// <term>Checks whether the subject certificate is on the issuer's revocation list.</term>
/// </item>
/// <item>
/// <term>CERT_STORE_SIGNATURE_FLAG</term>
/// <term>Uses the public key in the issuer's certificate to verify the signature on the subject certificate.</term>
/// </item>
/// <item>
/// <term>CERT_STORE_TIME_VALIDITY_FLAG</term>
/// <term>Gets the current time and verifies that it is within the subject certificate's validity period.</term>
/// </item>
/// </list>
/// <para>
/// If a verification check of an enabled type succeeds, its flag is set to zero. If it fails, its flag remains set upon return. For
/// CERT_STORE_REVOCATION_FLAG, the verification succeeds if the function does not find a CRL related to the subject certificate.
/// </para>
/// <para>
/// If CERT_STORE_REVOCATION_FLAG is set and the issuer does not have a CRL in the store, CERT_STORE_NO_CRL_FLAG is set and
/// CERT_STORE_REVOCATION_FLAG remains set.
/// </para>
/// <para>
/// If CERT_STORE_SIGNATURE_FLAG or CERT_STORE_REVOCATION_FLAG is set, CERT_STORE_NO_ISSUER_FLAG is set if the function does not
/// find an issuer certificate in the store. For more details, see Remarks.
/// </para>
/// <para>
/// In the case of a verification check failure, a pointer to the issuer's CERT_CONTEXT is still returned and GetLastError is not updated.
/// </para>
/// </param>
/// <returns>
/// <para>If the function succeeds, the return value is a pointer to a read-only issuer CERT_CONTEXT.</para>
/// <para>If the function fails and the first or next issuer certificate is not found, the return value is <c>NULL</c>.</para>
/// <para>
/// Only the last returned CERT_CONTEXT structure must be freed by calling CertFreeCertificateContext. When the returned
/// <c>CERT_CONTEXT</c> from one call to the function is supplied as the pPrevIssuerContext parameter on a subsequent call, the
/// context is freed as part of the action of the function.
/// </para>
/// <para>For extended error information, call GetLastError. Some possible error codes follow.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>CRYPT_E_NOT_FOUND</term>
/// <term>No issuer was found for the subject certificate.</term>
/// </item>
/// <item>
/// <term>CRYPT_E_SELF_SIGNED</term>
/// <term>The issuer certificate is the same as the subject certificate. It is a self-signed root certificate.</term>
/// </item>
/// <item>
/// <term>E_INVALIDARG</term>
/// <term>
/// The handle in the hCertStore parameter is not the same as that of the certificate context pointed to by the pPrevIssuerContext
/// parameter, or an unsupported flag was set in pdwFlags.
/// </term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The returned pointer is freed when passed as the pPrevIssuerContext parameter on a subsequent call to the function. Otherwise,
/// the pointer must be explicitly freed by calling CertFreeCertificateContext. A pPrevIssuerContext that is not <c>NULL</c> is
/// always freed by <c>CertGetIssuerCertificateFromStore</c> using a call to <c>CertFreeCertificateContext</c>, even if there is an
/// error in the function.
/// </para>
/// <para>CertDuplicateCertificateContext can be called to make a duplicate of the issuer certificate.</para>
/// <para>
/// The hexadecimal values for dwFlags can be combined using a bitwise- <c>OR</c> operation to enable multiple verifications. For
/// example, to enable both signature and time validity, the value 0x00000003 is passed in dwFlags on input. In this case, if
/// CERT_STORE_SIGNATURE_FLAG verification succeeds but CERT_STORE_TIME_VALIDITY_FLAG verification fails, dwFlags returns as
/// 0x00000002 on output.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-certgetissuercertificatefromstore PCCERT_CONTEXT
// CertGetIssuerCertificateFromStore( HCERTSTORE hCertStore, PCCERT_CONTEXT pSubjectContext, PCCERT_CONTEXT pPrevIssuerContext,
// DWORD *pdwFlags );
[DllImport(Lib.Crypt32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "b57982d0-cba8-43cd-a544-3635fdf599e2")]
public static extern SafePCCERT_CONTEXT CertGetIssuerCertificateFromStore(HCERTSTORE hCertStore, PCCERT_CONTEXT pSubjectContext, PCCERT_CONTEXT pPrevIssuerContext, ref CertStoreVerification pdwFlags);
/// <summary>
/// The <c>CertGetServerOcspResponseContext</c> function retrieves a non-blocking, time valid online certificate status protocol
/// (OCSP) response context for the specified handle.
/// </summary>
/// <param name="hServerOcspResponse">
/// The OCSP server response handle for which to retrieve a response context. This handle is returned by the
/// CertOpenServerOcspResponse function.
/// </param>
/// <param name="dwFlags">This parameter is reserved for future use and must be zero.</param>
/// <param name="pvReserved">This parameter is reserved for future use and must be <c>NULL</c>.</param>
/// <returns>
/// <para>If the function succeeds, it returns a pointer to a CERT_SERVER_OCSP_RESPONSE_CONTEXT structure.</para>
/// <para>
/// For a response to be time valid, the current time on the system hosting this function call must be less than the next update
/// time for the certificate revocation list (CRL) context. When a time valid OCSP response is not available, this function returns
/// <c>NULL</c> with the last error set to CRYPT_E_REVOCATION_OFFLINE.
/// </para>
/// </returns>
/// <remarks>
/// If you use the <c>CertGetServerOcspResponseContext</c> function to create multiple references to an OCSP response context, you
/// must call CertAddRefServerOcspResponseContext to increment the reference count for the CERT_SERVER_OCSP_RESPONSE_CONTEXT
/// structure. When you have finished using the structure, you must free it by calling the CertFreeServerOcspResponseContext function.
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-certgetserverocspresponsecontext
// PCCERT_SERVER_OCSP_RESPONSE_CONTEXT CertGetServerOcspResponseContext( HCERT_SERVER_OCSP_RESPONSE hServerOcspResponse, DWORD
// dwFlags, LPVOID pvReserved );
[DllImport(Lib.Crypt32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "07476e43-db6b-4119-8d6b-41143b98744e")]
public static extern SafePCCERT_SERVER_OCSP_RESPONSE_CONTEXT CertGetServerOcspResponseContext(HCERT_SERVER_OCSP_RESPONSE hServerOcspResponse, uint dwFlags = 0, IntPtr pvReserved = default);
/// <summary>
/// The <c>CertGetSubjectCertificateFromStore</c> function returns from a certificate store a subject certificate context uniquely
/// identified by its issuer and serial number.
/// </summary>
/// <param name="hCertStore">A handle of a certificate store.</param>
/// <param name="dwCertEncodingType">
/// <para>
/// The type of encoding used. It is always acceptable to specify both the certificate and message encoding types by combining them
/// with a bitwise- <c>OR</c> operation as shown in the following example:
/// </para>
/// <para>X509_ASN_ENCODING | PKCS_7_ASN_ENCODING Currently defined encoding types are:</para>
/// <list type="bullet">
/// <item>
/// <term>X509_ASN_ENCODING</term>
/// </item>
/// <item>
/// <term>PKCS_7_ASN_ENCODING</term>
/// </item>
/// </list>
/// </param>
/// <param name="pCertId">A pointer to a CERT_INFO structure. Only the <c>Issuer</c> and <c>SerialNumber</c> members are used.</param>
/// <returns>
/// <para>
/// If the function succeeds, the function returns a pointer to a read-only CERT_CONTEXT. The <c>CERT_CONTEXT</c> must be freed by
/// calling CertFreeCertificateContext.
/// </para>
/// <para>The returned certificate might not be valid. Usually, it is verified when getting its issuer certificate (CertGetIssuerCertificateFromStore).</para>
/// <para>For extended error information, call GetLastError. One possible error code is the following.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>CRYPT_E_NOT_FOUND</term>
/// <term>The subject certificate was not found in the store.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>CertDuplicateCertificateContext can be called to make a duplicate certificate.</para>
/// <para>Examples</para>
/// <para>
/// The following example shows retrieving a subject's certificate context, uniquely identified by its issuer and serial number,
/// from the certificate store. For an example that includes the complete context for this example, see Example C Program: Signing,
/// Encoding, Decoding, and Verifying a Message.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-certgetsubjectcertificatefromstore PCCERT_CONTEXT
// CertGetSubjectCertificateFromStore( HCERTSTORE hCertStore, DWORD dwCertEncodingType, PCERT_INFO pCertId );
[DllImport(Lib.Crypt32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "61d73501-91b1-4498-b1a3-17392360c700")]
public static extern SafePCCERT_CONTEXT CertGetSubjectCertificateFromStore(HCERTSTORE hCertStore, CertEncodingType dwCertEncodingType, in CERT_INFO pCertId);
/// <summary>
/// The <c>CertGetValidUsages</c> function returns an array of usages that consist of the intersection of the valid usages for all
/// certificates in an array of certificates.
/// </summary>
/// <param name="cCerts">The number of certificates in the array to be checked.</param>
/// <param name="rghCerts">An array of certificates to be checked for valid usage.</param>
/// <param name="cNumOIDs">
/// The number of valid usages found as the intersection of the valid usages of all certificates in the array. If all of the
/// certificates are valid for all usages, cNumOIDs is set to negative one (1).
/// </param>
/// <param name="rghOIDs">
/// An array of the object identifiers (OIDs) of the valid usages that are shared by all of the certificates in the rghCerts array.
/// This parameter can be <c>NULL</c> to set the size of this structure for memory allocation purposes. For more information, see
/// Retrieving Data of Unknown Length.
/// </param>
/// <param name="pcbOIDs">
/// A pointer to a <c>DWORD</c> value that specifies the size, in bytes, of the rghOIDs array and the strings pointed to. When the
/// function returns, the <c>DWORD</c> value contains the number of bytes needed for the array.
/// </param>
/// <returns>
/// If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. For extended error
/// information, call GetLastError.
/// </returns>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-certgetvalidusages BOOL CertGetValidUsages( DWORD cCerts,
// PCCERT_CONTEXT *rghCerts, int *cNumOIDs, LPSTR *rghOIDs, DWORD *pcbOIDs );
[DllImport(Lib.Crypt32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "1504f166-2fa9-4041-9d72-b150cd8baa8a")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CertGetValidUsages(uint cCerts, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] PCCERT_CONTEXT[] rghCerts, out int cNumOIDs, IntPtr rghOIDs, ref uint pcbOIDs);
/// <summary>
/// The <c>CertOpenServerOcspResponse</c> function opens a handle to an online certificate status protocol (OCSP) response
/// associated with a server certificate chain.
/// </summary>
/// <param name="pChainContext">The address of a CERT_CHAIN_CONTEXT structure that contains the certificate chain.</param>
/// <param name="dwFlags">This parameter is not used and must be zero.</param>
/// <param name="pOpenPara">This parameter is not used and must be <c>NULL</c>.</param>
/// <returns>
/// <para>
/// Returns a handle to the OCSP response associated with a server certificate chain if successful; otherwise, <c>NULL</c>. This
/// handle must be passed to the CertCloseServerOcspResponse function when it is no longer needed.
/// </para>
/// <para>
/// For extended error information, call GetLastError. Possible error codes returned by the <c>GetLastError</c> function include,
/// but are not limited to, the following.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>ERROR_INVALID_PARAMETER</term>
/// <term>One or more parameters are not valid.</term>
/// </item>
/// <item>
/// <term>CRYPT_E_NOT_IN_REVOCATION_DATABASE</term>
/// <term>The end certificate does not contain an OCSP authority information access (AIA) URL.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The <c>CertOpenServerOcspResponse</c> function tries to retrieve an initial OCSP response before it returns. It blocks its
/// process thread during the retrieval. The <c>CertOpenServerOcspResponse</c> function creates a background thread that prefetches
/// time-valid OCSP responses.
/// </para>
/// <para>
/// The <c>CertOpenServerOcspResponse</c> function increments the reference count for the chain context represented by the
/// pChainContext parameter. When you have finished using the chain context, close the returned handle by calling the
/// CertCloseServerOcspResponse function.
/// </para>
/// <para>The <c>CertOpenServerOcspResponse</c> function initializes configuration settings used by the following functions:</para>
/// <list type="bullet">
/// <item>
/// <term>CertAddRefServerOcspResponse</term>
/// </item>
/// <item>
/// <term>CertCloseServerOcspResponse</term>
/// </item>
/// <item>
/// <term>CertGetServerOcspResponseContext</term>
/// </item>
/// <item>
/// <term>CertAddRefServerOcspResponseContext</term>
/// </item>
/// <item>
/// <term>CertFreeServerOcspResponseContext</term>
/// </item>
/// </list>
/// <para>
/// First, the <c>CertOpenServerOcspResponse</c> function initializes the settings based on default values in Wincrypt.h. If the
/// function subsequently finds the registry key defined in <c>CERT_CHAIN_CONFIG_REGPATH</c>, it updates the previously initialized
/// values with the registry values.
/// </para>
/// <para>The following configuration setting names and default values are initialized by this function:</para>
/// <list type="bullet">
/// <item>
/// <term><c>CERT_SRV_OCSP_RESP_MIN_VALIDITY_SECONDS_VALUE_NAME</c></term>
/// </item>
/// <item>
/// <term><c>CERT_SRV_OCSP_RESP_MIN_VALIDITY_SECONDS_DEFAULT</c></term>
/// </item>
/// <item>
/// <term><c>CERT_SRV_OCSP_RESP_URL_RETRIEVAL_TIMEOUT_MILLISECONDS_VALUE_NAME</c></term>
/// </item>
/// <item>
/// <term><c>CERT_SRV_OCSP_RESP_URL_RETRIEVAL_TIMEOUT_MILLISECONDS_DEFAULT</c></term>
/// </item>
/// <item>
/// <term><c>CERT_SRV_OCSP_RESP_MAX_BEFORE_NEXT_UPDATE_SECONDS_VALUE_NAME</c></term>
/// </item>
/// <item>
/// <term><c>CERT_SRV_OCSP_RESP_MAX_BEFORE_NEXT_UPDATE_SECONDS_DEFAULT</c></term>
/// </item>
/// <item>
/// <term><c>CERT_SRV_OCSP_RESP_MIN_BEFORE_NEXT_UPDATE_SECONDS_VALUE_NAME</c></term>
/// </item>
/// <item>
/// <term><c>CERT_SRV_OCSP_RESP_MIN_BEFORE_NEXT_UPDATE_SECONDS_DEFAULT</c></term>
/// </item>
/// <item>
/// <term><c>CERT_SRV_OCSP_RESP_MIN_AFTER_NEXT_UPDATE_SECONDS_VALUE_NAME</c></term>
/// </item>
/// <item>
/// <term><c>CERT_SRV_OCSP_RESP_MIN_AFTER_NEXT_UPDATE_SECONDS_DEFAULT</c></term>
/// </item>
/// </list>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-certopenserverocspresponse HCERT_SERVER_OCSP_RESPONSE
// CertOpenServerOcspResponse( PCCERT_CHAIN_CONTEXT pChainContext, DWORD dwFlags, PCERT_SERVER_OCSP_RESPONSE_OPEN_PARA pOpenPara );
[DllImport(Lib.Crypt32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "c29d1972-b329-4e32-aead-a038130fb85e")]
public static extern HCERT_SERVER_OCSP_RESPONSE CertOpenServerOcspResponse([In] PCCERT_CHAIN_CONTEXT pChainContext, uint dwFlags = 0, IntPtr pOpenPara = default);
/// <summary>
/// The <c>CertRetrieveLogoOrBiometricInfo</c> function performs a URL retrieval of logo or biometric information specified in
/// either the <c>szOID_LOGOTYPE_EXT</c> or <c>szOID_BIOMETRIC_EXT</c> certificate extension. The <c>szOID_BIOMETRIC_EXT</c>
/// extension (IETF RFC 3739) supports the addition of a signature or a pictorial representation of the human holder of the
/// certificate. The <c>szOID_LOGOTYPE_EXT</c> extension (IETF RFC 3709) supports the addition of organizational pictorial
/// representations in certificates.
/// </summary>
/// <param name="pCertContext">The address of a CERT_CONTEXT structure that contains the certificate.</param>
/// <param name="lpszLogoOrBiometricType">
/// <para>
/// The address of a null-terminated ANSI string that contains an object identifier (OID) string that identifies the type of
/// information to retrieve.
/// </para>
/// <para>This parameter may also contain one of the following predefined values.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>CERT_RETRIEVE_ISSUER_LOGO</term>
/// <term>Retrieve the certificate issuer logotype.</term>
/// </item>
/// <item>
/// <term>CERT_RETRIEVE_SUBJECT_LOGO</term>
/// <term>Retrieve the certificate subject logotype.</term>
/// </item>
/// <item>
/// <term>CERT_RETRIEVE_COMMUNITY_LOGO</term>
/// <term>Retrieve the certificate community logotype.</term>
/// </item>
/// <item>
/// <term>CERT_RETRIEVE_BIOMETRIC_PICTURE_TYPE</term>
/// <term>Retrieve the picture associated with the certificate.</term>
/// </item>
/// <item>
/// <term>CERT_RETRIEVE_BIOMETRIC_SIGNATURE_TYPE</term>
/// <term>Retrieve the signature associated with the certificate.</term>
/// </item>
/// </list>
/// </param>
/// <param name="dwRetrievalFlags">
/// A set of flags that specify how the information should be retrieved. This parameter is passed as the dwRetrievalFlags in the
/// CryptRetrieveObjectByUrl function.
/// </param>
/// <param name="dwTimeout">The maximum amount of time, in milliseconds, to wait for the retrieval.</param>
/// <param name="dwFlags">This parameter is not used and must be zero.</param>
/// <param name="pvReserved">This parameter is not used and must be <c>NULL</c>.</param>
/// <param name="ppbData">
/// The address of a <c>BYTE</c> pointer that receives the logotype or biometric data. This memory must be freed when it is no
/// longer needed by passing this pointer to the CryptMemFree function.
/// </param>
/// <param name="pcbData">The address of a <c>DWORD</c> variable that receives the number of bytes in the ppbData buffer.</param>
/// <param name="ppwszMimeType">
/// <para>
/// The address of a pointer to a null-terminated Unicode string that receives the Multipurpose Internet Mail Extensions (MIME) type
/// of the data. This parameter can be <c>NULL</c> if this information is not needed. This memory must be freed when it is no longer
/// needed by passing this pointer to the CryptMemFree function.
/// </para>
/// <para>
/// This address always receives <c>NULL</c> for biometric types. You must always ensure that this parameter contains a valid memory
/// address before attempting to access the memory.
/// </para>
/// </param>
/// <returns>
/// <para>Returns nonzero if successful or zero otherwise.</para>
/// <para>
/// For extended error information, call GetLastError. Possible error codes returned by the <c>GetLastError</c> function include,
/// but are not limited to, the following.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>CRYPT_E_HASH_VALUE</term>
/// <term>The computed hash value does not match the hash value in the certificate.</term>
/// </item>
/// <item>
/// <term>CRYPT_E_NOT_FOUND</term>
/// <term>
/// The certificate does not contain the szOID_LOGOTYPE_EXT or szOID_BIOMETRIC_EXT extension, or the specified
/// lpszLogoOrBiometricType was not found.
/// </term>
/// </item>
/// <item>
/// <term>E_INVALIDARG</term>
/// <term>One or more parameters are not valid.</term>
/// </item>
/// <item>
/// <term>ERROR_INVALID_DATA</term>
/// <term>No data could be retrieved from the URL specified by the certificate extension.</term>
/// </item>
/// <item>
/// <term>ERROR_NOT_SUPPORTED</term>
/// <term>The certificate does not support the required extension.</term>
/// </item>
/// <item>
/// <term>NTE_BAD_ALGID</term>
/// <term>The hash algorithm OID is unknown.</term>
/// </item>
/// </list>
/// </returns>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-certretrievelogoorbiometricinfo BOOL
// CertRetrieveLogoOrBiometricInfo( PCCERT_CONTEXT pCertContext, LPCSTR lpszLogoOrBiometricType, DWORD dwRetrievalFlags, DWORD
// dwTimeout, DWORD dwFlags, void *pvReserved, BYTE **ppbData, DWORD *pcbData, LPWSTR *ppwszMimeType );
[DllImport(Lib.Crypt32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "35813928-728e-40b7-b627-817d3094eeb1")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CertRetrieveLogoOrBiometricInfo(PCCERT_CONTEXT pCertContext, [In] SafeOID lpszLogoOrBiometricType, CryptRetrievalFlags dwRetrievalFlags,
uint dwTimeout, [Optional] uint dwFlags, [Optional] IntPtr pvReserved, out SafeCryptMem ppbData, out uint pcbData, out SafeCryptMem ppwszMimeType);
/// <summary>The <c>CertSelectCertificateChains</c> function retrieves certificate chains based on specified selection criteria.</summary>
/// <param name="pSelectionContext">A pointer to the GUID of the certificate selection scenario to use for this call.</param>
/// <param name="dwFlags">
/// <para>
/// Flags for controlling the certificate selection process. This parameter can be a combination of zero or more of the following flags:
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>CERT_SELECT_ALLOW_EXPIRED</term>
/// <term>Select expired certificates that meet selection criteria. By default expired certificates are rejected from selection.</term>
/// </item>
/// <item>
/// <term>CERT_SELECT_TRUSTED_ROOT</term>
/// <term>
/// Select certificates on which the error bit in the certificate chain trust status is not set to CERT_TRUST_IS_UNTRUSTED_ROOT,
/// CERT_TRUST_IS_PARTIAL_CHAIN, or CERT_TRUST_IS_NOT_TIME_VALID. In addition, certificates that have one of the following invalid
/// constraint errors are not selected:
/// </term>
/// </item>
/// <item>
/// <term>CERT_SELECT_DISALLOW_SELFSIGNED</term>
/// <term>Select certificates that are not self-issued and self-signed.</term>
/// </item>
/// <item>
/// <term>CERT_SELECT_HAS_PRIVATE_KEY</term>
/// <term>Select certificates that have a value set for the CERT_KEY_PROV_INFO_PROP_ID property of the certificate.</term>
/// </item>
/// <item>
/// <term>CERT_SELECT_HAS_KEY_FOR_SIGNATURE</term>
/// <term>
/// Select certificates on which the value of the dwKeySpec member of the CERT_KEY_PROV_INFO_PROP_ID property is set to
/// AT_SIGNATURE. If this function is being called as part of a CNG enabled application and the dwKeySpec member of the
/// CERT_KEY_PROV_INFO_PROP_ID property is set to -1, select certificates on which the value of the NCRYPT_KEY_USAGE_PROPERTY
/// property of the associated private key has the NCRYPT_ALLOW_SIGNING_FLAG set.
/// </term>
/// </item>
/// <item>
/// <term>CERT_SELECT_HAS_KEY_FOR_KEY_EXCHANGE</term>
/// <term>
/// Select certificates on which the value of the dwKeySpec member of the CERT_KEY_PROV_INFO_PROP_ID property is set to
/// AT_KEYEXCHANGE. If this function is being called as part of a CNG enabled application and the dwKeySpec member of the
/// CERT_KEY_PROV_INFO_PROP_ID property is set to -1, select certificates on which either NCRYPT_ALLOW_DECRYPT_FLAG or
/// NCRYPT_ALLOW_KEY_AGREEMENT_FLAG is set.
/// </term>
/// </item>
/// <item>
/// <term>CERT_SELECT_HARDWARE_ONLY</term>
/// <term>
/// Select certificates on which the value of the PP_IMPTYPE property of the associated private key provider is set to either
/// CRYPT_IMPL_HARDWARE or CRYPT_IMPL_REMOVABLE. (For CNG providers, NCRYPT_IMPL_TYPE_PROPERTY property value MUST have either the
/// NCRYPT_IMPL_HARDWARE_FLAG or NCRYPT_IMPL_REMOVABLE_FLAG bit set). If this function is being called as part of a CNG enabled
/// application, select certificates on which the NCRYPT_IMPL_TYPE_PROPERTY property is set to NCRYPT_IMPL_HARDWARE_FLAG or NCRYPT_IMPL_REMOVABLE_FLAG.
/// </term>
/// </item>
/// <item>
/// <term>CERT_SELECT_ALLOW_DUPLICATES</term>
/// <term>
/// Allow the selection of certificates on which the Subject and Subject Alt Name contain the same information and the certificate
/// template extension value is equivalent. By default when certificates match this criteria, only the most recent certificate is selected.
/// </term>
/// </item>
/// </list>
/// </param>
/// <param name="pChainParameters">
/// <para>
/// A pointer to a CERT_SELECT_CHAIN_PARA structure to specify parameters for chain building. If <c>NULL</c>, default parameters
/// will be used.
/// </para>
/// <para>
/// The <c>pChainPara</c> member of the CERT_SELECT_CHAIN_PARA structure points to a CERT_CHAIN_PARA structure that can be used to
/// enable strong signing.
/// </para>
/// </param>
/// <param name="cCriteria">The number of elements in the array pointed to by the rgpCriteria array.</param>
/// <param name="rgpCriteria">
/// A pointer to an array of CERT_SELECT_CRITERIA structures that define the selection criteria. If this parameter is set to
/// <c>NULL</c>, the value of the cCriteria parameter must be zero.
/// </param>
/// <param name="hStore">The handle to a store from which to select the certificates.</param>
/// <param name="pcSelection">
/// A pointer to a <c>DWORD</c> value to receive the number of elements in the array pointed to by the pprgpSelection parameter.
/// </param>
/// <param name="pprgpSelection">
/// <para>
/// A pointer to a pointer to a location to receive an array of CERT_CHAIN_CONTEXT structure. The <c>CertSelectCertificateChains</c>
/// function only returns certificate chains that match all the selection criteria. The entries in the array are ordered by quality,
/// i.e. the chain with the highest quality is the first entry.
/// </para>
/// <para>
/// Storage for the array is allocated by the <c>CertSelectCertificateChains</c> function. To free the allocated memory you must
/// first release each individual chain context in the array by calling the CertFreeCertificateChain function. Then you must free
/// the memory by calling the CertFreeCertificateChainList function.
/// </para>
/// </param>
/// <returns>
/// <para>If the function succeeds, the function returns <c>TRUE</c>.</para>
/// <para>If the function fails, it returns zero (FALSE). For extended error information, call the GetLastError function.</para>
/// <para>
/// <c>Note</c> If the selection does not yield any results, the <c>CertSelectCertificateChains</c> function returns <c>TRUE</c>,
/// but the value pointed to by pcSelection parameter is set to zero.
/// </para>
/// </returns>
/// <remarks>
/// <para>
/// Selection criteria can be specified through either the dwFlags parameter, through the rgpCriteria parameter, or through both
/// parameters. If no selection criteria are specified, the function succeeds and returns certificate chains for all certificates in
/// the store specified by the hStore parameter.
/// </para>
/// <para>Certificate chains that are selected are ordered based on the following preference logic:</para>
/// <list type="bullet">
/// <item>
/// <term>Prefer certificates that are smart card certificates over certificates that are not smart-card based.</term>
/// </item>
/// <item>
/// <term>Prefer certificates that have a longer validity period (the expiration date is later.)</term>
/// </item>
/// <item>
/// <term>If multiple certificates have same expiration date, prefer certificates that were issued more recently.</term>
/// </item>
/// <item>
/// <term>If there is a tie, prefer shorter chains.</term>
/// </item>
/// </list>
/// <para>
/// Certain selection criteria require that a certificate chain be built before you can select that criteria for use. If the
/// intermediate certificates required to build the chain are not available locally, a network retrieval is performed for the issuer
/// certificates. This network retrieval is performed if the <c>CERT_SELECT_TRUSTED_ROOT</c> flag is set or for the following criteria:
/// </para>
/// <list type="bullet">
/// <item>
/// <term><c>CERT_SELECT_BY_ISSUER_NAME</c></term>
/// </item>
/// <item>
/// <term><c>CERT_SELECT_BY_ISSUER_ATTR</c></term>
/// </item>
/// <item>
/// <term><c>CERT_SELECT_BY_POLICY_OID</c></term>
/// </item>
/// </list>
/// <para>Perform the following actions to enable strong signature checking:</para>
/// <list type="bullet">
/// <item>
/// <term>
/// Create a CERT_STRONG_SIGN_PARA structure, specify the required strong signing parameters, and set a pointer to the structure in
/// the <c>pStrongSignPara</c> member of a CERT_CHAIN_PARA structure.
/// </term>
/// </item>
/// <item>
/// <term>Set a pointer to the CERT_CHAIN_PARA structure in the <c>pChainPara</c> member of a CERT_SELECT_CHAIN_PARA structure.</term>
/// </item>
/// <item>
/// <term>Set a pointer to the CERT_SELECT_CHAIN_PARA structure in the pChainParameters parameter of this ( <c>CertSelectCertificateChains</c>)function.</term>
/// </item>
/// </list>
/// <para>
/// When you enable strong signature checking, any certificate chain that returns a <c>CERT_TRUST_IS_NOT_SIGNATURE_VALID</c> error
/// in the <c>dwErrorStatus</c> field of the CERT_TRUST_STATUS structure will be skipped. (The pprgpSelection parameter points to a
/// CERT_CHAIN_CONTEXT structure which, in turn, points to the <c>CERT_TRUST_STATUS</c> structure.) The
/// <c>CERT_TRUST_HAS_WEAK_SIGNATURE</c> value is also set for a weak signature.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-certselectcertificatechains BOOL
// CertSelectCertificateChains( LPCGUID pSelectionContext, DWORD dwFlags, PCCERT_SELECT_CHAIN_PARA pChainParameters, DWORD
// cCriteria, PCCERT_SELECT_CRITERIA rgpCriteria, HCERTSTORE hStore, PDWORD pcSelection, PCCERT_CHAIN_CONTEXT **pprgpSelection );
[DllImport(Lib.Crypt32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "b740772b-d25b-4b3d-9acb-03f7018750d6")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CertSelectCertificateChains(in Guid pSelectionContext, CertSelection dwFlags, [Optional] IntPtr pChainParameters, uint cCriteria, [In, Optional, MarshalAs(UnmanagedType.LPArray)] CERT_SELECT_CRITERIA[] rgpCriteria,
HCERTSTORE hStore, out uint pcSelection, out IntPtr pprgpSelection);
/// <summary>The <c>CertSelectCertificateChains</c> function retrieves certificate chains based on specified selection criteria.</summary>
/// <param name="pSelectionContext">A pointer to the GUID of the certificate selection scenario to use for this call.</param>
/// <param name="dwFlags">
/// <para>
/// Flags for controlling the certificate selection process. This parameter can be a combination of zero or more of the following flags:
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>CERT_SELECT_ALLOW_EXPIRED</term>
/// <term>Select expired certificates that meet selection criteria. By default expired certificates are rejected from selection.</term>
/// </item>
/// <item>
/// <term>CERT_SELECT_TRUSTED_ROOT</term>
/// <term>
/// Select certificates on which the error bit in the certificate chain trust status is not set to CERT_TRUST_IS_UNTRUSTED_ROOT,
/// CERT_TRUST_IS_PARTIAL_CHAIN, or CERT_TRUST_IS_NOT_TIME_VALID. In addition, certificates that have one of the following invalid
/// constraint errors are not selected:
/// </term>
/// </item>
/// <item>
/// <term>CERT_SELECT_DISALLOW_SELFSIGNED</term>
/// <term>Select certificates that are not self-issued and self-signed.</term>
/// </item>
/// <item>
/// <term>CERT_SELECT_HAS_PRIVATE_KEY</term>
/// <term>Select certificates that have a value set for the CERT_KEY_PROV_INFO_PROP_ID property of the certificate.</term>
/// </item>
/// <item>
/// <term>CERT_SELECT_HAS_KEY_FOR_SIGNATURE</term>
/// <term>
/// Select certificates on which the value of the dwKeySpec member of the CERT_KEY_PROV_INFO_PROP_ID property is set to
/// AT_SIGNATURE. If this function is being called as part of a CNG enabled application and the dwKeySpec member of the
/// CERT_KEY_PROV_INFO_PROP_ID property is set to -1, select certificates on which the value of the NCRYPT_KEY_USAGE_PROPERTY
/// property of the associated private key has the NCRYPT_ALLOW_SIGNING_FLAG set.
/// </term>
/// </item>
/// <item>
/// <term>CERT_SELECT_HAS_KEY_FOR_KEY_EXCHANGE</term>
/// <term>
/// Select certificates on which the value of the dwKeySpec member of the CERT_KEY_PROV_INFO_PROP_ID property is set to
/// AT_KEYEXCHANGE. If this function is being called as part of a CNG enabled application and the dwKeySpec member of the
/// CERT_KEY_PROV_INFO_PROP_ID property is set to -1, select certificates on which either NCRYPT_ALLOW_DECRYPT_FLAG or
/// NCRYPT_ALLOW_KEY_AGREEMENT_FLAG is set.
/// </term>
/// </item>
/// <item>
/// <term>CERT_SELECT_HARDWARE_ONLY</term>
/// <term>
/// Select certificates on which the value of the PP_IMPTYPE property of the associated private key provider is set to either
/// CRYPT_IMPL_HARDWARE or CRYPT_IMPL_REMOVABLE. (For CNG providers, NCRYPT_IMPL_TYPE_PROPERTY property value MUST have either the
/// NCRYPT_IMPL_HARDWARE_FLAG or NCRYPT_IMPL_REMOVABLE_FLAG bit set). If this function is being called as part of a CNG enabled
/// application, select certificates on which the NCRYPT_IMPL_TYPE_PROPERTY property is set to NCRYPT_IMPL_HARDWARE_FLAG or NCRYPT_IMPL_REMOVABLE_FLAG.
/// </term>
/// </item>
/// <item>
/// <term>CERT_SELECT_ALLOW_DUPLICATES</term>
/// <term>
/// Allow the selection of certificates on which the Subject and Subject Alt Name contain the same information and the certificate
/// template extension value is equivalent. By default when certificates match this criteria, only the most recent certificate is selected.
/// </term>
/// </item>
/// </list>
/// </param>
/// <param name="pChainParameters">
/// <para>
/// A pointer to a CERT_SELECT_CHAIN_PARA structure to specify parameters for chain building. If <c>NULL</c>, default parameters
/// will be used.
/// </para>
/// <para>
/// The <c>pChainPara</c> member of the CERT_SELECT_CHAIN_PARA structure points to a CERT_CHAIN_PARA structure that can be used to
/// enable strong signing.
/// </para>
/// </param>
/// <param name="cCriteria">The number of elements in the array pointed to by the rgpCriteria array.</param>
/// <param name="rgpCriteria">
/// A pointer to an array of CERT_SELECT_CRITERIA structures that define the selection criteria. If this parameter is set to
/// <c>NULL</c>, the value of the cCriteria parameter must be zero.
/// </param>
/// <param name="hStore">The handle to a store from which to select the certificates.</param>
/// <param name="pcSelection">
/// A pointer to a <c>DWORD</c> value to receive the number of elements in the array pointed to by the pprgpSelection parameter.
/// </param>
/// <param name="pprgpSelection">
/// <para>
/// A pointer to a pointer to a location to receive an array of CERT_CHAIN_CONTEXT structure. The <c>CertSelectCertificateChains</c>
/// function only returns certificate chains that match all the selection criteria. The entries in the array are ordered by quality,
/// i.e. the chain with the highest quality is the first entry.
/// </para>
/// <para>
/// Storage for the array is allocated by the <c>CertSelectCertificateChains</c> function. To free the allocated memory you must
/// first release each individual chain context in the array by calling the CertFreeCertificateChain function. Then you must free
/// the memory by calling the CertFreeCertificateChainList function.
/// </para>
/// </param>
/// <returns>
/// <para>If the function succeeds, the function returns <c>TRUE</c>.</para>
/// <para>If the function fails, it returns zero (FALSE). For extended error information, call the GetLastError function.</para>
/// <para>
/// <c>Note</c> If the selection does not yield any results, the <c>CertSelectCertificateChains</c> function returns <c>TRUE</c>,
/// but the value pointed to by pcSelection parameter is set to zero.
/// </para>
/// </returns>
/// <remarks>
/// <para>
/// Selection criteria can be specified through either the dwFlags parameter, through the rgpCriteria parameter, or through both
/// parameters. If no selection criteria are specified, the function succeeds and returns certificate chains for all certificates in
/// the store specified by the hStore parameter.
/// </para>
/// <para>Certificate chains that are selected are ordered based on the following preference logic:</para>
/// <list type="bullet">
/// <item>
/// <term>Prefer certificates that are smart card certificates over certificates that are not smart-card based.</term>
/// </item>
/// <item>
/// <term>Prefer certificates that have a longer validity period (the expiration date is later.)</term>
/// </item>
/// <item>
/// <term>If multiple certificates have same expiration date, prefer certificates that were issued more recently.</term>
/// </item>
/// <item>
/// <term>If there is a tie, prefer shorter chains.</term>
/// </item>
/// </list>
/// <para>
/// Certain selection criteria require that a certificate chain be built before you can select that criteria for use. If the
/// intermediate certificates required to build the chain are not available locally, a network retrieval is performed for the issuer
/// certificates. This network retrieval is performed if the <c>CERT_SELECT_TRUSTED_ROOT</c> flag is set or for the following criteria:
/// </para>
/// <list type="bullet">
/// <item>
/// <term><c>CERT_SELECT_BY_ISSUER_NAME</c></term>
/// </item>
/// <item>
/// <term><c>CERT_SELECT_BY_ISSUER_ATTR</c></term>
/// </item>
/// <item>
/// <term><c>CERT_SELECT_BY_POLICY_OID</c></term>
/// </item>
/// </list>
/// <para>Perform the following actions to enable strong signature checking:</para>
/// <list type="bullet">
/// <item>
/// <term>
/// Create a CERT_STRONG_SIGN_PARA structure, specify the required strong signing parameters, and set a pointer to the structure in
/// the <c>pStrongSignPara</c> member of a CERT_CHAIN_PARA structure.
/// </term>
/// </item>
/// <item>
/// <term>Set a pointer to the CERT_CHAIN_PARA structure in the <c>pChainPara</c> member of a CERT_SELECT_CHAIN_PARA structure.</term>
/// </item>
/// <item>
/// <term>Set a pointer to the CERT_SELECT_CHAIN_PARA structure in the pChainParameters parameter of this ( <c>CertSelectCertificateChains</c>)function.</term>
/// </item>
/// </list>
/// <para>
/// When you enable strong signature checking, any certificate chain that returns a <c>CERT_TRUST_IS_NOT_SIGNATURE_VALID</c> error
/// in the <c>dwErrorStatus</c> field of the CERT_TRUST_STATUS structure will be skipped. (The pprgpSelection parameter points to a
/// CERT_CHAIN_CONTEXT structure which, in turn, points to the <c>CERT_TRUST_STATUS</c> structure.) The
/// <c>CERT_TRUST_HAS_WEAK_SIGNATURE</c> value is also set for a weak signature.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-certselectcertificatechains BOOL
// CertSelectCertificateChains( LPCGUID pSelectionContext, DWORD dwFlags, PCCERT_SELECT_CHAIN_PARA pChainParameters, DWORD
// cCriteria, PCCERT_SELECT_CRITERIA rgpCriteria, HCERTSTORE hStore, PDWORD pcSelection, PCCERT_CHAIN_CONTEXT **pprgpSelection );
[DllImport(Lib.Crypt32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "b740772b-d25b-4b3d-9acb-03f7018750d6")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CertSelectCertificateChains([Optional] IntPtr pSelectionContext, CertSelection dwFlags, [Optional] IntPtr pChainParameters, uint cCriteria, [In, Optional, MarshalAs(UnmanagedType.LPArray)] CERT_SELECT_CRITERIA[] rgpCriteria,
HCERTSTORE hStore, out uint pcSelection, out IntPtr pprgpSelection);
/// <summary>
/// The <c>CertSerializeCertificateStoreElement</c> function serializes a certificate context's encoded certificate and its encoded
/// properties. The result can be persisted to storage so that the certificate and properties can be retrieved at a later time.
/// </summary>
/// <param name="pCertContext">A pointer to the CERT_CONTEXT to be serialized.</param>
/// <param name="dwFlags">Reserved for future use and must be zero.</param>
/// <param name="pbElement">
/// <para>A pointer to a buffer that receives the serialized output, including the encoded certificate and possibly its properties.</para>
/// <para>
/// This parameter can be <c>NULL</c> to set the size of this information for memory allocation purposes. For more information, see
/// Retrieving Data of Unknown Length.
/// </para>
/// </param>
/// <param name="pcbElement">
/// <para>
/// A pointer to a <c>DWORD</c> value specifying the size, in bytes, of the buffer pointed to by the pbElement parameter. When the
/// function returns, <c>DWORD</c> value contains the number of bytes stored in the buffer.
/// </para>
/// <para>
/// <c>Note</c> When processing the data returned in the buffer, applications must use the actual size of the data returned. The
/// actual size can be slightly smaller than the size of the buffer specified on input. (On input, buffer sizes are usually
/// specified large enough to ensure that the largest possible output data fits in the buffer.) On output, the variable pointed to
/// by this parameter is updated to reflect the actual size of the data copied to the buffer.
/// </para>
/// </param>
/// <returns>
/// <para>If the function succeeds, the return value is <c>TRUE</c>.</para>
/// <para>If the function fails, the return value is <c>FALSE</c>. For extended error information, call GetLastError.</para>
/// </returns>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-certserializecertificatestoreelement BOOL
// CertSerializeCertificateStoreElement( PCCERT_CONTEXT pCertContext, DWORD dwFlags, BYTE *pbElement, DWORD *pcbElement );
[DllImport(Lib.Crypt32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "104fc986-6344-41b7-8843-23c3c72405a2")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CertSerializeCertificateStoreElement(PCCERT_CONTEXT pCertContext, [Optional] uint dwFlags, [In, Out, Optional] IntPtr pbElement, ref uint pcbElement);
/// <summary>
/// The <c>CertVerifySubjectCertificateContext</c> function performs the enabled verification checks on a certificate by checking
/// the validity of the certificate's issuer. The new Certificate Chain Verification Functions are recommended instead of this function.
/// </summary>
/// <param name="pSubject">A pointer to a CERT_CONTEXT structure containing the subject's certificate.</param>
/// <param name="pIssuer">
/// A pointer to a CERT_CONTEXT containing the issuer's certificate. When checking just CERT_STORE_TIME_VALIDITY_FLAG, pIssuer can
/// be <c>NULL</c>.
/// </param>
/// <param name="pdwFlags">
/// <para>
/// A pointer to a <c>DWORD</c> value contain verification check flags. The following flags can be set to enable verification checks
/// on the subject certificate. They can be combined using a bitwise- <c>OR</c> operation to enable multiple verifications.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>CERT_STORE_REVOCATION_FLAG</term>
/// <term>Checks whether the subject certificate is on the issuer's revocation list.</term>
/// </item>
/// <item>
/// <term>CERT_STORE_SIGNATURE_FLAG</term>
/// <term>Uses the public key in the issuer's certificate to verify the signature on the subject certificate.</term>
/// </item>
/// <item>
/// <term>CERT_STORE_TIME_VALIDITY_FLAG</term>
/// <term>Gets the current time and verifies that it is within the subject certificate's validity period.</term>
/// </item>
/// </list>
/// <para>If an enabled verification check succeeds, its flag is set to zero. If it fails, then its flag is set upon return.</para>
/// <para>
/// If CERT_STORE_REVOCATION_FLAG was enabled and the issuer does not have a CRL in the store, then CERT_STORE_NO_CRL_FLAG is set in
/// addition to CERT_STORE_REVOCATION_FLAG.
/// </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>.</para>
/// <para>
/// For a verification check failure, <c>TRUE</c> is still returned. <c>FALSE</c> is returned only when a bad parameter is passed in.
/// </para>
/// <para>For extended error information, call GetLastError. One possible error code is the following.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>E_INVALIDARG</term>
/// <term>
/// An unsupported bit was set in pdwFlags. Any combination of CERT_STORE_SIGNATURE_FLAG, CERT_STORE_TIME_VALIDITY_FLAG, and
/// CERT_STORE_REVOCATION_FLAG can be set. If pIssuer is NULL, only CERT_STORE_TIME_VALIDITY_FLAG can be set.
/// </term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The hexadecimal value of the flags can be combined using bitwise- <c>OR</c> operations to enable multiple verifications. For
/// example, to enable both signature and time validity, the value
/// </para>
/// <para>
/// is placed in the pdwFlags <c>DWORD</c> value as an input parameter. If CERT_STORE_SIGNATURE_FLAG verification succeeds, but
/// CERT_STORE_TIME_VALIDITY_FLAG verification fails, pdwFlags is set to CERT_STORE_TIME_VALIDITY_FLAG when the function returns.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-certverifysubjectcertificatecontext BOOL
// CertVerifySubjectCertificateContext( PCCERT_CONTEXT pSubject, PCCERT_CONTEXT pIssuer, DWORD *pdwFlags );
[DllImport(Lib.Crypt32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "063b19cf-d3b3-4ec3-bfd3-9406eecd3e10")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CertVerifySubjectCertificateContext(PCCERT_CONTEXT pSubject, PCCERT_CONTEXT pIssuer, ref CertStoreVerification pdwFlags);
/// <summary>
/// The <c>CERT_CHAIN_CONTEXT</c> structure contains an array of simple certificate chains and a trust status structure that
/// indicates summary validity data on all of the connected simple chains.
/// </summary>
/// <remarks>
/// When a <c>CERT_CHAIN_CONTEXT</c> is built, the first simple chain begins with an end certificate and ends with a self-signed
/// certificate. If that self-signed certificate is not a root or otherwise trusted certificate, an attempt is made to build a new
/// chain. CTLs are used to create the new chain beginning with the self-signed certificate from the original chain as the end
/// certificate of the new chain. This process continues building additional simple chains until the first self-signed certificate
/// is a trusted certificate or until an additional simple chain cannot be built.
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/ns-wincrypt-cert_chain_context typedef struct _CERT_CHAIN_CONTEXT {
// DWORD cbSize; CERT_TRUST_STATUS TrustStatus; DWORD cChain; PCERT_SIMPLE_CHAIN *rgpChain; DWORD cLowerQualityChainContext;
// PCCERT_CHAIN_CONTEXT *rgpLowerQualityChainContext; BOOL fHasRevocationFreshnessTime; DWORD dwRevocationFreshnessTime; DWORD
// dwCreateFlags; GUID ChainId; } CERT_CHAIN_CONTEXT, *PCERT_CHAIN_CONTEXT;
[PInvokeData("wincrypt.h", MSDNShortId = "609311f4-9cd6-4945-9f93-7266b3fc4a74")]
[StructLayout(LayoutKind.Sequential)]
public struct CERT_CHAIN_CONTEXT
{
/// <summary>The size, in bytes, of this structure.</summary>
public uint cbSize;
/// <summary>
/// A structure that indicates the combined trust status of the simple chains array. The structure includes an error status code
/// and an information status code. For information about status code values, see CERT_TRUST_STATUS.
/// </summary>
public CERT_TRUST_STATUS TrustStatus;
/// <summary>The number of simple chains in the array.</summary>
public uint cChain;
/// <summary>
/// An array of pointers to simple chain structures. <c>rgpChain</c>[0] is the end certificate simple chain, and
/// <c>rgpChain</c>[ <c>cChain</c>1] is the final chain. If the end certificate is to be considered valid, the final chain must
/// begin with a certificate contained in the root store or an otherwise trusted, self-signed certificate. If the original chain
/// begins with a trusted certificate, there will be only a single simple chain in the array.
/// </summary>
public IntPtr rgpChain;
/// <summary>The number of chains in the <c>rgpLowerQualityChainContext</c> array.</summary>
public uint cLowerQualityChainContext;
/// <summary>
/// An array of pointers to CERT_CHAIN_CONTEXT structures. Returned when CERT_CHAIN_RETURN_LOWER_QUALITY_CONTEXTS is set in dwFlags.
/// </summary>
public IntPtr rgpLowerQualityChainContext;
/// <summary>A Boolean value set to <c>TRUE</c> if <c>dwRevocationFreshnessTime</c> is available.</summary>
[MarshalAs(UnmanagedType.Bool)] public bool fHasRevocationFreshnessTime;
/// <summary>
/// The largest CurrentTime, in seconds, minus the certificate revocation list's (CRL's) ThisUpdate of all elements checked.
/// </summary>
public uint dwRevocationFreshnessTime;
/// <summary/>
public uint dwCreateFlags;
/// <summary/>
public Guid ChainId;
/// <summary>Gets the chain from <see cref="rgpChain"/>.</summary>
public unsafe CERT_SIMPLE_CHAIN*[] GetChain()
{
var ret = new CERT_SIMPLE_CHAIN*[(int)cChain];
for (int i = 0; i < cChain; i++)
ret[i] = ((CERT_SIMPLE_CHAIN**)rgpChain)[i];
return ret;
}
/// <summary>Gets the contexts from <see cref="rgpLowerQualityChainContext"/>.</summary>
public unsafe CERT_CHAIN_CONTEXT*[] GetLowerQualityChainContext()
{
var ret = new CERT_CHAIN_CONTEXT*[(int)cLowerQualityChainContext];
for (int i = 0; i < cLowerQualityChainContext; i++)
ret[i] = ((CERT_CHAIN_CONTEXT**)rgpLowerQualityChainContext)[i];
return ret;
}
}
/// <summary>
/// The <c>CERT_CHAIN_ELEMENT</c> structure is a single element in a simple certificate chain. Each element has a pointer to a
/// certificate context, a pointer to a structure that indicates the error status and information status of the certificate, and a
/// pointer to a structure that indicates the revocation status of the certificate.
/// </summary>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/ns-wincrypt-cert_chain_element typedef struct _CERT_CHAIN_ELEMENT {
// DWORD cbSize; PCCERT_CONTEXT pCertContext; CERT_TRUST_STATUS TrustStatus; PCERT_REVOCATION_INFO pRevocationInfo;
// PCERT_ENHKEY_USAGE pIssuanceUsage; PCERT_ENHKEY_USAGE pApplicationUsage; LPCWSTR pwszExtendedErrorInfo; } CERT_CHAIN_ELEMENT, *PCERT_CHAIN_ELEMENT;
[PInvokeData("wincrypt.h", MSDNShortId = "a1f6ba18-63ef-43ac-a17f-900fa13398aa")]
[StructLayout(LayoutKind.Sequential)]
public struct CERT_CHAIN_ELEMENT
{
/// <summary>Size of this structure in bytes.</summary>
public uint cbSize;
/// <summary>A pointer to a certificate context.</summary>
public PCCERT_CONTEXT pCertContext;
/// <summary>
/// Structure indicating the status of the certificate. The structure includes an error status code and an information status
/// code. For information about status code values, see CERT_TRUST_STATUS.
/// </summary>
public CERT_TRUST_STATUS TrustStatus;
/// <summary>
/// A pointer to a CERT_REVOCATION_INFO structure with information on the revocation status of the certificate. If revocation
/// checking was not enabled, <c>pRevocationInfo</c> is <c>NULL</c>.
/// </summary>
public IntPtr pRevocationInfo;
/// <summary>A pointer to a CERT_ENHKEY_USAGE structure. If <c>NULL</c>, any issuance policy is acceptable.</summary>
public IntPtr pIssuanceUsage;
/// <summary>A pointer to a CERT_ENHKEY_USAGE structure. If <c>NULL</c>, any enhanced key usage is acceptable.</summary>
public IntPtr pApplicationUsage;
/// <summary>
/// A pointer to a <c>null</c>-terminated wide character string that contains extended error information. If <c>NULL</c>, there
/// is no extended error information.
/// </summary>
public StrPtrUni pwszExtendedErrorInfo;
}
/// <summary>
/// Contains information updated by a certificate revocation list (CRL) revocation type handler. The <c>CERT_REVOCATION_CRL_INFO</c>
/// structure is used with both base and delta CRLs.
/// </summary>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/ns-wincrypt-cert_revocation_crl_info typedef struct
// _CERT_REVOCATION_CRL_INFO { DWORD cbSize; PCCRL_CONTEXT pBaseCrlContext; PCCRL_CONTEXT pDeltaCrlContext; PCRL_ENTRY pCrlEntry;
// BOOL fDeltaCrlEntry; } CERT_REVOCATION_CRL_INFO, *PCERT_REVOCATION_CRL_INFO;
[PInvokeData("wincrypt.h", MSDNShortId = "069ff521-90fd-4de8-9b5c-045e44e87f75")]
[StructLayout(LayoutKind.Sequential)]
public struct CERT_REVOCATION_CRL_INFO
{
/// <summary>Size, in bytes, of the structure.</summary>
public uint cbSize;
/// <summary/>
public PCCRL_CONTEXT pBaseCrlContext;
/// <summary/>
public PCCRL_CONTEXT pDeltaCrlContext;
/// <summary>A pointer to an entry in either the base CRL or the delta CRL.</summary>
public IntPtr pCrlEntry;
/// <summary>
/// <c>TRUE</c> if <c>pCrlEntry</c> points to an entry in the delta CRL. <c>FALSE</c> if <c>pCrlEntry</c> points to an entry in
/// the base CRL.
/// </summary>
[MarshalAs(UnmanagedType.Bool)] public bool fDeltaCrlEntry;
}
/// <summary>The <c>CERT_REVOCATION_INFO</c> structure indicates the revocation status of a certificate in a CERT_CHAIN_ELEMENT.</summary>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/ns-wincrypt-cert_revocation_info typedef struct _CERT_REVOCATION_INFO
// { DWORD cbSize; DWORD dwRevocationResult; LPCSTR pszRevocationOid; LPVOID pvOidSpecificInfo; BOOL fHasFreshnessTime; DWORD
// dwFreshnessTime; PCERT_REVOCATION_CRL_INFO pCrlInfo; } CERT_REVOCATION_INFO, *PCERT_REVOCATION_INFO;
[PInvokeData("wincrypt.h", MSDNShortId = "798aa2d7-bf8a-425f-bc36-98a44ba3a9d6")]
[StructLayout(LayoutKind.Sequential)]
public struct CERT_REVOCATION_INFO
{
/// <summary>Size of this structure in bytes.</summary>
public uint cbSize;
/// <summary>
/// <para>Currently defined values are:</para>
/// <list type="bullet">
/// <item>
/// <term>CERT_TRUST_IS_REVOKED</term>
/// </item>
/// <item>
/// <term>CERT_TRUST_REVOCATION_STATUS_IS_UNKNOWN</term>
/// </item>
/// </list>
/// </summary>
public uint dwRevocationResult;
/// <summary>Not currently used and is set to <c>NULL</c>.</summary>
public StrPtrAnsi pszRevocationOid;
/// <summary>Not currently used and is set to <c>NULL</c>.</summary>
public IntPtr pvOidSpecificInfo;
/// <summary>BOOL set to <c>TRUE</c> if dwFreshnessTime has been updated.</summary>
[MarshalAs(UnmanagedType.Bool)] public bool fHasFreshnessTime;
/// <summary>
/// If <c>fHasFreshnessTime</c> is <c>TRUE</c>, holds the CurrentTime minus the certificate revocation list's (CRL's). This time
/// is in seconds.
/// </summary>
public uint dwFreshnessTime;
/// <summary>For CRL base revocation checking, a non- <c>NULL</c> pointer to a CERT_REVOCATION_CRL_INFO structure.</summary>
public IntPtr pCrlInfo;
}
/// <summary>
/// The <c>CERT_SELECT_CHAIN_PARA</c> structure contains the parameters used for building and selecting chains. This structure is
/// used by the CertGetCertificateChain and CertSelectCertificateChains functions.
/// </summary>
/// <remarks>
/// <para>
/// Trust in a particular certificate being a trusted root is based on the current state of the root store and not the state of the
/// root store at a time passed in by this parameter. For revocation, a certificate revocation list (CRL), itself, must be valid at
/// the current time. The value of this parameter is used to determine whether a certificate listed in a CRL has been revoked.
/// </para>
/// <para>The following remarks apply to strong signature checking:</para>
/// <list type="bullet">
/// <item>
/// <term>
/// You can enable strong signature checking by using the CERT_CHAIN_PARA structure referenced by the <c>pChainPara</c> member. The
/// <c>pStrongSignPara</c> member of the <c>CERT_CHAIN_PARA</c> structure points to a CERT_STRONG_SIGN_PARA structure that can be
/// used to determine signature strength.
/// </term>
/// </item>
/// <item>
/// <term>
/// When you enable strong checking and a weak signature is encountered, the <c>CERT_TRUST_IS_NOT_SIGNATURE_VALID</c> and
/// <c>CERT_TRUST_HAS_WEAK_SIGNATURE</c> errors are set in the <c>dwErrorStatus</c> field of the CERT_TRUST_STATUS structure.
/// </term>
/// </item>
/// </list>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/ns-wincrypt-cert_select_chain_para typedef struct
// _CERT_SELECT_CHAIN_PARA { HCERTCHAINENGINE hChainEngine; PFILETIME pTime; HCERTSTORE hAdditionalStore; PCERT_CHAIN_PARA
// pChainPara; DWORD dwFlags; } CERT_SELECT_CHAIN_PARA, *PCERT_SELECT_CHAIN_PARA;
[PInvokeData("wincrypt.h", MSDNShortId = "55c6c063-2a65-40ad-8d3f-7723b83cf021")]
[StructLayout(LayoutKind.Sequential)]
public struct CERT_SELECT_CHAIN_PARA
{
/// <summary>
/// The handle of the chain engine to use to build the chain. If the value of the hChainEngine parameter is <c>NULL</c>, the
/// default chain engine, <c>HCCE_CURRENT_USER</c>, is used.
/// </summary>
public HCERTCHAINENGINE hChainEngine;
/// <summary>
/// <para>
/// A pointer to a FILETIME structure that contains the time for which the chain is to be validated. If the value of the pTime
/// parameter is <c>NULL</c>, the current system time is passed to this parameter.
/// </para>
/// <para><c>Note</c> The time does not affect trust list, revocation, or root store checking.</para>
/// </summary>
public IntPtr pTime;
/// <summary>
/// The handle of any additional store to search for supporting certificates and certificate trust lists (CTLs). This parameter
/// can be <c>NULL</c> if no additional store is to be searched.
/// </summary>
public HCERTSTORE hAdditionalStore;
/// <summary>A pointer to a CERT_CHAIN_PARA structure that includes chain-building parameters.</summary>
public IntPtr pChainPara;
/// <summary>
/// <para>Flag values that indicate special processing during chain build.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>CERT_CHAIN_REVOCATION_CHECK_CACHE_ONLY 0x00000004</term>
/// <term>Revocation checking only accesses cached URLs.</term>
/// </item>
/// <item>
/// <term>CERT_CHAIN_CACHE_ONLY_URL_RETRIEVAL 0x80000000</term>
/// <term>Use only cached URLs in building a certificate chain. The Internet and intranet are not searched for URL-based objects.</term>
/// </item>
/// </list>
/// </summary>
public uint dwFlags;
}
/// <summary>
/// The <c>CERT_SELECT_CRITERIA</c> structure specifies selection criteria that is passed to the CertSelectCertificateChains function.
/// </summary>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/ns-wincrypt-cert_select_criteria typedef struct _CERT_SELECT_CRITERIA
// { DWORD dwType; DWORD cPara; void **ppPara; } CERT_SELECT_CRITERIA, *PCERT_SELECT_CRITERIA;
[PInvokeData("wincrypt.h", MSDNShortId = "246722a9-5db6-4a82-8f29-f60f0a2263e3")]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct CERT_SELECT_CRITERIA
{
/// <summary>
/// <para>
/// Specifies the type of selection criteria used for the <c>ppPara</c> member. This member can have one of the following values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>CERT_SELECT_BY_ENHKEY_USAGE 1</term>
/// <term>
/// Select certificates based on a specific enhanced key usage. When this flag is set, the ppPara must reference a
/// null-terminated object identifier (OID) ANSI string that specifies the enhanced key usage. This criteria is evaluated on the certificate.
/// </term>
/// </item>
/// <item>
/// <term>CERT_SELECT_BY_KEY_USAGE 2</term>
/// <term>
/// Select certificates based on a specific szOID_KEY_USAGE extension in the certificate. When this flag is set, the ppPara
/// member must reference a CERT_EXTENSION structure where the value of the extension is a DWORD that identifies the Key Usage
/// bits. This criteria is evaluated on the certificate.
/// </term>
/// </item>
/// <item>
/// <term>CERT_SELECT_BY_POLICY_OID 3</term>
/// <term>
/// Select certificates based on a specific issuance policy. The ppPara member must reference a null-terminated OID ANSI string
/// of the desired issuance policy. This criteria is evaluated on the issuance policy of the certificate chain.
/// </term>
/// </item>
/// <item>
/// <term>CERT_SELECT_BY_PROV_NAME 4</term>
/// <term>
/// Select certificates based on a specific private key provider. The ppPara member must reference a null-terminated Unicode
/// string that represents the name of the provider.
/// </term>
/// </item>
/// <item>
/// <term>CERT_SELECT_BY_EXTENSION 5</term>
/// <term>
/// Select certificates based on the presence of a specified extension and an optional specified value. The ppPara member must
/// reference a CERT_EXTENSION structure that specifies the extension OID and the associated value.
/// </term>
/// </item>
/// <item>
/// <term>CERT_SELECT_BY_SUBJECT_HOST_NAME 6</term>
/// <term>
/// Select certificates based on the Subject DNS HOST Name. The ppPara member must reference a null-terminated Unicode string
/// that contains the subject host name. The selection performed based on this flag is the same as the evaluation of the
/// pwszServerName member of the SSL_EXTRA_CERT_CHAIN_POLICY_PARA structure during a call to the
/// CertVerifyCertificateChainPolicy function. This criteria is evaluated on the certificate.
/// </term>
/// </item>
/// <item>
/// <term>CERT_SELECT_BY_ISSUER_ATTR 7</term>
/// <term>
/// Select certificates based on the relative distinguished name (RDN) element of the issuer of the certificate. The ppPara
/// member must reference a CERT_RDN structure that contains the RDN element of the issuer. This criteria is evaluated on the
/// certificate chain.
/// </term>
/// </item>
/// <item>
/// <term>CERT_SELECT_BY_SUBJECT_ATTR 8</term>
/// <term>
/// Select certificates based on the RDN element in the Subject of the certificate. The ppPara member must be a reference to a
/// CERT_RDN structure that contains the RDN element of the Subject. This criteria is evaluated on the certificate.
/// </term>
/// </item>
/// <item>
/// <term>CERT_SELECT_BY_ISSUER_NAME 9</term>
/// <term>
/// Select certificates based on the issuer of the certificate. The ppPara member must be a reference to a CERT_NAME_BLOB
/// structure that contains the name of the issuer. This criteria is evaluated on the certificate chain.
/// </term>
/// </item>
/// <item>
/// <term>CERT_SELECT_BY_PUBLIC_KEY 10</term>
/// <term>
/// Select certificates based on the public key of the certificate. The ppPara member must reference a pointer to a
/// CERT_PUBLIC_KEY_INFO structure that contains the public key. This criteria is evaluated on the certificate.
/// </term>
/// </item>
/// <item>
/// <term>CERT_SELECT_BY_TLS_SIGNATURES 11</term>
/// <term>
/// Select certificates based on the Transport Layer Security protocol (TLS) Signature requirement. The ppPara member must
/// reference a SecPkgContext_SupportedSignatures structure. This criteria is evaluated on the certificate.
/// </term>
/// </item>
/// </list>
/// </summary>
public CertSelectBy dwType;
/// <summary>A <c>DWORD</c> value that specifies the number of search attributes specified in the <c>ppPara</c> member.</summary>
public uint cPara;
/// <summary>
/// A pointer to a pointer to one or more selection values. The data type depends on the selection type specified by the
/// <c>dwType</c> member. If more than one selection value is present, an application must match only one value.
/// </summary>
public IntPtr ppPara;
}
/// <summary>
/// The <c>CERT_SIMPLE_CHAIN</c> structure contains an array of chain elements and a summary trust status for the chain that the
/// array represents.
/// </summary>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/ns-wincrypt-cert_simple_chain typedef struct _CERT_SIMPLE_CHAIN {
// DWORD cbSize; CERT_TRUST_STATUS TrustStatus; DWORD cElement; PCERT_CHAIN_ELEMENT *rgpElement; PCERT_TRUST_LIST_INFO
// pTrustListInfo; BOOL fHasRevocationFreshnessTime; DWORD dwRevocationFreshnessTime; } CERT_SIMPLE_CHAIN, *PCERT_SIMPLE_CHAIN;
[PInvokeData("wincrypt.h", MSDNShortId = "c130cab4-bf8d-429a-beb7-04cb5d37d466")]
[StructLayout(LayoutKind.Sequential)]
public struct CERT_SIMPLE_CHAIN
{
/// <summary>The size, in bytes, of this structure.</summary>
public uint cbSize;
/// <summary>
/// A structure that indicates the trust status of the whole chain. The structure includes an error status code and an
/// information status code. For information about status code values, see CERT_TRUST_STATUS.
/// </summary>
public CERT_TRUST_STATUS TrustStatus;
/// <summary>The number of CERT_CHAIN_ELEMENT structures in the array.</summary>
public uint cElement;
/// <summary>
/// An array of pointers to CERT_CHAIN_ELEMENT structures. <c>rgpElement</c>[0] is the end certificate chain element.
/// <c>rgpElement</c>[ <c>cElement</c>1] is the self-signed "root" certificate element.
/// </summary>
public IntPtr rgpElement;
/// <summary>
/// A pointer to a CERT_TRUST_LIST_INFO structure that contains a pointer to a certificate trust list (CTL) connecting this
/// chain to a next certificate chain. If the current chain is the final chain, <c>pTrustListInfo</c> is <c>NULL</c>.
/// </summary>
public IntPtr pTrustListInfo;
/// <summary>BOOL. If <c>TRUE</c>, <c>dwRevocationFreshnessTime</c> has been calculated.</summary>
[MarshalAs(UnmanagedType.Bool)] public bool fHasRevocationFreshnessTime;
/// <summary>
/// The age of a certificate revocation list (CRL) in seconds, calculated as the CurrentTime minus the CRL's ThisUpdate time.
/// This values is the largest time across all elements checked.
/// </summary>
public uint dwRevocationFreshnessTime;
/// <summary>Gets the elements from <see cref="rgpElement"/>.</summary>
public unsafe CERT_CHAIN_ELEMENT*[] GetElements()
{
var ret = new CERT_CHAIN_ELEMENT*[(int)cElement];
for (int i = 0; i < cElement; i++)
ret[i] = ((CERT_CHAIN_ELEMENT**)rgpElement)[i];
return ret;
}
}
/// <summary>The <c>CERT_TRUST_LIST_INFO</c> structure that indicates valid usage of a CTL.</summary>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/ns-wincrypt-cert_trust_list_info typedef struct _CERT_TRUST_LIST_INFO
// { DWORD cbSize; PCTL_ENTRY pCtlEntry; PCCTL_CONTEXT pCtlContext; } CERT_TRUST_LIST_INFO, *PCERT_TRUST_LIST_INFO;
[PInvokeData("wincrypt.h", MSDNShortId = "774f5626-9b48-4585-b713-adbf191861cc")]
[StructLayout(LayoutKind.Sequential)]
public struct CERT_TRUST_LIST_INFO
{
/// <summary>Size of this structure in bytes.</summary>
public uint cbSize;
/// <summary>
/// A pointer to a structure that includes a subject identifier, the count of attributes associated with a CTL, and an array of
/// those attributes.
/// </summary>
public IntPtr pCtlEntry;
/// <summary>A pointer to a CTL context.</summary>
public PCCTL_CONTEXT pCtlContext;
}
/// <summary>Provides a handle to an online certificate status protocol (OCSP) response.</summary>
[StructLayout(LayoutKind.Sequential)]
public struct HCERT_SERVER_OCSP_RESPONSE : IHandle
{
private IntPtr handle;
/// <summary>Initializes a new instance of the <see cref="HCERT_SERVER_OCSP_RESPONSE"/> struct.</summary>
/// <param name="preexistingHandle">An <see cref="IntPtr"/> object that represents the pre-existing handle to use.</param>
public HCERT_SERVER_OCSP_RESPONSE(IntPtr preexistingHandle) => handle = preexistingHandle;
/// <summary>Returns an invalid handle by instantiating a <see cref="HCERT_SERVER_OCSP_RESPONSE"/> object with <see cref="IntPtr.Zero"/>.</summary>
public static HCERT_SERVER_OCSP_RESPONSE NULL => new HCERT_SERVER_OCSP_RESPONSE(IntPtr.Zero);
/// <summary>Gets a value indicating whether this instance is a null handle.</summary>
public bool IsNull => handle == IntPtr.Zero;
/// <summary>Performs an explicit conversion from <see cref="HCERT_SERVER_OCSP_RESPONSE"/> to <see cref="IntPtr"/>.</summary>
/// <param name="h">The handle.</param>
/// <returns>The result of the conversion.</returns>
public static explicit operator IntPtr(HCERT_SERVER_OCSP_RESPONSE h) => h.handle;
/// <summary>Performs an implicit conversion from <see cref="IntPtr"/> to <see cref="HCERT_SERVER_OCSP_RESPONSE"/>.</summary>
/// <param name="h">The pointer to a handle.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator HCERT_SERVER_OCSP_RESPONSE(IntPtr h) => new HCERT_SERVER_OCSP_RESPONSE(h);
/// <summary>Implements the operator !=.</summary>
/// <param name="h1">The first handle.</param>
/// <param name="h2">The second handle.</param>
/// <returns>The result of the operator.</returns>
public static bool operator !=(HCERT_SERVER_OCSP_RESPONSE h1, HCERT_SERVER_OCSP_RESPONSE h2) => !(h1 == h2);
/// <summary>Implements the operator ==.</summary>
/// <param name="h1">The first handle.</param>
/// <param name="h2">The second handle.</param>
/// <returns>The result of the operator.</returns>
public static bool operator ==(HCERT_SERVER_OCSP_RESPONSE h1, HCERT_SERVER_OCSP_RESPONSE h2) => h1.Equals(h2);
/// <inheritdoc/>
public override bool Equals(object obj) => obj is HCERT_SERVER_OCSP_RESPONSE h ? handle == h.handle : false;
/// <inheritdoc/>
public override int GetHashCode() => handle.GetHashCode();
/// <inheritdoc/>
public IntPtr DangerousGetHandle() => handle;
}
//public static CERT_SELECT_CRITERIA[] CertSelectCertificateChains(in Guid pSelectionContext, HCERTSTORE hStore, CertSelection dwFlags, [Optional] CERT_SELECT_CHAIN_PARA? pChainParameters, [Optional] CERT_SELECT_CRITERIA[] rgpCriteria)
//{
// unsafe
// {
// var cpdef = pChainParameters.GetValueOrDefault();
// if (!CertSelectCertificateChains(pSelectionContext, dwFlags, pChainParameters.HasValue ? &cpdef : null, rgpCriteria?.Length ?? 0, rgpCriteria, hStore, out var cSelections, out var ppSelections))
// throw new Win32Exception();
// var ret = new CERT_CHAIN_CONTEXT[cSelections];
// for (var i = 0; i < cSelections; i++)
// ret[i] = *ppSelections[i];
// return ret;
// }
//}
//[DllImport(Lib.Crypt32, SetLastError = true, ExactSpelling = true)]
//[return: MarshalAs(UnmanagedType.Bool)]
//private static extern unsafe bool CertSelectCertificateChains(in Guid pSelectionContext, CertSelection dwFlags, [In, Optional] CERT_SELECT_CHAIN_PARA* pChainParameters, int cCriteria,
// [In, Optional, MarshalAs(UnmanagedType.LPArray)] CERT_SELECT_CRITERIA[] rgpCriteria, HCERTSTORE hStore, out int pcSelection, out CERT_CHAIN_CONTEXT*[] pprgpSelection);
/// <summary>Provides a handle to a Certificate Chain Engine.</summary>
[StructLayout(LayoutKind.Sequential)]
public struct HCERTCHAINENGINE : IHandle
{
private IntPtr handle;
/// <summary>Initializes a new instance of the <see cref="HCERTCHAINENGINE"/> struct.</summary>
/// <param name="preexistingHandle">An <see cref="IntPtr"/> object that represents the pre-existing handle to use.</param>
public HCERTCHAINENGINE(IntPtr preexistingHandle) => handle = preexistingHandle;
/// <summary>Returns an invalid handle by instantiating a <see cref="HCERTCHAINENGINE"/> object with <see cref="IntPtr.Zero"/>.</summary>
public static HCERTCHAINENGINE NULL => new HCERTCHAINENGINE(IntPtr.Zero);
/// <summary>Gets a value indicating whether this instance is a null handle.</summary>
public bool IsNull => handle == IntPtr.Zero;
/// <summary>Performs an explicit conversion from <see cref="HCERTCHAINENGINE"/> to <see cref="IntPtr"/>.</summary>
/// <param name="h">The handle.</param>
/// <returns>The result of the conversion.</returns>
public static explicit operator IntPtr(HCERTCHAINENGINE h) => h.handle;
/// <summary>Performs an implicit conversion from <see cref="IntPtr"/> to <see cref="HCERTCHAINENGINE"/>.</summary>
/// <param name="h">The pointer to a handle.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator HCERTCHAINENGINE(IntPtr h) => new HCERTCHAINENGINE(h);
/// <summary>Implements the operator !=.</summary>
/// <param name="h1">The first handle.</param>
/// <param name="h2">The second handle.</param>
/// <returns>The result of the operator.</returns>
public static bool operator !=(HCERTCHAINENGINE h1, HCERTCHAINENGINE h2) => !(h1 == h2);
/// <summary>Implements the operator ==.</summary>
/// <param name="h1">The first handle.</param>
/// <param name="h2">The second handle.</param>
/// <returns>The result of the operator.</returns>
public static bool operator ==(HCERTCHAINENGINE h1, HCERTCHAINENGINE h2) => h1.Equals(h2);
/// <inheritdoc/>
public override bool Equals(object obj) => obj is HCERTCHAINENGINE h ? handle == h.handle : false;
/// <inheritdoc/>
public override int GetHashCode() => handle.GetHashCode();
/// <inheritdoc/>
public IntPtr DangerousGetHandle() => handle;
}
/// <summary>Provides a handle to a CERT_SERVER_OCSP_RESPONSE_CONTEXT.</summary>
[StructLayout(LayoutKind.Sequential)]
public struct PCCERT_SERVER_OCSP_RESPONSE_CONTEXT : IHandle
{
private IntPtr handle;
/// <summary>Initializes a new instance of the <see cref="PCCERT_SERVER_OCSP_RESPONSE_CONTEXT"/> struct.</summary>
/// <param name="preexistingHandle">An <see cref="IntPtr"/> object that represents the pre-existing handle to use.</param>
public PCCERT_SERVER_OCSP_RESPONSE_CONTEXT(IntPtr preexistingHandle) => handle = preexistingHandle;
/// <summary>
/// Returns an invalid handle by instantiating a <see cref="PCCERT_SERVER_OCSP_RESPONSE_CONTEXT"/> object with <see cref="IntPtr.Zero"/>.
/// </summary>
public static PCCERT_SERVER_OCSP_RESPONSE_CONTEXT NULL => new PCCERT_SERVER_OCSP_RESPONSE_CONTEXT(IntPtr.Zero);
/// <summary>Gets a value indicating whether this instance is a null handle.</summary>
public bool IsNull => handle == IntPtr.Zero;
/// <summary>Performs an explicit conversion from <see cref="PCCERT_SERVER_OCSP_RESPONSE_CONTEXT"/> to <see cref="IntPtr"/>.</summary>
/// <param name="h">The handle.</param>
/// <returns>The result of the conversion.</returns>
public static explicit operator IntPtr(PCCERT_SERVER_OCSP_RESPONSE_CONTEXT h) => h.handle;
/// <summary>Performs an implicit conversion from <see cref="IntPtr"/> to <see cref="PCCERT_SERVER_OCSP_RESPONSE_CONTEXT"/>.</summary>
/// <param name="h">The pointer to a handle.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator PCCERT_SERVER_OCSP_RESPONSE_CONTEXT(IntPtr h) => new PCCERT_SERVER_OCSP_RESPONSE_CONTEXT(h);
/// <summary>Implements the operator !=.</summary>
/// <param name="h1">The first handle.</param>
/// <param name="h2">The second handle.</param>
/// <returns>The result of the operator.</returns>
public static bool operator !=(PCCERT_SERVER_OCSP_RESPONSE_CONTEXT h1, PCCERT_SERVER_OCSP_RESPONSE_CONTEXT h2) => !(h1 == h2);
/// <summary>Implements the operator ==.</summary>
/// <param name="h1">The first handle.</param>
/// <param name="h2">The second handle.</param>
/// <returns>The result of the operator.</returns>
public static bool operator ==(PCCERT_SERVER_OCSP_RESPONSE_CONTEXT h1, PCCERT_SERVER_OCSP_RESPONSE_CONTEXT h2) => h1.Equals(h2);
/// <inheritdoc/>
public override bool Equals(object obj) => obj is PCCERT_SERVER_OCSP_RESPONSE_CONTEXT h ? handle == h.handle : false;
/// <inheritdoc/>
public override int GetHashCode() => handle.GetHashCode();
/// <inheritdoc/>
public IntPtr DangerousGetHandle() => handle;
}
/// <summary>Provides a <see cref="SafeHandle"/> for <see cref="PCCERT_CONTEXT"/> that is disposed using <see cref="CertFreeCertificateContext"/>.</summary>
public class SafePCCERT_CONTEXT : SafeHANDLE
{
/// <summary>Represents a NULL handle for <see cref="SafePCCERT_CONTEXT"/>. This must be used instead of <see langword="null"/>.</summary>
public static readonly SafePCCERT_CONTEXT Null = new SafePCCERT_CONTEXT(IntPtr.Zero, false);
/// <summary>Initializes a new instance of the <see cref="SafePCCERT_CONTEXT"/> class and assigns an existing handle.</summary>
/// <param name="preexistingHandle">An <see cref="IntPtr"/> object that represents the pre-existing handle to use.</param>
/// <param name="ownsHandle">
/// <see langword="true"/> to reliably release the handle during the finalization phase; otherwise, <see langword="false"/> (not recommended).
/// </param>
public SafePCCERT_CONTEXT(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { }
/// <summary>Initializes a new instance of the <see cref="SafePCCERT_CONTEXT"/> class.</summary>
private SafePCCERT_CONTEXT() : base() { }
/// <summary>Performs an implicit conversion from <see cref="SafePCCERT_CONTEXT"/> to <see cref="PCCERT_CONTEXT"/>.</summary>
/// <param name="h">The safe handle instance.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator PCCERT_CONTEXT(SafePCCERT_CONTEXT h) => h.handle;
/// <summary>
/// Performs an explicit conversion from <see cref="SafePCCERT_CONTEXT"/> to <see cref="CERT_CONTEXT"/>.
/// </summary>
/// <param name="h">The h.</param>
/// <returns>
/// The resulting <see cref="CERT_CONTEXT"/> instance from the conversion.
/// </returns>
public static unsafe explicit operator CERT_CONTEXT*(SafePCCERT_CONTEXT h) => (CERT_CONTEXT*)(void*)h.handle;
/// <inheritdoc/>
protected override bool InternalReleaseHandle() => CertFreeCertificateContext(handle);
}
/// <summary>
/// Provides a <see cref="SafeHandle"/> for <see cref="PCCERT_SERVER_OCSP_RESPONSE_CONTEXT"/> that is disposed using <see cref="CertFreeServerOcspResponseContext"/>.
/// </summary>
public class SafePCCERT_SERVER_OCSP_RESPONSE_CONTEXT : SafeHANDLE
{
/// <summary>
/// Initializes a new instance of the <see cref="SafePCCERT_SERVER_OCSP_RESPONSE_CONTEXT"/> class and assigns an existing handle.
/// </summary>
/// <param name="preexistingHandle">An <see cref="IntPtr"/> object that represents the pre-existing handle to use.</param>
/// <param name="ownsHandle">
/// <see langword="true"/> to reliably release the handle during the finalization phase; otherwise, <see langword="false"/> (not recommended).
/// </param>
public SafePCCERT_SERVER_OCSP_RESPONSE_CONTEXT(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { }
/// <summary>Initializes a new instance of the <see cref="SafePCCERT_SERVER_OCSP_RESPONSE_CONTEXT"/> class.</summary>
private SafePCCERT_SERVER_OCSP_RESPONSE_CONTEXT() : base() { }
/// <summary>Performs an implicit conversion from <see cref="SafePCCERT_SERVER_OCSP_RESPONSE_CONTEXT"/> to <see cref="PCCERT_SERVER_OCSP_RESPONSE_CONTEXT"/>.</summary>
/// <param name="h">The safe handle instance.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator PCCERT_SERVER_OCSP_RESPONSE_CONTEXT(SafePCCERT_SERVER_OCSP_RESPONSE_CONTEXT h) => h.handle;
/// <inheritdoc/>
protected override bool InternalReleaseHandle() { CertFreeServerOcspResponseContext(handle); return true; }
}
}
}