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