http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-common/src/main/java/org/apache/sshd/common/mac/BaseMac.java
----------------------------------------------------------------------
diff --git a/sshd-common/src/main/java/org/apache/sshd/common/mac/BaseMac.java 
b/sshd-common/src/main/java/org/apache/sshd/common/mac/BaseMac.java
new file mode 100644
index 0000000..e1681d4
--- /dev/null
+++ b/sshd-common/src/main/java/org/apache/sshd/common/mac/BaseMac.java
@@ -0,0 +1,111 @@
+/*
+ * 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.mac;
+
+import javax.crypto.spec.SecretKeySpec;
+
+import org.apache.sshd.common.util.security.SecurityUtils;
+
+/**
+ * Base class for <code>Mac</code> implementations based on the JCE provider.
+ *
+ * @author <a href="mailto:[email protected]";>Apache MINA SSHD Project</a>
+ */
+public class BaseMac implements Mac {
+
+    private final String algorithm;
+    private final int defbsize;
+    private final int bsize;
+    private final byte[] tmp;
+    private javax.crypto.Mac mac;
+    private String s;
+
+    public BaseMac(String algorithm, int bsize, int defbsize) {
+        this.algorithm = algorithm;
+        this.bsize = bsize;
+        this.defbsize = defbsize;
+        this.tmp = new byte[defbsize];
+    }
+
+    @Override
+    public final String getAlgorithm() {
+        return algorithm;
+    }
+
+    @Override
+    public final int getBlockSize() {
+        return bsize;
+    }
+
+    @Override
+    public final int getDefaultBlockSize() {
+        return defbsize;
+    }
+
+    @Override
+    public void init(byte[] key) throws Exception {
+        if (key.length > defbsize) {
+            byte[] tmp = new byte[defbsize];
+            System.arraycopy(key, 0, tmp, 0, defbsize);
+            key = tmp;
+        }
+
+        SecretKeySpec skey = new SecretKeySpec(key, algorithm);
+        mac = SecurityUtils.getMac(algorithm);
+        mac.init(skey);
+    }
+
+    @Override
+    public void updateUInt(long i) {
+        tmp[0] = (byte) (i >>> 24);
+        tmp[1] = (byte) (i >>> 16);
+        tmp[2] = (byte) (i >>> 8);
+        tmp[3] = (byte) i;
+        update(tmp, 0, 4);
+    }
+
+    @Override
+    public void update(byte buf[], int offset, int len) {
+        mac.update(buf, offset, len);
+    }
+
+    @Override
+    public void doFinal(byte[] buf, int offset) throws Exception {
+        int blockSize = getBlockSize();
+        int defaultSize = getDefaultBlockSize();
+        if (blockSize != defaultSize) {
+            mac.doFinal(tmp, 0);
+            System.arraycopy(tmp, 0, buf, offset, blockSize);
+        } else {
+            mac.doFinal(buf, offset);
+        }
+    }
+
+    @Override
+    public String toString() {
+        synchronized (this) {
+            if (s == null) {
+                s = getClass().getSimpleName() + "[" + getAlgorithm() + "] - "
+                    + " block=" + getBlockSize() + "/" + getDefaultBlockSize() 
+ " bytes";
+            }
+        }
+
+        return s;
+    }
+}

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-common/src/main/java/org/apache/sshd/common/mac/BuiltinMacs.java
----------------------------------------------------------------------
diff --git 
a/sshd-common/src/main/java/org/apache/sshd/common/mac/BuiltinMacs.java 
b/sshd-common/src/main/java/org/apache/sshd/common/mac/BuiltinMacs.java
new file mode 100644
index 0000000..5a4528d
--- /dev/null
+++ b/sshd-common/src/main/java/org/apache/sshd/common/mac/BuiltinMacs.java
@@ -0,0 +1,273 @@
+/*
+ * 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.mac;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.List;
+import java.util.Map;
+import java.util.NavigableSet;
+import java.util.Objects;
+import java.util.Set;
+import java.util.TreeMap;
+
+import org.apache.sshd.common.NamedFactory;
+import org.apache.sshd.common.NamedResource;
+import org.apache.sshd.common.config.NamedFactoriesListParseResult;
+import org.apache.sshd.common.util.GenericUtils;
+import org.apache.sshd.common.util.ValidateUtils;
+
+/**
+ * Provides easy access to the currently implemented macs
+ *
+ * @author <a href="mailto:[email protected]";>Apache MINA SSHD Project</a>
+ */
+public enum BuiltinMacs implements MacFactory {
+    hmacmd5(Constants.HMAC_MD5, "HmacMD5", 16, 16),
+    hmacmd596(Constants.HMAC_MD5_96, "HmacMD5", 12, 16),
+    hmacsha1(Constants.HMAC_SHA1, "HmacSHA1", 20, 20),
+    hmacsha196(Constants.HMAC_SHA1_96, "HmacSHA1", 12, 20),
+    /** See <A HREF="https://tools.ietf.org/html/rfc6668";>RFC 6668</A> */
+    hmacsha256(Constants.HMAC_SHA2_256, "HmacSHA256", 32, 32),
+    /** See <A HREF="https://tools.ietf.org/html/rfc6668";>RFC 6668</A> */
+    hmacsha512(Constants.HMAC_SHA2_512, "HmacSHA512", 64, 64);
+
+    public static final Set<BuiltinMacs> VALUES =
+            Collections.unmodifiableSet(EnumSet.allOf(BuiltinMacs.class));
+
+    private static final Map<String, MacFactory> EXTENSIONS =
+            new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
+
+    private final String factoryName;
+    private final String algorithm;
+    private final int defbsize;
+    private final int bsize;
+
+    BuiltinMacs(String factoryName, String algorithm, int bsize, int defbsize) 
{
+        this.factoryName = factoryName;
+        this.algorithm = algorithm;
+        this.bsize = bsize;
+        this.defbsize = defbsize;
+    }
+
+    @Override
+    public Mac create() {
+        return new BaseMac(getAlgorithm(), getBlockSize(), 
getDefaultBlockSize());
+    }
+
+    @Override
+    public final String getName() {
+        return factoryName;
+    }
+
+    @Override
+    public final String getAlgorithm() {
+        return algorithm;
+    }
+
+    @Override
+    public final int getBlockSize() {
+        return bsize;
+    }
+
+    @Override
+    public final int getDefaultBlockSize() {
+        return defbsize;
+    }
+
+    @Override
+    public final boolean isSupported() {
+        return true;
+    }
+
+    @Override
+    public final String toString() {
+        return getName();
+    }
+
+    /**
+     * Registered a {@link NamedFactory} to be available besides the built-in
+     * ones when parsing configuration
+     *
+     * @param extension The factory to register
+     * @throws IllegalArgumentException if factory instance is {@code null},
+     * or overrides a built-in one or overrides another registered factory
+     * with the same name (case <U>insensitive</U>).
+     */
+    public static void registerExtension(MacFactory extension) {
+        String name = Objects.requireNonNull(extension, "No extension 
provided").getName();
+        ValidateUtils.checkTrue(fromFactoryName(name) == null, "Extension 
overrides built-in: %s", name);
+
+        synchronized (EXTENSIONS) {
+            ValidateUtils.checkTrue(!EXTENSIONS.containsKey(name), "Extension 
overrides existing: %s", name);
+            EXTENSIONS.put(name, extension);
+        }
+    }
+
+    /**
+     * @return A {@link NavigableSet} of the currently registered extensions, 
sorted
+     * according to the factory name (case <U>insensitive</U>)
+     */
+    public static NavigableSet<MacFactory> getRegisteredExtensions() {
+        synchronized (EXTENSIONS) {
+            return GenericUtils.asSortedSet(NamedResource.BY_NAME_COMPARATOR, 
EXTENSIONS.values());
+        }
+    }
+
+    /**
+     * Unregisters specified extension
+     *
+     * @param name The factory name - ignored if {@code null}/empty
+     * @return The registered extension - {@code null} if not found
+     */
+    public static MacFactory unregisterExtension(String name) {
+        if (GenericUtils.isEmpty(name)) {
+            return null;
+        }
+
+        synchronized (EXTENSIONS) {
+            return EXTENSIONS.remove(name);
+        }
+    }
+
+    /**
+     * @param s The {@link Enum}'s name - ignored if {@code null}/empty
+     * @return The matching {@link org.apache.sshd.common.mac.BuiltinMacs} 
whose {@link Enum#name()} matches
+     * (case <U>insensitive</U>) the provided argument - {@code null} if no 
match
+     */
+    public static BuiltinMacs fromString(String s) {
+        if (GenericUtils.isEmpty(s)) {
+            return null;
+        }
+
+        for (BuiltinMacs c : VALUES) {
+            if (s.equalsIgnoreCase(c.name())) {
+                return c;
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * @param factory The {@link org.apache.sshd.common.NamedFactory} for the 
MAC - ignored if {@code null}
+     * @return The matching {@link org.apache.sshd.common.mac.BuiltinMacs} 
whose factory name matches
+     * (case <U>insensitive</U>) the digest factory name
+     * @see #fromFactoryName(String)
+     */
+    public static BuiltinMacs fromFactory(NamedFactory<Mac> factory) {
+        if (factory == null) {
+            return null;
+        } else {
+            return fromFactoryName(factory.getName());
+        }
+    }
+
+    /**
+     * @param name The factory name - ignored if {@code null}/empty
+     * @return The matching {@link BuiltinMacs} whose factory name matches
+     * (case <U>insensitive</U>) the provided name - {@code null} if no match
+     */
+    public static BuiltinMacs fromFactoryName(String name) {
+        return NamedResource.findByName(name, String.CASE_INSENSITIVE_ORDER, 
VALUES);
+    }
+
+    /**
+     * @param macs A comma-separated list of MACs' names - ignored
+     *             if {@code null}/empty
+     * @return A {@link ParseResult} containing the successfully parsed
+     * factories and the unknown ones. <B>Note:</B> it is up to caller to
+     * ensure that the lists do not contain duplicates
+     */
+    public static ParseResult parseMacsList(String macs) {
+        return parseMacsList(GenericUtils.split(macs, ','));
+    }
+
+    public static ParseResult parseMacsList(String... macs) {
+        return parseMacsList(GenericUtils.isEmpty((Object[]) macs) ? 
Collections.emptyList() : Arrays.asList(macs));
+    }
+
+    public static ParseResult parseMacsList(Collection<String> macs) {
+        if (GenericUtils.isEmpty(macs)) {
+            return ParseResult.EMPTY;
+        }
+
+        List<MacFactory> factories = new ArrayList<>(macs.size());
+        List<String> unknown = Collections.emptyList();
+        for (String name : macs) {
+            MacFactory m = resolveFactory(name);
+            if (m != null) {
+                factories.add(m);
+            } else {
+                // replace the (unmodifiable) empty list with a real one
+                if (unknown.isEmpty()) {
+                    unknown = new ArrayList<>();
+                }
+                unknown.add(name);
+            }
+        }
+
+        return new ParseResult(factories, unknown);
+    }
+
+    /**
+     * @param name The factory name
+     * @return The factory or {@code null} if it is neither a built-in one
+     * or a registered extension
+     */
+    public static MacFactory resolveFactory(String name) {
+        if (GenericUtils.isEmpty(name)) {
+            return null;
+        }
+
+        MacFactory m = fromFactoryName(name);
+        if (m != null) {
+            return m;
+        }
+
+        synchronized (EXTENSIONS) {
+            return EXTENSIONS.get(name);
+        }
+    }
+
+    public static final class ParseResult extends 
NamedFactoriesListParseResult<Mac, MacFactory> {
+        public static final ParseResult EMPTY = new 
ParseResult(Collections.emptyList(), Collections.emptyList());
+
+        public ParseResult(List<MacFactory> parsed, List<String> unsupported) {
+            super(parsed, unsupported);
+        }
+    }
+
+    public static final class Constants {
+        public static final String HMAC_MD5 = "hmac-md5";
+        public static final String HMAC_MD5_96 = "hmac-md5-96";
+        public static final String HMAC_SHA1 = "hmac-sha1";
+        public static final String HMAC_SHA1_96 = "hmac-sha1-96";
+        public static final String HMAC_SHA2_256 = "hmac-sha2-256";
+        public static final String HMAC_SHA2_512 = "hmac-sha2-512";
+
+        private Constants() {
+            throw new UnsupportedOperationException("No instance allowed");
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-common/src/main/java/org/apache/sshd/common/mac/Mac.java
----------------------------------------------------------------------
diff --git a/sshd-common/src/main/java/org/apache/sshd/common/mac/Mac.java 
b/sshd-common/src/main/java/org/apache/sshd/common/mac/Mac.java
new file mode 100644
index 0000000..4b80447
--- /dev/null
+++ b/sshd-common/src/main/java/org/apache/sshd/common/mac/Mac.java
@@ -0,0 +1,52 @@
+/*
+ * 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.mac;
+
+import org.apache.sshd.common.util.NumberUtils;
+
+/**
+ * Message Authentication Code for use in SSH.
+ * It usually wraps a javax.crypto.Mac class.
+ *
+ * @author <a href="mailto:[email protected]";>Apache MINA SSHD Project</a>
+ */
+public interface Mac extends MacInformation {
+    void init(byte[] key) throws Exception;
+
+    default void update(byte[] buf) {
+        update(buf, 0, NumberUtils.length(buf));
+    }
+
+    void update(byte[] buf, int start, int len);
+
+    void updateUInt(long foo);
+
+    default byte[] doFinal() throws Exception {
+        int blockSize = getBlockSize();
+        byte[] buf = new byte[blockSize];
+        doFinal(buf);
+        return buf;
+    }
+
+    default void doFinal(byte[] buf) throws Exception {
+        doFinal(buf, 0);
+    }
+
+    void doFinal(byte[] buf, int offset) throws Exception;
+}

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-common/src/main/java/org/apache/sshd/common/mac/MacFactory.java
----------------------------------------------------------------------
diff --git 
a/sshd-common/src/main/java/org/apache/sshd/common/mac/MacFactory.java 
b/sshd-common/src/main/java/org/apache/sshd/common/mac/MacFactory.java
new file mode 100644
index 0000000..4463600
--- /dev/null
+++ b/sshd-common/src/main/java/org/apache/sshd/common/mac/MacFactory.java
@@ -0,0 +1,31 @@
+/*
+ * 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.mac;
+
+import org.apache.sshd.common.BuiltinFactory;
+
+/**
+ * @author <a href="mailto:[email protected]";>Apache MINA SSHD Project</a>
+ */
+// CHECKSTYLE:OFF
+public interface MacFactory extends MacInformation, BuiltinFactory<Mac> {
+    // nothing extra
+}
+//CHECKSTYLE:ON

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-common/src/main/java/org/apache/sshd/common/mac/MacInformation.java
----------------------------------------------------------------------
diff --git 
a/sshd-common/src/main/java/org/apache/sshd/common/mac/MacInformation.java 
b/sshd-common/src/main/java/org/apache/sshd/common/mac/MacInformation.java
new file mode 100644
index 0000000..583165f
--- /dev/null
+++ b/sshd-common/src/main/java/org/apache/sshd/common/mac/MacInformation.java
@@ -0,0 +1,41 @@
+/*
+ * 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.mac;
+
+/**
+ * @author <a href="mailto:[email protected]";>Apache MINA SSHD Project</a>
+ */
+public interface MacInformation {
+    /**
+     * @return MAC algorithm name
+     */
+    String getAlgorithm();
+
+    /**
+     * @return MAC output block size in bytes - may be less than the default
+     * - e.g., MD5-96
+     */
+    int getBlockSize();
+
+    /**
+     * @return The &quot;natural&quot; MAC block size in bytes
+     */
+    int getDefaultBlockSize();
+}

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-common/src/main/java/org/apache/sshd/common/mac/package.html
----------------------------------------------------------------------
diff --git a/sshd-common/src/main/java/org/apache/sshd/common/mac/package.html 
b/sshd-common/src/main/java/org/apache/sshd/common/mac/package.html
new file mode 100644
index 0000000..52a90ca
--- /dev/null
+++ b/sshd-common/src/main/java/org/apache/sshd/common/mac/package.html
@@ -0,0 +1,25 @@
+<!--
+    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.
+-->
+<html>
+<head>
+</head>
+<body>
+
+<a href="{@docRoot}/org/apache/sshd/common/mac/Mac.html"><code>Mac</code></a> 
implementations.
+
+</body>
+</html>

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-common/src/main/java/org/apache/sshd/common/random/AbstractRandom.java
----------------------------------------------------------------------
diff --git 
a/sshd-common/src/main/java/org/apache/sshd/common/random/AbstractRandom.java 
b/sshd-common/src/main/java/org/apache/sshd/common/random/AbstractRandom.java
new file mode 100644
index 0000000..2a1f825
--- /dev/null
+++ 
b/sshd-common/src/main/java/org/apache/sshd/common/random/AbstractRandom.java
@@ -0,0 +1,34 @@
+/*
+ * 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.random;
+
+/**
+ * @author <a href="mailto:[email protected]";>Apache MINA SSHD Project</a>
+ */
+public abstract class AbstractRandom implements Random {
+    protected AbstractRandom() {
+        super();
+    }
+
+    @Override
+    public String toString() {
+        return getName();
+    }
+}

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-common/src/main/java/org/apache/sshd/common/random/AbstractRandomFactory.java
----------------------------------------------------------------------
diff --git 
a/sshd-common/src/main/java/org/apache/sshd/common/random/AbstractRandomFactory.java
 
b/sshd-common/src/main/java/org/apache/sshd/common/random/AbstractRandomFactory.java
new file mode 100644
index 0000000..c1d7893
--- /dev/null
+++ 
b/sshd-common/src/main/java/org/apache/sshd/common/random/AbstractRandomFactory.java
@@ -0,0 +1,43 @@
+/*
+ * 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.random;
+
+import org.apache.sshd.common.util.ValidateUtils;
+
+/**
+ * @author <a href="mailto:[email protected]";>Apache MINA SSHD Project</a>
+ */
+public abstract class AbstractRandomFactory implements RandomFactory {
+    private final String name;
+
+    protected AbstractRandomFactory(String name) {
+        this.name = ValidateUtils.checkNotNullAndNotEmpty(name, "No name");
+    }
+
+    @Override
+    public final String getName() {
+        return name;
+    }
+
+    @Override
+    public String toString() {
+        return getName();
+    }
+}

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-common/src/main/java/org/apache/sshd/common/random/JceRandom.java
----------------------------------------------------------------------
diff --git 
a/sshd-common/src/main/java/org/apache/sshd/common/random/JceRandom.java 
b/sshd-common/src/main/java/org/apache/sshd/common/random/JceRandom.java
new file mode 100644
index 0000000..ba050e6
--- /dev/null
+++ b/sshd-common/src/main/java/org/apache/sshd/common/random/JceRandom.java
@@ -0,0 +1,60 @@
+/*
+ * 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.random;
+
+import java.security.SecureRandom;
+
+/**
+ * A <code>Random</code> implementation using the built-in {@link 
SecureRandom} PRNG.
+ *
+ * @author <a href="mailto:[email protected]";>Apache MINA SSHD Project</a>
+ */
+public class JceRandom extends AbstractRandom {
+    public static final String NAME = "JCE";
+
+    private byte[] tmp = new byte[16];
+    private final SecureRandom random = new SecureRandom();
+
+    public JceRandom() {
+        super();
+    }
+
+    @Override
+    public String getName() {
+        return NAME;
+    }
+
+    @Override
+    public synchronized void fill(byte[] foo, int start, int len) {
+        if ((start == 0) && (len == foo.length)) {
+            random.nextBytes(foo);
+        } else {
+            if (len > tmp.length) {
+                tmp = new byte[len];
+            }
+            random.nextBytes(tmp);
+            System.arraycopy(tmp, 0, foo, start, len);
+        }
+    }
+
+    @Override
+    public synchronized int random(int n) {
+        return random.nextInt(n);
+    }
+}

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-common/src/main/java/org/apache/sshd/common/random/JceRandomFactory.java
----------------------------------------------------------------------
diff --git 
a/sshd-common/src/main/java/org/apache/sshd/common/random/JceRandomFactory.java 
b/sshd-common/src/main/java/org/apache/sshd/common/random/JceRandomFactory.java
new file mode 100644
index 0000000..450a85e
--- /dev/null
+++ 
b/sshd-common/src/main/java/org/apache/sshd/common/random/JceRandomFactory.java
@@ -0,0 +1,42 @@
+/*
+ * 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.random;
+
+/**
+ * Named factory for the JCE <code>Random</code>
+ */
+public class JceRandomFactory extends AbstractRandomFactory {
+    public static final String NAME = "default";
+    public static final JceRandomFactory INSTANCE = new JceRandomFactory();
+
+    public JceRandomFactory() {
+        super(NAME);
+    }
+
+    @Override
+    public boolean isSupported() {
+        return true;
+    }
+
+    @Override
+    public Random create() {
+        return new JceRandom();
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-common/src/main/java/org/apache/sshd/common/random/Random.java
----------------------------------------------------------------------
diff --git 
a/sshd-common/src/main/java/org/apache/sshd/common/random/Random.java 
b/sshd-common/src/main/java/org/apache/sshd/common/random/Random.java
new file mode 100644
index 0000000..6e597ef
--- /dev/null
+++ b/sshd-common/src/main/java/org/apache/sshd/common/random/Random.java
@@ -0,0 +1,56 @@
+/*
+ * 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.random;
+
+import org.apache.sshd.common.NamedResource;
+
+/**
+ * A pseudo random number generator.
+ *
+ * @author <a href="mailto:[email protected]";>Apache MINA SSHD Project</a>
+ */
+public interface Random extends NamedResource {
+    /**
+     * Fill the buffer with random values
+     *
+     * @param bytes The bytes to fill
+     * @see #fill(byte[], int, int)
+     */
+    default void fill(byte[] bytes) {
+        fill(bytes, 0, bytes.length);
+    }
+
+    /**
+     * Fill part of bytes with random values.
+     *
+     * @param bytes byte array to be filled.
+     * @param start index to start filling at.
+     * @param len   length of segment to fill.
+     */
+    void fill(byte[] bytes, int start, int len);
+
+    /**
+     * Returns a pseudo-random uniformly distributed {@code int}
+     * in the half-open range [0, n).
+     *
+     * @param n The range upper limit
+     * @return The randomly selected value in the range
+     */
+    int random(int n);
+}

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-common/src/main/java/org/apache/sshd/common/random/RandomFactory.java
----------------------------------------------------------------------
diff --git 
a/sshd-common/src/main/java/org/apache/sshd/common/random/RandomFactory.java 
b/sshd-common/src/main/java/org/apache/sshd/common/random/RandomFactory.java
new file mode 100644
index 0000000..dded06f
--- /dev/null
+++ b/sshd-common/src/main/java/org/apache/sshd/common/random/RandomFactory.java
@@ -0,0 +1,31 @@
+/*
+ * 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.random;
+
+import org.apache.sshd.common.BuiltinFactory;
+
+/**
+ * @author <a href="mailto:[email protected]";>Apache MINA SSHD Project</a>
+ */
+// CHECKSTYLE:OFF
+public interface RandomFactory extends BuiltinFactory<Random> {
+    // nothing extra
+}
+//CHECKSTYLE:ON

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-common/src/main/java/org/apache/sshd/common/random/SingletonRandomFactory.java
----------------------------------------------------------------------
diff --git 
a/sshd-common/src/main/java/org/apache/sshd/common/random/SingletonRandomFactory.java
 
b/sshd-common/src/main/java/org/apache/sshd/common/random/SingletonRandomFactory.java
new file mode 100644
index 0000000..ce24112
--- /dev/null
+++ 
b/sshd-common/src/main/java/org/apache/sshd/common/random/SingletonRandomFactory.java
@@ -0,0 +1,70 @@
+/*
+ * 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.random;
+
+import java.util.Objects;
+
+import org.apache.sshd.common.NamedFactory;
+import org.apache.sshd.common.OptionalFeature;
+
+/**
+ * A random factory wrapper that uses a single random instance.
+ * The underlying random instance has to be thread safe.
+ *
+ * @author <a href="mailto:[email protected]";>Apache MINA SSHD Project</a>
+ */
+public class SingletonRandomFactory extends AbstractRandom implements 
RandomFactory {
+
+    private final NamedFactory<Random> factory;
+    private final Random random;
+
+    public SingletonRandomFactory(NamedFactory<Random> factory) {
+        this.factory = Objects.requireNonNull(factory, "No factory");
+        this.random = Objects.requireNonNull(factory.create(), "No random 
instance created");
+    }
+
+    @Override
+    public boolean isSupported() {
+        if (factory instanceof OptionalFeature) {
+            return ((OptionalFeature) factory).isSupported();
+        } else {
+            return true;
+        }
+    }
+
+    @Override
+    public void fill(byte[] bytes, int start, int len) {
+        random.fill(bytes, start, len);
+    }
+
+    @Override
+    public int random(int max) {
+        return random.random(max);
+    }
+
+    @Override
+    public String getName() {
+        return factory.getName();
+    }
+
+    @Override
+    public Random create() {
+        return this;
+    }
+}

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-common/src/main/java/org/apache/sshd/common/random/package.html
----------------------------------------------------------------------
diff --git 
a/sshd-common/src/main/java/org/apache/sshd/common/random/package.html 
b/sshd-common/src/main/java/org/apache/sshd/common/random/package.html
new file mode 100644
index 0000000..0e94d7f
--- /dev/null
+++ b/sshd-common/src/main/java/org/apache/sshd/common/random/package.html
@@ -0,0 +1,25 @@
+<!--
+    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.
+-->
+<html>
+<head>
+</head>
+<body>
+
+<a 
href="{@docRoot}/org/apache/sshd/common/random/Random.html"><code>Random</code></a>
 implementations.
+
+</body>
+</html>

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-common/src/main/java/org/apache/sshd/common/signature/AbstractSignature.java
----------------------------------------------------------------------
diff --git 
a/sshd-common/src/main/java/org/apache/sshd/common/signature/AbstractSignature.java
 
b/sshd-common/src/main/java/org/apache/sshd/common/signature/AbstractSignature.java
new file mode 100644
index 0000000..ef06d15
--- /dev/null
+++ 
b/sshd-common/src/main/java/org/apache/sshd/common/signature/AbstractSignature.java
@@ -0,0 +1,149 @@
+/*
+ * 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.signature;
+
+import java.nio.charset.StandardCharsets;
+import java.security.GeneralSecurityException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.SignatureException;
+import java.util.AbstractMap.SimpleImmutableEntry;
+import java.util.Objects;
+
+import org.apache.sshd.common.util.NumberUtils;
+import org.apache.sshd.common.util.ValidateUtils;
+import org.apache.sshd.common.util.buffer.BufferUtils;
+import org.apache.sshd.common.util.security.SecurityUtils;
+
+/**
+ * Useful base class for {@link Signature} implementation
+ *
+ * @author <a href="mailto:[email protected]";>Apache MINA SSHD Project</a>
+ */
+public abstract class AbstractSignature implements Signature {
+    private java.security.Signature signatureInstance;
+    private final String algorithm;
+
+    protected AbstractSignature(String algorithm) {
+        this.algorithm = ValidateUtils.checkNotNullAndNotEmpty(algorithm, "No 
signature algorithm specified");
+    }
+
+    @Override
+    public final String getAlgorithm() {
+        return algorithm;
+    }
+
+    /**
+     * Initializes the internal signature instance
+     *
+     * @param algo The signature's algorithm
+     * @param forSigning If {@code true} then it is being initialized for 
signing,
+     * otherwise for verifying a signature
+     * @return The {@link java.security.Signature} instance
+     * @throws GeneralSecurityException if failed to initialize
+     */
+    protected java.security.Signature doInitSignature(String algo, boolean 
forSigning) throws GeneralSecurityException {
+        return SecurityUtils.getSignature(algo);
+    }
+
+    /**
+     * @return The current {@link java.security.Signature} instance
+     * - {@code null} if not initialized
+     * @see #doInitSignature(String, boolean)
+     */
+    protected java.security.Signature getSignature() {
+        return signatureInstance;
+    }
+
+    @Override
+    public byte[] sign() throws Exception {
+        java.security.Signature signature = 
Objects.requireNonNull(getSignature(), "Signature not initialized");
+        return signature.sign();
+    }
+
+    @Override
+    public void initVerifier(PublicKey key) throws Exception {
+        String algo = getAlgorithm();
+        signatureInstance = Objects.requireNonNull(doInitSignature(algo, 
false), "No signature instance create");
+        signatureInstance.initVerify(Objects.requireNonNull(key, "No public 
key provided"));
+    }
+
+    @Override
+    public void initSigner(PrivateKey key) throws Exception {
+        String algo = getAlgorithm();
+        signatureInstance = Objects.requireNonNull(doInitSignature(algo, 
true), "No signature instance create");
+        signatureInstance.initSign(Objects.requireNonNull(key, "No private key 
provided"));
+    }
+
+    @Override
+    public void update(byte[] hash, int off, int len) throws Exception {
+        java.security.Signature signature = 
Objects.requireNonNull(getSignature(), "Signature not initialized");
+        signature.update(hash, off, len);
+    }
+
+    /**
+     * Makes an attempt to detect if the signature is encoded or pure data
+     *
+     * @param sig The original signature
+     * @return A {@link SimpleImmutableEntry} where first value is the key 
type and second
+     * value is the data - {@code null} if not encoded
+     */
+    protected SimpleImmutableEntry<String, byte[]> 
extractEncodedSignature(byte[] sig) {
+        final int dataLen = NumberUtils.length(sig);
+        // if it is encoded then we must have at least 2 UINT32 values
+        if (dataLen < (2 * Integer.BYTES)) {
+            return null;
+        }
+
+        long keyTypeLen = BufferUtils.getUInt(sig, 0, dataLen);
+        // after the key type we MUST have data bytes
+        if (keyTypeLen >= (dataLen - Integer.BYTES)) {
+            return null;
+        }
+
+        int keyTypeStartPos = Integer.BYTES;
+        int keyTypeEndPos = keyTypeStartPos + (int) keyTypeLen;
+        int remainLen = dataLen - keyTypeEndPos;
+        // must have UINT32 with the data bytes length
+        if (remainLen < Integer.BYTES) {
+            return null;
+        }
+
+        long dataBytesLen = BufferUtils.getUInt(sig, keyTypeEndPos, remainLen);
+        // make sure reported number of bytes does not exceed available
+        if (dataBytesLen > (remainLen - Integer.BYTES)) {
+            return null;
+        }
+
+        String keyType = new String(sig, keyTypeStartPos, (int) keyTypeLen, 
StandardCharsets.UTF_8);
+        byte[] data = new byte[(int) dataBytesLen];
+        System.arraycopy(sig, keyTypeEndPos + Integer.BYTES, data, 0, (int) 
dataBytesLen);
+        return new SimpleImmutableEntry<>(keyType, data);
+    }
+
+    protected boolean doVerify(byte[] data) throws SignatureException {
+        java.security.Signature signature = 
Objects.requireNonNull(getSignature(), "Signature not initialized");
+        return signature.verify(data);
+    }
+
+    @Override
+    public String toString() {
+        return getClass().getSimpleName() + "[" + getAlgorithm() + "]";
+    }
+}

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-common/src/main/java/org/apache/sshd/common/signature/BuiltinSignatures.java
----------------------------------------------------------------------
diff --git 
a/sshd-common/src/main/java/org/apache/sshd/common/signature/BuiltinSignatures.java
 
b/sshd-common/src/main/java/org/apache/sshd/common/signature/BuiltinSignatures.java
new file mode 100644
index 0000000..7d4e1e2
--- /dev/null
+++ 
b/sshd-common/src/main/java/org/apache/sshd/common/signature/BuiltinSignatures.java
@@ -0,0 +1,305 @@
+/*
+ * 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.signature;
+
+import java.security.spec.ECParameterSpec;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.List;
+import java.util.Map;
+import java.util.NavigableSet;
+import java.util.Objects;
+import java.util.Set;
+import java.util.TreeMap;
+
+import org.apache.sshd.common.NamedFactory;
+import org.apache.sshd.common.NamedResource;
+import org.apache.sshd.common.cipher.ECCurves;
+import org.apache.sshd.common.config.NamedFactoriesListParseResult;
+import org.apache.sshd.common.keyprovider.KeyPairProvider;
+import org.apache.sshd.common.util.GenericUtils;
+import org.apache.sshd.common.util.ValidateUtils;
+import org.apache.sshd.common.util.security.SecurityUtils;
+
+/**
+ * Provides easy access to the currently implemented signatures
+ *
+ * @author <a href="mailto:[email protected]";>Apache MINA SSHD Project</a>
+ */
+public enum BuiltinSignatures implements SignatureFactory {
+    dsa(KeyPairProvider.SSH_DSS) {
+        @Override
+        public Signature create() {
+            return new SignatureDSA();
+        }
+    },
+    rsa(KeyPairProvider.SSH_RSA) {
+        @Override
+        public Signature create() {
+            return new SignatureRSA();
+        }
+    },
+    nistp256(KeyPairProvider.ECDSA_SHA2_NISTP256) {
+        @Override
+        public Signature create() {
+            return new SignatureECDSA.SignatureECDSA256();
+        }
+
+        @Override
+        public boolean isSupported() {
+            return SecurityUtils.isECCSupported();
+        }
+    },
+    nistp384(KeyPairProvider.ECDSA_SHA2_NISTP384) {
+        @Override
+        public Signature create() {
+            return new SignatureECDSA.SignatureECDSA384();
+        }
+
+        @Override
+        public boolean isSupported() {
+            return SecurityUtils.isECCSupported();
+        }
+    },
+    nistp521(KeyPairProvider.ECDSA_SHA2_NISTP521) {
+        @Override
+        public Signature create() {
+            return new SignatureECDSA.SignatureECDSA521();
+        }
+
+        @Override
+        public boolean isSupported() {
+            return SecurityUtils.isECCSupported();
+        }
+    },
+    ed25519(KeyPairProvider.SSH_ED25519) {
+        @Override
+        public Signature create() {
+            return SecurityUtils.getEDDSASigner();
+        }
+
+        @Override
+        public boolean isSupported() {
+            return SecurityUtils.isEDDSACurveSupported();
+        }
+    };
+
+    public static final Set<BuiltinSignatures> VALUES =
+            
Collections.unmodifiableSet(EnumSet.allOf(BuiltinSignatures.class));
+
+    private static final Map<String, SignatureFactory> EXTENSIONS =
+            new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
+
+    private final String factoryName;
+
+    BuiltinSignatures(String facName) {
+        factoryName = facName;
+    }
+
+    public static Signature getByCurveSize(ECParameterSpec params) {
+        int curveSize = ECCurves.getCurveSize(params);
+        if (curveSize <= 256) {
+            return nistp256.create();
+        } else if (curveSize <= 384) {
+            return nistp384.create();
+        } else {
+            return nistp521.create();
+        }
+    }
+
+    @Override
+    public final String getName() {
+        return factoryName;
+    }
+
+    @Override
+    public final String toString() {
+        return getName();
+    }
+
+    @Override
+    public boolean isSupported() {
+        return true;
+    }
+
+    /**
+     * Registered a {@link NamedFactory} to be available besides the built-in
+     * ones when parsing configuration
+     *
+     * @param extension The factory to register
+     * @throws IllegalArgumentException if factory instance is {@code null},
+     * or overrides a built-in one or overrides another registered factory
+     * with the same name (case <U>insensitive</U>).
+     */
+    public static void registerExtension(SignatureFactory extension) {
+        String name = Objects.requireNonNull(extension, "No extension 
provided").getName();
+        ValidateUtils.checkTrue(fromFactoryName(name) == null, "Extension 
overrides built-in: %s", name);
+
+        synchronized (EXTENSIONS) {
+            ValidateUtils.checkTrue(!EXTENSIONS.containsKey(name), "Extension 
overrides existing: %s", name);
+            EXTENSIONS.put(name, extension);
+        }
+    }
+
+    /**
+     * @return A {@link NavigableSet} of the currently registered extensions, 
sorted
+     * according to the factory name (case <U>insensitive</U>)
+     */
+    public static NavigableSet<SignatureFactory> getRegisteredExtensions() {
+        synchronized (EXTENSIONS) {
+            return GenericUtils.asSortedSet(NamedResource.BY_NAME_COMPARATOR, 
EXTENSIONS.values());
+        }
+    }
+
+    /**
+     * Unregisters specified extension
+     *
+     * @param name The factory name - ignored if {@code null}/empty
+     * @return The registered extension - {@code null} if not found
+     */
+    public static SignatureFactory unregisterExtension(String name) {
+        if (GenericUtils.isEmpty(name)) {
+            return null;
+        }
+
+        synchronized (EXTENSIONS) {
+            return EXTENSIONS.remove(name);
+        }
+    }
+
+    /**
+     * @param s The {@link Enum}'s name - ignored if {@code null}/empty
+     * @return The matching {@link 
org.apache.sshd.common.signature.BuiltinSignatures} whose {@link Enum#name()} 
matches
+     * (case <U>insensitive</U>) the provided argument - {@code null} if no 
match
+     */
+    public static BuiltinSignatures fromString(String s) {
+        if (GenericUtils.isEmpty(s)) {
+            return null;
+        }
+
+        for (BuiltinSignatures c : VALUES) {
+            if (s.equalsIgnoreCase(c.name())) {
+                return c;
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * @param factory The {@link org.apache.sshd.common.NamedFactory} for the 
signature - ignored if {@code null}
+     * @return The matching {@link 
org.apache.sshd.common.signature.BuiltinSignatures} whose factory name matches
+     * (case <U>insensitive</U>) the digest factory name
+     * @see #fromFactoryName(String)
+     */
+    public static BuiltinSignatures fromFactory(NamedFactory<Signature> 
factory) {
+        if (factory == null) {
+            return null;
+        } else {
+            return fromFactoryName(factory.getName());
+        }
+    }
+
+    /**
+     * @param name The factory name - ignored if {@code null}/empty
+     * @return The matching {@link BuiltinSignatures} whose factory name 
matches
+     * (case <U>insensitive</U>) the provided name - {@code null} if no match
+     */
+    public static BuiltinSignatures fromFactoryName(String name) {
+        return NamedResource.findByName(name, String.CASE_INSENSITIVE_ORDER, 
VALUES);
+    }
+
+    /**
+     * @param sigs A comma-separated list of signatures' names - ignored
+     *             if {@code null}/empty
+     * @return A {@link ParseResult} of all the {@link NamedFactory} whose
+     * name appears in the string and represent a built-in signature. Any
+     * unknown name is <U>ignored</U>. The order of the returned result
+     * is the same as the original order - bar the unknown signatures.
+     * <B>Note:</B> it is up to caller to ensure that the list does not
+     * contain duplicates
+     */
+    public static ParseResult parseSignatureList(String sigs) {
+        return parseSignatureList(GenericUtils.split(sigs, ','));
+    }
+
+    public static ParseResult parseSignatureList(String... sigs) {
+        return parseSignatureList(GenericUtils.isEmpty((Object[]) sigs) ? 
Collections.emptyList() : Arrays.asList(sigs));
+    }
+
+    public static ParseResult parseSignatureList(Collection<String> sigs) {
+        if (GenericUtils.isEmpty(sigs)) {
+            return ParseResult.EMPTY;
+        }
+
+        List<SignatureFactory> factories = new ArrayList<>(sigs.size());
+        List<String> unknown = Collections.emptyList();
+        for (String name : sigs) {
+            SignatureFactory s = resolveFactory(name);
+            if (s != null) {
+                factories.add(s);
+            } else {
+                // replace the (unmodifiable) empty list with a real one
+                if (unknown.isEmpty()) {
+                    unknown = new ArrayList<>();
+                }
+                unknown.add(name);
+            }
+        }
+
+        return new ParseResult(factories, unknown);
+    }
+
+    /**
+     * @param name The factory name
+     * @return The factory or {@code null} if it is neither a built-in one
+     * or a registered extension
+     */
+    public static SignatureFactory resolveFactory(String name) {
+        if (GenericUtils.isEmpty(name)) {
+            return null;
+        }
+
+        SignatureFactory s = fromFactoryName(name);
+        if (s != null) {
+            return s;
+        }
+
+        synchronized (EXTENSIONS) {
+            return EXTENSIONS.get(name);
+        }
+    }
+
+    /**
+     * Holds the result of the {@link 
BuiltinSignatures#parseSignatureList(String)}
+     *
+     * @author <a href="mailto:[email protected]";>Apache MINA SSHD 
Project</a>
+     */
+    public static final class ParseResult extends 
NamedFactoriesListParseResult<Signature, SignatureFactory> {
+        public static final ParseResult EMPTY = new 
ParseResult(Collections.emptyList(), Collections.emptyList());
+
+        public ParseResult(List<SignatureFactory> parsed, List<String> 
unsupported) {
+            super(parsed, unsupported);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-common/src/main/java/org/apache/sshd/common/signature/Signature.java
----------------------------------------------------------------------
diff --git 
a/sshd-common/src/main/java/org/apache/sshd/common/signature/Signature.java 
b/sshd-common/src/main/java/org/apache/sshd/common/signature/Signature.java
new file mode 100644
index 0000000..fd88a1d
--- /dev/null
+++ b/sshd-common/src/main/java/org/apache/sshd/common/signature/Signature.java
@@ -0,0 +1,88 @@
+/*
+ * 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.signature;
+
+import java.security.PrivateKey;
+import java.security.PublicKey;
+
+import org.apache.sshd.common.util.NumberUtils;
+
+/**
+ * Signature interface for SSH used to sign or verify packets
+ * Usually wraps a javax.crypto.Signature object
+ *
+ * @author <a href="mailto:[email protected]";>Apache MINA SSHD Project</a>
+ */
+public interface Signature {
+    /**
+     * @return The signature algorithm name
+     */
+    String getAlgorithm();
+
+    /**
+     * @param key The {@link PublicKey} to be used for verifying signatures
+     * @throws Exception If failed to initialize
+     */
+    void initVerifier(PublicKey key) throws Exception;
+
+    /**
+     * @param key The {@link PrivateKey} to be used for signing
+     * @throws Exception If failed to initialize
+     */
+    void initSigner(PrivateKey key) throws Exception;
+
+    /**
+     * Update the computed signature with the given data
+     *
+     * @param hash The hash data buffer
+     * @throws Exception If failed to update
+     * @see #update(byte[], int, int)
+     */
+    default void update(byte[] hash) throws Exception {
+        update(hash, 0, NumberUtils.length(hash));
+    }
+
+    /**
+     * Update the computed signature with the given data
+     *
+     * @param hash The hash data buffer
+     * @param off  Offset of hash data in buffer
+     * @param len  Length of hash data
+     * @throws Exception If failed to update
+     */
+    void update(byte[] hash, int off, int len) throws Exception;
+
+    /**
+     * Verify against the given signature
+     *
+     * @param sig The signed data
+     * @return {@code true} if signature is valid
+     * @throws Exception If failed to extract signed data for validation
+     */
+    boolean verify(byte[] sig) throws Exception;
+
+    /**
+     * Compute the signature
+     *
+     * @return The signature value
+     * @throws Exception If failed to calculate the signature
+     */
+    byte[] sign() throws Exception;
+
+}

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-common/src/main/java/org/apache/sshd/common/signature/SignatureDSA.java
----------------------------------------------------------------------
diff --git 
a/sshd-common/src/main/java/org/apache/sshd/common/signature/SignatureDSA.java 
b/sshd-common/src/main/java/org/apache/sshd/common/signature/SignatureDSA.java
new file mode 100644
index 0000000..1f552bd
--- /dev/null
+++ 
b/sshd-common/src/main/java/org/apache/sshd/common/signature/SignatureDSA.java
@@ -0,0 +1,142 @@
+/*
+ * 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.signature;
+
+import java.io.StreamCorruptedException;
+import java.math.BigInteger;
+import java.security.SignatureException;
+import java.util.Map;
+
+import org.apache.sshd.common.keyprovider.KeyPairProvider;
+import org.apache.sshd.common.util.NumberUtils;
+import org.apache.sshd.common.util.ValidateUtils;
+import org.apache.sshd.common.util.buffer.BufferUtils;
+import org.apache.sshd.common.util.io.der.DERParser;
+import org.apache.sshd.common.util.io.der.DERWriter;
+
+
+/**
+ * DSA <code>Signature</code>
+ *
+ * @author <a href="mailto:[email protected]";>Apache MINA SSHD Project</a>
+ * @see <A HREF="https://tools.ietf.org/html/rfc4253#section-6.6";>RFC4253 
section 6.6</A>
+ */
+public class SignatureDSA extends AbstractSignature {
+    public static final String DEFAULT_ALGORITHM = "SHA1withDSA";
+
+    public static final int DSA_SIGNATURE_LENGTH = 40;
+    // result must be 40 bytes, but length of r and s may not exceed 20 bytes
+    public static final int MAX_SIGNATURE_VALUE_LENGTH = DSA_SIGNATURE_LENGTH 
/ 2;
+
+    public SignatureDSA() {
+        this(DEFAULT_ALGORITHM);
+    }
+
+    protected SignatureDSA(String algorithm) {
+        super(algorithm);
+    }
+
+    @Override
+    public byte[] sign() throws Exception {
+        byte[] sig = super.sign();
+
+        try (DERParser parser = new DERParser(sig)) {
+            int type = parser.read();
+            if (type != 0x30) {
+                throw new StreamCorruptedException("Invalid signature format - 
not a DER SEQUENCE: 0x" + Integer.toHexString(type));
+            }
+
+            // length of remaining encoding of the 2 integers
+            int remainLen = parser.readLength();
+            /*
+             * There are supposed to be 2 INTEGERs, each encoded with:
+             *
+             *  - one byte representing the fact that it is an INTEGER
+             *  - one byte of the integer encoding length
+             *  - at least one byte of integer data (zero length is not an 
option)
+             */
+            if (remainLen < (2 * 3)) {
+                throw new StreamCorruptedException("Invalid signature format - 
not enough encoded data length: " + remainLen);
+            }
+
+            BigInteger r = parser.readBigInteger();
+            BigInteger s = parser.readBigInteger();
+
+            byte[] result = new byte[DSA_SIGNATURE_LENGTH];
+            putBigInteger(r, result, 0);
+            putBigInteger(s, result, MAX_SIGNATURE_VALUE_LENGTH);
+            return result;
+        }
+    }
+
+    public static void putBigInteger(BigInteger value, byte[] result, int 
offset) {
+        byte[] data = value.toByteArray();
+        boolean maxExceeded = data.length > MAX_SIGNATURE_VALUE_LENGTH;
+        int dstOffset = maxExceeded ? 0 : (MAX_SIGNATURE_VALUE_LENGTH - 
data.length);
+        System.arraycopy(data, maxExceeded ? 1 : 0,
+                result, offset + dstOffset,
+                Math.min(MAX_SIGNATURE_VALUE_LENGTH, data.length));
+    }
+
+    @Override
+    public boolean verify(byte[] sig) throws Exception {
+        int sigLen = NumberUtils.length(sig);
+        byte[] data = sig;
+
+        if (sigLen != DSA_SIGNATURE_LENGTH) {
+            // probably some encoded data
+            Map.Entry<String, byte[]> encoding = extractEncodedSignature(sig);
+            if (encoding != null) {
+                String keyType = encoding.getKey();
+                
ValidateUtils.checkTrue(KeyPairProvider.SSH_DSS.equals(keyType), "Mismatched 
key type: %s", keyType);
+                data = encoding.getValue();
+                sigLen = NumberUtils.length(data);
+            }
+        }
+
+        if (sigLen != DSA_SIGNATURE_LENGTH) {
+            throw new SignatureException("Bad signature length (" + sigLen + " 
instead of " + DSA_SIGNATURE_LENGTH + ")"
+                    + " for " + BufferUtils.toHex(':', data));
+        }
+
+        byte[] rEncoding;
+        try (DERWriter w = new DERWriter(MAX_SIGNATURE_VALUE_LENGTH + 4)) {    
 // in case length > 0x7F
+            w.writeBigInteger(data, 0, MAX_SIGNATURE_VALUE_LENGTH);
+            rEncoding = w.toByteArray();
+        }
+
+        byte[] sEncoding;
+        try (DERWriter w = new DERWriter(MAX_SIGNATURE_VALUE_LENGTH + 4)) {    
 // in case length > 0x7F
+            w.writeBigInteger(data, MAX_SIGNATURE_VALUE_LENGTH, 
MAX_SIGNATURE_VALUE_LENGTH);
+            sEncoding = w.toByteArray();
+        }
+
+        int length = rEncoding.length + sEncoding.length;
+        byte[] encoded;
+        try (DERWriter w = new DERWriter(1 + length + 4)) {  // in case length 
> 0x7F
+            w.write(0x30); // SEQUENCE
+            w.writeLength(length);
+            w.write(rEncoding);
+            w.write(sEncoding);
+            encoded = w.toByteArray();
+        }
+
+        return doVerify(encoded);
+    }
+}

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-common/src/main/java/org/apache/sshd/common/signature/SignatureECDSA.java
----------------------------------------------------------------------
diff --git 
a/sshd-common/src/main/java/org/apache/sshd/common/signature/SignatureECDSA.java
 
b/sshd-common/src/main/java/org/apache/sshd/common/signature/SignatureECDSA.java
new file mode 100644
index 0000000..56964d3
--- /dev/null
+++ 
b/sshd-common/src/main/java/org/apache/sshd/common/signature/SignatureECDSA.java
@@ -0,0 +1,144 @@
+/*
+ * 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.signature;
+
+import java.io.StreamCorruptedException;
+import java.math.BigInteger;
+import java.util.Map;
+
+import org.apache.sshd.common.cipher.ECCurves;
+import org.apache.sshd.common.util.ValidateUtils;
+import org.apache.sshd.common.util.buffer.Buffer;
+import org.apache.sshd.common.util.buffer.ByteArrayBuffer;
+import org.apache.sshd.common.util.io.der.DERParser;
+import org.apache.sshd.common.util.io.der.DERWriter;
+
+/**
+ * Signature algorithm for EC keys using ECDSA.
+ *
+ * @author <a href="mailto:[email protected]";>Apache MINA SSHD Project</a>
+ * @see <A HREF="http://tools.ietf.org/html/rfc3278#section-8.2";>RFC3278 
section 8.2</A>
+ */
+public class SignatureECDSA extends AbstractSignature {
+    public static class SignatureECDSA256 extends SignatureECDSA {
+        public static final String DEFAULT_ALGORITHM = "SHA256withECDSA";
+
+        public SignatureECDSA256() {
+            super(DEFAULT_ALGORITHM);
+        }
+    }
+
+    public static class SignatureECDSA384 extends SignatureECDSA {
+        public static final String DEFAULT_ALGORITHM = "SHA384withECDSA";
+
+        public SignatureECDSA384() {
+            super(DEFAULT_ALGORITHM);
+        }
+    }
+
+    public static class SignatureECDSA521 extends SignatureECDSA {
+        public static final String DEFAULT_ALGORITHM = "SHA512withECDSA";
+
+        public SignatureECDSA521() {
+            super(DEFAULT_ALGORITHM);
+        }
+    }
+
+    protected SignatureECDSA(String algo) {
+        super(algo);
+    }
+
+    @Override
+    public byte[] sign() throws Exception {
+        byte[] sig = super.sign();
+
+        try (DERParser parser = new DERParser(sig)) {
+            int type = parser.read();
+            if (type != 0x30) {
+                throw new StreamCorruptedException("Invalid signature format - 
not a DER SEQUENCE: 0x" + Integer.toHexString(type));
+            }
+
+            // length of remaining encoding of the 2 integers
+            int remainLen = parser.readLength();
+            /*
+             * There are supposed to be 2 INTEGERs, each encoded with:
+             *
+             *  - one byte representing the fact that it is an INTEGER
+             *  - one byte of the integer encoding length
+             *  - at least one byte of integer data (zero length is not an 
option)
+             */
+            if (remainLen < (2 * 3)) {
+                throw new StreamCorruptedException("Invalid signature format - 
not enough encoded data length: " + remainLen);
+            }
+
+            BigInteger r = parser.readBigInteger();
+            BigInteger s = parser.readBigInteger();
+            // Write the <r,s> to its own types writer.
+            Buffer rsBuf = new ByteArrayBuffer();
+            rsBuf.putMPInt(r);
+            rsBuf.putMPInt(s);
+
+            return rsBuf.getCompactData();
+        }
+    }
+
+    @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();
+            ECCurves curve = ECCurves.fromKeyType(keyType);
+            ValidateUtils.checkNotNull(curve, "Unknown curve type: %s", 
keyType);
+            data = encoding.getValue();
+        }
+
+        Buffer rsBuf = new ByteArrayBuffer(data);
+        byte[] rArray = rsBuf.getMPIntAsBytes();
+        byte[] rEncoding;
+        try (DERWriter w = new DERWriter(rArray.length + 4)) {     // in case 
length > 0x7F
+            w.writeBigInteger(rArray);
+            rEncoding = w.toByteArray();
+        }
+
+        byte[] sArray = rsBuf.getMPIntAsBytes();
+        byte[] sEncoding;
+        try (DERWriter w = new DERWriter(sArray.length + 4)) {     // in case 
length > 0x7F
+            w.writeBigInteger(sArray);
+            sEncoding = w.toByteArray();
+        }
+
+        int remaining = rsBuf.available();
+        if (remaining != 0) {
+            throw new StreamCorruptedException("Signature had padding - 
remaining=" + remaining);
+        }
+
+        int length = rEncoding.length + sEncoding.length;
+        byte[] encoded;
+        try (DERWriter w = new DERWriter(1 + length + 4)) {  // in case length 
> 0x7F
+            w.write(0x30); // SEQUENCE
+            w.writeLength(length);
+            w.write(rEncoding);
+            w.write(sEncoding);
+            encoded = w.toByteArray();
+        }
+
+        return doVerify(encoded);
+    }
+}

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-common/src/main/java/org/apache/sshd/common/signature/SignatureFactoriesManager.java
----------------------------------------------------------------------
diff --git 
a/sshd-common/src/main/java/org/apache/sshd/common/signature/SignatureFactoriesManager.java
 
b/sshd-common/src/main/java/org/apache/sshd/common/signature/SignatureFactoriesManager.java
new file mode 100644
index 0000000..c9d876a
--- /dev/null
+++ 
b/sshd-common/src/main/java/org/apache/sshd/common/signature/SignatureFactoriesManager.java
@@ -0,0 +1,94 @@
+/*
+ * 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.signature;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.sshd.common.NamedFactory;
+import org.apache.sshd.common.NamedResource;
+import org.apache.sshd.common.util.GenericUtils;
+import org.apache.sshd.common.util.ValidateUtils;
+
+/**
+ * Manage the list of named factories for <code>Signature</code>.
+ *
+ * @author <a href="mailto:[email protected]";>Apache MINA SSHD Project</a>
+ */
+public interface SignatureFactoriesManager {
+    /**
+     * @return The list of named <code>Signature</code> factories
+     */
+    List<NamedFactory<Signature>> getSignatureFactories();
+
+    default String getSignatureFactoriesNameList() {
+        return NamedResource.getNames(getSignatureFactories());
+    }
+
+    default List<String> getSignatureFactoriesNames() {
+        return NamedResource.getNameList(getSignatureFactories());
+    }
+
+    void setSignatureFactories(List<NamedFactory<Signature>> factories);
+
+    default void setSignatureFactoriesNameList(String names) {
+        setSignatureFactoriesNames(GenericUtils.split(names, ','));
+    }
+
+    default void setSignatureFactoriesNames(String... names) {
+        setSignatureFactoriesNames(GenericUtils.isEmpty((Object[]) names) ? 
Collections.emptyList() : Arrays.asList(names));
+    }
+
+    default void setSignatureFactoriesNames(Collection<String> names) {
+        BuiltinSignatures.ParseResult result = 
BuiltinSignatures.parseSignatureList(names);
+        @SuppressWarnings({ "rawtypes", "unchecked" })
+        List<NamedFactory<Signature>> factories =
+                (List) 
ValidateUtils.checkNotNullAndNotEmpty(result.getParsedFactories(), "No 
supported signature factories: %s", names);
+        Collection<String> unsupported = result.getUnsupportedFactories();
+        ValidateUtils.checkTrue(GenericUtils.isEmpty(unsupported), 
"Unsupported signature factories found: %s", unsupported);
+        setSignatureFactories(factories);
+    }
+
+    /**
+     * Attempts to use the primary manager's signature factories if not {@code 
null}/empty,
+     * otherwise uses the secondary ones (regardless of whether there are 
any...)
+     *
+     * @param primary The primary {@link SignatureFactoriesManager}
+     * @param secondary The secondary {@link SignatureFactoriesManager}
+     * @return The resolved signature factories - may be {@code null}/empty
+     * @see #getSignatureFactories(SignatureFactoriesManager)
+     */
+    static List<NamedFactory<Signature>> resolveSignatureFactories(
+            SignatureFactoriesManager primary, SignatureFactoriesManager 
secondary) {
+        List<NamedFactory<Signature>> factories = 
getSignatureFactories(primary);
+        return GenericUtils.isEmpty(factories) ? 
getSignatureFactories(secondary) : factories;
+    }
+
+    /**
+     * @param manager The {@link SignatureFactoriesManager} instance - ignored 
if {@code null}
+     * @return The associated list of named <code>Signature</code> factories 
or {@code null} if
+     * no manager instance
+     */
+    static List<NamedFactory<Signature>> 
getSignatureFactories(SignatureFactoriesManager manager) {
+        return (manager == null) ? null : manager.getSignatureFactories();
+    }
+}

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-common/src/main/java/org/apache/sshd/common/signature/SignatureFactory.java
----------------------------------------------------------------------
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
new file mode 100644
index 0000000..0881714
--- /dev/null
+++ 
b/sshd-common/src/main/java/org/apache/sshd/common/signature/SignatureFactory.java
@@ -0,0 +1,31 @@
+/*
+ * 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.signature;
+
+import org.apache.sshd.common.BuiltinFactory;
+
+/**
+ * @author <a href="mailto:[email protected]";>Apache MINA SSHD Project</a>
+ */
+// CHECKSTYLE:OFF
+public interface SignatureFactory extends BuiltinFactory<Signature> {
+    // nothing extra
+}
+//CHECKSTYLE:ON

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-common/src/main/java/org/apache/sshd/common/signature/SignatureRSA.java
----------------------------------------------------------------------
diff --git 
a/sshd-common/src/main/java/org/apache/sshd/common/signature/SignatureRSA.java 
b/sshd-common/src/main/java/org/apache/sshd/common/signature/SignatureRSA.java
new file mode 100644
index 0000000..ad1d37e
--- /dev/null
+++ 
b/sshd-common/src/main/java/org/apache/sshd/common/signature/SignatureRSA.java
@@ -0,0 +1,89 @@
+/*
+ * 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.signature;
+
+import java.math.BigInteger;
+import java.security.PublicKey;
+import java.security.interfaces.RSAKey;
+import java.util.Map;
+
+import org.apache.sshd.common.keyprovider.KeyPairProvider;
+import org.apache.sshd.common.util.ValidateUtils;
+
+/**
+ * RSA <code>Signature</code>
+ *
+ * @author <a href="mailto:[email protected]";>Apache MINA SSHD Project</a>
+ * @see <A HREF="https://tools.ietf.org/html/rfc4253#section-6.6";>RFC4253 
section 6.6</A>
+ */
+public class SignatureRSA extends AbstractSignature {
+    public static final String DEFAULT_ALGORITHM = "SHA1withRSA";
+
+    private int verifierSignatureSize = -1;
+
+    public SignatureRSA() {
+        super(DEFAULT_ALGORITHM);
+    }
+
+    protected SignatureRSA(String algorithm) {
+        super(algorithm);
+    }
+
+    /**
+     * @return The expected number of bytes in the signature - non-positive
+     * if not initialized or not intended to be used for verification
+     */
+    protected int getVerifierSignatureSize() {
+        return verifierSignatureSize;
+    }
+
+    @Override
+    public void initVerifier(PublicKey key) throws Exception {
+        super.initVerifier(key);
+        RSAKey rsaKey = ValidateUtils.checkInstanceOf(key, RSAKey.class, "Not 
an RSA key");
+        verifierSignatureSize = getVerifierSignatureSize(rsaKey);
+    }
+
+    public static int getVerifierSignatureSize(RSAKey key) {
+        BigInteger modulus = key.getModulus();
+        return (modulus.bitLength() + Byte.SIZE - 1) / Byte.SIZE;
+    }
+
+    @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_RSA.equals(keyType), 
"Mismatched key type: %s", keyType);
+            data = encoding.getValue();
+        }
+
+        int expectedSize = getVerifierSignatureSize();
+        ValidateUtils.checkTrue(expectedSize > 0, "Signature verification size 
has not been initialized");
+        // Pad with zero if value is trimmed
+        if (data.length < expectedSize) {
+            byte[] pad = new byte[expectedSize];
+            System.arraycopy(data, 0, pad, pad.length - data.length, 
data.length);
+            data = pad;
+        }
+
+        return doVerify(data);
+    }
+}

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-common/src/main/java/org/apache/sshd/common/signature/package.html
----------------------------------------------------------------------
diff --git 
a/sshd-common/src/main/java/org/apache/sshd/common/signature/package.html 
b/sshd-common/src/main/java/org/apache/sshd/common/signature/package.html
new file mode 100644
index 0000000..d1b16e4
--- /dev/null
+++ b/sshd-common/src/main/java/org/apache/sshd/common/signature/package.html
@@ -0,0 +1,25 @@
+<!--
+    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.
+-->
+<html>
+<head>
+</head>
+<body>
+
+<a 
href="{@docRoot}/org/apache/sshd/common/signature/Signature.html"><code>Signature</code></a>
 implementations.
+
+</body>
+</html>

Reply via email to