The patch relaxes buf_verify()'s "Non-matching signing type" check so
that an rsa-sha2-256 signature is accepted against an ssh-rsa key.
Dropbear no longer needs the help: both sides of that comparison are now
taken from the wire's own algorithm names, so a compliant client
satisfies expect_sigtype == sigtype unaided.
Tracing the provenance in 2026.92, since it is what the removal rests
on. svr-authpubkey.c:113 reads the algorithm name out of the
SSH_MSG_USERAUTH_REQUEST and :126 turns it into sigtype with
signature_type_from_name(); that value is what :233 hands to buf_verify()
as expect_sigtype. signkey.c:655 parses the type name out of the
signature blob through the same signature_type_from_name(), and :659
compares the two. Neither is derived from the key format found in
authorized_keys: :132 maps the signature type back to the key algorithm
with signkey_type_from_signature() purely for the checkpubkey() lookup.
RFC 8332 section 3 has a client using rsa-sha2-256 send that name in the
userauth request and in the signature both, so the two agree and the
check passes - with an ssh-rsa key in authorized_keys, which is the case
the patch was written for.
Confirmed rather than reasoned: built pristine 2026.92 with this
package's defaults (DROPBEAR_RSA 1, DROPBEAR_RSA_SHA1 0) and logged in
over publickey with an OpenSSH client pinned to
PubkeyAcceptedAlgorithms=rsa-sha2-256. It succeeds, and the server
reports "Pubkey auth succeeded ... with ssh-rsa key" - an ssh-rsa entry
in authorized_keys, an rsa-sha2-256 signature, no patch.
Keeping the patch has an effect of its own. With DROPBEAR_RSA_SHA1 0,
signature_type_from_name("ssh-rsa") falls through to
signkey_type_from_name() and returns DROPBEAR_SIGNKEY_RSA, which is 0.
That is not DROPBEAR_SIGNATURE_NONE, so the patch's own "No signature
type" guard passes it, and expect_sigtype == DROPBEAR_SIGNATURE_RSA_SHA256
skips the type check. buf_rsa_verify() then calls rsa_pad_em(), whose
switch has no case for 0 and ends in default: assert(0), so the process
aborts. Upstream's unconditional check rejects the mismatch instead.
It is also narrower than upstream's in a second way: the replacement
sits inside #if DROPBEAR_RSA / #if DROPBEAR_RSA_SHA256, while the check
it displaces is unconditional. An ECDSA or
Ed25519 only build therefore
has no expect_sigtype check at all today, only the "No signature type"
guard. Dropping the patch restores the check for every configuration,
not just this package's default one.
buf_verify() runs only after checkpubkey() has succeeded, so the abort
needs a key already listed in the target's authorized_keys - post-auth,
not an authentication bypass.
The patch's extra DROPBEAR_SIGNATURE_NONE guard is not lost with it:
svr-authpubkey.c rejects that case before buf_verify() is reached.
Assisted-by: Claude:claude-opus-5
Signed-off-by: Julius Bairaktaris <julius@bairaktaris.de>
Link: https://github.com/openwrt/openwrt/pull/24525
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
PKG_NAME:=dropbear
PKG_VERSION:=2026.92
-PKG_RELEASE:=1
+PKG_RELEASE:=2
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
PKG_SOURCE_URL:= \
+++ /dev/null
-From 667d9b75df86ec9ee1205f9101beb8dbbe4a00ae Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Petr=20=C5=A0tetiar?= <ynezz@true.cz>
-Date: Wed, 1 Jul 2020 11:38:33 +0200
-Subject: [PATCH] signkey: fix use of rsa-sha2-256 pubkeys
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Commit 972d723484d8 ("split signkey_type and signature_type for RSA sha1
-vs sha256") has added strict checking of pubkey algorithms which made
-keys with SHA-256 hashing algorithm unusable as they still reuse the
-`ssh-rsa` public key format. So fix this by disabling the check for
-rsa-sha2-256 pubkeys.
-
-Ref: https://tools.ietf.org/html/rfc8332#section-3
-Fixes: 972d723484d8 ("split signkey_type and signature_type for RSA sha1 vs sha256")
-Signed-off-by: Petr Štetiar <ynezz@true.cz>
----
- signkey.c | 8 ++++++--
- 1 file changed, 6 insertions(+), 2 deletions(-)
-
---- a/src/signkey.c
-+++ b/src/signkey.c
-@@ -656,10 +656,18 @@ int buf_verify(buffer * buf, sign_key *k
- sigtype = signature_type_from_name(type_name, type_name_len);
- m_free(type_name);
-
-- if (expect_sigtype != sigtype) {
-- dropbear_exit("Non-matching signing type");
-+ if (sigtype == DROPBEAR_SIGNATURE_NONE) {
-+ dropbear_exit("No signature type");
- }
-
-+#if DROPBEAR_RSA
-+#if DROPBEAR_RSA_SHA256
-+ if ((expect_sigtype != DROPBEAR_SIGNATURE_RSA_SHA256) && (expect_sigtype != sigtype)) {
-+ dropbear_exit("Non-matching signing type");
-+ }
-+#endif
-+#endif
-+
- keytype = signkey_type_from_signature(sigtype);
- #if DROPBEAR_DSS
- if (keytype == DROPBEAR_SIGNKEY_DSS) {