@@ -123,6 +123,42 @@ void ConfigureListenOptions(ListenOptions listenOptions)
123123 }
124124 }
125125
126+ [ Fact ]
127+ public async Task HandshakeDetailsAreAvailableAfterAsyncCallback ( )
128+ {
129+ void ConfigureListenOptions ( ListenOptions listenOptions )
130+ {
131+ listenOptions . UseHttps ( async ( stream , clientHelloInfo , state , cancellationToken ) =>
132+ {
133+ await Task . Yield ( ) ;
134+
135+ return new SslServerAuthenticationOptions
136+ {
137+ ServerCertificate = _x509Certificate2 ,
138+ } ;
139+ } , state : null ) ;
140+ }
141+
142+ await using ( var server = new TestServer ( context =>
143+ {
144+ var tlsFeature = context . Features . Get < ITlsHandshakeFeature > ( ) ;
145+ Assert . NotNull ( tlsFeature ) ;
146+ Assert . True ( tlsFeature . Protocol > SslProtocols . None , "Protocol" ) ;
147+ Assert . True ( tlsFeature . CipherAlgorithm > CipherAlgorithmType . Null , "Cipher" ) ;
148+ Assert . True ( tlsFeature . CipherStrength > 0 , "CipherStrength" ) ;
149+ Assert . True ( tlsFeature . HashAlgorithm >= HashAlgorithmType . None , "HashAlgorithm" ) ; // May be None on Linux.
150+ Assert . True ( tlsFeature . HashStrength >= 0 , "HashStrength" ) ; // May be 0 for some algorithms
151+ Assert . True ( tlsFeature . KeyExchangeAlgorithm >= ExchangeAlgorithmType . None , "KeyExchangeAlgorithm" ) ; // Maybe None on Windows 7
152+ Assert . True ( tlsFeature . KeyExchangeStrength >= 0 , "KeyExchangeStrength" ) ; // May be 0 on mac
153+
154+ return context . Response . WriteAsync ( "hello world" ) ;
155+ } , new TestServiceContext ( LoggerFactory ) , ConfigureListenOptions ) )
156+ {
157+ var result = await server . HttpClientSlim . GetStringAsync ( $ "https://localhost:{ server . Port } /", validateCertificate : false ) ;
158+ Assert . Equal ( "hello world" , result ) ;
159+ }
160+ }
161+
126162 [ Fact ]
127163 public async Task RequireCertificateFailsWhenNoCertificate ( )
128164 {
@@ -166,22 +202,18 @@ void ConfigureListenOptions(ListenOptions listenOptions)
166202 }
167203
168204 [ Fact ]
169- [ QuarantinedTest ( "https://github.com/dotnet/runtime/issues/40402" ) ]
170- public async Task ClientCertificateRequiredConfiguredInCallbackContinuesWhenNoCertificate ( )
205+ public async Task AsyncCallbackSettingClientCertificateRequiredContinuesWhenNoCertificate ( )
171206 {
172207 void ConfigureListenOptions ( ListenOptions listenOptions )
173208 {
174- listenOptions . UseHttps ( ( connection , stream , clientHelloInfo , state , cancellationToken ) =>
209+ listenOptions . UseHttps ( ( stream , clientHelloInfo , state , cancellationToken ) =>
175210 new ValueTask < SslServerAuthenticationOptions > ( new SslServerAuthenticationOptions
176211 {
177212 ServerCertificate = _x509Certificate2 ,
178- // From the API Docs: "Note that this is only a request --
179- // if no certificate is provided, the server still accepts the connection request."
180- // Not to mention this is equivalent to the test above.
181213 ClientCertificateRequired = true ,
182214 RemoteCertificateValidationCallback = ( sender , certificate , chain , sslPolicyErrors ) => true ,
183215 CertificateRevocationCheckMode = X509RevocationMode . NoCheck
184- } ) , state : null , HttpsConnectionAdapterOptions . DefaultHandshakeTimeout ) ;
216+ } ) , state : null ) ;
185217 }
186218
187219 await using ( var server = new TestServer ( context =>
@@ -255,6 +287,39 @@ void ConfigureListenOptions(ListenOptions listenOptions)
255287 }
256288 }
257289
290+ [ Fact ]
291+ public async Task UsesProvidedAsyncCallback ( )
292+ {
293+ var selectorCalled = 0 ;
294+ void ConfigureListenOptions ( ListenOptions listenOptions )
295+ {
296+ listenOptions . UseHttps ( async ( stream , clientHelloInfo , state , cancellationToken ) =>
297+ {
298+ await Task . Yield ( ) ;
299+
300+ Assert . NotNull ( stream ) ;
301+ Assert . Equal ( "localhost" , clientHelloInfo . ServerName ) ;
302+ selectorCalled ++ ;
303+
304+ return new SslServerAuthenticationOptions
305+ {
306+ ServerCertificate = _x509Certificate2
307+ } ;
308+ } , state : null ) ;
309+ }
310+
311+ await using ( var server = new TestServer ( context => Task . CompletedTask , new TestServiceContext ( LoggerFactory ) , ConfigureListenOptions ) )
312+ {
313+ using ( var connection = server . CreateConnection ( ) )
314+ {
315+ var stream = OpenSslStream ( connection . Stream ) ;
316+ await stream . AuthenticateAsClientAsync ( "localhost" ) ;
317+ Assert . True ( stream . RemoteCertificate . Equals ( _x509Certificate2 ) ) ;
318+ Assert . Equal ( 1 , selectorCalled ) ;
319+ }
320+ }
321+ }
322+
258323 [ Fact ]
259324 public async Task UsesProvidedServerCertificateSelectorEachTime ( )
260325 {
0 commit comments