Skip to content

Commit 51b3daf

Browse files
committed
feature: ngx_http_lua_ffi_ssl_get_client_hello_ciphers()
Partially inspired by: https://github.com/naofumi0628/haproxy/blob/fefb9e37714bd2e3ad2adc3a321e165fc1dafae2/src/ssl_sock.c#L2252 Relevant: fooinha/nginx-ssl-ja3#64 openssl/openssl#27580 And especially: https://github.com/openresty/lua-nginx-module#:~:text=after%20SSL%20handshake%2C-,the%20ngx.ctx%20created,-in%20ssl_certificate_by_lua* It might be pointless for me to pull all this data into Lua-land if I don't find a way to store those values. I need some kind of ngx.ctx but related not a request but to a connection instead of a request.
1 parent edd1b6a commit 51b3daf

File tree

1 file changed

+62
-0
lines changed

1 file changed

+62
-0
lines changed

src/ngx_http_lua_ssl_client_helloby.c

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -707,6 +707,68 @@ ngx_http_lua_ffi_ssl_get_client_hello_ext_present(ngx_http_request_t *r,
707707
}
708708

709709

710+
int ngx_http_lua_ffi_ssl_get_client_hello_ciphers(ngx_http_request_t *r,
711+
unsigned short **ciphers, size_t *ciphers_cnt, char **err)
712+
{
713+
ngx_ssl_conn_t *ssl_conn;
714+
size_t ciphersuites_bytes;
715+
const unsigned char *ciphers_raw;
716+
unsigned short *ciphers_ja3;
717+
ngx_connection_t *c;
718+
719+
720+
if (r->connection == NULL || r->connection->ssl == NULL) {
721+
*err = "bad request";
722+
return NGX_ERROR;
723+
}
724+
725+
ssl_conn = r->connection->ssl->connection;
726+
if (ssl_conn == NULL) {
727+
*err = "bad ssl conn";
728+
return NGX_ERROR;
729+
}
730+
731+
c = ngx_ssl_get_connection(ssl_conn);
732+
if (c == NULL) {
733+
*err = "couldn't get real ngx_connection_t pointer";
734+
return NGX_ERROR;
735+
}
736+
737+
#ifdef SSL_ERROR_WANT_CLIENT_HELLO_CB
738+
ciphersuites_bytes = SSL_client_hello_get0_ciphers(ssl_conn, &ciphers_raw);
739+
740+
if (!ciphersuites_bytes) {
741+
*err = "failed SSL_client_hello_get0_ciphers()";
742+
return NGX_DECLINED;
743+
}
744+
745+
if (ciphersuites_bytes % 2 != 0) {
746+
*err = "SSL_client_hello_get0_ciphers() odd ciphersuites_bytes";
747+
return NGX_DECLINED;
748+
}
749+
750+
*ciphers_cnt = ciphersuites_bytes / 2;
751+
752+
*ciphers = ngx_palloc(c->pool, sizeof(short) * (*ciphers_cnt));
753+
if (*ciphers == NULL) {
754+
*err = "ngx_palloc() failed for the ciphers array";
755+
return NGX_ERROR;
756+
}
757+
758+
for (int i = 0 ; i < *ciphers_cnt ; i++) {
759+
uint16_t cipher = (ciphers_raw[i*2] << 8) | ciphers_raw[i*2 + 1];
760+
(*ciphers)[i] = cipher; /* like ntohs but more portable, supposedly */
761+
}
762+
763+
764+
return NGX_OK;
765+
#else
766+
*err = "OpenSSL too old to support this function";
767+
return NGX_ERROR;
768+
#endif
769+
}
770+
771+
710772
int
711773
ngx_http_lua_ffi_ssl_set_protocols(ngx_http_request_t *r,
712774
int protocols, char **err)

0 commit comments

Comments
 (0)