/* engines/e_capi.c */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
 * project.
 */
/* ====================================================================
 * Copyright (c) 2008 The OpenSSL Project.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer. 
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
 *
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    licensing@OpenSSL.org.
 *
 * 5. Products derived from this software may not be called "OpenSSL"
 *    nor may "OpenSSL" appear in their names without prior written
 *    permission of the OpenSSL Project.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
 *
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 */


#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include <openssl/crypto.h>

#ifdef OPENSSL_SYS_WIN32
#ifndef OPENSSL_NO_CAPIENG

#include <openssl/buffer.h>
#include <openssl/bn.h>
#include <openssl/rsa.h>

#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0400
#endif

#include <windows.h>
#include <wincrypt.h>
#include <malloc.h>
#ifndef alloca
# define alloca _alloca
#endif

/*
 * This module uses several "new" interfaces, among which is
 * CertGetCertificateContextProperty. CERT_KEY_PROV_INFO_PROP_ID is
 * one of possible values you can pass to function in question. By
 * checking if it's defined we can see if wincrypt.h and accompanying
 * crypt32.lib are in shape. The native MingW32 headers up to and
 * including __W32API_VERSION 3.14 lack of struct DSSPUBKEY and the
 * defines CERT_STORE_PROV_SYSTEM_A and CERT_STORE_READONLY_FLAG,
 * so we check for these too and avoid compiling.
 * Yes, it's rather "weak" test and if compilation fails,
 * then re-configure with -DOPENSSL_NO_CAPIENG.
 */
#if defined(CERT_KEY_PROV_INFO_PROP_ID) && \
    defined(CERT_STORE_PROV_SYSTEM_A) && \
    defined(CERT_STORE_READONLY_FLAG)
# define __COMPILE_CAPIENG
#endif /* CERT_KEY_PROV_INFO_PROP_ID */
#endif /* OPENSSL_NO_CAPIENG */
#endif /* OPENSSL_SYS_WIN32 */

#ifdef __COMPILE_CAPIENG

#undef X509_EXTENSIONS
#undef X509_CERT_PAIR

/* Definitions which may be missing from earlier version of headers */
#ifndef CERT_STORE_OPEN_EXISTING_FLAG
#define CERT_STORE_OPEN_EXISTING_FLAG                   0x00004000
#endif

#ifndef CERT_STORE_CREATE_NEW_FLAG
#define CERT_STORE_CREATE_NEW_FLAG                      0x00002000
#endif

#ifndef CERT_SYSTEM_STORE_CURRENT_USER
#define CERT_SYSTEM_STORE_CURRENT_USER			0x00010000
#endif 

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

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

#include <openssl/engine.h>
#include <openssl/pem.h>
#include <openssl/x509v3.h>

#include "e_capi_err.h"
#include "e_capi_err.c"


static const char *engine_capi_id = "capi";
static const char *engine_capi_name = "CryptoAPI ENGINE";

typedef struct CAPI_CTX_st CAPI_CTX;
typedef struct CAPI_KEY_st CAPI_KEY;

static void capi_addlasterror(void);
static void capi_adderror(DWORD err);

static void CAPI_trace(CAPI_CTX *ctx, char *format, ...);

static int capi_list_providers(CAPI_CTX *ctx, BIO *out);
static int capi_list_containers(CAPI_CTX *ctx, BIO *out);
int capi_list_certs(CAPI_CTX *ctx, BIO *out, char *storename);
void capi_free_key(CAPI_KEY *key);

static PCCERT_CONTEXT capi_find_cert(CAPI_CTX *ctx, const char *id, HCERTSTORE hstore);

CAPI_KEY *capi_find_key(CAPI_CTX *ctx, const char *id);

static EVP_PKEY *capi_load_privkey(ENGINE *eng, const char *key_id,
	UI_METHOD *ui_method, void *callback_data);
static int capi_rsa_sign(int dtype, const unsigned char *m, unsigned int m_len,
             unsigned char *sigret, unsigned int *siglen, const RSA *rsa);
static int capi_rsa_priv_enc(int flen, const unsigned char *from,
                unsigned char *to, RSA *rsa, int padding);
static int capi_rsa_priv_dec(int flen, const unsigned char *from,
                unsigned char *to, RSA *rsa, int padding);
static int capi_rsa_free(RSA *rsa);

static DSA_SIG *capi_dsa_do_sign(const unsigned char *digest, int dlen,
							DSA *dsa);
static int capi_dsa_free(DSA *dsa);

static int capi_load_ssl_client_cert(ENGINE *e, SSL *ssl,
	STACK_OF(X509_NAME) *ca_dn, X509 **pcert, EVP_PKEY **pkey,
	STACK_OF(X509) **pother, UI_METHOD *ui_method, void *callback_data);

static int cert_select_simple(ENGINE *e, SSL *ssl, STACK_OF(X509) *certs);
#ifdef OPENSSL_CAPIENG_DIALOG
static int cert_select_dialog(ENGINE *e, SSL *ssl, STACK_OF(X509) *certs);
#endif

typedef PCCERT_CONTEXT (WINAPI *CERTDLG)(HCERTSTORE, HWND, LPCWSTR,
						LPCWSTR, DWORD, DWORD,
						void *);
typedef HWND (WINAPI *GETCONSWIN)(void);

/* This structure contains CAPI ENGINE specific data:
 * it contains various global options and affects how
 * other functions behave.
 */

#define CAPI_DBG_TRACE	2
#define CAPI_DBG_ERROR	1

struct CAPI_CTX_st {
	int debug_level;
	char *debug_file;
	/* Parameters to use for container lookup */
	DWORD keytype;
	LPSTR cspname;
	DWORD csptype;
	/* Certificate store name to use */
	LPSTR storename;
	LPSTR ssl_client_store;
	/* System store flags */
	DWORD store_flags;

/* Lookup string meanings in load_private_key */
/* Substring of subject: uses "storename" */
#define CAPI_LU_SUBSTR		1
/* Friendly name: uses storename */
#define CAPI_LU_FNAME		2
/* Container name: uses cspname, keytype */
#define CAPI_LU_CONTNAME	3
	int lookup_method;
/* Info to dump with dumpcerts option */
/* Issuer and serial name strings */
#define CAPI_DMP_SUMMARY	0x1
/* Friendly name */
#define CAPI_DMP_FNAME		0x2
/* Full X509_print dump */
#define CAPI_DMP_FULL		0x4
/* Dump PEM format certificate */
#define CAPI_DMP_PEM		0x8
/* Dump pseudo key (if possible) */
#define CAPI_DMP_PSKEY		0x10
/* Dump key info (if possible) */
#define CAPI_DMP_PKEYINFO	0x20

	DWORD dump_flags;
	int (*client_cert_select)(ENGINE *e, SSL *ssl, STACK_OF(X509) *certs);

	CERTDLG certselectdlg;
	GETCONSWIN getconswindow;
};


static CAPI_CTX *capi_ctx_new();
static void capi_ctx_free(CAPI_CTX *ctx);
static int capi_ctx_set_provname(CAPI_CTX *ctx, LPSTR pname, DWORD type, int check);
static int capi_ctx_set_provname_idx(CAPI_CTX *ctx, int idx);

#define CAPI_CMD_LIST_CERTS		ENGINE_CMD_BASE
#define CAPI_CMD_LOOKUP_CERT		(ENGINE_CMD_BASE + 1)
#define CAPI_CMD_DEBUG_LEVEL		(ENGINE_CMD_BASE + 2)
#define CAPI_CMD_DEBUG_FILE		(ENGINE_CMD_BASE + 3)
#define CAPI_CMD_KEYTYPE		(ENGINE_CMD_BASE + 4)
#define CAPI_CMD_LIST_CSPS		(ENGINE_CMD_BASE + 5)
#define CAPI_CMD_SET_CSP_IDX		(ENGINE_CMD_BASE + 6)
#define CAPI_CMD_SET_CSP_NAME		(ENGINE_CMD_BASE + 7)
#define CAPI_CMD_SET_CSP_TYPE		(ENGINE_CMD_BASE + 8)
#define CAPI_CMD_LIST_CONTAINERS	(ENGINE_CMD_BASE + 9)
#define CAPI_CMD_LIST_OPTIONS		(ENGINE_CMD_BASE + 10)
#define CAPI_CMD_LOOKUP_METHOD		(ENGINE_CMD_BASE + 11)
#define CAPI_CMD_STORE_NAME		(ENGINE_CMD_BASE + 12)
#define CAPI_CMD_STORE_FLAGS		(ENGINE_CMD_BASE + 13)

