Skip to content

Commit bb4de59

Browse files
committed
feat(ssl): add function to get upstream ssl certificate
FTI-6676 Signed-off-by: Walker Zhao <[email protected]>
1 parent 019a595 commit bb4de59

File tree

4 files changed

+131
-0
lines changed

4 files changed

+131
-0
lines changed

lualib/resty/kong/tls.lua

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ local errmsg = base.get_errmsg_ptr()
3535
local FFI_OK = base.FFI_OK
3636
base.allows_subsystem('http', 'stream')
3737

38+
local kong_lua_kong_ffi_get_full_upstream_certificate
3839
local kong_lua_kong_ffi_get_full_client_certificate_chain
3940
local kong_lua_kong_ffi_disable_session_reuse
4041
local kong_lua_kong_ffi_set_upstream_client_cert_and_key
@@ -49,6 +50,8 @@ if subsystem == "http" then
4950
typedef struct ssl_st SSL;
5051
typedef struct ngx_http_lua_socket_tcp_upstream_s ngx_http_lua_socket_tcp_upstream_t;
5152
53+
int ngx_http_lua_kong_ffi_get_full_upstream_certificate(
54+
ngx_http_request_t *r, char *buf, size_t *buf_len);
5255
int ngx_http_lua_kong_ffi_get_full_client_certificate_chain(
5356
ngx_http_request_t *r, char *buf, size_t *buf_len);
5457
const char *ngx_http_lua_kong_ffi_disable_session_reuse(ngx_http_request_t *r);
@@ -67,6 +70,7 @@ if subsystem == "http" then
6770
int ngx_http_lua_ffi_disable_http2_alpn(ngx_http_request_t *r, char **err);
6871
]])
6972

73+
kong_lua_kong_ffi_get_full_upstream_certificate = C.ngx_http_lua_kong_ffi_get_full_upstream_certificate
7074
kong_lua_kong_ffi_get_full_client_certificate_chain = C.ngx_http_lua_kong_ffi_get_full_client_certificate_chain
7175
kong_lua_kong_ffi_disable_session_reuse = C.ngx_http_lua_kong_ffi_disable_session_reuse
7276
kong_lua_kong_ffi_set_upstream_client_cert_and_key = C.ngx_http_lua_kong_ffi_set_upstream_client_cert_and_key
@@ -98,6 +102,9 @@ elseif subsystem == 'stream' then
98102
void **ssl_conn);
99103
]])
100104

105+
kong_lua_kong_ffi_get_full_upstream_certificate = function()
106+
error("API not available for the current subsystem")
107+
end
101108
kong_lua_kong_ffi_get_full_client_certificate_chain = C.ngx_stream_lua_kong_ffi_get_full_client_certificate_chain
102109
kong_lua_kong_ffi_disable_session_reuse = C.ngx_stream_lua_kong_ffi_disable_session_reuse
103110
kong_lua_kong_ffi_set_upstream_client_cert_and_key = C.ngx_stream_lua_kong_ffi_set_upstream_client_cert_and_key
@@ -174,6 +181,42 @@ function _M.get_request_ssl_pointer()
174181
end
175182

176183

184+
function _M.get_full_upstream_certificate()
185+
local r = get_request()
186+
187+
size_ptr[0] = DEFAULT_CERT_CHAIN_SIZE
188+
189+
::again::
190+
191+
local buf = get_string_buf(size_ptr[0])
192+
193+
local ret = kong_lua_kong_ffi_get_full_upstream_certificate(
194+
r, buf, size_ptr)
195+
if ret == NGX_OK then
196+
return ffi_string(buf, size_ptr[0])
197+
end
198+
199+
if ret == NGX_ERROR then
200+
return nil, "error while obtaining client certificate chain"
201+
end
202+
203+
if ret == NGX_ABORT then
204+
return nil,
205+
"connection is not TLS or TLS support for Nginx not enabled"
206+
end
207+
208+
if ret == NGX_DECLINED then
209+
return nil
210+
end
211+
212+
if ret == NGX_AGAIN then
213+
goto again
214+
end
215+
216+
error("unknown return code: " .. tostring(ret))
217+
end
218+
219+
177220
do
178221
local ALLOWED_PHASES = {
179222
['rewrite'] = true,

src/ngx_http_lua_kong_ssl.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,30 @@ ngx_http_lua_kong_ffi_disable_session_reuse(ngx_http_request_t *r)
3636
}
3737

