diff options
Diffstat (limited to 'dh.c')
-rw-r--r-- | dh.c | 59 |
1 files changed, 30 insertions, 29 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: dh.c,v 1.53 2013/11/21 00:45:44 djm Exp $ */ | 1 | /* $OpenBSD: dh.c,v 1.54 2015/01/19 20:16:15 markus Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2000 Niels Provos. All rights reserved. | 3 | * Copyright (c) 2000 Niels Provos. All rights reserved. |
4 | * | 4 | * |
@@ -39,6 +39,7 @@ | |||
39 | #include "pathnames.h" | 39 | #include "pathnames.h" |
40 | #include "log.h" | 40 | #include "log.h" |
41 | #include "misc.h" | 41 | #include "misc.h" |
42 | #include "ssherr.h" | ||
42 | 43 | ||
43 | static int | 44 | static int |
44 | parse_prime(int linenum, char *line, struct dhgroup *dhg) | 45 | parse_prime(int linenum, char *line, struct dhgroup *dhg) |
@@ -107,10 +108,11 @@ parse_prime(int linenum, char *line, struct dhgroup *dhg) | |||
107 | goto fail; | 108 | goto fail; |
108 | } | 109 | } |
109 | 110 | ||
110 | if ((dhg->g = BN_new()) == NULL) | 111 | if ((dhg->g = BN_new()) == NULL || |
111 | fatal("parse_prime: BN_new failed"); | 112 | (dhg->p = BN_new()) == NULL) { |
112 | if ((dhg->p = BN_new()) == NULL) | 113 | error("parse_prime: BN_new failed"); |
113 | fatal("parse_prime: BN_new failed"); | 114 | goto fail; |
115 | } | ||
114 | if (BN_hex2bn(&dhg->g, gen) == 0) { | 116 | if (BN_hex2bn(&dhg->g, gen) == 0) { |
115 | error("moduli:%d: could not parse generator value", linenum); | 117 | error("moduli:%d: could not parse generator value", linenum); |
116 | goto fail; | 118 | goto fail; |
@@ -128,7 +130,6 @@ parse_prime(int linenum, char *line, struct dhgroup *dhg) | |||
128 | error("moduli:%d: generator is invalid", linenum); | 130 | error("moduli:%d: generator is invalid", linenum); |
129 | goto fail; | 131 | goto fail; |
130 | } | 132 | } |
131 | |||
132 | return 1; | 133 | return 1; |
133 | 134 | ||
134 | fail: | 135 | fail: |
@@ -137,7 +138,6 @@ parse_prime(int linenum, char *line, struct dhgroup *dhg) | |||
137 | if (dhg->p != NULL) | 138 | if (dhg->p != NULL) |
138 | BN_clear_free(dhg->p); | 139 | BN_clear_free(dhg->p); |
139 | dhg->g = dhg->p = NULL; | 140 | dhg->g = dhg->p = NULL; |
140 | error("Bad prime description in line %d", linenum); | ||
141 | return 0; | 141 | return 0; |
142 | } | 142 | } |
143 | 143 | ||
@@ -200,9 +200,11 @@ choose_dh(int min, int wantbits, int max) | |||
200 | break; | 200 | break; |
201 | } | 201 | } |
202 | fclose(f); | 202 | fclose(f); |
203 | if (linenum != which+1) | 203 | if (linenum != which+1) { |
204 | fatal("WARNING: line %d disappeared in %s, giving up", | 204 | logit("WARNING: line %d disappeared in %s, giving up", |
205 | which, _PATH_DH_PRIMES); | 205 | which, _PATH_DH_PRIMES); |
206 | return (dh_new_group14()); | ||
207 | } | ||
206 | 208 | ||
207 | return (dh_new_group(dhg.g, dhg.p)); | 209 | return (dh_new_group(dhg.g, dhg.p)); |
208 | } | 210 | } |
@@ -251,22 +253,22 @@ dh_pub_is_valid(DH *dh, BIGNUM *dh_pub) | |||
251 | return 0; | 253 | return 0; |
252 | } | 254 | } |
253 | 255 | ||
254 | void | 256 | int |
255 | dh_gen_key(DH *dh, int need) | 257 | dh_gen_key(DH *dh, int need) |
256 | { | 258 | { |
257 | int pbits; | 259 | int pbits; |
258 | 260 | ||
259 | if (need <= 0) | 261 | if (need < 0 || dh->p == NULL || |
260 | fatal("%s: need <= 0", __func__); | 262 | (pbits = BN_num_bits(dh->p)) <= 0 || |
261 | if (dh->p == NULL) | 263 | need > INT_MAX / 2 || 2 * need >= pbits) |
262 | fatal("%s: dh->p == NULL", __func__); | 264 | return SSH_ERR_INVALID_ARGUMENT; |
263 | if ((pbits = BN_num_bits(dh->p)) <= 0) | ||
264 | fatal("%s: bits(p) <= 0", __func__); | ||
265 | dh->length = MIN(need * 2, pbits - 1); | 265 | dh->length = MIN(need * 2, pbits - 1); |
266 | if (DH_generate_key(dh) == 0) | 266 | if (DH_generate_key(dh) == 0 || |
267 | fatal("%s: key generation failed", __func__); | 267 | !dh_pub_is_valid(dh, dh->pub_key)) { |
268 | if (!dh_pub_is_valid(dh, dh->pub_key)) | 268 | BN_clear_free(dh->priv_key); |
269 | fatal("%s: generated invalid key", __func__); | 269 | return SSH_ERR_LIBCRYPTO_ERROR; |
270 | } | ||
271 | return 0; | ||
270 | } | 272 | } |
271 | 273 | ||
272 | DH * | 274 | DH * |
@@ -275,13 +277,12 @@ dh_new_group_asc(const char *gen, const char *modulus) | |||
275 | DH *dh; | 277 | DH *dh; |
276 | 278 | ||
277 | if ((dh = DH_new()) == NULL) | 279 | if ((dh = DH_new()) == NULL) |
278 | fatal("dh_new_group_asc: DH_new"); | 280 | return NULL; |
279 | 281 | if (BN_hex2bn(&dh->p, modulus) == 0 || | |
280 | if (BN_hex2bn(&dh->p, modulus) == 0) | 282 | BN_hex2bn(&dh->g, gen) == 0) { |
281 | fatal("BN_hex2bn p"); | 283 | DH_free(dh); |
282 | if (BN_hex2bn(&dh->g, gen) == 0) | 284 | return NULL; |
283 | fatal("BN_hex2bn g"); | 285 | } |
284 | |||
285 | return (dh); | 286 | return (dh); |
286 | } | 287 | } |
287 | 288 | ||
@@ -296,7 +297,7 @@ dh_new_group(BIGNUM *gen, BIGNUM *modulus) | |||
296 | DH *dh; | 297 | DH *dh; |
297 | 298 | ||
298 | if ((dh = DH_new()) == NULL) | 299 | if ((dh = DH_new()) == NULL) |
299 | fatal("dh_new_group: DH_new"); | 300 | return NULL; |
300 | dh->p = modulus; | 301 | dh->p = modulus; |
301 | dh->g = gen; | 302 | dh->g = gen; |
302 | 303 | ||
@@ -344,7 +345,7 @@ dh_new_group14(void) | |||
344 | * from RFC4419 section 3. | 345 | * from RFC4419 section 3. |
345 | */ | 346 | */ |
346 | 347 | ||
347 | int | 348 | u_int |
348 | dh_estimate(int bits) | 349 | dh_estimate(int bits) |
349 | { | 350 | { |
350 | if (bits <= 112) | 351 | if (bits <= 112) |