static const ENGINE_CMD_DEFN capi_cmd_defns[] = {
	{CAPI_CMD_LIST_CERTS,
		"list_certs",
		"List all certificates in store",
		ENGINE_CMD_FLAG_NO_INPUT},
	{CAPI_CMD_LOOKUP_CERT,
		"lookup_cert",
		"Lookup and output certificates",
		ENGINE_CMD_FLAG_STRING},
	{CAPI_CMD_DEBUG_LEVEL,
		"debug_level",
		"debug level (1=errors, 2=trace)",
		ENGINE_CMD_FLAG_NUMERIC},
	{CAPI_CMD_DEBUG_FILE,
		"debug_file",
		"debugging filename)",
		ENGINE_CMD_FLAG_STRING},
	{CAPI_CMD_KEYTYPE,
		"key_type",
		"Key type: 1=AT_KEYEXCHANGE (default), 2=AT_SIGNATURE",
		ENGINE_CMD_FLAG_NUMERIC},
	{CAPI_CMD_LIST_CSPS,
		"list_csps",
		"List all CSPs",
		ENGINE_CMD_FLAG_NO_INPUT},
	{CAPI_CMD_SET_CSP_IDX,
		"csp_idx",
		"Set CSP by index",
		ENGINE_CMD_FLAG_NUMERIC},
	{CAPI_CMD_SET_CSP_NAME,
		"csp_name",
		"Set CSP name, (default CSP used if not specified)",
		ENGINE_CMD_FLAG_STRING},
	{CAPI_CMD_SET_CSP_TYPE,
		"csp_type",
		"Set CSP type, (default RSA_PROV_FULL)",
		ENGINE_CMD_FLAG_NUMERIC},
	{CAPI_CMD_LIST_CONTAINERS,
		"list_containers",
		"list container names",
		ENGINE_CMD_FLAG_NO_INPUT},
	{CAPI_CMD_LIST_OPTIONS,
		"list_options",
		"Set list options (1=summary,2=friendly name, 4=full printout, 8=PEM output, 16=XXX, "
		"32=private key info)",
		ENGINE_CMD_FLAG_NUMERIC},
	{CAPI_CMD_LOOKUP_METHOD,
		"lookup_method",
		"Set key lookup method (1=substring, 2=friendlyname, 3=container name)",
		ENGINE_CMD_FLAG_NUMERIC},
	{CAPI_CMD_STORE_NAME,
		"store_name",
		"certificate store name, default \"MY\"",
		ENGINE_CMD_FLAG_STRING},
	{CAPI_CMD_STORE_FLAGS,
		"store_flags",
		"Certificate store flags: 1 = system store",
		ENGINE_CMD_FLAG_NUMERIC},

	{0, NULL, NULL, 0}
	};

static int capi_idx = -1;
static int rsa_capi_idx = -1;
static int dsa_capi_idx = -1;
static int cert_capi_idx = -1;

static int capi_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
	{
	int ret = 1;
	CAPI_CTX *ctx;
	BIO *out;
	if (capi_idx == -1)
		{
		CAPIerr(CAPI_F_CAPI_CTRL, CAPI_R_ENGINE_NOT_INITIALIZED);
		return 0;
		}
	ctx = ENGINE_get_ex_data(e, capi_idx);
	out = BIO_new_fp(stdout, BIO_NOCLOSE);
	switch (cmd)
		{
		case CAPI_CMD_LIST_CSPS:
		ret = capi_list_providers(ctx, out);
		break;

		case CAPI_CMD_LIST_CERTS:
		ret = capi_list_certs(ctx, out, NULL);
		break;

		case CAPI_CMD_LOOKUP_CERT:
		ret = capi_list_certs(ctx, out, p);
		break;

		case CAPI_CMD_LIST_CONTAINERS:
		ret = capi_list_containers(ctx, out);
		break;

		case CAPI_CMD_STORE_NAME:
		if (ctx->storename)
			OPENSSL_free(ctx->storename);
		ctx->storename = BUF_strdup(p);
		CAPI_trace(ctx, "Setting store name to %s\n", p);
		break;

		case CAPI_CMD_STORE_FLAGS:
		if (i & 1)
			{
			ctx->store_flags |= CERT_SYSTEM_STORE_LOCAL_MACHINE;
			ctx->store_flags &= ~CERT_SYSTEM_STORE_CURRENT_USER;
			}
		else
			{
			ctx->store_flags |= CERT_SYSTEM_STORE_CURRENT_USER;
			ctx->store_flags &= ~CERT_SYSTEM_STORE_LOCAL_MACHINE;
			}
		CAPI_trace(ctx, "Setting flags to %d\n", i);
		break;

		case CAPI_CMD_DEBUG_LEVEL:
		ctx->debug_level = (int)i;
		CAPI_trace(ctx, "Setting debug level to %d\n", ctx->debug_level);
		break;

		case CAPI_CMD_DEBUG_FILE:
		ctx->debug_file = BUF_strdup(p);
		CAPI_trace(ctx, "Setting debug file to %s\n", ctx->debug_file);
		break;

		case CAPI_CMD_KEYTYPE:
		ctx->keytype = i;
		CAPI_trace(ctx, "Setting key type to %d\n", ctx->keytype);
		break;

		case CAPI_CMD_SET_CSP_IDX:
		ret = capi_ctx_set_provname_idx(ctx, i);
		break;

		case CAPI_CMD_LIST_OPTIONS:
		ctx->dump_flags = i;
		break;

		case CAPI_CMD_LOOKUP_METHOD:
		if (i < 1 || i > 3)
			{
			CAPIerr(CAPI_F_CAPI_CTRL, CAPI_R_INVALID_LOOKUP_METHOD);
			return 0;
			}
		ctx->lookup_method = i;
		break;

		case CAPI_CMD_SET_CSP_NAME:
		ret = capi_ctx_set_provname(ctx, p, ctx->csptype, 1);
		break;

		case CAPI_CMD_SET_CSP_TYPE:
		ctx->csptype = i;
		break;

		default:
		CAPIerr(CAPI_F_CAPI_CTRL, CAPI_R_UNKNOWN_COMMAND);
		ret = 0;
	}

	BIO_free(out);
	return ret;

	}

static RSA_METHOD capi_rsa_method =
	{
	"CryptoAPI RSA method",
	0,				/* pub_enc */
	0,				/* pub_dec */
	capi_rsa_priv_enc,		/* priv_enc */
	capi_rsa_priv_dec,		/* priv_dec */
	0,				/* rsa_mod_exp */
	0,				/* bn_mod_exp */
	0,				/* init	*/
	capi_rsa_free,			/* finish */
	RSA_FLAG_SIGN_VER, 		/* flags */
	NULL,				/* app_data */
	capi_rsa_sign,			/* rsa_sign */
	0				/* rsa_verify */
	};

static DSA_METHOD capi_dsa_method =
	{
	"CryptoAPI DSA method",
	capi_dsa_do_sign,		/* dsa_do_sign */
	0,				/* dsa_sign_setup */
	0,				/* dsa_do_verify */
	0,				/* dsa_mod_exp */
	0,				/* bn_mod_exp */
	0,				/* init	*/
	capi_dsa_free,			/* finish */
	0, 				/* flags */
	NULL,				/* app_data */
	0,				/* dsa_paramgen */
	0				/* dsa_keygen */
	};

