From 5d13581f4737c18430f6572dd4ef486d1ad80dd1 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 10 Nov 2016 17:01:19 +0100 Subject: [PATCH] gpg,sm: Add STATUS_ERROR keydb_search and keydb_add-resource. * g10/keydb.c (keydb_add_resource): Make ANY_REGISTERED file-global. Write a STATUS_ERROR. (maybe_create_keyring_or_box): Check for non-accessible but existant file. (keydb_search): Write a STATUS_ERROR if no keyring has been registered but continue to return NOT_FOUND. * sm/keydb.c (keydb_add_resource): Rename ANY_PUBLIC to ANY_REGISTERED and make file-global. Write a STATUS_ERROR. (keydb_search): Write a STATUS_ERROR if no keyring has been registered but continue to return NOT_FOUND. Also add new arg CTRL and change all callers to pass it down. Signed-off-by: Werner Koch --- g10/keydb.c | 18 ++++++++++--- sm/call-agent.c | 2 +- sm/call-dirmngr.c | 8 +++--- sm/certchain.c | 66 ++++++++++++++++++++++++++++----------------- sm/certlist.c | 11 ++++---- sm/decrypt.c | 2 +- sm/delete.c | 6 ++--- sm/export.c | 6 ++--- sm/gpgsm.c | 6 ++--- sm/gpgsm.h | 5 +++- sm/import.c | 6 ++--- sm/keydb.c | 69 ++++++++++++++++++++++++++++------------------- sm/keydb.h | 25 +++++++++-------- sm/keylist.c | 7 +++-- sm/server.c | 15 ++++++++++- sm/sign.c | 6 ++--- sm/verify.c | 4 +-- 17 files changed, 163 insertions(+), 99 deletions(-) diff --git a/g10/keydb.c b/g10/keydb.c index 76850f963..1467b2d53 100644 --- a/g10/keydb.c +++ b/g10/keydb.c @@ -64,6 +64,8 @@ static int used_resources; to the struct resource_item's TOKEN. */ static void *primary_keydb; +/* Whether we have successfully registered any resource. */ +static int any_registered; /* This is a simple cache used to return the last result of a successful fingerprint search. This works only for keybox resources @@ -277,7 +279,7 @@ maybe_create_keyring_or_box (char *filename, int is_box, int force_create) /* A quick test whether the filename already exists. */ if (!access (filename, F_OK)) - return 0; + return !access (filename, R_OK)? 0 : gpg_error (GPG_ERR_EACCES); /* If we don't want to create a new file at all, there is no need to go any further - bail out right here. */ @@ -616,8 +618,6 @@ keydb_search_desc_dump (struct keydb_search_desc *desc) gpg_error_t keydb_add_resource (const char *url, unsigned int flags) { - /* Whether we have successfully registered a resource. */ - static int any_registered; /* The file named by the URL (i.e., without the prototype). */ const char *resname = url; @@ -819,7 +819,11 @@ keydb_add_resource (const char *url, unsigned int flags) leave: if (err) - log_error (_("keyblock resource '%s': %s\n"), filename, gpg_strerror (err)); + { + log_error (_("keyblock resource '%s': %s\n"), + filename, gpg_strerror (err)); + write_status_error ("add_keyblock_resource", err); + } else any_registered = 1; xfree (filename); @@ -1875,6 +1879,12 @@ keydb_search (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc, if (!hd) return gpg_error (GPG_ERR_INV_ARG); + if (!any_registered) + { + write_status_error ("keydb_search", gpg_error (GPG_ERR_KEYRING_OPEN)); + return gpg_error (GPG_ERR_NOT_FOUND); + } + if (DBG_CLOCK) log_clock ("keydb_search enter"); diff --git a/sm/call-agent.c b/sm/call-agent.c index 6dbaba534..11e6ae769 100644 --- a/sm/call-agent.c +++ b/sm/call-agent.c @@ -967,7 +967,7 @@ learn_cb (void *opaque, const void *buffer, size_t length) { int existed; - if (!keydb_store_cert (cert, 0, &existed)) + if (!keydb_store_cert (parm->ctrl, cert, 0, &existed)) { if (opt.verbose > 1 && existed) log_info ("certificate already in DB\n"); diff --git a/sm/call-dirmngr.c b/sm/call-dirmngr.c index dd566417c..d0250634a 100644 --- a/sm/call-dirmngr.c +++ b/sm/call-dirmngr.c @@ -78,6 +78,7 @@ struct lookup_parm_s { }; struct run_command_parm_s { + ctrl_t ctrl; assuan_context_t ctx; }; @@ -407,7 +408,7 @@ inq_certificate (void *opaque, const char *line) ksba_cert_t cert; - err = gpgsm_find_cert (line, ski, &cert); + err = gpgsm_find_cert (parm->ctrl, line, ski, &cert); if (err) { log_error ("certificate not found: %s\n", gpg_strerror (err)); @@ -580,7 +581,7 @@ gpgsm_dirmngr_isvalid (ctrl_t ctrl, if (!kh) rc = gpg_error (GPG_ERR_ENOMEM); if (!rc) - rc = keydb_search_fpr (kh, stparm.fpr); + rc = keydb_search_fpr (ctrl, kh, stparm.fpr); if (!rc) rc = keydb_get_cert (kh, &rspcert); if (rc) @@ -928,7 +929,7 @@ run_command_inq_cb (void *opaque, const char *line) if (!*line) return gpg_error (GPG_ERR_ASS_PARAMETER); - err = gpgsm_find_cert (line, NULL, &cert); + err = gpgsm_find_cert (parm->ctrl, line, NULL, &cert); if (err) { log_error ("certificate not found: %s\n", gpg_strerror (err)); @@ -1002,6 +1003,7 @@ gpgsm_dirmngr_run_command (ctrl_t ctrl, const char *command, if (rc) return rc; + parm.ctrl = ctrl; parm.ctx = dirmngr_ctx; len = strlen (command) + 1; diff --git a/sm/certchain.c b/sm/certchain.c index 1ac7228d6..083c3ad92 100644 --- a/sm/certchain.c +++ b/sm/certchain.c @@ -438,7 +438,7 @@ check_cert_policy (ksba_cert_t cert, int listmode, estream_t fplist) for an issuer ISSUER with a subjectKeyIdentifier of KEYID. Returns 0 on success or -1 when not found. */ static int -find_up_search_by_keyid (KEYDB_HANDLE kh, +find_up_search_by_keyid (ctrl_t ctrl, KEYDB_HANDLE kh, const char *issuer, ksba_sexp_t keyid) { int rc; @@ -448,7 +448,7 @@ find_up_search_by_keyid (KEYDB_HANDLE kh, ksba_isotime_t not_before, last_not_before; keydb_search_reset (kh); - while (!(rc = keydb_search_subject (kh, issuer))) + while (!(rc = keydb_search_subject (ctrl, kh, issuer))) { ksba_cert_release (cert); cert = NULL; rc = keydb_get_cert (kh, &cert); @@ -499,12 +499,20 @@ find_up_search_by_keyid (KEYDB_HANDLE kh, } +struct find_up_store_certs_s +{ + ctrl_t ctrl; + int count; +}; + static void find_up_store_certs_cb (void *cb_value, ksba_cert_t cert) { - if (keydb_store_cert (cert, 1, NULL)) + struct find_up_store_certs_s *parm = cb_value; + + if (keydb_store_cert (parm->ctrl, cert, 1, NULL)) log_error ("error storing issuer certificate as ephemeral\n"); - ++*(int*)cb_value; + parm->count++; } @@ -519,10 +527,13 @@ find_up_external (ctrl_t ctrl, KEYDB_HANDLE kh, { int rc; strlist_t names = NULL; - int count = 0; + struct find_up_store_certs_s find_up_store_certs_parm; char *pattern; const char *s; + find_up_store_certs_parm.ctrl = ctrl; + find_up_store_certs_parm.count = 0; + if (opt.verbose) log_info (_("looking up issuer at external location\n")); /* The Dirmngr process is confused about unknown attributes. As a @@ -539,17 +550,19 @@ find_up_external (ctrl_t ctrl, KEYDB_HANDLE kh, add_to_strlist (&names, pattern); xfree (pattern); - rc = gpgsm_dirmngr_lookup (ctrl, names, 0, find_up_store_certs_cb, &count); + rc = gpgsm_dirmngr_lookup (ctrl, names, 0, find_up_store_certs_cb, + &find_up_store_certs_parm); free_strlist (names); if (opt.verbose) - log_info (_("number of issuers matching: %d\n"), count); + log_info (_("number of issuers matching: %d\n"), + find_up_store_certs_parm.count); if (rc) { log_error ("external key lookup failed: %s\n", gpg_strerror (rc)); rc = -1; } - else if (!count) + else if (!find_up_store_certs_parm.count) rc = -1; else { @@ -558,11 +571,11 @@ find_up_external (ctrl_t ctrl, KEYDB_HANDLE kh, we temporary switch to ephemeral mode. */ old = keydb_set_ephemeral (kh, 1); if (keyid) - rc = find_up_search_by_keyid (kh, issuer, keyid); + rc = find_up_search_by_keyid (ctrl, kh, issuer, keyid); else { keydb_search_reset (kh); - rc = keydb_search_subject (kh, issuer); + rc = keydb_search_subject (ctrl, kh, issuer); } keydb_set_ephemeral (kh, old); } @@ -581,11 +594,14 @@ find_up_dirmngr (ctrl_t ctrl, KEYDB_HANDLE kh, { int rc; strlist_t names = NULL; - int count = 0; + struct find_up_store_certs_s find_up_store_certs_parm; char *pattern; (void)kh; + find_up_store_certs_parm.ctrl = ctrl; + find_up_store_certs_parm.count = 0; + if (opt.verbose) log_info (_("looking up issuer from the Dirmngr cache\n")); if (subject_mode) @@ -607,15 +623,17 @@ find_up_dirmngr (ctrl_t ctrl, KEYDB_HANDLE kh, add_to_strlist (&names, pattern); xfree (pattern); - rc = gpgsm_dirmngr_lookup (ctrl, names, 1, find_up_store_certs_cb, &count); + rc = gpgsm_dirmngr_lookup (ctrl, names, 1, find_up_store_certs_cb, + &find_up_store_certs_parm); free_strlist (names); if (opt.verbose) - log_info (_("number of matching certificates: %d\n"), count); + log_info (_("number of matching certificates: %d\n"), + find_up_store_certs_parm.count); if (rc && !opt.quiet) log_info (_("dirmngr cache-only key lookup failed: %s\n"), gpg_strerror (rc)); - return (!rc && count)? 0 : -1; + return (!rc && find_up_store_certs_parm.count)? 0 : -1; } @@ -642,7 +660,7 @@ find_up (ctrl_t ctrl, KEYDB_HANDLE kh, const char *s = ksba_name_enum (authid, 0); if (s && *authidno) { - rc = keydb_search_issuer_sn (kh, s, authidno); + rc = keydb_search_issuer_sn (ctrl, kh, s, authidno); if (rc) keydb_search_reset (kh); @@ -665,7 +683,7 @@ find_up (ctrl_t ctrl, KEYDB_HANDLE kh, int old = keydb_set_ephemeral (kh, 1); if (!old) { - rc = keydb_search_issuer_sn (kh, s, authidno); + rc = keydb_search_issuer_sn (ctrl, kh, s, authidno); if (rc) keydb_search_reset (kh); @@ -685,14 +703,14 @@ find_up (ctrl_t ctrl, KEYDB_HANDLE kh, subject and stop for the one with a matching subjectKeyIdentifier. */ /* Fixme: Should we also search in the dirmngr? */ - rc = find_up_search_by_keyid (kh, issuer, keyid); + rc = find_up_search_by_keyid (ctrl, kh, issuer, keyid); if (!rc && DBG_X509) log_debug (" found via authid and keyid\n"); if (rc) { int old = keydb_set_ephemeral (kh, 1); if (!old) - rc = find_up_search_by_keyid (kh, issuer, keyid); + rc = find_up_search_by_keyid (ctrl, kh, issuer, keyid); if (!rc && DBG_X509) log_debug (" found via authid and keyid (ephem)\n"); keydb_set_ephemeral (kh, old); @@ -709,11 +727,11 @@ find_up (ctrl_t ctrl, KEYDB_HANDLE kh, { int old = keydb_set_ephemeral (kh, 1); if (keyid) - rc = find_up_search_by_keyid (kh, issuer, keyid); + rc = find_up_search_by_keyid (ctrl, kh, issuer, keyid); else { keydb_search_reset (kh); - rc = keydb_search_subject (kh, issuer); + rc = keydb_search_subject (ctrl, kh, issuer); } keydb_set_ephemeral (kh, old); } @@ -765,7 +783,7 @@ find_up (ctrl_t ctrl, KEYDB_HANDLE kh, } if (rc) /* Not found via authorithyKeyIdentifier, try regular issuer name. */ - rc = keydb_search_subject (kh, issuer); + rc = keydb_search_subject (ctrl, kh, issuer); if (rc == -1 && !find_next) { int old; @@ -779,7 +797,7 @@ find_up (ctrl_t ctrl, KEYDB_HANDLE kh, if (!old) { keydb_search_reset (kh); - rc = keydb_search_subject (kh, issuer); + rc = keydb_search_subject (ctrl, kh, issuer); } keydb_set_ephemeral (kh, old); @@ -983,7 +1001,7 @@ is_cert_still_valid (ctrl_t ctrl, int force_ocsp, int lm, estream_t fp, /* Store that in the keybox so that key listings are able to return the revoked flag. We don't care about error, though. */ - keydb_set_cert_flags (subject_cert, 1, KEYBOX_FLAG_VALIDITY, 0, + keydb_set_cert_flags (ctrl, subject_cert, 1, KEYBOX_FLAG_VALIDITY, 0, ~0, VALIDITY_REVOKED); break; @@ -1786,7 +1804,7 @@ do_validate_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t checktime_arg, been stored in the keybox and thus the flag can't be set. We ignore this error because it will later be stored anyway. */ - err = keydb_set_cert_flags (ci->cert, 1, KEYBOX_FLAG_BLOB, 0, + err = keydb_set_cert_flags (ctrl, ci->cert, 1, KEYBOX_FLAG_BLOB, 0, KEYBOX_FLAG_BLOB_EPHEMERAL, 0); if (!ci->next && gpg_err_code (err) == GPG_ERR_NOT_FOUND) ; diff --git a/sm/certlist.c b/sm/certlist.c index a041a75de..7baec6557 100644 --- a/sm/certlist.c +++ b/sm/certlist.c @@ -329,7 +329,7 @@ gpgsm_add_to_certlist (ctrl_t ctrl, const char *name, int secret, char *first_issuer = NULL; get_next: - rc = keydb_search (kh, &desc, 1); + rc = keydb_search (ctrl, kh, &desc, 1); if (!rc) rc = keydb_get_cert (kh, &cert); if (!rc) @@ -376,7 +376,7 @@ gpgsm_add_to_certlist (ctrl_t ctrl, const char *name, int secret, certlist_t dup_certs = NULL; next_ambigious: - rc = keydb_search (kh, &desc, 1); + rc = keydb_search (ctrl, kh, &desc, 1); if (rc == -1) rc = 0; else if (!rc) @@ -488,7 +488,8 @@ gpgsm_release_certlist (certlist_t list) additional filter value which must match the subjectKeyIdentifier. */ int -gpgsm_find_cert (const char *name, ksba_sexp_t keyid, ksba_cert_t *r_cert) +gpgsm_find_cert (ctrl_t ctrl, + const char *name, ksba_sexp_t keyid, ksba_cert_t *r_cert) { int rc; KEYDB_SEARCH_DESC desc; @@ -504,7 +505,7 @@ gpgsm_find_cert (const char *name, ksba_sexp_t keyid, ksba_cert_t *r_cert) else { nextone: - rc = keydb_search (kh, &desc, 1); + rc = keydb_search (ctrl, kh, &desc, 1); if (!rc) { rc = keydb_get_cert (kh, r_cert); @@ -537,7 +538,7 @@ gpgsm_find_cert (const char *name, ksba_sexp_t keyid, ksba_cert_t *r_cert) if (!rc && !keyid) { next_ambiguous: - rc = keydb_search (kh, &desc, 1); + rc = keydb_search (ctrl, kh, &desc, 1); if (rc == -1) rc = 0; else diff --git a/sm/decrypt.c b/sm/decrypt.c index 9ae87d8cf..11c1cf844 100644 --- a/sm/decrypt.c +++ b/sm/decrypt.c @@ -400,7 +400,7 @@ gpgsm_decrypt (ctrl_t ctrl, int in_fd, estream_t out_fp) } keydb_search_reset (kh); - rc = keydb_search_issuer_sn (kh, issuer, serial); + rc = keydb_search_issuer_sn (ctrl, kh, issuer, serial); if (rc) { log_error ("failed to find the certificate: %s\n", diff --git a/sm/delete.c b/sm/delete.c index ae06261a2..35369683b 100644 --- a/sm/delete.c +++ b/sm/delete.c @@ -72,7 +72,7 @@ delete_one (ctrl_t ctrl, const char *username) keydb_set_ephemeral (kh, 1); } - rc = keydb_search (kh, &desc, 1); + rc = keydb_search (ctrl, kh, &desc, 1); if (!rc) rc = keydb_get_cert (kh, &cert); if (!rc && !is_ephem) @@ -82,7 +82,7 @@ delete_one (ctrl_t ctrl, const char *username) gpgsm_get_fingerprint (cert, 0, fpr, NULL); next_ambigious: - rc = keydb_search (kh, &desc, 1); + rc = keydb_search (ctrl, kh, &desc, 1); if (rc == -1) rc = 0; else if (!rc) @@ -126,7 +126,7 @@ delete_one (ctrl_t ctrl, const char *username) do { keydb_search_reset (kh); - rc = keydb_search (kh, &desc, 1); + rc = keydb_search (ctrl, kh, &desc, 1); if (rc) { log_error ("problem re-searching certificate: %s\n", diff --git a/sm/export.c b/sm/export.c index 4fedfa209..a32414edb 100644 --- a/sm/export.c +++ b/sm/export.c @@ -206,7 +206,7 @@ gpgsm_export (ctrl_t ctrl, strlist_t names, estream_t stream) keydb_set_ephemeral (hd, 1); } - while (!(rc = keydb_search (hd, desc, ndesc))) + while (!(rc = keydb_search (ctrl, hd, desc, ndesc))) { unsigned char fpr[20]; int exists; @@ -362,7 +362,7 @@ gpgsm_p12_export (ctrl_t ctrl, const char *name, estream_t stream, int rawmode) } /* Lookup the certificate and make sure that it is unique. */ - err = keydb_search (hd, desc, 1); + err = keydb_search (ctrl, hd, desc, 1); if (!err) { err = keydb_get_cert (hd, &cert); @@ -373,7 +373,7 @@ gpgsm_p12_export (ctrl_t ctrl, const char *name, estream_t stream, int rawmode) } next_ambiguous: - err = keydb_search (hd, desc, 1); + err = keydb_search (ctrl, hd, desc, 1); if (!err) { ksba_cert_t cert2 = NULL; diff --git a/sm/gpgsm.c b/sm/gpgsm.c index ae447eee7..d012465e6 100644 --- a/sm/gpgsm.c +++ b/sm/gpgsm.c @@ -1616,7 +1616,7 @@ main ( int argc, char **argv) { int created; - keydb_add_resource ("pubring.kbx", 0, &created); + keydb_add_resource (&ctrl, "pubring.kbx", 0, &created); if (created && !no_common_certs_import) { /* Import the standard certificates for a new default keybox. */ @@ -1634,7 +1634,7 @@ main ( int argc, char **argv) } } for (sl = nrings; sl; sl = sl->next) - keydb_add_resource (sl->d, 0, NULL); + keydb_add_resource (&ctrl, sl->d, 0, NULL); FREE_STRLIST(nrings); @@ -1996,7 +1996,7 @@ main ( int argc, char **argv) ksba_cert_t cert = NULL; char *grip = NULL; - rc = gpgsm_find_cert (*argv, NULL, &cert); + rc = gpgsm_find_cert (&ctrl, *argv, NULL, &cert); if (rc) ; else if (!(grip = gpgsm_get_keygrip_hexstring (cert))) diff --git a/sm/gpgsm.h b/sm/gpgsm.h index 88db67070..76ff327de 100644 --- a/sm/gpgsm.h +++ b/sm/gpgsm.h @@ -244,6 +244,8 @@ gpg_error_t gpgsm_status (ctrl_t ctrl, int no, const char *text); gpg_error_t gpgsm_status2 (ctrl_t ctrl, int no, ...) GPGRT_ATTR_SENTINEL(0); gpg_error_t gpgsm_status_with_err_code (ctrl_t ctrl, int no, const char *text, gpg_err_code_t ec); +gpg_error_t gpgsm_status_with_error (ctrl_t ctrl, int no, const char *text, + gpg_error_t err); gpg_error_t gpgsm_proxy_pinentry_notify (ctrl_t ctrl, const unsigned char *line); @@ -339,7 +341,8 @@ int gpgsm_add_cert_to_certlist (ctrl_t ctrl, ksba_cert_t cert, int gpgsm_add_to_certlist (ctrl_t ctrl, const char *name, int secret, certlist_t *listaddr, int is_encrypt_to); void gpgsm_release_certlist (certlist_t list); -int gpgsm_find_cert (const char *name, ksba_sexp_t keyid, ksba_cert_t *r_cert); +int gpgsm_find_cert (ctrl_t ctrl, const char *name, ksba_sexp_t keyid, + ksba_cert_t *r_cert); /*-- keylist.c --*/ gpg_error_t gpgsm_list_keys (ctrl_t ctrl, strlist_t names, diff --git a/sm/import.c b/sm/import.c index bd1af27a2..4a8ecf73c 100644 --- a/sm/import.c +++ b/sm/import.c @@ -199,7 +199,7 @@ check_and_store (ctrl_t ctrl, struct stats_s *stats, { int existed; - if (!keydb_store_cert (cert, 0, &existed)) + if (!keydb_store_cert (ctrl, cert, 0, &existed)) { ksba_cert_t next = NULL; @@ -442,7 +442,7 @@ reimport_one (ctrl_t ctrl, struct stats_s *stats, int in_fd) } keydb_search_reset (kh); - err = keydb_search (kh, &desc, 1); + err = keydb_search (ctrl, kh, &desc, 1); if (err) { print_import_problem (ctrl, NULL, 0); @@ -476,7 +476,7 @@ reimport_one (ctrl_t ctrl, struct stats_s *stats, int in_fd) continue; } - err = keydb_set_cert_flags (cert, 1, KEYBOX_FLAG_BLOB, 0, + err = keydb_set_cert_flags (ctrl, cert, 1, KEYBOX_FLAG_BLOB, 0, KEYBOX_FLAG_BLOB_EPHEMERAL, 0); if (err) { diff --git a/sm/keydb.c b/sm/keydb.c index 64b06e74a..44dd9ca14 100644 --- a/sm/keydb.c +++ b/sm/keydb.c @@ -53,6 +53,10 @@ struct resource_item { static struct resource_item all_resources[MAX_KEYDB_RESOURCES]; static int used_resources; +/* Whether we have successfully registered any resource. */ +static int any_registered; + + struct keydb_handle { int locked; int found; @@ -121,7 +125,7 @@ maybe_create_keybox (char *filename, int force, int *r_created) /* A quick test whether the filename already exists. */ if (!access (filename, F_OK)) - return 0; + return !access (filename, R_OK)? 0 : gpg_error (GPG_ERR_EACCES); /* If we don't want to create a new file at all, there is no need to go any further - bail out right here. */ @@ -249,9 +253,8 @@ maybe_create_keybox (char *filename, int force, int *r_created) * if the function has created a new keybox. */ gpg_error_t -keydb_add_resource (const char *url, int force, int *auto_created) +keydb_add_resource (ctrl_t ctrl, const char *url, int force, int *auto_created) { - static int any_public; const char *resname = url; char *filename = NULL; gpg_error_t err = 0; @@ -292,7 +295,7 @@ keydb_add_resource (const char *url, int force, int *auto_created) filename = xstrdup (resname); if (!force) - force = !any_public; + force = !any_registered; /* see whether we can determine the filetype */ if (rt == KEYDB_RESOURCE_TYPE_NONE) @@ -380,9 +383,13 @@ keydb_add_resource (const char *url, int force, int *auto_created) leave: if (err) - log_error ("keyblock resource '%s': %s\n", filename, gpg_strerror (err)); + { + log_error ("keyblock resource '%s': %s\n", filename, gpg_strerror (err)); + gpgsm_status_with_error (ctrl, STATUS_ERROR, + "add_keyblock_resource", err); + } else - any_public = 1; + any_registered = 1; xfree (filename); return err; } @@ -962,7 +969,8 @@ keydb_search_reset (KEYDB_HANDLE hd) * for a keyblock which contains one of the keys described in the DESC array. */ int -keydb_search (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc, size_t ndesc) +keydb_search (ctrl_t ctrl, KEYDB_HANDLE hd, + KEYDB_SEARCH_DESC *desc, size_t ndesc) { int rc = -1; unsigned long skipped; @@ -970,6 +978,13 @@ keydb_search (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc, size_t ndesc) if (!hd) return gpg_error (GPG_ERR_INV_VALUE); + if (!any_registered) + { + gpgsm_status_with_error (ctrl, STATUS_ERROR, "keydb_search", + gpg_error (GPG_ERR_KEYRING_OPEN)); + return gpg_error (GPG_ERR_NOT_FOUND); + } + while (rc == -1 && hd->current >= 0 && hd->current < hd->used) { switch (hd->active[hd->current].type) @@ -996,27 +1011,27 @@ keydb_search (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc, size_t ndesc) int -keydb_search_first (KEYDB_HANDLE hd) +keydb_search_first (ctrl_t ctrl, KEYDB_HANDLE hd) { KEYDB_SEARCH_DESC desc; memset (&desc, 0, sizeof desc); desc.mode = KEYDB_SEARCH_MODE_FIRST; - return keydb_search (hd, &desc, 1); + return keydb_search (ctrl, hd, &desc, 1); } int -keydb_search_next (KEYDB_HANDLE hd) +keydb_search_next (ctrl_t ctrl, KEYDB_HANDLE hd) { KEYDB_SEARCH_DESC desc; memset (&desc, 0, sizeof desc); desc.mode = KEYDB_SEARCH_MODE_NEXT; - return keydb_search (hd, &desc, 1); + return keydb_search (ctrl, hd, &desc, 1); } int -keydb_search_kid (KEYDB_HANDLE hd, u32 *kid) +keydb_search_kid (ctrl_t ctrl, KEYDB_HANDLE hd, u32 *kid) { KEYDB_SEARCH_DESC desc; @@ -1026,22 +1041,22 @@ keydb_search_kid (KEYDB_HANDLE hd, u32 *kid) desc.mode = KEYDB_SEARCH_MODE_LONG_KID; desc.u.kid[0] = kid[0]; desc.u.kid[1] = kid[1]; - return keydb_search (hd, &desc, 1); + return keydb_search (ctrl, hd, &desc, 1); } int -keydb_search_fpr (KEYDB_HANDLE hd, const byte *fpr) +keydb_search_fpr (ctrl_t ctrl, KEYDB_HANDLE hd, const byte *fpr) { KEYDB_SEARCH_DESC desc; memset (&desc, 0, sizeof desc); desc.mode = KEYDB_SEARCH_MODE_FPR; memcpy (desc.u.fpr, fpr, 20); - return keydb_search (hd, &desc, 1); + return keydb_search (ctrl, hd, &desc, 1); } int -keydb_search_issuer (KEYDB_HANDLE hd, const char *issuer) +keydb_search_issuer (ctrl_t ctrl, KEYDB_HANDLE hd, const char *issuer) { KEYDB_SEARCH_DESC desc; int rc; @@ -1049,12 +1064,12 @@ keydb_search_issuer (KEYDB_HANDLE hd, const char *issuer) memset (&desc, 0, sizeof desc); desc.mode = KEYDB_SEARCH_MODE_ISSUER; desc.u.name = issuer; - rc = keydb_search (hd, &desc, 1); + rc = keydb_search (ctrl, hd, &desc, 1); return rc; } int -keydb_search_issuer_sn (KEYDB_HANDLE hd, +keydb_search_issuer_sn (ctrl_t ctrl, KEYDB_HANDLE hd, const char *issuer, ksba_const_sexp_t serial) { KEYDB_SEARCH_DESC desc; @@ -1073,12 +1088,12 @@ keydb_search_issuer_sn (KEYDB_HANDLE hd, return gpg_error (GPG_ERR_INV_VALUE); desc.sn = s+1; desc.u.name = issuer; - rc = keydb_search (hd, &desc, 1); + rc = keydb_search (ctrl, hd, &desc, 1); return rc; } int -keydb_search_subject (KEYDB_HANDLE hd, const char *name) +keydb_search_subject (ctrl_t ctrl, KEYDB_HANDLE hd, const char *name) { KEYDB_SEARCH_DESC desc; int rc; @@ -1086,7 +1101,7 @@ keydb_search_subject (KEYDB_HANDLE hd, const char *name) memset (&desc, 0, sizeof desc); desc.mode = KEYDB_SEARCH_MODE_SUBJECT; desc.u.name = name; - rc = keydb_search (hd, &desc, 1); + rc = keydb_search (ctrl, hd, &desc, 1); return rc; } @@ -1097,7 +1112,7 @@ keydb_search_subject (KEYDB_HANDLE hd, const char *name) If EXISTED is not NULL it will be set to true if the certificate was already in the DB. */ int -keydb_store_cert (ksba_cert_t cert, int ephemeral, int *existed) +keydb_store_cert (ctrl_t ctrl, ksba_cert_t cert, int ephemeral, int *existed) { KEYDB_HANDLE kh; int rc; @@ -1127,7 +1142,7 @@ keydb_store_cert (ksba_cert_t cert, int ephemeral, int *existed) if (rc) return rc; - rc = keydb_search_fpr (kh, fpr); + rc = keydb_search_fpr (ctrl, kh, fpr); if (rc != -1) { keydb_release (kh); @@ -1139,7 +1154,7 @@ keydb_store_cert (ksba_cert_t cert, int ephemeral, int *existed) { /* Remove ephemeral flags from existing certificate to "store" it permanently. */ - rc = keydb_set_cert_flags (cert, 1, KEYBOX_FLAG_BLOB, 0, + rc = keydb_set_cert_flags (ctrl, cert, 1, KEYBOX_FLAG_BLOB, 0, KEYBOX_FLAG_BLOB_EPHEMERAL, 0); if (rc) { @@ -1183,7 +1198,7 @@ keydb_store_cert (ksba_cert_t cert, int ephemeral, int *existed) transaction by locating the certificate in the DB and updating the flags. */ gpg_error_t -keydb_set_cert_flags (ksba_cert_t cert, int ephemeral, +keydb_set_cert_flags (ctrl_t ctrl, ksba_cert_t cert, int ephemeral, int which, int idx, unsigned int mask, unsigned int value) { @@ -1216,7 +1231,7 @@ keydb_set_cert_flags (ksba_cert_t cert, int ephemeral, return err; } - err = keydb_search_fpr (kh, fpr); + err = keydb_search_fpr (ctrl, kh, fpr); if (err) { if (err == -1) @@ -1313,7 +1328,7 @@ keydb_clear_some_cert_flags (ctrl_t ctrl, strlist_t names) goto leave; } - while (!(rc = keydb_search (hd, desc, ndesc))) + while (!(rc = keydb_search (ctrl, hd, desc, ndesc))) { if (!names) desc[0].mode = KEYDB_SEARCH_MODE_NEXT; diff --git a/sm/keydb.h b/sm/keydb.h index bdf4a2de7..623462553 100644 --- a/sm/keydb.h +++ b/sm/keydb.h @@ -31,7 +31,8 @@ typedef struct keydb_handle *KEYDB_HANDLE; /*-- keydb.c --*/ -gpg_error_t keydb_add_resource (const char *url, int force, int *auto_created); +gpg_error_t keydb_add_resource (ctrl_t ctrl, const char *url, + int force, int *auto_created); KEYDB_HANDLE keydb_new (void); void keydb_release (KEYDB_HANDLE hd); int keydb_set_ephemeral (KEYDB_HANDLE hd, int yes); @@ -54,18 +55,20 @@ int keydb_locate_writable (KEYDB_HANDLE hd, const char *reserved); void keydb_rebuild_caches (void); gpg_error_t keydb_search_reset (KEYDB_HANDLE hd); -int keydb_search (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc, size_t ndesc); -int keydb_search_first (KEYDB_HANDLE hd); -int keydb_search_next (KEYDB_HANDLE hd); -int keydb_search_kid (KEYDB_HANDLE hd, u32 *kid); -int keydb_search_fpr (KEYDB_HANDLE hd, const byte *fpr); -int keydb_search_issuer (KEYDB_HANDLE hd, const char *issuer); -int keydb_search_issuer_sn (KEYDB_HANDLE hd, +int keydb_search (ctrl_t ctrl, KEYDB_HANDLE hd, + KEYDB_SEARCH_DESC *desc, size_t ndesc); +int keydb_search_first (ctrl_t ctrl, KEYDB_HANDLE hd); +int keydb_search_next (ctrl_t ctrl, KEYDB_HANDLE hd); +int keydb_search_kid (ctrl_t ctrl, KEYDB_HANDLE hd, u32 *kid); +int keydb_search_fpr (ctrl_t ctrl, KEYDB_HANDLE hd, const byte *fpr); +int keydb_search_issuer (ctrl_t ctrl, KEYDB_HANDLE hd, const char *issuer); +int keydb_search_issuer_sn (ctrl_t ctrl, KEYDB_HANDLE hd, const char *issuer, const unsigned char *serial); -int keydb_search_subject (KEYDB_HANDLE hd, const char *issuer); +int keydb_search_subject (ctrl_t ctrl, KEYDB_HANDLE hd, const char *issuer); -int keydb_store_cert (ksba_cert_t cert, int ephemeral, int *existed); -gpg_error_t keydb_set_cert_flags (ksba_cert_t cert, int ephemeral, +int keydb_store_cert (ctrl_t ctrl, ksba_cert_t cert, int ephemeral, + int *existed); +gpg_error_t keydb_set_cert_flags (ctrl_t ctrl, ksba_cert_t cert, int ephemeral, int which, int idx, unsigned int mask, unsigned int value); diff --git a/sm/keylist.c b/sm/keylist.c index 7bd20dd39..88a9c4fef 100644 --- a/sm/keylist.c +++ b/sm/keylist.c @@ -1401,7 +1401,7 @@ list_internal_keys (ctrl_t ctrl, strlist_t names, estream_t fp, /* Suppress duplicates at least when they follow each other. */ lastresname = NULL; - while (!(rc = keydb_search (hd, desc, ndesc))) + while (!(rc = keydb_search (ctrl, hd, desc, ndesc))) { unsigned int validity; @@ -1462,8 +1462,7 @@ list_internal_keys (ctrl_t ctrl, strlist_t names, estream_t fp, } } - if (!mode - || ((mode & 1) && !have_secret) + if (!mode || ((mode & 1) && !have_secret) || ((mode & 2) && have_secret) ) { if (ctrl->with_colons) @@ -1507,7 +1506,7 @@ list_external_cb (void *cb_value, ksba_cert_t cert) { struct list_external_parm_s *parm = cb_value; - if (keydb_store_cert (cert, 1, NULL)) + if (keydb_store_cert (parm->ctrl, cert, 1, NULL)) log_error ("error storing certificate as ephemeral\n"); if (parm->print_header) diff --git a/sm/server.c b/sm/server.c index d6a2dbbdd..0fadcadd9 100644 --- a/sm/server.c +++ b/sm/server.c @@ -1179,7 +1179,7 @@ cmd_passwd (assuan_context_t ctx, char *line) line = skip_options (line); - err = gpgsm_find_cert (line, NULL, &cert); + err = gpgsm_find_cert (ctrl, line, NULL, &cert); if (err) ; else if (!(grip = gpgsm_get_keygrip_hexstring (cert))) @@ -1469,6 +1469,19 @@ gpgsm_status_with_err_code (ctrl_t ctrl, int no, const char *text, return gpgsm_status2 (ctrl, no, buf, NULL); } +gpg_error_t +gpgsm_status_with_error (ctrl_t ctrl, int no, const char *text, + gpg_error_t err) +{ + char buf[30]; + + snprintf (buf, sizeof buf, "%u", err); + if (text) + return gpgsm_status2 (ctrl, no, text, buf, NULL); + else + return gpgsm_status2 (ctrl, no, buf, NULL); +} + /* Helper to notify the client about Pinentry events. Because that might disturb some older clients, this is only done when enabled diff --git a/sm/sign.c b/sm/sign.c index ff7215fe3..9153d588c 100644 --- a/sm/sign.c +++ b/sm/sign.c @@ -144,7 +144,7 @@ gpgsm_get_default_cert (ctrl_t ctrl, ksba_cert_t *r_cert) hd = keydb_new (); if (!hd) return gpg_error (GPG_ERR_GENERAL); - rc = keydb_search_first (hd); + rc = keydb_search_first (ctrl, hd); if (rc) { keydb_release (hd); @@ -180,7 +180,7 @@ gpgsm_get_default_cert (ctrl_t ctrl, ksba_cert_t *r_cert) ksba_cert_release (cert); cert = NULL; } - while (!(rc = keydb_search_next (hd))); + while (!(rc = keydb_search_next (ctrl, hd))); if (rc && rc != -1) log_error ("keydb_search_next failed: %s\n", gpg_strerror (rc)); @@ -222,7 +222,7 @@ get_default_signer (ctrl_t ctrl) if (!kh) return NULL; - rc = keydb_search (kh, &desc, 1); + rc = keydb_search (ctrl, kh, &desc, 1); if (rc) { log_debug ("failed to find default certificate: rc=%d\n", rc); diff --git a/sm/verify.c b/sm/verify.c index 7a9f7e163..a04688375 100644 --- a/sm/verify.c +++ b/sm/verify.c @@ -270,7 +270,7 @@ gpgsm_verify (ctrl_t ctrl, int in_fd, int data_fd, estream_t out_fp) we would avoid cluttering the DB with invalid certificates. */ audit_log_cert (ctrl->audit, AUDIT_SAVE_CERT, cert, - keydb_store_cert (cert, 0, NULL)); + keydb_store_cert (ctrl, cert, 0, NULL)); ksba_cert_release (cert); } @@ -417,7 +417,7 @@ gpgsm_verify (ctrl_t ctrl, int in_fd, int data_fd, estream_t out_fp) /* Find the certificate of the signer */ keydb_search_reset (kh); - rc = keydb_search_issuer_sn (kh, issuer, serial); + rc = keydb_search_issuer_sn (ctrl, kh, issuer, serial); if (rc) { if (rc == -1)