diff options
Diffstat (limited to 'dh.c')
-rw-r--r-- | dh.c | 74 |
1 files changed, 47 insertions, 27 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: dh.c,v 1.49 2011/12/07 05:44:38 djm Exp $ */ | 1 | /* $OpenBSD: dh.c,v 1.51 2013/07/02 12:31:43 markus Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2000 Niels Provos. All rights reserved. | 3 | * Copyright (c) 2000 Niels Provos. All rights reserved. |
4 | * | 4 | * |
@@ -48,6 +48,7 @@ parse_prime(int linenum, char *line, struct dhgroup *dhg) | |||
48 | const char *errstr = NULL; | 48 | const char *errstr = NULL; |
49 | long long n; | 49 | long long n; |
50 | 50 | ||
51 | dhg->p = dhg->g = NULL; | ||
51 | cp = line; | 52 | cp = line; |
52 | if ((arg = strdelim(&cp)) == NULL) | 53 | if ((arg = strdelim(&cp)) == NULL) |
53 | return 0; | 54 | return 0; |
@@ -59,66 +60,85 @@ parse_prime(int linenum, char *line, struct dhgroup *dhg) | |||
59 | 60 | ||
60 | /* time */ | 61 | /* time */ |
61 | if (cp == NULL || *arg == '\0') | 62 | if (cp == NULL || *arg == '\0') |
62 | goto fail; | 63 | goto truncated; |
63 | arg = strsep(&cp, " "); /* type */ | 64 | arg = strsep(&cp, " "); /* type */ |
64 | if (cp == NULL || *arg == '\0') | 65 | if (cp == NULL || *arg == '\0') |
65 | goto fail; | 66 | goto truncated; |
66 | /* Ensure this is a safe prime */ | 67 | /* Ensure this is a safe prime */ |
67 | n = strtonum(arg, 0, 5, &errstr); | 68 | n = strtonum(arg, 0, 5, &errstr); |
68 | if (errstr != NULL || n != MODULI_TYPE_SAFE) | 69 | if (errstr != NULL || n != MODULI_TYPE_SAFE) { |
70 | error("moduli:%d: type is not %d", linenum, MODULI_TYPE_SAFE); | ||
69 | goto fail; | 71 | goto fail; |
72 | } | ||
70 | arg = strsep(&cp, " "); /* tests */ | 73 | arg = strsep(&cp, " "); /* tests */ |
71 | if (cp == NULL || *arg == '\0') | 74 | if (cp == NULL || *arg == '\0') |
72 | goto fail; | 75 | goto truncated; |
73 | /* Ensure prime has been tested and is not composite */ | 76 | /* Ensure prime has been tested and is not composite */ |
74 | n = strtonum(arg, 0, 0x1f, &errstr); | 77 | n = strtonum(arg, 0, 0x1f, &errstr); |
75 | if (errstr != NULL || | 78 | if (errstr != NULL || |
76 | (n & MODULI_TESTS_COMPOSITE) || !(n & ~MODULI_TESTS_COMPOSITE)) | 79 | (n & MODULI_TESTS_COMPOSITE) || !(n & ~MODULI_TESTS_COMPOSITE)) { |
80 | error("moduli:%d: invalid moduli tests flag", linenum); | ||
77 | goto fail; | 81 | goto fail; |
82 | } | ||
78 | arg = strsep(&cp, " "); /* tries */ | 83 | arg = strsep(&cp, " "); /* tries */ |
79 | if (cp == NULL || *arg == '\0') | 84 | if (cp == NULL || *arg == '\0') |
80 | goto fail; | 85 | goto truncated; |
81 | n = strtonum(arg, 0, 1<<30, &errstr); | 86 | n = strtonum(arg, 0, 1<<30, &errstr); |
82 | if (errstr != NULL || n == 0) | 87 | if (errstr != NULL || n == 0) { |
88 | error("moduli:%d: invalid primality trial count", linenum); | ||
83 | goto fail; | 89 | goto fail; |
90 | } | ||
84 | strsize = strsep(&cp, " "); /* size */ | 91 | strsize = strsep(&cp, " "); /* size */ |
85 | if (cp == NULL || *strsize == '\0' || | 92 | if (cp == NULL || *strsize == '\0' || |
86 | (dhg->size = (int)strtonum(strsize, 0, 64*1024, &errstr)) == 0 || | 93 | (dhg->size = (int)strtonum(strsize, 0, 64*1024, &errstr)) == 0 || |
87 | errstr) | 94 | errstr) { |
95 | error("moduli:%d: invalid prime length", linenum); | ||
88 | goto fail; | 96 | goto fail; |
97 | } | ||
89 | /* The whole group is one bit larger */ | 98 | /* The whole group is one bit larger */ |
90 | dhg->size++; | 99 | dhg->size++; |
91 | gen = strsep(&cp, " "); /* gen */ | 100 | gen = strsep(&cp, " "); /* gen */ |
92 | if (cp == NULL || *gen == '\0') | 101 | if (cp == NULL || *gen == '\0') |
93 | goto fail; | 102 | goto truncated; |
94 | prime = strsep(&cp, " "); /* prime */ | 103 | prime = strsep(&cp, " "); /* prime */ |
95 | if (cp != NULL || *prime == '\0') | 104 | if (cp != NULL || *prime == '\0') { |
105 | truncated: | ||
106 | error("moduli:%d: truncated", linenum); | ||
96 | goto fail; | 107 | goto fail; |
108 | } | ||
97 | 109 | ||
98 | if ((dhg->g = BN_new()) == NULL) | 110 | if ((dhg->g = BN_new()) == NULL) |
99 | fatal("parse_prime: BN_new failed"); | 111 | fatal("parse_prime: BN_new failed"); |
100 | if ((dhg->p = BN_new()) == NULL) | 112 | if ((dhg->p = BN_new()) == NULL) |
101 | fatal("parse_prime: BN_new failed"); | 113 | fatal("parse_prime: BN_new failed"); |
102 | if (BN_hex2bn(&dhg->g, gen) == 0) | 114 | if (BN_hex2bn(&dhg->g, gen) == 0) { |
103 | goto failclean; | 115 | error("moduli:%d: could not parse generator value", linenum); |
104 | 116 | goto fail; | |
105 | if (BN_hex2bn(&dhg->p, prime) == 0) | 117 | } |
106 | goto failclean; | 118 | if (BN_hex2bn(&dhg->p, prime) == 0) { |
107 | 119 | error("moduli:%d: could not parse prime value", linenum); | |
108 | if (BN_num_bits(dhg->p) != dhg->size) | 120 | goto fail; |
109 | goto failclean; | 121 | } |
110 | 122 | if (BN_num_bits(dhg->p) != dhg->size) { | |
111 | if (BN_is_zero(dhg->g) || BN_is_one(dhg->g)) | 123 | error("moduli:%d: prime has wrong size: actual %d listed %d", |
112 | goto failclean; | 124 | linenum, BN_num_bits(dhg->p), dhg->size - 1); |
125 | goto fail; | ||
126 | } | ||
127 | if (BN_cmp(dhg->g, BN_value_one()) <= 0) { | ||
128 | error("moduli:%d: generator is invalid", linenum); | ||
129 | goto fail; | ||
130 | } | ||
113 | 131 | ||
114 | return (1); | 132 | return 1; |
115 | 133 | ||
116 | failclean: | ||
117 | BN_clear_free(dhg->g); | ||
118 | BN_clear_free(dhg->p); | ||
119 | fail: | 134 | fail: |
135 | if (dhg->g != NULL) | ||
136 | BN_clear_free(dhg->g); | ||
137 | if (dhg->p != NULL) | ||
138 | BN_clear_free(dhg->p); | ||
139 | dhg->g = dhg->p = NULL; | ||
120 | error("Bad prime description in line %d", linenum); | 140 | error("Bad prime description in line %d", linenum); |
121 | return (0); | 141 | return 0; |
122 | } | 142 | } |
123 | 143 | ||
124 | DH * | 144 | DH * |