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

Gracefully load OpenSSH known_hosts without requiring BouncyCastle #271

Merged
merged 3 commits into from
Sep 13, 2016

Conversation

solind
Copy link

@solind solind commented Sep 9, 2016

If BouncyCastle is not present, I want to be able to load whatever bits of the known_hosts file I can (i.e., the ssh-dss and ssh-rsa keys).

While making this change I noticed the KeyType.readPubKeyFromBuffer method didn't require passing in the String type name, so I cleaned that up too.

…y types requiring BouncyCastle, but we're not including BouncyCastle.
@solind
Copy link
Author

solind commented Sep 9, 2016

Do you really want me to use four spaces to indent cases in a switch statement? :(

@hierynomus
Copy link
Owner

Well actually, that spacing is a pretty default and widely accepted setting ;)

@hierynomus
Copy link
Owner

I'm missing some tests that showcase the problem you had and that was fixed now. From the code I don't see much difference except for the type of exception that might now be thrown. You might've first gotten a SecurityException and now a BufferException.

@solind
Copy link
Author

solind commented Sep 12, 2016

The BufferException is declared, the RuntimeException would generally be uncaught and terminate processing. That's the difference.

I thought the tests were all run with BouncyCastle in the classpath. How would I write a test case that requires BouncyCastle not be loaded? Is there an example you could point me to?

@hierynomus
Copy link
Owner

The whole problem with this is that there is also requests for being able
to use SpongyCastle, which is the Bouncy for Android. Adding this code
would now inadvertently throw an exception if Bouncy was not registered but
Spongy is. So I don't like this PR at the moment. The cleanup is nice
though, but the explicit checking for BC and switch outside of KeyType I
don't like.

2016-09-12 13:30 GMT+02:00 David Solin notifications@github.com:

The BufferException is declared, the RuntimeException would generally be
uncaught and terminate processing. That's the difference.

I thought the tests were all run with BouncyCastle in the classpath. How
would I write a test case that requires BouncyCastle not be loaded? Is
there an example you could point me to?


You are receiving this because you commented.
Reply to this email directly, view it on GitHub
#271 (comment), or mute
the thread
https://github.com/notifications/unsubscribe-auth/AAHLoyRjpt34LZqBDM-kvDEVm5FHV3o1ks5qpTfWgaJpZM4J5ZJx
.

@joval
Copy link

joval commented Sep 12, 2016

There are other places in the code that check for BouncyCastle -- the utility method is pre-existing. If SpongyCastle is a true replacement for BC, only that utility method would need to be changed to check for it to add SC support.

@solind
Copy link
Author

solind commented Sep 12, 2016

Would you prefer it if I checked for BC in the individual KeyType implementations?

@solind
Copy link
Author

solind commented Sep 12, 2016

Another possibility would be for me to modify the OpenSSHKnownHosts class, to catch SSHRuntimeExceptions in the constructor and log a different message.

Would that be preferable?

@solind
Copy link
Author

solind commented Sep 12, 2016

Actually that won't work... this is the error I was aiming to avoid:

Exception in thread "main" java.lang.NoClassDefFoundError: org/bouncycastle/asn1/nist/NISTNamedCurves
    at net.schmizz.sshj.common.KeyType$3.readPubKeyFromBuffer(KeyType.java:146)
    at net.schmizz.sshj.common.Buffer.readPublicKey(Buffer.java:429)
    at net.schmizz.sshj.transport.verification.OpenSSHKnownHosts$EntryFactory.parseEntry(OpenSSHKnownHosts.java:215)
    at net.schmizz.sshj.transport.verification.OpenSSHKnownHosts.<init>(OpenSSHKnownHosts.java:62)
    at net.schmizz.sshj.transport.verification.OpenSSHKnownHosts.<init>(OpenSSHKnownHosts.java:47)

@hierynomus
Copy link
Owner

Hi David,

I think for the ecdsa-sha2-nistp256 key you need to check whether BC is registered right at the start of the readPubKeyFromBuffer method, as that really is hardwired against BC classes. However for ssh-ed25519 you would not need that check, as it does not use BC at all, but rather the ed25519 library.

@solind
Copy link
Author

solind commented Sep 13, 2016

Hi Jeroen, you're quite right (of course)! I've verified that the last set of changes work, and avoid the ClassNotFoundException when BC is not available.

It would be nice if it would be possible to create automated test cases without the BouncyCastle dependency, to prevent future regressions. Do you have any ideas how that could be accomplished?

@solind
Copy link
Author

solind commented Sep 13, 2016

(Note, I also re-formatted the switch statement in PKCS5KeyFile per the style in this project).

@hierynomus
Copy link
Owner

There are a number of scenarios that I could think of:

  1. BC is not on the classpath
  2. BC is on the classpath but is not registered (ie. Security.addProvider(new BouncyCastleProvider()) has not been called)
  3. BC is on the classpath and is registered, but the unlimited strength crypto extensions have not been loaded
  4. BC is on the classpath and is registered in unlimited strength mode

Currently only 4. is being tested against.

In order to test for 1 you would maybe need to spin up a new JVM with a classpath without BC present in a unit test. We could maybe do that as a separate test task in Gradle. That should not be all too hard.

@hierynomus hierynomus merged commit a2fb4fb into hierynomus:master Sep 13, 2016
@hierynomus
Copy link
Owner

Merged! Thanks again for the PR :)

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

Successfully merging this pull request may close these issues.

None yet

3 participants