This is an automated email from the ASF dual-hosted git repository.

markt pushed a commit to branch 1.3.x
in repository https://gitbox.apache.org/repos/asf/tomcat-native.git

commit 5436b9b419b9d86dab92903b13b6b37bf9caf8b6
Author: Mark Thomas <[email protected]>
AuthorDate: Thu Dec 11 15:42:05 2025 +0000

    Add timeout support to reading/writing OCSP requests/responses
---
 native/include/ssl_private.h      |  2 ++
 native/src/sslconf.c              | 27 +++++++++++++++++++++++++++
 native/src/sslutils.c             | 26 ++++++++++++++++----------
 xdocs/miscellaneous/changelog.xml |  4 ++++
 4 files changed, 49 insertions(+), 10 deletions(-)

diff --git a/native/include/ssl_private.h b/native/include/ssl_private.h
index e748c5da5..8a46ba046 100644
--- a/native/include/ssl_private.h
+++ b/native/include/ssl_private.h
@@ -312,6 +312,7 @@ struct tcn_ssl_ctxt_t {
     /* End add from netty-tcnative */
     int             no_ocsp_check;
     int             ocsp_soft_fail;
+    int             ocsp_timeout;
 };
 
 #ifdef HAVE_SSL_CONF_CMD
@@ -322,6 +323,7 @@ struct tcn_ssl_conf_ctxt_t {
     SSL_CONF_CTX    *cctx;
     int             no_ocsp_check;
     int             ocsp_soft_fail;
+    int             ocsp_timeout;
 };
 #endif
 
diff --git a/native/src/sslconf.c b/native/src/sslconf.c
index 8ee5680be..f5b5e5e82 100644
--- a/native/src/sslconf.c
+++ b/native/src/sslconf.c
@@ -175,6 +175,19 @@ TCN_IMPLEMENT_CALL(jint, SSLConf, check)(TCN_STDARGS, 
jlong cctx,
         return 1;
     }
 
+    if (!strcmp(J2S(cmd), "OCSP_TIMEOUT")) {
+        int i;
+        errno = 0;
+        i = (int) strtol(J2S(value), NULL, 10);
+        if (!errno) {
+            // Tomcat configures timeout is millisecond. APR uses microseconds.
+            c->ocsp_timeout = i * 1000;
+        }
+        TCN_FREE_CSTRING(cmd);
+        TCN_FREE_CSTRING(value);
+        return 1;
+    }
+
     SSL_ERR_clear();
     value_type = SSL_CONF_cmd_value_type(c->cctx, J2S(cmd));
     ec = SSL_ERR_get();
@@ -230,6 +243,8 @@ TCN_IMPLEMENT_CALL(void, SSLConf, assign)(TCN_STDARGS, 
jlong cctx,
     SSL_CONF_CTX_set_ssl_ctx(c->cctx, sc->ctx);
     sc->no_ocsp_check = c->no_ocsp_check;
     sc->ocsp_soft_fail = c->ocsp_soft_fail;
+    sc->ocsp_timeout = c->ocsp_timeout;
+    // TODO verify
 }
 
 /* Apply a command to an SSL_CONF context */
@@ -287,6 +302,18 @@ TCN_IMPLEMENT_CALL(jint, SSLConf, apply)(TCN_STDARGS, 
jlong cctx,
         TCN_FREE_CSTRING(value);
         return 1;
     }
+    if (!strcmp(J2S(cmd), "OCSP_TIMEOUT")) {
+        int i;
+        errno = 0;
+        i = (int) strtol(J2S(value), NULL, 10);
+        if (!errno) {
+            // Tomcat configures timeout is millisecond. APR uses microseconds.
+            c->ocsp_timeout = i * 1000;
+        }
+        TCN_FREE_CSTRING(cmd);
+        TCN_FREE_CSTRING(value);
+        return 1;
+    }
     SSL_ERR_clear();
     rc = SSL_CONF_cmd(c->cctx, J2S(cmd), buf != NULL ? buf : J2S(value));
     ec = SSL_ERR_get();
diff --git a/native/src/sslutils.c b/native/src/sslutils.c
index ded6eb67a..0b34f2627 100644
--- a/native/src/sslutils.c
+++ b/native/src/sslutils.c
@@ -34,8 +34,8 @@ extern int WIN32_SSL_password_prompt(tcn_pass_cb_t *data);
 #define ASN1_SEQUENCE 0x30
 #define ASN1_OID      0x06
 #define ASN1_STRING   0x86
