@@ -570,6 +570,49 @@ void ConfigureListenOptions(ListenOptions listenOptions)
570
570
await AssertConnectionResult ( stream , true ) ;
571
571
}
572
572
573
+ [ ConditionalFact ]
574
+ [ TlsAlpnSupported ]
575
+ [ OSSkipCondition ( OperatingSystems . Windows | OperatingSystems . Linux , SkipReason = "MacOS only test." ) ]
576
+ public async Task CanRenegotiateForClientCertificate_MacOS_PlatformNotSupportedException ( )
577
+ {
578
+ void ConfigureListenOptions ( ListenOptions listenOptions )
579
+ {
580
+ listenOptions . Protocols = HttpProtocols . Http1 ;
581
+ listenOptions . UseHttps ( options =>
582
+ {
583
+ options . ServerCertificate = _x509Certificate2 ;
584
+ options . ClientCertificateMode = ClientCertificateMode . DelayCertificate ;
585
+ options . AllowAnyClientCertificate ( ) ;
586
+ } ) ;
587
+ }
588
+
589
+ await using var server = new TestServer ( async context =>
590
+ {
591
+ var tlsFeature = context . Features . Get < ITlsConnectionFeature > ( ) ;
592
+ Assert . NotNull ( tlsFeature ) ;
593
+ Assert . Null ( tlsFeature . ClientCertificate ) ;
594
+ Assert . Null ( context . Connection . ClientCertificate ) ;
595
+
596
+ await Assert . ThrowsAsync < PlatformNotSupportedException > ( ( ) => context . Connection . GetClientCertificateAsync ( ) ) ;
597
+
598
+ var lifetimeNotificationFeature = context . Features . Get < IConnectionLifetimeNotificationFeature > ( ) ;
599
+ Assert . False (
600
+ lifetimeNotificationFeature . ConnectionClosedRequested . IsCancellationRequested ,
601
+ "GetClientCertificateAsync shouldn't cause the connection to be closed." ) ;
602
+
603
+ await context . Response . WriteAsync ( "hello world" ) ;
604
+ } , new TestServiceContext ( LoggerFactory ) , ConfigureListenOptions ) ;
605
+
606
+ using var connection = server . CreateConnection ( ) ;
607
+ // SslStream is used to ensure the certificate is actually passed to the server
608
+ // HttpClient might not send the certificate because it is invalid or it doesn't match any
609
+ // of the certificate authorities sent by the server in the SSL handshake.
610
+ // Use a random host name to avoid the TLS session resumption cache.
611
+ var stream = OpenSslStreamWithCert ( connection . Stream ) ;
612
+ await stream . AuthenticateAsClientAsync ( Guid . NewGuid ( ) . ToString ( ) ) ;
613
+ await AssertConnectionResult ( stream , true ) ;
614
+ }
615
+
573
616
[ Fact ]
574
617
public async Task Renegotiate_ServerOptionsSelectionCallback_NotSupported ( )
575
618
{
0 commit comments