using System; using System.Runtime.InteropServices; namespace Vanara.PInvoke { /// Methods and data types found in Crypt32.dll. public static partial class Crypt32 { /// The CertAddCTLContextToStore function adds a certificate trust list (CTL) context to a certificate store. /// Handle of a certificate store. /// A pointer to the CTL_CONTEXT structure to be added to the store. /// /// /// Specifies the action to take if a matching CTL or a link to a matching CTL already exists in the store. Currently defined /// disposition values and their uses are as follows. /// /// /// /// Value /// Meaning /// /// /// CERT_STORE_ADD_ALWAYS /// /// Makes no check for an existing matching CTL or link to a matching CTL. A new CTL is always added to the store. This can lead to /// duplicates in a store. /// /// /// /// CERT_STORE_ADD_NEW /// If a matching CTL or a link to a matching CTL exists, the operation fails. GetLastError returns the CRYPT_E_EXISTS code. /// /// /// CERT_STORE_ADD_NEWER /// /// If a matching CTL or a link to a matching CTL exists, the ThisUpdate times on the CTLs are compared. If the existing CTL has a /// ThisUpdate time less than the ThisUpdate time on the new CTL, the old CTL or link is replaced just as with /// CERT_STORE_ADD_REPLACE_EXISTING. If the existing CTL has a ThisUpdate time greater than or equal to the ThisUpdate time on the /// CTL to be added, the function fails with GetLastError returning the CRYPT_E_EXISTS code. If a matching CTL or a link to a /// matching CTL is not found in the store, a new CTL is added to the store. /// /// /// /// CERT_STORE_ADD_NEWER_INHERIT_PROPERTIES /// /// The action is the same as for CERT_STORE_ADD_NEWER, except that if an older CTL is replaced, the properties of the older CTL are /// incorporated into the replacement CTL. /// /// /// /// CERT_STORE_ADD_REPLACE_EXISTING /// /// If a matching CTL or a link to a matching CTL exists, the existing CTL or link is deleted and a new CTL is created and added to /// the store. If a matching CTL or a link to a matching CTL does not exist, one is added. /// /// /// /// CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES /// /// If a matching CTL exists in the store, that existing context is deleted before creating and adding the new context. The added /// context inherits properties from the existing CTL. /// /// /// /// CERT_STORE_ADD_USE_EXISTING /// /// If a matching CTL or a link to a matching CTL exists, that existing CTL is used and properties from the new CTL are added. The /// function does not fail, but no new CTL is added. If ppCertContext is not NULL, the existing context is duplicated. If a matching /// CTL or a link to a matching CTL does not exist, a new CTL is added. /// /// /// /// /// /// Pointer to a pointer to the decoded CTL context. This optional parameter can be NULL indicating that the calling /// application does not require a copy of the added or existing CTL. If a copy is made, that context must be freed using CertFreeCTLContext. /// /// /// If the function succeeds, the return value is TRUE. /// /// If the function fails, the return value is FALSE. Errors from the called functions CertAddEncodedCRLToStore and /// CertSetCRLContextProperty can be propagated to this function. /// /// For extended error information, call GetLastError. Some possible error codes follow. /// /// /// Return code /// Description /// /// /// CRYPT_E_EXISTS /// /// This error is returned if CERT_STORE_ADD_NEW is set and the CTL exists in the store or if CERT_STORE_ADD_NEWER is set and a CTL /// exists in the store with a ThisUpdate date greater than or equal to the ThisUpdate date on the CTL to be added. /// /// /// /// E_INVALIDARG /// An add disposition that is not valid was specified by the dwAddDisposition parameter. /// /// /// /// /// /// The CTL context is not duplicated using CertDuplicateCTLContext. Instead, a new copy is created and added to the store. In /// addition to the encoded CTL, the context's properties are copied. /// /// To remove the CTL context from the certificate store, use the CertDeleteCTLFromStore function. /// // https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-certaddctlcontexttostore BOOL CertAddCTLContextToStore( // HCERTSTORE hCertStore, PCCTL_CONTEXT pCtlContext, DWORD dwAddDisposition, PCCTL_CONTEXT *ppStoreContext ); [DllImport(Lib.Crypt32, SetLastError = true, ExactSpelling = true)] [PInvokeData("wincrypt.h", MSDNShortId = "e8858f75-77a1-4c5f-a3e3-a645c5e0f053")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool CertAddCTLContextToStore(HCERTSTORE hCertStore, [In] PCCTL_CONTEXT pCtlContext, CertStoreAdd dwAddDisposition, out SafePCCTL_CONTEXT ppStoreContext); /// /// The CertAddCTLLinkToStore function adds a link in a store to a certificate trust list (CTL) context in a different store. /// Instead of creating and adding a duplicate of a CTL context, this function adds a link to the original CTL context. /// /// Handle of the certificate store where the link is to be added. /// A pointer to the CTL_CONTEXT structure to be linked. /// /// /// Specifies the action to take if a matching CTL or a link to a matching CTL already exists in the store. Currently defined /// disposition values and their uses are as follows. /// /// /// /// Value /// Meaning /// /// /// CERT_STORE_ADD_ALWAYS /// /// Makes no check for an existing matching CTL or link to a matching CTL. A new CTL is always added to the store. This can lead to /// duplicates in a store. /// /// /// /// CERT_STORE_ADD_NEW /// If a matching CTL or a link to a matching CTL exists, the operation fails. GetLastError returns the CRYPT_E_EXISTS code. /// /// /// CERT_STORE_ADD_NEWER /// /// If a matching CTL or a link to a matching CTL exists, the ThisUpdate times on the CTLs are compared. If the existing CTL has a /// ThisUpdate time less than the ThisUpdate time on the new CTL, the old CTL or link is replaced just as with /// CERT_STORE_ADD_REPLACE_EXISTING. If the existing CTL has a ThisUpdate time greater than or equal to the ThisUpdate time on the /// CTL to be added, the function fails with GetLastError returning the CRYPT_E_EXISTS code. If a matching CTL or a link to a /// matching CTL is not found in the store, a new CTL is added to the store. /// /// /// /// CERT_STORE_ADD_NEWER_INHERIT_PROPERTIES /// /// The action is the same as for CERT_STORE_ADD_NEWER, except that if an older CTL is replaced, the properties of the older CTL are /// incorporated into the replacement CTL. /// /// /// /// CERT_STORE_ADD_REPLACE_EXISTING /// /// If a matching CTL or a link to a matching CTL exists, the existing CTL or link is deleted and a new CTL is created and added to /// the store. If a matching CTL or a link to a matching CTL does not exist, one is added. /// /// /// /// CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES /// /// If a matching CTL exists in the store, that existing context is deleted before creating and adding the new context. The added /// context inherits properties from the existing CTL. /// /// /// /// CERT_STORE_ADD_USE_EXISTING /// /// If a matching CTL or a link to a matching CTL exists, that existing CTL is used and properties from the new CTL are added. The /// function does not fail, but no new CTL is added. If ppCertContext is not NULL, the existing context is duplicated. If a matching /// CTL or a link to a matching CTL does not exist, a new CTL is added. /// /// /// /// /// /// A pointer to a pointer to a copy of the link created. ppStoreContext can be NULL to indicate that a copy of the link is /// not needed. If a copy of the link is created, that copy must be freed using CertFreeCTLContext. /// /// /// If the function succeeds, the return value is TRUE. /// /// If the function fails, the return value is FALSE. For extended error information, call GetLastError. Some possible error /// codes follow. /// /// /// /// Return code /// Description /// /// /// CRYPT_E_EXISTS /// For a dwAddDisposition of CERT_STORE_ADD_NEW, the CTL already exists in the store. /// /// /// E_INVALIDARG /// The add disposition specified by the dwAddDisposition parameter is not valid. /// /// /// /// /// /// Because the link provides access to the original CTL context, setting an extended property in the linked CTL context changes /// that extended property in the original CTL's location and in any other links to that CTL. /// /// /// Links cannot be added to a store that is opened as a collection. Stores opened as collections include all stores opened with /// CertOpenSystemStore or CertOpenStore using CERT_STORE_PROV_SYSTEM or CERT_STORE_PROV_COLLECTION. Also see CertAddStoreToCollection. /// /// /// When links are used and CertCloseStore is called with CERT_CLOSE_STORE_FORCE_FLAG, the store using links must be closed before /// the store containing the original contexts is closed. If CERT_CLOSE_STORE_FORCE_FLAG is not used, the two stores can be closed /// in either order. /// /// To remove the CTL context link from the certificate store, use the CertDeleteCTLFromStore function. /// // https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-certaddctllinktostore BOOL CertAddCTLLinkToStore( // HCERTSTORE hCertStore, PCCTL_CONTEXT pCtlContext, DWORD dwAddDisposition, PCCTL_CONTEXT *ppStoreContext ); [DllImport(Lib.Crypt32, SetLastError = true, ExactSpelling = true)] [PInvokeData("wincrypt.h", MSDNShortId = "c129aeae-69d9-440a-979d-e9e481c64538")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool CertAddCTLLinkToStore(HCERTSTORE hCertStore, [In] PCCTL_CONTEXT pCtlContext, CertStoreAdd dwAddDisposition, out SafePCCTL_CONTEXT ppStoreContext); /// /// The CertAddEncodedCTLToStore function creates a certificate trust list (CTL) context from an encoded CTL and adds it to /// the certificate store. The function makes a copy of the CTL context before adding it to the store. /// /// Handle of a certificate store. /// /// /// Specifies the type of encoding used. Both the certificate and message encoding types must be specified 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 a buffer containing the encoded CTL to be added to the certificate store. /// The size, in bytes, of the pbCtlEncoded buffer. /// /// /// Specifies the action to take if a matching CTL or a link to a matching CTL already exists in the store. Currently defined /// disposition values and their uses are as follows /// /// /// /// Value /// Meaning /// /// /// CERT_STORE_ADD_ALWAYS /// /// Makes no check for an existing matching CTL or link to a matching CTL. A new CTL is always added to the store. This can lead to /// duplicates in a store. /// /// /// /// CERT_STORE_ADD_NEW /// If a matching CTL or a link to a matching CTL exists, the operation fails. GetLastError returns the CRYPT_E_EXISTS code. /// /// /// CERT_STORE_ADD_NEWER /// /// If a matching CTL or a link to a matching CTL exists, the ThisUpdate times on the CTLs are compared. If the existing CTL has a /// ThisUpdate time less than the ThisUpdate time on the new CTL, the old CTL or link is replaced just as with /// CERT_STORE_ADD_REPLACE_EXISTING. If the existing CTL has a ThisUpdate time greater than or equal to the ThisUpdate time on the /// CTL to be added, the function fails with GetLastError returning the CRYPT_E_EXISTS code. If a matching CTL or a link to a /// matching CTL is not found in the store, a new CTL is added to the store. /// /// /// /// CERT_STORE_ADD_NEWER_INHERIT_PROPERTIES /// /// The action is the same as for CERT_STORE_ADD_NEWER, except that if an older CTL is replaced, the properties of the older CTL are /// incorporated into the replacement CTL. /// /// /// /// CERT_STORE_ADD_REPLACE_EXISTING /// /// If a matching CTL or a link to a matching CTL exists, the existing CTL or link is deleted and a new CTL is created and added to /// the store. If a matching CTL or a link to a matching CTL does not exist, one is added. /// /// /// /// CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES /// /// If a matching CTL exists in the store, that existing context is deleted before creating and adding the new context. The added /// context inherits properties from the existing CTL. /// /// /// /// CERT_STORE_ADD_USE_EXISTING /// /// If a matching CTL or a link to a matching CTL exists, that existing CTL is used and properties from the new CTL are added. The /// function does not fail, but no new CTL is added. If ppCertContext is not NULL, the existing context is duplicated. If a matching /// CTL or a link to a matching CTL does not exist, a new CTL is added. /// /// /// /// /// /// A pointer to a pointer to the decoded CTL_CONTEXT structure. Can be NULL indicating that the calling application does not /// require a copy of the added or existing CTL. If a copy is made, it must be freed by using CertFreeCTLContext. /// /// /// If the function succeeds, the return value is TRUE. /// If the function fails, the return value is FALSE. For extended error information, call GetLastError. /// Some possible error codes follow. /// /// /// Return code /// Description /// /// /// CRYPT_E_EXISTS /// /// CERT_STORE_ADD_NEW is set, and the CTL already exists in the store; or CERT_STORE_ADD_NEWER is set and there is a CTL in the /// store with a ThisUpdate time greater than or equal to the ThisUpdate time on the CTL to be added. /// /// /// /// E_INVALIDARG /// /// A disposition value that is not valid was specified in the dwAddDisposition parameter, or an encoding type that is not valid was /// specified. Currently, only the encoding types X509_ASN_ENCODING and PKCS_7_ASN_ENCODING are supported. /// /// /// /// /// If the function fails, GetLastError may return an Abstract Syntax Notation One (ASN.1) encoding/decoding error. For information /// about these errors, see ASN.1 Encoding/Decoding Return Values. /// /// // https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-certaddencodedctltostore BOOL CertAddEncodedCTLToStore( // HCERTSTORE hCertStore, DWORD dwMsgAndCertEncodingType, const BYTE *pbCtlEncoded, DWORD cbCtlEncoded, DWORD dwAddDisposition, // PCCTL_CONTEXT *ppCtlContext ); [DllImport(Lib.Crypt32, SetLastError = true, ExactSpelling = true)] [PInvokeData("wincrypt.h", MSDNShortId = "4239d43e-187d-4f40-99ae-6f914b7577ac")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool CertAddEncodedCTLToStore(HCERTSTORE hCertStore, CertEncodingType dwMsgAndCertEncodingType, [In] IntPtr pbCtlEncoded, uint cbCtlEncoded, CertStoreAdd dwAddDisposition, out SafePCCTL_CONTEXT ppCtlContext); /// /// The CertCreateCTLContext function creates a certificate trust list (CTL) context from an encoded CTL. The created context /// is not persisted to a certificate store. The function makes a copy of the encoded CTL within the created context. /// /// /// /// Specifies the type of encoding used. Both the certificate and message encoding types must be specified 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 a buffer containing the encoded CTL from which the context is to be created. /// The size, in bytes, of the pbCtlEncoded buffer. /// /// If the function succeeds, the return value is a pointer to a read-only CTL_CONTEXT. /// /// If the function fails and is unable to decode and create the CTL_CONTEXT, the return value is NULL. For extended error /// information, call GetLastError. The following table shows a possible error code. /// /// /// /// Return code /// Description /// /// /// E_INVALIDARG /// Invalid certificate encoding type. Only PKCS_7_ASN_ENCODING and X509_ASN_ENCODING are supported. /// /// /// /// If the function fails, GetLastError may return an Abstract Syntax Notation One (ASN.1) encoding/decoding error. For information /// about these errors, see ASN.1 Encoding/Decoding Return Values. /// /// /// /// The CTL_CONTEXT must be freed by calling CertFreeCTLContext. CertDuplicateCTLContext can be called to make a duplicate. /// CertSetCTLContextProperty and CertGetCTLContextProperty can be called to store and read properties for the CTL. /// // https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-certcreatectlcontext PCCTL_CONTEXT CertCreateCTLContext( // DWORD dwMsgAndCertEncodingType, const BYTE *pbCtlEncoded, DWORD cbCtlEncoded ); [DllImport(Lib.Crypt32, SetLastError = true, ExactSpelling = true)] [PInvokeData("wincrypt.h", MSDNShortId = "172c59ee-9e06-4169-aaa7-2624e3fcf015")] public static extern SafePCCTL_CONTEXT CertCreateCTLContext(CertEncodingType dwMsgAndCertEncodingType, [In] IntPtr pbCtlEncoded, uint cbCtlEncoded); /// /// The CertDeleteCTLFromStore function deletes the specified certificate trust list (CTL) context from a certificate store. /// /// A pointer to the CTL_CONTEXT structure to be deleted. /// /// If the function succeeds, the return value is TRUE. /// /// If the function fails, the return value is FALSE. For extended error information, call GetLastError. One possible error /// code is the following. /// /// /// /// Return code /// Description /// /// /// E_ACCESSDENIED /// The store was opened read-only, and a delete operation is not allowed. /// /// /// /// /// /// All subsequent get or find operations for the CTL in this store fail. However, memory allocated for the CTL is not freed until /// all duplicated contexts have also been freed. /// /// The pCtlContext parameter is always freed by this function by using CertFreeCTLContext, even for an error. /// // https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-certdeletectlfromstore BOOL CertDeleteCTLFromStore( // PCCTL_CONTEXT pCtlContext ); [DllImport(Lib.Crypt32, SetLastError = true, ExactSpelling = true)] [PInvokeData("wincrypt.h", MSDNShortId = "e24d3445-8929-463a-b771-1f25f4e999b5")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool CertDeleteCTLFromStore([In] PCCTL_CONTEXT pCtlContext); /// /// The CertDuplicateCTLContext function duplicates a certificate trust list (CTL) context by incrementing its reference count. /// /// A pointer to the CTL_CONTEXT structure for which the reference count is being incremented. /// /// Currently, a copy is not made of the context, and the returned pointer to CTL_CONTEXT is the same as pointer input. If the /// pointer passed into this function is NULL, NULL is returned. /// // https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-certduplicatectlcontext PCCTL_CONTEXT // CertDuplicateCTLContext( PCCTL_CONTEXT pCtlContext ); [DllImport(Lib.Crypt32, SetLastError = false, ExactSpelling = true)] [PInvokeData("wincrypt.h", MSDNShortId = "512d246f-9f22-4ac1-a4fc-d5c615a65cf9")] public static extern PCCTL_CONTEXT CertDuplicateCTLContext(PCCTL_CONTEXT pCtlContext); /// /// The CertEnumCTLsInStore function retrieves the first or next certificate trust list (CTL) context in a certificate store. /// Used in a loop, this function can retrieve in sequence all CTL contexts in a certificate store. /// /// Handle of a certificate store. /// /// A pointer to the previous CTL_CONTEXT structure found. It must be NULL to get the first CTL in the store. Successive CTLs /// are enumerated by setting pPrevCtlContext to the pointer returned by a previous call. This function frees the CTL_CONTEXT /// referenced by non- NULL values of this parameter. The enumeration skips any CTLs previously deleted by CertDeleteCTLFromStore. /// /// /// If the function succeeds, the return value is a pointer to a read-only CTL_CONTEXT. /// If the function fails and a CTL is not found, the return value is NULL. For extended error information, call GetLastError. /// Some possible error codes follow. /// /// /// Return code /// Description /// /// /// CRYPT_E_NOT_FOUND /// Either no CTLs exist in the store, or the function reached the end of the store's list. /// /// /// E_INVALIDARG /// The handle in the hCertStore parameter is not the same as that in the CTL context pointed to by the pPrevCtlContext parameter. /// /// /// /// /// /// The returned pointer is freed when passed as the pPrevCtlContext on a subsequent call. Otherwise, the pointer must be explicitly /// freed by calling CertFreeCTLContext. A pPrevCtlContext that is not NULL is always freed by this function (through a call /// to CertFreeCTLContext), even for an error. /// /// A duplicate can be made by calling CertDuplicateCTLContext. /// // https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-certenumctlsinstore PCCTL_CONTEXT CertEnumCTLsInStore( // HCERTSTORE hCertStore, PCCTL_CONTEXT pPrevCtlContext ); [DllImport(Lib.Crypt32, SetLastError = true, ExactSpelling = true)] [PInvokeData("wincrypt.h", MSDNShortId = "dac9f91e-8ed4-43ce-8147-485c2ed7edd5")] public static extern SafePCCTL_CONTEXT CertEnumCTLsInStore(HCERTSTORE hCertStore, [In] PCCTL_CONTEXT pPrevCtlContext); /// /// The CertFindCTLInStore function finds the first or next certificate trust list (CTL) context that matches search criteria /// established by the dwFindType and its associated pvFindPara. This function can be used in a loop to find all of the CTL contexts /// in a certificate store that match the specified find criteria. /// /// Handle of the certificate store to be searched. /// /// /// Specifies the type of encoding used on the CTL. 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 /// /// /// This parameter is used only when the dwFindType parameter is set to CTL_FIND_USAGE. /// /// /// Can be set when dwFindType is set to CTL_FIND_USAGE. For details, see the comments under CTL_FIND_USAGE, following. /// /// /// /// Specifies the type of search being made. The search type determines the data type, contents, and the use of pvFindPara. This /// parameter can be one of the following values. /// /// /// /// Value /// Meaning /// /// /// CTL_FIND_ANY /// Data type of pvFindPara: NULL. Any CTL is a match. /// /// /// CTL_FIND_SHA1_HASH /// Data type of pvFindPara: CRYPT_HASH_BLOB. A CTL with a hash matching the hash in the CRYPT_HASH_BLOB structure is found. /// /// /// CTL_FIND_MD5_HASH /// Data type of pvFindPara: CRYPT_HASH_BLOB. A CTL with a hash matching the hash in the CRYPT_HASH_BLOB structure is found. /// /// /// CTL_FIND_USAGE /// /// Data type of pvFindPara: CTL_FIND_USAGE_PARA. Any CTL is found that has a usage identifier, list identifier, or signer matching /// the usage identifier, list identifier, or signer in the CTL_FIND_USAGE_PARA structure. If the cUsageIdentifier member is of /// SubjectUsage size, any CTL is a match. If the cbData member of ListIdentifier member is zero, any list identifier is a match. If /// the cbData member of ListIdentifier is CTL_FIND_NO_LIST_ID_CBDATA, only a CTL without a list identifier is a match. If the /// pSigner member in the CTL_FIND_USAGE_PARA structure is NULL, any CTL signer is a match, and only the Issuer and SerialNumber /// members in the pSigner CERT_INFO structure are used. If pSigner is CTL_FIND_NO_SIGNER_PTR, only a CTL without a signer is a match. /// /// /// /// CTL_FIND_SAME_USAGE_FLAG /// /// Data type of pvFindPara: CTL_FIND_USAGE_PARA. Only CTLs with exactly the same usage identifiers are matched. CTLs having /// additional usage identifiers are not matched. For example, if only "1.2.3" is specified in the CTL_FIND_USAGE_PARA structure, /// then for a match, the CTL must only contain "1.2.3" and no additional usage identifiers. /// /// /// /// CTL_FIND_EXISTING /// Data type of pvFindPara: PCCTL_CONTEXT. Searches for the next CRL that is an exact match of the CTL_CONTEXT. /// /// /// CTL_FIND_SUBJECT /// /// Data type of pvFindPara: CTL_FIND_SUBJECT_PARA. A CTL having the specified subject is found. CertFindSubjectInCTL can be called /// to get a pointer to the subject's entry in the CTL. The pUsagePara member in CTL_FIND_SUBJECT_PARA can optionally be set to /// enable the matching described preceding under CTL_FIND_USAGE. /// /// /// /// /// A pointer to the search value associated with the dwFindType parameter. /// /// A pointer to the last CTL_CONTEXT returned by this function. It must be NULL to get the first CTL in the store. /// Successive CTLs are retrieved by setting pPrevCtlContext to the pointer to the CTL_CONTEXT returned by a previous /// function call. Any certificates that do not meet the search criteria or that have been previously deleted by /// CertDeleteCTLFromStore are skipped. This function frees the CTL_CONTEXT referenced by non- NULL values of this parameter. /// /// /// If the function succeeds, the return value is a pointer to a read-only CTLcontext. /// For extended error information, call GetLastError. Some possible error codes follow. /// /// /// Return code /// Description /// /// /// CRYPT_E_NOT_FOUND /// /// Either no CTLs were found in the store, no CTL was found matching the search criteria, or the function reached the end of the /// store's list. /// /// /// /// E_INVALIDARG /// /// The handle in the hCertStore parameter is not the same as that in the CTL context pointed to by the pPrevCtlContext parameter, /// or a value that is not valid was specified in the dwFindType parameter. /// /// /// /// /// /// /// A returned pointer is freed when passed as the pPrevCtlContext on a subsequent call to the function. Otherwise, the pointer must /// be freed by calling CertFreeCTLContext. A non- NULL pPrevCtlContext passed to the function is always freed with a call to /// CertFreeCTLContext, even if the function generates an error. /// /// /// CertDuplicateCTLContext can be called to make a duplicate of the returned context. The returned CTL context can be added to a /// different certificate store using CertAddCTLContextToStore, or a link to that CTL context can be added to a noncollection store /// using CertAddCTLLinkToStore. If a CTL matching the search criteria is not found, NULL is returned. /// /// // https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-certfindctlinstore PCCTL_CONTEXT CertFindCTLInStore( // HCERTSTORE hCertStore, DWORD dwMsgAndCertEncodingType, DWORD dwFindFlags, DWORD dwFindType, const void *pvFindPara, PCCTL_CONTEXT // pPrevCtlContext ); [DllImport(Lib.Crypt32, SetLastError = true, ExactSpelling = true)] [PInvokeData("wincrypt.h", MSDNShortId = "e5ed3b22-e96f-4e7d-a20e-eebed0a84d3c")] public static extern SafePCCTL_CONTEXT CertFindCTLInStore(HCERTSTORE hCertStore, CertEncodingType dwMsgAndCertEncodingType, CertInfoFlags dwFindFlags, CertFindType dwFindType, [In] IntPtr pvFindPara, [In] PCCTL_CONTEXT pPrevCtlContext); /// /// /// The CertFreeCTLContext function frees a certificate trust list (CTL) context by decrementing its reference count. When /// the reference count goes to zero, CertFreeCTLContext frees the memory used by a CTL context. /// /// /// 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 the CTL_CONTEXT to be freed. /// The function always returns TRUE. // https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-certfreectlcontext BOOL CertFreeCTLContext( PCCTL_CONTEXT // pCtlContext ); [DllImport(Lib.Crypt32, SetLastError = false, ExactSpelling = true)] [PInvokeData("wincrypt.h", MSDNShortId = "84b1aa0c-44d9-4a2f-861c-fa7d8caac192")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool CertFreeCTLContext([In] PCCTL_CONTEXT pCtlContext); /// /// The CertSerializeCTLStoreElement function serializes an encoded certificate trust list (CTL) context and the encoded /// representation of its properties. The result can be persisted to storage so that the CTL and properties can be retrieved later. /// /// A pointer to the CTL_CONTEXT structure being serialized. /// Reserved for future use and must be zero. /// /// A pointer to a buffer that receives the serialized output, including the encoded CTL and, possibly, its properties. /// /// 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 value that specifies the size, in bytes, of the buffer that is pointed to by the pbElement /// parameter. When the function returns the DWORD value contains the number of bytes stored in the buffer. /// /// /// Note When processing the data returned in the buffer, applications must use the actual size of the data returned. The /// actual size can be slightly smaller than the size of the buffer specified on input. (On input, buffer sizes are usually /// specified large enough to ensure that the largest possible output data fits in the buffer.) On output, the variable pointed to /// by this parameter is updated to reflect the actual size of the data copied to the buffer. /// /// /// /// If the function succeeds, the return value is TRUE. /// If the function fails, the return value is FALSE. For extended error information, call GetLastError. /// // https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-certserializectlstoreelement BOOL // CertSerializeCTLStoreElement( PCCTL_CONTEXT pCtlContext, DWORD dwFlags, BYTE *pbElement, DWORD *pcbElement ); [DllImport(Lib.Crypt32, SetLastError = true, ExactSpelling = true)] [PInvokeData("wincrypt.h", MSDNShortId = "63d343c1-fa65-4cd1-a210-3805c7d92208")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool CertSerializeCTLStoreElement([In] PCCTL_CONTEXT pCtlContext, [Optional] uint dwFlags, [In, Out] IntPtr pbElement, ref uint pcbElement); /// Provides a for that is disposed using . public class SafePCCTL_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 SafePCCTL_CONTEXT(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { } /// Initializes a new instance of the class. private SafePCCTL_CONTEXT() : base() { } /// Performs an implicit conversion from to . /// The safe handle instance. /// The result of the conversion. public static implicit operator PCCTL_CONTEXT(SafePCCTL_CONTEXT h) => h.handle; /// Performs an explicit conversion from to . /// The handle. /// The resulting instance from the conversion. public static unsafe explicit operator CTL_CONTEXT*(SafePCCTL_CONTEXT ctx) => (CTL_CONTEXT*)(void*)ctx.handle; /// protected override bool InternalReleaseHandle() => CertFreeCTLContext(handle); } } }