Skip to content

Commit 086066c

Browse files
lucabsamugi
authored andcommitted
feat(tls): add SANs support for both DNS-names and URIs
This adds two new Lua functions (and the corresponding C logic) to configure custom SANs validation in nginx: * `resty.kong.tls.set_upstream_ssl_sans_dnsnames()` * `resty.kong.tls.set_upstream_ssl_sans_uris()` Part of KAG-6247.
1 parent 019a595 commit 086066c

File tree

6 files changed

+259
-0
lines changed

6 files changed

+259
-0
lines changed

lualib/resty/kong/tls.lua

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ local get_phase = ngx.get_phase
2323
local type = type
2424
local error = error
2525
local tostring = tostring
26+
local concat = table.concat
2627
local C = ffi.C
2728
local ffi_cast = ffi.cast
2829
local SOCKET_CTX_INDEX = 1
@@ -41,6 +42,8 @@ local kong_lua_kong_ffi_set_upstream_client_cert_and_key
4142
local kong_lua_kong_ffi_set_upstream_ssl_trusted_store
4243
local kong_lua_kong_ffi_set_upstream_ssl_verify
4344
local kong_lua_kong_ffi_set_upstream_ssl_verify_depth
45+
local kong_lua_kong_ffi_set_upstream_ssl_sans_dnsnames
46+
local kong_lua_kong_ffi_set_upstream_ssl_sans_uris
4447
local kong_lua_kong_ffi_get_socket_ssl
4548
local kong_lua_kong_ffi_get_request_ssl
4649
local kong_lua_kong_ffi_disable_http2_alpn
@@ -60,6 +63,10 @@ if subsystem == "http" then
6063
int verify);
6164
int ngx_http_lua_kong_ffi_set_upstream_ssl_verify_depth(ngx_http_request_t *r,
6265
int depth);
66+
int ngx_http_lua_kong_ffi_set_upstream_ssl_sans_dnsnames(ngx_http_request_t *r,
67+
const char *input, size_t input_len);
68+
int ngx_http_lua_kong_ffi_set_upstream_ssl_sans_uris(ngx_http_request_t *r,
69+
const char *input, size_t input_len);
6370
int ngx_http_lua_kong_ffi_get_socket_ssl(ngx_http_lua_socket_tcp_upstream_t *u,
6471
void **ssl_conn);
6572
int ngx_http_lua_kong_ffi_get_request_ssl(ngx_http_request_t *r,
@@ -73,6 +80,8 @@ if subsystem == "http" then
7380
kong_lua_kong_ffi_set_upstream_ssl_trusted_store = C.ngx_http_lua_kong_ffi_set_upstream_ssl_trusted_store
7481
kong_lua_kong_ffi_set_upstream_ssl_verify = C.ngx_http_lua_kong_ffi_set_upstream_ssl_verify
7582
kong_lua_kong_ffi_set_upstream_ssl_verify_depth = C.ngx_http_lua_kong_ffi_set_upstream_ssl_verify_depth
83+
kong_lua_kong_ffi_set_upstream_ssl_sans_dnsnames = C.ngx_http_lua_kong_ffi_set_upstream_ssl_sans_dnsnames
84+
kong_lua_kong_ffi_set_upstream_ssl_sans_uris = C.ngx_http_lua_kong_ffi_set_upstream_ssl_sans_uris
7685
kong_lua_kong_ffi_get_socket_ssl = C.ngx_http_lua_kong_ffi_get_socket_ssl
7786
kong_lua_kong_ffi_get_request_ssl = C.ngx_http_lua_kong_ffi_get_request_ssl
7887
kong_lua_kong_ffi_disable_http2_alpn = C.ngx_http_lua_ffi_disable_http2_alpn
@@ -94,6 +103,10 @@ elseif subsystem == 'stream' then
94103
int verify);
95104
int ngx_stream_lua_kong_ffi_set_upstream_ssl_verify_depth(ngx_stream_lua_request_t *r,
96105
int depth);
106+
int ngx_stream_lua_kong_ffi_set_upstream_ssl_sans_dnsnames(ngx_stream_lua_request_t *r,
107+
const char *input, size_t input_len);
108+
int ngx_stream_lua_kong_ffi_set_upstream_ssl_sans_uris(ngx_stream_lua_request_t *r,
109+
const char *input, size_t input_len);
97110
int ngx_stream_lua_kong_get_socket_ssl(ngx_stream_lua_socket_tcp_upstream_t *u,
98111
void **ssl_conn);
99112
]])
@@ -104,6 +117,8 @@ elseif subsystem == 'stream' then
104117
kong_lua_kong_ffi_set_upstream_ssl_trusted_store = C.ngx_stream_lua_kong_ffi_set_upstream_ssl_trusted_store
105118
kong_lua_kong_ffi_set_upstream_ssl_verify = C.ngx_stream_lua_kong_ffi_set_upstream_ssl_verify
106119
kong_lua_kong_ffi_set_upstream_ssl_verify_depth = C.ngx_stream_lua_kong_ffi_set_upstream_ssl_verify_depth
120+
kong_lua_kong_ffi_set_upstream_ssl_sans_dnsnames = C.ngx_stream_lua_kong_ffi_set_upstream_ssl_sans_dnsnames
121+
kong_lua_kong_ffi_set_upstream_ssl_sans_uris = C.ngx_stream_lua_kong_ffi_set_upstream_ssl_sans_uris
107122
kong_lua_kong_ffi_get_socket_ssl = C.ngx_stream_lua_kong_get_socket_ssl
108123
kong_lua_kong_ffi_get_request_ssl = function()
109124
error("API not available for the current subsystem")
@@ -338,6 +353,64 @@ do
338353
error("unknown return code: " .. tostring(ret))
339354
end
340355

