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