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/12/24 08:42:49 UTC
mina-sshd git commit: [SSHD-773] Add support for ed25519 Putty key
file
Repository: mina-sshd
Updated Branches:
refs/heads/master 539893ca6 -> 3d5a8e70f
[SSHD-773] Add support for ed25519 Putty key file
Project: http://git-wip-us.apache.org/repos/asf/mina-sshd/repo
Commit: http://git-wip-us.apache.org/repos/asf/mina-sshd/commit/3d5a8e70
Tree: http://git-wip-us.apache.org/repos/asf/mina-sshd/tree/3d5a8e70
Diff: http://git-wip-us.apache.org/repos/asf/mina-sshd/diff/3d5a8e70
Branch: refs/heads/master
Commit: 3d5a8e70ffd2dc6c37695428acf127d57dbaee66
Parents: 539893c
Author: Goldstein Lyor <ly...@c-b4.com>
Authored: Sun Dec 24 10:42:22 2017 +0200
Committer: Goldstein Lyor <ly...@c-b4.com>
Committed: Sun Dec 24 10:42:37 2017 +0200
----------------------------------------------------------------------
sshd-contrib/pom.xml | 6 ++
.../keys/loader/putty/ECDSAPuttyKeyDecoder.java | 10 +--
.../keys/loader/putty/EdDSAPuttyKeyDecoder.java | 68 ++++++++++++++++++++
.../config/keys/loader/putty/PuttyKeyUtils.java | 25 +++++--
.../keys/loader/putty/PuttyKeyUtilsTest.java | 15 ++++-
.../PuttyKeyUtilsTest-ssh-ed25519-KeyPair.ppk | 9 +++
...ssphrase-AES-256-CBC-ssh-ed25519-KeyPair.ppk | 9 +++
.../OpenSSHKeyPairResourceParserTest.java | 2 +-
.../common/keyprovider/KeyPairProviderTest.java | 6 +-
.../sshd/common/util/SecurityUtilsTest.java | 1 -
10 files changed, 134 insertions(+), 17 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/3d5a8e70/sshd-contrib/pom.xml
----------------------------------------------------------------------
diff --git a/sshd-contrib/pom.xml b/sshd-contrib/pom.xml
index 718dd7e..ac5660a 100644
--- a/sshd-contrib/pom.xml
+++ b/sshd-contrib/pom.xml
@@ -51,6 +51,12 @@
<artifactId>sshd-core</artifactId>
<version>${project.version}</version>
</dependency>
+ <!-- For ed25519 support -->
+ <dependency>
+ <groupId>net.i2p.crypto</groupId>
+ <artifactId>eddsa</artifactId>
+ <optional>true</optional>
+ </dependency>
<dependency>
<groupId>org.apache.sshd</groupId>
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/3d5a8e70/sshd-contrib/src/main/java/org/apache/sshd/common/config/keys/loader/putty/ECDSAPuttyKeyDecoder.java
----------------------------------------------------------------------
diff --git a/sshd-contrib/src/main/java/org/apache/sshd/common/config/keys/loader/putty/ECDSAPuttyKeyDecoder.java b/sshd-contrib/src/main/java/org/apache/sshd/common/config/keys/loader/putty/ECDSAPuttyKeyDecoder.java
index 03bfa6c..a257ff8 100644
--- a/sshd-contrib/src/main/java/org/apache/sshd/common/config/keys/loader/putty/ECDSAPuttyKeyDecoder.java
+++ b/sshd-contrib/src/main/java/org/apache/sshd/common/config/keys/loader/putty/ECDSAPuttyKeyDecoder.java
@@ -23,7 +23,7 @@ import java.math.BigInteger;
import java.security.GeneralSecurityException;
import java.security.KeyFactory;
import java.security.KeyPair;
-import java.security.NoSuchProviderException;
+import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.interfaces.ECPrivateKey;
@@ -56,16 +56,16 @@ public class ECDSAPuttyKeyDecoder extends AbstractPuttyKeyDecoder<ECPublicKey, E
@Override
public Collection<KeyPair> loadKeyPairs(String resourceKey, PuttyKeyReader pubReader, PuttyKeyReader prvReader)
throws IOException, GeneralSecurityException {
+ if (!SecurityUtils.isECCSupported()) {
+ throw new NoSuchAlgorithmException("ECC not supported for " + resourceKey);
+ }
+
String keyType = pubReader.readString();
ECCurves curve = ECCurves.fromKeyType(keyType);
if (curve == null) {
throw new InvalidKeySpecException("Not an EC curve name: " + keyType);
}
- if (!SecurityUtils.isECCSupported()) {
- throw new NoSuchProviderException("ECC not supported");
- }
-
String encCurveName = pubReader.readString();
String keyCurveName = curve.getName();
if (!keyCurveName.equals(encCurveName)) {
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/3d5a8e70/sshd-contrib/src/main/java/org/apache/sshd/common/config/keys/loader/putty/EdDSAPuttyKeyDecoder.java
----------------------------------------------------------------------
diff --git a/sshd-contrib/src/main/java/org/apache/sshd/common/config/keys/loader/putty/EdDSAPuttyKeyDecoder.java b/sshd-contrib/src/main/java/org/apache/sshd/common/config/keys/loader/putty/EdDSAPuttyKeyDecoder.java
new file mode 100644
index 0000000..bd2662c
--- /dev/null
+++ b/sshd-contrib/src/main/java/org/apache/sshd/common/config/keys/loader/putty/EdDSAPuttyKeyDecoder.java
@@ -0,0 +1,68 @@
+/*
+ * 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.config.keys.loader.putty;
+
+import java.io.IOException;
+import java.security.GeneralSecurityException;
+import java.security.KeyPair;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.spec.InvalidKeySpecException;
+import java.util.Collection;
+import java.util.Collections;
+
+import net.i2p.crypto.eddsa.EdDSAPrivateKey;
+import net.i2p.crypto.eddsa.EdDSAPublicKey;
+
+import org.apache.sshd.common.keyprovider.KeyPairProvider;
+import org.apache.sshd.common.util.security.SecurityUtils;
+import org.apache.sshd.common.util.security.eddsa.EdDSASecurityProviderUtils;
+
+/**
+ * TODO Add javadoc
+ *
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
+ */
+public class EdDSAPuttyKeyDecoder extends AbstractPuttyKeyDecoder<EdDSAPublicKey, EdDSAPrivateKey> {
+ public static final EdDSAPuttyKeyDecoder INSTANCE = new EdDSAPuttyKeyDecoder();
+
+ public EdDSAPuttyKeyDecoder() {
+ super(EdDSAPublicKey.class, EdDSAPrivateKey.class, Collections.singletonList(KeyPairProvider.SSH_ED25519));
+ }
+
+ @Override
+ public Collection<KeyPair> loadKeyPairs(String resourceKey, PuttyKeyReader pubReader, PuttyKeyReader prvReader)
+ throws IOException, GeneralSecurityException {
+ if (!SecurityUtils.isEDDSACurveSupported()) {
+ throw new NoSuchAlgorithmException(SecurityUtils.EDDSA + " provider not supported for " + resourceKey);
+ }
+
+ String keyType = pubReader.readString();
+ if (!KeyPairProvider.SSH_ED25519.equals(keyType)) {
+ throw new InvalidKeySpecException("Not an " + SecurityUtils.EDDSA + " key: " + keyType);
+ }
+
+ byte[] seed = pubReader.read();
+ PublicKey pubKey = EdDSASecurityProviderUtils.generateEDDSAPublicKey(seed);
+ seed = prvReader.read();
+ PrivateKey prvKey = EdDSASecurityProviderUtils.generateEDDSAPrivateKey(seed);
+ return Collections.singletonList(new KeyPair(pubKey, prvKey));
+ }
+}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/3d5a8e70/sshd-contrib/src/main/java/org/apache/sshd/common/config/keys/loader/putty/PuttyKeyUtils.java
----------------------------------------------------------------------
diff --git a/sshd-contrib/src/main/java/org/apache/sshd/common/config/keys/loader/putty/PuttyKeyUtils.java b/sshd-contrib/src/main/java/org/apache/sshd/common/config/keys/loader/putty/PuttyKeyUtils.java
index a3b4745..ee2851b 100644
--- a/sshd-contrib/src/main/java/org/apache/sshd/common/config/keys/loader/putty/PuttyKeyUtils.java
+++ b/sshd-contrib/src/main/java/org/apache/sshd/common/config/keys/loader/putty/PuttyKeyUtils.java
@@ -19,7 +19,7 @@
package org.apache.sshd.common.config.keys.loader.putty;
-import java.util.Arrays;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
@@ -27,17 +27,30 @@ import java.util.NavigableMap;
import java.util.TreeMap;
import org.apache.sshd.common.config.keys.loader.KeyPairResourceParser;
+import org.apache.sshd.common.util.security.SecurityUtils;
/**
* @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
*/
public final class PuttyKeyUtils {
public static final List<PuttyKeyPairResourceParser<?, ?>> DEFAULT_PARSERS =
- Collections.unmodifiableList(
- Arrays.asList(
- RSAPuttyKeyDecoder.INSTANCE,
- DSSPuttyKeyDecoder.INSTANCE,
- ECDSAPuttyKeyDecoder.INSTANCE));
+ Collections.unmodifiableList(new ArrayList<PuttyKeyPairResourceParser<?, ?>>() {
+ // Not serializing it
+ private static final long serialVersionUID = 1L;
+
+ {
+ add(RSAPuttyKeyDecoder.INSTANCE);
+ add(DSSPuttyKeyDecoder.INSTANCE);
+
+ if (SecurityUtils.isECCSupported()) {
+ add(ECDSAPuttyKeyDecoder.INSTANCE);
+ }
+
+ if (SecurityUtils.isEDDSACurveSupported()) {
+ add(EdDSAPuttyKeyDecoder.INSTANCE);
+ }
+ }
+ });
public static final NavigableMap<String, PuttyKeyPairResourceParser<?, ?>> BY_KEY_TYPE =
Collections.unmodifiableNavigableMap(
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/3d5a8e70/sshd-contrib/src/test/java/org/apache/sshd/common/config/keys/loader/putty/PuttyKeyUtilsTest.java
----------------------------------------------------------------------
diff --git a/sshd-contrib/src/test/java/org/apache/sshd/common/config/keys/loader/putty/PuttyKeyUtilsTest.java b/sshd-contrib/src/test/java/org/apache/sshd/common/config/keys/loader/putty/PuttyKeyUtilsTest.java
index 5ab953a..3f3d385 100644
--- a/sshd-contrib/src/test/java/org/apache/sshd/common/config/keys/loader/putty/PuttyKeyUtilsTest.java
+++ b/sshd-contrib/src/test/java/org/apache/sshd/common/config/keys/loader/putty/PuttyKeyUtilsTest.java
@@ -30,6 +30,8 @@ import java.util.List;
import org.apache.sshd.common.cipher.BuiltinCiphers;
import org.apache.sshd.common.config.keys.KeyUtils;
+import org.apache.sshd.common.config.keys.PrivateKeyEntryDecoder;
+import org.apache.sshd.common.config.keys.loader.openssh.OpenSSHKeyPairResourceParser;
import org.apache.sshd.common.util.GenericUtils;
import org.apache.sshd.common.util.io.IoUtils;
import org.apache.sshd.util.test.BaseTestSupport;
@@ -123,7 +125,7 @@ public class PuttyKeyUtilsTest extends BaseTestSupport {
assertLoadedKeyPair(encryptedFile, keys.iterator().next());
}
- private void assertLoadedKeyPair(String prefix, KeyPair kp) {
+ private void assertLoadedKeyPair(String prefix, KeyPair kp) throws GeneralSecurityException {
assertNotNull(prefix + ": no key pair loaded", kp);
PublicKey pubKey = kp.getPublic();
@@ -133,5 +135,16 @@ public class PuttyKeyUtilsTest extends BaseTestSupport {
PrivateKey prvKey = kp.getPrivate();
assertNotNull(prefix + ": no private key loaded", prvKey);
assertEquals(prefix + ": mismatched private key type", keyType, KeyUtils.getKeyType(prvKey));
+
+ @SuppressWarnings("rawtypes")
+ PrivateKeyEntryDecoder decoder =
+ OpenSSHKeyPairResourceParser.getPrivateKeyEntryDecoder(prvKey);
+ assertNotNull("No private key decoder", decoder);
+
+ if (decoder.isPublicKeyRecoverySupported()) {
+ @SuppressWarnings("unchecked")
+ PublicKey recKey = decoder.recoverPublicKey(prvKey);
+ assertKeyEquals("Mismatched recovered public key", pubKey, recKey);
+ }
}
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/3d5a8e70/sshd-contrib/src/test/resources/org/apache/sshd/common/config/keys/loader/putty/PuttyKeyUtilsTest-ssh-ed25519-KeyPair.ppk
----------------------------------------------------------------------
diff --git a/sshd-contrib/src/test/resources/org/apache/sshd/common/config/keys/loader/putty/PuttyKeyUtilsTest-ssh-ed25519-KeyPair.ppk b/sshd-contrib/src/test/resources/org/apache/sshd/common/config/keys/loader/putty/PuttyKeyUtilsTest-ssh-ed25519-KeyPair.ppk
new file mode 100644
index 0000000..614ac69
--- /dev/null
+++ b/sshd-contrib/src/test/resources/org/apache/sshd/common/config/keys/loader/putty/PuttyKeyUtilsTest-ssh-ed25519-KeyPair.ppk
@@ -0,0 +1,9 @@
+PuTTY-User-Key-File-2: ssh-ed25519
+Encryption: none
+Comment: ed25519-key-20170917
+Public-Lines: 2
+AAAAC3NzaC1lZDI1NTE5AAAAIN7fuKSIM5TbAX/1I1Ts3tfyo5eEs7JpmKsegHs/
+9fIi
+Private-Lines: 1
+AAAAIADKJJPxsUp7JXLzm1zwk8UswW/lkiwPJ73CbqGvalgP
+Private-MAC: 28a22234152feaf1d9a6a10ca0ae3a51b5e6dd52
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/3d5a8e70/sshd-contrib/src/test/resources/org/apache/sshd/common/config/keys/loader/putty/super-secret-passphrase-AES-256-CBC-ssh-ed25519-KeyPair.ppk
----------------------------------------------------------------------
diff --git a/sshd-contrib/src/test/resources/org/apache/sshd/common/config/keys/loader/putty/super-secret-passphrase-AES-256-CBC-ssh-ed25519-KeyPair.ppk b/sshd-contrib/src/test/resources/org/apache/sshd/common/config/keys/loader/putty/super-secret-passphrase-AES-256-CBC-ssh-ed25519-KeyPair.ppk
new file mode 100644
index 0000000..668ef1e
--- /dev/null
+++ b/sshd-contrib/src/test/resources/org/apache/sshd/common/config/keys/loader/putty/super-secret-passphrase-AES-256-CBC-ssh-ed25519-KeyPair.ppk
@@ -0,0 +1,9 @@
+PuTTY-User-Key-File-2: ssh-ed25519
+Encryption: aes256-cbc
+Comment: ed25519-key-20170917
+Public-Lines: 2
+AAAAC3NzaC1lZDI1NTE5AAAAIN7fuKSIM5TbAX/1I1Ts3tfyo5eEs7JpmKsegHs/
+9fIi
+Private-Lines: 1
+0cPG5BR80jQcJmHKs6IjpHS3R4/CTnudnJB4BcjaqKlRk0l603GVMDzTxkaICCb8
+Private-MAC: 381cff136b2516331ff4511cf382533fc14f0aeb
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/3d5a8e70/sshd-core/src/test/java/org/apache/sshd/common/config/keys/loader/openssh/OpenSSHKeyPairResourceParserTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/common/config/keys/loader/openssh/OpenSSHKeyPairResourceParserTest.java b/sshd-core/src/test/java/org/apache/sshd/common/config/keys/loader/openssh/OpenSSHKeyPairResourceParserTest.java
index b18564a..c45f89d 100644
--- a/sshd-core/src/test/java/org/apache/sshd/common/config/keys/loader/openssh/OpenSSHKeyPairResourceParserTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/common/config/keys/loader/openssh/OpenSSHKeyPairResourceParserTest.java
@@ -92,7 +92,7 @@ public class OpenSSHKeyPairResourceParserTest extends BaseTestSupport {
PrivateKey prvKey = ValidateUtils.checkInstanceOf(kp.getPrivate(), prvType, "Mismatched private key type");
@SuppressWarnings("rawtypes")
PrivateKeyEntryDecoder decoder =
- OpenSSHKeyPairResourceParser.getPrivateKeyEntryDecoder(prvKey);
+ OpenSSHKeyPairResourceParser.getPrivateKeyEntryDecoder(prvKey);
assertNotNull("No private key decoder", decoder);
if (decoder.isPublicKeyRecoverySupported()) {
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/3d5a8e70/sshd-core/src/test/java/org/apache/sshd/common/keyprovider/KeyPairProviderTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/common/keyprovider/KeyPairProviderTest.java b/sshd-core/src/test/java/org/apache/sshd/common/keyprovider/KeyPairProviderTest.java
index 463045c..7e3775b 100644
--- a/sshd-core/src/test/java/org/apache/sshd/common/keyprovider/KeyPairProviderTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/common/keyprovider/KeyPairProviderTest.java
@@ -55,9 +55,9 @@ public class KeyPairProviderTest extends BaseTestSupport {
@Test
public void testMapToKeyPairProvider() {
- final PublicKey pubKey = Mockito.mock(PublicKey.class);
- final PrivateKey prvKey = Mockito.mock(PrivateKey.class);
- final String[] testKeys = {getCurrentTestName(), getClass().getSimpleName()};
+ PublicKey pubKey = Mockito.mock(PublicKey.class);
+ PrivateKey prvKey = Mockito.mock(PrivateKey.class);
+ String[] testKeys = {getCurrentTestName(), getClass().getSimpleName()};
Map<String, KeyPair> pairsMap = GenericUtils.toSortedMap(
Arrays.asList(testKeys),
Function.identity(),
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/3d5a8e70/sshd-core/src/test/java/org/apache/sshd/common/util/SecurityUtilsTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/common/util/SecurityUtilsTest.java b/sshd-core/src/test/java/org/apache/sshd/common/util/SecurityUtilsTest.java
index a3dec7a..8bd2129 100644
--- a/sshd-core/src/test/java/org/apache/sshd/common/util/SecurityUtilsTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/common/util/SecurityUtilsTest.java
@@ -160,7 +160,6 @@ public class SecurityUtilsTest extends BaseTestSupport {
Class<?> clazz = getClass();
Package pkg = clazz.getPackage();
KeyPair kpResource = testLoadPrivateKeyResource(pkg.getName().replace('.', '/') + "/" + name, pubType, prvType);
-
assertTrue(name + ": Mismatched key file vs. resource values", KeyUtils.compareKeyPairs(kpFile, kpResource));
return kpResource;
}