Bugzilla – Attachment 3277 Details for
Bug 3005
Use high-level EVP PKEY API instead of low-level algorithm specific calls + separate digesting in the every backend
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
proposed patch
openssh-evp-pkey.patch (text/plain), 74.14 KB, created by
Jakub Jelen
on 2019-05-08 01:27:00 AEST
(
hide
)
Description:
proposed patch
Filename:
MIME Type:
Creator:
Jakub Jelen
Created:
2019-05-08 01:27:00 AEST
Size:
74.14 KB
patch
obsolete
>commit c4ec304d717498f7832da90822b188d2959979b7 >Author: Jakub Jelen <jjelen@redhat.com> >Date: Tue Apr 23 17:15:27 2019 +0200 > > Use high-level EVP API for signature generation and verification > >diff --git a/digest-openssl.c b/digest-openssl.c >index da7ed72b..6a21d8ad 100644 >--- a/digest-openssl.c >+++ b/digest-openssl.c >@@ -63,6 +63,22 @@ const struct ssh_digest digests[] = { > { -1, NULL, 0, NULL }, > }; > >+const EVP_MD * >+ssh_digest_to_md(int digest_type) >+{ >+ switch (digest_type) { >+ case SSH_DIGEST_SHA1: >+ return EVP_sha1(); >+ case SSH_DIGEST_SHA256: >+ return EVP_sha256(); >+ case SSH_DIGEST_SHA384: >+ return EVP_sha384(); >+ case SSH_DIGEST_SHA512: >+ return EVP_sha512(); >+ } >+ return NULL; >+} >+ > static const struct ssh_digest * > ssh_digest_by_alg(int alg) > { >diff --git a/digest.h b/digest.h >index 274574d0..c7ceeb36 100644 >--- a/digest.h >+++ b/digest.h >@@ -32,6 +32,12 @@ > struct sshbuf; > struct ssh_digest_ctx; > >+#ifdef WITH_OPENSSL >+#include <openssl/evp.h> >+/* Converts internal digest representation to the OpenSSL one */ >+const EVP_MD *ssh_digest_to_md(int digest_type); >+#endif >+ > /* Looks up a digest algorithm by name */ > int ssh_digest_alg_by_name(const char *name); > >diff --git a/regress/unittests/sshkey/common.c b/regress/unittests/sshkey/common.c >index e63465c4..ee41c0e6 100644 >--- a/regress/unittests/sshkey/common.c >+++ b/regress/unittests/sshkey/common.c >@@ -88,10 +88,12 @@ const BIGNUM * > rsa_n(struct sshkey *k) > { > const BIGNUM *n = NULL; >+ const RSA *rsa = NULL; > > ASSERT_PTR_NE(k, NULL); >- ASSERT_PTR_NE(k->rsa, NULL); >- RSA_get0_key(k->rsa, &n, NULL, NULL); >+ rsa = EVP_PKEY_get0_RSA(k->pkey); >+ ASSERT_PTR_NE(rsa, NULL); >+ RSA_get0_key(rsa, &n, NULL, NULL); > return n; > } > >@@ -99,10 +101,12 @@ const BIGNUM * > rsa_e(struct sshkey *k) > { > const BIGNUM *e = NULL; >+ const RSA *rsa = NULL; > > ASSERT_PTR_NE(k, NULL); >- ASSERT_PTR_NE(k->rsa, NULL); >- RSA_get0_key(k->rsa, NULL, &e, NULL); >+ rsa = EVP_PKEY_get0_RSA(k->pkey); >+ ASSERT_PTR_NE(rsa, NULL); >+ RSA_get0_key(rsa, NULL, &e, NULL); > return e; > } > >@@ -110,10 +114,12 @@ const BIGNUM * > rsa_p(struct sshkey *k) > { > const BIGNUM *p = NULL; >+ const RSA *rsa = NULL; > > ASSERT_PTR_NE(k, NULL); >- ASSERT_PTR_NE(k->rsa, NULL); >- RSA_get0_factors(k->rsa, &p, NULL); >+ rsa = EVP_PKEY_get0_RSA(k->pkey); >+ ASSERT_PTR_NE(rsa, NULL); >+ RSA_get0_factors(rsa, &p, NULL); > return p; > } > >@@ -121,10 +127,12 @@ const BIGNUM * > rsa_q(struct sshkey *k) > { > const BIGNUM *q = NULL; >+ const RSA *rsa = NULL; > > ASSERT_PTR_NE(k, NULL); >- ASSERT_PTR_NE(k->rsa, NULL); >- RSA_get0_factors(k->rsa, NULL, &q); >+ rsa = EVP_PKEY_get0_RSA(k->pkey); >+ ASSERT_PTR_NE(rsa, NULL); >+ RSA_get0_factors(rsa, NULL, &q); > return q; > } > >@@ -132,10 +140,12 @@ const BIGNUM * > dsa_g(struct sshkey *k) > { > const BIGNUM *g = NULL; >+ const DSA *dsa = NULL; > > ASSERT_PTR_NE(k, NULL); >- ASSERT_PTR_NE(k->dsa, NULL); >- DSA_get0_pqg(k->dsa, NULL, NULL, &g); >+ dsa = EVP_PKEY_get0_DSA(k->pkey); >+ ASSERT_PTR_NE(dsa, NULL); >+ DSA_get0_pqg(dsa, NULL, NULL, &g); > return g; > } > >@@ -143,10 +153,12 @@ const BIGNUM * > dsa_pub_key(struct sshkey *k) > { > const BIGNUM *pub_key = NULL; >+ const DSA *dsa = NULL; > > ASSERT_PTR_NE(k, NULL); >- ASSERT_PTR_NE(k->dsa, NULL); >- DSA_get0_key(k->dsa, &pub_key, NULL); >+ dsa = EVP_PKEY_get0_DSA(k->pkey); >+ ASSERT_PTR_NE(dsa, NULL); >+ DSA_get0_key(dsa, &pub_key, NULL); > return pub_key; > } > >@@ -154,10 +166,12 @@ const BIGNUM * > dsa_priv_key(struct sshkey *k) > { > const BIGNUM *priv_key = NULL; >+ const DSA *dsa = NULL; > > ASSERT_PTR_NE(k, NULL); >- ASSERT_PTR_NE(k->dsa, NULL); >- DSA_get0_key(k->dsa, NULL, &priv_key); >+ dsa = EVP_PKEY_get0_DSA(k->pkey); >+ ASSERT_PTR_NE(dsa, NULL); >+ DSA_get0_key(dsa, NULL, &priv_key); > return priv_key; > } > >diff --git a/regress/unittests/sshkey/test_file.c b/regress/unittests/sshkey/test_file.c >index 65610dac..5146eaa1 100644 >--- a/regress/unittests/sshkey/test_file.c >+++ b/regress/unittests/sshkey/test_file.c >@@ -45,6 +45,7 @@ sshkey_file_tests(void) > struct sshkey *k1, *k2; > struct sshbuf *buf, *pw; > BIGNUM *a, *b, *c; >+ EC_KEY *ecdsa; > char *cp; > > TEST_START("load passphrase"); >@@ -264,11 +265,12 @@ sshkey_file_tests(void) > sshbuf_free(buf); > a = load_bignum("ecdsa_1.param.priv"); > b = load_bignum("ecdsa_1.param.pub"); >- c = EC_POINT_point2bn(EC_KEY_get0_group(k1->ecdsa), >- EC_KEY_get0_public_key(k1->ecdsa), POINT_CONVERSION_UNCOMPRESSED, >+ ecdsa = EVP_PKEY_get0_EC_KEY(k1->pkey); >+ c = EC_POINT_point2bn(EC_KEY_get0_group(ecdsa), >+ EC_KEY_get0_public_key(ecdsa), POINT_CONVERSION_UNCOMPRESSED, > NULL, NULL); > ASSERT_PTR_NE(c, NULL); >- ASSERT_BIGNUM_EQ(EC_KEY_get0_private_key(k1->ecdsa), a); >+ ASSERT_BIGNUM_EQ(EC_KEY_get0_private_key(ecdsa), a); > ASSERT_BIGNUM_EQ(b, c); > BN_free(a); > BN_free(b); >diff --git a/regress/unittests/sshkey/test_sshkey.c b/regress/unittests/sshkey/test_sshkey.c >index 47a03fad..c702f491 100644 >--- a/regress/unittests/sshkey/test_sshkey.c >+++ b/regress/unittests/sshkey/test_sshkey.c >@@ -180,6 +180,9 @@ sshkey_tests(void) > #ifdef OPENSSL_HAS_ECC > struct sshkey *ke; > #endif >+ const RSA *rsa; >+ const DSA *dsa; >+ const EC_KEY *ecdsa; > struct sshbuf *b; > > TEST_START("new invalid"); >@@ -196,14 +199,16 @@ sshkey_tests(void) > TEST_START("new/free KEY_RSA"); > k1 = sshkey_new(KEY_RSA); > ASSERT_PTR_NE(k1, NULL); >- ASSERT_PTR_NE(k1->rsa, NULL); >+ rsa = EVP_PKEY_get0_RSA(k1->pkey); >+ ASSERT_PTR_NE(rsa, NULL); > sshkey_free(k1); > TEST_DONE(); > > TEST_START("new/free KEY_DSA"); > k1 = sshkey_new(KEY_DSA); > ASSERT_PTR_NE(k1, NULL); >- ASSERT_PTR_NE(k1->dsa, NULL); >+ dsa = EVP_PKEY_get0_DSA(k1->pkey); >+ ASSERT_PTR_NE(dsa, NULL); > sshkey_free(k1); > TEST_DONE(); > >@@ -211,7 +216,8 @@ sshkey_tests(void) > TEST_START("new/free KEY_ECDSA"); > k1 = sshkey_new(KEY_ECDSA); > ASSERT_PTR_NE(k1, NULL); >- ASSERT_PTR_EQ(k1->ecdsa, NULL); /* Can't allocate without NID */ >+ ecdsa = EVP_PKEY_get0_EC_KEY(k1->pkey); >+ ASSERT_PTR_EQ(ecdsa, NULL); /* Can't allocate without NID */ > sshkey_free(k1); > TEST_DONE(); > #endif >@@ -258,7 +264,8 @@ sshkey_tests(void) > SSH_ERR_KEY_LENGTH); > ASSERT_INT_EQ(sshkey_generate(KEY_RSA, 1024, &kr), 0); > ASSERT_PTR_NE(kr, NULL); >- ASSERT_PTR_NE(kr->rsa, NULL); >+ rsa = EVP_PKEY_get0_RSA(kr->pkey); >+ ASSERT_PTR_NE(rsa, NULL); > ASSERT_PTR_NE(rsa_n(kr), NULL); > ASSERT_PTR_NE(rsa_e(kr), NULL); > ASSERT_PTR_NE(rsa_p(kr), NULL); >@@ -268,7 +275,8 @@ sshkey_tests(void) > TEST_START("generate KEY_DSA"); > ASSERT_INT_EQ(sshkey_generate(KEY_DSA, 1024, &kd), 0); > ASSERT_PTR_NE(kd, NULL); >- ASSERT_PTR_NE(kd->dsa, NULL); >+ dsa = EVP_PKEY_get0_DSA(kd->pkey); >+ ASSERT_PTR_NE(dsa, NULL); > ASSERT_PTR_NE(dsa_g(kd), NULL); > ASSERT_PTR_NE(dsa_priv_key(kd), NULL); > TEST_DONE(); >@@ -277,9 +285,10 @@ sshkey_tests(void) > TEST_START("generate KEY_ECDSA"); > ASSERT_INT_EQ(sshkey_generate(KEY_ECDSA, 256, &ke), 0); > ASSERT_PTR_NE(ke, NULL); >- ASSERT_PTR_NE(ke->ecdsa, NULL); >- ASSERT_PTR_NE(EC_KEY_get0_public_key(ke->ecdsa), NULL); >- ASSERT_PTR_NE(EC_KEY_get0_private_key(ke->ecdsa), NULL); >+ ecdsa = EVP_PKEY_get0_EC_KEY(ke->pkey); >+ ASSERT_PTR_NE(ecdsa, NULL); >+ ASSERT_PTR_NE(EC_KEY_get0_public_key(ecdsa), NULL); >+ ASSERT_PTR_NE(EC_KEY_get0_private_key(ecdsa), NULL); > TEST_DONE(); > #endif > >@@ -296,7 +305,8 @@ sshkey_tests(void) > ASSERT_PTR_NE(k1, NULL); > ASSERT_PTR_NE(kr, k1); > ASSERT_INT_EQ(k1->type, KEY_RSA); >- ASSERT_PTR_NE(k1->rsa, NULL); >+ rsa = EVP_PKEY_get0_RSA(k1->pkey); >+ ASSERT_PTR_NE(rsa, NULL); > ASSERT_PTR_NE(rsa_n(k1), NULL); > ASSERT_PTR_NE(rsa_e(k1), NULL); > ASSERT_PTR_EQ(rsa_p(k1), NULL); >@@ -312,7 +322,8 @@ sshkey_tests(void) > ASSERT_PTR_NE(k1, NULL); > ASSERT_PTR_NE(kd, k1); > ASSERT_INT_EQ(k1->type, KEY_DSA); >- ASSERT_PTR_NE(k1->dsa, NULL); >+ dsa = EVP_PKEY_get0_DSA(k1->pkey); >+ ASSERT_PTR_NE(dsa, NULL); > ASSERT_PTR_NE(dsa_g(k1), NULL); > ASSERT_PTR_EQ(dsa_priv_key(k1), NULL); > TEST_DONE(); >@@ -328,10 +339,12 @@ sshkey_tests(void) > ASSERT_PTR_NE(k1, NULL); > ASSERT_PTR_NE(ke, k1); > ASSERT_INT_EQ(k1->type, KEY_ECDSA); >- ASSERT_PTR_NE(k1->ecdsa, NULL); >+ ecdsa = EVP_PKEY_get0_EC_KEY(k1->pkey); >+ ASSERT_PTR_NE(ecdsa, NULL); > ASSERT_INT_EQ(k1->ecdsa_nid, ke->ecdsa_nid); >- ASSERT_PTR_NE(EC_KEY_get0_public_key(ke->ecdsa), NULL); >- ASSERT_PTR_EQ(EC_KEY_get0_private_key(k1->ecdsa), NULL); >+ ASSERT_PTR_EQ(EC_KEY_get0_private_key(ecdsa), NULL); >+ ecdsa = EVP_PKEY_get0_EC_KEY(ke->pkey); >+ ASSERT_PTR_NE(EC_KEY_get0_public_key(ecdsa), NULL); > TEST_DONE(); > > TEST_START("equal KEY_ECDSA/demoted KEY_ECDSA"); >diff --git a/ssh-dss.c b/ssh-dss.c >index a23c383d..0b8b3b03 100644 >--- a/ssh-dss.c >+++ b/ssh-dss.c >@@ -54,9 +54,12 @@ ssh_dss_sign(const struct sshkey *key, u_char **sigp, size_t *lenp, > { > DSA_SIG *sig = NULL; > const BIGNUM *sig_r, *sig_s; >- u_char digest[SSH_DIGEST_MAX_LENGTH], sigblob[SIGBLOB_LEN]; >- size_t rlen, slen, len, dlen = ssh_digest_bytes(SSH_DIGEST_SHA1); >+ u_char sigblob[SIGBLOB_LEN]; >+ size_t rlen, slen; >+ int len; > struct sshbuf *b = NULL; >+ u_char *sigb = NULL; >+ const u_char *psig = NULL; > int ret = SSH_ERR_INVALID_ARGUMENT; > > if (lenp != NULL) >@@ -64,20 +67,23 @@ ssh_dss_sign(const struct sshkey *key, u_char **sigp, size_t *lenp, > if (sigp != NULL) > *sigp = NULL; > >- if (key == NULL || key->dsa == NULL || >+ if (key == NULL || EVP_PKEY_get0_DSA(key->pkey) == NULL || > sshkey_type_plain(key->type) != KEY_DSA) > return SSH_ERR_INVALID_ARGUMENT; >- if (dlen == 0) >- return SSH_ERR_INTERNAL_ERROR; > >- if ((ret = ssh_digest_memory(SSH_DIGEST_SHA1, data, datalen, >- digest, sizeof(digest))) != 0) >+ ret = sshkey_calculate_signature(key->pkey, SSH_DIGEST_SHA1, &sigb, &len, >+ data, datalen); >+ if (ret < 0) { > goto out; >+ } > >- if ((sig = DSA_do_sign(digest, dlen, key->dsa)) == NULL) { >+ psig = sigb; >+ if ((sig = d2i_DSA_SIG(NULL, &psig, len)) == NULL) { > ret = SSH_ERR_LIBCRYPTO_ERROR; > goto out; > } >+ free(sigb); >+ sigb = NULL; > > DSA_SIG_get0(sig, &sig_r, &sig_s); > rlen = BN_num_bytes(sig_r); >@@ -110,7 +116,7 @@ ssh_dss_sign(const struct sshkey *key, u_char **sigp, size_t *lenp, > *lenp = len; > ret = 0; > out: >- explicit_bzero(digest, sizeof(digest)); >+ free(sigb); > DSA_SIG_free(sig); > sshbuf_free(b); > return ret; >@@ -123,18 +129,17 @@ ssh_dss_verify(const struct sshkey *key, > { > DSA_SIG *sig = NULL; > BIGNUM *sig_r = NULL, *sig_s = NULL; >- u_char digest[SSH_DIGEST_MAX_LENGTH], *sigblob = NULL; >- size_t len, dlen = ssh_digest_bytes(SSH_DIGEST_SHA1); >+ u_char *sigblob = NULL; >+ size_t len, slen; > int ret = SSH_ERR_INTERNAL_ERROR; > struct sshbuf *b = NULL; > char *ktype = NULL; >+ u_char *sigb = NULL, *psig = NULL; > >- if (key == NULL || key->dsa == NULL || >+ if (key == NULL || EVP_PKEY_get0_DSA(key->pkey) == NULL || > sshkey_type_plain(key->type) != KEY_DSA || > signature == NULL || signaturelen == 0) > return SSH_ERR_INVALID_ARGUMENT; >- if (dlen == 0) >- return SSH_ERR_INTERNAL_ERROR; > > /* fetch signature */ > if ((b = sshbuf_from(signature, signaturelen)) == NULL) >@@ -176,25 +181,24 @@ ssh_dss_verify(const struct sshkey *key, > } > sig_r = sig_s = NULL; /* transferred */ > >- /* sha1 the data */ >- if ((ret = ssh_digest_memory(SSH_DIGEST_SHA1, data, datalen, >- digest, sizeof(digest))) != 0) >+ if ((slen = i2d_DSA_SIG(sig, NULL)) == 0) { >+ ret = SSH_ERR_LIBCRYPTO_ERROR; > goto out; >- >- switch (DSA_do_verify(digest, dlen, sig, key->dsa)) { >- case 1: >- ret = 0; >- break; >- case 0: >- ret = SSH_ERR_SIGNATURE_INVALID; >+ } >+ if ((sigb = malloc(slen)) == NULL) { >+ ret = SSH_ERR_ALLOC_FAIL; > goto out; >- default: >+ } >+ psig = sigb; >+ if ((slen = i2d_DSA_SIG(sig, &psig)) == 0) { > ret = SSH_ERR_LIBCRYPTO_ERROR; > goto out; > } > >+ ret = sshkey_verify_signature(key->pkey, SSH_DIGEST_SHA1, data, datalen, >+ sigb, slen); >+ > out: >- explicit_bzero(digest, sizeof(digest)); > DSA_SIG_free(sig); > BN_clear_free(sig_r); > BN_clear_free(sig_s); >diff --git a/ssh-ecdsa.c b/ssh-ecdsa.c >index 599c7199..3b9bcd95 100644 >--- a/ssh-ecdsa.c >+++ b/ssh-ecdsa.c >@@ -51,10 +51,11 @@ ssh_ecdsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp, > const u_char *data, size_t datalen, u_int compat) > { > ECDSA_SIG *sig = NULL; >+ unsigned char *sigb = NULL; >+ const unsigned char *psig; > const BIGNUM *sig_r, *sig_s; > int hash_alg; >- u_char digest[SSH_DIGEST_MAX_LENGTH]; >- size_t len, dlen; >+ int len; > struct sshbuf *b = NULL, *bb = NULL; > int ret = SSH_ERR_INTERNAL_ERROR; > >@@ -63,22 +64,24 @@ ssh_ecdsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp, > if (sigp != NULL) > *sigp = NULL; > >- if (key == NULL || key->ecdsa == NULL || >+ if (key == NULL || EVP_PKEY_get0_EC_KEY(key->pkey) == NULL || > sshkey_type_plain(key->type) != KEY_ECDSA) > return SSH_ERR_INVALID_ARGUMENT; > >- if ((hash_alg = sshkey_ec_nid_to_hash_alg(key->ecdsa_nid)) == -1 || >- (dlen = ssh_digest_bytes(hash_alg)) == 0) >+ if ((hash_alg = sshkey_ec_nid_to_hash_alg(key->ecdsa_nid)) == -1) > return SSH_ERR_INTERNAL_ERROR; >- if ((ret = ssh_digest_memory(hash_alg, data, datalen, >- digest, sizeof(digest))) != 0) >+ >+ ret = sshkey_calculate_signature(key->pkey, hash_alg, &sigb, &len, data, >+ datalen); >+ if (ret < 0) { > goto out; >+ } > >- if ((sig = ECDSA_do_sign(digest, dlen, key->ecdsa)) == NULL) { >+ psig = sigb; >+ if ((sig = d2i_ECDSA_SIG(NULL, &psig, len)) == NULL) { > ret = SSH_ERR_LIBCRYPTO_ERROR; > goto out; > } >- > if ((bb = sshbuf_new()) == NULL || (b = sshbuf_new()) == NULL) { > ret = SSH_ERR_ALLOC_FAIL; > goto out; >@@ -102,9 +105,9 @@ ssh_ecdsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp, > *lenp = len; > ret = 0; > out: >- explicit_bzero(digest, sizeof(digest)); > sshbuf_free(b); > sshbuf_free(bb); >+ free(sigb); > ECDSA_SIG_free(sig); > return ret; > } >@@ -117,20 +120,18 @@ ssh_ecdsa_verify(const struct sshkey *key, > { > ECDSA_SIG *sig = NULL; > BIGNUM *sig_r = NULL, *sig_s = NULL; >- int hash_alg; >- u_char digest[SSH_DIGEST_MAX_LENGTH]; >- size_t dlen; >+ int hash_alg, len; > int ret = SSH_ERR_INTERNAL_ERROR; > struct sshbuf *b = NULL, *sigbuf = NULL; > char *ktype = NULL; >+ unsigned char *sigb = NULL, *psig = NULL; > >- if (key == NULL || key->ecdsa == NULL || >+ if (key == NULL || EVP_PKEY_get0_EC_KEY(key->pkey) == NULL || > sshkey_type_plain(key->type) != KEY_ECDSA || > signature == NULL || signaturelen == 0) > return SSH_ERR_INVALID_ARGUMENT; > >- if ((hash_alg = sshkey_ec_nid_to_hash_alg(key->ecdsa_nid)) == -1 || >- (dlen = ssh_digest_bytes(hash_alg)) == 0) >+ if ((hash_alg = sshkey_ec_nid_to_hash_alg(key->ecdsa_nid)) == -1) > return SSH_ERR_INTERNAL_ERROR; > > /* fetch signature */ >@@ -166,34 +167,37 @@ ssh_ecdsa_verify(const struct sshkey *key, > } > sig_r = sig_s = NULL; /* transferred */ > >- if (sshbuf_len(sigbuf) != 0) { >- ret = SSH_ERR_UNEXPECTED_TRAILING_DATA; >+ /* Figure out the length */ >+ if ((len = i2d_ECDSA_SIG(sig, NULL)) == 0) { >+ ret = SSH_ERR_LIBCRYPTO_ERROR; > goto out; > } >- if ((ret = ssh_digest_memory(hash_alg, data, datalen, >- digest, sizeof(digest))) != 0) >- goto out; >- >- switch (ECDSA_do_verify(digest, dlen, sig, key->ecdsa)) { >- case 1: >- ret = 0; >- break; >- case 0: >- ret = SSH_ERR_SIGNATURE_INVALID; >+ if ((sigb = malloc(len)) == NULL) { >+ ret = SSH_ERR_ALLOC_FAIL; > goto out; >- default: >+ } >+ psig = sigb; >+ if ((len = i2d_ECDSA_SIG(sig, &psig)) == 0) { > ret = SSH_ERR_LIBCRYPTO_ERROR; > goto out; > } > >+ if (sshbuf_len(sigbuf) != 0) { >+ ret = SSH_ERR_UNEXPECTED_TRAILING_DATA; >+ goto out; >+ } >+ >+ ret = sshkey_verify_signature(key->pkey, hash_alg, data, datalen, >+ sigb, len); >+ > out: >- explicit_bzero(digest, sizeof(digest)); > sshbuf_free(sigbuf); > sshbuf_free(b); > ECDSA_SIG_free(sig); > BN_clear_free(sig_r); > BN_clear_free(sig_s); > free(ktype); >+ free(sigb); > return ret; > } > >diff --git a/ssh-keygen.c b/ssh-keygen.c >index d7249bd4..f5af0d9b 100644 >--- a/ssh-keygen.c >+++ b/ssh-keygen.c >@@ -328,16 +328,16 @@ do_convert_to_pkcs8(struct sshkey *k) > { > switch (sshkey_type_plain(k->type)) { > case KEY_RSA: >- if (!PEM_write_RSA_PUBKEY(stdout, k->rsa)) >+ if (!PEM_write_RSA_PUBKEY(stdout, EVP_PKEY_get0_RSA(k->pkey))) > fatal("PEM_write_RSA_PUBKEY failed"); > break; > case KEY_DSA: >- if (!PEM_write_DSA_PUBKEY(stdout, k->dsa)) >+ if (!PEM_write_DSA_PUBKEY(stdout, EVP_PKEY_get0_DSA(k->pkey))) > fatal("PEM_write_DSA_PUBKEY failed"); > break; > #ifdef OPENSSL_HAS_ECC > case KEY_ECDSA: >- if (!PEM_write_EC_PUBKEY(stdout, k->ecdsa)) >+ if (!PEM_write_EC_PUBKEY(stdout, EVP_PKEY_get0_EC_KEY(k->pkey))) > fatal("PEM_write_EC_PUBKEY failed"); > break; > #endif >@@ -352,7 +352,7 @@ do_convert_to_pem(struct sshkey *k) > { > switch (sshkey_type_plain(k->type)) { > case KEY_RSA: >- if (!PEM_write_RSAPublicKey(stdout, k->rsa)) >+ if (!PEM_write_RSAPublicKey(stdout, EVP_PKEY_get1_RSA(k->pkey))) > fatal("PEM_write_RSAPublicKey failed"); > break; > default: >@@ -427,6 +427,9 @@ do_convert_private_ssh2_from_blob(u_char *blob, u_int blen) > BIGNUM *dsa_pub_key = NULL, *dsa_priv_key = NULL; > BIGNUM *rsa_n = NULL, *rsa_e = NULL, *rsa_d = NULL; > BIGNUM *rsa_p = NULL, *rsa_q = NULL, *rsa_iqmp = NULL; >+ RSA *rsa; >+ DSA *dsa; >+ > if ((b = sshbuf_from(blob, blen)) == NULL) > fatal("%s: sshbuf_from failed", __func__); > if ((r = sshbuf_get_u32(b, &magic)) != 0) >@@ -481,10 +484,11 @@ do_convert_private_ssh2_from_blob(u_char *blob, u_int blen) > buffer_get_bignum_bits(b, dsa_q); > buffer_get_bignum_bits(b, dsa_pub_key); > buffer_get_bignum_bits(b, dsa_priv_key); >- if (!DSA_set0_pqg(key->dsa, dsa_p, dsa_q, dsa_g)) >+ dsa = EVP_PKEY_get0_DSA(key->pkey); >+ if (!DSA_set0_pqg(dsa, dsa_p, dsa_q, dsa_g)) > fatal("%s: DSA_set0_pqg failed", __func__); > dsa_p = dsa_q = dsa_g = NULL; /* transferred */ >- if (!DSA_set0_key(key->dsa, dsa_pub_key, dsa_priv_key)) >+ if (!DSA_set0_key(dsa, dsa_pub_key, dsa_priv_key)) > fatal("%s: DSA_set0_key failed", __func__); > dsa_pub_key = dsa_priv_key = NULL; /* transferred */ > break; >@@ -522,10 +526,11 @@ do_convert_private_ssh2_from_blob(u_char *blob, u_int blen) > buffer_get_bignum_bits(b, rsa_iqmp); > buffer_get_bignum_bits(b, rsa_q); > buffer_get_bignum_bits(b, rsa_p); >- if (!RSA_set0_key(key->rsa, rsa_n, rsa_e, rsa_d)) >+ rsa = EVP_PKEY_get0_RSA(key->pkey); >+ if (!RSA_set0_key(rsa, rsa_n, rsa_e, rsa_d)) > fatal("%s: RSA_set0_key failed", __func__); > rsa_n = rsa_e = rsa_d = NULL; /* transferred */ >- if (!RSA_set0_factors(key->rsa, rsa_p, rsa_q)) >+ if (!RSA_set0_factors(rsa, rsa_p, rsa_q)) > fatal("%s: RSA_set0_factors failed", __func__); > rsa_p = rsa_q = NULL; /* transferred */ > if ((r = ssh_rsa_complete_crt_parameters(key, rsa_iqmp)) != 0) >@@ -643,21 +648,27 @@ do_convert_from_pkcs8(struct sshkey **k, int *private) > if ((*k = sshkey_new(KEY_UNSPEC)) == NULL) > fatal("sshkey_new failed"); > (*k)->type = KEY_RSA; >- (*k)->rsa = EVP_PKEY_get1_RSA(pubkey); >+ EVP_PKEY_free((*k)->pkey); >+ (*k)->pkey = pubkey; >+ pubkey = NULL; > break; > case EVP_PKEY_DSA: > if ((*k = sshkey_new(KEY_UNSPEC)) == NULL) > fatal("sshkey_new failed"); > (*k)->type = KEY_DSA; >- (*k)->dsa = EVP_PKEY_get1_DSA(pubkey); >+ EVP_PKEY_free((*k)->pkey); >+ (*k)->pkey = pubkey; >+ pubkey = NULL; > break; > #ifdef OPENSSL_HAS_ECC > case EVP_PKEY_EC: > if ((*k = sshkey_new(KEY_UNSPEC)) == NULL) > fatal("sshkey_new failed"); > (*k)->type = KEY_ECDSA; >- (*k)->ecdsa = EVP_PKEY_get1_EC_KEY(pubkey); >- (*k)->ecdsa_nid = sshkey_ecdsa_key_to_nid((*k)->ecdsa); >+ EVP_PKEY_free((*k)->pkey); >+ (*k)->pkey = pubkey; >+ pubkey = NULL; >+ (*k)->ecdsa_nid = sshkey_ecdsa_key_to_nid(*k); > break; > #endif > default: >@@ -680,7 +691,8 @@ do_convert_from_pem(struct sshkey **k, int *private) > if ((*k = sshkey_new(KEY_UNSPEC)) == NULL) > fatal("sshkey_new failed"); > (*k)->type = KEY_RSA; >- (*k)->rsa = rsa; >+ (*k)->pkey = EVP_PKEY_new(); >+ EVP_PKEY_set1_RSA((*k)->pkey, rsa); > fclose(fp); > return; > } >@@ -693,6 +705,9 @@ do_convert_from(struct passwd *pw) > struct sshkey *k = NULL; > int r, private = 0, ok = 0; > struct stat st; >+ RSA *rsa; >+ DSA *dsa; >+ EC_KEY *ecdsa; > > if (!have_identity) > ask_filename(pw, "Enter file in which the key is"); >@@ -721,17 +736,20 @@ do_convert_from(struct passwd *pw) > } else { > switch (k->type) { > case KEY_DSA: >- ok = PEM_write_DSAPrivateKey(stdout, k->dsa, NULL, >+ dsa = EVP_PKEY_get0_DSA(k->pkey); >+ ok = PEM_write_DSAPrivateKey(stdout, dsa, NULL, > NULL, 0, NULL, NULL); > break; > #ifdef OPENSSL_HAS_ECC > case KEY_ECDSA: >- ok = PEM_write_ECPrivateKey(stdout, k->ecdsa, NULL, >+ ecdsa = EVP_PKEY_get0_EC_KEY(k->pkey); >+ ok = PEM_write_ECPrivateKey(stdout, ecdsa, NULL, > NULL, 0, NULL, NULL); > break; > #endif > case KEY_RSA: >- ok = PEM_write_RSAPrivateKey(stdout, k->rsa, NULL, >+ rsa = EVP_PKEY_get0_RSA(k->pkey); >+ ok = PEM_write_RSAPrivateKey(stdout, rsa, NULL, > NULL, 0, NULL, NULL); > break; > default: >diff --git a/ssh-pkcs11-client.c b/ssh-pkcs11-client.c >index e7860de8..61164a1e 100644 >--- a/ssh-pkcs11-client.c >+++ b/ssh-pkcs11-client.c >@@ -130,9 +130,14 @@ rsa_encrypt(int flen, const u_char *from, u_char *to, RSA *rsa, int padding) > error("%s: sshkey_new failed", __func__); > goto fail; > } >+ key->pkey = EVP_PKEY_new(); >+ if (key->pkey == NULL) { >+ error("%s: EVP_PKEY_new failed", __func__); >+ goto fail; >+ } >+ > key->type = KEY_RSA; >- RSA_up_ref(rsa); >- key->rsa = rsa; >+ EVP_PKEY_set1_RSA(key->pkey, rsa); > if ((r = sshkey_to_blob(key, &blob, &blen)) != 0) { > error("%s: sshkey_to_blob: %s", __func__, ssh_err(r)); > goto fail; >@@ -174,24 +179,24 @@ ecdsa_do_sign(const unsigned char *dgst, int dgst_len, const BIGNUM *inv, > const u_char *cp; > u_char *blob = NULL, *signature = NULL; > size_t blen, slen = 0; >- int r, nid; >- >- nid = sshkey_ecdsa_key_to_nid(ec); >- if (nid < 0) { >- error("%s: couldn't get curve nid", __func__); >- goto fail; >- } >+ int r; > > key = sshkey_new(KEY_UNSPEC); > if (key == NULL) { > error("%s: sshkey_new failed", __func__); > goto fail; > } >- key->ecdsa = ec; >- key->ecdsa_nid = nid; >+ > key->type = KEY_ECDSA; >+ EVP_PKEY_set1_EC_KEY(key->pkey, ec); > EC_KEY_up_ref(ec); > >+ key->ecdsa_nid = sshkey_ecdsa_key_to_nid(key); >+ if (key->ecdsa_nid < 0) { >+ error("%s: couldn't get curve nid", __func__); >+ goto fail; >+ } >+ > if ((r = sshkey_to_blob(key, &blob, &blen)) != 0) { > error("%s: sshkey_to_blob: %s", __func__, ssh_err(r)); > goto fail; >@@ -231,13 +236,15 @@ static EC_KEY_METHOD *helper_ecdsa; > static void > wrap_key(struct sshkey *k) > { >- if (k->type == KEY_RSA) >- RSA_set_method(k->rsa, helper_rsa); >+ if (k->type == KEY_RSA) { >+ RSA *rsa = EVP_PKEY_get0_RSA(k->pkey); >+ RSA_set_method(rsa, helper_rsa); > #ifdef HAVE_EC_KEY_METHOD_NEW >- else if (k->type == KEY_ECDSA) >- EC_KEY_set_method(k->ecdsa, helper_ecdsa); >+ } else if (k->type == KEY_ECDSA) { >+ EC_KEY *ecdsa = EVP_PKEY_get0_EC_KEY(k->pkey); >+ EC_KEY_set_method(ecdsa, helper_ecdsa); > #endif /* HAVE_EC_KEY_METHOD_NEW */ >- else >+ } else > fatal("%s: unknown key type", __func__); > } > >diff --git a/ssh-pkcs11-helper.c b/ssh-pkcs11-helper.c >index b6ee9403..4bac47a3 100644 >--- a/ssh-pkcs11-helper.c >+++ b/ssh-pkcs11-helper.c >@@ -39,6 +39,10 @@ > #include "ssh-pkcs11.h" > #include "ssherr.h" > >+#ifdef WITH_OPENSSL >+#include <openssl/rsa.h> >+#endif >+ > #ifdef ENABLE_PKCS11 > > /* borrows code from sftp-server and ssh-agent */ >@@ -200,20 +204,22 @@ process_sign(void) > > pkcs11_refresh_key(found); > if (key->type == KEY_RSA) { >- slen = RSA_size(key->rsa); >+ RSA *rsa = EVP_PKEY_get0_RSA(found->pkey); >+ slen = RSA_size(rsa); > signature = xmalloc(slen); > ret = RSA_private_encrypt(dlen, data, signature, >- found->rsa, RSA_PKCS1_PADDING); >+ rsa, RSA_PKCS1_PADDING); > if (ret != -1) { > slen = ret; > ok = 0; > } > } else if (key->type == KEY_ECDSA) { >- xslen = ECDSA_size(key->ecdsa); >+ EC_KEY *ecdsa = EVP_PKEY_get0_EC_KEY(found->pkey); >+ xslen = ECDSA_size(ecdsa); > signature = xmalloc(xslen); > /* "The parameter type is ignored." */ > ret = ECDSA_sign(-1, data, dlen, signature, >- &xslen, found->ecdsa); >+ &xslen, ecdsa); > if (ret != 0) > ok = 0; > else >diff --git a/ssh-pkcs11.c b/ssh-pkcs11.c >index 214b8558..e889710e 100644 >--- a/ssh-pkcs11.c >+++ b/ssh-pkcs11.c >@@ -399,24 +399,28 @@ static int pkcs11_reload_key(struct sshkey *key, struct pkcs11_key *k11) > > int pkcs11_refresh_key(struct sshkey *key) > { >- struct pkcs11_key *k11; >+ struct pkcs11_key *k11 = NULL; >+ RSA *rsa; >+ EC_KEY *ecdsa; > > switch (key->type) { > case KEY_RSA: >- if ((k11 = RSA_get_ex_data(key->rsa, rsa_idx)) == NULL) { >- error("RSA_get_ex_data failed for rsa %p", key->rsa); >+ if ((rsa = EVP_PKEY_get0_RSA(key->pkey)) == NULL || >+ (k11 = RSA_get_ex_data(rsa, rsa_idx)) == NULL) { >+ error("RSA_get_ex_data failed for rsa %p", rsa); > return (-1); > } > break; > case KEY_ECDSA: >- if ((k11 = EC_KEY_get_ex_data(key->ecdsa, ec_key_idx)) == NULL) { >- error("EC_KEY_get_ex_data failed for ecdsa %p", key->ecdsa); >+ if ((ecdsa = EVP_PKEY_get0_EC_KEY(key->pkey)) == NULL || >+ (k11 = EC_KEY_get_ex_data(ecdsa, ec_key_idx)) == NULL) { >+ error("EC_KEY_get_ex_data failed for ecdsa %p", ecdsa); > return (-1); > } > break; > } >- if (!k11->provider || !k11->provider->valid) { >- error("no pkcs11 (valid) provider for rsa %p", key->rsa); >+ if (!k11 || !k11->provider || !k11->provider->valid) { >+ error("no pkcs11 (valid) provider for key"); > return (-1); > } > >@@ -817,7 +821,6 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, > struct sshkey *key = NULL; > const unsigned char *attrp = NULL; > int i; >- int nid; > > memset(&key_attr, 0, sizeof(key_attr)); > key_attr[0].type = CKA_ID; >@@ -892,12 +895,6 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, > goto fail; > } > >- nid = sshkey_ecdsa_key_to_nid(ec); >- if (nid < 0) { >- error("couldn't get curve nid"); >- goto fail; >- } >- > if (pkcs11_ecdsa_wrap(p, slotidx, &key_attr[0], ec)) > goto fail; > >@@ -906,13 +903,18 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, > error("sshkey_new failed"); > goto fail; > } >- >- key->ecdsa = ec; >- key->ecdsa_nid = nid; > key->type = KEY_ECDSA; > key->flags |= SSHKEY_FLAG_EXT; >+ EVP_PKEY_set1_EC_KEY(key->pkey, ec); > ec = NULL; /* now owned by key */ > >+ key->ecdsa_nid = sshkey_ecdsa_key_to_nid(key); >+ if (key->ecdsa_nid < 0) { >+ error("couldn't get curve nid"); >+ goto fail; >+ } >+ >+ > fail: > for (i = 0; i < 3; i++) > free(key_attr[i].pValue); >@@ -1003,7 +1005,12 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, > goto fail; > } > >- key->rsa = rsa; >+ key->pkey = EVP_PKEY_new(); >+ if (key == NULL) { >+ error("EVP_PKEY_new failed"); >+ goto fail; >+ } >+ EVP_PKEY_set1_RSA(key->pkey, rsa); > key->type = KEY_RSA; > key->flags |= SSHKEY_FLAG_EXT; > rsa = NULL; /* now owned by key */ >@@ -1030,9 +1037,6 @@ 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)); >@@ -1109,8 +1113,11 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, > error("sshkey_new failed"); > goto fail; > } >- >- key->rsa = rsa; >+ if (key == NULL) { >+ error("EVP_PKEY_new failed"); >+ goto fail; >+ } >+ EVP_PKEY_set1_RSA(key->pkey, rsa); > key->type = KEY_RSA; > key->flags |= SSHKEY_FLAG_EXT; > rsa = NULL; /* now owned by key */ >@@ -1125,12 +1132,6 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, > goto fail; > } > >- nid = sshkey_ecdsa_key_to_nid(ec); >- if (nid < 0) { >- error("couldn't get curve nid"); >- goto fail; >- } >- > if (pkcs11_ecdsa_wrap(p, slotidx, &cert_attr[0], ec)) > goto fail; > >@@ -1139,12 +1140,17 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, > error("sshkey_new failed"); > goto fail; > } >- >- key->ecdsa = ec; >- key->ecdsa_nid = nid; > key->type = KEY_ECDSA; > key->flags |= SSHKEY_FLAG_EXT; >+ EVP_PKEY_set1_EC_KEY(key->pkey, ec); > ec = NULL; /* now owned by key */ >+ >+ key->ecdsa_nid = sshkey_ecdsa_key_to_nid(key); >+ if (key->ecdsa_nid < 0) { >+ error("couldn't get curve nid"); >+ goto fail; >+ } >+ > #endif /* HAVE_EC_KEY_METHOD_NEW */ > } else > error("unknown certificate key type"); >diff --git a/ssh-rsa.c b/ssh-rsa.c >index 9b14f9a9..fd5eb2a7 100644 >--- a/ssh-rsa.c >+++ b/ssh-rsa.c >@@ -37,7 +37,7 @@ > > #include "openbsd-compat/openssl-compat.h" > >-static int openssh_RSA_verify(int, u_char *, size_t, u_char *, size_t, RSA *); >+static int openssh_RSA_verify(int, const u_char *, size_t, u_char *, size_t, EVP_PKEY *); > > static const char * > rsa_hash_alg_ident(int hash_alg) >@@ -90,21 +90,6 @@ rsa_hash_id_from_keyname(const char *alg) > return -1; > } > >-static int >-rsa_hash_alg_nid(int type) >-{ >- switch (type) { >- case SSH_DIGEST_SHA1: >- return NID_sha1; >- case SSH_DIGEST_SHA256: >- return NID_sha256; >- case SSH_DIGEST_SHA512: >- return NID_sha512; >- default: >- return -1; >- } >-} >- > int > ssh_rsa_complete_crt_parameters(struct sshkey *key, const BIGNUM *iqmp) > { >@@ -112,14 +97,16 @@ ssh_rsa_complete_crt_parameters(struct sshkey *key, const BIGNUM *iqmp) > BIGNUM *aux = NULL, *d_consttime = NULL; > BIGNUM *rsa_dmq1 = NULL, *rsa_dmp1 = NULL, *rsa_iqmp = NULL; > BN_CTX *ctx = NULL; >+ RSA *rsa; > int r; > >- if (key == NULL || key->rsa == NULL || >+ rsa = EVP_PKEY_get0_RSA(key->pkey); >+ if (key == NULL || rsa == NULL || > sshkey_type_plain(key->type) != KEY_RSA) > return SSH_ERR_INVALID_ARGUMENT; > >- RSA_get0_key(key->rsa, NULL, NULL, &rsa_d); >- RSA_get0_factors(key->rsa, &rsa_p, &rsa_q); >+ RSA_get0_key(rsa, NULL, NULL, &rsa_d); >+ RSA_get0_factors(rsa, &rsa_p, &rsa_q); > > if ((ctx = BN_CTX_new()) == NULL) > return SSH_ERR_ALLOC_FAIL; >@@ -142,7 +129,7 @@ ssh_rsa_complete_crt_parameters(struct sshkey *key, const BIGNUM *iqmp) > r = SSH_ERR_LIBCRYPTO_ERROR; > goto out; > } >- if (!RSA_set0_crt_params(key->rsa, rsa_dmp1, rsa_dmq1, rsa_iqmp)) { >+ if (!RSA_set0_crt_params(rsa, rsa_dmp1, rsa_dmq1, rsa_iqmp)) { > r = SSH_ERR_LIBCRYPTO_ERROR; > goto out; > } >@@ -164,11 +151,10 @@ int > ssh_rsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp, > const u_char *data, size_t datalen, const char *alg_ident) > { >- const BIGNUM *rsa_n; >- u_char digest[SSH_DIGEST_MAX_LENGTH], *sig = NULL; >- size_t slen = 0; >- u_int dlen, len; >- int nid, hash_alg, ret = SSH_ERR_INTERNAL_ERROR; >+ const RSA *rsa; >+ u_char *sig = NULL; >+ int len, slen = 0; >+ int hash_alg, ret = SSH_ERR_INTERNAL_ERROR; > struct sshbuf *b = NULL; > > if (lenp != NULL) >@@ -180,33 +166,21 @@ ssh_rsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp, > hash_alg = SSH_DIGEST_SHA1; > else > hash_alg = rsa_hash_id_from_keyname(alg_ident); >- if (key == NULL || key->rsa == NULL || hash_alg == -1 || >+ >+ rsa = EVP_PKEY_get0_RSA(key->pkey); >+ if (key == NULL || rsa == NULL || hash_alg == -1 || > sshkey_type_plain(key->type) != KEY_RSA) > return SSH_ERR_INVALID_ARGUMENT; >- RSA_get0_key(key->rsa, &rsa_n, NULL, NULL); >- if (BN_num_bits(rsa_n) < SSH_RSA_MINIMUM_MODULUS_SIZE) >+ slen = RSA_size(rsa); >+ if (RSA_bits(rsa) < SSH_RSA_MINIMUM_MODULUS_SIZE) > return SSH_ERR_KEY_LENGTH; >- slen = RSA_size(key->rsa); >- if (slen <= 0 || slen > SSHBUF_MAX_BIGNUM) >- return SSH_ERR_INVALID_ARGUMENT; > >- /* hash the data */ >- nid = rsa_hash_alg_nid(hash_alg); >- if ((dlen = ssh_digest_bytes(hash_alg)) == 0) >- return SSH_ERR_INTERNAL_ERROR; >- if ((ret = ssh_digest_memory(hash_alg, data, datalen, >- digest, sizeof(digest))) != 0) >- goto out; >- >- if ((sig = malloc(slen)) == NULL) { >- ret = SSH_ERR_ALLOC_FAIL; >+ ret = sshkey_calculate_signature(key->pkey, hash_alg, &sig, &len, data, >+ datalen); >+ if (ret < 0) { > goto out; > } > >- if (RSA_sign(nid, digest, dlen, sig, &len, key->rsa) != 1) { >- ret = SSH_ERR_LIBCRYPTO_ERROR; >- goto out; >- } > if (len < slen) { > size_t diff = slen - len; > memmove(sig + diff, sig, len); >@@ -215,6 +189,7 @@ ssh_rsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp, > ret = SSH_ERR_INTERNAL_ERROR; > goto out; > } >+ > /* encode signature */ > if ((b = sshbuf_new()) == NULL) { > ret = SSH_ERR_ALLOC_FAIL; >@@ -235,7 +210,6 @@ ssh_rsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp, > *lenp = len; > ret = 0; > out: >- explicit_bzero(digest, sizeof(digest)); > freezero(sig, slen); > sshbuf_free(b); > return ret; >@@ -246,19 +220,19 @@ ssh_rsa_verify(const struct sshkey *key, > const u_char *sig, size_t siglen, const u_char *data, size_t datalen, > const char *alg) > { >- const BIGNUM *rsa_n; >+ const RSA *rsa; > char *sigtype = NULL; > int hash_alg, want_alg, ret = SSH_ERR_INTERNAL_ERROR; >- size_t len = 0, diff, modlen, dlen; >+ size_t len = 0, diff, modlen; > struct sshbuf *b = NULL; > u_char digest[SSH_DIGEST_MAX_LENGTH], *osigblob, *sigblob = NULL; > >- if (key == NULL || key->rsa == NULL || >+ rsa = EVP_PKEY_get0_RSA(key->pkey); >+ if (key == NULL || rsa == NULL || > sshkey_type_plain(key->type) != KEY_RSA || > sig == NULL || siglen == 0) > return SSH_ERR_INVALID_ARGUMENT; >- RSA_get0_key(key->rsa, &rsa_n, NULL, NULL); >- if (BN_num_bits(rsa_n) < SSH_RSA_MINIMUM_MODULUS_SIZE) >+ if (RSA_bits(rsa) < SSH_RSA_MINIMUM_MODULUS_SIZE) > return SSH_ERR_KEY_LENGTH; > > if ((b = sshbuf_from(sig, siglen)) == NULL) >@@ -294,7 +268,7 @@ ssh_rsa_verify(const struct sshkey *key, > goto out; > } > /* RSA_verify expects a signature of RSA_size */ >- modlen = RSA_size(key->rsa); >+ modlen = RSA_size(rsa); > if (len > modlen) { > ret = SSH_ERR_KEY_BITS_MISMATCH; > goto out; >@@ -310,16 +284,9 @@ ssh_rsa_verify(const struct sshkey *key, > explicit_bzero(sigblob, diff); > len = modlen; > } >- if ((dlen = ssh_digest_bytes(hash_alg)) == 0) { >- ret = SSH_ERR_INTERNAL_ERROR; >- goto out; >- } >- if ((ret = ssh_digest_memory(hash_alg, data, datalen, >- digest, sizeof(digest))) != 0) >- goto out; > >- ret = openssh_RSA_verify(hash_alg, digest, dlen, sigblob, len, >- key->rsa); >+ ret = openssh_RSA_verify(hash_alg, data, datalen, sigblob, len, >+ key->pkey); > out: > freezero(sigblob, len); > free(sigtype); >@@ -328,122 +295,26 @@ ssh_rsa_verify(const struct sshkey *key, > return ret; > } > >-/* >- * See: >- * http://www.rsasecurity.com/rsalabs/pkcs/pkcs-1/ >- * ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1.asn >- */ >- >-/* >- * id-sha1 OBJECT IDENTIFIER ::= { iso(1) identified-organization(3) >- * oiw(14) secsig(3) algorithms(2) 26 } >- */ >-static const u_char id_sha1[] = { >- 0x30, 0x21, /* type Sequence, length 0x21 (33) */ >- 0x30, 0x09, /* type Sequence, length 0x09 */ >- 0x06, 0x05, /* type OID, length 0x05 */ >- 0x2b, 0x0e, 0x03, 0x02, 0x1a, /* id-sha1 OID */ >- 0x05, 0x00, /* NULL */ >- 0x04, 0x14 /* Octet string, length 0x14 (20), followed by sha1 hash */ >-}; >- >-/* >- * See http://csrc.nist.gov/groups/ST/crypto_apps_infra/csor/algorithms.html >- * id-sha256 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) >- * organization(1) gov(101) csor(3) nistAlgorithm(4) hashAlgs(2) >- * id-sha256(1) } >- */ >-static const u_char id_sha256[] = { >- 0x30, 0x31, /* type Sequence, length 0x31 (49) */ >- 0x30, 0x0d, /* type Sequence, length 0x0d (13) */ >- 0x06, 0x09, /* type OID, length 0x09 */ >- 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, /* id-sha256 */ >- 0x05, 0x00, /* NULL */ >- 0x04, 0x20 /* Octet string, length 0x20 (32), followed by sha256 hash */ >-}; >- >-/* >- * See http://csrc.nist.gov/groups/ST/crypto_apps_infra/csor/algorithms.html >- * id-sha512 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) >- * organization(1) gov(101) csor(3) nistAlgorithm(4) hashAlgs(2) >- * id-sha256(3) } >- */ >-static const u_char id_sha512[] = { >- 0x30, 0x51, /* type Sequence, length 0x51 (81) */ >- 0x30, 0x0d, /* type Sequence, length 0x0d (13) */ >- 0x06, 0x09, /* type OID, length 0x09 */ >- 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, /* id-sha512 */ >- 0x05, 0x00, /* NULL */ >- 0x04, 0x40 /* Octet string, length 0x40 (64), followed by sha512 hash */ >-}; >- > static int >-rsa_hash_alg_oid(int hash_alg, const u_char **oidp, size_t *oidlenp) >+openssh_RSA_verify(int hash_alg, const u_char *data, size_t datalen, >+ u_char *sigbuf, size_t siglen, EVP_PKEY *pkey) > { >- switch (hash_alg) { >- case SSH_DIGEST_SHA1: >- *oidp = id_sha1; >- *oidlenp = sizeof(id_sha1); >- break; >- case SSH_DIGEST_SHA256: >- *oidp = id_sha256; >- *oidlenp = sizeof(id_sha256); >- break; >- case SSH_DIGEST_SHA512: >- *oidp = id_sha512; >- *oidlenp = sizeof(id_sha512); >- break; >- default: >- return SSH_ERR_INVALID_ARGUMENT; >- } >- return 0; >-} >+ size_t rsasize = 0; >+ const RSA *rsa; >+ int ret; > >-static int >-openssh_RSA_verify(int hash_alg, u_char *hash, size_t hashlen, >- u_char *sigbuf, size_t siglen, RSA *rsa) >-{ >- size_t rsasize = 0, oidlen = 0, hlen = 0; >- int ret, len, oidmatch, hashmatch; >- const u_char *oid = NULL; >- u_char *decrypted = NULL; >- >- if ((ret = rsa_hash_alg_oid(hash_alg, &oid, &oidlen)) != 0) >- return ret; >- ret = SSH_ERR_INTERNAL_ERROR; >- hlen = ssh_digest_bytes(hash_alg); >- if (hashlen != hlen) { >- ret = SSH_ERR_INVALID_ARGUMENT; >- goto done; >- } >+ rsa = EVP_PKEY_get0_RSA(pkey); > rsasize = RSA_size(rsa); > if (rsasize <= 0 || rsasize > SSHBUF_MAX_BIGNUM || > siglen == 0 || siglen > rsasize) { > ret = SSH_ERR_INVALID_ARGUMENT; > goto done; > } >- if ((decrypted = malloc(rsasize)) == NULL) { >- ret = SSH_ERR_ALLOC_FAIL; >- goto done; >- } >- if ((len = RSA_public_decrypt(siglen, sigbuf, decrypted, rsa, >- RSA_PKCS1_PADDING)) < 0) { >- ret = SSH_ERR_LIBCRYPTO_ERROR; >- goto done; >- } >- if (len < 0 || (size_t)len != hlen + oidlen) { >- ret = SSH_ERR_INVALID_FORMAT; >- goto done; >- } >- oidmatch = timingsafe_bcmp(decrypted, oid, oidlen) == 0; >- hashmatch = timingsafe_bcmp(decrypted + oidlen, hash, hlen) == 0; >- if (!oidmatch || !hashmatch) { >- ret = SSH_ERR_SIGNATURE_INVALID; >- goto done; >- } >- ret = 0; >+ >+ ret = sshkey_verify_signature(pkey, hash_alg, data, datalen, >+ sigbuf, siglen); >+ > done: >- freezero(decrypted, rsasize); > return ret; > } > #endif /* WITH_OPENSSL */ >diff --git a/sshkey.c b/sshkey.c >index ad195776..030e03cf 100644 >--- a/sshkey.c >+++ b/sshkey.c >@@ -285,21 +285,25 @@ sshkey_size(const struct sshkey *k) > { > #ifdef WITH_OPENSSL > const BIGNUM *rsa_n, *dsa_p; >+ RSA *rsa = NULL; >+ DSA *dsa = NULL; > #endif /* WITH_OPENSSL */ > > switch (k->type) { > #ifdef WITH_OPENSSL > case KEY_RSA: > case KEY_RSA_CERT: >- if (k->rsa == NULL) >+ rsa = EVP_PKEY_get0_RSA(k->pkey); >+ if (rsa == NULL) > return 0; >- RSA_get0_key(k->rsa, &rsa_n, NULL, NULL); >+ RSA_get0_key(rsa, &rsa_n, NULL, NULL); > return BN_num_bits(rsa_n); > case KEY_DSA: > case KEY_DSA_CERT: >- if (k->dsa == NULL) >+ dsa = EVP_PKEY_get0_DSA(k->pkey); >+ if (dsa == NULL) > return 0; >- DSA_get0_pqg(k->dsa, &dsa_p, NULL, NULL); >+ DSA_get0_pqg(dsa, &dsa_p, NULL, NULL); > return BN_num_bits(dsa_p); > case KEY_ECDSA: > case KEY_ECDSA_CERT: >@@ -358,6 +362,83 @@ sshkey_type_plain(int type) > } > > #ifdef WITH_OPENSSL >+int >+sshkey_calculate_signature(EVP_PKEY *pkey, int hash_alg, u_char **sigp, >+ int *lenp, const u_char *data, size_t datalen) >+{ >+ EVP_MD_CTX *ctx = NULL; >+ u_char *sig = NULL; >+ int ret, slen, len; >+ >+ if (sigp == NULL || lenp == NULL) { >+ return SSH_ERR_INVALID_ARGUMENT; >+ } >+ >+ slen = EVP_PKEY_size(pkey); >+ if (slen <= 0 || slen > SSHBUF_MAX_BIGNUM) >+ return SSH_ERR_INVALID_ARGUMENT; >+ >+ len = slen; >+ if ((sig = malloc(slen)) == NULL) { >+ return SSH_ERR_ALLOC_FAIL; >+ } >+ >+ if ((ctx = EVP_MD_CTX_new()) == NULL) { >+ ret = SSH_ERR_ALLOC_FAIL; >+ goto error; >+ } >+ if (EVP_SignInit_ex(ctx, ssh_digest_to_md(hash_alg), NULL) <= 0 || >+ EVP_SignUpdate(ctx, data, datalen) <= 0 || >+ EVP_SignFinal(ctx, sig, &len, pkey) <= 0) { >+ ret = SSH_ERR_LIBCRYPTO_ERROR; >+ goto error; >+ } >+ >+ *sigp = sig; >+ *lenp = len; >+ /* Now owned by the caller */ >+ sig = NULL; >+ ret = 0; >+ >+error: >+ EVP_MD_CTX_free(ctx); >+ free(sig); >+ return ret; >+} >+ >+int >+sshkey_verify_signature(EVP_PKEY *pkey, int hash_alg, const u_char *data, >+ size_t datalen, u_char *sigbuf, int siglen) >+{ >+ EVP_MD_CTX *ctx = NULL; >+ int ret; >+ >+ if ((ctx = EVP_MD_CTX_new()) == NULL) { >+ return SSH_ERR_ALLOC_FAIL; >+ } >+ if (EVP_VerifyInit_ex(ctx, ssh_digest_to_md(hash_alg), NULL) <= 0 || >+ EVP_VerifyUpdate(ctx, data, datalen) <= 0) { >+ ret = SSH_ERR_LIBCRYPTO_ERROR; >+ goto done; >+ } >+ ret = EVP_VerifyFinal(ctx, sigbuf, siglen, pkey); >+ switch (ret) { >+ case 1: >+ ret = 0; >+ break; >+ case 0: >+ ret = SSH_ERR_SIGNATURE_INVALID; >+ break; >+ default: >+ ret = SSH_ERR_LIBCRYPTO_ERROR; >+ break; >+ } >+ >+done: >+ EVP_MD_CTX_free(ctx); >+ return ret; >+} >+ > /* XXX: these are really begging for a table-driven approach */ > int > sshkey_curve_name_to_nid(const char *name) >@@ -494,10 +575,8 @@ sshkey_new(int type) > if ((k = calloc(1, sizeof(*k))) == NULL) > return NULL; > k->type = type; >- k->ecdsa = NULL; > k->ecdsa_nid = -1; >- k->dsa = NULL; >- k->rsa = NULL; >+ k->pkey = NULL; > k->cert = NULL; > k->ed25519_sk = NULL; > k->ed25519_pk = NULL; >@@ -507,22 +586,46 @@ sshkey_new(int type) > #ifdef WITH_OPENSSL > case KEY_RSA: > case KEY_RSA_CERT: >+ if ((k->pkey = EVP_PKEY_new()) == NULL) { >+ free(k); >+ return NULL; >+ } > if ((rsa = RSA_new()) == NULL) { >+ EVP_PKEY_free(k->pkey); > free(k); > return NULL; > } >- k->rsa = rsa; >+ if (EVP_PKEY_set1_RSA(k->pkey, rsa) != 1) { >+ EVP_PKEY_free(k->pkey); >+ free(k); >+ RSA_free(rsa); >+ return NULL; >+ } > break; > case KEY_DSA: > case KEY_DSA_CERT: >+ if ((k->pkey = EVP_PKEY_new()) == NULL) { >+ free(k); >+ return NULL; >+ } > if ((dsa = DSA_new()) == NULL) { >+ EVP_PKEY_free(k->pkey); >+ free(k); >+ return NULL; >+ } >+ if (EVP_PKEY_set1_DSA(k->pkey, dsa) != 1) { >+ EVP_PKEY_free(k->pkey); >+ DSA_free(dsa); > free(k); > return NULL; > } >- k->dsa = dsa; > break; > case KEY_ECDSA: > case KEY_ECDSA_CERT: >+ if ((k->pkey = EVP_PKEY_new()) == NULL) { >+ free(k); >+ return NULL; >+ } > /* Cannot do anything until we know the group */ > break; > #endif /* WITH_OPENSSL */ >@@ -558,21 +661,15 @@ sshkey_free(struct sshkey *k) > #ifdef WITH_OPENSSL > case KEY_RSA: > case KEY_RSA_CERT: >- RSA_free(k->rsa); >- k->rsa = NULL; >- break; > case KEY_DSA: > case KEY_DSA_CERT: >- DSA_free(k->dsa); >- k->dsa = NULL; >- break; > # ifdef OPENSSL_HAS_ECC > case KEY_ECDSA: > case KEY_ECDSA_CERT: >- EC_KEY_free(k->ecdsa); >- k->ecdsa = NULL; >- break; > # endif /* OPENSSL_HAS_ECC */ >+ EVP_PKEY_free(k->pkey); >+ k->pkey = NULL; >+ break; > #endif /* WITH_OPENSSL */ > case KEY_ED25519: > case KEY_ED25519_CERT: >@@ -628,6 +725,9 @@ int > sshkey_equal_public(const struct sshkey *a, const struct sshkey *b) > { > #if defined(WITH_OPENSSL) >+ const RSA *rsa_a, *rsa_b; >+ const DSA *dsa_a, *dsa_b; >+ const EC_KEY *ecdsa_a, *ecdsa_b; > const BIGNUM *rsa_e_a, *rsa_n_a; > const BIGNUM *rsa_e_b, *rsa_n_b; > const BIGNUM *dsa_p_a, *dsa_q_a, *dsa_g_a, *dsa_pub_key_a; >@@ -645,20 +745,24 @@ sshkey_equal_public(const struct sshkey *a, const struct sshkey *b) > #ifdef WITH_OPENSSL > case KEY_RSA_CERT: > case KEY_RSA: >- if (a->rsa == NULL || b->rsa == NULL) >+ rsa_a = EVP_PKEY_get0_RSA(a->pkey); >+ rsa_b = EVP_PKEY_get0_RSA(b->pkey); >+ if (rsa_a == NULL || rsa_b == NULL) > return 0; >- RSA_get0_key(a->rsa, &rsa_n_a, &rsa_e_a, NULL); >- RSA_get0_key(b->rsa, &rsa_n_b, &rsa_e_b, NULL); >+ RSA_get0_key(rsa_a, &rsa_n_a, &rsa_e_a, NULL); >+ RSA_get0_key(rsa_b, &rsa_n_b, &rsa_e_b, NULL); > return BN_cmp(rsa_e_a, rsa_e_b) == 0 && > BN_cmp(rsa_n_a, rsa_n_b) == 0; > case KEY_DSA_CERT: > case KEY_DSA: >- if (a->dsa == NULL || b->dsa == NULL) >+ dsa_a = EVP_PKEY_get0_DSA(a->pkey); >+ dsa_b = EVP_PKEY_get0_DSA(b->pkey); >+ if (dsa_a == NULL || dsa_b == NULL) > return 0; >- DSA_get0_pqg(a->dsa, &dsa_p_a, &dsa_q_a, &dsa_g_a); >- DSA_get0_pqg(b->dsa, &dsa_p_b, &dsa_q_b, &dsa_g_b); >- DSA_get0_key(a->dsa, &dsa_pub_key_a, NULL); >- DSA_get0_key(b->dsa, &dsa_pub_key_b, NULL); >+ DSA_get0_pqg(dsa_a, &dsa_p_a, &dsa_q_a, &dsa_g_a); >+ DSA_get0_pqg(dsa_b, &dsa_p_b, &dsa_q_b, &dsa_g_b); >+ DSA_get0_key(dsa_a, &dsa_pub_key_a, NULL); >+ DSA_get0_key(dsa_b, &dsa_pub_key_b, NULL); > return BN_cmp(dsa_p_a, dsa_p_b) == 0 && > BN_cmp(dsa_q_a, dsa_q_b) == 0 && > BN_cmp(dsa_g_a, dsa_g_b) == 0 && >@@ -666,17 +770,19 @@ sshkey_equal_public(const struct sshkey *a, const struct sshkey *b) > # ifdef OPENSSL_HAS_ECC > case KEY_ECDSA_CERT: > case KEY_ECDSA: >- if (a->ecdsa == NULL || b->ecdsa == NULL || >- EC_KEY_get0_public_key(a->ecdsa) == NULL || >- EC_KEY_get0_public_key(b->ecdsa) == NULL) >+ ecdsa_a = EVP_PKEY_get0_EC_KEY(a->pkey); >+ ecdsa_b = EVP_PKEY_get0_EC_KEY(b->pkey); >+ if (ecdsa_a == NULL || ecdsa_b == NULL || >+ EC_KEY_get0_public_key(ecdsa_a) == NULL || >+ EC_KEY_get0_public_key(ecdsa_b) == NULL) > return 0; > if ((bnctx = BN_CTX_new()) == NULL) > return 0; >- if (EC_GROUP_cmp(EC_KEY_get0_group(a->ecdsa), >- EC_KEY_get0_group(b->ecdsa), bnctx) != 0 || >- EC_POINT_cmp(EC_KEY_get0_group(a->ecdsa), >- EC_KEY_get0_public_key(a->ecdsa), >- EC_KEY_get0_public_key(b->ecdsa), bnctx) != 0) { >+ if (EC_GROUP_cmp(EC_KEY_get0_group(ecdsa_a), >+ EC_KEY_get0_group(ecdsa_b), bnctx) != 0 || >+ EC_POINT_cmp(EC_KEY_get0_group(ecdsa_a), >+ EC_KEY_get0_public_key(ecdsa_a), >+ EC_KEY_get0_public_key(ecdsa_b), bnctx) != 0) { > BN_CTX_free(bnctx); > return 0; > } >@@ -720,6 +826,9 @@ to_blob_buf(const struct sshkey *key, struct sshbuf *b, int force_plain, > int type, ret = SSH_ERR_INTERNAL_ERROR; > const char *typename; > #ifdef WITH_OPENSSL >+ const RSA *rsa; >+ const DSA *dsa; >+ const EC_KEY *ecdsa; > const BIGNUM *rsa_n, *rsa_e, *dsa_p, *dsa_q, *dsa_g, *dsa_pub_key; > #endif /* WITH_OPENSSL */ > >@@ -752,10 +861,11 @@ to_blob_buf(const struct sshkey *key, struct sshbuf *b, int force_plain, > break; > #ifdef WITH_OPENSSL > case KEY_DSA: >- if (key->dsa == NULL) >+ dsa = EVP_PKEY_get0_DSA(key->pkey); >+ if (dsa == NULL) > return SSH_ERR_INVALID_ARGUMENT; >- DSA_get0_pqg(key->dsa, &dsa_p, &dsa_q, &dsa_g); >- DSA_get0_key(key->dsa, &dsa_pub_key, NULL); >+ DSA_get0_pqg(dsa, &dsa_p, &dsa_q, &dsa_g); >+ DSA_get0_key(dsa, &dsa_pub_key, NULL); > if ((ret = sshbuf_put_cstring(b, typename)) != 0 || > (ret = sshbuf_put_bignum2(b, dsa_p)) != 0 || > (ret = sshbuf_put_bignum2(b, dsa_q)) != 0 || >@@ -765,19 +875,21 @@ to_blob_buf(const struct sshkey *key, struct sshbuf *b, int force_plain, > break; > # ifdef OPENSSL_HAS_ECC > case KEY_ECDSA: >- if (key->ecdsa == NULL) >+ ecdsa = EVP_PKEY_get0_EC_KEY(key->pkey); >+ if (ecdsa == NULL) > return SSH_ERR_INVALID_ARGUMENT; > if ((ret = sshbuf_put_cstring(b, typename)) != 0 || > (ret = sshbuf_put_cstring(b, > sshkey_curve_nid_to_name(key->ecdsa_nid))) != 0 || >- (ret = sshbuf_put_eckey(b, key->ecdsa)) != 0) >+ (ret = sshbuf_put_eckey(b, ecdsa)) != 0) > return ret; > break; > # endif > case KEY_RSA: >- if (key->rsa == NULL) >+ rsa = EVP_PKEY_get0_RSA(key->pkey); >+ if (rsa == NULL) > return SSH_ERR_INVALID_ARGUMENT; >- RSA_get0_key(key->rsa, &rsa_n, &rsa_e, NULL); >+ RSA_get0_key(rsa, &rsa_n, &rsa_e, NULL); > if ((ret = sshbuf_put_cstring(b, typename)) != 0 || > (ret = sshbuf_put_bignum2(b, rsa_e)) != 0 || > (ret = sshbuf_put_bignum2(b, rsa_n)) != 0) >@@ -1312,30 +1424,30 @@ sshkey_read(struct sshkey *ret, char **cpp) > switch (sshkey_type_plain(ret->type)) { > #ifdef WITH_OPENSSL > case KEY_RSA: >- RSA_free(ret->rsa); >- ret->rsa = k->rsa; >- k->rsa = NULL; >+ EVP_PKEY_free(ret->pkey); >+ ret->pkey = k->pkey; >+ k->pkey = NULL; > #ifdef DEBUG_PK >- RSA_print_fp(stderr, ret->rsa, 8); >+ RSA_print_fp(stderr, EVP_PKEY_get0_RSA(ret->pkey), 8); > #endif > break; > case KEY_DSA: >- DSA_free(ret->dsa); >- ret->dsa = k->dsa; >- k->dsa = NULL; >+ EVP_PKEY_free(ret->pkey); >+ ret->pkey = k->pkey; >+ k->pkey = NULL; > #ifdef DEBUG_PK >- DSA_print_fp(stderr, ret->dsa, 8); >+ DSA_print_fp(stderr, EVP_PKEY_get0_DSA(ret->pkey), 8); > #endif > break; > # ifdef OPENSSL_HAS_ECC > case KEY_ECDSA: >- EC_KEY_free(ret->ecdsa); >- ret->ecdsa = k->ecdsa; >+ EVP_PKEY_free(ret->pkey); >+ ret->pkey = k->pkey; > ret->ecdsa_nid = k->ecdsa_nid; >- k->ecdsa = NULL; >+ k->pkey = NULL; > k->ecdsa_nid = -1; > #ifdef DEBUG_PK >- sshkey_dump_ec_key(ret->ecdsa); >+ sshkey_dump_ec_key(EVP_PKEY_get0_EC_KEY(ret->pkey)); > #endif > break; > # endif /* OPENSSL_HAS_ECC */ >@@ -1463,18 +1575,18 @@ sshkey_cert_type(const struct sshkey *k) > > #ifdef WITH_OPENSSL > static int >-rsa_generate_private_key(u_int bits, RSA **rsap) >+rsa_generate_private_key(u_int bits, EVP_PKEY **pkeyp) > { > RSA *private = NULL; > BIGNUM *f4 = NULL; > int ret = SSH_ERR_INTERNAL_ERROR; > >- if (rsap == NULL) >+ if (pkeyp == NULL) > return SSH_ERR_INVALID_ARGUMENT; > if (bits < SSH_RSA_MINIMUM_MODULUS_SIZE || > bits > SSHBUF_MAX_BIGNUM * 8) > return SSH_ERR_KEY_LENGTH; >- *rsap = NULL; >+ *pkeyp = NULL; > if ((private = RSA_new()) == NULL || (f4 = BN_new()) == NULL) { > ret = SSH_ERR_ALLOC_FAIL; > goto out; >@@ -1484,7 +1596,15 @@ rsa_generate_private_key(u_int bits, RSA **rsap) > ret = SSH_ERR_LIBCRYPTO_ERROR; > goto out; > } >- *rsap = private; >+ *pkeyp = EVP_PKEY_new(); >+ if (*pkeyp == NULL) { >+ ret = SSH_ERR_ALLOC_FAIL; >+ goto out; >+ } >+ if (EVP_PKEY_set1_RSA(*pkeyp, private) != 1) { >+ ret = SSH_ERR_LIBCRYPTO_ERROR; >+ goto out; >+ } > private = NULL; > ret = 0; > out: >@@ -1494,12 +1614,12 @@ rsa_generate_private_key(u_int bits, RSA **rsap) > } > > static int >-dsa_generate_private_key(u_int bits, DSA **dsap) >+dsa_generate_private_key(u_int bits, EVP_PKEY **pkeyp) > { > DSA *private; > int ret = SSH_ERR_INTERNAL_ERROR; > >- if (dsap == NULL) >+ if (pkeyp == NULL) > return SSH_ERR_INVALID_ARGUMENT; > if (bits != 1024) > return SSH_ERR_KEY_LENGTH; >@@ -1507,13 +1627,21 @@ dsa_generate_private_key(u_int bits, DSA **dsap) > ret = SSH_ERR_ALLOC_FAIL; > goto out; > } >- *dsap = NULL; >+ *pkeyp = NULL; > if (!DSA_generate_parameters_ex(private, bits, NULL, 0, NULL, > NULL, NULL) || !DSA_generate_key(private)) { > ret = SSH_ERR_LIBCRYPTO_ERROR; > goto out; > } >- *dsap = private; >+ *pkeyp = EVP_PKEY_new(); >+ if (*pkeyp == NULL) { >+ ret = SSH_ERR_ALLOC_FAIL; >+ goto out; >+ } >+ if (EVP_PKEY_set1_DSA(*pkeyp, private) != 1) { >+ ret = SSH_ERR_LIBCRYPTO_ERROR; >+ goto out; >+ } > private = NULL; > ret = 0; > out: >@@ -1523,8 +1651,9 @@ dsa_generate_private_key(u_int bits, DSA **dsap) > > # ifdef OPENSSL_HAS_ECC > int >-sshkey_ecdsa_key_to_nid(EC_KEY *k) >+sshkey_ecdsa_key_to_nid(struct sshkey *key) > { >+ EC_KEY *k; > EC_GROUP *eg; > int nids[] = { > NID_X9_62_prime256v1, >@@ -1537,7 +1666,12 @@ sshkey_ecdsa_key_to_nid(EC_KEY *k) > int nid; > u_int i; > BN_CTX *bnctx; >- const EC_GROUP *g = EC_KEY_get0_group(k); >+ const EC_GROUP *g; >+ >+ if ((k = EVP_PKEY_get0_EC_KEY(key->pkey)) == NULL || >+ (g = EC_KEY_get0_group(k)) == NULL) { >+ return -1; >+ } > > /* > * The group may be stored in a ASN.1 encoded private key in one of two >@@ -1573,16 +1707,16 @@ sshkey_ecdsa_key_to_nid(EC_KEY *k) > } > > static int >-ecdsa_generate_private_key(u_int bits, int *nid, EC_KEY **ecdsap) >+ecdsa_generate_private_key(u_int bits, int *nid, EVP_PKEY **pkeyp) > { > EC_KEY *private; > int ret = SSH_ERR_INTERNAL_ERROR; > >- if (nid == NULL || ecdsap == NULL) >+ if (nid == NULL || pkeyp == NULL) > return SSH_ERR_INVALID_ARGUMENT; > if ((*nid = sshkey_ecdsa_bits_to_nid(bits)) == -1) > return SSH_ERR_KEY_LENGTH; >- *ecdsap = NULL; >+ *pkeyp = NULL; > if ((private = EC_KEY_new_by_curve_name(*nid)) == NULL) { > ret = SSH_ERR_ALLOC_FAIL; > goto out; >@@ -1592,7 +1726,15 @@ ecdsa_generate_private_key(u_int bits, int *nid, EC_KEY **ecdsap) > goto out; > } > EC_KEY_set_asn1_flag(private, OPENSSL_EC_NAMED_CURVE); >- *ecdsap = private; >+ *pkeyp = EVP_PKEY_new(); >+ if (*pkeyp == NULL) { >+ ret = SSH_ERR_ALLOC_FAIL; >+ goto out; >+ } >+ if (EVP_PKEY_set1_EC_KEY(*pkeyp, private) != 1) { >+ ret = SSH_ERR_LIBCRYPTO_ERROR; >+ goto out; >+ } > private = NULL; > ret = 0; > out: >@@ -1630,16 +1772,16 @@ sshkey_generate(int type, u_int bits, struct sshkey **keyp) > #endif /* WITH_XMSS */ > #ifdef WITH_OPENSSL > case KEY_DSA: >- ret = dsa_generate_private_key(bits, &k->dsa); >+ ret = dsa_generate_private_key(bits, &k->pkey); > break; > # ifdef OPENSSL_HAS_ECC > case KEY_ECDSA: > ret = ecdsa_generate_private_key(bits, &k->ecdsa_nid, >- &k->ecdsa); >+ &k->pkey); > break; > # endif /* OPENSSL_HAS_ECC */ > case KEY_RSA: >- ret = rsa_generate_private_key(bits, &k->rsa); >+ ret = rsa_generate_private_key(bits, &k->pkey); > break; > #endif /* WITH_OPENSSL */ > default: >@@ -1729,6 +1871,10 @@ sshkey_from_private(const struct sshkey *k, struct sshkey **pkp) > struct sshkey *n = NULL; > int r = SSH_ERR_INTERNAL_ERROR; > #ifdef WITH_OPENSSL >+ RSA *rsa; >+ DSA *dsa; >+ EC_KEY *ecdsa; >+ const EC_POINT *ec_point; > const BIGNUM *rsa_n, *rsa_e; > BIGNUM *rsa_n_dup = NULL, *rsa_e_dup = NULL; > const BIGNUM *dsa_p, *dsa_q, *dsa_g, *dsa_pub_key; >@@ -1746,8 +1892,13 @@ sshkey_from_private(const struct sshkey *k, struct sshkey **pkp) > goto out; > } > >- DSA_get0_pqg(k->dsa, &dsa_p, &dsa_q, &dsa_g); >- DSA_get0_key(k->dsa, &dsa_pub_key, NULL); >+ dsa = EVP_PKEY_get0_DSA(k->pkey); >+ if (dsa == NULL) { >+ r = SSH_ERR_LIBCRYPTO_ERROR; >+ goto out; >+ } >+ DSA_get0_pqg(dsa, &dsa_p, &dsa_q, &dsa_g); >+ DSA_get0_key(dsa, &dsa_pub_key, NULL); > if ((dsa_p_dup = BN_dup(dsa_p)) == NULL || > (dsa_q_dup = BN_dup(dsa_q)) == NULL || > (dsa_g_dup = BN_dup(dsa_g)) == NULL || >@@ -1755,12 +1906,13 @@ sshkey_from_private(const struct sshkey *k, struct sshkey **pkp) > r = SSH_ERR_ALLOC_FAIL; > goto out; > } >- if (!DSA_set0_pqg(n->dsa, dsa_p_dup, dsa_q_dup, dsa_g_dup)) { >+ dsa = EVP_PKEY_get0_DSA(n->pkey); >+ if (!dsa || !DSA_set0_pqg(dsa, dsa_p_dup, dsa_q_dup, dsa_g_dup)) { > r = SSH_ERR_LIBCRYPTO_ERROR; > goto out; > } > dsa_p_dup = dsa_q_dup = dsa_g_dup = NULL; /* transferred */ >- if (!DSA_set0_key(n->dsa, dsa_pub_key_dup, NULL)) { >+ if (!DSA_set0_key(dsa, dsa_pub_key_dup, NULL)) { > r = SSH_ERR_LIBCRYPTO_ERROR; > goto out; > } >@@ -1775,13 +1927,22 @@ sshkey_from_private(const struct sshkey *k, struct sshkey **pkp) > goto out; > } > n->ecdsa_nid = k->ecdsa_nid; >- n->ecdsa = EC_KEY_new_by_curve_name(k->ecdsa_nid); >- if (n->ecdsa == NULL) { >+ ecdsa = EVP_PKEY_get0_EC_KEY(k->pkey); >+ if (ecdsa == NULL) { >+ r = SSH_ERR_LIBCRYPTO_ERROR; >+ goto out; >+ } >+ ec_point = EC_KEY_get0_public_key(ecdsa); >+ ecdsa = EC_KEY_new_by_curve_name(k->ecdsa_nid); >+ if (ecdsa == NULL) { > r = SSH_ERR_ALLOC_FAIL; > goto out; > } >- if (EC_KEY_set_public_key(n->ecdsa, >- EC_KEY_get0_public_key(k->ecdsa)) != 1) { >+ if (EC_KEY_set_public_key(ecdsa, ec_point) != 1) { >+ r = SSH_ERR_LIBCRYPTO_ERROR; >+ goto out; >+ } >+ if (EVP_PKEY_set1_EC_KEY(n->pkey, ecdsa) != 1) { > r = SSH_ERR_LIBCRYPTO_ERROR; > goto out; > } >@@ -1793,13 +1954,19 @@ sshkey_from_private(const struct sshkey *k, struct sshkey **pkp) > r = SSH_ERR_ALLOC_FAIL; > goto out; > } >- RSA_get0_key(k->rsa, &rsa_n, &rsa_e, NULL); >+ rsa = EVP_PKEY_get0_RSA(k->pkey); >+ if (rsa == NULL) { >+ r = SSH_ERR_LIBCRYPTO_ERROR; >+ goto out; >+ } >+ RSA_get0_key(rsa, &rsa_n, &rsa_e, NULL); > if ((rsa_n_dup = BN_dup(rsa_n)) == NULL || > (rsa_e_dup = BN_dup(rsa_e)) == NULL) { > r = SSH_ERR_ALLOC_FAIL; > goto out; > } >- if (!RSA_set0_key(n->rsa, rsa_n_dup, rsa_e_dup, NULL)) { >+ rsa = EVP_PKEY_get0_RSA(n->pkey); >+ if (!rsa || !RSA_set0_key(rsa, rsa_n_dup, rsa_e_dup, NULL)) { > r = SSH_ERR_LIBCRYPTO_ERROR; > goto out; > } >@@ -1994,9 +2161,14 @@ cert_parse(struct sshbuf *b, struct sshkey *key, struct sshbuf *certbuf) > > #ifdef WITH_OPENSSL > static int >-check_rsa_length(const RSA *rsa) >+check_rsa_length(const struct sshkey *key) > { > const BIGNUM *rsa_n; >+ const RSA *rsa; >+ >+ rsa = EVP_PKEY_get0_RSA(key->pkey); >+ if (rsa == NULL) >+ return SSH_ERR_INTERNAL_ERROR; > > RSA_get0_key(rsa, &rsa_n, NULL, NULL); > if (BN_num_bits(rsa_n) < SSH_RSA_MINIMUM_MODULUS_SIZE) >@@ -2016,6 +2188,9 @@ sshkey_from_blob_internal(struct sshbuf *b, struct sshkey **keyp, > u_char *pk = NULL; > struct sshbuf *copy; > #if defined(WITH_OPENSSL) >+ RSA *rsa; >+ DSA *dsa; >+ EC_KEY *ecdsa; > BIGNUM *rsa_n = NULL, *rsa_e = NULL; > BIGNUM *dsa_p = NULL, *dsa_q = NULL, *dsa_g = NULL, *dsa_pub_key = NULL; > # if defined(OPENSSL_HAS_ECC) >@@ -2061,15 +2236,16 @@ sshkey_from_blob_internal(struct sshbuf *b, struct sshkey **keyp, > ret = SSH_ERR_INVALID_FORMAT; > goto out; > } >- if (!RSA_set0_key(key->rsa, rsa_n, rsa_e, NULL)) { >+ rsa = EVP_PKEY_get0_RSA(key->pkey); >+ if (!rsa || !RSA_set0_key(rsa, rsa_n, rsa_e, NULL)) { > ret = SSH_ERR_LIBCRYPTO_ERROR; > goto out; > } > rsa_n = rsa_e = NULL; /* transferred */ >- if ((ret = check_rsa_length(key->rsa)) != 0) >+ if ((ret = check_rsa_length(key)) != 0) > goto out; > #ifdef DEBUG_PK >- RSA_print_fp(stderr, key->rsa, 8); >+ RSA_print_fp(stderr, rsa, 8); > #endif > break; > case KEY_DSA_CERT: >@@ -2091,18 +2267,19 @@ sshkey_from_blob_internal(struct sshbuf *b, struct sshkey **keyp, > ret = SSH_ERR_INVALID_FORMAT; > goto out; > } >- if (!DSA_set0_pqg(key->dsa, dsa_p, dsa_q, dsa_g)) { >+ dsa = EVP_PKEY_get0_DSA(key->pkey); >+ if (!dsa || !DSA_set0_pqg(dsa, dsa_p, dsa_q, dsa_g)) { > ret = SSH_ERR_LIBCRYPTO_ERROR; > goto out; > } > dsa_p = dsa_q = dsa_g = NULL; /* transferred */ >- if (!DSA_set0_key(key->dsa, dsa_pub_key, NULL)) { >+ if (!DSA_set0_key(dsa, dsa_pub_key, NULL)) { > ret = SSH_ERR_LIBCRYPTO_ERROR; > goto out; > } > dsa_pub_key = NULL; /* transferred */ > #ifdef DEBUG_PK >- DSA_print_fp(stderr, key->dsa, 8); >+ DSA_print_fp(stderr, dsa, 8); > #endif > break; > case KEY_ECDSA_CERT: >@@ -2127,32 +2304,36 @@ sshkey_from_blob_internal(struct sshbuf *b, struct sshkey **keyp, > ret = SSH_ERR_EC_CURVE_MISMATCH; > goto out; > } >- EC_KEY_free(key->ecdsa); >- if ((key->ecdsa = EC_KEY_new_by_curve_name(key->ecdsa_nid)) >+ if ((ecdsa = EC_KEY_new_by_curve_name(key->ecdsa_nid)) > == NULL) { > ret = SSH_ERR_EC_CURVE_INVALID; > goto out; > } >- if ((q = EC_POINT_new(EC_KEY_get0_group(key->ecdsa))) == NULL) { >+ if ((q = EC_POINT_new(EC_KEY_get0_group(ecdsa))) == NULL) { > ret = SSH_ERR_ALLOC_FAIL; > goto out; > } >- if (sshbuf_get_ec(b, q, EC_KEY_get0_group(key->ecdsa)) != 0) { >+ if (sshbuf_get_ec(b, q, EC_KEY_get0_group(ecdsa)) != 0) { > ret = SSH_ERR_INVALID_FORMAT; > goto out; > } >- if (sshkey_ec_validate_public(EC_KEY_get0_group(key->ecdsa), >+ if (sshkey_ec_validate_public(EC_KEY_get0_group(ecdsa), > q) != 0) { > ret = SSH_ERR_KEY_INVALID_EC_VALUE; > goto out; > } >- if (EC_KEY_set_public_key(key->ecdsa, q) != 1) { >+ if (EC_KEY_set_public_key(ecdsa, q) != 1) { > /* XXX assume it is a allocation error */ > ret = SSH_ERR_ALLOC_FAIL; > goto out; > } >+ if (EVP_PKEY_set1_EC_KEY(key->pkey, ecdsa) != 1) { >+ ret = SSH_ERR_LIBCRYPTO_ERROR; >+ goto out; >+ } >+ ecdsa = NULL; > #ifdef DEBUG_PK >- sshkey_dump_ec_point(EC_KEY_get0_group(key->ecdsa), q); >+ sshkey_dump_ec_point(EC_KEY_get0_group(ecdsa), q); > #endif > break; > # endif /* OPENSSL_HAS_ECC */ >@@ -2505,6 +2686,9 @@ sshkey_certify_custom(struct sshkey *k, struct sshkey *ca, const char *alg, > struct sshbuf *cert = NULL; > char *sigtype = NULL; > #ifdef WITH_OPENSSL >+ const RSA *rsa; >+ const DSA *dsa; >+ const EC_KEY *ecdsa; > const BIGNUM *rsa_n, *rsa_e, *dsa_p, *dsa_q, *dsa_g, *dsa_pub_key; > #endif /* WITH_OPENSSL */ > >@@ -2543,8 +2727,13 @@ sshkey_certify_custom(struct sshkey *k, struct sshkey *ca, const char *alg, > switch (k->type) { > #ifdef WITH_OPENSSL > case KEY_DSA_CERT: >- DSA_get0_pqg(k->dsa, &dsa_p, &dsa_q, &dsa_g); >- DSA_get0_key(k->dsa, &dsa_pub_key, NULL); >+ dsa = EVP_PKEY_get0_DSA(k->pkey); >+ if (dsa == NULL) { >+ ret = SSH_ERR_LIBCRYPTO_ERROR; >+ goto out; >+ } >+ DSA_get0_pqg(dsa, &dsa_p, &dsa_q, &dsa_g); >+ DSA_get0_key(dsa, &dsa_pub_key, NULL); > if ((ret = sshbuf_put_bignum2(cert, dsa_p)) != 0 || > (ret = sshbuf_put_bignum2(cert, dsa_q)) != 0 || > (ret = sshbuf_put_bignum2(cert, dsa_g)) != 0 || >@@ -2553,16 +2742,26 @@ sshkey_certify_custom(struct sshkey *k, struct sshkey *ca, const char *alg, > break; > # ifdef OPENSSL_HAS_ECC > case KEY_ECDSA_CERT: >+ ecdsa = EVP_PKEY_get1_EC_KEY(k->pkey); >+ if (ecdsa == NULL) { >+ ret = SSH_ERR_LIBCRYPTO_ERROR; >+ goto out; >+ } > if ((ret = sshbuf_put_cstring(cert, > sshkey_curve_nid_to_name(k->ecdsa_nid))) != 0 || > (ret = sshbuf_put_ec(cert, >- EC_KEY_get0_public_key(k->ecdsa), >- EC_KEY_get0_group(k->ecdsa))) != 0) >+ EC_KEY_get0_public_key(ecdsa), >+ EC_KEY_get0_group(ecdsa))) != 0) > goto out; > break; > # endif /* OPENSSL_HAS_ECC */ > case KEY_RSA_CERT: >- RSA_get0_key(k->rsa, &rsa_n, &rsa_e, NULL); >+ rsa = EVP_PKEY_get0_RSA(k->pkey); >+ if (rsa == NULL) { >+ ret = SSH_ERR_LIBCRYPTO_ERROR; >+ goto out; >+ } >+ RSA_get0_key(rsa, &rsa_n, &rsa_e, NULL); > if ((ret = sshbuf_put_bignum2(cert, rsa_e)) != 0 || > (ret = sshbuf_put_bignum2(cert, rsa_n)) != 0) > goto out; >@@ -2758,6 +2957,9 @@ sshkey_private_serialize_opt(const struct sshkey *key, struct sshbuf *b, > { > int r = SSH_ERR_INTERNAL_ERROR; > #ifdef WITH_OPENSSL >+ const RSA *rsa; >+ const DSA *dsa; >+ const EC_KEY *ecdsa; > const BIGNUM *rsa_n, *rsa_e, *rsa_d, *rsa_iqmp, *rsa_p, *rsa_q; > const BIGNUM *dsa_p, *dsa_q, *dsa_g, *dsa_pub_key, *dsa_priv_key; > #endif /* WITH_OPENSSL */ >@@ -2767,9 +2969,14 @@ sshkey_private_serialize_opt(const struct sshkey *key, struct sshbuf *b, > switch (key->type) { > #ifdef WITH_OPENSSL > case KEY_RSA: >- RSA_get0_key(key->rsa, &rsa_n, &rsa_e, &rsa_d); >- RSA_get0_factors(key->rsa, &rsa_p, &rsa_q); >- RSA_get0_crt_params(key->rsa, NULL, NULL, &rsa_iqmp); >+ rsa = EVP_PKEY_get0_RSA(key->pkey); >+ if (rsa == NULL) { >+ r = SSH_ERR_LIBCRYPTO_ERROR; >+ goto out; >+ } >+ RSA_get0_key(rsa, &rsa_n, &rsa_e, &rsa_d); >+ RSA_get0_factors(rsa, &rsa_p, &rsa_q); >+ RSA_get0_crt_params(rsa, NULL, NULL, &rsa_iqmp); > if ((r = sshbuf_put_bignum2(b, rsa_n)) != 0 || > (r = sshbuf_put_bignum2(b, rsa_e)) != 0 || > (r = sshbuf_put_bignum2(b, rsa_d)) != 0 || >@@ -2783,9 +2990,14 @@ sshkey_private_serialize_opt(const struct sshkey *key, struct sshbuf *b, > r = SSH_ERR_INVALID_ARGUMENT; > goto out; > } >- RSA_get0_key(key->rsa, NULL, NULL, &rsa_d); >- RSA_get0_factors(key->rsa, &rsa_p, &rsa_q); >- RSA_get0_crt_params(key->rsa, NULL, NULL, &rsa_iqmp); >+ rsa = EVP_PKEY_get0_RSA(key->pkey); >+ if (rsa == NULL) { >+ r = SSH_ERR_LIBCRYPTO_ERROR; >+ goto out; >+ } >+ RSA_get0_key(rsa, NULL, NULL, &rsa_d); >+ RSA_get0_factors(rsa, &rsa_p, &rsa_q); >+ RSA_get0_crt_params(rsa, NULL, NULL, &rsa_iqmp); > if ((r = sshbuf_put_stringb(b, key->cert->certblob)) != 0 || > (r = sshbuf_put_bignum2(b, rsa_d)) != 0 || > (r = sshbuf_put_bignum2(b, rsa_iqmp)) != 0 || >@@ -2794,8 +3006,13 @@ sshkey_private_serialize_opt(const struct sshkey *key, struct sshbuf *b, > goto out; > break; > case KEY_DSA: >- DSA_get0_pqg(key->dsa, &dsa_p, &dsa_q, &dsa_g); >- DSA_get0_key(key->dsa, &dsa_pub_key, &dsa_priv_key); >+ dsa = EVP_PKEY_get0_DSA(key->pkey); >+ if (dsa == NULL) { >+ r = SSH_ERR_LIBCRYPTO_ERROR; >+ goto out; >+ } >+ DSA_get0_pqg(dsa, &dsa_p, &dsa_q, &dsa_g); >+ DSA_get0_key(dsa, &dsa_pub_key, &dsa_priv_key); > if ((r = sshbuf_put_bignum2(b, dsa_p)) != 0 || > (r = sshbuf_put_bignum2(b, dsa_q)) != 0 || > (r = sshbuf_put_bignum2(b, dsa_g)) != 0 || >@@ -2808,28 +3025,36 @@ sshkey_private_serialize_opt(const struct sshkey *key, struct sshbuf *b, > r = SSH_ERR_INVALID_ARGUMENT; > goto out; > } >- DSA_get0_key(key->dsa, NULL, &dsa_priv_key); >+ dsa = EVP_PKEY_get0_DSA(key->pkey); >+ if (dsa == NULL) { >+ r = SSH_ERR_LIBCRYPTO_ERROR; >+ goto out; >+ } >+ DSA_get0_key(dsa, NULL, &dsa_priv_key); > if ((r = sshbuf_put_stringb(b, key->cert->certblob)) != 0 || > (r = sshbuf_put_bignum2(b, dsa_priv_key)) != 0) > goto out; > break; > # ifdef OPENSSL_HAS_ECC > case KEY_ECDSA: >- if ((r = sshbuf_put_cstring(b, >+ ecdsa = EVP_PKEY_get0_EC_KEY(key->pkey); >+ if (!ecdsa || (r = sshbuf_put_cstring(b, > sshkey_curve_nid_to_name(key->ecdsa_nid))) != 0 || >- (r = sshbuf_put_eckey(b, key->ecdsa)) != 0 || >+ (r = sshbuf_put_eckey(b, ecdsa)) != 0 || > (r = sshbuf_put_bignum2(b, >- EC_KEY_get0_private_key(key->ecdsa))) != 0) >+ EC_KEY_get0_private_key(ecdsa))) != 0) > goto out; > break; > case KEY_ECDSA_CERT: >- if (key->cert == NULL || sshbuf_len(key->cert->certblob) == 0) { >+ ecdsa = EVP_PKEY_get0_EC_KEY(key->pkey); >+ if (!ecdsa || key->cert == NULL || >+ sshbuf_len(key->cert->certblob) == 0) { > r = SSH_ERR_INVALID_ARGUMENT; > goto out; > } > if ((r = sshbuf_put_stringb(b, key->cert->certblob)) != 0 || > (r = sshbuf_put_bignum2(b, >- EC_KEY_get0_private_key(key->ecdsa))) != 0) >+ EC_KEY_get0_private_key(ecdsa))) != 0) > goto out; > break; > # endif /* OPENSSL_HAS_ECC */ >@@ -2910,6 +3135,9 @@ sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **kp) > u_char *ed25519_pk = NULL, *ed25519_sk = NULL; > u_char *xmss_pk = NULL, *xmss_sk = NULL; > #ifdef WITH_OPENSSL >+ RSA *rsa; >+ DSA *dsa; >+ EC_KEY *ecdsa; > BIGNUM *exponent = NULL; > BIGNUM *rsa_n = NULL, *rsa_e = NULL, *rsa_d = NULL; > BIGNUM *rsa_iqmp = NULL, *rsa_p = NULL, *rsa_q = NULL; >@@ -2935,12 +3163,13 @@ sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **kp) > (r = sshbuf_get_bignum2(buf, &dsa_pub_key)) != 0 || > (r = sshbuf_get_bignum2(buf, &dsa_priv_key)) != 0) > goto out; >- if (!DSA_set0_pqg(k->dsa, dsa_p, dsa_q, dsa_g)) { >+ dsa = EVP_PKEY_get0_DSA(k->pkey); >+ if (!dsa || !DSA_set0_pqg(dsa, dsa_p, dsa_q, dsa_g)) { > r = SSH_ERR_LIBCRYPTO_ERROR; > goto out; > } > dsa_p = dsa_q = dsa_g = NULL; /* transferred */ >- if (!DSA_set0_key(k->dsa, dsa_pub_key, dsa_priv_key)) { >+ if (!DSA_set0_key(dsa, dsa_pub_key, dsa_priv_key)) { > r = SSH_ERR_LIBCRYPTO_ERROR; > goto out; > } >@@ -2950,7 +3179,8 @@ sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **kp) > if ((r = sshkey_froms(buf, &k)) != 0 || > (r = sshbuf_get_bignum2(buf, &dsa_priv_key)) != 0) > goto out; >- if (!DSA_set0_key(k->dsa, NULL, dsa_priv_key)) { >+ dsa = EVP_PKEY_get0_DSA(k->pkey); >+ if (!dsa || !DSA_set0_key(dsa, NULL, dsa_priv_key)) { > r = SSH_ERR_LIBCRYPTO_ERROR; > goto out; > } >@@ -2972,34 +3202,39 @@ sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **kp) > r = SSH_ERR_EC_CURVE_MISMATCH; > goto out; > } >- k->ecdsa = EC_KEY_new_by_curve_name(k->ecdsa_nid); >- if (k->ecdsa == NULL) { >+ ecdsa = EC_KEY_new_by_curve_name(k->ecdsa_nid); >+ if (ecdsa == NULL) { > r = SSH_ERR_LIBCRYPTO_ERROR; > goto out; > } >- if ((r = sshbuf_get_eckey(buf, k->ecdsa)) != 0 || >+ if ((r = sshbuf_get_eckey(buf, ecdsa)) != 0 || > (r = sshbuf_get_bignum2(buf, &exponent))) > goto out; >- if (EC_KEY_set_private_key(k->ecdsa, exponent) != 1) { >+ if (EC_KEY_set_private_key(ecdsa, exponent) != 1) { > r = SSH_ERR_LIBCRYPTO_ERROR; > goto out; > } >- if ((r = sshkey_ec_validate_public(EC_KEY_get0_group(k->ecdsa), >- EC_KEY_get0_public_key(k->ecdsa))) != 0 || >- (r = sshkey_ec_validate_private(k->ecdsa)) != 0) >+ if ((r = sshkey_ec_validate_public(EC_KEY_get0_group(ecdsa), >+ EC_KEY_get0_public_key(ecdsa))) != 0 || >+ (r = sshkey_ec_validate_private(ecdsa)) != 0) >+ goto out; >+ if (EVP_PKEY_set1_EC_KEY(k->pkey, ecdsa) != 1) { >+ r = SSH_ERR_LIBCRYPTO_ERROR; > goto out; >+ } > break; > case KEY_ECDSA_CERT: > if ((r = sshkey_froms(buf, &k)) != 0 || > (r = sshbuf_get_bignum2(buf, &exponent)) != 0) > goto out; >- if (EC_KEY_set_private_key(k->ecdsa, exponent) != 1) { >+ ecdsa = EVP_PKEY_get0_EC_KEY(k->pkey); >+ if (!ecdsa || EC_KEY_set_private_key(ecdsa, exponent) != 1) { > r = SSH_ERR_LIBCRYPTO_ERROR; > goto out; > } >- if ((r = sshkey_ec_validate_public(EC_KEY_get0_group(k->ecdsa), >- EC_KEY_get0_public_key(k->ecdsa))) != 0 || >- (r = sshkey_ec_validate_private(k->ecdsa)) != 0) >+ if ((r = sshkey_ec_validate_public(EC_KEY_get0_group(ecdsa), >+ EC_KEY_get0_public_key(ecdsa))) != 0 || >+ (r = sshkey_ec_validate_private(ecdsa)) != 0) > goto out; > break; > # endif /* OPENSSL_HAS_ECC */ >@@ -3015,17 +3250,18 @@ sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **kp) > (r = sshbuf_get_bignum2(buf, &rsa_p)) != 0 || > (r = sshbuf_get_bignum2(buf, &rsa_q)) != 0) > goto out; >- if (!RSA_set0_key(k->rsa, rsa_n, rsa_e, rsa_d)) { >+ rsa = EVP_PKEY_get0_RSA(k->pkey); >+ if (!rsa || !RSA_set0_key(rsa, rsa_n, rsa_e, rsa_d)) { > r = SSH_ERR_LIBCRYPTO_ERROR; > goto out; > } > rsa_n = rsa_e = rsa_d = NULL; /* transferred */ >- if (!RSA_set0_factors(k->rsa, rsa_p, rsa_q)) { >+ if (!RSA_set0_factors(rsa, rsa_p, rsa_q)) { > r = SSH_ERR_LIBCRYPTO_ERROR; > goto out; > } > rsa_p = rsa_q = NULL; /* transferred */ >- if ((r = check_rsa_length(k->rsa)) != 0) >+ if ((r = check_rsa_length(k)) != 0) > goto out; > if ((r = ssh_rsa_complete_crt_parameters(k, rsa_iqmp)) != 0) > goto out; >@@ -3037,17 +3273,18 @@ sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **kp) > (r = sshbuf_get_bignum2(buf, &rsa_p)) != 0 || > (r = sshbuf_get_bignum2(buf, &rsa_q)) != 0) > goto out; >- if (!RSA_set0_key(k->rsa, NULL, NULL, rsa_d)) { >+ rsa = EVP_PKEY_get0_RSA(k->pkey); >+ if (!rsa || !RSA_set0_key(rsa, NULL, NULL, rsa_d)) { > r = SSH_ERR_LIBCRYPTO_ERROR; > goto out; > } > rsa_d = NULL; /* transferred */ >- if (!RSA_set0_factors(k->rsa, rsa_p, rsa_q)) { >+ if (!RSA_set0_factors(rsa, rsa_p, rsa_q)) { > r = SSH_ERR_LIBCRYPTO_ERROR; > goto out; > } > rsa_p = rsa_q = NULL; /* transferred */ >- if ((r = check_rsa_length(k->rsa)) != 0) >+ if ((r = check_rsa_length(k)) != 0) > goto out; > if ((r = ssh_rsa_complete_crt_parameters(k, rsa_iqmp)) != 0) > goto out; >@@ -3137,7 +3374,8 @@ sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **kp) > switch (k->type) { > case KEY_RSA: > case KEY_RSA_CERT: >- if (RSA_blinding_on(k->rsa, NULL) != 1) { >+ rsa = EVP_PKEY_get0_RSA(k->pkey); >+ if (!rsa || RSA_blinding_on(rsa, NULL) != 1) { > r = SSH_ERR_LIBCRYPTO_ERROR; > goto out; > } >@@ -3728,6 +3966,9 @@ sshkey_private_pem_to_blob(struct sshkey *key, struct sshbuf *blob, > const EVP_CIPHER *cipher = (len > 0) ? EVP_aes_128_cbc() : NULL; > char *bptr; > BIO *bio = NULL; >+ RSA *rsa; >+ DSA *dsa; >+ EC_KEY *ecdsa; > > if (len > 0 && len <= 4) > return SSH_ERR_PASSPHRASE_TOO_SHORT; >@@ -3736,17 +3977,20 @@ sshkey_private_pem_to_blob(struct sshkey *key, struct sshbuf *blob, > > switch (key->type) { > case KEY_DSA: >- success = PEM_write_bio_DSAPrivateKey(bio, key->dsa, >+ dsa = EVP_PKEY_get0_DSA(key->pkey); >+ success = PEM_write_bio_DSAPrivateKey(bio, dsa, > cipher, passphrase, len, NULL, NULL); > break; > #ifdef OPENSSL_HAS_ECC > case KEY_ECDSA: >- success = PEM_write_bio_ECPrivateKey(bio, key->ecdsa, >+ ecdsa = EVP_PKEY_get0_EC_KEY(key->pkey); >+ success = PEM_write_bio_ECPrivateKey(bio, ecdsa, > cipher, passphrase, len, NULL, NULL); > break; > #endif > case KEY_RSA: >- success = PEM_write_bio_RSAPrivateKey(bio, key->rsa, >+ rsa = EVP_PKEY_get0_RSA(key->pkey); >+ success = PEM_write_bio_RSAPrivateKey(bio, rsa, > cipher, passphrase, len, NULL, NULL); > break; > default: >@@ -3912,20 +4156,27 @@ sshkey_parse_private_pem_fileblob(struct sshbuf *blob, int type, > } > if (EVP_PKEY_base_id(pk) == EVP_PKEY_RSA && > (type == KEY_UNSPEC || type == KEY_RSA)) { >+ RSA *rsa; > if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) { > r = SSH_ERR_ALLOC_FAIL; > goto out; > } >- prv->rsa = EVP_PKEY_get1_RSA(pk); >+ rsa = EVP_PKEY_get0_RSA(pk); >+ if (rsa == NULL) { >+ r = SSH_ERR_LIBCRYPTO_ERROR; >+ goto out; >+ } >+ prv->pkey = pk; >+ pk = NULL; > prv->type = KEY_RSA; > #ifdef DEBUG_PK >- RSA_print_fp(stderr, prv->rsa, 8); >+ RSA_print_fp(stderr, rsa, 8); > #endif >- if (RSA_blinding_on(prv->rsa, NULL) != 1) { >+ if (RSA_blinding_on(rsa, NULL) != 1) { > r = SSH_ERR_LIBCRYPTO_ERROR; > goto out; > } >- if ((r = check_rsa_length(prv->rsa)) != 0) >+ if ((r = check_rsa_length(prv)) != 0) > goto out; > } else if (EVP_PKEY_base_id(pk) == EVP_PKEY_DSA && > (type == KEY_UNSPEC || type == KEY_DSA)) { >@@ -3933,32 +4184,41 @@ sshkey_parse_private_pem_fileblob(struct sshbuf *blob, int type, > r = SSH_ERR_ALLOC_FAIL; > goto out; > } >- prv->dsa = EVP_PKEY_get1_DSA(pk); >+ prv->pkey = pk; >+ pk = NULL; > prv->type = KEY_DSA; > #ifdef DEBUG_PK >- DSA_print_fp(stderr, prv->dsa, 8); >+ DSA_print_fp(stderr, EVP_PKEY_get0_DSA(pk), 8); > #endif > #ifdef OPENSSL_HAS_ECC > } else if (EVP_PKEY_base_id(pk) == EVP_PKEY_EC && > (type == KEY_UNSPEC || type == KEY_ECDSA)) { >+ EC_KEY *ecdsa; > if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) { > r = SSH_ERR_ALLOC_FAIL; > goto out; > } >- prv->ecdsa = EVP_PKEY_get1_EC_KEY(pk); >+ ecdsa = EVP_PKEY_get0_EC_KEY(pk); >+ if (ecdsa == NULL) { >+ r = SSH_ERR_LIBCRYPTO_ERROR; >+ goto out; >+ } > prv->type = KEY_ECDSA; >- prv->ecdsa_nid = sshkey_ecdsa_key_to_nid(prv->ecdsa); >+ EVP_PKEY_free(prv->pkey); >+ prv->pkey = pk; >+ pk = NULL; >+ prv->ecdsa_nid = sshkey_ecdsa_key_to_nid(prv); > if (prv->ecdsa_nid == -1 || > sshkey_curve_nid_to_name(prv->ecdsa_nid) == NULL || >- sshkey_ec_validate_public(EC_KEY_get0_group(prv->ecdsa), >- EC_KEY_get0_public_key(prv->ecdsa)) != 0 || >- sshkey_ec_validate_private(prv->ecdsa) != 0) { >+ sshkey_ec_validate_public(EC_KEY_get0_group(ecdsa), >+ EC_KEY_get0_public_key(ecdsa)) != 0 || >+ sshkey_ec_validate_private(ecdsa) != 0) { > r = SSH_ERR_INVALID_FORMAT; > goto out; > } > # ifdef DEBUG_PK >- if (prv != NULL && prv->ecdsa != NULL) >- sshkey_dump_ec_key(prv->ecdsa); >+ if (prv != NULL && ecdsa != NULL) >+ sshkey_dump_ec_key(ecdsa); > # endif > #endif /* OPENSSL_HAS_ECC */ > } else { >diff --git a/sshkey.h b/sshkey.h >index a91e6043..5e7601c9 100644 >--- a/sshkey.h >+++ b/sshkey.h >@@ -29,21 +29,10 @@ > #include <sys/types.h> > > #ifdef WITH_OPENSSL >-#include <openssl/rsa.h> >-#include <openssl/dsa.h> >-# ifdef OPENSSL_HAS_ECC >-# include <openssl/ec.h> >-# include <openssl/ecdsa.h> >-# else /* OPENSSL_HAS_ECC */ >-# define EC_KEY void >-# define EC_GROUP void >-# define EC_POINT void >-# endif /* OPENSSL_HAS_ECC */ >+#include <openssl/evp.h> >+#include <openssl/ec.h> > #else /* WITH_OPENSSL */ >-# define BIGNUM void >-# define RSA void >-# define DSA void >-# define EC_KEY void >+# define EVP_PKEY void > # define EC_GROUP void > # define EC_POINT void > #endif /* WITH_OPENSSL */ >@@ -111,10 +100,8 @@ struct sshkey_cert { > struct sshkey { > int type; > int flags; >- RSA *rsa; >- DSA *dsa; >+ EVP_PKEY *pkey; > int ecdsa_nid; /* NID of curve */ >- EC_KEY *ecdsa; > u_char *ed25519_sk; > u_char *ed25519_pk; > char *xmss_name; >@@ -171,7 +158,7 @@ int sshkey_curve_name_to_nid(const char *); > const char * sshkey_curve_nid_to_name(int); > u_int sshkey_curve_nid_to_bits(int); > int sshkey_ecdsa_bits_to_nid(int); >-int sshkey_ecdsa_key_to_nid(EC_KEY *); >+int sshkey_ecdsa_key_to_nid(struct sshkey *); > int sshkey_ec_nid_to_hash_alg(int nid); > int sshkey_ec_validate_public(const EC_GROUP *, const EC_POINT *); > int sshkey_ec_validate_private(const EC_KEY *); >@@ -179,6 +166,10 @@ const char *sshkey_ssh_name(const struct sshkey *); > const char *sshkey_ssh_name_plain(const struct sshkey *); > int sshkey_names_valid2(const char *, int); > char *sshkey_alg_list(int, int, int, char); >+int sshkey_calculate_signature(EVP_PKEY*, int, u_char **, >+ int *, const u_char *, size_t); >+int sshkey_verify_signature(EVP_PKEY *, int, const u_char *, >+ size_t, u_char *, int); > > int sshkey_from_blob(const u_char *, size_t, struct sshkey **); > int sshkey_fromb(struct sshbuf *, struct sshkey **);
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 3005
: 3277 |
3283