using System;
using System.Runtime.InteropServices;
using Vanara.Extensions;
using Vanara.InteropServices;
using FILETIME = System.Runtime.InteropServices.ComTypes.FILETIME;
namespace Vanara.PInvoke
{
/// Methods and data types found in Crypt32.dll.
public static partial class Crypt32
{
/// Flags used by .
[PInvokeData("wincrypt.h", MSDNShortId = "9e010eb9-2cbb-4fca-ba5c-4a5a50f23786")]
[Flags]
public enum CertChainEngineExclusiveFlags
{
///
/// 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.
///
CERT_CHAIN_EXCLUSIVE_ENABLE_CA_FLAG = 0x00000001,
}
/// Flags used by .
[PInvokeData("wincrypt.h", MSDNShortId = "9e010eb9-2cbb-4fca-ba5c-4a5a50f23786")]
[Flags]
public enum CertChainEngineFlags
{
///
/// 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.
///
CERT_CHAIN_CACHE_END_CERT = 0x00000001,
///
CERT_CHAIN_THREAD_STORE_SYNC = 0x00000002,
///
/// Use only cached URLs in building a certificate chain. The Internet and intranet are not searched for URL-based objects.
///
CERT_CHAIN_CACHE_ONLY_URL_RETRIEVAL = 0x00000004,
/// Build the chain using the LocalMachine registry location as opposed to the CurrentUser location.
CERT_CHAIN_USE_LOCAL_MACHINE_STORE = 0x00000008,
/// Enable automatic updating of the cache as a chain is being built.
CERT_CHAIN_ENABLE_CACHE_AUTO_UPDATE = 0x00000010,
/// Allow certificate stores used to build the chain to be shared.
CERT_CHAIN_ENABLE_SHARE_STORE = 0x00000020,
/// Turn off Authority Information Access (AIA) retrievals explicitly.
CERT_CHAIN_DISABLE_AIA = 0x00002000,
}
/// Flags used by .
[PInvokeData("wincrypt.h", MSDNShortId = "8c93036c-0b93-40d4-b0e3-ba1f2fc72db1")]
[Flags]
public enum CertChainFlags : uint
{
///
/// 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.
///
CERT_CHAIN_CACHE_END_CERT = 0x00000001,
/// Revocation checking only accesses cached URLs.
CERT_CHAIN_REVOCATION_CHECK_CACHE_ONLY = 0x80000000,
///
/// 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.
///
CERT_CHAIN_REVOCATION_CHECK_OCSP_CERT = 0x04000000,
///
/// 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.
///
///
CERT_CHAIN_CACHE_ONLY_URL_RETRIEVAL = 0x00000004,
///
/// 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.
///
CERT_CHAIN_DISABLE_PASS1_QUALITY_FILTERING = 0x00000040,
/// This flag is not supported. Certificates in the "My" store are never considered for peer trust.
CERT_CHAIN_DISABLE_MY_PEER_TRUST = 0x00000800,
///
/// 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.
///
CERT_CHAIN_ENABLE_PEER_TRUST = 0x00000400,
///
/// 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.
///
CERT_CHAIN_OPT_IN_WEAK_SIGNATURE = 0x00010000,
///
/// 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.
///
CERT_CHAIN_RETURN_LOWER_QUALITY_CONTEXTS = 0x00000080,
/// Setting this flag inhibits the auto update of third-party roots from the Windows Update Web Server.
CERT_CHAIN_DISABLE_AUTH_ROOT_AUTO_UPDATE = 0x00000100,
///
/// 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.
///
CERT_CHAIN_REVOCATION_ACCUMULATIVE_TIMEOUT = 0x08000000,
///
/// 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.
///
CERT_CHAIN_TIMESTAMP_TIME = 0x00000200,
/// Setting this flag explicitly turns off Authority Information Access (AIA) retrievals.
CERT_CHAIN_DISABLE_AIA = 0x00002000,
/// Revocation checking is done on the end certificate and only the end certificate.
CERT_CHAIN_REVOCATION_CHECK_END_CERT = 0x10000000,
/// Revocation checking is done on all of the certificates in every chain.
CERT_CHAIN_REVOCATION_CHECK_CHAIN = 0x20000000,
/// Revocation checking is done on all certificates in all of the chains except the root certificate.
CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT = 0x40000000,
}
/// Flags used by
[PInvokeData("wincrypt.h", MSDNShortId = "5e4fffcb-132b-42c0-81b2-9f866e274c32")]
[Flags]
public enum CertChainPolicyFlags : uint
{
/// Ignore not time valid errors.
CERT_CHAIN_POLICY_IGNORE_NOT_TIME_VALID_FLAG = 0x00000001,
/// Ignore certificate trust list (CTL) not time valid errors.
CERT_CHAIN_POLICY_IGNORE_CTL_NOT_TIME_VALID_FLAG = 0x00000002,
/// Ignore time nesting errors.
CERT_CHAIN_POLICY_IGNORE_NOT_TIME_NESTED_FLAG = 0x00000004,
/// Ignore basic constraint errors.
CERT_CHAIN_POLICY_IGNORE_INVALID_BASIC_CONSTRAINTS_FLAG = 0x00000008,
/// Ignore all time validity errors.
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),
/// Allow untrusted roots.
CERT_CHAIN_POLICY_ALLOW_UNKNOWN_CA_FLAG = 0x00000010,
/// Ignore invalid usage errors.
CERT_CHAIN_POLICY_IGNORE_WRONG_USAGE_FLAG = 0x00000020,
/// Ignore invalid name errors.
CERT_CHAIN_POLICY_IGNORE_INVALID_NAME_FLAG = 0x00000040,
/// Ignore invalid policy errors.
CERT_CHAIN_POLICY_IGNORE_INVALID_POLICY_FLAG = 0x00000080,
/// Ignores errors in obtaining valid revocation information.
CERT_CHAIN_POLICY_IGNORE_END_REV_UNKNOWN_FLAG = 0x00000100,
/// Ignores errors in obtaining valid CTL revocation information.
CERT_CHAIN_POLICY_IGNORE_CTL_SIGNER_REV_UNKNOWN_FLAG = 0x00000200,
/// Ignores errors in obtaining valid certification authority (CA) revocation information.
CERT_CHAIN_POLICY_IGNORE_CA_REV_UNKNOWN_FLAG = 0x00000400,
/// Ignores errors in obtaining valid root revocation information.
CERT_CHAIN_POLICY_IGNORE_ROOT_REV_UNKNOWN_FLAG = 0x00000800,
/// Ignores errors in obtaining valid revocation information.
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),
/// Allow untrusted test roots.
CERT_CHAIN_POLICY_ALLOW_TESTROOT_FLAG = 0x00008000,
/// Always trust test roots.
CERT_CHAIN_POLICY_TRUST_TESTROOT_FLAG = 0x00004000,
/// Ignore critical extension not supported errors.
CERT_CHAIN_POLICY_IGNORE_NOT_SUPPORTED_CRITICAL_EXT_FLAG = 0x00002000,
/// Ignore peer trusts.
CERT_CHAIN_POLICY_IGNORE_PEER_TRUST_FLAG = 0x00001000,
///
CERT_CHAIN_POLICY_IGNORE_WEAK_SIGNATURE_FLAG = 0x08000000,
/// Checks if the first certificate element is a CA.
BASIC_CONSTRAINTS_CERT_CHAIN_POLICY_CA_FLAG = 0x80000000,
/// Checks if the first certificate element is an end entity.
BASIC_CONSTRAINTS_CERT_CHAIN_POLICY_END_ENTITY_FLAG = 0x40000000,
/// Also check for the Microsoft test roots in addition to the Microsoft public root.
MICROSOFT_ROOT_CERT_CHAIN_POLICY_ENABLE_TEST_ROOT_FLAG = 0x00010000,
///
MICROSOFT_ROOT_CERT_CHAIN_POLICY_CHECK_APPLICATION_ROOT_FLAG = 0x00020000,
///
MICROSOFT_ROOT_CERT_CHAIN_POLICY_DISABLE_FLIGHT_ROOT_FLAG = 0x00040000,
}
/// Optional flags that modify chain retrieval behavior.
[PInvokeData("wincrypt.h", MSDNShortId = "86094e1c-be59-4a15-a05b-21769f80e653")]
[Flags]
public enum CertChainStrongSignFlags
{
///
/// 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.
///
CERT_CHAIN_STRONG_SIGN_DISABLE_END_CHECK_FLAG = 0x00000001,
}
/// Flags used by .
[PInvokeData("wincrypt.h", MSDNShortId = "90ac512f-3cbe-4543-9b34-8e384f730cfe")]
[Flags]
public enum CertCreateCTLEntryFlags
{
/// Force the inclusion of the chain building hash properties as attributes.
CTL_ENTRY_FROM_PROP_CHAIN_FLAG = 1
}
/// Flags for CertVerifyCTLUsage.
[PInvokeData("wincrypt.h", MSDNShortId = "d87d8157-8e52-4198-bfd4-46d83d72eb13")]
[Flags]
public enum CertVerifyCTLFlags
{
///
/// 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.
///
CERT_VERIFY_INHIBIT_CTL_UPDATE_FLAG = 0x1,
///
/// 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.
///
CERT_VERIFY_TRUSTED_SIGNERS_FLAG = 0x2,
/// If CERT_VERIFY_NO_TIME_CHECK_FLAG is set, the CTLs are not checked for time validity. Otherwise, they are.
CERT_VERIFY_NO_TIME_CHECK_FLAG = 0x4,
///
/// 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.
///
CERT_VERIFY_ALLOW_MORE_USAGE_FLAG = 0x8,
}
/// Flags used by .
[PInvokeData("wincrypt.h", MSDNShortId = "5c0e9e2e-a50d-45d0-b51d-065784d1d912")]
[Flags]
public enum CryptMsgEncodeFlags
{
///
/// Set if the CTL entries are to be sorted before encoding. This flag is set if the CertFindSubjectInSortedCTL or
/// CertEnumSubjectInSortedCTL functions will be called.
///
CMSG_ENCODE_SORTED_CTL_FLAG = 0x1,
///
/// Set if CMSG_ENCODE_SORTED_CTL_FLAG is set, and the identifier for the TrustedSubjects is a hash, such as MD5 or SHA1.
///
CMSG_ENCODE_HASHED_SUBJECT_IDENTIFIER_FLAG = 0x2,
}
/// Flags for .
[PInvokeData("wincrypt.h", MSDNShortId = "380c9cf3-27a2-4354-b1c8-97cec33f4e44")]
[Flags]
public enum CryptMsgSignerFlags
{
///
/// 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.
///
CMSG_TRUSTED_SIGNER_FLAG = 0x1,
/// Return the signer without doing the signature verification.
CMSG_SIGNER_ONLY_FLAG = 0x2,
///
/// 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.
///
CMSG_USE_SIGNER_INDEX_FLAG = 0x4,
}
/// Flags for .
[PInvokeData("wincrypt.h", MSDNShortId = "85ae8ce3-d0a7-4fcb-beaa-ede09d30930e")]
[Flags]
public enum CryptMsgSignFlags
{
///
/// If CMS_PKCS7 is defined, can be set to CMSG_CMS_ENCAPSULATED_CTL_FLAG to encode a CMS compatible V3 SignedData message.
///
CMSG_CMS_ENCAPSULATED_CTL_FLAG = 0x00008000
}
/// Flags returned in CTL_VERIFY_USAGE_STATUS.
[PInvokeData("wincrypt.h", MSDNShortId = "2b7ef953-9422-4dcf-b293-a78a06bb080e")]
[Flags]
public enum CtlVerifyUsageStatusFlags
{
/// CertVerifyCTLUsage updated a CTL whose time was no longer valid with a new, time-valid CTL.
CERT_VERIFY_UPDATED_CTL_FLAG = 0x1
}
///
/// Determines the kind of issuer matching to be done. In AND logic, the certificate must meet all criteria. In OR
/// logic, the certificate must meet at least one of the criteria.
///
[PInvokeData("wincrypt.h", MSDNShortId = "6154f1f7-4293-4b8e-91ab-9f57bb6f5743")]
public enum UsageMatchType
{
/// AND logic
USAGE_MATCH_TYPE_AND = 0x00000000,
/// OR logic
USAGE_MATCH_TYPE_OR = 0x00000001,
}
///
/// The CertCreateCertificateChainEngine 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.
///
/// A pointer to a CERT_CHAIN_ENGINE_CONFIG data structure that specifies the parameters for the chain engine.
///
/// 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.
///
///
/// If the function succeeds, the function returns nonzero ( TRUE).
/// If the function fails, it returns zero ( FALSE). For extended error information, call GetLastError.
/// The phChainEngine parameter returns the chain engine handle.
///
// 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);
///
///
/// The CertCreateCTLEntryFromCertificateContextProperties 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.
///
///
/// 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.
///
/// Additional attributes can be included in the CTL entry by using the cOptAttr and rgOptAttr parameters.
///
/// A pointer to the CERT_CONTEXT used to create the CTL.
/// A DWORD that specifies the number of additional attributes to be added.
/// A pointer to any array of CRYPT_ATTRIBUTE attributes to be added to the CTL.
///
/// A DWORD. Can be set to CTL_ENTRY_FROM_PROP_CHAIN_FLAG to force the inclusion of the chain building hash properties as attributes.
///
/// A pointer to a VOID. Reserved for future use.
///
/// Address of a pointer to a CTL_ENTRY structure. Call this function twice to retrieve a CTL entry. Set this parameter to
/// NULL 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.
///
///
/// Pointer to a DWORD 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 DWORD value
/// that contains zero and set the pCtlEntry parameter to NULL. If the first call succeeds, the DWORD value will
/// contain the number of bytes that you must allocate for the CTL_ENTRY structure. Allocate the required memory and call the
/// function again, supplying the address of the memory in the pCtlEntry parameter.
///
///
/// If the function succeeds, the function returns nonzero ( TRUE).
/// If the function fails, it returns zero ( FALSE). For extended error information, call GetLastError.
///
// 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);
///
/// The CertDuplicateCertificateChain function duplicates a pointer to a certificate chain by incrementing the chain's
/// reference count.
///
/// A pointer to a CERT_CHAIN_CONTEXT chain context to be duplicated.
///
///
/// 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.
///
/// If the function fails, NULL is returned.
///
// 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);
///
/// The CertFindChainInStore 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.
///
///
/// 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.
///
///
///
/// The certificate encoding type that was used to encode the store. The message encoding type identifier, contained in the high
/// WORD of this value, is ignored by this function.
///
/// This parameter can be the following currently defined certificate encoding type.
///
///
/// Value
/// Meaning
///
/// -
/// X509_ASN_ENCODING 1 (0x1)
/// Specifies X.509 certificate encoding.
///
///
///
///
///
/// Contains additional options for the search. The possible values for this parameter depend on the value of the dwFindType parameter.
///
/// This parameter can contain zero or a combination of one or more of the following values when dwFindType contains CERT_CHAIN_FIND_BY_ISSUER.
///
///
/// Value
/// Meaning
///
/// -
/// CERT_CHAIN_FIND_BY_ISSUER_COMPARE_KEY_FLAG
///
/// 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.
///
///
/// -
/// CERT_CHAIN_FIND_BY_ISSUER_COMPLEX_CHAIN_FLAG
///
/// 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.
///
///
/// -
/// CERT_CHAIN_FIND_BY_ISSUER_CACHE_ONLY_FLAG
///
/// 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.
///
///
/// -
/// CERT_CHAIN_FIND_BY_ISSUER_CACHE_ONLY_URL_FLAG
/// Only the URL cache is searched. The Internet is not searched.
///
/// -
/// CERT_CHAIN_FIND_BY_ISSUER_LOCAL_MACHINE_FLAG
/// Only opens the Local Machine certificate stores. The certificate stores of the current user are not opened.
///
/// -
/// CERT_CHAIN_FIND_BY_ISSUER_NO_KEY_FLAG
/// No check is made to determine whether the certificate has an associated private key.
///
///
///
///
/// Determines what criteria to use to find a certificate in the store.
/// This parameter can be the following currently defined value.
/// CERT_CHAIN_FIND_BY_ISSUER
///
/// 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.
///
///
/// 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.
///
///
/// 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.
///
/// This function does not perform any revocation checks.
///
/// If pPrevChainContext is not NULL, 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
/// CertFindChainInStore 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 NULL, if no such chain can
/// be found.
///
///
///
/// 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.
///
///
/// 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 NULL. In subsequent calls, it is the pointer
/// returned by the previous call to the function. If this parameter is not NULL, this function will free this structure.
///
///
/// If the first or next chain context is not built, NULL is returned. Otherwise, a pointer to a read-only CERT_CHAIN_CONTEXT
/// structure is returned. The CERT_CHAIN_CONTEXT structure is freed when passed as the pPrevChainContext parameter on a
/// subsequent call to this function. Otherwise, the CERT_CHAIN_CONTEXT structure must be freed explicitly by calling the
/// CertFreeCertificateChain function.
///
///
/// The pPrevChainContext parameter must be NULL 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 NULL, the structure is always freed by this function by using the CertFreeCertificateChain function, even if an error occurs.
///
// 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);
///
///
/// The CertFreeCertificateChain function frees a certificate chain by reducing its reference count. If the reference count
/// becomes zero, memory allocated for the chain is released.
///
///
/// 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.
///
///
///
/// 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.
///
/// This function does not return a value.
// 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);
/// The CertFreeCertificateChainEngine function frees a certificate trust engine.
/// Handle of the chain engine to be freed.
/// This function does not return a value.
// 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);
/// The CertFreeCertificateChainList function frees the array of pointers to chain contexts.
/// A pointer to a PCCERT_CHAIN_CONTEXT structure returned by the CertSelectCertificateChains function.
/// This function does not return a value.
///
/// Before calling the CertFreeCertificateChainList function, you must call the CertFreeCertificateChain function on each
/// chain context within the array pointed to by the prgpSelection parameter.
///
// 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);
///
/// The CertGetCertificateChain function builds a certificate chain context starting from an end certificate and going back,
/// if possible, to a trusted root certificate.
///
///
/// A handle of the chain engine (namespace and cache) to be used. If hChainEngine is NULL, the default chain engine,
/// HCCE_CURRENT_USER, is used. This parameter can be set to HCCE_LOCAL_MACHINE.
///
///
/// 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.
///
///
/// 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 NULL 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.
///
///
/// A handle to any additional store to search for supporting certificates and certificate trust lists (CTLs). This parameter can be
/// NULL if no additional store is to be searched.
///
/// A pointer to a CERT_CHAIN_PARA structure that includes chain-building parameters.
///
/// Flag values that indicate special processing. This parameter can be a combination of one or more of the following flags.
///
///
/// Value
/// Meaning
///
/// -
/// CERT_CHAIN_CACHE_END_CERT 0x00000001
///
/// 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.
///
///
/// -
/// CERT_CHAIN_REVOCATION_CHECK_CACHE_ONLY 0x80000000
/// Revocation checking only accesses cached URLs.
///
/// -
/// CERT_CHAIN_REVOCATION_CHECK_OCSP_CERT 0x04000000
///
/// 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.
///
///
/// -
/// CERT_CHAIN_CACHE_ONLY_URL_RETRIEVAL 0x00000004
///
/// 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.
///
///
/// -
/// CERT_CHAIN_DISABLE_PASS1_QUALITY_FILTERING 0x00000040
///
/// 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.
///
///
/// -
/// CERT_CHAIN_DISABLE_MY_PEER_TRUST 0x00000800
/// This flag is not supported. Certificates in the "My" store are never considered for peer trust.
///
/// -
/// CERT_CHAIN_ENABLE_PEER_TRUST 0x00000400
///
/// 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.
///
///
/// -
/// CERT_CHAIN_OPT_IN_WEAK_SIGNATURE 0x00010000
///
/// 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.
///
///
/// -
/// CERT_CHAIN_RETURN_LOWER_QUALITY_CONTEXTS 0x00000080
///
/// 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.
///
///
/// -
/// CERT_CHAIN_DISABLE_AUTH_ROOT_AUTO_UPDATE 0x00000100
/// Setting this flag inhibits the auto update of third-party roots from the Windows Update Web Server.
///
/// -
/// CERT_CHAIN_REVOCATION_ACCUMULATIVE_TIMEOUT 0x08000000
///
/// 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.
///
///
/// -
/// CERT_CHAIN_TIMESTAMP_TIME 0x00000200
///
/// 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.
///
///
/// -
/// CERT_CHAIN_DISABLE_AIA 0x00002000
/// Setting this flag explicitly turns off Authority Information Access (AIA) retrievals.
///
///
/// You can also set the following revocation flags, but only one flag from this group may be set at a time.
///
///
/// Value
/// Meaning
///
/// -
/// CERT_CHAIN_REVOCATION_CHECK_END_CERT 0x10000000
/// Revocation checking is done on the end certificate and only the end certificate.
///
/// -
/// CERT_CHAIN_REVOCATION_CHECK_CHAIN 0x20000000
/// Revocation checking is done on all of the certificates in every chain.
///
/// -
/// CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT 0x40000000
/// Revocation checking is done on all certificates in all of the chains except the root certificate.
///
///
///
/// This parameter is reserved and must be NULL.
///
/// 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.
///
///
/// If the function succeeds, the function returns nonzero ( TRUE).
/// If the function fails, it returns zero ( FALSE). For extended error information, call GetLastError.
///
///
///
/// 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.
///
/// The following remarks apply to strong signature checking:
///
/// -
///
/// You can enable strong signature checking for this function by setting the pStrongSignPara member of the CERT_CHAIN_PARA
/// structure that is pointed to by the pChainPara parameter.
///
///
/// -
///
/// If a certificate without a strong signature is found in the chain, the CERT_TRUST_HAS_WEAK_SIGNATURE and
/// CERT_TRUST_IS_NOT_SIGNATURE_VALID errors are set in the dwErrorStatus field of the CERT_TRUST_STATUS structure.
/// The ppChainContext parameter points to a CERT_CHAIN_CONTEXT structure which, in turn, points to the CERT_TRUST_STATUS structure.
///
///
/// -
///
/// 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
/// CERT_TRUST_HAS_WEAK_SIGNATURE and CERT_TRUST_IS_NOT_SIGNATURE_VALID errors are set in the dwErrorStatus
/// field of the CERT_TRUST_STATUS structure. To disable checking the key length, set the
/// CERT_CHAIN_STRONG_SIGN_DISABLE_END_CHECK_FLAG value in the dwStrongSignFlags member of the CERT_CHAIN_PARA
/// structure pointed to by the pChainPara parameter.
///
///
/// -
///
/// If the CERT_STRONG_SIGN_ENABLE_CRL_CHECK or CERT_STRONG_SIGN_ENABLE_OCSP_CHECK 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 CERT_TRUST_IS_OFFLINE_REVOCATION and
/// CERT_TRUST_REVOCATION_STATUS_UNKNOWN errors are set in the dwErrorStatus field of the CERT_TRUST_STATUS structure.
/// Also, the dwRevocationResult member of the CERT_REVOCATION_INFO structure is set to NTE_BAD_ALGID.
///
///
///
/// Examples
/// For an example that uses this function, see Example C Program: Creating a Certificate Chain.
///
// 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);
///
/// The CertGetCertificateChain function builds a certificate chain context starting from an end certificate and going back,
/// if possible, to a trusted root certificate.
///
///
/// A handle of the chain engine (namespace and cache) to be used. If hChainEngine is NULL, the default chain engine,
/// HCCE_CURRENT_USER, is used. This parameter can be set to HCCE_LOCAL_MACHINE.
///
///
/// 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.
///
///
/// 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 NULL 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.
///
///
/// A handle to any additional store to search for supporting certificates and certificate trust lists (CTLs). This parameter can be
/// NULL if no additional store is to be searched.
///
/// A pointer to a CERT_CHAIN_PARA structure that includes chain-building parameters.
///
/// Flag values that indicate special processing. This parameter can be a combination of one or more of the following flags.
///
///
/// Value
/// Meaning
///
/// -
/// CERT_CHAIN_CACHE_END_CERT 0x00000001
///
/// 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.
///
///
/// -
/// CERT_CHAIN_REVOCATION_CHECK_CACHE_ONLY 0x80000000
/// Revocation checking only accesses cached URLs.
///
/// -
/// CERT_CHAIN_REVOCATION_CHECK_OCSP_CERT 0x04000000
///
/// 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.
///
///
/// -
/// CERT_CHAIN_CACHE_ONLY_URL_RETRIEVAL 0x00000004
///
/// 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.
///
///
/// -
/// CERT_CHAIN_DISABLE_PASS1_QUALITY_FILTERING 0x00000040
///
/// 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.
///
///
/// -
/// CERT_CHAIN_DISABLE_MY_PEER_TRUST 0x00000800
/// This flag is not supported. Certificates in the "My" store are never considered for peer trust.
///
/// -
/// CERT_CHAIN_ENABLE_PEER_TRUST 0x00000400
///
/// 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.
///
///
/// -
/// CERT_CHAIN_OPT_IN_WEAK_SIGNATURE 0x00010000
///
/// 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.
///
///
/// -
/// CERT_CHAIN_RETURN_LOWER_QUALITY_CONTEXTS 0x00000080
///
/// 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.
///
///
/// -
/// CERT_CHAIN_DISABLE_AUTH_ROOT_AUTO_UPDATE 0x00000100
/// Setting this flag inhibits the auto update of third-party roots from the Windows Update Web Server.
///
/// -
/// CERT_CHAIN_REVOCATION_ACCUMULATIVE_TIMEOUT 0x08000000
///
/// 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.
///
///
/// -
/// CERT_CHAIN_TIMESTAMP_TIME 0x00000200
///
/// 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.
///
///
/// -
/// CERT_CHAIN_DISABLE_AIA 0x00002000
/// Setting this flag explicitly turns off Authority Information Access (AIA) retrievals.
///
///
/// You can also set the following revocation flags, but only one flag from this group may be set at a time.
///
///
/// Value
/// Meaning
///
/// -
/// CERT_CHAIN_REVOCATION_CHECK_END_CERT 0x10000000
/// Revocation checking is done on the end certificate and only the end certificate.
///
/// -
/// CERT_CHAIN_REVOCATION_CHECK_CHAIN 0x20000000
/// Revocation checking is done on all of the certificates in every chain.
///
/// -
/// CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT 0x40000000
/// Revocation checking is done on all certificates in all of the chains except the root certificate.
///
///
///
/// This parameter is reserved and must be NULL.
///
/// 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.
///
///
/// If the function succeeds, the function returns nonzero ( TRUE).
/// If the function fails, it returns zero ( FALSE). For extended error information, call GetLastError.
///
///
///
/// 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.
///
/// The following remarks apply to strong signature checking:
///
/// -
///
/// You can enable strong signature checking for this function by setting the pStrongSignPara member of the CERT_CHAIN_PARA
/// structure that is pointed to by the pChainPara parameter.
///
///
/// -
///
/// If a certificate without a strong signature is found in the chain, the CERT_TRUST_HAS_WEAK_SIGNATURE and
/// CERT_TRUST_IS_NOT_SIGNATURE_VALID errors are set in the dwErrorStatus field of the CERT_TRUST_STATUS structure.
/// The ppChainContext parameter points to a CERT_CHAIN_CONTEXT structure which, in turn, points to the CERT_TRUST_STATUS structure.
///
///
/// -
///
/// 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
/// CERT_TRUST_HAS_WEAK_SIGNATURE and CERT_TRUST_IS_NOT_SIGNATURE_VALID errors are set in the dwErrorStatus
/// field of the CERT_TRUST_STATUS structure. To disable checking the key length, set the
/// CERT_CHAIN_STRONG_SIGN_DISABLE_END_CHECK_FLAG value in the dwStrongSignFlags member of the CERT_CHAIN_PARA
/// structure pointed to by the pChainPara parameter.
///
///
/// -
///
/// If the CERT_STRONG_SIGN_ENABLE_CRL_CHECK or CERT_STRONG_SIGN_ENABLE_OCSP_CHECK 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 CERT_TRUST_IS_OFFLINE_REVOCATION and
/// CERT_TRUST_REVOCATION_STATUS_UNKNOWN errors are set in the dwErrorStatus field of the CERT_TRUST_STATUS structure.
/// Also, the dwRevocationResult member of the CERT_REVOCATION_INFO structure is set to NTE_BAD_ALGID.
///
///
///
/// Examples
/// For an example that uses this function, see Example C Program: Creating a Certificate Chain.
///
// 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);
///
/// The CertIsValidCRLForCertificate 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.
///
/// A pointer to a certificate context.
///
/// 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.
///
/// Currently not used and must be set to zero.
/// Currently not used and must be set to NULL.
///
/// The function returns TRUE if the CRL is a valid CRL to be searched for the specific certificate. It returns FALSE
/// if the CRL is not a valid CRL for searching for the certificate.
///
///
/// For the CRL to be valid for the certificate, the CertIsValidCRLForCertificate function does not require the CRL to be
/// issued by the same certification authority (CA) as the issuer of the certificate.
///
// 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);
///
/// The CertSetCertificateContextPropertiesFromCTLEntry function sets the properties on the certificate context by using the
/// attributes in the specified certificate trust list (CTL) entry.
///
/// A pointer to the CERT_CONTEXT whose attributes are to be set.
/// A pointer to the CTL_ENTRY structure used to set the attributes on the certificate.
///
/// A DWORD. This parameter can be set to CERT_SET_PROPERTY_IGNORE_PERSIST_ERROR_FLAG to ignore any persisted error flags.
///
///
/// If the function succeeds, the function returns nonzero.
/// If the function fails, it returns zero. For extended error information, call GetLastError.
///
// 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);
///
/// The CertVerifyCertificateChainPolicy function checks a certificate chain to verify its validity, including its compliance
/// with any specified validity policy criteria.
///
///
/// Current predefined verify chain policy structures are listed in the following table.
///
///
/// Value
/// Meaning
///
/// -
/// CERT_CHAIN_POLICY_BASE (LPCSTR) 1
///
/// 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.
///
///
/// -
/// CERT_CHAIN_POLICY_AUTHENTICODE (LPCSTR) 2
///
/// 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.
///
///
/// -
/// CERT_CHAIN_POLICY_AUTHENTICODE_TS (LPCSTR) 3
///
/// 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
///
///
/// -
/// CERT_CHAIN_POLICY_SSL (LPCSTR) 4
///
/// 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.
///
///
/// -
/// CERT_CHAIN_POLICY_BASIC_CONSTRAINTS (LPCSTR) 5
///
/// 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.
///
///
/// -
/// CERT_CHAIN_POLICY_NT_AUTH (LPCSTR) 6
///
/// Implements the Windows NT Authentication chain policy, which consists of three distinct chain verifications in the following order:
///
///
/// -
/// CERT_CHAIN_POLICY_MICROSOFT_ROOT (LPCSTR) 7
///
/// 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.
///
///
/// -
/// CERT_CHAIN_POLICY_EV (LPCSTR) 8
///
/// Specifies that extended validation of certificates is performed. Windows Server 2008, Windows Vista, Windows Server 2003 and
/// Windows XP: This value is not supported.
///
///
/// -
/// CERT_CHAIN_POLICY_SSL_F12 (LPCSTR) 9
///
/// 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
///
///
///
///
/// A pointer to a CERT_CHAIN_CONTEXT structure that contains a chain to be verified.
///
///
/// A pointer to a CERT_CHAIN_POLICY_PARA structure that provides the policy verification criteria for the chain. The dwFlags
/// member of that structure can be set to change the default policy checking behavior.
///
/// In addition, policy-specific parameters can also be passed in the pvExtraPolicyPara member of the structure.
///
///
/// 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 pvExtraPolicyStatus member of this structure.
///
///
///
/// 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.
///
///
/// If the chain can be verified for the specified policy, TRUE is returned and the dwError member of the
/// pPolicyStatus is updated. A dwError of 0 (ERROR_SUCCESS or S_OK) indicates the chain satisfies the specified policy.
///
///
/// If the chain cannot be validated, the return value is TRUE and you need to verify the pPolicyStatus parameter for the
/// actual error.
///
/// A value of FALSE indicates that the function wasn't able to check for the policy.
///
///
///
/// A dwError 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 dwError applies to the entire chain context, both the
/// lChainIndex and the lElementIndex members of the CERT_CHAIN_POLICY_STATUS structure are set to –1. If
/// dwError applies to a complete simple chain, lElementIndex is set to –1 and lChainIndex is set to the index
/// of the first chain that has an error. If dwError applies to a single certificate element, lChainIndex and
/// lElementIndex index the first certificate that has the error.
///
/// To get the certificate element use this syntax:
///
// 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);
///
/// The CertVerifyCertificateChainPolicy function checks a certificate chain to verify its validity, including its compliance
/// with any specified validity policy criteria.
///
///
/// Current predefined verify chain policy structures are listed in the following table.
///
///
/// Value
/// Meaning
///
/// -
/// CERT_CHAIN_POLICY_BASE (LPCSTR) 1
///
/// 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.
///
///
/// -
/// CERT_CHAIN_POLICY_AUTHENTICODE (LPCSTR) 2
///
/// 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.
///
///
/// -
/// CERT_CHAIN_POLICY_AUTHENTICODE_TS (LPCSTR) 3
///
/// 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
///
///
/// -
/// CERT_CHAIN_POLICY_SSL (LPCSTR) 4
///
/// 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.
///
///
/// -
/// CERT_CHAIN_POLICY_BASIC_CONSTRAINTS (LPCSTR) 5
///
/// 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.
///
///
/// -
/// CERT_CHAIN_POLICY_NT_AUTH (LPCSTR) 6
///
/// Implements the Windows NT Authentication chain policy, which consists of three distinct chain verifications in the following order:
///
///
/// -
/// CERT_CHAIN_POLICY_MICROSOFT_ROOT (LPCSTR) 7
///
/// 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.
///
///
/// -
/// CERT_CHAIN_POLICY_EV (LPCSTR) 8
///
/// Specifies that extended validation of certificates is performed. Windows Server 2008, Windows Vista, Windows Server 2003 and
/// Windows XP: This value is not supported.
///
///
/// -
/// CERT_CHAIN_POLICY_SSL_F12 (LPCSTR) 9
///
/// 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
///
///
///
///
/// A pointer to a CERT_CHAIN_CONTEXT structure that contains a chain to be verified.
///
///
/// A pointer to a CERT_CHAIN_POLICY_PARA structure that provides the policy verification criteria for the chain. The dwFlags
/// member of that structure can be set to change the default policy checking behavior.
///
/// In addition, policy-specific parameters can also be passed in the pvExtraPolicyPara member of the structure.
///
///
/// 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 pvExtraPolicyStatus member of this structure.
///
///
///
/// 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.
///
///
/// If the chain can be verified for the specified policy, TRUE is returned and the dwError member of the
/// pPolicyStatus is updated. A dwError of 0 (ERROR_SUCCESS or S_OK) indicates the chain satisfies the specified policy.
///
///
/// If the chain cannot be validated, the return value is TRUE and you need to verify the pPolicyStatus parameter for the
/// actual error.
///
/// A value of FALSE indicates that the function wasn't able to check for the policy.
///
///
///
/// A dwError 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 dwError applies to the entire chain context, both the
/// lChainIndex and the lElementIndex members of the CERT_CHAIN_POLICY_STATUS structure are set to –1. If
/// dwError applies to a complete simple chain, lElementIndex is set to –1 and lChainIndex is set to the index
/// of the first chain that has an error. If dwError applies to a single certificate element, lChainIndex and
/// lElementIndex index the first certificate that has the error.
///
/// To get the certificate element use this syntax:
///
// 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,
in CERT_CHAIN_POLICY_PARA pPolicyPara, ref CERT_CHAIN_POLICY_STATUS pPolicyStatus);
///
/// The CertVerifyCTLUsage 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.
///
///
///
/// 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
///
/// X509_ASN_ENCODING | PKCS_7_ASN_ENCODING.
///
///
///
/// If the dwSubjectType parameter is set to CTL_CERT_SUBJECT_TYPE, pvSubject points to a CERT_CONTEXT structure. The structure's
/// SubjectAlgorithm member is examined to determine the representation of the subject's identity. Initially, only SHA1 and
/// MD5 hashes are supported as values for SubjectAlgorithm. The appropriate hash property is obtained from the
/// CERT_CONTEXT structure.
///
///
/// If the dwSubjectType parameter is set to CTL_ANY_SUBJECT_TYPE, pvSubject points to the CTL_ANY_SUBJECT_INFO structure. The
/// SubjectAlgorithm member of this structure must match the algorithm type of the CTL, and the SubjectIdentifier
/// member must match one of the CTL entries.
///
/// If dwSubjectType is set to either preceding value, dwEncodingType is not used.
///
/// Value used in conjunction with the dwSubjectType parameter.
/// A pointer to a CTL_USAGE structure used to specify the intended usage of the subject.
///
///
/// 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.
///
///
/// 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. For more information, see Remarks.
///
/// If CERT_VERIFY_NO_TIME_CHECK_FLAG is set, the CTLs are not checked for time validity. Otherwise, they are.
///
/// 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.
///
///
///
/// 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 ListIdentifier member further limits the search.
///
///
/// A pointer to a CTL_VERIFY_USAGE_STATUS structure. The cbSize 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 CertVerifyCTLUsage is called. For more
/// information, see CTL_VERIFY_USAGE_STATUS.
///
///
///
/// If the subject is trusted for the specified usage, TRUE is returned. Otherwise, FALSE is returned. GetLastError
/// can return one of the following error codes.
///
///
///
/// Value
/// Description
///
/// -
/// CRYPT_E_NO_VERIFY_USAGE_DLL
/// No DLL or exported function was found to verify subject usage.
///
/// -
/// CRYPT_E_NO_VERIFY_USAGE_CHECK
/// The called function was not able to do a usage check on the subject.
///
/// -
/// CRYPT_E_VERIFY_USAGE_OFFLINE
/// The server was offline; therefore, the called function could not complete the usage check.
///
/// -
/// CRYPT_E_NOT_IN_CTL
/// The subject was not found in a CTL.
///
/// -
/// CRYPT_E_NO_TRUSTED_SIGNER
/// No trusted signer was found to verify the signature of the message or trust list.
///
///
/// The dwError member of the CTL_VERIFY_USAGE_PARA pointed to by pVerifyUsageStatus is set to the same error code.
///
///
///
/// CertVerifyCTLUsage 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 CertDllVerifyCTLUsage functions.
///
/// The CertDllVerifyCTLUsage function in Cryptnet.dll can be installed by using an OID; it has the following properties:
///
/// -
///
/// If CTL stores are specified by rghCtlStore in pVerifyUsagePara, only those stores are searched to find a CTL. Otherwise,
/// the Trust system store is searched to find a CTL.
///
///
/// -
///
/// If CERT_VERIFY_TRUSTED_SIGNERS_FLAG is set, only the signer stores specified by rghSignerStore 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 rghSignerStore 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.
///
///
/// -
/// If the CTL has a set NextUpdate member and CERT_VERIFY_NO_TIME_CHECK is not set, it is verified for time validity.
///
/// -
///
/// 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
/// CertDllVerifyCTLUsage function uses the NextUpdateLocation property or the NextUpdateLocation extension of
/// the CTL, or it searches the signer's information for a NextUpdateLocation attribute.
///
///
///
///
// 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);
///
/// The CertVerifyCTLUsage 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.
///
///
///
/// 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
///
/// X509_ASN_ENCODING | PKCS_7_ASN_ENCODING.
///
///
///
/// If the dwSubjectType parameter is set to CTL_CERT_SUBJECT_TYPE, pvSubject points to a CERT_CONTEXT structure. The structure's
/// SubjectAlgorithm member is examined to determine the representation of the subject's identity. Initially, only SHA1 and
/// MD5 hashes are supported as values for SubjectAlgorithm. The appropriate hash property is obtained from the
/// CERT_CONTEXT structure.
///
///
/// If the dwSubjectType parameter is set to CTL_ANY_SUBJECT_TYPE, pvSubject points to the CTL_ANY_SUBJECT_INFO structure. The
/// SubjectAlgorithm member of this structure must match the algorithm type of the CTL, and the SubjectIdentifier
/// member must match one of the CTL entries.
///
/// If dwSubjectType is set to either preceding value, dwEncodingType is not used.
///
/// Value used in conjunction with the dwSubjectType parameter.
/// A pointer to a CTL_USAGE structure used to specify the intended usage of the subject.
///
///
/// 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.
///
///
/// 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. For more information, see Remarks.
///
/// If CERT_VERIFY_NO_TIME_CHECK_FLAG is set, the CTLs are not checked for time validity. Otherwise, they are.
///
/// 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.
///
///
///
/// 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 ListIdentifier member further limits the search.
///
///
/// A pointer to a CTL_VERIFY_USAGE_STATUS structure. The cbSize 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 CertVerifyCTLUsage is called. For more
/// information, see CTL_VERIFY_USAGE_STATUS.
///
///
///
/// If the subject is trusted for the specified usage, TRUE is returned. Otherwise, FALSE is returned. GetLastError
/// can return one of the following error codes.
///
///
///
/// Value
/// Description
///
/// -
/// CRYPT_E_NO_VERIFY_USAGE_DLL
/// No DLL or exported function was found to verify subject usage.
///
/// -
/// CRYPT_E_NO_VERIFY_USAGE_CHECK
/// The called function was not able to do a usage check on the subject.
///
/// -
/// CRYPT_E_VERIFY_USAGE_OFFLINE
/// The server was offline; therefore, the called function could not complete the usage check.
///
/// -
/// CRYPT_E_NOT_IN_CTL
/// The subject was not found in a CTL.
///
/// -
/// CRYPT_E_NO_TRUSTED_SIGNER
/// No trusted signer was found to verify the signature of the message or trust list.
///
///
/// The dwError member of the CTL_VERIFY_USAGE_PARA pointed to by pVerifyUsageStatus is set to the same error code.
///
///
///
/// CertVerifyCTLUsage 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 CertDllVerifyCTLUsage functions.
///
/// The CertDllVerifyCTLUsage function in Cryptnet.dll can be installed by using an OID; it has the following properties:
///
/// -
///
/// If CTL stores are specified by rghCtlStore in pVerifyUsagePara, only those stores are searched to find a CTL. Otherwise,
/// the Trust system store is searched to find a CTL.
///
///
/// -
///
/// If CERT_VERIFY_TRUSTED_SIGNERS_FLAG is set, only the signer stores specified by rghSignerStore 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 rghSignerStore 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.
///
///
/// -
/// If the CTL has a set NextUpdate member and CERT_VERIFY_NO_TIME_CHECK is not set, it is verified for time validity.
///
/// -
///
/// 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
/// CertDllVerifyCTLUsage function uses the NextUpdateLocation property or the NextUpdateLocation extension of
/// the CTL, or it searches the signer's information for a NextUpdateLocation attribute.
///
///
///
///
// 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);
///
/// The CryptMsgEncodeAndSignCTL function encodes a CTL and creates a signed message containing the encoded CTL.
/// This function first encodes the CTL pointed to by pCtlInfo and then calls CryptMsgSignCTL to sign the encoded message.
///
///
///
/// Specifies the encoding type used. It is always acceptable to specify both the certificate and message encoding types by
/// combining them with a bitwise- OR operation as shown in the following example:
///
/// X509_ASN_ENCODING | PKCS_7_ASN_ENCODING
/// Currently defined encoding types are:
///
/// -
/// X509_ASN_ENCODING
///
/// -
/// PKCS_7_ASN_ENCODING
///
///
///
/// A pointer to the CTL_INFO structure containing the CTL to be encoded and signed.
///
/// A pointer to a CMSG_SIGNED_ENCODE_INFO structure that contains an array of a CMSG_SIGNER_ENCODE_INFO structures.
///
/// The message can be encoded without signers if the cbSize member of the structure is set to the size of the structure and
/// all of the other members are set to zero.
///
///
///
///
/// 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.
///
///
/// 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.
///
///
/// If CMS_PKCS7 is defined, dwFlags can be set to CMSG_CMS_ENCAPSULATED_CTL_FLAG to encode a CMS compatible V3 SignedData message.
///
///
///
/// A pointer to a buffer that receives the encoded, signed message created.
///
/// This parameter can be NULL to set the size of this information for memory allocation purposes. For more information, see
/// Retrieving Data of Unknown Length.
///
///
///
/// A pointer to a DWORD that specifies the size, in bytes, of the pbEncoded buffer. When the function returns, the
/// DWORD contains the number of bytes stored or to be stored in the buffer.
///
///
/// If the function succeeds, the return value is nonzero ( TRUE).
///
/// If the function fails, the return value is zero ( FALSE). To get extended error information, call GetLastError. Errors
/// can be propagated from calls to CryptMsgOpenToEncode and CryptMsgUpdate.
///
///
// 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);
/// The CryptMsgGetAndVerifySigner function verifies a cryptographic message's signature.
/// Handle of a cryptographic message.
/// Number of stores in the rghSignerStore array.
/// Array of certificate store handles that can be searched for a signer's certificate.
///
/// Indicates particular use of the function.
///
///
/// Value
/// Meaning
///
/// -
/// CMSG_TRUSTED_SIGNER_FLAG
///
/// 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.
///
///
/// -
/// CMSG_SIGNER_ONLY_FLAG
/// Return the signer without doing the signature verification.
///
/// -
/// CMSG_USE_SIGNER_INDEX_FLAG
///
/// 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.
///
///
///
///
///
/// 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 NULL if the
/// application has no need for the signer's certificate.
///
///
/// 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 NULL if the application has no need for the index of the signer.
///
///
/// If the function succeeds, the return value is nonzero (TRUE).
/// If the function fails, the return value is zero (FALSE). For extended error information, call GetLastError.
///
// 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);
/// The CryptMsgSignCTL function creates a signed message containing an encoded CTL.
///
///
/// Specifies the encoding type used. It is always acceptable to specify both the certificate and message encoding types by
/// combining them with a bitwise- OR operation as shown in the following example:
///
/// X509_ASN_ENCODING | PKCS_7_ASN_ENCODING
/// Currently defined encoding types are:
///
/// -
/// X509_ASN_ENCODING
///
/// -
/// PKCS_7_ASN_ENCODING
///
///
///
///
/// The encoded CTL_INFO that can be a member of a CTL_CONTEXT structure or can be created using the CryptEncodeObject function.
///
/// The size, in bytes, of the content pointed to by pbCtlContent.
///
/// A pointer to a CMSG_SIGNED_ENCODE_INFO structure containing an array of a CMSG_SIGNER_ENCODE_INFO structures.
///
/// The message can be encoded without signers if the cbSize member of the structure is set to the size of the structure and
/// all of the other members are set to zero.
///
///
///
/// If CMS_PKCS7 is defined, can be set to CMSG_CMS_ENCAPSULATED_CTL_FLAG to encode a CMS compatible V3 SignedData message.
///
///
/// A pointer to a buffer to receives the encoded message.
///
/// This parameter can be NULL to get the size of this information for memory allocation purposes. For more information, see
/// Retrieving Data of Unknown Length.
///
///
///
/// A pointer to a DWORD specifying the size, in bytes, of the pbEncoded buffer. When the function returns, the DWORD
/// contains the number of bytes stored or to be stored in the buffer.
///
///
/// If the function succeeds, the return value is nonzero ( TRUE).
///
/// If the function fails, the return value is zero ( FALSE). For extended error information, call GetLastError. This
/// function can return errors propagated from calls to CryptMsgOpenToEncode and CryptMsgUpdate.
///
///
// 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);
///
/// The CERT_CHAIN_ENGINE_CONFIG structure sets parameters for building a non-default certificate chain engine. The engine
/// used determines the ways that certificate chains are built.
///
///
///
/// 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.
///
///
/// hRoot is the store handle from hRestrictedRoot or, if hRestrictedRoot is NULL, the handle for System Store "Root."
///
///
/// 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 rghAdditionalStore.
///
/// hTrust is the store handle from hRestrictedTrust or, if hRestrictedTrust is NULL, hWorld.
///
/// hOther is hRestrictedOther plus hRoot or, if hRestrictedTrust is non- NULL, the hWorld collection store
/// plus the store handle from hRestrictedTrust.
///
///
/// 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 hExclusiveRoot and hExclusiveTrustedPeople members are used instead.
///
///
// 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
{
/// Size of this structure in bytes.
public uint cbSize;
///
/// 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.
///
public HCERTSTORE hRestrictedRoot;
/// Store handle. If used, restricts the stores searched to find CTLs.
public HCERTSTORE hRestrictedTrust;
/// Store handle. If used, restricts the stores searched for certificates and CRLs.
public HCERTSTORE hRestrictedOther;
/// Count of additional stores to be searched for certificates and CRLs needed to build chains.
public uint cAdditionalStore;
/// A pointer to an array of store handles for any additional stores to be searched in building chains.
public IntPtr rghAdditionalStore;
///
/// The following flags are defined.
///
///
/// Value
/// Meaning
///
/// -
/// CERT_CHAIN_CACHE_END_CERT 0x00000001
///
/// 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.
///
///
/// -
/// CERT_CHAIN_CACHE_ONLY_URL_RETRIEVAL 0x00000004
/// Use only cached URLs in building a certificate chain. The Internet and intranet are not searched for URL-based objects.
///
/// -
/// CERT_CHAIN_USE_LOCAL_MACHINE_STORE 0x00000008
/// Build the chain using the LocalMachine registry location as opposed to the CurrentUser location.
///
/// -
/// CERT_CHAIN_ENABLE_CACHE_AUTO_UPDATE 0x00000010
/// Enable automatic updating of the cache as a chain is being built.
///
/// -
/// CERT_CHAIN_ENABLE_SHARE_STORE 0x00000020
/// Allow certificate stores used to build the chain to be shared.
///
/// -
/// CERT_CHAIN_DISABLE_AIA 0x00002000
/// Turn off Authority Information Access (AIA) retrievals explicitly.
///
///
///
public CertChainEngineFlags dwFlags;
///
/// Number of milliseconds before a time-out for network based–URL object retrievals. Can be set to zero to use the default limit.
///
public uint dwUrlRetrievalTimeout;
///
/// 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.
///
public uint MaximumCachedCertificates;
///
///
/// 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.
///
///
/// 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.
///
///
public uint CycleDetectionModulus;
///
///
/// Handle to a certificate store that contains exclusive trust anchors. If either the hExclusiveRoot or
/// hExclusiveTrustedPeople member points to a valid store, exclusive trust mode is used for the chain building.
///
/// Windows 7 and Windows Server 2008 R2: Support for this member begins.
///
public HCERTSTORE hExclusiveRoot;
///
///
/// Handle to a certificate store that contains application-specific peer trusted certificates. If either the
/// hExclusiveRoot or hExclusiveTrustedPeople member points to a valid store, exclusive trust mode is used for the
/// chain building.
///
/// Windows 7 and Windows Server 2008 R2: Support for this member begins.
///
public HCERTSTORE hExclusiveTrustedPeople;
///
///
/// The following flag can be set. The flag applies only if the hExclusiveRoot or hExclusiveTrustedPeople or both
/// are not NULL.
///
/// Windows 8 and Windows Server 2012: Support for this member begins.
///
///
/// Value
/// Meaning
///
/// -
/// CERT_CHAIN_EXCLUSIVE_ENABLE_CA_FLAG 0x00000001
///
/// 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.
///
///
///
///
public CertChainEngineExclusiveFlags dwExclusiveFlags;
}
///
/// The CERT_CHAIN_PARA structure establishes the searching and matching criteria to be used in building a certificate chain.
///
///
/// The following remarks apply when checking for strong signatures.
///
/// -
///
/// Set the pStrongSignPara member to check for strong signatures when using the CertGetCertificateChain or
/// CertSelectCertificateChains function.
///
///
/// -
///
/// If a certificate without a strong signature is found in the chain, the CERT_TRUST_HAS_WEAK_SIGNATURE and
/// CERT_TRUST_IS_NOT_SIGNATURE_VALID errors are set in the dwErrorStatus 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
/// CERT_TRUST_STATUS structure.
///
///
/// -
///
/// 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
/// CERT_TRUST_HAS_WEAK_SIGNATURE and CERT_TRUST_IS_NOT_SIGNATURE_VALID errors are set in the dwErrorStatus
/// field of the CERT_TRUST_STATUS structure. Set the CERT_CHAIN_STRONG_SIGN_DISABLE_END_CHECK_FLAG value in the
/// dwStrongSignFlags member to disable this check.
///
///
/// -
///
/// If the CERT_STRONG_SIGN_ENABLE_CRL_CHECK or CERT_STRONG_SIGN_ENABLE_OCSP_CHECK flags are set in the
/// CERT_STRONG_SIGN_SERIALIZED_INFO structure referenced by the CERT_STRONG_SIGN_PARA structure pointed to by the
/// pStrongSignPara 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 CERT_TRUST_IS_OFFLINE_REVOCATION and CERT_TRUST_REVOCATION_STATUS_UNKNOWN
/// errors are set in the dwErrorStatus field of the CERT_TRUST_STATUS structure. Also, the dwRevocationResult member
/// of the CERT_REVOCATION_INFO structure is set to NTE_BAD_ALGID.
///
///
///
///
// 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
{
/// The size, in bytes, of this structure.
public uint cbSize;
///
/// 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.
///
public CERT_USAGE_MATCH RequestedUsage;
///
///
/// 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.
///
///
/// Note This member can be used only if CERT_CHAIN_PARA_HAS_EXTRA_FIELDS is defined by using the #define
/// directive before including Wincrypt.h. If this value is defined, the application must zero all unused fields.
///
///
public CERT_USAGE_MATCH RequestedIssuancePolicy;
///
/// Optional time, in milliseconds, before revocation checking times out. This member is optional.
///
/// Note This member can be used only if CERT_CHAIN_PARA_HAS_EXTRA_FIELDS is defined by using the #define
/// directive before including Wincrypt.h. If this value is defined, the application must zero all unused fields.
///
///
public uint dwUrlRetrievalTimeout;
///
///
/// Optional member. When this flag is TRUE, an attempt is made to retrieve a new CRL if this update is greater than or
/// equal to the current system time minus the dwRevocationFreshnessTime value. If this flag is not set, the CRL's next
/// update time is used.
///
///
/// Note This member can be used only if CERT_CHAIN_PARA_HAS_EXTRA_FIELDS is defined by using the #define
/// directive before including Wincrypt.h. If this value is defined, the application must zero all unused fields.
///
///
[MarshalAs(UnmanagedType.Bool)] public bool fCheckRevocationFreshnessTime;
///
/// The current time, in seconds, minus the CRL's update time of all elements checked.
///
/// Note This member can be used only if CERT_CHAIN_PARA_HAS_EXTRA_FIELDS is defined by using the #define
/// directive before including Wincrypt.h. If this value is defined, the application must zero all unused fields.
///
///
public uint dwRevocationFreshnessTime;
///
///
/// Optional member. When set to a non- NULL value, information cached before the time specified is considered to be not
/// valid and cache resynchronization is performed.
///
/// Windows Vista: Support for this member begins.
///
/// Note This member can be used only if CERT_CHAIN_PARA_HAS_EXTRA_FIELDS is defined by using the #define
/// directive before including Wincrypt.h. If this value is defined, the application must zero all unused fields.
///
///
public IntPtr pftCacheResync;
///
/// Optional. Specify a pointer to a CERT_STRONG_SIGN_PARA structure to enable strong signature checking.
/// Windows 8 and Windows Server 2012: Support for this member begins.
///
/// Note This member can be used only if CERT_CHAIN_PARA_HAS_EXTRA_FIELDS is defined by using the #define
/// directive before including Wincrypt.h. If this value is defined, the application must zero all unused fields.
///
///
public IntPtr pStrongSignPara;
///
/// Optional flags that modify chain retrieval behavior. This can be zero or the following value.
///
///
/// Value
/// Meaning
///
/// -
/// CERT_CHAIN_STRONG_SIGN_DISABLE_END_CHECK_FLAG 0x00000001
///
/// 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.
///
///
///
/// Windows 8 and Windows Server 2012: Support for this property begins.
///
/// Note This member can be used only if CERT_CHAIN_PARA_HAS_EXTRA_FIELDS is defined by using the #define
/// directive before including Wincrypt.h. If this value is defined, the application must zero all unused fields.
///
///
public uint dwStrongSignFlags;
}
///
/// The CERT_CHAIN_POLICY_PARA structure contains information used in CertVerifyCertificateChainPolicy to establish policy
/// criteria for the verification of certificate chains.
///
// 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
{
/// The size, in bytes, of this structure.
public uint cbSize;
///
///
/// A set of flags that indicate conditions that could potentially be not valid and that are to be ignored in building
/// certificate chains.
///
/// The pszPolicyOID parameter of the CertVerifyCertificateChainPolicy function can contain one of the following values:
///
/// -
/// CERT_CHAIN_POLICY_BASE
///
/// -
/// CERT_CHAIN_POLICY_AUTHENTICODE
///
/// -
/// CERT_CHAIN_POLICY_AUTHENTICODE_TS
///
/// -
/// CERT_CHAIN_POLICY_SSL
///
/// -
/// CERT_CHAIN_POLICY_NT_AUTH
///
///
/// If the
/// pszPolicyOID
/// parameter of the
/// CertVerifyCertificateChainPolicy
///
/// function contains one of the preceding values, then this member can be zero or a combination of one or more of the following values.
///
///
///
/// Value
/// Meaning
///
/// -
/// CERT_CHAIN_POLICY_IGNORE_NOT_TIME_VALID_FLAG
/// Ignore not time valid errors.
///
/// -
/// CERT_CHAIN_POLICY_IGNORE_CTL_NOT_TIME_VALID_FLAG
/// Ignore certificate trust list (CTL) not time valid errors.
///
/// -
/// CERT_CHAIN_POLICY_IGNORE_NOT_TIME_NESTED_FLAG
/// Ignore time nesting errors.
///
/// -
/// CERT_CHAIN_POLICY_IGNORE_ALL_NOT_TIME_VALID_FLAGS
/// Ignore all time validity errors.
///
/// -
/// CERT_CHAIN_POLICY_IGNORE_INVALID_BASIC_CONSTRAINTS_FLAG
/// Ignore basic constraint errors.
///
/// -
/// CERT_CHAIN_POLICY_ALLOW_UNKNOWN_CA_FLAG
/// Allow untrusted roots.
///
/// -
/// CERT_CHAIN_POLICY_IGNORE_WRONG_USAGE_FLAG
/// Ignore invalid usage errors.
///
/// -
/// CERT_CHAIN_POLICY_IGNORE_INVALID_NAME_FLAG
/// Ignore invalid name errors.
///
/// -
/// CERT_CHAIN_POLICY_IGNORE_INVALID_POLICY_FLAG
/// Ignore invalid policy errors.
///
/// -
/// CERT_CHAIN_POLICY_IGNORE_END_REV_UNKNOWN_FLAG
/// Ignores errors in obtaining valid revocation information.
///
/// -
/// CERT_CHAIN_POLICY_IGNORE_CTL_SIGNER_REV_UNKNOWN_FLAG
/// Ignores errors in obtaining valid CTL revocation information.
///
/// -
/// CERT_CHAIN_POLICY_IGNORE_CA_REV_UNKNOWN_FLAG
/// Ignores errors in obtaining valid certification authority (CA) revocation information.
///
/// -
/// CERT_CHAIN_POLICY_IGNORE_ROOT_REV_UNKNOWN_FLAG
/// Ignores errors in obtaining valid root revocation information.
///
/// -
/// CERT_CHAIN_POLICY_IGNORE_ALL_REV_UNKNOWN_FLAGS
/// Ignores errors in obtaining valid revocation information.
///
/// -
/// CERT_CHAIN_POLICY_ALLOW_TESTROOT_FLAG
/// Allow untrusted test roots.
///
/// -
/// CERT_CHAIN_POLICY_TRUST_TESTROOT_FLAG
/// Always trust test roots.
///
/// -
/// CERT_CHAIN_POLICY_IGNORE_NOT_SUPPORTED_CRITICAL_EXT_FLAG
/// Ignore critical extension not supported errors.
///
/// -
/// CERT_CHAIN_POLICY_IGNORE_PEER_TRUST_FLAG
/// Ignore peer trusts.
///
///
///
/// If the pszPolicyOID parameter of the CertVerifyCertificateChainPolicy function contains
/// CERT_CHAIN_POLICY_BASIC_CONSTRAINTS, this member can be zero or a combination of one or more of the following values.
///
///
///
/// Value
/// Meaning
///
/// -
/// CERT_CHAIN_POLICY_IGNORE_PEER_TRUST_FLAG
/// Ignore peer trusts.
///
/// -
/// BASIC_CONSTRAINTS_CERT_CHAIN_POLICY_CA_FLAG
/// Checks if the first certificate element is a CA.
///
/// -
/// BASIC_CONSTRAINTS_CERT_CHAIN_POLICY_END_ENTITY_FLAG
/// Checks if the first certificate element is an end entity.
///
///
///
/// If the pszPolicyOID parameter of the CertVerifyCertificateChainPolicy function contains
/// CERT_CHAIN_POLICY_MICROSOFT_ROOT, this member can be zero or the following value.
///
///
///
/// Value
/// Meaning
///
/// -
/// MICROSOFT_ROOT_CERT_CHAIN_POLICY_ENABLE_TEST_ROOT_FLAG
/// Also check for the Microsoft test roots in addition to the Microsoft public root.
///
///
///
public CertChainPolicyFlags dwFlags;
/// The address of a pszPolicyOID-specific structure that provides additional validity policy conditions.
public IntPtr pvExtraPolicyPara;
}
///
/// The CERT_CHAIN_POLICY_STATUS structure holds certificate chain status information returned by the
/// CertVerifyCertificateChainPolicy function when the certificate chains are validated.
///
///
/// If both lChainIndex and lElementIndex are set to –1, the error or condition that is not valid applies to the whole
/// chain context. If only lElementIndex is set to –1, the error or condition that is not valid applies to the chain indexed
/// by lChainIndex. Otherwise, the error or condition that is not valid applies to the certificate element at
/// pChainContext->rgpChain[ lChainIndex]->rgpElement[ lElementIndex].
///
// 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
{
/// The size, in bytes, of this structure.
public uint cbSize;
///
///
/// 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.
///
/// Base Policy errors ( CERT_CHAIN_POLICY_BASE)
///
///
/// Value
/// Meaning
///
/// -
/// TRUST_E_CERT_SIGNATURE 0x80096004L
/// The signature of the certificate cannot be verified.
///
/// -
/// CRYPT_E_REVOKED 0x80092010L
/// The certificate or signature has been revoked.
///
/// -
/// CERT_E_UNTRUSTEDROOT 0x800B0109L
/// A certification chain processed correctly but terminated in a root certificate that is not trusted by the trust provider.
///
/// -
/// CERT_E_UNTRUSTEDTESTROOT 0x800B010DL
/// The root certificate is a testing certificate, and policy settings disallow test certificates.
///
/// -
/// CERT_E_CHAINING 0x800B010AL
/// A chain of certificates was not correctly created.
///
/// -
/// CERT_E_WRONG_USAGE 0x800B0110L
/// The certificate is not valid for the requested usage.
///
/// -
/// CERT_E_EXPIRED 0x800B0101L
/// A required certificate is not within its validity period.
///
/// -
/// CERT_E_INVALID_NAME 0x800B0114L
/// The certificate has an invalid name. Either the name is not included in the permitted list, or it is explicitly excluded.
///
/// -
/// CERT_E_INVALID_POLICY 0x800B0113L
/// The certificate has an invalid policy.
///
/// -
/// TRUST_E_BASIC_CONSTRAINTS 0x80096019L
/// The basic constraints of the certificate are not valid, or they are missing.
///
/// -
/// CERT_E_CRITICAL 0x800B0105L
/// The certificate is being used for a purpose other than the purpose specified by its CA.
///
/// -
/// CERT_E_VALIDITYPERIODNESTING 0x800B0102L
/// The validity periods of the certification chain do not nest correctly.
///
/// -
/// CRYPT_E_NO_REVOCATION_CHECK 0x80092012L
/// The revocation function was unable to check revocation for the certificate.
///
/// -
/// CRYPT_E_REVOCATION_OFFLINE 0x80092013L
/// The revocation function was unable to check revocation because the revocation server was offline.
///
///
/// Basic Constraints Policy errors ( CERT_CHAIN_POLICY_BASIC_CONSTRAINTS).
///
///
/// Value
/// Meaning
///
/// -
/// TRUST_E_BASIC_CONSTRAINTS 0x80096019L
/// The basic constraints of the certificate are not valid, or they are missing.
///
///
/// Authenticode Policy errors ( CERT_CHAIN_POLICY_AUTHENTICODE and CERT_CHAIN_POLICY_AUTHENTICODE_TS).
/// These errors are in addition to the Base Policy errors.
///
///
/// Value
/// Meaning
///
/// -
/// CERT_E_PURPOSE 0x800B0106L
/// The certificate is being used for a purpose other than one specified by the issuing CA.
///
/// -
/// CERT_E_REVOKED 0x800B010CL
/// The certificate has been explicitly revoked by the issuer.
///
/// -
/// CERT_E_REVOCATION_FAILURE 0x800B010EL
/// The revocation process could not continue, and the certificate could not be checked.
///
///
/// SSL Policy errors ( CERT_CHAIN_POLICY_SSL).
/// These errors are in addition to the Base Policy errors.
///
///
/// Value
/// Meaning
///
/// -
/// CERT_E_UNTRUSTEDROOT 0x800B0109L
/// A certification chain processed correctly but terminated in a root certificate that is not trusted by the trust provider.
///
/// -
/// CERT_E_CN_NO_MATCH 0x800B010FL
/// The certificate's CN name does not match the passed value.
///
/// -
/// CERT_E_PURPOSE 0x800B0106L
/// The certificate is being used for a purpose other than the purposes specified by its CA.
///
/// -
/// CERT_E_ROLE 0x800B0103L
/// A certificate that can only be used as an end-entity is being used as a CA or vice versa.
///
///
/// Microsoft Root Policy errors ( CERT_CHAIN_POLICY_MICROSOFT_ROOT).
///
///
/// Value
/// Meaning
///
/// -
/// CERT_E_UNTRUSTEDROOT 0x800B0109L
/// A certification chain processed correctly but terminated in a root certificate that is not trusted by the trust provider.
///
///
/// EV Policy errors.
///
///
/// Value
/// Meaning
///
/// -
/// CERT_E_CHAINING 0x800B010AL
/// The certificate chain to a trusted root authority could not be built.
///
/// -
/// CERT_E_WRONG_USAGE 0x800B0110L
/// The certificate is not valid for the requested usage.
///
///
///
public uint dwError;
///
/// Index that indicates the chain in which an error or condition that is not valid was found. For more information, see Remarks.
///
public int lChainIndex;
///
/// Index that indicates the element in a chain where an error or condition that is not valid was found. For more information,
/// see Remarks.
///
public int lElementIndex;
///
/// A pointer to a structure. The structure type is determined by the value of the pszPolicyOID parameter of the
/// CertVerifyCertificateChainPolicy function. In addition to dwError errors, policy OID–specific 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.
///
public IntPtr pvExtraPolicyStatus;
}
///
/// The CERT_USAGE_MATCH structure provides criteria for identifying issuer certificates to be used to build a certificate chain.
///
///
/// If the dwType member is set to USAGE_MATCH_TYPE_OR, the Usage member cannot be empty.
///
/// If the dwType member is set to USAGE_MATCH_TYPE_AND, an empty Usage member means that any nested usage in the chain will work.
///
/// The following describes the behavior given two enhanced key usage (EKU) extensions EKU A and EKU B.
/// AND Logic
///
/// 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.)
///
/// OR Logic
///
/// 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.
///
///
/// Besides the simple case where the certificates in the path contain EKU A or EKU B, the OR clause has the following
/// special evaluation.
///
/// Given the following path, the OR test is deemed valid:
///
/// 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.
///
///
// 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
{
///
///
/// Determines the kind of issuer matching to be done. In AND logic, the certificate must meet all criteria. In OR
/// 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.
///
///
///
/// Value
/// Meaning
///
/// -
/// USAGE_MATCH_TYPE_AND
/// AND logic
///
/// -
/// USAGE_MATCH_TYPE_OR
/// OR logic
///
///
/// Default usage match logic is USAGE_MATCH_TYPE_AND.
///
public UsageMatchType dwType;
///
/// CERT_ENHKEY_USAGE structure ( CERT_ENHKEY_USAGE is an alternate typedef name for the CTL_USAGE structure) that
/// includes an array of certificate object identifiers (OIDs) that a certificate must match in order to be valid.
///
public CTL_USAGE Usage;
}
///
/// The CMSG_SIGNED_ENCODE_INFO structure contains information to be passed to CryptMsgOpenToEncode if dwMsgType is CMSG_SIGNED.
///
// 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
{
/// Size of this structure in bytes.
public uint cbSize;
/// Number of elements in the rgSigners array.
public uint cSigners;
/// Array of pointers to CMSG_SIGNER_ENCODE_INFOstructures each holding signer information.
public IntPtr rgSigners;
/// Number of elements in the rgCertEncoded array.
public uint cCertEncoded;
/// Array of pointers to CERT_BLOB structures, each containing an encoded certificate.
public IntPtr rgCertEncoded;
/// Number of elements in the rgCrlEncoded array.
public uint cCrlEncoded;
/// Array of pointers to CRL_BLOB structures, each containing an encoded CRL.
public IntPtr rgCrlEncoded;
///
/// Number of elements in the rgAttrCertEncoded array. Used only if CMSG_SIGNED_ENCODE_INFO_HAS_CMS_FIELDS is defined.
///
public uint cAttrCertEncoded;
///
/// 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.
///
public IntPtr rgAttrCertEncoded;
}
///
/// The CTL_VERIFY_USAGE_PARA structure contains parameters used by CertVerifyCTLUsage to establish the validity of a CTL's usage.
///
// 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
{
/// Size of this structure in bytes.
public uint cbSize;
///
///
/// BLOB that specifies a ListIdentifier of a CTL to be found or verified. Normally the cbData member of the
/// ListIdentifier BLOB will be zero, indicating that a CTL with any ListIdentifier can be a match.
///
///
/// To match only CTLs with no ListIdentifier, the cbData member of the ListIdentifier BLOB is set to CTL_FIND_NO_LIST_ID_CBDATA.
///
///
/// If an issuer creates multiple CTLs for the same SubjectUsage, a ListIdentifier can distinguish among them.
///
///
public CRYPTOAPI_BLOB ListIdentifier;
/// The count of stores to be searched for a matching CTL.
public uint cCtlStore;
/// Array of handles of stores to be searched to find a matching CTL.
public IntPtr rghCtlStore;
/// Count of stores to be searched for acceptable CTL signers.
public uint cSignerStore;
/// Array of handles of stores to be searched for acceptable CTL signers.
public IntPtr rghSignerStore;
}
///
/// The CTL_VERIFY_USAGE_STATUS structure contains information about a Certificate Trust List (CTL) returned by CertVerifyCTLUsage.
///
///
/// The members dwError, dwFlags, dwCtlEntryIndex, and dwSignerIndex should be initialized to zero by
/// the calling application.
///
// 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
{
///
/// The size, in bytes, of the structure. The application calling CertVerifyCTLUsage sets this parameter. If cbSize is
/// not greater than or equal to the required size of the structure, CertVerifyCTLUsage returns FALSE and
/// GetLastError returns E_INVALIDARG.
///
public uint cbSize;
///
/// The error status, if any, returned by the call to CertVerifyCTLUsage. For the list of possible error values, see the Return
/// Values section in CertVerifyCTLUsage.
///
public uint dwError;
///
/// If CERT_VERIFY_UPDATED_CTL_FLAG is returned, CertVerifyCTLUsage updated a CTL whose time was no longer valid with a
/// new, time-valid CTL.
///
public CtlVerifyUsageStatusFlags dwFlags;
///
///
/// Pointer to a pointer to a CTL context containing the matched subject. The calling application can set this pointer to
/// NULL to indicate that a CTL containing the subject is not to be returned.
///
/// If ppCtl is not NULL, the calling application must free the returned context using CertFreeCTLContext.
///
public IntPtr ppCtl;
/// Returns the array location of the matching subject's entry in the CTL's array.
public uint dwCtlEntryIndex;
///
///
/// A pointer to a pointer to the certificate context of the signer of the CTL. This pointer can be set to NULL by the
/// calling application indicating that the certificate of the signer of the CTL is not to be returned.
///
/// If ppSigner is not NULL, the calling application must free the returned context using CertFreeCTLContext.
///
public IntPtr ppSigner;
/// Index of the signer actually used. Needed if a message has more than one signer.
public uint dwSignerIndex;
}
/// Provides a handle to a CERT_CHAIN_CONTEXT.
[StructLayout(LayoutKind.Sequential)]
public struct PCCERT_CHAIN_CONTEXT : IHandle
{
private IntPtr handle;
/// Initializes a new instance of the struct.
/// An object that represents the pre-existing handle to use.
public PCCERT_CHAIN_CONTEXT(IntPtr preexistingHandle) => handle = preexistingHandle;
/// Returns an invalid handle by instantiating a object with .
public static PCCERT_CHAIN_CONTEXT NULL => new PCCERT_CHAIN_CONTEXT(IntPtr.Zero);
/// Gets a value indicating whether this instance is a null handle.
public bool IsNull => handle == IntPtr.Zero;
/// Performs an explicit conversion from to .
/// The handle.
/// The result of the conversion.
public static explicit operator IntPtr(PCCERT_CHAIN_CONTEXT h) => h.handle;
/// Performs an explicit conversion from to .
/// The instance.
/// The resulting instance from the conversion.
public static explicit operator CERT_CHAIN_CONTEXT(PCCERT_CHAIN_CONTEXT h) => h.handle.ToStructure();
/// Performs an implicit conversion from to .
/// The pointer to a handle.
/// The result of the conversion.
public static implicit operator PCCERT_CHAIN_CONTEXT(IntPtr h) => new PCCERT_CHAIN_CONTEXT(h);
/// Implements the operator !=.
/// The first handle.
/// The second handle.
/// The result of the operator.
public static bool operator !=(PCCERT_CHAIN_CONTEXT h1, PCCERT_CHAIN_CONTEXT h2) => !(h1 == h2);
/// Implements the operator ==.
/// The first handle.
/// The second handle.
/// The result of the operator.
public static bool operator ==(PCCERT_CHAIN_CONTEXT h1, PCCERT_CHAIN_CONTEXT h2) => h1.Equals(h2);
///
public override bool Equals(object obj) => obj is PCCERT_CHAIN_CONTEXT h ? handle == h.handle : false;
///
public override int GetHashCode() => handle.GetHashCode();
///
public IntPtr DangerousGetHandle() => handle;
}
/// Provides a for that is disposed using .
public class SafeHCERTCHAINENGINE : SafeHANDLE
{
/// Initializes a new instance of the class and assigns an existing handle.
/// An object that represents the pre-existing handle to use.
///
/// to reliably release the handle during the finalization phase; otherwise, (not recommended).
///
public SafeHCERTCHAINENGINE(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { }
/// Initializes a new instance of the class.
private SafeHCERTCHAINENGINE() : base() { }
/// Performs an implicit conversion from to .
/// The safe handle instance.
/// The result of the conversion.
public static implicit operator HCERTCHAINENGINE(SafeHCERTCHAINENGINE h) => h.handle;
///
protected override bool InternalReleaseHandle() { CertFreeCertificateChainEngine(handle); return true; }
}
/// Provides a for that is disposed using .
public class SafePCCERT_CHAIN_CONTEXT : SafeHANDLE
{
/// Initializes a new instance of the class and assigns an existing handle.
/// An object that represents the pre-existing handle to use.
///
/// to reliably release the handle during the finalization phase; otherwise, (not recommended).
///
public SafePCCERT_CHAIN_CONTEXT(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { }
/// Initializes a new instance of the class.
private SafePCCERT_CHAIN_CONTEXT() : base() { }
/// Performs an implicit conversion from to .
/// The safe handle instance.
/// The result of the conversion.
public static implicit operator PCCERT_CHAIN_CONTEXT(SafePCCERT_CHAIN_CONTEXT h) => h.handle;
/// Performs an explicit conversion from to .
/// The safe handle instance.
/// The resulting instance from the conversion.
public static explicit operator CERT_CHAIN_CONTEXT(SafePCCERT_CHAIN_CONTEXT h) => h.handle.ToStructure();
///
protected override bool InternalReleaseHandle() { CertFreeCertificateChain(handle); return true; }
}
/// Predefined verify chain policies.
public static class CertVerifyChainPolicy
{
///
public const int CERT_CHAIN_POLICY_BASE = 1;
///
public const int CERT_CHAIN_POLICY_AUTHENTICODE = 2;
///
public const int CERT_CHAIN_POLICY_AUTHENTICODE_TS = 3;
///
public const int CERT_CHAIN_POLICY_SSL = 4;
///
public const int CERT_CHAIN_POLICY_BASIC_CONSTRAINTS = 5;
///
public const int CERT_CHAIN_POLICY_NT_AUTH = 6;
///
public const int CERT_CHAIN_POLICY_MICROSOFT_ROOT = 7;
///
public const int CERT_CHAIN_POLICY_EV = 8;
///
public const int CERT_CHAIN_POLICY_SSL_F12 = 9;
///
public const int CERT_CHAIN_POLICY_SSL_HPKP_HEADER = 10;
///
public const int CERT_CHAIN_POLICY_THIRD_PARTY_ROOT = 11;
///
public const int CERT_CHAIN_POLICY_SSL_KEY_PIN = 12;
}
}
}