summaryrefslogtreecommitdiffstats
path: root/meta/recipes-connectivity/openssh/openssh/CVE-2023-38408-05.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-connectivity/openssh/openssh/CVE-2023-38408-05.patch')
-rw-r--r--meta/recipes-connectivity/openssh/openssh/CVE-2023-38408-05.patch194
1 files changed, 194 insertions, 0 deletions
diff --git a/meta/recipes-connectivity/openssh/openssh/CVE-2023-38408-05.patch b/meta/recipes-connectivity/openssh/openssh/CVE-2023-38408-05.patch
new file mode 100644
index 0000000000..0ddbdc68d4
--- /dev/null
+++ b/meta/recipes-connectivity/openssh/openssh/CVE-2023-38408-05.patch
@@ -0,0 +1,194 @@
1From a6cee3905edf070c0de135d3f2ee5b74da1dbd28 Mon Sep 17 00:00:00 2001
2From: "djm@openbsd.org" <djm@openbsd.org>
3Date: Tue, 26 May 2020 01:26:58 +0000
4Subject: [PATCH 05/12] upstream: Restrict ssh-agent from signing web
5 challenges for FIDO
6
7keys.
8
9When signing messages in ssh-agent using a FIDO key that has an
10application string that does not start with "ssh:", ensure that the
11message being signed is one of the forms expected for the SSH protocol
12(currently pubkey authentication and sshsig signatures).
13
14This prevents ssh-agent forwarding on a host that has FIDO keys
15attached granting the ability for the remote side to sign challenges
16for web authentication using those keys too.
17
18Note that the converse case of web browsers signing SSH challenges is
19already precluded because no web RP can have the "ssh:" prefix in the
20application string that we require.
21
22ok markus@
23
24OpenBSD-Commit-ID: 9ab6012574ed0352d2f097d307f4a988222d1b19
25
26Upstream-Status: Backport [https://github.com/openssh/openssh-portable/commit/0c111eb84efba7c2a38b2cc3278901a0123161b9]
27CVE: CVE-2023-38408
28Signed-off-by: Shubham Kulkarni <skulkarni@mvista.com>
29---
30 ssh-agent.c | 110 +++++++++++++++++++++++++++++++++++++++++++++++-----
31 1 file changed, 100 insertions(+), 10 deletions(-)
32
33diff --git a/ssh-agent.c b/ssh-agent.c
34index ceb348c..1794f35 100644
35--- a/ssh-agent.c
36+++ b/ssh-agent.c
37@@ -1,4 +1,4 @@
38-/* $OpenBSD: ssh-agent.c,v 1.255 2020/02/06 22:30:54 naddy Exp $ */
39+/* $OpenBSD: ssh-agent.c,v 1.258 2020/05/26 01:26:58 djm Exp $ */
40 /*
41 * Author: Tatu Ylonen <ylo@cs.hut.fi>
42 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
43@@ -77,6 +77,7 @@
44
45 #include "xmalloc.h"
46 #include "ssh.h"
47+#include "ssh2.h"
48 #include "sshbuf.h"
49 #include "sshkey.h"
50 #include "authfd.h"
51@@ -167,6 +168,9 @@ static long lifetime = 0;
52
53 static int fingerprint_hash = SSH_FP_HASH_DEFAULT;
54
55+/* Refuse signing of non-SSH messages for web-origin FIDO keys */
56+static int restrict_websafe = 1;
57+
58 static void
59 close_socket(SocketEntry *e)
60 {
61@@ -282,6 +286,80 @@ agent_decode_alg(struct sshkey *key, u_int flags)
62 return NULL;
63 }
64
65+/*
66+ * This function inspects a message to be signed by a FIDO key that has a
67+ * web-like application string (i.e. one that does not begin with "ssh:".
68+ * It checks that the message is one of those expected for SSH operations
69+ * (pubkey userauth, sshsig, CA key signing) to exclude signing challenges
70+ * for the web.
71+ */
72+static int
73+check_websafe_message_contents(struct sshkey *key,
74+ const u_char *msg, size_t len)
75+{
76+ int matched = 0;
77+ struct sshbuf *b;
78+ u_char m, n;
79+ char *cp1 = NULL, *cp2 = NULL;
80+ int r;
81+ struct sshkey *mkey = NULL;
82+
83+ if ((b = sshbuf_from(msg, len)) == NULL)
84+ fatal("%s: sshbuf_new", __func__);
85+
86+ /* SSH userauth request */
87+ if ((r = sshbuf_get_string_direct(b, NULL, NULL)) == 0 && /* sess_id */
88+ (r = sshbuf_get_u8(b, &m)) == 0 && /* SSH2_MSG_USERAUTH_REQUEST */
89+ (r = sshbuf_get_cstring(b, NULL, NULL)) == 0 && /* server user */
90+ (r = sshbuf_get_cstring(b, &cp1, NULL)) == 0 && /* service */
91+ (r = sshbuf_get_cstring(b, &cp2, NULL)) == 0 && /* method */
92+ (r = sshbuf_get_u8(b, &n)) == 0 && /* sig-follows */
93+ (r = sshbuf_get_cstring(b, NULL, NULL)) == 0 && /* alg */
94+ (r = sshkey_froms(b, &mkey)) == 0 && /* key */
95+ sshbuf_len(b) == 0) {
96+ debug("%s: parsed userauth", __func__);
97+ if (m == SSH2_MSG_USERAUTH_REQUEST && n == 1 &&
98+ strcmp(cp1, "ssh-connection") == 0 &&
99+ strcmp(cp2, "publickey") == 0 &&
100+ sshkey_equal(key, mkey)) {
101+ debug("%s: well formed userauth", __func__);
102+ matched = 1;
103+ }
104+ }
105+ free(cp1);
106+ free(cp2);
107+ sshkey_free(mkey);
108+ sshbuf_free(b);
109+ if (matched)
110+ return 1;
111+
112+ if ((b = sshbuf_from(msg, len)) == NULL)
113+ fatal("%s: sshbuf_new", __func__);
114+ cp1 = cp2 = NULL;
115+ mkey = NULL;
116+
117+ /* SSHSIG */
118+ if ((r = sshbuf_cmp(b, 0, "SSHSIG", 6)) == 0 &&
119+ (r = sshbuf_consume(b, 6)) == 0 &&
120+ (r = sshbuf_get_cstring(b, NULL, NULL)) == 0 && /* namespace */
121+ (r = sshbuf_get_string_direct(b, NULL, NULL)) == 0 && /* reserved */
122+ (r = sshbuf_get_cstring(b, NULL, NULL)) == 0 && /* hashalg */
123+ (r = sshbuf_get_string_direct(b, NULL, NULL)) == 0 && /* H(msg) */
124+ sshbuf_len(b) == 0) {
125+ debug("%s: parsed sshsig", __func__);
126+ matched = 1;
127+ }
128+
129+ sshbuf_free(b);
130+ if (matched)
131+ return 1;
132+
133+ /* XXX CA signature operation */
134+
135+ error("web-origin key attempting to sign non-SSH message");
136+ return 0;
137+}
138+
139 /* ssh2 only */
140 static void
141 process_sign_request2(SocketEntry *e)
142@@ -314,14 +392,20 @@ process_sign_request2(SocketEntry *e)
143 verbose("%s: user refused key", __func__);
144 goto send;
145 }
146- if (sshkey_is_sk(id->key) &&
147- (id->key->sk_flags & SSH_SK_USER_PRESENCE_REQD)) {
148- if ((fp = sshkey_fingerprint(key, SSH_FP_HASH_DEFAULT,
149- SSH_FP_DEFAULT)) == NULL)
150- fatal("%s: fingerprint failed", __func__);
151- notifier = notify_start(0,
152- "Confirm user presence for key %s %s",
153- sshkey_type(id->key), fp);
154+ if (sshkey_is_sk(id->key)) {
155+ if (strncmp(id->key->sk_application, "ssh:", 4) != 0 &&
156+ !check_websafe_message_contents(key, data, dlen)) {
157+ /* error already logged */
158+ goto send;
159+ }
160+ if ((id->key->sk_flags & SSH_SK_USER_PRESENCE_REQD)) {
161+ if ((fp = sshkey_fingerprint(key, SSH_FP_HASH_DEFAULT,
162+ SSH_FP_DEFAULT)) == NULL)
163+ fatal("%s: fingerprint failed", __func__);
164+ notifier = notify_start(0,
165+ "Confirm user presence for key %s %s",
166+ sshkey_type(id->key), fp);
167+ }
168 }
169 if ((r = sshkey_sign(id->key, &signature, &slen,
170 data, dlen, agent_decode_alg(key, flags),
171@@ -1214,7 +1298,7 @@ main(int ac, char **av)
172 __progname = ssh_get_progname(av[0]);
173 seed_rng();
174
175- while ((ch = getopt(ac, av, "cDdksE:a:P:t:")) != -1) {
176+ while ((ch = getopt(ac, av, "cDdksE:a:O:P:t:")) != -1) {
177 switch (ch) {
178 case 'E':
179 fingerprint_hash = ssh_digest_alg_by_name(optarg);
180@@ -1229,6 +1313,12 @@ main(int ac, char **av)
181 case 'k':
182 k_flag++;
183 break;
184+ case 'O':
185+ if (strcmp(optarg, "no-restrict-websafe") == 0)
186+ restrict_websafe = 0;
187+ else
188+ fatal("Unknown -O option");
189+ break;
190 case 'P':
191 if (provider_whitelist != NULL)
192 fatal("-P option already specified");
193--
1942.41.0