You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mina.apache.org by lg...@apache.org on 2017/04/04 18:29:15 UTC
mina-sshd git commit: [SSHD-727] Upgrade used EdDSA artifact version
to 0.2.0
Repository: mina-sshd
Updated Branches:
refs/heads/master 080c52878 -> d3e55205e
[SSHD-727] Upgrade used EdDSA artifact version to 0.2.0
Project: http://git-wip-us.apache.org/repos/asf/mina-sshd/repo
Commit: http://git-wip-us.apache.org/repos/asf/mina-sshd/commit/d3e55205
Tree: http://git-wip-us.apache.org/repos/asf/mina-sshd/tree/d3e55205
Diff: http://git-wip-us.apache.org/repos/asf/mina-sshd/diff/d3e55205
Branch: refs/heads/master
Commit: d3e55205e6feab230a8a87cdb0085210e7082aa9
Parents: 080c528
Author: Lyor Goldstein <ly...@gmail.com>
Authored: Tue Apr 4 21:29:10 2017 +0300
Committer: Lyor Goldstein <ly...@gmail.com>
Committed: Tue Apr 4 21:29:10 2017 +0300
----------------------------------------------------------------------
pom.xml | 6 +-
.../common/util/security/SecurityUtils.java | 31 +--
.../security/eddsa/EdDSASecurityProvider.java | 205 -------------------
.../eddsa/EdDSASecurityProviderRegistrar.java | 2 +-
.../eddsa/EdDSASecurityProviderUtils.java | 201 ++++++++++++++++++
.../OpenSSHEd25519PrivateKeyEntryDecoder.java | 4 +-
.../util/security/eddsa/SignatureEd25519.java | 4 +-
.../server/subsystem/sftp/SftpSubsystem.java | 10 +-
.../common/signature/SignaturesDevelopment.java | 6 +-
.../util/security/eddsa/EDDSAProviderTest.java | 6 +-
.../util/security/eddsa/Ed25519VectorsTest.java | 12 +-
.../EdDSASecurityProviderRegistrarTest.java | 2 +
12 files changed, 245 insertions(+), 244 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/d3e55205/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 806f7fb..bc06820 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.2.0</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/d3e55205/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..55d1a62 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 EdDSAEngine.SIGNATURE_ALGORITHM
+ public static final String CURVE_ED25519_SHA512 = "NONEwithEdDSA";
/**
* 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/d3e55205/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:dev@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/d3e55205/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:dev@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/d3e55205/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..24e7e5c
--- /dev/null
+++ b/sshd-core/src/main/java/org/apache/sshd/common/util/security/eddsa/EdDSASecurityProviderUtils.java
@@ -0,0 +1,201 @@
+/*
+ * 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.EdDSAEngine;
+import net.i2p.crypto.eddsa.EdDSAKey;
+import net.i2p.crypto.eddsa.EdDSAPrivateKey;
+import net.i2p.crypto.eddsa.EdDSAPublicKey;
+import net.i2p.crypto.eddsa.spec.EdDSANamedCurveTable;
+import net.i2p.crypto.eddsa.spec.EdDSAParameterSpec;
+import net.i2p.crypto.eddsa.spec.EdDSAPrivateKeySpec;
+import net.i2p.crypto.eddsa.spec.EdDSAPublicKeySpec;
+
+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:dev@mina.apache.org">Apache MINA SSHD Project</a>
+ */
+public final class EdDSASecurityProviderUtils {
+ // See EdDSANamedCurveTable
+ public static final String CURVE_ED25519_SHA512 = "Ed25519";
+
+ private EdDSASecurityProviderUtils() {
+ throw new UnsupportedOperationException("No instance");
+ }
+
+ public static Class<? extends PublicKey> getEDDSAPublicKeyType() {
+ return EdDSAPublicKey.class;
+ }
+
+ public static Class<? extends PrivateKey> getEDDSAPrivateKeyType() {
+ return EdDSAPrivateKey.class;
+ }
+
+ public static int getEDDSAKeySize(Key key) {
+ return (SecurityUtils.isEDDSACurveSupported() && (key instanceof EdDSAKey)) ? 256 : -1;
+ }
+
+ public static boolean compareEDDSAPPublicKeys(PublicKey k1, PublicKey k2) {
+ if (!SecurityUtils.isEDDSACurveSupported()) {
+ return false;
+ }
+
+ if ((k1 instanceof EdDSAPublicKey) && (k2 instanceof EdDSAPublicKey)) {
+ if (Objects.equals(k1, k2)) {
+ return true;
+ } else if (k1 == null || k2 == null) {
+ return false; // both null is covered by Objects#equals
+ }
+
+ EdDSAPublicKey ed1 = (EdDSAPublicKey) k1;
+ EdDSAPublicKey ed2 = (EdDSAPublicKey) k2;
+ return Arrays.equals(ed1.getAbyte(), ed2.getAbyte())
+ && compareEDDSAKeyParams(ed1.getParams(), ed2.getParams());
+ }
+
+ return false;
+ }
+
+ public static boolean isEDDSASignatureAlgorithm(String algorithm) {
+ return EdDSAEngine.SIGNATURE_ALGORITHM.equalsIgnoreCase(algorithm);
+ }
+
+ public static EdDSAPublicKey recoverEDDSAPublicKey(PrivateKey key) throws GeneralSecurityException {
+ ValidateUtils.checkTrue(SecurityUtils.isEDDSACurveSupported(), SecurityUtils.EDDSA + " not supported");
+ if (!(key instanceof EdDSAPrivateKey)) {
+ throw new InvalidKeyException("Private key is not " + SecurityUtils.EDDSA);
+ }
+
+ EdDSAPrivateKey prvKey = (EdDSAPrivateKey) key;
+ EdDSAPublicKeySpec keySpec = new EdDSAPublicKeySpec(prvKey.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(CURVE_ED25519_SHA512);
+ EdDSAPublicKeySpec keySpec = new EdDSAPublicKeySpec(seed, params);
+ KeyFactory factory = SecurityUtils.getKeyFactory(SecurityUtils.EDDSA);
+ return factory.generatePublic(keySpec);
+ }
+
+ public static PrivateKey generateEDDSAPrivateKey(byte[] seed) throws GeneralSecurityException {
+ if (!SecurityUtils.isEDDSACurveSupported()) {
+ throw new NoSuchAlgorithmException(SecurityUtils.EDDSA + " not supported");
+ }
+
+ EdDSAParameterSpec params = EdDSANamedCurveTable.getByName(CURVE_ED25519_SHA512);
+ EdDSAPrivateKeySpec keySpec = new EdDSAPrivateKeySpec(seed, params);
+ KeyFactory factory = SecurityUtils.getKeyFactory(SecurityUtils.EDDSA);
+ return factory.generatePrivate(keySpec);
+ }
+
+ public static <B extends Buffer> B putRawEDDSAPublicKey(B buffer, PublicKey key) {
+ ValidateUtils.checkTrue(SecurityUtils.isEDDSACurveSupported(), SecurityUtils.EDDSA + " not supported");
+ EdDSAPublicKey edKey = ValidateUtils.checkInstanceOf(key, EdDSAPublicKey.class, "Not an EDDSA public key: %s", key);
+ byte[] seed = Ed25519PublicKeyDecoder.getSeedValue(edKey);
+ ValidateUtils.checkNotNull(seed, "No seed extracted from key: %s", edKey.getA());
+ buffer.putString(KeyPairProvider.SSH_ED25519);
+ buffer.putBytes(seed);
+ return buffer;
+ }
+
+ public static <B extends Buffer> B putEDDSAKeyPair(B buffer, PublicKey pubKey, PrivateKey prvKey) {
+ ValidateUtils.checkTrue(SecurityUtils.isEDDSACurveSupported(), SecurityUtils.EDDSA + " not supported");
+ ValidateUtils.checkInstanceOf(pubKey, EdDSAPublicKey.class, "Not an EDDSA public key: %s", pubKey);
+ ValidateUtils.checkInstanceOf(prvKey, EdDSAPrivateKey.class, "Not an EDDSA private key: %s", prvKey);
+ throw new UnsupportedOperationException("Full SSHD-440 implementation N/A");
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/d3e55205/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..e83a328 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
@@ -70,7 +70,7 @@ public class OpenSSHEd25519PrivateKeyEntryDecoder extends AbstractPrivateKeyEntr
throw new InvalidKeyException("Mismatched signature (" + signature.length + ") vs. seed (" + seed.length + ") length");
}
- EdDSAParameterSpec params = EdDSANamedCurveTable.getByName(EdDSANamedCurveTable.CURVE_ED25519_SHA512);
+ EdDSAParameterSpec params = EdDSANamedCurveTable.getByName(EdDSASecurityProviderUtils.CURVE_ED25519_SHA512);
EdDSAPrivateKeySpec keySpec = new EdDSAPrivateKeySpec(seed, params);
return generatePrivateKey(keySpec);
}
@@ -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/d3e55205/sshd-core/src/main/java/org/apache/sshd/common/util/security/eddsa/SignatureEd25519.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/util/security/eddsa/SignatureEd25519.java b/sshd-core/src/main/java/org/apache/sshd/common/util/security/eddsa/SignatureEd25519.java
index 97a7cf9..cd601f6 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/util/security/eddsa/SignatureEd25519.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/util/security/eddsa/SignatureEd25519.java
@@ -18,7 +18,7 @@
*/
package org.apache.sshd.common.util.security.eddsa;
-import net.i2p.crypto.eddsa.spec.EdDSANamedCurveTable;
+import net.i2p.crypto.eddsa.EdDSAEngine;
import org.apache.sshd.common.keyprovider.KeyPairProvider;
import org.apache.sshd.common.signature.AbstractSignature;
@@ -30,7 +30,7 @@ import org.apache.sshd.common.util.ValidateUtils;
*/
public class SignatureEd25519 extends AbstractSignature {
public SignatureEd25519() {
- super(EdDSANamedCurveTable.CURVE_ED25519_SHA512);
+ super(EdDSAEngine.SIGNATURE_ALGORITHM);
}
@Override
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/d3e55205/sshd-core/src/main/java/org/apache/sshd/server/subsystem/sftp/SftpSubsystem.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/subsystem/sftp/SftpSubsystem.java b/sshd-core/src/main/java/org/apache/sshd/server/subsystem/sftp/SftpSubsystem.java
index fcdb4ad..f328990 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/subsystem/sftp/SftpSubsystem.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/subsystem/sftp/SftpSubsystem.java
@@ -2714,7 +2714,7 @@ public class SftpSubsystem
* @throws IOException If failed to generate an entry
*/
protected int doReadDir(
- int id, String handle, DirectoryHandle dir, Buffer buffer, int maxSize, LinkOption ... options) throws IOException {
+ int id, String handle, DirectoryHandle dir, Buffer buffer, int maxSize, LinkOption... options) throws IOException {
int nb = 0;
Map<String, Path> entries = new TreeMap<>(Comparator.naturalOrder());
while ((dir.isSendDot() || dir.isSendDotDot() || dir.hasNext()) && (buffer.wpos() < maxSize)) {
@@ -2722,7 +2722,8 @@ public class SftpSubsystem
writeDirEntry(id, dir, entries, buffer, nb, dir.getFile(), ".", options);
dir.markDotSent(); // do not send it again
} else if (dir.isSendDotDot()) {
- writeDirEntry(id, dir, entries, buffer, nb, dir.getFile().getParent(), "..", options);
+ Path dirPath = dir.getFile();
+ writeDirEntry(id, dir, entries, buffer, nb, dirPath.getParent(), "..", options);
dir.markDotDotSent(); // do not send it again
} else {
Path f = dir.next();
@@ -2749,8 +2750,9 @@ public class SftpSubsystem
* @param options The {@link LinkOption}s to use for querying the entry-s attributes
* @throws IOException If failed to generate the entry data
*/
- protected void writeDirEntry(int id, DirectoryHandle dir, Map<String, Path> entries, Buffer buffer, int index, Path f, String shortName, LinkOption... options)
- throws IOException {
+ protected void writeDirEntry(
+ int id, DirectoryHandle dir, Map<String, Path> entries, Buffer buffer, int index, Path f, String shortName, LinkOption... options)
+ throws IOException {
Map<String, ?> attrs = resolveFileAttributes(f, SftpConstants.SSH_FILEXFER_ATTR_ALL, options);
entries.put(shortName, f);
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/d3e55205/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/d3e55205/sshd-core/src/test/java/org/apache/sshd/common/util/security/eddsa/EDDSAProviderTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/common/util/security/eddsa/EDDSAProviderTest.java b/sshd-core/src/test/java/org/apache/sshd/common/util/security/eddsa/EDDSAProviderTest.java
index f7461a3..b69f1ea 100644
--- a/sshd-core/src/test/java/org/apache/sshd/common/util/security/eddsa/EDDSAProviderTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/common/util/security/eddsa/EDDSAProviderTest.java
@@ -27,7 +27,7 @@ import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
-import net.i2p.crypto.eddsa.spec.EdDSANamedCurveTable;
+import net.i2p.crypto.eddsa.EdDSAEngine;
import org.apache.sshd.common.config.keys.AuthorizedKeyEntry;
import org.apache.sshd.common.config.keys.KeyUtils;
@@ -75,7 +75,7 @@ public class EDDSAProviderTest extends BaseTestSupport {
@Test
public void testSignature() throws GeneralSecurityException {
- Signature s = SecurityUtils.getSignature(EdDSANamedCurveTable.CURVE_ED25519_SHA512);
+ Signature s = SecurityUtils.getSignature(EdDSAEngine.SIGNATURE_ALGORITHM);
assertNotNull("No signature instance", s);
s.initSign(keyPair.getPrivate());
@@ -83,7 +83,7 @@ public class EDDSAProviderTest extends BaseTestSupport {
s.update(data);
byte[] signed = s.sign();
- s = SecurityUtils.getSignature(EdDSANamedCurveTable.CURVE_ED25519_SHA512);
+ s = SecurityUtils.getSignature(EdDSAEngine.SIGNATURE_ALGORITHM);
s.initVerify(keyPair.getPublic());
s.update(data);
assertTrue("Failed to verify", s.verify(signed));
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/d3e55205/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/d3e55205/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;