return 1;
}
-char *pgp_keyid(pgp_key_t k)
+static pgp_key_t _pgp_parent(pgp_key_t k)
{
if((k->flags & KEYFLAG_SUBKEY) && k->parent && option(OPTPGPIGNORESUB))
k = k->parent;
+ return k;
+}
+
+char *pgp_long_keyid(pgp_key_t k)
+{
+ k = _pgp_parent(k);
+
+ return k->keyid;
+}
+
+char *pgp_short_keyid(pgp_key_t k)
+{
+ k = _pgp_parent(k);
+
+ return k->keyid + 8;
+}
+
+char *pgp_keyid(pgp_key_t k)
+{
+ k = _pgp_parent(k);
+
return _pgp_keyid(k);
}
pgp_uid_t *a;
short match;
size_t l;
+ const char *ps, *pl;
if ((l = mutt_strlen (p)) && p[l-1] == '!')
p[l-1] = 0;
if (!keys)
goto out;
+ /* User input may be short or long key ID, independent of OPTPGPLONGIDS.
+ * pgp_key_t->keyid should always contain a long key ID without 0x.
+ * Strip leading "0x" before loops so it doesn't have to be done over and
+ * over again, and prepare pl and ps to simplify logic in the loop's inner
+ * condition.
+ */
+ pl = (!mutt_strncasecmp (p, "0x", 2) ? p + 2 : p);
+ ps = (mutt_strlen (pl) == 16 ? pl + 8 : pl);
+
+ /* If ps != pl it means a long ID (or name of 16 characters) was given, do
+ * not attempt to match short IDs then. Also, it is unnecessary to try to
+ * match pl against long IDs if ps == pl as pl could not be a long ID. */
+
for (k = keys; k; k = kn)
{
kn = k->next;
for (a = k->address; a; a = a->next)
{
dprint (5, (debugfile, "pgp_getkeybystr: matching \"%s\" against key %s, \"%s\": ",
- p, pgp_keyid (k), NONULL (a->addr)));
- if (!*p || mutt_strcasecmp (p, pgp_keyid (k)) == 0 ||
- (!mutt_strncasecmp (p, "0x", 2) && !mutt_strcasecmp (p + 2, pgp_keyid (k))) ||
- (option (OPTPGPLONGIDS) && !mutt_strncasecmp (p, "0x", 2) &&
- !mutt_strcasecmp (p + 2, k->keyid + 8)) ||
+ p, pgp_long_keyid (k), NONULL (a->addr)));
+ if (!*p ||
+ (ps != pl && mutt_strcasecmp (pl, pgp_long_keyid (k)) == 0) ||
+ (ps == pl && mutt_strcasecmp (ps, pgp_short_keyid (k)) == 0) ||
mutt_stristr (a->addr, p))
{
dprint (5, (debugfile, "match.\n"));