summaryrefslogtreecommitdiff
path: root/signkey.c
diff options
context:
space:
mode:
authorMatt Johnston <matt@ucc.asn.au>2020-05-26 00:24:02 +0800
committerMatt Johnston <matt@ucc.asn.au>2020-05-26 00:24:02 +0800
commitffa4f43fd6a3dfe36457263132d7a109b644aeb4 (patch)
treedad89ed65eaa7aa5605a54188ac14ca27092d609 /signkey.c
parent98c8392454154d33c08144e91432b690c939021d (diff)
parent5a2225370446cc90746c98acf71a9ad888ce7a5c (diff)
downloaddropbear-ffa4f43fd6a3dfe36457263132d7a109b644aeb4.tar.gz
merge rsa-sha256
Diffstat (limited to 'signkey.c')
-rw-r--r--signkey.c118
1 files changed, 100 insertions, 18 deletions
diff --git a/signkey.c b/signkey.c
index a0af44a..49801f3 100644
--- a/signkey.c
+++ b/signkey.c
@@ -28,6 +28,9 @@
#include "buffer.h"
#include "ssh.h"
#include "ecdsa.h"
+#include "rsa.h"
+#include "dss.h"
+#include "ed25519.h"
static const char * const signkey_names[DROPBEAR_SIGNKEY_NUM_NAMED] = {
#if DROPBEAR_RSA
@@ -44,6 +47,7 @@ static const char * const signkey_names[DROPBEAR_SIGNKEY_NUM_NAMED] = {
#if DROPBEAR_ED25519
"ssh-ed25519",
#endif /* DROPBEAR_ED25519 */
+ /* "rsa-sha2-256" is special-cased below since it is only a signature name, not key type */
};
/* malloc a new sign_key and set the dss and rsa keys to NULL */
@@ -105,6 +109,70 @@ enum signkey_type signkey_type_from_name(const char* name, unsigned int namelen)
return DROPBEAR_SIGNKEY_NONE;
}
+/* 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 signature_type type, unsigned int *namelen) {
+#if DROPBEAR_RSA_SHA256
+ if (type == DROPBEAR_SIGNATURE_RSA_SHA256) {
+ if (namelen) {
+ *namelen = strlen(SSH_SIGNATURE_RSA_SHA256);
+ }
+ return SSH_SIGNATURE_RSA_SHA256;
+ }
+#endif
+#if DROPBEAR_RSA_SHA1
+ if (type == DROPBEAR_SIGNATURE_RSA_SHA1) {
+ if (namelen) {
+ *namelen = strlen(SSH_SIGNKEY_RSA);
+ }
+ return SSH_SIGNKEY_RSA;
+ }
+#endif
+ return signkey_name_from_type((enum signkey_type)type, 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_SIGNATURE_RSA_SHA256)
+ && memcmp(name, SSH_SIGNATURE_RSA_SHA256, namelen) == 0) {
+ return DROPBEAR_SIGNATURE_RSA_SHA256;
+ }
+#endif
+#if DROPBEAR_RSA_SHA1
+ 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);
+}
+
+/* Returns the signature type from a key type. Must not be called
+ with RSA keytype */
+enum signature_type signature_type_from_signkey(enum signkey_type keytype) {
+#if DROPBEAR_RSA
+ assert(keytype != DROPBEAR_SIGNKEY_RSA);
+#endif
+ assert(keytype < DROPBEAR_SIGNKEY_NUM_NAMED);
+ return (enum signature_type)keytype;
+}
+
+enum signkey_type signkey_type_from_signature(enum signature_type sigtype) {
+#if DROPBEAR_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 (enum signkey_type)sigtype;
+}
+
/* Returns a pointer to the key part specific to "type".
Be sure to check both (ret != NULL) and (*ret != NULL) */
void **
@@ -526,31 +594,39 @@ char * sign_key_fingerprint(const unsigned char* keyblob, unsigned int keybloble
#endif
}
-void buf_put_sign(buffer* buf, sign_key *key, enum signkey_type type,
+void buf_put_sign(buffer* buf, sign_key *key, enum signature_type sigtype,
const buffer *data_buf) {
- buffer *sigblob;
- sigblob = buf_new(MAX_PUBKEY_SIZE);
+ buffer *sigblob = buf_new(MAX_PUBKEY_SIZE);
+ enum signkey_type keytype = signkey_type_from_signature(sigtype);
+
+#if DEBUG_TRACE
+ {
+ const char* signame = signature_name_from_type(sigtype, NULL);
+ TRACE(("buf_put_sign type %d %s", sigtype, signame));
+ }
+#endif
+
#if DROPBEAR_DSS
- if (type == DROPBEAR_SIGNKEY_DSS) {
+ if (keytype == DROPBEAR_SIGNKEY_DSS) {
buf_put_dss_sign(sigblob, key->dsskey, data_buf);
}
#endif
#if DROPBEAR_RSA
- if (type == DROPBEAR_SIGNKEY_RSA) {
- buf_put_rsa_sign(sigblob, key->rsakey, data_buf);
+ if (keytype == DROPBEAR_SIGNKEY_RSA) {
+ buf_put_rsa_sign(sigblob, key->rsakey, sigtype, data_buf);
}
#endif
#if DROPBEAR_ECDSA
- if (signkey_is_ecdsa(type)) {
- ecc_key **eck = (ecc_key**)signkey_key_ptr(key, type);
+ if (signkey_is_ecdsa(keytype)) {
+ ecc_key **eck = (ecc_key**)signkey_key_ptr(key, keytype);
if (eck && *eck) {
buf_put_ecdsa_sign(sigblob, *eck, data_buf);
}
}
#endif
#if DROPBEAR_ED25519
- if (type == DROPBEAR_SIGNKEY_ED25519) {
+ if (keytype == DROPBEAR_SIGNKEY_ED25519) {
buf_put_ed25519_sign(sigblob, key->ed25519key, data_buf);
}
#endif
@@ -567,21 +643,27 @@ void buf_put_sign(buffer* buf, sign_key *key, enum signkey_type type,
* 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, 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 type;
+ enum signature_type sigtype;
+ enum signkey_type keytype;
TRACE(("enter buf_verify"))
buf_getint(buf); /* blob length */
type_name = buf_getstring(buf, &type_name_len);
- type = signkey_type_from_name(type_name, type_name_len);
+ sigtype = signature_type_from_name(type_name, type_name_len);
m_free(type_name);
+ if (expect_sigtype != sigtype) {
+ dropbear_exit("Non-matching signing type");
+ }
+
+ keytype = signkey_type_from_signature(sigtype);
#if DROPBEAR_DSS
- if (type == DROPBEAR_SIGNKEY_DSS) {
+ if (keytype == DROPBEAR_SIGNKEY_DSS) {
if (key->dsskey == NULL) {
dropbear_exit("No DSS key to verify signature");
}
@@ -590,23 +672,23 @@ int buf_verify(buffer * buf, sign_key *key, const buffer *data_buf) {
#endif
#if DROPBEAR_RSA
- if (type == DROPBEAR_SIGNKEY_RSA) {
+ if (keytype == DROPBEAR_SIGNKEY_RSA) {
if (key->rsakey == NULL) {
dropbear_exit("No RSA key to verify signature");
}
- return buf_rsa_verify(buf, key->rsakey, data_buf);
+ return buf_rsa_verify(buf, key->rsakey, sigtype, data_buf);
}
#endif
#if DROPBEAR_ECDSA
- if (signkey_is_ecdsa(type)) {
- ecc_key **eck = (ecc_key**)signkey_key_ptr(key, type);
+ if (signkey_is_ecdsa(keytype)) {
+ ecc_key **eck = (ecc_key**)signkey_key_ptr(key, keytype);
if (eck && *eck) {
return buf_ecdsa_verify(buf, *eck, data_buf);
}
}
#endif
#if DROPBEAR_ED25519
- if (type == DROPBEAR_SIGNKEY_ED25519) {
+ if (keytype == DROPBEAR_SIGNKEY_ED25519) {
if (key->ed25519key == NULL) {
dropbear_exit("No Ed25519 key to verify signature");
}