diff --git a/include/rpm/rpmts.h b/include/rpm/rpmts.h index 3092fa4016..7c92a605b3 100644 --- a/include/rpm/rpmts.h +++ b/include/rpm/rpmts.h @@ -350,6 +350,17 @@ rpmRC rpmtsImportPubkey(rpmts ts, const unsigned char * pkt, size_t pktlen); */ 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) + * @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); + /** \ingroup rpmts * Retrieve handle for keyring used for this transaction set * @param ts transaction set diff --git a/lib/rpmts.cc b/lib/rpmts.cc index d215ada40a..6ba46a7c1b 100644 --- a/lib/rpmts.cc +++ b/lib/rpmts.cc @@ -582,14 +582,14 @@ rpmRC rpmtsImportHeader(rpmtxn txn, Header h, rpmFlags flags) static rpmRC rpmtsDeleteFSKey(rpmtxn txn, const string & keyid, const string & newname = "") { rpmRC rc = RPMRC_NOTFOUND; - string keyglob = "gpg-pubkey-" + keyid + "*.key"; + string keyglob = "gpg-pubkey-" + keyid + "-*.key"; ARGV_t files = NULL; char *pkpath = rpmGenPath(rpmtsRootDir(txn->ts), "%{_keyringpath}/", keyglob.c_str()); if (rpmGlob(pkpath, NULL, &files) == 0) { char **f; for (f = files; *f; f++) { char *bf = strrchr(*f, '/'); - if (bf && strcmp(bf + 1, newname.c_str()) != 0) + if (newname.empty() || (bf && strcmp(bf + 1, newname.c_str()) != 0)) rc = unlink(*f) ? RPMRC_FAIL : RPMRC_OK; } argvFree(files); @@ -781,6 +781,38 @@ rpmRC rpmtxnImportPubkey(rpmtxn txn, const unsigned char * pkt, size_t pktlen) return rc; } +rpmRC rpmtxnDeletePubkey(rpmtxn txn, const char *keyid) +{ + 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; + + if (txn) { + /* force keyring load */ + rpmVSFlags oflags = rpmtsVSFlags(txn->ts); + rpmtsSetVSFlags(txn->ts, (oflags & ~RPMVSF_MASK_NOSIGNATURES)); + rpmKeyring keyring = rpmtsGetKeyring(txn->ts, 1); + rpmtsSetVSFlags(txn->ts, oflags); + + /* Both import and delete just return OK on test-transaction */ + rc = RPMRC_OK; + if (!(rpmtsFlags(txn->ts) & RPMTRANS_FLAG_TEST)) { + if (txn->ts->keyringtype == KEYRING_FS) + rc = rpmtsDeleteFSKey(txn, keyid); + else + rc = rpmtsDeleteDBKey(txn, keyid); + } + rpmKeyringFree(keyring); + } + return rc; +} + rpmRC rpmtsImportPubkey(const rpmts ts, const unsigned char * pkt, size_t pktlen) { rpmRC rc = RPMRC_FAIL;