gpgsm: Always use the chain model if the root-CA requests this.

* sm/call-dirmngr.c (gpgsm_dirmngr_isvalid): Do not use
option --force-default-responder.
* sm/certchain.c (is_cert_still_valid): Rename arg for clarity.
(gpgsm_validate_chain): Always switch to chain model.
--

The trustlist.txt may indicate that a root CA issues certificates
which shall be validated using the chain model.  This is for example
the case for qualified signatures.  Before this change we did this
only if the default shell model indicated that a certificate has
expired.  This optimization is technically okay but has one problem:
The chain model requires the use of OCSP but we switch to this only
when running the chain model validation.  To catch revoked
certificates using OCSP we need to always switch to the chain model
unless OCSP has been enabled anyway.

Note that the old --force-default-responder option is not anymore
used.

Test cases are certificates issued by

  # CN=TeleSec qualified Root CA 1
  # O=Deutsche Telekom AG
  # C=DE
  # 2.5.4.97=USt-IdNr. DE 123475223
  90:C6:13:6C:7D:EF:EF:E9:7C:C7:64:F9:D2:67:8E:AD:03:E5:52:96 \
    S cm qual relax

A sample revoked certificate is

-----BEGIN CERTIFICATE-----
MIIDTzCCAvSgAwIBAgIQIXfquQjq32B03CdaflIbiDAMBggqhkjOPQQDAgUAMHEx
CzAJBgNVBAYTAkRFMRwwGgYDVQQKDBNEZXV0c2NoZSBUZWxla29tIEFHMSMwIQYD
VQQDDBpUZWxlU2VjIFBLUyBlSURBUyBRRVMgQ0EgMTEfMB0GA1UEYQwWVVN0LUlk
TnIuIERFIDEyMzQ3NTIyMzAeFw0yMDA2MjIxMDQ1NDJaFw0yMzA2MjUyMzU5MDBa
MDAxCzAJBgNVBAYTAkRFMRUwEwYDVQQDDAxLb2NoLCBXZXJuZXIxCjAIBgNVBAUT
ATMwWjAUBgcqhkjOPQIBBgkrJAMDAggBAQcDQgAEbkEXUuXTriWOwqQhjlh11oCc
6Z8lQdQDz3zY/OEh8fMJS7AKBNo8zkpPKDJ2olPph18b1goEbLiqHQsPRPahDaOC
AaowggGmMB8GA1UdIwQYMBaAFP/0iep1rMXT0iQ0+WUqBvLM6bqBMB0GA1UdDgQW
BBQEI3xsIUDnoOx+gLYbG63v5/f9kjAOBgNVHQ8BAf8EBAMCBkAwDAYDVR0TAQH/
BAIwADAgBgNVHREEGTAXgRV3ZXJuZXIua29jaEBnbnVwZy5jb20wPQYDVR0gBDYw
NDAyBgcEAIvsQAECMCcwJQYIKwYBBQUHAgEWGWh0dHA6Ly9wa3MudGVsZXNlYy5k
ZS9jcHMwgYQGCCsGAQUFBwEBBHgwdjBLBggrBgEFBQcwAoY/aHR0cDovL3RxcmNh
MS5wa2kudGVsZXNlYy5kZS9jcnQvVGVsZVNlY19QS1NfZUlEQVNfUUVTX0NBXzEu
Y3J0MCcGCCsGAQUFBzABhhtodHRwOi8vcGtzLnRlbGVzZWMuZGUvb2NzcHIwXgYI
KwYBBQUHAQMEUjBQMAgGBgQAjkYBATAIBgYEAI5GAQQwOgYGBACORgEFMDAwLhYo
aHR0cHM6Ly93d3cudGVsZXNlYy5kZS9zaWduYXR1cmthcnRlL2FnYhMCZW4wDAYI
KoZIzj0EAwIFAANHADBEAiAqgB8gyZyj05CRdHD5KJcpG68DzQECYnYP6ZPasUYK
AQIgI1GtRMJWvFTIKsZpgY+ty0pRb5/K09fbmvaSAKFpv/I=
-----END CERTIFICATE-----
This commit is contained in:
Werner Koch 2022-12-05 14:25:04 +01:00
parent 1a85ee9a43
commit 7fa1d3cc82
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B
4 changed files with 17 additions and 16 deletions

