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/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/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 7aeb4da6e5..dcbffcd79b 100644 --- a/tools/rpmkeys.cc +++ b/tools/rpmkeys.cc @@ -44,18 +44,42 @@ 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; + 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; + } + + /* 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))) { 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); @@ -67,7 +91,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; } } @@ -85,6 +109,7 @@ static int matchingKeys(rpmKeyring keyring, ARGV_const_t args, void * userdata, ec = EXIT_FAILURE; } } + rpmKeyringFree(keyring); return ec; } @@ -97,13 +122,19 @@ 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; poptContext optCon = NULL; rpmts ts = NULL; ARGV_const_t args = NULL; - rpmKeyring keyring = NULL; optCon = rpmcliInit(argc, argv, optionsTable); @@ -119,7 +150,6 @@ int main(int argc, char *argv[]) ts = rpmtsCreate(); rpmtsSetRootDir(ts, rpmcliRootDir); - keyring = rpmtsGetKeyring(ts, 1); switch (mode) { case MODE_CHECKSIG: @@ -134,27 +164,14 @@ 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; } case MODE_LISTKEY: { - ec = matchingKeys(keyring, args, NULL, printKey); + ec = matchingKeys(ts, args, printKey); break; } default: @@ -162,7 +179,6 @@ int main(int argc, char *argv[]) } exit: - rpmKeyringFree(keyring); rpmtsFree(ts); rpmcliFini(optCon); fflush(stderr);