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

Cannot connect to NextCloud with LetsEncrypt SSL certificate #111

Closed
martinstoeckli opened this issue Nov 8, 2021 · 11 comments
Closed

Cannot connect to NextCloud with LetsEncrypt SSL certificate #111

martinstoeckli opened this issue Nov 8, 2021 · 11 comments
Assignees
Labels
bug Something isn't working

Comments

@martinstoeckli
Copy link
Owner

martinstoeckli commented Nov 8, 2021

I got the report that SilentNotes on Android devices cannot connect to NextCloud instances anymore, even when they worked before and no settings have changed meanwhile (Windows installations are not affected). After some debugging and research I found out that this is caused by the LetsEncrypt SSL certificate, for an indepth explanation see:
dotnet/android#6351 (comment)

In short:
Since September 29th 2021 the "DST Root CA X3" certificate expired, it was used by LetsEncrypt, so older devices/os/libraries which do not know about LetsEncrypt's own root certificate, can validate the certificate anyway.

Workaround:
A workaround was implemenented, so that NextCloud users can connect to their NextCloud instance, even if the issue can currently not be solved in a satisfying way (scroll down to #111 (comment) for more information). WebDav connections now have a new option to accept invalid certificates, this allows to connect to NextCloud and /e/ cloud services. Unsafe SSL connections are not recommended, but since the content is always end-to-end encrypted anyway, it is justifiable.

@martinstoeckli martinstoeckli added the bug Something isn't working label Nov 8, 2021
@martinstoeckli martinstoeckli self-assigned this Nov 8, 2021
@martinstoeckli
Copy link
Owner Author

martinstoeckli commented Nov 8, 2021

There is a workaround which can be used, but it is not a final solution and cannot be built in into SilentNotes. You can do it on your own risk, should you encounter problems in other apps, it is possible to reactivate it any time.

Navigate to the Android settings:
Settings/Security & location/Advanced/Encryption & Credentials/Trusted credentials

Deactivate this old root certificate:
Digital Signature Trust Co.

Screenshot_1636365504

@martinstoeckli
Copy link
Owner Author

martinstoeckli commented Apr 2, 2022

Maybe the problem can be overcome by switching the HttpClient to the native Android implementation: https://docs.microsoft.com/en-us/xamarin/android/app-fundamentals/http-stack?tabs=windows , this will be considered for the next version of SilentNotes.

A quick test with an ecloud (nextcloud of the /e/ foundation) still gave this error, so switching the option in the Android project doesn't seem to switch the used implementation:

Ssl error:1000007d:SSL routines:OPENSSL_internal:CERTIFICATE_VERIFY_FAILED
at /Users/builder/jenkins/workspace/archive-mono/2020-02/android/release/external/boringssl/ssl/handshake_client.c:1132

@martinstoeckli
Copy link
Owner Author

martinstoeckli commented Apr 11, 2022

Switching to the native Android implementation indeed solves the problem with the SSL certificates, unfortunately the Java implementation of Android does not support the http method "PROPFIND", which is required by WebDav requests. So either we use the default HttpClient implementation (boring-ssl library) which cannot handle the expired SSL certificate, or we use the native Java HttpClient implementation, which cannot send "PROPFIND" requests.

The code below shows a possible native Android implementation, which raises the exception:

Java.Net.ProtocolException: Expected one of [OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, PATCH] but was PROPFIND

public class SilentNotes.Android.Startup
{
    public static void InitializeApplication(Activity rootActivity, ActivityResultAwaiter rootActivityResultWaiter)
    {
        ...
        ICloudStorageClientFactory cloudStorageClientFactory = Ioc.GetOrCreate<ICloudStorageClientFactory>();
        cloudStorageClientFactory.RegisterHttpMessageHandlerFactory(() => new Xamarin.Android.Net.AndroidClientHandler());
    }
}

public class CloudStorageClientFactory : ICloudStorageClientFactory
{
    public void RegisterHttpMessageHandlerFactory(Func<HttpMessageHandler> factory)
    {
        FlurlHttp.Configure(config => config.HttpClientFactory = new PlatformHttpClientFactory(factory));
    }

    public class PlatformHttpClientFactory : DefaultHttpClientFactory
    {
        private readonly Func<HttpMessageHandler> _factory;

        public PlatformHttpClientFactory(Func<HttpMessageHandler> factory)
        {
            _factory = factory;
        }

        public override HttpMessageHandler CreateMessageHandler()
        {
            return _factory();
        }
    }
}

See also: skazantsev/WebDavClient#59 . The circumvention with the X-HTTP-Method-Override property didn't work neither, because the server doesn't accept it.

@martinstoeckli
Copy link
Owner Author

A workaround was built in, but the issue is kept open, for when the development environment allows to solve the issue properly.

@pkoevesdi
Copy link

pkoevesdi commented Jul 13, 2022

I couldn't connect via SSL to my nextcloud server too. A generic Apache WebDAV server works, only with either of the builtin workaround or the workaround here. I'm stuck because I don't get any meaningful error message, see #174.
Both are Let's Encrypt SSLed.
What URL do I have to set for nextcloud? the main URL, usually example.com/nextcloud?

@martinstoeckli
Copy link
Owner Author

@pkoevesdi - Instead of the workaround it should now be possible to tick the option "Accept unsafe certificates".

It depends on your configuration what the url looks like, to get more information you can setup a WebDav connection with Windows Explorer (not Internet Explorer) if you have this OS available. The same credentials should work with SilentNotes too.

@pkoevesdi
Copy link

I'm aware of the "Accept unsafe certificates", which was also classified as a workaround here. But as said, on my generic webdav both workarounds work, on my nextcloud none.

So, I seem to have a different problem there, sorry for looking for support here, maybe, with the knowledge now, it shows up as the wrong place.

I can connect to nextcloud via webdav, which is the url example.com/nextcloud/remote.php/dav/files/USERNAME/
But there are also apps out there, which connect to example.com/nextcloud and then offer me the nextcloud content to choose the location from.
Of which type is silentnotes?
If of first type (connecting to the long webdav-URL), as I assume from Your last comment, then, what is the difference between choosing "webdav" or "nextcloud" connection?

@martinstoeckli
Copy link
Owner Author

On a test account I had to use an url of this form: https://example.com/nextcloud/remote.php/dav/files/USERNAME maybe in your case it could be just http:// .

There is no diference, the "Nextcloud WebDav" connection was only added to make it more recognizeable, so a user can find it easier.

If the problem persists and you can access the path with other tools, I would be interested in a test account, I would then try to debug the problem.

@pkoevesdi
Copy link

On a test account I had to use an url of this form: https://example.com/nextcloud/remote.php/dav/files/USERNAME maybe in your case it could be just http:// .

Nope, I rewrite http to https on the server.
But it works, now that I have the correct URL. :-) In my Tests my URL was most of the time malformed, and if not, the workarounds were switched off.
Ok, I use it with the first mentioned workaround, which I consider more secure than the second, built-in one?

