/*
 * Copyright (c) 2004 Peter 'Luna' Runestig <peter@runestig.com>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modifi-
 * cation, are permitted provided that the following conditions are met:
 *
 *   o  Redistributions of source code must retain the above copyright notice,
 *      this list of conditions and the following disclaimer.
 *
 *   o  Redistributions in binary form must reproduce the above copyright no-
 *      tice, this list of conditions and the following disclaimer in the do-
 *      cumentation and/or other materials provided with the distribution.
 *
 *   o  The names of the contributors may not be used to endorse or promote
 *      products derived from this software without specific prior written
 *      permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS 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 REGENTS OR CONTRIBUTORS BE LI-
 * ABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUEN-
 * TIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEV-
 * ER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABI-
 * LITY, 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.
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#elif defined(_MSC_VER)
#include "config-msvc.h"
#endif

#include "syshead.h"

#ifdef ENABLE_CRYPTOAPI

#include <openssl/ssl.h>
#include <openssl/evp.h>
#include <openssl/err.h>
#include <windows.h>
#include <wincrypt.h>
#include <ncrypt.h>
#include <stdio.h>
#include <ctype.h>
#include <assert.h>

#include "buffer.h"
#include "openssl_compat.h"
#include "win32.h"

/* MinGW w32api 3.17 is still incomplete when it comes to CryptoAPI while
 * MinGW32-w64 defines all macros used. This is a hack around that problem.
 */
#ifndef CERT_SYSTEM_STORE_LOCATION_SHIFT
#define CERT_SYSTEM_STORE_LOCATION_SHIFT 16
#endif
#ifndef CERT_SYSTEM_STORE_CURRENT_USER_ID
#define CERT_SYSTEM_STORE_CURRENT_USER_ID 1
#endif
#ifndef CERT_SYSTEM_STORE_CURRENT_USER
#define CERT_SYSTEM_STORE_CURRENT_USER (CERT_SYSTEM_STORE_CURRENT_USER_ID << CERT_SYSTEM_STORE_LOCATION_SHIFT)
#endif
#ifndef CERT_STORE_READONLY_FLAG
#define CERT_STORE_READONLY_FLAG 0x00008000
#endif
#ifndef CERT_STORE_OPEN_EXISTING_FLAG
#define CERT_STORE_OPEN_EXISTING_FLAG 0x00004000
#endif

/* Size of an SSL signature: MD5+SHA1 */
#define SSL_SIG_LENGTH  36

/* try to funnel any Windows/CryptoAPI error messages to OpenSSL ERR_... */
#define ERR_LIB_CRYPTOAPI (ERR_LIB_USER + 69)   /* 69 is just a number... */
#define CRYPTOAPIerr(f)   err_put_ms_error(GetLastError(), (f), __FILE__, __LINE__)
#define CRYPTOAPI_F_CERT_OPEN_SYSTEM_STORE                  100
#define CRYPTOAPI_F_CERT_FIND_CERTIFICATE_IN_STORE          101
#define CRYPTOAPI_F_CRYPT_ACQUIRE_CERTIFICATE_PRIVATE_KEY   102
#define CRYPTOAPI_F_CRYPT_CREATE_HASH                       103
#define CRYPTOAPI_F_CRYPT_GET_HASH_PARAM                    104
#define CRYPTOAPI_F_CRYPT_SET_HASH_PARAM                    105
#define CRYPTOAPI_F_CRYPT_SIGN_HASH                         106
#define CRYPTOAPI_F_LOAD_LIBRARY                            107
#define CRYPTOAPI_F_GET_PROC_ADDRESS                        108
#define CRYPTOAPI_F_NCRYPT_SIGN_HASH                        109

static ERR_STRING_DATA CRYPTOAPI_str_functs[] = {
    { ERR_PACK(ERR_LIB_CRYPTOAPI, 0, 0),                                    "microsoft cryptoapi"},
    { ERR_PACK(0, CRYPTOAPI_F_CERT_OPEN_SYSTEM_STORE, 0),                   "CertOpenSystemStore" },
    { ERR_PACK(0, CRYPTOAPI_F_CERT_FIND_CERTIFICATE_IN_STORE, 0),           "CertFindCertificateInStore" },
    { ERR_PACK(0, CRYPTOAPI_F_CRYPT_ACQUIRE_CERTIFICATE_PRIVATE_KEY, 0),    "CryptAcquireCertificatePrivateKey" },
    { ERR_PACK(0, CRYPTOAPI_F_CRYPT_CREATE_HASH, 0),                        "CryptCreateHash" },
    { ERR_PACK(0, CRYPTOAPI_F_CRYPT_GET_HASH_PARAM, 0),                     "CryptGetHashParam" },
    { ERR_PACK(0, CRYPTOAPI_F_CRYPT_SET_HASH_PARAM, 0),                     "CryptSetHashParam" },
    { ERR_PACK(0, CRYPTOAPI_F_CRYPT_SIGN_HASH, 0),                          "CryptSignHash" },
    { ERR_PACK(0, CRYPTOAPI_F_LOAD_LIBRARY, 0),                             "LoadLibrary" },
    { ERR_PACK(0, CRYPTOAPI_F_GET_PROC_ADDRESS, 0),                         "GetProcAddress" },
    { ERR_PACK(0, CRYPTOAPI_F_NCRYPT_SIGN_HASH, 0),                         "NCryptSignHash" },
    { 0, NULL }
};

