Description
The SunEC provider has an optional sunec
native library that provides additional algorithms.
We do not want to ship the sunec
native library with our native executable due to licensing and packaging concerns. However, not providing this library gives the following runtime error when opening an HTTPS connection:
Exception in thread "main" java.lang.UnsatisfiedLinkError: sun.security.ec.ECKeyPairGenerator.generateECKeyPair(I[B[B)[Ljava/lang/Object; [symbol: Java_sun_security_ec_ECKeyPairGenerator_generateECKeyPair or Java_sun_security_ec_ECKeyPairGenerator_generateECKeyPair__I_3B_3B]
at com.oracle.svm.jni.access.JNINativeLinkage.getOrFindEntryPoint(JNINativeLinkage.java:145)
at com.oracle.svm.jni.JNIGeneratedMethodSupport.nativeCallAddress(JNIGeneratedMethodSupport.java:54)
at sun.security.ec.ECKeyPairGenerator.generateECKeyPair(ECKeyPairGenerator.java)
at sun.security.ec.ECKeyPairGenerator.generateKeyPair(ECKeyPairGenerator.java:128)
at java.security.KeyPairGenerator$Delegate.generateKeyPair(KeyPairGenerator.java:703)
at sun.security.ssl.ECDHCrypt.<init>(ECDHCrypt.java:78)
at sun.security.ssl.ClientHandshaker.serverKeyExchange(ClientHandshaker.java:783)
at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:302)
at sun.security.ssl.Handshaker.processLoop(Handshaker.java:1037)
at sun.security.ssl.Handshaker.process_record(Handshaker.java:965)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1064)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1367)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1395)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1379)
at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:559)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1564)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1492)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:263)
at java.net.URL.openStream(URL.java:1045)
The error is preceded by the following warning:
WARNING: The sunec native library, required by the SunEC provider, could not be loaded. This library is usually shipped as part of the JDK and can be found under <JAVA_HOME>/jre/lib/<platform>/libsunec.so. It is loaded at run time via System.loadLibrary("sunec"), the first time services from SunEC are accessed. To use this provider's services the java.library.path system property needs to be set accordingly to point to a location that contains libsunec.so. Note that if java.library.path is not set it defaults to the current working directory.
We've tried several workarounds. The only one that worked is (code is in Kotlin):
class MyFeature: Feature {
override fun duringSetup(access: DuringSetupAccess) {
System.loadLibrary("sunec")
Log.setLog(object : RealLog() {
override fun string(value: String?): Log = this
override fun newline(): Log = this
})
}
}
Here, System.loadLibrary("sunec")
prevents the UnsatisfiedLinkError
(although we don't know why), and disabling logging prevents the warning.
The only usage of method generateECKeyPair
in our project is in com.oracle.svm.hosted.SecurityServicesFeature
, line 133:
JNIRuntimeAccess.register(sun.security.ec.ECKeyPairGenerator.class.getDeclaredMethod("generateECKeyPair", int.class, byte[].class, byte[].class));
We think this might be related to the issue we are seeing.
GraalVM CE 1.0.0-rc11, macOS 10.14.2