2

I have a simple C# app that makes a HTTPs request using TcpClient and SslStream. Everything works fine, except some websites that use TLS 1.3 are failing. I upgraded project to .Net Framework 4.8, also read slowly https://learn.microsoft.com/es-es/dotnet/framework/network-programming/tls but i can't achieve a solution.

I'm using Windows 10 64bit compilation 19041.508.

The minimal code example that i can provide is next:

using System;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Net.Security;
using System.Net.Sockets;
using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates;
        private void button1_Click(object sender, EventArgs e)
        {
            string hostname = "stackoverflow.com";

            using (TcpClient tcpClient = new TcpClient())
            {
                tcpClient.Connect(hostname, 443);

                //HTTP request headers
                string reqString = "GET / HTTP/1.1" + "\r\n";
                reqString += "Host: " + hostname + "\r\n";
                reqString += "Connection: Close\r\n\r\n";
                byte[] header_bytes = Encoding.ASCII.GetBytes(reqString);

                using (SslStream sslStream = new SslStream(tcpClient.GetStream(), false, new RemoteCertificateValidationCallback(ValidateServerCertificate), null))
                {
                    sslStream.AuthenticateAsClient(hostname, null, SslProtocols.Ssl3 | SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12 | SslProtocols.Tls13, false);
                    sslStream.Write(header_bytes, 0, header_bytes.Length);

                    string response = "";
                    using (var memory = new MemoryStream())
                    {
                        sslStream.CopyTo(memory, 81920);
                        memory.Position = 0;
                        byte[] data = memory.ToArray();
                        response = Encoding.UTF8.GetString(data);
                        textBox1.Text = response;
                    }
                }
            }
        }

        //Validate certificates
        public static bool ValidateServerCertificate(
        object sender,
        X509Certificate certificate,
        X509Chain chain,
        SslPolicyErrors sslPolicyErrors)
        {
            if (sslPolicyErrors == SslPolicyErrors.None)
                return true;

            // Do not allow this client to communicate with unauthenticated servers.
            return false;
        }

If you try as hostname stackoverflow.com it works but if you use for example manga1001.com it fails and an exception is thrown. Exception details:

System.Security.Authentication.AuthenticationException
  HResult=0x80131501
  Mensaje = A call to SSPI failed, see inner exception.
  Origen = System
  Seguimiento de la pila:
   en System.Net.Security.SslState.StartSendAuthResetSignal(ProtocolToken message, AsyncProtocolRequest asyncRequest, Exception exception)
   en System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)
   en System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest)
   en System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest)
   en System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest)
   en System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
   en System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)
   en System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest)
   en System.Net.Security.SslState.ForceAuthentication(Boolean receiveFirst, Byte[] buffer, AsyncProtocolRequest asyncRequest)
   en System.Net.Security.SslState.ProcessAuthentication(LazyAsyncResult lazyResult)
   en System.Net.Security.SslStream.AuthenticateAsClient(String targetHost, X509CertificateCollection clientCertificates, SslProtocols enabledSslProtocols, Boolean checkCertificateRevocation)
   en http_minimal.Form1.button1_Click(Object sender, EventArgs e) en C:\Users\VA\source\repos\http_minimal\http_minimal\Form1.cs: línea 36
   en System.Windows.Forms.Control.OnClick(EventArgs e)
   en System.Windows.Forms.Button.OnClick(EventArgs e)
   en System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
   en System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
   en System.Windows.Forms.Control.WndProc(Message& m)
   en System.Windows.Forms.ButtonBase.WndProc(Message& m)
   en System.Windows.Forms.Button.WndProc(Message& m)
   en System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
   en System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
   en System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
   en System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
   en System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
   en System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
   en System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
   en System.Windows.Forms.Application.Run(Form mainForm)
   en http_minimal.Program.Main() en C:\Users\VA\source\repos\http_minimal\http_minimal\Program.cs: línea 19

Excepción interna 1:
Win32Exception: No se permite la función solicitada

Hope that someone can give me a hand adressing this problem, i spend many hours but no solution found.

Zeokat
  • 504
  • 1
  • 5
  • 16
  • Can you post the whole exception here please? – Martin Staufcik Nov 15 '20 at 18:34
  • Added full exception text. Thanks. – Zeokat Nov 15 '20 at 18:37
  • The is not a client issue since it works with some server and not others. The servers are the issue. Make sure the server have the same certificate installed and make sure the server have the same version of Net. What application is being used for the servers? How did you install application? – jdweng Nov 15 '20 at 21:25
  • I'm not the owner of the servers, the servers run on the internet themselves, so i don't have to install anything on servers. I suggest you read the code slowly and the problem described. All webapges tested works perfectly into FireFox, Chrome, etc... only fails when i try to access using SSLStream code. – Zeokat Nov 15 '20 at 21:34

2 Answers2

0

Please try:

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls13;
  • Where should i use that? I tested into the SSLstream using and throws the same error. Can you detail more in depth your solution? – Zeokat Nov 15 '20 at 18:42
  • I use it at startup and i use HttpWebRequest. Try to find such code: var request = (HttpWebRequest)WebRequest.Create(Address); – Yaroslav Menshikov Nov 15 '20 at 19:21
  • If you check my code slowly i'm not using HttpWebRequest, i'm using tcpclient with sslstream. – Zeokat Nov 15 '20 at 19:29
0

I go to give some light to this after a frustrating research. Seems that current Windows 10 version doesn't support fully TLS 1.3. Microsoft announced an update with TLS Cipher Suites in Windows 10 v21H1.

In other words, we have to wait until Microsoft launch that update to check if the problem persists. At this moment the problem can't be fixed because the Windows 10 v19042.685 (20H2), can't support the required TLS 1.3 cipher required by the webpage tested.

Zeokat
  • 504
  • 1
  • 5
  • 16