dirmngr: Fallback to CRL if no default OCSP responder is configured.

* dirmngr/server.c (cmd_isvalid): Use option second arg to trigger
OCSP checkibng.  Fallback to CRL if no default OCSP responder has been
configured.
* sm/call-dirmngr.c (gpgsm_dirmngr_isvalid): Adjust accordingly.

Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
Werner Koch 2018-04-24 11:40:51 +02:00
parent d2ad715441
commit 460e3812be
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B
2 changed files with 59 additions and 47 deletions

View File

@ -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)
{
char *endp = strchr (issuerhash, ' ');
xfree (issuerhash);
return leave_cmd (ctx, PARM_ERROR (_("serialno missing in cert ID")));
}
*serialno++ = 0;
if (strlen (issuerhash) != 40)
{
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);

View File

@ -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,