bc-java
bc-java copied to clipboard
FipsStatus.getMarker method does not work with bootstrap class loader
If using bootstrap class loader, the FipsStatus.getMarker() cannot work because it relies on system class loader.
Here is the context:
- bootstrap class loader is used to load bc classes.
- bc classes and resources are not accessible in system class loader.
In the FipsStatus.getMarker(final Class sourceClass, final String markerName) implementation:
- try to get the sourceClass loader, which will return null for bootstrap class loader:
ClassLoader loader = sourceClass.getClassLoader(); - system class loader will be use instead when the "loader" is null
ClassLoader.getSystemResource(markerName).toString(); - As the resource is not available in system class loader, ClassLoader.getSystemResource() does not work as expected.
Is it possible to have an improvement so that this method could work with bootstrap class loader?
static String getMarker(final Class sourceClass, final String markerName) {
// wrap with privileged action
return sourceClass.getResource(markerName);
}
sourceClass.getResource(markerName) may not work as bc libs may not have a module name.
Thanks!
What version of the FIPS provider is this with? Just to clarify further:
java -Xbootclasspath/a:bc-fips-2.0.0.jar org.bouncycastle.util.DumpInfo
produces:
Version Info: BouncyCastle Security Provider (FIPS edition) v2.0.0 FIPS Ready Status: READY Module SHA-256 HMAC: 164c8ae41945cb85fdc65666fc4de7301a65d29659ecd455ee5199c7d42d107e
Looks like the issue is specific to java agents with bc-fips-2.0.0.jar appended to the boot class path using Instrumentation.appendToBootstrapClassLoaderSearch
Below are the steps to reproduce this
$ cat TestAgent.java
import java.io.File;
import java.io.IOException;
import java.lang.instrument.Instrumentation;
import java.util.jar.JarFile;
public class TestAgent {
public static void premain(String agentArgs, Instrumentation instrumentation) throws IOException {
File file = new File("/tmp/bc-fips-2.0.0.jar");
instrumentation.appendToBootstrapClassLoaderSearch(new JarFile(file));
}
}
$ cat MANIFEST.MF
Premain-Class: TestAgent
$ javac TestAgent.java
$ jar cfm TestAgent.jar MANIFEST.MF TestAgent.class
$ java -javaagent:TestAgent.jar org.bouncycastle.util.DumpInfo
OpenJDK 64-Bit Server VM warning: Sharing is only supported for boot loader classes because bootstrap classpath has been appended
Exception in thread "main" org.bouncycastle.crypto.fips.FipsSelfTestFailedError: Exception on self test: Cannot invoke "java.net.URL.toString()" because the return value of "java.lang.ClassLoader.getSystemResource(String)" is null: EC
at org.bouncycastle.crypto.fips.SelfTestExecutor.validate(Unknown Source)
at org.bouncycastle.crypto.fips.FipsEC$DsaProvider.createEngine(Unknown Source)
at org.bouncycastle.crypto.fips.FipsEC$DsaProvider.createEngine(Unknown Source)
at org.bouncycastle.crypto.fips.FipsEC.
So I've tried a couple of different things, but the problem seems to remain... I did find this worked though:
java --module-path /tmp/bc-fips-2.0.0.jar -javaagent:TestAgent.jar org.bouncycastle.util.DumpInfo
Is that any help, or does the additional use of --module-path cause problems?
I run into the issue with BCFIPS 2.0.0. The method is trying to get resource from system class loader, which is not available because BCFIPS was added to bootstrap class loader in the agent and the resource is not passed to system class loader.
I hate to say this, but the problem appears to be intractable.
Any call to getResource() returns null under this case, even when the class is something like: LICENSE.class.getResource("/org/bouncycastle/LICENCSE.class"); doing String.class.getResource("java.lang.String.class") actually works as expected though. My guess is there's a step missing when the appendToBootstrapClassLoaderSearch() method is used.
I also think this is a bug, but it's not one of ours. I'd recommend reporting it to Oracle, if it hasn't been already.
Inactive. Not our bug.