diff --git a/backport-0001-CVE-2023-6004-torture_config-Allow-multiple-in-usern.patch b/backport-0001-CVE-2023-6004-torture_config-Allow-multiple-in-usern.patch deleted file mode 100644 index b08fc3328714145d8ac4f64cf3c4a3b6bb4bf3d9..0000000000000000000000000000000000000000 --- a/backport-0001-CVE-2023-6004-torture_config-Allow-multiple-in-usern.patch +++ /dev/null @@ -1,112 +0,0 @@ -From c2c56bacab00766d01671413321d564227aabf19 Mon Sep 17 00:00:00 2001 -From: Norbert Pocs -Date: Sun, 5 Nov 2023 13:12:47 +0100 -Subject: [PATCH 01/20] CVE-2023-6004: torture_config: Allow multiple '@' in - usernames - -Signed-off-by: Norbert Pocs -Reviewed-by: Andreas Schneider -Reviewed-by: Jakub Jelen ---- - tests/unittests/torture_config.c | 56 +++++++++++++++++--------------- - 1 file changed, 30 insertions(+), 26 deletions(-) - -diff --git a/tests/unittests/torture_config.c b/tests/unittests/torture_config.c -index 406f1985..b7c763af 100644 ---- a/tests/unittests/torture_config.c -+++ b/tests/unittests/torture_config.c -@@ -995,23 +995,22 @@ static void torture_config_proxyjump(void **state, - assert_string_equal(session->opts.ProxyCommand, - "ssh -W '[%h]:%p' 2620:52:0::fed"); - -- /* In this part, we try various other config files and strings. */ -- -- /* Try to create some invalid configurations */ -- /* Non-numeric port */ -- config = "Host bad-port\n" -- "\tProxyJump jumpbox:22bad22\n"; -+ /* Multiple @ is allowed in second jump */ -+ config = "Host allowed-hostname\n" -+ "\tProxyJump localhost,user@principal.com@jumpbox:22\n"; - if (file != NULL) { - torture_write_file(file, config); - } else { - string = config; - } - torture_reset_config(session); -- ssh_options_set(session, SSH_OPTIONS_HOST, "bad-port"); -- _parse_config(session, file, string, SSH_ERROR); -+ ssh_options_set(session, SSH_OPTIONS_HOST, "allowed-hostname"); -+ _parse_config(session, file, string, SSH_OK); -+ assert_string_equal(session->opts.ProxyCommand, -+ "ssh -J user@principal.com@jumpbox:22 -W '[%h]:%p' localhost"); - -- /* Too many @ */ -- config = "Host bad-hostname\n" -+ /* Multiple @ is allowed */ -+ config = "Host allowed-hostname\n" - "\tProxyJump user@principal.com@jumpbox:22\n"; - if (file != NULL) { - torture_write_file(file, config); -@@ -1019,7 +1018,24 @@ static void torture_config_proxyjump(void **state, - string = config; - } - torture_reset_config(session); -- ssh_options_set(session, SSH_OPTIONS_HOST, "bad-hostname"); -+ ssh_options_set(session, SSH_OPTIONS_HOST, "allowed-hostname"); -+ _parse_config(session, file, string, SSH_OK); -+ assert_string_equal(session->opts.ProxyCommand, -+ "ssh -l user@principal.com -p 22 -W '[%h]:%p' jumpbox"); -+ -+ /* In this part, we try various other config files and strings. */ -+ -+ /* Try to create some invalid configurations */ -+ /* Non-numeric port */ -+ config = "Host bad-port\n" -+ "\tProxyJump jumpbox:22bad22\n"; -+ if (file != NULL) { -+ torture_write_file(file, config); -+ } else { -+ string = config; -+ } -+ torture_reset_config(session); -+ ssh_options_set(session, SSH_OPTIONS_HOST, "bad-port"); - _parse_config(session, file, string, SSH_ERROR); - - /* Braces mismatch in hostname */ -@@ -1094,18 +1110,6 @@ static void torture_config_proxyjump(void **state, - ssh_options_set(session, SSH_OPTIONS_HOST, "bad-port-2"); - _parse_config(session, file, string, SSH_ERROR); - -- /* Too many @ in second jump */ -- config = "Host bad-hostname\n" -- "\tProxyJump localhost,user@principal.com@jumpbox:22\n"; -- if (file != NULL) { -- torture_write_file(file, config); -- } else { -- string = config; -- } -- torture_reset_config(session); -- ssh_options_set(session, SSH_OPTIONS_HOST, "bad-hostname"); -- _parse_config(session, file, string, SSH_ERROR); -- - /* Braces mismatch in second jump */ - config = "Host mismatch\n" - "\tProxyJump localhost,[::1:20\n"; -@@ -1448,10 +1452,10 @@ static void torture_config_parser_get_cmd(void **state) - } else if (pid == 0) { - ssh_execute_command(tok, fileno(outfile), fileno(outfile)); - /* Does not return */ -- } else { -- /* parent -+ } else { -+ /* parent - * wait child process */ -- wait(NULL); -+ wait(NULL); - infile = fopen("output.log", "r"); - assert_non_null(infile); - p = fgets(buffer, sizeof(buffer), infile); --- -2.33.0 - diff --git a/backport-0002-CVE-2023-6004-config_parser-Allow-multiple-in-userna.patch b/backport-0002-CVE-2023-6004-config_parser-Allow-multiple-in-userna.patch deleted file mode 100644 index 9dc7b28cdbbf5c9204f4ee25935af5569efe726c..0000000000000000000000000000000000000000 --- a/backport-0002-CVE-2023-6004-config_parser-Allow-multiple-in-userna.patch +++ /dev/null @@ -1,29 +0,0 @@ -From a66b4a6eae6614d200a3625862d77565b96a7cd3 Mon Sep 17 00:00:00 2001 -From: Norbert Pocs -Date: Wed, 1 Nov 2023 11:24:43 +0100 -Subject: [PATCH 02/20] CVE-2023-6004: config_parser: Allow multiple '@' in - usernames - -Signed-off-by: Norbert Pocs -Reviewed-by: Andreas Schneider -Reviewed-by: Jakub Jelen ---- - src/config_parser.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/config_parser.c b/src/config_parser.c -index 0d988fec..cf83e2c5 100644 ---- a/src/config_parser.c -+++ b/src/config_parser.c -@@ -180,7 +180,7 @@ int ssh_config_parse_uri(const char *tok, - } - - /* Username part (optional) */ -- endp = strchr(tok, '@'); -+ endp = strrchr(tok, '@'); - if (endp != NULL) { - /* Zero-length username is not valid */ - if (tok == endp) { --- -2.33.0 - diff --git a/backport-0003-CVE-2023-6004-options-Simplify-the-hostname-parsing-.patch b/backport-0003-CVE-2023-6004-options-Simplify-the-hostname-parsing-.patch deleted file mode 100644 index 68632313c533888c11f1ea81c1d5a55fdffc5db8..0000000000000000000000000000000000000000 --- a/backport-0003-CVE-2023-6004-options-Simplify-the-hostname-parsing-.patch +++ /dev/null @@ -1,80 +0,0 @@ -From 8615c24647f773a5e04203c7459512715d698be1 Mon Sep 17 00:00:00 2001 -From: Norbert Pocs -Date: Tue, 31 Oct 2023 09:48:52 +0100 -Subject: [PATCH 03/20] CVE-2023-6004: options: Simplify the hostname parsing - in ssh_options_set - -Using ssh_config_parse_uri can simplify the parsing of the host -parsing inside the function of ssh_options_set - -Signed-off-by: Norbert Pocs -Reviewed-by: Andreas Schneider -Reviewed-by: Jakub Jelen ---- - src/options.c | 40 ++++++++++++++++------------------------ - 1 file changed, 16 insertions(+), 24 deletions(-) - -diff --git a/src/options.c b/src/options.c -index 6f2c9397..38511455 100644 ---- a/src/options.c -+++ b/src/options.c -@@ -37,6 +37,7 @@ - #include "libssh/session.h" - #include "libssh/misc.h" - #include "libssh/options.h" -+#include "libssh/config_parser.h" - #ifdef WITH_SERVER - #include "libssh/server.h" - #include "libssh/bind.h" -@@ -515,33 +516,24 @@ int ssh_options_set(ssh_session session, enum ssh_options_e type, - ssh_set_error_invalid(session); - return -1; - } else { -- q = strdup(value); -- if (q == NULL) { -- ssh_set_error_oom(session); -+ char *username = NULL, *hostname = NULL, *port = NULL; -+ rc = ssh_config_parse_uri(value, &username, &hostname, &port); -+ if (rc != SSH_OK) { - return -1; - } -- p = strrchr(q, '@'); -- -- SAFE_FREE(session->opts.host); -- -- if (p) { -- *p = '\0'; -- session->opts.host = strdup(p + 1); -- if (session->opts.host == NULL) { -- SAFE_FREE(q); -- ssh_set_error_oom(session); -- return -1; -- } -- -+ if (port != NULL) { -+ SAFE_FREE(username); -+ SAFE_FREE(hostname); -+ SAFE_FREE(port); -+ return -1; -+ } -+ if (username != NULL) { - SAFE_FREE(session->opts.username); -- session->opts.username = strdup(q); -- SAFE_FREE(q); -- if (session->opts.username == NULL) { -- ssh_set_error_oom(session); -- return -1; -- } -- } else { -- session->opts.host = q; -+ session->opts.username = username; -+ } -+ if (hostname != NULL) { -+ SAFE_FREE(session->opts.host); -+ session->opts.host = hostname; - } - } - break; --- -2.33.0 - diff --git a/backport-0004-CVE-2023-6004-misc-Add-function-to-check-allowed-cha.patch b/backport-0004-CVE-2023-6004-misc-Add-function-to-check-allowed-cha.patch deleted file mode 100644 index 296fbbabac922d54d3ce4e91daf4656594231725..0000000000000000000000000000000000000000 --- a/backport-0004-CVE-2023-6004-misc-Add-function-to-check-allowed-cha.patch +++ /dev/null @@ -1,118 +0,0 @@ -From c6180409677c765e6b9ae2b18a3a7a9671ac1dbe Mon Sep 17 00:00:00 2001 -From: Norbert Pocs -Date: Tue, 10 Oct 2023 12:44:16 +0200 -Subject: [PATCH 04/20] CVE-2023-6004: misc: Add function to check allowed - characters of a hostname - -The hostname can be a domain name or an ip address. The colon has to be -allowed because of IPv6 even it is prohibited in domain names. - -Signed-off-by: Norbert Pocs -Reviewed-by: Andreas Schneider -Reviewed-by: Jakub Jelen ---- - include/libssh/misc.h | 3 ++ - src/misc.c | 68 +++++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 71 insertions(+) - -diff --git a/include/libssh/misc.h b/include/libssh/misc.h -index 924da533..0924ba7f 100644 ---- a/include/libssh/misc.h -+++ b/include/libssh/misc.h -@@ -103,6 +103,9 @@ int ssh_newline_vis(const char *string, char *buf, size_t buf_len); - int ssh_tmpname(char *name); - - char *ssh_strreplace(const char *src, const char *pattern, const char *repl); -+ -+int ssh_check_hostname_syntax(const char *hostname); -+ - #ifdef __cplusplus - } - #endif -diff --git a/src/misc.c b/src/misc.c -index 7c478a77..be6ee836 100644 ---- a/src/misc.c -+++ b/src/misc.c -@@ -94,6 +94,8 @@ - #define ZLIB_STRING "" - #endif - -+#define ARPA_DOMAIN_MAX_LEN 63 -+ - /** - * @defgroup libssh_misc The SSH helper functions - * @ingroup libssh -@@ -1974,4 +1976,70 @@ char *ssh_strerror(int err_num, char *buf, size_t buflen) - #endif /* defined(__linux__) && defined(__GLIBC__) && defined(_GNU_SOURCE) */ - } - -+/** -+ * @brief Checks syntax of a domain name -+ * -+ * The check is made based on the RFC1035 section 2.3.1 -+ * Allowed characters are: hyphen, period, digits (0-9) and letters (a-zA-Z) -+ * -+ * The label should be no longer than 63 characters -+ * The label should start with a letter and end with a letter or number -+ * The label in this implementation can start with a number to allow virtual -+ * URLs to pass. Note that this will make IPv4 addresses to pass -+ * this check too. -+ * -+ * @param hostname The domain name to be checked, has to be null terminated -+ * -+ * @return SSH_OK if the hostname passes syntax check -+ * SSH_ERROR otherwise or if hostname is NULL or empty string -+ */ -+int ssh_check_hostname_syntax(const char *hostname) -+{ -+ char *it = NULL, *s = NULL, *buf = NULL; -+ size_t it_len; -+ char c; -+ -+ if (hostname == NULL || strlen(hostname) == 0) { -+ return SSH_ERROR; -+ } -+ -+ /* strtok_r writes into the string, keep the input clean */ -+ s = strdup(hostname); -+ if (s == NULL) { -+ return SSH_ERROR; -+ } -+ -+ it = strtok_r(s, ".", &buf); -+ /* if the token has 0 length */ -+ if (it == NULL) { -+ free(s); -+ return SSH_ERROR; -+ } -+ do { -+ it_len = strlen(it); -+ if (it_len > ARPA_DOMAIN_MAX_LEN || -+ /* the first char must be a letter, but some virtual urls start -+ * with a number */ -+ isalnum(it[0]) == 0 || -+ isalnum(it[it_len - 1]) == 0) { -+ free(s); -+ return SSH_ERROR; -+ } -+ while (*it != '\0') { -+ c = *it; -+ /* the "." is allowed too, but tokenization removes it from the -+ * string */ -+ if (isalnum(c) == 0 && c != '-') { -+ free(s); -+ return SSH_ERROR; -+ } -+ it++; -+ } -+ } while ((it = strtok_r(NULL, ".", &buf)) != NULL); -+ -+ free(s); -+ -+ return SSH_OK; -+} -+ - /** @} */ --- -2.33.0 - diff --git a/backport-0005-CVE-2023-6004-torture_misc-Add-test-for-ssh_check_ho.patch b/backport-0005-CVE-2023-6004-torture_misc-Add-test-for-ssh_check_ho.patch deleted file mode 100644 index 7a786879b589dc5881e601ef4264393d939529eb..0000000000000000000000000000000000000000 --- a/backport-0005-CVE-2023-6004-torture_misc-Add-test-for-ssh_check_ho.patch +++ /dev/null @@ -1,107 +0,0 @@ -From 9bbb817c0c5434f03613d0783b2ef5f52235b901 Mon Sep 17 00:00:00 2001 -From: Norbert Pocs -Date: Tue, 10 Oct 2023 12:45:28 +0200 -Subject: [PATCH 05/20] CVE-2023-6004: torture_misc: Add test for - ssh_check_hostname_syntax - -Signed-off-by: Norbert Pocs -Reviewed-by: Andreas Schneider -Reviewed-by: Jakub Jelen ---- - tests/unittests/torture_misc.c | 73 ++++++++++++++++++++++++++++++++++ - 1 file changed, 73 insertions(+) - -diff --git a/tests/unittests/torture_misc.c b/tests/unittests/torture_misc.c -index 9e346ff8..e682b6d4 100644 ---- a/tests/unittests/torture_misc.c -+++ b/tests/unittests/torture_misc.c -@@ -760,6 +760,78 @@ static void torture_ssh_strerror(void **state) - assert_non_null(out); - } - -+static void torture_ssh_check_hostname_syntax(void **state) -+{ -+ int rc; -+ (void)state; -+ -+ rc = ssh_check_hostname_syntax("duckduckgo.com"); -+ assert_int_equal(rc, SSH_OK); -+ rc = ssh_check_hostname_syntax("www.libssh.org"); -+ assert_int_equal(rc, SSH_OK); -+ rc = ssh_check_hostname_syntax("Some-Thing.com"); -+ assert_int_equal(rc, SSH_OK); -+ rc = ssh_check_hostname_syntax("amazon.a23456789012345678901234567890123456789012345678901234567890123"); -+ assert_int_equal(rc, SSH_OK); -+ rc = ssh_check_hostname_syntax("amazon.a23456789012345678901234567890123456789012345678901234567890123.a23456789012345678901234567890123456789012345678901234567890123.ok"); -+ assert_int_equal(rc, SSH_OK); -+ rc = ssh_check_hostname_syntax("amazon.a23456789012345678901234567890123456789012345678901234567890123.a23456789012345678901234567890123456789012345678901234567890123.a23456789012345678901234567890123456789012345678901234567890123"); -+ assert_int_equal(rc, SSH_OK); -+ rc = ssh_check_hostname_syntax("lavabo-inter.innocentes-manus-meas"); -+ assert_int_equal(rc, SSH_OK); -+ rc = ssh_check_hostname_syntax("localhost"); -+ assert_int_equal(rc, SSH_OK); -+ rc = ssh_check_hostname_syntax("a"); -+ assert_int_equal(rc, SSH_OK); -+ rc = ssh_check_hostname_syntax("a-0.b-b"); -+ assert_int_equal(rc, SSH_OK); -+ rc = ssh_check_hostname_syntax("libssh."); -+ assert_int_equal(rc, SSH_OK); -+ -+ rc = ssh_check_hostname_syntax(NULL); -+ assert_int_equal(rc, SSH_ERROR); -+ rc = ssh_check_hostname_syntax(""); -+ assert_int_equal(rc, SSH_ERROR); -+ rc = ssh_check_hostname_syntax("/"); -+ assert_int_equal(rc, SSH_ERROR); -+ rc = ssh_check_hostname_syntax("@"); -+ assert_int_equal(rc, SSH_ERROR); -+ rc = ssh_check_hostname_syntax("["); -+ assert_int_equal(rc, SSH_ERROR); -+ rc = ssh_check_hostname_syntax("`"); -+ assert_int_equal(rc, SSH_ERROR); -+ rc = ssh_check_hostname_syntax("{"); -+ assert_int_equal(rc, SSH_ERROR); -+ rc = ssh_check_hostname_syntax("&"); -+ assert_int_equal(rc, SSH_ERROR); -+ rc = ssh_check_hostname_syntax("|"); -+ assert_int_equal(rc, SSH_ERROR); -+ rc = ssh_check_hostname_syntax("\""); -+ assert_int_equal(rc, SSH_ERROR); -+ rc = ssh_check_hostname_syntax("`"); -+ assert_int_equal(rc, SSH_ERROR); -+ rc = ssh_check_hostname_syntax(" "); -+ assert_int_equal(rc, SSH_ERROR); -+ rc = ssh_check_hostname_syntax("*the+giant&\"rooks\".c0m"); -+ assert_int_equal(rc, SSH_ERROR); -+ rc = ssh_check_hostname_syntax("!www.libssh.org"); -+ assert_int_equal(rc, SSH_ERROR); -+ rc = ssh_check_hostname_syntax("--.--"); -+ assert_int_equal(rc, SSH_ERROR); -+ rc = ssh_check_hostname_syntax("libssh.a234567890123456789012345678901234567890123456789012345678901234"); -+ assert_int_equal(rc, SSH_ERROR); -+ rc = ssh_check_hostname_syntax("libssh.a234567890123456789012345678901234567890123456789012345678901234.a234567890123456789012345678901234567890123456789012345678901234"); -+ assert_int_equal(rc, SSH_ERROR); -+ rc = ssh_check_hostname_syntax("libssh-"); -+ assert_int_equal(rc, SSH_ERROR); -+ rc = ssh_check_hostname_syntax("fe80::9656:d028:8652:66b6"); -+ assert_int_equal(rc, SSH_ERROR); -+ rc = ssh_check_hostname_syntax("."); -+ assert_int_equal(rc, SSH_ERROR); -+ rc = ssh_check_hostname_syntax(".."); -+ assert_int_equal(rc, SSH_ERROR); -+} -+ - int torture_run_tests(void) { - int rc; - struct CMUnitTest tests[] = { -@@ -784,6 +856,7 @@ int torture_run_tests(void) { - cmocka_unit_test(torture_ssh_quote_file_name), - cmocka_unit_test(torture_ssh_strreplace), - cmocka_unit_test(torture_ssh_strerror), -+ cmocka_unit_test(torture_ssh_check_hostname_syntax), - }; - - ssh_init(); --- -2.33.0 - diff --git a/backport-0006-CVE-2023-6004-config_parser-Check-for-valid-syntax-o.patch b/backport-0006-CVE-2023-6004-config_parser-Check-for-valid-syntax-o.patch deleted file mode 100644 index c7a3761151576b15b7c9d1ca510c016b74a2534b..0000000000000000000000000000000000000000 --- a/backport-0006-CVE-2023-6004-config_parser-Check-for-valid-syntax-o.patch +++ /dev/null @@ -1,63 +0,0 @@ -From 22492b69bba22b102342afc574800d354a08e405 Mon Sep 17 00:00:00 2001 -From: Norbert Pocs -Date: Tue, 10 Oct 2023 18:33:56 +0200 -Subject: [PATCH 06/20] CVE-2023-6004: config_parser: Check for valid syntax of - a hostname if it is a domain name - -This prevents code injection. -The domain name syntax checker is based on RFC1035. - -Signed-off-by: Norbert Pocs -Reviewed-by: Andreas Schneider -Reviewed-by: Jakub Jelen ---- - src/config_parser.c | 12 +++++++++++- - 1 file changed, 11 insertions(+), 1 deletion(-) - -diff --git a/src/config_parser.c b/src/config_parser.c -index cf83e2c5..b8b94611 100644 ---- a/src/config_parser.c -+++ b/src/config_parser.c -@@ -30,6 +30,7 @@ - - #include "libssh/config_parser.h" - #include "libssh/priv.h" -+#include "libssh/misc.h" - - /* Returns the original string after skipping the leading whitespace - * until finding LF. -@@ -47,7 +48,7 @@ char *ssh_config_get_cmd(char **str) - break; - } - } -- -+ - for (r = c; *c; c++) { - if (*c == '\n') { - *c = '\0'; -@@ -167,6 +168,7 @@ int ssh_config_parse_uri(const char *tok, - { - char *endp = NULL; - long port_n; -+ int rc; - - /* Sanitize inputs */ - if (username != NULL) { -@@ -224,6 +226,14 @@ int ssh_config_parse_uri(const char *tok, - if (*hostname == NULL) { - goto error; - } -+ /* if not an ip, check syntax */ -+ rc = ssh_is_ipaddr(*hostname); -+ if (rc == 0) { -+ rc = ssh_check_hostname_syntax(*hostname); -+ if (rc != SSH_OK) { -+ goto error; -+ } -+ } - } - /* Skip also the closing bracket */ - if (*endp == ']') { --- -2.33.0 - diff --git a/backport-0007-CVE-2023-6004-torture_proxycommand-Add-test-for-prox.patch b/backport-0007-CVE-2023-6004-torture_proxycommand-Add-test-for-prox.patch deleted file mode 100644 index 9763e9c18ecb9878548bd010be7bd15f040201d9..0000000000000000000000000000000000000000 --- a/backport-0007-CVE-2023-6004-torture_proxycommand-Add-test-for-prox.patch +++ /dev/null @@ -1,87 +0,0 @@ -From d7467498fd988949edde9c6384973250fd454a8b Mon Sep 17 00:00:00 2001 -From: Norbert Pocs -Date: Tue, 10 Oct 2023 10:28:47 +0200 -Subject: [PATCH 07/20] CVE-2023-6004: torture_proxycommand: Add test for - proxycommand injection - -Signed-off-by: Norbert Pocs -Reviewed-by: Andreas Schneider -Reviewed-by: Jakub Jelen ---- - tests/client/torture_proxycommand.c | 53 +++++++++++++++++++++++++++++ - 1 file changed, 53 insertions(+) - -diff --git a/tests/client/torture_proxycommand.c b/tests/client/torture_proxycommand.c -index 9b8019ca..1bad4ccc 100644 ---- a/tests/client/torture_proxycommand.c -+++ b/tests/client/torture_proxycommand.c -@@ -166,6 +166,56 @@ static void torture_options_set_proxycommand_ssh_stderr(void **state) - assert_int_equal(rc & O_RDWR, O_RDWR); - } - -+static void torture_options_proxycommand_injection(void **state) -+{ -+ struct torture_state *s = *state; -+ struct passwd *pwd = NULL; -+ const char *malicious_host = "`echo foo > mfile`"; -+ const char *command = "nc %h %p"; -+ char *current_dir = NULL; -+ char *malicious_file_path = NULL; -+ int mfp_len; -+ int verbosity = torture_libssh_verbosity(); -+ struct stat sb; -+ int rc; -+ -+ pwd = getpwnam("bob"); -+ assert_non_null(pwd); -+ -+ rc = setuid(pwd->pw_uid); -+ assert_return_code(rc, errno); -+ -+ s->ssh.session = ssh_new(); -+ assert_non_null(s->ssh.session); -+ -+ ssh_options_set(s->ssh.session, SSH_OPTIONS_LOG_VERBOSITY, &verbosity); -+ // if we would be checking the rc, this should fail -+ ssh_options_set(s->ssh.session, SSH_OPTIONS_HOST, malicious_host); -+ -+ ssh_options_set(s->ssh.session, SSH_OPTIONS_USER, TORTURE_SSH_USER_ALICE); -+ -+ rc = ssh_options_set(s->ssh.session, SSH_OPTIONS_PROXYCOMMAND, command); -+ assert_int_equal(rc, 0); -+ rc = ssh_connect(s->ssh.session); -+ assert_ssh_return_code_equal(s->ssh.session, rc, SSH_ERROR); -+ -+ current_dir = torture_get_current_working_dir(); -+ assert_non_null(current_dir); -+ mfp_len = strlen(current_dir) + 6; -+ malicious_file_path = malloc(mfp_len); -+ assert_non_null(malicious_file_path); -+ rc = snprintf(malicious_file_path, mfp_len, -+ "%s/mfile", current_dir); -+ assert_int_equal(rc, mfp_len); -+ free(current_dir); -+ rc = stat(malicious_file_path, &sb); -+ assert_int_not_equal(rc, 0); -+ -+ // cleanup -+ remove(malicious_file_path); -+ free(malicious_file_path); -+} -+ - int torture_run_tests(void) { - int rc; - struct CMUnitTest tests[] = { -@@ -181,6 +231,9 @@ int torture_run_tests(void) { - cmocka_unit_test_setup_teardown(torture_options_set_proxycommand_ssh_stderr, - session_setup, - session_teardown), -+ cmocka_unit_test_setup_teardown(torture_options_proxycommand_injection, -+ NULL, -+ session_teardown), - }; - - --- -2.33.0 - diff --git a/backport-0008-CVE-2023-6004-torture_misc-Add-test-for-ssh_is_ipadd.patch b/backport-0008-CVE-2023-6004-torture_misc-Add-test-for-ssh_is_ipadd.patch deleted file mode 100644 index 6d34f5c17370991a0be6c01aee0dad1f1f2a79bf..0000000000000000000000000000000000000000 --- a/backport-0008-CVE-2023-6004-torture_misc-Add-test-for-ssh_is_ipadd.patch +++ /dev/null @@ -1,59 +0,0 @@ -From 62d3101c1f76b6891b70c50154e0e934d6b8cb57 Mon Sep 17 00:00:00 2001 -From: Norbert Pocs -Date: Mon, 6 Nov 2023 20:11:38 +0100 -Subject: [PATCH 08/20] CVE-2023-6004: torture_misc: Add test for ssh_is_ipaddr - -Signed-off-by: Norbert Pocs -Reviewed-by: Andreas Schneider -Reviewed-by: Jakub Jelen ---- - tests/unittests/torture_misc.c | 26 ++++++++++++++++++++++++++ - 1 file changed, 26 insertions(+) - -diff --git a/tests/unittests/torture_misc.c b/tests/unittests/torture_misc.c -index e682b6d4..b07392ab 100644 ---- a/tests/unittests/torture_misc.c -+++ b/tests/unittests/torture_misc.c -@@ -832,6 +832,31 @@ static void torture_ssh_check_hostname_syntax(void **state) - assert_int_equal(rc, SSH_ERROR); - } - -+static void torture_ssh_is_ipaddr(void **state) { -+ int rc; -+ (void)state; -+ -+ rc = ssh_is_ipaddr("201.255.3.69"); -+ assert_int_equal(rc, 1); -+ rc = ssh_is_ipaddr("::1"); -+ assert_int_equal(rc, 1); -+ rc = ssh_is_ipaddr("2001:0db8:85a3:0000:0000:8a2e:0370:7334"); -+ assert_int_equal(rc, 1); -+ -+ rc = ssh_is_ipaddr(".."); -+ assert_int_equal(rc, 0); -+ rc = ssh_is_ipaddr(":::"); -+ assert_int_equal(rc, 0); -+ rc = ssh_is_ipaddr("1.1.1.1.1"); -+ assert_int_equal(rc, 0); -+ rc = ssh_is_ipaddr("1.1"); -+ assert_int_equal(rc, 0); -+ rc = ssh_is_ipaddr("caesar"); -+ assert_int_equal(rc, 0); -+ rc = ssh_is_ipaddr("::xa:1"); -+ assert_int_equal(rc, 0); -+} -+ - int torture_run_tests(void) { - int rc; - struct CMUnitTest tests[] = { -@@ -857,6 +882,7 @@ int torture_run_tests(void) { - cmocka_unit_test(torture_ssh_strreplace), - cmocka_unit_test(torture_ssh_strerror), - cmocka_unit_test(torture_ssh_check_hostname_syntax), -+ cmocka_unit_test(torture_ssh_is_ipaddr), - }; - - ssh_init(); --- -2.33.0 - diff --git a/backport-0009-CVE-2023-6004-misc-Add-ipv6-link-local-check-for-an-.patch b/backport-0009-CVE-2023-6004-misc-Add-ipv6-link-local-check-for-an-.patch deleted file mode 100644 index c4f7858adb68da16567d5170cdcd60f77a65e844..0000000000000000000000000000000000000000 --- a/backport-0009-CVE-2023-6004-misc-Add-ipv6-link-local-check-for-an-.patch +++ /dev/null @@ -1,140 +0,0 @@ -From cea841d71c025f9c998b7d5fc9f2a2839df62921 Mon Sep 17 00:00:00 2001 -From: Norbert Pocs -Date: Tue, 28 Nov 2023 15:26:45 +0100 -Subject: [PATCH 09/20] CVE-2023-6004 misc: Add ipv6 link-local check for an ip - address - -Signed-off-by: Norbert Pocs -Reviewed-by: Andreas Schneider -Reviewed-by: Jakub Jelen ---- - src/CMakeLists.txt | 1 + - src/connect.c | 2 +- - src/misc.c | 44 ++++++++++++++++++++++++++++++++++++++------ - 3 files changed, 40 insertions(+), 7 deletions(-) - -diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt -index d6245c0d..807313b5 100644 ---- a/src/CMakeLists.txt -+++ b/src/CMakeLists.txt -@@ -91,6 +91,7 @@ endif() - if (WIN32) - set(LIBSSH_LINK_LIBRARIES - ${LIBSSH_LINK_LIBRARIES} -+ iphlpapi - ws2_32 - ) - endif (WIN32) -diff --git a/src/connect.c b/src/connect.c -index 57e37e63..15cae644 100644 ---- a/src/connect.c -+++ b/src/connect.c -@@ -136,7 +136,7 @@ static int getai(const char *host, int port, struct addrinfo **ai) - #endif - } - -- if (ssh_is_ipaddr(host)) { -+ if (ssh_is_ipaddr(host) == 1) { - /* this is an IP address */ - SSH_LOG(SSH_LOG_PACKET, "host %s matches an IP address", host); - hints.ai_flags |= AI_NUMERICHOST; -diff --git a/src/misc.c b/src/misc.c -index be6ee836..7081f12a 100644 ---- a/src/misc.c -+++ b/src/misc.c -@@ -32,6 +32,7 @@ - #include - #include - #include -+#include - - #endif /* _WIN32 */ - -@@ -59,6 +60,7 @@ - #include - #include - #include -+#include - - #ifdef HAVE_IO_H - #include -@@ -222,22 +224,37 @@ int ssh_is_ipaddr_v4(const char *str) - int ssh_is_ipaddr(const char *str) - { - int rc = SOCKET_ERROR; -+ char *s = strdup(str); - -- if (strchr(str, ':')) { -+ if (s == NULL) { -+ return -1; -+ } -+ if (strchr(s, ':')) { - struct sockaddr_storage ss; - int sslen = sizeof(ss); -+ char *network_interface = strchr(s, '%'); - -- /* TODO link-local (IP:v6:addr%ifname). */ -- rc = WSAStringToAddressA((LPSTR) str, -+ /* link-local (IP:v6:addr%ifname). */ -+ if (network_interface != NULL) { -+ rc = if_nametoindex(network_interface + 1); -+ if (rc == 0) { -+ free(s); -+ return 0; -+ } -+ *network_interface = '\0'; -+ } -+ rc = WSAStringToAddressA((LPSTR) s, - AF_INET6, - NULL, - (struct sockaddr*)&ss, - &sslen); - if (rc == 0) { -+ free(s); - return 1; - } - } - -+ free(s); - return ssh_is_ipaddr_v4(str); - } - #else /* _WIN32 */ -@@ -343,17 +360,32 @@ int ssh_is_ipaddr_v4(const char *str) - int ssh_is_ipaddr(const char *str) - { - int rc = -1; -+ char *s = strdup(str); - -- if (strchr(str, ':')) { -+ if (s == NULL) { -+ return -1; -+ } -+ if (strchr(s, ':')) { - struct in6_addr dest6; -+ char *network_interface = strchr(s, '%'); - -- /* TODO link-local (IP:v6:addr%ifname). */ -- rc = inet_pton(AF_INET6, str, &dest6); -+ /* link-local (IP:v6:addr%ifname). */ -+ if (network_interface != NULL) { -+ rc = if_nametoindex(network_interface + 1); -+ if (rc == 0) { -+ free(s); -+ return 0; -+ } -+ *network_interface = '\0'; -+ } -+ rc = inet_pton(AF_INET6, s, &dest6); - if (rc > 0) { -+ free(s); - return 1; - } - } - -+ free(s); - return ssh_is_ipaddr_v4(str); - } - --- -2.33.0 - diff --git a/backport-0010-CVE-2023-6004-torture_misc-Add-tests-for-ipv6-link-l.patch b/backport-0010-CVE-2023-6004-torture_misc-Add-tests-for-ipv6-link-l.patch deleted file mode 100644 index 2edfd436213ac48052ad44528c5cfabdd8100eb5..0000000000000000000000000000000000000000 --- a/backport-0010-CVE-2023-6004-torture_misc-Add-tests-for-ipv6-link-l.patch +++ /dev/null @@ -1,63 +0,0 @@ -From 2c492ee179d5caa2718c5e768bab6e0b2b64a8b0 Mon Sep 17 00:00:00 2001 -From: Norbert Pocs -Date: Tue, 28 Nov 2023 15:27:31 +0100 -Subject: [PATCH 10/20] CVE-2023-6004: torture_misc: Add tests for ipv6 - link-local - -Signed-off-by: Norbert Pocs -Reviewed-by: Andreas Schneider -Reviewed-by: Jakub Jelen ---- - tests/unittests/torture_misc.c | 20 ++++++++++++++++++++ - 1 file changed, 20 insertions(+) - -diff --git a/tests/unittests/torture_misc.c b/tests/unittests/torture_misc.c -index b07392ab..77166759 100644 ---- a/tests/unittests/torture_misc.c -+++ b/tests/unittests/torture_misc.c -@@ -17,7 +17,14 @@ - #include "torture.h" - #include "error.c" - -+#ifdef _WIN32 -+#include -+#else -+#include -+#endif -+ - #define TORTURE_TEST_DIR "/usr/local/bin/truc/much/.." -+#define TORTURE_IPV6_LOCAL_LINK "fe80::98e1:82ff:fe8d:28b3%%%s" - - const char template[] = "temp_dir_XXXXXX"; - -@@ -834,14 +841,27 @@ static void torture_ssh_check_hostname_syntax(void **state) - - static void torture_ssh_is_ipaddr(void **state) { - int rc; -+ char *interf = malloc(64); -+ char *test_interf = malloc(128); - (void)state; - -+ assert_non_null(interf); -+ assert_non_null(test_interf); - rc = ssh_is_ipaddr("201.255.3.69"); - assert_int_equal(rc, 1); - rc = ssh_is_ipaddr("::1"); - assert_int_equal(rc, 1); - rc = ssh_is_ipaddr("2001:0db8:85a3:0000:0000:8a2e:0370:7334"); - assert_int_equal(rc, 1); -+ if_indextoname(1, interf); -+ assert_non_null(interf); -+ rc = sprintf(test_interf, TORTURE_IPV6_LOCAL_LINK, interf); -+ /* the "%%s" is not written */ -+ assert_int_equal(rc, strlen(interf) + strlen(TORTURE_IPV6_LOCAL_LINK) - 3); -+ rc = ssh_is_ipaddr(test_interf); -+ assert_int_equal(rc, 1); -+ free(interf); -+ free(test_interf); - - rc = ssh_is_ipaddr(".."); - assert_int_equal(rc, 0); --- -2.33.0 - diff --git a/backport-0011-CVE-2023-48795-client-side-mitigation.patch b/backport-0011-CVE-2023-48795-client-side-mitigation.patch deleted file mode 100644 index 85d22e64c7ee664b3e4bf8c08e530ccc6b74cb67..0000000000000000000000000000000000000000 --- a/backport-0011-CVE-2023-48795-client-side-mitigation.patch +++ /dev/null @@ -1,450 +0,0 @@ -From 4cef5e965a46e9271aed62631b152e4bd23c1e3c Mon Sep 17 00:00:00 2001 -From: Aris Adamantiadis -Date: Tue, 12 Dec 2023 23:09:57 +0100 -Subject: [PATCH 11/20] CVE-2023-48795: client side mitigation - -Signed-off-by: Aris Adamantiadis -Signed-off-by: Jakub Jelen -Reviewed-by: Andreas Schneider ---- - include/libssh/packet.h | 1 + - include/libssh/session.h | 6 +++++ - src/curve25519.c | 19 +++---------- - src/dh-gex.c | 7 +---- - src/dh.c | 17 +++--------- - src/ecdh.c | 8 +----- - src/ecdh_crypto.c | 12 +++------ - src/ecdh_gcrypt.c | 10 +++---- - src/ecdh_mbedcrypto.c | 11 +++----- - src/kex.c | 34 +++++++++++++++++++---- - src/packet.c | 58 ++++++++++++++++++++++++++++++++++++++++ - src/packet_cb.c | 12 +++++++++ - 12 files changed, 126 insertions(+), 69 deletions(-) - -diff --git a/include/libssh/packet.h b/include/libssh/packet.h -index 7f10a709..f0c8cb20 100644 ---- a/include/libssh/packet.h -+++ b/include/libssh/packet.h -@@ -67,6 +67,7 @@ SSH_PACKET_CALLBACK(ssh_packet_ext_info); - SSH_PACKET_CALLBACK(ssh_packet_kexdh_init); - #endif - -+int ssh_packet_send_newkeys(ssh_session session); - int ssh_packet_send_unimplemented(ssh_session session, uint32_t seqnum); - int ssh_packet_parse_type(ssh_session session); - //int packet_flush(ssh_session session, int enforce_blocking); -diff --git a/include/libssh/session.h b/include/libssh/session.h -index eb14e97a..97936195 100644 ---- a/include/libssh/session.h -+++ b/include/libssh/session.h -@@ -81,6 +81,12 @@ enum ssh_pending_call_e { - * sending it twice during key exchange to simplify the state machine. */ - #define SSH_SESSION_FLAG_KEXINIT_SENT 4 - -+/* The current SSH2 session implements the "strict KEX" feature and should behave -+ * differently on SSH2_MSG_NEWKEYS. */ -+#define SSH_SESSION_FLAG_KEX_STRICT 0x0010 -+/* Unexpected packets have been sent while the session was still unencrypted */ -+#define SSH_SESSION_FLAG_KEX_TAINTED 0x0020 -+ - /* codes to use with ssh_handle_packets*() */ - /* Infinite timeout */ - #define SSH_TIMEOUT_INFINITE -1 -diff --git a/src/curve25519.c b/src/curve25519.c -index 66291b5f..4aeb4756 100644 ---- a/src/curve25519.c -+++ b/src/curve25519.c -@@ -335,16 +335,10 @@ static SSH_PACKET_CALLBACK(ssh_packet_client_curve25519_reply){ - } - - /* Send the MSG_NEWKEYS */ -- if (ssh_buffer_add_u8(session->out_buffer, SSH2_MSG_NEWKEYS) < 0) { -- goto error; -- } -- -- rc=ssh_packet_send(session); -+ rc = ssh_packet_send_newkeys(session); - if (rc == SSH_ERROR) { - goto error; - } -- -- SSH_LOG(SSH_LOG_PROTOCOL, "SSH_MSG_NEWKEYS sent"); - session->dh_handshake_state = DH_STATE_NEWKEYS_SENT; - - return SSH_PACKET_USED; -@@ -502,18 +496,13 @@ static SSH_PACKET_CALLBACK(ssh_packet_server_curve25519_init){ - return SSH_ERROR; - } - -- /* Send the MSG_NEWKEYS */ -- rc = ssh_buffer_add_u8(session->out_buffer, SSH2_MSG_NEWKEYS); -- if (rc < 0) { -- goto error; -- } -- - session->dh_handshake_state = DH_STATE_NEWKEYS_SENT; -- rc = ssh_packet_send(session); -+ -+ /* Send the MSG_NEWKEYS */ -+ rc = ssh_packet_send_newkeys(session); - if (rc == SSH_ERROR) { - goto error; - } -- SSH_LOG(SSH_LOG_PROTOCOL, "SSH_MSG_NEWKEYS sent"); - - return SSH_PACKET_USED; - error: -diff --git a/src/dh-gex.c b/src/dh-gex.c -index 91617081..642a88ae 100644 ---- a/src/dh-gex.c -+++ b/src/dh-gex.c -@@ -297,15 +297,10 @@ static SSH_PACKET_CALLBACK(ssh_packet_client_dhgex_reply) - } - - /* Send the MSG_NEWKEYS */ -- if (ssh_buffer_add_u8(session->out_buffer, SSH2_MSG_NEWKEYS) < 0) { -- goto error; -- } -- -- rc = ssh_packet_send(session); -+ rc = ssh_packet_send_newkeys(session); - if (rc == SSH_ERROR) { - goto error; - } -- SSH_LOG(SSH_LOG_PROTOCOL, "SSH_MSG_NEWKEYS sent"); - session->dh_handshake_state = DH_STATE_NEWKEYS_SENT; - - return SSH_PACKET_USED; -diff --git a/src/dh.c b/src/dh.c -index 011d97b3..e19e43d1 100644 ---- a/src/dh.c -+++ b/src/dh.c -@@ -398,16 +398,10 @@ SSH_PACKET_CALLBACK(ssh_packet_client_dh_reply){ - } - - /* Send the MSG_NEWKEYS */ -- if (ssh_buffer_add_u8(session->out_buffer, SSH2_MSG_NEWKEYS) < 0) { -- goto error; -- } -- -- rc=ssh_packet_send(session); -+ rc = ssh_packet_send_newkeys(session); - if (rc == SSH_ERROR) { - goto error; - } -- -- SSH_LOG(SSH_LOG_PROTOCOL, "SSH_MSG_NEWKEYS sent"); - session->dh_handshake_state = DH_STATE_NEWKEYS_SENT; - return SSH_PACKET_USED; - error: -@@ -551,15 +545,12 @@ int ssh_server_dh_process_init(ssh_session session, ssh_buffer packet) - } - SSH_LOG(SSH_LOG_DEBUG, "Sent KEX_DH_[GEX]_REPLY"); - -- if (ssh_buffer_add_u8(session->out_buffer, SSH2_MSG_NEWKEYS) < 0) { -- ssh_buffer_reinit(session->out_buffer); -- goto error; -- } - session->dh_handshake_state=DH_STATE_NEWKEYS_SENT; -- if (ssh_packet_send(session) == SSH_ERROR) { -+ /* Send the MSG_NEWKEYS */ -+ rc = ssh_packet_send_newkeys(session); -+ if (rc == SSH_ERROR) { - goto error; - } -- SSH_LOG(SSH_LOG_PACKET, "SSH_MSG_NEWKEYS sent"); - - return SSH_OK; - error: -diff --git a/src/ecdh.c b/src/ecdh.c -index e5b11ba9..af80beec 100644 ---- a/src/ecdh.c -+++ b/src/ecdh.c -@@ -93,16 +93,10 @@ SSH_PACKET_CALLBACK(ssh_packet_client_ecdh_reply){ - } - - /* Send the MSG_NEWKEYS */ -- if (ssh_buffer_add_u8(session->out_buffer, SSH2_MSG_NEWKEYS) < 0) { -- goto error; -- } -- -- rc=ssh_packet_send(session); -+ rc = ssh_packet_send_newkeys(session); - if (rc == SSH_ERROR) { - goto error; - } -- -- SSH_LOG(SSH_LOG_PROTOCOL, "SSH_MSG_NEWKEYS sent"); - session->dh_handshake_state = DH_STATE_NEWKEYS_SENT; - - return SSH_PACKET_USED; -diff --git a/src/ecdh_crypto.c b/src/ecdh_crypto.c -index 51084b7a..069b1372 100644 ---- a/src/ecdh_crypto.c -+++ b/src/ecdh_crypto.c -@@ -619,18 +619,12 @@ SSH_PACKET_CALLBACK(ssh_packet_server_ecdh_init){ - goto error; - } - -- /* Send the MSG_NEWKEYS */ -- rc = ssh_buffer_add_u8(session->out_buffer, SSH2_MSG_NEWKEYS); -- if (rc < 0) { -- goto error; -- } -- - session->dh_handshake_state = DH_STATE_NEWKEYS_SENT; -- rc = ssh_packet_send(session); -- if (rc == SSH_ERROR){ -+ /* Send the MSG_NEWKEYS */ -+ rc = ssh_packet_send_newkeys(session); -+ if (rc == SSH_ERROR) { - goto error; - } -- SSH_LOG(SSH_LOG_PROTOCOL, "SSH_MSG_NEWKEYS sent"); - - return SSH_PACKET_USED; - error: -diff --git a/src/ecdh_gcrypt.c b/src/ecdh_gcrypt.c -index 235f2904..3d9d426f 100644 ---- a/src/ecdh_gcrypt.c -+++ b/src/ecdh_gcrypt.c -@@ -372,17 +372,13 @@ SSH_PACKET_CALLBACK(ssh_packet_server_ecdh_init){ - goto out; - } - -- -+ session->dh_handshake_state = DH_STATE_NEWKEYS_SENT; - /* Send the MSG_NEWKEYS */ -- rc = ssh_buffer_add_u8(session->out_buffer, SSH2_MSG_NEWKEYS); -- if (rc != SSH_OK) { -+ rc = ssh_packet_send_newkeys(session); -+ if (rc == SSH_ERROR) { - goto out; - } - -- session->dh_handshake_state = DH_STATE_NEWKEYS_SENT; -- rc = ssh_packet_send(session); -- SSH_LOG(SSH_LOG_PROTOCOL, "SSH_MSG_NEWKEYS sent"); -- - out: - gcry_sexp_release(param); - gcry_sexp_release(key); -diff --git a/src/ecdh_mbedcrypto.c b/src/ecdh_mbedcrypto.c -index cfe017a0..dda73922 100644 ---- a/src/ecdh_mbedcrypto.c -+++ b/src/ecdh_mbedcrypto.c -@@ -318,16 +318,13 @@ SSH_PACKET_CALLBACK(ssh_packet_server_ecdh_init){ - goto out; - } - -- rc = ssh_buffer_add_u8(session->out_buffer, SSH2_MSG_NEWKEYS); -- if (rc < 0) { -- rc = SSH_ERROR; -+ session->dh_handshake_state = DH_STATE_NEWKEYS_SENT; -+ /* Send the MSG_NEWKEYS */ -+ rc = ssh_packet_send_newkeys(session); -+ if (rc == SSH_ERROR) { - goto out; - } - -- session->dh_handshake_state = DH_STATE_NEWKEYS_SENT; -- rc = ssh_packet_send(session); -- SSH_LOG(SSH_LOG_PROTOCOL, "SSH_MSG_NEWKEYS sent"); -- - out: - mbedtls_ecp_group_free(&grp); - if (rc == SSH_ERROR) { -diff --git a/src/kex.c b/src/kex.c -index b9455d2d..3818297b 100644 ---- a/src/kex.c -+++ b/src/kex.c -@@ -188,6 +188,9 @@ - - /* RFC 8308 */ - #define KEX_EXTENSION_CLIENT "ext-info-c" -+/* Strict kex mitigation against CVE-2023-48795 */ -+#define KEX_STRICT_CLIENT "kex-strict-c-v00@openssh.com" -+#define KEX_STRICT_SERVER "kex-strict-s-v00@openssh.com" - - /* Allowed algorithms in FIPS mode */ - #define FIPS_ALLOWED_CIPHERS "aes256-gcm@openssh.com,"\ -@@ -516,6 +519,27 @@ SSH_PACKET_CALLBACK(ssh_packet_kexinit) - session->first_kex_follows_guess_wrong ? "wrong" : "right"); - } - -+ /* -+ * handle the "strict KEX" feature. If supported by peer, then set up the -+ * flag and verify packet sequence numbers. -+ */ -+ if (server_kex) { -+ ok = ssh_match_group(crypto->client_kex.methods[SSH_KEX], -+ KEX_STRICT_CLIENT); -+ if (ok) { -+ SSH_LOG(SSH_LOG_DEBUG, "Client supports strict kex, enabling."); -+ session->flags |= SSH_SESSION_FLAG_KEX_STRICT; -+ } -+ } else { -+ /* client kex */ -+ ok = ssh_match_group(crypto->server_kex.methods[SSH_KEX], -+ KEX_STRICT_SERVER); -+ if (ok) { -+ SSH_LOG(SSH_LOG_DEBUG, "Server supports strict kex, enabling."); -+ session->flags |= SSH_SESSION_FLAG_KEX_STRICT; -+ } -+ } -+ - if (server_kex) { - /* - * If client sent a ext-info-c message in the kex list, it supports -@@ -792,21 +816,21 @@ int ssh_set_client_kex(ssh_session session) - return SSH_OK; - } - -- /* Here we append ext-info-c to the list of kex algorithms */ -+ /* Here we append ext-info-c and kex-strict-c-v00@openssh.com to the list of kex algorithms */ - kex = client->methods[SSH_KEX]; - len = strlen(kex); -- if (len + strlen(KEX_EXTENSION_CLIENT) + 2 < len) { -+ /* 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; - } -- kex_len = len + strlen(KEX_EXTENSION_CLIENT) + 2; /* comma, NULL */ - kex_tmp = realloc(kex, kex_len); - if (kex_tmp == NULL) { -- free(kex); - ssh_set_error_oom(session); - return SSH_ERROR; - } -- snprintf(kex_tmp + len, kex_len - len, ",%s", KEX_EXTENSION_CLIENT); -+ snprintf(kex_tmp + len, kex_len - len, ",%s,%s", KEX_EXTENSION_CLIENT, KEX_STRICT_CLIENT); - client->methods[SSH_KEX] = kex_tmp; - - return SSH_OK; -diff --git a/src/packet.c b/src/packet.c -index eb7eb42a..ea73f9ad 100644 ---- a/src/packet.c -+++ b/src/packet.c -@@ -1314,6 +1314,19 @@ ssh_packet_socket_callback(const void *data, size_t receivedlen, void *user) - } - #endif /* WITH_ZLIB */ - payloadsize = ssh_buffer_get_len(session->in_buffer); -+ if (session->recv_seq == UINT32_MAX) { -+ /* Overflowing sequence numbers is always fishy */ -+ if (crypto == NULL) { -+ /* don't allow sequence number overflow when unencrypted */ -+ ssh_set_error(session, -+ SSH_FATAL, -+ "Incoming sequence number overflow"); -+ goto error; -+ } else { -+ SSH_LOG(SSH_LOG_WARNING, -+ "Incoming sequence number overflow"); -+ } -+ } - session->recv_seq++; - if (crypto != NULL) { - struct ssh_cipher_struct *cipher = NULL; -@@ -1338,7 +1351,19 @@ ssh_packet_socket_callback(const void *data, size_t receivedlen, void *user) - "comp=%" PRIu32 ",payload=%" PRIu32 "]", - session->in_packet.type, packet_len, padding, compsize, - payloadsize); -+ if (crypto == NULL) { -+ /* In strict kex, only a few packets are allowed. Taint the session -+ * if we received packets that are normally allowed but to be -+ * refused if we are in strict kex when KEX is over. -+ */ -+ uint8_t type = session->in_packet.type; - -+ if (type != SSH2_MSG_KEXINIT && type != SSH2_MSG_NEWKEYS && -+ (type < SSH2_MSG_KEXDH_INIT || -+ type > SSH2_MSG_KEX_DH_GEX_REQUEST)) { -+ session->flags |= SSH_SESSION_FLAG_KEX_TAINTED; -+ } -+ } - /* Check if the packet is expected */ - filter_result = ssh_packet_incoming_filter(session); - -@@ -1354,6 +1379,9 @@ ssh_packet_socket_callback(const void *data, size_t receivedlen, void *user) - session->in_packet.type); - goto error; - case SSH_PACKET_UNKNOWN: -+ if (crypto == NULL) { -+ session->flags |= SSH_SESSION_FLAG_KEX_TAINTED; -+ } - ssh_packet_send_unimplemented(session, session->recv_seq - 1); - break; - } -@@ -1529,7 +1557,33 @@ void ssh_packet_process(ssh_session session, uint8_t type) - SSH_LOG(SSH_LOG_RARE, "Failed to send unimplemented: %s", - ssh_get_error(session)); - } -+ if (session->current_crypto == NULL) { -+ session->flags |= SSH_SESSION_FLAG_KEX_TAINTED; -+ } -+ } -+} -+ -+/** @internal -+ * @brief sends a SSH_MSG_NEWKEYS when enabling the new negotiated ciphers -+ * @param session the SSH session -+ * @return SSH_ERROR on error, else SSH_OK -+ */ -+int ssh_packet_send_newkeys(ssh_session session) -+{ -+ int rc; -+ -+ /* Send the MSG_NEWKEYS */ -+ rc = ssh_buffer_add_u8(session->out_buffer, SSH2_MSG_NEWKEYS); -+ if (rc < 0) { -+ return rc; - } -+ -+ rc = ssh_packet_send(session); -+ if (rc == SSH_ERROR) { -+ return rc; -+ } -+ SSH_LOG(SSH_LOG_DEBUG, "SSH_MSG_NEWKEYS sent"); -+ return rc; - } - - /** @internal -@@ -1842,6 +1896,10 @@ int ssh_packet_send(ssh_session session) - if (rc == SSH_OK && type == SSH2_MSG_NEWKEYS) { - struct ssh_iterator *it; - -+ if (session->flags & SSH_SESSION_FLAG_KEX_STRICT) { -+ /* reset packet sequence number when running in strict kex mode */ -+ session->send_seq = 0; -+ } - for (it = ssh_list_get_iterator(session->out_queue); - it != NULL; - it = ssh_list_get_iterator(session->out_queue)) { -diff --git a/src/packet_cb.c b/src/packet_cb.c -index 0ecf8771..2f364c26 100644 ---- a/src/packet_cb.c -+++ b/src/packet_cb.c -@@ -115,6 +115,18 @@ SSH_PACKET_CALLBACK(ssh_packet_newkeys){ - goto error; - } - -+ if (session->flags & SSH_SESSION_FLAG_KEX_STRICT) { -+ /* reset packet sequence number when running in strict kex mode */ -+ session->recv_seq = 0; -+ /* Check that we aren't tainted */ -+ if (session->flags & SSH_SESSION_FLAG_KEX_TAINTED) { -+ ssh_set_error(session, -+ SSH_FATAL, -+ "Received unexpected packets in strict KEX mode."); -+ goto error; -+ } -+ } -+ - if(session->server){ - /* server things are done in server.c */ - session->dh_handshake_state=DH_STATE_FINISHED; --- -2.33.0 - diff --git a/backport-0012-CVE-2023-48795-Server-side-mitigations.patch b/backport-0012-CVE-2023-48795-Server-side-mitigations.patch deleted file mode 100644 index 6ff8921ab3aebfe2457c4e7c0d02bf57023b6212..0000000000000000000000000000000000000000 --- a/backport-0012-CVE-2023-48795-Server-side-mitigations.patch +++ /dev/null @@ -1,122 +0,0 @@ -From 0870c8db28be9eb457ee3d4f9a168959d9507efd Mon Sep 17 00:00:00 2001 -From: Aris Adamantiadis -Date: Tue, 12 Dec 2023 23:30:26 +0100 -Subject: [PATCH 12/20] CVE-2023-48795: Server side mitigations - -Signed-off-by: Aris Adamantiadis -Signed-off-by: Jakub Jelen -Reviewed-by: Andreas Schneider ---- - 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 - diff --git a/backport-0013-CVE-2023-48795-Strip-extensions-from-both-kex-lists-.patch b/backport-0013-CVE-2023-48795-Strip-extensions-from-both-kex-lists-.patch deleted file mode 100644 index e4511f2d26743b2172e1a8075cfc6d15c60804c6..0000000000000000000000000000000000000000 --- a/backport-0013-CVE-2023-48795-Strip-extensions-from-both-kex-lists-.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 5846e57538c750c5ce67df887d09fa99861c79c6 Mon Sep 17 00:00:00 2001 -From: Jakub Jelen -Date: Thu, 14 Dec 2023 12:22:01 +0100 -Subject: [PATCH 13/20] CVE-2023-48795: Strip extensions from both kex lists - for matching - -Signed-off-by: Jakub Jelen -Reviewed-by: Andreas Schneider ---- - src/kex.c | 16 ++++++++++++---- - 1 file changed, 12 insertions(+), 4 deletions(-) - -diff --git a/src/kex.c b/src/kex.c -index 9ad671db..fbc70cf4 100644 ---- a/src/kex.c -+++ b/src/kex.c -@@ -961,11 +961,19 @@ int ssh_kex_select_methods (ssh_session session) - enum ssh_key_exchange_e kex_type; - int i; - -- /* Here we should drop the ext-info-c from the list so we avoid matching. -+ /* Here we should drop the extensions from the list so we avoid matching. - * it. We added it to the end, so we can just truncate the string here */ -- ext_start = strstr(client->methods[SSH_KEX], ","KEX_EXTENSION_CLIENT); -- if (ext_start != NULL) { -- ext_start[0] = '\0'; -+ if (session->client) { -+ ext_start = strstr(client->methods[SSH_KEX], "," KEX_EXTENSION_CLIENT); -+ if (ext_start != NULL) { -+ ext_start[0] = '\0'; -+ } -+ } -+ if (session->server) { -+ ext_start = strstr(server->methods[SSH_KEX], "," KEX_STRICT_SERVER); -+ if (ext_start != NULL) { -+ ext_start[0] = '\0'; -+ } - } - - for (i = 0; i < SSH_KEX_METHODS; i++) { --- -2.33.0 - diff --git a/backport-0014-CVE-2023-48795-tests-Adjust-calculation-to-strict-ke.patch b/backport-0014-CVE-2023-48795-tests-Adjust-calculation-to-strict-ke.patch deleted file mode 100644 index 8616db29525d4be564ff540ed6baa4a96ab2912c..0000000000000000000000000000000000000000 --- a/backport-0014-CVE-2023-48795-tests-Adjust-calculation-to-strict-ke.patch +++ /dev/null @@ -1,105 +0,0 @@ -From 89df759200d31fc79fbbe213d8eda0d329eebf6d Mon Sep 17 00:00:00 2001 -From: Jakub Jelen -Date: Thu, 14 Dec 2023 12:47:48 +0100 -Subject: [PATCH 14/20] CVE-2023-48795: tests: Adjust calculation to strict kex - -Signed-off-by: Jakub Jelen -Reviewed-by: Andreas Schneider ---- - tests/client/torture_rekey.c | 55 ++++++++++++++++++++---------------- - 1 file changed, 31 insertions(+), 24 deletions(-) - -diff --git a/tests/client/torture_rekey.c b/tests/client/torture_rekey.c -index ccd5ae2c..57e03e3f 100644 ---- a/tests/client/torture_rekey.c -+++ b/tests/client/torture_rekey.c -@@ -148,6 +148,29 @@ static void torture_rekey_default(void **state) - ssh_disconnect(s->ssh.session); - } - -+static void sanity_check_session(void **state) -+{ -+ struct torture_state *s = *state; -+ struct ssh_crypto_struct *c = NULL; -+ -+ c = s->ssh.session->current_crypto; -+ assert_non_null(c); -+ assert_int_equal(c->in_cipher->max_blocks, -+ bytes / c->in_cipher->blocksize); -+ assert_int_equal(c->out_cipher->max_blocks, -+ bytes / c->out_cipher->blocksize); -+ /* when strict kex is used, the newkeys reset the sequence number */ -+ if ((s->ssh.session->flags & SSH_SESSION_FLAG_KEX_STRICT) != 0) { -+ assert_int_equal(c->out_cipher->packets, s->ssh.session->send_seq); -+ assert_int_equal(c->in_cipher->packets, s->ssh.session->recv_seq); -+ } else { -+ /* Otherwise we have less encrypted packets than transferred -+ * (first are not encrypted) */ -+ assert_true(c->out_cipher->packets < s->ssh.session->send_seq); -+ assert_true(c->in_cipher->packets < s->ssh.session->recv_seq); -+ } -+} -+ - /* We lower the rekey limits manually and check that the rekey - * really happens when sending data - */ -@@ -166,16 +189,10 @@ static void torture_rekey_send(void **state) - rc = ssh_connect(s->ssh.session); - assert_ssh_return_code(s->ssh.session, rc); - -- /* The blocks limit is set correctly */ -- c = s->ssh.session->current_crypto; -- assert_int_equal(c->in_cipher->max_blocks, -- bytes / c->in_cipher->blocksize); -- assert_int_equal(c->out_cipher->max_blocks, -- bytes / c->out_cipher->blocksize); -- /* We should have less encrypted packets than transferred (first are not encrypted) */ -- assert_true(c->out_cipher->packets < s->ssh.session->send_seq); -- assert_true(c->in_cipher->packets < s->ssh.session->recv_seq); -+ sanity_check_session(state); - /* Copy the initial secret hash = session_id so we know we changed keys later */ -+ c = s->ssh.session->current_crypto; -+ assert_non_null(c); - secret_hash = malloc(c->digest_len); - assert_non_null(secret_hash); - memcpy(secret_hash, c->secret_hash, c->digest_len); -@@ -273,15 +290,10 @@ static void torture_rekey_recv(void **state) - mode_t mask; - int rc; - -- /* The blocks limit is set correctly */ -+ sanity_check_session(state); -+ /* Copy the initial secret hash = session_id so we know we changed keys later */ - c = s->ssh.session->current_crypto; - assert_non_null(c); -- assert_int_equal(c->in_cipher->max_blocks, bytes / c->in_cipher->blocksize); -- assert_int_equal(c->out_cipher->max_blocks, bytes / c->out_cipher->blocksize); -- /* We should have less encrypted packets than transferred (first are not encrypted) */ -- assert_true(c->out_cipher->packets < s->ssh.session->send_seq); -- assert_true(c->in_cipher->packets < s->ssh.session->recv_seq); -- /* Copy the initial secret hash = session_id so we know we changed keys later */ - secret_hash = malloc(c->digest_len); - assert_non_null(secret_hash); - memcpy(secret_hash, c->secret_hash, c->digest_len); -@@ -468,15 +480,10 @@ static void torture_rekey_different_kex(void **state) - assert_ssh_return_code(s->ssh.session, rc); - - /* The blocks limit is set correctly */ -- c = s->ssh.session->current_crypto; -- assert_int_equal(c->in_cipher->max_blocks, -- bytes / c->in_cipher->blocksize); -- assert_int_equal(c->out_cipher->max_blocks, -- bytes / c->out_cipher->blocksize); -- /* We should have less encrypted packets than transferred (first are not encrypted) */ -- assert_true(c->out_cipher->packets < s->ssh.session->send_seq); -- assert_true(c->in_cipher->packets < s->ssh.session->recv_seq); -+ sanity_check_session(state); - /* Copy the initial secret hash = session_id so we know we changed keys later */ -+ c = s->ssh.session->current_crypto; -+ assert_non_null(c); - secret_hash = malloc(c->digest_len); - assert_non_null(secret_hash); - memcpy(secret_hash, c->secret_hash, c->digest_len); --- -2.33.0 - diff --git a/backport-0015-CVE-2023-6918-kdf-Reformat.patch b/backport-0015-CVE-2023-6918-kdf-Reformat.patch deleted file mode 100644 index b33427586091b11429a8e91a322c8921da543045..0000000000000000000000000000000000000000 --- a/backport-0015-CVE-2023-6918-kdf-Reformat.patch +++ /dev/null @@ -1,72 +0,0 @@ -From 610d7a09f99c601224ae2aa3d3de7e75b1d284dd Mon Sep 17 00:00:00 2001 -From: Jakub Jelen -Date: Fri, 15 Dec 2023 10:30:09 +0100 -Subject: [PATCH 15/20] CVE-2023-6918: kdf: Reformat - -Signed-off-by: Jakub Jelen -Reviewed-by: Andreas Schneider ---- - src/kdf.c | 20 +++++++++++--------- - 1 file changed, 11 insertions(+), 9 deletions(-) - -diff --git a/src/kdf.c b/src/kdf.c -index 44f06631..987ae972 100644 ---- a/src/kdf.c -+++ b/src/kdf.c -@@ -58,7 +58,7 @@ static ssh_mac_ctx ssh_mac_ctx_init(enum ssh_kdf_digest type) - } - - ctx->digest_type = type; -- switch(type){ -+ switch (type) { - case SSH_KDF_SHA1: - ctx->ctx.sha1_ctx = sha1_init(); - return ctx; -@@ -79,7 +79,7 @@ static ssh_mac_ctx ssh_mac_ctx_init(enum ssh_kdf_digest type) - - static void ssh_mac_update(ssh_mac_ctx ctx, const void *data, size_t len) - { -- switch(ctx->digest_type){ -+ switch (ctx->digest_type) { - case SSH_KDF_SHA1: - sha1_update(ctx->ctx.sha1_ctx, data, len); - break; -@@ -97,26 +97,28 @@ static void ssh_mac_update(ssh_mac_ctx ctx, const void *data, size_t len) - - static void ssh_mac_final(unsigned char *md, ssh_mac_ctx ctx) - { -- switch(ctx->digest_type){ -+ switch (ctx->digest_type) { - case SSH_KDF_SHA1: -- sha1_final(md,ctx->ctx.sha1_ctx); -+ sha1_final(md, ctx->ctx.sha1_ctx); - break; - case SSH_KDF_SHA256: -- sha256_final(md,ctx->ctx.sha256_ctx); -+ sha256_final(md, ctx->ctx.sha256_ctx); - break; - case SSH_KDF_SHA384: -- sha384_final(md,ctx->ctx.sha384_ctx); -+ sha384_final(md, ctx->ctx.sha384_ctx); - break; - case SSH_KDF_SHA512: -- sha512_final(md,ctx->ctx.sha512_ctx); -+ sha512_final(md, ctx->ctx.sha512_ctx); - break; - } - SAFE_FREE(ctx); - } - - int sshkdf_derive_key(struct ssh_crypto_struct *crypto, -- unsigned char *key, size_t key_len, -- uint8_t key_type, unsigned char *output, -+ unsigned char *key, -+ size_t key_len, -+ uint8_t key_type, -+ unsigned char *output, - size_t requested_len) - { - /* Can't use VLAs with Visual Studio, so allocate the biggest --- -2.33.0 - diff --git a/backport-0016-CVE-2023-6918-Remove-unused-evp-functions-and-types.patch b/backport-0016-CVE-2023-6918-Remove-unused-evp-functions-and-types.patch deleted file mode 100644 index d3d3a39103c6932cf3b405ca2f6e01234d4b801a..0000000000000000000000000000000000000000 --- a/backport-0016-CVE-2023-6918-Remove-unused-evp-functions-and-types.patch +++ /dev/null @@ -1,289 +0,0 @@ -From 63ff242131c8e6d98917456f71f6d33b9ef3a763 Mon Sep 17 00:00:00 2001 -From: Jakub Jelen -Date: Fri, 15 Dec 2023 12:55:27 +0100 -Subject: [PATCH 16/20] CVE-2023-6918: Remove unused evp functions and types - -Signed-off-by: Jakub Jelen -Reviewed-by: Andreas Schneider ---- - include/libssh/libcrypto.h | 5 --- - include/libssh/libgcrypt.h | 1 - - include/libssh/libmbedcrypto.h | 1 - - include/libssh/wrapper.h | 4 -- - src/libcrypto.c | 54 ------------------------- - src/libgcrypt.c | 53 ------------------------ - src/libmbedcrypto.c | 74 ---------------------------------- - 7 files changed, 192 deletions(-) - -diff --git a/include/libssh/libcrypto.h b/include/libssh/libcrypto.h -index 16e5f98f..87f30a4d 100644 ---- a/include/libssh/libcrypto.h -+++ b/include/libssh/libcrypto.h -@@ -39,11 +39,6 @@ typedef EVP_MD_CTX* SHA384CTX; - typedef EVP_MD_CTX* SHA512CTX; - typedef EVP_MD_CTX* MD5CTX; - typedef EVP_MD_CTX* HMACCTX; --#ifdef HAVE_ECC --typedef EVP_MD_CTX *EVPCTX; --#else --typedef void *EVPCTX; --#endif - - #define SHA_DIGEST_LEN SHA_DIGEST_LENGTH - #define SHA256_DIGEST_LEN SHA256_DIGEST_LENGTH -diff --git a/include/libssh/libgcrypt.h b/include/libssh/libgcrypt.h -index e4087fd2..c6afc22e 100644 ---- a/include/libssh/libgcrypt.h -+++ b/include/libssh/libgcrypt.h -@@ -32,7 +32,6 @@ typedef gcry_md_hd_t SHA384CTX; - typedef gcry_md_hd_t SHA512CTX; - typedef gcry_md_hd_t MD5CTX; - typedef gcry_md_hd_t HMACCTX; --typedef gcry_md_hd_t EVPCTX; - #define SHA_DIGEST_LENGTH 20 - #define SHA_DIGEST_LEN SHA_DIGEST_LENGTH - #define MD5_DIGEST_LEN 16 -diff --git a/include/libssh/libmbedcrypto.h b/include/libssh/libmbedcrypto.h -index e6fc393c..540a025b 100644 ---- a/include/libssh/libmbedcrypto.h -+++ b/include/libssh/libmbedcrypto.h -@@ -41,7 +41,6 @@ typedef mbedtls_md_context_t *SHA384CTX; - typedef mbedtls_md_context_t *SHA512CTX; - typedef mbedtls_md_context_t *MD5CTX; - typedef mbedtls_md_context_t *HMACCTX; --typedef mbedtls_md_context_t *EVPCTX; - - #define SHA_DIGEST_LENGTH 20 - #define SHA_DIGEST_LEN SHA_DIGEST_LENGTH -diff --git a/include/libssh/wrapper.h b/include/libssh/wrapper.h -index 36589cff..07e64018 100644 ---- a/include/libssh/wrapper.h -+++ b/include/libssh/wrapper.h -@@ -95,10 +95,6 @@ void sha512_update(SHA512CTX c, const void *data, size_t len); - void sha512_final(unsigned char *md,SHA512CTX c); - void sha512(const unsigned char *digest, size_t len, unsigned char *hash); - --void evp(int nid, unsigned char *digest, size_t len, unsigned char *hash, unsigned int *hlen); --EVPCTX evp_init(int nid); --void evp_update(EVPCTX ctx, const void *data, size_t len); --void evp_final(EVPCTX ctx, unsigned char *md, unsigned int *mdlen); - - HMACCTX hmac_init(const void *key,size_t len, enum ssh_hmac_e type); - int hmac_update(HMACCTX c, const void *data, size_t len); -diff --git a/src/libcrypto.c b/src/libcrypto.c -index ebdca6e0..4f945d90 100644 ---- a/src/libcrypto.c -+++ b/src/libcrypto.c -@@ -125,60 +125,6 @@ ENGINE *pki_get_engine(void) - return engine; - } - --#ifdef HAVE_OPENSSL_ECC --static const EVP_MD *nid_to_evpmd(int nid) --{ -- switch (nid) { -- case NID_X9_62_prime256v1: -- return EVP_sha256(); -- case NID_secp384r1: -- return EVP_sha384(); -- case NID_secp521r1: -- return EVP_sha512(); -- default: -- return NULL; -- } -- -- return NULL; --} -- --void evp(int nid, unsigned char *digest, size_t len, unsigned char *hash, unsigned int *hlen) --{ -- const EVP_MD *evp_md = nid_to_evpmd(nid); -- EVP_MD_CTX *md = EVP_MD_CTX_new(); -- -- EVP_DigestInit(md, evp_md); -- EVP_DigestUpdate(md, digest, len); -- EVP_DigestFinal(md, hash, hlen); -- EVP_MD_CTX_free(md); --} -- --EVPCTX evp_init(int nid) --{ -- const EVP_MD *evp_md = nid_to_evpmd(nid); -- -- EVPCTX ctx = EVP_MD_CTX_new(); -- if (ctx == NULL) { -- return NULL; -- } -- -- EVP_DigestInit(ctx, evp_md); -- -- return ctx; --} -- --void evp_update(EVPCTX ctx, const void *data, size_t len) --{ -- EVP_DigestUpdate(ctx, data, len); --} -- --void evp_final(EVPCTX ctx, unsigned char *md, unsigned int *mdlen) --{ -- EVP_DigestFinal(ctx, md, mdlen); -- EVP_MD_CTX_free(ctx); --} --#endif /* HAVE_OPENSSL_ECC */ -- - #ifdef HAVE_OPENSSL_EVP_KDF_CTX - #if OPENSSL_VERSION_NUMBER < 0x30000000L - static const EVP_MD *sshkdf_digest_to_md(enum ssh_kdf_digest digest_type) -diff --git a/src/libgcrypt.c b/src/libgcrypt.c -index 2e44a53c..f410d997 100644 ---- a/src/libgcrypt.c -+++ b/src/libgcrypt.c -@@ -69,59 +69,6 @@ static int alloc_key(struct ssh_cipher_struct *cipher) { - void ssh_reseed(void){ - } - --#ifdef HAVE_GCRYPT_ECC --static int nid_to_md_algo(int nid) --{ -- switch (nid) { -- case NID_gcrypt_nistp256: -- return GCRY_MD_SHA256; -- case NID_gcrypt_nistp384: -- return GCRY_MD_SHA384; -- case NID_gcrypt_nistp521: -- return GCRY_MD_SHA512; -- } -- return GCRY_MD_NONE; --} -- --void evp(int nid, unsigned char *digest, size_t len, -- unsigned char *hash, unsigned int *hlen) --{ -- int algo = nid_to_md_algo(nid); -- -- /* Note: What gcrypt calls 'hash' is called 'digest' here and -- vice-versa. */ -- gcry_md_hash_buffer(algo, hash, digest, len); -- *hlen = gcry_md_get_algo_dlen(algo); --} -- --EVPCTX evp_init(int nid) --{ -- gcry_error_t err; -- int algo = nid_to_md_algo(nid); -- EVPCTX ctx; -- -- err = gcry_md_open(&ctx, algo, 0); -- if (err) { -- return NULL; -- } -- -- return ctx; --} -- --void evp_update(EVPCTX ctx, const void *data, size_t len) --{ -- gcry_md_write(ctx, data, len); --} -- --void evp_final(EVPCTX ctx, unsigned char *md, unsigned int *mdlen) --{ -- int algo = gcry_md_get_algo(ctx); -- *mdlen = gcry_md_get_algo_dlen(algo); -- memcpy(md, gcry_md_read(ctx, algo), *mdlen); -- gcry_md_close(ctx); --} --#endif -- - int ssh_kdf(struct ssh_crypto_struct *crypto, - unsigned char *key, size_t key_len, - uint8_t key_type, unsigned char *output, -diff --git a/src/libmbedcrypto.c b/src/libmbedcrypto.c -index 594e5369..caa3b6e9 100644 ---- a/src/libmbedcrypto.c -+++ b/src/libmbedcrypto.c -@@ -51,80 +51,6 @@ void ssh_reseed(void) - mbedtls_ctr_drbg_reseed(&ssh_mbedtls_ctr_drbg, NULL, 0); - } - --static mbedtls_md_type_t nid_to_md_algo(int nid) --{ -- switch (nid) { -- case NID_mbedtls_nistp256: -- return MBEDTLS_MD_SHA256; -- case NID_mbedtls_nistp384: -- return MBEDTLS_MD_SHA384; -- case NID_mbedtls_nistp521: -- return MBEDTLS_MD_SHA512; -- } -- return MBEDTLS_MD_NONE; --} -- --void evp(int nid, unsigned char *digest, size_t len, -- unsigned char *hash, unsigned int *hlen) --{ -- mbedtls_md_type_t algo = nid_to_md_algo(nid); -- const mbedtls_md_info_t *md_info = -- mbedtls_md_info_from_type(algo); -- -- -- if (md_info != NULL) { -- *hlen = mbedtls_md_get_size(md_info); -- mbedtls_md(md_info, digest, len, hash); -- } --} -- --EVPCTX evp_init(int nid) --{ -- EVPCTX ctx = NULL; -- int rc; -- mbedtls_md_type_t algo = nid_to_md_algo(nid); -- const mbedtls_md_info_t *md_info = -- mbedtls_md_info_from_type(algo); -- -- if (md_info == NULL) { -- return NULL; -- } -- -- ctx = malloc(sizeof(mbedtls_md_context_t)); -- if (ctx == NULL) { -- return NULL; -- } -- -- mbedtls_md_init(ctx); -- -- rc = mbedtls_md_setup(ctx, md_info, 0); -- if (rc != 0) { -- SAFE_FREE(ctx); -- return NULL; -- } -- -- rc = mbedtls_md_starts(ctx); -- if (rc != 0) { -- SAFE_FREE(ctx); -- return NULL; -- } -- -- return ctx; --} -- --void evp_update(EVPCTX ctx, const void *data, size_t len) --{ -- mbedtls_md_update(ctx, data, len); --} -- --void evp_final(EVPCTX ctx, unsigned char *md, unsigned int *mdlen) --{ -- *mdlen = mbedtls_md_get_size(ctx->MBEDTLS_PRIVATE(md_info)); -- mbedtls_md_finish(ctx, md); -- mbedtls_md_free(ctx); -- SAFE_FREE(ctx); --} -- - int ssh_kdf(struct ssh_crypto_struct *crypto, - unsigned char *key, size_t key_len, - uint8_t key_type, unsigned char *output, --- -2.33.0 - diff --git a/backport-0017-CVE-2023-6918-Systematically-check-return-values-whe.patch b/backport-0017-CVE-2023-6918-Systematically-check-return-values-whe.patch deleted file mode 100644 index 5a8b00729909af5e91afee9dfe8eff8d2613c502..0000000000000000000000000000000000000000 --- a/backport-0017-CVE-2023-6918-Systematically-check-return-values-whe.patch +++ /dev/null @@ -1,1094 +0,0 @@ -From 8b66d037d575e5f3ce4d35964547ff8c7e75ff8e Mon Sep 17 00:00:00 2001 -From: Jakub Jelen -Date: Fri, 15 Dec 2023 12:55:54 +0100 -Subject: [PATCH 17/20] CVE-2023-6918: Systematically check return values when - calculating digests - -with all crypto backends - -Signed-off-by: Jakub Jelen -Reviewed-by: Andreas Schneider ---- - include/libssh/wrapper.h | 34 ++++---- - src/kdf.c | 96 ++++++++++++++++++----- - src/md_crypto.c | 161 ++++++++++++++++++++++++++++++-------- - src/md_gcrypt.c | 107 +++++++++++++++++++++---- - src/md_mbedcrypto.c | 165 +++++++++++++++++++++++++++++++-------- - src/session.c | 72 ++++++++++++----- - 6 files changed, 504 insertions(+), 131 deletions(-) - -diff --git a/include/libssh/wrapper.h b/include/libssh/wrapper.h -index 07e64018..b3e28eac 100644 ---- a/include/libssh/wrapper.h -+++ b/include/libssh/wrapper.h -@@ -72,29 +72,33 @@ struct ssh_crypto_struct; - - typedef struct ssh_mac_ctx_struct *ssh_mac_ctx; - MD5CTX md5_init(void); --void md5_update(MD5CTX c, const void *data, size_t len); --void md5_final(unsigned char *md,MD5CTX c); -+void md5_ctx_free(MD5CTX); -+int md5_update(MD5CTX c, const void *data, size_t len); -+int md5_final(unsigned char *md, MD5CTX c); - - SHACTX sha1_init(void); --void sha1_update(SHACTX c, const void *data, size_t len); --void sha1_final(unsigned char *md,SHACTX c); --void sha1(const unsigned char *digest,size_t len,unsigned char *hash); -+void sha1_ctx_free(SHACTX); -+int sha1_update(SHACTX c, const void *data, size_t len); -+int sha1_final(unsigned char *md,SHACTX c); -+int sha1(const unsigned char *digest,size_t len, unsigned char *hash); - - SHA256CTX sha256_init(void); --void sha256_update(SHA256CTX c, const void *data, size_t len); --void sha256_final(unsigned char *md,SHA256CTX c); --void sha256(const unsigned char *digest, size_t len, unsigned char *hash); -+void sha256_ctx_free(SHA256CTX); -+int sha256_update(SHA256CTX c, const void *data, size_t len); -+int sha256_final(unsigned char *md,SHA256CTX c); -+int sha256(const unsigned char *digest, size_t len, unsigned char *hash); - - SHA384CTX sha384_init(void); --void sha384_update(SHA384CTX c, const void *data, size_t len); --void sha384_final(unsigned char *md,SHA384CTX c); --void sha384(const unsigned char *digest, size_t len, unsigned char *hash); -+void sha384_ctx_free(SHA384CTX); -+int sha384_update(SHA384CTX c, const void *data, size_t len); -+int sha384_final(unsigned char *md,SHA384CTX c); -+int sha384(const unsigned char *digest, size_t len, unsigned char *hash); - - SHA512CTX sha512_init(void); --void sha512_update(SHA512CTX c, const void *data, size_t len); --void sha512_final(unsigned char *md,SHA512CTX c); --void sha512(const unsigned char *digest, size_t len, unsigned char *hash); -- -+void sha512_ctx_free(SHA512CTX); -+int sha512_update(SHA512CTX c, const void *data, size_t len); -+int sha512_final(unsigned char *md,SHA512CTX c); -+int sha512(const unsigned char *digest, size_t len, unsigned char *hash); - - HMACCTX hmac_init(const void *key,size_t len, enum ssh_hmac_e type); - int hmac_update(HMACCTX c, const void *data, size_t len); -diff --git a/src/kdf.c b/src/kdf.c -index 987ae972..a8e534e5 100644 ---- a/src/kdf.c -+++ b/src/kdf.c -@@ -77,41 +77,64 @@ static ssh_mac_ctx ssh_mac_ctx_init(enum ssh_kdf_digest type) - } - } - --static void ssh_mac_update(ssh_mac_ctx ctx, const void *data, size_t len) -+static void ssh_mac_ctx_free(ssh_mac_ctx ctx) - { -+ if (ctx == NULL) { -+ return; -+ } -+ - switch (ctx->digest_type) { - case SSH_KDF_SHA1: -- sha1_update(ctx->ctx.sha1_ctx, data, len); -+ sha1_ctx_free(ctx->ctx.sha1_ctx); - break; - case SSH_KDF_SHA256: -- sha256_update(ctx->ctx.sha256_ctx, data, len); -+ sha256_ctx_free(ctx->ctx.sha256_ctx); - break; - case SSH_KDF_SHA384: -- sha384_update(ctx->ctx.sha384_ctx, data, len); -+ sha384_ctx_free(ctx->ctx.sha384_ctx); - break; - case SSH_KDF_SHA512: -- sha512_update(ctx->ctx.sha512_ctx, data, len); -+ sha512_ctx_free(ctx->ctx.sha512_ctx); - break; - } -+ SAFE_FREE(ctx); -+} -+ -+static int ssh_mac_update(ssh_mac_ctx ctx, const void *data, size_t len) -+{ -+ switch (ctx->digest_type) { -+ case SSH_KDF_SHA1: -+ return sha1_update(ctx->ctx.sha1_ctx, data, len); -+ case SSH_KDF_SHA256: -+ return sha256_update(ctx->ctx.sha256_ctx, data, len); -+ case SSH_KDF_SHA384: -+ return sha384_update(ctx->ctx.sha384_ctx, data, len); -+ case SSH_KDF_SHA512: -+ return sha512_update(ctx->ctx.sha512_ctx, data, len); -+ } -+ return SSH_ERROR; - } - --static void ssh_mac_final(unsigned char *md, ssh_mac_ctx ctx) -+static int ssh_mac_final(unsigned char *md, ssh_mac_ctx ctx) - { -+ int rc = SSH_ERROR; -+ - switch (ctx->digest_type) { - case SSH_KDF_SHA1: -- sha1_final(md, ctx->ctx.sha1_ctx); -+ rc = sha1_final(md, ctx->ctx.sha1_ctx); - break; - case SSH_KDF_SHA256: -- sha256_final(md, ctx->ctx.sha256_ctx); -+ rc = sha256_final(md, ctx->ctx.sha256_ctx); - break; - case SSH_KDF_SHA384: -- sha384_final(md, ctx->ctx.sha384_ctx); -+ rc = sha384_final(md, ctx->ctx.sha384_ctx); - break; - case SSH_KDF_SHA512: -- sha512_final(md, ctx->ctx.sha512_ctx); -+ rc = sha512_final(md, ctx->ctx.sha512_ctx); - break; - } - SAFE_FREE(ctx); -+ return rc; - } - - int sshkdf_derive_key(struct ssh_crypto_struct *crypto, -@@ -126,6 +149,7 @@ int sshkdf_derive_key(struct ssh_crypto_struct *crypto, - unsigned char digest[DIGEST_MAX_LEN]; - size_t output_len = crypto->digest_len; - ssh_mac_ctx ctx; -+ int rc; - - if (DIGEST_MAX_LEN < crypto->digest_len) { - return -1; -@@ -136,11 +160,30 @@ int sshkdf_derive_key(struct ssh_crypto_struct *crypto, - return -1; - } - -- ssh_mac_update(ctx, key, key_len); -- ssh_mac_update(ctx, crypto->secret_hash, crypto->digest_len); -- ssh_mac_update(ctx, &key_type, 1); -- ssh_mac_update(ctx, crypto->session_id, crypto->session_id_len); -- ssh_mac_final(digest, ctx); -+ rc = ssh_mac_update(ctx, key, key_len); -+ if (rc != SSH_OK) { -+ ssh_mac_ctx_free(ctx); -+ return -1; -+ } -+ rc = ssh_mac_update(ctx, crypto->secret_hash, crypto->digest_len); -+ if (rc != SSH_OK) { -+ ssh_mac_ctx_free(ctx); -+ return -1; -+ } -+ rc = ssh_mac_update(ctx, &key_type, 1); -+ if (rc != SSH_OK) { -+ ssh_mac_ctx_free(ctx); -+ return -1; -+ } -+ rc = ssh_mac_update(ctx, crypto->session_id, crypto->session_id_len); -+ if (rc != SSH_OK) { -+ ssh_mac_ctx_free(ctx); -+ return -1; -+ } -+ rc = ssh_mac_final(digest, ctx); -+ if (rc != SSH_OK) { -+ return -1; -+ } - - if (requested_len < output_len) { - output_len = requested_len; -@@ -152,10 +195,25 @@ int sshkdf_derive_key(struct ssh_crypto_struct *crypto, - if (ctx == NULL) { - return -1; - } -- ssh_mac_update(ctx, key, key_len); -- ssh_mac_update(ctx, crypto->secret_hash, crypto->digest_len); -- ssh_mac_update(ctx, output, output_len); -- ssh_mac_final(digest, ctx); -+ rc = ssh_mac_update(ctx, key, key_len); -+ if (rc != SSH_OK) { -+ ssh_mac_ctx_free(ctx); -+ return -1; -+ } -+ rc = ssh_mac_update(ctx, crypto->secret_hash, crypto->digest_len); -+ if (rc != SSH_OK) { -+ ssh_mac_ctx_free(ctx); -+ return -1; -+ } -+ rc = ssh_mac_update(ctx, output, output_len); -+ if (rc != SSH_OK) { -+ ssh_mac_ctx_free(ctx); -+ return -1; -+ } -+ rc = ssh_mac_final(digest, ctx); -+ if (rc != SSH_OK) { -+ return -1; -+ } - if (requested_len < output_len + crypto->digest_len) { - memcpy(output + output_len, digest, requested_len - output_len); - } else { -diff --git a/src/md_crypto.c b/src/md_crypto.c -index f5104f04..f7cda8dd 100644 ---- a/src/md_crypto.c -+++ b/src/md_crypto.c -@@ -25,6 +25,7 @@ - #include "libssh/crypto.h" - #include "libssh/wrapper.h" - -+#include - #include - #include - #include -@@ -46,28 +47,49 @@ sha1_init(void) - } - - void -+sha1_ctx_free(SHACTX c) -+{ -+ EVP_MD_CTX_free(c); -+} -+ -+int - sha1_update(SHACTX c, const void *data, size_t len) - { -- EVP_DigestUpdate(c, data, len); -+ int rc = EVP_DigestUpdate(c, data, len); -+ if (rc != 1) { -+ return SSH_ERROR; -+ } -+ return SSH_OK; - } - --void -+int - sha1_final(unsigned char *md, SHACTX c) - { - unsigned int mdlen = 0; -+ int rc = EVP_DigestFinal(c, md, &mdlen); - -- EVP_DigestFinal(c, md, &mdlen); - EVP_MD_CTX_free(c); -+ if (rc != 1) { -+ return SSH_ERROR; -+ } -+ return SSH_OK; - } - --void -+int - sha1(const unsigned char *digest, size_t len, unsigned char *hash) - { - SHACTX c = sha1_init(); -- if (c != NULL) { -- sha1_update(c, digest, len); -- sha1_final(hash, c); -+ int rc; -+ -+ if (c == NULL) { -+ return SSH_ERROR; - } -+ rc = sha1_update(c, digest, len); -+ if (rc != SSH_OK) { -+ EVP_MD_CTX_free(c); -+ return SSH_ERROR; -+ } -+ return sha1_final(hash, c); - } - - SHA256CTX -@@ -87,28 +109,49 @@ sha256_init(void) - } - - void -+sha256_ctx_free(SHA256CTX c) -+{ -+ EVP_MD_CTX_free(c); -+} -+ -+int - sha256_update(SHA256CTX c, const void *data, size_t len) - { -- EVP_DigestUpdate(c, data, len); -+ int rc = EVP_DigestUpdate(c, data, len); -+ if (rc != 1) { -+ return SSH_ERROR; -+ } -+ return SSH_OK; - } - --void -+int - sha256_final(unsigned char *md, SHA256CTX c) - { - unsigned int mdlen = 0; -+ int rc = EVP_DigestFinal(c, md, &mdlen); - -- EVP_DigestFinal(c, md, &mdlen); - EVP_MD_CTX_free(c); -+ if (rc != 1) { -+ return SSH_ERROR; -+ } -+ return SSH_OK; - } - --void -+int - sha256(const unsigned char *digest, size_t len, unsigned char *hash) - { - SHA256CTX c = sha256_init(); -- if (c != NULL) { -- sha256_update(c, digest, len); -- sha256_final(hash, c); -+ int rc; -+ -+ if (c == NULL) { -+ return SSH_ERROR; -+ } -+ rc = sha256_update(c, digest, len); -+ if (rc != SSH_OK) { -+ EVP_MD_CTX_free(c); -+ return SSH_ERROR; - } -+ return sha256_final(hash, c); - } - - SHA384CTX -@@ -128,28 +171,49 @@ sha384_init(void) - } - - void -+sha384_ctx_free(SHA384CTX c) -+{ -+ EVP_MD_CTX_free(c); -+} -+ -+int - sha384_update(SHA384CTX c, const void *data, size_t len) - { -- EVP_DigestUpdate(c, data, len); -+ int rc = EVP_DigestUpdate(c, data, len); -+ if (rc != 1) { -+ return SSH_ERROR; -+ } -+ return SSH_OK; - } - --void -+int - sha384_final(unsigned char *md, SHA384CTX c) - { - unsigned int mdlen = 0; -+ int rc = EVP_DigestFinal(c, md, &mdlen); - -- EVP_DigestFinal(c, md, &mdlen); - EVP_MD_CTX_free(c); -+ if (rc != 1) { -+ return SSH_ERROR; -+ } -+ return SSH_OK; - } - --void -+int - sha384(const unsigned char *digest, size_t len, unsigned char *hash) - { - SHA384CTX c = sha384_init(); -- if (c != NULL) { -- sha384_update(c, digest, len); -- sha384_final(hash, c); -+ int rc; -+ -+ if (c == NULL) { -+ return SSH_ERROR; - } -+ rc = sha384_update(c, digest, len); -+ if (rc != SSH_OK) { -+ EVP_MD_CTX_free(c); -+ return SSH_ERROR; -+ } -+ return sha384_final(hash, c); - } - - SHA512CTX -@@ -169,28 +233,49 @@ sha512_init(void) - } - - void -+sha512_ctx_free(SHA512CTX c) -+{ -+ EVP_MD_CTX_free(c); -+} -+ -+int - sha512_update(SHA512CTX c, const void *data, size_t len) - { -- EVP_DigestUpdate(c, data, len); -+ int rc = EVP_DigestUpdate(c, data, len); -+ if (rc != 1) { -+ return SSH_ERROR; -+ } -+ return SSH_OK; - } - --void -+int - sha512_final(unsigned char *md, SHA512CTX c) - { - unsigned int mdlen = 0; -+ int rc = EVP_DigestFinal(c, md, &mdlen); - -- EVP_DigestFinal(c, md, &mdlen); - EVP_MD_CTX_free(c); -+ if (rc != 1) { -+ return SSH_ERROR; -+ } -+ return SSH_OK; - } - --void -+int - sha512(const unsigned char *digest, size_t len, unsigned char *hash) - { - SHA512CTX c = sha512_init(); -- if (c != NULL) { -- sha512_update(c, digest, len); -- sha512_final(hash, c); -+ int rc; -+ -+ if (c == NULL) { -+ return SSH_ERROR; -+ } -+ rc = sha512_update(c, digest, len); -+ if (rc != SSH_OK) { -+ EVP_MD_CTX_free(c); -+ return SSH_ERROR; - } -+ return sha512_final(hash, c); - } - - MD5CTX -@@ -210,16 +295,30 @@ md5_init(void) - } - - void -+md5_ctx_free(MD5CTX c) -+{ -+ EVP_MD_CTX_free(c); -+} -+ -+int - md5_update(MD5CTX c, const void *data, size_t len) - { -- EVP_DigestUpdate(c, data, len); -+ int rc = EVP_DigestUpdate(c, data, len); -+ if (rc != 1) { -+ return SSH_ERROR; -+ } -+ return SSH_OK; - } - --void -+int - md5_final(unsigned char *md, MD5CTX c) - { - unsigned int mdlen = 0; -+ int rc = EVP_DigestFinal(c, md, &mdlen); - -- EVP_DigestFinal(c, md, &mdlen); - EVP_MD_CTX_free(c); -+ if (rc != 1) { -+ return SSH_ERROR; -+ } -+ return SSH_OK; - } -diff --git a/src/md_gcrypt.c b/src/md_gcrypt.c -index 1f0a71f3..93c7b0d9 100644 ---- a/src/md_gcrypt.c -+++ b/src/md_gcrypt.c -@@ -36,24 +36,40 @@ sha1_init(void) - return ctx; - } - --void -+int - sha1_update(SHACTX c, const void *data, size_t len) - { - gcry_md_write(c, data, len); -+ return SSH_OK; - } - - void -+sha1_ctx_free(SHACTX c) -+{ -+ gcry_md_close(c); -+} -+ -+int - sha1_final(unsigned char *md, SHACTX c) - { -+ unsigned char *tmp = NULL; -+ - gcry_md_final(c); -- memcpy(md, gcry_md_read(c, 0), SHA_DIGEST_LEN); -+ tmp = gcry_md_read(c, 0); -+ if (tmp == NULL) { -+ gcry_md_close(c); -+ return SSH_ERROR; -+ } -+ memcpy(md, tmp, SHA_DIGEST_LEN); - gcry_md_close(c); -+ return SSH_OK; - } - --void -+int - sha1(const unsigned char *digest, size_t len, unsigned char *hash) - { - gcry_md_hash_buffer(GCRY_MD_SHA1, hash, digest, len); -+ return SSH_OK; - } - - SHA256CTX -@@ -66,23 +82,39 @@ sha256_init(void) - } - - void -+sha256_ctx_free(SHA256CTX c) -+{ -+ gcry_md_close(c); -+} -+ -+int - sha256_update(SHACTX c, const void *data, size_t len) - { - gcry_md_write(c, data, len); -+ return SSH_OK; - } - --void -+int - sha256_final(unsigned char *md, SHACTX c) - { -+ unsigned char *tmp = NULL; -+ - gcry_md_final(c); -- memcpy(md, gcry_md_read(c, 0), SHA256_DIGEST_LEN); -+ tmp = gcry_md_read(c, 0); -+ if (tmp == NULL) { -+ gcry_md_close(c); -+ return SSH_ERROR; -+ } -+ memcpy(md, tmp, SHA256_DIGEST_LEN); - gcry_md_close(c); -+ return SSH_OK; - } - --void -+int - sha256(const unsigned char *digest, size_t len, unsigned char *hash) - { - gcry_md_hash_buffer(GCRY_MD_SHA256, hash, digest, len); -+ return SSH_OK; - } - - SHA384CTX -@@ -95,23 +127,39 @@ sha384_init(void) - } - - void -+sha384_ctx_free(SHA384CTX c) -+{ -+ gcry_md_close(c); -+} -+ -+int - sha384_update(SHACTX c, const void *data, size_t len) - { - gcry_md_write(c, data, len); -+ return SSH_OK; - } - --void -+int - sha384_final(unsigned char *md, SHACTX c) - { -+ unsigned char *tmp = NULL; -+ - gcry_md_final(c); -- memcpy(md, gcry_md_read(c, 0), SHA384_DIGEST_LEN); -+ tmp = gcry_md_read(c, 0); -+ if (tmp == NULL) { -+ gcry_md_close(c); -+ return SSH_ERROR; -+ } -+ memcpy(md, tmp, SHA384_DIGEST_LEN); - gcry_md_close(c); -+ return SSH_OK; - } - --void -+int - sha384(const unsigned char *digest, size_t len, unsigned char *hash) - { - gcry_md_hash_buffer(GCRY_MD_SHA384, hash, digest, len); -+ return SSH_OK; - } - - SHA512CTX -@@ -124,23 +172,39 @@ sha512_init(void) - } - - void -+sha512_ctx_free(SHA512CTX c) -+{ -+ gcry_md_close(c); -+} -+ -+int - sha512_update(SHACTX c, const void *data, size_t len) - { - gcry_md_write(c, data, len); -+ return SSH_OK; - } - --void -+int - sha512_final(unsigned char *md, SHACTX c) - { -+ unsigned char *tmp = NULL; -+ - gcry_md_final(c); -- memcpy(md, gcry_md_read(c, 0), SHA512_DIGEST_LEN); -+ tmp = gcry_md_read(c, 0); -+ if (tmp == NULL) { -+ gcry_md_close(c); -+ return SSH_ERROR; -+ } -+ memcpy(md, tmp, SHA512_DIGEST_LEN); - gcry_md_close(c); -+ return SSH_OK; - } - --void -+int - sha512(const unsigned char *digest, size_t len, unsigned char *hash) - { - gcry_md_hash_buffer(GCRY_MD_SHA512, hash, digest, len); -+ return SSH_OK; - } - - MD5CTX -@@ -153,15 +217,30 @@ md5_init(void) - } - - void -+md5_ctx_free(MD5CTX c) -+{ -+ gcry_md_close(c); -+} -+ -+int - md5_update(MD5CTX c, const void *data, size_t len) - { - gcry_md_write(c, data, len); -+ return SSH_OK; - } - --void -+int - md5_final(unsigned char *md, MD5CTX c) - { -+ unsigned char *tmp = NULL; -+ - gcry_md_final(c); -- memcpy(md, gcry_md_read(c, 0), MD5_DIGEST_LEN); -+ tmp = gcry_md_read(c, 0); -+ if (tmp == NULL) { -+ gcry_md_close(c); -+ return SSH_ERROR; -+ } -+ memcpy(md, tmp, MD5_DIGEST_LEN); - gcry_md_close(c); -+ return SSH_OK; - } -diff --git a/src/md_mbedcrypto.c b/src/md_mbedcrypto.c -index 227e20ab..b3529b4b 100644 ---- a/src/md_mbedcrypto.c -+++ b/src/md_mbedcrypto.c -@@ -64,27 +64,48 @@ sha1_init(void) - } - - void -+sha1_ctx_free(SHACTX c) -+{ -+ mbedtls_md_free(c); -+ SAFE_FREE(c); -+} -+ -+int - sha1_update(SHACTX c, const void *data, size_t len) - { -- mbedtls_md_update(c, data, len); -+ int rc = mbedtls_md_update(c, data, len); -+ if (rc != 0) { -+ return SSH_ERROR; -+ } -+ return SSH_OK; - } - --void -+int - sha1_final(unsigned char *md, SHACTX c) - { -- mbedtls_md_finish(c, md); -- mbedtls_md_free(c); -- SAFE_FREE(c); -+ int rc = mbedtls_md_finish(c, md); -+ sha1_ctx_free(c); -+ if (rc != 0) { -+ return SSH_ERROR; -+ } -+ return SSH_OK; - } - --void -+int - sha1(const unsigned char *digest, size_t len, unsigned char *hash) - { - const mbedtls_md_info_t *md_info = - mbedtls_md_info_from_type(MBEDTLS_MD_SHA1); -- if (md_info != NULL) { -- mbedtls_md(md_info, digest, len, hash); -+ int rc; -+ -+ if (md_info == NULL) { -+ return SSH_ERROR; -+ } -+ rc = mbedtls_md(md_info, digest, len, hash); -+ if (rc != 0) { -+ return SSH_ERROR; - } -+ return SSH_OK; - } - - SHA256CTX -@@ -122,27 +143,48 @@ sha256_init(void) - } - - void -+sha256_ctx_free(SHA256CTX c) -+{ -+ mbedtls_md_free(c); -+ SAFE_FREE(c); -+} -+ -+int - sha256_update(SHA256CTX c, const void *data, size_t len) - { -- mbedtls_md_update(c, data, len); -+ int rc = mbedtls_md_update(c, data, len); -+ if (rc != 0) { -+ return SSH_ERROR; -+ } -+ return SSH_OK; - } - --void -+int - sha256_final(unsigned char *md, SHA256CTX c) - { -- mbedtls_md_finish(c, md); -+ int rc = mbedtls_md_finish(c, md); - mbedtls_md_free(c); - SAFE_FREE(c); -+ if (rc != 0) { -+ return SSH_ERROR; -+ } -+ return SSH_OK; - } - --void -+int - sha256(const unsigned char *digest, size_t len, unsigned char *hash) - { -+ int rc; - const mbedtls_md_info_t *md_info = - mbedtls_md_info_from_type(MBEDTLS_MD_SHA256); -- if (md_info != NULL) { -- mbedtls_md(md_info, digest, len, hash); -+ if (md_info == NULL) { -+ return SSH_ERROR; -+ } -+ rc = mbedtls_md(md_info, digest, len, hash); -+ if (rc != 0) { -+ return SSH_ERROR; - } -+ return SSH_OK; - } - - SHA384CTX -@@ -180,27 +222,48 @@ sha384_init(void) - } - - void -+sha384_ctx_free(SHA384CTX c) -+{ -+ mbedtls_md_free(c); -+ SAFE_FREE(c); -+} -+ -+int - sha384_update(SHA384CTX c, const void *data, size_t len) - { -- mbedtls_md_update(c, data, len); -+ int rc = mbedtls_md_update(c, data, len); -+ if (rc != 0) { -+ return SSH_ERROR; -+ } -+ return SSH_OK; - } - --void -+int - sha384_final(unsigned char *md, SHA384CTX c) - { -- mbedtls_md_finish(c, md); -- mbedtls_md_free(c); -- SAFE_FREE(c); -+ int rc = mbedtls_md_finish(c, md); -+ sha384_ctx_free(c); -+ if (rc != 0) { -+ return SSH_ERROR; -+ } -+ return SSH_OK; - } - --void -+int - sha384(const unsigned char *digest, size_t len, unsigned char *hash) - { - const mbedtls_md_info_t *md_info = - mbedtls_md_info_from_type(MBEDTLS_MD_SHA384); -- if (md_info != NULL) { -- mbedtls_md(md_info, digest, len, hash); -+ int rc; -+ -+ if (md_info == NULL) { -+ return SSH_ERROR; -+ } -+ rc = mbedtls_md(md_info, digest, len, hash); -+ if (rc != 0) { -+ return SSH_ERROR; - } -+ return SSH_OK; - } - - SHA512CTX -@@ -237,27 +300,48 @@ sha512_init(void) - } - - void -+sha512_ctx_free(SHA512CTX c) -+{ -+ mbedtls_md_free(c); -+ SAFE_FREE(c); -+} -+ -+int - sha512_update(SHA512CTX c, const void *data, size_t len) - { -- mbedtls_md_update(c, data, len); -+ int rc = mbedtls_md_update(c, data, len); -+ if (rc != 0) { -+ return SSH_ERROR; -+ } -+ return SSH_OK; - } - --void -+int - sha512_final(unsigned char *md, SHA512CTX c) - { -- mbedtls_md_finish(c, md); -- mbedtls_md_free(c); -- SAFE_FREE(c); -+ int rc = mbedtls_md_finish(c, md); -+ sha512_ctx_free(c); -+ if (rc != 0) { -+ return SSH_ERROR; -+ } -+ return SSH_OK; - } - --void -+int - sha512(const unsigned char *digest, size_t len, unsigned char *hash) - { - const mbedtls_md_info_t *md_info = - mbedtls_md_info_from_type(MBEDTLS_MD_SHA512); -- if (md_info != NULL) { -- mbedtls_md(md_info, digest, len, hash); -+ int rc; -+ -+ if (md_info == NULL) { -+ return SSH_ERROR; - } -+ rc = mbedtls_md(md_info, digest, len, hash); -+ if (rc != 0) { -+ return SSH_ERROR; -+ } -+ return SSH_OK; - } - - MD5CTX -@@ -294,15 +378,30 @@ md5_init(void) - } - - void -+md5_ctx_free(MD5CTX c) -+{ -+ mbedtls_md_free(c); -+ SAFE_FREE(c); -+} -+ -+int - md5_update(MD5CTX c, const void *data, size_t len) - { -- mbedtls_md_update(c, data, len); -+ int rc = mbedtls_md_update(c, data, len); -+ if (rc != 0) { -+ return SSH_ERROR; -+ } -+ return SSH_OK; - } - --void -+int - md5_final(unsigned char *md, MD5CTX c) - { -- mbedtls_md_finish(c, md); -+ int rc = mbedtls_md_finish(c, md); - mbedtls_md_free(c); - SAFE_FREE(c); -+ if (rc != 0) { -+ return SSH_ERROR; -+ } -+ return SSH_OK; - } -diff --git a/src/session.c b/src/session.c -index fe998dee..8c509699 100644 ---- a/src/session.c -+++ b/src/session.c -@@ -1024,7 +1024,18 @@ int ssh_get_pubkey_hash(ssh_session session, unsigned char **hash) - *hash = NULL; - if (session->current_crypto == NULL || - session->current_crypto->server_pubkey == NULL) { -- ssh_set_error(session,SSH_FATAL,"No current cryptographic context"); -+ ssh_set_error(session, SSH_FATAL, "No current cryptographic context"); -+ return SSH_ERROR; -+ } -+ -+ rc = ssh_get_server_publickey(session, &pubkey); -+ if (rc != SSH_OK) { -+ return SSH_ERROR; -+ } -+ -+ rc = ssh_pki_export_pubkey_blob(pubkey, &pubkey_blob); -+ ssh_key_free(pubkey); -+ if (rc != SSH_OK) { - return SSH_ERROR; - } - -@@ -1039,25 +1050,21 @@ int ssh_get_pubkey_hash(ssh_session session, unsigned char **hash) - return SSH_ERROR; - } - -- rc = ssh_get_server_publickey(session, &pubkey); -+ rc = md5_update(ctx, -+ ssh_string_data(pubkey_blob), -+ ssh_string_len(pubkey_blob)); - if (rc != SSH_OK) { -- md5_final(h, ctx); -+ md5_ctx_free(ctx); - SAFE_FREE(h); -- return SSH_ERROR; -+ return rc; - } -- -- rc = ssh_pki_export_pubkey_blob(pubkey, &pubkey_blob); -- ssh_key_free(pubkey); -+ SSH_STRING_FREE(pubkey_blob); -+ rc = md5_final(h, ctx); - if (rc != SSH_OK) { -- md5_final(h, ctx); - SAFE_FREE(h); -- return SSH_ERROR; -+ return rc; - } - -- md5_update(ctx, ssh_string_data(pubkey_blob), ssh_string_len(pubkey_blob)); -- SSH_STRING_FREE(pubkey_blob); -- md5_final(h, ctx); -- - *hash = h; - - return MD5_DIGEST_LEN; -@@ -1177,8 +1184,17 @@ int ssh_get_publickey_hash(const ssh_key key, - goto out; - } - -- sha1_update(ctx, ssh_string_data(blob), ssh_string_len(blob)); -- sha1_final(h, ctx); -+ rc = sha1_update(ctx, ssh_string_data(blob), ssh_string_len(blob)); -+ if (rc != SSH_OK) { -+ free(h); -+ sha1_ctx_free(ctx); -+ goto out; -+ } -+ rc = sha1_final(h, ctx); -+ if (rc != SSH_OK) { -+ free(h); -+ goto out; -+ } - - *hlen = SHA_DIGEST_LEN; - } -@@ -1200,8 +1216,17 @@ int ssh_get_publickey_hash(const ssh_key key, - goto out; - } - -- sha256_update(ctx, ssh_string_data(blob), ssh_string_len(blob)); -- sha256_final(h, ctx); -+ rc = sha256_update(ctx, ssh_string_data(blob), ssh_string_len(blob)); -+ if (rc != SSH_OK) { -+ free(h); -+ sha256_ctx_free(ctx); -+ goto out; -+ } -+ rc = sha256_final(h, ctx); -+ if (rc != SSH_OK) { -+ free(h); -+ goto out; -+ } - - *hlen = SHA256_DIGEST_LEN; - } -@@ -1231,8 +1256,17 @@ int ssh_get_publickey_hash(const ssh_key key, - goto out; - } - -- md5_update(ctx, ssh_string_data(blob), ssh_string_len(blob)); -- md5_final(h, ctx); -+ rc = md5_update(ctx, ssh_string_data(blob), ssh_string_len(blob)); -+ if (rc != SSH_OK) { -+ free(h); -+ md5_ctx_free(ctx); -+ goto out; -+ } -+ rc = md5_final(h, ctx); -+ if (rc != SSH_OK) { -+ free(h); -+ goto out; -+ } - - *hlen = MD5_DIGEST_LEN; - } --- -2.33.0 - diff --git a/backport-0018-CVE-2023-6918-kdf-Detect-context-init-failures.patch b/backport-0018-CVE-2023-6918-kdf-Detect-context-init-failures.patch deleted file mode 100644 index e1f64f70dcb673cf43e97b65aae24d7e9ea14f2b..0000000000000000000000000000000000000000 --- a/backport-0018-CVE-2023-6918-kdf-Detect-context-init-failures.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 8977e246b6d7ae467cab008a49e0a9e3d84bc2a0 Mon Sep 17 00:00:00 2001 -From: Jakub Jelen -Date: Fri, 15 Dec 2023 13:35:14 +0100 -Subject: [PATCH 18/20] CVE-2023-6918: kdf: Detect context init failures - -Signed-off-by: Jakub Jelen -Reviewed-by: Andreas Schneider ---- - src/kdf.c | 18 +++++++++++++++--- - 1 file changed, 15 insertions(+), 3 deletions(-) - -diff --git a/src/kdf.c b/src/kdf.c -index a8e534e5..6bc477ce 100644 ---- a/src/kdf.c -+++ b/src/kdf.c -@@ -61,20 +61,32 @@ static ssh_mac_ctx ssh_mac_ctx_init(enum ssh_kdf_digest type) - switch (type) { - case SSH_KDF_SHA1: - ctx->ctx.sha1_ctx = sha1_init(); -+ if (ctx->ctx.sha1_ctx == NULL) { -+ goto err; -+ } - return ctx; - case SSH_KDF_SHA256: - ctx->ctx.sha256_ctx = sha256_init(); -+ if (ctx->ctx.sha256_ctx == NULL) { -+ goto err; -+ } - return ctx; - case SSH_KDF_SHA384: - ctx->ctx.sha384_ctx = sha384_init(); -+ if (ctx->ctx.sha384_ctx == NULL) { -+ goto err; -+ } - return ctx; - case SSH_KDF_SHA512: - ctx->ctx.sha512_ctx = sha512_init(); -+ if (ctx->ctx.sha512_ctx == NULL) { -+ goto err; -+ } - return ctx; -- default: -- SAFE_FREE(ctx); -- return NULL; - } -+err: -+ SAFE_FREE(ctx); -+ return NULL; - } - - static void ssh_mac_ctx_free(ssh_mac_ctx ctx) --- -2.33.0 - diff --git a/backport-0019-CVE-2023-6918-tests-Code-coverage-for-ssh_get_pubkey.patch b/backport-0019-CVE-2023-6918-tests-Code-coverage-for-ssh_get_pubkey.patch deleted file mode 100644 index efbd0b2a4e3c419acc1d2c8c44d808645063d262..0000000000000000000000000000000000000000 --- a/backport-0019-CVE-2023-6918-tests-Code-coverage-for-ssh_get_pubkey.patch +++ /dev/null @@ -1,68 +0,0 @@ -From 622421018b58392ffecc29726b947e089b678221 Mon Sep 17 00:00:00 2001 -From: Jakub Jelen -Date: Fri, 15 Dec 2023 15:39:12 +0100 -Subject: [PATCH 19/20] CVE-2023-6918: tests: Code coverage for - ssh_get_pubkey_hash() - -Signed-off-by: Jakub Jelen -Reviewed-by: Andreas Schneider ---- - tests/client/torture_session.c | 35 ++++++++++++++++++++++++++++++++++ - 1 file changed, 35 insertions(+) - -diff --git a/tests/client/torture_session.c b/tests/client/torture_session.c -index 27e8fc86..c437d421 100644 ---- a/tests/client/torture_session.c -+++ b/tests/client/torture_session.c -@@ -391,6 +391,38 @@ static void torture_freed_channel_get_exit_status(void **state) - assert_ssh_return_code_equal(session, rc, SSH_ERROR); - } - -+static void torture_pubkey_hash(void **state) -+{ -+ struct torture_state *s = *state; -+ ssh_session session = s->ssh.session; -+ char *hash = NULL; -+ char *hexa = NULL; -+ int rc = 0; -+ -+ /* bad arguments */ -+ rc = ssh_get_pubkey_hash(session, NULL); -+ assert_int_equal(rc, SSH_ERROR); -+ -+ rc = ssh_get_pubkey_hash(NULL, (unsigned char **)&hash); -+ assert_int_equal(rc, SSH_ERROR); -+ -+ /* deprecated, but should be covered by tests! */ -+ rc = ssh_get_pubkey_hash(session, (unsigned char **)&hash); -+ if (ssh_fips_mode()) { -+ /* When in FIPS mode, expect the call to fail */ -+ assert_int_equal(rc, SSH_ERROR); -+ } else { -+ assert_int_equal(rc, MD5_DIGEST_LEN); -+ -+ hexa = ssh_get_hexa((unsigned char *)hash, rc); -+ SSH_STRING_FREE_CHAR(hash); -+ assert_string_equal(hexa, -+ "ee:80:7f:61:f9:d5:be:f1:96:86:cc:96:7a:db:7a:7b"); -+ -+ SSH_STRING_FREE_CHAR(hexa); -+ } -+} -+ - int torture_run_tests(void) { - int rc; - struct CMUnitTest tests[] = { -@@ -421,6 +453,9 @@ int torture_run_tests(void) { - cmocka_unit_test_setup_teardown(torture_freed_channel_get_exit_status, - session_setup, - session_teardown), -+ cmocka_unit_test_setup_teardown(torture_pubkey_hash, -+ session_setup, -+ session_teardown), - }; - - ssh_init(); --- -2.33.0 - diff --git a/libssh-0.10.5.tar.xz b/libssh-0.10.5.tar.xz deleted file mode 100644 index 2a2603fce87e03459cfd117cd0fb7c6ab2f1b80c..0000000000000000000000000000000000000000 Binary files a/libssh-0.10.5.tar.xz and /dev/null differ diff --git a/libssh-0.10.5.tar.xz.asc b/libssh-0.10.5.tar.xz.asc deleted file mode 100644 index 01c568576e041899e9643d765070c88306fb4e28..0000000000000000000000000000000000000000 --- a/libssh-0.10.5.tar.xz.asc +++ /dev/null @@ -1,16 +0,0 @@ ------BEGIN PGP SIGNATURE----- - -iQIzBAABCgAdFiEEjf9T4Y8qvI2PPJIjfuD8TcwBTj0FAmRTm30ACgkQfuD8TcwB -Tj0TBQ/+MS5qNXgV8I/3s0k6jpzTsEMdozOZ7RYiJg9i9UzCGsIuJ0aiMl+G1aFH -UJOkLlHgGXTSCeZk4aoSTky2jEOezcFgsi0v9j8nmxRTjlDDAY0KxOoA//wc5nQ0 -fgQKUbX0SrtIbe9qpffoGBjaEap2ICAiM7a5PJ+Js0RQ944TqmkWmhGP/2XhxsF9 -0TJ6e4ilSg/mTBV5GemLTRSc+MgFoh5jJiV1+zmkOw5bBvPx7/KgsdmhoZ63prFI -8LvfChEEx50lyTXC8eLW4uSvO5tMHyAwDNBJcKOccp5yqEr147S1pZL8iNS0C2EF -/vG7zRDa3dv81xJjuPVdO40/GE77omp1IWC3i4ZskaAocGOmHo7KSwJ/7MjtAuJT -QgqeTPHjENRYbB6FvyesHpWzesORFIxQtCMxugVpEPcc3WLIRNLvJGa7rofAGJJf -u5uLyzmBuyAWm5gpPMyLRy2ysAgBi7NVusnAuR4v28r8YYpGrwTG+epJ1fV6MKWV -tlV8aCY51H7WVmDNJlwyJOwEZWzRdi9n3e22hEm79+cj3WKY3uwYwJI4s0CgcsUw -OzEZt97Yy+pSvdOokgNHRz0tGoDXZw55PF4+mcyvXSQfZJ2QCL7q7dJ/7DmibGgY -LtsN5bSfzXgEBqpty/sD5HSSt1/fNICJjfuiTKtjKXMD45wBUkE= -=IAN/ ------END PGP SIGNATURE----- diff --git a/libssh-0.10.6.tar.xz b/libssh-0.10.6.tar.xz new file mode 100644 index 0000000000000000000000000000000000000000..8ee7d6ea559eb8a701b364526daf14d898410638 Binary files /dev/null and b/libssh-0.10.6.tar.xz differ diff --git a/libssh-0.10.6.tar.xz.asc b/libssh-0.10.6.tar.xz.asc new file mode 100644 index 0000000000000000000000000000000000000000..bf9c36479583f4d0524de7c5f20b89b20e38444b --- /dev/null +++ b/libssh-0.10.6.tar.xz.asc @@ -0,0 +1,16 @@ +-----BEGIN PGP SIGNATURE----- + +iQIzBAABCgAdFiEEjf9T4Y8qvI2PPJIjfuD8TcwBTj0FAmWAeGkACgkQfuD8TcwB +Tj2yAw//QOMEcCiijJvOgXCKsVoV9oSuK3aYxqpOS9cV2P40eev0KQrAZC2EXNt3 +XAdfNhA21b2C6qSxckmkCWg3vwPmM6LousHG+zpyZkiSziolMoeBkvbEdU42fufE +SD39cA1bBEbZahyrILWT2I3Bi0d0G7FC13tIBXShS2zIITSXs/2SSRIhg3OXB979 +FTwvEE4zHeSXO4itTMNA/sMJ/0qPccQIzisH0g/TF4318b0qjlQjkHJS1y0f3/PL +Ge3RORQVcZqGTnhJNlF/tKD8wZ9mfqqurQ9yNshiAu8hH8sDH5ZhI3o5pjQe0mGO +JNEwTw0X/vZ4iglWFmm2CusiHrh0KUFsrp8f3oaL3HU4i7yYgo0FhzFtgFVt0gXO +JQOhlSUq50yqbBj6S9C5ecuSR0uPgYA4d8qCFrt9oD77m7Qi3mMi+f/kP+HctIaV +4ro7lZf6IS54J4/m5hRY3F0nweFnZZL8gn8Da8mBZSvhXCqQL6qbD9buwrTzxGft +Fct7+PrRwz9igO7j2nNMyWxtX55/GpX06n7vuonRgQQQiT8eQ5R71STMHJaACFPS +CJHCpuVL28HGdyAxN5d65TCvkNo9/gFGM6ocIH3OlreTFUvy22qNrqwHpCkLgYWU +ylntVoE/VYtHtwFOe0uuCX+2TiM03P5UT2NqAAa/8D4Z5ur3qUY= +=nXW5 +-----END PGP SIGNATURE----- diff --git a/libssh.spec b/libssh.spec index 2fb34fc551ceb2f61ef67cea828abd3b2496228c..803b5d5129b7df55e17e80f39b6495c7e9d93d2c 100644 --- a/libssh.spec +++ b/libssh.spec @@ -1,6 +1,6 @@ Name: libssh -Version: 0.10.5 -Release: 2 +Version: 0.10.6 +Release: 1 Summary: A library implementing the SSH protocol License: LGPLv2+ URL: http://www.libssh.org @@ -9,25 +9,6 @@ Source0: https://www.libssh.org/files/0.10/%{name}-%{version}.tar.xz Source1: https://www.libssh.org/files/0.10/%{name}-%{version}.tar.xz.asc Source2: https://cryptomilk.org/gpgkey-8DFF53E18F2ABC8D8F3C92237EE0FC4DCC014E3D.gpg#/%{name}.keyring -Patch1: backport-0001-CVE-2023-6004-torture_config-Allow-multiple-in-usern.patch -Patch2: backport-0002-CVE-2023-6004-config_parser-Allow-multiple-in-userna.patch -Patch3: backport-0003-CVE-2023-6004-options-Simplify-the-hostname-parsing-.patch -Patch4: backport-0004-CVE-2023-6004-misc-Add-function-to-check-allowed-cha.patch -Patch5: backport-0005-CVE-2023-6004-torture_misc-Add-test-for-ssh_check_ho.patch -Patch6: backport-0006-CVE-2023-6004-config_parser-Check-for-valid-syntax-o.patch -Patch7: backport-0007-CVE-2023-6004-torture_proxycommand-Add-test-for-prox.patch -Patch8: backport-0008-CVE-2023-6004-torture_misc-Add-test-for-ssh_is_ipadd.patch -Patch9: backport-0009-CVE-2023-6004-misc-Add-ipv6-link-local-check-for-an-.patch -Patch10: backport-0010-CVE-2023-6004-torture_misc-Add-tests-for-ipv6-link-l.patch -Patch11: backport-0011-CVE-2023-48795-client-side-mitigation.patch -Patch12: backport-0012-CVE-2023-48795-Server-side-mitigations.patch -Patch13: backport-0013-CVE-2023-48795-Strip-extensions-from-both-kex-lists-.patch -Patch14: backport-0014-CVE-2023-48795-tests-Adjust-calculation-to-strict-ke.patch -Patch15: backport-0015-CVE-2023-6918-kdf-Reformat.patch -Patch16: backport-0016-CVE-2023-6918-Remove-unused-evp-functions-and-types.patch -Patch17: backport-0017-CVE-2023-6918-Systematically-check-return-values-whe.patch -Patch18: backport-0018-CVE-2023-6918-kdf-Detect-context-init-failures.patch -Patch19: backport-0019-CVE-2023-6918-tests-Code-coverage-for-ssh_get_pubkey.patch BuildRequires: cmake gcc-c++ gnupg2 openssl-devel pkgconfig zlib-devel BuildRequires: krb5-devel libcmocka-devel openssh-clients openssh-server @@ -113,6 +94,15 @@ popd %doc CHANGELOG README %changelog +* Tue Jul 09 2024 liweigang - 0.10.6-1 +- Type: requirement +- Id: NA +- SUG: NA +- DESC: update to 0.10.6 + Fix ssh_send_issue_banner() for CMD(PowerShell) + Avoid passing other events to callbacks when poll is called recursively (#202) + Allow @ in usernames when parsing from URI composes + * Thu Jan 4 2024 renmingshuai - 0.10.5-2 - Type:CVE - Id:CVE-2023-6004,CVE-2023-48795,CVE-2023-6918