diff options
Diffstat (limited to 'kexgen.c')
-rw-r--r-- | kexgen.c | 67 |
1 files changed, 38 insertions, 29 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: kexgen.c,v 1.1 2019/01/21 11:22:00 djm Exp $ */ | 1 | /* $OpenBSD: kexgen.c,v 1.2 2019/01/23 00:30:41 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2019 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2019 Markus Friedl. All rights reserved. |
4 | * | 4 | * |
@@ -48,9 +48,9 @@ kex_gen_hash( | |||
48 | int hash_alg, | 48 | int hash_alg, |
49 | const struct sshbuf *client_version, | 49 | const struct sshbuf *client_version, |
50 | const struct sshbuf *server_version, | 50 | const struct sshbuf *server_version, |
51 | const u_char *ckexinit, size_t ckexinitlen, | 51 | const struct sshbuf *client_kexinit, |
52 | const u_char *skexinit, size_t skexinitlen, | 52 | const struct sshbuf *server_kexinit, |
53 | const u_char *serverhostkeyblob, size_t sbloblen, | 53 | const struct sshbuf *server_host_key_blob, |
54 | const struct sshbuf *client_pub, | 54 | const struct sshbuf *client_pub, |
55 | const struct sshbuf *server_pub, | 55 | const struct sshbuf *server_pub, |
56 | const struct sshbuf *shared_secret, | 56 | const struct sshbuf *shared_secret, |
@@ -66,13 +66,13 @@ kex_gen_hash( | |||
66 | if ((r = sshbuf_put_stringb(b, client_version)) != 0 || | 66 | if ((r = sshbuf_put_stringb(b, client_version)) != 0 || |
67 | (r = sshbuf_put_stringb(b, server_version)) != 0 || | 67 | (r = sshbuf_put_stringb(b, server_version)) != 0 || |
68 | /* kexinit messages: fake header: len+SSH2_MSG_KEXINIT */ | 68 | /* kexinit messages: fake header: len+SSH2_MSG_KEXINIT */ |
69 | (r = sshbuf_put_u32(b, ckexinitlen+1)) != 0 || | 69 | (r = sshbuf_put_u32(b, sshbuf_len(client_kexinit) + 1)) != 0 || |
70 | (r = sshbuf_put_u8(b, SSH2_MSG_KEXINIT)) != 0 || | 70 | (r = sshbuf_put_u8(b, SSH2_MSG_KEXINIT)) != 0 || |
71 | (r = sshbuf_put(b, ckexinit, ckexinitlen)) != 0 || | 71 | (r = sshbuf_putb(b, client_kexinit)) != 0 || |
72 | (r = sshbuf_put_u32(b, skexinitlen+1)) != 0 || | 72 | (r = sshbuf_put_u32(b, sshbuf_len(server_kexinit) + 1)) != 0 || |
73 | (r = sshbuf_put_u8(b, SSH2_MSG_KEXINIT)) != 0 || | 73 | (r = sshbuf_put_u8(b, SSH2_MSG_KEXINIT)) != 0 || |
74 | (r = sshbuf_put(b, skexinit, skexinitlen)) != 0 || | 74 | (r = sshbuf_putb(b, server_kexinit)) != 0 || |
75 | (r = sshbuf_put_string(b, serverhostkeyblob, sbloblen)) != 0 || | 75 | (r = sshbuf_put_stringb(b, server_host_key_blob)) != 0 || |
76 | (r = sshbuf_put_stringb(b, client_pub)) != 0 || | 76 | (r = sshbuf_put_stringb(b, client_pub)) != 0 || |
77 | (r = sshbuf_put_stringb(b, server_pub)) != 0 || | 77 | (r = sshbuf_put_stringb(b, server_pub)) != 0 || |
78 | (r = sshbuf_putb(b, shared_secret)) != 0) { | 78 | (r = sshbuf_putb(b, shared_secret)) != 0) { |
@@ -139,16 +139,21 @@ input_kex_gen_reply(int type, u_int32_t seq, struct ssh *ssh) | |||
139 | struct sshkey *server_host_key = NULL; | 139 | struct sshkey *server_host_key = NULL; |
140 | struct sshbuf *shared_secret = NULL; | 140 | struct sshbuf *shared_secret = NULL; |
141 | struct sshbuf *server_blob = NULL; | 141 | struct sshbuf *server_blob = NULL; |
142 | u_char *server_host_key_blob = NULL, *signature = NULL; | 142 | struct sshbuf *tmp = NULL, *server_host_key_blob = NULL; |
143 | u_char *signature = NULL; | ||
143 | u_char hash[SSH_DIGEST_MAX_LENGTH]; | 144 | u_char hash[SSH_DIGEST_MAX_LENGTH]; |
144 | size_t slen, sbloblen, hashlen; | 145 | size_t slen, hashlen; |
145 | int r; | 146 | int r; |
146 | 147 | ||
147 | /* hostkey */ | 148 | /* hostkey */ |
148 | if ((r = sshpkt_get_string(ssh, &server_host_key_blob, | 149 | if ((r = sshpkt_getb_froms(ssh, &server_host_key_blob)) != 0) |
149 | &sbloblen)) != 0 || | 150 | goto out; |
150 | (r = sshkey_from_blob(server_host_key_blob, sbloblen, | 151 | /* sshkey_fromb() consumes its buffer, so make a copy */ |
151 | &server_host_key)) != 0) | 152 | if ((tmp = sshbuf_fromb(server_host_key_blob)) == NULL) { |
153 | r = SSH_ERR_ALLOC_FAIL; | ||
154 | goto out; | ||
155 | } | ||
156 | if ((r = sshkey_fromb(tmp, &server_host_key)) != 0) | ||
152 | goto out; | 157 | goto out; |
153 | if ((r = kex_verify_host_key(ssh, server_host_key)) != 0) | 158 | if ((r = kex_verify_host_key(ssh, server_host_key)) != 0) |
154 | goto out; | 159 | goto out; |
@@ -192,9 +197,9 @@ input_kex_gen_reply(int type, u_int32_t seq, struct ssh *ssh) | |||
192 | kex->hash_alg, | 197 | kex->hash_alg, |
193 | kex->client_version, | 198 | kex->client_version, |
194 | kex->server_version, | 199 | kex->server_version, |
195 | sshbuf_ptr(kex->my), sshbuf_len(kex->my), | 200 | kex->my, |
196 | sshbuf_ptr(kex->peer), sshbuf_len(kex->peer), | 201 | kex->peer, |
197 | server_host_key_blob, sbloblen, | 202 | server_host_key_blob, |
198 | kex->client_pub, | 203 | kex->client_pub, |
199 | server_blob, | 204 | server_blob, |
200 | shared_secret, | 205 | shared_secret, |
@@ -212,8 +217,9 @@ out: | |||
212 | explicit_bzero(kex->c25519_client_key, sizeof(kex->c25519_client_key)); | 217 | explicit_bzero(kex->c25519_client_key, sizeof(kex->c25519_client_key)); |
213 | explicit_bzero(kex->sntrup4591761_client_key, | 218 | explicit_bzero(kex->sntrup4591761_client_key, |
214 | sizeof(kex->sntrup4591761_client_key)); | 219 | sizeof(kex->sntrup4591761_client_key)); |
215 | free(server_host_key_blob); | 220 | sshbuf_free(server_host_key_blob); |
216 | free(signature); | 221 | free(signature); |
222 | sshbuf_free(tmp); | ||
217 | sshkey_free(server_host_key); | 223 | sshkey_free(server_host_key); |
218 | sshbuf_free(server_blob); | 224 | sshbuf_free(server_blob); |
219 | sshbuf_free(shared_secret); | 225 | sshbuf_free(shared_secret); |
@@ -238,9 +244,9 @@ input_kex_gen_init(int type, u_int32_t seq, struct ssh *ssh) | |||
238 | struct sshbuf *shared_secret = NULL; | 244 | struct sshbuf *shared_secret = NULL; |
239 | struct sshbuf *server_pubkey = NULL; | 245 | struct sshbuf *server_pubkey = NULL; |
240 | struct sshbuf *client_pubkey = NULL; | 246 | struct sshbuf *client_pubkey = NULL; |
241 | u_char *server_host_key_blob = NULL, *signature = NULL; | 247 | struct sshbuf *server_host_key_blob = NULL; |
242 | u_char hash[SSH_DIGEST_MAX_LENGTH]; | 248 | u_char *signature = NULL, hash[SSH_DIGEST_MAX_LENGTH]; |
243 | size_t slen, sbloblen, hashlen; | 249 | size_t slen, hashlen; |
244 | int r; | 250 | int r; |
245 | 251 | ||
246 | if ((r = kex_load_hostkey(ssh, &server_host_private, | 252 | if ((r = kex_load_hostkey(ssh, &server_host_private, |
@@ -281,17 +287,20 @@ input_kex_gen_init(int type, u_int32_t seq, struct ssh *ssh) | |||
281 | goto out; | 287 | goto out; |
282 | 288 | ||
283 | /* calc H */ | 289 | /* calc H */ |
284 | if ((r = sshkey_to_blob(server_host_public, &server_host_key_blob, | 290 | if ((server_host_key_blob = sshbuf_new()) == NULL) { |
285 | &sbloblen)) != 0) | 291 | r = SSH_ERR_ALLOC_FAIL; |
292 | goto out; | ||
293 | } | ||
294 | if ((r = sshkey_putb(server_host_public, server_host_key_blob)) != 0) | ||
286 | goto out; | 295 | goto out; |
287 | hashlen = sizeof(hash); | 296 | hashlen = sizeof(hash); |
288 | if ((r = kex_gen_hash( | 297 | if ((r = kex_gen_hash( |
289 | kex->hash_alg, | 298 | kex->hash_alg, |
290 | kex->client_version, | 299 | kex->client_version, |
291 | kex->server_version, | 300 | kex->server_version, |
292 | sshbuf_ptr(kex->peer), sshbuf_len(kex->peer), | 301 | kex->peer, |
293 | sshbuf_ptr(kex->my), sshbuf_len(kex->my), | 302 | kex->my, |
294 | server_host_key_blob, sbloblen, | 303 | server_host_key_blob, |
295 | client_pubkey, | 304 | client_pubkey, |
296 | server_pubkey, | 305 | server_pubkey, |
297 | shared_secret, | 306 | shared_secret, |
@@ -305,7 +314,7 @@ input_kex_gen_init(int type, u_int32_t seq, struct ssh *ssh) | |||
305 | 314 | ||
306 | /* send server hostkey, ECDH pubkey 'Q_S' and signed H */ | 315 | /* send server hostkey, ECDH pubkey 'Q_S' and signed H */ |
307 | if ((r = sshpkt_start(ssh, SSH2_MSG_KEX_ECDH_REPLY)) != 0 || | 316 | if ((r = sshpkt_start(ssh, SSH2_MSG_KEX_ECDH_REPLY)) != 0 || |
308 | (r = sshpkt_put_string(ssh, server_host_key_blob, sbloblen)) != 0 || | 317 | (r = sshpkt_put_stringb(ssh, server_host_key_blob)) != 0 || |
309 | (r = sshpkt_put_stringb(ssh, server_pubkey)) != 0 || | 318 | (r = sshpkt_put_stringb(ssh, server_pubkey)) != 0 || |
310 | (r = sshpkt_put_string(ssh, signature, slen)) != 0 || | 319 | (r = sshpkt_put_string(ssh, signature, slen)) != 0 || |
311 | (r = sshpkt_send(ssh)) != 0) | 320 | (r = sshpkt_send(ssh)) != 0) |
@@ -315,7 +324,7 @@ input_kex_gen_init(int type, u_int32_t seq, struct ssh *ssh) | |||
315 | r = kex_send_newkeys(ssh); | 324 | r = kex_send_newkeys(ssh); |
316 | out: | 325 | out: |
317 | explicit_bzero(hash, sizeof(hash)); | 326 | explicit_bzero(hash, sizeof(hash)); |
318 | free(server_host_key_blob); | 327 | sshbuf_free(server_host_key_blob); |
319 | free(signature); | 328 | free(signature); |
320 | sshbuf_free(shared_secret); | 329 | sshbuf_free(shared_secret); |
321 | sshbuf_free(client_pubkey); | 330 | sshbuf_free(client_pubkey); |