* cardglue.c (learn_status_cb): Release values before assignment

so that it can be used by getattr to update the structure.
(agent_scd_getattr): New.

* keylist.c (print_pubkey_info): Add FP arg for optional printing
to a stream.  Changed all callers.
This commit is contained in:
Werner Koch 2003-10-02 10:20:12 +00:00
parent b0fe35f60e
commit 99cabff03f
17 changed files with 562 additions and 348 deletions

View File

@ -1,3 +1,8 @@
2003-10-01 Werner Koch <wk@gnupg.org>
* configure.ac (AH_BOTTOM): Define GNUPG_MAJOR_VERSION.
(ENABLE_CARD_SUPPORT): Define as automake conditional.
2003-09-30 David Shaw <dshaw@jabberwocky.com> 2003-09-30 David Shaw <dshaw@jabberwocky.com>
* NEWS: Note that SHA-256 is read-write now, that TIGER/192 is no * NEWS: Note that SHA-256 is read-write now, that TIGER/192 is no

View File

@ -112,6 +112,7 @@ if test "$card_support" = yes ; then
AC_DEFINE(ENABLE_CARD_SUPPORT,1, AC_DEFINE(ENABLE_CARD_SUPPORT,1,
[Define to include the OpenPGP card support]) [Define to include the OpenPGP card support])
fi fi
AM_CONDITIONAL(ENABLE_CARD_SUPPORT, test "$card_support" = yes)
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
@ -309,6 +310,10 @@ AH_BOTTOM([
#define EXEC_TEMPFILE_ONLY #define EXEC_TEMPFILE_ONLY
#endif #endif
/* This is the major version number of GnuPG so that
source included files can test for this. */
#define GNUPG_MAJOR_VERSION 1
#include "g10defs.h" #include "g10defs.h"
]) ])

View File

@ -1,3 +1,45 @@
2003-10-02 Werner Koch <wk@gnupg.org>
* cardglue.c (learn_status_cb): Release values before assignment
so that it can be used by getattr to update the structure.
(agent_scd_getattr): New.
* keylist.c (print_pubkey_info): Add FP arg for optional printing
to a stream. Changed all callers.
2003-10-01 Werner Koch <wk@gnupg.org>
* 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 over there are:
* card-util.c: Tweaked to use this source also under 1.3.
(card_edit): New command "forcesig".
* card-util.c (print_name, print_isoname): Use 0 and not LF fro
the max_n arg of tty_print_utf8_string2.
* card-util.c (change_pin): Simplified. We now have only a PIN
and an Admin PIN.
* ccid-driver.c: Detect GnuPG 1.3 and include appropriate files.
* apdu.c: Ditto.
* app-openpgp.c: Ditto.
* iso7816.c: Ditto.
(generate_keypair): Renamed to ..
(do_generate_keypair): .. this.
* app-common.h [GNUPG_MAJOR_VERSION]: New.
* iso7816.h [GNUPG_MAJOR_VERSION]: Include cardglue.h
* app-openpgp.c (do_change_pin): Make sure CVH1 and CHV2 are
always synced.
(verify_chv2, verify_chv3): New. Factored out common code.
(do_setattr, do_sign, do_auth, do_decipher): Change the names of
the prompts to match that we have only 2 different PINs.
(app_select_openpgp): Check whether the card enforced CHV1.
(convert_sig_counter_value): New. Factor out code from
get_sig_counter.
* Makefile.am (card_support_source): Depend on new AM conditional
to get the ifdef ENABLE_CARD_SUPPORT off the way from source
copied files.
(update-source-from-gnupg-2): Maintainer helper.
2003-10-01 David Shaw <dshaw@jabberwocky.com> 2003-10-01 David Shaw <dshaw@jabberwocky.com>
* g10.c (main): Add --no-groups to zero --group list. * g10.c (main): Add --no-groups to zero --group list.

View File

@ -63,15 +63,22 @@ common_source = \
keylist.c \ keylist.c \
signal.c signal.c
card_support_source = \ if ENABLE_CARD_SUPPORT
cardglue.c cardclue.h \ card_support_source_g10 = card-util.c
card-util.c \ card_support_source_scd = \
app-common.h \ app-common.h \
app-openpgp.c \ app-openpgp.c \
iso7816.c iso7816.h \ iso7816.c iso7816.h \
apdu.c apdu.h \ apdu.c apdu.h \
ccid-driver.c ccid-driver.h ccid-driver.c ccid-driver.h
card_support_source_local = cardglue.c cardclue.h
else
card_support_source_g10 =
card_support_source_scd =
card_support_source_local =
endif
card_support_source = $(card_support_source_local) $(card_support_source_g10) $(card_support_source_scd)
gpg_SOURCES = g10.c \ gpg_SOURCES = g10.c \
$(common_source) \ $(common_source) \
@ -132,3 +139,15 @@ install-data-local:
echo "removing obsolete gpgm binary" ; \ echo "removing obsolete gpgm binary" ; \
rm $(DESTDIR)$(bindir)/gpgm ; \ rm $(DESTDIR)$(bindir)/gpgm ; \
fi fi
# Helper to update some source files.
update-source-from-gnupg-2:
test -d ../../gnupg-1.9/scd
@for i in $(card_support_source_scd); do \
cp ../../gnupg-1.9/scd/$$i $$i; echo $$i; \
done
@for i in $(card_support_source_g10); do \
cp ../../gnupg-1.9/g10/$$i $$i; echo $$i; \
done
@echo "Please remember to update the ChangeLog accordingly!"

View File

