Toshaan Bharvani
11 months ago
5 changed files with 294 additions and 10 deletions
@ -0,0 +1,38 @@
@@ -0,0 +1,38 @@
|
||||
diff --git a/compat.c b/compat.c |
||||
index 46dfe3a9c2e..478a9403eea 100644 |
||||
--- a/compat.c |
||||
+++ b/compat.c |
||||
@@ -190,26 +190,26 @@ compat_pkalg_proposal(struct ssh *ssh, char *pkalg_prop) |
||||
char * |
||||
compat_kex_proposal(struct ssh *ssh, char *p) |
||||
{ |
||||
- char *cp = NULL; |
||||
+ char *cp = NULL, *cp2 = NULL; |
||||
|
||||
if ((ssh->compat & (SSH_BUG_CURVE25519PAD|SSH_OLD_DHGEX)) == 0) |
||||
return xstrdup(p); |
||||
debug2_f("original KEX proposal: %s", p); |
||||
if ((ssh->compat & SSH_BUG_CURVE25519PAD) != 0) |
||||
- if ((p = match_filter_denylist(p, |
||||
+ if ((cp = match_filter_denylist(p, |
||||
"curve25519-sha256@libssh.org")) == NULL) |
||||
fatal("match_filter_denylist failed"); |
||||
if ((ssh->compat & SSH_OLD_DHGEX) != 0) { |
||||
- cp = p; |
||||
- if ((p = match_filter_denylist(p, |
||||
+ if ((cp2 = match_filter_denylist(cp ? cp : p, |
||||
"diffie-hellman-group-exchange-sha256," |
||||
"diffie-hellman-group-exchange-sha1")) == NULL) |
||||
fatal("match_filter_denylist failed"); |
||||
free(cp); |
||||
+ cp = cp2; |
||||
} |
||||
- debug2_f("compat KEX proposal: %s", p); |
||||
- if (*p == '\0') |
||||
+ if (cp == NULL || *cp == '\0') |
||||
fatal("No supported key exchange algorithms found"); |
||||
- return p; |
||||
+ debug2_f("compat KEX proposal: %s", cp); |
||||
+ return cp; |
||||
} |
||||
|
@ -0,0 +1,100 @@
@@ -0,0 +1,100 @@
|
||||
diff -up openssh-8.7p1/compat.c.sshrsacheck openssh-8.7p1/compat.c |
||||
--- openssh-8.7p1/compat.c.sshrsacheck 2023-01-12 13:29:06.338710923 +0100 |
||||
+++ openssh-8.7p1/compat.c 2023-01-12 13:29:06.357711165 +0100 |
||||
@@ -43,6 +43,7 @@ void |
||||
compat_banner(struct ssh *ssh, const char *version) |
||||
{ |
||||
int i; |
||||
+ int forbid_ssh_rsa = 0; |
||||
static struct { |
||||
char *pat; |
||||
int bugs; |
||||
@@ -145,16 +146,21 @@ compat_banner(struct ssh *ssh, const cha |
||||
}; |
||||
|
||||
/* process table, return first match */ |
||||
+ forbid_ssh_rsa = (ssh->compat & SSH_RH_RSASIGSHA); |
||||
ssh->compat = 0; |
||||
for (i = 0; check[i].pat; i++) { |
||||
if (match_pattern_list(version, check[i].pat, 0) == 1) { |
||||
debug_f("match: %s pat %s compat 0x%08x", |
||||
version, check[i].pat, check[i].bugs); |
||||
ssh->compat = check[i].bugs; |
||||
+ if (forbid_ssh_rsa) |
||||
+ ssh->compat |= SSH_RH_RSASIGSHA; |
||||
return; |
||||
} |
||||
} |
||||
debug_f("no match: %s", version); |
||||
+ if (forbid_ssh_rsa) |
||||
+ ssh->compat |= SSH_RH_RSASIGSHA; |
||||
} |
||||
|
||||
/* Always returns pointer to allocated memory, caller must free. */ |
||||
diff -up openssh-8.7p1/compat.h.sshrsacheck openssh-8.7p1/compat.h |
||||
--- openssh-8.7p1/compat.h.sshrsacheck 2021-08-20 06:03:49.000000000 +0200 |
||||
+++ openssh-8.7p1/compat.h 2023-01-12 13:29:06.358711178 +0100 |
||||
@@ -30,7 +30,7 @@ |
||||
#define SSH_BUG_UTF8TTYMODE 0x00000001 |
||||
#define SSH_BUG_SIGTYPE 0x00000002 |
||||
#define SSH_BUG_SIGTYPE74 0x00000004 |
||||
-/* #define unused 0x00000008 */ |
||||
+#define SSH_RH_RSASIGSHA 0x00000008 |
||||
#define SSH_OLD_SESSIONID 0x00000010 |
||||
/* #define unused 0x00000020 */ |
||||
#define SSH_BUG_DEBUG 0x00000040 |
||||
diff -up openssh-8.7p1/serverloop.c.sshrsacheck openssh-8.7p1/serverloop.c |
||||
--- openssh-8.7p1/serverloop.c.sshrsacheck 2023-01-12 14:57:08.118400073 +0100 |
||||
+++ openssh-8.7p1/serverloop.c 2023-01-12 14:59:17.330470518 +0100 |
||||
@@ -737,6 +737,10 @@ server_input_hostkeys_prove(struct ssh * |
||||
else if (ssh->kex->flags & KEX_RSA_SHA2_256_SUPPORTED) |
||||
sigalg = "rsa-sha2-256"; |
||||
} |
||||
+ if (ssh->compat & SSH_RH_RSASIGSHA && sigalg == NULL) { |
||||
+ sigalg = "rsa-sha2-512"; |
||||
+ debug3_f("SHA1 signature is not supported, falling back to %s", sigalg); |
||||
+ } |
||||
debug3_f("sign %s key (index %d) using sigalg %s", |
||||
sshkey_type(key), ndx, sigalg == NULL ? "default" : sigalg); |
||||
if ((r = sshbuf_put_cstring(sigbuf, |
||||
diff -up openssh-8.7p1/sshd.c.sshrsacheck openssh-8.7p1/sshd.c |
||||
--- openssh-8.7p1/sshd.c.sshrsacheck 2023-01-12 13:29:06.355711140 +0100 |
||||
+++ openssh-8.7p1/sshd.c 2023-01-12 13:29:06.358711178 +0100 |
||||
@@ -1640,6 +1651,7 @@ main(int ac, char **av) |
||||
int keytype; |
||||
Authctxt *authctxt; |
||||
struct connection_info *connection_info = NULL; |
||||
+ int forbid_ssh_rsa = 0; |
||||
|
||||
#ifdef HAVE_SECUREWARE |
||||
(void)set_auth_parameters(ac, av); |
||||
@@ -1938,6 +1950,19 @@ main(int ac, char **av) |
||||
key = NULL; |
||||
continue; |
||||
} |
||||
+ if (key && (sshkey_type_plain(key->type) == KEY_RSA || sshkey_type_plain(key->type) == KEY_RSA_CERT)) { |
||||
+ size_t sign_size = 0; |
||||
+ u_char *tmp = NULL; |
||||
+ u_char data[] = "Test SHA1 vector"; |
||||
+ int res; |
||||
+ |
||||
+ res = ssh_rsa_sign(key, &tmp, &sign_size, data, sizeof(data), NULL); |
||||
+ free(tmp); |
||||
+ if (res == SSH_ERR_LIBCRYPTO_ERROR) { |
||||
+ logit_f("sshd: ssh-rsa algorithm is disabled"); |
||||
+ forbid_ssh_rsa = 1; |
||||
+ } |
||||
+ } |
||||
if (sshkey_is_sk(key) && |
||||
key->sk_flags & SSH_SK_USER_PRESENCE_REQD) { |
||||
debug("host key %s requires user presence, ignoring", |
||||
@@ -2275,6 +2306,9 @@ main(int ac, char **av) |
||||
|
||||
check_ip_options(ssh); |
||||
|
||||
+ if (forbid_ssh_rsa) |
||||
+ ssh->compat |= SSH_RH_RSASIGSHA; |
||||
+ |
||||
/* Prepare the channels layer */ |
||||
channel_init_channels(ssh); |
||||
channel_set_af(ssh, options.address_family); |
@ -0,0 +1,57 @@
@@ -0,0 +1,57 @@
|
||||
diff --git a/ssh-keyscan.c b/ssh-keyscan.c |
||||
index d29a03b4..d7283136 100644 |
||||
--- a/ssh-keyscan.c |
||||
+++ b/ssh-keyscan.c |
||||
@@ -490,6 +490,15 @@ congreet(int s) |
||||
return; |
||||
} |
||||
|
||||
+ /* |
||||
+ * Read the server banner as per RFC4253 section 4.2. The "SSH-" |
||||
+ * protocol identification string may be preceeded by an arbitarily |
||||
+ * large banner which we must read and ignore. Loop while reading |
||||
+ * newline-terminated lines until we have one starting with "SSH-". |
||||
+ * The ID string cannot be longer than 255 characters although the |
||||
+ * preceeding banner lines may (in which case they'll be discarded |
||||
+ * in multiple iterations of the outer loop). |
||||
+ */ |
||||
for (;;) { |
||||
memset(buf, '\0', sizeof(buf)); |
||||
bufsiz = sizeof(buf); |
||||
@@ -517,6 +526,11 @@ congreet(int s) |
||||
conrecycle(s); |
||||
return; |
||||
} |
||||
+ if (cp >= buf + sizeof(buf)) { |
||||
+ error("%s: greeting exceeds allowable length", c->c_name); |
||||
+ confree(s); |
||||
+ return; |
||||
+ } |
||||
if (*cp != '\n' && *cp != '\r') { |
||||
error("%s: bad greeting", c->c_name); |
||||
confree(s); |
||||
diff --git a/sshsig.c b/sshsig.c |
||||
index 1e3b6398..eb2a931e 100644 |
||||
--- a/sshsig.c |
||||
+++ b/sshsig.c |
||||
@@ -491,7 +491,7 @@ hash_file(int fd, const char *hashalg, struct sshbuf **bp) |
||||
{ |
||||
char *hex, rbuf[8192], hash[SSH_DIGEST_MAX_LENGTH]; |
||||
ssize_t n, total = 0; |
||||
- struct ssh_digest_ctx *ctx; |
||||
+ struct ssh_digest_ctx *ctx = NULL; |
||||
int alg, oerrno, r = SSH_ERR_INTERNAL_ERROR; |
||||
struct sshbuf *b = NULL; |
||||
|
||||
@@ -549,9 +548,11 @@ hash_file(int fd, const char *hashalg, struct sshbuf **bp) |
||||
/* success */ |
||||
r = 0; |
||||
out: |
||||
+ oerrno = errno; |
||||
sshbuf_free(b); |
||||
ssh_digest_free(ctx); |
||||
explicit_bzero(hash, sizeof(hash)); |
||||
+ errno = oerrno; |
||||
return r; |
||||
} |
||||
|
Loading…
Reference in new issue