clj-http
clj-http copied to clipboard
Enabling TLSv1.1 and TLSv1.2 on OpenJDK 7?
Sorry for the support request but I can't for the life of me tell how to do this with this library and I wanted to know if there was a way to do it or if it was simply a missing feature.
The closest related ticket as far as I can tell is #174 but that's not exactly the same idea.
Essentially, JDK 7 disables TLSv1.1 and TLSv1.2 for reasons I don't comprehend. JDK 8 enables them by default, and makes TLSv1.2 the default for client connections.
There is supposedly a way to turn this on at the JDK level using system properties but if I'm reading things correctly it would require using getSystemSocketFactory rather than getSocketFactory because the former respects the system properties while the later simply uses the defaults of the JVM which you can't affect via system properties.
The problem is that we're talking to a server that is disabling TLSv1 in the near future and this library appears to be unable to communicate with it because of that. Upgrading to Java 8 (openjdk) where the default is to use TLSv1.2 works fine. For environmental reasons we'd like to avoid upgrading to JDK 8 at the moment.
I'm unstuck with this at least. I put this code into my project
(defn connection-manager []
(BasicClientConnectionManager.
(doto (SchemeRegistry.)
(.register (Scheme. "http" 80 (PlainSocketFactory/getSocketFactory)))
(.register (Scheme. "https" 443 (SSLSocketFactory. (SSLContext/getDefault)
(into-array String ["TLSv1.1" "TLSv1.2"])
nil
(BrowserCompatHostnameVerifier.)))))))
and assoc it into the requests I'm making and thus TLSv1.1 and TLSv1.2 are available to the requests.
This definitely seems like it would be a welcome enhancement to the options map of a request rather than having to build an entire connection manager. Either that or making connection managers easier to build.
Do you notice any problems with what I did?
@dakrone ping :)
@timvisher I do think connection managers should be easier to build, I'd say probably 8 out of the last 10 issues people have requested have been something related to them :)
I think you may want to update your code for the changed I pushed in https://github.com/dakrone/clj-http/commit/b759154c06206f802f5e140cc64e98393c5f4916
Thanks for the response. :)
I'm not sure I follow what I would need to change related to that commit?
Ah, is it the use of SSLSocketFactory/STRICT_HOSTNAME_VERIFIER vs. BrowserCompatHostnameVerifier? Could you explain what the difference is?
Ah, is it the use of SSLSocketFactory/STRICT_HOSTNAME_VERIFIER vs. BrowserCompatHostnameVerifier? Could you explain what the difference is?
Yep, that's it. Basically the default hostname verifier will not verify something like foo.bar.baz.com if the wildcard is *.baz.com, see https://github.com/dakrone/clj-http/issues/298 for the whole backstory.
@dakrone Great catch! That's just the sort of feedback I was hoping for. I'm applying that fix internally. :)
I'm having a similar problem, but I need to connect to a TLSv1.0 server from java 8, I'm getting a protocol_version error as Java 8 doesn't want to support the old version (probably with good reason), however I'm unable to get them to fix it at the server end.
Is there any progress on how to pass this as a client setting? I've also tried v3 snapshop without success.
@scusack did java 8 remove the support for the feature entirely or just disable it by default? If it just disables it by default my code snippet above should basically work (with the caveats suggested by @dakrone).
Thanks @timvisher I used a variant of your solution, I was really just after a way to pass configuration parameters to set the protocol rather than digging into java land myself.
I've got two production servers running java7, we have new dev machines that are java8, the release being used is clj-http-1.0.1 (old code but very stable otherwise). It is hard to google and get a straight answer to this but from what I've gleaned;
Java7 uses TLSv1 by default, Java8 uses TLSv1.2 by default and disables TLSv1. You can however enable TLSv1 again using system properties.
All that is beside the point though as the underlying Apache HTTP libraries used by clj-http ignore system settings anyway :) and I couldn't find a way to tell them to use TLSv1 via properties only in code.
One thing I couldn't work out is why it failed when I passed ["TLSv1" "TLSv1.1" "TLS1.2"] but worked when I only passed ["TLSv1"], the documentation suggests it should try all of them but I think perhaps they want you to pass the minimum acceptable one.
What's really needed is an easier way to pass these configuration options down into clj-http, I'm going to wait until relase 3 is stable and have another look then.
@scusack Indeed. I think we'd all like an easier way to do this but for now we've got our workaround. :)
Hi All, I just released clj-http 3.0.0, this is a huge change am I'm sure there are bugs, but please do give it a try and open issues (or PRs, even better :) )
Unfortunately clj-http 3.0.0 requires JDK8, so I'm not sure if this still applies also?
@dakrone Awesome! Any chance for a changelog and such any time soon to help decide if we can take on the new version?
I'm pretty sure it still applies as a JDK8 based clj-http (even using the insecure setting) will be unable to connect to older servers that only support TLSv1, however I'm not sure where the fix should be applied as it might be a problem with the apache library not falling back to older protocols when newer ones aren't available.
Actually, I made a mistake with cheshire so I have released 3.0.1 that should be plenty compatible with earlier Java versions.
@timvisher I haven't come up with a changelog quite yet, there haven't been any real new features for 3.x, it's mostly a move from the deprecated to the non-deprecated Apache APIs
@dakrone Ah. I figured since you said it was "a huge change" that more had happened. :)
I understand now.
@timvisher it's been a really long time since I've revisited this, is this still applicable?
I have no reason to believe it isn't (for 2.x) but we haven't upgraded to 3.x. I'm not sure if I'll be able come up with a test case sometime soon but I'll try to.