summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordjm@openbsd.org <djm@openbsd.org>2020-08-27 01:07:09 +0000
committerDamien Miller <djm@mindrot.org>2020-08-27 11:28:36 +1000
commit801c9f095e6d8b7b91aefd98f5001c652ea13488 (patch)
tree6c6416d6d926939b208eb1f1181f196a554e0734
parent9b8ad93824c682ce841f53f3b5762cef4e7cc4dc (diff)
upstream: support for requiring user verified FIDO keys in sshd
This adds a "verify-required" authorized_keys flag and a corresponding sshd_config option that tells sshd to require that FIDO keys verify the user identity before completing the signing/authentication attempt. Whether or not user verification was performed is already baked into the signature made on the FIDO token, so this is just plumbing that flag through and adding ways to require it. feedback and ok markus@ OpenBSD-Commit-ID: 3a2313aae153e043d57763d766bb6d55c4e276e6
-rw-r--r--auth-options.c20
-rw-r--r--auth-options.h4
-rw-r--r--auth.c9
-rw-r--r--auth2-pubkey.c18
-rw-r--r--monitor.c17
-rw-r--r--servconf.c6
-rw-r--r--servconf.h5
-rw-r--r--sshd.811
-rw-r--r--sshd_config.523
9 files changed, 88 insertions, 25 deletions
diff --git a/auth-options.c b/auth-options.c
index 696ba6ac6..98afdf5fe 100644
--- a/auth-options.c
+++ b/auth-options.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: auth-options.c,v 1.92 2020/03/06 18:15:38 markus Exp $ */ 1/* $OpenBSD: auth-options.c,v 1.93 2020/08/27 01:07:09 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2018 Damien Miller <djm@mindrot.org> 3 * Copyright (c) 2018 Damien Miller <djm@mindrot.org>
4 * 4 *
@@ -119,7 +119,10 @@ cert_option_list(struct sshauthopt *opts, struct sshbuf *oblob,
119 } 119 }
120 } 120 }
121 if (!found && (which & OPTIONS_CRITICAL) != 0) { 121 if (!found && (which & OPTIONS_CRITICAL) != 0) {
122 if (strcmp(name, "force-command") == 0) { 122 if (strcmp(name, "verify-required") == 0) {
123 opts->require_verify = 1;
124 found = 1;
125 } else if (strcmp(name, "force-command") == 0) {
123 if ((r = sshbuf_get_cstring(data, &command, 126 if ((r = sshbuf_get_cstring(data, &command,
124 NULL)) != 0) { 127 NULL)) != 0) {
125 error("Unable to parse \"%s\" " 128 error("Unable to parse \"%s\" "
@@ -134,8 +137,7 @@ cert_option_list(struct sshauthopt *opts, struct sshbuf *oblob,
134 } 137 }
135 opts->force_command = command; 138 opts->force_command = command;
136 found = 1; 139 found = 1;
137 } 140 } else if (strcmp(name, "source-address") == 0) {
138 if (strcmp(name, "source-address") == 0) {
139 if ((r = sshbuf_get_cstring(data, &allowed, 141 if ((r = sshbuf_get_cstring(data, &allowed,
140 NULL)) != 0) { 142 NULL)) != 0) {
141 error("Unable to parse \"%s\" " 143 error("Unable to parse \"%s\" "
@@ -351,6 +353,8 @@ sshauthopt_parse(const char *opts, const char **errstrp)
351 ret->permit_x11_forwarding_flag = r == 1; 353 ret->permit_x11_forwarding_flag = r == 1;
352 } else if ((r = opt_flag("touch-required", 1, &opts)) != -1) { 354 } else if ((r = opt_flag("touch-required", 1, &opts)) != -1) {
353 ret->no_require_user_presence = r != 1; /* NB. flip */ 355 ret->no_require_user_presence = r != 1; /* NB. flip */
356 } else if ((r = opt_flag("verify-required", 1, &opts)) != -1) {
357 ret->require_verify = r == 1;
354 } else if ((r = opt_flag("pty", 1, &opts)) != -1) { 358 } else if ((r = opt_flag("pty", 1, &opts)) != -1) {
355 ret->permit_pty_flag = r == 1; 359 ret->permit_pty_flag = r == 1;
356 } else if ((r = opt_flag("user-rc", 1, &opts)) != -1) { 360 } else if ((r = opt_flag("user-rc", 1, &opts)) != -1) {
@@ -572,6 +576,7 @@ sshauthopt_merge(const struct sshauthopt *primary,
572 } 576 }
573 577
574#define OPTFLAG_AND(x) ret->x = (primary->x == 1) && (additional->x == 1) 578#define OPTFLAG_AND(x) ret->x = (primary->x == 1) && (additional->x == 1)
579#define OPTFLAG_OR(x) ret->x = (primary->x == 1) || (additional->x == 1)
575 /* Permissive flags are logical-AND (i.e. must be set in both) */ 580 /* Permissive flags are logical-AND (i.e. must be set in both) */
576 OPTFLAG_AND(permit_port_forwarding_flag); 581 OPTFLAG_AND(permit_port_forwarding_flag);
577 OPTFLAG_AND(permit_agent_forwarding_flag); 582 OPTFLAG_AND(permit_agent_forwarding_flag);
@@ -579,6 +584,8 @@ sshauthopt_merge(const struct sshauthopt *primary,
579 OPTFLAG_AND(permit_pty_flag); 584 OPTFLAG_AND(permit_pty_flag);
580 OPTFLAG_AND(permit_user_rc); 585 OPTFLAG_AND(permit_user_rc);
581 OPTFLAG_AND(no_require_user_presence); 586 OPTFLAG_AND(no_require_user_presence);
587 /* Restrictive flags are logical-OR (i.e. must be set in either) */
588 OPTFLAG_OR(require_verify);
582#undef OPTFLAG_AND 589#undef OPTFLAG_AND
583 590
584 /* Earliest expiry time should win */ 591 /* Earliest expiry time should win */
@@ -649,6 +656,7 @@ sshauthopt_copy(const struct sshauthopt *orig)
649 OPTSCALAR(force_tun_device); 656 OPTSCALAR(force_tun_device);
650 OPTSCALAR(valid_before); 657 OPTSCALAR(valid_before);
651 OPTSCALAR(no_require_user_presence); 658 OPTSCALAR(no_require_user_presence);
659 OPTSCALAR(require_verify);
652#undef OPTSCALAR 660#undef OPTSCALAR
653#define OPTSTRING(x) \ 661#define OPTSTRING(x) \
654 do { \ 662 do { \
@@ -781,7 +789,8 @@ sshauthopt_serialise(const struct sshauthopt *opts, struct sshbuf *m,
781 (r = sshbuf_put_u8(m, opts->permit_user_rc)) != 0 || 789 (r = sshbuf_put_u8(m, opts->permit_user_rc)) != 0 ||
782 (r = sshbuf_put_u8(m, opts->restricted)) != 0 || 790 (r = sshbuf_put_u8(m, opts->restricted)) != 0 ||
783 (r = sshbuf_put_u8(m, opts->cert_authority)) != 0 || 791 (r = sshbuf_put_u8(m, opts->cert_authority)) != 0 ||
784 (r = sshbuf_put_u8(m, opts->no_require_user_presence)) != 0) 792 (r = sshbuf_put_u8(m, opts->no_require_user_presence)) != 0 ||
793 (r = sshbuf_put_u8(m, opts->require_verify)) != 0)
785 return r; 794 return r;
786 795
787 /* Simple integer options */ 796 /* Simple integer options */
@@ -844,6 +853,7 @@ sshauthopt_deserialise(struct sshbuf *m, struct sshauthopt **optsp)
844 OPT_FLAG(restricted); 853 OPT_FLAG(restricted);
845 OPT_FLAG(cert_authority); 854 OPT_FLAG(cert_authority);
846 OPT_FLAG(no_require_user_presence); 855 OPT_FLAG(no_require_user_presence);
856 OPT_FLAG(require_verify);
847#undef OPT_FLAG 857#undef OPT_FLAG
848 858
849 /* Simple integer options */ 859 /* Simple integer options */
diff --git a/auth-options.h b/auth-options.h
index d96ffedee..118a32087 100644
--- a/auth-options.h
+++ b/auth-options.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: auth-options.h,v 1.29 2019/11/25 00:54:23 djm Exp $ */ 1/* $OpenBSD: auth-options.h,v 1.30 2020/08/27 01:07:09 djm Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2018 Damien Miller <djm@mindrot.org> 4 * Copyright (c) 2018 Damien Miller <djm@mindrot.org>
@@ -71,6 +71,8 @@ struct sshauthopt {
71 71
72 /* Key requires user presence asserted */ 72 /* Key requires user presence asserted */
73 int no_require_user_presence; 73 int no_require_user_presence;
74 /* Key requires user verification (e.g. PIN) */
75 int require_verify;
74}; 76};
75 77
76struct sshauthopt *sshauthopt_new(void); 78struct sshauthopt *sshauthopt_new(void);
diff --git a/auth.c b/auth.c
index 086b8ebb1..9a5498b66 100644
--- a/auth.c
+++ b/auth.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: auth.c,v 1.146 2020/01/31 22:42:45 djm Exp $ */ 1/* $OpenBSD: auth.c,v 1.147 2020/08/27 01:07:09 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2000 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000 Markus Friedl. All rights reserved.
4 * 4 *
@@ -1006,21 +1006,22 @@ auth_log_authopts(const char *loc, const struct sshauthopt *opts, int do_remote)
1006 1006
1007 snprintf(buf, sizeof(buf), "%d", opts->force_tun_device); 1007 snprintf(buf, sizeof(buf), "%d", opts->force_tun_device);
1008 /* Try to keep this alphabetically sorted */ 1008 /* Try to keep this alphabetically sorted */
1009 snprintf(msg, sizeof(msg), "key options:%s%s%s%s%s%s%s%s%s%s%s%s%s%s", 1009 snprintf(msg, sizeof(msg), "key options:%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
1010 opts->permit_agent_forwarding_flag ? " agent-forwarding" : "", 1010 opts->permit_agent_forwarding_flag ? " agent-forwarding" : "",
1011 opts->force_command == NULL ? "" : " command", 1011 opts->force_command == NULL ? "" : " command",
1012 do_env ? " environment" : "", 1012 do_env ? " environment" : "",
1013 opts->valid_before == 0 ? "" : "expires", 1013 opts->valid_before == 0 ? "" : "expires",
1014 opts->no_require_user_presence ? " no-touch-required" : "",
1014 do_permitopen ? " permitopen" : "", 1015 do_permitopen ? " permitopen" : "",
1015 do_permitlisten ? " permitlisten" : "", 1016 do_permitlisten ? " permitlisten" : "",
1016 opts->permit_port_forwarding_flag ? " port-forwarding" : "", 1017 opts->permit_port_forwarding_flag ? " port-forwarding" : "",
1017 opts->cert_principals == NULL ? "" : " principals", 1018 opts->cert_principals == NULL ? "" : " principals",
1018 opts->permit_pty_flag ? " pty" : "", 1019 opts->permit_pty_flag ? " pty" : "",
1020 opts->require_verify ? " uv" : "",
1019 opts->force_tun_device == -1 ? "" : " tun=", 1021 opts->force_tun_device == -1 ? "" : " tun=",
1020 opts->force_tun_device == -1 ? "" : buf, 1022 opts->force_tun_device == -1 ? "" : buf,
1021 opts->permit_user_rc ? " user-rc" : "", 1023 opts->permit_user_rc ? " user-rc" : "",
1022 opts->permit_x11_forwarding_flag ? " x11-forwarding" : "", 1024 opts->permit_x11_forwarding_flag ? " x11-forwarding" : "");
1023 opts->no_require_user_presence ? " no-touch-required" : "");
1024 1025
1025 debug("%s: %s", loc, msg); 1026 debug("%s: %s", loc, msg);
1026 if (do_remote) 1027 if (do_remote)
diff --git a/auth2-pubkey.c b/auth2-pubkey.c
index 815ea0f25..c3ecd9afc 100644
--- a/auth2-pubkey.c
+++ b/auth2-pubkey.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: auth2-pubkey.c,v 1.99 2020/02/06 22:30:54 naddy Exp $ */ 1/* $OpenBSD: auth2-pubkey.c,v 1.100 2020/08/27 01:07:09 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2000 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000 Markus Friedl. All rights reserved.
4 * 4 *
@@ -97,7 +97,7 @@ userauth_pubkey(struct ssh *ssh)
97 u_char *pkblob = NULL, *sig = NULL, have_sig; 97 u_char *pkblob = NULL, *sig = NULL, have_sig;
98 size_t blen, slen; 98 size_t blen, slen;
99 int r, pktype; 99 int r, pktype;
100 int req_presence = 0, authenticated = 0; 100 int req_presence = 0, req_verify = 0, authenticated = 0;
101 struct sshauthopt *authopts = NULL; 101 struct sshauthopt *authopts = NULL;
102 struct sshkey_sig_details *sig_details = NULL; 102 struct sshkey_sig_details *sig_details = NULL;
103 103
@@ -239,6 +239,20 @@ userauth_pubkey(struct ssh *ssh)
239 authenticated = 0; 239 authenticated = 0;
240 goto done; 240 goto done;
241 } 241 }
242 req_verify = (options.pubkey_auth_options &
243 PUBKEYAUTH_VERIFY_REQUIRED) ||
244 authopts->require_verify;
245 if (req_verify && (sig_details->sk_flags &
246 SSH_SK_USER_VERIFICATION_REQD) == 0) {
247 error("public key %s signature for %s%s from "
248 "%.128s port %d rejected: user "
249 "verification requirement not met ", key_s,
250 authctxt->valid ? "" : "invalid user ",
251 authctxt->user, ssh_remote_ipaddr(ssh),
252 ssh_remote_port(ssh));
253 authenticated = 0;
254 goto done;
255 }
242 } 256 }
243 auth2_record_key(authctxt, authenticated, key); 257 auth2_record_key(authctxt, authenticated, key);
244 } else { 258 } else {
diff --git a/monitor.c b/monitor.c
index 7c3e6aafe..4cf79dfc9 100644
--- a/monitor.c
+++ b/monitor.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: monitor.c,v 1.213 2020/08/27 01:06:18 djm Exp $ */ 1/* $OpenBSD: monitor.c,v 1.214 2020/08/27 01:07:09 djm Exp $ */
2/* 2/*
3 * Copyright 2002 Niels Provos <provos@citi.umich.edu> 3 * Copyright 2002 Niels Provos <provos@citi.umich.edu>
4 * Copyright 2002 Markus Friedl <markus@openbsd.org> 4 * Copyright 2002 Markus Friedl <markus@openbsd.org>
@@ -1387,7 +1387,8 @@ mm_answer_keyverify(struct ssh *ssh, int sock, struct sshbuf *m)
1387 const u_char *signature, *data, *blob; 1387 const u_char *signature, *data, *blob;
1388 char *sigalg = NULL, *fp = NULL; 1388 char *sigalg = NULL, *fp = NULL;
1389 size_t signaturelen, datalen, bloblen; 1389 size_t signaturelen, datalen, bloblen;
1390 int r, ret, req_presence = 0, valid_data = 0, encoded_ret; 1390 int r, ret, req_presence = 0, req_verify = 0, valid_data = 0;
1391 int encoded_ret;
1391 struct sshkey_sig_details *sig_details = NULL; 1392 struct sshkey_sig_details *sig_details = NULL;
1392 1393
1393 if ((r = sshbuf_get_string_direct(m, &blob, &bloblen)) != 0 || 1394 if ((r = sshbuf_get_string_direct(m, &blob, &bloblen)) != 0 ||
@@ -1452,6 +1453,18 @@ mm_answer_keyverify(struct ssh *ssh, int sock, struct sshbuf *m)
1452 ssh_remote_port(ssh)); 1453 ssh_remote_port(ssh));
1453 ret = SSH_ERR_SIGNATURE_INVALID; 1454 ret = SSH_ERR_SIGNATURE_INVALID;
1454 } 1455 }
1456 req_verify = (options.pubkey_auth_options &
1457 PUBKEYAUTH_VERIFY_REQUIRED) || key_opts->require_verify;
1458 if (req_verify &&
1459 (sig_details->sk_flags & SSH_SK_USER_VERIFICATION_REQD) == 0) {
1460 error("public key %s %s signature for %s%s from %.128s "
1461 "port %d rejected: user verification requirement "
1462 "not met ", sshkey_type(key), fp,
1463 authctxt->valid ? "" : "invalid user ",
1464 authctxt->user, ssh_remote_ipaddr(ssh),
1465 ssh_remote_port(ssh));
1466 ret = SSH_ERR_SIGNATURE_INVALID;
1467 }
1455 } 1468 }
1456 auth2_record_key(authctxt, ret == 0, key); 1469 auth2_record_key(authctxt, ret == 0, key);
1457 1470
diff --git a/servconf.c b/servconf.c
index 67581ccf2..1bc7ee31a 100644
--- a/servconf.c
+++ b/servconf.c
@@ -1,5 +1,5 @@
1 1
2/* $OpenBSD: servconf.c,v 1.367 2020/07/05 23:59:45 djm Exp $ */ 2/* $OpenBSD: servconf.c,v 1.368 2020/08/27 01:07:09 djm Exp $ */
3/* 3/*
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
5 * All rights reserved 5 * All rights reserved
@@ -1527,6 +1527,8 @@ process_server_config_line_depth(ServerOptions *options, char *line,
1527 continue; 1527 continue;
1528 if (strcasecmp(arg, "touch-required") == 0) 1528 if (strcasecmp(arg, "touch-required") == 0)
1529 value |= PUBKEYAUTH_TOUCH_REQUIRED; 1529 value |= PUBKEYAUTH_TOUCH_REQUIRED;
1530 else if (strcasecmp(arg, "verify-required") == 0)
1531 value |= PUBKEYAUTH_VERIFY_REQUIRED;
1530 else { 1532 else {
1531 fatal("%s line %d: unsupported " 1533 fatal("%s line %d: unsupported "
1532 "PubkeyAuthOptions option %s", 1534 "PubkeyAuthOptions option %s",
@@ -2937,5 +2939,7 @@ dump_config(ServerOptions *o)
2937 printf(" none"); 2939 printf(" none");
2938 if (o->pubkey_auth_options & PUBKEYAUTH_TOUCH_REQUIRED) 2940 if (o->pubkey_auth_options & PUBKEYAUTH_TOUCH_REQUIRED)
2939 printf(" touch-required"); 2941 printf(" touch-required");
2942 if (o->pubkey_auth_options & PUBKEYAUTH_VERIFY_REQUIRED)
2943 printf(" verify-required");
2940 printf("\n"); 2944 printf("\n");
2941} 2945}
diff --git a/servconf.h b/servconf.h
index 8422f3f51..1df8f3db8 100644
--- a/servconf.h
+++ b/servconf.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: servconf.h,v 1.145 2020/07/05 23:59:45 djm Exp $ */ 1/* $OpenBSD: servconf.h,v 1.146 2020/08/27 01:07:10 djm Exp $ */
2 2
3/* 3/*
4 * Author: Tatu Ylonen <ylo@cs.hut.fi> 4 * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -50,7 +50,8 @@
50#define INTERNAL_SFTP_NAME "internal-sftp" 50#define INTERNAL_SFTP_NAME "internal-sftp"
51 51
52/* PubkeyAuthOptions flags */ 52/* PubkeyAuthOptions flags */
53#define PUBKEYAUTH_TOUCH_REQUIRED 1 53#define PUBKEYAUTH_TOUCH_REQUIRED (1)
54#define PUBKEYAUTH_VERIFY_REQUIRED (1<<1)
54 55
55struct ssh; 56struct ssh;
56struct fwd_perm_list; 57struct fwd_perm_list;
diff --git a/sshd.8 b/sshd.8
index c5f8987d2..b2fad56d3 100644
--- a/sshd.8
+++ b/sshd.8
@@ -33,8 +33,8 @@
33.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 33.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
34.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35.\" 35.\"
36.\" $OpenBSD: sshd.8,v 1.312 2020/01/25 06:03:10 djm Exp $ 36.\" $OpenBSD: sshd.8,v 1.313 2020/08/27 01:07:10 djm Exp $
37.Dd $Mdocdate: January 25 2020 $ 37.Dd $Mdocdate: August 27 2020 $
38.Dt SSHD 8 38.Dt SSHD 8
39.Os 39.Os
40.Sh NAME 40.Sh NAME
@@ -631,6 +631,13 @@ This option only makes sense for the FIDO authenticator algorithms
631.Cm ecdsa-sk 631.Cm ecdsa-sk
632and 632and
633.Cm ed25519-sk . 633.Cm ed25519-sk .
634.It Cm verify-required
635Require that signatures made using this key attest that they verified
636the user, e.g. via a PIN.
637This option only makes sense for the FIDO authenticator algorithms
638.Cm ecdsa-sk
639and
640.Cm ed25519-sk .
634.It Cm restrict 641.It Cm restrict
635Enable all restrictions, i.e. disable port, agent and X11 forwarding, 642Enable all restrictions, i.e. disable port, agent and X11 forwarding,
636as well as disabling PTY allocation 643as well as disabling PTY allocation
diff --git a/sshd_config.5 b/sshd_config.5
index 17d8c130f..a1898baae 100644
--- a/sshd_config.5
+++ b/sshd_config.5
@@ -33,8 +33,8 @@
33.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 33.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
34.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35.\" 35.\"
36.\" $OpenBSD: sshd_config.5,v 1.312 2020/05/29 05:37:03 djm Exp $ 36.\" $OpenBSD: sshd_config.5,v 1.313 2020/08/27 01:07:10 djm Exp $
37.Dd $Mdocdate: May 29 2020 $ 37.Dd $Mdocdate: August 27 2020 $
38.Dt SSHD_CONFIG 5 38.Dt SSHD_CONFIG 5
39.Os 39.Os
40.Sh NAME 40.Sh NAME
@@ -1476,11 +1476,12 @@ The list of available key types may also be obtained using
1476.Qq ssh -Q PubkeyAcceptedKeyTypes . 1476.Qq ssh -Q PubkeyAcceptedKeyTypes .
1477.It Cm PubkeyAuthOptions 1477.It Cm PubkeyAuthOptions
1478Sets one or more public key authentication options. 1478Sets one or more public key authentication options.
1479Two option keywords are currently supported: 1479The supported keywords are:
1480.Cm none 1480.Cm none
1481(the default; indicating no additional options are enabled) 1481(the default; indicating no additional options are enabled),
1482.Cm touch-required
1482and 1483and
1483.Cm touch-required . 1484.Cm verify-required .
1484.Pp 1485.Pp
1485The 1486The
1486.Cm touch-required 1487.Cm touch-required
@@ -1497,7 +1498,17 @@ requires user presence unless overridden with an authorized_keys option.
1497The 1498The
1498.Cm touch-required 1499.Cm touch-required
1499flag disables this override. 1500flag disables this override.
1500This option has no effect for other, non-authenticator public key types. 1501.Pp
1502The
1503.Cm verify-required
1504option requires a FIDO key signature attest that verified the user, e.g.
1505via a PIN.
1506.Pp
1507Neither the
1508.Cm touch-required
1509or
1510.Cm verify-required
1511options have any effect for other, non-FIDO public key types.
1501.It Cm PubkeyAuthentication 1512.It Cm PubkeyAuthentication
1502Specifies whether public key authentication is allowed. 1513Specifies whether public key authentication is allowed.
1503The default is 1514The default is