/**
 * WinPR: Windows Portable Runtime
 * Cryptography API (CryptoAPI)
 *
 * Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef WINPR_CRYPTO_H
#define WINPR_CRYPTO_H

#include <winpr/winpr.h>
#include <winpr/wtypes.h>

#ifdef _WIN32

#include <wincrypt.h>

#else

#define GET_ALG_CLASS(x)		(x & (7 << 13))
#define GET_ALG_TYPE(x)			(x & (15 << 9))
#define GET_ALG_SID(x)			(x & (511))

#define ALG_CLASS_ANY			(0)
#define ALG_CLASS_SIGNATURE		(1 << 13)
#define ALG_CLASS_MSG_ENCRYPT		(2 << 13)
#define ALG_CLASS_DATA_ENCRYPT		(3 << 13)
#define ALG_CLASS_HASH			(4 << 13)
#define ALG_CLASS_KEY_EXCHANGE		(5 << 13)
#define ALG_CLASS_ALL			(7 << 13)

#define ALG_TYPE_ANY			(0)
#define ALG_TYPE_DSS			(1 << 9)
#define ALG_TYPE_RSA			(2 << 9)
#define ALG_TYPE_BLOCK			(3 << 9)
#define ALG_TYPE_STREAM			(4 << 9)
#define ALG_TYPE_DH			(5 << 9)
#define ALG_TYPE_SECURECHANNEL		(6 << 9)
#define ALG_TYPE_RESERVED7		(7 << 9)

#define ALG_SID_ANY			(0)

#define ALG_SID_RSA_ANY			0
#define ALG_SID_RSA_PKCS		1
#define ALG_SID_RSA_MSATWORK		2
#define ALG_SID_RSA_ENTRUST		3
#define ALG_SID_RSA_PGP			4

#define ALG_SID_DSS_ANY			0
#define ALG_SID_DSS_PKCS		1
#define ALG_SID_DSS_DMS			2

#define ALG_SID_ECDSA			3

#define ALG_SID_DES			1
#define ALG_SID_3DES			3
#define ALG_SID_DESX			4
#define ALG_SID_IDEA			5
#define ALG_SID_CAST			6
#define ALG_SID_SAFERSK64		7
#define ALG_SID_SAFERSK128		8
#define ALG_SID_3DES_112		9
#define ALG_SID_CYLINK_MEK		12
#define ALG_SID_RC5			13

#define ALG_SID_AES_128			14
#define ALG_SID_AES_192			15
#define ALG_SID_AES_256			16
#define ALG_SID_AES			17

#define ALG_SID_SKIPJACK		10
#define ALG_SID_TEK			11

#define CRYPT_MODE_CBCI			6
#define CRYPT_MODE_CFBP			7
#define CRYPT_MODE_OFBP			8
#define CRYPT_MODE_CBCOFM		9
#define CRYPT_MODE_CBCOFMI		10

#define ALG_SID_RC2			2

#define ALG_SID_RC4			1
#define ALG_SID_SEAL			2

#define ALG_SID_DH_SANDF		1
#define ALG_SID_DH_EPHEM		2
#define ALG_SID_AGREED_KEY_ANY		3
#define ALG_SID_KEA			4

#define ALG_SID_ECDH			5

#define ALG_SID_MD2			1
#define ALG_SID_MD4			2
#define ALG_SID_MD5			3
#define ALG_SID_SHA			4
#define ALG_SID_SHA1			4
#define ALG_SID_MAC			5
#define ALG_SID_RIPEMD			6
#define ALG_SID_RIPEMD160		7
#define ALG_SID_SSL3SHAMD5		8
#define ALG_SID_HMAC			9
#define ALG_SID_TLS1PRF			10

#define ALG_SID_HASH_REPLACE_OWF	11

#define ALG_SID_SHA_256			12
#define ALG_SID_SHA_384			13
#define ALG_SID_SHA_512			14

#define ALG_SID_SSL3_MASTER		1
#define ALG_SID_SCHANNEL_MASTER_HASH	2
#define ALG_SID_SCHANNEL_MAC_KEY	3
#define ALG_SID_PCT1_MASTER		4
#define ALG_SID_SSL2_MASTER		5
#define ALG_SID_TLS1_MASTER		6
#define ALG_SID_SCHANNEL_ENC_KEY	7

#define ALG_SID_ECMQV			1

#define CALG_MD2			(ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_MD2)
#define CALG_MD4			(ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_MD4)
#define CALG_MD5			(ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_MD5)
#define CALG_SHA			(ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_SHA)
#define CALG_SHA1			(ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_SHA1)
#define CALG_MAC			(ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_MAC)
#define CALG_RSA_SIGN			(ALG_CLASS_SIGNATURE | ALG_TYPE_RSA | ALG_SID_RSA_ANY)
#define CALG_DSS_SIGN			(ALG_CLASS_SIGNATURE | ALG_TYPE_DSS | ALG_SID_DSS_ANY)

#define CALG_NO_SIGN			(ALG_CLASS_SIGNATURE | ALG_TYPE_ANY | ALG_SID_ANY)

#define CALG_RSA_KEYX			(ALG_CLASS_KEY_EXCHANGE | ALG_TYPE_RSA | ALG_SID_RSA_ANY)
#define CALG_DES			(ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | ALG_SID_DES)
#define CALG_3DES_112			(ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | ALG_SID_3DES_112)
#define CALG_3DES			(ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | ALG_SID_3DES)
#define CALG_DESX			(ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | ALG_SID_DESX)
#define CALG_RC2			(ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | ALG_SID_RC2)
#define CALG_RC4			(ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_STREAM | ALG_SID_RC4)
#define CALG_SEAL			(ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_STREAM | ALG_SID_SEAL)
#define CALG_DH_SF			(ALG_CLASS_KEY_EXCHANGE | ALG_TYPE_DH | ALG_SID_DH_SANDF)
#define CALG_DH_EPHEM			(ALG_CLASS_KEY_EXCHANGE | ALG_TYPE_DH | ALG_SID_DH_EPHEM)
#define CALG_AGREEDKEY_ANY		(ALG_CLASS_KEY_EXCHANGE | ALG_TYPE_DH | ALG_SID_AGREED_KEY_ANY)
#define CALG_KEA_KEYX			(ALG_CLASS_KEY_EXCHANGE | ALG_TYPE_DH | ALG_SID_KEA)
#define CALG_HUGHES_MD5			(ALG_CLASS_KEY_EXCHANGE | ALG_TYPE_ANY | ALG_SID_MD5)
#define CALG_SKIPJACK			(ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | ALG_SID_SKIPJACK)
#define CALG_TEK			(ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | ALG_SID_TEK)
#define CALG_CYLINK_MEK			(ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | ALG_SID_CYLINK_MEK)
#define CALG_SSL3_SHAMD5		(ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_SSL3SHAMD5)
#define CALG_SSL3_MASTER		(ALG_CLASS_MSG_ENCRYPT | ALG_TYPE_SECURECHANNEL | ALG_SID_SSL3_MASTER)
#define CALG_SCHANNEL_MASTER_HASH	(ALG_CLASS_MSG_ENCRYPT | ALG_TYPE_SECURECHANNEL | ALG_SID_SCHANNEL_MASTER_HASH)
#define CALG_SCHANNEL_MAC_KEY		(ALG_CLASS_MSG_ENCRYPT | ALG_TYPE_SECURECHANNEL | ALG_SID_SCHANNEL_MAC_KEY)
#define CALG_SCHANNEL_ENC_KEY		(ALG_CLASS_MSG_ENCRYPT | ALG_TYPE_SECURECHANNEL | ALG_SID_SCHANNEL_ENC_KEY)
#define CALG_PCT1_MASTER		(ALG_CLASS_MSG_ENCRYPT | ALG_TYPE_SECURECHANNEL | ALG_SID_PCT1_MASTER)
#define CALG_SSL2_MASTER		(ALG_CLASS_MSG_ENCRYPT | ALG_TYPE_SECURECHANNEL | ALG_SID_SSL2_MASTER)
#define CALG_TLS1_MASTER		(ALG_CLASS_MSG_ENCRYPT | ALG_TYPE_SECURECHANNEL | ALG_SID_TLS1_MASTER)
#define CALG_RC5			(ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | ALG_SID_RC5)
#define CALG_HMAC			(ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_HMAC)
#define CALG_TLS1PRF			(ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_TLS1PRF)

#define CALG_HASH_REPLACE_OWF		(ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_HASH_REPLACE_OWF)
#define CALG_AES_128			(ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | ALG_SID_AES_128)
#define CALG_AES_192			(ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | ALG_SID_AES_192)
#define CALG_AES_256			(ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | ALG_SID_AES_256)
#define CALG_AES			(ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | ALG_SID_AES)

#define CALG_SHA_256			(ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_SHA_256)
#define CALG_SHA_384			(ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_SHA_384)
#define CALG_SHA_512			(ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_SHA_512)

#define CALG_ECDH			(ALG_CLASS_KEY_EXCHANGE | ALG_TYPE_DH | ALG_SID_ECDH)
#define CALG_ECMQV			(ALG_CLASS_KEY_EXCHANGE | ALG_TYPE_ANY | ALG_SID_ECMQV)
#define CALG_ECDSA			(ALG_CLASS_SIGNATURE | ALG_TYPE_DSS | ALG_SID_ECDSA)

typedef struct _CRYPTOAPI_BLOB
{
	DWORD cbData;
	BYTE* pbData;
} CRYPT_INTEGER_BLOB, *PCRYPT_INTEGER_BLOB,
CRYPT_UINT_BLOB, *PCRYPT_UINT_BLOB,
CRYPT_OBJID_BLOB, *PCRYPT_OBJID_BLOB,
CERT_NAME_BLOB, *PCERT_NAME_BLOB,
CERT_RDN_VALUE_BLOB, *PCERT_RDN_VALUE_BLOB,
CERT_BLOB, *PCERT_BLOB,
CRL_BLOB, *PCRL_BLOB,
DATA_BLOB, *PDATA_BLOB,
CRYPT_DATA_BLOB, *PCRYPT_DATA_BLOB,
CRYPT_HASH_BLOB, *PCRYPT_HASH_BLOB,
CRYPT_DIGEST_BLOB, *PCRYPT_DIGEST_BLOB,
CRYPT_DER_BLOB, *PCRYPT_DER_BLOB,
CRYPT_ATTR_BLOB, *PCRYPT_ATTR_BLOB;

typedef struct _CRYPT_ALGORITHM_IDENTIFIER
{
	LPSTR pszObjId;
	CRYPT_OBJID_BLOB Parameters;
} CRYPT_ALGORITHM_IDENTIFIER, *PCRYPT_ALGORITHM_IDENTIFIER;

typedef struct _CRYPT_BIT_BLOB
{
	DWORD cbData;
	BYTE* pbData;
	DWORD cUnusedBits;
} CRYPT_BIT_BLOB, *PCRYPT_BIT_BLOB;

typedef struct _CERT_PUBLIC_KEY_INFO
{
	CRYPT_ALGORITHM_IDENTIFIER Algorithm;
	CRYPT_BIT_BLOB PublicKey;
} CERT_PUBLIC_KEY_INFO, *PCERT_PUBLIC_KEY_INFO;

typedef struct _CERT_EXTENSION
{
	LPSTR pszObjId;
	BOOL fCritical;
	CRYPT_OBJID_BLOB Value;
} CERT_EXTENSION, *PCERT_EXTENSION;
typedef const CERT_EXTENSION* PCCERT_EXTENSION;

typedef struct _CERT_INFO
{
	DWORD dwVersion;
	CRYPT_INTEGER_BLOB SerialNumber;
	CRYPT_ALGORITHM_IDENTIFIER SignatureAlgorithm;
	CERT_NAME_BLOB Issuer;
	FILETIME NotBefore;
	FILETIME NotAfter;
	CERT_NAME_BLOB Subject;
	CERT_PUBLIC_KEY_INFO SubjectPublicKeyInfo;
	CRYPT_BIT_BLOB IssuerUniqueId;
	CRYPT_BIT_BLOB SubjectUniqueId;
	DWORD cExtension;
	PCERT_EXTENSION rgExtension;
} CERT_INFO, *PCERT_INFO;

typedef void *HCERTSTORE;
typedef ULONG_PTR HCRYPTPROV;
typedef ULONG_PTR HCRYPTPROV_LEGACY;

typedef struct _CERT_CONTEXT
{
	DWORD dwCertEncodingType;
	BYTE* pbCertEncoded;
	DWORD cbCertEncoded;
	PCERT_INFO pCertInfo;
	HCERTSTORE hCertStore;
} CERT_CONTEXT, *PCERT_CONTEXT;
typedef const CERT_CONTEXT *PCCERT_CONTEXT;

#define CERT_ENCODING_TYPE_MASK			0x0000FFFF
#define CMSG_ENCODING_TYPE_MASK			0xFFFF0000
#define GET_CERT_ENCODING_TYPE(x)		(x & CERT_ENCODING_TYPE_MASK)
#define GET_CMSG_ENCODING_TYPE(x)		(x & CMSG_ENCODING_TYPE_MASK)

#define CRYPT_ASN_ENCODING			0x00000001
#define CRYPT_NDR_ENCODING			0x00000002
#define X509_ASN_ENCODING			0x00000001
#define X509_NDR_ENCODING			0x00000002
#define PKCS_7_ASN_ENCODING			0x00010000
#define PKCS_7_NDR_ENCODING			0x00020000

#define CERT_COMPARE_MASK			0xFFFF
#define CERT_COMPARE_SHIFT			16
#define CERT_COMPARE_ANY			0
#define CERT_COMPARE_SHA1_HASH			1
#define CERT_COMPARE_NAME			2
#define CERT_COMPARE_ATTR			3
#define CERT_COMPARE_MD5_HASH			4
#define CERT_COMPARE_PROPERTY			5
#define CERT_COMPARE_PUBLIC_KEY			6
#define CERT_COMPARE_HASH			CERT_COMPARE_SHA1_HASH
#define CERT_COMPARE_NAME_STR_A			7
#define CERT_COMPARE_NAME_STR_W			8
#define CERT_COMPARE_KEY_SPEC			9
#define CERT_COMPARE_ENHKEY_USAGE		10
#define CERT_COMPARE_CTL_USAGE			CERT_COMPARE_ENHKEY_USAGE
#define CERT_COMPARE_SUBJECT_CERT		11
#define CERT_COMPARE_ISSUER_OF			12
#define CERT_COMPARE_EXISTING			13
#define CERT_COMPARE_SIGNATURE_HASH		14
#define CERT_COMPARE_KEY_IDENTIFIER		15
#define CERT_COMPARE_CERT_ID			16
#define CERT_COMPARE_CROSS_CERT_DIST_POINTS	17
#define CERT_COMPARE_PUBKEY_MD5_HASH		18
#define CERT_COMPARE_SUBJECT_INFO_ACCESS	19
#define CERT_COMPARE_HASH_STR			20
#define CERT_COMPARE_HAS_PRIVATE_KEY		21

#define CERT_FIND_ANY				(CERT_COMPARE_ANY << CERT_COMPARE_SHIFT)
#define CERT_FIND_SHA1_HASH			(CERT_COMPARE_SHA1_HASH << CERT_COMPARE_SHIFT)
#define CERT_FIND_MD5_HASH			(CERT_COMPARE_MD5_HASH << CERT_COMPARE_SHIFT)
#define CERT_FIND_SIGNATURE_HASH		(CERT_COMPARE_SIGNATURE_HASH << CERT_COMPARE_SHIFT)
#define CERT_FIND_KEY_IDENTIFIER		(CERT_COMPARE_KEY_IDENTIFIER << CERT_COMPARE_SHIFT)
#define CERT_FIND_HASH				CERT_FIND_SHA1_HASH
#define CERT_FIND_PROPERTY			(CERT_COMPARE_PROPERTY << CERT_COMPARE_SHIFT)
#define CERT_FIND_PUBLIC_KEY			(CERT_COMPARE_PUBLIC_KEY << CERT_COMPARE_SHIFT)
#define CERT_FIND_SUBJECT_NAME			(CERT_COMPARE_NAME << CERT_COMPARE_SHIFT | CERT_INFO_SUBJECT_FLAG)
#define CERT_FIND_SUBJECT_ATTR			(CERT_COMPARE_ATTR << CERT_COMPARE_SHIFT | CERT_INFO_SUBJECT_FLAG)
#define CERT_FIND_ISSUER_NAME			(CERT_COMPARE_NAME << CERT_COMPARE_SHIFT | CERT_INFO_ISSUER_FLAG)
#define CERT_FIND_ISSUER_ATTR			(CERT_COMPARE_ATTR << CERT_COMPARE_SHIFT | CERT_INFO_ISSUER_FLAG)
#define CERT_FIND_SUBJECT_STR_A			(CERT_COMPARE_NAME_STR_A << CERT_COMPARE_SHIFT | CERT_INFO_SUBJECT_FLAG)
#define CERT_FIND_SUBJECT_STR_W			(CERT_COMPARE_NAME_STR_W << CERT_COMPARE_SHIFT | CERT_INFO_SUBJECT_FLAG)
#define CERT_FIND_SUBJECT_STR			CERT_FIND_SUBJECT_STR_W
#define CERT_FIND_ISSUER_STR_A			(CERT_COMPARE_NAME_STR_A << CERT_COMPARE_SHIFT | CERT_INFO_ISSUER_FLAG)
#define CERT_FIND_ISSUER_STR_W			(CERT_COMPARE_NAME_STR_W << CERT_COMPARE_SHIFT | CERT_INFO_ISSUER_FLAG)
#define CERT_FIND_ISSUER_STR			CERT_FIND_ISSUER_STR_W
#define CERT_FIND_KEY_SPEC			(CERT_COMPARE_KEY_SPEC << CERT_COMPARE_SHIFT)
#define CERT_FIND_ENHKEY_USAGE			(CERT_COMPARE_ENHKEY_USAGE << CERT_COMPARE_SHIFT)
#define CERT_FIND_CTL_USAGE			CERT_FIND_ENHKEY_USAGE
#define CERT_FIND_SUBJECT_CERT			(CERT_COMPARE_SUBJECT_CERT << CERT_COMPARE_SHIFT)
#define CERT_FIND_ISSUER_OF			(CERT_COMPARE_ISSUER_OF << CERT_COMPARE_SHIFT)
#define CERT_FIND_EXISTING			(CERT_COMPARE_EXISTING << CERT_COMPARE_SHIFT)
#define CERT_FIND_CERT_ID			(CERT_COMPARE_CERT_ID << CERT_COMPARE_SHIFT)
#define CERT_FIND_CROSS_CERT_DIST_POINTS	(CERT_COMPARE_CROSS_CERT_DIST_POINTS << CERT_COMPARE_SHIFT)
#define CERT_FIND_PUBKEY_MD5_HASH		(CERT_COMPARE_PUBKEY_MD5_HASH << CERT_COMPARE_SHIFT)
#define CERT_FIND_SUBJECT_INFO_ACCESS		(CERT_COMPARE_SUBJECT_INFO_ACCESS << CERT_COMPARE_SHIFT)
#define CERT_FIND_HASH_STR			(CERT_COMPARE_HASH_STR << CERT_COMPARE_SHIFT)
#define CERT_FIND_HAS_PRIVATE_KEY		(CERT_COMPARE_HAS_PRIVATE_KEY << CERT_COMPARE_SHIFT)

#define CERT_FIND_OPTIONAL_ENHKEY_USAGE_FLAG	0x1
#define CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG	0x2
#define CERT_FIND_PROP_ONLY_ENHKEY_USAGE_FLAG	0x4
#define CERT_FIND_NO_ENHKEY_USAGE_FLAG		0x8
#define CERT_FIND_OR_ENHKEY_USAGE_FLAG		0x10
#define CERT_FIND_VALID_ENHKEY_USAGE_FLAG	0x20
#define CERT_FIND_OPTIONAL_CTL_USAGE_FLAG	CERT_FIND_OPTIONAL_ENHKEY_USAGE_FLAG
#define CERT_FIND_EXT_ONLY_CTL_USAGE_FLAG	CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG
#define CERT_FIND_PROP_ONLY_CTL_USAGE_FLAG	CERT_FIND_PROP_ONLY_ENHKEY_USAGE_FLAG
#define CERT_FIND_NO_CTL_USAGE_FLAG		CERT_FIND_NO_ENHKEY_USAGE_FLAG
#define CERT_FIND_OR_CTL_USAGE_FLAG		CERT_FIND_OR_ENHKEY_USAGE_FLAG
#define CERT_FIND_VALID_CTL_USAGE_FLAG		CERT_FIND_VALID_ENHKEY_USAGE_FLAG

#define CERT_NAME_EMAIL_TYPE			1
#define CERT_NAME_RDN_TYPE			2
#define CERT_NAME_ATTR_TYPE			3
#define CERT_NAME_SIMPLE_DISPLAY_TYPE		4
#define CERT_NAME_FRIENDLY_DISPLAY_TYPE		5
#define CERT_NAME_DNS_TYPE			6
#define CERT_NAME_URL_TYPE			7
#define CERT_NAME_UPN_TYPE			8

#define CERT_NAME_ISSUER_FLAG			0x1
#define CERT_NAME_DISABLE_IE4_UTF8_FLAG		0x00010000

#define CERT_NAME_SEARCH_ALL_NAMES_FLAG		0x2

WINPR_API HCERTSTORE CertOpenSystemStoreW(HCRYPTPROV_LEGACY hProv, LPCWSTR szSubsystemProtocol);
WINPR_API HCERTSTORE CertOpenSystemStoreA(HCRYPTPROV_LEGACY hProv, LPCSTR szSubsystemProtocol);

WINPR_API BOOL CertCloseStore(HCERTSTORE hCertStore, DWORD dwFlags);

#ifdef UNICODE
#define CertOpenSystemStore	CertOpenSystemStoreW
#else
#define CertOpenSystemStore	CertOpenSystemStoreA
#endif

#ifdef __cplusplus
extern "C" {
#endif

WINPR_API PCCERT_CONTEXT CertFindCertificateInStore(HCERTSTORE hCertStore, DWORD dwCertEncodingType,
		DWORD dwFindFlags, DWORD dwFindType, const void* pvFindPara, PCCERT_CONTEXT pPrevCertContext);

WINPR_API PCCERT_CONTEXT CertEnumCertificatesInStore(HCERTSTORE hCertStore, PCCERT_CONTEXT pPrevCertContext);

DWORD CertGetNameStringW(PCCERT_CONTEXT pCertContext, DWORD dwType,
		DWORD dwFlags, void* pvTypePara, LPWSTR pszNameString, DWORD cchNameString);
DWORD CertGetNameStringA(PCCERT_CONTEXT pCertContext, DWORD dwType,
		DWORD dwFlags, void* pvTypePara, LPSTR pszNameString, DWORD cchNameString);

#ifdef __cplusplus
}
#endif

#ifdef UNICODE
#define CertGetNameString	CertGetNameStringW
#else
#define CertGetNameString	CertGetNameStringA
#endif

#endif

#endif /* WINPR_CRYPTO_H */

