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