HttpServerBoxed 0.0.11 alpha
A simple http server for C# and .NET
Loading...
Searching...
No Matches
HSB.TLS Namespace Reference

Classes

class  ProtocolVersion
 

Functions

class Curl (string url="localhost", string port="443")
 
class CustomTLS (Socket socket)
 

Function Documentation

◆ Curl()

class HSB.TLS.Curl ( string  url = "localhost",
string  port = "443" 
)

Runs the curl command

Parameters
loopWether or not repeat the command
delayDelay between each request
timesIf loop is true, specifies how many times the command must be repeated (-1 means forever)

Definition at line 8 of file Curl.cs.

9{
10
11 readonly string fullUrl = $"https://{url}:{port}/";
12
13 ProtocolVersion protocolVersion = new(TLSVersion.TLS_1_3);
14
15 string cipherSuitesString = "";
16
17 public void SetTLSVersion(TLSVersion tlsVersion)
18 {
19 protocolVersion = new(tlsVersion);
20 }
21
22 public void SetCipherSuites(string cipherSuites)
23 {
24 cipherSuitesString = cipherSuites;
25 }
26
27 private string GetCurlCommand()
28 {
29
30 string command = $"curl -k --tlsv{protocolVersion} --tls-max {protocolVersion} ";
31 if (cipherSuitesString != "")
32 {
33 command += $"--ciphers {cipherSuitesString} ";
34 }
35 command = command[..^1];
36 command += $" {fullUrl}";
37 return command;
38 }
39
40
47 public void RunAsync(bool loop = true, int delay = 250, int times = -1)
48 {
49
50 Task.Run(() =>
51 {
52 if (loop)
53 {
54
55 bool _loop = true;
56 while (_loop)
57 {
58 Thread.Sleep(delay);
59 if (times != -1)
60 {
61 times--;
62 if (times == 0)
63 {
64 _loop = false;
65 }
66 }
67 Exec();
68
69 }
70 }
71 else
72 {
73 Thread.Sleep(delay);
74 Exec();
75 }
76 });
77 }
78
79 private void Exec()
80 {
81 string command = GetCurlCommand();
82 ProcessStartInfo startInfo = new();
83 //if windows
84 if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
85 {
86 startInfo.FileName = "cmd.exe";
87 startInfo.Arguments = $"/C \"{command}\"";
88
89 }
90 else
91 {
92 startInfo.FileName = "/bin/zsh";
93 startInfo.Arguments = $"-c \"{command}\"";
94 }
95 startInfo.RedirectStandardOutput = true;
96 startInfo.RedirectStandardError = true;
97 startInfo.UseShellExecute = false;
98 startInfo.CreateNoWindow = true;
99 Process process = new()
100 {
101 StartInfo = startInfo
102 };
103 Console.WriteLine($"Starting curl... \n{command}");
104 process.Start();
105 }
106
107
108}

◆ CustomTLS()

class HSB.TLS.CustomTLS ( Socket  socket)

Definition at line 12 of file TLS.cs.

