@@ -339,34 +339,59 @@ private static bool GetIsInContainer()
339339 return ( IsLinux && File . Exists ( "/.dockerenv" ) ) ;
340340 }
341341
342- private static bool GetSsl3Support ( )
342+ private static bool GetProtocolSupportFromWindowsRegistry ( SslProtocols protocol , bool defaultProtocolSupport )
343343 {
344- if ( IsWindows )
344+ string registryProtocolName = protocol switch
345345 {
346- string clientKey = @"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 3.0\Client" ;
347- string serverKey = @"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 3.0\Server" ;
346+ #pragma warning disable CS0618 // Ssl2 and Ssl3 are obsolete
347+ SslProtocols . Ssl3 => "SSL 3.0" ,
348+ #pragma warning restore CS0618
349+ SslProtocols . Tls => "TLS 1.0" ,
350+ SslProtocols . Tls11 => "TLS 1.1" ,
351+ SslProtocols . Tls12 => "TLS 1.2" ,
352+ #if ! NETFRAMEWORK
353+ SslProtocols . Tls13 => "TLS 1.3" ,
354+ #endif
355+ _ => throw new Exception ( $ "Registry key not defined for { protocol } .")
356+ } ;
348357
349- object client , server ;
350- try
351- {
352- client = Registry . GetValue ( clientKey , "Enabled" , null ) ;
353- server = Registry . GetValue ( serverKey , "Enabled" , null ) ;
354- }
355- catch ( SecurityException )
356- {
357- // Insufficient permission, assume that we don't have SSL3 (since we aren't exactly sure)
358- return false ;
359- }
358+ string clientKey = @$ "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\{ registryProtocolName } \Client";
359+ string serverKey = @$ "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\{ registryProtocolName } \Server";
360360
361+ object client , server ;
362+ try
363+ {
364+ client = Registry . GetValue ( clientKey , "Enabled" , defaultProtocolSupport ? 1 : 0 ) ;
365+ server = Registry . GetValue ( serverKey , "Enabled" , defaultProtocolSupport ? 1 : 0 ) ;
361366 if ( client is int c && server is int s )
362367 {
363368 return c == 1 && s == 1 ;
364369 }
370+ }
371+ catch ( SecurityException )
372+ {
373+ // Insufficient permission, assume that we don't have protocol support (since we aren't exactly sure)
374+ return false ;
375+ }
376+ catch { }
377+
378+ return defaultProtocolSupport ;
379+ }
380+
381+ private static bool GetSsl3Support ( )
382+ {
383+ if ( IsWindows )
384+ {
365385
366386 // Missing key. If we're pre-20H1 then assume SSL3 is enabled.
367387 // Otherwise, disabled. (See comments on https://github.com/dotnet/runtime/issues/1166)
368388 // Alternatively the returned values must have been some other types.
369- return ! IsWindows10Version2004OrGreater ;
389+ bool ssl3DefaultSupport = ! IsWindows10Version2004OrGreater ;
390+
391+ #pragma warning disable CS0618 // Ssl2 and Ssl3 are obsolete
392+ return GetProtocolSupportFromWindowsRegistry ( SslProtocols . Ssl3 , ssl3DefaultSupport ) ;
393+ #pragma warning restore CS0618
394+
370395 }
371396
372397 return ( IsOSX || ( IsLinux && OpenSslVersion < new Version ( 1 , 0 , 2 ) && ! IsDebian ) ) ;
@@ -390,21 +415,26 @@ private static bool AndroidGetSslProtocolSupport(SslProtocols protocol)
390415 private static bool GetTls10Support ( )
391416 {
392417 // on Windows, macOS, and Android TLS1.0/1.1 are supported.
393- if ( IsWindows || IsOSXLike || IsAndroid )
418+ if ( IsOSXLike || IsAndroid )
394419 {
395420 return true ;
421+ }
422+ if ( IsWindows )
423+ {
424+ return GetProtocolSupportFromWindowsRegistry ( SslProtocols . Tls , true ) ;
396425 }
397426
398427 return OpenSslGetTlsSupport ( SslProtocols . Tls ) ;
399428 }
400429
401430 private static bool GetTls11Support ( )
402431 {
403- // on Windows, macOS, and Android TLS1.0/1.1 are supported.
404- // TLS 1.1 and 1.2 can work on Windows7 but it is not enabled by default.
432+ // on Windows, macOS, and Android TLS1.0/1.1 are supported.
405433 if ( IsWindows )
406434 {
407- return ! IsWindows7 ;
435+ // TLS 1.1 and 1.2 can work on Windows7 but it is not enabled by default.
436+ bool defaultProtocolSupport = ! IsWindows7 ;
437+ return GetProtocolSupportFromWindowsRegistry ( SslProtocols . Tls11 , defaultProtocolSupport ) ;
408438 }
409439 else if ( IsOSXLike || IsAndroid )
410440 {
@@ -417,7 +447,8 @@ private static bool GetTls11Support()
417447 private static bool GetTls12Support ( )
418448 {
419449 // TLS 1.1 and 1.2 can work on Windows7 but it is not enabled by default.
420- return ! IsWindows7 ;
450+ bool defaultProtocolSupport = ! IsWindows7 ;
451+ return GetProtocolSupportFromWindowsRegistry ( SslProtocols . Tls12 , defaultProtocolSupport ) ;
421452 }
422453
423454 private static bool GetTls13Support ( )
@@ -428,25 +459,17 @@ private static bool GetTls13Support()
428459 {
429460 return false ;
430461 }
431-
432- string clientKey = @"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.3\Client" ;
433- string serverKey = @"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.3\Server" ;
434-
435- object client , server ;
436- try
437- {
438- client = Registry . GetValue ( clientKey , "Enabled" , null ) ;
439- server = Registry . GetValue ( serverKey , "Enabled" , null ) ;
440- if ( client is int c && server is int s )
441- {
442- return c == 1 && s == 1 ;
443- }
444- }
445- catch { }
446462 // assume no if positive entry is missing on older Windows
447463 // Latest insider builds have TLS 1.3 enabled by default.
448464 // The build number is approximation.
449- return IsWindows10Version2004Build19573OrGreater ;
465+ bool defaultProtocolSupport = IsWindows10Version2004Build19573OrGreater ;
466+
467+ #if NETFRAMEWORK
468+ return false ;
469+ #else
470+ return GetProtocolSupportFromWindowsRegistry ( SslProtocols . Tls13 , defaultProtocolSupport ) ;
471+ #endif
472+
450473 }
451474 else if ( IsOSX || IsMacCatalyst || IsiOS || IstvOS )
452475 {
0 commit comments