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