static int capi_init(ENGINE *e)
	{
	CAPI_CTX *ctx;
	const RSA_METHOD *ossl_rsa_meth;
	const DSA_METHOD *ossl_dsa_meth;

	if (capi_idx < 0)
		{
		capi_idx = ENGINE_get_ex_new_index(0, NULL, NULL, NULL, 0);
		if (capi_idx < 0)
			goto memerr;

		cert_capi_idx = X509_get_ex_new_index(0, NULL, NULL, NULL, 0);

		/* Setup RSA_METHOD */
		rsa_capi_idx = RSA_get_ex_new_index(0, NULL, NULL, NULL, 0);
		ossl_rsa_meth = RSA_PKCS1_SSLeay();
		capi_rsa_method.rsa_pub_enc = ossl_rsa_meth->rsa_pub_enc;
		capi_rsa_method.rsa_pub_dec = ossl_rsa_meth->rsa_pub_dec;
		capi_rsa_method.rsa_mod_exp = ossl_rsa_meth->rsa_mod_exp;
		capi_rsa_method.bn_mod_exp = ossl_rsa_meth->bn_mod_exp;

		/* Setup DSA Method */
		dsa_capi_idx = DSA_get_ex_new_index(0, NULL, NULL, NULL, 0);
		ossl_dsa_meth = DSA_OpenSSL();
		capi_dsa_method.dsa_do_verify = ossl_dsa_meth->dsa_do_verify;
		capi_dsa_method.dsa_mod_exp = ossl_dsa_meth->dsa_mod_exp;
		capi_dsa_method.bn_mod_exp = ossl_dsa_meth->bn_mod_exp;
		}

	ctx = capi_ctx_new();
	if (!ctx)
		goto memerr;

	ENGINE_set_ex_data(e, capi_idx, ctx);

#ifdef OPENSSL_CAPIENG_DIALOG
	{
	HMODULE cryptui = LoadLibrary(TEXT("CRYPTUI.DLL"));
	HMODULE kernel = GetModuleHandle(TEXT("KERNEL32.DLL"));
	if (cryptui)
		ctx->certselectdlg = (CERTDLG)GetProcAddress(cryptui, "CryptUIDlgSelectCertificateFromStore");
	if (kernel)
		ctx->getconswindow = (GETCONSWIN)GetProcAddress(kernel, "GetConsoleWindow");
	if (cryptui && !OPENSSL_isservice())
		ctx->client_cert_select = cert_select_dialog;
	}
#endif
		

	return 1;

	memerr:
	CAPIerr(CAPI_F_CAPI_INIT, ERR_R_MALLOC_FAILURE);
	return 0;

	return 1;
	}

static int capi_destroy(ENGINE *e)
	{
	ERR_unload_CAPI_strings();
	return 1;
	}

static int capi_finish(ENGINE *e)
	{
	CAPI_CTX *ctx;
	ctx = ENGINE_get_ex_data(e, capi_idx);
	capi_ctx_free(ctx);
	ENGINE_set_ex_data(e, capi_idx, NULL);
	return 1;
	}


/* CryptoAPI key application data. This contains
 * a handle to the private key container (for sign operations)
 * and a handle to the key (for decrypt operations).
 */

struct CAPI_KEY_st
	{
	/* Associated certificate context (if any) */
	PCCERT_CONTEXT pcert;
	HCRYPTPROV hprov;
	HCRYPTKEY key;
	DWORD keyspec;
	};

static int bind_capi(ENGINE *e)
	{
	if (!ENGINE_set_id(e, engine_capi_id)
		|| !ENGINE_set_name(e, engine_capi_name)
		|| !ENGINE_set_flags(e, ENGINE_FLAGS_NO_REGISTER_ALL)
		|| !ENGINE_set_init_function(e, capi_init)
		|| !ENGINE_set_finish_function(e, capi_finish)
		|| !ENGINE_set_destroy_function(e, capi_destroy)
		|| !ENGINE_set_RSA(e, &capi_rsa_method)
		|| !ENGINE_set_DSA(e, &capi_dsa_method)
		|| !ENGINE_set_load_privkey_function(e, capi_load_privkey)
		|| !ENGINE_set_load_ssl_client_cert_function(e,
						capi_load_ssl_client_cert)
		|| !ENGINE_set_cmd_defns(e, capi_cmd_defns)
		|| !ENGINE_set_ctrl_function(e, capi_ctrl))
			return 0;
	ERR_load_CAPI_strings();

	return 1;

	}

#ifndef OPENSSL_NO_DYNAMIC_ENGINE
static int bind_helper(ENGINE *e, const char *id)
	{
	if(id && (strcmp(id, engine_capi_id) != 0))
		return 0;
	if(!bind_capi(e))
		return 0;
	return 1;
	}       
IMPLEMENT_DYNAMIC_CHECK_FN()
IMPLEMENT_DYNAMIC_BIND_FN(bind_helper)
#else
static ENGINE *engine_capi(void)
	{
	ENGINE *ret = ENGINE_new();
	if(!ret)
		return NULL;
	if(!bind_capi(ret))
		{
		ENGINE_free(ret);
		return NULL;
		}
	return ret;
	}

void ENGINE_load_capi(void)
	{
	/* Copied from eng_[openssl|dyn].c */
	ENGINE *toadd = engine_capi();
	if(!toadd) return;
	ENGINE_add(toadd);
	ENGINE_free(toadd);
	ERR_clear_error();
	}
#endif


static int lend_tobn(BIGNUM *bn, unsigned char *bin, int binlen)
	{
	int i;
	/* Reverse buffer in place: since this is a keyblob structure
	 * that will be freed up after conversion anyway it doesn't 
	 * matter if we change it.
	 */
	for(i = 0; i < binlen / 2; i++)
		{
		unsigned char c;
		c = bin[i];
		bin[i] = bin[binlen - i - 1];
		bin[binlen - i - 1] = c;
		}

	if (!BN_bin2bn(bin, binlen, bn))
		return 0;
	return 1;
	}

/* Given a CAPI_KEY get an EVP_PKEY structure */

static EVP_PKEY *capi_get_pkey(ENGINE *eng, CAPI_KEY *key)
	{
	unsigned char *pubkey = NULL;
	DWORD len;
	BLOBHEADER *bh;
	RSA *rkey = NULL;
	DSA *dkey = NULL;
	EVP_PKEY *ret = NULL;
	if (!CryptExportKey(key->key, 0, PUBLICKEYBLOB, 0, NULL, &len))
		{
		CAPIerr(CAPI_F_CAPI_GET_PKEY, CAPI_R_PUBKEY_EXPORT_LENGTH_ERROR);
		capi_addlasterror();
		return NULL;
		}

	pubkey = OPENSSL_malloc(len);

	if (!pubkey)
		goto memerr;

	if (!CryptExportKey(key->key, 0, PUBLICKEYBLOB, 0, pubkey, &len))
		{
		CAPIerr(CAPI_F_CAPI_GET_PKEY, CAPI_R_PUBKEY_EXPORT_ERROR);
		capi_addlasterror();
		goto err;
		}

	bh = (BLOBHEADER *)pubkey;
	if (bh->bType != PUBLICKEYBLOB)
		{
		CAPIerr(CAPI_F_CAPI_GET_PKEY, CAPI_R_INVALID_PUBLIC_KEY_BLOB);
		goto err;
		}
	if (bh->aiKeyAlg == CALG_RSA_SIGN || bh->aiKeyAlg == CALG_RSA_KEYX)
		{
		RSAPUBKEY *rp;
		DWORD rsa_modlen;
		unsigned char *rsa_modulus;
		rp = (RSAPUBKEY *)(bh + 1);
		if (rp->magic != 0x31415352)
			{
			char magstr[10];
			BIO_snprintf(magstr, 10, "%lx", rp->magic);
			CAPIerr(CAPI_F_CAPI_GET_PKEY, CAPI_R_INVALID_RSA_PUBLIC_KEY_BLOB_MAGIC_NUMBER);
			ERR_add_error_data(2, "magic=0x", magstr);
			goto err;
			}
		rsa_modulus = (unsigned char *)(rp + 1);
		rkey = RSA_new_method(eng);
		if (!rkey)
			goto memerr;

		rkey->e = BN_new();
		rkey->n = BN_new();

		if (!rkey->e || !rkey->n)
			goto memerr;

		if (!BN_set_word(rkey->e, rp->pubexp))
			goto memerr;

		rsa_modlen = rp->bitlen / 8;
		if (!lend_tobn(rkey->n, rsa_modulus, rsa_modlen))
			goto memerr;

		RSA_set_ex_data(rkey, rsa_capi_idx, key);

		if (!(ret = EVP_PKEY_new()))
			goto memerr;

		EVP_PKEY_assign_RSA(ret, rkey);
		rkey = NULL;

		}
	else if (bh->aiKeyAlg == CALG_DSS_SIGN)
		{
		DSSPUBKEY *dp;
		DWORD dsa_plen;
		unsigned char *btmp;
		dp = (DSSPUBKEY *)(bh + 1);
		if (dp->magic != 0x31535344)
			{
			char magstr[10];
			BIO_snprintf(magstr, 10, "%lx", dp->magic);
			CAPIerr(CAPI_F_CAPI_GET_PKEY, CAPI_R_INVALID_DSA_PUBLIC_KEY_BLOB_MAGIC_NUMBER);
			ERR_add_error_data(2, "magic=0x", magstr);
			goto err;
			}
		dsa_plen = dp->bitlen / 8;
		btmp = (unsigned char *)(dp + 1);
		dkey = DSA_new_method(eng);
		if (!dkey)
			goto memerr;
		dkey->p = BN_new();
		dkey->q = BN_new();
		dkey->g = BN_new();
		dkey->pub_key = BN_new();
		if (!dkey->p || !dkey->q || !dkey->g || !dkey->pub_key)
			goto memerr;
		if (!lend_tobn(dkey->p, btmp, dsa_plen))
			goto memerr;
		btmp += dsa_plen;
		if (!lend_tobn(dkey->q, btmp, 20))
			goto memerr;
		btmp += 20;
		if (!lend_tobn(dkey->g, btmp, dsa_plen))
			goto memerr;
		btmp += dsa_plen;
		if (!lend_tobn(dkey->pub_key, btmp, dsa_plen))
			goto memerr;
		btmp += dsa_plen;

		DSA_set_ex_data(dkey, dsa_capi_idx, key);

		if (!(ret = EVP_PKEY_new()))
			goto memerr;

		EVP_PKEY_assign_DSA(ret, dkey);
		dkey = NULL;
		}
	else
		{
		char algstr[10];
		BIO_snprintf(algstr, 10, "%lx", bh->aiKeyAlg);
		CAPIerr(CAPI_F_CAPI_GET_PKEY, CAPI_R_UNSUPPORTED_PUBLIC_KEY_ALGORITHM);
		ERR_add_error_data(2, "aiKeyAlg=0x", algstr);
		goto err;
		}


	err:
	if (pubkey)
		OPENSSL_free(pubkey);
	if (!ret)
		{
		if (rkey)
			RSA_free(rkey);
		if (dkey)
			DSA_free(dkey);
		}

	return ret;

memerr:
	CAPIerr(CAPI_F_CAPI_GET_PKEY, ERR_R_MALLOC_FAILURE);
	goto err;

	}

