From: Peter Müller Date: Wed, 23 Jan 2019 19:54:07 +0000 (+0100) Subject: OpenSSH: update to 7.9p1 X-Git-Tag: v2.21-core128~67 X-Git-Url: http://git.ipfire.org/?p=ipfire-2.x.git;a=commitdiff_plain;h=fee8b1c5041e7a3abeda7b2148296f417d9f6362 OpenSSH: update to 7.9p1 Update OpenSSH to 7.9p1 (release note is available at https://www.openssh.com/txt/release-7.9). Patching support for OpenSSL 1.1.0 is no longer required, thus the orphaned patchfile has been deleted. Signed-off-by: Peter Müller Signed-off-by: Michael Tremer --- diff --git a/config/rootfiles/common/openssh b/config/rootfiles/common/openssh index c33003fe6b..b41190a474 100644 --- a/config/rootfiles/common/openssh +++ b/config/rootfiles/common/openssh @@ -7,8 +7,6 @@ etc/ssh/ssh_config #etc/ssh/ssh_host_ecdsa_key.pub #etc/ssh/ssh_host_ed25519_key #etc/ssh/ssh_host_ed25519_key.pub -#etc/ssh/ssh_host_key -#etc/ssh/ssh_host_key.pub #etc/ssh/ssh_host_rsa_key #etc/ssh/ssh_host_rsa_key.pub etc/ssh/sshd_config @@ -26,7 +24,6 @@ usr/lib/openssh/ssh-pkcs11-helper usr/sbin/sshd #usr/share/man/man1/scp.1 #usr/share/man/man1/sftp.1 -#usr/share/man/man1/slogin.1 #usr/share/man/man1/ssh-add.1 #usr/share/man/man1/ssh-agent.1 #usr/share/man/man1/ssh-keygen.1 diff --git a/lfs/openssh b/lfs/openssh index c67f135e81..7fbb5a9288 100644 --- a/lfs/openssh +++ b/lfs/openssh @@ -1,7 +1,7 @@ ############################################################################### # # # IPFire.org - A linux based firewall # -# Copyright (C) 2007-2018 IPFire Team # +# Copyright (C) 2007-2019 IPFire Team # # # # This program is free software: you can redistribute it and/or modify # # it under the terms of the GNU General Public License as published by # @@ -24,7 +24,7 @@ include Config -VER = 7.8p1 +VER = 7.9p1 THISAPP = openssh-$(VER) DL_FILE = $(THISAPP).tar.gz @@ -40,7 +40,7 @@ objects = $(DL_FILE) $(DL_FILE) = $(DL_FROM)/$(DL_FILE) -$(DL_FILE)_MD5 = ce1d090fa6239fd38eb989d5e983b074 +$(DL_FILE)_MD5 = c6af50b7a474d04726a5aa747a5dce8f install : $(TARGET) @@ -70,7 +70,6 @@ $(subst %,%_MD5,$(objects)) : $(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects)) @$(PREBUILD) @rm -rf $(DIR_APP) && cd $(DIR_SRC) && tar zxf $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/openssh-7.8p1-openssl-1.1.0-1.patch cd $(DIR_APP) && sed -i "s/lkrb5 -ldes/lkrb5/" configure cd $(DIR_APP) && ./configure \ --prefix=/usr \ diff --git a/src/patches/openssh-7.8p1-openssl-1.1.0-1.patch b/src/patches/openssh-7.8p1-openssl-1.1.0-1.patch deleted file mode 100644 index 7f8c7cd4f6..0000000000 --- a/src/patches/openssh-7.8p1-openssl-1.1.0-1.patch +++ /dev/null @@ -1,1950 +0,0 @@ -diff -aurp old/auth-pam.c new/auth-pam.c ---- old/auth-pam.c 2018-08-22 22:41:42.000000000 -0700 -+++ new/auth-pam.c 2018-08-23 21:31:53.324592767 -0700 -@@ -128,6 +128,10 @@ extern u_int utmp_len; - typedef pthread_t sp_pthread_t; - #else - typedef pid_t sp_pthread_t; -+# define pthread_create(a, b, c, d) _ssh_compat_pthread_create(a, b, c, d) -+# define pthread_exit(a) _ssh_compat_pthread_exit(a) -+# define pthread_cancel(a) _ssh_compat_pthread_cancel(a) -+# define pthread_join(a, b) _ssh_compat_pthread_join(a, b) - #endif - - struct pam_ctxt { -diff -aurp old/cipher.c new/cipher.c ---- old/cipher.c 2018-08-22 22:41:42.000000000 -0700 -+++ new/cipher.c 2018-08-23 21:31:53.327926112 -0700 -@@ -299,7 +299,10 @@ cipher_init(struct sshcipher_ctx **ccp, - goto out; - } - } -- if (EVP_CipherInit(cc->evp, NULL, (u_char *)key, NULL, -1) == 0) { -+ /* in OpenSSL 1.1.0, EVP_CipherInit clears all previous setups; -+ use EVP_CipherInit_ex for augmenting */ -+ if (EVP_CipherInit_ex(cc->evp, NULL, NULL, (u_char *)key, NULL, -1) == 0) -+ { - ret = SSH_ERR_LIBCRYPTO_ERROR; - goto out; - } -@@ -485,7 +488,7 @@ cipher_get_keyiv(struct sshcipher_ctx *c - len, iv)) - return SSH_ERR_LIBCRYPTO_ERROR; - } else -- memcpy(iv, cc->evp->iv, len); -+ memcpy(iv, EVP_CIPHER_CTX_iv(cc->evp), len); - #endif - return 0; - } -@@ -519,14 +522,19 @@ cipher_set_keyiv(struct sshcipher_ctx *c - EVP_CTRL_GCM_SET_IV_FIXED, -1, (void *)iv)) - return SSH_ERR_LIBCRYPTO_ERROR; - } else -- memcpy(cc->evp->iv, iv, evplen); -+ memcpy(EVP_CIPHER_CTX_iv(cc->evp), iv, evplen); - #endif - return 0; - } - - #ifdef WITH_OPENSSL --#define EVP_X_STATE(evp) (evp)->cipher_data --#define EVP_X_STATE_LEN(evp) (evp)->cipher->ctx_size -+# if OPENSSL_VERSION_NUMBER >= 0x10100000UL -+#define EVP_X_STATE(evp) EVP_CIPHER_CTX_get_cipher_data(evp) -+#define EVP_X_STATE_LEN(evp) EVP_CIPHER_impl_ctx_size(EVP_CIPHER_CTX_cipher(evp)) -+# else -+#define EVP_X_STATE(evp) (evp).cipher_data -+#define EVP_X_STATE_LEN(evp) (evp).cipher->ctx_size -+# endif - #endif - - int -diff -aurp old/cipher.h new/cipher.h ---- old/cipher.h 2018-08-22 22:41:42.000000000 -0700 -+++ new/cipher.h 2018-08-23 21:31:53.327926112 -0700 -@@ -46,7 +46,18 @@ - #define CIPHER_DECRYPT 0 - - struct sshcipher; -+#if 0 -+struct sshcipher_ctx { -+ int plaintext; -+ int encrypt; -+ EVP_CIPHER_CTX *evp; -+ struct chachapoly_ctx cp_ctx; /* XXX union with evp? */ -+ struct aesctr_ctx ac_ctx; /* XXX union with evp? */ -+ const struct sshcipher *cipher; -+}; -+#else - struct sshcipher_ctx; -+#endif - - const struct sshcipher *cipher_by_name(const char *); - const char *cipher_warning_message(const struct sshcipher_ctx *); -diff -aurp old/configure new/configure ---- old/configure 2018-08-23 00:09:30.000000000 -0700 -+++ new/configure 2018-08-23 21:31:53.331259457 -0700 -@@ -13032,7 +13032,6 @@ if ac_fn_c_try_run "$LINENO"; then : - 100*) ;; # 1.0.x - 200*) ;; # LibreSSL - *) -- as_fn_error $? "OpenSSL >= 1.1.0 is not yet supported (have \"$ssl_library_ver\")" "$LINENO" 5 - ;; - esac - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ssl_library_ver" >&5 -diff -aurp old/dh.c new/dh.c ---- old/dh.c 2018-08-22 22:41:42.000000000 -0700 -+++ new/dh.c 2018-08-23 21:39:18.863765579 -0700 -@@ -216,14 +216,15 @@ choose_dh(int min, int wantbits, int max - /* diffie-hellman-groupN-sha1 */ - - int --dh_pub_is_valid(DH *dh, BIGNUM *dh_pub) -+dh_pub_is_valid(const DH *dh, const BIGNUM *dh_pub) - { - int i; - int n = BN_num_bits(dh_pub); - int bits_set = 0; - BIGNUM *tmp; -+ const BIGNUM *p; - -- if (dh_pub->neg) { -+ if (BN_is_negative(dh_pub)) { - logit("invalid public DH value: negative"); - return 0; - } -@@ -236,7 +237,8 @@ dh_pub_is_valid(DH *dh, BIGNUM *dh_pub) - error("%s: BN_new failed", __func__); - return 0; - } -- if (!BN_sub(tmp, dh->p, BN_value_one()) || -+ DH_get0_pqg(dh, &p, NULL, NULL); -+ if (!BN_sub(tmp, p, BN_value_one()) || - BN_cmp(dh_pub, tmp) != -1) { /* pub_exp > p-2 */ - BN_clear_free(tmp); - logit("invalid public DH value: >= p-1"); -@@ -247,14 +249,14 @@ dh_pub_is_valid(DH *dh, BIGNUM *dh_pub) - for (i = 0; i <= n; i++) - if (BN_is_bit_set(dh_pub, i)) - bits_set++; -- debug2("bits set: %d/%d", bits_set, BN_num_bits(dh->p)); -+ debug2("bits set: %d/%d", bits_set, BN_num_bits(p)); - - /* - * if g==2 and bits_set==1 then computing log_g(dh_pub) is trivial - */ - if (bits_set < 4) { - logit("invalid public DH value (%d/%d)", -- bits_set, BN_num_bits(dh->p)); -+ bits_set, BN_num_bits(p)); - return 0; - } - return 1; -@@ -264,9 +266,13 @@ int - dh_gen_key(DH *dh, int need) - { - int pbits; -+ const BIGNUM *p, *pub_key; -+ BIGNUM *priv_key; - -- if (need < 0 || dh->p == NULL || -- (pbits = BN_num_bits(dh->p)) <= 0 || -+ DH_get0_pqg(dh, &p, NULL, NULL); -+ -+ if (need < 0 || p == NULL || -+ (pbits = BN_num_bits(p)) <= 0 || - need > INT_MAX / 2 || 2 * need > pbits) - return SSH_ERR_INVALID_ARGUMENT; - if (need < 256) -@@ -275,11 +281,13 @@ dh_gen_key(DH *dh, int need) - * Pollard Rho, Big step/Little Step attacks are O(sqrt(n)), - * so double requested need here. - */ -- dh->length = MINIMUM(need * 2, pbits - 1); -- if (DH_generate_key(dh) == 0 || -- !dh_pub_is_valid(dh, dh->pub_key)) { -- BN_clear_free(dh->priv_key); -- dh->priv_key = NULL; -+ DH_set_length(dh, MIN(need * 2, pbits - 1)); -+ if (DH_generate_key(dh) == 0) { -+ return SSH_ERR_LIBCRYPTO_ERROR; -+ } -+ DH_get0_key(dh, &pub_key, &priv_key); -+ if (!dh_pub_is_valid(dh, pub_key)) { -+ BN_clear(priv_key); - return SSH_ERR_LIBCRYPTO_ERROR; - } - return 0; -@@ -288,16 +296,27 @@ dh_gen_key(DH *dh, int need) - DH * - dh_new_group_asc(const char *gen, const char *modulus) - { -- DH *dh; -+ DH *dh = NULL; -+ BIGNUM *p=NULL, *g=NULL; - -- if ((dh = DH_new()) == NULL) -- return NULL; -- if (BN_hex2bn(&dh->p, modulus) == 0 || -- BN_hex2bn(&dh->g, gen) == 0) { -- DH_free(dh); -- return NULL; -+ if ((dh = DH_new()) == NULL || -+ (p = BN_new()) == NULL || -+ (g = BN_new()) == NULL) -+ goto null; -+ if (BN_hex2bn(&p, modulus) == 0 || -+ BN_hex2bn(&g, gen) == 0) { -+ goto null; - } -+ if (DH_set0_pqg(dh, p, NULL, g) == 0) { -+ goto null; -+ } -+ p = g = NULL; - return (dh); -+null: -+ BN_free(p); -+ BN_free(g); -+ DH_free(dh); -+ return NULL; - } - - /* -@@ -312,8 +331,8 @@ dh_new_group(BIGNUM *gen, BIGNUM *modulu - - if ((dh = DH_new()) == NULL) - return NULL; -- dh->p = modulus; -- dh->g = gen; -+ if (DH_set0_pqg(dh, modulus, NULL, gen) == 0) -+ return NULL; - - return (dh); - } -diff -aurp old/dh.h new/dh.h ---- old/dh.h 2018-08-22 22:41:42.000000000 -0700 -+++ new/dh.h 2018-08-23 21:31:53.331259457 -0700 -@@ -42,7 +42,7 @@ DH *dh_new_group18(void); - DH *dh_new_group_fallback(int); - - int dh_gen_key(DH *, int); --int dh_pub_is_valid(DH *, BIGNUM *); -+int dh_pub_is_valid(const DH *, const BIGNUM *); - - u_int dh_estimate(int); - -diff -aurp old/digest-openssl.c new/digest-openssl.c ---- old/digest-openssl.c 2018-08-22 22:41:42.000000000 -0700 -+++ new/digest-openssl.c 2018-08-23 21:31:53.331259457 -0700 -@@ -43,7 +43,7 @@ - - struct ssh_digest_ctx { - int alg; -- EVP_MD_CTX mdctx; -+ EVP_MD_CTX *mdctx; - }; - - struct ssh_digest { -@@ -106,20 +106,21 @@ ssh_digest_bytes(int alg) - size_t - ssh_digest_blocksize(struct ssh_digest_ctx *ctx) - { -- return EVP_MD_CTX_block_size(&ctx->mdctx); -+ return EVP_MD_CTX_block_size(ctx->mdctx); - } - - struct ssh_digest_ctx * - ssh_digest_start(int alg) - { - const struct ssh_digest *digest = ssh_digest_by_alg(alg); -- struct ssh_digest_ctx *ret; -+ struct ssh_digest_ctx *ret = NULL; - - if (digest == NULL || ((ret = calloc(1, sizeof(*ret))) == NULL)) - return NULL; - ret->alg = alg; -- EVP_MD_CTX_init(&ret->mdctx); -- if (EVP_DigestInit_ex(&ret->mdctx, digest->mdfunc(), NULL) != 1) { -+ if ((ret->mdctx = EVP_MD_CTX_new()) == NULL || -+ EVP_DigestInit_ex(ret->mdctx, digest->mdfunc(), NULL) != 1) { -+ EVP_MD_CTX_free(ret->mdctx); - free(ret); - return NULL; - } -@@ -132,7 +133,7 @@ ssh_digest_copy_state(struct ssh_digest_ - if (from->alg != to->alg) - return SSH_ERR_INVALID_ARGUMENT; - /* we have bcopy-style order while openssl has memcpy-style */ -- if (!EVP_MD_CTX_copy_ex(&to->mdctx, &from->mdctx)) -+ if (!EVP_MD_CTX_copy_ex(to->mdctx, from->mdctx)) - return SSH_ERR_LIBCRYPTO_ERROR; - return 0; - } -@@ -140,7 +141,7 @@ ssh_digest_copy_state(struct ssh_digest_ - int - ssh_digest_update(struct ssh_digest_ctx *ctx, const void *m, size_t mlen) - { -- if (EVP_DigestUpdate(&ctx->mdctx, m, mlen) != 1) -+ if (EVP_DigestUpdate(ctx->mdctx, m, mlen) != 1) - return SSH_ERR_LIBCRYPTO_ERROR; - return 0; - } -@@ -161,7 +162,7 @@ ssh_digest_final(struct ssh_digest_ctx * - return SSH_ERR_INVALID_ARGUMENT; - if (dlen < digest->digest_len) /* No truncation allowed */ - return SSH_ERR_INVALID_ARGUMENT; -- if (EVP_DigestFinal_ex(&ctx->mdctx, d, &l) != 1) -+ if (EVP_DigestFinal_ex(ctx->mdctx, d, &l) != 1) - return SSH_ERR_LIBCRYPTO_ERROR; - if (l != digest->digest_len) /* sanity */ - return SSH_ERR_INTERNAL_ERROR; -@@ -172,7 +173,7 @@ void - ssh_digest_free(struct ssh_digest_ctx *ctx) - { - if (ctx != NULL) { -- EVP_MD_CTX_cleanup(&ctx->mdctx); -+ EVP_MD_CTX_free(ctx->mdctx); - explicit_bzero(ctx, sizeof(*ctx)); - free(ctx); - } -diff -aurp old/kexdhc.c new/kexdhc.c ---- old/kexdhc.c 2018-08-22 22:41:42.000000000 -0700 -+++ new/kexdhc.c 2018-08-23 21:31:53.331259457 -0700 -@@ -81,11 +81,16 @@ kexdh_client(struct ssh *ssh) - goto out; - } - debug("sending SSH2_MSG_KEXDH_INIT"); -- if ((r = dh_gen_key(kex->dh, kex->we_need * 8)) != 0 || -- (r = sshpkt_start(ssh, SSH2_MSG_KEXDH_INIT)) != 0 || -- (r = sshpkt_put_bignum2(ssh, kex->dh->pub_key)) != 0 || -+ { -+ const BIGNUM *pub_key; -+ if ((r = dh_gen_key(kex->dh, kex->we_need * 8)) != 0) -+ goto out; -+ DH_get0_key(kex->dh, &pub_key, NULL); -+ if ((r = sshpkt_start(ssh, SSH2_MSG_KEXDH_INIT)) != 0 || -+ (r = sshpkt_put_bignum2(ssh, pub_key)) != 0 || - (r = sshpkt_send(ssh)) != 0) - goto out; -+ } - #ifdef DEBUG_KEXDH - DHparams_print_fp(stderr, kex->dh); - fprintf(stderr, "pub= "); -@@ -169,6 +174,9 @@ input_kex_dh(int type, u_int32_t seq, st - - /* calc and verify H */ - hashlen = sizeof(hash); -+ { -+ const BIGNUM *pub_key; -+ DH_get0_key(kex->dh, &pub_key, NULL); - if ((r = kex_dh_hash( - kex->hash_alg, - kex->client_version_string, -@@ -176,11 +184,13 @@ input_kex_dh(int type, u_int32_t seq, st - sshbuf_ptr(kex->my), sshbuf_len(kex->my), - sshbuf_ptr(kex->peer), sshbuf_len(kex->peer), - server_host_key_blob, sbloblen, -- kex->dh->pub_key, -+ pub_key, - dh_server_pub, - shared_secret, -- hash, &hashlen)) != 0) -+ hash, &hashlen)) != 0) { - goto out; -+ } -+ } - - if ((r = sshkey_verify(server_host_key, signature, slen, hash, hashlen, - kex->hostkey_alg, ssh->compat)) != 0) -diff -aurp old/kexdhs.c new/kexdhs.c ---- old/kexdhs.c 2018-08-22 22:41:42.000000000 -0700 -+++ new/kexdhs.c 2018-08-23 21:36:50.600564263 -0700 -@@ -163,6 +163,9 @@ input_kex_dh_init(int type, u_int32_t se - goto out; - /* calc H */ - hashlen = sizeof(hash); -+ { -+ const BIGNUM *pub_key; -+ DH_get0_key(kex->dh, &pub_key, NULL); - if ((r = kex_dh_hash( - kex->hash_alg, - kex->client_version_string, -@@ -171,10 +174,12 @@ input_kex_dh_init(int type, u_int32_t se - sshbuf_ptr(kex->my), sshbuf_len(kex->my), - server_host_key_blob, sbloblen, - dh_client_pub, -- kex->dh->pub_key, -+ pub_key, - shared_secret, -- hash, &hashlen)) != 0) -+ hash, &hashlen)) != 0) { - goto out; -+ } -+ } - - /* save session id := H */ - if (kex->session_id == NULL) { -@@ -195,12 +200,16 @@ input_kex_dh_init(int type, u_int32_t se - /* destroy_sensitive_data(); */ - - /* send server hostkey, DH pubkey 'f' and signed H */ -+ { -+ const BIGNUM *pub_key; -+ DH_get0_key(kex->dh, &pub_key, NULL); - if ((r = sshpkt_start(ssh, SSH2_MSG_KEXDH_REPLY)) != 0 || - (r = sshpkt_put_string(ssh, server_host_key_blob, sbloblen)) != 0 || -- (r = sshpkt_put_bignum2(ssh, kex->dh->pub_key)) != 0 || /* f */ -+ (r = sshpkt_put_bignum2(ssh, pub_key)) != 0 || /* f */ - (r = sshpkt_put_string(ssh, signature, slen)) != 0 || - (r = sshpkt_send(ssh)) != 0) - goto out; -+ } - - if ((r = kex_derive_keys_bn(ssh, hash, hashlen, shared_secret)) == 0) - r = kex_send_newkeys(ssh); -diff -aurp old/kexgexc.c new/kexgexc.c ---- old/kexgexc.c 2018-08-22 22:41:42.000000000 -0700 -+++ new/kexgexc.c 2018-08-23 21:31:53.331259457 -0700 -@@ -118,11 +118,17 @@ input_kex_dh_gex_group(int type, u_int32 - p = g = NULL; /* belong to kex->dh now */ - - /* generate and send 'e', client DH public key */ -- if ((r = dh_gen_key(kex->dh, kex->we_need * 8)) != 0 || -- (r = sshpkt_start(ssh, SSH2_MSG_KEX_DH_GEX_INIT)) != 0 || -- (r = sshpkt_put_bignum2(ssh, kex->dh->pub_key)) != 0 || -- (r = sshpkt_send(ssh)) != 0) -+ { -+ const BIGNUM *pub_key; -+ if ((r = dh_gen_key(kex->dh, kex->we_need * 8)) != 0) -+ goto out; -+ DH_get0_key(kex->dh, &pub_key, NULL); -+ if ((r = sshpkt_start(ssh, SSH2_MSG_KEX_DH_GEX_INIT)) != 0 || -+ (r = sshpkt_put_bignum2(ssh, pub_key)) != 0 || -+ (r = sshpkt_send(ssh)) != 0) { - goto out; -+ } -+ } - debug("SSH2_MSG_KEX_DH_GEX_INIT sent"); - #ifdef DEBUG_KEXDH - DHparams_print_fp(stderr, kex->dh); -@@ -212,6 +218,10 @@ input_kex_dh_gex_reply(int type, u_int32 - - /* calc and verify H */ - hashlen = sizeof(hash); -+ { -+ const BIGNUM *p, *g, *pub_key; -+ DH_get0_pqg(kex->dh, &p, NULL, &g); -+ DH_get0_key(kex->dh, &pub_key, NULL); - if ((r = kexgex_hash( - kex->hash_alg, - kex->client_version_string, -@@ -220,12 +230,14 @@ input_kex_dh_gex_reply(int type, u_int32 - sshbuf_ptr(kex->peer), sshbuf_len(kex->peer), - server_host_key_blob, sbloblen, - kex->min, kex->nbits, kex->max, -- kex->dh->p, kex->dh->g, -- kex->dh->pub_key, -+ p, g, -+ pub_key, - dh_server_pub, - shared_secret, -- hash, &hashlen)) != 0) -+ hash, &hashlen)) != 0) { - goto out; -+ } -+ } - - if ((r = sshkey_verify(server_host_key, signature, slen, hash, - hashlen, kex->hostkey_alg, ssh->compat)) != 0) -diff -aurp old/kexgexs.c new/kexgexs.c ---- old/kexgexs.c 2018-08-22 22:41:42.000000000 -0700 -+++ new/kexgexs.c 2018-08-23 21:36:11.493972372 -0700 -@@ -101,11 +101,16 @@ input_kex_dh_gex_request(int type, u_int - goto out; - } - debug("SSH2_MSG_KEX_DH_GEX_GROUP sent"); -+ { -+ const BIGNUM *p, *g; -+ DH_get0_pqg(kex->dh, &p, NULL, &g); - if ((r = sshpkt_start(ssh, SSH2_MSG_KEX_DH_GEX_GROUP)) != 0 || -- (r = sshpkt_put_bignum2(ssh, kex->dh->p)) != 0 || -- (r = sshpkt_put_bignum2(ssh, kex->dh->g)) != 0 || -- (r = sshpkt_send(ssh)) != 0) -+ (r = sshpkt_put_bignum2(ssh, p)) != 0 || -+ (r = sshpkt_put_bignum2(ssh, g)) != 0 || -+ (r = sshpkt_send(ssh)) != 0) { - goto out; -+ } -+ } - - /* Compute our exchange value in parallel with the client */ - if ((r = dh_gen_key(kex->dh, kex->we_need * 8)) != 0) -@@ -191,6 +196,10 @@ input_kex_dh_gex_init(int type, u_int32_ - goto out; - /* calc H */ - hashlen = sizeof(hash); -+ { -+ const BIGNUM *p, *g, *pub_key; -+ DH_get0_pqg(kex->dh, &p, NULL, &g); -+ DH_get0_key(kex->dh, &pub_key, NULL); - if ((r = kexgex_hash( - kex->hash_alg, - kex->client_version_string, -@@ -199,12 +208,14 @@ input_kex_dh_gex_init(int type, u_int32_ - sshbuf_ptr(kex->my), sshbuf_len(kex->my), - server_host_key_blob, sbloblen, - kex->min, kex->nbits, kex->max, -- kex->dh->p, kex->dh->g, -+ p, g, - dh_client_pub, -- kex->dh->pub_key, -+ pub_key, - shared_secret, -- hash, &hashlen)) != 0) -+ hash, &hashlen)) != 0) { - goto out; -+ } -+ } - - /* save session id := H */ - if (kex->session_id == NULL) { -@@ -225,12 +236,16 @@ input_kex_dh_gex_init(int type, u_int32_ - /* destroy_sensitive_data(); */ - - /* send server hostkey, DH pubkey 'f' and signed H */ -+ { -+ const BIGNUM *pub_key; -+ DH_get0_key(kex->dh, &pub_key, NULL); - if ((r = sshpkt_start(ssh, SSH2_MSG_KEX_DH_GEX_REPLY)) != 0 || - (r = sshpkt_put_string(ssh, server_host_key_blob, sbloblen)) != 0 || -- (r = sshpkt_put_bignum2(ssh, kex->dh->pub_key)) != 0 || /* f */ -+ (r = sshpkt_put_bignum2(ssh, pub_key)) != 0 || /* f */ - (r = sshpkt_put_string(ssh, signature, slen)) != 0 || - (r = sshpkt_send(ssh)) != 0) - goto out; -+ } - - if ((r = kex_derive_keys_bn(ssh, hash, hashlen, shared_secret)) == 0) - r = kex_send_newkeys(ssh); -diff -aurp old/monitor.c new/monitor.c ---- old/monitor.c 2018-08-22 22:41:42.000000000 -0700 -+++ new/monitor.c 2018-08-23 21:34:14.594343260 -0700 -@@ -589,10 +589,12 @@ mm_answer_moduli(int sock, struct sshbuf - fatal("%s: buffer error: %s", __func__, ssh_err(r)); - return (0); - } else { -+ const BIGNUM *p, *g; -+ DH_get0_pqg(dh, &p, NULL, &g); - /* Send first bignum */ - if ((r = sshbuf_put_u8(m, 1)) != 0 || -- (r = sshbuf_put_bignum2(m, dh->p)) != 0 || -- (r = sshbuf_put_bignum2(m, dh->g)) != 0) -+ (r = sshbuf_put_bignum2(m, p)) != 0 || -+ (r = sshbuf_put_bignum2(m, g)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); - - DH_free(dh); -diff -aurp old/openbsd-compat/openssl-compat.c new/openbsd-compat/openssl-compat.c ---- old/openbsd-compat/openssl-compat.c 2018-08-22 22:41:42.000000000 -0700 -+++ new/openbsd-compat/openssl-compat.c 2018-08-23 21:31:53.334592801 -0700 -@@ -75,7 +75,6 @@ ssh_OpenSSL_add_all_algorithms(void) - /* Enable use of crypto hardware */ - ENGINE_load_builtin_engines(); - ENGINE_register_all_complete(); -- OPENSSL_config(NULL); - } - #endif - -diff -aurp old/regress/unittests/sshkey/test_file.c new/regress/unittests/sshkey/test_file.c ---- old/regress/unittests/sshkey/test_file.c 2018-08-22 22:41:42.000000000 -0700 -+++ new/regress/unittests/sshkey/test_file.c 2018-08-23 21:31:53.334592801 -0700 -@@ -60,9 +60,14 @@ sshkey_file_tests(void) - a = load_bignum("rsa_1.param.n"); - b = load_bignum("rsa_1.param.p"); - c = load_bignum("rsa_1.param.q"); -- ASSERT_BIGNUM_EQ(k1->rsa->n, a); -- ASSERT_BIGNUM_EQ(k1->rsa->p, b); -- ASSERT_BIGNUM_EQ(k1->rsa->q, c); -+ { -+ const BIGNUM *n, *p, *q; -+ RSA_get0_key(k1->rsa, &n, NULL, NULL); -+ RSA_get0_factors(k1->rsa, &p, &q); -+ ASSERT_BIGNUM_EQ(n, a); -+ ASSERT_BIGNUM_EQ(p, b); -+ ASSERT_BIGNUM_EQ(q, c); -+ } - BN_free(a); - BN_free(b); - BN_free(c); -@@ -151,9 +156,14 @@ sshkey_file_tests(void) - a = load_bignum("dsa_1.param.g"); - b = load_bignum("dsa_1.param.priv"); - c = load_bignum("dsa_1.param.pub"); -- ASSERT_BIGNUM_EQ(k1->dsa->g, a); -- ASSERT_BIGNUM_EQ(k1->dsa->priv_key, b); -- ASSERT_BIGNUM_EQ(k1->dsa->pub_key, c); -+ { -+ const BIGNUM *g, *priv_key, *pub_key; -+ DSA_get0_pqg(k1->dsa, NULL, NULL, &g); -+ DSA_get0_key(k1->dsa, &pub_key, &priv_key); -+ ASSERT_BIGNUM_EQ(g, a); -+ ASSERT_BIGNUM_EQ(priv_key, b); -+ ASSERT_BIGNUM_EQ(pub_key, c); -+ } - BN_free(a); - BN_free(b); - BN_free(c); -diff -aurp old/regress/unittests/sshkey/test_sshkey.c new/regress/unittests/sshkey/test_sshkey.c ---- old/regress/unittests/sshkey/test_sshkey.c 2018-08-22 22:41:42.000000000 -0700 -+++ new/regress/unittests/sshkey/test_sshkey.c 2018-08-23 21:31:53.334592801 -0700 -@@ -197,9 +197,14 @@ sshkey_tests(void) - k1 = sshkey_new(KEY_RSA); - ASSERT_PTR_NE(k1, NULL); - ASSERT_PTR_NE(k1->rsa, NULL); -- ASSERT_PTR_NE(k1->rsa->n, NULL); -- ASSERT_PTR_NE(k1->rsa->e, NULL); -- ASSERT_PTR_EQ(k1->rsa->p, NULL); -+ { -+ const BIGNUM *n, *e, *p; -+ RSA_get0_key(k1->rsa, &n, &e, NULL); -+ RSA_get0_factors(k1->rsa, &p, NULL); -+ ASSERT_PTR_NE(n, NULL); -+ ASSERT_PTR_NE(e, NULL); -+ ASSERT_PTR_EQ(p, NULL); -+ } - sshkey_free(k1); - TEST_DONE(); - -@@ -207,8 +212,13 @@ sshkey_tests(void) - k1 = sshkey_new(KEY_DSA); - ASSERT_PTR_NE(k1, NULL); - ASSERT_PTR_NE(k1->dsa, NULL); -- ASSERT_PTR_NE(k1->dsa->g, NULL); -- ASSERT_PTR_EQ(k1->dsa->priv_key, NULL); -+ { -+ const BIGNUM *g, *priv_key; -+ DSA_get0_pqg(k1->dsa, NULL, NULL, &g); -+ DSA_get0_key(k1->dsa, NULL, &priv_key); -+ ASSERT_PTR_NE(g, NULL); -+ ASSERT_PTR_EQ(priv_key, NULL); -+ } - sshkey_free(k1); - TEST_DONE(); - -@@ -234,9 +244,14 @@ sshkey_tests(void) - k1 = sshkey_new_private(KEY_RSA); - ASSERT_PTR_NE(k1, NULL); - ASSERT_PTR_NE(k1->rsa, NULL); -- ASSERT_PTR_NE(k1->rsa->n, NULL); -- ASSERT_PTR_NE(k1->rsa->e, NULL); -- ASSERT_PTR_NE(k1->rsa->p, NULL); -+ { -+ const BIGNUM *n, *e, *p; -+ RSA_get0_key(k1->rsa, &n, &e, NULL); -+ RSA_get0_factors(k1->rsa, &p, NULL); -+ ASSERT_PTR_NE(n, NULL); -+ ASSERT_PTR_NE(e, NULL); -+ ASSERT_PTR_NE(p, NULL); -+ } - ASSERT_INT_EQ(sshkey_add_private(k1), 0); - sshkey_free(k1); - TEST_DONE(); -@@ -245,8 +260,13 @@ sshkey_tests(void) - k1 = sshkey_new_private(KEY_DSA); - ASSERT_PTR_NE(k1, NULL); - ASSERT_PTR_NE(k1->dsa, NULL); -- ASSERT_PTR_NE(k1->dsa->g, NULL); -- ASSERT_PTR_NE(k1->dsa->priv_key, NULL); -+ { -+ const BIGNUM *g, *priv_key; -+ DSA_get0_pqg(k1->dsa, NULL, NULL, &g); -+ DSA_get0_key(k1->dsa, NULL, &priv_key); -+ ASSERT_PTR_NE(g, NULL); -+ ASSERT_PTR_NE(priv_key, NULL); -+ } - ASSERT_INT_EQ(sshkey_add_private(k1), 0); - sshkey_free(k1); - TEST_DONE(); -@@ -285,18 +305,28 @@ sshkey_tests(void) - ASSERT_INT_EQ(sshkey_generate(KEY_RSA, 1024, &kr), 0); - ASSERT_PTR_NE(kr, NULL); - ASSERT_PTR_NE(kr->rsa, NULL); -- ASSERT_PTR_NE(kr->rsa->n, NULL); -- ASSERT_PTR_NE(kr->rsa->e, NULL); -- ASSERT_PTR_NE(kr->rsa->p, NULL); -- ASSERT_INT_EQ(BN_num_bits(kr->rsa->n), 1024); -+ { -+ const BIGNUM *n, *e, *p; -+ RSA_get0_key(kr->rsa, &n, &e, NULL); -+ RSA_get0_factors(kr->rsa, &p, NULL); -+ ASSERT_PTR_NE(n, NULL); -+ ASSERT_PTR_NE(e, NULL); -+ ASSERT_PTR_NE(p, NULL); -+ ASSERT_INT_EQ(BN_num_bits(n), 1024); -+ } - TEST_DONE(); - - 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); -- ASSERT_PTR_NE(kd->dsa->g, NULL); -- ASSERT_PTR_NE(kd->dsa->priv_key, NULL); -+ { -+ const BIGNUM *g, *priv_key; -+ DSA_get0_pqg(kd->dsa, NULL, NULL, &g); -+ DSA_get0_key(kd->dsa, NULL, &priv_key); -+ ASSERT_PTR_NE(g, NULL); -+ ASSERT_PTR_NE(priv_key, NULL); -+ } - TEST_DONE(); - - #ifdef OPENSSL_HAS_ECC -@@ -323,9 +353,14 @@ sshkey_tests(void) - ASSERT_PTR_NE(kr, k1); - ASSERT_INT_EQ(k1->type, KEY_RSA); - ASSERT_PTR_NE(k1->rsa, NULL); -- ASSERT_PTR_NE(k1->rsa->n, NULL); -- ASSERT_PTR_NE(k1->rsa->e, NULL); -- ASSERT_PTR_EQ(k1->rsa->p, NULL); -+ { -+ const BIGNUM *n, *e, *p; -+ RSA_get0_key(k1->rsa, &n, &e, NULL); -+ RSA_get0_factors(k1->rsa, &p, NULL); -+ ASSERT_PTR_NE(n, NULL); -+ ASSERT_PTR_NE(e, NULL); -+ ASSERT_PTR_EQ(p, NULL); -+ } - TEST_DONE(); - - TEST_START("equal KEY_RSA/demoted KEY_RSA"); -@@ -339,8 +374,13 @@ sshkey_tests(void) - ASSERT_PTR_NE(kd, k1); - ASSERT_INT_EQ(k1->type, KEY_DSA); - ASSERT_PTR_NE(k1->dsa, NULL); -- ASSERT_PTR_NE(k1->dsa->g, NULL); -- ASSERT_PTR_EQ(k1->dsa->priv_key, NULL); -+ { -+ const BIGNUM *g, *priv_key; -+ DSA_get0_pqg(k1->dsa, NULL, NULL, &g); -+ DSA_get0_key(k1->dsa, NULL, &priv_key); -+ ASSERT_PTR_NE(g, NULL); -+ ASSERT_PTR_EQ(priv_key, NULL); -+ } - TEST_DONE(); - - TEST_START("equal KEY_DSA/demoted KEY_DSA"); -diff -aurp old/ssh-dss.c new/ssh-dss.c ---- old/ssh-dss.c 2018-08-22 22:41:42.000000000 -0700 -+++ new/ssh-dss.c 2018-08-23 21:31:53.334592801 -0700 -@@ -53,6 +53,7 @@ ssh_dss_sign(const struct sshkey *key, u - DSA_SIG *sig = NULL; - u_char digest[SSH_DIGEST_MAX_LENGTH], sigblob[SIGBLOB_LEN]; - size_t rlen, slen, len, dlen = ssh_digest_bytes(SSH_DIGEST_SHA1); -+ const BIGNUM *r, *s; - struct sshbuf *b = NULL; - int ret = SSH_ERR_INVALID_ARGUMENT; - -@@ -76,15 +77,16 @@ ssh_dss_sign(const struct sshkey *key, u - goto out; - } - -- rlen = BN_num_bytes(sig->r); -- slen = BN_num_bytes(sig->s); -+ DSA_SIG_get0(sig, &r, &s); -+ rlen = BN_num_bytes(r); -+ slen = BN_num_bytes(s); - if (rlen > INTBLOB_LEN || slen > INTBLOB_LEN) { - ret = SSH_ERR_INTERNAL_ERROR; - goto out; - } - explicit_bzero(sigblob, SIGBLOB_LEN); -- BN_bn2bin(sig->r, sigblob + SIGBLOB_LEN - INTBLOB_LEN - rlen); -- BN_bn2bin(sig->s, sigblob + SIGBLOB_LEN - slen); -+ BN_bn2bin(r, sigblob + SIGBLOB_LEN - INTBLOB_LEN - rlen); -+ BN_bn2bin(s, sigblob + SIGBLOB_LEN - slen); - - if ((b = sshbuf_new()) == NULL) { - ret = SSH_ERR_ALLOC_FAIL; -@@ -154,17 +156,26 @@ ssh_dss_verify(const struct sshkey *key, - } - - /* parse signature */ -+ { -+ BIGNUM *r=NULL, *s=NULL; - if ((sig = DSA_SIG_new()) == NULL || -- (sig->r = BN_new()) == NULL || -- (sig->s = BN_new()) == NULL) { -+ (r = BN_new()) == NULL || -+ (s = BN_new()) == NULL) { - ret = SSH_ERR_ALLOC_FAIL; -+ BN_free(r); -+ BN_free(s); - goto out; - } -- if ((BN_bin2bn(sigblob, INTBLOB_LEN, sig->r) == NULL) || -- (BN_bin2bn(sigblob+ INTBLOB_LEN, INTBLOB_LEN, sig->s) == NULL)) { -+ if ((BN_bin2bn(sigblob, INTBLOB_LEN, r) == NULL) || -+ (BN_bin2bn(sigblob+ INTBLOB_LEN, INTBLOB_LEN, s) == NULL)) { - ret = SSH_ERR_LIBCRYPTO_ERROR; -+ BN_free(r); -+ BN_free(s); - goto out; - } -+ DSA_SIG_set0(sig, r, s); -+ r = s = NULL; -+ } - - /* sha1 the data */ - if ((ret = ssh_digest_memory(SSH_DIGEST_SHA1, data, datalen, -diff -aurp old/ssh-ecdsa.c new/ssh-ecdsa.c ---- old/ssh-ecdsa.c 2018-08-22 22:41:42.000000000 -0700 -+++ new/ssh-ecdsa.c 2018-08-23 21:31:53.334592801 -0700 -@@ -80,9 +80,14 @@ ssh_ecdsa_sign(const struct sshkey *key, - ret = SSH_ERR_ALLOC_FAIL; - goto out; - } -- if ((ret = sshbuf_put_bignum2(bb, sig->r)) != 0 || -- (ret = sshbuf_put_bignum2(bb, sig->s)) != 0) -+ { -+ const BIGNUM *r, *s; -+ ECDSA_SIG_get0(sig, &r, &s); -+ if ((ret = sshbuf_put_bignum2(bb, r)) != 0 || -+ (ret = sshbuf_put_bignum2(bb, s)) != 0) { - goto out; -+ } -+ } - if ((ret = sshbuf_put_cstring(b, sshkey_ssh_name_plain(key))) != 0 || - (ret = sshbuf_put_stringb(b, bb)) != 0) - goto out; -@@ -150,11 +155,27 @@ ssh_ecdsa_verify(const struct sshkey *ke - ret = SSH_ERR_ALLOC_FAIL; - goto out; - } -- if (sshbuf_get_bignum2(sigbuf, sig->r) != 0 || -- sshbuf_get_bignum2(sigbuf, sig->s) != 0) { -+ { -+ BIGNUM *r=NULL, *s=NULL; -+ if ((r = BN_new()) == NULL || -+ (s = BN_new()) == NULL) { -+ ret = SSH_ERR_ALLOC_FAIL; -+ goto out_rs; -+ } -+ if (sshbuf_get_bignum2(sigbuf, r) != 0 || -+ sshbuf_get_bignum2(sigbuf, s) != 0) { - ret = SSH_ERR_INVALID_FORMAT; -+ goto out_rs; -+ } -+ if (ECDSA_SIG_set0(sig, r, s) == 0) { -+ ret = SSH_ERR_LIBCRYPTO_ERROR; -+out_rs: -+ BN_free(r); -+ BN_free(s); - goto out; - } -+ r = s = NULL; -+ } - if (sshbuf_len(sigbuf) != 0) { - ret = SSH_ERR_UNEXPECTED_TRAILING_DATA; - goto out; -diff -aurp old/ssh-keygen.c new/ssh-keygen.c ---- old/ssh-keygen.c 2018-08-22 22:41:42.000000000 -0700 -+++ new/ssh-keygen.c 2018-08-23 21:31:53.334592801 -0700 -@@ -494,11 +494,33 @@ do_convert_private_ssh2_from_blob(u_char - - switch (key->type) { - case KEY_DSA: -- buffer_get_bignum_bits(b, key->dsa->p); -- buffer_get_bignum_bits(b, key->dsa->g); -- buffer_get_bignum_bits(b, key->dsa->q); -- buffer_get_bignum_bits(b, key->dsa->pub_key); -- buffer_get_bignum_bits(b, key->dsa->priv_key); -+ { -+ BIGNUM *p=NULL, *g=NULL, *q=NULL, *pub_key=NULL, *priv_key=NULL; -+ if ((p=BN_new()) == NULL || -+ (g=BN_new()) == NULL || -+ (q=BN_new()) == NULL || -+ (pub_key=BN_new()) == NULL || -+ (priv_key=BN_new()) == NULL) { -+ BN_free(p); -+ BN_free(g); -+ BN_free(q); -+ BN_free(pub_key); -+ BN_free(priv_key); -+ return NULL; -+ } -+ buffer_get_bignum_bits(b, p); -+ buffer_get_bignum_bits(b, g); -+ buffer_get_bignum_bits(b, q); -+ buffer_get_bignum_bits(b, pub_key); -+ buffer_get_bignum_bits(b, priv_key); -+ if (DSA_set0_pqg(key->dsa, p, q, g) == 0 || -+ DSA_set0_key(key->dsa, pub_key, priv_key) == 0) { -+ fatal("failed to set DSA key"); -+ BN_free(p); BN_free(g); BN_free(q); -+ BN_free(pub_key); BN_free(priv_key); -+ return NULL; -+ } -+ } - break; - case KEY_RSA: - if ((r = sshbuf_get_u8(b, &e1)) != 0 || -@@ -515,16 +537,52 @@ do_convert_private_ssh2_from_blob(u_char - e += e3; - debug("e %lx", e); - } -- if (!BN_set_word(key->rsa->e, e)) { -+ { -+ BIGNUM *rsa_e = NULL; -+ BIGNUM *d=NULL, *n=NULL, *iqmp=NULL, *q=NULL, *p=NULL; -+ BIGNUM *dmp1=NULL, *dmq1=NULL; /* dummy input to set in RSA_set0_crt_params */ -+ rsa_e = BN_new(); -+ if (!rsa_e || !BN_set_word(rsa_e, e)) { -+ if (rsa_e) BN_free(rsa_e); - sshbuf_free(b); - sshkey_free(key); - return NULL; - } -- buffer_get_bignum_bits(b, key->rsa->d); -- buffer_get_bignum_bits(b, key->rsa->n); -- buffer_get_bignum_bits(b, key->rsa->iqmp); -- buffer_get_bignum_bits(b, key->rsa->q); -- buffer_get_bignum_bits(b, key->rsa->p); -+ if ((d=BN_new()) == NULL || -+ (n=BN_new()) == NULL || -+ (iqmp=BN_new()) == NULL || -+ (q=BN_new()) == NULL || -+ (p=BN_new()) == NULL || -+ (dmp1=BN_new()) == NULL || -+ (dmq1=BN_new()) == NULL) { -+ BN_free(d); BN_free(n); BN_free(iqmp); -+ BN_free(q); BN_free(p); -+ BN_free(dmp1); BN_free(dmq1); -+ return NULL; -+ } -+ BN_clear(dmp1); BN_clear(dmq1); -+ buffer_get_bignum_bits(b, d); -+ buffer_get_bignum_bits(b, n); -+ buffer_get_bignum_bits(b, iqmp); -+ buffer_get_bignum_bits(b, q); -+ buffer_get_bignum_bits(b, p); -+ if (RSA_set0_key(key->rsa, n, rsa_e, d) == 0) -+ goto null; -+ n = d = NULL; -+ if (RSA_set0_factors(key->rsa, p, q) == 0) -+ goto null; -+ p = q = NULL; -+ /* dmp1, dmq1 should not be NULL for initial set0 */ -+ if (RSA_set0_crt_params(key->rsa, dmp1, dmq1, iqmp) == 0) { -+ null: -+ fatal("Failed to set RSA parameters"); -+ BN_free(d); BN_free(n); BN_free(iqmp); -+ BN_free(q); BN_free(p); -+ BN_free(dmp1); BN_free(dmq1); -+ return NULL; -+ } -+ dmp1 = dmq1 = iqmp = NULL; -+ } - if ((r = ssh_rsa_generate_additional_parameters(key)) != 0) - fatal("generate RSA parameters failed: %s", ssh_err(r)); - break; -@@ -634,7 +692,7 @@ do_convert_from_pkcs8(struct sshkey **k, - identity_file); - } - fclose(fp); -- switch (EVP_PKEY_type(pubkey->type)) { -+ switch (EVP_PKEY_type(EVP_PKEY_id(pubkey))) { - case EVP_PKEY_RSA: - if ((*k = sshkey_new(KEY_UNSPEC)) == NULL) - fatal("sshkey_new failed"); -@@ -658,7 +716,7 @@ do_convert_from_pkcs8(struct sshkey **k, - #endif - default: - fatal("%s: unsupported pubkey type %d", __func__, -- EVP_PKEY_type(pubkey->type)); -+ EVP_PKEY_type(EVP_PKEY_id(pubkey))); - } - EVP_PKEY_free(pubkey); - return; -diff -aurp old/ssh-pkcs11-client.c new/ssh-pkcs11-client.c ---- old/ssh-pkcs11-client.c 2018-08-22 22:41:42.000000000 -0700 -+++ new/ssh-pkcs11-client.c 2018-08-23 21:31:53.334592801 -0700 -@@ -156,12 +156,13 @@ pkcs11_rsa_private_encrypt(int flen, con - static int - wrap_key(RSA *rsa) - { -- static RSA_METHOD helper_rsa; -+ static RSA_METHOD *helper_rsa; - -- memcpy(&helper_rsa, RSA_get_default_method(), sizeof(helper_rsa)); -- helper_rsa.name = "ssh-pkcs11-helper"; -- helper_rsa.rsa_priv_enc = pkcs11_rsa_private_encrypt; -- RSA_set_method(rsa, &helper_rsa); -+ if ((helper_rsa = RSA_meth_dup(RSA_get_default_method())) == NULL) -+ return (-1); /* XXX but caller isn't checking */ -+ RSA_meth_set1_name(helper_rsa, "ssh-pkcs11-helper"); -+ RSA_meth_set_priv_enc(helper_rsa, pkcs11_rsa_private_encrypt); -+ RSA_set_method(rsa, helper_rsa); - return (0); - } - -diff -aurp old/ssh-pkcs11.c new/ssh-pkcs11.c ---- old/ssh-pkcs11.c 2018-08-22 22:41:42.000000000 -0700 -+++ new/ssh-pkcs11.c 2018-08-23 21:31:53.334592801 -0700 -@@ -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; - }; -@@ -326,13 +326,15 @@ pkcs11_rsa_wrap(struct pkcs11_provider * - 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->orig_finish = RSA_meth_get_finish(def); -+ -+ if ((k11->rsa_method = RSA_meth_new("pkcs11", RSA_meth_get_flags(def))) == NULL) -+ return -1; -+ 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); -+ -+ RSA_set_method(rsa, k11->rsa_method); - RSA_set_app_data(rsa, k11); - return (0); - } -@@ -512,10 +514,19 @@ pkcs11_fetch_keys_filter(struct pkcs11_p - if ((rsa = RSA_new()) == NULL) { - error("RSA_new failed"); - } else { -- rsa->n = BN_bin2bn(attribs[1].pValue, -- attribs[1].ulValueLen, NULL); -- rsa->e = BN_bin2bn(attribs[2].pValue, -- attribs[2].ulValueLen, NULL); -+ BIGNUM *n=NULL, *e=NULL; -+ n = BN_new(); -+ e = BN_new(); -+ if (n == NULL || e == NULL) -+ error("BN_new alloc failed"); -+ if (BN_bin2bn(attribs[1].pValue, -+ attribs[1].ulValueLen, n) == NULL || -+ BN_bin2bn(attribs[2].pValue, -+ attribs[2].ulValueLen, e) == NULL) -+ error("BN_bin2bn failed"); -+ if (RSA_set0_key(rsa, n, e, NULL) == 0) -+ error("RSA_set0_key failed"); -+ n = e = NULL; - } - } else { - cp = attribs[2].pValue; -@@ -525,16 +536,19 @@ pkcs11_fetch_keys_filter(struct pkcs11_p - == NULL) { - error("d2i_X509 failed"); - } else if ((evp = X509_get_pubkey(x509)) == NULL || -- evp->type != EVP_PKEY_RSA || -- evp->pkey.rsa == NULL) { -+ EVP_PKEY_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)) -+ } else if ((rsa = RSAPublicKey_dup(EVP_PKEY_get0_RSA(evp))) - == NULL) { - error("RSAPublicKey_dup"); - } - X509_free(x509); - } -- if (rsa && rsa->n && rsa->e && -+ { -+ const BIGNUM *n, *e; -+ RSA_get0_key(rsa, &n, &e, NULL); -+ if (rsa && n && e && - pkcs11_rsa_wrap(p, slotidx, &attribs[0], rsa) == 0) { - if ((key = sshkey_new(KEY_UNSPEC)) == NULL) - fatal("sshkey_new failed"); -@@ -554,6 +568,7 @@ pkcs11_fetch_keys_filter(struct pkcs11_p - } else if (rsa) { - RSA_free(rsa); - } -+ } - for (i = 0; i < 3; i++) - free(attribs[i].pValue); - } -diff -aurp old/ssh-rsa.c new/ssh-rsa.c ---- old/ssh-rsa.c 2018-08-22 22:41:42.000000000 -0700 -+++ new/ssh-rsa.c 2018-08-23 21:31:53.334592801 -0700 -@@ -108,7 +108,6 @@ ssh_rsa_generate_additional_parameters(s - { - BIGNUM *aux = NULL; - BN_CTX *ctx = NULL; -- BIGNUM d; - int r; - - if (key == NULL || key->rsa == NULL || -@@ -123,16 +122,27 @@ ssh_rsa_generate_additional_parameters(s - } - BN_set_flags(aux, BN_FLG_CONSTTIME); - -- BN_init(&d); -- BN_with_flags(&d, key->rsa->d, BN_FLG_CONSTTIME); -- -- if ((BN_sub(aux, key->rsa->q, BN_value_one()) == 0) || -- (BN_mod(key->rsa->dmq1, &d, aux, ctx) == 0) || -- (BN_sub(aux, key->rsa->p, BN_value_one()) == 0) || -- (BN_mod(key->rsa->dmp1, &d, aux, ctx) == 0)) { -+ { -+ const BIGNUM *q, *d, *p; -+ BIGNUM *dmq1=NULL, *dmp1=NULL; -+ if ((dmq1 = BN_new()) == NULL || -+ (dmp1 = BN_new()) == NULL ) { -+ r = SSH_ERR_ALLOC_FAIL; -+ goto out; -+ } -+ RSA_get0_key(key->rsa, NULL, NULL, &d); -+ RSA_get0_factors(key->rsa, &p, &q); -+ if ((BN_sub(aux, q, BN_value_one()) == 0) || -+ (BN_mod(dmq1, d, aux, ctx) == 0) || -+ (BN_sub(aux, p, BN_value_one()) == 0) || -+ (BN_mod(dmp1, d, aux, ctx) == 0) || -+ RSA_set0_crt_params(key->rsa, dmp1, dmq1, NULL) == 0) { - r = SSH_ERR_LIBCRYPTO_ERROR; -+ BN_clear_free(dmp1); -+ BN_clear_free(dmq1); - goto out; - } -+ } - r = 0; - out: - BN_clear_free(aux); -@@ -163,7 +173,7 @@ ssh_rsa_sign(const struct sshkey *key, u - if (key == NULL || key->rsa == NULL || hash_alg == -1 || - sshkey_type_plain(key->type) != KEY_RSA) - return SSH_ERR_INVALID_ARGUMENT; -- if (BN_num_bits(key->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) -+ if (RSA_bits(key->rsa) < SSH_RSA_MINIMUM_MODULUS_SIZE) - return SSH_ERR_KEY_LENGTH; - slen = RSA_size(key->rsa); - if (slen <= 0 || slen > SSHBUF_MAX_BIGNUM) -@@ -235,7 +245,7 @@ ssh_rsa_verify(const struct sshkey *key, - sshkey_type_plain(key->type) != KEY_RSA || - sig == NULL || siglen == 0) - return SSH_ERR_INVALID_ARGUMENT; -- if (BN_num_bits(key->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) -+ if (RSA_bits(key->rsa) < SSH_RSA_MINIMUM_MODULUS_SIZE) - return SSH_ERR_KEY_LENGTH; - - if ((b = sshbuf_from(sig, siglen)) == NULL) -diff -aurp old/sshkey.c new/sshkey.c ---- old/sshkey.c 2018-08-22 22:41:42.000000000 -0700 -+++ new/sshkey.c 2018-08-23 21:31:53.334592801 -0700 -@@ -292,10 +292,18 @@ sshkey_size(const struct sshkey *k) - #ifdef WITH_OPENSSL - case KEY_RSA: - case KEY_RSA_CERT: -- return BN_num_bits(k->rsa->n); -+#if OPENSSL_VERSION_NUMBER >= 0x10100000UL -+ return RSA_bits(k->rsa); -+#else -+ return RSA_bits(key->rsa); -+#endif - case KEY_DSA: - case KEY_DSA_CERT: -+#if OPENSSL_VERSION_NUMBER >= 0x10100000UL -+ return DSA_bits(k->dsa); -+#else - return BN_num_bits(k->dsa->p); -+#endif - case KEY_ECDSA: - case KEY_ECDSA_CERT: - return sshkey_curve_nid_to_bits(k->ecdsa_nid); -@@ -500,26 +508,53 @@ sshkey_new(int type) - #ifdef WITH_OPENSSL - case KEY_RSA: - case KEY_RSA_CERT: -+ { -+ BIGNUM *n=NULL, *e=NULL; /* just allocate */ - if ((rsa = RSA_new()) == NULL || -- (rsa->n = BN_new()) == NULL || -- (rsa->e = BN_new()) == NULL) { -+ (n = BN_new()) == NULL || -+ (e = BN_new()) == NULL) { -+ BN_free(n); -+ BN_free(e); - RSA_free(rsa); - free(k); - return NULL; - } -+ BN_clear(n); BN_clear(e); -+ if (RSA_set0_key(rsa, n, e, NULL) == 0) -+ return NULL; -+ n = e = NULL; -+ } - k->rsa = rsa; - break; - case KEY_DSA: - case KEY_DSA_CERT: -+ { -+ BIGNUM *p=NULL, *q=NULL, *g=NULL, *pubkey=NULL; /* just allocate */ - if ((dsa = DSA_new()) == NULL || -- (dsa->p = BN_new()) == NULL || -- (dsa->q = BN_new()) == NULL || -- (dsa->g = BN_new()) == NULL || -- (dsa->pub_key = BN_new()) == NULL) { -+ (p = BN_new()) == NULL || -+ (q = BN_new()) == NULL || -+ (g = BN_new()) == NULL || -+ (pubkey = BN_new()) == NULL) { -+ BN_free(p); -+ BN_free(q); -+ BN_free(g); -+ BN_free(pubkey); - DSA_free(dsa); - free(k); - return NULL; - } -+ if (DSA_set0_pqg(dsa, p, q, g) == 0) { -+ BN_free(p); BN_free(q); BN_free(g); -+ BN_free(pubkey); -+ return NULL; -+ } -+ p = q = g = NULL; -+ if (DSA_set0_key(dsa, pubkey, NULL) == 0) { -+ BN_free(pubkey); -+ return NULL; -+ } -+ pubkey = NULL; -+ } - k->dsa = dsa; - break; - case KEY_ECDSA: -@@ -557,6 +592,51 @@ sshkey_add_private(struct sshkey *k) - #ifdef WITH_OPENSSL - case KEY_RSA: - case KEY_RSA_CERT: -+#if OPENSSL_VERSION_NUMBER >= 0x10100000UL -+ /* Allocate BIGNUM. This is a mess. -+ For OpenSSL 1.1.x API these shouldn't be mandatory, -+ but some regression tests for non-NULL pointer of -+ the data. */ -+#define new_or_dup(bn, nbn) \ -+ if (bn == NULL) { \ -+ if ((nbn = BN_new()) == NULL) \ -+ return SSH_ERR_ALLOC_FAIL; \ -+ } else { \ -+ /* otherwise use-after-free will occur */ \ -+ if ((nbn = BN_dup(bn)) == NULL) \ -+ return SSH_ERR_ALLOC_FAIL; \ -+ } -+ { -+ const BIGNUM *d, *iqmp, *q, *p, *dmq1, *dmp1; /* allocate if NULL */ -+ BIGNUM *nd, *niqmp, *nq, *np, *ndmq1, *ndmp1; -+ -+ RSA_get0_key(k->rsa, NULL, NULL, &d); -+ RSA_get0_factors(k->rsa, &p, &q); -+ RSA_get0_crt_params(k->rsa, &dmp1, &dmq1, &iqmp); -+ -+ new_or_dup(d, nd); -+ new_or_dup(iqmp, niqmp); -+ new_or_dup(q, nq); -+ new_or_dup(p, np); -+ new_or_dup(dmq1, ndmq1); -+ new_or_dup(dmp1, ndmp1); -+ -+ if (RSA_set0_key(k->rsa, NULL, NULL, nd) == 0) -+ goto error1; -+ nd = NULL; -+ if (RSA_set0_factors(k->rsa, np, nq) == 0) -+ goto error1; -+ np = nq = NULL; -+ if (RSA_set0_crt_params(k->rsa, ndmp1, ndmq1, niqmp) == 0) { -+error1: -+ BN_free(nd); -+ BN_free(np); BN_free(nq); -+ BN_free(ndmp1); BN_free(ndmq1); BN_free(niqmp); -+ return SSH_ERR_LIBCRYPTO_ERROR; -+ } -+ ndmp1 = ndmq1 = niqmp = NULL; -+ } -+#else - #define bn_maybe_alloc_failed(p) (p == NULL && (p = BN_new()) == NULL) - if (bn_maybe_alloc_failed(k->rsa->d) || - bn_maybe_alloc_failed(k->rsa->iqmp) || -@@ -565,13 +645,28 @@ sshkey_add_private(struct sshkey *k) - bn_maybe_alloc_failed(k->rsa->dmq1) || - bn_maybe_alloc_failed(k->rsa->dmp1)) - return SSH_ERR_ALLOC_FAIL; -+#endif - break; - case KEY_DSA: - case KEY_DSA_CERT: -+#if OPENSSL_VERSION_NUMBER >= 0x10100000UL -+ { -+ const BIGNUM *priv_key; -+ BIGNUM *npriv_key; -+ DSA_get0_key(k->dsa, NULL, &priv_key); -+ new_or_dup(priv_key, npriv_key); -+ if (DSA_set0_key(k->dsa, NULL, npriv_key) == 0) { -+ BN_free(npriv_key); -+ return SSH_ERR_LIBCRYPTO_ERROR; -+ } -+ } -+#else - if (bn_maybe_alloc_failed(k->dsa->priv_key)) - return SSH_ERR_ALLOC_FAIL; -+#endif - break; - #undef bn_maybe_alloc_failed -+#undef new_or_dup - case KEY_ECDSA: - case KEY_ECDSA_CERT: - /* Cannot do anything until we know the group */ -@@ -695,16 +790,34 @@ sshkey_equal_public(const struct sshkey - #ifdef WITH_OPENSSL - case KEY_RSA_CERT: - case KEY_RSA: -- return a->rsa != NULL && b->rsa != NULL && -- BN_cmp(a->rsa->e, b->rsa->e) == 0 && -- BN_cmp(a->rsa->n, b->rsa->n) == 0; -+ { -+ const BIGNUM *a_e, *b_e, *a_n, *b_n; -+ const BIGNUM *a_d, *b_d; -+ if (a->rsa == NULL) return 0; -+ if (b->rsa == NULL) return 0; -+ RSA_get0_key(a->rsa, &a_n, &a_e, &a_d); -+ RSA_get0_key(b->rsa, &b_n, &b_e, &b_d); -+ return -+ BN_cmp(a_e, b_e) == 0 && -+ BN_cmp(a_n, b_n) == 0; -+ } - case KEY_DSA_CERT: - case KEY_DSA: -- return a->dsa != NULL && b->dsa != NULL && -- BN_cmp(a->dsa->p, b->dsa->p) == 0 && -- BN_cmp(a->dsa->q, b->dsa->q) == 0 && -- BN_cmp(a->dsa->g, b->dsa->g) == 0 && -- BN_cmp(a->dsa->pub_key, b->dsa->pub_key) == 0; -+ { -+ const BIGNUM *a_p, *a_q, *a_g, *a_pub_key; -+ const BIGNUM *b_p, *b_q, *b_g, *b_pub_key; -+ if (a->dsa == NULL) return 0; -+ if (b->dsa == NULL) return 0; -+ DSA_get0_pqg(a->dsa, &a_p, &a_q, &a_g); -+ DSA_get0_pqg(b->dsa, &b_p, &b_q, &b_g); -+ DSA_get0_key(a->dsa, &a_pub_key, NULL); -+ DSA_get0_key(b->dsa, &b_pub_key, NULL); -+ return -+ BN_cmp(a_p, b_p) == 0 && -+ BN_cmp(a_q, b_q) == 0 && -+ BN_cmp(a_g, b_g) == 0 && -+ BN_cmp(a_pub_key, b_pub_key) == 0; -+ } - # ifdef OPENSSL_HAS_ECC - case KEY_ECDSA_CERT: - case KEY_ECDSA: -@@ -793,12 +906,17 @@ to_blob_buf(const struct sshkey *key, st - case KEY_DSA: - if (key->dsa == NULL) - return SSH_ERR_INVALID_ARGUMENT; -+ { -+ const BIGNUM *p, *q, *g, *pub_key; -+ DSA_get0_pqg(key->dsa, &p, &q, &g); -+ DSA_get0_key(key->dsa, &pub_key, NULL); - if ((ret = sshbuf_put_cstring(b, typename)) != 0 || -- (ret = sshbuf_put_bignum2(b, key->dsa->p)) != 0 || -- (ret = sshbuf_put_bignum2(b, key->dsa->q)) != 0 || -- (ret = sshbuf_put_bignum2(b, key->dsa->g)) != 0 || -- (ret = sshbuf_put_bignum2(b, key->dsa->pub_key)) != 0) -+ (ret = sshbuf_put_bignum2(b, p)) != 0 || -+ (ret = sshbuf_put_bignum2(b, q)) != 0 || -+ (ret = sshbuf_put_bignum2(b, g)) != 0 || -+ (ret = sshbuf_put_bignum2(b, pub_key)) != 0) - return ret; -+ } - break; - # ifdef OPENSSL_HAS_ECC - case KEY_ECDSA: -@@ -814,10 +932,14 @@ to_blob_buf(const struct sshkey *key, st - case KEY_RSA: - if (key->rsa == NULL) - return SSH_ERR_INVALID_ARGUMENT; -+ { -+ const BIGNUM *e, *n; -+ RSA_get0_key(key->rsa, &n, &e, NULL); - if ((ret = sshbuf_put_cstring(b, typename)) != 0 || -- (ret = sshbuf_put_bignum2(b, key->rsa->e)) != 0 || -- (ret = sshbuf_put_bignum2(b, key->rsa->n)) != 0) -+ (ret = sshbuf_put_bignum2(b, e)) != 0 || -+ (ret = sshbuf_put_bignum2(b, n)) != 0) - return ret; -+ } - break; - #endif /* WITH_OPENSSL */ - case KEY_ED25519: -@@ -1758,13 +1880,32 @@ sshkey_from_private(const struct sshkey - case KEY_DSA_CERT: - if ((n = sshkey_new(k->type)) == NULL) - return SSH_ERR_ALLOC_FAIL; -- if ((BN_copy(n->dsa->p, k->dsa->p) == NULL) || -- (BN_copy(n->dsa->q, k->dsa->q) == NULL) || -- (BN_copy(n->dsa->g, k->dsa->g) == NULL) || -- (BN_copy(n->dsa->pub_key, k->dsa->pub_key) == NULL)) { -+ { -+ const BIGNUM *p, *q, *g, *pub_key, *priv_key; -+ BIGNUM *cp=NULL, *cq=NULL, *cg=NULL, *cpub_key=NULL; -+ DSA_get0_pqg(k->dsa, &p, &q, &g); -+ DSA_get0_key(k->dsa, &pub_key, &priv_key); -+ if ((cp = BN_dup(p)) == NULL || -+ (cq = BN_dup(q)) == NULL || -+ (cg = BN_dup(g)) == NULL || -+ (cpub_key = BN_dup(pub_key)) == NULL) { -+ BN_free(cp); BN_free(cq); BN_free(cg); -+ BN_free(cpub_key); - sshkey_free(n); - return SSH_ERR_ALLOC_FAIL; - } -+ if (DSA_set0_pqg(n->dsa, cp, cq, cg) == 0) -+ goto error1; -+ cp = cq = cg = NULL; -+ if (DSA_set0_key(n->dsa, cpub_key, NULL) == 0) { -+error1: -+ BN_free(cp); BN_free(cq); BN_free(cg); -+ BN_free(cpub_key); -+ sshkey_free(n); -+ return SSH_ERR_LIBCRYPTO_ERROR; -+ } -+ cpub_key = NULL; -+ } - break; - # ifdef OPENSSL_HAS_ECC - case KEY_ECDSA: -@@ -1788,11 +1929,23 @@ sshkey_from_private(const struct sshkey - case KEY_RSA_CERT: - if ((n = sshkey_new(k->type)) == NULL) - return SSH_ERR_ALLOC_FAIL; -- if ((BN_copy(n->rsa->n, k->rsa->n) == NULL) || -- (BN_copy(n->rsa->e, k->rsa->e) == NULL)) { -+ { -+ const BIGNUM *nn, *e, *d; -+ BIGNUM *cn=NULL, *ce=NULL; -+ RSA_get0_key(k->rsa, &nn, &e, &d); -+ if ((cn = BN_dup(nn)) == NULL || -+ (ce = BN_dup(e)) == NULL ) { -+ BN_free(cn); BN_free(ce); - sshkey_free(n); - return SSH_ERR_ALLOC_FAIL; - } -+ if (RSA_set0_key(n->rsa, cn, ce, NULL) == 0) { -+ BN_free(cn); BN_free(ce); -+ sshkey_free(n); -+ return SSH_ERR_LIBCRYPTO_ERROR; -+ } -+ cn = ce = NULL; -+ } - break; - #endif /* WITH_OPENSSL */ - case KEY_ED25519: -@@ -2013,12 +2166,27 @@ sshkey_from_blob_internal(struct sshbuf - ret = SSH_ERR_ALLOC_FAIL; - goto out; - } -- if (sshbuf_get_bignum2(b, key->rsa->e) != 0 || -- sshbuf_get_bignum2(b, key->rsa->n) != 0) { -+ { -+ BIGNUM *e=NULL, *n=NULL; -+ if ((e = BN_new()) == NULL || -+ (n = BN_new()) == NULL ) { -+ ret = SSH_ERR_ALLOC_FAIL; -+ BN_free(e); BN_free(n); -+ goto out; -+ } -+ if (sshbuf_get_bignum2(b, e) != 0 || -+ sshbuf_get_bignum2(b, n) != 0) { - ret = SSH_ERR_INVALID_FORMAT; -+ BN_free(e); BN_free(n); - goto out; - } -- if (BN_num_bits(key->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) { -+ if (RSA_set0_key(key->rsa, n, e, NULL) == 0) { -+ BN_free(e); BN_free(n); -+ return SSH_ERR_LIBCRYPTO_ERROR; -+ } -+ n = e = NULL; -+ } -+ if (RSA_bits(key->rsa) < SSH_RSA_MINIMUM_MODULUS_SIZE) { - ret = SSH_ERR_KEY_LENGTH; - goto out; - } -@@ -2038,13 +2206,36 @@ sshkey_from_blob_internal(struct sshbuf - ret = SSH_ERR_ALLOC_FAIL; - goto out; - } -- if (sshbuf_get_bignum2(b, key->dsa->p) != 0 || -- sshbuf_get_bignum2(b, key->dsa->q) != 0 || -- sshbuf_get_bignum2(b, key->dsa->g) != 0 || -- sshbuf_get_bignum2(b, key->dsa->pub_key) != 0) { -+ { -+ BIGNUM *p=NULL, *q=NULL, *g=NULL, *pub_key=NULL; -+ if ((p = BN_new()) == NULL || -+ (q = BN_new()) == NULL || -+ (g = BN_new()) == NULL || -+ (pub_key = BN_new()) == NULL) { -+ ret = SSH_ERR_ALLOC_FAIL; -+ goto error1; -+ } -+ if (sshbuf_get_bignum2(b, p) != 0 || -+ sshbuf_get_bignum2(b, q) != 0 || -+ sshbuf_get_bignum2(b, g) != 0 || -+ sshbuf_get_bignum2(b, pub_key) != 0) { - ret = SSH_ERR_INVALID_FORMAT; -+ goto error1; -+ } -+ if (DSA_set0_pqg(key->dsa, p, q, g) == 0) { -+ ret = SSH_ERR_LIBCRYPTO_ERROR; -+ goto error1; -+ } -+ p = q = g = NULL; -+ if (DSA_set0_key(key->dsa, pub_key, NULL) == 0) { -+ ret = SSH_ERR_LIBCRYPTO_ERROR; -+error1: -+ BN_free(p); BN_free(q); BN_free(g); -+ BN_free(pub_key); - goto out; - } -+ pub_key = NULL; -+ } - #ifdef DEBUG_PK - DSA_print_fp(stderr, key->dsa, 8); - #endif -@@ -2389,26 +2580,63 @@ sshkey_demote(const struct sshkey *k, st - goto fail; - /* FALLTHROUGH */ - case KEY_RSA: -- if ((pk->rsa = RSA_new()) == NULL || -- (pk->rsa->e = BN_dup(k->rsa->e)) == NULL || -- (pk->rsa->n = BN_dup(k->rsa->n)) == NULL) { -+ if ((pk->rsa = RSA_new()) == NULL ){ - ret = SSH_ERR_ALLOC_FAIL; - goto fail; - } -+ { -+ const BIGNUM *ke, *kn; -+ BIGNUM *pke=NULL, *pkn=NULL; -+ RSA_get0_key(k->rsa, &kn, &ke, NULL); -+ if ((pke = BN_dup(ke)) == NULL || -+ (pkn = BN_dup(kn)) == NULL) { -+ ret = SSH_ERR_ALLOC_FAIL; -+ BN_free(pke); BN_free(pkn); -+ goto fail; -+ } -+ if (RSA_set0_key(pk->rsa, pkn, pke, NULL) == 0) { -+ ret = SSH_ERR_LIBCRYPTO_ERROR; -+ BN_free(pke); BN_free(pkn); -+ goto fail; -+ } -+ pkn = pke = NULL; -+ } - break; - case KEY_DSA_CERT: - if ((ret = sshkey_cert_copy(k, pk)) != 0) - goto fail; - /* FALLTHROUGH */ - case KEY_DSA: -- if ((pk->dsa = DSA_new()) == NULL || -- (pk->dsa->p = BN_dup(k->dsa->p)) == NULL || -- (pk->dsa->q = BN_dup(k->dsa->q)) == NULL || -- (pk->dsa->g = BN_dup(k->dsa->g)) == NULL || -- (pk->dsa->pub_key = BN_dup(k->dsa->pub_key)) == NULL) { -+ if ((pk->dsa = DSA_new()) == NULL ) { - ret = SSH_ERR_ALLOC_FAIL; - goto fail; - } -+ { -+ const BIGNUM *kp, *kq, *kg, *kpub_key; -+ BIGNUM *pkp=NULL, *pkq=NULL, *pkg=NULL, *pkpub_key=NULL; -+ DSA_get0_pqg(k->dsa, &kp, &kq, &kg); -+ DSA_get0_key(k->dsa, &kpub_key, NULL); -+ if ((pkp = BN_dup(kp)) == NULL || -+ (pkq = BN_dup(kq)) == NULL || -+ (pkg = BN_dup(kg)) == NULL || -+ (pkpub_key = BN_dup(kpub_key)) == NULL) { -+ ret = SSH_ERR_ALLOC_FAIL; -+ goto error1; -+ } -+ if (DSA_set0_pqg(pk->dsa, pkp, pkq, pkg) == 0) { -+ ret = SSH_ERR_LIBCRYPTO_ERROR; -+ goto error1; -+ } -+ pkp = pkq = pkg = NULL; -+ if (DSA_set0_key(pk->dsa, pkpub_key, NULL) == 0) { -+ ret = SSH_ERR_LIBCRYPTO_ERROR; -+error1: -+ BN_free(pkp); BN_free(pkq); BN_free(pkg); -+ BN_free(pkpub_key); -+ goto fail; -+ } -+ pkpub_key = NULL; -+ } - break; - case KEY_ECDSA_CERT: - if ((ret = sshkey_cert_copy(k, pk)) != 0) -@@ -2558,11 +2786,17 @@ sshkey_certify_custom(struct sshkey *k, - switch (k->type) { - #ifdef WITH_OPENSSL - case KEY_DSA_CERT: -- if ((ret = sshbuf_put_bignum2(cert, k->dsa->p)) != 0 || -- (ret = sshbuf_put_bignum2(cert, k->dsa->q)) != 0 || -- (ret = sshbuf_put_bignum2(cert, k->dsa->g)) != 0 || -- (ret = sshbuf_put_bignum2(cert, k->dsa->pub_key)) != 0) -+ { -+ const BIGNUM *p, *q, *g, *pub_key; -+ DSA_get0_pqg(k->dsa, &p, &q, &g); -+ DSA_get0_key(k->dsa, &pub_key, NULL); -+ if ((ret = sshbuf_put_bignum2(cert, p)) != 0 || -+ (ret = sshbuf_put_bignum2(cert, q)) != 0 || -+ (ret = sshbuf_put_bignum2(cert, g)) != 0 || -+ (ret = sshbuf_put_bignum2(cert, pub_key)) != 0) { - goto out; -+ } -+ } - break; - # ifdef OPENSSL_HAS_ECC - case KEY_ECDSA_CERT: -@@ -2575,9 +2809,15 @@ sshkey_certify_custom(struct sshkey *k, - break; - # endif /* OPENSSL_HAS_ECC */ - case KEY_RSA_CERT: -- if ((ret = sshbuf_put_bignum2(cert, k->rsa->e)) != 0 || -- (ret = sshbuf_put_bignum2(cert, k->rsa->n)) != 0) -+ { -+ const BIGNUM *e, *n; -+ RSA_get0_key(k->rsa, &n, &e, NULL); -+ if (n == NULL || e == NULL || -+ (ret = sshbuf_put_bignum2(cert, e)) != 0 || -+ (ret = sshbuf_put_bignum2(cert, n)) != 0) { - goto out; -+ } -+ } - break; - #endif /* WITH_OPENSSL */ - case KEY_ED25519_CERT: -@@ -2764,42 +3004,67 @@ sshkey_private_serialize_opt(const struc - switch (key->type) { - #ifdef WITH_OPENSSL - case KEY_RSA: -- if ((r = sshbuf_put_bignum2(b, key->rsa->n)) != 0 || -- (r = sshbuf_put_bignum2(b, key->rsa->e)) != 0 || -- (r = sshbuf_put_bignum2(b, key->rsa->d)) != 0 || -- (r = sshbuf_put_bignum2(b, key->rsa->iqmp)) != 0 || -- (r = sshbuf_put_bignum2(b, key->rsa->p)) != 0 || -- (r = sshbuf_put_bignum2(b, key->rsa->q)) != 0) -+ { -+ const BIGNUM *n, *e, *d, *iqmp, *p, *q; -+ RSA_get0_key(key->rsa, &n, &e, &d); -+ RSA_get0_crt_params(key->rsa, NULL, NULL, &iqmp); -+ RSA_get0_factors(key->rsa, &p, &q); -+ if ((r = sshbuf_put_bignum2(b, n)) != 0 || -+ (r = sshbuf_put_bignum2(b, e)) != 0 || -+ (r = sshbuf_put_bignum2(b, d)) != 0 || -+ (r = sshbuf_put_bignum2(b, iqmp)) != 0 || -+ (r = sshbuf_put_bignum2(b, p)) != 0 || -+ (r = sshbuf_put_bignum2(b, q)) != 0) { - goto out; -+ } -+ } - break; - case KEY_RSA_CERT: - if (key->cert == NULL || sshbuf_len(key->cert->certblob) == 0) { - r = SSH_ERR_INVALID_ARGUMENT; - goto out; - } -+ { -+ const BIGNUM *d, *iqmp, *p, *q; -+ RSA_get0_key(key->rsa, NULL, NULL, &d); -+ RSA_get0_crt_params(key->rsa, NULL, NULL, &iqmp); -+ RSA_get0_factors(key->rsa, &p, &q); - if ((r = sshbuf_put_stringb(b, key->cert->certblob)) != 0 || -- (r = sshbuf_put_bignum2(b, key->rsa->d)) != 0 || -- (r = sshbuf_put_bignum2(b, key->rsa->iqmp)) != 0 || -- (r = sshbuf_put_bignum2(b, key->rsa->p)) != 0 || -- (r = sshbuf_put_bignum2(b, key->rsa->q)) != 0) -+ (r = sshbuf_put_bignum2(b, d)) != 0 || -+ (r = sshbuf_put_bignum2(b, iqmp)) != 0 || -+ (r = sshbuf_put_bignum2(b, p)) != 0 || -+ (r = sshbuf_put_bignum2(b, q)) != 0) { - goto out; -+ } -+ } - break; - case KEY_DSA: -- if ((r = sshbuf_put_bignum2(b, key->dsa->p)) != 0 || -- (r = sshbuf_put_bignum2(b, key->dsa->q)) != 0 || -- (r = sshbuf_put_bignum2(b, key->dsa->g)) != 0 || -- (r = sshbuf_put_bignum2(b, key->dsa->pub_key)) != 0 || -- (r = sshbuf_put_bignum2(b, key->dsa->priv_key)) != 0) -+ { -+ const BIGNUM *p, *q, *g, *pub_key, *priv_key; -+ DSA_get0_pqg(key->dsa, &p, &q, &g); -+ DSA_get0_key(key->dsa, &pub_key, &priv_key); -+ if ((r = sshbuf_put_bignum2(b, p)) != 0 || -+ (r = sshbuf_put_bignum2(b, q)) != 0 || -+ (r = sshbuf_put_bignum2(b, g)) != 0 || -+ (r = sshbuf_put_bignum2(b, pub_key)) != 0 || -+ (r = sshbuf_put_bignum2(b, priv_key)) != 0) { - goto out; -+ } -+ } - break; - case KEY_DSA_CERT: - if (key->cert == NULL || sshbuf_len(key->cert->certblob) == 0) { - r = SSH_ERR_INVALID_ARGUMENT; - goto out; - } -+ { -+ const BIGNUM *priv_key; -+ DSA_get0_key(key->dsa, NULL, &priv_key); - if ((r = sshbuf_put_stringb(b, key->cert->certblob)) != 0 || -- (r = sshbuf_put_bignum2(b, key->dsa->priv_key)) != 0) -+ (r = sshbuf_put_bignum2(b, priv_key)) != 0) { - goto out; -+ } -+ } - break; - # ifdef OPENSSL_HAS_ECC - case KEY_ECDSA: -@@ -2913,18 +3178,61 @@ sshkey_private_deserialize(struct sshbuf - r = SSH_ERR_ALLOC_FAIL; - goto out; - } -- if ((r = sshbuf_get_bignum2(buf, k->dsa->p)) != 0 || -- (r = sshbuf_get_bignum2(buf, k->dsa->q)) != 0 || -- (r = sshbuf_get_bignum2(buf, k->dsa->g)) != 0 || -- (r = sshbuf_get_bignum2(buf, k->dsa->pub_key)) != 0 || -- (r = sshbuf_get_bignum2(buf, k->dsa->priv_key)) != 0) -+ { -+ BIGNUM *p=NULL, *q=NULL, *g=NULL, *pub_key=NULL, *priv_key=NULL; -+ if ((p = BN_new()) == NULL || -+ (q = BN_new()) == NULL || -+ (g = BN_new()) == NULL || -+ (pub_key = BN_new()) == NULL || -+ (priv_key = BN_new()) == NULL) { -+ r = SSH_ERR_ALLOC_FAIL; -+ goto error1; -+ } -+ if (p == NULL || q == NULL || g == NULL || -+ pub_key == NULL || priv_key == NULL || -+ (r = sshbuf_get_bignum2(buf, p)) != 0 || -+ (r = sshbuf_get_bignum2(buf, q)) != 0 || -+ (r = sshbuf_get_bignum2(buf, g)) != 0 || -+ (r = sshbuf_get_bignum2(buf, pub_key)) != 0 || -+ (r = sshbuf_get_bignum2(buf, priv_key)) != 0) { -+ goto error1; -+ } -+ if (DSA_set0_pqg(k->dsa, p, q, g) == 0) { -+ r = SSH_ERR_LIBCRYPTO_ERROR; -+ goto error1; -+ } -+ p = q = g = NULL; -+ if (DSA_set0_key(k->dsa, pub_key, priv_key) == 0) { -+ r = SSH_ERR_LIBCRYPTO_ERROR; -+error1: -+ BN_free(p); BN_free(q); BN_free(g); -+ BN_free(pub_key); BN_free(priv_key); - goto out; -+ } -+ pub_key = priv_key = NULL; -+ } - break; - case KEY_DSA_CERT: -- if ((r = sshkey_froms(buf, &k)) != 0 || -+ { -+ BIGNUM *priv_key=NULL; -+ if ((priv_key = BN_new()) == NULL) { -+ r = SSH_ERR_ALLOC_FAIL; -+ goto out; -+ } -+ if (priv_key == NULL || -+ (r = sshkey_froms(buf, &k)) != 0 || - (r = sshkey_add_private(k)) != 0 || -- (r = sshbuf_get_bignum2(buf, k->dsa->priv_key)) != 0) -+ (r = sshbuf_get_bignum2(buf, priv_key)) != 0) { -+ BN_free(priv_key); -+ goto out; -+ } -+ if (DSA_set0_key(k->dsa, NULL, priv_key) == 0) { -+ r = SSH_ERR_LIBCRYPTO_ERROR; -+ BN_free(priv_key); - goto out; -+ } -+ priv_key = NULL; -+ } - break; - # ifdef OPENSSL_HAS_ECC - case KEY_ECDSA: -@@ -2983,29 +3291,104 @@ sshkey_private_deserialize(struct sshbuf - r = SSH_ERR_ALLOC_FAIL; - goto out; - } -- if ((r = sshbuf_get_bignum2(buf, k->rsa->n)) != 0 || -- (r = sshbuf_get_bignum2(buf, k->rsa->e)) != 0 || -- (r = sshbuf_get_bignum2(buf, k->rsa->d)) != 0 || -- (r = sshbuf_get_bignum2(buf, k->rsa->iqmp)) != 0 || -- (r = sshbuf_get_bignum2(buf, k->rsa->p)) != 0 || -- (r = sshbuf_get_bignum2(buf, k->rsa->q)) != 0 || -- (r = ssh_rsa_generate_additional_parameters(k)) != 0) -+ { -+ BIGNUM *n=NULL, *e=NULL, *d=NULL, *iqmp=NULL, *p=NULL, *q=NULL; -+ BIGNUM *dmp1=NULL, *dmq1=NULL; /* dummy for RSA_set0_crt_params */ -+ if ((n = BN_new()) == NULL || -+ (e = BN_new()) == NULL || -+ (d = BN_new()) == NULL || -+ (iqmp = BN_new()) == NULL || -+ (p = BN_new()) == NULL || -+ (q = BN_new()) == NULL || -+ (dmp1 = BN_new()) == NULL || -+ (dmq1 = BN_new()) == NULL) { -+ r = SSH_ERR_ALLOC_FAIL; -+ goto error2; -+ } -+ BN_clear(dmp1); BN_clear(dmq1); -+ if ((r = sshbuf_get_bignum2(buf, n)) != 0 || -+ (r = sshbuf_get_bignum2(buf, e)) != 0 || -+ (r = sshbuf_get_bignum2(buf, d)) != 0 || -+ (r = sshbuf_get_bignum2(buf, iqmp)) != 0 || -+ (r = sshbuf_get_bignum2(buf, p)) != 0 || -+ (r = sshbuf_get_bignum2(buf, q)) != 0) { -+ goto error2; -+ } -+ if (RSA_set0_key(k->rsa, n, e, d) == 0) { -+ r = SSH_ERR_LIBCRYPTO_ERROR; -+ goto error2; -+ } -+ n = e = d = NULL; -+ /* dmp1,dmpq1 should be non NULL to set iqmp value */ -+ if (RSA_set0_crt_params(k->rsa, dmp1, dmq1, iqmp) == 0) { -+ r = SSH_ERR_LIBCRYPTO_ERROR; -+ goto error2; -+ } -+ dmp1 = dmq1 = iqmp = NULL; -+ if (RSA_set0_factors(k->rsa, p, q) == 0) { -+ r = SSH_ERR_LIBCRYPTO_ERROR; -+ error2: -+ BN_free(n); BN_free(e); BN_free(d); -+ BN_free(iqmp); -+ BN_free(p); BN_free(q); -+ BN_free(dmp1); BN_free(dmq1); -+ goto out; -+ } -+ p = q = NULL; -+ if ((r = ssh_rsa_generate_additional_parameters(k)) != 0) { - goto out; -- if (BN_num_bits(k->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) { -+ } -+ } -+ if (RSA_bits(k->rsa) < SSH_RSA_MINIMUM_MODULUS_SIZE) { - r = SSH_ERR_KEY_LENGTH; - goto out; - } - break; - case KEY_RSA_CERT: -+ { -+ BIGNUM *d=NULL, *iqmp=NULL, *p=NULL, *q=NULL; -+ BIGNUM *dmp1=NULL, *dmq1=NULL; /* dummy for RSA_set0_crt_params */ -+ if ((d = BN_new()) == NULL || -+ (iqmp = BN_new()) == NULL || -+ (p = BN_new()) == NULL || -+ (q = BN_new()) == NULL || -+ (dmp1 = BN_new()) == NULL || -+ (dmq1 = BN_new()) == NULL) { -+ r = SSH_ERR_ALLOC_FAIL; -+ goto error3; -+ } -+ BN_clear(dmp1); BN_clear(dmq1); - if ((r = sshkey_froms(buf, &k)) != 0 || - (r = sshkey_add_private(k)) != 0 || -- (r = sshbuf_get_bignum2(buf, k->rsa->d)) != 0 || -- (r = sshbuf_get_bignum2(buf, k->rsa->iqmp)) != 0 || -- (r = sshbuf_get_bignum2(buf, k->rsa->p)) != 0 || -- (r = sshbuf_get_bignum2(buf, k->rsa->q)) != 0 || -- (r = ssh_rsa_generate_additional_parameters(k)) != 0) -+ (r = sshbuf_get_bignum2(buf, d)) != 0 || -+ (r = sshbuf_get_bignum2(buf, iqmp)) != 0 || -+ (r = sshbuf_get_bignum2(buf, p)) != 0 || -+ (r = sshbuf_get_bignum2(buf, q)) != 0) { -+ goto error3; -+ } -+ if (RSA_set0_key(k->rsa, NULL, NULL, d) == 0) { -+ r = SSH_ERR_LIBCRYPTO_ERROR; -+ goto error3; -+ } -+ /* dmp1,dmpq1 should be non NULL to set value */ -+ if (RSA_set0_crt_params(k->rsa, dmp1, dmq1, iqmp) == 0) { -+ r = SSH_ERR_LIBCRYPTO_ERROR; -+ goto error3; -+ } -+ dmp1 = dmq1 = iqmp = NULL; -+ if (RSA_set0_factors(k->rsa, p, q) == 0) { -+ r = SSH_ERR_LIBCRYPTO_ERROR; -+ error3: -+ BN_free(d); BN_free(iqmp); -+ BN_free(p); BN_free(q); -+ BN_free(dmp1); BN_free(dmq1); - goto out; -- if (BN_num_bits(k->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) { -+ } -+ p = q = NULL; -+ if ((r = ssh_rsa_generate_additional_parameters(k)) != 0) -+ goto out; -+ } -+ if (RSA_bits(k->rsa) < SSH_RSA_MINIMUM_MODULUS_SIZE) { - r = SSH_ERR_KEY_LENGTH; - goto out; - } -@@ -3769,7 +4152,6 @@ translate_libcrypto_error(unsigned long - switch (pem_reason) { - case EVP_R_BAD_DECRYPT: - return SSH_ERR_KEY_WRONG_PASSPHRASE; -- case EVP_R_BN_DECODE_ERROR: - case EVP_R_DECODE_ERROR: - #ifdef EVP_R_PRIVATE_KEY_DECODE_ERROR - case EVP_R_PRIVATE_KEY_DECODE_ERROR: -@@ -3834,7 +4216,7 @@ sshkey_parse_private_pem_fileblob(struct - r = convert_libcrypto_error(); - goto out; - } -- if (pk->type == EVP_PKEY_RSA && -+ if (EVP_PKEY_id(pk) == EVP_PKEY_RSA && - (type == KEY_UNSPEC || type == KEY_RSA)) { - if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) { - r = SSH_ERR_ALLOC_FAIL; -@@ -3849,11 +4231,11 @@ sshkey_parse_private_pem_fileblob(struct - r = SSH_ERR_LIBCRYPTO_ERROR; - goto out; - } -- if (BN_num_bits(prv->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) { -+ if (RSA_bits(prv->rsa) < SSH_RSA_MINIMUM_MODULUS_SIZE) { - r = SSH_ERR_KEY_LENGTH; - goto out; - } -- } else if (pk->type == EVP_PKEY_DSA && -+ } else if (EVP_PKEY_id(pk) == EVP_PKEY_DSA && - (type == KEY_UNSPEC || type == KEY_DSA)) { - if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) { - r = SSH_ERR_ALLOC_FAIL; -@@ -3865,7 +4247,7 @@ sshkey_parse_private_pem_fileblob(struct - DSA_print_fp(stderr, prv->dsa, 8); - #endif - #ifdef OPENSSL_HAS_ECC -- } else if (pk->type == EVP_PKEY_EC && -+ } else if (EVP_PKEY_id(pk) == EVP_PKEY_EC && - (type == KEY_UNSPEC || type == KEY_ECDSA)) { - if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) { - r = SSH_ERR_ALLOC_FAIL;