diff options
author | Werner Koch <[email protected]> | 2010-09-01 09:48:35 +0000 |
---|---|---|
committer | Werner Koch <[email protected]> | 2010-09-01 09:48:35 +0000 |
commit | 9a9b3da58ff97397e89ca59ef79f86c03a2a9ad6 (patch) | |
tree | 36231916783c4f4f4fc8063015704ce1b3f18abe /g10 | |
parent | 2010-09-01 Marcus Brinkmann <[email protected]> (diff) | |
download | gnupg-9a9b3da58ff97397e89ca59ef79f86c03a2a9ad6.tar.gz gnupg-9a9b3da58ff97397e89ca59ef79f86c03a2a9ad6.zip |
Use passphrase caching for import and genkey.
Diffstat (limited to 'g10')
-rw-r--r-- | g10/ChangeLog | 10 | ||||
-rw-r--r-- | g10/call-agent.c | 52 | ||||
-rw-r--r-- | g10/call-agent.h | 4 | ||||
-rw-r--r-- | g10/import.c | 7 | ||||
-rw-r--r-- | g10/keygen.c | 41 |
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, ×tamp, @@ -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; |