Implement no-touch-required and verify-requred for authorized_keys file

This commit is contained in:
Egor Duda 2022-06-11 13:35:06 +03:00
parent 544f28a051
commit 62ea53c1e5
No known key found for this signature in database
GPG Key ID: 8610EBBBC18A37F1
9 changed files with 57 additions and 10 deletions

4
auth.h
View File

@ -139,6 +139,10 @@ struct PubKeyOptions {
int no_pty_flag;
/* "command=" option. */
char * forced_command;
#if DROPBEAR_SK_ECDSA || DROPBEAR_SK_ED25519
int no_touch_required_flag;
int verify_required_flag;
#endif
};
#endif

View File

@ -688,7 +688,7 @@ int buf_verify(buffer * buf, sign_key *key, enum signature_type expect_sigtype,
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);
return buf_sk_ecdsa_verify(buf, *eck, data_buf, key->sk_app, key->sk_applen, key->sk_flags_mask);
}
}
#endif
@ -696,7 +696,7 @@ int buf_verify(buffer * buf, sign_key *key, enum signature_type expect_sigtype,
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);
return buf_sk_ed25519_verify(buf, *eck, data_buf, key->sk_app, key->sk_applen, key->sk_flags_mask);
}
}
#endif

View File

@ -127,6 +127,7 @@ struct SIGN_key {
/* application ID for U2F/FIDO key types, a malloced string */
char * sk_app;
unsigned int sk_applen;
unsigned char sk_flags_mask;
#endif
};

View File

@ -8,7 +8,9 @@
#include "sk-ecdsa.h"
#include "ssh.h"
int buf_sk_ecdsa_verify(buffer *buf, const ecc_key *key, const buffer *data_buf, const char* app, unsigned int applen) {
int buf_sk_ecdsa_verify(buffer *buf, const ecc_key *key, const buffer *data_buf,
const char* app, unsigned int applen,
unsigned char sk_flags_mask) {
hash_state hs;
unsigned char subhash[SHA256_HASH_SIZE];
buffer *sk_buffer = NULL, *sig_buffer = NULL;
@ -41,13 +43,18 @@ int buf_sk_ecdsa_verify(buffer *buf, const ecc_key *key, const buffer *data_buf,
buf_free(sk_buffer);
buf_free(sig_buffer);
/* TODO: allow "no-touch-required" or "verify-required" authorized_keys options */
if (!(flags & SSH_SK_USER_PRESENCE_REQD)) {
if (~flags & sk_flags_mask & SSH_SK_USER_PRESENCE_REQD) {
if (ret == DROPBEAR_SUCCESS) {
dropbear_log(LOG_WARNING, "Rejecting, user-presence not set");
}
ret = DROPBEAR_FAILURE;
}
if (~flags & sk_flags_mask & SSH_SK_USER_VERIFICATION_REQD) {
if (ret == DROPBEAR_SUCCESS) {
dropbear_log(LOG_WARNING, "Rejecting, user-verification not set");
}
ret = DROPBEAR_FAILURE;
}
TRACE(("leave buf_sk_ecdsa_verify, ret=%d", ret))
return ret;

View File

@ -8,7 +8,9 @@
#include "buffer.h"
#include "signkey.h"
int buf_sk_ecdsa_verify(buffer *buf, const ecc_key *key, const buffer *data_buf, const char* app, unsigned int applen);
int buf_sk_ecdsa_verify(buffer *buf, const ecc_key *key, const buffer *data_buf,
const char* app, unsigned int applen,
unsigned char sk_flags_mask);
#endif

View File

@ -8,7 +8,9 @@
#include "ed25519.h"
#include "ssh.h"
int buf_sk_ed25519_verify(buffer *buf, const dropbear_ed25519_key *key, const buffer *data_buf, const char* app, unsigned int applen) {
int buf_sk_ed25519_verify(buffer *buf, const dropbear_ed25519_key *key, const buffer *data_buf,
const char* app, unsigned int applen,
unsigned char sk_flags_mask) {
int ret = DROPBEAR_FAILURE;
unsigned char *s;
@ -52,13 +54,18 @@ int buf_sk_ed25519_verify(buffer *buf, const dropbear_ed25519_key *key, const bu
ret = DROPBEAR_SUCCESS;
}
/* TODO: allow "no-touch-required" or "verify-required" authorized_keys options */
if (!(flags & SSH_SK_USER_PRESENCE_REQD)) {
if (~flags & sk_flags_mask & SSH_SK_USER_PRESENCE_REQD) {
if (ret == DROPBEAR_SUCCESS) {
dropbear_log(LOG_WARNING, "Rejecting, user-presence not set");
}
ret = DROPBEAR_FAILURE;
}
if (~flags & sk_flags_mask & SSH_SK_USER_VERIFICATION_REQD) {
if (ret == DROPBEAR_SUCCESS) {
dropbear_log(LOG_WARNING, "Rejecting, user-verification not set");
}
ret = DROPBEAR_FAILURE;
}
out:
buf_free(sk_buffer);
TRACE(("leave buf_sk_ed25519_verify: ret %d", ret))

View File

@ -8,7 +8,9 @@
#include "buffer.h"
#include "ed25519.h"
int buf_sk_ed25519_verify(buffer *buf, const dropbear_ed25519_key *key, const buffer *data_buf, const char* app, unsigned int applen);
int buf_sk_ed25519_verify(buffer *buf, const dropbear_ed25519_key *key, const buffer *data_buf,
const char* app, unsigned int applen,
unsigned char sk_flags_mask);
#endif

View File

@ -182,6 +182,16 @@ void svr_auth_pubkey(int valid_user) {
goto out;
}
#if DROPBEAR_SK_ECDSA || DROPBEAR_SK_ED25519
key->sk_flags_mask = SSH_SK_USER_PRESENCE_REQD;
if (ses.authstate.pubkey_options && ses.authstate.pubkey_options->no_touch_required_flag) {
key->sk_flags_mask &= ~SSH_SK_USER_PRESENCE_REQD;
}
if (ses.authstate.pubkey_options && ses.authstate.pubkey_options->verify_required_flag) {
key->sk_flags_mask |= SSH_SK_USER_VERIFICATION_REQD;
}
#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);

View File

@ -205,6 +205,20 @@ int svr_add_pubkey_options(buffer *options_buf, int line_num, const char* filena
dropbear_log(LOG_WARNING, "Badly formatted command= authorized_keys option");
goto bad_option;
}
if (match_option(options_buf, "no-touch-required") == DROPBEAR_SUCCESS) {
#if DROPBEAR_SK_ECDSA || DROPBEAR_SK_ED25519
dropbear_log(LOG_WARNING, "No user presence check required for U2F/FIDO key.");
ses.authstate.pubkey_options->no_touch_required_flag = 1;
#endif
goto next_option;
}
if (match_option(options_buf, "verify-required") == DROPBEAR_SUCCESS) {
#if DROPBEAR_SK_ECDSA || DROPBEAR_SK_ED25519
dropbear_log(LOG_WARNING, "User verification required for U2F/FIDO key.");
ses.authstate.pubkey_options->verify_required_flag = 1;
#endif
goto next_option;
}
next_option:
/*