Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

wss protocol does not work when build on UWP #1

Open
salinhard opened this issue Sep 23, 2019 · 12 comments
Open

wss protocol does not work when build on UWP #1

salinhard opened this issue Sep 23, 2019 · 12 comments

Comments

@salinhard
Copy link

I'm using your great library for implement websockets on Hololens.
If I use a ws protocol, it works on Unity Editor and Hololens.
If I use wss, it works on Unity Editor but does not work on Hololens.

Seems a certificate error, because I get this error on the Hololens log:
Curl error 51: Cert verify failed: UNITYTLS_X509VERIFY_FLAG_NOT_TRUSTED

Here the errors I got:

A call to SSPI failed, see inner exception.

Mono.Security.Interface.TlsException: Handshake failed - error code: UNITYTLS_INTERNAL_ERROR, verify result: UNITYTLS_X509VERIFY_FLAG_NOT_TRUSTED
at Mono.Unity.Debug.CheckAndThrow (Mono.Unity.UnityTls+unitytls_errorstate errorState, Mono.Unity.UnityTls+unitytls_x509verify_result verifyResult, System.String context, Mono.Security.Interface.AlertDescription defaultAlert) [0x00036] in <0d3e94ab2a1c4d2a8582ccee7031f5c6>:0
at Mono.Unity.UnityTlsContext.ProcessHandshake () [0x00082] in <0d3e94ab2a1c4d2a8582ccee7031f5c6>:0
at Mono.Net.Security.MobileAuthenticatedStream.ProcessHandshake (Mono.Net.Security.AsyncOperationStatus status) [0x0003e] in <0d3e94ab2a1c4d2a8582ccee7031f5c6>: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 <0d3e94ab2a1c4d2a8582ccee7031f5c6>:0
at Mono.Net.Security.AsyncProtocolRequest+d__24.MoveNext () [0x000ff] in <0d3e94ab2a1c4d2a8582ccee7031f5c6>: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 <0d3e94ab2a1c4d2a8582ccee7031f5c6>:0

at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in :0
at Mono.Net.Security.MobileAuthenticatedStream+d__47.MoveNext () [0x00254] in <0d3e94ab2a1c4d2a8582ccee7031f5c6>: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 System.Net.WebSockets.WebSocketHandle+d__24.MoveNext () [0x00199] in <0d3e94ab2a1c4d2a8582ccee7031f5c6>:0

System.Security.Authentication.AuthenticationException

at System.Net.WebSockets.WebSocketHandle+d__24.MoveNext () [0x00391] in <0d3e94ab2a1c4d2a8582ccee7031f5c6>: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 System.Net.WebSockets.ClientWebSocket+d__16.MoveNext () [0x000d1] in <0d3e94ab2a1c4d2a8582ccee7031f5c6>: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.TaskAwaiter.GetResult () [0x00000] in :0
at NativeWebSocket.WebSocket+d__19.MoveNext () [0x0005a] in C:\Users\manuel\development\unityProjects\NativeWebsocket\Assets\Scripts\WebSocket.cs:306

@endel
Copy link
Owner

endel commented Sep 23, 2019

Hi @salinhard, could it be a certificate issue? Can you confirm on this SSL reports if yours is valid? https://www.ssllabs.com/ssltest/