@ -19,13 +19,6 @@
*/ */
#include <config.h> #include <config.h>
#ifdef ENABLE_CARD_SUPPORT
/*
Note, that most of this code has been taken from 1.9.x branch
and is maintained over there if at all possible. Thus, if you make
changes here, please check that a similar change has been commited
to the 1.9.x branch.
*/
#include <errno.h> #include <errno.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -35,12 +28,19 @@
# include <opensc/opensc.h> # include <opensc/opensc.h>
#endif #endif
#if GNUPG_MAJOR_VERSION == 1
/* This is used with GnuPG version < 1.9. The code has been source
copied from the current GnuPG >= 1.9 and is maintained over
there. */
#include "options.h" #include "options.h"
#include "errors.h" #include "errors.h"
#include "memory.h" #include "memory.h"
#include "util.h" #include "util.h"
#include "i18n.h" #include "i18n.h"
#include "cardglue.h" #include "cardglue.h"
#else /* GNUPG_MAJOR_VERSION != 1 */
#include "scdaemon.h"
#endif /* GNUPG_MAJOR_VERSION != 1 */
#include "apdu.h" #include "apdu.h"
#include "dynload.h" #include "dynload.h"
@ -1190,4 +1190,4 @@ apdu_send_simple (int slot, int class, int ins, int p0, int p1,
#endif /*ENABLE_CARD_SUPPORT*/

View File

@ -1,4 +1,4 @@
/* app-common.h /* app-common.h - Common declarations for all card applications
* Copyright (C) 2003 Free Software Foundation, Inc. * Copyright (C) 2003 Free Software Foundation, Inc.
* *
* This file is part of GnuPG. * This file is part of GnuPG.
@ -18,8 +18,8 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#ifndef APP_COMMON_H #ifndef GNUPG_SCD_APP_COMMON_H
#define APP_COMMON_H #define GNUPG_SCD_APP_COMMON_H
struct app_ctx_s { struct app_ctx_s {
int initialized; /* The application has been initialied and the int initialized; /* The application has been initialied and the
@ -31,10 +31,12 @@ struct app_ctx_s {
size_t serialnolen; /* Length in octets of serialnumber. */ size_t serialnolen; /* Length in octets of serialnumber. */
unsigned int card_version; unsigned int card_version;
int did_chv1; int did_chv1;
int force_chv1; /* True if the card does not cache CHV1. */
int did_chv2; int did_chv2;
int did_chv3; int did_chv3;
struct { struct {
int (*learn_status) (APP app, CTRL ctrl); int (*learn_status) (APP app, CTRL ctrl);
int (*getattr) (APP app, CTRL ctrl, const char *name);
int (*setattr) (APP app, const char *name, int (*setattr) (APP app, const char *name,
int (*pincb)(void*, const char *, char **), int (*pincb)(void*, const char *, char **),
void *pincb_arg, void *pincb_arg,
@ -64,13 +66,73 @@ struct app_ctx_s {
int (*pincb)(void*, const char *, char **), int (*pincb)(void*, const char *, char **),
void *pincb_arg); void *pincb_arg);
} fnc; } fnc;
}; };
#if GNUPG_MAJOR_VERSION == 1
int app_select_openpgp (APP app, unsigned char **sn, size_t *snlen); int app_select_openpgp (APP app, unsigned char **sn, size_t *snlen);
int app_get_serial_and_stamp (APP app, char **serial, time_t *stamp); int app_get_serial_and_stamp (APP app, char **serial, time_t *stamp);
#else
/*-- app.c --*/
void app_set_default_reader_port (const char *portstr);
APP select_application (void);
int app_get_serial_and_stamp (APP app, char **serial, time_t *stamp);
int app_write_learn_status (APP app, CTRL ctrl);
int app_getattr (APP app, CTRL ctrl, const char *name);
int app_setattr (APP app, const char *name,
int (*pincb)(void*, const char *, char **),
void *pincb_arg,
const unsigned char *value, size_t valuelen);
int app_sign (APP app, const char *keyidstr, int hashalgo,
int (pincb)(void*, const char *, char **),
void *pincb_arg,
const void *indata, size_t indatalen,
unsigned char **outdata, size_t *outdatalen );
int app_auth (APP app, const char *keyidstr,
int (*pincb)(void*, const char *, char **),
void *pincb_arg,
const void *indata, size_t indatalen,
unsigned char **outdata, size_t *outdatalen);
int app_decipher (APP app, const char *keyidstr,
int (pincb)(void*, const char *, char **),
void *pincb_arg,
const void *indata, size_t indatalen,
unsigned char **outdata, size_t *outdatalen );
int app_genkey (APP app, CTRL ctrl, const char *keynostr, unsigned int flags,
int (*pincb)(void*, const char *, char **),
void *pincb_arg);
int app_get_challenge (APP app, size_t nbytes, unsigned char *buffer);
int app_change_pin (APP app, CTRL ctrl, const char *chvnostr, int reset_mode,
int (*pincb)(void*, const char *, char **),
void *pincb_arg);
#endif /*APP_COMMON_H*/
/*-- app-openpgp.c --*/
int app_select_openpgp (APP app, unsigned char **sn, size_t *snlen);
int app_openpgp_cardinfo (APP app,
char **serialno,
char **disp_name,
char **pubkey_url,
unsigned char **fpr1,
unsigned char **fpr2,
unsigned char **fpr3);
int app_openpgp_storekey (APP app, int keyno,
unsigned char *template, size_t template_len,
time_t created_at,
const unsigned char *m, size_t mlen,
const unsigned char *e, size_t elen,
int (*pincb)(void*, const char *, char **),
void *pincb_arg);
int app_openpgp_readkey (APP app, int keyno,
unsigned char **m, size_t *mlen,
unsigned char **e, size_t *elen);
#endif
#endif /*GNUPG_SCD_APP_COMMON_H*/

View File

