summaryrefslogtreecommitdiff
path: root/ssh-add.c
diff options
context:
space:
mode:
authordjm@openbsd.org <djm@openbsd.org>2019-10-31 21:19:56 +0000
committerDamien Miller <djm@mindrot.org>2019-11-01 09:46:09 +1100
commit486164d060314a7f8bca2a00f53be9e900c5e74d (patch)
treefd88518f7ef5c9e8b8ea168f670e929b1a81c4a1 /ssh-add.c
parentb9dd14d3091e31fb836f69873d3aa622eb7b4a1c (diff)
upstream: ssh-add support for U2F/FIDO keys
OpenBSD-Commit-ID: 7f88a5181c982687afedf3130c6ab2bba60f7644
Diffstat (limited to 'ssh-add.c')
-rw-r--r--ssh-add.c37
1 files changed, 27 insertions, 10 deletions
diff --git a/ssh-add.c b/ssh-add.c
index 2c65d0272..3c8849ac4 100644
--- a/ssh-add.c
+++ b/ssh-add.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh-add.c,v 1.142 2019/10/31 21:19:15 djm Exp $ */ 1/* $OpenBSD: ssh-add.c,v 1.143 2019/10/31 21:19:56 djm Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -77,6 +77,7 @@ static char *default_files[] = {
77 _PATH_SSH_CLIENT_ID_DSA, 77 _PATH_SSH_CLIENT_ID_DSA,
78#ifdef OPENSSL_HAS_ECC 78#ifdef OPENSSL_HAS_ECC
79 _PATH_SSH_CLIENT_ID_ECDSA, 79 _PATH_SSH_CLIENT_ID_ECDSA,
80 _PATH_SSH_CLIENT_ID_ECDSA_SK,
80#endif 81#endif
81#endif /* WITH_OPENSSL */ 82#endif /* WITH_OPENSSL */
82 _PATH_SSH_CLIENT_ID_ED25519, 83 _PATH_SSH_CLIENT_ID_ED25519,
@@ -191,7 +192,8 @@ delete_all(int agent_fd, int qflag)
191} 192}
192 193
193static int 194static int
194add_file(int agent_fd, const char *filename, int key_only, int qflag) 195add_file(int agent_fd, const char *filename, int key_only, int qflag,
196 const char *skprovider)
195{ 197{
196 struct sshkey *private, *cert; 198 struct sshkey *private, *cert;
197 char *comment = NULL; 199 char *comment = NULL;
@@ -310,8 +312,16 @@ add_file(int agent_fd, const char *filename, int key_only, int qflag)
310 ssh_free_identitylist(idlist); 312 ssh_free_identitylist(idlist);
311 } 313 }
312 314
315 if (sshkey_type_plain(private->type) != KEY_ECDSA_SK)
316 skprovider = NULL; /* Don't send constraint for other keys */
317 else if (skprovider == NULL) {
318 fprintf(stderr, "Cannot load security key %s without "
319 "provider\n", filename);
320 goto out;
321 }
322
313 if ((r = ssh_add_identity_constrained(agent_fd, private, comment, 323 if ((r = ssh_add_identity_constrained(agent_fd, private, comment,
314 lifetime, confirm, maxsign, NULL)) == 0) { 324 lifetime, confirm, maxsign, skprovider)) == 0) {
315 ret = 0; 325 ret = 0;
316 if (!qflag) { 326 if (!qflag) {
317 fprintf(stderr, "Identity added: %s (%s)\n", 327 fprintf(stderr, "Identity added: %s (%s)\n",
@@ -364,7 +374,7 @@ add_file(int agent_fd, const char *filename, int key_only, int qflag)
364 sshkey_free(cert); 374 sshkey_free(cert);
365 375
366 if ((r = ssh_add_identity_constrained(agent_fd, private, comment, 376 if ((r = ssh_add_identity_constrained(agent_fd, private, comment,
367 lifetime, confirm, maxsign, NULL)) != 0) { 377 lifetime, confirm, maxsign, skprovider)) != 0) {
368 error("Certificate %s (%s) add failed: %s", certpath, 378 error("Certificate %s (%s) add failed: %s", certpath,
369 private->cert->key_id, ssh_err(r)); 379 private->cert->key_id, ssh_err(r));
370 goto out; 380 goto out;
@@ -529,13 +539,14 @@ lock_agent(int agent_fd, int lock)
529} 539}
530 540
531static int 541static int
532do_file(int agent_fd, int deleting, int key_only, char *file, int qflag) 542do_file(int agent_fd, int deleting, int key_only, char *file, int qflag,
543 const char *skprovider)
533{ 544{
534 if (deleting) { 545 if (deleting) {
535 if (delete_file(agent_fd, file, key_only, qflag) == -1) 546 if (delete_file(agent_fd, file, key_only, qflag) == -1)
536 return -1; 547 return -1;
537 } else { 548 } else {
538 if (add_file(agent_fd, file, key_only, qflag) == -1) 549 if (add_file(agent_fd, file, key_only, qflag, skprovider) == -1)
539 return -1; 550 return -1;
540 } 551 }
541 return 0; 552 return 0;
@@ -561,6 +572,7 @@ usage(void)
561 fprintf(stderr, " -s pkcs11 Add keys from PKCS#11 provider.\n"); 572 fprintf(stderr, " -s pkcs11 Add keys from PKCS#11 provider.\n");
562 fprintf(stderr, " -e pkcs11 Remove keys provided by PKCS#11 provider.\n"); 573 fprintf(stderr, " -e pkcs11 Remove keys provided by PKCS#11 provider.\n");
563 fprintf(stderr, " -T pubkey Test if ssh-agent can access matching private key.\n"); 574 fprintf(stderr, " -T pubkey Test if ssh-agent can access matching private key.\n");
575 fprintf(stderr, " -S provider Specify security key provider.\n");
564 fprintf(stderr, " -q Be quiet after a successful operation.\n"); 576 fprintf(stderr, " -q Be quiet after a successful operation.\n");
565 fprintf(stderr, " -v Be more verbose.\n"); 577 fprintf(stderr, " -v Be more verbose.\n");
566} 578}
@@ -571,7 +583,7 @@ main(int argc, char **argv)
571 extern char *optarg; 583 extern char *optarg;
572 extern int optind; 584 extern int optind;
573 int agent_fd; 585 int agent_fd;
574 char *pkcs11provider = NULL; 586 char *pkcs11provider = NULL, *skprovider = NULL;
575 int r, i, ch, deleting = 0, ret = 0, key_only = 0; 587 int r, i, ch, deleting = 0, ret = 0, key_only = 0;
576 int xflag = 0, lflag = 0, Dflag = 0, qflag = 0, Tflag = 0; 588 int xflag = 0, lflag = 0, Dflag = 0, qflag = 0, Tflag = 0;
577 SyslogFacility log_facility = SYSLOG_FACILITY_AUTH; 589 SyslogFacility log_facility = SYSLOG_FACILITY_AUTH;
@@ -600,7 +612,9 @@ main(int argc, char **argv)
600 exit(2); 612 exit(2);
601 } 613 }
602 614
603 while ((ch = getopt(argc, argv, "vklLcdDTxXE:e:M:m:qs:t:")) != -1) { 615 skprovider = getenv("SSH_SK_PROVIDER");
616
617 while ((ch = getopt(argc, argv, "vklLcdDTxXE:e:M:m:qs:S:t:")) != -1) {
604 switch (ch) { 618 switch (ch) {
605 case 'v': 619 case 'v':
606 if (log_level == SYSLOG_LEVEL_INFO) 620 if (log_level == SYSLOG_LEVEL_INFO)
@@ -656,6 +670,9 @@ main(int argc, char **argv)
656 case 's': 670 case 's':
657 pkcs11provider = optarg; 671 pkcs11provider = optarg;
658 break; 672 break;
673 case 'S':
674 skprovider = optarg;
675 break;
659 case 'e': 676 case 'e':
660 deleting = 1; 677 deleting = 1;
661 pkcs11provider = optarg; 678 pkcs11provider = optarg;
@@ -732,7 +749,7 @@ main(int argc, char **argv)
732 if (stat(buf, &st) == -1) 749 if (stat(buf, &st) == -1)
733 continue; 750 continue;
734 if (do_file(agent_fd, deleting, key_only, buf, 751 if (do_file(agent_fd, deleting, key_only, buf,
735 qflag) == -1) 752 qflag, skprovider) == -1)
736 ret = 1; 753 ret = 1;
737 else 754 else
738 count++; 755 count++;
@@ -742,7 +759,7 @@ main(int argc, char **argv)
742 } else { 759 } else {
743 for (i = 0; i < argc; i++) { 760 for (i = 0; i < argc; i++) {
744 if (do_file(agent_fd, deleting, key_only, 761 if (do_file(agent_fd, deleting, key_only,
745 argv[i], qflag) == -1) 762 argv[i], qflag, skprovider) == -1)
746 ret = 1; 763 ret = 1;
747 } 764 }
748 } 765 }