mirror of
git://git.gnupg.org/gnupg.git
synced 2025-02-01 16:33:02 +01:00
* scdaemon.c: New option --debug-sc N.
* card.c (card_open): set it here. * card-p15.c (p15_prepare_key): Factored out common code from ... (p15_sign, p15_decipher): here and made the decryption work the regular way.
This commit is contained in:
parent
7e07a397a0
commit
7db161552c
@ -1,3 +1,12 @@
|
||||
2002-04-12 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* scdaemon.c: New option --debug-sc N.
|
||||
* card.c (card_open): set it here.
|
||||
|
||||
* card-p15.c (p15_prepare_key): Factored out common code from ...
|
||||
(p15_sign, p15_decipher): here and made the decryption work the
|
||||
regular way.
|
||||
|
||||
2002-04-10 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* card.c (card_open): Return immediately when no reader is available.
|
||||
|
139
scd/card-p15.c
139
scd/card-p15.c
@ -32,9 +32,6 @@
|
||||
#include "card-common.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* See card.c for interface description */
|
||||
static int
|
||||
p15_enum_keypairs (CARD card, int idx,
|
||||
@ -198,26 +195,19 @@ p15_read_cert (CARD card, const char *certidstr,
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* See card.c for interface description */
|
||||
static int
|
||||
p15_sign (CARD card, const char *keyidstr, int hashalgo,
|
||||
int (pincb)(void*, const char *, char **),
|
||||
void *pincb_arg,
|
||||
const void *indata, size_t indatalen,
|
||||
void **outdata, size_t *outdatalen )
|
||||
static int
|
||||
p15_prepare_key (CARD card, const char *keyidstr,
|
||||
int (pincb)(void*, const char *, char **),
|
||||
void *pincb_arg, struct sc_pkcs15_object **r_keyobj)
|
||||
{
|
||||
unsigned int cryptflags = 0;
|
||||
struct sc_pkcs15_id keyid;
|
||||
struct sc_pkcs15_pin_info *pin;
|
||||
struct sc_pkcs15_object *keyobj, *pinobj;
|
||||
char *pinvalue;
|
||||
int rc;
|
||||
unsigned char *outbuf = NULL;
|
||||
size_t outbuflen;
|
||||
|
||||
if (hashalgo != GCRY_MD_SHA1)
|
||||
return GNUPG_Unsupported_Algorithm;
|
||||
|
||||
rc = idstr_to_id (keyidstr, &keyid);
|
||||
if (rc)
|
||||
@ -227,18 +217,15 @@ p15_sign (CARD card, const char *keyidstr, int hashalgo,
|
||||
if (rc < 0)
|
||||
{
|
||||
log_error ("private key not found: %s\n", sc_strerror(rc));
|
||||
rc = GNUPG_No_Secret_Key;
|
||||
goto leave;
|
||||
return GNUPG_No_Secret_Key;
|
||||
}
|
||||
rc = 0;
|
||||
|
||||
rc = sc_pkcs15_find_pin_by_auth_id (card->p15card,
|
||||
&keyobj->auth_id, &pinobj);
|
||||
if (rc)
|
||||
{
|
||||
log_error ("failed to find PIN by auth ID: %s\n", sc_strerror (rc));
|
||||
rc = GNUPG_Bad_PIN_Method;
|
||||
goto leave;
|
||||
return GNUPG_Bad_PIN_Method;
|
||||
}
|
||||
pin = pinobj->data;
|
||||
|
||||
@ -249,7 +236,7 @@ p15_sign (CARD card, const char *keyidstr, int hashalgo,
|
||||
if (rc)
|
||||
{
|
||||
log_info ("PIN callback returned error: %s\n", gnupg_strerror (rc));
|
||||
goto leave;
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = sc_pkcs15_verify_pin (card->p15card, pin,
|
||||
@ -258,11 +245,37 @@ p15_sign (CARD card, const char *keyidstr, int hashalgo,
|
||||
if (rc)
|
||||
{
|
||||
log_info ("PIN verification failed: %s\n", sc_strerror (rc));
|
||||
rc = GNUPG_Bad_PIN;
|
||||
goto leave;
|
||||
return GNUPG_Bad_PIN;
|
||||
}
|
||||
|
||||
cryptflags |= SC_ALGORITHM_RSA_PAD_PKCS1;
|
||||
/* fixme: check wheter we need to release KEYOBJ in case of an error */
|
||||
*r_keyobj = keyobj;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* See card.c for interface description */
|
||||
static int
|
||||
p15_sign (CARD card, const char *keyidstr, int hashalgo,
|
||||
int (pincb)(void*, const char *, char **),
|
||||
void *pincb_arg,
|
||||
const void *indata, size_t indatalen,
|
||||
void **outdata, size_t *outdatalen )
|
||||
{
|
||||
unsigned int cryptflags;
|
||||
struct sc_pkcs15_object *keyobj;
|
||||
int rc;
|
||||
unsigned char *outbuf = NULL;
|
||||
size_t outbuflen;
|
||||
|
||||
if (hashalgo != GCRY_MD_SHA1)
|
||||
return GNUPG_Unsupported_Algorithm;
|
||||
|
||||
rc = p15_prepare_key (card, keyidstr, pincb, pincb_arg, &keyobj);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
cryptflags = SC_ALGORITHM_RSA_PAD_PKCS1;
|
||||
|
||||
outbuflen = 1024;
|
||||
outbuf = xtrymalloc (outbuflen);
|
||||
@ -286,8 +299,6 @@ p15_sign (CARD card, const char *keyidstr, int hashalgo,
|
||||
rc = 0;
|
||||
}
|
||||
|
||||
|
||||
leave:
|
||||
xfree (outbuf);
|
||||
return rc;
|
||||
}
|
||||
@ -301,55 +312,31 @@ p15_decipher (CARD card, const char *keyidstr,
|
||||
const void *indata, size_t indatalen,
|
||||
void **outdata, size_t *outdatalen )
|
||||
{
|
||||
struct sc_pkcs15_id keyid;
|
||||
struct sc_pkcs15_pin_info *pin;
|
||||
struct sc_pkcs15_object *keyobj, *pinobj;
|
||||
char *pinvalue;
|
||||
struct sc_pkcs15_object *keyobj;
|
||||
int rc;
|
||||
unsigned char *outbuf = NULL;
|
||||
size_t outbuflen;
|
||||
|
||||
rc = idstr_to_id (keyidstr, &keyid);
|
||||
rc = p15_prepare_key (card, keyidstr, pincb, pincb_arg, &keyobj);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
rc = sc_pkcs15_find_prkey_by_id (card->p15card, &keyid, &keyobj);
|
||||
if (rc < 0)
|
||||
if (card && card->scard && card->scard->driver
|
||||
&& !strcasecmp (card->scard->driver->short_name, "tcos"))
|
||||
{
|
||||
log_error ("private key not found: %s\n", sc_strerror(rc));
|
||||
rc = GNUPG_No_Secret_Key;
|
||||
goto leave;
|
||||
}
|
||||
rc = 0;
|
||||
|
||||
rc = sc_pkcs15_find_pin_by_auth_id (card->p15card,
|
||||
&keyobj->auth_id, &pinobj);
|
||||
if (rc)
|
||||
{
|
||||
log_error ("failed to find PIN by auth ID: %s\n", sc_strerror (rc));
|
||||
rc = GNUPG_Bad_PIN_Method;
|
||||
goto leave;
|
||||
}
|
||||
pin = pinobj->data;
|
||||
|
||||
/* Fixme: pack this into a verification loop */
|
||||
/* Fixme: we might want to pass pin->min_length and
|
||||
pin->stored_length */
|
||||
rc = pincb (pincb_arg, pinobj->label, &pinvalue);
|
||||
if (rc)
|
||||
{
|
||||
log_info ("PIN callback returned error: %s\n", gnupg_strerror (rc));
|
||||
goto leave;
|
||||
}
|
||||
|
||||
rc = sc_pkcs15_verify_pin (card->p15card, pin,
|
||||
pinvalue, strlen (pinvalue));
|
||||
xfree (pinvalue);
|
||||
if (rc)
|
||||
{
|
||||
log_info ("PIN verification failed: %s\n", sc_strerror (rc));
|
||||
rc = GNUPG_Bad_PIN;
|
||||
goto leave;
|
||||
/* very ugly hack to force the use of a local key. We need this
|
||||
until we have fixed the initialization code for TCOS cards */
|
||||
struct sc_pkcs15_prkey_info *prkey = keyobj->data;
|
||||
if ( !(prkey->key_reference & 0x80))
|
||||
{
|
||||
prkey->key_reference |= 0x80;
|
||||
log_debug ("using TCOS hack to force the use of local keys\n");
|
||||
}
|
||||
if (*keyidstr && keyidstr[strlen(keyidstr)-1] == '6')
|
||||
{
|
||||
prkey->key_reference |= 1;
|
||||
log_debug ("warning: using even more TCOS hacks\n");
|
||||
}
|
||||
}
|
||||
|
||||
outbuflen = indatalen < 256? 256 : indatalen;
|
||||
@ -357,17 +344,12 @@ p15_decipher (CARD card, const char *keyidstr,
|
||||
if (!outbuf)
|
||||
return GNUPG_Out_Of_Core;
|
||||
|
||||
/* OpenSC does not yet support decryption for cryptflex cards */
|
||||
/* rc = sc_pkcs15_decipher (card->p15card, key, */
|
||||
/* indata, indatalen, */
|
||||
/* outbuf, outbuflen); */
|
||||
rc = sc_pkcs15_compute_signature (card->p15card, keyobj,
|
||||
0,
|
||||
indata, indatalen,
|
||||
outbuf, outbuflen );
|
||||
rc = sc_pkcs15_decipher (card->p15card, keyobj,
|
||||
indata, indatalen,
|
||||
outbuf, outbuflen);
|
||||
if (rc < 0)
|
||||
{
|
||||
log_error ("failed to decipger the data: %s\n", sc_strerror (rc));
|
||||
log_error ("failed to decipher the data: %s\n", sc_strerror (rc));
|
||||
rc = GNUPG_Card_Error;
|
||||
}
|
||||
else
|
||||
@ -378,15 +360,12 @@ p15_decipher (CARD card, const char *keyidstr,
|
||||
rc = 0;
|
||||
}
|
||||
|
||||
|
||||
leave:
|
||||
xfree (outbuf);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* Bind our operations to the card */
|
||||
void
|
||||
card_p15_bind (CARD card)
|
||||
|
11
scd/card.c
11
scd/card.c
@ -141,10 +141,9 @@ card_open (CARD *rcard)
|
||||
goto leave;
|
||||
}
|
||||
card->ctx->error_file = log_get_stream ();
|
||||
if (opt.debug)
|
||||
{
|
||||
card->ctx->debug_file = log_get_stream ();
|
||||
}
|
||||
card->ctx->debug = opt.debug_sc;
|
||||
card->ctx->debug_file = log_get_stream ();
|
||||
|
||||
if (sc_detect_card_presence (card->ctx->reader[card->reader], 0) != 1)
|
||||
{
|
||||
rc = GNUPG_Card_Not_Present;
|
||||
@ -258,7 +257,9 @@ card_get_serial_and_stamp (CARD card, char **serial, time_t *stamp)
|
||||
|
||||
/* We should lookup the iso 7812-1 and 8583-3 - argh ISO
|
||||
practice is suppressing innovation - IETF rules! So we
|
||||
always get the serialnumber from the 2F00 GDO file. */
|
||||
always get the serialnumber from the 2F02 GDO file. */
|
||||
/* FIXME: in case we can't parse the 2F02 EF and we have a P15 card,
|
||||
we should get the serial number from the respective P15 file */
|
||||
sc_format_path ("3F002F02", &path);
|
||||
rc = sc_select_file (card->scard, &path, &file);
|
||||
if (rc)
|
||||
|
@ -60,6 +60,7 @@ enum cmd_and_opt_values
|
||||
oDebug,
|
||||
oDebugAll,
|
||||
oDebugWait,
|
||||
oDebugSC,
|
||||
oNoGreeting,
|
||||
oNoOptions,
|
||||
oHomedir,
|
||||
@ -86,6 +87,7 @@ static ARGPARSE_OPTS opts[] = {
|
||||
{ oDebug, "debug" ,4|16, N_("set debugging flags")},
|
||||
{ oDebugAll, "debug-all" ,0, N_("enable full debugging")},
|
||||
{ oDebugWait,"debug-wait",1, "@"},
|
||||
{ oDebugSC, "debug-sc", 1, N_("N|set OpenSC debug level to N")},
|
||||
{ oNoDetach, "no-detach" ,0, N_("do not detach from the console")},
|
||||
{ oLogFile, "log-file" ,2, N_("use a log file for the server")},
|
||||
|
||||
@ -344,6 +346,7 @@ main (int argc, char **argv )
|
||||
case oDebug: opt.debug |= pargs.r.ret_ulong; break;
|
||||
case oDebugAll: opt.debug = ~0; break;
|
||||
case oDebugWait: debug_wait = pargs.r.ret_int; break;
|
||||
case oDebugSC: opt.debug_sc = pargs.r.ret_int; break;
|
||||
|
||||
case oOptions:
|
||||
/* config files may not be nested (silently ignore them) */
|
||||
|
@ -31,6 +31,7 @@
|
||||
/* A large struct name "opt" to keep global flags */
|
||||
struct {
|
||||
unsigned int debug; /* debug flags (DBG_foo_VALUE) */
|
||||
int debug_sc; /* OpenSC debug level */
|
||||
int verbose; /* verbosity level */
|
||||
int quiet; /* be as quiet as possible */
|
||||
int dry_run; /* don't change any persistent data */
|
||||
|
Loading…
x
Reference in New Issue
Block a user