Skip to content

Optional "sunec" native library of SunEC provider becomes mandatory when using SVM #951

Closed
@fcurts

Description

@fcurts

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

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions