Imported Upstream version 1.11.0
[platform/upstream/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 static gpgme_keyorg_t
380 parse_keyorg (const char *string)
381 {
382   switch (atoi (string))
383     {
384     case 0: return GPGME_KEYORG_UNKNOWN;
385     case 1:
386     case 2:
387       return GPGME_KEYORG_KS;
388     case 3: return GPGME_KEYORG_DANE;
389     case 4: return GPGME_KEYORG_WKD;
390     case 5: return GPGME_KEYORG_URL;
391     case 6: return GPGME_KEYORG_FILE;
392     case 7: return GPGME_KEYORG_SELF;
393     default: return GPGME_KEYORG_OTHER;
394     }
395 }
396
397
398 /* Parse field 15 of a secret key or subkey.  This fields holds a
399    reference to smartcards.  FIELD is the content of the field and we
400    are allowed to modify it.  */
401 static gpg_error_t
402 parse_sec_field15 (gpgme_key_t key, gpgme_subkey_t subkey, char *field)
403 {
404   if (!*field)
405     ; /* Empty.  */
406   else if (*field == '#')
407     {
408       /* This is a stub for an offline key.  We reset the SECRET flag
409          of the subkey here.  Note that the secret flag of the entire
410          key will be true even then.  We even explicitly set
411          key->secret to make it works for GPGME_KEYLIST_MODE_WITH_SECRET. */
412       subkey->secret = 0;
413       key->secret = 1;
414     }
415   else if (strchr ("01234567890ABCDEFabcdef", *field))
416     {
417       /* Fields starts with a hex digit; thus it is a serial number.  */
418       key->secret = 1;
419       subkey->is_cardkey = 1;
420       subkey->card_number = strdup (field);
421       if (!subkey->card_number)
422         return gpg_error_from_syserror ();
423     }
424   else if (*field == '+')
425     {
426       key->secret = 1;
427       subkey->secret = 1;
428     }
429   else
430     {
431       /* RFU.  */
432     }
433
434   return 0;
435 }
436
437
438 /* Parse a tfs record.  */
439 static gpg_error_t
440 parse_tfs_record (gpgme_user_id_t uid, char **field, int nfield)
441 {
442   gpg_error_t err;
443   gpgme_tofu_info_t ti;
444   unsigned long uval;
445
446   /* We add only the first TOFU record in case future versions emit
447    * several.  */
448   if (uid->tofu)
449     return 0;
450
451   /* Check that we have enough fields and that the version is supported.  */
452   if (nfield < 8 || atoi(field[1]) != 1)
453     return trace_gpg_error (GPG_ERR_INV_ENGINE);
454
455   ti = calloc (1, sizeof *ti);
456   if (!ti)
457     return gpg_error_from_syserror ();
458
459   /* Note that we allow a value of up to 7 which is what we can store
460    * in the ti->validity.  */
461   err = _gpgme_strtoul_field (field[2], &uval);
462   if (err || uval > 7)
463     goto inv_engine;
464   ti->validity = uval;
465
466   /* Parse the sign-count.  */
467   err = _gpgme_strtoul_field (field[3], &uval);
468   if (err)
469     goto inv_engine;
470   if (uval > USHRT_MAX)
471     uval = USHRT_MAX;
472   ti->signcount = uval;
473
474   /* Parse the encr-count.  */
475   err = _gpgme_strtoul_field (field[4], &uval);
476   if (err)
477     goto inv_engine;
478   if (uval > USHRT_MAX)
479     uval = USHRT_MAX;
480   ti->encrcount = uval;
481
482   /* Parse the policy.  */
483   if (!strcmp (field[5], "none"))
484     ti->policy = GPGME_TOFU_POLICY_NONE;
485   else if (!strcmp (field[5], "auto"))
486     ti->policy = GPGME_TOFU_POLICY_AUTO;
487   else if (!strcmp (field[5], "good"))
488     ti->policy = GPGME_TOFU_POLICY_GOOD;
489   else if (!strcmp (field[5], "bad"))
490     ti->policy = GPGME_TOFU_POLICY_BAD;
491   else if (!strcmp (field[5], "ask"))
492     ti->policy = GPGME_TOFU_POLICY_ASK;
493   else /* "unknown" and invalid policy strings.  */
494     ti->policy = GPGME_TOFU_POLICY_UNKNOWN;
495
496   /* Parse first and last seen timestamps.  */
497   err = _gpgme_strtoul_field (field[6], &uval);
498   if (err)
499     goto inv_engine;
500   ti->signfirst = uval;
501   err = _gpgme_strtoul_field (field[7], &uval);
502   if (err)
503     goto inv_engine;
504   ti->signlast = uval;
505
506   if (nfield > 9)
507     {
508       /* This condition is only to allow for gpg 2.1.15 - can
509        * eventually be removed.  */
510       err = _gpgme_strtoul_field (field[8], &uval);
511       if (err)
512         goto inv_engine;
513       ti->encrfirst = uval;
514       err = _gpgme_strtoul_field (field[9], &uval);
515       if (err)
516         goto inv_engine;
517       ti->encrlast = uval;
518     }
519
520   /* Ready.  */
521   uid->tofu = ti;
522   return 0;
523
524  inv_engine:
525   free (ti);
526   return trace_gpg_error (GPG_ERR_INV_ENGINE);
527 }
528
529
530 /* We have read an entire key into tmp_key and should now finish it.
531    It is assumed that this releases tmp_key.  */
532 static void
533 finish_key (gpgme_ctx_t ctx, op_data_t opd)
534 {
535   gpgme_key_t key = opd->tmp_key;
536
537   opd->tmp_key = NULL;
538   opd->tmp_uid = NULL;
539   opd->tmp_keysig = NULL;
540
541   if (key)
542     _gpgme_engine_io_event (ctx->engine, GPGME_EVENT_NEXT_KEY, key);
543 }
544
545
546 /* Note: We are allowed to modify LINE.  */
547 static gpgme_error_t
548 keylist_colon_handler (void *priv, char *line)
549 {
550   gpgme_ctx_t ctx = (gpgme_ctx_t) priv;
551   enum
552     {
553       RT_NONE, RT_SIG, RT_UID, RT_TFS, RT_SUB, RT_PUB, RT_FPR, RT_GRP,
554       RT_SSB, RT_SEC, RT_CRT, RT_CRS, RT_REV, RT_SPK
555     }
556   rectype = RT_NONE;
557 #define NR_FIELDS 20
558   char *field[NR_FIELDS];
559   int fields = 0;
560   void *hook;
561   op_data_t opd;
562   gpgme_error_t err;
563   gpgme_key_t key;
564   gpgme_subkey_t subkey = NULL;
565   gpgme_key_sig_t keysig = NULL;
566
567   err = _gpgme_op_data_lookup (ctx, OPDATA_KEYLIST, &hook, -1, NULL);
568   opd = hook;
569   if (err)
570     return err;
571
572   key = opd->tmp_key;
573
574   TRACE2 (DEBUG_CTX, "gpgme:keylist_colon_handler", ctx,
575           "key = %p, line = %s", key, line ? line : "(null)");
576
577   if (!line)
578     {
579       /* End Of File.  */
580       finish_key (ctx, opd);
581       return 0;
582     }
583
584   while (line && fields < NR_FIELDS)
585     {
586       field[fields++] = line;
587       line = strchr (line, ':');
588       if (line)
589         *(line++) = '\0';
590     }
591
592   if (!strcmp (field[0], "sig"))
593     rectype = RT_SIG;
594   else if (!strcmp (field[0], "rev"))
595     rectype = RT_REV;
596   else if (!strcmp (field[0], "pub"))
597     rectype = RT_PUB;
598   else if (!strcmp (field[0], "sec"))
599     rectype = RT_SEC;
600   else if (!strcmp (field[0], "crt"))
601     rectype = RT_CRT;
602   else if (!strcmp (field[0], "crs"))
603     rectype = RT_CRS;
604   else if (!strcmp (field[0], "fpr") && key)
605     rectype = RT_FPR;
606   else if (!strcmp (field[0], "grp") && key)
607     rectype = RT_GRP;
608   else if (!strcmp (field[0], "uid") && key)
609     rectype = RT_UID;
610   else if (!strcmp (field[0], "tfs") && key)
611     rectype = RT_TFS;
612   else if (!strcmp (field[0], "sub") && key)
613     rectype = RT_SUB;
614   else if (!strcmp (field[0], "ssb") && key)
615     rectype = RT_SSB;
616   else if (!strcmp (field[0], "spk") && key)
617     rectype = RT_SPK;
618   else
619     rectype = RT_NONE;
620
621   /* Only look at signature and trust info records immediately
622      following a user ID.  For this, clear the user ID pointer when
623      encountering anything but a signature or trust record.  */
624   if (rectype != RT_SIG && rectype != RT_REV && rectype != RT_TFS)
625     opd->tmp_uid = NULL;
626
627   /* Only look at subpackets immediately following a signature.  For
628      this, clear the signature pointer when encountering anything but
629      a subpacket.  */
630   if (rectype != RT_SPK)
631     opd->tmp_keysig = NULL;
632
633   switch (rectype)
634     {
635     case RT_PUB:
636     case RT_SEC:
637     case RT_CRT:
638     case RT_CRS:
639       /* Start a new keyblock.  */
640       err = _gpgme_key_new (&key);
641       if (err)
642         return err;
643       key->keylist_mode = ctx->keylist_mode;
644       err = _gpgme_key_add_subkey (key, &subkey);
645       if (err)
646         {
647           gpgme_key_unref (key);
648           return err;
649         }
650
651       if (rectype == RT_SEC || rectype == RT_CRS)
652         key->secret = subkey->secret = 1;
653       if (rectype == RT_CRT || rectype == RT_CRS)
654         key->protocol = GPGME_PROTOCOL_CMS;
655       finish_key (ctx, opd);
656       opd->tmp_key = key;
657
658       /* Field 2 has the trust info.  */
659       if (fields >= 2)
660         set_mainkey_trust_info (key, field[1]);
661
662       /* Field 3 has the key length.  */
663       if (fields >= 3)
664         {
665           int i = atoi (field[2]);
666           /* Ignore invalid values.  */
667           if (i > 1)
668             subkey->length = i;
669         }
670
671       /* Field 4 has the public key algorithm.  */
672       if (fields >= 4)
673         {
674           int i = atoi (field[3]);
675           if (i >= 1 && i < 128)
676             subkey->pubkey_algo = _gpgme_map_pk_algo (i, ctx->protocol);
677         }
678
679       /* Field 5 has the long keyid.  Allow short key IDs for the
680          output of an external keyserver listing.  */
681       if (fields >= 5 && strlen (field[4]) <= DIM(subkey->_keyid) - 1)
682         strcpy (subkey->_keyid, field[4]);
683
684       /* Field 6 has the timestamp (seconds).  */
685       if (fields >= 6)
686         subkey->timestamp = _gpgme_parse_timestamp (field[5], NULL);
687
688       /* Field 7 has the expiration time (seconds).  */
689       if (fields >= 7)
690         subkey->expires = _gpgme_parse_timestamp (field[6], NULL);
691
692       /* Field 8 has the X.509 serial number.  */
693       if (fields >= 8 && (rectype == RT_CRT || rectype == RT_CRS))
694         {
695           key->issuer_serial = strdup (field[7]);
696           if (!key->issuer_serial)
697             return gpg_error_from_syserror ();
698         }
699
700       /* Field 9 has the ownertrust.  */
701       if (fields >= 9)
702         set_ownertrust (key, field[8]);
703
704       /* Field 10 is not used for gpg due to --fixed-list-mode option
705          but GPGSM stores the issuer name.  */
706       if (fields >= 10 && (rectype == RT_CRT || rectype == RT_CRS))
707         if (_gpgme_decode_c_string (field[9], &key->issuer_name, 0))
708           return gpg_error (GPG_ERR_ENOMEM);    /* FIXME */
709
710       /* Field 11 has the signature class.  */
711
712       /* Field 12 has the capabilities.  */
713       if (fields >= 12)
714         set_mainkey_capability (key, field[11]);
715
716       /* Field 15 carries special flags of a secret key.  */
717       if (fields >= 15
718           && (key->secret
719               || (ctx->keylist_mode & GPGME_KEYLIST_MODE_WITH_SECRET)))
720         {
721           err = parse_sec_field15 (key, subkey, field[14]);
722           if (err)
723             return err;
724         }
725
726       /* Field 17 has the curve name for ECC.  */
727       if (fields >= 17 && *field[16])
728         {
729           subkey->curve = strdup (field[16]);
730           if (!subkey->curve)
731             return gpg_error_from_syserror ();
732         }
733
734       /* Field 18 has the compliance flags.  */
735       if (fields >= 17 && *field[17])
736         PARSE_COMPLIANCE_FLAGS (field[17], subkey);
737
738       if (fields >= 20)
739         {
740           key->last_update = _gpgme_parse_timestamp_ul (field[18]);
741           key->origin = parse_keyorg (field[19]);
742         }
743
744       break;
745
746     case RT_SUB:
747     case RT_SSB:
748       /* Start a new subkey.  */
749       err = _gpgme_key_add_subkey (key, &subkey);
750       if (err)
751         return err;
752
753       if (rectype == RT_SSB)
754         subkey->secret = 1;
755
756       /* Field 2 has the trust info.  */
757       if (fields >= 2)
758         set_subkey_trust_info (subkey, field[1]);
759
760       /* Field 3 has the key length.  */
761       if (fields >= 3)
762         {
763           int i = atoi (field[2]);
764           /* Ignore invalid values.  */
765           if (i > 1)
766             subkey->length = i;
767         }
768
769       /* Field 4 has the public key algorithm.  */
770       if (fields >= 4)
771         {
772           int i = atoi (field[3]);
773           if (i >= 1 && i < 128)
774             subkey->pubkey_algo = _gpgme_map_pk_algo (i, ctx->protocol);
775         }
776
777       /* Field 5 has the long keyid.  */
778       if (fields >= 5 && strlen (field[4]) == DIM(subkey->_keyid) - 1)
779         strcpy (subkey->_keyid, field[4]);
780
781       /* Field 6 has the timestamp (seconds).  */
782       if (fields >= 6)
783         subkey->timestamp = _gpgme_parse_timestamp (field[5], NULL);
784
785       /* Field 7 has the expiration time (seconds).  */
786       if (fields >= 7)
787         subkey->expires = _gpgme_parse_timestamp (field[6], NULL);
788
789       /* Field 8 is reserved (LID).  */
790       /* Field 9 has the ownertrust.  */
791       /* Field 10, the user ID, is n/a for a subkey.  */
792
793       /* Field 11 has the signature class.  */
794
795       /* Field 12 has the capabilities.  */
796       if (fields >= 12)
797         set_subkey_capability (subkey, field[11]);
798
799       /* Field 15 carries special flags of a secret key. */
800       if (fields >= 15
801           && (key->secret
802               || (ctx->keylist_mode & GPGME_KEYLIST_MODE_WITH_SECRET)))
803         {
804           err = parse_sec_field15 (key, subkey, field[14]);
805           if (err)
806             return err;
807         }
808
809       /* Field 17 has the curve name for ECC.  */
810       if (fields >= 17 && *field[16])
811         {
812           subkey->curve = strdup (field[16]);
813           if (!subkey->curve)
814             return gpg_error_from_syserror ();
815         }
816
817       /* Field 18 has the compliance flags.  */
818       if (fields >= 17 && *field[17])
819         PARSE_COMPLIANCE_FLAGS (field[17], subkey);
820
821       break;
822
823     case RT_UID:
824       /* Field 2 has the trust info, and field 10 has the user ID.  */
825       if (fields >= 10)
826         {
827           if (_gpgme_key_append_name (key, field[9], 1))
828             return gpg_error (GPG_ERR_ENOMEM);  /* FIXME */
829
830           if (field[1])
831             set_userid_flags (key, field[1]);
832           opd->tmp_uid = key->_last_uid;
833           if (fields >= 20)
834             {
835               opd->tmp_uid->last_update = _gpgme_parse_timestamp_ul (field[18]);
836               opd->tmp_uid->origin = parse_keyorg (field[19]);
837             }
838         }
839       break;
840
841     case RT_TFS:
842       if (opd->tmp_uid)
843         {
844           err = parse_tfs_record (opd->tmp_uid, field, fields);
845           if (err)
846             return err;
847         }
848       break;
849
850     case RT_FPR:
851       /* Field 10 has the fingerprint (take only the first one).  */
852       if (fields >= 10 && field[9] && *field[9])
853         {
854           /* Need to apply it to the last subkey because all subkeys
855              do have fingerprints. */
856           subkey = key->_last_subkey;
857           if (!subkey->fpr)
858             {
859               subkey->fpr = strdup (field[9]);
860               if (!subkey->fpr)
861                 return gpg_error_from_syserror ();
862             }
863           /* If this is the first subkey, store the fingerprint also
864              in the KEY object.  */
865           if (subkey == key->subkeys)
866             {
867               if (key->fpr && strcmp (key->fpr, subkey->fpr))
868                 {
869                   /* FPR already set but mismatch: Should never happen.  */
870                   return trace_gpg_error (GPG_ERR_INTERNAL);
871                 }
872               if (!key->fpr)
873                 {
874                   key->fpr = strdup (subkey->fpr);
875                   if (!key->fpr)
876                     return gpg_error_from_syserror ();
877                 }
878             }
879         }
880
881       /* Field 13 has the gpgsm chain ID (take only the first one).  */
882       if (fields >= 13 && !key->chain_id && *field[12])
883         {
884           key->chain_id = strdup (field[12]);
885           if (!key->chain_id)
886             return gpg_error_from_syserror ();
887         }
888       break;
889
890     case RT_GRP:
891       /* Field 10 has the keygrip.  */
892       if (fields >= 10 && field[9] && *field[9])
893         {
894           /* Need to apply it to the last subkey because all subkeys
895              have a keygrip. */
896           subkey = key->_last_subkey;
897           if (!subkey->keygrip)
898             {
899               subkey->keygrip = strdup (field[9]);
900               if (!subkey->keygrip)
901                 return gpg_error_from_syserror ();
902             }
903         }
904       break;
905
906     case RT_SIG:
907     case RT_REV:
908       if (!opd->tmp_uid)
909         return 0;
910
911       /* Start a new (revoked) signature.  */
912       assert (opd->tmp_uid == key->_last_uid);
913       keysig = _gpgme_key_add_sig (key, (fields >= 10) ? field[9] : NULL);
914       if (!keysig)
915         return gpg_error (GPG_ERR_ENOMEM);      /* FIXME */
916
917       /* Field 2 has the calculated trust ('!', '-', '?', '%').  */
918       if (fields >= 2)
919         switch (field[1][0])
920           {
921           case '!':
922             keysig->status = gpg_error (GPG_ERR_NO_ERROR);
923             break;
924
925           case '-':
926             keysig->status = gpg_error (GPG_ERR_BAD_SIGNATURE);
927             break;
928
929           case '?':
930             keysig->status = gpg_error (GPG_ERR_NO_PUBKEY);
931             break;
932
933           case '%':
934             keysig->status = gpg_error (GPG_ERR_GENERAL);
935             break;
936
937           default:
938             keysig->status = gpg_error (GPG_ERR_NO_ERROR);
939             break;
940           }
941
942       /* Field 4 has the public key algorithm.  */
943       if (fields >= 4)
944         {
945           int i = atoi (field[3]);
946           if (i >= 1 && i < 128)
947             keysig->pubkey_algo = _gpgme_map_pk_algo (i, ctx->protocol);
948         }
949
950       /* Field 5 has the long keyid.  */
951       if (fields >= 5 && strlen (field[4]) == DIM(keysig->_keyid) - 1)
952         strcpy (keysig->_keyid, field[4]);
953
954       /* Field 6 has the timestamp (seconds).  */
955       if (fields >= 6)
956         keysig->timestamp = _gpgme_parse_timestamp (field[5], NULL);
957
958       /* Field 7 has the expiration time (seconds).  */
959       if (fields >= 7)
960         keysig->expires = _gpgme_parse_timestamp (field[6], NULL);
961
962       /* Field 11 has the signature class (eg, 0x30 means revoked).  */
963       if (fields >= 11)
964         if (field[10][0] && field[10][1])
965           {
966             int sig_class = _gpgme_hextobyte (field[10]);
967             if (sig_class >= 0)
968               {
969                 keysig->sig_class = sig_class;
970                 keysig->class = keysig->sig_class;
971                 if (sig_class == 0x30)
972                   keysig->revoked = 1;
973               }
974             if (field[10][2] == 'x')
975               keysig->exportable = 1;
976           }
977
978       opd->tmp_keysig = keysig;
979       break;
980
981     case RT_SPK:
982       if (!opd->tmp_keysig)
983         return 0;
984       assert (opd->tmp_keysig == key->_last_uid->_last_keysig);
985
986       if (fields >= 4)
987         {
988           /* Field 2 has the subpacket type.  */
989           int type = atoi (field[1]);
990
991           /* Field 3 has the flags.  */
992           int flags = atoi (field[2]);
993
994           /* Field 4 has the length.  */
995           int len = atoi (field[3]);
996
997           /* Field 5 has the data.  */
998           char *data = field[4];
999
1000           /* Type 20: Notation data.  */
1001           /* Type 26: Policy URL.  */
1002           if (type == 20 || type == 26)
1003             {
1004               gpgme_sig_notation_t notation;
1005
1006               keysig = opd->tmp_keysig;
1007
1008               /* At this time, any error is serious.  */
1009               err = _gpgme_parse_notation (&notation, type, flags, len, data);
1010               if (err)
1011                 return err;
1012
1013               /* Add a new notation.  FIXME: Could be factored out.  */
1014               if (!keysig->notations)
1015                 keysig->notations = notation;
1016               if (keysig->_last_notation)
1017                 keysig->_last_notation->next = notation;
1018               keysig->_last_notation = notation;
1019             }
1020         }
1021
1022     case RT_NONE:
1023       /* Unknown record.  */
1024       break;
1025     }
1026   return 0;
1027 }
1028
1029
1030 void
1031 _gpgme_op_keylist_event_cb (void *data, gpgme_event_io_t type, void *type_data)
1032 {
1033   gpgme_error_t err;
1034   gpgme_ctx_t ctx = (gpgme_ctx_t) data;
1035   gpgme_key_t key = (gpgme_key_t) type_data;
1036   void *hook;
1037   op_data_t opd;
1038   struct key_queue_item_s *q, *q2;
1039
1040   assert (type == GPGME_EVENT_NEXT_KEY);
1041
1042   err = _gpgme_op_data_lookup (ctx, OPDATA_KEYLIST, &hook, -1, NULL);
1043   opd = hook;
1044   if (err)
1045     return;
1046
1047   q = malloc (sizeof *q);
1048   if (!q)
1049     {
1050       gpgme_key_unref (key);
1051       /* FIXME       return GPGME_Out_Of_Core; */
1052       return;
1053     }
1054   q->key = key;
1055   q->next = NULL;
1056   /* FIXME: Use a tail pointer?  */
1057   if (!(q2 = opd->key_queue))
1058     opd->key_queue = q;
1059   else
1060     {
1061       for (; q2->next; q2 = q2->next)
1062         ;
1063       q2->next = q;
1064     }
1065   opd->key_cond = 1;
1066 }
1067
1068
1069 /* Start a keylist operation within CTX, searching for keys which
1070    match PATTERN.  If SECRET_ONLY is true, only secret keys are
1071    returned.  */
1072 gpgme_error_t
1073 gpgme_op_keylist_start (gpgme_ctx_t ctx, const char *pattern, int secret_only)
1074 {
1075   gpgme_error_t err;
1076   void *hook;
1077   op_data_t opd;
1078   int flags = 0;
1079
1080   TRACE_BEG2 (DEBUG_CTX, "gpgme_op_keylist_start", ctx,
1081               "pattern=%s, secret_only=%i", pattern, secret_only);
1082
1083   if (!ctx)
1084     return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
1085
1086   err = _gpgme_op_reset (ctx, 2);
1087   if (err)
1088     return TRACE_ERR (err);
1089
1090   err = _gpgme_op_data_lookup (ctx, OPDATA_KEYLIST, &hook,
1091                                sizeof (*opd), release_op_data);
1092   opd = hook;
1093   if (err)
1094     return TRACE_ERR (err);
1095
1096   _gpgme_engine_set_status_handler (ctx->engine, keylist_status_handler, ctx);
1097
1098   err = _gpgme_engine_set_colon_line_handler (ctx->engine,
1099                                               keylist_colon_handler, ctx);
1100   if (err)
1101     return TRACE_ERR (err);
1102
1103   if (ctx->offline)
1104     flags |= GPGME_ENGINE_FLAG_OFFLINE;
1105
1106   err = _gpgme_engine_op_keylist (ctx->engine, pattern, secret_only,
1107                                   ctx->keylist_mode, flags);
1108   return TRACE_ERR (err);
1109 }
1110
1111
1112 /* Start a keylist operation within CTX, searching for keys which
1113    match PATTERN.  If SECRET_ONLY is true, only secret keys are
1114    returned.  */
1115 gpgme_error_t
1116 gpgme_op_keylist_ext_start (gpgme_ctx_t ctx, const char *pattern[],
1117                             int secret_only, int reserved)
1118 {
1119   gpgme_error_t err;
1120   void *hook;
1121   op_data_t opd;
1122   int flags = 0;
1123
1124   TRACE_BEG2 (DEBUG_CTX, "gpgme_op_keylist_ext_start", ctx,
1125               "secret_only=%i, reserved=0x%x", secret_only, reserved);
1126
1127   if (!ctx)
1128     return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
1129
1130   err = _gpgme_op_reset (ctx, 2);
1131   if (err)
1132     return TRACE_ERR (err);
1133
1134   err = _gpgme_op_data_lookup (ctx, OPDATA_KEYLIST, &hook,
1135                                sizeof (*opd), release_op_data);
1136   opd = hook;
1137   if (err)
1138     return TRACE_ERR (err);
1139
1140   _gpgme_engine_set_status_handler (ctx->engine, keylist_status_handler, ctx);
1141   err = _gpgme_engine_set_colon_line_handler (ctx->engine,
1142                                               keylist_colon_handler, ctx);
1143   if (err)
1144     return TRACE_ERR (err);
1145
1146   if (ctx->offline)
1147     flags |= GPGME_ENGINE_FLAG_OFFLINE;
1148
1149   err = _gpgme_engine_op_keylist_ext (ctx->engine, pattern, secret_only,
1150                                       reserved, ctx->keylist_mode,
1151                                       flags);
1152   return TRACE_ERR (err);
1153 }
1154
1155
1156 /* Start a keylist operation within CTX to show keys contained
1157  * in DATA.  */
1158 gpgme_error_t
1159 gpgme_op_keylist_from_data_start (gpgme_ctx_t ctx, gpgme_data_t data,
1160                                   int reserved)
1161 {
1162   gpgme_error_t err;
1163   void *hook;
1164   op_data_t opd;
1165
1166   TRACE_BEG (DEBUG_CTX, "gpgme_op_keylist_from_data_start", ctx);
1167
1168   if (!ctx || !data || reserved)
1169     return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
1170
1171   err = _gpgme_op_reset (ctx, 2);
1172   if (err)
1173     return TRACE_ERR (err);
1174
1175   err = _gpgme_op_data_lookup (ctx, OPDATA_KEYLIST, &hook,
1176                                sizeof (*opd), release_op_data);
1177   opd = hook;
1178   if (err)
1179     return TRACE_ERR (err);
1180
1181   _gpgme_engine_set_status_handler (ctx->engine, keylist_status_handler, ctx);
1182   err = _gpgme_engine_set_colon_line_handler (ctx->engine,
1183                                               keylist_colon_handler, ctx);
1184   if (err)
1185     return TRACE_ERR (err);
1186
1187   err = _gpgme_engine_op_keylist_data (ctx->engine, data);
1188   return TRACE_ERR (err);
1189 }
1190
1191
1192 /* Return the next key from the keylist in R_KEY.  */
1193 gpgme_error_t
1194 gpgme_op_keylist_next (gpgme_ctx_t ctx, gpgme_key_t *r_key)
1195 {
1196   gpgme_error_t err;
1197   struct key_queue_item_s *queue_item;
1198   void *hook;
1199   op_data_t opd;
1200
1201   TRACE_BEG (DEBUG_CTX, "gpgme_op_keylist_next", ctx);
1202
1203   if (!ctx || !r_key)
1204     return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
1205   *r_key = NULL;
1206   if (!ctx)
1207     return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
1208
1209   err = _gpgme_op_data_lookup (ctx, OPDATA_KEYLIST, &hook, -1, NULL);
1210   opd = hook;
1211   if (err)
1212     return TRACE_ERR (err);
1213   if (opd == NULL)
1214     return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
1215
1216   if (!opd->key_queue)
1217     {
1218       err = _gpgme_wait_on_condition (ctx, &opd->key_cond, NULL);
1219       if (err)
1220         return TRACE_ERR (err);
1221
1222       if (!opd->key_cond)
1223         return TRACE_ERR (opd->keydb_search_err? opd->keydb_search_err
1224                           /**/                 : gpg_error (GPG_ERR_EOF));
1225
1226       opd->key_cond = 0;
1227       assert (opd->key_queue);
1228     }
1229   queue_item = opd->key_queue;
1230   opd->key_queue = queue_item->next;
1231   if (!opd->key_queue)
1232     opd->key_cond = 0;
1233
1234   *r_key = queue_item->key;
1235   free (queue_item);
1236
1237   return TRACE_SUC2 ("key=%p (%s)", *r_key,
1238                      ((*r_key)->subkeys && (*r_key)->subkeys->fpr) ?
1239                      (*r_key)->subkeys->fpr : "invalid");
1240 }
1241
1242
1243 /* Terminate a pending keylist operation within CTX.  */
1244 gpgme_error_t
1245 gpgme_op_keylist_end (gpgme_ctx_t ctx)
1246 {
1247   TRACE (DEBUG_CTX, "gpgme_op_keylist_end", ctx);
1248
1249   if (!ctx)
1250     return gpg_error (GPG_ERR_INV_VALUE);
1251
1252   return 0;
1253 }
1254
1255 \f
1256 /* Get the key with the fingerprint FPR from the crypto backend.  If
1257    SECRET is true, get the secret key.  */
1258 gpgme_error_t
1259 gpgme_get_key (gpgme_ctx_t ctx, const char *fpr, gpgme_key_t *r_key,
1260                int secret)
1261 {
1262   gpgme_ctx_t listctx;
1263   gpgme_error_t err;
1264   gpgme_key_t result, key;
1265
1266   TRACE_BEG2 (DEBUG_CTX, "gpgme_get_key", ctx,
1267               "fpr=%s, secret=%i", fpr, secret);
1268
1269   if (!ctx || !r_key || !fpr)
1270     return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
1271
1272   *r_key = NULL;
1273
1274   if (strlen (fpr) < 8) /* We have at least a key ID.  */
1275     return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
1276
1277   /* FIXME: We use our own context because we have to avoid the user's
1278      I/O callback handlers.  */
1279   err = gpgme_new (&listctx);
1280   if (err)
1281     return TRACE_ERR (err);
1282   {
1283     gpgme_protocol_t proto;
1284     gpgme_engine_info_t info;
1285
1286     /* Clone the relevant state.  */
1287     proto = gpgme_get_protocol (ctx);
1288     gpgme_set_protocol (listctx, proto);
1289     gpgme_set_keylist_mode (listctx, gpgme_get_keylist_mode (ctx));
1290     info = gpgme_ctx_get_engine_info (ctx);
1291     while (info && info->protocol != proto)
1292       info = info->next;
1293     if (info)
1294       gpgme_ctx_set_engine_info (listctx, proto,
1295                                  info->file_name, info->home_dir);
1296   }
1297
1298   err = gpgme_op_keylist_start (listctx, fpr, secret);
1299   if (!err)
1300     err = gpgme_op_keylist_next (listctx, &result);
1301   if (!err)
1302     {
1303     try_next_key:
1304       err = gpgme_op_keylist_next (listctx, &key);
1305       if (gpgme_err_code (err) == GPG_ERR_EOF)
1306         err = 0;
1307       else
1308         {
1309           if (!err
1310               && result && result->subkeys && result->subkeys->fpr
1311               && key && key->subkeys && key->subkeys->fpr
1312               && !strcmp (result->subkeys->fpr, key->subkeys->fpr))
1313             {
1314               /* The fingerprint is identical.  We assume that this is
1315                  the same key and don't mark it as an ambiguous.  This
1316                  problem may occur with corrupted keyrings and has
1317                  been noticed often with gpgsm.  In fact gpgsm uses a
1318                  similar hack to sort out such duplicates but it can't
1319                  do that while listing keys.  */
1320               gpgme_key_unref (key);
1321               goto try_next_key;
1322             }
1323           if (!err)
1324             {
1325               gpgme_key_unref (key);
1326               err = gpg_error (GPG_ERR_AMBIGUOUS_NAME);
1327             }
1328           gpgme_key_unref (result);
1329           result = NULL;
1330         }
1331     }
1332   gpgme_release (listctx);
1333   if (! err)
1334     {
1335       *r_key = result;
1336       TRACE_LOG2 ("key=%p (%s)", *r_key,
1337                   ((*r_key)->subkeys && (*r_key)->subkeys->fpr) ?
1338                   (*r_key)->subkeys->fpr : "invalid");
1339     }
1340   return TRACE_ERR (err);
1341 }