This is an automated email from the ASF dual-hosted git repository.

twolf pushed a commit to branch dev_3.0
in repository https://gitbox.apache.org/repos/asf/mina-sshd.git

commit 31d9bdc8aa25803721e35e467bde76b646b9152c
Author: Thomas Wolf <tw...@apache.org>
AuthorDate: Sun Sep 21 21:58:10 2025 +0200

    Remove reflective calls to security getInstance(algorithm) methods
    
    Simplify this setup a little. We always know what kind of security
    entity we want to create, so there is no need for some convoluted
    reflective way to create factories.
---
 .../util/security/SecurityEntityFactory.java       | 351 ++++++++++++---------
 .../util/security/SecurityProviderChoice.java      |   6 +-
 .../sshd/common/util/security/SecurityUtils.java   |  81 ++---
 .../BouncyCastleSecurityProviderRegistrar.java     |  11 +
 .../eddsa/EdDSASecurityProviderRegistrar.java      |  73 ++---
 5 files changed, 291 insertions(+), 231 deletions(-)

diff --git 
a/sshd-common/src/main/java/org/apache/sshd/common/util/security/SecurityEntityFactory.java
 
b/sshd-common/src/main/java/org/apache/sshd/common/util/security/SecurityEntityFactory.java
index d8648cb83..eab3f0cec 100644
--- 
a/sshd-common/src/main/java/org/apache/sshd/common/util/security/SecurityEntityFactory.java
+++ 
b/sshd-common/src/main/java/org/apache/sshd/common/util/security/SecurityEntityFactory.java
@@ -19,169 +19,218 @@
 
 package org.apache.sshd.common.util.security;
 
-import java.lang.reflect.Method;
 import java.security.GeneralSecurityException;
+import java.security.KeyFactory;
+import java.security.KeyPairGenerator;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
 import java.security.Provider;
-import java.util.Objects;
+import java.security.SecureRandom;
+import java.security.Signature;
+import java.security.cert.CertificateFactory;
+
+import javax.crypto.Cipher;
+import javax.crypto.KeyAgreement;
+import javax.crypto.Mac;
 
-import org.apache.sshd.common.util.ExceptionUtils;
 import org.apache.sshd.common.util.ValidateUtils;
 
 /**
- * @param  <T> Type of security entity being generated by this factory
- * @author     <a href="mailto:d...@mina.apache.org";>Apache MINA SSHD 
Project</a>
+ * @author <a href="mailto:d...@mina.apache.org";>Apache MINA SSHD Project</a>
  */
