Magellan Linux

Annotation of /trunk/openssh/patches/openssh-7.7p1-openssl-1.1.0.patch

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3139 - (hide annotations) (download)
Tue Jun 19 12:24:11 2018 UTC (5 years, 10 months ago) by niro
File size: 60970 byte(s)
-re-diffed for openssh-7.7p1
1 niro 3139 diff -aurp old/auth-pam.c new/auth-pam.c
2     --- old/auth-pam.c 2018-03-22 16:21:14.000000000 -1000
3     +++ new/auth-pam.c 2018-03-23 10:05:03.886621278 -1000
4     @@ -128,6 +128,10 @@ extern u_int utmp_len;
5     typedef pthread_t sp_pthread_t;
6     #else
7     typedef pid_t sp_pthread_t;
8     +# define pthread_create(a, b, c, d) _ssh_compat_pthread_create(a, b, c, d)
9     +# define pthread_exit(a) _ssh_compat_pthread_exit(a)
10     +# define pthread_cancel(a) _ssh_compat_pthread_cancel(a)
11     +# define pthread_join(a, b) _ssh_compat_pthread_join(a, b)
12     #endif
13    
14     struct pam_ctxt {
15     diff -aurp old/cipher.c new/cipher.c
16     --- old/cipher.c 2018-03-22 16:21:14.000000000 -1000
17     +++ new/cipher.c 2018-03-23 10:05:03.886621278 -1000
18     @@ -297,7 +297,10 @@ cipher_init(struct sshcipher_ctx **ccp,
19     goto out;
20     }
21     }
22     - if (EVP_CipherInit(cc->evp, NULL, (u_char *)key, NULL, -1) == 0) {
23     + /* in OpenSSL 1.1.0, EVP_CipherInit clears all previous setups;
24     + use EVP_CipherInit_ex for augmenting */
25     + if (EVP_CipherInit_ex(cc->evp, NULL, NULL, (u_char *)key, NULL, -1) == 0)
26     + {
27     ret = SSH_ERR_LIBCRYPTO_ERROR;
28     goto out;
29     }
30     @@ -483,7 +486,7 @@ cipher_get_keyiv(struct sshcipher_ctx *c
31     len, iv))
32     return SSH_ERR_LIBCRYPTO_ERROR;
33     } else
34     - memcpy(iv, cc->evp->iv, len);
35     + memcpy(iv, EVP_CIPHER_CTX_iv(cc->evp), len);
36     #endif
37     return 0;
38     }
39     @@ -517,14 +520,19 @@ cipher_set_keyiv(struct sshcipher_ctx *c
40     EVP_CTRL_GCM_SET_IV_FIXED, -1, (void *)iv))
41     return SSH_ERR_LIBCRYPTO_ERROR;
42     } else
43     - memcpy(cc->evp->iv, iv, evplen);
44     + memcpy(EVP_CIPHER_CTX_iv(cc->evp), iv, evplen);
45     #endif
46     return 0;
47     }
48    
49     #ifdef WITH_OPENSSL
50     -#define EVP_X_STATE(evp) (evp)->cipher_data
51     -#define EVP_X_STATE_LEN(evp) (evp)->cipher->ctx_size
52     +# if OPENSSL_VERSION_NUMBER >= 0x10100000UL
53     +#define EVP_X_STATE(evp) EVP_CIPHER_CTX_get_cipher_data(evp)
54     +#define EVP_X_STATE_LEN(evp) EVP_CIPHER_impl_ctx_size(EVP_CIPHER_CTX_cipher(evp))
55     +# else
56     +#define EVP_X_STATE(evp) (evp).cipher_data
57     +#define EVP_X_STATE_LEN(evp) (evp).cipher->ctx_size
58     +# endif
59     #endif
60    
61     int
62     diff -aurp old/cipher.h new/cipher.h
63     --- old/cipher.h 2018-03-22 16:21:14.000000000 -1000
64     +++ new/cipher.h 2018-03-23 10:05:03.886621278 -1000
65     @@ -46,7 +46,18 @@
66     #define CIPHER_DECRYPT 0
67    
68     struct sshcipher;
69     +#if 0
70     +struct sshcipher_ctx {
71     + int plaintext;
72     + int encrypt;
73     + EVP_CIPHER_CTX *evp;
74     + struct chachapoly_ctx cp_ctx; /* XXX union with evp? */
75     + struct aesctr_ctx ac_ctx; /* XXX union with evp? */
76     + const struct sshcipher *cipher;
77     +};
78     +#else
79     struct sshcipher_ctx;
80     +#endif
81    
82     const struct sshcipher *cipher_by_name(const char *);
83     const char *cipher_warning_message(const struct sshcipher_ctx *);
84     diff -aurp old/configure new/configure
85     --- old/configure 2018-03-23 03:30:17.000000000 -1000
86     +++ new/configure 2018-03-23 10:05:03.888621444 -1000
87     @@ -13076,7 +13076,6 @@ if ac_fn_c_try_run "$LINENO"; then :
88     100*) ;; # 1.0.x
89     200*) ;; # LibreSSL
90     *)
91     - as_fn_error $? "OpenSSL >= 1.1.0 is not yet supported (have \"$ssl_library_ver\")" "$LINENO" 5
92     ;;
93     esac
94     { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ssl_library_ver" >&5
95     diff -aurp old/dh.c new/dh.c
96     --- old/dh.c 2018-03-22 16:21:14.000000000 -1000
97     +++ new/dh.c 2018-03-23 10:05:03.888621444 -1000
98     @@ -211,14 +211,15 @@ choose_dh(int min, int wantbits, int max
99     /* diffie-hellman-groupN-sha1 */
100    
101     int
102     -dh_pub_is_valid(DH *dh, BIGNUM *dh_pub)
103     +dh_pub_is_valid(const DH *dh, const BIGNUM *dh_pub)
104     {
105     int i;
106     int n = BN_num_bits(dh_pub);
107     int bits_set = 0;
108     BIGNUM *tmp;
109     + const BIGNUM *p;
110    
111     - if (dh_pub->neg) {
112     + if (BN_is_negative(dh_pub)) {
113     logit("invalid public DH value: negative");
114     return 0;
115     }
116     @@ -231,7 +232,8 @@ dh_pub_is_valid(DH *dh, BIGNUM *dh_pub)
117     error("%s: BN_new failed", __func__);
118     return 0;
119     }
120     - if (!BN_sub(tmp, dh->p, BN_value_one()) ||
121     + DH_get0_pqg(dh, &p, NULL, NULL);
122     + if (!BN_sub(tmp, p, BN_value_one()) ||
123     BN_cmp(dh_pub, tmp) != -1) { /* pub_exp > p-2 */
124     BN_clear_free(tmp);
125     logit("invalid public DH value: >= p-1");
126     @@ -242,14 +244,14 @@ dh_pub_is_valid(DH *dh, BIGNUM *dh_pub)
127     for (i = 0; i <= n; i++)
128     if (BN_is_bit_set(dh_pub, i))
129     bits_set++;
130     - debug2("bits set: %d/%d", bits_set, BN_num_bits(dh->p));
131     + debug2("bits set: %d/%d", bits_set, BN_num_bits(p));
132    
133     /*
134     * if g==2 and bits_set==1 then computing log_g(dh_pub) is trivial
135     */
136     if (bits_set < 4) {
137     logit("invalid public DH value (%d/%d)",
138     - bits_set, BN_num_bits(dh->p));
139     + bits_set, BN_num_bits(p));
140     return 0;
141     }
142     return 1;
143     @@ -259,9 +261,13 @@ int
144     dh_gen_key(DH *dh, int need)
145     {
146     int pbits;
147     + const BIGNUM *p, *pub_key;
148     + BIGNUM *priv_key;
149    
150     - if (need < 0 || dh->p == NULL ||
151     - (pbits = BN_num_bits(dh->p)) <= 0 ||
152     + DH_get0_pqg(dh, &p, NULL, NULL);
153     +
154     + if (need < 0 || p == NULL ||
155     + (pbits = BN_num_bits(p)) <= 0 ||
156     need > INT_MAX / 2 || 2 * need > pbits)
157     return SSH_ERR_INVALID_ARGUMENT;
158     if (need < 256)
159     @@ -270,10 +276,13 @@ dh_gen_key(DH *dh, int need)
160     * Pollard Rho, Big step/Little Step attacks are O(sqrt(n)),
161     * so double requested need here.
162     */
163     - dh->length = MINIMUM(need * 2, pbits - 1);
164     - if (DH_generate_key(dh) == 0 ||
165     - !dh_pub_is_valid(dh, dh->pub_key)) {
166     - BN_clear_free(dh->priv_key);
167     + DH_set_length(dh, MIN(need * 2, pbits - 1));
168     + if (DH_generate_key(dh) == 0) {
169     + return SSH_ERR_LIBCRYPTO_ERROR;
170     + }
171     + DH_get0_key(dh, &pub_key, &priv_key);
172     + if (!dh_pub_is_valid(dh, pub_key)) {
173     + BN_clear(priv_key);
174     return SSH_ERR_LIBCRYPTO_ERROR;
175     }
176     return 0;
177     @@ -282,16 +291,27 @@ dh_gen_key(DH *dh, int need)
178     DH *
179     dh_new_group_asc(const char *gen, const char *modulus)
180     {
181     - DH *dh;
182     + DH *dh = NULL;
183     + BIGNUM *p=NULL, *g=NULL;
184    
185     - if ((dh = DH_new()) == NULL)
186     - return NULL;
187     - if (BN_hex2bn(&dh->p, modulus) == 0 ||
188     - BN_hex2bn(&dh->g, gen) == 0) {
189     - DH_free(dh);
190     - return NULL;
191     + if ((dh = DH_new()) == NULL ||
192     + (p = BN_new()) == NULL ||
193     + (g = BN_new()) == NULL)
194     + goto null;
195     + if (BN_hex2bn(&p, modulus) == 0 ||
196     + BN_hex2bn(&g, gen) == 0) {
197     + goto null;
198     }
199     + if (DH_set0_pqg(dh, p, NULL, g) == 0) {
200     + goto null;
201     + }
202     + p = g = NULL;
203     return (dh);
204     +null:
205     + BN_free(p);
206     + BN_free(g);
207     + DH_free(dh);
208     + return NULL;
209     }
210    
211     /*
212     @@ -306,8 +326,8 @@ dh_new_group(BIGNUM *gen, BIGNUM *modulu
213    
214     if ((dh = DH_new()) == NULL)
215     return NULL;
216     - dh->p = modulus;
217     - dh->g = gen;
218     + if (DH_set0_pqg(dh, modulus, NULL, gen) == 0)
219     + return NULL;
220    
221     return (dh);
222     }
223     diff -aurp old/dh.h new/dh.h
224     --- old/dh.h 2018-03-22 16:21:14.000000000 -1000
225     +++ new/dh.h 2018-03-23 10:05:03.889621527 -1000
226     @@ -42,7 +42,7 @@ DH *dh_new_group18(void);
227     DH *dh_new_group_fallback(int);
228    
229     int dh_gen_key(DH *, int);
230     -int dh_pub_is_valid(DH *, BIGNUM *);
231     +int dh_pub_is_valid(const DH *, const BIGNUM *);
232    
233     u_int dh_estimate(int);
234    
235     diff -aurp old/digest-openssl.c new/digest-openssl.c
236     --- old/digest-openssl.c 2018-03-22 16:21:14.000000000 -1000
237     +++ new/digest-openssl.c 2018-03-23 10:05:03.889621527 -1000
238     @@ -43,7 +43,7 @@
239    
240     struct ssh_digest_ctx {
241     int alg;
242     - EVP_MD_CTX mdctx;
243     + EVP_MD_CTX *mdctx;
244     };
245    
246     struct ssh_digest {
247     @@ -106,20 +106,21 @@ ssh_digest_bytes(int alg)
248     size_t
249     ssh_digest_blocksize(struct ssh_digest_ctx *ctx)
250     {
251     - return EVP_MD_CTX_block_size(&ctx->mdctx);
252     + return EVP_MD_CTX_block_size(ctx->mdctx);
253     }
254    
255     struct ssh_digest_ctx *
256     ssh_digest_start(int alg)
257     {
258     const struct ssh_digest *digest = ssh_digest_by_alg(alg);
259     - struct ssh_digest_ctx *ret;
260     + struct ssh_digest_ctx *ret = NULL;
261    
262     if (digest == NULL || ((ret = calloc(1, sizeof(*ret))) == NULL))
263     return NULL;
264     ret->alg = alg;
265     - EVP_MD_CTX_init(&ret->mdctx);
266     - if (EVP_DigestInit_ex(&ret->mdctx, digest->mdfunc(), NULL) != 1) {
267     + if ((ret->mdctx = EVP_MD_CTX_new()) == NULL ||
268     + EVP_DigestInit_ex(ret->mdctx, digest->mdfunc(), NULL) != 1) {
269     + EVP_MD_CTX_free(ret->mdctx);
270     free(ret);
271     return NULL;
272     }
273     @@ -132,7 +133,7 @@ ssh_digest_copy_state(struct ssh_digest_
274     if (from->alg != to->alg)
275     return SSH_ERR_INVALID_ARGUMENT;
276     /* we have bcopy-style order while openssl has memcpy-style */
277     - if (!EVP_MD_CTX_copy_ex(&to->mdctx, &from->mdctx))
278     + if (!EVP_MD_CTX_copy_ex(to->mdctx, from->mdctx))
279     return SSH_ERR_LIBCRYPTO_ERROR;
280     return 0;
281     }
282     @@ -140,7 +141,7 @@ ssh_digest_copy_state(struct ssh_digest_
283     int
284     ssh_digest_update(struct ssh_digest_ctx *ctx, const void *m, size_t mlen)
285     {
286     - if (EVP_DigestUpdate(&ctx->mdctx, m, mlen) != 1)
287     + if (EVP_DigestUpdate(ctx->mdctx, m, mlen) != 1)
288     return SSH_ERR_LIBCRYPTO_ERROR;
289     return 0;
290     }
291     @@ -161,7 +162,7 @@ ssh_digest_final(struct ssh_digest_ctx *
292     return SSH_ERR_INVALID_ARGUMENT;
293     if (dlen < digest->digest_len) /* No truncation allowed */
294     return SSH_ERR_INVALID_ARGUMENT;
295     - if (EVP_DigestFinal_ex(&ctx->mdctx, d, &l) != 1)
296     + if (EVP_DigestFinal_ex(ctx->mdctx, d, &l) != 1)
297     return SSH_ERR_LIBCRYPTO_ERROR;
298     if (l != digest->digest_len) /* sanity */
299     return SSH_ERR_INTERNAL_ERROR;
300     @@ -172,7 +173,7 @@ void
301     ssh_digest_free(struct ssh_digest_ctx *ctx)
302     {
303     if (ctx != NULL) {
304     - EVP_MD_CTX_cleanup(&ctx->mdctx);
305     + EVP_MD_CTX_free(ctx->mdctx);
306     explicit_bzero(ctx, sizeof(*ctx));
307     free(ctx);
308     }
309     diff -aurp old/kexdhc.c new/kexdhc.c
310     --- old/kexdhc.c 2018-03-22 16:21:14.000000000 -1000
311     +++ new/kexdhc.c 2018-03-23 10:05:03.889621527 -1000
312     @@ -81,11 +81,16 @@ kexdh_client(struct ssh *ssh)
313     goto out;
314     }
315     debug("sending SSH2_MSG_KEXDH_INIT");
316     - if ((r = dh_gen_key(kex->dh, kex->we_need * 8)) != 0 ||
317     - (r = sshpkt_start(ssh, SSH2_MSG_KEXDH_INIT)) != 0 ||
318     - (r = sshpkt_put_bignum2(ssh, kex->dh->pub_key)) != 0 ||
319     + {
320     + const BIGNUM *pub_key;
321     + if ((r = dh_gen_key(kex->dh, kex->we_need * 8)) != 0)
322     + goto out;
323     + DH_get0_key(kex->dh, &pub_key, NULL);
324     + if ((r = sshpkt_start(ssh, SSH2_MSG_KEXDH_INIT)) != 0 ||
325     + (r = sshpkt_put_bignum2(ssh, pub_key)) != 0 ||
326     (r = sshpkt_send(ssh)) != 0)
327     goto out;
328     + }
329     #ifdef DEBUG_KEXDH
330     DHparams_print_fp(stderr, kex->dh);
331     fprintf(stderr, "pub= ");
332     @@ -169,6 +174,9 @@ input_kex_dh(int type, u_int32_t seq, st
333    
334     /* calc and verify H */
335     hashlen = sizeof(hash);
336     + {
337     + const BIGNUM *pub_key;
338     + DH_get0_key(kex->dh, &pub_key, NULL);
339     if ((r = kex_dh_hash(
340     kex->hash_alg,
341     kex->client_version_string,
342     @@ -176,11 +184,13 @@ input_kex_dh(int type, u_int32_t seq, st
343     sshbuf_ptr(kex->my), sshbuf_len(kex->my),
344     sshbuf_ptr(kex->peer), sshbuf_len(kex->peer),
345     server_host_key_blob, sbloblen,
346     - kex->dh->pub_key,
347     + pub_key,
348     dh_server_pub,
349     shared_secret,
350     - hash, &hashlen)) != 0)
351     + hash, &hashlen)) != 0) {
352     goto out;
353     + }
354     + }
355    
356     if ((r = sshkey_verify(server_host_key, signature, slen, hash, hashlen,
357     kex->hostkey_alg, ssh->compat)) != 0)
358     diff -aurp old/kexdhs.c new/kexdhs.c
359     --- old/kexdhs.c 2018-03-22 16:21:14.000000000 -1000
360     +++ new/kexdhs.c 2018-03-23 10:58:58.126733207 -1000
361     @@ -163,6 +163,9 @@ input_kex_dh_init(int type, u_int32_t se
362     goto out;
363     /* calc H */
364     hashlen = sizeof(hash);
365     + {
366     + const BIGNUM *pub_key;
367     + DH_get0_key(kex->dh, &pub_key, NULL);
368     if ((r = kex_dh_hash(
369     kex->hash_alg,
370     kex->client_version_string,
371     @@ -171,10 +174,12 @@ input_kex_dh_init(int type, u_int32_t se
372     sshbuf_ptr(kex->my), sshbuf_len(kex->my),
373     server_host_key_blob, sbloblen,
374     dh_client_pub,
375     - kex->dh->pub_key,
376     + pub_key,
377     shared_secret,
378     - hash, &hashlen)) != 0)
379     + hash, &hashlen)) != 0) {
380     goto out;
381     + }
382     + }
383    
384     /* save session id := H */
385     if (kex->session_id == NULL) {
386     @@ -195,12 +200,17 @@ input_kex_dh_init(int type, u_int32_t se
387     /* destroy_sensitive_data(); */
388    
389     /* send server hostkey, DH pubkey 'f' and singed H */
390     + {
391     + const BIGNUM *pub_key;
392     + DH_get0_key(kex->dh, &pub_key, NULL);
393     if ((r = sshpkt_start(ssh, SSH2_MSG_KEXDH_REPLY)) != 0 ||
394     (r = sshpkt_put_string(ssh, server_host_key_blob, sbloblen)) != 0 ||
395     - (r = sshpkt_put_bignum2(ssh, kex->dh->pub_key)) != 0 || /* f */
396     + (r = sshpkt_put_bignum2(ssh, pub_key)) != 0 || /* f */
397     (r = sshpkt_put_string(ssh, signature, slen)) != 0 ||
398     - (r = sshpkt_send(ssh)) != 0)
399     + (r = sshpkt_send(ssh)) != 0) {
400     goto out;
401     + }
402     + }
403    
404     if ((r = kex_derive_keys_bn(ssh, hash, hashlen, shared_secret)) == 0)
405     r = kex_send_newkeys(ssh);
406     diff -aurp old/kexgexc.c new/kexgexc.c
407     --- old/kexgexc.c 2018-03-22 16:21:14.000000000 -1000
408     +++ new/kexgexc.c 2018-03-23 11:00:00.132866201 -1000
409     @@ -118,11 +118,17 @@ input_kex_dh_gex_group(int type, u_int32
410     p = g = NULL; /* belong to kex->dh now */
411    
412     /* generate and send 'e', client DH public key */
413     - if ((r = dh_gen_key(kex->dh, kex->we_need * 8)) != 0 ||
414     - (r = sshpkt_start(ssh, SSH2_MSG_KEX_DH_GEX_INIT)) != 0 ||
415     - (r = sshpkt_put_bignum2(ssh, kex->dh->pub_key)) != 0 ||
416     - (r = sshpkt_send(ssh)) != 0)
417     + {
418     + const BIGNUM *pub_key;
419     + if ((r = dh_gen_key(kex->dh, kex->we_need * 8)) != 0)
420     + goto out;
421     + DH_get0_key(kex->dh, &pub_key, NULL);
422     + if ((r = sshpkt_start(ssh, SSH2_MSG_KEX_DH_GEX_INIT)) != 0 ||
423     + (r = sshpkt_put_bignum2(ssh, pub_key)) != 0 ||
424     + (r = sshpkt_send(ssh)) != 0) {
425     goto out;
426     + }
427     + }
428     debug("SSH2_MSG_KEX_DH_GEX_INIT sent");
429     #ifdef DEBUG_KEXDH
430     DHparams_print_fp(stderr, kex->dh);
431     @@ -212,6 +218,10 @@ input_kex_dh_gex_reply(int type, u_int32
432    
433     /* calc and verify H */
434     hashlen = sizeof(hash);
435     + {
436     + const BIGNUM *p, *g, *pub_key;
437     + DH_get0_pqg(kex->dh, &p, NULL, &g);
438     + DH_get0_key(kex->dh, &pub_key, NULL);
439     if ((r = kexgex_hash(
440     kex->hash_alg,
441     kex->client_version_string,
442     @@ -220,12 +230,14 @@ input_kex_dh_gex_reply(int type, u_int32
443     sshbuf_ptr(kex->peer), sshbuf_len(kex->peer),
444     server_host_key_blob, sbloblen,
445     kex->min, kex->nbits, kex->max,
446     - kex->dh->p, kex->dh->g,
447     - kex->dh->pub_key,
448     + p, g,
449     + pub_key,
450     dh_server_pub,
451     shared_secret,
452     - hash, &hashlen)) != 0)
453     + hash, &hashlen)) != 0) {
454     goto out;
455     + }
456     + }
457    
458     if ((r = sshkey_verify(server_host_key, signature, slen, hash,
459     hashlen, kex->hostkey_alg, ssh->compat)) != 0)
460     diff -aurp old/kexgexs.c new/kexgexs.c
461     --- old/kexgexs.c 2018-03-22 16:21:14.000000000 -1000
462     +++ new/kexgexs.c 2018-03-23 11:03:06.045049721 -1000
463     @@ -101,11 +101,16 @@ input_kex_dh_gex_request(int type, u_int
464     goto out;
465     }
466     debug("SSH2_MSG_KEX_DH_GEX_GROUP sent");
467     + {
468     + const BIGNUM *p, *g;
469     + DH_get0_pqg(kex->dh, &p, NULL, &g);
470     if ((r = sshpkt_start(ssh, SSH2_MSG_KEX_DH_GEX_GROUP)) != 0 ||
471     - (r = sshpkt_put_bignum2(ssh, kex->dh->p)) != 0 ||
472     - (r = sshpkt_put_bignum2(ssh, kex->dh->g)) != 0 ||
473     - (r = sshpkt_send(ssh)) != 0)
474     + (r = sshpkt_put_bignum2(ssh, p)) != 0 ||
475     + (r = sshpkt_put_bignum2(ssh, g)) != 0 ||
476     + (r = sshpkt_send(ssh)) != 0) {
477     goto out;
478     + }
479     + }
480    
481     /* Compute our exchange value in parallel with the client */
482     if ((r = dh_gen_key(kex->dh, kex->we_need * 8)) != 0)
483     @@ -191,6 +196,10 @@ input_kex_dh_gex_init(int type, u_int32_
484     goto out;
485     /* calc H */
486     hashlen = sizeof(hash);
487     + {
488     + const BIGNUM *p, *g, *pub_key;
489     + DH_get0_pqg(kex->dh, &p, NULL, &g);
490     + DH_get0_key(kex->dh, &pub_key, NULL);
491     if ((r = kexgex_hash(
492     kex->hash_alg,
493     kex->client_version_string,
494     @@ -199,12 +208,14 @@ input_kex_dh_gex_init(int type, u_int32_
495     sshbuf_ptr(kex->my), sshbuf_len(kex->my),
496     server_host_key_blob, sbloblen,
497     kex->min, kex->nbits, kex->max,
498     - kex->dh->p, kex->dh->g,
499     + p, g,
500     dh_client_pub,
501     - kex->dh->pub_key,
502     + pub_key,
503     shared_secret,
504     - hash, &hashlen)) != 0)
505     + hash, &hashlen)) != 0) {
506     goto out;
507     + }
508     + }
509    
510     /* save session id := H */
511     if (kex->session_id == NULL) {
512     @@ -225,12 +236,17 @@ input_kex_dh_gex_init(int type, u_int32_
513     /* destroy_sensitive_data(); */
514    
515     /* send server hostkey, DH pubkey 'f' and singed H */
516     + {
517     + const BIGNUM *pub_key;
518     + DH_get0_key(kex->dh, &pub_key, NULL);
519     if ((r = sshpkt_start(ssh, SSH2_MSG_KEX_DH_GEX_REPLY)) != 0 ||
520     (r = sshpkt_put_string(ssh, server_host_key_blob, sbloblen)) != 0 ||
521     - (r = sshpkt_put_bignum2(ssh, kex->dh->pub_key)) != 0 || /* f */
522     + (r = sshpkt_put_bignum2(ssh, pub_key)) != 0 || /* f */
523     (r = sshpkt_put_string(ssh, signature, slen)) != 0 ||
524     - (r = sshpkt_send(ssh)) != 0)
525     + (r = sshpkt_send(ssh)) != 0) {
526     goto out;
527     + }
528     + }
529    
530     if ((r = kex_derive_keys_bn(ssh, hash, hashlen, shared_secret)) == 0)
531     r = kex_send_newkeys(ssh);
532     diff -aurp old/monitor.c new/monitor.c
533     --- old/monitor.c 2018-03-22 16:21:14.000000000 -1000
534     +++ new/monitor.c 2018-03-23 10:05:03.890621610 -1000
535     @@ -595,10 +595,12 @@ mm_answer_moduli(int sock, Buffer *m)
536     buffer_put_char(m, 0);
537     return (0);
538     } else {
539     + const BIGNUM *p, *g;
540     + DH_get0_pqg(dh, &p, NULL, &g);
541     /* Send first bignum */
542     buffer_put_char(m, 1);
543     - buffer_put_bignum2(m, dh->p);
544     - buffer_put_bignum2(m, dh->g);
545     + buffer_put_bignum2(m, p);
546     + buffer_put_bignum2(m, g);
547    
548     DH_free(dh);
549     }
550     diff -aurp old/openbsd-compat/openssl-compat.c new/openbsd-compat/openssl-compat.c
551     --- old/openbsd-compat/openssl-compat.c 2018-03-22 16:21:14.000000000 -1000
552     +++ new/openbsd-compat/openssl-compat.c 2018-03-23 10:05:03.890621610 -1000
553     @@ -75,7 +75,6 @@ ssh_OpenSSL_add_all_algorithms(void)
554     /* Enable use of crypto hardware */
555     ENGINE_load_builtin_engines();
556     ENGINE_register_all_complete();
557     - OPENSSL_config(NULL);
558     }
559     #endif
560    
561     diff -aurp old/regress/unittests/sshkey/test_file.c new/regress/unittests/sshkey/test_file.c
562     --- old/regress/unittests/sshkey/test_file.c 2018-03-22 16:21:14.000000000 -1000
563     +++ new/regress/unittests/sshkey/test_file.c 2018-03-23 10:05:03.890621610 -1000
564     @@ -60,9 +60,14 @@ sshkey_file_tests(void)
565     a = load_bignum("rsa_1.param.n");
566     b = load_bignum("rsa_1.param.p");
567     c = load_bignum("rsa_1.param.q");
568     - ASSERT_BIGNUM_EQ(k1->rsa->n, a);
569     - ASSERT_BIGNUM_EQ(k1->rsa->p, b);
570     - ASSERT_BIGNUM_EQ(k1->rsa->q, c);
571     + {
572     + const BIGNUM *n, *p, *q;
573     + RSA_get0_key(k1->rsa, &n, NULL, NULL);
574     + RSA_get0_factors(k1->rsa, &p, &q);
575     + ASSERT_BIGNUM_EQ(n, a);
576     + ASSERT_BIGNUM_EQ(p, b);
577     + ASSERT_BIGNUM_EQ(q, c);
578     + }
579     BN_free(a);
580     BN_free(b);
581     BN_free(c);
582     @@ -151,9 +156,14 @@ sshkey_file_tests(void)
583     a = load_bignum("dsa_1.param.g");
584     b = load_bignum("dsa_1.param.priv");
585     c = load_bignum("dsa_1.param.pub");
586     - ASSERT_BIGNUM_EQ(k1->dsa->g, a);
587     - ASSERT_BIGNUM_EQ(k1->dsa->priv_key, b);
588     - ASSERT_BIGNUM_EQ(k1->dsa->pub_key, c);
589     + {
590     + const BIGNUM *g, *priv_key, *pub_key;
591     + DSA_get0_pqg(k1->dsa, NULL, NULL, &g);
592     + DSA_get0_key(k1->dsa, &pub_key, &priv_key);
593     + ASSERT_BIGNUM_EQ(g, a);
594     + ASSERT_BIGNUM_EQ(priv_key, b);
595     + ASSERT_BIGNUM_EQ(pub_key, c);
596     + }
597     BN_free(a);
598     BN_free(b);
599     BN_free(c);
600     diff -aurp old/regress/unittests/sshkey/test_sshkey.c new/regress/unittests/sshkey/test_sshkey.c
601     --- old/regress/unittests/sshkey/test_sshkey.c 2018-03-22 16:21:14.000000000 -1000
602     +++ new/regress/unittests/sshkey/test_sshkey.c 2018-03-23 10:05:03.890621610 -1000
603     @@ -197,9 +197,14 @@ sshkey_tests(void)
604     k1 = sshkey_new(KEY_RSA);
605     ASSERT_PTR_NE(k1, NULL);
606     ASSERT_PTR_NE(k1->rsa, NULL);
607     - ASSERT_PTR_NE(k1->rsa->n, NULL);
608     - ASSERT_PTR_NE(k1->rsa->e, NULL);
609     - ASSERT_PTR_EQ(k1->rsa->p, NULL);
610     + {
611     + const BIGNUM *n, *e, *p;
612     + RSA_get0_key(k1->rsa, &n, &e, NULL);
613     + RSA_get0_factors(k1->rsa, &p, NULL);
614     + ASSERT_PTR_NE(n, NULL);
615     + ASSERT_PTR_NE(e, NULL);
616     + ASSERT_PTR_EQ(p, NULL);
617     + }
618     sshkey_free(k1);
619     TEST_DONE();
620    
621     @@ -207,8 +212,13 @@ sshkey_tests(void)
622     k1 = sshkey_new(KEY_DSA);
623     ASSERT_PTR_NE(k1, NULL);
624     ASSERT_PTR_NE(k1->dsa, NULL);
625     - ASSERT_PTR_NE(k1->dsa->g, NULL);
626     - ASSERT_PTR_EQ(k1->dsa->priv_key, NULL);
627     + {
628     + const BIGNUM *g, *priv_key;
629     + DSA_get0_pqg(k1->dsa, NULL, NULL, &g);
630     + DSA_get0_key(k1->dsa, NULL, &priv_key);
631     + ASSERT_PTR_NE(g, NULL);
632     + ASSERT_PTR_EQ(priv_key, NULL);
633     + }
634     sshkey_free(k1);
635     TEST_DONE();
636    
637     @@ -234,9 +244,14 @@ sshkey_tests(void)
638     k1 = sshkey_new_private(KEY_RSA);
639     ASSERT_PTR_NE(k1, NULL);
640     ASSERT_PTR_NE(k1->rsa, NULL);
641     - ASSERT_PTR_NE(k1->rsa->n, NULL);
642     - ASSERT_PTR_NE(k1->rsa->e, NULL);
643     - ASSERT_PTR_NE(k1->rsa->p, NULL);
644     + {
645     + const BIGNUM *n, *e, *p;
646     + RSA_get0_key(k1->rsa, &n, &e, NULL);
647     + RSA_get0_factors(k1->rsa, &p, NULL);
648     + ASSERT_PTR_NE(n, NULL);
649     + ASSERT_PTR_NE(e, NULL);
650     + ASSERT_PTR_NE(p, NULL);
651     + }
652     ASSERT_INT_EQ(sshkey_add_private(k1), 0);
653     sshkey_free(k1);
654     TEST_DONE();
655     @@ -245,8 +260,13 @@ sshkey_tests(void)
656     k1 = sshkey_new_private(KEY_DSA);
657     ASSERT_PTR_NE(k1, NULL);
658     ASSERT_PTR_NE(k1->dsa, NULL);
659     - ASSERT_PTR_NE(k1->dsa->g, NULL);
660     - ASSERT_PTR_NE(k1->dsa->priv_key, NULL);
661     + {
662     + const BIGNUM *g, *priv_key;
663     + DSA_get0_pqg(k1->dsa, NULL, NULL, &g);
664     + DSA_get0_key(k1->dsa, NULL, &priv_key);
665     + ASSERT_PTR_NE(g, NULL);
666     + ASSERT_PTR_NE(priv_key, NULL);
667     + }
668     ASSERT_INT_EQ(sshkey_add_private(k1), 0);
669     sshkey_free(k1);
670     TEST_DONE();
671     @@ -285,18 +305,28 @@ sshkey_tests(void)
672     ASSERT_INT_EQ(sshkey_generate(KEY_RSA, 1024, &kr), 0);
673     ASSERT_PTR_NE(kr, NULL);
674     ASSERT_PTR_NE(kr->rsa, NULL);
675     - ASSERT_PTR_NE(kr->rsa->n, NULL);
676     - ASSERT_PTR_NE(kr->rsa->e, NULL);
677     - ASSERT_PTR_NE(kr->rsa->p, NULL);
678     - ASSERT_INT_EQ(BN_num_bits(kr->rsa->n), 1024);
679     + {
680     + const BIGNUM *n, *e, *p;
681     + RSA_get0_key(kr->rsa, &n, &e, NULL);
682     + RSA_get0_factors(kr->rsa, &p, NULL);
683     + ASSERT_PTR_NE(n, NULL);
684     + ASSERT_PTR_NE(e, NULL);
685     + ASSERT_PTR_NE(p, NULL);
686     + ASSERT_INT_EQ(BN_num_bits(n), 1024);
687     + }
688     TEST_DONE();
689    
690     TEST_START("generate KEY_DSA");
691     ASSERT_INT_EQ(sshkey_generate(KEY_DSA, 1024, &kd), 0);
692     ASSERT_PTR_NE(kd, NULL);
693     ASSERT_PTR_NE(kd->dsa, NULL);
694     - ASSERT_PTR_NE(kd->dsa->g, NULL);
695     - ASSERT_PTR_NE(kd->dsa->priv_key, NULL);
696     + {
697     + const BIGNUM *g, *priv_key;
698     + DSA_get0_pqg(kd->dsa, NULL, NULL, &g);
699     + DSA_get0_key(kd->dsa, NULL, &priv_key);
700     + ASSERT_PTR_NE(g, NULL);
701     + ASSERT_PTR_NE(priv_key, NULL);
702     + }
703     TEST_DONE();
704    
705     #ifdef OPENSSL_HAS_ECC
706     @@ -323,9 +353,14 @@ sshkey_tests(void)
707     ASSERT_PTR_NE(kr, k1);
708     ASSERT_INT_EQ(k1->type, KEY_RSA);
709     ASSERT_PTR_NE(k1->rsa, NULL);
710     - ASSERT_PTR_NE(k1->rsa->n, NULL);
711     - ASSERT_PTR_NE(k1->rsa->e, NULL);
712     - ASSERT_PTR_EQ(k1->rsa->p, NULL);
713     + {
714     + const BIGNUM *n, *e, *p;
715     + RSA_get0_key(k1->rsa, &n, &e, NULL);
716     + RSA_get0_factors(k1->rsa, &p, NULL);
717     + ASSERT_PTR_NE(n, NULL);
718     + ASSERT_PTR_NE(e, NULL);
719     + ASSERT_PTR_EQ(p, NULL);
720     + }
721     TEST_DONE();
722    
723     TEST_START("equal KEY_RSA/demoted KEY_RSA");
724     @@ -339,8 +374,13 @@ sshkey_tests(void)
725     ASSERT_PTR_NE(kd, k1);
726     ASSERT_INT_EQ(k1->type, KEY_DSA);
727     ASSERT_PTR_NE(k1->dsa, NULL);
728     - ASSERT_PTR_NE(k1->dsa->g, NULL);
729     - ASSERT_PTR_EQ(k1->dsa->priv_key, NULL);
730     + {
731     + const BIGNUM *g, *priv_key;
732     + DSA_get0_pqg(k1->dsa, NULL, NULL, &g);
733     + DSA_get0_key(k1->dsa, NULL, &priv_key);
734     + ASSERT_PTR_NE(g, NULL);
735     + ASSERT_PTR_EQ(priv_key, NULL);
736     + }
737     TEST_DONE();
738    
739     TEST_START("equal KEY_DSA/demoted KEY_DSA");
740     diff -aurp old/ssh-dss.c new/ssh-dss.c
741     --- old/ssh-dss.c 2018-03-22 16:21:14.000000000 -1000
742     +++ new/ssh-dss.c 2018-03-23 10:05:03.891621693 -1000
743     @@ -53,6 +53,7 @@ ssh_dss_sign(const struct sshkey *key, u
744     DSA_SIG *sig = NULL;
745     u_char digest[SSH_DIGEST_MAX_LENGTH], sigblob[SIGBLOB_LEN];
746     size_t rlen, slen, len, dlen = ssh_digest_bytes(SSH_DIGEST_SHA1);
747     + const BIGNUM *r, *s;
748     struct sshbuf *b = NULL;
749     int ret = SSH_ERR_INVALID_ARGUMENT;
750    
751     @@ -76,15 +77,16 @@ ssh_dss_sign(const struct sshkey *key, u
752     goto out;
753     }
754    
755     - rlen = BN_num_bytes(sig->r);
756     - slen = BN_num_bytes(sig->s);
757     + DSA_SIG_get0(sig, &r, &s);
758     + rlen = BN_num_bytes(r);
759     + slen = BN_num_bytes(s);
760     if (rlen > INTBLOB_LEN || slen > INTBLOB_LEN) {
761     ret = SSH_ERR_INTERNAL_ERROR;
762     goto out;
763     }
764     explicit_bzero(sigblob, SIGBLOB_LEN);
765     - BN_bn2bin(sig->r, sigblob + SIGBLOB_LEN - INTBLOB_LEN - rlen);
766     - BN_bn2bin(sig->s, sigblob + SIGBLOB_LEN - slen);
767     + BN_bn2bin(r, sigblob + SIGBLOB_LEN - INTBLOB_LEN - rlen);
768     + BN_bn2bin(s, sigblob + SIGBLOB_LEN - slen);
769    
770     if ((b = sshbuf_new()) == NULL) {
771     ret = SSH_ERR_ALLOC_FAIL;
772     @@ -154,17 +156,26 @@ ssh_dss_verify(const struct sshkey *key,
773     }
774    
775     /* parse signature */
776     + {
777     + BIGNUM *r=NULL, *s=NULL;
778     if ((sig = DSA_SIG_new()) == NULL ||
779     - (sig->r = BN_new()) == NULL ||
780     - (sig->s = BN_new()) == NULL) {
781     + (r = BN_new()) == NULL ||
782     + (s = BN_new()) == NULL) {
783     ret = SSH_ERR_ALLOC_FAIL;
784     + BN_free(r);
785     + BN_free(s);
786     goto out;
787     }
788     - if ((BN_bin2bn(sigblob, INTBLOB_LEN, sig->r) == NULL) ||
789     - (BN_bin2bn(sigblob+ INTBLOB_LEN, INTBLOB_LEN, sig->s) == NULL)) {
790     + if ((BN_bin2bn(sigblob, INTBLOB_LEN, r) == NULL) ||
791     + (BN_bin2bn(sigblob+ INTBLOB_LEN, INTBLOB_LEN, s) == NULL)) {
792     ret = SSH_ERR_LIBCRYPTO_ERROR;
793     + BN_free(r);
794     + BN_free(s);
795     goto out;
796     }
797     + DSA_SIG_set0(sig, r, s);
798     + r = s = NULL;
799     + }
800    
801     /* sha1 the data */
802     if ((ret = ssh_digest_memory(SSH_DIGEST_SHA1, data, datalen,
803     diff -aurp old/ssh-ecdsa.c new/ssh-ecdsa.c
804     --- old/ssh-ecdsa.c 2018-03-22 16:21:14.000000000 -1000
805     +++ new/ssh-ecdsa.c 2018-03-23 10:05:03.891621693 -1000
806     @@ -80,9 +80,14 @@ ssh_ecdsa_sign(const struct sshkey *key,
807     ret = SSH_ERR_ALLOC_FAIL;
808     goto out;
809     }
810     - if ((ret = sshbuf_put_bignum2(bb, sig->r)) != 0 ||
811     - (ret = sshbuf_put_bignum2(bb, sig->s)) != 0)
812     + {
813     + const BIGNUM *r, *s;
814     + ECDSA_SIG_get0(sig, &r, &s);
815     + if ((ret = sshbuf_put_bignum2(bb, r)) != 0 ||
816     + (ret = sshbuf_put_bignum2(bb, s)) != 0) {
817     goto out;
818     + }
819     + }
820     if ((ret = sshbuf_put_cstring(b, sshkey_ssh_name_plain(key))) != 0 ||
821     (ret = sshbuf_put_stringb(b, bb)) != 0)
822     goto out;
823     @@ -150,11 +155,27 @@ ssh_ecdsa_verify(const struct sshkey *ke
824     ret = SSH_ERR_ALLOC_FAIL;
825     goto out;
826     }
827     - if (sshbuf_get_bignum2(sigbuf, sig->r) != 0 ||
828     - sshbuf_get_bignum2(sigbuf, sig->s) != 0) {
829     + {
830     + BIGNUM *r=NULL, *s=NULL;
831     + if ((r = BN_new()) == NULL ||
832     + (s = BN_new()) == NULL) {
833     + ret = SSH_ERR_ALLOC_FAIL;
834     + goto out_rs;
835     + }
836     + if (sshbuf_get_bignum2(sigbuf, r) != 0 ||
837     + sshbuf_get_bignum2(sigbuf, s) != 0) {
838     ret = SSH_ERR_INVALID_FORMAT;
839     + goto out_rs;
840     + }
841     + if (ECDSA_SIG_set0(sig, r, s) == 0) {
842     + ret = SSH_ERR_LIBCRYPTO_ERROR;
843     +out_rs:
844     + BN_free(r);
845     + BN_free(s);
846     goto out;
847     }
848     + r = s = NULL;
849     + }
850     if (sshbuf_len(sigbuf) != 0) {
851     ret = SSH_ERR_UNEXPECTED_TRAILING_DATA;
852     goto out;
853     diff -aurp old/ssh-keygen.c new/ssh-keygen.c
854     --- old/ssh-keygen.c 2018-03-22 16:21:14.000000000 -1000
855     +++ new/ssh-keygen.c 2018-03-23 10:05:03.891621693 -1000
856     @@ -493,11 +493,33 @@ do_convert_private_ssh2_from_blob(u_char
857    
858     switch (key->type) {
859     case KEY_DSA:
860     - buffer_get_bignum_bits(b, key->dsa->p);
861     - buffer_get_bignum_bits(b, key->dsa->g);
862     - buffer_get_bignum_bits(b, key->dsa->q);
863     - buffer_get_bignum_bits(b, key->dsa->pub_key);
864     - buffer_get_bignum_bits(b, key->dsa->priv_key);
865     + {
866     + BIGNUM *p=NULL, *g=NULL, *q=NULL, *pub_key=NULL, *priv_key=NULL;
867     + if ((p=BN_new()) == NULL ||
868     + (g=BN_new()) == NULL ||
869     + (q=BN_new()) == NULL ||
870     + (pub_key=BN_new()) == NULL ||
871     + (priv_key=BN_new()) == NULL) {
872     + BN_free(p);
873     + BN_free(g);
874     + BN_free(q);
875     + BN_free(pub_key);
876     + BN_free(priv_key);
877     + return NULL;
878     + }
879     + buffer_get_bignum_bits(b, p);
880     + buffer_get_bignum_bits(b, g);
881     + buffer_get_bignum_bits(b, q);
882     + buffer_get_bignum_bits(b, pub_key);
883     + buffer_get_bignum_bits(b, priv_key);
884     + if (DSA_set0_pqg(key->dsa, p, q, g) == 0 ||
885     + DSA_set0_key(key->dsa, pub_key, priv_key) == 0) {
886     + fatal("failed to set DSA key");
887     + BN_free(p); BN_free(g); BN_free(q);
888     + BN_free(pub_key); BN_free(priv_key);
889     + return NULL;
890     + }
891     + }
892     break;
893     case KEY_RSA:
894     if ((r = sshbuf_get_u8(b, &e1)) != 0 ||
895     @@ -514,16 +536,52 @@ do_convert_private_ssh2_from_blob(u_char
896     e += e3;
897     debug("e %lx", e);
898     }
899     - if (!BN_set_word(key->rsa->e, e)) {
900     + {
901     + BIGNUM *rsa_e = NULL;
902     + BIGNUM *d=NULL, *n=NULL, *iqmp=NULL, *q=NULL, *p=NULL;
903     + BIGNUM *dmp1=NULL, *dmq1=NULL; /* dummy input to set in RSA_set0_crt_params */
904     + rsa_e = BN_new();
905     + if (!rsa_e || !BN_set_word(rsa_e, e)) {
906     + if (rsa_e) BN_free(rsa_e);
907     sshbuf_free(b);
908     sshkey_free(key);
909     return NULL;
910     }
911     - buffer_get_bignum_bits(b, key->rsa->d);
912     - buffer_get_bignum_bits(b, key->rsa->n);
913     - buffer_get_bignum_bits(b, key->rsa->iqmp);
914     - buffer_get_bignum_bits(b, key->rsa->q);
915     - buffer_get_bignum_bits(b, key->rsa->p);
916     + if ((d=BN_new()) == NULL ||
917     + (n=BN_new()) == NULL ||
918     + (iqmp=BN_new()) == NULL ||
919     + (q=BN_new()) == NULL ||
920     + (p=BN_new()) == NULL ||
921     + (dmp1=BN_new()) == NULL ||
922     + (dmq1=BN_new()) == NULL) {
923     + BN_free(d); BN_free(n); BN_free(iqmp);
924     + BN_free(q); BN_free(p);
925     + BN_free(dmp1); BN_free(dmq1);
926     + return NULL;
927     + }
928     + BN_clear(dmp1); BN_clear(dmq1);
929     + buffer_get_bignum_bits(b, d);
930     + buffer_get_bignum_bits(b, n);
931     + buffer_get_bignum_bits(b, iqmp);
932     + buffer_get_bignum_bits(b, q);
933     + buffer_get_bignum_bits(b, p);
934     + if (RSA_set0_key(key->rsa, n, rsa_e, d) == 0)
935     + goto null;
936     + n = d = NULL;
937     + if (RSA_set0_factors(key->rsa, p, q) == 0)
938     + goto null;
939     + p = q = NULL;
940     + /* dmp1, dmq1 should not be NULL for initial set0 */
941     + if (RSA_set0_crt_params(key->rsa, dmp1, dmq1, iqmp) == 0) {
942     + null:
943     + fatal("Failed to set RSA parameters");
944     + BN_free(d); BN_free(n); BN_free(iqmp);
945     + BN_free(q); BN_free(p);
946     + BN_free(dmp1); BN_free(dmq1);
947     + return NULL;
948     + }
949     + dmp1 = dmq1 = iqmp = NULL;
950     + }
951     if ((r = ssh_rsa_generate_additional_parameters(key)) != 0)
952     fatal("generate RSA parameters failed: %s", ssh_err(r));
953     break;
954     @@ -633,7 +691,7 @@ do_convert_from_pkcs8(struct sshkey **k,
955     identity_file);
956     }
957     fclose(fp);
958     - switch (EVP_PKEY_type(pubkey->type)) {
959     + switch (EVP_PKEY_type(EVP_PKEY_id(pubkey))) {
960     case EVP_PKEY_RSA:
961     if ((*k = sshkey_new(KEY_UNSPEC)) == NULL)
962     fatal("sshkey_new failed");
963     @@ -657,7 +715,7 @@ do_convert_from_pkcs8(struct sshkey **k,
964     #endif
965     default:
966     fatal("%s: unsupported pubkey type %d", __func__,
967     - EVP_PKEY_type(pubkey->type));
968     + EVP_PKEY_type(EVP_PKEY_id(pubkey)));
969     }
970     EVP_PKEY_free(pubkey);
971     return;
972     diff -aurp old/ssh-pkcs11-client.c new/ssh-pkcs11-client.c
973     --- old/ssh-pkcs11-client.c 2018-03-22 16:21:14.000000000 -1000
974     +++ new/ssh-pkcs11-client.c 2018-03-23 10:05:03.892621777 -1000
975     @@ -144,12 +144,13 @@ pkcs11_rsa_private_encrypt(int flen, con
976     static int
977     wrap_key(RSA *rsa)
978     {
979     - static RSA_METHOD helper_rsa;
980     + static RSA_METHOD *helper_rsa;
981    
982     - memcpy(&helper_rsa, RSA_get_default_method(), sizeof(helper_rsa));
983     - helper_rsa.name = "ssh-pkcs11-helper";
984     - helper_rsa.rsa_priv_enc = pkcs11_rsa_private_encrypt;
985     - RSA_set_method(rsa, &helper_rsa);
986     + if ((helper_rsa = RSA_meth_dup(RSA_get_default_method())) == NULL)
987     + return (-1); /* XXX but caller isn't checking */
988     + RSA_meth_set1_name(helper_rsa, "ssh-pkcs11-helper");
989     + RSA_meth_set_priv_enc(helper_rsa, pkcs11_rsa_private_encrypt);
990     + RSA_set_method(rsa, helper_rsa);
991     return (0);
992     }
993    
994     diff -aurp old/ssh-pkcs11.c new/ssh-pkcs11.c
995     --- old/ssh-pkcs11.c 2018-03-22 16:21:14.000000000 -1000
996     +++ new/ssh-pkcs11.c 2018-03-23 10:05:03.892621777 -1000
997     @@ -67,7 +67,7 @@ struct pkcs11_key {
998     struct pkcs11_provider *provider;
999     CK_ULONG slotidx;
1000     int (*orig_finish)(RSA *rsa);
1001     - RSA_METHOD rsa_method;
1002     + RSA_METHOD *rsa_method;
1003     char *keyid;
1004     int keyid_len;
1005     };
1006     @@ -326,13 +326,15 @@ pkcs11_rsa_wrap(struct pkcs11_provider *
1007     k11->keyid = xmalloc(k11->keyid_len);
1008     memcpy(k11->keyid, keyid_attrib->pValue, k11->keyid_len);
1009     }
1010     - k11->orig_finish = def->finish;
1011     - memcpy(&k11->rsa_method, def, sizeof(k11->rsa_method));
1012     - k11->rsa_method.name = "pkcs11";
1013     - k11->rsa_method.rsa_priv_enc = pkcs11_rsa_private_encrypt;
1014     - k11->rsa_method.rsa_priv_dec = pkcs11_rsa_private_decrypt;
1015     - k11->rsa_method.finish = pkcs11_rsa_finish;
1016     - RSA_set_method(rsa, &k11->rsa_method);
1017     + k11->orig_finish = RSA_meth_get_finish(def);
1018     +
1019     + if ((k11->rsa_method = RSA_meth_new("pkcs11", RSA_meth_get_flags(def))) == NULL)
1020     + return -1;
1021     + RSA_meth_set_priv_enc(k11->rsa_method, pkcs11_rsa_private_encrypt);
1022     + RSA_meth_set_priv_dec(k11->rsa_method, pkcs11_rsa_private_decrypt);
1023     + RSA_meth_set_finish(k11->rsa_method, pkcs11_rsa_finish);
1024     +
1025     + RSA_set_method(rsa, k11->rsa_method);
1026     RSA_set_app_data(rsa, k11);
1027     return (0);
1028     }
1029     @@ -512,10 +514,19 @@ pkcs11_fetch_keys_filter(struct pkcs11_p
1030     if ((rsa = RSA_new()) == NULL) {
1031     error("RSA_new failed");
1032     } else {
1033     - rsa->n = BN_bin2bn(attribs[1].pValue,
1034     - attribs[1].ulValueLen, NULL);
1035     - rsa->e = BN_bin2bn(attribs[2].pValue,
1036     - attribs[2].ulValueLen, NULL);
1037     + BIGNUM *n=NULL, *e=NULL;
1038     + n = BN_new();
1039     + e = BN_new();
1040     + if (n == NULL || e == NULL)
1041     + error("BN_new alloc failed");
1042     + if (BN_bin2bn(attribs[1].pValue,
1043     + attribs[1].ulValueLen, n) == NULL ||
1044     + BN_bin2bn(attribs[2].pValue,
1045     + attribs[2].ulValueLen, e) == NULL)
1046     + error("BN_bin2bn failed");
1047     + if (RSA_set0_key(rsa, n, e, NULL) == 0)
1048     + error("RSA_set0_key failed");
1049     + n = e = NULL;
1050     }
1051     } else {
1052     cp = attribs[2].pValue;
1053     @@ -525,16 +536,19 @@ pkcs11_fetch_keys_filter(struct pkcs11_p
1054     == NULL) {
1055     error("d2i_X509 failed");
1056     } else if ((evp = X509_get_pubkey(x509)) == NULL ||
1057     - evp->type != EVP_PKEY_RSA ||
1058     - evp->pkey.rsa == NULL) {
1059     + EVP_PKEY_id(evp) != EVP_PKEY_RSA ||
1060     + EVP_PKEY_get0_RSA(evp) == NULL) {
1061     debug("X509_get_pubkey failed or no rsa");
1062     - } else if ((rsa = RSAPublicKey_dup(evp->pkey.rsa))
1063     + } else if ((rsa = RSAPublicKey_dup(EVP_PKEY_get0_RSA(evp)))
1064     == NULL) {
1065     error("RSAPublicKey_dup");
1066     }
1067     X509_free(x509);
1068     }
1069     - if (rsa && rsa->n && rsa->e &&
1070     + {
1071     + const BIGNUM *n, *e;
1072     + RSA_get0_key(rsa, &n, &e, NULL);
1073     + if (rsa && n && e &&
1074     pkcs11_rsa_wrap(p, slotidx, &attribs[0], rsa) == 0) {
1075     if ((key = sshkey_new(KEY_UNSPEC)) == NULL)
1076     fatal("sshkey_new failed");
1077     @@ -554,6 +568,7 @@ pkcs11_fetch_keys_filter(struct pkcs11_p
1078     } else if (rsa) {
1079     RSA_free(rsa);
1080     }
1081     + }
1082     for (i = 0; i < 3; i++)
1083     free(attribs[i].pValue);
1084     }
1085     diff -aurp old/ssh-rsa.c new/ssh-rsa.c
1086     --- old/ssh-rsa.c 2018-03-22 16:21:14.000000000 -1000
1087     +++ new/ssh-rsa.c 2018-03-23 10:05:03.892621777 -1000
1088     @@ -84,7 +84,6 @@ ssh_rsa_generate_additional_parameters(s
1089     {
1090     BIGNUM *aux = NULL;
1091     BN_CTX *ctx = NULL;
1092     - BIGNUM d;
1093     int r;
1094    
1095     if (key == NULL || key->rsa == NULL ||
1096     @@ -99,16 +98,27 @@ ssh_rsa_generate_additional_parameters(s
1097     }
1098     BN_set_flags(aux, BN_FLG_CONSTTIME);
1099    
1100     - BN_init(&d);
1101     - BN_with_flags(&d, key->rsa->d, BN_FLG_CONSTTIME);
1102     -
1103     - if ((BN_sub(aux, key->rsa->q, BN_value_one()) == 0) ||
1104     - (BN_mod(key->rsa->dmq1, &d, aux, ctx) == 0) ||
1105     - (BN_sub(aux, key->rsa->p, BN_value_one()) == 0) ||
1106     - (BN_mod(key->rsa->dmp1, &d, aux, ctx) == 0)) {
1107     + {
1108     + const BIGNUM *q, *d, *p;
1109     + BIGNUM *dmq1=NULL, *dmp1=NULL;
1110     + if ((dmq1 = BN_new()) == NULL ||
1111     + (dmp1 = BN_new()) == NULL ) {
1112     + r = SSH_ERR_ALLOC_FAIL;
1113     + goto out;
1114     + }
1115     + RSA_get0_key(key->rsa, NULL, NULL, &d);
1116     + RSA_get0_factors(key->rsa, &p, &q);
1117     + if ((BN_sub(aux, q, BN_value_one()) == 0) ||
1118     + (BN_mod(dmq1, d, aux, ctx) == 0) ||
1119     + (BN_sub(aux, p, BN_value_one()) == 0) ||
1120     + (BN_mod(dmp1, d, aux, ctx) == 0) ||
1121     + RSA_set0_crt_params(key->rsa, dmp1, dmq1, NULL) == 0) {
1122     r = SSH_ERR_LIBCRYPTO_ERROR;
1123     + BN_clear_free(dmp1);
1124     + BN_clear_free(dmq1);
1125     goto out;
1126     }
1127     + }
1128     r = 0;
1129     out:
1130     BN_clear_free(aux);
1131     @@ -139,7 +149,7 @@ ssh_rsa_sign(const struct sshkey *key, u
1132     if (key == NULL || key->rsa == NULL || hash_alg == -1 ||
1133     sshkey_type_plain(key->type) != KEY_RSA)
1134     return SSH_ERR_INVALID_ARGUMENT;
1135     - if (BN_num_bits(key->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE)
1136     + if (RSA_bits(key->rsa) < SSH_RSA_MINIMUM_MODULUS_SIZE)
1137     return SSH_ERR_KEY_LENGTH;
1138     slen = RSA_size(key->rsa);
1139     if (slen <= 0 || slen > SSHBUF_MAX_BIGNUM)
1140     @@ -211,7 +221,7 @@ ssh_rsa_verify(const struct sshkey *key,
1141     sshkey_type_plain(key->type) != KEY_RSA ||
1142     sig == NULL || siglen == 0)
1143     return SSH_ERR_INVALID_ARGUMENT;
1144     - if (BN_num_bits(key->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE)
1145     + if (RSA_bits(key->rsa) < SSH_RSA_MINIMUM_MODULUS_SIZE)
1146     return SSH_ERR_KEY_LENGTH;
1147    
1148     if ((b = sshbuf_from(sig, siglen)) == NULL)
1149     diff -aurp old/sshkey.c new/sshkey.c
1150     --- old/sshkey.c 2018-03-22 16:21:14.000000000 -1000
1151     +++ new/sshkey.c 2018-03-23 10:05:03.893621860 -1000
1152     @@ -274,10 +274,18 @@ sshkey_size(const struct sshkey *k)
1153     #ifdef WITH_OPENSSL
1154     case KEY_RSA:
1155     case KEY_RSA_CERT:
1156     - return BN_num_bits(k->rsa->n);
1157     +#if OPENSSL_VERSION_NUMBER >= 0x10100000UL
1158     + return RSA_bits(k->rsa);
1159     +#else
1160     + return RSA_bits(key->rsa);
1161     +#endif
1162     case KEY_DSA:
1163     case KEY_DSA_CERT:
1164     +#if OPENSSL_VERSION_NUMBER >= 0x10100000UL
1165     + return DSA_bits(k->dsa);
1166     +#else
1167     return BN_num_bits(k->dsa->p);
1168     +#endif
1169     case KEY_ECDSA:
1170     case KEY_ECDSA_CERT:
1171     return sshkey_curve_nid_to_bits(k->ecdsa_nid);
1172     @@ -482,26 +490,53 @@ sshkey_new(int type)
1173     #ifdef WITH_OPENSSL
1174     case KEY_RSA:
1175     case KEY_RSA_CERT:
1176     + {
1177     + BIGNUM *n=NULL, *e=NULL; /* just allocate */
1178     if ((rsa = RSA_new()) == NULL ||
1179     - (rsa->n = BN_new()) == NULL ||
1180     - (rsa->e = BN_new()) == NULL) {
1181     + (n = BN_new()) == NULL ||
1182     + (e = BN_new()) == NULL) {
1183     + BN_free(n);
1184     + BN_free(e);
1185     RSA_free(rsa);
1186     free(k);
1187     return NULL;
1188     }
1189     + BN_clear(n); BN_clear(e);
1190     + if (RSA_set0_key(rsa, n, e, NULL) == 0)
1191     + return NULL;
1192     + n = e = NULL;
1193     + }
1194     k->rsa = rsa;
1195     break;
1196     case KEY_DSA:
1197     case KEY_DSA_CERT:
1198     + {
1199     + BIGNUM *p=NULL, *q=NULL, *g=NULL, *pubkey=NULL; /* just allocate */
1200     if ((dsa = DSA_new()) == NULL ||
1201     - (dsa->p = BN_new()) == NULL ||
1202     - (dsa->q = BN_new()) == NULL ||
1203     - (dsa->g = BN_new()) == NULL ||
1204     - (dsa->pub_key = BN_new()) == NULL) {
1205     + (p = BN_new()) == NULL ||
1206     + (q = BN_new()) == NULL ||
1207     + (g = BN_new()) == NULL ||
1208     + (pubkey = BN_new()) == NULL) {
1209     + BN_free(p);
1210     + BN_free(q);
1211     + BN_free(g);
1212     + BN_free(pubkey);
1213     DSA_free(dsa);
1214     free(k);
1215     return NULL;
1216     }
1217     + if (DSA_set0_pqg(dsa, p, q, g) == 0) {
1218     + BN_free(p); BN_free(q); BN_free(g);
1219     + BN_free(pubkey);
1220     + return NULL;
1221     + }
1222     + p = q = g = NULL;
1223     + if (DSA_set0_key(dsa, pubkey, NULL) == 0) {
1224     + BN_free(pubkey);
1225     + return NULL;
1226     + }
1227     + pubkey = NULL;
1228     + }
1229     k->dsa = dsa;
1230     break;
1231     case KEY_ECDSA:
1232     @@ -539,6 +574,51 @@ sshkey_add_private(struct sshkey *k)
1233     #ifdef WITH_OPENSSL
1234     case KEY_RSA:
1235     case KEY_RSA_CERT:
1236     +#if OPENSSL_VERSION_NUMBER >= 0x10100000UL
1237     + /* Allocate BIGNUM. This is a mess.
1238     + For OpenSSL 1.1.x API these shouldn't be mandatory,
1239     + but some regression tests for non-NULL pointer of
1240     + the data. */
1241     +#define new_or_dup(bn, nbn) \
1242     + if (bn == NULL) { \
1243     + if ((nbn = BN_new()) == NULL) \
1244     + return SSH_ERR_ALLOC_FAIL; \
1245     + } else { \
1246     + /* otherwise use-after-free will occur */ \
1247     + if ((nbn = BN_dup(bn)) == NULL) \
1248     + return SSH_ERR_ALLOC_FAIL; \
1249     + }
1250     + {
1251     + const BIGNUM *d, *iqmp, *q, *p, *dmq1, *dmp1; /* allocate if NULL */
1252     + BIGNUM *nd, *niqmp, *nq, *np, *ndmq1, *ndmp1;
1253     +
1254     + RSA_get0_key(k->rsa, NULL, NULL, &d);
1255     + RSA_get0_factors(k->rsa, &p, &q);
1256     + RSA_get0_crt_params(k->rsa, &dmp1, &dmq1, &iqmp);
1257     +
1258     + new_or_dup(d, nd);
1259     + new_or_dup(iqmp, niqmp);
1260     + new_or_dup(q, nq);
1261     + new_or_dup(p, np);
1262     + new_or_dup(dmq1, ndmq1);
1263     + new_or_dup(dmp1, ndmp1);
1264     +
1265     + if (RSA_set0_key(k->rsa, NULL, NULL, nd) == 0)
1266     + goto error1;
1267     + nd = NULL;
1268     + if (RSA_set0_factors(k->rsa, np, nq) == 0)
1269     + goto error1;
1270     + np = nq = NULL;
1271     + if (RSA_set0_crt_params(k->rsa, ndmp1, ndmq1, niqmp) == 0) {
1272     +error1:
1273     + BN_free(nd);
1274     + BN_free(np); BN_free(nq);
1275     + BN_free(ndmp1); BN_free(ndmq1); BN_free(niqmp);
1276     + return SSH_ERR_LIBCRYPTO_ERROR;
1277     + }
1278     + ndmp1 = ndmq1 = niqmp = NULL;
1279     + }
1280     +#else
1281     #define bn_maybe_alloc_failed(p) (p == NULL && (p = BN_new()) == NULL)
1282     if (bn_maybe_alloc_failed(k->rsa->d) ||
1283     bn_maybe_alloc_failed(k->rsa->iqmp) ||
1284     @@ -547,13 +627,28 @@ sshkey_add_private(struct sshkey *k)
1285     bn_maybe_alloc_failed(k->rsa->dmq1) ||
1286     bn_maybe_alloc_failed(k->rsa->dmp1))
1287     return SSH_ERR_ALLOC_FAIL;
1288     +#endif
1289     break;
1290     case KEY_DSA:
1291     case KEY_DSA_CERT:
1292     +#if OPENSSL_VERSION_NUMBER >= 0x10100000UL
1293     + {
1294     + const BIGNUM *priv_key;
1295     + BIGNUM *npriv_key;
1296     + DSA_get0_key(k->dsa, NULL, &priv_key);
1297     + new_or_dup(priv_key, npriv_key);
1298     + if (DSA_set0_key(k->dsa, NULL, npriv_key) == 0) {
1299     + BN_free(npriv_key);
1300     + return SSH_ERR_LIBCRYPTO_ERROR;
1301     + }
1302     + }
1303     +#else
1304     if (bn_maybe_alloc_failed(k->dsa->priv_key))
1305     return SSH_ERR_ALLOC_FAIL;
1306     +#endif
1307     break;
1308     #undef bn_maybe_alloc_failed
1309     +#undef new_or_dup
1310     case KEY_ECDSA:
1311     case KEY_ECDSA_CERT:
1312     /* Cannot do anything until we know the group */
1313     @@ -677,16 +772,34 @@ sshkey_equal_public(const struct sshkey
1314     #ifdef WITH_OPENSSL
1315     case KEY_RSA_CERT:
1316     case KEY_RSA:
1317     - return a->rsa != NULL && b->rsa != NULL &&
1318     - BN_cmp(a->rsa->e, b->rsa->e) == 0 &&
1319     - BN_cmp(a->rsa->n, b->rsa->n) == 0;
1320     + {
1321     + const BIGNUM *a_e, *b_e, *a_n, *b_n;
1322     + const BIGNUM *a_d, *b_d;
1323     + if (a->rsa == NULL) return 0;
1324     + if (b->rsa == NULL) return 0;
1325     + RSA_get0_key(a->rsa, &a_n, &a_e, &a_d);
1326     + RSA_get0_key(b->rsa, &b_n, &b_e, &b_d);
1327     + return
1328     + BN_cmp(a_e, b_e) == 0 &&
1329     + BN_cmp(a_n, b_n) == 0;
1330     + }
1331     case KEY_DSA_CERT:
1332     case KEY_DSA:
1333     - return a->dsa != NULL && b->dsa != NULL &&
1334     - BN_cmp(a->dsa->p, b->dsa->p) == 0 &&
1335     - BN_cmp(a->dsa->q, b->dsa->q) == 0 &&
1336     - BN_cmp(a->dsa->g, b->dsa->g) == 0 &&
1337     - BN_cmp(a->dsa->pub_key, b->dsa->pub_key) == 0;
1338     + {
1339     + const BIGNUM *a_p, *a_q, *a_g, *a_pub_key;
1340     + const BIGNUM *b_p, *b_q, *b_g, *b_pub_key;
1341     + if (a->dsa == NULL) return 0;
1342     + if (b->dsa == NULL) return 0;
1343     + DSA_get0_pqg(a->dsa, &a_p, &a_q, &a_g);
1344     + DSA_get0_pqg(b->dsa, &b_p, &b_q, &b_g);
1345     + DSA_get0_key(a->dsa, &a_pub_key, NULL);
1346     + DSA_get0_key(b->dsa, &b_pub_key, NULL);
1347     + return
1348     + BN_cmp(a_p, b_p) == 0 &&
1349     + BN_cmp(a_q, b_q) == 0 &&
1350     + BN_cmp(a_g, b_g) == 0 &&
1351     + BN_cmp(a_pub_key, b_pub_key) == 0;
1352     + }
1353     # ifdef OPENSSL_HAS_ECC
1354     case KEY_ECDSA_CERT:
1355     case KEY_ECDSA:
1356     @@ -775,12 +888,17 @@ to_blob_buf(const struct sshkey *key, st
1357     case KEY_DSA:
1358     if (key->dsa == NULL)
1359     return SSH_ERR_INVALID_ARGUMENT;
1360     + {
1361     + const BIGNUM *p, *q, *g, *pub_key;
1362     + DSA_get0_pqg(key->dsa, &p, &q, &g);
1363     + DSA_get0_key(key->dsa, &pub_key, NULL);
1364     if ((ret = sshbuf_put_cstring(b, typename)) != 0 ||
1365     - (ret = sshbuf_put_bignum2(b, key->dsa->p)) != 0 ||
1366     - (ret = sshbuf_put_bignum2(b, key->dsa->q)) != 0 ||
1367     - (ret = sshbuf_put_bignum2(b, key->dsa->g)) != 0 ||
1368     - (ret = sshbuf_put_bignum2(b, key->dsa->pub_key)) != 0)
1369     + (ret = sshbuf_put_bignum2(b, p)) != 0 ||
1370     + (ret = sshbuf_put_bignum2(b, q)) != 0 ||
1371     + (ret = sshbuf_put_bignum2(b, g)) != 0 ||
1372     + (ret = sshbuf_put_bignum2(b, pub_key)) != 0)
1373     return ret;
1374     + }
1375     break;
1376     # ifdef OPENSSL_HAS_ECC
1377     case KEY_ECDSA:
1378     @@ -796,10 +914,14 @@ to_blob_buf(const struct sshkey *key, st
1379     case KEY_RSA:
1380     if (key->rsa == NULL)
1381     return SSH_ERR_INVALID_ARGUMENT;
1382     + {
1383     + const BIGNUM *e, *n;
1384     + RSA_get0_key(key->rsa, &n, &e, NULL);
1385     if ((ret = sshbuf_put_cstring(b, typename)) != 0 ||
1386     - (ret = sshbuf_put_bignum2(b, key->rsa->e)) != 0 ||
1387     - (ret = sshbuf_put_bignum2(b, key->rsa->n)) != 0)
1388     + (ret = sshbuf_put_bignum2(b, e)) != 0 ||
1389     + (ret = sshbuf_put_bignum2(b, n)) != 0)
1390     return ret;
1391     + }
1392     break;
1393     #endif /* WITH_OPENSSL */
1394     case KEY_ED25519:
1395     @@ -1740,13 +1862,32 @@ sshkey_from_private(const struct sshkey
1396     case KEY_DSA_CERT:
1397     if ((n = sshkey_new(k->type)) == NULL)
1398     return SSH_ERR_ALLOC_FAIL;
1399     - if ((BN_copy(n->dsa->p, k->dsa->p) == NULL) ||
1400     - (BN_copy(n->dsa->q, k->dsa->q) == NULL) ||
1401     - (BN_copy(n->dsa->g, k->dsa->g) == NULL) ||
1402     - (BN_copy(n->dsa->pub_key, k->dsa->pub_key) == NULL)) {
1403     + {
1404     + const BIGNUM *p, *q, *g, *pub_key, *priv_key;
1405     + BIGNUM *cp=NULL, *cq=NULL, *cg=NULL, *cpub_key=NULL;
1406     + DSA_get0_pqg(k->dsa, &p, &q, &g);
1407     + DSA_get0_key(k->dsa, &pub_key, &priv_key);
1408     + if ((cp = BN_dup(p)) == NULL ||
1409     + (cq = BN_dup(q)) == NULL ||
1410     + (cg = BN_dup(g)) == NULL ||
1411     + (cpub_key = BN_dup(pub_key)) == NULL) {
1412     + BN_free(cp); BN_free(cq); BN_free(cg);
1413     + BN_free(cpub_key);
1414     sshkey_free(n);
1415     return SSH_ERR_ALLOC_FAIL;
1416     }
1417     + if (DSA_set0_pqg(n->dsa, cp, cq, cg) == 0)
1418     + goto error1;
1419     + cp = cq = cg = NULL;
1420     + if (DSA_set0_key(n->dsa, cpub_key, NULL) == 0) {
1421     +error1:
1422     + BN_free(cp); BN_free(cq); BN_free(cg);
1423     + BN_free(cpub_key);
1424     + sshkey_free(n);
1425     + return SSH_ERR_LIBCRYPTO_ERROR;
1426     + }
1427     + cpub_key = NULL;
1428     + }
1429     break;
1430     # ifdef OPENSSL_HAS_ECC
1431     case KEY_ECDSA:
1432     @@ -1770,11 +1911,23 @@ sshkey_from_private(const struct sshkey
1433     case KEY_RSA_CERT:
1434     if ((n = sshkey_new(k->type)) == NULL)
1435     return SSH_ERR_ALLOC_FAIL;
1436     - if ((BN_copy(n->rsa->n, k->rsa->n) == NULL) ||
1437     - (BN_copy(n->rsa->e, k->rsa->e) == NULL)) {
1438     + {
1439     + const BIGNUM *nn, *e, *d;
1440     + BIGNUM *cn=NULL, *ce=NULL;
1441     + RSA_get0_key(k->rsa, &nn, &e, &d);
1442     + if ((cn = BN_dup(nn)) == NULL ||
1443     + (ce = BN_dup(e)) == NULL ) {
1444     + BN_free(cn); BN_free(ce);
1445     sshkey_free(n);
1446     return SSH_ERR_ALLOC_FAIL;
1447     }
1448     + if (RSA_set0_key(n->rsa, cn, ce, NULL) == 0) {
1449     + BN_free(cn); BN_free(ce);
1450     + sshkey_free(n);
1451     + return SSH_ERR_LIBCRYPTO_ERROR;
1452     + }
1453     + cn = ce = NULL;
1454     + }
1455     break;
1456     #endif /* WITH_OPENSSL */
1457     case KEY_ED25519:
1458     @@ -1995,12 +2148,27 @@ sshkey_from_blob_internal(struct sshbuf
1459     ret = SSH_ERR_ALLOC_FAIL;
1460     goto out;
1461     }
1462     - if (sshbuf_get_bignum2(b, key->rsa->e) != 0 ||
1463     - sshbuf_get_bignum2(b, key->rsa->n) != 0) {
1464     + {
1465     + BIGNUM *e=NULL, *n=NULL;
1466     + if ((e = BN_new()) == NULL ||
1467     + (n = BN_new()) == NULL ) {
1468     + ret = SSH_ERR_ALLOC_FAIL;
1469     + BN_free(e); BN_free(n);
1470     + goto out;
1471     + }
1472     + if (sshbuf_get_bignum2(b, e) != 0 ||
1473     + sshbuf_get_bignum2(b, n) != 0) {
1474     ret = SSH_ERR_INVALID_FORMAT;
1475     + BN_free(e); BN_free(n);
1476     goto out;
1477     }
1478     - if (BN_num_bits(key->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) {
1479     + if (RSA_set0_key(key->rsa, n, e, NULL) == 0) {
1480     + BN_free(e); BN_free(n);
1481     + return SSH_ERR_LIBCRYPTO_ERROR;
1482     + }
1483     + n = e = NULL;
1484     + }
1485     + if (RSA_bits(key->rsa) < SSH_RSA_MINIMUM_MODULUS_SIZE) {
1486     ret = SSH_ERR_KEY_LENGTH;
1487     goto out;
1488     }
1489     @@ -2020,13 +2188,36 @@ sshkey_from_blob_internal(struct sshbuf
1490     ret = SSH_ERR_ALLOC_FAIL;
1491     goto out;
1492     }
1493     - if (sshbuf_get_bignum2(b, key->dsa->p) != 0 ||
1494     - sshbuf_get_bignum2(b, key->dsa->q) != 0 ||
1495     - sshbuf_get_bignum2(b, key->dsa->g) != 0 ||
1496     - sshbuf_get_bignum2(b, key->dsa->pub_key) != 0) {
1497     + {
1498     + BIGNUM *p=NULL, *q=NULL, *g=NULL, *pub_key=NULL;
1499     + if ((p = BN_new()) == NULL ||
1500     + (q = BN_new()) == NULL ||
1501     + (g = BN_new()) == NULL ||
1502     + (pub_key = BN_new()) == NULL) {
1503     + ret = SSH_ERR_ALLOC_FAIL;
1504     + goto error1;
1505     + }
1506     + if (sshbuf_get_bignum2(b, p) != 0 ||
1507     + sshbuf_get_bignum2(b, q) != 0 ||
1508     + sshbuf_get_bignum2(b, g) != 0 ||
1509     + sshbuf_get_bignum2(b, pub_key) != 0) {
1510     ret = SSH_ERR_INVALID_FORMAT;
1511     + goto error1;
1512     + }
1513     + if (DSA_set0_pqg(key->dsa, p, q, g) == 0) {
1514     + ret = SSH_ERR_LIBCRYPTO_ERROR;
1515     + goto error1;
1516     + }
1517     + p = q = g = NULL;
1518     + if (DSA_set0_key(key->dsa, pub_key, NULL) == 0) {
1519     + ret = SSH_ERR_LIBCRYPTO_ERROR;
1520     +error1:
1521     + BN_free(p); BN_free(q); BN_free(g);
1522     + BN_free(pub_key);
1523     goto out;
1524     }
1525     + pub_key = NULL;
1526     + }
1527     #ifdef DEBUG_PK
1528     DSA_print_fp(stderr, key->dsa, 8);
1529     #endif
1530     @@ -2327,26 +2518,63 @@ sshkey_demote(const struct sshkey *k, st
1531     goto fail;
1532     /* FALLTHROUGH */
1533     case KEY_RSA:
1534     - if ((pk->rsa = RSA_new()) == NULL ||
1535     - (pk->rsa->e = BN_dup(k->rsa->e)) == NULL ||
1536     - (pk->rsa->n = BN_dup(k->rsa->n)) == NULL) {
1537     + if ((pk->rsa = RSA_new()) == NULL ){
1538     ret = SSH_ERR_ALLOC_FAIL;
1539     goto fail;
1540     }
1541     + {
1542     + const BIGNUM *ke, *kn;
1543     + BIGNUM *pke=NULL, *pkn=NULL;
1544     + RSA_get0_key(k->rsa, &kn, &ke, NULL);
1545     + if ((pke = BN_dup(ke)) == NULL ||
1546     + (pkn = BN_dup(kn)) == NULL) {
1547     + ret = SSH_ERR_ALLOC_FAIL;
1548     + BN_free(pke); BN_free(pkn);
1549     + goto fail;
1550     + }
1551     + if (RSA_set0_key(pk->rsa, pkn, pke, NULL) == 0) {
1552     + ret = SSH_ERR_LIBCRYPTO_ERROR;
1553     + BN_free(pke); BN_free(pkn);
1554     + goto fail;
1555     + }
1556     + pkn = pke = NULL;
1557     + }
1558     break;
1559     case KEY_DSA_CERT:
1560     if ((ret = sshkey_cert_copy(k, pk)) != 0)
1561     goto fail;
1562     /* FALLTHROUGH */
1563     case KEY_DSA:
1564     - if ((pk->dsa = DSA_new()) == NULL ||
1565     - (pk->dsa->p = BN_dup(k->dsa->p)) == NULL ||
1566     - (pk->dsa->q = BN_dup(k->dsa->q)) == NULL ||
1567     - (pk->dsa->g = BN_dup(k->dsa->g)) == NULL ||
1568     - (pk->dsa->pub_key = BN_dup(k->dsa->pub_key)) == NULL) {
1569     + if ((pk->dsa = DSA_new()) == NULL ) {
1570     ret = SSH_ERR_ALLOC_FAIL;
1571     goto fail;
1572     }
1573     + {
1574     + const BIGNUM *kp, *kq, *kg, *kpub_key;
1575     + BIGNUM *pkp=NULL, *pkq=NULL, *pkg=NULL, *pkpub_key=NULL;
1576     + DSA_get0_pqg(k->dsa, &kp, &kq, &kg);
1577     + DSA_get0_key(k->dsa, &kpub_key, NULL);
1578     + if ((pkp = BN_dup(kp)) == NULL ||
1579     + (pkq = BN_dup(kq)) == NULL ||
1580     + (pkg = BN_dup(kg)) == NULL ||
1581     + (pkpub_key = BN_dup(kpub_key)) == NULL) {
1582     + ret = SSH_ERR_ALLOC_FAIL;
1583     + goto error1;
1584     + }
1585     + if (DSA_set0_pqg(pk->dsa, pkp, pkq, pkg) == 0) {
1586     + ret = SSH_ERR_LIBCRYPTO_ERROR;
1587     + goto error1;
1588     + }
1589     + pkp = pkq = pkg = NULL;
1590     + if (DSA_set0_key(pk->dsa, pkpub_key, NULL) == 0) {
1591     + ret = SSH_ERR_LIBCRYPTO_ERROR;
1592     +error1:
1593     + BN_free(pkp); BN_free(pkq); BN_free(pkg);
1594     + BN_free(pkpub_key);
1595     + goto fail;
1596     + }
1597     + pkpub_key = NULL;
1598     + }
1599     break;
1600     case KEY_ECDSA_CERT:
1601     if ((ret = sshkey_cert_copy(k, pk)) != 0)
1602     @@ -2496,11 +2724,17 @@ sshkey_certify_custom(struct sshkey *k,
1603     switch (k->type) {
1604     #ifdef WITH_OPENSSL
1605     case KEY_DSA_CERT:
1606     - if ((ret = sshbuf_put_bignum2(cert, k->dsa->p)) != 0 ||
1607     - (ret = sshbuf_put_bignum2(cert, k->dsa->q)) != 0 ||
1608     - (ret = sshbuf_put_bignum2(cert, k->dsa->g)) != 0 ||
1609     - (ret = sshbuf_put_bignum2(cert, k->dsa->pub_key)) != 0)
1610     + {
1611     + const BIGNUM *p, *q, *g, *pub_key;
1612     + DSA_get0_pqg(k->dsa, &p, &q, &g);
1613     + DSA_get0_key(k->dsa, &pub_key, NULL);
1614     + if ((ret = sshbuf_put_bignum2(cert, p)) != 0 ||
1615     + (ret = sshbuf_put_bignum2(cert, q)) != 0 ||
1616     + (ret = sshbuf_put_bignum2(cert, g)) != 0 ||
1617     + (ret = sshbuf_put_bignum2(cert, pub_key)) != 0) {
1618     goto out;
1619     + }
1620     + }
1621     break;
1622     # ifdef OPENSSL_HAS_ECC
1623     case KEY_ECDSA_CERT:
1624     @@ -2513,9 +2747,15 @@ sshkey_certify_custom(struct sshkey *k,
1625     break;
1626     # endif /* OPENSSL_HAS_ECC */
1627     case KEY_RSA_CERT:
1628     - if ((ret = sshbuf_put_bignum2(cert, k->rsa->e)) != 0 ||
1629     - (ret = sshbuf_put_bignum2(cert, k->rsa->n)) != 0)
1630     + {
1631     + const BIGNUM *e, *n;
1632     + RSA_get0_key(k->rsa, &n, &e, NULL);
1633     + if (n == NULL || e == NULL ||
1634     + (ret = sshbuf_put_bignum2(cert, e)) != 0 ||
1635     + (ret = sshbuf_put_bignum2(cert, n)) != 0) {
1636     goto out;
1637     + }
1638     + }
1639     break;
1640     #endif /* WITH_OPENSSL */
1641     case KEY_ED25519_CERT:
1642     @@ -2702,42 +2942,67 @@ sshkey_private_serialize_opt(const struc
1643     switch (key->type) {
1644     #ifdef WITH_OPENSSL
1645     case KEY_RSA:
1646     - if ((r = sshbuf_put_bignum2(b, key->rsa->n)) != 0 ||
1647     - (r = sshbuf_put_bignum2(b, key->rsa->e)) != 0 ||
1648     - (r = sshbuf_put_bignum2(b, key->rsa->d)) != 0 ||
1649     - (r = sshbuf_put_bignum2(b, key->rsa->iqmp)) != 0 ||
1650     - (r = sshbuf_put_bignum2(b, key->rsa->p)) != 0 ||
1651     - (r = sshbuf_put_bignum2(b, key->rsa->q)) != 0)
1652     + {
1653     + const BIGNUM *n, *e, *d, *iqmp, *p, *q;
1654     + RSA_get0_key(key->rsa, &n, &e, &d);
1655     + RSA_get0_crt_params(key->rsa, NULL, NULL, &iqmp);
1656     + RSA_get0_factors(key->rsa, &p, &q);
1657     + if ((r = sshbuf_put_bignum2(b, n)) != 0 ||
1658     + (r = sshbuf_put_bignum2(b, e)) != 0 ||
1659     + (r = sshbuf_put_bignum2(b, d)) != 0 ||
1660     + (r = sshbuf_put_bignum2(b, iqmp)) != 0 ||
1661     + (r = sshbuf_put_bignum2(b, p)) != 0 ||
1662     + (r = sshbuf_put_bignum2(b, q)) != 0) {
1663     goto out;
1664     + }
1665     + }
1666     break;
1667     case KEY_RSA_CERT:
1668     if (key->cert == NULL || sshbuf_len(key->cert->certblob) == 0) {
1669     r = SSH_ERR_INVALID_ARGUMENT;
1670     goto out;
1671     }
1672     + {
1673     + const BIGNUM *d, *iqmp, *p, *q;
1674     + RSA_get0_key(key->rsa, NULL, NULL, &d);
1675     + RSA_get0_crt_params(key->rsa, NULL, NULL, &iqmp);
1676     + RSA_get0_factors(key->rsa, &p, &q);
1677     if ((r = sshbuf_put_stringb(b, key->cert->certblob)) != 0 ||
1678     - (r = sshbuf_put_bignum2(b, key->rsa->d)) != 0 ||
1679     - (r = sshbuf_put_bignum2(b, key->rsa->iqmp)) != 0 ||
1680     - (r = sshbuf_put_bignum2(b, key->rsa->p)) != 0 ||
1681     - (r = sshbuf_put_bignum2(b, key->rsa->q)) != 0)
1682     + (r = sshbuf_put_bignum2(b, d)) != 0 ||
1683     + (r = sshbuf_put_bignum2(b, iqmp)) != 0 ||
1684     + (r = sshbuf_put_bignum2(b, p)) != 0 ||
1685     + (r = sshbuf_put_bignum2(b, q)) != 0) {
1686     goto out;
1687     + }
1688     + }
1689     break;
1690     case KEY_DSA:
1691     - if ((r = sshbuf_put_bignum2(b, key->dsa->p)) != 0 ||
1692     - (r = sshbuf_put_bignum2(b, key->dsa->q)) != 0 ||
1693     - (r = sshbuf_put_bignum2(b, key->dsa->g)) != 0 ||
1694     - (r = sshbuf_put_bignum2(b, key->dsa->pub_key)) != 0 ||
1695     - (r = sshbuf_put_bignum2(b, key->dsa->priv_key)) != 0)
1696     + {
1697     + const BIGNUM *p, *q, *g, *pub_key, *priv_key;
1698     + DSA_get0_pqg(key->dsa, &p, &q, &g);
1699     + DSA_get0_key(key->dsa, &pub_key, &priv_key);
1700     + if ((r = sshbuf_put_bignum2(b, p)) != 0 ||
1701     + (r = sshbuf_put_bignum2(b, q)) != 0 ||
1702     + (r = sshbuf_put_bignum2(b, g)) != 0 ||
1703     + (r = sshbuf_put_bignum2(b, pub_key)) != 0 ||
1704     + (r = sshbuf_put_bignum2(b, priv_key)) != 0) {
1705     goto out;
1706     + }
1707     + }
1708     break;
1709     case KEY_DSA_CERT:
1710     if (key->cert == NULL || sshbuf_len(key->cert->certblob) == 0) {
1711     r = SSH_ERR_INVALID_ARGUMENT;
1712     goto out;
1713     }
1714     + {
1715     + const BIGNUM *priv_key;
1716     + DSA_get0_key(key->dsa, NULL, &priv_key);
1717     if ((r = sshbuf_put_stringb(b, key->cert->certblob)) != 0 ||
1718     - (r = sshbuf_put_bignum2(b, key->dsa->priv_key)) != 0)
1719     + (r = sshbuf_put_bignum2(b, priv_key)) != 0) {
1720     goto out;
1721     + }
1722     + }
1723     break;
1724     # ifdef OPENSSL_HAS_ECC
1725     case KEY_ECDSA:
1726     @@ -2851,18 +3116,61 @@ sshkey_private_deserialize(struct sshbuf
1727     r = SSH_ERR_ALLOC_FAIL;
1728     goto out;
1729     }
1730     - if ((r = sshbuf_get_bignum2(buf, k->dsa->p)) != 0 ||
1731     - (r = sshbuf_get_bignum2(buf, k->dsa->q)) != 0 ||
1732     - (r = sshbuf_get_bignum2(buf, k->dsa->g)) != 0 ||
1733     - (r = sshbuf_get_bignum2(buf, k->dsa->pub_key)) != 0 ||
1734     - (r = sshbuf_get_bignum2(buf, k->dsa->priv_key)) != 0)
1735     + {
1736     + BIGNUM *p=NULL, *q=NULL, *g=NULL, *pub_key=NULL, *priv_key=NULL;
1737     + if ((p = BN_new()) == NULL ||
1738     + (q = BN_new()) == NULL ||
1739     + (g = BN_new()) == NULL ||
1740     + (pub_key = BN_new()) == NULL ||
1741     + (priv_key = BN_new()) == NULL) {
1742     + r = SSH_ERR_ALLOC_FAIL;
1743     + goto error1;
1744     + }
1745     + if (p == NULL || q == NULL || g == NULL ||
1746     + pub_key == NULL || priv_key == NULL ||
1747     + (r = sshbuf_get_bignum2(buf, p)) != 0 ||
1748     + (r = sshbuf_get_bignum2(buf, q)) != 0 ||
1749     + (r = sshbuf_get_bignum2(buf, g)) != 0 ||
1750     + (r = sshbuf_get_bignum2(buf, pub_key)) != 0 ||
1751     + (r = sshbuf_get_bignum2(buf, priv_key)) != 0) {
1752     + goto error1;
1753     + }
1754     + if (DSA_set0_pqg(k->dsa, p, q, g) == 0) {
1755     + r = SSH_ERR_LIBCRYPTO_ERROR;
1756     + goto error1;
1757     + }
1758     + p = q = g = NULL;
1759     + if (DSA_set0_key(k->dsa, pub_key, priv_key) == 0) {
1760     + r = SSH_ERR_LIBCRYPTO_ERROR;
1761     +error1:
1762     + BN_free(p); BN_free(q); BN_free(g);
1763     + BN_free(pub_key); BN_free(priv_key);
1764     goto out;
1765     + }
1766     + pub_key = priv_key = NULL;
1767     + }
1768     break;
1769     case KEY_DSA_CERT:
1770     - if ((r = sshkey_froms(buf, &k)) != 0 ||
1771     + {
1772     + BIGNUM *priv_key=NULL;
1773     + if ((priv_key = BN_new()) == NULL) {
1774     + r = SSH_ERR_ALLOC_FAIL;
1775     + goto out;
1776     + }
1777     + if (priv_key == NULL ||
1778     + (r = sshkey_froms(buf, &k)) != 0 ||
1779     (r = sshkey_add_private(k)) != 0 ||
1780     - (r = sshbuf_get_bignum2(buf, k->dsa->priv_key)) != 0)
1781     + (r = sshbuf_get_bignum2(buf, priv_key)) != 0) {
1782     + BN_free(priv_key);
1783     + goto out;
1784     + }
1785     + if (DSA_set0_key(k->dsa, NULL, priv_key) == 0) {
1786     + r = SSH_ERR_LIBCRYPTO_ERROR;
1787     + BN_free(priv_key);
1788     goto out;
1789     + }
1790     + priv_key = NULL;
1791     + }
1792     break;
1793     # ifdef OPENSSL_HAS_ECC
1794     case KEY_ECDSA:
1795     @@ -2921,29 +3229,104 @@ sshkey_private_deserialize(struct sshbuf
1796     r = SSH_ERR_ALLOC_FAIL;
1797     goto out;
1798     }
1799     - if ((r = sshbuf_get_bignum2(buf, k->rsa->n)) != 0 ||
1800     - (r = sshbuf_get_bignum2(buf, k->rsa->e)) != 0 ||
1801     - (r = sshbuf_get_bignum2(buf, k->rsa->d)) != 0 ||
1802     - (r = sshbuf_get_bignum2(buf, k->rsa->iqmp)) != 0 ||
1803     - (r = sshbuf_get_bignum2(buf, k->rsa->p)) != 0 ||
1804     - (r = sshbuf_get_bignum2(buf, k->rsa->q)) != 0 ||
1805     - (r = ssh_rsa_generate_additional_parameters(k)) != 0)
1806     + {
1807     + BIGNUM *n=NULL, *e=NULL, *d=NULL, *iqmp=NULL, *p=NULL, *q=NULL;
1808     + BIGNUM *dmp1=NULL, *dmq1=NULL; /* dummy for RSA_set0_crt_params */
1809     + if ((n = BN_new()) == NULL ||
1810     + (e = BN_new()) == NULL ||
1811     + (d = BN_new()) == NULL ||
1812     + (iqmp = BN_new()) == NULL ||
1813     + (p = BN_new()) == NULL ||
1814     + (q = BN_new()) == NULL ||
1815     + (dmp1 = BN_new()) == NULL ||
1816     + (dmq1 = BN_new()) == NULL) {
1817     + r = SSH_ERR_ALLOC_FAIL;
1818     + goto error2;
1819     + }
1820     + BN_clear(dmp1); BN_clear(dmq1);
1821     + if ((r = sshbuf_get_bignum2(buf, n)) != 0 ||
1822     + (r = sshbuf_get_bignum2(buf, e)) != 0 ||
1823     + (r = sshbuf_get_bignum2(buf, d)) != 0 ||
1824     + (r = sshbuf_get_bignum2(buf, iqmp)) != 0 ||
1825     + (r = sshbuf_get_bignum2(buf, p)) != 0 ||
1826     + (r = sshbuf_get_bignum2(buf, q)) != 0) {
1827     + goto error2;
1828     + }
1829     + if (RSA_set0_key(k->rsa, n, e, d) == 0) {
1830     + r = SSH_ERR_LIBCRYPTO_ERROR;
1831     + goto error2;
1832     + }
1833     + n = e = d = NULL;
1834     + /* dmp1,dmpq1 should be non NULL to set iqmp value */
1835     + if (RSA_set0_crt_params(k->rsa, dmp1, dmq1, iqmp) == 0) {
1836     + r = SSH_ERR_LIBCRYPTO_ERROR;
1837     + goto error2;
1838     + }
1839     + dmp1 = dmq1 = iqmp = NULL;
1840     + if (RSA_set0_factors(k->rsa, p, q) == 0) {
1841     + r = SSH_ERR_LIBCRYPTO_ERROR;
1842     + error2:
1843     + BN_free(n); BN_free(e); BN_free(d);
1844     + BN_free(iqmp);
1845     + BN_free(p); BN_free(q);
1846     + BN_free(dmp1); BN_free(dmq1);
1847     + goto out;
1848     + }
1849     + p = q = NULL;
1850     + if ((r = ssh_rsa_generate_additional_parameters(k)) != 0) {
1851     goto out;
1852     - if (BN_num_bits(k->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) {
1853     + }
1854     + }
1855     + if (RSA_bits(k->rsa) < SSH_RSA_MINIMUM_MODULUS_SIZE) {
1856     r = SSH_ERR_KEY_LENGTH;
1857     goto out;
1858     }
1859     break;
1860     case KEY_RSA_CERT:
1861     + {
1862     + BIGNUM *d=NULL, *iqmp=NULL, *p=NULL, *q=NULL;
1863     + BIGNUM *dmp1=NULL, *dmq1=NULL; /* dummy for RSA_set0_crt_params */
1864     + if ((d = BN_new()) == NULL ||
1865     + (iqmp = BN_new()) == NULL ||
1866     + (p = BN_new()) == NULL ||
1867     + (q = BN_new()) == NULL ||
1868     + (dmp1 = BN_new()) == NULL ||
1869     + (dmq1 = BN_new()) == NULL) {
1870     + r = SSH_ERR_ALLOC_FAIL;
1871     + goto error3;
1872     + }
1873     + BN_clear(dmp1); BN_clear(dmq1);
1874     if ((r = sshkey_froms(buf, &k)) != 0 ||
1875     (r = sshkey_add_private(k)) != 0 ||
1876     - (r = sshbuf_get_bignum2(buf, k->rsa->d)) != 0 ||
1877     - (r = sshbuf_get_bignum2(buf, k->rsa->iqmp)) != 0 ||
1878     - (r = sshbuf_get_bignum2(buf, k->rsa->p)) != 0 ||
1879     - (r = sshbuf_get_bignum2(buf, k->rsa->q)) != 0 ||
1880     - (r = ssh_rsa_generate_additional_parameters(k)) != 0)
1881     + (r = sshbuf_get_bignum2(buf, d)) != 0 ||
1882     + (r = sshbuf_get_bignum2(buf, iqmp)) != 0 ||
1883     + (r = sshbuf_get_bignum2(buf, p)) != 0 ||
1884     + (r = sshbuf_get_bignum2(buf, q)) != 0) {
1885     + goto error3;
1886     + }
1887     + if (RSA_set0_key(k->rsa, NULL, NULL, d) == 0) {
1888     + r = SSH_ERR_LIBCRYPTO_ERROR;
1889     + goto error3;
1890     + }
1891     + /* dmp1,dmpq1 should be non NULL to set value */
1892     + if (RSA_set0_crt_params(k->rsa, dmp1, dmq1, iqmp) == 0) {
1893     + r = SSH_ERR_LIBCRYPTO_ERROR;
1894     + goto error3;
1895     + }
1896     + dmp1 = dmq1 = iqmp = NULL;
1897     + if (RSA_set0_factors(k->rsa, p, q) == 0) {
1898     + r = SSH_ERR_LIBCRYPTO_ERROR;
1899     + error3:
1900     + BN_free(d); BN_free(iqmp);
1901     + BN_free(p); BN_free(q);
1902     + BN_free(dmp1); BN_free(dmq1);
1903     goto out;
1904     - if (BN_num_bits(k->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) {
1905     + }
1906     + p = q = NULL;
1907     + if ((r = ssh_rsa_generate_additional_parameters(k)) != 0)
1908     + goto out;
1909     + }
1910     + if (RSA_bits(k->rsa) < SSH_RSA_MINIMUM_MODULUS_SIZE) {
1911     r = SSH_ERR_KEY_LENGTH;
1912     goto out;
1913     }
1914     @@ -3707,7 +4090,6 @@ translate_libcrypto_error(unsigned long
1915     switch (pem_reason) {
1916     case EVP_R_BAD_DECRYPT:
1917     return SSH_ERR_KEY_WRONG_PASSPHRASE;
1918     - case EVP_R_BN_DECODE_ERROR:
1919     case EVP_R_DECODE_ERROR:
1920     #ifdef EVP_R_PRIVATE_KEY_DECODE_ERROR
1921     case EVP_R_PRIVATE_KEY_DECODE_ERROR:
1922     @@ -3772,7 +4154,7 @@ sshkey_parse_private_pem_fileblob(struct
1923     r = convert_libcrypto_error();
1924     goto out;
1925     }
1926     - if (pk->type == EVP_PKEY_RSA &&
1927     + if (EVP_PKEY_id(pk) == EVP_PKEY_RSA &&
1928     (type == KEY_UNSPEC || type == KEY_RSA)) {
1929     if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) {
1930     r = SSH_ERR_ALLOC_FAIL;
1931     @@ -3787,11 +4169,11 @@ sshkey_parse_private_pem_fileblob(struct
1932     r = SSH_ERR_LIBCRYPTO_ERROR;
1933     goto out;
1934     }
1935     - if (BN_num_bits(prv->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) {
1936     + if (RSA_bits(prv->rsa) < SSH_RSA_MINIMUM_MODULUS_SIZE) {
1937     r = SSH_ERR_KEY_LENGTH;
1938     goto out;
1939     }
1940     - } else if (pk->type == EVP_PKEY_DSA &&
1941     + } else if (EVP_PKEY_id(pk) == EVP_PKEY_DSA &&
1942     (type == KEY_UNSPEC || type == KEY_DSA)) {
1943     if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) {
1944     r = SSH_ERR_ALLOC_FAIL;
1945     @@ -3803,7 +4185,7 @@ sshkey_parse_private_pem_fileblob(struct
1946     DSA_print_fp(stderr, prv->dsa, 8);
1947     #endif
1948     #ifdef OPENSSL_HAS_ECC
1949     - } else if (pk->type == EVP_PKEY_EC &&
1950     + } else if (EVP_PKEY_id(pk) == EVP_PKEY_EC &&
1951     (type == KEY_UNSPEC || type == KEY_ECDSA)) {
1952     if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) {
1953     r = SSH_ERR_ALLOC_FAIL;