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