Repository navigation
Return Complete from RequestClientCertificate when the client didn't offer post-handshake auth - #135049
Merged
Conversation
RequestClientCertificateBufferedCore threw AuthenticationException for any failed token, including NoRenegotiation, which the OpenSSL and SChannel PALs report when a TLS 1.3 client didn't offer post-handshake authentication. This affected TlsBufferSession and, on Windows, TlsSocketSession. On NoRenegotiation, stage nothing and return Complete. Update the RequestClientCertificate docs to describe that TLS 1.3 case on both session types and to cover TLS 1.2 renegotiation. Fix dotnet#135047 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Azure Pipelines: Successfully started running 4 pipeline(s). 12 pipeline(s) were filtered out due to trigger conditions. There may be pipelines that require an authorized user to comment /azp run to run. |
Contributor
|
Tagging subscribers to this area: @dotnet/ncl, @bartonjs, @vcsjones |
This was referenced Oct 2, 2026
Open
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
RequestClientCertificateBufferedCorethrowsAuthenticationExceptionfor any failed token. When a TLS 1.3 client didn't offer post-handshake authentication, both PALs reportNoRenegotiation(OpenSSL failsSSL_verify_client_post_handshakewithSSL_R_EXTENSION_NOT_RECEIVED, SChannel returnsSECURITY_STATUS.NoRenegotiation), so the method throws before reaching its own!stagedbranch, whose comment says such a decline returnsComplete. This affectsTlsBufferSession.RequestClientCertificateand, on Windows,TlsSocketSession.RequestClientCertificate, which runs the buffered core there.SslStream.NegotiateClientCertificateAsyncand the Linux socket-bound path (TryFastRequestClientCertificate) already return.Change. On
NoRenegotiation, nothing is staged, the session stays in its completed state, and the method returnsCompletewith nothing written. Any other failed status still throws.Docs.
TlsBufferSession.RequestClientCertificategets the remarkTlsSocketSession.RequestClientCertificatealready has about the decline, and that remark loses "On Linux". Both summaries described the method as TLS 1.3 post-handshake authentication only, andTlsBufferSession'sInvalidOperationExceptionentry listed "the current session is not TLS 1.3". The buffered core has no protocol check, and on TLS 1.2 the method starts a renegotiation:ServerSession_RequestClientCertificate_Tls12_ProducesHandshakeBytesand theTls12rows of both..._RequestClientCertificate_DrivesSecondHandshakeToCompletiontests pass on Linux and Windows. The summaries now name both protocols, and the TLS 1.3 condition is dropped from the exception entry.TLS 1.2.
NoRenegotiationalso comes back when renegotiation is disabled locally by an OpenSSL configuration withOptions = NoRenegotiation, which makesSSL_renegotiatefail withSSL_R_NO_RENEGOTIATION. There the method now returnsCompletewith nothing written instead of throwing, asSslStream.NegotiateClientCertificateAsyncalready does. Checked on Linux x64 with OpenSSL 3.0.2 and 1.1.1f throughOPENSSL_CONF.Tests
TlsSessionTests.ServerSession_RequestClientCertificate_Tls13PhaNotOffered_Completes, the buffered counterpart ofSocketBoundSession_RequestClientCertificate_Tls13PhaNotOffered_Completesand Linux-only like it: anSslStreamclient without a certificate, which on Linux doesn't offer post-handshake authentication, thenRequestClientCertificatemust returnCompletewith 0 bytes written, the handshake must stay complete with no remote certificate, and data must flow both ways. Without the change it fails on OpenSSL 3.0.2 withAuthenticationException(innererror:0A000117:SSL routines::extension not received); with it, it passes on 3.0.2 and 1.1.1f.SslStreamclient offers post-handshake authentication even without a certificate, so the decline was produced withopenssl s_client3.5.7 without-enable_pha. With the changeTlsBufferSessionandTlsSocketSessionreturnCompleteand still deliver data to the client; without itTlsBufferSessionthrowsAuthenticationException(innerWin32Exception: "The recipient rejected the renegotiation request.").System.Net.Security.Testscompared by test name with and without the change: on Linux (OpenSSL 3.0.2) identical apart from the new test, withNegotiateAuthenticationKerberosTestfailing in both runs; on Windows 11 identical.Resolves #135047
Note
AI-generated, written at my direction and reviewed by me before posting. The tests ran on local builds of
mainat 12955c8, with and without this commit:clr+libs -rc release -lc releaseon Ubuntu 22.04 x64, where each run's test process memory map was checked for thelibsslit loaded, andclr+libs -rc releaseon Windows 11 x64. Thes_clientchecks ran the repro from the linked issue, and a larger scratch app forTlsSocketSession, on the Windows build. The TLS 1.2 check ran a scratch app with anOPENSSL_CONFfile on the Linux build.