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