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 04492979..eebd89a2 100644
--- a/ssh-keygen.c
+++ b/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
@@ -2599,7 +2599,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;
@@ -2670,8 +2670,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;
@@ -2694,7 +2694,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)
@@ -2757,6 +2757,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)
{
@@ -3042,6 +3093,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"
@@ -3305,6 +3357,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");
@@ -3316,15 +3381,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: "
@@ -3341,7 +3407,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();