Http request failure on Android Emulator/device

Hi,

following scenario:

Server: Custom Data Abstract on a Rasperry Pi under Mono connected to a revers proxy with openvpn (for now a WinInetHttpClientChannel)

Client: Xamarin.Forms PCL for iOS, Android and UWP connected to the reverse proyy with HTTPS. The https request to the reverse proxy is passed via http to the Data Abstract server on the Raspi.

This is my Client Login Method

    public async Task<Boolean> LogOnAsync(String userId, String password)
    {
        if (String.IsNullOrEmpty(userId))
        {
            this.IsLoggedOn = false;

            return await Task.FromResult(false);
        }

        bool result = false;
        try
        {
            result = await (new RemObjects.DataAbstract.Server.BaseLoginService_AsyncProxy(this.fMessage, this.fClientChannel, "LoginService")).LoginExAsync(String.Format(DataModule.ConnectionString, userId, password));
            
        }
        catch (Exception ex)
        {
            this.ErrorCode = ex.Message;
            System.Diagnostics.Debug.WriteLine("LOGIN Error: " + ex.Message);
        }
        this.IsLoggedOn = true;
        return result;
    }

This works fine on iOS and UWP(Desktop and Mobile) also Data Access, but not on Android (Marshmallow).

But direct Access via HTTP to the Raspi works fine on Android too.

I get this error: “SecureChannelFailure (The authentication or decryption has failed.)”

StackTrace:

at RemObjects.SDK.WinInetHttpClientChannel+AsyncState.get_Message () [0x0004e] in c:\ci\b\rofx\932\RemObjects SDK for .NET\Source\RemObjects.SDK\ClientChannels\WinInetHttpClientChannel.cs:296
at RemObjects.DataAbstract.Server.BaseLoginService_AsyncProxy.EndLoginEx (System.IAsyncResult __AsyncResult) [0x00000] in c:\CI\b\rofx\932\Data Abstract for .NET\Source\RemObjects.DataAbstract.Server\DataAbstract4_Intf.pas:1868
at System.Threading.Tasks.TaskFactory1[TResult].FromAsyncCoreLogic (System.IAsyncResult iar, System.Func2[T,TResult] endFunction, System.Action1[T] endAction, System.Threading.Tasks.Task1[TResult] promise, System.Boolean requiresSynchronization) [0x00014] in /Users/builder/data/lanes/3511/501e63ce/source/mono/mcs/class/referencesource/mscorlib/system/threading/Tasks/FutureFactory.cs:550
— End of stack trace from previous location where exception was thrown —
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in /Users/builder/data/lanes/3511/501e63ce/source/mono/mcs/class/referencesource/mscorlib/system/runtime/exceptionservices/exceptionservicescommon.cs:143
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) [0x00047] in /Users/builder/data/lanes/3511/501e63ce/source/mono/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:187
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) [0x0002e] in /Users/builder/data/lanes/3511/501e63ce/source/mono/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:156
at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) [0x0000b] in /Users/builder/data/lanes/3511/501e63ce/source/mono/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:128
at System.Runtime.CompilerServices.TaskAwaiter`1[TResult].GetResult () [0x00000] in /Users/builder/data/lanes/3511/501e63ce/source/mono/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:357
at PMWconnect.DataModule+d__36.MoveNext () [0x0011a] in C:\Users\Helmut\documents\visual studio 2015\Projects\PMWconnect\DataModule.cs:126

ex.InnerException.StackTrace:

at Mono.Security.Protocol.Tls.SslStreamBase.EndRead (System.IAsyncResult asyncResult) [0x00051] in /Users/builder/data/lanes/3511/501e63ce/source/mono/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/SslStreamBase.cs:883
at Mono.Net.Security.Private.LegacySslStream.EndAuthenticateAsClient (System.IAsyncResult asyncResult) [0x00011] in /Users/builder/data/lanes/3511/501e63ce/source/mono/mcs/class/System/Mono.Net.Security/LegacySslStream.cs:475
at Mono.Net.Security.Private.LegacySslStream.AuthenticateAsClient (System.String targetHost, System.Security.Cryptography.X509Certificates.X509CertificateCollection clientCertificates, System.Security.Authentication.SslProtocols enabledSslProtocols, System.Boolean checkCertificateRevocation) [0x00000] in /Users/builder/data/lanes/3511/501e63ce/source/mono/mcs/class/System/Mono.Net.Security/LegacySslStream.cs:445
at Mono.Net.Security.MonoTlsStream.CreateStream (System.Byte[] buffer) [0x0004e] in /Users/builder/data/lanes/3511/501e63ce/source/mono/mcs/class/System/Mono.Net.Security/MonoTlsStream.cs:106

Any ideas ??

Regards
Helmut

Hello

At first - is this a self-signed certificate? By default it will be rejected. Have you added a code to handle such certificate?

System.Net.ServicePointManager.ServerCertificateValidationCallback = 
                                            ServerCertificateValidationCallback;
...
private static bool ServerCertificateValidationCallback(object sender, 
                                                        X509Certificate certificate, 
                                                        X509Chain chain, 
                                                        SslPolicyErrors sslPolicyErrors)
{
    // Very simple certificate hash check
    return certificate.GetCertHashString() != "BED6...E5D0";
}

Also please check the linker settings. According to this thread https://forums.xamarin.com/discussion/10405/the-authentication-or-decryption-has-failed-in-the-web-request similar issue can be caused by build optimizations.

Regards

Hello Anton,

This works fine on IOS and Windows, but not on Android. I can’t Login. But if i call the DA server inside my App like (xxx = placeholder)
WebView webView = new WebView
{
Source = new UrlWebViewSource
{
Url = “https://xxxx.de/bin”,
},
VerticalOptions = LayoutOptions.FillAndExpand
};
the DA Server is responding correctly on all plattforms, Android too.
Is this a RemObjects issue/bug ?
Thanks and Regards

Helmut Lubik

So far it looks like some issues with SSL/TLS in Mono/Xamarin.

https://bugzilla.xamarin.com/show_bug.cgi?id=42805

After all the failing code just sends a POST request out via an HttpWebRequest instance and lets the system do all the SSL stuff. And then it fails.

As a workaround try to use a client channel described here: HttpClient-based Client Channel for Xamarin platforms (and other platforms supported via PCL)

Seems these parts of Mono should use newer SSL code paths

Hi Anton,

i tried your workaround, but the same issue.

Regards
Helmut

Ok. Given you did add the http certificate check handler, could you provide more information on the exception?
There should be nested InnerException - would be nice to see their messages and stacktraces, esp when the new ClientChannel is used.

Hi Anton,

i solved it. It’s a Xamarin.Android issue. Android sends a cipher which was not recogniced by the relayserver.

As a workaround, I added the strongest cipher (which is sending by Android) to the relayserver and it works now.

Next step is to work with certificates on DA Server.

Thanks and Regards

Helmut

Could you post the solution here? Would greatly help if someone else runs into the same issue too.

As i described above, I added this Cipher suite (TLS_RSA_WITH_AES_256_CBC_SHA (0x35) ) to my proxy server