static EVP_PKEY *capi_load_privkey(ENGINE *eng, const char *key_id,
	UI_METHOD *ui_method, void *callback_data)
	{
	CAPI_CTX *ctx;
	CAPI_KEY *key;
	EVP_PKEY *ret;
	ctx = ENGINE_get_ex_data(eng, capi_idx);

	if (!ctx)
		{
		CAPIerr(CAPI_F_CAPI_LOAD_PRIVKEY, CAPI_R_CANT_FIND_CAPI_CONTEXT);
		return NULL;
		}

	key = capi_find_key(ctx, key_id);

	if (!key)
		return NULL;

	ret = capi_get_pkey(eng, key);

	if (!ret)
		capi_free_key(key);
	return ret;

	}

/* CryptoAPI RSA operations */

int capi_rsa_priv_enc(int flen, const unsigned char *from,
                unsigned char *to, RSA *rsa, int padding)
	{
	CAPIerr(CAPI_F_CAPI_RSA_PRIV_ENC, CAPI_R_FUNCTION_NOT_SUPPORTED);
	return -1;
	}

int capi_rsa_sign(int dtype, const unsigned char *m, unsigned int m_len,
             unsigned char *sigret, unsigned int *siglen, const RSA *rsa)
	{
	ALG_ID alg;
	HCRYPTHASH hash;
	DWORD slen;
	unsigned int i;
	int ret = -1;
	CAPI_KEY *capi_key;
	CAPI_CTX *ctx;

	ctx = ENGINE_get_ex_data(rsa->engine, capi_idx);

	CAPI_trace(ctx, "Called CAPI_rsa_sign()\n");

	capi_key = RSA_get_ex_data(rsa, rsa_capi_idx);
	if (!capi_key)
		{
		CAPIerr(CAPI_F_CAPI_RSA_SIGN, CAPI_R_CANT_GET_KEY);
		return -1;
		}
/* Convert the signature type to a CryptoAPI algorithm ID */
	switch(dtype)
		{
	case NID_sha256:
		alg = CALG_SHA_256;
		break;

	case NID_sha384:
		alg = CALG_SHA_384;
		break;

	case NID_sha512:
		alg = CALG_SHA_512;
		break;

	case NID_sha1:
		alg = CALG_SHA1;
		break;

	case NID_md5:
		alg = CALG_MD5;
		break;

	case NID_md5_sha1:
		alg = CALG_SSL3_SHAMD5;
		break;
	default:
		{
		char algstr[10];
		BIO_snprintf(algstr, 10, "%lx", dtype);
		CAPIerr(CAPI_F_CAPI_RSA_SIGN, CAPI_R_UNSUPPORTED_ALGORITHM_NID);
		ERR_add_error_data(2, "NID=0x", algstr);
		return -1;
		}
	}



/* Create the hash object */
	if(!CryptCreateHash(capi_key->hprov, alg, 0, 0, &hash))
		{
		CAPIerr(CAPI_F_CAPI_RSA_SIGN, CAPI_R_CANT_CREATE_HASH_OBJECT);
		capi_addlasterror();
		return -1;
		}
/* Set the hash value to the value passed */

	if(!CryptSetHashParam(hash, HP_HASHVAL, (unsigned char *)m, 0))
		{
		CAPIerr(CAPI_F_CAPI_RSA_SIGN, CAPI_R_CANT_SET_HASH_VALUE);
		capi_addlasterror();
		goto err;
		}


/* Finally sign it */
	slen = RSA_size(rsa);
	if(!CryptSignHash(hash, capi_key->keyspec, NULL, 0, sigret, &slen))
		{
		CAPIerr(CAPI_F_CAPI_RSA_SIGN, CAPI_R_ERROR_SIGNING_HASH);
		capi_addlasterror();
		goto err;
		}
	else
		{
		ret = 1;
		/* Inplace byte reversal of signature */
		for(i = 0; i < slen / 2; i++)
			{
			unsigned char c;
			c = sigret[i];
			sigret[i] = sigret[slen - i - 1];
			sigret[slen - i - 1] = c;
			}
		*siglen = slen;
		}

	/* Now cleanup */

err:
	CryptDestroyHash(hash);

	return ret;
	}

int capi_rsa_priv_dec(int flen, const unsigned char *from,
                unsigned char *to, RSA *rsa, int padding)
	{
	int i;
	unsigned char *tmpbuf;
	CAPI_KEY *capi_key;
	CAPI_CTX *ctx;
	ctx = ENGINE_get_ex_data(rsa->engine, capi_idx);

	CAPI_trace(ctx, "Called capi_rsa_priv_dec()\n");


	capi_key = RSA_get_ex_data(rsa, rsa_capi_idx);
	if (!capi_key)
		{
		CAPIerr(CAPI_F_CAPI_RSA_PRIV_DEC, CAPI_R_CANT_GET_KEY);
		return -1;
		}

	if(padding != RSA_PKCS1_PADDING)
		{
		char errstr[10];
		BIO_snprintf(errstr, 10, "%d", padding);
		CAPIerr(CAPI_F_CAPI_RSA_PRIV_DEC, CAPI_R_UNSUPPORTED_PADDING);
		ERR_add_error_data(2, "padding=", errstr);
		return -1;
		}

	/* Create temp reverse order version of input */
	if(!(tmpbuf = OPENSSL_malloc(flen)) ) 
		{
		CAPIerr(CAPI_F_CAPI_RSA_PRIV_DEC, ERR_R_MALLOC_FAILURE);
		return -1;
		}
	for(i = 0; i < flen; i++)
		tmpbuf[flen - i - 1] = from[i];
	
	/* Finally decrypt it */
	if(!CryptDecrypt(capi_key->key, 0, TRUE, 0, tmpbuf, &flen))
		{
		CAPIerr(CAPI_F_CAPI_RSA_PRIV_DEC, CAPI_R_DECRYPT_ERROR);
		capi_addlasterror();
		OPENSSL_free(tmpbuf);
		return -1;
		} 
	else memcpy(to, tmpbuf, flen);

	OPENSSL_free(tmpbuf);

	return flen;
	}

