diff options
Diffstat (limited to 'kexgexc.c')
-rw-r--r-- | kexgexc.c | 45 |
1 files changed, 11 insertions, 34 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: kexgexc.c,v 1.31 2019/01/21 09:55:52 djm Exp $ */ | 1 | /* $OpenBSD: kexgexc.c,v 1.32 2019/01/21 10:03:37 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2000 Niels Provos. All rights reserved. | 3 | * Copyright (c) 2000 Niels Provos. All rights reserved. |
4 | * Copyright (c) 2001 Markus Friedl. All rights reserved. | 4 | * Copyright (c) 2001 Markus Friedl. All rights reserved. |
@@ -143,13 +143,14 @@ static int | |||
143 | input_kex_dh_gex_reply(int type, u_int32_t seq, struct ssh *ssh) | 143 | input_kex_dh_gex_reply(int type, u_int32_t seq, struct ssh *ssh) |
144 | { | 144 | { |
145 | struct kex *kex = ssh->kex; | 145 | struct kex *kex = ssh->kex; |
146 | BIGNUM *dh_server_pub = NULL, *shared_secret = NULL; | 146 | BIGNUM *dh_server_pub = NULL; |
147 | const BIGNUM *pub_key, *dh_p, *dh_g; | 147 | const BIGNUM *pub_key, *dh_p, *dh_g; |
148 | struct sshbuf *shared_secret = NULL; | ||
148 | struct sshkey *server_host_key = NULL; | 149 | struct sshkey *server_host_key = NULL; |
149 | u_char *kbuf = NULL, *signature = NULL, *server_host_key_blob = NULL; | 150 | u_char *signature = NULL, *server_host_key_blob = NULL; |
150 | u_char hash[SSH_DIGEST_MAX_LENGTH]; | 151 | u_char hash[SSH_DIGEST_MAX_LENGTH]; |
151 | size_t klen = 0, slen, sbloblen, hashlen; | 152 | size_t slen, sbloblen, hashlen; |
152 | int kout, r; | 153 | int r; |
153 | 154 | ||
154 | debug("got SSH2_MSG_KEX_DH_GEX_REPLY"); | 155 | debug("got SSH2_MSG_KEX_DH_GEX_REPLY"); |
155 | if (kex->verify_host_key == NULL) { | 156 | if (kex->verify_host_key == NULL) { |
@@ -177,32 +178,12 @@ input_kex_dh_gex_reply(int type, u_int32_t seq, struct ssh *ssh) | |||
177 | (r = sshpkt_get_string(ssh, &signature, &slen)) != 0 || | 178 | (r = sshpkt_get_string(ssh, &signature, &slen)) != 0 || |
178 | (r = sshpkt_get_end(ssh)) != 0) | 179 | (r = sshpkt_get_end(ssh)) != 0) |
179 | goto out; | 180 | goto out; |
180 | #ifdef DEBUG_KEXDH | 181 | if ((shared_secret = sshbuf_new()) == NULL) { |
181 | fprintf(stderr, "dh_server_pub= "); | ||
182 | BN_print_fp(stderr, dh_server_pub); | ||
183 | fprintf(stderr, "\n"); | ||
184 | debug("bits %d", BN_num_bits(dh_server_pub)); | ||
185 | #endif | ||
186 | if (!dh_pub_is_valid(kex->dh, dh_server_pub)) { | ||
187 | sshpkt_disconnect(ssh, "bad server public DH value"); | ||
188 | r = SSH_ERR_MESSAGE_INCOMPLETE; | ||
189 | goto out; | ||
190 | } | ||
191 | |||
192 | klen = DH_size(kex->dh); | ||
193 | if ((kbuf = malloc(klen)) == NULL || | ||
194 | (shared_secret = BN_new()) == NULL) { | ||
195 | r = SSH_ERR_ALLOC_FAIL; | 182 | r = SSH_ERR_ALLOC_FAIL; |
196 | goto out; | 183 | goto out; |
197 | } | 184 | } |
198 | if ((kout = DH_compute_key(kbuf, dh_server_pub, kex->dh)) < 0 || | 185 | if ((r = kex_dh_compute_key(kex, dh_server_pub, shared_secret)) != 0) |
199 | BN_bin2bn(kbuf, kout, shared_secret) == NULL) { | ||
200 | r = SSH_ERR_LIBCRYPTO_ERROR; | ||
201 | goto out; | 186 | goto out; |
202 | } | ||
203 | #ifdef DEBUG_KEXDH | ||
204 | dump_digest("shared secret", kbuf, kout); | ||
205 | #endif | ||
206 | if (ssh->compat & SSH_OLD_DHGEX) | 187 | if (ssh->compat & SSH_OLD_DHGEX) |
207 | kex->min = kex->max = -1; | 188 | kex->min = kex->max = -1; |
208 | 189 | ||
@@ -221,7 +202,7 @@ input_kex_dh_gex_reply(int type, u_int32_t seq, struct ssh *ssh) | |||
221 | dh_p, dh_g, | 202 | dh_p, dh_g, |
222 | pub_key, | 203 | pub_key, |
223 | dh_server_pub, | 204 | dh_server_pub, |
224 | shared_secret, | 205 | sshbuf_ptr(shared_secret), sshbuf_len(shared_secret), |
225 | hash, &hashlen)) != 0) | 206 | hash, &hashlen)) != 0) |
226 | goto out; | 207 | goto out; |
227 | 208 | ||
@@ -229,18 +210,14 @@ input_kex_dh_gex_reply(int type, u_int32_t seq, struct ssh *ssh) | |||
229 | hashlen, kex->hostkey_alg, ssh->compat)) != 0) | 210 | hashlen, kex->hostkey_alg, ssh->compat)) != 0) |
230 | goto out; | 211 | goto out; |
231 | 212 | ||
232 | if ((r = kex_derive_keys_bn(ssh, hash, hashlen, shared_secret)) == 0) | 213 | if ((r = kex_derive_keys(ssh, hash, hashlen, shared_secret)) == 0) |
233 | r = kex_send_newkeys(ssh); | 214 | r = kex_send_newkeys(ssh); |
234 | out: | 215 | out: |
235 | explicit_bzero(hash, sizeof(hash)); | 216 | explicit_bzero(hash, sizeof(hash)); |
236 | DH_free(kex->dh); | 217 | DH_free(kex->dh); |
237 | kex->dh = NULL; | 218 | kex->dh = NULL; |
238 | BN_clear_free(dh_server_pub); | 219 | BN_clear_free(dh_server_pub); |
239 | if (kbuf) { | 220 | sshbuf_free(shared_secret); |
240 | explicit_bzero(kbuf, klen); | ||
241 | free(kbuf); | ||
242 | } | ||
243 | BN_clear_free(shared_secret); | ||
244 | sshkey_free(server_host_key); | 221 | sshkey_free(server_host_key); |
245 | free(server_host_key_blob); | 222 | free(server_host_key_blob); |
246 | free(signature); | 223 | free(signature); |