@ -19,13 +19,6 @@
*/ */
#include <config.h> #include <config.h>
#ifdef ENABLE_CARD_SUPPORT
/*
Note, that most of this code has been taken from 1.9.x branch
and is maintained over there if at all possible. Thus, if you make
changes here, please check that a similar change has been commited
to the 1.9.x branch.
*/
#include <errno.h> #include <errno.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -33,16 +26,25 @@
#include <assert.h> #include <assert.h>
#include <time.h> #include <time.h>
#if GNUPG_MAJOR_VERSION == 1
/* This is used with GnuPG version < 1.9. The code has been source
copied from the current GnuPG >= 1.9 and is maintained over
there. */
#include "options.h" #include "options.h"
#include "errors.h" #include "errors.h"
#include "memory.h" #include "memory.h"
#include "util.h" #include "util.h"
#include "i18n.h" #include "i18n.h"
#include "cardglue.h"
#else /* GNUPG_MAJOR_VERSION != 1 */
#include "scdaemon.h"
#endif /* GNUPG_MAJOR_VERSION != 1 */
#include "iso7816.h" #include "iso7816.h"
#include "cardglue.h"
#include "app-common.h" #include "app-common.h"
static struct { static struct {
int tag; int tag;
int constructed; int constructed;
@ -73,10 +75,11 @@ static struct {
}; };
static unsigned long convert_sig_counter_value (const unsigned char *value,
size_t valuelen);
static unsigned long get_sig_counter (APP app); static unsigned long get_sig_counter (APP app);
/* Locate a TLV encoded data object in BUFFER of LENGTH and /* Locate a TLV encoded data object in BUFFER of LENGTH and
return a pointer to value as well as its length in NBYTES. Return return a pointer to value as well as its length in NBYTES. Return
NULL if it was not found. Note, that the function does not check NULL if it was not found. Note, that the function does not check
@ -403,83 +406,168 @@ send_key_data (CTRL ctrl, const char *name,
xfree (buf); xfree (buf);
} }
/* Implement the GETATTR command. This is similar to the LEARN
command but returns just one value via the status interface. */
static int
do_getattr (APP app, CTRL ctrl, const char *name)
{
static struct {
const char *name;
int tag;
int special;
} table[] = {
{ "DISP-NAME", 0x005B },
{ "LOGIN-DATA", 0x005E },
{ "DISP-LANG", 0x5F2D },
{ "DISP-SEX", 0x5F35 },
{ "PUBKEY-URL", 0x5F50 },
{ "KEY-FPR", 0x00C5, 3 },
{ "CA-FPR", 0x00C6, 3 },
{ "CHV-STATUS", 0x00C4, 1 },
{ "SIG-COUNTER", 0x0093, 2 },
{ NULL, 0 }
};
int idx, i;
void *relptr;
unsigned char *value;
size_t valuelen;
for (idx=0; table[idx].name && strcmp (table[idx].name, name); idx++)
;
if (!table[idx].name)
return gpg_error (GPG_ERR_INV_NAME);
relptr = get_one_do (app->slot, table[idx].tag, &value, &valuelen);
if (relptr)
{
if (table[idx].special == 1)
{
char numbuf[7*23];
for (i=0,*numbuf=0; i < valuelen && i < 7; i++)
sprintf (numbuf+strlen (numbuf), " %d", value[i]);
send_status_info (ctrl, table[idx].name,
numbuf, strlen (numbuf), NULL, 0);
}
else if (table[idx].special == 2)
{
char numbuf[50];
sprintf (numbuf, "%lu", convert_sig_counter_value (value, valuelen));
send_status_info (ctrl, table[idx].name,
numbuf, strlen (numbuf), NULL, 0);
}
else if (table[idx].special == 3)
{
if (valuelen >= 60)
for (i=0; i < 3; i++)
send_fpr_if_not_null (ctrl, "KEY-FPR", i+1, value+i*20);
}
else
send_status_info (ctrl, table[idx].name, value, valuelen, NULL, 0);
xfree (relptr);
}
return 0;
}
static int static int
do_learn_status (APP app, CTRL ctrl) do_learn_status (APP app, CTRL ctrl)
{ {
void *relptr; do_getattr (app, ctrl, "DISP-NAME");
unsigned char *value; do_getattr (app, ctrl, "DISP-LANG");
size_t valuelen; do_getattr (app, ctrl, "DISP-SEX");
int i; do_getattr (app, ctrl, "PUBKEY-URL");
do_getattr (app, ctrl, "LOGIN-DATA");
do_getattr (app, ctrl, "KEY-FPR");
do_getattr (app, ctrl, "CA-FPR");
do_getattr (app, ctrl, "CHV-STATUS");
do_getattr (app, ctrl, "SIG-COUNTER");
relptr = get_one_do (app->slot, 0x005B, &value, &valuelen);
if (relptr)
{
send_status_info (ctrl, "DISP-NAME", value, valuelen, NULL, 0);
xfree (relptr);
}
relptr = get_one_do (app->slot, 0x5F2D, &value, &valuelen);
if (relptr)
{
send_status_info (ctrl, "DISP-LANG", value, valuelen, NULL, 0);
xfree (relptr);
}
relptr = get_one_do (app->slot, 0x5F35, &value, &valuelen);
if (relptr)
{
send_status_info (ctrl, "DISP-SEX", value, valuelen, NULL, 0);
xfree (relptr);
}
relptr = get_one_do (app->slot, 0x5F50, &value, &valuelen);
if (relptr)
{
send_status_info (ctrl, "PUBKEY-URL", value, valuelen, NULL, 0);
xfree (relptr);
}
relptr = get_one_do (app->slot, 0x005E, &value, &valuelen);
if (relptr)
{
send_status_info (ctrl, "LOGIN-DATA", value, valuelen, NULL, 0);
xfree (relptr);
}
relptr = get_one_do (app->slot, 0x00C5, &value, &valuelen);
if (relptr && valuelen >= 60)
{
for (i=0; i < 3; i++)
send_fpr_if_not_null (ctrl, "KEY-FPR", i+1, value+i*20);
}
xfree (relptr);
relptr = get_one_do (app->slot, 0x00C6, &value, &valuelen);
if (relptr && valuelen >= 60)
{
for (i=0; i < 3; i++)
send_fpr_if_not_null (ctrl, "CA-FPR", i+1, value+i*20);
}
xfree (relptr);
relptr = get_one_do (app->slot, 0x00C4, &value, &valuelen);
if (relptr)
{
char numbuf[7*23];
for (i=0,*numbuf=0; i < valuelen && i < 7; i++)
sprintf (numbuf+strlen (numbuf), " %d", value[i]);
send_status_info (ctrl, "CHV-STATUS", numbuf, strlen (numbuf), NULL, 0);
xfree (relptr);
}
{
unsigned long ul = get_sig_counter (app);
char numbuf[23];
sprintf (numbuf, "%lu", ul);
send_status_info (ctrl, "SIG-COUNTER", numbuf, strlen (numbuf), NULL, 0);
}
return 0; return 0;
} }
/* Verify CHV2 if required. Depending on the configuration of the
card CHV1 will also be verified. */
static int
verify_chv2 (APP app,
int (*pincb)(void*, const char *, char **),
void *pincb_arg)
{
int rc = 0;
if (!app->did_chv2)
{
char *pinvalue;
rc = pincb (pincb_arg, "PIN", &pinvalue);
if (rc)
{
log_info ("PIN callback returned error: %s\n", gpg_strerror (rc));
return rc;
}
rc = iso7816_verify (app->slot, 0x82, pinvalue, strlen (pinvalue));
if (rc)
{
log_error ("verify CHV2 failed: %s\n", gpg_strerror (rc));
xfree (pinvalue);
return rc;
}
app->did_chv2 = 1;
if (!app->did_chv1 && !app->force_chv1)
{
rc = iso7816_verify (app->slot, 0x81, pinvalue, strlen (pinvalue));
if (gpg_err_code (rc) == GPG_ERR_BAD_PIN)
rc = gpg_error (GPG_ERR_PIN_NOT_SYNCED);
if (rc)
{
log_error ("verify CHV1 failed: %s\n", gpg_strerror (rc));
xfree (pinvalue);
return rc;
}
app->did_chv1 = 1;
}
xfree (pinvalue);
}
return rc;
}
/* Verify CHV3 if required. */
static int
verify_chv3 (APP app,
int (*pincb)(void*, const char *, char **),
void *pincb_arg)
{
int rc = 0;
if (!app->did_chv3)
{
char *pinvalue;
rc = pincb (pincb_arg, "Admin PIN", &pinvalue);
if (rc)
{
log_info ("PIN callback returned error: %s\n", gpg_strerror (rc));
return rc;
}
rc = iso7816_verify (app->slot, 0x83, pinvalue, strlen (pinvalue));
xfree (pinvalue);
if (rc)
{
log_error ("verify CHV3 failed: %s\n", gpg_strerror (rc));
return rc;
}
app->did_chv3 = 1;
}
return rc;
}
/* Handle the SETATTR operation. All arguments are already basically /* Handle the SETATTR operation. All arguments are already basically
checked. */ checked. */
static int static int
@ -512,41 +600,18 @@ do_setattr (APP app, const char *name,
if (!table[idx].name) if (!table[idx].name)
return gpg_error (GPG_ERR_INV_NAME); return gpg_error (GPG_ERR_INV_NAME);
if (!app->did_chv3) rc = verify_chv3 (app, pincb, pincb_arg);
{ if (rc)
char *pinvalue; return rc;
rc = pincb (pincb_arg, "Admin PIN (CHV3)",
&pinvalue);
/* pinvalue = xstrdup ("12345678"); */
/* rc = 0; */
if (rc)
{
log_info ("PIN callback returned error: %s\n", gpg_strerror (rc));
return rc;
}
rc = iso7816_verify (app->slot, 0x83, pinvalue, strlen (pinvalue));
xfree (pinvalue);
if (rc)
{
log_error ("verify CHV3 failed: %s\n", gpg_strerror (rc));
rc = gpg_error (GPG_ERR_GENERAL);
return rc;
}
app->did_chv3 = 1;
}
rc = iso7816_put_data (app->slot, table[idx].tag, value, valuelen); rc = iso7816_put_data (app->slot, table[idx].tag, value, valuelen);
if (rc) if (rc)
log_error ("failed to set `%s': %s\n", table[idx].name, gpg_strerror (rc)); log_error ("failed to set `%s': %s\n", table[idx].name, gpg_strerror (rc));
/* FIXME: If this fails we should *once* try again after
doing a verify command, so that in case of a problem with
tracking the verify operation we have a fallback. */
return rc; return rc;
} }
/* Handle the PASSWD command. */ /* Handle the PASSWD command. */
static int static int
do_change_pin (APP app, CTRL ctrl, const char *chvnostr, int reset_mode, do_change_pin (APP app, CTRL ctrl, const char *chvnostr, int reset_mode,
@ -564,51 +629,25 @@ do_change_pin (APP app, CTRL ctrl, const char *chvnostr, int reset_mode,
} }
else if (reset_mode || chvno == 3) else if (reset_mode || chvno == 3)
{ {
rc = pincb (pincb_arg, "Admin PIN", &pinvalue); /* we always require that the PIN is entered. */
app->did_chv3 = 0;
rc = verify_chv3 (app, pincb, pincb_arg);
if (rc) if (rc)
{ goto leave;
log_error ("error getting PIN: %s\n", gpg_strerror (rc));
goto leave;
}
rc = iso7816_verify (app->slot, 0x83, pinvalue, strlen (pinvalue));
xfree (pinvalue);
if (rc)
{
log_error ("verify CHV3 failed: rc=%s\n", gpg_strerror (rc));
goto leave;
}
} }
else if (chvno == 1) else if (chvno == 1 || chvno == 2)
{ {
rc = pincb (pincb_arg, "Signature PIN", &pinvalue); /* CHV1 and CVH2 should always have the same value, thus we
enforce it here. */
int save_force = app->force_chv1;
app->force_chv1 = 0;
app->did_chv1 = 0;
app->did_chv2 = 0;
rc = verify_chv2 (app, pincb, pincb_arg);
app->force_chv1 = save_force;
if (rc) if (rc)
{ goto leave;
log_error ("error getting PIN: %s\n", gpg_strerror (rc));
goto leave;
}
rc = iso7816_verify (app->slot, 0x81, pinvalue, strlen (pinvalue));
xfree (pinvalue);
if (rc)
{
log_error ("verify CHV1 failed: rc=%s\n", gpg_strerror (rc));
goto leave;
}
}
else if (chvno == 2)
{
rc = pincb (pincb_arg, "Decryption PIN", &pinvalue);
if (rc)
{
log_error ("error getting PIN: %s\n", gpg_strerror (rc));
goto leave;
}
rc = iso7816_verify (app->slot, 0x82, pinvalue, strlen (pinvalue));
xfree (pinvalue);
if (rc)
{
log_error ("verify CHV2 failed: rc=%s\n", gpg_strerror (rc));
goto leave;
}
} }
else else
{ {
@ -616,10 +655,12 @@ do_change_pin (APP app, CTRL ctrl, const char *chvnostr, int reset_mode,
goto leave; goto leave;
} }
if (chvno == 3)
rc = pincb (pincb_arg, chvno == 1? "New Signature PIN" : app->did_chv3 = 0;
chvno == 2? "New Decryption PIN" : else
chvno == 3? "New Admin PIN" : "?", &pinvalue); app->did_chv1 = app->did_chv2 = 0;
rc = pincb (pincb_arg, chvno == 3? "New Admin PIN" : "New PIN", &pinvalue);
if (rc) if (rc)
{ {
log_error ("error getting new PIN: %s\n", gpg_strerror (rc)); log_error ("error getting new PIN: %s\n", gpg_strerror (rc));
@ -627,12 +668,27 @@ do_change_pin (APP app, CTRL ctrl, const char *chvnostr, int reset_mode,
} }
if (reset_mode) if (reset_mode)
rc = iso7816_reset_retry_counter (app->slot, 0x80 + chvno, {
pinvalue, strlen (pinvalue)); rc = iso7816_reset_retry_counter (app->slot, 0x81,
else
rc = iso7816_change_reference_data (app->slot, 0x80 + chvno,
NULL, 0,
pinvalue, strlen (pinvalue)); pinvalue, strlen (pinvalue));
if (!rc)
rc = iso7816_reset_retry_counter (app->slot, 0x82,
pinvalue, strlen (pinvalue));
}
else
{
if (chvno == 1 || chvno == 2)
{
rc = iso7816_change_reference_data (app->slot, 0x81, NULL, 0,
pinvalue, strlen (pinvalue));
if (!rc)
rc = iso7816_change_reference_data (app->slot, 0x82, NULL, 0,
pinvalue, strlen (pinvalue));
}
else
rc = iso7816_change_reference_data (app->slot, 0x80 + chvno, NULL, 0,
pinvalue, strlen (pinvalue));
}
xfree (pinvalue); xfree (pinvalue);
@ -692,22 +748,10 @@ do_genkey (APP app, CTRL ctrl, const char *keynostr, unsigned int flags,
else else
log_info ("generating new key\n"); log_info ("generating new key\n");
{
char *pinvalue; rc = verify_chv3 (app, pincb, pincb_arg);
rc = pincb (pincb_arg, "Admin PIN", &pinvalue);
if (rc)
{
log_error ("error getting PIN: %s\n", gpg_strerror (rc));
return rc;
}
rc = iso7816_verify (app->slot, 0x83, pinvalue, strlen (pinvalue));
xfree (pinvalue);
}
if (rc) if (rc)
{ goto leave;
log_error ("verify CHV3 failed: rc=%s\n", gpg_strerror (rc));
goto leave;
}
xfree (buffer); buffer = NULL; xfree (buffer); buffer = NULL;
#if 1 #if 1
@ -777,6 +821,21 @@ do_genkey (APP app, CTRL ctrl, const char *keynostr, unsigned int flags,
} }
static unsigned long
convert_sig_counter_value (const unsigned char *value, size_t valuelen)
{
unsigned long ul;
if (valuelen == 3 )
ul = (value[0] << 16) | (value[1] << 8) | value[2];
else
{
log_error ("invalid structure of OpenPGP card (DO 0x93)\n");
ul = 0;
}
return ul;
}
static unsigned long static unsigned long
get_sig_counter (APP app) get_sig_counter (APP app)
{ {
@ -788,13 +847,7 @@ get_sig_counter (APP app)
relptr = get_one_do (app->slot, 0x0093, &value, &valuelen); relptr = get_one_do (app->slot, 0x0093, &value, &valuelen);
if (!relptr) if (!relptr)
return 0; return 0;
if (valuelen == 3 ) ul = convert_sig_counter_value (value, valuelen);
ul = (value[0] << 16) | (value[1] << 8) | value[2];
else
{
log_error ("invalid structure of OpenPGP card (DO 0x93)\n");
ul = 0;
}
xfree (relptr); xfree (relptr);
return ul; return ul;
} }
@ -927,21 +980,17 @@ do_sign (APP app, const char *keyidstr, int hashalgo,
sigcount = get_sig_counter (app); sigcount = get_sig_counter (app);
log_info ("signatures created so far: %lu\n", sigcount); log_info ("signatures created so far: %lu\n", sigcount);
/* FIXME: Check whether we are really required to enter the PIN for if (!app->did_chv1 || app->force_chv1 )
each signature. There is a DO for this. */
if (!app->did_chv1 || 1)
{ {
char *pinvalue; char *pinvalue;
{ {
char *prompt; char *prompt;
if (asprintf (&prompt, "Signature PIN [sigs done: %lu]", sigcount) < 0) if (asprintf (&prompt, "PIN [sigs done: %lu]", sigcount) < 0)
return gpg_error_from_errno (errno); return gpg_error_from_errno (errno);
rc = pincb (pincb_arg, prompt, &pinvalue); rc = pincb (pincb_arg, prompt, &pinvalue);
free (prompt); free (prompt);
} }
/* pinvalue = xstrdup ("123456"); */
/* rc = 0; */
if (rc) if (rc)
{ {
log_info ("PIN callback returned error: %s\n", gpg_strerror (rc)); log_info ("PIN callback returned error: %s\n", gpg_strerror (rc));
@ -949,14 +998,28 @@ do_sign (APP app, const char *keyidstr, int hashalgo,
} }
rc = iso7816_verify (app->slot, 0x81, pinvalue, strlen (pinvalue)); rc = iso7816_verify (app->slot, 0x81, pinvalue, strlen (pinvalue));
xfree (pinvalue);
if (rc) if (rc)
{ {
log_error ("verify CHV1 failed\n"); log_error ("verify CHV1 failed\n");
rc = gpg_error (GPG_ERR_GENERAL); xfree (pinvalue);
return rc; return rc;
} }
app->did_chv1 = 1; app->did_chv1 = 1;
if (!app->did_chv2)
{
/* We should also verify CHV2. */
rc = iso7816_verify (app->slot, 0x82, pinvalue, strlen (pinvalue));
if (gpg_err_code (rc) == GPG_ERR_BAD_PIN)
rc = gpg_error (GPG_ERR_PIN_NOT_SYNCED);
if (rc)
{
log_error ("verify CHV2 failed\n");
xfree (pinvalue);
return rc;
}
app->did_chv2 = 1;
}
xfree (pinvalue);
} }
rc = iso7816_compute_ds (app->slot, data, 35, outdata, outdatalen); rc = iso7816_compute_ds (app->slot, data, 35, outdata, outdatalen);
@ -1037,30 +1100,10 @@ do_auth (APP app, const char *keyidstr,
return rc; return rc;
} }
if (!app->did_chv2) rc = verify_chv2 (app, pincb, pincb_arg);
{ if (!rc)
char *pinvalue; rc = iso7816_internal_authenticate (app->slot, indata, indatalen,
outdata, outdatalen);
rc = pincb (pincb_arg, "Authentication/Decryption PIN", &pinvalue);
if (rc)
{
log_info ("PIN callback returned error: %s\n", gpg_strerror (rc));
return rc;
}
rc = iso7816_verify (app->slot, 0x82, pinvalue, strlen (pinvalue));
xfree (pinvalue);
if (rc)
{
log_error ("verify CHV2 failed\n");
rc = gpg_error (GPG_ERR_GENERAL);
return rc;
}
app->did_chv2 = 1;
}
rc = iso7816_internal_authenticate (app->slot, indata, indatalen,
outdata, outdatalen);
return rc; return rc;
} }
@ -1127,31 +1170,9 @@ do_decipher (APP app, const char *keyidstr,
return rc; return rc;
} }
if (!app->did_chv2) rc = verify_chv2 (app, pincb, pincb_arg);
{ if (!rc)
char *pinvalue; rc = iso7816_decipher (app->slot, indata, indatalen, outdata, outdatalen);
rc = pincb (pincb_arg, "Decryption PIN", &pinvalue);
/* pinvalue = xstrdup ("123456"); */
/* rc = 0; */
if (rc)
{
log_info ("PIN callback returned error: %s\n", gpg_strerror (rc));
return rc;
}
rc = iso7816_verify (app->slot, 0x82, pinvalue, strlen (pinvalue));
xfree (pinvalue);
if (rc)
{
log_error ("verify CHV2 failed\n");
rc = gpg_error (GPG_ERR_GENERAL);
return rc;
}
app->did_chv2 = 1;
}
rc = iso7816_decipher (app->slot, indata, indatalen, outdata, outdatalen);
return rc; return rc;
} }
@ -1168,10 +1189,15 @@ app_select_openpgp (APP app, unsigned char **sn, size_t *snlen)
int rc; int rc;
unsigned char *buffer; unsigned char *buffer;
size_t buflen; size_t buflen;
void *relptr;
rc = iso7816_select_application (slot, aid, sizeof aid); rc = iso7816_select_application (slot, aid, sizeof aid);
if (!rc) if (!rc)
{ {
app->did_chv1 = 0;
app->did_chv2 = 0;
app->did_chv3 = 0;
rc = iso7816_get_data (slot, 0x004F, &buffer, &buflen); rc = iso7816_get_data (slot, 0x004F, &buffer, &buflen);
if (rc) if (rc)
goto leave; goto leave;
@ -1191,10 +1217,20 @@ app_select_openpgp (APP app, unsigned char **sn, size_t *snlen)
else else
xfree (buffer); xfree (buffer);
relptr = get_one_do (app->slot, 0x00C4, &buffer, &buflen);
if (!relptr)
{
log_error ("can't access CHV Status Bytes - invalid OpenPGP card?\n");
goto leave;
}
app->force_chv1 = (buflen && *buffer == 0);
xfree (relptr);
if (opt.verbose > 1) if (opt.verbose > 1)
dump_all_do (slot); dump_all_do (slot);
app->fnc.learn_status = do_learn_status; app->fnc.learn_status = do_learn_status;
app->fnc.getattr = do_getattr;
app->fnc.setattr = do_setattr; app->fnc.setattr = do_setattr;
app->fnc.genkey = do_genkey; app->fnc.genkey = do_genkey;
app->fnc.sign = do_sign; app->fnc.sign = do_sign;
@ -1319,22 +1355,10 @@ app_openpgp_storekey (APP app, int keyno,
return gpg_error (GPG_ERR_INV_ID); return gpg_error (GPG_ERR_INV_ID);
keyno--; keyno--;
{ rc = verify_chv3 (app, pincb, pincb_arg);
char *pinvalue;
rc = pincb (pincb_arg, "Admin PIN", &pinvalue);
if (rc)
{
log_error ("error getting PIN: %s\n", gpg_strerror (rc));
return rc;
}
rc = iso7816_verify (app->slot, 0x83, pinvalue, strlen (pinvalue));
xfree (pinvalue);
}
if (rc) if (rc)
{ goto leave;
log_error ("verify CHV3 failed: rc=%s\n", gpg_strerror (rc));
goto leave;
}
rc = iso7816_put_data (app->slot, rc = iso7816_put_data (app->slot,
(app->card_version > 0x0007? 0xE0 : 0xE9) + keyno, (app->card_version > 0x0007? 0xE0 : 0xE9) + keyno,
@ -1426,5 +1450,3 @@ app_openpgp_readkey (APP app, int keyno, unsigned char **m, size_t *mlen,
} }
return rc; return rc;
} }
#endif /*ENABLE_CARD_SUPPORT*/

View File

@ -19,27 +19,26 @@
*/ */
#include <config.h> #include <config.h>
#ifdef ENABLE_CARD_SUPPORT
/*
Note, that most card related code has been taken from 1.9.x branch
and is maintained over there if at all possible. Thus, if you make
changes here, please check that a similar change has been commited
to the 1.9.x branch.
*/
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include <assert.h> #include <assert.h>
#if GNUPG_MAJOR_VERSION != 1
#include "gpg.h"
#endif
#include "util.h" #include "util.h"
#include "i18n.h" #include "i18n.h"
#include "ttyio.h" #include "ttyio.h"
#include "status.h" #include "status.h"
#include "options.h" #include "options.h"
#include "main.h" #include "main.h"
#if GNUPG_MAJOR_VERSION == 1
#include "cardglue.h" #include "cardglue.h"
#else
#include "call-agent.h"
#endif
#define CONTROL_D ('D' - 'A' + 1) #define CONTROL_D ('D' - 'A' + 1)
@ -51,7 +50,6 @@ change_pin (int chvno)
{ {
struct agent_card_info_s info; struct agent_card_info_s info;
int rc; int rc;
int reset_mode = 0;
rc = agent_learn (&info); rc = agent_learn (&info);
if (rc) if (rc)
@ -77,17 +75,11 @@ change_pin (int chvno)
char *answer; char *answer;
tty_printf ("\n"); tty_printf ("\n");
tty_printf ("1 - change signature PIN\n" tty_printf ("1 - change PIN\n"
"2 - change decryption and authentication PIN\n" "2 - unblock PIN\n"
"3 - change Admin's PIN\n" "3 - change Admin PIN\n"
"R - toggle reset retry counter mode\n"
"Q - quit\n"); "Q - quit\n");
tty_printf ("\n"); tty_printf ("\n");
if (reset_mode)
{
tty_printf ("Reset Retry Counter mode active\n");
tty_printf ("\n");
}
answer = cpr_get("cardutil.change_pin.menu",_("Your selection? ")); answer = cpr_get("cardutil.change_pin.menu",_("Your selection? "));
cpr_kill_prompt(); cpr_kill_prompt();
@ -95,30 +87,35 @@ change_pin (int chvno)
continue; continue;
rc = 0; rc = 0;
if (reset_mode && *answer == '3') if (*answer == '1')
{ {
tty_printf ("Sorry, reset of the Admin PIN's retry counter " rc = agent_scd_change_pin (1);
"is not possible.\n");
}
else if (*answer == '1' || *answer == '2' || *answer == '3')
{
rc = agent_scd_change_pin (*answer - '0' + (reset_mode?100:0));
if (rc) if (rc)
tty_printf ("Error changing/resetting the PIN: %s\n", tty_printf ("Error changing the PIN: %s\n", gpg_strerror (rc));
gpg_strerror (rc));
else else
tty_printf ("New PIN successfully set.\n"); tty_printf ("PIN changed.\n");
} }
else if (*answer == 'r' || *answer == 'R') else if (*answer == '2')
{ {
reset_mode = !reset_mode; rc = agent_scd_change_pin (101);
if (rc)
tty_printf ("Error unblocking the PIN: %s\n", gpg_strerror (rc));
else
tty_printf ("PIN unblocked and new PIN set.\n");
}
else if (*answer == '3')
{
rc = agent_scd_change_pin (3);
if (rc)
tty_printf ("Error changing the PIN: %s\n", gpg_strerror (rc));
else
tty_printf ("PIN changed.\n");
} }
else if (*answer == 'q' || *answer == 'Q') else if (*answer == 'q' || *answer == 'Q')
{ {
break; break;
} }
} }
} }
static const char * static const char *
@ -182,7 +179,7 @@ print_name (FILE *fp, const char *text, const char *name)
if (fp) if (fp)
print_utf8_string2 (fp, name, strlen (name), '\n'); print_utf8_string2 (fp, name, strlen (name), '\n');
else else
tty_print_utf8_string2 (name, strlen (name), '\n'); tty_print_utf8_string2 (name, strlen (name), 0);
} }
else else
tty_fprintf (fp, _("[not set]")); tty_fprintf (fp, _("[not set]"));
@ -214,7 +211,7 @@ print_isoname (FILE *fp, const char *text, const char *tag, const char *name)
else if (fp) else if (fp)
print_utf8_string2 (fp, given, strlen (given), '\n'); print_utf8_string2 (fp, given, strlen (given), '\n');
else else
tty_print_utf8_string2 (given, strlen (given), '\n'); tty_print_utf8_string2 (given, strlen (given), 0);
if (opt.with_colons) if (opt.with_colons)
putc (':', fp); putc (':', fp);
@ -227,7 +224,7 @@ print_isoname (FILE *fp, const char *text, const char *tag, const char *name)
else if (fp) else if (fp)
print_utf8_string2 (fp, buf, strlen (buf), '\n'); print_utf8_string2 (fp, buf, strlen (buf), '\n');
else else
tty_print_utf8_string2 (buf, strlen (buf), '\n'); tty_print_utf8_string2 (buf, strlen (buf), 0);
xfree (buf); xfree (buf);
} }
else else
@ -346,7 +343,7 @@ card_status (FILE *fp)
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);
tty_fprintf (fp, "Signature PIN ....: %s\n", tty_fprintf (fp, "Signature PIN ....: %s\n",
info.chv1_cached? _("cached"): _("not cached")); 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",
info.chvmaxlen[0], info.chvmaxlen[1], info.chvmaxlen[2]); info.chvmaxlen[0], info.chvmaxlen[1], info.chvmaxlen[2]);
tty_fprintf (fp, "PIN retry counter : %d %d %d\n", tty_fprintf (fp, "PIN retry counter : %d %d %d\n",
@ -358,11 +355,11 @@ card_status (FILE *fp)
print_sha1_fpr (fp, info.fpr2valid? info.fpr2:NULL); print_sha1_fpr (fp, info.fpr2valid? info.fpr2:NULL);
tty_fprintf (fp, "Authentication key:"); tty_fprintf (fp, "Authentication key:");
print_sha1_fpr (fp, info.fpr3valid? info.fpr3:NULL); print_sha1_fpr (fp, info.fpr3valid? info.fpr3:NULL);
/* tty_fprintf (fp, "General key info..: "); */ tty_fprintf (fp, "General key info..: ");
/* if (info.fpr1valid && !get_pubkey_byfprint (pk, info.fpr1, 20)) */ if (info.fpr1valid && !get_pubkey_byfprint (pk, info.fpr1, 20))
/* print_pubkey_info (fp, pk); */ print_pubkey_info (fp, pk);
/* else */ else
/* tty_fprintf (fp, "[none]\n"); */ tty_fprintf (fp, "[none]\n");
} }
free_public_key (pk); free_public_key (pk);
@ -549,6 +546,30 @@ change_sex (void)
} }
static void
toggle_forcesig (void)
{
struct agent_card_info_s info;
int rc;
int newstate;
memset (&info, 0, sizeof info);
rc = agent_scd_getattr ("CHV-STATUS", &info);
if (rc)
{
log_error ("error getting current status: %s\n", gpg_strerror (rc));
return;
}
newstate = !info.chv1_cached;
agent_release_card_info (&info);
rc = agent_scd_setattr ("CHV-STATUS-1", newstate? "\x01":"", 1);
if (rc)
log_error ("error toggling signature PIN flag: %s\n", gpg_strerror (rc));
}
/* Menu to edit all user changeable values on an OpenPGP card. Only /* Menu to edit all user changeable values on an OpenPGP card. Only
Key creation is not handled here. */ Key creation is not handled here. */
void void
@ -558,7 +579,7 @@ card_edit (STRLIST commands)
cmdNOP = 0, cmdNOP = 0,
cmdQUIT, cmdHELP, cmdLIST, cmdDEBUG, cmdQUIT, cmdHELP, cmdLIST, cmdDEBUG,
cmdNAME, cmdURL, cmdLOGIN, cmdLANG, cmdSEX, cmdNAME, cmdURL, cmdLOGIN, cmdLANG, cmdSEX,
cmdFORCESIG,
cmdINVCMD cmdINVCMD
}; };
@ -579,9 +600,10 @@ 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_("forcesig"), cmdFORCESIG, N_("toggle the signature force PIN flag") },
{ NULL, cmdINVCMD } { NULL, cmdINVCMD }
}; };
enum cmdids cmd = cmdNOP; enum cmdids cmd = cmdNOP;
int have_commands = !!commands; int have_commands = !!commands;
int redisplay = 1; int redisplay = 1;
@ -699,6 +721,10 @@ card_edit (STRLIST commands)
change_sex (); change_sex ();
break; break;
case cmdFORCESIG:
toggle_forcesig ();
break;
case cmdQUIT: case cmdQUIT:
goto leave; goto leave;
@ -717,4 +743,3 @@ card_edit (STRLIST commands)
xfree (answer); xfree (answer);
} }
#endif /*ENABLE_CARD_SUPPORT*/

View File

@ -19,13 +19,9 @@
*/ */
#include <config.h> #include <config.h>
#ifdef ENABLE_CARD_SUPPORT #ifndef ENABLE_CARD_SUPPORT
/* #error no configured for card support.
Note, that most card related code has been taken from 1.9.x branch #endif
and is maintained over there if at all possible. Thus, if you make
changes here, please check that a similar change has been commited
to the 1.9.x branch.
*/
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -357,14 +353,17 @@ learn_status_cb (void *opaque, const char *line)
if (keywordlen == 8 && !memcmp (keyword, "SERIALNO", keywordlen)) if (keywordlen == 8 && !memcmp (keyword, "SERIALNO", keywordlen))
{ {
xfree (parm->serialno);
parm->serialno = store_serialno (line); parm->serialno = store_serialno (line);
} }
else if (keywordlen == 9 && !memcmp (keyword, "DISP-NAME", keywordlen)) else if (keywordlen == 9 && !memcmp (keyword, "DISP-NAME", keywordlen))
{ {
xfree (parm->disp_name);
parm->disp_name = unescape_status_string (line); parm->disp_name = unescape_status_string (line);
} }
else if (keywordlen == 9 && !memcmp (keyword, "DISP-LANG", keywordlen)) else if (keywordlen == 9 && !memcmp (keyword, "DISP-LANG", keywordlen))
{ {
xfree (parm->disp_lang);
parm->disp_lang = unescape_status_string (line); parm->disp_lang = unescape_status_string (line);
} }
else if (keywordlen == 8 && !memcmp (keyword, "DISP-SEX", keywordlen)) else if (keywordlen == 8 && !memcmp (keyword, "DISP-SEX", keywordlen))
@ -373,10 +372,12 @@ learn_status_cb (void *opaque, const char *line)
} }
else if (keywordlen == 10 && !memcmp (keyword, "PUBKEY-URL", keywordlen)) else if (keywordlen == 10 && !memcmp (keyword, "PUBKEY-URL", keywordlen))
{ {
xfree (parm->pubkey_url);
parm->pubkey_url = unescape_status_string (line); parm->pubkey_url = unescape_status_string (line);
} }
else if (keywordlen == 10 && !memcmp (keyword, "LOGIN-DATA", keywordlen)) else if (keywordlen == 10 && !memcmp (keyword, "LOGIN-DATA", keywordlen))
{ {
xfree (parm->login_data);
parm->login_data = unescape_status_string (line); parm->login_data = unescape_status_string (line);
} }
else if (keywordlen == 11 && !memcmp (keyword, "SIG-COUNTER", keywordlen)) else if (keywordlen == 11 && !memcmp (keyword, "SIG-COUNTER", keywordlen))
@ -449,6 +450,7 @@ agent_learn (struct agent_card_info_s *info)
if (!app) if (!app)
return gpg_error (GPG_ERR_CARD); return gpg_error (GPG_ERR_CARD);
memset (info, 0, sizeof *info);
memset (&ctrl, 0, sizeof ctrl); memset (&ctrl, 0, sizeof ctrl);
ctrl.status_cb = learn_status_cb; ctrl.status_cb = learn_status_cb;
ctrl.status_cb_arg = info; ctrl.status_cb_arg = info;
@ -464,6 +466,24 @@ agent_learn (struct agent_card_info_s *info)
return rc; return rc;
} }
/* Get an attribite from the card. Make sure info is initialized. */
int
agent_scd_getattr (const char *name, struct agent_card_info_s *info)
{
APP app;
struct ctrl_ctx_s ctrl;
app = current_app? current_app : open_card ();
if (!app)
return gpg_error (GPG_ERR_CARD);
ctrl.status_cb = learn_status_cb;
ctrl.status_cb_arg = info;
return app->fnc.getattr (app, &ctrl, name);
}
static int static int
pin_cb (void *opaque, const char *info, char **retstr) pin_cb (void *opaque, const char *info, char **retstr)
{ {
@ -548,8 +568,3 @@ agent_scd_change_pin (int chvno)
return gpg_error (GPG_ERR_CARD); return gpg_error (GPG_ERR_CARD);
} }
#endif /*ENABLE_CARD_SUPPORT*/

