[ 
https://issues.apache.org/jira/browse/SSHD-1145?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17313142#comment-17313142
 ] 

Grzegorz Grzybek commented on SSHD-1145:
----------------------------------------

[~gnodet], with this little change, EdDSASecurityProviderRegistrar can find 
EdDSA from net.i2p.crypto library
{noformat}
diff --git 
a/sshd-common/src/main/java/org/apache/sshd/common/util/security/eddsa/EdDSASecurityProviderRegistrar.java
 
b/sshd-common/src/main/java/org/apache/sshd/common/util/security/eddsa/EdDSASecurityProviderRegistrar.java
index 431a04c11..04babe5a7 100644
--- 
a/sshd-common/src/main/java/org/apache/sshd/common/util/security/eddsa/EdDSASecurityProviderRegistrar.java
+++ 
b/sshd-common/src/main/java/org/apache/sshd/common/util/security/eddsa/EdDSASecurityProviderRegistrar.java
@@ -26,7 +26,6 @@ import java.util.Objects;
 import java.util.concurrent.atomic.AtomicReference;
 
 import org.apache.sshd.common.util.GenericUtils;
-import org.apache.sshd.common.util.ReflectionUtils;
 import org.apache.sshd.common.util.security.AbstractSecurityProviderRegistrar;
 import org.apache.sshd.common.util.security.SecurityUtils;
 import org.apache.sshd.common.util.threads.ThreadUtils;
@@ -94,9 +93,10 @@ public class EdDSASecurityProviderRegistrar extends 
AbstractSecurityProviderRegi
                 return supported.booleanValue();
             }
 
-            ClassLoader cl = ThreadUtils.resolveDefaultClassLoader(getClass());
-            supported = ReflectionUtils.isClassAvailable(cl, 
"net.i2p.crypto.eddsa.EdDSAKey");
-            supportHolder.set(supported);
+            Class clazz
+                    = ThreadUtils.resolveDefaultClass(getClass(), 
"net.i2p.crypto.eddsa.EdDSAKey");
+            supportHolder.set(clazz != null);
+            supported = supportHolder.get();
         }
 
         return supported.booleanValue();
diff --git 
a/sshd-common/src/main/java/org/apache/sshd/common/util/threads/ThreadUtils.java
 
b/sshd-common/src/main/java/org/apache/sshd/common/util/threads/ThreadUtils.java
index 9879b7482..ba229ecee 100644
--- 
a/sshd-common/src/main/java/org/apache/sshd/common/util/threads/ThreadUtils.java
+++ 
b/sshd-common/src/main/java/org/apache/sshd/common/util/threads/ThreadUtils.java
@@ -74,6 +74,21 @@ public final class ThreadUtils {
         return () -> iterateDefaultClassLoaders(anchor);
     }
 
+    public static Class<?> resolveDefaultClass(Class<?> anchor, String 
className) {
+        return resolveDefaultClass(resolveDefaultClassLoaders(anchor), 
className);
+    }
+
+    public static Class<?> resolveDefaultClass(Iterable<? extends ClassLoader> 
cls, String className) {
+        for (ClassLoader cl : cls) {
+            try {
+                return cl.loadClass(className);
+            } catch (Throwable ignored) {
+                // Ignore
+            }
+        }
+        return null;
+    }
+
     public static <T> T createDefaultInstance(
             Class<?> anchor, Class<T> targetType, String className)
             throws ReflectiveOperationException {
{noformat}

The idea is to not use two step process like:
# 
org.apache.sshd.common.util.threads.ThreadUtils#resolveDefaultClassLoader(java.lang.Object)
 to get first non-null classloader
# org.apache.sshd.common.util.ReflectionUtils#isClassAvailable() to use the 
above CL to load a class

I added 
{{org.apache.sshd.common.util.threads.ThreadUtils#resolveDefaultClass(java.lang.Class<?>,
 java.lang.String)}} method and 
{{org.apache.sshd.common.util.threads.ThreadUtils#resolveDefaultClass(java.lang.Iterable<?
 extends java.lang.ClassLoader>, java.lang.String)}} method, so we can use all 
reachable classloaders to try to load a class.

My tests related to camel-ssh component in Karaf environment work fine.

The problem is that there are many places that use the code like:
{code:java}
ClassLoader cl = ThreadUtils.resolveDefaultClassLoader(getClass());
supported = ReflectionUtils.isClassAvailable(cl, PROVIDER_CLASS);
{code}

namely:
* 
org.apache.sshd.common.util.security.bouncycastle.BouncyCastleSecurityProviderRegistrar#isSupported()
* org.apache.sshd.cli.server.SshServerCliSupport#resolveServerSubsystems()
* org.apache.sshd.cli.client.ScpCommandMain#resolveScpClientCreator()
* org.apache.sshd.cli.client.SftpCommandMain#resolveSftpClientFactory()
* org.apache.sshd.cli.server.SshServerCliSupport#resolveShellFactory()
* org.apache.sshd.cli.client.SshClientCliSupport#setupSessionExtensions()
(and possibly other methods)

WDYT?
As alternative solution, for now I'm just adding net.i2p.crypto as boot library 
to Karaf.

> EdDSASecurityProviderRegistrar#isSupported() should check more classloaders
> ---------------------------------------------------------------------------
>
>                 Key: SSHD-1145
>                 URL: https://issues.apache.org/jira/browse/SSHD-1145
>             Project: MINA SSHD
>          Issue Type: Improvement
>    Affects Versions: 2.5.1
>            Reporter: Grzegorz Grzybek
>            Priority: Major
>
> I'm working for Karaf and Camel fix that would allow me to use ssh-ed25519 
> for server key.
> EdDSA is supported via net.i2p.crypto/eddsa library, but its availability is 
> checked in a way that is not correct (and not only in OSGi environment).
> It's is also problematic for BouncyCastleSecurityProviderRegistrar, but 
> actually for all methods that use 
> {{org.apache.sshd.common.util.threads.ThreadUtils#resolveDefaultClassLoader(java.lang.Class<?>)}}.
> {{resolveDefaultClassLoader()}} method result is a classloader which is 
> checked for availability of e.g., "net.i2p.crypto.eddsa.EdDSAKey" class, but 
> the check result is cached statically. The problem is that if TCCL is used 
> (which is generally not defined in OSGi) it may be a false negative.
> More precisely - if in Karaf, I start Karaf's own sshd server with a TCCL 
> that _sees_ {{net.i2p.crypto.eddsa}} package, I can use EdDSA algorithm.
> If I add camel-ssh usage, it _may_ have own TCCL (depending on how Camel is 
> started - e.g., through OSGi blueprint) - the first one who calls 
> {{org.apache.sshd.common.util.security.eddsa.EdDSASecurityProviderRegistrar#isSupported()}}
>  _wins_.
> I'll work on a way to check more classloaders in search for given 
> provider/registrar and send a PR soon.



--
This message was sent by Atlassian Jira
(v8.3.4#803005)

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to