diff options
Diffstat (limited to 'ssh-keygen.c')
-rw-r--r-- | ssh-keygen.c | 84 |
1 files changed, 75 insertions, 9 deletions
diff --git a/ssh-keygen.c b/ssh-keygen.c index 04492979b..eebd89a27 100644 --- a/ssh-keygen.c +++ b/ssh-keygen.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssh-keygen.c,v 1.385 2020/01/22 04:51:51 claudio Exp $ */ | 1 | /* $OpenBSD: ssh-keygen.c,v 1.386 2020/01/23 02:43:48 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -2599,7 +2599,7 @@ sign_one(struct sshkey *signkey, const char *filename, int fd, | |||
2599 | } | 2599 | } |
2600 | 2600 | ||
2601 | static int | 2601 | static int |
2602 | sign(const char *keypath, const char *sig_namespace, int argc, char **argv) | 2602 | sig_sign(const char *keypath, const char *sig_namespace, int argc, char **argv) |
2603 | { | 2603 | { |
2604 | int i, fd = -1, r, ret = -1; | 2604 | int i, fd = -1, r, ret = -1; |
2605 | int agent_fd = -1; | 2605 | int agent_fd = -1; |
@@ -2670,8 +2670,8 @@ done: | |||
2670 | } | 2670 | } |
2671 | 2671 | ||
2672 | static int | 2672 | static int |
2673 | verify(const char *signature, const char *sig_namespace, const char *principal, | 2673 | sig_verify(const char *signature, const char *sig_namespace, |
2674 | const char *allowed_keys, const char *revoked_keys) | 2674 | const char *principal, const char *allowed_keys, const char *revoked_keys) |
2675 | { | 2675 | { |
2676 | int r, ret = -1, sigfd = -1; | 2676 | int r, ret = -1, sigfd = -1; |
2677 | struct sshbuf *sigbuf = NULL, *abuf = NULL; | 2677 | struct sshbuf *sigbuf = NULL, *abuf = NULL; |
@@ -2694,7 +2694,7 @@ verify(const char *signature, const char *sig_namespace, const char *principal, | |||
2694 | } | 2694 | } |
2695 | if ((r = sshsig_dearmor(abuf, &sigbuf)) != 0) { | 2695 | if ((r = sshsig_dearmor(abuf, &sigbuf)) != 0) { |
2696 | error("%s: sshsig_armor: %s", __func__, ssh_err(r)); | 2696 | error("%s: sshsig_armor: %s", __func__, ssh_err(r)); |
2697 | return r; | 2697 | goto done; |
2698 | } | 2698 | } |
2699 | if ((r = sshsig_verify_fd(sigbuf, STDIN_FILENO, sig_namespace, | 2699 | if ((r = sshsig_verify_fd(sigbuf, STDIN_FILENO, sig_namespace, |
2700 | &sign_key, &sig_details)) != 0) | 2700 | &sign_key, &sig_details)) != 0) |
@@ -2757,6 +2757,57 @@ done: | |||
2757 | return ret; | 2757 | return ret; |
2758 | } | 2758 | } |
2759 | 2759 | ||
2760 | static int | ||
2761 | sig_find_principal(const char *signature, const char *allowed_keys) { | ||
2762 | int r, ret = -1, sigfd = -1; | ||
2763 | struct sshbuf *sigbuf = NULL, *abuf = NULL; | ||
2764 | struct sshkey *sign_key = NULL; | ||
2765 | char *principal = NULL; | ||
2766 | |||
2767 | if ((abuf = sshbuf_new()) == NULL) | ||
2768 | fatal("%s: sshbuf_new() failed", __func__); | ||
2769 | |||
2770 | if ((sigfd = open(signature, O_RDONLY)) < 0) { | ||
2771 | error("Couldn't open signature file %s", signature); | ||
2772 | goto done; | ||
2773 | } | ||
2774 | |||
2775 | if ((r = sshkey_load_file(sigfd, abuf)) != 0) { | ||
2776 | error("Couldn't read signature file: %s", ssh_err(r)); | ||
2777 | goto done; | ||
2778 | } | ||
2779 | if ((r = sshsig_dearmor(abuf, &sigbuf)) != 0) { | ||
2780 | error("%s: sshsig_armor: %s", __func__, ssh_err(r)); | ||
2781 | goto done; | ||
2782 | } | ||
2783 | if ((r = sshsig_get_pubkey(sigbuf, &sign_key)) != 0) { | ||
2784 | error("%s: sshsig_get_pubkey: %s", | ||
2785 | __func__, ssh_err(r)); | ||
2786 | goto done; | ||
2787 | } | ||
2788 | |||
2789 | if ((r = sshsig_find_principal(allowed_keys, sign_key, | ||
2790 | &principal)) != 0) { | ||
2791 | error("%s: sshsig_get_principal: %s", | ||
2792 | __func__, ssh_err(r)); | ||
2793 | goto done; | ||
2794 | } | ||
2795 | ret = 0; | ||
2796 | done: | ||
2797 | if (ret == 0 ) { | ||
2798 | printf("Found matching principal: %s\n", principal); | ||
2799 | } else { | ||
2800 | printf("Could not find matching principal.\n"); | ||
2801 | } | ||
2802 | if (sigfd != -1) | ||
2803 | close(sigfd); | ||
2804 | sshbuf_free(sigbuf); | ||
2805 | sshbuf_free(abuf); | ||
2806 | sshkey_free(sign_key); | ||
2807 | free(principal); | ||
2808 | return ret; | ||
2809 | } | ||
2810 | |||
2760 | static void | 2811 | static void |
2761 | do_moduli_gen(const char *out_file, char **opts, size_t nopts) | 2812 | do_moduli_gen(const char *out_file, char **opts, size_t nopts) |
2762 | { | 2813 | { |
@@ -3042,6 +3093,7 @@ usage(void) | |||
3042 | " ssh-keygen -k -f krl_file [-u] [-s ca_public] [-z version_number]\n" | 3093 | " ssh-keygen -k -f krl_file [-u] [-s ca_public] [-z version_number]\n" |
3043 | " file ...\n" | 3094 | " file ...\n" |
3044 | " ssh-keygen -Q -f krl_file file ...\n" | 3095 | " ssh-keygen -Q -f krl_file file ...\n" |
3096 | " ssh-keygen -Y find-principal -s signature_file -f allowed_signers_file\n" | ||
3045 | " ssh-keygen -Y check-novalidate -n namespace -s signature_file\n" | 3097 | " ssh-keygen -Y check-novalidate -n namespace -s signature_file\n" |
3046 | " ssh-keygen -Y sign -f key_file -n namespace file ...\n" | 3098 | " ssh-keygen -Y sign -f key_file -n namespace file ...\n" |
3047 | " ssh-keygen -Y verify -f allowed_signers_file -I signer_identity\n" | 3099 | " ssh-keygen -Y verify -f allowed_signers_file -I signer_identity\n" |
@@ -3305,6 +3357,19 @@ main(int argc, char **argv) | |||
3305 | argc -= optind; | 3357 | argc -= optind; |
3306 | 3358 | ||
3307 | if (sign_op != NULL) { | 3359 | if (sign_op != NULL) { |
3360 | if (strncmp(sign_op, "find-principal", 14) == 0) { | ||
3361 | if (ca_key_path == NULL) { | ||
3362 | error("Too few arguments for find-principal:" | ||
3363 | "missing signature file"); | ||
3364 | exit(1); | ||
3365 | } | ||
3366 | if (!have_identity) { | ||
3367 | error("Too few arguments for find-principal:" | ||
3368 | "missing allowed keys file"); | ||
3369 | exit(1); | ||
3370 | } | ||
3371 | return sig_find_principal(ca_key_path, identity_file); | ||
3372 | } | ||
3308 | if (cert_principals == NULL || *cert_principals == '\0') { | 3373 | if (cert_principals == NULL || *cert_principals == '\0') { |
3309 | error("Too few arguments for sign/verify: " | 3374 | error("Too few arguments for sign/verify: " |
3310 | "missing namespace"); | 3375 | "missing namespace"); |
@@ -3316,15 +3381,16 @@ main(int argc, char **argv) | |||
3316 | "missing key"); | 3381 | "missing key"); |
3317 | exit(1); | 3382 | exit(1); |
3318 | } | 3383 | } |
3319 | return sign(identity_file, cert_principals, argc, argv); | 3384 | return sig_sign(identity_file, cert_principals, |
3385 | argc, argv); | ||
3320 | } else if (strncmp(sign_op, "check-novalidate", 16) == 0) { | 3386 | } else if (strncmp(sign_op, "check-novalidate", 16) == 0) { |
3321 | if (ca_key_path == NULL) { | 3387 | if (ca_key_path == NULL) { |
3322 | error("Too few arguments for check-novalidate: " | 3388 | error("Too few arguments for check-novalidate: " |
3323 | "missing signature file"); | 3389 | "missing signature file"); |
3324 | exit(1); | 3390 | exit(1); |
3325 | } | 3391 | } |
3326 | return verify(ca_key_path, cert_principals, | 3392 | return sig_verify(ca_key_path, cert_principals, |
3327 | NULL, NULL, NULL); | 3393 | NULL, NULL, NULL); |
3328 | } else if (strncmp(sign_op, "verify", 6) == 0) { | 3394 | } else if (strncmp(sign_op, "verify", 6) == 0) { |
3329 | if (ca_key_path == NULL) { | 3395 | if (ca_key_path == NULL) { |
3330 | error("Too few arguments for verify: " | 3396 | error("Too few arguments for verify: " |
@@ -3341,7 +3407,7 @@ main(int argc, char **argv) | |||
3341 | "missing principal ID"); | 3407 | "missing principal ID"); |
3342 | exit(1); | 3408 | exit(1); |
3343 | } | 3409 | } |
3344 | return verify(ca_key_path, cert_principals, | 3410 | return sig_verify(ca_key_path, cert_principals, |
3345 | cert_key_id, identity_file, rr_hostname); | 3411 | cert_key_id, identity_file, rr_hostname); |
3346 | } | 3412 | } |
3347 | usage(); | 3413 | usage(); |