/* Global EVP_PKEY_METHOD used to override the sign operation */
static EVP_PKEY_METHOD *pmethod;
static int (*default_pkey_sign_init) (EVP_PKEY_CTX *ctx);
static int (*default_pkey_sign) (EVP_PKEY_CTX *ctx, unsigned char *sig,
                                 size_t *siglen, const unsigned char *tbs, size_t tbslen);

typedef struct _CAPI_DATA {
    const CERT_CONTEXT *cert_context;
    HCRYPTPROV_OR_NCRYPT_KEY_HANDLE crypt_prov;
    DWORD key_spec;
    BOOL free_crypt_prov;
} CAPI_DATA;

/**
 * Translate OpenSSL padding type to CNG padding type
 * Returns 0 for unknown/unsupported padding.
 */
static DWORD
cng_padding_type(int padding)
{
    DWORD pad = 0;

    switch (padding)
    {
        case RSA_NO_PADDING:
            pad = BCRYPT_PAD_NONE;
            break;

        case RSA_PKCS1_PADDING:
            pad = BCRYPT_PAD_PKCS1;
            break;

        case RSA_PKCS1_PSS_PADDING:
            pad = BCRYPT_PAD_PSS;
            break;

        default:
            msg(M_WARN|M_INFO, "cryptoapicert: unknown OpenSSL padding type %d.",
                padding);
    }

    return pad;
}

/**
 * Translate OpenSSL hash OID to CNG algorithm name. Returns
 * "UNKNOWN" for unsupported algorithms and NULL for MD5+SHA1
 * mixed hash used in TLS 1.1 and earlier.
 */
static const wchar_t *
cng_hash_algo(int md_type)
{
    const wchar_t *alg = L"UNKNOWN";
    switch (md_type)
    {
        case NID_md5:
            alg = BCRYPT_MD5_ALGORITHM;
            break;

        case NID_sha1:
            alg = BCRYPT_SHA1_ALGORITHM;
            break;

        case NID_sha256:
            alg = BCRYPT_SHA256_ALGORITHM;
            break;

        case NID_sha384:
            alg = BCRYPT_SHA384_ALGORITHM;
            break;

        case NID_sha512:
            alg = BCRYPT_SHA512_ALGORITHM;
            break;

        case NID_md5_sha1:
        case 0:
            alg = NULL;
            break;

        default:
            msg(M_WARN|M_INFO, "cryptoapicert: Unknown hash type NID=0x%x", md_type);
            break;
    }
    return alg;
}

static char *
ms_error_text(DWORD ms_err)
{
    LPVOID lpMsgBuf = NULL;
    char *rv = NULL;

    FormatMessage(
        FORMAT_MESSAGE_ALLOCATE_BUFFER
        |FORMAT_MESSAGE_FROM_SYSTEM
        |FORMAT_MESSAGE_IGNORE_INSERTS,
        NULL, ms_err,
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), /* Default language */
        (LPTSTR) &lpMsgBuf, 0, NULL);
    if (lpMsgBuf)
    {
        char *p;
        rv = string_alloc(lpMsgBuf, NULL);
        LocalFree(lpMsgBuf);
        /* trim to the left */
        if (rv)
        {
            for (p = rv + strlen(rv) - 1; p >= rv; p--) {
                if (isspace(*p))
                {
                    *p = '\0';
                }
                else
                {
                    break;
                }
            }
        }
    }
    return rv;
}

