From 91c5d60408ee1d8864d8a85ef7233bf4beadb3d6 Mon Sep 17 00:00:00 2001 From: Panu Matilainen Date: Thu, 24 Oct 2024 16:29:42 +0300 Subject: [PATCH] Drill pubkeys one level deeper into the keystore APIs Pass pubkeys down to the keystore on import, and let the keystore handle the actual format. For rpmdb keystore this remains the header, so it's a no-op there, but on the fs keystore we drop the trailing "time or something" hex garbage from the filename because we no longer have it at hand but also because it's just not relevant for anything. The key load glob is relaxed enough that we still pick the old format keys too. Related: #3342 --- lib/keystore.cc | 47 ++++++++++++++++++++++++---------------------- tests/rpmsigdig.at | 6 +++--- 2 files changed, 28 insertions(+), 25 deletions(-) diff --git a/lib/keystore.cc b/lib/keystore.cc index e393341f0a..18155da72d 100644 --- a/lib/keystore.cc +++ b/lib/keystore.cc @@ -27,6 +27,8 @@ enum { KEYRING_FS = 2, }; +static int makePubkeyHeader(rpmts ts, rpmPubkey key, Header * hdrp); + static int keyringAdd(rpmKeyring keyring, rpmPubkey key, const char *name) { int nkeys = 0; @@ -84,7 +86,7 @@ static int rpmtsLoadKeyringFromFiles(rpmts ts, rpmKeyring keyring) 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(rpmtxnRootDir(txn), "%{_keyringpath}/", keyglob.c_str()); if (rpmGlob(pkpath, NULL, &files) == 0) { @@ -105,11 +107,12 @@ static rpmRC rpmtsDeleteFSKey(rpmtxn txn, rpmPubkey key) return rpmtsDeleteFSKey(txn, rpmPubkeyFingerprintAsHex(key)); } -static rpmRC rpmtsImportFSKey(rpmtxn txn, Header h, rpmFlags flags, int replace) +static rpmRC rpmtsImportFSKey(rpmtxn txn, rpmPubkey key, rpmFlags flags, int replace) { rpmRC rc = RPMRC_FAIL; - char *keyfmt = headerFormat(h, "%{nvr}.key", NULL); - char *keyval = headerGetAsString(h, RPMTAG_DESCRIPTION); + const char *fp = rpmPubkeyFingerprintAsHex(key); + char *keyfmt = rstrscat(NULL, "gpg-pubkey-", fp, ".key", NULL); + char *keyval = rpmPubkeyArmorWrap(key); char *path = rpmGenPath(rpmtxnRootDir(txn), "%{_keyringpath}/", keyfmt); char *tmppath = NULL; @@ -142,13 +145,10 @@ static rpmRC rpmtsImportFSKey(rpmtxn txn, Header h, rpmFlags flags, int replace) if (!rc && replace) { /* find and delete the old pubkey entry */ - char *keyid = headerFormat(h, "%{version}", NULL); - if (rpmtsDeleteFSKey(txn, keyid, keyfmt) == RPMRC_NOTFOUND) { + if (rpmtsDeleteFSKey(txn, fp, keyfmt) == RPMRC_NOTFOUND) { /* make sure an old, short keyid version gets removed */ - rpmtsDeleteFSKey(txn, keyid+32, keyfmt); + rpmtsDeleteFSKey(txn, fp+32, keyfmt); } - free(keyid); - } exit: @@ -226,9 +226,15 @@ static rpmRC rpmtsDeleteDBKey(rpmtxn txn, rpmPubkey key) return rpmtsDeleteDBKey(txn, rpmPubkeyFingerprintAsHex(key)); } -static rpmRC rpmtsImportDBKey(rpmtxn txn, Header h, rpmFlags flags, int replace) +static rpmRC rpmtsImportDBKey(rpmtxn txn, rpmPubkey key, rpmFlags flags, int replace) { - rpmRC rc = rpmtsImportHeader(txn, h, 0); + Header h = NULL; + rpmRC rc = RPMRC_FAIL; + + if (makePubkeyHeader(rpmtxnTs(txn), key, &h) != 0) + return rc; + + rc = rpmtsImportHeader(txn, h, 0); if (!rc && replace) { /* find and delete the old pubkey entry */ @@ -240,6 +246,7 @@ static rpmRC rpmtsImportDBKey(rpmtxn txn, Header h, rpmFlags flags, int replace) } free(keyid); } + headerFree(h); return rc; } @@ -376,6 +383,11 @@ static int makePubkeyHeader(rpmts ts, rpmPubkey key, Header * hdrp) if (h != NULL) { *hdrp = headerLink(h); rc = 0; + + /* Add install time/tid as icing on the cake */ + rpm_tid_t tid = rpmtsGetTid(ts); + headerPutUint32(h, RPMTAG_INSTALLTIME, &tid, 1); + headerPutUint32(h, RPMTAG_INSTALLTID, &tid, 1); } exit: @@ -392,25 +404,16 @@ rpmRC rpmKeystoreImportPubkey(rpmtxn txn, rpmPubkey key, int replace) { rpmRC rc = RPMRC_FAIL; rpmts ts = rpmtxnTs(txn); - Header h = NULL; - - if (makePubkeyHeader(ts, key, &h) != 0) - return rc; - - rpm_tid_t tid = rpmtsGetTid(ts); - headerPutUint32(h, RPMTAG_INSTALLTIME, &tid, 1); - headerPutUint32(h, RPMTAG_INSTALLTID, &tid, 1); /* Add header to database. */ if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_TEST)) { if (ts->keyringtype == KEYRING_FS) - rc = rpmtsImportFSKey(txn, h, 0, replace); + rc = rpmtsImportFSKey(txn, key, 0, replace); else - rc = rpmtsImportDBKey(txn, h, 0, replace); + rc = rpmtsImportDBKey(txn, key, 0, replace); } else { rc = RPMRC_OK; } - headerFree(h); return rc; } diff --git a/tests/rpmsigdig.at b/tests/rpmsigdig.at index 08da96251c..47424d0dc2 100644 --- a/tests/rpmsigdig.at +++ b/tests/rpmsigdig.at @@ -159,7 +159,7 @@ echo "%_keyring fs" >> "${RPMTEST}"/root/.rpmmacros RPMTEST_CHECK([ runroot rpmkeys --import /data/keys/rpm.org-rsa-2048-test.pub -runroot_other mv /var/lib/rpm/pubkeys/gpg-pubkey-771b18d3d7baa28734333c424344591e1964c5fc-58e63918.key /var/lib/rpm/pubkeys/gpg-pubkey-1964c5fc-58e63918.key +runroot_other mv /var/lib/rpm/pubkeys/gpg-pubkey-771b18d3d7baa28734333c424344591e1964c5fc.key /var/lib/rpm/pubkeys/gpg-pubkey-1964c5fc-58e63918.key runroot_other ls /var/lib/rpm/pubkeys/ runroot rpmkeys --list ], @@ -180,7 +180,7 @@ RPMTEST_CHECK([ runroot_other ls /var/lib/rpm/pubkeys/ ], [0], -[gpg-pubkey-771b18d3d7baa28734333c424344591e1964c5fc-58e63918.key +[gpg-pubkey-771b18d3d7baa28734333c424344591e1964c5fc.key ], []) RPMTEST_CLEANUP @@ -495,7 +495,7 @@ runroot rpmkeys \ --define "_keyringpath /tmp/kr" \ --define "_keyring fs" \ --import /data/keys/rpm.org-rsa-2048-test.pub -runroot_other cat /tmp/kr/gpg-pubkey-771b18d3d7baa28734333c424344591e1964c5fc-58e63918.key | grep -v 'Version: ' +runroot_other cat /tmp/kr/gpg-pubkey-771b18d3d7baa28734333c424344591e1964c5fc.key | grep -v 'Version: ' ], [0], [-----BEGIN PGP PUBLIC KEY BLOCK-----