Skip to content

Commit

Permalink
Add rpmtxnDeletePubkey() API for deleting keys from keystore
Browse files Browse the repository at this point in the history
Make an attempt to validate keyid is a legit keyid (short or full, we'll
need both for a while) or a fingeprint. A caveat here is that our
keystores only support short keyids now.

Mapping the return codes to rpmrc this way is clunky, but at least we
can differentiate between a few failure types.

Fixes: rpm-software-management#3338, rpm-software-management#3340
  • Loading branch information
pmatilai authored and ffesti committed Oct 10, 2024
1 parent 0de0ce4 commit 9469bf8
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 2 deletions.
11 changes: 11 additions & 0 deletions include/rpm/rpmts.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
36 changes: 34 additions & 2 deletions lib/rpmts.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit 9469bf8

Please sign in to comment.