A recurring SSL configuration issue I see (and do myself sometimes) is not using the fullchain.pem certificate in the server-side. (If you're using only cert.pem, you should consider using fullchain.pem instead!)

Cheers

@salinhard
Copy link
Author

Hi @endel
I checked on https://www.ssllabs.com/ssltest/ and my certificate seems valid, I'm also trying to connect to wss://echo.websocket.org and does not work.

Did you try some wss that is working?

@wivanw
Copy link

wivanw commented Nov 12, 2019

Hello. I have a similar error. The certificate is verified and working.
TlsException: Handshake failed - error code: UNITYTLS_INTERNAL_ERROR, verify result: UNITYTLS_X509VERIFY_FLAG_NOT_TRUSTED
Mono.Unity.Debug.CheckAndThrow (Mono.Unity.UnityTls+unitytls_errorstate errorState, Mono.Unity.UnityTls+unitytls_x509verify_result verifyResult, System.String context, Mono.Security.Interface.AlertDescription defaultAlert) (at <0d3e94ab2a1c4d2a8582ccee7031f5c6>:0)
Mono.Unity.UnityTlsContext.ProcessHandshake () (at <0d3e94ab2a1c4d2a8582ccee7031f5c6>:0)
Mono.Net.Security.MobileAuthenticatedStream.ProcessHandshake (Mono.Net.Security.AsyncOperationStatus status) (at <0d3e94ab2a1c4d2a8582ccee7031f5c6>:0)
(wrapper remoting-invoke-with-check) Mono.Net.Security.MobileAuthenticatedStream.ProcessHandshake(Mono.Net.Security.AsyncOperationStatus)
Mono.Net.Security.AsyncHandshakeRequest.Run (Mono.Net.Security.AsyncOperationStatus status) (at <0d3e94ab2a1c4d2a8582ccee7031f5c6>:0)
Mono.Net.Security.AsyncProtocolRequest+d__24.MoveNext () (at <0d3e94ab2a1c4d2a8582ccee7031f5c6>:0)
--- End of stack trace from previous location where exception was thrown ---
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () (at :0)
System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) (at :0)
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) (at :0)
System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) (at :0)
System.Runtime.CompilerServices.ConfiguredTaskAwaitable+ConfiguredTaskAwaiter.GetResult () (at :0)
Mono.Net.Security.AsyncProtocolRequest+d__23.MoveNext () (at <0d3e94ab2a1c4d2a8582ccee7031f5c6>:0)
Rethrow as AuthenticationException: A call to SSPI failed, see inner exception.
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () (at :0)
Mono.Net.Security.MobileAuthenticatedStream+d__47.MoveNext () (at <0d3e94ab2a1c4d2a8582ccee7031f5c6>:0)
--- End of stack trace from previous location where exception was thrown ---
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () (at :0)
System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) (at :0)
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) (at :0)
System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) (at :0)
System.Runtime.CompilerServices.ConfiguredTaskAwaitable+ConfiguredTaskAwaiter.GetResult () (at :0)
System.Net.WebSockets.WebSocketHandle+d__24.MoveNext () (at <0d3e94ab2a1c4d2a8582ccee7031f5c6>:0)
Rethrow as WebSocketException: Unable to connect to the remote server
System.Net.WebSockets.WebSocketHandle+d__24.MoveNext () (at <0d3e94ab2a1c4d2a8582ccee7031f5c6>:0)
--- End of stack trace from previous location where exception was thrown ---
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () (at :0)
System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) (at :0)
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) (at :0)
System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) (at :0)
System.Runtime.CompilerServices.ConfiguredTaskAwaitable+ConfiguredTaskAwaiter.GetResult () (at :0)
System.Net.WebSockets.ClientWebSocket+d__16.MoveNext () (at <0d3e94ab2a1c4d2a8582ccee7031f5c6>:0)
--- End of stack trace from previous location where exception was thrown ---
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () (at :0)
System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) (at :0)
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) (at :0)
System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) (at :0)
System.Runtime.CompilerServices.TaskAwaiter.GetResult () (at :0)
NativeWebSocket.WebSocket+d__19.MoveNext () (at Assets/Scripts/Network/WebSocket.cs:297)
--- End of stack trace from previous location where exception was thrown ---
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () (at :0)
System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) (at :0)
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) (at :0)
System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) (at :0)
System.Runtime.CompilerServices.TaskAwaiter.GetResult () (at :0)
Network.Core.SocketClient+d__7.MoveNext () (at Assets/Scripts/Network/SocketClient.cs:67)
--- End of stack trace from previous location where exception was thrown ---
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () (at :0)
System.Runtime.CompilerServices.AsyncMethodBuilderCore+<>c.b__6_0 (System.Object state) (at :0)
UnityEngine.UnitySynchronizationContext+WorkRequest.Invoke () (at /Users/builduser/buildslave/unity/build/Runtime/Export/UnitySynchronizationContext.cs:115)
UnityEngine.UnitySynchronizationContext:ExecuteTasks()

@endel
Copy link
Owner

endel commented Nov 12, 2019

Hi @wivanw are you also using UWP? On which platform are you getting this error?

@wivanw
Copy link

wivanw commented Nov 12, 2019

The problem was incorrect protocol settings:
webSocketServer.SslConfiguration.EnabledSslProtocols = System.Security.Authentication.SslProtocols.Ssl3;
WebGL platform. Sorry for your time.

@wivanw
Copy link

wivanw commented Nov 12, 2019

In fact, the error was deeper. The solution is described:
https://issuetracker.unity3d.com/issues/error-of-tlsexception-when-system-dot-net-dot-http-dot-dll-is-used-for-http-in-the-editor
Only now my WebSockets have worked correctly.

@endel
Copy link
Owner

endel commented Nov 12, 2019

Thanks for the details @wivanw, this is probably going to be helpful for more people having this issue!

@wivanw
Copy link

wivanw commented Nov 19, 2019

