Single-binary ECC (ECDSA/ECDHE) TLS support for SubstrateVM #1336
#951 addresses the issue that SunEC becomes mandatory for GraalVM native-image binaries doing TLS. While this is fine for some uses of native-image, people sometimes want good TLS support, including ECC, in a single binary. My example in point for this is shipping CLI tools.
In #951, a workaround was discovered that easily disables the SunEC provider. A downside is that only DHE/RSA is supported. The purpose of this ticket is to examine how to get single binary that still supports ECDHE.
One way that this could be resolved is if native-image supported e.g. Sulong's LLVM implementation for System.loadLibrary, or native-image learned how to System.loadLibrary libraries that are actually embedded in the image. I have no idea if that's possible or realistic: but I'm not an Oracle employee so deep engineering on GraalVM itself feels a little scary :) I'm calling this approach "loading embedded dynamic libraries".
Another way to hack this together is to add libsunec.so (or .dylib or .dll) as an embedded resource, set
Another way that perhaps doesn't require as much hacking on Graal internals is to use a different provider. The best (on the metric of "satisfying my proclivities as a cryptographic engineer") provider available is probably conscrypt, a provider published by Google using BoringSSL. I believe it's the default in modern Android. Unfortunately because BoringSSL itself is a C product, you end up with exactly the same problem that the SunEC provider has: a runtime dependency on a dynamic library.
While I generally don't love BouncyCastle (I am singularly convinced my dinky HTTPS-speaking CLI tool should not have a qTESLA implementation...) it is a pure-Java implementation and therefore "easy" for GraalVM to get working. For the rest of this ticket I'll be focusing on BouncyCastle.
To get replace the SunEC provider, two things need to happen:
I created a Clojure program that just downloads
The name column is "overrides+injects". Overrides are statements in java.security.overrides. Injects are parsed as follows: if there's an addbcprov, the code includes
"Successful download?" checks if I could find the
My interpretation of these results is that if I want TLS to work reliably and I don't care about ECDHE I should just disable the SunEC provider via override, which was the conclusion of #951. Effectively, the builtin TLS support is fine, so bctls is a red herring; we just need an ECC provider implementation. BC does not actually work in any of these cases, which is evidenced by the fact that the table only shows DHE successful attempts.
I think the next step is to try and debug why the native image can't create an instance of bcprov.
Things that would be useful to me:
The text was updated successfully, but these errors were encountered:
Have you got this test working without graal? That seems to me to be the first step. n.b. inserting the BC providers at the top of the list.
You shouldn't need to disable the SunEC provider, but if you do, you should presumably also disable SunJSSE at the same time when using bctls.
At this point I've got it working outside of Graal, so I'll switch to Graal next.
Now hitting first this with Graal - #378
Then after fixing above
Annoyingly, the Security feature seems really tied to SunEC - https://github.com/oracle/graal/blob/9ce4ed93a2797e922ff3a364e1f7b192984b9537/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/SecurityServicesFeature.java
But it feels close...
@lvh on further testing outside of Graal, I can't get bctls working with JDK8. Works fine with JDK11, just switching the execution JVM for running the test, nothing else. But I suspect the issues I'm seeing with Graal are now related to that instead. So I'm not going to spend more time getting bctls working with Graal.