356+
function _M.set_upstream_ssl_sans_dnsnames(sans)
357+
if not ALLOWED_PHASES[get_phase()] then
358+
error("API disabled in the current context", 2)
359+
end
360+
361+
if type(sans) ~= "table" then
362+
error("incorrect argument, expects an array, got " ..
363+
type(sans), 2)
364+
end
365+
366+
if #sans == 0 then
367+
error("incorrect argument, the value can not be an empty array", 2)
368+
end
369+
370+
local r = get_request()
371+
372+
local ssl_sans = concat(sans, " ")
373+
local ret = kong_lua_kong_ffi_set_upstream_ssl_sans_dnsnames(r, ssl_sans, #ssl_sans)
374+
if ret == NGX_OK then
375+
return true
376+
end
377+
378+
if ret == NGX_ERROR then
379+
return nil, "error while setting upstream SSL dnsnames SANs"
380+
end
381+
382+
error("unknown return code: " .. tostring(ret))
383+
end
384+
385+
function _M.set_upstream_ssl_sans_uris(uris)
386+
if not ALLOWED_PHASES[get_phase()] then
387+
error("API disabled in the current context", 2)
388+
end
389+
390+
if type(uris) ~= "table" then
391+
error("incorrect argument, expects an array, got " ..
392+
type(uris), 2)
393+
end
394+
395+
if #uris == 0 then
396+
error("incorrect argument, the value can not be an empty array", 2)
397+
end
398+
399+
local r = get_request()
400+
401+
local ssl_sans = concat(uris, " ")
402+
local ret = kong_lua_kong_ffi_set_upstream_ssl_sans_uris(r, ssl_sans, #ssl_sans)
403+
if ret == NGX_OK then
404+
return true
405+
end
406+
407+
if ret == NGX_ERROR then
408+
return nil, "error while setting upstream SSL URIs SANs"
409+
end
410+
411+
error("unknown return code: " .. tostring(ret))
412+
end
413+
341414
function _M.disable_http2_alpn()
342415
if get_phase() ~= "ssl_client_hello" then
343416
error("API disabled in the current context")

src/ngx_http_lua_kong_module.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,4 +44,10 @@ ngx_flag_t
4444
ngx_http_lua_kong_get_next_upstream_mask(ngx_http_request_t *r,
4545
ngx_flag_t upstream_next);
4646

47+
ngx_str_t *
48+
ngx_http_lua_kong_ssl_get_upstream_ssl_sans_dnsnames(ngx_http_request_t *r);
49+
50+
ngx_str_t *
51+
ngx_http_lua_kong_ssl_get_upstream_ssl_sans_uris(ngx_http_request_t *r);
52+
4753
#endif /* _NGX_HTTP_LUA_KONG_MODULE_H_INCLUDED_ */

src/ngx_http_lua_kong_ssl.c

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,93 @@ ngx_http_lua_ffi_disable_http2_alpn(ngx_http_request_t *r, char **err)
242242
return NGX_OK;
243243
}
244244

245+
246+
int
247+
ngx_http_lua_kong_ffi_set_upstream_ssl_sans_dnsnames(ngx_http_request_t *r,
248+
const char *input, size_t input_len)
249+
{
250+
u_char *sans_data;
251+
ngx_http_lua_kong_ctx_t *ctx;
252+
253+
ctx = ngx_http_lua_kong_get_module_ctx(r);
254+
if (ctx == NULL) {
255+
return NGX_ERROR;
256+
}
257+
258+
sans_data = ngx_palloc(r->pool, input_len);
259+
if (sans_data == NULL) {
260+
return NGX_ERROR;
261+
}
262+
263+
ngx_memcpy(sans_data, input, input_len);
264+
265+
ctx->ssl_ctx.upstream_ssl_sans_dnsnames.data = sans_data;
266+
ctx->ssl_ctx.upstream_ssl_sans_dnsnames.len = input_len;
267+
268+
return NGX_OK;
269+
}
270+
271+
272+
ngx_str_t *
273+
ngx_http_lua_kong_ssl_get_upstream_ssl_sans_dnsnames(ngx_http_request_t *r)
274+
{
275+
ngx_http_lua_kong_ctx_t *ctx;
276+
277+
ctx = ngx_http_lua_kong_get_module_ctx(r);
278+
if (ctx == NULL) {
279+
return NULL;
280+
}
281+
282+
if (ctx->ssl_ctx.upstream_ssl_sans_dnsnames.len == 0) {
283+
return NULL;
284+
}
285+
286+
return &ctx->ssl_ctx.upstream_ssl_sans_dnsnames;
287+
}
288+
289+
int
290+
ngx_http_lua_kong_ffi_set_upstream_ssl_sans_uris(ngx_http_request_t *r,
291+
const char *input, size_t input_len)
292+
{
293+
u_char *sans_data;
294+
ngx_http_lua_kong_ctx_t *ctx;
295+
296+
ctx = ngx_http_lua_kong_get_module_ctx(r);
297+
if (ctx == NULL) {
298+
return NGX_ERROR;
299+
}
300+
301+
sans_data = ngx_palloc(r->pool, input_len);
302+
if (sans_data == NULL) {
303+
return NGX_ERROR;
304+
}
305+
306+
ngx_memcpy(sans_data, input, input_len);
307+
308+
ctx->ssl_ctx.upstream_ssl_sans_uris.data = sans_data;
309+
ctx->ssl_ctx.upstream_ssl_sans_uris.len = input_len;
310+
311+
return NGX_OK;
312+
}
313+
314+
315+
ngx_str_t *
316+
ngx_http_lua_kong_ssl_get_upstream_ssl_sans_uris(ngx_http_request_t *r)
317+
{
318+
ngx_http_lua_kong_ctx_t *ctx;
319+
320+
ctx = ngx_http_lua_kong_get_module_ctx(r);
321+
if (ctx == NULL) {
322+
return NULL;
323+
}
324+
325+
if (ctx->ssl_ctx.upstream_ssl_sans_uris.len == 0) {
326+
return NULL;
327+
}
328+
329+
return &ctx->ssl_ctx.upstream_ssl_sans_uris;
330+
}
331+
245332
#endif
246333

247334

src/ssl/ngx_lua_kong_ssl.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ typedef struct {
2424
EVP_PKEY *upstream_client_private_key;
2525
X509_STORE *upstream_trusted_store;
2626
ngx_uint_t upstream_ssl_verify_depth;
27+
// TODO(lucab): consider changing these two SANs fields into arrays of strings.
28+
ngx_str_t upstream_ssl_sans_dnsnames;
29+
ngx_str_t upstream_ssl_sans_uris;
2730
unsigned upstream_ssl_verify:1;
2831
unsigned upstream_ssl_verify_set:1;
2932
unsigned upstream_ssl_verify_depth_set:1;

stream/src/ngx_stream_lua_kong_module.c

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,90 @@ ngx_stream_lua_kong_get_upstream_ssl_verify(ngx_stream_session_t *s,
297297

298298
return ngx_lua_kong_ssl_get_upstream_ssl_verify(&ctx->ssl_ctx, proxy_ssl_verify);
299299
}
300+
301+
int
302+
ngx_stream_lua_kong_ffi_set_upstream_ssl_sans_dnsnames(ngx_stream_lua_request_t *r,
303+
const char *input, size_t input_len)
304+
{
305+
u_char *sans_data;
306+
ngx_stream_lua_kong_ctx_t *ctx;
307+
308+
ctx = ngx_stream_lua_kong_get_module_ctx(r);
309+
if (ctx == NULL) {
310+
return NGX_ERROR;
311+
}
312+
313+
sans_data = ngx_palloc(r->pool, input_len);
314+
if (sans_data == NULL) {
315+
return NGX_ERROR;
316+
}
317+
318+
ngx_memcpy(sans_data, input, input_len);
319+
320+
ctx->ssl_ctx.upstream_ssl_sans_dnsnames.data = sans_data;
321+
ctx->ssl_ctx.upstream_ssl_sans_dnsnames.len = input_len;
322+
323+
return NGX_OK;
324+
}
325+
326+
ngx_str_t *
327+
ngx_stream_lua_kong_get_upstream_ssl_sans_dnsnames(ngx_stream_session_t *s)
328+
{
329+
ngx_stream_lua_kong_ctx_t *ctx;
330+
331+
ctx = ngx_stream_get_module_ctx(s, ngx_stream_lua_kong_module);
332+
if (ctx == NULL) {
333+
return NULL;
334+
}
335+
336+
if (ctx->ssl_ctx.upstream_ssl_sans_dnsnames.len == 0) {
337+
return NULL;
338+
}
339+
340+
return &ctx->ssl_ctx.upstream_ssl_sans_dnsnames;
341+
}
342+
343+
int
344+
ngx_stream_lua_kong_ffi_set_upstream_ssl_sans_uris(ngx_stream_lua_request_t *r,
345+
const char *input, size_t input_len)
346+
{
347+
u_char *sans_data;
348+
ngx_stream_lua_kong_ctx_t *ctx;
349+
350+
ctx = ngx_stream_lua_kong_get_module_ctx(r);
351+
if (ctx == NULL) {
352+
return NGX_ERROR;
353+
}
354+
355+
sans_data = ngx_palloc(r->pool, input_len);
356+
if (sans_data == NULL) {
357+
return NGX_ERROR;
358+
}
359+
360+
ngx_memcpy(sans_data, input, input_len);
361+
362+
ctx->ssl_ctx.upstream_ssl_sans_uris.data = sans_data;
363+
ctx->ssl_ctx.upstream_ssl_sans_uris.len = input_len;
364+
365+
return NGX_OK;
366+
}
367+
368+
ngx_str_t *
369+
ngx_stream_lua_kong_get_upstream_ssl_sans_uris(ngx_stream_session_t *s)
370+
{
371+
ngx_stream_lua_kong_ctx_t *ctx;
372+
373+
ctx = ngx_stream_get_module_ctx(s, ngx_stream_lua_kong_module);
374+
if (ctx == NULL) {
375+
return NULL;
376+
}
377+
378+
if (ctx->ssl_ctx.upstream_ssl_sans_uris.len == 0) {
379+
return NULL;
380+
}
381+
382+
return &ctx->ssl_ctx.upstream_ssl_sans_uris;
383+
}
300384
#endif
301385

302386

stream/src/ngx_stream_lua_kong_module.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,12 @@ ngx_flag_t
3232
ngx_stream_lua_kong_get_upstream_ssl_verify(ngx_stream_session_t *s,
3333
ngx_flag_t proxy_ssl_verify);
3434

35+
ngx_str_t *
36+
ngx_stream_lua_kong_get_upstream_ssl_sans_dnsnames(ngx_stream_session_t *s);
37+
38+
ngx_str_t *
39+
ngx_stream_lua_kong_get_upstream_ssl_sans_uris(ngx_stream_session_t *s);
40+
3541
#endif
3642

3743
#endif /* _NGX_STREAM_LUA_KONG_MODULE_H_INCLUDED_ */

0 commit comments

Comments
 (0)