static int capi_rsa_free(RSA *rsa)
	{
	CAPI_KEY *capi_key;
	capi_key = RSA_get_ex_data(rsa, rsa_capi_idx);
	capi_free_key(capi_key);
	RSA_set_ex_data(rsa, rsa_capi_idx, 0);
	return 1;
	}

/* CryptoAPI DSA operations */

static DSA_SIG *capi_dsa_do_sign(const unsigned char *digest, int dlen,
								DSA *dsa)
	{
	HCRYPTHASH hash;
	DWORD slen;
	DSA_SIG *ret = NULL;
	CAPI_KEY *capi_key;
	CAPI_CTX *ctx;
	unsigned char csigbuf[40];

	ctx = ENGINE_get_ex_data(dsa->engine, capi_idx);

	CAPI_trace(ctx, "Called CAPI_dsa_do_sign()\n");

	capi_key = DSA_get_ex_data(dsa, dsa_capi_idx);

	if (!capi_key)
		{
		CAPIerr(CAPI_F_CAPI_DSA_DO_SIGN, CAPI_R_CANT_GET_KEY);
		return NULL;
		}

	if (dlen != 20)
		{
		CAPIerr(CAPI_F_CAPI_DSA_DO_SIGN, CAPI_R_INVALID_DIGEST_LENGTH);
		return NULL;
		}

	/* Create the hash object */
	if(!CryptCreateHash(capi_key->hprov, CALG_SHA1, 0, 0, &hash))
		{
		CAPIerr(CAPI_F_CAPI_DSA_DO_SIGN, CAPI_R_CANT_CREATE_HASH_OBJECT);
		capi_addlasterror();
		return NULL;
		}

	/* Set the hash value to the value passed */
	if(!CryptSetHashParam(hash, HP_HASHVAL, (unsigned char *)digest, 0))
		{
		CAPIerr(CAPI_F_CAPI_DSA_DO_SIGN, CAPI_R_CANT_SET_HASH_VALUE);
		capi_addlasterror();
		goto err;
		}


	/* Finally sign it */
	slen = sizeof(csigbuf);
	if(!CryptSignHash(hash, capi_key->keyspec, NULL, 0, csigbuf, &slen))
		{
		CAPIerr(CAPI_F_CAPI_DSA_DO_SIGN, CAPI_R_ERROR_SIGNING_HASH);
		capi_addlasterror();
		goto err;
		}
	else
		{
		ret = DSA_SIG_new();
		if (!ret)
			goto err;
		ret->r = BN_new();
		ret->s = BN_new();
		if (!ret->r || !ret->s)
			goto err;
		if (!lend_tobn(ret->r, csigbuf, 20)
			|| !lend_tobn(ret->s, csigbuf + 20, 20))
			{
			DSA_SIG_free(ret);
			ret = NULL;
			goto err;
			}
		}

	/* Now cleanup */

err:
	OPENSSL_cleanse(csigbuf, 40);
	CryptDestroyHash(hash);
	return ret;
	}

static int capi_dsa_free(DSA *dsa)
	{
	CAPI_KEY *capi_key;
	capi_key = DSA_get_ex_data(dsa, dsa_capi_idx);
	capi_free_key(capi_key);
	DSA_set_ex_data(dsa, dsa_capi_idx, 0);
	return 1;
	}

static void capi_vtrace(CAPI_CTX *ctx, int level, char *format, va_list argptr)
	{
	BIO *out;

	if (!ctx || (ctx->debug_level < level) || (!ctx->debug_file))
		return;
	out = BIO_new_file(ctx->debug_file, "a+");
	BIO_vprintf(out, format, argptr);
	BIO_free(out);
	}

static void CAPI_trace(CAPI_CTX *ctx, char *format, ...)
	{
	va_list args;
	va_start(args, format);
	capi_vtrace(ctx, CAPI_DBG_TRACE, format, args);
	va_end(args);
	}

static void capi_addlasterror(void)
	{
	capi_adderror(GetLastError());
	}

static void capi_adderror(DWORD err)
	{
	char errstr[10];
	BIO_snprintf(errstr, 10, "%lX", err);
	ERR_add_error_data(2, "Error code= 0x", errstr);
	}

static char *wide_to_asc(LPCWSTR wstr)
	{
	char *str;
	int len_0,sz;

	if (!wstr)
		return NULL;
	len_0 = (int)wcslen(wstr)+1;	/* WideCharToMultiByte expects int */
        sz = WideCharToMultiByte(CP_ACP,0,wstr,len_0,NULL,0,NULL,NULL);
	if (!sz)
		{
		CAPIerr(CAPI_F_WIDE_TO_ASC, CAPI_R_WIN32_ERROR);
		return NULL;
		}
	str = OPENSSL_malloc(sz);
	if (!str)
		{
		CAPIerr(CAPI_F_WIDE_TO_ASC, ERR_R_MALLOC_FAILURE);
		return NULL;
		}
	if (!WideCharToMultiByte(CP_ACP,0,wstr,len_0,str,sz,NULL,NULL))
		{
		OPENSSL_free(str);
		CAPIerr(CAPI_F_WIDE_TO_ASC, CAPI_R_WIN32_ERROR);
		return NULL;
		}
	return str;
	}

static int capi_get_provname(CAPI_CTX *ctx, LPSTR *pname, DWORD *ptype, DWORD idx)
	{
	DWORD len, err;
	LPTSTR name;
	CAPI_trace(ctx, "capi_get_provname, index=%d\n", idx);
	if (!CryptEnumProviders(idx, NULL, 0, ptype, NULL, &len))
		{
		err = GetLastError();
		if (err == ERROR_NO_MORE_ITEMS)
			return 2;
		CAPIerr(CAPI_F_CAPI_GET_PROVNAME, CAPI_R_CRYPTENUMPROVIDERS_ERROR);
		capi_adderror(err);
		return 0;
		}
	if (sizeof(TCHAR) != sizeof(char))
		name = alloca(len);
	else
		name = OPENSSL_malloc(len);
	if (!CryptEnumProviders(idx, NULL, 0, ptype, name, &len))
		{
		err = GetLastError();
		if (err == ERROR_NO_MORE_ITEMS)
			return 2;
		CAPIerr(CAPI_F_CAPI_GET_PROVNAME, CAPI_R_CRYPTENUMPROVIDERS_ERROR);
		capi_adderror(err);
		return 0;
		}
	if (sizeof(TCHAR) != sizeof(char))
		*pname = wide_to_asc((WCHAR *)name);
	else
		*pname = (char *)name;
	CAPI_trace(ctx, "capi_get_provname, returned name=%s, type=%d\n", *pname, *ptype);

	return 1;
	}

static int capi_list_providers(CAPI_CTX *ctx, BIO *out)
	{
	DWORD idx, ptype;
	int ret;
	LPSTR provname = NULL;
	CAPI_trace(ctx, "capi_list_providers\n");
	BIO_printf(out, "Available CSPs:\n");
	for(idx = 0; ; idx++)
		{
		ret = capi_get_provname(ctx, &provname, &ptype, idx);
		if (ret == 2)
			break;
		if (ret == 0)
			break;
		BIO_printf(out, "%d. %s, type %d\n", idx, provname, ptype);
		OPENSSL_free(provname);
		}
	return 1;
	}

