Skip to content

Commit ed7c6db

Browse files
dedokphuslu
authored andcommitted
Supporing the laters versions of: nginx v1.27 patch and openssl v3.4 patch; Fix segfault; speedup sulution by reducting number of allocations per requests;
1 parent d27041f commit ed7c6db

File tree

3 files changed

+380
-0
lines changed

3 files changed

+380
-0
lines changed

patches/nginx-1.27.patch

Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c
2+
index 2f68a55de..d069b72ea 100644
3+
--- a/src/event/ngx_event_openssl.c
4+
+++ b/src/event/ngx_event_openssl.c
5+
@@ -11,6 +11,7 @@
6+
#include <ngx_event.h>
7+
8+
9+
+#define NGX_SSL_JA3_BUFFER_SIZE 256 /* = (sizeof(uint16_t) * 128) */
10+
#define NGX_SSL_PASSWORD_BUFFER_SIZE 4096
11+
12+
#if (NGX_HAVE_NTLS)
13+
@@ -1971,6 +1972,40 @@ ngx_ssl_set_session(ngx_connection_t *c, ngx_ssl_session_t *session)
14+
return NGX_OK;
15+
}
16+
17+
+int
18+
+ngx_ssl_client_hello_ja3_cb(SSL *s, int *al, void *arg)
19+
+{
20+
+ ngx_connection_t *c = arg;
21+
+ ngx_str_t *ja;
22+
+
23+
+ if (c == NULL) {
24+
+ return SSL_CLIENT_HELLO_SUCCESS;
25+
+ }
26+
+
27+
+ if (c->ssl == NULL) {
28+
+ return SSL_CLIENT_HELLO_SUCCESS;
29+
+ }
30+
+
31+
+ ja = &c->ssl->fp_ja3_data;
32+
+ ja->len = NGX_SSL_JA3_BUFFER_SIZE;
33+
+
34+
+ ja->data = ngx_pnalloc(c->pool, c->ssl->fp_ja3_data.len);
35+
+ if (ja->data == NULL) {
36+
+ ja->len = 0;
37+
+ return SSL_CLIENT_HELLO_SUCCESS;
38+
+ }
39+
+
40+
+ ja->len = SSL_client_hello_get_ja3_data(c->ssl->connection, ja->data,
41+
+ NGX_SSL_JA3_BUFFER_SIZE);
42+
+ if (ja->len == 0) {
43+
+ ngx_log_error(NGX_LOG_WARN, c->log, 0, "SSL_client_hello_get_ja3_data "
44+
+ "seems the buffer size is less that number of fileds; "
45+
+ "for this SSL connection can't get a ja3 hash string");
46+
+ ja->data = NULL;
47+
+ }
48+
+
49+
+ return SSL_CLIENT_HELLO_SUCCESS;
50+
+}
51+
52+
ngx_int_t
53+
ngx_ssl_handshake(ngx_connection_t *c)
54+
@@ -1991,6 +2026,9 @@ ngx_ssl_handshake(ngx_connection_t *c)
55+
56+
ngx_ssl_clear_error(c->log);
57+
58+
+ (void) SSL_CTX_set_client_hello_cb(c->ssl->session_ctx,
59+
+ ngx_ssl_client_hello_ja3_cb, c);
60+
+
61+
n = SSL_do_handshake(c->ssl->connection);
62+
63+
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_do_handshake: %d", n);
64+
diff --git a/src/event/ngx_event_openssl.h b/src/event/ngx_event_openssl.h
65+
index 42a01ce62..c4adc270d 100644
66+
--- a/src/event/ngx_event_openssl.h
67+
+++ b/src/event/ngx_event_openssl.h
68+
@@ -129,6 +129,11 @@ struct ngx_ssl_connection_s {
69+
unsigned in_ocsp:1;
70+
unsigned early_preread:1;
71+
unsigned write_blocked:1;
72+
+
73+
+ ngx_str_t fp_ja3_data;
74+
+ ngx_str_t fp_ja3_str;
75+
+ ngx_str_t fp_ja3_hash;
76+
+ uint16_t fp_tls_greased;
77+
};
78+
79+
80+
diff --git a/src/http/v2/ngx_http_v2.c b/src/http/v2/ngx_http_v2.c
81+
index 0f5bd3de8..1b85e378d 100644
82+
--- a/src/http/v2/ngx_http_v2.c
83+
+++ b/src/http/v2/ngx_http_v2.c
84+
@@ -301,6 +301,8 @@ ngx_http_v2_init(ngx_event_t *rev)
85+
ngx_add_timer(rev, cscf->client_header_timeout);
86+
}
87+
88+
+ h2c->fp_fingerprinted = 0;
89+
+
90+
c->idle = 1;
91+
ngx_reusable_connection(c, 0);
92+
93+
@@ -1352,6 +1354,14 @@ ngx_http_v2_state_headers(ngx_http_v2_connection_t *h2c, u_char *pos,
94+
}
95+
}
96+
97+
+ if (!h2c->fp_fingerprinted && h2c->fp_priorities.len < 32) {
98+
+ h2c->fp_priorities.data[h2c->fp_priorities.len] = (uint8_t)stream->node->id;
99+
+ h2c->fp_priorities.data[h2c->fp_priorities.len+1] = (uint8_t)excl;
100+
+ h2c->fp_priorities.data[h2c->fp_priorities.len+2] = (uint8_t)depend;
101+
+ h2c->fp_priorities.data[h2c->fp_priorities.len+3] = (uint8_t)(weight-1);
102+
+ h2c->fp_priorities.len += 4;
103+
+ }
104+
+
105+
return ngx_http_v2_state_header_block(h2c, pos, end);
106+
107+
rst_stream:
108+
@@ -1775,6 +1785,9 @@ ngx_http_v2_state_process_header(ngx_http_v2_connection_t *h2c, u_char *pos,
109+
}
110+
111+
if (header->name.data[0] == ':') {
112+
+ if (!h2c->fp_fingerprinted && h2c->fp_pseudoheaders.len < 32 && header->name.len > 1)
113+
+ h2c->fp_pseudoheaders.data[h2c->fp_pseudoheaders.len++] = header->name.data[1];
114+
+
115+
rc = ngx_http_v2_pseudo_header(r, header);
116+
117+
if (rc == NGX_OK) {
118+
@@ -2194,6 +2207,12 @@ ngx_http_v2_state_settings_params(ngx_http_v2_connection_t *h2c, u_char *pos,
119+
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
120+
"http2 setting %ui:%ui", id, value);
121+
122+
+ if (!h2c->fp_fingerprinted && h2c->fp_settings.len < 32) {
123+
+ h2c->fp_settings.data[h2c->fp_settings.len] = (uint8_t)id;
124+
+ *(uint32_t*)(h2c->fp_settings.data + h2c->fp_settings.len + 1) = (uint32_t)value;
125+
+ h2c->fp_settings.len += 5;
126+
+ }
127+
+
128+
switch (id) {
129+
130+
case NGX_HTTP_V2_INIT_WINDOW_SIZE_SETTING:
131+
@@ -2478,6 +2497,9 @@ ngx_http_v2_state_window_update(ngx_http_v2_connection_t *h2c, u_char *pos,
132+
}
133+
134+
h2c->send_window += window;
135+
+ if (!h2c->fp_fingerprinted) {
136+
+ h2c->fp_windowupdate = window;
137+
+ }
138+
139+
while (!ngx_queue_empty(&h2c->waiting)) {
140+
q = ngx_queue_head(&h2c->waiting);
141+
diff --git a/src/http/v2/ngx_http_v2.h b/src/http/v2/ngx_http_v2.h
142+
index 6751b3026..60a68a0fd 100644
143+
--- a/src/http/v2/ngx_http_v2.h
144+
+++ b/src/http/v2/ngx_http_v2.h
145+
@@ -17,6 +17,8 @@
146+
147+
#define NGX_HTTP_V2_STATE_BUFFER_SIZE 16
148+
149+
+#define NGX_FP_V2_BUFFER_SIZE 32
150+
+
151+
#define NGX_HTTP_V2_DEFAULT_FRAME_SIZE (1 << 14)
152+
#define NGX_HTTP_V2_MAX_FRAME_SIZE ((1 << 24) - 1)
153+
154+
@@ -121,6 +123,12 @@ typedef struct {
155+
} ngx_http_v2_hpack_t;
156+
157+
158+
+typedef struct {
159+
+ u_char data[NGX_FP_V2_BUFFER_SIZE];
160+
+ size_t len;
161+
+} ngx_http_v2_fp_fixed_str_t;
162+
+
163+
+
164+
struct ngx_http_v2_connection_s {
165+
ngx_connection_t *connection;
166+
ngx_http_connection_t *http_connection;
167+
@@ -168,6 +176,13 @@ struct ngx_http_v2_connection_s {
168+
unsigned table_update:1;
169+
unsigned blocked:1;
170+
unsigned goaway:1;
171+
+
172+
+ unsigned fp_fingerprinted:1;
173+
+ ngx_http_v2_fp_fixed_str_t fp_settings,
174+
+ fp_priorities,
175+
+ fp_pseudoheaders;
176+
+ ngx_uint_t fp_windowupdate;
177+
+ ngx_str_t fp_str;
178+
};
179+
180+

patches/openssl.openssl-3.4.patch

Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
diff --git a/include/openssl/ssl.h.in b/include/openssl/ssl.h.in
2+
index 4bab2ac767..9732ece423 100644
3+
--- a/include/openssl/ssl.h.in
4+
+++ b/include/openssl/ssl.h.in
5+
@@ -1905,6 +1905,8 @@ size_t SSL_client_hello_get0_ciphers(SSL *s, const unsigned char **out);
6+
size_t SSL_client_hello_get0_compression_methods(SSL *s,
7+
const unsigned char **out);
8+
int SSL_client_hello_get1_extensions_present(SSL *s, int **out, size_t *outlen);
9+
+size_t SSL_client_hello_get_ja3_data(SSL *s, unsigned char *data,
10+
+ size_t data_size);
11+
int SSL_client_hello_get_extension_order(SSL *s, uint16_t *exts,
12+
size_t *num_exts);
13+
int SSL_client_hello_get0_ext(SSL *s, unsigned int type,
14+
diff --git a/include/openssl/tls1.h b/include/openssl/tls1.h
15+
index 8e9b110bb3..3a2407b0e4 100644
16+
--- a/include/openssl/tls1.h
17+
+++ b/include/openssl/tls1.h
18+
@@ -142,6 +142,13 @@ extern "C" {
19+
/* ExtensionType value from RFC7627 */
20+
# define TLSEXT_TYPE_extended_master_secret 23
21+
22+
+/* ExtensionType value from RFC6961 */
23+
+# define TLSEXT_TYPE_status_request_v2 17
24+
+/* ExtensionType value from RFC8449 */
25+
+# define TLSEXT_TYPE_record_size_limit 28
26+
+/* ExtensionType value from RFC7639 */
27+
+# define TLSEXT_TYPE_application_settings 17513
28+
+
29+
/* ExtensionType value from RFC8879 */
30+
# define TLSEXT_TYPE_compress_certificate 27
31+
32+
diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
33+
index 295b719ff2..429d710fa2 100644
34+
--- a/ssl/ssl_lib.c
35+
+++ b/ssl/ssl_lib.c
36+
@@ -6641,6 +6641,101 @@ int SSL_client_hello_get1_extensions_present(SSL *s, int **out, size_t *outlen)
37+
return 0;
38+
}
39+
40+
+size_t SSL_client_hello_get_ja3_data(SSL *s, unsigned char *data,
41+
+ size_t data_size)
42+
+{
43+
+ RAW_EXTENSION *ext;
44+
+ PACKET *groups = NULL, *formats = NULL;
45+
+ size_t num = 0, i;
46+
+ unsigned char *ptr = data,
47+
+ *end = data + data_size;
48+
+ const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);
49+
+
50+
+ if (sc == NULL)
51+
+ return 0;
52+
+
53+
+ if (ossl_unlikely(sc->clienthello == NULL || data == NULL
54+
+ /** just checking that we have at least this */
55+
+ || data_size < 128))
56+
+ return 0;
57+
+
58+
+ /* version */
59+
+ *(uint16_t *) ptr = (uint16_t) sc->clienthello->legacy_version;
60+
+ ptr += sizeof(uint16_t);
61+
+
62+
+ num = PACKET_remaining(&sc->clienthello->ciphersuites);
63+
+ *(uint16_t *) ptr = (uint16_t) num;
64+
+ ptr += sizeof(uint16_t);
65+
+
66+
+ if (ossl_unlikely(ptr + num > end))
67+
+ return 0;
68+
+
69+
+ memcpy(ptr, PACKET_data(&sc->clienthello->ciphersuites), num);
70+
+ ptr += num;
71+
+
72+
+ /* extensions */
73+
+ num = 0;
74+
+ for (i = 0; i < sc->clienthello->pre_proc_exts_len; i++) {
75+
+ ext = sc->clienthello->pre_proc_exts + i;
76+
+ if (ext->present)
77+
+ num++;
78+
+ }
79+
+
80+
+ num = num * 2;
81+
+ if (ossl_unlikely((ptr + num + sizeof(uint16_t)) > end))
82+
+ return 0;
83+
+ *(uint16_t*) ptr = (uint16_t) num;
84+
+ ptr += sizeof(uint16_t);
85+
+
86+
+ for (i = 0; i < sc->clienthello->pre_proc_exts_len; i++) {
87+
+ ext = sc->clienthello->pre_proc_exts + i;
88+
+ if (ext->present) {
89+
+ if (ext->received_order >= num)
90+
+ break;
91+
+ if (ext->type == TLSEXT_TYPE_supported_groups)
92+
+ groups = &ext->data;
93+
+ if (ext->type == TLSEXT_TYPE_ec_point_formats)
94+
+ formats = &ext->data;
95+
+ if (ossl_likely(ext->received_order < data_size)) {
96+
+ *(uint16_t*)(ptr + ext->received_order) = (uint16_t) ext->type;
97+
+ }
98+
+ }
99+
+ }
100+
+
101+
+ ptr += num;
102+
+ /* groups */
103+
+ if (groups) {
104+
+ num = PACKET_remaining(groups);
105+
+ if (ossl_unlikely((ptr + num + sizeof(uint16_t)) > end))
106+
+ return 0;
107+
+ memcpy(ptr, PACKET_data(groups), num);
108+
+ *(uint16_t*) ptr = (uint16_t) num;
109+
+ ptr += num;
110+
+ } else {
111+
+ if (ossl_unlikely(ptr + sizeof(uint16_t) > end))
112+
+ return 0;
113+
+ *(uint16_t *) ptr = (uint16_t) 0;
114+
+ ptr += sizeof(uint16_t);
115+
+ }
116+
+
117+
+ /* formats */
118+
+ if (formats) {
119+
+ num = PACKET_remaining(formats);
120+
+ if (ossl_unlikely((ptr + num + sizeof(uint8_t)) > end))
121+
+ return 0;
122+
+ memcpy(ptr, PACKET_data(formats), num);
123+
+ *(uint8_t *) ptr = (uint8_t) num;
124+
+ ptr += num;
125+
+ } else {
126+
+ if (ossl_unlikely(ptr + sizeof(uint8_t) > end))
127+
+ return 0;
128+
+ *(uint8_t *) ptr = (uint8_t) 0;
129+
+ ptr += sizeof(uint8_t);
130+
+ }
131+
+
132+
+ return ptr - data;
133+
+}
134+
+
135+
int SSL_client_hello_get_extension_order(SSL *s, uint16_t *exts, size_t *num_exts)
136+
{
137+
RAW_EXTENSION *ext;
138+
diff --git a/ssl/ssl_local.h b/ssl/ssl_local.h
139+
index 277be3084d..6b3821737f 100644
140+
--- a/ssl/ssl_local.h
141+
+++ b/ssl/ssl_local.h
142+
@@ -701,6 +701,9 @@ typedef enum tlsext_index_en {
143+
TLSEXT_IDX_compress_certificate,
144+
TLSEXT_IDX_early_data,
145+
TLSEXT_IDX_certificate_authorities,
146+
+ TLSEXT_IDX_status_request_v2,
147+
+ TLSEXT_IDX_record_size_limit,
148+
+ TLSEXT_IDX_application_settings,
149+
TLSEXT_IDX_padding,
150+
TLSEXT_IDX_psk,
151+
/* Dummy index - must always be the last entry */
152+
diff --git a/ssl/statem/extensions.c b/ssl/statem/extensions.c
153+
index 762c7ac0d4..56d2f5ba60 100644
154+
--- a/ssl/statem/extensions.c
155+
+++ b/ssl/statem/extensions.c
156+
@@ -413,6 +413,30 @@ static const EXTENSION_DEFINITION ext_defs[] = {
157+
tls_construct_certificate_authorities,
158+
tls_construct_certificate_authorities, NULL,
159+
},
160+
+ {
161+
+ TLSEXT_TYPE_status_request_v2,
162+
+ SSL_EXT_CLIENT_HELLO,
163+
+ NULL,
164+
+ NULL, NULL,
165+
+ NULL,
166+
+ NULL, NULL,
167+
+ },
168+
+ {
169+
+ TLSEXT_TYPE_record_size_limit,
170+
+ SSL_EXT_CLIENT_HELLO,
171+
+ NULL,
172+
+ NULL, NULL,
173+
+ NULL,
174+
+ NULL, NULL,
175+
+ },
176+
+ {
177+
+ TLSEXT_TYPE_application_settings,
178+
+ SSL_EXT_CLIENT_HELLO,
179+
+ NULL,
180+
+ NULL, NULL,
181+
+ NULL,
182+
+ NULL, NULL,
183+
+ },
184+
{
185+
/* Must be immediately before pre_shared_key */
186+
TLSEXT_TYPE_padding,

0 commit comments

Comments
 (0)