You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mina.apache.org by lg...@apache.org on 2018/09/06 16:03:21 UTC

[11/51] [abbrv] mina-sshd git commit: [SSHD-842] Split common utilities code from sshd-core into sshd-common (new artifact)

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-core/src/main/java/org/apache/sshd/common/util/security/eddsa/Ed25519PublicKeyDecoder.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/util/security/eddsa/Ed25519PublicKeyDecoder.java b/sshd-core/src/main/java/org/apache/sshd/common/util/security/eddsa/Ed25519PublicKeyDecoder.java
deleted file mode 100644
index 793965c..0000000
--- a/sshd-core/src/main/java/org/apache/sshd/common/util/security/eddsa/Ed25519PublicKeyDecoder.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.sshd.common.util.security.eddsa;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.security.GeneralSecurityException;
-import java.security.KeyFactory;
-import java.security.KeyPairGenerator;
-import java.util.Collections;
-import java.util.Objects;
-
-import org.apache.sshd.common.config.keys.KeyEntryResolver;
-import org.apache.sshd.common.config.keys.impl.AbstractPublicKeyEntryDecoder;
-import org.apache.sshd.common.keyprovider.KeyPairProvider;
-import org.apache.sshd.common.util.security.SecurityUtils;
-
-import net.i2p.crypto.eddsa.EdDSAPrivateKey;
-import net.i2p.crypto.eddsa.EdDSAPublicKey;
-import net.i2p.crypto.eddsa.spec.EdDSAPrivateKeySpec;
-import net.i2p.crypto.eddsa.spec.EdDSAPublicKeySpec;
-
-/**
- * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
- */
-public final class Ed25519PublicKeyDecoder extends AbstractPublicKeyEntryDecoder<EdDSAPublicKey, EdDSAPrivateKey> {
-    public static final Ed25519PublicKeyDecoder INSTANCE = new Ed25519PublicKeyDecoder();
-
-    private Ed25519PublicKeyDecoder() {
-        super(EdDSAPublicKey.class, EdDSAPrivateKey.class, Collections.unmodifiableList(Collections.singletonList(KeyPairProvider.SSH_ED25519)));
-    }
-
-    @Override
-    public EdDSAPublicKey clonePublicKey(EdDSAPublicKey key) throws GeneralSecurityException {
-        if (key == null) {
-            return null;
-        } else {
-            return generatePublicKey(new EdDSAPublicKeySpec(key.getA(), key.getParams()));
-        }
-    }
-
-    @Override
-    public EdDSAPrivateKey clonePrivateKey(EdDSAPrivateKey key) throws GeneralSecurityException {
-        if (key == null) {
-            return null;
-        } else {
-            return generatePrivateKey(new EdDSAPrivateKeySpec(key.getSeed(), key.getParams()));
-        }
-    }
-
-    @Override
-    public KeyPairGenerator getKeyPairGenerator() throws GeneralSecurityException {
-        return SecurityUtils.getKeyPairGenerator(SecurityUtils.EDDSA);
-    }
-
-    @Override
-    public String encodePublicKey(OutputStream s, EdDSAPublicKey key) throws IOException {
-        Objects.requireNonNull(key, "No public key provided");
-        KeyEntryResolver.encodeString(s, KeyPairProvider.SSH_ED25519);
-        byte[] seed = getSeedValue(key);
-        KeyEntryResolver.writeRLEBytes(s, seed);
-        return KeyPairProvider.SSH_ED25519;
-    }
-
-    @Override
-    public KeyFactory getKeyFactoryInstance() throws GeneralSecurityException {
-        return SecurityUtils.getKeyFactory(SecurityUtils.EDDSA);
-    }
-
-    @Override
-    public EdDSAPublicKey decodePublicKey(String keyType, InputStream keyData) throws IOException, GeneralSecurityException {
-        byte[] seed = KeyEntryResolver.readRLEBytes(keyData);
-        return EdDSAPublicKey.class.cast(SecurityUtils.generateEDDSAPublicKey(keyType, seed));
-    }
-
-    public static byte[] getSeedValue(EdDSAPublicKey key) {
-        // a bit of reverse-engineering on the EdDSAPublicKeySpec
-        return (key == null) ? null : key.getAbyte();
-    }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-core/src/main/java/org/apache/sshd/common/util/security/eddsa/EdDSASecurityProviderRegistrar.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/util/security/eddsa/EdDSASecurityProviderRegistrar.java b/sshd-core/src/main/java/org/apache/sshd/common/util/security/eddsa/EdDSASecurityProviderRegistrar.java
deleted file mode 100644
index 61f16e9..0000000
--- a/sshd-core/src/main/java/org/apache/sshd/common/util/security/eddsa/EdDSASecurityProviderRegistrar.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.sshd.common.util.security.eddsa;
-
-import java.security.KeyFactory;
-import java.security.KeyPairGenerator;
-import java.security.Provider;
-import java.security.Signature;
-import java.util.Objects;
-import java.util.concurrent.atomic.AtomicReference;
-
-import org.apache.sshd.common.util.GenericUtils;
-import org.apache.sshd.common.util.ReflectionUtils;
-import org.apache.sshd.common.util.security.AbstractSecurityProviderRegistrar;
-import org.apache.sshd.common.util.security.SecurityUtils;
-import org.apache.sshd.common.util.threads.ThreadUtils;
-
-/**
- * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
- */
-public class EdDSASecurityProviderRegistrar extends AbstractSecurityProviderRegistrar {
-    public static final String PROVIDER_CLASS = "net.i2p.crypto.eddsa.EdDSASecurityProvider";
-    // Do not define a static registrar instance to minimize class loading issues
-    private final AtomicReference<Boolean> supportHolder = new AtomicReference<>(null);
-
-    public EdDSASecurityProviderRegistrar() {
-        super(SecurityUtils.EDDSA);
-    }
-
-    @Override
-    public boolean isEnabled() {
-        if (!super.isEnabled()) {
-            return false;
-        }
-
-        // For backward compatibility
-        return this.getBooleanProperty(SecurityUtils.EDDSA_SUPPORTED_PROP, true);
-    }
-
-    @Override
-    public Provider getSecurityProvider() {
-        try {
-            return getOrCreateProvider(PROVIDER_CLASS);
-        } catch (ReflectiveOperationException t) {
-            Throwable e = GenericUtils.peelException(t);
-            log.error("getSecurityProvider({}) failed ({}) to instantiate {}: {}",
-                      getName(), e.getClass().getSimpleName(), PROVIDER_CLASS, e.getMessage());
-            if (e instanceof RuntimeException) {
-                throw (RuntimeException) e;
-            }
-
-            throw new RuntimeException(e);
-        }
-    }
-
-    @Override
-    public boolean isSecurityEntitySupported(Class<?> entityType, String name) {
-        if (!isSupported()) {
-            return false;
-        }
-
-        if (KeyPairGenerator.class.isAssignableFrom(entityType)
-                || KeyFactory.class.isAssignableFrom(entityType)) {
-            return Objects.compare(name, getName(), String.CASE_INSENSITIVE_ORDER) == 0;
-        } else if (Signature.class.isAssignableFrom(entityType)) {
-            return Objects.compare(SecurityUtils.CURVE_ED25519_SHA512, name, String.CASE_INSENSITIVE_ORDER) == 0;
-        } else {
-            return false;
-        }
-    }
-
-    @Override
-    public boolean isSupported() {
-        Boolean supported;
-        synchronized (supportHolder) {
-            supported = supportHolder.get();
-            if (supported != null) {
-                return supported.booleanValue();
-            }
-
-            ClassLoader cl = ThreadUtils.resolveDefaultClassLoader(getClass());
-            supported = ReflectionUtils.isClassAvailable(cl, "net.i2p.crypto.eddsa.EdDSAKey");
-            supportHolder.set(supported);
-        }
-
-        return supported.booleanValue();
-    }
-}

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-core/src/main/java/org/apache/sshd/common/util/security/eddsa/EdDSASecurityProviderUtils.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/util/security/eddsa/EdDSASecurityProviderUtils.java b/sshd-core/src/main/java/org/apache/sshd/common/util/security/eddsa/EdDSASecurityProviderUtils.java
deleted file mode 100644
index 242f550..0000000
--- a/sshd-core/src/main/java/org/apache/sshd/common/util/security/eddsa/EdDSASecurityProviderUtils.java
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.sshd.common.util.security.eddsa;
-
-import java.security.GeneralSecurityException;
-import java.security.InvalidKeyException;
-import java.security.Key;
-import java.security.KeyFactory;
-import java.security.NoSuchAlgorithmException;
-import java.security.PrivateKey;
-import java.security.PublicKey;
-import java.util.Arrays;
-import java.util.Objects;
-
-import org.apache.sshd.common.config.keys.PrivateKeyEntryDecoder;
-import org.apache.sshd.common.config.keys.PublicKeyEntryDecoder;
-import org.apache.sshd.common.keyprovider.KeyPairProvider;
-import org.apache.sshd.common.util.ValidateUtils;
-import org.apache.sshd.common.util.buffer.Buffer;
-import org.apache.sshd.common.util.security.SecurityUtils;
-
-import net.i2p.crypto.eddsa.EdDSAEngine;
-import net.i2p.crypto.eddsa.EdDSAKey;
-import net.i2p.crypto.eddsa.EdDSAPrivateKey;
-import net.i2p.crypto.eddsa.EdDSAPublicKey;
-import net.i2p.crypto.eddsa.spec.EdDSANamedCurveTable;
-import net.i2p.crypto.eddsa.spec.EdDSAParameterSpec;
-import net.i2p.crypto.eddsa.spec.EdDSAPrivateKeySpec;
-import net.i2p.crypto.eddsa.spec.EdDSAPublicKeySpec;
-
-/**
- * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
- */
-public final class EdDSASecurityProviderUtils {
-    // See EdDSANamedCurveTable
-    public static final String CURVE_ED25519_SHA512 = "Ed25519";
-
-    private EdDSASecurityProviderUtils() {
-        throw new UnsupportedOperationException("No instance");
-    }
-
-    public static Class<? extends PublicKey> getEDDSAPublicKeyType() {
-        return EdDSAPublicKey.class;
-    }
-
-    public static Class<? extends PrivateKey> getEDDSAPrivateKeyType() {
-        return EdDSAPrivateKey.class;
-    }
-
-    public static int getEDDSAKeySize(Key key) {
-        return (SecurityUtils.isEDDSACurveSupported() && (key instanceof EdDSAKey)) ? 256 : -1;
-    }
-
-    public static boolean compareEDDSAPPublicKeys(PublicKey k1, PublicKey k2) {
-        if (!SecurityUtils.isEDDSACurveSupported()) {
-            return false;
-        }
-
-        if ((k1 instanceof EdDSAPublicKey) && (k2 instanceof EdDSAPublicKey)) {
-            if (Objects.equals(k1, k2)) {
-                return true;
-            } else if (k1 == null || k2 == null) {
-                return false;   // both null is covered by Objects#equals
-            }
-
-            EdDSAPublicKey ed1 = (EdDSAPublicKey) k1;
-            EdDSAPublicKey ed2 = (EdDSAPublicKey) k2;
-            return Arrays.equals(ed1.getAbyte(), ed2.getAbyte())
-                && compareEDDSAKeyParams(ed1.getParams(), ed2.getParams());
-        }
-
-        return false;
-    }
-
-    public static boolean isEDDSASignatureAlgorithm(String algorithm) {
-        return EdDSAEngine.SIGNATURE_ALGORITHM.equalsIgnoreCase(algorithm);
-    }
-
-    public static EdDSAPublicKey recoverEDDSAPublicKey(PrivateKey key) throws GeneralSecurityException {
-        ValidateUtils.checkTrue(SecurityUtils.isEDDSACurveSupported(), SecurityUtils.EDDSA + " not supported");
-        if (!(key instanceof EdDSAPrivateKey)) {
-            throw new InvalidKeyException("Private key is not " + SecurityUtils.EDDSA);
-        }
-
-        EdDSAPrivateKey prvKey = (EdDSAPrivateKey) key;
-        EdDSAPublicKeySpec keySpec = new EdDSAPublicKeySpec(prvKey.getAbyte(), prvKey.getParams());
-        KeyFactory factory = SecurityUtils.getKeyFactory(SecurityUtils.EDDSA);
-        return EdDSAPublicKey.class.cast(factory.generatePublic(keySpec));
-    }
-
-    public static org.apache.sshd.common.signature.Signature getEDDSASignature() {
-        ValidateUtils.checkTrue(SecurityUtils.isEDDSACurveSupported(), SecurityUtils.EDDSA + " not supported");
-        return new SignatureEd25519();
-    }
-
-    public static boolean isEDDSAKeyFactoryAlgorithm(String algorithm) {
-        return SecurityUtils.EDDSA.equalsIgnoreCase(algorithm);
-    }
-
-    public static boolean isEDDSAKeyPairGeneratorAlgorithm(String algorithm) {
-        return SecurityUtils.EDDSA.equalsIgnoreCase(algorithm);
-    }
-
-    public static PublicKeyEntryDecoder<? extends PublicKey, ? extends PrivateKey> getEDDSAPublicKeyEntryDecoder() {
-        ValidateUtils.checkTrue(SecurityUtils.isEDDSACurveSupported(), SecurityUtils.EDDSA + " not supported");
-        return Ed25519PublicKeyDecoder.INSTANCE;
-    }
-
-    public static PrivateKeyEntryDecoder<? extends PublicKey, ? extends PrivateKey> getOpenSSHEDDSAPrivateKeyEntryDecoder() {
-        ValidateUtils.checkTrue(SecurityUtils.isEDDSACurveSupported(), SecurityUtils.EDDSA + " not supported");
-        return OpenSSHEd25519PrivateKeyEntryDecoder.INSTANCE;
-    }
-
-    public static boolean compareEDDSAPrivateKeys(PrivateKey k1, PrivateKey k2) {
-        if (!SecurityUtils.isEDDSACurveSupported()) {
-            return false;
-        }
-
-        if ((k1 instanceof EdDSAPrivateKey) && (k2 instanceof EdDSAPrivateKey)) {
-            if (Objects.equals(k1, k2)) {
-                return true;
-            } else if (k1 == null || k2 == null) {
-                return false;   // both null is covered by Objects#equals
-            }
-
-            EdDSAPrivateKey ed1 = (EdDSAPrivateKey) k1;
-            EdDSAPrivateKey ed2 = (EdDSAPrivateKey) k2;
-            return Arrays.equals(ed1.getSeed(), ed2.getSeed())
-                && compareEDDSAKeyParams(ed1.getParams(), ed2.getParams());
-        }
-
-        return false;
-    }
-
-    public static boolean compareEDDSAKeyParams(EdDSAParameterSpec s1, EdDSAParameterSpec s2) {
-        if (Objects.equals(s1, s2)) {
-            return true;
-        } else if (s1 == null || s2 == null) {
-            return false;   // both null is covered by Objects#equals
-        } else {
-            return Objects.equals(s1.getHashAlgorithm(), s2.getHashAlgorithm())
-                && Objects.equals(s1.getCurve(), s2.getCurve())
-                && Objects.equals(s1.getB(), s2.getB());
-        }
-    }
-
-    public static PublicKey generateEDDSAPublicKey(byte[] seed) throws GeneralSecurityException {
-        if (!SecurityUtils.isEDDSACurveSupported()) {
-            throw new NoSuchAlgorithmException(SecurityUtils.EDDSA + " not supported");
-        }
-
-        EdDSAParameterSpec params = EdDSANamedCurveTable.getByName(CURVE_ED25519_SHA512);
-        EdDSAPublicKeySpec keySpec = new EdDSAPublicKeySpec(seed, params);
-        KeyFactory factory = SecurityUtils.getKeyFactory(SecurityUtils.EDDSA);
-        return factory.generatePublic(keySpec);
-    }
-
-    public static PrivateKey generateEDDSAPrivateKey(byte[] seed) throws GeneralSecurityException {
-        if (!SecurityUtils.isEDDSACurveSupported()) {
-            throw new NoSuchAlgorithmException(SecurityUtils.EDDSA + " not supported");
-        }
-
-        EdDSAParameterSpec params = EdDSANamedCurveTable.getByName(CURVE_ED25519_SHA512);
-        EdDSAPrivateKeySpec keySpec = new EdDSAPrivateKeySpec(seed, params);
-        KeyFactory factory = SecurityUtils.getKeyFactory(SecurityUtils.EDDSA);
-        return factory.generatePrivate(keySpec);
-    }
-
-    public static <B extends Buffer> B putRawEDDSAPublicKey(B buffer, PublicKey key) {
-        ValidateUtils.checkTrue(SecurityUtils.isEDDSACurveSupported(), SecurityUtils.EDDSA + " not supported");
-        EdDSAPublicKey edKey = ValidateUtils.checkInstanceOf(key, EdDSAPublicKey.class, "Not an EDDSA public key: %s", key);
-        byte[] seed = Ed25519PublicKeyDecoder.getSeedValue(edKey);
-        ValidateUtils.checkNotNull(seed, "No seed extracted from key: %s", edKey.getA());
-        buffer.putString(KeyPairProvider.SSH_ED25519);
-        buffer.putBytes(seed);
-        return buffer;
-    }
-
-    public static <B extends Buffer> B putEDDSAKeyPair(B buffer, PublicKey pubKey, PrivateKey prvKey) {
-        ValidateUtils.checkTrue(SecurityUtils.isEDDSACurveSupported(), SecurityUtils.EDDSA + " not supported");
-        ValidateUtils.checkInstanceOf(pubKey, EdDSAPublicKey.class, "Not an EDDSA public key: %s", pubKey);
-        ValidateUtils.checkInstanceOf(prvKey, EdDSAPrivateKey.class, "Not an EDDSA private key: %s", prvKey);
-        throw new UnsupportedOperationException("Full SSHD-440 implementation N/A");
-    }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-core/src/main/java/org/apache/sshd/common/util/security/eddsa/OpenSSHEd25519PrivateKeyEntryDecoder.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/util/security/eddsa/OpenSSHEd25519PrivateKeyEntryDecoder.java b/sshd-core/src/main/java/org/apache/sshd/common/util/security/eddsa/OpenSSHEd25519PrivateKeyEntryDecoder.java
deleted file mode 100644
index 4888818..0000000
--- a/sshd-core/src/main/java/org/apache/sshd/common/util/security/eddsa/OpenSSHEd25519PrivateKeyEntryDecoder.java
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.sshd.common.util.security.eddsa;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.security.GeneralSecurityException;
-import java.security.InvalidKeyException;
-import java.security.KeyFactory;
-import java.security.KeyPairGenerator;
-import java.security.NoSuchAlgorithmException;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Locale;
-import java.util.Objects;
-
-import org.apache.sshd.common.config.keys.FilePasswordProvider;
-import org.apache.sshd.common.config.keys.KeyEntryResolver;
-import org.apache.sshd.common.config.keys.impl.AbstractPrivateKeyEntryDecoder;
-import org.apache.sshd.common.keyprovider.KeyPairProvider;
-import org.apache.sshd.common.util.security.SecurityUtils;
-
-import net.i2p.crypto.eddsa.EdDSAPrivateKey;
-import net.i2p.crypto.eddsa.EdDSAPublicKey;
-import net.i2p.crypto.eddsa.spec.EdDSANamedCurveTable;
-import net.i2p.crypto.eddsa.spec.EdDSAParameterSpec;
-import net.i2p.crypto.eddsa.spec.EdDSAPrivateKeySpec;
-import net.i2p.crypto.eddsa.spec.EdDSAPublicKeySpec;
-
-/**
- * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
- */
-public class OpenSSHEd25519PrivateKeyEntryDecoder extends AbstractPrivateKeyEntryDecoder<EdDSAPublicKey, EdDSAPrivateKey> {
-    public static final OpenSSHEd25519PrivateKeyEntryDecoder INSTANCE = new OpenSSHEd25519PrivateKeyEntryDecoder();
-    private static final int PK_SIZE = 32;
-    private static final int SK_SIZE = 32;
-    private static final int KEYPAIR_SIZE = PK_SIZE + SK_SIZE;
-
-    public OpenSSHEd25519PrivateKeyEntryDecoder() {
-        super(EdDSAPublicKey.class, EdDSAPrivateKey.class, Collections.unmodifiableList(Collections.singletonList(KeyPairProvider.SSH_ED25519)));
-    }
-
-    @Override
-    public EdDSAPrivateKey decodePrivateKey(String keyType, FilePasswordProvider passwordProvider, InputStream keyData)
-            throws IOException, GeneralSecurityException {
-        if (!KeyPairProvider.SSH_ED25519.equals(keyType)) {
-            throw new InvalidKeyException("Unsupported key type: " + keyType);
-        }
-
-        if (!SecurityUtils.isEDDSACurveSupported()) {
-            throw new NoSuchAlgorithmException(SecurityUtils.EDDSA + " provider not supported");
-        }
-
-        // ed25519 bernstein naming: pk .. public key, sk .. secret key
-        // we expect to find two byte arrays with the following structure (type:size):
-        // [pk:32], [sk:32,pk:32]
-
-        byte[] pk = KeyEntryResolver.readRLEBytes(keyData);
-        byte[] keypair = KeyEntryResolver.readRLEBytes(keyData);
-
-        if (pk.length != PK_SIZE) {
-            throw new InvalidKeyException(String.format(Locale.ENGLISH, "Unexpected pk size: %s (expected %s)", pk.length, PK_SIZE));
-        }
-
-        if (keypair.length != KEYPAIR_SIZE) {
-            throw new InvalidKeyException(String.format(Locale.ENGLISH, "Unexpected keypair size: %s (expected %s)", keypair.length, KEYPAIR_SIZE));
-        }
-
-        byte[] sk = Arrays.copyOf(keypair, SK_SIZE);
-
-        // verify that the keypair contains the expected pk
-        // yes, it's stored redundant, this seems to mimic the output structure of the keypair generation interface
-        if (!Arrays.equals(pk, Arrays.copyOfRange(keypair, SK_SIZE, KEYPAIR_SIZE))) {
-            throw new InvalidKeyException("Keypair did not contain the public key.");
-        }
-
-        // create the private key
-        EdDSAParameterSpec params = EdDSANamedCurveTable.getByName(EdDSASecurityProviderUtils.CURVE_ED25519_SHA512);
-        EdDSAPrivateKey privateKey = generatePrivateKey(new EdDSAPrivateKeySpec(sk, params));
-
-        // the private key class contains the calculated public key (Abyte)
-        // pointers to the corresponding code:
-        // EdDSAPrivateKeySpec.EdDSAPrivateKeySpec(byte[], EdDSAParameterSpec): A = spec.getB().scalarMultiply(a);
-        // EdDSAPrivateKey.EdDSAPrivateKey(EdDSAPrivateKeySpec): this.Abyte = this.A.toByteArray();
-
-        // we can now verify the generated pk matches the one we read
-        if (!Arrays.equals(privateKey.getAbyte(), pk)) {
-            throw new InvalidKeyException("The provided pk does NOT match the computed pk for the given sk.");
-        }
-
-        return privateKey;
-    }
-
-    @Override
-    public String encodePrivateKey(OutputStream s, EdDSAPrivateKey key) throws IOException {
-        Objects.requireNonNull(key, "No private key provided");
-
-        // ed25519 bernstein naming: pk .. public key, sk .. secret key
-        // we are expected to write the following arrays (type:size):
-        // [pk:32], [sk:32,pk:32]
-
-        byte[] sk = key.getSeed();
-        byte[] pk = key.getAbyte();
-
-        Objects.requireNonNull(sk, "No seed");
-
-        byte[] keypair = new byte[KEYPAIR_SIZE];
-        System.arraycopy(sk, 0, keypair, 0, SK_SIZE);
-        System.arraycopy(pk, 0, keypair, SK_SIZE, PK_SIZE);
-
-        KeyEntryResolver.writeRLEBytes(s, pk);
-        KeyEntryResolver.writeRLEBytes(s, keypair);
-
-        return KeyPairProvider.SSH_ED25519;
-    }
-
-    @Override
-    public boolean isPublicKeyRecoverySupported() {
-        return true;
-    }
-
-    @Override
-    public EdDSAPublicKey recoverPublicKey(EdDSAPrivateKey prvKey) throws GeneralSecurityException {
-        return EdDSASecurityProviderUtils.recoverEDDSAPublicKey(prvKey);
-    }
-
-    @Override
-    public EdDSAPublicKey clonePublicKey(EdDSAPublicKey key) throws GeneralSecurityException {
-        if (key == null) {
-            return null;
-        } else {
-            return generatePublicKey(new EdDSAPublicKeySpec(key.getA(), key.getParams()));
-        }
-    }
-
-    @Override
-    public EdDSAPrivateKey clonePrivateKey(EdDSAPrivateKey key) throws GeneralSecurityException {
-        if (key == null) {
-            return null;
-        } else {
-            return generatePrivateKey(new EdDSAPrivateKeySpec(key.getSeed(), key.getParams()));
-        }
-    }
-
-    @Override
-    public KeyPairGenerator getKeyPairGenerator() throws GeneralSecurityException {
-        return SecurityUtils.getKeyPairGenerator(SecurityUtils.EDDSA);
-    }
-
-    @Override
-    public KeyFactory getKeyFactoryInstance() throws GeneralSecurityException {
-        return SecurityUtils.getKeyFactory(SecurityUtils.EDDSA);
-    }
-}

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-core/src/main/java/org/apache/sshd/common/util/security/eddsa/SignatureEd25519.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/util/security/eddsa/SignatureEd25519.java b/sshd-core/src/main/java/org/apache/sshd/common/util/security/eddsa/SignatureEd25519.java
deleted file mode 100644
index 012be95..0000000
--- a/sshd-core/src/main/java/org/apache/sshd/common/util/security/eddsa/SignatureEd25519.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.sshd.common.util.security.eddsa;
-
-import java.util.Map;
-
-import org.apache.sshd.common.keyprovider.KeyPairProvider;
-import org.apache.sshd.common.signature.AbstractSignature;
-import org.apache.sshd.common.util.ValidateUtils;
-
-import net.i2p.crypto.eddsa.EdDSAEngine;
-
-/**
- * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
- */
-public class SignatureEd25519 extends AbstractSignature {
-    public SignatureEd25519() {
-        super(EdDSAEngine.SIGNATURE_ALGORITHM);
-    }
-
-    @Override
-    public boolean verify(byte[] sig) throws Exception {
-        byte[] data = sig;
-        Map.Entry<String, byte[]> encoding = extractEncodedSignature(data);
-        if (encoding != null) {
-            String keyType = encoding.getKey();
-            ValidateUtils.checkTrue(KeyPairProvider.SSH_ED25519.equals(keyType), "Mismatched key type: %s", keyType);
-            data = encoding.getValue();
-        }
-
-        return doVerify(data);
-    }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-core/src/main/java/org/apache/sshd/common/util/threads/CloseableExecutorService.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/util/threads/CloseableExecutorService.java b/sshd-core/src/main/java/org/apache/sshd/common/util/threads/CloseableExecutorService.java
deleted file mode 100644
index 3b9beeb..0000000
--- a/sshd-core/src/main/java/org/apache/sshd/common/util/threads/CloseableExecutorService.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.sshd.common.util.threads;
-
-import java.util.concurrent.ExecutorService;
-
-import org.apache.sshd.common.Closeable;
-
-public interface CloseableExecutorService extends ExecutorService, Closeable {
-    // Nothing extra
-}

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-core/src/main/java/org/apache/sshd/common/util/threads/ExecutorServiceCarrier.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/util/threads/ExecutorServiceCarrier.java b/sshd-core/src/main/java/org/apache/sshd/common/util/threads/ExecutorServiceCarrier.java
deleted file mode 100644
index b44bd46..0000000
--- a/sshd-core/src/main/java/org/apache/sshd/common/util/threads/ExecutorServiceCarrier.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.sshd.common.util.threads;
-
-/**
- * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
- */
-public interface ExecutorServiceCarrier {
-    /**
-     * @return The {@link CloseableExecutorService} to use
-     */
-    CloseableExecutorService getExecutorService();
-
-}

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-core/src/main/java/org/apache/sshd/common/util/threads/NoCloseExecutor.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/util/threads/NoCloseExecutor.java b/sshd-core/src/main/java/org/apache/sshd/common/util/threads/NoCloseExecutor.java
deleted file mode 100644
index cb42805..0000000
--- a/sshd-core/src/main/java/org/apache/sshd/common/util/threads/NoCloseExecutor.java
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.sshd.common.util.threads;
-
-import java.io.IOException;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Future;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-
-import org.apache.sshd.common.future.CloseFuture;
-import org.apache.sshd.common.future.DefaultCloseFuture;
-import org.apache.sshd.common.future.SshFutureListener;
-import org.apache.sshd.common.util.ValidateUtils;
-
-/**
- * Wraps an {@link ExecutorService} as a {@link CloseableExecutorService}
- * and avoids calling its {@code shutdown} methods when the wrapper is shut down
- *
- * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
- */
-public class NoCloseExecutor implements CloseableExecutorService {
-    protected final ExecutorService executor;
-    protected final CloseFuture closeFuture;
-
-    public NoCloseExecutor(ExecutorService executor) {
-        this.executor = executor;
-        closeFuture = new DefaultCloseFuture(null, null);
-    }
-
-    @Override
-    public <T> Future<T> submit(Callable<T> task) {
-        ValidateUtils.checkState(!isShutdown(), "Executor has been shut down");
-        return executor.submit(task);
-    }
-
-    @Override
-    public <T> Future<T> submit(Runnable task, T result) {
-        ValidateUtils.checkState(!isShutdown(), "Executor has been shut down");
-        return executor.submit(task, result);
-    }
-
-    @Override
-    public Future<?> submit(Runnable task) {
-        ValidateUtils.checkState(!isShutdown(), "Executor has been shut down");
-        return executor.submit(task);
-    }
-
-    @Override
-    public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
-            throws InterruptedException {
-        ValidateUtils.checkState(!isShutdown(), "Executor has been shut down");
-        return executor.invokeAll(tasks);
-    }
-
-    @Override
-    public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit)
-            throws InterruptedException {
-        ValidateUtils.checkState(!isShutdown(), "Executor has been shut down");
-        return executor.invokeAll(tasks, timeout, unit);
-    }
-
-    @Override
-    public <T> T invokeAny(Collection<? extends Callable<T>> tasks)
-            throws InterruptedException, ExecutionException {
-        ValidateUtils.checkState(!isShutdown(), "Executor has been shut down");
-        return executor.invokeAny(tasks);
-    }
-
-    @Override
-    public <T> T invokeAny(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit)
-            throws InterruptedException, ExecutionException, TimeoutException {
-        ValidateUtils.checkState(!isShutdown(), "Executor has been shut down");
-        return executor.invokeAny(tasks, timeout, unit);
-    }
-
-    @Override
-    public void execute(Runnable command) {
-        ValidateUtils.checkState(!isShutdown(), "Executor has been shut down");
-        executor.execute(command);
-    }
-
-    @Override
-    public void shutdown() {
-        close(true);
-    }
-
-    @Override
-    public List<Runnable> shutdownNow() {
-        close(true);
-        return Collections.emptyList();
-    }
-
-    @Override
-    public boolean isShutdown() {
-        return isClosed();
-    }
-
-    @Override
-    public boolean isTerminated() {
-        return isClosed();
-    }
-
-    @Override
-    public boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException {
-        try {
-            return closeFuture.await(timeout, unit);
-        } catch (IOException e) {
-            throw (InterruptedException) new InterruptedException().initCause(e);
-        }
-    }
-
-    @Override
-    public CloseFuture close(boolean immediately) {
-        closeFuture.setClosed();
-        return closeFuture;
-    }
-
-    @Override
-    public void addCloseFutureListener(SshFutureListener<CloseFuture> listener) {
-        closeFuture.addListener(listener);
-    }
-
-    @Override
-    public void removeCloseFutureListener(SshFutureListener<CloseFuture> listener) {
-        closeFuture.removeListener(listener);
-    }
-
-    @Override
-    public boolean isClosed() {
-        return closeFuture.isClosed();
-    }
-
-    @Override
-    public boolean isClosing() {
-        return isClosed();
-    }
-
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-core/src/main/java/org/apache/sshd/common/util/threads/SshThreadPoolExecutor.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/util/threads/SshThreadPoolExecutor.java b/sshd-core/src/main/java/org/apache/sshd/common/util/threads/SshThreadPoolExecutor.java
deleted file mode 100644
index ccaa655..0000000
--- a/sshd-core/src/main/java/org/apache/sshd/common/util/threads/SshThreadPoolExecutor.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.sshd.common.util.threads;
-
-import java.util.List;
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.RejectedExecutionHandler;
-import java.util.concurrent.ThreadFactory;
-import java.util.concurrent.ThreadPoolExecutor;
-import java.util.concurrent.TimeUnit;
-
-import org.apache.sshd.common.future.CloseFuture;
-import org.apache.sshd.common.future.SshFutureListener;
-import org.apache.sshd.common.util.closeable.AbstractCloseable;
-
-/**
- * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
- */
-public class SshThreadPoolExecutor extends ThreadPoolExecutor implements CloseableExecutorService {
-    protected final DelegateCloseable closeable = new DelegateCloseable();
-
-    protected class DelegateCloseable extends AbstractCloseable {
-        protected DelegateCloseable() {
-            super();
-        }
-
-        @Override
-        protected CloseFuture doCloseGracefully() {
-            shutdown();
-            return closeFuture;
-        }
-
-        @Override
-        protected void doCloseImmediately() {
-            shutdownNow();
-            super.doCloseImmediately();
-        }
-
-        protected void setClosed() {
-            closeFuture.setClosed();
-        }
-    }
-
-    public SshThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) {
-        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
-    }
-
-    public SshThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit,
-            BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory) {
-        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory);
-    }
-
-    public SshThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit,
-            BlockingQueue<Runnable> workQueue, RejectedExecutionHandler handler) {
-        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, handler);
-    }
-
-    public SshThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit,
-            BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler) {
-        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, handler);
-    }
-
-    @Override
-    protected void terminated() {
-        closeable.doCloseImmediately();
-    }
-
-    @Override
-    public void shutdown() {
-        super.shutdown();
-    }
-
-    @Override
-    public List<Runnable> shutdownNow() {
-        return super.shutdownNow();
-    }
-
-    @Override
-    public boolean isShutdown() {
-        return super.isShutdown();
-    }
-
-    @Override
-    public boolean isTerminating() {
-        return super.isTerminating();
-    }
-
-    @Override
-    public boolean isTerminated() {
-        return super.isTerminated();
-    }
-
-    @Override
-    public boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException {
-        return super.awaitTermination(timeout, unit);
-    }
-
-    @Override
-    public CloseFuture close(boolean immediately) {
-        return closeable.close(immediately);
-    }
-
-    @Override
-    public void addCloseFutureListener(SshFutureListener<CloseFuture> listener) {
-        closeable.addCloseFutureListener(listener);
-    }
-
-    @Override
-    public void removeCloseFutureListener(SshFutureListener<CloseFuture> listener) {
-        closeable.removeCloseFutureListener(listener);
-    }
-
-    @Override
-    public boolean isClosed() {
-        return closeable.isClosed();
-    }
-
-    @Override
-    public boolean isClosing() {
-        return closeable.isClosing();
-    }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-core/src/main/java/org/apache/sshd/common/util/threads/SshdThreadFactory.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/util/threads/SshdThreadFactory.java b/sshd-core/src/main/java/org/apache/sshd/common/util/threads/SshdThreadFactory.java
deleted file mode 100644
index 5dc0c7b..0000000
--- a/sshd-core/src/main/java/org/apache/sshd/common/util/threads/SshdThreadFactory.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.sshd.common.util.threads;
-
-import java.security.AccessController;
-import java.security.PrivilegedActionException;
-import java.security.PrivilegedExceptionAction;
-import java.util.concurrent.ThreadFactory;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import org.apache.sshd.common.util.logging.AbstractLoggingBean;
-
-/**
- * Default {@link ThreadFactory} used by {@link ThreadUtils} to create
- * thread pools if user did provide one
- *
- * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
- */
-public class SshdThreadFactory extends AbstractLoggingBean implements ThreadFactory {
-    private final ThreadGroup group;
-    private final AtomicInteger threadNumber = new AtomicInteger(1);
-    private final String namePrefix;
-
-    public SshdThreadFactory(String name) {
-        SecurityManager s = System.getSecurityManager();
-        group = (s != null) ? s.getThreadGroup() : Thread.currentThread().getThreadGroup();
-        String effectiveName = name.replace(' ', '-');
-        namePrefix = "sshd-" + effectiveName + "-thread-";
-    }
-
-    @Override
-    public Thread newThread(Runnable r) {
-        Thread t;
-        try {
-            // see SSHD-668
-            if (System.getSecurityManager() != null) {
-                t = AccessController.doPrivileged((PrivilegedExceptionAction<Thread>) () ->
-                        new Thread(group, r, namePrefix + threadNumber.getAndIncrement(), 0));
-            } else {
-                t = new Thread(group, r, namePrefix + threadNumber.getAndIncrement(), 0);
-            }
-        } catch (PrivilegedActionException e) {
-            Exception err = e.getException();
-            if (err instanceof RuntimeException) {
-                throw (RuntimeException) err;
-            } else {
-                throw new RuntimeException(err);
-            }
-        }
-
-        if (!t.isDaemon()) {
-            t.setDaemon(true);
-        }
-        if (t.getPriority() != Thread.NORM_PRIORITY) {
-            t.setPriority(Thread.NORM_PRIORITY);
-        }
-        if (log.isTraceEnabled()) {
-            log.trace("newThread({})[{}] runnable={}", group, t.getName(), r);
-        }
-        return t;
-    }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-core/src/main/java/org/apache/sshd/common/util/threads/ThreadUtils.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/util/threads/ThreadUtils.java b/sshd-core/src/main/java/org/apache/sshd/common/util/threads/ThreadUtils.java
deleted file mode 100644
index c803389..0000000
--- a/sshd-core/src/main/java/org/apache/sshd/common/util/threads/ThreadUtils.java
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.sshd.common.util.threads;
-
-import java.util.LinkedHashSet;
-import java.util.Set;
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.ScheduledThreadPoolExecutor;
-import java.util.concurrent.SynchronousQueue;
-import java.util.concurrent.ThreadPoolExecutor;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Utility class for thread pools.
- *
- * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
- */
-public final class ThreadUtils {
-    private ThreadUtils() {
-        throw new UnsupportedOperationException("No instance");
-    }
-
-    /**
-     * Wraps an {@link CloseableExecutorService} in such a way as to &quot;protect&quot;
-     * it for calls to the {@link CloseableExecutorService#shutdown()} or
-     * {@link CloseableExecutorService#shutdownNow()}. All other calls are delegated as-is
-     * to the original service. <B>Note:</B> the exposed wrapped proxy will
-     * answer correctly the {@link CloseableExecutorService#isShutdown()} query if indeed
-     * one of the {@code shutdown} methods was invoked.
-     *
-     * @param executorService The original service - ignored if {@code null}
-     * @param shutdownOnExit  If {@code true} then it is OK to shutdown the executor
-     *                        so no wrapping takes place.
-     * @return Either the original service or a wrapped one - depending on the
-     * value of the <tt>shutdownOnExit</tt> parameter
-     */
-    public static CloseableExecutorService protectExecutorServiceShutdown(CloseableExecutorService executorService, boolean shutdownOnExit) {
-        if (executorService == null || shutdownOnExit || executorService instanceof NoCloseExecutor) {
-            return executorService;
-        } else {
-            return new NoCloseExecutor(executorService);
-        }
-    }
-
-    public static CloseableExecutorService noClose(CloseableExecutorService executorService) {
-        return protectExecutorServiceShutdown(executorService, false);
-    }
-
-    public static ClassLoader resolveDefaultClassLoader(Object anchor) {
-        return resolveDefaultClassLoader(anchor == null ? null : anchor.getClass());
-    }
-
-    public static Iterable<ClassLoader> resolveDefaultClassLoaders(Object anchor) {
-        return resolveDefaultClassLoaders(anchor == null ? null : anchor.getClass());
-    }
-
-    public static <T> T createDefaultInstance(Class<?> anchor, Class<T> targetType, String className)
-            throws ReflectiveOperationException {
-        return createDefaultInstance(resolveDefaultClassLoaders(anchor), targetType, className);
-    }
-
-    public static <T> T createDefaultInstance(ClassLoader cl, Class<T> targetType, String className)
-            throws ReflectiveOperationException {
-        Class<?> instanceType = cl.loadClass(className);
-        Object instance = instanceType.newInstance();
-        return targetType.cast(instance);
-    }
-
-    public static <T> T createDefaultInstance(Iterable<ClassLoader> cls, Class<T> targetType, String className)
-            throws ReflectiveOperationException {
-        for (ClassLoader cl : cls) {
-            try {
-                return createDefaultInstance(cl, targetType, className);
-            } catch (ClassNotFoundException e) {
-                // Ignore
-            }
-        }
-        throw new ClassNotFoundException(className);
-    }
-
-    /**
-     * <P>Attempts to find the most suitable {@link ClassLoader} as follows:</P>
-     * <UL>
-     * <LI><P>
-     * Check the {@link Thread#getContextClassLoader()} value
-     * </P></LI>
-     *
-     * <LI><P>
-     * If no thread context class loader then check the anchor
-     * class (if given) for its class loader
-     * </P></LI>
-     *
-     * <LI><P>
-     * If still no loader available, then use {@link ClassLoader#getSystemClassLoader()}
-     * </P></LI>
-     * </UL>
-     *
-     * @param anchor The anchor {@link Class} to use if no current thread
-     *               - ignored if {@code null}
-     *               context class loader
-     * @return The resolver {@link ClassLoader}
-     */
-    public static ClassLoader resolveDefaultClassLoader(Class<?> anchor) {
-        Thread thread = Thread.currentThread();
-        ClassLoader cl = thread.getContextClassLoader();
-        if (cl != null) {
-            return cl;
-        }
-
-        if (anchor != null) {
-            cl = anchor.getClassLoader();
-        }
-
-        if (cl == null) {   // can happen for core Java classes
-            cl = ClassLoader.getSystemClassLoader();
-        }
-
-        return cl;
-    }
-
-    public static Iterable<ClassLoader> resolveDefaultClassLoaders(Class<?> anchor) {
-        Set<ClassLoader> cls = new LinkedHashSet<>();
-        Thread thread = Thread.currentThread();
-        ClassLoader cl = thread.getContextClassLoader();
-        if (cl != null) {
-            cls.add(cl);
-        }
-        if (anchor != null) {
-            cls.add(anchor.getClassLoader());
-        }
-        cls.add(ClassLoader.getSystemClassLoader());
-        return cls;
-    }
-
-    public static CloseableExecutorService newFixedThreadPoolIf(CloseableExecutorService executorService, String poolName, int nThreads) {
-        return executorService == null ? newFixedThreadPool(poolName, nThreads) : executorService;
-    }
-
-    public static CloseableExecutorService newFixedThreadPool(String poolName, int nThreads) {
-        return new SshThreadPoolExecutor(
-                nThreads, nThreads,
-                0L, TimeUnit.MILLISECONDS, // TODO make this configurable
-                new LinkedBlockingQueue<>(),
-                new SshdThreadFactory(poolName),
-                new ThreadPoolExecutor.CallerRunsPolicy());
-    }
-
-    public static CloseableExecutorService newCachedThreadPoolIf(CloseableExecutorService executorService, String poolName) {
-        return executorService == null ? newCachedThreadPool(poolName) : executorService;
-    }
-
-    public static CloseableExecutorService newCachedThreadPool(String poolName) {
-        return new SshThreadPoolExecutor(
-                0, Integer.MAX_VALUE, // TODO make this configurable
-                60L, TimeUnit.SECONDS, // TODO make this configurable
-                new SynchronousQueue<>(),
-                new SshdThreadFactory(poolName),
-                new ThreadPoolExecutor.CallerRunsPolicy());
-    }
-
-    public static ScheduledExecutorService newSingleThreadScheduledExecutor(String poolName) {
-        return new ScheduledThreadPoolExecutor(1, new SshdThreadFactory(poolName));
-    }
-
-    public static CloseableExecutorService newSingleThreadExecutor(String poolName) {
-        return newFixedThreadPool(poolName, 1);
-    }
-}

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-core/src/main/java/org/apache/sshd/server/auth/pubkey/PublickeyAuthenticator.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/auth/pubkey/PublickeyAuthenticator.java b/sshd-core/src/main/java/org/apache/sshd/server/auth/pubkey/PublickeyAuthenticator.java
index 2d7a908..a498478 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/auth/pubkey/PublickeyAuthenticator.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/auth/pubkey/PublickeyAuthenticator.java
@@ -18,8 +18,14 @@
  */
 package org.apache.sshd.server.auth.pubkey;
 
+import java.io.IOException;
+import java.security.GeneralSecurityException;
 import java.security.PublicKey;
+import java.util.Collection;
 
+import org.apache.sshd.common.config.keys.AuthorizedKeyEntry;
+import org.apache.sshd.common.config.keys.PublicKeyEntryResolver;
+import org.apache.sshd.common.util.GenericUtils;
 import org.apache.sshd.server.auth.AsyncAuthException;
 import org.apache.sshd.server.session.ServerSession;
 
@@ -42,4 +48,15 @@ public interface PublickeyAuthenticator {
      * @throws AsyncAuthException If the authentication is performed asynchronously
      */
     boolean authenticate(String username, PublicKey key, ServerSession session) throws AsyncAuthException;
+
+    static PublickeyAuthenticator fromAuthorizedEntries(
+                PublicKeyEntryResolver fallbackResolver, Collection<? extends AuthorizedKeyEntry> entries)
+            throws IOException, GeneralSecurityException {
+        Collection<PublicKey> keys = AuthorizedKeyEntry.resolveAuthorizedKeys(fallbackResolver, entries);
+        if (GenericUtils.isEmpty(keys)) {
+            return RejectAllPublickeyAuthenticator.INSTANCE;
+        } else {
+            return new KeySetPublickeyAuthenticator(keys);
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-core/src/main/java/org/apache/sshd/server/config/SshServerConfigFileReader.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/config/SshServerConfigFileReader.java b/sshd-core/src/main/java/org/apache/sshd/server/config/SshServerConfigFileReader.java
index 381d2a3..bf4a958 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/config/SshServerConfigFileReader.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/config/SshServerConfigFileReader.java
@@ -22,6 +22,7 @@ import java.nio.file.Paths;
 
 import org.apache.sshd.common.PropertyResolver;
 import org.apache.sshd.common.PropertyResolverUtils;
+import org.apache.sshd.common.config.ConfigFileReaderSupport;
 import org.apache.sshd.common.config.SshConfigFileReader;
 import org.apache.sshd.common.helpers.AbstractFactoryManager;
 import org.apache.sshd.common.util.GenericUtils;
@@ -62,7 +63,8 @@ public final class SshServerConfigFileReader {
         throw new UnsupportedOperationException("No instance allowed");
     }
 
-    public static <S extends SshServer> S configure(S server, PropertyResolver props, boolean lenient, boolean ignoreUnsupported) {
+    public static <S extends SshServer> S configure(
+            S server, PropertyResolver props, boolean lenient, boolean ignoreUnsupported) {
         SshConfigFileReader.configure((AbstractFactoryManager) server, props, lenient, ignoreUnsupported);
         SshConfigFileReader.configureKeyExchanges(server, props, lenient, ServerBuilder.DH2KEX, ignoreUnsupported);
         return server;
@@ -80,27 +82,31 @@ public final class SshServerConfigFileReader {
     }
 
     public static AgentForwardingFilter resolveAgentForwardingFilter(PropertyResolver options) {
-        String value = PropertyResolverUtils.getStringProperty(options, ALLOW_AGENT_FORWARDING_CONFIG_PROP, DEFAULT_AGENT_FORWARDING);
-        return AgentForwardingFilter.of(SshConfigFileReader.parseBooleanValue(value));
+        String value = PropertyResolverUtils.getStringProperty(options,
+            ALLOW_AGENT_FORWARDING_CONFIG_PROP, DEFAULT_AGENT_FORWARDING);
+        return AgentForwardingFilter.of(ConfigFileReaderSupport.parseBooleanValue(value));
     }
 
     public static TcpForwardingFilter resolveTcpForwardingFilter(PropertyResolver options) {
-        String value = PropertyResolverUtils.getStringProperty(options, ALLOW_TCP_FORWARDING_CONFIG_PROP, DEFAULT_TCP_FORWARDING);
+        String value = PropertyResolverUtils.getStringProperty(options,
+            ALLOW_TCP_FORWARDING_CONFIG_PROP, DEFAULT_TCP_FORWARDING);
         TcpForwardingFilter filter = AllowTcpForwardingValue.fromString(value);
         ValidateUtils.checkNotNull(filter, "Unknown %s value: %s", ALLOW_TCP_FORWARDING_CONFIG_PROP, value);
         return filter;
     }
 
     public static X11ForwardingFilter resolveX11ForwardingFilter(PropertyResolver options) {
-        String value = PropertyResolverUtils.getStringProperty(options, ALLOW_X11_FORWARDING_CONFIG_PROP, DEFAULT_X11_FORWARDING);
-        return X11ForwardingFilter.of(SshConfigFileReader.parseBooleanValue(value));
+        String value = PropertyResolverUtils.getStringProperty(options,
+            ALLOW_X11_FORWARDING_CONFIG_PROP, DEFAULT_X11_FORWARDING);
+        return X11ForwardingFilter.of(ConfigFileReaderSupport.parseBooleanValue(value));
     }
 
     public static Object resolveBanner(PropertyResolver options) {
         String bannerOption = PropertyResolverUtils.getString(options, BANNER_CONFIG_PROP);
         if (GenericUtils.isEmpty(bannerOption)) {
-            bannerOption = PropertyResolverUtils.getStringProperty(options, VISUAL_HOST_KEY, DEFAULT_VISUAL_HOST_KEY);
-            if (SshConfigFileReader.parseBooleanValue(bannerOption)) {
+            bannerOption = PropertyResolverUtils.getStringProperty(options,
+                VISUAL_HOST_KEY, DEFAULT_VISUAL_HOST_KEY);
+            if (ConfigFileReaderSupport.parseBooleanValue(bannerOption)) {
                 bannerOption = ServerAuthenticationManager.AUTO_WELCOME_BANNER_VALUE;
             } else {
                 bannerOption = null;

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-core/src/main/java/org/apache/sshd/server/config/keys/AuthorizedKeysAuthenticator.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/config/keys/AuthorizedKeysAuthenticator.java b/sshd-core/src/main/java/org/apache/sshd/server/config/keys/AuthorizedKeysAuthenticator.java
index cfc7ba1..b05837b 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/config/keys/AuthorizedKeysAuthenticator.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/config/keys/AuthorizedKeysAuthenticator.java
@@ -131,7 +131,9 @@ public class AuthorizedKeysAuthenticator extends ModifiableFileWatcher implement
             if (exists()) {
                 Collection<AuthorizedKeyEntry> entries = reloadAuthorizedKeys(path, username, session);
                 if (GenericUtils.size(entries) > 0) {
-                    delegateHolder.set(AuthorizedKeyEntry.fromAuthorizedEntries(getFallbackPublicKeyEntryResolver(), entries));
+                    PublickeyAuthenticator authDelegate =
+                        PublickeyAuthenticator.fromAuthorizedEntries(getFallbackPublicKeyEntryResolver(), entries);
+                    delegateHolder.set(authDelegate);
                 }
             } else {
                 log.info("resolvePublickeyAuthenticator(" + username + ")[" + session + "] no authorized keys file at " + path);

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-core/src/main/java/org/apache/sshd/server/keyprovider/AbstractGeneratorHostKeyProvider.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/keyprovider/AbstractGeneratorHostKeyProvider.java b/sshd-core/src/main/java/org/apache/sshd/server/keyprovider/AbstractGeneratorHostKeyProvider.java
deleted file mode 100644
index 9131f99..0000000
--- a/sshd-core/src/main/java/org/apache/sshd/server/keyprovider/AbstractGeneratorHostKeyProvider.java
+++ /dev/null
@@ -1,293 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.sshd.server.keyprovider;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.nio.file.Files;
-import java.nio.file.LinkOption;
-import java.nio.file.OpenOption;
-import java.nio.file.Path;
-import java.security.GeneralSecurityException;
-import java.security.KeyPair;
-import java.security.KeyPairGenerator;
-import java.security.PublicKey;
-import java.security.spec.AlgorithmParameterSpec;
-import java.util.Collections;
-import java.util.List;
-import java.util.Objects;
-import java.util.concurrent.atomic.AtomicReference;
-
-import org.apache.sshd.common.cipher.ECCurves;
-import org.apache.sshd.common.config.keys.BuiltinIdentities;
-import org.apache.sshd.common.config.keys.KeyUtils;
-import org.apache.sshd.common.keyprovider.AbstractKeyPairProvider;
-import org.apache.sshd.common.util.io.IoUtils;
-import org.apache.sshd.common.util.security.SecurityUtils;
-
-/**
- * Holds a <U>single</U> {@link KeyPair} which is generated the 1st time
- * {@link #loadKeys()} is called. If there is a file backing it up and the
- * file exists, the key is loaded from it. Otherwise a new key pair is
- * generated and saved (provided a path is configured and {@link #isOverwriteAllowed()}
- *
- * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
- */
-public abstract class AbstractGeneratorHostKeyProvider extends AbstractKeyPairProvider {
-    public static final String DEFAULT_ALGORITHM = KeyUtils.RSA_ALGORITHM;
-    public static final boolean DEFAULT_ALLOWED_TO_OVERWRITE = true;
-
-    private final AtomicReference<KeyPair> keyPairHolder = new AtomicReference<>();
-
-    private Path path;
-    private String algorithm = DEFAULT_ALGORITHM;
-    private int keySize;
-    private AlgorithmParameterSpec keySpec;
-    private boolean overwriteAllowed = DEFAULT_ALLOWED_TO_OVERWRITE;
-
-    protected AbstractGeneratorHostKeyProvider() {
-        super();
-    }
-
-    public Path getPath() {
-        return path;
-    }
-
-    public void setFile(File file) {
-        setPath((file == null) ? null : file.toPath());
-    }
-
-    public void setPath(Path path) {
-        this.path = (path == null) ? null : path.toAbsolutePath();
-    }
-
-    public String getAlgorithm() {
-        return algorithm;
-    }
-
-    public void setAlgorithm(String algorithm) {
-        this.algorithm = algorithm;
-    }
-
-    public int getKeySize() {
-        return keySize;
-    }
-
-    public void setKeySize(int keySize) {
-        this.keySize = keySize;
-    }
-
-    public AlgorithmParameterSpec getKeySpec() {
-        return keySpec;
-    }
-
-    public void setKeySpec(AlgorithmParameterSpec keySpec) {
-        this.keySpec = keySpec;
-    }
-
-    public boolean isOverwriteAllowed() {
-        return overwriteAllowed;
-    }
-
-    public void setOverwriteAllowed(boolean overwriteAllowed) {
-        this.overwriteAllowed = overwriteAllowed;
-    }
-
-    public void clearLoadedKeys() {
-        KeyPair kp;
-        synchronized (keyPairHolder) {
-            kp = keyPairHolder.getAndSet(null);
-        }
-
-        if ((kp != null) & log.isDebugEnabled()) {
-            PublicKey key = kp.getPublic();
-            log.debug("clearLoadedKeys({}) removed key={}-{}",
-                      getPath(), KeyUtils.getKeyType(key), KeyUtils.getFingerPrint(key));
-        }
-    }
-
-    @Override   // co-variant return
-    public synchronized List<KeyPair> loadKeys() {
-        Path keyPath = getPath();
-        KeyPair kp;
-        synchronized (keyPairHolder) {
-            kp = keyPairHolder.get();
-            if (kp == null) {
-                try {
-                    kp = resolveKeyPair(keyPath);
-                    if (kp != null) {
-                        keyPairHolder.set(kp);
-                    }
-                } catch (Throwable t) {
-                    log.warn("loadKeys({}) Failed ({}) to resolve: {}",
-                            keyPath, t.getClass().getSimpleName(), t.getMessage());
-                    if (log.isDebugEnabled()) {
-                        log.debug("loadKeys(" + keyPath + ") resolution failure details", t);
-                    }
-                }
-            }
-        }
-
-        if (kp == null) {
-            return Collections.emptyList();
-        } else {
-            return Collections.singletonList(kp);
-        }
-    }
-
-    protected KeyPair resolveKeyPair(Path keyPath) throws IOException, GeneralSecurityException {
-        String alg = getAlgorithm();
-        KeyPair kp;
-        if (keyPath != null) {
-            try {
-                kp = loadFromFile(alg, keyPath);
-                if (kp != null) {
-                    return kp;
-                }
-            } catch (Throwable e) {
-                log.warn("resolveKeyPair({}) Failed ({}) to load: {}",
-                        keyPath, e.getClass().getSimpleName(), e.getMessage());
-                if (log.isDebugEnabled()) {
-                    log.debug("resolveKeyPair(" + keyPath + ") load failure details", e);
-                }
-            }
-        }
-
-        // either no file specified or no key in file
-        try {
-            kp = generateKeyPair(alg);
-            if (kp == null) {
-                return null;
-            }
-
-            if (log.isDebugEnabled()) {
-                PublicKey key = kp.getPublic();
-                log.debug("resolveKeyPair({}) generated {} key={}-{}",
-                          keyPath, alg, KeyUtils.getKeyType(key), KeyUtils.getFingerPrint(key));
-            }
-        } catch (Throwable e) {
-            log.warn("resolveKeyPair({})[{}] Failed ({}) to generate {} key-pair: {}",
-                     keyPath, alg, e.getClass().getSimpleName(), alg, e.getMessage());
-            if (log.isDebugEnabled()) {
-                log.debug("resolveKeyPair(" + keyPath + ")[" + alg + "] key-pair generation failure details", e);
-            }
-
-            return null;
-        }
-
-        if (keyPath != null) {
-            try {
-                writeKeyPair(kp, keyPath);
-            } catch (Throwable e) {
-                log.warn("resolveKeyPair({})[{}] Failed ({}) to write {} key: {}",
-                         alg, keyPath, e.getClass().getSimpleName(), alg, e.getMessage());
-                if (log.isDebugEnabled()) {
-                    log.debug("resolveKeyPair(" + keyPath + ")[" + alg + "] write failure details", e);
-                }
-            }
-        }
-
-        return kp;
-    }
-
-    protected KeyPair loadFromFile(String alg, Path keyPath) throws IOException, GeneralSecurityException {
-        LinkOption[] options = IoUtils.getLinkOptions(true);
-        if ((!Files.exists(keyPath, options)) || (!Files.isRegularFile(keyPath, options))) {
-            return null;
-        }
-
-        KeyPair kp = readKeyPair(keyPath, IoUtils.EMPTY_OPEN_OPTIONS);
-        if (kp == null) {
-            return null;
-        }
-
-        PublicKey key = kp.getPublic();
-        String keyAlgorithm = key.getAlgorithm();
-        if (BuiltinIdentities.Constants.ECDSA.equalsIgnoreCase(keyAlgorithm)) {
-            keyAlgorithm = KeyUtils.EC_ALGORITHM;
-        } else if (BuiltinIdentities.Constants.ED25519.equalsIgnoreCase(keyAlgorithm)) {
-            keyAlgorithm = SecurityUtils.EDDSA;
-        }
-
-        if (Objects.equals(alg, keyAlgorithm)) {
-            if (log.isDebugEnabled()) {
-                log.debug("resolveKeyPair({}) loaded key={}-{}",
-                          keyPath, KeyUtils.getKeyType(key), KeyUtils.getFingerPrint(key));
-            }
-            return kp;
-        }
-
-        // Not same algorithm - start again
-        if (log.isDebugEnabled()) {
-            log.debug("resolveKeyPair({}) mismatched loaded key algorithm: expected={}, loaded={}",
-                      keyPath, alg, keyAlgorithm);
-        }
-        Files.deleteIfExists(keyPath);
-        return null;
-    }
-
-    protected KeyPair readKeyPair(Path keyPath, OpenOption... options) throws IOException, GeneralSecurityException {
-        try (InputStream inputStream = Files.newInputStream(keyPath, options)) {
-            return doReadKeyPair(keyPath.toString(), inputStream);
-        }
-    }
-
-    protected KeyPair doReadKeyPair(String resourceKey, InputStream inputStream) throws IOException, GeneralSecurityException {
-        return SecurityUtils.loadKeyPairIdentity(resourceKey, inputStream, null);
-    }
-
-    protected void writeKeyPair(KeyPair kp, Path keyPath, OpenOption... options) throws IOException, GeneralSecurityException {
-        if ((!Files.exists(keyPath)) || isOverwriteAllowed()) {
-            try (OutputStream os = Files.newOutputStream(keyPath, options)) {
-                doWriteKeyPair(keyPath.toString(), kp, os);
-            } catch (Throwable e) {
-                log.warn("writeKeyPair({}) failed ({}) to write key {}: {}",
-                         keyPath, e.getClass().getSimpleName(), e.getMessage());
-                if (log.isDebugEnabled()) {
-                    log.debug("writeKeyPair(" + keyPath + ") write failure details", e);
-                }
-            }
-        } else {
-            log.error("Overwriting key ({}) is disabled: using throwaway {}: {}",
-                      keyPath, KeyUtils.getKeyType(kp), KeyUtils.getFingerPrint((kp == null) ? null : kp.getPublic()));
-        }
-    }
-
-    protected abstract void doWriteKeyPair(String resourceKey, KeyPair kp, OutputStream outputStream) throws IOException, GeneralSecurityException;
-
-    protected KeyPair generateKeyPair(String algorithm) throws GeneralSecurityException {
-        KeyPairGenerator generator = SecurityUtils.getKeyPairGenerator(algorithm);
-        if (keySpec != null) {
-            generator.initialize(keySpec);
-            log.info("generateKeyPair(" + algorithm + ") generating host key - spec=" + keySpec.getClass().getSimpleName());
-        } else if (keySize != 0) {
-            generator.initialize(keySize);
-            log.info("generateKeyPair(" + algorithm + ") generating host key - size=" + keySize);
-        } else if (KeyUtils.EC_ALGORITHM.equals(algorithm)) {
-            // If left to our own devices choose the biggest key size possible
-            int numCurves = ECCurves.SORTED_KEY_SIZE.size();
-            ECCurves curve = ECCurves.SORTED_KEY_SIZE.get(numCurves - 1);
-            generator.initialize(curve.getParameters());
-        }
-
-        return generator.generateKeyPair();
-    }
-}

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-core/src/main/java/org/apache/sshd/server/keyprovider/SimpleGeneratorHostKeyProvider.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/keyprovider/SimpleGeneratorHostKeyProvider.java b/sshd-core/src/main/java/org/apache/sshd/server/keyprovider/SimpleGeneratorHostKeyProvider.java
deleted file mode 100644
index 3bccde8..0000000
--- a/sshd-core/src/main/java/org/apache/sshd/server/keyprovider/SimpleGeneratorHostKeyProvider.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.sshd.server.keyprovider;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.io.OutputStream;
-import java.nio.file.Path;
-import java.security.GeneralSecurityException;
-import java.security.KeyPair;
-import java.security.spec.InvalidKeySpecException;
-
-/**
- * TODO Add javadoc
- *
- * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
- */
-public class SimpleGeneratorHostKeyProvider extends AbstractGeneratorHostKeyProvider {
-    public SimpleGeneratorHostKeyProvider() {
-        super();
-    }
-
-    public SimpleGeneratorHostKeyProvider(File file) {
-        this((file == null) ? null : file.toPath());
-    }
-
-    public SimpleGeneratorHostKeyProvider(Path path) {
-        setPath(path);
-    }
-
-    @Override
-    protected KeyPair doReadKeyPair(String resourceKey, InputStream inputStream) throws IOException, GeneralSecurityException {
-        try (ObjectInputStream r = new ObjectInputStream(inputStream)) {
-            try {
-                return (KeyPair) r.readObject();
-            } catch (ClassNotFoundException e) {
-                throw new InvalidKeySpecException("Missing classes: " + e.getMessage(), e);
-            }
-        }
-    }
-
-    @Override
-    protected void doWriteKeyPair(String resourceKey, KeyPair kp, OutputStream outputStream) throws IOException, GeneralSecurityException {
-        try (ObjectOutputStream w = new ObjectOutputStream(outputStream)) {
-            w.writeObject(kp);
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-core/src/test/java/org/apache/sshd/KeepAliveTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/KeepAliveTest.java b/sshd-core/src/test/java/org/apache/sshd/KeepAliveTest.java
index 774620b..906df28 100644
--- a/sshd-core/src/test/java/org/apache/sshd/KeepAliveTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/KeepAliveTest.java
@@ -35,9 +35,9 @@ import org.apache.sshd.common.channel.Channel;
 import org.apache.sshd.server.SshServer;
 import org.apache.sshd.server.command.Command;
 import org.apache.sshd.util.test.BaseTestSupport;
+import org.apache.sshd.util.test.CoreTestSupportUtils;
 import org.apache.sshd.util.test.EchoShell;
 import org.apache.sshd.util.test.EchoShellFactory;
-import org.apache.sshd.util.test.Utils;
 import org.junit.After;
 import org.junit.AfterClass;
 import org.junit.Before;
@@ -65,12 +65,12 @@ public class KeepAliveTest extends BaseTestSupport {
 
     @BeforeClass
     public static void setupClientAndServer() throws Exception {
-        sshd = Utils.setupTestServer(KeepAliveTest.class);
+        sshd = CoreTestSupportUtils.setupTestServer(KeepAliveTest.class);
         sshd.setShellFactory(new TestEchoShellFactory());
         sshd.start();
         port = sshd.getPort();
 
-        client = Utils.setupTestClient(KeepAliveTest.class);
+        client = CoreTestSupportUtils.setupTestClient(KeepAliveTest.class);
         client.start();
     }
 

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-core/src/test/java/org/apache/sshd/agent/AgentTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/agent/AgentTest.java b/sshd-core/src/test/java/org/apache/sshd/agent/AgentTest.java
index 7deebfc..dffb00b 100644
--- a/sshd-core/src/test/java/org/apache/sshd/agent/AgentTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/agent/AgentTest.java
@@ -43,9 +43,9 @@ import org.apache.sshd.server.SshServer;
 import org.apache.sshd.server.command.Command;
 import org.apache.sshd.server.forward.AcceptAllForwardingFilter;
 import org.apache.sshd.util.test.BaseTestSupport;
+import org.apache.sshd.util.test.CommonTestSupportUtils;
 import org.apache.sshd.util.test.EchoShell;
 import org.apache.sshd.util.test.EchoShellFactory;
-import org.apache.sshd.util.test.Utils;
 import org.junit.Assume;
 import org.junit.BeforeClass;
 import org.junit.FixMethodOrder;
@@ -109,7 +109,7 @@ public class AgentTest extends BaseTestSupport {
         ProxyAgentFactory agentFactory = new ProxyAgentFactory();
         LocalAgentFactory localAgentFactory = new LocalAgentFactory();
         String username = getCurrentTestName();
-        KeyPair pair = Utils.createTestKeyPairProvider("dsaprivkey.pem").loadKey(KeyPairProvider.SSH_DSS);
+        KeyPair pair = CommonTestSupportUtils.createTestKeyPairProvider("dsaprivkey.pem").loadKey(KeyPairProvider.SSH_DSS);
         localAgentFactory.getAgent().addIdentity(pair, username);
 
         try (SshServer sshd1 = setupTestServer()) {

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-core/src/test/java/org/apache/sshd/client/ClientSessionListenerTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/client/ClientSessionListenerTest.java b/sshd-core/src/test/java/org/apache/sshd/client/ClientSessionListenerTest.java
index 9989dd1..e5e928a 100644
--- a/sshd-core/src/test/java/org/apache/sshd/client/ClientSessionListenerTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/client/ClientSessionListenerTest.java
@@ -40,7 +40,7 @@ import org.apache.sshd.common.session.SessionListener;
 import org.apache.sshd.common.util.GenericUtils;
 import org.apache.sshd.server.SshServer;
 import org.apache.sshd.util.test.BaseTestSupport;
-import org.apache.sshd.util.test.Utils;
+import org.apache.sshd.util.test.CoreTestSupportUtils;
 import org.junit.AfterClass;
 import org.junit.BeforeClass;
 import org.junit.FixMethodOrder;
@@ -62,11 +62,11 @@ public class ClientSessionListenerTest extends BaseTestSupport {
 
     @BeforeClass
     public static void setupClientAndServer() throws Exception {
-        sshd = Utils.setupTestServer(ClientSessionListenerTest.class);
+        sshd = CoreTestSupportUtils.setupTestServer(ClientSessionListenerTest.class);
         sshd.start();
         port = sshd.getPort();
 
-        client = Utils.setupTestClient(ClientSessionListenerTest.class);
+        client = CoreTestSupportUtils.setupTestClient(ClientSessionListenerTest.class);
         client.start();
     }
 

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-core/src/test/java/org/apache/sshd/client/auth/PasswordIdentityProviderTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/client/auth/PasswordIdentityProviderTest.java b/sshd-core/src/test/java/org/apache/sshd/client/auth/PasswordIdentityProviderTest.java
deleted file mode 100644
index 4eaeed6..0000000
--- a/sshd-core/src/test/java/org/apache/sshd/client/auth/PasswordIdentityProviderTest.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.sshd.client.auth;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Date;
-import java.util.LinkedList;
-import java.util.List;
-
-import org.apache.sshd.client.auth.password.PasswordIdentityProvider;
-import org.apache.sshd.util.test.BaseTestSupport;
-import org.apache.sshd.util.test.NoIoTestCase;
-import org.junit.FixMethodOrder;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.junit.runners.MethodSorters;
-
-/**
- * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
- */
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-@Category({ NoIoTestCase.class })
-public class PasswordIdentityProviderTest extends BaseTestSupport {
-    public PasswordIdentityProviderTest() {
-        super();
-    }
-
-    @Test
-    public void testMultiProvider() {
-        String[][] values = {
-            {getClass().getSimpleName(), getCurrentTestName()},
-            {new Date(System.currentTimeMillis()).toString()},
-            {getClass().getPackage().getName()}
-        };
-        List<String> expected = new ArrayList<>();
-        Collection<PasswordIdentityProvider> providers = new LinkedList<>();
-        for (String[] va : values) {
-            Collection<String> passwords = Arrays.asList(va);
-            expected.addAll(passwords);
-
-            PasswordIdentityProvider p = PasswordIdentityProvider.wrapPasswords(passwords);
-            assertProviderContents("Wrapped", p, passwords);
-            providers.add(p);
-        }
-
-        PasswordIdentityProvider p = PasswordIdentityProvider.multiProvider(providers);
-        assertProviderContents("Multi", p, expected);
-    }
-
-    private static void assertProviderContents(String message, PasswordIdentityProvider p, Iterable<String> expected) {
-        assertNotNull(message + ": no provider", p);
-        assertEquals(message, expected, p.loadPasswords());
-    }
-}

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-core/src/test/java/org/apache/sshd/client/channel/ChannelExecTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/client/channel/ChannelExecTest.java b/sshd-core/src/test/java/org/apache/sshd/client/channel/ChannelExecTest.java
index 038ce55..6bc5213 100644
--- a/sshd-core/src/test/java/org/apache/sshd/client/channel/ChannelExecTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/client/channel/ChannelExecTest.java
@@ -28,7 +28,7 @@ import org.apache.sshd.client.session.ClientSession;
 import org.apache.sshd.server.SshServer;
 import org.apache.sshd.util.test.BaseTestSupport;
 import org.apache.sshd.util.test.CommandExecutionHelper;
-import org.apache.sshd.util.test.Utils;
+import org.apache.sshd.util.test.CoreTestSupportUtils;
 import org.junit.AfterClass;
 import org.junit.BeforeClass;
 import org.junit.FixMethodOrder;
@@ -50,7 +50,7 @@ public class ChannelExecTest extends BaseTestSupport {
 
     @BeforeClass
     public static void setupClientAndServer() throws Exception {
-        sshd = Utils.setupTestServer(ChannelExecTest.class);
+        sshd = CoreTestSupportUtils.setupTestServer(ChannelExecTest.class);
         sshd.setCommandFactory(command -> new CommandExecutionHelper(command) {
             @Override
             protected boolean handleCommandLine(String command) throws Exception {
@@ -63,7 +63,7 @@ public class ChannelExecTest extends BaseTestSupport {
         sshd.start();
         port = sshd.getPort();
 
-        client = Utils.setupTestClient(ChannelExecTest.class);
+        client = CoreTestSupportUtils.setupTestClient(ChannelExecTest.class);
         client.start();
     }