Don't change _WIN32_WINNT and detect GetConsoleWindow() and
CryptUIDlgSelectCertificateFromStore() at runtime. Add callback function for selection mechanism.
This commit is contained in:
parent
11f3cee93b
commit
1cd504e7be
1 changed files with 39 additions and 16 deletions
|
@ -62,10 +62,6 @@
|
||||||
#ifdef OPENSSL_SYS_WIN32
|
#ifdef OPENSSL_SYS_WIN32
|
||||||
#ifndef OPENSSL_NO_CAPIENG
|
#ifndef OPENSSL_NO_CAPIENG
|
||||||
|
|
||||||
#if _WIN32_WINNT < 0x0500
|
|
||||||
#define _WIN32_WINNT 0x0500
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <wincrypt.h>
|
#include <wincrypt.h>
|
||||||
|
|
||||||
|
@ -94,7 +90,6 @@ static int capi_list_providers(CAPI_CTX *ctx, BIO *out);
|
||||||
static int capi_list_containers(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);
|
int capi_list_certs(CAPI_CTX *ctx, BIO *out, char *storename);
|
||||||
void capi_free_key(CAPI_KEY *key);
|
void capi_free_key(CAPI_KEY *key);
|
||||||
static int client_cert_select(ENGINE *e, SSL *ssl, STACK_OF(X509) *certs);
|
|
||||||
|
|
||||||
static PCCERT_CONTEXT capi_find_cert(CAPI_CTX *ctx, const char *id, HCERTSTORE hstore);
|
static PCCERT_CONTEXT capi_find_cert(CAPI_CTX *ctx, const char *id, HCERTSTORE hstore);
|
||||||
|
|
||||||
|
@ -117,7 +112,17 @@ static int capi_dsa_free(DSA *dsa);
|
||||||
static int capi_load_ssl_client_cert(ENGINE *e, SSL *ssl,
|
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_NAME) *ca_dn, X509 **pcert, EVP_PKEY **pkey,
|
||||||
STACK_OF(X509) **pother, UI_METHOD *ui_method, void *callback_data);
|
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:
|
/* This structure contains CAPI ENGINE specific data:
|
||||||
* it contains various global options and affects how
|
* it contains various global options and affects how
|
||||||
* other functions behave.
|
* other functions behave.
|
||||||
|
@ -160,6 +165,10 @@ struct CAPI_CTX_st {
|
||||||
#define CAPI_DMP_PKEYINFO 0x20
|
#define CAPI_DMP_PKEYINFO 0x20
|
||||||
|
|
||||||
DWORD dump_flags;
|
DWORD dump_flags;
|
||||||
|
int (*client_cert_select)(ENGINE *e, SSL *ssl, STACK_OF(X509) *certs);
|
||||||
|
|
||||||
|
CERTDLG certselectdlg;
|
||||||
|
GETCONSWIN getconswindow;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -393,6 +402,21 @@ static int capi_init(ENGINE *e)
|
||||||
capi_dsa_method.dsa_mod_exp = ossl_dsa_meth->dsa_mod_exp;
|
capi_dsa_method.dsa_mod_exp = ossl_dsa_meth->dsa_mod_exp;
|
||||||
capi_dsa_method.bn_mod_exp = ossl_dsa_meth->bn_mod_exp;
|
capi_dsa_method.bn_mod_exp = ossl_dsa_meth->bn_mod_exp;
|
||||||
|
|
||||||
|
#ifdef OPENSSL_CAPIENG_DIALOG
|
||||||
|
{
|
||||||
|
HMODULE cryptui = LoadLibrary(TEXT("CRYPTUI.DLL"));
|
||||||
|
HMODULE kernel = LoadLibrary(TEXT("KERNEL32.DLL"));
|
||||||
|
if (cryptui)
|
||||||
|
ctx->certselectdlg = (CERTDLG)GetProcAddress(cryptui, "CryptUIDlgSelectCertificateFromStore");
|
||||||
|
if (kernel)
|
||||||
|
ctx->getconswindow = (GETCONSWIN)GetProcAddress(kernel, "GetConsoleWindow");
|
||||||
|
if (cryptui)
|
||||||
|
// if (cryptui && !OPENSSL_isservice())
|
||||||
|
ctx->client_cert_select = cert_select_dialog;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
memerr:
|
memerr:
|
||||||
|
@ -1434,6 +1458,7 @@ static CAPI_CTX *capi_ctx_new()
|
||||||
ctx->lookup_method = CAPI_LU_SUBSTR;
|
ctx->lookup_method = CAPI_LU_SUBSTR;
|
||||||
ctx->debug_level = 0;
|
ctx->debug_level = 0;
|
||||||
ctx->debug_file = NULL;
|
ctx->debug_file = NULL;
|
||||||
|
ctx->client_cert_select = cert_select_simple;
|
||||||
return ctx;
|
return ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1571,7 +1596,7 @@ static int capi_load_ssl_client_cert(ENGINE *e, SSL *ssl,
|
||||||
|
|
||||||
/* Select the appropriate certificate */
|
/* Select the appropriate certificate */
|
||||||
|
|
||||||
client_cert_idx = client_cert_select(e, ssl, certs);
|
client_cert_idx = ctx->client_cert_select(e, ssl, certs);
|
||||||
|
|
||||||
/* Set the selected certificate and free the rest */
|
/* Set the selected certificate and free the rest */
|
||||||
|
|
||||||
|
@ -1603,16 +1628,15 @@ static int capi_load_ssl_client_cert(ENGINE *e, SSL *ssl,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef OPENSSL_CAPIENG_DIALOG
|
|
||||||
|
|
||||||
/* Simple client cert selection function: always select first */
|
/* Simple client cert selection function: always select first */
|
||||||
|
|
||||||
static int client_cert_select(ENGINE *e, SSL *ssl, STACK_OF(X509) *certs)
|
static int cert_select_simple(ENGINE *e, SSL *ssl, STACK_OF(X509) *certs)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#ifdef OPENSSL_CAPIENG_DIALOG
|
||||||
|
|
||||||
/* More complex cert selection function, using standard function
|
/* More complex cert selection function, using standard function
|
||||||
* CryptUIDlgSelectCertificateFromStore() to produce a dialog box.
|
* CryptUIDlgSelectCertificateFromStore() to produce a dialog box.
|
||||||
|
@ -1626,7 +1650,7 @@ static int client_cert_select(ENGINE *e, SSL *ssl, STACK_OF(X509) *certs)
|
||||||
#define dlg_columns CRYPTUI_SELECT_LOCATION_COLUMN \
|
#define dlg_columns CRYPTUI_SELECT_LOCATION_COLUMN \
|
||||||
|CRYPTUI_SELECT_INTENDEDUSE_COLUMN
|
|CRYPTUI_SELECT_INTENDEDUSE_COLUMN
|
||||||
|
|
||||||
static int client_cert_select(ENGINE *e, SSL *ssl, STACK_OF(X509) *certs)
|
static int cert_select_dialog(ENGINE *e, SSL *ssl, STACK_OF(X509) *certs)
|
||||||
{
|
{
|
||||||
X509 *x;
|
X509 *x;
|
||||||
HCERTSTORE dstore;
|
HCERTSTORE dstore;
|
||||||
|
@ -1663,12 +1687,11 @@ static int client_cert_select(ENGINE *e, SSL *ssl, STACK_OF(X509) *certs)
|
||||||
|
|
||||||
}
|
}
|
||||||
hwnd = GetActiveWindow();
|
hwnd = GetActiveWindow();
|
||||||
if (!hwnd)
|
if (!hwnd && ctx->getconswindow)
|
||||||
hwnd = GetConsoleWindow();
|
hwnd = ctx->getconswindow();
|
||||||
/* Call dialog to select one */
|
/* Call dialog to select one */
|
||||||
cert = CryptUIDlgSelectCertificateFromStore(dstore, hwnd,
|
cert = ctx->certselectdlg(dstore, hwnd, dlg_title, dlg_prompt,
|
||||||
dlg_title, dlg_prompt,
|
dlg_columns, 0, NULL);
|
||||||
dlg_columns, 0, NULL);
|
|
||||||
|
|
||||||
/* Find matching cert from list */
|
/* Find matching cert from list */
|
||||||
if (cert)
|
if (cert)
|
||||||
|
|
Loading…
Reference in a new issue