Skip to content

Conversation

rzikm
Copy link
Member

@rzikm rzikm commented Jul 15, 2025

There are two instances where SslStream will abandon X509Certificate2 instances to finalizer to deal with:

  • any intermediate certificates received from the peer over the wire (those which end up in ExtraStore on the X509ChainPolicy)
  • any certificate handles that are created when internally creating the SslStreamCertificateContext (like intermediate cert handles), if we create the context internally, we can ensure proper cleanup when disposing SslStream.

As a result, HttpClient.GetAsync to a mTLS-enabled server does not produce any hanging cert handles (as per DEBUG_SAFEX509HANDLE_FINALIZATION-enabled logs)

SslStreamCertificateContext seems like it would benefit from IDisposeable, but it is too late for that in .NET 10.

@Copilot Copilot AI review requested due to automatic review settings July 15, 2025 16:08
@rzikm
Copy link
Member Author

rzikm commented Jul 15, 2025

/azp run runtime-libraries-coreclr outerloop

Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@rzikm rzikm requested review from wfurt and bartonjs July 15, 2025 16:20
Copilot

This comment was marked as outdated.

@wfurt
Copy link
Member

wfurt commented Jul 15, 2025

SslStreamCertificateContext seems like it would benefit from IDisposeable, but it is too late for that in .NET 10.

We talk about it with @bartonjs while back. As we added more things to it, I do agree that ability to manage the life cycle explicitly would be beneficial.

@liveans liveans requested a review from Copilot July 16, 2025 13:56
Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR ensures that intermediate certificates and internal certificate handles used by SslStream are explicitly disposed instead of relying on finalization. It introduces new disposal methods in the certificate context classes, updates authentication option patterns to track and clean up owned contexts, and refactors protocol logic to handle certificate context updates and cleanup consistently. Test changes attempt to verify that user certificates remain valid post-disposal.

Reviewed Changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamMutualAuthenticationTest.cs Added assertions for certificate handle validity and updated lambda closing syntax in several tests.
src/libraries/System.Net.Security/src/System/Net/Security/SslStreamCertificateContext.cs Added ReleaseResources to dispose intermediate certificates and invoke platform-specific cleanup.
src/libraries/System.Net.Security/src/System/Net/Security/SslStreamCertificateContext.Windows.cs Introduced DisposeChainElements to clean up chain certificates after chain-building failures.
src/libraries/System.Net.Security/src/System/Net/Security/SslStreamCertificateContext.Linux.cs Implemented ReleasePlatformSpecificResources disposing native handles and private intermediate certificates.
src/libraries/System.Net.Security/src/System/Net/Security/SslStream.Protocol.cs Refactored credential acquisition to use a local UpdateCertificateContext helper and added disposal of extra chain certificates after validation.
src/libraries/System.Net.Security/src/System/Net/Security/SslAuthenticationOptions.cs Made SslAuthenticationOptions implement IDisposable, added SetCertificateContextFromCert, and wired up proper disposal logic.
Comments suppressed due to low confidence (2)

src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamMutualAuthenticationTest.cs:118

  • The comment and subsequent assertions only check the user certificates, not any intermediate certificates received over the wire. To validate that intermediate certs aren’t prematurely disposed, add assertions on those intermediate cert handles or inspect the chain stored in ExtraStore.
            // Assert that the certificates are not being disposed

src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamMutualAuthenticationTest.cs:159

  • [nitpick] Splitting the lambda closing }; into separate } and ; lines reduces readability. Combine them on a single line (};) to match common C# style for block lambdas.
                }

@rzikm rzikm merged commit 901395a into dotnet:main Jul 18, 2025
85 of 87 checks passed
@github-actions github-actions bot locked and limited conversation to collaborators Aug 17, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants