1
0
mirror of git://git.gnupg.org/gnupg.git synced 2025-03-24 22:09:57 +01: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

@ -1,3 +1,17 @@
2005-05-03 Werner Koch <wk@g10code.com>
* 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.
2005-04-24 David Shaw <dshaw@jabberwocky.com>
* trustdb.h, trustdb.c (mark_usable_uid_certs): Add flags for the
@ -24,6 +38,11 @@
here. We'll fail quite happily later, and usually with a better
error message to boot.
2005-04-20 Werner Koch <wk@g10code.com>
* sign.c (sign_file, sign_symencrypt_file): Allow for hash
debugging.
2005-04-16 David Shaw <dshaw@jabberwocky.com>
* keyserver.c (keyserver_spawn): Free some memory.

View File

@ -67,6 +67,8 @@ change_pin (int chvno, int allow_admin)
log_info (_("OpenPGP card no. %s detected\n"),
info.serialno? info.serialno : "[none]");
agent_clear_pin_cache (info.serialno);
agent_release_card_info (&info);
if (opt.batch)
@ -950,6 +952,8 @@ check_pin_for_key_operation (struct agent_card_info_s *info, int *forced_chv1)
{
int rc = 0;
agent_clear_pin_cache (info->serialno);
*forced_chv1 = !info->chv1_cached;
if (*forced_chv1)
{ /* Switch of the forced mode so that during key generation we

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);
}
}

View File

@ -194,6 +194,10 @@ int agent_openpgp_storekey (int keyno,
const unsigned char *m, size_t mlen,
const unsigned char *e, size_t elen);
/* Clear a cached PIN. */
void agent_clear_pin_cache (const char *sn);
#endif /*ENABLE_CARD_SUPPORT*/
#endif /*GNUPG_G10_CARDGLUE_H*/

View File

@ -186,11 +186,12 @@ int build_sk_list( STRLIST locusr, SK_LIST *ret_sk_list,
/*-- passphrase.h --*/
int have_static_passphrase(void);
void read_passphrase_from_fd( int fd );
void passphrase_clear_cache ( u32 *keyid, int algo );
void passphrase_clear_cache ( u32 *keyid, const char *cacheid, int algo );
char *ask_passphrase (const char *description,
const char *tryagain_text,
const char *promptid,
const char *prompt, int *canceled);
const char *prompt,
const char *cacheid, int *canceled);
DEK *passphrase_to_dek( u32 *keyid, int pubkey_algo,
int cipher_algo, STRING2KEY *s2k, int mode,
const char *tryagain_text, int *canceled);

View File

@ -425,10 +425,13 @@ agent_okay_cb (void *opaque, const char *line)
*
* Note that TRYAGAIN_TEXT must not be translated. If canceled is not
* NULL, the function does set it to 1 if the user canceled the
* operation.
* operation. If CACHEID is not NULL, it will be used as the cacheID
* for the gpg-agent; if is NULL and a key fingerprint can be
* computed, this will be used as the cacheid.
*/
static char *
agent_get_passphrase ( u32 *keyid, int mode, const char *tryagain_text,
agent_get_passphrase ( u32 *keyid, int mode, const char *cacheid,
const char *tryagain_text,
const char *custom_description,
const char *custom_prompt, int *canceled)
{
@ -545,11 +548,16 @@ agent_get_passphrase ( u32 *keyid, int mode, const char *tryagain_text,
line = xmalloc (15 + 46
+ 3*strlen (atext)
+ 3*strlen (custom_prompt? custom_prompt:"")
+ (cacheid? (3*strlen (cacheid)): 0)
+ 3*strlen (tryagain_text)
+ 1);
strcpy (line, "GET_PASSPHRASE ");
p = line+15;
if (!mode && have_fpr)
if (!mode && cacheid)
{
p = percent_plus_escape (p, cacheid);
}
else if (!mode && have_fpr)
{
for (i=0; i < 20; i++, p +=2 )
sprintf (p, "%02X", fpr[i]);
@ -629,10 +637,11 @@ agent_get_passphrase ( u32 *keyid, int mode, const char *tryagain_text,
/*
* Clear the cached passphrase
* Clear the cached passphrase. If CACHEID is not NULL, it will be
* used instead of a cache ID derived from KEYID.
*/
void
passphrase_clear_cache ( u32 *keyid, int algo )
passphrase_clear_cache ( u32 *keyid, const char *cacheid, int algo )
{
#ifdef ENABLE_AGENT_SUPPORT
assuan_context_t ctx = NULL;
@ -646,17 +655,22 @@ passphrase_clear_cache ( u32 *keyid, int algo )
if (!opt.use_agent)
return;
pk = xcalloc (1, sizeof *pk);
memset (fpr, 0, MAX_FINGERPRINT_LEN );
if( !keyid || get_pubkey( pk, keyid ) )
if (!cacheid)
{
goto failure; /* oops: no key for some reason */
}
pk = xcalloc (1, sizeof *pk);
memset (fpr, 0, MAX_FINGERPRINT_LEN );
if( !keyid || get_pubkey( pk, keyid ) )
{
goto failure; /* oops: no key for some reason */
}
{
size_t dummy;
fingerprint_from_pk( pk, fpr, &dummy );
}
{
size_t dummy;
fingerprint_from_pk( pk, fpr, &dummy );
}
}
else
pk = NULL;
if ( !(ctx = agent_open ()) )
goto failure;
@ -665,11 +679,21 @@ passphrase_clear_cache ( u32 *keyid, int algo )
char *line, *p;
int i, rc;
line = xmalloc (17 + 40 + 2);
strcpy (line, "CLEAR_PASSPHRASE ");
p = line+17;
for (i=0; i < 20; i++, p +=2 )
sprintf (p, "%02X", fpr[i]);
if (cacheid)
{
line = xmalloc (17 + 3*strlen (cacheid) + 2);
strcpy (line, "CLEAR_PASSPHRASE ");
p = line+17;
p = percent_plus_escape (p, cacheid);
}
else
{
line = xmalloc (17 + 40 + 2);
strcpy (line, "CLEAR_PASSPHRASE ");
p = line+17;
for (i=0; i < 20; i++, p +=2 )
sprintf (p, "%02X", fpr[i]);
}
*p = 0;
rc = assuan_transact (ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
@ -696,7 +720,8 @@ char *
ask_passphrase (const char *description,
const char *tryagain_text,
const char *promptid,
const char *prompt, int *canceled)
const char *prompt,
const char *cacheid, int *canceled)
{
char *pw = NULL;
@ -709,7 +734,7 @@ ask_passphrase (const char *description,
agent_died:
if ( opt.use_agent )
{
pw = agent_get_passphrase (NULL, 0,
pw = agent_get_passphrase (NULL, 0, cacheid,
tryagain_text, description, prompt,
canceled );
if (!pw)
@ -853,7 +878,7 @@ passphrase_to_dek( u32 *keyid, int pubkey_algo,
}
else if ( opt.use_agent ) {
/* Divert to the gpg-agent. */
pw = agent_get_passphrase ( keyid, mode == 2? 1: 0,
pw = agent_get_passphrase ( keyid, mode == 2? 1: 0, NULL,
tryagain_text, NULL, NULL, canceled );
if (!pw)
{
@ -862,7 +887,7 @@ passphrase_to_dek( u32 *keyid, int pubkey_algo,
pw = m_strdup ("");
}
if( *pw && mode == 2 ) {
char *pw2 = agent_get_passphrase ( keyid, 2, NULL, NULL,
char *pw2 = agent_get_passphrase ( keyid, 2, NULL, NULL, NULL,
NULL, canceled );
if (!pw2)
{

View File

@ -203,7 +203,7 @@ do_check( PKT_secret_key *sk, const char *tryagain_text, int mode,
/* now let's see whether we have used the right passphrase */
if( csum != sk->csum ) {
copy_secret_key( sk, save_sk );
passphrase_clear_cache ( keyid, sk->pubkey_algo );
passphrase_clear_cache ( keyid, NULL, sk->pubkey_algo );
free_secret_key( save_sk );
return G10ERR_BAD_PASS;
}
@ -211,7 +211,7 @@ do_check( PKT_secret_key *sk, const char *tryagain_text, int mode,
res = pubkey_check_secret_key( sk->pubkey_algo, sk->skey );
if( res ) {
copy_secret_key( sk, save_sk );
passphrase_clear_cache ( keyid, sk->pubkey_algo );
passphrase_clear_cache ( keyid, NULL, sk->pubkey_algo );
free_secret_key( save_sk );
return G10ERR_BAD_PASS;
}

View File

@ -808,6 +808,8 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr,
}
mfx.md = md_open(0, 0);
if (DBG_HASHING)
md_start_debug (mfx.md, "sign");
/* If we're encrypting and signing, it is reasonable to pick the
hash algorithm to use out of the recepient key prefs. */
@ -1217,6 +1219,8 @@ sign_symencrypt_file (const char *fname, STRLIST locusr)
if (opt.textmode)
iobuf_push_filter (inp, text_filter, &tfx);
mfx.md = md_open(0, 0);
if ( DBG_HASHING )
md_start_debug (mfx.md, "symc-sign");
for (sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next) {
PKT_secret_key *sk = sk_rover->sk;