mirror of
git://git.gnupg.org/gnupg.git
synced 2025-02-01 16:33:02 +01:00
* configure.ac: Changed tests for libusb to also suuport the
stable version 0.1.x. * scdaemon.texi (Card applications): New section. * scdaemon.c (main): New option --disable-application. * app.c (is_app_allowed): New. (select_application): Use it to check for disabled applications. * 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.
This commit is contained in:
parent
587222f48d
commit
818e9bad58
@ -1,3 +1,8 @@
|
||||
2004-08-05 Werner Koch <wk@g10code.de>
|
||||
|
||||
* configure.ac: Changed tests for libusb to also suuport the
|
||||
stable version 0.1.x.
|
||||
|
||||
2004-07-22 Werner Koch <wk@g10code.de>
|
||||
|
||||
Released 1.9.10.
|
||||
|
22
TODO
22
TODO
@ -79,3 +79,25 @@ might want to have an agent context for each service request
|
||||
* doc/
|
||||
** Explain how to setup a root CA key as trusted
|
||||
** Explain how trustlist.txt might be managed.
|
||||
|
||||
|
||||
* Requirements by the BSI
|
||||
** Support authorityKeyIdentifier.keyIdentifier
|
||||
This needs support in libksba/src/cert.c as well as in sm/*.c.
|
||||
Need test certs as well. Same goes for CRL authorityKeyIdentifier.
|
||||
|
||||
** For pkcs#10 request header.
|
||||
We use "NEW CERTIFICATE REQUEST" the specs say "CERTIFICATE
|
||||
REQUEST" should be used. However it seems that their CA software
|
||||
is also able to use our header. Binary pkcs#10 request are not
|
||||
allowed.
|
||||
|
||||
** Dirmngr: name subordination (nameRelativeToCRLIssuer)
|
||||
is not yet supported by Dirmngr.
|
||||
|
||||
** Dirmngr: CRL DP URI
|
||||
The CRL DP shall use an URI for LDAP without a host name. The host
|
||||
name shall be looked by using the DN in the URI. We don't implement
|
||||
this yet. Solution is to have a mapping DN->host in our ldapservers
|
||||
configuration file.
|
||||
|
||||
|
@ -451,15 +451,13 @@ AM_PATH_KSBA("$NEED_KSBA_VERSION",have_ksba=yes,have_ksba=no)
|
||||
#
|
||||
# libusb allows us to use the integrated CCID smartcard reader driver.
|
||||
#
|
||||
# Note, that we need the CVS version. FIXME: libusb should have a
|
||||
# regular check as the other libraries do.
|
||||
#
|
||||
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])
|
||||
])
|
||||
AC_SUBST(LIBUSB_LIBS)
|
||||
AC_CHECK_FUNCS(usb_create_match)
|
||||
|
||||
#
|
||||
# Check wether it is necessary to link against libdl.
|
||||
|
@ -1,3 +1,7 @@
|
||||
2004-08-05 Werner Koch <wk@g10code.de>
|
||||
|
||||
* scdaemon.texi (Card applications): New section.
|
||||
|
||||
2004-06-22 Werner Koch <wk@g10code.com>
|
||||
|
||||
* glossary.texi: New.
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
@c man begin DESCRIPTION
|
||||
|
||||
The @sc{scdaeon} is a daemon to manage smartcards. It is usually
|
||||
The @sc{scdaemon} is a daemon to manage smartcards. It is usually
|
||||
invoked by gpg-agent and in general not used directly.
|
||||
|
||||
@c man end
|
||||
@ -20,6 +20,7 @@ invoked by gpg-agent and in general not used directly.
|
||||
@menu
|
||||
* Scdaemon Commands:: List of all commands.
|
||||
* Scdaemon Options:: List of all options.
|
||||
* Card applications:: Description of card applications.
|
||||
* Scdaemon Examples:: Some usage examples.
|
||||
* Scdaemon Protocol:: The protocol the daemon uses.
|
||||
@end menu
|
||||
@ -176,18 +177,70 @@ is @code{libtowitoko.so}.
|
||||
@itemx --deny-admin
|
||||
@opindex allow-admin
|
||||
@opindex deny-admin
|
||||
This enables the use of Admin class commands for card application
|
||||
This enables the use of Admin class commands for card applications
|
||||
where this is supported. Currently we support it for the OpenPGP
|
||||
card. Deny is the default. This commands is useful to inhibit
|
||||
accidental access to admin class command which could ultimately lock
|
||||
the card through worng PIN numbers.
|
||||
|
||||
@item --disable-application @var{name}
|
||||
@opindex disable-application
|
||||
This option disables the use of the card application named
|
||||
@var{name}. This is mainly useful for debugging or if a application
|
||||
with lower priority should be used by default.
|
||||
|
||||
@end table
|
||||
|
||||
All the long options may also be given in the configuration file after
|
||||
stripping off the two leading dashes.
|
||||
|
||||
|
||||
@c man begin CARD APPLICATIONS
|
||||
|
||||
@node Card applications
|
||||
@section Description of card applications
|
||||
|
||||
@sc{scdaemon} supports the card applications as described below.
|
||||
|
||||
@menu
|
||||
* OpenPGP Card:: The OpenPGP card application
|
||||
* NKS Card:: The Telesec NetKey card application
|
||||
* DINSIG Card:: The DINSIG card application
|
||||
* PKCS#15 Card:: The PKCS#15 card application
|
||||
@end menu
|
||||
|
||||
@node OpenPGP Card
|
||||
@subsection The OpenPGP card application ``openpgp''
|
||||
|
||||
This application is currently only used by @sc{gpg} but may in
|
||||
future also be useful with @sc{gpgsm}.
|
||||
|
||||
The specification for such a card is available at
|
||||
@uref{http://g10code.com/docs/openpgp-card-1.0.pdf}.
|
||||
|
||||
@node NKS Card
|
||||
@subsection The Telesec NetKey card ``nks''
|
||||
|
||||
This is the main application of the Telesec cards as available in
|
||||
Germany. It is a superset of the German DINSIG card. The card is
|
||||
used by @sc{gpgsm}.
|
||||
|
||||
@node DINSIG Card
|
||||
@subsection The DINSIG card application ``dinsig''
|
||||
|
||||
This is an application as described in the German draft standard
|
||||
@emph{DIN V 66291-1}. It is intended to be used by cards supporteing
|
||||
the German signature law and its bylaws (SigG and SigV).
|
||||
|
||||
@node PKCS#15 Card
|
||||
@subsection The PKCS#15 card application ``p15''
|
||||
|
||||
This is common fraqmework for smart card applications; support is only
|
||||
available if compiled with support for the OpenSC library. It is used
|
||||
by @sc{gpgsm}.
|
||||
|
||||
|
||||
|
||||
@c
|
||||
@c Examples
|
||||
@c
|
||||
|
@ -1,3 +1,16 @@
|
||||
2004-08-05 Werner Koch <wk@g10code.de>
|
||||
|
||||
* scdaemon.c (main): New option --disable-application.
|
||||
* app.c (is_app_allowed): New.
|
||||
(select_application): Use it to check for disabled applications.
|
||||
|
||||
* 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.
|
||||
|
||||
2004-07-27 Moritz Schulte <moritz@g10code.com>
|
||||
|
||||
* apdu.c: Include <signal.h>.
|
||||
|
39
scd/apdu.c
39
scd/apdu.c
@ -19,7 +19,6 @@
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@ -296,6 +295,7 @@ host_sw_string (long err)
|
||||
case SW_HOST_CARD_IO_ERROR: return "card I/O error";
|
||||
case SW_HOST_GENERAL_ERROR: return "general error";
|
||||
case SW_HOST_NO_READER: return "no reader";
|
||||
case SW_HOST_ABORTED: return "aborted";
|
||||
default: return "unknown host status error";
|
||||
}
|
||||
}
|
||||
@ -1633,7 +1633,42 @@ reset_rapdu_reader (int slot)
|
||||
static int
|
||||
my_rapdu_get_status (int slot, unsigned int *status)
|
||||
{
|
||||
return SW_HOST_NOT_SUPPORTED;
|
||||
int err;
|
||||
reader_table_t slotp;
|
||||
rapdu_msg_t msg = NULL;
|
||||
int oldslot;
|
||||
|
||||
slotp = reader_table + slot;
|
||||
|
||||
oldslot = rapdu_set_reader (slotp->rapdu.handle, slot);
|
||||
err = rapdu_send_cmd (slotp->rapdu.handle, RAPDU_CMD_GET_STATUS);
|
||||
rapdu_set_reader (slotp->rapdu.handle, oldslot);
|
||||
if (err)
|
||||
{
|
||||
log_error ("sending rapdu command GET_STATUS failed: %s\n",
|
||||
err < 0 ? strerror (errno): rapdu_strerror (err));
|
||||
return rapdu_status_to_sw (err);
|
||||
}
|
||||
err = rapdu_read_msg (slotp->rapdu.handle, &msg);
|
||||
if (err)
|
||||
{
|
||||
log_error ("receiving rapdu message failed: %s\n",
|
||||
err < 0 ? strerror (errno): rapdu_strerror (err));
|
||||
rapdu_msg_release (msg);
|
||||
return rapdu_status_to_sw (err);
|
||||
}
|
||||
if (msg->cmd != RAPDU_STATUS_SUCCESS || !msg->datalen)
|
||||
{
|
||||
int sw = rapdu_status_to_sw (msg->cmd);
|
||||
log_error ("rapdu command GET_STATUS failed: %s\n",
|
||||
rapdu_strerror (msg->cmd));
|
||||
rapdu_msg_release (msg);
|
||||
return sw;
|
||||
}
|
||||
*status = msg->data[0];
|
||||
|
||||
rapdu_msg_release (msg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -58,7 +58,8 @@ enum {
|
||||
SW_HOST_CARD_INACTIVE = 0x10009,
|
||||
SW_HOST_CARD_IO_ERROR = 0x1000a,
|
||||
SW_HOST_GENERAL_ERROR = 0x1000b,
|
||||
SW_HOST_NO_READER = 0x1000c
|
||||
SW_HOST_NO_READER = 0x1000c,
|
||||
SW_HOST_ABORTED = 0x1000d
|
||||
};
|
||||
|
||||
|
||||
|
19
scd/app.c
19
scd/app.c
@ -32,6 +32,19 @@
|
||||
#include "tlv.h"
|
||||
|
||||
|
||||
/* Check wether the application NAME is allowed. This does not mean
|
||||
we have support for it though. */
|
||||
static int
|
||||
is_app_allowed (const char *name)
|
||||
{
|
||||
strlist_t l;
|
||||
|
||||
for (l=opt.disabled_applications; l; l = l->next)
|
||||
if (!strcmp (l->d, name))
|
||||
return 0; /* no */
|
||||
return 1; /* yes */
|
||||
}
|
||||
|
||||
/* If called with NAME as NULL, select the best fitting application
|
||||
and return a context; otherwise select the application with NAME
|
||||
and return a context. SLOT identifies the reader device. Returns
|
||||
@ -84,11 +97,11 @@ select_application (ctrl_t ctrl, int slot, const char *name)
|
||||
|
||||
rc = gpg_error (GPG_ERR_NOT_FOUND);
|
||||
|
||||
if (!name || !strcmp (name, "openpgp"))
|
||||
if (rc && is_app_allowed ("openpgp") && (!name || !strcmp (name, "openpgp")))
|
||||
rc = app_select_openpgp (app);
|
||||
if (rc && (!name || !strcmp (name, "nks")))
|
||||
if (rc && is_app_allowed ("nks") && (!name || !strcmp (name, "nks")))
|
||||
rc = app_select_nks (app);
|
||||
if (rc && (!name || !strcmp (name, "dinsig")))
|
||||
if (rc && is_app_allowed ("dinsig") && (!name || !strcmp (name, "dinsig")))
|
||||
rc = app_select_dinsig (app);
|
||||
if (rc && name)
|
||||
rc = gpg_error (GPG_ERR_NOT_SUPPORTED);
|
||||
|
@ -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;
|
||||
@ -451,8 +457,9 @@ read_device_info (ccid_driver_t handle, struct usb_device *dev)
|
||||
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;
|
||||
@ -471,7 +478,7 @@ ccid_open_reader (ccid_driver_t *handle, int readerno)
|
||||
DEBUGOUT_1 ("usb_create_match failed: %d\n", rc);
|
||||
return CCID_DRIVER_ERR_NO_READER;
|
||||
}
|
||||
|
||||
|
||||
while (usb_find_device(match, dev, &dev) >= 0)
|
||||
{
|
||||
DEBUGOUT_3 ("%-40s %04X/%04X\n", dev->filename,
|
||||
@ -530,7 +537,6 @@ ccid_open_reader (ccid_driver_t *handle, int readerno)
|
||||
readerno--;
|
||||
}
|
||||
|
||||
|
||||
leave:
|
||||
if (idev)
|
||||
usb_close (idev);
|
||||
@ -542,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. */
|
||||
}
|
||||
|
||||
|
||||
@ -894,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",
|
||||
@ -1092,10 +1185,9 @@ ccid_transceive (ccid_driver_t handle,
|
||||
|
||||
if (tpdulen < 4)
|
||||
{
|
||||
DEBUGOUT ("cannot yet handle short blocks!\n");
|
||||
return CCID_DRIVER_ERR_NOT_SUPPORTED;
|
||||
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' :
|
||||
|
@ -70,7 +70,7 @@
|
||||
#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;
|
||||
|
@ -90,6 +90,7 @@ map_sw (int sw)
|
||||
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))
|
||||
|
@ -80,6 +80,7 @@ enum cmd_and_opt_values
|
||||
oDisableOpenSC,
|
||||
oAllowAdmin,
|
||||
oDenyAdmin,
|
||||
oDisableApplication,
|
||||
|
||||
aTest };
|
||||
|
||||
@ -124,6 +125,7 @@ static ARGPARSE_OPTS opts[] = {
|
||||
/* end --disable-opensc */},
|
||||
{ oAllowAdmin, "allow-admin", 0, N_("allow the use of admin card commands")},
|
||||
{ oDenyAdmin, "deny-admin", 0, "@" },
|
||||
{ oDisableApplication, "disable-application", 2, "@"},
|
||||
|
||||
{0}
|
||||
};
|
||||
@ -493,6 +495,10 @@ main (int argc, char **argv )
|
||||
case oAllowAdmin: opt.allow_admin = 1; break;
|
||||
case oDenyAdmin: opt.allow_admin = 0; break;
|
||||
|
||||
case oDisableApplication:
|
||||
add_to_strlist (&opt.disabled_applications, pargs.r.ret_str);
|
||||
break;
|
||||
|
||||
default : pargs.err = configfp? 1:2; break;
|
||||
}
|
||||
}
|
||||
|
@ -52,6 +52,8 @@ struct {
|
||||
int disable_ccid; /* Disable the use of the internal CCID driver. */
|
||||
int allow_admin; /* Allow the use of admin commands for certain
|
||||
cards. */
|
||||
strlist_t disabled_applications; /* card applications we do not
|
||||
want to use. */
|
||||
} opt;
|
||||
|
||||
|
||||
|
@ -1,3 +1,8 @@
|
||||
2004-07-23 Werner Koch <wk@g10code.de>
|
||||
|
||||
* certreqgen.c (proc_parameters): Do not allow key length below
|
||||
1024.
|
||||
|
||||
2004-07-22 Werner Koch <wk@g10code.de>
|
||||
|
||||
* keylist.c (list_cert_raw): Print the keygrip.
|
||||
|
@ -444,7 +444,7 @@ proc_parameters (ctrl_t ctrl,
|
||||
if (i < 1 || i != GCRY_PK_RSA )
|
||||
{
|
||||
r = get_parameter (para, pKEYTYPE);
|
||||
log_error ("line %d: invalid algorithm\n", r->lnr);
|
||||
log_error (_("line %d: invalid algorithm\n"), r->lnr);
|
||||
return gpg_error (GPG_ERR_INV_PARAMETER);
|
||||
}
|
||||
|
||||
@ -453,11 +453,12 @@ proc_parameters (ctrl_t ctrl,
|
||||
nbits = 1024;
|
||||
else
|
||||
nbits = get_parameter_uint (para, pKEYLENGTH);
|
||||
if (nbits < 512 || nbits > 4096)
|
||||
if (nbits < 1024 || nbits > 4096)
|
||||
{
|
||||
/* The BSI specs dated 2002-11-25 don't allow lengths below 1024. */
|
||||
r = get_parameter (para, pKEYTYPE);
|
||||
log_error ("line %d: invalid key length %u (valid are 512 to 4096)\n",
|
||||
r->lnr, nbits);
|
||||
log_error (_("line %d: invalid key length %u (valid are %d to %d)\n"),
|
||||
r->lnr, nbits, 1024, 4096);
|
||||
return gpg_error (GPG_ERR_INV_PARAMETER);
|
||||
}
|
||||
|
||||
@ -470,7 +471,7 @@ proc_parameters (ctrl_t ctrl,
|
||||
if (!(s=get_parameter_value (para, pNAMEDN)))
|
||||
{
|
||||
r = get_parameter (para, pKEYTYPE);
|
||||
log_error ("line %d: no subject name given\n", r->lnr);
|
||||
log_error (_("line %d: no subject name given\n"), r->lnr);
|
||||
return gpg_error (GPG_ERR_INV_PARAMETER);
|
||||
}
|
||||
/* fixme check s */
|
||||
@ -485,7 +486,7 @@ proc_parameters (ctrl_t ctrl,
|
||||
|| strstr(s, ".."))
|
||||
{
|
||||
r = get_parameter (para, pKEYTYPE);
|
||||
log_error ("line %d: not a valid email address\n", r->lnr);
|
||||
log_error (_("line %d: not a valid email address\n"), r->lnr);
|
||||
return gpg_error (GPG_ERR_INV_PARAMETER);
|
||||
}
|
||||
}
|
||||
@ -497,7 +498,7 @@ proc_parameters (ctrl_t ctrl,
|
||||
if (rc)
|
||||
{
|
||||
r = get_parameter (para, pKEYTYPE);
|
||||
log_error ("line %d: key generation failed: %s\n",
|
||||
log_error (_("line %d: key generation failed: %s\n"),
|
||||
r->lnr, gpg_strerror (rc));
|
||||
return rc;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user