summaryrefslogtreecommitdiffstats
path: root/usr.bin/ssh/ssh-keygen.c
diff options
context:
space:
mode:
authordjm <djm@openbsd.org>2020-01-23 02:43:48 +0000
committerdjm <djm@openbsd.org>2020-01-23 02:43:48 +0000
commit80b4cf6a93605061dc8f287d3fc920f40dff8704 (patch)
treebc50489d40ff667e735dc28170fe5cb6d6bdd2ac /usr.bin/ssh/ssh-keygen.c
parentwire up pppac(4) to some majors on each arch. (diff)
downloadwireguard-openbsd-80b4cf6a93605061dc8f287d3fc920f40dff8704.tar.xz
wireguard-openbsd-80b4cf6a93605061dc8f287d3fc920f40dff8704.zip
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@
Diffstat (limited to 'usr.bin/ssh/ssh-keygen.c')
-rw-r--r--usr.bin/ssh/ssh-keygen.c84
1 files changed, 75 insertions, 9 deletions
diff --git a/usr.bin/ssh/ssh-keygen.c b/usr.bin/ssh/ssh-keygen.c
index fbf31f2a95d..635821d7309 100644
--- a/usr.bin/ssh/ssh-keygen.c
+++ b/usr.bin/ssh/ssh-keygen.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-keygen.c,v 1.385 2020/01/22 04:51:51 claudio Exp $ */
+/* $OpenBSD: ssh-keygen.c,v 1.386 2020/01/23 02:43:48 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -2579,7 +2579,7 @@ sign_one(struct sshkey *signkey, const char *filename, int fd,
}
static int
-sign(const char *keypath, const char *sig_namespace, int argc, char **argv)
+sig_sign(const char *keypath, const char *sig_namespace, int argc, char **argv)
{
int i, fd = -1, r, ret = -1;
int agent_fd = -1;
@@ -2650,8 +2650,8 @@ done:
}
static int
-verify(const char *signature, const char *sig_namespace, const char *principal,
- const char *allowed_keys, const char *revoked_keys)
+sig_verify(const char *signature, const char *sig_namespace,
+ const char *principal, const char *allowed_keys, const char *revoked_keys)
{
int r, ret = -1, sigfd = -1;
struct sshbuf *sigbuf = NULL, *abuf = NULL;
@@ -2674,7 +2674,7 @@ verify(const char *signature, const char *sig_namespace, const char *principal,
}
if ((r = sshsig_dearmor(abuf, &sigbuf)) != 0) {
error("%s: sshsig_armor: %s", __func__, ssh_err(r));
- return r;
+ goto done;
}
if ((r = sshsig_verify_fd(sigbuf, STDIN_FILENO, sig_namespace,
&sign_key, &sig_details)) != 0)
@@ -2737,6 +2737,57 @@ done:
return ret;
}
+static int
+sig_find_principal(const char *signature, const char *allowed_keys) {
+ int r, ret = -1, sigfd = -1;
+ struct sshbuf *sigbuf = NULL, *abuf = NULL;
+ struct sshkey *sign_key = NULL;
+ char *principal = NULL;
+
+ if ((abuf = sshbuf_new()) == NULL)
+ fatal("%s: sshbuf_new() failed", __func__);
+
+ if ((sigfd = open(signature, O_RDONLY)) < 0) {
+ error("Couldn't open signature file %s", signature);
+ goto done;
+ }
+
+ if ((r = sshkey_load_file(sigfd, abuf)) != 0) {
+ error("Couldn't read signature file: %s", ssh_err(r));
+ goto done;
+ }
+ if ((r = sshsig_dearmor(abuf, &sigbuf)) != 0) {
+ error("%s: sshsig_armor: %s", __func__, ssh_err(r));
+ goto done;
+ }
+ if ((r = sshsig_get_pubkey(sigbuf, &sign_key)) != 0) {
+ error("%s: sshsig_get_pubkey: %s",
+ __func__, ssh_err(r));
+ goto done;
+ }
+
+ if ((r = sshsig_find_principal(allowed_keys, sign_key,
+ &principal)) != 0) {
+ error("%s: sshsig_get_principal: %s",
+ __func__, ssh_err(r));
+ goto done;
+ }
+ ret = 0;
+done:
+ if (ret == 0 ) {
+ printf("Found matching principal: %s\n", principal);
+ } else {
+ printf("Could not find matching principal.\n");
+ }
+ if (sigfd != -1)
+ close(sigfd);
+ sshbuf_free(sigbuf);
+ sshbuf_free(abuf);
+ sshkey_free(sign_key);
+ free(principal);
+ return ret;
+}
+
static void
do_moduli_gen(const char *out_file, char **opts, size_t nopts)
{
@@ -3022,6 +3073,7 @@ usage(void)
" ssh-keygen -k -f krl_file [-u] [-s ca_public] [-z version_number]\n"
" file ...\n"
" ssh-keygen -Q -f krl_file file ...\n"
+ " ssh-keygen -Y find-principal -s signature_file -f allowed_signers_file\n"
" ssh-keygen -Y check-novalidate -n namespace -s signature_file\n"
" ssh-keygen -Y sign -f key_file -n namespace file ...\n"
" ssh-keygen -Y verify -f allowed_signers_file -I signer_identity\n"
@@ -3282,6 +3334,19 @@ main(int argc, char **argv)
argc -= optind;
if (sign_op != NULL) {
+ if (strncmp(sign_op, "find-principal", 14) == 0) {
+ if (ca_key_path == NULL) {
+ error("Too few arguments for find-principal:"
+ "missing signature file");
+ exit(1);
+ }
+ if (!have_identity) {
+ error("Too few arguments for find-principal:"
+ "missing allowed keys file");
+ exit(1);
+ }
+ return sig_find_principal(ca_key_path, identity_file);
+ }
if (cert_principals == NULL || *cert_principals == '\0') {
error("Too few arguments for sign/verify: "
"missing namespace");
@@ -3293,15 +3358,16 @@ main(int argc, char **argv)
"missing key");
exit(1);
}
- return sign(identity_file, cert_principals, argc, argv);
+ return sig_sign(identity_file, cert_principals,
+ argc, argv);
} else if (strncmp(sign_op, "check-novalidate", 16) == 0) {
if (ca_key_path == NULL) {
error("Too few arguments for check-novalidate: "
"missing signature file");
exit(1);
}
- return verify(ca_key_path, cert_principals,
- NULL, NULL, NULL);
+ return sig_verify(ca_key_path, cert_principals,
+ NULL, NULL, NULL);
} else if (strncmp(sign_op, "verify", 6) == 0) {
if (ca_key_path == NULL) {
error("Too few arguments for verify: "
@@ -3318,7 +3384,7 @@ main(int argc, char **argv)
"missing principal ID");
exit(1);
}
- return verify(ca_key_path, cert_principals,
+ return sig_verify(ca_key_path, cert_principals,
cert_key_id, identity_file, rr_hostname);
}
usage();