diff signkey.c @ 1855:35d504d59c05

Implement server-side support for sk-ecdsa U2F-backed keys (#142) * Implement server-side support for sk-ecdsa U2F-backed keys * Fix out-of-bounds read on normal ecdsa-sha2-[identifier] keys * Fix one more potential out-of-bounds read * Check if nistp256 curve is used in sk-ecdsa-sha2- key It's the only allowed curve per PROTOCOL.u2f specification * Implement server-side support for sk-ed25519 FIDO2-backed keys * Keys with type sk-* make no sense as host keys, so they should be disabled * fix typo * Make sk-ecdsa call buf_ecdsa_verify This reduces code duplication, the SK code just handles the different message format. * Reduce sk specific code The application id can be stored in signkey, then we don't need to call sk-specific functions from svr-authpubkey * Remove debugging output, which causes compilation errors with DEBUG_TRACE disabled * Proper cleanup of sk_app Co-authored-by: Matt Johnston <[email protected]>
author egor-duda <egor-duda@users.noreply.github.com>
date Sat, 22 Jan 2022 16:53:04 +0300
parents fa6ff07dcc77
children 3f4cdf839a1a
line wrap: on
line diff
--- a/signkey.c	Sat Jan 22 12:46:08 2022 +0800
+++ b/signkey.c	Sat Jan 22 16:53:04 2022 +0300
@@ -28,6 +28,8 @@
 #include "buffer.h"
 #include "ssh.h"
 #include "ecdsa.h"
+#include "sk-ecdsa.h"
+#include "sk-ed25519.h"
 #include "rsa.h"
 #include "dss.h"
 #include "ed25519.h"
@@ -43,9 +45,15 @@
 	"ecdsa-sha2-nistp256",
 	"ecdsa-sha2-nistp384",
 	"ecdsa-sha2-nistp521",
+#if DROPBEAR_SK_ECDSA
+	"[email protected]",
+#endif /* DROPBEAR_SK_ECDSA */
 #endif /* DROPBEAR_ECDSA */
 #if DROPBEAR_ED25519
 	"ssh-ed25519",
+#if DROPBEAR_SK_ED25519
+	"[email protected]",
+#endif /* DROPBEAR_SK_ED25519 */
 #endif /* DROPBEAR_ED25519 */
 	/* "rsa-sha2-256" is special-cased below since it is only a signature name, not key type */
 };
@@ -180,11 +188,17 @@
 	switch (type) {
 #if DROPBEAR_ED25519
 		case DROPBEAR_SIGNKEY_ED25519:
+#if DROPBEAR_SK_ED25519
+		case DROPBEAR_SIGNKEY_SK_ED25519:
+#endif
 			return (void**)&key->ed25519key;
 #endif
 #if DROPBEAR_ECDSA
 #if DROPBEAR_ECC_256
 		case DROPBEAR_SIGNKEY_ECDSA_NISTP256:
+#if DROPBEAR_SK_ECDSA
+		case DROPBEAR_SIGNKEY_SK_ECDSA_NISTP256:
+#endif
 			return (void**)&key->ecckey256;
 #endif
 #if DROPBEAR_ECC_384
@@ -260,7 +274,11 @@
 	}
 #endif
 #if DROPBEAR_ECDSA
-	if (signkey_is_ecdsa(keytype)) {
+	if (signkey_is_ecdsa(keytype)
+#if DROPBEAR_SK_ECDSA
+		|| keytype == DROPBEAR_SIGNKEY_SK_ECDSA_NISTP256
+#endif
+	) {
 		ecc_key **eck = (ecc_key**)signkey_key_ptr(key, keytype);
 		if (eck) {
 			if (*eck) {
@@ -276,10 +294,14 @@
 	}
 #endif
 #if DROPBEAR_ED25519
-	if (keytype == DROPBEAR_SIGNKEY_ED25519) {
+	if (keytype == DROPBEAR_SIGNKEY_ED25519
+#if DROPBEAR_SK_ED25519
+		|| keytype == DROPBEAR_SIGNKEY_SK_ED25519
+#endif
+    ) {
 		ed25519_key_free(key->ed25519key);
 		key->ed25519key = m_malloc(sizeof(*key->ed25519key));
-		ret = buf_get_ed25519_pub_key(buf, key->ed25519key);
+		ret = buf_get_ed25519_pub_key(buf, key->ed25519key, keytype);
 		if (ret == DROPBEAR_FAILURE) {
 			m_free(key->ed25519key);
 			key->ed25519key = NULL;
@@ -287,6 +309,19 @@
 	}
 #endif
 
+#if DROPBEAR_SK_ECDSA || DROPBEAR_SK_ED25519
+	if (0
+#if DROPBEAR_SK_ED25519
+		|| keytype == DROPBEAR_SIGNKEY_SK_ED25519
+#endif
+#if DROPBEAR_SK_ECDSA
+		|| keytype == DROPBEAR_SIGNKEY_SK_ECDSA_NISTP256
+#endif
+	) {
+		key->sk_app = buf_getstring(buf, &key->sk_applen);
+	}
+#endif
+
 	TRACE2(("leave buf_get_pub_key"))
 
 	return ret;
@@ -401,7 +436,11 @@
 	}
 #endif
 #if DROPBEAR_ED25519
-	if (type == DROPBEAR_SIGNKEY_ED25519) {
+	if (type == DROPBEAR_SIGNKEY_ED25519
+#if DROPBEAR_SK_ED25519
+		|| type == DROPBEAR_SIGNKEY_SK_ED25519
+#endif
+	) {
 		buf_put_ed25519_pub_key(pubkeys, key->ed25519key);
 	}
 #endif
@@ -495,6 +534,11 @@
 #endif
 
 	m_free(key->filename);
+#if DROPBEAR_SK_ECDSA || DROPBEAR_SK_ED25519
+	if (key->sk_app) {
+		m_free(key->sk_app);
+	}
+#endif
 
 	m_free(key);
 	TRACE2(("leave sign_key_free"))
@@ -639,6 +683,7 @@
 }
 
 #if DROPBEAR_SIGNKEY_VERIFY
+
 /* Return DROPBEAR_SUCCESS or DROPBEAR_FAILURE.
  * If FAILURE is returned, the position of
  * buf is undefined. If SUCCESS is returned, buf will be positioned after the
@@ -695,6 +740,22 @@
 		return buf_ed25519_verify(buf, key->ed25519key, data_buf);
 	}
 #endif
+#if DROPBEAR_SK_ECDSA
+	if (keytype == DROPBEAR_SIGNKEY_SK_ECDSA_NISTP256) {
+		ecc_key **eck = (ecc_key**)signkey_key_ptr(key, keytype);
+		if (eck && *eck) {
+			return buf_sk_ecdsa_verify(buf, *eck, data_buf, key->sk_app, key->sk_applen);
+		}
+	}
+#endif
+#if DROPBEAR_SK_ED25519
+	if (keytype == DROPBEAR_SIGNKEY_SK_ED25519) {
+		dropbear_ed25519_key **eck = (dropbear_ed25519_key**)signkey_key_ptr(key, keytype);
+		if (eck && *eck) {
+			return buf_sk_ed25519_verify(buf, *eck, data_buf, key->sk_app, key->sk_applen);
+		}
+	}
+#endif
 
 	dropbear_exit("Non-matching signing type");
 	return DROPBEAR_FAILURE;