Commit graph

8419 commits

Author SHA1 Message Date
Sergey Kandaurov
034f15bbc2 Auth basic: fixed file descriptor leak on memory allocation error.
Found by Coverity (CID 1662016).
2025-08-11 20:57:47 +04:00
Sergey Kandaurov
251444fcf4 SSL: support for compressed server certificates with OpenSSL.
The ssl_certificate_compression directive allows to send compressed
server certificates.  In OpenSSL, they are pre-compressed on startup.
To simplify configuration, the SSL_OP_NO_TX_CERTIFICATE_COMPRESSION
option is automatically cleared if certificates were pre-compressed.

SSL_CTX_compress_certs() may return an error in legitimate cases,
e.g., when none of compression algorithms is available or if the
resulting compressed size is larger than the original one, thus it
is silently ignored.

Certificate compression is supported in Chrome with brotli only,
in Safari with zlib only, and in Firefox with all listed algorithms.
It is supported since Ubuntu 24.10, which has OpenSSL with enabled
zlib and zstd support.

The actual list of algorithms supported in OpenSSL depends on how
the library was configured; it can be brotli, zlib, zstd as listed
in RFC 8879.
2025-08-03 19:15:16 +04:00
Sergey Kandaurov
ed99269eed SSL: disabled certificate compression by default with OpenSSL.
Certificate compression is supported since OpenSSL 3.2, it is enabled
automatically as negotiated in a TLSv1.3 handshake.

Using certificate compression and decompression in runtime may be
suboptimal in terms of CPU and memory consumption in certain typical
scenarios, hence it is disabled by default on both server and client
sides.  It can be enabled with ssl_conf_command and similar directives
in upstream as appropriate, for example:

    ssl_conf_command Options RxCertificateCompression;
    ssl_conf_command Options TxCertificateCompression;

Compressing server certificates requires additional support, this is
addressed separately.
2025-08-03 19:15:16 +04:00
Sergey Kandaurov
f4005126d7 Updated ngx_http_process_multi_header_lines() comments.
Missed in fcf4331a0.
2025-08-03 10:07:07 +04:00
Sergey Kandaurov
372659114e HTTP/3: improved invalid ":authority" error message. 2025-08-03 10:07:07 +04:00
Sergey Kandaurov
4d857aaf43 Made ngx_http_process_request_header() static again.
The function contains mostly HTTP/1.x specific request processing,
which has no use in other protocols.  After the previous change in
HTTP/2, it can now be hidden.

This is an API change.
2025-08-03 10:07:07 +04:00
Sergey Kandaurov
ede5623b15 HTTP/2: fixed handling of the ":authority" header.
Previously, it misused the Host header processing resulting in
400 (Bad Request) errors for a valid request that contains both
":authority" and Host headers with the same value, treating it
after 37984f0be as if client sent more than one Host header.
Such an overly strict handling violates RFC 9113.

The fix is to process ":authority" as a distinct header, similarly
to processing an authority component in the HTTP/1.x request line.
This allows to disambiguate and compare Host and ":authority"
values after all headers were processed.

With this change, the ngx_http_process_request_header() function
can no longer be used here, certain parts were inlined similar to
the HTTP/3 module.

To provide compatibility for misconfigurations that use $http_host
to return the value of the ":authority" header, the Host header,
if missing, is now reconstructed from ":authority".
2025-08-03 10:07:07 +04:00
Sergey Kandaurov
a238bb3d22 HTTP/2: factored out constructing the Host header.
No functional changes.
2025-08-03 10:07:07 +04:00
Roman Arutyunyan
50932c3c6c HTTP/2: fixed flushing early hints over SSL.
Previously, when using HTTP/2 over SSL, an early hints HEADERS frame was
queued in SSL buffer, and might not be immediately flushed.  This resulted
in a delay of early hints delivery until the main response was sent.

The fix is to set the flush flag for the early hints HEADERS frame buffer.
2025-07-28 21:06:48 +04:00
Roman Arutyunyan
4da7711082 HTTP/3: fixed handling of :authority and Host with port.
RFC 9114, Section 4.3.1. specifies a restriction for :authority and Host
coexistence in an HTTP/3 request:

: If both fields are present, they MUST contain the same value.

Previously, this restriction was correctly enforced only for portless
values.  When Host contained a port, the request failed as if :authority
and Host were different, regardless of :authority presence.

This happens because the value of r->headers_in.server used for :authority
has port stripped.  The fix is to use r->host_start / r->host_end instead.
2025-07-24 20:15:55 +04:00
Sergey Kandaurov
3739fe94d1 HTTP/3: fixed potential type overflow in string literal parser.
This might happen for Huffman encoded string literals as the result
of length expansion.  Notably, the maximum length of string literals
is already limited with the "large_client_header_buffers" directive,
so this was only possible with nonsensically large configured limits.
2025-07-23 17:24:43 +04:00
Sergey Kandaurov
c52c5698cd Events: compatibility with NetBSD 10.0 in kqueue.
The kevent udata field was changed from intptr_t to "void *",
similar to other BSDs and Darwin.

The NGX_KQUEUE_UDATA_T macro is adjusted to reflect that change,
fixing -Werror=int-conversion errors.
2025-07-11 16:25:51 +04:00
Sergey Kandaurov
3f5f8a7f51 Configure: set NGX_KQUEUE_UDATA_T at compile time.
The NGX_KQUEUE_UDATA_T macro is used to compensate the incompatible
kqueue() API in NetBSD, it doesn't really belong to feature tests.

The change limits the macro visibility to the kqueue event module.
Moving from autotests also simplifies testing a particular NetBSD
version as seen in a subsequent change.
2025-07-11 16:25:51 +04:00
Sergey Kandaurov
0daaba5c54 Events: fixed -Wzero-as-null-pointer-constant warnings in kqueue.
The kevent udata field is special in that we maintain compatibility
with NetBSD versions that predate using the "void *" type.

The fix is to cast to intermediate uintptr_t that is casted back to
"void *" where appropriate.
2025-07-11 16:25:51 +04:00
Sergey Kandaurov
a5ca38f303 SSL: fixed testing OPENSSL_VERSION_NUMBER for OpenSSL 3.0+.
Prior to OpenSSL 3.0, OPENSSL_VERSION_NUMBER used the following format:

MNNFFPPS: major minor fix patch status

Where the status nibble (S) has 0+ for development and f for release.

The format was changed in OpenSSL 3.0.0, where it is always zero:

MNN00PP0: major minor patch
2025-07-10 19:00:45 +04:00
Sergey Kandaurov
a5d60c30d3 SSL: SSL_group_to_name() compatibility macro.
No functional changes.
2025-07-10 19:00:45 +04:00
Sergey Kandaurov
0bb7489cb2 QUIC: adjusted OpenSSL 3.5 QUIC API feature test.
A bug with the "quic_transport_parameters" extension and SNI described
in cedb855d7 is now fixed in the OpenSSL 3.5.1 release, as requested
in https://github.com/openssl/openssl/pull/27706.
2025-07-03 22:50:25 +04:00
Sergey Kandaurov
d1843e1d9b Win32: fixed PCRE license for nginx/Windows zip. 2025-06-25 14:19:13 +04:00
Sergey Kandaurov
279fe352cb Version bump. 2025-06-25 14:19:13 +04:00
Sergey Kandaurov
235f409907 nginx-1.29.0-RELEASE 2025-06-24 21:22:41 +04:00
Sergey Kandaurov
1263d6bec3 Updated OpenSSL and PCRE used for win32 builds. 2025-06-24 21:22:41 +04:00
Sergey Kandaurov
b997be14f5 Win32: skip OpenSSL dependency generation to conserve time.
Disabling the build dependency feature is safe assuming that
nginx/Windows release zip is always built from a clean tree.
This allows to speed up total build time by around 40%.

As it may not be suitable in general, the option resides here
and not in configure.
2025-06-24 21:22:41 +04:00
Sergey Kandaurov
cedb855d75 QUIC: disabled OpenSSL 3.5 QUIC API support by default.
In OpenSSL 3.5.0, the "quic_transport_parameters" extension set
internally by the QUIC API is cleared on the SSL context switch,
which disables sending QUIC transport parameters if switching to
a different server block on SNI.  See the initial report in [1].

