aboutsummaryrefslogtreecommitdiffstats
path: root/dirmngr/server.c
diff options
context:
space:
mode:
Diffstat (limited to 'dirmngr/server.c')
-rw-r--r--dirmngr/server.c121
1 files changed, 95 insertions, 26 deletions
diff --git a/dirmngr/server.c b/dirmngr/server.c
index 60d980211..b7cdb24c9 100644
--- a/dirmngr/server.c
+++ b/dirmngr/server.c
@@ -1105,7 +1105,7 @@ cmd_ldapserver (assuan_context_t ctx, char *line)
static const char hlp_isvalid[] =
"ISVALID [--only-ocsp] [--force-default-responder]"
- " <certificate_id>|<certificate_fpr>\n"
+ " <certificate_id> [<certificate_fpr>]\n"
"\n"
"This command checks whether the certificate identified by the\n"
"certificate_id is valid. This is done by consulting CRLs or\n"
@@ -1117,8 +1117,9 @@ static const char hlp_isvalid[] =
"delimited by a single dot. The first part is the SHA-1 hash of the\n"
"issuer name and the second part the serial number.\n"
"\n"
- "Alternatively the certificate's fingerprint may be given in which\n"
- "case an OCSP request is done before consulting the CRL.\n"
+ "If an OCSP check is desired CERTIFICATE_FPR with the hex encoded\n"
+ "fingerprint of the certificate is required. In this case an OCSP\n"
+ "request is done before consulting the CRL.\n"
"\n"
"If the option --only-ocsp is given, no fallback to a CRL check will\n"
"be used.\n"
@@ -1130,7 +1131,7 @@ static gpg_error_t
cmd_isvalid (assuan_context_t ctx, char *line)
{
ctrl_t ctrl = assuan_get_pointer (ctx);
- char *issuerhash, *serialno;
+ char *issuerhash, *serialno, *fpr;
gpg_error_t err;
int did_inquire = 0;
int ocsp_mode = 0;
@@ -1141,25 +1142,36 @@ cmd_isvalid (assuan_context_t ctx, char *line)
force_default_responder = has_option (line, "--force-default-responder");
line = skip_options (line);
- issuerhash = xstrdup (line); /* We need to work on a copy of the
- line because that same Assuan
- context may be used for an inquiry.
- That is because Assuan reuses its
- line buffer.
- */
+ /* We need to work on a copy of the line because that same Assuan
+ * context may be used for an inquiry. That is because Assuan
+ * reuses its line buffer. */
+ issuerhash = xstrdup (line);
serialno = strchr (issuerhash, '.');
- if (serialno)
- *serialno++ = 0;
- else
+ if (!serialno)
+ {
+ xfree (issuerhash);
+ return leave_cmd (ctx, PARM_ERROR (_("serialno missing in cert ID")));
+ }
+ *serialno++ = 0;
+ if (strlen (issuerhash) != 40)
{
- char *endp = strchr (issuerhash, ' ');
+ xfree (issuerhash);
+ return leave_cmd (ctx, PARM_ERROR ("cert ID is too short"));
+ }
+
+ fpr = strchr (serialno, ' ');
+ while (fpr && spacep (fpr))
+ fpr++;
+ if (fpr && *fpr)
+ {
+ char *endp = strchr (fpr, ' ');
if (endp)
*endp = 0;
- if (strlen (issuerhash) != 40)
+ if (strlen (fpr) != 40)
{
xfree (issuerhash);
- return leave_cmd (ctx, PARM_ERROR (_("serialno missing in cert ID")));
+ return leave_cmd (ctx, PARM_ERROR ("fingerprint too short"));
}
ocsp_mode = 1;
}
@@ -1168,17 +1180,24 @@ cmd_isvalid (assuan_context_t ctx, char *line)
again:
if (ocsp_mode)
{
- /* Note, that we ignore the given issuer hash and instead rely
- on the current certificate semantics used with this
- command. */
+ /* Note, that we currently ignore the supplied fingerprint FPR;
+ * instead ocsp_isvalid does an inquire to ask for the cert.
+ * The fingerprint may eventually be used to lookup the
+ * certificate in a local cache. */
if (!opt.allow_ocsp)
err = gpg_error (GPG_ERR_NOT_SUPPORTED);
else
err = ocsp_isvalid (ctrl, NULL, NULL, force_default_responder);
- /* Fixme: If we got no ocsp response and --only-ocsp is not used
- we should fall back to CRL mode. Thus we need to clear
- OCSP_MODE, get the issuerhash and the serialno from the
- current certificate and jump to again. */
+
+ if (gpg_err_code (err) == GPG_ERR_CONFIGURATION
+ && gpg_err_source (err) == GPG_ERR_SOURCE_DIRMNGR)
+ {
+ /* No default responder configured - fallback to CRL. */
+ if (!only_ocsp)
+ log_info ("falling back to CRL check\n");
+ ocsp_mode = 0;
+ goto again;
+ }
}
else if (only_ocsp)
err = gpg_error (GPG_ERR_NO_CRL_KNOWN);
@@ -1858,7 +1877,7 @@ static const char hlp_validate[] =
" INQUIRE CERTLIST\n"
"\n"
"Here the first certificate is the target certificate, the remaining\n"
- "certificates are suggested intermediary certificates. All certifciates\n"
+ "certificates are suggested intermediary certificates. All certificates\n"
"need to be PEM encoded.\n"
"\n"
"The option --systrust changes the behaviour to include the system\n"
@@ -1909,7 +1928,7 @@ cmd_validate (assuan_context_t ctx, char *line)
err = gpg_error (GPG_ERR_MISSING_CERT);
if (!err)
{
- /* Extraxt the first certificate from the list. */
+ /* Extract the first certificate from the list. */
cert = certlist->cert;
ksba_cert_ref (cert);
}
@@ -1978,6 +1997,38 @@ make_keyserver_item (const char *uri, uri_item_t *r_item)
uri_item_t item;
*r_item = NULL;
+
+ /* We used to have DNS CNAME redirection from the URLs below to
+ * sks-keyserver. pools. The idea was to allow for a quick way to
+ * switch to a different set of pools. The problem with that
+ * approach is that TLS needs to verify the hostname and - because
+ * DNS is not secured - it can only check the user supplied hostname
+ * and not a hostname from a CNAME RR. Thus the final server all
+ * need to have certificates with the actual pool name as well as
+ * for keys.gnupg.net - that would render the advantage of
+ * keys.gnupg.net useless and so we better give up on this. Because
+ * the keys.gnupg.net URL are still in widespread use we do a static
+ * mapping here.
+ */
+ if (!strcmp (uri, "hkps://keys.gnupg.net")
+ || !strcmp (uri, "keys.gnupg.net"))
+ uri = "hkps://hkps.pool.sks-keyservers.net";
+ else if (!strcmp (uri, "https://keys.gnupg.net"))
+ uri = "https://hkps.pool.sks-keyservers.net";
+ else if (!strcmp (uri, "hkp://keys.gnupg.net"))
+ uri = "hkp://hkps.pool.sks-keyservers.net";
+ else if (!strcmp (uri, "http://keys.gnupg.net"))
+ uri = "http://hkps.pool.sks-keyservers.net";
+ else if (!strcmp (uri, "hkps://http-keys.gnupg.net")
+ || !strcmp (uri, "http-keys.gnupg.net"))
+ uri = "hkps://ha.pool.sks-keyservers.net";
+ else if (!strcmp (uri, "https://http-keys.gnupg.net"))
+ uri = "https://ha.pool.sks-keyservers.net";
+ else if (!strcmp (uri, "hkp://http-keys.gnupg.net"))
+ uri = "hkp://ha.pool.sks-keyservers.net";
+ else if (!strcmp (uri, "http://http-keys.gnupg.net"))
+ uri = "http://ha.pool.sks-keyservers.net";
+
item = xtrymalloc (sizeof *item + strlen (uri));
if (!item)
return gpg_error_from_syserror ();
@@ -2489,7 +2540,8 @@ static const char hlp_getinfo[] =
"dnsinfo - Return info about the DNS resolver\n"
"socket_name - Return the name of the socket.\n"
"session_id - Return the current session_id.\n"
- "workqueue - Inspect the work queue\n";
+ "workqueue - Inspect the work queue\n"
+ "getenv NAME - Return value of envvar NAME\n";
static gpg_error_t
cmd_getinfo (assuan_context_t ctx, char *line)
{
@@ -2557,6 +2609,23 @@ cmd_getinfo (assuan_context_t ctx, char *line)
workqueue_dump_queue (ctrl);
err = 0;
}
+ else if (!strncmp (line, "getenv", 6)
+ && (line[6] == ' ' || line[6] == '\t' || !line[6]))
+ {
+ line += 6;
+ while (*line == ' ' || *line == '\t')
+ line++;
+ if (!*line)
+ err = gpg_error (GPG_ERR_MISSING_VALUE);
+ else
+ {
+ const char *s = getenv (line);
+ if (!s)
+ err = set_error (GPG_ERR_NOT_FOUND, "No such envvar");
+ else
+ err = assuan_send_data (ctx, s, strlen (s));
+ }
+ }
else
err = set_error (GPG_ERR_ASS_PARAMETER, "unknown value for WHAT");