I’ll supplement it. Check if you generated the certificate correctly. Although this stub works on some platforms, it does not work in WebGL. The error was precisely in the fact that the certificate was generated at the wrong level of the domain address. Here is the code that will make it easier for you to find certificate errors:

        ServicePointManager.ServerCertificateValidationCallback =
            (sender, certificate, chain, sslPolicyErrors) =>
            {
                bool isOk = true;
                // If there are errors in the certificate chain, look at each error to determine the cause.
                if (sslPolicyErrors != SslPolicyErrors.None)
                {
                    for (int i = 0; i < chain.ChainStatus.Length; i++)
                    {
                        if (chain.ChainStatus[i].Status != X509ChainStatusFlags.RevocationStatusUnknown)
                        {
                            chain.ChainPolicy.RevocationFlag = X509RevocationFlag.EntireChain;
                            chain.ChainPolicy.RevocationMode = X509RevocationMode.Online;
                            chain.ChainPolicy.UrlRetrievalTimeout = new TimeSpan(0, 1, 0);
                            chain.ChainPolicy.VerificationFlags = X509VerificationFlags.AllFlags;
                            bool chainIsValid = chain.Build((X509Certificate2) certificate);
                            Debug.Log($"ChainIsValid: {chainIsValid}");
                            if (!chainIsValid)
                            {
                                isOk = false;
                            }
                        }
                    }
                }

                return isOk;
            };
        ServicePointManager.CertificatePolicy = new StubCertificatePolicy();
    private enum CertificateProblem : uint
    {
        None = 0x00000000,
        CertExpired = 0x800B0101,
        CertValidityPeriodNesting = 0x800B0102,
        CertRole = 0x800B0103,
        CertPathLenConst = 0x800B0104,
        CertCritical = 0x800B0105,
        CertPurpose = 0x800B0106,
        CertIssuerChaining = 0x800B0107,
        CertMalformed = 0x800B0108,
        CertUntrustedRoot = 0x800B0109,
        CertChaining = 0x800B010A,
        CertRevoked = 0x800B010C,
        CertUntrustedTestRoot = 0x800B010D,
        CertRevocationFailure = 0x800B010E,
        CertCnNoMatch = 0x800B010F,
        CertWrongUsage = 0x800B0110,
        CertUntrustedCa = 0x800B0112,

        //https://docs.microsoft.com/ru-ru/office/troubleshoot/error-messages/generic-trust-failure-(0x800b010b)-error
        GeneralFailureOfTrust = 0x800B010B
    };

    private class StubCertificatePolicy : ICertificatePolicy
    {
        private const bool DefaultValidate = true;

        public bool CheckValidationResult(ServicePoint srvPoint, X509Certificate certificate, WebRequest request,
            int certificateProblem)
        {
            if ((CertificateProblem) certificateProblem != CertificateProblem.None)
            {
                Debug.Log($"Certificate Problem with accessing {request?.RequestUri}");
                Debug.Log($"Problem code 0x{certificateProblem:X8},");
                Debug.LogError(GetProblemMessage((CertificateProblem) certificateProblem));
                return true;
            }

            return DefaultValidate;
        }

        private static string GetProblemMessage(CertificateProblem problem)
        {
            var problemMessage = string.Empty;
            var problemCodeName = Enum.GetName(typeof(CertificateProblem), problem);
            problemMessage = !string.IsNullOrEmpty(problemCodeName)
                ? $"{problemMessage} Certificate problem:{problem}  code:{problemCodeName}"
                : "Unknown Certificate Problem";

            return problemMessage;
        }
    }

@Roar1827
Copy link

Hey @wivanw @endel - thank you for your work in exploring this issue.

I believe I have hit the same problem. When we run our app through unity, or side loaded onto the Oculus Rift it works properly utilizing the NativeWebSocket library. When we build and upload to Oculus and install that way, the Websocket is no longer able to connect.

@wivanw - where did you apply that code in your most recent reply?

Thank you!

@wivanw
Copy link

wivanw commented Apr 27, 2020

Hey @wivanw @endel - thank you for your work in exploring this issue.

I believe I have hit the same problem. When we run our app through unity, or side loaded onto the Oculus Rift it works properly utilizing the NativeWebSocket library. When we build and upload to Oculus and install that way, the Websocket is no longer able to connect.

@wivanw - where did you apply that code in your most recent reply?

Thank you!

It took a long time until we realized that this library is based on another 4 years ago. It is very unstable and unsuitable for product release. We use Best HTTP2 which works like a watch. You can also use the libraries of both the server and the client pulled from Photone engyne assets.

@Roar1827
Copy link

Thank you for the reply @wivanw - I appreciate you taking the time.

@grilledalready
Copy link

The problem was incorrect protocol settings: webSocketServer.SslConfiguration.EnabledSslProtocols = System.Security.Authentication.SslProtocols.Ssl3; WebGL platform. Sorry for your time.

Hi How were you able to add this to code?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants