Repository: mina-sshd
Updated Branches:
  refs/heads/master 8e255459a -> cbb92d2a8


[SSHD-727] Upgrade used EdDSA artifact version to 1.1


Project: http://git-wip-us.apache.org/repos/asf/mina-sshd/repo
Commit: http://git-wip-us.apache.org/repos/asf/mina-sshd/commit/cbb92d2a
Tree: http://git-wip-us.apache.org/repos/asf/mina-sshd/tree/cbb92d2a
Diff: http://git-wip-us.apache.org/repos/asf/mina-sshd/diff/cbb92d2a

Branch: refs/heads/master
Commit: cbb92d2a89600ee8a34abdf7d84cdc08291dcbf5
Parents: 22dc7c3
Author: Lyor Goldstein <lyor.goldst...@gmail.com>
Authored: Thu Mar 2 21:47:51 2017 +0200
Committer: Lyor Goldstein <lyor.goldst...@gmail.com>
Committed: Thu Mar 2 22:01:14 2017 +0200

----------------------------------------------------------------------
 pom.xml                                         |   6 +-
 .../common/util/security/SecurityUtils.java     |  31 +--
 .../security/eddsa/EdDSASecurityProvider.java   | 205 -------------------
 .../eddsa/EdDSASecurityProviderRegistrar.java   |   2 +-
 .../eddsa/EdDSASecurityProviderUtils.java       | 197 ++++++++++++++++++
 .../OpenSSHEd25519PrivateKeyEntryDecoder.java   |   2 +-
 .../common/signature/SignaturesDevelopment.java |   6 +-
 .../util/security/eddsa/Ed25519VectorsTest.java |  12 +-
 .../EdDSASecurityProviderRegistrarTest.java     |   2 +
 9 files changed, 229 insertions(+), 234 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/cbb92d2a/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 806f7fb..06ec711 100644
--- a/pom.xml
+++ b/pom.xml
@@ -104,7 +104,7 @@
         <gmaven.plugin.version>2.0</gmaven.plugin.version>
         <groovy.major.version>2</groovy.major.version>
         <groovy.minor.version>4</groovy.minor.version>
-        <groovy.release.version>8</groovy.release.version>
+        <groovy.release.version>9</groovy.release.version>
         <groovy.compliance.level>2.0</groovy.compliance.level>
         
<groovy.version>${groovy.major.version}.${groovy.minor.version}.${groovy.release.version}</groovy.version>
        
 
@@ -202,7 +202,7 @@
             <dependency>
                 <groupId>net.i2p.crypto</groupId>
                 <artifactId>eddsa</artifactId>
-                <version>0.1.0</version>
+                <version>0.1.1</version>
             </dependency>
 
             <dependency>
@@ -594,7 +594,7 @@
                         <dependency>
                             <groupId>com.puppycrawl.tools</groupId>
                             <artifactId>checkstyle</artifactId>
-                            <version>7.5.1</version>
+                            <version>7.6</version>
                             <exclusions>
                                 <!-- MCHECKSTYLE-156 -->
                                 <exclusion>

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/cbb92d2a/sshd-core/src/main/java/org/apache/sshd/common/util/security/SecurityUtils.java
----------------------------------------------------------------------
diff --git 
a/sshd-core/src/main/java/org/apache/sshd/common/util/security/SecurityUtils.java
 
b/sshd-core/src/main/java/org/apache/sshd/common/util/security/SecurityUtils.java
index 6aff088..b86bcc3 100644
--- 
a/sshd-core/src/main/java/org/apache/sshd/common/util/security/SecurityUtils.java
+++ 
b/sshd-core/src/main/java/org/apache/sshd/common/util/security/SecurityUtils.java
@@ -73,7 +73,7 @@ import org.apache.sshd.common.util.buffer.Buffer;
 import 
org.apache.sshd.common.util.security.bouncycastle.BouncyCastleGeneratorHostKeyProvider;
 import 
org.apache.sshd.common.util.security.bouncycastle.BouncyCastleKeyPairResourceParser;
 import 
org.apache.sshd.common.util.security.bouncycastle.BouncyCastleRandomFactory;
-import org.apache.sshd.common.util.security.eddsa.EdDSASecurityProvider;
+import org.apache.sshd.common.util.security.eddsa.EdDSASecurityProviderUtils;
 import org.apache.sshd.common.util.threads.ThreadUtils;
 import org.apache.sshd.server.keyprovider.AbstractGeneratorHostKeyProvider;
 import org.slf4j.Logger;
