From b2c330ec05878cb4a92f931e045e5b634d2407ac Mon Sep 17 00:00:00 2001 From: djm Date: Sun, 19 Dec 2021 22:08:06 +0000 Subject: [PATCH] Record session ID, host key and sig at intital KEX These will be used later for agent session ID / hostkey binding ok markus@ --- usr.bin/ssh/kex.c | 4 +++- usr.bin/ssh/kex.h | 5 ++++- usr.bin/ssh/kexgen.c | 35 ++++++++++++++++++++++++++++++----- usr.bin/ssh/kexgexc.c | 24 +++++++++++++++++++++--- usr.bin/ssh/kexgexs.c | 14 +++++++++++--- 5 files changed, 69 insertions(+), 13 deletions(-) diff --git a/usr.bin/ssh/kex.c b/usr.bin/ssh/kex.c index d663466cda8..3f9c1851dcc 100644 --- a/usr.bin/ssh/kex.c +++ b/usr.bin/ssh/kex.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kex.c,v 1.168 2021/04/03 06:18:40 djm Exp $ */ +/* $OpenBSD: kex.c,v 1.169 2021/12/19 22:08:06 djm Exp $ */ /* * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. * @@ -682,6 +682,8 @@ kex_free(struct kex *kex) sshbuf_free(kex->server_version); sshbuf_free(kex->client_pub); sshbuf_free(kex->session_id); + sshbuf_free(kex->initial_sig); + sshkey_free(kex->initial_hostkey); free(kex->failed_choice); free(kex->hostkey_alg); free(kex->name); diff --git a/usr.bin/ssh/kex.h b/usr.bin/ssh/kex.h index 212fd35d56b..b7967da44e5 100644 --- a/usr.bin/ssh/kex.h +++ b/usr.bin/ssh/kex.h @@ -1,4 +1,4 @@ -/* $OpenBSD: kex.h,v 1.114 2021/01/31 22:55:29 djm Exp $ */ +/* $OpenBSD: kex.h,v 1.115 2021/12/19 22:08:06 djm Exp $ */ /* * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. @@ -123,6 +123,7 @@ struct newkeys { }; struct ssh; +struct sshbuf; struct kex { struct newkeys *newkeys[MODE_MAX]; @@ -141,6 +142,8 @@ struct kex { struct sshbuf *client_version; struct sshbuf *server_version; struct sshbuf *session_id; + struct sshbuf *initial_sig; + struct sshkey *initial_hostkey; sig_atomic_t done; u_int flags; int hash_alg; diff --git a/usr.bin/ssh/kexgen.c b/usr.bin/ssh/kexgen.c index 12d8bab9094..e7534f5ce88 100644 --- a/usr.bin/ssh/kexgen.c +++ b/usr.bin/ssh/kexgen.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kexgen.c,v 1.7 2021/04/03 06:18:40 djm Exp $ */ +/* $OpenBSD: kexgen.c,v 1.8 2021/12/19 22:08:06 djm Exp $ */ /* * Copyright (c) 2019 Markus Friedl. All rights reserved. * @@ -215,8 +215,26 @@ input_kex_gen_reply(int type, u_int32_t seq, struct ssh *ssh) kex->hostkey_alg, ssh->compat, NULL)) != 0) goto out; - if ((r = kex_derive_keys(ssh, hash, hashlen, shared_secret)) == 0) - r = kex_send_newkeys(ssh); + if ((r = kex_derive_keys(ssh, hash, hashlen, shared_secret)) != 0 || + (r = kex_send_newkeys(ssh)) != 0) + goto out; + + /* save initial signature and hostkey */ + if ((kex->flags & KEX_INITIAL) != 0) { + if (kex->initial_hostkey != NULL || kex->initial_sig != NULL) { + r = SSH_ERR_INTERNAL_ERROR; + goto out; + } + if ((kex->initial_sig = sshbuf_new()) == NULL) { + r = SSH_ERR_ALLOC_FAIL; + goto out; + } + if ((r = sshbuf_put(kex->initial_sig, signature, slen)) != 0) + goto out; + kex->initial_hostkey = server_host_key; + server_host_key = NULL; + } + /* success */ out: explicit_bzero(hash, sizeof(hash)); explicit_bzero(kex->c25519_client_key, sizeof(kex->c25519_client_key)); @@ -330,8 +348,15 @@ input_kex_gen_init(int type, u_int32_t seq, struct ssh *ssh) (r = sshpkt_send(ssh)) != 0) goto out; - if ((r = kex_derive_keys(ssh, hash, hashlen, shared_secret)) == 0) - r = kex_send_newkeys(ssh); + if ((r = kex_derive_keys(ssh, hash, hashlen, shared_secret)) != 0 || + (r = kex_send_newkeys(ssh)) != 0) + goto out; + /* retain copy of hostkey used at initial KEX */ + if (kex->initial_hostkey == NULL && + (r = sshkey_from_private(server_host_public, + &kex->initial_hostkey)) != 0) + goto out; + /* success */ out: explicit_bzero(hash, sizeof(hash)); sshbuf_free(server_host_key_blob); diff --git a/usr.bin/ssh/kexgexc.c b/usr.bin/ssh/kexgexc.c index 75d843c9c43..6a06d981f9e 100644 --- a/usr.bin/ssh/kexgexc.c +++ b/usr.bin/ssh/kexgexc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kexgexc.c,v 1.37 2021/01/31 22:55:29 djm Exp $ */ +/* $OpenBSD: kexgexc.c,v 1.38 2021/12/19 22:08:06 djm Exp $ */ /* * Copyright (c) 2000 Niels Provos. All rights reserved. * Copyright (c) 2001 Markus Friedl. All rights reserved. @@ -199,8 +199,26 @@ input_kex_dh_gex_reply(int type, u_int32_t seq, struct ssh *ssh) hashlen, kex->hostkey_alg, ssh->compat, NULL)) != 0) goto out; - if ((r = kex_derive_keys(ssh, hash, hashlen, shared_secret)) == 0) - r = kex_send_newkeys(ssh); + if ((r = kex_derive_keys(ssh, hash, hashlen, shared_secret)) != 0 || + (r = kex_send_newkeys(ssh)) != 0) + goto out; + + /* save initial signature and hostkey */ + if ((kex->flags & KEX_INITIAL) != 0) { + if (kex->initial_hostkey != NULL || kex->initial_sig != NULL) { + r = SSH_ERR_INTERNAL_ERROR; + goto out; + } + if ((kex->initial_sig = sshbuf_new()) == NULL) { + r = SSH_ERR_ALLOC_FAIL; + goto out; + } + if ((r = sshbuf_put(kex->initial_sig, signature, slen)) != 0) + goto out; + kex->initial_hostkey = server_host_key; + server_host_key = NULL; + } + /* success */ out: explicit_bzero(hash, sizeof(hash)); DH_free(kex->dh); diff --git a/usr.bin/ssh/kexgexs.c b/usr.bin/ssh/kexgexs.c index 43c2410d4a7..aa86ea65082 100644 --- a/usr.bin/ssh/kexgexs.c +++ b/usr.bin/ssh/kexgexs.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kexgexs.c,v 1.43 2021/01/31 22:55:29 djm Exp $ */ +/* $OpenBSD: kexgexs.c,v 1.44 2021/12/19 22:08:06 djm Exp $ */ /* * Copyright (c) 2000 Niels Provos. All rights reserved. * Copyright (c) 2001 Markus Friedl. All rights reserved. @@ -187,8 +187,16 @@ input_kex_dh_gex_init(int type, u_int32_t seq, struct ssh *ssh) (r = sshpkt_send(ssh)) != 0) goto out; - if ((r = kex_derive_keys(ssh, hash, hashlen, shared_secret)) == 0) - r = kex_send_newkeys(ssh); + if ((r = kex_derive_keys(ssh, hash, hashlen, shared_secret)) != 0 || + (r = kex_send_newkeys(ssh)) != 0) + goto out; + + /* retain copy of hostkey used at initial KEX */ + if (kex->initial_hostkey == NULL && + (r = sshkey_from_private(server_host_public, + &kex->initial_hostkey)) != 0) + goto out; + /* success */ out: explicit_bzero(hash, sizeof(hash)); DH_free(kex->dh); -- 2.20.1