summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjoe <joe@61a7d7f5-40b7-0310-9c16-bb0ea8cb1845>2016-09-26 21:07:28 +0000
committerjoe <joe@61a7d7f5-40b7-0310-9c16-bb0ea8cb1845>2016-09-26 21:07:28 +0000
commitdf0731d81c9fe1a14903b29c31efb2bbf88ecc1b (patch)
tree61600f7cf5e256ec903ad79f0add7c04cd69ca70
parent40fa0058108fcd54374d4bbc3f1c9b44afa9a435 (diff)
downloadneon-df0731d81c9fe1a14903b29c31efb2bbf88ecc1b.tar.gz
* 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
-rw-r--r--src/ne_pkcs11.c70
1 files 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 <openssl/rsa.h>
#include <openssl/err.h>
+#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);
}