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

2837 lines
155 KiB
C#
Raw Normal View History

2020-03-09 11:54:19 -04:00
using System;
using System.Runtime.InteropServices;
using Vanara.Extensions;
using Vanara.InteropServices;
2020-03-09 11:54:19 -04:00
using FILETIME = System.Runtime.InteropServices.ComTypes.FILETIME;
namespace Vanara.PInvoke
{
/// <summary>Methods and data types found in Crypt32.dll.</summary>
public static partial class Crypt32
{
/// <summary>Flags used by <see cref="CERT_CHAIN_ENGINE_CONFIG"/>.</summary>
[PInvokeData("wincrypt.h", MSDNShortId = "9e010eb9-2cbb-4fca-ba5c-4a5a50f23786")]
[Flags]
public enum CertChainEngineExclusiveFlags
{
/// <summary>
/// Indicates that a non-self-signed intermediate CA certificate in the hExclusiveRoot store should be treated as a trust anchor
/// during certificate validation. If a certificate chains up to this CA, chain building is terminated and the certificate is
/// considered trusted. No signature verification or revocation checking is performed on the CA certificate.
/// <para>
/// By default, if this flag is not set, only self-signed certificates in the hExclusiveRoot store are treated as trust anchors.
/// </para>
/// <para>See also the CERT_TRUST_IS_CA_TRUSTED value in the CERT_TRUST_STATUS structure.</para>
/// </summary>
CERT_CHAIN_EXCLUSIVE_ENABLE_CA_FLAG = 0x00000001,
}
/// <summary>Flags used by <see cref="CERT_CHAIN_ENGINE_CONFIG"/>.</summary>
[PInvokeData("wincrypt.h", MSDNShortId = "9e010eb9-2cbb-4fca-ba5c-4a5a50f23786")]
[Flags]
public enum CertChainEngineFlags
{
/// <summary>
/// Information in the end certificate is cached. By default, information in all certificates except the end certificate is
/// cached as a chain is built. Setting this flag extends the caching to the end certificate.
/// </summary>
CERT_CHAIN_CACHE_END_CERT = 0x00000001,
/// <summary/>
CERT_CHAIN_THREAD_STORE_SYNC = 0x00000002,
/// <summary>
/// Use only cached URLs in building a certificate chain. The Internet and intranet are not searched for URL-based objects.
/// </summary>
CERT_CHAIN_CACHE_ONLY_URL_RETRIEVAL = 0x00000004,
/// <summary>Build the chain using the LocalMachine registry location as opposed to the CurrentUser location.</summary>
CERT_CHAIN_USE_LOCAL_MACHINE_STORE = 0x00000008,
/// <summary>Enable automatic updating of the cache as a chain is being built.</summary>
CERT_CHAIN_ENABLE_CACHE_AUTO_UPDATE = 0x00000010,
/// <summary>Allow certificate stores used to build the chain to be shared.</summary>
CERT_CHAIN_ENABLE_SHARE_STORE = 0x00000020,
/// <summary>Turn off Authority Information Access (AIA) retrievals explicitly.</summary>
CERT_CHAIN_DISABLE_AIA = 0x00002000,
}
2020-03-09 12:53:39 -04:00
/// <summary>Flags used by <see cref="CertGetCertificateChain(HCERTCHAINENGINE, PCCERT_CONTEXT, in FILETIME, HCERTSTORE, in CERT_CHAIN_PARA, CertChainFlags, IntPtr, out SafePCCERT_CHAIN_CONTEXT)"/>.</summary>
2020-03-09 11:54:19 -04:00
[PInvokeData("wincrypt.h", MSDNShortId = "8c93036c-0b93-40d4-b0e3-ba1f2fc72db1")]
[Flags]
public enum CertChainFlags : uint
{
/// <summary>
/// When this flag is set, the end certificate is cached, which might speed up the chain-building process. By default, the end
/// certificate is not cached, and it would need to be verified each time a chain is built for it.
/// </summary>
CERT_CHAIN_CACHE_END_CERT = 0x00000001,
/// <summary>Revocation checking only accesses cached URLs.</summary>
CERT_CHAIN_REVOCATION_CHECK_CACHE_ONLY = 0x80000000,
/// <summary>
/// This flag is used internally during chain building for an online certificate status protocol (OCSP) signer certificate to
/// prevent cyclic revocation checks. During chain building, if the OCSP response is signed by an independent OCSP signer, then,
/// in addition to the original chain build, there is a second chain built for the OCSP signer certificate itself. This flag is
/// used during this second chain build to inhibit a recursive independent OCSP signer certificate. If the signer certificate
/// contains the szOID_PKIX_OCSP_NOCHECK extension, revocation checking is skipped for the leaf signer certificate. Both OCSP
/// and CRL checking are allowed.
/// <para>Windows Server 2003 and Windows XP: This value is not supported.</para>
/// </summary>
CERT_CHAIN_REVOCATION_CHECK_OCSP_CERT = 0x04000000,
/// <summary>
/// Uses only cached URLs in building a certificate chain. The Internet and intranet are not searched for URL-based objects.
/// <para>
/// Note This flag is not applicable to revocation checking. Set CERT_CHAIN_REVOCATION_CHECK_CACHE_ONLY to use only cached URLs
/// for revocation checking.
/// </para>
/// </summary>
CERT_CHAIN_CACHE_ONLY_URL_RETRIEVAL = 0x00000004,
/// <summary>
/// For performance reasons, the second pass of chain building only considers potential chain paths that have quality greater
/// than or equal to the highest quality determined during the first pass. The first pass only considers valid signature,
/// complete chain, and trusted roots to calculate chain quality. This flag can be set to disable this optimization and consider
/// all potential chain paths during the second pass.
/// </summary>
CERT_CHAIN_DISABLE_PASS1_QUALITY_FILTERING = 0x00000040,
/// <summary>This flag is not supported. Certificates in the "My" store are never considered for peer trust.</summary>
CERT_CHAIN_DISABLE_MY_PEER_TRUST = 0x00000800,
/// <summary>
/// End entity certificates in the "TrustedPeople" store are trusted without performing any chain building. This function does
/// not set the CERT_TRUST_IS_PARTIAL_CHAIN or CERT_TRUST_IS_UNTRUSTED_ROOT dwErrorStatus member bits of the ppChainContext
/// parameter. Windows Server 2003 Windows XP : This flag is not supported.
/// </summary>
CERT_CHAIN_ENABLE_PEER_TRUST = 0x00000400,
/// <summary>
/// Setting this flag indicates the caller wishes to opt into weak signature checks.
/// <para>This flag is available in the rollup update for each OS starting with Windows 7 and Windows Server 2008 R2.</para>
/// </summary>
CERT_CHAIN_OPT_IN_WEAK_SIGNATURE = 0x00010000,
/// <summary>
/// The default is to return only the highest quality chain path. Setting this flag will return the lower quality chains. These
/// are returned in the cLowerQualityChainContext and rgpLowerQualityChainContext fields of the chain context.
/// </summary>
CERT_CHAIN_RETURN_LOWER_QUALITY_CONTEXTS = 0x00000080,
/// <summary>Setting this flag inhibits the auto update of third-party roots from the Windows Update Web Server.</summary>
CERT_CHAIN_DISABLE_AUTH_ROOT_AUTO_UPDATE = 0x00000100,
/// <summary>
/// When you set CERT_CHAIN_REVOCATION_ACCUMULATIVE_TIMEOUT and you also specify a value for the dwUrlRetrievalTimeout member of
/// the CERT_CHAIN_PARA structure, the value you specify in dwUrlRetrievalTimeout represents the cumulative timeout across all
/// revocation URL retrievals.
/// <para>
/// If you set CERT_CHAIN_REVOCATION_ACCUMULATIVE_TIMEOUT but do not specify a dwUrlRetrievalTimeout value, the maximum
/// cumulative timeout is set, by default, to 20 seconds. Each URL tested will timeout after half of the remaining cumulative
/// balance has passed. That is, the first URL times out after 10 seconds, the second after 5 seconds, the third after 2.5
/// seconds and so on until a URL succeeds, 20 seconds has passed, or there are no more URLs to test.
/// </para>
/// <para>
/// If you do not set CERT_CHAIN_REVOCATION_ACCUMULATIVE_TIMEOUT, each revocation URL in the chain is assigned a maximum timeout
/// equal to the value specified in dwUrlRetrievalTimeout. If you do not specify a value for the dwUrlRetrievalTimeout member,
/// each revocation URL is assigned a maximum default timeout of 15 seconds. If no URL succeeds, the maximum cumulative timeout
/// value is 15 seconds multiplied by the number of URLs in the chain.
/// </para>
/// <para>You can set the default values by using Group Policy.</para>
/// </summary>
CERT_CHAIN_REVOCATION_ACCUMULATIVE_TIMEOUT = 0x08000000,
/// <summary>
/// When this flag is set, pTime is used as the time stamp time to determine whether the end certificate was time valid. Current
/// time can also be used to determine whether the end certificate remains time valid. All other certification authority (CA)
/// and root certificates in the chain are checked by using current time and not pTime.
/// </summary>
CERT_CHAIN_TIMESTAMP_TIME = 0x00000200,
/// <summary>Setting this flag explicitly turns off Authority Information Access (AIA) retrievals.</summary>
CERT_CHAIN_DISABLE_AIA = 0x00002000,
/// <summary>Revocation checking is done on the end certificate and only the end certificate.</summary>
CERT_CHAIN_REVOCATION_CHECK_END_CERT = 0x10000000,
/// <summary>Revocation checking is done on all of the certificates in every chain.</summary>
CERT_CHAIN_REVOCATION_CHECK_CHAIN = 0x20000000,
/// <summary>Revocation checking is done on all certificates in all of the chains except the root certificate.</summary>
CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT = 0x40000000,
2020-03-09 11:54:19 -04:00
}
/// <summary>Flags used by <see cref="CERT_CHAIN_POLICY_PARA"/></summary>
[PInvokeData("wincrypt.h", MSDNShortId = "5e4fffcb-132b-42c0-81b2-9f866e274c32")]
[Flags]
public enum CertChainPolicyFlags : uint
{
/// <summary>Ignore not time valid errors.</summary>
CERT_CHAIN_POLICY_IGNORE_NOT_TIME_VALID_FLAG = 0x00000001,
/// <summary>Ignore certificate trust list (CTL) not time valid errors.</summary>
CERT_CHAIN_POLICY_IGNORE_CTL_NOT_TIME_VALID_FLAG = 0x00000002,
/// <summary>Ignore time nesting errors.</summary>
CERT_CHAIN_POLICY_IGNORE_NOT_TIME_NESTED_FLAG = 0x00000004,
/// <summary>Ignore basic constraint errors.</summary>
CERT_CHAIN_POLICY_IGNORE_INVALID_BASIC_CONSTRAINTS_FLAG = 0x00000008,
/// <summary>Ignore all time validity errors.</summary>
CERT_CHAIN_POLICY_IGNORE_ALL_NOT_TIME_VALID_FLAGS = (CERT_CHAIN_POLICY_IGNORE_NOT_TIME_VALID_FLAG | CERT_CHAIN_POLICY_IGNORE_CTL_NOT_TIME_VALID_FLAG | CERT_CHAIN_POLICY_IGNORE_NOT_TIME_NESTED_FLAG),
/// <summary>Allow untrusted roots.</summary>
CERT_CHAIN_POLICY_ALLOW_UNKNOWN_CA_FLAG = 0x00000010,
/// <summary>Ignore invalid usage errors.</summary>
CERT_CHAIN_POLICY_IGNORE_WRONG_USAGE_FLAG = 0x00000020,
/// <summary>Ignore invalid name errors.</summary>
CERT_CHAIN_POLICY_IGNORE_INVALID_NAME_FLAG = 0x00000040,
/// <summary>Ignore invalid policy errors.</summary>
CERT_CHAIN_POLICY_IGNORE_INVALID_POLICY_FLAG = 0x00000080,
/// <summary>Ignores errors in obtaining valid revocation information.</summary>
CERT_CHAIN_POLICY_IGNORE_END_REV_UNKNOWN_FLAG = 0x00000100,
/// <summary>Ignores errors in obtaining valid CTL revocation information.</summary>
CERT_CHAIN_POLICY_IGNORE_CTL_SIGNER_REV_UNKNOWN_FLAG = 0x00000200,
/// <summary>Ignores errors in obtaining valid certification authority (CA) revocation information.</summary>
CERT_CHAIN_POLICY_IGNORE_CA_REV_UNKNOWN_FLAG = 0x00000400,
/// <summary>Ignores errors in obtaining valid root revocation information.</summary>
CERT_CHAIN_POLICY_IGNORE_ROOT_REV_UNKNOWN_FLAG = 0x00000800,
/// <summary>Ignores errors in obtaining valid revocation information.</summary>
CERT_CHAIN_POLICY_IGNORE_ALL_REV_UNKNOWN_FLAGS = (CERT_CHAIN_POLICY_IGNORE_END_REV_UNKNOWN_FLAG | CERT_CHAIN_POLICY_IGNORE_CTL_SIGNER_REV_UNKNOWN_FLAG | CERT_CHAIN_POLICY_IGNORE_CA_REV_UNKNOWN_FLAG | CERT_CHAIN_POLICY_IGNORE_ROOT_REV_UNKNOWN_FLAG),
/// <summary>Allow untrusted test roots.</summary>
CERT_CHAIN_POLICY_ALLOW_TESTROOT_FLAG = 0x00008000,
/// <summary>Always trust test roots.</summary>
CERT_CHAIN_POLICY_TRUST_TESTROOT_FLAG = 0x00004000,
/// <summary>Ignore critical extension not supported errors.</summary>
CERT_CHAIN_POLICY_IGNORE_NOT_SUPPORTED_CRITICAL_EXT_FLAG = 0x00002000,
/// <summary>Ignore peer trusts.</summary>
CERT_CHAIN_POLICY_IGNORE_PEER_TRUST_FLAG = 0x00001000,
/// <summary/>
CERT_CHAIN_POLICY_IGNORE_WEAK_SIGNATURE_FLAG = 0x08000000,
/// <summary>Checks if the first certificate element is a CA.</summary>
BASIC_CONSTRAINTS_CERT_CHAIN_POLICY_CA_FLAG = 0x80000000,
/// <summary>Checks if the first certificate element is an end entity.</summary>
BASIC_CONSTRAINTS_CERT_CHAIN_POLICY_END_ENTITY_FLAG = 0x40000000,
/// <summary>Also check for the Microsoft test roots in addition to the Microsoft public root.</summary>
MICROSOFT_ROOT_CERT_CHAIN_POLICY_ENABLE_TEST_ROOT_FLAG = 0x00010000,
/// <summary/>
MICROSOFT_ROOT_CERT_CHAIN_POLICY_CHECK_APPLICATION_ROOT_FLAG = 0x00020000,
/// <summary/>
MICROSOFT_ROOT_CERT_CHAIN_POLICY_DISABLE_FLIGHT_ROOT_FLAG = 0x00040000,
}
/// <summary>Optional flags that modify chain retrieval behavior.</summary>
[PInvokeData("wincrypt.h", MSDNShortId = "86094e1c-be59-4a15-a05b-21769f80e653")]
[Flags]
public enum CertChainStrongSignFlags
{
/// <summary>
/// If the chain is strong signed, the public key in the end certificate will be checked to verify whether it satisfies the
/// minimum public key length requirements for a strong signature. You can specify CERT_CHAIN_STRONG_SIGN_DISABLE_END_CHECK_FLAG
/// to disable default checking.
/// </summary>
CERT_CHAIN_STRONG_SIGN_DISABLE_END_CHECK_FLAG = 0x00000001,
}
/// <summary>Flags used by <see cref="CertCreateCTLEntryFromCertificateContextProperties"/>.</summary>
[PInvokeData("wincrypt.h", MSDNShortId = "90ac512f-3cbe-4543-9b34-8e384f730cfe")]
[Flags]
public enum CertCreateCTLEntryFlags
{
/// <summary>Force the inclusion of the chain building hash properties as attributes.</summary>
CTL_ENTRY_FROM_PROP_CHAIN_FLAG = 1
}
/// <summary>Flags for CertVerifyCTLUsage.</summary>
[PInvokeData("wincrypt.h", MSDNShortId = "d87d8157-8e52-4198-bfd4-46d83d72eb13")]
[Flags]
public enum CertVerifyCTLFlags
{
/// <summary>
/// If the CERT_VERIFY_INHIBIT_CTL_UPDATE_FLAG is not set, a CTL whose time is no longer valid in one of the stores specified by
/// rghCtlStore in CTL_VERIFY_USAGE_PARA can be replaced. When replaced, the CERT_VERIFY_UPDATED_CTL_FLAG is set in the dwFlags
/// member of pVerifyUsageStatus. If this flag is set, an update will not be made, even if a time-valid, updated CTL is received
/// for a CTL that is in the store and whose time is no longer valid.
/// </summary>
CERT_VERIFY_INHIBIT_CTL_UPDATE_FLAG = 0x1,
/// <summary>
/// If the CERT_VERIFY_TRUSTED_SIGNERS_FLAG is set, only the signer stores specified by rghSignerStore in CTL_VERIFY_USAGE_PARA
/// are searched to find the signer. Otherwise, the signer stores provide additional sources to find the signer's certificate.
/// </summary>
CERT_VERIFY_TRUSTED_SIGNERS_FLAG = 0x2,
/// <summary>If CERT_VERIFY_NO_TIME_CHECK_FLAG is set, the CTLs are not checked for time validity. Otherwise, they are.</summary>
CERT_VERIFY_NO_TIME_CHECK_FLAG = 0x4,
/// <summary>
/// If CERT_VERIFY_ALLOW_MORE_USAGE_FLAG is set, the CTL can contain usage identifiers in addition to those specified by
/// pSubjectUsage. Otherwise, the found CTL will contain no additional usage identifiers.
/// </summary>
CERT_VERIFY_ALLOW_MORE_USAGE_FLAG = 0x8,
}
/// <summary>Flags used by <see cref="CryptMsgEncodeAndSignCTL"/>.</summary>
[PInvokeData("wincrypt.h", MSDNShortId = "5c0e9e2e-a50d-45d0-b51d-065784d1d912")]
[Flags]
public enum CryptMsgEncodeFlags
{
/// <summary>
/// Set if the CTL entries are to be sorted before encoding. This flag is set if the CertFindSubjectInSortedCTL or
/// CertEnumSubjectInSortedCTL functions will be called.
/// </summary>
CMSG_ENCODE_SORTED_CTL_FLAG = 0x1,
/// <summary>
/// Set if CMSG_ENCODE_SORTED_CTL_FLAG is set, and the identifier for the TrustedSubjects is a hash, such as MD5 or SHA1.
/// </summary>
CMSG_ENCODE_HASHED_SUBJECT_IDENTIFIER_FLAG = 0x2,
}
/// <summary>Flags for <see cref="CryptMsgGetAndVerifySigner"/>.</summary>
[PInvokeData("wincrypt.h", MSDNShortId = "380c9cf3-27a2-4354-b1c8-97cec33f4e44")]
[Flags]
public enum CryptMsgSignerFlags
{
/// <summary>
/// The stores in rghSignerStore are assumed trusted and they are the only stores searched to find the certificate corresponding
/// to the signer's issuer and serial number. Otherwise, signer stores can be provided to supplement the message's store of
/// certificates. If a signer certificate is found, its public key is used to verify the message signature.
/// </summary>
CMSG_TRUSTED_SIGNER_FLAG = 0x1,
/// <summary>Return the signer without doing the signature verification.</summary>
CMSG_SIGNER_ONLY_FLAG = 0x2,
/// <summary>
/// Only the signer specified by *pdwSignerIndex is returned. Otherwise, iterate through all the signers until a signature is
/// verified or there are no more signers.
/// </summary>
CMSG_USE_SIGNER_INDEX_FLAG = 0x4,
}
/// <summary>Flags for <see cref="CryptMsgSignCTL"/>.</summary>
[PInvokeData("wincrypt.h", MSDNShortId = "85ae8ce3-d0a7-4fcb-beaa-ede09d30930e")]
[Flags]
public enum CryptMsgSignFlags
{
/// <summary>
/// If CMS_PKCS7 is defined, can be set to CMSG_CMS_ENCAPSULATED_CTL_FLAG to encode a CMS compatible V3 SignedData message.
/// </summary>
CMSG_CMS_ENCAPSULATED_CTL_FLAG = 0x00008000
}
/// <summary>Flags returned in CTL_VERIFY_USAGE_STATUS.</summary>
[PInvokeData("wincrypt.h", MSDNShortId = "2b7ef953-9422-4dcf-b293-a78a06bb080e")]
[Flags]
public enum CtlVerifyUsageStatusFlags
{
/// <summary>CertVerifyCTLUsage updated a CTL whose time was no longer valid with a new, time-valid CTL.</summary>
CERT_VERIFY_UPDATED_CTL_FLAG = 0x1
}
/// <summary>
/// Determines the kind of issuer matching to be done. In <c>AND</c> logic, the certificate must meet all criteria. In <c>OR</c>
/// logic, the certificate must meet at least one of the criteria.
/// </summary>
[PInvokeData("wincrypt.h", MSDNShortId = "6154f1f7-4293-4b8e-91ab-9f57bb6f5743")]
public enum UsageMatchType
{
/// <summary>AND logic</summary>
USAGE_MATCH_TYPE_AND = 0x00000000,
/// <summary>OR logic</summary>
USAGE_MATCH_TYPE_OR = 0x00000001,
}
/// <summary>
/// The <c>CertCreateCertificateChainEngine</c> function creates a new, nondefault chain engine for an application. A chain engine
/// restricts the certificates in the root store that can be used for verification, restricts the certificate stores to be searched
/// for certificates and certificate trust lists (CTLs), sets a time-out limit for searches that involve URLs, and limits the number
/// of certificates checked between checking for a certificate cycle.
/// </summary>
/// <param name="pConfig">A pointer to a CERT_CHAIN_ENGINE_CONFIG data structure that specifies the parameters for the chain engine.</param>
/// <param name="phChainEngine">
/// A pointer to the handle of the chain engine created. When you have finished using the chain engine, release the chain engine by
/// calling the CertFreeCertificateChainEngine function.
/// </param>
/// <returns>
/// <para>If the function succeeds, the function returns nonzero ( <c>TRUE</c>).</para>
/// <para>If the function fails, it returns zero ( <c>FALSE</c>). For extended error information, call GetLastError.</para>
/// <para>The phChainEngine parameter returns the chain engine handle.</para>
/// </returns>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-certcreatecertificatechainengine BOOL
// CertCreateCertificateChainEngine( PCERT_CHAIN_ENGINE_CONFIG pConfig, HCERTCHAINENGINE *phChainEngine );
[DllImport(Lib.Crypt32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "e173016a-d3d7-42e0-aad8-e738abaf1df9")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CertCreateCertificateChainEngine(in CERT_CHAIN_ENGINE_CONFIG pConfig, out SafeHCERTCHAINENGINE phChainEngine);
/// <summary>
/// <para>
/// The <c>CertCreateCTLEntryFromCertificateContextProperties</c> function creates a certificate trust list (CTL) entry whose
/// attributes are the properties of the certificate context. The SubjectIdentifier in the CTL entry is the SHA1 hash of the certificate.
/// </para>
/// <para>
/// The certificate properties are added as attributes. The property attribute OID is the decimal PROP_ID preceded by
/// szOID_CERT_PROP_ID_PREFIX. Each property value is copied as a single attribute value.
/// </para>
/// <para>Additional attributes can be included in the CTL entry by using the cOptAttr and rgOptAttr parameters.</para>
/// </summary>
/// <param name="pCertContext">A pointer to the CERT_CONTEXT used to create the CTL.</param>
/// <param name="cOptAttr">A <c>DWORD</c> that specifies the number of additional attributes to be added.</param>
/// <param name="rgOptAttr">A pointer to any array of CRYPT_ATTRIBUTE attributes to be added to the CTL.</param>
/// <param name="dwFlags">
/// A <c>DWORD</c>. Can be set to CTL_ENTRY_FROM_PROP_CHAIN_FLAG to force the inclusion of the chain building hash properties as attributes.
/// </param>
/// <param name="pvReserved">A pointer to a <c>VOID</c>. Reserved for future use.</param>
/// <param name="pCtlEntry">
/// Address of a pointer to a CTL_ENTRY structure. Call this function twice to retrieve a CTL entry. Set this parameter to
/// <c>NULL</c> on the first call. When the function returns, use the number of bytes retrieved from the pcbCtlEntry parameter to
/// allocate memory. Call the function again, setting this parameter to the address of the allocated memory.
/// </param>
/// <param name="pcbCtlEntry">
/// Pointer to a <c>DWORD</c> that contains the number of bytes that must be allocated for the CTL_ENTRY structure. Call this
/// function twice to retrieve the number of bytes. For the first call, set this parameter to the address of a <c>DWORD</c> value
/// that contains zero and set the pCtlEntry parameter to <c>NULL</c>. If the first call succeeds, the <c>DWORD</c> value will
/// contain the number of bytes that you must allocate for the <c>CTL_ENTRY</c> structure. Allocate the required memory and call the
/// function again, supplying the address of the memory in the pCtlEntry parameter.
/// </param>
/// <returns>
/// <para>If the function succeeds, the function returns nonzero ( <c>TRUE</c>).</para>
/// <para>If the function fails, it returns zero ( <c>FALSE</c>). For extended error information, call GetLastError.</para>
/// </returns>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-certcreatectlentryfromcertificatecontextproperties BOOL
// CertCreateCTLEntryFromCertificateContextProperties( PCCERT_CONTEXT pCertContext, DWORD cOptAttr, PCRYPT_ATTRIBUTE rgOptAttr,
// DWORD dwFlags, void *pvReserved, PCTL_ENTRY pCtlEntry, DWORD *pcbCtlEntry );
[DllImport(Lib.Crypt32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "90ac512f-3cbe-4543-9b34-8e384f730cfe")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CertCreateCTLEntryFromCertificateContextProperties([In] PCCERT_CONTEXT pCertContext, uint cOptAttr, [In, MarshalAs(UnmanagedType.LPArray)] CRYPT_ATTRIBUTE[] rgOptAttr,
CertCreateCTLEntryFlags dwFlags, [Optional] IntPtr pvReserved, [Out] IntPtr pCtlEntry, ref uint pcbCtlEntry);
/// <summary>
/// The <c>CertDuplicateCertificateChain</c> function duplicates a pointer to a certificate chain by incrementing the chain's
/// reference count.
/// </summary>
/// <param name="pChainContext">A pointer to a CERT_CHAIN_CONTEXT chain context to be duplicated.</param>
/// <returns>
/// <para>
/// If the function succeeds, a pointer is returned to the chain context. This pointer has the same value as the pChainContext
/// passed into the function. When you have finished using the chain context, release the chain context by calling the
/// CertFreeCertificateChain function.
/// </para>
/// <para>If the function fails, <c>NULL</c> is returned.</para>
/// </returns>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-certduplicatecertificatechain PCCERT_CHAIN_CONTEXT
// CertDuplicateCertificateChain( PCCERT_CHAIN_CONTEXT pChainContext );
[DllImport(Lib.Crypt32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "fea72a3e-5a22-47c7-8f6e-0d76fc3339f8")]
public static extern PCCERT_CHAIN_CONTEXT CertDuplicateCertificateChain(PCCERT_CHAIN_CONTEXT pChainContext);
/// <summary>
/// The <c>CertFindChainInStore</c> function finds the first or next certificate in a store that meets the specified criteria. It
/// then builds and verifies a certificate chain context for that certificate. The certificate that is found and for which the chain
/// is built is selected according to criteria established by the dwFindFlags, dwFindType, and pvFindPara parameters. This function
/// can be used in a loop to find all of the certificates in a certificate store that match the specified find criteria and to build
/// a certificate chain context for each certificate found.
/// </summary>
/// <param name="hCertStore">
/// The handle of the store to be searched for a certificate upon which a chain is built. This handle is passed as an additional
/// store to the CertGetCertificateChain function as the chain is built.
/// </param>
/// <param name="dwCertEncodingType">
/// <para>
/// The certificate encoding type that was used to encode the store. The message encoding type identifier, contained in the high
/// <c>WORD</c> of this value, is ignored by this function.
/// </para>
/// <para>This parameter can be the following currently defined certificate encoding type.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>X509_ASN_ENCODING 1 (0x1)</term>
/// <term>Specifies X.509 certificate encoding.</term>
/// </item>
/// </list>
/// </param>
/// <param name="dwFindFlags">
/// <para>
/// Contains additional options for the search. The possible values for this parameter depend on the value of the dwFindType parameter.
/// </para>
/// <para>This parameter can contain zero or a combination of one or more of the following values when dwFindType contains <c>CERT_CHAIN_FIND_BY_ISSUER</c>.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>CERT_CHAIN_FIND_BY_ISSUER_COMPARE_KEY_FLAG</term>
/// <term>
/// Compares the public key in the certificate with the cryptographic service provider's public key. This comparison is the last
/// check made on the chain when it is built. Because the hCryptProv member of an issuer contains a private key, it might need to be
/// checked several times during this process; to facilitate this checking, the dwAcquirePrivateKeyFlags member can be set in the
/// CERT_CHAIN_FIND_BY_ISSUER_PARA structure to enable caching of that hCryptProv.
/// </term>
/// </item>
/// <item>
/// <term>CERT_CHAIN_FIND_BY_ISSUER_COMPLEX_CHAIN_FLAG</term>
/// <term>
/// By default, only the first simple chain is checked for issuer name matches. With this flag set, the default is overridden and
/// subsequent simple chains are also checked for issuer name matches.
/// </term>
/// </item>
/// <item>
/// <term>CERT_CHAIN_FIND_BY_ISSUER_CACHE_ONLY_FLAG</term>
/// <term>
/// Improves the performance of this function by causing it to search only the cached system stores (Root, My, Ca, Trust) to find
/// issuer certificates. If this flag is not set, the function searches the cached system stores and the store represented by the
/// hCertStore parameter.
/// </term>
/// </item>
/// <item>
/// <term>CERT_CHAIN_FIND_BY_ISSUER_CACHE_ONLY_URL_FLAG</term>
/// <term>Only the URL cache is searched. The Internet is not searched.</term>
/// </item>
/// <item>
/// <term>CERT_CHAIN_FIND_BY_ISSUER_LOCAL_MACHINE_FLAG</term>
/// <term>Only opens the Local Machine certificate stores. The certificate stores of the current user are not opened.</term>
/// </item>
/// <item>
/// <term>CERT_CHAIN_FIND_BY_ISSUER_NO_KEY_FLAG</term>
/// <term>No check is made to determine whether the certificate has an associated private key.</term>
/// </item>
/// </list>
/// </param>
/// <param name="dwFindType">
/// <para>Determines what criteria to use to find a certificate in the store.</para>
/// <para>This parameter can be the following currently defined value.</para>
/// <para>CERT_CHAIN_FIND_BY_ISSUER</para>
/// <para>
/// Finds the certificate based on the name of the issuer. The pvFindPara parameter is a pointer to a CERT_CHAIN_FIND_BY_ISSUER_PARA
/// structure that contains members that modify the search.
/// </para>
/// <para>
/// The certificate chain is built for a certificate with an available private key. By default, only the issuers in the first simple
/// chain are compared in an issuer name match. If this flag is set, all of the chains are checked for an issuer certificate that
/// matches one of a set of issuer names.
/// </para>
/// <para>
/// This function will compare the name BLOBs passed in the pvFindPara structure to any certification authority (CA) in the chain,
/// not just the certification authority in the root certificate.
/// </para>
/// <para>This function does not perform any revocation checks.</para>
/// <para>
/// If pPrevChainContext is not <c>NULL</c>, this function will return a chain for a different certificate every time the function
/// is called. If there is only one suitable certificate, but there are two matching issuing certificate authorities, one of which
/// is revoked, it is possible for this function to return the revoked chain. If the application then checks for revocation itself
/// through calls to the CertVerifyRevocation function and finds the chain unsuitable, an additional call to the
/// <c>CertFindChainInStore</c> function will not return a chain that includes the same certificate from the valid certification
/// authority. It will instead return a completely different chain with a different certificate or <c>NULL</c>, if no such chain can
/// be found.
/// </para>
/// </param>
/// <param name="pvFindPara">
/// A pointer that contains additional search criteria. The type and format of the data this parameter points to depends on the
/// value of the dwFindType parameter.
/// </param>
/// <param name="pPrevChainContext">
/// A pointer to a CERT_CHAIN_CONTEXT structure returned from a previous call to this function. The search is begun from this
/// certificate. For the first call to this function, this parameter must be <c>NULL</c>. In subsequent calls, it is the pointer
/// returned by the previous call to the function. If this parameter is not <c>NULL</c>, this function will free this structure.
/// </param>
/// <returns>
/// If the first or next chain context is not built, <c>NULL</c> is returned. Otherwise, a pointer to a read-only CERT_CHAIN_CONTEXT
/// structure is returned. The <c>CERT_CHAIN_CONTEXT</c> structure is freed when passed as the pPrevChainContext parameter on a
/// subsequent call to this function. Otherwise, the <c>CERT_CHAIN_CONTEXT</c> structure must be freed explicitly by calling the
/// CertFreeCertificateChain function.
/// </returns>
/// <remarks>
/// The pPrevChainContext parameter must be <c>NULL</c> on the first call to build the chain context. To build the next chain
/// context, the pPrevChainContext is set to the CERT_CHAIN_CONTEXT structure returned by a previous call. If pPrevChainContext is
/// not <c>NULL</c>, the structure is always freed by this function by using the CertFreeCertificateChain function, even if an error occurs.
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-certfindchaininstore PCCERT_CHAIN_CONTEXT
// CertFindChainInStore( HCERTSTORE hCertStore, DWORD dwCertEncodingType, DWORD dwFindFlags, DWORD dwFindType, const void
// *pvFindPara, PCCERT_CHAIN_CONTEXT pPrevChainContext );
[DllImport(Lib.Crypt32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "698cece8-71a8-4bfa-8ee6-8035a6dcbe05")]
public static extern SafePCCERT_CHAIN_CONTEXT CertFindChainInStore(HCERTSTORE hCertStore, uint dwCertEncodingType, uint dwFindFlags, uint dwFindType, IntPtr pvFindPara, PCCERT_CHAIN_CONTEXT pPrevChainContext);
/// <summary>
/// <para>
/// The <c>CertFreeCertificateChain</c> function frees a certificate chain by reducing its reference count. If the reference count
/// becomes zero, memory allocated for the chain is released.
/// </para>
/// <para>
/// To free a context obtained by a get, duplicate, or create function, call the appropriate free function. To free a context
/// obtained by a find or enumerate function, either pass it in as the previous context parameter to a subsequent invocation of the
/// function, or call the appropriate free function. For more information, see the reference topic for the function that obtains the context.
/// </para>
/// </summary>
/// <param name="pChainContext">
/// A pointer to a CERT_CHAIN_CONTEXT certificate chain context to be freed. If the reference count on the context reaches zero, the
/// storage allocated for the context is freed.
/// </param>
/// <returns>This function does not return a value.</returns>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-certfreecertificatechain void CertFreeCertificateChain(
// PCCERT_CHAIN_CONTEXT pChainContext );
[DllImport(Lib.Crypt32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "5ba181c2-6936-4848-a571-2bb58f46f081")]
public static extern void CertFreeCertificateChain(PCCERT_CHAIN_CONTEXT pChainContext);
/// <summary>The <c>CertFreeCertificateChainEngine</c> function frees a certificate trust engine.</summary>
/// <param name="hChainEngine">Handle of the chain engine to be freed.</param>
/// <returns>This function does not return a value.</returns>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-certfreecertificatechainengine void
// CertFreeCertificateChainEngine( HCERTCHAINENGINE hChainEngine );
[DllImport(Lib.Crypt32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "5aebc09d-342d-4938-8a1a-0cbfdc147bb5")]
public static extern void CertFreeCertificateChainEngine(HCERTCHAINENGINE hChainEngine);
/// <summary>The <c>CertFreeCertificateChainList</c> function frees the array of pointers to chain contexts.</summary>
/// <param name="prgpSelection">A pointer to a PCCERT_CHAIN_CONTEXT structure returned by the CertSelectCertificateChains function.</param>
/// <returns>This function does not return a value.</returns>
/// <remarks>
/// Before calling the <c>CertFreeCertificateChainList</c> function, you must call the CertFreeCertificateChain function on each
/// chain context within the array pointed to by the prgpSelection parameter.
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-certfreecertificatechainlist void
// CertFreeCertificateChainList( PCCERT_CHAIN_CONTEXT *prgpSelection );
[DllImport(Lib.Crypt32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "a53b02ca-bc3f-43fd-8c90-2f646d550182")]
public static extern void CertFreeCertificateChainList(in IntPtr prgpSelection);
/// <summary>
/// The <c>CertGetCertificateChain</c> function builds a certificate chain context starting from an end certificate and going back,
/// if possible, to a trusted root certificate.
/// </summary>
/// <param name="hChainEngine">
/// A handle of the chain engine (namespace and cache) to be used. If hChainEngine is <c>NULL</c>, the default chain engine,
/// HCCE_CURRENT_USER, is used. This parameter can be set to HCCE_LOCAL_MACHINE.
/// </param>
/// <param name="pCertContext">
/// A pointer to the CERT_CONTEXT of the end certificate, the certificate for which a chain is being built. This certificate context
/// will be the zero-index element in the first simple chain.
/// </param>
/// <param name="pTime">
/// A pointer to a FILETIME variable that indicates the time for which the chain is to be validated. Note that the time does not
/// affect trust list, revocation, or root store checking. The current system time is used if <c>NULL</c> is passed to this
/// parameter. 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.
/// </param>
/// <param name="hAdditionalStore">
/// A handle to 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.
/// </param>
/// <param name="pChainPara">A pointer to a CERT_CHAIN_PARA structure that includes chain-building parameters.</param>
/// <param name="dwFlags">
/// <para>Flag values that indicate special processing. This parameter can be a combination of one or more of the following flags.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>CERT_CHAIN_CACHE_END_CERT 0x00000001</term>
/// <term>
/// When this flag is set, the end certificate is cached, which might speed up the chain-building process. By default, the end
/// certificate is not cached, and it would need to be verified each time a chain is built for it.
/// </term>
/// </item>
/// <item>
/// <term>CERT_CHAIN_REVOCATION_CHECK_CACHE_ONLY 0x80000000</term>
/// <term>Revocation checking only accesses cached URLs.</term>
/// </item>
/// <item>
/// <term>CERT_CHAIN_REVOCATION_CHECK_OCSP_CERT 0x04000000</term>
/// <term>
/// This flag is used internally during chain building for an online certificate status protocol (OCSP) signer certificate to
/// prevent cyclic revocation checks. During chain building, if the OCSP response is signed by an independent OCSP signer, then, in
/// addition to the original chain build, there is a second chain built for the OCSP signer certificate itself. This flag is used
/// during this second chain build to inhibit a recursive independent OCSP signer certificate. If the signer certificate contains
/// the szOID_PKIX_OCSP_NOCHECK extension, revocation checking is skipped for the leaf signer certificate. Both OCSP and CRL
/// checking are allowed. Windows Server 2003 and Windows XP: This value is not supported.
/// </term>
/// </item>
/// <item>
/// <term>CERT_CHAIN_CACHE_ONLY_URL_RETRIEVAL 0x00000004</term>
/// <term>
/// Uses only cached URLs in building a certificate chain. The Internet and intranet are not searched for URL-based objects. Note
/// This flag is not applicable to revocation checking. Set CERT_CHAIN_REVOCATION_CHECK_CACHE_ONLY to use only cached URLs for
/// revocation checking.
/// </term>
/// </item>
/// <item>
/// <term>CERT_CHAIN_DISABLE_PASS1_QUALITY_FILTERING 0x00000040</term>
/// <term>
/// For performance reasons, the second pass of chain building only considers potential chain paths that have quality greater than
/// or equal to the highest quality determined during the first pass. The first pass only considers valid signature, complete chain,
/// and trusted roots to calculate chain quality. This flag can be set to disable this optimization and consider all potential chain
/// paths during the second pass.
/// </term>
/// </item>
/// <item>
/// <term>CERT_CHAIN_DISABLE_MY_PEER_TRUST 0x00000800</term>
/// <term>This flag is not supported. Certificates in the "My" store are never considered for peer trust.</term>
/// </item>
/// <item>
/// <term>CERT_CHAIN_ENABLE_PEER_TRUST 0x00000400</term>
/// <term>
/// End entity certificates in the "TrustedPeople" store are trusted without performing any chain building. This function does not
/// set the CERT_TRUST_IS_PARTIAL_CHAIN or CERT_TRUST_IS_UNTRUSTED_ROOT dwErrorStatus member bits of the ppChainContext parameter.
/// Windows Server 2003 Windows XP : This flag is not supported.
/// </term>
/// </item>
/// <item>
/// <term>CERT_CHAIN_OPT_IN_WEAK_SIGNATURE 0x00010000</term>
/// <term>
/// Setting this flag indicates the caller wishes to opt into weak signature checks. This flag is available in the rollup update for
/// each OS starting with Windows 7 and Windows Server 2008 R2.
/// </term>
/// </item>
/// <item>
/// <term>CERT_CHAIN_RETURN_LOWER_QUALITY_CONTEXTS 0x00000080</term>
/// <term>
/// The default is to return only the highest quality chain path. Setting this flag will return the lower quality chains. These are
/// returned in the cLowerQualityChainContext and rgpLowerQualityChainContext fields of the chain context.
/// </term>
/// </item>
/// <item>
/// <term>CERT_CHAIN_DISABLE_AUTH_ROOT_AUTO_UPDATE 0x00000100</term>
/// <term>Setting this flag inhibits the auto update of third-party roots from the Windows Update Web Server.</term>
/// </item>
/// <item>
/// <term>CERT_CHAIN_REVOCATION_ACCUMULATIVE_TIMEOUT 0x08000000</term>
/// <term>
/// When you set CERT_CHAIN_REVOCATION_ACCUMULATIVE_TIMEOUT and you also specify a value for the dwUrlRetrievalTimeout member of the
/// CERT_CHAIN_PARA structure, the value you specify in dwUrlRetrievalTimeout represents the cumulative timeout across all
/// revocation URL retrievals. If you set CERT_CHAIN_REVOCATION_ACCUMULATIVE_TIMEOUT but do not specify a dwUrlRetrievalTimeout
/// value, the maximum cumulative timeout is set, by default, to 20 seconds. Each URL tested will timeout after half of the
/// remaining cumulative balance has passed. That is, the first URL times out after 10 seconds, the second after 5 seconds, the
/// third after 2.5 seconds and so on until a URL succeeds, 20 seconds has passed, or there are no more URLs to test. If you do not
/// set CERT_CHAIN_REVOCATION_ACCUMULATIVE_TIMEOUT, each revocation URL in the chain is assigned a maximum timeout equal to the
/// value specified in dwUrlRetrievalTimeout. If you do not specify a value for the dwUrlRetrievalTimeout member, each revocation
/// URL is assigned a maximum default timeout of 15 seconds. If no URL succeeds, the maximum cumulative timeout value is 15 seconds
/// multiplied by the number of URLs in the chain. You can set the default values by using Group Policy.
/// </term>
/// </item>
/// <item>
/// <term>CERT_CHAIN_TIMESTAMP_TIME 0x00000200</term>
/// <term>
/// When this flag is set, pTime is used as the time stamp time to determine whether the end certificate was time valid. Current
/// time can also be used to determine whether the end certificate remains time valid. All other certification authority (CA) and
/// root certificates in the chain are checked by using current time and not pTime.
/// </term>
/// </item>
/// <item>
/// <term>CERT_CHAIN_DISABLE_AIA 0x00002000</term>
/// <term>Setting this flag explicitly turns off Authority Information Access (AIA) retrievals.</term>
/// </item>
/// </list>
/// <para>You can also set the following revocation flags, but only one flag from this group may be set at a time.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>CERT_CHAIN_REVOCATION_CHECK_END_CERT 0x10000000</term>
/// <term>Revocation checking is done on the end certificate and only the end certificate.</term>
/// </item>
/// <item>
/// <term>CERT_CHAIN_REVOCATION_CHECK_CHAIN 0x20000000</term>
/// <term>Revocation checking is done on all of the certificates in every chain.</term>
/// </item>
/// <item>
/// <term>CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT 0x40000000</term>
/// <term>Revocation checking is done on all certificates in all of the chains except the root certificate.</term>
/// </item>
/// </list>
/// </param>
/// <param name="pvReserved">This parameter is reserved and must be <c>NULL</c>.</param>
/// <param name="ppChainContext">
/// The address of a pointer to the chain context created. When you have finished using the chain context, release the chain by
/// calling the CertFreeCertificateChain function.
/// </param>
/// <returns>
/// <para>If the function succeeds, the function returns nonzero ( <c>TRUE</c>).</para>
/// <para>If the function fails, it returns zero ( <c>FALSE</c>). For extended error information, call GetLastError.</para>
/// </returns>
/// <remarks>
/// <para>
/// When an application requests a certificate chain, the structure returned is in the form of a CERT_CHAIN_CONTEXT. This context
/// contains an array of CERT_SIMPLE_CHAIN structures where each simple chain goes from an end certificate to a self-signed
/// certificate. The chain context connects simple chains through trust lists. Each simple chain contains the chain of certificates,
/// summary trust information about the chain, and trust information about each certificate element in the chain.
/// </para>
/// <para>The following remarks apply to strong signature checking:</para>
/// <list type="bullet">
/// <item>
/// <term>
/// You can enable strong signature checking for this function by setting the <c>pStrongSignPara</c> member of the CERT_CHAIN_PARA
/// structure that is pointed to by the pChainPara parameter.
/// </term>
/// </item>
/// <item>
/// <term>
/// If a certificate without a strong signature is found in the chain, the <c>CERT_TRUST_HAS_WEAK_SIGNATURE</c> and
/// <c>CERT_TRUST_IS_NOT_SIGNATURE_VALID</c> errors are set in the <c>dwErrorStatus</c> field of the CERT_TRUST_STATUS structure.
/// The ppChainContext parameter points to a CERT_CHAIN_CONTEXT structure which, in turn, points to the <c>CERT_TRUST_STATUS</c> structure.
/// </term>
/// </item>
/// <item>
/// <term>
/// If the chain is strong signed, the public key in the end certificate is checked to determine whether it satisfies the minimum
/// public key length requirements for a strong signature. If the condition is not satisfied, the
/// <c>CERT_TRUST_HAS_WEAK_SIGNATURE</c> and <c>CERT_TRUST_IS_NOT_SIGNATURE_VALID</c> errors are set in the <c>dwErrorStatus</c>
/// field of the CERT_TRUST_STATUS structure. To disable checking the key length, set the
/// <c>CERT_CHAIN_STRONG_SIGN_DISABLE_END_CHECK_FLAG</c> value in the <c>dwStrongSignFlags</c> member of the CERT_CHAIN_PARA
/// structure pointed to by the pChainPara parameter.
/// </term>
/// </item>
/// <item>
/// <term>
/// If the <c>CERT_STRONG_SIGN_ENABLE_CRL_CHECK</c> or <c>CERT_STRONG_SIGN_ENABLE_OCSP_CHECK</c> flags are set in the
/// CERT_STRONG_SIGN_SERIALIZED_INFO structure and a CRL or OCSP response is found without a strong signature, the CRL or OCSP
/// response will be treated as being offline. That is, the <c>CERT_TRUST_IS_OFFLINE_REVOCATION</c> and
/// <c>CERT_TRUST_REVOCATION_STATUS_UNKNOWN</c> errors are set in the <c>dwErrorStatus</c> field of the CERT_TRUST_STATUS structure.
/// Also, the <c>dwRevocationResult</c> member of the CERT_REVOCATION_INFO structure is set to <c>NTE_BAD_ALGID</c>.
/// </term>
/// </item>
/// </list>
/// <para>Examples</para>
/// <para>For an example that uses this function, see Example C Program: Creating a Certificate Chain.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-certgetcertificatechain BOOL CertGetCertificateChain(
// HCERTCHAINENGINE hChainEngine, PCCERT_CONTEXT pCertContext, LPFILETIME pTime, HCERTSTORE hAdditionalStore, PCERT_CHAIN_PARA
// pChainPara, DWORD dwFlags, LPVOID pvReserved, PCCERT_CHAIN_CONTEXT *ppChainContext );
[DllImport(Lib.Crypt32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "8c93036c-0b93-40d4-b0e3-ba1f2fc72db1")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CertGetCertificateChain([Optional] HCERTCHAINENGINE hChainEngine, [In] PCCERT_CONTEXT pCertContext, in FILETIME pTime,
[Optional] HCERTSTORE hAdditionalStore, in CERT_CHAIN_PARA pChainPara, CertChainFlags dwFlags, [Optional] IntPtr pvReserved, out SafePCCERT_CHAIN_CONTEXT ppChainContext);
/// <summary>
/// The <c>CertGetCertificateChain</c> function builds a certificate chain context starting from an end certificate and going back,
/// if possible, to a trusted root certificate.
/// </summary>
/// <param name="hChainEngine">
/// A handle of the chain engine (namespace and cache) to be used. If hChainEngine is <c>NULL</c>, the default chain engine,
/// HCCE_CURRENT_USER, is used. This parameter can be set to HCCE_LOCAL_MACHINE.
/// </param>
/// <param name="pCertContext">
/// A pointer to the CERT_CONTEXT of the end certificate, the certificate for which a chain is being built. This certificate context
/// will be the zero-index element in the first simple chain.
/// </param>
/// <param name="pTime">
/// A pointer to a FILETIME variable that indicates the time for which the chain is to be validated. Note that the time does not
/// affect trust list, revocation, or root store checking. The current system time is used if <c>NULL</c> is passed to this
/// parameter. 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.
/// </param>
/// <param name="hAdditionalStore">
/// A handle to 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.
/// </param>
/// <param name="pChainPara">A pointer to a CERT_CHAIN_PARA structure that includes chain-building parameters.</param>
/// <param name="dwFlags">
/// <para>Flag values that indicate special processing. This parameter can be a combination of one or more of the following flags.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>CERT_CHAIN_CACHE_END_CERT 0x00000001</term>
/// <term>
/// When this flag is set, the end certificate is cached, which might speed up the chain-building process. By default, the end
/// certificate is not cached, and it would need to be verified each time a chain is built for it.
/// </term>
/// </item>
/// <item>
/// <term>CERT_CHAIN_REVOCATION_CHECK_CACHE_ONLY 0x80000000</term>
/// <term>Revocation checking only accesses cached URLs.</term>
/// </item>
/// <item>
/// <term>CERT_CHAIN_REVOCATION_CHECK_OCSP_CERT 0x04000000</term>
/// <term>
/// This flag is used internally during chain building for an online certificate status protocol (OCSP) signer certificate to
/// prevent cyclic revocation checks. During chain building, if the OCSP response is signed by an independent OCSP signer, then, in
/// addition to the original chain build, there is a second chain built for the OCSP signer certificate itself. This flag is used
/// during this second chain build to inhibit a recursive independent OCSP signer certificate. If the signer certificate contains
/// the szOID_PKIX_OCSP_NOCHECK extension, revocation checking is skipped for the leaf signer certificate. Both OCSP and CRL
/// checking are allowed. Windows Server 2003 and Windows XP: This value is not supported.
/// </term>
/// </item>
/// <item>
/// <term>CERT_CHAIN_CACHE_ONLY_URL_RETRIEVAL 0x00000004</term>
/// <term>
/// Uses only cached URLs in building a certificate chain. The Internet and intranet are not searched for URL-based objects. Note
/// This flag is not applicable to revocation checking. Set CERT_CHAIN_REVOCATION_CHECK_CACHE_ONLY to use only cached URLs for
/// revocation checking.
/// </term>
/// </item>
/// <item>
/// <term>CERT_CHAIN_DISABLE_PASS1_QUALITY_FILTERING 0x00000040</term>
/// <term>
/// For performance reasons, the second pass of chain building only considers potential chain paths that have quality greater than
/// or equal to the highest quality determined during the first pass. The first pass only considers valid signature, complete chain,
/// and trusted roots to calculate chain quality. This flag can be set to disable this optimization and consider all potential chain
/// paths during the second pass.
/// </term>
/// </item>
/// <item>
/// <term>CERT_CHAIN_DISABLE_MY_PEER_TRUST 0x00000800</term>
/// <term>This flag is not supported. Certificates in the "My" store are never considered for peer trust.</term>
/// </item>
/// <item>
/// <term>CERT_CHAIN_ENABLE_PEER_TRUST 0x00000400</term>
/// <term>
/// End entity certificates in the "TrustedPeople" store are trusted without performing any chain building. This function does not
/// set the CERT_TRUST_IS_PARTIAL_CHAIN or CERT_TRUST_IS_UNTRUSTED_ROOT dwErrorStatus member bits of the ppChainContext parameter.
/// Windows Server 2003 Windows XP : This flag is not supported.
/// </term>
/// </item>
/// <item>
/// <term>CERT_CHAIN_OPT_IN_WEAK_SIGNATURE 0x00010000</term>
/// <term>
/// Setting this flag indicates the caller wishes to opt into weak signature checks. This flag is available in the rollup update for
/// each OS starting with Windows 7 and Windows Server 2008 R2.
/// </term>
/// </item>
/// <item>
/// <term>CERT_CHAIN_RETURN_LOWER_QUALITY_CONTEXTS 0x00000080</term>
/// <term>
/// The default is to return only the highest quality chain path. Setting this flag will return the lower quality chains. These are
/// returned in the cLowerQualityChainContext and rgpLowerQualityChainContext fields of the chain context.
/// </term>
/// </item>
/// <item>
/// <term>CERT_CHAIN_DISABLE_AUTH_ROOT_AUTO_UPDATE 0x00000100</term>
/// <term>Setting this flag inhibits the auto update of third-party roots from the Windows Update Web Server.</term>
/// </item>
/// <item>
/// <term>CERT_CHAIN_REVOCATION_ACCUMULATIVE_TIMEOUT 0x08000000</term>
/// <term>
/// When you set CERT_CHAIN_REVOCATION_ACCUMULATIVE_TIMEOUT and you also specify a value for the dwUrlRetrievalTimeout member of the
/// CERT_CHAIN_PARA structure, the value you specify in dwUrlRetrievalTimeout represents the cumulative timeout across all
/// revocation URL retrievals. If you set CERT_CHAIN_REVOCATION_ACCUMULATIVE_TIMEOUT but do not specify a dwUrlRetrievalTimeout
/// value, the maximum cumulative timeout is set, by default, to 20 seconds. Each URL tested will timeout after half of the
/// remaining cumulative balance has passed. That is, the first URL times out after 10 seconds, the second after 5 seconds, the
/// third after 2.5 seconds and so on until a URL succeeds, 20 seconds has passed, or there are no more URLs to test. If you do not
/// set CERT_CHAIN_REVOCATION_ACCUMULATIVE_TIMEOUT, each revocation URL in the chain is assigned a maximum timeout equal to the
/// value specified in dwUrlRetrievalTimeout. If you do not specify a value for the dwUrlRetrievalTimeout member, each revocation
/// URL is assigned a maximum default timeout of 15 seconds. If no URL succeeds, the maximum cumulative timeout value is 15 seconds
/// multiplied by the number of URLs in the chain. You can set the default values by using Group Policy.
/// </term>
/// </item>
/// <item>
/// <term>CERT_CHAIN_TIMESTAMP_TIME 0x00000200</term>
/// <term>
/// When this flag is set, pTime is used as the time stamp time to determine whether the end certificate was time valid. Current
/// time can also be used to determine whether the end certificate remains time valid. All other certification authority (CA) and
/// root certificates in the chain are checked by using current time and not pTime.
/// </term>
/// </item>
/// <item>
/// <term>CERT_CHAIN_DISABLE_AIA 0x00002000</term>
/// <term>Setting this flag explicitly turns off Authority Information Access (AIA) retrievals.</term>
/// </item>
/// </list>
/// <para>You can also set the following revocation flags, but only one flag from this group may be set at a time.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>CERT_CHAIN_REVOCATION_CHECK_END_CERT 0x10000000</term>
/// <term>Revocation checking is done on the end certificate and only the end certificate.</term>
/// </item>
/// <item>
/// <term>CERT_CHAIN_REVOCATION_CHECK_CHAIN 0x20000000</term>
/// <term>Revocation checking is done on all of the certificates in every chain.</term>
/// </item>
/// <item>
/// <term>CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT 0x40000000</term>
/// <term>Revocation checking is done on all certificates in all of the chains except the root certificate.</term>
/// </item>
/// </list>
/// </param>
/// <param name="pvReserved">This parameter is reserved and must be <c>NULL</c>.</param>
/// <param name="ppChainContext">
/// The address of a pointer to the chain context created. When you have finished using the chain context, release the chain by
/// calling the CertFreeCertificateChain function.
/// </param>
/// <returns>
/// <para>If the function succeeds, the function returns nonzero ( <c>TRUE</c>).</para>
/// <para>If the function fails, it returns zero ( <c>FALSE</c>). For extended error information, call GetLastError.</para>
/// </returns>
/// <remarks>
/// <para>
/// When an application requests a certificate chain, the structure returned is in the form of a CERT_CHAIN_CONTEXT. This context
/// contains an array of CERT_SIMPLE_CHAIN structures where each simple chain goes from an end certificate to a self-signed
/// certificate. The chain context connects simple chains through trust lists. Each simple chain contains the chain of certificates,
/// summary trust information about the chain, and trust information about each certificate element in the chain.
/// </para>
/// <para>The following remarks apply to strong signature checking:</para>
/// <list type="bullet">
/// <item>
/// <term>
/// You can enable strong signature checking for this function by setting the <c>pStrongSignPara</c> member of the CERT_CHAIN_PARA
/// structure that is pointed to by the pChainPara parameter.
/// </term>
/// </item>
/// <item>
/// <term>
/// If a certificate without a strong signature is found in the chain, the <c>CERT_TRUST_HAS_WEAK_SIGNATURE</c> and
/// <c>CERT_TRUST_IS_NOT_SIGNATURE_VALID</c> errors are set in the <c>dwErrorStatus</c> field of the CERT_TRUST_STATUS structure.
/// The ppChainContext parameter points to a CERT_CHAIN_CONTEXT structure which, in turn, points to the <c>CERT_TRUST_STATUS</c> structure.
/// </term>
/// </item>
/// <item>
/// <term>
/// If the chain is strong signed, the public key in the end certificate is checked to determine whether it satisfies the minimum
/// public key length requirements for a strong signature. If the condition is not satisfied, the
/// <c>CERT_TRUST_HAS_WEAK_SIGNATURE</c> and <c>CERT_TRUST_IS_NOT_SIGNATURE_VALID</c> errors are set in the <c>dwErrorStatus</c>
/// field of the CERT_TRUST_STATUS structure. To disable checking the key length, set the
/// <c>CERT_CHAIN_STRONG_SIGN_DISABLE_END_CHECK_FLAG</c> value in the <c>dwStrongSignFlags</c> member of the CERT_CHAIN_PARA
/// structure pointed to by the pChainPara parameter.
/// </term>
/// </item>
/// <item>
/// <term>
/// If the <c>CERT_STRONG_SIGN_ENABLE_CRL_CHECK</c> or <c>CERT_STRONG_SIGN_ENABLE_OCSP_CHECK</c> flags are set in the
/// CERT_STRONG_SIGN_SERIALIZED_INFO structure and a CRL or OCSP response is found without a strong signature, the CRL or OCSP
/// response will be treated as being offline. That is, the <c>CERT_TRUST_IS_OFFLINE_REVOCATION</c> and
/// <c>CERT_TRUST_REVOCATION_STATUS_UNKNOWN</c> errors are set in the <c>dwErrorStatus</c> field of the CERT_TRUST_STATUS structure.
/// Also, the <c>dwRevocationResult</c> member of the CERT_REVOCATION_INFO structure is set to <c>NTE_BAD_ALGID</c>.
/// </term>
/// </item>
/// </list>
/// <para>Examples</para>
/// <para>For an example that uses this function, see Example C Program: Creating a Certificate Chain.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-certgetcertificatechain BOOL CertGetCertificateChain(
// HCERTCHAINENGINE hChainEngine, PCCERT_CONTEXT pCertContext, LPFILETIME pTime, HCERTSTORE hAdditionalStore, PCERT_CHAIN_PARA
// pChainPara, DWORD dwFlags, LPVOID pvReserved, PCCERT_CHAIN_CONTEXT *ppChainContext );
[DllImport(Lib.Crypt32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "8c93036c-0b93-40d4-b0e3-ba1f2fc72db1")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CertGetCertificateChain([Optional] HCERTCHAINENGINE hChainEngine, [In] PCCERT_CONTEXT pCertContext, [In, Optional] IntPtr pTime,
[Optional] HCERTSTORE hAdditionalStore, in CERT_CHAIN_PARA pChainPara, CertChainFlags dwFlags, [Optional] IntPtr pvReserved, out SafePCCERT_CHAIN_CONTEXT ppChainContext);
/// <summary>
/// The <c>CertIsValidCRLForCertificate</c> function checks a CRL to find out if it is a CRL that would include a specific
/// certificate if that certificate were revoked. If the CRL has an issuing distribution point (IDP) extension, the function checks
/// whether that IDP is valid for the certificate being checked.
/// </summary>
/// <param name="pCert">A pointer to a certificate context.</param>
/// <param name="pCrl">
/// A pointer to a CRL. The function checks this CRL to determine whether it could contain the certificate context pointed to by
/// pCert. The function does not look for the certificate in the CRL.
/// </param>
/// <param name="dwFlags">Currently not used and must be set to zero.</param>
/// <param name="pvReserved">Currently not used and must be set to <c>NULL</c>.</param>
/// <returns>
/// The function returns <c>TRUE</c> if the CRL is a valid CRL to be searched for the specific certificate. It returns <c>FALSE</c>
/// if the CRL is not a valid CRL for searching for the certificate.
/// </returns>
/// <remarks>
/// For the CRL to be valid for the certificate, the <c>CertIsValidCRLForCertificate</c> function does not require the CRL to be
/// issued by the same certification authority (CA) as the issuer of the certificate.
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-certisvalidcrlforcertificate BOOL
// CertIsValidCRLForCertificate( PCCERT_CONTEXT pCert, PCCRL_CONTEXT pCrl, DWORD dwFlags, void *pvReserved );
[DllImport(Lib.Crypt32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "06047b7a-4bdd-42f9-bb85-49b6ec6f35a0")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CertIsValidCRLForCertificate(PCCERT_CONTEXT pCert, PCCRL_CONTEXT pCrl, uint dwFlags = 0, IntPtr pvReserved = default);
/// <summary>
/// The <c>CertSetCertificateContextPropertiesFromCTLEntry</c> function sets the properties on the certificate context by using the
/// attributes in the specified certificate trust list (CTL) entry.
/// </summary>
/// <param name="pCertContext">A pointer to the CERT_CONTEXT whose attributes are to be set.</param>
/// <param name="pCtlEntry">A pointer to the CTL_ENTRY structure used to set the attributes on the certificate.</param>
/// <param name="dwFlags">
/// A <c>DWORD</c>. This parameter can be set to CERT_SET_PROPERTY_IGNORE_PERSIST_ERROR_FLAG to ignore any persisted error flags.
/// </param>
/// <returns>
/// <para>If the function succeeds, the function returns nonzero.</para>
/// <para>If the function fails, it returns zero. For extended error information, call GetLastError.</para>
/// </returns>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-certsetcertificatecontextpropertiesfromctlentry BOOL
// CertSetCertificateContextPropertiesFromCTLEntry( PCCERT_CONTEXT pCertContext, PCTL_ENTRY pCtlEntry, DWORD dwFlags );
[DllImport(Lib.Crypt32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "b53b046a-68d4-4dc5-ab89-1b30ebd1de60")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CertSetCertificateContextPropertiesFromCTLEntry(PCCERT_CONTEXT pCertContext, in CTL_ENTRY pCtlEntry, uint dwFlags);
/// <summary>
/// The <c>CertVerifyCertificateChainPolicy</c> function checks a certificate chain to verify its validity, including its compliance
/// with any specified validity policy criteria.
/// </summary>
/// <param name="pszPolicyOID">
/// <para>Current predefined verify chain policy structures are listed in the following table.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>CERT_CHAIN_POLICY_BASE (LPCSTR) 1</term>
/// <term>
/// Implements the base chain policy verification checks. The dwFlags member of the structure pointed to by pPolicyPara can be set
/// to alter the default policy checking behavior.
/// </term>
/// </item>
/// <item>
/// <term>CERT_CHAIN_POLICY_AUTHENTICODE (LPCSTR) 2</term>
/// <term>
/// Implements the Authenticode chain policy verification checks. The pvExtraPolicyPara member of the structure pointed to by
/// pPolicyPara can be set to point to an AUTHENTICODE_EXTRA_CERT_CHAIN_POLICY_PARA structure. The pvExtraPolicyStatus member of the
/// structure pointed to by pPolicyStatus can be set to point to an AUTHENTICODE_EXTRA_CERT_CHAIN_POLICY_STATUS structure.
/// </term>
/// </item>
/// <item>
/// <term>CERT_CHAIN_POLICY_AUTHENTICODE_TS (LPCSTR) 3</term>
/// <term>
/// Implements Authenticode Time Stamp chain policy verification checks. The pvExtraPolicyPara member of the data structure pointed
/// to by pPolicyPara can be set to point to an AUTHENTICODE_TS_EXTRA_CERT_CHAIN_POLICY_PARA structure. The pvExtraPolicyStatus
/// member of the data structure pointed to by pPolicyStatus is not used and must be set to NULL
/// </term>
/// </item>
/// <item>
/// <term>CERT_CHAIN_POLICY_SSL (LPCSTR) 4</term>
/// <term>
/// Implements the SSL client/server chain policy verification checks. The pvExtraPolicyPara member in the data structure pointed to
/// by pPolicyPara can be set to point to an SSL_EXTRA_CERT_CHAIN_POLICY_PARA structure initialized with additional policy criteria.
/// </term>
/// </item>
/// <item>
/// <term>CERT_CHAIN_POLICY_BASIC_CONSTRAINTS (LPCSTR) 5</term>
/// <term>
/// Implements the basic constraints chain policy. Iterates through all the certificates in the chain checking for either a
/// szOID_BASIC_CONSTRAINTS or a szOID_BASIC_CONSTRAINTS2 extension. If neither extension is present, the certificate is assumed to
/// have valid policy. Otherwise, for the first certificate element, checks if it matches the expected CA_FLAG or END_ENTITY_FLAG
/// specified in the dwFlags member of the CERT_CHAIN_POLICY_PARA structure pointed to by the pPolicyPara parameter. If neither or
/// both flags are set, then, the first element can be either a CA or END_ENTITY. All other elements must be a certification
/// authority (CA). If the PathLenConstraint is present in the extension, it is checked. The first elements in the remaining simple
/// chains (that is, the certificates used to sign the CTL) are checked to be an END_ENTITY. If this verification fails, dwError
/// will be set to TRUST_E_BASIC_CONSTRAINTS.
/// </term>
/// </item>
/// <item>
/// <term>CERT_CHAIN_POLICY_NT_AUTH (LPCSTR) 6</term>
/// <term>
/// Implements the Windows NT Authentication chain policy, which consists of three distinct chain verifications in the following order:
/// </term>
/// </item>
/// <item>
/// <term>CERT_CHAIN_POLICY_MICROSOFT_ROOT (LPCSTR) 7</term>
/// <term>
/// Checks the last element of the first simple chain for a Microsoft root public key. If that element does not contain a Microsoft
/// root public key, the dwError member of the CERT_CHAIN_POLICY_STATUS structure pointed to by the pPolicyStatus parameter is set
/// to CERT_E_UNTRUSTEDROOT. The dwFlags member of the CERT_CHAIN_POLICY_PARA structure pointed to by the pPolicyStatus parameter
/// can contain the MICROSOFT_ROOT_CERT_CHAIN_POLICY_CHECK_APPLICATION_ROOT_FLAG flag, which causes this function to also check for
/// the Microsoft application root "Microsoft Root Certificate Authority 2011". The dwFlags member of the CERT_CHAIN_POLICY_PARA
/// structure pointed to by the pPolicyPara parameter can contain the MICROSOFT_ROOT_CERT_CHAIN_POLICY_ENABLE_TEST_ROOT_FLAG flag,
/// which causes this function to also check for the Microsoft test roots.
/// </term>
/// </item>
/// <item>
/// <term>CERT_CHAIN_POLICY_EV (LPCSTR) 8</term>
/// <term>
/// Specifies that extended validation of certificates is performed. Windows Server 2008, Windows Vista, Windows Server 2003 and
/// Windows XP: This value is not supported.
/// </term>
/// </item>
/// <item>
/// <term>CERT_CHAIN_POLICY_SSL_F12 (LPCSTR) 9</term>
/// <term>
/// Checks if any certificates in the chain have weak crypto or if third party root certificate compliance and provide an error
/// string. The pvExtraPolicyStatus member of the CERT_CHAIN_POLICY_STATUS structure pointed to by the pPolicyStatus parameter must
/// point to SSL_F12_EXTRA_CERT_CHAIN_POLICY_STATUS, which is updated with the results of the weak crypto and root program
/// compliance checks. Before calling, the cbSize member of the CERT_CHAIN_POLICY_STATUS structure pointed to by the pPolicyStatus
/// parameter must be set to a value greater than or equal to sizeof(SSL_F12_EXTRA_CERT_CHAIN_POLICY_STATUS). The dwError member in
/// CERT_CHAIN_POLICY_STATUS structure pointed to by the pPolicyStatus parameter will be set to TRUST_E_CERT_SIGNATURE for potential
/// weak crypto and set to CERT_E_UNTRUSTEDROOT for Third Party Roots not in compliance with the Microsoft Root Program. Windows 10,
/// version 1607, Windows Server 2016, Windows 10, version 1511 with KB3172985, Windows 10 RTM with KB3163912, Windows 8.1 and
/// Windows Server 2012 R2 with KB3163912, and Windows 7 with SP1 and Windows Server 2008 R2 SP1 with KB3161029
/// </term>
/// </item>
/// </list>
/// </param>
/// <param name="pChainContext">A pointer to a CERT_CHAIN_CONTEXT structure that contains a chain to be verified.</param>
/// <param name="pPolicyPara">
/// <para>
/// A pointer to a CERT_CHAIN_POLICY_PARA structure that provides the policy verification criteria for the chain. The <c>dwFlags</c>
/// member of that structure can be set to change the default policy checking behavior.
/// </para>
/// <para>In addition, policy-specific parameters can also be passed in the <c>pvExtraPolicyPara</c> member of the structure.</para>
/// </param>
/// <param name="pPolicyStatus">
/// A pointer to a CERT_CHAIN_POLICY_STATUS structure where status information on the chain is returned. OID-specific extra status
/// can be returned in the <c>pvExtraPolicyStatus</c> member of this structure.
/// </param>
/// <returns>
/// <para>
/// The return value indicates whether the function was able to check for the policy, it does not indicate whether the policy check
/// failed or passed.
/// </para>
/// <para>
/// If the chain can be verified for the specified policy, <c>TRUE</c> is returned and the <c>dwError</c> member of the
/// pPolicyStatus is updated. A <c>dwError</c> of 0 (ERROR_SUCCESS or S_OK) indicates the chain satisfies the specified policy.
/// </para>
/// <para>
/// If the chain cannot be validated, the return value is <c>TRUE</c> and you need to verify the pPolicyStatus parameter for the
/// actual error.
/// </para>
/// <para>A value of <c>FALSE</c> indicates that the function wasn't able to check for the policy.</para>
/// </returns>
/// <remarks>
/// <para>
/// A <c>dwError</c> member of the CERT_CHAIN_POLICY_STATUS structure pointed to by pPolicyStatus can apply to a single chain
/// element, to a simple chain, or to an entire chain context. If <c>dwError</c> applies to the entire chain context, both the
/// <c>lChainIndex</c> and the <c>lElementIndex</c> members of the <c>CERT_CHAIN_POLICY_STATUS</c> structure are set to 1. If
/// <c>dwError</c> applies to a complete simple chain, <c>lElementIndex</c> is set to 1 and <c>lChainIndex</c> is set to the index
/// of the first chain that has an error. If <c>dwError</c> applies to a single certificate element, <c>lChainIndex</c> and
/// <c>lElementIndex</c> index the first certificate that has the error.
/// </para>
/// <para>To get the certificate element use this syntax:</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-certverifycertificatechainpolicy BOOL
// CertVerifyCertificateChainPolicy( LPCSTR pszPolicyOID, PCCERT_CHAIN_CONTEXT pChainContext, PCERT_CHAIN_POLICY_PARA pPolicyPara,
// PCERT_CHAIN_POLICY_STATUS pPolicyStatus );
[DllImport(Lib.Crypt32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "19c37f77-1072-4740-b244-764b816a2a1f")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CertVerifyCertificateChainPolicy([In] SafeOID pszPolicyOID, [In] PCCERT_CHAIN_CONTEXT pChainContext,
in CERT_CHAIN_POLICY_PARA pPolicyPara, ref CERT_CHAIN_POLICY_STATUS pPolicyStatus);
/// <summary>
/// The <c>CertVerifyCertificateChainPolicy</c> function checks a certificate chain to verify its validity, including its compliance
/// with any specified validity policy criteria.
/// </summary>
/// <param name="pszPolicyOID">
/// <para>Current predefined verify chain policy structures are listed in the following table.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>CERT_CHAIN_POLICY_BASE (LPCSTR) 1</term>
/// <term>
/// Implements the base chain policy verification checks. The dwFlags member of the structure pointed to by pPolicyPara can be set
/// to alter the default policy checking behavior.
/// </term>
/// </item>
/// <item>
/// <term>CERT_CHAIN_POLICY_AUTHENTICODE (LPCSTR) 2</term>
/// <term>
/// Implements the Authenticode chain policy verification checks. The pvExtraPolicyPara member of the structure pointed to by
/// pPolicyPara can be set to point to an AUTHENTICODE_EXTRA_CERT_CHAIN_POLICY_PARA structure. The pvExtraPolicyStatus member of the
/// structure pointed to by pPolicyStatus can be set to point to an AUTHENTICODE_EXTRA_CERT_CHAIN_POLICY_STATUS structure.
/// </term>
/// </item>
/// <item>
/// <term>CERT_CHAIN_POLICY_AUTHENTICODE_TS (LPCSTR) 3</term>
/// <term>
/// Implements Authenticode Time Stamp chain policy verification checks. The pvExtraPolicyPara member of the data structure pointed
/// to by pPolicyPara can be set to point to an AUTHENTICODE_TS_EXTRA_CERT_CHAIN_POLICY_PARA structure. The pvExtraPolicyStatus
/// member of the data structure pointed to by pPolicyStatus is not used and must be set to NULL
/// </term>
/// </item>
/// <item>
/// <term>CERT_CHAIN_POLICY_SSL (LPCSTR) 4</term>
/// <term>
/// Implements the SSL client/server chain policy verification checks. The pvExtraPolicyPara member in the data structure pointed to
/// by pPolicyPara can be set to point to an SSL_EXTRA_CERT_CHAIN_POLICY_PARA structure initialized with additional policy criteria.
/// </term>
/// </item>
/// <item>
/// <term>CERT_CHAIN_POLICY_BASIC_CONSTRAINTS (LPCSTR) 5</term>
/// <term>
/// Implements the basic constraints chain policy. Iterates through all the certificates in the chain checking for either a
/// szOID_BASIC_CONSTRAINTS or a szOID_BASIC_CONSTRAINTS2 extension. If neither extension is present, the certificate is assumed to
/// have valid policy. Otherwise, for the first certificate element, checks if it matches the expected CA_FLAG or END_ENTITY_FLAG
/// specified in the dwFlags member of the CERT_CHAIN_POLICY_PARA structure pointed to by the pPolicyPara parameter. If neither or
/// both flags are set, then, the first element can be either a CA or END_ENTITY. All other elements must be a certification
/// authority (CA). If the PathLenConstraint is present in the extension, it is checked. The first elements in the remaining simple
/// chains (that is, the certificates used to sign the CTL) are checked to be an END_ENTITY. If this verification fails, dwError
/// will be set to TRUST_E_BASIC_CONSTRAINTS.
/// </term>
/// </item>
/// <item>
/// <term>CERT_CHAIN_POLICY_NT_AUTH (LPCSTR) 6</term>
/// <term>
/// Implements the Windows NT Authentication chain policy, which consists of three distinct chain verifications in the following order:
/// </term>
/// </item>
/// <item>
/// <term>CERT_CHAIN_POLICY_MICROSOFT_ROOT (LPCSTR) 7</term>
/// <term>
/// Checks the last element of the first simple chain for a Microsoft root public key. If that element does not contain a Microsoft
/// root public key, the dwError member of the CERT_CHAIN_POLICY_STATUS structure pointed to by the pPolicyStatus parameter is set
/// to CERT_E_UNTRUSTEDROOT. The dwFlags member of the CERT_CHAIN_POLICY_PARA structure pointed to by the pPolicyStatus parameter
/// can contain the MICROSOFT_ROOT_CERT_CHAIN_POLICY_CHECK_APPLICATION_ROOT_FLAG flag, which causes this function to also check for
/// the Microsoft application root "Microsoft Root Certificate Authority 2011". The dwFlags member of the CERT_CHAIN_POLICY_PARA
/// structure pointed to by the pPolicyPara parameter can contain the MICROSOFT_ROOT_CERT_CHAIN_POLICY_ENABLE_TEST_ROOT_FLAG flag,
/// which causes this function to also check for the Microsoft test roots.
/// </term>
/// </item>
/// <item>
/// <term>CERT_CHAIN_POLICY_EV (LPCSTR) 8</term>
/// <term>
/// Specifies that extended validation of certificates is performed. Windows Server 2008, Windows Vista, Windows Server 2003 and
/// Windows XP: This value is not supported.
/// </term>
/// </item>
/// <item>
/// <term>CERT_CHAIN_POLICY_SSL_F12 (LPCSTR) 9</term>
/// <term>
/// Checks if any certificates in the chain have weak crypto or if third party root certificate compliance and provide an error
/// string. The pvExtraPolicyStatus member of the CERT_CHAIN_POLICY_STATUS structure pointed to by the pPolicyStatus parameter must
/// point to SSL_F12_EXTRA_CERT_CHAIN_POLICY_STATUS, which is updated with the results of the weak crypto and root program
/// compliance checks. Before calling, the cbSize member of the CERT_CHAIN_POLICY_STATUS structure pointed to by the pPolicyStatus
/// parameter must be set to a value greater than or equal to sizeof(SSL_F12_EXTRA_CERT_CHAIN_POLICY_STATUS). The dwError member in
/// CERT_CHAIN_POLICY_STATUS structure pointed to by the pPolicyStatus parameter will be set to TRUST_E_CERT_SIGNATURE for potential
/// weak crypto and set to CERT_E_UNTRUSTEDROOT for Third Party Roots not in compliance with the Microsoft Root Program. Windows 10,
/// version 1607, Windows Server 2016, Windows 10, version 1511 with KB3172985, Windows 10 RTM with KB3163912, Windows 8.1 and
/// Windows Server 2012 R2 with KB3163912, and Windows 7 with SP1 and Windows Server 2008 R2 SP1 with KB3161029
/// </term>
/// </item>
/// </list>
/// </param>
/// <param name="pChainContext">A pointer to a CERT_CHAIN_CONTEXT structure that contains a chain to be verified.</param>
/// <param name="pPolicyPara">
/// <para>
/// A pointer to a CERT_CHAIN_POLICY_PARA structure that provides the policy verification criteria for the chain. The <c>dwFlags</c>
/// member of that structure can be set to change the default policy checking behavior.
/// </para>
/// <para>In addition, policy-specific parameters can also be passed in the <c>pvExtraPolicyPara</c> member of the structure.</para>
/// </param>
/// <param name="pPolicyStatus">
/// A pointer to a CERT_CHAIN_POLICY_STATUS structure where status information on the chain is returned. OID-specific extra status
/// can be returned in the <c>pvExtraPolicyStatus</c> member of this structure.
/// </param>
/// <returns>
/// <para>
/// The return value indicates whether the function was able to check for the policy, it does not indicate whether the policy check
/// failed or passed.
/// </para>
/// <para>
/// If the chain can be verified for the specified policy, <c>TRUE</c> is returned and the <c>dwError</c> member of the
/// pPolicyStatus is updated. A <c>dwError</c> of 0 (ERROR_SUCCESS or S_OK) indicates the chain satisfies the specified policy.
/// </para>
/// <para>
/// If the chain cannot be validated, the return value is <c>TRUE</c> and you need to verify the pPolicyStatus parameter for the
/// actual error.
/// </para>
/// <para>A value of <c>FALSE</c> indicates that the function wasn't able to check for the policy.</para>
/// </returns>
/// <remarks>
/// <para>
/// A <c>dwError</c> member of the CERT_CHAIN_POLICY_STATUS structure pointed to by pPolicyStatus can apply to a single chain
/// element, to a simple chain, or to an entire chain context. If <c>dwError</c> applies to the entire chain context, both the
/// <c>lChainIndex</c> and the <c>lElementIndex</c> members of the <c>CERT_CHAIN_POLICY_STATUS</c> structure are set to 1. If
/// <c>dwError</c> applies to a complete simple chain, <c>lElementIndex</c> is set to 1 and <c>lChainIndex</c> is set to the index
/// of the first chain that has an error. If <c>dwError</c> applies to a single certificate element, <c>lChainIndex</c> and
/// <c>lElementIndex</c> index the first certificate that has the error.
/// </para>
/// <para>To get the certificate element use this syntax:</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-certverifycertificatechainpolicy BOOL
// CertVerifyCertificateChainPolicy( LPCSTR pszPolicyOID, PCCERT_CHAIN_CONTEXT pChainContext, PCERT_CHAIN_POLICY_PARA pPolicyPara,
// PCERT_CHAIN_POLICY_STATUS pPolicyStatus );
[DllImport(Lib.Crypt32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "19c37f77-1072-4740-b244-764b816a2a1f")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CertVerifyCertificateChainPolicy(IntPtr pszPolicyOID, [In] PCCERT_CHAIN_CONTEXT pChainContext,
2020-03-09 11:54:19 -04:00
in CERT_CHAIN_POLICY_PARA pPolicyPara, ref CERT_CHAIN_POLICY_STATUS pPolicyStatus);
/// <summary>
/// The <c>CertVerifyCTLUsage</c> function verifies that a subject is trusted for a specified usage by finding a signed and
/// time-valid certificate trust list (CTL) with the usage identifiers that contain the subject. A certificate's subject can be
/// identified by either its certificate context or any unique identifier such as the SHA1 hash of the subject's certificate.
/// </summary>
/// <param name="dwEncodingType">
/// <para>
/// Specifies the encoding type used. Currently, only X509_ASN_ENCODING and PKCS_7_ASN_ENCODING are being used; however, additional
/// encoding types can be added in the future. For either current encoding type, use
/// </para>
/// <para>X509_ASN_ENCODING | PKCS_7_ASN_ENCODING.</para>
/// </param>
/// <param name="dwSubjectType">
/// <para>
/// If the dwSubjectType parameter is set to CTL_CERT_SUBJECT_TYPE, pvSubject points to a CERT_CONTEXT structure. The structure's
/// <c>SubjectAlgorithm</c> member is examined to determine the representation of the subject's identity. Initially, only SHA1 and
/// MD5 hashes are supported as values for <c>SubjectAlgorithm</c>. The appropriate hash property is obtained from the
/// <c>CERT_CONTEXT</c> structure.
/// </para>
/// <para>
/// If the dwSubjectType parameter is set to CTL_ANY_SUBJECT_TYPE, pvSubject points to the CTL_ANY_SUBJECT_INFO structure. The
/// <c>SubjectAlgorithm</c> member of this structure must match the algorithm type of the CTL, and the <c>SubjectIdentifier</c>
/// member must match one of the CTL entries.
/// </para>
/// <para>If dwSubjectType is set to either preceding value, dwEncodingType is not used.</para>
/// </param>
/// <param name="pvSubject">Value used in conjunction with the dwSubjectType parameter.</param>
/// <param name="pSubjectUsage">A pointer to a CTL_USAGE structure used to specify the intended usage of the subject.</param>
/// <param name="dwFlags">
/// <para>
/// If the CERT_VERIFY_INHIBIT_CTL_UPDATE_FLAG is not set, a CTL whose time is no longer valid in one of the stores specified by
/// <c>rghCtlStore</c> in CTL_VERIFY_USAGE_PARA can be replaced. When replaced, the CERT_VERIFY_UPDATED_CTL_FLAG is set in the
/// <c>dwFlags</c> member of pVerifyUsageStatus. If this flag is set, an update will not be made, even if a time-valid, updated CTL
/// is received for a CTL that is in the store and whose time is no longer valid.
/// </para>
/// <para>
/// If the CERT_VERIFY_TRUSTED_SIGNERS_FLAG is set, only the signer stores specified by <c>rghSignerStore</c> in
/// CTL_VERIFY_USAGE_PARA are searched to find the signer. Otherwise, the signer stores provide additional sources to find the
/// signer's certificate. For more information, see Remarks.
/// </para>
/// <para>If CERT_VERIFY_NO_TIME_CHECK_FLAG is set, the CTLs are not checked for time validity. Otherwise, they are.</para>
/// <para>
/// If CERT_VERIFY_ALLOW_MORE_USAGE_FLAG is set, the CTL can contain usage identifiers in addition to those specified by
/// pSubjectUsage. Otherwise, the found CTL will contain no additional usage identifiers.
/// </para>
/// </param>
/// <param name="pVerifyUsagePara">
/// A pointer to a CTL_VERIFY_USAGE_PARA structure that specifies the stores to be searched to find the CTL and the stores that
/// contain acceptable CTL signers. Setting the <c>ListIdentifier</c> member further limits the search.
/// </param>
/// <param name="pVerifyUsageStatus">
/// A pointer to a CTL_VERIFY_USAGE_STATUS structure. The <c>cbSize</c> member of the structure must to be set to the size, in
/// bytes, of the structure, and all other fields must be set to zero before <c>CertVerifyCTLUsage</c> is called. For more
/// information, see <c>CTL_VERIFY_USAGE_STATUS</c>.
/// </param>
/// <returns>
/// <para>
/// If the subject is trusted for the specified usage, <c>TRUE</c> is returned. Otherwise, <c>FALSE</c> is returned. GetLastError
/// can return one of the following error codes.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>CRYPT_E_NO_VERIFY_USAGE_DLL</term>
/// <term>No DLL or exported function was found to verify subject usage.</term>
/// </item>
/// <item>
/// <term>CRYPT_E_NO_VERIFY_USAGE_CHECK</term>
/// <term>The called function was not able to do a usage check on the subject.</term>
/// </item>
/// <item>
/// <term>CRYPT_E_VERIFY_USAGE_OFFLINE</term>
/// <term>The server was offline; therefore, the called function could not complete the usage check.</term>
/// </item>
/// <item>
/// <term>CRYPT_E_NOT_IN_CTL</term>
/// <term>The subject was not found in a CTL.</term>
/// </item>
/// <item>
/// <term>CRYPT_E_NO_TRUSTED_SIGNER</term>
/// <term>No trusted signer was found to verify the signature of the message or trust list.</term>
/// </item>
/// </list>
/// <para>The <c>dwError</c> member of the CTL_VERIFY_USAGE_PARA pointed to by pVerifyUsageStatus is set to the same error code.</para>
/// </returns>
/// <remarks>
/// <para>
/// <c>CertVerifyCTLUsage</c> is a dispatcher to functions that can be installed by using an object identifier (OID). First, it
/// tries to find an OID function that matches the first usage object identifier in the CLT_USAGE structure pointed to by
/// pSubjectUsage. If this fails, it uses the default <c>CertDllVerifyCTLUsage</c> functions.
/// </para>
/// <para>The <c>CertDllVerifyCTLUsage</c> function in Cryptnet.dll can be installed by using an OID; it has the following properties:</para>
/// <list type="bullet">
/// <item>
/// <term>
/// If CTL stores are specified by <c>rghCtlStore</c> in pVerifyUsagePara, only those stores are searched to find a CTL. Otherwise,
/// the Trust system store is searched to find a CTL.
/// </term>
/// </item>
/// <item>
/// <term>
/// If CERT_VERIFY_TRUSTED_SIGNERS_FLAG is set, only the signer stores specified by <c>rghSignerStore</c> in pVerifyUsagePara are
/// searched to find the certificate that corresponds to the signer's issuer and serial number. Otherwise, the CTL message's store,
/// the signer stores specified by <c>rghSignerStore</c> in pVerifyUsagePara, the Trust system store, CA system store, ROOT, and
/// Software Publisher Certificate (SPC) system stores are searched to find the signer's certificate. In either case, the public key
/// in the found certificate is used to verify the signature of the CTL.
/// </term>
/// </item>
/// <item>
/// <term>If the CTL has a set <c>NextUpdate</c> member and CERT_VERIFY_NO_TIME_CHECK is not set, it is verified for time validity.</term>
/// </item>
/// <item>
/// <term>
/// If the CTL obtained from the store has a time that is not valid, an attempt is made to get a time-valid version. The
/// <c>CertDllVerifyCTLUsage</c> function uses the <c>NextUpdateLocation</c> property or the <c>NextUpdateLocation</c> extension of
/// the CTL, or it searches the signer's information for a <c>NextUpdateLocation</c> attribute.
/// </term>
/// </item>
/// </list>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-certverifyctlusage BOOL CertVerifyCTLUsage( DWORD
// dwEncodingType, DWORD dwSubjectType, void *pvSubject, PCTL_USAGE pSubjectUsage, DWORD dwFlags, PCTL_VERIFY_USAGE_PARA
// pVerifyUsagePara, PCTL_VERIFY_USAGE_STATUS pVerifyUsageStatus );
[DllImport(Lib.Crypt32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "d87d8157-8e52-4198-bfd4-46d83d72eb13")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CertVerifyCTLUsage(CertEncodingType dwEncodingType, CtlCertSubject dwSubjectType, [In] IntPtr pvSubject, in CTL_USAGE pSubjectUsage,
CertVerifyCTLFlags dwFlags, in CTL_VERIFY_USAGE_PARA pVerifyUsagePara, ref CTL_VERIFY_USAGE_STATUS pVerifyUsageStatus);
/// <summary>
/// The <c>CertVerifyCTLUsage</c> function verifies that a subject is trusted for a specified usage by finding a signed and
/// time-valid certificate trust list (CTL) with the usage identifiers that contain the subject. A certificate's subject can be
/// identified by either its certificate context or any unique identifier such as the SHA1 hash of the subject's certificate.
/// </summary>
/// <param name="dwEncodingType">
/// <para>
/// Specifies the encoding type used. Currently, only X509_ASN_ENCODING and PKCS_7_ASN_ENCODING are being used; however, additional
/// encoding types can be added in the future. For either current encoding type, use
/// </para>
/// <para>X509_ASN_ENCODING | PKCS_7_ASN_ENCODING.</para>
/// </param>
/// <param name="dwSubjectType">
/// <para>
/// If the dwSubjectType parameter is set to CTL_CERT_SUBJECT_TYPE, pvSubject points to a CERT_CONTEXT structure. The structure's
/// <c>SubjectAlgorithm</c> member is examined to determine the representation of the subject's identity. Initially, only SHA1 and
/// MD5 hashes are supported as values for <c>SubjectAlgorithm</c>. The appropriate hash property is obtained from the
/// <c>CERT_CONTEXT</c> structure.
/// </para>
/// <para>
/// If the dwSubjectType parameter is set to CTL_ANY_SUBJECT_TYPE, pvSubject points to the CTL_ANY_SUBJECT_INFO structure. The
/// <c>SubjectAlgorithm</c> member of this structure must match the algorithm type of the CTL, and the <c>SubjectIdentifier</c>
/// member must match one of the CTL entries.
/// </para>
/// <para>If dwSubjectType is set to either preceding value, dwEncodingType is not used.</para>
/// </param>
/// <param name="pvSubject">Value used in conjunction with the dwSubjectType parameter.</param>
/// <param name="pSubjectUsage">A pointer to a CTL_USAGE structure used to specify the intended usage of the subject.</param>
/// <param name="dwFlags">
/// <para>
/// If the CERT_VERIFY_INHIBIT_CTL_UPDATE_FLAG is not set, a CTL whose time is no longer valid in one of the stores specified by
/// <c>rghCtlStore</c> in CTL_VERIFY_USAGE_PARA can be replaced. When replaced, the CERT_VERIFY_UPDATED_CTL_FLAG is set in the
/// <c>dwFlags</c> member of pVerifyUsageStatus. If this flag is set, an update will not be made, even if a time-valid, updated CTL
/// is received for a CTL that is in the store and whose time is no longer valid.
/// </para>
/// <para>
/// If the CERT_VERIFY_TRUSTED_SIGNERS_FLAG is set, only the signer stores specified by <c>rghSignerStore</c> in
/// CTL_VERIFY_USAGE_PARA are searched to find the signer. Otherwise, the signer stores provide additional sources to find the
/// signer's certificate. For more information, see Remarks.
/// </para>
/// <para>If CERT_VERIFY_NO_TIME_CHECK_FLAG is set, the CTLs are not checked for time validity. Otherwise, they are.</para>
/// <para>
/// If CERT_VERIFY_ALLOW_MORE_USAGE_FLAG is set, the CTL can contain usage identifiers in addition to those specified by
/// pSubjectUsage. Otherwise, the found CTL will contain no additional usage identifiers.
/// </para>
/// </param>
/// <param name="pVerifyUsagePara">
/// A pointer to a CTL_VERIFY_USAGE_PARA structure that specifies the stores to be searched to find the CTL and the stores that
/// contain acceptable CTL signers. Setting the <c>ListIdentifier</c> member further limits the search.
/// </param>
/// <param name="pVerifyUsageStatus">
/// A pointer to a CTL_VERIFY_USAGE_STATUS structure. The <c>cbSize</c> member of the structure must to be set to the size, in
/// bytes, of the structure, and all other fields must be set to zero before <c>CertVerifyCTLUsage</c> is called. For more
/// information, see <c>CTL_VERIFY_USAGE_STATUS</c>.
/// </param>
/// <returns>
/// <para>
/// If the subject is trusted for the specified usage, <c>TRUE</c> is returned. Otherwise, <c>FALSE</c> is returned. GetLastError
/// can return one of the following error codes.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>CRYPT_E_NO_VERIFY_USAGE_DLL</term>
/// <term>No DLL or exported function was found to verify subject usage.</term>
/// </item>
/// <item>
/// <term>CRYPT_E_NO_VERIFY_USAGE_CHECK</term>
/// <term>The called function was not able to do a usage check on the subject.</term>
/// </item>
/// <item>
/// <term>CRYPT_E_VERIFY_USAGE_OFFLINE</term>
/// <term>The server was offline; therefore, the called function could not complete the usage check.</term>
/// </item>
/// <item>
/// <term>CRYPT_E_NOT_IN_CTL</term>
/// <term>The subject was not found in a CTL.</term>
/// </item>
/// <item>
/// <term>CRYPT_E_NO_TRUSTED_SIGNER</term>
/// <term>No trusted signer was found to verify the signature of the message or trust list.</term>
/// </item>
/// </list>
/// <para>The <c>dwError</c> member of the CTL_VERIFY_USAGE_PARA pointed to by pVerifyUsageStatus is set to the same error code.</para>
/// </returns>
/// <remarks>
/// <para>
/// <c>CertVerifyCTLUsage</c> is a dispatcher to functions that can be installed by using an object identifier (OID). First, it
/// tries to find an OID function that matches the first usage object identifier in the CLT_USAGE structure pointed to by
/// pSubjectUsage. If this fails, it uses the default <c>CertDllVerifyCTLUsage</c> functions.
/// </para>
/// <para>The <c>CertDllVerifyCTLUsage</c> function in Cryptnet.dll can be installed by using an OID; it has the following properties:</para>
/// <list type="bullet">
/// <item>
/// <term>
/// If CTL stores are specified by <c>rghCtlStore</c> in pVerifyUsagePara, only those stores are searched to find a CTL. Otherwise,
/// the Trust system store is searched to find a CTL.
/// </term>
/// </item>
/// <item>
/// <term>
/// If CERT_VERIFY_TRUSTED_SIGNERS_FLAG is set, only the signer stores specified by <c>rghSignerStore</c> in pVerifyUsagePara are
/// searched to find the certificate that corresponds to the signer's issuer and serial number. Otherwise, the CTL message's store,
/// the signer stores specified by <c>rghSignerStore</c> in pVerifyUsagePara, the Trust system store, CA system store, ROOT, and
/// Software Publisher Certificate (SPC) system stores are searched to find the signer's certificate. In either case, the public key
/// in the found certificate is used to verify the signature of the CTL.
/// </term>
/// </item>
/// <item>
/// <term>If the CTL has a set <c>NextUpdate</c> member and CERT_VERIFY_NO_TIME_CHECK is not set, it is verified for time validity.</term>
/// </item>
/// <item>
/// <term>
/// If the CTL obtained from the store has a time that is not valid, an attempt is made to get a time-valid version. The
/// <c>CertDllVerifyCTLUsage</c> function uses the <c>NextUpdateLocation</c> property or the <c>NextUpdateLocation</c> extension of
/// the CTL, or it searches the signer's information for a <c>NextUpdateLocation</c> attribute.
/// </term>
/// </item>
/// </list>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-certverifyctlusage BOOL CertVerifyCTLUsage( DWORD
// dwEncodingType, DWORD dwSubjectType, void *pvSubject, PCTL_USAGE pSubjectUsage, DWORD dwFlags, PCTL_VERIFY_USAGE_PARA
// pVerifyUsagePara, PCTL_VERIFY_USAGE_STATUS pVerifyUsageStatus );
[DllImport(Lib.Crypt32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "d87d8157-8e52-4198-bfd4-46d83d72eb13")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CertVerifyCTLUsage(CertEncodingType dwEncodingType, CtlCertSubject dwSubjectType, [In] IntPtr pvSubject, in CTL_USAGE pSubjectUsage,
CertVerifyCTLFlags dwFlags, [In, Optional] IntPtr pVerifyUsagePara, ref CTL_VERIFY_USAGE_STATUS pVerifyUsageStatus);
/// <summary>
/// <para>The <c>CryptMsgEncodeAndSignCTL</c> function encodes a CTL and creates a signed message containing the encoded CTL.</para>
/// <para>This function first encodes the CTL pointed to by pCtlInfo and then calls CryptMsgSignCTL to sign the encoded message.</para>
/// </summary>
/// <param name="dwMsgEncodingType">
/// <para>
/// Specifies the encoding type 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</para>
/// <para>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="pCtlInfo">A pointer to the CTL_INFO structure containing the CTL to be encoded and signed.</param>
/// <param name="pSignInfo">
/// <para>A pointer to a CMSG_SIGNED_ENCODE_INFO structure that contains an array of a CMSG_SIGNER_ENCODE_INFO structures.</para>
/// <para>
/// The message can be encoded without signers if the <c>cbSize</c> member of the structure is set to the size of the structure and
/// all of the other members are set to zero.
/// </para>
/// </param>
/// <param name="dwFlags">
/// <para>
/// CMSG_ENCODE_SORTED_CTL_FLAG is set if the CTL entries are to be sorted before encoding. This flag is set if the
/// CertFindSubjectInSortedCTL or CertEnumSubjectInSortedCTL functions will be called.
/// </para>
/// <para>
/// CMSG_ENCODE_HASHED_SUBJECT_IDENTIFIER_FLAG is set if CMSG_ENCODE_SORTED_CTL_FLAG is set, and the identifier for the
/// TrustedSubjects is a hash, such as MD5 or SHA1.
/// </para>
/// <para>
/// If CMS_PKCS7 is defined, dwFlags can be set to CMSG_CMS_ENCAPSULATED_CTL_FLAG to encode a CMS compatible V3 SignedData message.
/// </para>
/// </param>
/// <param name="pbEncoded">
/// <para>A pointer to a buffer that receives the encoded, signed message created.</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="pcbEncoded">
/// A pointer to a <c>DWORD</c> that specifies the size, in bytes, of the pbEncoded buffer. When the function returns, the
/// <c>DWORD</c> contains the number of bytes stored or to be stored in the buffer.
/// </param>
/// <returns>
/// <para>If the function succeeds, the return value is nonzero ( <c>TRUE</c>).</para>
/// <para>
/// If the function fails, the return value is zero ( <c>FALSE</c>). To get extended error information, call GetLastError. Errors
/// can be propagated from calls to CryptMsgOpenToEncode and CryptMsgUpdate.
/// </para>
/// </returns>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptmsgencodeandsignctl BOOL CryptMsgEncodeAndSignCTL(
// DWORD dwMsgEncodingType, PCTL_INFO pCtlInfo, PCMSG_SIGNED_ENCODE_INFO pSignInfo, DWORD dwFlags, BYTE *pbEncoded, DWORD
// *pcbEncoded );
[DllImport(Lib.Crypt32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "5c0e9e2e-a50d-45d0-b51d-065784d1d912")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptMsgEncodeAndSignCTL(CertEncodingType dwMsgEncodingType, in CTL_INFO pCtlInfo, in CMSG_SIGNED_ENCODE_INFO pSignInfo,
CryptMsgEncodeFlags dwFlags, [Out] IntPtr pbEncoded, ref uint pcbEncoded);
/// <summary>The <c>CryptMsgGetAndVerifySigner</c> function verifies a cryptographic message's signature.</summary>
/// <param name="hCryptMsg">Handle of a cryptographic message.</param>
/// <param name="cSignerStore">Number of stores in the rghSignerStore array.</param>
/// <param name="rghSignerStore">Array of certificate store handles that can be searched for a signer's certificate.</param>
/// <param name="dwFlags">
/// <para>Indicates particular use of the function.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>CMSG_TRUSTED_SIGNER_FLAG</term>
/// <term>
/// The stores in rghSignerStore are assumed trusted and they are the only stores searched to find the certificate corresponding to
/// the signer's issuer and serial number. Otherwise, signer stores can be provided to supplement the message's store of
/// certificates. If a signer certificate is found, its public key is used to verify the message signature.
/// </term>
/// </item>
/// <item>
/// <term>CMSG_SIGNER_ONLY_FLAG</term>
/// <term>Return the signer without doing the signature verification.</term>
/// </item>
/// <item>
/// <term>CMSG_USE_SIGNER_INDEX_FLAG</term>
/// <term>
/// Only the signer specified by *pdwSignerIndex is returned. Otherwise, iterate through all the signers until a signature is
/// verified or there are no more signers.
/// </term>
/// </item>
/// </list>
/// </param>
/// <param name="ppSigner">
/// If the signature is verified, ppSigner is updated to point to the signer's certificate context. When you have finished using the
/// certificate, free the context by calling the CertFreeCertificateContext function. This parameter can be <c>NULL</c> if the
/// application has no need for the signer's certificate.
/// </param>
/// <param name="pdwSignerIndex">
/// If the signature is verified, pdwSigner is updated to point to the index of the signer in the array of signers. This parameter
/// can be <c>NULL</c> if the application has no need for the index of the signer.
/// </param>
/// <returns>
/// <para>If the function succeeds, the return value is nonzero (TRUE).</para>
/// <para>If the function fails, the return value is zero (FALSE). For extended error information, call GetLastError.</para>
/// </returns>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptmsggetandverifysigner BOOL
// CryptMsgGetAndVerifySigner( HCRYPTMSG hCryptMsg, DWORD cSignerStore, HCERTSTORE *rghSignerStore, DWORD dwFlags, PCCERT_CONTEXT
// *ppSigner, DWORD *pdwSignerIndex );
[DllImport(Lib.Crypt32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "380c9cf3-27a2-4354-b1c8-97cec33f4e44")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptMsgGetAndVerifySigner(HCRYPTMSG hCryptMsg, uint cSignerStore, [In, MarshalAs(UnmanagedType.LPArray)] HCERTSTORE[] rghSignerStore,
CryptMsgSignerFlags dwFlags, out SafePCCERT_CONTEXT ppSigner, ref uint pdwSignerIndex);
/// <summary>The <c>CryptMsgSignCTL</c> function creates a signed message containing an encoded CTL.</summary>
/// <param name="dwMsgEncodingType">
/// <para>
/// Specifies the encoding type 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</para>
/// <para>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="pbCtlContent">
/// The encoded CTL_INFO that can be a member of a CTL_CONTEXT structure or can be created using the CryptEncodeObject function.
/// </param>
/// <param name="cbCtlContent">The size, in bytes, of the content pointed to by pbCtlContent.</param>
/// <param name="pSignInfo">
/// <para>A pointer to a CMSG_SIGNED_ENCODE_INFO structure containing an array of a CMSG_SIGNER_ENCODE_INFO structures.</para>
/// <para>
/// The message can be encoded without signers if the <c>cbSize</c> member of the structure is set to the size of the structure and
/// all of the other members are set to zero.
/// </para>
/// </param>
/// <param name="dwFlags">
/// If CMS_PKCS7 is defined, can be set to CMSG_CMS_ENCAPSULATED_CTL_FLAG to encode a CMS compatible V3 SignedData message.
/// </param>
/// <param name="pbEncoded">
/// <para>A pointer to a buffer to receives the encoded message.</para>
/// <para>
/// This parameter can be <c>NULL</c> to get the size of this information for memory allocation purposes. For more information, see
/// Retrieving Data of Unknown Length.
/// </para>
/// </param>
/// <param name="pcbEncoded">
/// A pointer to a <c>DWORD</c> specifying the size, in bytes, of the pbEncoded buffer. When the function returns, the <c>DWORD</c>
/// contains the number of bytes stored or to be stored in the buffer.
/// </param>
/// <returns>
/// <para>If the function succeeds, the return value is nonzero ( <c>TRUE</c>).</para>
/// <para>
/// If the function fails, the return value is zero ( <c>FALSE</c>). For extended error information, call GetLastError. This
/// function can return errors propagated from calls to CryptMsgOpenToEncode and CryptMsgUpdate.
/// </para>
/// </returns>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptmsgsignctl BOOL CryptMsgSignCTL( DWORD
// dwMsgEncodingType, BYTE *pbCtlContent, DWORD cbCtlContent, PCMSG_SIGNED_ENCODE_INFO pSignInfo, DWORD dwFlags, BYTE *pbEncoded,
// DWORD *pcbEncoded );
[DllImport(Lib.Crypt32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("wincrypt.h", MSDNShortId = "85ae8ce3-d0a7-4fcb-beaa-ede09d30930e")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptMsgSignCTL(CertEncodingType dwMsgEncodingType, [In] IntPtr pbCtlContent, uint cbCtlContent, in CMSG_SIGNED_ENCODE_INFO pSignInfo,
CryptMsgSignFlags dwFlags, [Out] IntPtr pbEncoded, ref uint pcbEncoded);
/// <summary>
/// The <c>CERT_CHAIN_ENGINE_CONFIG</c> structure sets parameters for building a non-default certificate chain engine. The engine
/// used determines the ways that certificate chains are built.
/// </summary>
/// <remarks>
/// <para>
/// The chain-building engine uses four certificate stores in building chains. These are hRoot, hWorld, hTrust, and hOther. These
/// stores' handles are established by using information in this structure when a chain engine is created.
/// </para>
/// <para>
/// hRoot is the store handle from <c>hRestrictedRoot</c> or, if <c>hRestrictedRoot</c> is <c>NULL</c>, the handle for System Store "Root."
/// </para>
/// <para>
/// hWorld is a collection certificate store including sibling stores hRoot, "CA," "My," "Trust," and any additional stores whose
/// handles are in the array pointed to by <c>rghAdditionalStore</c>.
/// </para>
/// <para>hTrust is the store handle from <c>hRestrictedTrust</c> or, if <c>hRestrictedTrust</c> is <c>NULL</c>, hWorld.</para>
/// <para>
/// hOther is <c>hRestrictedOther</c> plus hRoot or, if <c>hRestrictedTrust</c> is non- <c>NULL</c>, the hWorld collection store
/// plus the store handle from <c>hRestrictedTrust</c>.
/// </para>
/// <para>
/// Exclusive trust mode allows applications to specify trust anchors and peer-trusted certificates for certificate chain
/// validation. In the exclusive trust mode, the root store and the trusted people store on the system are ignored, and the anchors
/// and certificates pointed to by the <c>hExclusiveRoot</c> and <c>hExclusiveTrustedPeople</c> members are used instead.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/ns-wincrypt-cert_chain_engine_config typedef struct
// _CERT_CHAIN_ENGINE_CONFIG { DWORD cbSize; HCERTSTORE hRestrictedRoot; HCERTSTORE hRestrictedTrust; HCERTSTORE hRestrictedOther;
// DWORD cAdditionalStore; HCERTSTORE *rghAdditionalStore; DWORD dwFlags; DWORD dwUrlRetrievalTimeout; DWORD
// MaximumCachedCertificates; DWORD CycleDetectionModulus; HCERTSTORE hExclusiveRoot; HCERTSTORE hExclusiveTrustedPeople; DWORD
// dwExclusiveFlags; } CERT_CHAIN_ENGINE_CONFIG, *PCERT_CHAIN_ENGINE_CONFIG;
[PInvokeData("wincrypt.h", MSDNShortId = "9e010eb9-2cbb-4fca-ba5c-4a5a50f23786")]
[StructLayout(LayoutKind.Sequential)]
public struct CERT_CHAIN_ENGINE_CONFIG
{
/// <summary>Size of this structure in bytes.</summary>
public uint cbSize;
/// <summary>
/// This configuration parameter can be used to restrict the root store. If used, it can be the handle of any HCERTSTORE
/// containing only a proper subset of the certificates in the root store.
/// </summary>
public HCERTSTORE hRestrictedRoot;
/// <summary>Store handle. If used, restricts the stores searched to find CTLs.</summary>
public HCERTSTORE hRestrictedTrust;
/// <summary>Store handle. If used, restricts the stores searched for certificates and CRLs.</summary>
public HCERTSTORE hRestrictedOther;
/// <summary>Count of additional stores to be searched for certificates and CRLs needed to build chains.</summary>
public uint cAdditionalStore;
/// <summary>A pointer to an array of store handles for any additional stores to be searched in building chains.</summary>
public IntPtr rghAdditionalStore;
/// <summary>
/// <para>The following flags are defined.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>CERT_CHAIN_CACHE_END_CERT 0x00000001</term>
/// <term>
/// Information in the end certificate is cached. By default, information in all certificates except the end certificate is
/// cached as a chain is built. Setting this flag extends the caching to the end certificate.
/// </term>
/// </item>
/// <item>
/// <term>CERT_CHAIN_CACHE_ONLY_URL_RETRIEVAL 0x00000004</term>
/// <term>Use only cached URLs in building a certificate chain. The Internet and intranet are not searched for URL-based objects.</term>
/// </item>
/// <item>
/// <term>CERT_CHAIN_USE_LOCAL_MACHINE_STORE 0x00000008</term>
/// <term>Build the chain using the LocalMachine registry location as opposed to the CurrentUser location.</term>
/// </item>
/// <item>
/// <term>CERT_CHAIN_ENABLE_CACHE_AUTO_UPDATE 0x00000010</term>
/// <term>Enable automatic updating of the cache as a chain is being built.</term>
/// </item>
/// <item>
/// <term>CERT_CHAIN_ENABLE_SHARE_STORE 0x00000020</term>
/// <term>Allow certificate stores used to build the chain to be shared.</term>
/// </item>
/// <item>
/// <term>CERT_CHAIN_DISABLE_AIA 0x00002000</term>
/// <term>Turn off Authority Information Access (AIA) retrievals explicitly.</term>
/// </item>
/// </list>
/// </summary>
public CertChainEngineFlags dwFlags;
/// <summary>
/// Number of milliseconds before a time-out for network basedURL object retrievals. Can be set to zero to use the default limit.
/// </summary>
public uint dwUrlRetrievalTimeout;
/// <summary>
/// Limit on the number of certificates that can be cached as a chain is built. Can be set to 0 to use the default limit.
/// </summary>
public uint MaximumCachedCertificates;
/// <summary>
/// <para>
/// Number of certificates added to the chain before a check is made to determine whether there is a cycle of certificates in
/// the chain. A cycle may be defined as having the same certificate in two different places in a chain.
/// </para>
/// <para>
/// The lower the number, the more frequently checks will be made. Extra checking for cycles of certificates will slow the
/// process considerably. This parameter can be set to zero to use the default limit.
/// </para>
/// </summary>
public uint CycleDetectionModulus;
/// <summary>
/// <para>
/// Handle to a certificate store that contains exclusive trust anchors. If either the <c>hExclusiveRoot</c> or
/// <c>hExclusiveTrustedPeople</c> member points to a valid store, exclusive trust mode is used for the chain building.
/// </para>
/// <para><c>Windows 7 and Windows Server 2008 R2:</c> Support for this member begins.</para>
/// </summary>
public HCERTSTORE hExclusiveRoot;
/// <summary>
/// <para>
/// Handle to a certificate store that contains application-specific peer trusted certificates. If either the
/// <c>hExclusiveRoot</c> or <c>hExclusiveTrustedPeople</c> member points to a valid store, exclusive trust mode is used for the
/// chain building.
/// </para>
/// <para><c>Windows 7 and Windows Server 2008 R2:</c> Support for this member begins.</para>
/// </summary>
public HCERTSTORE hExclusiveTrustedPeople;
/// <summary>
/// <para>
/// The following flag can be set. The flag applies only if the <c>hExclusiveRoot</c> or <c>hExclusiveTrustedPeople</c> or both
/// are not <c>NULL</c>.
/// </para>
/// <para><c>Windows 8 and Windows Server 2012:</c> Support for this member begins.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>CERT_CHAIN_EXCLUSIVE_ENABLE_CA_FLAG 0x00000001</term>
/// <term>
/// Indicates that a non-self-signed intermediate CA certificate in the hExclusiveRoot store should be treated as a trust anchor
/// during certificate validation. If a certificate chains up to this CA, chain building is terminated and the certificate is
/// considered trusted. No signature verification or revocation checking is performed on the CA certificate. By default, if this
/// flag is not set, only self-signed certificates in the hExclusiveRoot store are treated as trust anchors. See also the
/// CERT_TRUST_IS_CA_TRUSTED value in the CERT_TRUST_STATUS structure.
/// </term>
/// </item>
/// </list>
/// </summary>
public CertChainEngineExclusiveFlags dwExclusiveFlags;
}
/// <summary>
/// The <c>CERT_CHAIN_PARA</c> structure establishes the searching and matching criteria to be used in building a certificate chain.
/// </summary>
/// <remarks>
/// <para>The following remarks apply when checking for strong signatures.</para>
/// <list type="bullet">
/// <item>
/// <term>
/// Set the <c>pStrongSignPara</c> member to check for strong signatures when using the CertGetCertificateChain or
/// CertSelectCertificateChains function.
/// </term>
/// </item>
/// <item>
/// <term>
/// If a certificate without a strong signature is found in the chain, the <c>CERT_TRUST_HAS_WEAK_SIGNATURE</c> and
/// <c>CERT_TRUST_IS_NOT_SIGNATURE_VALID</c> errors are set in the <c>dwErrorStatus</c> field of the CERT_TRUST_STATUS structure.
/// The ppChainContext parameter of the CertGetCertificateChain function and the pprgpSelection parameter of the
/// CertSelectCertificateChains function point to a CERT_CHAIN_CONTEXT structure which, in turn, points to the
/// <c>CERT_TRUST_STATUS</c> structure.
/// </term>
/// </item>
/// <item>
/// <term>
/// If the chain is strong signed, the public key in the end certificate is checked to determine whether it satisfies the minimum
/// public key length requirements for a strong signature. If the condition is not satisfied, the
/// <c>CERT_TRUST_HAS_WEAK_SIGNATURE</c> and <c>CERT_TRUST_IS_NOT_SIGNATURE_VALID</c> errors are set in the <c>dwErrorStatus</c>
/// field of the CERT_TRUST_STATUS structure. Set the <c>CERT_CHAIN_STRONG_SIGN_DISABLE_END_CHECK_FLAG</c> value in the
/// <c>dwStrongSignFlags</c> member to disable this check.
/// </term>
/// </item>
/// <item>
/// <term>
/// If the <c>CERT_STRONG_SIGN_ENABLE_CRL_CHECK</c> or <c>CERT_STRONG_SIGN_ENABLE_OCSP_CHECK</c> flags are set in the
/// CERT_STRONG_SIGN_SERIALIZED_INFO structure referenced by the CERT_STRONG_SIGN_PARA structure pointed to by the
/// <c>pStrongSignPara</c> member, and a CRL or OCSP response is found without a strong signature, the CRL or OCSP response will be
/// treated as being offline. That is, the <c>CERT_TRUST_IS_OFFLINE_REVOCATION</c> and <c>CERT_TRUST_REVOCATION_STATUS_UNKNOWN</c>
/// errors are set in the <c>dwErrorStatus</c> field of the CERT_TRUST_STATUS structure. Also, the <c>dwRevocationResult</c> member
/// of the CERT_REVOCATION_INFO structure is set to <c>NTE_BAD_ALGID</c>.
/// </term>
/// </item>
/// </list>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/ns-wincrypt-cert_chain_para typedef struct _CERT_CHAIN_PARA { DWORD
// cbSize; CERT_USAGE_MATCH RequestedUsage; CERT_USAGE_MATCH RequestedIssuancePolicy; DWORD dwUrlRetrievalTimeout; BOOL
// fCheckRevocationFreshnessTime; DWORD dwRevocationFreshnessTime; LPFILETIME pftCacheResync; PCCERT_STRONG_SIGN_PARA
// pStrongSignPara; DWORD dwStrongSignFlags; } CERT_CHAIN_PARA, *PCERT_CHAIN_PARA;
[PInvokeData("wincrypt.h", MSDNShortId = "86094e1c-be59-4a15-a05b-21769f80e653")]
[StructLayout(LayoutKind.Sequential)]
public struct CERT_CHAIN_PARA
{
/// <summary>The size, in bytes, of this structure.</summary>
public uint cbSize;
/// <summary>
/// Structure indicating the kind of matching necessary to find issuer certificates for building a certificate chain. The
/// structure pointed to indicates whether AND or OR logic is to be used in the matching process. The structure also includes an
/// array of OIDs to be matched.
/// </summary>
public CERT_USAGE_MATCH RequestedUsage;
/// <summary>
/// <para>
/// Optional structure that indicates the kind of issuance policy constraint matching that applies when building a certificate
/// chain. The structure pointed to indicates whether AND or OR logic is to be used in the matching process. The structure also
/// includes an array of OIDs to be matched.
/// </para>
/// <para>
/// <c>Note</c> This member can be used only if <c>CERT_CHAIN_PARA_HAS_EXTRA_FIELDS</c> is defined by using the <c>#define</c>
/// directive before including Wincrypt.h. If this value is defined, the application must zero all unused fields.
/// </para>
/// </summary>
public CERT_USAGE_MATCH RequestedIssuancePolicy;
/// <summary>
/// <para>Optional time, in milliseconds, before revocation checking times out. This member is optional.</para>
/// <para>
/// <c>Note</c> This member can be used only if <c>CERT_CHAIN_PARA_HAS_EXTRA_FIELDS</c> is defined by using the <c>#define</c>
/// directive before including Wincrypt.h. If this value is defined, the application must zero all unused fields.
/// </para>
/// </summary>
public uint dwUrlRetrievalTimeout;
/// <summary>
/// <para>
/// Optional member. When this flag is <c>TRUE</c>, an attempt is made to retrieve a new CRL if this update is greater than or
/// equal to the current system time minus the <c>dwRevocationFreshnessTime</c> value. If this flag is not set, the CRL's next
/// update time is used.
/// </para>
/// <para>
/// <c>Note</c> This member can be used only if <c>CERT_CHAIN_PARA_HAS_EXTRA_FIELDS</c> is defined by using the <c>#define</c>
/// directive before including Wincrypt.h. If this value is defined, the application must zero all unused fields.
/// </para>
/// </summary>
[MarshalAs(UnmanagedType.Bool)] public bool fCheckRevocationFreshnessTime;
/// <summary>
/// <para>The current time, in seconds, minus the CRL's update time of all elements checked.</para>
/// <para>
/// <c>Note</c> This member can be used only if <c>CERT_CHAIN_PARA_HAS_EXTRA_FIELDS</c> is defined by using the <c>#define</c>
/// directive before including Wincrypt.h. If this value is defined, the application must zero all unused fields.
/// </para>
/// </summary>
public uint dwRevocationFreshnessTime;
/// <summary>
/// <para>
/// Optional member. When set to a non- <c>NULL</c> value, information cached before the time specified is considered to be not
/// valid and cache resynchronization is performed.
/// </para>
/// <para><c>Windows Vista:</c> Support for this member begins.</para>
/// <para>
/// <c>Note</c> This member can be used only if <c>CERT_CHAIN_PARA_HAS_EXTRA_FIELDS</c> is defined by using the <c>#define</c>
/// directive before including Wincrypt.h. If this value is defined, the application must zero all unused fields.
/// </para>
/// </summary>
public IntPtr pftCacheResync;
/// <summary>
/// <para>Optional. Specify a pointer to a CERT_STRONG_SIGN_PARA structure to enable strong signature checking.</para>
/// <para><c>Windows 8 and Windows Server 2012:</c> Support for this member begins.</para>
/// <para>
/// <c>Note</c> This member can be used only if <c>CERT_CHAIN_PARA_HAS_EXTRA_FIELDS</c> is defined by using the <c>#define</c>
/// directive before including Wincrypt.h. If this value is defined, the application must zero all unused fields.
/// </para>
/// </summary>
public IntPtr pStrongSignPara;
/// <summary>
/// <para>Optional flags that modify chain retrieval behavior. This can be zero or the following value.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>CERT_CHAIN_STRONG_SIGN_DISABLE_END_CHECK_FLAG 0x00000001</term>
/// <term>
/// If the chain is strong signed, the public key in the end certificate will be checked to verify whether it satisfies the
/// minimum public key length requirements for a strong signature. You can specify CERT_CHAIN_STRONG_SIGN_DISABLE_END_CHECK_FLAG
/// to disable default checking.
/// </term>
/// </item>
/// </list>
/// <para><c>Windows 8 and Windows Server 2012:</c> Support for this property begins.</para>
/// <para>
/// <c>Note</c> This member can be used only if <c>CERT_CHAIN_PARA_HAS_EXTRA_FIELDS</c> is defined by using the <c>#define</c>
/// directive before including Wincrypt.h. If this value is defined, the application must zero all unused fields.
/// </para>
/// </summary>
public uint dwStrongSignFlags;
}
/// <summary>
/// The <c>CERT_CHAIN_POLICY_PARA</c> structure contains information used in CertVerifyCertificateChainPolicy to establish policy
/// criteria for the verification of certificate chains.
/// </summary>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/ns-wincrypt-cert_chain_policy_para typedef struct
// _CERT_CHAIN_POLICY_PARA { DWORD cbSize; DWORD dwFlags; void *pvExtraPolicyPara; } CERT_CHAIN_POLICY_PARA, *PCERT_CHAIN_POLICY_PARA;
[PInvokeData("wincrypt.h", MSDNShortId = "5e4fffcb-132b-42c0-81b2-9f866e274c32")]
[StructLayout(LayoutKind.Sequential)]
public struct CERT_CHAIN_POLICY_PARA
{
/// <summary>The size, in bytes, of this structure.</summary>
public uint cbSize;
/// <summary>
/// <para>
/// A set of flags that indicate conditions that could potentially be not valid and that are to be ignored in building
/// certificate chains.
/// </para>
/// <para>The pszPolicyOID parameter of the CertVerifyCertificateChainPolicy function can contain one of the following values:</para>
/// <list type="bullet">
/// <item>
/// <term><c>CERT_CHAIN_POLICY_BASE</c></term>
/// </item>
/// <item>
/// <term><c>CERT_CHAIN_POLICY_AUTHENTICODE</c></term>
/// </item>
/// <item>
/// <term><c>CERT_CHAIN_POLICY_AUTHENTICODE_TS</c></term>
/// </item>
/// <item>
/// <term><c>CERT_CHAIN_POLICY_SSL</c></term>
/// </item>
/// <item>
/// <term><c>CERT_CHAIN_POLICY_NT_AUTH</c></term>
/// </item>
/// </list>
/// <para>If the</para>
/// <para>pszPolicyOID</para>
/// <para>parameter of the</para>
/// <para>CertVerifyCertificateChainPolicy</para>
/// <para>
/// function contains one of the preceding values, then this member 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_CHAIN_POLICY_IGNORE_NOT_TIME_VALID_FLAG</term>
/// <term>Ignore not time valid errors.</term>
/// </item>
/// <item>
/// <term>CERT_CHAIN_POLICY_IGNORE_CTL_NOT_TIME_VALID_FLAG</term>
/// <term>Ignore certificate trust list (CTL) not time valid errors.</term>
/// </item>
/// <item>
/// <term>CERT_CHAIN_POLICY_IGNORE_NOT_TIME_NESTED_FLAG</term>
/// <term>Ignore time nesting errors.</term>
/// </item>
/// <item>
/// <term>CERT_CHAIN_POLICY_IGNORE_ALL_NOT_TIME_VALID_FLAGS</term>
/// <term>Ignore all time validity errors.</term>
/// </item>
/// <item>
/// <term>CERT_CHAIN_POLICY_IGNORE_INVALID_BASIC_CONSTRAINTS_FLAG</term>
/// <term>Ignore basic constraint errors.</term>
/// </item>
/// <item>
/// <term>CERT_CHAIN_POLICY_ALLOW_UNKNOWN_CA_FLAG</term>
/// <term>Allow untrusted roots.</term>
/// </item>
/// <item>
/// <term>CERT_CHAIN_POLICY_IGNORE_WRONG_USAGE_FLAG</term>
/// <term>Ignore invalid usage errors.</term>
/// </item>
/// <item>
/// <term>CERT_CHAIN_POLICY_IGNORE_INVALID_NAME_FLAG</term>
/// <term>Ignore invalid name errors.</term>
/// </item>
/// <item>
/// <term>CERT_CHAIN_POLICY_IGNORE_INVALID_POLICY_FLAG</term>
/// <term>Ignore invalid policy errors.</term>
/// </item>
/// <item>
/// <term>CERT_CHAIN_POLICY_IGNORE_END_REV_UNKNOWN_FLAG</term>
/// <term>Ignores errors in obtaining valid revocation information.</term>
/// </item>
/// <item>
/// <term>CERT_CHAIN_POLICY_IGNORE_CTL_SIGNER_REV_UNKNOWN_FLAG</term>
/// <term>Ignores errors in obtaining valid CTL revocation information.</term>
/// </item>
/// <item>
/// <term>CERT_CHAIN_POLICY_IGNORE_CA_REV_UNKNOWN_FLAG</term>
/// <term>Ignores errors in obtaining valid certification authority (CA) revocation information.</term>
/// </item>
/// <item>
/// <term>CERT_CHAIN_POLICY_IGNORE_ROOT_REV_UNKNOWN_FLAG</term>
/// <term>Ignores errors in obtaining valid root revocation information.</term>
/// </item>
/// <item>
/// <term>CERT_CHAIN_POLICY_IGNORE_ALL_REV_UNKNOWN_FLAGS</term>
/// <term>Ignores errors in obtaining valid revocation information.</term>
/// </item>
/// <item>
/// <term>CERT_CHAIN_POLICY_ALLOW_TESTROOT_FLAG</term>
/// <term>Allow untrusted test roots.</term>
/// </item>
/// <item>
/// <term>CERT_CHAIN_POLICY_TRUST_TESTROOT_FLAG</term>
/// <term>Always trust test roots.</term>
/// </item>
/// <item>
/// <term>CERT_CHAIN_POLICY_IGNORE_NOT_SUPPORTED_CRITICAL_EXT_FLAG</term>
/// <term>Ignore critical extension not supported errors.</term>
/// </item>
/// <item>
/// <term>CERT_CHAIN_POLICY_IGNORE_PEER_TRUST_FLAG</term>
/// <term>Ignore peer trusts.</term>
/// </item>
/// </list>
/// <para>
/// If the pszPolicyOID parameter of the CertVerifyCertificateChainPolicy function contains
/// <c>CERT_CHAIN_POLICY_BASIC_CONSTRAINTS</c>, this member 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_CHAIN_POLICY_IGNORE_PEER_TRUST_FLAG</term>
/// <term>Ignore peer trusts.</term>
/// </item>
/// <item>
/// <term>BASIC_CONSTRAINTS_CERT_CHAIN_POLICY_CA_FLAG</term>
/// <term>Checks if the first certificate element is a CA.</term>
/// </item>
/// <item>
/// <term>BASIC_CONSTRAINTS_CERT_CHAIN_POLICY_END_ENTITY_FLAG</term>
/// <term>Checks if the first certificate element is an end entity.</term>
/// </item>
/// </list>
/// <para>
/// If the pszPolicyOID parameter of the CertVerifyCertificateChainPolicy function contains
/// <c>CERT_CHAIN_POLICY_MICROSOFT_ROOT</c>, this member can be zero or the following value.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>MICROSOFT_ROOT_CERT_CHAIN_POLICY_ENABLE_TEST_ROOT_FLAG</term>
/// <term>Also check for the Microsoft test roots in addition to the Microsoft public root.</term>
/// </item>
/// </list>
/// </summary>
public CertChainPolicyFlags dwFlags;
/// <summary>The address of a pszPolicyOID-specific structure that provides additional validity policy conditions.</summary>
public IntPtr pvExtraPolicyPara;
}
/// <summary>
/// The <c>CERT_CHAIN_POLICY_STATUS</c> structure holds certificate chain status information returned by the
/// CertVerifyCertificateChainPolicy function when the certificate chains are validated.
/// </summary>
/// <remarks>
/// If both <c>lChainIndex</c> and <c>lElementIndex</c> are set to 1, the error or condition that is not valid applies to the whole
/// chain context. If only <c>lElementIndex</c> is set to 1, the error or condition that is not valid applies to the chain indexed
/// by <c>lChainIndex</c>. Otherwise, the error or condition that is not valid applies to the certificate element at
/// pChainContext-&gt;rgpChain[ <c>lChainIndex</c>]-&gt;rgpElement[ <c>lElementIndex</c>].
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/ns-wincrypt-cert_chain_policy_status typedef struct
// _CERT_CHAIN_POLICY_STATUS { DWORD cbSize; DWORD dwError; LONG lChainIndex; LONG lElementIndex; void *pvExtraPolicyStatus; }
// CERT_CHAIN_POLICY_STATUS, *PCERT_CHAIN_POLICY_STATUS;
[PInvokeData("wincrypt.h", MSDNShortId = "599a09b6-fe9e-4489-99ae-8a88fa78a660")]
[StructLayout(LayoutKind.Sequential)]
public struct CERT_CHAIN_POLICY_STATUS
{
/// <summary>The size, in bytes, of this structure.</summary>
public uint cbSize;
/// <summary>
/// <para>
/// A value that indicates that an error or invalid condition was encountered during the validation process. The values of this
/// member are specific to the policy type as specified by the value of the pszPolicyOID parameter of the
/// CertVerifyCertificateChainPolicy function.
/// </para>
/// <para>Base Policy errors ( <c>CERT_CHAIN_POLICY_BASE</c>)</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>TRUST_E_CERT_SIGNATURE 0x80096004L</term>
/// <term>The signature of the certificate cannot be verified.</term>
/// </item>
/// <item>
/// <term>CRYPT_E_REVOKED 0x80092010L</term>
/// <term>The certificate or signature has been revoked.</term>
/// </item>
/// <item>
/// <term>CERT_E_UNTRUSTEDROOT 0x800B0109L</term>
/// <term>A certification chain processed correctly but terminated in a root certificate that is not trusted by the trust provider.</term>
/// </item>
/// <item>
/// <term>CERT_E_UNTRUSTEDTESTROOT 0x800B010DL</term>
/// <term>The root certificate is a testing certificate, and policy settings disallow test certificates.</term>
/// </item>
/// <item>
/// <term>CERT_E_CHAINING 0x800B010AL</term>
/// <term>A chain of certificates was not correctly created.</term>
/// </item>
/// <item>
/// <term>CERT_E_WRONG_USAGE 0x800B0110L</term>
/// <term>The certificate is not valid for the requested usage.</term>
/// </item>
/// <item>
/// <term>CERT_E_EXPIRED 0x800B0101L</term>
/// <term>A required certificate is not within its validity period.</term>
/// </item>
/// <item>
/// <term>CERT_E_INVALID_NAME 0x800B0114L</term>
/// <term>The certificate has an invalid name. Either the name is not included in the permitted list, or it is explicitly excluded.</term>
/// </item>
/// <item>
/// <term>CERT_E_INVALID_POLICY 0x800B0113L</term>
/// <term>The certificate has an invalid policy.</term>
/// </item>
/// <item>
/// <term>TRUST_E_BASIC_CONSTRAINTS 0x80096019L</term>
/// <term>The basic constraints of the certificate are not valid, or they are missing.</term>
/// </item>
/// <item>
/// <term>CERT_E_CRITICAL 0x800B0105L</term>
/// <term>The certificate is being used for a purpose other than the purpose specified by its CA.</term>
/// </item>
/// <item>
/// <term>CERT_E_VALIDITYPERIODNESTING 0x800B0102L</term>
/// <term>The validity periods of the certification chain do not nest correctly.</term>
/// </item>
/// <item>
/// <term>CRYPT_E_NO_REVOCATION_CHECK 0x80092012L</term>
/// <term>The revocation function was unable to check revocation for the certificate.</term>
/// </item>
/// <item>
/// <term>CRYPT_E_REVOCATION_OFFLINE 0x80092013L</term>
/// <term>The revocation function was unable to check revocation because the revocation server was offline.</term>
/// </item>
/// </list>
/// <para>Basic Constraints Policy errors ( <c>CERT_CHAIN_POLICY_BASIC_CONSTRAINTS</c>).</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>TRUST_E_BASIC_CONSTRAINTS 0x80096019L</term>
/// <term>The basic constraints of the certificate are not valid, or they are missing.</term>
/// </item>
/// </list>
/// <para>Authenticode Policy errors ( <c>CERT_CHAIN_POLICY_AUTHENTICODE</c> and <c>CERT_CHAIN_POLICY_AUTHENTICODE_TS</c>).</para>
/// <para>These errors are in addition to the Base Policy errors.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>CERT_E_PURPOSE 0x800B0106L</term>
/// <term>The certificate is being used for a purpose other than one specified by the issuing CA.</term>
/// </item>
/// <item>
/// <term>CERT_E_REVOKED 0x800B010CL</term>
/// <term>The certificate has been explicitly revoked by the issuer.</term>
/// </item>
/// <item>
/// <term>CERT_E_REVOCATION_FAILURE 0x800B010EL</term>
/// <term>The revocation process could not continue, and the certificate could not be checked.</term>
/// </item>
/// </list>
/// <para>SSL Policy errors ( <c>CERT_CHAIN_POLICY_SSL</c>).</para>
/// <para>These errors are in addition to the Base Policy errors.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>CERT_E_UNTRUSTEDROOT 0x800B0109L</term>
/// <term>A certification chain processed correctly but terminated in a root certificate that is not trusted by the trust provider.</term>
/// </item>
/// <item>
/// <term>CERT_E_CN_NO_MATCH 0x800B010FL</term>
/// <term>The certificate's CN name does not match the passed value.</term>
/// </item>
/// <item>
/// <term>CERT_E_PURPOSE 0x800B0106L</term>
/// <term>The certificate is being used for a purpose other than the purposes specified by its CA.</term>
/// </item>
/// <item>
/// <term>CERT_E_ROLE 0x800B0103L</term>
/// <term>A certificate that can only be used as an end-entity is being used as a CA or vice versa.</term>
/// </item>
/// </list>
/// <para>Microsoft Root Policy errors ( <c>CERT_CHAIN_POLICY_MICROSOFT_ROOT</c>).</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>CERT_E_UNTRUSTEDROOT 0x800B0109L</term>
/// <term>A certification chain processed correctly but terminated in a root certificate that is not trusted by the trust provider.</term>
/// </item>
/// </list>
/// <para>EV Policy errors.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>CERT_E_CHAINING 0x800B010AL</term>
/// <term>The certificate chain to a trusted root authority could not be built.</term>
/// </item>
/// <item>
/// <term>CERT_E_WRONG_USAGE 0x800B0110L</term>
/// <term>The certificate is not valid for the requested usage.</term>
/// </item>
/// </list>
/// </summary>
public uint dwError;
/// <summary>
/// Index that indicates the chain in which an error or condition that is not valid was found. For more information, see Remarks.
/// </summary>
public int lChainIndex;
/// <summary>
/// Index that indicates the element in a chain where an error or condition that is not valid was found. For more information,
/// see Remarks.
/// </summary>
public int lElementIndex;
/// <summary>
/// A pointer to a structure. The structure type is determined by the value of the <c>pszPolicyOID</c> parameter of the
/// CertVerifyCertificateChainPolicy function. In addition to <c>dwError</c> errors, policy OIDspecific extra status can also
/// be returned here to provide additional chain status information. This pointer can be optionally set to point to an
/// AUTHENTICODE_EXTRA_CERT_CHAIN_POLICY_STATUS structure.
/// </summary>
public IntPtr pvExtraPolicyStatus;
}
/// <summary>
/// The <c>CERT_USAGE_MATCH</c> structure provides criteria for identifying issuer certificates to be used to build a certificate chain.
/// </summary>
/// <remarks>
/// <para>If the dwType member is set to <c>USAGE_MATCH_TYPE_OR</c>, the Usage member cannot be empty.</para>
/// <para>
/// If the dwType member is set to <c>USAGE_MATCH_TYPE_AND</c>, an empty Usage member means that any nested usage in the chain will work.
/// </para>
/// <para>The following describes the behavior given two enhanced key usage (EKU) extensions EKU A and EKU B.</para>
/// <para>AND Logic</para>
/// <para>
/// If the caller specifies EKU A AND EKU B then the target certificate is valid if EKU A and EKU B are supported by every
/// certificate in the path (either by an explicit EKU setting or through an absent EKU extension in CA certificates.)
/// </para>
/// <para>OR Logic</para>
/// <para>
/// If the caller specifies EKU A OR EKU B then the target certificate is valid if either EKU A or EKU B is supported in the path.
/// </para>
/// <para>
/// Besides the simple case where the certificates in the path contain EKU A or EKU B, the <c>OR</c> clause has the following
/// special evaluation.
/// </para>
/// <para>Given the following path, the <c>OR</c> test is deemed valid:</para>
/// <para>
/// Although the intersection of the EKUs in the chain is an empty set, the use of the EE certificate is valid for EKU A because the
/// request to the cryptography API specifies that the certificate is valid if each certificate of the path supports either EKU A OR
/// EKU B.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/ns-wincrypt-cert_usage_match typedef struct _CERT_USAGE_MATCH { DWORD
// dwType; CERT_ENHKEY_USAGE Usage; } CERT_USAGE_MATCH, *PCERT_USAGE_MATCH;
[PInvokeData("wincrypt.h", MSDNShortId = "6154f1f7-4293-4b8e-91ab-9f57bb6f5743")]
[StructLayout(LayoutKind.Sequential)]
public struct CERT_USAGE_MATCH
{
/// <summary>
/// <para>
/// Determines the kind of issuer matching to be done. In <c>AND</c> logic, the certificate must meet all criteria. In <c>OR</c>
/// logic, the certificate must meet at least one of the criteria. The following codes are defined to determine the logic used
/// in the match. For more information about how this applied, see Remarks.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>USAGE_MATCH_TYPE_AND</term>
/// <term>AND logic</term>
/// </item>
/// <item>
/// <term>USAGE_MATCH_TYPE_OR</term>
/// <term>OR logic</term>
/// </item>
/// </list>
/// <para>Default usage match logic is USAGE_MATCH_TYPE_AND.</para>
/// </summary>
public UsageMatchType dwType;
/// <summary>
/// CERT_ENHKEY_USAGE structure ( <c>CERT_ENHKEY_USAGE</c> is an alternate typedef name for the <c>CTL_USAGE</c> structure) that
/// includes an array of certificate object identifiers (OIDs) that a certificate must match in order to be valid.
/// </summary>
public CTL_USAGE Usage;
}
/// <summary>
/// The <c>CMSG_SIGNED_ENCODE_INFO</c> structure contains information to be passed to CryptMsgOpenToEncode if dwMsgType is CMSG_SIGNED.
/// </summary>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/ns-wincrypt-cmsg_signed_encode_info typedef struct
// _CMSG_SIGNED_ENCODE_INFO { DWORD cbSize; DWORD cSigners; PCMSG_SIGNER_ENCODE_INFO rgSigners; DWORD cCertEncoded; PCERT_BLOB
// rgCertEncoded; DWORD cCrlEncoded; PCRL_BLOB rgCrlEncoded; DWORD cAttrCertEncoded; PCERT_BLOB rgAttrCertEncoded; }
// CMSG_SIGNED_ENCODE_INFO, *PCMSG_SIGNED_ENCODE_INFO;
[PInvokeData("wincrypt.h", MSDNShortId = "93138744-8316-461b-908a-1eab47e83f63")]
[StructLayout(LayoutKind.Sequential)]
public struct CMSG_SIGNED_ENCODE_INFO
{
/// <summary>Size of this structure in bytes.</summary>
public uint cbSize;
/// <summary>Number of elements in the <c>rgSigners</c> array.</summary>
public uint cSigners;
/// <summary>Array of pointers to CMSG_SIGNER_ENCODE_INFOstructures each holding signer information.</summary>
public IntPtr rgSigners;
/// <summary>Number of elements in the <c>rgCertEncoded</c> array.</summary>
public uint cCertEncoded;
/// <summary>Array of pointers to CERT_BLOB structures, each containing an encoded certificate.</summary>
public IntPtr rgCertEncoded;
/// <summary>Number of elements in the <c>rgCrlEncoded</c> array.</summary>
public uint cCrlEncoded;
/// <summary>Array of pointers to CRL_BLOB structures, each containing an encoded CRL.</summary>
public IntPtr rgCrlEncoded;
/// <summary>
/// Number of elements in the <c>rgAttrCertEncoded</c> array. Used only if CMSG_SIGNED_ENCODE_INFO_HAS_CMS_FIELDS is defined.
/// </summary>
public uint cAttrCertEncoded;
/// <summary>
/// Array of encoded attribute certificates. Used only if CMSG_SIGNED_ENCODE_INFO_HAS_CMS_FIELDS is defined. This array of
/// encoded attribute certificates can be used with CMS for PKCS #7 processing.
/// </summary>
public IntPtr rgAttrCertEncoded;
}
/// <summary>
/// The <c>CTL_VERIFY_USAGE_PARA</c> structure contains parameters used by CertVerifyCTLUsage to establish the validity of a CTL's usage.
/// </summary>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/ns-wincrypt-ctl_verify_usage_para typedef struct
// _CTL_VERIFY_USAGE_PARA { DWORD cbSize; CRYPT_DATA_BLOB ListIdentifier; DWORD cCtlStore; HCERTSTORE *rghCtlStore; DWORD
// cSignerStore; HCERTSTORE *rghSignerStore; } CTL_VERIFY_USAGE_PARA, *PCTL_VERIFY_USAGE_PARA;
[PInvokeData("wincrypt.h", MSDNShortId = "bf9a3c81-f8c4-45a6-b045-8cbefebebbd3")]
[StructLayout(LayoutKind.Sequential)]
public struct CTL_VERIFY_USAGE_PARA
{
/// <summary>Size of this structure in bytes.</summary>
public uint cbSize;
/// <summary>
/// <para>
/// BLOB that specifies a <c>ListIdentifier</c> of a CTL to be found or verified. Normally the <c>cbData</c> member of the
/// <c>ListIdentifier</c> BLOB will be zero, indicating that a CTL with any <c>ListIdentifier</c> can be a match.
/// </para>
/// <para>
/// To match only CTLs with no <c>ListIdentifier</c>, the <c>cbData</c> member of the <c>ListIdentifier</c> BLOB is set to CTL_FIND_NO_LIST_ID_CBDATA.
/// </para>
/// <para>
/// If an issuer creates multiple CTLs for the same <c>SubjectUsage</c>, a <c>ListIdentifier</c> can distinguish among them.
/// </para>
/// </summary>
public CRYPTOAPI_BLOB ListIdentifier;
/// <summary>The count of stores to be searched for a matching CTL.</summary>
public uint cCtlStore;
/// <summary>Array of handles of stores to be searched to find a matching CTL.</summary>
public IntPtr rghCtlStore;
/// <summary>Count of stores to be searched for acceptable CTL signers.</summary>
public uint cSignerStore;
/// <summary>Array of handles of stores to be searched for acceptable CTL signers.</summary>
public IntPtr rghSignerStore;
}
/// <summary>
/// The <c>CTL_VERIFY_USAGE_STATUS</c> structure contains information about a Certificate Trust List (CTL) returned by CertVerifyCTLUsage.
/// </summary>
/// <remarks>
/// The members <c>dwError</c>, <c>dwFlags</c>, <c>dwCtlEntryIndex</c>, and <c>dwSignerIndex</c> should be initialized to zero by
/// the calling application.
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/ns-wincrypt-ctl_verify_usage_status typedef struct
// _CTL_VERIFY_USAGE_STATUS { DWORD cbSize; DWORD dwError; DWORD dwFlags; PCCTL_CONTEXT *ppCtl; DWORD dwCtlEntryIndex;
// PCCERT_CONTEXT *ppSigner; DWORD dwSignerIndex; } CTL_VERIFY_USAGE_STATUS, *PCTL_VERIFY_USAGE_STATUS;
[PInvokeData("wincrypt.h", MSDNShortId = "2b7ef953-9422-4dcf-b293-a78a06bb080e")]
[StructLayout(LayoutKind.Sequential)]
public struct CTL_VERIFY_USAGE_STATUS
{
/// <summary>
/// The size, in bytes, of the structure. The application calling CertVerifyCTLUsage sets this parameter. If <c>cbSize</c> is
/// not greater than or equal to the required size of the structure, <c>CertVerifyCTLUsage</c> returns <c>FALSE</c> and
/// GetLastError returns <c>E_INVALIDARG</c>.
/// </summary>
public uint cbSize;
/// <summary>
/// The error status, if any, returned by the call to CertVerifyCTLUsage. For the list of possible error values, see the Return
/// Values section in <c>CertVerifyCTLUsage</c>.
/// </summary>
public uint dwError;
/// <summary>
/// If <c>CERT_VERIFY_UPDATED_CTL_FLAG</c> is returned, CertVerifyCTLUsage updated a CTL whose time was no longer valid with a
/// new, time-valid CTL.
/// </summary>
public CtlVerifyUsageStatusFlags dwFlags;
/// <summary>
/// <para>
/// Pointer to a pointer to a CTL context containing the matched subject. The calling application can set this pointer to
/// <c>NULL</c> to indicate that a CTL containing the subject is not to be returned.
/// </para>
/// <para>If <c>ppCtl</c> is not <c>NULL</c>, the calling application must free the returned context using CertFreeCTLContext.</para>
/// </summary>
public IntPtr ppCtl;
/// <summary>Returns the array location of the matching subject's entry in the CTL's array.</summary>
public uint dwCtlEntryIndex;
/// <summary>
/// <para>
/// A pointer to a pointer to the certificate context of the signer of the CTL. This pointer can be set to <c>NULL</c> by the
/// calling application indicating that the certificate of the signer of the CTL is not to be returned.
/// </para>
/// <para>If <c>ppSigner</c> is not <c>NULL</c>, the calling application must free the returned context using CertFreeCTLContext.</para>
/// </summary>
public IntPtr ppSigner;
/// <summary>Index of the signer actually used. Needed if a message has more than one signer.</summary>
public uint dwSignerIndex;
}
/// <summary>Provides a handle to a CERT_CHAIN_CONTEXT.</summary>
[StructLayout(LayoutKind.Sequential)]
public struct PCCERT_CHAIN_CONTEXT : IHandle
{
private IntPtr handle;
/// <summary>Initializes a new instance of the <see cref="PCCERT_CHAIN_CONTEXT"/> struct.</summary>
/// <param name="preexistingHandle">An <see cref="IntPtr"/> object that represents the pre-existing handle to use.</param>
public PCCERT_CHAIN_CONTEXT(IntPtr preexistingHandle) => handle = preexistingHandle;
/// <summary>Returns an invalid handle by instantiating a <see cref="PCCERT_CHAIN_CONTEXT"/> object with <see cref="IntPtr.Zero"/>.</summary>
public static PCCERT_CHAIN_CONTEXT NULL => new PCCERT_CHAIN_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_CHAIN_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_CHAIN_CONTEXT h) => h.handle;
/// <summary>Performs an explicit conversion from <see cref="PCCERT_CHAIN_CONTEXT"/> to <see cref="CERT_CHAIN_CONTEXT"/>.</summary>
/// <param name="h">The <see cref="PCCERT_CHAIN_CONTEXT"/> instance.</param>
/// <returns>The resulting <see cref="CERT_CHAIN_CONTEXT"/> instance from the conversion.</returns>
public static explicit operator CERT_CHAIN_CONTEXT(PCCERT_CHAIN_CONTEXT h) => h.handle.ToStructure<CERT_CHAIN_CONTEXT>();
/// <summary>Performs an implicit conversion from <see cref="IntPtr"/> to <see cref="PCCERT_CHAIN_CONTEXT"/>.</summary>
/// <param name="h">The pointer to a handle.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator PCCERT_CHAIN_CONTEXT(IntPtr h) => new PCCERT_CHAIN_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_CHAIN_CONTEXT h1, PCCERT_CHAIN_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_CHAIN_CONTEXT h1, PCCERT_CHAIN_CONTEXT h2) => h1.Equals(h2);
/// <inheritdoc/>
public override bool Equals(object obj) => obj is PCCERT_CHAIN_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="HCERTCHAINENGINE"/> that is disposed using <see cref="CertFreeCertificateChainEngine"/>.</summary>
public class SafeHCERTCHAINENGINE : SafeHANDLE
{
/// <summary>Initializes a new instance of the <see cref="SafeHCERTCHAINENGINE"/> 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 SafeHCERTCHAINENGINE(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { }
/// <summary>Initializes a new instance of the <see cref="SafeHCERTCHAINENGINE"/> class.</summary>
private SafeHCERTCHAINENGINE() : base() { }
/// <summary>Performs an implicit conversion from <see cref="SafeHCERTCHAINENGINE"/> to <see cref="HCERTCHAINENGINE"/>.</summary>
/// <param name="h">The safe handle instance.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator HCERTCHAINENGINE(SafeHCERTCHAINENGINE h) => h.handle;
/// <inheritdoc/>
protected override bool InternalReleaseHandle() { CertFreeCertificateChainEngine(handle); return true; }
}
/// <summary>Provides a <see cref="SafeHandle"/> for <see cref="PCCERT_CHAIN_CONTEXT"/> that is disposed using <see cref="CertFreeCertificateChain"/>.</summary>
public class SafePCCERT_CHAIN_CONTEXT : SafeHANDLE
{
/// <summary>Initializes a new instance of the <see cref="SafePCCERT_CHAIN_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_CHAIN_CONTEXT(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { }
/// <summary>Initializes a new instance of the <see cref="SafePCCERT_CHAIN_CONTEXT"/> class.</summary>
private SafePCCERT_CHAIN_CONTEXT() : base() { }
/// <summary>Performs an implicit conversion from <see cref="SafePCCERT_CHAIN_CONTEXT"/> to <see cref="PCCERT_CHAIN_CONTEXT"/>.</summary>
/// <param name="h">The safe handle instance.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator PCCERT_CHAIN_CONTEXT(SafePCCERT_CHAIN_CONTEXT h) => h.handle;
/// <summary>Performs an explicit conversion from <see cref="SafePCCERT_CHAIN_CONTEXT"/> to <see cref="CERT_CHAIN_CONTEXT"/>.</summary>
/// <param name="h">The safe handle instance.</param>
/// <returns>The resulting <see cref="CERT_CHAIN_CONTEXT"/> instance from the conversion.</returns>
public static explicit operator CERT_CHAIN_CONTEXT(SafePCCERT_CHAIN_CONTEXT h) => h.handle.ToStructure<CERT_CHAIN_CONTEXT>();
2020-03-09 11:54:19 -04:00
/// <inheritdoc/>
protected override bool InternalReleaseHandle() { CertFreeCertificateChain(handle); return true; }
}
/// <summary>Predefined verify chain policies.</summary>
public static class CertVerifyChainPolicy
{
/// <summary/>
public const int CERT_CHAIN_POLICY_BASE = 1;
/// <summary/>
public const int CERT_CHAIN_POLICY_AUTHENTICODE = 2;
/// <summary/>
public const int CERT_CHAIN_POLICY_AUTHENTICODE_TS = 3;
/// <summary/>
public const int CERT_CHAIN_POLICY_SSL = 4;
/// <summary/>
public const int CERT_CHAIN_POLICY_BASIC_CONSTRAINTS = 5;
/// <summary/>
public const int CERT_CHAIN_POLICY_NT_AUTH = 6;
/// <summary/>
public const int CERT_CHAIN_POLICY_MICROSOFT_ROOT = 7;
/// <summary/>
public const int CERT_CHAIN_POLICY_EV = 8;
/// <summary/>
public const int CERT_CHAIN_POLICY_SSL_F12 = 9;
/// <summary/>
public const int CERT_CHAIN_POLICY_SSL_HPKP_HEADER = 10;
/// <summary/>
public const int CERT_CHAIN_POLICY_THIRD_PARTY_ROOT = 11;
/// <summary/>
public const int CERT_CHAIN_POLICY_SSL_KEY_PIN = 12;
}
2020-03-09 11:54:19 -04:00
}
}