scd:piv: Allow writecert to only write matching certs.
[gnupg.git] / scd / app.c
1 /* app.c - Application selection.
2  * Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
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  */
19
20 #include <config.h>
21 #include <errno.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <npth.h>
26
27 #include "scdaemon.h"
28 #include "../common/exechelp.h"
29 #include "app-common.h"
30 #include "iso7816.h"
31 #include "apdu.h"
32 #include "../common/tlv.h"
33
34 static npth_mutex_t app_list_lock;
35 static app_t app_top;
36 \f
37 static void
38 print_progress_line (void *opaque, const char *what, int pc, int cur, int tot)
39 {
40   ctrl_t ctrl = opaque;
41   char line[100];
42
43   if (ctrl)
44     {
45       snprintf (line, sizeof line, "%s %c %d %d", what, pc, cur, tot);
46       send_status_direct (ctrl, "PROGRESS", line);
47     }
48 }
49
50
51 /* Lock the reader SLOT.  This function shall be used right before
52    calling any of the actual application functions to serialize access
53    to the reader.  We do this always even if the reader is not
54    actually used.  This allows an actual connection to assume that it
55    never shares a reader (while performing one command).  Returns 0 on
56    success; only then the unlock_reader function must be called after
57    returning from the handler. */
58 static gpg_error_t
59 lock_app (app_t app, ctrl_t ctrl)
60 {
61   if (npth_mutex_lock (&app->lock))
62     {
63       gpg_error_t err = gpg_error_from_syserror ();
64       log_error ("failed to acquire APP lock for %p: %s\n",
65                  app, gpg_strerror (err));
66       return err;
67     }
68
69   apdu_set_progress_cb (app->slot, print_progress_line, ctrl);
70   apdu_set_prompt_cb (app->slot, popup_prompt, ctrl);
71
72   return 0;
73 }
74
75 /* Release a lock on the reader.  See lock_reader(). */
76 static void
77 unlock_app (app_t app)
78 {
79   apdu_set_progress_cb (app->slot, NULL, NULL);
80   apdu_set_prompt_cb (app->slot, NULL, NULL);
81
82   if (npth_mutex_unlock (&app->lock))
83     {
84       gpg_error_t err = gpg_error_from_syserror ();
85       log_error ("failed to release APP lock for %p: %s\n",
86                  app, gpg_strerror (err));
87     }
88 }
89
90
91 /* This function may be called to print information pertaining to the
92    current state of this module to the log. */
93 void
94 app_dump_state (void)
95 {
96   app_t a;
97
98   npth_mutex_lock (&app_list_lock);
99   for (a = app_top; a; a = a->next)
100     log_info ("app_dump_state: app=%p type='%s'\n", a, a->apptype);
101   npth_mutex_unlock (&app_list_lock);
102 }
103
104 /* Check whether the application NAME is allowed.  This does not mean
105    we have support for it though.  */
106 static int
107 is_app_allowed (const char *name)
108 {
109   strlist_t l;
110
111   for (l=opt.disabled_applications; l; l = l->next)
112     if (!strcmp (l->d, name))
113       return 0; /* no */
114   return 1; /* yes */
115 }
116
117
118 static gpg_error_t
119 check_conflict (app_t app, const char *name)
120 {
121   if (!app || !name || (app->apptype && !ascii_strcasecmp (app->apptype, name)))
122     return 0;
123
124   if (app->apptype && !strcmp (app->apptype, "UNDEFINED"))
125     return 0;
126
127   log_info ("application '%s' in use - can't switch\n",
128             app->apptype? app->apptype : "<null>");
129
130   return gpg_error (GPG_ERR_CONFLICT);
131 }
132
133 /* This function is used by the serialno command to check for an
134    application conflict which may appear if the serialno command is
135    used to request a specific application and the connection has
136    already done a select_application. */
137 gpg_error_t
138 check_application_conflict (const char *name, app_t app)
139 {
140   return check_conflict (app, name);
141 }
142
143
144 gpg_error_t
145 app_reset (app_t app, ctrl_t ctrl, int send_reset)
146 {
147   gpg_error_t err = 0;
148
149   if (send_reset)
150     {
151       int sw;
152
153       lock_app (app, ctrl);
154       sw = apdu_reset (app->slot);
155       if (sw)
156         err = gpg_error (GPG_ERR_CARD_RESET);
157
158       app->reset_requested = 1;
159       unlock_app (app);
160
161       scd_kick_the_loop ();
162       gnupg_sleep (1);
163     }
164   else
165     {
166       ctrl->app_ctx = NULL;
167       release_application (app, 0);
168     }
169
170   return err;
171 }
172
173 static gpg_error_t
174 app_new_register (int slot, ctrl_t ctrl, const char *name,
175                   int periodical_check_needed)
176 {
177   gpg_error_t err = 0;
178   app_t app = NULL;
179   unsigned char *result = NULL;
180   size_t resultlen;
181   int want_undefined;
182
183   /* Need to allocate a new one.  */
184   app = xtrycalloc (1, sizeof *app);
185   if (!app)
186     {
187       err = gpg_error_from_syserror ();
188       log_info ("error allocating context: %s\n", gpg_strerror (err));
189       return err;
190     }
191
192   app->slot = slot;
193   app->card_status = (unsigned int)-1;
194
195   if (npth_mutex_init (&app->lock, NULL))
196     {
197       err = gpg_error_from_syserror ();
198       log_error ("error initializing mutex: %s\n", gpg_strerror (err));
199       xfree (app);
200       return err;
201     }
202
203   err = lock_app (app, ctrl);
204   if (err)
205     {
206       xfree (app);
207       return err;
208     }
209
210   want_undefined = (name && !strcmp (name, "undefined"));
211
212   /* Try to read the GDO file first to get a default serial number.
213      We skip this if the undefined application has been requested. */
214   if (!want_undefined)
215     {
216       err = iso7816_select_file (slot, 0x3F00, 1);
217       if (gpg_err_code (err) == GPG_ERR_CARD)
218         {
219           /* Might be SW==0x7D00.  Let's test whether it is a Yubikey
220            * by selecting its manager application and then reading the
221            * config.  */
222           static char const yk_aid[] =
223             { 0xA0, 0x00, 0x00, 0x05, 0x27, 0x47, 0x11, 0x17 }; /*MGR*/
224           unsigned char *buf;
225           size_t buflen;
226           const unsigned char *s0, *s1;
227           size_t n;
228
229           if (!iso7816_select_application (slot, yk_aid, sizeof yk_aid,
230                                            0x0001)
231               && !iso7816_apdu_direct (slot, "\x00\x1d\x00\x00\x00", 5, 0,
232                                        NULL, &buf, &buflen))
233             {
234               app->cardtype = "yubikey";
235               if (opt.verbose)
236                 {
237                   log_info ("Yubico: config=");
238                   log_printhex (buf, buflen, "");
239                 }
240
241               /* We skip the first byte which seems to be the total
242                * length of the config data.  */
243               if (buflen > 1)
244                 {
245                   s0 = find_tlv (buf+1, buflen-1, 0x04, &n);  /* Form factor */
246                   if (s0 && n == 1)
247                     {
248                       s1 = find_tlv (buf+1, buflen-1, 0x02, &n);  /* Serial */
249                       if (s1 && n >= 4)
250                         {
251                           app->serialno = xtrymalloc (3 + 1 + n);
252                           if (app->serialno)
253                             {
254                               app->serialnolen = 3 + 1 + n;
255                               app->serialno[0] = 0xff;
256                               app->serialno[1] = 0x02;
257                               app->serialno[2] = 0x0;
258                               app->serialno[3] = *s0;
259                               memcpy (app->serialno + 4, s1, n);
260                               /* Note that we do not clear the error
261                                * so that no further serial number
262                                * testing is done.  After all we just
263                                * set the serial number.  */
264                             }
265                         }
266                     }
267                 }
268               xfree (buf);
269             }
270         }
271
272       if (!err)
273         err = iso7816_select_file (slot, 0x2F02, 0);
274       if (!err)
275         err = iso7816_read_binary (slot, 0, 0, &result, &resultlen);
276       if (!err)
277         {
278           size_t n;
279           const unsigned char *p;
280
281           p = find_tlv_unchecked (result, resultlen, 0x5A, &n);
282           if (p)
283             resultlen -= (p-result);
284           if (p && n > resultlen && n == 0x0d && resultlen+1 == n)
285             {
286               /* The object it does not fit into the buffer.  This is an
287                  invalid encoding (or the buffer is too short.  However, I
288                  have some test cards with such an invalid encoding and
289                  therefore I use this ugly workaround to return something
290                  I can further experiment with. */
291               log_info ("enabling BMI testcard workaround\n");
292               n--;
293             }
294
295           if (p && n <= resultlen)
296             {
297               /* The GDO file is pretty short, thus we simply reuse it for
298                  storing the serial number. */
299               memmove (result, p, n);
300               app->serialno = result;
301               app->serialnolen = n;
302               err = app_munge_serialno (app);
303               if (err)
304                 goto leave;
305             }
306           else
307             xfree (result);
308           result = NULL;
309         }
310     }
311
312   /* Figure out the application to use.  */
313   if (want_undefined)
314     {
315       /* We switch to the "undefined" application only if explicitly
316          requested.  */
317       app->apptype = "UNDEFINED";
318       /* Clear the error so that we don't run through the application
319        * selection chain.  */
320       err = 0;
321     }
322   else
323     {
324       /* For certain error codes, there is no need to try more.  */
325       if (gpg_err_code (err) == GPG_ERR_CARD_NOT_PRESENT
326           || gpg_err_code (err) == GPG_ERR_ENODEV)
327         goto leave;
328
329       /* Set a default error so that we run through the application
330        * selecion chain.  */
331       err = gpg_error (GPG_ERR_NOT_FOUND);
332     }
333
334   if (err && is_app_allowed ("openpgp")
335           && (!name || !strcmp (name, "openpgp")))
336     err = app_select_openpgp (app);
337   if (err && is_app_allowed ("piv") && (!name || !strcmp (name, "piv")))
338     err = app_select_piv (app);
339   if (err && is_app_allowed ("nks") && (!name || !strcmp (name, "nks")))
340     err = app_select_nks (app);
341   if (err && is_app_allowed ("p15") && (!name || !strcmp (name, "p15")))
342     err = app_select_p15 (app);
343   if (err && is_app_allowed ("geldkarte")
344       && (!name || !strcmp (name, "geldkarte")))
345     err = app_select_geldkarte (app);
346   if (err && is_app_allowed ("dinsig") && (!name || !strcmp (name, "dinsig")))
347     err = app_select_dinsig (app);
348   if (err && is_app_allowed ("sc-hsm") && (!name || !strcmp (name, "sc-hsm")))
349     err = app_select_sc_hsm (app);
350   if (err && name && gpg_err_code (err) != GPG_ERR_OBJ_TERM_STATE)
351     err = gpg_error (GPG_ERR_NOT_SUPPORTED);
352
353  leave:
354   if (err)
355     {
356       if (name)
357         log_info ("can't select application '%s': %s\n",
358                   name, gpg_strerror (err));
359       else
360         log_info ("no supported card application found: %s\n",
361                   gpg_strerror (err));
362       unlock_app (app);
363       xfree (app);
364       return err;
365     }
366
367   app->periodical_check_needed = periodical_check_needed;
368   app->next = app_top;
369   app_top = app;
370   unlock_app (app);
371   return 0;
372 }
373
374 /* If called with NAME as NULL, select the best fitting application
375    and return a context; otherwise select the application with NAME
376    and return a context.  Returns an error code and stores NULL at
377    R_APP if no application was found or no card is present. */
378 gpg_error_t
379 select_application (ctrl_t ctrl, const char *name, app_t *r_app,
380                     int scan, const unsigned char *serialno_bin,
381                     size_t serialno_bin_len)
382 {
383   gpg_error_t err = 0;
384   app_t a, a_prev = NULL;
385
386   *r_app = NULL;
387
388   npth_mutex_lock (&app_list_lock);
389
390   if (scan || !app_top)
391     {
392       struct dev_list *l;
393       int new_app = 0;
394
395       /* Scan the devices to find new device(s).  */
396       err = apdu_dev_list_start (opt.reader_port, &l);
397       if (err)
398         {
399           npth_mutex_unlock (&app_list_lock);
400           return err;
401         }
402
403       while (1)
404         {
405           int slot;
406           int periodical_check_needed_this;
407
408           slot = apdu_open_reader (l, !app_top);
409           if (slot < 0)
410             break;
411
412           periodical_check_needed_this = apdu_connect (slot);
413           if (periodical_check_needed_this < 0)
414             {
415               /* We close a reader with no card.  */
416               err = gpg_error (GPG_ERR_ENODEV);
417             }
418           else
419             {
420               err = app_new_register (slot, ctrl, name,
421                                       periodical_check_needed_this);
422               new_app++;
423             }
424
425           if (err)
426             apdu_close_reader (slot);
427         }
428
429       apdu_dev_list_finish (l);
430
431       /* If new device(s), kick the scdaemon loop.  */
432       if (new_app)
433         scd_kick_the_loop ();
434     }
435
436   for (a = app_top; a; a = a->next)
437     {
438       lock_app (a, ctrl);
439       if (serialno_bin == NULL)
440         break;
441       if (a->serialnolen == serialno_bin_len
442           && !memcmp (a->serialno, serialno_bin, a->serialnolen))
443         break;
444       unlock_app (a);
445       a_prev = a;
446     }
447
448   if (a)
449     {
450       err = check_conflict (a, name);
451       if (!err)
452         {
453           a->ref_count++;
454           *r_app = a;
455           if (a_prev)
456             {
457               a_prev->next = a->next;
458               a->next = app_top;
459               app_top = a;
460             }
461       }
462       unlock_app (a);
463     }
464   else
465     err = gpg_error (GPG_ERR_ENODEV);
466
467   npth_mutex_unlock (&app_list_lock);
468
469   return err;
470 }
471
472
473 char *
474 get_supported_applications (void)
475 {
476   const char *list[] = {
477     "openpgp",
478     "piv",
479     "nks",
480     "p15",
481     "geldkarte",
482     "dinsig",
483     "sc-hsm",
484     /* Note: "undefined" is not listed here because it needs special
485        treatment by the client.  */
486     NULL
487   };
488   int idx;
489   size_t nbytes;
490   char *buffer, *p;
491
492   for (nbytes=1, idx=0; list[idx]; idx++)
493     nbytes += strlen (list[idx]) + 1 + 1;
494
495   buffer = xtrymalloc (nbytes);
496   if (!buffer)
497     return NULL;
498
499   for (p=buffer, idx=0; list[idx]; idx++)
500     if (is_app_allowed (list[idx]))
501       p = stpcpy (stpcpy (p, list[idx]), ":\n");
502   *p = 0;
503
504   return buffer;
505 }
506
507
508 /* Deallocate the application.  */
509 static void
510 deallocate_app (app_t app)
511 {
512   app_t a, a_prev = NULL;
513
514   for (a = app_top; a; a = a->next)
515     if (a == app)
516       {
517         if (a_prev == NULL)
518           app_top = a->next;
519         else
520           a_prev->next = a->next;
521         break;
522       }
523     else
524       a_prev = a;
525
526   if (app->ref_count)
527     log_error ("trying to release context used yet (%d)\n", app->ref_count);
528
529   if (app->fnc.deinit)
530     {
531       app->fnc.deinit (app);
532       app->fnc.deinit = NULL;
533     }
534
535   xfree (app->serialno);
536
537   unlock_app (app);
538   xfree (app);
539 }
540
541 /* Free the resources associated with the application APP.  APP is
542    allowed to be NULL in which case this is a no-op.  Note that we are
543    using reference counting to track the users of the application and
544    actually deferring the deallocation to allow for a later reuse by
545    a new connection. */
546 void
547 release_application (app_t app, int locked_already)
548 {
549   if (!app)
550     return;
551
552   /* We don't deallocate app here.  Instead, we keep it.  This is
553      useful so that a card does not get reset even if only one session
554      is using the card - this way the PIN cache and other cached data
555      are preserved.  */
556
557   if (!locked_already)
558     lock_app (app, NULL);
559
560   if (!app->ref_count)
561     log_bug ("trying to release an already released context\n");
562
563   --app->ref_count;
564   if (!locked_already)
565     unlock_app (app);
566 }
567
568
569
570 /* The serial number may need some cosmetics.  Do it here.  This
571    function shall only be called once after a new serial number has
572    been put into APP->serialno.
573
574    Prefixes we use:
575
576      FF 00 00 = For serial numbers starting with an FF
577      FF 01 00 = Some german p15 cards return an empty serial number so the
578                 serial number from the EF(TokenInfo) is used instead.
579      FF 02 00 = Serial number from Yubikey config
580      FF 7F 00 = No serialno.
581
582      All other serial number not starting with FF are used as they are.
583 */
584 gpg_error_t
585 app_munge_serialno (app_t app)
586 {
587   if (app->serialnolen && app->serialno[0] == 0xff)
588     {
589       /* The serial number starts with our special prefix.  This
590          requires that we put our default prefix "FF0000" in front. */
591       unsigned char *p = xtrymalloc (app->serialnolen + 3);
592       if (!p)
593         return gpg_error_from_syserror ();
594       memcpy (p, "\xff\0", 3);
595       memcpy (p+3, app->serialno, app->serialnolen);
596       app->serialnolen += 3;
597       xfree (app->serialno);
598       app->serialno = p;
599     }
600   else if (!app->serialnolen)
601     {
602       unsigned char *p = xtrymalloc (3);
603       if (!p)
604         return gpg_error_from_syserror ();
605       memcpy (p, "\xff\x7f", 3);
606       app->serialnolen = 3;
607       xfree (app->serialno);
608       app->serialno = p;
609     }
610   return 0;
611 }
612
613
614
615 /* Retrieve the serial number of the card.  The serial number is
616    returned as a malloced string (hex encoded) in SERIAL.  Caller must
617    free SERIAL unless the function returns an error.  */
618 char *
619 app_get_serialno (app_t app)
620 {
621   char *serial;
622
623   if (!app)
624     return NULL;
625
626   if (!app->serialnolen)
627     serial = xtrystrdup ("FF7F00");
628   else
629     serial = bin2hex (app->serialno, app->serialnolen, NULL);
630
631   return serial;
632 }
633
634
635 /* Write out the application specifig status lines for the LEARN
636    command. */
637 gpg_error_t
638 app_write_learn_status (app_t app, ctrl_t ctrl, unsigned int flags)
639 {
640   gpg_error_t err;
641
642   if (!app)
643     return gpg_error (GPG_ERR_INV_VALUE);
644   if (!app->fnc.learn_status)
645     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
646
647   /* We do not send CARD and APPTYPE if only keypairinfo is requested.  */
648   if (app->cardtype && !(flags & 1))
649     send_status_direct (ctrl, "CARDTYPE", app->cardtype);
650   if (app->apptype && !(flags & 1))
651     send_status_direct (ctrl, "APPTYPE", app->apptype);
652
653   err = lock_app (app, ctrl);
654   if (err)
655     return err;
656   err = app->fnc.learn_status (app, ctrl, flags);
657   unlock_app (app);
658   return err;
659 }
660
661
662 /* Read the certificate with id CERTID (as returned by learn_status in
663    the CERTINFO status lines) and return it in the freshly allocated
664    buffer put into CERT and the length of the certificate put into
665    CERTLEN. */
666 gpg_error_t
667 app_readcert (app_t app, ctrl_t ctrl, const char *certid,
668               unsigned char **cert, size_t *certlen)
669 {
670   gpg_error_t err;
671
672   if (!app)
673     return gpg_error (GPG_ERR_INV_VALUE);
674   if (!app->ref_count)
675     return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
676   if (!app->fnc.readcert)
677     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
678   err = lock_app (app, ctrl);
679   if (err)
680     return err;
681   err = app->fnc.readcert (app, certid, cert, certlen);
682   unlock_app (app);
683   return err;
684 }
685
686
687 /* Read the key with ID KEYID.  On success a canonical encoded
688    S-expression with the public key will get stored at PK and its
689    length (for assertions) at PKLEN; the caller must release that
690    buffer. On error NULL will be stored at PK and PKLEN and an error
691    code returned.
692
693    This function might not be supported by all applications.  */
694 gpg_error_t
695 app_readkey (app_t app, ctrl_t ctrl, const char *keyid,
696              unsigned char **pk, size_t *pklen)
697 {
698   gpg_error_t err;
699
700   if (pk)
701     *pk = NULL;
702   if (pklen)
703     *pklen = 0;
704
705   if (!app || !keyid || !pk || !pklen)
706     return gpg_error (GPG_ERR_INV_VALUE);
707   if (!app->ref_count)
708     return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
709   if (!app->fnc.readkey)
710     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
711   err = lock_app (app, ctrl);
712   if (err)
713     return err;
714   err= app->fnc.readkey (app, keyid, pk, pklen);
715   unlock_app (app);
716   return err;
717 }
718
719
720 /* Perform a GETATTR operation.  */
721 gpg_error_t
722 app_getattr (app_t app, ctrl_t ctrl, const char *name)
723 {
724   gpg_error_t err;
725
726   if (!app || !name || !*name)
727     return gpg_error (GPG_ERR_INV_VALUE);
728   if (!app->ref_count)
729     return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
730
731   if (app->cardtype && name && !strcmp (name, "CARDTYPE"))
732     {
733       send_status_direct (ctrl, "CARDTYPE", app->cardtype);
734       return 0;
735     }
736   if (app->apptype && name && !strcmp (name, "APPTYPE"))
737     {
738       send_status_direct (ctrl, "APPTYPE", app->apptype);
739       return 0;
740     }
741   if (name && !strcmp (name, "SERIALNO"))
742     {
743       char *serial;
744
745       serial = app_get_serialno (app);
746       if (!serial)
747         return gpg_error (GPG_ERR_INV_VALUE);
748
749       send_status_direct (ctrl, "SERIALNO", serial);
750       xfree (serial);
751       return 0;
752     }
753
754   if (!app->fnc.getattr)
755     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
756   err = lock_app (app, ctrl);
757   if (err)
758     return err;
759   err = app->fnc.getattr (app, ctrl, name);
760   unlock_app (app);
761   return err;
762 }
763
764 /* Perform a SETATTR operation.  */
765 gpg_error_t
766 app_setattr (app_t app, ctrl_t ctrl, const char *name,
767              gpg_error_t (*pincb)(void*, const char *, char **),
768              void *pincb_arg,
769              const unsigned char *value, size_t valuelen)
770 {
771   gpg_error_t err;
772
773   if (!app || !name || !*name || !value)
774     return gpg_error (GPG_ERR_INV_VALUE);
775   if (!app->ref_count)
776     return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
777   if (!app->fnc.setattr)
778     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
779   err = lock_app (app, ctrl);
780   if (err)
781     return err;
782   err = app->fnc.setattr (app, name, pincb, pincb_arg, value, valuelen);
783   unlock_app (app);
784   return err;
785 }
786
787 /* Create the signature and return the allocated result in OUTDATA.
788    If a PIN is required the PINCB will be used to ask for the PIN; it
789    should return the PIN in an allocated buffer and put it into PIN.  */
790 gpg_error_t
791 app_sign (app_t app, ctrl_t ctrl, const char *keyidstr, int hashalgo,
792           gpg_error_t (*pincb)(void*, const char *, char **),
793           void *pincb_arg,
794           const void *indata, size_t indatalen,
795           unsigned char **outdata, size_t *outdatalen )
796 {
797   gpg_error_t err;
798
799   if (!app || !indata || !indatalen || !outdata || !outdatalen || !pincb)
800     return gpg_error (GPG_ERR_INV_VALUE);
801   if (!app->ref_count)
802     return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
803   if (!app->fnc.sign)
804     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
805   err = lock_app (app, ctrl);
806   if (err)
807     return err;
808   err = app->fnc.sign (app, keyidstr, hashalgo,
809                        pincb, pincb_arg,
810                        indata, indatalen,
811                        outdata, outdatalen);
812   unlock_app (app);
813   if (opt.verbose)
814     log_info ("operation sign result: %s\n", gpg_strerror (err));
815   return err;
816 }
817
818 /* Create the signature using the INTERNAL AUTHENTICATE command and
819    return the allocated result in OUTDATA.  If a PIN is required the
820    PINCB will be used to ask for the PIN; it should return the PIN in
821    an allocated buffer and put it into PIN.  */
822 gpg_error_t
823 app_auth (app_t app, ctrl_t ctrl, const char *keyidstr,
824           gpg_error_t (*pincb)(void*, const char *, char **),
825           void *pincb_arg,
826           const void *indata, size_t indatalen,
827           unsigned char **outdata, size_t *outdatalen )
828 {
829   gpg_error_t err;
830
831   if (!app || !indata || !indatalen || !outdata || !outdatalen || !pincb)
832     return gpg_error (GPG_ERR_INV_VALUE);
833   if (!app->ref_count)
834     return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
835   if (!app->fnc.auth)
836     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
837   err = lock_app (app, ctrl);
838   if (err)
839     return err;
840   err = app->fnc.auth (app, keyidstr,
841                        pincb, pincb_arg,
842                        indata, indatalen,
843                        outdata, outdatalen);
844   unlock_app (app);
845   if (opt.verbose)
846     log_info ("operation auth result: %s\n", gpg_strerror (err));
847   return err;
848 }
849
850
851 /* Decrypt the data in INDATA and return the allocated result in OUTDATA.
852    If a PIN is required the PINCB will be used to ask for the PIN; it
853    should return the PIN in an allocated buffer and put it into PIN.  */
854 gpg_error_t
855 app_decipher (app_t app, ctrl_t ctrl, const char *keyidstr,
856               gpg_error_t (*pincb)(void*, const char *, char **),
857               void *pincb_arg,
858               const void *indata, size_t indatalen,
859               unsigned char **outdata, size_t *outdatalen,
860               unsigned int *r_info)
861 {
862   gpg_error_t err;
863
864   *r_info = 0;
865
866   if (!app || !indata || !indatalen || !outdata || !outdatalen || !pincb)
867     return gpg_error (GPG_ERR_INV_VALUE);
868   if (!app->ref_count)
869     return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
870   if (!app->fnc.decipher)
871     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
872   err = lock_app (app, ctrl);
873   if (err)
874     return err;
875   err = app->fnc.decipher (app, keyidstr,
876                            pincb, pincb_arg,
877                            indata, indatalen,
878                            outdata, outdatalen,
879                            r_info);
880   unlock_app (app);
881   if (opt.verbose)
882     log_info ("operation decipher result: %s\n", gpg_strerror (err));
883   return err;
884 }
885
886
887 /* Perform the WRITECERT operation.  */
888 gpg_error_t
889 app_writecert (app_t app, ctrl_t ctrl,
890               const char *certidstr,
891               gpg_error_t (*pincb)(void*, const char *, char **),
892               void *pincb_arg,
893               const unsigned char *data, size_t datalen)
894 {
895   gpg_error_t err;
896
897   if (!app || !certidstr || !*certidstr || !pincb)
898     return gpg_error (GPG_ERR_INV_VALUE);
899   if (!app->ref_count)
900     return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
901   if (!app->fnc.writecert)
902     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
903   err = lock_app (app, ctrl);
904   if (err)
905     return err;
906   err = app->fnc.writecert (app, ctrl, certidstr,
907                             pincb, pincb_arg, data, datalen);
908   unlock_app (app);
909   if (opt.verbose)
910     log_info ("operation writecert result: %s\n", gpg_strerror (err));
911   return err;
912 }
913
914
915 /* Perform the WRITEKEY operation.  */
916 gpg_error_t
917 app_writekey (app_t app, ctrl_t ctrl,
918               const char *keyidstr, unsigned int flags,
919               gpg_error_t (*pincb)(void*, const char *, char **),
920               void *pincb_arg,
921               const unsigned char *keydata, size_t keydatalen)
922 {
923   gpg_error_t err;
924
925   if (!app || !keyidstr || !*keyidstr || !pincb)
926     return gpg_error (GPG_ERR_INV_VALUE);
927   if (!app->ref_count)
928     return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
929   if (!app->fnc.writekey)
930     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
931   err = lock_app (app, ctrl);
932   if (err)
933     return err;
934   err = app->fnc.writekey (app, ctrl, keyidstr, flags,
935                            pincb, pincb_arg, keydata, keydatalen);
936   unlock_app (app);
937   if (opt.verbose)
938     log_info ("operation writekey result: %s\n", gpg_strerror (err));
939   return err;
940 }
941
942
943 /* Perform a SETATTR operation.  */
944 gpg_error_t
945 app_genkey (app_t app, ctrl_t ctrl, const char *keynostr,
946             const char *keytype, unsigned int flags, time_t createtime,
947             gpg_error_t (*pincb)(void*, const char *, char **),
948             void *pincb_arg)
949 {
950   gpg_error_t err;
951
952   if (!app || !keynostr || !*keynostr || !pincb)
953     return gpg_error (GPG_ERR_INV_VALUE);
954   if (!app->ref_count)
955     return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
956   if (!app->fnc.genkey)
957     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
958   err = lock_app (app, ctrl);
959   if (err)
960     return err;
961   err = app->fnc.genkey (app, ctrl, keynostr, keytype, flags,
962                          createtime, pincb, pincb_arg);
963   unlock_app (app);
964   if (opt.verbose)
965     log_info ("operation genkey result: %s\n", gpg_strerror (err));
966   return err;
967 }
968
969
970 /* Perform a GET CHALLENGE operation.  This function is special as it
971    directly accesses the card without any application specific
972    wrapper. */
973 gpg_error_t
974 app_get_challenge (app_t app, ctrl_t ctrl, size_t nbytes, unsigned char *buffer)
975 {
976   gpg_error_t err;
977
978   if (!app || !nbytes || !buffer)
979     return gpg_error (GPG_ERR_INV_VALUE);
980   if (!app->ref_count)
981     return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
982   err = lock_app (app, ctrl);
983   if (err)
984     return err;
985   err = iso7816_get_challenge (app->slot, nbytes, buffer);
986   unlock_app (app);
987   return err;
988 }
989
990
991
992 /* Perform a CHANGE REFERENCE DATA or RESET RETRY COUNTER operation.  */
993 gpg_error_t
994 app_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr,
995                 unsigned int flags,
996                 gpg_error_t (*pincb)(void*, const char *, char **),
997                 void *pincb_arg)
998 {
999   gpg_error_t err;
1000
1001   if (!app || !chvnostr || !*chvnostr || !pincb)
1002     return gpg_error (GPG_ERR_INV_VALUE);
1003   if (!app->ref_count)
1004     return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
1005   if (!app->fnc.change_pin)
1006     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1007   err = lock_app (app, ctrl);
1008   if (err)
1009     return err;
1010   err = app->fnc.change_pin (app, ctrl, chvnostr, flags, pincb, pincb_arg);
1011   unlock_app (app);
1012   if (opt.verbose)
1013     log_info ("operation change_pin result: %s\n", gpg_strerror (err));
1014   return err;
1015 }
1016
1017
1018 /* Perform a VERIFY operation without doing anything else.  This may
1019    be used to initialize a the PIN cache for long lasting other
1020    operations.  Its use is highly application dependent. */
1021 gpg_error_t
1022 app_check_pin (app_t app, ctrl_t ctrl, const char *keyidstr,
1023                gpg_error_t (*pincb)(void*, const char *, char **),
1024                void *pincb_arg)
1025 {
1026   gpg_error_t err;
1027
1028   if (!app || !keyidstr || !*keyidstr || !pincb)
1029     return gpg_error (GPG_ERR_INV_VALUE);
1030   if (!app->ref_count)
1031     return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
1032   if (!app->fnc.check_pin)
1033     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
1034   err = lock_app (app, ctrl);
1035   if (err)
1036     return err;
1037   err = app->fnc.check_pin (app, keyidstr, pincb, pincb_arg);
1038   unlock_app (app);
1039   if (opt.verbose)
1040     log_info ("operation check_pin result: %s\n", gpg_strerror (err));
1041   return err;
1042 }
1043
1044 static void
1045 report_change (int slot, int old_status, int cur_status)
1046 {
1047   char *homestr, *envstr;
1048   char *fname;
1049   char templ[50];
1050   FILE *fp;
1051
1052   snprintf (templ, sizeof templ, "reader_%d.status", slot);
1053   fname = make_filename (gnupg_homedir (), templ, NULL );
1054   fp = fopen (fname, "w");
1055   if (fp)
1056     {
1057       fprintf (fp, "%s\n",
1058                (cur_status & 1)? "USABLE":
1059                (cur_status & 4)? "ACTIVE":
1060                (cur_status & 2)? "PRESENT": "NOCARD");
1061       fclose (fp);
1062     }
1063   xfree (fname);
1064
1065   homestr = make_filename (gnupg_homedir (), NULL);
1066   if (gpgrt_asprintf (&envstr, "GNUPGHOME=%s", homestr) < 0)
1067     log_error ("out of core while building environment\n");
1068   else
1069     {
1070       gpg_error_t err;
1071       const char *args[9], *envs[2];
1072       char numbuf1[30], numbuf2[30], numbuf3[30];
1073
1074       envs[0] = envstr;
1075       envs[1] = NULL;
1076
1077       sprintf (numbuf1, "%d", slot);
1078       sprintf (numbuf2, "0x%04X", old_status);
1079       sprintf (numbuf3, "0x%04X", cur_status);
1080       args[0] = "--reader-port";
1081       args[1] = numbuf1;
1082       args[2] = "--old-code";
1083       args[3] = numbuf2;
1084       args[4] = "--new-code";
1085       args[5] = numbuf3;
1086       args[6] = "--status";
1087       args[7] = ((cur_status & 1)? "USABLE":
1088                  (cur_status & 4)? "ACTIVE":
1089                  (cur_status & 2)? "PRESENT": "NOCARD");
1090       args[8] = NULL;
1091
1092       fname = make_filename (gnupg_homedir (), "scd-event", NULL);
1093       err = gnupg_spawn_process_detached (fname, args, envs);
1094       if (err && gpg_err_code (err) != GPG_ERR_ENOENT)
1095         log_error ("failed to run event handler '%s': %s\n",
1096                    fname, gpg_strerror (err));
1097       xfree (fname);
1098       xfree (envstr);
1099     }
1100   xfree (homestr);
1101 }
1102
1103 int
1104 scd_update_reader_status_file (void)
1105 {
1106   app_t a, app_next;
1107   int periodical_check_needed = 0;
1108
1109   npth_mutex_lock (&app_list_lock);
1110   for (a = app_top; a; a = app_next)
1111     {
1112       int sw;
1113       unsigned int status;
1114
1115       lock_app (a, NULL);
1116       app_next = a->next;
1117
1118       if (a->reset_requested)
1119         status = 0;
1120       else
1121         {
1122           sw = apdu_get_status (a->slot, 0, &status);
1123           if (sw == SW_HOST_NO_READER)
1124             {
1125               /* Most likely the _reader_ has been unplugged.  */
1126               status = 0;
1127             }
1128           else if (sw)
1129             {
1130               /* Get status failed.  Ignore that.  */
1131               if (a->periodical_check_needed)
1132                 periodical_check_needed = 1;
1133               unlock_app (a);
1134               continue;
1135             }
1136         }
1137
1138       if (a->card_status != status)
1139         {
1140           report_change (a->slot, a->card_status, status);
1141           send_client_notifications (a, status == 0);
1142
1143           if (status == 0)
1144             {
1145               log_debug ("Removal of a card: %d\n", a->slot);
1146               apdu_close_reader (a->slot);
1147               deallocate_app (a);
1148             }
1149           else
1150             {
1151               a->card_status = status;
1152               if (a->periodical_check_needed)
1153                 periodical_check_needed = 1;
1154               unlock_app (a);
1155             }
1156         }
1157       else
1158         {
1159           if (a->periodical_check_needed)
1160             periodical_check_needed = 1;
1161           unlock_app (a);
1162         }
1163     }
1164   npth_mutex_unlock (&app_list_lock);
1165
1166   return periodical_check_needed;
1167 }
1168
1169 /* This function must be called once to initialize this module.  This
1170    has to be done before a second thread is spawned.  We can't do the
1171    static initialization because Pth emulation code might not be able
1172    to do a static init; in particular, it is not possible for W32. */
1173 gpg_error_t
1174 initialize_module_command (void)
1175 {
1176   gpg_error_t err;
1177
1178   if (npth_mutex_init (&app_list_lock, NULL))
1179     {
1180       err = gpg_error_from_syserror ();
1181       log_error ("app: error initializing mutex: %s\n", gpg_strerror (err));
1182       return err;
1183     }
1184
1185   return apdu_init ();
1186 }
1187
1188 void
1189 app_send_card_list (ctrl_t ctrl)
1190 {
1191   app_t a;
1192   char buf[65];
1193
1194   npth_mutex_lock (&app_list_lock);
1195   for (a = app_top; a; a = a->next)
1196     {
1197       if (DIM (buf) < 2 * a->serialnolen + 1)
1198         continue;
1199
1200       bin2hex (a->serialno, a->serialnolen, buf);
1201       send_status_direct (ctrl, "SERIALNO", buf);
1202     }
1203   npth_mutex_unlock (&app_list_lock);
1204 }