dirmngr: Distinguish between "no crl" and "crl not trusted".

* dirmngr/crlcache.h (CRL_CACHE_NOTTRUSTED): New.
* dirmngr/crlcache.c (cache_isvalid): Set this status.
(crl_cache_cert_isvalid): Map it to GPG_ERR_NOT_TRUSTED.
(crl_cache_reload_crl): Move diagnostic to ...
* dirmngr/crlfetch.c (crl_fetch): here.
* dirmngr/server.c (cmd_isvalid): Map it to GPG_ERR_NOT_TRUSTED.
* dirmngr/validate.c (check_revocations): Handle new status.  Improve
diagnostics.
* common/status.c (get_inv_recpsgnr_code): Map INV_CRL_OBJ.
* common/audit.c (proc_type_verify): Ditto.
--

This avoids repeated loading of CRLs in case of untrusted root
certificates.
This commit is contained in:
Werner Koch 2023-03-09 18:28:39 +01:00
parent 65288fc52f
commit b52a0e244a
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B
8 changed files with 33 additions and 12 deletions

View File

@ -1109,6 +1109,7 @@ proc_type_verify (audit_ctx_t ctx)
case GPG_ERR_CERT_REVOKED: ok = "bad"; break; case GPG_ERR_CERT_REVOKED: ok = "bad"; break;
case GPG_ERR_NOT_ENABLED: ok = "disabled"; break; case GPG_ERR_NOT_ENABLED: ok = "disabled"; break;
case GPG_ERR_NO_CRL_KNOWN: case GPG_ERR_NO_CRL_KNOWN:
case GPG_ERR_INV_CRL_OBJ:
ok = _("no CRL found for certificate"); ok = _("no CRL found for certificate");
break; break;
case GPG_ERR_CRL_TOO_OLD: case GPG_ERR_CRL_TOO_OLD:

View File

@ -158,7 +158,8 @@ get_inv_recpsgnr_code (gpg_error_t err)
case GPG_ERR_WRONG_KEY_USAGE: errstr = "3"; break; case GPG_ERR_WRONG_KEY_USAGE: errstr = "3"; break;
case GPG_ERR_CERT_REVOKED: errstr = "4"; break; case GPG_ERR_CERT_REVOKED: errstr = "4"; break;
case GPG_ERR_CERT_EXPIRED: errstr = "5"; break; case GPG_ERR_CERT_EXPIRED: errstr = "5"; break;
case GPG_ERR_NO_CRL_KNOWN: errstr = "6"; break; case GPG_ERR_NO_CRL_KNOWN:
case GPG_ERR_INV_CRL_OBJ: errstr = "6"; break;
case GPG_ERR_CRL_TOO_OLD: errstr = "7"; break; case GPG_ERR_CRL_TOO_OLD: errstr = "7"; break;
case GPG_ERR_NO_POLICY_MATCH: errstr = "8"; break; case GPG_ERR_NO_POLICY_MATCH: errstr = "8"; break;

View File

@ -164,7 +164,7 @@ struct crl_cache_entry_s
unsigned int cdb_use_count; /* Current use count. */ unsigned int cdb_use_count; /* Current use count. */
unsigned int cdb_lru_count; /* Used for LRU purposes. */ unsigned int cdb_lru_count; /* Used for LRU purposes. */
int dbfile_checked; /* Set to true if the dbfile_hash value has int dbfile_checked; /* Set to true if the dbfile_hash value has
been checked one. */ been checked once. */
}; };
@ -1402,7 +1402,7 @@ cache_isvalid (ctrl_t ctrl, const char *issuer_hash,
{ {
if (opt.verbose) if (opt.verbose)
log_info ("no system trust and client does not trust either\n"); log_info ("no system trust and client does not trust either\n");
retval = CRL_CACHE_CANTUSE; retval = CRL_CACHE_NOTTRUSTED;
} }
else else
{ {
@ -1522,8 +1522,11 @@ crl_cache_cert_isvalid (ctrl_t ctrl, ksba_cert_t cert,
case CRL_CACHE_DONTKNOW: case CRL_CACHE_DONTKNOW:
err = gpg_error (GPG_ERR_NO_CRL_KNOWN); err = gpg_error (GPG_ERR_NO_CRL_KNOWN);
break; break;
case CRL_CACHE_NOTTRUSTED:
err = gpg_error (GPG_ERR_NOT_TRUSTED);
break;
case CRL_CACHE_CANTUSE: case CRL_CACHE_CANTUSE:
err = gpg_error (GPG_ERR_NO_CRL_KNOWN); err = gpg_error (GPG_ERR_INV_CRL_OBJ);
break; break;
default: default:
log_fatal ("cache_isvalid returned invalid status code %d\n", result); log_fatal ("cache_isvalid returned invalid status code %d\n", result);
@ -2104,7 +2107,7 @@ crl_parse_insert (ctrl_t ctrl, ksba_crl_t crl,
} }
} }
while (stopreason != KSBA_SR_READY); while (stopreason != KSBA_SR_READY);
assert (!err); log_assert (!err);
failure: failure:
@ -2729,8 +2732,6 @@ crl_cache_reload_crl (ctrl_t ctrl, ksba_cert_t cert)
any_dist_point = 1; any_dist_point = 1;
if (opt.verbose)
log_info ("fetching CRL from '%s'\n", distpoint_uri);
crl_close_reader (reader); crl_close_reader (reader);
err = crl_fetch (ctrl, distpoint_uri, &reader); err = crl_fetch (ctrl, distpoint_uri, &reader);
if (err) if (err)

View File

@ -27,6 +27,7 @@ typedef enum
CRL_CACHE_VALID = 0, CRL_CACHE_VALID = 0,
CRL_CACHE_INVALID, CRL_CACHE_INVALID,
CRL_CACHE_DONTKNOW, CRL_CACHE_DONTKNOW,
CRL_CACHE_NOTTRUSTED,
CRL_CACHE_CANTUSE CRL_CACHE_CANTUSE
} }
crl_cache_result_t; crl_cache_result_t;

View File

@ -175,6 +175,9 @@ crl_fetch (ctrl_t ctrl, const char *url, ksba_reader_t *reader)
if (!url) if (!url)
return gpg_error (GPG_ERR_INV_ARG); return gpg_error (GPG_ERR_INV_ARG);
if (opt.verbose)
log_info ("fetching CRL from '%s'\n", url);
err = http_parse_uri (&uri, url, 0); err = http_parse_uri (&uri, url, 0);
http_release_parsed_uri (uri); http_release_parsed_uri (uri);
if (!err) /* Yes, our HTTP code groks that. */ if (!err) /* Yes, our HTTP code groks that. */

View File

@ -1360,8 +1360,11 @@ cmd_isvalid (assuan_context_t ctx, char *line)
goto again; goto again;
} }
break; break;
case CRL_CACHE_NOTTRUSTED:
err = gpg_error (GPG_ERR_NOT_TRUSTED);
break;
case CRL_CACHE_CANTUSE: case CRL_CACHE_CANTUSE:
err = gpg_error (GPG_ERR_NO_CRL_KNOWN); err = gpg_error (GPG_ERR_INV_CRL_OBJ);
break; break;
default: default:
log_fatal ("crl_cache_isvalid returned invalid code\n"); log_fatal ("crl_cache_isvalid returned invalid code\n");
@ -1469,7 +1472,7 @@ cmd_checkcrl (assuan_context_t ctx, char *line)
goto leave; goto leave;
} }
assert (cert); log_assert (cert);
err = crl_cache_cert_isvalid (ctrl, cert, ctrl->force_crl_refresh); err = crl_cache_cert_isvalid (ctrl, cert, ctrl->force_crl_refresh);
if (gpg_err_code (err) == GPG_ERR_NO_CRL_KNOWN) if (gpg_err_code (err) == GPG_ERR_NO_CRL_KNOWN)

View File

