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

TLS 1.2 in android option (it does not exists in VS Preview 17.1) #5604

Closed
thevirtualdj opened this issue Mar 28, 2022 · 29 comments
Closed

TLS 1.2 in android option (it does not exists in VS Preview 17.1) #5604

thevirtualdj opened this issue Mar 28, 2022 · 29 comments
Assignees
Labels
area-tooling XAML & C# Hot Reload, XAML Editor, Live Visual Tree, Live Preview, Debugging partner/android Issues for the Android SDK proposal/open

Comments

@thevirtualdj
Copy link

Description

Where to set TLS 1.2 in android options (it does not exists in VS Preview 17.1)
Can find it in Xamarin but no option to set it on .NET MAUI. project properties.
https://docs.microsoft.com/en-us/xamarin/cross-platform/app-fundamentals/transport-layer-security?tabs=windows
Is there an option in VS somewhere (really got into it but cannot find it)?

And not only one for now.. Please advise.

https://docs.microsoft.com/en-us/answers/questions/658469/use-httpclient-in-maui.html

Public API Changes

TLS 1.2 in android option (it does not exists in VS Preview 17.1)

Intended Use-Case

TLS 1.2 in android option (it does not exists in VS Preview 17.1)

@jonathanpeppers
Copy link
Member

@thevirtualdj these settings don't exist in .NET 6, so some of these settings actually need to be removed from the Project Options pages. We're tracking this internally here.

What are you looking to do exactly? Do the default values work for your case? Thanks!

@Steven-L-42
Copy link

I need this setting too. Cant get data with my RestApi (RestSharp) while running Android. it works on Windows machine, but on Android not.

@jonathanpeppers
Copy link
Member

@ShiiikK can you file a new issue?

The issue here is about the setting -- which is actually not needed. .NET 6 supports TLS 1.2, and you don't need a dropdown box to enable it.

@logikonline
Copy link

@jonathanpeppers This is not true, I believe. Here is an example.

NEO provides seed servers to connect too. This is one of them https://seed1t5.neo.org:20332

If I connect using wither WIndows or iOS, it works correctly (using either HTTP or https since some have said it requires one or the other) But with Android, testing on an Android 11 and Android 12 devices - we get the following errors:

HTTPS yields "System.Net.WebException: Unable to parse TLS packet header
---> Javax.Net.Ssl.SSLException: Unable to parse TLS packet header"

HTTP yields "System.Net.WebException: Cleartext HTTP traffic to seed1t5.neo.org not permitted
---> Java.IO.IOException: Cleartext HTTP traffic to seed1t5.neo.org not permitted"

The full stack trae for the failure to prse the TLS packet is below BUT I have seen this in the past with XF - and it was a failure of the TLS 1.2 not being selected.

