aboutsummaryrefslogtreecommitdiffstats
path: root/test
Commit message (Collapse)AuthorAgeFilesLines
* test/cmp_client_test.c: add RR tests with issuer or serialNumber missingHEADmasterDaniel Kubec21 hours1-0/+72
| | | | | | | | | | | | | | Issuer and serialNumber are independently OPTIONAL in a CertTemplate, and the library hands them to the process_rr callback separately. The OpenSSL CMP client always sends both, so the mock server has never been exercised with an RR that carries only one of them. Assisted-by: Claude:claude-fable-5-1 Reviewed-by: Dmitry Belyavskiy <[email protected]> Reviewed-by: Mounir Idrassi <[email protected]> Reviewed-by: Eugene Syromiatnikov <[email protected]> Merge-date: Sat Oct 24 09:44:20 2026 Merged-from: https://github.com/openssl/openssl/pull/33071
* Migrate test_gcm_reinit from evp_extra_test.c to evp_aead_test.cDanny Nichols34 hours2-185/+185
| | | | | | | Reviewed-by: Neil Horman <[email protected]> Reviewed-by: Bob Beck <[email protected]> Merge-date: Fri Oct 23 20:40:17 2026 Merged-from: https://github.com/openssl/openssl/pull/33308
* QUIC: resend the whole ClientHello after a RetryNikolas Gauder42 hours4-76/+364
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | When the client received a Retry, ch_retry() marked only its first Initial packet as pseudo-lost, assuming that the ClientHello fits in it. Since 3.5 the default key shares (X25519MLKEM768 and X25519) put the ClientHello into two Initial packets. The second one stayed in flight, so the client resent only the first part of the ClientHello, and the server could do no more than acknowledge it. The rest was sent only once that acknowledgement had the second packet declared lost: one more round trip for every Retry, and a congestion event that halved the congestion window although nothing was lost. RFC 9002 section 6.3 has a client that receives a Retry reset its loss recovery state, as the server processed none of its Initial packets. Mark every Initial packet still in flight as pseudo-lost instead. ch_restart() marked only the first Initial packet after version negotiation in the same way. It now shares the helper, so ch_retry() no longer needs drop_later_pn to work out which packet number to mark. A Version Negotiation packet and a Retry can be processed in the same batch of datagrams. The first then leaves no Initial packet in flight for the second, and their data is already queued, so that is not an error. test_quic_retry_after_version_neg covers this order. The SSL_trace reference recorded the extra round trip, and is updated. The radix forbidden_frame_types script injects a frame into the server's Initial packets. With the whole ClientHello sent at once, a post-quantum ServerHello can fill the server's only Initial packet, leaving no room, so the script's server now uses classical groups. Fixes: f538b4215528 "QUIC_CHANNEL: Implementation" Fixes #33077 Assisted-by: Claude:claude-opus-5-5 Reviewed-by: Mounir Idrassi <[email protected]> Reviewed-by: Saša Nedvědický <[email protected]> Merge-date: Fri Oct 23 12:53:54 2026 Merged-from: https://github.com/openssl/openssl/pull/33298
* QUIC: release pseudo-lost packets from the congestion controllerNikolas Gauder42 hours1-0/+96
| | | | | | | | | | | | | | | | | | | | | | | On a Retry, and after version negotiation, the client marks Initial packets it has sent as pseudo-lost, so that their CRYPTO data is sent again. The ACK manager then stops counting them as in flight, but on purpose does not report them to the congestion controller as lost, since the network lost nothing. The congestion controller is not told about them at all, so NewReno kept counting their bytes as in flight for the rest of the connection, and allowed that much less to be sent. Release them with on_data_invalidated(), as when a packet number space is discarded. The congestion window is left alone. This follows the approach proposed in #33099. Fixes: 90699176b074 "QUIC CC: Major revisions to CC abstract interface" Fixes #33079 Assisted-by: Claude:claude-opus-5-5 Reviewed-by: Mounir Idrassi <[email protected]> Reviewed-by: Saša Nedvědický <[email protected]> Merge-date: Fri Oct 23 12:53:54 2026 Merged-from: https://github.com/openssl/openssl/pull/33298
* test: clear stale RADIX handshake injection selectorsMounir IDRASSI42 hours2-0/+7
| | | | | | | | | | | | | | | | | | | | | The handshake injection helpers share radix_fault with earlier scripts but left its selector words unchanged. script_68 leaves word0 set to 1, which selects CertificateRequest. script_69 installs the same callback before it sets word0 to 2 for KeyUpdate. A session ticket generated in that interval can trigger the previous script's fault and close the connection before the intended KeyUpdate injection. Clear both selector words in the handshake injection setup paths, as the plaintext injection setup already does. Request a normal session ticket in script_69 before arming its fault, so the test exercises the interval where an inherited selector caused the unexpected close. Keep the expected KeyUpdate close code unchanged. Assisted-by: Codex:gpt-6-astra Reviewed-by: Tomas Mraz <[email protected]> Reviewed-by: Nikola Pajkovsky <[email protected]> Merge-date: Fri Oct 23 12:40:35 2026 Merged-from: https://github.com/openssl/openssl/pull/33213
* test: make RADIX QUIC objects nonblocking by defaultMounir IDRASSI42 hours3-3/+102
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | RADIX drives both endpoints and advances its simulated clock from one interpreter. Accepted server connections inherit blocking mode from their listeners, even though the underlying UDP sockets are nonblocking. Extra handshake retries advance fake time and can inflate the initial RTT estimates. In the one-way key update loops the server's estimate can stay high while later samples reduce the client's PTO. The server can then retain its previous receive keys for longer than the client waits before its next update. Packets starting that update are then discarded, as permitted by RFC 9001 section 6.5. A blocking server read prevents the interpreter from driving client retransmission or advancing the clock, so this recoverable discard becomes a hang. The interpreter's 60-second deadline cannot interrupt the call, leaving the process watchdog to abort. External UDP loss is not required to reproduce the failure. Set clients and listeners to nonblocking mode at construction, including listeners created from a domain and the custom listener constructors. Accepted connections and their streams inherit this setting. The client setting makes the construction policy consistent before OP_CONNECT_WAIT, which also sets its mode. Retain the domain blocking capability needed by SSL_poll and document how tests can explicitly enable blocking I/O. Add a regression using existing opcodes to delay an ACK, increase the server's PTO and require recovery across successive client key updates. Cover both listener creation paths. Check listener and client modes before connection establishment and the accepted server's mode, so a recurrence fails promptly instead of waiting for the process watchdog. Fixes #33206. Assisted-by: Codex:gpt-6-astra Reviewed-by: Tomas Mraz <[email protected]> Reviewed-by: Nikola Pajkovsky <[email protected]> Merge-date: Fri Oct 23 12:40:35 2026 Merged-from: https://github.com/openssl/openssl/pull/33213
* DTLS listener: do not drive idle pending connections every tickMatt Caswell3 days1-0/+741
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | Every listener tick called SSL_accept() on every pending connection, whether or not anything had arrived for it, and each such call pumped the demux with another recvmmsg(). SSL_poll() ticks the listener once per item, so 256 one-byte datagrams from distinct source ports, which fill the pending table for 30 s, made every SSL_poll() over N connections cost (N + 1) * 256 futile SSL_accept() calls. Record whether the last drive left a pending connection waiting for its peer, and skip it until a datagram is queued for it or its retransmission timer expires. Driving one connection pumps the demux, which can queue a datagram for a connection the tick skipped or has already driven while emptying the socket the caller then waits on. Drive again when that happens, up to DTLS_LISTENER_MAX_DRIVE_PASSES times, and do not let a wait on the listener or on its connections sleep while such input remains. Discovered by Anthropic's OSS Scanner (finding ANT-2026-EFVK6J4Z). Assisted-by: Claude:claude-opus-5-5 Reviewed-by: Tomas Mraz <[email protected]> Reviewed-by: Saša Nedvědický <[email protected]> Reviewed-by: Ryan Hooper <[email protected]> Reviewed-by: Mounir Idrassi <[email protected]> Merge-date: Thu Oct 22 14:38:07 2026 Merged-from: https://github.com/openssl/openssl/pull/33265
* DTLS listener: free a pending connection that fails after HVRMatt Caswell3 days1-0/+101
| | | | | | | | | | | | | | | | | | | | dtls_listener_conn_needs_retry() reported a DTLS 1.2 connection as waiting for its second ClientHello whenever its handshake state was DTLS_ST_SW_HELLO_VERIFY_REQUEST, even if the connection had since entered the error state, e.g. on receiving a fatal alert from the peer. The listener then kept it in its pending table, and called SSL_accept() on it every tick, until the pending timeout expired instead of freeing it as a failed connection. Check ossl_statem_in_error() as the DTLS 1.3 HRR case already does. Assisted-by: Claude:claude-opus-5-5 Reviewed-by: Tomas Mraz <[email protected]> Reviewed-by: Saša Nedvědický <[email protected]> Reviewed-by: Ryan Hooper <[email protected]> Reviewed-by: Mounir Idrassi <[email protected]> Merge-date: Thu Oct 22 14:38:07 2026 Merged-from: https://github.com/openssl/openssl/pull/33265
* DTLS 1.3: Fix WANT_READ while awaiting ServerHelloRyan Hooper3 days1-0/+183
| | | | | | | | | | | | | | | | | | | | | After HelloRetryRequest, buffering records from a later epoch can request a retry without reading the BIO. Supply missing read-retry flags so SSL_get_error() reports SSL_ERROR_WANT_READ rather than SSL_ERROR_SYSCALL. Preserve existing retry conditions and handle listener connections without a read BIO. Add regression tests for delayed ServerHello delivery and permanent loss followed by timeout-driven retransmission. Check WANT_READ and an empty error queue after every retry, then verify handshake completion and bidirectional application data. Fixes: #33241 Assisted-by: Claude Code:claude-sonnet-5-5 Assisted-by: OpenCode:github-copilot/gpt-6-astra Reviewed-by: Tomas Mraz <[email protected]> Reviewed-by: Mounir Idrassi <[email protected]> Merge-date: Thu Oct 22 06:08:35 2026 Merged-from: https://github.com/openssl/openssl/pull/33268
* Fix wrong alignment in tho allocator used in quic_stream test.rainerjung4 days1-2/+16
| | | | | | | | | | | | | | | Wrong alignment observed on Solaris Sparc 10 (bus error). THO_ALLOC_HDR has size 20 and memory for structures gets allocated at addresses directly following a THO_ALLOC_HDR. Backport needed for the 4.1 branch. Fixes https://github.com/openssl/openssl/issues/33187 Reviewed-by: Eugene Syromiatnikov <[email protected]> Reviewed-by: Nikola Pajkovsky <[email protected]> Merge-date: Wed Oct 21 17:10:20 2026 Merged-from: https://github.com/openssl/openssl/pull/33204
* Add test for an update with no inputTrust-Worthy4 days1-0/+90
| | | | | | | | | | | | An update with no input and a nonzero length must fail, except for the CCM message length. test_evp_aead_update_null_input checks this for every AEAD, and that a rejected update writes no output. Assisted-by: Claude:claude-opus-5-5 Reviewed-by: Paul Dale <[email protected]> Reviewed-by: Neil Horman <[email protected]> Merge-date: Wed Oct 21 16:59:57 2026 Merged-from: https://github.com/openssl/openssl/pull/33157
* TLS: Generate the server random before processing ClientHello extensionsDaniel Kubec4 days3-8/+587
| | | | | | | | | | | | | | | | | | | | | | | The server random was only generated after all of the ClientHello extensions had been processed. In (D)TLSv1.3 the PSK callbacks are invoked while the pre_shared_key extension is being parsed, so a call to SSL_get_server_random() from within them returned all zeros. The TLSv1.2 psk_server_callback runs during ClientKeyExchange processing and so already observed the real value, making the behaviour inconsistent between protocol versions. Move the generation of the server random to immediately after the protocol version has been selected and before any of the remaining ClientHello processing. As a result the server random is also visible from the other callbacks invoked during ClientHello processing, such as the session ticket and servername callbacks. Fixes #26404 Assisted-by: Claude:claude-fable-5-1 Reviewed-by: Tomas Mraz <[email protected]> Reviewed-by: Frederik Wedel-Heinen <[email protected]> Merge-date: Wed Oct 21 16:45:34 2026 Merged-from: https://github.com/openssl/openssl/pull/33102
* Add updated Wycheproof test vectors to aes-gcm-siv test fileishamistry034 days1-0/+1767
| | | | | | | | | Assisted-by: Claude Sonnet 5 Signed-off-by: rkselvam-hub <[email protected]> Reviewed-by: Neil Horman <[email protected]> Reviewed-by: Nikola Pajkovsky <[email protected]> Merge-date: Wed Oct 21 16:33:06 2026 Merged-from: https://github.com/openssl/openssl/pull/32830
* Fix TLS 1.3 alert for missing key_shareAnuj Ramesh4 days1-1/+27
| | | | | | | | | | | Fixes #30818 Co-authored-by: Anuj Ramesh <[email protected]> Assisted-by: Claude:claude-fable-5 Reviewed-by: Matt Caswell <[email protected]> Reviewed-by: Frederik Wedel-Heinen <[email protected]> Merge-date: Wed Oct 21 16:29:21 2026 Merged-from: https://github.com/openssl/openssl/pull/32527
* ssl: handle session ID cache lock failureMounir IDRASSI4 days2-0/+142
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | SSL_has_matching_session_id() returns 0 both when no matching session exists and when the cache lock cannot be acquired. Its use in the built-in generator's retry loop and the final uniqueness check can therefore treat a lock failure as proof that no conflict exists. Add an internal tri-state lookup. The final uniqueness check uses it as a backstop for IDs produced by both built-in and application callbacks, recording an internal fatal error when the cache cannot be checked. The retry loop also uses it to prevent the built-in generator from returning an ID after its own lookup failed, through the existing callback failure path. Preserve the public API's boolean contract. Correct the callback-selection cache lock failure reason from SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED to ERR_R_INTERNAL_ERROR. Remove a redundant caller-side SSLfatal() that appended a generic ERR_R_INTERNAL_ERROR after the specific error already recorded. Add a deterministic unit test for final cache lookup failure. Fixes #32358 Assisted-by: Codex:gpt-5.6-sol Reviewed-by: Tomas Mraz <[email protected]> Reviewed-by: Dmitry Belyavskiy <[email protected]> Merge-date: Wed Oct 21 16:25:29 2026 Merged-from: https://github.com/openssl/openssl/pull/32359
* Adds a test that tests missing integrity only ciphers effect on TLS cipher ↵Frederik Wedel-Heinen4 days1-0/+90
| | | | | | | | | | suites. Co-authored-by: Mounir Idrassi <[email protected]> Reviewed-by: Mounir Idrassi <[email protected]> Reviewed-by: Dmitry Belyavskiy <[email protected]> Merge-date: Wed Oct 21 16:22:59 2026 Merged-from: https://github.com/openssl/openssl/pull/32051
* x509: key the duplicate-extension hash with SipHash to resist floodingDaniel Kubec4 days1-0/+55
| | | | | | | | | | | | | | | | | | | | | | | | scan_ext_flags() deduplicates certificate extensions. Standard extensions have an assigned NID and are handled by an O(1) bitset, but unknown or dynamically registered OIDs fall back to an hash table. Hash the OID with SipHash under a random key drawn once per scan, so the bucket an OID lands in is unpredictable to an attacker. This mirrors the existing defense for attacker-controlled keys in ssl/quic/quic_lcidm.c. If the table cannot be set up or an insert fails, fail closed with EXFLAG_INVALID, as ossl_x509v3_cache_extensions() does for any other extension it cannot process. Leaving the loop silently would skip not only the duplicate check but also the unsupported-critical check for this and every later extension. Discovered by Anthropic's OSS Scanner (finding ANT-2026-7UKRZ2MY). Assisted-by: Claude:claude-opus-4-8 Reviewed-by: Neil Horman <[email protected]> Reviewed-by: Matt Caswell <[email protected]> Merge-date: Wed Oct 21 15:58:52 2026 Merged-from: https://github.com/openssl/openssl/pull/33281
* DTLS 1.3: discard forbidden plaintext before replay checksMounir IDRASSI4 days1-1/+13
| | | | | | | | | | | | | | | | After the hellos, rejected plaintext records mustn't advance the epoch 0 replay window. The existing check runs after record processing updates that window, so a rejected record can affect a later plaintext alert. Move the check ahead of replay processing, while keeping next epoch records eligible for buffering. Extend the existing rejection test to verify that the bitmap stays unchanged before completing the handshake. Assisted-by: Codex:gpt-6-astra Reviewed-by: Tomas Mraz <[email protected]> Reviewed-by: Matt Caswell <[email protected]> Merge-date: Wed Oct 21 15:56:56 2026 Merged-from: https://github.com/openssl/openssl/pull/33271
* Fix DTLS listener waiter cleanup in SSL_pollMounir IDRASSI4 days1-25/+728
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | A blocking SSL_poll can register several objects on one DTLS listener. A single thread using DTLS can trigger this when a connection translator demultiplexes a datagram after an earlier listener item registers. Cleanup can then wait for a notification which only a later registration in the same call can clear. A finite poll timeout does not bound that cleanup wait. Overlapping polls can also wait on each other's registrations across distinct listeners. Track one registration per DTLS listener in the poll's wait context and separate deregistration from waiting for notification completion. Record the notification generation during deregistration so a later signal cannot prolong the wait for an earlier cycle. Cleanup still depends on the other registered waiters making progress. Extend the QUIC two-phase cleanup from PR #32137 to DTLS. Release every DTLS and QUIC registration before waiting for any notification cycle to finish. The QUIC translator's early deregistration remains nonblocking, so readiness rechecks and failures obey the same ordering in mixed arrays. The DTLS wait context records registrations as they are acquired, so partial setup failures and translation aborts release each exactly once. No public API changes are needed. Add coverage for shared listeners, repeated items, forced two-listener and mixed-protocol cleanup ordering, readiness rechecks, translation and allocation failures, single-thread controls, and notification generations. Use queued datagrams for the natural single-thread triggers and raise synthetic notifications only after registration. Guard cleanup and notification-generation regression tests with watchdogs. Fixes #33230 Assisted-by: Codex:gpt-6-astra Reviewed-by: Matt Caswell <[email protected]> Reviewed-by: Ryan Hooper <[email protected]> Merge-date: Wed Oct 21 15:51:43 2026 Merged-from: https://github.com/openssl/openssl/pull/33237
* DTLS: Fix listener cleanup after failed SSL_clearRyan Hooper4 days1-0/+153
| | | | | | | | | | | | | | | | | | | | | | | | | | SSL_clear() temporarily detaches an accepted connection's listener association while replacing its DTLS state. If initialization fails, unregister the saved peer before releasing the receive queue and listener reference. Otherwise, freeing the connection leaves a stale entry in the listener's established-connection table. Build the temporary unregister key in stack storage so removal does not depend on a successful allocation during cleanup. Share the key serialization with registration and lookup, preserving the existing peer-address matching and SipHash inputs. Add allocation-failure tests for SSL_clear() on an accepted DTLS 1.2 connection. Cover both single failures and sustained allocation failure through reset cleanup. Check that detached connections are removed, while connections retaining their listener association stay registered. Fixes: #32974 Assisted-by: OpenCode:github-copilot/gpt-6-astra Reviewed-by: Tomas Mraz <[email protected]> Reviewed-by: Matt Caswell <[email protected]> Reviewed-by: Mounir Idrassi <[email protected]> Merge-date: Wed Oct 21 15:41:49 2026 Merged-from: https://github.com/openssl/openssl/pull/33270
* CMS_get0_signers() returns only the signers that passed verificationIgor Ustinov4 days2-1/+15
| | | | | | | | | | | | | | | | | | | | With CMS_VERIFY_PARTIAL, CMS_verify() succeeds as long as at least one SignerInfo verifies, but CMS_get0_signers() still returned the certificate of every SignerInfo, defeating "signed by X" or "signed by N signers" policies. The same applied to the certificates written by "openssl cms -verify -verify_partial -signer". This commit fixes CMS_get0_signers() behaviour returning only certificates of signers that passed verification. Nothing changes if CMS_VERIFY_PARTIAL isn't set. Reported-by: Anthropic OSS scan id ANT-2026-GF4OIPVH Assisted-by: Claude:claude-opus-5-5 Reviewed-by: Tomas Mraz <[email protected]> Reviewed-by: Matt Caswell <[email protected]> Merge-date: Wed Oct 21 15:39:29 2026 Merged-from: https://github.com/openssl/openssl/pull/33279
* CMS_verify() stops at the first failure without CMS_VERIFY_PARTIALIgor Ustinov4 days1-3/+27
| | | | | | | | | | | | | | | | | | | | When CMS_VERIFY_PARTIAL was added, every "goto err" on a failed certificate, signed attributes, CAdES or content check was replaced by "continue", so that the remaining SignerInfos are still checked. Without the flag one failure already makes the whole call fail, yet CMS_verify() went on checking all the other signers and reading the content, which only wastes time. Goto err on the first failure unless CMS_VERIFY_PARTIAL is set again. Fixes: 5af9dbf12832 "Implement partial verification for CMS with multiple signatures" Reported-by: Anthropic's OSS Scanner, ANT-2026-D12JMUYJ Assisted-by: Claude:claude-opus-5-5 Reviewed-by: Tomas Mraz <[email protected]> Reviewed-by: Milan Broz <[email protected]> Merge-date: Wed Oct 21 15:36:24 2026 Merged-from: https://github.com/openssl/openssl/pull/33283
* Don't report held-back DTLS app data as readable in SSL_poll()Matt Caswell4 days1-0/+159
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | ossl_dtls_conn_poll_events() reported SSL_POLL_EVENT_R whenever SSL_has_pending() was true. For DTLS that includes records in buffered_app_data, which dtls1_read_bytes() only releases once the handshake has finished. In DTLS 1.3 the sender of a KeyUpdate stays in init until it is ACKed. If the peer sends application data without ACKing, e.g.: 1. Server sends KeyUpdate, enters TLS_ST_SW_KEY_UPDATE. 2. Client sends a record before reading the KeyUpdate. 3. Server's SSL_read() buffers the record, returns WANT_READ. then every SSL_poll() returns at once with SSL_POLL_EVENT_R and every SSL_read() returns SSL_ERROR_WANT_READ. An event loop spins until the ACK arrives or the KeyUpdate retransmissions run out (483s). The same happens to a client, and in DTLS 1.2 for data received between ChangeCipherSpec and Finished. Only count buffered_app_data once the handshake has finished, and otherwise wait for incoming datagrams as usual. Discovered by Anthropic's OSS Scanner (finding ANT-2026-QCQMEE2S). Assisted-by: Claude Code:claude-opus-5-5 Reviewed-by: Mounir Idrassi <[email protected]> Reviewed-by: Ryan Hooper <[email protected]> Merge-date: Wed Oct 21 09:21:56 2026 Merged-from: https://github.com/openssl/openssl/pull/33262
* Don't dereference a NULL rbio in dtls1_read_failed()Matt Caswell5 days1-0/+106
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Connections created by a DTLS listener have no read BIO; they read from a queue that the listener's demux fills. dtls1_read_failed() still set BIO_FLAGS_READ on the read BIO unconditionally once the handshake had finished. A DTLS 1.3 server keeps its retransmission timer armed after the handshake until the client ACKs the NewSessionTickets. A client that never sends that ACK can arrange for the timer to expire while a non-blocking SSL_read() on the server is pumping the demux and finds no record (for example, by sending datagrams the record layer discards). dtls1_read_bytes() then calls dtls1_read_failed(), which crashes on the NULL BIO. Skip setting the flag when there is no read BIO. SSL_get_error() already returns SSL_ERROR_WANT_READ for listener connections without one. The DTLS listener has not been in any final release, so no released version of OpenSSL is affected. Discovered by Anthropic's OSS Scanner (finding ANT-2026-NPC3SFSW). Assisted-by: Claude Code:claude-opus-5-5 Reviewed-by: Tomas Mraz <[email protected]> Reviewed-by: Mounir Idrassi <[email protected]> Reviewed-by: Nikola Pajkovsky <[email protected]> Merge-date: Tue Oct 20 13:30:03 2026 Merged-from: https://github.com/openssl/openssl/pull/33257
* DTLS 1.3: only accept plaintext alerts once the hellos are doneMatt Caswell5 days1-0/+95
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | DTLS 1.3 defers installing the handshake read keys until the peer's first epoch 2 record arrives. Until then the read record layer stays in epoch 0 and accepted plaintext handshake and ACK records. A peer that never sends an epoch 2 record could therefore send its Finished in plaintext. That Finished was checked with a finished key that was never derived (all zero), and the connection completed with its application read keys numbered epoch 1 instead of 3. From that state a client can ACK only the second NewSessionTicket and then send a record claiming epoch 2. The server performs the deferred key change on the established connection, and dtls1_clear_sent_buffer() on the partly acknowledged queue leaves a freed item linked in sent_messages, which is a use-after-free. A malicious server can do the same to a client. Once the hellos are done, tell the epoch 0 read layer that only plaintext alerts may still arrive, and discard any handshake fragments buffered before then. Make tls_process_finished() refuse a DTLS 1.3 Finished read before the handshake keys are installed. Disarm the deferred key change once it has run, and reset it with the connection. DTLS 1.3 has not been in any final release, so no released version of OpenSSL is affected. Discovered by Anthropic's OSS Scanner (finding ANT-2026-YZ5U4MXB). Assisted-by: Claude Code:claude-opus-5-5 Reviewed-by: Tomas Mraz <[email protected]> Reviewed-by: Mounir Idrassi <[email protected]> Reviewed-by: Daniel Kubec <[email protected]> Merge-date: Tue Oct 20 12:38:20 2026 Merged-from: https://github.com/openssl/openssl/pull/33256
* Fix SSL_poll() multi-reactor cleanup deadlockMounir IDRASSI5 days1-0/+489
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | SSL_poll() cleaned up QUIC reactor wait registrations in item-array order. Leaving a reactor can block while its notifier is signalled, so two callers spanning the same reactors could each wait on one reactor while still registered on another. The translation abort path has the same ordering problem. Split QUIC leave into two phases: deregister from every QUIC reactor, then wait for any notification cycles still pending. For QUIC-only poll sets this removes every waiter registration before any notifier wait. DTLS listener cleanup is unchanged. Guard the QUIC drain call for no-quic builds. Phase 2 also prevents an immediate re-registration from keeping the notifier signalled. Capture notify_generation during deregistration so a wait is bounded to the observed cycle. Apply the same generation bound to the combined single-reactor leave operation. Exercise real SSL_poll cleanup on two reactors in both the post-poll and translation-abort paths, including repeated items sharing a reactor. Check that a delayed phase-2 waiter completes while a later notification cycle remains signalled. Fixes #32130 Assisted-by: OpenCode:GLM-5.2 Assisted-by: Codex:gpt-5.6-sol Assisted-by: Codex:gpt-6-astra Reviewed-by: Tomas Mraz <[email protected]> Reviewed-by: Neil Horman <[email protected]> Merge-date: Tue Oct 20 12:29:05 2026 Merged-from: https://github.com/openssl/openssl/pull/32137
* Move scripts script_70 - script_108 from QUIC multistream testAndrew Dinh6 days7-4423/+1769
| | | | | | | | | | | to QUIC radix tests. Also remove now unused test/quic_multistream_test.c Assisted-by: Claude:claude-sonnet-5 Reviewed-by: Neil Horman <[email protected]> Reviewed-by: Saša Nedvědický <[email protected]> MergeDate: Mon Oct 19 14:13:33 2026 (Merged from https://github.com/openssl/openssl/pull/33103)
* apps/ocsp.c: fail on invalid response timesskaiea13-ai6 days1-2/+33
| | | | | | | | | | | | | | | | | | | | Propagate OCSP_check_validity() failures through print_ocsp_summary(), so the command returns a nonzero exit status for stale responses. Add a request-aware regression test using the existing signed fixtures. Resolves: https://github.com/openssl/openssl/issues/32367 References: 639bb581ce5b "apps/ocsp: Return non zero exit code with invalid certID" References: https://github.com/openssl/openssl/issues/7151 Co-Authored-by: Mounir Idrassi <[email protected]> Assisted-by: OpenAI Codex:GPT-5 Assisted-by: OpenAI Codex:GPT-6 Reviewed-by: Frederik Wedel-Heinen <[email protected]> Reviewed-by: Mounir Idrassi <[email protected]> Reviewed-by: Tomas Mraz <[email protected]> Reviewed-by: Eugene Syromiatnikov <[email protected]> Merge-date: Mon Oct 19 13:41:13 2026 Merged-from: https://github.com/openssl/openssl/pull/32600
* test/ml_dsa_test.c: add a check for empty message finalisationAlberto Maschietto6 days1-0/+89
| | | | | | | | | | | | | | | | | | | | | | The regression test covers four cases: pure ML-DSA and SHA-512 prehash mode, each with either no update or an explicit EVP_DigestUpdate(mdctx, NULL, 0). Pure mode must succeed and return the independently calculated SHAKE256(SHAKE256(pub, 64) || 0x00 || 0x00, 64). Prehash mode must reject the missing prehash input. The test is gated on FIPS provider version because unfixed providers would crash. The default provider always runs the regression. References: https://github.com/openssl/openssl/issues/32445 Assisted-by: Claude Code Assisted-by: Codex:gpt-6 Reviewed-by: Mounir Idrassi <[email protected]> Reviewed-by: Nikola Pajkovsky <[email protected]> Reviewed-by: Tomas Mraz <[email protected]> Reviewed-by: Eugene Syromiatnikov <[email protected]> Merge-date: Mon Oct 19 11:08:03 2026 Merged-from: https://github.com/openssl/openssl/pull/32447
* Fix use-after-free in EC_GROUP_get_ecpkparameters()Minkyung Park7 days1-1/+37
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | When a caller-supplied ECPKPARAMETERS object is passed in, the CHOICE member it already holds is released on entry, but the union pointer was left untouched. If a later step then failed, the error exit called ECPKPARAMETERS_free() on that object, which followed the still valid selector and freed the already released member a second time. Clear the pointer once it has been released, so that the error exit has nothing left to free. This does not change the fact that a caller supplied object is freed on error. That behaviour differs from the sibling function EC_GROUP_get_ecparameters(), which only frees the object it allocated itself, but it is left as-is here. The new test only fails on a sanitizer build; the ECPKPARAMETERS layout is private to ec_asn1.c, so the state cannot be inspected directly. The regression test and the pull request description were written with AI assistance. Fixes: 012c86ab74ae "move ECC ASN1 that is not specific to ECDSA into crypto/ec/, and make some appropriate changes to the EC library." Co-authored-by: Jakub Zelenka <[email protected]> Assisted-by: Claude:claude-fable-5 Reviewed-by: Jakub Zelenka <[email protected]> Reviewed-by: Frederik Wedel-Heinen <[email protected]> Reviewed-by: Eugene Syromiatnikov <[email protected]> Merge-date: Sun Oct 18 15:26:51 2026 Merged-from: https://github.com/openssl/openssl/pull/32169
* test/cmp_vfy_test.c: prevent memory leak in ↵jdymitarai10 days1-9/+5
| | | | | | | | | | | | | | | | | | | | | | | | test_msg_check_update_malicious_sender In test_msg_check_update_malicious_sender(), expected and actual were allocated via X509_NAME_new() prior to SETUP_TEST_FIXTURE(). If set_up() failed, SETUP_TEST_FIXTURE() returned early, leaking both allocated X509_NAME objects. Defer allocation until after SETUP_TEST_FIXTURE(), initialize both pointers to NULL, and allocate them safely within the TEST_ptr() validation chain. On setup or validation failure, both pointers and the test fixture are freed cleanly. Resolves: https://github.com/openssl/openssl/issues/33200 Fixes: a6286cd01801 "Add test for CVE-2026-63073" CLA: trivial Signed-off-by: jdymitarai <[email protected]> Reviewed-by: Neil Horman <[email protected]> Reviewed-by: Eugene Syromiatnikov <[email protected]> Reviewed-by: Nikola Pajkovsky <[email protected]> Merge-date: Thu Oct 15 11:51:16 2026 Merged-from: https://github.com/openssl/openssl/pull/33203
* test/dtlsssllistenertest.c: fix flaky zero-wait handshake loopsRyan Hooper11 days1-2/+8
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | test_dtls_listener_max_dgram_size_functional() and test_dtls_notifier_signalled_on_accept_queue_push() drive a real loopback UDP handshake in a fixed 100-iteration loop that polls with a zero timeout and never sleeps between attempts. If loopback delivery lags - as it does intermittently on macOS CI runners - the loop can exhaust its budget before a datagram becomes readable and the test fails with "did not converge", even though the listener is working correctly. This is the same bug fixed in drive_until_connection_queued() by 271222650b ("dtls: fix flaky cookie exchange loop in listener test"). Apply the same treatment here: sleep 10ms between iterations so a delayed datagram has time to arrive, and raise the iteration cap to 200 so the budget still covers the client's 1s initial retransmit timer if a datagram is lost outright. Every other real-socket convergence loop in the file already waits on the SSL_poll() call itself (poll_timeout.tv_usec = 100000) rather than busy-spinning, and the remaining zero-timeout loops are backed by an in-memory dgram BIO pair with synchronous delivery, so neither needed this fix. Assisted-by: Claude:claude-sonnet-5 Reviewed-by: Jakub Zelenka <[email protected]> Reviewed-by: Mounir Idrassi <[email protected]> Reviewed-by: Eugene Syromiatnikov <[email protected]> Merge-date: Wed Oct 14 11:41:42 2026 Merged-from: https://github.com/openssl/openssl/pull/32673
* DTLS listener: bound the demux free listMounir IDRASSI11 days1-0/+136
| | | | | | | | | | | | | | | | | | | | | | | | | The demux free list caches released URXEs so a receive burst can be served without allocating, but nothing bounds it: a transient flood raising the per-connection receive queues also raises the free list's retained high-water mark for the remaining lifetime of the listener. Add a per-demux limit, ossl_dgram_demux_set_max_free_urxe(), enforced in ossl_dgram_demux_release_urxe(): a URXE released while the free list is at its limit is freed instead of cached, so the bound is strict and no later trim pass is needed. Freeing there honours the documented contract that no reference may be made to a URXE or its buffer after it is released, and no release caller touches the entry afterwards. The DTLS listener sets the limit to DEMUX_MAX_FREE_URXE, two receive batches, so one full batch can always be cached; QUIC keeps the default unbounded behaviour. Resolves: https://github.com/openssl/openssl/issues/33173 Assisted-by: Claude Code:moonshotai/kimi-k3 Reviewed-by: Tomas Mraz <[email protected]> Reviewed-by: Ryan Hooper <[email protected]> Reviewed-by: Eugene Syromiatnikov <[email protected]> Merge-date: Wed Oct 14 10:54:56 2026 Merged-from: https://github.com/openssl/openssl/pull/33197
* DTLS listener: make max_pending_conns a combined admission budgetMounir IDRASSI11 days1-0/+361
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The pending-connection cap only applied to pending_conns, the table of connections still doing their handshake: the moment a connection passed cookie validation it was moved onto the accept queue (incoming_connections) with no length check and no expiry. A reachable peer completing the ordinary cookie exchange from many source endpoints could accumulate an unbounded, unexpiring queue of listener-owned SSL objects. This is the same missing admission bound as the QUIC listener admission check fixed in [1]; the DTLS listener is new in 4.1 and not in any final release. Mirror the QUIC fix: enforce the bound at admission, in the packet handler, before any per-connection state is allocated. SSL_VALUE_DTLS_LISTENER_MAX_PENDING_CONNS is now a single admission budget covering both listener-owned tables, pending plus accept queue, so listener-owned connections are bounded at N in total, including under SSL_LISTENER_FLAG_NO_VALIDATE. Moving a connection from one table to the other leaves the total unchanged, so a validated connection can always be queued: none is discarded, and no handshake work (cookie exchange, server flight) is spent on an attempt that cannot be admitted. A peer whose datagram is dropped while the budget is exhausted retransmits its ClientHello and is admitted once the application drains the queue; measured on real UDP, such a client completes its handshake about one retransmit interval after the drain. This also aligns the DTLS knob's meaning with the QUIC one ("not yet accepted"), which it was modelled on in [2]. Accept-queue entries still do not expire; a full queue stays full until the application drains it. With the budget, an attacker can pin at most N accept-queue slots, and only after proving return routability - spoofed ClientHellos can still occupy pending slots until the pending timeout reaps them, as before this change - so what remains is a bounded availability concern, not memory exhaustion. [1] https://github.com/openssl/openssl/pull/32052 [2] https://github.com/openssl/openssl/pull/31980 Resolves: https://github.com/openssl/openssl/issues/33172 Assisted-by: Claude Code:moonshotai/kimi-k3 Reviewed-by: Tomas Mraz <[email protected]> Reviewed-by: Ryan Hooper <[email protected]> Reviewed-by: Eugene Syromiatnikov <[email protected]> Merge-date: Wed Oct 14 10:54:55 2026 Merged-from: https://github.com/openssl/openssl/pull/33197
* DTLS listener: bound the per-connection receive queueMounir IDRASSI11 days1-0/+111
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The DTLS listener queues datagrams from a known peer into a per-connection list (DTLS_RX::urxe_pending) with no limit on count or bytes. A reachable peer that completes the ordinary cookie exchange can grow one parked connection's queue without bound as long as the application keeps the shared demux pumped, moving datagrams into userspace past the bound the kernel socket buffer would otherwise provide. Cap the queue at OSSL_DTLS_RX_DEFAULT_MAX_QUEUED (128) datagrams per connection - a datagram count, not a byte cap. Every queued URXE holds a buffer of at least the listener's maximum datagram size whatever the datagram's length, so a full queue costs about 295 KB per connection at the default 2000-byte size, roughly one default kernel socket receive buffer; across a full 256-connection listener budget that is about 75 MB. The queue is consumed FIFO, so on overflow the oldest datagram is evicted rather than the newest: a DTLS flight can span several datagrams, and under overload keeping the newest biases the queue toward the flight the peer just sent instead of stale fragments of an older one. The evicted URXE is unhooked under rx->mutex and released to the demux after dropping it, so demux->mutex is never taken while rx->mutex is held. References: https://github.com/openssl/openssl/issues/33173 Assisted-by: Claude Code:moonshotai/kimi-k3 Reviewed-by: Tomas Mraz <[email protected]> Reviewed-by: Ryan Hooper <[email protected]> Reviewed-by: Eugene Syromiatnikov <[email protected]> Merge-date: Wed Oct 14 10:54:54 2026 Merged-from: https://github.com/openssl/openssl/pull/33197
* AEAD regression test for EVP_CIPHER_do_all_providedBilly Brumley12 days1-98/+123
| | | | | | | | | | | | | | | | | | | | | ... combined with a sanity check for expected AEAD algs in a static list. - every cipher in aead_algs[] must be discovered - every discovered cipher must be in aead_algs[] Meant to catch: - ciphers falling out of dynamic discovery for unexpected reasons - ciphers discovered dynamically for unexpected reasons Could happen for reasons like build system errors, flags shifting, etc. Assisted-by: Claude:claude-fable-5-1 Reviewed-by: Neil Horman <[email protected]> Reviewed-by: Saša Nedvědický <[email protected]> Reviewed-by: Eugene Syromiatnikov <[email protected]> Merge-date: Tue Oct 13 15:22:55 2026 Merged-from: https://github.com/openssl/openssl/pull/32842
* test: migrate test_aes_siv_ctx_enc_retval from evp_extra_test.c to ↵Hamzah Yamani13 days2-37/+65
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | evp_aead_test.c Move test_aes_siv_ctx_enc_retval() out of test/evp_extra_test.c into test/evp_aead_test.c, rename it to test_evp_aead_enc_retval() and run it over aead_list instead of only AES-128-SIV. The check is that after a completed encrypt, a further EVP_EncryptUpdate() on the same context is rejected, and the EVP_EncryptFinal_ex() that follows fails as well, instead of reporting the earlier success. GCM, OCB and ASCON mark the context finished. SIV stores the result of the last operation, so a rejected Update makes the following Final fail. CCM, GCM-SIV and ChaCha20-Poly1305 are skipped: Final currently succeeds after the rejected Update, and what it should do is not settled yet. ChaCha20-Poly1305 reports the same mode as ASCON, so it is matched by name. Key and IV are sized from the resolved cipher parameters, the context is set up with EVP_EncryptInit_ex2(), and the tag is fetched after Final with OSSL_PARAM. Assisted-by: Claude:claude-sonnet-5 Reviewed-by: Neil Horman <[email protected]> Reviewed-by: Nikola Pajkovsky <[email protected]> Reviewed-by: Eugene Syromiatnikov <[email protected]> Merge-date: Mon Oct 12 13:15:18 2026 Merged-from: https://github.com/openssl/openssl/pull/33135
* Migrate test_evp_final_no_tag to evp_aead_test.cHamzah Yamani13 days2-75/+83
| | | | | | | | | | | | | | | | | | | | | | | | | | Move test_evp_final_no_tag out of evp_extra_test.c into evp_aead_test.c and run it over every AEAD in aead_list instead of a hardcoded pair of ciphers. The check is that EVP_DecryptFinal_ex() refuses to finalize a decrypt when no tag has been set. CCM, OCB, SIV and GCM-SIV are skipped for now. Those modes either require the tag and payload length to be declared before the payload update, or verify inside the payload update rather than in final, so the check as written does not apply to them. How the interface should behave for these modes is still under discussion. Key and IV buffers are sized to EVP_MAX_KEY_LENGTH and EVP_MAX_IV_LENGTH so ciphers with longer keys, such as AES-256-SIV, stay in bounds, and the keylen, ivlen and taglen of each cipher are checked against those buffers. Encryption and decryption use separate contexts, initialized with EVP_*Init_ex2(), and the decrypt final writes to the plaintext buffer. Assisted-by: Claude:claude-sonnet-5 Reviewed-by: Neil Horman <[email protected]> Reviewed-by: Saša Nedvědický <[email protected]> Reviewed-by: Eugene Syromiatnikov <[email protected]> Merge-date: Sun Oct 11 22:27:06 2026 Merged-from: https://github.com/openssl/openssl/pull/32907
* QUIC: don't answer a refused Retry token with another RetryNikolas Gauder13 days1-0/+215
| | | | | | | | | | | | | | | | | | | When an Initial packet carries a Retry token that we minted, but which then fails validation (expired, wrong address or DCID), the server sent a fresh Retry. The client has already processed a Retry packet and must ignore any further ones (RFC 9000 section 17.2.5.2), so it just waits for its idle timeout. Drop the packet instead, which RFC 9000 section 8.1.2 allows. Tokens that don't decrypt, or NEW_TOKEN tokens, still get a Retry as before. Fixes: 29e861a5a605 "Add lookup for initial token assignment on channel start" Assisted-by: Claude:claude-opus-5-5 Reviewed-by: Saša Nedvědický <[email protected]> Reviewed-by: Neil Horman <[email protected]> Reviewed-by: Eugene Syromiatnikov <[email protected]> Merge-date: Sun Oct 11 20:18:44 2026 Merged-from: https://github.com/openssl/openssl/pull/33149
* test/quic_stream_test.c: remove unused tho_heap1024_total global variableEugene Syromiatnikov2026-10-101-2/+1
| | | | | | | | | | | | | | | | | | | msys-minigw64 workflow with clang compiler started to fail during build with the following diagnostics: test/quic_stream_test.c:3172:53: error: variable 'tho_heap1024_total' set but not used [-Werror,-Wunused-but-set-global] 3172 | static size_t tho_heap1024_live, tho_heap1024_peak, tho_heap1024_total; | ^ Remove the variable, as it seems that it indeed has no use in the current version of the test. Complements: 2d6c7ced4337 "tests: test_dstorage_cleanse() and test_heap_overlap()" Signed-off-by: Eugene Syromiatnikov <[email protected]> Reviewed-by: Milan Broz <[email protected]> Reviewed-by: Neil Horman <[email protected]> Merge-date: Sat Oct 10 16:16:22 2026 Merged-from: https://github.com/openssl/openssl/pull/33180
* test/quicapitest.c: fix BIO leak in test_quic_amplification_limit()Nikolas Gauder2026-10-101-3/+9
| | | | | | | | | | | | | | The dgram pair BIOs leaked if the test failed before SSL_set_bio(). Free them on exit, and clear the local pointers once the SSL objects own them, as other tests in this file do. Fixes: dc13cfb93120 "Add a test to check for quic unvalidated credit" Assisted-by: Claude:claude-opus-5-5 Reviewed-by: Neil Horman <[email protected]> Reviewed-by: Saša Nedvědický <[email protected]> Reviewed-by: Eugene Syromiatnikov <[email protected]> Merge-date: Sat Oct 10 08:16:49 2026 Merged-from: https://github.com/openssl/openssl/pull/33150
* CONF: reject a NUL list separator in CONF_parse_list()Darren Carreras2026-10-093-1/+122
| | | | | | | | | | | | | | | | | | | | | | | CONF_parse_list() treated any integer separator that converts to NUL as a match for the input string terminator. After processing the final element, the loop advanced beyond the input and searched from that invalid pointer on the next iteration. Reject every NUL-equivalent separator before parsing and raise ERR_R_PASSED_INVALID_ARGUMENT. Add a regression test that verifies the direct NUL value and positive/negative integer aliases, confirms that no callback is invoked, checks the error queue, and checks that normal comma-separated parsing keeps working as expected. Resolves: https://github.com/openssl/openssl/issues/32667 Fixes: df5eaa8a5297 "default_algorithms option in ENGINE config." Reported-by: x-ray-z Assisted-by: OpenAI Codex:gpt-5.6-sol Reviewed-by: Mounir Idrassi <[email protected]> Reviewed-by: Daniel Kubec <[email protected]> Reviewed-by: Eugene Syromiatnikov <[email protected]> Merge-date: Fri Oct 9 21:25:58 2026 Merged-from: https://github.com/openssl/openssl/pull/32684
* crypto/ct/ct_log.c: handle negative returns when loading a log storeMounir IDRASSI2026-10-092-0/+32
| | | | | | | | | | | | | | | | | | | | | | | | CTLOG_STORE_load_file() treats a negative CONF_parse_list() return as success, even when the callback failed to allocate the log name. Check for non-positive parser returns so internal errors produce the documented 0 return value, preserving the existing invalid-entry handling. Add a regression using the existing allocation failure framework and a configuration referencing a missing log section. Loading must return 0 both normally and when allocations fail. Return -1 from the test on unexpected success so ADD_MFAIL_NO_CHECK_TEST cannot mask the failure. Resolves: https://github.com/openssl/openssl/issues/32703 References: 70073f3e3aeb "Treat boolean functions as booleans" Complements: 68efafc51378 "Add checks on sk_TYPE_push() returned value" Complements: e57036f2bf81 "Fix some memory error handling in CT" Assisted-by: Codex:gpt-6-astra Reviewed-by: Saša Nedvědický <[email protected]> Reviewed-by: Frederik Wedel-Heinen <[email protected]> Reviewed-by: Eugene Syromiatnikov <[email protected]> Merge-date: Fri Oct 9 20:40:44 2026 Merged-from: https://github.com/openssl/openssl/pull/32704
* EVP_MD_demo.c, tls13secretstest.c: avoid signed-to-unsigned integer conversionJan Schaumann2026-10-091-1/+5
| | | | | | | | | | | | | | | | | | Should EVP_MD_size() return -1, the size_t len variable would wrap, causing any subsequent error checks to not trigger. Change to type int (which is what EVP_MD_size() returns). While this is just in test/demo code, that's the kind of code that people might copy and reuse elsewhere, and that AI vuln scanners trigger on, so might as well try to eliminate that noise. Fixes: 7a7fbeb924a0 "fix all the warnings in our demos and make them enableable" Fixes: 134bfe56c4fe "Add a test for the TLS1.3 secret generation" Reviewed-by: Paul Dale <[email protected]> Reviewed-by: Nikola Pajkovsky <[email protected]> Reviewed-by: Eugene Syromiatnikov <[email protected]> Merge-date: Fri Oct 9 19:19:13 2026 Merged-from: https://github.com/openssl/openssl/pull/31222
* Fix ossltest provider SHA384 sizeViktor Dukhovni2026-10-091-1/+1
| | | | | | | Reviewed-by: Mounir Idrassi <[email protected]> Reviewed-by: Nikola Pajkovsky <[email protected]> Merge-date: Fri Oct 9 13:56:08 2026 Merged-from: https://github.com/openssl/openssl/pull/31925
* Fix ECH server verify_result misuseViktor Dukhovni2026-10-091-0/+70
| | | | | | | Reviewed-by: Mounir Idrassi <[email protected]> Reviewed-by: Nikola Pajkovsky <[email protected]> Merge-date: Fri Oct 9 13:56:06 2026 Merged-from: https://github.com/openssl/openssl/pull/31925
* PSK: Check for invalid server PSK ciphersViktor Dukhovni2026-10-091-0/+112
| | | | | | | | | | | | | If an application fails to set the PSK session cipher, or sets it to a TLS 1.2 cipher by mistake, skip the invalid PSK, avoiding a crash or an invalid outcome. Tests added to make sure a full handshake takes place instead. Reviewed-by: Mounir Idrassi <[email protected]> Reviewed-by: Nikola Pajkovsky <[email protected]> Merge-date: Fri Oct 9 13:56:05 2026 Merged-from: https://github.com/openssl/openssl/pull/31925
* Test PHA verification results across session resumptionMounir IDRASSI2026-10-081-412/+503
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | An application verification callback may accept a nonempty client certificate or RPK while retaining a nonzero verification error. That result must survive post-handshake authentication and resumption, without changing the previously published session. Expand pending-identity coverage to exercise X.509 and RPK replacement with successful and callback-accepted error results, using stateful and stateless refreshed tickets. Check the replacement identity and result on the live connection and session, then on a resumed connection. Also check that the retained cache-owned session remains unchanged. Start empty-RPK tests with a nonzero prior verification result. An optional empty response must remove that stale result, while a required empty response must fail without replacing the previous session state. Document that the empty-response helper retains the SSL_get_verify_result() semantics for an absent peer certificate: X509_V_OK does not establish authentication. The helper does not clear errors for supplied credentials. Remove two unused local pointer resets immediately before successful parse returns. No library verification-result behavior is changed. Validation: debug --strict-warnings build; test_sslapi, test_rpk, test_dtls and test_dtls13_internal all pass (no-fips). Assisted-by: Codex:gpt-6-astra Reviewed-by: Neil Horman <[email protected]> Reviewed-by: Matt Caswell <[email protected]> Reviewed-by: Tomas Mraz <[email protected]> Merge-date: Thu Oct 8 16:16:17 2026 Merged-from: https://github.com/openssl/openssl/pull/32638
* Keep pending client credentials out of cached sessionsMounir IDRASSI2026-10-081-0/+624
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The server retry-verification split in 95dcb1b719 introduced two regressions in client credential handling on master. The parse step stores a received client certificate chain or raw public key in SSL_SESSION before validation has finished. During (D)TLS 1.3 post-handshake authentication, that session may already be published in a server cache. A paused or failed attempt can then expose an unverified identity through an older stateful ticket and can mutate a shared session. The X.509 empty-response path also leaves the previous peer certificate installed. The state machine then expects CertificateVerify and rejects the legal Finished sent by the client. Keep the received credential on SSL_CONNECTION while validation is in progress. Once certificate-chain or RPK validation succeeds, duplicate the PHA session and install the accepted identity in that copy. An allowed empty Certificate now clears the previous client identity, verified chain, matched peer name, verification result, and DANE match state before the state machine chooses between Finished and CertificateVerify. Add coverage for paused validation with a retained cache-owned session, concurrent RPK resumption and rejection, and optional and required empty X.509 and RPK PHA responses, including connection-level DANE state. Fixes: 95dcb1b719a1 "Allow SSL_set_retry_verify() on server session" Assisted-by: Codex:gpt-5.6-sol Reviewed-by: Neil Horman <[email protected]> Reviewed-by: Matt Caswell <[email protected]> Reviewed-by: Tomas Mraz <[email protected]> Merge-date: Thu Oct 8 16:16:16 2026 Merged-from: https://github.com/openssl/openssl/pull/32638
* make c-style check in CI happy again.Alexandr Nedvedicky2026-10-071-2/+1
| | | | | | | | | | | Fixes: e91dd0082d86 "New implementation of stream reassembly for QUIC." Fixes: 3d70d094d1c3 "tests: test_dstorage_cleanse() and test_heap_overlap()" Reviewed-by: Matt Caswell <[email protected]> Reviewed-by: Kurt Roeckx <[email protected]> Reviewed-by: Eugene Syromiatnikov <[email protected]> Reviewed-by: Tomas Mraz <[email protected]> Merge-date: Wed Oct 7 15:39:21 2026 Merged-from: https://github.com/openssl/openssl/pull/33137