/* 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 <openssl/crypto.h>
#include <openssl/buffer.h>
#include <openssl/bn.h>

#ifdef OPENSSL_SYS_WIN32
# ifndef OPENSSL_NO_CAPIENG

#  include <openssl/rsa.h>

#  include <windows.h>

#  ifndef _WIN32_WINNT
#   define _WIN32_WINNT 0x0400
#  endif

#  include <wincrypt.h>

/*
 * 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

# 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_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 (!CryptSignHashA(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 (!CryptSignHashA(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(LPWSTR 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)
{
    LPSTR name;
    DWORD len, err;
    CAPI_trace(ctx, "capi_get_provname, index=%d\n", idx);
    if (!CryptEnumProvidersA(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;
    }
    name = OPENSSL_malloc(len);
    if (!CryptEnumProvidersA(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;
    }
    *pname = name;
    CAPI_trace(ctx, "capi_get_provname, returned name=%s, type=%d\n", name,
               *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;
    CAPI_trace(ctx, "Listing containers CSP=%s, type = %d\n", ctx->cspname,
               ctx->csptype);
    if (!CryptAcquireContextA
        (&hprov, NULL, ctx->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, 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++) {
            LPWSTR fname = NULL;
            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 char *contname,
                              char *provname, DWORD ptype, DWORD keyspec)
{
    CAPI_KEY *key;
    DWORD dwFlags = 0;
    key = OPENSSL_malloc(sizeof(CAPI_KEY));
    CAPI_trace(ctx, "capi_get_key, contname=%s, provname=%s, type=%d\n",
               contname, provname, ptype);
    if (ctx->store_flags & CERT_SYSTEM_STORE_LOCAL_MACHINE)
        dwFlags = CRYPT_MACHINE_KEYSET;
    if (!CryptAcquireContextA
        (&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;
    provname = wide_to_asc(pinfo->pwszProvName);
    contname = wide_to_asc(pinfo->pwszContainerName);
    if (!provname || !contname)
        goto err;
    key = capi_get_key(ctx, contname, 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:
        key = capi_get_key(ctx, id, 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;
        if (!CryptAcquireContextA(&hprov, NULL, pname, 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
