mirror of
git://git.gnupg.org/gnupg.git
synced 2025-04-12 22:11:29 +02:00
*** empty log message ***
This commit is contained in:
parent
1a389c1e1e
commit
f8d44bc637
@ -1,3 +1,17 @@
|
|||||||
|
2004-03-11 Werner Koch <wk@gnupg.org>
|
||||||
|
|
||||||
|
* scdaemon.h (out_of_core): Removed. Replaced callers by standard
|
||||||
|
gpg_error function.
|
||||||
|
|
||||||
|
* apdu.c, iso7816.c, ccid-driver.c [GNUPG_SCD_MAIN_HEADER]: Allow
|
||||||
|
to include a header defined by the compiler. This helps us to
|
||||||
|
reuse the source in other software.
|
||||||
|
|
||||||
|
2004-03-10 Werner Koch <wk@gnupg.org>
|
||||||
|
|
||||||
|
* iso7816.c (iso7816_read_record): New arg SHORT_EF. Changed all
|
||||||
|
callers.
|
||||||
|
|
||||||
2004-02-18 Werner Koch <wk@gnupg.org>
|
2004-02-18 Werner Koch <wk@gnupg.org>
|
||||||
|
|
||||||
* sc-investigate.c (main): Setup the used character set.
|
* sc-investigate.c (main): Setup the used character set.
|
||||||
|
@ -28,7 +28,9 @@
|
|||||||
# include <opensc/opensc.h>
|
# include <opensc/opensc.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if GNUPG_MAJOR_VERSION == 1
|
#if defined(GNUPG_SCD_MAIN_HEADER)
|
||||||
|
#include GNUPG_SCD_MAIN_HEADER
|
||||||
|
#elif GNUPG_MAJOR_VERSION == 1
|
||||||
/* This is used with GnuPG version < 1.9. The code has been source
|
/* This is used with GnuPG version < 1.9. The code has been source
|
||||||
copied from the current GnuPG >= 1.9 and is maintained over
|
copied from the current GnuPG >= 1.9 and is maintained over
|
||||||
there. */
|
there. */
|
||||||
|
@ -130,10 +130,10 @@ keygripstr_from_pk_file (int slot, int fid, char *r_gripstr)
|
|||||||
err = iso7816_select_file (slot, fid, 0, NULL, NULL);
|
err = iso7816_select_file (slot, fid, 0, NULL, NULL);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
err = iso7816_read_record (slot, 1, 1, &buffer[0], &buflen[0]);
|
err = iso7816_read_record (slot, 1, 1, 0, &buffer[0], &buflen[0]);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
err = iso7816_read_record (slot, 2, 1, &buffer[1], &buflen[1]);
|
err = iso7816_read_record (slot, 2, 1, 0, &buffer[1], &buflen[1]);
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
xfree (buffer[0]);
|
xfree (buffer[0]);
|
||||||
|
@ -245,7 +245,7 @@ store_fpr (int slot, int keynumber, u32 timestamp,
|
|||||||
n = 6 + 2 + mlen + 2 + elen;
|
n = 6 + 2 + mlen + 2 + elen;
|
||||||
p = buffer = xtrymalloc (3 + n);
|
p = buffer = xtrymalloc (3 + n);
|
||||||
if (!buffer)
|
if (!buffer)
|
||||||
return out_of_core ();
|
return gpg_error (gpg_err_code_from_errno (errno));
|
||||||
|
|
||||||
*p++ = 0x99; /* ctb */
|
*p++ = 0x99; /* ctb */
|
||||||
*p++ = n >> 8; /* 2 byte length header */
|
*p++ = n >> 8; /* 2 byte length header */
|
||||||
|
@ -47,7 +47,7 @@ select_application (ctrl_t ctrl, int slot, const char *name)
|
|||||||
app = xtrycalloc (1, sizeof *app);
|
app = xtrycalloc (1, sizeof *app);
|
||||||
if (!app)
|
if (!app)
|
||||||
{
|
{
|
||||||
rc = out_of_core ();
|
rc = gpg_error (gpg_err_code_from_errno (errno));
|
||||||
log_info ("error allocating context: %s\n", gpg_strerror (rc));
|
log_info ("error allocating context: %s\n", gpg_strerror (rc));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -141,7 +141,7 @@ dinsig_enum_keypairs (CARD card, int idx,
|
|||||||
{
|
{
|
||||||
*keyid = xtrymalloc (17);
|
*keyid = xtrymalloc (17);
|
||||||
if (!*keyid)
|
if (!*keyid)
|
||||||
return out_of_core ();
|
return gpg_error (gpg_err_code_from_errno (errno));
|
||||||
if (!idx)
|
if (!idx)
|
||||||
strcpy (*keyid, "DINSIG-DF01.C000");
|
strcpy (*keyid, "DINSIG-DF01.C000");
|
||||||
else
|
else
|
||||||
@ -193,7 +193,7 @@ dinsig_read_cert (CARD card, const char *certidstr,
|
|||||||
buf = xtrymalloc (file->size);
|
buf = xtrymalloc (file->size);
|
||||||
if (!buf)
|
if (!buf)
|
||||||
{
|
{
|
||||||
gpg_error_t tmperr = out_of_core ();
|
gpg_error_t tmperr = gpg_error (gpg_err_code_from_errno (errno));
|
||||||
sc_file_free (file);
|
sc_file_free (file);
|
||||||
return tmperr;
|
return tmperr;
|
||||||
}
|
}
|
||||||
|
@ -53,7 +53,7 @@ init_private_data (CARD card)
|
|||||||
|
|
||||||
priv = xtrycalloc (1, sizeof *priv);
|
priv = xtrycalloc (1, sizeof *priv);
|
||||||
if (!priv)
|
if (!priv)
|
||||||
return out_of_core ();
|
return gpg_error (gpg_err_code_from_errno (errno));
|
||||||
|
|
||||||
/* OpenSC (0.7.0) is a bit strange in that the get_objects functions
|
/* OpenSC (0.7.0) is a bit strange in that the get_objects functions
|
||||||
tries to be a bit too clever and implicitly does an enumeration
|
tries to be a bit too clever and implicitly does an enumeration
|
||||||
@ -179,7 +179,7 @@ p15_enum_keypairs (CARD card, int idx,
|
|||||||
|
|
||||||
*keyid = p = xtrymalloc (9+pinfo->id.len*2+1);
|
*keyid = p = xtrymalloc (9+pinfo->id.len*2+1);
|
||||||
if (!*keyid)
|
if (!*keyid)
|
||||||
return out_of_core ();
|
return gpg_error (gpg_err_code_from_errno (errno));
|
||||||
p = stpcpy (p, "P15-5015.");
|
p = stpcpy (p, "P15-5015.");
|
||||||
for (i=0; i < pinfo->id.len; i++, p += 2)
|
for (i=0; i < pinfo->id.len; i++, p += 2)
|
||||||
sprintf (p, "%02X", pinfo->id.value[i]);
|
sprintf (p, "%02X", pinfo->id.value[i]);
|
||||||
@ -217,7 +217,7 @@ p15_enum_certs (CARD card, int idx, char **certid, int *type)
|
|||||||
|
|
||||||
*certid = p = xtrymalloc (9+cinfo->id.len*2+1);
|
*certid = p = xtrymalloc (9+cinfo->id.len*2+1);
|
||||||
if (!*certid)
|
if (!*certid)
|
||||||
return out_of_core ();
|
return gpg_error (gpg_err_code_from_errno (errno));
|
||||||
p = stpcpy (p, "P15-5015.");
|
p = stpcpy (p, "P15-5015.");
|
||||||
for (i=0; i < cinfo->id.len; i++, p += 2)
|
for (i=0; i < cinfo->id.len; i++, p += 2)
|
||||||
sprintf (p, "%02X", cinfo->id.value[i]);
|
sprintf (p, "%02X", cinfo->id.value[i]);
|
||||||
@ -304,7 +304,7 @@ p15_read_cert (CARD card, const char *certidstr,
|
|||||||
*cert = xtrymalloc (certder->data_len);
|
*cert = xtrymalloc (certder->data_len);
|
||||||
if (!*cert)
|
if (!*cert)
|
||||||
{
|
{
|
||||||
gpg_error_t tmperr = out_of_core ();
|
gpg_error_t tmperr = gpg_error (gpg_err_code_from_errno (errno));
|
||||||
sc_pkcs15_free_certificate (certder);
|
sc_pkcs15_free_certificate (certder);
|
||||||
return tmperr;
|
return tmperr;
|
||||||
}
|
}
|
||||||
@ -400,7 +400,7 @@ p15_sign (CARD card, const char *keyidstr, int hashalgo,
|
|||||||
outbuflen = 1024;
|
outbuflen = 1024;
|
||||||
outbuf = xtrymalloc (outbuflen);
|
outbuf = xtrymalloc (outbuflen);
|
||||||
if (!outbuf)
|
if (!outbuf)
|
||||||
return out_of_core ();
|
return gpg_error (gpg_err_code_from_errno (errno));
|
||||||
|
|
||||||
rc = sc_pkcs15_compute_signature (card->p15card, keyobj,
|
rc = sc_pkcs15_compute_signature (card->p15card, keyobj,
|
||||||
cryptflags,
|
cryptflags,
|
||||||
@ -462,7 +462,7 @@ p15_decipher (CARD card, const char *keyidstr,
|
|||||||
outbuflen = indatalen < 256? 256 : indatalen;
|
outbuflen = indatalen < 256? 256 : indatalen;
|
||||||
outbuf = xtrymalloc (outbuflen);
|
outbuf = xtrymalloc (outbuflen);
|
||||||
if (!outbuf)
|
if (!outbuf)
|
||||||
return out_of_core ();
|
return gpg_error (gpg_err_code_from_errno (errno));
|
||||||
|
|
||||||
rc = sc_pkcs15_decipher (card->p15card, keyobj,
|
rc = sc_pkcs15_decipher (card->p15card, keyobj,
|
||||||
0,
|
0,
|
||||||
|
@ -108,7 +108,7 @@ card_open (CARD *rcard)
|
|||||||
|
|
||||||
card = xtrycalloc (1, sizeof *card);
|
card = xtrycalloc (1, sizeof *card);
|
||||||
if (!card)
|
if (!card)
|
||||||
return out_of_core ();
|
return gpg_error (gpg_err_code_from_errno (errno));
|
||||||
card->reader = 0;
|
card->reader = 0;
|
||||||
|
|
||||||
rc = sc_establish_context (&card->ctx, "scdaemon");
|
rc = sc_establish_context (&card->ctx, "scdaemon");
|
||||||
@ -275,7 +275,7 @@ find_iccsn (const unsigned char *buffer, size_t length, char **serial)
|
|||||||
|
|
||||||
*serial = p = xtrymalloc (2*n+1);
|
*serial = p = xtrymalloc (2*n+1);
|
||||||
if (!*serial)
|
if (!*serial)
|
||||||
return out_of_core ();
|
return gpg_error (gpg_err_code_from_errno (errno));
|
||||||
for (; n; n--, p += 2, s++)
|
for (; n; n--, p += 2, s++)
|
||||||
sprintf (p, "%02X", *s);
|
sprintf (p, "%02X", *s);
|
||||||
*p = 0;
|
*p = 0;
|
||||||
@ -389,7 +389,7 @@ card_get_serial_and_stamp (CARD card, char **serial, time_t *stamp)
|
|||||||
*serial = NULL;
|
*serial = NULL;
|
||||||
p = xtrymalloc (strlen (efser) + 7);
|
p = xtrymalloc (strlen (efser) + 7);
|
||||||
if (!p)
|
if (!p)
|
||||||
rc = out_of_core ();
|
rc = gpg_error (gpg_err_code_from_errno (errno));
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
strcpy (p, "FF0100");
|
strcpy (p, "FF0100");
|
||||||
@ -405,7 +405,7 @@ card_get_serial_and_stamp (CARD card, char **serial, time_t *stamp)
|
|||||||
{
|
{
|
||||||
xfree (*serial);
|
xfree (*serial);
|
||||||
*serial = NULL;
|
*serial = NULL;
|
||||||
rc = out_of_core ();
|
rc = gpg_error (gpg_err_code_from_errno (errno));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -87,16 +87,24 @@
|
|||||||
#define DRVNAME "ccid-driver: "
|
#define DRVNAME "ccid-driver: "
|
||||||
|
|
||||||
|
|
||||||
#ifdef GNUPG_MAJOR_VERSION /* This source is used within GnuPG. */
|
/* Depending on how this source is used we either define our error
|
||||||
|
output to go to stderr or to the jnlib based logging functions. We
|
||||||
|
use the latter when GNUPG_MAJOR_VERSION is defines or when both,
|
||||||
|
GNUPG_SCD_MAIN_HEADER and HAVE_JNLIB_LOGGING are defined.
|
||||||
|
*/
|
||||||
|
#if defined(GNUPG_MAJOR_VERSION) \
|
||||||
|
|| (defined(GNUPG_SCD_MAIN_HEADER) && defined(HAVE_JNLIB_LOGGING))
|
||||||
|
|
||||||
# if GNUPG_MAJOR_VERSION == 1 /* GnuPG Version is < 1.9. */
|
#if defined(GNUPG_SCD_MAIN_HEADER)
|
||||||
|
# include GNUPG_SCD_MAIN_HEADER
|
||||||
|
#elif GNUPG_MAJOR_VERSION == 1 /* GnuPG Version is < 1.9. */
|
||||||
# include "options.h"
|
# include "options.h"
|
||||||
# include "util.h"
|
# include "util.h"
|
||||||
# include "memory.h"
|
# include "memory.h"
|
||||||
# include "cardglue.h"
|
# include "cardglue.h"
|
||||||
# else /* This is the modularized GnuPG 1.9 or later. */
|
# else /* This is the modularized GnuPG 1.9 or later. */
|
||||||
# include "scdaemon.h"
|
# include "scdaemon.h"
|
||||||
# endif
|
#endif
|
||||||
|
|
||||||
/* Disable all debugging output for now. */
|
/* Disable all debugging output for now. */
|
||||||
#undef DBG_CARD_IO
|
#undef DBG_CARD_IO
|
||||||
|
@ -351,7 +351,7 @@ cmd_learn (ASSUAN_CONTEXT ctx, char *line)
|
|||||||
|
|
||||||
buf = xtrymalloc (40 + 1 + strlen (certid) + 1);
|
buf = xtrymalloc (40 + 1 + strlen (certid) + 1);
|
||||||
if (!buf)
|
if (!buf)
|
||||||
rc = out_of_core ();
|
rc = gpg_error (gpg_err_code_from_errno (errno));
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sprintf (buf, "%d %s", certtype, certid);
|
sprintf (buf, "%d %s", certtype, certid);
|
||||||
@ -389,7 +389,7 @@ cmd_learn (ASSUAN_CONTEXT ctx, char *line)
|
|||||||
|
|
||||||
buf = p = xtrymalloc (40 + 1 + strlen (keyid) + 1);
|
buf = p = xtrymalloc (40 + 1 + strlen (keyid) + 1);
|
||||||
if (!buf)
|
if (!buf)
|
||||||
rc = out_of_core ();
|
rc = gpg_error (gpg_err_code_from_errno (errno));
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@ -577,7 +577,7 @@ pin_cb (void *opaque, const char *info, char **retstr)
|
|||||||
|
|
||||||
rc = asprintf (&command, "NEEDPIN %s", info);
|
rc = asprintf (&command, "NEEDPIN %s", info);
|
||||||
if (rc < 0)
|
if (rc < 0)
|
||||||
return out_of_core ();
|
return gpg_error (gpg_err_code_from_errno (errno));
|
||||||
|
|
||||||
/* FIXME: Write an inquire function which returns the result in
|
/* FIXME: Write an inquire function which returns the result in
|
||||||
secure memory */
|
secure memory */
|
||||||
|
@ -24,7 +24,9 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#if GNUPG_MAJOR_VERSION == 1
|
#if defined(GNUPG_SCD_MAIN_HEADER)
|
||||||
|
#include GNUPG_SCD_MAIN_HEADER
|
||||||
|
#elif GNUPG_MAJOR_VERSION == 1
|
||||||
/* This is used with GnuPG version < 1.9. The code has been source
|
/* This is used with GnuPG version < 1.9. The code has been source
|
||||||
copied from the current GnuPG >= 1.9 and is maintained over
|
copied from the current GnuPG >= 1.9 and is maintained over
|
||||||
there. */
|
there. */
|
||||||
@ -200,7 +202,7 @@ iso7816_change_reference_data (int slot, int chvno,
|
|||||||
|
|
||||||
buf = xtrymalloc (oldchvlen + newchvlen);
|
buf = xtrymalloc (oldchvlen + newchvlen);
|
||||||
if (!buf)
|
if (!buf)
|
||||||
return out_of_core ();
|
return gpg_error (gpg_err_code_from_errno (errno));
|
||||||
if (oldchvlen)
|
if (oldchvlen)
|
||||||
memcpy (buf, oldchv, oldchvlen);
|
memcpy (buf, oldchv, oldchvlen);
|
||||||
memcpy (buf+oldchvlen, newchv, newchvlen);
|
memcpy (buf+oldchvlen, newchv, newchvlen);
|
||||||
@ -341,7 +343,8 @@ iso7816_decipher (int slot, const unsigned char *data, size_t datalen,
|
|||||||
/* We need to prepend the padding indicator. */
|
/* We need to prepend the padding indicator. */
|
||||||
buf = xtrymalloc (datalen + 1);
|
buf = xtrymalloc (datalen + 1);
|
||||||
if (!buf)
|
if (!buf)
|
||||||
return out_of_core ();
|
return gpg_error (gpg_err_code_from_errno (errno));
|
||||||
|
|
||||||
*buf = padind; /* Padding indicator. */
|
*buf = padind; /* Padding indicator. */
|
||||||
memcpy (buf+1, data, datalen);
|
memcpy (buf+1, data, datalen);
|
||||||
sw = apdu_send (slot, 0x00, CMD_PSO, 0x80, 0x86, datalen+1, buf,
|
sw = apdu_send (slot, 0x00, CMD_PSO, 0x80, 0x86, datalen+1, buf,
|
||||||
@ -550,11 +553,13 @@ iso7816_read_binary (int slot, size_t offset, size_t nmax,
|
|||||||
|
|
||||||
/* Perform a READ RECORD command. RECNO gives the record number to
|
/* Perform a READ RECORD command. RECNO gives the record number to
|
||||||
read with 0 indicating the current record. RECCOUNT must be 1 (not
|
read with 0 indicating the current record. RECCOUNT must be 1 (not
|
||||||
all cards support reading of more than one record). The result is
|
all cards support reading of more than one record). SHORT_EF
|
||||||
stored in a newly allocated buffer at the address passed by RESULT.
|
should be 0 to read the current EF or contain a short EF. The
|
||||||
Returns the length of this data at the address of RESULTLEN. */
|
result is stored in a newly allocated buffer at the address passed
|
||||||
|
by RESULT. Returns the length of this data at the address of
|
||||||
|
RESULTLEN. */
|
||||||
gpg_error_t
|
gpg_error_t
|
||||||
iso7816_read_record (int slot, int recno, int reccount,
|
iso7816_read_record (int slot, int recno, int reccount, int short_ef,
|
||||||
unsigned char **result, size_t *resultlen)
|
unsigned char **result, size_t *resultlen)
|
||||||
{
|
{
|
||||||
int sw;
|
int sw;
|
||||||
@ -568,7 +573,8 @@ iso7816_read_record (int slot, int recno, int reccount,
|
|||||||
|
|
||||||
/* We can only encode 15 bits in p0,p1 to indicate an offset. Thus
|
/* We can only encode 15 bits in p0,p1 to indicate an offset. Thus
|
||||||
we check for this limit. */
|
we check for this limit. */
|
||||||
if (recno < 0 || recno > 255 || reccount != 1)
|
if (recno < 0 || recno > 255 || reccount != 1
|
||||||
|
|| short_ef < 0 || short_ef > 254 )
|
||||||
return gpg_error (GPG_ERR_INV_VALUE);
|
return gpg_error (GPG_ERR_INV_VALUE);
|
||||||
|
|
||||||
buffer = NULL;
|
buffer = NULL;
|
||||||
@ -577,7 +583,7 @@ iso7816_read_record (int slot, int recno, int reccount,
|
|||||||
with an Le of 0. */
|
with an Le of 0. */
|
||||||
sw = apdu_send_le (slot, 0x00, CMD_READ_RECORD,
|
sw = apdu_send_le (slot, 0x00, CMD_READ_RECORD,
|
||||||
recno,
|
recno,
|
||||||
0x04,
|
short_ef? short_ef : 0x04,
|
||||||
-1, NULL,
|
-1, NULL,
|
||||||
254, &buffer, &bufferlen);
|
254, &buffer, &bufferlen);
|
||||||
|
|
||||||
|
@ -67,6 +67,7 @@ gpg_error_t iso7816_get_challenge (int slot,
|
|||||||
gpg_error_t iso7816_read_binary (int slot, size_t offset, size_t nmax,
|
gpg_error_t iso7816_read_binary (int slot, size_t offset, size_t nmax,
|
||||||
unsigned char **result, size_t *resultlen);
|
unsigned char **result, size_t *resultlen);
|
||||||
gpg_error_t iso7816_read_record (int slot, int recno, int reccount,
|
gpg_error_t iso7816_read_record (int slot, int recno, int reccount,
|
||||||
|
int short_ef,
|
||||||
unsigned char **result, size_t *resultlen);
|
unsigned char **result, size_t *resultlen);
|
||||||
|
|
||||||
#endif /*ISO7816_H*/
|
#endif /*ISO7816_H*/
|
||||||
|
@ -50,8 +50,10 @@ enum cmd_and_opt_values
|
|||||||
{
|
{
|
||||||
oInteractive = 'i',
|
oInteractive = 'i',
|
||||||
oVerbose = 'v',
|
oVerbose = 'v',
|
||||||
|
oQuiet = 'q',
|
||||||
oReaderPort = 500,
|
oReaderPort = 500,
|
||||||
octapiDriver,
|
octapiDriver,
|
||||||
|
|
||||||
oDebug,
|
oDebug,
|
||||||
oDebugAll,
|
oDebugAll,
|
||||||
|
|
||||||
@ -68,6 +70,7 @@ static ARGPARSE_OPTS opts[] = {
|
|||||||
{ 301, NULL, 0, "@Options:\n " },
|
{ 301, NULL, 0, "@Options:\n " },
|
||||||
|
|
||||||
{ oInteractive, "interactive", 0, "start in interactive explorer mode"},
|
{ oInteractive, "interactive", 0, "start in interactive explorer mode"},
|
||||||
|
{ oQuiet, "quiet", 0, "quiet" },
|
||||||
{ oVerbose, "verbose", 0, "verbose" },
|
{ oVerbose, "verbose", 0, "verbose" },
|
||||||
{ oReaderPort, "reader-port", 2, "|N|connect to reader at port N"},
|
{ oReaderPort, "reader-port", 2, "|N|connect to reader at port N"},
|
||||||
{ octapiDriver, "ctapi-driver", 2, "NAME|use NAME as ctAPI driver"},
|
{ octapiDriver, "ctapi-driver", 2, "NAME|use NAME as ctAPI driver"},
|
||||||
@ -86,7 +89,7 @@ static ARGPARSE_OPTS opts[] = {
|
|||||||
|
|
||||||
|
|
||||||
static void interactive_shell (int slot);
|
static void interactive_shell (int slot);
|
||||||
|
static void dump_other_cards (int slot);
|
||||||
|
|
||||||
static const char *
|
static const char *
|
||||||
my_strusage (int level)
|
my_strusage (int level)
|
||||||
@ -168,6 +171,7 @@ main (int argc, char **argv )
|
|||||||
switch (pargs.r_opt)
|
switch (pargs.r_opt)
|
||||||
{
|
{
|
||||||
case oVerbose: opt.verbose++; break;
|
case oVerbose: opt.verbose++; break;
|
||||||
|
case oQuiet: opt.quiet++; break;
|
||||||
case oDebug: opt.debug |= pargs.r.ret_ulong; break;
|
case oDebug: opt.debug |= pargs.r.ret_ulong; break;
|
||||||
case oDebugAll: opt.debug = ~0; break;
|
case oDebugAll: opt.debug = ~0; break;
|
||||||
case oReaderPort: reader_port = pargs.r.ret_str; break;
|
case oReaderPort: reader_port = pargs.r.ret_str; break;
|
||||||
@ -191,7 +195,7 @@ main (int argc, char **argv )
|
|||||||
if (slot == -1)
|
if (slot == -1)
|
||||||
exit (1);
|
exit (1);
|
||||||
|
|
||||||
if (!gen_random)
|
if (!gen_random && !opt.quiet)
|
||||||
{
|
{
|
||||||
rc = atr_dump (slot, stdout);
|
rc = atr_dump (slot, stdout);
|
||||||
if (rc)
|
if (rc)
|
||||||
@ -210,12 +214,17 @@ main (int argc, char **argv )
|
|||||||
rc = app_select_openpgp (&appbuf);
|
rc = app_select_openpgp (&appbuf);
|
||||||
if (rc)
|
if (rc)
|
||||||
{
|
{
|
||||||
log_info ("selecting openpgp failed: %s\n", gpg_strerror (rc));
|
if (!opt.quiet)
|
||||||
|
log_info ("selecting openpgp failed: %s\n", gpg_strerror (rc));
|
||||||
memset (&appbuf, 0, sizeof appbuf);
|
memset (&appbuf, 0, sizeof appbuf);
|
||||||
appbuf.slot = slot;
|
appbuf.slot = slot;
|
||||||
rc = app_select_dinsig (&appbuf);
|
rc = app_select_dinsig (&appbuf);
|
||||||
if (rc)
|
if (rc)
|
||||||
log_info ("selecting dinsig failed: %s\n", gpg_strerror (rc));
|
{
|
||||||
|
if (!opt.quiet)
|
||||||
|
log_info ("selecting dinsig failed: %s\n", gpg_strerror (rc));
|
||||||
|
dump_other_cards (slot);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
appbuf.initialized = 1;
|
appbuf.initialized = 1;
|
||||||
@ -398,6 +407,7 @@ interactive_shell (int slot)
|
|||||||
cmdAPP,
|
cmdAPP,
|
||||||
cmdREAD,
|
cmdREAD,
|
||||||
cmdREADREC,
|
cmdREADREC,
|
||||||
|
cmdREADSHORTREC,
|
||||||
cmdDEBUG,
|
cmdDEBUG,
|
||||||
cmdVERIFY,
|
cmdVERIFY,
|
||||||
cmdCHANGEREF,
|
cmdCHANGEREF,
|
||||||
@ -425,6 +435,7 @@ interactive_shell (int slot)
|
|||||||
{ "rb" , cmdREAD, NULL },
|
{ "rb" , cmdREAD, NULL },
|
||||||
{ "readrec", cmdREADREC, "read record(s)" },
|
{ "readrec", cmdREADREC, "read record(s)" },
|
||||||
{ "rr" , cmdREADREC, NULL },
|
{ "rr" , cmdREADREC, NULL },
|
||||||
|
{ "rsr" , cmdREADSHORTREC, "readshortrec RECNO SHORT_EF" },
|
||||||
{ "verify" , cmdVERIFY, "verify CHVNO PIN" },
|
{ "verify" , cmdVERIFY, "verify CHVNO PIN" },
|
||||||
{ "ver" , cmdVERIFY, NULL },
|
{ "ver" , cmdVERIFY, NULL },
|
||||||
{ "changeref", cmdCHANGEREF, "change reference data" },
|
{ "changeref", cmdCHANGEREF, "change reference data" },
|
||||||
@ -559,7 +570,8 @@ interactive_shell (int slot)
|
|||||||
for (i=1, err=0; !err; i++)
|
for (i=1, err=0; !err; i++)
|
||||||
{
|
{
|
||||||
xfree (result); result = NULL;
|
xfree (result); result = NULL;
|
||||||
err = iso7816_read_record (slot, i, 1, &result, &resultlen);
|
err = iso7816_read_record (slot, i, 1, 0,
|
||||||
|
&result, &resultlen);
|
||||||
if (!err)
|
if (!err)
|
||||||
dump_buffer (result, resultlen);
|
dump_buffer (result, resultlen);
|
||||||
}
|
}
|
||||||
@ -568,13 +580,31 @@ interactive_shell (int slot)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
err = iso7816_read_record (slot, arg_number, 1,
|
err = iso7816_read_record (slot, arg_number, 1, 0,
|
||||||
&result, &resultlen);
|
&result, &resultlen);
|
||||||
if (!err)
|
if (!err)
|
||||||
dump_or_store_buffer (arg_string, result, resultlen);
|
dump_or_store_buffer (arg_string, result, resultlen);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case cmdREADSHORTREC:
|
||||||
|
{
|
||||||
|
int short_ef;
|
||||||
|
|
||||||
|
short_ef = strtol (arg_next, NULL, 0);
|
||||||
|
|
||||||
|
if (short_ef < 1 || short_ef > 254)
|
||||||
|
printf ("error: short EF must be between 1 and 254\n");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
err = iso7816_read_record (slot, arg_number, 1, short_ef,
|
||||||
|
&result, &resultlen);
|
||||||
|
if (!err)
|
||||||
|
dump_or_store_buffer (arg_string, result, resultlen);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case cmdVERIFY:
|
case cmdVERIFY:
|
||||||
if (arg_number < 0 || arg_number > 255 || (arg_number & 127) > 31)
|
if (arg_number < 0 || arg_number > 255 || (arg_number & 127) > 31)
|
||||||
printf ("error: invalid CHVNO\n");
|
printf ("error: invalid CHVNO\n");
|
||||||
@ -637,3 +667,104 @@ interactive_shell (int slot)
|
|||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Figure out whether the current card is a German Geldkarte and print
|
||||||
|
what we know about it. */
|
||||||
|
static int
|
||||||
|
dump_geldkarte (int slot)
|
||||||
|
{
|
||||||
|
unsigned char *r = NULL;
|
||||||
|
size_t rlen;
|
||||||
|
const char *t;
|
||||||
|
|
||||||
|
if (iso7816_read_record (slot, 1, 1, 0xbc, &r, &rlen))
|
||||||
|
return -1;
|
||||||
|
/* We require that the record is at least 24 bytes, the first byte
|
||||||
|
is 0x67 and the filler byte is correct. */
|
||||||
|
if (rlen < 24 || *r != 0x67 || r[22])
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* The short Bankleitzahl consists of 3 bytes at offset 1. */
|
||||||
|
switch (r[1])
|
||||||
|
{
|
||||||
|
case 0x21: t = "Oeffentlich-rechtliche oder private Bank"; break;
|
||||||
|
case 0x22: t = "Privat- oder Geschäftsbank"; break;
|
||||||
|
case 0x25: t = "Sparkasse"; break;
|
||||||
|
case 0x26:
|
||||||
|
case 0x29: t = "Genossenschaftsbank"; break;
|
||||||
|
default:
|
||||||
|
xfree (r);
|
||||||
|
return -1; /* Probably not a Geldkarte. */
|
||||||
|
}
|
||||||
|
|
||||||
|
printf ("KBLZ .....: %02X-%02X%02X (%s)\n", r[1], r[2], r[3], t);
|
||||||
|
printf ("Card-No ..: %02X%02X%02X%02X%02X\n", r[4], r[5], r[6], r[7], r[8]);
|
||||||
|
|
||||||
|
/* Byte 10 enthält im linken Halbbyte eine Prüfziffer, die nach dem */
|
||||||
|
/* Verfahren 'Luhn formula for computing modulus 10' über die Ziffern der */
|
||||||
|
/* ersten 9 Byte berechnet ist. */
|
||||||
|
|
||||||
|
/* Das rechte Halbbyte wird zu 'D' gesetzt. */
|
||||||
|
|
||||||
|
/* Für die Berechnung der Luhn-Prüfziffer sind die folgenden Schritte */
|
||||||
|
/* durchzuführen: */
|
||||||
|
|
||||||
|
/* Schritt 1: Mit der rechtesten Ziffer beginnend ist einschließlich dieser */
|
||||||
|
/* Ziffer jede übernächste Ziffer zu verdoppeln (mit 2 multiplizieren). */
|
||||||
|
|
||||||
|
/* Schritt 2: Die einzelnen Ziffern der Produkte aus Schritt 1 und die bei */
|
||||||
|
/* diesen Multiplikationen unberührt gebliebenen Ziffern sind zu addieren. */
|
||||||
|
|
||||||
|
/* Schritt 3: Das Ergebnis der Addition aus Schritt 2 ist von dem auf die */
|
||||||
|
/* nächst höhere Zahl mit der Einerstelle 0 aufgerundeten Ergebnis der */
|
||||||
|
/* Addition aus Schritt 2 abzuziehen. Wenn das Ergebnis der Addition aus */
|
||||||
|
/* Schritt 2 bereits eine Zahl mit der Einerstelle 0 ergibt (z.B. 30, 40, */
|
||||||
|
/* usw.), ist die Prüfziffer 0. */
|
||||||
|
|
||||||
|
/* Beispiel: Kartennummer ohne Prüfziffer: 992 839 871 */
|
||||||
|
|
||||||
|
/* 9 9 2 8 3 9 8 7 1 */
|
||||||
|
|
||||||
|
/* x 2 x 2 x 2 x 2 x 2 Schritt 1 */
|
||||||
|
|
||||||
|
/* 18 4 6 16 2 */
|
||||||
|
|
||||||
|
/* 1+8 +9 +4 +8 +6 +9 +1+6 +7 +2 = 61 Schritt 2 */
|
||||||
|
|
||||||
|
/* 70-61 = 9 Schritt 3 */
|
||||||
|
|
||||||
|
/* Prüfziffer zu 992 839 871 = 9 */
|
||||||
|
|
||||||
|
|
||||||
|
printf ("Expires at: %02X/%02X\n", r[11], r[10] );
|
||||||
|
printf ("Valid from: %02X.%02X.%02X\n", r[14], r[13], r[12]);
|
||||||
|
printf ("Country ..: %02X%02X\n", r[15], r[16]);
|
||||||
|
printf ("Currency .: %c%c%c\n", isascii (r[17])? r[17]:' ',
|
||||||
|
isascii (r[18])? r[18]:' ', isascii (r[19])? r[19]:' ');
|
||||||
|
printf ("Cur.-Mult : %s\n",
|
||||||
|
r[20] == 0x01? "0.01":
|
||||||
|
r[20] == 0x02? "0.1":
|
||||||
|
r[20] == 0x04? "1":
|
||||||
|
r[20] == 0x08? "10":
|
||||||
|
r[20] == 0x10? "100":
|
||||||
|
r[20] == 0x20? "1000": "?");
|
||||||
|
printf ("ZKA ChipID: %02X\n", r[21]);
|
||||||
|
printf ("OS version: %02X\n", r[23]);
|
||||||
|
|
||||||
|
xfree (r);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Try to figure out the type of teh card and dump its contents. */
|
||||||
|
static void
|
||||||
|
dump_other_cards (int slot)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (!dump_geldkarte (slot))
|
||||||
|
return;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -33,14 +33,6 @@
|
|||||||
#include "../common/util.h"
|
#include "../common/util.h"
|
||||||
#include "../common/errors.h"
|
#include "../common/errors.h"
|
||||||
|
|
||||||
/* Convenience funcion to be used instead of returning the old
|
|
||||||
GNUPG_Out_Of_Core. */
|
|
||||||
static __inline__ gpg_error_t
|
|
||||||
out_of_core (void)
|
|
||||||
{
|
|
||||||
return gpg_error (gpg_err_code_from_errno (errno));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#define MAX_DIGEST_LEN 24
|
#define MAX_DIGEST_LEN 24
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user