This is an automated email from the ASF dual-hosted git repository.

lgoldstein pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mina-sshd.git

commit f8ba7b9baaccb93376a1cf46fe667b4e62687bf7
Author: Lyor Goldstein <[email protected]>
AuthorDate: Sun Feb 17 17:14:16 2019 +0200

    [SSHD-895] Added server-side support for RSA sha256/512 signatures
---
 CHANGES.md                                         | 34 +++++++++++
 README.md                                          |  3 +
 .../apache/sshd/common/config/keys/KeyUtils.java   | 26 +++++++++
 .../sshd/common/signature/SignatureFactory.java    | 68 +++++++++++++++++++++-
 .../java/org/apache/sshd/client/ClientBuilder.java | 37 ++++++++++++
 .../java/org/apache/sshd/common/BaseBuilder.java   | 36 ------------
 .../common/session/helpers/AbstractSession.java    |  1 +
 .../java/org/apache/sshd/server/ServerBuilder.java | 23 ++++++++
 .../sshd/server/session/AbstractServerSession.java | 66 ++++++++-------------
 .../org/apache/sshd/common/SshBuilderTest.java     |  3 +-
 .../common/config/SshConfigFileReaderTest.java     |  3 +-
 11 files changed, 218 insertions(+), 82 deletions(-)

