Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OSGI dependencies are broken #255

Closed
15knots opened this issue Jul 17, 2016 · 28 comments
Closed

OSGI dependencies are broken #255

15knots opened this issue Jul 17, 2016 · 28 comments

Comments

@15knots
Copy link

15knots commented Jul 17, 2016

The manifest header declares a dependency to package net.i2p.crypto.eddsa.math, but bundle net.i2p.crypto.eddsa does not export that package. (The pom of net.i2p.crypto.eddsa explicitly excludes the package from the exported package list.)

This results in a tycho error when building:
Missing requirement: com.hierynomus.sshj 0.17.2 requires 'package net.i2p.crypto.eddsa.math 0.0.0' but it could not be found

@hierynomus
Copy link
Owner

As I'm not an OSGI whiz, what would be the best solution for this? Isn't this something that needs to be fixed in the net.i2p.crypto.eddsa pom?

@15knots
Copy link
Author

15knots commented Jul 18, 2016

src/main/java/net/schmizz/sshj/common/KeyType.java imports the package and uses types from it.

So it needs to be fixed in the net.i2p.crypto.eddsa pom.

@15knots
Copy link
Author

15knots commented Jul 19, 2016

Thank you for the quick response!

@15knots
Copy link
Author

15knots commented Sep 23, 2016

Please publish a new release containing this fix. Thank You!

@hierynomus
Copy link
Owner

Done, version 0.18.0 is downloadable from Maven.

@adagios
Copy link
Contributor

adagios commented Jan 6, 2017

Unfortunately it's still broken. The build.gradle file also needs to be corrected. I've created a pull request.

@15knots
Copy link
Author

15knots commented Jan 6, 2017

I am currently working on a project that tests how sshj behaves in an OSGI environment.
Things I found so far:

  1. Missing requirement: com.hierynomus.sshj 0.19.0 requires 'package net.i2p.crypto.eddsa.math 0.0.0' but it could not be found. This is because sshj imports package net.i2p.crypto.eddsa.math, which is not exported (possibly a bug in gradle bundler which adds the import?)

  2. ClassNotFoundEx: org.bouncycastle.jce.provider.BouncyCastleProvider in net.schmizz.sshj.common.SecurityUtils.BouncyCastleRegistration.run() due to a missing dependency in manifest.mf.

  3. Shouldn´ t sshj export packages com.hierynomus.sshj.*, too?

I fixed all of the above by changing build.gradlethis way:

jar {
    manifest {
      // please see http://bnd.bndtools.org/chapters/390-wrapping.html
        instruction "Bundle-Description", "SSHv2 library for Java"
        instruction "Bundle-License", "http://www.apache.org/licenses/LICENSE-2.0.txt"
        instruction "Import-Package", \
          "com.jcraft.jzlib*;version=\"[1.1,2)\";resolution:=optional", \
          "!com.hierynomus.sshj.*", "!net.schmizz.*", \
          "!net.i2p.crypto.eddsa.math", \
          "*"
        instruction "Require-Bundle", \
          "bcprov;bundle-version=\"$bouncycastleVersion\";resolution:=optional", \
          "bcprov;bundle-version=\"$bouncycastleVersion\";resolution:=optional"
        instruction "Export-Package", "com.hierynomus.sshj.*", "net.schmizz.*"
  }
}

But I am still working on my testing project...

@hierynomus
Copy link
Owner

Let me know once you've finished testing. I'll reopen this ticket until then.

@hierynomus hierynomus reopened this Jan 9, 2017
@15knots
Copy link
Author

15knots commented Jan 10, 2017

Test project is here: https://github.com/15knots/sshj.osgi.tests
Currently, it only tests the missing-requirement issue above.

@15knots
Copy link
Author

15knots commented Jan 11, 2017

I changed the testing project to work with development versions of sshj, too. It now proves that the missing requirements issue is solved in sshj now.

@adagios
Copy link
Contributor

