/*
 * Copyright 2008-2020 The OpenSSL Project Authors. All Rights Reserved.
 *
 * Licensed under the Apache License 2.0 (the "License").  You may not use
 * this file except in compliance with the License.  You can obtain a copy
 * in the file LICENSE in the source distribution or at
 * https://www.openssl.org/source/license.html
 */

/* We need to use some deprecated APIs */
#define OPENSSL_SUPPRESS_DEPRECATED

#ifdef _WIN32
# ifndef _WIN32_WINNT
#  define _WIN32_WINNT 0x0400
# endif
# include <windows.h>
# include <wincrypt.h>

# include <stdio.h>
# include <string.h>
# include <stdlib.h>
# include <malloc.h>
# ifndef alloca
#  define alloca _alloca
# endif

# include <openssl/crypto.h>

# ifndef OPENSSL_NO_CAPIENG

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

DEFINE_STACK_OF(X509)
DEFINE_STACK_OF(X509_NAME)

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

#ifdef __COMPILE_CAPIENG

# undef X509_EXTENSIONS

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

# ifndef PROV_RSA_AES
#  define PROV_RSA_AES 24
# 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);

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

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

void engine_load_capi_int(void);

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 */
# define CAPI_LU_SUBSTR          1  /* Substring of subject: uses "storename" */
# define CAPI_LU_FNAME           2  /* Friendly name: uses storename */
# define CAPI_LU_CONTNAME        3  /* Container name: uses cspname, keytype */
    int lookup_method;
/* Info to dump with dumpcerts option */
# define CAPI_DMP_SUMMARY        0x1    /* Issuer and serial name strings */
# define CAPI_DMP_FNAME          0x2    /* Friendly name */
# define CAPI_DMP_FULL           0x4    /* Full X509_print dump */
# define CAPI_DMP_PEM            0x8    /* Dump PEM format certificate */
# define CAPI_DMP_PSKEY          0x10   /* Dump pseudo key (if possible) */
# define CAPI_DMP_PKEYINFO       0x20   /* Dump key info (if possible) */
    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(void);
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;
    LPSTR tmpstr;
    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);
    if (out == NULL) {
        CAPIerr(CAPI_F_CAPI_CTRL, CAPI_R_FILE_OPEN_ERROR);
        return 0;
    }
    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:
        tmpstr = OPENSSL_strdup(p);
        if (tmpstr != NULL) {
            OPENSSL_free(ctx->storename);
            ctx->storename = tmpstr;
            CAPI_trace(ctx, "Setting store name to %s\n", p);
        } else {
            CAPIerr(CAPI_F_CAPI_CTRL, ERR_R_MALLOC_FAILURE);
            ret = 0;
        }
        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:
        tmpstr = OPENSSL_strdup(p);
        if (tmpstr != NULL) {
            ctx->debug_file = tmpstr;
            CAPI_trace(ctx, "Setting debug file to %s\n", ctx->debug_file);
        } else {
            CAPIerr(CAPI_F_CAPI_CTRL, ERR_R_MALLOC_FAILURE);
            ret = 0;
        }
        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);
            BIO_free(out);
            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 = NULL;
# ifndef OPENSSL_NO_DSA
static DSA_METHOD *capi_dsa_method = NULL;
# endif

static int use_aes_csp = 0;
static const WCHAR rsa_aes_cspname[] =
    L"Microsoft Enhanced RSA and AES Cryptographic Provider";
static const WCHAR rsa_enh_cspname[] =
    L"Microsoft Enhanced Cryptographic Provider v1.0";