-public interface SecurityEntityFactory<T> {
-    Class<T> getEntityType();
-
-    T getInstance(String algorithm) throws GeneralSecurityException;
-
-    /**
-     * Uses reflection in order to wrap the {@code getInstance} method(s) as a 
security entity factory.
-     *
-     * @param  <F>                          Type of entity being generated by 
the factor
-     * @param  entityType                   The entity type class
-     * @param  registrar                    The {@code 
SecurityProviderRegistrar} to use - if {@code null} then default
-     *                                      provider is used (if specified).
-     * @param  defaultProvider              Default provider choice to use if 
no registrar provided. If
-     *                                      {@code null}/empty then JCE 
default is used
-     * @return                              The {@link SecurityEntityFactory} 
for the entity
-     * @throws ReflectiveOperationException If failed to create the factory
-     * @see                                 #toDefaultFactory(Class)
-     * @see                                 #toNamedProviderFactory(Class, 
String)
-     * @see                                 #toProviderInstanceFactory(Class, 
Provider)
-     * @see                                 
SecurityProviderChoice#isNamedProviderUsed()
-     * @see                                 
SecurityProviderChoice#getSecurityProvider()
-     */
-    static <F> SecurityEntityFactory<F> toFactory(
-            Class<F> entityType, SecurityProviderChoice registrar, 
SecurityProviderChoice defaultProvider)
-            throws ReflectiveOperationException {
-        if (registrar == null) {
-            if ((defaultProvider == null) || (defaultProvider == 
SecurityProviderChoice.EMPTY)) {
-                return toDefaultFactory(entityType);
-            }
-            return defaultProvider.getFactory(entityType);
-        }
-        return registrar.getFactory(entityType);
+public interface SecurityEntityFactory {
+
+    default CertificateFactory createCertificateFactory(String algorithm) 
throws GeneralSecurityException {
+        throw new NoSuchAlgorithmException("Algorithm '" + algorithm + "' not 
supported (default)");
+    }
+
+    default Cipher createCipher(String algorithm) throws 
GeneralSecurityException {
+        throw new NoSuchAlgorithmException("Algorithm '" + algorithm + "' not 
supported (default)");
+    }
+
+    default KeyAgreement createKeyAgreement(String algorithm) throws 
GeneralSecurityException {
+        throw new NoSuchAlgorithmException("Algorithm '" + algorithm + "' not 
supported (default)");
+    }
+
+    default KeyFactory createKeyFactory(String algorithm) throws 
GeneralSecurityException {
+        throw new NoSuchAlgorithmException("Algorithm '" + algorithm + "' not 
supported (default)");
+    }
+
+    default KeyPairGenerator createKeyPairGenerator(String algorithm) throws 
GeneralSecurityException {
+        throw new NoSuchAlgorithmException("Algorithm '" + algorithm + "' not 
supported (default)");
     }
 
-    static <F> SecurityEntityFactory<F> toDefaultFactory(Class<F> entityType)
-            throws ReflectiveOperationException {
-        Method m = entityType.getDeclaredMethod("getInstance", String.class);
-        return new SecurityEntityFactory<F>() {
-            private final String s = 
SecurityEntityFactory.class.getSimpleName()
-                                     + "[" + entityType.getSimpleName() + "]"
-                                     + "[default]";
-
-            @Override
-            public Class<F> getEntityType() {
-                return entityType;
-            }
-
-            @Override
-            public F getInstance(String algorithm) throws 
GeneralSecurityException {
-                try {
-                    Object value = m.invoke(null, algorithm);
-                    return entityType.cast(value);
-                } catch (ReflectiveOperationException t) {
-                    Throwable e = ExceptionUtils.peelException(t);
-                    if (e instanceof GeneralSecurityException) {
-                        throw (GeneralSecurityException) e;
-                    } else if (e instanceof RuntimeException) {
-                        throw (RuntimeException) e;
-                    } else if (e instanceof Error) {
-                        throw (Error) e;
-                    } else {
-                        throw new GeneralSecurityException(e);
-                    }
-                }
-            }
-
-            @Override
-            public String toString() {
-                return s;
-            }
-        };
+    default Mac createMac(String algorithm) throws GeneralSecurityException {
+        throw new NoSuchAlgorithmException("Algorithm '" + algorithm + "' not 
supported (default)");
     }
 
-    static <F> SecurityEntityFactory<F> toNamedProviderFactory(Class<F> 
entityType, String name)
-            throws ReflectiveOperationException {
-        ValidateUtils.checkNotNullAndNotEmpty(name, "No provider name 
specified");
-        Method m = entityType.getDeclaredMethod("getInstance", String.class, 
String.class);
-        return new SecurityEntityFactory<F>() {
-            private final String s = 
SecurityEntityFactory.class.getSimpleName()
-                                     + "[" + entityType.getSimpleName() + "]"
-                                     + "[" + name + "]";
-
-            @Override
-            public Class<F> getEntityType() {
-                return entityType;
-            }
-
-            @Override
-            public F getInstance(String algorithm) throws 
GeneralSecurityException {
-                try {
-                    Object value = m.invoke(null, algorithm, name);
-                    return entityType.cast(value);
-                } catch (ReflectiveOperationException t) {
-                    Throwable e = ExceptionUtils.peelException(t);
-                    if (e instanceof GeneralSecurityException) {
-                        throw (GeneralSecurityException) e;
-                    } else if (e instanceof RuntimeException) {
-                        throw (RuntimeException) e;
-                    } else if (e instanceof Error) {
-                        throw (Error) e;
-                    } else {
-                        throw new GeneralSecurityException(e);
-                    }
-                }
-            }
-
-            @Override
-            public String toString() {
-                return s;
-            }
-        };
+    default MessageDigest createMessageDigest(String algorithm) throws 
GeneralSecurityException {
+        throw new NoSuchAlgorithmException("Algorithm '" + algorithm + "' not 
supported (default)");
+    }
+
+    default Signature createSignature(String algorithm) throws 
GeneralSecurityException {
+        throw new NoSuchAlgorithmException("Algorithm '" + algorithm + "' not 
supported (default)");
+    }
+
+    default SecureRandom createSecureRandom(String algorithm) throws 
GeneralSecurityException {
+        throw new NoSuchAlgorithmException("Algorithm '" + algorithm + "' not 
supported (default)");
+    }
+
+    class Named implements SecurityEntityFactory {
+
+        private final String name;
+
+        public Named(String name) {
+            this.name = ValidateUtils.checkNotNullAndNotEmpty(name, "Security 
provider name must not be empty");
+        }
+
+        @Override
+        public CertificateFactory createCertificateFactory(String algorithm) 
throws GeneralSecurityException {
+            return CertificateFactory.getInstance(algorithm, name);
+        }
+
+        @Override
+        public Cipher createCipher(String algorithm) throws 
GeneralSecurityException {
+            return Cipher.getInstance(algorithm, name);
+        }
+
+        @Override
+        public KeyAgreement createKeyAgreement(String algorithm) throws 
GeneralSecurityException {
+            return KeyAgreement.getInstance(algorithm, name);
+        }
+
+        @Override
+        public KeyFactory createKeyFactory(String algorithm) throws 
GeneralSecurityException {
+            return KeyFactory.getInstance(algorithm, name);
+        }
+
+        @Override
+        public KeyPairGenerator createKeyPairGenerator(String algorithm) 
throws GeneralSecurityException {
+            return KeyPairGenerator.getInstance(algorithm, name);
+        }
+
+        @Override
+        public Mac createMac(String algorithm) throws GeneralSecurityException 
{
+            return Mac.getInstance(algorithm, name);
+        }
+
+        @Override
+        public MessageDigest createMessageDigest(String algorithm) throws 
GeneralSecurityException {
+            return MessageDigest.getInstance(algorithm, name);
+        }
+
+        @Override
+        public Signature createSignature(String algorithm) throws 
GeneralSecurityException {
+            return Signature.getInstance(algorithm, name);
+        }
+
+        @Override
+        public SecureRandom createSecureRandom(String algorithm) throws 
GeneralSecurityException {
+            return SecureRandom.getInstance(algorithm, name);
+        }
     }
 
-    static <F> SecurityEntityFactory<F> toProviderInstanceFactory(Class<F> 
entityType, Provider provider)
-            throws ReflectiveOperationException {
-        Objects.requireNonNull(provider, "No provider instance");
-        Method m = entityType.getDeclaredMethod("getInstance", String.class, 
Provider.class);
-        return new SecurityEntityFactory<F>() {
-            private final String s = 
SecurityEntityFactory.class.getSimpleName()
-                                     + "[" + entityType.getSimpleName() + "]"
-                                     + "[" + Provider.class.getSimpleName() + 
"]"
-                                     + "[" + provider.getName() + "]";
-
-            @Override
-            public Class<F> getEntityType() {
-                return entityType;
-            }
-
-            @Override
-            public F getInstance(String algorithm) throws 
GeneralSecurityException {
-                try {
-                    Object value = m.invoke(null, algorithm, provider);
-                    return entityType.cast(value);
-                } catch (ReflectiveOperationException t) {
-                    Throwable e = ExceptionUtils.peelException(t);
-                    if (e instanceof GeneralSecurityException) {
-                        throw (GeneralSecurityException) e;
-                    } else if (e instanceof RuntimeException) {
-                        throw (RuntimeException) e;
-                    } else if (e instanceof Error) {
-                        throw (Error) e;
-                    } else {
-                        throw new GeneralSecurityException(e);
-                    }
-                }
-            }
-
-            @Override
-            public String toString() {
-                return s;
-            }
-        };
+    class ByProvider implements SecurityEntityFactory {
+
+        private final Provider provider;
+
+        public ByProvider(Provider name) {
+            this.provider = ValidateUtils.checkNotNull(name, "Security 
provider must not be null");
+        }
+
+        @Override
+        public CertificateFactory createCertificateFactory(String algorithm) 
throws GeneralSecurityException {
+            return CertificateFactory.getInstance(algorithm, provider);
+        }
+
+        @Override
+        public Cipher createCipher(String algorithm) throws 
GeneralSecurityException {
+            return Cipher.getInstance(algorithm, provider);
+        }
+
+        @Override
+        public KeyAgreement createKeyAgreement(String algorithm) throws 
GeneralSecurityException {
+            return KeyAgreement.getInstance(algorithm, provider);
+        }
+
+        @Override
+        public KeyFactory createKeyFactory(String algorithm) throws 
GeneralSecurityException {
+            return KeyFactory.getInstance(algorithm, provider);
+        }
+
+        @Override
+        public KeyPairGenerator createKeyPairGenerator(String algorithm) 
throws GeneralSecurityException {
+            return KeyPairGenerator.getInstance(algorithm, provider);
+        }
+
+        @Override
+        public Mac createMac(String algorithm) throws GeneralSecurityException 
{
+            return Mac.getInstance(algorithm, provider);
+        }
+
+        @Override
+        public MessageDigest createMessageDigest(String algorithm) throws 
GeneralSecurityException {
+            return MessageDigest.getInstance(algorithm, provider);
+        }
+
+        @Override
+        public Signature createSignature(String algorithm) throws 
GeneralSecurityException {
+            return Signature.getInstance(algorithm, provider);
+        }
+
+        @Override
+        public SecureRandom createSecureRandom(String algorithm) throws 
GeneralSecurityException {
+            return SecureRandom.getInstance(algorithm, provider);
+        }
+    }
+
+    enum Default implements SecurityEntityFactory {
+
+        INSTANCE;
+
+        @Override
+        public CertificateFactory createCertificateFactory(String algorithm) 
throws GeneralSecurityException {
+            return CertificateFactory.getInstance(algorithm);
+        }
+
+        @Override
+        public Cipher createCipher(String algorithm) throws 
GeneralSecurityException {
+            return Cipher.getInstance(algorithm);
+        }
+
+        @Override
+        public KeyAgreement createKeyAgreement(String algorithm) throws 
GeneralSecurityException {
+            return KeyAgreement.getInstance(algorithm);
+        }
+
+        @Override
+        public KeyFactory createKeyFactory(String algorithm) throws 
GeneralSecurityException {
+            return KeyFactory.getInstance(algorithm);
+        }
+
+        @Override
+        public KeyPairGenerator createKeyPairGenerator(String algorithm) 
throws GeneralSecurityException {
+            return KeyPairGenerator.getInstance(algorithm);
+        }
+
+        @Override
+        public Mac createMac(String algorithm) throws GeneralSecurityException 
{
+            return Mac.getInstance(algorithm);
+        }
+
+        @Override
+        public MessageDigest createMessageDigest(String algorithm) throws 
GeneralSecurityException {
+            return MessageDigest.getInstance(algorithm);
+        }
+
+        @Override
+        public Signature createSignature(String algorithm) throws 
GeneralSecurityException {
+            return Signature.getInstance(algorithm);
+        }
+
+        @Override
+        public SecureRandom createSecureRandom(String algorithm) throws 
GeneralSecurityException {
+            return SecureRandom.getInstance(algorithm);
+        }
     }
 }
diff --git 
a/sshd-common/src/main/java/org/apache/sshd/common/util/security/SecurityProviderChoice.java
 
b/sshd-common/src/main/java/org/apache/sshd/common/util/security/SecurityProviderChoice.java
index 1da7e6017..82b820a39 100644
--- 
a/sshd-common/src/main/java/org/apache/sshd/common/util/security/SecurityProviderChoice.java
+++ 
b/sshd-common/src/main/java/org/apache/sshd/common/util/security/SecurityProviderChoice.java
@@ -71,11 +71,11 @@ public interface SecurityProviderChoice extends 
NamedResource {
         return getName();
     }
 
-    default <F> SecurityEntityFactory<F> getFactory(Class<F> entityType) 
throws ReflectiveOperationException {
+    default SecurityEntityFactory getFactory() {
         if (isNamedProviderUsed()) {
-            return SecurityEntityFactory.toNamedProviderFactory(entityType, 
getProviderName());
+            return new SecurityEntityFactory.Named(getProviderName());
         }
-        return SecurityEntityFactory.toProviderInstanceFactory(entityType, 
getSecurityProvider());
+        return new SecurityEntityFactory.ByProvider(getSecurityProvider());
     }
 
     /**
diff --git 
a/sshd-common/src/main/java/org/apache/sshd/common/util/security/SecurityUtils.java
 
b/sshd-common/src/main/java/org/apache/sshd/common/util/security/SecurityUtils.java
index 512c09066..dcb93c20c 100644
--- 
a/sshd-common/src/main/java/org/apache/sshd/common/util/security/SecurityUtils.java
+++ 
b/sshd-common/src/main/java/org/apache/sshd/common/util/security/SecurityUtils.java
@@ -169,7 +169,10 @@ public final class SecurityUtils {
     // If an entry already exists for the named provider, then it overrides 
its SecurityProviderRegistrar#isEnabled()
     private static final Set<String> APRIORI_DISABLED_PROVIDERS = new 
TreeSet<>();
     private static final AtomicBoolean REGISTRATION_STATE_HOLDER = new 
AtomicBoolean(false);
-    private static final Map<Class<?>, Map<String, SecurityEntityFactory<?>>> 
SECURITY_ENTITY_FACTORIES = new HashMap<>();
+    /*
+     * This map keys security entities by algorithm names to 
SecurityEntityProviders.
+     */
+    private static final Map<Class<?>, Map<String, SecurityEntityFactory>> 
SECURITY_ENTITY_FACTORIES = new HashMap<>();
 
     private static final AtomicReference<SecurityProviderChoice> 
DEFAULT_PROVIDER_HOLDER = new AtomicReference<>();
 
@@ -667,27 +670,25 @@ public final class SecurityUtils {
 
     //////////////////////////// Security entities factories 
/////////////////////////////
 
-    @SuppressWarnings("unchecked")
-    public static <T> SecurityEntityFactory<T> resolveSecurityEntityFactory(
-            Class<T> entityType, String algorithm, Predicate<? super 
SecurityProviderRegistrar> entitySelector) {
-        Map<String, SecurityEntityFactory<?>> factoriesMap;
+    public static SecurityEntityFactory resolveSecurityEntityFactory(
+            Class<?> entityType, String algorithm,
+            Predicate<? super SecurityProviderRegistrar> entitySelector) {
+        Map<String, SecurityEntityFactory> factoriesMap;
         synchronized (SECURITY_ENTITY_FACTORIES) {
             factoriesMap = SECURITY_ENTITY_FACTORIES.computeIfAbsent(
                     entityType, k -> new 
TreeMap<>(String.CASE_INSENSITIVE_ORDER));
         }
 
-        String effectiveName = 
SecurityProviderRegistrar.getEffectiveSecurityEntityName(entityType, algorithm);
-        SecurityEntityFactory<?> factoryEntry;
+        SecurityEntityFactory provider;
         synchronized (factoriesMap) {
-            factoryEntry = factoriesMap.computeIfAbsent(
-                    effectiveName, k -> 
createSecurityEntityFactory(entityType, entitySelector));
+            provider = factoriesMap.computeIfAbsent(algorithm, k -> 
createSecurityEntityFactory(entitySelector));
         }
 
-        return (SecurityEntityFactory<T>) factoryEntry;
+        return provider;
     }
 
-    public static <T> SecurityEntityFactory<T> createSecurityEntityFactory(
-            Class<T> entityType, Predicate<? super SecurityProviderRegistrar> 
entitySelector) {
+    public static SecurityEntityFactory createSecurityEntityFactory(
+            Predicate<? super SecurityProviderRegistrar> entitySelector) {
         register();
 
         SecurityProviderRegistrar registrar;
@@ -696,65 +697,67 @@ public final class SecurityUtils {
                     entitySelector, REGISTERED_PROVIDERS.values());
         }
 
-        try {
-            return SecurityEntityFactory.toFactory(entityType, registrar, 
getDefaultProviderChoice());
-        } catch (ReflectiveOperationException t) {
-            Throwable e = ExceptionUtils.peelException(t);
-            if (e instanceof RuntimeException) {
-                throw (RuntimeException) e;
-            } else if (e instanceof Error) {
-                throw (Error) e;
-            } else {
-                throw new IllegalArgumentException(e);
+        return getSecurityEntityProvider(registrar, 
getDefaultProviderChoice());
+    }
+
+    public static SecurityEntityFactory getSecurityEntityProvider(
+            SecurityProviderRegistrar registrar,
+            SecurityProviderChoice defaultProvider) {
+        if (registrar == null) {
+            if ((defaultProvider == null) || (defaultProvider == 
SecurityProviderChoice.EMPTY)) {
+                return SecurityEntityFactory.Default.INSTANCE;
             }
+            return defaultProvider.getFactory();
         }
+        return registrar.getFactory();
     }
 
     public static KeyFactory getKeyFactory(String algorithm) throws 
GeneralSecurityException {
-        SecurityEntityFactory<KeyFactory> factory = 
resolveSecurityEntityFactory(KeyFactory.class, algorithm,
+        SecurityEntityFactory factory = 
resolveSecurityEntityFactory(KeyFactory.class, algorithm,
                 r -> r.isKeyFactorySupported(algorithm));
-        return factory.getInstance(algorithm);
+        return factory.createKeyFactory(algorithm);
     }
 
     public static Cipher getCipher(String transformation) throws 
GeneralSecurityException {
-        SecurityEntityFactory<Cipher> factory
-                = resolveSecurityEntityFactory(Cipher.class, transformation, r 
-> r.isCipherSupported(transformation));
-        return factory.getInstance(transformation);
+        String algorithm = 
SecurityProviderRegistrar.getEffectiveSecurityEntityName(Cipher.class, 
transformation);
+        SecurityEntityFactory factory = 
resolveSecurityEntityFactory(Cipher.class, algorithm,
+                r -> r.isCipherSupported(algorithm));
+        return factory.createCipher(transformation);
     }
 
     public static MessageDigest getMessageDigest(String algorithm) throws 
GeneralSecurityException {
-        SecurityEntityFactory<MessageDigest> factory
+        SecurityEntityFactory factory
                 = resolveSecurityEntityFactory(MessageDigest.class, algorithm, 
r -> r.isMessageDigestSupported(algorithm));
-        return factory.getInstance(algorithm);
+        return factory.createMessageDigest(algorithm);
     }
 
     public static KeyPairGenerator getKeyPairGenerator(String algorithm) 
throws GeneralSecurityException {
-        SecurityEntityFactory<KeyPairGenerator> factory = 
resolveSecurityEntityFactory(KeyPairGenerator.class, algorithm,
+        SecurityEntityFactory factory = 
resolveSecurityEntityFactory(KeyPairGenerator.class, algorithm,
                 r -> r.isKeyPairGeneratorSupported(algorithm));
-        return factory.getInstance(algorithm);
+        return factory.createKeyPairGenerator(algorithm);
     }
 
     public static KeyAgreement getKeyAgreement(String algorithm) throws 
GeneralSecurityException {
-        SecurityEntityFactory<KeyAgreement> factory
+        SecurityEntityFactory factory
                 = resolveSecurityEntityFactory(KeyAgreement.class, algorithm, 
r -> r.isKeyAgreementSupported(algorithm));
-        return factory.getInstance(algorithm);
+        return factory.createKeyAgreement(algorithm);
     }
 
     public static Mac getMac(String algorithm) throws GeneralSecurityException 
{
-        SecurityEntityFactory<Mac> factory
+        SecurityEntityFactory factory
                 = resolveSecurityEntityFactory(Mac.class, algorithm, r -> 
r.isMacSupported(algorithm));
-        return factory.getInstance(algorithm);
+        return factory.createMac(algorithm);
     }
 
     public static Signature getSignature(String algorithm) throws 
GeneralSecurityException {
-        SecurityEntityFactory<Signature> factory
+        SecurityEntityFactory factory
                 = resolveSecurityEntityFactory(Signature.class, algorithm, r 
-> r.isSignatureSupported(algorithm));
-        return factory.getInstance(algorithm);
+        return factory.createSignature(algorithm);
     }
 
     public static CertificateFactory getCertificateFactory(String type) throws 
GeneralSecurityException {
-        SecurityEntityFactory<CertificateFactory> factory
+        SecurityEntityFactory factory
                 = resolveSecurityEntityFactory(CertificateFactory.class, type, 
r -> r.isCertificateFactorySupported(type));
-        return factory.getInstance(type);
+        return factory.createCertificateFactory(type);
     }
 }
diff --git 
a/sshd-common/src/main/java/org/apache/sshd/common/util/security/bouncycastle/BouncyCastleSecurityProviderRegistrar.java
 
b/sshd-common/src/main/java/org/apache/sshd/common/util/security/bouncycastle/BouncyCastleSecurityProviderRegistrar.java
index f5d186044..a6a1bb8d0 100644
--- 
a/sshd-common/src/main/java/org/apache/sshd/common/util/security/bouncycastle/BouncyCastleSecurityProviderRegistrar.java
+++ 
b/sshd-common/src/main/java/org/apache/sshd/common/util/security/bouncycastle/BouncyCastleSecurityProviderRegistrar.java
@@ -50,6 +50,8 @@ public class BouncyCastleSecurityProviderRegistrar extends 
AbstractSecurityProvi
     private String providerClass;
     private String providerName;
 
+    private boolean useName = true;
+
     public BouncyCastleSecurityProviderRegistrar() {
         super(SecurityUtils.BOUNCY_CASTLE);
     }
@@ -59,6 +61,11 @@ public class BouncyCastleSecurityProviderRegistrar extends 
AbstractSecurityProvi
         return providerName;
     }
 
+    @Override
+    public boolean isNamedProviderUsed() {
+        return useName;
+    }
+
     @Override
     public Provider getSecurityProvider() {
         try {
@@ -142,19 +149,23 @@ public class BouncyCastleSecurityProviderRegistrar 
extends AbstractSecurityProvi
                 if (fipsInstalled && haveFips) {
                     providerClass = FIPS_PROVIDER_CLASS;
                     providerName = BCFIPS_PROVIDER_NAME;
+                    useName = true;
                     supported = Boolean.TRUE;
                 } else if (bcInstalled && haveBc) {
                     providerClass = PROVIDER_CLASS;
                     providerName = BC_PROVIDER_NAME;
+                    useName = true;
                     supported = Boolean.TRUE;
                 } else if (haveFips) {
                     providerClass = FIPS_PROVIDER_CLASS;
                     providerName = BCFIPS_PROVIDER_NAME;
+                    useName = false;
                     supported = Boolean.TRUE;
                 } else if (haveBc) {
                     providerClass = PROVIDER_CLASS;
                     providerName = BC_PROVIDER_NAME;
                     supported = Boolean.TRUE;
+                    useName = false;
                 } else {
                     supported = Boolean.FALSE;
                 }
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 dd9a5f5c0..3c2e1de3d 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
@@ -24,6 +24,7 @@ import java.security.KeyPairGenerator;
 import java.security.PrivateKey;
 import java.security.Provider;
 import java.security.PublicKey;
+import java.security.Security;
 import java.security.Signature;
 import java.util.concurrent.atomic.AtomicReference;
 
@@ -42,6 +43,8 @@ public class EdDSASecurityProviderRegistrar extends 
AbstractSecurityProviderRegi
     // Do not define a static registrar instance to minimize class loading 
issues
     private final AtomicReference<Boolean> supportHolder = new 
AtomicReference<>(null);
 
+    private boolean useName = true;
+
     public EdDSASecurityProviderRegistrar() {
         super(SecurityUtils.EDDSA);
     }
@@ -51,6 +54,11 @@ public class EdDSASecurityProviderRegistrar extends 
AbstractSecurityProviderRegi
         return !SecurityUtils.isFipsMode() && super.isEnabled();
     }
 
+    @Override
+    public boolean isNamedProviderUsed() {
+        return useName;
+    }
+
     @Override
     public Provider getSecurityProvider() {
         try {
@@ -93,6 +101,10 @@ public class EdDSASecurityProviderRegistrar extends 
AbstractSecurityProviderRegi
             }
 
             supported = Boolean.valueOf(EdDSAAccessor.INSTANCE.isSupported());
+            if (supported.booleanValue()) {
+                Provider provider = Security.getProvider(getProviderName());
+                useName = provider != null;
+            }
             supportHolder.set(supported);
         }
 
@@ -110,33 +122,8 @@ public class EdDSASecurityProviderRegistrar extends 
AbstractSecurityProviderRegi
     }
 
     @Override
-    public <F> SecurityEntityFactory<F> getFactory(Class<F> entityType) throws 
ReflectiveOperationException {
-        // Return factories that map the algorithm names to the non-standard 
ones used by net.i2p.
-        // That way the rest of our code can work with the standard names.
-        if (KeyPairGenerator.class.isAssignableFrom(entityType) || 
KeyFactory.class.isAssignableFrom(entityType)) {
-            return new 
DelegatingSecurityEntityFactory<F>(super.getFactory(entityType)) {
-
-                @Override
-                protected String effectiveAlgorithm(String originalAlgorithm) {
-                    if 
(SecurityUtils.ED25519.equalsIgnoreCase(originalAlgorithm)) {
-                        return SecurityUtils.EDDSA;
-                    }
-                    return originalAlgorithm;
-                }
-            };
-        } else if (Signature.class.isAssignableFrom(entityType)) {
-            return new 
DelegatingSecurityEntityFactory<F>(super.getFactory(entityType)) {
-
-                @Override
-                protected String effectiveAlgorithm(String originalAlgorithm) {
-                    if 
(SecurityUtils.ED25519.equalsIgnoreCase(originalAlgorithm)) {
-                        return "NONEwithEdDSA";
-                    }
-                    return originalAlgorithm;
-                }
-            };
-        }
-        return super.getFactory(entityType);
+    public SecurityEntityFactory getFactory() {
+        return new DelegatingSecurityEntityProvider(super.getFactory());
     }
 
     @Override
@@ -148,29 +135,39 @@ public class EdDSASecurityProviderRegistrar extends 
AbstractSecurityProviderRegi
         return super.getPublicKey(key);
     }
 
-    private abstract static class DelegatingSecurityEntityFactory<F> 
implements SecurityEntityFactory<F> {
+    private static class DelegatingSecurityEntityProvider implements 
SecurityEntityFactory {
 
-        private SecurityEntityFactory<F> delegate;
+        private SecurityEntityFactory delegate;
 
-        DelegatingSecurityEntityFactory(SecurityEntityFactory<F> delegate) {
+        DelegatingSecurityEntityProvider(SecurityEntityFactory delegate) {
             this.delegate = delegate;
         }
 
         @Override
-        public Class<F> getEntityType() {
-            return delegate.getEntityType();
+        public KeyFactory createKeyFactory(String algorithm) throws 
GeneralSecurityException {
+            String effective = algorithm;
+            if (SecurityUtils.ED25519.equalsIgnoreCase(effective)) {
+                effective = SecurityUtils.EDDSA;
+            }
+            return delegate.createKeyFactory(effective);
         }
 
         @Override
-        public F getInstance(String algorithm) throws GeneralSecurityException 
{
-            return delegate.getInstance(effectiveAlgorithm(algorithm));
+        public KeyPairGenerator createKeyPairGenerator(String algorithm) 
throws GeneralSecurityException {
+            String effective = algorithm;
+            if (SecurityUtils.ED25519.equalsIgnoreCase(effective)) {
+                effective = SecurityUtils.EDDSA;
+            }
+            return delegate.createKeyPairGenerator(effective);
         }
 
-        protected abstract String effectiveAlgorithm(String originalAlgorithm);
-
         @Override
-        public String toString() {
-            return delegate.toString();
+        public Signature createSignature(String algorithm) throws 
GeneralSecurityException {
+            String effective = algorithm;
+            if (SecurityUtils.ED25519.equalsIgnoreCase(effective)) {
+                effective = "NONEwithEdDSA";
+            }
+            return delegate.createSignature(effective);
         }
     }
 }

Reply via email to