hierynomus / hierynomus/sshj

Android: "Unable to reach a settlement" exception

Open
#308 3 comments 0 reactions 0 assignees View on GitHub
Dominant language
Java
Stars
2.7k
Forks
620
Avg merge
3d 23h
Merged PRs (30d)
11

Description

On Android, using Spongy Castle, SSH connection:

SSHClient ssh = new SSHClient(new AndroidConfig());
ssh.addHostKeyVerifier(new PromiscuousVerifier());
ssh.connect(HOST, PORT);

fails:

E/TransportImpl: Dying because - {}
net.schmizz.sshj.transport.TransportException: Unable to reach a settlement: [diffie-hellman-group1-sha1, diffie-hellman-group-exchange-sha1] and [curve25519-sha256, curve25519-sha256@libssh.org, ecdh-sha2-nistp256, ecdh-sha2-nistp384, ecdh-sha2-nistp521, diffie-hellman-group-exchange-sha256, diffie-hellman-group16-sha512, diffie-hellman-group18-sha512, diffie-hellman-group14-sha256, diffie-hellman-group14-sha1]
at net.schmizz.sshj.transport.Proposal.firstMatch(Proposal.java:145)
at net.schmizz.sshj.transport.Proposal.negotiate(Proposal.java:127)
at net.schmizz.sshj.transport.KeyExchanger.gotKexInit(KeyExchanger.java:218)
at net.schmizz.sshj.transport.KeyExchanger.handle(KeyExchanger.java:350)
at net.schmizz.sshj.transport.TransportImpl.handle(TransportImpl.java:500)
at net.schmizz.sshj.transport.Decoder.decode(Decoder.java:102)
at net.schmizz.sshj.transport.Decoder.received(Decoder.java:170)
at net.schmizz.sshj.transport.Reader.run(Reader.java:59)
I/TransportImpl: Disconnected - UNKNOWN
E/n*.s*.c*.Promise: <> woke to: net.schmizz.sshj.transport.TransportException: Unable to reach a settlement: [diffie-hellman-group1-sha1, diffie-hellman-group-exchange-sha1] and [curve25519-sha256, curve25519-sha256@libssh.org, ecdh-sha2-nistp256, ecdh-sha2-nistp384, ecdh-sha2-nistp521, diffie-hellman-group-exchange-sha256, diffie-hellman-group16-sha512, diffie-hellman-group18-sha512, diffie-hellman-group14-sha256, diffie-hellman-group14-sha1]
W/System.err: net.schmizz.sshj.transport.TransportException: Unable to reach a settlement: [diffie-hellman-group1-sha1, diffie-hellman-group-exchange-sha1] and [curve25519-sha256, curve25519-sha256@libssh.org, ecdh-sha2-nistp256, ecdh-sha2-nistp384, ecdh-sha2-nistp521, diffie-hellman-group-exchange-sha256, diffie-hellman-group16-sha512, diffie-hellman-group18-sha512, diffie-hellman-group14-sha256, diffie-hellman-group14-sha1]
W/System.err: at net.schmizz.sshj.transport.Proposal.firstMatch(Proposal.java:145)
W/System.err: at net.schmizz.sshj.transport.Proposal.negotiate(Proposal.java:127)
W/System.err: at net.schmizz.sshj.transport.KeyExchanger.gotKexInit(KeyExchanger.java:218)
W/System.err: at net.schmizz.sshj.transport.KeyExchanger.handle(KeyExchanger.java:350)
W/System.err: at net.schmizz.sshj.transport.TransportImpl.handle(TransportImpl.java:500)
W/System.err: at net.schmizz.sshj.transport.Decoder.decode(Decoder.java:102)
W/System.err: at net.schmizz.sshj.transport.Decoder.received(Decoder.java:170)
W/System.err: at net.schmizz.sshj.transport.Reader.run(Reader.java:59)

The reason for this is that in SecurityUtils.java, isBouncyCastleRegistered() returns false:

public static final String BOUNCY_CASTLE = "BC";

public static synchronized boolean isBouncyCastleRegistered() {
register();
return BOUNCY_CASTLE.equals(securityProvider);
}

because securityProvider is "SC", not "BC.

Then in DefaultConfig.java, the connection is not properly initialized:

public DefaultConfig() {
this.setLoggerFactory(LoggerFactory.DEFAULT);
this.setVersion(this.readVersionFromProperties());
boolean bouncyCastleRegistered = SecurityUtils.isBouncyCastleRegistered();
this.initKeyExchangeFactories(bouncyCastleRegistered);
this.initRandomFactory(bouncyCastleRegistered);
this.initFileKeyProviderFactories(bouncyCastleRegistered);
this.initCipherFactories();
this.initCompressionFactories();
this.initMACFactories();
this.initSignatureFactories();

because of the:

if(bouncyCastleRegistered) {

statements in the init methods.

A solution for this issue, that has worked in my case, might be for isBouncyCastleRegistered() to also accept the Spongy Castle provider:

public static final String SPONGY_CASTLE = "SC";

public static synchronized boolean isBouncyCastleRegistered() {
register();
return BOUNCY_CASTLE.equals(securityProvider) || SPONGY_CASTLE.equals(securityProvider);
}

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.