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