mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-22 10:19:57 +01:00
* README: Doc --disable-card-support and --without-readline.
* configure.ac: Check for readline. Make enable-card-support the default. New option --without-readline. Allow the use of either the development or the stable libusb. * cardglue.h: Add members for CA fingerprints. * cardglue.c (agent_release_card_info): Invalid them. (learn_status_cb): Store them. * app-common.h, app-openpgp.c, iso7816.c, iso7816.h * apdu.c, apdu.h, ccid-driver.c, ccid-driver.h * card-util.c: Updated from current gnupg-1.9. * ccid-driver.h (CCID_DRIVER_ERR_ABORTED): New. * ccid-driver.c (ccid_open_reader): Support the stable 0.1 version of libusb. (ccid_get_atr): Handle short messages. * apdu.c (my_rapdu_get_status): Implemented. * apdu.c: Include <signal.h>. * apdu.c (reader_table_s): Add function pointers for the backends. (apdu_close_reader, apdu_get_status, apdu_activate) (send_apdu): Make use of them. (new_reader_slot): Intialize them to NULL. (dump_ccid_reader_status, ct_dump_reader_status): New. (dump_pcsc_reader_status): New. (open_ct_reader, open_pcsc_reader, open_ccid_reader) (open_osc_reader, open_rapdu_reader): Intialize function pointers. (ct_activate_card, ct_send_apdu, pcsc_send_apdu, osc_send_apdu) (error_string): Removed. Replaced by apdu_strerror. (get_ccid_error_string): Removed. (ct_activate_card): Remove the unused loop. (reset_ct_reader): Implemented. (ct_send_apdu): Activate the card if not yet done. (pcsc_send_apdu): Ditto. * ccid-driver.h: Add error codes. * ccid-driver.c: Implement more or less proper error codes all over the place. * apdu.c (apdu_send_direct): New. (get_ccid_error_string): Add some error code mappings. (send_apdu): Pass error codes along for drivers already supporting them. (host_sw_string): New. (get_ccid_error_string): Use above. (send_apdu_ccid): Reset the reader if it has not yet been done. (open_ccid_reader): Don't care if the ATR can't be read. (apdu_activate_card): New. (apdu_strerror): New. (dump_reader_status): Only enable it with opt.VERBOSE. * iso7816.c (map_sw): Add mappings for the new error codes. * apdu.c (open_ct_reader, open_pcsc_reader, open_ccid_reader) (reset_ccid_reader, open_osc_reader): Call dump_reader_status only in verbose mode. * app-openpgp.c (do_getattr): Fix for sending CA-FPR. * app-openpgp.c (app_openpgp_readkey): Fixed check for valid exponent. * app-openpgp.c (do_setattr): Sync FORCE_CHV1. * card-util.c (change_login): Kludge to allow reading data from a file. (card_edit): Pass ARG_STRING to change_login. (card_status): Print CA fingerprints. (change_cafpr): New. (card_edit): New command CAFPR. * errors.h (G10ERR_NO_CARD, G10ERR_CANCELED): New error codes. * errors.c (g10_errstr): New error codes G10ERR_NO_CARD, G10ERR_CANCELED.
This commit is contained in:
parent
bfc45cc8bc
commit
06853bbc4d
@ -1,6 +1,10 @@
|
||||
2004-09-09 Werner Koch <wk@g10code.com>
|
||||
|
||||
* configure.ac: Check for readline.
|
||||
* README: Doc --disable-card-support and --without-readline.
|
||||
|
||||
* configure.ac: Check for readline. Make enable-card-support the
|
||||
default. New option --without-readline. Allow the use of either
|
||||
the development or the stable libusb.
|
||||
|
||||
2004-07-27 Werner Koch <wk@g10code.de>
|
||||
|
||||
|
9
NEWS
9
NEWS
@ -1,8 +1,13 @@
|
||||
Noteworthy changes in version 1.3.6 (2004-05-22)
|
||||
------------------------------------------------
|
||||
|
||||
* Readline support at all prompt if the systems provides a
|
||||
readline library.
|
||||
* Readline support at all prompts is now available if the systems
|
||||
provides a readline library. The build time option
|
||||
--without-readline may be used to disable this feature.
|
||||
|
||||
* Support for the OpenPGP smartcard is now enabled by default.
|
||||
Use the option --disable-card-support to build without support
|
||||
for smartcards.
|
||||
|
||||
* New --keyid-format option that selects short (99242560), long
|
||||
(DB698D7199242560), 0xshort (0x99242560), or 0xlong
|
||||
|
15
README
15
README
@ -476,7 +476,7 @@
|
||||
auto - Compile linux, egd and unix in and
|
||||
automagically select at runtime.
|
||||
|
||||
--with-egd-socket=<name>
|
||||
--with-egd-socket=<name>
|
||||
This is only used when EGD is used as random
|
||||
gatherer. GnuPG uses by default "~/.gnupg/entropy"
|
||||
as the socket to connect EGD. Using this option the
|
||||
@ -485,7 +485,13 @@
|
||||
"~/" uses the socket in the home directory of the user
|
||||
and one starting with a "=" uses a socket in the
|
||||
GnuPG home directory which is "~/.gnupg" by default.
|
||||
|
||||
|
||||
--without-readline
|
||||
Do not include support for the readline libary
|
||||
even if it is available. The default is to check
|
||||
whether the readline libarry is a availbale and
|
||||
use it to allow fancy command line editing.
|
||||
|
||||
--with-included-zlib
|
||||
Forces usage of the local zlib sources. Default is
|
||||
to use the (shared) library of the system.
|
||||
@ -590,6 +596,11 @@
|
||||
platforms where memory is an issue, it can be set
|
||||
as low as 5.
|
||||
|
||||
--disable-card-support
|
||||
Do not include smartcard support. The default is
|
||||
to include support if all required libraries are
|
||||
available.
|
||||
|
||||
|
||||
Installation Problems
|
||||
---------------------
|
||||
|
3
TODO
3
TODO
@ -72,9 +72,6 @@
|
||||
|
||||
* Get new assembler stuff from gmp 3.1
|
||||
|
||||
* use DEL and ^H for erasing the previous character (util/ttyio.c).
|
||||
or better readline.
|
||||
|
||||
* add test cases for invalid data (scrambled armor or other random data)
|
||||
|
||||
* add checking of armor trailers. Try to detect garbled header
|
||||
|
25
configure.ac
25
configure.ac
@ -104,10 +104,20 @@ fi
|
||||
|
||||
AC_MSG_CHECKING([whether OpenPGP card support is requested])
|
||||
AC_ARG_ENABLE(card-support,
|
||||
[ --enable-card-support enable OpenPGP card support],
|
||||
card_support=$enableval, card_support=no)
|
||||
AC_HELP_STRING([--disable-card-support],
|
||||
[enable OpenPGP card support]),
|
||||
card_support=$enableval, card_support=yes)
|
||||
AC_MSG_RESULT($card_support)
|
||||
|
||||
AC_MSG_CHECKING([whether readline support is requested])
|
||||
AC_ARG_WITH(readline,
|
||||
AC_HELP_STRING([--without-readline],
|
||||
[do not support fancy command line editing]),
|
||||
[readline_support="$withval"], [readline_support=yes])
|
||||
case "$readline_support" in yes);; no);; *)readline_support=yes;; esac
|
||||
AC_MSG_RESULT($readline_support)
|
||||
|
||||
|
||||
dnl See if we are disabling any algorithms or features for a smaller
|
||||
dnl binary
|
||||
|
||||
@ -1072,23 +1082,24 @@ AC_SUBST(ZLIBS)
|
||||
#
|
||||
# libusb allows us to use the integrated CCID smartcard reader driver.
|
||||
#
|
||||
# Note, that we need the CVS (unstable) version.
|
||||
#
|
||||
LIBUSB_LIBS=""
|
||||
if test "$card_support" = yes; then
|
||||
AC_CHECK_LIB(usb, usb_find_device,
|
||||
AC_CHECK_LIB(usb, usb_bulk_write,
|
||||
[ LIBUSB_LIBS="$LIBUSB_LIBS -lusb"
|
||||
AC_DEFINE(HAVE_LIBUSB,1,
|
||||
[defined if libusb is available])
|
||||
])
|
||||
fi
|
||||
AC_SUBST(LIBUSB_LIBS)
|
||||
AC_CHECK_FUNCS(usb_create_match)
|
||||
|
||||
#
|
||||
# Check for readline support
|
||||
#
|
||||
AC_CHECK_LIB(readline, add_history)
|
||||
AC_CHECK_HEADERS([readline/readline.h])
|
||||
if test "$readline_support" = yes ; then
|
||||
AC_CHECK_LIB(readline, add_history)
|
||||
AC_CHECK_HEADERS([readline/readline.h])
|
||||
fi
|
||||
|
||||
|
||||
# Allow users to append something to the version string without
|
||||
|
@ -1,3 +1,77 @@
|
||||
2004-09-09 Werner Koch <wk@g10code.com>
|
||||
|
||||
* cardglue.h: Add members for CA fingerprints.
|
||||
* cardglue.c (agent_release_card_info): Invalid them.
|
||||
(learn_status_cb): Store them.
|
||||
|
||||
* app-common.h, app-openpgp.c, iso7816.c, iso7816.h
|
||||
* apdu.c, apdu.h, ccid-driver.c, ccid-driver.h
|
||||
* card-util.c: Updated from current gnupg-1.9.
|
||||
|
||||
Changes are:
|
||||
|
||||
* ccid-driver.h (CCID_DRIVER_ERR_ABORTED): New.
|
||||
* ccid-driver.c (ccid_open_reader): Support the stable 0.1 version
|
||||
of libusb.
|
||||
(ccid_get_atr): Handle short messages.
|
||||
* apdu.c (my_rapdu_get_status): Implemented.
|
||||
* apdu.c: Include <signal.h>.
|
||||
* apdu.c (reader_table_s): Add function pointers for the backends.
|
||||
(apdu_close_reader, apdu_get_status, apdu_activate)
|
||||
(send_apdu): Make use of them.
|
||||
(new_reader_slot): Intialize them to NULL.
|
||||
(dump_ccid_reader_status, ct_dump_reader_status): New.
|
||||
(dump_pcsc_reader_status): New.
|
||||
(open_ct_reader, open_pcsc_reader, open_ccid_reader)
|
||||
(open_osc_reader, open_rapdu_reader): Intialize function pointers.
|
||||
(ct_activate_card, ct_send_apdu, pcsc_send_apdu, osc_send_apdu)
|
||||
(error_string): Removed. Replaced by apdu_strerror.
|
||||
(get_ccid_error_string): Removed.
|
||||
(ct_activate_card): Remove the unused loop.
|
||||
(reset_ct_reader): Implemented.
|
||||
(ct_send_apdu): Activate the card if not yet done.
|
||||
(pcsc_send_apdu): Ditto.
|
||||
* ccid-driver.h: Add error codes.
|
||||
* ccid-driver.c: Implement more or less proper error codes all
|
||||
over the place.
|
||||
* apdu.c (apdu_send_direct): New.
|
||||
(get_ccid_error_string): Add some error code mappings.
|
||||
(send_apdu): Pass error codes along for drivers already supporting
|
||||
them.
|
||||
(host_sw_string): New.
|
||||
(get_ccid_error_string): Use above.
|
||||
(send_apdu_ccid): Reset the reader if it has not yet been done.
|
||||
(open_ccid_reader): Don't care if the ATR can't be read.
|
||||
(apdu_activate_card): New.
|
||||
(apdu_strerror): New.
|
||||
(dump_reader_status): Only enable it with opt.VERBOSE.
|
||||
* iso7816.c (map_sw): Add mappings for the new error codes.
|
||||
* apdu.c (open_ct_reader, open_pcsc_reader, open_ccid_reader)
|
||||
(reset_ccid_reader, open_osc_reader): Call dump_reader_status only
|
||||
in verbose mode.
|
||||
* app-openpgp.c (do_getattr): Fix for sending CA-FPR.
|
||||
* app-openpgp.c (app_openpgp_readkey): Fixed check for valid
|
||||
exponent.
|
||||
* app-openpgp.c (do_setattr): Sync FORCE_CHV1.
|
||||
* card-util.c (change_login): Kludge to allow reading data from a
|
||||
file.
|
||||
(card_edit): Pass ARG_STRING to change_login.
|
||||
(card_status): Print CA fingerprints.
|
||||
(change_cafpr): New.
|
||||
(card_edit): New command CAFPR.
|
||||
|
||||
2004-04-30 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* g10.c (main) <gpgconf>: Use gpg.conf and not /dev/null as
|
||||
default filename.
|
||||
|
||||
2004-04-28 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* card-util.c (card_edit): Remove PIN verification.
|
||||
(generate_card_keys): New arg SERIALNO. Do PIN verification here
|
||||
after resetting forced_chv1.
|
||||
|
||||
|
||||
2004-09-09 Werner Koch <wk@g10code.com>
|
||||
|
||||
* signal.c (got_fatal_signal): Do readline cleanup. Print signal
|
||||
|
1749
g10/apdu.c
1749
g10/apdu.c
File diff suppressed because it is too large
Load Diff
28
g10/apdu.h
28
g10/apdu.h
@ -53,19 +53,39 @@ enum {
|
||||
SW_HOST_NO_DRIVER = 0x10004,
|
||||
SW_HOST_NOT_SUPPORTED = 0x10005,
|
||||
SW_HOST_LOCKING_FAILED= 0x10006,
|
||||
SW_HOST_BUSY = 0x10007
|
||||
SW_HOST_BUSY = 0x10007,
|
||||
SW_HOST_NO_CARD = 0x10008,
|
||||
SW_HOST_CARD_INACTIVE = 0x10009,
|
||||
SW_HOST_CARD_IO_ERROR = 0x1000a,
|
||||
SW_HOST_GENERAL_ERROR = 0x1000b,
|
||||
SW_HOST_NO_READER = 0x1000c,
|
||||
SW_HOST_ABORTED = 0x1000d
|
||||
};
|
||||
|
||||
|
||||
|
||||
/* Note , that apdu_open_reader returns no status word but -1 on error. */
|
||||
int apdu_open_reader (const char *portstr);
|
||||
int apdu_open_remote_reader (const char *portstr,
|
||||
const unsigned char *cookie, size_t length,
|
||||
int (*readfnc) (void *opaque,
|
||||
void *buffer, size_t size),
|
||||
void *readfnc_value,
|
||||
int (*writefnc) (void *opaque,
|
||||
const void *buffer, size_t size),
|
||||
void *writefnc_value,
|
||||
void (*closefnc) (void *opaque),
|
||||
void *closefnc_value);
|
||||
int apdu_close_reader (int slot);
|
||||
int apdu_enum_reader (int slot, int *used);
|
||||
unsigned char *apdu_get_atr (int slot, size_t *atrlen);
|
||||
|
||||
const char *apdu_strerror (int rc);
|
||||
|
||||
/* The apdu send functions do return status words. */
|
||||
|
||||
/* These apdu functions do return status words. */
|
||||
|
||||
int apdu_activate (int slot);
|
||||
int apdu_reset (int slot);
|
||||
int apdu_get_status (int slot, int hang,
|
||||
unsigned int *status, unsigned int *changed);
|
||||
@ -77,6 +97,10 @@ int apdu_send (int slot, int class, int ins, int p0, int p1,
|
||||
int apdu_send_le (int slot, int class, int ins, int p0, int p1,
|
||||
int lc, const char *data, int le,
|
||||
unsigned char **retbuf, size_t *retbuflen);
|
||||
int apdu_send_direct (int slot,
|
||||
const unsigned char *apdudata, size_t apdudatalen,
|
||||
int handle_more,
|
||||
unsigned char **retbuf, size_t *retbuflen);
|
||||
|
||||
|
||||
#endif /*APDU_H*/
|
||||
|
@ -561,7 +561,7 @@ do_getattr (APP app, CTRL ctrl, const char *name)
|
||||
{
|
||||
if (valuelen >= 60)
|
||||
for (i=0; i < 3; i++)
|
||||
send_fpr_if_not_null (ctrl, "KEY-FPR", i+1, value+i*20);
|
||||
send_fpr_if_not_null (ctrl, table[idx].name, i+1, value+i*20);
|
||||
}
|
||||
else
|
||||
send_status_info (ctrl, table[idx].name, value, valuelen, NULL, 0);
|
||||
@ -1619,7 +1619,7 @@ app_openpgp_readkey (APP app, int keyno, unsigned char **m, size_t *mlen,
|
||||
memcpy (*m, a, alen);
|
||||
|
||||
a = find_tlv (keydata, keydatalen, 0x0082, &alen);
|
||||
if (!e)
|
||||
if (!a)
|
||||
{
|
||||
log_error ("response does not contain the RSA public exponent\n");
|
||||
rc = gpg_error (GPG_ERR_CARD);
|
||||
|
123
g10/card-util.c
123
g10/card-util.c
@ -336,6 +336,11 @@ card_status (FILE *fp, char *serialno, size_t serialnobuflen)
|
||||
info.chvretry[0], info.chvretry[1], info.chvretry[2]);
|
||||
fprintf (fp, "sigcount:%lu:::\n", info.sig_counter);
|
||||
|
||||
fputs ("cafpr:", fp);
|
||||
print_sha1_fpr_colon (fp, info.cafpr1valid? info.cafpr1:NULL);
|
||||
print_sha1_fpr_colon (fp, info.cafpr2valid? info.cafpr2:NULL);
|
||||
print_sha1_fpr_colon (fp, info.cafpr3valid? info.cafpr3:NULL);
|
||||
putc ('\n', fp);
|
||||
fputs ("fpr:", fp);
|
||||
print_sha1_fpr_colon (fp, info.fpr1valid? info.fpr1:NULL);
|
||||
print_sha1_fpr_colon (fp, info.fpr2valid? info.fpr2:NULL);
|
||||
@ -362,6 +367,21 @@ card_status (FILE *fp, char *serialno, size_t serialnobuflen)
|
||||
info.disp_sex == 2? _("female") : _("unspecified"));
|
||||
print_name (fp, "URL of public key : ", info.pubkey_url);
|
||||
print_name (fp, "Login data .......: ", info.login_data);
|
||||
if (info.cafpr1valid)
|
||||
{
|
||||
tty_fprintf (fp, "CA fingerprint %d .:", 1);
|
||||
print_sha1_fpr (fp, info.cafpr1);
|
||||
}
|
||||
if (info.cafpr2valid)
|
||||
{
|
||||
tty_fprintf (fp, "CA fingerprint %d .:", 2);
|
||||
print_sha1_fpr (fp, info.cafpr2);
|
||||
}
|
||||
if (info.cafpr3valid)
|
||||
{
|
||||
tty_fprintf (fp, "CA fingerprint %d .:", 3);
|
||||
print_sha1_fpr (fp, info.cafpr3);
|
||||
}
|
||||
tty_fprintf (fp, "Signature PIN ....: %s\n",
|
||||
info.chv1_cached? _("not forced"): _("forced"));
|
||||
tty_fprintf (fp, "Max. PIN lengths .: %d %d %d\n",
|
||||
@ -491,19 +511,46 @@ change_url (void)
|
||||
}
|
||||
|
||||
static int
|
||||
change_login (void)
|
||||
change_login (const char *args)
|
||||
{
|
||||
char *data;
|
||||
int n;
|
||||
int rc;
|
||||
|
||||
data = cpr_get ("cardedit.change_login",
|
||||
_("Login data (account name): "));
|
||||
if (!data)
|
||||
return -1;
|
||||
trim_spaces (data);
|
||||
cpr_kill_prompt ();
|
||||
if (args && *args == '<') /* Read it from a file */
|
||||
{
|
||||
FILE *fp;
|
||||
|
||||
if (strlen (data) > 254 )
|
||||
for (args++; spacep (args); args++)
|
||||
;
|
||||
fp = fopen (args, "rb");
|
||||
if (!fp)
|
||||
{
|
||||
tty_printf ("can't open `%s': %s\n", args, strerror (errno));
|
||||
return -1;
|
||||
}
|
||||
data = xmalloc (254);
|
||||
n = fread (data, 1, 254, fp);
|
||||
fclose (fp);
|
||||
if (n < 0)
|
||||
{
|
||||
tty_printf ("error reading `%s': %s\n", args, strerror (errno));
|
||||
xfree (data);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
data = cpr_get ("cardedit.change_login",
|
||||
_("Login data (account name): "));
|
||||
if (!data)
|
||||
return -1;
|
||||
trim_spaces (data);
|
||||
cpr_kill_prompt ();
|
||||
n = strlen (data);
|
||||
}
|
||||
|
||||
if (n > 254 )
|
||||
{
|
||||
tty_printf (_("Error: Login data too long "
|
||||
"(limit is %d characters).\n"), 254);
|
||||
@ -511,7 +558,7 @@ change_login (void)
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc = agent_scd_setattr ("LOGIN-DATA", data, strlen (data) );
|
||||
rc = agent_scd_setattr ("LOGIN-DATA", data, n );
|
||||
if (rc)
|
||||
log_error ("error setting login data: %s\n", gpg_strerror (rc));
|
||||
xfree (data);
|
||||
@ -590,6 +637,51 @@ change_sex (void)
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
change_cafpr (int fprno)
|
||||
{
|
||||
char *data;
|
||||
const char *s;
|
||||
int i, c, rc;
|
||||
unsigned char fpr[20];
|
||||
|
||||
data = cpr_get ("cardedit.change_cafpr", _("CA fingerprint: "));
|
||||
if (!data)
|
||||
return -1;
|
||||
trim_spaces (data);
|
||||
cpr_kill_prompt ();
|
||||
|
||||
for (i=0, s=data; i < 20 && *s; )
|
||||
{
|
||||
while (spacep(s))
|
||||
s++;
|
||||
if (*s == ':')
|
||||
s++;
|
||||
while (spacep(s))
|
||||
s++;
|
||||
c = hextobyte (s);
|
||||
if (c == -1)
|
||||
break;
|
||||
fpr[i++] = c;
|
||||
s += 2;
|
||||
}
|
||||
xfree (data);
|
||||
if (i != 20 || *s)
|
||||
{
|
||||
tty_printf (_("Error: invalid formatted fingerprint.\n"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc = agent_scd_setattr (fprno==1?"CA-FPR-1":
|
||||
fprno==2?"CA-FPR-2":
|
||||
fprno==3?"CA-FPR-3":"x", fpr, 20 );
|
||||
if (rc)
|
||||
log_error ("error setting cafpr: %s\n", gpg_strerror (rc));
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void
|
||||
toggle_forcesig (void)
|
||||
{
|
||||
@ -700,7 +792,7 @@ card_edit (STRLIST commands)
|
||||
enum cmdids {
|
||||
cmdNOP = 0,
|
||||
cmdQUIT, cmdHELP, cmdLIST, cmdDEBUG,
|
||||
cmdNAME, cmdURL, cmdLOGIN, cmdLANG, cmdSEX,
|
||||
cmdNAME, cmdURL, cmdLOGIN, cmdLANG, cmdSEX, cmdCAFPR,
|
||||
cmdFORCESIG, cmdGENERATE, cmdPASSWD,
|
||||
cmdINVCMD
|
||||
};
|
||||
@ -722,6 +814,7 @@ card_edit (STRLIST commands)
|
||||
{ N_("login") , cmdLOGIN , N_("change the login name") },
|
||||
{ N_("lang") , cmdLANG , N_("change the language preferences") },
|
||||
{ N_("sex") , cmdSEX , N_("change card holder's sex") },
|
||||
{ N_("cafpr"), cmdCAFPR, N_("change a CA fingerprint") },
|
||||
{ N_("forcesig"),
|
||||
cmdFORCESIG, N_("toggle the signature force PIN flag") },
|
||||
{ N_("generate"),
|
||||
@ -840,7 +933,7 @@ card_edit (STRLIST commands)
|
||||
break;
|
||||
|
||||
case cmdLOGIN:
|
||||
change_login ();
|
||||
change_login (arg_string);
|
||||
break;
|
||||
|
||||
case cmdLANG:
|
||||
@ -851,6 +944,14 @@ card_edit (STRLIST commands)
|
||||
change_sex ();
|
||||
break;
|
||||
|
||||
case cmdCAFPR:
|
||||
if ( arg_number < 1 || arg_number > 3 )
|
||||
tty_printf ("usage: cafpr N\n"
|
||||
" 1 <= N <= 3\n");
|
||||
else
|
||||
change_cafpr (arg_number);
|
||||
break;
|
||||
|
||||
case cmdFORCESIG:
|
||||
toggle_forcesig ();
|
||||
break;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* cardglue.c - mainly dispatcher for card related functions.
|
||||
* Copyright (C) 2003 Free Software Foundation, Inc.
|
||||
* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -237,6 +237,7 @@ agent_release_card_info (struct agent_card_info_s *info)
|
||||
xfree (info->pubkey_url); info->pubkey_url = NULL;
|
||||
xfree (info->login_data); info->login_data = NULL;
|
||||
info->fpr1valid = info->fpr2valid = info->fpr3valid = 0;
|
||||
info->cafpr1valid = info->cafpr2valid = info->cafpr3valid = 0;
|
||||
}
|
||||
|
||||
|
||||
@ -529,7 +530,21 @@ learn_status_cb (void *opaque, const char *line)
|
||||
else if (no == 3)
|
||||
parm->fpr3valid = unhexify_fpr (line, parm->fpr3);
|
||||
}
|
||||
|
||||
else if (keywordlen == 6 && !memcmp (keyword, "CA-FPR", keywordlen))
|
||||
{
|
||||
int no = atoi (line);
|
||||
while (*line && !spacep (line))
|
||||
line++;
|
||||
while (spacep (line))
|
||||
line++;
|
||||
if (no == 1)
|
||||
parm->cafpr1valid = unhexify_fpr (line, parm->cafpr1);
|
||||
else if (no == 2)
|
||||
parm->cafpr2valid = unhexify_fpr (line, parm->cafpr2);
|
||||
else if (no == 3)
|
||||
parm->cafpr3valid = unhexify_fpr (line, parm->cafpr3);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* call-agent.h - Divert operations to the agent
|
||||
* Copyright (C) 2003 Free Software Foundation, Inc.
|
||||
/* cardglue.h - Divert operations to the agent
|
||||
* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -37,6 +37,12 @@ struct agent_card_info_s {
|
||||
int disp_sex; /* 0 = unspecified, 1 = male, 2 = female */
|
||||
char *pubkey_url; /* malloced. */
|
||||
char *login_data; /* malloced. */
|
||||
char cafpr1valid;
|
||||
char cafpr2valid;
|
||||
char cafpr3valid;
|
||||
char cafpr1[20];
|
||||
char cafpr2[20];
|
||||
char cafpr3[20];
|
||||
char fpr1valid;
|
||||
char fpr2valid;
|
||||
char fpr3valid;
|
||||
@ -93,10 +99,15 @@ typedef struct ctrl_ctx_s *ctrl_t;
|
||||
#define GPG_ERR_NOT_IMPLEMENTED G10ERR_GENERAL
|
||||
#define GPG_ERR_BAD_BER G10ERR_GENERAL
|
||||
#define GPG_ERR_EOF (-1)
|
||||
#define GPG_ERR_CARD_NOT_PRESENT G10ERR_NO_CARD
|
||||
#define GPG_ERR_CARD_RESET G10ERR_GENERAL
|
||||
|
||||
#define GPG_ERR_EBUSY G10ERR_GENERAL
|
||||
#define GPG_ERR_ENOENT G10ERR_OPEN_FILE
|
||||
#define GPG_ERR_EACCES G10ERR_UNSUPPORTED
|
||||
#define GPG_ERR_EIO G10ERR_GENERAL
|
||||
#define GPG_ERR_ENODEV G10ERR_GENERAL
|
||||
#define GPG_ERR_CANCELED G10ERR_CANCELED
|
||||
|
||||
typedef int gpg_error_t;
|
||||
typedef int gpg_err_code_t;
|
||||
|
@ -412,7 +412,13 @@ read_device_info (ccid_driver_t handle, struct usb_device *dev)
|
||||
{
|
||||
int cfg_no;
|
||||
|
||||
for (cfg_no=0; cfg_no < dev->descriptor->bNumConfigurations; cfg_no++)
|
||||
for (cfg_no=0; cfg_no <
|
||||
#ifdef HAVE_USB_CREATE_MATCH
|
||||
dev->descriptor->bNumConfigurations
|
||||
#else
|
||||
dev->descriptor.bNumConfigurations
|
||||
#endif
|
||||
; cfg_no++)
|
||||
{
|
||||
struct usb_config_descriptor *config = dev->config + cfg_no;
|
||||
int ifc_no;
|
||||
@ -442,17 +448,18 @@ read_device_info (ccid_driver_t handle, struct usb_device *dev)
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1; /* No suitable device found. */
|
||||
return CCID_DRIVER_ERR_NO_READER; /* No suitable device found. */
|
||||
}
|
||||
|
||||
|
||||
/* Open the reader with the internal number READERNO and return a a
|
||||
/* Open the reader with the internal number READERNO and return a
|
||||
pointer to be used as handle in HANDLE. Returns 0 on success. */
|
||||
int
|
||||
ccid_open_reader (ccid_driver_t *handle, int readerno)
|
||||
{
|
||||
#ifdef HAVE_USB_CREATE_MATCH
|
||||
/* This is the development version of libusb. */
|
||||
static int initialized;
|
||||
|
||||
int rc;
|
||||
usb_match_handle *match = NULL;
|
||||
struct usb_device *dev = NULL;
|
||||
@ -469,9 +476,9 @@ ccid_open_reader (ccid_driver_t *handle, int readerno)
|
||||
if (rc)
|
||||
{
|
||||
DEBUGOUT_1 ("usb_create_match failed: %d\n", rc);
|
||||
return -1;
|
||||
return CCID_DRIVER_ERR_NO_READER;
|
||||
}
|
||||
|
||||
|
||||
while (usb_find_device(match, dev, &dev) >= 0)
|
||||
{
|
||||
DEBUGOUT_3 ("%-40s %04X/%04X\n", dev->filename,
|
||||
@ -482,7 +489,7 @@ ccid_open_reader (ccid_driver_t *handle, int readerno)
|
||||
if (!*handle)
|
||||
{
|
||||
DEBUGOUT ("out of memory\n");
|
||||
rc = -1;
|
||||
rc = CCID_DRIVER_ERR_OUT_OF_CORE;
|
||||
free (*handle);
|
||||
*handle = NULL;
|
||||
goto leave;
|
||||
@ -503,6 +510,7 @@ ccid_open_reader (ccid_driver_t *handle, int readerno)
|
||||
DEBUGOUT_1 ("usb_open failed: %d\n", rc);
|
||||
free (*handle);
|
||||
*handle = NULL;
|
||||
rc = CCID_DRIVER_ERR_CARD_IO_ERROR;
|
||||
goto leave;
|
||||
}
|
||||
|
||||
@ -513,16 +521,9 @@ ccid_open_reader (ccid_driver_t *handle, int readerno)
|
||||
if (rc)
|
||||
{
|
||||
DEBUGOUT_1 ("usb_claim_interface failed: %d\n", rc);
|
||||
#if defined(GNUPG_MAJOR_VERSION) \
|
||||
|| (defined(GNUPG_SCD_MAIN_HEADER) && defined(HAVE_JNLIB_LOGGING))
|
||||
log_info ("CCID can't be used - "
|
||||
"please check that the device file "
|
||||
"(e.g. /proc/bus/usb) "
|
||||
"has appropriate permissions\n" );
|
||||
#endif
|
||||
|
||||
free (*handle);
|
||||
*handle = NULL;
|
||||
rc = CCID_DRIVER_ERR_CARD_IO_ERROR;
|
||||
goto leave;
|
||||
}
|
||||
|
||||
@ -536,7 +537,6 @@ ccid_open_reader (ccid_driver_t *handle, int readerno)
|
||||
readerno--;
|
||||
}
|
||||
|
||||
|
||||
leave:
|
||||
if (idev)
|
||||
usb_close (idev);
|
||||
@ -548,6 +548,96 @@ ccid_open_reader (ccid_driver_t *handle, int readerno)
|
||||
rc = -1; /* In case we didn't enter the while loop at all. */
|
||||
|
||||
return rc;
|
||||
#else /* Stable 0.1 version of libusb. */
|
||||
static int initialized;
|
||||
int rc = 0;
|
||||
struct usb_bus *busses, *bus;
|
||||
struct usb_device *dev = NULL;
|
||||
usb_dev_handle *idev = NULL;
|
||||
|
||||
*handle = NULL;
|
||||
if (!initialized)
|
||||
{
|
||||
usb_init ();
|
||||
initialized = 1;
|
||||
}
|
||||
|
||||
usb_find_busses();
|
||||
usb_find_devices();
|
||||
busses = usb_get_busses();
|
||||
|
||||
for (bus = busses; bus; bus = bus->next)
|
||||
{
|
||||
for (dev = bus->devices; dev; dev = dev->next)
|
||||
{
|
||||
DEBUGOUT_3 ("%-40s %04X/%04X\n", dev->filename,
|
||||
dev->descriptor.idVendor, dev->descriptor.idProduct);
|
||||
|
||||
if (!readerno)
|
||||
{
|
||||
*handle = calloc (1, sizeof **handle);
|
||||
if (!*handle)
|
||||
{
|
||||
DEBUGOUT ("out of memory\n");
|
||||
rc = CCID_DRIVER_ERR_OUT_OF_CORE;
|
||||
free (*handle);
|
||||
*handle = NULL;
|
||||
goto leave;
|
||||
}
|
||||
|
||||
rc = read_device_info (*handle, dev);
|
||||
if (rc)
|
||||
{
|
||||
DEBUGOUT ("device not supported\n");
|
||||
free (*handle);
|
||||
*handle = NULL;
|
||||
continue;
|
||||
}
|
||||
|
||||
idev = usb_open (dev);
|
||||
if (!idev)
|
||||
{
|
||||
DEBUGOUT_1 ("usb_open failed: %s\n", strerror (errno));
|
||||
free (*handle);
|
||||
*handle = NULL;
|
||||
rc = CCID_DRIVER_ERR_CARD_IO_ERROR;
|
||||
goto leave;
|
||||
}
|
||||
|
||||
/* fixme: Do we need to claim and set the interface as
|
||||
determined by read_device_info ()? */
|
||||
rc = usb_claim_interface (idev, 0);
|
||||
if (rc)
|
||||
{
|
||||
DEBUGOUT_1 ("usb_claim_interface failed: %d\n", rc);
|
||||
free (*handle);
|
||||
*handle = NULL;
|
||||
rc = CCID_DRIVER_ERR_CARD_IO_ERROR;
|
||||
goto leave;
|
||||
}
|
||||
|
||||
(*handle)->idev = idev;
|
||||
idev = NULL;
|
||||
/* FIXME: Do we need to get the endpoint addresses from the
|
||||
structure and store them with the handle? */
|
||||
|
||||
goto leave; /* ready. */
|
||||
}
|
||||
readerno--;
|
||||
}
|
||||
}
|
||||
|
||||
leave:
|
||||
if (idev)
|
||||
usb_close (idev);
|
||||
/* fixme: Do we need to release dev or is it supposed to be a
|
||||
shallow copy of the list created internally by usb_init ? */
|
||||
|
||||
if (!rc && !*handle)
|
||||
rc = -1; /* In case we didn't enter the while loop at all. */
|
||||
|
||||
return rc;
|
||||
#endif /* Stable version 0.1 of libusb. */
|
||||
}
|
||||
|
||||
|
||||
@ -613,7 +703,7 @@ bulk_out (ccid_driver_t handle, unsigned char *msg, size_t msglen)
|
||||
DEBUGOUT_1 ("usb_bulk_write error: %s\n", strerror (errno));
|
||||
else
|
||||
DEBUGOUT_1 ("usb_bulk_write failed: %d\n", rc);
|
||||
return -1;
|
||||
return CCID_DRIVER_ERR_CARD_IO_ERROR;
|
||||
}
|
||||
|
||||
|
||||
@ -639,7 +729,7 @@ bulk_in (ccid_driver_t handle, unsigned char *buffer, size_t length,
|
||||
if (rc < 0)
|
||||
{
|
||||
DEBUGOUT_1 ("usb_bulk_read error: %s\n", strerror (errno));
|
||||
return -1;
|
||||
return CCID_DRIVER_ERR_CARD_IO_ERROR;
|
||||
}
|
||||
|
||||
*nread = msglen = rc;
|
||||
@ -647,23 +737,23 @@ bulk_in (ccid_driver_t handle, unsigned char *buffer, size_t length,
|
||||
if (msglen < 10)
|
||||
{
|
||||
DEBUGOUT_1 ("bulk-in msg too short (%u)\n", (unsigned int)msglen);
|
||||
return -1;
|
||||
return CCID_DRIVER_ERR_INV_VALUE;
|
||||
}
|
||||
if (buffer[0] != expected_type)
|
||||
{
|
||||
DEBUGOUT_1 ("unexpected bulk-in msg type (%02x)\n", buffer[0]);
|
||||
return -1;
|
||||
return CCID_DRIVER_ERR_INV_VALUE;
|
||||
}
|
||||
if (buffer[5] != 0)
|
||||
{
|
||||
DEBUGOUT_1 ("unexpected bulk-in slot (%d)\n", buffer[5]);
|
||||
return -1;
|
||||
return CCID_DRIVER_ERR_INV_VALUE;
|
||||
}
|
||||
if (buffer[6] != seqno)
|
||||
{
|
||||
DEBUGOUT_2 ("bulk-in seqno does not match (%d/%d)\n",
|
||||
seqno, buffer[6]);
|
||||
return -1;
|
||||
return CCID_DRIVER_ERR_INV_VALUE;
|
||||
}
|
||||
|
||||
if ( !(buffer[7] & 0x03) && (buffer[7] & 0xC0) == 0x80)
|
||||
@ -680,6 +770,13 @@ bulk_in (ccid_driver_t handle, unsigned char *buffer, size_t length,
|
||||
DEBUGOUT_CONT_1 (" %02X", buffer[i]);
|
||||
DEBUGOUT_LF ();
|
||||
|
||||
switch ((buffer[7] & 0x03))
|
||||
{
|
||||
case 0: /* no error */ break;
|
||||
case 1: return CCID_DRIVER_ERR_CARD_INACTIVE;
|
||||
case 2: return CCID_DRIVER_ERR_NO_CARD;
|
||||
case 3: /* RFU */ break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -703,7 +800,7 @@ ccid_poll (ccid_driver_t handle)
|
||||
if (rc < 0)
|
||||
{
|
||||
DEBUGOUT_1 ("usb_intr_read error: %s\n", strerror (errno));
|
||||
return -1;
|
||||
return CCID_DRIVER_ERR_CARD_IO_ERROR;
|
||||
}
|
||||
|
||||
msglen = rc;
|
||||
@ -712,7 +809,7 @@ ccid_poll (ccid_driver_t handle)
|
||||
if (msglen < 1)
|
||||
{
|
||||
DEBUGOUT ("intr-in msg too short\n");
|
||||
return -1;
|
||||
return CCID_DRIVER_ERR_INV_VALUE;
|
||||
}
|
||||
|
||||
if (msg[0] == RDR_to_PC_NotifySlotChange)
|
||||
@ -739,7 +836,8 @@ ccid_poll (ccid_driver_t handle)
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Note that this fucntion won't return the error codes NO_CARD or
|
||||
CARD_INACTIVE */
|
||||
int
|
||||
ccid_slot_status (ccid_driver_t handle, int *statusbits)
|
||||
{
|
||||
@ -760,7 +858,8 @@ ccid_slot_status (ccid_driver_t handle, int *statusbits)
|
||||
if (rc)
|
||||
return rc;
|
||||
rc = bulk_in (handle, msg, sizeof msg, &msglen, RDR_to_PC_SlotStatus, seqno);
|
||||
if (rc)
|
||||
if (rc && rc != CCID_DRIVER_ERR_NO_CARD
|
||||
&& rc != CCID_DRIVER_ERR_CARD_INACTIVE)
|
||||
return rc;
|
||||
*statusbits = (msg[7] & 3);
|
||||
|
||||
@ -891,10 +990,7 @@ ccid_get_atr (ccid_driver_t handle,
|
||||
tpdulen = msglen - 10;
|
||||
|
||||
if (tpdulen < 4)
|
||||
{
|
||||
DEBUGOUT ("cannot yet handle short blocks!\n");
|
||||
return -1;
|
||||
}
|
||||
return CCID_DRIVER_ERR_ABORTED;
|
||||
|
||||
#ifdef DEBUG_T1
|
||||
fprintf (stderr, "T1: got %c-block seq=%d err=%d\n",
|
||||
@ -1026,7 +1122,7 @@ ccid_transceive (ccid_driver_t handle,
|
||||
|
||||
/* Construct an I-Block. */
|
||||
if (apdulen > 254)
|
||||
return -1; /* Invalid length. */
|
||||
return CCID_DRIVER_ERR_INV_VALUE; /* Invalid length. */
|
||||
|
||||
tpdu = msg+10;
|
||||
/* NAD: DAD=1, SAD=0 */
|
||||
@ -1089,10 +1185,9 @@ ccid_transceive (ccid_driver_t handle,
|
||||
|
||||
if (tpdulen < 4)
|
||||
{
|
||||
DEBUGOUT ("cannot yet handle short blocks!\n");
|
||||
return -1;
|
||||
usb_clear_halt (handle->idev, 0x82);
|
||||
return CCID_DRIVER_ERR_ABORTED;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_T1
|
||||
fprintf (stderr, "T1: got %c-block seq=%d err=%d\n",
|
||||
((msg[11] & 0xc0) == 0x80)? 'R' :
|
||||
@ -1140,7 +1235,7 @@ ccid_transceive (ccid_driver_t handle,
|
||||
DEBUGOUT_2 ("provided buffer too short for received data "
|
||||
"(%u/%u)\n",
|
||||
(unsigned int)n, (unsigned int)maxresplen);
|
||||
return -1;
|
||||
return CCID_DRIVER_ERR_INV_VALUE;
|
||||
}
|
||||
|
||||
memcpy (resp, p, n);
|
||||
@ -1171,7 +1266,7 @@ ccid_transceive (ccid_driver_t handle,
|
||||
if (++retries > 3)
|
||||
{
|
||||
DEBUGOUT ("3 failed retries\n");
|
||||
return -1;
|
||||
return CCID_DRIVER_ERR_CARD_IO_ERROR;
|
||||
}
|
||||
msg = send_buffer;
|
||||
tpdulen = last_tpdulen;
|
||||
@ -1179,7 +1274,7 @@ ccid_transceive (ccid_driver_t handle,
|
||||
else if (sending && !!(tpdu[1] & 0x40) == handle->t1_ns)
|
||||
{ /* Reponse does not match our sequence number. */
|
||||
DEBUGOUT ("R-block with wrong seqno received on more bit\n");
|
||||
return -1;
|
||||
return CCID_DRIVER_ERR_CARD_IO_ERROR;
|
||||
}
|
||||
else if (sending)
|
||||
{ /* Send next chunk. */
|
||||
@ -1191,7 +1286,7 @@ ccid_transceive (ccid_driver_t handle,
|
||||
else
|
||||
{
|
||||
DEBUGOUT ("unexpected ACK R-block received\n");
|
||||
return -1;
|
||||
return CCID_DRIVER_ERR_CARD_IO_ERROR;
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -1218,7 +1313,7 @@ ccid_transceive (ccid_driver_t handle,
|
||||
DEBUGOUT_1 ("T1 waittime extension of bwi=%d\n", bwi);
|
||||
}
|
||||
else
|
||||
return -1;
|
||||
return CCID_DRIVER_ERR_CARD_IO_ERROR;
|
||||
}
|
||||
} /* end T=1 protocol loop. */
|
||||
|
||||
|
@ -55,6 +55,22 @@
|
||||
#ifndef CCID_DRIVER_H
|
||||
#define CCID_DRIVER_H
|
||||
|
||||
/* The CID driver returns the same error codes as the statsu words
|
||||
used by GnuPG's apdu.h. For ease of maintenance they should always
|
||||
match. */
|
||||
#define CCID_DRIVER_ERR_OUT_OF_CORE 0x10001
|
||||
#define CCID_DRIVER_ERR_INV_VALUE 0x10002
|
||||
#define CCID_DRIVER_ERR_INCOMPLETE_CARD_RESPONSE = 0x10003
|
||||
#define CCID_DRIVER_ERR_NO_DRIVER 0x10004
|
||||
#define CCID_DRIVER_ERR_NOT_SUPPORTED 0x10005
|
||||
#define CCID_DRIVER_ERR_LOCKING_FAILED 0x10006
|
||||
#define CCID_DRIVER_ERR_BUSY 0x10007
|
||||
#define CCID_DRIVER_ERR_NO_CARD 0x10008
|
||||
#define CCID_DRIVER_ERR_CARD_INACTIVE 0x10009
|
||||
#define CCID_DRIVER_ERR_CARD_IO_ERROR 0x1000a
|
||||
#define CCID_DRIVER_ERR_GENERAL_ERROR 0x1000b
|
||||
#define CCID_DRIVER_ERR_NO_READER 0x1000c
|
||||
#define CCID_DRIVER_ERR_ABORTED 0x1000d
|
||||
|
||||
struct ccid_driver_s;
|
||||
typedef struct ccid_driver_s *ccid_driver_t;
|
||||
|
@ -85,6 +85,13 @@ map_sw (int sw)
|
||||
case SW_HOST_NOT_SUPPORTED: ec = GPG_ERR_NOT_SUPPORTED; break;
|
||||
case SW_HOST_LOCKING_FAILED: ec = GPG_ERR_BUG; break;
|
||||
case SW_HOST_BUSY: ec = GPG_ERR_EBUSY; break;
|
||||
case SW_HOST_NO_CARD: ec = GPG_ERR_CARD_NOT_PRESENT; break;
|
||||
case SW_HOST_CARD_INACTIVE: ec = GPG_ERR_CARD_RESET; break;
|
||||
case SW_HOST_CARD_IO_ERROR: ec = GPG_ERR_EIO; break;
|
||||
case SW_HOST_GENERAL_ERROR: ec = GPG_ERR_GENERAL; break;
|
||||
case SW_HOST_NO_READER: ec = GPG_ERR_ENODEV; break;
|
||||
case SW_HOST_ABORTED: ec = GPG_ERR_CANCELED; break;
|
||||
|
||||
default:
|
||||
if ((sw & 0x010000))
|
||||
ec = GPG_ERR_GENERAL; /* Should not happen. */
|
||||
|
@ -1,3 +1,7 @@
|
||||
2004-09-09 Werner Koch <wk@g10code.com>
|
||||
|
||||
* errors.h (G10ERR_NO_CARD, G10ERR_CANCELED): New error codes.
|
||||
|
||||
2004-04-27 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* mpi.h: Renamed prototype parameter name to avoid gcc warnings.
|
||||
|
@ -75,7 +75,8 @@
|
||||
#define G10ERR_UNU_PUBKEY 53
|
||||
#define G10ERR_UNU_SECKEY 54
|
||||
#define G10ERR_KEYSERVER 55
|
||||
|
||||
#define G10ERR_CANCELED 56
|
||||
#define G10ERR_NO_CARD 57
|
||||
|
||||
#ifndef HAVE_STRERROR
|
||||
char *strerror( int n );
|
||||
|
Binary file not shown.
BIN
po/en@quot.gmo
BIN
po/en@quot.gmo
Binary file not shown.
@ -1,5 +1,8 @@
|
||||
2004-09-09 Werner Koch <wk@g10code.com>
|
||||
|
||||
* errors.c (g10_errstr): New error codes G10ERR_NO_CARD,
|
||||
G10ERR_CANCELED.
|
||||
|
||||
* ttyio.c (tty_get): Add readline support.
|
||||
|
||||
* iobuf.c (iobuf_skip_rest): New. Orginal patch by Florian
|
||||
|
@ -105,6 +105,8 @@ g10_errstr( int err )
|
||||
X(UNU_PUBKEY ,N_("unusable public key"))
|
||||
X(UNU_SECKEY ,N_("unusable secret key"))
|
||||
X(KEYSERVER ,N_("keyserver error"))
|
||||
X(CANCELED ,N_("canceled"))
|
||||
X(NO_CARD ,N_("no card"))
|
||||
default: p = buf; sprintf(buf, "g10err=%d", err); break;
|
||||
}
|
||||
#undef X
|
||||
|
Loading…
x
Reference in New Issue
Block a user