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