diff --git a/include/rpm/rpmkeyring.h b/include/rpm/rpmkeyring.h index 7d6cd13492..e4c7e3568a 100644 --- a/include/rpm/rpmkeyring.h +++ b/include/rpm/rpmkeyring.h @@ -47,6 +47,29 @@ rpmKeyring rpmKeyringFree(rpmKeyring keyring); */ int rpmKeyringAddKey(rpmKeyring keyring, rpmPubkey key); +/** \ingroup rpmkeyring + * Get iterator for all the primary keys in the keyring + * @param keyring keyring handle + * @param unused reserved for future use, must be 0 + * @return iterator or NULL + */ +rpmKeyringIterator rpmKeyringInitIterator(rpmKeyring keyring, int unused); + +/** \ingroup rpmkeyring + * Get next key in keyring + * @param iterator iterator handle + * @return weak reference to next public key + * or NULL if end is reached + */ +rpmPubkey rpmKeyringIteratorNext(rpmKeyringIterator iterator); + +/** \ingroup rpmkeyring + * Free iterator + * @param iterator iterator handle + * @return NULL + */ +rpmKeyringIterator rpmKeyringIteratorFree(rpmKeyringIterator iterator); + /** \ingroup rpmkeyring * Perform combined keyring lookup and signature verification * @param keyring keyring handle diff --git a/include/rpm/rpmtypes.h b/include/rpm/rpmtypes.h index b551ab5338..e5ac7a39d6 100644 --- a/include/rpm/rpmtypes.h +++ b/include/rpm/rpmtypes.h @@ -79,6 +79,7 @@ typedef void * rpmCallbackData; typedef struct rpmPubkey_s * rpmPubkey; typedef struct rpmKeyring_s * rpmKeyring; +typedef struct rpmKeyringIterator_s * rpmKeyringIterator; typedef uint32_t rpmsid; typedef struct rpmstrPool_s * rpmstrPool; diff --git a/rpmio/rpmkeyring.cc b/rpmio/rpmkeyring.cc index 0d8f922593..132974324b 100644 --- a/rpmio/rpmkeyring.cc +++ b/rpmio/rpmkeyring.cc @@ -35,6 +35,13 @@ struct rpmKeyring_s { std::shared_mutex mutex; }; +struct rpmKeyringIterator_s { + rpmKeyring keyring; + rdlock * keyringlock; + std::map::const_iterator iterator; + rpmPubkey current; +}; + static std::string key2str(const uint8_t *keyid) { return std::string(reinterpret_cast(keyid), PGP_KEYID_LEN); @@ -61,6 +68,53 @@ rpmKeyring rpmKeyringFree(rpmKeyring keyring) return NULL; } +rpmKeyringIterator rpmKeyringInitIterator(rpmKeyring keyring, int unused) +{ + if (!keyring || unused != 0) + return NULL; + + return new rpmKeyringIterator_s { + rpmKeyringLink(keyring), + new rdlock(keyring->mutex), + keyring->keys.cbegin(), + NULL, + }; +} + +rpmPubkey rpmKeyringIteratorNext(rpmKeyringIterator iterator) +{ + rpmPubkey next = NULL; + + if (!iterator) + return NULL; + + while (iterator->iterator != iterator->keyring->keys.end()) { + next = iterator->iterator->second; + iterator->iterator++; + rdlock lock(next->mutex); + if (!next->primarykey) + break; + else + next = NULL; + } + rpmPubkeyFree(iterator->current); + iterator->current = rpmPubkeyLink(next); + return iterator->current; +} + +rpmKeyringIterator rpmKeyringIteratorFree(rpmKeyringIterator iterator) +{ + if (!iterator) + return NULL; + + rpmPubkeyFree(iterator->current); + delete iterator->keyringlock; + rpmKeyringFree(iterator->keyring); + delete iterator; + return NULL; +} + + int rpmKeyringModify(rpmKeyring keyring, rpmPubkey key, rpmKeyringModifyMode mode) { int rc = 1; /* assume already seen key */