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