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:
parent
5e6d360596
commit
6639bbf699
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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*/
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user