agent: Stop scdaemon after reload when disable_scdaemon.
[gnupg.git] / tools / card-keys.c
1 /* card-keys.c - OpenPGP and CMS related functions for gpg-card
2  * Copyright (C) 2019 g10 Code GmbH
3  *
4  * This file is part of GnuPG.
5  *
6  * GnuPG is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * GnuPG is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, see <https://www.gnu.org/licenses/>.
18  * SPDX-License-Identifier: GPL-3.0-or-later
19  */
20
21 #include <config.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25
26 #include "../common/util.h"
27 #include "../common/i18n.h"
28 #include "../common/ccparray.h"
29 #include "../common/exectool.h"
30 #include "../common/openpgpdefs.h"
31 #include "gpg-card.h"
32
33
34 /* It is quite common that all keys of an OpenPGP card belong to the
35  * the same OpenPGP keyblock.  To avoid running several queries
36  * despite that we already got the information with the previous
37  * keyblock, we keep a small cache of of previous done queries.  */
38 static struct
39 {
40   unsigned int lru;
41   keyblock_t keyblock;
42 } keyblock_cache[5];
43
44
45
46 /* Helper for release_keyblock.  */
47 static void
48 do_release_keyblock (keyblock_t keyblock)
49 {
50   pubkey_t pubkey;
51   userid_t uid;
52
53   while (keyblock)
54     {
55       keyblock_t keyblocknext = keyblock->next;
56       pubkey = keyblock->keys;
57       while (pubkey)
58         {
59           pubkey_t pubkeynext = pubkey->next;
60           xfree (pubkey);
61           pubkey = pubkeynext;
62         }
63       uid = keyblock->uids;
64       while (uid)
65         {
66           userid_t uidnext = uid->next;
67           xfree (uid->value);
68           xfree (uid);
69           uid = uidnext;
70         }
71       xfree (keyblock);
72       keyblock = keyblocknext;
73     }
74 }
75
76
77 /* Release a keyblock object.  */
78 void
79 release_keyblock (keyblock_t keyblock)
80 {
81   static unsigned int lru_counter;
82   unsigned int lru;
83   int i, lru_idx;
84
85   if (!keyblock)
86     return;
87
88   lru = (unsigned int)(-1);
89   lru_idx = 0;
90   for (i=0; i < DIM (keyblock_cache); i++)
91     {
92       if (!keyblock_cache[i].keyblock)
93         {
94           keyblock_cache[i].keyblock = keyblock;
95           keyblock_cache[i].lru = ++lru_counter;
96           goto leave;
97         }
98       if (keyblock_cache[i].lru < lru)
99         {
100           lru = keyblock_cache[i].lru;
101           lru_idx = i;
102         }
103     }
104
105   /* No free slot.  Replace one. */
106   do_release_keyblock (keyblock_cache[lru_idx].keyblock);
107   keyblock_cache[lru_idx].keyblock = keyblock;
108   keyblock_cache[lru_idx].lru = ++lru_counter;
109
110  leave:
111   if (!lru_counter)
112     {
113       /* Wrapped around.  We simply clear the entire cache. */
114       flush_keyblock_cache ();
115     }
116 }
117
118
119 /* Flush the enire keyblock cache.  */
120 void
121 flush_keyblock_cache (void)
122 {
123   int i;
124
125   for (i=0; i < DIM (keyblock_cache); i++)
126     {
127       do_release_keyblock (keyblock_cache[i].keyblock);
128       keyblock_cache[i].keyblock = NULL;
129     }
130 }
131
132
133
134 /* Object to communicate with the status_cb. */
135 struct status_cb_s
136 {
137   const char *pgm; /* Name of the program for debug purposes. */
138   int no_pubkey;   /* Result flag.  */
139 };
140
141
142 /* Status callback helper for the exec functions.  */
143 static void
144 status_cb (void *opaque, const char *keyword, char *args)
145 {
146   struct status_cb_s *c = opaque;
147   const char *s;
148
149   if (DBG_EXTPROG)
150     log_debug ("%s: status: %s %s\n", c->pgm, keyword, args);
151
152   if (!strcmp (keyword, "ERROR")
153       && (s=has_leading_keyword (args, "keylist.getkey"))
154       && gpg_err_code (atoi (s)) == GPG_ERR_NO_PUBKEY)
155     {
156       /* No public key was found.  gpg terminates with an error in
157        * this case and we can't change that behaviour.  Instead we
158        * detect this status and carry that error forward. */
159       c->no_pubkey = 1;
160     }
161
162 }
163
164
165 /* Helper for get_matching_keys to parse "pub" style records.  */
166 static gpg_error_t
167 parse_key_record (char **fields, int nfields, pubkey_t *r_pubkey)
168 {
169   pubkey_t pubkey;
170
171   (void)fields; /* Not yet used.  */
172   (void)nfields;
173
174   pubkey = xtrycalloc (1, sizeof *pubkey);
175   if (!pubkey)
176     return gpg_error_from_syserror ();
177   *r_pubkey = pubkey;
178   return 0;
179 }
180
181
182 /* Run gpg or gpgsm to get a list of all keys matching the 20 byte
183  * KEYGRIP.  PROTOCOL is one of or a combination of
184  * GNUPG_PROTOCOL_OPENPGP and GNUPG_PROTOCOL_CMS.  On success a new
185  * keyblock is stored at R_KEYBLOCK; on error NULL is stored there. */
186 gpg_error_t
187 get_matching_keys (const unsigned char *keygrip, int protocol,
188                    keyblock_t *r_keyblock)
189 {
190   gpg_error_t err;
191   ccparray_t ccp;
192   const char **argv;
193   estream_t listing;
194   char hexgrip[1 + (2*KEYGRIP_LEN) + 1];
195   char *line = NULL;
196   size_t length_of_line = 0;
197   size_t maxlen;
198   ssize_t len;
199   char **fields = NULL;
200   int nfields;
201   int first_seen;
202   int i;
203   keyblock_t keyblock_head, *keyblock_tail, kb;
204   pubkey_t pubkey, pk;
205   size_t n;
206   struct status_cb_s status_cb_parm;
207
208   *r_keyblock = NULL;
209
210   keyblock_head = NULL;
211   keyblock_tail = &keyblock_head;
212   kb = NULL;
213
214   /* Shortcut to run a listing on both protocols.  */
215   if ((protocol & GNUPG_PROTOCOL_OPENPGP) && (protocol & GNUPG_PROTOCOL_CMS))
216     {
217       err = get_matching_keys (keygrip, GNUPG_PROTOCOL_OPENPGP, &kb);
218       if (!err || gpg_err_code (err) == GPG_ERR_NO_PUBKEY)
219         {
220           if (!err)
221             {
222               *keyblock_tail = kb;
223               keyblock_tail = &kb->next;
224               kb = NULL;
225             }
226           err = get_matching_keys (keygrip, GNUPG_PROTOCOL_CMS, &kb);
227           if (!err)
228             {
229               *keyblock_tail = kb;
230               keyblock_tail = &kb->next;
231               kb = NULL;
232             }
233           else if (gpg_err_code (err) == GPG_ERR_NO_PUBKEY)
234             err = 0;
235         }
236       if (err)
237         release_keyblock (keyblock_head);
238       else
239         *r_keyblock = keyblock_head;
240       return err;
241     }
242
243   /* Check that we have only one protocol.  */
244   if (protocol != GNUPG_PROTOCOL_OPENPGP && protocol != GNUPG_PROTOCOL_CMS)
245     return gpg_error (GPG_ERR_UNSUPPORTED_PROTOCOL);
246
247   /* Try to get it from our cache. */
248   for (i=0; i < DIM (keyblock_cache); i++)
249     for (kb = keyblock_cache[i].keyblock; kb; kb = kb->next)
250       if (kb->protocol == protocol)
251         for (pk = kb->keys; pk; pk = pk->next)
252           if (pk->grip_valid && !memcmp (pk->grip, keygrip, KEYGRIP_LEN))
253             {
254               *r_keyblock = keyblock_cache[i].keyblock;
255               keyblock_cache[i].keyblock = NULL;
256               return 0;
257             }
258
259   /* Open a memory stream.  */
260   listing = es_fopenmem (0, "w+b");
261   if (!listing)
262     {
263       err = gpg_error_from_syserror ();
264       log_error ("error allocating memory buffer: %s\n", gpg_strerror (err));
265       return err;
266     }
267
268   status_cb_parm.pgm = protocol == GNUPG_PROTOCOL_OPENPGP? "gpg":"gpgsm";
269   status_cb_parm.no_pubkey = 0;
270
271   hexgrip[0] = '&';
272   bin2hex (keygrip, KEYGRIP_LEN, hexgrip+1);
273
274   ccparray_init (&ccp, 0);
275
276   if (opt.verbose > 1 || DBG_EXTPROG)
277     ccparray_put (&ccp, "--verbose");
278   else
279     ccparray_put (&ccp, "--quiet");
280   ccparray_put (&ccp, "--no-options");
281   ccparray_put (&ccp, "--batch");
282   ccparray_put (&ccp, "--status-fd=2");
283   ccparray_put (&ccp, "--with-colons");
284   ccparray_put (&ccp, "--with-keygrip");
285   ccparray_put (&ccp, "--list-keys");
286   ccparray_put (&ccp, hexgrip);
287
288   ccparray_put (&ccp, NULL);
289   argv = ccparray_get (&ccp, NULL);
290   if (!argv)
291     {
292       err = gpg_error_from_syserror ();
293       goto leave;
294     }
295   err = gnupg_exec_tool_stream (protocol == GNUPG_PROTOCOL_OPENPGP?
296                                 opt.gpg_program : opt.gpgsm_program,
297                                 argv, NULL, NULL, listing, status_cb,
298                                 &status_cb_parm);
299   if (err)
300     {
301       if (status_cb_parm.no_pubkey)
302         err = gpg_error (GPG_ERR_NO_PUBKEY);
303       else if (gpg_err_code (err) != GPG_ERR_GENERAL)
304         log_error ("key listing failed: %s\n", gpg_strerror (err));
305       goto leave;
306     }
307
308   es_rewind (listing);
309   first_seen = 0;
310   maxlen = 8192; /* Set limit large enough for all escaped UIDs.  */
311   while ((len = es_read_line (listing, &line, &length_of_line, &maxlen)) > 0)
312     {
313       if (!maxlen)
314         {
315           log_error ("received line too long\n");
316           err = gpg_error (GPG_ERR_LINE_TOO_LONG);
317           goto leave;
318         }
319       /* Strip newline and carriage return, if present.  */
320       while (len > 0 && (line[len - 1] == '\n' || line[len - 1] == '\r'))
321         line[--len] = '\0';
322
323       xfree (fields);
324       fields = strtokenize (line, ":");
325       if (!fields)
326         {
327           err = gpg_error_from_syserror ();
328           log_error ("strtokenize failed: %s\n", gpg_strerror (err));
329           goto leave;
330         }
331       for (nfields = 0; fields[nfields]; nfields++)
332         ;
333       if (!nfields)
334         {
335           err = gpg_error (GPG_ERR_INV_ENGINE);
336           goto leave;
337         }
338
339       /* Skip over all records until we reach a pub or sec.  */
340       if (!first_seen
341           && (!strcmp (fields[0], "pub") || !strcmp (fields[0], "sec")
342               || !strcmp (fields[0], "crt") || !strcmp (fields[0], "crs")))
343         first_seen = 1;
344       if (!first_seen)
345         continue;
346
347       if (!strcmp (fields[0], "pub") || !strcmp (fields[0], "sec")
348           || !strcmp (fields[0], "crt") || !strcmp (fields[0], "crs"))
349         {
350           if (kb)  /* Finish the current keyblock.  */
351             {
352               *keyblock_tail = kb;
353               keyblock_tail = &kb->next;
354             }
355           kb = xtrycalloc (1, sizeof *kb);
356           if (!kb)
357             {
358               err = gpg_error_from_syserror ();
359               goto leave;
360             }
361           kb->protocol = protocol;
362           err = parse_key_record (fields, nfields, &pubkey);
363           if (err)
364             goto leave;
365           kb->keys = pubkey;
366           pubkey = NULL;
367         }
368       else if (!strcmp (fields[0], "sub") || !strcmp (fields[0], "ssb"))
369         {
370           log_assert (kb && kb->keys);
371           err = parse_key_record (fields, nfields, &pubkey);
372           if (err)
373             goto leave;
374           for (pk = kb->keys; pk->next; pk = pk->next)
375                 ;
376           pk->next = pubkey;
377           pubkey = NULL;
378         }
379       else if (!strcmp (fields[0], "fpr") && nfields > 9)
380         {
381           log_assert (kb && kb->keys);
382           n = strlen (fields[9]);
383           if (n != 64 && n != 40 && n != 32)
384             {
385               log_debug ("bad length (%zu) in fpr record\n", n);
386               err = gpg_error (GPG_ERR_INV_ENGINE);
387               goto leave;
388             }
389           n /= 2;
390
391           for (pk = kb->keys; pk->next; pk = pk->next)
392             ;
393           if (pk->fprlen)
394             {
395               log_debug ("too many fpr records\n");
396               err = gpg_error (GPG_ERR_INV_ENGINE);
397               goto leave;
398             }
399           log_assert (n <= sizeof pk->fpr);
400           pk->fprlen = n;
401           if (hex2bin (fields[9], pk->fpr, n) < 0)
402             {
403               log_debug ("bad chars in fpr record\n");
404               err = gpg_error (GPG_ERR_INV_ENGINE);
405               goto leave;
406             }
407         }
408       else if (!strcmp (fields[0], "grp") && nfields > 9)
409         {
410           log_assert (kb && kb->keys);
411           n = strlen (fields[9]);
412           if (n != 2*KEYGRIP_LEN)
413             {
414               log_debug ("bad length (%zu) in grp record\n", n);
415               err = gpg_error (GPG_ERR_INV_ENGINE);
416               goto leave;
417             }
418           n /= 2;
419
420           for (pk = kb->keys; pk->next; pk = pk->next)
421             ;
422           if (pk->grip_valid)
423             {
424               log_debug ("too many grp records\n");
425               err = gpg_error (GPG_ERR_INV_ENGINE);
426               goto leave;
427             }
428           if (hex2bin (fields[9], pk->grip, KEYGRIP_LEN) < 0)
429             {
430               log_debug ("bad chars in fpr record\n");
431               err = gpg_error (GPG_ERR_INV_ENGINE);
432               goto leave;
433             }
434           pk->grip_valid = 1;
435           if (!memcmp (pk->grip, keygrip, KEYGRIP_LEN))
436             pk->requested = 1;
437         }
438       else if (!strcmp (fields[0], "uid") && nfields > 9)
439         {
440           userid_t uid, u;
441
442           uid = xtrycalloc (1, sizeof *uid);
443           if (!uid)
444             {
445               err = gpg_error_from_syserror ();
446               goto leave;
447             }
448           uid->value = decode_c_string (fields[9]);
449           if (!uid->value)
450             {
451               err = gpg_error_from_syserror ();
452               xfree (uid);
453               goto leave;
454             }
455           if (!kb->uids)
456             kb->uids = uid;
457           else
458             {
459               for (u = kb->uids; u->next; u = u->next)
460                 ;
461               u->next = uid;
462             }
463         }
464     }
465   if (len < 0 || es_ferror (listing))
466     {
467       err = gpg_error_from_syserror ();
468       log_error ("error reading memory stream\n");
469       goto leave;
470     }
471
472   if (kb) /* Finish the current keyblock.  */
473     {
474       *keyblock_tail = kb;
475       keyblock_tail = &kb->next;
476       kb = NULL;
477     }
478
479   if (!keyblock_head)
480     err = gpg_error (GPG_ERR_NO_PUBKEY);
481
482  leave:
483   if (err)
484     release_keyblock (keyblock_head);
485   else
486     *r_keyblock = keyblock_head;
487   xfree (kb);
488   xfree (fields);
489   es_free (line);
490   xfree (argv);
491   es_fclose (listing);
492   return err;
493 }
494
495
496 void
497 dump_keyblock (keyblock_t keyblock)
498 {
499   keyblock_t kb;
500   pubkey_t pubkey;
501   userid_t uid;
502
503   for (kb = keyblock; kb; kb = kb->next)
504     {
505       log_info ("%s key:\n",
506                  kb->protocol == GNUPG_PROTOCOL_OPENPGP? "OpenPGP":"X.509");
507       for (pubkey = kb->keys; pubkey; pubkey = pubkey->next)
508         {
509           log_info ("  grip: ");
510           if (pubkey->grip_valid)
511             log_printhex (pubkey->grip, KEYGRIP_LEN, NULL);
512           log_printf ("%s\n", pubkey->requested? " (*)":"");
513
514           log_info ("   fpr: ");
515           log_printhex (pubkey->fpr, pubkey->fprlen, "");
516         }
517       for (uid = kb->uids; uid; uid = uid->next)
518         {
519           log_info ("   uid: %s\n", uid->value);
520         }
521     }
522 }
523
524
525
526 gpg_error_t
527 test_get_matching_keys (const char *hexgrip)
528 {
529   gpg_error_t err;
530   unsigned char grip[KEYGRIP_LEN];
531   keyblock_t keyblock;
532
533   if (strlen (hexgrip) != 40)
534     {
535       log_error ("error: invalid keygrip\n");
536       return 0;
537     }
538   if (hex2bin (hexgrip, grip, sizeof grip) < 0)
539     {
540       log_error ("error: bad kegrip\n");
541       return 0;
542     }
543   err = get_matching_keys (grip,
544                            (GNUPG_PROTOCOL_OPENPGP | GNUPG_PROTOCOL_CMS),
545                            &keyblock);
546   if (err)
547     {
548       log_error ("get_matching_keys failed: %s\n", gpg_strerror (err));
549       return err;
550     }
551
552   dump_keyblock (keyblock);
553   release_keyblock (keyblock);
554   return 0;
555 }