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