-
Notifications
You must be signed in to change notification settings - Fork 275
feature: implement ssl.verify_client()
#289
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
6a51aa4
to
978e012
Compare
@ArchangelSDY this feature looks cool to me, will you please add some test case to cover it? thanks! |
@doujiang24 I've added some tests in this and other repos. Could you take a look? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ArchangelSDY Cool, just found a style issue now, will take a deep look soon.
82f2253
to
8d975a8
Compare
lib/ngx/ssl.lua
Outdated
@@ -78,6 +79,9 @@ if subsystem == 'http' then | |||
void ngx_http_lua_ffi_free_cert(void *cdata); | |||
|
|||
void ngx_http_lua_ffi_free_priv_key(void *cdata); | |||
|
|||
int ngx_http_lua_ffi_ssl_verify_client(void *r, | |||
int depth, void *cdata, char **err); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
style: we can move more arguments to the previous line, like:
int ngx_http_lua_ffi_ssl_verify_client(void *r, int depth, void *cdata,
char **err);
lib/ngx/ssl.md
Outdated
@@ -475,6 +475,28 @@ This function was first added in version `0.1.7`. | |||
|
|||
[Back to TOC](#table-of-contents) | |||
|
|||
verify_client | |||
------------ | |||
**syntax:** *ok, err = ssl.verify_client(depth, ca_certs)* |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
may be this style can be better? we use the depth in ssl_verify_depth
by default.ssl.verify_client(ca_certs, depth?)
.
thoughts? @thibaultcha @agentzh @spacewander
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ping @doujiang24 @thibaultcha @agentzh @spacewander
any comment?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so, what's your opinion for my above suggestion? @ArchangelSDY
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually ca_certs
can also be optional so i think the default form should be just ssl.verify_client()
. I have no preference for the order of parameters. If you prefer ca_certs
first, let me know. @doujiang24
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what the behavior when the ca_certs
is nil
? just rewrite the depth
at the request level?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I prefer ca_certs
first personally, I think it's more often to set ca_certs
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we'd better add a ?
suffix after the argument name if it's optional, clarify the behavior when it's omitted or nil
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When ca_certs
is nil
, it will use system CA list to verify client cert.
Then I will update the order and work on a new patch.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated. @doujiang24
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ArchangelSDY good job. we will merge it after the new release it out in the near feature days if no other ones request changes, and it will be bundled in the next release that will be out in about June.
@ArchangelSDY |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Hi! First of all, thank you for developing this patch! I've been testing it and I run into an issue. When the contents of Test CaseI've got a This is my nginx config:
So I change the content of
While I expect only Now I execute
Is this expected behavior? |
@pommi Nice catch! Looks like I call a wrong API which sets the global store in |
Yes, this works as expected. No nginx reload required anymore. |
Should we add a test case to cover it? |
|
||
|
||
|
||
=== TEST 23: verify client with CA certificates |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test case fails with the following leak error in the valgrind test mode on my side using OpenSSL 1.1.1g:
t/ssl.t .. # I found ONLY: maybe you're debugging?
TEST 23: verify client with CA certificates
t/ssl.t .. 1/14 ==29716== 5,491 (648 direct, 4,843 indirect) bytes in 1 blocks are definitely lost in loss record 43 of 48
==29716== at 0x4C2EE3B: malloc (vg_replace_malloc.c:309)
==29716== by 0x6338608: CRYPTO_zalloc (mem.c:230)
==29716== by 0x5F62C98: SSL_SESSION_new (ssl_sess.c:74)
==29716== by 0x5F63462: ssl_get_new_session (ssl_sess.c:370)
==29716== by 0x5F71319: tls_construct_client_hello (statem_clnt.c:1121)
==29716== by 0x5F7064E: write_state_machine (statem.c:843)
==29716== by 0x5F7064E: state_machine.part.5 (statem.c:443)
==29716== by 0x5F5BEE3: SSL_do_handshake (ssl_lib.c:3663)
==29716== by 0x454067: ngx_ssl_handshake (ngx_event_openssl.c:1606)
==29716== by 0x454067: ngx_ssl_handshake (ngx_event_openssl.c:1593)
==29716== by 0x47C30C: ngx_http_upstream_ssl_init_connection (ngx_http_upstream.c:1721)
==29716== by 0x47C30C: ngx_http_upstream_ssl_init_connection (ngx_http_upstream.c:1668)
==29716== by 0x47D2CB: ngx_http_upstream_init_request (ngx_http_upstream.c:813)
==29716== by 0x470959: ngx_http_read_client_request_body (ngx_http_request_body.c:77)
==29716== by 0x470959: ngx_http_read_client_request_body (ngx_http_request_body.c:30)
==29716== by 0x4B2400: ngx_http_proxy_handler (ngx_http_proxy_module.c:937)
==29716== by 0x4B2400: ngx_http_proxy_handler (ngx_http_proxy_module.c:849)
==29716== by 0x4624DE: ngx_http_core_content_phase (ngx_http_core_module.c:1179)
==29716== by 0x45D354: ngx_http_core_run_phases (ngx_http_core_module.c:868)
==29716== by 0x468C5F: ngx_http_process_request_headers (ngx_http_request.c:1480)
==29716== by 0x469095: ngx_http_process_request_line (ngx_http_request.c:1151)
==29716== by 0x44F067: ngx_epoll_process_events (ngx_epoll_module.c:901)
==29716== by 0x444591: ngx_process_events_and_timers (ngx_event.c:257)
==29716== by 0x44E6A2: ngx_single_process_cycle (ngx_process_cycle.c:333)
==29716== by 0x422CDE: main (nginx.c:382)
==29716==
{
<insert_a_suppression_name_here>
Memcheck:Leak
match-leak-kinds: definite
fun:malloc
fun:CRYPTO_zalloc
fun:SSL_SESSION_new
fun:ssl_get_new_session
fun:tls_construct_client_hello
fun:write_state_machine
fun:state_machine.part.5
fun:SSL_do_handshake
fun:ngx_ssl_handshake
fun:ngx_ssl_handshake
fun:ngx_http_upstream_ssl_init_connection
fun:ngx_http_upstream_ssl_init_connection
fun:ngx_http_upstream_init_request
fun:ngx_http_read_client_request_body
fun:ngx_http_read_client_request_body
fun:ngx_http_proxy_handler
fun:ngx_http_proxy_handler
fun:ngx_http_core_content_phase
fun:ngx_http_core_run_phases
fun:ngx_http_process_request_headers
fun:ngx_http_process_request_line
fun:ngx_epoll_process_events
fun:ngx_process_events_and_timers
fun:ngx_single_process_cycle
fun:main
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed by adding proxy_ssl_session_reuse: off
.
This PR adds an API that allows users to configure SSL client certificate verification dynamically. For example, Nginx can now read SNI first and then determine whether to request a client certificate during handshake. Optionally, caller can pass in a CA list used for verification.
See openresty/lua-nginx-module#1666 for FFI changes.
I hereby granted the copyright of the changes in this pull request
to the authors of this lua-resty-core project.