navossoc / KeePass-Yet-Another-Favicon-Downloader

Yet Another Favicon Downloader for KeePass 2.x
MIT License
532 stars 30 forks source link

TLS 1.2 with .Net 2.0 possible #23

Closed Tragen closed 5 years ago

Tragen commented 5 years ago

If you still want to support .Net 2.0 and use TLS 1.2, you can use this code. I'm using it in my own KeePass Favicon Downloader.

// Only available from .Net 4.5+ // System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls11 | System.Net.SecurityProtocolType.Tls12;

const System.Security.Authentication.SslProtocols _Tls12 = (System.Security.Authentication.SslProtocols)0x00000C00; const System.Net.SecurityProtocolType Tls12 = (System.Net.SecurityProtocolType)_Tls12; System.Net.ServicePointManager.SecurityProtocol = Tls12;

You can close this bug anytime.

navossoc commented 5 years ago

I'm not sure right now, but I already tried that. If I remember correctly, it will fail silently on Mono (neither TLS 1.0 will work).

You should check it out.

[]'s

Tragen commented 5 years ago

I can only speak for Windows where it's working. I don't use Linux and Mono.

navossoc commented 5 years ago

@Tragen I'm not sure how did you tested it, but if you try it on a clean Windows 7 SP1 machine without installing any additional .NET Framework you will get this error:

System.NotSupportedException: The requested security protocol is not supported.
   at System.Net.ServicePointManager.set_SecurityProtocol(SecurityProtocolType value)

A sample code for testing:

TlsTest.cs

using System.Net;
using System;
using System.Text.RegularExpressions;

namespace TlsTest
{
    class Program
    {
        // https://github.com/mono/mono/blob/master/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/SecurityProtocolType.cs
        enum SecurityProtocolType
        {
            Default = -1073741824,
            Ssl2 = 12,
            Ssl3 = 48,
            Tls = 192,
            Tls11 = 768,
            Tls12 = 3072,
        }

        static void Main(string[] args)
        {
            try
            {
                //ServicePointManager.SecurityProtocol = (System.Net.SecurityProtocolType)SecurityProtocolType.Tls;
                //ServicePointManager.SecurityProtocol = (System.Net.SecurityProtocolType)SecurityProtocolType.Tls11;
                ServicePointManager.SecurityProtocol = (System.Net.SecurityProtocolType)SecurityProtocolType.Tls12;
                //ServicePointManager.SecurityProtocol = (System.Net.SecurityProtocolType)SecurityProtocolType.Tls | (System.Net.SecurityProtocolType)SecurityProtocolType.Tls11 | (System.Net.SecurityProtocolType)SecurityProtocolType.Tls12;

                WebClient wc = new WebClient();

                // TLS 1.0, TLS 1.1, TLS 1.2
                string result = wc.DownloadString("https://www.howsmyssl.com/a/check");
                Console.WriteLine(Regex.Match(result, "\"tls_version\":\".+?\"").Value);

                byte[] data;

                // TLS 1.0, TLS 1.1, TLS 1.2
                data = wc.DownloadData("https://www.google.com/favicon.ico");
                Console.WriteLine("TLS 1.0: {0}", data.Length);

                // TLS 1.1, TLS 1.2
                data = wc.DownloadData("https://tls1test.salesforce.com/favicon.ico");
                Console.WriteLine("TLS 1.1: {0}", data.Length);

                // TLS 1.2
                data = wc.DownloadData("https://github.com/favicon.ico");
                Console.WriteLine("TLS 1.2: {0}", data.Length);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
            }

            Console.ReadKey();
        }
    }
}

You can compile it with: C:\Windows\Microsoft.NET\Framework\v2.0.50727\csc.exe TlsTest.cs

Tragen commented 5 years ago

On Windows 7 TLS 1.1 and TLS 1.2 are disabled by default. You have to enable them in the registry.

navossoc commented 5 years ago

Yes, with this tweak on the registry:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1\Client]
"DisabledByDefault"=dword:00000000

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1\Server]
"DisabledByDefault"=dword:00000000

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Client]
"DisabledByDefault"=dword:00000000

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Server]
"DisabledByDefault"=dword:00000000

This will let Outlook for example connect using TLS 1.1 or TLS 1.2, but .NET still refuses to connect using it.

System.Net.WebException: The underlying connection was closed: An unexpected error occurred on a send. ---> System.IO.IOException: Received an unexpected EOF or 0 bytes from the transport stream.
   at System.Net.FixedSizeReader.ReadPacket(Byte[] buffer, Int32 offset, Int32 count)

I'm missing something? Maybe a specific KB from Microsoft?

Tragen commented 5 years ago

You can try https://support.microsoft.com/en-ph/help/3154518/support-for-tls-system-default-versions-included-in-the-net-framework

I found the hint here https://docs.microsoft.com/en-us/dotnet/framework/network-programming/tls

navossoc commented 5 years ago

Well, I did another shot after updating the whole operational system, but still no luck.

Anyway, I don't mind in getting the requirements higher, but I'm still not sure that your workaround works on .NET 2.0. The article makes reference to .NET 3.5.