Last active
June 5, 2019 21:06
-
-
Save JonCole/10a7fede4102643c2b63eebf37ac3491 to your computer and use it in GitHub Desktop.
TLS Version Test
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections.Generic; | |
using System.Diagnostics; | |
using System.Linq; | |
using System.Net.Security; | |
using System.Net.Sockets; | |
using System.Security.Authentication; | |
using System.Text; | |
using System.Threading.Tasks; | |
namespace System | |
{ | |
public static class TlsVersionTest | |
{ | |
public static void Run(string hostnameFQDN, int port) | |
{ | |
Console.WriteLine(); | |
Console.WriteLine($"[{DateTimeOffset.Now.TimeOfDay}] ********* Running TLS/SSL Tests against: {hostnameFQDN}:{port} *********\r\n"); | |
var protocols = new[] { SslProtocols.Ssl2, SslProtocols.Ssl3, SslProtocols.Tls, SslProtocols.Tls11, SslProtocols.Tls12 }; | |
var tasks = new HashSet<Task<String>>(); | |
foreach (var p in protocols) | |
{ | |
tasks.Add(TestSslProtocol(hostnameFQDN, port, p, p.ToString())); | |
} | |
//tasks.Add(TestSslProtocol(hostnameFQDN, AnySSLProtocol(), "AllowAny")); | |
tasks.Add(TestSslProtocol(hostnameFQDN, port, SslProtocols.Default, "Default")); | |
while (tasks.Any()) | |
{ | |
var completed = Task.WhenAny(tasks).Result; | |
string result = completed.Result; | |
tasks.Remove(completed); | |
} | |
} | |
public static void RunInLoop(string hostnameFQDN, int port, SslProtocols sslProtocol, int iterationCount) | |
{ | |
Console.WriteLine(); | |
Console.WriteLine($"[{DateTimeOffset.Now.TimeOfDay}] ********* Running TLS/SSL Tests against: {hostnameFQDN}:{port} *********\r\n"); | |
HashSet<Task<string>> results = new HashSet<Task<string>>(); | |
for(int i = 0; i < iterationCount; i++) | |
{ | |
results.Add(TestSslProtocol(hostnameFQDN, port, sslProtocol, sslProtocol.ToString(), includeDetails: false)); | |
} | |
int countCompleted = 0; | |
while (results.Count > 0) | |
{ | |
var t = Task.WhenAny(results).Result; | |
//var t = results.ElementAt(0); | |
countCompleted++; | |
results.Remove(t); | |
Console.WriteLine($"Attempt {countCompleted} of {iterationCount} => {t.Result}"); | |
} | |
} | |
private static async Task<string> TestSslProtocol(string hostName, int port, SslProtocols p, string testDescription, bool includeDetails = true) | |
{ | |
//Console.WriteLine($"P:{p}"); | |
await Task.Yield(); | |
var sb = new StringBuilder(); | |
Stopwatch sw = Stopwatch.StartNew(); | |
var actualProtocol = SslProtocols.None; | |
try | |
{ | |
using (var socket = new Socket(SocketType.Stream, ProtocolType.Tcp)) | |
{ | |
socket.Connect(hostName, port); | |
var networkStream = new NetworkStream(socket, false); | |
var sslStream = new SslStream(networkStream); | |
var clientCerts = new System.Security.Cryptography.X509Certificates.X509CertificateCollection(); | |
sslStream.AuthenticateAsClient(hostName, clientCerts, p, true); | |
actualProtocol = sslStream.SslProtocol; | |
sw.Stop(); | |
sb.AppendLine($"{testDescription}: Allowed, Duration={sw.ElapsedMilliseconds}ms, Protocols Allowed: {p.ToStringExpanded()}, Protocol Used: {actualProtocol}"); | |
if (includeDetails) | |
{ | |
sb.AppendLine($" Cipher: {sslStream.CipherAlgorithm}, strength {sslStream.CipherStrength} bits"); | |
sb.AppendLine($" Hash: {sslStream.HashAlgorithm}, strength {sslStream.HashStrength} bits"); | |
sb.AppendLine($" Key exchange: {sslStream.KeyExchangeAlgorithm}, strength {sslStream.KeyExchangeStrength} bits"); | |
} | |
} | |
} | |
catch (Exception) | |
{ | |
sb.AppendLine($"{testDescription}: BLOCKED, Duration={sw.ElapsedMilliseconds}ms, Protocols Attempted: {p.ToStringExpanded()}"); | |
} | |
return sb.ToString(); | |
} | |
private static SslProtocols AnySSLProtocol() | |
{ | |
SslProtocols retval = SslProtocols.None; | |
foreach (var t in Enum.GetValues(typeof(SslProtocols)).Cast<SslProtocols>()) | |
{ | |
retval = t | retval; | |
} | |
return retval; | |
} | |
private static string ToStringExpanded(this SslProtocols p) | |
{ | |
var list = new System.Collections.Generic.List<SslProtocols>(); | |
foreach (var v in Enum.GetValues(typeof(SslProtocols)).Cast<SslProtocols>()) | |
{ | |
if (v == SslProtocols.Default || v == SslProtocols.None) | |
continue; | |
if (p.HasFlag(v)) | |
list.Add(v); | |
} | |
return string.Join(",", list); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment