summaryrefslogtreecommitdiff
path: root/kexgexc.c
diff options
context:
space:
mode:
authordjm@openbsd.org <djm@openbsd.org>2019-01-21 10:03:37 +0000
committerDamien Miller <djm@mindrot.org>2019-01-21 21:47:28 +1100
commitdec5e9d33891e3bc3f1395d7db0e56fdc7f86dfc (patch)
treea91c7543cc726563651cc9eb2603f205ab7b27b1 /kexgexc.c
parente93bd98eab79b9a78f64ee8dd4dffc4d3979c7ae (diff)
upstream: factor out kex_dh_compute_key() - it's shared between
plain DH KEX and DH GEX in both the client and server implementations from markus@ ok djm@ OpenBSD-Commit-ID: 12186e18791fffcd4642c82e7e0cfdd7ea37e2ec
Diffstat (limited to 'kexgexc.c')
-rw-r--r--kexgexc.c45
1 files changed, 11 insertions, 34 deletions
diff --git a/kexgexc.c b/kexgexc.c
index 0425309d4..600d91acc 100644
--- a/kexgexc.c
+++ b/kexgexc.c
@@ -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
143input_kex_dh_gex_reply(int type, u_int32_t seq, struct ssh *ssh) 143input_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);