You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mina.apache.org by lg...@apache.org on 2018/11/18 04:55:07 UTC
[12/12] mina-sshd git commit: [SSHD-864] Replaced BC deprecated
PEMWriter with JCAPemWriter in BouncyCastleGeneratorHostKeyProvider
[SSHD-864] Replaced BC deprecated PEMWriter with JCAPemWriter in BouncyCastleGeneratorHostKeyProvider
Project: http://git-wip-us.apache.org/repos/asf/mina-sshd/repo
Commit: http://git-wip-us.apache.org/repos/asf/mina-sshd/commit/025df0e8
Tree: http://git-wip-us.apache.org/repos/asf/mina-sshd/tree/025df0e8
Diff: http://git-wip-us.apache.org/repos/asf/mina-sshd/diff/025df0e8
Branch: refs/heads/master
Commit: 025df0e85655c83d99a585a620479b2a44287cb2
Parents: 895f30f
Author: Lyor Goldstein <lg...@apache.org>
Authored: Thu Nov 15 16:18:51 2018 +0200
Committer: Lyor Goldstein <lg...@apache.org>
Committed: Sun Nov 18 06:54:48 2018 +0200
----------------------------------------------------------------------
.../BouncyCastleGeneratorHostKeyProvider.java | 28 +++-
.../AbstractGeneratorHostKeyProvider.java | 4 +-
...ouncyCastleGeneratorHostKeyProviderTest.java | 140 +++++++++++++++++++
3 files changed, 166 insertions(+), 6 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/025df0e8/sshd-common/src/main/java/org/apache/sshd/common/util/security/bouncycastle/BouncyCastleGeneratorHostKeyProvider.java
----------------------------------------------------------------------
diff --git a/sshd-common/src/main/java/org/apache/sshd/common/util/security/bouncycastle/BouncyCastleGeneratorHostKeyProvider.java b/sshd-common/src/main/java/org/apache/sshd/common/util/security/bouncycastle/BouncyCastleGeneratorHostKeyProvider.java
index 534b033..cee48bd 100644
--- a/sshd-common/src/main/java/org/apache/sshd/common/util/security/bouncycastle/BouncyCastleGeneratorHostKeyProvider.java
+++ b/sshd-common/src/main/java/org/apache/sshd/common/util/security/bouncycastle/BouncyCastleGeneratorHostKeyProvider.java
@@ -22,12 +22,16 @@ import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.OpenOption;
import java.nio.file.Path;
import java.security.GeneralSecurityException;
import java.security.KeyPair;
import org.apache.sshd.common.NamedResource;
+import org.apache.sshd.common.util.io.IoUtils;
import org.apache.sshd.server.keyprovider.AbstractGeneratorHostKeyProvider;
+import org.bouncycastle.openssl.jcajce.JcaPEMWriter;
/**
* @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
@@ -37,11 +41,27 @@ public class BouncyCastleGeneratorHostKeyProvider extends AbstractGeneratorHostK
setPath(path);
}
- @SuppressWarnings("deprecation")
@Override
- protected void doWriteKeyPair(NamedResource resourceKey, KeyPair kp, OutputStream outputStream) throws IOException, GeneralSecurityException {
- try (org.bouncycastle.openssl.PEMWriter w =
- new org.bouncycastle.openssl.PEMWriter(new OutputStreamWriter(outputStream, StandardCharsets.UTF_8))) {
+ protected void doWriteKeyPair(NamedResource resourceKey, KeyPair kp, OutputStream outputStream)
+ throws IOException, GeneralSecurityException {
+ writePEMKeyPair(kp, outputStream);
+ }
+
+ public static void writePEMKeyPair(KeyPair kp, Path targetPath) throws IOException {
+ writePEMKeyPair(kp, targetPath, IoUtils.EMPTY_OPEN_OPTIONS);
+ }
+
+ public static void writePEMKeyPair(
+ KeyPair kp, Path targetPath, OpenOption... options)
+ throws IOException {
+ try (OutputStream os = Files.newOutputStream(targetPath, options)) {
+ writePEMKeyPair(kp, os);
+ }
+ }
+
+ public static void writePEMKeyPair(KeyPair kp, OutputStream outputStream) throws IOException {
+ try (JcaPEMWriter w = new JcaPEMWriter(
+ new OutputStreamWriter(outputStream, StandardCharsets.UTF_8))) {
w.writeObject(kp);
w.flush();
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/025df0e8/sshd-common/src/main/java/org/apache/sshd/server/keyprovider/AbstractGeneratorHostKeyProvider.java
----------------------------------------------------------------------
diff --git a/sshd-common/src/main/java/org/apache/sshd/server/keyprovider/AbstractGeneratorHostKeyProvider.java b/sshd-common/src/main/java/org/apache/sshd/server/keyprovider/AbstractGeneratorHostKeyProvider.java
index be4ceb5..287abec 100644
--- a/sshd-common/src/main/java/org/apache/sshd/server/keyprovider/AbstractGeneratorHostKeyProvider.java
+++ b/sshd-common/src/main/java/org/apache/sshd/server/keyprovider/AbstractGeneratorHostKeyProvider.java
@@ -118,7 +118,7 @@ public abstract class AbstractGeneratorHostKeyProvider extends AbstractKeyPairPr
if ((kp != null) & log.isDebugEnabled()) {
PublicKey key = kp.getPublic();
log.debug("clearLoadedKeys({}) removed key={}-{}",
- getPath(), KeyUtils.getKeyType(key), KeyUtils.getFingerPrint(key));
+ getPath(), KeyUtils.getKeyType(key), KeyUtils.getFingerPrint(key));
}
}
@@ -162,7 +162,7 @@ public abstract class AbstractGeneratorHostKeyProvider extends AbstractKeyPairPr
}
} catch (Throwable e) {
log.warn("resolveKeyPair({}) Failed ({}) to load: {}",
- keyPath, e.getClass().getSimpleName(), e.getMessage());
+ keyPath, e.getClass().getSimpleName(), e.getMessage());
if (log.isDebugEnabled()) {
log.debug("resolveKeyPair(" + keyPath + ") load failure details", e);
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/025df0e8/sshd-common/src/test/java/org/apache/sshd/common/util/security/bouncycastle/BouncyCastleGeneratorHostKeyProviderTest.java
----------------------------------------------------------------------
diff --git a/sshd-common/src/test/java/org/apache/sshd/common/util/security/bouncycastle/BouncyCastleGeneratorHostKeyProviderTest.java b/sshd-common/src/test/java/org/apache/sshd/common/util/security/bouncycastle/BouncyCastleGeneratorHostKeyProviderTest.java
new file mode 100644
index 0000000..3bca2e2
--- /dev/null
+++ b/sshd-common/src/test/java/org/apache/sshd/common/util/security/bouncycastle/BouncyCastleGeneratorHostKeyProviderTest.java
@@ -0,0 +1,140 @@
+/*
+ * 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.bouncycastle;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.security.GeneralSecurityException;
+import java.security.InvalidKeyException;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.PublicKey;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.sshd.common.cipher.ECCurves;
+import org.apache.sshd.common.config.keys.BuiltinIdentities;
+import org.apache.sshd.common.config.keys.KeyUtils;
+import org.apache.sshd.common.keyprovider.KeyPairProvider;
+import org.apache.sshd.common.util.security.SecurityUtils;
+import org.apache.sshd.server.keyprovider.AbstractGeneratorHostKeyProvider;
+import org.apache.sshd.util.test.JUnit4ClassRunnerWithParametersFactory;
+import org.apache.sshd.util.test.JUnitTestSupport;
+import org.apache.sshd.util.test.NoIoTestCase;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.runner.RunWith;
+import org.junit.runners.MethodSorters;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+import org.junit.runners.Parameterized.UseParametersRunnerFactory;
+
+/**
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
+ */
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+@RunWith(Parameterized.class) // see https://github.com/junit-team/junit/wiki/Parameterized-tests
+@UseParametersRunnerFactory(JUnit4ClassRunnerWithParametersFactory.class)
+@Category({ NoIoTestCase.class })
+public class BouncyCastleGeneratorHostKeyProviderTest extends JUnitTestSupport {
+ private final String keyType;
+ private final int keySize;
+
+ public BouncyCastleGeneratorHostKeyProviderTest(String keyType, int keySize) {
+ this.keyType = keyType;
+ this.keySize = keySize;
+ }
+
+ @Parameters(name = "{0} / {1}")
+ public static List<Object[]> parameters() {
+ if (!SecurityUtils.isBouncyCastleRegistered()) {
+ return Collections.emptyList();
+ }
+
+ List<Object[]> params = new ArrayList<>();
+ for (Integer ks : RSA_SIZES) {
+ params.add(new Object[]{BuiltinIdentities.Constants.RSA, ks});
+ }
+ for (Integer ks : DSS_SIZES) {
+ params.add(new Object[]{BuiltinIdentities.Constants.DSA, ks});
+ }
+
+/* TODO - causes an issue where BC cannot parse its own file
+ if (SecurityUtils.isECCSupported()) {
+ for (ECCurves curve : ECCurves.VALUES) {
+ params.add(new Object[]{BuiltinIdentities.Constants.ECDSA, curve.getKeySize()});
+ }
+ }
+*/
+ return params;
+ }
+
+ @Test
+ public void testKeyReadWrite() throws IOException, GeneralSecurityException {
+ KeyPair expected;
+ if (BuiltinIdentities.Constants.RSA.equalsIgnoreCase(keyType)) {
+ expected = KeyUtils.generateKeyPair(KeyPairProvider.SSH_RSA, keySize);
+ } else if (BuiltinIdentities.Constants.DSA.equalsIgnoreCase(keyType)) {
+ expected = KeyUtils.generateKeyPair(KeyPairProvider.SSH_DSS, keySize);
+ } else if (BuiltinIdentities.Constants.ECDSA.equalsIgnoreCase(keyType)) {
+ ECCurves curve = ECCurves.fromCurveSize(keySize);
+ assertNotNull("No curve for key size=" + keySize, curve);
+ expected = KeyUtils.generateKeyPair(curve.getKeyType(), curve.getKeySize());
+ } else if (BuiltinIdentities.Constants.ED25519.equalsIgnoreCase(keyType)) {
+ KeyPairGenerator g = SecurityUtils.getKeyPairGenerator(SecurityUtils.EDDSA);
+ expected = g.generateKeyPair();
+ } else {
+ throw new InvalidKeyException("Unsupported key type: " + keyType);
+ }
+
+ PublicKey key = expected.getPublic();
+ String keyAlgorithm = key.getAlgorithm();
+ if (BuiltinIdentities.Constants.ECDSA.equalsIgnoreCase(keyAlgorithm)) {
+ keyAlgorithm = KeyUtils.EC_ALGORITHM;
+ } else if (BuiltinIdentities.Constants.ED25519.equalsIgnoreCase(keyAlgorithm)) {
+ keyAlgorithm = SecurityUtils.EDDSA;
+ }
+
+ Path dir = getTempTargetFolder();
+ dir = Files.createDirectories(dir.resolve(getClass().getSimpleName()));
+ Path file = dir.resolve(keyType + "-" + keySize + ".pem");
+ BouncyCastleGeneratorHostKeyProvider.writePEMKeyPair(expected, file);
+
+ AbstractGeneratorHostKeyProvider provider = new BouncyCastleGeneratorHostKeyProvider(file);
+ provider.setAlgorithm(keyAlgorithm);
+
+ Iterable<KeyPair> keys = provider.loadKeys(null);
+ KeyPair actual = null;
+ for (KeyPair k : keys) {
+ assertNull("Unexpected multiple keys loaded", actual);
+ actual = k;
+ }
+
+ assertKeyPairEquals(keyType + "/" + keySize, expected, actual);
+ }
+
+ @Override
+ public String toString() {
+ return getClass().getSimpleName() + "[" + keyType + "/" + keySize + "]";
+ }
+}