static int capi_list_containers(CAPI_CTX *ctx, BIO *out)
	{
	int ret = 1;
	HCRYPTPROV hprov;
	DWORD err, idx, flags, buflen = 0, clen;
	LPSTR cname;
	LPTSTR cspname = NULL;

	CAPI_trace(ctx, "Listing containers CSP=%s, type = %d\n", ctx->cspname, ctx->csptype);
	if (ctx->cspname && sizeof(TCHAR)!=sizeof(char))
		{
		if ((clen=MultiByteToWideChar(CP_ACP,0,ctx->cspname,-1,NULL,0)))
			{
			cspname = alloca(clen*sizeof(WCHAR));
			MultiByteToWideChar(CP_ACP,0,ctx->cspname,-1,(WCHAR *)cspname,clen);
			}
		if (!cspname)
			{
			CAPIerr(CAPI_F_CAPI_LIST_CONTAINERS, ERR_R_MALLOC_FAILURE);
			capi_addlasterror();
			return 0;
			}
		}
	else
		cspname = (TCHAR *)ctx->cspname;
	if (!CryptAcquireContext(&hprov, NULL, cspname, ctx->csptype, CRYPT_VERIFYCONTEXT))
		{
		CAPIerr(CAPI_F_CAPI_LIST_CONTAINERS, CAPI_R_CRYPTACQUIRECONTEXT_ERROR);
		capi_addlasterror();
		return 0;
		}
	if (!CryptGetProvParam(hprov, PP_ENUMCONTAINERS, NULL, &buflen, CRYPT_FIRST))
		{
		CAPIerr(CAPI_F_CAPI_LIST_CONTAINERS, CAPI_R_ENUMCONTAINERS_ERROR);
		capi_addlasterror();
		CryptReleaseContext(hprov, 0);
		return 0;
		}
	CAPI_trace(ctx, "Got max container len %d\n", buflen);
	if (buflen == 0)
		buflen = 1024;
	cname = OPENSSL_malloc(buflen);
	if (!cname)
		{
		CAPIerr(CAPI_F_CAPI_LIST_CONTAINERS, ERR_R_MALLOC_FAILURE);
		goto err;
		}

	for (idx = 0;;idx++)
		{
		clen = buflen;
		cname[0] = 0;

		if (idx == 0)
			flags = CRYPT_FIRST;
		else
			flags = 0;
		if(!CryptGetProvParam(hprov, PP_ENUMCONTAINERS, (BYTE *)cname, &clen, flags))
			{
			err = GetLastError();
			if (err == ERROR_NO_MORE_ITEMS)
				goto done;
			CAPIerr(CAPI_F_CAPI_LIST_CONTAINERS, CAPI_R_ENUMCONTAINERS_ERROR);
			capi_adderror(err);
			goto err;
			}
		CAPI_trace(ctx, "Container name %s, len=%d, index=%d, flags=%d\n", cname, clen, idx, flags);
		if (!cname[0] && (clen == buflen))
			{
			CAPI_trace(ctx, "Enumerate bug: using workaround\n");
			goto done;
			}
		BIO_printf(out, "%d. %s\n", idx, cname);
		}
	err:

	ret = 0;

	done:
	if (cname)
		OPENSSL_free(cname);
	CryptReleaseContext(hprov, 0);

	return ret;
	}

CRYPT_KEY_PROV_INFO *capi_get_prov_info(CAPI_CTX *ctx, PCCERT_CONTEXT cert)
	{
	DWORD len;
	CRYPT_KEY_PROV_INFO *pinfo;
	
	if(!CertGetCertificateContextProperty(cert, CERT_KEY_PROV_INFO_PROP_ID, NULL, &len))
		return NULL;
	pinfo = OPENSSL_malloc(len);
	if (!pinfo)
		{
		CAPIerr(CAPI_F_CAPI_GET_PROV_INFO, ERR_R_MALLOC_FAILURE);
		return NULL;
		}
	if(!CertGetCertificateContextProperty(cert, CERT_KEY_PROV_INFO_PROP_ID, pinfo, &len))
		{
		CAPIerr(CAPI_F_CAPI_GET_PROV_INFO, CAPI_R_ERROR_GETTING_KEY_PROVIDER_INFO);
		capi_addlasterror();
		OPENSSL_free(pinfo);
		return NULL;
		}
	return pinfo;
	}

static void capi_dump_prov_info(CAPI_CTX *ctx, BIO *out, CRYPT_KEY_PROV_INFO *pinfo)
	{
	char *provname = NULL, *contname = NULL;
	if (!pinfo)
		{
		BIO_printf(out, "  No Private Key\n");
		return;
		}
	provname = wide_to_asc(pinfo->pwszProvName);
	contname = wide_to_asc(pinfo->pwszContainerName);
	if (!provname || !contname)
		goto err;

	BIO_printf(out, "  Private Key Info:\n");
	BIO_printf(out, "    Provider Name:  %s, Provider Type %d\n", provname, pinfo->dwProvType);
	BIO_printf(out, "    Container Name: %s, Key Type %d\n", contname, pinfo->dwKeySpec);
	err:
	if (provname)
		OPENSSL_free(provname);
	if (contname)
		OPENSSL_free(contname);
	}

char * capi_cert_get_fname(CAPI_CTX *ctx, PCCERT_CONTEXT cert)
	{
	LPWSTR wfname;
	DWORD dlen;

	CAPI_trace(ctx, "capi_cert_get_fname\n");
	if (!CertGetCertificateContextProperty(cert, CERT_FRIENDLY_NAME_PROP_ID, NULL, &dlen))
		return NULL;
	wfname = OPENSSL_malloc(dlen);
	if (CertGetCertificateContextProperty(cert, CERT_FRIENDLY_NAME_PROP_ID, wfname, &dlen))
		{
		char *fname = wide_to_asc(wfname);
		OPENSSL_free(wfname);
		return fname;
		}
	CAPIerr(CAPI_F_CAPI_CERT_GET_FNAME, CAPI_R_ERROR_GETTING_FRIENDLY_NAME);
	capi_addlasterror();

	OPENSSL_free(wfname);
	return NULL;
	}


void capi_dump_cert(CAPI_CTX *ctx, BIO *out, PCCERT_CONTEXT cert)
	{
	X509 *x;
	unsigned char *p;
	unsigned long flags = ctx->dump_flags;
	if (flags & CAPI_DMP_FNAME)
		{
		char *fname;
		fname = capi_cert_get_fname(ctx, cert);
		if (fname)
			{
			BIO_printf(out, "  Friendly Name \"%s\"\n", fname);
			OPENSSL_free(fname);
			}
		else
			BIO_printf(out, "  <No Friendly Name>\n");
		}

	p = cert->pbCertEncoded;
	x = d2i_X509(NULL, &p, cert->cbCertEncoded);
	if (!x)
		BIO_printf(out, "  <Can't parse certificate>\n");
	if (flags & CAPI_DMP_SUMMARY)
		{
		BIO_printf(out, "  Subject: ");
		X509_NAME_print_ex(out, X509_get_subject_name(x), 0, XN_FLAG_ONELINE);
		BIO_printf(out, "\n  Issuer: ");
		X509_NAME_print_ex(out, X509_get_issuer_name(x), 0, XN_FLAG_ONELINE);
		BIO_printf(out, "\n");
		}
	if (flags & CAPI_DMP_FULL)
		X509_print_ex(out, x, XN_FLAG_ONELINE,0);

	if (flags & CAPI_DMP_PKEYINFO)
		{
		CRYPT_KEY_PROV_INFO *pinfo;
		pinfo = capi_get_prov_info(ctx, cert);
		capi_dump_prov_info(ctx, out, pinfo);
		if (pinfo)
			OPENSSL_free(pinfo);
		}

	if (flags & CAPI_DMP_PEM)
		PEM_write_bio_X509(out, x);
	X509_free(x);
	}

HCERTSTORE capi_open_store(CAPI_CTX *ctx, char *storename)
	{
	HCERTSTORE hstore;

	if (!storename)
		storename = ctx->storename;
	if (!storename)
		storename = "MY";
	CAPI_trace(ctx, "Opening certificate store %s\n", storename);

	hstore = CertOpenStore(CERT_STORE_PROV_SYSTEM_A, 0, 0, 
				ctx->store_flags, storename);
	if (!hstore)
		{
		CAPIerr(CAPI_F_CAPI_OPEN_STORE, CAPI_R_ERROR_OPENING_STORE);
		capi_addlasterror();
		}
	return hstore;
	}

int capi_list_certs(CAPI_CTX *ctx, BIO *out, char *id)
	{
	char *storename;
	int idx;
	int ret = 1;
	HCERTSTORE hstore;
	PCCERT_CONTEXT cert = NULL;

	storename = ctx->storename;
	if (!storename)
		storename = "MY";
	CAPI_trace(ctx, "Listing certs for store %s\n", storename);

	hstore = capi_open_store(ctx, storename);
	if (!hstore)
		return 0;
	if (id)
		{
		cert = capi_find_cert(ctx, id, hstore);
		if (!cert)
			{
			ret = 0;
			goto err;
			}
		capi_dump_cert(ctx, out, cert);
		CertFreeCertificateContext(cert);
		}
	else
		{
		for(idx = 0;;idx++)
			{
			cert = CertEnumCertificatesInStore(hstore, cert);
			if (!cert)
				break;
			BIO_printf(out, "Certificate %d\n", idx);
			capi_dump_cert(ctx, out, cert);
			}
		}
	err:
	CertCloseStore(hstore, 0);
	return ret;
	}

