summaryrefslogtreecommitdiff
path: root/ssh-pkcs11.c
diff options
context:
space:
mode:
Diffstat (limited to 'ssh-pkcs11.c')
-rw-r--r--ssh-pkcs11.c56
1 files changed, 41 insertions, 15 deletions
diff --git a/ssh-pkcs11.c b/ssh-pkcs11.c
index 65a7b5897..775de9642 100644
--- a/ssh-pkcs11.c
+++ b/ssh-pkcs11.c
@@ -30,6 +30,7 @@
30#include <dlfcn.h> 30#include <dlfcn.h>
31 31
32#include "openbsd-compat/sys-queue.h" 32#include "openbsd-compat/sys-queue.h"
33#include "openbsd-compat/openssl-compat.h"
33 34
34#include <openssl/x509.h> 35#include <openssl/x509.h>
35 36
@@ -67,7 +68,7 @@ struct pkcs11_key {
67 struct pkcs11_provider *provider; 68 struct pkcs11_provider *provider;
68 CK_ULONG slotidx; 69 CK_ULONG slotidx;
69 int (*orig_finish)(RSA *rsa); 70 int (*orig_finish)(RSA *rsa);
70 RSA_METHOD rsa_method; 71 RSA_METHOD *rsa_method;
71 char *keyid; 72 char *keyid;
72 int keyid_len; 73 int keyid_len;
73}; 74};
@@ -182,6 +183,7 @@ pkcs11_rsa_finish(RSA *rsa)
182 rv = k11->orig_finish(rsa); 183 rv = k11->orig_finish(rsa);
183 if (k11->provider) 184 if (k11->provider)
184 pkcs11_provider_unref(k11->provider); 185 pkcs11_provider_unref(k11->provider);
186 RSA_meth_free(k11->rsa_method);
185 free(k11->keyid); 187 free(k11->keyid);
186 free(k11); 188 free(k11);
187 } 189 }
@@ -326,13 +328,18 @@ pkcs11_rsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx,
326 k11->keyid = xmalloc(k11->keyid_len); 328 k11->keyid = xmalloc(k11->keyid_len);
327 memcpy(k11->keyid, keyid_attrib->pValue, k11->keyid_len); 329 memcpy(k11->keyid, keyid_attrib->pValue, k11->keyid_len);
328 } 330 }
329 k11->orig_finish = def->finish; 331 k11->rsa_method = RSA_meth_dup(def);
330 memcpy(&k11->rsa_method, def, sizeof(k11->rsa_method)); 332 if (k11->rsa_method == NULL)
331 k11->rsa_method.name = "pkcs11"; 333 fatal("%s: RSA_meth_dup failed", __func__);
332 k11->rsa_method.rsa_priv_enc = pkcs11_rsa_private_encrypt; 334 k11->orig_finish = RSA_meth_get_finish(def);
333 k11->rsa_method.rsa_priv_dec = pkcs11_rsa_private_decrypt; 335 if (!RSA_meth_set1_name(k11->rsa_method, "pkcs11") ||
334 k11->rsa_method.finish = pkcs11_rsa_finish; 336 !RSA_meth_set_priv_enc(k11->rsa_method,
335 RSA_set_method(rsa, &k11->rsa_method); 337 pkcs11_rsa_private_encrypt) ||
338 !RSA_meth_set_priv_dec(k11->rsa_method,
339 pkcs11_rsa_private_decrypt) ||
340 !RSA_meth_set_finish(k11->rsa_method, pkcs11_rsa_finish))
341 fatal("%s: setup pkcs11 method failed", __func__);
342 RSA_set_method(rsa, k11->rsa_method);
336 RSA_set_app_data(rsa, k11); 343 RSA_set_app_data(rsa, k11);
337 return (0); 344 return (0);
338} 345}
@@ -445,6 +452,15 @@ pkcs11_key_included(struct sshkey ***keysp, int *nkeys, struct sshkey *key)
445} 452}
446 453
447static int 454static int
455have_rsa_key(const RSA *rsa)
456{
457 const BIGNUM *rsa_n, *rsa_e;
458
459 RSA_get0_key(rsa, &rsa_n, &rsa_e, NULL);
460 return rsa_n != NULL && rsa_e != NULL;
461}
462
463static int
448pkcs11_fetch_keys_filter(struct pkcs11_provider *p, CK_ULONG slotidx, 464pkcs11_fetch_keys_filter(struct pkcs11_provider *p, CK_ULONG slotidx,
449 CK_ATTRIBUTE filter[], CK_ATTRIBUTE attribs[3], 465 CK_ATTRIBUTE filter[], CK_ATTRIBUTE attribs[3],
450 struct sshkey ***keysp, int *nkeys) 466 struct sshkey ***keysp, int *nkeys)
@@ -512,10 +528,20 @@ pkcs11_fetch_keys_filter(struct pkcs11_provider *p, CK_ULONG slotidx,
512 if ((rsa = RSA_new()) == NULL) { 528 if ((rsa = RSA_new()) == NULL) {
513 error("RSA_new failed"); 529 error("RSA_new failed");
514 } else { 530 } else {
515 rsa->n = BN_bin2bn(attribs[1].pValue, 531 BIGNUM *rsa_n, *rsa_e;
532
533 rsa_n = BN_bin2bn(attribs[1].pValue,
516 attribs[1].ulValueLen, NULL); 534 attribs[1].ulValueLen, NULL);
517 rsa->e = BN_bin2bn(attribs[2].pValue, 535 rsa_e = BN_bin2bn(attribs[2].pValue,
518 attribs[2].ulValueLen, NULL); 536 attribs[2].ulValueLen, NULL);
537 if (rsa_n != NULL && rsa_e != NULL) {
538 if (!RSA_set0_key(rsa,
539 rsa_n, rsa_e, NULL))
540 fatal("%s: set key", __func__);
541 rsa_n = rsa_e = NULL; /* transferred */
542 }
543 BN_free(rsa_n);
544 BN_free(rsa_e);
519 } 545 }
520 } else { 546 } else {
521 cp = attribs[2].pValue; 547 cp = attribs[2].pValue;
@@ -525,16 +551,16 @@ pkcs11_fetch_keys_filter(struct pkcs11_provider *p, CK_ULONG slotidx,
525 == NULL) { 551 == NULL) {
526 error("d2i_X509 failed"); 552 error("d2i_X509 failed");
527 } else if ((evp = X509_get_pubkey(x509)) == NULL || 553 } else if ((evp = X509_get_pubkey(x509)) == NULL ||
528 evp->type != EVP_PKEY_RSA || 554 EVP_PKEY_base_id(evp) != EVP_PKEY_RSA ||
529 evp->pkey.rsa == NULL) { 555 EVP_PKEY_get0_RSA(evp) == NULL) {
530 debug("X509_get_pubkey failed or no rsa"); 556 debug("X509_get_pubkey failed or no rsa");
531 } else if ((rsa = RSAPublicKey_dup(evp->pkey.rsa)) 557 } else if ((rsa = RSAPublicKey_dup(
532 == NULL) { 558 EVP_PKEY_get0_RSA(evp))) == NULL) {
533 error("RSAPublicKey_dup"); 559 error("RSAPublicKey_dup");
534 } 560 }
535 X509_free(x509); 561 X509_free(x509);
536 } 562 }
537 if (rsa && rsa->n && rsa->e && 563 if (rsa && have_rsa_key(rsa) &&
538 pkcs11_rsa_wrap(p, slotidx, &attribs[0], rsa) == 0) { 564 pkcs11_rsa_wrap(p, slotidx, &attribs[0], rsa) == 0) {
539 if ((key = sshkey_new(KEY_UNSPEC)) == NULL) 565 if ((key = sshkey_new(KEY_UNSPEC)) == NULL)
540 fatal("sshkey_new failed"); 566 fatal("sshkey_new failed");