aboutsummaryrefslogtreecommitdiffstats
path: root/sm/certpath.c
diff options
context:
space:
mode:
Diffstat (limited to 'sm/certpath.c')
-rw-r--r--sm/certpath.c82
1 files changed, 80 insertions, 2 deletions
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;
}