@@ -91,12 +91,13 @@ public final class SecurityUtils {
     public static final String BOUNCY_CASTLE = "BC";
 
     /**
-     * EDDSA support
+     * EDDSA support - should match {@code EdDSAKey.KEY_ALGORITHM}
      */
     public static final String EDDSA = "EdDSA";
 
     // A copy-paste from the original, but we don't want to drag the classes 
into the classpath
-    public static final String CURVE_ED25519_SHA512 = "ed25519-sha-512";
+    // See EdDSANamedCurveTable.CURVE_ED25519_SHA512
+    public static final String CURVE_ED25519_SHA512 = "SHA512withEd25519";
 
     /**
      * System property used to configure the value for the maximum supported 
Diffie-Hellman
@@ -538,7 +539,7 @@ public final class SecurityUtils {
             throw new UnsupportedOperationException(EDDSA + " provider N/A");
         }
 
-        return EdDSASecurityProvider.getEDDSAPublicKeyEntryDecoder();
+        return EdDSASecurityProviderUtils.getEDDSAPublicKeyEntryDecoder();
     }
 
     public static PrivateKeyEntryDecoder<? extends PublicKey, ? extends 
PrivateKey> getOpenSSHEDDSAPrivateKeyEntryDecoder() {
@@ -546,35 +547,35 @@ public final class SecurityUtils {
             throw new UnsupportedOperationException(EDDSA + " provider N/A");
         }
 
-        return EdDSASecurityProvider.getOpenSSHEDDSAPrivateKeyEntryDecoder();
+        return 
EdDSASecurityProviderUtils.getOpenSSHEDDSAPrivateKeyEntryDecoder();
     }
 
     public static org.apache.sshd.common.signature.Signature getEDDSASigner() {
         if (isEDDSACurveSupported()) {
-            return EdDSASecurityProvider.getEDDSASignature();
+            return EdDSASecurityProviderUtils.getEDDSASignature();
         }
 
         throw new UnsupportedOperationException(EDDSA + " Signer not 
available");
     }
 
     public static int getEDDSAKeySize(Key key) {
-        return EdDSASecurityProvider.getEDDSAKeySize(key);
+        return EdDSASecurityProviderUtils.getEDDSAKeySize(key);
     }
 
     public static Class<? extends PublicKey> getEDDSAPublicKeyType() {
-        return isEDDSACurveSupported() ? 
EdDSASecurityProvider.getEDDSAPublicKeyType() : PublicKey.class;
+        return isEDDSACurveSupported() ? 
EdDSASecurityProviderUtils.getEDDSAPublicKeyType() : PublicKey.class;
     }
 
     public static Class<? extends PrivateKey> getEDDSAPrivateKeyType() {
-        return isEDDSACurveSupported() ? 
EdDSASecurityProvider.getEDDSAPrivateKeyType() : PrivateKey.class;
+        return isEDDSACurveSupported() ? 
EdDSASecurityProviderUtils.getEDDSAPrivateKeyType() : PrivateKey.class;
     }
 
     public static boolean compareEDDSAPPublicKeys(PublicKey k1, PublicKey k2) {
-        return isEDDSACurveSupported() ? 
EdDSASecurityProvider.compareEDDSAPPublicKeys(k1, k2) : false;
+        return isEDDSACurveSupported() ? 
EdDSASecurityProviderUtils.compareEDDSAPPublicKeys(k1, k2) : false;
     }
 
     public static boolean compareEDDSAPrivateKeys(PrivateKey k1, PrivateKey 
k2) {
-        return isEDDSACurveSupported() ? 
EdDSASecurityProvider.compareEDDSAPrivateKeys(k1, k2) : false;
+        return isEDDSACurveSupported() ? 
EdDSASecurityProviderUtils.compareEDDSAPrivateKeys(k1, k2) : false;
     }
 
     public static PublicKey recoverEDDSAPublicKey(PrivateKey key) throws 
GeneralSecurityException {
@@ -582,7 +583,7 @@ public final class SecurityUtils {
             throw new NoSuchAlgorithmException(EDDSA + " provider not 
supported");
         }
 
-        return EdDSASecurityProvider.recoverEDDSAPublicKey(key);
+        return EdDSASecurityProviderUtils.recoverEDDSAPublicKey(key);
     }
 
     public static PublicKey generateEDDSAPublicKey(String keyType, byte[] 
seed) throws GeneralSecurityException {
@@ -594,7 +595,7 @@ public final class SecurityUtils {
             throw new NoSuchAlgorithmException(EDDSA + " provider not 
supported");
         }
 
-        return EdDSASecurityProvider.generateEDDSAPublicKey(seed);
+        return EdDSASecurityProviderUtils.generateEDDSAPublicKey(seed);
     }
 
     public static <B extends Buffer> B putRawEDDSAPublicKey(B buffer, 
PublicKey key) {
@@ -602,7 +603,7 @@ public final class SecurityUtils {
             throw new UnsupportedOperationException(EDDSA + " provider not 
supported");
         }
 
-        return EdDSASecurityProvider.putRawEDDSAPublicKey(buffer, key);
+        return EdDSASecurityProviderUtils.putRawEDDSAPublicKey(buffer, key);
     }
 
     public static <B extends Buffer> B putEDDSAKeyPair(B buffer, KeyPair kp) {
@@ -614,7 +615,7 @@ public final class SecurityUtils {
             throw new UnsupportedOperationException(EDDSA + " provider not 
supported");
         }
 
-        return EdDSASecurityProvider.putEDDSAKeyPair(buffer, pubKey, prvKey);
+        return EdDSASecurityProviderUtils.putEDDSAKeyPair(buffer, pubKey, 
prvKey);
     }
 
     public static KeyPair extractEDDSAKeyPair(Buffer buffer, String keyType) 
throws GeneralSecurityException {

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/cbb92d2a/sshd-core/src/main/java/org/apache/sshd/common/util/security/eddsa/EdDSASecurityProvider.java
----------------------------------------------------------------------
diff --git 
a/sshd-core/src/main/java/org/apache/sshd/common/util/security/eddsa/EdDSASecurityProvider.java
 
b/sshd-core/src/main/java/org/apache/sshd/common/util/security/eddsa/EdDSASecurityProvider.java
deleted file mode 100644
index e039547..0000000
--- 
a/sshd-core/src/main/java/org/apache/sshd/common/util/security/eddsa/EdDSASecurityProvider.java
+++ /dev/null
@@ -1,205 +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.Provider;
-import java.security.PublicKey;
-import java.util.Arrays;
-import java.util.Objects;
-
-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;
-
-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;
-
-/**
- * @author <a href="mailto:d...@mina.apache.org";>Apache MINA SSHD Project</a>
- */
-public class EdDSASecurityProvider extends Provider {
-    private static final long serialVersionUID = -6183277432144104981L;
-
-    public EdDSASecurityProvider() {
-        super(SecurityUtils.EDDSA, 0.1, "net.i2p security provider wrapper");
-
-        // see 
https://docs.oracle.com/javase/8/docs/technotes/guides/security/crypto/HowToImplAProvider.html
-        put("KeyPairGenerator." + SecurityUtils.EDDSA, 
"net.i2p.crypto.eddsa.KeyPairGenerator");
-        put("KeyFactory." + SecurityUtils.EDDSA, 
"net.i2p.crypto.eddsa.KeyFactory");
-        put("Signature." + EdDSANamedCurveTable.CURVE_ED25519_SHA512, 
"net.i2p.crypto.eddsa.EdDSAEngine");
-    }
-
-    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 
EdDSANamedCurveTable.CURVE_ED25519_SHA512.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.getSeed(), 
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(EdDSANamedCurveTable.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(EdDSANamedCurveTable.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/cbb92d2a/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
index b463d27..2bb3f95 100644
--- 
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
@@ -36,7 +36,7 @@ import org.apache.sshd.common.util.threads.ThreadUtils;
  * @author <a href="mailto:d...@mina.apache.org";>Apache MINA SSHD Project</a>
  */
 public class EdDSASecurityProviderRegistrar extends 
AbstractSecurityProviderRegistrar {
-    public static final String PROVIDER_CLASS = 
"org.apache.sshd.common.util.security.eddsa.EdDSASecurityProvider";
+    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);
 

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/cbb92d2a/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
new file mode 100644
index 0000000..b5d79f0
--- /dev/null
+++ 
b/sshd-core/src/main/java/org/apache/sshd/common/util/security/eddsa/EdDSASecurityProviderUtils.java
@@ -0,0 +1,197 @@
+/*
+ * 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 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;
+
+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;
+
+/**
+ * @author <a href="mailto:d...@mina.apache.org";>Apache MINA SSHD Project</a>
+ */
+public final class EdDSASecurityProviderUtils {
+    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 
EdDSANamedCurveTable.CURVE_ED25519_SHA512.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.getSeed(), 
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(EdDSANamedCurveTable.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(EdDSANamedCurveTable.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/cbb92d2a/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
index b05a4cc..e5ae0ac 100644
--- 
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
@@ -98,7 +98,7 @@ public class OpenSSHEd25519PrivateKeyEntryDecoder extends 
AbstractPrivateKeyEntr
 
     @Override
     public EdDSAPublicKey recoverPublicKey(EdDSAPrivateKey prvKey) throws 
GeneralSecurityException {
-        return EdDSASecurityProvider.recoverEDDSAPublicKey(prvKey);
+        return EdDSASecurityProviderUtils.recoverEDDSAPublicKey(prvKey);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/cbb92d2a/sshd-core/src/test/java/org/apache/sshd/common/signature/SignaturesDevelopment.java
----------------------------------------------------------------------
diff --git 
a/sshd-core/src/test/java/org/apache/sshd/common/signature/SignaturesDevelopment.java
 
b/sshd-core/src/test/java/org/apache/sshd/common/signature/SignaturesDevelopment.java
index 6c4929a..180e997 100644
--- 
a/sshd-core/src/test/java/org/apache/sshd/common/signature/SignaturesDevelopment.java
+++ 
b/sshd-core/src/test/java/org/apache/sshd/common/signature/SignaturesDevelopment.java
@@ -25,7 +25,7 @@ import java.security.PublicKey;
 
 import org.apache.sshd.common.util.GenericUtils;
 import org.apache.sshd.common.util.buffer.BufferUtils;
-import org.apache.sshd.common.util.security.eddsa.EdDSASecurityProvider;
+import org.apache.sshd.common.util.security.eddsa.EdDSASecurityProviderUtils;
 import org.apache.sshd.util.test.BaseTestSupport;
 
 /**
@@ -64,9 +64,9 @@ public class SignaturesDevelopment extends BaseTestSupport {
         SignatureFactory factory = BuiltinSignatures.resolveFactory(args[0]);
         // TODO recover public/private keys according to factory name
         byte[] publicKey = BufferUtils.decodeHex(':', args[1]);
-        PublicKey pubKey = 
EdDSASecurityProvider.generateEDDSAPublicKey(publicKey);
+        PublicKey pubKey = 
EdDSASecurityProviderUtils.generateEDDSAPublicKey(publicKey);
         byte[] privateKey = BufferUtils.decodeHex(':', args[2]);
-        PrivateKey prvKey = 
EdDSASecurityProvider.generateEDDSAPrivateKey(privateKey);
+        PrivateKey prvKey = 
EdDSASecurityProviderUtils.generateEDDSAPrivateKey(privateKey);
         String op = args[3];
         byte[] data = BufferUtils.decodeHex(':', args[4]);
         byte[] signature = GenericUtils.EMPTY_BYTE_ARRAY;

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/cbb92d2a/sshd-core/src/test/java/org/apache/sshd/common/util/security/eddsa/Ed25519VectorsTest.java
----------------------------------------------------------------------
diff --git 
a/sshd-core/src/test/java/org/apache/sshd/common/util/security/eddsa/Ed25519VectorsTest.java
 
b/sshd-core/src/test/java/org/apache/sshd/common/util/security/eddsa/Ed25519VectorsTest.java
index fab3294..b58aad3 100644
--- 
a/sshd-core/src/test/java/org/apache/sshd/common/util/security/eddsa/Ed25519VectorsTest.java
+++ 
b/sshd-core/src/test/java/org/apache/sshd/common/util/security/eddsa/Ed25519VectorsTest.java
@@ -60,9 +60,9 @@ public class Ed25519VectorsTest extends BaseTestSupport {
     public Ed25519VectorsTest(String name, String prvKey, String pubKey, 
String msg, String signature)
             throws GeneralSecurityException {
         prvBytes = BufferUtils.decodeHex(BufferUtils.EMPTY_HEX_SEPARATOR, 
prvKey);
-        privateKey = 
EdDSASecurityProvider.generateEDDSAPrivateKey(prvBytes.clone());
+        privateKey = 
EdDSASecurityProviderUtils.generateEDDSAPrivateKey(prvBytes.clone());
         pubBytes = BufferUtils.decodeHex(BufferUtils.EMPTY_HEX_SEPARATOR, 
pubKey);
-        publicKey = 
EdDSASecurityProvider.generateEDDSAPublicKey(pubBytes.clone());
+        publicKey = 
EdDSASecurityProviderUtils.generateEDDSAPublicKey(pubBytes.clone());
         msgBytes = BufferUtils.decodeHex(BufferUtils.EMPTY_HEX_SEPARATOR, msg);
         expSignature = BufferUtils.decodeHex(BufferUtils.EMPTY_HEX_SEPARATOR, 
signature);
     }
@@ -200,14 +200,14 @@ public class Ed25519VectorsTest extends BaseTestSupport {
 
     @Test
     public void testSignature() throws Exception {
-        Signature signer = EdDSASecurityProvider.getEDDSASignature();
+        Signature signer = EdDSASecurityProviderUtils.getEDDSASignature();
         signer.initSigner(privateKey);
         signer.update(msgBytes.clone());
 
         byte[] actSignature = signer.sign();
         assertArrayEquals("Mismatched signature", expSignature, actSignature);
 
-        Signature verifier = EdDSASecurityProvider.getEDDSASignature();
+        Signature verifier = EdDSASecurityProviderUtils.getEDDSASignature();
         verifier.initVerifier(publicKey);
         verifier.update(msgBytes.clone());
         assertTrue("Verification failed", verifier.verify(expSignature));
@@ -222,14 +222,14 @@ public class Ed25519VectorsTest extends BaseTestSupport {
         System.arraycopy(msgBytes, 0, dataBuf, offset, msgBytes.length);
         System.arraycopy(extraData, offset, dataBuf, offset + msgBytes.length, 
extraData.length - offset);
 
-        Signature signer = EdDSASecurityProvider.getEDDSASignature();
+        Signature signer = EdDSASecurityProviderUtils.getEDDSASignature();
         signer.initSigner(privateKey);
         signer.update(dataBuf.clone(), offset, msgBytes.length);
 
         byte[] actSignature = signer.sign();
         assertArrayEquals("Mismatched signature", expSignature, actSignature);
 
-        Signature verifier = EdDSASecurityProvider.getEDDSASignature();
+        Signature verifier = EdDSASecurityProviderUtils.getEDDSASignature();
         verifier.initVerifier(publicKey);
         verifier.update(dataBuf.clone(), offset, msgBytes.length);
         assertTrue("Verification failed", verifier.verify(expSignature));

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/cbb92d2a/sshd-core/src/test/java/org/apache/sshd/common/util/security/eddsa/EdDSASecurityProviderRegistrarTest.java
----------------------------------------------------------------------
diff --git 
a/sshd-core/src/test/java/org/apache/sshd/common/util/security/eddsa/EdDSASecurityProviderRegistrarTest.java
 
b/sshd-core/src/test/java/org/apache/sshd/common/util/security/eddsa/EdDSASecurityProviderRegistrarTest.java
index 9e12fab..f2c1f3f 100644
--- 
a/sshd-core/src/test/java/org/apache/sshd/common/util/security/eddsa/EdDSASecurityProviderRegistrarTest.java
+++ 
b/sshd-core/src/test/java/org/apache/sshd/common/util/security/eddsa/EdDSASecurityProviderRegistrarTest.java
@@ -26,6 +26,8 @@ import java.util.Arrays;
 import java.util.Collection;
 import java.util.HashSet;
 
+import net.i2p.crypto.eddsa.EdDSASecurityProvider;
+
 import org.apache.sshd.common.util.security.SecurityProviderRegistrar;
 import 
org.apache.sshd.common.util.security.SecurityProviderRegistrarTestSupport;
 import org.apache.sshd.common.util.security.SecurityUtils;

Reply via email to