SSL Stream handsake exception

Hello,

I have decided to move my game server to the unity (mainly because of collisions), sadly the SSL Authentication is for some odd reason throwing a bunch of errors. Both server and client are authenticating with Tls12, and it is working perfectly fine when I’m connecting the client to the console server that I’ve been using before. I’m using a self-signed cert for that, that I have moved to the Trusted root folder. There is the exception that it’s throwing:

Exceptions

Authentication failed: System.AggregateException: One or more errors occurred. —> System.Security.Authentication.AuthenticationException: A call to SSPI failed, see inner exception. —> Mono.Security.Interface.TlsException: Verification failure during handshake
at Mono.Unity.UnityTlsContext.ProcessHandshake () [0x00081] in <525dc68fbe6640f483d9939a51075a29>:0
at Mono.Net.Security.MobileAuthenticatedStream.ProcessHandshake (Mono.Net.Security.AsyncOperationStatus status) [0x0003e] in <525dc68fbe6640f483d9939a51075a29>:0
at (wrapper remoting-invoke-with-check) Mono.Net.Security.MobileAuthenticatedStream.ProcessHandshake(Mono.Net.Security.AsyncOperationStatus)
at Mono.Net.Security.AsyncHandshakeRequest.Run (Mono.Net.Security.AsyncOperationStatus status) [0x00006] in <525dc68fbe6640f483d9939a51075a29>:0
at Mono.Net.Security.AsyncProtocolRequest+d__24.MoveNext () [0x000ff] in <525dc68fbe6640f483d9939a51075a29>:0
— End of stack trace from previous location where exception was thrown —
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in :0
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) [0x0003e] in :0
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) [0x00028] in :0
at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) [0x00008] in :0
at System.Runtime.CompilerServices.ConfiguredTaskAwaitable+ConfiguredTaskAwaiter.GetResult () [0x00000] in :0
at Mono.Net.Security.AsyncProtocolRequest+d__23.MoveNext () [0x0008b] in <525dc68fbe6640f483d9939a51075a29>:0
— End of inner exception stack trace —
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in :0
at Mono.Net.Security.MobileAuthenticatedStream+d__47.MoveNext () [0x00254] in <525dc68fbe6640f483d9939a51075a29>:0
— End of inner exception stack trace —
at System.Threading.Tasks.Task.ThrowIfExceptional (System.Boolean includeTaskCanceledExceptions) [0x00011] in :0
at System.Threading.Tasks.Task.Wait (System.Int32 millisecondsTimeout, System.Threading.CancellationToken cancellationToken) [0x00043] in :0
at System.Threading.Tasks.Task.Wait () [0x00000] in :0
at Mono.Net.Security.MobileAuthenticatedStream.AuthenticateAsServer (System.Security.Cryptography.X509Certificates.X509Certificate serverCertificate, System.Boolean clientCertificateRequired, System.Security.Authentication.SslProtocols enabledSslProtocols, System.Boolean checkCertificateRevocation) [0x00011] in <525dc68fbe6640f483d9939a51075a29>:0
at System.Net.Security.SslStream.AuthenticateAsServer (System.Security.Cryptography.X509Certificates.X509Certificate serverCertificate, System.Boolean clientCertificateRequired, System.Security.Authentication.SslProtocols enabledSslProtocols, System.Boolean checkCertificateRevocation) [0x00006] in <525dc68fbe6640f483d9939a51075a29>:0
at Client+SSL.ProcessClient (System.Net.Sockets.TcpClient _client, System.Int32 _id) [0x00058] in D:\Dokumenty\Projects\PolyFights\PolyWorldServer\Assets\Scripts\Client.cs:216
—> (Inner Exception #0) System.Security.Authentication.AuthenticationException: A call to SSPI failed, see inner exception. —> Mono.Security.Interface.TlsException: Verification failure during handshake
at Mono.Unity.UnityTlsContext.ProcessHandshake () [0x00081] in <525dc68fbe6640f483d9939a51075a29>:0
at Mono.Net.Security.MobileAuthenticatedStream.ProcessHandshake (Mono.Net.Security.AsyncOperationStatus status) [0x0003e] in <525dc68fbe6640f483d9939a51075a29>:0
at (wrapper remoting-invoke-with-check) Mono.Net.Security.MobileAuthenticatedStream.ProcessHandshake(Mono.Net.Security.AsyncOperationStatus)
at Mono.Net.Security.AsyncHandshakeRequest.Run (Mono.Net.Security.AsyncOperationStatus status) [0x00006] in <525dc68fbe6640f483d9939a51075a29>:0
at Mono.Net.Security.AsyncProtocolRequest+d__24.MoveNext () [0x000ff] in <525dc68fbe6640f483d9939a51075a29>:0
— End of stack trace from previous location where exception was thrown —
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in :0
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) [0x0003e] in :0
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) [0x00028] in :0
at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) [0x00008] in :0
at System.Runtime.CompilerServices.ConfiguredTaskAwaitable+ConfiguredTaskAwaiter.GetResult () [0x00000] in :0
at Mono.Net.Security.AsyncProtocolRequest+d__23.MoveNext () [0x0008b] in <525dc68fbe6640f483d9939a51075a29>:0
— End of inner exception stack trace —
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in :0
at Mono.Net.Security.MobileAuthenticatedStream+d__47.MoveNext () [0x00254] in <525dc68fbe6640f483d9939a51075a29>:0 <—