at Java.Interop.JniEnvironment.InstanceMethods.CallVoidMethod(JniObjectReference instance, JniMethodInfo method, JniArgumentValue* args) in /Users/runner/work/1/s/xamarin-android/external/Java.Interop/src/Java.Interop/Java.Interop/JniEnvironment.g.cs:line 11884
at Java.Interop.JniPeerMembers.JniInstanceMethods.InvokeAbstractVoidMethod(String encodedMember, IJavaPeerable self, JniArgumentValue* parameters) in /Users/runner/work/1/s/xamarin-android/external/Java.Interop/src/Java.Interop/Java.Interop/JniPeerMembers.JniInstanceMethods_Invoke.cs:line 17
at Javax.Net.Ssl.HttpsURLConnectionInvoker.Connect() in /Users/runner/work/1/s/xamarin-android/src/Mono.Android/obj/Release/net6.0/android-31/mcw/Javax.Net.Ssl.HttpsURLConnection.cs:line 433
at Xamarin.Android.Net.AndroidMessageHandler.<>c__DisplayClass125_0.b__0() in /Users/runner/work/1/s/xamarin-android/src/Mono.Android/Xamarin.Android.Net/AndroidMessageHandler.cs:line 450
at System.Threading.Tasks.Task.InnerInvoke()
at System.Threading.Tasks.Task.<>c.<.cctor>b__272_0(Object obj)
at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)
--- End of stack trace from previous location ---
at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread)
--- End of stack trace from previous location ---
at Xamarin.Android.Net.AndroidMessageHandler.DoProcessRequest(HttpRequestMessage request, URL javaUrl, HttpURLConnection httpConnection, CancellationToken cancellationToken, RequestRedirectionState redirectState) in /Users/runner/work/1/s/xamarin-android/src/Mono.Android/Xamarin.Android.Net/AndroidMessageHandler.cs:line 502
at Xamarin.Android.Net.AndroidMessageHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) in /Users/runner/work/1/s/xamarin-android/src/Mono.Android/Xamarin.Android.Net/AndroidMessageHandler.cs:line 375
--- End of managed Javax.Net.Ssl.SSLException stack trace ---
javax.net.ssl.SSLException: Unable to parse TLS packet header
at com.android.org.conscrypt.ConscryptEngine.unwrap(ConscryptEngine.java:807)
at com.android.org.conscrypt.ConscryptEngine.unwrap(ConscryptEngine.java:747)
at com.android.org.conscrypt.ConscryptEngine.unwrap(ConscryptEngine.java:712)
at com.android.org.conscrypt.ConscryptEngineSocket$SSLInputStream.processDataFromSocket(ConscryptEngineSocket.java:858)
at com.android.org.conscrypt.ConscryptEngineSocket$SSLInputStream.-$$Nest$mprocessDataFromSocket(Unknown Source:0)
at com.android.org.conscrypt.ConscryptEngineSocket.doHandshake(ConscryptEngineSocket.java:241)
at com.android.org.conscrypt.ConscryptEngineSocket.startHandshake(ConscryptEngineSocket.java:220)
at com.android.okhttp.internal.io.RealConnection.connectTls(RealConnection.java:196)
at com.android.okhttp.internal.io.RealConnection.connectSocket(RealConnection.java:153)
at com.android.okhttp.internal.io.RealConnection.connect(RealConnection.java:116)
at com.android.okhttp.internal.http.StreamAllocation.findConnection(StreamAllocation.java:186)
at com.android.okhttp.internal.http.StreamAllocation.findHealthyConnection(StreamAllocation.java:128)
at com.android.okhttp.internal.http.StreamAllocation.newStream(StreamAllocation.java:97)
at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:289)
at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:232)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:465)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:131)
at com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.connect(DelegatingHttpsURLConnection.java:90)
at com.android.okhttp.internal.huc.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:30)

@logikonline
Copy link

@jonathanpeppers please reopen the issue.

@jonathanpeppers
Copy link
Member

@logikonline can you file a new issue here: https://github.com/xamarin/xamarin-android/issues

Link to it here, thanks!

This issue is about these dropdowns:

image

And we don't have these settings anymore in .NET 6+.

@logikonline
Copy link

@jonathanpeppers I am sorry, I see the issue. android:usesCleartextTraffic="true" needed to be specified for Android to allow the HHTP traffic.

Sorry, too much coffee this morning

@thevirtualdj
Copy link
Author

I set it in AndroidManifest in MAUI App like: image
And still the same error.

@ghost
Copy link

ghost commented Sep 22, 2022

Hello lovely human, thank you for your comment on this issue. Because this issue has been closed for a period of time, please strongly consider opening a new issue linking to this issue instead to ensure better visibility of your comment. Thank you!

@logikonline
Copy link

@thevirtualdj - if give me a url of the image, I may be able to assist. It works for me.

My client initializes for the HTTP is as follows:

httpClient = new System.Net.Http.HttpClient(new HttpClientHandler() { AutomaticDecompression = System.Net.DecompressionMethods.GZip });

I also set a few default headers

@thevirtualdj
Copy link
Author

thevirtualdj commented Sep 26, 2022

Trouble is that this is Microsoft.Data.SqlClient 5.0 not HTTPClient.

It will fail in Connection Open on MAUI app.. you can try it.

using System.Collections.ObjectModel;
using System.Data;
using System.Data.Common;
using Microsoft.Data.SqlClient;
//using Microsoft.Data.SqlClient;

