BouncyCastleProvider not found by JAR on Lucee - java

We are successfully using the AmazonPay API for Java (amazon-pay-api-sdk-java-2.2.2.jar) in Adobe ColdFusion. We recently introduced Lucee (on Jetty, also running on OpenJDK 8) and attempted to run the same code (relevant excerpt):
payConfig = createObject("java", "com.amazon.pay.api.PayConfiguration").init();
payConfig.setPrivateKey("...");
However, upon calling setPrivateKey, which will arrive at Security.addProvider(new BouncyCastleProvider()); through PayConfiguration, we receive a java.lang.ClassNotFoundException:
lucee.runtime.exp.NativeException: org.bouncycastle.jce.provider.BouncyCastleProvider
at com.amazon.pay.api.PayConfiguration.setPrivateKey(PayConfiguration.java:77)
[...]
at java.lang.Thread.run(Thread.java:823)
Caused by: java.lang.NoClassDefFoundError: org.bouncycastle.jce.provider.BouncyCastleProvider
... 57 more
Caused by: java.lang.ClassNotFoundException: org.bouncycastle.jce.provider.BouncyCastleProvider not found by amazon.pay.api.sdk.java.2.2.2 [49]
at org.apache.felix.framework.BundleWiringImpl.findClassOrResourceByDelegation(BundleWiringImpl.java:1597)
at org.apache.felix.framework.BundleWiringImpl.access$300(BundleWiringImpl.java:79)
at org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.loadClass(BundleWiringImpl.java:1982)
at java.lang.ClassLoader.loadClass(ClassLoader.java:881)
... 57 more
We have placed all dependencies (bcprov-jdk15on-1.65.jar being BouncyCastle) in /lucee-server/context/lib. Creating BouncyCastleProvider within a .cfm/.cfc does work as expected:
createObject("java", "org.bouncycastle.jce.provider.BouncyCastleProvider").init()
I don't understand what Lucee's classloader is doing here. What am I missing?

I don't know what Lucee's classloader is doing either to be honest, but this kind of error seems to be quite common when loading certain more complex jars via the Lucee /lib path. It's likely there are "class clashes" going on somewhere.
Lucee is now OSGi based which means the best way of avoiding this is to load third-party java libraries as OSGi bundles. Some libraries are already packaged for OSGi and others can be converted fairly easily. More details here.
The Amazon library doesn't seem to be OSGi friendly, although it could probably be converted without too much effort.
For now, I would look at JavaLoader as the simplest way of getting it working. I don't have any valid Amazon keys to test fully with, but using JavaLoader I was able to at least call the payConfig.setPrivateKey() method without getting a ClassNotFoundException error.

Related

Java JCE cannot authenticate provider BC in jarsplice created jar

I am working on a game and I am using the Slick2D library. I am also using bouncycastle for encryption. Then I use jarsplice to package everything together in a nice executable. And it runs fine until it needs to encrypt something. It gives me a java.lang.SecurityException: JCE cannot authenticate the provider BC And I am using a signed jarfile (http://www.bouncycastle.org/download/bcprov-jdk15on-150.jar)
Here is the stack trace
java.lang.SecurityException: JCE cannot authenticate the provider BC
at javax.crypto.Cipher.getInstance(Cipher.java:642)
at javax.crypto.Cipher.getInstance(Cipher.java:580)
at net.matrixstudios.zenerith.networking.ZenerithLogin.encryptLogin(ZenerithLogin.java:159)
at net.matrixstudios.zenerith.networking.ZenerithLogin.<init>(ZenerithLogin.java:112)
at net.matrixstudios.zenerith.MultiplayerMenu$1.performAction(MultiplayerMenu.java:90)
at net.matrixstudios.zenerith.gui.menu.MenuGameState.clickButton(MenuGameState.java:83)
at net.matrixstudios.zenerith.gui.menu.MenuGameState.checkForButtonClicks(MenuGameState.java:75)
at net.matrixstudios.zenerith.gui.menu.MenuGameState.update(MenuGameState.java:51)
at net.matrixstudios.zenerith.gui.menu.AbstractGameState.update(AbstractGameState.java:47)
at org.newdawn.slick.state.StateBasedGame.update(StateBasedGame.java:266)
at org.newdawn.slick.GameContainer.updateAndRender(GameContainer.java:663)
at org.newdawn.slick.AppGameContainer.gameLoop(AppGameContainer.java:411)
at org.newdawn.slick.AppGameContainer.start(AppGameContainer.java:321)
at net.matrixstudios.zenerith.gui.Window.<init>(Window.java:28)
at net.matrixstudios.Main.main(Main.java:28)
Caused by: java.util.jar.JarException: file:/C:/Users/M4trixSh4d0w/Desktop/Zenerith_Alpha.0.2.1.5.jar has unsigned entries - org/bouncycastle/LICENSE.class
at javax.crypto.JarVerifier.verifySingleJar(JarVerifier.java:462)
at javax.crypto.JarVerifier.verifyJars(JarVerifier.java:322)
at javax.crypto.JarVerifier.verify(JarVerifier.java:250)
at javax.crypto.JceSecurity.verifyProviderJar(JceSecurity.java:161)
at javax.crypto.JceSecurity.getVerificationResult(JceSecurity.java:187)
at javax.crypto.Cipher.getInstance(Cipher.java:638)
... 14 more
So how do I authenticate the jarfile to run?
This is a standalone executable jarfile.
I'm a Android developer, got this error when I upgraded the compile and build tool to Android 12 (31), I tried lots of ways to fix it and finally I found the only way that works is changing the JDK to the version of 11.0.14.1 (x86_64), I worked on Mac M1, the downloading link of this version is: https://docs.aws.amazon.com/corretto/latest/corretto-11-ug/downloads-list.html
You probably want to register the cryptographic service provider at runtime to ensure the configuration will work for everyone. You can use either of the Security.addProvider() or Security.insertProviderAt() methods. See documentation linked below under "Managing Providers".
http://docs.oracle.com/javase/6/docs/technotes/guides/security/crypto/CryptoSpec.html#Provider
Just use addProvider() unless the order of providers is somehow important for you. I saw one contributor commented that you might slot it in at entry #9, but I didn't see evidence that this is right for your configuration, so probably just an extraneous detail from his/her config file. Obviously, if I missed something about your configuration and you do need it there, then go for insertProviderAt().

SSHJ and the Maven shade plugin

Testing SSHJ in Eclipse and everything looks good. But When I use the Maven shade plugin to package SSHJ I get the following error:
Exception in thread "main" net.schmizz.sshj.userauth.UserAuthException: Exhausted available authentication methods
at net.schmizz.sshj.SSHClient.auth(SSHClient.java:217)
at net.schmizz.sshj.SSHClient.authPublickey(SSHClient.java:316)
at net.schmizz.sshj.SSHClient.authPublickey(SSHClient.java:365)
at net.schmizz.sshj.SSHClient.authPublickey(SSHClient.java:295)
at no.f12.SshRepository.executeTaskOnHost(SshRepository.java:23)
at no.f12.SshService.serviceCommand(SshService.java:22)
at no.f12.App.main(App.java:29)
Adding
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
changes the error message to:
Exception in thread "main" net.schmizz.sshj.transport.TransportException: Unable to reach a settlement: [] and [aes128-ctr, aes192-ctr, aes256-ctr, arcfour256, arcfour128, aes128-gcm#openssh.com, aes256-gcm#openssh.com, aes128-cbc, 3des-cbc, blowfish-cbc, cast128-cbc, aes192-cbc, aes256-cbc, arcfour, rijndael-cbc#lysator.liu.se]
at net.schmizz.sshj.transport.Proposal.firstMatch(Proposal.java:165)
at net.schmizz.sshj.transport.Proposal.negotiate(Proposal.java:147)
at net.schmizz.sshj.transport.KeyExchanger.gotKexInit(KeyExchanger.java:239)
at net.schmizz.sshj.transport.KeyExchanger.handle(KeyExchanger.java:364)
at net.schmizz.sshj.transport.TransportImpl.handle(TransportImpl.java:478)
at net.schmizz.sshj.transport.Decoder.decode(Decoder.java:127)
at net.schmizz.sshj.transport.Decoder.received(Decoder.java:195)
at net.schmizz.sshj.transport.Reader.run(Reader.java:72)
Any idea how to get around this?
A bit of background to why I want to use shade... I am trying to get to a point where usage of Java and distribution of small utils is dead simple. So I create a really executable jar using this: https://github.com/brianm/really-executable-jars-maven-plugin . That enables me to create one, executable file to distribute and add to the path of the user. A bit like how Go has one binary file with all dependencies.
I had this exact problem. I finally gave up on trying to put everything in a big "uberjar".
Instead I assembled all the jars using maven-assembly-plugin, and then extract and add them to the classpath in order to execute, e.g. 'java -cp all-needed-libs/* com.company.MainClass'.
Another approach that might work is to add bouncycastle to the JRE extension library.
E.g put 'bcprov-jdk15on-1.49.jar' in folder '$JAVA_HOME/jre/lib/ext/' on the host.
You have to sign jar, it's required by Javax.security. I got similar problem and there's stacktrace from my test:
Cannot init Cipher factory: blowfish-cbc
java.lang.SecurityException: JCE cannot authenticate the provider BC
at javax.crypto.Cipher.getInstance(Cipher.java:642)
at javax.crypto.Cipher.getInstance(Cipher.java:580)
at net.schmizz.sshj.common.SecurityUtils.getCipher(SecurityUtils.java:96)
at net.schmizz.sshj.transport.cipher.BaseCipher.init(BaseCipher.java:88)
....
Caused by: java.util.jar.JarException: file:/test-jar-with-dependencies.jar has unsigned entries - library.properties
at javax.crypto.JarVerifier.verifySingleJar(JarVerifier.java:462)
at javax.crypto.JarVerifier.verifyJars(JarVerifier.java:322)
at javax.crypto.JarVerifier.verify(JarVerifier.java:250)
at javax.crypto.JceSecurity.verifyProviderJar(JceSecurity.java:161)
at javax.crypto.JceSecurity.getVerificationResult(JceSecurity.java:187)
at javax.crypto.Cipher.getInstance(Cipher.java:638)
at javax.crypto.Cipher.getInstance(Cipher.java:580)
at net.schmizz.sshj.common.SecurityUtils.getCipher(SecurityUtils.java:96)
at net.schmizz.sshj.transport.cipher.BaseCipher.init(BaseCipher.java:88)
at net.schmizz.sshj.DefaultConfig.initCipherFactories(DefaultConfig.java:152)
at net.schmizz.sshj.DefaultConfig.<init>(DefaultConfig.java:107)

Loading external dll with bridj is not possible due to hebrew username

I tried to load native library (lib.dll) to Java application via BridJ on Windows 7, where username is written in Hebrew.
What is important is that the Java application downloads lib.dll and save it properly in place:
C:\Users\דני\AppData\Local\Temp\lib.dll
I have reference to that file -> File lib, and pass lib.getCanonicalPath() to BridJ.
In the end I get the following exception:
Caused by: java.io.FileNotFoundException: Library 'LIB' was not found in path
...
...
...
(failed to load C:\Users\???\AppData\Local\Temp\lib.dll)
at org.bridj.BridJ.getNativeLibrary(BridJ.java:619)
at org.bridj.BridJ.getNativeLibrary(BridJ.java:619)
at org.bridj.BridJ.getNativeLibrary(BridJ.java:599)
at org.bridj.BridJ.getNativeLibrary(BridJ.java:315)
at org.bridj.CRuntime.getNativeLibrary(CRuntime.java:341)
at org.bridj.CRuntime.register(CRuntime.java:299)
... 21 more
So it seems that, getCanonicalPath() converts דני to.
How can I solve that ?
This bug looks similar to the following issue, which was fixed yesterday :
https://github.com/ochafik/nativelibs4java/issues/276
You might want to try again with the latest 0.7-SNAPSHOT.

Apache Camel web console's scalate servlet fails in WebLogic

I've found a similar issue described in detail in the scala mailing list (also here). It seems to be related to this change in classpath management when creating scala interpretation environments.
In my case both scala-library and scala-compiler are included in the war being deployed to WebLogic 10.3 (camel version: 2.8.0, jvm: oracle 1.6).
The exception is shown below:
com.sun.jersey.api.container.ContainerException: org.fusesource.scalate.TemplateException: object scala not found.
at org.fusesource.scalate.jersey.ScalateTemplateProcessor.writeToUsingServletTemplateEngine(ScalateTemplateProcessor.scala:190)
at org.fusesource.scalate.jersey.ScalateTemplateProcessor.writeTo(ScalateTemplateProcessor.scala:136)
at org.fusesource.scalate.jersey.ScalateTemplateProcessor.writeTo(ScalateTemplateProcessor.scala:44)
at com.sun.jersey.spi.template.ResolvedViewable.writeTo(ResolvedViewable.java:103)
at com.sun.jersey.server.impl.template.ViewableMessageBodyWriter.writeTo(ViewableMessageBodyWriter.java:83)
Truncated. see log file for complete stacktrace
Caused By: org.fusesource.scalate.TemplateException: object scala not found.
at org.fusesource.scalate.TemplateEngine.compileAndLoad(TemplateEngine.scala:784)
at org.fusesource.scalate.TemplateEngine.compileAndLoadEntry(TemplateEngine.scala:643)
at org.fusesource.scalate.TemplateEngine.liftedTree1$1(TemplateEngine.scala:374)
at org.fusesource.scalate.TemplateEngine.load(TemplateEngine.scala:368)
at org.fusesource.scalate.TemplateEngine.load(TemplateEngine.scala:426)
Truncated. see log file for complete stacktrace
Caused By: scala.tools.nsc.MissingRequirementError: object scala not found.
at scala.tools.nsc.symtab.Definitions$definitions$.getModuleOrClass(Definitions.scala:653)
at scala.tools.nsc.symtab.Definitions$definitions$.getModule(Definitions.scala:603)
at scala.tools.nsc.symtab.Definitions$definitions$.ScalaPackage(Definitions.scala:145)
at scala.tools.nsc.symtab.Definitions$definitions$.ScalaPackageClass(Definitions.scala:146)
at scala.tools.nsc.symtab.Definitions$definitions$.AnyClass(Definitions.scala:176)
The question: is it possible to make camel web-console work in this environment?
No its a problem with WebLogic. Scalaete needs to add special support for WebLogic, as WebLogic does classloading a bit differently, than the usual practice.

Amazon SimpleDB: KeyStoreException problem accessing trust store

All in a sudden my Java application using SimpleDB doesn't work anymore. I'm using Java AWS SDK version 1.2.4 on Windows 7. I've the following exception:
java.security.KeyStoreException: problem accessing trust storejava.io.IOException: Invalid keystore format
com.sun.net.ssl.internal.ssl.TrustManagerFactoryImpl.engineInit(TrustManagerFactoryImpl.java:55)
javax.net.ssl.TrustManagerFactory.init(TrustManagerFactory.java:230)
org.apache.http.conn.ssl.SSLSocketFactory.createSSLContext(SSLSocketFactory.java:190)
org.apache.http.conn.ssl.SSLSocketFactory.createDefaultSSLContext(SSLSocketFactory.java:209)
org.apache.http.conn.ssl.SSLSocketFactory.<init>(SSLSocketFactory.java:333)
org.apache.http.conn.ssl.SSLSocketFactory.getSocketFactory(SSLSocketFactory.java:165)
org.apache.http.impl.conn.SchemeRegistryFactory.createDefault(SchemeRegistryFactory.java:45)
org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager.<init>(ThreadSafeClientConnManager.java:98)
com.amazonaws.http.HttpClientFactory.createHttpClient(HttpClientFactory.java:67)
com.amazonaws.http.AmazonHttpClient.<init>(AmazonHttpClient.java:111)
com.amazonaws.AmazonWebServiceClient.<init>(AmazonWebServiceClient.java:59)
com.amazonaws.services.simpledb.AmazonSimpleDBClient.<init>(AmazonSimpleDBClient.java:118)
What could the cause be and how to solve the problem?
Sorry for self answer, but I solved the problem. It was caused by my certificate file, pointed by these statements loaded by a ServletContextListener defined in my web.xml
String sslCertPath = contextEvent.getServletContext().getRealPath(
"/WEB-INF/classes/jssecacerts");
System.setProperty("javax.net.ssl.trustStore", sslCertPath);
Commenting out those lines everything works. This is caused by a corruption of that file.
After that, I fixed my key store, uncommented the lines, had a little fight with tomcat and after that everything was working again, also with my certificates in place.

Categories