Skip to content

[Breaking change]: SslStream does not revalidate peer certificates on resumed TLS sessions #56298

Description

@rzikm

Description

Starting in .NET 11, SslStream does not revalidate the peer certificate during a resumed initial TLS handshake when the platform can reliably detect TLS session resumption. The peer certificate from the original full handshake remains available through SslStream.RemoteCertificate, but SslStream does not rebuild the certificate chain or invoke the configured remote-certificate validation callback for the resumed handshake.

This affects resumed initial handshakes on Windows and Linux. On Apple platforms and Android, where the underlying TLS backend does not provide a reliable resumption signal, certificate validation continues to run for resumed connections.

For more information, see dotnet/runtime#133174.

Version

.NET 12 preview 1

Previous behavior

SslStream rebuilt the peer certificate chain and invoked RemoteCertificateValidationCallback for every successful handshake, including a resumed TLS session.

New behavior

On Windows and Linux, a resumed initial TLS handshake does not invoke the remote-certificate validation callback or rebuild the certificate chain by default. The callback still runs during the original full handshake that establishes the resumable session.

The shortcut applies only to the initial resumed handshake. Renegotiation and TLS 1.3 post-handshake authentication continue to fully validate a newly presented peer certificate.

Type of breaking change

  • Binary incompatible: Existing binaries might encounter a breaking change in behavior, such as failure to load or execute, and if so, require recompilation.
  • Source incompatible: When recompiled using the new SDK or component or to target the new runtime, existing source code might require source changes to compile successfully.
  • Behavioral change: Existing binaries might behave differently at run time.

Reason for change

In a resumed, abbreviated TLS handshake, the peer does not resend its certificate. Its identity was established and validated in the original full handshake that created the session ticket or session ID. Skipping repeated managed certificate-chain construction and callback invocation aligns SslStream with common TLS implementations and reduces the work and allocations of resumed handshakes.

Recommended action

Do not rely on RemoteCertificateValidationCallback as a per-connection notification for resumed TLS sessions. Perform any authorization or connection-specific checks independently of that callback.

If an application requires the previous behavior, enable the System.Net.Security.RevalidateCertificateOnTlsResume AppContext switch:

AppContext.SetSwitch(
    "System.Net.Security.RevalidateCertificateOnTlsResume",
    isEnabled: true);

Alternatively, set the DOTNET_SYSTEM_NET_SECURITY_REVALIDATECERTIFICATEONTLSRESUME environment variable to 1 before the process starts. With either setting, SslStream rebuilds the chain and invokes the remote-certificate validation callback on resumed handshakes as in earlier versions.

Another alternative is disabling TLS resumption via AllowTlsResume on the authentication options classes.

Feature area

Networking

Affected APIs

  • System.Net.Security.SslStream.AuthenticateAsClient, AuthenticateAsClientAsync, AuthenticateAsServer, and AuthenticateAsServerAsync (all overloads when the supplied authentication options configure remote certificate validation).
  • System.Net.Security.SslClientAuthenticationOptions.RemoteCertificateValidationCallback.
  • System.Net.Security.SslServerAuthenticationOptions.RemoteCertificateValidationCallback.
  • System.Net.Security.SslStream.RemoteCertificate remains populated with the certificate cached from the original full handshake.

Note

This issue was generated by GitHub Copilot.

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions