Skip to content

bugfix: reject settrustedstore on already-handshaked cosocket#1

Merged
perfgao merged 2 commits into
masterfrom
fix/settrustedstore-after-handshake
Jun 5, 2026
Merged

bugfix: reject settrustedstore on already-handshaked cosocket#1
perfgao merged 2 commits into
masterfrom
fix/settrustedstore-after-handshake

Conversation

@perfgao
Copy link
Copy Markdown
Owner

@perfgao perfgao commented May 29, 2026

Summary

tcpsock:settrustedstore() called on a cosocket whose TLS handshake has already completed silently became a no-op, while appearing to succeed. The new X509_STORE was stashed into u->ssl_trusted_store, but a subsequent tcpsock:sslhandshake() short-circuits via the c->ssl->handshaked early return in ngx_http_lua_ffi_socket_tcp_sslhandshake and never reaches the SSL_set1_verify_cert_store() block at src/ngx_http_lua_socket_tcp.c:1942. The connection therefore kept verifying the peer against the trust anchor configured before the first handshake.

Fix

Reject the call at the FFI entry when the underlying TLS connection is already established, so callers get a clear error instead of a silently ineffective swap. Scope is intentionally narrow — only ngx_http_lua_ffi_socket_tcp_settrustedstore. The handshake state machine and session-reuse semantics are unchanged. Returning NGX_ERROR here is the existing FFI argument-validation path; it does not close the connection.

Tests

Adds TEST 6 in t/193-ssl-trusted-store.t:

  1. Initial settrustedstore + sslhandshake succeeds (positive path unchanged).
  2. Second settrustedstore on the already-handshaked cosocket returns nil, "ssl handshake already done; trusted store cannot be changed on an established TLS connection".
  3. The connection remains usable for subsequent send/receive after the rejected call.

Mirrors the upstream PR openresty#2505.

perfgao added 2 commits May 29, 2026 10:51
Calling tcpsock:settrustedstore() after sslhandshake() has completed
silently stashed the new X509_STORE into u->ssl_trusted_store, but the
next sslhandshake() short-circuits via the c->ssl->handshaked check and
never reaches the SSL_set1_verify_cert_store() block, so peer
verification kept using the original trust anchor.

Reject the call at the FFI entry when the underlying TLS connection is
already established so callers get a clear error instead of a silently
ineffective trust-anchor swap. The fix is contained to the FFI argument
validation path and does not touch the handshake state machine.
Verifies that calling tcpsock:settrustedstore() on an already-handshaked
cosocket now fails with a clear error message instead of silently
stashing an X509_STORE that never takes effect, and that the rejected
call leaves the existing TLS connection usable for subsequent I/O.
@perfgao perfgao closed this May 29, 2026
@perfgao perfgao reopened this May 29, 2026
@perfgao perfgao merged commit 2358d4a into master Jun 5, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant