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