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