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); } } }