diff options
author | Neal H. Walfield <neal@pep.foundation> | 2022-09-06 12:43:08 +0200 |
---|---|---|
committer | Panu Matilainen <pmatilai@redhat.com> | 2022-09-20 15:07:44 +0300 |
commit | 3404dd64d4c67ee830cfcc13ef71b671354ce889 (patch) | |
tree | e8f8e002d86bf9d453f9c04e88ae3979ae9615b8 | |
parent | 12e0c8b2979280350c9b55c56eb5662bae04408c (diff) | |
download | rpm-3404dd64d4c67ee830cfcc13ef71b671354ce889.tar.gz |
Add pgpPubkeyFingerprint for Sequoia.
Also add a unit test to exercise pgpPubkeyFingerprint.
Backported from commit 2bc745f2fde028e09f663c7967353e8b6aacdbf1
-rw-r--r-- | rpmio/rpmpgp_sequoia.c | 3 | ||||
-rw-r--r-- | tests/Makefile.am | 3 | ||||
-rw-r--r-- | tests/rpmpgp.at | 11 | ||||
-rw-r--r-- | tests/rpmpgppubkeyfingerprint.c | 117 |
4 files changed, 133 insertions, 1 deletions
diff --git a/rpmio/rpmpgp_sequoia.c b/rpmio/rpmpgp_sequoia.c index 24a381acc..e01acd0e9 100644 --- a/rpmio/rpmpgp_sequoia.c +++ b/rpmio/rpmpgp_sequoia.c @@ -39,6 +39,9 @@ W(rpmRC, pgpVerifySignature, W(int, pgpPubkeyKeyID, (const uint8_t * pkt, size_t pktlen, pgpKeyID_t keyid), (pkt, pktlen, keyid)) +W(int, pgpPubkeyFingerprint, + (const uint8_t * pkt, size_t pktlen, uint8_t **fp, size_t *fplen), + (pkt, pktlen, fp, fplen)) W(char *, pgpArmorWrap, (int atype, const unsigned char * s, size_t ns), (atype, s, ns)) diff --git a/tests/Makefile.am b/tests/Makefile.am index 821f001f1..ca96f952e 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -14,6 +14,7 @@ AM_CPPFLAGS = -I$(top_srcdir)/include rpmpgpcheck_LDADD = ../rpmio/librpmio.la rpmpgpprtpkts_LDADD = ../rpmio/librpmio.la +rpmpgppubkeyfingerprint_LDADD = ../rpmio/librpmio.la ## testsuite components TESTSUITE_AT = rpmtests.at @@ -147,7 +148,7 @@ EXTRA_DIST += data/misc/libhello.so .PHONY: populate_testing -check_PROGRAMS = rpmpgpcheck rpmpgpprtpkts +check_PROGRAMS = rpmpgpcheck rpmpgpprtpkts rpmpgppubkeyfingerprint # testsuite voodoo AUTOTEST = $(AUTOM4TE) --language=autotest diff --git a/tests/rpmpgp.at b/tests/rpmpgp.at index 0ba35fe3f..c2d475a98 100644 --- a/tests/rpmpgp.at +++ b/tests/rpmpgp.at @@ -10,6 +10,17 @@ AT_CHECK([[ ]],0,) AT_CLEANUP +# Test pgpPubkeyFingerprint +AT_SETUP([[Running tests for computing OpenPGP fingerprints]]) +AT_KEYWORDS([[rpmkeys digest OpenPGP]]) +# Note: the internal OpenPGP parser produces a warning when fed +# bad data. Don't force Sequoia to generate the same warning. +AT_CHECK([[ +../../rpmpgppubkeyfingerprint 2>&1 | { grep -v 'warning: Unsupported version of key: '; true; } +]],0,[Exit code: 0 +]) +AT_CLEANUP + # Test pgpPrtPkts printing AT_SETUP([[Running tests for pgpPrtPkts]]) AT_KEYWORDS([[rpmkeys digest OpenPGP]]) diff --git a/tests/rpmpgppubkeyfingerprint.c b/tests/rpmpgppubkeyfingerprint.c new file mode 100644 index 000000000..11db45bfb --- /dev/null +++ b/tests/rpmpgppubkeyfingerprint.c @@ -0,0 +1,117 @@ +#include <stddef.h> +#include <limits.h> +#include <stdio.h> + +#include <rpm/rpmpgp.h> + +struct test { + char *filename; + // If NULL, then filename does not contain a valid fingerprint. + char *fingerprint; +}; + +static int test(struct test *test) +{ + // This program is run from BUILDDIR/tests/rpmtests.dir/XXX. The + // data is in BUILDDIR/tests/testing. + const char *dir = "../../testing/data/"; + + const char *filename = test->filename; + const char *fpr = test->fingerprint; + + char *path = malloc(strlen(dir) + 1 + strlen(filename) + 1); + if (!path) { + fprintf(stderr, "out of memory\n"); + return 1; + } + sprintf(path, "%s/%s", dir, filename); + + + FILE *f = fopen(path, "r"); + if (!f) { + char buffer[PATH_MAX]; + char *cwd = getcwd(buffer, sizeof(buffer)); + + fprintf(stderr, "Failed to open %s (cwd: %s)\n", + path, cwd ? : "<unknown>"); + free(path); + return 1; + } + free(path); + + const int len = 100 * 1024; + uint8_t *data = malloc(len); + if (!data) { + fprintf(stderr, "out of memory\n"); + return 1; + } + + ssize_t bytes = fread((char *)data, 1, len, f); + int err = ferror(f); + if (err) { + fprintf(stderr, "%s: Read error: %s\n", + filename, strerror(err)); + free(data); + return 1; + } + + uint8_t *fp = NULL; + size_t fplen = 0; + int rc = pgpPubkeyFingerprint(data, bytes, &fp, &fplen); + if (rc) { + if (! fpr) { + // This test expects the parser to fail. + return 0; + } + fprintf(stderr, "pgpPubkeyFingerprint failed on %s\n", filename); + return 1; + } + + // We expect success now. + char *got = rpmhex(fp, fplen); + if (! got) { + fprintf(stderr, "%s: rpmhex failed\n", filename); + return 1; + } + + if (!fpr || strcmp(got, fpr) != 0) { + fprintf(stderr, "%s:\n got '%s'\nexpected '%s'\n", + filename, got, fpr ? fpr : "<none>"); + free(got); + return 1; + } + free(got); + + return 0; +} + +int main(void) +{ + int rt; + int ec = 0; + + struct test tests[] = { + // Make sure this fails. + { "RPMS/hello-1.0-1.i386.rpm", NULL }, + // ASCII-armor + { "keys/rpm.org-rsa-2048-test.pub", + NULL }, + { "keys/CVE-2021-3521-badbind.asc", + NULL }, + // Binary. + { "keys/rpm.org-rsa-2048-test.pgp", + "771b18d3d7baa28734333c424344591e1964c5fc" }, + }; + + int i; + for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) { + rt = test(&tests[i]); + if (rt != 0) { + fprintf(stderr, "%s failed\n", tests[i].filename); + ec = 1; + } + } + + fprintf(stderr, "Exit code: %d\n", ec); + return ec; +} |