gpg: Take care of keydb_new returning NULL.

* g10/keydb.c (keydb_new): Print an error message if needed.  Also use
xtrycalloc because we return an error anyway.
* g10/delkey.c (do_delete_key): Handle error retruned by keydb_new.
* g10/export.c (do_export_stream): Ditto.
* g10/getkey.c (get_pubkey): Ditto.
(get_pubkey_fast): Ditto.
(get_pubkeyblock): Ditto.
(get_seckey): Ditto.
(key_byname): Ditto.
(get_pubkey_byfprint): Ditto.
(get_pubkey_byfprint_fast): Ditto.
(parse_def_secret_key): Ditto.
(have_secret_key_with_kid): Ditto.
* g10/import.c (import_one): Ditto.
(import_revoke_cert): Ditto.
* g10/keyedit.c (keyedit_quick_adduid): Ditto.
* g10/keygen.c (quick_generate_keypair): Ditto.
(do_generate_keypair): Ditto.
* g10/trustdb.c (validate_keys): Ditto.
* g10/keyserver.c (keyidlist): Ditto.
* g10/revoke.c (gen_desig_revoke): Ditto.
(gen_revoke): Ditto.
* g10/gpg.c (check_user_ids): Ditto.
(main): Do not print an error message for keydb_new error.
* g10/keylist.c (list_all): Use actual error code returned by
keydb_new.

* g10/t-keydb-get-keyblock.c (do_test): Abort on keydb_new error.
* g10/t-keydb.c (do_test): Ditto.

* g10/keyring.c (keyring_new): Actually return an error so that the
existing keydb_new error checking makes sense for a keyring resource.
(keyring_rebuild_cache): Take care of keyring_new returning an error.
--

Commit 04a6b903 changed keydb_new to return an error.  However the
error was not checked at most places which we fix with this patch.  To
make things easier keydb_new prints an error message itself.

Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
Werner Koch 2015-12-03 12:18:32 +01:00
parent 9fcc047d92
commit a28ac99efe
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B
16 changed files with 155 additions and 37 deletions

View File

@ -65,6 +65,8 @@ do_delete_key( const char *username, int secret, int force, int *r_sec_avail )
*r_sec_avail = 0; *r_sec_avail = 0;
hd = keydb_new (); hd = keydb_new ();
if (!hd)
return gpg_error_from_syserror ();
/* Search the userid. */ /* Search the userid. */
err = classify_user_id (username, &desc, 1); err = classify_user_id (username, &desc, 1);

View File