static void
err_put_ms_error(DWORD ms_err, int func, const char *file, int line)
{
    static int init = 0;
#define ERR_MAP_SZ 16
    static struct {
        int err;
        DWORD ms_err;       /* I don't think we get more than 16 *different* errors */
    } err_map[ERR_MAP_SZ];  /* in here, before we give up the whole thing...        */
    int i;

    if (ms_err == 0)
    {
        /* 0 is not an error */
        return;
    }
    if (!init)
    {
        ERR_load_strings(ERR_LIB_CRYPTOAPI, CRYPTOAPI_str_functs);
        memset(&err_map, 0, sizeof(err_map));
        init++;
    }
    /* since MS error codes are 32 bit, and the ones in the ERR_... system is
     * only 12, we must have a mapping table between them.  */
    for (i = 0; i < ERR_MAP_SZ; i++) {
        if (err_map[i].ms_err == ms_err)
        {
            ERR_PUT_error(ERR_LIB_CRYPTOAPI, func, err_map[i].err, file, line);
            break;
        }
        else if (err_map[i].ms_err == 0)
        {
            /* end of table, add new entry */
            ERR_STRING_DATA *esd = calloc(2, sizeof(*esd));
            if (esd == NULL)
            {
                break;
            }
            err_map[i].ms_err = ms_err;
            err_map[i].err = esd->error = i + 100;
            esd->string = ms_error_text(ms_err);
            check_malloc_return(esd->string);
            ERR_load_strings(ERR_LIB_CRYPTOAPI, esd);
            ERR_PUT_error(ERR_LIB_CRYPTOAPI, func, err_map[i].err, file, line);
            break;
        }
    }
}

/* encrypt */
static int
rsa_pub_enc(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding)
{
    /* I haven't been able to trigger this one, but I want to know if it happens... */
    assert(0);

    return 0;
}

/* verify arbitrary data */
static int
rsa_pub_dec(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding)
{
    /* I haven't been able to trigger this one, but I want to know if it happens... */
    assert(0);

    return 0;
}

/**
 * Sign the hash in 'from' using NCryptSignHash(). This requires an NCRYPT
 * key handle in cd->crypt_prov. On return the signature is in 'to'. Returns
 * the length of the signature or 0 on error.
 * Only RSA is supported and padding should be BCRYPT_PAD_PKCS1 or
 * BCRYPT_PAD_PSS.
 * If the hash_algo is not NULL, PKCS #1 DigestInfo header gets added
 * to |from|, else it is signed as is. Use NULL for MD5 + SHA1 hash used
 * in TLS 1.1 and earlier.
 * In case of PSS padding, |saltlen| should specify the size of salt to use.
 * If |to| is NULL returns the required buffer size.
 */
static int
priv_enc_CNG(const CAPI_DATA *cd, const wchar_t *hash_algo, const unsigned char *from,
             int flen, unsigned char *to, int tlen, DWORD padding, DWORD saltlen)
{
    NCRYPT_KEY_HANDLE hkey = cd->crypt_prov;
    DWORD len = 0;
    ASSERT(cd->key_spec == CERT_NCRYPT_KEY_SPEC);

    DWORD status;

    msg(D_LOW, "Signing hash using CNG: data size = %d padding = %lu", flen, padding);

    if (padding == BCRYPT_PAD_PKCS1)
    {
        BCRYPT_PKCS1_PADDING_INFO padinfo = {hash_algo};
        status = NCryptSignHash(hkey, &padinfo, (BYTE *)from, flen,
                                to, tlen, &len, padding);
    }
    else if (padding == BCRYPT_PAD_PSS)
    {
        BCRYPT_PSS_PADDING_INFO padinfo = {hash_algo, saltlen};
        status = NCryptSignHash(hkey, &padinfo, (BYTE *)from, flen,
                                to, tlen, &len, padding);
    }
    else
    {
        RSAerr(RSA_F_RSA_OSSL_PRIVATE_ENCRYPT, RSA_R_UNKNOWN_PADDING_TYPE);
        return 0;
    }

    if (status != ERROR_SUCCESS)
    {
        SetLastError(status);
        CRYPTOAPIerr(CRYPTOAPI_F_NCRYPT_SIGN_HASH);
        len = 0;
    }

    /* Unlike CAPI, CNG signature is in big endian order. No reversing needed. */
    return len;
}

