mirror of
git://git.gnupg.org/gnupg.git
synced 2025-01-02 12:01:32 +01:00
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:
parent
d2ad715441
commit
460e3812be
@ -1105,7 +1105,7 @@ cmd_ldapserver (assuan_context_t ctx, char *line)
|
|||||||
|
|
||||||
static const char hlp_isvalid[] =
|
static const char hlp_isvalid[] =
|
||||||
"ISVALID [--only-ocsp] [--force-default-responder]"
|
"ISVALID [--only-ocsp] [--force-default-responder]"
|
||||||
" <certificate_id>|<certificate_fpr>\n"
|
" <certificate_id> [<certificate_fpr>]\n"
|
||||||
"\n"
|
"\n"
|
||||||
"This command checks whether the certificate identified by the\n"
|
"This command checks whether the certificate identified by the\n"
|
||||||
"certificate_id is valid. This is done by consulting CRLs or\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"
|
"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"
|
"issuer name and the second part the serial number.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Alternatively the certificate's fingerprint may be given in which\n"
|
"If an OCSP check is desired CERTIFICATE_FPR with the hex encoded\n"
|
||||||
"case an OCSP request is done before consulting the CRL.\n"
|
"fingerprint of the certificate is required. In this case an OCSP\n"
|
||||||
|
"request is done before consulting the CRL.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"If the option --only-ocsp is given, no fallback to a CRL check will\n"
|
"If the option --only-ocsp is given, no fallback to a CRL check will\n"
|
||||||
"be used.\n"
|
"be used.\n"
|
||||||
@ -1130,7 +1131,7 @@ static gpg_error_t
|
|||||||
cmd_isvalid (assuan_context_t ctx, char *line)
|
cmd_isvalid (assuan_context_t ctx, char *line)
|
||||||
{
|
{
|
||||||
ctrl_t ctrl = assuan_get_pointer (ctx);
|
ctrl_t ctrl = assuan_get_pointer (ctx);
|
||||||
char *issuerhash, *serialno;
|
char *issuerhash, *serialno, *fpr;
|
||||||
gpg_error_t err;
|
gpg_error_t err;
|
||||||
int did_inquire = 0;
|
int did_inquire = 0;
|
||||||
int ocsp_mode = 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");
|
force_default_responder = has_option (line, "--force-default-responder");
|
||||||
line = skip_options (line);
|
line = skip_options (line);
|
||||||
|
|
||||||
issuerhash = xstrdup (line); /* We need to work on a copy of the
|
/* We need to work on a copy of the line because that same Assuan
|
||||||
line because that same Assuan
|
* context may be used for an inquiry. That is because Assuan
|
||||||
context may be used for an inquiry.
|
* reuses its line buffer. */
|
||||||
That is because Assuan reuses its
|
issuerhash = xstrdup (line);
|
||||||
line buffer.
|
|
||||||
*/
|
|
||||||
|
|
||||||
serialno = strchr (issuerhash, '.');
|
serialno = strchr (issuerhash, '.');
|
||||||
if (serialno)
|
if (!serialno)
|
||||||
*serialno++ = 0;
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
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)
|
if (endp)
|
||||||
*endp = 0;
|
*endp = 0;
|
||||||
if (strlen (issuerhash) != 40)
|
if (strlen (fpr) != 40)
|
||||||
{
|
{
|
||||||
xfree (issuerhash);
|
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;
|
ocsp_mode = 1;
|
||||||
}
|
}
|
||||||
@ -1168,17 +1180,24 @@ cmd_isvalid (assuan_context_t ctx, char *line)
|
|||||||
again:
|
again:
|
||||||
if (ocsp_mode)
|
if (ocsp_mode)
|
||||||
{
|
{
|
||||||
/* Note, that we ignore the given issuer hash and instead rely
|
/* Note, that we currently ignore the supplied fingerprint FPR;
|
||||||
on the current certificate semantics used with this
|
* instead ocsp_isvalid does an inquire to ask for the cert.
|
||||||
command. */
|
* The fingerprint may eventually be used to lookup the
|
||||||
|
* certificate in a local cache. */
|
||||||
if (!opt.allow_ocsp)
|
if (!opt.allow_ocsp)
|
||||||
err = gpg_error (GPG_ERR_NOT_SUPPORTED);
|
err = gpg_error (GPG_ERR_NOT_SUPPORTED);
|
||||||
else
|
else
|
||||||
err = ocsp_isvalid (ctrl, NULL, NULL, force_default_responder);
|
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
|
if (gpg_err_code (err) == GPG_ERR_CONFIGURATION
|
||||||
OCSP_MODE, get the issuerhash and the serialno from the
|
&& gpg_err_source (err) == GPG_ERR_SOURCE_DIRMNGR)
|
||||||
current certificate and jump to again. */
|
{
|
||||||
|
/* 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)
|
else if (only_ocsp)
|
||||||
err = gpg_error (GPG_ERR_NO_CRL_KNOWN);
|
err = gpg_error (GPG_ERR_NO_CRL_KNOWN);
|
||||||
|
@ -491,8 +491,8 @@ isvalid_status_cb (void *opaque, const char *line)
|
|||||||
|
|
||||||
Values for USE_OCSP:
|
Values for USE_OCSP:
|
||||||
0 = Do CRL check.
|
0 = Do CRL check.
|
||||||
1 = Do an OCSP check.
|
1 = Do an OCSP check but fallback to CRL unless CRLS are disabled.
|
||||||
2 = Do an OCSP check using only the default responder.
|
2 = Do only an OCSP check using only the default responder.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
gpgsm_dirmngr_isvalid (ctrl_t ctrl,
|
gpgsm_dirmngr_isvalid (ctrl_t ctrl,
|
||||||
@ -500,7 +500,7 @@ gpgsm_dirmngr_isvalid (ctrl_t ctrl,
|
|||||||
{
|
{
|
||||||
static int did_options;
|
static int did_options;
|
||||||
int rc;
|
int rc;
|
||||||
char *certid;
|
char *certid, *certfpr;
|
||||||
char line[ASSUAN_LINELENGTH];
|
char line[ASSUAN_LINELENGTH];
|
||||||
struct inq_certificate_parm_s parm;
|
struct inq_certificate_parm_s parm;
|
||||||
struct isvalid_status_parm_s stparm;
|
struct isvalid_status_parm_s stparm;
|
||||||
@ -509,19 +509,13 @@ gpgsm_dirmngr_isvalid (ctrl_t ctrl,
|
|||||||
if (rc)
|
if (rc)
|
||||||
return 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);
|
log_error ("error getting the certificate ID\n");
|
||||||
}
|
release_dirmngr (ctrl);
|
||||||
else
|
return gpg_error (GPG_ERR_GENERAL);
|
||||||
{
|
|
||||||
certid = gpgsm_get_certid (cert);
|
|
||||||
if (!certid)
|
|
||||||
{
|
|
||||||
log_error ("error getting the certificate ID\n");
|
|
||||||
release_dirmngr (ctrl);
|
|
||||||
return gpg_error (GPG_ERR_GENERAL);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opt.verbose > 1)
|
if (opt.verbose > 1)
|
||||||
@ -541,13 +535,8 @@ gpgsm_dirmngr_isvalid (ctrl_t ctrl,
|
|||||||
stparm.seen = 0;
|
stparm.seen = 0;
|
||||||
memset (stparm.fpr, 0, 20);
|
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
|
/* 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 (!did_options)
|
||||||
{
|
{
|
||||||
if (opt.force_crl_refresh)
|
if (opt.force_crl_refresh)
|
||||||
@ -555,10 +544,14 @@ gpgsm_dirmngr_isvalid (ctrl_t ctrl,
|
|||||||
NULL, NULL, NULL, NULL, NULL, NULL);
|
NULL, NULL, NULL, NULL, NULL, NULL);
|
||||||
did_options = 1;
|
did_options = 1;
|
||||||
}
|
}
|
||||||
snprintf (line, DIM(line), "ISVALID%s %s",
|
snprintf (line, DIM(line), "ISVALID%s%s %s%s%s",
|
||||||
use_ocsp == 2? " --only-ocsp --force-default-responder":"",
|
use_ocsp == 2 || opt.no_crl_check ? " --only-ocsp":"",
|
||||||
certid);
|
use_ocsp == 2? " --force-default-responder":"",
|
||||||
|
certid,
|
||||||
|
use_ocsp? " ":"",
|
||||||
|
use_ocsp? certfpr:"");
|
||||||
xfree (certid);
|
xfree (certid);
|
||||||
|
xfree (certfpr);
|
||||||
|
|
||||||
rc = assuan_transact (dirmngr_ctx, line, NULL, NULL,
|
rc = assuan_transact (dirmngr_ctx, line, NULL, NULL,
|
||||||
inq_certificate, &parm,
|
inq_certificate, &parm,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user