Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -467,6 +467,12 @@ private async ValueTask<int> ReceiveHandshakeFrameAsync<TIOAdapter>(Cancellation
options |= TlsFrameHelper.ProcessingOptions.RawApplicationProtocol;
}

if (_sslAuthenticationOptions.ServerOptionDelegate != null)
{
// We need to process supported versions extension to pass it to user callback.
options |= TlsFrameHelper.ProcessingOptions.Versions;
Comment thread
wfurt marked this conversation as resolved.
Comment thread
wfurt marked this conversation as resolved.
}

// Process SNI from Client Hello message
if (!TlsFrameHelper.TryGetFrameInfo(_buffer.EncryptedReadOnlySpan, ref _lastFrame, options))
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,44 @@ public async Task ServerAsyncAuthenticate_SniSetVersion_Success(SslProtocols ver
}
}

[ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.SupportsTls13))]
public async Task ServerAsyncAuthenticate_SniCallback_ReceivesSupportedVersionsFromExtension()
{
// Regression test: ensure that when a ServerOptionDelegate (SNI callback) is used,
// the supported_versions extension from the ClientHello is parsed and exposed via
// SslClientHelloInfo.SslProtocols. TLS 1.3 advertises its version only via that
// extension (the record-layer / legacy_version field still reports TLS 1.2), so
// without parsing the extension the callback would not see Tls13.
var serverOptions = new SslServerAuthenticationOptions() { ServerCertificate = _serverCertificate, EnabledSslProtocols = SslProtocols.Tls13 };
var clientOptions = new SslClientAuthenticationOptions()
{
TargetHost = _serverCertificate.GetNameInfo(X509NameType.SimpleName, forIssuer: false),
EnabledSslProtocols = SslProtocols.Tls13,
};
clientOptions.RemoteCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true;

SslProtocols observedProtocols = SslProtocols.None;

(SslStream client, SslStream server) = TestHelper.GetConnectedSslStreams();
using (client)
using (server)
{
Task t1 = client.AuthenticateAsClientAsync(clientOptions, CancellationToken.None);
Task t2 = server.AuthenticateAsServerAsync(
(stream, clientHelloInfo, userState, cancellationToken) =>
{
observedProtocols = clientHelloInfo.SslProtocols;
return new ValueTask<SslServerAuthenticationOptions>(serverOptions);
},
null, CancellationToken.None);

await TestConfiguration.WhenAllOrAnyFailedWithTimeout(t1, t2);
}

Assert.True((observedProtocols & SslProtocols.Tls13) == SslProtocols.Tls13,
$"Expected SslClientHelloInfo.SslProtocols to include Tls13, got '{observedProtocols}'.");
Comment thread
wfurt marked this conversation as resolved.
}

private async Task<SslServerAuthenticationOptions> FailedTask()
{
await Task.Yield();
Expand Down
Loading