Mercurial > hg > nginx
comparison src/event/quic/ngx_event_quic.c @ 8753:46161c610919 quic
QUIC: separate files for SSL library interfaces.
author | Vladimir Homutov <vl@nginx.com> |
---|---|
date | Wed, 14 Apr 2021 14:47:04 +0300 |
parents | e19723c40d28 |
children | 4117aa7fa38e |
comparison
equal
deleted
inserted
replaced
8752:e19723c40d28 | 8753:46161c610919 |
---|---|
8 #include <ngx_core.h> | 8 #include <ngx_core.h> |
9 #include <ngx_event.h> | 9 #include <ngx_event.h> |
10 #include <ngx_event_quic_connection.h> | 10 #include <ngx_event_quic_connection.h> |
11 | 11 |
12 | 12 |
13 /* | |
14 * 7.4. Cryptographic Message Buffering | |
15 * Implementations MUST support buffering at least 4096 bytes of data | |
16 */ | |
17 #define NGX_QUIC_MAX_BUFFERED 65535 | |
18 | |
19 | |
20 #if BORINGSSL_API_VERSION >= 10 | |
21 static int ngx_quic_set_read_secret(ngx_ssl_conn_t *ssl_conn, | |
22 enum ssl_encryption_level_t level, const SSL_CIPHER *cipher, | |
23 const uint8_t *secret, size_t secret_len); | |
24 static int ngx_quic_set_write_secret(ngx_ssl_conn_t *ssl_conn, | |
25 enum ssl_encryption_level_t level, const SSL_CIPHER *cipher, | |
26 const uint8_t *secret, size_t secret_len); | |
27 #else | |
28 static int ngx_quic_set_encryption_secrets(ngx_ssl_conn_t *ssl_conn, | |
29 enum ssl_encryption_level_t level, const uint8_t *read_secret, | |
30 const uint8_t *write_secret, size_t secret_len); | |
31 #endif | |
32 | |
33 static int ngx_quic_add_handshake_data(ngx_ssl_conn_t *ssl_conn, | |
34 enum ssl_encryption_level_t level, const uint8_t *data, size_t len); | |
35 static int ngx_quic_flush_flight(ngx_ssl_conn_t *ssl_conn); | |
36 | |
37 | |
38 static ngx_int_t ngx_quic_apply_transport_params(ngx_connection_t *c, | |
39 ngx_quic_tp_t *ctp); | |
40 static ngx_quic_connection_t *ngx_quic_new_connection(ngx_connection_t *c, | 13 static ngx_quic_connection_t *ngx_quic_new_connection(ngx_connection_t *c, |
41 ngx_quic_conf_t *conf, ngx_quic_header_t *pkt); | 14 ngx_quic_conf_t *conf, ngx_quic_header_t *pkt); |
42 static ngx_int_t ngx_quic_process_stateless_reset(ngx_connection_t *c, | 15 static ngx_int_t ngx_quic_process_stateless_reset(ngx_connection_t *c, |
43 ngx_quic_header_t *pkt); | 16 ngx_quic_header_t *pkt); |
44 static ngx_int_t ngx_quic_init_connection(ngx_connection_t *c); | |
45 static void ngx_quic_input_handler(ngx_event_t *rev); | 17 static void ngx_quic_input_handler(ngx_event_t *rev); |
46 | 18 |
47 static ngx_int_t ngx_quic_close_quic(ngx_connection_t *c, ngx_int_t rc); | 19 static ngx_int_t ngx_quic_close_quic(ngx_connection_t *c, ngx_int_t rc); |
48 static void ngx_quic_close_timer_handler(ngx_event_t *ev); | 20 static void ngx_quic_close_timer_handler(ngx_event_t *ev); |
49 | 21 |
51 ngx_quic_conf_t *conf); | 23 ngx_quic_conf_t *conf); |
52 static ngx_int_t ngx_quic_process_packet(ngx_connection_t *c, | 24 static ngx_int_t ngx_quic_process_packet(ngx_connection_t *c, |
53 ngx_quic_conf_t *conf, ngx_quic_header_t *pkt); | 25 ngx_quic_conf_t *conf, ngx_quic_header_t *pkt); |
54 static ngx_int_t ngx_quic_process_payload(ngx_connection_t *c, | 26 static ngx_int_t ngx_quic_process_payload(ngx_connection_t *c, |
55 ngx_quic_header_t *pkt); | 27 ngx_quic_header_t *pkt); |
56 static void ngx_quic_discard_ctx(ngx_connection_t *c, | |
57 enum ssl_encryption_level_t level); | |
58 static ngx_int_t ngx_quic_check_csid(ngx_quic_connection_t *qc, | 28 static ngx_int_t ngx_quic_check_csid(ngx_quic_connection_t *qc, |
59 ngx_quic_header_t *pkt); | 29 ngx_quic_header_t *pkt); |
60 static ngx_int_t ngx_quic_handle_frames(ngx_connection_t *c, | 30 static ngx_int_t ngx_quic_handle_frames(ngx_connection_t *c, |
61 ngx_quic_header_t *pkt); | 31 ngx_quic_header_t *pkt); |
62 | |
63 | |
64 static ngx_int_t ngx_quic_handle_crypto_frame(ngx_connection_t *c, | |
65 ngx_quic_header_t *pkt, ngx_quic_frame_t *frame); | |
66 ngx_int_t ngx_quic_crypto_input(ngx_connection_t *c, | |
67 ngx_quic_frame_t *frame, void *data); | |
68 | 32 |
69 static void ngx_quic_push_handler(ngx_event_t *ev); | 33 static void ngx_quic_push_handler(ngx_event_t *ev); |
70 | 34 |
71 | 35 |
72 static ngx_core_module_t ngx_quic_module_ctx = { | 36 static ngx_core_module_t ngx_quic_module_ctx = { |
90 NULL, /* exit master */ | 54 NULL, /* exit master */ |
91 NGX_MODULE_V1_PADDING | 55 NGX_MODULE_V1_PADDING |
92 }; | 56 }; |
93 | 57 |
94 | 58 |
95 static SSL_QUIC_METHOD quic_method = { | |
96 #if BORINGSSL_API_VERSION >= 10 | |
97 ngx_quic_set_read_secret, | |
98 ngx_quic_set_write_secret, | |
99 #else | |
100 ngx_quic_set_encryption_secrets, | |
101 #endif | |
102 ngx_quic_add_handshake_data, | |
103 ngx_quic_flush_flight, | |
104 ngx_quic_send_alert, | |
105 }; | |
106 | |
107 | |
108 #if (NGX_DEBUG) | 59 #if (NGX_DEBUG) |
109 | 60 |
110 void | 61 void |
111 ngx_quic_connstate_dbg(ngx_connection_t *c) | 62 ngx_quic_connstate_dbg(ngx_connection_t *c) |
112 { | 63 { |
171 } | 122 } |
172 | 123 |
173 #endif | 124 #endif |
174 | 125 |
175 | 126 |
176 #if BORINGSSL_API_VERSION >= 10 | 127 ngx_int_t |
177 | |
178 static int | |
179 ngx_quic_set_read_secret(ngx_ssl_conn_t *ssl_conn, | |
180 enum ssl_encryption_level_t level, const SSL_CIPHER *cipher, | |
181 const uint8_t *rsecret, size_t secret_len) | |
182 { | |
183 ngx_connection_t *c; | |
184 ngx_quic_connection_t *qc; | |
185 | |
186 c = ngx_ssl_get_connection((ngx_ssl_conn_t *) ssl_conn); | |
187 qc = ngx_quic_get_connection(c); | |
188 | |
189 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
190 "quic ngx_quic_set_read_secret() level:%d", level); | |
191 #ifdef NGX_QUIC_DEBUG_CRYPTO | |
192 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
193 "quic read secret len:%uz %*xs", secret_len, | |
194 secret_len, rsecret); | |
195 #endif | |
196 | |
197 return ngx_quic_keys_set_encryption_secret(c->pool, 0, qc->keys, level, | |
198 cipher, rsecret, secret_len); | |
199 } | |
200 | |
201 | |
202 static int | |
203 ngx_quic_set_write_secret(ngx_ssl_conn_t *ssl_conn, | |
204 enum ssl_encryption_level_t level, const SSL_CIPHER *cipher, | |
205 const uint8_t *wsecret, size_t secret_len) | |
206 { | |
207 ngx_connection_t *c; | |
208 ngx_quic_connection_t *qc; | |
209 | |
210 c = ngx_ssl_get_connection((ngx_ssl_conn_t *) ssl_conn); | |
211 qc = ngx_quic_get_connection(c); | |
212 | |
213 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
214 "quic ngx_quic_set_write_secret() level:%d", level); | |
215 #ifdef NGX_QUIC_DEBUG_CRYPTO | |
216 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
217 "quic write secret len:%uz %*xs", secret_len, | |
218 secret_len, wsecret); | |
219 #endif | |
220 | |
221 return ngx_quic_keys_set_encryption_secret(c->pool, 1, qc->keys, level, | |
222 cipher, wsecret, secret_len); | |
223 } | |
224 | |
225 #else | |
226 | |
227 static int | |
228 ngx_quic_set_encryption_secrets(ngx_ssl_conn_t *ssl_conn, | |
229 enum ssl_encryption_level_t level, const uint8_t *rsecret, | |
230 const uint8_t *wsecret, size_t secret_len) | |
231 { | |
232 ngx_connection_t *c; | |
233 const SSL_CIPHER *cipher; | |
234 ngx_quic_connection_t *qc; | |
235 | |
236 c = ngx_ssl_get_connection((ngx_ssl_conn_t *) ssl_conn); | |
237 qc = ngx_quic_get_connection(c); | |
238 | |
239 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
240 "quic ngx_quic_set_encryption_secrets() level:%d", level); | |
241 #ifdef NGX_QUIC_DEBUG_CRYPTO | |
242 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
243 "quic read secret len:%uz %*xs", secret_len, | |
244 secret_len, rsecret); | |
245 #endif | |
246 | |
247 cipher = SSL_get_current_cipher(ssl_conn); | |
248 | |
249 if (ngx_quic_keys_set_encryption_secret(c->pool, 0, qc->keys, level, | |
250 cipher, rsecret, secret_len) | |
251 != 1) | |
252 { | |
253 return 0; | |
254 } | |
255 | |
256 if (level == ssl_encryption_early_data) { | |
257 return 1; | |
258 } | |
259 | |
260 #ifdef NGX_QUIC_DEBUG_CRYPTO | |
261 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
262 "quic write secret len:%uz %*xs", secret_len, | |
263 secret_len, wsecret); | |
264 #endif | |
265 | |
266 return ngx_quic_keys_set_encryption_secret(c->pool, 1, qc->keys, level, | |
267 cipher, wsecret, secret_len); | |
268 } | |
269 | |
270 #endif | |
271 | |
272 | |
273 static int | |
274 ngx_quic_add_handshake_data(ngx_ssl_conn_t *ssl_conn, | |
275 enum ssl_encryption_level_t level, const uint8_t *data, size_t len) | |
276 { | |
277 u_char *p, *end; | |
278 size_t client_params_len; | |
279 const uint8_t *client_params; | |
280 ngx_quic_tp_t ctp; | |
281 ngx_quic_frame_t *frame; | |
282 ngx_connection_t *c; | |
283 ngx_quic_connection_t *qc; | |
284 ngx_quic_frames_stream_t *fs; | |
285 | |
286 c = ngx_ssl_get_connection((ngx_ssl_conn_t *) ssl_conn); | |
287 qc = ngx_quic_get_connection(c); | |
288 | |
289 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
290 "quic ngx_quic_add_handshake_data"); | |
291 | |
292 if (!qc->client_tp_done) { | |
293 /* | |
294 * things to do once during handshake: check ALPN and transport | |
295 * parameters; we want to break handshake if something is wrong | |
296 * here; | |
297 */ | |
298 | |
299 #if defined(TLSEXT_TYPE_application_layer_protocol_negotiation) | |
300 if (qc->conf->require_alpn) { | |
301 unsigned int len; | |
302 const unsigned char *data; | |
303 | |
304 SSL_get0_alpn_selected(ssl_conn, &data, &len); | |
305 | |
306 if (len == 0) { | |
307 qc->error = 0x100 + SSL_AD_NO_APPLICATION_PROTOCOL; | |
308 qc->error_reason = "unsupported protocol in ALPN extension"; | |
309 | |
310 ngx_log_error(NGX_LOG_INFO, c->log, 0, | |
311 "quic unsupported protocol in ALPN extension"); | |
312 return 0; | |
313 } | |
314 } | |
315 #endif | |
316 | |
317 SSL_get_peer_quic_transport_params(ssl_conn, &client_params, | |
318 &client_params_len); | |
319 | |
320 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
321 "quic SSL_get_peer_quic_transport_params():" | |
322 " params_len:%ui", client_params_len); | |
323 | |
324 if (client_params_len == 0) { | |
325 /* quic-tls 8.2 */ | |
326 qc->error = NGX_QUIC_ERR_CRYPTO(SSL_AD_MISSING_EXTENSION); | |
327 qc->error_reason = "missing transport parameters"; | |
328 | |
329 ngx_log_error(NGX_LOG_INFO, c->log, 0, | |
330 "missing transport parameters"); | |
331 return 0; | |
332 } | |
333 | |
334 p = (u_char *) client_params; | |
335 end = p + client_params_len; | |
336 | |
337 /* defaults for parameters not sent by client */ | |
338 ngx_memcpy(&ctp, &qc->ctp, sizeof(ngx_quic_tp_t)); | |
339 | |
340 if (ngx_quic_parse_transport_params(p, end, &ctp, c->log) | |
341 != NGX_OK) | |
342 { | |
343 qc->error = NGX_QUIC_ERR_TRANSPORT_PARAMETER_ERROR; | |
344 qc->error_reason = "failed to process transport parameters"; | |
345 | |
346 return 0; | |
347 } | |
348 | |
349 if (ngx_quic_apply_transport_params(c, &ctp) != NGX_OK) { | |
350 return 0; | |
351 } | |
352 | |
353 qc->client_tp_done = 1; | |
354 } | |
355 | |
356 fs = &qc->crypto[level]; | |
357 | |
358 frame = ngx_quic_alloc_frame(c); | |
359 if (frame == NULL) { | |
360 return 0; | |
361 } | |
362 | |
363 frame->data = ngx_quic_copy_buf(c, (u_char *) data, len); | |
364 if (frame->data == NGX_CHAIN_ERROR) { | |
365 return 0; | |
366 } | |
367 | |
368 frame->level = level; | |
369 frame->type = NGX_QUIC_FT_CRYPTO; | |
370 frame->u.crypto.offset = fs->sent; | |
371 frame->u.crypto.length = len; | |
372 | |
373 fs->sent += len; | |
374 | |
375 ngx_quic_queue_frame(qc, frame); | |
376 | |
377 return 1; | |
378 } | |
379 | |
380 | |
381 static int | |
382 ngx_quic_flush_flight(ngx_ssl_conn_t *ssl_conn) | |
383 { | |
384 #if (NGX_DEBUG) | |
385 ngx_connection_t *c; | |
386 | |
387 c = ngx_ssl_get_connection((ngx_ssl_conn_t *) ssl_conn); | |
388 | |
389 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
390 "quic ngx_quic_flush_flight()"); | |
391 #endif | |
392 return 1; | |
393 } | |
394 | |
395 | |
396 static ngx_int_t | |
397 ngx_quic_apply_transport_params(ngx_connection_t *c, ngx_quic_tp_t *ctp) | 128 ngx_quic_apply_transport_params(ngx_connection_t *c, ngx_quic_tp_t *ctp) |
398 { | 129 { |
399 ngx_quic_connection_t *qc; | 130 ngx_quic_connection_t *qc; |
400 | 131 |
401 qc = ngx_quic_get_connection(c); | 132 qc = ngx_quic_get_connection(c); |
654 return NGX_OK; | 385 return NGX_OK; |
655 } | 386 } |
656 } | 387 } |
657 | 388 |
658 return NGX_DECLINED; | 389 return NGX_DECLINED; |
659 } | |
660 | |
661 | |
662 static ngx_int_t | |
663 ngx_quic_init_connection(ngx_connection_t *c) | |
664 { | |
665 u_char *p; | |
666 size_t clen; | |
667 ssize_t len; | |
668 ngx_ssl_conn_t *ssl_conn; | |
669 ngx_quic_connection_t *qc; | |
670 | |
671 qc = ngx_quic_get_connection(c); | |
672 | |
673 if (ngx_ssl_create_connection(qc->conf->ssl, c, NGX_SSL_BUFFER) != NGX_OK) { | |
674 return NGX_ERROR; | |
675 } | |
676 | |
677 c->ssl->no_wait_shutdown = 1; | |
678 | |
679 ssl_conn = c->ssl->connection; | |
680 | |
681 if (SSL_set_quic_method(ssl_conn, &quic_method) == 0) { | |
682 ngx_log_error(NGX_LOG_INFO, c->log, 0, | |
683 "quic SSL_set_quic_method() failed"); | |
684 return NGX_ERROR; | |
685 } | |
686 | |
687 #ifdef SSL_READ_EARLY_DATA_SUCCESS | |
688 if (SSL_CTX_get_max_early_data(qc->conf->ssl->ctx)) { | |
689 SSL_set_quic_early_data_enabled(ssl_conn, 1); | |
690 } | |
691 #endif | |
692 | |
693 #if BORINGSSL_API_VERSION >= 13 | |
694 SSL_set_quic_use_legacy_codepoint(ssl_conn, qc->version != 1); | |
695 #endif | |
696 | |
697 if (ngx_quic_new_sr_token(c, &qc->dcid, qc->conf->sr_token_key, | |
698 qc->tp.sr_token) | |
699 != NGX_OK) | |
700 { | |
701 return NGX_ERROR; | |
702 } | |
703 | |
704 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
705 "quic stateless reset token %*xs", | |
706 (size_t) NGX_QUIC_SR_TOKEN_LEN, qc->tp.sr_token); | |
707 | |
708 len = ngx_quic_create_transport_params(NULL, NULL, &qc->tp, &clen); | |
709 /* always succeeds */ | |
710 | |
711 p = ngx_pnalloc(c->pool, len); | |
712 if (p == NULL) { | |
713 return NGX_ERROR; | |
714 } | |
715 | |
716 len = ngx_quic_create_transport_params(p, p + len, &qc->tp, NULL); | |
717 if (len < 0) { | |
718 return NGX_ERROR; | |
719 } | |
720 | |
721 #ifdef NGX_QUIC_DEBUG_PACKETS | |
722 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
723 "quic transport parameters len:%uz %*xs", len, len, p); | |
724 #endif | |
725 | |
726 if (SSL_set_quic_transport_params(ssl_conn, p, len) == 0) { | |
727 ngx_log_error(NGX_LOG_INFO, c->log, 0, | |
728 "quic SSL_set_quic_transport_params() failed"); | |
729 return NGX_ERROR; | |
730 } | |
731 | |
732 #if NGX_OPENSSL_QUIC_ZRTT_CTX | |
733 if (SSL_set_quic_early_data_context(ssl_conn, p, clen) == 0) { | |
734 ngx_log_error(NGX_LOG_INFO, c->log, 0, | |
735 "quic SSL_set_quic_early_data_context() failed"); | |
736 return NGX_ERROR; | |
737 } | |
738 #endif | |
739 | |
740 return NGX_OK; | |
741 } | 390 } |
742 | 391 |
743 | 392 |
744 static void | 393 static void |
745 ngx_quic_input_handler(ngx_event_t *rev) | 394 ngx_quic_input_handler(ngx_event_t *rev) |
1359 | 1008 |
1360 return ngx_quic_keys_update(c, qc->keys); | 1009 return ngx_quic_keys_update(c, qc->keys); |
1361 } | 1010 } |
1362 | 1011 |
1363 | 1012 |
1364 static void | 1013 void |
1365 ngx_quic_discard_ctx(ngx_connection_t *c, enum ssl_encryption_level_t level) | 1014 ngx_quic_discard_ctx(ngx_connection_t *c, enum ssl_encryption_level_t level) |
1366 { | 1015 { |
1367 ngx_queue_t *q; | 1016 ngx_queue_t *q; |
1368 ngx_quic_frame_t *f; | 1017 ngx_quic_frame_t *f; |
1369 ngx_quic_send_ctx_t *ctx; | 1018 ngx_quic_send_ctx_t *ctx; |
1670 | 1319 |
1671 return NGX_OK; | 1320 return NGX_OK; |
1672 } | 1321 } |
1673 | 1322 |
1674 | 1323 |
1675 static ngx_int_t | |
1676 ngx_quic_handle_crypto_frame(ngx_connection_t *c, ngx_quic_header_t *pkt, | |
1677 ngx_quic_frame_t *frame) | |
1678 { | |
1679 uint64_t last; | |
1680 ngx_int_t rc; | |
1681 ngx_quic_send_ctx_t *ctx; | |
1682 ngx_quic_connection_t *qc; | |
1683 ngx_quic_crypto_frame_t *f; | |
1684 ngx_quic_frames_stream_t *fs; | |
1685 | |
1686 qc = ngx_quic_get_connection(c); | |
1687 fs = &qc->crypto[pkt->level]; | |
1688 f = &frame->u.crypto; | |
1689 | |
1690 /* no overflow since both values are 62-bit */ | |
1691 last = f->offset + f->length; | |
1692 | |
1693 if (last > fs->received && last - fs->received > NGX_QUIC_MAX_BUFFERED) { | |
1694 qc->error = NGX_QUIC_ERR_CRYPTO_BUFFER_EXCEEDED; | |
1695 return NGX_ERROR; | |
1696 } | |
1697 | |
1698 rc = ngx_quic_handle_ordered_frame(c, fs, frame, ngx_quic_crypto_input, | |
1699 NULL); | |
1700 if (rc != NGX_DECLINED) { | |
1701 return rc; | |
1702 } | |
1703 | |
1704 /* speeding up handshake completion */ | |
1705 | |
1706 if (pkt->level == ssl_encryption_initial) { | |
1707 ctx = ngx_quic_get_send_ctx(qc, pkt->level); | |
1708 | |
1709 if (!ngx_queue_empty(&ctx->sent)) { | |
1710 ngx_quic_resend_frames(c, ctx); | |
1711 | |
1712 ctx = ngx_quic_get_send_ctx(qc, ssl_encryption_handshake); | |
1713 while (!ngx_queue_empty(&ctx->sent)) { | |
1714 ngx_quic_resend_frames(c, ctx); | |
1715 } | |
1716 } | |
1717 } | |
1718 | |
1719 return NGX_OK; | |
1720 } | |
1721 | |
1722 | |
1723 ngx_int_t | |
1724 ngx_quic_crypto_input(ngx_connection_t *c, ngx_quic_frame_t *frame, void *data) | |
1725 { | |
1726 int n, sslerr; | |
1727 ngx_buf_t *b; | |
1728 ngx_chain_t *cl; | |
1729 ngx_ssl_conn_t *ssl_conn; | |
1730 ngx_quic_connection_t *qc; | |
1731 | |
1732 qc = ngx_quic_get_connection(c); | |
1733 | |
1734 ssl_conn = c->ssl->connection; | |
1735 | |
1736 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
1737 "quic SSL_quic_read_level:%d SSL_quic_write_level:%d", | |
1738 (int) SSL_quic_read_level(ssl_conn), | |
1739 (int) SSL_quic_write_level(ssl_conn)); | |
1740 | |
1741 for (cl = frame->data; cl; cl = cl->next) { | |
1742 b = cl->buf; | |
1743 | |
1744 if (!SSL_provide_quic_data(ssl_conn, SSL_quic_read_level(ssl_conn), | |
1745 b->pos, b->last - b->pos)) | |
1746 { | |
1747 ngx_ssl_error(NGX_LOG_INFO, c->log, 0, | |
1748 "SSL_provide_quic_data() failed"); | |
1749 return NGX_ERROR; | |
1750 } | |
1751 } | |
1752 | |
1753 n = SSL_do_handshake(ssl_conn); | |
1754 | |
1755 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
1756 "quic SSL_quic_read_level:%d SSL_quic_write_level:%d", | |
1757 (int) SSL_quic_read_level(ssl_conn), | |
1758 (int) SSL_quic_write_level(ssl_conn)); | |
1759 | |
1760 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_do_handshake: %d", n); | |
1761 | |
1762 if (n <= 0) { | |
1763 sslerr = SSL_get_error(ssl_conn, n); | |
1764 | |
1765 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_get_error: %d", | |
1766 sslerr); | |
1767 | |
1768 if (sslerr != SSL_ERROR_WANT_READ) { | |
1769 ngx_ssl_error(NGX_LOG_ERR, c->log, 0, "SSL_do_handshake() failed"); | |
1770 return NGX_ERROR; | |
1771 } | |
1772 | |
1773 return NGX_OK; | |
1774 } | |
1775 | |
1776 if (SSL_in_init(ssl_conn)) { | |
1777 return NGX_OK; | |
1778 } | |
1779 | |
1780 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
1781 "quic ssl cipher:%s", SSL_get_cipher(ssl_conn)); | |
1782 | |
1783 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
1784 "quic handshake completed successfully"); | |
1785 | |
1786 c->ssl->handshaked = 1; | |
1787 | |
1788 frame = ngx_quic_alloc_frame(c); | |
1789 if (frame == NULL) { | |
1790 return NGX_ERROR; | |
1791 } | |
1792 | |
1793 /* 12.4 Frames and frame types, figure 8 */ | |
1794 frame->level = ssl_encryption_application; | |
1795 frame->type = NGX_QUIC_FT_HANDSHAKE_DONE; | |
1796 ngx_quic_queue_frame(qc, frame); | |
1797 | |
1798 if (ngx_quic_send_new_token(c) != NGX_OK) { | |
1799 return NGX_ERROR; | |
1800 } | |
1801 | |
1802 /* | |
1803 * Generating next keys before a key update is received. | |
1804 * See quic-tls 9.4 Header Protection Timing Side-Channels. | |
1805 */ | |
1806 | |
1807 if (ngx_quic_keys_update(c, qc->keys) != NGX_OK) { | |
1808 return NGX_ERROR; | |
1809 } | |
1810 | |
1811 /* | |
1812 * 4.10.2 An endpoint MUST discard its handshake keys | |
1813 * when the TLS handshake is confirmed | |
1814 */ | |
1815 ngx_quic_discard_ctx(c, ssl_encryption_handshake); | |
1816 | |
1817 if (ngx_quic_issue_server_ids(c) != NGX_OK) { | |
1818 return NGX_ERROR; | |
1819 } | |
1820 | |
1821 return NGX_OK; | |
1822 } | |
1823 | |
1824 | |
1825 static void | 1324 static void |
1826 ngx_quic_push_handler(ngx_event_t *ev) | 1325 ngx_quic_push_handler(ngx_event_t *ev) |
1827 { | 1326 { |
1828 ngx_connection_t *c; | 1327 ngx_connection_t *c; |
1829 | 1328 |