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
);
52 print_progress_line (void *opaque
, const char *what
, int pc
, int cur
, int tot
)
59 snprintf (line
, sizeof line
, "%s %c %d %d", what
, pc
, cur
, tot
);
60 send_status_direct (ctrl
, "PROGRESS", line
);
65 /* Lock the reader SLOT. This function shall be used right before
66 calling any of the actual application functions to serialize access
67 to the reader. We do this always even if the reader is not
68 actually used. This allows an actual connection to assume that it
69 never shares a reader (while performing one command). Returns 0 on
70 success; only then the unlock_reader function must be called after
71 returning from the handler. */
73 lock_reader (int slot
, ctrl_t ctrl
)
77 if (slot
< 0 || slot
>= DIM (lock_table
))
78 return gpg_error (slot
<0? GPG_ERR_INV_VALUE
: GPG_ERR_RESOURCE_LIMIT
);
80 if (!lock_table
[slot
].initialized
)
82 if (!pth_mutex_init (&lock_table
[slot
].lock
))
84 err
= gpg_error_from_syserror ();
85 log_error ("error initializing mutex: %s\n", strerror (errno
));
88 lock_table
[slot
].initialized
= 1;
89 lock_table
[slot
].app
= NULL
;
90 lock_table
[slot
].last_app
= NULL
;
93 if (!pth_mutex_acquire (&lock_table
[slot
].lock
, 0, NULL
))
95 err
= gpg_error_from_syserror ();
96 log_error ("failed to acquire APP lock for slot %d: %s\n",
97 slot
, strerror (errno
));
101 apdu_set_progress_cb (slot
, print_progress_line
, ctrl
);
106 /* Release a lock on the reader. See lock_reader(). */
108 unlock_reader (int slot
)
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
);
114 apdu_set_progress_cb (slot
, NULL
, NULL
);
116 if (!pth_mutex_release (&lock_table
[slot
].lock
))
117 log_error ("failed to release APP lock for slot %d: %s\n",
118 slot
, strerror (errno
));
123 dump_mutex_state (pth_mutex_t
*m
)
127 log_printf ("unknown under W32");
129 if (!(m
->mx_state
& PTH_MUTEX_INITIALIZED
))
130 log_printf ("not_initialized");
131 else if (!(m
->mx_state
& PTH_MUTEX_LOCKED
))
132 log_printf ("not_locked");
134 log_printf ("locked tid=0x%lx count=%lu", (long)m
->mx_owner
, m
->mx_count
);
139 /* This function may be called to print information pertaining to the
140 current state of this module to the log. */
142 app_dump_state (void)
146 for (slot
=0; slot
< DIM (lock_table
); slot
++)
147 if (lock_table
[slot
].initialized
)
149 log_info ("app_dump_state: slot=%d lock=", slot
);
150 dump_mutex_state (&lock_table
[slot
].lock
);
151 if (lock_table
[slot
].app
)
153 log_printf (" app=%p", lock_table
[slot
].app
);
154 if (lock_table
[slot
].app
->apptype
)
155 log_printf (" type=`%s'", lock_table
[slot
].app
->apptype
);
157 if (lock_table
[slot
].last_app
)
159 log_printf (" lastapp=%p", lock_table
[slot
].last_app
);
160 if (lock_table
[slot
].last_app
->apptype
)
161 log_printf (" type=`%s'", lock_table
[slot
].last_app
->apptype
);
167 /* Check wether the application NAME is allowed. This does not mean
168 we have support for it though. */
170 is_app_allowed (const char *name
)
174 for (l
=opt
.disabled_applications
; l
; l
= l
->next
)
175 if (!strcmp (l
->d
, name
))
181 /* This may be called to tell this module about a removed or resetted card. */
183 application_notify_card_reset (int slot
)
187 if (slot
< 0 || slot
>= DIM (lock_table
))
190 /* FIXME: We are ignoring any error value here. */
191 lock_reader (slot
, NULL
);
193 /* Mark application as non-reusable. */
194 if (lock_table
[slot
].app
)
195 lock_table
[slot
].app
->no_reuse
= 1;
197 /* Deallocate a saved application for that slot, so that we won't
198 try to reuse it. If there is no saved application, set a flag so
199 that we won't save the current state. */
200 app
= lock_table
[slot
].last_app
;
204 lock_table
[slot
].last_app
= NULL
;
205 deallocate_app (app
);
207 unlock_reader (slot
);
211 /* This function is used by the serialno command to check for an
212 application conflict which may appear if the serialno command is
213 used to request a specific application and the connection has
214 already done a select_application. */
216 check_application_conflict (ctrl_t ctrl
, const char *name
)
218 int slot
= ctrl
->reader_slot
;
221 if (slot
< 0 || slot
>= DIM (lock_table
))
222 return gpg_error (GPG_ERR_INV_VALUE
);
224 app
= lock_table
[slot
].initialized
? lock_table
[slot
].app
: NULL
;
225 if (app
&& app
->apptype
&& name
)
226 if ( ascii_strcasecmp (app
->apptype
, name
))
227 return gpg_error (GPG_ERR_CONFLICT
);
232 /* If called with NAME as NULL, select the best fitting application
233 and return a context; otherwise select the application with NAME
234 and return a context. SLOT identifies the reader device. Returns
235 an error code and stores NULL at R_APP if no application was found
236 or no card is present. */
238 select_application (ctrl_t ctrl
, int slot
, const char *name
, app_t
*r_app
)
242 unsigned char *result
= NULL
;
249 err
= lock_reader (slot
, ctrl
);
253 /* First check whether we already have an application to share. */
254 app
= lock_table
[slot
].initialized
? lock_table
[slot
].app
: NULL
;
256 if (!app
->apptype
|| ascii_strcasecmp (app
->apptype
, name
))
258 unlock_reader (slot
);
260 log_info ("application `%s' in use by reader %d - can't switch\n",
262 return gpg_error (GPG_ERR_CONFLICT
);
265 /* Don't use a non-reusable marked application. */
266 if (app
&& app
->no_reuse
)
268 unlock_reader (slot
);
269 log_info ("lingering application `%s' in use by reader %d"
271 app
->apptype
? app
->apptype
:"?", slot
);
272 return gpg_error (GPG_ERR_CONFLICT
);
275 /* If we don't have an app, check whether we have a saved
276 application for that slot. This is useful so that a card does
277 not get reset even if only one session is using the card - this
278 way the PIN cache and other cached data are preserved. */
279 if (!app
&& lock_table
[slot
].initialized
&& lock_table
[slot
].last_app
)
281 app
= lock_table
[slot
].last_app
;
282 if (!name
|| (app
->apptype
&& !ascii_strcasecmp (app
->apptype
, name
)) )
284 /* Yes, we can reuse this application - either the caller
285 requested an unspecific one or the requested one matches
287 lock_table
[slot
].app
= app
;
288 lock_table
[slot
].last_app
= NULL
;
292 /* No, this saved application can't be used - deallocate it. */
293 lock_table
[slot
].last_app
= NULL
;
294 deallocate_app (app
);
299 /* If we can reuse an application, bump the reference count and
303 if (app
->slot
!= slot
)
304 log_bug ("slot mismatch %d/%d\n", app
->slot
, slot
);
309 unlock_reader (slot
);
310 return 0; /* Okay: We share that one. */
313 /* Need to allocate a new one. */
314 app
= xtrycalloc (1, sizeof *app
);
317 err
= gpg_error_from_syserror ();
318 log_info ("error allocating context: %s\n", gpg_strerror (err
));
319 unlock_reader (slot
);
325 /* Fixme: We should now first check whether a card is at all
328 /* Try to read the GDO file first to get a default serial number. */
329 err
= iso7816_select_file (slot
, 0x3F00, 1, NULL
, NULL
);
331 err
= iso7816_select_file (slot
, 0x2F02, 0, NULL
, NULL
);
333 err
= iso7816_read_binary (slot
, 0, 0, &result
, &resultlen
);
337 const unsigned char *p
;
339 p
= find_tlv_unchecked (result
, resultlen
, 0x5A, &n
);
341 resultlen
-= (p
-result
);
342 if (p
&& n
> resultlen
&& n
== 0x0d && resultlen
+1 == n
)
344 /* The object it does not fit into the buffer. This is an
345 invalid encoding (or the buffer is too short. However, I
346 have some test cards with such an invalid encoding and
347 therefore I use this ugly workaround to return something
348 I can further experiment with. */
349 log_info ("enabling BMI testcard workaround\n");
353 if (p
&& n
<= resultlen
)
355 /* The GDO file is pretty short, thus we simply reuse it for
356 storing the serial number. */
357 memmove (result
, p
, n
);
358 app
->serialno
= result
;
359 app
->serialnolen
= n
;
360 err
= app_munge_serialno (app
);
369 /* For certain error codes, there is no need to try more. */
370 if (gpg_err_code (err
) == GPG_ERR_CARD_NOT_PRESENT
371 || gpg_err_code (err
) == GPG_ERR_ENODEV
)
374 /* Figure out the application to use. */
375 err
= gpg_error (GPG_ERR_NOT_FOUND
);
377 if (err
&& is_app_allowed ("openpgp")
378 && (!name
|| !strcmp (name
, "openpgp")))
379 err
= app_select_openpgp (app
);
380 if (err
&& is_app_allowed ("nks") && (!name
|| !strcmp (name
, "nks")))
381 err
= app_select_nks (app
);
382 if (err
&& is_app_allowed ("p15") && (!name
|| !strcmp (name
, "p15")))
383 err
= app_select_p15 (app
);
384 if (err
&& is_app_allowed ("dinsig") && (!name
|| !strcmp (name
, "dinsig")))
385 err
= app_select_dinsig (app
);
386 if (err
&& is_app_allowed ("geldkarte")
387 && (!name
|| !strcmp (name
, "geldkarte")))
388 err
= app_select_geldkarte (app
);
390 err
= gpg_error (GPG_ERR_NOT_SUPPORTED
);
396 log_info ("can't select application `%s': %s\n",
397 name
, gpg_strerror (err
));
399 log_info ("no supported card application found: %s\n",
402 unlock_reader (slot
);
408 lock_table
[slot
].app
= app
;
410 unlock_reader (slot
);
416 get_supported_applications (void)
418 const char *list
[] = {
430 for (nbytes
=1, idx
=0; list
[idx
]; idx
++)
431 nbytes
+= strlen (list
[idx
]) + 1 + 1;
433 buffer
= xtrymalloc (nbytes
);
437 for (p
=buffer
, idx
=0; list
[idx
]; idx
++)
438 if (is_app_allowed (list
[idx
]))
439 p
= stpcpy (stpcpy (p
, list
[idx
]), ":\n");
446 /* Deallocate the application. */
448 deallocate_app (app_t app
)
452 app
->fnc
.deinit (app
);
453 app
->fnc
.deinit
= NULL
;
456 xfree (app
->serialno
);
460 /* Free the resources associated with the application APP. APP is
461 allowed to be NULL in which case this is a no-op. Note that we are
462 using reference counting to track the users of the application and
463 actually deferring the deallocation to allow for a later reuse by
466 release_application (app_t app
)
474 log_bug ("trying to release an already released context\n");
475 if (--app
->ref_count
)
478 /* Move the reference to the application in the lock table. */
480 /* FIXME: We are ignoring any error value. */
481 lock_reader (slot
, NULL
);
482 if (lock_table
[slot
].app
!= app
)
484 unlock_reader (slot
);
485 log_bug ("app mismatch %p/%p\n", app
, lock_table
[slot
].app
);
486 deallocate_app (app
);
490 if (lock_table
[slot
].last_app
)
491 deallocate_app (lock_table
[slot
].last_app
);
494 /* If we shall not re-use the application we can't save it for
496 deallocate_app (app
);
497 lock_table
[slot
].last_app
= NULL
;
500 lock_table
[slot
].last_app
= lock_table
[slot
].app
;
501 lock_table
[slot
].app
= NULL
;
502 unlock_reader (slot
);
507 /* The serial number may need some cosmetics. Do it here. This
508 function shall only be called once after a new serial number has
509 been put into APP->serialno.
513 FF 00 00 = For serial numbers starting with an FF
514 FF 01 00 = Some german p15 cards return an empty serial number so the
515 serial number from the EF(TokenInfo) is used instead.
516 FF 7F 00 = No serialno.
518 All other serial number not starting with FF are used as they are.
521 app_munge_serialno (app_t app
)
523 if (app
->serialnolen
&& app
->serialno
[0] == 0xff)
525 /* The serial number starts with our special prefix. This
526 requires that we put our default prefix "FF0000" in front. */
527 unsigned char *p
= xtrymalloc (app
->serialnolen
+ 3);
529 return gpg_error_from_syserror ();
530 memcpy (p
, "\xff\0", 3);
531 memcpy (p
+3, app
->serialno
, app
->serialnolen
);
532 app
->serialnolen
+= 3;
533 xfree (app
->serialno
);
536 else if (!app
->serialnolen
)
538 unsigned char *p
= xtrymalloc (3);
540 return gpg_error_from_syserror ();
541 memcpy (p
, "\xff\x7f", 3);
542 app
->serialnolen
= 3;
543 xfree (app
->serialno
);
551 /* Retrieve the serial number and the time of the last update of the
552 card. The serial number is returned as a malloced string (hex
553 encoded) in SERIAL and the time of update is returned in STAMP. If
554 no update time is available the returned value is 0. Caller must
555 free SERIAL unless the function returns an error. If STAMP is not
556 of interest, NULL may be passed. */
558 app_get_serial_and_stamp (app_t app
, char **serial
, time_t *stamp
)
563 return gpg_error (GPG_ERR_INV_VALUE
);
567 *stamp
= 0; /* not available */
569 if (!app
->serialnolen
)
570 buf
= xtrystrdup ("FF7F00");
572 buf
= bin2hex (app
->serialno
, app
->serialnolen
, NULL
);
574 return gpg_error_from_syserror ();
581 /* Write out the application specifig status lines for the LEARN
584 app_write_learn_status (app_t app
, ctrl_t ctrl
, unsigned int flags
)
589 return gpg_error (GPG_ERR_INV_VALUE
);
591 return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED
);
592 if (!app
->fnc
.learn_status
)
593 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION
);
595 /* We do not send APPTYPE if only keypairinfo is requested. */
596 if (app
->apptype
&& !(flags
& 1))
597 send_status_info (ctrl
, "APPTYPE",
598 app
->apptype
, strlen (app
->apptype
), NULL
, 0);
599 err
= lock_reader (app
->slot
, ctrl
);
602 err
= app
->fnc
.learn_status (app
, ctrl
, flags
);
603 unlock_reader (app
->slot
);
608 /* Read the certificate with id CERTID (as returned by learn_status in
609 the CERTINFO status lines) and return it in the freshly allocated
610 buffer put into CERT and the length of the certificate put into
613 app_readcert (app_t app
, const char *certid
,
614 unsigned char **cert
, size_t *certlen
)
619 return gpg_error (GPG_ERR_INV_VALUE
);
621 return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED
);
622 if (!app
->fnc
.readcert
)
623 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION
);
624 err
= lock_reader (app
->slot
, NULL
/* FIXME*/);
627 err
= app
->fnc
.readcert (app
, certid
, cert
, certlen
);
628 unlock_reader (app
->slot
);
633 /* Read the key with ID KEYID. On success a canonical encoded
634 S-expression with the public key will get stored at PK and its
635 length (for assertions) at PKLEN; the caller must release that
636 buffer. On error NULL will be stored at PK and PKLEN and an error
639 This function might not be supported by all applications. */
641 app_readkey (app_t app
, const char *keyid
, unsigned char **pk
, size_t *pklen
)
650 if (!app
|| !keyid
|| !pk
|| !pklen
)
651 return gpg_error (GPG_ERR_INV_VALUE
);
653 return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED
);
654 if (!app
->fnc
.readkey
)
655 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION
);
656 err
= lock_reader (app
->slot
, NULL
/*FIXME*/);
659 err
= app
->fnc
.readkey (app
, keyid
, pk
, pklen
);
660 unlock_reader (app
->slot
);
665 /* Perform a GETATTR operation. */
667 app_getattr (app_t app
, ctrl_t ctrl
, const char *name
)
671 if (!app
|| !name
|| !*name
)
672 return gpg_error (GPG_ERR_INV_VALUE
);
674 return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED
);
676 if (app
->apptype
&& name
&& !strcmp (name
, "APPTYPE"))
678 send_status_info (ctrl
, "APPTYPE",
679 app
->apptype
, strlen (app
->apptype
), NULL
, 0);
682 if (name
&& !strcmp (name
, "SERIALNO"))
688 rc
= app_get_serial_and_stamp (app
, &serial
, &stamp
);
691 send_status_info (ctrl
, "SERIALNO", serial
, strlen (serial
), NULL
, 0);
696 if (!app
->fnc
.getattr
)
697 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION
);
698 err
= lock_reader (app
->slot
, ctrl
);
701 err
= app
->fnc
.getattr (app
, ctrl
, name
);
702 unlock_reader (app
->slot
);
706 /* Perform a SETATTR operation. */
708 app_setattr (app_t app
, const char *name
,
709 gpg_error_t (*pincb
)(void*, const char *, char **),
711 const unsigned char *value
, size_t valuelen
)
715 if (!app
|| !name
|| !*name
|| !value
)
716 return gpg_error (GPG_ERR_INV_VALUE
);
718 return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED
);
719 if (!app
->fnc
.setattr
)
720 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION
);
721 err
= lock_reader (app
->slot
, NULL
/*FIXME*/);
724 err
= app
->fnc
.setattr (app
, name
, pincb
, pincb_arg
, value
, valuelen
);
725 unlock_reader (app
->slot
);
729 /* Create the signature and return the allocated result in OUTDATA.
730 If a PIN is required the PINCB will be used to ask for the PIN; it
731 should return the PIN in an allocated buffer and put it into PIN. */
733 app_sign (app_t app
, const char *keyidstr
, int hashalgo
,
734 gpg_error_t (*pincb
)(void*, const char *, char **),
736 const void *indata
, size_t indatalen
,
737 unsigned char **outdata
, size_t *outdatalen
)
741 if (!app
|| !indata
|| !indatalen
|| !outdata
|| !outdatalen
|| !pincb
)
742 return gpg_error (GPG_ERR_INV_VALUE
);
744 return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED
);
746 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION
);
747 err
= lock_reader (app
->slot
, NULL
/*FIXME*/);
750 err
= app
->fnc
.sign (app
, keyidstr
, hashalgo
,
753 outdata
, outdatalen
);
754 unlock_reader (app
->slot
);
756 log_info ("operation sign result: %s\n", gpg_strerror (err
));
760 /* Create the signature using the INTERNAL AUTHENTICATE command and
761 return the allocated result in OUTDATA. If a PIN is required the
762 PINCB will be used to ask for the PIN; it should return the PIN in
763 an allocated buffer and put it into PIN. */
765 app_auth (app_t app
, const char *keyidstr
,
766 gpg_error_t (*pincb
)(void*, const char *, char **),
768 const void *indata
, size_t indatalen
,
769 unsigned char **outdata
, size_t *outdatalen
)
773 if (!app
|| !indata
|| !indatalen
|| !outdata
|| !outdatalen
|| !pincb
)
774 return gpg_error (GPG_ERR_INV_VALUE
);
776 return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED
);
778 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION
);
779 err
= lock_reader (app
->slot
, NULL
/*FIXME*/);
782 err
= app
->fnc
.auth (app
, keyidstr
,
785 outdata
, outdatalen
);
786 unlock_reader (app
->slot
);
788 log_info ("operation auth result: %s\n", gpg_strerror (err
));
793 /* Decrypt the data in INDATA and return the allocated result in OUTDATA.
794 If a PIN is required the PINCB will be used to ask for the PIN; it
795 should return the PIN in an allocated buffer and put it into PIN. */
797 app_decipher (app_t app
, const char *keyidstr
,
798 gpg_error_t (*pincb
)(void*, const char *, char **),
800 const void *indata
, size_t indatalen
,
801 unsigned char **outdata
, size_t *outdatalen
)
805 if (!app
|| !indata
|| !indatalen
|| !outdata
|| !outdatalen
|| !pincb
)
806 return gpg_error (GPG_ERR_INV_VALUE
);
808 return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED
);
809 if (!app
->fnc
.decipher
)
810 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION
);
811 err
= lock_reader (app
->slot
, NULL
/*FIXME*/);
814 err
= app
->fnc
.decipher (app
, keyidstr
,
817 outdata
, outdatalen
);
818 unlock_reader (app
->slot
);
820 log_info ("operation decipher result: %s\n", gpg_strerror (err
));
825 /* Perform the WRITECERT operation. */
827 app_writecert (app_t app
, ctrl_t ctrl
,
828 const char *certidstr
,
829 gpg_error_t (*pincb
)(void*, const char *, char **),
831 const unsigned char *data
, size_t datalen
)
835 if (!app
|| !certidstr
|| !*certidstr
|| !pincb
)
836 return gpg_error (GPG_ERR_INV_VALUE
);
838 return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED
);
839 if (!app
->fnc
.writecert
)
840 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION
);
841 err
= lock_reader (app
->slot
, ctrl
);
844 err
= app
->fnc
.writecert (app
, ctrl
, certidstr
,
845 pincb
, pincb_arg
, data
, datalen
);
846 unlock_reader (app
->slot
);
848 log_info ("operation writecert result: %s\n", gpg_strerror (err
));
853 /* Perform the WRITEKEY operation. */
855 app_writekey (app_t app
, ctrl_t ctrl
,
856 const char *keyidstr
, unsigned int flags
,
857 gpg_error_t (*pincb
)(void*, const char *, char **),
859 const unsigned char *keydata
, size_t keydatalen
)
863 if (!app
|| !keyidstr
|| !*keyidstr
|| !pincb
)
864 return gpg_error (GPG_ERR_INV_VALUE
);
866 return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED
);
867 if (!app
->fnc
.writekey
)
868 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION
);
869 err
= lock_reader (app
->slot
, ctrl
);
872 err
= app
->fnc
.writekey (app
, ctrl
, keyidstr
, flags
,
873 pincb
, pincb_arg
, keydata
, keydatalen
);
874 unlock_reader (app
->slot
);
876 log_info ("operation writekey result: %s\n", gpg_strerror (err
));
881 /* Perform a SETATTR operation. */
883 app_genkey (app_t app
, ctrl_t ctrl
, const char *keynostr
, unsigned int flags
,
885 gpg_error_t (*pincb
)(void*, const char *, char **),
890 if (!app
|| !keynostr
|| !*keynostr
|| !pincb
)
891 return gpg_error (GPG_ERR_INV_VALUE
);
893 return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED
);
894 if (!app
->fnc
.genkey
)
895 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION
);
896 err
= lock_reader (app
->slot
, ctrl
);
899 err
= app
->fnc
.genkey (app
, ctrl
, keynostr
, flags
,
900 createtime
, pincb
, pincb_arg
);
901 unlock_reader (app
->slot
);
903 log_info ("operation genkey result: %s\n", gpg_strerror (err
));
908 /* Perform a GET CHALLENGE operation. This fucntion is special as it
909 directly accesses the card without any application specific
912 app_get_challenge (app_t app
, size_t nbytes
, unsigned char *buffer
)
916 if (!app
|| !nbytes
|| !buffer
)
917 return gpg_error (GPG_ERR_INV_VALUE
);
919 return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED
);
920 err
= lock_reader (app
->slot
, NULL
/*FIXME*/);
923 err
= iso7816_get_challenge (app
->slot
, nbytes
, buffer
);
924 unlock_reader (app
->slot
);
930 /* Perform a CHANGE REFERENCE DATA or RESET RETRY COUNTER operation. */
932 app_change_pin (app_t app
, ctrl_t ctrl
, const char *chvnostr
, int reset_mode
,
933 gpg_error_t (*pincb
)(void*, const char *, char **),
938 if (!app
|| !chvnostr
|| !*chvnostr
|| !pincb
)
939 return gpg_error (GPG_ERR_INV_VALUE
);
941 return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED
);
942 if (!app
->fnc
.change_pin
)
943 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION
);
944 err
= lock_reader (app
->slot
, ctrl
);
947 err
= app
->fnc
.change_pin (app
, ctrl
, chvnostr
, reset_mode
,
949 unlock_reader (app
->slot
);
951 log_info ("operation change_pin result: %s\n", gpg_strerror (err
));
956 /* Perform a VERIFY operation without doing anything lese. This may
957 be used to initialze a the PIN cache for long lasting other
958 operations. Its use is highly application dependent. */
960 app_check_pin (app_t app
, const char *keyidstr
,
961 gpg_error_t (*pincb
)(void*, const char *, char **),
966 if (!app
|| !keyidstr
|| !*keyidstr
|| !pincb
)
967 return gpg_error (GPG_ERR_INV_VALUE
);
969 return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED
);
970 if (!app
->fnc
.check_pin
)
971 return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION
);
972 err
= lock_reader (app
->slot
, NULL
/*FIXME*/);
975 err
= app
->fnc
.check_pin (app
, keyidstr
, pincb
, pincb_arg
);
976 unlock_reader (app
->slot
);
978 log_info ("operation check_pin result: %s\n", gpg_strerror (err
));