aboutsummaryrefslogtreecommitdiffstats
path: root/g10/getkey.c
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2025-02-11 13:44:23 +0000
committerWerner Koch <[email protected]>2025-02-11 13:46:19 +0000
commit70049e5f16b412bcaaf97e6ea05613593c0c4247 (patch)
treedee5a422dc05e630c8042a9d7cc4bd4bdb1c0ff3 /g10/getkey.c
parentUpdate NEWS (diff)
downloadgnupg-70049e5f16b412bcaaf97e6ea05613593c0c4247.tar.gz
gnupg-70049e5f16b412bcaaf97e6ea05613593c0c4247.zip
gpg: Lookup key for merging/inserting only beu primary key.
* g10/getkey.c (get_keyblock_byfpr_fast): Add arg primary_only and implement. * g10/import.c (import_one_real): Simplify filling the fpr buffer with zeroes. (import_one_real): Find key only by primary fingerprint. -- This should have been done early: When looking up the original keyblock we want to update, we need to lookup it up only using the primary key. This avoids to find a key which has the primary key also has a subkey. GnuPG-bug-id: 7527
Diffstat (limited to 'g10/getkey.c')
-rw-r--r--g10/getkey.c23
1 files changed, 20 insertions, 3 deletions
diff --git a/g10/getkey.c b/g10/getkey.c
index a841aeec8..bee5ff356 100644
--- a/g10/getkey.c
+++ b/g10/getkey.c
@@ -1945,7 +1945,7 @@ get_pubkey_byfpr_fast (ctrl_t ctrl, PKT_public_key * pk,
gpg_error_t err;
KBNODE keyblock;
- err = get_keyblock_byfpr_fast (ctrl, &keyblock, NULL, fpr, fprlen, 0);
+ err = get_keyblock_byfpr_fast (ctrl, &keyblock, NULL, 0, fpr, fprlen, 0);
if (!err)
{
if (pk)
@@ -1962,11 +1962,14 @@ get_pubkey_byfpr_fast (ctrl_t ctrl, PKT_public_key * pk,
* R_HD may be NULL. If LOCK is set the handle has been opend in
* locked mode and keydb_disable_caching () has been called. On error
* R_KEYBLOCK is set to NULL but R_HD must be released by the caller;
- * it may have a value of NULL, though. This allows one to do an insert
- * operation on a locked keydb handle. */
+ * it may have a value of NULL, though. This allows one to do an
+ * insert operation on a locked keydb handle. If PRIMARY_ONLY is set
+ * the function returns a keyblock which has the requested fingerprint
+ * has primary key. */
gpg_error_t
get_keyblock_byfpr_fast (ctrl_t ctrl,
kbnode_t *r_keyblock, KEYDB_HANDLE *r_hd,
+ int primary_only,
const byte *fpr, size_t fprlen, int lock)
{
gpg_error_t err;
@@ -1974,6 +1977,8 @@ get_keyblock_byfpr_fast (ctrl_t ctrl,
kbnode_t keyblock;
byte fprbuf[MAX_FINGERPRINT_LEN];
int i;
+ byte tmpfpr[MAX_FINGERPRINT_LEN];
+ size_t tmpfprlen;
if (r_keyblock)
*r_keyblock = NULL;
@@ -2005,6 +2010,7 @@ get_keyblock_byfpr_fast (ctrl_t ctrl,
if (r_hd)
*r_hd = hd;
+ again:
err = keydb_search_fpr (hd, fprbuf, fprlen);
if (gpg_err_code (err) == GPG_ERR_NOT_FOUND)
{
@@ -2024,6 +2030,17 @@ get_keyblock_byfpr_fast (ctrl_t ctrl,
log_assert (keyblock->pkt->pkttype == PKT_PUBLIC_KEY
|| keyblock->pkt->pkttype == PKT_PUBLIC_SUBKEY);
+ if (primary_only)
+ {
+ fingerprint_from_pk (keyblock->pkt->pkt.public_key, tmpfpr, &tmpfprlen);
+ if (fprlen != tmpfprlen || memcmp (fpr, tmpfpr, fprlen))
+ {
+ release_kbnode (keyblock);
+ keyblock = NULL;
+ goto again;
+ }
+ }
+
/* Not caching key here since it won't have all of the fields
properly set. */