summaryrefslogtreecommitdiffstats
path: root/usr.bin/ssh/ssh-add.c
diff options
context:
space:
mode:
authordjm <djm@openbsd.org>2019-10-31 21:19:56 +0000
committerdjm <djm@openbsd.org>2019-10-31 21:19:56 +0000
commit8867a42f6e51fdcd31198eb6283fd95976795cb9 (patch)
tree314b2b8c6c0f3013f82d7d8046be30de3db9497a /usr.bin/ssh/ssh-add.c
parentadd new agent key constraint for U2F/FIDO provider (diff)
downloadwireguard-openbsd-8867a42f6e51fdcd31198eb6283fd95976795cb9.tar.xz
wireguard-openbsd-8867a42f6e51fdcd31198eb6283fd95976795cb9.zip
ssh-add support for U2F/FIDO keys
Diffstat (limited to 'usr.bin/ssh/ssh-add.c')
-rw-r--r--usr.bin/ssh/ssh-add.c37
1 files changed, 27 insertions, 10 deletions
diff --git a/usr.bin/ssh/ssh-add.c b/usr.bin/ssh/ssh-add.c
index 2d26f01fc81..6d7484fdd4b 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.142 2019/10/31 21:19:15 djm Exp $ */
+/* $OpenBSD: ssh-add.c,v 1.143 2019/10/31 21:19:56 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -71,6 +71,7 @@ static char *default_files[] = {
_PATH_SSH_CLIENT_ID_RSA,
_PATH_SSH_CLIENT_ID_DSA,
_PATH_SSH_CLIENT_ID_ECDSA,
+ _PATH_SSH_CLIENT_ID_ECDSA_SK,
_PATH_SSH_CLIENT_ID_ED25519,
_PATH_SSH_CLIENT_ID_XMSS,
NULL
@@ -183,7 +184,8 @@ delete_all(int agent_fd, int qflag)
}
static int
-add_file(int agent_fd, const char *filename, int key_only, int qflag)
+add_file(int agent_fd, const char *filename, int key_only, int qflag,
+ const char *skprovider)
{
struct sshkey *private, *cert;
char *comment = NULL;
@@ -302,8 +304,16 @@ add_file(int agent_fd, const char *filename, int key_only, int qflag)
ssh_free_identitylist(idlist);
}
+ if (sshkey_type_plain(private->type) != KEY_ECDSA_SK)
+ skprovider = NULL; /* Don't send constraint for other keys */
+ else if (skprovider == NULL) {
+ fprintf(stderr, "Cannot load security key %s without "
+ "provider\n", filename);
+ goto out;
+ }
+
if ((r = ssh_add_identity_constrained(agent_fd, private, comment,
- lifetime, confirm, maxsign, NULL)) == 0) {
+ lifetime, confirm, maxsign, skprovider)) == 0) {
ret = 0;
if (!qflag) {
fprintf(stderr, "Identity added: %s (%s)\n",
@@ -356,7 +366,7 @@ add_file(int agent_fd, const char *filename, int key_only, int qflag)
sshkey_free(cert);
if ((r = ssh_add_identity_constrained(agent_fd, private, comment,
- lifetime, confirm, maxsign, NULL)) != 0) {
+ lifetime, confirm, maxsign, skprovider)) != 0) {
error("Certificate %s (%s) add failed: %s", certpath,
private->cert->key_id, ssh_err(r));
goto out;
@@ -521,13 +531,14 @@ lock_agent(int agent_fd, int lock)
}
static int
-do_file(int agent_fd, int deleting, int key_only, char *file, int qflag)
+do_file(int agent_fd, int deleting, int key_only, char *file, int qflag,
+ const char *skprovider)
{
if (deleting) {
if (delete_file(agent_fd, file, key_only, qflag) == -1)
return -1;
} else {
- if (add_file(agent_fd, file, key_only, qflag) == -1)
+ if (add_file(agent_fd, file, key_only, qflag, skprovider) == -1)
return -1;
}
return 0;
@@ -553,6 +564,7 @@ usage(void)
fprintf(stderr, " -s pkcs11 Add keys from PKCS#11 provider.\n");
fprintf(stderr, " -e pkcs11 Remove keys provided by PKCS#11 provider.\n");
fprintf(stderr, " -T pubkey Test if ssh-agent can access matching private key.\n");
+ fprintf(stderr, " -S provider Specify security key provider.\n");
fprintf(stderr, " -q Be quiet after a successful operation.\n");
fprintf(stderr, " -v Be more verbose.\n");
}
@@ -563,7 +575,7 @@ main(int argc, char **argv)
extern char *optarg;
extern int optind;
int agent_fd;
- char *pkcs11provider = NULL;
+ char *pkcs11provider = NULL, *skprovider = NULL;
int r, i, ch, deleting = 0, ret = 0, key_only = 0;
int xflag = 0, lflag = 0, Dflag = 0, qflag = 0, Tflag = 0;
SyslogFacility log_facility = SYSLOG_FACILITY_AUTH;
@@ -592,7 +604,9 @@ main(int argc, char **argv)
exit(2);
}
- while ((ch = getopt(argc, argv, "vklLcdDTxXE:e:M:m:qs:t:")) != -1) {
+ skprovider = getenv("SSH_SK_PROVIDER");
+
+ while ((ch = getopt(argc, argv, "vklLcdDTxXE:e:M:m:qs:S:t:")) != -1) {
switch (ch) {
case 'v':
if (log_level == SYSLOG_LEVEL_INFO)
@@ -648,6 +662,9 @@ main(int argc, char **argv)
case 's':
pkcs11provider = optarg;
break;
+ case 'S':
+ skprovider = optarg;
+ break;
case 'e':
deleting = 1;
pkcs11provider = optarg;
@@ -724,7 +741,7 @@ main(int argc, char **argv)
if (stat(buf, &st) == -1)
continue;
if (do_file(agent_fd, deleting, key_only, buf,
- qflag) == -1)
+ qflag, skprovider) == -1)
ret = 1;
else
count++;
@@ -734,7 +751,7 @@ main(int argc, char **argv)
} else {
for (i = 0; i < argc; i++) {
if (do_file(agent_fd, deleting, key_only,
- argv[i], qflag) == -1)
+ argv[i], qflag, skprovider) == -1)
ret = 1;
}
}