There is no diference, the "Nextcloud WebDav" connection was only added to make it more recognizeable, so a user can find it easier.

Ah, ok.
See, these two menu points lead me to the assumption, that I can give the main nexcloud URL example.com/nextcloud there (as in other nextcloud-supporting apps), in opposite to "Webdav", where I have to put the direct Webdav-URL.
From my side, I'd suggest rather make a single menu point and maybe name it "webdav/nextcloud". But, just my humble opinion.
Also, it could be helpful to mention an example nextcloud URL https://example.com/nextcloud/remote.php/dav/files/USERNAME/FOLDER in the credentials dialog.

But, anyway, thanks for the help and the project!

@martinstoeckli
Copy link
Owner Author

martinstoeckli commented Oct 4, 2023

Workaround: On Android the default HttpClientHandler uses the underlying Java class "HttpURLConnection", which unfortunately cannot handle the http method "PROPFIND".

So when running on Android we make an expection for this single request and use the "SocketsHttpHandler" which has its own implementation, though it cannot validate SSL certificates from LetsEncrypt. We can safely ignore the validation, because consecutive calls will do the validation with the Android implementation.

For lower versions of Android (e.g. v7), the "accept unsafe certificates" will still be available, so users can connect to WebDav servers with a certificate which is not yet known to this Android version.

@martinstoeckli
Copy link
Owner Author

Finally solved this issue in version 8.0.0, see description above.

@martinstoeckli martinstoeckli unpinned this issue Aug 6, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants