Skip to content

Commit 5bac2d8

Browse files
committed
feature: support custom trusted CA store for cosocket TLS handshake.
Adds the cosocket-level plumbing for a new tcpsock:settrustedstore(store) method, allowing Lua code to supply a per-handshake X509_STORE that overrides lua_ssl_trusted_certificate for the upcoming sslhandshake(). This is needed for use cases where the set of trusted CAs is determined at request time (e.g. per-tenant mTLS upstreams). * a new X509_STORE *ssl_trusted_store field on ngx_http_lua_socket_tcp_upstream_t, used as a one-shot slot consumed by the handshake; * the FFI entry point ngx_http_lua_ffi_socket_tcp_settrustedstore() that validates the cosocket state and stores the pointer on the upstream; * SSL_set1_verify_cert_store() invocation inside ngx_http_lua_ffi_socket_tcp_sslhandshake() when a store has been set, with the slot cleared after use so it cannot leak across handshakes. The matching tcpsock:settrustedstore() Lua wrapper will land in lua-resty-core in a separate change. Signed-off-by: Walker Zhao <walker.zhao@konghq.com>
1 parent cf9f7aa commit 5bac2d8

4 files changed

Lines changed: 425 additions & 1 deletion

File tree

doc/HttpLuaModule.wiki

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6662,6 +6662,7 @@ Creates and returns a TCP or stream-oriented unix domain socket object (also kno
66626662
* [[#tcpsock:bind|bind]]
66636663
* [[#tcpsock:connect|connect]]
66646664
* [[#tcpsock:setclientcert|setclientcert]]
6665+
* [[#tcpsock:settrustedstore|settrustedstore]]
66656666
* [[#tcpsock:sslhandshake|sslhandshake]]
66666667
* [[#tcpsock:send|send]]
66676668
* [[#tcpsock:receive|receive]]
@@ -6866,6 +6867,34 @@ that was previously set on the cosocket object.
68666867
68676868
This method was first introduced in the `v0.10.22` release.
68686869
6870+
== tcpsock:settrustedstore ==
6871+
6872+
'''syntax:''' ''ok, err = tcpsock:settrustedstore(x509_store)''
6873+
6874+
'''context:''' ''rewrite_by_lua*, access_by_lua*, content_by_lua*, ngx.timer.*, ssl_certificate_by_lua*, ssl_session_fetch_by_lua*, ssl_client_hello_by_lua*''
6875+
6876+
Set an X509 trusted certificate store on the TCP socket object. The store will be used by the
6877+
[tcpsock:sslhandshake](#tcpsocksslhandshake) method to verify the remote server's certificate, in
6878+
place of the CAs configured by the [[#lua_ssl_trusted_certificate|lua_ssl_trusted_certificate]]
6879+
directive. This is useful when the set of trusted CAs is determined at request time, for example
6880+
when talking to per-tenant upstreams whose CAs are not known at configuration time.
6881+
6882+
* <code>x509_store</code> specifies an <code>X509_STORE *</code> cdata object that will be used
6883+
during the SSL/TLS handshake. Such an object can be built using the
6884+
[resty.openssl.x509.store](https://github.com/fffonion/lua-resty-openssl) library or directly via
6885+
raw OpenSSL FFI bindings.
6886+
6887+
If <code>x509_store</code> is <code>nil</code>, this method will clear any existing trusted store
6888+
that was previously set on the cosocket object.
6889+
6890+
The TCP connection must already be established before calling this method. The trusted store is
6891+
applied to the underlying SSL connection during the next [tcpsock:sslhandshake](#tcpsocksslhandshake)
6892+
call when <code>ssl_verify</code> is <code>true</code>; it is not retained across handshakes, so
6893+
callers wishing to apply it to a subsequent handshake on the same cosocket must call this method
6894+
again.
6895+
6896+
This method was first introduced in the `v0.10.27` release.
6897+
68696898
== tcpsock:sslhandshake ==
68706899
68716900
'''syntax:''' ''session, err = tcpsock:sslhandshake(reused_session?, server_name?, ssl_verify?, send_status_req?)''
@@ -6894,7 +6923,10 @@ the remote.
68946923
The optional <code>ssl_verify</code> argument takes a Lua boolean value to
68956924
control whether to perform SSL verification. When set to <code>true</code>, the server
68966925
certificate will be verified according to the CA certificates specified by
6897-
the [[#lua_ssl_trusted_certificate|lua_ssl_trusted_certificate]] directive.
6926+
the [[#lua_ssl_trusted_certificate|lua_ssl_trusted_certificate]] directive,
6927+
or, if [[#tcpsock:settrustedstore|tcpsock:settrustedstore]] has been called on
6928+
this cosocket, by the X509 store supplied there (which takes precedence for
6929+
this handshake).
68986930
You may also need to adjust the [[#lua_ssl_verify_depth|lua_ssl_verify_depth]]
68996931
directive to control how deep we should follow along the certificate chain.
69006932
Also, when the <code>ssl_verify</code> argument is true and the

src/ngx_http_lua_socket_tcp.c

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1939,6 +1939,16 @@ ngx_http_lua_ffi_socket_tcp_sslhandshake(ngx_http_request_t *r,
19391939

19401940
u->ssl_verify = verify;
19411941

1942+
if (u->ssl_trusted_store) {
1943+
if (SSL_set1_verify_cert_store(ssl_conn, u->ssl_trusted_store) == 0) {
1944+
ERR_clear_error();
1945+
*errmsg = "SSL_set1_verify_cert_store() failed";
1946+
return NGX_ERROR;
1947+
}
1948+
1949+
u->ssl_trusted_store = NULL;
1950+
}
1951+
19421952
if (ocsp_status_req) {
19431953
#ifdef NGX_HTTP_LUA_USE_OCSP
19441954
SSL_set_tlsext_status_type(c->ssl->connection,
@@ -2255,6 +2265,35 @@ ngx_http_lua_ffi_socket_tcp_get_ssl_ctx(ngx_http_request_t *r,
22552265
}
22562266

22572267

2268+
int
2269+
ngx_http_lua_ffi_socket_tcp_settrustedstore(ngx_http_request_t *r,
2270+
ngx_http_lua_socket_tcp_upstream_t *u, void *store, const char **errmsg)
2271+
{
2272+
if (u == NULL
2273+
|| u->peer.connection == NULL
2274+
|| u->read_closed
2275+
|| u->write_closed)
2276+
{
2277+
*errmsg = "closed";
2278+
return NGX_ERROR;
2279+
}
2280+
2281+
if (u->request != r) {
2282+
*errmsg = "bad request";
2283+
return NGX_ERROR;
2284+
}
2285+
2286+
if (store == NULL) {
2287+
*errmsg = "no trusted store";
2288+
return NGX_ERROR;
2289+
}
2290+
2291+
u->ssl_trusted_store = store;
2292+
2293+
return NGX_OK;
2294+
}
2295+
2296+
22582297
#endif /* NGX_HTTP_SSL */
22592298

22602299

src/ngx_http_lua_socket_tcp.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ struct ngx_http_lua_socket_tcp_upstream_s {
135135
ngx_ssl_session_t *ssl_session_ret;
136136
const char *error_ret;
137137
int openssl_error_code_ret;
138+
X509_STORE *ssl_trusted_store;
138139
#endif
139140

140141
ngx_chain_t *busy_bufs;

0 commit comments

Comments
 (0)