@ -857,6 +857,8 @@ do_export_stream (ctrl_t ctrl, iobuf_t out, strlist_t users, int secret,
*any = 0; *any = 0;
init_packet (&pkt); init_packet (&pkt);
kdbhd = keydb_new (); kdbhd = keydb_new ();
if (!kdbhd)
return gpg_error_from_syserror ();
/* For the DANE format override the options. */ /* For the DANE format override the options. */
if ((options & EXPORT_DANE_FORMAT)) if ((options & EXPORT_DANE_FORMAT))

View File

@ -424,6 +424,11 @@ get_pubkey (PKT_public_key * pk, u32 * keyid)
ctx.exact = 1; /* Use the key ID exactly as given. */ ctx.exact = 1; /* Use the key ID exactly as given. */
ctx.not_allocated = 1; ctx.not_allocated = 1;
ctx.kr_handle = keydb_new (); ctx.kr_handle = keydb_new ();
if (!ctx.kr_handle)
{
rc = gpg_error_from_syserror ();
goto leave;
}
ctx.nitems = 1; ctx.nitems = 1;
ctx.items[0].mode = KEYDB_SEARCH_MODE_LONG_KID; ctx.items[0].mode = KEYDB_SEARCH_MODE_LONG_KID;
ctx.items[0].u.kid[0] = keyid[0]; ctx.items[0].u.kid[0] = keyid[0];
@ -482,6 +487,8 @@ get_pubkey_fast (PKT_public_key * pk, u32 * keyid)
#endif #endif
hd = keydb_new (); hd = keydb_new ();
if (!hd)
return gpg_error_from_syserror ();
rc = keydb_search_kid (hd, keyid); rc = keydb_search_kid (hd, keyid);
if (gpg_err_code (rc) == GPG_ERR_NOT_FOUND) if (gpg_err_code (rc) == GPG_ERR_NOT_FOUND)
{ {
@ -528,6 +535,8 @@ get_pubkeyblock (u32 * keyid)
/* No need to set exact here because we want the entire block. */ /* No need to set exact here because we want the entire block. */
ctx.not_allocated = 1; ctx.not_allocated = 1;
ctx.kr_handle = keydb_new (); ctx.kr_handle = keydb_new ();
if (!ctx.kr_handle)
return NULL;
ctx.nitems = 1; ctx.nitems = 1;
ctx.items[0].mode = KEYDB_SEARCH_MODE_LONG_KID; ctx.items[0].mode = KEYDB_SEARCH_MODE_LONG_KID;
ctx.items[0].u.kid[0] = keyid[0]; ctx.items[0].u.kid[0] = keyid[0];
@ -552,6 +561,8 @@ get_seckey (PKT_public_key *pk, u32 *keyid)
ctx.exact = 1; /* Use the key ID exactly as given. */ ctx.exact = 1; /* Use the key ID exactly as given. */
ctx.not_allocated = 1; ctx.not_allocated = 1;
ctx.kr_handle = keydb_new (); ctx.kr_handle = keydb_new ();
if (!ctx.kr_handle)
return gpg_error_from_syserror ();
ctx.nitems = 1; ctx.nitems = 1;
ctx.items[0].mode = KEYDB_SEARCH_MODE_LONG_KID; ctx.items[0].mode = KEYDB_SEARCH_MODE_LONG_KID;
ctx.items[0].u.kid[0] = keyid[0]; ctx.items[0].u.kid[0] = keyid[0];
@ -748,6 +759,13 @@ key_byname (GETKEY_CTX *retctx, strlist_t namelist,
ctx->want_secret = want_secret; ctx->want_secret = want_secret;
ctx->kr_handle = keydb_new (); ctx->kr_handle = keydb_new ();
if (!ctx->kr_handle)
{
rc = gpg_error_from_syserror ();
getkey_end (ctx);
return rc;
}
if (!ret_kb) if (!ret_kb)
ret_kb = &help_kb; ret_kb = &help_kb;
@ -1068,6 +1086,9 @@ get_pubkey_byfprint (PKT_public_key *pk, kbnode_t *r_keyblock,
ctx.exact = 1; ctx.exact = 1;
ctx.not_allocated = 1; ctx.not_allocated = 1;
ctx.kr_handle = keydb_new (); ctx.kr_handle = keydb_new ();
if (!ctx.kr_handle)
return gpg_error_from_syserror ();
ctx.nitems = 1; ctx.nitems = 1;
ctx.items[0].mode = fprint_len == 16 ? KEYDB_SEARCH_MODE_FPR16 ctx.items[0].mode = fprint_len == 16 ? KEYDB_SEARCH_MODE_FPR16
: KEYDB_SEARCH_MODE_FPR20; : KEYDB_SEARCH_MODE_FPR20;
@ -1106,6 +1127,9 @@ get_pubkey_byfprint_fast (PKT_public_key * pk,
fprbuf[i++] = 0; fprbuf[i++] = 0;
hd = keydb_new (); hd = keydb_new ();
if (!hd)
return gpg_error_from_syserror ();
rc = keydb_search_fpr (hd, fprbuf); rc = keydb_search_fpr (hd, fprbuf);
if (gpg_err_code (rc) == GPG_ERR_NOT_FOUND) if (gpg_err_code (rc) == GPG_ERR_NOT_FOUND)
{ {
@ -1156,10 +1180,15 @@ parse_def_secret_key (ctrl_t ctrl)
} }
if (! hd) if (! hd)
hd = keydb_new (); {
hd = keydb_new ();
if (!hd)
return NULL;
}
else else
keydb_search_reset (hd); keydb_search_reset (hd);
err = keydb_search (hd, &desc, 1, NULL); err = keydb_search (hd, &desc, 1, NULL);
if (gpg_err_code (err) == GPG_ERR_NOT_FOUND) if (gpg_err_code (err) == GPG_ERR_NOT_FOUND)
continue; continue;
@ -3148,7 +3177,11 @@ parse_auto_key_locate (char *options)
} }
/* For documentation see keydb.h. */ /* Returns true if a secret key is available for the public key with
key id KEYID; returns false if not. This function ignores legacy
keys. Note: this is just a fast check and does not tell us whether
the secret key is valid; this check merely indicates whether there
is some secret key with the specified key id. */
int int
have_secret_key_with_kid (u32 *keyid) have_secret_key_with_kid (u32 *keyid)
{ {
@ -3160,6 +3193,8 @@ have_secret_key_with_kid (u32 *keyid)
int result = 0; int result = 0;
kdbhd = keydb_new (); kdbhd = keydb_new ();
if (!kdbhd)
return 0;
memset (&desc, 0, sizeof desc); memset (&desc, 0, sizeof desc);
desc.mode = KEYDB_SEARCH_MODE_LONG_KID; desc.mode = KEYDB_SEARCH_MODE_LONG_KID;
desc.u.kid[0] = keyid[0]; desc.u.kid[0] = keyid[0];
@ -3187,9 +3222,8 @@ have_secret_key_with_kid (u32 *keyid)
assert (node->pkt->pkttype == PKT_PUBLIC_KEY assert (node->pkt->pkttype == PKT_PUBLIC_KEY
|| node->pkt->pkttype == PKT_PUBLIC_SUBKEY); || node->pkt->pkttype == PKT_PUBLIC_SUBKEY);
if (agent_probe_secret_key (NULL, node->pkt->pkt.public_key) == 0) if (!agent_probe_secret_key (NULL, node->pkt->pkt.public_key))
/* Not available. */ result = 1; /* Secret key available. */
result = 1;
else else
result = 0; result = 0;

View File

@ -2155,7 +2155,14 @@ check_user_ids (strlist_t *sp,
t->d, option); t->d, option);
if (! hd) if (! hd)
hd = keydb_new (); {
hd = keydb_new ();
if (!hd)
{
rc = gpg_error_from_syserror ();
break;
}
}
else else
keydb_search_reset (hd); keydb_search_reset (hd);
@ -2295,8 +2302,7 @@ check_user_ids (strlist_t *sp,
strlist_rev (&s2); strlist_rev (&s2);
if (hd) keydb_release (hd);
keydb_release (hd);
free_strlist (s); free_strlist (s);
*sp = s2; *sp = s2;
@ -4728,10 +4734,7 @@ main (int argc, char **argv)
hd = keydb_new (); hd = keydb_new ();
if (! hd) if (! hd)
{ g10_exit (1);
log_error (_("Failed to open the keyring DB.\n"));
g10_exit (1);
}
for (i = 1; i < argc; i ++) for (i = 1; i < argc; i ++)
{ {

View File

@ -1071,7 +1071,11 @@ import_one (ctrl_t ctrl,
} }
else if (rc ) /* Insert this key. */ else if (rc ) /* Insert this key. */
{ {
KEYDB_HANDLE hd = keydb_new (); KEYDB_HANDLE hd;
hd = keydb_new ();
if (!hd)
return gpg_error_from_syserror ();
rc = keydb_locate_writable (hd); rc = keydb_locate_writable (hd);
if (rc) if (rc)
@ -1136,6 +1140,11 @@ import_one (ctrl_t ctrl,
/* Now read the original keyblock again so that we can use /* Now read the original keyblock again so that we can use
that handle for updating the keyblock. */ that handle for updating the keyblock. */
hd = keydb_new (); hd = keydb_new ();
if (!hd)
{
rc = gpg_error_from_syserror ();
goto leave;
}
keydb_disable_caching (hd); keydb_disable_caching (hd);
rc = keydb_search_fpr (hd, fpr2); rc = keydb_search_fpr (hd, fpr2);
if (rc ) if (rc )
@ -1846,6 +1855,12 @@ import_revoke_cert( const char *fname, kbnode_t node, struct stats_s *stats )
/* Read the original keyblock. */ /* Read the original keyblock. */
hd = keydb_new (); hd = keydb_new ();
if (!hd)
{
rc = gpg_error_from_syserror ();
goto leave;
}
{ {
byte afp[MAX_FINGERPRINT_LEN]; byte afp[MAX_FINGERPRINT_LEN];
size_t an; size_t an;

View File

@ -754,17 +754,26 @@ keydb_dump_stats (void)
} }
/* Create a new database handle. A database handle is similar to a
file handle: it contains a local file position. This is used when
searching: subsequent searches resume where the previous search
left off. To rewind the position, use keydb_search_reset(). This
function returns NULL on error, sets ERRNO, and prints an error
diagnostic. */
KEYDB_HANDLE KEYDB_HANDLE
keydb_new (void) keydb_new (void)
{ {
KEYDB_HANDLE hd; KEYDB_HANDLE hd;
int i, j; int i, j;
int die = 0; int die = 0;
int reterrno;
if (DBG_CLOCK) if (DBG_CLOCK)
log_clock ("keydb_new"); log_clock ("keydb_new");
hd = xmalloc_clear (sizeof *hd); hd = xtrycalloc (1, sizeof *hd);
if (!hd)
goto leave;
hd->found = -1; hd->found = -1;
hd->saved_found = -1; hd->saved_found = -1;
hd->is_reset = 1; hd->is_reset = 1;
@ -781,7 +790,10 @@ keydb_new (void)
hd->active[j].token = all_resources[i].token; hd->active[j].token = all_resources[i].token;
hd->active[j].u.kr = keyring_new (all_resources[i].token); hd->active[j].u.kr = keyring_new (all_resources[i].token);
if (!hd->active[j].u.kr) if (!hd->active[j].u.kr)
die = 1; {
reterrno = errno;
die = 1;
}
j++; j++;
break; break;
case KEYDB_RESOURCE_TYPE_KEYBOX: case KEYDB_RESOURCE_TYPE_KEYBOX:
@ -789,7 +801,10 @@ keydb_new (void)
hd->active[j].token = all_resources[i].token; hd->active[j].token = all_resources[i].token;
hd->active[j].u.kb = keybox_new_openpgp (all_resources[i].token, 0); hd->active[j].u.kb = keybox_new_openpgp (all_resources[i].token, 0);
if (!hd->active[j].u.kb) if (!hd->active[j].u.kb)
die = 1; {
reterrno = errno;
die = 1;
}
j++; j++;
break; break;
} }
@ -801,9 +816,15 @@ keydb_new (void)
if (die) if (die)
{ {
keydb_release (hd); keydb_release (hd);
gpg_err_set_errno (reterrno);
hd = NULL; hd = NULL;
} }
leave:
if (!hd)
log_error (_("error opening key DB: %s\n"),
gpg_strerror (gpg_error_from_syserror()));
return hd; return hd;
} }

View File

@ -186,10 +186,8 @@ gpg_error_t keydb_add_resource (const char *url, unsigned int flags);
/* Dump some statistics to the log. */ /* Dump some statistics to the log. */
void keydb_dump_stats (void); void keydb_dump_stats (void);
/* Create a new database handle. A database handle is similar to a /* Create a new database handle. Returns NULL on error, sets ERRNO,
file handle: it contains a local file position. This is used when and prints an error diagnostic. */
searching: subsequent searches resume where the previous search
left off. To rewind the position, use keydb_search_reset(). */
KEYDB_HANDLE keydb_new (void); KEYDB_HANDLE keydb_new (void);
/* Free all resources owned by the database handle. */ /* Free all resources owned by the database handle. */
@ -580,11 +578,8 @@ int get_pubkey_byfprint (PKT_public_key *pk, kbnode_t *r_keyblock,
int get_pubkey_byfprint_fast (PKT_public_key *pk, int get_pubkey_byfprint_fast (PKT_public_key *pk,
const byte *fprint, size_t fprint_len); const byte *fprint, size_t fprint_len);
/* Return whether a secret key is available for the public key with /* Returns true if a secret key is available for the public key with
key id KEYID. This function ignores legacy keys. Note: this is key id KEYID. */
just a fast check and does not tell us whether the secret key is
valid; this check merely indicates whether there is some secret key
with the specified key id. */
int have_secret_key_with_kid (u32 *keyid); int have_secret_key_with_kid (u32 *keyid);
/* Parse the --default-key parameter. Returns the last key (in terms /* Parse the --default-key parameter. Returns the last key (in terms

View File

@ -2386,6 +2386,12 @@ keyedit_quick_adduid (ctrl_t ctrl, const char *username, const char *newuid)
/* Search the key; we don't want the whole getkey stuff here. */ /* Search the key; we don't want the whole getkey stuff here. */
kdbhd = keydb_new (); kdbhd = keydb_new ();
if (!kdbhd)
{
err = gpg_error_from_syserror ();
goto leave;
}
err = classify_user_id (username, &desc, 1); err = classify_user_id (username, &desc, 1);
if (!err) if (!err)
err = keydb_search (kdbhd, &desc, 1, NULL); err = keydb_search (kdbhd, &desc, 1, NULL);

View File

@ -3533,6 +3533,9 @@ quick_generate_keypair (ctrl_t ctrl, const char *uid)
desc.u.name = uid; desc.u.name = uid;
kdbhd = keydb_new (); kdbhd = keydb_new ();
if (!kdbhd)
goto leave;
err = keydb_search (kdbhd, &desc, 1, NULL); err = keydb_search (kdbhd, &desc, 1, NULL);
keydb_release (kdbhd); keydb_release (kdbhd);
if (gpg_err_code (err) != GPG_ERR_NOT_FOUND) if (gpg_err_code (err) != GPG_ERR_NOT_FOUND)
@ -4148,12 +4151,18 @@ do_generate_keypair (ctrl_t ctrl, struct para_data_s *para,
} }
else if (!err) /* Write to the standard keyrings. */ else if (!err) /* Write to the standard keyrings. */
{ {
KEYDB_HANDLE pub_hd = keydb_new (); KEYDB_HANDLE pub_hd;
err = keydb_locate_writable (pub_hd); pub_hd = keydb_new ();
if (err) if (!pub_hd)
log_error (_("no writable public keyring found: %s\n"), err = gpg_error_from_syserror ();
gpg_strerror (err)); else
{
err = keydb_locate_writable (pub_hd);
if (err)
log_error (_("no writable public keyring found: %s\n"),
gpg_strerror (err));
}
if (!err && opt.verbose) if (!err && opt.verbose)
{ {

View File

@ -505,7 +505,7 @@ list_all (ctrl_t ctrl, int secret, int mark_secret)
hd = keydb_new (); hd = keydb_new ();
if (!hd) if (!hd)
rc = gpg_error (GPG_ERR_GENERAL); rc = gpg_error_from_syserror ();
else else
rc = keydb_search_first (hd); rc = keydb_search_first (hd);
if (rc) if (rc)

View File

@ -250,7 +250,7 @@ keyring_is_writable (void *token)
/* Create a new handle for the resource associated with TOKEN. /* Create a new handle for the resource associated with TOKEN.
On error NULL is returned and ERRNO is set.
The returned handle must be released using keyring_release (). */ The returned handle must be released using keyring_release (). */
KEYRING_HANDLE KEYRING_HANDLE
keyring_new (void *token) keyring_new (void *token)
@ -260,7 +260,9 @@ keyring_new (void *token)
assert (resource); assert (resource);
hd = xmalloc_clear (sizeof *hd); hd = xtrycalloc (1, sizeof *hd);
if (!hd)
return hd;
hd->resource = resource; hd->resource = resource;
active_handles++; active_handles++;
return hd; return hd;
@ -1487,6 +1489,8 @@ keyring_rebuild_cache (void *token,int noisy)
ulong count = 0, sigcount = 0; ulong count = 0, sigcount = 0;
hd = keyring_new (token); hd = keyring_new (token);
if (!hd)
return gpg_error_from_syserror ();
memset (&desc, 0, sizeof desc); memset (&desc, 0, sizeof desc);
desc.mode = KEYDB_SEARCH_MODE_FIRST; desc.mode = KEYDB_SEARCH_MODE_FIRST;

View File

@ -1190,10 +1190,13 @@ keyserver_import_keyid (ctrl_t ctrl,
static int static int
keyidlist(strlist_t users,KEYDB_SEARCH_DESC **klist,int *count,int fakev3) keyidlist(strlist_t users,KEYDB_SEARCH_DESC **klist,int *count,int fakev3)
{ {
int rc=0,ndesc,num=100; int rc = 0;
KBNODE keyblock=NULL,node; int num = 100;
kbnode_t keyblock = NULL;
kbnode_t node;
KEYDB_HANDLE kdbhd; KEYDB_HANDLE kdbhd;
KEYDB_SEARCH_DESC *desc; int ndesc;
KEYDB_SEARCH_DESC *desc = NULL;
strlist_t sl; strlist_t sl;
*count=0; *count=0;
@ -1201,6 +1204,11 @@ keyidlist(strlist_t users,KEYDB_SEARCH_DESC **klist,int *count,int fakev3)
*klist=xmalloc(sizeof(KEYDB_SEARCH_DESC)*num); *klist=xmalloc(sizeof(KEYDB_SEARCH_DESC)*num);
kdbhd = keydb_new (); kdbhd = keydb_new ();
if (!kdbhd)
{
rc = gpg_error_from_syserror ();
goto leave;
}
keydb_disable_caching (kdbhd); /* We are looping the search. */ keydb_disable_caching (kdbhd); /* We are looping the search. */
if(!users) if(!users)

View File

@ -220,6 +220,11 @@ gen_desig_revoke (ctrl_t ctrl, const char *uname, strlist_t locusr)
afx = new_armor_context (); afx = new_armor_context ();
kdbhd = keydb_new (); kdbhd = keydb_new ();
if (!kdbhd)
{
rc = gpg_error_from_syserror ();
goto leave;
}
rc = classify_user_id (uname, &desc, 1); rc = classify_user_id (uname, &desc, 1);
if (!rc) if (!rc)
rc = keydb_search (kdbhd, &desc, 1, NULL); rc = keydb_search (kdbhd, &desc, 1, NULL);
@ -609,6 +614,11 @@ gen_revoke (const char *uname)
/* Search the userid; we don't want the whole getkey stuff here. */ /* Search the userid; we don't want the whole getkey stuff here. */
kdbhd = keydb_new (); kdbhd = keydb_new ();
if (!kdbhd)
{
rc = gpg_error_from_syserror ();
goto leave;
}
rc = classify_user_id (uname, &desc, 1); rc = classify_user_id (uname, &desc, 1);
if (!rc) if (!rc)
rc = keydb_search (kdbhd, &desc, 1, NULL); rc = keydb_search (kdbhd, &desc, 1, NULL);

View File

@ -45,6 +45,8 @@ do_test (int argc, char *argv[])
ABORT ("Failed to open keyring."); ABORT ("Failed to open keyring.");
hd1 = keydb_new (); hd1 = keydb_new ();
if (!hd1)
ABORT ("");
rc = classify_user_id ("8061 5870 F5BA D690 3336 86D0 F2AD 85AC 1E42 B367", rc = classify_user_id ("8061 5870 F5BA D690 3336 86D0 F2AD 85AC 1E42 B367",
&desc1, 0); &desc1, 0);

View File

@ -42,7 +42,11 @@ do_test (int argc, char *argv[])
ABORT ("Failed to open keyring."); ABORT ("Failed to open keyring.");
hd1 = keydb_new (); hd1 = keydb_new ();
if (!hd1)
ABORT ("");
hd2 = keydb_new (); hd2 = keydb_new ();
if (!hd2)
ABORT ("");
rc = classify_user_id ("2689 5E25 E844 6D44 A26D 8FAF 2F79 98F3 DBFC 6AD9", rc = classify_user_id ("2689 5E25 E844 6D44 A26D 8FAF 2F79 98F3 DBFC 6AD9",
&desc1, 0); &desc1, 0);

View File

@ -1896,13 +1896,16 @@ validate_keys (int interactive)
trust. */ trust. */
keydb_rebuild_caches(0); keydb_rebuild_caches(0);
kdb = keydb_new ();
if (!kdb)
return gpg_error_from_syserror ();
start_time = make_timestamp (); start_time = make_timestamp ();
next_expire = 0xffffffff; /* set next expire to the year 2106 */ next_expire = 0xffffffff; /* set next expire to the year 2106 */
stored = new_key_hash_table (); stored = new_key_hash_table ();
used = new_key_hash_table (); used = new_key_hash_table ();
full_trust = new_key_hash_table (); full_trust = new_key_hash_table ();
kdb = keydb_new ();
reset_trust_records(); reset_trust_records();
/* Fixme: Instead of always building a UTK list, we could just build it /* Fixme: Instead of always building a UTK list, we could just build it