Skip to content

Commit aabb1be

Browse files
authored
Try all public key algorithms available for a specific key type in SSH_MSG_USERAUTH_REQUEST. (#763)
1 parent 32329e5 commit aabb1be

File tree

3 files changed

+31
-7
lines changed

3 files changed

+31
-7
lines changed

src/main/java/net/schmizz/sshj/transport/Transport.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828

2929
import java.io.InputStream;
3030
import java.io.OutputStream;
31+
import java.util.List;
3132
import java.util.concurrent.TimeUnit;
3233

3334
/** Transport layer of the SSH protocol. */
@@ -224,5 +225,5 @@ long write(SSHPacket payload)
224225
void die(Exception e);
225226

226227
KeyAlgorithm getHostKeyAlgorithm();
227-
KeyAlgorithm getClientKeyAlgorithm(KeyType keyType) throws TransportException;
228+
List<KeyAlgorithm> getClientKeyAlgorithms(KeyType keyType) throws TransportException;
228229
}

src/main/java/net/schmizz/sshj/transport/TransportImpl.java

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import java.io.InputStream;
3434
import java.io.OutputStream;
3535
import java.net.InetSocketAddress;
36+
import java.util.ArrayList;
3637
import java.util.List;
3738
import java.util.concurrent.TimeUnit;
3839
import java.util.concurrent.locks.ReentrantLock;
@@ -637,15 +638,18 @@ public KeyAlgorithm getHostKeyAlgorithm() {
637638
}
638639

639640
@Override
640-
public KeyAlgorithm getClientKeyAlgorithm(KeyType keyType) throws TransportException {
641+
public List<KeyAlgorithm> getClientKeyAlgorithms(KeyType keyType) throws TransportException {
641642
List<Factory.Named<KeyAlgorithm>> factories = getConfig().getKeyAlgorithms();
643+
List<KeyAlgorithm> available = new ArrayList<>();
642644
if (factories != null)
643645
for (Factory.Named<KeyAlgorithm> f : factories)
644646
if (
645647
f instanceof KeyAlgorithms.Factory && ((KeyAlgorithms.Factory) f).getKeyType().equals(keyType)
646-
|| !(f instanceof KeyAlgorithms.Factory) && f.getName().equals(keyType.toString())
648+
|| !(f instanceof KeyAlgorithms.Factory) && f.getName().equals(keyType.toString())
647649
)
648-
return f.create();
649-
throw new TransportException("Cannot find an available KeyAlgorithm for type " + keyType);
650+
available.add(f.create());
651+
if (available.isEmpty())
652+
throw new TransportException("Cannot find an available KeyAlgorithm for type " + keyType);
653+
return available;
650654
}
651655
}

src/main/java/net/schmizz/sshj/userauth/method/KeyedAuthMethod.java

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,17 +27,36 @@
2727
import java.io.IOException;
2828
import java.security.PrivateKey;
2929
import java.security.PublicKey;
30+
import java.util.LinkedList;
31+
import java.util.Queue;
3032

3133
public abstract class KeyedAuthMethod
3234
extends AbstractAuthMethod {
3335

3436
protected final KeyProvider kProv;
37+
private Queue<KeyAlgorithm> available;
3538

3639
public KeyedAuthMethod(String name, KeyProvider kProv) {
3740
super(name);
3841
this.kProv = kProv;
3942
}
4043

44+
private KeyAlgorithm getPublicKeyAlgorithm(KeyType keyType) throws TransportException {
45+
if (available == null) {
46+
available = new LinkedList<>(params.getTransport().getClientKeyAlgorithms(keyType));
47+
}
48+
return available.peek();
49+
}
50+
51+
@Override
52+
public boolean shouldRetry() {
53+
if (available != null) {
54+
available.poll();
55+
return !available.isEmpty();
56+
}
57+
return false;
58+
}
59+
4160
protected SSHPacket putPubKey(SSHPacket reqBuf)
4261
throws UserAuthException {
4362
PublicKey key;
@@ -50,7 +69,7 @@ protected SSHPacket putPubKey(SSHPacket reqBuf)
5069
// public key as 2 strings: [ key type | key blob ]
5170
KeyType keyType = KeyType.fromKey(key);
5271
try {
53-
KeyAlgorithm ka = params.getTransport().getClientKeyAlgorithm(keyType);
72+
KeyAlgorithm ka = getPublicKeyAlgorithm(keyType);
5473
if (ka != null) {
5574
reqBuf.putString(ka.getKeyAlgorithm())
5675
.putString(new Buffer.PlainBuffer().putPublicKey(key).getCompactData());
@@ -74,7 +93,7 @@ protected SSHPacket putSig(SSHPacket reqBuf)
7493
final KeyType kt = KeyType.fromKey(key);
7594
Signature signature;
7695
try {
77-
signature = params.getTransport().getClientKeyAlgorithm(kt).newSignature();
96+
signature = getPublicKeyAlgorithm(kt).newSignature();
7897
} catch (TransportException e) {
7998
throw new UserAuthException("No KeyAlgorithm configured for key " + kt);
8099
}

0 commit comments

Comments
 (0)