11using System . Net ;
22using System . Net . Security ;
3+ using System . Security . Authentication ;
34using System . Security . Cryptography . X509Certificates ;
45using Microsoft . AspNetCore . Authentication . Certificate ;
6+ using Microsoft . AspNetCore . Connections . Features ;
7+ using Microsoft . AspNetCore . Http . Features ;
58using Microsoft . AspNetCore . Server . HttpSys ;
69using Microsoft . AspNetCore . Server . Kestrel . Core ;
710using Microsoft . AspNetCore . Server . Kestrel . Https ;
811
912var builder = WebApplication . CreateBuilder ( args ) ;
1013builder . Logging . ClearProviders ( ) ;
1114
12- var writeCertValidationEventsToConsole = bool . TryParse ( builder . Configuration [ "certValidationConsoleEnabled" ] , out var certValidationConsoleEnabled ) && certValidationConsoleEnabled ;
15+ // behavioral
1316var mTlsEnabled = bool . TryParse ( builder . Configuration [ "mTLS" ] , out var mTlsEnabledConfig ) && mTlsEnabledConfig ;
1417var tlsRenegotiationEnabled = bool . TryParse ( builder . Configuration [ "tlsRenegotiation" ] , out var tlsRenegotiationEnabledConfig ) && tlsRenegotiationEnabledConfig ;
15- var statsEnabled = bool . TryParse ( builder . Configuration [ "statsEnabled" ] , out var connectionStatsEnabledConfig ) && connectionStatsEnabledConfig ;
1618var listeningEndpoints = builder . Configuration [ "urls" ] ?? "https://localhost:5000/" ;
19+ var supportedTlsVersions = ParseSslProtocols ( builder . Configuration [ "tlsProtocols" ] ) ;
20+
21+ // debug
22+ var writeCertValidationEventsToConsole = bool . TryParse ( builder . Configuration [ "certValidationConsoleEnabled" ] , out var certValidationConsoleEnabled ) && certValidationConsoleEnabled ;
23+ var statsEnabled = bool . TryParse ( builder . Configuration [ "statsEnabled" ] , out var connectionStatsEnabledConfig ) && connectionStatsEnabledConfig ;
24+ var logRequestDetails = bool . TryParse ( builder . Configuration [ "logRequestDetails" ] , out var logRequestDetailsConfig ) && logRequestDetailsConfig ;
1725
1826if ( mTlsEnabled && tlsRenegotiationEnabled )
1927{
@@ -40,6 +48,11 @@ void ConfigureListen(KestrelServerOptions serverOptions, IConfigurationRoot conf
4048 // [SuppressMessage("Microsoft.Security", "CSCAN0220.DefaultPasswordContexts", Justification="Benchmark code, not a secret")]
4149 listenOptions . UseHttps ( "testCert.pfx" , "testPassword" , options =>
4250 {
51+ if ( supportedTlsVersions is not null )
52+ {
53+ options . SslProtocols = supportedTlsVersions . Value ;
54+ }
55+
4356 if ( mTlsEnabled )
4457 {
4558 options . ClientCertificateMode = ClientCertificateMode . RequireCertificate ;
@@ -81,6 +94,28 @@ bool AllowAnyCertificateValidationWithLogging(X509Certificate2 certificate, X509
8194 return true ;
8295}
8396
97+ if ( logRequestDetails )
98+ {
99+ var logged = false ;
100+ Console . WriteLine ( "Registered request details logging middleware" ) ;
101+ app . Use ( async ( context , next ) =>
102+ {
103+ if ( ! logged )
104+ {
105+ logged = true ;
106+
107+ var tlsHandshakeFeature = context . Features . GetRequiredFeature < ITlsHandshakeFeature > ( ) ;
108+
109+ Console . WriteLine ( "Request details:" ) ;
110+ Console . WriteLine ( "-----" ) ;
111+ Console . WriteLine ( "TLS: " + tlsHandshakeFeature . Protocol ) ;
112+ Console . WriteLine ( "-----" ) ;
113+ }
114+
115+ await next ( context ) ;
116+ } ) ;
117+ }
118+
84119if ( statsEnabled )
85120{
86121 Console . WriteLine ( "Registered stats middleware" ) ;
@@ -89,7 +124,7 @@ bool AllowAnyCertificateValidationWithLogging(X509Certificate2 certificate, X509
89124 connectionIds . Add ( context . Connection . Id ) ;
90125 Console . WriteLine ( $ "[stats] unique connections established: { connectionIds . Count } ; fetched certificates: { fetchedCertsCounter } ") ;
91126
92- await next ( ) ;
127+ await next ( context ) ;
93128 } ) ;
94129}
95130
@@ -109,7 +144,7 @@ bool AllowAnyCertificateValidationWithLogging(X509Certificate2 certificate, X509
109144 Console . WriteLine ( $ "client certificate ({ clientCert . Thumbprint } ) already exists on the connection { context . Connection . Id } ") ;
110145 }
111146
112- await next ( ) ;
147+ await next ( context ) ;
113148 } ) ;
114149}
115150
@@ -137,6 +172,7 @@ bool AllowAnyCertificateValidationWithLogging(X509Certificate2 certificate, X509
137172{
138173 Console . WriteLine ( $ "\t enabled logging stats to console") ;
139174}
175+ Console . WriteLine ( $ "\t supported TLS versions: { supportedTlsVersions } ") ;
140176Console . WriteLine ( $ "\t listening endpoints: { listeningEndpoints } ") ;
141177Console . WriteLine ( "--------------------------------" ) ;
142178
@@ -157,4 +193,30 @@ static IPEndPoint CreateIPEndPoint(UrlPrefix urlPrefix)
157193 }
158194
159195 return new IPEndPoint ( ip , urlPrefix . PortValue ) ;
196+ }
197+
198+ static SslProtocols ? ParseSslProtocols ( string ? supportedTlsVersions )
199+ {
200+ var protocols = SslProtocols . None ;
201+ if ( string . IsNullOrEmpty ( supportedTlsVersions ) || supportedTlsVersions == "any" )
202+ {
203+ return null ;
204+ }
205+
206+ foreach ( var version in supportedTlsVersions . Split ( ',' ) )
207+ {
208+ switch ( version . Trim ( ) . ToLower ( ) )
209+ {
210+ case "tls12" :
211+ protocols |= SslProtocols . Tls12 ;
212+ break ;
213+ case "tls13" :
214+ protocols |= SslProtocols . Tls13 ;
215+ break ;
216+ default :
217+ throw new ArgumentException ( $ "Unsupported TLS version: { version } ") ;
218+ }
219+ }
220+
221+ return protocols ;
160222}
0 commit comments