View File

@ -1341,7 +1341,7 @@ Assume "no" on most questions. Should not be used in an option file.
@item --list-filter @{select=@var{expr}@}
@opindex list-filter
A list filter can be used to output only certain keys during key
listsin command. For the availbale property names, see the description
listing commands. For the available property names, see the description
of @option{--import-filter}.

View File

@ -510,10 +510,10 @@ isvalid_status_cb (void *opaque, const char *line)
Values for USE_OCSP:
0 = Do CRL check.
1 = Do an OCSP check but fallback to CRL unless CRLS are disabled.
2 = Do only 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 (used for the chain model).
*/
int
gpg_error_t
gpgsm_dirmngr_isvalid (ctrl_t ctrl,
ksba_cert_t cert, ksba_cert_t issuer_cert, int use_ocsp)
{
@ -563,9 +563,8 @@ gpgsm_dirmngr_isvalid (ctrl_t ctrl,
NULL, NULL, NULL, NULL, NULL, NULL);
did_options = 1;
}
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":"",
snprintf (line, DIM(line), "ISVALID%s %s%s%s",
(use_ocsp == 2 || opt.no_crl_check) ? " --only-ocsp":"",
certid,
use_ocsp? " ":"",
use_ocsp? certfpr:"");

View File

@ -1187,7 +1187,7 @@ gpgsm_is_root_cert (ksba_cert_t cert)
/* This is a helper for gpgsm_validate_chain. */
static gpg_error_t
is_cert_still_valid (ctrl_t ctrl, int force_ocsp, int lm, estream_t fp,
is_cert_still_valid (ctrl_t ctrl, int chain_model, int lm, estream_t fp,
ksba_cert_t subject_cert, ksba_cert_t issuer_cert,
int *any_revoked, int *any_no_crl, int *any_crl_too_old)
{
@ -1201,7 +1201,7 @@ is_cert_still_valid (ctrl_t ctrl, int force_ocsp, int lm, estream_t fp,
}
if (!(force_ocsp || ctrl->use_ocsp)
if (!(chain_model || ctrl->use_ocsp)
&& !opt.enable_issuer_based_crl_check)
{
err = ksba_cert_get_crl_dist_point (subject_cert, 0, NULL, NULL, NULL);
@ -1220,7 +1220,7 @@ is_cert_still_valid (ctrl_t ctrl, int force_ocsp, int lm, estream_t fp,
err = gpgsm_dirmngr_isvalid (ctrl,
subject_cert, issuer_cert,
force_ocsp? 2 : !!ctrl->use_ocsp);
chain_model? 2 : !!ctrl->use_ocsp);
audit_log_ok (ctrl->audit, AUDIT_CRL_CHECK, err);
if (err)
@ -2158,10 +2158,12 @@ gpgsm_validate_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t checktime,
{
*retflags |= VALIDATE_FLAG_STEED;
}
else if (gpg_err_code (rc) == GPG_ERR_CERT_EXPIRED
&& !(flags & VALIDATE_FLAG_CHAIN_MODEL)
&& (rootca_flags.valid && rootca_flags.chain_model))
else if (!(flags & VALIDATE_FLAG_CHAIN_MODEL)
&& (rootca_flags.valid && rootca_flags.chain_model))
{
/* The root CA indicated that the chain model is to be used but
* we have not yet used it. Thus do the validation again using
* the chain model. */
do_list (0, listmode, listfp, _("switching to chain model"));
rc = do_validate_chain (ctrl, cert, checktime,
r_exptime, listmode, listfp,

View File

@ -494,9 +494,9 @@ gpg_error_t gpgsm_agent_export_key (ctrl_t ctrl, const char *keygrip,
size_t *r_resultlen);
/*-- call-dirmngr.c --*/
int gpgsm_dirmngr_isvalid (ctrl_t ctrl,
ksba_cert_t cert, ksba_cert_t issuer_cert,
int use_ocsp);
gpg_error_t gpgsm_dirmngr_isvalid (ctrl_t ctrl,
ksba_cert_t cert, ksba_cert_t issuer_cert,
int use_ocsp);
int gpgsm_dirmngr_lookup (ctrl_t ctrl, strlist_t names, const char *uri,
int cache_only,
void (*cb)(void*, ksba_cert_t), void *cb_value);