diff --git a/CHANGES.md b/CHANGES.md
index 078e12d..9815aa6 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -28,4 +28,38 @@ to disconnecting and allow intervention via 
`SessionDisconnectHandler`.
 
 * [SSHD-893](https://issues.apache.org/jira/browse/SSHD-893) - Using Path(s) 
instead of String(s) as DirectoryScanner results
 
+* [SSHD-895](https://issues.apache.org/jira/browse/SSHD-895) - Add support for 
RSA + SHA-256/512 signatures. **Note:** according
+to [RFC - 8332 - section 3.3](https://tools.ietf.org/html/rfc8332#section-3.3):
+
+>> Implementation experience has shown that there are servers that apply
+>> authentication penalties to clients attempting public key algorithms
+>> that the SSH server does not support.
+
+>> When authenticating with an RSA key against a server that does not
+>> implement the "server-sig-algs" extension, clients MAY default to an
+>> "ssh-rsa" signature to avoid authentication penalties.  When the new
+>> rsa-sha2-* algorithms have been sufficiently widely adopted to
+>> warrant disabling "ssh-rsa", clients MAY default to one of the new
+>> algorithms.
+
+Therefore we do not include by default the "rsa-sha-*" signature factories in 
the `SshClient`. They can
+be easily added by using the relevant `BuiltinSignatures`:
+
+```java
+SshClient client = SshClient.setupDefaultClient();
+client.setSignatureFactories(
+    Arrays.asList(
+        /* This is the full list in the recommended preference order,
+         * but the initialization code can choose and/or re-order
+         */
+        BuiltinSignatures.nistp256,
+        BuiltinSignatures.nistp384,
+        BuiltinSignatures.nistp521,
+        BuiltinSignatures.ed25519,
+        BuiltinSignatures.rsaSHA512,
+        BuiltinSignatures.rsaSHA256,     // should check if isSupported since 
not required by default for Java 8
+        BuiltinSignatures.rsa,
+        BuiltinSignatures.dsa));
+```
+
 * [SSHD-896](https://issues.apache.org/jira/browse/SSHD-896) - Added support 
for [KEX extension negotiation](https://tools.wordtothewise.com/rfc/rfc8308)
diff --git a/README.md b/README.md
index 5e2d881..fc22ec0 100644
--- a/README.md
+++ b/README.md
@@ -17,6 +17,9 @@ based applications requiring SSH support.
 * [RFC 8308 - Extension Negotiation in the Secure Shell (SSH) 
Protocol](https://tools.ietf.org/html/rfc8308)
     * **Note:** - the code contains **hooks** for implementing the RFC but 
beyond allowing convenient
     access to the required protocol details, it does not implement any logic 
that handles the messages.
+* [RFC 8332 - Use of RSA Keys with SHA-256 and SHA-512 in the Secure Shell 
(SSH) Protocol](https://tools.ietf.org/html/rfc8332)
+    * **Note:** - the server side supports these signatures by default. The 
client side requires specific
+    initialization - see [section 
3.3](https://tools.ietf.org/html/rfc8332#section-3.3).
 * SFTP version 3-6 + extensions
     * `supported` - [DRAFT 05 - section 
4.4](http://tools.ietf.org/wg/secsh/draft-ietf-secsh-filexfer/draft-ietf-secsh-filexfer-05.tx)
     * `supported2` - [DRAFT 13 section 
5.4](https://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#page-10)
diff --git 
a/sshd-common/src/main/java/org/apache/sshd/common/config/keys/KeyUtils.java 
b/sshd-common/src/main/java/org/apache/sshd/common/config/keys/KeyUtils.java
index 7ced362..61b391a 100644
--- a/sshd-common/src/main/java/org/apache/sshd/common/config/keys/KeyUtils.java
+++ b/sshd-common/src/main/java/org/apache/sshd/common/config/keys/KeyUtils.java
@@ -800,6 +800,32 @@ public final class KeyUtils {
     }
 
     /**
+     * @param keyType A key type name - ignored if {@code null}/empty
+     * @return A {@link List} of they canonical key name and all its aliases
+     * @see #getCanonicalKeyType(String)
+     */
+    public static List<String> getAllEquivalentKeyTypes(String keyType) {
+        if (GenericUtils.isEmpty(keyType)) {
+            return Collections.emptyList();
+        }
+
+        String canonicalName = getCanonicalKeyType(keyType);
+        List<String> equivalents = new ArrayList<>();
+        equivalents.add(canonicalName);
+        synchronized (KEY_TYPE_ALIASES) {
+            for (Map.Entry<String, String> ae : KEY_TYPE_ALIASES.entrySet()) {
+                String alias = ae.getKey();
+                String name = ae.getValue();
+                if (canonicalName.equalsIgnoreCase(name)) {
+                    equivalents.add(alias);
+                }
+            }
+        }
+
+        return equivalents;
+    }
+
+    /**
      * @param keyType The available key-type - ignored if {@code null}/empty
      * @return The canonical key type - same as input if no alias registered
      * for the provided key type
diff --git 
a/sshd-common/src/main/java/org/apache/sshd/common/signature/SignatureFactory.java
 
b/sshd-common/src/main/java/org/apache/sshd/common/signature/SignatureFactory.java
index 0881714..b6273c0 100644
--- 
a/sshd-common/src/main/java/org/apache/sshd/common/signature/SignatureFactory.java
+++ 
b/sshd-common/src/main/java/org/apache/sshd/common/signature/SignatureFactory.java
@@ -19,13 +19,75 @@
 
 package org.apache.sshd.common.signature;
 
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
 import org.apache.sshd.common.BuiltinFactory;
+import org.apache.sshd.common.NamedFactory;
+import org.apache.sshd.common.NamedResource;
+import org.apache.sshd.common.config.keys.KeyUtils;
+import org.apache.sshd.common.util.GenericUtils;
 
 /**
  * @author <a href="mailto:[email protected]";>Apache MINA SSHD Project</a>
  */
-// CHECKSTYLE:OFF
 public interface SignatureFactory extends BuiltinFactory<Signature> {
-    // nothing extra
+    /**
+     * @param provided The provided signature key types
+     * @param factories The available signature factories
+     * @return A {@link List} of the matching available factories names
+     * that are also listed as provided ones - in the same <U>order</U>
+     * of preference as they appear in the available listing. May be
+     * empty if no provided signature key types, or no available ones
+     * or no match found.
+     * @see #resolveSignatureFactoryNamesProposal(Iterable, Collection)
+     */
+    static List<String> resolveSignatureFactoriesProposal(
+            Iterable<String> provided, Collection<? extends 
NamedFactory<Signature>> factories) {
+        return resolveSignatureFactoryNamesProposal(provided, 
NamedResource.getNameList(factories));
+    }
+
+    /**
+     * @param provided The provided signature key types
+     * @param available The available signature factories names
+     * @return A {@link List} of the matching available factories names
+     * that are also listed as provided ones - in the same <U>order</U>
+     * of preference as they appear in the available listing. May be
+     * empty if no provided signature key types, or no available ones
+     * or no match found.
+     */
+    static List<String> resolveSignatureFactoryNamesProposal(
+            Iterable<String> provided, Collection<String> available) {
+        if ((provided == null) || GenericUtils.isEmpty(available)) {
+            return Collections.emptyList();
+        }
+
+        // We want to preserve the original available order as it indicates 
the preference
+        Set<String> providedKeys = new HashSet<>();
+        for (String providedType : provided) {
+            Collection<String> equivTypes =
+                KeyUtils.getAllEquivalentKeyTypes(providedType);
+            providedKeys.addAll(equivTypes);
+        }
+
+        if (GenericUtils.isEmpty(providedKeys)) {
+            return Collections.emptyList();
+        }
+
+        List<String> supported = new ArrayList<>(available);
+        for (int index = 0; index < supported.size(); index++) {
+            String kt = supported.get(index);
+            if (!providedKeys.contains(kt)) {
+                supported.remove(index);
+                index--;    // compensate for auto-increment
+            }
+        }
+
+        return supported;
+    }
 }
-//CHECKSTYLE:ON
+
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/ClientBuilder.java 
b/sshd-core/src/main/java/org/apache/sshd/client/ClientBuilder.java
index 4f069d4..e720768 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/ClientBuilder.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/ClientBuilder.java
@@ -19,6 +19,7 @@
 
 package org.apache.sshd.client;
 
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
 import java.util.function.Function;
@@ -41,12 +42,44 @@ import 
org.apache.sshd.common.config.keys.FilePasswordProvider;
 import org.apache.sshd.common.kex.DHFactory;
 import org.apache.sshd.common.kex.KeyExchange;
 import org.apache.sshd.common.session.ConnectionService;
+import org.apache.sshd.common.signature.BuiltinSignatures;
 import org.apache.sshd.server.forward.ForwardedTcpipFactory;
 
 /**
  * SshClient builder
  */
 public class ClientBuilder extends BaseBuilder<SshClient, ClientBuilder> {
+    /**
+     * Preferred {@link BuiltinSignatures} according to
+     * <A 
HREF="https://www.freebsd.org/cgi/man.cgi?query=ssh_config&sektion=5";>sshd_config(5)</A>
+     * {@code HostKeyAlgorithms} recommendation
+     */
+    public static final List<BuiltinSignatures> DEFAULT_SIGNATURE_PREFERENCE =
+        /*
+         * According to https://tools.ietf.org/html/rfc8332#section-3.3:
+         *
+         *      Implementation experience has shown that there are servers 
that apply
+         *      authentication penalties to clients attempting public key 
algorithms
+         *      that the SSH server does not support.
+         *
+         *      When authenticating with an RSA key against a server that does 
not
+         *      implement the "server-sig-algs" extension, clients MAY default 
to an
+         *      "ssh-rsa" signature to avoid authentication penalties.  When 
the new
+         *      rsa-sha2-* algorithms have been sufficiently widely adopted to
+         *      warrant disabling "ssh-rsa", clients MAY default to one of the 
new
+         *      algorithms.
+         *
+         * Therefore we do not include by default the "rsa-sha-*" signatures.
+         */
+        Collections.unmodifiableList(
+            Arrays.asList(
+                BuiltinSignatures.nistp256,
+                BuiltinSignatures.nistp384,
+                BuiltinSignatures.nistp521,
+                BuiltinSignatures.ed25519,
+                BuiltinSignatures.rsa,
+                BuiltinSignatures.dsa
+            ));
 
     public static final Function<DHFactory, NamedFactory<KeyExchange>> DH2KEX 
= factory ->
             factory == null
@@ -102,6 +135,10 @@ public class ClientBuilder extends BaseBuilder<SshClient, 
ClientBuilder> {
     protected ClientBuilder fillWithDefaultValues() {
         super.fillWithDefaultValues();
 
+        if (signatureFactories == null) {
+            signatureFactories = NamedFactory.setUpBuiltinFactories(false, 
DEFAULT_SIGNATURE_PREFERENCE);
+        }
+
         if (compressionFactories == null) {
             compressionFactories = NamedFactory.setUpBuiltinFactories(false, 
DEFAULT_COMPRESSION_FACTORIES);
         }
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/BaseBuilder.java 
b/sshd-core/src/main/java/org/apache/sshd/common/BaseBuilder.java
index bce2283..c578e5a 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/BaseBuilder.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/BaseBuilder.java
@@ -43,7 +43,6 @@ import org.apache.sshd.common.random.SingletonRandomFactory;
 import org.apache.sshd.common.session.ConnectionService;
 import org.apache.sshd.common.session.UnknownChannelReferenceHandler;
 import 
org.apache.sshd.common.session.helpers.DefaultUnknownChannelReferenceHandler;
-import org.apache.sshd.common.signature.BuiltinSignatures;
 import org.apache.sshd.common.signature.Signature;
 import org.apache.sshd.common.util.ObjectBuilder;
 import org.apache.sshd.common.util.security.SecurityUtils;
@@ -125,22 +124,6 @@ public class BaseBuilder<T extends AbstractFactoryManager, 
S extends BaseBuilder
                 BuiltinMacs.hmacmd596
             ));
 
-    /**
-     * Preferred {@link BuiltinSignatures} according to
-     * <A 
HREF="https://www.freebsd.org/cgi/man.cgi?query=ssh_config&sektion=5";>sshd_config(5)</A>
-     * {@code HostKeyAlgorithms} recommendation
-     */
-    public static final List<BuiltinSignatures> DEFAULT_SIGNATURE_PREFERENCE =
-        Collections.unmodifiableList(
-            Arrays.asList(
-                BuiltinSignatures.nistp256,
-                BuiltinSignatures.nistp384,
-                BuiltinSignatures.nistp521,
-                BuiltinSignatures.ed25519,
-                BuiltinSignatures.rsa,
-                BuiltinSignatures.dsa
-            ));
-
     public static final UnknownChannelReferenceHandler 
DEFAULT_UNKNOWN_CHANNEL_REFERENCE_HANDLER =
             DefaultUnknownChannelReferenceHandler.INSTANCE;
 
@@ -164,10 +147,6 @@ public class BaseBuilder<T extends AbstractFactoryManager, 
S extends BaseBuilder
     }
 
     protected S fillWithDefaultValues() {
-        if (signatureFactories == null) {
-            signatureFactories = setUpDefaultSignatures(false);
-        }
-
         if (randomFactory == null) {
             randomFactory = new 
SingletonRandomFactory(SecurityUtils.getRandomFactory());
         }
@@ -332,19 +311,4 @@ public class BaseBuilder<T extends AbstractFactoryManager, 
S extends BaseBuilder
     public static List<NamedFactory<Mac>> setUpDefaultMacs(boolean 
ignoreUnsupported) {
         return NamedFactory.setUpBuiltinFactories(ignoreUnsupported, 
DEFAULT_MAC_PREFERENCE);
     }
-
-    /**
-     * @param ignoreUnsupported If {@code true} all the available built-in
-     *                          {@link Signature} factories are added, 
otherwise only those that are supported
-     *                          by the current JDK setup
-     * @return A {@link List} of the default {@link NamedFactory}
-     * instances of the {@link Signature}s according to the preference
-     * order defined by {@link #DEFAULT_SIGNATURE_PREFERENCE}.
-     * <B>Note:</B> the list may be filtered to exclude unsupported JCE
-     * signatures according to the <tt>ignoreUnsupported</tt> parameter
-     * @see BuiltinSignatures#isSupported()
-     */
-    public static List<NamedFactory<Signature>> setUpDefaultSignatures(boolean 
ignoreUnsupported) {
-        return NamedFactory.setUpBuiltinFactories(ignoreUnsupported, 
DEFAULT_SIGNATURE_PREFERENCE);
-    }
 }
\ No newline at end of file
diff --git 
a/sshd-core/src/main/java/org/apache/sshd/common/session/helpers/AbstractSession.java
 
b/sshd-core/src/main/java/org/apache/sshd/common/session/helpers/AbstractSession.java
index 6a26457..1dfc381 100644
--- 
a/sshd-core/src/main/java/org/apache/sshd/common/session/helpers/AbstractSession.java
+++ 
b/sshd-core/src/main/java/org/apache/sshd/common/session/helpers/AbstractSession.java
@@ -1905,6 +1905,7 @@ public abstract class AbstractSession extends 
SessionHelper {
     @Override
     protected String resolveSessionKexProposal(String hostKeyTypes) throws 
IOException {
         String proposal = super.resolveSessionKexProposal(hostKeyTypes);
+        // see https://tools.ietf.org/html/rfc8308
         KexExtensionHandler extHandler = getKexExtensionHandler();
         if ((extHandler == null) || 
(!extHandler.isKexExtensionsAvailable(this))) {
             return proposal;
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/ServerBuilder.java 
b/sshd-core/src/main/java/org/apache/sshd/server/ServerBuilder.java
index 2698eab..b6c3144 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/ServerBuilder.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/ServerBuilder.java
@@ -33,6 +33,7 @@ import org.apache.sshd.common.compression.CompressionFactory;
 import org.apache.sshd.common.kex.DHFactory;
 import org.apache.sshd.common.kex.KeyExchange;
 import org.apache.sshd.common.session.ConnectionService;
+import org.apache.sshd.common.signature.BuiltinSignatures;
 import 
org.apache.sshd.server.auth.keyboard.DefaultKeyboardInteractiveAuthenticator;
 import org.apache.sshd.server.auth.keyboard.KeyboardInteractiveAuthenticator;
 import org.apache.sshd.server.auth.pubkey.PublickeyAuthenticator;
@@ -85,6 +86,24 @@ public class ServerBuilder extends BaseBuilder<SshServer, 
ServerBuilder> {
                 BuiltinCompressions.zlib,
                 BuiltinCompressions.delayedZlib));
 
+    /**
+     * Preferred {@link BuiltinSignatures} according to
+     * <A 
HREF="http://man7.org/linux/man-pages/man5/sshd_config.5.html";>sshd_config(5) - 
HostKeyAlgorithms</A>
+     * {@code HostKeyAlgorithms} recommendation
+     */
+    public static final List<BuiltinSignatures> DEFAULT_SIGNATURE_PREFERENCE =
+        Collections.unmodifiableList(
+            Arrays.asList(
+                BuiltinSignatures.nistp256,
+                BuiltinSignatures.nistp384,
+                BuiltinSignatures.nistp521,
+                BuiltinSignatures.ed25519,
+                BuiltinSignatures.rsaSHA512,
+                BuiltinSignatures.rsaSHA256,
+                BuiltinSignatures.rsa,
+                BuiltinSignatures.dsa
+            ));
+
     protected PublickeyAuthenticator pubkeyAuthenticator;
     protected KeyboardInteractiveAuthenticator interactiveAuthenticator;
 
@@ -110,6 +129,10 @@ public class ServerBuilder extends BaseBuilder<SshServer, 
ServerBuilder> {
             compressionFactories = NamedFactory.setUpBuiltinFactories(false, 
DEFAULT_COMPRESSION_FACTORIES);
         }
 
+        if (signatureFactories == null) {
+            signatureFactories = NamedFactory.setUpBuiltinFactories(false, 
DEFAULT_SIGNATURE_PREFERENCE);
+        }
+
         if (keyExchangeFactories == null) {
             keyExchangeFactories = setUpDefaultKeyExchanges(false);
         }
diff --git 
a/sshd-core/src/main/java/org/apache/sshd/server/session/AbstractServerSession.java
 
b/sshd-core/src/main/java/org/apache/sshd/server/session/AbstractServerSession.java
index 79b7bb7..fb9c3aa 100644
--- 
a/sshd-core/src/main/java/org/apache/sshd/server/session/AbstractServerSession.java
+++ 
b/sshd-core/src/main/java/org/apache/sshd/server/session/AbstractServerSession.java
@@ -37,6 +37,7 @@ import org.apache.sshd.common.ServiceFactory;
 import org.apache.sshd.common.SshConstants;
 import org.apache.sshd.common.SshException;
 import org.apache.sshd.common.auth.AbstractUserAuthServiceFactory;
+import org.apache.sshd.common.config.keys.KeyUtils;
 import org.apache.sshd.common.io.IoService;
 import org.apache.sshd.common.io.IoSession;
 import org.apache.sshd.common.io.IoWriteFuture;
@@ -50,6 +51,7 @@ import org.apache.sshd.common.session.ConnectionService;
 import org.apache.sshd.common.session.SessionContext;
 import org.apache.sshd.common.session.SessionDisconnectHandler;
 import org.apache.sshd.common.session.helpers.AbstractSession;
+import org.apache.sshd.common.signature.SignatureFactory;
 import org.apache.sshd.common.util.GenericUtils;
 import org.apache.sshd.common.util.ValidateUtils;
 import org.apache.sshd.common.util.buffer.Buffer;
@@ -267,6 +269,16 @@ public abstract class AbstractServerSession extends 
AbstractSession implements S
                     "Authentication success signalled though KEX state=" + 
curState);
         }
 
+        /*
+         * According to https://tools.ietf.org/html/rfc8308#section-2.4
+         *
+         *      If a server sends SSH_MSG_EXT_INFO, it MAY send it at zero, 
one, or
+         *      both of the following opportunities:
+         *
+         *      ...
+         *
+         *      + Immediately preceding the server's SSH_MSG_USERAUTH_SUCCESS
+         */
         KexExtensionHandler extHandler = getKexExtensionHandler();
         if ((extHandler != null) && extHandler.isKexExtensionsAvailable(this)) 
{
             extHandler.sendKexExtensions(this, KexPhase.AUTHOK);
@@ -276,16 +288,6 @@ public abstract class AbstractServerSession extends 
AbstractSession implements S
         IoWriteFuture future;
         IoSession networkSession = getIoSession();
         synchronized (encodeLock) {
-            /*
-             * According to https://tools.ietf.org/html/rfc8308#section-2.4
-             *
-             *      If a server sends SSH_MSG_EXT_INFO, it MAY send it at 
zero, one, or
-             *      both of the following opportunities:
-             *
-             *      ...
-             *
-             *      + Immediately preceding the server's 
SSH_MSG_USERAUTH_SUCCESS
-             */
             Buffer packet = resolveOutputPacket(response);
 
             setUsername(username);
@@ -340,7 +342,6 @@ public abstract class AbstractServerSession extends 
AbstractSession implements S
         ValidateUtils.checkTrue(proposedManager == getFactoryManager(), 
"Mismatched signatures proposed factory manager");
 
         KeyPairProvider kpp = getKeyPairProvider();
-        Collection<String> supported = 
NamedResource.getNameList(getSignatureFactories());
         boolean debugEnabled = log.isDebugEnabled();
         Iterable<String> provided;
         try {
@@ -355,35 +356,17 @@ public abstract class AbstractServerSession extends 
AbstractSession implements S
             throw new RuntimeSshException(e);
         }
 
-        if ((provided == null) || GenericUtils.isEmpty(supported)) {
-            return resolveEmptySignaturesProposal(supported, provided);
-        }
-
-        StringBuilder resolveKeys = null;
-        for (String keyType : provided) {
-            if (!supported.contains(keyType)) {
-                if (debugEnabled) {
-                    log.debug("resolveAvailableSignaturesProposal({})[{}] {} 
not in supported list: {}",
-                          this, provided, keyType, supported);
-                }
-                continue;
-            }
-
-            if (resolveKeys == null) {
-                resolveKeys = new StringBuilder(supported.size() * 16 /* 
ecdsa-sha2-xxxx */);
-            }
-
-            if (resolveKeys.length() > 0) {
-                resolveKeys.append(',');
-            }
-
-            resolveKeys.append(keyType);
+        Collection<String> available = 
NamedResource.getNameList(getSignatureFactories());
+        if ((provided == null) || GenericUtils.isEmpty(available)) {
+            return resolveEmptySignaturesProposal(available, provided);
         }
 
-        if (GenericUtils.isEmpty(resolveKeys)) {
-            return resolveEmptySignaturesProposal(supported, provided);
+        Collection<String> supported =
+            SignatureFactory.resolveSignatureFactoryNamesProposal(provided, 
available);
+        if (GenericUtils.isEmpty(supported)) {
+            return resolveEmptySignaturesProposal(available, provided);
         } else {
-            return resolveKeys.toString();
+            return GenericUtils.join(supported, ',');
         }
     }
 
@@ -477,15 +460,16 @@ public abstract class AbstractServerSession extends 
AbstractSession implements S
 
     @Override
     public KeyPair getHostKey() {
-        String keyType = 
getNegotiatedKexParameter(KexProposalOption.SERVERKEYS);
+        String proposedKey = 
getNegotiatedKexParameter(KexProposalOption.SERVERKEYS);
+        String keyType = KeyUtils.getCanonicalKeyType(proposedKey);
         KeyPairProvider provider = 
Objects.requireNonNull(getKeyPairProvider(), "No host keys provider");
         try {
             return provider.loadKey(this, keyType);
         } catch (IOException | GeneralSecurityException | Error e) {
-            log.warn("getHostKey({}) failed ({}) to load key of type={}: {}",
-                 this, e.getClass().getSimpleName(), keyType, e.getMessage());
+            log.warn("getHostKey({}) failed ({}) to load key of type={}[{}]: 
{}",
+                 this, e.getClass().getSimpleName(), proposedKey, keyType, 
e.getMessage());
             if (log.isDebugEnabled()) {
-                log.debug("getHostKey(" + this + ") " + keyType + " key load 
failure details", e);
+                log.debug("getHostKey(" + this + ") " + proposedKey + "[" + 
keyType + "] key load failure details", e);
             }
 
             throw new RuntimeSshException(e);
diff --git a/sshd-core/src/test/java/org/apache/sshd/common/SshBuilderTest.java 
b/sshd-core/src/test/java/org/apache/sshd/common/SshBuilderTest.java
index 74ad5b1..e668670 100644
--- a/sshd-core/src/test/java/org/apache/sshd/common/SshBuilderTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/common/SshBuilderTest.java
@@ -30,6 +30,7 @@ import org.apache.sshd.common.kex.BuiltinDHFactories;
 import org.apache.sshd.common.mac.BuiltinMacs;
 import org.apache.sshd.common.signature.BuiltinSignatures;
 import org.apache.sshd.common.util.GenericUtils;
+import org.apache.sshd.server.ServerBuilder;
 import org.apache.sshd.util.test.BaseTestSupport;
 import org.apache.sshd.util.test.NoIoTestCase;
 import org.junit.FixMethodOrder;
@@ -74,7 +75,7 @@ public class SshBuilderTest extends BaseTestSupport {
      */
     @Test
     public void testAllBuiltinSignaturesListed() {
-        testAllInstancesListed(BuiltinSignatures.VALUES, 
BaseBuilder.DEFAULT_SIGNATURE_PREFERENCE);
+        testAllInstancesListed(BuiltinSignatures.VALUES, 
ServerBuilder.DEFAULT_SIGNATURE_PREFERENCE);
     }
 
     /**
diff --git 
a/sshd-core/src/test/java/org/apache/sshd/common/config/SshConfigFileReaderTest.java
 
b/sshd-core/src/test/java/org/apache/sshd/common/config/SshConfigFileReaderTest.java
index 94ce291..3f7aeda 100644
--- 
a/sshd-core/src/test/java/org/apache/sshd/common/config/SshConfigFileReaderTest.java
+++ 
b/sshd-core/src/test/java/org/apache/sshd/common/config/SshConfigFileReaderTest.java
@@ -30,6 +30,7 @@ import java.util.List;
 import java.util.Properties;
 import java.util.function.Function;
 
+import org.apache.sshd.client.ClientBuilder;
 import org.apache.sshd.common.BaseBuilder;
 import org.apache.sshd.common.Closeable;
 import org.apache.sshd.common.FactoryManager;
@@ -113,7 +114,7 @@ public class SshConfigFileReaderTest extends 
BaseTestSupport {
 
     @Test
     public void testParseSignaturesList() {
-        List<? extends NamedResource> expected = 
BaseBuilder.DEFAULT_SIGNATURE_PREFERENCE;
+        List<? extends NamedResource> expected = 
ClientBuilder.DEFAULT_SIGNATURE_PREFERENCE;
         Properties props = 
initNamedResourceProperties(ConfigFileReaderSupport.HOST_KEY_ALGORITHMS_CONFIG_PROP,
 expected);
         BuiltinSignatures.ParseResult result = 
SshConfigFileReader.getSignatures(PropertyResolverUtils.toPropertyResolver(props));
         testParsedFactoriesList(expected, result.getParsedFactories(), 
result.getUnsupportedFactories());

Reply via email to