core: Protect the trace macros for fun and profit.
[gpgme.git] / src / keylist.c
1 /* keylist.c - Listing keys.
2  * Copyright (C) 2000 Werner Koch (dd9jn)
3  * Copyright (C) 2001, 2002, 2003, 2004, 2006, 2007,
4  *               2008, 2009  g10 Code GmbH
5  *
6  * This file is part of GPGME.
7  *
8  * GPGME is free software; you can redistribute it and/or modify it
9  * under the terms of the GNU Lesser General Public License as
10  * published by the Free Software Foundation; either version 2.1 of
11  * the License, or (at your option) any later version.
12  *
13  * GPGME is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this program; if not, see <https://gnu.org/licenses/>.
20  * SPDX-License-Identifier: LGPL-2.1-or-later
21  */
22
23 #if HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #ifdef HAVE_SYS_TYPES_H
30   /* Solaris 8 needs sys/types.h before time.h.  */
31 # include <sys/types.h>
32 #endif
33 #include <time.h>
34 #include <assert.h>
35 #include <ctype.h>
36 #include <errno.h>
37 #include <limits.h>
38
39 /* Suppress warning for accessing deprecated member "class".  */
40 #define _GPGME_IN_GPGME
41 #include "gpgme.h"
42 #include "util.h"
43 #include "context.h"
44 #include "ops.h"
45 #include "debug.h"
46
47 \f
48 struct key_queue_item_s
49 {
50   struct key_queue_item_s *next;
51   gpgme_key_t key;
52 };
53
54 typedef struct
55 {
56   struct _gpgme_op_keylist_result result;
57
58   /* The error code from ERROR keydb_search. */
59   gpgme_error_t keydb_search_err;
60
61   gpgme_key_t tmp_key;
62
63   /* This points to the last uid in tmp_key.  */
64   gpgme_user_id_t tmp_uid;
65
66   /* This points to the last sig in tmp_uid.  */
67   gpgme_key_sig_t tmp_keysig;
68
69   /* Something new is available.  */
70   int key_cond;
71   struct key_queue_item_s *key_queue;
72 } *op_data_t;
73
74
75 static void
76 release_op_data (void *hook)
77 {
78   op_data_t opd = (op_data_t) hook;
79   struct key_queue_item_s *key = opd->key_queue;
80
81   if (opd->tmp_key)
82     gpgme_key_unref (opd->tmp_key);
83
84   /* opd->tmp_uid and opd->tmp_keysig are actually part of opd->tmp_key,
85      so we do not need to release them here.  */
86
87   while (key)
88     {
89       struct key_queue_item_s *next = key->next;
90
91       gpgme_key_unref (key->key);
92       key = next;
93     }
94 }
95
96
97 gpgme_keylist_result_t
98 gpgme_op_keylist_result (gpgme_ctx_t ctx)
99 {
100   void *hook;
101   op_data_t opd;
102   gpgme_error_t err;
103
104   TRACE_BEG (DEBUG_CTX, "gpgme_op_keylist_result", ctx, "");
105
106   err = _gpgme_op_data_lookup (ctx, OPDATA_KEYLIST, &hook, -1, NULL);
107   opd = hook;
108   if (err || !opd)
109     {
110       TRACE_SUC ("result=(null)");
111       return NULL;
112     }
113
114   TRACE_LOG  ("truncated = %i", opd->result.truncated);
115
116   TRACE_SUC ("result=%p", &opd->result);
117   return &opd->result;
118 }
119
120 \f
121 static gpgme_error_t
122 keylist_status_handler (void *priv, gpgme_status_code_t code, char *args)
123 {
124   gpgme_ctx_t ctx = (gpgme_ctx_t) priv;
125   gpgme_error_t err;
126   void *hook;
127   op_data_t opd;
128
129   (void)args;
130
131   err = _gpgme_op_data_lookup (ctx, OPDATA_KEYLIST, &hook, -1, NULL);
132   opd = hook;
133   if (err)
134     return err;
135
136   switch (code)
137     {
138     case GPGME_STATUS_TRUNCATED:
139       opd->result.truncated = 1;
140       break;
141
142     case GPGME_STATUS_ERROR:
143       err = _gpgme_parse_failure (args);
144       if (!opd->keydb_search_err && !strcmp (args, "keydb_search"))
145         opd->keydb_search_err = err;
146       err = 0;
147       break;
148
149     default:
150       break;
151     }
152   return err;
153 }
154
155 \f
156 static void
157 set_subkey_trust_info (gpgme_subkey_t subkey, const char *src)
158 {
159   while (*src && !isdigit (*src))
160     {
161       switch (*src)
162         {
163         case 'e':
164           subkey->expired = 1;
165           break;
166
167         case 'r':
168           subkey->revoked = 1;
169           break;
170
171         case 'd':
172           /* Note that gpg 1.3 won't print that anymore but only uses
173              the capabilities field. */
174           subkey->disabled = 1;
175           break;
176
177         case 'i':
178           subkey->invalid = 1;
179           break;
180         }
181       src++;
182     }
183 }
184
185
186 static void
187 set_mainkey_trust_info (gpgme_key_t key, const char *src)
188 {
189   /* First set the trust info of the main key (the first subkey).  */
190   set_subkey_trust_info (key->subkeys, src);
191
192   /* Now set the summarized trust info.  */
193   while (*src && !isdigit (*src))
194     {
195       switch (*src)
196         {
197         case 'e':
198           key->expired = 1;
199           break;
200
201         case 'r':
202           key->revoked = 1;
203           break;
204
205         case 'd':
206           /* Note that gpg 1.3 won't print that anymore but only uses
207              the capabilities field.  However, it is still used for
208              external key listings.  */
209           key->disabled = 1;
210           break;
211
212         case 'i':
213           key->invalid = 1;
214           break;
215         }
216       src++;
217     }
218 }
219
220
221 static void
222 set_userid_flags (gpgme_key_t key, const char *src)
223 {
224   gpgme_user_id_t uid = key->_last_uid;
225
226   assert (uid);
227   /* Look at letters and stop at the first digit.  */
228   while (*src && !isdigit (*src))
229     {
230       switch (*src)
231         {
232         case 'r':
233           uid->revoked = 1;
234           break;
235
236         case 'i':
237           uid->invalid = 1;
238           break;
239
240         case 'n':
241           uid->validity = GPGME_VALIDITY_NEVER;
242           break;
243
244         case 'm':
245           uid->validity = GPGME_VALIDITY_MARGINAL;
246           break;
247
248         case 'f':
249           uid->validity = GPGME_VALIDITY_FULL;
250           break;
251
252         case 'u':
253           uid->validity = GPGME_VALIDITY_ULTIMATE;
254           break;
255         }
256       src++;
257     }
258 }
259
260
261 static void
262 set_subkey_capability (gpgme_subkey_t subkey, const char *src)
263 {
264   while (*src)
265     {
266       switch (*src)
267         {
268         case 'e':
269           subkey->can_encrypt = 1;
270           break;
271
272         case 's':
273           subkey->can_sign = 1;
274           break;
275
276         case 'c':
277           subkey->can_certify = 1;
278           break;
279
280         case 'a':
281           subkey->can_authenticate = 1;
282           break;
283
284         case 'q':
285           subkey->is_qualified = 1;
286           break;
287
288         case 'd':
289           subkey->disabled = 1;
290           break;
291         }
292       src++;
293     }
294 }
295
296
297 static void
298 set_mainkey_capability (gpgme_key_t key, const char *src)
299 {
300   /* First set the capabilities of the main key (the first subkey).  */
301   set_subkey_capability (key->subkeys, src);
302
303   while (*src)
304     {
305       switch (*src)
306         {
307         case 'd':
308         case 'D':
309           /* Note, that this flag is also set using the key validity
310              field for backward compatibility with gpg 1.2.  We use d
311              and D, so that a future gpg version will be able to
312              disable certain subkeys. Currently it is expected that
313              gpg sets this for the primary key. */
314           key->disabled = 1;
315           break;
316
317         case 'e':
318         case 'E':
319           key->can_encrypt = 1;
320           break;
321
322         case 's':
323         case 'S':
324           key->can_sign = 1;
325           break;
326
327         case 'c':
328         case 'C':
329           key->can_certify = 1;
330           break;
331
332         case 'a':
333         case 'A':
334           key->can_authenticate = 1;
335           break;
336
337         case 'q':
338         case 'Q':
339           key->is_qualified = 1;
340           break;
341         }
342       src++;
343     }
344 }
345
346
347 static void
348 set_ownertrust (gpgme_key_t key, const char *src)
349 {
350   /* Look at letters and stop at the first digit.  */
351   while (*src && !isdigit (*src))
352     {
353       switch (*src)
354         {
355         case 'n':
356           key->owner_trust = GPGME_VALIDITY_NEVER;
357           break;
358
359         case 'm':
360           key->owner_trust = GPGME_VALIDITY_MARGINAL;
361           break;
362
363         case 'f':
364           key->owner_trust = GPGME_VALIDITY_FULL;
365           break;
366
367         case 'u':
368           key->owner_trust = GPGME_VALIDITY_ULTIMATE;
369           break;
370
371         default:
372           key->owner_trust = GPGME_VALIDITY_UNKNOWN;
373           break;
374         }
375       src++;
376     }
377 }
378
379
380 static gpgme_keyorg_t
381 parse_keyorg (const char *string)
382 {
383   switch (atoi (string))
384     {
385     case 0: return GPGME_KEYORG_UNKNOWN;
386     case 1:
387     case 2:
388       return GPGME_KEYORG_KS;
389     case 3: return GPGME_KEYORG_DANE;
390     case 4: return GPGME_KEYORG_WKD;
391     case 5: return GPGME_KEYORG_URL;
392     case 6: return GPGME_KEYORG_FILE;
393     case 7: return GPGME_KEYORG_SELF;
394     default: return GPGME_KEYORG_OTHER;
395     }
396 }
397
398
399 /* Parse field 15 of a secret key or subkey.  This fields holds a
400    reference to smartcards.  FIELD is the content of the field and we
401    are allowed to modify it.  */
402 static gpg_error_t
403 parse_sec_field15 (gpgme_key_t key, gpgme_subkey_t subkey, char *field)
404 {
405   if (!*field)
406     ; /* Empty.  */
407   else if (*field == '#')
408     {
409       /* This is a stub for an offline key.  We reset the SECRET flag
410          of the subkey here.  Note that the secret flag of the entire
411          key will be true even then.  We even explicitly set
412          key->secret to make it works for GPGME_KEYLIST_MODE_WITH_SECRET. */
413       subkey->secret = 0;
414       key->secret = 1;
415     }
416   else if (strchr ("01234567890ABCDEFabcdef", *field))
417     {
418       /* Fields starts with a hex digit; thus it is a serial number.  */
419       key->secret = 1;
420       subkey->is_cardkey = 1;
421       subkey->card_number = strdup (field);
422       if (!subkey->card_number)
423         return gpg_error_from_syserror ();
424     }
425   else if (*field == '+')
426     {
427       key->secret = 1;
428       subkey->secret = 1;
429     }
430   else
431     {
432       /* RFU.  */
433     }
434
435   return 0;
436 }
437
438
439 /* Parse a tfs record.  */
440 static gpg_error_t
441 parse_tfs_record (gpgme_user_id_t uid, char **field, int nfield)
442 {
443   gpg_error_t err;
444   gpgme_tofu_info_t ti;
445   unsigned long uval;
446
447   /* We add only the first TOFU record in case future versions emit
448    * several.  */
449   if (uid->tofu)
450     return 0;
451
452   /* Check that we have enough fields and that the version is supported.  */
453   if (nfield < 8 || atoi(field[1]) != 1)
454     return trace_gpg_error (GPG_ERR_INV_ENGINE);
455
456   ti = calloc (1, sizeof *ti);
457   if (!ti)
458     return gpg_error_from_syserror ();
459
460   /* Note that we allow a value of up to 7 which is what we can store
461    * in the ti->validity.  */
462   err = _gpgme_strtoul_field (field[2], &uval);
463   if (err || uval > 7)
464     goto inv_engine;
465   ti->validity = uval;
466
467   /* Parse the sign-count.  */
468   err = _gpgme_strtoul_field (field[3], &uval);
469   if (err)
470     goto inv_engine;
471   if (uval > USHRT_MAX)
472     uval = USHRT_MAX;
473   ti->signcount = uval;
474
475   /* Parse the encr-count.  */
476   err = _gpgme_strtoul_field (field[4], &uval);
477   if (err)
478     goto inv_engine;
479   if (uval > USHRT_MAX)
480     uval = USHRT_MAX;
481   ti->encrcount = uval;
482
483   /* Parse the policy.  */
484   if (!strcmp (field[5], "none"))
485     ti->policy = GPGME_TOFU_POLICY_NONE;
486   else if (!strcmp (field[5], "auto"))
487     ti->policy = GPGME_TOFU_POLICY_AUTO;
488   else if (!strcmp (field[5], "good"))
489     ti->policy = GPGME_TOFU_POLICY_GOOD;
490   else if (!strcmp (field[5], "bad"))
491     ti->policy = GPGME_TOFU_POLICY_BAD;
492   else if (!strcmp (field[5], "ask"))
493     ti->policy = GPGME_TOFU_POLICY_ASK;
494   else /* "unknown" and invalid policy strings.  */
495     ti->policy = GPGME_TOFU_POLICY_UNKNOWN;
496
497   /* Parse first and last seen timestamps.  */
498   err = _gpgme_strtoul_field (field[6], &uval);
499   if (err)
500     goto inv_engine;
501   ti->signfirst = uval;
502   err = _gpgme_strtoul_field (field[7], &uval);
503   if (err)
504     goto inv_engine;
505   ti->signlast = uval;
506
507   if (nfield > 9)
508     {
509       /* This condition is only to allow for gpg 2.1.15 - can
510        * eventually be removed.  */
511       err = _gpgme_strtoul_field (field[8], &uval);
512       if (err)
513         goto inv_engine;
514       ti->encrfirst = uval;
515       err = _gpgme_strtoul_field (field[9], &uval);
516       if (err)
517         goto inv_engine;
518       ti->encrlast = uval;
519     }
520
521   /* Ready.  */
522   uid->tofu = ti;
523   return 0;
524
525  inv_engine:
526   free (ti);
527   return trace_gpg_error (GPG_ERR_INV_ENGINE);
528 }
529
530
531 /* We have read an entire key into tmp_key and should now finish it.
532    It is assumed that this releases tmp_key.  */
533 static void
534 finish_key (gpgme_ctx_t ctx, op_data_t opd)
535 {
536   gpgme_key_t key = opd->tmp_key;
537
538   opd->tmp_key = NULL;
539   opd->tmp_uid = NULL;
540   opd->tmp_keysig = NULL;
541
542   if (key)
543     _gpgme_engine_io_event (ctx->engine, GPGME_EVENT_NEXT_KEY, key);
544 }
545
546
547 /* Note: We are allowed to modify LINE.  */
548 static gpgme_error_t
549 keylist_colon_handler (void *priv, char *line)
550 {
551   gpgme_ctx_t ctx = (gpgme_ctx_t) priv;
552   enum
553     {
554       RT_NONE, RT_SIG, RT_UID, RT_TFS, RT_SUB, RT_PUB, RT_FPR, RT_GRP,
555       RT_SSB, RT_SEC, RT_CRT, RT_CRS, RT_REV, RT_SPK
556     }
557   rectype = RT_NONE;
558 #define NR_FIELDS 20
559   char *field[NR_FIELDS];
560   int fields = 0;
561   void *hook;
562   op_data_t opd;
563   gpgme_error_t err;
564   gpgme_key_t key;
565   gpgme_subkey_t subkey = NULL;
566   gpgme_key_sig_t keysig = NULL;
567
568   err = _gpgme_op_data_lookup (ctx, OPDATA_KEYLIST, &hook, -1, NULL);
569   opd = hook;
570   if (err)
571     return err;
572
573   key = opd->tmp_key;
574
575   TRACE (DEBUG_CTX, "gpgme:keylist_colon_handler", ctx,
576           "key = %p, line = %s", key, line ? line : "(null)");
577
578   if (!line)
579     {
580       /* End Of File.  */
581       finish_key (ctx, opd);
582       return 0;
583     }
584
585   while (line && fields < NR_FIELDS)
586     {
587       field[fields++] = line;
588       line = strchr (line, ':');
589       if (line)
590         *(line++) = '\0';
591     }
592
593   if (!strcmp (field[0], "sig"))
594     rectype = RT_SIG;
595   else if (!strcmp (field[0], "rev"))
596     rectype = RT_REV;
597   else if (!strcmp (field[0], "pub"))
598     rectype = RT_PUB;
599   else if (!strcmp (field[0], "sec"))
600     rectype = RT_SEC;
601   else if (!strcmp (field[0], "crt"))
602     rectype = RT_CRT;
603   else if (!strcmp (field[0], "crs"))
604     rectype = RT_CRS;
605   else if (!strcmp (field[0], "fpr") && key)
606     rectype = RT_FPR;
607   else if (!strcmp (field[0], "grp") && key)
608     rectype = RT_GRP;
609   else if (!strcmp (field[0], "uid") && key)
610     rectype = RT_UID;
611   else if (!strcmp (field[0], "tfs") && key)
612     rectype = RT_TFS;
613   else if (!strcmp (field[0], "sub") && key)
614     rectype = RT_SUB;
615   else if (!strcmp (field[0], "ssb") && key)
616     rectype = RT_SSB;
617   else if (!strcmp (field[0], "spk") && key)
618     rectype = RT_SPK;
619   else
620     rectype = RT_NONE;
621
622   /* Only look at signature and trust info records immediately
623      following a user ID.  For this, clear the user ID pointer when
624      encountering anything but a signature or trust record.  */
625   if (rectype != RT_SIG && rectype != RT_REV && rectype != RT_TFS)
626     opd->tmp_uid = NULL;
627
628   /* Only look at subpackets immediately following a signature.  For
629      this, clear the signature pointer when encountering anything but
630      a subpacket.  */
631   if (rectype != RT_SPK)
632     opd->tmp_keysig = NULL;
633
634   switch (rectype)
635     {
636     case RT_PUB:
637     case RT_SEC:
638     case RT_CRT:
639     case RT_CRS:
640       /* Start a new keyblock.  */
641       err = _gpgme_key_new (&key);
642       if (err)
643         return err;
644       key->keylist_mode = ctx->keylist_mode;
645       err = _gpgme_key_add_subkey (key, &subkey);
646       if (err)
647         {
648           gpgme_key_unref (key);
649           return err;
650         }
651
652       if (rectype == RT_SEC || rectype == RT_CRS)
653         key->secret = subkey->secret = 1;
654       if (rectype == RT_CRT || rectype == RT_CRS)
655         key->protocol = GPGME_PROTOCOL_CMS;
656       finish_key (ctx, opd);
657       opd->tmp_key = key;
658
659       /* Field 2 has the trust info.  */
660       if (fields >= 2)
661         set_mainkey_trust_info (key, field[1]);
662
663       /* Field 3 has the key length.  */
664       if (fields >= 3)
665         {
666           int i = atoi (field[2]);
667           /* Ignore invalid values.  */
668           if (i > 1)
669             subkey->length = i;
670         }
671
672       /* Field 4 has the public key algorithm.  */
673       if (fields >= 4)
674         {
675           int i = atoi (field[3]);
676           if (i >= 1 && i < 128)
677             subkey->pubkey_algo = _gpgme_map_pk_algo (i, ctx->protocol);
678         }
679
680       /* Field 5 has the long keyid.  Allow short key IDs for the
681          output of an external keyserver listing.  */
682       if (fields >= 5 && strlen (field[4]) <= DIM(subkey->_keyid) - 1)
683         strcpy (subkey->_keyid, field[4]);
684
685       /* Field 6 has the timestamp (seconds).  */
686       if (fields >= 6)
687         subkey->timestamp = _gpgme_parse_timestamp (field[5], NULL);
688
689       /* Field 7 has the expiration time (seconds).  */
690       if (fields >= 7)
691         subkey->expires = _gpgme_parse_timestamp (field[6], NULL);
692
693       /* Field 8 has the X.509 serial number.  */
694       if (fields >= 8 && (rectype == RT_CRT || rectype == RT_CRS))
695         {
696           key->issuer_serial = strdup (field[7]);
697           if (!key->issuer_serial)
698             return gpg_error_from_syserror ();
699         }
700
701       /* Field 9 has the ownertrust.  */
702       if (fields >= 9)
703         set_ownertrust (key, field[8]);
704
705       /* Field 10 is not used for gpg due to --fixed-list-mode option
706          but GPGSM stores the issuer name.  */
707       if (fields >= 10 && (rectype == RT_CRT || rectype == RT_CRS))
708         if (_gpgme_decode_c_string (field[9], &key->issuer_name, 0))
709           return gpg_error (GPG_ERR_ENOMEM);    /* FIXME */
710
711       /* Field 11 has the signature class.  */
712
713       /* Field 12 has the capabilities.  */
714       if (fields >= 12)
715         set_mainkey_capability (key, field[11]);
716
717       /* Field 15 carries special flags of a secret key.  */
718       if (fields >= 15
719           && (key->secret
720               || (ctx->keylist_mode & GPGME_KEYLIST_MODE_WITH_SECRET)))
721         {
722           err = parse_sec_field15 (key, subkey, field[14]);
723           if (err)
724             return err;
725         }
726
727       /* Field 17 has the curve name for ECC.  */
728       if (fields >= 17 && *field[16])
729         {
730           subkey->curve = strdup (field[16]);
731           if (!subkey->curve)
732             return gpg_error_from_syserror ();
733         }
734
735       /* Field 18 has the compliance flags.  */
736       if (fields >= 17 && *field[17])
737         PARSE_COMPLIANCE_FLAGS (field[17], subkey);
738
739       if (fields >= 20)
740         {
741           key->last_update = _gpgme_parse_timestamp_ul (field[18]);
742           key->origin = parse_keyorg (field[19]);
743         }
744
745       break;
746
747     case RT_SUB:
748     case RT_SSB:
749       /* Start a new subkey.  */
750       err = _gpgme_key_add_subkey (key, &subkey);
751       if (err)
752         return err;
753
754       if (rectype == RT_SSB)
755         subkey->secret = 1;
756
757       /* Field 2 has the trust info.  */
758       if (fields >= 2)
759         set_subkey_trust_info (subkey, field[1]);
760
761       /* Field 3 has the key length.  */
762       if (fields >= 3)
763         {
764           int i = atoi (field[2]);
765           /* Ignore invalid values.  */
766           if (i > 1)
767             subkey->length = i;
768         }
769
770       /* Field 4 has the public key algorithm.  */
771       if (fields >= 4)
772         {
773           int i = atoi (field[3]);
774           if (i >= 1 && i < 128)
775             subkey->pubkey_algo = _gpgme_map_pk_algo (i, ctx->protocol);
776         }
777
778       /* Field 5 has the long keyid.  */
779       if (fields >= 5 && strlen (field[4]) == DIM(subkey->_keyid) - 1)
780         strcpy (subkey->_keyid, field[4]);
781
782       /* Field 6 has the timestamp (seconds).  */
783       if (fields >= 6)
784         subkey->timestamp = _gpgme_parse_timestamp (field[5], NULL);
785
786       /* Field 7 has the expiration time (seconds).  */
787       if (fields >= 7)
788         subkey->expires = _gpgme_parse_timestamp (field[6], NULL);
789
790       /* Field 8 is reserved (LID).  */
791       /* Field 9 has the ownertrust.  */
792       /* Field 10, the user ID, is n/a for a subkey.  */
793
794       /* Field 11 has the signature class.  */
795
796       /* Field 12 has the capabilities.  */
797       if (fields >= 12)
798         set_subkey_capability (subkey, field[11]);
799
800       /* Field 15 carries special flags of a secret key. */
801       if (fields >= 15
802           && (key->secret
803               || (ctx->keylist_mode & GPGME_KEYLIST_MODE_WITH_SECRET)))
804         {
805           err = parse_sec_field15 (key, subkey, field[14]);
806           if (err)
807             return err;
808         }
809
810       /* Field 17 has the curve name for ECC.  */
811       if (fields >= 17 && *field[16])
812         {
813           subkey->curve = strdup (field[16]);
814           if (!subkey->curve)
815             return gpg_error_from_syserror ();
816         }
817
818       /* Field 18 has the compliance flags.  */
819       if (fields >= 17 && *field[17])
820         PARSE_COMPLIANCE_FLAGS (field[17], subkey);
821
822       break;
823
824     case RT_UID:
825       /* Field 2 has the trust info, and field 10 has the user ID.  */
826       if (fields >= 10)
827         {
828           if (_gpgme_key_append_name (key, field[9], 1))
829             return gpg_error (GPG_ERR_ENOMEM);  /* FIXME */
830
831           if (field[1])
832             set_userid_flags (key, field[1]);
833           opd->tmp_uid = key->_last_uid;
834           if (fields >= 20)
835             {
836               opd->tmp_uid->last_update = _gpgme_parse_timestamp_ul (field[18]);
837               opd->tmp_uid->origin = parse_keyorg (field[19]);
838             }
839         }
840       break;
841
842     case RT_TFS:
843       if (opd->tmp_uid)
844         {
845           err = parse_tfs_record (opd->tmp_uid, field, fields);
846           if (err)
847             return err;
848         }
849       break;
850
851     case RT_FPR:
852       /* Field 10 has the fingerprint (take only the first one).  */
853       if (fields >= 10 && field[9] && *field[9])
854         {
855           /* Need to apply it to the last subkey because all subkeys
856              do have fingerprints. */
857           subkey = key->_last_subkey;
858           if (!subkey->fpr)
859             {
860               subkey->fpr = strdup (field[9]);
861               if (!subkey->fpr)
862                 return gpg_error_from_syserror ();
863             }
864           /* If this is the first subkey, store the fingerprint also
865              in the KEY object.  */
866           if (subkey == key->subkeys)
867             {
868               if (key->fpr && strcmp (key->fpr, subkey->fpr))
869                 {
870                   /* FPR already set but mismatch: Should never happen.  */
871                   return trace_gpg_error (GPG_ERR_INTERNAL);
872                 }
873               if (!key->fpr)
874                 {
875                   key->fpr = strdup (subkey->fpr);
876                   if (!key->fpr)
877                     return gpg_error_from_syserror ();
878                 }
879             }
880         }
881
882       /* Field 13 has the gpgsm chain ID (take only the first one).  */
883       if (fields >= 13 && !key->chain_id && *field[12])
884         {
885           key->chain_id = strdup (field[12]);
886           if (!key->chain_id)
887             return gpg_error_from_syserror ();
888         }
889       break;
890
891     case RT_GRP:
892       /* Field 10 has the keygrip.  */
893       if (fields >= 10 && field[9] && *field[9])
894         {
895           /* Need to apply it to the last subkey because all subkeys
896              have a keygrip. */
897           subkey = key->_last_subkey;
898           if (!subkey->keygrip)
899             {
900               subkey->keygrip = strdup (field[9]);
901               if (!subkey->keygrip)
902                 return gpg_error_from_syserror ();
903             }
904         }
905       break;
906
907     case RT_SIG:
908     case RT_REV:
909       if (!opd->tmp_uid)
910         return 0;
911
912       /* Start a new (revoked) signature.  */
913       assert (opd->tmp_uid == key->_last_uid);
914       keysig = _gpgme_key_add_sig (key, (fields >= 10) ? field[9] : NULL);
915       if (!keysig)
916         return gpg_error (GPG_ERR_ENOMEM);      /* FIXME */
917
918       /* Field 2 has the calculated trust ('!', '-', '?', '%').  */
919       if (fields >= 2)
920         switch (field[1][0])
921           {
922           case '!':
923             keysig->status = gpg_error (GPG_ERR_NO_ERROR);
924             break;
925
926           case '-':
927             keysig->status = gpg_error (GPG_ERR_BAD_SIGNATURE);
928             break;
929
930           case '?':
931             keysig->status = gpg_error (GPG_ERR_NO_PUBKEY);
932             break;
933
934           case '%':
935             keysig->status = gpg_error (GPG_ERR_GENERAL);
936             break;
937
938           default:
939             keysig->status = gpg_error (GPG_ERR_NO_ERROR);
940             break;
941           }
942
943       /* Field 4 has the public key algorithm.  */
944       if (fields >= 4)
945         {
946           int i = atoi (field[3]);
947           if (i >= 1 && i < 128)
948             keysig->pubkey_algo = _gpgme_map_pk_algo (i, ctx->protocol);
949         }
950
951       /* Field 5 has the long keyid.  */
952       if (fields >= 5 && strlen (field[4]) == DIM(keysig->_keyid) - 1)
953         strcpy (keysig->_keyid, field[4]);
954
955       /* Field 6 has the timestamp (seconds).  */
956       if (fields >= 6)
957         keysig->timestamp = _gpgme_parse_timestamp (field[5], NULL);
958
959       /* Field 7 has the expiration time (seconds).  */
960       if (fields >= 7)
961         keysig->expires = _gpgme_parse_timestamp (field[6], NULL);
962
963       /* Field 11 has the signature class (eg, 0x30 means revoked).  */
964       if (fields >= 11)
965         if (field[10][0] && field[10][1])
966           {
967             int sig_class = _gpgme_hextobyte (field[10]);
968             if (sig_class >= 0)
969               {
970                 keysig->sig_class = sig_class;
971                 keysig->class = keysig->sig_class;
972                 if (sig_class == 0x30)
973                   keysig->revoked = 1;
974               }
975             if (field[10][2] == 'x')
976               keysig->exportable = 1;
977           }
978
979       opd->tmp_keysig = keysig;
980       break;
981
982     case RT_SPK:
983       if (!opd->tmp_keysig)
984         return 0;
985       assert (opd->tmp_keysig == key->_last_uid->_last_keysig);
986
987       if (fields >= 4)
988         {
989           /* Field 2 has the subpacket type.  */
990           int type = atoi (field[1]);
991
992           /* Field 3 has the flags.  */
993           int flags = atoi (field[2]);
994
995           /* Field 4 has the length.  */
996           int len = atoi (field[3]);
997
998           /* Field 5 has the data.  */
999           char *data = field[4];
1000
1001           /* Type 20: Notation data.  */
1002           /* Type 26: Policy URL.  */
1003           if (type == 20 || type == 26)
1004             {
1005               gpgme_sig_notation_t notation;
1006
1007               keysig = opd->tmp_keysig;
1008
1009               /* At this time, any error is serious.  */
1010               err = _gpgme_parse_notation (&notation, type, flags, len, data);
1011               if (err)
1012                 return err;
1013
1014               /* Add a new notation.  FIXME: Could be factored out.  */
1015               if (!keysig->notations)
1016                 keysig->notations = notation;
1017               if (keysig->_last_notation)
1018                 keysig->_last_notation->next = notation;
1019               keysig->_last_notation = notation;
1020             }
1021         }
1022
1023     case RT_NONE:
1024       /* Unknown record.  */
1025       break;
1026     }
1027   return 0;
1028 }
1029
1030
1031 void
1032 _gpgme_op_keylist_event_cb (void *data, gpgme_event_io_t type, void *type_data)
1033 {
1034   gpgme_error_t err;
1035   gpgme_ctx_t ctx = (gpgme_ctx_t) data;
1036   gpgme_key_t key = (gpgme_key_t) type_data;
1037   void *hook;
1038   op_data_t opd;
1039   struct key_queue_item_s *q, *q2;
1040
1041   assert (type == GPGME_EVENT_NEXT_KEY);
1042
1043   err = _gpgme_op_data_lookup (ctx, OPDATA_KEYLIST, &hook, -1, NULL);
1044   opd = hook;
1045   if (err)
1046     return;
1047
1048   q = malloc (sizeof *q);
1049   if (!q)
1050     {
1051       gpgme_key_unref (key);
1052       /* FIXME       return GPGME_Out_Of_Core; */
1053       return;
1054     }
1055   q->key = key;
1056   q->next = NULL;
1057   /* FIXME: Use a tail pointer?  */
1058   if (!(q2 = opd->key_queue))
1059     opd->key_queue = q;
1060   else
1061     {
1062       for (; q2->next; q2 = q2->next)
1063         ;
1064       q2->next = q;
1065     }
1066   opd->key_cond = 1;
1067 }
1068
1069
1070 /* Start a keylist operation within CTX, searching for keys which
1071    match PATTERN.  If SECRET_ONLY is true, only secret keys are
1072    returned.  */
1073 gpgme_error_t
1074 gpgme_op_keylist_start (gpgme_ctx_t ctx, const char *pattern, int secret_only)
1075 {
1076   gpgme_error_t err;
1077   void *hook;
1078   op_data_t opd;
1079   int flags = 0;
1080
1081   TRACE_BEG  (DEBUG_CTX, "gpgme_op_keylist_start", ctx,
1082               "pattern=%s, secret_only=%i", pattern, secret_only);
1083
1084   if (!ctx)
1085     return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
1086
1087   err = _gpgme_op_reset (ctx, 2);
1088   if (err)
1089     return TRACE_ERR (err);
1090
1091   err = _gpgme_op_data_lookup (ctx, OPDATA_KEYLIST, &hook,
1092                                sizeof (*opd), release_op_data);
1093   opd = hook;
1094   if (err)
1095     return TRACE_ERR (err);
1096
1097   _gpgme_engine_set_status_handler (ctx->engine, keylist_status_handler, ctx);
1098
1099   err = _gpgme_engine_set_colon_line_handler (ctx->engine,
1100                                               keylist_colon_handler, ctx);
1101   if (err)
1102     return TRACE_ERR (err);
1103
1104   if (ctx->offline)
1105     flags |= GPGME_ENGINE_FLAG_OFFLINE;
1106
1107   err = _gpgme_engine_op_keylist (ctx->engine, pattern, secret_only,
1108                                   ctx->keylist_mode, flags);
1109   return TRACE_ERR (err);
1110 }
1111
1112
1113 /* Start a keylist operation within CTX, searching for keys which
1114    match PATTERN.  If SECRET_ONLY is true, only secret keys are
1115    returned.  */
1116 gpgme_error_t
1117 gpgme_op_keylist_ext_start (gpgme_ctx_t ctx, const char *pattern[],
1118                             int secret_only, int reserved)
1119 {
1120   gpgme_error_t err;
1121   void *hook;
1122   op_data_t opd;
1123   int flags = 0;
1124
1125   TRACE_BEG  (DEBUG_CTX, "gpgme_op_keylist_ext_start", ctx,
1126               "secret_only=%i, reserved=0x%x", secret_only, reserved);
1127
1128   if (!ctx)
1129     return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
1130
1131   err = _gpgme_op_reset (ctx, 2);
1132   if (err)
1133     return TRACE_ERR (err);
1134
1135   err = _gpgme_op_data_lookup (ctx, OPDATA_KEYLIST, &hook,
1136                                sizeof (*opd), release_op_data);
1137   opd = hook;
1138   if (err)
1139     return TRACE_ERR (err);
1140
1141   _gpgme_engine_set_status_handler (ctx->engine, keylist_status_handler, ctx);
1142   err = _gpgme_engine_set_colon_line_handler (ctx->engine,
1143                                               keylist_colon_handler, ctx);
1144   if (err)
1145     return TRACE_ERR (err);
1146
1147   if (ctx->offline)
1148     flags |= GPGME_ENGINE_FLAG_OFFLINE;
1149
1150   err = _gpgme_engine_op_keylist_ext (ctx->engine, pattern, secret_only,
1151                                       reserved, ctx->keylist_mode,
1152                                       flags);
1153   return TRACE_ERR (err);
1154 }
1155
1156
1157 /* Start a keylist operation within CTX to show keys contained
1158  * in DATA.  */
1159 gpgme_error_t
1160 gpgme_op_keylist_from_data_start (gpgme_ctx_t ctx, gpgme_data_t data,
1161                                   int reserved)
1162 {
1163   gpgme_error_t err;
1164   void *hook;
1165   op_data_t opd;
1166
1167   TRACE_BEG (DEBUG_CTX, "gpgme_op_keylist_from_data_start", ctx, "");
1168
1169   if (!ctx || !data || reserved)
1170     return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
1171
1172   err = _gpgme_op_reset (ctx, 2);
1173   if (err)
1174     return TRACE_ERR (err);
1175
1176   err = _gpgme_op_data_lookup (ctx, OPDATA_KEYLIST, &hook,
1177                                sizeof (*opd), release_op_data);
1178   opd = hook;
1179   if (err)
1180     return TRACE_ERR (err);
1181
1182   _gpgme_engine_set_status_handler (ctx->engine, keylist_status_handler, ctx);
1183   err = _gpgme_engine_set_colon_line_handler (ctx->engine,
1184                                               keylist_colon_handler, ctx);
1185   if (err)
1186     return TRACE_ERR (err);
1187
1188   err = _gpgme_engine_op_keylist_data (ctx->engine, data);
1189   return TRACE_ERR (err);
1190 }
1191
1192
1193 /* Return the next key from the keylist in R_KEY.  */
1194 gpgme_error_t
1195 gpgme_op_keylist_next (gpgme_ctx_t ctx, gpgme_key_t *r_key)
1196 {
1197   gpgme_error_t err;
1198   struct key_queue_item_s *queue_item;
1199   void *hook;
1200   op_data_t opd;
1201
1202   TRACE_BEG (DEBUG_CTX, "gpgme_op_keylist_next", ctx, "");
1203
1204   if (!ctx || !r_key)
1205     return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
1206   *r_key = NULL;
1207   if (!ctx)
1208     return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
1209
1210   err = _gpgme_op_data_lookup (ctx, OPDATA_KEYLIST, &hook, -1, NULL);
1211   opd = hook;
1212   if (err)
1213     return TRACE_ERR (err);
1214   if (opd == NULL)
1215     return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
1216
1217   if (!opd->key_queue)
1218     {
1219       err = _gpgme_wait_on_condition (ctx, &opd->key_cond, NULL);
1220       if (err)
1221         return TRACE_ERR (err);
1222
1223       if (!opd->key_cond)
1224         return TRACE_ERR (opd->keydb_search_err? opd->keydb_search_err
1225                           /**/                 : gpg_error (GPG_ERR_EOF));
1226
1227       opd->key_cond = 0;
1228       assert (opd->key_queue);
1229     }
1230   queue_item = opd->key_queue;
1231   opd->key_queue = queue_item->next;
1232   if (!opd->key_queue)
1233     opd->key_cond = 0;
1234
1235   *r_key = queue_item->key;
1236   free (queue_item);
1237
1238   TRACE_SUC ("key=%p (%s)", *r_key,
1239              ((*r_key)->subkeys && (*r_key)->subkeys->fpr) ?
1240              (*r_key)->subkeys->fpr : "invalid");
1241   return 0;
1242 }
1243
1244
1245 /* Terminate a pending keylist operation within CTX.  */
1246 gpgme_error_t
1247 gpgme_op_keylist_end (gpgme_ctx_t ctx)
1248 {
1249   TRACE (DEBUG_CTX, "gpgme_op_keylist_end", ctx, "");
1250
1251   if (!ctx)
1252     return gpg_error (GPG_ERR_INV_VALUE);
1253
1254   return 0;
1255 }
1256
1257 \f
1258 /* Get the key with the fingerprint FPR from the crypto backend.  If
1259    SECRET is true, get the secret key.  */
1260 gpgme_error_t
1261 gpgme_get_key (gpgme_ctx_t ctx, const char *fpr, gpgme_key_t *r_key,
1262                int secret)
1263 {
1264   gpgme_ctx_t listctx;
1265   gpgme_error_t err;
1266   gpgme_key_t result, key;
1267
1268   TRACE_BEG  (DEBUG_CTX, "gpgme_get_key", ctx,
1269               "fpr=%s, secret=%i", fpr, secret);
1270
1271   if (r_key)
1272     *r_key = NULL;
1273
1274   if (!ctx || !r_key || !fpr)
1275     return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
1276
1277   if (strlen (fpr) < 8) /* We have at least a key ID.  */
1278     return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
1279
1280   /* FIXME: We use our own context because we have to avoid the user's
1281      I/O callback handlers.  */
1282   err = gpgme_new (&listctx);
1283   if (err)
1284     return TRACE_ERR (err);
1285   {
1286     gpgme_protocol_t proto;
1287     gpgme_engine_info_t info;
1288
1289     /* Clone the relevant state.  */
1290     proto = gpgme_get_protocol (ctx);
1291     gpgme_set_protocol (listctx, proto);
1292     gpgme_set_keylist_mode (listctx, gpgme_get_keylist_mode (ctx));
1293     info = gpgme_ctx_get_engine_info (ctx);
1294     while (info && info->protocol != proto)
1295       info = info->next;
1296     if (info)
1297       gpgme_ctx_set_engine_info (listctx, proto,
1298                                  info->file_name, info->home_dir);
1299   }
1300
1301   err = gpgme_op_keylist_start (listctx, fpr, secret);
1302   if (!err)
1303     err = gpgme_op_keylist_next (listctx, &result);
1304   if (!err)
1305     {
1306     try_next_key:
1307       err = gpgme_op_keylist_next (listctx, &key);
1308       if (gpgme_err_code (err) == GPG_ERR_EOF)
1309         err = 0;
1310       else
1311         {
1312           if (!err
1313               && result && result->subkeys && result->subkeys->fpr
1314               && key && key->subkeys && key->subkeys->fpr
1315               && !strcmp (result->subkeys->fpr, key->subkeys->fpr))
1316             {
1317               /* The fingerprint is identical.  We assume that this is
1318                  the same key and don't mark it as an ambiguous.  This
1319                  problem may occur with corrupted keyrings and has
1320                  been noticed often with gpgsm.  In fact gpgsm uses a
1321                  similar hack to sort out such duplicates but it can't
1322                  do that while listing keys.  */
1323               gpgme_key_unref (key);
1324               goto try_next_key;
1325             }
1326           if (!err)
1327             {
1328               gpgme_key_unref (key);
1329               err = gpg_error (GPG_ERR_AMBIGUOUS_NAME);
1330             }
1331           gpgme_key_unref (result);
1332           result = NULL;
1333         }
1334     }
1335   gpgme_release (listctx);
1336   if (! err)
1337     {
1338       *r_key = result;
1339       TRACE_LOG  ("key=%p (%s)", *r_key,
1340                   ((*r_key)->subkeys && (*r_key)->subkeys->fpr) ?
1341                   (*r_key)->subkeys->fpr : "invalid");
1342     }
1343   return TRACE_ERR (err);
1344 }