/* sign arbitrary data */
static int
rsa_priv_enc(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding)
{
    CAPI_DATA *cd = (CAPI_DATA *) RSA_meth_get0_app_data(RSA_get_method(rsa));
    HCRYPTHASH hash;
    DWORD hash_size, len, i;
    unsigned char *buf;

    if (cd == NULL)
    {
        RSAerr(RSA_F_RSA_OSSL_PRIVATE_ENCRYPT, ERR_R_PASSED_NULL_PARAMETER);
        return 0;
    }

    if (cd->key_spec == CERT_NCRYPT_KEY_SPEC)
    {
        return priv_enc_CNG(cd, NULL, from, flen, to, RSA_size(rsa),
                            cng_padding_type(padding), 0);
    }

    if (padding != RSA_PKCS1_PADDING)
    {
        /* AFAICS, CryptSignHash() *always* uses PKCS1 padding. */
        RSAerr(RSA_F_RSA_OSSL_PRIVATE_ENCRYPT, RSA_R_UNKNOWN_PADDING_TYPE);
        return 0;
    }

    /* Unfortunately, there is no "CryptSign()" function in CryptoAPI, that would
     * be way to straightforward for M$, I guess... So we have to do it this
     * tricky way instead, by creating a "Hash", and load the already-made hash
     * from 'from' into it.  */
    /* For now, we only support NID_md5_sha1 */
    if (flen != SSL_SIG_LENGTH)
    {
        RSAerr(RSA_F_RSA_OSSL_PRIVATE_ENCRYPT, RSA_R_INVALID_MESSAGE_LENGTH);
        return 0;
    }
    if (!CryptCreateHash(cd->crypt_prov, CALG_SSL3_SHAMD5, 0, 0, &hash))
    {
        CRYPTOAPIerr(CRYPTOAPI_F_CRYPT_CREATE_HASH);
        return 0;
    }
    len = sizeof(hash_size);
    if (!CryptGetHashParam(hash, HP_HASHSIZE, (BYTE *) &hash_size, &len, 0))
    {
        CRYPTOAPIerr(CRYPTOAPI_F_CRYPT_GET_HASH_PARAM);
        CryptDestroyHash(hash);
        return 0;
    }
    if ((int) hash_size != flen)
    {
        RSAerr(RSA_F_RSA_OSSL_PRIVATE_ENCRYPT, RSA_R_INVALID_MESSAGE_LENGTH);
        CryptDestroyHash(hash);
        return 0;
    }
    if (!CryptSetHashParam(hash, HP_HASHVAL, (BYTE * ) from, 0))
    {
        CRYPTOAPIerr(CRYPTOAPI_F_CRYPT_SET_HASH_PARAM);
        CryptDestroyHash(hash);
        return 0;
    }

    len = RSA_size(rsa);
    buf = malloc(len);
    if (buf == NULL)
    {
        RSAerr(RSA_F_RSA_OSSL_PRIVATE_ENCRYPT, ERR_R_MALLOC_FAILURE);
        CryptDestroyHash(hash);
        return 0;
    }
    if (!CryptSignHash(hash, cd->key_spec, NULL, 0, buf, &len))
    {
        CRYPTOAPIerr(CRYPTOAPI_F_CRYPT_SIGN_HASH);
        CryptDestroyHash(hash);
        free(buf);
        return 0;
    }
    /* and now, we have to reverse the byte-order in the result from CryptSignHash()... */
    for (i = 0; i < len; i++)
    {
        to[i] = buf[len - i - 1];
    }
    free(buf);

    CryptDestroyHash(hash);
    return len;
}

/**
 * Sign the hash in |m| and return the signature in |sig|.
 * Returns 1 on success, 0 on error.
 * NCryptSignHash() is used to sign and it is instructed to add the
 * the PKCS #1 DigestInfo header to |m| unless the hash algorithm is
 * the MD5/SHA1 combination used in TLS 1.1 and earlier versions.
 * OpenSSL exercises this callback only when padding is PKCS1 v1.5.
 */
static int
rsa_sign_CNG(int type, const unsigned char *m, unsigned int m_len,
              unsigned char *sig, unsigned int *siglen, const RSA *rsa)
{
    CAPI_DATA *cd = (CAPI_DATA *) RSA_meth_get0_app_data(RSA_get_method(rsa));
    const wchar_t *alg = NULL;
    int padding = RSA_PKCS1_PADDING;

    *siglen = 0;
    if (cd == NULL)
    {
        RSAerr(RSA_F_RSA_OSSL_PRIVATE_ENCRYPT, ERR_R_PASSED_NULL_PARAMETER);
        return 0;
    }

    alg = cng_hash_algo(type);
    if (alg && wcscmp(alg, L"UNKNOWN") == 0)
    {
        RSAerr(RSA_F_RSA_SIGN, RSA_R_UNKNOWN_ALGORITHM_TYPE);
        return 0;
    }

    *siglen = priv_enc_CNG(cd, alg, m, (int)m_len, sig, RSA_size(rsa),
                           cng_padding_type(padding), 0);

    return (*siglen == 0) ? 0 : 1;
}

/* decrypt */
static int
rsa_priv_dec(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding)
{
    /* I haven't been able to trigger this one, but I want to know if it happens... */
    assert(0);

    return 0;
}

/* called at RSA_new */
static int
init(RSA *rsa)
{

    return 0;
}

/* called at RSA_free */
static int
finish(RSA *rsa)
{
    const RSA_METHOD *rsa_meth = RSA_get_method(rsa);
    CAPI_DATA *cd = (CAPI_DATA *) RSA_meth_get0_app_data(rsa_meth);

    if (cd == NULL)
    {
        return 0;
    }
    if (cd->crypt_prov && cd->free_crypt_prov)
    {
        if (cd->key_spec == CERT_NCRYPT_KEY_SPEC)
        {
            NCryptFreeObject(cd->crypt_prov);
        }
        else
        {
            CryptReleaseContext(cd->crypt_prov, 0);
        }
    }
    if (cd->cert_context)
    {
        CertFreeCertificateContext(cd->cert_context);
    }
    free(cd);
    RSA_meth_free((RSA_METHOD*) rsa_meth);
    return 1;
}