@ -255,6 +255,7 @@ check_revocations (ctrl_t ctrl, chain_item_t chain)
int any_revoked = 0; int any_revoked = 0;
int any_no_crl = 0; int any_no_crl = 0;
int any_crl_too_old = 0; int any_crl_too_old = 0;
int any_not_trusted = 0;
chain_item_t ci; chain_item_t ci;
log_assert (ctrl->check_revocations_nest_level >= 0); log_assert (ctrl->check_revocations_nest_level >= 0);
@ -266,7 +267,8 @@ check_revocations (ctrl_t ctrl, chain_item_t chain)
return gpg_error(GPG_ERR_BAD_CERT_CHAIN); return gpg_error(GPG_ERR_BAD_CERT_CHAIN);
} }
ctrl->check_revocations_nest_level++; ctrl->check_revocations_nest_level++;
if (opt.verbose)
log_info ("[%d] start checking CRLs\n", ctrl->check_revocations_nest_level);
for (ci=chain; ci; ci = ci->next) for (ci=chain; ci; ci = ci->next)
{ {
@ -293,17 +295,19 @@ check_revocations (ctrl_t ctrl, chain_item_t chain)
if (!err) if (!err)
err = crl_cache_cert_isvalid (ctrl, ci->cert, 0); err = crl_cache_cert_isvalid (ctrl, ci->cert, 0);
} }
if (opt.verbose)
log_info ("[%d] result of checking this CRL: %s\n",
ctrl->check_revocations_nest_level, gpg_strerror (err));
switch (gpg_err_code (err)) switch (gpg_err_code (err))
{ {
case 0: err = 0; break; case 0: err = 0; break;
case GPG_ERR_CERT_REVOKED: any_revoked = 1; err = 0; break; case GPG_ERR_CERT_REVOKED: any_revoked = 1; err = 0; break;
case GPG_ERR_NO_CRL_KNOWN: any_no_crl = 1; err = 0; break; case GPG_ERR_NO_CRL_KNOWN: any_no_crl = 1; err = 0; break;
case GPG_ERR_NOT_TRUSTED: any_not_trusted = 1; err = 0; break;
case GPG_ERR_CRL_TOO_OLD: any_crl_too_old = 1; err = 0; break; case GPG_ERR_CRL_TOO_OLD: any_crl_too_old = 1; err = 0; break;
default: break; default: break;
} }
} }
ctrl->check_revocations_nest_level--;
if (err) if (err)
; ;
@ -311,10 +315,16 @@ check_revocations (ctrl_t ctrl, chain_item_t chain)
err = gpg_error (GPG_ERR_CERT_REVOKED); err = gpg_error (GPG_ERR_CERT_REVOKED);
else if (any_no_crl) else if (any_no_crl)
err = gpg_error (GPG_ERR_NO_CRL_KNOWN); err = gpg_error (GPG_ERR_NO_CRL_KNOWN);
else if (any_not_trusted)
err = gpg_error (GPG_ERR_NOT_TRUSTED);
else if (any_crl_too_old) else if (any_crl_too_old)
err = gpg_error (GPG_ERR_CRL_TOO_OLD); err = gpg_error (GPG_ERR_CRL_TOO_OLD);
else else
err = 0; err = 0;
if (opt.verbose)
log_info ("[%d] result of checking all CRLs: %s\n",
ctrl->check_revocations_nest_level, gpg_strerror (err));
ctrl->check_revocations_nest_level--;
return err; return err;
} }

View File

@ -521,6 +521,7 @@ isvalid_status_cb (void *opaque, const char *line)
GPG_ERR_CERTIFICATE_REVOKED GPG_ERR_CERTIFICATE_REVOKED
GPG_ERR_NO_CRL_KNOWN GPG_ERR_NO_CRL_KNOWN
GPG_ERR_INV_CRL_OBJ
GPG_ERR_CRL_TOO_OLD GPG_ERR_CRL_TOO_OLD
Values for USE_OCSP: Values for USE_OCSP: