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/>.
28 #include "app-common.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). */
41 app_t app
; /* Application context in use or NULL. */
42 app_t last_app
; /* Last application object used as this slot or NULL. */
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. */
59 lock_reader (int slot
)
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
));
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
));
90 /* Release a lock on the reader. See lock_reader(). */
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
));
106 dump_mutex_state (pth_mutex_t
*m
)
110 log_printf ("unknown under W32");
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");
117 log_printf ("locked tid=0x%lx count=%lu", (long)m
->mx_owner
, m
->mx_count
);
122 /* This function may be called to print information pertaining to the
123 current state of this module to the log. */
125 app_dump_state (void)
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
);
150 /* Check wether the application NAME is allowed. This does not mean
151 we have support for it though. */
153 is_app_allowed (const char *name
)
157 for (l
=opt
.disabled_applications
; l
; l
= l
->next
)
158 if (!strcmp (l
->d
, name
))
164 /* This may be called to tell this module about a removed or resetted card. */
166 application_notify_card_reset (int slot
)
170 if (slot
< 0 || slot
>= DIM (lock_table
))
173 /* FIXME: We are ignoring any error value here. */
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
;
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. */
199 check_application_conflict (ctrl_t ctrl
, const char *name
)
201 int slot
= ctrl
->reader_slot
;
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
);
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. */
221 select_application (ctrl_t ctrl
, int slot
, const char *name
, app_t
*r_app
)
225 unsigned char *result
= NULL
;
232 err
= lock_reader (slot
);
236 /* First check whether we already have an application to share. */
237 app
= lock_table
[slot
].initialized
? lock_table
[slot
].app
: NULL
;
239 if (!app
->apptype
|| ascii_strcasecmp (app
->apptype
, name
))
241 unlock_reader (slot
);
243 log_info ("application `%s' in use by reader %d - can't switch\n",
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"
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
270 lock_table
[slot
].app
= app
;
271 lock_table
[slot
].last_app
= NULL
;
275 /* No, this saved application can't be used - deallocate it. */
276 lock_table
[slot
].last_app
= NULL
;
277 deallocate_app (app
);
282 /* If we can reuse an application, bump the reference count and
286 if (app
->slot
!= slot
)
287 log_bug ("slot mismatch %d/%d\n", app
->slot
, slot
);
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
);
300 err
= gpg_error_from_syserror ();
301 log_info ("error allocating context: %s\n", gpg_strerror (err
));
302 unlock_reader (slot
);
308 /* Fixme: We should now first check whether a card is at all
311 /* Try to read the GDO file first to get a default serial number. */
312 err
= iso7816_select_file (slot
, 0x3F00, 1, NULL
, NULL
);
314 err
= iso7816_select_file (slot
, 0x2F02, 0, NULL
, NULL
);
316 err
= iso7816_read_binary (slot
, 0, 0, &result
, &resultlen
);
320 const unsigned char *p
;
322 p
= find_tlv_unchecked (result
, resultlen
, 0x5A, &n
);
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");
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
);
352 /* For certain error codes, there is no need to try more. */
353 if (gpg_err_code (err
) == GPG_ERR_CARD_NOT_PRESENT
)
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
);
373 err
= gpg_error (GPG_ERR_NOT_SUPPORTED
);
379 log_info ("can't select application `%s': %s\n",
380 name
, gpg_strerror (err
));
382 log_info ("no supported card application found: %s\n",
385 unlock_reader (slot
);
391 lock_table
[slot
].app
= app
;
393 unlock_reader (slot
);
399 get_supported_applications (void)
401 const char *list
[] = {
413 for (nbytes
=1, idx
=0; list
[idx
]; idx
++)
414 nbytes
+= strlen (list
[idx
]) + 1 + 1;
416 buffer
= xtrymalloc (nbytes
);
420 for (p
=buffer
, idx
=0; list
[idx
]; idx
++)
421 if (is_app_allowed (list
[idx
]))
422 p
= stpcpy (stpcpy (p
, list
[idx
]), ":\n");
429 /* Deallocate the application. */
431 deallocate_app (app_t app
)
435 app
->fnc
.deinit (app
);
436 app
->fnc
.deinit
= NULL
;
439 xfree (app
->serialno
);
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
449 release_application (app_t app
)
457 log_bug ("trying to release an already released context\n");
458 if (--app
->ref_count
)
461 /* Move the reference to the application in the lock table. */
463 /* FIXME: We are ignoring any error value. */
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
);
473 if (lock_table
[slot
].last_app
)
474 deallocate_app (lock_table
[slot
].last_app
);
477 /* If we shall not re-use the application we can't save it for
479 deallocate_app (app
);
480 lock_table
[slot
].last_app
= NULL
;
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.
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.
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);
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
);
519 else if (!app
->serialnolen
)
521 unsigned char *p
= xtrymalloc (3);
523 return gpg_error_from_syserror ();
524 memcpy (p
, "\xff\x7f", 3);
525 app
->serialnolen
= 3;
526 xfree (app
->serialno
);
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. */
541 app_get_serial_and_stamp (app_t app
, char **serial
, time_t *stamp
)
546 return gpg_error (GPG_ERR_INV_VALUE
);
550 *stamp
= 0; /* not available */
552 if (!app
->serialnolen
)
553 buf
= xtrystrdup ("FF7F00");
555 buf
= bin2hex (app
->serialno
, app
->serialnolen
, NULL
);
557 return gpg_error_from_syserror ();
564 /* Write out the application specifig status lines for the LEARN
567 app_write_learn_status (app_t app
, ctrl_t ctrl
, unsigned int flags
)
572 return gpg_error (GPG_ERR_INV_VALUE
);
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
);
585 err
= app
->fnc
.learn_status (app
, ctrl
, flags
);
586 unlock_reader (app
->slot
);
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
596 app_readcert (app_t app
, const char *certid
,
597 unsigned char **cert
, size_t *certlen
)
602 return gpg_error (GPG_ERR_INV_VALUE
);
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
);
610 err
= app
->fnc
.readcert (app
, certid
, cert
, certlen
);
611 unlock_reader (app
->slot
);
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
622 This function might not be supported by all applications. */
624 app_readkey (app_t app
, const char *keyid
, unsigned char **pk
, size_t *pklen
)
633 if (!app
|| !keyid
|| !pk
|| !pklen
)
634 return gpg_error (GPG_ERR_INV_VALUE
);
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
);
642 err
= app
->fnc
.readkey (app
, keyid
, pk
, pklen
);
643 unlock_reader (app
->slot
);
648 /* Perform a GETATTR operation. */
650 app_getattr (app_t app
, ctrl_t ctrl
, const char *name
)
654 if (!app
|| !name
|| !*name
)
655 return gpg_error (GPG_ERR_INV_VALUE
);
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);
665 if (name
&& !strcmp (name
, "SERIALNO"))
671 rc
= app_get_serial_and_stamp (app
, &serial
, &stamp
);
674 send_status_info (ctrl
, "SERIALNO", serial
, strlen (serial
), NULL
, 0);
679 if (!app
->fnc
.getattr
)
680 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION
);
681 err
= lock_reader (app
->slot
);
684 err
= app
->fnc
.getattr (app
, ctrl
, name
);
685 unlock_reader (app
->slot
);
689 /* Perform a SETATTR operation. */
691 app_setattr (app_t app
, const char *name
,
692 gpg_error_t (*pincb
)(void*, const char *, char **),
694 const unsigned char *value
, size_t valuelen
)
698 if (!app
|| !name
|| !*name
|| !value
)
699 return gpg_error (GPG_ERR_INV_VALUE
);
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
);
707 err
= app
->fnc
.setattr (app
, name
, pincb
, pincb_arg
, value
, valuelen
);
708 unlock_reader (app
->slot
);
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. */
716 app_sign (app_t app
, const char *keyidstr
, int hashalgo
,
717 gpg_error_t (*pincb
)(void*, const char *, char **),
719 const void *indata
, size_t indatalen
,
720 unsigned char **outdata
, size_t *outdatalen
)
724 if (!app
|| !indata
|| !indatalen
|| !outdata
|| !outdatalen
|| !pincb
)
725 return gpg_error (GPG_ERR_INV_VALUE
);
727 return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED
);
729 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION
);
730 err
= lock_reader (app
->slot
);
733 err
= app
->fnc
.sign (app
, keyidstr
, hashalgo
,
736 outdata
, outdatalen
);
737 unlock_reader (app
->slot
);
739 log_info ("operation sign result: %s\n", gpg_strerror (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. */
748 app_auth (app_t app
, const char *keyidstr
,
749 gpg_error_t (*pincb
)(void*, const char *, char **),
751 const void *indata
, size_t indatalen
,
752 unsigned char **outdata
, size_t *outdatalen
)
756 if (!app
|| !indata
|| !indatalen
|| !outdata
|| !outdatalen
|| !pincb
)
757 return gpg_error (GPG_ERR_INV_VALUE
);
759 return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED
);
761 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION
);
762 err
= lock_reader (app
->slot
);
765 err
= app
->fnc
.auth (app
, keyidstr
,
768 outdata
, outdatalen
);
769 unlock_reader (app
->slot
);
771 log_info ("operation auth result: %s\n", gpg_strerror (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. */
780 app_decipher (app_t app
, const char *keyidstr
,
781 gpg_error_t (*pincb
)(void*, const char *, char **),
783 const void *indata
, size_t indatalen
,
784 unsigned char **outdata
, size_t *outdatalen
)
788 if (!app
|| !indata
|| !indatalen
|| !outdata
|| !outdatalen
|| !pincb
)
789 return gpg_error (GPG_ERR_INV_VALUE
);
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
);
797 err
= app
->fnc
.decipher (app
, keyidstr
,
800 outdata
, outdatalen
);
801 unlock_reader (app
->slot
);
803 log_info ("operation decipher result: %s\n", gpg_strerror (err
));
808 /* Perform the WRITECERT operation. */
810 app_writecert (app_t app
, ctrl_t ctrl
,
811 const char *certidstr
,
812 gpg_error_t (*pincb
)(void*, const char *, char **),
814 const unsigned char *data
, size_t datalen
)
818 if (!app
|| !certidstr
|| !*certidstr
|| !pincb
)
819 return gpg_error (GPG_ERR_INV_VALUE
);
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
);
827 err
= app
->fnc
.writecert (app
, ctrl
, certidstr
,
828 pincb
, pincb_arg
, data
, datalen
);
829 unlock_reader (app
->slot
);
831 log_info ("operation writecert result: %s\n", gpg_strerror (err
));
836 /* Perform the WRITEKEY operation. */
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 **),
842 const unsigned char *keydata
, size_t keydatalen
)
846 if (!app
|| !keyidstr
|| !*keyidstr
|| !pincb
)
847 return gpg_error (GPG_ERR_INV_VALUE
);
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
);
855 err
= app
->fnc
.writekey (app
, ctrl
, keyidstr
, flags
,
856 pincb
, pincb_arg
, keydata
, keydatalen
);
857 unlock_reader (app
->slot
);
859 log_info ("operation writekey result: %s\n", gpg_strerror (err
));
864 /* Perform a SETATTR operation. */
866 app_genkey (app_t app
, ctrl_t ctrl
, const char *keynostr
, unsigned int flags
,
868 gpg_error_t (*pincb
)(void*, const char *, char **),
873 if (!app
|| !keynostr
|| !*keynostr
|| !pincb
)
874 return gpg_error (GPG_ERR_INV_VALUE
);
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
);
882 err
= app
->fnc
.genkey (app
, ctrl
, keynostr
, flags
,
883 createtime
, pincb
, pincb_arg
);
884 unlock_reader (app
->slot
);
886 log_info ("operation genkey result: %s\n", gpg_strerror (err
));
891 /* Perform a GET CHALLENGE operation. This fucntion is special as it
892 directly accesses the card without any application specific
895 app_get_challenge (app_t app
, size_t nbytes
, unsigned char *buffer
)
899 if (!app
|| !nbytes
|| !buffer
)
900 return gpg_error (GPG_ERR_INV_VALUE
);
902 return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED
);
903 err
= lock_reader (app
->slot
);
906 err
= iso7816_get_challenge (app
->slot
, nbytes
, buffer
);
907 unlock_reader (app
->slot
);
913 /* Perform a CHANGE REFERENCE DATA or RESET RETRY COUNTER operation. */
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 **),
921 if (!app
|| !chvnostr
|| !*chvnostr
|| !pincb
)
922 return gpg_error (GPG_ERR_INV_VALUE
);
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
);
930 err
= app
->fnc
.change_pin (app
, ctrl
, chvnostr
, reset_mode
,
932 unlock_reader (app
->slot
);
934 log_info ("operation change_pin result: %s\n", gpg_strerror (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. */
943 app_check_pin (app_t app
, const char *keyidstr
,
944 gpg_error_t (*pincb
)(void*, const char *, char **),
949 if (!app
|| !keyidstr
|| !*keyidstr
|| !pincb
)
950 return gpg_error (GPG_ERR_INV_VALUE
);
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
);
958 err
= app
->fnc
.check_pin (app
, keyidstr
, pincb
, pincb_arg
);
959 unlock_reader (app
->slot
);
961 log_info ("operation check_pin result: %s\n", gpg_strerror (err
));