From 482d23bcacdd3664f21cc82a5135f66fc598275f Mon Sep 17 00:00:00 2001 From: "djm@openbsd.org" Date: Thu, 13 Sep 2018 02:08:33 +0000 Subject: upstream: hold our collective noses and use the openssl-1.1.x API in OpenSSH; feedback and ok tb@ jsing@ markus@ OpenBSD-Commit-ID: cacbcac87ce5da0d3ca7ef1b38a6f7fb349e4417 --- ssh-pkcs11.c | 55 ++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 40 insertions(+), 15 deletions(-) (limited to 'ssh-pkcs11.c') diff --git a/ssh-pkcs11.c b/ssh-pkcs11.c index 65a7b5897..c35f9415f 100644 --- a/ssh-pkcs11.c +++ b/ssh-pkcs11.c @@ -67,7 +67,7 @@ struct pkcs11_key { 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; }; @@ -182,6 +182,7 @@ pkcs11_rsa_finish(RSA *rsa) rv = k11->orig_finish(rsa); if (k11->provider) pkcs11_provider_unref(k11->provider); + RSA_meth_free(k11->rsa_method); free(k11->keyid); free(k11); } @@ -326,13 +327,18 @@ pkcs11_rsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx, 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); } @@ -444,6 +450,15 @@ pkcs11_key_included(struct sshkey ***keysp, int *nkeys, struct sshkey *key) return (0); } +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], @@ -512,10 +527,20 @@ pkcs11_fetch_keys_filter(struct pkcs11_provider *p, CK_ULONG slotidx, 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; @@ -525,16 +550,16 @@ pkcs11_fetch_keys_filter(struct pkcs11_provider *p, CK_ULONG slotidx, == 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"); -- cgit v1.2.3