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