namespace MySQLTest
{
public static class TringSQL
{
public static String GetStringFromExternClass()
{
return "Test string!";
}
public static String GetStringFromDB()
{

        string connectionString = "Server =192.168.0.253,1433; Database=INSERTYOURDBHERE; User Id =sa; Password=INSERTYOURPASSHERE;Encrypt=false;TrustServerCertificate=true;";
        //string connectionString = @"Server=192.168.0.15,1433;Database=INSERTYOURDBHERE;User Id=sa;Password=INSERTYOURPASSHERE;integrated security=True;Encrypt=True;TrustServerCertificate=True;MultiSubnetFailover=true";
        //string connectionString = @"Data Source =192.168.0.15,1433;Database=INSERTYOURDBHERE; UID=sa; PWD=INSERTYOURPASSHERE; Integrated Security=true;Encrypt=false; Connection Timeout = 30;TrustServerCertificate=true;";
        string sql = "select UserName from [dbo].[OPERATORS] where OperatorId = 13";
        string ret = "";
        SqlConnection Connection = new SqlConnection(connectionString);
        
        ConnectionState ps = Connection.State;
        var tbl = new DataTable();
        var cmd = new SqlDataAdapter(sql, Connection);
        cmd.SelectCommand.CommandTimeout = 0;
        try
        {
            if (ps != ConnectionState.Open)
                //Here it will fail to open TLS connection!
                Connection.Open();
            cmd.Fill(tbl);
        }
        catch (DbException ex)
        {
            //error message is:
            //A connection was successfully established with the server, but then an error
            //occurred during the pre-login handshake. (provider: TCP Provider, error: 35 - An internal exception was caught)
            ret = ex.Message;
        }
        finally
        {
            cmd = default;
            if (ps == ConnectionState.Closed)
                Connection.Close();
        }
        if (tbl.Rows.Count > 0)
        {
            ret = tbl.Rows[0][0].ToString();
        }
        return ret;
    }
}

}

@logikonline
Copy link

@thevirtualdj sorry man. I would never approach direct SQL connection with apps anymore. I would expose a RESTful interface. I suppose it is also why they always ask for a github sample app to be attached to tickets. I hope you find a workaround although you may want to undertake my approach

@jovanmhn
Copy link

These threads always end the same way, don't use direct SQL connections... Maybe we should tell MS that none of these classes should be allowed to exist at all inside MAUI projects? Isn't the whole point of .NET that everything works everywhere?
If I wanted to go the traditional way, I might as well use languages/technologies that are proven and tested, and go back to some good ol Java on Android Studio...
Anyway...
The same issue described by thevirtualdj makes EFCore non usable in MAUI android, which is why I'm here

@logikonline
Copy link

logikonline commented Sep 26, 2022

@jovanmhn I use SQLite in my XF/Maui apps exclusively because it works cross-platform, but I do not leave the device for those calls. So the connections are to a file and not cross the wire. I have used this tech since before Microsoft acquired it, and it is solid, but there are design patterns that I exclusively use to achieve that. Sorry I could not be of more assistance.

@jovanmhn
Copy link

@logikonline The main attraction of using .NET to create mobile apps for me is the ability to use powerful tools (such as Entity Framwork) that make it possible to manipluate complex (several hundred tables) SQL databases, have the ability to track changes, commit batches in the correct order without too much pain, use stored procedures, fucntions and all the good stuff, without too much hassle
How I aquire my credentials, how my SQL server is set up, and where, if at all, I keep my credentials is a completely different issue which should not be brought up in these discussions.

Doing this by through REST APIs as a "middle-man", while of course possible, makes the project considerably more complex

But that is all besides the point, we have code that works on one enviroment (possibly 2, havent tested iOS), but breaks on Android, and, in my opinion, is clearly an issue to be dealt with if we want to call MAUI true multi platform tech

@thevirtualdj
Copy link
Author

