Even less prompts for a new key now.

This commit is contained in:
Werner Koch 2010-09-01 12:49:05 +00:00
parent 31bc3c8edd
commit a0b9ebfb7d
13 changed files with 107 additions and 53 deletions

View File

@ -13,6 +13,7 @@
* agent.h (CACHE_MODE_NONCE): New.
* pksign.c (agent_pksign_do, agent_pksign): Add arg CACHE_NONCE.
* findkey.c (agent_key_from_file): Ditto.
(unprotect): Implement it.
2010-08-31 Werner Koch <wk@g10code.com>

View File

@ -275,7 +275,7 @@ modify_description (const char *in, const char *comment, char **result)
description used for the pinentry. If LOOKUP_TTL is given this
function is used to lookup the default ttl. */
static int
unprotect (ctrl_t ctrl, const char *desc_text,
unprotect (ctrl_t ctrl, const char *cache_nonce, const char *desc_text,
unsigned char **keybuf, const unsigned char *grip,
cache_mode_t cache_mode, lookup_ttl_t lookup_ttl)
{
@ -288,6 +288,26 @@ unprotect (ctrl_t ctrl, const char *desc_text,
bin2hex (grip, 20, hexgrip);
/* Initially try to get it using a cache nonce. */
if (cache_nonce)
{
void *cache_marker;
const char *pw;
pw = agent_get_cache (cache_nonce, CACHE_MODE_NONCE, &cache_marker);
if (pw)
{
rc = agent_unprotect (*keybuf, pw, NULL, &result, &resultlen);
agent_unlock_cache_entry (&cache_marker);
if (!rc)
{
xfree (*keybuf);
*keybuf = result;
return 0;
}
}
}
/* First try to get it from the cache - if there is none or we can't
unprotect it, we fall back to ask the user */
if (cache_mode != CACHE_MODE_IGNORE)
@ -560,7 +580,7 @@ agent_key_from_file (ctrl_t ctrl, const char *cache_nonce,
if (!rc)
{
rc = unprotect (ctrl, desc_text_final, &buf, grip,
rc = unprotect (ctrl, cache_nonce, desc_text_final, &buf, grip,
cache_mode, lookup_ttl);
if (rc)
log_error ("failed to unprotect the secret key: %s\n",

View File

@ -1,12 +1,25 @@
2010-09-01 Werner Koch <wk@g10code.com>
* sign.c (do_sign, write_signature_packets, complete_sig): Add arg
CACHE_NONCE.
(make_keysig_packet): Ditto.
* keygen.c (make_backsig, write_direct_sig, write_selfsigs)
(write_keybinding): Add arg CACHE_NONCE.
(do_generate_keypair): Use cache_nonce to avoid a pinentry for the
self-signatures.
* passphrase.c (gpg_format_keydesc): Remove now superfluous
algo_name fallback.
* keygen.c (gen_elg, gen_dsa, gen_rsa, do_create, common_gen): Add
arg CACHE_NONCE_ADDR.
(generate_subkeypair): Pass NULL for CACHE_NONCE_ADDR.
(do_generate_keypair): Add cache nonce handling.
* import.c (transfer_secret_keys): Support a cache nonce.
* call-agent.c (cache_nonce_status_cb): New.
(agent_genkey, agent_import_key): Add arg CACHE_NONCE_ADDR.
(agent_pksign): Ditto.
2010-08-30 Werner Koch <wk@g10code.com>

View File

@ -1549,9 +1549,11 @@ agent_genkey (ctrl_t ctrl, char **cache_nonce_addr,
the hex string KEYGRIP. DESC is a description of the key to be
displayed if the agent needs to ask for the PIN. DIGEST and
DIGESTLEN is the hash value to sign and DIGESTALGO the algorithm id
used to compute the digest. */
used to compute the digest. If CACHE_NONCE is used the agent is
advised to firts try a passphrase associated with that nonce. */
gpg_error_t
agent_pksign (ctrl_t ctrl, const char *keygrip, const char *desc,
agent_pksign (ctrl_t ctrl, const char *cache_nonce,
const char *keygrip, const char *desc,
unsigned char *digest, size_t digestlen, int digestalgo,
gcry_sexp_t *r_sigval)
{
@ -1598,7 +1600,11 @@ agent_pksign (ctrl_t ctrl, const char *keygrip, const char *desc,
return err;
init_membuf (&data, 1024);
err = assuan_transact (agent_ctx, "PKSIGN",
snprintf (line, sizeof line, "PKSIGN%s%s",
cache_nonce? " -- ":"",
cache_nonce? cache_nonce:"");
err = assuan_transact (agent_ctx, line,
membuf_data_cb, &data, default_inq_cb, ctrl,
NULL, NULL);
if (err)

View File

@ -154,7 +154,8 @@ gpg_error_t agent_genkey (ctrl_t ctrl, char **cache_nonce_addr,
gcry_sexp_t *r_pubkey);
/* Create a signature. */
gpg_error_t agent_pksign (ctrl_t ctrl, const char *hexkeygrip, const char *desc,
gpg_error_t agent_pksign (ctrl_t ctrl, const char *cache_nonce,
const char *hexkeygrip, const char *desc,
unsigned char *digest, size_t digestlen,
int digestalgo,
gcry_sexp_t *r_sigval);

View File

@ -1243,7 +1243,10 @@ transfer_secret_keys (ctrl_t ctrl, kbnode_t sec_keyblock)
size_t uidlen;
u32 keyid[2];
char *orig_codeset;
/* FIXME: We should use gpg_format_keydesc, however that
requires a public key structure. It might be useful to
merge the secret and public key structures. */
keyid_from_sk (sk, keyid);
uid = get_user_id (keyid, &uidlen);
orig_codeset = i18n_switchto_utf8 ();

View File

@ -1083,7 +1083,8 @@ sign_uids (KBNODE keyblock, strlist_t locusr, int *ret_modified,
NULL,
pk,
0x13, 0, force_v4 ? 4 : 0, 0, 0,
keygen_add_std_prefs, primary_pk);
keygen_add_std_prefs, primary_pk,
NULL);
else
rc = make_keysig_packet (&sig, primary_pk,
node->pkt->pkt.user_id,
@ -1091,7 +1092,8 @@ sign_uids (KBNODE keyblock, strlist_t locusr, int *ret_modified,
pk,
class, 0, force_v4 ? 4 : 0,
timestamp, duration,
sign_mk_attrib, &attrib);
sign_mk_attrib, &attrib,
NULL);
if (rc)
{
log_error (_("signing failed: %s\n"), g10_errstr (rc));
@ -3222,7 +3224,7 @@ menu_adduid (KBNODE pub_keyblock, int photo, const char *photo_name)
return 0;
err = make_keysig_packet (&sig, pk, uid, NULL, pk, 0x13, 0, 0, 0, 0,
keygen_add_std_prefs, pk);
keygen_add_std_prefs, pk, NULL);
if (err)
{
log_error ("signing failed: %s\n", g10_errstr (err));
@ -3610,7 +3612,7 @@ menu_addrevoker (KBNODE pub_keyblock, int sensitive)
/* The 1F signature must be at least v4 to carry the revocation key
subpacket. */
rc = make_keysig_packet (&sig, pk, NULL, NULL, pk, 0x1F, 0, 4, 0, 0,
keygen_add_revkey, &revkey);
keygen_add_revkey, &revkey, NULL);
if (rc)
{
log_error ("signing failed: %s\n", g10_errstr (rc));
@ -3810,7 +3812,7 @@ menu_backsign (KBNODE pub_keyblock)
/* Now we can get to work. */
rc = make_backsig (sig_pk->pkt->pkt.signature, main_pk, sub_pk, sub_pk,
timestamp);
timestamp, NULL);
if (!rc)
{
PKT_signature *newsig;
@ -4901,7 +4903,7 @@ reloop: /* (must use this, because we are modifing the list) */
rc = make_keysig_packet (&sig, primary_pk,
unode->pkt->pkt.user_id,
NULL, signerkey, 0x30, 0, 0, 0, 0,
sign_mk_attrib, &attrib);
sign_mk_attrib, &attrib, NULL);
free_public_key (signerkey);
if (rc)
{
@ -4993,7 +4995,7 @@ menu_revuid (KBNODE pub_keyblock)
rc = make_keysig_packet (&sig, pk, uid, NULL, pk, 0x30, 0,
(reason == NULL) ? 3 : 0, timestamp, 0,
sign_mk_attrib, &attrib);
sign_mk_attrib, &attrib, NULL);
if (rc)
{
log_error (_("signing failed: %s\n"), g10_errstr (rc));
@ -5055,7 +5057,7 @@ menu_revkey (KBNODE pub_keyblock)
rc = make_keysig_packet (&sig, pk, NULL, NULL, pk,
0x20, 0, opt.force_v4_certs ? 4 : 0, 0, 0,
revocation_reason_build_cb, reason);
revocation_reason_build_cb, reason, NULL);
if (rc)
{
log_error (_("signing failed: %s\n"), g10_errstr (rc));
@ -5115,7 +5117,8 @@ menu_revsubkey (KBNODE pub_keyblock)
node->flag &= ~NODFLG_SELKEY;
rc = make_keysig_packet (&sig, mainpk, NULL, subpk, mainpk,
0x28, 0, 0, 0, 0, sign_mk_attrib, &attrib);
0x28, 0, 0, 0, 0, sign_mk_attrib, &attrib,
NULL);
if (rc)
{
log_error (_("signing failed: %s\n"), g10_errstr (rc));

View File

@ -824,7 +824,7 @@ keygen_add_revkey (PKT_signature *sig, void *opaque)
gpg_error_t
make_backsig (PKT_signature *sig, PKT_public_key *pk,
PKT_public_key *sub_pk, PKT_public_key *sub_psk,
u32 timestamp)
u32 timestamp, const char *cache_nonce)
{
gpg_error_t err;
PKT_signature *backsig;
@ -832,7 +832,7 @@ make_backsig (PKT_signature *sig, PKT_public_key *pk,
cache_public_key (sub_pk);
err = make_keysig_packet (&backsig, pk, NULL, sub_pk, sub_psk, 0x19,
0, 0, timestamp, 0, NULL, NULL);
0, 0, timestamp, 0, NULL, NULL, cache_nonce);
if (err)
log_error ("make_keysig_packet failed for backsig: %s\n", g10_errstr(err));
else
@ -918,7 +918,8 @@ make_backsig (PKT_signature *sig, PKT_public_key *pk,
the timestamp to set on the signature. */
static gpg_error_t
write_direct_sig (KBNODE root, PKT_public_key *psk,
struct revocation_key *revkey, u32 timestamp)
struct revocation_key *revkey, u32 timestamp,
const char *cache_nonce)
{
gpg_error_t err;
PACKET *pkt;
@ -942,7 +943,7 @@ write_direct_sig (KBNODE root, PKT_public_key *psk,
/* Make the signature. */
err = make_keysig_packet (&sig, pk, NULL,NULL, psk, 0x1F,
0, 0, timestamp, 0,
keygen_add_revkey, revkey);
keygen_add_revkey, revkey, cache_nonce);
if (err)
{
log_error ("make_keysig_packet failed: %s\n", g10_errstr (err) );
@ -963,7 +964,7 @@ write_direct_sig (KBNODE root, PKT_public_key *psk,
signature. */
static gpg_error_t
write_selfsigs (KBNODE root, PKT_public_key *psk,
unsigned int use, u32 timestamp)
unsigned int use, u32 timestamp, const char *cache_nonce)
{
gpg_error_t err;
PACKET *pkt;
@ -997,7 +998,7 @@ write_selfsigs (KBNODE root, PKT_public_key *psk,
/* Make the signature. */
err = make_keysig_packet (&sig, pk, uid, NULL, psk, 0x13,
0, 0, timestamp, 0,
keygen_add_std_prefs, pk);
keygen_add_std_prefs, pk, cache_nonce);
if (err)
{
log_error ("make_keysig_packet failed: %s\n", g10_errstr (err));
@ -1019,7 +1020,7 @@ write_selfsigs (KBNODE root, PKT_public_key *psk,
used if USE has the PUBKEY_USAGE_SIG capability. */
static int
write_keybinding (KBNODE root, PKT_public_key *pri_psk, PKT_public_key *sub_psk,
unsigned int use, u32 timestamp)
unsigned int use, u32 timestamp, const char *cache_nonce)
{
gpg_error_t err;
PACKET *pkt;
@ -1056,7 +1057,8 @@ write_keybinding (KBNODE root, PKT_public_key *pri_psk, PKT_public_key *sub_psk,
oduap.pk = sub_pk;
err = make_keysig_packet (&sig, pri_pk, NULL, sub_pk, pri_psk, 0x18,
0, 0, timestamp, 0,
keygen_add_key_flags_and_expire, &oduap);
keygen_add_key_flags_and_expire, &oduap,
cache_nonce);
if (err)
{
log_error ("make_keysig_packet failed: %s\n", g10_errstr (err));
@ -1066,7 +1068,7 @@ write_keybinding (KBNODE root, PKT_public_key *pri_psk, PKT_public_key *sub_psk,
/* Make a backsig. */
if (use & PUBKEY_USAGE_SIG)
{
err = make_backsig (sig, pri_pk, sub_pk, sub_psk, timestamp);
err = make_backsig (sig, pri_pk, sub_pk, sub_psk, timestamp, cache_nonce);
if (err)
return err;
}
@ -3254,13 +3256,14 @@ do_generate_keypair (struct para_data_s *para,
}
if (!err && (revkey = get_parameter_revkey (para, pREVOKER)))
err = write_direct_sig (pub_root, pri_psk, revkey, timestamp);
err = write_direct_sig (pub_root, pri_psk, revkey, timestamp, cache_nonce);
if (!err && (s = get_parameter_value (para, pUSERID)))
{
write_uid (pub_root, s );
err = write_selfsigs (pub_root, pri_psk,
get_parameter_uint (para, pKEYUSAGE), timestamp);
get_parameter_uint (para, pKEYUSAGE), timestamp,
cache_nonce);
}
/* Write the auth key to the card before the encryption key. This
@ -3277,7 +3280,7 @@ do_generate_keypair (struct para_data_s *para,
get_parameter_u32 (para, pKEYEXPIRE), para);
if (!err)
err = write_keybinding (pub_root, pri_psk, NULL,
PUBKEY_USAGE_AUTH, timestamp);
PUBKEY_USAGE_AUTH, timestamp, cache_nonce);
}
if (!err && get_parameter (para, pSUBKEYTYPE))
@ -3327,7 +3330,7 @@ do_generate_keypair (struct para_data_s *para,
if (!err)
err = write_keybinding (pub_root, pri_psk, sub_psk,
get_parameter_uint (para, pSUBKEYUSAGE),
timestamp);
timestamp, cache_nonce);
did_sub = 1;
}
@ -3526,7 +3529,7 @@ generate_subkeypair (KBNODE keyblock)
sub_psk = node->pkt->pkt.public_key;
/* Write the binding signature. */
err = write_keybinding (keyblock, pri_psk, sub_psk, use, cur_time);
err = write_keybinding (keyblock, pri_psk, sub_psk, use, cur_time, NULL);
if (err)
goto leave;

View File

@ -201,7 +201,8 @@ int encrypt_filter (void *opaque, int control,
/*-- sign.c --*/
int complete_sig (PKT_signature *sig, PKT_public_key *pksk, gcry_md_hd_t md);
int complete_sig (PKT_signature *sig, PKT_public_key *pksk, gcry_md_hd_t md,
const char *cache_nonce);
int sign_file( strlist_t filenames, int detached, strlist_t locusr,
int do_encrypt, strlist_t remusr, const char *outfile );
int clearsign_file( const char *fname, strlist_t locusr, const char *outfile );
@ -241,7 +242,7 @@ int keygen_add_notations(PKT_signature *sig,void *opaque);
int keygen_add_revkey(PKT_signature *sig, void *opaque);
gpg_error_t make_backsig (PKT_signature *sig, PKT_public_key *pk,
PKT_public_key *sub_pk, PKT_public_key *sub_psk,
u32 timestamp);
u32 timestamp, const char *cache_nonce);
gpg_error_t generate_subkeypair (kbnode_t pub_keyblock);
#ifdef ENABLE_CARD_SUPPORT
int generate_card_subkeypair (KBNODE pub_keyblock, KBNODE sec_keyblock,

View File

@ -502,7 +502,8 @@ int make_keysig_packet( PKT_signature **ret_sig, PKT_public_key *pk,
PKT_public_key *pksk, int sigclass, int digest_algo,
int sigversion, u32 timestamp, u32 duration,
int (*mksubpkt)(PKT_signature *, void *),
void *opaque );
void *opaque,
const char *cache_nonce);
int update_keysig_packet( PKT_signature **ret_sig,
PKT_signature *orig_sig,
PKT_public_key *pk,

View File

@ -700,8 +700,6 @@ gpg_format_keydesc (PKT_public_key *pk, int escaped)
char *desc;
algo_name = gcry_pk_algo_name (pk->pubkey_algo);
if (!algo_name)
algo_name = "?";
timestr = strtimestamp (pk->timestamp);
uid = get_user_id (pk->keyid, &uidlen);

View File

@ -339,7 +339,8 @@ gen_desig_revoke( const char *uname, strlist_t locusr )
/* create it */
rc = make_keysig_packet( &sig, pk, NULL, NULL, pk2, 0x20, 0,
0, 0, 0,
revocation_reason_build_cb, reason );
revocation_reason_build_cb, reason,
NULL);
if( rc ) {
log_error(_("make_keysig_packet failed: %s\n"), g10_errstr(rc));
goto leave;
@ -525,7 +526,7 @@ gen_revoke (const char *uname)
/* create it */
rc = make_keysig_packet (&sig, psk, NULL, NULL, psk, 0x20, 0,
opt.force_v4_certs?4:0, 0, 0,
revocation_reason_build_cb, reason );
revocation_reason_build_cb, reason, NULL);
if (rc)
{
log_error (_("make_keysig_packet failed: %s\n"), g10_errstr (rc));

View File

@ -242,10 +242,11 @@ mpi_from_sexp (gcry_sexp_t sexp, const char * item)
return data;
}
/* Perform the sign operation. If CACHE_NONCE is given the agent is
advised to use that cached passphrase fro the key. */
static int
do_sign (PKT_public_key *pksk, PKT_signature *sig,
gcry_md_hd_t md, int mdalgo)
gcry_md_hd_t md, int mdalgo, const char *cache_nonce)
{
gpg_error_t err;
gcry_mpi_t frame;
@ -314,7 +315,7 @@ do_sign (PKT_public_key *pksk, PKT_signature *sig,
gcry_sexp_t s_sigval;
desc = gpg_format_keydesc (pksk, 1);
err = agent_pksign (NULL/*ctrl*/, hexgrip, desc,
err = agent_pksign (NULL/*ctrl*/, cache_nonce, hexgrip, desc,
dp, gcry_md_get_algo_dlen (mdalgo), mdalgo,
&s_sigval);
xfree (desc);
@ -378,12 +379,13 @@ do_sign (PKT_public_key *pksk, PKT_signature *sig,
int
complete_sig (PKT_signature *sig, PKT_public_key *pksk, gcry_md_hd_t md)
complete_sig (PKT_signature *sig, PKT_public_key *pksk, gcry_md_hd_t md,
const char *cache_nonce)
{
int rc;
/* if (!(rc = check_secret_key (pksk, 0))) */
rc = do_sign (pksk, sig, md, 0);
rc = do_sign (pksk, sig, md, 0, cache_nonce);
return rc;
}
@ -675,7 +677,7 @@ write_plaintext_packet (IOBUF out, IOBUF inp, const char *fname, int ptmode)
static int
write_signature_packets (SK_LIST sk_list, IOBUF out, gcry_md_hd_t hash,
int sigclass, u32 timestamp, u32 duration,
int status_letter)
int status_letter, const char *cache_nonce)
{
SK_LIST sk_rover;
@ -722,7 +724,7 @@ write_signature_packets (SK_LIST sk_list, IOBUF out, gcry_md_hd_t hash,
hash_sigversion_to_magic (md, sig);
gcry_md_final (md);
rc = do_sign (pk, sig, md, hash_for (pk));
rc = do_sign (pk, sig, md, hash_for (pk), cache_nonce);
gcry_md_close (md);
if (!rc)
{
@ -1070,7 +1072,7 @@ sign_file( strlist_t filenames, int detached, strlist_t locusr,
/* write the signatures */
rc = write_signature_packets (sk_list, out, mfx.md,
opt.textmode && !outfile? 0x01 : 0x00,
0, duration, detached ? 'D':'S');
0, duration, detached ? 'D':'S', NULL);
if( rc )
goto leave;
@ -1234,8 +1236,9 @@ clearsign_file( const char *fname, strlist_t locusr, const char *outfile )
afx->what = 2;
push_armor_filter (afx, out);
/* write the signatures */
rc=write_signature_packets (sk_list, out, textmd, 0x01, 0, duration, 'C');
/* Write the signatures. */
rc = write_signature_packets (sk_list, out, textmd, 0x01, 0, duration, 'C',
NULL);
if( rc )
goto leave;
@ -1401,7 +1404,7 @@ sign_symencrypt_file (const char *fname, strlist_t locusr)
/*(current filters: zip - encrypt - armor)*/
rc = write_signature_packets (sk_list, out, mfx.md,
opt.textmode? 0x01 : 0x00,
0, duration, 'S');
0, duration, 'S', NULL);
if( rc )
goto leave;
@ -1439,8 +1442,8 @@ make_keysig_packet( PKT_signature **ret_sig, PKT_public_key *pk,
PKT_public_key *pksk,
int sigclass, int digest_algo,
int sigversion, u32 timestamp, u32 duration,
int (*mksubpkt)(PKT_signature *, void *), void *opaque
)
int (*mksubpkt)(PKT_signature *, void *), void *opaque,
const char *cache_nonce)
{
PKT_signature *sig;
int rc=0;
@ -1533,7 +1536,7 @@ make_keysig_packet( PKT_signature **ret_sig, PKT_public_key *pk,
hash_sigversion_to_magic (md, sig);
gcry_md_final (md);
rc = complete_sig (sig, pksk, md);
rc = complete_sig (sig, pksk, md, cache_nonce);
}
gcry_md_close (md);
@ -1562,7 +1565,7 @@ update_keysig_packet( PKT_signature **ret_sig,
PKT_public_key *subpk,
PKT_public_key *pksk,
int (*mksubpkt)(PKT_signature *, void *),
void *opaque )
void *opaque)
{
PKT_signature *sig;
int rc=0;
@ -1619,7 +1622,7 @@ update_keysig_packet( PKT_signature **ret_sig,
hash_sigversion_to_magic (md, sig);
gcry_md_final (md);
rc = complete_sig (sig, pksk, md);
rc = complete_sig (sig, pksk, md, NULL);
}
gcry_md_close (md);