[Openvpn-devel,2/2] Make CRL reload EOF detection independent of stale error queue entries

Message ID 20260922140520.71500-3-drew@linuxkids.com
State New
Headers
Series Stop failed cipher/digest lookups from polluting the OpenSSL error queue |

Commit Message

Drew Blokzyl Sept. 22, 2026, 2:05 p.m. UTC
  backend_tls_ctx_reload_crl() treats a NULL from PEM_read_bio_X509_CRL()
as EOF when ERR_peek_error() shows PEM_R_NO_START_LINE. ERR_peek_error()
returns the OLDEST queued error, so any entry left behind earlier in the
thread turns a clean EOF into a "CRL: cannot read CRL from file" warning,
prints the unrelated errors as if they came from the CRL file, and still
installs the CRLs already parsed. The previous commit removes the
leftover that triggered this in practice; this one stops the loop from
depending on the queue being clean at all.

Start the loop from an empty queue so only errors raised by
PEM_read_bio_X509_CRL() are visible, test the error it raised last rather
than the oldest one, and clear the queue on the EOF path instead of
popping a single entry.

Signed-off-by: Drew Blokzyl <drew@linuxkids.com>
---
 src/openvpn/ssl_openssl.c | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)
  

Patch

diff --git a/src/openvpn/ssl_openssl.c b/src/openvpn/ssl_openssl.c
index 7cfe9f4a..da3e07fe 100644
--- a/src/openvpn/ssl_openssl.c
+++ b/src/openvpn/ssl_openssl.c
@@ -1360,6 +1360,13 @@  backend_tls_ctx_reload_crl(struct tls_root_ctx *ssl_ctx, const char *crl_file, b
     }
 
     int num_crls_loaded = 0;
+    /*
+     * Start from an empty error queue so the EOF test below only sees errors
+     * raised by PEM_read_bio_X509_CRL(). A stale error left by an earlier
+     * operation in this thread would otherwise be what ERR_peek_error()
+     * returns, and a clean EOF gets reported as "cannot read CRL".
+     */
+    ERR_clear_error();
     while (true)
     {
         X509_CRL *crl = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL);
@@ -1367,13 +1374,15 @@  backend_tls_ctx_reload_crl(struct tls_root_ctx *ssl_ctx, const char *crl_file, b
         {
             /*
              * PEM_R_NO_START_LINE can be considered equivalent to EOF.
+             * ERR_peek_last_error() is the error PEM_read_bio_X509_CRL()
+             * raised last; ERR_peek_error() would be the oldest queued one.
              */
-            bool eof = ERR_GET_REASON(ERR_peek_error()) == PEM_R_NO_START_LINE;
+            bool eof = ERR_GET_REASON(ERR_peek_last_error()) == PEM_R_NO_START_LINE;
             /* but warn if no CRLs have been loaded */
             if (num_crls_loaded > 0 && eof)
             {
                 /* remove that error from error stack */
-                (void)ERR_get_error();
+                ERR_clear_error();
                 break;
             }