From 752cae6dd2ee8982a34c796a3f168ae538f7938c Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 18 Oct 2017 13:09:47 +0200 Subject: gpg: Simplify keydb handling of the main import function. * g10/import.c (import_keys_internal): Return gpg_error_t instead of int. Change var names. (import_keys_es_stream): Ditto. (import_one): Ditto. Use a single keydb_new and simplify the use of of keydb_release. -- Note that this opens a keydb handle before we call get_pubkey_byfprint_fast which internally uses another key db handle. A further patch will cleanup this double use. Note that we also disable the keydb caching for the insert case. The s/int/gpg_error_t/ has been done while checking the call chains of the import functions and making sure that gpg_err_code is always used. Signed-off-by: Werner Koch --- g10/import.c | 159 +++++++++++++++++++++++++++++------------------------------ 1 file changed, 79 insertions(+), 80 deletions(-) (limited to 'g10/import.c') diff --git a/g10/import.c b/g10/import.c index 5b55f8f82..e7850023e 100644 --- a/g10/import.c +++ b/g10/import.c @@ -102,7 +102,7 @@ static int import (ctrl_t ctrl, static int read_block (IOBUF a, int with_meta, PACKET **pending_pkt, kbnode_t *ret_root, int *r_v3keys); static void revocation_present (ctrl_t ctrl, kbnode_t keyblock); -static int import_one (ctrl_t ctrl, +static gpg_error_t import_one (ctrl_t ctrl, kbnode_t keyblock, struct import_stats_s *stats, unsigned char **fpr, size_t *fpr_len, @@ -436,7 +436,7 @@ read_key_from_file (ctrl_t ctrl, const char *fname, kbnode_t *r_keyblock) * * Key revocation certificates have special handling. */ -static int +static gpg_error_t import_keys_internal (ctrl_t ctrl, iobuf_t inp, char **fnames, int nnames, import_stats_t stats_handle, unsigned char **fpr, size_t *fpr_len, @@ -445,7 +445,7 @@ import_keys_internal (ctrl_t ctrl, iobuf_t inp, char **fnames, int nnames, int origin, const char *url) { int i; - int rc = 0; + gpg_error_t err = 0; struct import_stats_s *stats = stats_handle; if (!stats) @@ -453,8 +453,8 @@ import_keys_internal (ctrl_t ctrl, iobuf_t inp, char **fnames, int nnames, if (inp) { - rc = import (ctrl, inp, "[stream]", stats, fpr, fpr_len, options, - screener, screener_arg, origin, url); + err = import (ctrl, inp, "[stream]", stats, fpr, fpr_len, options, + screener, screener_arg, origin, url); } else { @@ -478,14 +478,14 @@ import_keys_internal (ctrl_t ctrl, iobuf_t inp, char **fnames, int nnames, log_error (_("can't open '%s': %s\n"), fname, strerror (errno)); else { - rc = import (ctrl, inp2, fname, stats, fpr, fpr_len, options, + err = import (ctrl, inp2, fname, stats, fpr, fpr_len, options, screener, screener_arg, origin, url); iobuf_close (inp2); /* Must invalidate that ugly cache to actually close it. */ iobuf_ioctl (NULL, IOBUF_IOCTL_INVALIDATE_CACHE, 0, (char*)fname); - if (rc) + if (err) log_error ("import from '%s' failed: %s\n", - fname, gpg_strerror (rc) ); + fname, gpg_strerror (err) ); } if (!fname) break; @@ -507,7 +507,7 @@ import_keys_internal (ctrl_t ctrl, iobuf_t inp, char **fnames, int nnames, if (!(options & IMPORT_FAST)) check_or_update_trustdb (ctrl); - return rc; + return err; } @@ -521,7 +521,7 @@ import_keys (ctrl_t ctrl, char **fnames, int nnames, } -int +gpg_error_t import_keys_es_stream (ctrl_t ctrl, estream_t fp, import_stats_t stats_handle, unsigned char **fpr, size_t *fpr_len, @@ -529,23 +529,23 @@ import_keys_es_stream (ctrl_t ctrl, estream_t fp, import_screener_t screener, void *screener_arg, int origin, const char *url) { - int rc; + gpg_error_t err; iobuf_t inp; inp = iobuf_esopen (fp, "rb", 1); if (!inp) { - rc = gpg_error_from_syserror (); - log_error ("iobuf_esopen failed: %s\n", gpg_strerror (rc)); - return rc; + err = gpg_error_from_syserror (); + log_error ("iobuf_esopen failed: %s\n", gpg_strerror (err)); + return err; } - rc = import_keys_internal (ctrl, inp, NULL, 0, stats_handle, + err = import_keys_internal (ctrl, inp, NULL, 0, stats_handle, fpr, fpr_len, options, screener, screener_arg, origin, url); iobuf_close (inp); - return rc; + return err; } @@ -1608,7 +1608,7 @@ update_key_origin (kbnode_t keyblock, u32 curtime, int origin, const char *url) * even most error messages are suppressed. ORIGIN is the origin of * the key (0 for unknown) and URL the corresponding URL. */ -static int +static gpg_error_t import_one (ctrl_t ctrl, kbnode_t keyblock, struct import_stats_s *stats, unsigned char **fpr, size_t *fpr_len, unsigned int options, @@ -1616,6 +1616,7 @@ import_one (ctrl_t ctrl, import_screener_t screener, void *screener_arg, int origin, const char *url) { + gpg_error_t err = 0; PKT_public_key *pk; PKT_public_key *pk_orig = NULL; kbnode_t node, uidnode; @@ -1623,7 +1624,6 @@ import_one (ctrl_t ctrl, byte fpr2[MAX_FINGERPRINT_LEN]; size_t fpr2len; u32 keyid[2]; - int rc = 0; int new_key = 0; int mod_key = 0; int same_key = 0; @@ -1632,6 +1632,7 @@ import_one (ctrl_t ctrl, char pkstrbuf[PUBKEY_STRING_SIZE]; int merge_keys_done = 0; int any_filter = 0; + KEYDB_HANDLE hd = NULL; /* Get the key and print some info about it. */ node = find_kbnode( keyblock, PKT_PUBLIC_KEY ); @@ -1791,7 +1792,7 @@ import_one (ctrl_t ctrl, merge_keys_and_selfsig (ctrl, keyblock); merge_keys_done = 1; } - rc = write_keyblock_to_output (keyblock, opt.armor, opt.export_options); + err = write_keyblock_to_output (keyblock, opt.armor, opt.export_options); goto leave; } @@ -1799,37 +1800,37 @@ import_one (ctrl_t ctrl, goto leave; /* Do we have this key already in one of our pubrings ? */ + hd = keydb_new (); + if (!hd) + return gpg_error_from_syserror (); + keydb_disable_caching (hd); pk_orig = xmalloc_clear( sizeof *pk_orig ); - rc = get_pubkey_byfprint_fast (pk_orig, fpr2, fpr2len); - if (rc && gpg_err_code (rc) != GPG_ERR_NO_PUBKEY - && gpg_err_code (rc) != GPG_ERR_UNUSABLE_PUBKEY ) + err = get_pubkey_byfprint_fast (pk_orig, fpr2, fpr2len); + if (err + && gpg_err_code (err) != GPG_ERR_NO_PUBKEY + && gpg_err_code (err) != GPG_ERR_UNUSABLE_PUBKEY ) { if (!silent) log_error (_("key %s: public key not found: %s\n"), - keystr(keyid), gpg_strerror (rc)); + keystr(keyid), gpg_strerror (err)); } - else if ( rc && (opt.import_options&IMPORT_MERGE_ONLY) ) + else if (err && (opt.import_options&IMPORT_MERGE_ONLY) ) { if (opt.verbose && !silent ) log_info( _("key %s: new key - skipped\n"), keystr(keyid)); - rc = 0; + err = 0; stats->skipped_new_keys++; } - else if (rc ) /* Insert this key. */ + else if (err) /* Insert this key. */ { - KEYDB_HANDLE hd; int n_sigs_cleaned, n_uids_cleaned; - hd = keydb_new (); - if (!hd) - return gpg_error_from_syserror (); - - rc = keydb_locate_writable (hd); - if (rc) + err = keydb_locate_writable (hd); + if (err) { - log_error (_("no writable keyring found: %s\n"), gpg_strerror (rc)); - keydb_release (hd); - return GPG_ERR_GENERAL; + log_error (_("no writable keyring found: %s\n"), gpg_strerror (err)); + err = gpg_error (GPG_ERR_GENERAL); + goto leave; } if (opt.verbose > 1 ) log_info (_("writing to '%s'\n"), keydb_get_resource_name (hd) ); @@ -1843,19 +1844,19 @@ import_one (ctrl_t ctrl, * and thus the address of KEYBLOCK won't change. */ if ( !(options & IMPORT_RESTORE) ) { - rc = insert_key_origin (keyblock, origin, url); - if (rc) + err = insert_key_origin (keyblock, origin, url); + if (err) { - log_error ("insert_key_origin failed: %s\n", gpg_strerror (rc)); - keydb_release (hd); - return GPG_ERR_GENERAL; + log_error ("insert_key_origin failed: %s\n", gpg_strerror (err)); + err = gpg_error (GPG_ERR_GENERAL); + goto leave; } } - rc = keydb_insert_keyblock (hd, keyblock ); - if (rc) + err = keydb_insert_keyblock (hd, keyblock ); + if (err) log_error (_("error writing keyring '%s': %s\n"), - keydb_get_resource_name (hd), gpg_strerror (rc)); + keydb_get_resource_name (hd), gpg_strerror (err)); else if (!(opt.import_options & IMPORT_KEEP_OWNERTTRUST)) { /* This should not be possible since we delete the @@ -1868,7 +1869,10 @@ import_one (ctrl_t ctrl, if (non_self) revalidation_mark (ctrl); } + + /* Release the handle and thus unlock the keyring asap. */ keydb_release (hd); + hd = NULL; /* We are ready. */ if (!opt.quiet && !silent) @@ -1890,7 +1894,6 @@ import_one (ctrl_t ctrl, } else /* Merge the key. */ { - KEYDB_HANDLE hd; int n_uids, n_sigs, n_subk, n_sigs_cleaned, n_uids_cleaned; u32 curtime = make_timestamp (); @@ -1903,29 +1906,22 @@ import_one (ctrl_t ctrl, goto leave; } - /* Now read the original keyblock again so that we can use - that handle for updating the keyblock. */ - hd = keydb_new (); - if (!hd) - { - rc = gpg_error_from_syserror (); - goto leave; - } - keydb_disable_caching (hd); - rc = keydb_search_fpr (hd, fpr2); - if (rc ) + /* Now read the original keyblock again so that we can use the + * handle for updating the keyblock. FIXME: Why not let + * get_pubkey_byfprint_fast do that - it fetches the keyblock + * anyway. */ + err = keydb_search_fpr (hd, fpr2); + if (err) { log_error (_("key %s: can't locate original keyblock: %s\n"), - keystr(keyid), gpg_strerror (rc)); - keydb_release (hd); + keystr(keyid), gpg_strerror (err)); goto leave; } - rc = keydb_get_keyblock (hd, &keyblock_orig); - if (rc) + err = keydb_get_keyblock (hd, &keyblock_orig); + if (err) { log_error (_("key %s: can't read original keyblock: %s\n"), - keystr(keyid), gpg_strerror (rc)); - keydb_release (hd); + keystr(keyid), gpg_strerror (err)); goto leave; } @@ -1938,14 +1934,11 @@ import_one (ctrl_t ctrl, clear_kbnode_flags( keyblock_orig ); clear_kbnode_flags( keyblock ); n_uids = n_sigs = n_subk = n_uids_cleaned = 0; - rc = merge_blocks (ctrl, options, keyblock_orig, keyblock, keyid, - curtime, origin, url, - &n_uids, &n_sigs, &n_subk ); - if (rc ) - { - keydb_release (hd); - goto leave; - } + err = merge_blocks (ctrl, options, keyblock_orig, keyblock, keyid, + curtime, origin, url, + &n_uids, &n_sigs, &n_subk ); + if (err) + goto leave; if ((options & IMPORT_CLEAN)) clean_key (ctrl, keyblock_orig, opt.verbose, (options&IMPORT_MINIMAL), @@ -1958,25 +1951,28 @@ import_one (ctrl_t ctrl, * and thus the address of KEYBLOCK won't change. */ if ( !(options & IMPORT_RESTORE) ) { - rc = update_key_origin (keyblock_orig, curtime, origin, url); - if (rc) + err = update_key_origin (keyblock_orig, curtime, origin, url); + if (err) { log_error ("update_key_origin failed: %s\n", - gpg_strerror (rc)); - keydb_release (hd); + gpg_strerror (err)); goto leave; } } mod_key = 1; /* KEYBLOCK_ORIG has been updated; write */ - rc = keydb_update_keyblock (ctrl, hd, keyblock_orig); - if (rc) + err = keydb_update_keyblock (ctrl, hd, keyblock_orig); + if (err) log_error (_("error writing keyring '%s': %s\n"), - keydb_get_resource_name (hd), gpg_strerror (rc) ); + keydb_get_resource_name (hd), gpg_strerror (err)); else if (non_self) revalidation_mark (ctrl); + /* Release the handle and thus unlock the keyring asap. */ + keydb_release (hd); + hd = NULL; + /* We are ready. */ if (!opt.quiet && !silent) { @@ -2025,6 +2021,10 @@ import_one (ctrl_t ctrl, } else { + /* Release the handle and thus unlock the keyring asap. */ + keydb_release (hd); + hd = NULL; + /* Fixme: we do not track the time we last checked a key for * updates. To do this we would need to rewrite even the * keys which have no changes. */ @@ -2041,11 +2041,10 @@ import_one (ctrl_t ctrl, stats->unchanged++; } - - keydb_release (hd); hd = NULL; } leave: + keydb_release (hd); if (mod_key || new_key || same_key) { /* A little explanation for this: we fill in the fingerprint @@ -2094,7 +2093,7 @@ import_one (ctrl_t ctrl, release_kbnode( keyblock_orig ); free_public_key( pk_orig ); - return rc; + return err; } -- cgit From 8448347b5bdee56e6f9938a93ea92fe4d3c8800c Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 18 Oct 2017 17:52:41 +0200 Subject: gpg: Improve keydb handling in the main import function. * g10/getkey.c (get_pubkey_byfprint_fast): Factor most code out to ... (get_keyblock_byfprint_fast): .. new function. * g10/import.c (revocation_present): s/int rc/gpg_error_t err/. (import_one): Use get_keyblock_byfprint_fast to get the keyblock and a handle. Remove the now surplus keyblock fetch in the merge branch. Signed-off-by: Werner Koch --- g10/getkey.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++++------------ g10/import.c | 66 ++++++++++++++++++---------------------------------- g10/keydb.h | 13 +++++++++-- 3 files changed, 95 insertions(+), 60 deletions(-) (limited to 'g10/import.c') diff --git a/g10/getkey.c b/g10/getkey.c index 852c53286..5ce580541 100644 --- a/g10/getkey.c +++ b/g10/getkey.c @@ -1828,16 +1828,47 @@ get_pubkey_byfprint (ctrl_t ctrl, PKT_public_key *pk, kbnode_t *r_keyblock, * * Like get_pubkey_byfprint, PK may be NULL. In that case, this * function effectively just checks for the existence of the key. */ -int +gpg_error_t get_pubkey_byfprint_fast (PKT_public_key * pk, const byte * fprint, size_t fprint_len) { - int rc = 0; - KEYDB_HANDLE hd; + gpg_error_t err; KBNODE keyblock; + + err = get_keyblock_byfprint_fast (&keyblock, NULL, fprint, fprint_len, 0); + if (!err) + { + if (pk) + copy_public_key (pk, keyblock->pkt->pkt.public_key); + release_kbnode (keyblock); + } + + return err; +} + + +/* This function is similar to get_pubkey_byfprint_fast but returns a + * keydb handle at R_HD and the keyblock at R_KEYBLOCK. R_KEYBLOCK or + * R_HD may be NULL. If LOCK is set the handle has been opend in + * locked mode and keydb_disable_caching () has been called. On error + * R_KEYBLOCK is set to NULL but R_HD must be released by the caller; + * it may have a value of NULL, though. This allows to do an insert + * operation on a locked keydb handle. */ +gpg_error_t +get_keyblock_byfprint_fast (kbnode_t *r_keyblock, KEYDB_HANDLE *r_hd, + const byte *fprint, size_t fprint_len, int lock) +{ + gpg_error_t err; + KEYDB_HANDLE hd; + kbnode_t keyblock; byte fprbuf[MAX_FINGERPRINT_LEN]; int i; + if (r_keyblock) + *r_keyblock = NULL; + if (r_hd) + *r_hd = NULL; + for (i = 0; i < MAX_FINGERPRINT_LEN && i < fprint_len; i++) fprbuf[i] = fprint[i]; while (i < MAX_FINGERPRINT_LEN) @@ -1846,33 +1877,48 @@ get_pubkey_byfprint_fast (PKT_public_key * pk, hd = keydb_new (); if (!hd) return gpg_error_from_syserror (); + if (r_hd) + *r_hd = hd; - rc = keydb_search_fpr (hd, fprbuf); - if (gpg_err_code (rc) == GPG_ERR_NOT_FOUND) + if (lock) { - keydb_release (hd); - return GPG_ERR_NO_PUBKEY; + keydb_disable_caching (hd); } - rc = keydb_get_keyblock (hd, &keyblock); - keydb_release (hd); - if (rc) + + err = keydb_search_fpr (hd, fprbuf); + if (gpg_err_code (err) == GPG_ERR_NOT_FOUND) { - log_error ("keydb_get_keyblock failed: %s\n", gpg_strerror (rc)); - return GPG_ERR_NO_PUBKEY; + if (!r_hd) + keydb_release (hd); + return gpg_error (GPG_ERR_NO_PUBKEY); + } + err = keydb_get_keyblock (hd, &keyblock); + if (err) + { + log_error ("keydb_get_keyblock failed: %s\n", gpg_strerror (err)); + if (!r_hd) + keydb_release (hd); + return gpg_error (GPG_ERR_NO_PUBKEY); } log_assert (keyblock->pkt->pkttype == PKT_PUBLIC_KEY || keyblock->pkt->pkttype == PKT_PUBLIC_SUBKEY); - if (pk) - copy_public_key (pk, keyblock->pkt->pkt.public_key); - release_kbnode (keyblock); /* Not caching key here since it won't have all of the fields properly set. */ + if (r_keyblock) + *r_keyblock = keyblock; + else + release_kbnode (keyblock); + + if (!r_hd) + keydb_release (hd); + return 0; } + const char * parse_def_secret_key (ctrl_t ctrl) { diff --git a/g10/import.c b/g10/import.c index e7850023e..8dd6b501e 100644 --- a/g10/import.c +++ b/g10/import.c @@ -1618,7 +1618,6 @@ import_one (ctrl_t ctrl, { gpg_error_t err = 0; PKT_public_key *pk; - PKT_public_key *pk_orig = NULL; kbnode_t node, uidnode; kbnode_t keyblock_orig = NULL; byte fpr2[MAX_FINGERPRINT_LEN]; @@ -1800,16 +1799,15 @@ import_one (ctrl_t ctrl, goto leave; /* Do we have this key already in one of our pubrings ? */ - hd = keydb_new (); - if (!hd) - return gpg_error_from_syserror (); - keydb_disable_caching (hd); - pk_orig = xmalloc_clear( sizeof *pk_orig ); - err = get_pubkey_byfprint_fast (pk_orig, fpr2, fpr2len); - if (err - && gpg_err_code (err) != GPG_ERR_NO_PUBKEY - && gpg_err_code (err) != GPG_ERR_UNUSABLE_PUBKEY ) - { + err = get_keyblock_byfprint_fast (&keyblock_orig, &hd, + fpr2, fpr2len, 1/*locked*/); + if ((err + && gpg_err_code (err) != GPG_ERR_NO_PUBKEY + && gpg_err_code (err) != GPG_ERR_UNUSABLE_PUBKEY) + || !hd) + { + /* The !hd above is to catch a misbehaving function which + * returns NO_PUBKEY for failing to allocate a handle. */ if (!silent) log_error (_("key %s: public key not found: %s\n"), keystr(keyid), gpg_strerror (err)); @@ -1823,6 +1821,7 @@ import_one (ctrl_t ctrl, } else if (err) /* Insert this key. */ { + /* Note: ERR can only be NO_PUBKEY or UNUSABLE_PUBKEY. */ int n_sigs_cleaned, n_uids_cleaned; err = keydb_locate_writable (hd); @@ -1892,45 +1891,26 @@ import_one (ctrl_t ctrl, stats->imported++; new_key = 1; } - else /* Merge the key. */ + else /* Key already exists - merge. */ { int n_uids, n_sigs, n_subk, n_sigs_cleaned, n_uids_cleaned; u32 curtime = make_timestamp (); /* Compare the original against the new key; just to be sure nothing * weird is going on */ - if (cmp_public_keys( pk_orig, pk ) ) + if (cmp_public_keys (keyblock_orig->pkt->pkt.public_key, pk)) { if (!silent) log_error( _("key %s: doesn't match our copy\n"),keystr(keyid)); goto leave; } - /* Now read the original keyblock again so that we can use the - * handle for updating the keyblock. FIXME: Why not let - * get_pubkey_byfprint_fast do that - it fetches the keyblock - * anyway. */ - err = keydb_search_fpr (hd, fpr2); - if (err) - { - log_error (_("key %s: can't locate original keyblock: %s\n"), - keystr(keyid), gpg_strerror (err)); - goto leave; - } - err = keydb_get_keyblock (hd, &keyblock_orig); - if (err) - { - log_error (_("key %s: can't read original keyblock: %s\n"), - keystr(keyid), gpg_strerror (err)); - goto leave; - } - /* Make sure the original direct key sigs are all sane. */ n_sigs_cleaned = fix_bad_direct_key_sigs (ctrl, keyblock_orig, keyid); if (n_sigs_cleaned) commit_kbnode (&keyblock_orig); - /* and try to merge the block */ + /* Try to merge KEYBLOCK into KEYBLOCK_ORIG. */ clear_kbnode_flags( keyblock_orig ); clear_kbnode_flags( keyblock ); n_uids = n_sigs = n_subk = n_uids_cleaned = 0; @@ -2091,7 +2071,6 @@ import_one (ctrl_t ctrl, } release_kbnode( keyblock_orig ); - free_public_key( pk_orig ); return err; } @@ -3266,14 +3245,15 @@ revocation_present (ctrl_t ctrl, kbnode_t keyblock) /* Okay, we have a revocation key, and a * revocation issued by it. Do we have the key * itself? */ - int rc; + gpg_error_t err; - rc=get_pubkey_byfprint_fast (NULL,sig->revkey[idx].fpr, - MAX_FINGERPRINT_LEN); - if (gpg_err_code (rc) == GPG_ERR_NO_PUBKEY - || gpg_err_code (rc) == GPG_ERR_UNUSABLE_PUBKEY) + err = get_pubkey_byfprint_fast (NULL, + sig->revkey[idx].fpr, + MAX_FINGERPRINT_LEN); + if (gpg_err_code (err) == GPG_ERR_NO_PUBKEY + || gpg_err_code (err) == GPG_ERR_UNUSABLE_PUBKEY) { - char *tempkeystr=xstrdup(keystr_from_pk(pk)); + char *tempkeystr = xstrdup (keystr_from_pk (pk)); /* No, so try and get it */ if ((opt.keyserver_options.options @@ -3289,13 +3269,13 @@ revocation_present (ctrl_t ctrl, kbnode_t keyblock) opt.keyserver, 0); /* Do we have it now? */ - rc=get_pubkey_byfprint_fast (NULL, + err = get_pubkey_byfprint_fast (NULL, sig->revkey[idx].fpr, MAX_FINGERPRINT_LEN); } - if (gpg_err_code (rc) == GPG_ERR_NO_PUBKEY - || gpg_err_code (rc) == GPG_ERR_UNUSABLE_PUBKEY) + if (gpg_err_code (err) == GPG_ERR_NO_PUBKEY + || gpg_err_code (err) == GPG_ERR_UNUSABLE_PUBKEY) log_info(_("WARNING: key %s may be revoked:" " revocation key %s not present.\n"), tempkeystr,keystr(keyid)); diff --git a/g10/keydb.h b/g10/keydb.h index f503c9990..b173751ca 100644 --- a/g10/keydb.h +++ b/g10/keydb.h @@ -339,8 +339,17 @@ int get_pubkey_byfprint (ctrl_t ctrl, PKT_public_key *pk, kbnode_t *r_keyblock, /* This function is similar to get_pubkey_byfprint, but it doesn't merge the self-signed data into the public key and subkeys or into the user ids. */ -int get_pubkey_byfprint_fast (PKT_public_key *pk, - const byte *fprint, size_t fprint_len); +gpg_error_t get_pubkey_byfprint_fast (PKT_public_key *pk, + const byte *fprint, size_t fprint_len); + +/* This function is similar to get_pubkey_byfprint, but it doesn't + merge the self-signed data into the public key and subkeys or into + the user ids. */ +gpg_error_t get_keyblock_byfprint_fast (kbnode_t *r_keyblock, + KEYDB_HANDLE *r_hd, + const byte *fprint, size_t fprint_len, + int lock); + /* Returns true if a secret key is available for the public key with key id KEYID. */ -- cgit From 68c8619114fd5f24cb6bfb9e0f25c428a8805323 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 19 Oct 2017 17:05:39 +0200 Subject: gpg: Make --dry-run and show-only work for secret keys. * g10/import.c (import_secret_one): Check for dry-run before transferring keys. -- The use of --dry-run or --import-option show-only had no effect when importing a secret key and the public key already existed. If the public key did not exist an error message inhibited the import of the secret key. Signed-off-by: Werner Koch --- g10/import.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'g10/import.c') diff --git a/g10/import.c b/g10/import.c index 8dd6b501e..255e48fb2 100644 --- a/g10/import.c +++ b/g10/import.c @@ -2532,7 +2532,8 @@ import_secret_one (ctrl_t ctrl, kbnode_t keyblock, /* At least we cancel the secret key import when the public key import was skipped due to MERGE_ONLY option and a new key. */ - if (stats->skipped_new_keys <= nr_prev) + if (!(opt.dry_run || (options & IMPORT_DRY_RUN)) + && stats->skipped_new_keys <= nr_prev) { /* Read the keyblock again to get the effects of a merge. */ /* Fixme: we should do this based on the fingerprint or -- cgit From 2c7dccca9b617780a3ea760adf460bb3b77f90f3 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 19 Oct 2017 17:12:36 +0200 Subject: gpg: Print sec/sbb with --import-option import-show or show-only. * g10/import.c (import_one): Pass FROM_SK to list_keyblock_direct. -- Note that this will likely add the suffix '#' top "sec" because the secret key has not yet (or will not be) imported. If the secret key already exists locally another suffix might be printed. The upshot is that the suffix has no usefulness. GnuPG-bug-id: 3431 Signed-off-by: Werner Koch --- doc/gpg.texi | 3 ++- g10/import.c | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'g10/import.c') diff --git a/doc/gpg.texi b/doc/gpg.texi index b14cb371b..bd45b0422 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -2306,7 +2306,8 @@ opposite meaning. The options are: Show a listing of the key as imported right before it is stored. This can be combined with the option @option{--dry-run} to only look at keys; the option @option{show-only} is a shortcut for this - combination. + combination. Note that suffixes like '#' for "sec" and "sbb" lines + may or may not be printed. @item import-export Run the entire import code but instead of storing the key to the diff --git a/g10/import.c b/g10/import.c index 255e48fb2..71e39557c 100644 --- a/g10/import.c +++ b/g10/import.c @@ -1778,7 +1778,7 @@ import_one (ctrl_t ctrl, merge_keys_done = 1; /* Note that we do not want to show the validity because the key * has not yet imported. */ - list_keyblock_direct (ctrl, keyblock, 0, 0, + list_keyblock_direct (ctrl, keyblock, from_sk, 0, opt.fingerprint || opt.with_fingerprint, 1); es_fflush (es_stdout); } -- cgit