UnityEngine.Debug:Log (object)
Client/SSL:ProcessClient (System.Net.Sockets.TcpClient,int) (at Assets/Scripts/Client.cs:224)
Client/TCP:Connect (System.Net.Sockets.TcpClient) (at Assets/Scripts/Client.cs:76)
Server:TCPConnectCallback (System.IAsyncResult) (at Assets/Scripts/Server.cs:61)
System.Threading._ThreadPoolWaitCallback:PerformWaitCallback ()

So I’ve tried to generate a new certificate with a “New-SelfSignedCertificate”, and it’s still throwing the same error, also I found out, that when I want to use X509Store, it would return 0 certificates, and when I tried to create a custom store for unity certs, it created one, but I have no idea where is that one stored, it’s not in “C:\Windows\System32\Certlog”, but Unity can access it without a problem. Just to be sure that my code is right (which should be, because like I said, it’s working perfectly fine on my console server), this is the code that I’m using for verification:

Server:

public bool ProcessClient(TcpClient _client)
        {
            socket = _client;

            stream = new SslStream(_client.GetStream(), false);
            receivedData = new Packet();
            receiveBuffer = new byte[dataBufferSize];

            try
            {
                stream.AuthenticateAsServer(serverCertificate, false, SslProtocols.Tls12, true);

                stream.BeginRead(receiveBuffer, 0, dataBufferSize, ReceiveCallback, null);
                return true;
            }
            catch (Exception _ex)
            {
                Debug.Log($"Authentication failed: {_ex}");
                stream.Close();
                socket.Close();
                return false;
            }
        }

Client:

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

            Debug.Log($"Certificate error: {sslPolicyErrors}");

            return false;
        }

        public void VerifyCredentials(TcpClient _client)
        {
            Debug.Log("Client connected, waiting for authentication..");

            socket = _client;
            stream = new SslStream(socket.GetStream(), false);

            receivedData = new Packet();
            receiveBuffer = new byte[dataBufferSize];

            try
            {
                stream.AuthenticateAsClient(nameOfTheServer);
            }
            catch (Exception _ex)
            {
                Debug.Log($"SSL stream failed:{_ex}");

                if (_ex.InnerException != null)
                    Debug.Log("Authentication failed.");
                socket.Close();
            }

            ClientSend.AuthenticationVerify();
        }

Have you been able to figure this out? I’ve also encountered this. Works perfectly fine on console server but errors out on unity server build.