@@ -7,17 +7,25 @@ namespace HttpSys;
77[ System . Diagnostics . CodeAnalysis . SuppressMessage ( "Interoperability" , "CA1416:Validate platform compatibility" , Justification = "benchmark only runs on windows" ) ]
88public static class RegistryController
99{
10- private const string TLS12Key = @"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Server" ;
11- private const string TLS13Key = @"SYSTEM\CurrentControlSet\Services\HTTP\Parameters" ;
10+ // see https://learn.microsoft.com/en-us/windows-server/security/tls/tls-registry-settings?tabs=diffie-hellman
11+ private const string TLS12SubKey = @"SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Server" ;
12+ private const string TLS13SubKey = @"SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.3\Server" ;
13+
14+ private static RegistryKey RootRegistryKey => Environment . Is64BitOperatingSystem
15+ ? RegistryKey . OpenBaseKey ( RegistryHive . LocalMachine , RegistryView . Registry64 )
16+ : RegistryKey . OpenBaseKey ( RegistryHive . LocalMachine , RegistryView . Registry32 ) ;
1217
1318 public static void ShowRegistryKeys ( )
1419 {
15- var tls12Enabled = GetRegistryValue ( TLS12Key , "" ) ;
16- var tls13Enabled = GetRegistryValue ( TLS13Key , "EnableHTTP3" ) ;
20+ var tls12DisabledByDefault = GetRegistryValue ( TLS12SubKey , "DisabledByDefault" ) ;
21+ var tls12Enabled = GetRegistryValue ( TLS12SubKey , "Enabled" ) ;
22+
23+ var tls13DisabledByDefault = GetRegistryValue ( TLS13SubKey , "DisabledByDefault" ) ;
24+ var tls13Enabled = GetRegistryValue ( TLS13SubKey , "Enabled" ) ;
1725
1826 var strBuilder = new StringBuilder ( "Registry TLS settings: \n " ) ;
19- strBuilder . AppendLine ( "\t TLS 1.2: " + tls12Enabled ? . ToString ( ) ) ;
20- strBuilder . AppendLine ( "\t TLS 1.3: " + tls13Enabled ? . ToString ( ) ) ;
27+ strBuilder . AppendLine ( $ "\t TLS 1.2: DisabledByDefault=' { tls12DisabledByDefault } ', Enabled=' { tls12Enabled } '" ) ;
28+ strBuilder . AppendLine ( $ "\t TLS 1.3: DisabledByDefault=' { tls13DisabledByDefault } ', Enabled=' { tls13Enabled } '" ) ;
2129 strBuilder . AppendLine ( "\t ------" ) ;
2230
2331 Console . WriteLine ( strBuilder . ToString ( ) ) ;
@@ -41,40 +49,78 @@ public static void EnableTls(SslProtocols sslProtocols)
4149
4250 private static void EnableTls12 ( )
4351 {
44- // todo
52+ // Enable TLS1.2
53+ SetRegistryValue ( TLS12SubKey , "DisabledByDefault" , value : 0 , valueToOverride : 1 ) ;
54+ SetRegistryValue ( TLS12SubKey , "Enabled" , value : 1 , valueToOverride : 0 ) ;
55+
56+ // and disable TLS1.3
57+ SetRegistryValue ( TLS13SubKey , "DisabledByDefault" , value : 0 , valueToOverride : 1 ) ;
58+ SetRegistryValue ( TLS13SubKey , "Enabled" , value : 0 , valueToOverride : 1 ) ;
4559 }
4660
4761 private static void EnableTls13 ( )
4862 {
49- var localKey = Environment . Is64BitOperatingSystem
50- ? RegistryKey . OpenBaseKey ( RegistryHive . LocalMachine , RegistryView . Registry64 )
51- : RegistryKey . OpenBaseKey ( RegistryHive . LocalMachine , RegistryView . Registry32 ) ;
63+ // Enable TLS1.3
64+ SetRegistryValue ( TLS13SubKey , "DisabledByDefault" , value : 0 , valueToOverride : 1 ) ;
65+ SetRegistryValue ( TLS13SubKey , "Enabled" , value : 1 , valueToOverride : 0 ) ;
66+
67+ // and disable TLS1.2
68+ SetRegistryValue ( TLS12SubKey , "DisabledByDefault" , value : 0 , valueToOverride : 1 ) ;
69+ SetRegistryValue ( TLS12SubKey , "Enabled" , value : 0 , valueToOverride : 1 ) ;
70+ }
5271
53- var registrySubKey = localKey . OpenSubKey ( TLS13Key , writable : true ) ;
54- if ( registrySubKey is null )
72+ private static void SetRegistryValue ( string subKey , string name , int value , int valueToOverride )
73+ {
74+ var registrySubKey = GetAndCreateSubKey ( subKey ) ;
75+
76+ var registryValue = registrySubKey . GetValue ( name ) as int ? ;
77+ if ( registryValue is null || registryValue == valueToOverride )
5578 {
56- Console . WriteLine ( $ "Registry subKey ` { TLS13Key } ` does not exist. Creating one... ") ;
57- registrySubKey = localKey . CreateSubKey ( TLS13Key ) ;
58- Console . WriteLine ( $ "Created Registry subKey ` { TLS13Key } ` ") ;
79+ Console . WriteLine ( $ "Setting value ' { value } ' on { subKey } \\ { name } ") ;
80+ registrySubKey . SetValue ( name , value ) ;
81+ Console . WriteLine ( $ "Successfully set value ' { value } ' on { subKey } \\ { name } ") ;
5982 }
60-
61- Console . WriteLine ( $ "Enabling registry setting { TLS13Key } \\ EnableHTTP3 for TLS1.3") ;
62- registrySubKey . SetValue ( "EnableHTTP3" , 1 ) ;
63- Console . WriteLine ( $ "Enabled registry setting { TLS13Key } \\ EnableHTTP3 for TLS1.3") ;
6483 }
6584
66- private static string ? GetRegistryValue ( string path , string name )
85+ private static int ? GetRegistryValue ( string path , string name )
6786 {
68- var localKey = Environment . Is64BitOperatingSystem
69- ? RegistryKey . OpenBaseKey ( RegistryHive . LocalMachine , RegistryView . Registry64 )
70- : RegistryKey . OpenBaseKey ( RegistryHive . LocalMachine , RegistryView . Registry32 ) ;
87+ var localKey = RootRegistryKey ;
7188
7289 var registrySubKey = localKey . OpenSubKey ( path ) ;
7390 if ( registrySubKey is not null )
7491 {
75- return registrySubKey . GetValue ( name ) ? . ToString ( ) ;
92+ var value = registrySubKey . GetValue ( name ) ;
93+ return value as int ? ;
7694 }
7795
7896 return null ;
7997 }
98+
99+ private static RegistryKey GetAndCreateSubKey ( string path )
100+ {
101+ var parts = path . Split ( @"\" ) ;
102+ var localKey = RootRegistryKey ;
103+
104+ RegistryKey ? registrySubKey = null ;
105+ var currentPath = parts [ 0 ] + @"\" + parts [ 1 ] ;
106+ var i = 1 ;
107+ while ( i <= parts . Length )
108+ {
109+ registrySubKey = localKey . OpenSubKey ( currentPath , writable : true ) ;
110+ if ( registrySubKey is null )
111+ {
112+ Console . WriteLine ( $ "Registry subKey `{ currentPath } ` does not exist. Creating one...") ;
113+ registrySubKey = localKey . CreateSubKey ( currentPath , writable : true ) ;
114+ Console . WriteLine ( $ "Created Registry subKey `{ currentPath } `") ;
115+ }
116+ currentPath = string . Join ( @"\" , parts . Take ( i ++ + 1 ) ) ;
117+ }
118+
119+ if ( registrySubKey is null || registrySubKey . Name . Substring ( localKey . Name . Length + 1 ) != path )
120+ {
121+ throw new ArgumentException ( $ "failed to create registry subKey { path } ") ;
122+ }
123+
124+ return registrySubKey ;
125+ }
80126}
0 commit comments