1
0
mirror of git://git.gnupg.org/gnupg.git synced 2025-06-13 18:21:03 +02: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:
Werner Koch 2004-09-09 18:18:36 +00:00
parent bfc45cc8bc
commit 06853bbc4d
21 changed files with 1634 additions and 644 deletions

View File

@ -1,6 +1,10 @@
2004-09-09 Werner Koch <wk@g10code.com> 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> 2004-07-27 Werner Koch <wk@g10code.de>

9
NEWS
View File

@ -1,8 +1,13 @@
Noteworthy changes in version 1.3.6 (2004-05-22) Noteworthy changes in version 1.3.6 (2004-05-22)
------------------------------------------------ ------------------------------------------------
* Readline support at all prompt if the systems provides a * Readline support at all prompts is now available if the systems
readline library. 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 * New --keyid-format option that selects short (99242560), long
(DB698D7199242560), 0xshort (0x99242560), or 0xlong (DB698D7199242560), 0xshort (0x99242560), or 0xlong

15
README
View File

@ -476,7 +476,7 @@
auto - Compile linux, egd and unix in and auto - Compile linux, egd and unix in and
automagically select at runtime. automagically select at runtime.
--with-egd-socket=<name> --with-egd-socket=<name>
This is only used when EGD is used as random This is only used when EGD is used as random
gatherer. GnuPG uses by default "~/.gnupg/entropy" gatherer. GnuPG uses by default "~/.gnupg/entropy"
as the socket to connect EGD. Using this option the as the socket to connect EGD. Using this option the
@ -485,7 +485,13 @@
"~/" uses the socket in the home directory of the user "~/" uses the socket in the home directory of the user
and one starting with a "=" uses a socket in the and one starting with a "=" uses a socket in the
GnuPG home directory which is "~/.gnupg" by default. 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 --with-included-zlib
Forces usage of the local zlib sources. Default is Forces usage of the local zlib sources. Default is
to use the (shared) library of the system. to use the (shared) library of the system.
@ -590,6 +596,11 @@
platforms where memory is an issue, it can be set platforms where memory is an issue, it can be set
as low as 5. 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 Installation Problems
--------------------- ---------------------

3
TODO
View File

@ -72,9 +72,6 @@
* Get new assembler stuff from gmp 3.1 * 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 test cases for invalid data (scrambled armor or other random data)
* add checking of armor trailers. Try to detect garbled header * add checking of armor trailers. Try to detect garbled header

View File

@ -104,10 +104,20 @@ fi
AC_MSG_CHECKING([whether OpenPGP card support is requested]) AC_MSG_CHECKING([whether OpenPGP card support is requested])
AC_ARG_ENABLE(card-support, AC_ARG_ENABLE(card-support,
[ --enable-card-support enable OpenPGP card support], AC_HELP_STRING([--disable-card-support],
card_support=$enableval, card_support=no) [enable OpenPGP card support]),
card_support=$enableval, card_support=yes)
AC_MSG_RESULT($card_support) 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 See if we are disabling any algorithms or features for a smaller
dnl binary dnl binary
@ -1072,23 +1082,24 @@ AC_SUBST(ZLIBS)
# #
# libusb allows us to use the integrated CCID smartcard reader driver. # libusb allows us to use the integrated CCID smartcard reader driver.
# #
# Note, that we need the CVS (unstable) version.
#
LIBUSB_LIBS="" LIBUSB_LIBS=""
if test "$card_support" = yes; then 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" [ LIBUSB_LIBS="$LIBUSB_LIBS -lusb"
AC_DEFINE(HAVE_LIBUSB,1, AC_DEFINE(HAVE_LIBUSB,1,
[defined if libusb is available]) [defined if libusb is available])
]) ])
fi fi
AC_SUBST(LIBUSB_LIBS) AC_SUBST(LIBUSB_LIBS)
AC_CHECK_FUNCS(usb_create_match)
# #
# Check for readline support # Check for readline support
# #
AC_CHECK_LIB(readline, add_history) if test "$readline_support" = yes ; then
AC_CHECK_HEADERS([readline/readline.h]) AC_CHECK_LIB(readline, add_history)
AC_CHECK_HEADERS([readline/readline.h])
fi
# Allow users to append something to the version string without # Allow users to append something to the version string without

View File

