summaryrefslogtreecommitdiff
path: root/usr.bin
diff options
context:
space:
mode:
authorDamien Miller <djm@cvs.openbsd.org>2022-01-14 03:43:49 +0000
committerDamien Miller <djm@cvs.openbsd.org>2022-01-14 03:43:49 +0000
commit36a3aa3617311b3dfacb415f3227d56d7bcf43ed (patch)
tree624d83e75fca7a7267b3dc4f8764eaa65f744aad /usr.bin
parent16b1fff7fe0abc84939cc7ef673a4e9dbca4bc25 (diff)
allow pin-required FIDO keys to be added to ssh-agent(1).
ssh-askpass will be used to request the PIN at authentication time. From Pedro Martelletto, ok djm
Diffstat (limited to 'usr.bin')
-rw-r--r--usr.bin/ssh/ssh-add.c7
-rw-r--r--usr.bin/ssh/ssh-agent.c41
2 files changed, 36 insertions, 12 deletions
diff --git a/usr.bin/ssh/ssh-add.c b/usr.bin/ssh/ssh-add.c
index 50790d2a014..ceefa749618 100644
--- a/usr.bin/ssh/ssh-add.c
+++ b/usr.bin/ssh/ssh-add.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-add.c,v 1.163 2021/12/22 06:56:41 jmc Exp $ */
+/* $OpenBSD: ssh-add.c,v 1.164 2022/01/14 03:43:48 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -349,11 +349,6 @@ add_file(int agent_fd, const char *filename, int key_only, int qflag,
"without provider\n", filename);
goto out;
}
- if ((private->sk_flags & SSH_SK_USER_VERIFICATION_REQD) != 0) {
- fprintf(stderr, "FIDO verify-required key %s is not "
- "currently supported by ssh-agent\n", filename);
- goto out;
- }
} else {
/* Don't send provider constraint for other keys */
skprovider = NULL;
diff --git a/usr.bin/ssh/ssh-agent.c b/usr.bin/ssh/ssh-agent.c
index c459dbec79e..83a162d4978 100644
--- a/usr.bin/ssh/ssh-agent.c
+++ b/usr.bin/ssh/ssh-agent.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-agent.c,v 1.286 2022/01/12 03:30:32 dtucker Exp $ */
+/* $OpenBSD: ssh-agent.c,v 1.287 2022/01/14 03:43:48 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -711,8 +711,9 @@ process_sign_request2(SocketEntry *e)
u_char *signature = NULL;
size_t slen = 0;
u_int compat = 0, flags;
- int r, ok = -1;
- char *fp = NULL, *user = NULL, *sig_dest = NULL;
+ int r, ok = -1, retried = 0;
+ char *fp = NULL, *pin = NULL, *prompt = NULL;
+ char *user = NULL, *sig_dest = NULL;
const char *fwd_host = NULL, *dest_host = NULL;
struct sshbuf *msg = NULL, *data = NULL, *sid = NULL;
struct sshkey *key = NULL, *hostkey = NULL;
@@ -799,7 +800,16 @@ process_sign_request2(SocketEntry *e)
/* error already logged */
goto send;
}
- if ((id->key->sk_flags & SSH_SK_USER_PRESENCE_REQD)) {
+ if ((id->key->sk_flags & SSH_SK_USER_VERIFICATION_REQD)) {
+ /* XXX include sig_dest */
+ xasprintf(&prompt, "Enter PIN%sfor %s key %s: ",
+ (id->key->sk_flags & SSH_SK_USER_PRESENCE_REQD) ?
+ " and confirm user presence " : " ",
+ sshkey_type(id->key), fp);
+ pin = read_passphrase(prompt, RP_USE_ASKPASS);
+ free(prompt);
+ prompt = NULL;
+ } else if ((id->key->sk_flags & SSH_SK_USER_PRESENCE_REQD)) {
notifier = notify_start(0,
"Confirm user presence for key %s %s%s%s",
sshkey_type(id->key), fp,
@@ -807,10 +817,26 @@ process_sign_request2(SocketEntry *e)
sig_dest == NULL ? "" : sig_dest);
}
}
- /* XXX support PIN required FIDO keys */
+ retry_pin:
if ((r = sshkey_sign(id->key, &signature, &slen,
sshbuf_ptr(data), sshbuf_len(data), agent_decode_alg(key, flags),
- id->sk_provider, NULL, compat)) != 0) {
+ id->sk_provider, pin, compat)) != 0) {
+ debug_fr(r, "sshkey_sign");
+ if (pin == NULL && !retried && sshkey_is_sk(id->key) &&
+ r == SSH_ERR_KEY_WRONG_PASSPHRASE) {
+ if (notifier) {
+ notify_complete(notifier, NULL);
+ notifier = NULL;
+ }
+ /* XXX include sig_dest */
+ xasprintf(&prompt, "Enter PIN%sfor %s key %s: ",
+ (id->key->sk_flags & SSH_SK_USER_PRESENCE_REQD) ?
+ " and confirm user presence " : " ",
+ sshkey_type(id->key), fp);
+ pin = read_passphrase(prompt, RP_USE_ASKPASS);
+ retried = 1;
+ goto retry_pin;
+ }
error_fr(r, "sshkey_sign");
goto send;
}
@@ -838,6 +864,9 @@ process_sign_request2(SocketEntry *e)
free(signature);
free(sig_dest);
free(user);
+ free(prompt);
+ if (pin != NULL)
+ freezero(pin, strlen(pin));
}
/* shared */