summaryrefslogtreecommitdiffstats
path: root/crypt.c
diff options
context:
space:
mode:
authorEike Rathke <erack@erack.de>2015-02-11 21:38:37 +0100
committerEike Rathke <erack@erack.de>2015-02-11 21:38:37 +0100
commitccd098b83ebbb6546152d53361c99f3f778396cf (patch)
tree1a7c3f60c9401061539a850ac04597ba99bc6423 /crypt.c
parentbe71d820d27234d7badc27ae7aecfd881f2b5953 (diff)
Allow fingerprint user input for key selection. (see #3695)
Accept and check input of a fingerprint and find the matching key. Note that for both to work, match against and display of fingerprint, the pgp_list_pubring_command and pgp_list_secring_command need to contain the --with-fingerprint option, or have with-fingerprint in ~/.gnupg/gpg.conf.
Diffstat (limited to 'crypt.c')
-rw-r--r--crypt.c80
1 files changed, 80 insertions, 0 deletions
diff --git a/crypt.c b/crypt.c
index d87e424d..83471859 100644
--- a/crypt.c
+++ b/crypt.c
@@ -900,3 +900,83 @@ int mutt_signed_handler (BODY *a, STATE *s)
}
+/* Obtain pointers to fingerprint or short or long key ID, if any.
+ * See mutt_crypt.h for details.
+ */
+const char* crypt_get_fingerprint_or_id (char *p, const char **pphint,
+ const char **ppl, const char **pps)
+{
+ const char *ps, *pl, *phint;
+ char *pfcopy, *pf, *s1, *s2;
+ char c;
+ int isid;
+ size_t hexdigits;
+
+ /* User input may be partial name, fingerprint or short or long key ID,
+ * independent of OPTPGPLONGIDS.
+ * Fingerprint without spaces is 40 hex digits (SHA-1) or 32 hex digits (MD5).
+ * Strip leading "0x" for key ID detection and prepare pl and ps to indicate
+ * if an ID was found and to simplify logic in the key loop's inner
+ * condition of the caller. */
+
+ pf = mutt_skip_whitespace (p);
+ if (!mutt_strncasecmp (pf, "0x", 2))
+ pf += 2;
+
+ /* Check if a fingerprint is given, must be hex digits only, blanks
+ * separating groups of 4 hex digits are allowed. Also pre-check for ID. */
+ isid = 2; /* unknown */
+ hexdigits = 0;
+ s1 = pf;
+ do
+ {
+ c = *(s1++);
+ if (('0' <= c && c <= '9') || ('A' <= c && c <= 'F') || ('a' <= c && c <= 'f'))
+ {
+ ++hexdigits;
+ if (isid == 2)
+ isid = 1; /* it is an ID so far */
+ }
+ else if (c)
+ {
+ isid = 0; /* not an ID */
+ if (c == ' ' && ((hexdigits % 4) == 0))
+ ; /* skip blank before or after 4 hex digits */
+ else
+ break; /* any other character or position */
+ }
+ } while (c);
+
+ /* If at end of input, check for correct fingerprint length and copy if. */
+ pfcopy = (!c && ((hexdigits == 40) || (hexdigits == 32)) ? safe_strdup (pf) : NULL);
+
+ if (pfcopy)
+ {
+ /* Use pfcopy to strip all spaces from fingerprint and as hint. */
+ s1 = s2 = pfcopy;
+ do
+ {
+ *(s1++) = *(s2 = mutt_skip_whitespace (s2));
+ } while (*(s2++));
+
+ phint = pfcopy;
+ ps = pl = NULL;
+ }
+ else
+ {
+ phint = p;
+ ps = pl = NULL;
+ if (isid == 1)
+ {
+ if (mutt_strlen (pf) == 16)
+ pl = pf; /* long key ID */
+ else if (mutt_strlen (pf) == 8)
+ ps = pf; /* short key ID */
+ }
+ }
+
+ *pphint = phint;
+ *ppl = pl;
+ *pps = ps;
+ return pfcopy;
+}