This is fixed post OpenSSL 3.5.0 [2].  The fix is anticipated in
OpenSSL 3.5.1, which has not been released yet.  When building
with OpenSSL 3.5, OpenSSL compat layer is now used by default.
The OpenSSL 3.5 QUIC API support can be switched back using
--with-cc-opt='-DNGX_QUIC_OPENSSL_API=1'.

[1] https://github.com/nginx/nginx/issues/711
[2] 45bd3c3798
2025-06-23 22:35:09 +04:00
Sergey Kandaurov
cdf7a9c6cb Upstream: fixed reinit request with gRPC and Early Hints.
The gRPC module context has connection specific state, which can be lost
after request reinitialization when it comes to processing early hints.

The fix is to do only a portion of u->reinit_request() implementation
required after processing early hints, now inlined in modules.

Now NGX_HTTP_UPSTREAM_EARLY_HINTS is returned from u->process_header()
for early hints.  When reading a cached response, this code is mapped
to NGX_HTTP_UPSTREAM_INVALID_HEADER to indicate invalid header format.
2025-06-23 20:12:21 +04:00
Andrew Clayton
4eaecc5e8a Use NULL instead of 0 for null pointer constant.
There were a few random places where 0 was being used as a null pointer
constant.

We have a NULL macro for this very purpose, use it.

There is also some interest in actually deprecating the use of 0 as a
null pointer constant in C.

This was found with -Wzero-as-null-pointer-constant which was enabled
for C in GCC 15 (not enabled with Wall or Wextra... yet).

Link: <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117059>
2025-06-21 10:36:45 +04:00
Andrew Clayton
c370ac8a51 Use NGX_CONF_OK in some function return checks.
The functions ngx_http_merge_types() & ngx_conf_merge_path_value()
return either NGX_CONF_OK aka NULL aka ((void *)0) (probably) or
NGX_CONF_ERROR aka ((void *)-1).

They don't return an integer constant which is what NGX_OK aka (0) is.

Lets use the right thing in the function return check.

This was found with -Wzero-as-null-pointer-constant which was enabled
for C in GCC 15 (not enabled with Wall or Wextra... yet).

Link: <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117059>
2025-06-21 10:36:45 +04:00
Sergey Kandaurov
ba917b1360 HTTP/3: indexed field line encoding for "103 Early Hints". 2025-06-21 10:36:28 +04:00
Roman Arutyunyan
662c1dd2a9 Upstream: early hints support.
The change implements processing upstream early hints response in
ngx_http_proxy_module and ngx_http_grpc_module.  A new directive
"early_hints" enables sending early hints to the client.  By default,
sending early hints is disabled.

Example:

    map $http_sec_fetch_mode $early_hints {
        navigate $http2$http3;
    }

    early_hints $early_hints;

    proxy_pass http://example.com;
2025-06-19 10:19:57 +04:00
Roman Arutyunyan
ea001feb10 HTTP/2: added function declaration. 2025-06-19 10:19:57 +04:00
Sergey Kandaurov
5b8a5c08ce Core: added support for TCP keepalive parameters on macOS.
The support first appeared in OS X Mavericks 10.9 and documented since
OS X Yosemite 10.10.

It has a subtle implementation difference from other operating systems
in that the TCP_KEEPALIVE socket option (used in place of TCP_KEEPIDLE)
isn't inherited from a listening socket to an accepted socket.

An apparent reason for this behaviour is that it might be preserved for
the sake of backward compatibility.  The TCP_KEEPALIVE socket option is
not inherited since appearance in OS X Panther 10.3, which long predates
two other TCP_KEEPINTVL and TCP_KEEPCNT socket options.

Thanks to Andy Pan for initial work.
2025-05-27 01:59:02 +04:00
Aleksei Bavshin
3d5889a3ee SSL: disabled UI console prompts from worker processes.
Certain providers may attempt to reload the key on the first use after a
fork.  Such attempt would require re-prompting the pin, and this time we
are not able to pass the password callback.

While it is addressable with configuration for a specific provider, it would
be prudent to ensure that no such prompts could block worker processes by
setting the default UI method.

