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
This commit is contained in:
Matt Johnston 2022-01-22 15:45:07 +08:00
parent cc481a646d
commit cafebe2d30
5 changed files with 58 additions and 96 deletions

View File

@ -38,17 +38,24 @@
* The key will have the same format as buf_put_ed25519_key.
* These should be freed with ed25519_key_free.
* Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */
int buf_get_ed25519_pub_key(buffer *buf, dropbear_ed25519_key *key, int sk) {
int buf_get_ed25519_pub_key(buffer *buf, dropbear_ed25519_key *key,
enum signkey_type expect_keytype) {
unsigned int len;
unsigned int len, typelen;
char *keytype = NULL;
enum signkey_type buf_keytype;
TRACE(("enter buf_get_ed25519_pub_key"))
dropbear_assert(key != NULL);
if (sk) {
buf_incrpos(buf, 30); /* int + "sk-ssh-ed25519@openssh.com" */
} else {
buf_incrpos(buf, 4+SSH_SIGNKEY_ED25519_LEN); /* int + "ssh-ed25519" */
/* consume and check the key string */
keytype = buf_getstring(buf, &typelen);
buf_keytype = signkey_type_from_name(keytype, typelen);
m_free(keytype);
if (buf_keytype != expect_keytype) {
TRACE(("leave buf_get_ed25519_pub_key: mismatch key type"))
return DROPBEAR_FAILURE;
}
len = buf_getint(buf);

View File

@ -27,6 +27,7 @@
#include "includes.h"
#include "buffer.h"
#include "signkey.h"
#if DROPBEAR_ED25519
@ -43,7 +44,8 @@ void buf_put_ed25519_sign(buffer* buf, const dropbear_ed25519_key *key, const bu
#if DROPBEAR_SIGNKEY_VERIFY
int buf_ed25519_verify(buffer * buf, const dropbear_ed25519_key *key, const buffer *data_buf);
#endif
int buf_get_ed25519_pub_key(buffer* buf, dropbear_ed25519_key *key, int sk);
int buf_get_ed25519_pub_key(buffer *buf, dropbear_ed25519_key *key,
enum signkey_type expect_keytype);
int buf_get_ed25519_priv_key(buffer* buf, dropbear_ed25519_key *key);
void buf_put_ed25519_pub_key(buffer* buf, const dropbear_ed25519_key *key);
void buf_put_ed25519_priv_key(buffer* buf, const dropbear_ed25519_key *key);

View File

@ -232,7 +232,6 @@ int buf_get_pub_key(buffer *buf, sign_key *key, enum signkey_type *type) {
unsigned int len;
enum signkey_type keytype;
int ret = DROPBEAR_FAILURE;
int is_sk = 0;
TRACE2(("enter buf_get_pub_key"))
@ -300,14 +299,9 @@ int buf_get_pub_key(buffer *buf, sign_key *key, enum signkey_type *type) {
|| keytype == DROPBEAR_SIGNKEY_SK_ED25519
#endif
) {
#if DROPBEAR_SK_ED25519
if (keytype == DROPBEAR_SIGNKEY_SK_ED25519) {
is_sk = 1;
}
#endif
ed25519_key_free(key->ed25519key);
key->ed25519key = m_malloc(sizeof(*key->ed25519key));
ret = buf_get_ed25519_pub_key(buf, key->ed25519key, is_sk);
ret = buf_get_ed25519_pub_key(buf, key->ed25519key, keytype);
if (ret == DROPBEAR_FAILURE) {
m_free(key->ed25519key);
key->ed25519key = NULL;
@ -315,6 +309,19 @@ int buf_get_pub_key(buffer *buf, sign_key *key, enum signkey_type *type) {
}
#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;
@ -527,6 +534,7 @@ void sign_key_free(sign_key *key) {
#endif
m_free(key->filename);
m_free(key->sk_app);
m_free(key);
TRACE2(("leave sign_key_free"))
@ -672,50 +680,6 @@ void buf_put_sign(buffer* buf, sign_key *key, enum signature_type sigtype,
#if DROPBEAR_SIGNKEY_VERIFY
#if DROPBEAR_SK_ECDSA || DROPBEAR_SK_ED25519
int sk_buf_verify(buffer * buf, sign_key *key, enum signature_type expect_sigtype, const buffer *data_buf, char* app, unsigned int applen) {
char *type_name = NULL;
unsigned int type_name_len = 0;
enum signature_type sigtype;
enum signkey_type keytype;
TRACE(("enter sk_buf_verify"))
buf_getint(buf); /* blob length */
type_name = buf_getstring(buf, &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_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, app, 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, app, applen);
}
}
#endif
dropbear_exit("Non-matching signing type");
return DROPBEAR_FAILURE;
}
#endif
/* 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
@ -729,6 +693,9 @@ int buf_verify(buffer * buf, sign_key *key, enum signature_type expect_sigtype,
TRACE(("enter buf_verify"))
printhex("buf", buf->data, buf->pos);
printhex("remw", &buf->data[buf->pos], buf->len-buf->pos);
buf_getint(buf); /* blob length */
type_name = buf_getstring(buf, &type_name_len);
sigtype = signature_type_from_name(type_name, type_name_len);
@ -772,6 +739,22 @@ int buf_verify(buffer * buf, sign_key *key, enum signature_type expect_sigtype,
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;

View File

@ -122,6 +122,12 @@ struct SIGN_key {
#if DROPBEAR_ED25519
struct dropbear_ED25519_Key * ed25519key;
#endif
#if DROPBEAR_SK_ECDSA || DROPBEAR_SK_ED25519
/* application ID for U2F/FIDO key types, a malloced string */
char * sk_app;
unsigned int sk_applen;
#endif
};
typedef struct SIGN_key sign_key;

View File

@ -95,12 +95,6 @@ void svr_auth_pubkey(int valid_user) {
enum signature_type sigtype;
enum signkey_type keytype;
int auth_failure = 1;
int verify_ret = DROPBEAR_FAILURE;
#if DROPBEAR_SK_ECDSA || DROPBEAR_SK_ED25519
char* app = NULL;
unsigned int applen;
int is_sk = 0;
#endif
TRACE(("enter pubkeyauth"))
@ -188,27 +182,11 @@ void svr_auth_pubkey(int valid_user) {
goto out;
}
#if DROPBEAR_SK_ECDSA || DROPBEAR_SK_ED25519
#if DROPBEAR_SK_ECDSA
if (keytype == DROPBEAR_SIGNKEY_SK_ECDSA_NISTP256) {
is_sk = 1;
}
#endif
#if DROPBEAR_SK_ED25519
if (keytype == DROPBEAR_SIGNKEY_SK_ED25519) {
is_sk = 1;
}
#endif
if (is_sk) {
app = buf_getstring (ses.payload, &applen);
}
#endif
/* create the data which has been signed - this a string containing
* session_id, concatenated with the payload packet up to the signature */
assert(ses.payload_beginning <= ses.payload->pos);
sign_payload_length = ses.payload->pos - ses.payload_beginning;
signbuf = buf_new(ses.payload->pos + 12 + ses.session_id->len);
signbuf = buf_new(ses.payload->pos + 4 + ses.session_id->len);
buf_putbufstring(signbuf, ses.session_id);
/* The entire contents of the payload prior. */
@ -222,16 +200,7 @@ void svr_auth_pubkey(int valid_user) {
/* ... and finally verify the signature */
fp = sign_key_fingerprint(keyblob, keybloblen);
#if DROPBEAR_SK_ECDSA || DROPBEAR_SK_ED25519
if (is_sk) {
verify_ret = sk_buf_verify(ses.payload, key, sigtype, signbuf, app, applen);
} else {
verify_ret = buf_verify(ses.payload, key, sigtype, signbuf);
}
#else
verify_ret = buf_verify(ses.payload, key, sigtype, signbuf);
#endif
if (verify_ret == DROPBEAR_SUCCESS) {
if (buf_verify(ses.payload, key, sigtype, signbuf) == DROPBEAR_SUCCESS) {
dropbear_log(LOG_NOTICE,
"Pubkey auth succeeded for '%s' with key %s from %s",
ses.authstate.pw_name, fp, svr_ses.addrstring);
@ -263,11 +232,6 @@ out:
sign_key_free(key);
key = NULL;
}
#if DROPBEAR_SK_ECDSA || DROPBEAR_SK_ED25519
if (app) {
m_free(app);
}
#endif
/* Retain pubkey options only if auth succeeded */
if (!ses.authstate.authdone) {
svr_pubkey_options_cleanup();