chiark / gitweb /
Import gnupg2_2.1.18.orig.tar.bz2
[gnupg2.git] / scd / app.c
1 /* app.c - Application selection.
2  * Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
3  *
4  * This file is part of GnuPG.
5  *
6  * GnuPG is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * GnuPG is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, see <https://www.gnu.org/licenses/>.
18  */
19
20 #include <config.h>
21 #include <errno.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <npth.h>
26
27 #include "scdaemon.h"
28 #include "exechelp.h"
29 #include "app-common.h"
30 #include "iso7816.h"
31 #include "apdu.h"
32 #include "tlv.h"
33
34 static npth_mutex_t app_list_lock;
35 static app_t app_top;
36 \f
37 static void
38 print_progress_line (void *opaque, const char *what, int pc, int cur, int tot)
39 {
40   ctrl_t ctrl = opaque;
41   char line[100];
42
43   if (ctrl)
44     {
45       snprintf (line, sizeof line, "%s %c %d %d", what, pc, cur, tot);
46       send_status_direct (ctrl, "PROGRESS", line);
47     }
48 }
49
50
51 /* Lock the reader SLOT.  This function shall be used right before
52    calling any of the actual application functions to serialize access
53    to the reader.  We do this always even if the reader is not
54    actually used.  This allows an actual connection to assume that it
55    never shares a reader (while performing one command).  Returns 0 on
56    success; only then the unlock_reader function must be called after
57    returning from the handler. */
58 static gpg_error_t
59 lock_app (app_t app, ctrl_t ctrl)
60 {
61   if (npth_mutex_lock (&app->lock))
62     {
63       gpg_error_t err = gpg_error_from_syserror ();
64       log_error ("failed to acquire APP lock for %p: %s\n",
65                  app, gpg_strerror (err));
66       return err;
67     }
68
69   apdu_set_progress_cb (app->slot, print_progress_line, ctrl);
70
71   return 0;
72 }
73
74 /* Release a lock on the reader.  See lock_reader(). */
75 static void
76 unlock_app (app_t app)
77 {
78   apdu_set_progress_cb (app->slot, NULL, NULL);
79
80   if (npth_mutex_unlock (&app->lock))
81     {
82       gpg_error_t err = gpg_error_from_syserror ();
83       log_error ("failed to release APP lock for %p: %s\n",
84                  app, gpg_strerror (err));
85     }
86 }
87
88
89 /* This function may be called to print information pertaining to the
90    current state of this module to the log. */
91 void
92 app_dump_state (void)
93 {
94   app_t a;
95
96   npth_mutex_lock (&app_list_lock);
97   for (a = app_top; a; a = a->next)
98     log_info ("app_dump_state: app=%p type='%s'\n", a, a->apptype);
99   npth_mutex_unlock (&app_list_lock);
100 }
101
102 /* Check wether the application NAME is allowed.  This does not mean
103    we have support for it though.  */
104 static int
105 is_app_allowed (const char *name)
106 {
107   strlist_t l;
108
109   for (l=opt.disabled_applications; l; l = l->next)
110     if (!strcmp (l->d, name))
111       return 0; /* no */
112   return 1; /* yes */
113 }
114
115
116 static gpg_error_t
117 check_conflict (app_t app, const char *name)
118 {
119   if (!app || !name || (app->apptype && !ascii_strcasecmp (app->apptype, name)))
120     return 0;
121
122   log_info ("application '%s' in use - can't switch\n",
123             app->apptype? app->apptype : "<null>");
124
125   return gpg_error (GPG_ERR_CONFLICT);
126 }
127
128 /* This function is used by the serialno command to check for an
129    application conflict which may appear if the serialno command is
130    used to request a specific application and the connection has
131    already done a select_application. */
132 gpg_error_t
133 check_application_conflict (const char *name, app_t app)
134 {
135   return check_conflict (app, name);
136 }
137
138
139 static void
140 release_application_internal (app_t app)
141 {
142   if (!app->ref_count)
143     log_bug ("trying to release an already released context\n");
144
145   --app->ref_count;
146 }
147
148 gpg_error_t
149 app_reset (app_t app, ctrl_t ctrl, int send_reset)
150 {
151   gpg_error_t err;
152
153   err = lock_app (app, ctrl);
154   if (err)
155     return err;
156
157   if (send_reset)
158     {
159       int sw = apdu_reset (app->slot);
160       if (sw)
161         err = gpg_error (GPG_ERR_CARD_RESET);
162
163       /* Release the same application which is used by other sessions.  */
164       send_client_notifications (app, 1);
165     }
166   else
167     {
168       ctrl->app_ctx = NULL;
169       release_application_internal (app);
170     }
171
172   unlock_app (app);
173   return err;
174 }
175
176 static gpg_error_t
177 app_new_register (int slot, ctrl_t ctrl, const char *name)
178 {
179   gpg_error_t err = 0;
180   app_t app = NULL;
181   unsigned char *result = NULL;
182   size_t resultlen;
183   int want_undefined;
184
185   /* Need to allocate a new one.  */
186   app = xtrycalloc (1, sizeof *app);
187   if (!app)
188     {
189       err = gpg_error_from_syserror ();
190       log_info ("error allocating context: %s\n", gpg_strerror (err));
191       return err;
192     }
193
194   app->slot = slot;
195
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 of the card.  The serial number is
538    returned as a malloced string (hex encoded) in SERIAL.  Caller must
539    free SERIAL unless the function returns an error.  */
540 char *
541 app_get_serialno (app_t app)
542 {
543   char *serial;
544
545   if (!app)
546     return NULL;
547
548   if (!app->serialnolen)
549     serial = xtrystrdup ("FF7F00");
550   else
551     serial = bin2hex (app->serialno, app->serialnolen, NULL);
552
553   return serial;
554 }
555
556
557 /* Write out the application specifig status lines for the LEARN
558    command. */
559 gpg_error_t
560 app_write_learn_status (app_t app, ctrl_t ctrl, unsigned int flags)
561 {
562   gpg_error_t err;
563
564   if (!app)
565     return gpg_error (GPG_ERR_INV_VALUE);
566   if (!app->fnc.learn_status)
567     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
568
569   /* We do not send APPTYPE if only keypairinfo is requested.  */
570   if (app->apptype && !(flags & 1))
571     send_status_direct (ctrl, "APPTYPE", app->apptype);
572   err = lock_app (app, ctrl);
573   if (err)
574     return err;
575   err = app->fnc.learn_status (app, ctrl, flags);
576   unlock_app (app);
577   return err;
578 }
579
580
581 /* Read the certificate with id CERTID (as returned by learn_status in
582    the CERTINFO status lines) and return it in the freshly allocated
583    buffer put into CERT and the length of the certificate put into
584    CERTLEN. */
585 gpg_error_t
586 app_readcert (app_t app, ctrl_t ctrl, const char *certid,
587               unsigned char **cert, size_t *certlen)
588 {
589   gpg_error_t err;
590
591   if (!app)
592     return gpg_error (GPG_ERR_INV_VALUE);
593   if (!app->ref_count)
594     return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
595   if (!app->fnc.readcert)
596     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
597   err = lock_app (app, ctrl);
598   if (err)
599     return err;
600   err = app->fnc.readcert (app, certid, cert, certlen);
601   unlock_app (app);
602   return err;
603 }
604
605
606 /* Read the key with ID KEYID.  On success a canonical encoded
607    S-expression with the public key will get stored at PK and its
608    length (for assertions) at PKLEN; the caller must release that
609    buffer. On error NULL will be stored at PK and PKLEN and an error
610    code returned.
611
612    This function might not be supported by all applications.  */
613 gpg_error_t
614 app_readkey (app_t app, ctrl_t ctrl, int advanced, const char *keyid,
615              unsigned char **pk, size_t *pklen)
616 {
617   gpg_error_t err;
618
619   if (pk)
620     *pk = NULL;
621   if (pklen)
622     *pklen = 0;
623
624   if (!app || !keyid || !pk || !pklen)
625     return gpg_error (GPG_ERR_INV_VALUE);
626   if (!app->ref_count)
627     return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
628   if (!app->fnc.readkey)
629     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
630   err = lock_app (app, ctrl);
631   if (err)
632     return err;
633   err= app->fnc.readkey (app, advanced, keyid, pk, pklen);
634   unlock_app (app);
635   return err;
636 }
637
638
639 /* Perform a GETATTR operation.  */
640 gpg_error_t
641 app_getattr (app_t app, ctrl_t ctrl, const char *name)
642 {
643   gpg_error_t err;
644
645   if (!app || !name || !*name)
646     return gpg_error (GPG_ERR_INV_VALUE);
647   if (!app->ref_count)
648     return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
649
650   if (app->apptype && name && !strcmp (name, "APPTYPE"))
651     {
652       send_status_direct (ctrl, "APPTYPE", app->apptype);
653       return 0;
654     }
655   if (name && !strcmp (name, "SERIALNO"))
656     {
657       char *serial;
658
659       serial = app_get_serialno (app);
660       if (!serial)
661         return gpg_error (GPG_ERR_INV_VALUE);
662
663       send_status_direct (ctrl, "SERIALNO", serial);
664       xfree (serial);
665       return 0;
666     }
667
668   if (!app->fnc.getattr)
669     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
670   err = lock_app (app, ctrl);
671   if (err)
672     return err;
673   err =  app->fnc.getattr (app, ctrl, name);
674   unlock_app (app);
675   return err;
676 }
677
678 /* Perform a SETATTR operation.  */
679 gpg_error_t
680 app_setattr (app_t app, ctrl_t ctrl, const char *name,
681              gpg_error_t (*pincb)(void*, const char *, char **),
682              void *pincb_arg,
683              const unsigned char *value, size_t valuelen)
684 {
685   gpg_error_t err;
686
687   if (!app || !name || !*name || !value)
688     return gpg_error (GPG_ERR_INV_VALUE);
689   if (!app->ref_count)
690     return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
691   if (!app->fnc.setattr)
692     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
693   err = lock_app (app, ctrl);
694   if (err)
695     return err;
696   err = app->fnc.setattr (app, name, pincb, pincb_arg, value, valuelen);
697   unlock_app (app);
698   return err;
699 }
700
701 /* Create the signature and return the allocated result in OUTDATA.
702    If a PIN is required the PINCB will be used to ask for the PIN; it
703    should return the PIN in an allocated buffer and put it into PIN.  */
704 gpg_error_t
705 app_sign (app_t app, ctrl_t ctrl, const char *keyidstr, int hashalgo,
706           gpg_error_t (*pincb)(void*, const char *, char **),
707           void *pincb_arg,
708           const void *indata, size_t indatalen,
709           unsigned char **outdata, size_t *outdatalen )
710 {
711   gpg_error_t err;
712
713   if (!app || !indata || !indatalen || !outdata || !outdatalen || !pincb)
714     return gpg_error (GPG_ERR_INV_VALUE);
715   if (!app->ref_count)
716     return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
717   if (!app->fnc.sign)
718     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
719   err = lock_app (app, ctrl);
720   if (err)
721     return err;
722   err = app->fnc.sign (app, keyidstr, hashalgo,
723                        pincb, pincb_arg,
724                        indata, indatalen,
725                        outdata, outdatalen);
726   unlock_app (app);
727   if (opt.verbose)
728     log_info ("operation sign result: %s\n", gpg_strerror (err));
729   return err;
730 }
731
732 /* Create the signature using the INTERNAL AUTHENTICATE command and
733    return the allocated result in OUTDATA.  If a PIN is required the
734    PINCB will be used to ask for the PIN; it should return the PIN in
735    an allocated buffer and put it into PIN.  */
736 gpg_error_t
737 app_auth (app_t app, ctrl_t ctrl, const char *keyidstr,
738           gpg_error_t (*pincb)(void*, const char *, char **),
739           void *pincb_arg,
740           const void *indata, size_t indatalen,
741           unsigned char **outdata, size_t *outdatalen )
742 {
743   gpg_error_t err;
744
745   if (!app || !indata || !indatalen || !outdata || !outdatalen || !pincb)
746     return gpg_error (GPG_ERR_INV_VALUE);
747   if (!app->ref_count)
748     return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
749   if (!app->fnc.auth)
750     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
751   err = lock_app (app, ctrl);
752   if (err)
753     return err;
754   err = app->fnc.auth (app, keyidstr,
755                        pincb, pincb_arg,
756                        indata, indatalen,
757                        outdata, outdatalen);
758   unlock_app (app);
759   if (opt.verbose)
760     log_info ("operation auth result: %s\n", gpg_strerror (err));
761   return err;
762 }
763
764
765 /* Decrypt the data in INDATA and return the allocated result in OUTDATA.
766    If a PIN is required the PINCB will be used to ask for the PIN; it
767    should return the PIN in an allocated buffer and put it into PIN.  */
768 gpg_error_t
769 app_decipher (app_t app, ctrl_t ctrl, const char *keyidstr,
770               gpg_error_t (*pincb)(void*, const char *, char **),
771               void *pincb_arg,
772               const void *indata, size_t indatalen,
773               unsigned char **outdata, size_t *outdatalen,
774               unsigned int *r_info)
775 {
776   gpg_error_t err;
777
778   *r_info = 0;
779
780   if (!app || !indata || !indatalen || !outdata || !outdatalen || !pincb)
781     return gpg_error (GPG_ERR_INV_VALUE);
782   if (!app->ref_count)
783     return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
784   if (!app->fnc.decipher)
785     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
786   err = lock_app (app, ctrl);
787   if (err)
788     return err;
789   err = app->fnc.decipher (app, keyidstr,
790                            pincb, pincb_arg,
791                            indata, indatalen,
792                            outdata, outdatalen,
793                            r_info);
794   unlock_app (app);
795   if (opt.verbose)
796     log_info ("operation decipher result: %s\n", gpg_strerror (err));
797   return err;
798 }
799
800
801 /* Perform the WRITECERT operation.  */
802 gpg_error_t
803 app_writecert (app_t app, ctrl_t ctrl,
804               const char *certidstr,
805               gpg_error_t (*pincb)(void*, const char *, char **),
806               void *pincb_arg,
807               const unsigned char *data, size_t datalen)
808 {
809   gpg_error_t err;
810
811   if (!app || !certidstr || !*certidstr || !pincb)
812     return gpg_error (GPG_ERR_INV_VALUE);
813   if (!app->ref_count)
814     return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
815   if (!app->fnc.writecert)
816     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
817   err = lock_app (app, ctrl);
818   if (err)
819     return err;
820   err = app->fnc.writecert (app, ctrl, certidstr,
821                             pincb, pincb_arg, data, datalen);
822   unlock_app (app);
823   if (opt.verbose)
824     log_info ("operation writecert result: %s\n", gpg_strerror (err));
825   return err;
826 }
827
828
829 /* Perform the WRITEKEY operation.  */
830 gpg_error_t
831 app_writekey (app_t app, ctrl_t ctrl,
832               const char *keyidstr, unsigned int flags,
833               gpg_error_t (*pincb)(void*, const char *, char **),
834               void *pincb_arg,
835               const unsigned char *keydata, size_t keydatalen)
836 {
837   gpg_error_t err;
838
839   if (!app || !keyidstr || !*keyidstr || !pincb)
840     return gpg_error (GPG_ERR_INV_VALUE);
841   if (!app->ref_count)
842     return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
843   if (!app->fnc.writekey)
844     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
845   err = lock_app (app, ctrl);
846   if (err)
847     return err;
848   err = app->fnc.writekey (app, ctrl, keyidstr, flags,
849                            pincb, pincb_arg, keydata, keydatalen);
850   unlock_app (app);
851   if (opt.verbose)
852     log_info ("operation writekey result: %s\n", gpg_strerror (err));
853   return err;
854 }
855
856
857 /* Perform a SETATTR operation.  */
858 gpg_error_t
859 app_genkey (app_t app, ctrl_t ctrl, const char *keynostr, unsigned int flags,
860             time_t createtime,
861             gpg_error_t (*pincb)(void*, const char *, char **),
862             void *pincb_arg)
863 {
864   gpg_error_t err;
865
866   if (!app || !keynostr || !*keynostr || !pincb)
867     return gpg_error (GPG_ERR_INV_VALUE);
868   if (!app->ref_count)
869     return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
870   if (!app->fnc.genkey)
871     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
872   err = lock_app (app, ctrl);
873   if (err)
874     return err;
875   err = app->fnc.genkey (app, ctrl, keynostr, flags,
876                          createtime, pincb, pincb_arg);
877   unlock_app (app);
878   if (opt.verbose)
879     log_info ("operation genkey result: %s\n", gpg_strerror (err));
880   return err;
881 }
882
883
884 /* Perform a GET CHALLENGE operation.  This function is special as it
885    directly accesses the card without any application specific
886    wrapper. */
887 gpg_error_t
888 app_get_challenge (app_t app, ctrl_t ctrl, size_t nbytes, unsigned char *buffer)
889 {
890   gpg_error_t err;
891
892   if (!app || !nbytes || !buffer)
893     return gpg_error (GPG_ERR_INV_VALUE);
894   if (!app->ref_count)
895     return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
896   err = lock_app (app, ctrl);
897   if (err)
898     return err;
899   err = iso7816_get_challenge (app->slot, nbytes, buffer);
900   unlock_app (app);
901   return err;
902 }
903
904
905
906 /* Perform a CHANGE REFERENCE DATA or RESET RETRY COUNTER operation.  */
907 gpg_error_t
908 app_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr, int reset_mode,
909                 gpg_error_t (*pincb)(void*, const char *, char **),
910                 void *pincb_arg)
911 {
912   gpg_error_t err;
913
914   if (!app || !chvnostr || !*chvnostr || !pincb)
915     return gpg_error (GPG_ERR_INV_VALUE);
916   if (!app->ref_count)
917     return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
918   if (!app->fnc.change_pin)
919     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
920   err = lock_app (app, ctrl);
921   if (err)
922     return err;
923   err = app->fnc.change_pin (app, ctrl, chvnostr, reset_mode,
924                              pincb, pincb_arg);
925   unlock_app (app);
926   if (opt.verbose)
927     log_info ("operation change_pin result: %s\n", gpg_strerror (err));
928   return err;
929 }
930
931
932 /* Perform a VERIFY operation without doing anything lese.  This may
933    be used to initialze a the PIN cache for long lasting other
934    operations.  Its use is highly application dependent. */
935 gpg_error_t
936 app_check_pin (app_t app, ctrl_t ctrl, const char *keyidstr,
937                gpg_error_t (*pincb)(void*, const char *, char **),
938                void *pincb_arg)
939 {
940   gpg_error_t err;
941
942   if (!app || !keyidstr || !*keyidstr || !pincb)
943     return gpg_error (GPG_ERR_INV_VALUE);
944   if (!app->ref_count)
945     return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
946   if (!app->fnc.check_pin)
947     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
948   err = lock_app (app, ctrl);
949   if (err)
950     return err;
951   err = app->fnc.check_pin (app, keyidstr, pincb, pincb_arg);
952   unlock_app (app);
953   if (opt.verbose)
954     log_info ("operation check_pin result: %s\n", gpg_strerror (err));
955   return err;
956 }
957
958 static void
959 report_change (int slot, int old_status, int cur_status)
960 {
961   char *homestr, *envstr;
962   char *fname;
963   char templ[50];
964   FILE *fp;
965
966   snprintf (templ, sizeof templ, "reader_%d.status", slot);
967   fname = make_filename (gnupg_homedir (), templ, NULL );
968   fp = fopen (fname, "w");
969   if (fp)
970     {
971       fprintf (fp, "%s\n",
972                (cur_status & 1)? "USABLE":
973                (cur_status & 4)? "ACTIVE":
974                (cur_status & 2)? "PRESENT": "NOCARD");
975       fclose (fp);
976     }
977   xfree (fname);
978
979   homestr = make_filename (gnupg_homedir (), NULL);
980   if (gpgrt_asprintf (&envstr, "GNUPGHOME=%s", homestr) < 0)
981     log_error ("out of core while building environment\n");
982   else
983     {
984       gpg_error_t err;
985       const char *args[9], *envs[2];
986       char numbuf1[30], numbuf2[30], numbuf3[30];
987
988       envs[0] = envstr;
989       envs[1] = NULL;
990
991       sprintf (numbuf1, "%d", slot);
992       sprintf (numbuf2, "0x%04X", old_status);
993       sprintf (numbuf3, "0x%04X", cur_status);
994       args[0] = "--reader-port";
995       args[1] = numbuf1;
996       args[2] = "--old-code";
997       args[3] = numbuf2;
998       args[4] = "--new-code";
999       args[5] = numbuf3;
1000       args[6] = "--status";
1001       args[7] = ((cur_status & 1)? "USABLE":
1002                  (cur_status & 4)? "ACTIVE":
1003                  (cur_status & 2)? "PRESENT": "NOCARD");
1004       args[8] = NULL;
1005
1006       fname = make_filename (gnupg_homedir (), "scd-event", NULL);
1007       err = gnupg_spawn_process_detached (fname, args, envs);
1008       if (err && gpg_err_code (err) != GPG_ERR_ENOENT)
1009         log_error ("failed to run event handler '%s': %s\n",
1010                    fname, gpg_strerror (err));
1011       xfree (fname);
1012       xfree (envstr);
1013     }
1014   xfree (homestr);
1015 }
1016
1017 void
1018 scd_update_reader_status_file (void)
1019 {
1020   app_t a, app_next;
1021
1022   npth_mutex_lock (&app_list_lock);
1023   for (a = app_top; a; a = app_next)
1024     {
1025       app_next = a->next;
1026       if (a->require_get_status)
1027         {
1028           int sw;
1029           unsigned int status;
1030           sw = apdu_get_status (a->slot, 0, &status);
1031
1032           if (sw == SW_HOST_NO_READER)
1033             {
1034               /* Most likely the _reader_ has been unplugged.  */
1035               status = 0;
1036             }
1037           else if (sw)
1038             {
1039               /* Get status failed.  Ignore that.  */
1040               continue;
1041             }
1042
1043           if (a->card_status != status)
1044             {
1045               report_change (a->slot, a->card_status, status);
1046               send_client_notifications (a, status == 0);
1047
1048               if (status == 0)
1049                 {
1050                   log_debug ("Removal of a card: %d\n", a->slot);
1051                   apdu_close_reader (a->slot);
1052                   deallocate_app (a);
1053                 }
1054               else
1055                 a->card_status = status;
1056             }
1057         }
1058     }
1059   npth_mutex_unlock (&app_list_lock);
1060 }
1061
1062 /* This function must be called once to initialize this module.  This
1063    has to be done before a second thread is spawned.  We can't do the
1064    static initialization because Pth emulation code might not be able
1065    to do a static init; in particular, it is not possible for W32. */
1066 gpg_error_t
1067 initialize_module_command (void)
1068 {
1069   gpg_error_t err;
1070
1071   if (npth_mutex_init (&app_list_lock, NULL))
1072     {
1073       err = gpg_error_from_syserror ();
1074       log_error ("app: error initializing mutex: %s\n", gpg_strerror (err));
1075       return err;
1076     }
1077
1078   return apdu_init ();
1079 }
1080
1081 app_t
1082 app_list_start (void)
1083 {
1084   npth_mutex_lock (&app_list_lock);
1085   return app_top;
1086 }
1087
1088 void
1089 app_list_finish (void)
1090 {
1091   npth_mutex_unlock (&app_list_lock);
1092 }
1093
1094 void
1095 app_send_card_list (ctrl_t ctrl)
1096 {
1097   app_t a;
1098   char buf[65];
1099
1100   npth_mutex_lock (&app_list_lock);
1101   for (a = app_top; a; a = a->next)
1102     {
1103       if (DIM (buf) < 2 * a->serialnolen + 1)
1104         continue;
1105
1106       bin2hex (a->serialno, a->serialnolen, buf);
1107       send_status_direct (ctrl, "SERIALNO", buf);
1108     }
1109   npth_mutex_unlock (&app_list_lock);
1110 }