提交 7d537d4f 编写于 作者: D Dr. Stephen Henson

Add initial support for multiple SSL client certifcate selection in

CryptoAPI ENGINE.
上级 ca89fc1f
...@@ -238,6 +238,7 @@ static const ENGINE_CMD_DEFN capi_cmd_defns[] = { ...@@ -238,6 +238,7 @@ static const ENGINE_CMD_DEFN capi_cmd_defns[] = {
static int capi_idx = -1; static int capi_idx = -1;
static int rsa_capi_idx = -1; static int rsa_capi_idx = -1;
static int dsa_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)) static int capi_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
{ {
...@@ -365,6 +366,7 @@ static int capi_init(ENGINE *e) ...@@ -365,6 +366,7 @@ static int capi_init(ENGINE *e)
const RSA_METHOD *ossl_rsa_meth; const RSA_METHOD *ossl_rsa_meth;
const DSA_METHOD *ossl_dsa_meth; const DSA_METHOD *ossl_dsa_meth;
capi_idx = ENGINE_get_ex_new_index(0, NULL, NULL, NULL, 0); capi_idx = ENGINE_get_ex_new_index(0, NULL, NULL, NULL, 0);
cert_capi_idx = X509_get_ex_new_index(0, NULL, NULL, NULL, 0);
ctx = capi_ctx_new(); ctx = capi_ctx_new();
if (!ctx || (capi_idx < 0)) if (!ctx || (capi_idx < 0))
...@@ -418,6 +420,8 @@ static int capi_finish(ENGINE *e) ...@@ -418,6 +420,8 @@ static int capi_finish(ENGINE *e)
struct CAPI_KEY_st struct CAPI_KEY_st
{ {
/* Associated certificate context (if any) */
PCERT_CONTEXT pcert;
HCRYPTPROV hprov; HCRYPTPROV hprov;
HCRYPTKEY key; HCRYPTKEY key;
DWORD keyspec; DWORD keyspec;
...@@ -1329,6 +1333,7 @@ static CAPI_KEY *capi_get_key(CAPI_CTX *ctx, const char *contname, char *provnam ...@@ -1329,6 +1333,7 @@ static CAPI_KEY *capi_get_key(CAPI_CTX *ctx, const char *contname, char *provnam
goto err; goto err;
} }
key->keyspec = keyspec; key->keyspec = keyspec;
key->pcert = NULL;
return key; return key;
err: err:
...@@ -1398,6 +1403,8 @@ void capi_free_key(CAPI_KEY *key) ...@@ -1398,6 +1403,8 @@ void capi_free_key(CAPI_KEY *key)
return; return;
CryptDestroyKey(key->key); CryptDestroyKey(key->key);
CryptReleaseContext(key->hprov, 0); CryptReleaseContext(key->hprov, 0);
if (key->pcert)
CertFreeCertificateContext(key->pcert);
OPENSSL_free(key); OPENSSL_free(key);
} }
...@@ -1486,23 +1493,25 @@ static int cert_issuer_match(STACK_OF(X509_NAME) *ca_dn, X509 *x) ...@@ -1486,23 +1493,25 @@ static int cert_issuer_match(STACK_OF(X509_NAME) *ca_dn, X509 *x)
return 0; return 0;
} }
static int client_cert_select(ENGINE *e, SSL *ssl, STACK_OF(X509) *certs)
{
fprintf(stderr, "%d certificates\n", sk_X509_num(certs));
return 0;
}
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)
{ {
#if 0
/* For now just one matching key/cert */
STACK_OF(X509) *certs = NULL; STACK_OF(X509) *certs = NULL;
STACK_OF(EVP_PKEY) *keys = NULL;
#endif
X509 *x; X509 *x;
EVP_PKEY *pk;
char *storename; char *storename;
const char *p; const char *p;
int i; int i, client_cert_idx;
HCERTSTORE hstore; HCERTSTORE hstore;
PCCERT_CONTEXT cert = NULL; PCCERT_CONTEXT cert = NULL, excert = NULL;
CAPI_CTX *ctx; CAPI_CTX *ctx;
CAPI_KEY *key;
ctx = ENGINE_get_ex_data(e, capi_idx); ctx = ENGINE_get_ex_data(e, capi_idx);
*pcert = NULL; *pcert = NULL;
...@@ -1516,7 +1525,7 @@ static int capi_load_ssl_client_cert(ENGINE *e, SSL *ssl, ...@@ -1516,7 +1525,7 @@ static int capi_load_ssl_client_cert(ENGINE *e, SSL *ssl,
if (!hstore) if (!hstore)
return 0; return 0;
/* Enumerate all certificates looking for a match */ /* Enumerate all certificates looking for a match */
for(i = 0;!*pcert;i++) for(i = 0;;i++)
{ {
cert = CertEnumCertificatesInStore(hstore, cert); cert = CertEnumCertificatesInStore(hstore, cert);
if (!cert) if (!cert)
...@@ -1530,9 +1539,17 @@ static int capi_load_ssl_client_cert(ENGINE *e, SSL *ssl, ...@@ -1530,9 +1539,17 @@ static int capi_load_ssl_client_cert(ENGINE *e, SSL *ssl,
} }
if (cert_issuer_match(ca_dn, x)) if (cert_issuer_match(ca_dn, x))
{ {
CAPI_KEY *key = capi_get_cert_key(ctx, cert); key = capi_get_cert_key(ctx, cert);
if (!key) if (!key)
continue; continue;
excert = CertDuplicateCertificateContext(cert);
X509_set_ex_data(x, cert_capi_idx, key);
if (!certs)
certs = sk_X509_new_null();
sk_X509_push(certs, x);
#if 0
pk = capi_get_pkey(e, key); pk = capi_get_pkey(e, key);
if (!pk) if (!pk)
{ {
...@@ -1541,6 +1558,7 @@ static int capi_load_ssl_client_cert(ENGINE *e, SSL *ssl, ...@@ -1541,6 +1558,7 @@ static int capi_load_ssl_client_cert(ENGINE *e, SSL *ssl,
} }
*pcert = x; *pcert = x;
*pkey = pk; *pkey = pk;
#endif
} }
else else
X509_free(x); X509_free(x);
...@@ -1550,11 +1568,35 @@ static int capi_load_ssl_client_cert(ENGINE *e, SSL *ssl, ...@@ -1550,11 +1568,35 @@ static int capi_load_ssl_client_cert(ENGINE *e, SSL *ssl,
if (cert) if (cert)
CertFreeCertificateContext(cert); CertFreeCertificateContext(cert);
if (*pcert) if (!certs)
return 1;
else
return 0; return 0;
client_cert_idx = client_cert_select(e, ssl, certs);
for(i = 0; i < sk_X509_num(certs); i++)
{
x = sk_X509_value(certs, i);
if (i == client_cert_idx)
*pcert = x;
else
{
key = X509_get_ex_data(x, cert_capi_idx);
capi_free_key(key);
X509_free(x);
}
}
sk_X509_free(certs);
if (!*pcert)
return 0;
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;
} }
#endif #endif
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册