changeset 1675:ae41624c2198

split signkey_type and signature_type for RSA sha1 vs sha256
author Matt Johnston <matt@ucc.asn.au>
date Sun, 17 May 2020 23:58:31 +0800
parents ba6fc7afe1c5
children d5cdc60db08e
files cli-authpubkey.c common-algo.c fuzzer-verify.c rsa.c rsa.h session.h signkey.c signkey.h ssh.h svr-authpubkey.c
diffstat 10 files changed, 148 insertions(+), 68 deletions(-) [+]
line wrap: on
line diff
--- a/cli-authpubkey.c	Mon Apr 06 23:18:26 2020 +0800
+++ b/cli-authpubkey.c	Sun May 17 23:58:31 2020 +0800
@@ -33,7 +33,7 @@
 #include "agentfwd.h"
 
 #if DROPBEAR_CLI_PUBKEY_AUTH
-static void send_msg_userauth_pubkey(sign_key *key, enum signkey_type sigtype, int realsign);
+static void send_msg_userauth_pubkey(sign_key *key, enum signature_type sigtype, int realsign);
 
 /* Called when we receive a SSH_MSG_USERAUTH_FAILURE for a pubkey request.
  * We use it to remove the key we tried from the list */
@@ -58,7 +58,8 @@
 	buffer* keybuf = NULL;
 	char* algotype = NULL;
 	unsigned int algolen;
-	enum signkey_type sigtype, keytype;
+	enum signkey_type keytype;
+	enum signature_type sigtype;
 	unsigned int remotelen;
 
 	TRACE(("enter recv_msg_userauth_pk_ok"))
@@ -113,7 +114,7 @@
 		TRACE(("matching key"))
 		/* XXX TODO: if it's an encrypted key, here we ask for their
 		 * password */
-		send_msg_userauth_pubkey((sign_key*)iter->item, keytype, 1);
+		send_msg_userauth_pubkey((sign_key*)iter->item, sigtype, 1);
 	} else {
 		TRACE(("That was whacky. We got told that a key was valid, but it didn't match our list. Sounds like dodgy code on Dropbear's part"))
 	}
@@ -121,7 +122,7 @@
 	TRACE(("leave recv_msg_userauth_pk_ok"))
 }
 
-static void cli_buf_put_sign(buffer* buf, sign_key *key, enum signkey_type sigtype,
+static void cli_buf_put_sign(buffer* buf, sign_key *key, enum signature_type sigtype,
 			const buffer *data_buf) {
 #if DROPBEAR_CLI_AGENTFWD
 	// TODO: rsa-sha256 agent
@@ -139,14 +140,14 @@
 	}
 }
 