static PCCERT_CONTEXT capi_find_cert(CAPI_CTX *ctx, const char *id, HCERTSTORE hstore)
	{
	PCCERT_CONTEXT cert = NULL;
	char *fname = NULL;
	int match;
	switch(ctx->lookup_method)
		{
		case CAPI_LU_SUBSTR:
			return CertFindCertificateInStore(hstore,
					X509_ASN_ENCODING, 0,
					CERT_FIND_SUBJECT_STR_A, id, NULL);
		case CAPI_LU_FNAME:
			for(;;)
				{
				cert = CertEnumCertificatesInStore(hstore, cert);
				if (!cert)
					return NULL;
				fname = capi_cert_get_fname(ctx, cert);
				if (fname)
					{
					if (strcmp(fname, id))
						match = 0;
					else
						match = 1;
					OPENSSL_free(fname);
					if (match)
						return cert;
					}
				}
		default:
			return NULL;
		}
	}

static CAPI_KEY *capi_get_key(CAPI_CTX *ctx, const TCHAR *contname, TCHAR *provname, DWORD ptype, DWORD keyspec)
	{
	CAPI_KEY *key;
	DWORD dwFlags = 0; 
	key = OPENSSL_malloc(sizeof(CAPI_KEY));
	if (sizeof(TCHAR)==sizeof(char))
		CAPI_trace(ctx, "capi_get_key, contname=%s, provname=%s, type=%d\n",
						contname, provname, ptype);
	else if (ctx && ctx->debug_level>=CAPI_DBG_TRACE && ctx->debug_file)
		{
		/* above 'if' is optimization to minimize malloc-ations */
		char *_contname = wide_to_asc((WCHAR *)contname);
		char *_provname = wide_to_asc((WCHAR *)provname);

		CAPI_trace(ctx, "capi_get_key, contname=%s, provname=%s, type=%d\n", 
						_contname, _provname, ptype);
		if (_provname) OPENSSL_free(_provname);
		if (_contname) OPENSSL_free(_contname);
		}
	if(ctx->store_flags & CERT_SYSTEM_STORE_LOCAL_MACHINE)
		dwFlags = CRYPT_MACHINE_KEYSET;
	if (!CryptAcquireContext(&key->hprov, contname, provname, ptype, dwFlags))
		{
		CAPIerr(CAPI_F_CAPI_GET_KEY, CAPI_R_CRYPTACQUIRECONTEXT_ERROR);
		capi_addlasterror();
		goto err;
		}
	if (!CryptGetUserKey(key->hprov, keyspec, &key->key))
		{
		CAPIerr(CAPI_F_CAPI_GET_KEY, CAPI_R_GETUSERKEY_ERROR);
		capi_addlasterror();
		CryptReleaseContext(key->hprov, 0);
		goto err;
		}
	key->keyspec = keyspec;
	key->pcert = NULL;
	return key;

	err:
	OPENSSL_free(key);
	return NULL;
	}

static CAPI_KEY *capi_get_cert_key(CAPI_CTX *ctx, PCCERT_CONTEXT cert)
	{
	CAPI_KEY *key = NULL;
	CRYPT_KEY_PROV_INFO *pinfo = NULL;
	char *provname = NULL, *contname = NULL;
	pinfo = capi_get_prov_info(ctx, cert);
	if (!pinfo)
		goto err;
	if (sizeof(TCHAR) != sizeof(char))
		key = capi_get_key(ctx, (TCHAR *)pinfo->pwszContainerName,
				(TCHAR *)pinfo->pwszProvName,
				pinfo->dwProvType, pinfo->dwKeySpec);
	else
		{
		provname = wide_to_asc(pinfo->pwszProvName);
		contname = wide_to_asc(pinfo->pwszContainerName);
		if (!provname || !contname)
			goto err;
		key = capi_get_key(ctx, (TCHAR *)contname, (TCHAR *)provname,
				pinfo->dwProvType, pinfo->dwKeySpec);
		}

	err:
	if (pinfo)
		OPENSSL_free(pinfo);
	if (provname)
		OPENSSL_free(provname);
	if (contname)
		OPENSSL_free(contname);
	return key;
	}

CAPI_KEY *capi_find_key(CAPI_CTX *ctx, const char *id)
	{
	PCCERT_CONTEXT cert;
	HCERTSTORE hstore;
	CAPI_KEY *key = NULL;
	switch (ctx->lookup_method)
		{
		case CAPI_LU_SUBSTR:
		case CAPI_LU_FNAME:
		hstore = capi_open_store(ctx, NULL);
		if (!hstore)
			return NULL;
		cert = capi_find_cert(ctx, id, hstore);
		if (cert)
			{
			key = capi_get_cert_key(ctx, cert);
			CertFreeCertificateContext(cert);
			}
		CertCloseStore(hstore, 0);
		break;

		case CAPI_LU_CONTNAME:
		if (sizeof(TCHAR)!=sizeof(char))
			{
			WCHAR *contname, *provname;
			DWORD len;

			if ((len=MultiByteToWideChar(CP_ACP,0,id,-1,NULL,0)) &&
			    (contname=alloca(len*sizeof(WCHAR)),
			     MultiByteToWideChar(CP_ACP,0,id,-1,contname,len)) &&
			    (len=MultiByteToWideChar(CP_ACP,0,ctx->cspname,-1,NULL,0)) &&
			    (provname=alloca(len*sizeof(WCHAR)),
			     MultiByteToWideChar(CP_ACP,0,ctx->cspname,-1,provname,len)))
				key = capi_get_key(ctx,(TCHAR *)contname,
						(TCHAR *)provname,
						ctx->csptype,ctx->keytype);
			}
		else
			key = capi_get_key(ctx, (TCHAR *)id,
						(TCHAR *)ctx->cspname,
						ctx->csptype,ctx->keytype);
		break;
		}

	return key;
	}

void capi_free_key(CAPI_KEY *key)
	{
	if (!key)
		return;
	CryptDestroyKey(key->key);
	CryptReleaseContext(key->hprov, 0);
	if (key->pcert)
		CertFreeCertificateContext(key->pcert);
	OPENSSL_free(key);
	}


/* Initialize a CAPI_CTX structure */

static CAPI_CTX *capi_ctx_new()
	{
	CAPI_CTX *ctx;
	ctx = OPENSSL_malloc(sizeof(CAPI_CTX));
	if (!ctx)
		{
		CAPIerr(CAPI_F_CAPI_CTX_NEW, ERR_R_MALLOC_FAILURE);
		return NULL;
		}
	ctx->cspname = NULL;
	ctx->csptype = PROV_RSA_FULL;
	ctx->dump_flags = CAPI_DMP_SUMMARY|CAPI_DMP_FNAME;
	ctx->keytype = AT_KEYEXCHANGE;
	ctx->storename = NULL;
	ctx->ssl_client_store = NULL;
	ctx->store_flags = CERT_STORE_OPEN_EXISTING_FLAG |
				CERT_STORE_READONLY_FLAG |
				CERT_SYSTEM_STORE_CURRENT_USER;
	ctx->lookup_method = CAPI_LU_SUBSTR;
	ctx->debug_level = 0;
	ctx->debug_file = NULL;
	ctx->client_cert_select = cert_select_simple;
	return ctx;
	}

static void capi_ctx_free(CAPI_CTX *ctx)
	{
	CAPI_trace(ctx, "Calling capi_ctx_free with %lx\n", ctx);
	if (!ctx)
		return;
	if (ctx->cspname)
		OPENSSL_free(ctx->cspname);
	if (ctx->debug_file)
		OPENSSL_free(ctx->debug_file);
	if (ctx->storename)
		OPENSSL_free(ctx->storename);
	if (ctx->ssl_client_store)
		OPENSSL_free(ctx->ssl_client_store);
	OPENSSL_free(ctx);
	}