adagios commented Jan 12, 2017

@15knots is there any specific reason why you are using Require-Bundle? It's use is generally discouraged. see http://stackoverflow.com/questions/1865819/when-should-i-use-import-package-and-when-should-i-use-require-bundle for an example

@hierynomus
Copy link
Owner

@adagios Thanks, I was wondering the same, but having not enough experience with OSGI bundles I accepted the change. If you have a better proposition I'm all ears.

@adagios
Copy link
Contributor

adagios commented Jan 12, 2017

@hierynomus I think I got it running with only Import-Package, but I would just like to check that when it doesn't find the following cyphers that it's not related to bouncy castle:

net.schmizz.sshj.DefaultConfig : aes192-ctr:Illegal key size
net.schmizz.sshj.DefaultConfig : aes256-ctr:Illegal key size
net.schmizz.sshj.DefaultConfig : aes192-cbc:Illegal key size
net.schmizz.sshj.DefaultConfig : aes256-cbc:Illegal key size
net.schmizz.sshj.DefaultConfig : blowfish-ctr:Illegal key size
net.schmizz.sshj.DefaultConfig : serpent192-cbc:Illegal key size
net.schmizz.sshj.DefaultConfig : serpent192-ctr:Illegal key size
net.schmizz.sshj.DefaultConfig : serpent256-cbc:Illegal key size
net.schmizz.sshj.DefaultConfig : serpent256-ctr:Illegal key size
net.schmizz.sshj.DefaultConfig : twofish192-cbc:Illegal key size
net.schmizz.sshj.DefaultConfig : twofish192-ctr:Illegal key size
net.schmizz.sshj.DefaultConfig : twofish256-cbc:Illegal key size
net.schmizz.sshj.DefaultConfig : twofish256-ctr:Illegal key size
net.schmizz.sshj.DefaultConfig : twofish-cbc:Illegal key size
net.schmizz.sshj.DefaultConfig : arcfour256:Illegal key size or default parameters

@hierynomus
Copy link
Owner

Nope, that is related to not running a JVM with the unlimited crypto extensions :)

@adagios
Copy link
Contributor

adagios commented Jan 12, 2017

I've created a pull request with my solution.

@15knots wan't to test it?

With regards to exporting com.hierynomus.sshj packages, is it something that clients should use directly? I looked and they seemed like internal classes, so I left them out of the Export-Package.

@15knots
Copy link
Author

15knots commented Jan 12, 2017

@adagios, @hierynomus: I used Require-Bundle", "bcprov because I had difficulties to figure out which packages should be imported: I just wanted to be on the safe side,

@15knots
Copy link
Author

15knots commented Jan 12, 2017

With d1dff55, test no longer fail.
mvn -Dsshj.version=0.19.2-dev.6.uncommitted+d1dff55 verify runs successfully.

Thanks!

@hierynomus
Copy link
Owner

hierynomus commented Jan 12, 2017 via email

@15knots
Copy link
Author

15knots commented Jan 12, 2017

@hierynomus Pls help me to check out the commit of the PR for #295.
Will try then.

@hierynomus
Copy link
Owner

@15knots Just pull the repository and check out 66d4b34

@15knots
Copy link
Author

15knots commented Jan 13, 2017

Sorry for the delay, github``s web UI confused me first, then I realized that I have to switch to adagios´ repo to get that commit:-)

Commit 66d4b34 for #295 fails as follows:
mvn -Dsshj.version=0.19.2-dev.8.uncommitted+66d4b34 verify
...

testBouncyCastleProvider(net.schmizz.sshj.common.SecurityUtilsTest)  Time elapsed: 0.005 sec  <<< ERROR!
net.schmizz.sshj.common.SSHRuntimeException: Failed to register BouncyCastle as the defaut JCE provider
        at net.schmizz.sshj.common.SecurityUtils.register(SecurityUtils.java:254)
        at net.schmizz.sshj.common.SecurityUtils.isBouncyCastleRegistered(SecurityUtils.java:227)
        at net.schmizz.sshj.common.SecurityUtilsTest.testBouncyCastleProvider(SecurityUtilsTest.java:27)

