diff options
Diffstat (limited to 'ssh-add.c')
-rw-r--r-- | ssh-add.c | 66 |
1 files changed, 60 insertions, 6 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssh-add.c,v 1.136 2018/09/19 02:03:02 djm Exp $ */ | 1 | /* $OpenBSD: ssh-add.c,v 1.138 2019/01/21 12:53:35 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 |
@@ -418,6 +418,40 @@ update_card(int agent_fd, int add, const char *id, int qflag) | |||
418 | } | 418 | } |
419 | 419 | ||
420 | static int | 420 | static int |
421 | test_key(int agent_fd, const char *filename) | ||
422 | { | ||
423 | struct sshkey *key = NULL; | ||
424 | u_char *sig = NULL; | ||
425 | size_t slen = 0; | ||
426 | int r, ret = -1; | ||
427 | char data[1024]; | ||
428 | |||
429 | if ((r = sshkey_load_public(filename, &key, NULL)) != 0) { | ||
430 | error("Couldn't read public key %s: %s", filename, ssh_err(r)); | ||
431 | return -1; | ||
432 | } | ||
433 | arc4random_buf(data, sizeof(data)); | ||
434 | if ((r = ssh_agent_sign(agent_fd, key, &sig, &slen, data, sizeof(data), | ||
435 | NULL, 0)) != 0) { | ||
436 | error("Agent signature failed for %s: %s", | ||
437 | filename, ssh_err(r)); | ||
438 | goto done; | ||
439 | } | ||
440 | if ((r = sshkey_verify(key, sig, slen, data, sizeof(data), | ||
441 | NULL, 0)) != 0) { | ||
442 | error("Signature verification failed for %s: %s", | ||
443 | filename, ssh_err(r)); | ||
444 | goto done; | ||
445 | } | ||
446 | /* success */ | ||
447 | ret = 0; | ||
448 | done: | ||
449 | free(sig); | ||
450 | sshkey_free(key); | ||
451 | return ret; | ||
452 | } | ||
453 | |||
454 | static int | ||
421 | list_identities(int agent_fd, int do_fp) | 455 | list_identities(int agent_fd, int do_fp) |
422 | { | 456 | { |
423 | char *fp; | 457 | char *fp; |
@@ -524,7 +558,9 @@ usage(void) | |||
524 | fprintf(stderr, " -X Unlock agent.\n"); | 558 | fprintf(stderr, " -X Unlock agent.\n"); |
525 | fprintf(stderr, " -s pkcs11 Add keys from PKCS#11 provider.\n"); | 559 | fprintf(stderr, " -s pkcs11 Add keys from PKCS#11 provider.\n"); |
526 | fprintf(stderr, " -e pkcs11 Remove keys provided by PKCS#11 provider.\n"); | 560 | fprintf(stderr, " -e pkcs11 Remove keys provided by PKCS#11 provider.\n"); |
561 | fprintf(stderr, " -T pubkey Test if ssh-agent can access matching private key.\n"); | ||
527 | fprintf(stderr, " -q Be quiet after a successful operation.\n"); | 562 | fprintf(stderr, " -q Be quiet after a successful operation.\n"); |
563 | fprintf(stderr, " -v Be more verbose.\n"); | ||
528 | } | 564 | } |
529 | 565 | ||
530 | int | 566 | int |
@@ -535,7 +571,9 @@ main(int argc, char **argv) | |||
535 | int agent_fd; | 571 | int agent_fd; |
536 | char *pkcs11provider = NULL; | 572 | char *pkcs11provider = NULL; |
537 | int r, i, ch, deleting = 0, ret = 0, key_only = 0; | 573 | int r, i, ch, deleting = 0, ret = 0, key_only = 0; |
538 | int xflag = 0, lflag = 0, Dflag = 0, qflag = 0; | 574 | int xflag = 0, lflag = 0, Dflag = 0, qflag = 0, Tflag = 0; |
575 | SyslogFacility log_facility = SYSLOG_FACILITY_AUTH; | ||
576 | LogLevel log_level = SYSLOG_LEVEL_INFO; | ||
539 | 577 | ||
540 | ssh_malloc_init(); /* must be called before any mallocs */ | 578 | ssh_malloc_init(); /* must be called before any mallocs */ |
541 | /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ | 579 | /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ |
@@ -544,9 +582,7 @@ main(int argc, char **argv) | |||
544 | __progname = ssh_get_progname(argv[0]); | 582 | __progname = ssh_get_progname(argv[0]); |
545 | seed_rng(); | 583 | seed_rng(); |
546 | 584 | ||
547 | #ifdef WITH_OPENSSL | 585 | log_init(__progname, log_level, log_facility, 1); |
548 | OpenSSL_add_all_algorithms(); | ||
549 | #endif | ||
550 | 586 | ||
551 | setvbuf(stdout, NULL, _IOLBF, 0); | 587 | setvbuf(stdout, NULL, _IOLBF, 0); |
552 | 588 | ||
@@ -563,8 +599,14 @@ main(int argc, char **argv) | |||
563 | exit(2); | 599 | exit(2); |
564 | } | 600 | } |
565 | 601 | ||
566 | while ((ch = getopt(argc, argv, "klLcdDxXE:e:M:m:qs:t:")) != -1) { | 602 | while ((ch = getopt(argc, argv, "vklLcdDTxXE:e:M:m:qs:t:")) != -1) { |
567 | switch (ch) { | 603 | switch (ch) { |
604 | case 'v': | ||
605 | if (log_level == SYSLOG_LEVEL_INFO) | ||
606 | log_level = SYSLOG_LEVEL_DEBUG1; | ||
607 | else if (log_level < SYSLOG_LEVEL_DEBUG3) | ||
608 | log_level++; | ||
609 | break; | ||
568 | case 'E': | 610 | case 'E': |
569 | fingerprint_hash = ssh_digest_alg_by_name(optarg); | 611 | fingerprint_hash = ssh_digest_alg_by_name(optarg); |
570 | if (fingerprint_hash == -1) | 612 | if (fingerprint_hash == -1) |
@@ -627,12 +669,16 @@ main(int argc, char **argv) | |||
627 | case 'q': | 669 | case 'q': |
628 | qflag = 1; | 670 | qflag = 1; |
629 | break; | 671 | break; |
672 | case 'T': | ||
673 | Tflag = 1; | ||
674 | break; | ||
630 | default: | 675 | default: |
631 | usage(); | 676 | usage(); |
632 | ret = 1; | 677 | ret = 1; |
633 | goto done; | 678 | goto done; |
634 | } | 679 | } |
635 | } | 680 | } |
681 | log_init(__progname, log_level, log_facility, 1); | ||
636 | 682 | ||
637 | if ((xflag != 0) + (lflag != 0) + (Dflag != 0) > 1) | 683 | if ((xflag != 0) + (lflag != 0) + (Dflag != 0) > 1) |
638 | fatal("Invalid combination of actions"); | 684 | fatal("Invalid combination of actions"); |
@@ -652,6 +698,14 @@ main(int argc, char **argv) | |||
652 | 698 | ||
653 | argc -= optind; | 699 | argc -= optind; |
654 | argv += optind; | 700 | argv += optind; |
701 | if (Tflag) { | ||
702 | if (argc <= 0) | ||
703 | fatal("no keys to test"); | ||
704 | for (r = i = 0; i < argc; i++) | ||
705 | r |= test_key(agent_fd, argv[i]); | ||
706 | ret = r == 0 ? 0 : 1; | ||
707 | goto done; | ||
708 | } | ||
655 | if (pkcs11provider != NULL) { | 709 | if (pkcs11provider != NULL) { |
656 | if (update_card(agent_fd, !deleting, pkcs11provider, | 710 | if (update_card(agent_fd, !deleting, pkcs11provider, |
657 | qflag) == -1) | 711 | qflag) == -1) |