[Openvpn-devel,v6] tls: reject incoming reneg request if primary key is not fully valid

Message ID 20261110115827.1649-1-gert@greenie.muc.de
State New
Headers
Series [Openvpn-devel,v6] tls: reject incoming reneg request if primary key is not fully valid |

Commit Message

Gert Doering Nov. 10, 2026, 11:58 a.m. UTC
  From: Ralf Lici <ralf@mandelbit.com>

Incoming P_CONTROL_SOFT_RESET_V1 can arrive while the active key is not
yet fully valid for renegotiation. This includes the window where we are
still waiting for auth_deferred_expire (derived from handshake/reneg
timing), as well as cases where deferred or mid-session auth later
leaves the key non-authenticated even though state is S_GENERATED_KEYS.

This patch keeps read_control_auth as the first gate, then rejects the
incoming renegotiation requests unless the primary key is KS_AUTH_TRUE
and auth_deferred_expire has passed.

The rejected request is not counted as a TLS error, since soft TLS
errors trigger an instance restart in TCP mode.

Change-Id: I704c560fa23c03237d0f8adc30908a617265a5a1
Signed-off-by: Ralf Lici <ralf@mandelbit.com>
Acked-by: Arne Schwabe <arne-openvpn@rfc2549.org>
Gerrit URL: https://gerrit.openvpn.net/c/openvpn/+/1478
---

This change was reviewed on Gerrit and approved by at least one
developer. I request to merge it to master.

Gerrit URL: https://gerrit.openvpn.net/c/openvpn/+/1478
This mail reflects revision 6 of this Change.

Acked-by according to Gerrit (reflected above):
Arne Schwabe <arne-openvpn@rfc2549.org>
  

Patch

diff --git a/src/openvpn/ssl.c b/src/openvpn/ssl.c
index 420daef..54223da 100644
--- a/src/openvpn/ssl.c
+++ b/src/openvpn/ssl.c
@@ -3951,6 +3951,21 @@ 
                 goto error;
             }
 
+            /*
+             * Do not allow incoming renegotiation unless our primary key is
+             * fully authenticated and past the deferred-auth/transition gate.
+             */
+            time_t auth_deferred_left = ks->auth_deferred_expire - now;
+            if (ks->authenticated != KS_AUTH_TRUE || auth_deferred_left > 0)
+            {
+                msg(D_TLS_ERRORS,
+                    "TLS: refusing premature incoming renegotiation request for key-id %d: "
+                    "auth=%s, auth_deferred_expire in %d seconds",
+                    ks->key_id, ks_auth_name(ks->authenticated),
+                    auth_deferred_left > 0 ? (int)auth_deferred_left : 0);
+                goto done;
+            }
+
             key_state_soft_reset(session, NULL);
 
             dmsg(D_TLS_DEBUG, "TLS: received P_CONTROL_SOFT_RESET_V1 s=%d sid=%s", i,