diff options
author | Werner Koch <wk@gnupg.org> | 2022-12-05 16:42:08 +0100 |
---|---|---|
committer | Werner Koch <wk@gnupg.org> | 2022-12-05 16:42:08 +0100 |
commit | b6abaed2b5f6a6e52069f370c61006abdc81cdf5 (patch) | |
tree | 3aaca56d2678d54c1bc60b67c85602b44b5daf28 /sm | |
parent | gpgsm: Silence the "non-critical certificate policy not allowed". (diff) | |
download | gnupg2-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.c | 44 | ||||
-rw-r--r-- | sm/certchain.c | 17 | ||||
-rw-r--r-- | sm/gpgsm.c | 4 | ||||
-rw-r--r-- | sm/gpgsm.h | 8 | ||||
-rw-r--r-- | sm/keylist.c | 18 |
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) |