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