static const CERT_CONTEXT *
find_certificate_in_store(const char *cert_prop, HCERTSTORE cert_store)
{
    /* Find, and use, the desired certificate from the store. The
     * 'cert_prop' certificate search string can look like this:
     * SUBJ:<certificate substring to match>
     * THUMB:<certificate thumbprint hex value>, e.g.
     *     THUMB:f6 49 24 41 01 b4 fb 44 0c ce f4 36 ae d0 c4 c9 df 7a b6 28
     * The first matching certificate that has not expired is returned.
     */
    const CERT_CONTEXT *rv = NULL;
    DWORD find_type;
    const void *find_param;
    unsigned char hash[255];
    CRYPT_HASH_BLOB blob = {.cbData = 0, .pbData = hash};
    struct gc_arena gc = gc_new();

    if (!strncmp(cert_prop, "SUBJ:", 5))
    {
        /* skip the tag */
        find_param = wide_string(cert_prop + 5, &gc);
        find_type = CERT_FIND_SUBJECT_STR_W;
    }
    else if (!strncmp(cert_prop, "THUMB:", 6))
    {
        const char *p;
        int i, x = 0;
        find_type = CERT_FIND_HASH;
        find_param = &blob;

        /* skip the tag */
        cert_prop += 6;
        for (p = cert_prop, i = 0; *p && i < sizeof(hash); i++)
        {
            if (*p >= '0' && *p <= '9')
            {
                x = (*p - '0') << 4;
            }
            else if (*p >= 'A' && *p <= 'F')
            {
                x = (*p - 'A' + 10) << 4;
            }
            else if (*p >= 'a' && *p <= 'f')
            {
                x = (*p - 'a' + 10) << 4;
            }
            if (!*++p)  /* unexpected end of string */
            {
                msg(M_WARN, "WARNING: cryptoapicert: error parsing <THUMB:%s>.", cert_prop);
                goto out;
            }
            if (*p >= '0' && *p <= '9')
            {
                x += *p - '0';
            }
            else if (*p >= 'A' && *p <= 'F')
            {
                x += *p - 'A' + 10;
            }
            else if (*p >= 'a' && *p <= 'f')
            {
                x += *p - 'a' + 10;
            }
            hash[i] = x;
            /* skip any space(s) between hex numbers */
            for (p++; *p && *p == ' '; p++)
            {
            }
        }
        blob.cbData = i;
    }
    else
    {
        msg(M_WARN, "WARNING: cryptoapicert: unsupported certificate specification <%s>", cert_prop);
        goto out;
    }

    while(true)
    {
        int validity = 1;
        /* this frees previous rv, if not NULL */
        rv = CertFindCertificateInStore(cert_store, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
                                        0, find_type, find_param, rv);
        if (rv)
        {
            validity = CertVerifyTimeValidity(NULL, rv->pCertInfo);
        }
        if (!rv || validity == 0)
        {
            break;
        }
        msg(M_WARN, "WARNING: cryptoapicert: ignoring certificate in store %s.",
            validity < 0 ? "not yet valid" : "that has expired");
    }

out:
    gc_free(&gc);
    return rv;
}

#if (OPENSSL_VERSION_NUMBER >= 0x10100000L)

static const CAPI_DATA *
retrieve_capi_data(EVP_PKEY *pkey)
{
    const CAPI_DATA *cd = NULL;

    if (pkey && EVP_PKEY_id(pkey) == EVP_PKEY_RSA)
    {
        RSA *rsa = EVP_PKEY_get0_RSA(pkey);
        if (rsa)
        {
            cd = (CAPI_DATA *)RSA_meth_get0_app_data(RSA_get_method(rsa));
        }
    }
    return cd;
}

static int
pkey_rsa_sign_init(EVP_PKEY_CTX *ctx)
{
    EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx);

    if (pkey && retrieve_capi_data(pkey))
    {
        return 1; /* Return success */
    }
    else if (default_pkey_sign_init)  /* Not our key. Call the default method */
    {
        return default_pkey_sign_init(ctx);
    }
    return 1;
}

/**
 * Implementation of EVP_PKEY_sign() using CNG: sign the digest in |tbs|
 * and save the the signature in |sig| and its size in |*siglen|.
 * If |sig| is NULL the required buffer size is returned in |*siglen|.
 * Returns 1 on success, 0 or a negative integer on error.
 */
