123 lines
4.0 KiB
Diff
123 lines
4.0 KiB
Diff
From 0870c8db28be9eb457ee3d4f9a168959d9507efd Mon Sep 17 00:00:00 2001
|
|
From: Aris Adamantiadis <aris@0xbadc0de.be>
|
|
Date: Tue, 12 Dec 2023 23:30:26 +0100
|
|
Subject: [PATCH 12/20] CVE-2023-48795: Server side mitigations
|
|
|
|
Signed-off-by: Aris Adamantiadis <aris@0xbadc0de.be>
|
|
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
|
|
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
|
|
---
|
|
include/libssh/kex.h | 1 +
|
|
src/kex.c | 46 ++++++++++++++++++++++++++++++++++----------
|
|
src/server.c | 8 +++++++-
|
|
3 files changed, 44 insertions(+), 11 deletions(-)
|
|
|
|
diff --git a/include/libssh/kex.h b/include/libssh/kex.h
|
|
index ede7fa8a..ba98fded 100644
|
|
--- a/include/libssh/kex.h
|
|
+++ b/include/libssh/kex.h
|
|
@@ -40,6 +40,7 @@ SSH_PACKET_CALLBACK(ssh_packet_kexinit);
|
|
int ssh_send_kex(ssh_session session);
|
|
void ssh_list_kex(struct ssh_kex_struct *kex);
|
|
int ssh_set_client_kex(ssh_session session);
|
|
+int ssh_kex_append_extensions(ssh_session session, struct ssh_kex_struct *pkex);
|
|
int ssh_kex_select_methods(ssh_session session);
|
|
int ssh_verify_existing_algo(enum ssh_kex_types_e algo, const char *name);
|
|
char *ssh_keep_known_algos(enum ssh_kex_types_e algo, const char *list);
|
|
diff --git a/src/kex.c b/src/kex.c
|
|
index 3818297b..9ad671db 100644
|
|
--- a/src/kex.c
|
|
+++ b/src/kex.c
|
|
@@ -763,11 +763,8 @@ int ssh_set_client_kex(ssh_session session)
|
|
{
|
|
struct ssh_kex_struct *client = &session->next_crypto->client_kex;
|
|
const char *wanted;
|
|
- char *kex = NULL;
|
|
- char *kex_tmp = NULL;
|
|
int ok;
|
|
int i;
|
|
- size_t kex_len, len;
|
|
|
|
/* Skip if already set, for example for the rekey or when we do the guessing
|
|
* it could have been already used to make some protocol decisions. */
|
|
@@ -816,11 +813,33 @@ int ssh_set_client_kex(ssh_session session)
|
|
return SSH_OK;
|
|
}
|
|
|
|
- /* Here we append ext-info-c and kex-strict-c-v00@openssh.com to the list of kex algorithms */
|
|
- kex = client->methods[SSH_KEX];
|
|
+ ok = ssh_kex_append_extensions(session, client);
|
|
+ if (ok != SSH_OK){
|
|
+ return ok;
|
|
+ }
|
|
+
|
|
+ return SSH_OK;
|
|
+}
|
|
+
|
|
+int ssh_kex_append_extensions(ssh_session session, struct ssh_kex_struct *pkex)
|
|
+{
|
|
+ char *kex = NULL;
|
|
+ char *kex_tmp = NULL;
|
|
+ size_t kex_len, len;
|
|
+
|
|
+ /* Here we append ext-info-c and kex-strict-c-v00@openssh.com for client
|
|
+ * and kex-strict-s-v00@openssh.com for server to the list of kex algorithms
|
|
+ */
|
|
+ kex = pkex->methods[SSH_KEX];
|
|
len = strlen(kex);
|
|
- /* Comma, comma, nul byte */
|
|
- kex_len = len + 1 + strlen(KEX_EXTENSION_CLIENT) + 1 + strlen(KEX_STRICT_CLIENT ) + 1;
|
|
+ if (session->server) {
|
|
+ /* Comma, nul byte */
|
|
+ kex_len = len + 1 + strlen(KEX_STRICT_SERVER) + 1;
|
|
+ } else {
|
|
+ /* Comma, comma, nul byte */
|
|
+ kex_len = len + 1 + strlen(KEX_EXTENSION_CLIENT) + 1 +
|
|
+ strlen(KEX_STRICT_CLIENT) + 1;
|
|
+ }
|
|
if (kex_len >= MAX_PACKET_LEN) {
|
|
/* Overflow */
|
|
return SSH_ERROR;
|
|
@@ -830,9 +849,16 @@ int ssh_set_client_kex(ssh_session session)
|
|
ssh_set_error_oom(session);
|
|
return SSH_ERROR;
|
|
}
|
|
- snprintf(kex_tmp + len, kex_len - len, ",%s,%s", KEX_EXTENSION_CLIENT, KEX_STRICT_CLIENT);
|
|
- client->methods[SSH_KEX] = kex_tmp;
|
|
-
|
|
+ if (session->server){
|
|
+ snprintf(kex_tmp + len, kex_len - len, ",%s", KEX_STRICT_SERVER);
|
|
+ } else {
|
|
+ snprintf(kex_tmp + len,
|
|
+ kex_len - len,
|
|
+ ",%s,%s",
|
|
+ KEX_EXTENSION_CLIENT,
|
|
+ KEX_STRICT_CLIENT);
|
|
+ }
|
|
+ pkex->methods[SSH_KEX] = kex_tmp;
|
|
return SSH_OK;
|
|
}
|
|
|
|
diff --git a/src/server.c b/src/server.c
|
|
index dc070a73..70b90899 100644
|
|
--- a/src/server.c
|
|
+++ b/src/server.c
|
|
@@ -195,7 +195,13 @@ int server_set_kex(ssh_session session)
|
|
}
|
|
}
|
|
|
|
- return 0;
|
|
+ /* Do not append the extensions during rekey */
|
|
+ if (session->flags & SSH_SESSION_FLAG_AUTHENTICATED) {
|
|
+ return SSH_OK;
|
|
+ }
|
|
+
|
|
+ rc = ssh_kex_append_extensions(session, server);
|
|
+ return rc;
|
|
}
|
|
|
|
int ssh_server_init_kex(ssh_session session) {
|
|
--
|
|
2.33.0
|
|
|