@ -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> 2004-09-09 Werner Koch <wk@g10code.com>
* signal.c (got_fatal_signal): Do readline cleanup. Print signal * signal.c (got_fatal_signal): Do readline cleanup. Print signal

1749
g10/apdu.c

File diff suppressed because it is too large Load Diff

View File

@ -53,19 +53,39 @@ enum {
SW_HOST_NO_DRIVER = 0x10004, SW_HOST_NO_DRIVER = 0x10004,
SW_HOST_NOT_SUPPORTED = 0x10005, SW_HOST_NOT_SUPPORTED = 0x10005,
SW_HOST_LOCKING_FAILED= 0x10006, 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. */ /* Note , that apdu_open_reader returns no status word but -1 on error. */
int apdu_open_reader (const char *portstr); 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_close_reader (int slot);
int apdu_enum_reader (int slot, int *used); int apdu_enum_reader (int slot, int *used);
unsigned char *apdu_get_atr (int slot, size_t *atrlen); 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_reset (int slot);
int apdu_get_status (int slot, int hang, int apdu_get_status (int slot, int hang,
unsigned int *status, unsigned int *changed); 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 apdu_send_le (int slot, int class, int ins, int p0, int p1,
int lc, const char *data, int le, int lc, const char *data, int le,
unsigned char **retbuf, size_t *retbuflen); 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*/ #endif /*APDU_H*/

View File

@ -561,7 +561,7 @@ do_getattr (APP app, CTRL ctrl, const char *name)
{ {
if (valuelen >= 60) if (valuelen >= 60)
for (i=0; i < 3; i++) 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 else
send_status_info (ctrl, table[idx].name, value, valuelen, NULL, 0); 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); memcpy (*m, a, alen);
a = find_tlv (keydata, keydatalen, 0x0082, &alen); a = find_tlv (keydata, keydatalen, 0x0082, &alen);
if (!e) if (!a)
{ {
log_error ("response does not contain the RSA public exponent\n"); log_error ("response does not contain the RSA public exponent\n");
rc = gpg_error (GPG_ERR_CARD); rc = gpg_error (GPG_ERR_CARD);

View File

@ -336,6 +336,11 @@ card_status (FILE *fp, char *serialno, size_t serialnobuflen)
info.chvretry[0], info.chvretry[1], info.chvretry[2]); info.chvretry[0], info.chvretry[1], info.chvretry[2]);
fprintf (fp, "sigcount:%lu:::\n", info.sig_counter); 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); fputs ("fpr:", fp);
print_sha1_fpr_colon (fp, info.fpr1valid? info.fpr1:NULL); print_sha1_fpr_colon (fp, info.fpr1valid? info.fpr1:NULL);
print_sha1_fpr_colon (fp, info.fpr2valid? info.fpr2: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")); info.disp_sex == 2? _("female") : _("unspecified"));
print_name (fp, "URL of public key : ", info.pubkey_url); print_name (fp, "URL of public key : ", info.pubkey_url);
print_name (fp, "Login data .......: ", info.login_data); 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", tty_fprintf (fp, "Signature PIN ....: %s\n",
info.chv1_cached? _("not forced"): _("forced")); info.chv1_cached? _("not forced"): _("forced"));
tty_fprintf (fp, "Max. PIN lengths .: %d %d %d\n", tty_fprintf (fp, "Max. PIN lengths .: %d %d %d\n",
@ -491,19 +511,46 @@ change_url (void)
} }
static int static int
change_login (void) change_login (const char *args)
{ {
char *data; char *data;
int n;
int rc; int rc;
data = cpr_get ("cardedit.change_login", if (args && *args == '<') /* Read it from a file */
_("Login data (account name): ")); {
if (!data) FILE *fp;
return -1;
trim_spaces (data);
cpr_kill_prompt ();
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 " tty_printf (_("Error: Login data too long "
"(limit is %d characters).\n"), 254); "(limit is %d characters).\n"), 254);
@ -511,7 +558,7 @@ change_login (void)
return -1; return -1;
} }
rc = agent_scd_setattr ("LOGIN-DATA", data, strlen (data) ); rc = agent_scd_setattr ("LOGIN-DATA", data, n );
if (rc) if (rc)
log_error ("error setting login data: %s\n", gpg_strerror (rc)); log_error ("error setting login data: %s\n", gpg_strerror (rc));
xfree (data); 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 static void
toggle_forcesig (void) toggle_forcesig (void)
{ {
@ -700,7 +792,7 @@ card_edit (STRLIST commands)
enum cmdids { enum cmdids {
cmdNOP = 0, cmdNOP = 0,
cmdQUIT, cmdHELP, cmdLIST, cmdDEBUG, cmdQUIT, cmdHELP, cmdLIST, cmdDEBUG,
cmdNAME, cmdURL, cmdLOGIN, cmdLANG, cmdSEX, cmdNAME, cmdURL, cmdLOGIN, cmdLANG, cmdSEX, cmdCAFPR,
cmdFORCESIG, cmdGENERATE, cmdPASSWD, cmdFORCESIG, cmdGENERATE, cmdPASSWD,
cmdINVCMD cmdINVCMD
}; };
@ -722,6 +814,7 @@ card_edit (STRLIST commands)
{ N_("login") , cmdLOGIN , N_("change the login name") }, { N_("login") , cmdLOGIN , N_("change the login name") },
{ N_("lang") , cmdLANG , N_("change the language preferences") }, { N_("lang") , cmdLANG , N_("change the language preferences") },
{ N_("sex") , cmdSEX , N_("change card holder's sex") }, { N_("sex") , cmdSEX , N_("change card holder's sex") },
{ N_("cafpr"), cmdCAFPR, N_("change a CA fingerprint") },
{ N_("forcesig"), { N_("forcesig"),
cmdFORCESIG, N_("toggle the signature force PIN flag") }, cmdFORCESIG, N_("toggle the signature force PIN flag") },
{ N_("generate"), { N_("generate"),
@ -840,7 +933,7 @@ card_edit (STRLIST commands)
break; break;
case cmdLOGIN: case cmdLOGIN:
change_login (); change_login (arg_string);
break; break;
case cmdLANG: case cmdLANG:
@ -851,6 +944,14 @@ card_edit (STRLIST commands)
change_sex (); change_sex ();
break; 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: case cmdFORCESIG:
toggle_forcesig (); toggle_forcesig ();
break; break;

View File

@ -1,5 +1,5 @@
/* cardglue.c - mainly dispatcher for card related functions. /* 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. * 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->pubkey_url); info->pubkey_url = NULL;
xfree (info->login_data); info->login_data = NULL; xfree (info->login_data); info->login_data = NULL;
info->fpr1valid = info->fpr2valid = info->fpr3valid = 0; 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) else if (no == 3)
parm->fpr3valid = unhexify_fpr (line, parm->fpr3); 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; return 0;
} }

View File

@ -1,5 +1,5 @@
/* call-agent.h - Divert operations to the agent /* cardglue.h - Divert operations to the agent
* Copyright (C) 2003 Free Software Foundation, Inc. * Copyright (C) 2003, 2004 Free Software Foundation, Inc.
* *
* This file is part of GnuPG. * This file is part of GnuPG.
* *
@ -37,6 +37,12 @@ struct agent_card_info_s {
int disp_sex; /* 0 = unspecified, 1 = male, 2 = female */ int disp_sex; /* 0 = unspecified, 1 = male, 2 = female */
char *pubkey_url; /* malloced. */ char *pubkey_url; /* malloced. */
char *login_data; /* malloced. */ char *login_data; /* malloced. */
char cafpr1valid;
char cafpr2valid;
char cafpr3valid;
char cafpr1[20];
char cafpr2[20];
char cafpr3[20];
char fpr1valid; char fpr1valid;
char fpr2valid; char fpr2valid;
char fpr3valid; char fpr3valid;
@ -93,10 +99,15 @@ typedef struct ctrl_ctx_s *ctrl_t;
#define GPG_ERR_NOT_IMPLEMENTED G10ERR_GENERAL #define GPG_ERR_NOT_IMPLEMENTED G10ERR_GENERAL
#define GPG_ERR_BAD_BER G10ERR_GENERAL #define GPG_ERR_BAD_BER G10ERR_GENERAL
#define GPG_ERR_EOF (-1) #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_EBUSY G10ERR_GENERAL
#define GPG_ERR_ENOENT G10ERR_OPEN_FILE #define GPG_ERR_ENOENT G10ERR_OPEN_FILE
#define GPG_ERR_EACCES G10ERR_UNSUPPORTED #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_error_t;
typedef int gpg_err_code_t; typedef int gpg_err_code_t;

View File

@ -412,7 +412,13 @@ read_device_info (ccid_driver_t handle, struct usb_device *dev)
{ {
int cfg_no; 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; struct usb_config_descriptor *config = dev->config + cfg_no;
int ifc_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. */ pointer to be used as handle in HANDLE. Returns 0 on success. */
int int
ccid_open_reader (ccid_driver_t *handle, int readerno) ccid_open_reader (ccid_driver_t *handle, int readerno)
{ {
#ifdef HAVE_USB_CREATE_MATCH
/* This is the development version of libusb. */
static int initialized; static int initialized;
int rc; int rc;
usb_match_handle *match = NULL; usb_match_handle *match = NULL;
struct usb_device *dev = NULL; struct usb_device *dev = NULL;
@ -469,9 +476,9 @@ ccid_open_reader (ccid_driver_t *handle, int readerno)
if (rc) if (rc)
{ {
DEBUGOUT_1 ("usb_create_match failed: %d\n", 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) while (usb_find_device(match, dev, &dev) >= 0)
{ {
DEBUGOUT_3 ("%-40s %04X/%04X\n", dev->filename, DEBUGOUT_3 ("%-40s %04X/%04X\n", dev->filename,
@ -482,7 +489,7 @@ ccid_open_reader (ccid_driver_t *handle, int readerno)
if (!*handle) if (!*handle)
{ {
DEBUGOUT ("out of memory\n"); DEBUGOUT ("out of memory\n");
rc = -1; rc = CCID_DRIVER_ERR_OUT_OF_CORE;
free (*handle); free (*handle);
*handle = NULL; *handle = NULL;
goto leave; goto leave;
@ -503,6 +510,7 @@ ccid_open_reader (ccid_driver_t *handle, int readerno)
DEBUGOUT_1 ("usb_open failed: %d\n", rc); DEBUGOUT_1 ("usb_open failed: %d\n", rc);
free (*handle); free (*handle);
*handle = NULL; *handle = NULL;
rc = CCID_DRIVER_ERR_CARD_IO_ERROR;
goto leave; goto leave;
} }
@ -513,16 +521,9 @@ ccid_open_reader (ccid_driver_t *handle, int readerno)
if (rc) if (rc)
{ {
DEBUGOUT_1 ("usb_claim_interface failed: %d\n", 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); free (*handle);
*handle = NULL; *handle = NULL;
rc = CCID_DRIVER_ERR_CARD_IO_ERROR;
goto leave; goto leave;
} }
@ -536,7 +537,6 @@ ccid_open_reader (ccid_driver_t *handle, int readerno)
readerno--; readerno--;
} }
leave: leave:
if (idev) if (idev)
usb_close (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. */ rc = -1; /* In case we didn't enter the while loop at all. */
return rc; 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)); DEBUGOUT_1 ("usb_bulk_write error: %s\n", strerror (errno));
else else
DEBUGOUT_1 ("usb_bulk_write failed: %d\n", rc); 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) if (rc < 0)
{ {
DEBUGOUT_1 ("usb_bulk_read error: %s\n", strerror (errno)); DEBUGOUT_1 ("usb_bulk_read error: %s\n", strerror (errno));
return -1; return CCID_DRIVER_ERR_CARD_IO_ERROR;
} }
*nread = msglen = rc; *nread = msglen = rc;
@ -647,23 +737,23 @@ bulk_in (ccid_driver_t handle, unsigned char *buffer, size_t length,
if (msglen < 10) if (msglen < 10)
{ {
DEBUGOUT_1 ("bulk-in msg too short (%u)\n", (unsigned int)msglen); 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) if (buffer[0] != expected_type)
{ {
DEBUGOUT_1 ("unexpected bulk-in msg type (%02x)\n", buffer[0]); DEBUGOUT_1 ("unexpected bulk-in msg type (%02x)\n", buffer[0]);
return -1; return CCID_DRIVER_ERR_INV_VALUE;
} }
if (buffer[5] != 0) if (buffer[5] != 0)
{ {
DEBUGOUT_1 ("unexpected bulk-in slot (%d)\n", buffer[5]); DEBUGOUT_1 ("unexpected bulk-in slot (%d)\n", buffer[5]);
return -1; return CCID_DRIVER_ERR_INV_VALUE;
} }
if (buffer[6] != seqno) if (buffer[6] != seqno)
{ {
DEBUGOUT_2 ("bulk-in seqno does not match (%d/%d)\n", DEBUGOUT_2 ("bulk-in seqno does not match (%d/%d)\n",
seqno, buffer[6]); seqno, buffer[6]);
return -1; return CCID_DRIVER_ERR_INV_VALUE;
} }
if ( !(buffer[7] & 0x03) && (buffer[7] & 0xC0) == 0x80) 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_CONT_1 (" %02X", buffer[i]);
DEBUGOUT_LF (); 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; return 0;
} }
@ -703,7 +800,7 @@ ccid_poll (ccid_driver_t handle)
if (rc < 0) if (rc < 0)
{ {
DEBUGOUT_1 ("usb_intr_read error: %s\n", strerror (errno)); DEBUGOUT_1 ("usb_intr_read error: %s\n", strerror (errno));
return -1; return CCID_DRIVER_ERR_CARD_IO_ERROR;
} }
msglen = rc; msglen = rc;
@ -712,7 +809,7 @@ ccid_poll (ccid_driver_t handle)
if (msglen < 1) if (msglen < 1)
{ {
DEBUGOUT ("intr-in msg too short\n"); DEBUGOUT ("intr-in msg too short\n");
return -1; return CCID_DRIVER_ERR_INV_VALUE;
} }
if (msg[0] == RDR_to_PC_NotifySlotChange) 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 int
ccid_slot_status (ccid_driver_t handle, int *statusbits) ccid_slot_status (ccid_driver_t handle, int *statusbits)
{ {
@ -760,7 +858,8 @@ ccid_slot_status (ccid_driver_t handle, int *statusbits)
if (rc) if (rc)
return rc; return rc;
rc = bulk_in (handle, msg, sizeof msg, &msglen, RDR_to_PC_SlotStatus, seqno); 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; return rc;
*statusbits = (msg[7] & 3); *statusbits = (msg[7] & 3);
@ -891,10 +990,7 @@ ccid_get_atr (ccid_driver_t handle,
tpdulen = msglen - 10; tpdulen = msglen - 10;
if (tpdulen < 4) if (tpdulen < 4)
{ return CCID_DRIVER_ERR_ABORTED;
DEBUGOUT ("cannot yet handle short blocks!\n");
return -1;
}
#ifdef DEBUG_T1 #ifdef DEBUG_T1
fprintf (stderr, "T1: got %c-block seq=%d err=%d\n", 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. */ /* Construct an I-Block. */
if (apdulen > 254) if (apdulen > 254)
return -1; /* Invalid length. */ return CCID_DRIVER_ERR_INV_VALUE; /* Invalid length. */
tpdu = msg+10; tpdu = msg+10;
/* NAD: DAD=1, SAD=0 */ /* NAD: DAD=1, SAD=0 */
@ -1089,10 +1185,9 @@ ccid_transceive (ccid_driver_t handle,
if (tpdulen < 4) if (tpdulen < 4)
{ {
DEBUGOUT ("cannot yet handle short blocks!\n"); usb_clear_halt (handle->idev, 0x82);
return -1; return CCID_DRIVER_ERR_ABORTED;
} }
#ifdef DEBUG_T1 #ifdef DEBUG_T1
fprintf (stderr, "T1: got %c-block seq=%d err=%d\n", fprintf (stderr, "T1: got %c-block seq=%d err=%d\n",
((msg[11] & 0xc0) == 0x80)? 'R' : ((msg[11] & 0xc0) == 0x80)? 'R' :
@ -1140,7 +1235,7 @@ ccid_transceive (ccid_driver_t handle,
DEBUGOUT_2 ("provided buffer too short for received data " DEBUGOUT_2 ("provided buffer too short for received data "
"(%u/%u)\n", "(%u/%u)\n",
(unsigned int)n, (unsigned int)maxresplen); (unsigned int)n, (unsigned int)maxresplen);
return -1; return CCID_DRIVER_ERR_INV_VALUE;
} }
memcpy (resp, p, n); memcpy (resp, p, n);
@ -1171,7 +1266,7 @@ ccid_transceive (ccid_driver_t handle,
if (++retries > 3) if (++retries > 3)
{ {
DEBUGOUT ("3 failed retries\n"); DEBUGOUT ("3 failed retries\n");
return -1; return CCID_DRIVER_ERR_CARD_IO_ERROR;
} }
msg = send_buffer; msg = send_buffer;
tpdulen = last_tpdulen; tpdulen = last_tpdulen;
@ -1179,7 +1274,7 @@ ccid_transceive (ccid_driver_t handle,
else if (sending && !!(tpdu[1] & 0x40) == handle->t1_ns) else if (sending && !!(tpdu[1] & 0x40) == handle->t1_ns)
{ /* Reponse does not match our sequence number. */ { /* Reponse does not match our sequence number. */
DEBUGOUT ("R-block with wrong seqno received on more bit\n"); DEBUGOUT ("R-block with wrong seqno received on more bit\n");
return -1; return CCID_DRIVER_ERR_CARD_IO_ERROR;
} }
else if (sending) else if (sending)
{ /* Send next chunk. */ { /* Send next chunk. */
@ -1191,7 +1286,7 @@ ccid_transceive (ccid_driver_t handle,
else else
{ {
DEBUGOUT ("unexpected ACK R-block received\n"); DEBUGOUT ("unexpected ACK R-block received\n");
return -1; return CCID_DRIVER_ERR_CARD_IO_ERROR;
} }
} }
else else
@ -1218,7 +1313,7 @@ ccid_transceive (ccid_driver_t handle,
DEBUGOUT_1 ("T1 waittime extension of bwi=%d\n", bwi); DEBUGOUT_1 ("T1 waittime extension of bwi=%d\n", bwi);
} }
else else
return -1; return CCID_DRIVER_ERR_CARD_IO_ERROR;
} }
} /* end T=1 protocol loop. */ } /* end T=1 protocol loop. */

View File

@ -55,6 +55,22 @@
#ifndef CCID_DRIVER_H #ifndef CCID_DRIVER_H
#define 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; struct ccid_driver_s;
typedef struct ccid_driver_s *ccid_driver_t; typedef struct ccid_driver_s *ccid_driver_t;

View File

@ -85,6 +85,13 @@ map_sw (int sw)
case SW_HOST_NOT_SUPPORTED: ec = GPG_ERR_NOT_SUPPORTED; break; case SW_HOST_NOT_SUPPORTED: ec = GPG_ERR_NOT_SUPPORTED; break;
case SW_HOST_LOCKING_FAILED: ec = GPG_ERR_BUG; break; case SW_HOST_LOCKING_FAILED: ec = GPG_ERR_BUG; break;
case SW_HOST_BUSY: ec = GPG_ERR_EBUSY; 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: default:
if ((sw & 0x010000)) if ((sw & 0x010000))
ec = GPG_ERR_GENERAL; /* Should not happen. */ ec = GPG_ERR_GENERAL; /* Should not happen. */

View File

@ -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> 2004-04-27 Werner Koch <wk@gnupg.org>
* mpi.h: Renamed prototype parameter name to avoid gcc warnings. * mpi.h: Renamed prototype parameter name to avoid gcc warnings.

View File

@ -75,7 +75,8 @@
#define G10ERR_UNU_PUBKEY 53 #define G10ERR_UNU_PUBKEY 53
#define G10ERR_UNU_SECKEY 54 #define G10ERR_UNU_SECKEY 54
#define G10ERR_KEYSERVER 55 #define G10ERR_KEYSERVER 55
#define G10ERR_CANCELED 56
#define G10ERR_NO_CARD 57
#ifndef HAVE_STRERROR #ifndef HAVE_STRERROR
char *strerror( int n ); char *strerror( int n );

Binary file not shown.

Binary file not shown.

View File

@ -1,5 +1,8 @@
2004-09-09 Werner Koch <wk@g10code.com> 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. * ttyio.c (tty_get): Add readline support.
* iobuf.c (iobuf_skip_rest): New. Orginal patch by Florian * iobuf.c (iobuf_skip_rest): New. Orginal patch by Florian

View File

@ -105,6 +105,8 @@ g10_errstr( int err )
X(UNU_PUBKEY ,N_("unusable public key")) X(UNU_PUBKEY ,N_("unusable public key"))
X(UNU_SECKEY ,N_("unusable secret key")) X(UNU_SECKEY ,N_("unusable secret key"))
X(KEYSERVER ,N_("keyserver error")) X(KEYSERVER ,N_("keyserver error"))
X(CANCELED ,N_("canceled"))
X(NO_CARD ,N_("no card"))
default: p = buf; sprintf(buf, "g10err=%d", err); break; default: p = buf; sprintf(buf, "g10err=%d", err); break;
} }
#undef X #undef X