static int capi_init(ENGINE *e)
{
    CAPI_CTX *ctx;
    const RSA_METHOD *ossl_rsa_meth;
# ifndef OPENSSL_NO_DSA
    const DSA_METHOD *ossl_dsa_meth;
# endif
    HCRYPTPROV hprov;

    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_OpenSSL();
        if (   !RSA_meth_set_pub_enc(capi_rsa_method,
                                     RSA_meth_get_pub_enc(ossl_rsa_meth))
            || !RSA_meth_set_pub_dec(capi_rsa_method,
                                     RSA_meth_get_pub_dec(ossl_rsa_meth))
            || !RSA_meth_set_priv_enc(capi_rsa_method, capi_rsa_priv_enc)
            || !RSA_meth_set_priv_dec(capi_rsa_method, capi_rsa_priv_dec)
            || !RSA_meth_set_mod_exp(capi_rsa_method,
                                     RSA_meth_get_mod_exp(ossl_rsa_meth))
            || !RSA_meth_set_bn_mod_exp(capi_rsa_method,
                                        RSA_meth_get_bn_mod_exp(ossl_rsa_meth))
            || !RSA_meth_set_finish(capi_rsa_method, capi_rsa_free)
            || !RSA_meth_set_sign(capi_rsa_method, capi_rsa_sign)) {
            goto memerr;
        }

# ifndef OPENSSL_NO_DSA
        /* Setup DSA Method */
        dsa_capi_idx = DSA_get_ex_new_index(0, NULL, NULL, NULL, 0);
        ossl_dsa_meth = DSA_OpenSSL();
        if (   !DSA_meth_set_sign(capi_dsa_method, capi_dsa_do_sign)
            || !DSA_meth_set_verify(capi_dsa_method,
                                    DSA_meth_get_verify(ossl_dsa_meth))
            || !DSA_meth_set_finish(capi_dsa_method, capi_dsa_free)
            || !DSA_meth_set_mod_exp(capi_dsa_method,
                                     DSA_meth_get_mod_exp(ossl_dsa_meth))
            || !DSA_meth_set_bn_mod_exp(capi_dsa_method,
                                    DSA_meth_get_bn_mod_exp(ossl_dsa_meth))) {
            goto memerr;
        }
# endif
    }

    ctx = capi_ctx_new();
    if (ctx == NULL)
        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

    /* See if there is RSA+AES CSP */
    if (CryptAcquireContextW(&hprov, NULL, rsa_aes_cspname, PROV_RSA_AES,
                             CRYPT_VERIFYCONTEXT)) {
        use_aes_csp = 1;
        CryptReleaseContext(hprov, 0);
    }

    return 1;

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

    return 1;
}

static int capi_destroy(ENGINE *e)
{
    RSA_meth_free(capi_rsa_method);
    capi_rsa_method = NULL;
# ifndef OPENSSL_NO_DSA
    DSA_meth_free(capi_dsa_method);
    capi_dsa_method = NULL;
# endif
    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)
{
    capi_rsa_method = RSA_meth_new("CryptoAPI RSA method", 0);
    if (capi_rsa_method == NULL)
        return 0;
# ifndef OPENSSL_NO_DSA
    capi_dsa_method = DSA_meth_new("CryptoAPI DSA method", 0);
    if (capi_dsa_method == NULL)
        goto memerr;
# endif
    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)
# ifndef OPENSSL_NO_DSA
        || !ENGINE_set_DSA(e, capi_dsa_method)
# endif
        || !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))
        goto memerr;
    ERR_load_CAPI_strings();

    return 1;
 memerr:
    RSA_meth_free(capi_rsa_method);
    capi_rsa_method = NULL;
# ifndef OPENSSL_NO_DSA
    DSA_meth_free(capi_dsa_method);
    capi_dsa_method = NULL;
# endif
    return 0;
}

# 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 == NULL)
        return NULL;
    if (!bind_capi(ret)) {
        ENGINE_free(ret);
        return NULL;
    }
    return ret;
}

void engine_load_capi_int(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 == NULL)
        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;
        BIGNUM *e = NULL, *n = NULL;
        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;

        e = BN_new();
        n = BN_new();

        if (e == NULL || n == NULL) {
            BN_free(e);
            BN_free(n);
            goto memerr;
        }

        RSA_set0_key(rkey, n, e, NULL);

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

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

        RSA_set_ex_data(rkey, rsa_capi_idx, key);

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

        EVP_PKEY_assign_RSA(ret, rkey);
        rkey = NULL;