-static int ssl_verify_OCSP(X509_STORE_CTX *ctx);
-static int ssl_ocsp_request(X509 *cert, X509 *issuer, X509_STORE_CTX *ctx);
+static int ssl_verify_OCSP(X509_STORE_CTX *ctx, int timeout);
+static int ssl_ocsp_request(X509 *cert, X509 *issuer, X509_STORE_CTX *ctx, int 
timeout);
 #endif
 
 /*  _________________________________________________________________
@@ -325,6 +325,7 @@ int SSL_callback_SSL_verify(int ok, X509_STORE_CTX *ctx)
     int depth             = con->ctx->verify_depth;
     int ocsp_check_type   = con->ctx->no_ocsp_check;
     int ocsp_soft_fail    = con->ctx->ocsp_soft_fail;
+    int ocsp_timeout      = con->ctx->ocsp_timeout;
 
 #if defined(SSL_OP_NO_TLSv1_3)
     con->pha_state = PHA_COMPLETE;
@@ -370,7 +371,7 @@ int SSL_callback_SSL_verify(int ok, X509_STORE_CTX *ctx)
                 ok = 0;
             }
             else {
-                int ocsp_response = ssl_verify_OCSP(ctx);
+                int ocsp_response = ssl_verify_OCSP(ctx, ocsp_timeout);
                 if (ocsp_response == OCSP_STATUS_REVOKED) {
                     ok = 0 ;
                     errnum = X509_STORE_CTX_get_error(ctx);
@@ -513,7 +514,7 @@ int SSL_callback_alpn_select_proto(SSL* ssl, const unsigned 
char **out, unsigned
 #ifdef HAVE_OCSP
 
 /* Function that is used to do the OCSP verification */
-static int ssl_verify_OCSP(X509_STORE_CTX *ctx)
+static int ssl_verify_OCSP(X509_STORE_CTX *ctx, int timeout)
 {
     X509 *cert, *issuer;
     int r = OCSP_STATUS_UNKNOWN;
@@ -538,7 +539,7 @@ static int ssl_verify_OCSP(X509_STORE_CTX *ctx)
     /* if we can't get the issuer, we cannot perform OCSP verification */
     issuer = X509_STORE_CTX_get0_current_issuer(ctx);
     if (issuer != NULL) {
-        r = ssl_ocsp_request(cert, issuer, ctx);
+        r = ssl_ocsp_request(cert, issuer, ctx, timeout);
         switch (r) {
         case OCSP_STATUS_OK:
             X509_STORE_CTX_set_error(ctx, X509_V_OK);
@@ -978,7 +979,7 @@ static OCSP_REQUEST *get_ocsp_request(X509 *cert, X509 
*issuer)
 }
 
 /* Submits an OCSP request and returns the OCSP_RESPONSE */
-static OCSP_RESPONSE *get_ocsp_response(apr_pool_t *p, char *url, OCSP_REQUEST 
*ocsp_req)
+static OCSP_RESPONSE *get_ocsp_response(apr_pool_t *p, char *url, OCSP_REQUEST 
*ocsp_req, int timeout)
 {
     OCSP_RESPONSE *ocsp_resp = NULL;
     BIO *bio_req;
@@ -1009,6 +1010,8 @@ static OCSP_RESPONSE *get_ocsp_response(apr_pool_t *p, 
char *url, OCSP_REQUEST *
         goto free_bio;
     }
 
+    apr_socket_timeout_set(apr_sock, timeout);
+
     ok = ocsp_send_req(apr_sock, bio_req);
     if (ok) {
         ocsp_resp = ocsp_get_resp(mp, apr_sock);
@@ -1095,7 +1098,7 @@ clean_bs:
     return o;
 }
 
-static int ssl_ocsp_request(X509 *cert, X509 *issuer, X509_STORE_CTX *ctx)
+static int ssl_ocsp_request(X509 *cert, X509 *issuer, X509_STORE_CTX *ctx, int 
timeout)
 {
     char **ocsp_urls = NULL;
     int nid;
@@ -1124,13 +1127,16 @@ static int ssl_ocsp_request(X509 *cert, X509 *issuer, 
X509_STORE_CTX *ctx)
            approach is to iterate for all the possible ocsp urls */
         req = get_ocsp_request(cert, issuer);
         if (req != NULL) {
-            resp = get_ocsp_response(p, ocsp_urls[0], req);
+            resp = get_ocsp_response(p, ocsp_urls[0], req, timeout);
             if (resp != NULL) {
                 rv = process_ocsp_response(req, resp, cert, issuer, ctx);
             } else {
-                /* correct error code for application errors? */
-                X509_STORE_CTX_set_error(ctx, 
X509_V_ERR_APPLICATION_VERIFICATION);
+                /* Unable to send request / receive response. */
+                X509_STORE_CTX_set_error(ctx, X509_V_ERR_UNABLE_TO_GET_CRL);
             }
+        } else {
+            /* correct error code for application errors? */
+            X509_STORE_CTX_set_error(ctx, X509_V_ERR_APPLICATION_VERIFICATION);
         }
 
         if (req != NULL) {
diff --git a/xdocs/miscellaneous/changelog.xml 
b/xdocs/miscellaneous/changelog.xml
index 2f0b6ddc4..8ba5607ae 100644
--- a/xdocs/miscellaneous/changelog.xml
+++ b/xdocs/miscellaneous/changelog.xml
@@ -64,6 +64,10 @@
       responder cannot be contacted or fails to respond in a timely manner the
       OCSP check will not fail. (markt)
     </add>
+    <add>
+      Add a configurable timeout to the writing of OCSP requests and reading of
+      OCSP responses. (markt)
+    </add>
   </changelog>
 </section>
 <section name="Changes in 1.3.1">


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to