diff --git a/ed25519.c b/ed25519.c index 1ac3e3d..f200e13 100644 --- a/ed25519.c +++ b/ed25519.c @@ -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); diff --git a/ed25519.h b/ed25519.h index f415e66..1da9fbd 100644 --- a/ed25519.h +++ b/ed25519.h @@ -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); diff --git a/signkey.c b/signkey.c index 253154f..8749d85 100644 --- a/signkey.c +++ b/signkey.c @@ -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; diff --git a/signkey.h b/signkey.h index ee0ac11..cc7fd8b 100644 --- a/signkey.h +++ b/signkey.h @@ -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; diff --git a/svr-authpubkey.c b/svr-authpubkey.c index f325fe8..a33cc39 100644 --- a/svr-authpubkey.c +++ b/svr-authpubkey.c @@ -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();