diff options
author | Werner Koch <[email protected]> | 2023-04-05 19:32:23 +0000 |
---|---|---|
committer | Werner Koch <[email protected]> | 2023-04-05 19:32:23 +0000 |
commit | c9e95b8dee05b9a837419fdef9a98f0b3e9671ed (patch) | |
tree | c8f574986ea2a49707e5c29e7102bbd88c9478f3 /g10/verify.c | |
parent | speedo,w32: Remove removed profiles and temporary disable runonce. (diff) | |
download | gnupg-c9e95b8dee05b9a837419fdef9a98f0b3e9671ed.tar.gz gnupg-c9e95b8dee05b9a837419fdef9a98f0b3e9671ed.zip |
gpg: New option --assert-signer.
* g10/gpg.c (enum cmd_and_opt_values): Add oAssertSigner.
(opts): Add "assert-signer".
(main): Set option.
(assert_signer_true): New var.
(g10_exit): Evaluate new var.
* g10/main.h (assert_signer_true): Declare new var.
* common/status.h (STATUS_ASSERT_SIGNER): New.
* g10/options.h (opt): Add field assert_signer_list.
* g10/verify.c (is_fingerprint): New.
(check_assert_signer_list): New.
* g10/mainproc.c (check_sig_and_print): Call that function. Clear
assert_signer_true on a warning.
* g10/gpgv.c: Add dummy function and vars.
* g10/t-keydb-get-keyblock.c: Ditto.
* g10/t-keydb.c: Ditto.
* g10/t-stutter.c: Ditto.
--
Diffstat (limited to 'g10/verify.c')
-rw-r--r-- | g10/verify.c | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/g10/verify.c b/g10/verify.c index fc18882b0..e9792939d 100644 --- a/g10/verify.c +++ b/g10/verify.c @@ -1,6 +1,8 @@ /* verify.c - Verify signed data * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2006, * 2007, 2010 Free Software Foundation, Inc. + * Copyright (C) 2003, 2006-2008, 2010-2011, 2015-2017, + * 2020, 2023 g10 Code GmbH * * This file is part of GnuPG. * @@ -16,6 +18,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, see <https://www.gnu.org/licenses/>. + * SPDX-License-Identifier: GPL-3.0-or-later */ #include <config.h> @@ -281,3 +284,124 @@ gpg_verify (ctrl_t ctrl, int sig_fd, int data_fd, estream_t out_fp) release_armor_context (afx); return rc; } + + +static int +is_fingerprint (const char *string) +{ + int n; + + if (!string || !*string) + return 0; + for (n=0; hexdigitp (string); string++) + n++; + if (!*string && (n == 40 || n == 64)) + return 1; /* v4 or v5 fingerprint. */ + + return 0; +} + + +/* This function shall be called with the main and subkey fingerprint + * iff a signature is fully valid. If the option --assert-signer is + * active it check whether the signing key matches one of the keys + * given by this option and if so, sets a global flag. */ +void +check_assert_signer_list (const char *mainpkhex, const char *pkhex) +{ + gpg_error_t err; + strlist_t item; + const char *fname; + estream_t fp = NULL; + int lnr; + int n, c; + char *p, *pend; + char line[256]; + + if (!opt.assert_signer_list) + return; /* Nothing to do. */ + if (assert_signer_true) + return; /* Already one valid signature seen. */ + + for (item = opt.assert_signer_list; item; item = item->next) + { + if (is_fingerprint (item->d)) + { + ascii_strupr (item->d); + if (!strcmp (item->d, mainpkhex) || !strcmp (item->d, pkhex)) + { + assert_signer_true = 1; + write_status_text (STATUS_ASSERT_SIGNER, item->d); + if (!opt.quiet) + log_info ("signer '%s' matched\n", item->d); + goto leave; + } + } + else /* Assume this is a file - read and compare. */ + { + fname = item->d; + es_fclose (fp); + fp = es_fopen (fname, "r"); + if (!fp) + { + err = gpg_error_from_syserror (); + log_error (_("error opening '%s': %s\n"), + fname, gpg_strerror (err)); + continue; + } + + lnr = 0; + err = 0; + while (es_fgets (line, DIM(line)-1, fp)) + { + lnr++; + + n = strlen (line); + if (!n || line[n-1] != '\n') + { + /* Eat until end of line. */ + while ( (c=es_getc (fp)) != EOF && c != '\n') + ; + err = gpg_error (GPG_ERR_INCOMPLETE_LINE); + log_error (_("file '%s', line %d: %s\n"), + fname, lnr, gpg_strerror (err)); + continue; + } + line[--n] = 0; /* Chop the LF. */ + if (n && line[n-1] == '\r') + line[--n] = 0; /* Chop an optional CR. */ + + /* Allow for empty lines and spaces */ + for (p=line; spacep (p); p++) + ; + if (!*p || *p == '#') + continue; + + /* Get the first token and ignore trailing stuff. */ + for (pend = p; *pend && !spacep (pend); pend++) + ; + *pend = 0; + ascii_strupr (p); + + if (!strcmp (p, mainpkhex) || !strcmp (p, pkhex)) + { + assert_signer_true = 1; + write_status_text (STATUS_ASSERT_SIGNER, p); + if (!opt.quiet) + log_info ("signer '%s' matched '%s', line %d\n", + p, fname, lnr); + goto leave; + } + } + if (!err && !es_feof (fp)) + { + err = gpg_error_from_syserror (); + log_error (_("error reading '%s', line %d: %s\n"), + fname, lnr, gpg_strerror (err)); + } + } + } + + leave: + es_fclose (fp); +} |