Merge secret keys during import

This commit is contained in:
Werner Koch 2010-09-02 15:11:51 +00:00
parent 90a4599c5e
commit daab9aff3a
3 changed files with 25 additions and 28 deletions

2
NEWS
View File

@ -41,6 +41,8 @@ Noteworthy changes in version 2.1.x (under development)
operations to gpg-agent. The import command moves secret keys to operations to gpg-agent. The import command moves secret keys to
the agent. the agent.
* The OpenPGP import command is now able to merge secret keys.
Noteworthy changes in version 2.0.13 (2009-09-04) Noteworthy changes in version 2.0.13 (2009-09-04)
------------------------------------------------- -------------------------------------------------

View File

@ -1,3 +1,8 @@
2010-09-02 Werner Koch <wk@g10code.com>
* import.c (transfer_secret_keys, import_secret_one): Enable stats.
(import_secret_one): Enable secret key merging.
2010-09-01 Werner Koch <wk@g10code.com> 2010-09-01 Werner Koch <wk@g10code.com>
* sign.c (do_sign, write_signature_packets, complete_sig): Add arg * sign.c (do_sign, write_signature_packets, complete_sig): Add arg

View File

@ -112,7 +112,8 @@ parse_import_options(char *str,unsigned int *options,int noisy)
{"import-unusable-sigs",0,NULL,NULL}, {"import-unusable-sigs",0,NULL,NULL},
{"import-clean-sigs",0,NULL,NULL}, {"import-clean-sigs",0,NULL,NULL},
{"import-clean-uids",0,NULL,NULL}, {"import-clean-uids",0,NULL,NULL},
{"convert-sk-to-pk",0, NULL,NULL}, {"convert-sk-to-pk",0, NULL,NULL}, /* Not anymore needed due to
the new design. */
{NULL,0,NULL,NULL} {NULL,0,NULL,NULL}
}; };
@ -1084,7 +1085,7 @@ import_one( const char *fname, KBNODE keyblock, struct stats_s *stats,
/* Transfer all the secret keys in SEC_KEYBLOCK to the gpg-agent. The /* Transfer all the secret keys in SEC_KEYBLOCK to the gpg-agent. The
function prints diagnostics and returns an error code. */ function prints diagnostics and returns an error code. */
static gpg_error_t static gpg_error_t
transfer_secret_keys (ctrl_t ctrl, kbnode_t sec_keyblock) transfer_secret_keys (ctrl_t ctrl, struct stats_s *stats, kbnode_t sec_keyblock)
{ {
gpg_error_t err = 0; gpg_error_t err = 0;
void *kek = NULL; void *kek = NULL;
@ -1135,6 +1136,9 @@ transfer_secret_keys (ctrl_t ctrl, kbnode_t sec_keyblock)
if (!main_sk) if (!main_sk)
main_sk = sk; main_sk = sk;
stats->count++;
stats->secret_read++;
/* Convert our internal secret key object into an S-expression. */ /* Convert our internal secret key object into an S-expression. */
nskey = pubkey_get_nskey (sk->pubkey_algo); nskey = pubkey_get_nskey (sk->pubkey_algo);
if (!nskey || nskey > PUBKEY_MAX_NSKEY) if (!nskey || nskey > PUBKEY_MAX_NSKEY)
@ -1279,9 +1283,7 @@ transfer_secret_keys (ctrl_t ctrl, kbnode_t sec_keyblock)
if (opt.verbose) if (opt.verbose)
log_info (_("key %s: secret key imported\n"), log_info (_("key %s: secret key imported\n"),
keystr_from_sk_with_sub (main_sk, sk)); keystr_from_sk_with_sub (main_sk, sk));
/* stats->count++; */ stats->secret_imported++;
/* stats->secret_read++; */
/* stats->secret_imported++; */
} }
else if ( gpg_err_code (err) == GPG_ERR_EEXIST ) else if ( gpg_err_code (err) == GPG_ERR_EEXIST )
{ {
@ -1289,9 +1291,7 @@ transfer_secret_keys (ctrl_t ctrl, kbnode_t sec_keyblock)
log_info (_("key %s: secret key already exists\n"), log_info (_("key %s: secret key already exists\n"),
keystr_from_sk_with_sub (main_sk, sk)); keystr_from_sk_with_sub (main_sk, sk));
err = 0; err = 0;
/* stats->count++; */ stats->secret_dups++;
/* stats->secret_read++; */
/* stats->secret_dups++; */
} }
else else
{ {
@ -1449,21 +1449,16 @@ import_secret_one (ctrl_t ctrl, const char *fname, KBNODE keyblock,
clear_kbnode_flags( keyblock ); clear_kbnode_flags( keyblock );
have_seckey = have_secret_key_with_kid (keyid); if ( !(opt.import_options&IMPORT_MERGE_ONLY) )
if (!have_seckey && !(opt.import_options&IMPORT_MERGE_ONLY) )
{ {
/* We don't have this key, insert as a new key. */ /* We don't have this key, insert as a new key. */
kbnode_t pub_keyblock; kbnode_t pub_keyblock;
stats->secret_imported++;
if (is_status_enabled ())
print_import_ok (NULL, sk, 1|16);
/* Make a public key out of this. */ /* Make a public key out of this. */
pub_keyblock = sec_to_pub_keyblock (keyblock); pub_keyblock = sec_to_pub_keyblock (keyblock);
if (!pub_keyblock) if (!pub_keyblock)
log_error ("oops: FIXME (bad error message)\n"); log_error ("key %s: failed to create public key from secret key\n",
keystr_from_sk (sk));
else else
{ {
import_one (fname, pub_keyblock, stats, import_one (fname, pub_keyblock, stats,
@ -1478,36 +1473,31 @@ import_secret_one (ctrl_t ctrl, const char *fname, KBNODE keyblock,
keyblock. */ keyblock. */
node = get_pubkeyblock (keyid); node = get_pubkeyblock (keyid);
if (!node) if (!node)
log_error ("oops: error getting public keyblock again\n"); log_error ("key %s: failed to re-lookup public key\n",
keystr_from_sk (sk));
else else
{ {
if (!transfer_secret_keys (ctrl, keyblock)) if (!transfer_secret_keys (ctrl, stats, keyblock))
{ {
if (!opt.quiet) if (!opt.quiet)
log_info (_("key %s: secret key imported\n"), log_info (_("key %s: secret key imported\n"),
keystr_from_sk (sk)); keystr_from_sk (sk));
if (is_status_enabled ())
print_import_ok (NULL, sk, 1|16);
check_prefs (node); check_prefs (node);
} }
release_kbnode (node); release_kbnode (node);
} }
} }
} }
else if (have_seckey) else if (have_secret_key_with_kid (keyid))
{ {
/* We can't yet merge secret keys. - Well, with the new system /* We don't want to merge the secret keys. */
we can => FIXME */
log_error( _("key %s: secret key part already available\n"), log_error( _("key %s: secret key part already available\n"),
keystr_from_sk(sk)); keystr_from_sk(sk));
stats->secret_dups++;
if (is_status_enabled ()) if (is_status_enabled ())
print_import_ok (NULL, sk, 16); print_import_ok (NULL, sk, 16);
/* TODO: if we ever do merge secret keys, make sure to handle
the sec_to_pub_keyblock feature as well. */
} }
else
log_error( _("key %s: secret key not found: %s\n"),
keystr_from_sk(sk), g10_errstr(rc));
return rc; return rc;
} }