static int Main(string[] args) { string api = "socket"; string server = "169.254.201.47"; // Common address for server (running on .NET 47) int port = 13342; // TLS12_ON_13342 var protocols = SslProtocols.Ssl2; // Out default for "not a real protocol" string expect = ExpectWasNotSet; bool waitForRead = false; bool verbose = false; bool parseOk = true; for (int i = 0; i < args.Length; i++) { var argarg = (i < args.Length - 1) ? args[i + 1] : ""; switch (args[i]) { case "-api": switch (argarg) { case "socket": api = argarg; break; case "http": api = argarg; break; default: Console.WriteLine($"ERROR: -arg {argarg} expected either socket or http"); parseOk = false; break; } i += 1; break; case "-expect": { if (argarg == "") { Console.WriteLine($"ERROR: -expect {argarg} expected e.g. Tls12"); parseOk = false; } else { expect = argarg; } } i += 1; break; case "-port": { var parsePort = Int32.TryParse(argarg, out port); if (!parsePort) { Console.WriteLine($"ERROR: -port {argarg} expected e.g. 13400"); parseOk = false; } } i += 1; break; case "-quiet": verbose = false; break; case "-server": { if (argarg == "") { Console.WriteLine($"ERROR: -server {argarg} expected e.g. localhost"); parseOk = false; } else { server = argarg; } } i += 1; break; case "-tls": { var tlsvalues = argarg.Split(new char[] { '+' }); protocols = 0; foreach (var item in tlsvalues) { switch (item) { case "DontPassAnything": protocols |= SslProtocolsExtensions.DontPassAnything; break; case "SystemDefault": protocols = 0; break; case "None": protocols = 0; break; case "Ssl3": protocols |= SslProtocols.Ssl3; break; case "Tls": protocols |= SslProtocols.Tls; break; case "Tls10": protocols |= SslProtocols.Tls; break; case "Tls11": protocols |= SslProtocolsExtensions.Tls11; break; case "Tls12": protocols |= SslProtocolsExtensions.Tls12; break; case "Default": protocols |= SslProtocols.Default; break; default: Console.WriteLine($"ERROR: -tls {item} exected None+SystemDefault+DontPassAnything+Ssl3+Tls+Tls11+Tls12+Default"); parseOk = false; break; } } } i += 1; break; case "-verbose": verbose = true; break; case "-waitforread": waitForRead = true; break; default: Console.WriteLine($"ERROR: {args[i]} is invalid argument"); parseOk = false; break; } } string actual = "FAIL_REALLY_NOT_SET!"; int result = 0; if (!parseOk) { result = 2; } else { //Note: the config will print out information when -verbose is on. //That's the only actual effect of the registry value. var config = new GetConfig(); config.GetRegistry(verbose); switch (api) { case "http": result = ValidateHttp.ValidateHttpWebRequest(server, port, verbose, protocols, expect, out actual); break; case "socket": result = ValidateSslAuthentication.ValidateSslStream(server, port, verbose, protocols, expect, out actual); break; } } if (expect == ExpectWasNotSet) { // If there are no expectations then we aren't either passing or failing. Console.WriteLine($"RESULT: actual {actual} -tls {SslProtocolsExtensions.ToString(protocols)} -port {port}"); } else if (result == 0) { Console.WriteLine($"PASS: expected {expect}"); } else { Console.WriteLine($"FAIL: expected {expect} actual {actual} -tls {SslProtocolsExtensions.ToString(protocols)} -port {port}"); } if (waitForRead) { Console.WriteLine("Press RETURN to exit"); Console.ReadLine(); } return(result); }
public static int ValidateSslStream(string host, int port, bool verbose, System.Security.Authentication.SslProtocols sslProtocols, string expected, out string actual) { var certificateHostName = "supersimplesockettlsversionserver.example.com"; if (verbose) { Console.WriteLine($"STARTING {host} protocol {sslProtocols}"); } actual = "FAIL_NOT_SET!"; string step = "Starting"; try { step = "Make TcpClient"; var tcpclient = new TcpClient(host, port); tcpclient.NoDelay = true; step = "Get Stream"; var networkStream = tcpclient.GetStream(); Stream stream = networkStream; SslProtocols actualProtocol = SslProtocols.Ssl2; // Ssl2 is our default for "not set" :-) string actualProtocolString = "Ssl2"; // Still the default for "not set" step = "Make SslStream"; var sslstream = new SslStream(networkStream, false, (sender, cert, chain, errors) => { return(true); }); stream = sslstream; step = "AuthenticateAsClient"; try { if (sslProtocols == SslProtocolsExtensions.DontPassAnything) { step = "AuthenticateAsClient_default"; sslstream.AuthenticateAsClient(certificateHostName); } else { step = "AuthenticateAsClient_param"; sslstream.AuthenticateAsClient(certificateHostName, null, sslProtocols, false); } step = "AuthenticateAsClient_set_actualProtocol"; actualProtocol = sslstream.SslProtocol; step = "AuthenticateAsClient_set_actualProtocolString"; actualProtocolString = SslProtocolsExtensions.ToString(actualProtocol); } catch (Exception ex2) { if (ex2.Message == "The client and server cannot communicate, because they do not possess a common algorithm") { actual = "FAILED_TLS"; } else { actual = $"FAIL_EXCEPTION_AT_{step}_{ex2.Message}"; } if (verbose) { Console.WriteLine($"EXCEPTION: when authenticateAsClient got {ex2.Message}"); } tcpclient.Close(); } if (tcpclient.Connected) { step = "Store"; var request = "biggely /index.html\r\n"; var requestBuffer = System.Text.Encoding.ASCII.GetBytes(request); if (verbose) { Console.WriteLine($"WRITE STRING {request}"); } stream.Write(requestBuffer, 0, requestBuffer.Length); if (verbose) { Console.WriteLine($"READ STRING"); } byte[] buffer = new byte[1024]; int i; string data = ""; while ((i = stream.Read(buffer, 0, buffer.Length)) != 0) { data = data + System.Text.Encoding.ASCII.GetString(buffer, 0, i); if (verbose) { Console.WriteLine($"GOT PARTIAL STRING: {data}"); } } if (verbose) { Console.WriteLine($"GOT COMPLETE STRING: {data}"); } // $"HTTP/1.0 200 OK\r\n\r\n{replyword} SuperSimpleSocketTlsVersionServer TLS {protocols.ToString()}" var lines = data.Split(new char[] { '\n' }); var dataitems = lines[lines.Length - 1].Split(new char[] { ' ' }); actual = dataitems[0]; if (actual != actualProtocolString) { actual = $"{actual} OR {SslProtocolsExtensions.ToString(actualProtocol)}"; Console.WriteLine($"ERROR: What? at {step} the measured protocol is {actualProtocol} but the server reported {actual}"); } } step = "Close"; tcpclient.Close(); step = "Done"; } catch (Exception ex) { if (verbose) { Console.WriteLine($"EXCEPTION at {step}: {ex.Message}"); } actual = $"FAIL_EXCEPTION_AT{step}_{ex.Message}"; } int Retval = 0; if (actual != expected && expected != Program.ExpectWasNotSet) { Retval = 1; } return(Retval); }