View File

@ -84,7 +84,7 @@ typedef struct ctrl_ctx_s *CTRL;
#define GPG_ERR_USE_CONDITIONS G10ERR_GENERAL #define GPG_ERR_USE_CONDITIONS G10ERR_GENERAL
#define GPG_ERR_WRONG_CARD G10ERR_GENERAL #define GPG_ERR_WRONG_CARD G10ERR_GENERAL
#define GPG_ERR_WRONG_SECKEY G10ERR_WRONG_SECKEY #define GPG_ERR_WRONG_SECKEY G10ERR_WRONG_SECKEY
#define GPG_ERR_PIN_NOT_SYNCED G10ERR_GENERAL
typedef int gpg_error_t; typedef int gpg_error_t;
typedef int gpg_err_code_t; typedef int gpg_err_code_t;
@ -130,6 +130,9 @@ int agent_learn (struct agent_card_info_s *info);
is available. Return 0 for yes or an error code. */ is available. Return 0 for yes or an error code. */
int agent_havekey (const char *hexkeygrip); int agent_havekey (const char *hexkeygrip);
/* Return card info. */
int agent_scd_getattr (const char *name, struct agent_card_info_s *info);
/* Send a SETATTR command to the SCdaemon. */ /* Send a SETATTR command to the SCdaemon. */
int agent_scd_setattr (const char *name, int agent_scd_setattr (const char *name,
const unsigned char *value, size_t valuelen); const unsigned char *value, size_t valuelen);