-static void send_msg_userauth_pubkey(sign_key *key, enum signkey_type sigtype, int realsign) {
+static void send_msg_userauth_pubkey(sign_key *key, enum signature_type sigtype, int realsign) {
 
 	const char *algoname = NULL;
 	unsigned int algolen;
 	buffer* sigbuf = NULL;
 	enum signkey_type keytype = signkey_type_from_signature(sigtype);
 
-	TRACE(("enter send_msg_userauth_pubkey"))
+	TRACE(("enter send_msg_userauth_pubkey sigtype %d", sigtype))
 	CHECKCLEARTOWRITE();
 
 	buf_putbyte(ses.writepayload, SSH_MSG_USERAUTH_REQUEST);
@@ -183,7 +184,6 @@
 
 /* Returns 1 if a key was tried */
 int cli_auth_pubkey() {
-
 	TRACE(("enter cli_auth_pubkey"))
 
 #if DROPBEAR_CLI_AGENTFWD
@@ -194,16 +194,26 @@
 	}
 #endif
 
+	/* TODO iterate through privkeys to skip ones not in server-sig-algs */
+
+	/* TODO: testing */
+#if DROPBEAR_RSA_SHA256
+	cli_ses.preferred_rsa_sigtype = DROPBEAR_SIGNATURE_RSA_SHA256;
+#elif DROPBEAR_RSA_SHA1
+	cli_ses.preferred_rsa_sigtype = DROPBEAR_SIGNATURE_RSA_SHA1;
+#endif
+
 	if (cli_opts.privkeys->first) {
 		sign_key * key = (sign_key*)cli_opts.privkeys->first->item;
-		enum signkey_type sigtype = key->type;
-		/* Send a trial request */
-#if DROPBEAR_RSA && DROPBEAR_RSA_SHA256
-		// TODO: use ext-info to choose rsa kind
-		if (sigtype == DROPBEAR_SIGNKEY_RSA) {
-			sigtype = DROPBEAR_SIGNKEY_RSA_SHA256;
+		/* Determine the signature type to use */
+		enum signature_type sigtype = (enum signature_type)key->type;
+#if DROPBEAR_RSA 
+		if (key->type == DROPBEAR_SIGNKEY_RSA) {
+			sigtype = cli_ses.preferred_rsa_sigtype;
 		}
 #endif
+
+		/* Send a trial request */
 		send_msg_userauth_pubkey(key, sigtype, 0);
 		cli_ses.lastprivkey = key;
 		TRACE(("leave cli_auth_pubkey-success"))
--- a/common-algo.c	Mon Apr 06 23:18:26 2020 +0800
+++ b/common-algo.c	Sun May 17 23:58:31 2020 +0800
@@ -223,29 +223,29 @@
 
 algo_type sshhostkey[] = {
 #if DROPBEAR_ED25519
-	{"ssh-ed25519", DROPBEAR_SIGNKEY_ED25519, NULL, 1, NULL},
+	{"ssh-ed25519", DROPBEAR_SIGNATURE_ED25519, NULL, 1, NULL},
 #endif
 #if DROPBEAR_ECDSA
 #if DROPBEAR_ECC_256
-	{"ecdsa-sha2-nistp256", DROPBEAR_SIGNKEY_ECDSA_NISTP256, NULL, 1, NULL},
+	{"ecdsa-sha2-nistp256", DROPBEAR_SIGNATURE_ECDSA_NISTP256, NULL, 1, NULL},
 #endif
 #if DROPBEAR_ECC_384
-	{"ecdsa-sha2-nistp384", DROPBEAR_SIGNKEY_ECDSA_NISTP384, NULL, 1, NULL},
+	{"ecdsa-sha2-nistp384", DROPBEAR_SIGNATURE_ECDSA_NISTP384, NULL, 1, NULL},
 #endif
 #if DROPBEAR_ECC_521
-	{"ecdsa-sha2-nistp521", DROPBEAR_SIGNKEY_ECDSA_NISTP521, NULL, 1, NULL},
+	{"ecdsa-sha2-nistp521", DROPBEAR_SIGNATURE_ECDSA_NISTP521, NULL, 1, NULL},
 #endif
 #endif
 #if DROPBEAR_RSA
 #if DROPBEAR_RSA_SHA256
-	{"rsa-sha2-256", DROPBEAR_SIGNKEY_RSA_SHA256, NULL, 1, NULL},
+	{"rsa-sha2-256", DROPBEAR_SIGNATURE_RSA_SHA256, NULL, 1, NULL},
 #endif
 #if DROPBEAR_RSA_SHA1
-	{"ssh-rsa", DROPBEAR_SIGNKEY_RSA, NULL, 1, NULL},
+	{"ssh-rsa", DROPBEAR_SIGNATURE_RSA_SHA1, NULL, 1, NULL},
 #endif
 #endif
 #if DROPBEAR_DSS
-	{"ssh-dss", DROPBEAR_SIGNKEY_DSS, NULL, 1, NULL},
+	{"ssh-dss", DROPBEAR_SIGNATURE_DSS, NULL, 1, NULL},
 #endif
 	{NULL, 0, NULL, 0, NULL}
 };
@@ -263,8 +263,6 @@
 static const struct dropbear_kex kex_dh_group16_sha512 = {DROPBEAR_KEX_NORMAL_DH, dh_p_16, DH_P_16_LEN, NULL, &sha512_desc };
 #endif
 
-/* These can't be const since dropbear_ecc_fill_dp() fills out
- ecc_curve at runtime */
 #if DROPBEAR_ECDH
 #if DROPBEAR_ECC_256
 static const struct dropbear_kex kex_ecdh_nistp256 = {DROPBEAR_KEX_ECDH, NULL, 0, &ecc_curve_nistp256, &sha256_desc };
--- a/fuzzer-verify.c	Mon Apr 06 23:18:26 2020 +0800
+++ b/fuzzer-verify.c	Sun May 17 23:58:31 2020 +0800
@@ -27,15 +27,25 @@
 
 	if (setjmp(fuzz.jmp) == 0) {
 		sign_key *key = new_sign_key();
-		enum signkey_type type = DROPBEAR_SIGNKEY_ANY;
-		if (buf_get_pub_key(fuzz.input, key, &type) == DROPBEAR_SUCCESS) {
-			if (buf_verify(fuzz.input, key, verifydata) == DROPBEAR_SUCCESS) {
+		enum signkey_type keytype = DROPBEAR_SIGNKEY_ANY;
+		if (buf_get_pub_key(fuzz.input, key, &keytype) == DROPBEAR_SUCCESS) {
+			enum signature_type sigtype = (enum signature_type)keytype;
+			if (keytype == DROPBEAR_SIGNKEY_RSA) {
+				/* Flip a coin to decide rsa signature type */
+				int flag = buf_getbyte(fuzz_input);
+				if (flag & 0x01) {
+					sigtype = DROPBEAR_SIGNATURE_RSA_SHA256;
+				} else {
+					sigtype = DROPBEAR_SIGNATURE_RSA_SHA1;
+				}
+			}
+			if (buf_verify(fuzz.input, key, sigtype, verifydata) == DROPBEAR_SUCCESS) {
 				/* The fuzzer is capable of generating keys with a signature to match.
 				We don't want false positives if the key is bogus, since a client/server 
 				wouldn't be trusting a bogus key anyway */
 				int boguskey = 0;
 
-				if (type == DROPBEAR_SIGNKEY_DSS) {
+				if (keytype == DROPBEAR_SIGNKEY_DSS) {
 					/* So far have seen dss keys with bad p/q/g domain parameters */
 					int pprime, qprime, trials;
 					trials = mp_prime_rabin_miller_trials(mp_count_bits(key->dsskey->p));
--- a/rsa.c	Mon Apr 06 23:18:26 2020 +0800
+++ b/rsa.c	Sun May 17 23:58:31 2020 +0800
@@ -44,7 +44,7 @@
 #endif
 
 static void rsa_pad_em(const dropbear_rsa_key * key,
-	const buffer *data_buf, mp_int * rsa_em, enum signkey_type sigtype);
+	const buffer *data_buf, mp_int * rsa_em, enum signature_type sigtype);
 
 /* Load a public rsa key from a buffer, initialising the values.
  * The key will have the same format as buf_put_rsa_key.
@@ -197,7 +197,7 @@
 /* Verify a signature in buf, made on data by the key given.
  * Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */
 int buf_rsa_verify(buffer * buf, const dropbear_rsa_key *key, 
-		enum signkey_type sigtype, const buffer *data_buf) {
+		enum signature_type sigtype, const buffer *data_buf) {
 	unsigned int slen;
 	DEF_MP_INT(rsa_s);
 	DEF_MP_INT(rsa_mdash);
@@ -253,7 +253,7 @@
 /* Sign the data presented with key, writing the signature contents
  * to the buffer */
 void buf_put_rsa_sign(buffer* buf, const dropbear_rsa_key *key, 
-		enum signkey_type sigtype, const buffer *data_buf) {
+		enum signature_type sigtype, const buffer *data_buf) {
 	const char *name = NULL;
 	unsigned int nsize, ssize, namelen = 0;
 	unsigned int i;
@@ -352,7 +352,7 @@
 /* Creates the message value as expected by PKCS, 
    see rfc8017 section 9.2 */
 static void rsa_pad_em(const dropbear_rsa_key * key,
-	const buffer *data_buf, mp_int * rsa_em, enum signkey_type sigtype) {
+	const buffer *data_buf, mp_int * rsa_em, enum signature_type sigtype) {
     /* EM = 0x00 || 0x01 || PS || 0x00 || T 
 	   PS is padding of 0xff to make EM the size of key->n
 
@@ -380,14 +380,14 @@
 
 	switch (sigtype) {
 #if DROPBEAR_RSA_SHA1
-		case DROPBEAR_SIGNKEY_RSA:
+		case DROPBEAR_SIGNATURE_RSA_SHA1:
 			Tlen = sizeof(T_sha1);
 			T = T_sha1;
 			hash_desc = &sha1_desc;
 			break;
 #endif
 #if DROPBEAR_RSA_SHA256
-		case DROPBEAR_SIGNKEY_RSA_SHA256:
+		case DROPBEAR_SIGNATURE_RSA_SHA256:
 			Tlen = sizeof(T_sha256);
 			T = T_sha256;
 			hash_desc = &sha256_desc;
--- a/rsa.h	Mon Apr 06 23:18:26 2020 +0800
+++ b/rsa.h	Sun May 17 23:58:31 2020 +0800
@@ -43,10 +43,10 @@
 } dropbear_rsa_key;
 
 void buf_put_rsa_sign(buffer* buf, const dropbear_rsa_key *key, 
-        enum signkey_type sigtype, const buffer *data_buf);
+        enum signature_type sigtype, const buffer *data_buf);
 #if DROPBEAR_SIGNKEY_VERIFY
 int buf_rsa_verify(buffer * buf, const dropbear_rsa_key *key, 
-        enum signkey_type sigtype, const buffer *data_buf);
+        enum signature_type sigtype, const buffer *data_buf);
 #endif
 int buf_get_rsa_pub_key(buffer* buf, dropbear_rsa_key *key);
 int buf_get_rsa_priv_key(buffer* buf, dropbear_rsa_key *key);
--- a/session.h	Mon Apr 06 23:18:26 2020 +0800
+++ b/session.h	Sun May 17 23:58:31 2020 +0800
@@ -92,8 +92,8 @@
 	struct key_context_directional trans;
 
 	const struct dropbear_kex *algo_kex;
-	int algo_hostkey; /* server key type */
-	int algo_signature; /* server signature type */
+	enum signkey_type algo_hostkey; /* server key type */
+	enum signature_type algo_signature; /* server signature type */
 
 	int allow_compress; /* whether compression has started (useful in 
 							[email protected] delayed compression case) */
@@ -313,6 +313,14 @@
 #endif
 	sign_key *lastprivkey;
 
+	enum signature_type server_sig_algs[DROPBEAR_SIGNKEY_NUM_NAMED+1];
+	int server_sig_algs_count;
+#if DROPBEAR_RSA
+	/* Set to DROPBEAR_SIGNATURE_RSA_SHA256 or DROPBEAR_SIGNATURE_RSA_SHA1
+	if depending which the server accepts */
+	enum signature_type preferred_rsa_sigtype; 
+#endif
+
 	int retval; /* What the command exit status was - we emulate it */
 #if 0
 	TODO
--- a/signkey.c	Mon Apr 06 23:18:26 2020 +0800
+++ b/signkey.c	Sun May 17 23:58:31 2020 +0800
@@ -111,34 +111,52 @@
 
 /* Special case for rsa-sha2-256. This could be generalised if more 
    signature names are added that aren't 1-1 with public key names */
-const char* signature_name_from_type(enum signkey_type type, unsigned int *namelen) {
+const char* signature_name_from_type(enum signature_type type, unsigned int *namelen) {
 #if DROPBEAR_RSA_SHA256
-	if (type == DROPBEAR_SIGNKEY_RSA_SHA256) {
-		*namelen = strlen(SSH_SIGNKEY_RSA_SHA256);
-		return SSH_SIGNKEY_RSA_SHA256;
+	if (type == DROPBEAR_SIGNATURE_RSA_SHA256) {
+		*namelen = strlen(SSH_SIGNATURE_RSA_SHA256);
+		return SSH_SIGNATURE_RSA_SHA256;
 	}
 #endif
-	return signkey_name_from_type(type, namelen);
+#if DROPBEAR_RSA_SHA1
+	if (type == DROPBEAR_SIGNATURE_RSA_SHA1) {
+		*namelen = strlen(SSH_SIGNKEY_RSA);
+		return SSH_SIGNKEY_RSA;
+	}
+#endif
+	return signkey_name_from_type((enum signkey_type)type, namelen);
 }
 
-enum signkey_type signature_type_from_name(const char* name, unsigned int namelen) {
+/* Returns DROPBEAR_SIGNATURE_NONE if none match */
+enum signature_type signature_type_from_name(const char* name, unsigned int namelen) {
 #if DROPBEAR_RSA_SHA256
-	if (namelen == strlen(SSH_SIGNKEY_RSA_SHA256) 
-		&& memcmp(name, SSH_SIGNKEY_RSA_SHA256, namelen) == 0) {
-		return DROPBEAR_SIGNKEY_RSA_SHA256;
+	if (namelen == strlen(SSH_SIGNATURE_RSA_SHA256) 
+		&& memcmp(name, SSH_SIGNATURE_RSA_SHA256, namelen) == 0) {
+		return DROPBEAR_SIGNATURE_RSA_SHA256;
 	}
 #endif
-	return signkey_type_from_name(name, namelen);
+#if DROPBEAR_RSA_SHA256
+	if (namelen == strlen(SSH_SIGNKEY_RSA) 
+		&& memcmp(name, SSH_SIGNKEY_RSA, namelen) == 0) {
+		return DROPBEAR_SIGNATURE_RSA_SHA1;
+	}
+#endif
+	return (enum signature_type)signkey_type_from_name(name, namelen);
 }
 
-enum signkey_type signkey_type_from_signature(enum signkey_type sigtype) {
+enum signkey_type signkey_type_from_signature(enum signature_type sigtype) {
 #if DROPBEAR_RSA_SHA256
-	if (sigtype == DROPBEAR_SIGNKEY_RSA_SHA256) {
+	if (sigtype == DROPBEAR_SIGNATURE_RSA_SHA256) {
+		return DROPBEAR_SIGNKEY_RSA;
+	}
+#endif
+#if DROPBEAR_RSA_SHA1
+	if (sigtype == DROPBEAR_SIGNATURE_RSA_SHA1) {
 		return DROPBEAR_SIGNKEY_RSA;
 	}
 #endif
 	assert(sigtype < DROPBEAR_SIGNKEY_NUM_NAMED);
-	return sigtype;
+	return (enum signkey_type)sigtype;
 }
 
 /* Returns a pointer to the key part specific to "type".
@@ -562,11 +580,20 @@
 #endif
 }
 
-void buf_put_sign(buffer* buf, sign_key *key, enum signkey_type sigtype, 
+void buf_put_sign(buffer* buf, sign_key *key, enum signature_type sigtype, 
 	const buffer *data_buf) {
 	buffer *sigblob = buf_new(MAX_PUBKEY_SIZE);
 	enum signkey_type keytype = signkey_type_from_signature(sigtype);
 
+#if DEBUG_TRACE
+	{
+		int namelen;
+		const char* signame = signature_name_from_type(sigtype, &namelen);
+		TRACE(("buf_put_sign type %d %s", sigtype, signame));
+	}
+#endif
+
+
 #if DROPBEAR_DSS
 	if (keytype == DROPBEAR_SIGNKEY_DSS) {
 		buf_put_dss_sign(sigblob, key->dsskey, data_buf);
@@ -603,11 +630,12 @@
  * If FAILURE is returned, the position of
  * buf is undefined. If SUCCESS is returned, buf will be positioned after the
  * signature blob */
-int buf_verify(buffer * buf, sign_key *key, enum signkey_type expect_sigtype, const buffer *data_buf) {
+int buf_verify(buffer * buf, sign_key *key, enum signature_type expect_sigtype, const buffer *data_buf) {
 	
 	char *type_name = NULL;
 	unsigned int type_name_len = 0;
-	enum signkey_type sigtype, keytype;
+	enum signature_type sigtype;
+	enum signkey_type keytype;
 
 	TRACE(("enter buf_verify"))
 
@@ -616,8 +644,7 @@
 	sigtype = signature_type_from_name(type_name, type_name_len);
 	m_free(type_name);
 
-	if (expect_sigtype != DROPBEAR_SIGNKEY_ANY
-		&& expect_sigtype != sigtype) {
+	if (expect_sigtype != sigtype) {
 			dropbear_exit("Non-matching signing type");
 	}
 
--- a/signkey.h	Mon Apr 06 23:18:26 2020 +0800
+++ b/signkey.h	Sun May 17 23:58:31 2020 +0800
@@ -32,6 +32,7 @@
 struct dropbear_RSA_Key;
 struct dropbear_ED25519_Key;
 
+/* Must match with signature_type below */
 enum signkey_type {
 #if DROPBEAR_RSA
 	DROPBEAR_SIGNKEY_RSA,
@@ -49,13 +50,32 @@
 #endif
 	DROPBEAR_SIGNKEY_NUM_NAMED,
 	DROPBEAR_SIGNKEY_ECDSA_KEYGEN = 70, /* just "ecdsa" for keygen */
-#if DROPBEAR_RSA_SHA256
-	DROPBEAR_SIGNKEY_RSA_SHA256, /* rsa-sha2-256 signature. has a ssh-rsa key */
-#endif
 	DROPBEAR_SIGNKEY_ANY = 80,
 	DROPBEAR_SIGNKEY_NONE = 90,
 };
 
+/* Must match with signkey_type above, apart from rsa */
+enum signature_type {
+#if DROPBEAR_DSS
+	DROPBEAR_SIGNATURE_DSS = DROPBEAR_SIGNKEY_DSS,
+#endif
+#if DROPBEAR_ECDSA
+	DROPBEAR_SIGNATURE_ECDSA_NISTP256 = DROPBEAR_SIGNKEY_ECDSA_NISTP256,
+	DROPBEAR_SIGNATURE_ECDSA_NISTP384 = DROPBEAR_SIGNKEY_ECDSA_NISTP384,
+	DROPBEAR_SIGNATURE_ECDSA_NISTP521 = DROPBEAR_SIGNKEY_ECDSA_NISTP521,
+#endif /* DROPBEAR_ECDSA */
+#if DROPBEAR_ED25519
+	DROPBEAR_SIGNATURE_ED25519 = DROPBEAR_SIGNKEY_ED25519,
+#endif
+#if DROPBEAR_RSA_SHA1
+	DROPBEAR_SIGNATURE_RSA_SHA1 = 100, /* ssh-rsa signature (sha1) */
+#endif
+#if DROPBEAR_RSA_SHA256
+	DROPBEAR_SIGNATURE_RSA_SHA256 = 101, /* rsa-sha2-256 signature. has a ssh-rsa key */
+#endif
+	DROPBEAR_SIGNATURE_NONE = DROPBEAR_SIGNKEY_NONE,
+};
+
 
 /* Sources for signing keys */
 typedef enum {
@@ -97,17 +117,17 @@
 sign_key * new_sign_key(void);
 const char* signkey_name_from_type(enum signkey_type type, unsigned int *namelen);
 enum signkey_type signkey_type_from_name(const char* name, unsigned int namelen);
-const char* signature_name_from_type(enum signkey_type type, unsigned int *namelen);
-enum signkey_type signature_type_from_name(const char* name, unsigned int namelen);
-enum signkey_type signkey_type_from_signature(enum signkey_type sigtype);
+const char* signature_name_from_type(enum signature_type type, unsigned int *namelen);
+enum signature_type signature_type_from_name(const char* name, unsigned int namelen);
+enum signkey_type signkey_type_from_signature(enum signature_type sigtype);
 int buf_get_pub_key(buffer *buf, sign_key *key, enum signkey_type *type);
 int buf_get_priv_key(buffer* buf, sign_key *key, enum signkey_type *type);
 void buf_put_pub_key(buffer* buf, sign_key *key, enum signkey_type type);
 void buf_put_priv_key(buffer* buf, sign_key *key, enum signkey_type type);
 void sign_key_free(sign_key *key);
-void buf_put_sign(buffer* buf, sign_key *key, enum signkey_type sigtype, const buffer *data_buf);
+void buf_put_sign(buffer* buf, sign_key *key, enum signature_type sigtype, const buffer *data_buf);
 #if DROPBEAR_SIGNKEY_VERIFY
-int buf_verify(buffer * buf, sign_key *key, enum signkey_type type, const buffer *data_buf);
+int buf_verify(buffer * buf, sign_key *key, enum signature_type expect_sigtype, const buffer *data_buf);
 char * sign_key_fingerprint(const unsigned char* keyblob, unsigned int keybloblen);
 #endif
 int cmp_base64_key(const unsigned char* keyblob, unsigned int keybloblen, 
--- a/ssh.h	Mon Apr 06 23:18:26 2020 +0800
+++ b/ssh.h	Sun May 17 23:58:31 2020 +0800
@@ -108,7 +108,7 @@
 #define SSH_SIGNKEY_ED25519 "ssh-ed25519"
 #define SSH_SIGNKEY_ED25519_LEN 11
 /* signature type */
-#define SSH_SIGNKEY_RSA_SHA256 "rsa-sha2-256"
+#define SSH_SIGNATURE_RSA_SHA256 "rsa-sha2-256"
 
 /* Agent commands. These aren't part of the spec, and are defined
  * only on the openssh implementation. */
--- a/svr-authpubkey.c	Mon Apr 06 23:18:26 2020 +0800
+++ b/svr-authpubkey.c	Sun May 17 23:58:31 2020 +0800
@@ -92,7 +92,8 @@
 	buffer * signbuf = NULL;
 	sign_key * key = NULL;
 	char* fp = NULL;
-	enum signkey_type sigtype, keytype;
+	enum signature_type sigtype;
+	enum signkey_type keytype;
     int auth_failure = 1;
 
 	TRACE(("enter pubkeyauth"))
@@ -102,10 +103,6 @@
 	testkey = (buf_getbool(ses.payload) == 0);
 
 	sigalgo = buf_getstring(ses.payload, &sigalgolen);
-	sigtype = signature_type_from_name(sigalgo, sigalgolen);
-	keytype = signkey_type_from_signature(sigtype);
-	keyalgo = signkey_name_from_type(keytype, &keyalgolen);
-
 	keybloblen = buf_getint(ses.payload);
 	keyblob = buf_getptr(ses.payload, keybloblen);
 
@@ -117,6 +114,16 @@
 		send_msg_userauth_failure(0, 0);
 		goto out;
 	}
+
+	sigtype = signature_type_from_name(sigalgo, sigalgolen);
+	if (sigtype == DROPBEAR_SIGNATURE_NONE) {
+		send_msg_userauth_failure(0, 0);
+		goto out;
+	}
+
+	keytype = signkey_type_from_signature(sigtype);
+	keyalgo = signkey_name_from_type(keytype, &keyalgolen);
+
 #if DROPBEAR_PLUGIN
         if (svr_ses.plugin_instance != NULL) {
             char *options_buf;