Skip to content

Commit 13b4044

Browse files
Introduce ConfigImpl.prioritizeSshRsaKeyAlgorithm to deal with broken backward compatibility
1 parent 7d01e7e commit 13b4044

File tree

3 files changed

+96
-4
lines changed

3 files changed

+96
-4
lines changed

src/main/java/net/schmizz/sshj/ConfigImpl.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,4 +188,27 @@ public boolean isVerifyHostKeyCertificates() {
188188
public void setVerifyHostKeyCertificates(boolean value) {
189189
verifyHostKeyCertificates = value;
190190
}
191+
192+
/**
193+
* Modern servers neglect the key algorithm ssh-rsa. OpenSSH 8.8 even dropped its support by default in favour
194+
* of rsa-sha2-*. However, there are legacy servers like Apache SSHD that don't support the newer replacements
195+
* for ssh-rsa.
196+
*
197+
* If ssh-rsa factory is in {@link #getKeyAlgorithms()}, this methods makes ssh-rsa key algorithm more preferred
198+
* than any of rsa-sha2-*. Otherwise, nothing happens.
199+
*/
200+
public void prioritizeSshRsaKeyAlgorithm() {
201+
for (int sshRsaIndex = 0; sshRsaIndex < keyAlgorithms.size(); ++ sshRsaIndex) {
202+
if ("ssh-rsa".equals(keyAlgorithms.get(sshRsaIndex).getName())) {
203+
for (int i = 0; i < sshRsaIndex; ++i) {
204+
final String algo = keyAlgorithms.get(i).getName();
205+
if ("rsa-sha2-256".equals(algo) || "rsa-sha2-512".equals(algo)) {
206+
keyAlgorithms.add(i, keyAlgorithms.remove(sshRsaIndex));
207+
break;
208+
}
209+
}
210+
break;
211+
}
212+
}
213+
}
191214
}

src/test/groovy/com/hierynomus/sshj/userauth/keyprovider/FileKeyProviderSpec.groovy

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,7 @@ class FileKeyProviderSpec extends Specification {
4343
// `fixture` is backed by Apache SSHD server. Looks like it doesn't support rsa-sha2-512 public key signature.
4444
// Changing the default config to prioritize the former default implementation of RSA signature.
4545
def config = new DefaultConfig()
46-
def sshRsaFactory = config.keyAlgorithms.find {it.name == "ssh-rsa" }
47-
if (sshRsaFactory == null)
48-
throw new IllegalStateException("ssh-rsa was removed from the default config, the test should be refactored")
49-
config.keyAlgorithms = [sshRsaFactory] + config.keyAlgorithms.grep { it != sshRsaFactory }
46+
config.prioritizeSshRsaKeyAlgorithm()
5047

5148
and:
5249
SSHClient client = fixture.setupClient(config)
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
package net.schmizz.sshj
2+
3+
import com.hierynomus.sshj.key.KeyAlgorithms
4+
import spock.lang.Specification
5+
6+
class ConfigImplSpec extends Specification {
7+
static def ECDSA = KeyAlgorithms.ECDSASHANistp521()
8+
static def ED25519 = KeyAlgorithms.EdDSA25519()
9+
static def RSA_SHA_256 = KeyAlgorithms.RSASHA256()
10+
static def RSA_SHA_512 = KeyAlgorithms.RSASHA512()
11+
static def SSH_RSA = KeyAlgorithms.SSHRSA()
12+
13+
def "prioritizeSshRsaKeyAlgorithm does nothing if there is no ssh-rsa"() {
14+
given:
15+
def config = new DefaultConfig()
16+
config.keyAlgorithms = [RSA_SHA_512, ED25519]
17+
18+
when:
19+
config.prioritizeSshRsaKeyAlgorithm()
20+
21+
then:
22+
config.keyAlgorithms == [RSA_SHA_512, ED25519]
23+
}
24+
25+
def "prioritizeSshRsaKeyAlgorithm does nothing if there is no rsa-sha2-any"() {
26+
given:
27+
def config = new DefaultConfig()
28+
config.keyAlgorithms = [ED25519, SSH_RSA, ECDSA]
29+
30+
when:
31+
config.prioritizeSshRsaKeyAlgorithm()
32+
33+
then:
34+
config.keyAlgorithms == [ED25519, SSH_RSA, ECDSA]
35+
}
36+
37+
def "prioritizeSshRsaKeyAlgorithm does nothing if ssh-rsa already has higher priority"() {
38+
given:
39+
def config = new DefaultConfig()
40+
config.keyAlgorithms = [ED25519, SSH_RSA, RSA_SHA_512, ECDSA]
41+
42+
when:
43+
config.prioritizeSshRsaKeyAlgorithm()
44+
45+
then:
46+
config.keyAlgorithms == [ED25519, SSH_RSA, RSA_SHA_512, ECDSA]
47+
}
48+
49+
def "prioritizeSshRsaKeyAlgorithm prioritizes ssh-rsa if there is one rsa-sha2-any is prioritized"() {
50+
given:
51+
def config = new DefaultConfig()
52+
config.keyAlgorithms = [ED25519, RSA_SHA_512, ECDSA, SSH_RSA]
53+
54+
when:
55+
config.prioritizeSshRsaKeyAlgorithm()
56+
57+
then:
58+
config.keyAlgorithms == [ED25519, SSH_RSA, RSA_SHA_512, ECDSA]
59+
}
60+
61+
def "prioritizeSshRsaKeyAlgorithm prioritizes ssh-rsa if there are two rsa-sha2-any is prioritized"() {
62+
given:
63+
def config = new DefaultConfig()
64+
config.keyAlgorithms = [ED25519, RSA_SHA_512, ECDSA, RSA_SHA_256, SSH_RSA]
65+
66+
when:
67+
config.prioritizeSshRsaKeyAlgorithm()
68+
69+
then:
70+
config.keyAlgorithms == [ED25519, SSH_RSA, RSA_SHA_512, ECDSA, RSA_SHA_256]
71+
}
72+
}

0 commit comments

Comments
 (0)