diff options
| author | Sergey Kandaurov <pluknet@nginx.com> | 2025-05-06 15:58:17 +0400 |
|---|---|---|
| committer | Roman Arutyunyan <arutyunyan.roman@gmail.com> | 2025-05-23 15:00:47 +0400 |
| commit | bcb9d3fd2cc88eee23a5da854a0e2aa5c5b688d7 (patch) | |
| tree | e3f2cad0739ee85bd098bd1278c6a1927ca66c4c /src/event/quic/ngx_event_quic_ssl.c | |
| parent | 9857578f15352ec248813f5b3e58ca55dc82f967 (diff) | |
| download | nginx-bcb9d3fd2cc88eee23a5da854a0e2aa5c5b688d7.tar.gz nginx-bcb9d3fd2cc88eee23a5da854a0e2aa5c5b688d7.tar.bz2 | |
QUIC: ssl_encryption_level_t abstraction layer.
Encryption level values are decoupled from ssl_encryption_level_t,
which is now limited to BoringSSL QUIC callbacks, with mappings
provided. Although the values match, this provides a technically
safe approach, in particular, to access protection level sized arrays.
In preparation for using OpenSSL 3.5 TLS callbacks.
Diffstat (limited to 'src/event/quic/ngx_event_quic_ssl.c')
| -rw-r--r-- | src/event/quic/ngx_event_quic_ssl.c | 98 |
1 files changed, 71 insertions, 27 deletions
diff --git a/src/event/quic/ngx_event_quic_ssl.c b/src/event/quic/ngx_event_quic_ssl.c index c9ebd70bc..fc8ebd8cf 100644 --- a/src/event/quic/ngx_event_quic_ssl.c +++ b/src/event/quic/ngx_event_quic_ssl.c @@ -18,44 +18,65 @@ #define NGX_QUIC_MAX_BUFFERED 65535 +static ngx_inline ngx_uint_t ngx_quic_map_encryption_level( + enum ssl_encryption_level_t ssl_level); + #if (NGX_QUIC_BORINGSSL_API) static int ngx_quic_set_read_secret(ngx_ssl_conn_t *ssl_conn, - enum ssl_encryption_level_t level, const SSL_CIPHER *cipher, + enum ssl_encryption_level_t ssl_level, const SSL_CIPHER *cipher, const uint8_t *secret, size_t secret_len); static int ngx_quic_set_write_secret(ngx_ssl_conn_t *ssl_conn, - enum ssl_encryption_level_t level, const SSL_CIPHER *cipher, + enum ssl_encryption_level_t ssl_level, const SSL_CIPHER *cipher, const uint8_t *secret, size_t secret_len); #else /* NGX_QUIC_QUICTLS_API */ static int ngx_quic_set_encryption_secrets(ngx_ssl_conn_t *ssl_conn, - enum ssl_encryption_level_t level, const uint8_t *read_secret, + enum ssl_encryption_level_t ssl_level, const uint8_t *read_secret, const uint8_t *write_secret, size_t secret_len); #endif static int ngx_quic_add_handshake_data(ngx_ssl_conn_t *ssl_conn, - enum ssl_encryption_level_t level, const uint8_t *data, size_t len); + enum ssl_encryption_level_t ssl_level, const uint8_t *data, size_t len); static int ngx_quic_flush_flight(ngx_ssl_conn_t *ssl_conn); static int ngx_quic_send_alert(ngx_ssl_conn_t *ssl_conn, - enum ssl_encryption_level_t level, uint8_t alert); + enum ssl_encryption_level_t ssl_level, uint8_t alert); static ngx_int_t ngx_quic_handshake(ngx_connection_t *c); static ngx_int_t ngx_quic_crypto_provide(ngx_connection_t *c, ngx_chain_t *out, - enum ssl_encryption_level_t level); + ngx_uint_t level); + + +static ngx_inline ngx_uint_t +ngx_quic_map_encryption_level(enum ssl_encryption_level_t ssl_level) +{ + switch (ssl_level) { + case ssl_encryption_initial: + return NGX_QUIC_ENCRYPTION_INITIAL; + case ssl_encryption_early_data: + return NGX_QUIC_ENCRYPTION_EARLY_DATA; + case ssl_encryption_handshake: + return NGX_QUIC_ENCRYPTION_HANDSHAKE; + default: /* ssl_encryption_application */ + return NGX_QUIC_ENCRYPTION_APPLICATION; + } +} #if (NGX_QUIC_BORINGSSL_API) static int ngx_quic_set_read_secret(ngx_ssl_conn_t *ssl_conn, - enum ssl_encryption_level_t level, const SSL_CIPHER *cipher, + enum ssl_encryption_level_t ssl_level, const SSL_CIPHER *cipher, const uint8_t *rsecret, size_t secret_len) { + ngx_uint_t level; ngx_connection_t *c; ngx_quic_connection_t *qc; c = ngx_ssl_get_connection(ssl_conn); qc = ngx_quic_get_connection(c); + level = ngx_quic_map_encryption_level(ssl_level); ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, - "quic ngx_quic_set_read_secret() level:%d", level); + "quic ngx_quic_set_read_secret() level:%d", ssl_level); #ifdef NGX_QUIC_DEBUG_CRYPTO ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, "quic read secret len:%uz %*xs", secret_len, @@ -75,17 +96,19 @@ ngx_quic_set_read_secret(ngx_ssl_conn_t *ssl_conn, static int ngx_quic_set_write_secret(ngx_ssl_conn_t *ssl_conn, - enum ssl_encryption_level_t level, const SSL_CIPHER *cipher, + enum ssl_encryption_level_t ssl_level, const SSL_CIPHER *cipher, const uint8_t *wsecret, size_t secret_len) { + ngx_uint_t level; ngx_connection_t *c; ngx_quic_connection_t *qc; c = ngx_ssl_get_connection(ssl_conn); qc = ngx_quic_get_connection(c); + level = ngx_quic_map_encryption_level(ssl_level); ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, - "quic ngx_quic_set_write_secret() level:%d", level); + "quic ngx_quic_set_write_secret() level:%d", ssl_level); #ifdef NGX_QUIC_DEBUG_CRYPTO ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, "quic write secret len:%uz %*xs", secret_len, @@ -106,18 +129,21 @@ ngx_quic_set_write_secret(ngx_ssl_conn_t *ssl_conn, static int ngx_quic_set_encryption_secrets(ngx_ssl_conn_t *ssl_conn, - enum ssl_encryption_level_t level, const uint8_t *rsecret, + enum ssl_encryption_level_t ssl_level, const uint8_t *rsecret, const uint8_t *wsecret, size_t secret_len) { + ngx_uint_t level; ngx_connection_t *c; const SSL_CIPHER *cipher; ngx_quic_connection_t *qc; c = ngx_ssl_get_connection(ssl_conn); qc = ngx_quic_get_connection(c); + level = ngx_quic_map_encryption_level(ssl_level); ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, - "quic ngx_quic_set_encryption_secrets() level:%d", level); + "quic ngx_quic_set_encryption_secrets() level:%d", + ssl_level); #ifdef NGX_QUIC_DEBUG_CRYPTO ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, "quic read secret len:%uz %*xs", secret_len, @@ -134,7 +160,7 @@ ngx_quic_set_encryption_secrets(ngx_ssl_conn_t *ssl_conn, return 1; } - if (level == ssl_encryption_early_data) { + if (level == NGX_QUIC_ENCRYPTION_EARLY_DATA) { return 1; } @@ -159,10 +185,11 @@ ngx_quic_set_encryption_secrets(ngx_ssl_conn_t *ssl_conn, static int ngx_quic_add_handshake_data(ngx_ssl_conn_t *ssl_conn, - enum ssl_encryption_level_t level, const uint8_t *data, size_t len) + enum ssl_encryption_level_t ssl_level, const uint8_t *data, size_t len) { u_char *p, *end; size_t client_params_len; + ngx_uint_t level; ngx_chain_t *out; unsigned int alpn_len; const uint8_t *client_params; @@ -175,6 +202,7 @@ ngx_quic_add_handshake_data(ngx_ssl_conn_t *ssl_conn, c = ngx_ssl_get_connection(ssl_conn); qc = ngx_quic_get_connection(c); + level = ngx_quic_map_encryption_level(ssl_level); ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, "quic ngx_quic_add_handshake_data"); @@ -287,8 +315,8 @@ ngx_quic_flush_flight(ngx_ssl_conn_t *ssl_conn) static int -ngx_quic_send_alert(ngx_ssl_conn_t *ssl_conn, enum ssl_encryption_level_t level, - uint8_t alert) +ngx_quic_send_alert(ngx_ssl_conn_t *ssl_conn, + enum ssl_encryption_level_t ssl_level, uint8_t alert) { ngx_connection_t *c; ngx_quic_connection_t *qc; @@ -296,8 +324,8 @@ ngx_quic_send_alert(ngx_ssl_conn_t *ssl_conn, enum ssl_encryption_level_t level, c = ngx_ssl_get_connection(ssl_conn); ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, - "quic ngx_quic_send_alert() level:%s alert:%d", - ngx_quic_level_name(level), (int) alert); + "quic ngx_quic_send_alert() level:%d alert:%d", + ssl_level, (int) alert); /* already closed on regular shutdown */ @@ -341,13 +369,13 @@ ngx_quic_handle_crypto_frame(ngx_connection_t *c, ngx_quic_header_t *pkt, } if (last <= ctx->crypto.offset) { - if (pkt->level == ssl_encryption_initial) { + if (pkt->level == NGX_QUIC_ENCRYPTION_INITIAL) { /* speeding up handshake completion */ if (!ngx_queue_empty(&ctx->sent)) { ngx_quic_resend_frames(c, ctx); - ctx = ngx_quic_get_send_ctx(qc, ssl_encryption_handshake); + ctx = ngx_quic_get_send_ctx(qc, NGX_QUIC_ENCRYPTION_HANDSHAKE); while (!ngx_queue_empty(&ctx->sent)) { ngx_quic_resend_frames(c, ctx); } @@ -436,7 +464,7 @@ ngx_quic_handshake(ngx_connection_t *c) } if (n <= 0 || SSL_in_init(ssl_conn)) { - if (ngx_quic_keys_available(qc->keys, ssl_encryption_early_data, 0) + if (ngx_quic_keys_available(qc->keys, NGX_QUIC_ENCRYPTION_EARLY_DATA, 0) && qc->client_tp_done) { if (ngx_quic_init_streams(c) != NGX_OK) { @@ -458,7 +486,7 @@ ngx_quic_handshake(ngx_connection_t *c) return NGX_ERROR; } - frame->level = ssl_encryption_application; + frame->level = NGX_QUIC_ENCRYPTION_APPLICATION; frame->type = NGX_QUIC_FT_HANDSHAKE_DONE; ngx_quic_queue_frame(qc, frame); @@ -482,7 +510,7 @@ ngx_quic_handshake(ngx_connection_t *c) * An endpoint MUST discard its Handshake keys * when the TLS handshake is confirmed. */ - ngx_quic_discard_ctx(c, ssl_encryption_handshake); + ngx_quic_discard_ctx(c, NGX_QUIC_ENCRYPTION_HANDSHAKE); ngx_quic_discover_path_mtu(c, qc->path); @@ -501,15 +529,31 @@ ngx_quic_handshake(ngx_connection_t *c) static ngx_int_t ngx_quic_crypto_provide(ngx_connection_t *c, ngx_chain_t *out, - enum ssl_encryption_level_t level) + ngx_uint_t level) { - ngx_buf_t *b; - ngx_chain_t *cl; + ngx_buf_t *b; + ngx_chain_t *cl; + enum ssl_encryption_level_t ssl_level; + + switch (level) { + case NGX_QUIC_ENCRYPTION_INITIAL: + ssl_level = ssl_encryption_initial; + break; + case NGX_QUIC_ENCRYPTION_EARLY_DATA: + ssl_level = ssl_encryption_early_data; + break; + case NGX_QUIC_ENCRYPTION_HANDSHAKE: + ssl_level = ssl_encryption_handshake; + break; + default: /* NGX_QUIC_ENCRYPTION_APPLICATION */ + ssl_level = ssl_encryption_application; + break; + } for (cl = out; cl; cl = cl->next) { b = cl->buf; - if (!SSL_provide_quic_data(c->ssl->connection, level, b->pos, + if (!SSL_provide_quic_data(c->ssl->connection, ssl_level, b->pos, b->last - b->pos)) { ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, |