# ifndef OPENSSL_NO_DSA
    } else if (bh->aiKeyAlg == CALG_DSS_SIGN) {
        DSSPUBKEY *dp;
        DWORD dsa_plen;
        unsigned char *btmp;
        BIGNUM *p, *q, *g, *pub_key;
        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;
        p = BN_new();
        q = BN_new();
        g = BN_new();
        pub_key = BN_new();
        if (p == NULL || q == NULL || g == NULL || pub_key == NULL) {
            BN_free(p);
            BN_free(q);
            BN_free(g);
            BN_free(pub_key);
            goto memerr;
        }
        DSA_set0_pqg(dkey, p, q, g);
        DSA_set0_key(dkey, pub_key, NULL);
        if (!lend_tobn(p, btmp, dsa_plen))
            goto memerr;
        btmp += dsa_plen;
        if (!lend_tobn(q, btmp, 20))
            goto memerr;
        btmp += 20;
        if (!lend_tobn(g, btmp, dsa_plen))
            goto memerr;
        btmp += dsa_plen;
        if (!lend_tobn(pub_key, btmp, dsa_plen))
            goto memerr;
        btmp += dsa_plen;

        DSA_set_ex_data(dkey, dsa_capi_idx, key);

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

        EVP_PKEY_assign_DSA(ret, dkey);
        dkey = NULL;
# endif
    } else {
        char algstr[10];
        BIO_snprintf(algstr, 10, "%ux", 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:
    OPENSSL_free(pubkey);
    if (!ret) {
        RSA_free(rkey);
# ifndef OPENSSL_NO_DSA
        DSA_free(dkey);
# endif
    }

    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_get0_engine(rsa), 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, "%x", 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;
    DWORD flags = 0;
    DWORD dlen;

    if (flen <= 0)
        return flen;

    ctx = ENGINE_get_ex_data(RSA_get0_engine(rsa), 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;
    }

    switch (padding) {
    case RSA_PKCS1_PADDING:
        /* Nothing to do */
        break;
#ifdef CRYPT_DECRYPT_RSA_NO_PADDING_CHECK
    case RSA_NO_PADDING:
        flags = CRYPT_DECRYPT_RSA_NO_PADDING_CHECK;
        break;
#endif
    default:
        {
            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)) == NULL) {
        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 */
    dlen = flen;
    if (!CryptDecrypt(capi_key->key, 0, TRUE, flags, tmpbuf, &dlen)) {
        CAPIerr(CAPI_F_CAPI_RSA_PRIV_DEC, CAPI_R_DECRYPT_ERROR);
        capi_addlasterror();
        OPENSSL_cleanse(tmpbuf, dlen);
        OPENSSL_free(tmpbuf);
        return -1;
    } else {
        memcpy(to, tmpbuf, (flen = (int)dlen));
    }
    OPENSSL_cleanse(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;
}

# ifndef OPENSSL_NO_DSA
/* 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_get0_engine(dsa), 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 {
        BIGNUM *r = BN_new(), *s = BN_new();

        if (r == NULL || s == NULL
            || !lend_tobn(r, csigbuf, 20)
            || !lend_tobn(s, csigbuf + 20, 20)
            || (ret = DSA_SIG_new()) == NULL) {
            BN_free(r); /* BN_free checks for BIGNUM * being NULL */
            BN_free(s);
            goto err;
        }
        DSA_SIG_set0(ret, r, s);
    }

    /* 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;
}
# endif

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+");
    if (out == NULL) {
        CAPIerr(CAPI_F_CAPI_VTRACE, CAPI_R_FILE_OPEN_ERROR);
        return;
    }
    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 == NULL) {
        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;
    }
    name = OPENSSL_malloc(len);
    if (name == NULL) {
        CAPIerr(CAPI_F_CAPI_GET_PROVNAME, ERR_R_MALLOC_FAILURE);
        return 0;
    }
    if (!CryptEnumProviders(idx, NULL, 0, ptype, name, &len)) {
        err = GetLastError();
        OPENSSL_free(name);
        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);
        OPENSSL_free(name);
        if (*pname == NULL)
            return 0;
    } 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, "%lu. %s, type %lu\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;
    LPWSTR cspname = NULL;

    CAPI_trace(ctx, "Listing containers CSP=%s, type = %d\n", ctx->cspname,
               ctx->csptype);
    if (ctx->cspname != NULL) {
        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 == NULL) {
            CAPIerr(CAPI_F_CAPI_LIST_CONTAINERS, ERR_R_MALLOC_FAILURE);
            capi_addlasterror();
            return 0;
        }
    }
    if (!CryptAcquireContextW(&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 == NULL) {
        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, "%lu. %s\n", idx, cname);
    }
 err:

    ret = 0;

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

    return ret;
}

static 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 == NULL) {
        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 == NULL) {
        BIO_printf(out, "  No Private Key\n");
        return;
    }
    provname = wide_to_asc(pinfo->pwszProvName);
    contname = wide_to_asc(pinfo->pwszContainerName);
    if (provname == NULL || contname == NULL)
        goto err;

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

static 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 (wfname == NULL)
        return NULL;
    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;
}

static void capi_dump_cert(CAPI_CTX *ctx, BIO *out, PCCERT_CONTEXT cert)
{
    X509 *x;
    const 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);
        OPENSSL_free(pinfo);
    }

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

static 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 WCHAR *contname,
                              const WCHAR *provname, DWORD ptype,
                              DWORD keyspec)
{
    DWORD dwFlags = 0;
    CAPI_KEY *key = OPENSSL_malloc(sizeof(*key));

    if (key == NULL)
        return NULL;
    /* If PROV_RSA_AES supported use it instead */
    if (ptype == PROV_RSA_FULL && use_aes_csp &&
        wcscmp(provname, rsa_enh_cspname) == 0) {
        provname = rsa_aes_cspname;
        ptype = PROV_RSA_AES;
    }
    if (ctx && ctx->debug_level >= CAPI_DBG_TRACE && ctx->debug_file) {
        /*
         * above 'if' is [complementary] copy from CAPI_trace and serves
         * as optimization to minimize [below] malloc-ations
         */
        char *_contname = wide_to_asc(contname);
        char *_provname = wide_to_asc(provname);

        CAPI_trace(ctx, "capi_get_key, contname=%s, provname=%s, type=%d\n",
                   _contname, _provname, ptype);
        OPENSSL_free(_provname);
        OPENSSL_free(_contname);
    }
    if (ctx->store_flags & CERT_SYSTEM_STORE_LOCAL_MACHINE)
        dwFlags = CRYPT_MACHINE_KEYSET;
    if (!CryptAcquireContextW(&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;

    pinfo = capi_get_prov_info(ctx, cert);

    if (pinfo != NULL)
        key = capi_get_key(ctx, pinfo->pwszContainerName, pinfo->pwszProvName,
                           pinfo->dwProvType, pinfo->dwKeySpec);

    OPENSSL_free(pinfo);
    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:
        {
            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, contname, provname,
                                   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(void)
{
    CAPI_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx));

    if (ctx == NULL) {
        CAPIerr(CAPI_F_CAPI_CTX_NEW, ERR_R_MALLOC_FAILURE);
        return NULL;
    }
    ctx->csptype = PROV_RSA_FULL;
    ctx->dump_flags = CAPI_DMP_SUMMARY | CAPI_DMP_FNAME;
    ctx->keytype = AT_KEYEXCHANGE;
    ctx->store_flags = CERT_STORE_OPEN_EXISTING_FLAG |
        CERT_STORE_READONLY_FLAG | CERT_SYSTEM_STORE_CURRENT_USER;
    ctx->lookup_method = CAPI_LU_SUBSTR;
    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;
    OPENSSL_free(ctx->cspname);
    OPENSSL_free(ctx->debug_file);
    OPENSSL_free(ctx->storename);
    OPENSSL_free(ctx->ssl_client_store);
    OPENSSL_free(ctx);
}

static int capi_ctx_set_provname(CAPI_CTX *ctx, LPSTR pname, DWORD type,
                                 int check)
{
    LPSTR tmpcspname;

    CAPI_trace(ctx, "capi_ctx_set_provname, name=%s, type=%d\n", pname, type);
    if (check) {
        HCRYPTPROV hprov;
        LPWSTR name = NULL;
        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);
        }
        if (name == NULL || !CryptAcquireContextW(&hprov, NULL, name, type,
                                                  CRYPT_VERIFYCONTEXT)) {
            CAPIerr(CAPI_F_CAPI_CTX_SET_PROVNAME,
                    CAPI_R_CRYPTACQUIRECONTEXT_ERROR);
            capi_addlasterror();
            return 0;
        }
        CryptReleaseContext(hprov, 0);
    }
    tmpcspname = OPENSSL_strdup(pname);
    if (tmpcspname == NULL) {
        CAPIerr(CAPI_F_CAPI_CTX_SET_PROVNAME, ERR_R_MALLOC_FAILURE);
        return 0;
    }
    OPENSSL_free(ctx->cspname);
    ctx->cspname = tmpcspname;
    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 unsigned 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 == NULL)
        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_int(void);
void engine_load_capi_int(void)
{
}
# endif
#endif