13{
14 readonly Socket socket = socket;
15 //items of the TLS request
16
17 // ProtocolVersion clientVersion;
18
19
20 byte[] clientRandom = [];
21 ushort sessionID_size;
22 byte[] fakeSessionID = [];
23 readonly List<Ciphers> cipherSuites = [];
24
25 public void Parse(byte[] data)
26 {
27 Console.Clear();
28 PrintDatatable(data);
29 PrintDatatableASCII(data);
30 //print each byte explaning what is
31 //Record Header
32 Console.WriteLine($"(offset : 0 )\tRequest Type: {data[0]:X2} (16 == Handshake record))");
33 Console.WriteLine($"(offset: 1)\tTLS Version (Major): {data[1]:X2} (Minor): {data[2]:X2})");
34 //handshake length
35 int handshakeLength = Utils.BytesToUShort([data[3], data[4]]);
36 Console.WriteLine(
37 $"(offset: 3)\tHandshake length (bytes): {data[3]:X2}{data[4]:X2} (int : {handshakeLength}) handshake ends at row {(handshakeLength + 4) / 16} col {(handshakeLength + 4) % 16})");
38 //handshake header
39 Console.WriteLine($"(offset 5)\tHandshake Type: {data[5]:X2} (1 == Client Hello))");
40 Console.WriteLine(
41 $"(offset 6)\tHandshake length (bytes): {data[6]:X2}{data[7]:X2}{data[8]:X2} (int : {Utils.UInt24ToUInt32([data[6], data[7], data[8]])})");
42 //Client Version
43 Console.WriteLine($"(offset 9)\tClient Version (Major): {data[9]:X2} (Minor): {data[10]:X2})");
44
45 if (data[9] == 0x03 && data[10] == 0x03)
46 {
47 ClientHello c = new (data[9..]);
48 Console.WriteLine(c);
49 return;
50
51 Console.WriteLine("Detected client TLS v1.3");
52 ParseTLS_1_3(data, handshakeLength);
53 ParseTLSv1_3(data);
54 }
55 else
56 {
57 Console.WriteLine("Detected client TLS up to v1.2");
58 //ParseTLS_UP_TO_1_2(data, handshake_length);
59 }
60 }
61
62 static void PrintDatatable(byte[] data)
63 {
64 Console.WriteLine("Printing raw request preview\n============================================");
65 //print table header (0 -> 15)
66 Console.WriteLine("\t 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15");
67 int i = 0;
68 int j = 0;
69 Console.Write($"{0}\t");
70 foreach (byte b in data)
71 {
72 Console.Write($"{b:X2} ");
73 i++;
74 if (i == 16)
75 {
76 j++;
77 Console.WriteLine("");
78 Console.Write($"{j}\t");
79 i = 0;
80 }
81 }
82
83 Console.WriteLine("\n====================================");
84 }
85
86 static void PrintDatatableASCII(byte[] data)
87 {
88 Console.WriteLine("Printing raw request preview\n============================================");
89 //print table header (0 -> 15)
90 Console.WriteLine("\t 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15");
91 int i = 0;
92 int j = 0;
93 Console.Write($"{0}\t");
94 var str = Encoding.ASCII.GetString(data).ToCharArray();
95 for (int k = 0; k < data.Length; k++)
96 {
97 Console.Write($"{str[k]} ");
98 i++;
99 if (i == 16)
100 {
101 j++;
102 Console.WriteLine("");
103 Console.Write($"{j}\t");
104 i = 0;
105 }
106 }
107
108 Console.WriteLine("\n====================================");
109 }
110
111
112 /*ProtocolVersion version = new(data);
113 Console.WriteLine("Client hello with TLS version: " + version.ToString());*/
114
115
116 private void ParseTLSv1_3(byte[] data)
117 {
118 Console.WriteLine("=============================\nNew parser result:");
119 DataReader d = new(data);
120
121 byte requestType = d.ReadByte();
122 byte[] TLS_Version = d.ReadBytes(DataOffsets.TLS_VERSION.size);
123 byte[] msgLength = d.ReadBytes(DataOffsets.MESSAGE_LENGTH.size);
124 byte handshakeType = d.ReadByte();
125 byte[] handshakeLenght = d.ReadBytes(DataOffsets.HANDSHAKE_DATA_LENGHT.size); //in bytes
126 uint handshakeLenghtInt = Utils.UInt24ToUInt32(handshakeLenght);
127
128
129 uint endPosition =
130 handshakeLenghtInt +
131 1 +
132 DataOffsets.TLS_VERSION.size +
133 DataOffsets.MESSAGE_LENGTH.size +
134 1 +
135 DataOffsets.HANDSHAKE_DATA_LENGHT.size;
136 d.SetEndPosition(Math.Min(endPosition, 512));
137
138 byte[] clientVersion = d.ReadBytes(DataOffsets.CLIENT_VERSION.size);
139 byte[] clientRandom = d.ReadBytes(32);
140 byte sessionIDSize = d.ReadByte(); //should always be 0 in TLS1.3
141 byte[] fakeSessionID = d.ReadBytes(sessionIDSize);
142 byte[] cipherSuitesLength = d.ReadBytes(2);
143 ushort cipherSuitesLengthInt = Utils.BytesToUShort(cipherSuitesLength);
144 List<Ciphers> ciphers = [];
145 for (int i = 0; i < cipherSuitesLengthInt; i += 2)
146 {
147 ciphers.Add(GetCipher(d.ReadBytes(2)));
148 }
149
150 byte[] compressionData = d.ReadBytes(2);
151 byte[] extensionsLength = d.ReadBytes(2);
152 extensionsLength[0] = 0x0; //testing
153 ushort extensionsLengthInt = Utils.BytesToUShort(extensionsLength); //in bytes
154 List<IExtension> extensions = [];
155
156 while (d.DataAvailable() && extensionsLengthInt > 0 && extensionsLengthInt < 512)
157 {
158 IExtension e = ExtensionUtils.ReadExtension(d);
159 extensions.Add(e);
160 // Console.WriteLine(d.RemainingData);
161 }
162
163
164 Console.Write(
165 $"Request Type: 0x{requestType:X2}" +
166 $"\nTLS Version: 0x{BitConverter.ToString(TLS_Version).Replace("-", " 0x")}" +
167 $"\nMessage Length: 0x{BitConverter.ToString(msgLength).Replace("-", " 0x")} ({Utils.BytesToUShort(msgLength)})" +
168 $"\nHandshake Type: 0x{handshakeType:X2}" +
169 $"\nHandshake Length: 0x{BitConverter.ToString(handshakeLenght).Replace("-", " 0x")} ({Utils.UInt24ToUInt32(handshakeLenght)})" +
170 $"\nClient Version: 0x{BitConverter.ToString(clientVersion).Replace("-", " 0x")}" +
171 $"\nClient Random: 0x{BitConverter.ToString(clientRandom).Replace("-", " 0x")}" +
172 $"\nSession ID: 0x{sessionIDSize:X2}" +
173 $"\nFake Session ID: 0x{BitConverter.ToString(fakeSessionID).Replace("-", " 0x")}0" +
174 $"\nCipher Suites Length: 0x{BitConverter.ToString(cipherSuitesLength).Replace("-", " 0x")} ({cipherSuitesLengthInt} bytes, {cipherSuitesLengthInt / 2} ciphers)" +
175 $"\nCipher Suites: \n\t{string.Join(",\n\t", ciphers)}" +
176 $"\nCompression Data: 0x{BitConverter.ToString(compressionData).Replace("-", " 0x")}" +
177 $"\nExtensions Length: 0x{BitConverter.ToString(extensionsLength).Replace("-", " 0x")} ({extensionsLengthInt} bytes)\n"
178 );
179 //print extensions
180 foreach (IExtension e in extensions)
181 Console.WriteLine("\t" + e.ToString());
182
183
184 ClientHello clientHello = new(clientRandom, fakeSessionID, ciphers, extensions);
185 ServerHello serverHello = new(clientHello);
186 serverHello.BuildResponse();
187
188 //Generate a private key with the X25519 curve
189 /* using ECDiffieHellmanCng ecdh = new(ECCurve.NamedCurves.);
190 ecdh.KeyDerivationFunction = ECDiffieHellmanKeyDerivationFunction.Hash;
191 ecdh.HashAlgorithm = CngAlgorithm.Sha256;
192 byte[] publicKey = ecdh.PublicKey.ToByteArray();
193 Console.WriteLine($"Generate public key: 0x{BitConverter.ToString(publicKey).Replace("-", " 0x")}");*/
194
195
196 Console.WriteLine("Done");
197 }
198
199 private void ParseTLS_1_3(byte[] data, int handshake_length)
200 {
201 //in TLS 1.3+ session id is differente and have a size
202
203 int offset = 11;
204 int col = offset % 16;
205 int row = offset / 16;
206
207
208 //client random -> 32 bytes
209 clientRandom = new byte[32];
210 Array.Copy(data, offset, clientRandom, 0, 32);
211 uint clientRandomInt = BitConverter.ToUInt32(clientRandom);
212 Console.WriteLine(
213 $"(offset {offset} (riga {row}, col {col}))\tRandom (32 bytes): 0x{BitConverter.ToString(clientRandom).Replace("-", " 0x")}");
214 Console.WriteLine($"The 32bit random number is : {clientRandomInt}");
215 offset += 32;
216 col = offset % 16;
217 row = offset / 16;
218 //Session ID
219 sessionID_size = data[offset];
220 Console.WriteLine(
221 $"(offset {offset} (riga {row}, col {col}))\tSession ID size: {data[offset]:X2} (int : {sessionID_size})");
222 fakeSessionID = new byte[sessionID_size];
223 Array.Copy(data, offset + 1, fakeSessionID, 0, sessionID_size);
224 Console.WriteLine(
225 $"(offset {offset} (riga {row}, col {col}))\tSession ID: {BitConverter.ToString(fakeSessionID).Replace("-", " ")}");
226 offset += 1 + sessionID_size;
227 //Cipher Suites
228 col = offset % 16;
229 row = offset / 16;
230 ushort cipher_suites_length =
231 Utils.BytesToUShort([data[offset], data[offset + 1]]); //length in bytes
232 Console.WriteLine(
233 $"(offset {offset} (riga {row}, col {col}))\tCipher Suites Length: {data[offset]:X2} {data[offset + 1]:X2} (int : {cipher_suites_length / 2})");
234 offset += 2;
235 col = offset % 16;
236 row = offset / 16;
237 for (int i = 0; i < cipher_suites_length; i += 2)
238 {
239 Console.Write(
240 $"(offset {offset} (riga {row}, col {col}))\tCipher Suite: 0x{data[offset]:X2}, 0x{data[offset + 1]:X2} -> ");
241 var cS = GetCipher([data[offset], data[offset + 1]]);
242 cipherSuites.Add(cS);
243 Console.WriteLine(cS);
244 offset += 2;
245 col = offset % 16;
246 row = offset / 16;
247 }
248
249 //Compression data -> not available in TLS 1.3+ so two bytes const 0x01 0x00
250 Console.WriteLine(
251 $"(offset {offset} (riga {row}, col {col}))\tCompression Data: {data[offset]:X2} {data[offset + 1]:X2}");
252 offset += 2;
253 //Extensions
254 col = offset % 16;
255 row = offset / 16;
256 ushort extensions_length = Utils.BytesToUShort([data[offset], data[offset + 1]]);
257 //same as TLS 1.2
258 Console.WriteLine(
259 $"(offset {offset} (riga {row}, col {col}))\tExtensions Length: {data[offset]:X2} {data[offset + 1]:X2} (int : {extensions_length}))");
260 offset += 2;
261
262 /* List<Extension> extensions = new();
263
264 while (offset < handshake_length)
265 {
266 //extension range from current two bytes to current two bytes + 4 + extension length
267 Extension e;
268 offset = ExtensionUtils.ExtensionReaderExtended(data, offset, out e);
269 extensions.Add(e);
270 Console.WriteLine(e.ToString());
271
272 }*/
273
274
275 Console.WriteLine("Client Hello (TLS version 1.3) parsed!");
276 }
277
278 private void ParseTLS_UP_TO_1_2(byte[] data)
279 {
280 int i;
281 //Random
282 Console.WriteLine($"(offset 11)\tRandom (32 bytes): {BitConverter.ToString(data, 11, 32).Replace("-", " ")}");
283 //Session ID
284 Console.WriteLine($"(offset 43 (riga {43 / 16}, col {43 % 16}))\tSession ID: 0x{data[43]:X2}");
285 //Cipher Suites
286 //two bytes to int
287 ushort cipher_suites_length = Utils.BytesToUShort([data[44], data[45]]);
288 Console.WriteLine(
289 $"(offset 44 (riga {44 / 16}, col {44 % 16}))\tCipher Suites Length: {data[44]:X2} {data[45]:X2} (int : {cipher_suites_length / 2})");
290 int offset = 46;
291 int col = offset % 16;
292 int row = offset / 16;
293
294 for (i = 0; i < cipher_suites_length; i += 2)
295 {
296 offset += i;
297 Console.Write(
298 $"(offset {offset} (riga {row}, col {col}))\tCipher Suite: 0x{data[46 + i]:X2}, 0x{data[47 + i]:X2} -> ");
299 Console.WriteLine(CipherSuite.GetCipher([data[46 + i], data[47 + i]]));
300 }
301
302 //compression methods
303 offset = 46 + cipher_suites_length;
304 col = offset % 16;
305 row = offset / 16;
306 Console.WriteLine(
307 $"(offset {offset} (riga {row}, col {col}))\tCompression Methods Length: {data[offset]:X2} {data[offset + 1]:X2} (int : {Utils.BytesToUShort([data[offset], data[offset + 1]])})");
308 offset += 2;
309 col = offset % 16;
310 row = offset / 16;
311 //Extensions length
312 int extensionsLength = Utils.BytesToUShort([data[offset], data[offset + 1]]);
313 Console.WriteLine(
314 $"(offset {offset} (riga {row}, col {col}))\tExtensions Length: {data[offset]:X2} {data[offset + 1]:X2} (int : {extensionsLength}))");
315 offset += 2;
316 //Each extension will start with two bytes that indicate which extension it is,
317 //followed by a two-byte content length field, followed by the contents of the extension.
318 //Extensions
319
320 //server name?
321 /* Console.WriteLine("Extension 1");
322 byte[] extensionType = new byte[] { data[offset], data[offset + 1] };
323 Console.WriteLine($"(offset {offset} (riga {row}, col {col}))\tExtension Type: 0x{data[offset]:X2} 0x{data[offset + 1]:X2}");
324 offset += 2;
325 ushort extensionLength = TwoBytesToShort(new byte[] { data[offset], data[offset + 1] });
326 Console.WriteLine($"(offset {offset} (riga {row}, col {col}))\tExtension Length: 0x{data[offset]:X2} 0x{data[offset + 1]:X2} (int : {extensionLength})");
327 offset += 2;
328 byte[] extensionData = new byte[extensionLength];
329 Array.Copy(data, offset, extensionData, 0, extensionLength);
330 Console.WriteLine($"(offset {offset} (riga {row}, col {col}))\tExtension Data: {BitConverter.ToString(extensionData).Replace("-", " ")} -> {Encoding.ASCII.GetString(extensionData)}");
331
332 //next extension
333 Console.WriteLine("Extension 2");
334 offset += extensionLength;
335 extensionType = new byte[] { data[offset], data[offset + 1] };
336 Console.WriteLine($"(offset {offset} (riga {row}, col {col}))\tExtension Type: 0x{data[offset]:X2} 0x{data[offset + 1]:X2}");
337 offset += 2;
338 extensionLength = TwoBytesToShort(new byte[] { data[offset], data[offset + 1] });
339 Console.WriteLine($"(offset {offset} (riga {row}, col {col}))\tExtension Length: 0x{data[offset]:X2} 0x{data[offset + 1]:X2} (int : {extensionLength})");
340 offset += 2;
341 extensionData = new byte[extensionLength];
342 Array.Copy(data, offset, extensionData, 0, extensionLength);
343 Console.WriteLine($"(offset {offset} (riga {row}, col {col}))\tExtension Data: {BitConverter.ToString(extensionData).Replace("-", " ")} -> {Encoding.ASCII.GetString(extensionData)}");
344*/
345
346
347 Console.WriteLine("Client Hello (TLS version max 1.2) parsed!");
348 }
349}
class DataReader(byte[] data)
A class to simplify reading data from a byte array.
Definition DataReader.cs:5