View File

@ -74,8 +74,6 @@
#if defined(HAVE_LIBUSB) || defined(TEST) #if defined(HAVE_LIBUSB) || defined(TEST)
#define GNUPG_DEFAULT_SCDAEMON 1 /* Hack for 1.3 */
#include <errno.h> #include <errno.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -89,12 +87,16 @@
#define DRVNAME "ccid-driver: " #define DRVNAME "ccid-driver: "
#ifdef GNUPG_DEFAULT_SCDAEMON /* This source is used within the #ifdef GNUPG_MAJOR_VERSION /* This source is used within GnuPG. */
gnupg>=1.9 source tree. */
# include "options.h"
# include "util.h"
# include "memory.h"
# if GNUPG_MAJOR_VERSION == 1 /* GnuPG Version is < 1.9. */
# include "options.h"
# include "util.h"
# include "memory.h"
# include "cardglue.h"
# else /* This is the modularized GnuPG 1.9 or later. */
# include "scdaemon.h"
# endif
# define DEBUGOUT(t) do { if (DBG_CARD_IO) \ # define DEBUGOUT(t) do { if (DBG_CARD_IO) \
log_debug (DRVNAME t); } while (0) log_debug (DRVNAME t); } while (0)

View File

@ -130,7 +130,7 @@ do_delete_key( const char *username, int secret, int *r_sec_avail )
if( secret ) if( secret )
print_seckey_info( sk ); print_seckey_info( sk );
else else
print_pubkey_info( pk ); print_pubkey_info(NULL, pk );
tty_printf( "\n" ); tty_printf( "\n" );
yes = cpr_get_answer_is_yes( secret? "delete_key.secret.okay" yes = cpr_get_answer_is_yes( secret? "delete_key.secret.okay"

View File

@ -19,23 +19,23 @@
*/ */
#include <config.h> #include <config.h>
#ifdef ENABLE_CARD_SUPPORT
/*
Note, that most of this code has been taken from 1.9.x branch
and is maintained over there if at all possible. Thus, if you make
changes here, please check that a similar change has been commited
to the 1.9.x branch.
*/
#include <errno.h> #include <errno.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#if GNUPG_MAJOR_VERSION == 1
/* This is used with GnuPG version < 1.9. The code has been source
copied from the current GnuPG >= 1.9 and is maintained over
there. */
#include "options.h" #include "options.h"
#include "errors.h" #include "errors.h"
#include "memory.h" #include "memory.h"
#include "util.h" #include "util.h"
#include "i18n.h" #include "i18n.h"
#else /* GNUPG_MAJOR_VERSION != 1 */
#include "scdaemon.h"
#endif /* GNUPG_MAJOR_VERSION != 1 */
#include "iso7816.h" #include "iso7816.h"
#include "apdu.h" #include "apdu.h"
@ -381,5 +381,3 @@ iso7816_get_challenge (int slot, int length, unsigned char *buffer)
return 0; return 0;
} }
#endif /*ENABLE_CARD_SUPPORT*/

