=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/ssh/ssh-pkcs11.c,v retrieving revision 1.26 retrieving revision 1.27 diff -u -r1.26 -r1.27 --- src/usr.bin/ssh/ssh-pkcs11.c 2018/02/07 02:06:51 1.26 +++ src/usr.bin/ssh/ssh-pkcs11.c 2018/09/13 02:08:33 1.27 @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-pkcs11.c,v 1.26 2018/02/07 02:06:51 jsing Exp $ */ +/* $OpenBSD: ssh-pkcs11.c,v 1.27 2018/09/13 02:08:33 djm Exp $ */ /* * Copyright (c) 2010 Markus Friedl. All rights reserved. * @@ -59,7 +59,7 @@ struct pkcs11_provider *provider; CK_ULONG slotidx; int (*orig_finish)(RSA *rsa); - RSA_METHOD rsa_method; + RSA_METHOD *rsa_method; char *keyid; int keyid_len; }; @@ -176,6 +176,7 @@ rv = k11->orig_finish(rsa); if (k11->provider) pkcs11_provider_unref(k11->provider); + RSA_meth_free(k11->rsa_method); free(k11->keyid); free(k11); } @@ -317,13 +318,18 @@ k11->keyid = xmalloc(k11->keyid_len); memcpy(k11->keyid, keyid_attrib->pValue, k11->keyid_len); } - k11->orig_finish = def->finish; - memcpy(&k11->rsa_method, def, sizeof(k11->rsa_method)); - k11->rsa_method.name = "pkcs11"; - k11->rsa_method.rsa_priv_enc = pkcs11_rsa_private_encrypt; - k11->rsa_method.rsa_priv_dec = pkcs11_rsa_private_decrypt; - k11->rsa_method.finish = pkcs11_rsa_finish; - RSA_set_method(rsa, &k11->rsa_method); + k11->rsa_method = RSA_meth_dup(def); + if (k11->rsa_method == NULL) + fatal("%s: RSA_meth_dup failed", __func__); + k11->orig_finish = RSA_meth_get_finish(def); + if (!RSA_meth_set1_name(k11->rsa_method, "pkcs11") || + !RSA_meth_set_priv_enc(k11->rsa_method, + pkcs11_rsa_private_encrypt) || + !RSA_meth_set_priv_dec(k11->rsa_method, + pkcs11_rsa_private_decrypt) || + !RSA_meth_set_finish(k11->rsa_method, pkcs11_rsa_finish)) + fatal("%s: setup pkcs11 method failed", __func__); + RSA_set_method(rsa, k11->rsa_method); RSA_set_app_data(rsa, k11); return (0); } @@ -434,6 +440,15 @@ } static int +have_rsa_key(const RSA *rsa) +{ + const BIGNUM *rsa_n, *rsa_e; + + RSA_get0_key(rsa, &rsa_n, &rsa_e, NULL); + return rsa_n != NULL && rsa_e != NULL; +} + +static int pkcs11_fetch_keys_filter(struct pkcs11_provider *p, CK_ULONG slotidx, CK_ATTRIBUTE filter[], CK_ATTRIBUTE attribs[3], struct sshkey ***keysp, int *nkeys) @@ -501,10 +516,20 @@ if ((rsa = RSA_new()) == NULL) { error("RSA_new failed"); } else { - rsa->n = BN_bin2bn(attribs[1].pValue, + BIGNUM *rsa_n, *rsa_e; + + rsa_n = BN_bin2bn(attribs[1].pValue, attribs[1].ulValueLen, NULL); - rsa->e = BN_bin2bn(attribs[2].pValue, + rsa_e = BN_bin2bn(attribs[2].pValue, attribs[2].ulValueLen, NULL); + if (rsa_n != NULL && rsa_e != NULL) { + if (!RSA_set0_key(rsa, + rsa_n, rsa_e, NULL)) + fatal("%s: set key", __func__); + rsa_n = rsa_e = NULL; /* transferred */ + } + BN_free(rsa_n); + BN_free(rsa_e); } } else { cp = attribs[2].pValue; @@ -514,16 +539,16 @@ == NULL) { error("d2i_X509 failed"); } else if ((evp = X509_get_pubkey(x509)) == NULL || - evp->type != EVP_PKEY_RSA || - evp->pkey.rsa == NULL) { + EVP_PKEY_base_id(evp) != EVP_PKEY_RSA || + EVP_PKEY_get0_RSA(evp) == NULL) { debug("X509_get_pubkey failed or no rsa"); - } else if ((rsa = RSAPublicKey_dup(evp->pkey.rsa)) - == NULL) { + } else if ((rsa = RSAPublicKey_dup( + EVP_PKEY_get0_RSA(evp))) == NULL) { error("RSAPublicKey_dup"); } X509_free(x509); } - if (rsa && rsa->n && rsa->e && + if (rsa && have_rsa_key(rsa) && pkcs11_rsa_wrap(p, slotidx, &attribs[0], rsa) == 0) { if ((key = sshkey_new(KEY_UNSPEC)) == NULL) fatal("sshkey_new failed");