From e2cb445d786f7572da2af93e3433308eaed1093a Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Mon, 21 Jan 2019 11:32:28 +1100 Subject: conditionalise ECDSA PKCS#11 support Require EC_KEY_METHOD support in libcrypto, evidenced by presence of EC_KEY_METHOD_new() function. --- configure.ac | 1 + ssh-pkcs11-client.c | 10 +++++++++- ssh-pkcs11.c | 10 ++++++++++ 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 0509c306d..a5974e372 100644 --- a/configure.ac +++ b/configure.ac @@ -2973,6 +2973,7 @@ if test "x$openssl" = "xyes" ; then if test x$enable_nistp256 = x1 || test x$enable_nistp384 = x1 || \ test x$enable_nistp521 = x1; then AC_DEFINE(OPENSSL_HAS_ECC, [1], [OpenSSL has ECC]) + AC_CHECK_FUNCS([EC_KEY_METHOD_new]) fi if test x$enable_nistp256 = x1; then AC_DEFINE([OPENSSL_HAS_NISTP256], [1], diff --git a/ssh-pkcs11-client.c b/ssh-pkcs11-client.c index 6cecf4863..5ba33332a 100644 --- a/ssh-pkcs11-client.c +++ b/ssh-pkcs11-client.c @@ -163,6 +163,7 @@ rsa_encrypt(int flen, const u_char *from, u_char *to, RSA *rsa, int padding) return (ret); } +#ifdef HAVE_EC_KEY_METHOD_NEW static ECDSA_SIG * ecdsa_do_sign(const unsigned char *dgst, int dgst_len, const BIGNUM *inv, const BIGNUM *rp, EC_KEY *ec) @@ -219,9 +220,12 @@ ecdsa_do_sign(const unsigned char *dgst, int dgst_len, const BIGNUM *inv, sshbuf_free(msg); return (ret); } +#endif /* HAVE_EC_KEY_METHOD_NEW */ static RSA_METHOD *helper_rsa; +#ifdef HAVE_EC_KEY_METHOD_NEW static EC_KEY_METHOD *helper_ecdsa; +#endif /* HAVE_EC_KEY_METHOD_NEW */ /* redirect private key crypto operations to the ssh-pkcs11-helper */ static void @@ -229,8 +233,10 @@ wrap_key(struct sshkey *k) { if (k->type == KEY_RSA) RSA_set_method(k->rsa, helper_rsa); +#ifdef HAVE_EC_KEY_METHOD_NEW else if (k->type == KEY_ECDSA) EC_KEY_set_method(k->ecdsa, helper_ecdsa); +#endif /* HAVE_EC_KEY_METHOD_NEW */ else fatal("%s: unknown key type", __func__); } @@ -238,9 +244,10 @@ wrap_key(struct sshkey *k) static int pkcs11_start_helper_methods(void) { - if (helper_ecdsa != NULL) + if (helper_rsa != NULL) return (0); +#ifdef HAVE_EC_KEY_METHOD_NEW int (*orig_sign)(int, const unsigned char *, int, unsigned char *, unsigned int *, const BIGNUM *, const BIGNUM *, EC_KEY *) = NULL; if (helper_ecdsa != NULL) @@ -250,6 +257,7 @@ pkcs11_start_helper_methods(void) return (-1); EC_KEY_METHOD_get_sign(helper_ecdsa, &orig_sign, NULL, NULL); EC_KEY_METHOD_set_sign(helper_ecdsa, orig_sign, NULL, ecdsa_do_sign); +#endif /* HAVE_EC_KEY_METHOD_NEW */ if ((helper_rsa = RSA_meth_dup(RSA_get_default_method())) == NULL) fatal("%s: RSA_meth_dup failed", __func__); diff --git a/ssh-pkcs11.c b/ssh-pkcs11.c index b49034952..2b65010ce 100644 --- a/ssh-pkcs11.c +++ b/ssh-pkcs11.c @@ -409,6 +409,7 @@ pkcs11_rsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx, return (0); } +#ifdef HAVE_EC_KEY_METHOD_NEW /* openssl callback doing the actual signing operation */ static ECDSA_SIG * ecdsa_do_sign(const unsigned char *dgst, int dgst_len, const BIGNUM *inv, @@ -512,6 +513,7 @@ pkcs11_ecdsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx, return (0); } +#endif /* HAVE_EC_KEY_METHOD_NEW */ /* remove trailing spaces */ static void @@ -582,6 +584,7 @@ pkcs11_key_included(struct sshkey ***keysp, int *nkeys, struct sshkey *key) return (0); } +#ifdef HAVE_EC_KEY_METHOD_NEW static struct sshkey * pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, CK_OBJECT_HANDLE *obj) @@ -704,6 +707,7 @@ fail: return (key); } +#endif /* HAVE_EC_KEY_METHOD_NEW */ static struct sshkey * pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, @@ -808,7 +812,9 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, EC_KEY *ec = NULL; struct sshkey *key = NULL; int i; +#ifdef HAVE_EC_KEY_METHOD_NEW int nid; +#endif const u_char *cp; memset(&cert_attr, 0, sizeof(cert_attr)); @@ -890,6 +896,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, key->type = KEY_RSA; key->flags |= SSHKEY_FLAG_EXT; rsa = NULL; /* now owned by key */ +#ifdef HAVE_EC_KEY_METHOD_NEW } else if (EVP_PKEY_base_id(evp) == EVP_PKEY_EC) { if (EVP_PKEY_get0_EC_KEY(evp) == NULL) { error("invalid x509; no ec key"); @@ -920,6 +927,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, key->type = KEY_ECDSA; key->flags |= SSHKEY_FLAG_EXT; ec = NULL; /* now owned by key */ +#endif /* HAVE_EC_KEY_METHOD_NEW */ } else error("unknown certificate key type"); @@ -1103,9 +1111,11 @@ pkcs11_fetch_keys(struct pkcs11_provider *p, CK_ULONG slotidx, case CKK_RSA: key = pkcs11_fetch_rsa_pubkey(p, slotidx, &obj); break; +#ifdef HAVE_EC_KEY_METHOD_NEW case CKK_ECDSA: key = pkcs11_fetch_ecdsa_pubkey(p, slotidx, &obj); break; +#endif /* HAVE_EC_KEY_METHOD_NEW */ default: /* XXX print key type? */ error("skipping unsupported key type"); -- cgit v1.2.3