Skip to content

Android: "Unable to reach a settlement" exception #308

@willemw12

Description

@willemw12

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: <<kex done>> 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);
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions