diff options
-rw-r--r-- | auth2.c | 4 | ||||
-rw-r--r-- | cipher.c | 16 | ||||
-rw-r--r-- | cipher.h | 4 | ||||
-rw-r--r-- | dh.c | 60 | ||||
-rw-r--r-- | dh.h | 2 | ||||
-rw-r--r-- | digest-openssl.c | 26 | ||||
-rw-r--r-- | kexdhc.c | 15 | ||||
-rw-r--r-- | kexdhs.c | 11 | ||||
-rw-r--r-- | kexgexc.c | 18 | ||||
-rw-r--r-- | kexgexs.c | 21 | ||||
-rw-r--r-- | monitor.c | 6 | ||||
-rw-r--r-- | ssh-dss.c | 26 | ||||
-rw-r--r-- | ssh-ecdsa.c | 23 | ||||
-rw-r--r-- | ssh-keygen.c | 61 | ||||
-rw-r--r-- | ssh-pkcs11-client.c | 12 | ||||
-rw-r--r-- | ssh-pkcs11.c | 55 | ||||
-rw-r--r-- | ssh-rsa.c | 47 | ||||
-rw-r--r-- | sshd.c | 6 | ||||
-rw-r--r-- | sshkey.c | 637 | ||||
-rw-r--r-- | sshkey.h | 7 |
20 files changed, 619 insertions, 438 deletions
@@ -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, |
@@ -446,7 +446,7 @@ cipher_get_keyiv_len(const struct sshcipher_ctx *cc) | |||
446 | } | 446 | } |
447 | 447 | ||
448 | int | 448 | int |
449 | cipher_get_keyiv(struct sshcipher_ctx *cc, u_char *iv, u_int len) | 449 | cipher_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 | ||
493 | int | 493 | int |
494 | cipher_set_keyiv(struct sshcipher_ctx *cc, const u_char *iv) | 494 | cipher_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 | } |
@@ -68,8 +68,8 @@ u_int cipher_is_cbc(const struct sshcipher *); | |||
68 | 68 | ||
69 | u_int cipher_ctx_is_plaintext(struct sshcipher_ctx *); | 69 | u_int cipher_ctx_is_plaintext(struct sshcipher_ctx *); |
70 | 70 | ||
71 | int cipher_get_keyiv(struct sshcipher_ctx *, u_char *, u_int); | 71 | int cipher_get_keyiv(struct sshcipher_ctx *, u_char *, size_t); |
72 | int cipher_set_keyiv(struct sshcipher_ctx *, const u_char *); | 72 | int cipher_set_keyiv(struct sshcipher_ctx *, const u_char *, size_t); |
73 | int cipher_get_keyiv_len(const struct sshcipher_ctx *); | 73 | int cipher_get_keyiv_len(const struct sshcipher_ctx *); |
74 | 74 | ||
75 | #endif /* CIPHER_H */ | 75 | #endif /* CIPHER_H */ |
@@ -216,14 +216,17 @@ choose_dh(int min, int wantbits, int max) | |||
216 | /* diffie-hellman-groupN-sha1 */ | 216 | /* diffie-hellman-groupN-sha1 */ |
217 | 217 | ||
218 | int | 218 | int |
219 | dh_pub_is_valid(DH *dh, BIGNUM *dh_pub) | 219 | dh_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 | |||
264 | dh_gen_key(DH *dh, int need) | 267 | dh_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 * | |||
289 | dh_new_group_asc(const char *gen, const char *modulus) | 296 | dh_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 | |||
308 | DH * | 320 | DH * |
309 | dh_new_group(BIGNUM *gen, BIGNUM *modulus) | 321 | dh_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) */ |
@@ -42,7 +42,7 @@ DH *dh_new_group18(void); | |||
42 | DH *dh_new_group_fallback(int); | 42 | DH *dh_new_group_fallback(int); |
43 | 43 | ||
44 | int dh_gen_key(DH *, int); | 44 | int dh_gen_key(DH *, int); |
45 | int dh_pub_is_valid(DH *, BIGNUM *); | 45 | int dh_pub_is_valid(const DH *, const BIGNUM *); |
46 | 46 | ||
47 | u_int dh_estimate(int); | 47 | u_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 | ||
44 | struct ssh_digest_ctx { | 44 | struct ssh_digest_ctx { |
45 | int alg; | 45 | int alg; |
46 | EVP_MD_CTX mdctx; | 46 | EVP_MD_CTX *mdctx; |
47 | }; | 47 | }; |
48 | 48 | ||
49 | struct ssh_digest { | 49 | struct ssh_digest { |
@@ -106,7 +106,7 @@ ssh_digest_bytes(int alg) | |||
106 | size_t | 106 | size_t |
107 | ssh_digest_blocksize(struct ssh_digest_ctx *ctx) | 107 | ssh_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 | ||
112 | struct ssh_digest_ctx * | 112 | struct 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) | |||
140 | int | 143 | int |
141 | ssh_digest_update(struct ssh_digest_ctx *ctx, const void *m, size_t mlen) | 144 | ssh_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) | |||
171 | void | 174 | void |
172 | ssh_digest_free(struct ssh_digest_ctx *ctx) | 175 | ssh_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 | ||
181 | int | 183 | int |
@@ -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) |
@@ -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; |
@@ -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) |
@@ -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; |
@@ -566,6 +566,7 @@ int | |||
566 | mm_answer_moduli(int sock, struct sshbuf *m) | 566 | mm_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); |
@@ -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, | |||
156 | static int | 156 | static int |
157 | wrap_key(RSA *rsa) | 157 | wrap_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 | ||
447 | static int | 453 | static int |
454 | have_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 | |||
462 | static int | ||
448 | pkcs11_fetch_keys_filter(struct pkcs11_provider *p, CK_ULONG slotidx, | 463 | pkcs11_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"); |
@@ -104,38 +104,55 @@ rsa_hash_alg_nid(int type) | |||
104 | } | 104 | } |
105 | 105 | ||
106 | int | 106 | int |
107 | ssh_rsa_generate_additional_parameters(struct sshkey *key) | 107 | ssh_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 | |||
145 | ssh_rsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp, | 162 | ssh_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) |
@@ -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; |
@@ -289,14 +289,24 @@ sshkey_names_valid2(const char *names, int allow_wildcard) | |||
289 | u_int | 289 | u_int |
290 | sshkey_size(const struct sshkey *k) | 290 | sshkey_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 | ||
556 | int | 558 | /* XXX garbage-collect this API */ |
557 | sshkey_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 | |||
597 | struct sshkey * | 559 | struct sshkey * |
598 | sshkey_new_private(int type) | 560 | sshkey_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) | |||
686 | int | 644 | int |
687 | sshkey_equal_public(const struct sshkey *a, const struct sshkey *b) | 645 | sshkey_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 | ||
1863 | static int | 1886 | static int |
@@ -1986,6 +2009,17 @@ cert_parse(struct sshbuf *b, struct sshkey *key, struct sshbuf *certbuf) | |||
1986 | } | 2009 | } |
1987 | 2010 | ||
1988 | static int | 2011 | static int |
2012 | check_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 | |||
2022 | static int | ||
1989 | sshkey_from_blob_internal(struct sshbuf *b, struct sshkey **keyp, | 2023 | sshkey_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 */ | ||
2405 | int | ||
2406 | sshkey_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 */ |
2519 | int | 2476 | int |
2520 | sshkey_to_certified(struct sshkey *k) | 2477 | sshkey_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; |
@@ -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 | ||
129 | struct sshkey *sshkey_new(int); | 130 | struct sshkey *sshkey_new(int); |
130 | int sshkey_add_private(struct sshkey *); | 131 | struct sshkey *sshkey_new_private(int); /* XXX garbage collect */ |
131 | struct sshkey *sshkey_new_private(int); | ||
132 | void sshkey_free(struct sshkey *); | 132 | void sshkey_free(struct sshkey *); |
133 | int sshkey_demote(const struct sshkey *, struct sshkey **); | ||
134 | int sshkey_equal_public(const struct sshkey *, | 133 | int sshkey_equal_public(const struct sshkey *, |
135 | const struct sshkey *); | 134 | const struct sshkey *); |
136 | int sshkey_equal(const struct sshkey *, const struct sshkey *); | 135 | int 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 */ |
223 | int ssh_rsa_generate_additional_parameters(struct sshkey *); | 222 | int 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 |