static int capi_ctx_set_provname(CAPI_CTX *ctx, LPSTR pname, DWORD type, int check)
	{
	CAPI_trace(ctx, "capi_ctx_set_provname, name=%s, type=%d\n", pname, type);
	if (check)
		{
		HCRYPTPROV hprov;
		LPTSTR name=NULL;

		if (sizeof(TCHAR)!=sizeof(char))
			{
			DWORD len;
			if ((len=MultiByteToWideChar(CP_ACP,0,pname,-1,NULL,0)))
				{
				name = alloca(len*sizeof(WCHAR));
				MultiByteToWideChar(CP_ACP,0,pname,-1,(WCHAR *)name,len);
				}
			}
		else
			name = (TCHAR *)pname;

		if (!name || !CryptAcquireContext(&hprov, NULL, name, type,
						CRYPT_VERIFYCONTEXT))
			{
			CAPIerr(CAPI_F_CAPI_CTX_SET_PROVNAME, CAPI_R_CRYPTACQUIRECONTEXT_ERROR);
			capi_addlasterror();
			return 0;
			}
		CryptReleaseContext(hprov, 0);
		}
	if (ctx->cspname)
		OPENSSL_free(ctx->cspname);
	ctx->cspname = BUF_strdup(pname);
	ctx->csptype = type;
	return 1;
	}

static int capi_ctx_set_provname_idx(CAPI_CTX *ctx, int idx)
	{
	LPSTR pname;
	DWORD type;
	int res;
	if (capi_get_provname(ctx, &pname, &type, idx) != 1)
		return 0;
	res = capi_ctx_set_provname(ctx, pname, type, 0);
	OPENSSL_free(pname);
	return res;
	}

static int cert_issuer_match(STACK_OF(X509_NAME) *ca_dn, X509 *x)
	{
	int i;
	X509_NAME *nm;
	/* Special case: empty list: match anything */
	if (sk_X509_NAME_num(ca_dn) <= 0)
		return 1;
	for (i = 0; i < sk_X509_NAME_num(ca_dn); i++)
		{
		nm = sk_X509_NAME_value(ca_dn, i);
		if (!X509_NAME_cmp(nm, X509_get_issuer_name(x)))
				return 1;
		}
	return 0;
	}



static int capi_load_ssl_client_cert(ENGINE *e, SSL *ssl,
	STACK_OF(X509_NAME) *ca_dn, X509 **pcert, EVP_PKEY **pkey,
	STACK_OF(X509) **pother, UI_METHOD *ui_method, void *callback_data)
	{
	STACK_OF(X509) *certs = NULL;
	X509 *x;
	char *storename;
	const char *p;
	int i, client_cert_idx;
	HCERTSTORE hstore;
	PCCERT_CONTEXT cert = NULL, excert = NULL;
	CAPI_CTX *ctx;
	CAPI_KEY *key;
	ctx = ENGINE_get_ex_data(e, capi_idx);

	*pcert = NULL;
	*pkey = NULL;

	storename = ctx->ssl_client_store;
	if (!storename)
		storename = "MY";

	hstore = capi_open_store(ctx, storename);
	if (!hstore)
		return 0;
	/* Enumerate all certificates collect any matches */
	for(i = 0;;i++)
		{
		cert = CertEnumCertificatesInStore(hstore, cert);
		if (!cert)
			break;
		p = cert->pbCertEncoded;
		x = d2i_X509(NULL, &p, cert->cbCertEncoded);
		if (!x)
			{
			CAPI_trace(ctx, "Can't Parse Certificate %d\n", i);
			continue;
			}
		if (cert_issuer_match(ca_dn, x)
			&& X509_check_purpose(x, X509_PURPOSE_SSL_CLIENT, 0))
			{
			key = capi_get_cert_key(ctx, cert);
			if (!key)
				{
				X509_free(x);
				continue;
				}
			/* Match found: attach extra data to it so
			 * we can retrieve the key later.
			 */
			excert = CertDuplicateCertificateContext(cert);
			key->pcert = excert;
			X509_set_ex_data(x, cert_capi_idx, key);

			if (!certs)
				certs = sk_X509_new_null();

			sk_X509_push(certs, x);
			}
		else
			X509_free(x);

		}

	if (cert)
		CertFreeCertificateContext(cert);
	if (hstore)
		CertCloseStore(hstore, 0);

	if (!certs)
		return 0;


	/* Select the appropriate certificate */

	client_cert_idx = ctx->client_cert_select(e, ssl, certs);

	/* Set the selected certificate and free the rest */

	for(i = 0; i < sk_X509_num(certs); i++)
		{
		x = sk_X509_value(certs, i);
		if (i == client_cert_idx)
			*pcert = x;
		else
			{
			key = X509_get_ex_data(x, cert_capi_idx);
			capi_free_key(key);
			X509_free(x);
			}
		}

	sk_X509_free(certs);

	if (!*pcert)
		return 0;

	/* Setup key for selected certificate */

	key = X509_get_ex_data(*pcert, cert_capi_idx);
	*pkey = capi_get_pkey(e, key);
	X509_set_ex_data(*pcert, cert_capi_idx, NULL);

	return 1;

	}


/* Simple client cert selection function: always select first */

static int cert_select_simple(ENGINE *e, SSL *ssl, STACK_OF(X509) *certs)
	{
	return 0;
	}

#ifdef OPENSSL_CAPIENG_DIALOG

/* More complex cert selection function, using standard function
 * CryptUIDlgSelectCertificateFromStore() to produce a dialog box.
 */

/* Definitions which are in cryptuiapi.h but this is not present in older
 * versions of headers.
 */

#ifndef CRYPTUI_SELECT_LOCATION_COLUMN
#define CRYPTUI_SELECT_LOCATION_COLUMN                   0x000000010
#define CRYPTUI_SELECT_INTENDEDUSE_COLUMN                0x000000004
#endif

#define dlg_title L"OpenSSL Application SSL Client Certificate Selection"
#define dlg_prompt L"Select a certificate to use for authentication"
#define dlg_columns	 CRYPTUI_SELECT_LOCATION_COLUMN \
			|CRYPTUI_SELECT_INTENDEDUSE_COLUMN

static int cert_select_dialog(ENGINE *e, SSL *ssl, STACK_OF(X509) *certs)
	{
	X509 *x;
	HCERTSTORE dstore;
	PCCERT_CONTEXT cert;
	CAPI_CTX *ctx;
	CAPI_KEY *key;
	HWND hwnd;
	int i, idx = -1;
	if (sk_X509_num(certs) == 1)
		return 0;
	ctx = ENGINE_get_ex_data(e, capi_idx);
	/* Create an in memory store of certificates */
	dstore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
					CERT_STORE_CREATE_NEW_FLAG, NULL);
	if (!dstore)
		{
		CAPIerr(CAPI_F_CERT_SELECT_DIALOG, CAPI_R_ERROR_CREATING_STORE);
		capi_addlasterror();
		goto err;
		}
	/* Add all certificates to store */
	for(i = 0; i < sk_X509_num(certs); i++)
		{
		x = sk_X509_value(certs, i);
		key = X509_get_ex_data(x, cert_capi_idx);

		if (!CertAddCertificateContextToStore(dstore, key->pcert,
						CERT_STORE_ADD_NEW, NULL))
			{
			CAPIerr(CAPI_F_CERT_SELECT_DIALOG, CAPI_R_ERROR_ADDING_CERT);
			capi_addlasterror();
			goto err;
			}

		}
	hwnd = GetForegroundWindow();
	if (!hwnd)
		hwnd = GetActiveWindow();
	if (!hwnd && ctx->getconswindow)
		hwnd = ctx->getconswindow();
	/* Call dialog to select one */
	cert = ctx->certselectdlg(dstore, hwnd, dlg_title, dlg_prompt,
						dlg_columns, 0, NULL);

	/* Find matching cert from list */
	if (cert)
		{
		for(i = 0; i < sk_X509_num(certs); i++)
			{
			x = sk_X509_value(certs, i);
			key = X509_get_ex_data(x, cert_capi_idx);
			if (CertCompareCertificate(
				X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
					cert->pCertInfo,
					key->pcert->pCertInfo))
				{
				idx = i;
				break;
				}
			}
		}

	err:
	if (dstore)
		CertCloseStore(dstore, 0);
	return idx;

	}
#endif

#else /* !__COMPILE_CAPIENG */
#include <openssl/engine.h>
#ifndef OPENSSL_NO_DYNAMIC_ENGINE
OPENSSL_EXPORT
int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns);
OPENSSL_EXPORT
int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns) { return 0; }
IMPLEMENT_DYNAMIC_CHECK_FN()
#else
void ENGINE_load_capi(void){}
#endif
#endif
