From 7928d99073a7f38ec3f6fd8223d99f7b3dd0ae9c Mon Sep 17 00:00:00 2001 From: Florian Festi Date: Mon, 14 Oct 2024 12:12:36 +0200 Subject: [PATCH 1/4] rpmkeys: Match error message of --list to --delete Make the output consistent and use RPMLOG_ERR --- tests/rpmdb.at | 6 +++--- tools/rpmkeys.cc | 11 ++++++++++- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/tests/rpmdb.at b/tests/rpmdb.at index 424a1271bd..b689217acf 100644 --- a/tests/rpmdb.at +++ b/tests/rpmdb.at @@ -186,9 +186,9 @@ RPMTEST_CHECK([ runroot rpmkeys --list XXX ], [1], -[Key XXX not found -], -[]) +[], +[error: invalid key id: XXX +]) RPMTEST_CHECK([ runroot rpmkeys --delete 1964c5fc diff --git a/tools/rpmkeys.cc b/tools/rpmkeys.cc index 7aeb4da6e5..6bca1f122a 100644 --- a/tools/rpmkeys.cc +++ b/tools/rpmkeys.cc @@ -50,6 +50,15 @@ static int matchingKeys(rpmKeyring keyring, ARGV_const_t args, void * userdata, if (args) { for (char * const * arg = args; *arg; arg++) { int found = false; + size_t klen = strlen(*arg); + + /* Allow short keyid while we're transitioning */ + if (klen != 40 && klen != 16 && klen != 8) { + rpmlog(RPMLOG_ERR, ("invalid key id: %s\n"), *arg); + ec = EXIT_FAILURE; + continue; + } + auto iter = rpmKeyringInitIterator(keyring, 0); rpmPubkey key = NULL; while ((key = rpmKeyringIteratorNext(iter))) { @@ -67,7 +76,7 @@ static int matchingKeys(rpmKeyring keyring, ARGV_const_t args, void * userdata, if (found) { callback(key, userdata); } else { - rpmlog(RPMLOG_NOTICE, "Key %s not found\n", *arg); + rpmlog(RPMLOG_ERR, ("key not found: %s\n"), *arg); ec = EXIT_FAILURE; } } From 2da4d23bec28dd8a668e231f59e1c76ef8e28f52 Mon Sep 17 00:00:00 2001 From: Florian Festi Date: Mon, 14 Oct 2024 12:15:48 +0200 Subject: [PATCH 2/4] Make rpmkeys --list accept short key IDs Get this in sync with rpm --delete for now. --- tools/rpmkeys.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/rpmkeys.cc b/tools/rpmkeys.cc index 6bca1f122a..731d086d83 100644 --- a/tools/rpmkeys.cc +++ b/tools/rpmkeys.cc @@ -64,7 +64,8 @@ static int matchingKeys(rpmKeyring keyring, ARGV_const_t args, void * userdata, while ((key = rpmKeyringIteratorNext(iter))) { char * fp = rpmPubkeyFingerprintAsHex(key); char * keyid = rpmPubkeyKeyIDAsHex(key); - if (!strcmp(*arg, fp) || !strcmp(*arg, keyid)) { + if (!strcmp(*arg, fp) || !strcmp(*arg, keyid) || + !strcmp(*arg, keyid+8)) { found = true; } free(fp); From 52c675f099550b7bbf7089c29f3259c6d259fc61 Mon Sep 17 00:00:00 2001 From: Florian Festi Date: Mon, 14 Oct 2024 15:05:11 +0200 Subject: [PATCH 3/4] Improve matchingKeys Pass in rpmts instead of only a keyring Move userdata pointer to end of signature and make it optional Check for invalid character --- tools/rpmkeys.cc | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/tools/rpmkeys.cc b/tools/rpmkeys.cc index 731d086d83..9f59b465a7 100644 --- a/tools/rpmkeys.cc +++ b/tools/rpmkeys.cc @@ -44,9 +44,12 @@ static struct poptOption optionsTable[] = { POPT_TABLEEND }; -static int matchingKeys(rpmKeyring keyring, ARGV_const_t args, void * userdata, int callback(rpmPubkey, void*)) +static int matchingKeys(rpmts ts, ARGV_const_t args, int callback(rpmPubkey, void*), void * userdata = NULL) { int ec = EXIT_SUCCESS; + rpmKeyring keyring = rpmtsGetKeyring(ts, 1); + char * c; + if (args) { for (char * const * arg = args; *arg; arg++) { int found = false; @@ -59,6 +62,17 @@ static int matchingKeys(rpmKeyring keyring, ARGV_const_t args, void * userdata, continue; } + /* Check for valid hex chars */ + for (c=*arg; *c; c++) { + if (strchr("0123456789abcdefABCDEF", *c) == NULL) + break; + } + if (*c) { + rpmlog(RPMLOG_ERR, ("invalid key id: %s\n"), *arg); + ec = EXIT_FAILURE; + continue; + } + auto iter = rpmKeyringInitIterator(keyring, 0); rpmPubkey key = NULL; while ((key = rpmKeyringIteratorNext(iter))) { @@ -95,6 +109,7 @@ static int matchingKeys(rpmKeyring keyring, ARGV_const_t args, void * userdata, ec = EXIT_FAILURE; } } + rpmKeyringFree(keyring); return ec; } @@ -113,7 +128,6 @@ int main(int argc, char *argv[]) poptContext optCon = NULL; rpmts ts = NULL; ARGV_const_t args = NULL; - rpmKeyring keyring = NULL; optCon = rpmcliInit(argc, argv, optionsTable); @@ -129,7 +143,6 @@ int main(int argc, char *argv[]) ts = rpmtsCreate(); rpmtsSetRootDir(ts, rpmcliRootDir); - keyring = rpmtsGetKeyring(ts, 1); switch (mode) { case MODE_CHECKSIG: @@ -164,7 +177,7 @@ int main(int argc, char *argv[]) } case MODE_LISTKEY: { - ec = matchingKeys(keyring, args, NULL, printKey); + ec = matchingKeys(ts, args, printKey); break; } default: @@ -172,7 +185,6 @@ int main(int argc, char *argv[]) } exit: - rpmKeyringFree(keyring); rpmtsFree(ts); rpmcliFini(optCon); fflush(stderr); From 662c231e0fcaa5e238b8dde18903c1416964d3dc Mon Sep 17 00:00:00 2001 From: Florian Festi Date: Mon, 14 Oct 2024 12:25:24 +0200 Subject: [PATCH 4/4] Pass rpmPubkey instance to rpmtxnDeletePubkey Use the matchingKeys() in rpmkeys to acquire those rpmPubkey instances. Use EXIT_FAILURE as exit code for rpmkeys --delete instead of the count of errors. --- include/rpm/rpmts.h | 6 +++--- lib/rpmts.cc | 16 +++++----------- tests/rpmsigdig.at | 4 ++-- tools/rpmkeys.cc | 22 ++++++++-------------- 4 files changed, 18 insertions(+), 30 deletions(-) diff --git a/include/rpm/rpmts.h b/include/rpm/rpmts.h index 7c92a605b3..dc5b31c55c 100644 --- a/include/rpm/rpmts.h +++ b/include/rpm/rpmts.h @@ -14,6 +14,7 @@ #include #include #include +#include #ifdef __cplusplus extern "C" { @@ -353,13 +354,12 @@ rpmRC rpmtxnImportPubkey(rpmtxn txn, const unsigned char * pkt, size_t pktlen); /** \ingroup rpmts * Delete public key from transaction keystore. * @param txn transaction handle - * @param keyid key fingerprint or keyid (in hex) + * @param key public key * @return RPMRC_OK on success * RPMRC_NOTFOUND if key not found - * RPMRC_NOKEY on invalid keyid * RPMRC_FAIL on other failure */ -rpmRC rpmtxnDeletePubkey(rpmtxn txn, const char *keyid); +rpmRC rpmtxnDeletePubkey(rpmtxn txn, rpmPubkey key); /** \ingroup rpmts * Retrieve handle for keyring used for this transaction set diff --git a/lib/rpmts.cc b/lib/rpmts.cc index f218363e9e..2cd567642b 100644 --- a/lib/rpmts.cc +++ b/lib/rpmts.cc @@ -774,17 +774,10 @@ rpmRC rpmtxnImportPubkey(rpmtxn txn, const unsigned char * pkt, size_t pktlen) return rc; } -rpmRC rpmtxnDeletePubkey(rpmtxn txn, const char *keyid) +rpmRC rpmtxnDeletePubkey(rpmtxn txn, rpmPubkey key) { rpmRC rc = RPMRC_FAIL; - size_t klen = strlen(keyid); - - /* Allow short keyid while we're transitioning */ - if (klen != 40 && klen != 16 && klen != 8) - return RPMRC_NOKEY; - - if (!rpmIsValidHex(keyid, klen)) - return RPMRC_NOKEY; + char * keyid = rpmPubkeyKeyIDAsHex(key); if (txn) { /* force keyring load */ @@ -797,12 +790,13 @@ rpmRC rpmtxnDeletePubkey(rpmtxn txn, const char *keyid) rc = RPMRC_OK; if (!(rpmtsFlags(txn->ts) & RPMTRANS_FLAG_TEST)) { if (txn->ts->keyringtype == KEYRING_FS) - rc = rpmtsDeleteFSKey(txn, keyid); + rc = rpmtsDeleteFSKey(txn, keyid+8); else - rc = rpmtsDeleteDBKey(txn, keyid); + rc = rpmtsDeleteDBKey(txn, keyid+8); } rpmKeyringFree(keyring); } + free(keyid); return rc; } diff --git a/tests/rpmsigdig.at b/tests/rpmsigdig.at index e3209a36d0..2d75b83959 100644 --- a/tests/rpmsigdig.at +++ b/tests/rpmsigdig.at @@ -78,7 +78,7 @@ runroot rpmkeys -Kv /data/RPMS/hello-2.0-1.x86_64-signed-with-new-subkey.rpm RPMTEST_CHECK([ runroot rpmkeys --delete abcd gimmekey 1111aaaa2222bbbb ], -[3], +[1], [], [error: invalid key id: abcd error: invalid key id: gimmekey @@ -147,7 +147,7 @@ runroot rpmkeys -Kv /data/RPMS/hello-2.0-1.x86_64-signed-with-new-subkey.rpm RPMTEST_CHECK([ runroot rpmkeys --delete abcd gimmekey 1111aaaa2222bbbb ], -[3], +[1], [], [error: invalid key id: abcd error: invalid key id: gimmekey diff --git a/tools/rpmkeys.cc b/tools/rpmkeys.cc index 9f59b465a7..dcbffcd79b 100644 --- a/tools/rpmkeys.cc +++ b/tools/rpmkeys.cc @@ -122,6 +122,13 @@ static int printKey(rpmPubkey key, void * data) return 0; } +static int deleteKey(rpmPubkey key, void * data) +{ + rpmtxn txn = (rpmtxn) data; + rpmtxnDeletePubkey(txn, key); + return 0; +} + int main(int argc, char *argv[]) { int ec = EXIT_FAILURE; @@ -157,20 +164,7 @@ int main(int argc, char *argv[]) { rpmtxn txn = rpmtxnBegin(ts, RPMTXN_WRITE); if (txn) { - int nfail = 0; - for (char const * const *arg = args; *arg && **arg; arg++) { - rpmRC delrc = rpmtxnDeletePubkey(txn, *arg); - if (delrc) { - if (delrc == RPMRC_NOTFOUND) - rpmlog(RPMLOG_ERR, ("key not found: %s\n"), *arg); - else if (delrc == RPMRC_NOKEY) - rpmlog(RPMLOG_ERR, ("invalid key id: %s\n"), *arg); - else if (delrc == RPMRC_FAIL) - rpmlog(RPMLOG_ERR, ("failed to delete key: %s\n"), *arg); - nfail++; - } - } - ec = nfail; + ec = matchingKeys(ts, args, deleteKey, txn); rpmtxnEnd(txn); } break;