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