aboutsummaryrefslogtreecommitdiffstats
path: root/sm/certchain.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--sm/certchain.c109
1 files changed, 69 insertions, 40 deletions
diff --git a/sm/certchain.c b/sm/certchain.c
index bb3fd0339..2904680ea 100644
--- a/sm/certchain.c
+++ b/sm/certchain.c
@@ -347,7 +347,7 @@ find_up (KEYDB_HANDLE kh, ksba_cert_t cert, const char *issuer, int find_next)
if (opt.verbose)
log_info (_("looking up issuer at external location\n"));
- /* dirmngr is confused about unknown attributes so has a quick
+ /* dirmngr is confused about unknown attributes so as a quick
and ugly hack we locate the CN and use this and the
following. Fixme: we should have far better parsing in the
dirmngr. */
@@ -469,6 +469,55 @@ gpgsm_is_root_cert (ksba_cert_t cert)
return yes;
}
+
+/* This is a helper for gpgsm_validate_chain. */
+static gpg_error_t
+is_cert_still_valid (ctrl_t ctrl, int lm, FILE *fp,
+ ksba_cert_t subject_cert, ksba_cert_t issuer_cert,
+ int *any_revoked, int *any_no_crl, int *any_crl_too_old)
+{
+ if (!opt.no_crl_check || ctrl->use_ocsp)
+ {
+ gpg_error_t err;
+
+ err = gpgsm_dirmngr_isvalid (subject_cert, ctrl->use_ocsp);
+ if (err)
+ {
+ /* Fixme: We should change the wording because we may
+ have used OCSP. */
+ switch (gpg_err_code (err))
+ {
+ case GPG_ERR_CERT_REVOKED:
+ do_list (1, lm, fp, _("certificate has been revoked"));
+ *any_revoked = 1;
+ /* Store that in the keybox so that key listings are
+ able to return the revoked flag. We don't care
+ about error, though. */
+ keydb_set_cert_flags (subject_cert, KEYBOX_FLAG_VALIDITY, 0,
+ VALIDITY_REVOKED);
+ break;
+ case GPG_ERR_NO_CRL_KNOWN:
+ do_list (1, lm, fp, _("no CRL found for certificate"));
+ *any_no_crl = 1;
+ break;
+ case GPG_ERR_CRL_TOO_OLD:
+ do_list (1, lm, fp, _("the available CRL is too old"));
+ if (!lm)
+ log_info (_("please make sure that the "
+ "\"dirmngr\" is properly installed\n"));
+ *any_crl_too_old = 1;
+ break;
+ default:
+ do_list (1, lm, fp, _("checking the CRL failed: %s"),
+ gpg_strerror (rc));
+ return err;
+ }
+ }
+ }
+ return 0;
+}
+
+
/* Validate a chain and optionally return the nearest expiration time
in R_EXPTIME. With LISTMODE set to 1 a special listmode is
@@ -597,46 +646,10 @@ gpgsm_validate_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t r_exptime,
goto leave;
}
- if (!opt.no_crl_check || ctrl->use_ocsp)
- {
- rc = gpgsm_dirmngr_isvalid (subject_cert, ctrl->use_ocsp);
- if (rc)
- {
- /* Fixme: We should change the wording because we may
- have used OCSP. */
- switch (gpg_err_code (rc))
- {
- case GPG_ERR_CERT_REVOKED:
- do_list (1, lm, fp, _("certificate has been revoked"));
- any_revoked = 1;
- /* Store that in the keybox so that key listings are
- able to return the revoked flag. We don't care
- about error, though. */
- keydb_set_cert_flags (subject_cert, KEYBOX_FLAG_VALIDITY, 0,
- VALIDITY_REVOKED);
- break;
- case GPG_ERR_NO_CRL_KNOWN:
- do_list (1, lm, fp, _("no CRL found for certificate"));
- any_no_crl = 1;
- break;
- case GPG_ERR_CRL_TOO_OLD:
- do_list (1, lm, fp, _("the available CRL is too old"));
- if (!lm)
- log_info (_("please make sure that the "
- "\"dirmngr\" is properly installed\n"));
- any_crl_too_old = 1;
- break;
- default:
- do_list (1, lm, fp, _("checking the CRL failed: %s"),
- gpg_strerror (rc));
- goto leave;
- }
- rc = 0;
- }
- }
+ /* Is this a self-signed certificate? */
if (subject && !strcmp (issuer, subject))
- {
+ { /* Yes. */
if (gpgsm_check_cert_sig (subject_cert, subject_cert) )
{
do_list (1, lm, fp,
@@ -684,7 +697,15 @@ gpgsm_validate_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t r_exptime,
gpg_strerror (rc));
}
- break; /* okay, a self-signed certicate is an end-point */
+ /* Check for revocations etc. */
+ rc = is_cert_still_valid (ctrl, lm, fp,
+ subject_cert, subject_cert,
+ &any_revoked, &any_no_crl,
+ &any_crl_too_old);
+ if (rc)
+ goto leave;
+
+ break; /* Okay: a self-signed certicate is an end-point. */
}
depth++;
@@ -801,6 +822,14 @@ gpgsm_validate_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t r_exptime,
}
}
+ /* Check for revocations etc. */
+ rc = is_cert_still_valid (ctrl, lm, fp,
+ subject_cert, issuer_cert,
+ &any_revoked, &any_no_crl, &any_crl_too_old);
+ if (rc)
+ goto leave;
+
+
if (opt.verbose && !listmode)
log_info ("certificate is good\n");