summaryrefslogtreecommitdiffstats
path: root/sm
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2022-12-05 16:42:08 +0100
committerWerner Koch <wk@gnupg.org>2022-12-05 16:42:08 +0100
commitb6abaed2b5f6a6e52069f370c61006abdc81cdf5 (patch)
tree3aaca56d2678d54c1bc60b67c85602b44b5daf28 /sm
parentgpgsm: Silence the "non-critical certificate policy not allowed". (diff)
downloadgnupg2-b6abaed2b5f6a6e52069f370c61006abdc81cdf5.tar.xz
gnupg2-b6abaed2b5f6a6e52069f370c61006abdc81cdf5.zip
gpgsm: Print revocation date and reason in cert listings.
* dirmngr/ocsp.c (ocsp_isvalid): Add args r_revoked_at and r_revocation_reason. * dirmngr/server.c (cmd_isvalid): Emit a new REVOCATIONINFO status. (cmd_checkocsp): Ditto. * sm/call-dirmngr.c (struct isvalid_status_parm_s): Add new fields. (isvalid_status_cb): Parse REVOCATIONINFO. (gpgsm_dirmngr_isvalid): Add args r_revoked_at and r_revocation_reason. * sm/gpgsm.h (struct server_control_s): Add fields revoked_art and revocation_reason. * sm/keylist.c (list_cert_raw): Print revocation date. (list_cert_std): Ditto. -- Note that for now we do this only for OCSP because it is an important piece of information when using the chain model. For a sample key see commit 7fa1d3cc821dca1ea8e1c80a0bdd527177c185ee.
Diffstat (limited to 'sm')
-rw-r--r--sm/call-dirmngr.c44
-rw-r--r--sm/certchain.c17
-rw-r--r--sm/gpgsm.c4
-rw-r--r--sm/gpgsm.h8
-rw-r--r--sm/keylist.c18
5 files changed, 88 insertions, 3 deletions
diff --git a/sm/call-dirmngr.c b/sm/call-dirmngr.c
index a15ff240d..cc958ccf8 100644
--- a/sm/call-dirmngr.c
+++ b/sm/call-dirmngr.c
@@ -64,6 +64,8 @@ struct isvalid_status_parm_s {
ctrl_t ctrl;
int seen;
unsigned char fpr[20];
+ gnupg_isotime_t revoked_at;
+ char *revocation_reason; /* malloced or NULL */
};
@@ -491,6 +493,19 @@ isvalid_status_cb (void *opaque, const char *line)
if (!*s || !unhexify_fpr (s, parm->fpr))
parm->seen++; /* Bump it to indicate an error. */
}
+ else if ((s = has_leading_keyword (line, "REVOCATIONINFO")))
+ {
+ if (*s && strlen (s) >= 15)
+ {
+ memcpy (parm->revoked_at, s, 15);
+ parm->revoked_at[15] = 0;
+ }
+ s += 15;
+ while (*s && spacep (s))
+ s++;
+ xfree (parm->revocation_reason);
+ parm->revocation_reason = *s? xtrystrdup (s) : NULL;
+ }
else if (warning_and_note_printer (line))
{
}
@@ -512,10 +527,15 @@ isvalid_status_cb (void *opaque, const char *line)
0 = Do CRL check.
1 = Do an OCSP check but fallback to CRL unless CRLs are disabled.
2 = Do only an OCSP check (used for the chain model).
+
+ If R_REVOKED_AT pr R_REASON are not NULL and the certificate has
+ been revoked the revocation time and the reason are copied to there.
+ The caller needs to free R_REASON.
*/
gpg_error_t
gpgsm_dirmngr_isvalid (ctrl_t ctrl,
- ksba_cert_t cert, ksba_cert_t issuer_cert, int use_ocsp)
+ ksba_cert_t cert, ksba_cert_t issuer_cert, int use_ocsp,
+ gnupg_isotime_t r_revoked_at, char **r_reason)
{
static int did_options;
int rc;
@@ -524,6 +544,11 @@ gpgsm_dirmngr_isvalid (ctrl_t ctrl,
struct inq_certificate_parm_s parm;
struct isvalid_status_parm_s stparm;
+ if (r_revoked_at)
+ *r_revoked_at = 0;
+ if (r_reason)
+ *r_reason = NULL;
+
rc = start_dirmngr (ctrl);
if (rc)
return rc;
@@ -553,6 +578,8 @@ gpgsm_dirmngr_isvalid (ctrl_t ctrl,
stparm.ctrl = ctrl;
stparm.seen = 0;
memset (stparm.fpr, 0, 20);
+ stparm.revoked_at[0] = 0;
+ stparm.revocation_reason = NULL;
/* It is sufficient to send the options only once because we have
* one connection per process only. */
@@ -577,6 +604,19 @@ gpgsm_dirmngr_isvalid (ctrl_t ctrl,
if (opt.verbose > 1)
log_info ("response of dirmngr: %s\n", rc? gpg_strerror (rc): "okay");
+ if (gpg_err_code (rc) == GPG_ERR_CERT_REVOKED
+ && !check_isotime (stparm.revoked_at))
+ {
+ if (r_revoked_at)
+ gnupg_copy_time (r_revoked_at, stparm.revoked_at);
+ if (r_reason)
+ {
+ *r_reason = stparm.revocation_reason;
+ stparm.revocation_reason = NULL;
+ }
+
+ }
+
if (!rc && stparm.seen)
{
/* Need to also check the certificate validity. */
@@ -634,7 +674,9 @@ gpgsm_dirmngr_isvalid (ctrl_t ctrl,
ksba_cert_release (rspcert);
}
}
+
release_dirmngr (ctrl);
+ xfree (stparm.revocation_reason);
return rc;
}
diff --git a/sm/certchain.c b/sm/certchain.c
index efe8cb1d5..abce4c327 100644
--- a/sm/certchain.c
+++ b/sm/certchain.c
@@ -1193,6 +1193,8 @@ is_cert_still_valid (ctrl_t ctrl, int chain_model, int lm, estream_t fp,
int *any_revoked, int *any_no_crl, int *any_crl_too_old)
{
gpg_error_t err;
+ gnupg_isotime_t revoked_at;
+ char *reason;
if (ctrl->offline || (opt.no_crl_check && !ctrl->use_ocsp))
{
@@ -1221,7 +1223,20 @@ is_cert_still_valid (ctrl_t ctrl, int chain_model, int lm, estream_t fp,
err = gpgsm_dirmngr_isvalid (ctrl,
subject_cert, issuer_cert,
- chain_model? 2 : !!ctrl->use_ocsp);
+ chain_model? 2 : !!ctrl->use_ocsp,
+ revoked_at, &reason);
+ if (gpg_err_code (err) == GPG_ERR_CERT_REVOKED)
+ {
+ gnupg_copy_time (ctrl->revoked_at, revoked_at);
+ xfree (ctrl->revocation_reason);
+ ctrl->revocation_reason = reason;
+ reason = NULL;
+ }
+ else
+ {
+ xfree (reason);
+ reason = (NULL);
+ }
audit_log_ok (ctrl->audit, AUDIT_CRL_CHECK, err);
if (err)
diff --git a/sm/gpgsm.c b/sm/gpgsm.c
index 3247a0f2e..f8b3856c2 100644
--- a/sm/gpgsm.c
+++ b/sm/gpgsm.c
@@ -2228,6 +2228,8 @@ gpgsm_init_default_ctrl (struct server_control_s *ctrl)
ctrl->use_ocsp = opt.enable_ocsp;
ctrl->validation_model = default_validation_model;
ctrl->offline = opt.disable_dirmngr;
+ ctrl->revoked_at[0] = 0;
+ ctrl->revocation_reason = NULL;
}
@@ -2237,6 +2239,8 @@ void
gpgsm_deinit_default_ctrl (ctrl_t ctrl)
{
gpgsm_keydb_deinit_session_data (ctrl);
+ xfree (ctrl->revocation_reason);
+ ctrl->revocation_reason = NULL;
}
diff --git a/sm/gpgsm.h b/sm/gpgsm.h
index b0ed8891c..ced2d679f 100644
--- a/sm/gpgsm.h
+++ b/sm/gpgsm.h
@@ -264,6 +264,10 @@ struct server_control_s
/* The current time. Used as a helper in certchain.c. */
ksba_isotime_t current_time;
+
+ /* The revocation info. Used as a helper inc ertchain.c */
+ gnupg_isotime_t revoked_at;
+ char *revocation_reason;
};
@@ -496,7 +500,9 @@ gpg_error_t gpgsm_agent_export_key (ctrl_t ctrl, const char *keygrip,
/*-- call-dirmngr.c --*/
gpg_error_t gpgsm_dirmngr_isvalid (ctrl_t ctrl,
ksba_cert_t cert, ksba_cert_t issuer_cert,
- int use_ocsp);
+ int use_ocsp,
+ gnupg_isotime_t r_revoked_at,
+ char **r_reason);
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);
diff --git a/sm/keylist.c b/sm/keylist.c
index fb2c3bad5..fabd82224 100644
--- a/sm/keylist.c
+++ b/sm/keylist.c
@@ -1201,6 +1201,15 @@ list_cert_raw (ctrl_t ctrl, KEYDB_HANDLE hd,
{
err = gpgsm_validate_chain (ctrl, cert,
GNUPG_ISOTIME_NONE, NULL, 1, fp, 0, NULL);
+ if (gpg_err_code (err) == GPG_ERR_CERT_REVOKED
+ && !check_isotime (ctrl->revoked_at))
+ {
+ es_fputs (" revoked: ", fp);
+ gpgsm_print_time (fp, ctrl->revoked_at);
+ if (ctrl->revocation_reason)
+ es_fprintf (fp, " (%s)", ctrl->revocation_reason);
+ es_putc ('\n', fp);
+ }
if (!err)
es_fprintf (fp, " [certificate is good]\n");
else
@@ -1451,6 +1460,15 @@ list_cert_std (ctrl_t ctrl, ksba_cert_t cert, estream_t fp, int have_secret,
err = gpgsm_validate_chain (ctrl, cert,
GNUPG_ISOTIME_NONE, NULL, 1, fp, 0, NULL);
+ if (gpg_err_code (err) == GPG_ERR_CERT_REVOKED
+ && !check_isotime (ctrl->revoked_at))
+ {
+ es_fputs (" revoked: ", fp);
+ gpgsm_print_time (fp, ctrl->revoked_at);
+ if (ctrl->revocation_reason)
+ es_fprintf (fp, " (%s)", ctrl->revocation_reason);
+ es_putc ('\n', fp);
+ }
tmperr = ksba_cert_get_user_data (cert, "is_qualified",
&buffer, sizeof (buffer), &buflen);
if (!tmperr && buflen)