From df0731d81c9fe1a14903b29c31efb2bbf88ecc1b Mon Sep 17 00:00:00 2001 From: joe Date: Mon, 26 Sep 2016 21:07:28 +0000 Subject: * src/ne_pkcs11.c: Create RSA_METHOD once per provider, rather than dynamically. Add OpenSSL 1.1.0 compatibility. (pk11_rsa_finish): Remove. (pk11_init): Create RSA_METHOD here, ... (ne_ssl_pkcs11_provider_destroy): ... destroy it here. git-svn-id: http://svn.webdav.org/repos/projects/neon/trunk@1974 61a7d7f5-40b7-0310-9c16-bb0ea8cb1845 --- src/ne_pkcs11.c | 70 ++++++++++++++++++++++++++++++++------------------------- 1 file changed, 39 insertions(+), 31 deletions(-) diff --git a/src/ne_pkcs11.c b/src/ne_pkcs11.c index daec1ce..a388e7e 100644 --- a/src/ne_pkcs11.c +++ b/src/ne_pkcs11.c @@ -40,6 +40,9 @@ struct ne_ssl_pkcs11_provider_s { ne_ssl_client_cert *clicert; ck_object_handle_t privkey; ck_key_type_t keytype; +#ifdef HAVE_OPENSSL + RSA_METHOD *method; +#endif }; /* To do list for PKCS#11 support: @@ -69,14 +72,37 @@ struct ne_ssl_pkcs11_provider_s { #include #include +#if defined(RSA_F_RSA_PRIVATE_ENCRYPT) +#define PK11_RSA_ERR (RSA_F_RSA_PRIVATE_ENCRYPT) +#else #define PK11_RSA_ERR (RSA_F_RSA_EAY_PRIVATE_ENCRYPT) +#endif + +#if OPENSSL_VERSION_NUMBER < 0x10100000L +/* Compatibility functions for OpenSSL < 1.1.0: */ +#define RSA_meth_get0_app_data(rsa) (void *)(rsa->app_data) +static RSA_METHOD *RSA_meth_new(const char *name, int flags) +{ + RSA_METHOD *m = ne_calloc(sizeof *m); + + m->name = name; + m->flags = flags; + + return m; + +} +#define RSA_meth_free ne_free +#define RSA_meth_set_priv_enc(m, f) (m)->rsa_priv_enc = (f) +#define RSA_meth_set0_app_data(m, f) (m)->app_data = (void *)(f) +#endif /* RSA_METHOD ->rsa_private_encrypt calback. */ static int pk11_rsa_encrypt(int mlen, const unsigned char *m, unsigned char *sigret, RSA *r, int padding) { - ne_ssl_pkcs11_provider *prov = (ne_ssl_pkcs11_provider *)r->meth->app_data; + const RSA_METHOD *method = RSA_get_method(r); + ne_ssl_pkcs11_provider *prov = RSA_meth_get0_app_data(method); ck_rv_t rv; struct ck_mechanism mech; unsigned long len; @@ -118,41 +144,16 @@ static int pk11_rsa_encrypt(int mlen, const unsigned char *m, return len; } -/* RSA_METHOD ->rsa_finish implementation; called during - * RSA_free(rsa). */ -static int pk11_rsa_finish(RSA *rsa) -{ - RSA_METHOD *meth = (RSA_METHOD *)rsa->meth; - - /* Freeing the dynamically allocated method here works as well as - * doing anything else: */ - ne_free(meth); - /* Does not appear that rsa->meth will be used after this, but in - * case it is, ensure a NULL pointer dereference rather than a - * random pointer dereference. */ - rsa->meth = NULL; - - return 0; -} - /* Return an RSA_METHOD which will use the PKCS#11 provider to * implement the signing operation. */ static RSA_METHOD *pk11_rsa_method(ne_ssl_pkcs11_provider *prov) { - RSA_METHOD *m = ne_calloc(sizeof *m); + RSA_METHOD *m = RSA_meth_new("neon PKCS#11", RSA_METHOD_FLAG_NO_CHECK); - m->name = "neon PKCS#11"; - m->rsa_priv_enc = pk11_rsa_encrypt; - - m->finish = pk11_rsa_finish; - - /* This is hopefully under complete control of the RSA_METHOD, - * otherwise there is nowhere to put this. */ - m->app_data = (char *)prov; + RSA_meth_set_priv_enc(m, pk11_rsa_encrypt); + RSA_meth_set0_app_data(m, prov); - m->flags = RSA_METHOD_FLAG_NO_CHECK; - - return m; + return m; } #endif @@ -212,7 +213,7 @@ static int pk11_find_x509(ne_ssl_pkcs11_provider *prov, #ifdef HAVE_GNUTLS cc = ne__ssl_clicert_exkey_import(value, a[0].value_len, pk11_sign_callback, prov); #else - cc = ne__ssl_clicert_exkey_import(value, a[0].value_len, pk11_rsa_method(prov)); + cc = ne__ssl_clicert_exkey_import(value, a[0].value_len, prov->method); #endif if (cc) { NE_DEBUG(NE_DBG_SSL, "pk11: Imported X.509 cert.\n"); @@ -532,6 +533,10 @@ static int pk11_init(ne_ssl_pkcs11_provider **provider, prov->module = module; prov->privkey = CK_INVALID_HANDLE; +#ifdef HAVE_OPENSSL + prov->method = pk11_rsa_method(prov); +#endif + return NE_PK11_OK; } @@ -588,6 +593,9 @@ void ne_ssl_pkcs11_provider_destroy(ne_ssl_pkcs11_provider *prov) ne_ssl_clicert_free(prov->clicert); } pakchois_module_destroy(prov->module); +#ifdef HAVE_OPENSSL + RSA_meth_free(prov->method); +#endif ne_free(prov); } -- cgit v1.2.1