You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by co...@apache.org on 2019/07/05 08:45:47 UTC
[camel] branch master updated: CAMEL-13726 - Add support for PKCS8
keys and encrypted PKCS8 keys
This is an automated email from the ASF dual-hosted git repository.
coheigea pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/master by this push:
new d09b13c CAMEL-13726 - Add support for PKCS8 keys and encrypted PKCS8 keys
d09b13c is described below
commit d09b13cb9205a058a1974a172ac904a0f14a6de0
Author: Colm O hEigeartaigh <co...@apache.org>
AuthorDate: Fri Jul 5 09:44:54 2019 +0100
CAMEL-13726 - Add support for PKCS8 keys and encrypted PKCS8 keys
---
.../camel-ssh/src/main/docs/ssh-component.adoc | 10 ++--
.../ssh/ResourceHelperKeyPairProvider.java | 59 ++++++++++++++++++++--
.../apache/camel/component/ssh/SshComponent.java | 23 +++++++--
.../camel/component/ssh/SshConfiguration.java | 16 ++++++
.../apache/camel/component/ssh/SshEndpoint.java | 14 +++--
.../org/apache/camel/component/ssh/SshHelper.java | 8 ++-
.../component/ssh/SshComponentSecurityTest.java | 56 +++++++++++++++++++-
.../camel-ssh/src/test/resources/ecpkcs8.pem | 8 +++
components/camel-ssh/src/test/resources/encrsa.pem | 30 +++++++++++
components/camel-ssh/src/test/resources/rsa.pem | 28 ++++++++++
.../endpoint/dsl/SshEndpointBuilderFactory.java | 33 ++++++++++++
.../ssh/springboot/SshComponentConfiguration.java | 26 ++++++++++
12 files changed, 294 insertions(+), 17 deletions(-)
diff --git a/components/camel-ssh/src/main/docs/ssh-component.adoc b/components/camel-ssh/src/main/docs/ssh-component.adoc
index 3b961f8..4df54df 100644
--- a/components/camel-ssh/src/main/docs/ssh-component.adoc
+++ b/components/camel-ssh/src/main/docs/ssh-component.adoc
@@ -31,7 +31,7 @@ ssh:[username[:password]@]host[:port][?options]
// component options: START
-The SSH component supports 15 options, which are listed below.
+The SSH component supports 16 options, which are listed below.
@@ -48,6 +48,7 @@ The SSH component supports 15 options, which are listed below.
| *keyType* (security) | Sets the key type to pass to the KeyPairProvider as part of authentication. KeyPairProvider.loadKey(...) will be passed this value. Defaults to ssh-rsa. | | String
| *timeout* (common) | Sets the timeout in milliseconds to wait in establishing the remote SSH server connection. Defaults to 30000 milliseconds. | | long
| *certResource* (security) | Sets the resource path of the certificate to use for Authentication. Will use ResourceHelperKeyPairProvider to resolve file based certificate, and depends on keyType setting. | | String
+| *certResourcePassword* (security) | Sets the password to use in loading certResource, if certResource is an encrypted key. | | String
| *channelType* (advanced) | Sets the channel type to pass to the Channel as part of command execution. Defaults to exec. | | String
| *shellPrompt* (advanced) | Sets the shellPrompt to be dropped when response is read after command execution | | String
| *sleepForShellPrompt* (advanced) | Sets the sleep period in milliseconds to wait reading response from shell prompt. Defaults to 100 milliseconds. | | long
@@ -79,7 +80,7 @@ with the following path and query parameters:
|===
-==== Query Parameters (33 parameters):
+==== Query Parameters (34 parameters):
[width="100%",cols="2,5,^1,2",options="header"]
@@ -114,6 +115,7 @@ with the following path and query parameters:
| *timeUnit* (scheduler) | Time unit for initialDelay and delay options. | MILLISECONDS | TimeUnit
| *useFixedDelay* (scheduler) | Controls if fixed delay or fixed rate is used. See ScheduledExecutorService in JDK for details. | true | boolean
| *certResource* (security) | Sets the resource path of the certificate to use for Authentication. Will use ResourceHelperKeyPairProvider to resolve file based certificate, and depends on keyType setting. | | String
+| *certResourcePassword* (security) | Sets the password to use in loading certResource, if certResource is an encrypted key. | | String
| *keyPairProvider* (security) | Sets the KeyPairProvider reference to use when connecting using Certificates to the remote SSH Server. | | KeyPairProvider
| *keyType* (security) | Sets the key type to pass to the KeyPairProvider as part of authentication. KeyPairProvider.loadKey(...) will be passed this value. From Camel 3.0.0 / 2.25.0, by default Camel will select the first available KeyPair that is loaded. Prior to this, a KeyType of 'ssh-rsa' was enforced by default. | | String
| *password* (security) | Sets the password to use in connecting to remote SSH server. Requires keyPairProvider to be set to null. | | String
@@ -136,7 +138,7 @@ When using Spring Boot make sure to use the following Maven dependency to have s
----
-The component supports 30 options, which are listed below.
+The component supports 32 options, which are listed below.
@@ -145,8 +147,10 @@ The component supports 30 options, which are listed below.
| Name | Description | Default | Type
| *camel.component.ssh.basic-property-binding* | Whether the component should use basic property binding (Camel 2.x) or the newer property binding with additional capabilities | false | Boolean
| *camel.component.ssh.cert-resource* | Sets the resource path of the certificate to use for Authentication. Will use ResourceHelperKeyPairProvider to resolve file based certificate, and depends on keyType setting. | | String
+| *camel.component.ssh.cert-resource-password* | Sets the password to use in loading certResource, if certResource is an encrypted key. | | String
| *camel.component.ssh.channel-type* | Sets the channel type to pass to the Channel as part of command execution. Defaults to exec. | | String
| *camel.component.ssh.configuration.cert-resource* | Sets the resource path of the certificate to use for Authentication. Will use {@link ResourceHelperKeyPairProvider} to resolve file based certificate, and depends on keyType setting. | | String
+| *camel.component.ssh.configuration.cert-resource-password* | Sets the password to use in loading certResource, if certResource is an encrypted key. | | String
| *camel.component.ssh.configuration.channel-type* | Sets the channel type to pass to the Channel as part of command execution. Defaults to "exec". | exec | String
| *camel.component.ssh.configuration.fail-on-unknown-host* | Specifies whether a connection to an unknown host should fail or not. This value is only checked when the property knownHosts is set. | false | Boolean
| *camel.component.ssh.configuration.host* | Sets the hostname of the remote SSH server. | | String
diff --git a/components/camel-ssh/src/main/java/org/apache/camel/component/ssh/ResourceHelperKeyPairProvider.java b/components/camel-ssh/src/main/java/org/apache/camel/component/ssh/ResourceHelperKeyPairProvider.java
index 9436cbe..a0763ed 100644
--- a/components/camel-ssh/src/main/java/org/apache/camel/component/ssh/ResourceHelperKeyPairProvider.java
+++ b/components/camel-ssh/src/main/java/org/apache/camel/component/ssh/ResourceHelperKeyPairProvider.java
@@ -18,7 +18,16 @@ package org.apache.camel.component.ssh;
import java.io.InputStream;
import java.io.InputStreamReader;
+import java.security.KeyFactory;
import java.security.KeyPair;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.interfaces.ECPrivateKey;
+import java.security.interfaces.RSAPrivateCrtKey;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.KeySpec;
+import java.security.spec.RSAPublicKeySpec;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Supplier;
@@ -28,12 +37,20 @@ import org.apache.camel.support.ResourceHelper;
import org.apache.sshd.common.keyprovider.AbstractKeyPairProvider;
import org.apache.sshd.common.util.io.IoUtils;
import org.apache.sshd.common.util.security.SecurityUtils;
+import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
+import org.bouncycastle.jcajce.provider.asymmetric.util.EC5Util;
+import org.bouncycastle.jce.spec.ECParameterSpec;
+import org.bouncycastle.jce.spec.ECPublicKeySpec;
+import org.bouncycastle.math.ec.ECPoint;
import org.bouncycastle.openssl.PEMDecryptorProvider;
import org.bouncycastle.openssl.PEMEncryptedKeyPair;
import org.bouncycastle.openssl.PEMKeyPair;
import org.bouncycastle.openssl.PEMParser;
import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;
+import org.bouncycastle.openssl.jcajce.JceOpenSSLPKCS8DecryptorProviderBuilder;
import org.bouncycastle.openssl.jcajce.JcePEMDecryptorProviderBuilder;
+import org.bouncycastle.operator.InputDecryptorProvider;
+import org.bouncycastle.pkcs.PKCS8EncryptedPrivateKeyInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -112,22 +129,33 @@ public class ResourceHelperKeyPairProvider extends AbstractKeyPairProvider {
r = new PEMParser(isr);
Object o = r.readObject();
-
+
JcaPEMKeyConverter pemConverter = new JcaPEMKeyConverter();
pemConverter.setProvider("BC");
if (passwordFinder != null && o instanceof PEMEncryptedKeyPair) {
JcePEMDecryptorProviderBuilder decryptorBuilder = new JcePEMDecryptorProviderBuilder();
PEMDecryptorProvider pemDecryptor = decryptorBuilder.build(passwordFinder.get());
o = pemConverter.getKeyPair(((PEMEncryptedKeyPair) o).decryptKeyPair(pemDecryptor));
+ } else if (passwordFinder != null && o instanceof PKCS8EncryptedPrivateKeyInfo) {
+ JceOpenSSLPKCS8DecryptorProviderBuilder jce = new JceOpenSSLPKCS8DecryptorProviderBuilder();
+ jce.setProvider("BC");
+ InputDecryptorProvider decProv = jce.build(passwordFinder.get());
+ o = ((PKCS8EncryptedPrivateKeyInfo)o).decryptPrivateKeyInfo(decProv);
}
-
+
if (o instanceof PEMKeyPair) {
o = pemConverter.getKeyPair((PEMKeyPair)o);
keys.add((KeyPair) o);
} else if (o instanceof KeyPair) {
keys.add((KeyPair) o);
+ } else if (o instanceof PrivateKeyInfo) {
+ PrivateKey privateKey = pemConverter.getPrivateKey((PrivateKeyInfo)o);
+ PublicKey publicKey = convertPrivateToPublicKey(privateKey);
+ if (publicKey != null) {
+ keys.add(new KeyPair(publicKey, privateKey));
+ }
}
-
+
} catch (Exception e) {
log.warn("Unable to read key", e);
} finally {
@@ -137,5 +165,28 @@ public class ResourceHelperKeyPairProvider extends AbstractKeyPairProvider {
return keys;
}
-
+
+ private PublicKey convertPrivateToPublicKey(PrivateKey privateKey) throws NoSuchAlgorithmException, InvalidKeySpecException {
+ if (privateKey instanceof RSAPrivateCrtKey) {
+ KeySpec keySpec = new RSAPublicKeySpec(((RSAPrivateCrtKey)privateKey).getModulus(),
+ ((RSAPrivateCrtKey)privateKey).getPublicExponent());
+ KeyFactory keyFactory = KeyFactory.getInstance("RSA");
+ return keyFactory.generatePublic(keySpec);
+ } else if (privateKey instanceof ECPrivateKey) {
+ ECPrivateKey ecPrivateKey = (ECPrivateKey)privateKey;
+
+ // Derive the public point by multiplying the generator by the private value
+ ECParameterSpec paramSpec = EC5Util.convertSpec(ecPrivateKey.getParams(), false);
+ ECPoint q = paramSpec.getG().multiply(ecPrivateKey.getS());
+
+ KeySpec keySpec = new ECPublicKeySpec(q, paramSpec);
+
+ KeyFactory keyFactory = KeyFactory.getInstance("EC");
+ return keyFactory.generatePublic(keySpec);
+ } else {
+ log.warn("Unable to convert private key to public key. Only RSA + ECDSA supported");
+ return null;
+ }
+ }
+
}
diff --git a/components/camel-ssh/src/main/java/org/apache/camel/component/ssh/SshComponent.java b/components/camel-ssh/src/main/java/org/apache/camel/component/ssh/SshComponent.java
index 5cc5972..35e267b 100644
--- a/components/camel-ssh/src/main/java/org/apache/camel/component/ssh/SshComponent.java
+++ b/components/camel-ssh/src/main/java/org/apache/camel/component/ssh/SshComponent.java
@@ -190,7 +190,22 @@ public class SshComponent extends DefaultComponent {
public void setCertResource(String certResource) {
getConfiguration().setCertResource(certResource);
}
-
+
+ public String getCertResourcePassword() {
+ return getConfiguration().getCertResourcePassword();
+ }
+
+ /**
+ * Sets the password to use in loading certResource, if certResource is an encrypted key.
+ *
+ * @param certResourcePassword
+ * String representing password use to load the certResource key
+ */
+ @Metadata(label = "security", secret = true)
+ public void setCertResourcePassword(String certResourcePassword) {
+ getConfiguration().setCertResourcePassword(certResourcePassword);
+ }
+
/**
* Sets the channel type to pass to the Channel as part of command execution.
* Defaults to "exec".
@@ -204,19 +219,19 @@ public class SshComponent extends DefaultComponent {
public void setChannelType(String channelType) {
getConfiguration().setChannelType(channelType);
}
-
+
/**
* Sets the shellPrompt to be dropped when response is read after command execution
*
* @param shellPrompt
- * String defining ending string of command line which has to be dropped when response is
+ * String defining ending string of command line which has to be dropped when response is
* read after command execution.
*/
@Metadata(label = "advanced")
public void setShellPrompt(String shellPrompt) {
getConfiguration().setShellPrompt(shellPrompt);
}
-
+
/**
* Sets the sleep period in milliseconds to wait reading response from shell prompt.
* Defaults to 100 milliseconds.
diff --git a/components/camel-ssh/src/main/java/org/apache/camel/component/ssh/SshConfiguration.java b/components/camel-ssh/src/main/java/org/apache/camel/component/ssh/SshConfiguration.java
index 9899a2d6..417b755 100644
--- a/components/camel-ssh/src/main/java/org/apache/camel/component/ssh/SshConfiguration.java
+++ b/components/camel-ssh/src/main/java/org/apache/camel/component/ssh/SshConfiguration.java
@@ -48,6 +48,8 @@ public class SshConfiguration implements Cloneable {
private String keyType;
@UriParam(label = "security")
private String certResource;
+ @UriParam(label = "security", secret = true)
+ private String certResourcePassword;
@UriParam(defaultValue = "30000")
private long timeout = 30000;
@UriParam()
@@ -263,6 +265,20 @@ public class SshConfiguration implements Cloneable {
this.certResource = certResource;
}
+ public String getCertResourcePassword() {
+ return certResourcePassword;
+ }
+
+ /**
+ * Sets the password to use in loading certResource, if certResource is an encrypted key.
+ *
+ * @param certResourcePassword
+ * String representing password use to load the certResource key
+ */
+ public void setCertResourcePassword(String certResourcePassword) {
+ this.certResourcePassword = certResourcePassword;
+ }
+
public String getKnownHostsResource() {
return knownHostsResource;
}
diff --git a/components/camel-ssh/src/main/java/org/apache/camel/component/ssh/SshEndpoint.java b/components/camel-ssh/src/main/java/org/apache/camel/component/ssh/SshEndpoint.java
index 71ced79..041226e 100644
--- a/components/camel-ssh/src/main/java/org/apache/camel/component/ssh/SshEndpoint.java
+++ b/components/camel-ssh/src/main/java/org/apache/camel/component/ssh/SshEndpoint.java
@@ -163,6 +163,14 @@ public class SshEndpoint extends ScheduledPollEndpoint {
getConfiguration().setCertResource(certResource);
}
+ public String getCertResourcePassword() {
+ return getConfiguration().getCertResourcePassword();
+ }
+
+ public void setCertResourcePassword(String certResourcePassword) {
+ getConfiguration().setCertResourcePassword(certResourcePassword);
+ }
+
public String getKnownHostsResource() {
return getConfiguration().getKnownHostsResource();
}
@@ -178,7 +186,7 @@ public class SshEndpoint extends ScheduledPollEndpoint {
public void setFailOnUnknownHost(boolean failOnUnknownHost) {
getConfiguration().setFailOnUnknownHost(failOnUnknownHost);
}
-
+
public String getChannelType() {
return getConfiguration().getChannelType();
}
@@ -186,7 +194,7 @@ public class SshEndpoint extends ScheduledPollEndpoint {
public void setChannelType(String channelType) {
getConfiguration().setChannelType(channelType);
}
-
+
public String getShellPrompt() {
return getConfiguration().getShellPrompt();
}
@@ -194,7 +202,7 @@ public class SshEndpoint extends ScheduledPollEndpoint {
public void setShellPrompt(String shellPrompt) {
getConfiguration().setShellPrompt(shellPrompt);
}
-
+
public long getSleepForShellPrompt() {
return getConfiguration().getSleepForShellPrompt();
}
diff --git a/components/camel-ssh/src/main/java/org/apache/camel/component/ssh/SshHelper.java b/components/camel-ssh/src/main/java/org/apache/camel/component/ssh/SshHelper.java
index d5ae2fe..92a5723 100644
--- a/components/camel-ssh/src/main/java/org/apache/camel/component/ssh/SshHelper.java
+++ b/components/camel-ssh/src/main/java/org/apache/camel/component/ssh/SshHelper.java
@@ -27,6 +27,7 @@ import java.util.Arrays;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
+import java.util.function.Supplier;
import org.apache.camel.RuntimeCamelException;
import org.apache.sshd.client.SshClient;
@@ -83,7 +84,12 @@ public final class SshHelper {
final String certResource = configuration.getCertResource();
if (certResource != null) {
LOG.debug("Attempting to authenticate using ResourceKey '{}'...", certResource);
- keyPairProvider = new ResourceHelperKeyPairProvider(new String[]{certResource}, endpoint.getCamelContext());
+ if (endpoint.getCertResourcePassword() != null) {
+ Supplier<char[]> passwordFinder = () -> endpoint.getCertResourcePassword().toCharArray();
+ keyPairProvider = new ResourceHelperKeyPairProvider(new String[]{certResource}, passwordFinder, endpoint.getCamelContext());
+ } else {
+ keyPairProvider = new ResourceHelperKeyPairProvider(new String[]{certResource}, endpoint.getCamelContext());
+ }
} else {
keyPairProvider = configuration.getKeyPairProvider();
}
diff --git a/components/camel-ssh/src/test/java/org/apache/camel/component/ssh/SshComponentSecurityTest.java b/components/camel-ssh/src/test/java/org/apache/camel/component/ssh/SshComponentSecurityTest.java
index d9ab553..c0607eb 100644
--- a/components/camel-ssh/src/test/java/org/apache/camel/component/ssh/SshComponentSecurityTest.java
+++ b/components/camel-ssh/src/test/java/org/apache/camel/component/ssh/SshComponentSecurityTest.java
@@ -53,6 +53,32 @@ public class SshComponentSecurityTest extends SshComponentTestSupport {
}
@Test
+ public void testRsaFilePKCS8() throws Exception {
+ final String msg = "test";
+
+ MockEndpoint mock = getMockEndpoint("mock:rsapkcs8");
+ mock.expectedMinimumMessageCount(1);
+ mock.expectedBodiesReceived(msg);
+
+ template.sendBody("direct:ssh-rsapkcs8", msg);
+
+ assertMockEndpointsSatisfied();
+ }
+
+ @Test
+ public void testEncryptedRsaFile() throws Exception {
+ final String msg = "test";
+
+ MockEndpoint mock = getMockEndpoint("mock:encrsaFile");
+ mock.expectedMinimumMessageCount(1);
+ mock.expectedBodiesReceived(msg);
+
+ template.sendBody("direct:ssh-encrsaFile", msg);
+
+ assertMockEndpointsSatisfied();
+ }
+
+ @Test
public void testECFile() throws Exception {
final String msg = "test";
@@ -65,6 +91,19 @@ public class SshComponentSecurityTest extends SshComponentTestSupport {
assertMockEndpointsSatisfied();
}
+ @Test
+ public void testECFilePKCS8() throws Exception {
+ final String msg = "test";
+
+ MockEndpoint mock = getMockEndpoint("mock:ecFilepkcs8");
+ mock.expectedMinimumMessageCount(1);
+ mock.expectedBodiesReceived(msg);
+
+ template.sendBody("direct:ssh-ecFilepkcs8", msg);
+
+ assertMockEndpointsSatisfied();
+ }
+
@Override
protected RouteBuilder createRouteBuilder() throws Exception {
return new RouteBuilder() {
@@ -91,9 +130,22 @@ public class SshComponentSecurityTest extends SshComponentTestSupport {
.to("ssh://smx@localhost:" + port + "?certResource=file:src/test/resources/hostkey.pem")
.to("mock:rsaFile");
+ from("direct:ssh-rsapkcs8")
+ .to("ssh://smx@localhost:" + port + "?certResource=file:src/test/resources/rsa.pem")
+ .to("mock:rsapkcs8");
+
+ from("direct:ssh-encrsaFile")
+ .to("ssh://smx@localhost:" + port + "?certResource=file:src/test/resources/encrsa.pem&certResourcePassword=security")
+ .to("mock:encrsaFile");
+
from("direct:ssh-ecFile")
- .to("ssh://smx@localhost:" + port + "?certResource=file:src/test/resources/ec.pem")
- .to("mock:ecFile");
+ .to("ssh://smx@localhost:" + port + "?certResource=file:src/test/resources/ec.pem")
+ .to("mock:ecFile");
+
+
+ from("direct:ssh-ecFilepkcs8")
+ .to("ssh://smx@localhost:" + port + "?certResource=file:src/test/resources/ecpkcs8.pem")
+ .to("mock:ecFilepkcs8");
}
};
}
diff --git a/components/camel-ssh/src/test/resources/ecpkcs8.pem b/components/camel-ssh/src/test/resources/ecpkcs8.pem
new file mode 100644
index 0000000..8b8d4b3
--- /dev/null
+++ b/components/camel-ssh/src/test/resources/ecpkcs8.pem
@@ -0,0 +1,8 @@
+-----BEGIN PRIVATE KEY-----
+MIHuAgEAMBAGByqGSM49AgEGBSuBBAAjBIHWMIHTAgEBBEIB5Twq2mxiOAieZslZ
+lOkOG1Pi4PEmAWJ78+bRLAV7Q4F5Nd4u0bAdzGIEMFARoeVb/2C8ZFjNhL8xgOUP
+WJqY316hgYkDgYYABADMulfTEOAzU9gsMEfrOuTJj9J8c4SNaAeeUb6uDHYfKPnY
+vfMJrBcGlnRePjJjeWpGHOykqB8NYpCFk/TPgYFGpQGpz51EZngsQwpEEQXw/jzB
+HZsVOdrTADYu09Cy/AMLu3wAnaQ5rWm41G3eC8mfZ1Q0BQ7Fc0K103mxlayEM605
+jw==
+-----END PRIVATE KEY-----
diff --git a/components/camel-ssh/src/test/resources/encrsa.pem b/components/camel-ssh/src/test/resources/encrsa.pem
new file mode 100644
index 0000000..f9d39df
--- /dev/null
+++ b/components/camel-ssh/src/test/resources/encrsa.pem
@@ -0,0 +1,30 @@
+-----BEGIN ENCRYPTED PRIVATE KEY-----
+MIIFLTBXBgkqhkiG9w0BBQ0wSjApBgkqhkiG9w0BBQwwHAQICsCP4wKZn6cCAggA
+MAwGCCqGSIb3DQIJBQAwHQYJYIZIAWUDBAEqBBAqBNa9ItIjNW16FFwcOqYRBIIE
+0Fd0cEbimhWmGaoC4zfJT1MyLUnqLrctscaE62NvBr5LL6ei6doShIViIWW0xNdG
+1/c8loSSraXmTaxUWLihQKwEwjV2NETEz/JNT0hkUNKmSk225Rrq0LBXGFiV3sd/
+uA9UGbn8GsD+pAj/pEC2Z9XfuSgUB8ZreO/N3eSfRyzryJqmhiJuskG6Q5JhkWur
+0B1YaDd2AszVrI7UnAJn/RjnlL2YzW9NO0NTaCHHS5syFwg7ocgwVCd3jkXyx9os
+x3Wvd3FF4DwbT5Au3LxlUbWCyyTaB2NAm5yqYa9D2eTajPoxnT9OLkG2tq+LVlYl
+OpDykHZIqOxUJ1+bTbmKSw9CTj7a/2L6TbmP3Z6OkXeDfNpelM8HzNVFvYTUbIuj
++IxJVNo4/GdI3j1LunPJLccAmA7RbLrxISDvoVE79L56c8dGd1DVzMyr33jnVqXi
+SP+1sgHKMeyL3iZpo69/F+brkz7/HgH7hlsqGP718TXwt+ZMy9+cftfdngDe+5FI
+spCnduZveHx4B98Nwlxl+TYlZO1sXNzmxck7g8fngjWgtKK/B1HEVhUUEiJaneUN
+AG4R/6bibpZDSorslPbWzGQAoMK2tEFYIxKRagBA1GiX9HsHU8rYx7+fNEHe5yJm
+BM/p1OLBTO9crvPhaRHNK4NWYd1kmKz9gJQtK7y16A1JO8gaI6XsZZdsitAEuFsR
+Ni4BjrTxb89TEoI7l9Hn6NQBfJBp4W5/IQ4UFtvX4T8hfAt/ELFH8QvJJdYkpf95
+XvJ69dKp4yptpWmyfp8D/t22cls28Bj8sxSXnuf45tN6EJcTqCM4YCFX2O2/upc/
+8GKWteYNGBo2G/9Y9fxiiWmi3mSsPGzbdjHTqDW0g38RqdMkTq1FTDojeMUiaRsF
+7wx/QwDq80hkTX4Jv+tVF1czCjfu3kfVxiOw3YQf2DpjNCAZX/QLYLQYOadpxp3m
+SdHpm4+L4uNLgtDNrXtMpMCJz8yuCeCz4diKCUT2GVKUNvDpz5sKKPIeJlEGJkAU
+llBpcCJcUk2VQCzz+PePNJgrGtbtGlXqkxfGESzctndoQsc3NAK5QHlvT/tfKrwA
+buPfg4gT/YAJiTD7tU4fiB/qyX4p+VKV6/FQZzXOx6H1U7mdqGjGUgUUpyGhDr2r
+oMVipIH8n8ndXe+8iYlqHyjjm9ROHO3etadAzaOxohG4wAF4s0T2aabR6cYftK9L
+XYmtjgoPh6tHgley3U4MNWX3Zew0t9vIPz4khoDokBbslEc9ePaqHGyqgpuQ4aZE
+jaQpyZ3hJOBy7+zoAAxCnMT0S2qH+MthKLp3I/OHTkSqFS1LsK8wdTBCAsTww0zJ
+nNfJ9LYVnsX6qfzfQxlkLlxJVxWjSorMvoiawunpftDvnTcoWk2zf6JSFq2ccgKA
++vxSyMyegDcHgYbhbOPVzCqcE/766upfkFVngaEyC8lI5D4eXc8IJIzMJb00kSmY
+n7jo6OZXOFwL2B6tKvwWaYXz8zgwCbTYv+RBtF3lb0aG1hSwQ0Pc0puZ9IV1FR0q
+7gT3g/uWBqUBGy4aaCUraf16K+DNHipmTSeYk5Z1fu27aTruY/Dlt7NwtsNxDtAO
+IzjSY69NAvmjtdjz237yeVXUFS0LJJ4dCrOxBA+oV2cD
+-----END ENCRYPTED PRIVATE KEY-----
diff --git a/components/camel-ssh/src/test/resources/rsa.pem b/components/camel-ssh/src/test/resources/rsa.pem
new file mode 100644
index 0000000..bfbaec8
--- /dev/null
+++ b/components/camel-ssh/src/test/resources/rsa.pem
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQC65ADW0lX/y6v0
+XK0zWoeE7WHI6odRl6vy+ocvjvFwSjjDsj8/fyHyq8hbeMAsR98SIEUh5gHjX2T+
+1RVE2AJ2+jV+5llY7tYG2He1kvMKra+fppWvVkbJ/wEqQ38eyN9G/KgET5p/izgb
+CycCKSe/VO/I6gLJSDB3kIKvX+sh0oynOg67A1OcFA0GOcM9p3mIbYjnz4QLAueT
+vkQdBPgojB+ooh1nZtb35naUTwXuKBCEeuc39P+HFeBSDuQoZQUqxXSbi2kq9vO6
+0qXQDb4hmLjJ32LrMeU+Kwe6c2TL76SxXZnsTPSnPA9+R+ChD0RElYLgqqIiUi2Y
+Q6lDyG77AgMBAAECggEBAIcapqSln3fws9lOWgNC0a89sC//o11PqQVZKPsveci0
+Tz7hj6mGbXMxzgCaVUptloxS+cccsIa/gpJaVirTgUyjaqLXQQXyepSuTjPcDIjO
+sKRYV+NOGpSSHTSBYNdPXWHC6m9bYJQNf7zFHikIuWwuqb1zthnubuMwe9juHVvv
+za7Qni/AbjLiazXvWtiqzUjo7k0TRlJq2UM/uKun2MCT5tRGTIj4v053U7MnxHlr
+05TJ7KDhxMzbSjkDWC/fQxSvPJiqfO241+rHRYl4/xGgN1mvk0SMU3Hpk/PzQZAu
+jw2/ztMIYV8NMe83GAIVdmZH0aDdUhHPYy8aED2UCfkCgYEA6mI6yJ17y3+llttD
+pZe9S3MvhQdJBRgRespT6vmatM+QjYZT49IG/VWhBwB91xP9qe4XwQpW7vUPAvTk
+mxX8QekY5JhCFQ29LUalKUswjGJ8j894ailvdNDtUIyVgjoBpBWj9VRYfY8F/6ew
+1mJ7CsIbTFcs06wXLqYy6Zxh2z8CgYEAzCB31gS5Y8VjncdZ0PvOBHTLxL4wStFp
+5Dw6dSzFZrB6PJc9xFqVS1ffdfNtzfIH9uT9ISNHSWq6F4JM1YipYg3LLraRTK2I
+KOr2B2fZllhKk3LUZcVouFWys4jM7976IGEHL1r973Av9iBXfRgakYMMihTu/ONA
+81YWb8gk6UUCgYB/fW78MK1lw8kOhbYGHMOahs0STyQo4S6g2+1JovvD3iOC185J
+3bRvmGQ+qsXId9dC13+UQUuIL0Q7F3pB4XOVZnVj4m4PhamhNwwfqgZ+VhPrJa8a
+D+/QWtS7O70XWPYLirnkeDyqD2Hz7gMCmg7Ti0HOBJ0dhj4V4dFPwQB5gQKBgQCe
+xu6P4bLWwXYgBy182jDA1Jyfl5R2zfeBGbwa4s1VeBZMxRO9hPw10880rzoNBKNf
+T3T57rgHimXf3XGocxnV9IbD+iyBKUYNFd5zmjrssBaqJJrD4s72+2n6LoHCX33N
+68sr8aouMeSMnVGQM0yPPRFm4quWt6oQ3TiskFDtxQKBgQCJraYImZDjd9hcPMk4
+dYY9RnX6NVSvsy9YTmie6W7HfjAfZqw1V/5MZXY0rnD/H+aqTttNaHHM0ANR7Z5H
+b9rbZArpM+AliJavMFYeooQPSpb87Vz2BR6ZVbJQFTJwFAP4krA5ypCDqTawQfXS
+hXNkIr8C4/CL0I0ho339Gp6o1g==
+-----END PRIVATE KEY-----
diff --git a/core/camel-endpointdsl/src/main/java/org/apache/camel/builder/endpoint/dsl/SshEndpointBuilderFactory.java b/core/camel-endpointdsl/src/main/java/org/apache/camel/builder/endpoint/dsl/SshEndpointBuilderFactory.java
index 73eabe8..3589d7f 100644
--- a/core/camel-endpointdsl/src/main/java/org/apache/camel/builder/endpoint/dsl/SshEndpointBuilderFactory.java
+++ b/core/camel-endpointdsl/src/main/java/org/apache/camel/builder/endpoint/dsl/SshEndpointBuilderFactory.java
@@ -499,6 +499,17 @@ public interface SshEndpointBuilderFactory {
return this;
}
/**
+ * Sets the password to use in loading certResource, if certResource is
+ * an encrypted key.
+ * The option is a <code>java.lang.String</code> type.
+ * @group security
+ */
+ default SshEndpointConsumerBuilder certResourcePassword(
+ String certResourcePassword) {
+ setProperty("certResourcePassword", certResourcePassword);
+ return this;
+ }
+ /**
* Sets the KeyPairProvider reference to use when connecting using
* Certificates to the remote SSH Server.
* The option is a
@@ -868,6 +879,17 @@ public interface SshEndpointBuilderFactory {
return this;
}
/**
+ * Sets the password to use in loading certResource, if certResource is
+ * an encrypted key.
+ * The option is a <code>java.lang.String</code> type.
+ * @group security
+ */
+ default SshEndpointProducerBuilder certResourcePassword(
+ String certResourcePassword) {
+ setProperty("certResourcePassword", certResourcePassword);
+ return this;
+ }
+ /**
* Sets the KeyPairProvider reference to use when connecting using
* Certificates to the remote SSH Server.
* The option is a
@@ -1121,6 +1143,17 @@ public interface SshEndpointBuilderFactory {
return this;
}
/**
+ * Sets the password to use in loading certResource, if certResource is
+ * an encrypted key.
+ * The option is a <code>java.lang.String</code> type.
+ * @group security
+ */
+ default SshEndpointBuilder certResourcePassword(
+ String certResourcePassword) {
+ setProperty("certResourcePassword", certResourcePassword);
+ return this;
+ }
+ /**
* Sets the KeyPairProvider reference to use when connecting using
* Certificates to the remote SSH Server.
* The option is a
diff --git a/platforms/spring-boot/components-starter/camel-ssh-starter/src/main/java/org/apache/camel/component/ssh/springboot/SshComponentConfiguration.java b/platforms/spring-boot/components-starter/camel-ssh-starter/src/main/java/org/apache/camel/component/ssh/springboot/SshComponentConfiguration.java
index b8e6a32..51d01c9 100644
--- a/platforms/spring-boot/components-starter/camel-ssh-starter/src/main/java/org/apache/camel/component/ssh/springboot/SshComponentConfiguration.java
+++ b/platforms/spring-boot/components-starter/camel-ssh-starter/src/main/java/org/apache/camel/component/ssh/springboot/SshComponentConfiguration.java
@@ -91,6 +91,11 @@ public class SshComponentConfiguration
*/
private String certResource;
/**
+ * Sets the password to use in loading certResource, if certResource is an
+ * encrypted key.
+ */
+ private String certResourcePassword;
+ /**
* Sets the channel type to pass to the Channel as part of command
* execution. Defaults to exec.
*/
@@ -198,6 +203,14 @@ public class SshComponentConfiguration
this.certResource = certResource;
}
+ public String getCertResourcePassword() {
+ return certResourcePassword;
+ }
+
+ public void setCertResourcePassword(String certResourcePassword) {
+ this.certResourcePassword = certResourcePassword;
+ }
+
public String getChannelType() {
return channelType;
}
@@ -292,6 +305,11 @@ public class SshComponentConfiguration
*/
private String certResource;
/**
+ * Sets the password to use in loading certResource, if certResource is
+ * an encrypted key.
+ */
+ private String certResourcePassword;
+ /**
* Sets the resource path for a known_hosts file
*/
private String knownHostsResource;
@@ -399,6 +417,14 @@ public class SshComponentConfiguration
this.certResource = certResource;
}
+ public String getCertResourcePassword() {
+ return certResourcePassword;
+ }
+
+ public void setCertResourcePassword(String certResourcePassword) {
+ this.certResourcePassword = certResourcePassword;
+ }
+
public String getKnownHostsResource() {
return knownHostsResource;
}