[SOLVED] Example java code to access https:// on a local device

I’m trying to modify an existing binding to access a device via https://. It is accessed via a local ip address, i.e. https://192.168.x.x/xxxx

I tried using HttpUtil.executeUrl() from org.eclipse.smarthome.io.net.http.HttpUtil. However, this resulted in an error, presumably because of common name mismatch. Furthermore I don’t think the CA is also verifiable through the standard CA.

How can I achieve the equivalent of curl --insecure using either HttpUtil.ExecuteUrl or is there another example of doing this using jetty?

Not an answer, but suggestion. I am not sure (ATM) which HTTP client library is used under the hood, but with most of them you have an option to ignore or override certificate verification policy.

My advice - check util sources and then check how to change (or give) hostname verifier/sal socket factory/trust resolver to “accept all”.

Cheers, Łukasz

Yep. Already done that. Jetty is the recommended library to use. I’m just wondering if there’s already a straight forward, simple example. Right now I’m trying to decipher Jetty’s documentation and writing the code.

Search TrustAll in the code base, nearly sure it exists

The “correct” way probably involves using HttpClientFactory and ExtensibleTrustManager

A quck and dirty way is to just create your own HttpClient:

final HttpClient httpClient = new HttpClient(new SslContextFactory(true));
try {
    httpClient.start();
} catch (Exception ex) {
    throw new IllegalStateException("Could not start HttpClient.", ex);
}

ContentResponse response = httpClient.GET("https://192.168.x.x/xxxx");

N.B. new SslContextFactory(boolean trustAll)

Here’s what I’ve tried so far:

  • I created a custom TlsTrustManagerProvider as such:
@Component
@NonNullByDefault
public class DaikinTlsTrustManagerProvider implements TlsTrustManagerProvider {
    @Override
    public String getHostName() {
        return "daikin";
    }

    @Override
    public X509ExtendedTrustManager getTrustManager() {
        return TrustAllTrustMananger.getInstance();
    }
}
  • I am using httpClient = httpClientFactory.getCommonHttpClient(); // this didn’t work, so
  • I tried httpClient = httpClientFactory.createHttpClient(“daikin”); - this didn’t work either, and yes I did call httpClient.start() first.

It would work when accessing a valid SSL site such as https://google.com/
An invalid ssl site example that doesn’t work: https://self-signed.badssl.com

This is from my log trace

11:18:22.072 [TRACE] [p.internal.ExtensibleTrustManagerImpl] - Did NOT find trustManager by sslEngine peer/host: redacted:443
11:18:22.072 [TRACE] [p.internal.ExtensibleTrustManagerImpl] - Searching trustManager by Subject Alternative Names: [[2, redacted]]
11:18:22.073 [TRACE] [p.internal.ExtensibleTrustManagerImpl] - No specific trust manager found, falling back to default

After further digging, I found that the custom TlsTrustManagerProvider class needs to return either the common name or host:port in the getHostName() that would match. Since neither the common name nor the host is going to be predictable / constant, I cannot use this method.

So I am resorting to @rossgb’s suggestion with creating HttpClient(new SslContextFactory(true)). Thank you!