6f0d7560bde47e79b3daf1492bcb8d362956c97a
[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 && name)
391     err = gpg_error (GPG_ERR_NOT_SUPPORTED);
392
393  leave:
394   if (err)
395     {
396       if (name)
397         log_info ("can't select application `%s': %s\n",
398                   name, gpg_strerror (err));
399       else
400         log_info ("no supported card application found: %s\n",
401                   gpg_strerror (err));
402       xfree (app);
403       unlock_reader (slot);
404       return err;
405     }
406
407   app->ref_count = 1;
408
409   lock_table[slot].app = app;
410   *r_app = app;
411   unlock_reader (slot);
412   return 0;
413 }
414
415
416 char *
417 get_supported_applications (void)
418 {
419   const char *list[] = {
420     "openpgp",
421     "nks",
422     "p15",
423     "dinsig",
424     "geldkarte",
425     NULL
426   };
427   int idx;
428   size_t nbytes;
429   char *buffer, *p;
430
431   for (nbytes=1, idx=0; list[idx]; idx++)
432     nbytes += strlen (list[idx]) + 1 + 1;
433
434   buffer = xtrymalloc (nbytes);
435   if (!buffer)
436     return NULL;
437
438   for (p=buffer, idx=0; list[idx]; idx++)
439     if (is_app_allowed (list[idx]))
440       p = stpcpy (stpcpy (p, list[idx]), ":\n");
441   *p = 0;
442
443   return buffer;
444 }
445
446
447 /* Deallocate the application. */
448 static void
449 deallocate_app (app_t app)
450 {
451   if (app->fnc.deinit)
452     {
453       app->fnc.deinit (app);
454       app->fnc.deinit = NULL;
455     }
456
457   xfree (app->serialno);
458   xfree (app);
459 }
460
461 /* Free the resources associated with the application APP.  APP is
462    allowed to be NULL in which case this is a no-op.  Note that we are
463    using reference counting to track the users of the application and
464    actually deferring the deallocation to allow for a later reuse by
465    a new connection. */
466 void
467 release_application (app_t app)
468 {
469   int slot;
470
471   if (!app)
472     return;
473
474   if (!app->ref_count)
475     log_bug ("trying to release an already released context\n");
476   if (--app->ref_count)
477     return;
478
479   /* Move the reference to the application in the lock table. */
480   slot = app->slot;
481   /* FIXME: We are ignoring any error value.  */
482   lock_reader (slot, NULL);
483   if (lock_table[slot].app != app)
484     {
485       unlock_reader (slot);
486       log_bug ("app mismatch %p/%p\n", app, lock_table[slot].app);
487       deallocate_app (app);
488       return;
489     }
490
491   if (lock_table[slot].last_app)
492     deallocate_app (lock_table[slot].last_app);
493   if (app->no_reuse)
494     {
495       /* If we shall not re-use the application we can't save it for
496          later use. */
497       deallocate_app (app);
498       lock_table[slot].last_app = NULL;
499     }
500   else
501     lock_table[slot].last_app = lock_table[slot].app;
502   lock_table[slot].app = NULL;
503   unlock_reader (slot);
504 }
505
506
507
508 /* The serial number may need some cosmetics.  Do it here.  This
509    function shall only be called once after a new serial number has
510    been put into APP->serialno.
511
512    Prefixes we use:
513
514      FF 00 00 = For serial numbers starting with an FF
515      FF 01 00 = Some german p15 cards return an empty serial number so the
516                 serial number from the EF(TokenInfo) is used instead.
517      FF 7F 00 = No serialno.
518
519      All other serial number not starting with FF are used as they are.
520 */
521 gpg_error_t
522 app_munge_serialno (app_t app)
523 {
524   if (app->serialnolen && app->serialno[0] == 0xff)
525     {
526       /* The serial number starts with our special prefix.  This
527          requires that we put our default prefix "FF0000" in front. */
528       unsigned char *p = xtrymalloc (app->serialnolen + 3);
529       if (!p)
530         return gpg_error_from_syserror ();
531       memcpy (p, "\xff\0", 3);
532       memcpy (p+3, app->serialno, app->serialnolen);
533       app->serialnolen += 3;
534       xfree (app->serialno);
535       app->serialno = p;
536     }
537   else if (!app->serialnolen)
538     {
539       unsigned char *p = xtrymalloc (3);
540       if (!p)
541         return gpg_error_from_syserror ();
542       memcpy (p, "\xff\x7f", 3);
543       app->serialnolen = 3;
544       xfree (app->serialno);
545       app->serialno = p;
546     }
547   return 0;
548 }
549
550
551
552 /* Retrieve the serial number and the time of the last update of the
553    card.  The serial number is returned as a malloced string (hex
554    encoded) in SERIAL and the time of update is returned in STAMP.  If
555    no update time is available the returned value is 0.  Caller must
556    free SERIAL unless the function returns an error.  If STAMP is not
557    of interest, NULL may be passed. */
558 gpg_error_t
559 app_get_serial_and_stamp (app_t app, char **serial, time_t *stamp)
560 {
561   char *buf;
562
563   if (!app || !serial)
564     return gpg_error (GPG_ERR_INV_VALUE);
565
566   *serial = NULL;
567   if (stamp)
568     *stamp = 0; /* not available */
569
570   if (!app->serialnolen)
571     buf = xtrystrdup ("FF7F00");
572   else
573     buf = bin2hex (app->serialno, app->serialnolen, NULL);
574   if (!buf)
575     return gpg_error_from_syserror ();
576
577   *serial = buf;
578   return 0;
579 }
580
581
582 /* Write out the application specifig status lines for the LEARN
583    command. */
584 gpg_error_t
585 app_write_learn_status (app_t app, ctrl_t ctrl, unsigned int flags)
586 {
587   gpg_error_t err;
588
589   if (!app)
590     return gpg_error (GPG_ERR_INV_VALUE);
591   if (!app->ref_count)
592     return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
593   if (!app->fnc.learn_status)
594     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
595
596   /* We do not send APPTYPE if only keypairinfo is requested.  */
597   if (app->apptype && !(flags & 1))
598     send_status_info (ctrl, "APPTYPE",
599                       app->apptype, strlen (app->apptype), NULL, 0);
600   err = lock_reader (app->slot, ctrl);
601   if (err)
602     return err;
603   err = app->fnc.learn_status (app, ctrl, flags);
604   unlock_reader (app->slot);
605   return err;
606 }
607
608
609 /* Read the certificate with id CERTID (as returned by learn_status in
610    the CERTINFO status lines) and return it in the freshly allocated
611    buffer put into CERT and the length of the certificate put into
612    CERTLEN. */
613 gpg_error_t
614 app_readcert (app_t app, const char *certid,
615               unsigned char **cert, size_t *certlen)
616 {
617   gpg_error_t err;
618
619   if (!app)
620     return gpg_error (GPG_ERR_INV_VALUE);
621   if (!app->ref_count)
622     return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
623   if (!app->fnc.readcert)
624     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
625   err = lock_reader (app->slot, NULL/* FIXME*/);
626   if (err)
627     return err;
628   err = app->fnc.readcert (app, certid, cert, certlen);
629   unlock_reader (app->slot);
630   return err;
631 }
632
633
634 /* Read the key with ID KEYID.  On success a canonical encoded
635    S-expression with the public key will get stored at PK and its
636    length (for assertions) at PKLEN; the caller must release that
637    buffer. On error NULL will be stored at PK and PKLEN and an error
638    code returned.
639
640    This function might not be supported by all applications.  */
641 gpg_error_t
642 app_readkey (app_t app, const char *keyid, unsigned char **pk, size_t *pklen)
643 {
644   gpg_error_t err;
645
646   if (pk)
647     *pk = NULL;
648   if (pklen)
649     *pklen = 0;
650
651   if (!app || !keyid || !pk || !pklen)
652     return gpg_error (GPG_ERR_INV_VALUE);
653   if (!app->ref_count)
654     return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
655   if (!app->fnc.readkey)
656     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
657   err = lock_reader (app->slot, NULL /*FIXME*/);
658   if (err)
659     return err;
660   err= app->fnc.readkey (app, keyid, pk, pklen);
661   unlock_reader (app->slot);
662   return err;
663 }
664
665
666 /* Perform a GETATTR operation.  */
667 gpg_error_t
668 app_getattr (app_t app, ctrl_t ctrl, const char *name)
669 {
670   gpg_error_t err;
671
672   if (!app || !name || !*name)
673     return gpg_error (GPG_ERR_INV_VALUE);
674   if (!app->ref_count)
675     return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
676
677   if (app->apptype && name && !strcmp (name, "APPTYPE"))
678     {
679       send_status_info (ctrl, "APPTYPE",
680                         app->apptype, strlen (app->apptype), NULL, 0);
681       return 0;
682     }
683   if (name && !strcmp (name, "SERIALNO"))
684     {
685       char *serial;
686       time_t stamp;
687       int rc;
688
689       rc = app_get_serial_and_stamp (app, &serial, &stamp);
690       if (rc)
691         return rc;
692       send_status_info (ctrl, "SERIALNO", serial, strlen (serial), NULL, 0);
693       xfree (serial);
694       return 0;
695     }
696
697   if (!app->fnc.getattr)
698     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
699   err = lock_reader (app->slot, ctrl);
700   if (err)
701     return err;
702   err =  app->fnc.getattr (app, ctrl, name);
703   unlock_reader (app->slot);
704   return err;
705 }
706
707 /* Perform a SETATTR operation.  */
708 gpg_error_t
709 app_setattr (app_t app, const char *name,
710              gpg_error_t (*pincb)(void*, const char *, char **),
711              void *pincb_arg,
712              const unsigned char *value, size_t valuelen)
713 {
714   gpg_error_t err;
715
716   if (!app || !name || !*name || !value)
717     return gpg_error (GPG_ERR_INV_VALUE);
718   if (!app->ref_count)
719     return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
720   if (!app->fnc.setattr)
721     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
722   err = lock_reader (app->slot, NULL /*FIXME*/);
723   if (err)
724     return err;
725   err = app->fnc.setattr (app, name, pincb, pincb_arg, value, valuelen);
726   unlock_reader (app->slot);
727   return err;
728 }
729
730 /* Create the signature and return the allocated result in OUTDATA.
731    If a PIN is required the PINCB will be used to ask for the PIN; it
732    should return the PIN in an allocated buffer and put it into PIN.  */
733 gpg_error_t
734 app_sign (app_t app, const char *keyidstr, int hashalgo,
735           gpg_error_t (*pincb)(void*, const char *, char **),
736           void *pincb_arg,
737           const void *indata, size_t indatalen,
738           unsigned char **outdata, size_t *outdatalen )
739 {
740   gpg_error_t err;
741
742   if (!app || !indata || !indatalen || !outdata || !outdatalen || !pincb)
743     return gpg_error (GPG_ERR_INV_VALUE);
744   if (!app->ref_count)
745     return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
746   if (!app->fnc.sign)
747     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
748   err = lock_reader (app->slot, NULL /*FIXME*/);
749   if (err)
750     return err;
751   err = app->fnc.sign (app, keyidstr, hashalgo,
752                        pincb, pincb_arg,
753                        indata, indatalen,
754                        outdata, outdatalen);
755   unlock_reader (app->slot);
756   if (opt.verbose)
757     log_info ("operation sign result: %s\n", gpg_strerror (err));
758   return err;
759 }
760
761 /* Create the signature using the INTERNAL AUTHENTICATE command and
762    return the allocated result in OUTDATA.  If a PIN is required the
763    PINCB will be used to ask for the PIN; it should return the PIN in
764    an allocated buffer and put it into PIN.  */
765 gpg_error_t
766 app_auth (app_t app, const char *keyidstr,
767           gpg_error_t (*pincb)(void*, const char *, char **),
768           void *pincb_arg,
769           const void *indata, size_t indatalen,
770           unsigned char **outdata, size_t *outdatalen )
771 {
772   gpg_error_t err;
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.auth)
779     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
780   err = lock_reader (app->slot, NULL /*FIXME*/);
781   if (err)
782     return err;
783   err = app->fnc.auth (app, keyidstr,
784                        pincb, pincb_arg,
785                        indata, indatalen,
786                        outdata, outdatalen);
787   unlock_reader (app->slot);
788   if (opt.verbose)
789     log_info ("operation auth result: %s\n", gpg_strerror (err));
790   return err;
791 }
792
793
794 /* Decrypt the data in INDATA and return the allocated result in OUTDATA.
795    If a PIN is required the PINCB will be used to ask for the PIN; it
796    should return the PIN in an allocated buffer and put it into PIN.  */
797 gpg_error_t
798 app_decipher (app_t app, const char *keyidstr,
799               gpg_error_t (*pincb)(void*, const char *, char **),
800               void *pincb_arg,
801               const void *indata, size_t indatalen,
802               unsigned char **outdata, size_t *outdatalen )
803 {
804   gpg_error_t err;
805
806   if (!app || !indata || !indatalen || !outdata || !outdatalen || !pincb)
807     return gpg_error (GPG_ERR_INV_VALUE);
808   if (!app->ref_count)
809     return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
810   if (!app->fnc.decipher)
811     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
812   err = lock_reader (app->slot, NULL /*FIXME*/);
813   if (err)
814     return err;
815   err = app->fnc.decipher (app, keyidstr,
816                            pincb, pincb_arg,
817                            indata, indatalen,
818                            outdata, outdatalen);
819   unlock_reader (app->slot);
820   if (opt.verbose)
821     log_info ("operation decipher result: %s\n", gpg_strerror (err));
822   return err;
823 }
824
825
826 /* Perform the WRITECERT operation.  */
827 gpg_error_t
828 app_writecert (app_t app, ctrl_t ctrl,
829               const char *certidstr,
830               gpg_error_t (*pincb)(void*, const char *, char **),
831               void *pincb_arg,
832               const unsigned char *data, size_t datalen)
833 {
834   gpg_error_t err;
835
836   if (!app || !certidstr || !*certidstr || !pincb)
837     return gpg_error (GPG_ERR_INV_VALUE);
838   if (!app->ref_count)
839     return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
840   if (!app->fnc.writecert)
841     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
842   err = lock_reader (app->slot, ctrl);
843   if (err)
844     return err;
845   err = app->fnc.writecert (app, ctrl, certidstr,
846                             pincb, pincb_arg, data, datalen);
847   unlock_reader (app->slot);
848   if (opt.verbose)
849     log_info ("operation writecert result: %s\n", gpg_strerror (err));
850   return err;
851 }
852
853
854 /* Perform the WRITEKEY operation.  */
855 gpg_error_t
856 app_writekey (app_t app, ctrl_t ctrl,
857               const char *keyidstr, unsigned int flags,
858               gpg_error_t (*pincb)(void*, const char *, char **),
859               void *pincb_arg,
860               const unsigned char *keydata, size_t keydatalen)
861 {
862   gpg_error_t err;
863
864   if (!app || !keyidstr || !*keyidstr || !pincb)
865     return gpg_error (GPG_ERR_INV_VALUE);
866   if (!app->ref_count)
867     return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
868   if (!app->fnc.writekey)
869     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
870   err = lock_reader (app->slot, ctrl);
871   if (err)
872     return err;
873   err = app->fnc.writekey (app, ctrl, keyidstr, flags,
874                            pincb, pincb_arg, keydata, keydatalen);
875   unlock_reader (app->slot);
876   if (opt.verbose)
877     log_info ("operation writekey result: %s\n", gpg_strerror (err));
878   return err;
879 }
880
881
882 /* Perform a SETATTR operation.  */
883 gpg_error_t
884 app_genkey (app_t app, ctrl_t ctrl, const char *keynostr, unsigned int flags,
885             time_t createtime,
886             gpg_error_t (*pincb)(void*, const char *, char **),
887             void *pincb_arg)
888 {
889   gpg_error_t err;
890
891   if (!app || !keynostr || !*keynostr || !pincb)
892     return gpg_error (GPG_ERR_INV_VALUE);
893   if (!app->ref_count)
894     return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
895   if (!app->fnc.genkey)
896     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
897   err = lock_reader (app->slot, ctrl);
898   if (err)
899     return err;
900   err = app->fnc.genkey (app, ctrl, keynostr, flags,
901                          createtime, pincb, pincb_arg);
902   unlock_reader (app->slot);
903   if (opt.verbose)
904     log_info ("operation genkey result: %s\n", gpg_strerror (err));
905   return err;
906 }
907
908
909 /* Perform a GET CHALLENGE operation.  This fucntion is special as it
910    directly accesses the card without any application specific
911    wrapper. */
912 gpg_error_t
913 app_get_challenge (app_t app, size_t nbytes, unsigned char *buffer)
914 {
915   gpg_error_t err;
916
917   if (!app || !nbytes || !buffer)
918     return gpg_error (GPG_ERR_INV_VALUE);
919   if (!app->ref_count)
920     return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
921   err = lock_reader (app->slot, NULL /*FIXME*/);
922   if (err)
923     return err;
924   err = iso7816_get_challenge (app->slot, nbytes, buffer);
925   unlock_reader (app->slot);
926   return err;
927 }
928
929
930
931 /* Perform a CHANGE REFERENCE DATA or RESET RETRY COUNTER operation.  */
932 gpg_error_t
933 app_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr, int reset_mode,
934                 gpg_error_t (*pincb)(void*, const char *, char **),
935                 void *pincb_arg)
936 {
937   gpg_error_t err;
938
939   if (!app || !chvnostr || !*chvnostr || !pincb)
940     return gpg_error (GPG_ERR_INV_VALUE);
941   if (!app->ref_count)
942     return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
943   if (!app->fnc.change_pin)
944     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
945   err = lock_reader (app->slot, ctrl);
946   if (err)
947     return err;
948   err = app->fnc.change_pin (app, ctrl, chvnostr, reset_mode,
949                              pincb, pincb_arg);
950   unlock_reader (app->slot);
951   if (opt.verbose)
952     log_info ("operation change_pin result: %s\n", gpg_strerror (err));
953   return err;
954 }
955
956
957 /* Perform a VERIFY operation without doing anything lese.  This may
958    be used to initialze a the PIN cache for long lasting other
959    operations.  Its use is highly application dependent. */
960 gpg_error_t
961 app_check_pin (app_t app, const char *keyidstr,
962                gpg_error_t (*pincb)(void*, const char *, char **),
963                void *pincb_arg)
964 {
965   gpg_error_t err;
966
967   if (!app || !keyidstr || !*keyidstr || !pincb)
968     return gpg_error (GPG_ERR_INV_VALUE);
969   if (!app->ref_count)
970     return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
971   if (!app->fnc.check_pin)
972     return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
973   err = lock_reader (app->slot, NULL /*FIXME*/);
974   if (err)
975     return err;
976   err = app->fnc.check_pin (app, keyidstr, pincb, pincb_arg);
977   unlock_reader (app->slot);
978   if (opt.verbose)
979     log_info ("operation check_pin result: %s\n", gpg_strerror (err));
980   return err;
981 }