scd: Support multiple readers by 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, 1);
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 = 0;
323   app_t app;
324
325   *r_app = NULL;
326
327   if (scan || !app_top)
328     {
329       struct dev_list *l;
330
331       err = apdu_dev_list_start (opt.reader_port, &l);
332       if (err)
333         return err;
334
335       while (1)
336         {
337           int slot;
338           int sw;
339
340           slot = apdu_open_reader (l);
341           if (slot < 0)
342             break;
343
344           err = 0;
345           sw = apdu_connect (slot);
346
347           if (sw == SW_HOST_CARD_INACTIVE)
348             {
349               /* Try again.  */
350               sw = apdu_reset (slot);
351             }
352
353           if (!sw || sw == SW_HOST_ALREADY_CONNECTED)
354             err = 0;
355           else
356             err = gpg_error (GPG_ERR_ENODEV);
357
358           if (!err)
359             err = app_new_register (slot, ctrl, name);
360           else
361             apdu_close_reader (slot);
362         }
363
364       apdu_dev_list_finish (l);
365     }
366
367   app = app_top;
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   else
380     err = gpg_error (GPG_ERR_ENODEV);
381
382   return err;
383 }
384
385
386 char *
387 get_supported_applications (void)
388 {
389   const char *list[] = {
390     "openpgp",
391     "nks",
392     "p15",
393     "geldkarte",
394     "dinsig",
395     "sc-hsm",
396     /* Note: "undefined" is not listed here because it needs special
397        treatment by the client.  */
398     NULL
399   };
400   int idx;
401   size_t nbytes;
402   char *buffer, *p;
403
404   for (nbytes=1, idx=0; list[idx]; idx++)
405     nbytes += strlen (list[idx]) + 1 + 1;
406
407   buffer = xtrymalloc (nbytes);
408   if (!buffer)
409     return NULL;
410
411   for (p=buffer, idx=0; list[idx]; idx++)
412     if (is_app_allowed (list[idx]))
413       p = stpcpy (stpcpy (p, list[idx]), ":\n");
414   *p = 0;
415
416   return buffer;
417 }
418
419
420 /* Deallocate the application.  */
421 static void
422 deallocate_app (app_t app)
423 {
424   app_t a, a_prev = NULL;
425
426   for (a = app_top; a; a = a->next)
427     if (a == app)
428       {
429         if (a_prev == NULL)
430           app_top = a->next;
431         else
432           a_prev->next = a->next;
433         break;
434       }
435     else
436       a_prev = a;
437
438   if (app->ref_count)
439     log_error ("trying to release context used yet (%d)\n", app->ref_count);
440
441   if (app->fnc.deinit)
442     {
443       app->fnc.deinit (app);
444       app->fnc.deinit = NULL;
445     }
446
447   xfree (app->serialno);
448   xfree (app);
449 }
450
451 /* Free the resources associated with the application APP.  APP is
452    allowed to be NULL in which case this is a no-op.  Note that we are
453    using reference counting to track the users of the application and
454    actually deferring the deallocation to allow for a later reuse by
455    a new connection. */
456 void
457 release_application (app_t app)
458 {
459   if (!app)
460     return;
461
462   /* We don't deallocate app here.  Instead, we keep it.  This is
463      useful so that a card does not get reset even if only one session
464      is using the card - this way the PIN cache and other cached data
465      are preserved.  */
466
467   lock_app (app, NULL);
468   release_application_internal (app);
469   unlock_app (app);
470 }
471
472
473
474 /* The serial number may need some cosmetics.  Do it here.  This
475    function shall only be called once after a new serial number has
476    been put into APP->serialno.
477
478    Prefixes we use:
479
480      FF 00 00 = For serial numbers starting with an FF
481      FF 01 00 = Some german p15 cards return an empty serial number so the
482                 serial number from the EF(TokenInfo) is used instead.
483      FF 7F 00 = No serialno.
484
485      All other serial number not starting with FF are used as they are.
486 */
487 gpg_error_t
488 app_munge_serialno (app_t app)
489 {
490   if (app->serialnolen && app->serialno[0] == 0xff)
491     {
492       /* The serial number starts with our special prefix.  This
493          requires that we put our default prefix "FF0000" in front. */
494       unsigned char *p = xtrymalloc (app->serialnolen + 3);
495       if (!p)
496         return gpg_error_from_syserror ();
497       memcpy (p, "\xff\0", 3);
498       memcpy (p+3, app->serialno, app->serialnolen);
499       app->serialnolen += 3;
500       xfree (app->serialno);
501       app->serialno = p;
502     }
503   else if (!app->serialnolen)
504     {
505       unsigned char *p = xtrymalloc (3);
506       if (!p)
507         return gpg_error_from_syserror ();
508       memcpy (p, "\xff\x7f", 3);
509       app->serialnolen = 3;
510       xfree (app->serialno);
511       app->serialno = p;
512     }
513   return 0;
514 }
515
516
517
518 /* Retrieve the serial number and the time of the last update of the
519    card.  The serial number is returned as a malloced string (hex
520    encoded) in SERIAL and the time of update is returned in STAMP.  If
521    no update time is available the returned value is 0.  Caller must
522    free SERIAL unless the function returns an error.  If STAMP is not
523    of interest, NULL may be passed. */
524 gpg_error_t
525 app_get_serial_and_stamp (app_t app, char **serial, time_t *stamp)
526 {
527   char *buf;
528
529   if (!app || !serial)
530     return gpg_error (GPG_ERR_INV_VALUE);
531
532   *serial = NULL;
533   if (stamp)
534     *stamp = 0; /* not available */
535
536   if (!app->serialnolen)
537     buf = xtrystrdup ("FF7F00");
538   else
539     buf = bin2hex (app->serialno, app->serialnolen, NULL);
540   if (!buf)
541     return gpg_error_from_syserror ();
542
543   *serial = buf;
544   return 0;
545 }
546
547
548 /* Write out the application specifig status lines for the LEARN
549    command. */
550 gpg_error_t
551 app_write_learn_status (app_t app, ctrl_t ctrl, unsigned int flags)
552 {
553   gpg_error_t err;
554
555   if (!app)
556     return gpg_error (GPG_ERR_INV_VALUE);
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, status == 0);
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 gpg_error_t
1061 initialize_module_command (void)
1062 {
1063   gpg_error_t err;
1064
1065   if (npth_mutex_init (&app_list_lock, NULL))
1066     {
1067       err = gpg_error_from_syserror ();
1068       log_error ("app: error initializing mutex: %s\n", gpg_strerror (err));
1069       return err;
1070     }
1071
1072   return apdu_init ();
1073 }
1074
1075 app_t
1076 app_list_start (void)
1077 {
1078   npth_mutex_lock (&app_list_lock);
1079   return app_top;
1080 }
1081
1082 void
1083 app_list_finish (void)
1084 {
1085   npth_mutex_unlock (&app_list_lock);
1086 }