f5454ac98aa641d06c8f34660050fc5a27566501
[ipfire-2.x.git] / src / patches / openssh-7.6p1-openssl-1.1.0.patch
1 diff -Naur old/auth-pam.c new/auth-pam.c
2 --- old/auth-pam.c      2017-10-03 21:49:05.363829772 -1000
3 +++ new/auth-pam.c      2017-10-03 21:55:50.869718862 -1000
4 @@ -128,6 +128,10 @@
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 -Naur old/cipher.c new/cipher.c
16 --- old/cipher.c        2017-10-03 21:49:05.367162904 -1000
17 +++ new/cipher.c        2017-10-03 21:55:50.869718862 -1000
18 @@ -297,7 +297,10 @@
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 @@ -486,7 +489,7 @@
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 @@ -520,14 +523,19 @@
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 -Naur old/cipher.h new/cipher.h
63 --- old/cipher.h        2017-10-03 21:49:05.367162904 -1000
64 +++ new/cipher.h        2017-10-03 21:55:50.869718862 -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 -Naur old/configure new/configure
85 --- old/configure       2017-10-03 21:49:05.410493626 -1000
86 +++ new/configure       2017-10-03 22:01:49.159050540 -1000
87 @@ -12688,7 +12688,6 @@
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 -Naur old/dh.c new/dh.c
96 --- old/dh.c    2017-10-03 21:49:05.370496037 -1000
97 +++ new/dh.c    2017-10-03 21:55:50.869718862 -1000
98 @@ -212,14 +212,15 @@
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 @@ -232,7 +233,8 @@
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 @@ -243,14 +245,14 @@
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 @@ -260,9 +262,13 @@
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 @@ -271,10 +277,13 @@
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 @@ -283,16 +292,27 @@
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 @@ -307,8 +327,8 @@
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 -Naur old/dh.h new/dh.h
224 --- old/dh.h    2017-10-03 21:49:05.370496037 -1000
225 +++ new/dh.h    2017-10-03 21:55:50.869718862 -1000
226 @@ -42,7 +42,7 @@
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 -Naur old/digest-openssl.c new/digest-openssl.c
236 --- old/digest-openssl.c        2017-10-03 21:49:05.370496037 -1000
237 +++ new/digest-openssl.c        2017-10-03 21:55:50.869718862 -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 @@
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 @@
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 @@
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 @@
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 @@
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 -Naur old/kexdhc.c new/kexdhc.c
310 --- old/kexdhc.c        2017-10-03 21:49:05.373829169 -1000
311 +++ new/kexdhc.c        2017-10-03 21:55:50.869718862 -1000
312 @@ -81,11 +81,16 @@
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 @@
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 @@
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             ssh->compat)) != 0)
358 diff -Naur old/kexdhs.c new/kexdhs.c
359 --- old/kexdhs.c        2017-10-03 21:49:05.373829169 -1000
360 +++ new/kexdhs.c        2017-10-03 21:55:50.869718862 -1000
361 @@ -87,6 +87,10 @@
362         ssh_dispatch_set(ssh, SSH2_MSG_KEXDH_INIT, &input_kex_dh_init);
363         r = 0;
364   out:
365 +       if (r != 0) {
366 +               if (kex->dh) DH_free(kex->dh);
367 +               kex->dh = NULL;
368 +       }
369         return r;
370  }
371  
372 @@ -163,6 +167,9 @@
373                 goto out;
374         /* calc H */
375         hashlen = sizeof(hash);
376 +       {
377 +       const BIGNUM *pub_key;
378 +       DH_get0_key(kex->dh, &pub_key, NULL);
379         if ((r = kex_dh_hash(
380             kex->hash_alg,
381             kex->client_version_string,
382 @@ -171,10 +178,12 @@
383             sshbuf_ptr(kex->my), sshbuf_len(kex->my),
384             server_host_key_blob, sbloblen,
385             dh_client_pub,
386 -           kex->dh->pub_key,
387 +           pub_key,
388             shared_secret,
389 -           hash, &hashlen)) != 0)
390 +           hash, &hashlen)) != 0) {
391                 goto out;
392 +       }
393 +       }
394  
395         /* save session id := H */
396         if (kex->session_id == NULL) {
397 @@ -195,12 +204,17 @@
398         /* destroy_sensitive_data(); */
399  
400         /* send server hostkey, DH pubkey 'f' and singed H */
401 +       {
402 +       const BIGNUM *pub_key;
403 +       DH_get0_key(kex->dh, &pub_key, NULL);
404         if ((r = sshpkt_start(ssh, SSH2_MSG_KEXDH_REPLY)) != 0 ||
405             (r = sshpkt_put_string(ssh, server_host_key_blob, sbloblen)) != 0 ||
406 -           (r = sshpkt_put_bignum2(ssh, kex->dh->pub_key)) != 0 ||     /* f */
407 +           (r = sshpkt_put_bignum2(ssh, pub_key)) != 0 ||      /* f */
408             (r = sshpkt_put_string(ssh, signature, slen)) != 0 ||
409 -           (r = sshpkt_send(ssh)) != 0)
410 +           (r = sshpkt_send(ssh)) != 0) {
411                 goto out;
412 +       }
413 +       }
414  
415         if ((r = kex_derive_keys_bn(ssh, hash, hashlen, shared_secret)) == 0)
416                 r = kex_send_newkeys(ssh);
417 diff -Naur old/kexgexc.c new/kexgexc.c
418 --- old/kexgexc.c       2017-10-03 21:49:05.373829169 -1000
419 +++ new/kexgexc.c       2017-10-03 21:55:50.869718862 -1000
420 @@ -118,11 +118,17 @@
421         p = g = NULL; /* belong to kex->dh now */
422  
423         /* generate and send 'e', client DH public key */
424 -       if ((r = dh_gen_key(kex->dh, kex->we_need * 8)) != 0 ||
425 -           (r = sshpkt_start(ssh, SSH2_MSG_KEX_DH_GEX_INIT)) != 0 ||
426 -           (r = sshpkt_put_bignum2(ssh, kex->dh->pub_key)) != 0 ||
427 -           (r = sshpkt_send(ssh)) != 0)
428 +       {
429 +       const BIGNUM *pub_key;
430 +       if ((r = dh_gen_key(kex->dh, kex->we_need * 8)) != 0)
431 +               goto out;
432 +       DH_get0_key(kex->dh, &pub_key, NULL);
433 +       if ((r = sshpkt_start(ssh, SSH2_MSG_KEX_DH_GEX_INIT)) != 0 ||
434 +           (r = sshpkt_put_bignum2(ssh, pub_key)) != 0 ||
435 +           (r = sshpkt_send(ssh)) != 0) {
436                 goto out;
437 +       }
438 +       }
439         debug("SSH2_MSG_KEX_DH_GEX_INIT sent");
440  #ifdef DEBUG_KEXDH
441         DHparams_print_fp(stderr, kex->dh);
442 @@ -134,10 +140,12 @@
443         ssh_dispatch_set(ssh, SSH2_MSG_KEX_DH_GEX_REPLY, &input_kex_dh_gex_reply);
444         r = 0;
445  out:
446 -       if (p)
447 +       if (r != 0) {
448                 BN_clear_free(p);
449 -       if (g)
450                 BN_clear_free(g);
451 +               DH_free(kex->dh);
452 +               kex->dh = NULL;
453 +       }
454         return r;
455  }
456  
457 @@ -214,6 +222,10 @@
458  
459         /* calc and verify H */
460         hashlen = sizeof(hash);
461 +       {
462 +       const BIGNUM *p, *g, *pub_key;
463 +       DH_get0_pqg(kex->dh, &p, NULL, &g);
464 +       DH_get0_key(kex->dh, &pub_key, NULL);
465         if ((r = kexgex_hash(
466             kex->hash_alg,
467             kex->client_version_string,
468 @@ -222,12 +234,14 @@
469             sshbuf_ptr(kex->peer), sshbuf_len(kex->peer),
470             server_host_key_blob, sbloblen,
471             kex->min, kex->nbits, kex->max,
472 -           kex->dh->p, kex->dh->g,
473 -           kex->dh->pub_key,
474 +           p, g,
475 +           pub_key,
476             dh_server_pub,
477             shared_secret,
478 -           hash, &hashlen)) != 0)
479 +           hash, &hashlen)) != 0) {
480                 goto out;
481 +       }
482 +       }
483  
484         if ((r = sshkey_verify(server_host_key, signature, slen, hash,
485             hashlen, ssh->compat)) != 0)
486 diff -Naur old/kexgexs.c new/kexgexs.c
487 --- old/kexgexs.c       2017-10-03 21:49:05.373829169 -1000
488 +++ new/kexgexs.c       2017-10-03 21:55:50.869718862 -1000
489 @@ -101,11 +101,16 @@
490                 goto out;
491         }
492         debug("SSH2_MSG_KEX_DH_GEX_GROUP sent");
493 +       {
494 +       const BIGNUM *p, *g;
495 +       DH_get0_pqg(kex->dh, &p, NULL, &g);
496         if ((r = sshpkt_start(ssh, SSH2_MSG_KEX_DH_GEX_GROUP)) != 0 ||
497 -           (r = sshpkt_put_bignum2(ssh, kex->dh->p)) != 0 ||
498 -           (r = sshpkt_put_bignum2(ssh, kex->dh->g)) != 0 ||
499 -           (r = sshpkt_send(ssh)) != 0)
500 +           (r = sshpkt_put_bignum2(ssh, p)) != 0 ||
501 +           (r = sshpkt_put_bignum2(ssh, g)) != 0 ||
502 +           (r = sshpkt_send(ssh)) != 0) {
503                 goto out;
504 +       }
505 +       }
506  
507         /* Compute our exchange value in parallel with the client */
508         if ((r = dh_gen_key(kex->dh, kex->we_need * 8)) != 0)
509 @@ -115,6 +120,10 @@
510         ssh_dispatch_set(ssh, SSH2_MSG_KEX_DH_GEX_INIT, &input_kex_dh_gex_init);
511         r = 0;
512   out:
513 +       if (r != 0) {
514 +               DH_free(kex->dh);
515 +               kex->dh = NULL;
516 +       }
517         return r;
518  }
519  
520 @@ -191,6 +200,10 @@
521                 goto out;
522         /* calc H */
523         hashlen = sizeof(hash);
524 +       {
525 +       const BIGNUM *p, *g, *pub_key;
526 +       DH_get0_pqg(kex->dh, &p, NULL, &g);
527 +       DH_get0_key(kex->dh, &pub_key, NULL);
528         if ((r = kexgex_hash(
529             kex->hash_alg,
530             kex->client_version_string,
531 @@ -199,12 +212,14 @@
532             sshbuf_ptr(kex->my), sshbuf_len(kex->my),
533             server_host_key_blob, sbloblen,
534             kex->min, kex->nbits, kex->max,
535 -           kex->dh->p, kex->dh->g,
536 +           p, g,
537             dh_client_pub,
538 -           kex->dh->pub_key,
539 +           pub_key,
540             shared_secret,
541 -           hash, &hashlen)) != 0)
542 +           hash, &hashlen)) != 0) {
543                 goto out;
544 +       }
545 +       }
546  
547         /* save session id := H */
548         if (kex->session_id == NULL) {
549 @@ -225,12 +240,17 @@
550         /* destroy_sensitive_data(); */
551  
552         /* send server hostkey, DH pubkey 'f' and singed H */
553 +       {
554 +       const BIGNUM *pub_key;
555 +       DH_get0_key(kex->dh, &pub_key, NULL);
556         if ((r = sshpkt_start(ssh, SSH2_MSG_KEX_DH_GEX_REPLY)) != 0 ||
557             (r = sshpkt_put_string(ssh, server_host_key_blob, sbloblen)) != 0 ||
558 -           (r = sshpkt_put_bignum2(ssh, kex->dh->pub_key)) != 0 ||     /* f */
559 +           (r = sshpkt_put_bignum2(ssh, pub_key)) != 0 ||     /* f */
560             (r = sshpkt_put_string(ssh, signature, slen)) != 0 ||
561 -           (r = sshpkt_send(ssh)) != 0)
562 +           (r = sshpkt_send(ssh)) != 0) {
563                 goto out;
564 +       }
565 +       }
566  
567         if ((r = kex_derive_keys_bn(ssh, hash, hashlen, shared_secret)) == 0)
568                 r = kex_send_newkeys(ssh);
569 diff -Naur old/monitor.c new/monitor.c
570 --- old/monitor.c       2017-10-03 21:49:05.377162302 -1000
571 +++ new/monitor.c       2017-10-03 21:55:50.869718862 -1000
572 @@ -586,10 +586,12 @@
573                 buffer_put_char(m, 0);
574                 return (0);
575         } else {
576 +               const BIGNUM *p, *g;
577 +               DH_get0_pqg(dh, &p, NULL, &g);
578                 /* Send first bignum */
579                 buffer_put_char(m, 1);
580 -               buffer_put_bignum2(m, dh->p);
581 -               buffer_put_bignum2(m, dh->g);
582 +               buffer_put_bignum2(m, p);
583 +               buffer_put_bignum2(m, g);
584  
585                 DH_free(dh);
586         }
587 diff -Naur old/openbsd-compat/openssl-compat.c new/openbsd-compat/openssl-compat.c
588 --- old/openbsd-compat/openssl-compat.c 2017-10-03 21:49:05.397161097 -1000
589 +++ new/openbsd-compat/openssl-compat.c 2017-10-03 21:55:50.886387486 -1000
590 @@ -75,7 +75,6 @@
591         /* Enable use of crypto hardware */
592         ENGINE_load_builtin_engines();
593         ENGINE_register_all_complete();
594 -       OPENSSL_config(NULL);
595  }
596  #endif
597  
598 diff -Naur old/regress/unittests/sshkey/test_file.c new/regress/unittests/sshkey/test_file.c
599 --- old/regress/unittests/sshkey/test_file.c    2017-10-03 21:49:05.387161699 -1000
600 +++ new/regress/unittests/sshkey/test_file.c    2017-10-03 21:55:50.883053761 -1000
601 @@ -60,9 +60,14 @@
602         a = load_bignum("rsa_1.param.n");
603         b = load_bignum("rsa_1.param.p");
604         c = load_bignum("rsa_1.param.q");
605 -       ASSERT_BIGNUM_EQ(k1->rsa->n, a);
606 -       ASSERT_BIGNUM_EQ(k1->rsa->p, b);
607 -       ASSERT_BIGNUM_EQ(k1->rsa->q, c);
608 +       {
609 +       const BIGNUM *n, *p, *q;
610 +       RSA_get0_key(k1->rsa, &n, NULL, NULL);
611 +       RSA_get0_factors(k1->rsa, &p, &q);
612 +       ASSERT_BIGNUM_EQ(n, a);
613 +       ASSERT_BIGNUM_EQ(p, b);
614 +       ASSERT_BIGNUM_EQ(q, c);
615 +       }
616         BN_free(a);
617         BN_free(b);
618         BN_free(c);
619 @@ -151,9 +156,14 @@
620         a = load_bignum("dsa_1.param.g");
621         b = load_bignum("dsa_1.param.priv");
622         c = load_bignum("dsa_1.param.pub");
623 -       ASSERT_BIGNUM_EQ(k1->dsa->g, a);
624 -       ASSERT_BIGNUM_EQ(k1->dsa->priv_key, b);
625 -       ASSERT_BIGNUM_EQ(k1->dsa->pub_key, c);
626 +       {
627 +       const BIGNUM *g, *priv_key, *pub_key;
628 +       DSA_get0_pqg(k1->dsa, NULL, NULL, &g);
629 +       DSA_get0_key(k1->dsa, &pub_key, &priv_key);
630 +       ASSERT_BIGNUM_EQ(g, a);
631 +       ASSERT_BIGNUM_EQ(priv_key, b);
632 +       ASSERT_BIGNUM_EQ(pub_key, c);
633 +       }
634         BN_free(a);
635         BN_free(b);
636         BN_free(c);
637 diff -Naur old/regress/unittests/sshkey/test_sshkey.c new/regress/unittests/sshkey/test_sshkey.c
638 --- old/regress/unittests/sshkey/test_sshkey.c  2017-10-03 21:49:05.387161699 -1000
639 +++ new/regress/unittests/sshkey/test_sshkey.c  2017-10-03 21:55:50.883053761 -1000
640 @@ -197,9 +197,14 @@
641         k1 = sshkey_new(KEY_RSA);
642         ASSERT_PTR_NE(k1, NULL);
643         ASSERT_PTR_NE(k1->rsa, NULL);
644 -       ASSERT_PTR_NE(k1->rsa->n, NULL);
645 -       ASSERT_PTR_NE(k1->rsa->e, NULL);
646 -       ASSERT_PTR_EQ(k1->rsa->p, NULL);
647 +       {
648 +       const BIGNUM *n, *e, *p;
649 +       RSA_get0_key(k1->rsa, &n, &e, NULL);
650 +       RSA_get0_factors(k1->rsa, &p, NULL);
651 +       ASSERT_PTR_NE(n, NULL);
652 +       ASSERT_PTR_NE(e, NULL);
653 +       ASSERT_PTR_EQ(p, NULL);
654 +       }
655         sshkey_free(k1);
656         TEST_DONE();
657  
658 @@ -207,8 +212,13 @@
659         k1 = sshkey_new(KEY_DSA);
660         ASSERT_PTR_NE(k1, NULL);
661         ASSERT_PTR_NE(k1->dsa, NULL);
662 -       ASSERT_PTR_NE(k1->dsa->g, NULL);
663 -       ASSERT_PTR_EQ(k1->dsa->priv_key, NULL);
664 +       {
665 +       const BIGNUM *g, *priv_key;
666 +       DSA_get0_pqg(k1->dsa, NULL, NULL, &g);
667 +       DSA_get0_key(k1->dsa, NULL, &priv_key);
668 +       ASSERT_PTR_NE(g, NULL);
669 +       ASSERT_PTR_EQ(priv_key, NULL);
670 +       }
671         sshkey_free(k1);
672         TEST_DONE();
673  
674 @@ -234,9 +244,14 @@
675         k1 = sshkey_new_private(KEY_RSA);
676         ASSERT_PTR_NE(k1, NULL);
677         ASSERT_PTR_NE(k1->rsa, NULL);
678 -       ASSERT_PTR_NE(k1->rsa->n, NULL);
679 -       ASSERT_PTR_NE(k1->rsa->e, NULL);
680 -       ASSERT_PTR_NE(k1->rsa->p, NULL);
681 +       {
682 +       const BIGNUM *n, *e, *p;
683 +       RSA_get0_key(k1->rsa, &n, &e, NULL);
684 +       RSA_get0_factors(k1->rsa, &p, NULL);
685 +       ASSERT_PTR_NE(n, NULL);
686 +       ASSERT_PTR_NE(e, NULL);
687 +       ASSERT_PTR_NE(p, NULL);
688 +       }
689         ASSERT_INT_EQ(sshkey_add_private(k1), 0);
690         sshkey_free(k1);
691         TEST_DONE();
692 @@ -245,8 +260,13 @@
693         k1 = sshkey_new_private(KEY_DSA);
694         ASSERT_PTR_NE(k1, NULL);
695         ASSERT_PTR_NE(k1->dsa, NULL);
696 -       ASSERT_PTR_NE(k1->dsa->g, NULL);
697 -       ASSERT_PTR_NE(k1->dsa->priv_key, NULL);
698 +       {
699 +       const BIGNUM *g, *priv_key;
700 +       DSA_get0_pqg(k1->dsa, NULL, NULL, &g);
701 +       DSA_get0_key(k1->dsa, NULL, &priv_key);
702 +       ASSERT_PTR_NE(g, NULL);
703 +       ASSERT_PTR_NE(priv_key, NULL);
704 +       }
705         ASSERT_INT_EQ(sshkey_add_private(k1), 0);
706         sshkey_free(k1);
707         TEST_DONE();
708 @@ -285,18 +305,28 @@
709         ASSERT_INT_EQ(sshkey_generate(KEY_RSA, 1024, &kr), 0);
710         ASSERT_PTR_NE(kr, NULL);
711         ASSERT_PTR_NE(kr->rsa, NULL);
712 -       ASSERT_PTR_NE(kr->rsa->n, NULL);
713 -       ASSERT_PTR_NE(kr->rsa->e, NULL);
714 -       ASSERT_PTR_NE(kr->rsa->p, NULL);
715 -       ASSERT_INT_EQ(BN_num_bits(kr->rsa->n), 1024);
716 +       {
717 +       const BIGNUM *n, *e, *p;
718 +       RSA_get0_key(kr->rsa, &n, &e, NULL);
719 +       RSA_get0_factors(kr->rsa, &p, NULL);
720 +       ASSERT_PTR_NE(n, NULL);
721 +       ASSERT_PTR_NE(e, NULL);
722 +       ASSERT_PTR_NE(p, NULL);
723 +       ASSERT_INT_EQ(BN_num_bits(n), 1024);
724 +       }
725         TEST_DONE();
726  
727         TEST_START("generate KEY_DSA");
728         ASSERT_INT_EQ(sshkey_generate(KEY_DSA, 1024, &kd), 0);
729         ASSERT_PTR_NE(kd, NULL);
730         ASSERT_PTR_NE(kd->dsa, NULL);
731 -       ASSERT_PTR_NE(kd->dsa->g, NULL);
732 -       ASSERT_PTR_NE(kd->dsa->priv_key, NULL);
733 +       {
734 +       const BIGNUM *g, *priv_key;
735 +       DSA_get0_pqg(kd->dsa, NULL, NULL, &g);
736 +       DSA_get0_key(kd->dsa, NULL, &priv_key);
737 +       ASSERT_PTR_NE(g, NULL);
738 +       ASSERT_PTR_NE(priv_key, NULL);
739 +       }
740         TEST_DONE();
741  
742  #ifdef OPENSSL_HAS_ECC
743 @@ -323,9 +353,14 @@
744         ASSERT_PTR_NE(kr, k1);
745         ASSERT_INT_EQ(k1->type, KEY_RSA);
746         ASSERT_PTR_NE(k1->rsa, NULL);
747 -       ASSERT_PTR_NE(k1->rsa->n, NULL);
748 -       ASSERT_PTR_NE(k1->rsa->e, NULL);
749 -       ASSERT_PTR_EQ(k1->rsa->p, NULL);
750 +       {
751 +       const BIGNUM *n, *e, *p;
752 +       RSA_get0_key(k1->rsa, &n, &e, NULL);
753 +       RSA_get0_factors(k1->rsa, &p, NULL);
754 +       ASSERT_PTR_NE(n, NULL);
755 +       ASSERT_PTR_NE(e, NULL);
756 +       ASSERT_PTR_EQ(p, NULL);
757 +       }
758         TEST_DONE();
759  
760         TEST_START("equal KEY_RSA/demoted KEY_RSA");
761 @@ -339,8 +374,13 @@
762         ASSERT_PTR_NE(kd, k1);
763         ASSERT_INT_EQ(k1->type, KEY_DSA);
764         ASSERT_PTR_NE(k1->dsa, NULL);
765 -       ASSERT_PTR_NE(k1->dsa->g, NULL);
766 -       ASSERT_PTR_EQ(k1->dsa->priv_key, NULL);
767 +       {
768 +       const BIGNUM *g, *priv_key;
769 +       DSA_get0_pqg(k1->dsa, NULL, NULL, &g);
770 +       DSA_get0_key(k1->dsa, NULL, &priv_key);
771 +       ASSERT_PTR_NE(g, NULL);
772 +       ASSERT_PTR_EQ(priv_key, NULL);
773 +       }
774         TEST_DONE();
775  
776         TEST_START("equal KEY_DSA/demoted KEY_DSA");
777 diff -Naur old/ssh-dss.c new/ssh-dss.c
778 --- old/ssh-dss.c       2017-10-03 21:49:05.403827361 -1000
779 +++ new/ssh-dss.c       2017-10-03 21:55:50.869718862 -1000
780 @@ -53,6 +53,7 @@
781         DSA_SIG *sig = NULL;
782         u_char digest[SSH_DIGEST_MAX_LENGTH], sigblob[SIGBLOB_LEN];
783         size_t rlen, slen, len, dlen = ssh_digest_bytes(SSH_DIGEST_SHA1);
784 +       const BIGNUM *r, *s;
785         struct sshbuf *b = NULL;
786         int ret = SSH_ERR_INVALID_ARGUMENT;
787  
788 @@ -76,15 +77,16 @@
789                 goto out;
790         }
791  
792 -       rlen = BN_num_bytes(sig->r);
793 -       slen = BN_num_bytes(sig->s);
794 +       DSA_SIG_get0(sig, &r, &s);
795 +       rlen = BN_num_bytes(r);
796 +       slen = BN_num_bytes(s);
797         if (rlen > INTBLOB_LEN || slen > INTBLOB_LEN) {
798                 ret = SSH_ERR_INTERNAL_ERROR;
799                 goto out;
800         }
801         explicit_bzero(sigblob, SIGBLOB_LEN);
802 -       BN_bn2bin(sig->r, sigblob + SIGBLOB_LEN - INTBLOB_LEN - rlen);
803 -       BN_bn2bin(sig->s, sigblob + SIGBLOB_LEN - slen);
804 +       BN_bn2bin(r, sigblob + SIGBLOB_LEN - INTBLOB_LEN - rlen);
805 +       BN_bn2bin(s, sigblob + SIGBLOB_LEN - slen);
806  
807         if (compat & SSH_BUG_SIGBLOB) {
808                 if (sigp != NULL) {
809 @@ -176,17 +178,26 @@
810         }
811  
812         /* parse signature */
813 +       {
814 +       BIGNUM *r=NULL, *s=NULL;
815         if ((sig = DSA_SIG_new()) == NULL ||
816 -           (sig->r = BN_new()) == NULL ||
817 -           (sig->s = BN_new()) == NULL) {
818 +           (r = BN_new()) == NULL ||
819 +           (s = BN_new()) == NULL) {
820                 ret = SSH_ERR_ALLOC_FAIL;
821 +               BN_free(r);
822 +               BN_free(s);
823                 goto out;
824         }
825 -       if ((BN_bin2bn(sigblob, INTBLOB_LEN, sig->r) == NULL) ||
826 -           (BN_bin2bn(sigblob+ INTBLOB_LEN, INTBLOB_LEN, sig->s) == NULL)) {
827 +       if ((BN_bin2bn(sigblob, INTBLOB_LEN, r) == NULL) ||
828 +           (BN_bin2bn(sigblob+ INTBLOB_LEN, INTBLOB_LEN, s) == NULL)) {
829                 ret = SSH_ERR_LIBCRYPTO_ERROR;
830 +               BN_free(r);
831 +               BN_free(s);
832                 goto out;
833         }
834 +       DSA_SIG_set0(sig, r, s);
835 +       r = s = NULL;
836 +       }
837  
838         /* sha1 the data */
839         if ((ret = ssh_digest_memory(SSH_DIGEST_SHA1, data, datalen,
840 diff -Naur old/ssh-ecdsa.c new/ssh-ecdsa.c
841 --- old/ssh-ecdsa.c     2017-10-03 21:49:05.403827361 -1000
842 +++ new/ssh-ecdsa.c     2017-10-03 21:55:50.869718862 -1000
843 @@ -80,9 +80,14 @@
844                 ret = SSH_ERR_ALLOC_FAIL;
845                 goto out;
846         }
847 -       if ((ret = sshbuf_put_bignum2(bb, sig->r)) != 0 ||
848 -           (ret = sshbuf_put_bignum2(bb, sig->s)) != 0)
849 +       {
850 +       const BIGNUM *r, *s;
851 +       ECDSA_SIG_get0(sig, &r, &s);
852 +       if ((ret = sshbuf_put_bignum2(bb, r)) != 0 ||
853 +           (ret = sshbuf_put_bignum2(bb, s)) != 0) {
854                 goto out;
855 +       }
856 +       }
857         if ((ret = sshbuf_put_cstring(b, sshkey_ssh_name_plain(key))) != 0 ||
858             (ret = sshbuf_put_stringb(b, bb)) != 0)
859                 goto out;
860 @@ -151,11 +156,27 @@
861                 ret = SSH_ERR_ALLOC_FAIL;
862                 goto out;
863         }
864 -       if (sshbuf_get_bignum2(sigbuf, sig->r) != 0 ||
865 -           sshbuf_get_bignum2(sigbuf, sig->s) != 0) {
866 +       {
867 +       BIGNUM *r=NULL, *s=NULL;
868 +       if ((r = BN_new()) == NULL ||
869 +           (s = BN_new()) == NULL) {
870 +               ret = SSH_ERR_ALLOC_FAIL;
871 +               goto out_rs;
872 +       }
873 +       if (sshbuf_get_bignum2(sigbuf, r) != 0 ||
874 +           sshbuf_get_bignum2(sigbuf, s) != 0) {
875                 ret = SSH_ERR_INVALID_FORMAT;
876 +               goto out_rs;
877 +       }
878 +       if (ECDSA_SIG_set0(sig, r, s) == 0) {
879 +               ret = SSH_ERR_LIBCRYPTO_ERROR;
880 +out_rs:
881 +               BN_free(r);
882 +               BN_free(s);
883                 goto out;
884         }
885 +       r = s = NULL;
886 +       }
887         if (sshbuf_len(sigbuf) != 0) {
888                 ret = SSH_ERR_UNEXPECTED_TRAILING_DATA;
889                 goto out;
890 diff -Naur old/ssh-keygen.c new/ssh-keygen.c
891 --- old/ssh-keygen.c    2017-10-03 21:49:05.403827361 -1000
892 +++ new/ssh-keygen.c    2017-10-03 21:55:50.869718862 -1000
893 @@ -496,11 +496,33 @@
894  
895         switch (key->type) {
896         case KEY_DSA:
897 -               buffer_get_bignum_bits(b, key->dsa->p);
898 -               buffer_get_bignum_bits(b, key->dsa->g);
899 -               buffer_get_bignum_bits(b, key->dsa->q);
900 -               buffer_get_bignum_bits(b, key->dsa->pub_key);
901 -               buffer_get_bignum_bits(b, key->dsa->priv_key);
902 +               {
903 +               BIGNUM *p=NULL, *g=NULL, *q=NULL, *pub_key=NULL, *priv_key=NULL;
904 +               if ((p=BN_new()) == NULL ||
905 +                   (g=BN_new()) == NULL ||
906 +                   (q=BN_new()) == NULL ||
907 +                   (pub_key=BN_new()) == NULL ||
908 +                   (priv_key=BN_new()) == NULL) {
909 +                       BN_free(p);
910 +                       BN_free(g);
911 +                       BN_free(q);
912 +                       BN_free(pub_key);
913 +                       BN_free(priv_key);
914 +                       return NULL;
915 +               }
916 +               buffer_get_bignum_bits(b, p);
917 +               buffer_get_bignum_bits(b, g);
918 +               buffer_get_bignum_bits(b, q);
919 +               buffer_get_bignum_bits(b, pub_key);
920 +               buffer_get_bignum_bits(b, priv_key);
921 +               if (DSA_set0_pqg(key->dsa, p, q, g) == 0 ||
922 +                   DSA_set0_key(key->dsa, pub_key, priv_key) == 0) {
923 +                       fatal("failed to set DSA key");
924 +                       BN_free(p); BN_free(g); BN_free(q);
925 +                       BN_free(pub_key); BN_free(priv_key);
926 +                       return NULL;
927 +               }
928 +               }
929                 break;
930         case KEY_RSA:
931                 if ((r = sshbuf_get_u8(b, &e1)) != 0 ||
932 @@ -517,16 +539,52 @@
933                         e += e3;
934                         debug("e %lx", e);
935                 }
936 -               if (!BN_set_word(key->rsa->e, e)) {
937 +               {
938 +               BIGNUM *rsa_e = NULL;
939 +               BIGNUM *d=NULL, *n=NULL, *iqmp=NULL, *q=NULL, *p=NULL;
940 +               BIGNUM *dmp1=NULL, *dmq1=NULL; /* dummy input to set in RSA_set0_crt_params */
941 +               rsa_e = BN_new();
942 +               if (!rsa_e || !BN_set_word(rsa_e, e)) {
943 +                       if (rsa_e) BN_free(rsa_e);
944                         sshbuf_free(b);
945                         sshkey_free(key);
946                         return NULL;
947                 }
948 -               buffer_get_bignum_bits(b, key->rsa->d);
949 -               buffer_get_bignum_bits(b, key->rsa->n);
950 -               buffer_get_bignum_bits(b, key->rsa->iqmp);
951 -               buffer_get_bignum_bits(b, key->rsa->q);
952 -               buffer_get_bignum_bits(b, key->rsa->p);
953 +               if ((d=BN_new()) == NULL ||
954 +                   (n=BN_new()) == NULL ||
955 +                   (iqmp=BN_new()) == NULL ||
956 +                   (q=BN_new()) == NULL ||
957 +                   (p=BN_new()) == NULL ||
958 +                   (dmp1=BN_new()) == NULL ||
959 +                   (dmq1=BN_new()) == NULL) {
960 +                       BN_free(d); BN_free(n); BN_free(iqmp);
961 +                       BN_free(q); BN_free(p);
962 +                       BN_free(dmp1); BN_free(dmq1);
963 +                       return NULL;
964 +               }
965 +               BN_clear(dmp1); BN_clear(dmq1);
966 +               buffer_get_bignum_bits(b, d);
967 +               buffer_get_bignum_bits(b, n);
968 +               buffer_get_bignum_bits(b, iqmp);
969 +               buffer_get_bignum_bits(b, q);
970 +               buffer_get_bignum_bits(b, p);
971 +               if (RSA_set0_key(key->rsa, n, rsa_e, d) == 0)
972 +                       goto null;
973 +               n = d = NULL;
974 +               if (RSA_set0_factors(key->rsa, p, q) == 0)
975 +                       goto null;
976 +               p = q = NULL;
977 +               /* dmp1, dmq1 should not be NULL for initial set0 */
978 +               if (RSA_set0_crt_params(key->rsa, dmp1, dmq1, iqmp) == 0) {
979 + null:
980 +                       fatal("Failed to set RSA parameters");
981 +                       BN_free(d); BN_free(n); BN_free(iqmp);
982 +                       BN_free(q); BN_free(p);
983 +                       BN_free(dmp1); BN_free(dmq1);
984 +                       return NULL;
985 +               }
986 +               dmp1 = dmq1 = iqmp = NULL;
987 +               }
988                 if ((r = ssh_rsa_generate_additional_parameters(key)) != 0)
989                         fatal("generate RSA parameters failed: %s", ssh_err(r));
990                 break;
991 @@ -636,7 +694,7 @@
992                     identity_file);
993         }
994         fclose(fp);
995 -       switch (EVP_PKEY_type(pubkey->type)) {
996 +       switch (EVP_PKEY_type(EVP_PKEY_id(pubkey))) {
997         case EVP_PKEY_RSA:
998                 if ((*k = sshkey_new(KEY_UNSPEC)) == NULL)
999                         fatal("sshkey_new failed");
1000 @@ -660,7 +718,7 @@
1001  #endif
1002         default:
1003                 fatal("%s: unsupported pubkey type %d", __func__,
1004 -                   EVP_PKEY_type(pubkey->type));
1005 +                   EVP_PKEY_type(EVP_PKEY_id(pubkey)));
1006         }
1007         EVP_PKEY_free(pubkey);
1008         return;
1009 diff -Naur old/ssh-pkcs11-client.c new/ssh-pkcs11-client.c
1010 --- old/ssh-pkcs11-client.c     2017-10-03 21:49:05.403827361 -1000
1011 +++ new/ssh-pkcs11-client.c     2017-10-03 21:55:50.869718862 -1000
1012 @@ -143,12 +143,13 @@
1013  static int
1014  wrap_key(RSA *rsa)
1015  {
1016 -       static RSA_METHOD helper_rsa;
1017 +       static RSA_METHOD *helper_rsa;
1018  
1019 -       memcpy(&helper_rsa, RSA_get_default_method(), sizeof(helper_rsa));
1020 -       helper_rsa.name = "ssh-pkcs11-helper";
1021 -       helper_rsa.rsa_priv_enc = pkcs11_rsa_private_encrypt;
1022 -       RSA_set_method(rsa, &helper_rsa);
1023 +       if ((helper_rsa = RSA_meth_dup(RSA_get_default_method())) == NULL)
1024 +               return (-1); /* XXX but caller isn't checking */
1025 +       RSA_meth_set1_name(helper_rsa, "ssh-pkcs11-helper");
1026 +       RSA_meth_set_priv_enc(helper_rsa, pkcs11_rsa_private_encrypt);
1027 +       RSA_set_method(rsa, helper_rsa);
1028         return (0);
1029  }
1030  
1031 diff -Naur old/ssh-pkcs11.c new/ssh-pkcs11.c
1032 --- old/ssh-pkcs11.c    2017-10-03 21:49:05.403827361 -1000
1033 +++ new/ssh-pkcs11.c    2017-10-03 21:55:50.869718862 -1000
1034 @@ -67,7 +67,7 @@
1035         struct pkcs11_provider  *provider;
1036         CK_ULONG                slotidx;
1037         int                     (*orig_finish)(RSA *rsa);
1038 -       RSA_METHOD              rsa_method;
1039 +       RSA_METHOD              *rsa_method;
1040         char                    *keyid;
1041         int                     keyid_len;
1042  };
1043 @@ -326,13 +326,15 @@
1044                 k11->keyid = xmalloc(k11->keyid_len);
1045                 memcpy(k11->keyid, keyid_attrib->pValue, k11->keyid_len);
1046         }
1047 -       k11->orig_finish = def->finish;
1048 -       memcpy(&k11->rsa_method, def, sizeof(k11->rsa_method));
1049 -       k11->rsa_method.name = "pkcs11";
1050 -       k11->rsa_method.rsa_priv_enc = pkcs11_rsa_private_encrypt;
1051 -       k11->rsa_method.rsa_priv_dec = pkcs11_rsa_private_decrypt;
1052 -       k11->rsa_method.finish = pkcs11_rsa_finish;
1053 -       RSA_set_method(rsa, &k11->rsa_method);
1054 +       k11->orig_finish = RSA_meth_get_finish(def);
1055 +
1056 +       if ((k11->rsa_method = RSA_meth_new("pkcs11", RSA_meth_get_flags(def))) == NULL)
1057 +               return -1;
1058 +       RSA_meth_set_priv_enc(k11->rsa_method, pkcs11_rsa_private_encrypt);
1059 +       RSA_meth_set_priv_dec(k11->rsa_method, pkcs11_rsa_private_decrypt);
1060 +       RSA_meth_set_finish(k11->rsa_method, pkcs11_rsa_finish);
1061 +
1062 +       RSA_set_method(rsa, k11->rsa_method);
1063         RSA_set_app_data(rsa, k11);
1064         return (0);
1065  }
1066 @@ -512,10 +514,19 @@
1067                         if ((rsa = RSA_new()) == NULL) {
1068                                 error("RSA_new failed");
1069                         } else {
1070 -                               rsa->n = BN_bin2bn(attribs[1].pValue,
1071 -                                   attribs[1].ulValueLen, NULL);
1072 -                               rsa->e = BN_bin2bn(attribs[2].pValue,
1073 -                                   attribs[2].ulValueLen, NULL);
1074 +                               BIGNUM *n=NULL, *e=NULL;
1075 +                               n = BN_new();
1076 +                               e = BN_new();
1077 +                               if (n == NULL || e == NULL)
1078 +                                       error("BN_new alloc failed");
1079 +                               if (BN_bin2bn(attribs[1].pValue,
1080 +                                     attribs[1].ulValueLen, n) == NULL ||
1081 +                                   BN_bin2bn(attribs[2].pValue,
1082 +                                     attribs[2].ulValueLen, e) == NULL)
1083 +                                       error("BN_bin2bn failed");
1084 +                               if (RSA_set0_key(rsa, n, e, NULL) == 0)
1085 +                                       error("RSA_set0_key failed");
1086 +                               n = e = NULL;
1087                         }
1088                 } else {
1089                         cp = attribs[2].pValue;
1090 @@ -525,17 +536,20 @@
1091                             == NULL) {
1092                                 error("d2i_X509 failed");
1093                         } else if ((evp = X509_get_pubkey(x509)) == NULL ||
1094 -                           evp->type != EVP_PKEY_RSA ||
1095 -                           evp->pkey.rsa == NULL) {
1096 +                           EVP_PKEY_id(evp) != EVP_PKEY_RSA ||
1097 +                           EVP_PKEY_get0_RSA(evp) == NULL) {
1098                                 debug("X509_get_pubkey failed or no rsa");
1099 -                       } else if ((rsa = RSAPublicKey_dup(evp->pkey.rsa))
1100 +                       } else if ((rsa = RSAPublicKey_dup(EVP_PKEY_get0_RSA(evp)))
1101                             == NULL) {
1102                                 error("RSAPublicKey_dup");
1103                         }
1104                         if (x509)
1105                                 X509_free(x509);
1106                 }
1107 -               if (rsa && rsa->n && rsa->e &&
1108 +               {
1109 +               const BIGNUM *n, *e;
1110 +               RSA_get0_key(rsa, &n, &e, NULL);
1111 +               if (rsa && n && e &&
1112                     pkcs11_rsa_wrap(p, slotidx, &attribs[0], rsa) == 0) {
1113                         if ((key = sshkey_new(KEY_UNSPEC)) == NULL)
1114                                 fatal("sshkey_new failed");
1115 @@ -555,6 +569,7 @@
1116                 } else if (rsa) {
1117                         RSA_free(rsa);
1118                 }
1119 +               }
1120                 for (i = 0; i < 3; i++)
1121                         free(attribs[i].pValue);
1122         }
1123 diff -Naur old/ssh-rsa.c new/ssh-rsa.c
1124 --- old/ssh-rsa.c       2017-10-03 21:49:05.403827361 -1000
1125 +++ new/ssh-rsa.c       2017-10-03 22:06:32.005937158 -1000
1126 @@ -99,13 +99,27 @@
1127         }
1128         rsa = key->rsa;
1129  
1130 -       if ((BN_sub(aux, rsa->q, BN_value_one()) == 0) ||
1131 -           (BN_mod(rsa->dmq1, rsa->d, aux, ctx) == 0) ||
1132 -           (BN_sub(aux, rsa->p, BN_value_one()) == 0) ||
1133 -           (BN_mod(rsa->dmp1, rsa->d, aux, ctx) == 0)) {
1134 +       {
1135 +       const BIGNUM *q, *d, *p;
1136 +       BIGNUM *dmq1=NULL, *dmp1=NULL;
1137 +       if ((dmq1 = BN_new()) == NULL ||
1138 +           (dmp1 = BN_new()) == NULL ) {
1139 +               r = SSH_ERR_ALLOC_FAIL;
1140 +               goto out;
1141 +       }
1142 +       RSA_get0_key(rsa, NULL, NULL, &d);
1143 +       RSA_get0_factors(rsa, &p, &q);
1144 +       if ((BN_sub(aux, q, BN_value_one()) == 0) ||
1145 +           (BN_mod(dmq1, d, aux, ctx) == 0) ||
1146 +           (BN_sub(aux, p, BN_value_one()) == 0) ||
1147 +           (BN_mod(dmp1, d, aux, ctx) == 0) ||
1148 +            RSA_set0_crt_params(rsa, dmp1, dmq1, NULL) == 0) {
1149                 r = SSH_ERR_LIBCRYPTO_ERROR;
1150 +               BN_clear_free(dmp1);
1151 +               BN_clear_free(dmq1);
1152                 goto out;
1153         }
1154 +       }
1155         r = 0;
1156   out:
1157         BN_clear_free(aux);
1158 @@ -136,7 +150,7 @@
1159         if (key == NULL || key->rsa == NULL || hash_alg == -1 ||
1160             sshkey_type_plain(key->type) != KEY_RSA)
1161                 return SSH_ERR_INVALID_ARGUMENT;
1162 -       if (BN_num_bits(key->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE)
1163 +       if (RSA_bits(key->rsa) < SSH_RSA_MINIMUM_MODULUS_SIZE)
1164                 return SSH_ERR_KEY_LENGTH;
1165         slen = RSA_size(key->rsa);
1166         if (slen <= 0 || slen > SSHBUF_MAX_BIGNUM)
1167 @@ -210,7 +224,7 @@
1168             sshkey_type_plain(key->type) != KEY_RSA ||
1169             sig == NULL || siglen == 0)
1170                 return SSH_ERR_INVALID_ARGUMENT;
1171 -       if (BN_num_bits(key->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE)
1172 +       if (RSA_bits(key->rsa) < SSH_RSA_MINIMUM_MODULUS_SIZE)
1173                 return SSH_ERR_KEY_LENGTH;
1174  
1175         if ((b = sshbuf_from(sig, siglen)) == NULL)
1176 diff -Naur old/sshkey.c new/sshkey.c
1177 --- old/sshkey.c        2017-10-03 21:49:05.407160494 -1000
1178 +++ new/sshkey.c        2017-10-03 22:16:31.124964276 -1000
1179 @@ -264,10 +264,18 @@
1180  #ifdef WITH_OPENSSL
1181         case KEY_RSA:
1182         case KEY_RSA_CERT:
1183 -               return BN_num_bits(k->rsa->n);
1184 +#if OPENSSL_VERSION_NUMBER >= 0x10100000UL
1185 +               return RSA_bits(k->rsa);
1186 +#else
1187 +               return RSA_bits(key->rsa);
1188 +#endif
1189         case KEY_DSA:
1190         case KEY_DSA_CERT:
1191 +#if OPENSSL_VERSION_NUMBER >= 0x10100000UL
1192 +               return DSA_bits(k->dsa);
1193 +#else
1194                 return BN_num_bits(k->dsa->p);
1195 +#endif
1196         case KEY_ECDSA:
1197         case KEY_ECDSA_CERT:
1198                 return sshkey_curve_nid_to_bits(k->ecdsa_nid);
1199 @@ -466,28 +474,55 @@
1200  #ifdef WITH_OPENSSL
1201         case KEY_RSA:
1202         case KEY_RSA_CERT:
1203 +               {
1204 +               BIGNUM *n=NULL, *e=NULL; /* just allocate */
1205                 if ((rsa = RSA_new()) == NULL ||
1206 -                   (rsa->n = BN_new()) == NULL ||
1207 -                   (rsa->e = BN_new()) == NULL) {
1208 +                   (n = BN_new()) == NULL ||
1209 +                   (e = BN_new()) == NULL) {
1210 +                       BN_free(n);
1211 +                       BN_free(e);
1212                         if (rsa != NULL)
1213                                 RSA_free(rsa);
1214                         free(k);
1215                         return NULL;
1216                 }
1217 +               BN_clear(n); BN_clear(e);
1218 +               if (RSA_set0_key(rsa, n, e, NULL) == 0)
1219 +                       return NULL;
1220 +               n = e = NULL;
1221 +               }
1222                 k->rsa = rsa;
1223                 break;
1224         case KEY_DSA:
1225         case KEY_DSA_CERT:
1226 +               {
1227 +               BIGNUM *p=NULL, *q=NULL, *g=NULL, *pubkey=NULL; /* just allocate */
1228                 if ((dsa = DSA_new()) == NULL ||
1229 -                   (dsa->p = BN_new()) == NULL ||
1230 -                   (dsa->q = BN_new()) == NULL ||
1231 -                   (dsa->g = BN_new()) == NULL ||
1232 -                   (dsa->pub_key = BN_new()) == NULL) {
1233 +                   (p = BN_new()) == NULL ||
1234 +                   (q = BN_new()) == NULL ||
1235 +                   (g = BN_new()) == NULL ||
1236 +                   (pubkey = BN_new()) == NULL) {
1237 +                       BN_free(p);
1238 +                       BN_free(q);
1239 +                       BN_free(g);
1240 +                       BN_free(pubkey);
1241                         if (dsa != NULL)
1242                                 DSA_free(dsa);
1243                         free(k);
1244                         return NULL;
1245                 }
1246 +               if (DSA_set0_pqg(dsa, p, q, g) == 0) {
1247 +                       BN_free(p); BN_free(q); BN_free(g);
1248 +                       BN_free(pubkey);
1249 +                       return NULL;
1250 +               }
1251 +               p = q = g = NULL;
1252 +               if (DSA_set0_key(dsa, pubkey, NULL) == 0) {
1253 +                       BN_free(pubkey);
1254 +                       return NULL;
1255 +               }
1256 +               pubkey = NULL;
1257 +               }
1258                 k->dsa = dsa;
1259                 break;
1260         case KEY_ECDSA:
1261 @@ -523,6 +558,51 @@
1262  #ifdef WITH_OPENSSL
1263         case KEY_RSA:
1264         case KEY_RSA_CERT:
1265 +#if OPENSSL_VERSION_NUMBER >= 0x10100000UL
1266 +               /* Allocate BIGNUM. This is a mess.
1267 +                  For OpenSSL 1.1.x API these shouldn't be mandatory,
1268 +                  but some regression tests for non-NULL pointer of
1269 +                  the data. */
1270 +#define new_or_dup(bn, nbn) \
1271 +               if (bn == NULL) { \
1272 +                       if ((nbn = BN_new()) == NULL) \
1273 +                               return SSH_ERR_ALLOC_FAIL; \
1274 +               } else { \
1275 +                       /* otherwise use-after-free will occur */ \
1276 +                       if ((nbn = BN_dup(bn)) == NULL) \
1277 +                               return SSH_ERR_ALLOC_FAIL; \
1278 +               }
1279 +               {
1280 +               const BIGNUM *d, *iqmp, *q, *p, *dmq1, *dmp1; /* allocate if NULL */
1281 +               BIGNUM *nd, *niqmp, *nq, *np, *ndmq1, *ndmp1;
1282 +
1283 +               RSA_get0_key(k->rsa, NULL, NULL, &d);
1284 +               RSA_get0_factors(k->rsa, &p, &q);
1285 +               RSA_get0_crt_params(k->rsa, &dmp1, &dmq1, &iqmp);
1286 +
1287 +               new_or_dup(d, nd);
1288 +               new_or_dup(iqmp, niqmp);
1289 +               new_or_dup(q, nq);
1290 +               new_or_dup(p, np);
1291 +               new_or_dup(dmq1, ndmq1);
1292 +               new_or_dup(dmp1, ndmp1);
1293 +
1294 +               if (RSA_set0_key(k->rsa, NULL, NULL, nd) == 0)
1295 +                       goto error1;
1296 +               nd = NULL;
1297 +               if (RSA_set0_factors(k->rsa, np, nq) == 0)
1298 +                       goto error1;
1299 +               np = nq = NULL;
1300 +               if (RSA_set0_crt_params(k->rsa, ndmp1, ndmq1, niqmp) == 0) {
1301 +error1:
1302 +                       BN_free(nd);
1303 +                       BN_free(np); BN_free(nq);
1304 +                       BN_free(ndmp1); BN_free(ndmq1); BN_free(niqmp);
1305 +                       return SSH_ERR_LIBCRYPTO_ERROR;
1306 +               }
1307 +               ndmp1 = ndmq1 = niqmp = NULL;
1308 +               }
1309 +#else
1310  #define bn_maybe_alloc_failed(p) (p == NULL && (p = BN_new()) == NULL)
1311                 if (bn_maybe_alloc_failed(k->rsa->d) ||
1312                     bn_maybe_alloc_failed(k->rsa->iqmp) ||
1313 @@ -531,13 +611,28 @@
1314                     bn_maybe_alloc_failed(k->rsa->dmq1) ||
1315                     bn_maybe_alloc_failed(k->rsa->dmp1))
1316                         return SSH_ERR_ALLOC_FAIL;
1317 +#endif
1318                 break;
1319         case KEY_DSA:
1320         case KEY_DSA_CERT:
1321 +#if OPENSSL_VERSION_NUMBER >= 0x10100000UL
1322 +               {
1323 +               const BIGNUM *priv_key;
1324 +               BIGNUM *npriv_key;
1325 +               DSA_get0_key(k->dsa, NULL, &priv_key);
1326 +               new_or_dup(priv_key, npriv_key);
1327 +               if (DSA_set0_key(k->dsa, NULL, npriv_key) == 0) {
1328 +                       BN_free(npriv_key);
1329 +                       return SSH_ERR_LIBCRYPTO_ERROR;
1330 +               }
1331 +               }
1332 +#else
1333                 if (bn_maybe_alloc_failed(k->dsa->priv_key))
1334                         return SSH_ERR_ALLOC_FAIL;
1335 +#endif
1336                 break;
1337  #undef bn_maybe_alloc_failed
1338 +#undef new_or_dup
1339         case KEY_ECDSA:
1340         case KEY_ECDSA_CERT:
1341                 /* Cannot do anything until we know the group */
1342 @@ -655,16 +750,34 @@
1343  #ifdef WITH_OPENSSL
1344         case KEY_RSA_CERT:
1345         case KEY_RSA:
1346 -               return a->rsa != NULL && b->rsa != NULL &&
1347 -                   BN_cmp(a->rsa->e, b->rsa->e) == 0 &&
1348 -                   BN_cmp(a->rsa->n, b->rsa->n) == 0;
1349 +               {
1350 +               const BIGNUM *a_e, *b_e, *a_n, *b_n;
1351 +               const BIGNUM *a_d, *b_d;
1352 +               if (a->rsa == NULL) return 0;
1353 +               if (b->rsa == NULL) return 0;
1354 +               RSA_get0_key(a->rsa, &a_n, &a_e, &a_d);
1355 +               RSA_get0_key(b->rsa, &b_n, &b_e, &b_d);
1356 +               return 
1357 +                   BN_cmp(a_e, b_e) == 0 &&
1358 +                   BN_cmp(a_n, b_n) == 0;
1359 +               }
1360         case KEY_DSA_CERT:
1361         case KEY_DSA:
1362 -               return a->dsa != NULL && b->dsa != NULL &&
1363 -                   BN_cmp(a->dsa->p, b->dsa->p) == 0 &&
1364 -                   BN_cmp(a->dsa->q, b->dsa->q) == 0 &&
1365 -                   BN_cmp(a->dsa->g, b->dsa->g) == 0 &&
1366 -                   BN_cmp(a->dsa->pub_key, b->dsa->pub_key) == 0;
1367 +               {
1368 +               const BIGNUM *a_p, *a_q, *a_g, *a_pub_key;
1369 +               const BIGNUM *b_p, *b_q, *b_g, *b_pub_key;
1370 +               if (a->dsa == NULL) return 0;
1371 +               if (b->dsa == NULL) return 0;
1372 +               DSA_get0_pqg(a->dsa, &a_p, &a_q, &a_g);
1373 +               DSA_get0_pqg(b->dsa, &b_p, &b_q, &b_g);
1374 +               DSA_get0_key(a->dsa, &a_pub_key, NULL);
1375 +               DSA_get0_key(b->dsa, &b_pub_key, NULL);
1376 +               return 
1377 +                   BN_cmp(a_p, b_p) == 0 &&
1378 +                   BN_cmp(a_q, b_q) == 0 &&
1379 +                   BN_cmp(a_g, b_g) == 0 &&
1380 +                   BN_cmp(a_pub_key, b_pub_key) == 0;
1381 +               }
1382  # ifdef OPENSSL_HAS_ECC
1383         case KEY_ECDSA_CERT:
1384         case KEY_ECDSA:
1385 @@ -742,12 +855,17 @@
1386         case KEY_DSA:
1387                 if (key->dsa == NULL)
1388                         return SSH_ERR_INVALID_ARGUMENT;
1389 +               {
1390 +               const BIGNUM *p, *q, *g, *pub_key;
1391 +               DSA_get0_pqg(key->dsa, &p, &q, &g);
1392 +               DSA_get0_key(key->dsa, &pub_key, NULL);
1393                 if ((ret = sshbuf_put_cstring(b, typename)) != 0 ||
1394 -                   (ret = sshbuf_put_bignum2(b, key->dsa->p)) != 0 ||
1395 -                   (ret = sshbuf_put_bignum2(b, key->dsa->q)) != 0 ||
1396 -                   (ret = sshbuf_put_bignum2(b, key->dsa->g)) != 0 ||
1397 -                   (ret = sshbuf_put_bignum2(b, key->dsa->pub_key)) != 0)
1398 +                   (ret = sshbuf_put_bignum2(b, p)) != 0 ||
1399 +                   (ret = sshbuf_put_bignum2(b, q)) != 0 ||
1400 +                   (ret = sshbuf_put_bignum2(b, g)) != 0 ||
1401 +                   (ret = sshbuf_put_bignum2(b, pub_key)) != 0)
1402                         return ret;
1403 +               }
1404                 break;
1405  # ifdef OPENSSL_HAS_ECC
1406         case KEY_ECDSA:
1407 @@ -763,10 +881,14 @@
1408         case KEY_RSA:
1409                 if (key->rsa == NULL)
1410                         return SSH_ERR_INVALID_ARGUMENT;
1411 +               {
1412 +               const BIGNUM *e, *n;
1413 +               RSA_get0_key(key->rsa, &n, &e, NULL);
1414                 if ((ret = sshbuf_put_cstring(b, typename)) != 0 ||
1415 -                   (ret = sshbuf_put_bignum2(b, key->rsa->e)) != 0 ||
1416 -                   (ret = sshbuf_put_bignum2(b, key->rsa->n)) != 0)
1417 +                   (ret = sshbuf_put_bignum2(b, e)) != 0 ||
1418 +                   (ret = sshbuf_put_bignum2(b, n)) != 0)
1419                         return ret;
1420 +               }
1421                 break;
1422  #endif /* WITH_OPENSSL */
1423         case KEY_ED25519:
1424 @@ -1643,13 +1765,32 @@
1425         case KEY_DSA_CERT:
1426                 if ((n = sshkey_new(k->type)) == NULL)
1427                         return SSH_ERR_ALLOC_FAIL;
1428 -               if ((BN_copy(n->dsa->p, k->dsa->p) == NULL) ||
1429 -                   (BN_copy(n->dsa->q, k->dsa->q) == NULL) ||
1430 -                   (BN_copy(n->dsa->g, k->dsa->g) == NULL) ||
1431 -                   (BN_copy(n->dsa->pub_key, k->dsa->pub_key) == NULL)) {
1432 +               {
1433 +               const BIGNUM *p, *q, *g, *pub_key, *priv_key;
1434 +               BIGNUM *cp=NULL, *cq=NULL, *cg=NULL, *cpub_key=NULL;
1435 +               DSA_get0_pqg(k->dsa, &p, &q, &g);
1436 +               DSA_get0_key(k->dsa, &pub_key, &priv_key);
1437 +               if ((cp = BN_dup(p)) == NULL ||
1438 +                   (cq = BN_dup(q)) == NULL ||
1439 +                   (cg = BN_dup(g)) == NULL ||
1440 +                   (cpub_key = BN_dup(pub_key)) == NULL) {
1441 +                       BN_free(cp); BN_free(cq); BN_free(cg);
1442 +                       BN_free(cpub_key);
1443                         sshkey_free(n);
1444                         return SSH_ERR_ALLOC_FAIL;
1445                 }
1446 +               if (DSA_set0_pqg(n->dsa, cp, cq, cg) == 0)
1447 +                       goto error1;
1448 +               cp = cq = cg = NULL;
1449 +               if (DSA_set0_key(n->dsa, cpub_key, NULL) == 0) {
1450 +error1:
1451 +                       BN_free(cp); BN_free(cq); BN_free(cg);
1452 +                       BN_free(cpub_key);
1453 +                       sshkey_free(n);
1454 +                       return SSH_ERR_LIBCRYPTO_ERROR;
1455 +               }
1456 +               cpub_key = NULL;
1457 +               }
1458                 break;
1459  # ifdef OPENSSL_HAS_ECC
1460         case KEY_ECDSA:
1461 @@ -1673,11 +1814,23 @@
1462         case KEY_RSA_CERT:
1463                 if ((n = sshkey_new(k->type)) == NULL)
1464                         return SSH_ERR_ALLOC_FAIL;
1465 -               if ((BN_copy(n->rsa->n, k->rsa->n) == NULL) ||
1466 -                   (BN_copy(n->rsa->e, k->rsa->e) == NULL)) {
1467 +               {
1468 +               const BIGNUM *nn, *e, *d;
1469 +               BIGNUM *cn=NULL, *ce=NULL;
1470 +               RSA_get0_key(k->rsa, &nn, &e, &d);
1471 +               if ((cn = BN_dup(nn)) == NULL ||
1472 +                   (ce = BN_dup(e)) == NULL ) {
1473 +                       BN_free(cn); BN_free(ce);
1474                         sshkey_free(n);
1475                         return SSH_ERR_ALLOC_FAIL;
1476                 }
1477 +               if (RSA_set0_key(n->rsa, cn, ce, NULL) == 0) {
1478 +                       BN_free(cn); BN_free(ce);
1479 +                       sshkey_free(n);
1480 +                       return SSH_ERR_LIBCRYPTO_ERROR;
1481 +               }
1482 +               cn = ce = NULL;
1483 +               }
1484                 break;
1485  #endif /* WITH_OPENSSL */
1486         case KEY_ED25519:
1487 @@ -1875,12 +2028,27 @@
1488                         ret = SSH_ERR_ALLOC_FAIL;
1489                         goto out;
1490                 }
1491 -               if (sshbuf_get_bignum2(b, key->rsa->e) != 0 ||
1492 -                   sshbuf_get_bignum2(b, key->rsa->n) != 0) {
1493 +               {
1494 +               BIGNUM *e=NULL, *n=NULL;
1495 +               if ((e = BN_new()) == NULL ||
1496 +                   (n = BN_new()) == NULL ) {
1497 +                       ret = SSH_ERR_ALLOC_FAIL;
1498 +                       BN_free(e); BN_free(n);
1499 +                       goto out;
1500 +               }
1501 +               if (sshbuf_get_bignum2(b, e) != 0 ||
1502 +                   sshbuf_get_bignum2(b, n) != 0) {
1503                         ret = SSH_ERR_INVALID_FORMAT;
1504 +                       BN_free(e); BN_free(n);
1505                         goto out;
1506                 }
1507 -               if (BN_num_bits(key->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) {
1508 +               if (RSA_set0_key(key->rsa, n, e, NULL) == 0) {
1509 +                       BN_free(e); BN_free(n);
1510 +                       return SSH_ERR_LIBCRYPTO_ERROR;
1511 +               }
1512 +               n = e = NULL;
1513 +               }
1514 +               if (RSA_bits(key->rsa) < SSH_RSA_MINIMUM_MODULUS_SIZE) {
1515                         ret = SSH_ERR_KEY_LENGTH;
1516                         goto out;
1517                 }
1518 @@ -1900,13 +2068,36 @@
1519                         ret = SSH_ERR_ALLOC_FAIL;
1520                         goto out;
1521                 }
1522 -               if (sshbuf_get_bignum2(b, key->dsa->p) != 0 ||
1523 -                   sshbuf_get_bignum2(b, key->dsa->q) != 0 ||
1524 -                   sshbuf_get_bignum2(b, key->dsa->g) != 0 ||
1525 -                   sshbuf_get_bignum2(b, key->dsa->pub_key) != 0) {
1526 +               {
1527 +               BIGNUM *p=NULL, *q=NULL, *g=NULL, *pub_key=NULL;
1528 +               if ((p = BN_new()) == NULL ||
1529 +                   (q = BN_new()) == NULL ||
1530 +                   (g = BN_new()) == NULL ||
1531 +                   (pub_key = BN_new()) == NULL) {
1532 +                       ret = SSH_ERR_ALLOC_FAIL;
1533 +                       goto error1;
1534 +               }
1535 +               if (sshbuf_get_bignum2(b, p) != 0 ||
1536 +                   sshbuf_get_bignum2(b, q) != 0 ||
1537 +                   sshbuf_get_bignum2(b, g) != 0 ||
1538 +                   sshbuf_get_bignum2(b, pub_key) != 0) {
1539                         ret = SSH_ERR_INVALID_FORMAT;
1540 +                       goto error1;
1541 +               }
1542 +               if (DSA_set0_pqg(key->dsa, p, q, g) == 0) {
1543 +                       ret = SSH_ERR_LIBCRYPTO_ERROR;
1544 +                       goto error1;
1545 +               }
1546 +               p = q = g = NULL;
1547 +               if (DSA_set0_key(key->dsa, pub_key, NULL) == 0) {
1548 +                       ret = SSH_ERR_LIBCRYPTO_ERROR;
1549 +error1:
1550 +                       BN_free(p); BN_free(q); BN_free(g);
1551 +                       BN_free(pub_key);
1552                         goto out;
1553                 }
1554 +               pub_key = NULL;
1555 +               }
1556  #ifdef DEBUG_PK
1557                 DSA_print_fp(stderr, key->dsa, 8);
1558  #endif
1559 @@ -2140,26 +2331,63 @@
1560                         goto fail;
1561                 /* FALLTHROUGH */
1562         case KEY_RSA:
1563 -               if ((pk->rsa = RSA_new()) == NULL ||
1564 -                   (pk->rsa->e = BN_dup(k->rsa->e)) == NULL ||
1565 -                   (pk->rsa->n = BN_dup(k->rsa->n)) == NULL) {
1566 +               if ((pk->rsa = RSA_new()) == NULL ){
1567                         ret = SSH_ERR_ALLOC_FAIL;
1568                         goto fail;
1569                         }
1570 +               {
1571 +               const BIGNUM *ke, *kn;
1572 +               BIGNUM *pke=NULL, *pkn=NULL;
1573 +               RSA_get0_key(k->rsa, &kn, &ke, NULL);
1574 +                if ((pke = BN_dup(ke)) == NULL ||
1575 +                    (pkn = BN_dup(kn)) == NULL) {
1576 +                       ret = SSH_ERR_ALLOC_FAIL;
1577 +                       BN_free(pke); BN_free(pkn);
1578 +                       goto fail;
1579 +                       }
1580 +               if (RSA_set0_key(pk->rsa, pkn, pke, NULL) == 0) {
1581 +                       ret = SSH_ERR_LIBCRYPTO_ERROR;
1582 +                       BN_free(pke); BN_free(pkn);
1583 +                       goto fail;
1584 +               }
1585 +               pkn = pke = NULL;
1586 +               }
1587                 break;
1588         case KEY_DSA_CERT:
1589                 if ((ret = sshkey_cert_copy(k, pk)) != 0)
1590                         goto fail;
1591                 /* FALLTHROUGH */
1592         case KEY_DSA:
1593 -               if ((pk->dsa = DSA_new()) == NULL ||
1594 -                   (pk->dsa->p = BN_dup(k->dsa->p)) == NULL ||
1595 -                   (pk->dsa->q = BN_dup(k->dsa->q)) == NULL ||
1596 -                   (pk->dsa->g = BN_dup(k->dsa->g)) == NULL ||
1597 -                   (pk->dsa->pub_key = BN_dup(k->dsa->pub_key)) == NULL) {
1598 +               if ((pk->dsa = DSA_new()) == NULL ) {
1599                         ret = SSH_ERR_ALLOC_FAIL;
1600                         goto fail;
1601                 }
1602 +               {
1603 +               const BIGNUM *kp, *kq, *kg, *kpub_key;
1604 +               BIGNUM *pkp=NULL, *pkq=NULL, *pkg=NULL, *pkpub_key=NULL;
1605 +               DSA_get0_pqg(k->dsa, &kp, &kq, &kg);
1606 +               DSA_get0_key(k->dsa, &kpub_key, NULL);
1607 +               if ((pkp = BN_dup(kp)) == NULL ||
1608 +                   (pkq = BN_dup(kq)) == NULL ||
1609 +                   (pkg = BN_dup(kg)) == NULL ||
1610 +                   (pkpub_key = BN_dup(kpub_key)) == NULL) {
1611 +                       ret = SSH_ERR_ALLOC_FAIL;
1612 +                       goto error1;
1613 +               }
1614 +               if (DSA_set0_pqg(pk->dsa, pkp, pkq, pkg) == 0) {
1615 +                       ret = SSH_ERR_LIBCRYPTO_ERROR;
1616 +                       goto error1;
1617 +               }
1618 +               pkp = pkq = pkg = NULL;
1619 +               if (DSA_set0_key(pk->dsa, pkpub_key, NULL) == 0) {
1620 +                       ret = SSH_ERR_LIBCRYPTO_ERROR;
1621 +error1:
1622 +                       BN_free(pkp); BN_free(pkq); BN_free(pkg);
1623 +                       BN_free(pkpub_key);
1624 +                       goto fail;
1625 +               }
1626 +               pkpub_key = NULL;
1627 +               }
1628                 break;
1629         case KEY_ECDSA_CERT:
1630                 if ((ret = sshkey_cert_copy(k, pk)) != 0)
1631 @@ -2281,11 +2509,17 @@
1632         switch (k->type) {
1633  #ifdef WITH_OPENSSL
1634         case KEY_DSA_CERT:
1635 -               if ((ret = sshbuf_put_bignum2(cert, k->dsa->p)) != 0 ||
1636 -                   (ret = sshbuf_put_bignum2(cert, k->dsa->q)) != 0 ||
1637 -                   (ret = sshbuf_put_bignum2(cert, k->dsa->g)) != 0 ||
1638 -                   (ret = sshbuf_put_bignum2(cert, k->dsa->pub_key)) != 0)
1639 +               {
1640 +               const BIGNUM *p, *q, *g, *pub_key;
1641 +               DSA_get0_pqg(k->dsa, &p, &q, &g);
1642 +               DSA_get0_key(k->dsa, &pub_key, NULL);
1643 +               if ((ret = sshbuf_put_bignum2(cert, p)) != 0 ||
1644 +                   (ret = sshbuf_put_bignum2(cert, q)) != 0 ||
1645 +                   (ret = sshbuf_put_bignum2(cert, g)) != 0 ||
1646 +                   (ret = sshbuf_put_bignum2(cert, pub_key)) != 0) {
1647                         goto out;
1648 +               }
1649 +               }
1650                 break;
1651  # ifdef OPENSSL_HAS_ECC
1652         case KEY_ECDSA_CERT:
1653 @@ -2298,9 +2532,15 @@
1654                 break;
1655  # endif /* OPENSSL_HAS_ECC */
1656         case KEY_RSA_CERT:
1657 -               if ((ret = sshbuf_put_bignum2(cert, k->rsa->e)) != 0 ||
1658 -                   (ret = sshbuf_put_bignum2(cert, k->rsa->n)) != 0)
1659 +               {
1660 +               const BIGNUM *e, *n;
1661 +               RSA_get0_key(k->rsa, &n, &e, NULL);
1662 +               if (n == NULL || e == NULL ||
1663 +                   (ret = sshbuf_put_bignum2(cert, e)) != 0 ||
1664 +                   (ret = sshbuf_put_bignum2(cert, n)) != 0) {
1665                         goto out;
1666 +               }
1667 +               }
1668                 break;
1669  #endif /* WITH_OPENSSL */
1670         case KEY_ED25519_CERT:
1671 @@ -2474,42 +2714,67 @@
1672         switch (key->type) {
1673  #ifdef WITH_OPENSSL
1674         case KEY_RSA:
1675 -               if ((r = sshbuf_put_bignum2(b, key->rsa->n)) != 0 ||
1676 -                   (r = sshbuf_put_bignum2(b, key->rsa->e)) != 0 ||
1677 -                   (r = sshbuf_put_bignum2(b, key->rsa->d)) != 0 ||
1678 -                   (r = sshbuf_put_bignum2(b, key->rsa->iqmp)) != 0 ||
1679 -                   (r = sshbuf_put_bignum2(b, key->rsa->p)) != 0 ||
1680 -                   (r = sshbuf_put_bignum2(b, key->rsa->q)) != 0)
1681 +               {
1682 +               const BIGNUM *n, *e, *d, *iqmp, *p, *q;
1683 +               RSA_get0_key(key->rsa, &n, &e, &d);
1684 +               RSA_get0_crt_params(key->rsa, NULL, NULL, &iqmp);
1685 +               RSA_get0_factors(key->rsa, &p, &q);
1686 +               if ((r = sshbuf_put_bignum2(b, n)) != 0 ||
1687 +                   (r = sshbuf_put_bignum2(b, e)) != 0 ||
1688 +                   (r = sshbuf_put_bignum2(b, d)) != 0 ||
1689 +                   (r = sshbuf_put_bignum2(b, iqmp)) != 0 ||
1690 +                   (r = sshbuf_put_bignum2(b, p)) != 0 ||
1691 +                   (r = sshbuf_put_bignum2(b, q)) != 0) {
1692                         goto out;
1693 +               }
1694 +               }
1695                 break;
1696         case KEY_RSA_CERT:
1697                 if (key->cert == NULL || sshbuf_len(key->cert->certblob) == 0) {
1698                         r = SSH_ERR_INVALID_ARGUMENT;
1699                         goto out;
1700                 }
1701 +               {
1702 +               const BIGNUM *d, *iqmp, *p, *q;
1703 +               RSA_get0_key(key->rsa, NULL, NULL, &d);
1704 +               RSA_get0_crt_params(key->rsa, NULL, NULL, &iqmp);
1705 +               RSA_get0_factors(key->rsa, &p, &q);
1706                 if ((r = sshbuf_put_stringb(b, key->cert->certblob)) != 0 ||
1707 -                   (r = sshbuf_put_bignum2(b, key->rsa->d)) != 0 ||
1708 -                   (r = sshbuf_put_bignum2(b, key->rsa->iqmp)) != 0 ||
1709 -                   (r = sshbuf_put_bignum2(b, key->rsa->p)) != 0 ||
1710 -                   (r = sshbuf_put_bignum2(b, key->rsa->q)) != 0)
1711 +                   (r = sshbuf_put_bignum2(b, d)) != 0 ||
1712 +                   (r = sshbuf_put_bignum2(b, iqmp)) != 0 ||
1713 +                   (r = sshbuf_put_bignum2(b, p)) != 0 ||
1714 +                   (r = sshbuf_put_bignum2(b, q)) != 0) {
1715                         goto out;
1716 +               }
1717 +               }
1718                 break;
1719         case KEY_DSA:
1720 -               if ((r = sshbuf_put_bignum2(b, key->dsa->p)) != 0 ||
1721 -                   (r = sshbuf_put_bignum2(b, key->dsa->q)) != 0 ||
1722 -                   (r = sshbuf_put_bignum2(b, key->dsa->g)) != 0 ||
1723 -                   (r = sshbuf_put_bignum2(b, key->dsa->pub_key)) != 0 ||
1724 -                   (r = sshbuf_put_bignum2(b, key->dsa->priv_key)) != 0)
1725 +               {
1726 +               const BIGNUM *p, *q, *g, *pub_key, *priv_key;
1727 +               DSA_get0_pqg(key->dsa, &p, &q, &g);
1728 +               DSA_get0_key(key->dsa, &pub_key, &priv_key);
1729 +               if ((r = sshbuf_put_bignum2(b, p)) != 0 ||
1730 +                   (r = sshbuf_put_bignum2(b, q)) != 0 ||
1731 +                   (r = sshbuf_put_bignum2(b, g)) != 0 ||
1732 +                   (r = sshbuf_put_bignum2(b, pub_key)) != 0 ||
1733 +                   (r = sshbuf_put_bignum2(b, priv_key)) != 0) {
1734                         goto out;
1735 +               }
1736 +               }
1737                 break;
1738         case KEY_DSA_CERT:
1739                 if (key->cert == NULL || sshbuf_len(key->cert->certblob) == 0) {
1740                         r = SSH_ERR_INVALID_ARGUMENT;
1741                         goto out;
1742                 }
1743 +               {
1744 +               const BIGNUM *priv_key;
1745 +               DSA_get0_key(key->dsa, NULL, &priv_key);
1746                 if ((r = sshbuf_put_stringb(b, key->cert->certblob)) != 0 ||
1747 -                   (r = sshbuf_put_bignum2(b, key->dsa->priv_key)) != 0)
1748 +                   (r = sshbuf_put_bignum2(b, priv_key)) != 0) {
1749                         goto out;
1750 +               }
1751 +               }
1752                 break;
1753  # ifdef OPENSSL_HAS_ECC
1754         case KEY_ECDSA:
1755 @@ -2585,18 +2850,61 @@
1756                         r = SSH_ERR_ALLOC_FAIL;
1757                         goto out;
1758                 }
1759 -               if ((r = sshbuf_get_bignum2(buf, k->dsa->p)) != 0 ||
1760 -                   (r = sshbuf_get_bignum2(buf, k->dsa->q)) != 0 ||
1761 -                   (r = sshbuf_get_bignum2(buf, k->dsa->g)) != 0 ||
1762 -                   (r = sshbuf_get_bignum2(buf, k->dsa->pub_key)) != 0 ||
1763 -                   (r = sshbuf_get_bignum2(buf, k->dsa->priv_key)) != 0)
1764 +               {
1765 +               BIGNUM *p=NULL, *q=NULL, *g=NULL, *pub_key=NULL, *priv_key=NULL;
1766 +               if ((p = BN_new()) == NULL ||
1767 +                   (q = BN_new()) == NULL ||
1768 +                   (g = BN_new()) == NULL ||
1769 +                   (pub_key = BN_new()) == NULL ||
1770 +                   (priv_key = BN_new()) == NULL) {
1771 +                       r = SSH_ERR_ALLOC_FAIL;
1772 +                       goto error1;
1773 +               }
1774 +               if (p == NULL || q == NULL || g == NULL ||
1775 +                   pub_key == NULL || priv_key == NULL ||
1776 +                   (r = sshbuf_get_bignum2(buf, p)) != 0 ||
1777 +                   (r = sshbuf_get_bignum2(buf, q)) != 0 ||
1778 +                   (r = sshbuf_get_bignum2(buf, g)) != 0 ||
1779 +                   (r = sshbuf_get_bignum2(buf, pub_key)) != 0 ||
1780 +                   (r = sshbuf_get_bignum2(buf, priv_key)) != 0) {
1781 +                       goto error1;
1782 +               }
1783 +               if (DSA_set0_pqg(k->dsa, p, q, g) == 0) {
1784 +                       r = SSH_ERR_LIBCRYPTO_ERROR;
1785 +                       goto error1;
1786 +               }
1787 +               p = q = g = NULL;
1788 +               if (DSA_set0_key(k->dsa, pub_key, priv_key) == 0) {
1789 +                       r = SSH_ERR_LIBCRYPTO_ERROR;
1790 +error1:
1791 +                       BN_free(p); BN_free(q); BN_free(g);
1792 +                       BN_free(pub_key); BN_free(priv_key);
1793                         goto out;
1794 +               }
1795 +               pub_key = priv_key = NULL;
1796 +               }
1797                 break;
1798         case KEY_DSA_CERT:
1799 -               if ((r = sshkey_froms(buf, &k)) != 0 ||
1800 +               {
1801 +               BIGNUM *priv_key=NULL;
1802 +               if ((priv_key = BN_new()) == NULL) {
1803 +                       r = SSH_ERR_ALLOC_FAIL;
1804 +                       goto out;
1805 +               }
1806 +               if (priv_key == NULL ||
1807 +                   (r = sshkey_froms(buf, &k)) != 0 ||
1808                     (r = sshkey_add_private(k)) != 0 ||
1809 -                   (r = sshbuf_get_bignum2(buf, k->dsa->priv_key)) != 0)
1810 +                   (r = sshbuf_get_bignum2(buf, priv_key)) != 0) {
1811 +                       BN_free(priv_key);
1812 +                       goto out;
1813 +               }
1814 +               if (DSA_set0_key(k->dsa, NULL, priv_key) == 0) {
1815 +                       r = SSH_ERR_LIBCRYPTO_ERROR;
1816 +                       BN_free(priv_key);
1817                         goto out;
1818 +               }
1819 +               priv_key = NULL;
1820 +               }
1821                 break;
1822  # ifdef OPENSSL_HAS_ECC
1823         case KEY_ECDSA:
1824 @@ -2655,29 +2963,104 @@
1825                         r = SSH_ERR_ALLOC_FAIL;
1826                         goto out;
1827                 }
1828 -               if ((r = sshbuf_get_bignum2(buf, k->rsa->n)) != 0 ||
1829 -                   (r = sshbuf_get_bignum2(buf, k->rsa->e)) != 0 ||
1830 -                   (r = sshbuf_get_bignum2(buf, k->rsa->d)) != 0 ||
1831 -                   (r = sshbuf_get_bignum2(buf, k->rsa->iqmp)) != 0 ||
1832 -                   (r = sshbuf_get_bignum2(buf, k->rsa->p)) != 0 ||
1833 -                   (r = sshbuf_get_bignum2(buf, k->rsa->q)) != 0 ||
1834 -                   (r = ssh_rsa_generate_additional_parameters(k)) != 0)
1835 +               {
1836 +               BIGNUM *n=NULL, *e=NULL, *d=NULL, *iqmp=NULL, *p=NULL, *q=NULL;
1837 +               BIGNUM *dmp1=NULL, *dmq1=NULL; /* dummy for RSA_set0_crt_params */
1838 +               if ((n = BN_new()) == NULL ||
1839 +                   (e = BN_new()) == NULL ||
1840 +                   (d = BN_new()) == NULL ||
1841 +                   (iqmp = BN_new()) == NULL ||
1842 +                   (p = BN_new()) == NULL ||
1843 +                   (q = BN_new()) == NULL ||
1844 +                   (dmp1 = BN_new()) == NULL ||
1845 +                   (dmq1 = BN_new()) == NULL) {
1846 +                       r = SSH_ERR_ALLOC_FAIL;
1847 +                       goto error2;
1848 +               }
1849 +               BN_clear(dmp1); BN_clear(dmq1);
1850 +               if ((r = sshbuf_get_bignum2(buf, n)) != 0 ||
1851 +                   (r = sshbuf_get_bignum2(buf, e)) != 0 ||
1852 +                   (r = sshbuf_get_bignum2(buf, d)) != 0 ||
1853 +                   (r = sshbuf_get_bignum2(buf, iqmp)) != 0 ||
1854 +                   (r = sshbuf_get_bignum2(buf, p)) != 0 ||
1855 +                   (r = sshbuf_get_bignum2(buf, q)) != 0) {
1856 +                       goto error2;
1857 +               }
1858 +               if (RSA_set0_key(k->rsa, n, e, d) == 0) {
1859 +                       r = SSH_ERR_LIBCRYPTO_ERROR;
1860 +                       goto error2;
1861 +               }
1862 +               n = e = d = NULL;
1863 +               /* dmp1,dmpq1 should be non NULL to set iqmp value */
1864 +               if (RSA_set0_crt_params(k->rsa, dmp1, dmq1, iqmp) == 0) {
1865 +                       r = SSH_ERR_LIBCRYPTO_ERROR;
1866 +                       goto error2;
1867 +               }
1868 +               dmp1 = dmq1 = iqmp = NULL;
1869 +               if (RSA_set0_factors(k->rsa, p, q) == 0) {
1870 +                       r = SSH_ERR_LIBCRYPTO_ERROR;
1871 + error2:
1872 +                       BN_free(n); BN_free(e); BN_free(d);
1873 +                       BN_free(iqmp);
1874 +                       BN_free(p); BN_free(q);
1875 +                       BN_free(dmp1); BN_free(dmq1);
1876 +                       goto out;
1877 +               }
1878 +               p = q = NULL;
1879 +               if ((r = ssh_rsa_generate_additional_parameters(k)) != 0) {
1880                         goto out;
1881 -               if (BN_num_bits(k->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) {
1882 +               }
1883 +               }
1884 +               if (RSA_bits(k->rsa) < SSH_RSA_MINIMUM_MODULUS_SIZE) {
1885                         r = SSH_ERR_KEY_LENGTH;
1886                         goto out;
1887                 }
1888                 break;
1889         case KEY_RSA_CERT:
1890 +               {
1891 +               BIGNUM *d=NULL, *iqmp=NULL, *p=NULL, *q=NULL;
1892 +               BIGNUM *dmp1=NULL, *dmq1=NULL; /* dummy for RSA_set0_crt_params */
1893 +               if ((d = BN_new()) == NULL ||
1894 +                   (iqmp = BN_new()) == NULL ||
1895 +                   (p = BN_new()) == NULL ||
1896 +                   (q = BN_new()) == NULL ||
1897 +                   (dmp1 = BN_new()) == NULL ||
1898 +                   (dmq1 = BN_new()) == NULL) {
1899 +                       r = SSH_ERR_ALLOC_FAIL;
1900 +                       goto error3;
1901 +               }
1902 +               BN_clear(dmp1); BN_clear(dmq1);
1903                 if ((r = sshkey_froms(buf, &k)) != 0 ||
1904                     (r = sshkey_add_private(k)) != 0 ||
1905 -                   (r = sshbuf_get_bignum2(buf, k->rsa->d)) != 0 ||
1906 -                   (r = sshbuf_get_bignum2(buf, k->rsa->iqmp)) != 0 ||
1907 -                   (r = sshbuf_get_bignum2(buf, k->rsa->p)) != 0 ||
1908 -                   (r = sshbuf_get_bignum2(buf, k->rsa->q)) != 0 ||
1909 -                   (r = ssh_rsa_generate_additional_parameters(k)) != 0)
1910 +                   (r = sshbuf_get_bignum2(buf, d)) != 0 ||
1911 +                   (r = sshbuf_get_bignum2(buf, iqmp)) != 0 ||
1912 +                   (r = sshbuf_get_bignum2(buf, p)) != 0 ||
1913 +                   (r = sshbuf_get_bignum2(buf, q)) != 0) {
1914 +                       goto error3;
1915 +               }
1916 +               if (RSA_set0_key(k->rsa, NULL, NULL, d) == 0) {
1917 +                       r = SSH_ERR_LIBCRYPTO_ERROR;
1918 +                       goto error3;
1919 +               }
1920 +               /* dmp1,dmpq1 should be non NULL to set value */
1921 +               if (RSA_set0_crt_params(k->rsa, dmp1, dmq1, iqmp) == 0) {
1922 +                       r = SSH_ERR_LIBCRYPTO_ERROR;
1923 +                       goto error3;
1924 +               }
1925 +               dmp1 = dmq1 = iqmp = NULL;
1926 +               if (RSA_set0_factors(k->rsa, p, q) == 0) {
1927 +                       r = SSH_ERR_LIBCRYPTO_ERROR;
1928 + error3:
1929 +                       BN_free(d); BN_free(iqmp);
1930 +                       BN_free(p); BN_free(q);
1931 +                       BN_free(dmp1); BN_free(dmq1);
1932                         goto out;
1933 -               if (BN_num_bits(k->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) {
1934 +               }
1935 +               p = q = NULL;
1936 +               if ((r = ssh_rsa_generate_additional_parameters(k)) != 0)
1937 +                       goto out;
1938 +               }
1939 +               if (RSA_bits(k->rsa) < SSH_RSA_MINIMUM_MODULUS_SIZE) {
1940                         r = SSH_ERR_KEY_LENGTH;
1941                         goto out;
1942                 }
1943 @@ -3395,7 +3778,6 @@
1944                 switch (pem_reason) {
1945                 case EVP_R_BAD_DECRYPT:
1946                         return SSH_ERR_KEY_WRONG_PASSPHRASE;
1947 -               case EVP_R_BN_DECODE_ERROR:
1948                 case EVP_R_DECODE_ERROR:
1949  #ifdef EVP_R_PRIVATE_KEY_DECODE_ERROR
1950                 case EVP_R_PRIVATE_KEY_DECODE_ERROR:
1951 @@ -3460,7 +3842,7 @@
1952                 r = convert_libcrypto_error();
1953                 goto out;
1954         }
1955 -       if (pk->type == EVP_PKEY_RSA &&
1956 +       if (EVP_PKEY_id(pk) == EVP_PKEY_RSA &&
1957             (type == KEY_UNSPEC || type == KEY_RSA)) {
1958                 if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) {
1959                         r = SSH_ERR_ALLOC_FAIL;
1960 @@ -3475,11 +3857,11 @@
1961                         r = SSH_ERR_LIBCRYPTO_ERROR;
1962                         goto out;
1963                 }
1964 -               if (BN_num_bits(prv->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) {
1965 +               if (RSA_bits(prv->rsa) < SSH_RSA_MINIMUM_MODULUS_SIZE) {
1966                         r = SSH_ERR_KEY_LENGTH;
1967                         goto out;
1968                 }
1969 -       } else if (pk->type == EVP_PKEY_DSA &&
1970 +       } else if (EVP_PKEY_id(pk) == EVP_PKEY_DSA &&
1971             (type == KEY_UNSPEC || type == KEY_DSA)) {
1972                 if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) {
1973                         r = SSH_ERR_ALLOC_FAIL;
1974 @@ -3491,7 +3873,7 @@
1975                 DSA_print_fp(stderr, prv->dsa, 8);
1976  #endif
1977  #ifdef OPENSSL_HAS_ECC
1978 -       } else if (pk->type == EVP_PKEY_EC &&
1979 +       } else if (EVP_PKEY_id(pk) == EVP_PKEY_EC &&
1980             (type == KEY_UNSPEC || type == KEY_ECDSA)) {
1981                 if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) {
1982                         r = SSH_ERR_ALLOC_FAIL;