We are creating a javassist based custom class-loader modifying some classes byte code on loading. Part of the project is also a signed jar containing a security provider.
The initialization of the Loader simply looks like follows:
private final Loader initLoader(ClassLoader master) {
final ClassPool pool = ClassPool.getDefault();
final Loader loader = new Loader(master, pool);
try {
loader.addTranslator(pool, new MyTranslator());
} catch (Exception e) {
e.printStackTrace();
}
return loader;
}
The MyTranslator class does the modifications but does not care about the security relevant classes. The master is the system (parent) class loader.
When the application comes to the part when loading the relevant security classes this exception is thrown:
Caused by: java.security.NoSuchProviderException: JCE cannot authenticate the provider EXAMPLE-PROV
at javax.crypto.JceSecurity.getInstance(JceSecurity.java:100) ~[?:1.8.0_121]
at javax.crypto.KeyAgreement.getInstance(KeyAgreement.java:230) ~[?:1.8.0_121]
at my.example.app.security.ExampleKeyAgreement.generateSharedSecret(ExampleKeyAgreement.java:56) ~[?:?]
... 22 more
Caused by: java.util.jar.JarException: Class is on the bootclasspath
at javax.crypto.JarVerifier.verify(JarVerifier.java:286) ~[?:1.8.0_121]
at javax.crypto.JceSecurity.verifyProviderJar(JceSecurity.java:159) ~[?:1.8.0_121]
at javax.crypto.JceSecurity.getVerificationResult(JceSecurity.java:185) ~[?:1.8.0_121]
at javax.crypto.JceSecurity.getInstance(JceSecurity.java:97) ~[?:1.8.0_121]
at javax.crypto.KeyAgreement.getInstance(KeyAgreement.java:230) ~[?:1.8.0_121]
at my.example.app.security.ExampleKeyAgreement.generateSharedSecret(ExampleKeyAgreement.java:56) ~[?:?]
My question is, if there is a way to load these classes from a custom class-loader without violating the java security mechanisms?
The method javassist.Loader#setDomain(ProtectionDomain) says
Without registering an appropriate protection domain, the program loaded by this loader will not work with a security manager or a signed jar file.
How can I create or determine a valid ProtectionDomain instance?