core,cpp: New key flag 'is_de_vs'.
[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 18
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       break;
737
738     case RT_SUB:
739     case RT_SSB:
740       /* Start a new subkey.  */
741       err = _gpgme_key_add_subkey (key, &subkey);
742       if (err)
743         return err;
744
745       if (rectype == RT_SSB)
746         subkey->secret = 1;
747
748       /* Field 2 has the trust info.  */
749       if (fields >= 2)
750         set_subkey_trust_info (subkey, field[1]);
751
752       /* Field 3 has the key length.  */
753       if (fields >= 3)
754         {
755           int i = atoi (field[2]);
756           /* Ignore invalid values.  */
757           if (i > 1)
758             subkey->length = i;
759         }
760
761       /* Field 4 has the public key algorithm.  */
762       if (fields >= 4)
763         {
764           int i = atoi (field[3]);
765           if (i >= 1 && i < 128)
766             subkey->pubkey_algo = _gpgme_map_pk_algo (i, ctx->protocol);
767         }
768
769       /* Field 5 has the long keyid.  */
770       if (fields >= 5 && strlen (field[4]) == DIM(subkey->_keyid) - 1)
771         strcpy (subkey->_keyid, field[4]);
772
773       /* Field 6 has the timestamp (seconds).  */
774       if (fields >= 6)
775         subkey->timestamp = _gpgme_parse_timestamp (field[5], NULL);
776
777       /* Field 7 has the expiration time (seconds).  */
778       if (fields >= 7)
779         subkey->expires = _gpgme_parse_timestamp (field[6], NULL);
780
781       /* Field 8 is reserved (LID).  */
782       /* Field 9 has the ownertrust.  */
783       /* Field 10, the user ID, is n/a for a subkey.  */
784
785       /* Field 11 has the signature class.  */
786
787       /* Field 12 has the capabilities.  */
788       if (fields >= 12)
789         set_subkey_capability (subkey, field[11]);
790
791       /* Field 15 carries special flags of a secret key. */
792       if (fields >= 15
793           && (key->secret
794               || (ctx->keylist_mode & GPGME_KEYLIST_MODE_WITH_SECRET)))
795         {
796           err = parse_sec_field15 (key, subkey, field[14]);
797           if (err)
798             return err;
799         }
800
801       /* Field 17 has the curve name for ECC.  */
802       if (fields >= 17 && *field[16])
803         {
804           subkey->curve = strdup (field[16]);
805           if (!subkey->curve)
806             return gpg_error_from_syserror ();
807         }
808
809       /* Field 18 has the compliance flags.  */
810       if (fields >= 17 && *field[17])
811         parse_pub_field18 (subkey, field[17]);
812
813       break;
814
815     case RT_UID:
816       /* Field 2 has the trust info, and field 10 has the user ID.  */
817       if (fields >= 10)
818         {
819           if (_gpgme_key_append_name (key, field[9], 1))
820             return gpg_error (GPG_ERR_ENOMEM);  /* FIXME */
821           else
822             {
823               if (field[1])
824                 set_userid_flags (key, field[1]);
825               opd->tmp_uid = key->_last_uid;
826             }
827         }
828       break;
829
830     case RT_TFS:
831       if (opd->tmp_uid)
832         {
833           err = parse_tfs_record (opd->tmp_uid, field, fields);
834           if (err)
835             return err;
836         }
837       break;
838
839     case RT_FPR:
840       /* Field 10 has the fingerprint (take only the first one).  */
841       if (fields >= 10 && field[9] && *field[9])
842         {
843           /* Need to apply it to the last subkey because all subkeys
844              do have fingerprints. */
845           subkey = key->_last_subkey;
846           if (!subkey->fpr)
847             {
848               subkey->fpr = strdup (field[9]);
849               if (!subkey->fpr)
850                 return gpg_error_from_syserror ();
851             }
852           /* If this is the first subkey, store the fingerprint also
853              in the KEY object.  */
854           if (subkey == key->subkeys)
855             {
856               if (key->fpr && strcmp (key->fpr, subkey->fpr))
857                 {
858                   /* FPR already set but mismatch: Should never happen.  */
859                   return trace_gpg_error (GPG_ERR_INTERNAL);
860                 }
861               if (!key->fpr)
862                 {
863                   key->fpr = strdup (subkey->fpr);
864                   if (!key->fpr)
865                     return gpg_error_from_syserror ();
866                 }
867             }
868         }
869
870       /* Field 13 has the gpgsm chain ID (take only the first one).  */
871       if (fields >= 13 && !key->chain_id && *field[12])
872         {
873           key->chain_id = strdup (field[12]);
874           if (!key->chain_id)
875             return gpg_error_from_syserror ();
876         }
877       break;
878
879     case RT_GRP:
880       /* Field 10 has the keygrip.  */
881       if (fields >= 10 && field[9] && *field[9])
882         {
883           /* Need to apply it to the last subkey because all subkeys
884              have a keygrip. */
885           subkey = key->_last_subkey;
886           if (!subkey->keygrip)
887             {
888               subkey->keygrip = strdup (field[9]);
889               if (!subkey->keygrip)
890                 return gpg_error_from_syserror ();
891             }
892         }
893       break;
894
895     case RT_SIG:
896     case RT_REV:
897       if (!opd->tmp_uid)
898         return 0;
899
900       /* Start a new (revoked) signature.  */
901       assert (opd->tmp_uid == key->_last_uid);
902       keysig = _gpgme_key_add_sig (key, (fields >= 10) ? field[9] : NULL);
903       if (!keysig)
904         return gpg_error (GPG_ERR_ENOMEM);      /* FIXME */
905
906       /* Field 2 has the calculated trust ('!', '-', '?', '%').  */
907       if (fields >= 2)
908         switch (field[1][0])
909           {
910           case '!':
911             keysig->status = gpg_error (GPG_ERR_NO_ERROR);
912             break;
913
914           case '-':
915             keysig->status = gpg_error (GPG_ERR_BAD_SIGNATURE);
916             break;
917
918           case '?':
919             keysig->status = gpg_error (GPG_ERR_NO_PUBKEY);
920             break;
921
922           case '%':
923             keysig->status = gpg_error (GPG_ERR_GENERAL);
924             break;
925
926           default:
927             keysig->status = gpg_error (GPG_ERR_NO_ERROR);
928             break;
929           }
930
931       /* Field 4 has the public key algorithm.  */
932       if (fields >= 4)
933         {
934           int i = atoi (field[3]);
935           if (i >= 1 && i < 128)
936             keysig->pubkey_algo = _gpgme_map_pk_algo (i, ctx->protocol);
937         }
938
939       /* Field 5 has the long keyid.  */
940       if (fields >= 5 && strlen (field[4]) == DIM(keysig->_keyid) - 1)
941         strcpy (keysig->_keyid, field[4]);
942
943       /* Field 6 has the timestamp (seconds).  */
944       if (fields >= 6)
945         keysig->timestamp = _gpgme_parse_timestamp (field[5], NULL);
946
947       /* Field 7 has the expiration time (seconds).  */
948       if (fields >= 7)
949         keysig->expires = _gpgme_parse_timestamp (field[6], NULL);
950
951       /* Field 11 has the signature class (eg, 0x30 means revoked).  */
952       if (fields >= 11)
953         if (field[10][0] && field[10][1])
954           {
955             int sig_class = _gpgme_hextobyte (field[10]);
956             if (sig_class >= 0)
957               {
958                 keysig->sig_class = sig_class;
959                 keysig->class = keysig->sig_class;
960                 if (sig_class == 0x30)
961                   keysig->revoked = 1;
962               }
963             if (field[10][2] == 'x')
964               keysig->exportable = 1;
965           }
966
967       opd->tmp_keysig = keysig;
968       break;
969
970     case RT_SPK:
971       if (!opd->tmp_keysig)
972         return 0;
973       assert (opd->tmp_keysig == key->_last_uid->_last_keysig);
974
975       if (fields >= 4)
976         {
977           /* Field 2 has the subpacket type.  */
978           int type = atoi (field[1]);
979
980           /* Field 3 has the flags.  */
981           int flags = atoi (field[2]);
982
983           /* Field 4 has the length.  */
984           int len = atoi (field[3]);
985
986           /* Field 5 has the data.  */
987           char *data = field[4];
988
989           /* Type 20: Notation data.  */
990           /* Type 26: Policy URL.  */
991           if (type == 20 || type == 26)
992             {
993               gpgme_sig_notation_t notation;
994
995               keysig = opd->tmp_keysig;
996
997               /* At this time, any error is serious.  */
998               err = _gpgme_parse_notation (&notation, type, flags, len, data);
999               if (err)
1000                 return err;
1001
1002               /* Add a new notation.  FIXME: Could be factored out.  */
1003               if (!keysig->notations)
1004                 keysig->notations = notation;
1005               if (keysig->_last_notation)
1006                 keysig->_last_notation->next = notation;
1007               keysig->_last_notation = notation;
1008             }
1009         }
1010
1011     case RT_NONE:
1012       /* Unknown record.  */
1013       break;
1014     }
1015   return 0;
1016 }
1017
1018
1019 void
1020 _gpgme_op_keylist_event_cb (void *data, gpgme_event_io_t type, void *type_data)
1021 {
1022   gpgme_error_t err;
1023   gpgme_ctx_t ctx = (gpgme_ctx_t) data;
1024   gpgme_key_t key = (gpgme_key_t) type_data;
1025   void *hook;
1026   op_data_t opd;
1027   struct key_queue_item_s *q, *q2;
1028
1029   assert (type == GPGME_EVENT_NEXT_KEY);
1030
1031   err = _gpgme_op_data_lookup (ctx, OPDATA_KEYLIST, &hook, -1, NULL);
1032   opd = hook;
1033   if (err)
1034     return;
1035
1036   q = malloc (sizeof *q);
1037   if (!q)
1038     {
1039       gpgme_key_unref (key);
1040       /* FIXME       return GPGME_Out_Of_Core; */
1041       return;
1042     }
1043   q->key = key;
1044   q->next = NULL;
1045   /* FIXME: Use a tail pointer?  */
1046   if (!(q2 = opd->key_queue))
1047     opd->key_queue = q;
1048   else
1049     {
1050       for (; q2->next; q2 = q2->next)
1051         ;
1052       q2->next = q;
1053     }
1054   opd->key_cond = 1;
1055 }
1056
1057
1058 /* Start a keylist operation within CTX, searching for keys which
1059    match PATTERN.  If SECRET_ONLY is true, only secret keys are
1060    returned.  */
1061 gpgme_error_t
1062 gpgme_op_keylist_start (gpgme_ctx_t ctx, const char *pattern, int secret_only)
1063 {
1064   gpgme_error_t err;
1065   void *hook;
1066   op_data_t opd;
1067   int flags = 0;
1068
1069   TRACE_BEG2 (DEBUG_CTX, "gpgme_op_keylist_start", ctx,
1070               "pattern=%s, secret_only=%i", pattern, secret_only);
1071
1072   if (!ctx)
1073     return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
1074
1075   err = _gpgme_op_reset (ctx, 2);
1076   if (err)
1077     return TRACE_ERR (err);
1078
1079   err = _gpgme_op_data_lookup (ctx, OPDATA_KEYLIST, &hook,
1080                                sizeof (*opd), release_op_data);
1081   opd = hook;
1082   if (err)
1083     return TRACE_ERR (err);
1084
1085   _gpgme_engine_set_status_handler (ctx->engine, keylist_status_handler, ctx);
1086
1087   err = _gpgme_engine_set_colon_line_handler (ctx->engine,
1088                                               keylist_colon_handler, ctx);
1089   if (err)
1090     return TRACE_ERR (err);
1091
1092   if (ctx->offline)
1093     flags |= GPGME_ENGINE_FLAG_OFFLINE;
1094
1095   err = _gpgme_engine_op_keylist (ctx->engine, pattern, secret_only,
1096                                   ctx->keylist_mode, flags);
1097   return TRACE_ERR (err);
1098 }
1099
1100
1101 /* Start a keylist operation within CTX, searching for keys which
1102    match PATTERN.  If SECRET_ONLY is true, only secret keys are
1103    returned.  */
1104 gpgme_error_t
1105 gpgme_op_keylist_ext_start (gpgme_ctx_t ctx, const char *pattern[],
1106                             int secret_only, int reserved)
1107 {
1108   gpgme_error_t err;
1109   void *hook;
1110   op_data_t opd;
1111   int flags = 0;
1112
1113   TRACE_BEG2 (DEBUG_CTX, "gpgme_op_keylist_ext_start", ctx,
1114               "secret_only=%i, reserved=0x%x", secret_only, reserved);
1115
1116   if (!ctx)
1117     return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
1118
1119   err = _gpgme_op_reset (ctx, 2);
1120   if (err)
1121     return TRACE_ERR (err);
1122
1123   err = _gpgme_op_data_lookup (ctx, OPDATA_KEYLIST, &hook,
1124                                sizeof (*opd), release_op_data);
1125   opd = hook;
1126   if (err)
1127     return TRACE_ERR (err);
1128
1129   _gpgme_engine_set_status_handler (ctx->engine, keylist_status_handler, ctx);
1130   err = _gpgme_engine_set_colon_line_handler (ctx->engine,
1131                                               keylist_colon_handler, ctx);
1132   if (err)
1133     return TRACE_ERR (err);
1134
1135   if (ctx->offline)
1136     flags |= GPGME_ENGINE_FLAG_OFFLINE;
1137
1138   err = _gpgme_engine_op_keylist_ext (ctx->engine, pattern, secret_only,
1139                                       reserved, ctx->keylist_mode,
1140                                       flags);
1141   return TRACE_ERR (err);
1142 }
1143
1144
1145 /* Return the next key from the keylist in R_KEY.  */
1146 gpgme_error_t
1147 gpgme_op_keylist_next (gpgme_ctx_t ctx, gpgme_key_t *r_key)
1148 {
1149   gpgme_error_t err;
1150   struct key_queue_item_s *queue_item;
1151   void *hook;
1152   op_data_t opd;
1153
1154   TRACE_BEG (DEBUG_CTX, "gpgme_op_keylist_next", ctx);
1155
1156   if (!ctx || !r_key)
1157     return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
1158   *r_key = NULL;
1159   if (!ctx)
1160     return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
1161
1162   err = _gpgme_op_data_lookup (ctx, OPDATA_KEYLIST, &hook, -1, NULL);
1163   opd = hook;
1164   if (err)
1165     return TRACE_ERR (err);
1166   if (opd == NULL)
1167     return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
1168
1169   if (!opd->key_queue)
1170     {
1171       err = _gpgme_wait_on_condition (ctx, &opd->key_cond, NULL);
1172       if (err)
1173         return TRACE_ERR (err);
1174
1175       if (!opd->key_cond)
1176         return TRACE_ERR (opd->keydb_search_err? opd->keydb_search_err
1177                           /**/                 : gpg_error (GPG_ERR_EOF));
1178
1179       opd->key_cond = 0;
1180       assert (opd->key_queue);
1181     }
1182   queue_item = opd->key_queue;
1183   opd->key_queue = queue_item->next;
1184   if (!opd->key_queue)
1185     opd->key_cond = 0;
1186
1187   *r_key = queue_item->key;
1188   free (queue_item);
1189
1190   return TRACE_SUC2 ("key=%p (%s)", *r_key,
1191                      ((*r_key)->subkeys && (*r_key)->subkeys->fpr) ?
1192                      (*r_key)->subkeys->fpr : "invalid");
1193 }
1194
1195
1196 /* Terminate a pending keylist operation within CTX.  */
1197 gpgme_error_t
1198 gpgme_op_keylist_end (gpgme_ctx_t ctx)
1199 {
1200   TRACE (DEBUG_CTX, "gpgme_op_keylist_end", ctx);
1201
1202   if (!ctx)
1203     return gpg_error (GPG_ERR_INV_VALUE);
1204
1205   return 0;
1206 }
1207
1208 \f
1209 /* Get the key with the fingerprint FPR from the crypto backend.  If
1210    SECRET is true, get the secret key.  */
1211 gpgme_error_t
1212 gpgme_get_key (gpgme_ctx_t ctx, const char *fpr, gpgme_key_t *r_key,
1213                int secret)
1214 {
1215   gpgme_ctx_t listctx;
1216   gpgme_error_t err;
1217   gpgme_key_t key;
1218
1219   TRACE_BEG2 (DEBUG_CTX, "gpgme_get_key", ctx,
1220               "fpr=%s, secret=%i", fpr, secret);
1221
1222   if (!ctx || !r_key || !fpr)
1223     return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
1224
1225   if (strlen (fpr) < 8) /* We have at least a key ID.  */
1226     return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
1227
1228   /* FIXME: We use our own context because we have to avoid the user's
1229      I/O callback handlers.  */
1230   err = gpgme_new (&listctx);
1231   if (err)
1232     return TRACE_ERR (err);
1233   {
1234     gpgme_protocol_t proto;
1235     gpgme_engine_info_t info;
1236
1237     /* Clone the relevant state.  */
1238     proto = gpgme_get_protocol (ctx);
1239     gpgme_set_protocol (listctx, proto);
1240     gpgme_set_keylist_mode (listctx, gpgme_get_keylist_mode (ctx));
1241     info = gpgme_ctx_get_engine_info (ctx);
1242     while (info && info->protocol != proto)
1243       info = info->next;
1244     if (info)
1245       gpgme_ctx_set_engine_info (listctx, proto,
1246                                  info->file_name, info->home_dir);
1247   }
1248
1249   err = gpgme_op_keylist_start (listctx, fpr, secret);
1250   if (!err)
1251     err = gpgme_op_keylist_next (listctx, r_key);
1252   if (!err)
1253     {
1254     try_next_key:
1255       err = gpgme_op_keylist_next (listctx, &key);
1256       if (gpgme_err_code (err) == GPG_ERR_EOF)
1257         err = 0;
1258       else
1259         {
1260           if (!err
1261               && *r_key && (*r_key)->subkeys && (*r_key)->subkeys->fpr
1262               && key && key->subkeys && key->subkeys->fpr
1263               && !strcmp ((*r_key)->subkeys->fpr, key->subkeys->fpr))
1264             {
1265               /* The fingerprint is identical.  We assume that this is
1266                  the same key and don't mark it as an ambiguous.  This
1267                  problem may occur with corrupted keyrings and has
1268                  been noticed often with gpgsm.  In fact gpgsm uses a
1269                  similar hack to sort out such duplicates but it can't
1270                  do that while listing keys.  */
1271               gpgme_key_unref (key);
1272               goto try_next_key;
1273             }
1274           if (!err)
1275             {
1276               gpgme_key_unref (key);
1277               err = gpg_error (GPG_ERR_AMBIGUOUS_NAME);
1278             }
1279           gpgme_key_unref (*r_key);
1280         }
1281     }
1282   gpgme_release (listctx);
1283   if (! err)
1284     {
1285       TRACE_LOG2 ("key=%p (%s)", *r_key,
1286                   ((*r_key)->subkeys && (*r_key)->subkeys->fpr) ?
1287                   (*r_key)->subkeys->fpr : "invalid");
1288     }
1289   return TRACE_ERR (err);
1290 }