[TLS] detect expired stapling file at startup (fixes #3056)

also adjust time_t comparison to (pc_stapling_nextts > cur_ts + 256)
(time_t is expected to be signed integral type, but might be unsigned)

x-ref:
  "OCSP Stapling reload seems not to work"
  https://redmine.lighttpd.net/issues/3056
This commit is contained in:
Glenn Strauss 2021-01-22 02:38:25 -05:00
parent 3a2ddc6cf8
commit 81e4f4c4a7
4 changed files with 91 additions and 51 deletions

View File

@ -893,6 +893,23 @@ mod_gnutls_ocsp_next_update (plugin_cert *pc, log_error_st *errh)
#endif
__attribute_cold__
static void
mod_gnutls_expire_stapling_file (server *srv, plugin_cert *pc)
{
#if 0
/* discard expired OCSP stapling response */
/* Does GnuTLS detect expired OCSP response? */
/* or must we rebuild gnutls_certificate_credentials_t ? */
#endif
if (pc->must_staple)
log_error(srv->errh, __FILE__, __LINE__,
"certificate marked OCSP Must-Staple, "
"but OCSP response expired from ssl.stapling-file %s",
pc->ssl_stapling_file->ptr);
}
static int
mod_gnutls_reload_stapling_file (server *srv, plugin_cert *pc, const time_t cur_ts)
{
@ -948,6 +965,8 @@ mod_gnutls_reload_stapling_file (server *srv, plugin_cert *pc, const time_t cur_
pc->ssl_stapling_nextts = cur_ts + 3600;
pc->ssl_stapling_loadts = 0;
}
else if (pc->ssl_stapling_nextts < cur_ts)
mod_gnutls_expire_stapling_file(srv, pc);
return 0;
}
@ -956,25 +975,13 @@ mod_gnutls_reload_stapling_file (server *srv, plugin_cert *pc, const time_t cur_
static int
mod_gnutls_refresh_stapling_file (server *srv, plugin_cert *pc, const time_t cur_ts)
{
if (pc->ssl_stapling_nextts >= 256
&& pc->ssl_stapling_nextts - 256 > cur_ts)
if (pc->ssl_stapling_nextts > cur_ts + 256)
return 0; /* skip check for refresh unless close to expire */
struct stat st;
if (0 != stat(pc->ssl_stapling_file->ptr, &st)
|| st.st_mtime <= pc->ssl_stapling_loadts) {
if (pc->ssl_stapling_nextts < cur_ts) {
#if 0
/* discard expired OCSP stapling response */
/* Does GnuTLS detect expired OCSP response? */
/* or must we rebuild gnutls_certificate_credentials_t ? */
#endif
if (pc->must_staple) {
log_error(srv->errh, __FILE__, __LINE__,
"certificate marked OCSP Must-Staple, "
"but OCSP response expired from ssl.stapling-file %s",
pc->ssl_stapling_file->ptr);
}
}
if (pc->ssl_stapling_nextts < cur_ts)
mod_gnutls_expire_stapling_file(srv, pc);
return 0;
}
return mod_gnutls_reload_stapling_file(srv, pc, cur_ts);

View File

@ -1014,6 +1014,20 @@ mod_nss_verify_cb (void *arg, PRFileDesc *ssl, PRBool checkSig, PRBool isServer)
}
__attribute_cold__
static void
mod_nss_expire_stapling_file (server *srv, plugin_cert *pc)
{
/* discard expired OCSP stapling response */
pc->ssl_credex.stapledOCSPResponses = NULL;
if (pc->must_staple)
log_error(srv->errh, __FILE__, __LINE__,
"certificate marked OCSP Must-Staple, "
"but OCSP response expired from ssl.stapling-file %s",
pc->ssl_stapling_file->ptr);
}
static int
mod_nss_reload_stapling_file (server *srv, plugin_cert *pc, const time_t cur_ts)
{
@ -1059,6 +1073,8 @@ mod_nss_reload_stapling_file (server *srv, plugin_cert *pc, const time_t cur_ts)
pc->ssl_stapling_nextts = cur_ts + 3600;
pc->ssl_stapling_loadts = 0;
}
else if (pc->ssl_stapling_nextts < cur_ts)
mod_nss_expire_stapling_file(srv, pc);
return 0;
}
@ -1067,22 +1083,13 @@ mod_nss_reload_stapling_file (server *srv, plugin_cert *pc, const time_t cur_ts)
static int
mod_nss_refresh_stapling_file (server *srv, plugin_cert *pc, const time_t cur_ts)
{
if (pc->ssl_stapling_nextts >= 256
&& pc->ssl_stapling_nextts - 256 > cur_ts)
if (pc->ssl_stapling_nextts > cur_ts + 256)
return 0; /* skip check for refresh unless close to expire */
struct stat st;
if (0 != stat(pc->ssl_stapling_file->ptr, &st)
|| st.st_mtime <= pc->ssl_stapling_loadts) {
if (pc->ssl_stapling_nextts < cur_ts) {
/* discard expired OCSP stapling response */
pc->ssl_credex.stapledOCSPResponses = NULL;
if (pc->must_staple) {
log_error(srv->errh, __FILE__, __LINE__,
"certificate marked OCSP Must-Staple, "
"but OCSP response expired from ssl.stapling-file %s",
pc->ssl_stapling_file->ptr);
}
}
if (pc->ssl_stapling_nextts < cur_ts)
mod_nss_expire_stapling_file(srv, pc);
return 0;
}
return mod_nss_reload_stapling_file(srv, pc, cur_ts);

View File

@ -1503,6 +1503,24 @@ mod_openssl_ocsp_next_update (plugin_cert *pc)
}
__attribute_cold__
static void
mod_openssl_expire_stapling_file (server *srv, plugin_cert *pc)
{
if (NULL == pc->ssl_stapling) /*(previously discarded or never loaded)*/
return;
/* discard expired OCSP stapling response */
buffer_free(pc->ssl_stapling);
pc->ssl_stapling = NULL;
if (pc->must_staple)
log_error(srv->errh, __FILE__, __LINE__,
"certificate marked OCSP Must-Staple, "
"but OCSP response expired from ssl.stapling-file %s",
pc->ssl_stapling_file->ptr);
}
static int
mod_openssl_reload_stapling_file (server *srv, plugin_cert *pc, const time_t cur_ts)
{
@ -1520,6 +1538,10 @@ mod_openssl_reload_stapling_file (server *srv, plugin_cert *pc, const time_t cur
pc->ssl_stapling_nextts = cur_ts + 3600;
pc->ssl_stapling_loadts = 0;
}
else if (pc->ssl_stapling_nextts < cur_ts) {
mod_openssl_expire_stapling_file(srv, pc);
return 0;
}
return 1;
}
@ -1528,22 +1550,13 @@ mod_openssl_reload_stapling_file (server *srv, plugin_cert *pc, const time_t cur
static int
mod_openssl_refresh_stapling_file (server *srv, plugin_cert *pc, const time_t cur_ts)
{
if (pc->ssl_stapling && pc->ssl_stapling_nextts - 256 > cur_ts)
if (pc->ssl_stapling && pc->ssl_stapling_nextts > cur_ts + 256)
return 1; /* skip check for refresh unless close to expire */
struct stat st;
if (0 != stat(pc->ssl_stapling_file->ptr, &st)
|| st.st_mtime <= pc->ssl_stapling_loadts) {
if (pc->ssl_stapling_nextts < cur_ts) {
/* discard expired OCSP stapling response */
buffer_free(pc->ssl_stapling);
pc->ssl_stapling = NULL;
if (pc->must_staple) {
log_error(srv->errh, __FILE__, __LINE__,
"certificate marked OCSP Must-Staple, "
"but OCSP response expired from ssl.stapling-file %s",
pc->ssl_stapling_file->ptr);
}
}
if (pc->ssl_stapling && pc->ssl_stapling_nextts < cur_ts)
mod_openssl_expire_stapling_file(srv, pc);
return 1;
}
return mod_openssl_reload_stapling_file(srv, pc, cur_ts);

View File

@ -1420,6 +1420,24 @@ mod_openssl_ocsp_next_update (plugin_cert *pc)
}
__attribute_cold__
static void
mod_openssl_expire_stapling_file (server *srv, plugin_cert *pc)
{
if (NULL == pc->ssl_stapling) /*(previously discarded or never loaded)*/
return;
/* discard expired OCSP stapling response */
buffer_free(pc->ssl_stapling);
pc->ssl_stapling = NULL;
if (pc->must_staple)
log_error(srv->errh, __FILE__, __LINE__,
"certificate marked OCSP Must-Staple, "
"but OCSP response expired from ssl.stapling-file %s",
pc->ssl_stapling_file->ptr);
}
static int
mod_openssl_reload_stapling_file (server *srv, plugin_cert *pc, const time_t cur_ts)
{
@ -1437,6 +1455,10 @@ mod_openssl_reload_stapling_file (server *srv, plugin_cert *pc, const time_t cur
pc->ssl_stapling_nextts = cur_ts + 3600;
pc->ssl_stapling_loadts = 0;
}
else if (pc->ssl_stapling_nextts < cur_ts) {
mod_openssl_expire_stapling_file(srv, pc);
return 0;
}
return 1;
}
@ -1445,22 +1467,13 @@ mod_openssl_reload_stapling_file (server *srv, plugin_cert *pc, const time_t cur
static int
mod_openssl_refresh_stapling_file (server *srv, plugin_cert *pc, const time_t cur_ts)
{
if (pc->ssl_stapling && pc->ssl_stapling_nextts - 256 > cur_ts)
if (pc->ssl_stapling && pc->ssl_stapling_nextts > cur_ts + 256)
return 1; /* skip check for refresh unless close to expire */
struct stat st;
if (0 != stat(pc->ssl_stapling_file->ptr, &st)
|| st.st_mtime <= pc->ssl_stapling_loadts) {
if (pc->ssl_stapling_nextts < cur_ts) {
/* discard expired OCSP stapling response */
buffer_free(pc->ssl_stapling);
pc->ssl_stapling = NULL;
if (pc->must_staple) {
log_error(srv->errh, __FILE__, __LINE__,
"certificate marked OCSP Must-Staple, "
"but OCSP response expired from ssl.stapling-file %s",
pc->ssl_stapling_file->ptr);
}
}
if (pc->ssl_stapling && pc->ssl_stapling_nextts < cur_ts)
mod_openssl_expire_stapling_file(srv, pc);
return 1;
}
return mod_openssl_reload_stapling_file(srv, pc, cur_ts);