From 85c2fc9d5753d39e34ee82df2bdff6634c01105d Mon Sep 17 00:00:00 2001 From: lijunlong Date: Sat, 30 Oct 2021 13:28:54 +0800 Subject: [PATCH 1/5] feature: added new ffi function ngx_http_lua_ffi_ssl_ciphers. --- src/ngx_http_lua_ssl_certby.c | 103 ++++++++++++++++++++++++++++++++++ t/139-ssl-cert-by.t | 101 +++++++++++++++++++++++++++++++++ t/166-ssl-client-hello.t | 1 + 3 files changed, 205 insertions(+) diff --git a/src/ngx_http_lua_ssl_certby.c b/src/ngx_http_lua_ssl_certby.c index b561122b13..bee7ed6360 100644 --- a/src/ngx_http_lua_ssl_certby.c +++ b/src/ngx_http_lua_ssl_certby.c @@ -961,6 +961,109 @@ ngx_http_lua_ffi_ssl_raw_client_addr(ngx_http_request_t *r, char **addr, } +int +ngx_http_lua_ffi_ssl_ciphers(ngx_http_request_t *r, char **pciphers, + size_t *cipherslen, char **err) +{ + ngx_pool_t *pool; + ngx_ssl_conn_t *ssl_conn; + ngx_connection_t *c; + + if (r->connection == NULL || r->connection->ssl == NULL) { + *err = "bad request"; + return NGX_ERROR; + } + + ssl_conn = r->connection->ssl->connection; + if (ssl_conn == NULL) { + *err = "bad ssl conn"; + return NGX_ERROR; + } + + pool = r->pool; + c = ngx_ssl_get_connection(ssl_conn); + +#ifdef SSL_CTRL_GET_RAW_CIPHERLIST + + int n, i, bytes; + size_t len; + u_char *ciphers, *p; + const SSL_CIPHER *cipher; + + bytes = SSL_get0_raw_cipherlist(c->ssl->connection, NULL); + n = SSL_get0_raw_cipherlist(c->ssl->connection, &ciphers); + + if (n <= 0) { + *cipherslen = 0; + return NGX_OK; + } + + len = 0; + n /= bytes; + + for (i = 0; i < n; i++) { + cipher = SSL_CIPHER_find(c->ssl->connection, ciphers + i * bytes); + + if (cipher) { + len += ngx_strlen(SSL_CIPHER_get_name(cipher)); + + } else { + len += sizeof("0x") - 1 + bytes * (sizeof("00") - 1); + } + + len += sizeof(":") - 1; + } + + *pciphers = ngx_pnalloc(pool, len); + if (*pciphers == NULL) { + return NGX_ERROR; + } + + p = (u_char *) *pciphers; + + for (i = 0; i < n; i++) { + cipher = SSL_CIPHER_find(c->ssl->connection, ciphers + i * bytes); + + if (cipher) { + p = ngx_sprintf(p, "%s", SSL_CIPHER_get_name(cipher)); + + } else { + p = ngx_sprintf(p, "0x"); + p = ngx_hex_dump(p, ciphers + i * bytes, bytes); + } + + *p++ = ':'; + } + + p--; + + *cipherslen = p - (u_char *) *pciphers; + +#else + + u_char buf[4096]; + + if (SSL_get_shared_ciphers(c->ssl->connection, (char *) buf, 4096) + == NULL) + { + *cipherslen = 0; + return NGX_OK; + } + + *cipherslen = ngx_strlen(buf); + *pciphers = ngx_pnalloc(pool, *cipherslen); + if (*pciphers == NULL) { + return NGX_ERROR; + } + + ngx_memcpy(*pciphers, buf, *cipherslen); + +#endif + + return NGX_OK; +} + + int ngx_http_lua_ffi_cert_pem_to_der(const u_char *pem, size_t pem_len, u_char *der, char **err) diff --git a/t/139-ssl-cert-by.t b/t/139-ssl-cert-by.t index d7e20bafea..aa748bcb4e 100644 --- a/t/139-ssl-cert-by.t +++ b/t/139-ssl-cert-by.t @@ -2321,3 +2321,104 @@ ssl handshake: userdata uthread: hello from f() uthread: killed uthread: failed to kill: already waited or killed + + + +=== TEST 27: get ciphers +--- http_config + lua_package_path "../lua-resty-core/lib/?.lua;;"; + lua_ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384; + + server { + listen 127.0.0.1:12345 ssl; + server_name test.com; + + ssl_certificate_by_lua_block { + local ssl = require "ngx.ssl" + print("ciphers: ", ssl.ciphers()) + } + ssl_certificate ../../cert/test.crt; + ssl_certificate_key ../../cert/test.key; + + server_tokens off; + location /foo { + default_type 'text/plain'; + content_by_lua_block { ngx.status = 201 ngx.say("foo") ngx.exit(201) } + more_clear_headers Date; + } + } +--- config + server_tokens off; + lua_ssl_trusted_certificate ../../cert/test.crt; + + location /t { + content_by_lua_block { + do + local sock = ngx.socket.tcp() + + sock:settimeout(2000) + + local ok, err = sock:connect("127.0.0.1", 12345) + if not ok then + ngx.say("failed to connect: ", err) + return + end + + ngx.say("connected: ", ok) + + local sess, err = sock:sslhandshake(nil, "test.com", true) + if not sess then + ngx.say("failed to do SSL handshake: ", err) + return + end + + ngx.say("ssl handshake: ", type(sess)) + + local req = "GET /foo HTTP/1.0\r\nHost: test.com\r\nConnection: close\r\n\r\n" + local bytes, err = sock:send(req) + if not bytes then + ngx.say("failed to send http request: ", err) + return + end + + ngx.say("sent http request: ", bytes, " bytes.") + + while true do + local line, err = sock:receive() + if not line then + -- ngx.say("failed to receive response status line: ", err) + break + end + + ngx.say("received: ", line) + end + + local ok, err = sock:close() + ngx.say("close: ", ok, " ", err) + end -- do + -- collectgarbage() + } + } + +--- request +GET /t +--- response_body +connected: 1 +ssl handshake: userdata +sent http request: 56 bytes. +received: HTTP/1.1 201 Created +received: Server: nginx +received: Content-Type: text/plain +received: Content-Length: 4 +received: Connection: close +received: +received: foo +close: 1 nil + +--- error_log +ciphers: ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:TLS_EMPTY_RENEGOTIATION_INFO_SCSV + +--- no_error_log +[error] +[alert] +[crit] diff --git a/t/166-ssl-client-hello.t b/t/166-ssl-client-hello.t index 79787f63a0..eef08d7cba 100644 --- a/t/166-ssl-client-hello.t +++ b/t/166-ssl-client-hello.t @@ -2140,6 +2140,7 @@ ssl_client_hello_by_lua:1: ssl client hello by lua is running! local ip = string.format("%d.%d.%d.%d", byte(addr, 1), byte(addr, 2), byte(addr, 3), byte(addr, 4)) print("client ip: ", ip) + } ssl_certificate ../../cert/test.crt; ssl_certificate_key ../../cert/test.key; From 3a99dad0cb8e977559ff86ed133bb6c8892a2248 Mon Sep 17 00:00:00 2001 From: lijunlong Date: Sat, 30 Oct 2021 13:42:33 +0800 Subject: [PATCH 2/5] tests: change branch of lua-resty-core for ci. --- .travis.yml | 2 +- t/139-ssl-cert-by.t | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 5a60f5e43a..01e447ba94 100644 --- a/.travis.yml +++ b/.travis.yml @@ -87,7 +87,7 @@ install: - git clone https://github.com/openresty/rds-json-nginx-module.git ../rds-json-nginx-module - git clone https://github.com/openresty/srcache-nginx-module.git ../srcache-nginx-module - git clone https://github.com/openresty/redis2-nginx-module.git ../redis2-nginx-module - - git clone https://github.com/openresty/lua-resty-core.git ../lua-resty-core + - git clone -b ciphers https://github.com/openresty/lua-resty-core.git ../lua-resty-core - git clone https://github.com/openresty/lua-resty-lrucache.git ../lua-resty-lrucache - git clone https://github.com/openresty/lua-resty-mysql.git ../lua-resty-mysql - git clone https://github.com/openresty/lua-resty-string.git ../lua-resty-string diff --git a/t/139-ssl-cert-by.t b/t/139-ssl-cert-by.t index aa748bcb4e..415597b4b7 100644 --- a/t/139-ssl-cert-by.t +++ b/t/139-ssl-cert-by.t @@ -2327,7 +2327,7 @@ uthread: failed to kill: already waited or killed === TEST 27: get ciphers --- http_config lua_package_path "../lua-resty-core/lib/?.lua;;"; - lua_ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384; + lua_ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384; server { listen 127.0.0.1:12345 ssl; @@ -2416,7 +2416,7 @@ received: foo close: 1 nil --- error_log -ciphers: ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:TLS_EMPTY_RENEGOTIATION_INFO_SCSV +ciphers: ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384 --- no_error_log [error] From 6c3f3f0f448c10fd68641b08a4b71fdeea17884f Mon Sep 17 00:00:00 2001 From: lijunlong Date: Sun, 31 Oct 2021 08:48:16 +0800 Subject: [PATCH 3/5] set err message when can not alloc. --- src/ngx_http_lua_ssl_certby.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/ngx_http_lua_ssl_certby.c b/src/ngx_http_lua_ssl_certby.c index bee7ed6360..153d251526 100644 --- a/src/ngx_http_lua_ssl_certby.c +++ b/src/ngx_http_lua_ssl_certby.c @@ -1016,6 +1016,7 @@ ngx_http_lua_ffi_ssl_ciphers(ngx_http_request_t *r, char **pciphers, *pciphers = ngx_pnalloc(pool, len); if (*pciphers == NULL) { + *err = "no memory"; return NGX_ERROR; } @@ -1053,6 +1054,7 @@ ngx_http_lua_ffi_ssl_ciphers(ngx_http_request_t *r, char **pciphers, *cipherslen = ngx_strlen(buf); *pciphers = ngx_pnalloc(pool, *cipherslen); if (*pciphers == NULL) { + *err = "no memory"; return NGX_ERROR; } From dbd98128b157afd1906a18f2abca246f5b669186 Mon Sep 17 00:00:00 2001 From: lijunlong Date: Sun, 31 Oct 2021 18:35:07 +0800 Subject: [PATCH 4/5] call ngx_ssl_get_ciphers instead. --- src/ngx_http_lua_ssl_certby.c | 94 +++-------------------------------- 1 file changed, 8 insertions(+), 86 deletions(-) diff --git a/src/ngx_http_lua_ssl_certby.c b/src/ngx_http_lua_ssl_certby.c index 153d251526..7fe053f71b 100644 --- a/src/ngx_http_lua_ssl_certby.c +++ b/src/ngx_http_lua_ssl_certby.c @@ -965,102 +965,24 @@ int ngx_http_lua_ffi_ssl_ciphers(ngx_http_request_t *r, char **pciphers, size_t *cipherslen, char **err) { - ngx_pool_t *pool; - ngx_ssl_conn_t *ssl_conn; + ngx_int_t rc; + ngx_str_t ciphers; ngx_connection_t *c; - if (r->connection == NULL || r->connection->ssl == NULL) { + c = r->connection; + if (c == NULL || c->ssl == NULL) { *err = "bad request"; return NGX_ERROR; } - ssl_conn = r->connection->ssl->connection; - if (ssl_conn == NULL) { - *err = "bad ssl conn"; - return NGX_ERROR; - } - - pool = r->pool; - c = ngx_ssl_get_connection(ssl_conn); - -#ifdef SSL_CTRL_GET_RAW_CIPHERLIST - - int n, i, bytes; - size_t len; - u_char *ciphers, *p; - const SSL_CIPHER *cipher; - - bytes = SSL_get0_raw_cipherlist(c->ssl->connection, NULL); - n = SSL_get0_raw_cipherlist(c->ssl->connection, &ciphers); - - if (n <= 0) { - *cipherslen = 0; - return NGX_OK; - } - - len = 0; - n /= bytes; - - for (i = 0; i < n; i++) { - cipher = SSL_CIPHER_find(c->ssl->connection, ciphers + i * bytes); - - if (cipher) { - len += ngx_strlen(SSL_CIPHER_get_name(cipher)); - - } else { - len += sizeof("0x") - 1 + bytes * (sizeof("00") - 1); - } - - len += sizeof(":") - 1; - } - - *pciphers = ngx_pnalloc(pool, len); - if (*pciphers == NULL) { - *err = "no memory"; - return NGX_ERROR; - } - - p = (u_char *) *pciphers; - - for (i = 0; i < n; i++) { - cipher = SSL_CIPHER_find(c->ssl->connection, ciphers + i * bytes); - - if (cipher) { - p = ngx_sprintf(p, "%s", SSL_CIPHER_get_name(cipher)); - - } else { - p = ngx_sprintf(p, "0x"); - p = ngx_hex_dump(p, ciphers + i * bytes, bytes); - } - - *p++ = ':'; - } - - p--; - - *cipherslen = p - (u_char *) *pciphers; - -#else - - u_char buf[4096]; - - if (SSL_get_shared_ciphers(c->ssl->connection, (char *) buf, 4096) - == NULL) - { - *cipherslen = 0; - return NGX_OK; - } - - *cipherslen = ngx_strlen(buf); - *pciphers = ngx_pnalloc(pool, *cipherslen); - if (*pciphers == NULL) { + rc = ngx_ssl_get_ciphers(c, r->pool, &ciphers); + if (rc != NGX_OK) { *err = "no memory"; return NGX_ERROR; } - ngx_memcpy(*pciphers, buf, *cipherslen); - -#endif + *pciphers = (char *) ciphers.data; + *cipherslen = ciphers.len; return NGX_OK; } From b78cc00b8fbb9b778e9cd6ca3d39dc19697de61a Mon Sep 17 00:00:00 2001 From: lijunlong Date: Sun, 31 Oct 2021 18:50:16 +0800 Subject: [PATCH 5/5] removed extra blank line. --- t/166-ssl-client-hello.t | 1 - 1 file changed, 1 deletion(-) diff --git a/t/166-ssl-client-hello.t b/t/166-ssl-client-hello.t index eef08d7cba..79787f63a0 100644 --- a/t/166-ssl-client-hello.t +++ b/t/166-ssl-client-hello.t @@ -2140,7 +2140,6 @@ ssl_client_hello_by_lua:1: ssl client hello by lua is running! local ip = string.format("%d.%d.%d.%d", byte(addr, 1), byte(addr, 2), byte(addr, 3), byte(addr, 4)) print("client ip: ", ip) - } ssl_certificate ../../cert/test.crt; ssl_certificate_key ../../cert/test.key;