klippa-app/nativescript-http

Request hangs when using a Self-Signed certificate

Omnomios opened this issue · 11 comments

NativeScript: 8.3.3
Android: v13 on Pixel 7

I have been using a self signed cert on Android for development successfully by a using a void trust manager. Setting HttpsURLConnection.setDefaultSSLSocketFactory seems to work with the core Http library.

When I switch over to @klippa/nativescript-http all requests hang indefinitely when making requests to the development server that uses a self signed certificate. I switch it back to the production server and everything works as expected.

Is there a way to set sslSocketFactory to a void trust manager on the OKHttp builder from within Javascript or is the only option to fork this repo and patch it for my own use case?

Hi,

It looks like there is no way to set the default OkHttp hostnameVerifier/sslSocketFactory, so you would sadly have to fork the repo indeed. I'm open for PR's on it though.

I just had a go at applying a quick and dirty patch to see if it would even work and I came across a few fatal errors with publish/pack.sh.

This might be above my head as I'm very new to NativeScript and still not familiar with its conventions.

Here is the patch I was trying if anyone else comes across this ticket and has more of an idea how to get it working. It's a hack, not production ready.

public static void InitClient() {
    if (cookieJar == null) {
        cookieJar = new MemoryCookieJar();
    }

    TrustManager TRUST_ALL_CERTS = new X509TrustManager() {
        @Override
        public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) {
        }

        @Override
        public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) {
        }

        @Override
        public java.security.cert.X509Certificate[] getAcceptedIssuers() {
            return new java.security.cert.X509Certificate[] {};
        }
    };

    try {
        SSLContext sslContext = SSLContext.getInstance("SSL");
        sslContext.init(null, new TrustManager[] { TRUST_ALL_CERTS }, new java.security.SecureRandom());

        if (client == null) {
            client = new OkHttpClient.Builder()
                    .writeTimeout(60, TimeUnit.SECONDS)
                    .readTimeout(60, TimeUnit.SECONDS)
                    .connectTimeout(60, TimeUnit.SECONDS)
                    .sslSocketFactory(sslContext.getSocketFactory(), (X509TrustManager) TRUST_ALL_CERTS)
                    .cookieJar(cookieJar)
                    .build();
        }

    } catch (KeyManagementException e) {
        e.printStackTrace();
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    }
}

You probably do not want to patch the source code in the repo since you can't use that directly in your project.
It's probably way easier to use something like patch-package on the package that's installed through npm.

How that would work is that you edit the java in the package in node_modules and when you have a working version you execute npx patch-package @klippa/nativescript-http and it will automatically generate a patch for you. When someone else then works on your project, it should automatically work since patch-package hooks into your package.json.

Normally you would be correct, but the published module doesn't include the Java sources.
Just /platforms/android/nativescript_http.aar. I don't think patch-package would work.

I could patch in the whole aar file but that's not even building.

> @klippa/nativescript-http@3.0.3 build.native
> node scripts/build-native.js

executing 'ns plugin build'
Error: Command failed: ns plugin build

FAILURE: Build failed with an exception.

* Where:
Build file '/tmp/android-project202328-45437-1fad9ps.v0bc/nativescript_http/build.gradle' line: 38

* What went wrong:
A problem occurred evaluating root project 'nativescript_http'.
> /platforms/android/dependencies.json (No such file or directory)

Like I said; this is probably a trivial fix for someone who is comfortable with NativeScript and Java. I just don't know how it all fits together.

Ah yeah, you're right :( It generates an aar file. I haven't done anything with NS for a while so not sure why it's not building, could have to do with the NS version that you have.

I could reproduce this with the latest NS CLI version.
So it seems like this is a known issue: NativeScript/nativescript-cli#5660

It sounds like the fix would be to ship the sources, and not the aar file, and not do the build before shipping, however I have never tried that, I have to schedule some time to fix the build process for the NS 8 version.

@Omnomios I have just published version 3.0.4 to npm, can you see if that works for you? (I don't have time to test it right now)
It ships with the original android source and not the .aar file, it should automatically build it for you when you launch your app.

That also makes it easier for you to patch the java files.

That's amazing!
I just pulled down 3.0.4, applied my patch and now can connect to localhost with its self-signed certificate.

🎉

Thanks for testing that out! I have just pushed the changes :)
If you feel like it, I'm still willing to add a "AllowSelfSigned" option to the plugin if provided in a PR.

Would love to. I'll have a look over it on the weekend.

Is there any update on this?

I made the changes directly to that code, but the build of the package itself does not work on my machine. Probably because of that latest Node and Angular version.