From: Panu Matilainen Date: Wed, 2 Jul 2008 10:31:12 +0000 (+0300) Subject: Some keyring improvements X-Git-Tag: rpm-4.6.0-rc1~207 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=cea83865c944d378d3aa8632c81a68c3d669b4db;p=platform%2Fupstream%2Frpm.git Some keyring improvements - keep keyring sorted by keyid, use bsearch for key lookups - check for key in keyring before adding it to avoid dupes - actually check that pubkey parameters match the signature on keyring lookup like was done in rpmtsFindPubkey() --- diff --git a/rpmio/rpmkeyring.c b/rpmio/rpmkeyring.c index d0c352d..99ac149 100644 --- a/rpmio/rpmkeyring.c +++ b/rpmio/rpmkeyring.c @@ -22,6 +22,14 @@ struct rpmKeyring_s { size_t numkeys; }; +static int keyidcmp(const void *k1, const void *k2) +{ + const struct rpmPubkey_s *key1 = *(const struct rpmPubkey_s **) k1; + const struct rpmPubkey_s *key2 = *(const struct rpmPubkey_s **) k2; + + return memcmp(key1->keyid, key2->keyid, sizeof(key1->keyid)); +} + rpmKeyring rpmKeyringNew(void) { rpmKeyring keyring = xcalloc(1, sizeof(*keyring)); @@ -42,17 +50,29 @@ rpmKeyring rpmKeyringFree(rpmKeyring keyring) return NULL; } +static rpmPubkey rpmKeyringFindKeyid(rpmKeyring keyring, rpmPubkey key) +{ + rpmPubkey *found = NULL; + found = bsearch(&key, keyring->keys, keyring->numkeys, sizeof(*keyring->keys), keyidcmp); + return found ? *found : NULL; +} + int rpmKeyringAddKey(rpmKeyring keyring, rpmPubkey key) { if (keyring == NULL || key == NULL) - return 0; + return -1; + + /* check if we already have this key */ + if (rpmKeyringFindKeyid(keyring, key)) { + return 1; + } - /* XXX TODO: check if we already have this key */ keyring->keys = xrealloc(keyring->keys, (keyring->numkeys + 1) * sizeof(rpmPubkey)); keyring->keys[keyring->numkeys] = key; keyring->numkeys++; + qsort(keyring->keys, keyring->numkeys, sizeof(*keyring->keys), keyidcmp); - return 1; + return 0; } rpmPubkey rpmPubkeyRead(const char *filename) @@ -100,21 +120,26 @@ rpmPubkey rpmPubkeyFree(rpmPubkey key) rpmRC rpmKeyringLookup(rpmKeyring keyring, pgpDig sig) { - pgpDigParams sigp = sig ? &sig->signature : NULL; rpmRC res = RPMRC_NOKEY; - - if (keyring == NULL || sig == NULL) - goto exit; - for (int i = 0; i < keyring->numkeys; i++) { - const struct rpmPubkey_s *key = keyring->keys[i]; - if (memcmp(key->keyid, sigp->signid, sizeof(key->keyid)) == 0) { - if (pgpPrtPkts(key->pkt, key->pktlen, sig, 0) == 0) { + if (keyring && sig) { + pgpDigParams sigp = &sig->signature; + pgpDigParams pubp = &sig->pubkey; + struct rpmPubkey_s needle, *key; + needle.pkt = NULL; + needle.pktlen = 0; + memcpy(needle.keyid, sigp->signid, sizeof(needle.keyid)); + + if ((key = rpmKeyringFindKeyid(keyring, &needle))) { + /* Retrieve parameters from pubkey packet(s) */ + (void) pgpPrtPkts(key->pkt, key->pktlen, sig, 0); + /* Do the parameters match the signature? */ + if (sigp->pubkey_algo == pubp->pubkey_algo && + memcmp(sigp->signid, pubp->signid, sizeof(sigp->signid)) == 0) { res = RPMRC_OK; } } } -exit: return res; }