summaryrefslogtreecommitdiff
path: root/ssh-pkcs11.c
diff options
context:
space:
mode:
authordjm@openbsd.org <djm@openbsd.org>2019-01-20 23:10:33 +0000
committerDamien Miller <djm@mindrot.org>2019-01-21 10:57:03 +1100
commit58622a8c82f4e2aad630580543f51ba537c1f39e (patch)
tree544e597d8edee42899f55bcd79cb345290a3529c /ssh-pkcs11.c
parentf118542fc82a3b3ab0360955b33bc5a271ea709f (diff)
upstream: use OpenSSL's RSA reference counting hooks to
implicitly clean up pkcs11_key objects when their owning RSA object's reference count drops to zero. Simplifies the cleanup path and makes it more like ECDSA's work by markus@, ok djm@ OpenBSD-Commit-ID: 74b9c98f405cd78f7148e9e4a4982336cd3df25c
Diffstat (limited to 'ssh-pkcs11.c')
-rw-r--r--ssh-pkcs11.c56
1 files changed, 21 insertions, 35 deletions
diff --git a/ssh-pkcs11.c b/ssh-pkcs11.c
index d7b3a65f0..b8f2a3a4e 100644
--- a/ssh-pkcs11.c
+++ b/ssh-pkcs11.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh-pkcs11.c,v 1.33 2019/01/20 23:08:24 djm Exp $ */ 1/* $OpenBSD: ssh-pkcs11.c,v 1.34 2019/01/20 23:10:33 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2010 Markus Friedl. All rights reserved. 3 * Copyright (c) 2010 Markus Friedl. All rights reserved.
4 * Copyright (c) 2014 Pedro Martelletto. All rights reserved. 4 * Copyright (c) 2014 Pedro Martelletto. All rights reserved.
@@ -72,7 +72,6 @@ TAILQ_HEAD(, pkcs11_provider) pkcs11_providers;
72struct pkcs11_key { 72struct pkcs11_key {
73 struct pkcs11_provider *provider; 73 struct pkcs11_provider *provider;
74 CK_ULONG slotidx; 74 CK_ULONG slotidx;
75 int (*orig_finish)(RSA *rsa);
76 RSA_METHOD *rsa_method; 75 RSA_METHOD *rsa_method;
77 EC_KEY_METHOD *ec_key_method; 76 EC_KEY_METHOD *ec_key_method;
78 char *keyid; 77 char *keyid;
@@ -190,23 +189,20 @@ pkcs11_del_provider(char *provider_id)
190 return (-1); 189 return (-1);
191} 190}
192 191
193/* openssl callback for freeing an RSA key */ 192/* release a wrapped object */
194static int 193static void
195pkcs11_rsa_finish(RSA *rsa) 194pkcs11_k11_free(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx,
195 long argl, void *argp)
196{ 196{
197 struct pkcs11_key *k11; 197 struct pkcs11_key *k11 = ptr;
198 int rv = -1; 198
199 199 debug("%s: parent %p ptr %p idx %d", __func__, parent, ptr, idx);
200 if ((k11 = RSA_get_app_data(rsa)) != NULL) { 200 if (k11 == NULL)
201 if (k11->orig_finish) 201 return;
202 rv = k11->orig_finish(rsa); 202 if (k11->provider)
203 if (k11->provider) 203 pkcs11_provider_unref(k11->provider);
204 pkcs11_provider_unref(k11->provider); 204 free(k11->keyid);
205 RSA_meth_free(k11->rsa_method); 205 free(k11);
206 free(k11->keyid);
207 free(k11);
208 }
209 return (rv);
210} 206}
211 207
212/* find a single 'obj' for given attributes */ 208/* find a single 'obj' for given attributes */
@@ -366,6 +362,7 @@ pkcs11_rsa_private_decrypt(int flen, const u_char *from, u_char *to, RSA *rsa,
366} 362}
367 363
368static RSA_METHOD *rsa_method; 364static RSA_METHOD *rsa_method;
365static int rsa_idx = 0;
369 366
370static int 367static int
371pkcs11_rsa_start_wrapper(void) 368pkcs11_rsa_start_wrapper(void)
@@ -375,10 +372,13 @@ pkcs11_rsa_start_wrapper(void)
375 rsa_method = RSA_meth_dup(RSA_get_default_method()); 372 rsa_method = RSA_meth_dup(RSA_get_default_method());
376 if (rsa_method == NULL) 373 if (rsa_method == NULL)
377 return (-1); 374 return (-1);
375 rsa_idx = RSA_get_ex_new_index(0, "ssh-pkcs11-rsa",
376 NULL, NULL, pkcs11_k11_free);
377 if (rsa_idx == -1)
378 return (-1);
378 if (!RSA_meth_set1_name(rsa_method, "pkcs11") || 379 if (!RSA_meth_set1_name(rsa_method, "pkcs11") ||
379 !RSA_meth_set_priv_enc(rsa_method, pkcs11_rsa_private_encrypt) || 380 !RSA_meth_set_priv_enc(rsa_method, pkcs11_rsa_private_encrypt) ||
380 !RSA_meth_set_priv_dec(rsa_method, pkcs11_rsa_private_decrypt) || 381 !RSA_meth_set_priv_dec(rsa_method, pkcs11_rsa_private_decrypt)) {
381 !RSA_meth_set_finish(rsa_method, pkcs11_rsa_finish)) {
382 error("%s: setup pkcs11 method failed", __func__); 382 error("%s: setup pkcs11 method failed", __func__);
383 return (-1); 383 return (-1);
384 } 384 }
@@ -408,7 +408,7 @@ pkcs11_rsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx,
408 408
409 k11->rsa_method = rsa_method; 409 k11->rsa_method = rsa_method;
410 RSA_set_method(rsa, k11->rsa_method); 410 RSA_set_method(rsa, k11->rsa_method);
411 RSA_set_ex_data(rsa, 0, k11); 411 RSA_set_ex_data(rsa, rsa_idx, k11);
412 return (0); 412 return (0);
413} 413}
414 414
@@ -472,20 +472,6 @@ ecdsa_do_sign(const unsigned char *dgst, int dgst_len, const BIGNUM *inv,
472static EC_KEY_METHOD *ec_key_method; 472static EC_KEY_METHOD *ec_key_method;
473static int ec_key_idx = 0; 473static int ec_key_idx = 0;
474 474
475static void
476pkcs11_k11_free(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx,
477 long argl, void *argp)
478{
479 struct pkcs11_key *k11 = ptr;
480
481 if (k11 == NULL)
482 return;
483 if (k11->provider)
484 pkcs11_provider_unref(k11->provider);
485 free(k11->keyid);
486 free(k11);
487}
488
489static int 475static int
490pkcs11_ecdsa_start_wrapper(void) 476pkcs11_ecdsa_start_wrapper(void)
491{ 477{