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