aboutsummaryrefslogtreecommitdiffstats
path: root/g10
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2010-09-01 09:48:35 +0000
committerWerner Koch <[email protected]>2010-09-01 09:48:35 +0000
commit9a9b3da58ff97397e89ca59ef79f86c03a2a9ad6 (patch)
tree36231916783c4f4f4fc8063015704ce1b3f18abe /g10
parent2010-09-01 Marcus Brinkmann <[email protected]> (diff)
downloadgnupg-9a9b3da58ff97397e89ca59ef79f86c03a2a9ad6.tar.gz
gnupg-9a9b3da58ff97397e89ca59ef79f86c03a2a9ad6.zip
Use passphrase caching for import and genkey.
Diffstat (limited to 'g10')
-rw-r--r--g10/ChangeLog10
-rw-r--r--g10/call-agent.c52
-rw-r--r--g10/call-agent.h4
-rw-r--r--g10/import.c7
-rw-r--r--g10/keygen.c41
5 files changed, 88 insertions, 26 deletions
diff --git a/g10/ChangeLog b/g10/ChangeLog
index abfa6f7af..ce97e1671 100644
--- a/g10/ChangeLog
+++ b/g10/ChangeLog
@@ -1,3 +1,13 @@
+2010-09-01 Werner Koch <[email protected]>
+
+ * 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.
+
2010-08-30 Werner Koch <[email protected]>
* keyid.c (KEYID_STR_SIZE): New
diff --git a/g10/call-agent.c b/g10/call-agent.c
index 7f98cfba9..2ffa28b69 100644
--- a/g10/call-agent.c
+++ b/g10/call-agent.c
@@ -1392,6 +1392,32 @@ agent_get_keyinfo (ctrl_t ctrl, const char *hexkeygrip, char **r_serialno)
return err;
}
+
+/* Status callback for agent_import_key and agent_genkey. */
+static gpg_error_t
+cache_nonce_status_cb (void *opaque, const char *line)
+{
+ char **cache_nonce = opaque;
+ const char *keyword = line;
+ int keywordlen;
+
+ for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
+ ;
+ while (spacep (line))
+ line++;
+
+ if (keywordlen == 11 && !memcmp (keyword, "CACHE_NONCE", keywordlen))
+ {
+ if (cache_nonce)
+ {
+ xfree (*cache_nonce);
+ *cache_nonce = xtrystrdup (line);
+ }
+ }
+
+ return 0;
+}
+
/* Handle a KEYPARMS inquiry. Note, we only send the data,
@@ -1418,13 +1444,15 @@ inq_genkey_parms (void *opaque, const char *line)
S-expression giving the parameters of the key. gpg-agent passes it
gcry_pk_genkey. */
gpg_error_t
-agent_genkey (ctrl_t ctrl, const char *keyparms, gcry_sexp_t *r_pubkey)
+agent_genkey (ctrl_t ctrl, char **cache_nonce_addr,
+ const char *keyparms, gcry_sexp_t *r_pubkey)
{
gpg_error_t err;
struct genkey_parm_s gk_parm;
membuf_t data;
size_t len;
unsigned char *buf;
+ char line[ASSUAN_LINELENGTH];
*r_pubkey = NULL;
err = start_agent (ctrl, 0);
@@ -1440,9 +1468,13 @@ agent_genkey (ctrl_t ctrl, const char *keyparms, gcry_sexp_t *r_pubkey)
gk_parm.ctrl = ctrl;
gk_parm.ctx = agent_ctx;
gk_parm.keyparms = keyparms;
- err = assuan_transact (agent_ctx, "GENKEY",
+ snprintf (line, sizeof line, "GENKEY%s%s",
+ cache_nonce_addr && *cache_nonce_addr? " ":"",
+ cache_nonce_addr && *cache_nonce_addr? *cache_nonce_addr:"");
+ err = assuan_transact (agent_ctx, line,
membuf_data_cb, &data,
- inq_genkey_parms, &gk_parm, NULL, NULL);
+ inq_genkey_parms, &gk_parm,
+ cache_nonce_status_cb, cache_nonce_addr);
if (err)
{
xfree (get_membuf (&data, &len));
@@ -1775,10 +1807,12 @@ inq_import_key_parms (void *opaque, const char *line)
/* Call the agent to import a key into the agent. */
gpg_error_t
-agent_import_key (ctrl_t ctrl, const char *desc, const void *key, size_t keylen)
+agent_import_key (ctrl_t ctrl, const char *desc, char **cache_nonce_addr,
+ const void *key, size_t keylen)
{
gpg_error_t err;
struct import_key_parm_s parm;
+ char line[ASSUAN_LINELENGTH];
err = start_agent (ctrl, 0);
if (err)
@@ -1786,8 +1820,6 @@ agent_import_key (ctrl_t ctrl, const char *desc, const void *key, size_t keylen)
if (desc)
{
- char line[ASSUAN_LINELENGTH];
-
snprintf (line, DIM(line)-1, "SETKEYDESC %s", desc);
line[DIM(line)-1] = 0;
err = assuan_transact (agent_ctx, line,
@@ -1801,8 +1833,12 @@ agent_import_key (ctrl_t ctrl, const char *desc, const void *key, size_t keylen)
parm.key = key;
parm.keylen = keylen;
- err = assuan_transact (agent_ctx, "IMPORT_KEY",
- NULL, NULL, inq_import_key_parms, &parm, NULL, NULL);
+ snprintf (line, sizeof line, "IMPORT_KEY%s%s",
+ cache_nonce_addr && *cache_nonce_addr? " ":"",
+ cache_nonce_addr && *cache_nonce_addr? *cache_nonce_addr:"");
+ err = assuan_transact (agent_ctx, line,
+ NULL, NULL, inq_import_key_parms, &parm,
+ cache_nonce_status_cb, cache_nonce_addr);
return err;
}
diff --git a/g10/call-agent.h b/g10/call-agent.h
index 7495b2ac6..c0611ed2b 100644
--- a/g10/call-agent.h
+++ b/g10/call-agent.h
@@ -149,7 +149,8 @@ gpg_error_t agent_get_keyinfo (ctrl_t ctrl, const char *hexkeygrip,
char **r_serialno);
/* Generate a new key. */
-gpg_error_t agent_genkey (ctrl_t ctrl, const char *keyparms,
+gpg_error_t agent_genkey (ctrl_t ctrl, char **cache_nonce_addr,
+ const char *keyparms,
gcry_sexp_t *r_pubkey);
/* Create a signature. */
@@ -169,6 +170,7 @@ gpg_error_t agent_keywrap_key (ctrl_t ctrl, int forexport,
/* Send a key to the agent. */
gpg_error_t agent_import_key (ctrl_t ctrl, const char *desc,
+ char **cache_nonce_addr,
const void *key, size_t keylen);
diff --git a/g10/import.c b/g10/import.c
index 13773da25..2e0b2fee2 100644
--- a/g10/import.c
+++ b/g10/import.c
@@ -1105,6 +1105,7 @@ transfer_secret_keys (ctrl_t ctrl, kbnode_t sec_keyblock)
gcry_cipher_hd_t cipherhd = NULL;
unsigned char *wrappedkey = NULL;
size_t wrappedkeylen;
+ char *cache_nonce = NULL;
/* Get the current KEK. */
err = agent_keywrap_key (ctrl, 0, &kek, &keklen);
@@ -1266,7 +1267,8 @@ transfer_secret_keys (ctrl_t ctrl, kbnode_t sec_keyblock)
xfree (desc);
desc = uid;
}
- err = agent_import_key (ctrl, desc, wrappedkey, wrappedkeylen);
+ err = agent_import_key (ctrl, desc, &cache_nonce,
+ wrappedkey, wrappedkeylen);
xfree (desc);
}
if (!err)
@@ -1305,6 +1307,7 @@ transfer_secret_keys (ctrl_t ctrl, kbnode_t sec_keyblock)
}
leave:
+ xfree (cache_nonce);
xfree (wrappedkey);
xfree (transferkey);
gcry_cipher_close (cipherhd);
@@ -1409,7 +1412,7 @@ import_secret_one (ctrl_t ctrl, const char *fname, KBNODE keyblock,
pubkey_letter (sk->pubkey_algo),
keystr_from_sk (sk), datestr_from_sk (sk));
if (uidnode)
- print_utf8_buffer (es_stderr, uidnode->pkt->pkt.user_id->name,
+ print_utf8_buffer (log_get_stream (), uidnode->pkt->pkt.user_id->name,
uidnode->pkt->pkt.user_id->len);
log_printf ("\n");
}
diff --git a/g10/keygen.c b/g10/keygen.c
index 1be92db06..0f4fb96ef 100644
--- a/g10/keygen.c
+++ b/g10/keygen.c
@@ -1134,14 +1134,15 @@ key_from_sexp (gcry_mpi_t *array, gcry_sexp_t sexp,
/* Common code for the key generation fucntion gen_xxx. */
static int
common_gen (const char *keyparms, int algo, const char *algoelem,
- kbnode_t pub_root, u32 timestamp, u32 expireval, int is_subkey)
+ kbnode_t pub_root, u32 timestamp, u32 expireval, int is_subkey,
+ char **cache_nonce_addr)
{
int err;
PACKET *pkt;
PKT_public_key *pk;
gcry_sexp_t s_key;
- err = agent_genkey (NULL, keyparms, &s_key);
+ err = agent_genkey (NULL, cache_nonce_addr, keyparms, &s_key);
if (err)
{
log_error ("agent_genkey failed: %s\n", gpg_strerror (err) );
@@ -1193,7 +1194,7 @@ common_gen (const char *keyparms, int algo, const char *algoelem,
*/
static int
gen_elg (int algo, unsigned int nbits, KBNODE pub_root,
- u32 timestamp, u32 expireval, int is_subkey)
+ u32 timestamp, u32 expireval, int is_subkey, char **cache_nonce_addr)
{
int err;
char *keyparms;
@@ -1223,7 +1224,8 @@ gen_elg (int algo, unsigned int nbits, KBNODE pub_root,
else
{
err = common_gen (keyparms, algo, "pgy",
- pub_root, timestamp, expireval, is_subkey);
+ pub_root, timestamp, expireval, is_subkey,
+ cache_nonce_addr);
xfree (keyparms);
}
@@ -1236,7 +1238,7 @@ gen_elg (int algo, unsigned int nbits, KBNODE pub_root,
*/
static gpg_error_t
gen_dsa (unsigned int nbits, KBNODE pub_root,
- u32 timestamp, u32 expireval, int is_subkey)
+ u32 timestamp, u32 expireval, int is_subkey, char **cache_nonce_addr)
{
int err;
unsigned int qbits;
@@ -1305,7 +1307,8 @@ gen_dsa (unsigned int nbits, KBNODE pub_root,
else
{
err = common_gen (keyparms, PUBKEY_ALGO_DSA, "pqgy",
- pub_root, timestamp, expireval, is_subkey);
+ pub_root, timestamp, expireval, is_subkey,
+ cache_nonce_addr);
xfree (keyparms);
}
@@ -1318,7 +1321,7 @@ gen_dsa (unsigned int nbits, KBNODE pub_root,
*/
static int
gen_rsa (int algo, unsigned int nbits, KBNODE pub_root,
- u32 timestamp, u32 expireval, int is_subkey)
+ u32 timestamp, u32 expireval, int is_subkey, char **cache_nonce_addr)
{
int err;
char *keyparms;
@@ -1349,7 +1352,8 @@ gen_rsa (int algo, unsigned int nbits, KBNODE pub_root,
else
{
err = common_gen (keyparms, algo, "ne",
- pub_root, timestamp, expireval, is_subkey);
+ pub_root, timestamp, expireval, is_subkey,
+ cache_nonce_addr);
xfree (keyparms);
}
@@ -2146,7 +2150,8 @@ do_ask_passphrase (STRING2KEY **ret_s2k, int mode, int *r_canceled)
routines based on the requested algorithm. */
static int
do_create (int algo, unsigned int nbits, KBNODE pub_root,
- u32 timestamp, u32 expiredate, int is_subkey )
+ u32 timestamp, u32 expiredate, int is_subkey,
+ char **cache_nonce_addr)
{
gpg_error_t err;
@@ -2160,11 +2165,14 @@ do_create (int algo, unsigned int nbits, KBNODE pub_root,
"generator a better chance to gain enough entropy.\n") );
if (algo == PUBKEY_ALGO_ELGAMAL_E)
- err = gen_elg (algo, nbits, pub_root, timestamp, expiredate, is_subkey);
+ err = gen_elg (algo, nbits, pub_root, timestamp, expiredate, is_subkey,
+ cache_nonce_addr);
else if (algo == PUBKEY_ALGO_DSA)
- err = gen_dsa (nbits, pub_root, timestamp, expiredate, is_subkey);
+ err = gen_dsa (nbits, pub_root, timestamp, expiredate, is_subkey,
+ cache_nonce_addr);
else if (algo == PUBKEY_ALGO_RSA)
- err = gen_rsa (algo, nbits, pub_root, timestamp, expiredate, is_subkey);
+ err = gen_rsa (algo, nbits, pub_root, timestamp, expiredate, is_subkey,
+ cache_nonce_addr);
else
BUG();
@@ -3161,6 +3169,7 @@ do_generate_keypair (struct para_data_s *para,
struct revocation_key *revkey;
int did_sub = 0;
u32 timestamp;
+ char *cache_nonce = NULL;
if (outctrl->dryrun)
{
@@ -3231,7 +3240,7 @@ do_generate_keypair (struct para_data_s *para,
get_parameter_uint( para, pKEYLENGTH ),
pub_root,
timestamp,
- get_parameter_u32( para, pKEYEXPIRE ), 0 );
+ get_parameter_u32( para, pKEYEXPIRE ), 0, &cache_nonce);
else
err = gen_card_key (PUBKEY_ALGO_RSA, 1, 1, pub_root,
&timestamp,
@@ -3280,7 +3289,8 @@ do_generate_keypair (struct para_data_s *para,
get_parameter_uint (para, pSUBKEYLENGTH),
pub_root,
timestamp,
- get_parameter_u32 (para, pSUBKEYEXPIRE), 1 );
+ get_parameter_u32 (para, pSUBKEYEXPIRE), 1,
+ &cache_nonce);
/* Get the pointer to the generated public subkey packet. */
if (!err)
{
@@ -3410,6 +3420,7 @@ do_generate_keypair (struct para_data_s *para,
}
release_kbnode (pub_root);
+ xfree (cache_nonce);
}
@@ -3505,7 +3516,7 @@ generate_subkeypair (KBNODE keyblock)
goto leave;
}
- err = do_create (algo, nbits, keyblock, cur_time, expire, 1);
+ err = do_create (algo, nbits, keyblock, cur_time, expire, 1, NULL);
if (err)
goto leave;