3838

39+
int
40+
ngx_http_lua_kong_ffi_get_full_upstream_certificate(ngx_http_request_t *r,
41+
char *buf, size_t *buf_len)
42+
{
43+
#if (NGX_SSL)
44+
ngx_http_upstream_t *u = r->upstream;
45+
if (u == NULL) {
46+
return NGX_ABORT;
47+
}
48+
ngx_peer_connection_t *peer = &(u->peer);
49+
if (peer == NULL) {
50+
return NGX_ABORT;
51+
}
52+
ngx_connection_t *c = peer->connection;
53+
if (c == NULL) {
54+
return NGX_ABORT;
55+
}
56+
return ngx_lua_kong_ssl_get_full_upstream_certificate(c, buf, buf_len);
57+
#else
58+
return NGX_ABORT;
59+
#endif
60+
}
61+
62+
3963
int
4064
ngx_http_lua_kong_ffi_get_full_client_certificate_chain(ngx_http_request_t *r,
4165
char *buf, size_t *buf_len)

src/ssl/ngx_lua_kong_ssl.c

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,68 @@ ngx_lua_kong_ssl_disable_session_reuse(ngx_connection_t *c)
127127
}
128128

129129

130+
int
131+
ngx_lua_kong_ssl_get_full_upstream_certificate(ngx_connection_t *c,
132+
char *buf, size_t *buf_len)
133+
{
134+
ngx_ssl_conn_t *sc;
135+
STACK_OF(X509) *chain;
136+
X509 *cert;
137+
int i, n;
138+
size_t len;
139+
BIO *bio;
140+
int ret;
141+
142+
if (c->ssl == NULL) {
143+
return NGX_ABORT;
144+
}
145+
146+
cert = SSL_get_peer_certificate(c->ssl->connection);
147+
if (cert == NULL) {
148+
/* client did not present a certificate or server did not request it */
149+
return NGX_DECLINED;
150+
}
151+
152+
bio = BIO_new(BIO_s_mem());
153+
if (bio == NULL) {
154+
ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "BIO_new() failed");
155+
156+
X509_free(cert);
157+
ret = NGX_ERROR;
158+
goto done;
159+
}
160+
161+
if (PEM_write_bio_X509(bio, cert) == 0) {
162+
ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "PEM_write_bio_X509() failed");
163+
164+
X509_free(cert);
165+
ret = NGX_ERROR;
166+
goto done;
167+
}
168+
169+
X509_free(cert);
170+
171+
len = BIO_pending(bio);
172+
if (len > *buf_len) {
173+
*buf_len = len;
174+
175+
ret = NGX_AGAIN;
176+
goto done;
177+
}
178+
179+
BIO_read(bio, buf, len);
180+
*buf_len = len;
181+
182+
ret = NGX_OK;
183+
184+
done:
185+
186+
BIO_free(bio);
187+
188+
return ret;
189+
}
190+
191+
130192
int
131193
ngx_lua_kong_ssl_get_full_client_certificate_chain(ngx_connection_t *c,
132194
char *buf, size_t *buf_len)

src/ssl/ngx_lua_kong_ssl.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ ngx_int_t ngx_lua_kong_ssl_init(ngx_conf_t *cf);
3333
const char *ngx_lua_kong_ssl_disable_session_reuse(ngx_connection_t *c);
3434
int ngx_lua_kong_ssl_get_full_client_certificate_chain(ngx_connection_t *c,
3535
char *buf, size_t *buf_len);
36+
int ngx_lua_kong_ssl_get_full_upstream_certificate(ngx_connection_t *c,
37+
char *buf, size_t *buf_len);
3638

3739
void ngx_lua_kong_ssl_set_upstream_ssl(ngx_lua_kong_ssl_ctx_t *ctx, ngx_connection_t *c);
3840
void ngx_lua_kong_ssl_cleanup(ngx_lua_kong_ssl_ctx_t *ctx);

0 commit comments

Comments
 (0)