UI_null() first appeared in 1.1.1 along with the OSSL_STORE, so it is safe
to assume the same set of guards.
2025-05-26 06:56:18 -07:00
Aleksei Bavshin
0fdbfc1ff4 SSL: support loading keys via OSSL_STORE.
A new "store:..." prefix for the "ssl_certificate_key" directive allows
loading keys via the OSSL_STORE API.

The change is required to support hardware backed keys in OpenSSL 3.x using
the new "provider(7ossl)" modules, such as "pkcs11-provider".  While the
engine API is present in 3.x, some operating systems (notably, RHEL10)
have already disabled it in their builds of OpenSSL.

Related: https://trac.nginx.org/nginx/ticket/2449
2025-05-26 06:56:18 -07:00
Sergey Kandaurov
6a134dfd48 QUIC: using QUIC API introduced in OpenSSL 3.5.
Similarly to the QUIC API originated in BoringSSL, this API allows
to register custom TLS callbacks for an external QUIC implementation.
See the SSL_set_quic_tls_cbs manual page for details.

Due to a different approach used in OpenSSL 3.5, handling of CRYPTO
frames was streamlined to always write an incoming CRYPTO buffer to
the crypto context.  Using SSL_provide_quic_data(), this results in
transient allocation of chain links and buffers for CRYPTO frames
received in order.  Testing didn't reveal performance degradation of
QUIC handshakes, https://github.com/nginx/nginx/pull/646 provides
specific results.
2025-05-23 15:00:47 +04:00
Sergey Kandaurov
1d4d2f2c96 QUIC: better approach for premature handshake completion.
Using SSL_in_init() to inspect a handshake state was replaced with
SSL_is_init_finished().  This represents a more complete fix to the
BoringSSL issue addressed in 22671b37e.

This provides awareness of the early data handshake state when using
OpenSSL 3.5 TLS callbacks in 0-RTT enabled configurations, which, in
particular, is used to avoid premature completion of the initial TLS
handshake, before required client handshake messages are received.

This is a non-functional change when using BoringSSL.  It supersedes
testing non-positive SSL_do_handshake() results in all supported SSL
libraries, hence simplified.

In preparation for using OpenSSL 3.5 TLS callbacks.
2025-05-23 15:00:47 +04:00
Sergey Kandaurov
bcb9d3fd2c 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.
2025-05-23 15:00:47 +04:00
Sergey Kandaurov
9857578f15 QUIC: factored out SSL_provide_quic_data() to the helper function.
It is now called from ngx_quic_handle_crypto_frame(), prior to proceeding
with the handshake.  With this logic removed, the handshake function is
renamed to ngx_quic_handshake() to better match ngx_ssl_handshake().
2025-05-23 15:00:47 +04:00
Sergey Kandaurov
e561f7dbcf QUIC: defined SSL API macros in a single place.
All definitions now set in ngx_event_quic.h, this includes moving
NGX_QUIC_OPENSSL_COMPAT from autotests to compile time.  Further,
to improve code readability, a new NGX_QUIC_QUICTLS_API macro is
used for QuicTLS that provides old BoringSSL QUIC API.
2025-05-23 15:00:47 +04:00
Sergey Kandaurov
54e6b7cfee QUIC: logging missing mandatory TLS extensions only once.
Previously, they might be logged on every add_handshake_data
callback invocation when using OpenSSL compat layer and processing
coalesced handshake messages.

Further, the ALPN error message is adjusted to signal the missing
extension.  Possible reasons were previously narrowed down with
ebb6f7d65 changes in the ALPN callback that is invoked earlier in
the handshake.
2025-05-23 15:00:47 +04:00
Sergey Kandaurov
5d7fd4a7e3 QUIC: reset qc->error to zero again.
Following the previous change that removed posting a close event
in OpenSSL compat layer, now ngx_quic_close_connection() is always
called on error path with either NGX_ERROR or qc->error set.

This allows to remove a special value -1 served as a missing error,
which simplifies the code.  Partially reverts d3fb12d77.

