diff --git a/dirmngr/crlcache.c b/dirmngr/crlcache.c index 2e471cb09..3cd8cf420 100644 --- a/dirmngr/crlcache.c +++ b/dirmngr/crlcache.c @@ -1851,7 +1851,8 @@ crl_parse_insert (ctrl_t ctrl, ksba_crl_t crl, md = NULL; err = validate_cert_chain (ctrl, crlissuer_cert, NULL, - VALIDATE_MODE_CRL_RECURSIVE, + (VALIDATE_FLAG_CRL + | VALIDATE_FLAG_RECURSIVE), r_trust_anchor); if (err) { diff --git a/dirmngr/server.c b/dirmngr/server.c index 05ef439a1..1134ac081 100644 --- a/dirmngr/server.c +++ b/dirmngr/server.c @@ -1733,7 +1733,7 @@ cmd_cachecert (assuan_context_t ctx, char *line) static const char hlp_validate[] = - "VALIDATE [--systrust] [--tls]\n" + "VALIDATE [--systrust] [--tls] [--no-crl]\n" "\n" "Validate a certificate using the certificate validation function\n" "used internally by dirmngr. This command is only useful for\n" @@ -1753,7 +1753,8 @@ static const char hlp_validate[] = "need to be PEM encoded.\n" "\n" "The option --systrust changes the behaviour to include the system\n" - "provided root certificates as trust anchors."; + "provided root certificates as trust anchors. The option --no-crl\n" + "skips CRL checks"; static gpg_error_t cmd_validate (assuan_context_t ctx, char *line) { @@ -1763,10 +1764,11 @@ cmd_validate (assuan_context_t ctx, char *line) certlist_t certlist = NULL; unsigned char *value = NULL; size_t valuelen; - int systrust_mode, tls_mode; + int systrust_mode, tls_mode, no_crl; systrust_mode = has_option (line, "--systrust"); tls_mode = has_option (line, "--tls"); + no_crl = has_option (line, "--no-crl"); line = skip_options (line); if (tls_mode) @@ -1843,14 +1845,11 @@ cmd_validate (assuan_context_t ctx, char *line) cache_cert (cl->cert); } - - err = validate_cert_chain - (ctrl, cert, NULL, - tls_mode && systrust_mode ? VALIDATE_MODE_TLS_SYSTRUST : - tls_mode ? VALIDATE_MODE_TLS : - /**/ systrust_mode ? VALIDATE_MODE_CERT_SYSTRUST : - /**/ VALIDATE_MODE_CERT, - NULL); + err = validate_cert_chain (ctrl, cert, NULL, + ((tls_mode ? VALIDATE_FLAG_TLS : 0) + | (systrust_mode ? VALIDATE_FLAG_SYSTRUST : 0) + | (no_crl ? VALIDATE_FLAG_NOCRLCHECK : 0)), + NULL); leave: ksba_cert_release (cert); diff --git a/dirmngr/validate.c b/dirmngr/validate.c index 8fb2df2c3..1599a8d5a 100644 --- a/dirmngr/validate.c +++ b/dirmngr/validate.c @@ -379,7 +379,7 @@ is_root_cert (ksba_cert_t cert, const char *issuerdn, const char *subjectdn) R_TRUST_ANCHOR; in all other cases NULL is stored there. */ gpg_error_t validate_cert_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t r_exptime, - int mode, char **r_trust_anchor) + unsigned int flags, char **r_trust_anchor) { gpg_error_t err = 0; int depth, maxdepth; @@ -405,20 +405,9 @@ validate_cert_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t r_exptime, dump_cert ("subject", cert); /* May the target certificate be used for this purpose? */ - switch (mode) - { - case VALIDATE_MODE_OCSP: - err = check_cert_use_ocsp (cert); - break; - case VALIDATE_MODE_CRL: - case VALIDATE_MODE_CRL_RECURSIVE: - err = check_cert_use_crl (cert); - break; - default: - err = 0; - break; - } - if (err) + if ((flags & VALIDATE_FLAG_OCSP) && (err = check_cert_use_ocsp (cert))) + return err; + if ((flags & VALIDATE_FLAG_CRL) && (err = check_cert_use_crl (cert))) return err; /* If we already validated the certificate not too long ago, we can @@ -552,8 +541,7 @@ validate_cert_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t r_exptime, goto leave; /* No. */ err = is_trusted_cert (subject_cert, - (mode == VALIDATE_MODE_CERT_SYSTRUST - || mode == VALIDATE_MODE_TLS_SYSTRUST)); + !!(flags & VALIDATE_FLAG_SYSTRUST)); if (!err) ; /* Yes we trust this cert. */ else if (gpg_err_code (err) == GPG_ERR_NOT_TRUSTED) @@ -759,7 +747,12 @@ validate_cert_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t r_exptime, cert_log_name (" certificate", citem->cert); } - if (!err && mode != VALIDATE_MODE_CRL) + /* Now check for revocations unless CRL checks are disabled or we + * are non-recursive CRL mode. */ + if (!err + && !(flags & VALIDATE_FLAG_NOCRLCHECK) + && !((flags & VALIDATE_FLAG_CRL) + && !(flags & VALIDATE_FLAG_RECURSIVE))) { /* Now that everything is fine, walk the chain and check each * certificate for revocations. * @@ -774,9 +767,7 @@ validate_cert_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t r_exptime, * our validity results to avoid double work. Far worse a * catch-22 may happen for an improper setup hierarchy and we * need a way to break up such a deadlock. */ - if (mode != VALIDATE_MODE_TLS_SYSTRUST) - err = check_revocations (ctrl, chain); -#warning fix the above + err = check_revocations (ctrl, chain); } if (!err && opt.verbose) diff --git a/dirmngr/validate.h b/dirmngr/validate.h index 376d99d60..b6222b51f 100644 --- a/dirmngr/validate.h +++ b/dirmngr/validate.h @@ -22,38 +22,35 @@ #define VALIDATE_H -enum { - /* Simple certificate validation mode. */ - VALIDATE_MODE_CERT = 0, +/* Make use of the system provided root certificates. */ +#define VALIDATE_FLAG_SYSTRUST 1 - /* Same as MODE_CERT but using the system provided root - * certificates. */ - VALIDATE_MODE_CERT_SYSTRUST, +/* Make use of extra provided root certificates. */ +#define VALIDATE_FLAG_EXTRATRUST 2 - /* Same as MODE_CERT but uses a provided list of certificates. */ - VALIDATE_MODE_TLS, +/* Standard CRL issuer certificate validation; i.e. CRLs are not + * considered for CRL issuer certificates. */ +#define VALIDATE_FLAG_CRL 4 - /* Same as MODE_TLS but using the system provided root - * certificates. */ - VALIDATE_MODE_TLS_SYSTRUST, +/* If this flag is set along with VALIDATE_FLAG_CRL a full CRL + * verification is done. */ +#define VALIDATE_FLAG_RECURSIVE 8 - /* Standard CRL issuer certificate validation; i.e. CRLs are not - considered for CRL issuer certificates. */ - VALIDATE_MODE_CRL, +/* Validation mode as used for OCSP. */ +#define VALIDATE_FLAG_OCSP 16 - /* Full CRL validation. */ - VALIDATE_MODE_CRL_RECURSIVE, +/* Validation mode as used with TLS. */ +#define VALIDATE_FLAG_TLS 32 - /* Validation as used for OCSP. */ - VALIDATE_MODE_OCSP -}; +/* Don't do CRL checks. */ +#define VALIDATE_FLAG_NOCRLCHECK 64 /* Validate the certificate CHAIN up to the trust anchor. Optionally return the closest expiration time in R_EXPTIME. */ gpg_error_t validate_cert_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t r_exptime, - int mode, char **r_trust_anchor); + unsigned int flags, char **r_trust_anchor); /* Return 0 if the certificate CERT is usable for certification. */ gpg_error_t check_cert_use_cert (ksba_cert_t cert);