static int
pkey_rsa_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
              const unsigned char *tbs, size_t tbslen)
{
    EVP_PKEY *pkey = NULL;
    const CAPI_DATA *cd = NULL;
    EVP_MD *md = NULL;
    const wchar_t *alg = NULL;

    int padding;
    int hashlen;
    int saltlen;

    pkey = EVP_PKEY_CTX_get0_pkey(ctx);
    if (pkey)
    {
        cd = retrieve_capi_data(pkey);
    }

    /*
     * We intercept all sign requests, not just the one's for our key.
     * Check the key and call the saved OpenSSL method for unknown keys.
     */
    if (!pkey || !cd)
    {
        if (default_pkey_sign)
        {
            return default_pkey_sign(ctx, sig, siglen, tbs, tbslen);
        }
        else  /* This should not happen */
        {
            msg(M_FATAL, "cryptopaicert: Unknown key and no default sign operation to fallback on");
            return -1;
        }
    }

    if (!EVP_PKEY_CTX_get_rsa_padding(ctx, &padding))
    {
        padding = RSA_PKCS1_PADDING; /* Default padding for RSA */
    }

    if (EVP_PKEY_CTX_get_signature_md(ctx, &md))
    {
        hashlen = EVP_MD_size(md);
        alg = cng_hash_algo(EVP_MD_type(md));

        /*
         * alg == NULL indicates legacy MD5+SHA1 hash, else alg should be a valid
         * digest algorithm.
         */
        if (alg && wcscmp(alg, L"UNKNOWN") == 0)
        {
            RSAerr(RSA_F_PKEY_RSA_SIGN, RSA_R_UNKNOWN_ALGORITHM_TYPE);
            return -1;
        }
    }
    else
    {
        msg(M_NONFATAL, "cryptoapicert: could not determine the signature digest algorithm");
        RSAerr(RSA_F_PKEY_RSA_SIGN, RSA_R_UNKNOWN_ALGORITHM_TYPE);
        return -1;
    }

    if (tbslen != (size_t)hashlen)
    {
        RSAerr(RSA_F_PKEY_RSA_SIGN, RSA_R_INVALID_DIGEST_LENGTH);
        return -1;
    }

    /* If padding is PSS, determine parameters to pass to CNG */
    if (padding == RSA_PKCS1_PSS_PADDING)
    {
        /*
         * Ensure the digest type for signature and mask generation match.
         * In CNG there is no option to specify separate hash functions for
         * the two, but OpenSSL supports it. However, I have not seen the
         * two being different in practice. Also the recommended practice is
         * to use the same for both (rfc 8017 sec 8.1).
         */
        EVP_MD *mgf1md;
        if (!EVP_PKEY_CTX_get_rsa_mgf1_md(ctx, &mgf1md)
            || EVP_MD_type(mgf1md) != EVP_MD_type(md))
        {
            msg(M_NONFATAL, "cryptoapicert: Unknown MGF1 digest type or does"
                " not match the signature digest type.");
            RSAerr(RSA_F_PKEY_RSA_SIGN, RSA_R_UNSUPPORTED_MASK_PARAMETER);
        }

        if (!EVP_PKEY_CTX_get_rsa_pss_saltlen(ctx, &saltlen))
        {
            msg(M_WARN|M_INFO, "cryptoapicert: unable to get the salt length from context."
                " Using the default value.");
            saltlen = -1;
        }

        /*
         * In OpenSSL saltlen = -1 indicates to use the size of the digest as
         * size of the salt. A value of -2 or -3 indicates maximum salt length
         * that will fit. See RSA_padding_add_PKCS1_PSS_mgf1() of OpenSSL.
         */
        if (saltlen == -1)
        {
            saltlen = hashlen;
        }
        else if (saltlen < 0)
        {
            const RSA *rsa = EVP_PKEY_get0_RSA(pkey);
            saltlen = RSA_size(rsa) - hashlen - 2; /* max salt length for RSASSA-PSS */
            if (RSA_bits(rsa) &0x7) /* number of bits in the key not a multiple of 8 */
            {
                saltlen--;
            }
        }

        if (saltlen < 0)
        {
            RSAerr(RSA_F_PKEY_RSA_SIGN, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
            return -1;
        }
        msg(D_LOW, "cryptoapicert: PSS padding using saltlen = %d", saltlen);
    }

    *siglen = priv_enc_CNG(cd, alg, tbs, (int)tbslen, sig, *siglen,
                           cng_padding_type(padding), (DWORD)saltlen);

    return (*siglen == 0) ? 0 : 1;
}

#endif /* OPENSSL_VERSION >= 1.1.0 */

int
SSL_CTX_use_CryptoAPI_certificate(SSL_CTX *ssl_ctx, const char *cert_prop)
{
    HCERTSTORE cs;
    X509 *cert = NULL;
    RSA *rsa = NULL, *pub_rsa;
    CAPI_DATA *cd = calloc(1, sizeof(*cd));
    RSA_METHOD *my_rsa_method = NULL;

    if (cd == NULL)
    {
        SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, ERR_R_MALLOC_FAILURE);
        goto err;
    }
    /* search CURRENT_USER first, then LOCAL_MACHINE */
    cs = CertOpenStore((LPCSTR) CERT_STORE_PROV_SYSTEM, 0, 0, CERT_SYSTEM_STORE_CURRENT_USER
                       |CERT_STORE_OPEN_EXISTING_FLAG | CERT_STORE_READONLY_FLAG, L"MY");
    if (cs == NULL)
    {
        CRYPTOAPIerr(CRYPTOAPI_F_CERT_OPEN_SYSTEM_STORE);
        goto err;
    }
    cd->cert_context = find_certificate_in_store(cert_prop, cs);
    CertCloseStore(cs, 0);
    if (!cd->cert_context)
    {
        cs = CertOpenStore((LPCSTR) CERT_STORE_PROV_SYSTEM, 0, 0, CERT_SYSTEM_STORE_LOCAL_MACHINE
                           |CERT_STORE_OPEN_EXISTING_FLAG | CERT_STORE_READONLY_FLAG, L"MY");
        if (cs == NULL)
        {
            CRYPTOAPIerr(CRYPTOAPI_F_CERT_OPEN_SYSTEM_STORE);
            goto err;
        }
        cd->cert_context = find_certificate_in_store(cert_prop, cs);
        CertCloseStore(cs, 0);
        if (cd->cert_context == NULL)
        {
            CRYPTOAPIerr(CRYPTOAPI_F_CERT_FIND_CERTIFICATE_IN_STORE);
            goto err;
        }
    }

    /* cert_context->pbCertEncoded is the cert X509 DER encoded. */
    cert = d2i_X509(NULL, (const unsigned char **) &cd->cert_context->pbCertEncoded,
                    cd->cert_context->cbCertEncoded);
    if (cert == NULL)
    {
        SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, ERR_R_ASN1_LIB);
        goto err;
    }

    /* set up stuff to use the private key */
    /* We prefer to get an NCRYPT key handle so that TLS1.2 can be supported */
    DWORD flags = CRYPT_ACQUIRE_COMPARE_KEY_FLAG
                  | CRYPT_ACQUIRE_PREFER_NCRYPT_KEY_FLAG;
    if (!CryptAcquireCertificatePrivateKey(cd->cert_context, flags, NULL,
                    &cd->crypt_prov, &cd->key_spec, &cd->free_crypt_prov))
    {
        /* if we don't have a smart card reader here, and we try to access a
         * smart card certificate, we get:
         * "Error 1223: The operation was canceled by the user." */
        CRYPTOAPIerr(CRYPTOAPI_F_CRYPT_ACQUIRE_CERTIFICATE_PRIVATE_KEY);
        goto err;
    }
    /* here we don't need to do CryptGetUserKey() or anything; all necessary key
     * info is in cd->cert_context, and then, in cd->crypt_prov.  */

    /* if we do not have an NCRYPT key handle restrict TLS to v1.1 or lower */
    int max_version = SSL_CTX_get_max_proto_version(ssl_ctx);
    if ((!max_version || max_version > TLS1_1_VERSION)
        && cd->key_spec != CERT_NCRYPT_KEY_SPEC)
    {
        msg(M_WARN, "WARNING: cryptoapicert: private key is in a legacy store."
            " Restricting TLS version to 1.1");
        if (SSL_CTX_get_min_proto_version(ssl_ctx) > TLS1_1_VERSION)
        {
            msg(M_NONFATAL,
                "ERROR: cryptoapicert: min TLS version larger than 1.1."
                " Try config option --tls-version-min 1.1");
            goto err;
        }
        if (!SSL_CTX_set_max_proto_version(ssl_ctx, TLS1_1_VERSION))
        {
            msg(M_NONFATAL, "ERROR: cryptoapicert: set max TLS version failed");
            goto err;
        }
    }

    my_rsa_method = RSA_meth_new("Microsoft Cryptography API RSA Method",
                                  RSA_METHOD_FLAG_NO_CHECK);
    check_malloc_return(my_rsa_method);
    RSA_meth_set_pub_enc(my_rsa_method, rsa_pub_enc);
    RSA_meth_set_pub_dec(my_rsa_method, rsa_pub_dec);
    RSA_meth_set_priv_enc(my_rsa_method, rsa_priv_enc);
    RSA_meth_set_priv_dec(my_rsa_method, rsa_priv_dec);
    RSA_meth_set_init(my_rsa_method, NULL);
    RSA_meth_set_finish(my_rsa_method, finish);
    RSA_meth_set0_app_data(my_rsa_method, cd);

    /* For CNG, set the RSA_sign method which gets priority over priv_enc().
     * This method is called with the raw hash without the digestinfo
     * header and works better when using NCryptSignHash() with some tokens.
     * However, if PSS padding is in use, openssl does not call this
     * function but adds the padding and then calls rsa_priv_enc()
     * with padding set to NONE which is not supported by CNG.
     * So, when posisble (OpenSSL 1.1.0 and up), we hook on to the sign
     * operation in EVP_PKEY_METHOD struct.
     */
    if (cd->key_spec == CERT_NCRYPT_KEY_SPEC)
    {
#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
        RSA_meth_set_sign(my_rsa_method, rsa_sign_CNG);
#else
        /* pmethod is global -- initialize only if NULL */
        if (!pmethod)
        {
            pmethod = EVP_PKEY_meth_new(EVP_PKEY_RSA, 0);
            if (!pmethod)
            {
                SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, ERR_R_MALLOC_FAILURE);
                goto err;
            }
            const EVP_PKEY_METHOD *default_pmethod = EVP_PKEY_meth_find(EVP_PKEY_RSA);
            EVP_PKEY_meth_copy(pmethod, default_pmethod);

            /* We want to override only sign_init() and sign() */
            EVP_PKEY_meth_set_sign(pmethod, pkey_rsa_sign_init, pkey_rsa_sign);
            EVP_PKEY_meth_add0(pmethod);

            /* Keep a copy of the default sign and sign_init methods */

#if (OPENSSL_VERSION_NUMBER < 0x1010009fL)   /* < version 1.1.0i */
            /* The function signature is not const-correct in these versions */
            EVP_PKEY_meth_get_sign((EVP_PKEY_METHOD *)default_pmethod, &default_pkey_sign_init,
                                   &default_pkey_sign);
#else
            EVP_PKEY_meth_get_sign(default_pmethod, &default_pkey_sign_init,
                                   &default_pkey_sign);
#endif
        }
