summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--dirmngr/server.c65
-rw-r--r--sm/call-dirmngr.c41
2 files changed, 59 insertions, 47 deletions
diff --git a/dirmngr/server.c b/dirmngr/server.c
index 4315c4133..48244d4af 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);
diff --git a/sm/call-dirmngr.c b/sm/call-dirmngr.c
index e94311892..3a38bca50 100644
--- a/sm/call-dirmngr.c
+++ b/sm/call-dirmngr.c
@@ -491,8 +491,8 @@ isvalid_status_cb (void *opaque, const char *line)
Values for USE_OCSP:
0 = Do CRL check.
- 1 = Do an OCSP check.
- 2 = Do an OCSP check using only the default responder.
+ 1 = Do an OCSP check but fallback to CRL unless CRLS are disabled.
+ 2 = Do only an OCSP check using only the default responder.
*/
int
gpgsm_dirmngr_isvalid (ctrl_t ctrl,
@@ -500,7 +500,7 @@ gpgsm_dirmngr_isvalid (ctrl_t ctrl,
{
static int did_options;
int rc;
- char *certid;
+ char *certid, *certfpr;
char line[ASSUAN_LINELENGTH];
struct inq_certificate_parm_s parm;
struct isvalid_status_parm_s stparm;
@@ -509,19 +509,13 @@ gpgsm_dirmngr_isvalid (ctrl_t ctrl,
if (rc)
return rc;
- if (use_ocsp)
+ certfpr = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA1);
+ certid = gpgsm_get_certid (cert);
+ if (!certid)
{
- certid = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA1);
- }
- else
- {
- certid = gpgsm_get_certid (cert);
- if (!certid)
- {
- log_error ("error getting the certificate ID\n");
- release_dirmngr (ctrl);
- return gpg_error (GPG_ERR_GENERAL);
- }
+ log_error ("error getting the certificate ID\n");
+ release_dirmngr (ctrl);
+ return gpg_error (GPG_ERR_GENERAL);
}
if (opt.verbose > 1)
@@ -541,13 +535,8 @@ gpgsm_dirmngr_isvalid (ctrl_t ctrl,
stparm.seen = 0;
memset (stparm.fpr, 0, 20);
- /* FIXME: If --disable-crl-checks has been set, we should pass an
- option to dirmngr, so that no fallback CRL check is done after an
- ocsp check. It is not a problem right now as dirmngr does not
- fallback to CRL checking. */
-
/* It is sufficient to send the options only once because we have
- one connection per process only. */
+ * one connection per process only. */
if (!did_options)
{
if (opt.force_crl_refresh)
@@ -555,10 +544,14 @@ gpgsm_dirmngr_isvalid (ctrl_t ctrl,
NULL, NULL, NULL, NULL, NULL, NULL);
did_options = 1;
}
- snprintf (line, DIM(line), "ISVALID%s %s",
- use_ocsp == 2? " --only-ocsp --force-default-responder":"",
- certid);
+ snprintf (line, DIM(line), "ISVALID%s%s %s%s%s",
+ use_ocsp == 2 || opt.no_crl_check ? " --only-ocsp":"",
+ use_ocsp == 2? " --force-default-responder":"",
+ certid,
+ use_ocsp? " ":"",
+ use_ocsp? certfpr:"");
xfree (certid);
+ xfree (certfpr);
rc = assuan_transact (dirmngr_ctx, line, NULL, NULL,
inq_certificate, &parm,