From df58e024e71b100a1557b1023d35b2a0092a8748 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Sat, 29 Jun 2002 14:01:53 +0000 Subject: * gpgsm.c: New option --auto-issuer-key-retrieve. * certpath.c (find_up): Try to retrieve an issuer key from an external source and from the ephemeral key DB. (find_up_store_certs_cb): New. * keydb.c (keydb_set_ephemeral): Does now return the old state. Call the backend only when required. * call-dirmngr.c (start_dirmngr): Use GNUPG_DEFAULT_DIRMNGR. (lookup_status_cb): Issue status only when CTRL is not NULL. (gpgsm_dirmngr_lookup): Document that CTRL is optional. * call-agent.c (start_agent): Use GNUPG_DEFAULT_AGENT. --- sm/certpath.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 80 insertions(+), 2 deletions(-) (limited to 'sm/certpath.c') diff --git a/sm/certpath.c b/sm/certpath.c index a32c2d7f7..0457a0aa1 100644 --- a/sm/certpath.c +++ b/sm/certpath.c @@ -196,6 +196,15 @@ check_cert_policy (KsbaCert cert) } +static void +find_up_store_certs_cb (void *cb_value, KsbaCert cert) +{ + if (keydb_store_cert (cert, 1)) + log_error ("error storing issuer certificate as ephemeral\n"); + ++*(int*)cb_value; +} + + static int find_up (KEYDB_HANDLE kh, KsbaCert cert, const char *issuer) { @@ -211,13 +220,82 @@ find_up (KEYDB_HANDLE kh, KsbaCert cert, const char *issuer) rc = keydb_search_issuer_sn (kh, s, authidno); if (rc) keydb_search_reset (kh); + if (rc == -1) + { /* And try the ephemeral DB. */ + int old = keydb_set_ephemeral (kh, 1); + if (!old) + { + rc = keydb_search_issuer_sn (kh, s, authidno); + if (rc) + keydb_search_reset (kh); + } + keydb_set_ephemeral (kh, old); + } } ksba_name_release (authid); xfree (authidno); + /* Fixme: don't know how to do dirmngr lookup with serial+issuer. */ } - if (rc) - rc = keydb_search_subject (kh, issuer); + if (rc) /* not found via authorithyKeyIdentifier, try regular issuer name */ + rc = keydb_search_subject (kh, issuer); + if (rc == -1) + { + /* Not found, lets see whether we have one in the ephemeral key DB. */ + int old = keydb_set_ephemeral (kh, 1); + if (!old) + { + keydb_search_reset (kh); + rc = keydb_search_subject (kh, issuer); + } + keydb_set_ephemeral (kh, old); + } + + if (rc == -1 && opt.auto_issuer_key_retrieve) + { + STRLIST names = NULL; + int count = 0; + char *pattern; + const char *s; + + if (opt.verbose) + log_info (_("looking up issuer at external location\n")); + /* dirmngr is confused about unknown attributes so has a quick + and ugly hack we locate the CN and use this and the + following. Fixme: we should have far ebtter parsing in the + dirmngr. */ + s = strstr (issuer, "CN="); + if (!s || s == issuer || s[-1] != ',') + s = issuer; + + pattern = xtrymalloc (strlen (s)+2); + if (!pattern) + return GNUPG_Out_Of_Core; + strcpy (stpcpy (pattern, "/"), s); + add_to_strlist (&names, pattern); + xfree (pattern); + rc = gpgsm_dirmngr_lookup (NULL, names, find_up_store_certs_cb, &count); + free_strlist (names); + if (opt.verbose) + log_info (_("number of issuers matching: %d\n"), count); + if (rc) + { + log_error ("external key lookup failed: %s\n", gnupg_strerror (rc)); + rc = -1; + } + else if (!count) + rc = -1; + else + { + int old; + /* The issuers are currently stored in the ephemeral key + DB, so we temporary switch to ephemeral mode. */ + old = keydb_set_ephemeral (kh, 1); + keydb_search_reset (kh); + rc = keydb_search_subject (kh, issuer); + keydb_set_ephemeral (kh, old); + } + } return rc; } -- cgit v1.2.3