hierynomus / sshj

ssh, scp and sftp for java
Apache License 2.0
2.48k stars 600 forks source link

OSGI dependencies are broken #255

Closed 15knots closed 7 years ago

15knots commented 8 years ago

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 commented 8 years ago

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 commented 8 years ago

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 commented 8 years ago

Thank you for the quick response!

15knots commented 7 years ago

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

hierynomus commented 7 years ago

Done, version 0.18.0 is downloadable from Maven.

adagios commented 7 years ago

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

15knots commented 7 years ago

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 commented 7 years ago

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

15knots commented 7 years ago

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

15knots commented 7 years ago

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 commented 7 years ago

@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 commented 7 years ago

@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 commented 7 years ago

@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 commented 7 years ago

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

adagios commented 7 years ago

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 commented 7 years ago

@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 commented 7 years ago

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

Thanks!

hierynomus commented 7 years ago

Does it run with sshj#295?

Op 12 jan. 2017 8:05 p.m. schreef "15knots" notifications@github.com:

With d1dff55 https://github.com/hierynomus/sshj/commit/d1dff550ce08d7bd263a090993d5724f92651c00, test no longer fail. mvn -Dsshj.version=0.19.2-dev.6.uncommitted+d1dff55 verify runs successfully.

Thanks!

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/hierynomus/sshj/issues/255#issuecomment-272251772, or mute the thread https://github.com/notifications/unsubscribe-auth/AAHLoyjSxaUJzSePV5EwylBbxSqI5WrNks5rRnlxgaJpZM4JORMd .

15knots commented 7 years ago

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

hierynomus commented 7 years ago

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

15knots commented 7 years ago

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 66d4b34eba39661116339c012495787ec846351b 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 commented 7 years ago

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 commented 7 years ago

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

adagios commented 7 years ago

@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 commented 7 years ago

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 commented 7 years ago

295 has been merged.

ahgittin commented 2 years ago

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 commented 2 years ago

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.