@@ -339,34 +339,59 @@ private static bool GetIsInContainer()
339
339
return ( IsLinux && File . Exists ( "/.dockerenv" ) ) ;
340
340
}
341
341
342
- private static bool GetSsl3Support ( )
342
+ private static bool GetProtocolSupportFromWindowsRegistry ( SslProtocols protocol , bool defaultProtocolSupport )
343
343
{
344
- if ( IsWindows )
344
+ string registryProtocolName = protocol switch
345
345
{
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
+ } ;
348
357
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";
360
360
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 ) ;
361
366
if ( client is int c && server is int s )
362
367
{
363
368
return c == 1 && s == 1 ;
364
369
}
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
+ {
365
385
366
386
// Missing key. If we're pre-20H1 then assume SSL3 is enabled.
367
387
// Otherwise, disabled. (See comments on https://github.com/dotnet/runtime/issues/1166)
368
388
// 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
+
370
395
}
371
396
372
397
return ( IsOSX || ( IsLinux && OpenSslVersion < new Version ( 1 , 0 , 2 ) && ! IsDebian ) ) ;
@@ -390,21 +415,26 @@ private static bool AndroidGetSslProtocolSupport(SslProtocols protocol)
390
415
private static bool GetTls10Support ( )
391
416
{
392
417
// on Windows, macOS, and Android TLS1.0/1.1 are supported.
393
- if ( IsWindows || IsOSXLike || IsAndroid )
418
+ if ( IsOSXLike || IsAndroid )
394
419
{
395
420
return true ;
421
+ }
422
+ if ( IsWindows )
423
+ {
424
+ return GetProtocolSupportFromWindowsRegistry ( SslProtocols . Tls , true ) ;
396
425
}
397
426
398
427
return OpenSslGetTlsSupport ( SslProtocols . Tls ) ;
399
428
}
400
429
401
430
private static bool GetTls11Support ( )
402
431
{
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.
405
433
if ( IsWindows )
406
434
{
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 ) ;
408
438
}
409
439
else if ( IsOSXLike || IsAndroid )
410
440
{
@@ -417,7 +447,8 @@ private static bool GetTls11Support()
417
447
private static bool GetTls12Support ( )
418
448
{
419
449
// 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 ) ;
421
452
}
422
453
423
454
private static bool GetTls13Support ( )
@@ -428,25 +459,17 @@ private static bool GetTls13Support()
428
459
{
429
460
return false ;
430
461
}
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 { }
446
462
// assume no if positive entry is missing on older Windows
447
463
// Latest insider builds have TLS 1.3 enabled by default.
448
464
// 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
+
450
473
}
451
474
else if ( IsOSX || IsMacCatalyst || IsiOS || IstvOS )
452
475
{
0 commit comments