1
0
Fork 0
mirror of git://git.gnupg.org/gnupg.git synced 2025-07-03 22:56:33 +02:00

* passphrase.c (agent_get_passphrase): Add new arg CACHEID.

Changed all callers.
(ask_passphrase): Add new arg CACHEID and use it in agent mode.
Changed all callers.
(passphrase_clear_cache): New arg CACHEID.  Changed all callers.
* cardglue.c (format_cacheid): New.
(pin_cb): Compute a cache ID.
(agent_scd_pksign, agent_scd_pkdecrypt): Use it.
(agent_clear_pin_cache): New.
* card-util.c (change_pin): Clear the PIN cache.
(check_pin_for_key_operation): Ditto.
This commit is contained in:
Werner Koch 2005-05-03 22:27:07 +00:00
parent 5e6d360596
commit 6639bbf699
8 changed files with 174 additions and 34 deletions

View file

@ -43,12 +43,19 @@
#include "apdu.h"
#include "app-common.h"
struct ctrl_ctx_s {
struct ctrl_ctx_s
{
int (*status_cb)(void *opaque, const char *line);
void *status_cb_arg;
};
struct pincb_parm_s
{
const char *sn;
};
static char *default_reader_port;
static APP current_app;
@ -334,6 +341,39 @@ card_close (void)
}
/* Format a cache ID from the serialnumber in SN and return it as an
allocated string. In case of an error NULL is returned. */
static char *
format_cacheid (const char *sn)
{
const char *s;
size_t snlen;
char *cacheid = NULL;
/* The serialnumber we use for a card is "CARDSN:serialno". Where
serialno is the BCD string (i.e. hex string) with the full
number. The serial number expect here constsis of hexdigits
followed by other characters, we cut off these other
characters. */
if (sn)
{
for (s=sn,snlen=0; hexdigitp (s); s++, snlen++)
;
if (snlen == 32)
{
/* Yes, this looks indeed like an OpenPGP card S/N. */
cacheid = xtrymalloc (7+snlen+1);
if (cacheid)
{
memcpy (cacheid, "CARDSN:", 7);
memcpy (cacheid+7, sn, snlen);
cacheid[7+snlen] = 0;
}
}
}
return cacheid;
}
/* Check that the serial number of the current card (as described by
APP) matches SERIALNO. If there is no match and we are not in
batch mode, present a prompt to insert the desired card. The
@ -651,12 +691,14 @@ agent_scd_getattr (const char *name, struct agent_card_info_s *info)
static int
pin_cb (void *opaque, const char *info, char **retstr)
{
struct pincb_parm_s *parm = opaque;
char *value;
int canceled;
int isadmin = 0;
int newpin = 0;
const char *again_text = NULL;
const char *ends, *s;
char *cacheid = NULL;
*retstr = NULL;
/* log_debug ("asking for PIN '%s'\n", info); */
@ -674,9 +716,23 @@ pin_cb (void *opaque, const char *info, char **retstr)
}
info = ends+1;
}
else
else if (info && *info == '|')
log_debug ("pin_cb called without proper PIN info hack\n");
/* If we are not requesting a new PIN and we are not requesting an
AdminPIN, compute a string to be used as the cacheID for
gpg-agent. */
if (!newpin && !isadmin && parm)
{
cacheid = format_cacheid (parm->sn);
}
else if (newpin && parm)
{
/* Make really sure that it is not cached anymore. */
agent_clear_pin_cache (parm->sn);
}
again:
if (is_status_enabled())
write_status_text (STATUS_NEED_PASSPHRASE_PIN,
@ -691,7 +747,10 @@ pin_cb (void *opaque, const char *info, char **retstr)
newpin? _("Enter New PIN: ") :
isadmin? _("Enter Admin PIN: ")
: _("Enter PIN: "),
cacheid,
&canceled);
xfree (cacheid);
cacheid = NULL;
again_text = NULL;
if (!value && canceled)
return -1;
@ -702,7 +761,7 @@ pin_cb (void *opaque, const char *info, char **retstr)
{
char *value2;
value2 = ask_passphrase (info, NULL,
value2 = ask_passphrase (info, NULL, NULL,
"passphrase.pin.repeat",
_("Repeat this PIN: "),
&canceled);
@ -837,11 +896,14 @@ agent_scd_pksign (const char *serialno, int hashalgo,
const unsigned char *indata, size_t indatalen,
unsigned char **r_buf, size_t *r_buflen)
{
struct pincb_parm_s parm;
APP app;
int rc;
*r_buf = NULL;
*r_buflen = 0;
memset (&parm, 0, sizeof parm);
parm.sn = serialno;
retry:
app = current_app? current_app : open_card ();
if (!app)
@ -854,11 +916,14 @@ agent_scd_pksign (const char *serialno, int hashalgo,
if (!rc)
rc = app->fnc.sign (app, serialno, hashalgo,
pin_cb, NULL,
pin_cb, &parm,
indata, indatalen,
r_buf, r_buflen);
if (rc)
write_status (STATUS_SC_OP_FAILURE);
{
write_status (STATUS_SC_OP_FAILURE);
agent_clear_pin_cache (serialno);
}
return rc;
}
@ -869,11 +934,14 @@ agent_scd_pkdecrypt (const char *serialno,
const unsigned char *indata, size_t indatalen,
unsigned char **r_buf, size_t *r_buflen)
{
struct pincb_parm_s parm;
APP app;
int rc;
*r_buf = NULL;
*r_buflen = 0;
memset (&parm, 0, sizeof parm);
parm.sn = serialno;
retry:
app = current_app? current_app : open_card ();
if (!app)
@ -886,11 +954,14 @@ agent_scd_pkdecrypt (const char *serialno,
if (!rc)
rc = app->fnc.decipher (app, serialno,
pin_cb, NULL,
pin_cb, &parm,
indata, indatalen,
r_buf, r_buflen);
if (rc)
write_status (STATUS_SC_OP_FAILURE);
{
write_status (STATUS_SC_OP_FAILURE);
agent_clear_pin_cache (serialno);
}
return rc;
}
@ -960,3 +1031,15 @@ agent_openpgp_storekey (int keyno,
write_status (STATUS_SC_OP_FAILURE);
return rc;
}
void
agent_clear_pin_cache (const char *sn)
{
char *cacheid = format_cacheid (sn);
if (cacheid)
{
passphrase_clear_cache (NULL, cacheid, 0);
xfree (cacheid);
}
}