Also, this improves handling of the draining connection state, which
consists of posting a close event with NGX_OK and no qc->error set,
where it was previously converted to NGX_QUIC_ERR_INTERNAL_ERROR.
Notably, this is rather a cosmetic fix, because drained connections
do not send any packets including CONNECTION_CLOSE, and qc->error
is not otherwise used.
2025-05-23 15:00:47 +04:00
Sergey Kandaurov
7468a10b62 QUIC: adjusted handling of callback errors.
Changed handshake callbacks to always return success.  This allows to avoid
logging SSL_do_handshake() errors with empty or cryptic "internal error"
OpenSSL error messages at the inappropriate "crit" log level.

Further, connections with failed callbacks are closed now right away when
using OpenSSL compat layer.  This change supersedes and reverts c37fdcdd1,
with the conditions to check callbacks invocation kept to slightly improve
code readability of control flow; they are optimized out in the resulting
assembly code.
2025-05-23 15:00:47 +04:00
Sergey Kandaurov
47f96993f6 QUIC: logging of SSL library errors.
Logging level for such errors, which should not normally happen,
is changed to NGX_LOG_ALERT, and ngx_log_error() is replaced with
ngx_ssl_error() for consistency with the rest of the code.
2025-05-23 15:00:47 +04:00
Sergey Kandaurov
ef9cd3214f QUIC: logging level of handshake errors.
Various errors reported by SSL_do_handshake() are now logged at the
"info" or "crit" level, akin to handshakes on regular TCP connections.
2025-05-23 15:00:47 +04:00
Sergey Kandaurov
aa43385ffa QUIC: removed ALPN feature test.
ALPN support is present in all libraries that have QUIC support,
it is safe to compile it unconditionally.
2025-05-23 15:00:47 +04:00
Sergey Kandaurov
39b1e3fe9d QUIC: removed excessive casts for ngx_ssl_get_connection().
They were blindly copied from ngx_ssl_info_callback(), where
the ngx_ssl_conn_t pointer is passed with const qualifier.
2025-05-23 15:00:47 +04:00
Sergey Kandaurov
335993154c QUIC: removed level field from ngx_quic_compat_record_t.
It was made unused in d15f8f2 after introducing reusable crypto contexts.
2025-05-23 15:00:47 +04:00
Sergey Kandaurov
f3542500b6 QUIC: do not block ACKs by congestion control.
Previously, it was not possible to send acknowledgments if the
congestion window was limited or temporarily exceeded, such as
after sending a large response or MTU probe.  If ACKs were not
received from the peer for some reason to update the in-flight
bytes counter below the congestion window, this might result in
a stalled connection.

The fix is to send ACKs regardless of congestion control.  This
meets RFC 9002, Section 7:
: Similar to TCP, packets containing only ACK frames do not count
: toward bytes in flight and are not congestion controlled.

This is a simplified implementation to send ACK frames from the
head of the queue.  This was made possible after 6f5f17358.

Reported in trac ticket #2621 and subsequently by Vladimir Homutov:
https://mailman.nginx.org/pipermail/nginx-devel/2025-April/ZKBAWRJVQXSZ2ISG3YJAF3EWMDRDHCMO.html
2025-04-29 19:53:41 +04:00
Sergey Kandaurov
adda704158 SSL: fixed build with OPENSSL_NO_DH. 2025-04-25 14:56:31 +04:00
Sergey Kandaurov
4f8bc0b282 SSL: fixed build with OPENSSL_NO_DEPRECATED. 2025-04-25 14:56:31 +04:00
nandsky
9785db9bd5 QUIC: fixed a typo. 2025-04-23 11:53:51 +04:00
Aleksei Bavshin
020b1db7eb Win32: added detection of ARM64 target.
This extends the target selection implemented in dad6ec3aa6 to support
Windows ARM64 platforms.  OpenSSL support for VC-WIN64-ARM target first
appeared in 1.1.1 and is present in all currently supported (3.x)
branches.

As a side effect, ARM64 Windows builds will get 16-byte alignment along
with the rest of non-x86 platforms.  This is safe, as malloc on 64-bit
Windows guarantees the fundamental alignment of allocations, 16 bytes.
2025-04-18 12:57:26 -07:00