I agree with @jovanmhn . We think that this issue for some small side apps (warehouse mgm, local apps that connect to on-premise SQL servers are still a big piece of cake. So this issue with clear text traffic on android should be solved for these apps.
TLS 1.2 is not a problem for us to implement but we are facing so much issues to get it working on android right now.

Currently we are trying to implement clear text traffic but no success.

In some threads they say you should use: android:usesCleartextTraffic="true".
Tried it, no success.
Some of them says implement: network_security_config.xml in Resources\xml folder or \Platform\Android\xml folder and add it to AndroidManifest.xml like: android:networkSecurityConfig="@xml/network_security_config"
Tried it, have an issue that VS linker does not see the file at all: resource xml/network_security_config (aka com.companyname.mysqltest:xml/network_security_config) not found.

With TLS 1.2 no success to:

dotnet/SqlClient#1662

Tried everything in this thread but main issue is that it is tied to DOMAIN that is not so useful at all:
"set the commonName to the ServerName like this: [PCName].[Domain].local"

So if anyone has any idea pls advise.

We would really like to use MAUI and start developing our apps on it with SQL Server support.

Thank you in advance.

@logikonline
Copy link

logikonline commented Sep 27, 2022

@thevirtualdj If you shared a repo, I would give you some time to help resolve it. I presently use this on very large projects (north of 200+ tables @jovanmhn) with much success, but we will have to disagree around approaches. I do see value in EF, but I chose to use a different ORM and the approach does require some middle work, although the payoff is better IMO.

If you saw above, my error posted in the stacktrace reported clearText issue. I haven't seen your stacktrace so it likely isn't applicable to the same outcome. I can tell you, Maui is finicky around getting everything just right to compile/function. I personally preferred the different projects in XF but I can see their direction and once it is flushed out, it hopefully will grow on me. The ability to edit the project file is better IMO and the new handlers are nicer.

If I were you, I would post a repo where it can be reproduced. Then I can give you some constructive feedback and possibly a workaround.

@thevirtualdj
Copy link
Author

Greetings,

I do not agree with you. Direct access to SQL server is a great feature. Sure it needs to be encrypted on public networks. But for small usage and private nets it is indeed a great feature.
For generic purposes we HAVE to use direct access.
But never mind.
Here is the repo: https://github.com/thevirtualdj/MAUISqlTestApp

Thank in advance for your help. It is not a problem to encrypt the connection but now I am having a trouble to export SQL Server certificate and use it in this app.
But in some cases for other users it would be good to have plain text.
But for my case I really need a direct access (never mind even encrypted is fine, we will use certificates)

@jovanmhn
Copy link

I would follow these 2 threads, as I can see it got narrowed down to the sql client

dotnet/SqlClient#1656
dotnet/SqlClient#1662

although it could be a wider android certificate issue

@thevirtualdj
Copy link
Author

I would follow these 2 threads, as I can see it got narrowed down to the sql client

dotnet/SqlClient#1656 dotnet/SqlClient#1662

although it could be a wider android certificate issue

Trouble with first possible solution is "set the commonName to the ServerName like this: [PCName].[Domain].local".
We have to set up a domain to get "local" connection.
Cannot use IP addresses than.

Second thread (I tried it all but it gets to first thread, you have to have two way cert that has to have a domain).
And this TLS option was cut out of VS in MAUI.

So blind street there.. No success.

@jovanmhn
Copy link

I found no adequate solution either, but I would assume that when it happens, it will be anounced in these threads.

@thevirtualdj
Copy link
Author

I found no adequate solution either, but I would assume that when it happens, it will be anounced in these threads.

I hit the subscribe button but all of these issues are just closed and moved around. I opened one here on MAUI for this and they just closed it like that is not MAUI problem. So.. will check those issues.

@janseris
Copy link

I would follow these 2 threads, as I can see it got narrowed down to the sql client

dotnet/SqlClient#1656 dotnet/SqlClient#1662

although it could be a wider android certificate issue

Yes this is a much wider tls android issue (I am author of these SQL Client MAUI issues)

@thevirtualdj
Copy link
Author

thevirtualdj commented Sep 28, 2022

Managed to solve it with cert and IP address.
How?

  1. Create a cert with powershell for your IP address: New-SelfSignedCertificate -certstorelocation cert:\localmachine\my -dnsname '192.168.0.15','localhost' -KeySpec KeyExchange -FriendlyName '192.168.0.15' -NotAfter (Get-Date).AddMonths(240)
    (Will work with any IP address of your sql server later).

  2. Set your cert in SQL Server Configuration manager.

  3. Export that certificate as Base-64 encoded X.509 (.CER) file.

  4. Import that cer in Platforms\Android\Resources\raw folder (if it does not exist create it).

  5. In Platforms\Android\xml folder create nsc.xml (for me was not working if I name it network_security_config.xml)
    with content: (change the data ofc IP and domain names and @raw/certname mine was called razvoj1.cer in \Platforms\Android\Resources\raw folder and my SQL server IP was 192.168.0.15 )

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
	<base-config cleartextTrafficPermitted="true">
		<trust-anchors>
			<certificates src="system" />
			<certificates src="user" />
			<certificates src="@raw/razvoj1"/>
		</trust-anchors>
	</base-config>
    <domain-config cleartextTrafficPermitted="true">
		<domain includeSubdomains="true">localhost</domain>
		<domain includeSubdomains="true">192.168.0.15,1433</domain>
		<domain includeSubdomains="true">192.168.0.15</domain>
        <domain includeSubdomains="true">RAZVOJ1</domain>
		<domain includeSubdomains="true">RAZVOJ1.localhost</domain>
		<trust-anchors>
			<certificates src="system" />
			<certificates src="user" />
			<certificates src="@raw/razvoj1"/>
		</trust-anchors>
    </domain-config>
</network-security-config>
  1. In AndroidManifest add android:usesCleartextTraffic="true" and android:networkSecurityConfig = "@xml/nsc" to application tag :
<?xml version="1.0" encoding="utf-8"?>
<manifest android:targetSandboxVersion="1" xmlns:android="http://schemas.android.com/apk/res/android">
	<application android:allowBackup="true" 
				 android:icon="@mipmap/appicon" 
				 android:roundIcon="@mipmap/appicon_round"
				 android:usesCleartextTraffic="true"
			         android:networkSecurityConfig="@xml/nsc"
				 android:supportsRtl="true"></application>
	<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
	<uses-permission android:name="android.permission.INTERNET" />
</manifest>
  1. Use this connection string:
    string connectionString = @"Server=192.168.0.15,1433;Database=YOURDB;User Id=sa;Password=YOURPASS;Persist Security Info=True;Encrypt=True;TrustServerCertificate=True";

  2. You should be able to open SQLConnection with Microsoft.Data.SQLClient 5.0.0 and .net 7 MAUI

@jovanmhn
Copy link

its looks more or less like the solution lcheunglci posted in one of the mentioned threads

its ok for testing and development, obviously cant expect random people to install random certs on their phones

@thevirtualdj
Copy link
Author

thevirtualdj commented Sep 28, 2022

its looks more or less like the solution lcheunglci posted in one of the mentioned threads

its ok for testing and development, obviously cant expect random people to install random certs on their phones

This is actually not bad because cert is embedded in your app. For now at least we have some solution (was afraid that this will not work without domain, but it does).
And yes lcheunglci was a great help. Thank you lcheunglci.

@lcheunglci
Copy link

its looks more or less like the solution lcheunglci posted in one of the mentioned threads
its ok for testing and development, obviously cant expect random people to install random certs on their phones

This is actually not bad because cert is embedded in your app. For now at least we have some solution (was afraid that this will not work without domain, but it does). And yes lcheunglci was a great help. Thank you lcheunglci.

I'm glad it helped, you're welcome 👍

@logikonline
Copy link

its looks more or less like the solution lcheunglci posted in one of the mentioned threads
its ok for testing and development, obviously cant expect random people to install random certs on their phones

Sorry for the delayed reply, I was impacted by Hurricane Ian & had to evacuate. It did work on my Azure server with .NET 6.0 but it appears you are solid now.

I didn't have to create a cert for my device, being that Azure provides one. As a general development environment, which allows you to not worry about certs when debugging on Android (Android is very picky) - I always use NGROK since that can be set up to serve any IP with their SSL to any server. I have used this for 3 years and can vouch it works.

@ghost
Copy link

ghost commented Oct 6, 2022

Hello lovely human, thank you for your comment on this issue. Because this issue has been closed for a period of time, please strongly consider opening a new issue linking to this issue instead to ensure better visibility of your comment. Thank you!

@ghost ghost locked as resolved and limited conversation to collaborators Nov 5, 2022
@Eilon Eilon added the area-tooling XAML & C# Hot Reload, XAML Editor, Live Visual Tree, Live Preview, Debugging label Jan 20, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-tooling XAML & C# Hot Reload, XAML Editor, Live Visual Tree, Live Preview, Debugging partner/android Issues for the Android SDK proposal/open
Projects
None yet
Development

No branches or pull requests