Results :

Tests in error:
  SecurityUtilsTest.testBouncyCastleProvider:27 » SSHRuntime Failed to register

Unfortunately, SecurityUtils.registerSecurityProvider()swallows the original exception, it is just logged at INFO level, so no more diags ATM.

@adagios
Copy link
Contributor

adagios commented Jan 16, 2017

I had a look, and It's failing because it can't find the class org.bouncycastle.jce.provider.BouncyCastleProvider but it's because the bouncycastle bundles are not included in the test run.

I took a look at the equinox config at target\work\configuration\config.ini and it only lists the sshj and the eddsa bundles.
But, I don't really know how tycho works and was unable to add bouncycastle to the list of bundles.

@15knots
Copy link
Author

15knots commented Jan 16, 2017

@adagios You are right!
The bouncycastle bundles are added to the tests runtime only if they are referenced by a Require-Bundle` in some manifest.mf file.
I fixed my testing project, commit 66d4b34 for #295 succeeds now.

@adagios
Copy link
Contributor

adagios commented Jan 23, 2017

@hierynomus I think that this is done. Can you share when are you thinking of releasing a new version? I would really like to switch to an official version :)

@hierynomus
Copy link
Owner

I'll merge #295 in in a moment. It might be cool if we could somehow integrate the osgi test into the build so that it is verified to not break. Don't know how feasible that is, and whether there are plugins for that for Gradle?

@hierynomus
Copy link
Owner

#295 has been merged.

@ahgittin
Copy link
Contributor

I'm encountering the same error now at runtime in OSGi. Ed25519PublicKey does a spec.getParams().getCurve().equals(ed25519.getCurve()) at [1] which requires visibility to net.i2p.crypto.eddsa.math which is neither exported from net.i2p.crypto.eddsa nor (per original message in this issue) imported here. Of course it can't be imported here but even using it without an import can cause NoClassDefFound.

It might be possible to avoid the problem here using !Objects.equal(spec.getParams().getCurve(), ed25519.getCurve()) at [1] instead.

(The right fix I think per the second and third messages would be in net.i2p.crypto.eddsa either to export the math package or remove it from the API of exported classes.)

A workaround -- in case someone else comes across this -- is to wrap the dependencies to explicitly export and import math; it's ugly but it works:

        <bundle dependency="true">wrap:mvn:net.i2p.crypto/eddsa/${eddsa.version}$overwrite=merge&amp;Bundle-SymbolicName=net.i2p.crypto.eddsa_wrapped&amp;Bundle-Version=${eddsa.version}&amp;Export-Package=*;version="${eddsa.version}"</bundle>
        <bundle dependency="true">wrap:mvn:com.hierynomus/sshj/${sshj.version}$overwrite=merge&amp;Bundle-SymbolicName=com.hierynomus.sshj_wrapped&amp;Bundle-Version=${sshj.version}&amp;Import-Package=net.i2p.crypto.eddsa.math;version="[0.2,1)",javax.crypto,javax.crypto.interfaces,javax.crypto.spec,net.i2p.crypto.eddsa;version="[0.2,1)",net.i2p.crypto.eddsa.spec;version="[0.2,1)",com.jcraft.jzlib;version="[1.1,2)";resolution:=optional,org.slf4j;version="[1.7,5)",org.bouncycastle.asn1;resolution:=optional;version="[1.60,2)",org.bouncycastle.asn1.nist;resolution:=optional;version="[1.60,2)",org.bouncycastle.asn1.x9;resolution:=optional;version="[1.60,2)",org.bouncycastle.crypto.ec;resolution:=optional;version="[1.60,2)",org.bouncycastle.crypto.prng;resolution:=optional;version="[1.60,2)",org.bouncycastle.jce.spec;resolution:=optional;version="[1.60,2)",org.bouncycastle.math.ec;resolution:=optional;version="[1.60,2)",org.bouncycastle.openssl;resolution:=optional;version="[1.60,2)",org.bouncycastle.openssl.jcajce;resolution:=optional;version="[1.60,2)",org.bouncycastle.util.encoders;resolution:=optional;version="[1.60,2)",javax.net,javax.security.auth,javax.security.auth.login,org.ietf.jgss,org.bouncycastle.jce.provider;resolution:=optional;version="[1.60,2)"</bundle>

[1] https://github.com/hierynomus/sshj/blob/master/src/main/java/com/hierynomus/sshj/signature/Ed25519PublicKey.java#L37

@FireT12
Copy link

FireT12 commented Mar 5, 2022

I'm encountering the same error now at runtime in OSGi. Ed25519PublicKey does a spec.getParams().getCurve().equals(ed25519.getCurve()) at [1] which requires visibility to net.i2p.crypto.eddsa.math which is neither exported from net.i2p.crypto.eddsa nor (per original message in this issue) imported here. Of course it can't be imported here but even using it without an import can cause NoClassDefFound.

It might be possible to avoid the problem here using !Objects.equal(spec.getParams().getCurve(), ed25519.getCurve()) at [1] instead.

(The right fix I think per the second and third messages would be in net.i2p.crypto.eddsa either to export the math package or remove it from the API of exported classes.)

A workaround -- in case someone else comes across this -- is to wrap the dependencies to explicitly export and import math; it's ugly but it works:

        <bundle dependency="true">wrap:mvn:net.i2p.crypto/eddsa/${eddsa.version}$overwrite=merge&amp;Bundle-SymbolicName=net.i2p.crypto.eddsa_wrapped&amp;Bundle-Version=${eddsa.version}&amp;Export-Package=*;version="${eddsa.version}"</bundle>
        <bundle dependency="true">wrap:mvn:com.hierynomus/sshj/${sshj.version}$overwrite=merge&amp;Bundle-SymbolicName=com.hierynomus.sshj_wrapped&amp;Bundle-Version=${sshj.version}&amp;Import-Package=net.i2p.crypto.eddsa.math;version="[0.2,1)",javax.crypto,javax.crypto.interfaces,javax.crypto.spec,net.i2p.crypto.eddsa;version="[0.2,1)",net.i2p.crypto.eddsa.spec;version="[0.2,1)",com.jcraft.jzlib;version="[1.1,2)";resolution:=optional,org.slf4j;version="[1.7,5)",org.bouncycastle.asn1;resolution:=optional;version="[1.60,2)",org.bouncycastle.asn1.nist;resolution:=optional;version="[1.60,2)",org.bouncycastle.asn1.x9;resolution:=optional;version="[1.60,2)",org.bouncycastle.crypto.ec;resolution:=optional;version="[1.60,2)",org.bouncycastle.crypto.prng;resolution:=optional;version="[1.60,2)",org.bouncycastle.jce.spec;resolution:=optional;version="[1.60,2)",org.bouncycastle.math.ec;resolution:=optional;version="[1.60,2)",org.bouncycastle.openssl;resolution:=optional;version="[1.60,2)",org.bouncycastle.openssl.jcajce;resolution:=optional;version="[1.60,2)",org.bouncycastle.util.encoders;resolution:=optional;version="[1.60,2)",javax.net,javax.security.auth,javax.security.auth.login,org.ietf.jgss,org.bouncycastle.jce.provider;resolution:=optional;version="[1.60,2)"</bundle>

[1] https://github.com/hierynomus/sshj/blob/master/src/main/java/com/hierynomus/sshj/signature/Ed25519PublicKey.java#L37

Thank you! I was considering having to rebuild both libraries to correct the problem. TIL you can wrap the bundle in that manner - excellent.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants