diff --git a/g10/delkey.c b/g10/delkey.c index 063de78e6..b8c03a140 100644 --- a/g10/delkey.c +++ b/g10/delkey.c @@ -65,6 +65,8 @@ do_delete_key( const char *username, int secret, int force, int *r_sec_avail ) *r_sec_avail = 0; hd = keydb_new (); + if (!hd) + return gpg_error_from_syserror (); /* Search the userid. */ err = classify_user_id (username, &desc, 1); diff --git a/g10/export.c b/g10/export.c index 1d71c1c46..f7ad1b276 100644 --- a/g10/export.c +++ b/g10/export.c @@ -857,6 +857,8 @@ do_export_stream (ctrl_t ctrl, iobuf_t out, strlist_t users, int secret, *any = 0; init_packet (&pkt); kdbhd = keydb_new (); + if (!kdbhd) + return gpg_error_from_syserror (); /* For the DANE format override the options. */ if ((options & EXPORT_DANE_FORMAT)) diff --git a/g10/getkey.c b/g10/getkey.c index 7d69912c4..b09d967f0 100644 --- a/g10/getkey.c +++ b/g10/getkey.c @@ -424,6 +424,11 @@ get_pubkey (PKT_public_key * pk, u32 * keyid) ctx.exact = 1; /* Use the key ID exactly as given. */ ctx.not_allocated = 1; ctx.kr_handle = keydb_new (); + if (!ctx.kr_handle) + { + rc = gpg_error_from_syserror (); + goto leave; + } ctx.nitems = 1; ctx.items[0].mode = KEYDB_SEARCH_MODE_LONG_KID; ctx.items[0].u.kid[0] = keyid[0]; @@ -482,6 +487,8 @@ get_pubkey_fast (PKT_public_key * pk, u32 * keyid) #endif hd = keydb_new (); + if (!hd) + return gpg_error_from_syserror (); rc = keydb_search_kid (hd, keyid); 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. */ ctx.not_allocated = 1; ctx.kr_handle = keydb_new (); + if (!ctx.kr_handle) + return NULL; ctx.nitems = 1; ctx.items[0].mode = KEYDB_SEARCH_MODE_LONG_KID; 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.not_allocated = 1; ctx.kr_handle = keydb_new (); + if (!ctx.kr_handle) + return gpg_error_from_syserror (); ctx.nitems = 1; ctx.items[0].mode = KEYDB_SEARCH_MODE_LONG_KID; 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->kr_handle = keydb_new (); + if (!ctx->kr_handle) + { + rc = gpg_error_from_syserror (); + getkey_end (ctx); + return rc; + } + if (!ret_kb) ret_kb = &help_kb; @@ -1068,6 +1086,9 @@ get_pubkey_byfprint (PKT_public_key *pk, kbnode_t *r_keyblock, ctx.exact = 1; ctx.not_allocated = 1; ctx.kr_handle = keydb_new (); + if (!ctx.kr_handle) + return gpg_error_from_syserror (); + ctx.nitems = 1; ctx.items[0].mode = fprint_len == 16 ? KEYDB_SEARCH_MODE_FPR16 : KEYDB_SEARCH_MODE_FPR20; @@ -1106,6 +1127,9 @@ get_pubkey_byfprint_fast (PKT_public_key * pk, fprbuf[i++] = 0; hd = keydb_new (); + if (!hd) + return gpg_error_from_syserror (); + rc = keydb_search_fpr (hd, fprbuf); if (gpg_err_code (rc) == GPG_ERR_NOT_FOUND) { @@ -1156,10 +1180,15 @@ parse_def_secret_key (ctrl_t ctrl) } if (! hd) - hd = keydb_new (); + { + hd = keydb_new (); + if (!hd) + return NULL; + } else keydb_search_reset (hd); + err = keydb_search (hd, &desc, 1, NULL); if (gpg_err_code (err) == GPG_ERR_NOT_FOUND) 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 have_secret_key_with_kid (u32 *keyid) { @@ -3160,6 +3193,8 @@ have_secret_key_with_kid (u32 *keyid) int result = 0; kdbhd = keydb_new (); + if (!kdbhd) + return 0; memset (&desc, 0, sizeof desc); desc.mode = KEYDB_SEARCH_MODE_LONG_KID; desc.u.kid[0] = keyid[0]; @@ -3187,9 +3222,8 @@ have_secret_key_with_kid (u32 *keyid) assert (node->pkt->pkttype == PKT_PUBLIC_KEY || node->pkt->pkttype == PKT_PUBLIC_SUBKEY); - if (agent_probe_secret_key (NULL, node->pkt->pkt.public_key) == 0) - /* Not available. */ - result = 1; + if (!agent_probe_secret_key (NULL, node->pkt->pkt.public_key)) + result = 1; /* Secret key available. */ else result = 0; diff --git a/g10/gpg.c b/g10/gpg.c index 225ca9af0..34d436ff3 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -2155,7 +2155,14 @@ check_user_ids (strlist_t *sp, t->d, option); if (! hd) - hd = keydb_new (); + { + hd = keydb_new (); + if (!hd) + { + rc = gpg_error_from_syserror (); + break; + } + } else keydb_search_reset (hd); @@ -2295,8 +2302,7 @@ check_user_ids (strlist_t *sp, strlist_rev (&s2); - if (hd) - keydb_release (hd); + keydb_release (hd); free_strlist (s); *sp = s2; @@ -4728,10 +4734,7 @@ main (int argc, char **argv) hd = keydb_new (); if (! hd) - { - log_error (_("Failed to open the keyring DB.\n")); - g10_exit (1); - } + g10_exit (1); for (i = 1; i < argc; i ++) { diff --git a/g10/import.c b/g10/import.c index e1577b8a1..518e97f71 100644 --- a/g10/import.c +++ b/g10/import.c @@ -1071,7 +1071,11 @@ import_one (ctrl_t ctrl, } 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); if (rc) @@ -1136,6 +1140,11 @@ import_one (ctrl_t ctrl, /* 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 ) @@ -1846,6 +1855,12 @@ import_revoke_cert( const char *fname, kbnode_t node, struct stats_s *stats ) /* Read the original keyblock. */ hd = keydb_new (); + if (!hd) + { + rc = gpg_error_from_syserror (); + goto leave; + } + { byte afp[MAX_FINGERPRINT_LEN]; size_t an; diff --git a/g10/keydb.c b/g10/keydb.c index 8a689809a..97dfb5fa3 100644 --- a/g10/keydb.c +++ b/g10/keydb.c @@ -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_new (void) { KEYDB_HANDLE hd; int i, j; int die = 0; + int reterrno; if (DBG_CLOCK) log_clock ("keydb_new"); - hd = xmalloc_clear (sizeof *hd); + hd = xtrycalloc (1, sizeof *hd); + if (!hd) + goto leave; hd->found = -1; hd->saved_found = -1; hd->is_reset = 1; @@ -781,7 +790,10 @@ keydb_new (void) hd->active[j].token = all_resources[i].token; hd->active[j].u.kr = keyring_new (all_resources[i].token); if (!hd->active[j].u.kr) - die = 1; + { + reterrno = errno; + die = 1; + } j++; break; case KEYDB_RESOURCE_TYPE_KEYBOX: @@ -789,7 +801,10 @@ keydb_new (void) hd->active[j].token = all_resources[i].token; hd->active[j].u.kb = keybox_new_openpgp (all_resources[i].token, 0); if (!hd->active[j].u.kb) - die = 1; + { + reterrno = errno; + die = 1; + } j++; break; } @@ -801,9 +816,15 @@ keydb_new (void) if (die) { keydb_release (hd); + gpg_err_set_errno (reterrno); hd = NULL; } + leave: + if (!hd) + log_error (_("error opening key DB: %s\n"), + gpg_strerror (gpg_error_from_syserror())); + return hd; } diff --git a/g10/keydb.h b/g10/keydb.h index 1848316b9..919f3fd77 100644 --- a/g10/keydb.h +++ b/g10/keydb.h @@ -186,10 +186,8 @@ gpg_error_t keydb_add_resource (const char *url, unsigned int flags); /* Dump some statistics to the log. */ void 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(). */ +/* Create a new database handle. Returns NULL on error, sets ERRNO, + and prints an error diagnostic. */ KEYDB_HANDLE keydb_new (void); /* 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, const byte *fprint, size_t fprint_len); -/* Return whether a secret key is available for the public key with - key id KEYID. 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. */ +/* Returns true if a secret key is available for the public key with + key id KEYID. */ int have_secret_key_with_kid (u32 *keyid); /* Parse the --default-key parameter. Returns the last key (in terms diff --git a/g10/keyedit.c b/g10/keyedit.c index a3feb796d..0a4766e81 100644 --- a/g10/keyedit.c +++ b/g10/keyedit.c @@ -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. */ kdbhd = keydb_new (); + if (!kdbhd) + { + err = gpg_error_from_syserror (); + goto leave; + } + err = classify_user_id (username, &desc, 1); if (!err) err = keydb_search (kdbhd, &desc, 1, NULL); diff --git a/g10/keygen.c b/g10/keygen.c index b3367a4ac..a1f449e15 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -3533,6 +3533,9 @@ quick_generate_keypair (ctrl_t ctrl, const char *uid) desc.u.name = uid; kdbhd = keydb_new (); + if (!kdbhd) + goto leave; + err = keydb_search (kdbhd, &desc, 1, NULL); keydb_release (kdbhd); 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. */ { - KEYDB_HANDLE pub_hd = keydb_new (); + KEYDB_HANDLE pub_hd; - err = keydb_locate_writable (pub_hd); - if (err) - log_error (_("no writable public keyring found: %s\n"), - gpg_strerror (err)); + pub_hd = keydb_new (); + if (!pub_hd) + err = gpg_error_from_syserror (); + 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) { diff --git a/g10/keylist.c b/g10/keylist.c index 58c0a9699..b2836e8cd 100644 --- a/g10/keylist.c +++ b/g10/keylist.c @@ -505,7 +505,7 @@ list_all (ctrl_t ctrl, int secret, int mark_secret) hd = keydb_new (); if (!hd) - rc = gpg_error (GPG_ERR_GENERAL); + rc = gpg_error_from_syserror (); else rc = keydb_search_first (hd); if (rc) diff --git a/g10/keyring.c b/g10/keyring.c index cf67eb0cd..6ba5202ac 100644 --- a/g10/keyring.c +++ b/g10/keyring.c @@ -250,7 +250,7 @@ keyring_is_writable (void *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 (). */ KEYRING_HANDLE keyring_new (void *token) @@ -260,7 +260,9 @@ keyring_new (void *token) assert (resource); - hd = xmalloc_clear (sizeof *hd); + hd = xtrycalloc (1, sizeof *hd); + if (!hd) + return hd; hd->resource = resource; active_handles++; return hd; @@ -1487,6 +1489,8 @@ keyring_rebuild_cache (void *token,int noisy) ulong count = 0, sigcount = 0; hd = keyring_new (token); + if (!hd) + return gpg_error_from_syserror (); memset (&desc, 0, sizeof desc); desc.mode = KEYDB_SEARCH_MODE_FIRST; diff --git a/g10/keyserver.c b/g10/keyserver.c index ab0eb627c..e9de4962e 100644 --- a/g10/keyserver.c +++ b/g10/keyserver.c @@ -1190,10 +1190,13 @@ keyserver_import_keyid (ctrl_t ctrl, static int keyidlist(strlist_t users,KEYDB_SEARCH_DESC **klist,int *count,int fakev3) { - int rc=0,ndesc,num=100; - KBNODE keyblock=NULL,node; + int rc = 0; + int num = 100; + kbnode_t keyblock = NULL; + kbnode_t node; KEYDB_HANDLE kdbhd; - KEYDB_SEARCH_DESC *desc; + int ndesc; + KEYDB_SEARCH_DESC *desc = NULL; strlist_t sl; *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); kdbhd = keydb_new (); + if (!kdbhd) + { + rc = gpg_error_from_syserror (); + goto leave; + } keydb_disable_caching (kdbhd); /* We are looping the search. */ if(!users) diff --git a/g10/revoke.c b/g10/revoke.c index 99242d115..ba87f3546 100644 --- a/g10/revoke.c +++ b/g10/revoke.c @@ -220,6 +220,11 @@ gen_desig_revoke (ctrl_t ctrl, const char *uname, strlist_t locusr) afx = new_armor_context (); kdbhd = keydb_new (); + if (!kdbhd) + { + rc = gpg_error_from_syserror (); + goto leave; + } rc = classify_user_id (uname, &desc, 1); if (!rc) 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. */ kdbhd = keydb_new (); + if (!kdbhd) + { + rc = gpg_error_from_syserror (); + goto leave; + } rc = classify_user_id (uname, &desc, 1); if (!rc) rc = keydb_search (kdbhd, &desc, 1, NULL); diff --git a/g10/t-keydb-get-keyblock.c b/g10/t-keydb-get-keyblock.c index 2fbcb73e3..c12bab182 100644 --- a/g10/t-keydb-get-keyblock.c +++ b/g10/t-keydb-get-keyblock.c @@ -45,6 +45,8 @@ do_test (int argc, char *argv[]) ABORT ("Failed to open keyring."); hd1 = keydb_new (); + if (!hd1) + ABORT (""); rc = classify_user_id ("8061 5870 F5BA D690 3336 86D0 F2AD 85AC 1E42 B367", &desc1, 0); diff --git a/g10/t-keydb.c b/g10/t-keydb.c index 17a76111d..f0b7778b6 100644 --- a/g10/t-keydb.c +++ b/g10/t-keydb.c @@ -42,7 +42,11 @@ do_test (int argc, char *argv[]) ABORT ("Failed to open keyring."); hd1 = keydb_new (); + if (!hd1) + ABORT (""); hd2 = keydb_new (); + if (!hd2) + ABORT (""); rc = classify_user_id ("2689 5E25 E844 6D44 A26D 8FAF 2F79 98F3 DBFC 6AD9", &desc1, 0); diff --git a/g10/trustdb.c b/g10/trustdb.c index fbb806d85..af839d1e8 100644 --- a/g10/trustdb.c +++ b/g10/trustdb.c @@ -1896,13 +1896,16 @@ validate_keys (int interactive) trust. */ keydb_rebuild_caches(0); + kdb = keydb_new (); + if (!kdb) + return gpg_error_from_syserror (); + start_time = make_timestamp (); next_expire = 0xffffffff; /* set next expire to the year 2106 */ stored = new_key_hash_table (); used = new_key_hash_table (); full_trust = new_key_hash_table (); - kdb = keydb_new (); reset_trust_records(); /* Fixme: Instead of always building a UTK list, we could just build it