#endif /* (OPENSSL_VERSION_NUMBER < 0x10100000L) */
    }

    rsa = RSA_new();
    if (rsa == NULL)
    {
        SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, ERR_R_MALLOC_FAILURE);
        goto err;
    }

    /* Public key in cert is NULL until we call SSL_CTX_use_certificate(),
     * so we do it here then...  */
    if (!SSL_CTX_use_certificate(ssl_ctx, cert))
    {
        goto err;
    }
    /* the public key */
    EVP_PKEY *pkey = X509_get0_pubkey(cert);

    /* SSL_CTX_use_certificate() increased the reference count in 'cert', so
     * we decrease it here with X509_free(), or it will never be cleaned up. */
    X509_free(cert);
    cert = NULL;

    if (!(pub_rsa = EVP_PKEY_get0_RSA(pkey)))
    {
        msg(M_WARN, "cryptoapicert requires an RSA certificate");
        goto err;
    }

    /* Our private key is external, so we fill in only n and e from the public key */
    const BIGNUM *n = NULL;
    const BIGNUM *e = NULL;
    RSA_get0_key(pub_rsa, &n, &e, NULL);
    if (!RSA_set0_key(rsa, BN_dup(n), BN_dup(e), NULL))
    {
        goto err;
    }
    RSA_set_flags(rsa, RSA_flags(rsa) | RSA_FLAG_EXT_PKEY);
    if (!RSA_set_method(rsa, my_rsa_method))
    {
        goto err;
    }

    if (!SSL_CTX_use_RSAPrivateKey(ssl_ctx, rsa))
    {
        goto err;
    }
    /* SSL_CTX_use_RSAPrivateKey() increased the reference count in 'rsa', so
    * we decrease it here with RSA_free(), or it will never be cleaned up. */
    RSA_free(rsa);
    return 1;

err:
    if (cert)
    {
        X509_free(cert);
    }
    if (rsa)
    {
        RSA_free(rsa);
    }
    else
    {
        if (my_rsa_method)
        {
            free(my_rsa_method);
        }
        if (cd)
        {
            if (cd->free_crypt_prov && cd->crypt_prov)
            {
                if (cd->key_spec == CERT_NCRYPT_KEY_SPEC)
                {
                    NCryptFreeObject(cd->crypt_prov);
                }
                else
                {
                    CryptReleaseContext(cd->crypt_prov, 0);
                }
            }
            if (cd->cert_context)
            {
                CertFreeCertificateContext(cd->cert_context);
            }
            free(cd);
        }
    }
    return 0;
}

#else  /* ifdef ENABLE_CRYPTOAPI */
#ifdef _MSC_VER  /* Dummy function needed to avoid empty file compiler warning in Microsoft VC */
static void
dummy(void)
{
}
#endif
#endif                          /* _WIN32 */
