Prepare for OpenPGP cards with extended length support.
[gnupg.git] / scd / app.c
blobeb97d846ae1905788b9f1b4aa7969de5aba86e45
1 /* app.c - Application selection.
2 * Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
4 * This file is part of GnuPG.
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.
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.
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/>.
20 #include <config.h>
21 #include <errno.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <pth.h>
27 #include "scdaemon.h"
28 #include "app-common.h"
29 #include "apdu.h"
30 #include "iso7816.h"
31 #include "tlv.h"
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
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];
47 static void deallocate_app (app_t app);
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)
61 gpg_error_t err;
63 if (slot < 0 || slot >= DIM (lock_table))
64 return gpg_error (slot<0? GPG_ERR_INV_VALUE : GPG_ERR_RESOURCE_LIMIT);
66 if (!lock_table[slot].initialized)
68 if (!pth_mutex_init (&lock_table[slot].lock))
70 err = gpg_error_from_syserror ();
71 log_error ("error initializing mutex: %s\n", strerror (errno));
72 return err;
74 lock_table[slot].initialized = 1;
75 lock_table[slot].app = NULL;
76 lock_table[slot].last_app = NULL;
79 if (!pth_mutex_acquire (&lock_table[slot].lock, 0, NULL))
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;
87 return 0;
90 /* Release a lock on the reader. See lock_reader(). */
91 static void
92 unlock_reader (int slot)
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);
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));
105 static void
106 dump_mutex_state (pth_mutex_t *m)
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
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)
127 int slot;
129 for (slot=0; slot < DIM (lock_table); slot++)
130 if (lock_table[slot].initialized)
132 log_info ("app_dump_state: slot=%d lock=", slot);
133 dump_mutex_state (&lock_table[slot].lock);
134 if (lock_table[slot].app)
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);
140 if (lock_table[slot].last_app)
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);
146 log_printf ("\n");
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)
155 strlist_t l;
157 for (l=opt.disabled_applications; l; l = l->next)
158 if (!strcmp (l->d, name))
159 return 0; /* no */
160 return 1; /* yes */
164 /* This may be called to tell this module about a removed or resetted card. */
165 void
166 application_notify_card_reset (int slot)
168 app_t app;
170 if (slot < 0 || slot >= DIM (lock_table))
171 return;
173 /* FIXME: We are ignoring any error value here. */
174 lock_reader (slot);
176 /* Mark application as non-reusable. */
177 if (lock_table[slot].app)
178 lock_table[slot].app->no_reuse = 1;
180 /* Deallocate a saved application for that slot, so that we won't
181 try to reuse it. If there is no saved application, set a flag so
182 that we won't save the current state. */
183 app = lock_table[slot].last_app;
185 if (app)
187 lock_table[slot].last_app = NULL;
188 deallocate_app (app);
190 unlock_reader (slot);
194 /* This function is used by the serialno command to check for an
195 application conflict which may appear if the serialno command is
196 used to request a specific application and the connection has
197 already done a select_application. */
198 gpg_error_t
199 check_application_conflict (ctrl_t ctrl, const char *name)
201 int slot = ctrl->reader_slot;
202 app_t app;
204 if (slot < 0 || slot >= DIM (lock_table))
205 return gpg_error (GPG_ERR_INV_VALUE);
207 app = lock_table[slot].initialized ? lock_table[slot].app : NULL;
208 if (app && app->apptype && name)
209 if ( ascii_strcasecmp (app->apptype, name))
210 return gpg_error (GPG_ERR_CONFLICT);
211 return 0;
215 /* If called with NAME as NULL, select the best fitting application
216 and return a context; otherwise select the application with NAME
217 and return a context. SLOT identifies the reader device. Returns
218 an error code and stores NULL at R_APP if no application was found
219 or no card is present. */
220 gpg_error_t
221 select_application (ctrl_t ctrl, int slot, const char *name, app_t *r_app)
223 gpg_error_t err;
224 app_t app = NULL;
225 unsigned char *result = NULL;
226 size_t resultlen;
228 (void)ctrl;
230 *r_app = NULL;
232 err = lock_reader (slot);
233 if (err)
234 return err;
236 /* First check whether we already have an application to share. */
237 app = lock_table[slot].initialized ? lock_table[slot].app : NULL;
238 if (app && name)
239 if (!app->apptype || ascii_strcasecmp (app->apptype, name))
241 unlock_reader (slot);
242 if (app->apptype)
243 log_info ("application `%s' in use by reader %d - can't switch\n",
244 app->apptype, slot);
245 return gpg_error (GPG_ERR_CONFLICT);
248 /* Don't use a non-reusable marked application. */
249 if (app && app->no_reuse)
251 unlock_reader (slot);
252 log_info ("lingering application `%s' in use by reader %d"
253 " - can't switch\n",
254 app->apptype? app->apptype:"?", slot);
255 return gpg_error (GPG_ERR_CONFLICT);
258 /* If we don't have an app, check whether we have a saved
259 application for that slot. This is useful so that a card does
260 not get reset even if only one session is using the card - this
261 way the PIN cache and other cached data are preserved. */
262 if (!app && lock_table[slot].initialized && lock_table[slot].last_app)
264 app = lock_table[slot].last_app;
265 if (!name || (app->apptype && !ascii_strcasecmp (app->apptype, name)) )
267 /* Yes, we can reuse this application - either the caller
268 requested an unspecific one or the requested one matches
269 the saved one. */
270 lock_table[slot].app = app;
271 lock_table[slot].last_app = NULL;
273 else
275 /* No, this saved application can't be used - deallocate it. */
276 lock_table[slot].last_app = NULL;
277 deallocate_app (app);
278 app = NULL;
282 /* If we can reuse an application, bump the reference count and
283 return it. */
284 if (app)
286 if (app->slot != slot)
287 log_bug ("slot mismatch %d/%d\n", app->slot, slot);
288 app->slot = slot;
290 app->ref_count++;
291 *r_app = app;
292 unlock_reader (slot);
293 return 0; /* Okay: We share that one. */
296 /* Need to allocate a new one. */
297 app = xtrycalloc (1, sizeof *app);
298 if (!app)
300 err = gpg_error_from_syserror ();
301 log_info ("error allocating context: %s\n", gpg_strerror (err));
302 unlock_reader (slot);
303 return err;
305 app->slot = slot;
308 /* Fixme: We should now first check whether a card is at all
309 present. */
311 /* Try to read the GDO file first to get a default serial number. */
312 err = iso7816_select_file (slot, 0x3F00, 1, NULL, NULL);
313 if (!err)
314 err = iso7816_select_file (slot, 0x2F02, 0, NULL, NULL);
315 if (!err)
316 err = iso7816_read_binary (slot, 0, 0, &result, &resultlen);
317 if (!err)
319 size_t n;
320 const unsigned char *p;
322 p = find_tlv_unchecked (result, resultlen, 0x5A, &n);
323 if (p)
324 resultlen -= (p-result);
325 if (p && n > resultlen && n == 0x0d && resultlen+1 == n)
327 /* The object it does not fit into the buffer. This is an
328 invalid encoding (or the buffer is too short. However, I
329 have some test cards with such an invalid encoding and
330 therefore I use this ugly workaround to return something
331 I can further experiment with. */
332 log_info ("enabling BMI testcard workaround\n");
333 n--;
336 if (p && n <= resultlen)
338 /* The GDO file is pretty short, thus we simply reuse it for
339 storing the serial number. */
340 memmove (result, p, n);
341 app->serialno = result;
342 app->serialnolen = n;
343 err = app_munge_serialno (app);
344 if (err)
345 goto leave;
347 else
348 xfree (result);
349 result = NULL;
352 /* For certain error codes, there is no need to try more. */
353 if (gpg_err_code (err) == GPG_ERR_CARD_NOT_PRESENT)
354 goto leave;
357 /* Figure out the application to use. */
358 err = gpg_error (GPG_ERR_NOT_FOUND);
360 if (err && is_app_allowed ("openpgp")
361 && (!name || !strcmp (name, "openpgp")))
362 err = app_select_openpgp (app);
363 if (err && is_app_allowed ("nks") && (!name || !strcmp (name, "nks")))
364 err = app_select_nks (app);
365 if (err && is_app_allowed ("p15") && (!name || !strcmp (name, "p15")))
366 err = app_select_p15 (app);
367 if (err && is_app_allowed ("dinsig") && (!name || !strcmp (name, "dinsig")))
368 err = app_select_dinsig (app);
369 if (err && is_app_allowed ("geldkarte")
370 && (!name || !strcmp (name, "geldkarte")))
371 err = app_select_geldkarte (app);
372 if (err && name)
373 err = gpg_error (GPG_ERR_NOT_SUPPORTED);
375 leave:
376 if (err)
378 if (name)
379 log_info ("can't select application `%s': %s\n",
380 name, gpg_strerror (err));
381 else
382 log_info ("no supported card application found: %s\n",
383 gpg_strerror (err));
384 xfree (app);
385 unlock_reader (slot);
386 return err;
389 app->ref_count = 1;
391 lock_table[slot].app = app;
392 *r_app = app;
393 unlock_reader (slot);
394 return 0;
398 char *
399 get_supported_applications (void)
401 const char *list[] = {
402 "openpgp",
403 "nks",
404 "p15",
405 "dinsig",
406 "geldkarte",
407 NULL
409 int idx;
410 size_t nbytes;
411 char *buffer, *p;
413 for (nbytes=1, idx=0; list[idx]; idx++)
414 nbytes += strlen (list[idx]) + 1 + 1;
416 buffer = xtrymalloc (nbytes);
417 if (!buffer)
418 return NULL;
420 for (p=buffer, idx=0; list[idx]; idx++)
421 if (is_app_allowed (list[idx]))
422 p = stpcpy (stpcpy (p, list[idx]), ":\n");
423 *p = 0;
425 return buffer;
429 /* Deallocate the application. */
430 static void
431 deallocate_app (app_t app)
433 if (app->fnc.deinit)
435 app->fnc.deinit (app);
436 app->fnc.deinit = NULL;
439 xfree (app->serialno);
440 xfree (app);
443 /* Free the resources associated with the application APP. APP is
444 allowed to be NULL in which case this is a no-op. Note that we are
445 using reference counting to track the users of the application and
446 actually deferring the deallocation to allow for a later reuse by
447 a new connection. */
448 void
449 release_application (app_t app)
451 int slot;
453 if (!app)
454 return;
456 if (!app->ref_count)
457 log_bug ("trying to release an already released context\n");
458 if (--app->ref_count)
459 return;
461 /* Move the reference to the application in the lock table. */
462 slot = app->slot;
463 /* FIXME: We are ignoring any error value. */
464 lock_reader (slot);
465 if (lock_table[slot].app != app)
467 unlock_reader (slot);
468 log_bug ("app mismatch %p/%p\n", app, lock_table[slot].app);
469 deallocate_app (app);
470 return;
473 if (lock_table[slot].last_app)
474 deallocate_app (lock_table[slot].last_app);
475 if (app->no_reuse)
477 /* If we shall not re-use the application we can't save it for
478 later use. */
479 deallocate_app (app);
480 lock_table[slot].last_app = NULL;
482 else
483 lock_table[slot].last_app = lock_table[slot].app;
484 lock_table[slot].app = NULL;
485 unlock_reader (slot);
490 /* The serial number may need some cosmetics. Do it here. This
491 function shall only be called once after a new serial number has
492 been put into APP->serialno.
494 Prefixes we use:
496 FF 00 00 = For serial numbers starting with an FF
497 FF 01 00 = Some german p15 cards return an empty serial number so the
498 serial number from the EF(TokenInfo) is used instead.
499 FF 7F 00 = No serialno.
501 All other serial number not starting with FF are used as they are.
503 gpg_error_t
504 app_munge_serialno (app_t app)
506 if (app->serialnolen && app->serialno[0] == 0xff)
508 /* The serial number starts with our special prefix. This
509 requires that we put our default prefix "FF0000" in front. */
510 unsigned char *p = xtrymalloc (app->serialnolen + 3);
511 if (!p)
512 return gpg_error_from_syserror ();
513 memcpy (p, "\xff\0", 3);
514 memcpy (p+3, app->serialno, app->serialnolen);
515 app->serialnolen += 3;
516 xfree (app->serialno);
517 app->serialno = p;
519 else if (!app->serialnolen)
521 unsigned char *p = xtrymalloc (3);
522 if (!p)
523 return gpg_error_from_syserror ();
524 memcpy (p, "\xff\x7f", 3);
525 app->serialnolen = 3;
526 xfree (app->serialno);
527 app->serialno = p;
529 return 0;
534 /* Retrieve the serial number and the time of the last update of the
535 card. The serial number is returned as a malloced string (hex
536 encoded) in SERIAL and the time of update is returned in STAMP. If
537 no update time is available the returned value is 0. Caller must
538 free SERIAL unless the function returns an error. If STAMP is not
539 of interest, NULL may be passed. */
540 gpg_error_t
541 app_get_serial_and_stamp (app_t app, char **serial, time_t *stamp)
543 char *buf;
545 if (!app || !serial)
546 return gpg_error (GPG_ERR_INV_VALUE);
548 *serial = NULL;
549 if (stamp)
550 *stamp = 0; /* not available */
552 if (!app->serialnolen)
553 buf = xtrystrdup ("FF7F00");
554 else
555 buf = bin2hex (app->serialno, app->serialnolen, NULL);
556 if (!buf)
557 return gpg_error_from_syserror ();
559 *serial = buf;
560 return 0;
564 /* Write out the application specifig status lines for the LEARN
565 command. */
566 gpg_error_t
567 app_write_learn_status (app_t app, ctrl_t ctrl, unsigned int flags)
569 gpg_error_t err;
571 if (!app)
572 return gpg_error (GPG_ERR_INV_VALUE);
573 if (!app->ref_count)
574 return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
575 if (!app->fnc.learn_status)
576 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
578 /* We do not send APPTYPE if only keypairinfo is requested. */
579 if (app->apptype && !(flags & 1))
580 send_status_info (ctrl, "APPTYPE",
581 app->apptype, strlen (app->apptype), NULL, 0);
582 err = lock_reader (app->slot);
583 if (err)
584 return err;
585 err = app->fnc.learn_status (app, ctrl, flags);
586 unlock_reader (app->slot);
587 return err;
591 /* Read the certificate with id CERTID (as returned by learn_status in
592 the CERTINFO status lines) and return it in the freshly allocated
593 buffer put into CERT and the length of the certificate put into
594 CERTLEN. */
595 gpg_error_t
596 app_readcert (app_t app, const char *certid,
597 unsigned char **cert, size_t *certlen)
599 gpg_error_t err;
601 if (!app)
602 return gpg_error (GPG_ERR_INV_VALUE);
603 if (!app->ref_count)
604 return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
605 if (!app->fnc.readcert)
606 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
607 err = lock_reader (app->slot);
608 if (err)
609 return err;
610 err = app->fnc.readcert (app, certid, cert, certlen);
611 unlock_reader (app->slot);
612 return err;
616 /* Read the key with ID KEYID. On success a canonical encoded
617 S-expression with the public key will get stored at PK and its
618 length (for assertions) at PKLEN; the caller must release that
619 buffer. On error NULL will be stored at PK and PKLEN and an error
620 code returned.
622 This function might not be supported by all applications. */
623 gpg_error_t
624 app_readkey (app_t app, const char *keyid, unsigned char **pk, size_t *pklen)
626 gpg_error_t err;
628 if (pk)
629 *pk = NULL;
630 if (pklen)
631 *pklen = 0;
633 if (!app || !keyid || !pk || !pklen)
634 return gpg_error (GPG_ERR_INV_VALUE);
635 if (!app->ref_count)
636 return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
637 if (!app->fnc.readkey)
638 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
639 err = lock_reader (app->slot);
640 if (err)
641 return err;
642 err= app->fnc.readkey (app, keyid, pk, pklen);
643 unlock_reader (app->slot);
644 return err;
648 /* Perform a GETATTR operation. */
649 gpg_error_t
650 app_getattr (app_t app, ctrl_t ctrl, const char *name)
652 gpg_error_t err;
654 if (!app || !name || !*name)
655 return gpg_error (GPG_ERR_INV_VALUE);
656 if (!app->ref_count)
657 return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
659 if (app->apptype && name && !strcmp (name, "APPTYPE"))
661 send_status_info (ctrl, "APPTYPE",
662 app->apptype, strlen (app->apptype), NULL, 0);
663 return 0;
665 if (name && !strcmp (name, "SERIALNO"))
667 char *serial;
668 time_t stamp;
669 int rc;
671 rc = app_get_serial_and_stamp (app, &serial, &stamp);
672 if (rc)
673 return rc;
674 send_status_info (ctrl, "SERIALNO", serial, strlen (serial), NULL, 0);
675 xfree (serial);
676 return 0;
679 if (!app->fnc.getattr)
680 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
681 err = lock_reader (app->slot);
682 if (err)
683 return err;
684 err = app->fnc.getattr (app, ctrl, name);
685 unlock_reader (app->slot);
686 return err;
689 /* Perform a SETATTR operation. */
690 gpg_error_t
691 app_setattr (app_t app, const char *name,
692 gpg_error_t (*pincb)(void*, const char *, char **),
693 void *pincb_arg,
694 const unsigned char *value, size_t valuelen)
696 gpg_error_t err;
698 if (!app || !name || !*name || !value)
699 return gpg_error (GPG_ERR_INV_VALUE);
700 if (!app->ref_count)
701 return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
702 if (!app->fnc.setattr)
703 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
704 err = lock_reader (app->slot);
705 if (err)
706 return err;
707 err = app->fnc.setattr (app, name, pincb, pincb_arg, value, valuelen);
708 unlock_reader (app->slot);
709 return err;
712 /* Create the signature and return the allocated result in OUTDATA.
713 If a PIN is required the PINCB will be used to ask for the PIN; it
714 should return the PIN in an allocated buffer and put it into PIN. */
715 gpg_error_t
716 app_sign (app_t app, const char *keyidstr, int hashalgo,
717 gpg_error_t (*pincb)(void*, const char *, char **),
718 void *pincb_arg,
719 const void *indata, size_t indatalen,
720 unsigned char **outdata, size_t *outdatalen )
722 gpg_error_t err;
724 if (!app || !indata || !indatalen || !outdata || !outdatalen || !pincb)
725 return gpg_error (GPG_ERR_INV_VALUE);
726 if (!app->ref_count)
727 return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
728 if (!app->fnc.sign)
729 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
730 err = lock_reader (app->slot);
731 if (err)
732 return err;
733 err = app->fnc.sign (app, keyidstr, hashalgo,
734 pincb, pincb_arg,
735 indata, indatalen,
736 outdata, outdatalen);
737 unlock_reader (app->slot);
738 if (opt.verbose)
739 log_info ("operation sign result: %s\n", gpg_strerror (err));
740 return err;
743 /* Create the signature using the INTERNAL AUTHENTICATE command and
744 return the allocated result in OUTDATA. If a PIN is required the
745 PINCB will be used to ask for the PIN; it should return the PIN in
746 an allocated buffer and put it into PIN. */
747 gpg_error_t
748 app_auth (app_t app, const char *keyidstr,
749 gpg_error_t (*pincb)(void*, const char *, char **),
750 void *pincb_arg,
751 const void *indata, size_t indatalen,
752 unsigned char **outdata, size_t *outdatalen )
754 gpg_error_t err;
756 if (!app || !indata || !indatalen || !outdata || !outdatalen || !pincb)
757 return gpg_error (GPG_ERR_INV_VALUE);
758 if (!app->ref_count)
759 return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
760 if (!app->fnc.auth)
761 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
762 err = lock_reader (app->slot);
763 if (err)
764 return err;
765 err = app->fnc.auth (app, keyidstr,
766 pincb, pincb_arg,
767 indata, indatalen,
768 outdata, outdatalen);
769 unlock_reader (app->slot);
770 if (opt.verbose)
771 log_info ("operation auth result: %s\n", gpg_strerror (err));
772 return err;
776 /* Decrypt the data in INDATA and return the allocated result in OUTDATA.
777 If a PIN is required the PINCB will be used to ask for the PIN; it
778 should return the PIN in an allocated buffer and put it into PIN. */
779 gpg_error_t
780 app_decipher (app_t app, const char *keyidstr,
781 gpg_error_t (*pincb)(void*, const char *, char **),
782 void *pincb_arg,
783 const void *indata, size_t indatalen,
784 unsigned char **outdata, size_t *outdatalen )
786 gpg_error_t err;
788 if (!app || !indata || !indatalen || !outdata || !outdatalen || !pincb)
789 return gpg_error (GPG_ERR_INV_VALUE);
790 if (!app->ref_count)
791 return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
792 if (!app->fnc.decipher)
793 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
794 err = lock_reader (app->slot);
795 if (err)
796 return err;
797 err = app->fnc.decipher (app, keyidstr,
798 pincb, pincb_arg,
799 indata, indatalen,
800 outdata, outdatalen);
801 unlock_reader (app->slot);
802 if (opt.verbose)
803 log_info ("operation decipher result: %s\n", gpg_strerror (err));
804 return err;
808 /* Perform the WRITECERT operation. */
809 gpg_error_t
810 app_writecert (app_t app, ctrl_t ctrl,
811 const char *certidstr,
812 gpg_error_t (*pincb)(void*, const char *, char **),
813 void *pincb_arg,
814 const unsigned char *data, size_t datalen)
816 gpg_error_t err;
818 if (!app || !certidstr || !*certidstr || !pincb)
819 return gpg_error (GPG_ERR_INV_VALUE);
820 if (!app->ref_count)
821 return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
822 if (!app->fnc.writecert)
823 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
824 err = lock_reader (app->slot);
825 if (err)
826 return err;
827 err = app->fnc.writecert (app, ctrl, certidstr,
828 pincb, pincb_arg, data, datalen);
829 unlock_reader (app->slot);
830 if (opt.verbose)
831 log_info ("operation writecert result: %s\n", gpg_strerror (err));
832 return err;
836 /* Perform the WRITEKEY operation. */
837 gpg_error_t
838 app_writekey (app_t app, ctrl_t ctrl,
839 const char *keyidstr, unsigned int flags,
840 gpg_error_t (*pincb)(void*, const char *, char **),
841 void *pincb_arg,
842 const unsigned char *keydata, size_t keydatalen)
844 gpg_error_t err;
846 if (!app || !keyidstr || !*keyidstr || !pincb)
847 return gpg_error (GPG_ERR_INV_VALUE);
848 if (!app->ref_count)
849 return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
850 if (!app->fnc.writekey)
851 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
852 err = lock_reader (app->slot);
853 if (err)
854 return err;
855 err = app->fnc.writekey (app, ctrl, keyidstr, flags,
856 pincb, pincb_arg, keydata, keydatalen);
857 unlock_reader (app->slot);
858 if (opt.verbose)
859 log_info ("operation writekey result: %s\n", gpg_strerror (err));
860 return err;
864 /* Perform a SETATTR operation. */
865 gpg_error_t
866 app_genkey (app_t app, ctrl_t ctrl, const char *keynostr, unsigned int flags,
867 time_t createtime,
868 gpg_error_t (*pincb)(void*, const char *, char **),
869 void *pincb_arg)
871 gpg_error_t err;
873 if (!app || !keynostr || !*keynostr || !pincb)
874 return gpg_error (GPG_ERR_INV_VALUE);
875 if (!app->ref_count)
876 return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
877 if (!app->fnc.genkey)
878 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
879 err = lock_reader (app->slot);
880 if (err)
881 return err;
882 err = app->fnc.genkey (app, ctrl, keynostr, flags,
883 createtime, pincb, pincb_arg);
884 unlock_reader (app->slot);
885 if (opt.verbose)
886 log_info ("operation genkey result: %s\n", gpg_strerror (err));
887 return err;
891 /* Perform a GET CHALLENGE operation. This fucntion is special as it
892 directly accesses the card without any application specific
893 wrapper. */
894 gpg_error_t
895 app_get_challenge (app_t app, size_t nbytes, unsigned char *buffer)
897 gpg_error_t err;
899 if (!app || !nbytes || !buffer)
900 return gpg_error (GPG_ERR_INV_VALUE);
901 if (!app->ref_count)
902 return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
903 err = lock_reader (app->slot);
904 if (err)
905 return err;
906 err = iso7816_get_challenge (app->slot, nbytes, buffer);
907 unlock_reader (app->slot);
908 return err;
913 /* Perform a CHANGE REFERENCE DATA or RESET RETRY COUNTER operation. */
914 gpg_error_t
915 app_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr, int reset_mode,
916 gpg_error_t (*pincb)(void*, const char *, char **),
917 void *pincb_arg)
919 gpg_error_t err;
921 if (!app || !chvnostr || !*chvnostr || !pincb)
922 return gpg_error (GPG_ERR_INV_VALUE);
923 if (!app->ref_count)
924 return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
925 if (!app->fnc.change_pin)
926 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
927 err = lock_reader (app->slot);
928 if (err)
929 return err;
930 err = app->fnc.change_pin (app, ctrl, chvnostr, reset_mode,
931 pincb, pincb_arg);
932 unlock_reader (app->slot);
933 if (opt.verbose)
934 log_info ("operation change_pin result: %s\n", gpg_strerror (err));
935 return err;
939 /* Perform a VERIFY operation without doing anything lese. This may
940 be used to initialze a the PIN cache for long lasting other
941 operations. Its use is highly application dependent. */
942 gpg_error_t
943 app_check_pin (app_t app, const char *keyidstr,
944 gpg_error_t (*pincb)(void*, const char *, char **),
945 void *pincb_arg)
947 gpg_error_t err;
949 if (!app || !keyidstr || !*keyidstr || !pincb)
950 return gpg_error (GPG_ERR_INV_VALUE);
951 if (!app->ref_count)
952 return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
953 if (!app->fnc.check_pin)
954 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
955 err = lock_reader (app->slot);
956 if (err)
957 return err;
958 err = app->fnc.check_pin (app, keyidstr, pincb, pincb_arg);
959 unlock_reader (app->slot);
960 if (opt.verbose)
961 log_info ("operation check_pin result: %s\n", gpg_strerror (err));
962 return err;