summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordjm@openbsd.org <djm@openbsd.org>2018-09-13 02:08:33 +0000
committerDamien Miller <djm@mindrot.org>2018-09-13 12:12:33 +1000
commit482d23bcacdd3664f21cc82a5135f66fc598275f (patch)
tree362f697a94da0a765d1dabcfbf33370b2a4df121
parentd70d061828730a56636ab6f1f24fe4a8ccefcfc1 (diff)
upstream: hold our collective noses and use the openssl-1.1.x API in
OpenSSH; feedback and ok tb@ jsing@ markus@ OpenBSD-Commit-ID: cacbcac87ce5da0d3ca7ef1b38a6f7fb349e4417
-rw-r--r--auth2.c4
-rw-r--r--cipher.c16
-rw-r--r--cipher.h4
-rw-r--r--dh.c60
-rw-r--r--dh.h2
-rw-r--r--digest-openssl.c26
-rw-r--r--kexdhc.c15
-rw-r--r--kexdhs.c11
-rw-r--r--kexgexc.c18
-rw-r--r--kexgexs.c21
-rw-r--r--monitor.c6
-rw-r--r--ssh-dss.c26
-rw-r--r--ssh-ecdsa.c23
-rw-r--r--ssh-keygen.c61
-rw-r--r--ssh-pkcs11-client.c12
-rw-r--r--ssh-pkcs11.c55
-rw-r--r--ssh-rsa.c47
-rw-r--r--sshd.c6
-rw-r--r--sshkey.c637
-rw-r--r--sshkey.h7
20 files changed, 619 insertions, 438 deletions
diff --git a/auth2.c b/auth2.c
index ab8795895..4d19957a6 100644
--- a/auth2.c
+++ b/auth2.c
@@ -706,7 +706,7 @@ auth2_record_key(Authctxt *authctxt, int authenticated,
706 struct sshkey **tmp, *dup; 706 struct sshkey **tmp, *dup;
707 int r; 707 int r;
708 708
709 if ((r = sshkey_demote(key, &dup)) != 0) 709 if ((r = sshkey_from_private(key, &dup)) != 0)
710 fatal("%s: copy key: %s", __func__, ssh_err(r)); 710 fatal("%s: copy key: %s", __func__, ssh_err(r));
711 sshkey_free(authctxt->auth_method_key); 711 sshkey_free(authctxt->auth_method_key);
712 authctxt->auth_method_key = dup; 712 authctxt->auth_method_key = dup;
@@ -715,7 +715,7 @@ auth2_record_key(Authctxt *authctxt, int authenticated,
715 return; 715 return;
716 716
717 /* If authenticated, make sure we don't accept this key again */ 717 /* If authenticated, make sure we don't accept this key again */
718 if ((r = sshkey_demote(key, &dup)) != 0) 718 if ((r = sshkey_from_private(key, &dup)) != 0)
719 fatal("%s: copy key: %s", __func__, ssh_err(r)); 719 fatal("%s: copy key: %s", __func__, ssh_err(r));
720 if (authctxt->nprev_keys >= INT_MAX || 720 if (authctxt->nprev_keys >= INT_MAX ||
721 (tmp = recallocarray(authctxt->prev_keys, authctxt->nprev_keys, 721 (tmp = recallocarray(authctxt->prev_keys, authctxt->nprev_keys,
diff --git a/cipher.c b/cipher.c
index a72682a82..df43826e0 100644
--- a/cipher.c
+++ b/cipher.c
@@ -446,7 +446,7 @@ cipher_get_keyiv_len(const struct sshcipher_ctx *cc)
446} 446}
447 447
448int 448int
449cipher_get_keyiv(struct sshcipher_ctx *cc, u_char *iv, u_int len) 449cipher_get_keyiv(struct sshcipher_ctx *cc, u_char *iv, size_t len)
450{ 450{
451#ifdef WITH_OPENSSL 451#ifdef WITH_OPENSSL
452 const struct sshcipher *c = cc->cipher; 452 const struct sshcipher *c = cc->cipher;
@@ -473,7 +473,7 @@ cipher_get_keyiv(struct sshcipher_ctx *cc, u_char *iv, u_int len)
473 return 0; 473 return 0;
474 else if (evplen < 0) 474 else if (evplen < 0)
475 return SSH_ERR_LIBCRYPTO_ERROR; 475 return SSH_ERR_LIBCRYPTO_ERROR;
476 if ((u_int)evplen != len) 476 if ((size_t)evplen != len)
477 return SSH_ERR_INVALID_ARGUMENT; 477 return SSH_ERR_INVALID_ARGUMENT;
478#ifndef OPENSSL_HAVE_EVPCTR 478#ifndef OPENSSL_HAVE_EVPCTR
479 if (c->evptype == evp_aes_128_ctr) 479 if (c->evptype == evp_aes_128_ctr)
@@ -484,14 +484,14 @@ cipher_get_keyiv(struct sshcipher_ctx *cc, u_char *iv, u_int len)
484 if (!EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_IV_GEN, 484 if (!EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_IV_GEN,
485 len, iv)) 485 len, iv))
486 return SSH_ERR_LIBCRYPTO_ERROR; 486 return SSH_ERR_LIBCRYPTO_ERROR;
487 } else 487 } else if (!EVP_CIPHER_CTX_get_iv(cc->evp, iv, len))
488 memcpy(iv, cc->evp->iv, len); 488 return SSH_ERR_LIBCRYPTO_ERROR;
489#endif 489#endif
490 return 0; 490 return 0;
491} 491}
492 492
493int 493int
494cipher_set_keyiv(struct sshcipher_ctx *cc, const u_char *iv) 494cipher_set_keyiv(struct sshcipher_ctx *cc, const u_char *iv, size_t len)
495{ 495{
496#ifdef WITH_OPENSSL 496#ifdef WITH_OPENSSL
497 const struct sshcipher *c = cc->cipher; 497 const struct sshcipher *c = cc->cipher;
@@ -507,6 +507,8 @@ cipher_set_keyiv(struct sshcipher_ctx *cc, const u_char *iv)
507 evplen = EVP_CIPHER_CTX_iv_length(cc->evp); 507 evplen = EVP_CIPHER_CTX_iv_length(cc->evp);
508 if (evplen <= 0) 508 if (evplen <= 0)
509 return SSH_ERR_LIBCRYPTO_ERROR; 509 return SSH_ERR_LIBCRYPTO_ERROR;
510 if ((size_t)evplen != len)
511 return SSH_ERR_INVALID_ARGUMENT;
510#ifndef OPENSSL_HAVE_EVPCTR 512#ifndef OPENSSL_HAVE_EVPCTR
511 /* XXX iv arg is const, but ssh_aes_ctr_iv isn't */ 513 /* XXX iv arg is const, but ssh_aes_ctr_iv isn't */
512 if (c->evptype == evp_aes_128_ctr) 514 if (c->evptype == evp_aes_128_ctr)
@@ -518,8 +520,8 @@ cipher_set_keyiv(struct sshcipher_ctx *cc, const u_char *iv)
518 if (!EVP_CIPHER_CTX_ctrl(cc->evp, 520 if (!EVP_CIPHER_CTX_ctrl(cc->evp,
519 EVP_CTRL_GCM_SET_IV_FIXED, -1, (void *)iv)) 521 EVP_CTRL_GCM_SET_IV_FIXED, -1, (void *)iv))
520 return SSH_ERR_LIBCRYPTO_ERROR; 522 return SSH_ERR_LIBCRYPTO_ERROR;
521 } else 523 } else if (!EVP_CIPHER_CTX_set_iv(cc->evp, iv, evplen))
522 memcpy(cc->evp->iv, iv, evplen); 524 return SSH_ERR_LIBCRYPTO_ERROR;
523#endif 525#endif
524 return 0; 526 return 0;
525} 527}
diff --git a/cipher.h b/cipher.h
index dc7ecf113..dc1571d2e 100644
--- a/cipher.h
+++ b/cipher.h
@@ -68,8 +68,8 @@ u_int cipher_is_cbc(const struct sshcipher *);
68 68
69u_int cipher_ctx_is_plaintext(struct sshcipher_ctx *); 69u_int cipher_ctx_is_plaintext(struct sshcipher_ctx *);
70 70
71int cipher_get_keyiv(struct sshcipher_ctx *, u_char *, u_int); 71int cipher_get_keyiv(struct sshcipher_ctx *, u_char *, size_t);
72int cipher_set_keyiv(struct sshcipher_ctx *, const u_char *); 72int cipher_set_keyiv(struct sshcipher_ctx *, const u_char *, size_t);
73int cipher_get_keyiv_len(const struct sshcipher_ctx *); 73int cipher_get_keyiv_len(const struct sshcipher_ctx *);
74 74
75#endif /* CIPHER_H */ 75#endif /* CIPHER_H */
diff --git a/dh.c b/dh.c
index ac8d5a0ae..d0d4527b1 100644
--- a/dh.c
+++ b/dh.c
@@ -216,14 +216,17 @@ choose_dh(int min, int wantbits, int max)
216/* diffie-hellman-groupN-sha1 */ 216/* diffie-hellman-groupN-sha1 */
217 217
218int 218int
219dh_pub_is_valid(DH *dh, BIGNUM *dh_pub) 219dh_pub_is_valid(const DH *dh, const BIGNUM *dh_pub)
220{ 220{
221 int i; 221 int i;
222 int n = BN_num_bits(dh_pub); 222 int n = BN_num_bits(dh_pub);
223 int bits_set = 0; 223 int bits_set = 0;
224 BIGNUM *tmp; 224 BIGNUM *tmp;
225 const BIGNUM *dh_p;
225 226
226 if (dh_pub->neg) { 227 DH_get0_pqg(dh, &dh_p, NULL, NULL);
228
229 if (BN_is_negative(dh_pub)) {
227 logit("invalid public DH value: negative"); 230 logit("invalid public DH value: negative");
228 return 0; 231 return 0;
229 } 232 }
@@ -236,7 +239,7 @@ dh_pub_is_valid(DH *dh, BIGNUM *dh_pub)
236 error("%s: BN_new failed", __func__); 239 error("%s: BN_new failed", __func__);
237 return 0; 240 return 0;
238 } 241 }
239 if (!BN_sub(tmp, dh->p, BN_value_one()) || 242 if (!BN_sub(tmp, dh_p, BN_value_one()) ||
240 BN_cmp(dh_pub, tmp) != -1) { /* pub_exp > p-2 */ 243 BN_cmp(dh_pub, tmp) != -1) { /* pub_exp > p-2 */
241 BN_clear_free(tmp); 244 BN_clear_free(tmp);
242 logit("invalid public DH value: >= p-1"); 245 logit("invalid public DH value: >= p-1");
@@ -247,14 +250,14 @@ dh_pub_is_valid(DH *dh, BIGNUM *dh_pub)
247 for (i = 0; i <= n; i++) 250 for (i = 0; i <= n; i++)
248 if (BN_is_bit_set(dh_pub, i)) 251 if (BN_is_bit_set(dh_pub, i))
249 bits_set++; 252 bits_set++;
250 debug2("bits set: %d/%d", bits_set, BN_num_bits(dh->p)); 253 debug2("bits set: %d/%d", bits_set, BN_num_bits(dh_p));
251 254
252 /* 255 /*
253 * if g==2 and bits_set==1 then computing log_g(dh_pub) is trivial 256 * if g==2 and bits_set==1 then computing log_g(dh_pub) is trivial
254 */ 257 */
255 if (bits_set < 4) { 258 if (bits_set < 4) {
256 logit("invalid public DH value (%d/%d)", 259 logit("invalid public DH value (%d/%d)",
257 bits_set, BN_num_bits(dh->p)); 260 bits_set, BN_num_bits(dh_p));
258 return 0; 261 return 0;
259 } 262 }
260 return 1; 263 return 1;
@@ -264,9 +267,12 @@ int
264dh_gen_key(DH *dh, int need) 267dh_gen_key(DH *dh, int need)
265{ 268{
266 int pbits; 269 int pbits;
270 const BIGNUM *dh_p, *pub_key;
271
272 DH_get0_pqg(dh, &dh_p, NULL, NULL);
267 273
268 if (need < 0 || dh->p == NULL || 274 if (need < 0 || dh_p == NULL ||
269 (pbits = BN_num_bits(dh->p)) <= 0 || 275 (pbits = BN_num_bits(dh_p)) <= 0 ||
270 need > INT_MAX / 2 || 2 * need > pbits) 276 need > INT_MAX / 2 || 2 * need > pbits)
271 return SSH_ERR_INVALID_ARGUMENT; 277 return SSH_ERR_INVALID_ARGUMENT;
272 if (need < 256) 278 if (need < 256)
@@ -275,13 +281,14 @@ dh_gen_key(DH *dh, int need)
275 * Pollard Rho, Big step/Little Step attacks are O(sqrt(n)), 281 * Pollard Rho, Big step/Little Step attacks are O(sqrt(n)),
276 * so double requested need here. 282 * so double requested need here.
277 */ 283 */
278 dh->length = MINIMUM(need * 2, pbits - 1); 284 if (!DH_set_length(dh, MINIMUM(need * 2, pbits - 1)))
279 if (DH_generate_key(dh) == 0 ||
280 !dh_pub_is_valid(dh, dh->pub_key)) {
281 BN_clear_free(dh->priv_key);
282 dh->priv_key = NULL;
283 return SSH_ERR_LIBCRYPTO_ERROR; 285 return SSH_ERR_LIBCRYPTO_ERROR;
284 } 286
287 if (DH_generate_key(dh) == 0)
288 return SSH_ERR_LIBCRYPTO_ERROR;
289 DH_get0_key(dh, &pub_key, NULL);
290 if (!dh_pub_is_valid(dh, pub_key))
291 return SSH_ERR_INVALID_FORMAT;
285 return 0; 292 return 0;
286} 293}
287 294
@@ -289,22 +296,27 @@ DH *
289dh_new_group_asc(const char *gen, const char *modulus) 296dh_new_group_asc(const char *gen, const char *modulus)
290{ 297{
291 DH *dh; 298 DH *dh;
299 BIGNUM *dh_p = NULL, *dh_g = NULL;
292 300
293 if ((dh = DH_new()) == NULL) 301 if ((dh = DH_new()) == NULL)
294 return NULL; 302 return NULL;
295 if (BN_hex2bn(&dh->p, modulus) == 0 || 303 if (BN_hex2bn(&dh_p, modulus) == 0 ||
296 BN_hex2bn(&dh->g, gen) == 0) { 304 BN_hex2bn(&dh_g, gen) == 0)
297 DH_free(dh); 305 goto fail;
298 return NULL; 306 if (!DH_set0_pqg(dh, dh_p, NULL, dh_g))
299 } 307 goto fail;
300 return (dh); 308 return dh;
309 fail:
310 DH_free(dh);
311 BN_clear_free(dh_p);
312 BN_clear_free(dh_g);
313 return NULL;
301} 314}
302 315
303/* 316/*
304 * This just returns the group, we still need to generate the exchange 317 * This just returns the group, we still need to generate the exchange
305 * value. 318 * value.
306 */ 319 */
307
308DH * 320DH *
309dh_new_group(BIGNUM *gen, BIGNUM *modulus) 321dh_new_group(BIGNUM *gen, BIGNUM *modulus)
310{ 322{
@@ -312,10 +324,12 @@ dh_new_group(BIGNUM *gen, BIGNUM *modulus)
312 324
313 if ((dh = DH_new()) == NULL) 325 if ((dh = DH_new()) == NULL)
314 return NULL; 326 return NULL;
315 dh->p = modulus; 327 if (!DH_set0_pqg(dh, modulus, NULL, gen)) {
316 dh->g = gen; 328 DH_free(dh);
329 return NULL;
330 }
317 331
318 return (dh); 332 return dh;
319} 333}
320 334
321/* rfc2409 "Second Oakley Group" (1024 bits) */ 335/* rfc2409 "Second Oakley Group" (1024 bits) */
diff --git a/dh.h b/dh.h
index bcd485cf9..344b29e35 100644
--- a/dh.h
+++ b/dh.h
@@ -42,7 +42,7 @@ DH *dh_new_group18(void);
42DH *dh_new_group_fallback(int); 42DH *dh_new_group_fallback(int);
43 43
44int dh_gen_key(DH *, int); 44int dh_gen_key(DH *, int);
45int dh_pub_is_valid(DH *, BIGNUM *); 45int dh_pub_is_valid(const DH *, const BIGNUM *);
46 46
47u_int dh_estimate(int); 47u_int dh_estimate(int);
48 48
diff --git a/digest-openssl.c b/digest-openssl.c
index 277099929..da7ed72bc 100644
--- a/digest-openssl.c
+++ b/digest-openssl.c
@@ -43,7 +43,7 @@
43 43
44struct ssh_digest_ctx { 44struct ssh_digest_ctx {
45 int alg; 45 int alg;
46 EVP_MD_CTX mdctx; 46 EVP_MD_CTX *mdctx;
47}; 47};
48 48
49struct ssh_digest { 49struct ssh_digest {
@@ -106,7 +106,7 @@ ssh_digest_bytes(int alg)
106size_t 106size_t
107ssh_digest_blocksize(struct ssh_digest_ctx *ctx) 107ssh_digest_blocksize(struct ssh_digest_ctx *ctx)
108{ 108{
109 return EVP_MD_CTX_block_size(&ctx->mdctx); 109 return EVP_MD_CTX_block_size(ctx->mdctx);
110} 110}
111 111
112struct ssh_digest_ctx * 112struct ssh_digest_ctx *
@@ -118,11 +118,14 @@ ssh_digest_start(int alg)
118 if (digest == NULL || ((ret = calloc(1, sizeof(*ret))) == NULL)) 118 if (digest == NULL || ((ret = calloc(1, sizeof(*ret))) == NULL))
119 return NULL; 119 return NULL;
120 ret->alg = alg; 120 ret->alg = alg;
121 EVP_MD_CTX_init(&ret->mdctx); 121 if ((ret->mdctx = EVP_MD_CTX_new()) == NULL) {
122 if (EVP_DigestInit_ex(&ret->mdctx, digest->mdfunc(), NULL) != 1) {
123 free(ret); 122 free(ret);
124 return NULL; 123 return NULL;
125 } 124 }
125 if (EVP_DigestInit_ex(ret->mdctx, digest->mdfunc(), NULL) != 1) {
126 ssh_digest_free(ret);
127 return NULL;
128 }
126 return ret; 129 return ret;
127} 130}
128 131
@@ -132,7 +135,7 @@ ssh_digest_copy_state(struct ssh_digest_ctx *from, struct ssh_digest_ctx *to)
132 if (from->alg != to->alg) 135 if (from->alg != to->alg)
133 return SSH_ERR_INVALID_ARGUMENT; 136 return SSH_ERR_INVALID_ARGUMENT;
134 /* we have bcopy-style order while openssl has memcpy-style */ 137 /* we have bcopy-style order while openssl has memcpy-style */
135 if (!EVP_MD_CTX_copy_ex(&to->mdctx, &from->mdctx)) 138 if (!EVP_MD_CTX_copy_ex(to->mdctx, from->mdctx))
136 return SSH_ERR_LIBCRYPTO_ERROR; 139 return SSH_ERR_LIBCRYPTO_ERROR;
137 return 0; 140 return 0;
138} 141}
@@ -140,7 +143,7 @@ ssh_digest_copy_state(struct ssh_digest_ctx *from, struct ssh_digest_ctx *to)
140int 143int
141ssh_digest_update(struct ssh_digest_ctx *ctx, const void *m, size_t mlen) 144ssh_digest_update(struct ssh_digest_ctx *ctx, const void *m, size_t mlen)
142{ 145{
143 if (EVP_DigestUpdate(&ctx->mdctx, m, mlen) != 1) 146 if (EVP_DigestUpdate(ctx->mdctx, m, mlen) != 1)
144 return SSH_ERR_LIBCRYPTO_ERROR; 147 return SSH_ERR_LIBCRYPTO_ERROR;
145 return 0; 148 return 0;
146} 149}
@@ -161,7 +164,7 @@ ssh_digest_final(struct ssh_digest_ctx *ctx, u_char *d, size_t dlen)
161 return SSH_ERR_INVALID_ARGUMENT; 164 return SSH_ERR_INVALID_ARGUMENT;
162 if (dlen < digest->digest_len) /* No truncation allowed */ 165 if (dlen < digest->digest_len) /* No truncation allowed */
163 return SSH_ERR_INVALID_ARGUMENT; 166 return SSH_ERR_INVALID_ARGUMENT;
164 if (EVP_DigestFinal_ex(&ctx->mdctx, d, &l) != 1) 167 if (EVP_DigestFinal_ex(ctx->mdctx, d, &l) != 1)
165 return SSH_ERR_LIBCRYPTO_ERROR; 168 return SSH_ERR_LIBCRYPTO_ERROR;
166 if (l != digest->digest_len) /* sanity */ 169 if (l != digest->digest_len) /* sanity */
167 return SSH_ERR_INTERNAL_ERROR; 170 return SSH_ERR_INTERNAL_ERROR;
@@ -171,11 +174,10 @@ ssh_digest_final(struct ssh_digest_ctx *ctx, u_char *d, size_t dlen)
171void 174void
172ssh_digest_free(struct ssh_digest_ctx *ctx) 175ssh_digest_free(struct ssh_digest_ctx *ctx)
173{ 176{
174 if (ctx != NULL) { 177 if (ctx == NULL)
175 EVP_MD_CTX_cleanup(&ctx->mdctx); 178 return;
176 explicit_bzero(ctx, sizeof(*ctx)); 179 EVP_MD_CTX_free(ctx->mdctx);
177 free(ctx); 180 freezero(ctx, sizeof(*ctx));
178 }
179} 181}
180 182
181int 183int
diff --git a/kexdhc.c b/kexdhc.c
index 9a9f1ea78..a8b74247f 100644
--- a/kexdhc.c
+++ b/kexdhc.c
@@ -56,6 +56,7 @@ kexdh_client(struct ssh *ssh)
56{ 56{
57 struct kex *kex = ssh->kex; 57 struct kex *kex = ssh->kex;
58 int r; 58 int r;
59 const BIGNUM *pub_key;
59 60
60 /* generate and send 'e', client DH public key */ 61 /* generate and send 'e', client DH public key */
61 switch (kex->kex_type) { 62 switch (kex->kex_type) {
@@ -81,15 +82,17 @@ kexdh_client(struct ssh *ssh)
81 goto out; 82 goto out;
82 } 83 }
83 debug("sending SSH2_MSG_KEXDH_INIT"); 84 debug("sending SSH2_MSG_KEXDH_INIT");
84 if ((r = dh_gen_key(kex->dh, kex->we_need * 8)) != 0 || 85 if ((r = dh_gen_key(kex->dh, kex->we_need * 8)) != 0)
85 (r = sshpkt_start(ssh, SSH2_MSG_KEXDH_INIT)) != 0 || 86 goto out;
86 (r = sshpkt_put_bignum2(ssh, kex->dh->pub_key)) != 0 || 87 DH_get0_key(kex->dh, &pub_key, NULL);
88 if ((r = sshpkt_start(ssh, SSH2_MSG_KEXDH_INIT)) != 0 ||
89 (r = sshpkt_put_bignum2(ssh, pub_key)) != 0 ||
87 (r = sshpkt_send(ssh)) != 0) 90 (r = sshpkt_send(ssh)) != 0)
88 goto out; 91 goto out;
89#ifdef DEBUG_KEXDH 92#ifdef DEBUG_KEXDH
90 DHparams_print_fp(stderr, kex->dh); 93 DHparams_print_fp(stderr, kex->dh);
91 fprintf(stderr, "pub= "); 94 fprintf(stderr, "pub= ");
92 BN_print_fp(stderr, kex->dh->pub_key); 95 BN_print_fp(stderr, pub_key);
93 fprintf(stderr, "\n"); 96 fprintf(stderr, "\n");
94#endif 97#endif
95 debug("expecting SSH2_MSG_KEXDH_REPLY"); 98 debug("expecting SSH2_MSG_KEXDH_REPLY");
@@ -104,6 +107,7 @@ input_kex_dh(int type, u_int32_t seq, struct ssh *ssh)
104{ 107{
105 struct kex *kex = ssh->kex; 108 struct kex *kex = ssh->kex;
106 BIGNUM *dh_server_pub = NULL, *shared_secret = NULL; 109 BIGNUM *dh_server_pub = NULL, *shared_secret = NULL;
110 const BIGNUM *pub_key;
107 struct sshkey *server_host_key = NULL; 111 struct sshkey *server_host_key = NULL;
108 u_char *kbuf = NULL, *server_host_key_blob = NULL, *signature = NULL; 112 u_char *kbuf = NULL, *server_host_key_blob = NULL, *signature = NULL;
109 u_char hash[SSH_DIGEST_MAX_LENGTH]; 113 u_char hash[SSH_DIGEST_MAX_LENGTH];
@@ -168,6 +172,7 @@ input_kex_dh(int type, u_int32_t seq, struct ssh *ssh)
168#endif 172#endif
169 173
170 /* calc and verify H */ 174 /* calc and verify H */
175 DH_get0_key(kex->dh, &pub_key, NULL);
171 hashlen = sizeof(hash); 176 hashlen = sizeof(hash);
172 if ((r = kex_dh_hash( 177 if ((r = kex_dh_hash(
173 kex->hash_alg, 178 kex->hash_alg,
@@ -176,7 +181,7 @@ input_kex_dh(int type, u_int32_t seq, struct ssh *ssh)
176 sshbuf_ptr(kex->my), sshbuf_len(kex->my), 181 sshbuf_ptr(kex->my), sshbuf_len(kex->my),
177 sshbuf_ptr(kex->peer), sshbuf_len(kex->peer), 182 sshbuf_ptr(kex->peer), sshbuf_len(kex->peer),
178 server_host_key_blob, sbloblen, 183 server_host_key_blob, sbloblen,
179 kex->dh->pub_key, 184 pub_key,
180 dh_server_pub, 185 dh_server_pub,
181 shared_secret, 186 shared_secret,
182 hash, &hashlen)) != 0) 187 hash, &hashlen)) != 0)
diff --git a/kexdhs.c b/kexdhs.c
index 5dfca0a24..8367c6c30 100644
--- a/kexdhs.c
+++ b/kexdhs.c
@@ -95,6 +95,7 @@ input_kex_dh_init(int type, u_int32_t seq, struct ssh *ssh)
95{ 95{
96 struct kex *kex = ssh->kex; 96 struct kex *kex = ssh->kex;
97 BIGNUM *shared_secret = NULL, *dh_client_pub = NULL; 97 BIGNUM *shared_secret = NULL, *dh_client_pub = NULL;
98 const BIGNUM *pub_key;
98 struct sshkey *server_host_public, *server_host_private; 99 struct sshkey *server_host_public, *server_host_private;
99 u_char *kbuf = NULL, *signature = NULL, *server_host_key_blob = NULL; 100 u_char *kbuf = NULL, *signature = NULL, *server_host_key_blob = NULL;
100 u_char hash[SSH_DIGEST_MAX_LENGTH]; 101 u_char hash[SSH_DIGEST_MAX_LENGTH];
@@ -121,6 +122,7 @@ input_kex_dh_init(int type, u_int32_t seq, struct ssh *ssh)
121 r = SSH_ERR_ALLOC_FAIL; 122 r = SSH_ERR_ALLOC_FAIL;
122 goto out; 123 goto out;
123 } 124 }
125 DH_get0_key(kex->dh, &pub_key, NULL);
124 if ((r = sshpkt_get_bignum2(ssh, dh_client_pub)) != 0 || 126 if ((r = sshpkt_get_bignum2(ssh, dh_client_pub)) != 0 ||
125 (r = sshpkt_get_end(ssh)) != 0) 127 (r = sshpkt_get_end(ssh)) != 0)
126 goto out; 128 goto out;
@@ -130,12 +132,9 @@ input_kex_dh_init(int type, u_int32_t seq, struct ssh *ssh)
130 BN_print_fp(stderr, dh_client_pub); 132 BN_print_fp(stderr, dh_client_pub);
131 fprintf(stderr, "\n"); 133 fprintf(stderr, "\n");
132 debug("bits %d", BN_num_bits(dh_client_pub)); 134 debug("bits %d", BN_num_bits(dh_client_pub));
133#endif
134
135#ifdef DEBUG_KEXDH
136 DHparams_print_fp(stderr, kex->dh); 135 DHparams_print_fp(stderr, kex->dh);
137 fprintf(stderr, "pub= "); 136 fprintf(stderr, "pub= ");
138 BN_print_fp(stderr, kex->dh->pub_key); 137 BN_print_fp(stderr, pub_key);
139 fprintf(stderr, "\n"); 138 fprintf(stderr, "\n");
140#endif 139#endif
141 if (!dh_pub_is_valid(kex->dh, dh_client_pub)) { 140 if (!dh_pub_is_valid(kex->dh, dh_client_pub)) {
@@ -171,7 +170,7 @@ input_kex_dh_init(int type, u_int32_t seq, struct ssh *ssh)
171 sshbuf_ptr(kex->my), sshbuf_len(kex->my), 170 sshbuf_ptr(kex->my), sshbuf_len(kex->my),
172 server_host_key_blob, sbloblen, 171 server_host_key_blob, sbloblen,
173 dh_client_pub, 172 dh_client_pub,
174 kex->dh->pub_key, 173 pub_key,
175 shared_secret, 174 shared_secret,
176 hash, &hashlen)) != 0) 175 hash, &hashlen)) != 0)
177 goto out; 176 goto out;
@@ -197,7 +196,7 @@ input_kex_dh_init(int type, u_int32_t seq, struct ssh *ssh)
197 /* send server hostkey, DH pubkey 'f' and signed H */ 196 /* send server hostkey, DH pubkey 'f' and signed H */
198 if ((r = sshpkt_start(ssh, SSH2_MSG_KEXDH_REPLY)) != 0 || 197 if ((r = sshpkt_start(ssh, SSH2_MSG_KEXDH_REPLY)) != 0 ||
199 (r = sshpkt_put_string(ssh, server_host_key_blob, sbloblen)) != 0 || 198 (r = sshpkt_put_string(ssh, server_host_key_blob, sbloblen)) != 0 ||
200 (r = sshpkt_put_bignum2(ssh, kex->dh->pub_key)) != 0 || /* f */ 199 (r = sshpkt_put_bignum2(ssh, pub_key)) != 0 || /* f */
201 (r = sshpkt_put_string(ssh, signature, slen)) != 0 || 200 (r = sshpkt_put_string(ssh, signature, slen)) != 0 ||
202 (r = sshpkt_send(ssh)) != 0) 201 (r = sshpkt_send(ssh)) != 0)
203 goto out; 202 goto out;
diff --git a/kexgexc.c b/kexgexc.c
index 762a9a322..955bc837c 100644
--- a/kexgexc.c
+++ b/kexgexc.c
@@ -93,6 +93,7 @@ input_kex_dh_gex_group(int type, u_int32_t seq, struct ssh *ssh)
93{ 93{
94 struct kex *kex = ssh->kex; 94 struct kex *kex = ssh->kex;
95 BIGNUM *p = NULL, *g = NULL; 95 BIGNUM *p = NULL, *g = NULL;
96 const BIGNUM *pub_key;
96 int r, bits; 97 int r, bits;
97 98
98 debug("got SSH2_MSG_KEX_DH_GEX_GROUP"); 99 debug("got SSH2_MSG_KEX_DH_GEX_GROUP");
@@ -118,16 +119,18 @@ input_kex_dh_gex_group(int type, u_int32_t seq, struct ssh *ssh)
118 p = g = NULL; /* belong to kex->dh now */ 119 p = g = NULL; /* belong to kex->dh now */
119 120
120 /* generate and send 'e', client DH public key */ 121 /* generate and send 'e', client DH public key */
121 if ((r = dh_gen_key(kex->dh, kex->we_need * 8)) != 0 || 122 if ((r = dh_gen_key(kex->dh, kex->we_need * 8)) != 0)
122 (r = sshpkt_start(ssh, SSH2_MSG_KEX_DH_GEX_INIT)) != 0 || 123 goto out;
123 (r = sshpkt_put_bignum2(ssh, kex->dh->pub_key)) != 0 || 124 DH_get0_key(kex->dh, &pub_key, NULL);
125 if ((r = sshpkt_start(ssh, SSH2_MSG_KEX_DH_GEX_INIT)) != 0 ||
126 (r = sshpkt_put_bignum2(ssh, pub_key)) != 0 ||
124 (r = sshpkt_send(ssh)) != 0) 127 (r = sshpkt_send(ssh)) != 0)
125 goto out; 128 goto out;
126 debug("SSH2_MSG_KEX_DH_GEX_INIT sent"); 129 debug("SSH2_MSG_KEX_DH_GEX_INIT sent");
127#ifdef DEBUG_KEXDH 130#ifdef DEBUG_KEXDH
128 DHparams_print_fp(stderr, kex->dh); 131 DHparams_print_fp(stderr, kex->dh);
129 fprintf(stderr, "pub= "); 132 fprintf(stderr, "pub= ");
130 BN_print_fp(stderr, kex->dh->pub_key); 133 BN_print_fp(stderr, pub_key);
131 fprintf(stderr, "\n"); 134 fprintf(stderr, "\n");
132#endif 135#endif
133 ssh_dispatch_set(ssh, SSH2_MSG_KEX_DH_GEX_GROUP, NULL); 136 ssh_dispatch_set(ssh, SSH2_MSG_KEX_DH_GEX_GROUP, NULL);
@@ -144,6 +147,7 @@ input_kex_dh_gex_reply(int type, u_int32_t seq, struct ssh *ssh)
144{ 147{
145 struct kex *kex = ssh->kex; 148 struct kex *kex = ssh->kex;
146 BIGNUM *dh_server_pub = NULL, *shared_secret = NULL; 149 BIGNUM *dh_server_pub = NULL, *shared_secret = NULL;
150 const BIGNUM *pub_key, *dh_p, *dh_g;
147 struct sshkey *server_host_key = NULL; 151 struct sshkey *server_host_key = NULL;
148 u_char *kbuf = NULL, *signature = NULL, *server_host_key_blob = NULL; 152 u_char *kbuf = NULL, *signature = NULL, *server_host_key_blob = NULL;
149 u_char hash[SSH_DIGEST_MAX_LENGTH]; 153 u_char hash[SSH_DIGEST_MAX_LENGTH];
@@ -211,6 +215,8 @@ input_kex_dh_gex_reply(int type, u_int32_t seq, struct ssh *ssh)
211 kex->min = kex->max = -1; 215 kex->min = kex->max = -1;
212 216
213 /* calc and verify H */ 217 /* calc and verify H */
218 DH_get0_key(kex->dh, &pub_key, NULL);
219 DH_get0_pqg(kex->dh, &dh_p, NULL, &dh_g);
214 hashlen = sizeof(hash); 220 hashlen = sizeof(hash);
215 if ((r = kexgex_hash( 221 if ((r = kexgex_hash(
216 kex->hash_alg, 222 kex->hash_alg,
@@ -220,8 +226,8 @@ input_kex_dh_gex_reply(int type, u_int32_t seq, struct ssh *ssh)
220 sshbuf_ptr(kex->peer), sshbuf_len(kex->peer), 226 sshbuf_ptr(kex->peer), sshbuf_len(kex->peer),
221 server_host_key_blob, sbloblen, 227 server_host_key_blob, sbloblen,
222 kex->min, kex->nbits, kex->max, 228 kex->min, kex->nbits, kex->max,
223 kex->dh->p, kex->dh->g, 229 dh_p, dh_g,
224 kex->dh->pub_key, 230 pub_key,
225 dh_server_pub, 231 dh_server_pub,
226 shared_secret, 232 shared_secret,
227 hash, &hashlen)) != 0) 233 hash, &hashlen)) != 0)
diff --git a/kexgexs.c b/kexgexs.c
index f6983fd69..2a4aa7e81 100644
--- a/kexgexs.c
+++ b/kexgexs.c
@@ -72,6 +72,7 @@ input_kex_dh_gex_request(int type, u_int32_t seq, struct ssh *ssh)
72 struct kex *kex = ssh->kex; 72 struct kex *kex = ssh->kex;
73 int r; 73 int r;
74 u_int min = 0, max = 0, nbits = 0; 74 u_int min = 0, max = 0, nbits = 0;
75 const BIGNUM *dh_p, *dh_g;
75 76
76 debug("SSH2_MSG_KEX_DH_GEX_REQUEST received"); 77 debug("SSH2_MSG_KEX_DH_GEX_REQUEST received");
77 if ((r = sshpkt_get_u32(ssh, &min)) != 0 || 78 if ((r = sshpkt_get_u32(ssh, &min)) != 0 ||
@@ -101,9 +102,10 @@ input_kex_dh_gex_request(int type, u_int32_t seq, struct ssh *ssh)
101 goto out; 102 goto out;
102 } 103 }
103 debug("SSH2_MSG_KEX_DH_GEX_GROUP sent"); 104 debug("SSH2_MSG_KEX_DH_GEX_GROUP sent");
105 DH_get0_pqg(kex->dh, &dh_p, NULL, &dh_g);
104 if ((r = sshpkt_start(ssh, SSH2_MSG_KEX_DH_GEX_GROUP)) != 0 || 106 if ((r = sshpkt_start(ssh, SSH2_MSG_KEX_DH_GEX_GROUP)) != 0 ||
105 (r = sshpkt_put_bignum2(ssh, kex->dh->p)) != 0 || 107 (r = sshpkt_put_bignum2(ssh, dh_p)) != 0 ||
106 (r = sshpkt_put_bignum2(ssh, kex->dh->g)) != 0 || 108 (r = sshpkt_put_bignum2(ssh, dh_g)) != 0 ||
107 (r = sshpkt_send(ssh)) != 0) 109 (r = sshpkt_send(ssh)) != 0)
108 goto out; 110 goto out;
109 111
@@ -123,6 +125,7 @@ input_kex_dh_gex_init(int type, u_int32_t seq, struct ssh *ssh)
123{ 125{
124 struct kex *kex = ssh->kex; 126 struct kex *kex = ssh->kex;
125 BIGNUM *shared_secret = NULL, *dh_client_pub = NULL; 127 BIGNUM *shared_secret = NULL, *dh_client_pub = NULL;
128 const BIGNUM *pub_key, *dh_p, *dh_g;
126 struct sshkey *server_host_public, *server_host_private; 129 struct sshkey *server_host_public, *server_host_private;
127 u_char *kbuf = NULL, *signature = NULL, *server_host_key_blob = NULL; 130 u_char *kbuf = NULL, *signature = NULL, *server_host_key_blob = NULL;
128 u_char hash[SSH_DIGEST_MAX_LENGTH]; 131 u_char hash[SSH_DIGEST_MAX_LENGTH];
@@ -153,17 +156,17 @@ input_kex_dh_gex_init(int type, u_int32_t seq, struct ssh *ssh)
153 (r = sshpkt_get_end(ssh)) != 0) 156 (r = sshpkt_get_end(ssh)) != 0)
154 goto out; 157 goto out;
155 158
159 DH_get0_key(kex->dh, &pub_key, NULL);
160 DH_get0_pqg(kex->dh, &dh_p, NULL, &dh_g);
161
156#ifdef DEBUG_KEXDH 162#ifdef DEBUG_KEXDH
157 fprintf(stderr, "dh_client_pub= "); 163 fprintf(stderr, "dh_client_pub= ");
158 BN_print_fp(stderr, dh_client_pub); 164 BN_print_fp(stderr, dh_client_pub);
159 fprintf(stderr, "\n"); 165 fprintf(stderr, "\n");
160 debug("bits %d", BN_num_bits(dh_client_pub)); 166 debug("bits %d", BN_num_bits(dh_client_pub));
161#endif
162
163#ifdef DEBUG_KEXDH
164 DHparams_print_fp(stderr, kex->dh); 167 DHparams_print_fp(stderr, kex->dh);
165 fprintf(stderr, "pub= "); 168 fprintf(stderr, "pub= ");
166 BN_print_fp(stderr, kex->dh->pub_key); 169 BN_print_fp(stderr, pub_key);
167 fprintf(stderr, "\n"); 170 fprintf(stderr, "\n");
168#endif 171#endif
169 if (!dh_pub_is_valid(kex->dh, dh_client_pub)) { 172 if (!dh_pub_is_valid(kex->dh, dh_client_pub)) {
@@ -199,9 +202,9 @@ input_kex_dh_gex_init(int type, u_int32_t seq, struct ssh *ssh)
199 sshbuf_ptr(kex->my), sshbuf_len(kex->my), 202 sshbuf_ptr(kex->my), sshbuf_len(kex->my),
200 server_host_key_blob, sbloblen, 203 server_host_key_blob, sbloblen,
201 kex->min, kex->nbits, kex->max, 204 kex->min, kex->nbits, kex->max,
202 kex->dh->p, kex->dh->g, 205 dh_p, dh_g,
203 dh_client_pub, 206 dh_client_pub,
204 kex->dh->pub_key, 207 pub_key,
205 shared_secret, 208 shared_secret,
206 hash, &hashlen)) != 0) 209 hash, &hashlen)) != 0)
207 goto out; 210 goto out;
@@ -227,7 +230,7 @@ input_kex_dh_gex_init(int type, u_int32_t seq, struct ssh *ssh)
227 /* send server hostkey, DH pubkey 'f' and signed H */ 230 /* send server hostkey, DH pubkey 'f' and signed H */
228 if ((r = sshpkt_start(ssh, SSH2_MSG_KEX_DH_GEX_REPLY)) != 0 || 231 if ((r = sshpkt_start(ssh, SSH2_MSG_KEX_DH_GEX_REPLY)) != 0 ||
229 (r = sshpkt_put_string(ssh, server_host_key_blob, sbloblen)) != 0 || 232 (r = sshpkt_put_string(ssh, server_host_key_blob, sbloblen)) != 0 ||
230 (r = sshpkt_put_bignum2(ssh, kex->dh->pub_key)) != 0 || /* f */ 233 (r = sshpkt_put_bignum2(ssh, pub_key)) != 0 || /* f */
231 (r = sshpkt_put_string(ssh, signature, slen)) != 0 || 234 (r = sshpkt_put_string(ssh, signature, slen)) != 0 ||
232 (r = sshpkt_send(ssh)) != 0) 235 (r = sshpkt_send(ssh)) != 0)
233 goto out; 236 goto out;
diff --git a/monitor.c b/monitor.c
index d4b4b0471..b30813b4d 100644
--- a/monitor.c
+++ b/monitor.c
@@ -566,6 +566,7 @@ int
566mm_answer_moduli(int sock, struct sshbuf *m) 566mm_answer_moduli(int sock, struct sshbuf *m)
567{ 567{
568 DH *dh; 568 DH *dh;
569 const BIGNUM *dh_p, *dh_g;
569 int r; 570 int r;
570 u_int min, want, max; 571 u_int min, want, max;
571 572
@@ -590,9 +591,10 @@ mm_answer_moduli(int sock, struct sshbuf *m)
590 return (0); 591 return (0);
591 } else { 592 } else {
592 /* Send first bignum */ 593 /* Send first bignum */
594 DH_get0_pqg(dh, &dh_p, NULL, &dh_g);
593 if ((r = sshbuf_put_u8(m, 1)) != 0 || 595 if ((r = sshbuf_put_u8(m, 1)) != 0 ||
594 (r = sshbuf_put_bignum2(m, dh->p)) != 0 || 596 (r = sshbuf_put_bignum2(m, dh_p)) != 0 ||
595 (r = sshbuf_put_bignum2(m, dh->g)) != 0) 597 (r = sshbuf_put_bignum2(m, dh_g)) != 0)
596 fatal("%s: buffer error: %s", __func__, ssh_err(r)); 598 fatal("%s: buffer error: %s", __func__, ssh_err(r));
597 599
598 DH_free(dh); 600 DH_free(dh);
diff --git a/ssh-dss.c b/ssh-dss.c
index 9f832ee2b..631b15712 100644
--- a/ssh-dss.c
+++ b/ssh-dss.c
@@ -51,6 +51,7 @@ ssh_dss_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
51 const u_char *data, size_t datalen, u_int compat) 51 const u_char *data, size_t datalen, u_int compat)
52{ 52{
53 DSA_SIG *sig = NULL; 53 DSA_SIG *sig = NULL;
54 const BIGNUM *sig_r, *sig_s;
54 u_char digest[SSH_DIGEST_MAX_LENGTH], sigblob[SIGBLOB_LEN]; 55 u_char digest[SSH_DIGEST_MAX_LENGTH], sigblob[SIGBLOB_LEN];
55 size_t rlen, slen, len, dlen = ssh_digest_bytes(SSH_DIGEST_SHA1); 56 size_t rlen, slen, len, dlen = ssh_digest_bytes(SSH_DIGEST_SHA1);
56 struct sshbuf *b = NULL; 57 struct sshbuf *b = NULL;
@@ -76,15 +77,16 @@ ssh_dss_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
76 goto out; 77 goto out;
77 } 78 }
78 79
79 rlen = BN_num_bytes(sig->r); 80 DSA_SIG_get0(sig, &sig_r, &sig_s);
80 slen = BN_num_bytes(sig->s); 81 rlen = BN_num_bytes(sig_r);
82 slen = BN_num_bytes(sig_s);
81 if (rlen > INTBLOB_LEN || slen > INTBLOB_LEN) { 83 if (rlen > INTBLOB_LEN || slen > INTBLOB_LEN) {
82 ret = SSH_ERR_INTERNAL_ERROR; 84 ret = SSH_ERR_INTERNAL_ERROR;
83 goto out; 85 goto out;
84 } 86 }
85 explicit_bzero(sigblob, SIGBLOB_LEN); 87 explicit_bzero(sigblob, SIGBLOB_LEN);
86 BN_bn2bin(sig->r, sigblob + SIGBLOB_LEN - INTBLOB_LEN - rlen); 88 BN_bn2bin(sig_r, sigblob + SIGBLOB_LEN - INTBLOB_LEN - rlen);
87 BN_bn2bin(sig->s, sigblob + SIGBLOB_LEN - slen); 89 BN_bn2bin(sig_s, sigblob + SIGBLOB_LEN - slen);
88 90
89 if ((b = sshbuf_new()) == NULL) { 91 if ((b = sshbuf_new()) == NULL) {
90 ret = SSH_ERR_ALLOC_FAIL; 92 ret = SSH_ERR_ALLOC_FAIL;
@@ -118,6 +120,7 @@ ssh_dss_verify(const struct sshkey *key,
118 const u_char *data, size_t datalen, u_int compat) 120 const u_char *data, size_t datalen, u_int compat)
119{ 121{
120 DSA_SIG *sig = NULL; 122 DSA_SIG *sig = NULL;
123 BIGNUM *sig_r = NULL, *sig_s = NULL;
121 u_char digest[SSH_DIGEST_MAX_LENGTH], *sigblob = NULL; 124 u_char digest[SSH_DIGEST_MAX_LENGTH], *sigblob = NULL;
122 size_t len, dlen = ssh_digest_bytes(SSH_DIGEST_SHA1); 125 size_t len, dlen = ssh_digest_bytes(SSH_DIGEST_SHA1);
123 int ret = SSH_ERR_INTERNAL_ERROR; 126 int ret = SSH_ERR_INTERNAL_ERROR;
@@ -155,16 +158,21 @@ ssh_dss_verify(const struct sshkey *key,
155 158
156 /* parse signature */ 159 /* parse signature */
157 if ((sig = DSA_SIG_new()) == NULL || 160 if ((sig = DSA_SIG_new()) == NULL ||
158 (sig->r = BN_new()) == NULL || 161 (sig_r = BN_new()) == NULL ||
159 (sig->s = BN_new()) == NULL) { 162 (sig_s = BN_new()) == NULL) {
160 ret = SSH_ERR_ALLOC_FAIL; 163 ret = SSH_ERR_ALLOC_FAIL;
161 goto out; 164 goto out;
162 } 165 }
163 if ((BN_bin2bn(sigblob, INTBLOB_LEN, sig->r) == NULL) || 166 if ((BN_bin2bn(sigblob, INTBLOB_LEN, sig_r) == NULL) ||
164 (BN_bin2bn(sigblob+ INTBLOB_LEN, INTBLOB_LEN, sig->s) == NULL)) { 167 (BN_bin2bn(sigblob + INTBLOB_LEN, INTBLOB_LEN, sig_s) == NULL)) {
165 ret = SSH_ERR_LIBCRYPTO_ERROR; 168 ret = SSH_ERR_LIBCRYPTO_ERROR;
166 goto out; 169 goto out;
167 } 170 }
171 if (!DSA_SIG_set0(sig, sig_r, sig_s)) {
172 ret = SSH_ERR_LIBCRYPTO_ERROR;
173 goto out;
174 }
175 sig_r = sig_s = NULL; /* transferred */
168 176
169 /* sha1 the data */ 177 /* sha1 the data */
170 if ((ret = ssh_digest_memory(SSH_DIGEST_SHA1, data, datalen, 178 if ((ret = ssh_digest_memory(SSH_DIGEST_SHA1, data, datalen,
@@ -186,6 +194,8 @@ ssh_dss_verify(const struct sshkey *key,
186 out: 194 out:
187 explicit_bzero(digest, sizeof(digest)); 195 explicit_bzero(digest, sizeof(digest));
188 DSA_SIG_free(sig); 196 DSA_SIG_free(sig);
197 BN_clear_free(sig_r);
198 BN_clear_free(sig_s);
189 sshbuf_free(b); 199 sshbuf_free(b);
190 free(ktype); 200 free(ktype);
191 if (sigblob != NULL) { 201 if (sigblob != NULL) {
diff --git a/ssh-ecdsa.c b/ssh-ecdsa.c
index 3d3b78d7b..9e92af044 100644
--- a/ssh-ecdsa.c
+++ b/ssh-ecdsa.c
@@ -49,6 +49,7 @@ ssh_ecdsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
49 const u_char *data, size_t datalen, u_int compat) 49 const u_char *data, size_t datalen, u_int compat)
50{ 50{
51 ECDSA_SIG *sig = NULL; 51 ECDSA_SIG *sig = NULL;
52 const BIGNUM *sig_r, *sig_s;
52 int hash_alg; 53 int hash_alg;
53 u_char digest[SSH_DIGEST_MAX_LENGTH]; 54 u_char digest[SSH_DIGEST_MAX_LENGTH];
54 size_t len, dlen; 55 size_t len, dlen;
@@ -80,8 +81,9 @@ ssh_ecdsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
80 ret = SSH_ERR_ALLOC_FAIL; 81 ret = SSH_ERR_ALLOC_FAIL;
81 goto out; 82 goto out;
82 } 83 }
83 if ((ret = sshbuf_put_bignum2(bb, sig->r)) != 0 || 84 ECDSA_SIG_get0(sig, &sig_r, &sig_s);
84 (ret = sshbuf_put_bignum2(bb, sig->s)) != 0) 85 if ((ret = sshbuf_put_bignum2(bb, sig_r)) != 0 ||
86 (ret = sshbuf_put_bignum2(bb, sig_s)) != 0)
85 goto out; 87 goto out;
86 if ((ret = sshbuf_put_cstring(b, sshkey_ssh_name_plain(key))) != 0 || 88 if ((ret = sshbuf_put_cstring(b, sshkey_ssh_name_plain(key))) != 0 ||
87 (ret = sshbuf_put_stringb(b, bb)) != 0) 89 (ret = sshbuf_put_stringb(b, bb)) != 0)
@@ -112,6 +114,7 @@ ssh_ecdsa_verify(const struct sshkey *key,
112 const u_char *data, size_t datalen, u_int compat) 114 const u_char *data, size_t datalen, u_int compat)
113{ 115{
114 ECDSA_SIG *sig = NULL; 116 ECDSA_SIG *sig = NULL;
117 BIGNUM *sig_r = NULL, *sig_s = NULL;
115 int hash_alg; 118 int hash_alg;
116 u_char digest[SSH_DIGEST_MAX_LENGTH]; 119 u_char digest[SSH_DIGEST_MAX_LENGTH];
117 size_t dlen; 120 size_t dlen;
@@ -146,15 +149,23 @@ ssh_ecdsa_verify(const struct sshkey *key,
146 } 149 }
147 150
148 /* parse signature */ 151 /* parse signature */
149 if ((sig = ECDSA_SIG_new()) == NULL) { 152 if ((sig = ECDSA_SIG_new()) == NULL ||
153 (sig_r = BN_new()) == NULL ||
154 (sig_s = BN_new()) == NULL) {
150 ret = SSH_ERR_ALLOC_FAIL; 155 ret = SSH_ERR_ALLOC_FAIL;
151 goto out; 156 goto out;
152 } 157 }
153 if (sshbuf_get_bignum2(sigbuf, sig->r) != 0 || 158 if (sshbuf_get_bignum2(sigbuf, sig_r) != 0 ||
154 sshbuf_get_bignum2(sigbuf, sig->s) != 0) { 159 sshbuf_get_bignum2(sigbuf, sig_s) != 0) {
155 ret = SSH_ERR_INVALID_FORMAT; 160 ret = SSH_ERR_INVALID_FORMAT;
156 goto out; 161 goto out;
157 } 162 }
163 if (!ECDSA_SIG_set0(sig, sig_r, sig_s)) {
164 ret = SSH_ERR_LIBCRYPTO_ERROR;
165 goto out;
166 }
167 sig_r = sig_s = NULL; /* transferred */
168
158 if (sshbuf_len(sigbuf) != 0) { 169 if (sshbuf_len(sigbuf) != 0) {
159 ret = SSH_ERR_UNEXPECTED_TRAILING_DATA; 170 ret = SSH_ERR_UNEXPECTED_TRAILING_DATA;
160 goto out; 171 goto out;
@@ -180,6 +191,8 @@ ssh_ecdsa_verify(const struct sshkey *key,
180 sshbuf_free(sigbuf); 191 sshbuf_free(sigbuf);
181 sshbuf_free(b); 192 sshbuf_free(b);
182 ECDSA_SIG_free(sig); 193 ECDSA_SIG_free(sig);
194 BN_clear_free(sig_r);
195 BN_clear_free(sig_s);
183 free(ktype); 196 free(ktype);
184 return ret; 197 return ret;
185} 198}
diff --git a/ssh-keygen.c b/ssh-keygen.c
index 748ce37d7..a70fd1f88 100644
--- a/ssh-keygen.c
+++ b/ssh-keygen.c
@@ -450,7 +450,10 @@ do_convert_private_ssh2_from_blob(u_char *blob, u_int blen)
450 u_int magic, i1, i2, i3, i4; 450 u_int magic, i1, i2, i3, i4;
451 size_t slen; 451 size_t slen;
452 u_long e; 452 u_long e;
453 453 BIGNUM *dsa_p = NULL, *dsa_q = NULL, *dsa_g = NULL;
454 BIGNUM *dsa_pub_key = NULL, *dsa_priv_key = NULL;
455 BIGNUM *rsa_n = NULL, *rsa_e = NULL, *rsa_d = NULL;
456 BIGNUM *rsa_p = NULL, *rsa_q = NULL, *rsa_iqmp = NULL;
454 if ((b = sshbuf_from(blob, blen)) == NULL) 457 if ((b = sshbuf_from(blob, blen)) == NULL)
455 fatal("%s: sshbuf_from failed", __func__); 458 fatal("%s: sshbuf_from failed", __func__);
456 if ((r = sshbuf_get_u32(b, &magic)) != 0) 459 if ((r = sshbuf_get_u32(b, &magic)) != 0)
@@ -494,11 +497,23 @@ do_convert_private_ssh2_from_blob(u_char *blob, u_int blen)
494 497
495 switch (key->type) { 498 switch (key->type) {
496 case KEY_DSA: 499 case KEY_DSA:
497 buffer_get_bignum_bits(b, key->dsa->p); 500 if ((dsa_p = BN_new()) == NULL ||
498 buffer_get_bignum_bits(b, key->dsa->g); 501 (dsa_q = BN_new()) == NULL ||
499 buffer_get_bignum_bits(b, key->dsa->q); 502 (dsa_g = BN_new()) == NULL ||
500 buffer_get_bignum_bits(b, key->dsa->pub_key); 503 (dsa_pub_key = BN_new()) == NULL ||
501 buffer_get_bignum_bits(b, key->dsa->priv_key); 504 (dsa_priv_key = BN_new()) == NULL)
505 fatal("%s: BN_new", __func__);
506 buffer_get_bignum_bits(b, dsa_p);
507 buffer_get_bignum_bits(b, dsa_g);
508 buffer_get_bignum_bits(b, dsa_q);
509 buffer_get_bignum_bits(b, dsa_pub_key);
510 buffer_get_bignum_bits(b, dsa_priv_key);
511 if (!DSA_set0_pqg(key->dsa, dsa_p, dsa_q, dsa_g))
512 fatal("%s: DSA_set0_pqg failed", __func__);
513 dsa_p = dsa_q = dsa_g = NULL; /* transferred */
514 if (!DSA_set0_key(key->dsa, dsa_pub_key, dsa_priv_key))
515 fatal("%s: DSA_set0_key failed", __func__);
516 dsa_pub_key = dsa_priv_key = NULL; /* transferred */
502 break; 517 break;
503 case KEY_RSA: 518 case KEY_RSA:
504 if ((r = sshbuf_get_u8(b, &e1)) != 0 || 519 if ((r = sshbuf_get_u8(b, &e1)) != 0 ||
@@ -515,18 +530,34 @@ do_convert_private_ssh2_from_blob(u_char *blob, u_int blen)
515 e += e3; 530 e += e3;
516 debug("e %lx", e); 531 debug("e %lx", e);
517 } 532 }
518 if (!BN_set_word(key->rsa->e, e)) { 533 if ((rsa_e = BN_new()) == NULL)
534 fatal("%s: BN_new", __func__);
535 if (!BN_set_word(rsa_e, e)) {
536 BN_clear_free(rsa_e);
519 sshbuf_free(b); 537 sshbuf_free(b);
520 sshkey_free(key); 538 sshkey_free(key);
521 return NULL; 539 return NULL;
522 } 540 }
523 buffer_get_bignum_bits(b, key->rsa->d); 541 if ((rsa_n = BN_new()) == NULL ||
524 buffer_get_bignum_bits(b, key->rsa->n); 542 (rsa_d = BN_new()) == NULL ||
525 buffer_get_bignum_bits(b, key->rsa->iqmp); 543 (rsa_p = BN_new()) == NULL ||
526 buffer_get_bignum_bits(b, key->rsa->q); 544 (rsa_q = BN_new()) == NULL ||
527 buffer_get_bignum_bits(b, key->rsa->p); 545 (rsa_iqmp = BN_new()) == NULL)
528 if ((r = ssh_rsa_generate_additional_parameters(key)) != 0) 546 fatal("%s: BN_new", __func__);
547 buffer_get_bignum_bits(b, rsa_d);
548 buffer_get_bignum_bits(b, rsa_n);
549 buffer_get_bignum_bits(b, rsa_iqmp);
550 buffer_get_bignum_bits(b, rsa_q);
551 buffer_get_bignum_bits(b, rsa_p);
552 if (!RSA_set0_key(key->rsa, rsa_n, rsa_e, rsa_d))
553 fatal("%s: RSA_set0_key failed", __func__);
554 rsa_n = rsa_e = rsa_d = NULL; /* transferred */
555 if (!RSA_set0_factors(key->rsa, rsa_p, rsa_q))
556 fatal("%s: RSA_set0_factors failed", __func__);
557 rsa_p = rsa_q = NULL; /* transferred */
558 if ((r = ssh_rsa_complete_crt_parameters(key, rsa_iqmp)) != 0)
529 fatal("generate RSA parameters failed: %s", ssh_err(r)); 559 fatal("generate RSA parameters failed: %s", ssh_err(r));
560 BN_clear_free(rsa_iqmp);
530 break; 561 break;
531 } 562 }
532 rlen = sshbuf_len(b); 563 rlen = sshbuf_len(b);
@@ -634,7 +665,7 @@ do_convert_from_pkcs8(struct sshkey **k, int *private)
634 identity_file); 665 identity_file);
635 } 666 }
636 fclose(fp); 667 fclose(fp);
637 switch (EVP_PKEY_type(pubkey->type)) { 668 switch (EVP_PKEY_base_id(pubkey)) {
638 case EVP_PKEY_RSA: 669 case EVP_PKEY_RSA:
639 if ((*k = sshkey_new(KEY_UNSPEC)) == NULL) 670 if ((*k = sshkey_new(KEY_UNSPEC)) == NULL)
640 fatal("sshkey_new failed"); 671 fatal("sshkey_new failed");
@@ -658,7 +689,7 @@ do_convert_from_pkcs8(struct sshkey **k, int *private)
658#endif 689#endif
659 default: 690 default:
660 fatal("%s: unsupported pubkey type %d", __func__, 691 fatal("%s: unsupported pubkey type %d", __func__,
661 EVP_PKEY_type(pubkey->type)); 692 EVP_PKEY_base_id(pubkey));
662 } 693 }
663 EVP_PKEY_free(pubkey); 694 EVP_PKEY_free(pubkey);
664 return; 695 return;
diff --git a/ssh-pkcs11-client.c b/ssh-pkcs11-client.c
index 028b272cb..bcc18c6bc 100644
--- a/ssh-pkcs11-client.c
+++ b/ssh-pkcs11-client.c
@@ -156,12 +156,14 @@ pkcs11_rsa_private_encrypt(int flen, const u_char *from, u_char *to, RSA *rsa,
156static int 156static int
157wrap_key(RSA *rsa) 157wrap_key(RSA *rsa)
158{ 158{
159 static RSA_METHOD helper_rsa; 159 static RSA_METHOD *helper_rsa;
160 160
161 memcpy(&helper_rsa, RSA_get_default_method(), sizeof(helper_rsa)); 161 if ((helper_rsa = RSA_meth_dup(RSA_get_default_method())) == NULL)
162 helper_rsa.name = "ssh-pkcs11-helper"; 162 fatal("%s: RSA_meth_dup failed", __func__);
163 helper_rsa.rsa_priv_enc = pkcs11_rsa_private_encrypt; 163 if (!RSA_meth_set1_name(helper_rsa, "ssh-pkcs11-helper") ||
164 RSA_set_method(rsa, &helper_rsa); 164 !RSA_meth_set_priv_enc(helper_rsa, pkcs11_rsa_private_encrypt))
165 fatal("%s: failed to prepare method", __func__);
166 RSA_set_method(rsa, helper_rsa);
165 return (0); 167 return (0);
166} 168}
167 169
diff --git a/ssh-pkcs11.c b/ssh-pkcs11.c
index 65a7b5897..c35f9415f 100644
--- a/ssh-pkcs11.c
+++ b/ssh-pkcs11.c
@@ -67,7 +67,7 @@ struct pkcs11_key {
67 struct pkcs11_provider *provider; 67 struct pkcs11_provider *provider;
68 CK_ULONG slotidx; 68 CK_ULONG slotidx;
69 int (*orig_finish)(RSA *rsa); 69 int (*orig_finish)(RSA *rsa);
70 RSA_METHOD rsa_method; 70 RSA_METHOD *rsa_method;
71 char *keyid; 71 char *keyid;
72 int keyid_len; 72 int keyid_len;
73}; 73};
@@ -182,6 +182,7 @@ pkcs11_rsa_finish(RSA *rsa)
182 rv = k11->orig_finish(rsa); 182 rv = k11->orig_finish(rsa);
183 if (k11->provider) 183 if (k11->provider)
184 pkcs11_provider_unref(k11->provider); 184 pkcs11_provider_unref(k11->provider);
185 RSA_meth_free(k11->rsa_method);
185 free(k11->keyid); 186 free(k11->keyid);
186 free(k11); 187 free(k11);
187 } 188 }
@@ -326,13 +327,18 @@ pkcs11_rsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx,
326 k11->keyid = xmalloc(k11->keyid_len); 327 k11->keyid = xmalloc(k11->keyid_len);
327 memcpy(k11->keyid, keyid_attrib->pValue, k11->keyid_len); 328 memcpy(k11->keyid, keyid_attrib->pValue, k11->keyid_len);
328 } 329 }
329 k11->orig_finish = def->finish; 330 k11->rsa_method = RSA_meth_dup(def);
330 memcpy(&k11->rsa_method, def, sizeof(k11->rsa_method)); 331 if (k11->rsa_method == NULL)
331 k11->rsa_method.name = "pkcs11"; 332 fatal("%s: RSA_meth_dup failed", __func__);
332 k11->rsa_method.rsa_priv_enc = pkcs11_rsa_private_encrypt; 333 k11->orig_finish = RSA_meth_get_finish(def);
333 k11->rsa_method.rsa_priv_dec = pkcs11_rsa_private_decrypt; 334 if (!RSA_meth_set1_name(k11->rsa_method, "pkcs11") ||
334 k11->rsa_method.finish = pkcs11_rsa_finish; 335 !RSA_meth_set_priv_enc(k11->rsa_method,
335 RSA_set_method(rsa, &k11->rsa_method); 336 pkcs11_rsa_private_encrypt) ||
337 !RSA_meth_set_priv_dec(k11->rsa_method,
338 pkcs11_rsa_private_decrypt) ||
339 !RSA_meth_set_finish(k11->rsa_method, pkcs11_rsa_finish))
340 fatal("%s: setup pkcs11 method failed", __func__);
341 RSA_set_method(rsa, k11->rsa_method);
336 RSA_set_app_data(rsa, k11); 342 RSA_set_app_data(rsa, k11);
337 return (0); 343 return (0);
338} 344}
@@ -445,6 +451,15 @@ pkcs11_key_included(struct sshkey ***keysp, int *nkeys, struct sshkey *key)
445} 451}
446 452
447static int 453static int
454have_rsa_key(const RSA *rsa)
455{
456 const BIGNUM *rsa_n, *rsa_e;
457
458 RSA_get0_key(rsa, &rsa_n, &rsa_e, NULL);
459 return rsa_n != NULL && rsa_e != NULL;
460}
461
462static int
448pkcs11_fetch_keys_filter(struct pkcs11_provider *p, CK_ULONG slotidx, 463pkcs11_fetch_keys_filter(struct pkcs11_provider *p, CK_ULONG slotidx,
449 CK_ATTRIBUTE filter[], CK_ATTRIBUTE attribs[3], 464 CK_ATTRIBUTE filter[], CK_ATTRIBUTE attribs[3],
450 struct sshkey ***keysp, int *nkeys) 465 struct sshkey ***keysp, int *nkeys)
@@ -512,10 +527,20 @@ pkcs11_fetch_keys_filter(struct pkcs11_provider *p, CK_ULONG slotidx,
512 if ((rsa = RSA_new()) == NULL) { 527 if ((rsa = RSA_new()) == NULL) {
513 error("RSA_new failed"); 528 error("RSA_new failed");
514 } else { 529 } else {
515 rsa->n = BN_bin2bn(attribs[1].pValue, 530 BIGNUM *rsa_n, *rsa_e;
531
532 rsa_n = BN_bin2bn(attribs[1].pValue,
516 attribs[1].ulValueLen, NULL); 533 attribs[1].ulValueLen, NULL);
517 rsa->e = BN_bin2bn(attribs[2].pValue, 534 rsa_e = BN_bin2bn(attribs[2].pValue,
518 attribs[2].ulValueLen, NULL); 535 attribs[2].ulValueLen, NULL);
536 if (rsa_n != NULL && rsa_e != NULL) {
537 if (!RSA_set0_key(rsa,
538 rsa_n, rsa_e, NULL))
539 fatal("%s: set key", __func__);
540 rsa_n = rsa_e = NULL; /* transferred */
541 }
542 BN_free(rsa_n);
543 BN_free(rsa_e);
519 } 544 }
520 } else { 545 } else {
521 cp = attribs[2].pValue; 546 cp = attribs[2].pValue;
@@ -525,16 +550,16 @@ pkcs11_fetch_keys_filter(struct pkcs11_provider *p, CK_ULONG slotidx,
525 == NULL) { 550 == NULL) {
526 error("d2i_X509 failed"); 551 error("d2i_X509 failed");
527 } else if ((evp = X509_get_pubkey(x509)) == NULL || 552 } else if ((evp = X509_get_pubkey(x509)) == NULL ||
528 evp->type != EVP_PKEY_RSA || 553 EVP_PKEY_base_id(evp) != EVP_PKEY_RSA ||
529 evp->pkey.rsa == NULL) { 554 EVP_PKEY_get0_RSA(evp) == NULL) {
530 debug("X509_get_pubkey failed or no rsa"); 555 debug("X509_get_pubkey failed or no rsa");
531 } else if ((rsa = RSAPublicKey_dup(evp->pkey.rsa)) 556 } else if ((rsa = RSAPublicKey_dup(
532 == NULL) { 557 EVP_PKEY_get0_RSA(evp))) == NULL) {
533 error("RSAPublicKey_dup"); 558 error("RSAPublicKey_dup");
534 } 559 }
535 X509_free(x509); 560 X509_free(x509);
536 } 561 }
537 if (rsa && rsa->n && rsa->e && 562 if (rsa && have_rsa_key(rsa) &&
538 pkcs11_rsa_wrap(p, slotidx, &attribs[0], rsa) == 0) { 563 pkcs11_rsa_wrap(p, slotidx, &attribs[0], rsa) == 0) {
539 if ((key = sshkey_new(KEY_UNSPEC)) == NULL) 564 if ((key = sshkey_new(KEY_UNSPEC)) == NULL)
540 fatal("sshkey_new failed"); 565 fatal("sshkey_new failed");
diff --git a/ssh-rsa.c b/ssh-rsa.c
index 1756315b9..2788f3340 100644
--- a/ssh-rsa.c
+++ b/ssh-rsa.c
@@ -104,38 +104,55 @@ rsa_hash_alg_nid(int type)
104} 104}
105 105
106int 106int
107ssh_rsa_generate_additional_parameters(struct sshkey *key) 107ssh_rsa_complete_crt_parameters(struct sshkey *key, const BIGNUM *iqmp)
108{ 108{
109 BIGNUM *aux = NULL; 109 const BIGNUM *rsa_p, *rsa_q, *rsa_d;
110 BIGNUM *aux = NULL, *d_consttime = NULL;
111 BIGNUM *rsa_dmq1 = NULL, *rsa_dmp1 = NULL, *rsa_iqmp = NULL;
110 BN_CTX *ctx = NULL; 112 BN_CTX *ctx = NULL;
111 BIGNUM d;
112 int r; 113 int r;
113 114
114 if (key == NULL || key->rsa == NULL || 115 if (key == NULL || key->rsa == NULL ||
115 sshkey_type_plain(key->type) != KEY_RSA) 116 sshkey_type_plain(key->type) != KEY_RSA)
116 return SSH_ERR_INVALID_ARGUMENT; 117 return SSH_ERR_INVALID_ARGUMENT;
117 118
119 RSA_get0_key(key->rsa, NULL, NULL, &rsa_d);
120 RSA_get0_factors(key->rsa, &rsa_p, &rsa_q);
121
118 if ((ctx = BN_CTX_new()) == NULL) 122 if ((ctx = BN_CTX_new()) == NULL)
119 return SSH_ERR_ALLOC_FAIL; 123 return SSH_ERR_ALLOC_FAIL;
120 if ((aux = BN_new()) == NULL) { 124 if ((aux = BN_new()) == NULL ||
125 (rsa_dmq1 = BN_new()) == NULL ||
126 (rsa_dmp1 = BN_new()) == NULL)
127 return SSH_ERR_ALLOC_FAIL;
128 if ((d_consttime = BN_dup(rsa_d)) == NULL ||
129 (rsa_iqmp = BN_dup(iqmp)) == NULL) {
121 r = SSH_ERR_ALLOC_FAIL; 130 r = SSH_ERR_ALLOC_FAIL;
122 goto out; 131 goto out;
123 } 132 }
124 BN_set_flags(aux, BN_FLG_CONSTTIME); 133 BN_set_flags(aux, BN_FLG_CONSTTIME);
134 BN_set_flags(d_consttime, BN_FLG_CONSTTIME);
125 135
126 BN_init(&d); 136 if ((BN_sub(aux, rsa_q, BN_value_one()) == 0) ||
127 BN_with_flags(&d, key->rsa->d, BN_FLG_CONSTTIME); 137 (BN_mod(rsa_dmq1, d_consttime, aux, ctx) == 0) ||
128 138 (BN_sub(aux, rsa_p, BN_value_one()) == 0) ||
129 if ((BN_sub(aux, key->rsa->q, BN_value_one()) == 0) || 139 (BN_mod(rsa_dmp1, d_consttime, aux, ctx) == 0)) {
130 (BN_mod(key->rsa->dmq1, &d, aux, ctx) == 0) || 140 r = SSH_ERR_LIBCRYPTO_ERROR;
131 (BN_sub(aux, key->rsa->p, BN_value_one()) == 0) || 141 goto out;
132 (BN_mod(key->rsa->dmp1, &d, aux, ctx) == 0)) { 142 }
143 if (!RSA_set0_crt_params(key->rsa, rsa_dmp1, rsa_dmq1, rsa_iqmp)) {
133 r = SSH_ERR_LIBCRYPTO_ERROR; 144 r = SSH_ERR_LIBCRYPTO_ERROR;
134 goto out; 145 goto out;
135 } 146 }
147 rsa_dmp1 = rsa_dmq1 = rsa_iqmp = NULL; /* transferred */
148 /* success */
136 r = 0; 149 r = 0;
137 out: 150 out:
138 BN_clear_free(aux); 151 BN_clear_free(aux);
152 BN_clear_free(d_consttime);
153 BN_clear_free(rsa_dmp1);
154 BN_clear_free(rsa_dmq1);
155 BN_clear_free(rsa_iqmp);
139 BN_CTX_free(ctx); 156 BN_CTX_free(ctx);
140 return r; 157 return r;
141} 158}
@@ -145,6 +162,7 @@ int
145ssh_rsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp, 162ssh_rsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
146 const u_char *data, size_t datalen, const char *alg_ident) 163 const u_char *data, size_t datalen, const char *alg_ident)
147{ 164{
165 const BIGNUM *rsa_n;
148 u_char digest[SSH_DIGEST_MAX_LENGTH], *sig = NULL; 166 u_char digest[SSH_DIGEST_MAX_LENGTH], *sig = NULL;
149 size_t slen = 0; 167 size_t slen = 0;
150 u_int dlen, len; 168 u_int dlen, len;
@@ -163,7 +181,8 @@ ssh_rsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
163 if (key == NULL || key->rsa == NULL || hash_alg == -1 || 181 if (key == NULL || key->rsa == NULL || hash_alg == -1 ||
164 sshkey_type_plain(key->type) != KEY_RSA) 182 sshkey_type_plain(key->type) != KEY_RSA)
165 return SSH_ERR_INVALID_ARGUMENT; 183 return SSH_ERR_INVALID_ARGUMENT;
166 if (BN_num_bits(key->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) 184 RSA_get0_key(key->rsa, &rsa_n, NULL, NULL);
185 if (BN_num_bits(rsa_n) < SSH_RSA_MINIMUM_MODULUS_SIZE)
167 return SSH_ERR_KEY_LENGTH; 186 return SSH_ERR_KEY_LENGTH;
168 slen = RSA_size(key->rsa); 187 slen = RSA_size(key->rsa);
169 if (slen <= 0 || slen > SSHBUF_MAX_BIGNUM) 188 if (slen <= 0 || slen > SSHBUF_MAX_BIGNUM)
@@ -225,6 +244,7 @@ ssh_rsa_verify(const struct sshkey *key,
225 const u_char *sig, size_t siglen, const u_char *data, size_t datalen, 244 const u_char *sig, size_t siglen, const u_char *data, size_t datalen,
226 const char *alg) 245 const char *alg)
227{ 246{
247 const BIGNUM *rsa_n;
228 char *sigtype = NULL; 248 char *sigtype = NULL;
229 int hash_alg, want_alg, ret = SSH_ERR_INTERNAL_ERROR; 249 int hash_alg, want_alg, ret = SSH_ERR_INTERNAL_ERROR;
230 size_t len = 0, diff, modlen, dlen; 250 size_t len = 0, diff, modlen, dlen;
@@ -235,7 +255,8 @@ ssh_rsa_verify(const struct sshkey *key,
235 sshkey_type_plain(key->type) != KEY_RSA || 255 sshkey_type_plain(key->type) != KEY_RSA ||
236 sig == NULL || siglen == 0) 256 sig == NULL || siglen == 0)
237 return SSH_ERR_INVALID_ARGUMENT; 257 return SSH_ERR_INVALID_ARGUMENT;
238 if (BN_num_bits(key->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) 258 RSA_get0_key(key->rsa, &rsa_n, NULL, NULL);
259 if (BN_num_bits(rsa_n) < SSH_RSA_MINIMUM_MODULUS_SIZE)
239 return SSH_ERR_KEY_LENGTH; 260 return SSH_ERR_KEY_LENGTH;
240 261
241 if ((b = sshbuf_from(sig, siglen)) == NULL) 262 if ((b = sshbuf_from(sig, siglen)) == NULL)
diff --git a/sshd.c b/sshd.c
index a738c3ab6..98beb1ed5 100644
--- a/sshd.c
+++ b/sshd.c
@@ -493,8 +493,8 @@ demote_sensitive_data(void)
493 493
494 for (i = 0; i < options.num_host_key_files; i++) { 494 for (i = 0; i < options.num_host_key_files; i++) {
495 if (sensitive_data.host_keys[i]) { 495 if (sensitive_data.host_keys[i]) {
496 if ((r = sshkey_demote(sensitive_data.host_keys[i], 496 if ((r = sshkey_from_private(
497 &tmp)) != 0) 497 sensitive_data.host_keys[i], &tmp)) != 0)
498 fatal("could not demote host %s key: %s", 498 fatal("could not demote host %s key: %s",
499 sshkey_type(sensitive_data.host_keys[i]), 499 sshkey_type(sensitive_data.host_keys[i]),
500 ssh_err(r)); 500 ssh_err(r));
@@ -1772,7 +1772,7 @@ main(int ac, char **av)
1772 error("Error loading host key \"%s\": %s", 1772 error("Error loading host key \"%s\": %s",
1773 options.host_key_files[i], ssh_err(r)); 1773 options.host_key_files[i], ssh_err(r));
1774 if (pubkey == NULL && key != NULL) 1774 if (pubkey == NULL && key != NULL)
1775 if ((r = sshkey_demote(key, &pubkey)) != 0) 1775 if ((r = sshkey_from_private(key, &pubkey)) != 0)
1776 fatal("Could not demote key: \"%s\": %s", 1776 fatal("Could not demote key: \"%s\": %s",
1777 options.host_key_files[i], ssh_err(r)); 1777 options.host_key_files[i], ssh_err(r));
1778 sensitive_data.host_keys[i] = key; 1778 sensitive_data.host_keys[i] = key;
diff --git a/sshkey.c b/sshkey.c
index 50ebdc256..085f17079 100644
--- a/sshkey.c
+++ b/sshkey.c
@@ -289,14 +289,24 @@ sshkey_names_valid2(const char *names, int allow_wildcard)
289u_int 289u_int
290sshkey_size(const struct sshkey *k) 290sshkey_size(const struct sshkey *k)
291{ 291{
292#ifdef WITH_OPENSSL
293 const BIGNUM *rsa_n, *dsa_p;
294#endif /* WITH_OPENSSL */
295
292 switch (k->type) { 296 switch (k->type) {
293#ifdef WITH_OPENSSL 297#ifdef WITH_OPENSSL
294 case KEY_RSA: 298 case KEY_RSA:
295 case KEY_RSA_CERT: 299 case KEY_RSA_CERT:
296 return BN_num_bits(k->rsa->n); 300 if (k->rsa == NULL)
301 return 0;
302 RSA_get0_key(k->rsa, &rsa_n, NULL, NULL);
303 return BN_num_bits(rsa_n);
297 case KEY_DSA: 304 case KEY_DSA:
298 case KEY_DSA_CERT: 305 case KEY_DSA_CERT:
299 return BN_num_bits(k->dsa->p); 306 if (k->dsa == NULL)
307 return 0;
308 DSA_get0_pqg(k->dsa, &dsa_p, NULL, NULL);
309 return BN_num_bits(dsa_p);
300 case KEY_ECDSA: 310 case KEY_ECDSA:
301 case KEY_ECDSA_CERT: 311 case KEY_ECDSA_CERT:
302 return sshkey_curve_nid_to_bits(k->ecdsa_nid); 312 return sshkey_curve_nid_to_bits(k->ecdsa_nid);
@@ -503,10 +513,7 @@ sshkey_new(int type)
503#ifdef WITH_OPENSSL 513#ifdef WITH_OPENSSL
504 case KEY_RSA: 514 case KEY_RSA:
505 case KEY_RSA_CERT: 515 case KEY_RSA_CERT:
506 if ((rsa = RSA_new()) == NULL || 516 if ((rsa = RSA_new()) == NULL) {
507 (rsa->n = BN_new()) == NULL ||
508 (rsa->e = BN_new()) == NULL) {
509 RSA_free(rsa);
510 free(k); 517 free(k);
511 return NULL; 518 return NULL;
512 } 519 }
@@ -514,12 +521,7 @@ sshkey_new(int type)
514 break; 521 break;
515 case KEY_DSA: 522 case KEY_DSA:
516 case KEY_DSA_CERT: 523 case KEY_DSA_CERT:
517 if ((dsa = DSA_new()) == NULL || 524 if ((dsa = DSA_new()) == NULL) {
518 (dsa->p = BN_new()) == NULL ||
519 (dsa->q = BN_new()) == NULL ||
520 (dsa->g = BN_new()) == NULL ||
521 (dsa->pub_key = BN_new()) == NULL) {
522 DSA_free(dsa);
523 free(k); 525 free(k);
524 return NULL; 526 return NULL;
525 } 527 }
@@ -553,47 +555,7 @@ sshkey_new(int type)
553 return k; 555 return k;
554} 556}
555 557
556int 558/* XXX garbage-collect this API */
557sshkey_add_private(struct sshkey *k)
558{
559 switch (k->type) {
560#ifdef WITH_OPENSSL
561 case KEY_RSA:
562 case KEY_RSA_CERT:
563#define bn_maybe_alloc_failed(p) (p == NULL && (p = BN_new()) == NULL)
564 if (bn_maybe_alloc_failed(k->rsa->d) ||
565 bn_maybe_alloc_failed(k->rsa->iqmp) ||
566 bn_maybe_alloc_failed(k->rsa->q) ||
567 bn_maybe_alloc_failed(k->rsa->p) ||
568 bn_maybe_alloc_failed(k->rsa->dmq1) ||
569 bn_maybe_alloc_failed(k->rsa->dmp1))
570 return SSH_ERR_ALLOC_FAIL;
571 break;
572 case KEY_DSA:
573 case KEY_DSA_CERT:
574 if (bn_maybe_alloc_failed(k->dsa->priv_key))
575 return SSH_ERR_ALLOC_FAIL;
576 break;
577#undef bn_maybe_alloc_failed
578 case KEY_ECDSA:
579 case KEY_ECDSA_CERT:
580 /* Cannot do anything until we know the group */
581 break;
582#endif /* WITH_OPENSSL */
583 case KEY_ED25519:
584 case KEY_ED25519_CERT:
585 case KEY_XMSS:
586 case KEY_XMSS_CERT:
587 /* no need to prealloc */
588 break;
589 case KEY_UNSPEC:
590 break;
591 default:
592 return SSH_ERR_INVALID_ARGUMENT;
593 }
594 return 0;
595}
596
597struct sshkey * 559struct sshkey *
598sshkey_new_private(int type) 560sshkey_new_private(int type)
599{ 561{
@@ -601,10 +563,6 @@ sshkey_new_private(int type)
601 563
602 if (k == NULL) 564 if (k == NULL)
603 return NULL; 565 return NULL;
604 if (sshkey_add_private(k) != 0) {
605 sshkey_free(k);
606 return NULL;
607 }
608 return k; 566 return k;
609} 567}
610 568
@@ -686,9 +644,15 @@ cert_compare(struct sshkey_cert *a, struct sshkey_cert *b)
686int 644int
687sshkey_equal_public(const struct sshkey *a, const struct sshkey *b) 645sshkey_equal_public(const struct sshkey *a, const struct sshkey *b)
688{ 646{
689#if defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC) 647#if defined(WITH_OPENSSL)
648 const BIGNUM *rsa_e_a, *rsa_n_a;
649 const BIGNUM *rsa_e_b, *rsa_n_b;
650 const BIGNUM *dsa_p_a, *dsa_q_a, *dsa_g_a, *dsa_pub_key_a;
651 const BIGNUM *dsa_p_b, *dsa_q_b, *dsa_g_b, *dsa_pub_key_b;
652# if defined(OPENSSL_HAS_ECC)
690 BN_CTX *bnctx; 653 BN_CTX *bnctx;
691#endif /* WITH_OPENSSL && OPENSSL_HAS_ECC */ 654# endif /* OPENSSL_HAS_ECC */
655#endif /* WITH_OPENSSL */
692 656
693 if (a == NULL || b == NULL || 657 if (a == NULL || b == NULL ||
694 sshkey_type_plain(a->type) != sshkey_type_plain(b->type)) 658 sshkey_type_plain(a->type) != sshkey_type_plain(b->type))
@@ -698,16 +662,24 @@ sshkey_equal_public(const struct sshkey *a, const struct sshkey *b)
698#ifdef WITH_OPENSSL 662#ifdef WITH_OPENSSL
699 case KEY_RSA_CERT: 663 case KEY_RSA_CERT:
700 case KEY_RSA: 664 case KEY_RSA:
701 return a->rsa != NULL && b->rsa != NULL && 665 if (a->rsa == NULL || b->rsa == NULL)
702 BN_cmp(a->rsa->e, b->rsa->e) == 0 && 666 return 0;
703 BN_cmp(a->rsa->n, b->rsa->n) == 0; 667 RSA_get0_key(a->rsa, &rsa_n_a, &rsa_e_a, NULL);
668 RSA_get0_key(b->rsa, &rsa_n_b, &rsa_e_b, NULL);
669 return BN_cmp(rsa_e_a, rsa_e_b) == 0 &&
670 BN_cmp(rsa_n_a, rsa_n_b) == 0;
704 case KEY_DSA_CERT: 671 case KEY_DSA_CERT:
705 case KEY_DSA: 672 case KEY_DSA:
706 return a->dsa != NULL && b->dsa != NULL && 673 if (a->dsa == NULL || b->dsa == NULL)
707 BN_cmp(a->dsa->p, b->dsa->p) == 0 && 674 return 0;
708 BN_cmp(a->dsa->q, b->dsa->q) == 0 && 675 DSA_get0_pqg(a->dsa, &dsa_p_a, &dsa_q_a, &dsa_g_a);
709 BN_cmp(a->dsa->g, b->dsa->g) == 0 && 676 DSA_get0_pqg(b->dsa, &dsa_p_b, &dsa_q_b, &dsa_g_b);
710 BN_cmp(a->dsa->pub_key, b->dsa->pub_key) == 0; 677 DSA_get0_key(a->dsa, &dsa_pub_key_a, NULL);
678 DSA_get0_key(b->dsa, &dsa_pub_key_b, NULL);
679 return BN_cmp(dsa_p_a, dsa_p_b) == 0 &&
680 BN_cmp(dsa_q_a, dsa_q_b) == 0 &&
681 BN_cmp(dsa_g_a, dsa_g_b) == 0 &&
682 BN_cmp(dsa_pub_key_a, dsa_pub_key_b) == 0;
711# ifdef OPENSSL_HAS_ECC 683# ifdef OPENSSL_HAS_ECC
712 case KEY_ECDSA_CERT: 684 case KEY_ECDSA_CERT:
713 case KEY_ECDSA: 685 case KEY_ECDSA:
@@ -764,6 +736,9 @@ to_blob_buf(const struct sshkey *key, struct sshbuf *b, int force_plain,
764{ 736{
765 int type, ret = SSH_ERR_INTERNAL_ERROR; 737 int type, ret = SSH_ERR_INTERNAL_ERROR;
766 const char *typename; 738 const char *typename;
739#ifdef WITH_OPENSSL
740 const BIGNUM *rsa_n, *rsa_e, *dsa_p, *dsa_q, *dsa_g, *dsa_pub_key;
741#endif /* WITH_OPENSSL */
767 742
768 if (key == NULL) 743 if (key == NULL)
769 return SSH_ERR_INVALID_ARGUMENT; 744 return SSH_ERR_INVALID_ARGUMENT;
@@ -796,11 +771,13 @@ to_blob_buf(const struct sshkey *key, struct sshbuf *b, int force_plain,
796 case KEY_DSA: 771 case KEY_DSA:
797 if (key->dsa == NULL) 772 if (key->dsa == NULL)
798 return SSH_ERR_INVALID_ARGUMENT; 773 return SSH_ERR_INVALID_ARGUMENT;
774 DSA_get0_pqg(key->dsa, &dsa_p, &dsa_q, &dsa_g);
775 DSA_get0_key(key->dsa, &dsa_pub_key, NULL);
799 if ((ret = sshbuf_put_cstring(b, typename)) != 0 || 776 if ((ret = sshbuf_put_cstring(b, typename)) != 0 ||
800 (ret = sshbuf_put_bignum2(b, key->dsa->p)) != 0 || 777 (ret = sshbuf_put_bignum2(b, dsa_p)) != 0 ||
801 (ret = sshbuf_put_bignum2(b, key->dsa->q)) != 0 || 778 (ret = sshbuf_put_bignum2(b, dsa_q)) != 0 ||
802 (ret = sshbuf_put_bignum2(b, key->dsa->g)) != 0 || 779 (ret = sshbuf_put_bignum2(b, dsa_g)) != 0 ||
803 (ret = sshbuf_put_bignum2(b, key->dsa->pub_key)) != 0) 780 (ret = sshbuf_put_bignum2(b, dsa_pub_key)) != 0)
804 return ret; 781 return ret;
805 break; 782 break;
806# ifdef OPENSSL_HAS_ECC 783# ifdef OPENSSL_HAS_ECC
@@ -817,9 +794,10 @@ to_blob_buf(const struct sshkey *key, struct sshbuf *b, int force_plain,
817 case KEY_RSA: 794 case KEY_RSA:
818 if (key->rsa == NULL) 795 if (key->rsa == NULL)
819 return SSH_ERR_INVALID_ARGUMENT; 796 return SSH_ERR_INVALID_ARGUMENT;
797 RSA_get0_key(key->rsa, &rsa_n, &rsa_e, NULL);
820 if ((ret = sshbuf_put_cstring(b, typename)) != 0 || 798 if ((ret = sshbuf_put_cstring(b, typename)) != 0 ||
821 (ret = sshbuf_put_bignum2(b, key->rsa->e)) != 0 || 799 (ret = sshbuf_put_bignum2(b, rsa_e)) != 0 ||
822 (ret = sshbuf_put_bignum2(b, key->rsa->n)) != 0) 800 (ret = sshbuf_put_bignum2(b, rsa_n)) != 0)
823 return ret; 801 return ret;
824 break; 802 break;
825#endif /* WITH_OPENSSL */ 803#endif /* WITH_OPENSSL */
@@ -1767,59 +1745,95 @@ sshkey_from_private(const struct sshkey *k, struct sshkey **pkp)
1767{ 1745{
1768 struct sshkey *n = NULL; 1746 struct sshkey *n = NULL;
1769 int ret = SSH_ERR_INTERNAL_ERROR; 1747 int ret = SSH_ERR_INTERNAL_ERROR;
1748 int r = SSH_ERR_INTERNAL_ERROR;
1749#ifdef WITH_OPENSSL
1750 const BIGNUM *rsa_n, *rsa_e;
1751 BIGNUM *rsa_n_dup = NULL, *rsa_e_dup = NULL;
1752 const BIGNUM *dsa_p, *dsa_q, *dsa_g, *dsa_pub_key;
1753 BIGNUM *dsa_p_dup = NULL, *dsa_q_dup = NULL, *dsa_g_dup = NULL;
1754 BIGNUM *dsa_pub_key_dup = NULL;
1755#endif /* WITH_OPENSSL */
1770 1756
1771 *pkp = NULL; 1757 *pkp = NULL;
1772 switch (k->type) { 1758 switch (k->type) {
1773#ifdef WITH_OPENSSL 1759#ifdef WITH_OPENSSL
1774 case KEY_DSA: 1760 case KEY_DSA:
1775 case KEY_DSA_CERT: 1761 case KEY_DSA_CERT:
1776 if ((n = sshkey_new(k->type)) == NULL) 1762 if ((n = sshkey_new(k->type)) == NULL) {
1777 return SSH_ERR_ALLOC_FAIL; 1763 r = SSH_ERR_ALLOC_FAIL;
1778 if ((BN_copy(n->dsa->p, k->dsa->p) == NULL) || 1764 goto out;
1779 (BN_copy(n->dsa->q, k->dsa->q) == NULL) || 1765 }
1780 (BN_copy(n->dsa->g, k->dsa->g) == NULL) || 1766
1781 (BN_copy(n->dsa->pub_key, k->dsa->pub_key) == NULL)) { 1767 DSA_get0_pqg(k->dsa, &dsa_p, &dsa_q, &dsa_g);
1782 sshkey_free(n); 1768 DSA_get0_key(k->dsa, &dsa_pub_key, NULL);
1783 return SSH_ERR_ALLOC_FAIL; 1769 if ((dsa_p_dup = BN_dup(dsa_p)) == NULL ||
1770 (dsa_q_dup = BN_dup(dsa_q)) == NULL ||
1771 (dsa_g_dup = BN_dup(dsa_g)) == NULL ||
1772 (dsa_pub_key_dup = BN_dup(dsa_pub_key)) == NULL) {
1773 r = SSH_ERR_ALLOC_FAIL;
1774 goto out;
1784 } 1775 }
1776 if (!DSA_set0_pqg(n->dsa, dsa_p_dup, dsa_q_dup, dsa_g_dup)) {
1777 r = SSH_ERR_LIBCRYPTO_ERROR;
1778 goto out;
1779 }
1780 dsa_p_dup = dsa_q_dup = dsa_g_dup = NULL; /* transferred */
1781 if (!DSA_set0_key(n->dsa, dsa_pub_key_dup, NULL)) {
1782 r = SSH_ERR_LIBCRYPTO_ERROR;
1783 goto out;
1784 }
1785 dsa_pub_key_dup = NULL; /* transferred */
1786
1785 break; 1787 break;
1786# ifdef OPENSSL_HAS_ECC 1788# ifdef OPENSSL_HAS_ECC
1787 case KEY_ECDSA: 1789 case KEY_ECDSA:
1788 case KEY_ECDSA_CERT: 1790 case KEY_ECDSA_CERT:
1789 if ((n = sshkey_new(k->type)) == NULL) 1791 if ((n = sshkey_new(k->type)) == NULL) {
1790 return SSH_ERR_ALLOC_FAIL; 1792 r = SSH_ERR_ALLOC_FAIL;
1793 goto out;
1794 }
1791 n->ecdsa_nid = k->ecdsa_nid; 1795 n->ecdsa_nid = k->ecdsa_nid;
1792 n->ecdsa = EC_KEY_new_by_curve_name(k->ecdsa_nid); 1796 n->ecdsa = EC_KEY_new_by_curve_name(k->ecdsa_nid);
1793 if (n->ecdsa == NULL) { 1797 if (n->ecdsa == NULL) {
1794 sshkey_free(n); 1798 r = SSH_ERR_ALLOC_FAIL;
1795 return SSH_ERR_ALLOC_FAIL; 1799 goto out;
1796 } 1800 }
1797 if (EC_KEY_set_public_key(n->ecdsa, 1801 if (EC_KEY_set_public_key(n->ecdsa,
1798 EC_KEY_get0_public_key(k->ecdsa)) != 1) { 1802 EC_KEY_get0_public_key(k->ecdsa)) != 1) {
1799 sshkey_free(n); 1803 r = SSH_ERR_LIBCRYPTO_ERROR;
1800 return SSH_ERR_LIBCRYPTO_ERROR; 1804 goto out;
1801 } 1805 }
1802 break; 1806 break;
1803# endif /* OPENSSL_HAS_ECC */ 1807# endif /* OPENSSL_HAS_ECC */
1804 case KEY_RSA: 1808 case KEY_RSA:
1805 case KEY_RSA_CERT: 1809 case KEY_RSA_CERT:
1806 if ((n = sshkey_new(k->type)) == NULL) 1810 if ((n = sshkey_new(k->type)) == NULL) {
1807 return SSH_ERR_ALLOC_FAIL; 1811 r = SSH_ERR_ALLOC_FAIL;
1808 if ((BN_copy(n->rsa->n, k->rsa->n) == NULL) || 1812 goto out;
1809 (BN_copy(n->rsa->e, k->rsa->e) == NULL)) {
1810 sshkey_free(n);
1811 return SSH_ERR_ALLOC_FAIL;
1812 } 1813 }
1814 RSA_get0_key(k->rsa, &rsa_n, &rsa_e, NULL);
1815 if ((rsa_n_dup = BN_dup(rsa_n)) == NULL ||
1816 (rsa_e_dup = BN_dup(rsa_e)) == NULL) {
1817 r = SSH_ERR_ALLOC_FAIL;
1818 goto out;
1819 }
1820 if (!RSA_set0_key(n->rsa, rsa_n_dup, rsa_e_dup, NULL)) {
1821 r = SSH_ERR_LIBCRYPTO_ERROR;
1822 goto out;
1823 }
1824 rsa_n_dup = rsa_e_dup = NULL; /* transferred */
1813 break; 1825 break;
1814#endif /* WITH_OPENSSL */ 1826#endif /* WITH_OPENSSL */
1815 case KEY_ED25519: 1827 case KEY_ED25519:
1816 case KEY_ED25519_CERT: 1828 case KEY_ED25519_CERT:
1817 if ((n = sshkey_new(k->type)) == NULL) 1829 if ((n = sshkey_new(k->type)) == NULL) {
1818 return SSH_ERR_ALLOC_FAIL; 1830 r = SSH_ERR_ALLOC_FAIL;
1831 goto out;
1832 }
1819 if (k->ed25519_pk != NULL) { 1833 if (k->ed25519_pk != NULL) {
1820 if ((n->ed25519_pk = malloc(ED25519_PK_SZ)) == NULL) { 1834 if ((n->ed25519_pk = malloc(ED25519_PK_SZ)) == NULL) {
1821 sshkey_free(n); 1835 r = SSH_ERR_ALLOC_FAIL;
1822 return SSH_ERR_ALLOC_FAIL; 1836 goto out;
1823 } 1837 }
1824 memcpy(n->ed25519_pk, k->ed25519_pk, ED25519_PK_SZ); 1838 memcpy(n->ed25519_pk, k->ed25519_pk, ED25519_PK_SZ);
1825 } 1839 }
@@ -1827,37 +1841,46 @@ sshkey_from_private(const struct sshkey *k, struct sshkey **pkp)
1827#ifdef WITH_XMSS 1841#ifdef WITH_XMSS
1828 case KEY_XMSS: 1842 case KEY_XMSS:
1829 case KEY_XMSS_CERT: 1843 case KEY_XMSS_CERT:
1830 if ((n = sshkey_new(k->type)) == NULL) 1844 if ((n = sshkey_new(k->type)) == NULL) {
1831 return SSH_ERR_ALLOC_FAIL; 1845 r = SSH_ERR_ALLOC_FAIL;
1832 if ((ret = sshkey_xmss_init(n, k->xmss_name)) != 0) { 1846 goto out;
1833 sshkey_free(n);
1834 return ret;
1835 } 1847 }
1848 if ((r = sshkey_xmss_init(n, k->xmss_name)) != 0)
1849 goto out;
1836 if (k->xmss_pk != NULL) { 1850 if (k->xmss_pk != NULL) {
1837 size_t pklen = sshkey_xmss_pklen(k); 1851 size_t pklen = sshkey_xmss_pklen(k);
1838 if (pklen == 0 || sshkey_xmss_pklen(n) != pklen) { 1852 if (pklen == 0 || sshkey_xmss_pklen(n) != pklen) {
1839 sshkey_free(n); 1853 r = SSH_ERR_INTERNAL_ERROR;
1840 return SSH_ERR_INTERNAL_ERROR; 1854 goto out;
1841 } 1855 }
1842 if ((n->xmss_pk = malloc(pklen)) == NULL) { 1856 if ((n->xmss_pk = malloc(pklen)) == NULL) {
1843 sshkey_free(n); 1857 r = SSH_ERR_ALLOC_FAIL;
1844 return SSH_ERR_ALLOC_FAIL; 1858 goto out;
1845 } 1859 }
1846 memcpy(n->xmss_pk, k->xmss_pk, pklen); 1860 memcpy(n->xmss_pk, k->xmss_pk, pklen);
1847 } 1861 }
1848 break; 1862 break;
1849#endif /* WITH_XMSS */ 1863#endif /* WITH_XMSS */
1850 default: 1864 default:
1851 return SSH_ERR_KEY_TYPE_UNKNOWN; 1865 r = SSH_ERR_KEY_TYPE_UNKNOWN;
1852 } 1866 goto out;
1853 if (sshkey_is_cert(k)) {
1854 if ((ret = sshkey_cert_copy(k, n)) != 0) {
1855 sshkey_free(n);
1856 return ret;
1857 }
1858 } 1867 }
1868 if (sshkey_is_cert(k) && (r = sshkey_cert_copy(k, n)) != 0)
1869 goto out;
1870 /* success */
1859 *pkp = n; 1871 *pkp = n;
1860 return 0; 1872 n = NULL;
1873 r = 0;
1874 out:
1875 sshkey_free(n);
1876 BN_clear_free(rsa_n_dup);
1877 BN_clear_free(rsa_e_dup);
1878 BN_clear_free(dsa_p_dup);
1879 BN_clear_free(dsa_q_dup);
1880 BN_clear_free(dsa_g_dup);
1881 BN_clear_free(dsa_pub_key_dup);
1882
1883 return r;
1861} 1884}
1862 1885
1863static int 1886static int
@@ -1986,6 +2009,17 @@ cert_parse(struct sshbuf *b, struct sshkey *key, struct sshbuf *certbuf)
1986} 2009}
1987 2010
1988static int 2011static int
2012check_rsa_length(const RSA *rsa)
2013{
2014 const BIGNUM *rsa_n;
2015
2016 RSA_get0_key(rsa, &rsa_n, NULL, NULL);
2017 if (BN_num_bits(rsa_n) < SSH_RSA_MINIMUM_MODULUS_SIZE)
2018 return SSH_ERR_KEY_LENGTH;
2019 return 0;
2020}
2021
2022static int
1989sshkey_from_blob_internal(struct sshbuf *b, struct sshkey **keyp, 2023sshkey_from_blob_internal(struct sshbuf *b, struct sshkey **keyp,
1990 int allow_cert) 2024 int allow_cert)
1991{ 2025{
@@ -1995,9 +2029,13 @@ sshkey_from_blob_internal(struct sshbuf *b, struct sshkey **keyp,
1995 size_t len; 2029 size_t len;
1996 u_char *pk = NULL; 2030 u_char *pk = NULL;
1997 struct sshbuf *copy; 2031 struct sshbuf *copy;
1998#if defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC) 2032#if defined(WITH_OPENSSL)
2033 BIGNUM *rsa_n = NULL, *rsa_e = NULL;
2034 BIGNUM *dsa_p = NULL, *dsa_q = NULL, *dsa_g = NULL, *dsa_pub_key = NULL;
2035# if defined(OPENSSL_HAS_ECC)
1999 EC_POINT *q = NULL; 2036 EC_POINT *q = NULL;
2000#endif /* WITH_OPENSSL && OPENSSL_HAS_ECC */ 2037# endif /* OPENSSL_HAS_ECC */
2038#endif /* WITH_OPENSSL */
2001 2039
2002#ifdef DEBUG_PK /* XXX */ 2040#ifdef DEBUG_PK /* XXX */
2003 sshbuf_dump(b, stderr); 2041 sshbuf_dump(b, stderr);
@@ -2032,15 +2070,23 @@ sshkey_from_blob_internal(struct sshbuf *b, struct sshkey **keyp,
2032 ret = SSH_ERR_ALLOC_FAIL; 2070 ret = SSH_ERR_ALLOC_FAIL;
2033 goto out; 2071 goto out;
2034 } 2072 }
2035 if (sshbuf_get_bignum2(b, key->rsa->e) != 0 || 2073 if ((rsa_e = BN_new()) == NULL ||
2036 sshbuf_get_bignum2(b, key->rsa->n) != 0) { 2074 (rsa_n = BN_new()) == NULL) {
2075 ret = SSH_ERR_ALLOC_FAIL;
2076 goto out;
2077 }
2078 if (sshbuf_get_bignum2(b, rsa_e) != 0 ||
2079 sshbuf_get_bignum2(b, rsa_n) != 0) {
2037 ret = SSH_ERR_INVALID_FORMAT; 2080 ret = SSH_ERR_INVALID_FORMAT;
2038 goto out; 2081 goto out;
2039 } 2082 }
2040 if (BN_num_bits(key->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) { 2083 if (!RSA_set0_key(key->rsa, rsa_n, rsa_e, NULL)) {
2041 ret = SSH_ERR_KEY_LENGTH; 2084 ret = SSH_ERR_LIBCRYPTO_ERROR;
2042 goto out; 2085 goto out;
2043 } 2086 }
2087 rsa_n = rsa_e = NULL; /* transferred */
2088 if ((ret = check_rsa_length(key->rsa)) != 0)
2089 goto out;
2044#ifdef DEBUG_PK 2090#ifdef DEBUG_PK
2045 RSA_print_fp(stderr, key->rsa, 8); 2091 RSA_print_fp(stderr, key->rsa, 8);
2046#endif 2092#endif
@@ -2057,13 +2103,30 @@ sshkey_from_blob_internal(struct sshbuf *b, struct sshkey **keyp,
2057 ret = SSH_ERR_ALLOC_FAIL; 2103 ret = SSH_ERR_ALLOC_FAIL;
2058 goto out; 2104 goto out;
2059 } 2105 }
2060 if (sshbuf_get_bignum2(b, key->dsa->p) != 0 || 2106 if ((dsa_p = BN_new()) == NULL ||
2061 sshbuf_get_bignum2(b, key->dsa->q) != 0 || 2107 (dsa_q = BN_new()) == NULL ||
2062 sshbuf_get_bignum2(b, key->dsa->g) != 0 || 2108 (dsa_g = BN_new()) == NULL ||
2063 sshbuf_get_bignum2(b, key->dsa->pub_key) != 0) { 2109 (dsa_pub_key = BN_new()) == NULL) {
2110 ret = SSH_ERR_ALLOC_FAIL;
2111 goto out;
2112 }
2113 if (sshbuf_get_bignum2(b, dsa_p) != 0 ||
2114 sshbuf_get_bignum2(b, dsa_q) != 0 ||
2115 sshbuf_get_bignum2(b, dsa_g) != 0 ||
2116 sshbuf_get_bignum2(b, dsa_pub_key) != 0) {
2064 ret = SSH_ERR_INVALID_FORMAT; 2117 ret = SSH_ERR_INVALID_FORMAT;
2065 goto out; 2118 goto out;
2066 } 2119 }
2120 if (!DSA_set0_pqg(key->dsa, dsa_p, dsa_q, dsa_g)) {
2121 ret = SSH_ERR_LIBCRYPTO_ERROR;
2122 goto out;
2123 }
2124 dsa_p = dsa_q = dsa_g = NULL; /* transferred */
2125 if (!DSA_set0_key(key->dsa, dsa_pub_key, NULL)) {
2126 ret = SSH_ERR_LIBCRYPTO_ERROR;
2127 goto out;
2128 }
2129 dsa_pub_key = NULL; /* transferred */
2067#ifdef DEBUG_PK 2130#ifdef DEBUG_PK
2068 DSA_print_fp(stderr, key->dsa, 8); 2131 DSA_print_fp(stderr, key->dsa, 8);
2069#endif 2132#endif
@@ -2197,9 +2260,17 @@ sshkey_from_blob_internal(struct sshbuf *b, struct sshkey **keyp,
2197 free(ktype); 2260 free(ktype);
2198 free(curve); 2261 free(curve);
2199 free(pk); 2262 free(pk);
2200#if defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC) 2263#if defined(WITH_OPENSSL)
2264 BN_clear_free(rsa_n);
2265 BN_clear_free(rsa_e);
2266 BN_clear_free(dsa_p);
2267 BN_clear_free(dsa_q);
2268 BN_clear_free(dsa_g);
2269 BN_clear_free(dsa_pub_key);
2270# if defined(OPENSSL_HAS_ECC)
2201 EC_POINT_free(q); 2271 EC_POINT_free(q);
2202#endif /* WITH_OPENSSL && OPENSSL_HAS_ECC */ 2272# endif /* OPENSSL_HAS_ECC */
2273#endif /* WITH_OPENSSL */
2203 return ret; 2274 return ret;
2204} 2275}
2205 2276
@@ -2401,120 +2472,6 @@ sshkey_verify(const struct sshkey *key,
2401 } 2472 }
2402} 2473}
2403 2474
2404/* Converts a private to a public key */
2405int
2406sshkey_demote(const struct sshkey *k, struct sshkey **dkp)
2407{
2408 struct sshkey *pk;
2409 int ret = SSH_ERR_INTERNAL_ERROR;
2410
2411 *dkp = NULL;
2412 if ((pk = calloc(1, sizeof(*pk))) == NULL)
2413 return SSH_ERR_ALLOC_FAIL;
2414 pk->type = k->type;
2415 pk->flags = k->flags;
2416 pk->ecdsa_nid = k->ecdsa_nid;
2417 pk->dsa = NULL;
2418 pk->ecdsa = NULL;
2419 pk->rsa = NULL;
2420 pk->ed25519_pk = NULL;
2421 pk->ed25519_sk = NULL;
2422 pk->xmss_pk = NULL;
2423 pk->xmss_sk = NULL;
2424
2425 switch (k->type) {
2426#ifdef WITH_OPENSSL
2427 case KEY_RSA_CERT:
2428 if ((ret = sshkey_cert_copy(k, pk)) != 0)
2429 goto fail;
2430 /* FALLTHROUGH */
2431 case KEY_RSA:
2432 if ((pk->rsa = RSA_new()) == NULL ||
2433 (pk->rsa->e = BN_dup(k->rsa->e)) == NULL ||
2434 (pk->rsa->n = BN_dup(k->rsa->n)) == NULL) {
2435 ret = SSH_ERR_ALLOC_FAIL;
2436 goto fail;
2437 }
2438 break;
2439 case KEY_DSA_CERT:
2440 if ((ret = sshkey_cert_copy(k, pk)) != 0)
2441 goto fail;
2442 /* FALLTHROUGH */
2443 case KEY_DSA:
2444 if ((pk->dsa = DSA_new()) == NULL ||
2445 (pk->dsa->p = BN_dup(k->dsa->p)) == NULL ||
2446 (pk->dsa->q = BN_dup(k->dsa->q)) == NULL ||
2447 (pk->dsa->g = BN_dup(k->dsa->g)) == NULL ||
2448 (pk->dsa->pub_key = BN_dup(k->dsa->pub_key)) == NULL) {
2449 ret = SSH_ERR_ALLOC_FAIL;
2450 goto fail;
2451 }
2452 break;
2453 case KEY_ECDSA_CERT:
2454 if ((ret = sshkey_cert_copy(k, pk)) != 0)
2455 goto fail;
2456 /* FALLTHROUGH */
2457# ifdef OPENSSL_HAS_ECC
2458 case KEY_ECDSA:
2459 pk->ecdsa = EC_KEY_new_by_curve_name(pk->ecdsa_nid);
2460 if (pk->ecdsa == NULL) {
2461 ret = SSH_ERR_ALLOC_FAIL;
2462 goto fail;
2463 }
2464 if (EC_KEY_set_public_key(pk->ecdsa,
2465 EC_KEY_get0_public_key(k->ecdsa)) != 1) {
2466 ret = SSH_ERR_LIBCRYPTO_ERROR;
2467 goto fail;
2468 }
2469 break;
2470# endif /* OPENSSL_HAS_ECC */
2471#endif /* WITH_OPENSSL */
2472 case KEY_ED25519_CERT:
2473 if ((ret = sshkey_cert_copy(k, pk)) != 0)
2474 goto fail;
2475 /* FALLTHROUGH */
2476 case KEY_ED25519:
2477 if (k->ed25519_pk != NULL) {
2478 if ((pk->ed25519_pk = malloc(ED25519_PK_SZ)) == NULL) {
2479 ret = SSH_ERR_ALLOC_FAIL;
2480 goto fail;
2481 }
2482 memcpy(pk->ed25519_pk, k->ed25519_pk, ED25519_PK_SZ);
2483 }
2484 break;
2485#ifdef WITH_XMSS
2486 case KEY_XMSS_CERT:
2487 if ((ret = sshkey_cert_copy(k, pk)) != 0)
2488 goto fail;
2489 /* FALLTHROUGH */
2490 case KEY_XMSS:
2491 if ((ret = sshkey_xmss_init(pk, k->xmss_name)) != 0)
2492 goto fail;
2493 if (k->xmss_pk != NULL) {
2494 size_t pklen = sshkey_xmss_pklen(k);
2495
2496 if (pklen == 0 || sshkey_xmss_pklen(pk) != pklen) {
2497 ret = SSH_ERR_INTERNAL_ERROR;
2498 goto fail;
2499 }
2500 if ((pk->xmss_pk = malloc(pklen)) == NULL) {
2501 ret = SSH_ERR_ALLOC_FAIL;
2502 goto fail;
2503 }
2504 memcpy(pk->xmss_pk, k->xmss_pk, pklen);
2505 }
2506 break;
2507#endif /* WITH_XMSS */
2508 default:
2509 ret = SSH_ERR_KEY_TYPE_UNKNOWN;
2510 fail:
2511 sshkey_free(pk);
2512 return ret;
2513 }
2514 *dkp = pk;
2515 return 0;
2516}
2517
2518/* Convert a plain key to their _CERT equivalent */ 2475/* Convert a plain key to their _CERT equivalent */
2519int 2476int
2520sshkey_to_certified(struct sshkey *k) 2477sshkey_to_certified(struct sshkey *k)
@@ -2573,6 +2530,9 @@ sshkey_certify_custom(struct sshkey *k, struct sshkey *ca, const char *alg,
2573 int ret = SSH_ERR_INTERNAL_ERROR; 2530 int ret = SSH_ERR_INTERNAL_ERROR;
2574 struct sshbuf *cert = NULL; 2531 struct sshbuf *cert = NULL;
2575 char *sigtype = NULL; 2532 char *sigtype = NULL;
2533#ifdef WITH_OPENSSL
2534 const BIGNUM *rsa_n, *rsa_e, *dsa_p, *dsa_q, *dsa_g, *dsa_pub_key;
2535#endif /* WITH_OPENSSL */
2576 2536
2577 if (k == NULL || k->cert == NULL || 2537 if (k == NULL || k->cert == NULL ||
2578 k->cert->certblob == NULL || ca == NULL) 2538 k->cert->certblob == NULL || ca == NULL)
@@ -2609,10 +2569,12 @@ sshkey_certify_custom(struct sshkey *k, struct sshkey *ca, const char *alg,
2609 switch (k->type) { 2569 switch (k->type) {
2610#ifdef WITH_OPENSSL 2570#ifdef WITH_OPENSSL
2611 case KEY_DSA_CERT: 2571 case KEY_DSA_CERT:
2612 if ((ret = sshbuf_put_bignum2(cert, k->dsa->p)) != 0 || 2572 DSA_get0_pqg(k->dsa, &dsa_p, &dsa_q, &dsa_g);
2613 (ret = sshbuf_put_bignum2(cert, k->dsa->q)) != 0 || 2573 DSA_get0_key(k->dsa, &dsa_pub_key, NULL);
2614 (ret = sshbuf_put_bignum2(cert, k->dsa->g)) != 0 || 2574 if ((ret = sshbuf_put_bignum2(cert, dsa_p)) != 0 ||
2615 (ret = sshbuf_put_bignum2(cert, k->dsa->pub_key)) != 0) 2575 (ret = sshbuf_put_bignum2(cert, dsa_q)) != 0 ||
2576 (ret = sshbuf_put_bignum2(cert, dsa_g)) != 0 ||
2577 (ret = sshbuf_put_bignum2(cert, dsa_pub_key)) != 0)
2616 goto out; 2578 goto out;
2617 break; 2579 break;
2618# ifdef OPENSSL_HAS_ECC 2580# ifdef OPENSSL_HAS_ECC
@@ -2626,8 +2588,9 @@ sshkey_certify_custom(struct sshkey *k, struct sshkey *ca, const char *alg,
2626 break; 2588 break;
2627# endif /* OPENSSL_HAS_ECC */ 2589# endif /* OPENSSL_HAS_ECC */
2628 case KEY_RSA_CERT: 2590 case KEY_RSA_CERT:
2629 if ((ret = sshbuf_put_bignum2(cert, k->rsa->e)) != 0 || 2591 RSA_get0_key(k->rsa, &rsa_n, &rsa_e, NULL);
2630 (ret = sshbuf_put_bignum2(cert, k->rsa->n)) != 0) 2592 if ((ret = sshbuf_put_bignum2(cert, rsa_e)) != 0 ||
2593 (ret = sshbuf_put_bignum2(cert, rsa_n)) != 0)
2631 goto out; 2594 goto out;
2632 break; 2595 break;
2633#endif /* WITH_OPENSSL */ 2596#endif /* WITH_OPENSSL */
@@ -2820,18 +2783,25 @@ sshkey_private_serialize_opt(const struct sshkey *key, struct sshbuf *b,
2820 enum sshkey_serialize_rep opts) 2783 enum sshkey_serialize_rep opts)
2821{ 2784{
2822 int r = SSH_ERR_INTERNAL_ERROR; 2785 int r = SSH_ERR_INTERNAL_ERROR;
2786#ifdef WITH_OPENSSL
2787 const BIGNUM *rsa_n, *rsa_e, *rsa_d, *rsa_iqmp, *rsa_p, *rsa_q;
2788 const BIGNUM *dsa_p, *dsa_q, *dsa_g, *dsa_pub_key, *dsa_priv_key;
2789#endif /* WITH_OPENSSL */
2823 2790
2824 if ((r = sshbuf_put_cstring(b, sshkey_ssh_name(key))) != 0) 2791 if ((r = sshbuf_put_cstring(b, sshkey_ssh_name(key))) != 0)
2825 goto out; 2792 goto out;
2826 switch (key->type) { 2793 switch (key->type) {
2827#ifdef WITH_OPENSSL 2794#ifdef WITH_OPENSSL
2828 case KEY_RSA: 2795 case KEY_RSA:
2829 if ((r = sshbuf_put_bignum2(b, key->rsa->n)) != 0 || 2796 RSA_get0_key(key->rsa, &rsa_n, &rsa_e, &rsa_d);
2830 (r = sshbuf_put_bignum2(b, key->rsa->e)) != 0 || 2797 RSA_get0_factors(key->rsa, &rsa_p, &rsa_q);
2831 (r = sshbuf_put_bignum2(b, key->rsa->d)) != 0 || 2798 RSA_get0_crt_params(key->rsa, NULL, NULL, &rsa_iqmp);
2832 (r = sshbuf_put_bignum2(b, key->rsa->iqmp)) != 0 || 2799 if ((r = sshbuf_put_bignum2(b, rsa_n)) != 0 ||
2833 (r = sshbuf_put_bignum2(b, key->rsa->p)) != 0 || 2800 (r = sshbuf_put_bignum2(b, rsa_e)) != 0 ||
2834 (r = sshbuf_put_bignum2(b, key->rsa->q)) != 0) 2801 (r = sshbuf_put_bignum2(b, rsa_d)) != 0 ||
2802 (r = sshbuf_put_bignum2(b, rsa_iqmp)) != 0 ||
2803 (r = sshbuf_put_bignum2(b, rsa_p)) != 0 ||
2804 (r = sshbuf_put_bignum2(b, rsa_q)) != 0)
2835 goto out; 2805 goto out;
2836 break; 2806 break;
2837 case KEY_RSA_CERT: 2807 case KEY_RSA_CERT:
@@ -2839,19 +2809,24 @@ sshkey_private_serialize_opt(const struct sshkey *key, struct sshbuf *b,
2839 r = SSH_ERR_INVALID_ARGUMENT; 2809 r = SSH_ERR_INVALID_ARGUMENT;
2840 goto out; 2810 goto out;
2841 } 2811 }
2812 RSA_get0_key(key->rsa, NULL, NULL, &rsa_d);
2813 RSA_get0_factors(key->rsa, &rsa_p, &rsa_q);
2814 RSA_get0_crt_params(key->rsa, NULL, NULL, &rsa_iqmp);
2842 if ((r = sshbuf_put_stringb(b, key->cert->certblob)) != 0 || 2815 if ((r = sshbuf_put_stringb(b, key->cert->certblob)) != 0 ||
2843 (r = sshbuf_put_bignum2(b, key->rsa->d)) != 0 || 2816 (r = sshbuf_put_bignum2(b, rsa_d)) != 0 ||
2844 (r = sshbuf_put_bignum2(b, key->rsa->iqmp)) != 0 || 2817 (r = sshbuf_put_bignum2(b, rsa_iqmp)) != 0 ||
2845 (r = sshbuf_put_bignum2(b, key->rsa->p)) != 0 || 2818 (r = sshbuf_put_bignum2(b, rsa_p)) != 0 ||
2846 (r = sshbuf_put_bignum2(b, key->rsa->q)) != 0) 2819 (r = sshbuf_put_bignum2(b, rsa_q)) != 0)
2847 goto out; 2820 goto out;
2848 break; 2821 break;
2849 case KEY_DSA: 2822 case KEY_DSA:
2850 if ((r = sshbuf_put_bignum2(b, key->dsa->p)) != 0 || 2823 DSA_get0_pqg(key->dsa, &dsa_p, &dsa_q, &dsa_g);
2851 (r = sshbuf_put_bignum2(b, key->dsa->q)) != 0 || 2824 DSA_get0_key(key->dsa, &dsa_pub_key, &dsa_priv_key);
2852 (r = sshbuf_put_bignum2(b, key->dsa->g)) != 0 || 2825 if ((r = sshbuf_put_bignum2(b, dsa_p)) != 0 ||
2853 (r = sshbuf_put_bignum2(b, key->dsa->pub_key)) != 0 || 2826 (r = sshbuf_put_bignum2(b, dsa_q)) != 0 ||
2854 (r = sshbuf_put_bignum2(b, key->dsa->priv_key)) != 0) 2827 (r = sshbuf_put_bignum2(b, dsa_g)) != 0 ||
2828 (r = sshbuf_put_bignum2(b, dsa_pub_key)) != 0 ||
2829 (r = sshbuf_put_bignum2(b, dsa_priv_key)) != 0)
2855 goto out; 2830 goto out;
2856 break; 2831 break;
2857 case KEY_DSA_CERT: 2832 case KEY_DSA_CERT:
@@ -2859,8 +2834,9 @@ sshkey_private_serialize_opt(const struct sshkey *key, struct sshbuf *b,
2859 r = SSH_ERR_INVALID_ARGUMENT; 2834 r = SSH_ERR_INVALID_ARGUMENT;
2860 goto out; 2835 goto out;
2861 } 2836 }
2837 DSA_get0_key(key->dsa, NULL, &dsa_priv_key);
2862 if ((r = sshbuf_put_stringb(b, key->cert->certblob)) != 0 || 2838 if ((r = sshbuf_put_stringb(b, key->cert->certblob)) != 0 ||
2863 (r = sshbuf_put_bignum2(b, key->dsa->priv_key)) != 0) 2839 (r = sshbuf_put_bignum2(b, dsa_priv_key)) != 0)
2864 goto out; 2840 goto out;
2865 break; 2841 break;
2866# ifdef OPENSSL_HAS_ECC 2842# ifdef OPENSSL_HAS_ECC
@@ -2961,6 +2937,10 @@ sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **kp)
2961 u_char *xmss_pk = NULL, *xmss_sk = NULL; 2937 u_char *xmss_pk = NULL, *xmss_sk = NULL;
2962#ifdef WITH_OPENSSL 2938#ifdef WITH_OPENSSL
2963 BIGNUM *exponent = NULL; 2939 BIGNUM *exponent = NULL;
2940 BIGNUM *rsa_n = NULL, *rsa_e = NULL, *rsa_d = NULL;
2941 BIGNUM *rsa_iqmp = NULL, *rsa_p = NULL, *rsa_q = NULL;
2942 BIGNUM *dsa_p = NULL, *dsa_q = NULL, *dsa_g = NULL;
2943 BIGNUM *dsa_pub_key = NULL, *dsa_priv_key = NULL;
2964#endif /* WITH_OPENSSL */ 2944#endif /* WITH_OPENSSL */
2965 2945
2966 if (kp != NULL) 2946 if (kp != NULL)
@@ -2975,18 +2955,44 @@ sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **kp)
2975 r = SSH_ERR_ALLOC_FAIL; 2955 r = SSH_ERR_ALLOC_FAIL;
2976 goto out; 2956 goto out;
2977 } 2957 }
2978 if ((r = sshbuf_get_bignum2(buf, k->dsa->p)) != 0 || 2958 if ((dsa_p = BN_new()) == NULL ||
2979 (r = sshbuf_get_bignum2(buf, k->dsa->q)) != 0 || 2959 (dsa_q = BN_new()) == NULL ||
2980 (r = sshbuf_get_bignum2(buf, k->dsa->g)) != 0 || 2960 (dsa_g = BN_new()) == NULL ||
2981 (r = sshbuf_get_bignum2(buf, k->dsa->pub_key)) != 0 || 2961 (dsa_pub_key = BN_new()) == NULL ||
2982 (r = sshbuf_get_bignum2(buf, k->dsa->priv_key)) != 0) 2962 (dsa_priv_key = BN_new()) == NULL) {
2963 r = SSH_ERR_ALLOC_FAIL;
2964 goto out;
2965 }
2966 if ((r = sshbuf_get_bignum2(buf, dsa_p)) != 0 ||
2967 (r = sshbuf_get_bignum2(buf, dsa_q)) != 0 ||
2968 (r = sshbuf_get_bignum2(buf, dsa_g)) != 0 ||
2969 (r = sshbuf_get_bignum2(buf, dsa_pub_key)) != 0 ||
2970 (r = sshbuf_get_bignum2(buf, dsa_priv_key)) != 0)
2983 goto out; 2971 goto out;
2972 if (!DSA_set0_pqg(k->dsa, dsa_p, dsa_q, dsa_g)) {
2973 r = SSH_ERR_LIBCRYPTO_ERROR;
2974 goto out;
2975 }
2976 dsa_p = dsa_q = dsa_g = NULL; /* transferred */
2977 if (!DSA_set0_key(k->dsa, dsa_pub_key, dsa_priv_key)) {
2978 r = SSH_ERR_LIBCRYPTO_ERROR;
2979 goto out;
2980 }
2981 dsa_pub_key = dsa_priv_key = NULL; /* transferred */
2984 break; 2982 break;
2985 case KEY_DSA_CERT: 2983 case KEY_DSA_CERT:
2984 if ((dsa_priv_key = BN_new()) == NULL) {
2985 r = SSH_ERR_ALLOC_FAIL;
2986 goto out;
2987 }
2986 if ((r = sshkey_froms(buf, &k)) != 0 || 2988 if ((r = sshkey_froms(buf, &k)) != 0 ||
2987 (r = sshkey_add_private(k)) != 0 || 2989 (r = sshbuf_get_bignum2(buf, dsa_priv_key)) != 0)
2988 (r = sshbuf_get_bignum2(buf, k->dsa->priv_key)) != 0) 2990 goto out;
2991 if (!DSA_set0_key(k->dsa, NULL, dsa_priv_key)) {
2992 r = SSH_ERR_LIBCRYPTO_ERROR;
2989 goto out; 2993 goto out;
2994 }
2995 dsa_priv_key = NULL; /* transferred */
2990 break; 2996 break;
2991# ifdef OPENSSL_HAS_ECC 2997# ifdef OPENSSL_HAS_ECC
2992 case KEY_ECDSA: 2998 case KEY_ECDSA:
@@ -3027,7 +3033,6 @@ sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **kp)
3027 goto out; 3033 goto out;
3028 } 3034 }
3029 if ((r = sshkey_froms(buf, &k)) != 0 || 3035 if ((r = sshkey_froms(buf, &k)) != 0 ||
3030 (r = sshkey_add_private(k)) != 0 ||
3031 (r = sshbuf_get_bignum2(buf, exponent)) != 0) 3036 (r = sshbuf_get_bignum2(buf, exponent)) != 0)
3032 goto out; 3037 goto out;
3033 if (EC_KEY_set_private_key(k->ecdsa, exponent) != 1) { 3038 if (EC_KEY_set_private_key(k->ecdsa, exponent) != 1) {
@@ -3045,32 +3050,65 @@ sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **kp)
3045 r = SSH_ERR_ALLOC_FAIL; 3050 r = SSH_ERR_ALLOC_FAIL;
3046 goto out; 3051 goto out;
3047 } 3052 }
3048 if ((r = sshbuf_get_bignum2(buf, k->rsa->n)) != 0 || 3053 if ((rsa_n = BN_new()) == NULL ||
3049 (r = sshbuf_get_bignum2(buf, k->rsa->e)) != 0 || 3054 (rsa_e = BN_new()) == NULL ||
3050 (r = sshbuf_get_bignum2(buf, k->rsa->d)) != 0 || 3055 (rsa_d = BN_new()) == NULL ||
3051 (r = sshbuf_get_bignum2(buf, k->rsa->iqmp)) != 0 || 3056 (rsa_iqmp = BN_new()) == NULL ||
3052 (r = sshbuf_get_bignum2(buf, k->rsa->p)) != 0 || 3057 (rsa_p = BN_new()) == NULL ||
3053 (r = sshbuf_get_bignum2(buf, k->rsa->q)) != 0 || 3058 (rsa_q = BN_new()) == NULL) {
3054 (r = ssh_rsa_generate_additional_parameters(k)) != 0) 3059 r = SSH_ERR_ALLOC_FAIL;
3060 goto out;
3061 }
3062 if ((r = sshbuf_get_bignum2(buf, rsa_n)) != 0 ||
3063 (r = sshbuf_get_bignum2(buf, rsa_e)) != 0 ||
3064 (r = sshbuf_get_bignum2(buf, rsa_d)) != 0 ||
3065 (r = sshbuf_get_bignum2(buf, rsa_iqmp)) != 0 ||
3066 (r = sshbuf_get_bignum2(buf, rsa_p)) != 0 ||
3067 (r = sshbuf_get_bignum2(buf, rsa_q)) != 0)
3055 goto out; 3068 goto out;
3056 if (BN_num_bits(k->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) { 3069 if (!RSA_set0_key(k->rsa, rsa_n, rsa_e, rsa_d)) {
3057 r = SSH_ERR_KEY_LENGTH; 3070 r = SSH_ERR_LIBCRYPTO_ERROR;
3071 goto out;
3072 }
3073 rsa_n = rsa_e = rsa_d = NULL; /* transferred */
3074 if (!RSA_set0_factors(k->rsa, rsa_p, rsa_q)) {
3075 r = SSH_ERR_LIBCRYPTO_ERROR;
3058 goto out; 3076 goto out;
3059 } 3077 }
3078 rsa_p = rsa_q = NULL; /* transferred */
3079 if ((r = check_rsa_length(k->rsa)) != 0)
3080 goto out;
3081 if ((r = ssh_rsa_complete_crt_parameters(k, rsa_iqmp)) != 0)
3082 goto out;
3060 break; 3083 break;
3061 case KEY_RSA_CERT: 3084 case KEY_RSA_CERT:
3085 if ((rsa_d = BN_new()) == NULL ||
3086 (rsa_iqmp = BN_new()) == NULL ||
3087 (rsa_p = BN_new()) == NULL ||
3088 (rsa_q = BN_new()) == NULL) {
3089 r = SSH_ERR_ALLOC_FAIL;
3090 goto out;
3091 }
3062 if ((r = sshkey_froms(buf, &k)) != 0 || 3092 if ((r = sshkey_froms(buf, &k)) != 0 ||
3063 (r = sshkey_add_private(k)) != 0 || 3093 (r = sshbuf_get_bignum2(buf, rsa_d)) != 0 ||
3064 (r = sshbuf_get_bignum2(buf, k->rsa->d)) != 0 || 3094 (r = sshbuf_get_bignum2(buf, rsa_iqmp)) != 0 ||
3065 (r = sshbuf_get_bignum2(buf, k->rsa->iqmp)) != 0 || 3095 (r = sshbuf_get_bignum2(buf, rsa_p)) != 0 ||
3066 (r = sshbuf_get_bignum2(buf, k->rsa->p)) != 0 || 3096 (r = sshbuf_get_bignum2(buf, rsa_q)) != 0)
3067 (r = sshbuf_get_bignum2(buf, k->rsa->q)) != 0 || 3097 goto out;
3068 (r = ssh_rsa_generate_additional_parameters(k)) != 0) 3098 if (!RSA_set0_key(k->rsa, NULL, NULL, rsa_d)) {
3099 r = SSH_ERR_LIBCRYPTO_ERROR;
3069 goto out; 3100 goto out;
3070 if (BN_num_bits(k->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) { 3101 }
3071 r = SSH_ERR_KEY_LENGTH; 3102 rsa_d = NULL; /* transferred */
3103 if (!RSA_set0_factors(k->rsa, rsa_p, rsa_q)) {
3104 r = SSH_ERR_LIBCRYPTO_ERROR;
3072 goto out; 3105 goto out;
3073 } 3106 }
3107 rsa_p = rsa_q = NULL; /* transferred */
3108 if ((r = check_rsa_length(k->rsa)) != 0)
3109 goto out;
3110 if ((r = ssh_rsa_complete_crt_parameters(k, rsa_iqmp)) != 0)
3111 goto out;
3074 break; 3112 break;
3075#endif /* WITH_OPENSSL */ 3113#endif /* WITH_OPENSSL */
3076 case KEY_ED25519: 3114 case KEY_ED25519:
@@ -3091,7 +3129,6 @@ sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **kp)
3091 break; 3129 break;
3092 case KEY_ED25519_CERT: 3130 case KEY_ED25519_CERT:
3093 if ((r = sshkey_froms(buf, &k)) != 0 || 3131 if ((r = sshkey_froms(buf, &k)) != 0 ||
3094 (r = sshkey_add_private(k)) != 0 ||
3095 (r = sshbuf_get_string(buf, &ed25519_pk, &pklen)) != 0 || 3132 (r = sshbuf_get_string(buf, &ed25519_pk, &pklen)) != 0 ||
3096 (r = sshbuf_get_string(buf, &ed25519_sk, &sklen)) != 0) 3133 (r = sshbuf_get_string(buf, &ed25519_sk, &sklen)) != 0)
3097 goto out; 3134 goto out;
@@ -3128,7 +3165,6 @@ sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **kp)
3128 break; 3165 break;
3129 case KEY_XMSS_CERT: 3166 case KEY_XMSS_CERT:
3130 if ((r = sshkey_froms(buf, &k)) != 0 || 3167 if ((r = sshkey_froms(buf, &k)) != 0 ||
3131 (r = sshkey_add_private(k)) != 0 ||
3132 (r = sshbuf_get_cstring(buf, &xmss_name, NULL)) != 0 || 3168 (r = sshbuf_get_cstring(buf, &xmss_name, NULL)) != 0 ||
3133 (r = sshbuf_get_string(buf, &xmss_pk, &pklen)) != 0 || 3169 (r = sshbuf_get_string(buf, &xmss_pk, &pklen)) != 0 ||
3134 (r = sshbuf_get_string(buf, &xmss_sk, &sklen)) != 0) 3170 (r = sshbuf_get_string(buf, &xmss_sk, &sklen)) != 0)
@@ -3177,6 +3213,17 @@ sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **kp)
3177 free(curve); 3213 free(curve);
3178#ifdef WITH_OPENSSL 3214#ifdef WITH_OPENSSL
3179 BN_clear_free(exponent); 3215 BN_clear_free(exponent);
3216 BN_clear_free(dsa_p);
3217 BN_clear_free(dsa_q);
3218 BN_clear_free(dsa_g);
3219 BN_clear_free(dsa_pub_key);
3220 BN_clear_free(dsa_priv_key);
3221 BN_clear_free(rsa_n);
3222 BN_clear_free(rsa_e);
3223 BN_clear_free(rsa_d);
3224 BN_clear_free(rsa_p);
3225 BN_clear_free(rsa_q);
3226 BN_clear_free(rsa_iqmp);
3180#endif /* WITH_OPENSSL */ 3227#endif /* WITH_OPENSSL */
3181 sshkey_free(k); 3228 sshkey_free(k);
3182 freezero(ed25519_pk, pklen); 3229 freezero(ed25519_pk, pklen);
@@ -3831,7 +3878,9 @@ translate_libcrypto_error(unsigned long pem_err)
3831 switch (pem_reason) { 3878 switch (pem_reason) {
3832 case EVP_R_BAD_DECRYPT: 3879 case EVP_R_BAD_DECRYPT:
3833 return SSH_ERR_KEY_WRONG_PASSPHRASE; 3880 return SSH_ERR_KEY_WRONG_PASSPHRASE;
3881#ifdef EVP_R_BN_DECODE_ERROR
3834 case EVP_R_BN_DECODE_ERROR: 3882 case EVP_R_BN_DECODE_ERROR:
3883#endif
3835 case EVP_R_DECODE_ERROR: 3884 case EVP_R_DECODE_ERROR:
3836#ifdef EVP_R_PRIVATE_KEY_DECODE_ERROR 3885#ifdef EVP_R_PRIVATE_KEY_DECODE_ERROR
3837 case EVP_R_PRIVATE_KEY_DECODE_ERROR: 3886 case EVP_R_PRIVATE_KEY_DECODE_ERROR:
@@ -3896,7 +3945,7 @@ sshkey_parse_private_pem_fileblob(struct sshbuf *blob, int type,
3896 r = convert_libcrypto_error(); 3945 r = convert_libcrypto_error();
3897 goto out; 3946 goto out;
3898 } 3947 }
3899 if (pk->type == EVP_PKEY_RSA && 3948 if (EVP_PKEY_base_id(pk) == EVP_PKEY_RSA &&
3900 (type == KEY_UNSPEC || type == KEY_RSA)) { 3949 (type == KEY_UNSPEC || type == KEY_RSA)) {
3901 if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) { 3950 if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) {
3902 r = SSH_ERR_ALLOC_FAIL; 3951 r = SSH_ERR_ALLOC_FAIL;
@@ -3911,11 +3960,9 @@ sshkey_parse_private_pem_fileblob(struct sshbuf *blob, int type,
3911 r = SSH_ERR_LIBCRYPTO_ERROR; 3960 r = SSH_ERR_LIBCRYPTO_ERROR;
3912 goto out; 3961 goto out;
3913 } 3962 }
3914 if (BN_num_bits(prv->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) { 3963 if ((r = check_rsa_length(prv->rsa)) != 0)
3915 r = SSH_ERR_KEY_LENGTH;
3916 goto out; 3964 goto out;
3917 } 3965 } else if (EVP_PKEY_base_id(pk) == EVP_PKEY_DSA &&
3918 } else if (pk->type == EVP_PKEY_DSA &&
3919 (type == KEY_UNSPEC || type == KEY_DSA)) { 3966 (type == KEY_UNSPEC || type == KEY_DSA)) {
3920 if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) { 3967 if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) {
3921 r = SSH_ERR_ALLOC_FAIL; 3968 r = SSH_ERR_ALLOC_FAIL;
@@ -3927,7 +3974,7 @@ sshkey_parse_private_pem_fileblob(struct sshbuf *blob, int type,
3927 DSA_print_fp(stderr, prv->dsa, 8); 3974 DSA_print_fp(stderr, prv->dsa, 8);
3928#endif 3975#endif
3929#ifdef OPENSSL_HAS_ECC 3976#ifdef OPENSSL_HAS_ECC
3930 } else if (pk->type == EVP_PKEY_EC && 3977 } else if (EVP_PKEY_base_id(pk) == EVP_PKEY_EC &&
3931 (type == KEY_UNSPEC || type == KEY_ECDSA)) { 3978 (type == KEY_UNSPEC || type == KEY_ECDSA)) {
3932 if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) { 3979 if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) {
3933 r = SSH_ERR_ALLOC_FAIL; 3980 r = SSH_ERR_ALLOC_FAIL;
diff --git a/sshkey.h b/sshkey.h
index 5a22a66f5..4147ad92b 100644
--- a/sshkey.h
+++ b/sshkey.h
@@ -39,6 +39,7 @@
39# define EC_POINT void 39# define EC_POINT void
40# endif /* OPENSSL_HAS_ECC */ 40# endif /* OPENSSL_HAS_ECC */
41#else /* WITH_OPENSSL */ 41#else /* WITH_OPENSSL */
42# define BIGNUM void
42# define RSA void 43# define RSA void
43# define DSA void 44# define DSA void
44# define EC_KEY void 45# define EC_KEY void
@@ -127,10 +128,8 @@ struct sshkey {
127#define ED25519_PK_SZ crypto_sign_ed25519_PUBLICKEYBYTES 128#define ED25519_PK_SZ crypto_sign_ed25519_PUBLICKEYBYTES
128 129
129struct sshkey *sshkey_new(int); 130struct sshkey *sshkey_new(int);
130int sshkey_add_private(struct sshkey *); 131struct sshkey *sshkey_new_private(int); /* XXX garbage collect */
131struct sshkey *sshkey_new_private(int);
132void sshkey_free(struct sshkey *); 132void sshkey_free(struct sshkey *);
133int sshkey_demote(const struct sshkey *, struct sshkey **);
134int sshkey_equal_public(const struct sshkey *, 133int sshkey_equal_public(const struct sshkey *,
135 const struct sshkey *); 134 const struct sshkey *);
136int sshkey_equal(const struct sshkey *, const struct sshkey *); 135int sshkey_equal(const struct sshkey *, const struct sshkey *);
@@ -220,7 +219,7 @@ int sshkey_parse_private_fileblob_type(struct sshbuf *blob, int type,
220 const char *passphrase, struct sshkey **keyp, char **commentp); 219 const char *passphrase, struct sshkey **keyp, char **commentp);
221 220
222/* XXX should be internal, but used by ssh-keygen */ 221/* XXX should be internal, but used by ssh-keygen */
223int ssh_rsa_generate_additional_parameters(struct sshkey *); 222int ssh_rsa_complete_crt_parameters(struct sshkey *, const BIGNUM *);
224 223
225/* stateful keys (e.g. XMSS) */ 224/* stateful keys (e.g. XMSS) */
226#ifdef NO_ATTRIBUTE_ON_PROTOTYPE_ARGS 225#ifdef NO_ATTRIBUTE_ON_PROTOTYPE_ARGS