gpg: Fix get_best_pubkey_byname to consider the first match.
[gnupg.git] / common / userids.c
1 /* userids.c - Utility functions for user ids.
2  * Copyright (C) 2001, 2003, 2004, 2006,
3  *               2009 Free Software Foundation, Inc.
4  * Copyright (C) 2015  g10 Code GmbH
5  *
6  * This file is part of GnuPG.
7  *
8  * This file is free software; you can redistribute it and/or modify
9  * it under the terms of either
10  *
11  *   - the GNU Lesser General Public License as published by the Free
12  *     Software Foundation; either version 3 of the License, or (at
13  *     your option) any later version.
14  *
15  * or
16  *
17  *   - the GNU General Public License as published by the Free
18  *     Software Foundation; either version 2 of the License, or (at
19  *     your option) any later version.
20  *
21  * or both in parallel, as here.
22  *
23  * This file is distributed in the hope that it will be useful,
24  * but WITHOUT ANY WARRANTY; without even the implied warranty of
25  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
26  * GNU General Public License for more details.
27  *
28  * You should have received a copy of the GNU General Public License
29  * along with this program; if not, see <https://www.gnu.org/licenses/>.
30  */
31
32 #include <config.h>
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <string.h>
36
37 #include "util.h"
38 #include "userids.h"
39
40
41 /* Parse the user-id NAME and build a search description for it.
42  * Returns 0 on success or an error code.  DESC may be NULL to merely
43  * check the validity of a user-id.
44  *
45  * Some used rules:
46  * - If the username starts with 8,9,16 or 17 hex-digits (the first one
47  *   must be in the range 0..9), this is considered a keyid; depending
48  *   on the length a short or complete one.
49  * - If the username starts with 32,33,40 or 41 hex-digits (the first one
50  *   must be in the range 0..9), this is considered a fingerprint.
51  * - If the username starts with a left angle, we assume it is a complete
52  *   email address and look only at this part.
53  * - If the username starts with a colon we assume it is a unified
54  *   key specfification.
55  * - If the username starts with a '.', we assume it is the ending
56  *   part of an email address
57  * - If the username starts with an '@', we assume it is a part of an
58  *   email address
59  * - If the userid start with an '=' an exact compare is done.
60  * - If the userid starts with a '*' a case insensitive substring search is
61  *   done (This is the default).
62  * - If the userid starts with a '+' we will compare individual words
63  *   and a match requires that all the words are in the userid.
64  *   Words are delimited by white space or "()<>[]{}.@-+_,;/&!"
65  *   (note that you can't search for these characters). Compare
66  *   is not case sensitive.
67  * - If the userid starts with a '&' a 40 hex digits keygrip is expected.
68  * - If the userid starts with a '^' followed by 40 hex digits it describes
69  *   a Unique-Blob-ID (UBID) which is the hash of keyblob or certificate as
70  *   stored in the database.  This is used in the IPC of the keyboxd.
71  */
72
73 gpg_error_t
74 classify_user_id (const char *name, KEYDB_SEARCH_DESC *desc, int openpgp_hack)
75 {
76   const char *s;
77   char *s2 = NULL;
78   int rc = 0;
79   int hexprefix = 0;
80   int hexlength;
81   int mode = 0;
82   KEYDB_SEARCH_DESC dummy_desc;
83
84   if (!desc)
85     desc = &dummy_desc;
86
87   /* Clear the structure so that the mode field is set to zero unless
88      we set it to the correct value right at the end of this
89      function. */
90   memset (desc, 0, sizeof *desc);
91
92   /* Skip leading and trailing spaces.  */
93   for(s = name; *s && spacep (s); s++ )
94     ;
95   if (*s && spacep (s + strlen(s) - 1))
96     {
97       s2 = xtrystrdup (s);
98       if (!s2)
99         {
100           rc = gpg_error_from_syserror ();
101           goto out;
102         }
103       trim_trailing_spaces (s2);
104       s = s2;
105     }
106
107   switch (*s)
108     {
109     case 0:  /* Empty string is an error.  */
110       rc = gpg_error (GPG_ERR_INV_USER_ID);
111       goto out;
112
113     case '.': /* An email address, compare from end.  Note that this
114                  has not yet been implemented in the search code.  */
115       mode = KEYDB_SEARCH_MODE_MAILEND;
116       s++;
117       desc->u.name = s;
118       break;
119
120     case '<': /* An email address.  */
121       mode = KEYDB_SEARCH_MODE_MAIL;
122       /* FIXME: The keyring code in g10 assumes that the mail name is
123          prefixed with an '<'.  However the keybox code used for sm/
124          assumes it has been removed.  For now we use this simple hack
125          to overcome the problem.  */
126       if (!openpgp_hack)
127         s++;
128       desc->u.name = s;
129       break;
130
131     case '@':  /* Part of an email address.  */
132       mode = KEYDB_SEARCH_MODE_MAILSUB;
133       s++;
134       desc->u.name = s;
135       break;
136
137     case '=':  /* Exact compare.  */
138       mode = KEYDB_SEARCH_MODE_EXACT;
139       s++;
140       desc->u.name = s;
141       break;
142
143     case '*':  /* Case insensitive substring search.  */
144       mode = KEYDB_SEARCH_MODE_SUBSTR;
145       s++;
146       desc->u.name = s;
147       break;
148
149     case '+':  /* Compare individual words.  Note that this has not
150                   yet been implemented in the search code.  */
151       mode = KEYDB_SEARCH_MODE_WORDS;
152       s++;
153       desc->u.name = s;
154       break;
155
156     case '/': /* Subject's DN.  */
157       s++;
158       if (!*s || spacep (s)) /* No DN or prefixed with a space.  */
159         {
160           rc = gpg_error (GPG_ERR_INV_USER_ID);
161           goto out;
162         }
163       desc->u.name = s;
164       mode = KEYDB_SEARCH_MODE_SUBJECT;
165       break;
166
167     case '#': /* S/N with optional issuer id or just issuer id.  */
168       {
169         const char *si;
170
171         s++;
172         if ( *s == '/')
173           { /* "#/" indicates an issuer's DN.  */
174             s++;
175             if (!*s || spacep (s)) /* No DN or prefixed with a space.  */
176               {
177                 rc = gpg_error (GPG_ERR_INV_USER_ID);
178                 goto out;
179               }
180             desc->u.name = s;
181             mode = KEYDB_SEARCH_MODE_ISSUER;
182           }
183         else
184           { /* Serialnumber + optional issuer ID.  */
185             for (si=s; *si && *si != '/'; si++)
186               {
187                  /* Check for an invalid digit in the serial number. */
188                 if (!strchr("01234567890abcdefABCDEF", *si))
189                   {
190                     rc = gpg_error (GPG_ERR_INV_USER_ID);
191                     goto out;
192                   }
193               }
194             desc->sn = (const unsigned char*)s;
195             desc->snlen = -1;
196             if (!*si)
197               mode = KEYDB_SEARCH_MODE_SN;
198             else
199               {
200                 s = si+1;
201                 if (!*s || spacep (s))  /* No DN or prefixed with a space.  */
202                   {
203                     rc = gpg_error (GPG_ERR_INV_USER_ID);
204                     goto out;
205                   }
206                 desc->u.name = s;
207                 mode = KEYDB_SEARCH_MODE_ISSUER_SN;
208               }
209           }
210       }
211       break;
212
213     case ':': /* Unified fingerprint. */
214       {
215         const char *se, *si;
216         int i;
217
218         se = strchr (++s,':');
219         if (!se)
220           {
221             rc = gpg_error (GPG_ERR_INV_USER_ID);
222             goto out;
223           }
224         for (i=0,si=s; si < se; si++, i++ )
225           {
226             if (!strchr("01234567890abcdefABCDEF", *si))
227               {
228                 rc = gpg_error (GPG_ERR_INV_USER_ID); /* Invalid digit.  */
229                 goto out;
230               }
231           }
232         if (i != 32 && i != 40 && i != 64)
233           {
234             rc = gpg_error (GPG_ERR_INV_USER_ID); /* Invalid length of fpr.  */
235             goto out;
236           }
237         for (i=0,si=s; si < se; i++, si +=2)
238           desc->u.fpr[i] = hextobyte(si);
239         desc->fprlen = i;
240         for (; i < 32; i++)
241           desc->u.fpr[i]= 0;
242         mode = KEYDB_SEARCH_MODE_FPR;
243       }
244       break;
245
246     case '&': /* Keygrip*/
247       {
248         if (hex2bin (s+1, desc->u.grip, 20) < 0)
249           {
250             rc = gpg_error (GPG_ERR_INV_USER_ID); /* Invalid. */
251             goto out;
252           }
253         mode = KEYDB_SEARCH_MODE_KEYGRIP;
254       }
255       break;
256
257     case '^': /* UBID */
258       {
259         if (hex2bin (s+1, desc->u.ubid, 20) < 0)
260           {
261             rc = gpg_error (GPG_ERR_INV_USER_ID); /* Invalid. */
262             goto out;
263           }
264         mode = KEYDB_SEARCH_MODE_UBID;
265       }
266       break;
267
268     default:
269       if (s[0] == '0' && s[1] == 'x')
270         {
271           hexprefix = 1;
272           s += 2;
273         }
274
275       hexlength = strspn(s, "0123456789abcdefABCDEF");
276       if (hexlength >= 8 && s[hexlength] =='!')
277         {
278           desc->exact = 1;
279           hexlength++; /* Just for the following check.  */
280         }
281
282       /* Check if a hexadecimal number is terminated by EOS or blank.  */
283       if (hexlength && s[hexlength] && !spacep (s+hexlength))
284         {
285           if (hexprefix) /* A "0x" prefix without a correct
286                             termination is an error.  */
287             {
288               rc = gpg_error (GPG_ERR_INV_USER_ID);
289               goto out;
290             }
291           /* The first characters looked like a hex number, but the
292              entire string is not.  */
293           hexlength = 0;
294         }
295
296       if (desc->exact)
297         hexlength--; /* Remove the bang.  */
298
299       if ((hexlength == 8
300            && (s[hexlength] == 0
301                || (s[hexlength] == '!' && s[hexlength + 1] == 0)))
302           || (!hexprefix && hexlength == 9 && *s == '0'))
303         {
304           /* Short keyid.  */
305           if (hexlength == 9)
306             s++;
307           desc->u.kid[1] = strtoul( s, NULL, 16 );
308           mode = KEYDB_SEARCH_MODE_SHORT_KID;
309         }
310       else if ((hexlength == 16
311                 && (s[hexlength] == 0
312                     || (s[hexlength] == '!' && s[hexlength + 1] == 0)))
313                || (!hexprefix && hexlength == 17 && *s == '0'))
314         {
315           /* Long keyid.  */
316           char buf[9];
317           if (hexlength == 17)
318             s++;
319           mem2str (buf, s, 9);
320           desc->u.kid[0] = strtoul (buf, NULL, 16);
321           desc->u.kid[1] = strtoul (s+8, NULL, 16);
322           mode = KEYDB_SEARCH_MODE_LONG_KID;
323         }
324       else if ((hexlength == 32
325                 && (s[hexlength] == 0
326                     || (s[hexlength] == '!' && s[hexlength + 1] == 0)))
327                || (!hexprefix && hexlength == 33 && *s == '0'))
328         {
329           /* MD5 fingerprint.  */
330           int i;
331           if (hexlength == 33)
332             s++;
333           memset (desc->u.fpr+16, 0, 4);
334           for (i=0; i < 16; i++, s+=2)
335             {
336               int c = hextobyte(s);
337               if (c == -1)
338                 {
339                   rc = gpg_error (GPG_ERR_INV_USER_ID);
340                   goto out;
341                 }
342               desc->u.fpr[i] = c;
343             }
344           desc->fprlen = 16;
345           for (; i < 32; i++)
346             desc->u.fpr[i]= 0;
347           mode = KEYDB_SEARCH_MODE_FPR;
348         }
349       else if ((hexlength == 40
350                 && (s[hexlength] == 0
351                     || (s[hexlength] == '!' && s[hexlength + 1] == 0)))
352                || (!hexprefix && hexlength == 41 && *s == '0'))
353         {
354           /* SHA1 fingerprint.  */
355           int i;
356           if (hexlength == 41)
357             s++;
358           for (i=0; i < 20; i++, s+=2)
359             {
360               int c = hextobyte(s);
361               if (c == -1)
362                 {
363                   rc = gpg_error (GPG_ERR_INV_USER_ID);
364                   goto out;
365                 }
366               desc->u.fpr[i] = c;
367             }
368           desc->fprlen = 20;
369           for (; i < 32; i++)
370             desc->u.fpr[i]= 0;
371           mode = KEYDB_SEARCH_MODE_FPR;
372         }
373       else if ((hexlength == 64
374                 && (s[hexlength] == 0
375                     || (s[hexlength] == '!' && s[hexlength + 1] == 0)))
376                || (!hexprefix && hexlength == 65 && *s == '0'))
377         {
378           /* SHA256 fingerprint.  */
379           int i;
380           if (hexlength == 65)
381             s++;
382           for (i=0; i < 32; i++, s+=2)
383             {
384               int c = hextobyte(s);
385               if (c == -1)
386                 {
387                   rc = gpg_error (GPG_ERR_INV_USER_ID);
388                   goto out;
389                 }
390               desc->u.fpr[i] = c;
391             }
392           desc->fprlen = 32;
393           mode = KEYDB_SEARCH_MODE_FPR;
394         }
395       else if (!hexprefix)
396         {
397           /* The fingerprint of an X.509 listing is often delimited by
398            * colons, so we try to single this case out.  Note that the
399            * OpenPGP bang suffix is not supported here.  */
400           desc->exact = 0;
401           mode = 0;
402           hexlength = strspn (s, ":0123456789abcdefABCDEF");
403           if (hexlength == 59 && (!s[hexlength] || spacep (s+hexlength)))
404             {
405               int i;
406
407               for (i=0; i < 20; i++, s += 3)
408                 {
409                   int c = hextobyte(s);
410                   if (c == -1 || (i < 19 && s[2] != ':'))
411                     break;
412                   desc->u.fpr[i] = c;
413                 }
414               if (i == 20)
415                 {
416                   desc->fprlen = 20;
417                   mode = KEYDB_SEARCH_MODE_FPR;
418                 }
419               for (; i < 32; i++)
420                 desc->u.fpr[i]= 0;
421             }
422           if (!mode)
423             {
424               /* Still not found.  Now check for a space separated
425                * OpenPGP v4 fingerprint like:
426                *   8061 5870 F5BA D690 3336  86D0 F2AD 85AC 1E42 B367
427                * or
428                *   8061 5870 F5BA D690 3336 86D0 F2AD 85AC 1E42 B367
429                * FIXME: Support OpenPGP v5 fingerprint
430                */
431               hexlength = strspn (s, " 0123456789abcdefABCDEF");
432               if (s[hexlength] && s[hexlength] != ' ')
433                 hexlength = 0; /* Followed by non-space.  */
434               while (hexlength && s[hexlength-1] == ' ')
435                 hexlength--;   /* Trim trailing spaces.  */
436               if ((hexlength == 49 || hexlength == 50)
437                   && (!s[hexlength] || s[hexlength] == ' '))
438                 {
439                   int i, c;
440
441                   for (i=0; i < 20; i++)
442                     {
443                       if (i && !(i % 2))
444                         {
445                           if (*s != ' ')
446                             break;
447                           s++;
448                           /* Skip the double space in the middle but
449                              don't require it to help copying
450                              fingerprints from sources which fold
451                              multiple space to one.  */
452                           if (i == 10 && *s == ' ')
453                             s++;
454                         }
455
456                       c = hextobyte(s);
457                       if (c == -1)
458                         break;
459                       desc->u.fpr[i] = c;
460                       s += 2;
461                     }
462                   if (i == 20)
463                     {
464                       desc->fprlen = 20;
465                       mode = KEYDB_SEARCH_MODE_FPR;
466                     }
467                   for (; i < 32; i++)
468                     desc->u.fpr[i]= 0;
469                 }
470             }
471           if (!mode) /* Default to substring search.  */
472             {
473               desc->u.name = s;
474               mode = KEYDB_SEARCH_MODE_SUBSTR;
475             }
476         }
477       else
478         {
479           /* Hex number with a prefix but with a wrong length.  */
480           rc = gpg_error (GPG_ERR_INV_USER_ID);
481           goto out;
482         }
483     }
484
485   desc->mode = mode;
486  out:
487   xfree (s2);
488   return rc;
489 }