CVSROOT:        /cvs
Module name:    src
Changes by:     [email protected]    2026/09/27 09:50:00

Modified files:
        lib/libcrypto/x509: Tag: OPENBSD_7_8 x509_verify.c 
        lib/libssl     : Tag: OPENBSD_7_8 d1_both.c d1_pkt.c 
        lib/libtls     : Tag: OPENBSD_7_8 tls_ocsp.c 
        usr.sbin/ocspcheck: Tag: OPENBSD_7_8 ocspcheck.c 

Log message:
Don't drop X509_V_ERR_HOSTNAME_MISMATCH when verify callback returns 1

While not the advised way of using the verify callback (either by OpenSSL
or by us) in production, sometimes folks like to return 1 from everything
in the callback and then check the error return and make decicions about
things.

This fix ensures that such callbacks will see the hostname mismatch and
be able to act upon them.

Reported by Alexander Aleksandrovic Klimov
from beck, ok tb@

Correct botched size check in dtls1_preprocess_fragment().

Check message length against max, rather than fragment offset and length.
Due to a various questionable code, this allows for a crafted messsage
to be sent that results in a 21MB allocation, which then promptly results
in an error. Providing that the SSL context is cleared or freed, the
allocation then freed, meaning that this has minimal impact. A similar
fix was landed in OpenSSL in 48c054fec35, although this checks against
dtls1_max_handshake_message_len() rather than max.

Thanks to Abdullah Al Ishtiaq for flagging this.

from jsing, ok kenjiro@ tb@

Limit size of buffered DTLS handshake messages.

Fragments from out-of-sequence DTLS handshake messages are buffered for
reassembly. When a new out-of-sequence handshake message fragment is
received it will allocate the full message length buffer that would be
used by the fully reassembled message. This is limited to the next
10 messages in sequence, each capped to a maximum size of 128KB - a
further 16KB is allocated for each reassembly bitmap. A set of crafted
handshake message fragments can trigger allocation of 10 * 144KB
(128KB + 16KB), with 156 bytes on the wire.

Change dtls1_max_handshake_message_len() so that we limit handshake
messages to ~16KB, with the exception of a Certificate message, which
uses s->max_cert_list (128KB by default). Also ensure that we do not
currently have an identical handshake message type pending for
reassembly - this prevents resassembly of multiple Certificate messages
which would then result in the original allocations.

This caps the allocation to ~306KB (9 * ~18KB + 144KB) - the correct
long term fix is to avoid full allocation by only storing the fragments
received on the wire, until reassembly can be completed.

from jsing, ok joshua@ kenjiro@ tb@

Reduce size of DTLS queues for unprocessed records and application data.

DTLS currently buffers records that contain handshake messages and alerts,
which are in the next epoch and cannot yet be processsed. This is done by
saving the entire buffer that is 16KB in size, regardless of the actual
bytes sent on the wire. With a queue limit of 100 it is possible to send a
small number of bytes on the wire and have the server allocate 1.6MB -
reducing the limit to 16 reduces the allocation to 256KB. This queue will
soon be removed entirely.

DTLS also currently buffers record content from application data where the
handshake has not yet finished. This only buffers the actual content
received on the wire and does not suffer from the same problem, however
reduce the queue size to further limit memory consumption.

from jsing, ok kenjiro@ tb@

libtls: fix OCSP responder authorization bypass

If a CA revokes a valid TLS server cert using OCSP, a client configured to
require a valid OCSP staple should always reject that cert. If the server's
private key has been compromised, it was possible to bypass this requirement.

The problem is the behavior of OCSP_TRUSTOTHER which skips chain
validation for the OCSP trust chain to the root and the checking that
the staple was signed by a CA of the validating chain. So remove this flag.

This only affects callers of tls_config_ocsp_require_stapling(). In OpenBSD
base these are reachable in OpenBSD base via opt-in behaviors of nc(1) -T
and ftp(1) -S via the "muststaple" keyword. No ports call these functions.

Reported by Acts1631 and Jiho Kim

ok beck kenjiro

ocspcheck: do not use OCSP_TRUSTOTHER

Like in libtls, ensure that the provided OCSP staple is validated by an
OCSP trust chain to the root.

>From Acts1631

ok beck kenjiro

Fix an off-by-one error in the X.509 verifier depth checking.

In x509_verify_build_chains(), ensure that we check the current depth
against max_depth prior to turning it into a legacy-style depth index.
Additionally, add a guard to x509_verify_chain_append() so that we avoid
exceeding the maximum certs per chain, even if we fail to handle this
correctly elsewhere. Also prevent the legacy callback from being able
to override the maximum verification depth.

The current off-by-one allows for a 4 byte overwrite to occur on heap
allocated memory - this will likely trigger a crash on OpenBSD (but may
go unnoticed elsewhere). This is only reachable if a TLS client is talking
to a malicious server or if a TLS server has client certificate
verification enabled - in both cases the verification depth also needs to
be set to the maximum allowed value of 32.

It is worth noting that many TLS clients/servers set the maximum
verification depth to a value that is much less than the default. A libtls
client or server uses a default depth of 6 and is not impacted in this
configuration.

Thanks to Calif.io in collaboration with Claude and Anthropic Research,
for reporting the issue.

ok tb@

Restore the previous behaviour with maximum verification depth.

The maximum depth is not expected to include the leaf certificate - restore
the decrement prior to checking, which means the previous behaviour is
retained for the callback depth and the maximum depth. Reduce the maximum
depth by one in order to avoid the overwrite that could previously occur.

Thanks to anton@ for flagging the rust-openssl failure in regress.

from jsing, ok tb@

verifier: re-enable the callback override for depth

kirill reported that his nginx reverse proxy setup stopped working
with x509_verify.c r1.74 and r1.75. It turns out that nginx relies
on a verify callback that always returns 1.

In revision 1.74 we removed the possibility of the verify_cb() to
override X509_V_ERR_CERT_CHAIN_TOO_LONG, which is what breaks the
config in kirill's setup since it used to use the nginx default of
setting the depth to 1. Re-enable this to make the new scenario
"2a with depth 1 and depth callback" pass.

As shown by the other new test scenario "14b with yolo calback"
with a "just say yes" cb, the guard added in r1.74 still prevents
the overwrite.

This makes kirill's reproducer work as verified by kirill and myself.
It was also tested by kirill in the real life setup.

discussed with beck
from tb, ok jsing kenjiro

this is errata/7.8/024_libressl.patch.sig

Reply via email to