View File

@ -21,7 +21,9 @@
#ifndef ISO7816_H #ifndef ISO7816_H
#define ISO7816_H #define ISO7816_H
#if GNUPG_MAJOR_VERSION == 1
#include "cardglue.h" #include "cardglue.h"
#endif
gpg_error_t iso7816_select_application (int slot, gpg_error_t iso7816_select_application (int slot,
const char *aid, size_t aidlen); const char *aid, size_t aidlen);

View File

@ -129,25 +129,39 @@ print_seckey_info (PKT_secret_key *sk)
tty_printf ("\n"); tty_printf ("\n");
} }
/* Print information about the public key. With FP passed as NULL,
the tty output interface is used, otherwise output is directted to
the given stream. */
void void
print_pubkey_info (PKT_public_key *pk) print_pubkey_info (FILE *fp, PKT_public_key *pk)
{ {
u32 pk_keyid[2]; u32 pk_keyid[2];
size_t n; size_t n;
char *p; char *p;
keyid_from_pk (pk, pk_keyid); keyid_from_pk (pk, pk_keyid);
tty_printf ("\npub %4u%c/%08lX %s ", if (fp)
nbits_from_pk (pk), fprintf (fp, "pub %4u%c/%08lX %s ",
pubkey_letter (pk->pubkey_algo), nbits_from_pk (pk),
(ulong)pk_keyid[1], datestr_from_pk (pk)); pubkey_letter (pk->pubkey_algo),
(ulong)pk_keyid[1], datestr_from_pk (pk));
else
tty_printf ("\npub %4u%c/%08lX %s ",
nbits_from_pk (pk),
pubkey_letter (pk->pubkey_algo),
(ulong)pk_keyid[1], datestr_from_pk (pk));
p = get_user_id (pk_keyid, &n); p = get_user_id (pk_keyid, &n);
tty_print_utf8_string (p, n); if (fp)
print_utf8_string2 (fp, p, n, '\n');
else
tty_print_utf8_string (p, n);
m_free (p); m_free (p);
tty_printf ("\n\n"); if (fp)
putc ('\n', fp);
else
tty_printf ("\n\n");
} }
/* /*

View File

@ -217,7 +217,7 @@ void dump_attribs(const PKT_user_id *uid,
PKT_public_key *pk,PKT_secret_key *sk); PKT_public_key *pk,PKT_secret_key *sk);
void set_attrib_fd(int fd); void set_attrib_fd(int fd);
void print_seckey_info (PKT_secret_key *sk); void print_seckey_info (PKT_secret_key *sk);
void print_pubkey_info (PKT_public_key *pk); void print_pubkey_info (FILE *fp, PKT_public_key *pk);
/*-- verify.c --*/ /*-- verify.c --*/
void print_file_status( int status, const char *name, int what ); void print_file_status( int status, const char *name, int what );

View File

@ -264,7 +264,7 @@ gen_desig_revoke( const char *uname )
any = 1; any = 1;
print_pubkey_info (pk); print_pubkey_info (NULL, pk);
tty_printf ("\n"); tty_printf ("\n");
tty_printf (_("To be revoked by:\n")); tty_printf (_("To be revoked by:\n"));