summaryrefslogtreecommitdiff
path: root/ssh-keygen.c
diff options
context:
space:
mode:
authordjm@openbsd.org <djm@openbsd.org>2020-01-23 02:43:48 +0000
committerDamien Miller <djm@mindrot.org>2020-01-23 13:45:24 +1100
commit56cffcc09f8a2e661d2ba02e61364ae6f998b2b1 (patch)
tree7056f21f29a73cce790ed19c6118983f1ceb6c7d /ssh-keygen.c
parent65cf8730de6876a56595eef296e07a86c52534a6 (diff)
upstream: add a new signature operations "find-principal" to look
up the principal associated with a signature from an allowed-signers file. Work by Sebastian Kinne; ok dtucker@ OpenBSD-Commit-ID: 6f782cc7e18e38fcfafa62af53246a1dcfe74e5d
Diffstat (limited to 'ssh-keygen.c')
-rw-r--r--ssh-keygen.c84
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
2601static int 2601static int
2602sign(const char *keypath, const char *sig_namespace, int argc, char **argv) 2602sig_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
2672static int 2672static int
2673verify(const char *signature, const char *sig_namespace, const char *principal, 2673sig_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
2760static int
2761sig_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;
2796done:
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
2760static void 2811static void
2761do_moduli_gen(const char *out_file, char **opts, size_t nopts) 2812do_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();