2
System.Net.WebException: 
java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.'

This is an error that occurs in my VS2022 solution when working with a self signed certificate and Android.

The case is the following:
It is an android app that runs on an local network, with a local https backend service. A certificate has been issued for this service by the domain admin. However, the domain is not an official CA (Certificate Authority). You then have to manually install a CA, via settings.

Part of the solution
What I did to solve this is adding the CA certificates to the Android device (via Settings > Security -> Encryption & Credentials -> Install a Certificate).

The web browser, in the android app, can now successfully access the https site, without warnings.

I still need help with
However the CA store is not accessible via the app unless it is configured via network-security-config: https://developer.android.com/training/articles/security-config#TrustingAdditionalCas

This is something that can be done in the Xamarin days like:

But in MAUI I'm a bit lost, I don't see the right resources, mipmap, etc.

I would like to solve this issue with a one-liner like this:

[assembly: Application(UsesCleartextTraffic = true)]

...which can also be configured via the via network-security-config.

Is there a one-liner or can someone help me out configuring my network-security-config to get the CA store available in a MAUI solution?

promicro
  • 1,280
  • 7
  • 14

3 Answers3

4

After this suggestion of Gerald, "So you can still add a xml folder under Resources (under the Android folder that is)", I finally got it!

enter image description here

Add a network_security_config.xml file, under the Android folder, with:

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <base-config>
        <trust-anchors>
        <!-- Trust preinstalled CAs -->
        <certificates src="system" />
        <!-- Additionaly trusted user added CAs -->
        <certificates src="user"/>
    </trust-anchors>
    </base-config>
</network-security-config>

And in your AndroidManifest.xml add the: android:networkSecurityConfig="@xml/network_security_config" attribute to your Application node.
So, add it to the already existing node, don't add a new one (or else you'll get strange errors):

enter image description here

And the trust anchor exception is gone, but I'm still curious if there is another way - without the network-security-config. ;-)

PS Don't forget to add the CA certificates to the Android device, as stated in the original question.

promicro
  • 1,280
  • 7
  • 14
  • I do that but I get an error when I try to build the maui project in which the certificate is not found in the path raw/ca. I put the certificate in the folder resources\raw of the maui project, not inside the folder of platform\android. – Álvaro García Aug 23 '22 at 15:09
  • in my solution (and problem description) the certificate is not included in the solution. It is installed on the device. I'm not familiar with including CA certs in the solution. I don't think that a right approach, but you might want to start a separated question for that. – promicro Aug 24 '22 at 10:28
  • Finally I could sonve the problem. deleting all the entries related with certificates in the .csproject of the MAUI project. I like this solution because I prefer don't install the CA in the client devices, so if I have to update the CA, only it is needed to build a new version of the application. It is more transparent for the user. However, I have to build a new version, that's right, but the CA rarely will be change in my case. – Álvaro García Aug 24 '22 at 10:33
  • Ok, nice. Just curious, the CA cert will load dynamically when the app runs? Or will the app install it in the device at first run? – promicro Aug 24 '22 at 10:45
0

OK so I see a couple of things here and not sure what you're after exactly so let me go over it one by one.

Let's start with: if you can, please avoid using clear text traffic! ;)

UseClearTextTraffic Attribute

Then, the easy one, you want the [assembly: Application(UsesCleartextTraffic = true)] oneliner. You can totally still do that and actually you can now that throughout the whole project I think. But it makes the most sense in Android.

Notice how the attribute says assembly so it works for the whole assembly anyway and it doesn't really matter where you put it. That is how it typically works. However, in .NET MAUI there is already a [Application] attribute above the MainApplication, so open that and modify it like below.

namespace MauiAndroidClearText;

[Application(UsesCleartextTraffic = true)]
public class MainApplication : MauiApplication
{
   // Your code
}

Network Security Config

Basically your separate Android project is now under the Platforms\Android folder. Everything you put there, even if it's not there by default, will still behave as it was in a separate Android project.

So you can still add a xml folder under Resources (under the Android folder that is), then add the network_security_config.xml file with:

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
  <domain-config cleartextTrafficPermitted="true">
    <domain includeSubdomains="true">10.0.2.2</domain> <!-- Debug port -->
    <domain includeSubdomains="true">xamarin.com</domain>
  </domain-config>
</network-security-config>

And in your AndroidManifest.xml add the android:networkSecurityConfig="@xml/network_security_config" attribute to your Application node.

See a full sample here: https://github.com/jfversluis/MauiAndroidClearText

Gerald Versluis
  • 30,492
  • 6
  • 73
  • 100
  • I'm not after CleartextTraffic, but another Network-security-config item: trust-anchors. And if possible with an oneliner ;-) – promicro May 17 '22 at 20:19
0

How you asked how you could trust a self signed root certificate (self signed CA) without needed to install in the device, I will share the code.

I am using a MAUI project that use .NET 6.

In the MAUI project, in platform/android/resources/raw, you have to copy your ca.crt certificate. It can have .crt or .pem extension. In my case, I use .crt.

The raw folder is not created by default, so you have to create this folder.

In platform/android/resources, you have to create the folder xml, so you will have platform/android/resources/xml folder. In this folder, add a new xml file, with this name: network_security_config.xml.

This file set the certificates in which you want to trust.

The code of this file is:

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
  <domain-config>
    <!--NOTA: el subdominio es necesario porque si no no se podrá instalar-->
    <domain includeSubdomains="true">192.168.1.200</domain>
    <trust-anchors>
      <certificates src="@raw/ca"/>
    </trust-anchors>
  </domain-config>
</network-security-config>

The certificate is ca, with no extension, if not, it will give an error when you try to compile.

You have to include a subdomain, in my case, the IP of the server, because I am not inside a domain. If you don't set this, when you try to debug it doesn't start, gives problems.

You have to edit the file AndroidManifest.xml, this exists. The code of my file is this:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
    <application android:allowBackup="true" android:icon="@mipmap/appicon" android:roundIcon="@mipmap/appicon_round" android:supportsRtl="true"
               android:networkSecurityConfig="@xml/network_security_config"></application>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.INTERNET" />
</manifest>

You only need to add android:networkSecurityConfig="@xml/network_security_config" in the application entry. This tells that you will config the network security.

That's all, you can build the project and then the application will include the CA in the trusted certificates, so you don't need to install the certificate in the device.

You can also see the following documentation for more information:

https://developer.android.com/training/articles/security-config

If you have some question, tell me and I will try tohelp.

Álvaro García
  • 18,114
  • 30
  • 102
  • 193
  • Interesting approach thanks for sharing! – promicro Aug 24 '22 at 11:18
  • It is the same solution than yours, but in your case you trust in the system certificates, instead to tell which certificate you want to trust outside the system certificates. If you set the certificate, can't avoid to install to system and no trust in the system certificates. – Álvaro García Aug 24 '22 at 11:20