You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mina.apache.org by lg...@apache.org on 2018/09/06 16:03:22 UTC
[12/51] [abbrv] mina-sshd git commit: [SSHD-842] Split common
utilities code from sshd-core into sshd-common (new artifact)
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-core/src/main/java/org/apache/sshd/common/util/security/AbstractSecurityProviderRegistrar.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/util/security/AbstractSecurityProviderRegistrar.java b/sshd-core/src/main/java/org/apache/sshd/common/util/security/AbstractSecurityProviderRegistrar.java
deleted file mode 100644
index b665166..0000000
--- a/sshd-core/src/main/java/org/apache/sshd/common/util/security/AbstractSecurityProviderRegistrar.java
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.sshd.common.util.security;
-
-import java.security.Provider;
-import java.security.Security;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.TreeMap;
-import java.util.concurrent.atomic.AtomicReference;
-
-import org.apache.sshd.common.util.ValidateUtils;
-import org.apache.sshd.common.util.logging.AbstractLoggingBean;
-
-/**
- * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
- */
-public abstract class AbstractSecurityProviderRegistrar
- extends AbstractLoggingBean
- implements SecurityProviderRegistrar {
- protected final Map<String, Object> props = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
- protected final Map<Class<?>, Map<String, Boolean>> supportedEntities = new HashMap<>();
- protected final AtomicReference<Provider> providerHolder = new AtomicReference<>(null);
-
- private final String name;
-
- protected AbstractSecurityProviderRegistrar(String name) {
- this.name = ValidateUtils.checkNotNullAndNotEmpty(name, "No name provided");
- }
-
- @Override
- public final String getName() {
- return name;
- }
-
- @Override
- public Map<String, Object> getProperties() {
- return props;
- }
-
- @Override
- public boolean isSecurityEntitySupported(Class<?> entityType, String name) {
- Map<String, Boolean> supportMap;
- synchronized (supportedEntities) {
- supportMap = supportedEntities.computeIfAbsent(
- entityType, k -> new TreeMap<>(String.CASE_INSENSITIVE_ORDER));
- }
-
- Boolean supportFlag;
- synchronized (supportMap) {
- supportFlag = supportMap.computeIfAbsent(
- name, k -> SecurityProviderRegistrar.super.isSecurityEntitySupported(entityType, name));
- }
-
- return supportFlag;
- }
-
- /**
- * Attempts to see if a provider with this name already registered. If not,
- * then uses reflection API in order to load and instantiate the specified
- * <tt>providerClassName</tt>
- *
- * @param providerClassName The fully-qualified class name to instantiate
- * if a provider not already registered
- * @return The resolved {@link Provider} instance - <B>Note:</B> the result
- * is <U>cached</U> - i.e., successful resolution result will not cause
- * the code to re-resolve the provider
- * @throws ReflectiveOperationException If failed to instantiate the provider
- * @throws UnsupportedOperationException If registrar not supported
- * @see #isSupported()
- * @see Security#getProvider(String)
- * @see #createProviderInstance(String)
- */
- protected Provider getOrCreateProvider(String providerClassName) throws ReflectiveOperationException {
- if (!isSupported()) {
- throw new UnsupportedOperationException("Provider not supported");
- }
-
- Provider provider;
- boolean created = false;
- synchronized (providerHolder) {
- provider = providerHolder.get();
- if (provider != null) {
- return provider;
- }
-
- provider = Security.getProvider(getName());
- if (provider == null) {
- provider = createProviderInstance(providerClassName);
- created = true;
- }
- providerHolder.set(provider);
- }
-
- if (created) {
- log.info("getOrCreateProvider({}) created instance of {}", getName(), providerClassName);
- } else {
- log.info("getOrCreateProvider({}) resolved instance of {}", getName(), provider.getClass().getName());
- }
-
- return provider;
- }
-
- protected Provider createProviderInstance(String providerClassName) throws ReflectiveOperationException {
- return SecurityProviderChoice.createProviderInstance(getClass(), providerClassName);
- }
-
- @Override
- public String toString() {
- return getClass().getSimpleName() + "[" + getName() + "]";
- }
-}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-core/src/main/java/org/apache/sshd/common/util/security/SecurityEntityFactory.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/util/security/SecurityEntityFactory.java b/sshd-core/src/main/java/org/apache/sshd/common/util/security/SecurityEntityFactory.java
deleted file mode 100644
index 94b9454..0000000
--- a/sshd-core/src/main/java/org/apache/sshd/common/util/security/SecurityEntityFactory.java
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.sshd.common.util.security;
-
-import java.lang.reflect.Method;
-import java.security.GeneralSecurityException;
-import java.security.Provider;
-import java.util.Objects;
-
-import org.apache.sshd.common.util.GenericUtils;
-import org.apache.sshd.common.util.ValidateUtils;
-
-/**
- * @param <T> Type of security entity being generated by this factory
- * @author <a href="mailto:dev@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);
- } else if (defaultProvider.isNamedProviderUsed()) {
- return toNamedProviderFactory(entityType, defaultProvider.getName());
- } else {
- return toProviderInstanceFactory(entityType, defaultProvider.getSecurityProvider());
- }
- } else if (registrar.isNamedProviderUsed()) {
- return toNamedProviderFactory(entityType, registrar.getName());
- } else {
- return toProviderInstanceFactory(entityType, registrar.getSecurityProvider());
- }
- }
-
- 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 = GenericUtils.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;
- }
- };
- }
-
- 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 = GenericUtils.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;
- }
- };
- }
-
- 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 = GenericUtils.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;
- }
- };
- }
-}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-core/src/main/java/org/apache/sshd/common/util/security/SecurityProviderChoice.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/util/security/SecurityProviderChoice.java b/sshd-core/src/main/java/org/apache/sshd/common/util/security/SecurityProviderChoice.java
deleted file mode 100644
index c12e747..0000000
--- a/sshd-core/src/main/java/org/apache/sshd/common/util/security/SecurityProviderChoice.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.sshd.common.util.security;
-
-import java.security.Provider;
-import java.util.Objects;
-
-import org.apache.sshd.common.NamedResource;
-import org.apache.sshd.common.util.ValidateUtils;
-import org.apache.sshd.common.util.threads.ThreadUtils;
-
-/**
- * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
- */
-public interface SecurityProviderChoice extends NamedResource {
- SecurityProviderChoice EMPTY = new SecurityProviderChoice() {
- @Override
- public String getName() {
- return null;
- }
-
- @Override
- public boolean isNamedProviderUsed() {
- return false;
- }
-
- @Override
- public Provider getSecurityProvider() {
- return null;
- }
-
- @Override
- public String toString() {
- return "EMPTY";
- }
- };
-
- /**
- * @return {@code true} if to use the provider's name rather than its
- * {@link Provider} instance - default={@code true}.
- */
- default boolean isNamedProviderUsed() {
- return true;
- }
-
- /**
- * @return The security {@link Provider} to use in case {@link #isNamedProviderUsed()}
- * is {@code false}. Can be {@code null} if {@link #isNamedProviderUsed()} is {@code true},
- * but not recommended.
- */
- Provider getSecurityProvider();
-
- static SecurityProviderChoice toSecurityProviderChoice(String name) {
- ValidateUtils.checkNotNullAndNotEmpty(name, "No name provided");
- return new SecurityProviderChoice() {
- private final String s = SecurityProviderChoice.class.getSimpleName() + "[" + name + "]";
-
- @Override
- public String getName() {
- return name;
- }
-
- @Override
- public boolean isNamedProviderUsed() {
- return true;
- }
-
- @Override
- public Provider getSecurityProvider() {
- return null;
- }
-
- @Override
- public String toString() {
- return s;
- }
- };
- }
-
- static SecurityProviderChoice toSecurityProviderChoice(Provider provider) {
- Objects.requireNonNull(provider, "No provider instance");
- return new SecurityProviderChoice() {
- private final String s = SecurityProviderChoice.class.getSimpleName()
- + "[" + Provider.class.getSimpleName() + "]"
- + "[" + provider.getName() + "]";
-
- @Override
- public String getName() {
- return provider.getName();
- }
-
- @Override
- public boolean isNamedProviderUsed() {
- return false;
- }
-
- @Override
- public Provider getSecurityProvider() {
- return provider;
- }
-
- @Override
- public String toString() {
- return s;
- }
- };
- }
-
- static Provider createProviderInstance(Class<?> anchor, String providerClassName)
- throws ReflectiveOperationException {
- return ThreadUtils.createDefaultInstance(anchor, Provider.class, providerClassName);
- }
-}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-core/src/main/java/org/apache/sshd/common/util/security/SecurityProviderRegistrar.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/util/security/SecurityProviderRegistrar.java b/sshd-core/src/main/java/org/apache/sshd/common/util/security/SecurityProviderRegistrar.java
deleted file mode 100644
index 31e428b..0000000
--- a/sshd-core/src/main/java/org/apache/sshd/common/util/security/SecurityProviderRegistrar.java
+++ /dev/null
@@ -1,337 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.sshd.common.util.security;
-
-import java.security.KeyFactory;
-import java.security.KeyPairGenerator;
-import java.security.MessageDigest;
-import java.security.Provider;
-import java.security.Security;
-import java.security.Signature;
-import java.security.cert.CertificateFactory;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.function.Predicate;
-
-import javax.crypto.Cipher;
-import javax.crypto.KeyAgreement;
-import javax.crypto.Mac;
-
-import org.apache.sshd.common.OptionalFeature;
-import org.apache.sshd.common.PropertyResolver;
-import org.apache.sshd.common.PropertyResolverUtils;
-import org.apache.sshd.common.SyspropsMapWrapper;
-import org.apache.sshd.common.util.GenericUtils;
-import org.apache.sshd.common.util.IgnoringEmptyMap;
-import org.apache.sshd.common.util.ValidateUtils;
-
-/**
- * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
- */
-public interface SecurityProviderRegistrar extends SecurityProviderChoice, OptionalFeature, PropertyResolver {
- /**
- * Base name for configuration properties related to security providers
- */
- String CONFIG_PROP_BASE = "org.apache.sshd.security.provider";
-
- /**
- * Property used to configure whether the provider is enabled regardless of
- * whether it is supported.
- *
- * @see #isEnabled()
- */
- String ENABLED_PROPERTY = "enabled";
-
- /**
- * Property used to configure whether to use the provider's name rather than its
- * {@link Provider} instance
- *
- * @see #isNamedProviderUsed()
- */
- String NAMED_PROVIDER_PROPERTY = "useNamed";
-
- String ALL_OPTIONS_VALUE = "all";
- String ALL_OPTIONS_WILDCARD = "*";
-
- String NO_OPTIONS_VALUE = "none";
-
- /**
- * All the entities that are used in calls to {@link #isSecurityEntitySupported(Class, String)}
- */
- List<Class<?>> SECURITY_ENTITIES =
- Collections.unmodifiableList(
- Arrays.asList(
- Cipher.class, KeyFactory.class, MessageDigest.class,
- KeyPairGenerator.class, KeyAgreement.class, Mac.class,
- Signature.class, CertificateFactory.class));
-
- default String getBasePropertyName() {
- return CONFIG_PROP_BASE + "." + getName();
- }
-
- default String getConfigurationPropertyName(String name) {
- return getBasePropertyName() + "." + name;
- }
-
- /**
- * @return {@code true} if the provider is enabled regardless of
- * whether it is supported - default={@code true}. <B>Note:</B>
- * checks if the provider has been <U>programmatically</U> disabled
- * via {@link SecurityUtils#setAPrioriDisabledProvider(String, boolean)}
- * @see #ENABLED_PROPERTY
- */
- default boolean isEnabled() {
- if (SecurityUtils.isAPrioriDisabledProvider(getName())) {
- return false;
- }
-
- return this.getBooleanProperty(getConfigurationPropertyName(ENABLED_PROPERTY), true);
- }
-
- @Override
- default PropertyResolver getParentPropertyResolver() {
- return SyspropsMapWrapper.SYSPROPS_RESOLVER;
- }
-
- @Override
- default Map<String, Object> getProperties() {
- return IgnoringEmptyMap.getInstance();
- }
-
- /**
- * @param transformation The requested {@link Cipher} transformation
- * @return {@code true} if this security provider supports the transformation
- * @see #isSecurityEntitySupported(Class, String)
- */
- default boolean isCipherSupported(String transformation) {
- return isSecurityEntitySupported(Cipher.class, transformation);
- }
-
- /**
- * @param algorithm The {@link KeyFactory} algorithm
- * @return {@code true} if this security provider supports the algorithm
- * @see #isSecurityEntitySupported(Class, String)
- */
- default boolean isKeyFactorySupported(String algorithm) {
- return isSecurityEntitySupported(KeyFactory.class, algorithm);
- }
-
- /**
- * @param algorithm The {@link MessageDigest} algorithm
- * @return {@code true} if this security provider supports the algorithm
- * @see #isSecurityEntitySupported(Class, String)
- */
- default boolean isMessageDigestSupported(String algorithm) {
- return isSecurityEntitySupported(MessageDigest.class, algorithm);
- }
-
- /**
- * @param algorithm The {@link KeyPairGenerator} algorithm
- * @return {@code true} if this security provider supports the algorithm
- * @see #isSecurityEntitySupported(Class, String)
- */
- default boolean isKeyPairGeneratorSupported(String algorithm) {
- return isSecurityEntitySupported(KeyPairGenerator.class, algorithm);
- }
-
- /**
- * @param algorithm The {@link KeyAgreement} algorithm
- * @return {@code true} if this security provider supports the algorithm
- * @see #isSecurityEntitySupported(Class, String)
- */
- default boolean isKeyAgreementSupported(String algorithm) {
- return isSecurityEntitySupported(KeyAgreement.class, algorithm);
- }
-
- /**
- * @param algorithm The {@link Mac} algorithm
- * @return {@code true} if this security provider supports the algorithm
- * @see #isSecurityEntitySupported(Class, String)
- */
- default boolean isMacSupported(String algorithm) {
- return isSecurityEntitySupported(Mac.class, algorithm);
- }
-
- /**
- * @param algorithm The {@link Signature} algorithm
- * @return {@code true} if this security provider supports the algorithm
- * @see #isSecurityEntitySupported(Class, String)
- */
- default boolean isSignatureSupported(String algorithm) {
- return isSecurityEntitySupported(Signature.class, algorithm);
- }
-
- /**
- * @param type The {@link CertificateFactory} type
- * @return {@code true} if this security provider supports the algorithm
- * @see #isSecurityEntitySupported(Class, String)
- */
- default boolean isCertificateFactorySupported(String type) {
- return isSecurityEntitySupported(CertificateFactory.class, type);
- }
-
- /**
- * @param entityType The requested entity type - its simple name serves to
- * build the configuration property name.
- * @return Configuration value to use if no specific configuration provided
- * - default=empty
- * @see #isSecurityEntitySupported(Class, String)
- */
- default String getDefaultSecurityEntitySupportValue(Class<?> entityType) {
- return "";
- }
-
- default boolean isSecurityEntitySupported(Class<?> entityType, String name) {
- String defaultValue = getDefaultSecurityEntitySupportValue(entityType);
- return isSecurityEntitySupported(this, entityType, name, defaultValue);
- }
-
- /**
- * @return {@code true} if to use the provider's name rather than its
- * {@link Provider} instance - default={@code true}
- * @see #NAMED_PROVIDER_PROPERTY
- * @see #getSecurityProvider()
- * @see #registerSecurityProvider(SecurityProviderRegistrar)
- */
- @Override
- default boolean isNamedProviderUsed() {
- return PropertyResolverUtils.getBooleanProperty(this,
- getConfigurationPropertyName(NAMED_PROVIDER_PROPERTY),
- SecurityProviderChoice.super.isNamedProviderUsed());
- }
-
- /**
- * @param v Value to be examined
- * @return {@code true} if the value equals (case insensitive) to
- * either {@link #ALL_OPTIONS_VALUE} or {@link #ALL_OPTIONS_WILDCARD}
- */
- static boolean isAllOptionsValue(String v) {
- return ALL_OPTIONS_VALUE.equalsIgnoreCase(v)
- || ALL_OPTIONS_WILDCARD.equalsIgnoreCase(v);
- }
-
- /**
- * Checks whether the requested entity type algorithm/name is listed
- * as supported by the registrar's configuration
- *
- * @param registrar The {@link SecurityProviderRegistrar}
- * @param entityType The requested entity type - its simple name serves to
- * build the configuration property name.
- * @param name The requested algorithm/name - <B>Note:</B> if the requested
- * entity is a {@link Cipher} then the argument is assumed to be a possible
- * "/" separated transformation and parsed as such in order to
- * retrieve the pure cipher name
- * @param defaultValue Configuration value to use if no specific configuration provided
- * @return {@code true} registrar is supported and the value is listed
- * (case <U>insensitive</U>) or * the property is one of the "all" markers
- * @see SecurityProviderRegistrar#isSupported()
- * @see #isAllOptionsValue(String)
- */
- static boolean isSecurityEntitySupported(SecurityProviderRegistrar registrar, Class<?> entityType, String name, String defaultValue) {
- return Objects.requireNonNull(registrar, "No registrar instance").isSupported()
- && isSecurityEntitySupported(registrar, registrar.getConfigurationPropertyName(entityType.getSimpleName()), entityType, name, defaultValue);
- }
-
- static boolean isSecurityEntitySupported(PropertyResolver resolver, String propName, Class<?> entityType, String name, String defaultValue) {
- if (GenericUtils.isEmpty(name)) {
- return false;
- }
-
- String propValue = resolver.getString(propName);
- if (GenericUtils.isEmpty(propValue)) {
- propValue = defaultValue;
- }
-
- if (NO_OPTIONS_VALUE.equalsIgnoreCase(propValue)) {
- return false;
- }
-
- String[] values = GenericUtils.split(propValue, ',');
- if (GenericUtils.isEmpty(values)) {
- return false;
- }
-
- if ((values.length == 1) && isAllOptionsValue(values[0])) {
- return true;
- }
-
- String effectiveName = getEffectiveSecurityEntityName(entityType, name);
- int index = Arrays.binarySearch(values, effectiveName, String.CASE_INSENSITIVE_ORDER);
- return index >= 0;
- }
-
- /**
- * Determines the "pure" security entity name - e.g., for {@link Cipher}s
- * it strips the trailing transformation specification in order to extract the
- * base cipher name - e.g., "AES/CBC/NoPadding" => "AES"
- *
- * @param entityType The security entity type - ignored if {@code null}
- * @param name The effective name - ignored if {@code null}/empty
- * @return The resolved name
- */
- static String getEffectiveSecurityEntityName(Class<?> entityType, String name) {
- if ((entityType == null) || GenericUtils.isEmpty(name) || (!Cipher.class.isAssignableFrom(entityType))) {
- return name;
- }
-
- int pos = name.indexOf('/');
- return (pos > 0) ? name.substring(0, pos) : name;
- }
-
- /**
- * Attempts to register the security provider represented by the registrar
- * if not already registered. <B>Note:</B> if {@link SecurityProviderRegistrar#isNamedProviderUsed()}
- * is {@code true} then the generated provider will be added to the system's
- * list of known providers.
- *
- * @param registrar The {@link SecurityProviderRegistrar}
- * @return {@code true} if no provider was previously registered
- * @see Security#getProvider(String)
- * @see SecurityProviderRegistrar#getSecurityProvider()
- * @see Security#addProvider(Provider)
- */
- static boolean registerSecurityProvider(SecurityProviderRegistrar registrar) {
- String name = ValidateUtils.checkNotNullAndNotEmpty(
- (registrar == null) ? null : registrar.getName(), "No name for registrar=%s", registrar);
- Provider p = Security.getProvider(name);
- if (p != null) {
- return false;
- }
-
- p = ValidateUtils.checkNotNull(
- registrar.getSecurityProvider(), "No provider created for registrar of %s", name);
- if (registrar.isNamedProviderUsed()) {
- Security.addProvider(p);
- }
-
- return true;
- }
-
- static SecurityProviderRegistrar findSecurityProviderRegistrarBySecurityEntity(
- Predicate<? super SecurityProviderRegistrar> entitySelector,
- Collection<? extends SecurityProviderRegistrar> registrars) {
- return GenericUtils.findFirstMatchingMember(
- r -> r.isEnabled() && r.isSupported() && entitySelector.test(r), registrars);
- }
-}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-core/src/main/java/org/apache/sshd/common/util/security/SecurityUtils.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/util/security/SecurityUtils.java b/sshd-core/src/main/java/org/apache/sshd/common/util/security/SecurityUtils.java
deleted file mode 100644
index ee755e6..0000000
--- a/sshd-core/src/main/java/org/apache/sshd/common/util/security/SecurityUtils.java
+++ /dev/null
@@ -1,759 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.sshd.common.util.security;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.math.BigInteger;
-import java.nio.file.Path;
-import java.security.GeneralSecurityException;
-import java.security.InvalidKeyException;
-import java.security.Key;
-import java.security.KeyFactory;
-import java.security.KeyPair;
-import java.security.KeyPairGenerator;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.security.NoSuchProviderException;
-import java.security.PrivateKey;
-import java.security.PublicKey;
-import java.security.Signature;
-import java.security.cert.CertificateFactory;
-import java.security.spec.InvalidKeySpecException;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Set;
-import java.util.TreeMap;
-import java.util.TreeSet;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.concurrent.atomic.AtomicReference;
-import java.util.function.Predicate;
-
-import javax.crypto.Cipher;
-import javax.crypto.KeyAgreement;
-import javax.crypto.Mac;
-import javax.crypto.spec.DHParameterSpec;
-
-import org.apache.sshd.common.config.keys.FilePasswordProvider;
-import org.apache.sshd.common.config.keys.KeyUtils;
-import org.apache.sshd.common.config.keys.PrivateKeyEntryDecoder;
-import org.apache.sshd.common.config.keys.PublicKeyEntryDecoder;
-import org.apache.sshd.common.config.keys.loader.KeyPairResourceParser;
-import org.apache.sshd.common.config.keys.loader.openssh.OpenSSHKeyPairResourceParser;
-import org.apache.sshd.common.config.keys.loader.pem.PEMResourceParserUtils;
-import org.apache.sshd.common.keyprovider.KeyPairProvider;
-import org.apache.sshd.common.random.JceRandomFactory;
-import org.apache.sshd.common.random.RandomFactory;
-import org.apache.sshd.common.util.GenericUtils;
-import org.apache.sshd.common.util.ValidateUtils;
-import org.apache.sshd.common.util.buffer.Buffer;
-import org.apache.sshd.common.util.security.bouncycastle.BouncyCastleGeneratorHostKeyProvider;
-import org.apache.sshd.common.util.security.bouncycastle.BouncyCastleKeyPairResourceParser;
-import org.apache.sshd.common.util.security.bouncycastle.BouncyCastleRandomFactory;
-import org.apache.sshd.common.util.security.eddsa.EdDSASecurityProviderUtils;
-import org.apache.sshd.common.util.threads.ThreadUtils;
-import org.apache.sshd.server.keyprovider.AbstractGeneratorHostKeyProvider;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Specific security providers related code
- *
- * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
- */
-public final class SecurityUtils {
- /**
- * Bouncycastle JCE provider name
- */
- public static final String BOUNCY_CASTLE = "BC";
-
- /**
- * EDDSA support - should match {@code EdDSAKey.KEY_ALGORITHM}
- */
- public static final String EDDSA = "EdDSA";
-
- // A copy-paste from the original, but we don't want to drag the classes into the classpath
- // See EdDSAEngine.SIGNATURE_ALGORITHM
- public static final String CURVE_ED25519_SHA512 = "NONEwithEdDSA";
-
- /**
- * System property used to configure the value for the maximum supported Diffie-Hellman
- * Group Exchange key size. If not set, then an internal auto-discovery mechanism is employed.
- * If set to negative value then Diffie-Hellman Group Exchange is disabled. If set to a
- * negative value then Diffie-Hellman Group Exchange is disabled
- */
- public static final String MAX_DHGEX_KEY_SIZE_PROP = "org.apache.sshd.maxDHGexKeySize";
-
- /**
- * The min. key size value used for testing whether Diffie-Hellman Group Exchange
- * is supported or not. According to <A HREF="https://tools.ietf.org/html/rfc4419">RFC 4419</A>
- * section 3: "Servers and clients SHOULD support groups with a modulus length of k
- * bits, where 1024 <= k <= 8192".
- * </code>
- */
- public static final int MIN_DHGEX_KEY_SIZE = 1024;
- // Keys of size > 1024 are not support by default with JCE
- public static final int DEFAULT_DHGEX_KEY_SIZE = MIN_DHGEX_KEY_SIZE;
- public static final int PREFERRED_DHGEX_KEY_SIZE = 4096;
- public static final int MAX_DHGEX_KEY_SIZE = 8192;
-
- /**
- * Comma separated list of fully qualified {@link SecurityProviderRegistrar}s
- * to automatically register
- */
- public static final String SECURITY_PROVIDER_REGISTRARS = "org.apache.sshd.security.registrars";
- public static final List<String> DEFAULT_SECURITY_PROVIDER_REGISTRARS =
- Collections.unmodifiableList(
- Arrays.asList(
- "org.apache.sshd.common.util.security.bouncycastle.BouncyCastleSecurityProviderRegistrar",
- "org.apache.sshd.common.util.security.eddsa.EdDSASecurityProviderRegistrar"));
-
-
- /**
- * System property used to control whether to automatically register the
- * {@code Bouncyastle} JCE provider
- * @deprecated Please use "org.apache.sshd.security.provider.BC.enabled"
- */
- @Deprecated
- public static final String REGISTER_BOUNCY_CASTLE_PROP = "org.apache.sshd.registerBouncyCastle";
-
- /**
- * System property used to control whether Elliptic Curves are supported or not.
- * If not set then the support is auto-detected. <B>Note:</B> if set to {@code true}
- * it is up to the user to make sure that indeed there is a provider for them
- */
- public static final String ECC_SUPPORTED_PROP = "org.apache.sshd.eccSupport";
-
- /**
- * System property used to decide whether EDDSA curves are supported or not
- * (in addition or even in spite of {@link #isEDDSACurveSupported()}). If not
- * set or set to {@code true}, then the existence of the optional support classes
- * determines the support.
- * @deprecated Please use "org.apache.sshd.security.provider.EdDSA.enabled&qupt;
- */
- @Deprecated
- public static final String EDDSA_SUPPORTED_PROP = "org.apache.sshd.eddsaSupport";
-
- public static final String PROP_DEFAULT_SECURITY_PROVIDER = "org.apache.sshd.security.defaultProvider";
-
- private static final AtomicInteger MAX_DHG_KEY_SIZE_HOLDER = new AtomicInteger(0);
-
- /*
- * NOTE: we use a LinkedHashMap in order to preserve registration order
- * in case several providers support the same security entity
- */
- private static final Map<String, SecurityProviderRegistrar> REGISTERED_PROVIDERS = new LinkedHashMap<>();
- private static final AtomicReference<KeyPairResourceParser> KEYPAIRS_PARSER_HODLER = new AtomicReference<>();
- // 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<>();
-
- private static final AtomicReference<SecurityProviderChoice> DEFAULT_PROVIDER_HOLDER = new AtomicReference<>();
-
- private static Boolean hasEcc;
-
- private SecurityUtils() {
- throw new UnsupportedOperationException("No instance");
- }
-
- /**
- * @param name The provider's name - never {@code null}/empty
- * @return {@code true} if the provider is marked as disabled a-priori
- * @see #setAPrioriDisabledProvider(String, boolean)
- */
- public static boolean isAPrioriDisabledProvider(String name) {
- ValidateUtils.checkNotNullAndNotEmpty(name, "No provider name specified");
- synchronized (APRIORI_DISABLED_PROVIDERS) {
- return APRIORI_DISABLED_PROVIDERS.contains(name);
- }
- }
-
- /**
- * Marks a provider's registrar as "a-priori" <U>programatically</U>
- * so that when its {@link SecurityProviderRegistrar#isEnabled()} is eventually
- * consulted it will return {@code false} regardless of the configured value for
- * the specific provider registrar instance. <B>Note:</B> has no effect if the
- * provider has already been registered.
- *
- * @param name The provider's name - never {@code null}/empty
- * @param disabled {@code true} whether to disable it a-priori
- * @see #isAPrioriDisabledProvider(String)
- */
- public static void setAPrioriDisabledProvider(String name, boolean disabled) {
- ValidateUtils.checkNotNullAndNotEmpty(name, "No provider name specified");
- synchronized (APRIORI_DISABLED_PROVIDERS) {
- if (disabled) {
- APRIORI_DISABLED_PROVIDERS.add(name);
- } else {
- APRIORI_DISABLED_PROVIDERS.remove(name);
- }
- }
- }
-
- /**
- * @return A <U>copy</U> if the current a-priori disabled providers names
- */
- public static Set<String> getAPrioriDisabledProviders() {
- synchronized (APRIORI_DISABLED_PROVIDERS) {
- return new TreeSet<>(APRIORI_DISABLED_PROVIDERS);
- }
- }
-
- /**
- * @return {@code true} if Elliptic Curve Cryptography is supported
- * @see #ECC_SUPPORTED_PROP
- */
- public static boolean isECCSupported() {
- if (hasEcc == null) {
- String propValue = System.getProperty(ECC_SUPPORTED_PROP);
- if (GenericUtils.isEmpty(propValue)) {
- try {
- getKeyPairGenerator(KeyUtils.EC_ALGORITHM);
- hasEcc = Boolean.TRUE;
- } catch (Throwable t) {
- hasEcc = Boolean.FALSE;
- }
- } else {
- Logger logger = LoggerFactory.getLogger(SecurityUtils.class);
- logger.info("Override ECC support value: " + propValue);
- hasEcc = Boolean.valueOf(propValue);
- }
- }
-
- return hasEcc;
- }
-
- /**
- * @return {@code true} if Diffie-Hellman Group Exchange is supported
- * @see #getMaxDHGroupExchangeKeySize()
- */
- public static boolean isDHGroupExchangeSupported() {
- return getMaxDHGroupExchangeKeySize() > 0;
- }
-
- /**
- * @param keySize The expected key size
- * @return {@code true} if Oakely Diffie-Hellman Group Exchange is supported
- * for the specified key size
- * @see #getMaxDHGroupExchangeKeySize()
- */
- public static boolean isDHOakelyGroupSupported(int keySize) {
- return getMaxDHGroupExchangeKeySize() >= keySize;
- }
-
- /**
- * @return The maximum supported Diffie-Hellman Group Exchange key size,
- * or non-positive if not supported
- */
- public static int getMaxDHGroupExchangeKeySize() {
- int maxSupportedKeySize;
- synchronized (MAX_DHG_KEY_SIZE_HOLDER) {
- maxSupportedKeySize = MAX_DHG_KEY_SIZE_HOLDER.get();
- if (maxSupportedKeySize != 0) { // 1st time we are called ?
- return maxSupportedKeySize;
- }
-
- String propValue = System.getProperty(MAX_DHGEX_KEY_SIZE_PROP);
- if (GenericUtils.isEmpty(propValue)) {
- maxSupportedKeySize = -1;
- // Go down from max. to min. to ensure we stop at 1st maximum value success
- for (int testKeySize = MAX_DHGEX_KEY_SIZE; testKeySize >= MIN_DHGEX_KEY_SIZE; testKeySize -= 1024) {
- if (isDHGroupExchangeSupported(testKeySize)) {
- maxSupportedKeySize = testKeySize;
- break;
- }
- }
- } else {
- Logger logger = LoggerFactory.getLogger(SecurityUtils.class);
- logger.info("Override max. DH group exchange key size: " + propValue);
- maxSupportedKeySize = Integer.parseInt(propValue);
- // negative is OK - means user wants to disable DH group exchange
- ValidateUtils.checkTrue(maxSupportedKeySize != 0,
- "Configured " + MAX_DHGEX_KEY_SIZE_PROP + " value must be non-zero: %d", maxSupportedKeySize);
- }
-
- MAX_DHG_KEY_SIZE_HOLDER.set(maxSupportedKeySize);
- }
-
- return maxSupportedKeySize;
- }
-
- /**
- * Set programmatically the reported value for {@link #getMaxDHGroupExchangeKeySize()}
- * @param keySize The reported key size - if zero, then it will be auto-detected, if
- * negative then DH group exchange will be disabled
- */
- public static void setMaxDHGroupExchangeKeySize(int keySize) {
- synchronized (MAX_DHG_KEY_SIZE_HOLDER) {
- MAX_DHG_KEY_SIZE_HOLDER.set(keySize);
- }
- }
-
- public static boolean isDHGroupExchangeSupported(int maxKeySize) {
- ValidateUtils.checkTrue(maxKeySize > Byte.SIZE, "Invalid max. key size: %d", maxKeySize);
-
- try {
- BigInteger r = new BigInteger("0").setBit(maxKeySize - 1);
- DHParameterSpec dhSkipParamSpec = new DHParameterSpec(r, r);
- KeyPairGenerator kpg = getKeyPairGenerator("DH");
- kpg.initialize(dhSkipParamSpec);
- return true;
- } catch (GeneralSecurityException t) {
- return false;
- }
- }
-
- public static SecurityProviderChoice getDefaultProviderChoice() {
- SecurityProviderChoice choice;
- synchronized (DEFAULT_PROVIDER_HOLDER) {
- choice = DEFAULT_PROVIDER_HOLDER.get();
- if (choice != null) {
- return choice;
- }
-
- String name = System.getProperty(PROP_DEFAULT_SECURITY_PROVIDER);
- choice = (GenericUtils.isEmpty(name) || "none".equalsIgnoreCase(name))
- ? SecurityProviderChoice.EMPTY
- : SecurityProviderChoice.toSecurityProviderChoice(name);
- DEFAULT_PROVIDER_HOLDER.set(choice);
- }
-
- return choice;
- }
-
- public static void setDefaultProviderChoice(SecurityProviderChoice choice) {
- DEFAULT_PROVIDER_HOLDER.set(choice);
- }
-
- /**
- * @return A <U>copy</U> of the currently registered security providers
- */
- public static Set<String> getRegisteredProviders() {
- // returns a COPY of the providers in order to avoid modifications
- synchronized (REGISTERED_PROVIDERS) {
- return new TreeSet<>(REGISTERED_PROVIDERS.keySet());
- }
- }
-
- public static boolean isBouncyCastleRegistered() {
- register();
- return isProviderRegistered(BOUNCY_CASTLE);
- }
-
- public static boolean isProviderRegistered(String provider) {
- return getRegisteredProvider(provider) != null;
- }
-
- public static SecurityProviderRegistrar getRegisteredProvider(String provider) {
- ValidateUtils.checkNotNullAndNotEmpty(provider, "No provider name specified");
- synchronized (REGISTERED_PROVIDERS) {
- return REGISTERED_PROVIDERS.get(provider);
- }
- }
-
- public static boolean isRegistrationCompleted() {
- return REGISTRATION_STATE_HOLDER.get();
- }
-
- private static void register() {
- synchronized (REGISTRATION_STATE_HOLDER) {
- if (REGISTRATION_STATE_HOLDER.get()) {
- return;
- }
-
- String regsList = System.getProperty(SECURITY_PROVIDER_REGISTRARS,
- GenericUtils.join(DEFAULT_SECURITY_PROVIDER_REGISTRARS, ','));
- boolean bouncyCastleRegistered = false;
- if ((GenericUtils.length(regsList) > 0) && (!"none".equalsIgnoreCase(regsList))) {
- String[] classes = GenericUtils.split(regsList, ',');
- Logger logger = LoggerFactory.getLogger(SecurityUtils.class);
- boolean debugEnabled = logger.isDebugEnabled();
- for (String registrarClass : classes) {
- SecurityProviderRegistrar r;
- try {
- r = ThreadUtils.createDefaultInstance(SecurityUtils.class, SecurityProviderRegistrar.class, registrarClass);
- } catch (ReflectiveOperationException t) {
- Throwable e = GenericUtils.peelException(t);
- logger.error("Failed ({}) to create default {} registrar instance: {}",
- e.getClass().getSimpleName(), registrarClass, e.getMessage());
- if (e instanceof RuntimeException) {
- throw (RuntimeException) e;
- } else if (e instanceof Error) {
- throw (Error) e;
- } else {
- throw new RuntimeException(e);
- }
- }
-
- String name = r.getName();
- SecurityProviderRegistrar registeredInstance = registerSecurityProvider(r);
- if (registeredInstance == null) {
- if (debugEnabled) {
- logger.debug("register({}) not registered - enabled={}, supported={}",
- name, r.isEnabled(), r.isSupported());
- }
- continue; // provider not registered - e.g., disabled, not supported
- }
-
- if (BOUNCY_CASTLE.equalsIgnoreCase(name)) {
- bouncyCastleRegistered = true;
- }
- }
- }
-
- SecurityProviderChoice choice = getDefaultProviderChoice();
- if (((choice == null) || (choice == SecurityProviderChoice.EMPTY)) && bouncyCastleRegistered) {
- setDefaultProviderChoice(SecurityProviderChoice.toSecurityProviderChoice(BOUNCY_CASTLE));
- }
-
- REGISTRATION_STATE_HOLDER.set(true);
- }
- }
-
- /**
- * @param registrar The registrar instance to register
- * @return The registered instance - may be different than required
- * if already registered. Returns {@code null} if not already registered
- * and not enabled or not supported registrar.
- */
- public static SecurityProviderRegistrar registerSecurityProvider(SecurityProviderRegistrar registrar) {
- Objects.requireNonNull(registrar, "No registrar instance to register");
- String name = registrar.getName();
- SecurityProviderRegistrar registeredInstance = getRegisteredProvider(name);
- if ((registeredInstance == null) && registrar.isEnabled() && registrar.isSupported()) {
- try {
- SecurityProviderRegistrar.registerSecurityProvider(registrar);
- synchronized (REGISTERED_PROVIDERS) {
- REGISTERED_PROVIDERS.put(name, registrar);
- }
-
- return registrar;
- } catch (Throwable t) {
- Logger logger = LoggerFactory.getLogger(SecurityUtils.class);
- logger.error("Failed {} to register {} as a JCE provider: {}",
- t.getClass().getSimpleName(), name, t.getMessage());
- throw new RuntimeException("Failed to register " + name + " as a JCE provider", t);
- }
- }
-
- return registeredInstance;
- }
-
- ///////////////// Bouncycastle specific implementations //////////////////
-
- /* -------------------------------------------------------------------- */
-
- /**
- * @param resourceKey An identifier of the key being loaded - used as
- * argument to the {@link FilePasswordProvider#getPassword(String)}
- * invocation
- * @param inputStream The {@link InputStream} for the <U>private</U> key
- * @param provider A {@link FilePasswordProvider} - may be {@code null}
- * if the loaded key is <U>guaranteed</U> not to be encrypted
- * @return The loaded {@link KeyPair}
- * @throws IOException If failed to read/parse the input stream
- * @throws GeneralSecurityException If failed to generate the keys
- */
- public static KeyPair loadKeyPairIdentity(String resourceKey, InputStream inputStream, FilePasswordProvider provider)
- throws IOException, GeneralSecurityException {
- KeyPairResourceParser parser = getKeyPairResourceParser();
- if (parser == null) {
- throw new NoSuchProviderException("No registered key-pair resource parser");
- }
-
- Collection<KeyPair> ids = parser.loadKeyPairs(resourceKey, provider, inputStream);
- int numLoaded = GenericUtils.size(ids);
- if (numLoaded <= 0) {
- throw new InvalidKeyException("Unsupported private key file format: " + resourceKey);
- }
- if (numLoaded != 1) {
- throw new InvalidKeySpecException("Multiple private key pairs N/A: " + resourceKey);
- }
-
- return ids.iterator().next();
- }
-
- /* -------------------------------------------------------------------- */
-
- public static AbstractGeneratorHostKeyProvider createGeneratorHostKeyProvider(Path path) {
- ValidateUtils.checkTrue(isBouncyCastleRegistered(), "BouncyCastle not registered");
- return new BouncyCastleGeneratorHostKeyProvider(path);
- }
-
- public static KeyPairResourceParser getBouncycastleKeyPairResourceParser() {
- ValidateUtils.checkTrue(isBouncyCastleRegistered(), "BouncyCastle not registered");
- return BouncyCastleKeyPairResourceParser.INSTANCE;
- }
-
- /**
- * @return If {@link #isBouncyCastleRegistered()} then a {@link BouncyCastleRandomFactory}
- * instance, otherwise a {@link JceRandomFactory} one
- */
- public static RandomFactory getRandomFactory() {
- if (isBouncyCastleRegistered()) {
- return BouncyCastleRandomFactory.INSTANCE;
- } else {
- return JceRandomFactory.INSTANCE;
- }
- }
-
- ///////////////////////////// ED25519 support ///////////////////////////////
-
- /**
- * @return {@code true} if EDDSA curves (e.g., {@code ed25519}) are supported
- */
- public static boolean isEDDSACurveSupported() {
- register();
-
- SecurityProviderRegistrar r = getRegisteredProvider(EDDSA);
- return (r != null) && r.isEnabled() && r.isSupported();
- }
-
- /* -------------------------------------------------------------------- */
-
- public static PublicKeyEntryDecoder<? extends PublicKey, ? extends PrivateKey> getEDDSAPublicKeyEntryDecoder() {
- if (!isEDDSACurveSupported()) {
- throw new UnsupportedOperationException(EDDSA + " provider N/A");
- }
-
- return EdDSASecurityProviderUtils.getEDDSAPublicKeyEntryDecoder();
- }
-
- public static PrivateKeyEntryDecoder<? extends PublicKey, ? extends PrivateKey> getOpenSSHEDDSAPrivateKeyEntryDecoder() {
- if (!isEDDSACurveSupported()) {
- throw new UnsupportedOperationException(EDDSA + " provider N/A");
- }
-
- return EdDSASecurityProviderUtils.getOpenSSHEDDSAPrivateKeyEntryDecoder();
- }
-
- public static org.apache.sshd.common.signature.Signature getEDDSASigner() {
- if (isEDDSACurveSupported()) {
- return EdDSASecurityProviderUtils.getEDDSASignature();
- }
-
- throw new UnsupportedOperationException(EDDSA + " Signer not available");
- }
-
- public static int getEDDSAKeySize(Key key) {
- return EdDSASecurityProviderUtils.getEDDSAKeySize(key);
- }
-
- public static Class<? extends PublicKey> getEDDSAPublicKeyType() {
- return isEDDSACurveSupported() ? EdDSASecurityProviderUtils.getEDDSAPublicKeyType() : PublicKey.class;
- }
-
- public static Class<? extends PrivateKey> getEDDSAPrivateKeyType() {
- return isEDDSACurveSupported() ? EdDSASecurityProviderUtils.getEDDSAPrivateKeyType() : PrivateKey.class;
- }
-
- public static boolean compareEDDSAPPublicKeys(PublicKey k1, PublicKey k2) {
- return isEDDSACurveSupported() ? EdDSASecurityProviderUtils.compareEDDSAPPublicKeys(k1, k2) : false;
- }
-
- public static boolean compareEDDSAPrivateKeys(PrivateKey k1, PrivateKey k2) {
- return isEDDSACurveSupported() ? EdDSASecurityProviderUtils.compareEDDSAPrivateKeys(k1, k2) : false;
- }
-
- public static PublicKey recoverEDDSAPublicKey(PrivateKey key) throws GeneralSecurityException {
- if (!isEDDSACurveSupported()) {
- throw new NoSuchAlgorithmException(EDDSA + " provider not supported");
- }
-
- return EdDSASecurityProviderUtils.recoverEDDSAPublicKey(key);
- }
-
- public static PublicKey generateEDDSAPublicKey(String keyType, byte[] seed) throws GeneralSecurityException {
- if (!KeyPairProvider.SSH_ED25519.equals(keyType)) {
- throw new InvalidKeyException("Unsupported key type: " + keyType);
- }
-
- if (!isEDDSACurveSupported()) {
- throw new NoSuchAlgorithmException(EDDSA + " provider not supported");
- }
-
- return EdDSASecurityProviderUtils.generateEDDSAPublicKey(seed);
- }
-
- public static <B extends Buffer> B putRawEDDSAPublicKey(B buffer, PublicKey key) {
- if (!isEDDSACurveSupported()) {
- throw new UnsupportedOperationException(EDDSA + " provider not supported");
- }
-
- return EdDSASecurityProviderUtils.putRawEDDSAPublicKey(buffer, key);
- }
-
- public static <B extends Buffer> B putEDDSAKeyPair(B buffer, KeyPair kp) {
- return putEDDSAKeyPair(buffer, Objects.requireNonNull(kp, "No key pair").getPublic(), kp.getPrivate());
- }
-
- public static <B extends Buffer> B putEDDSAKeyPair(B buffer, PublicKey pubKey, PrivateKey prvKey) {
- if (!isEDDSACurveSupported()) {
- throw new UnsupportedOperationException(EDDSA + " provider not supported");
- }
-
- return EdDSASecurityProviderUtils.putEDDSAKeyPair(buffer, pubKey, prvKey);
- }
-
- public static KeyPair extractEDDSAKeyPair(Buffer buffer, String keyType) throws GeneralSecurityException {
- if (!KeyPairProvider.SSH_ED25519.equals(keyType)) {
- throw new InvalidKeyException("Unsupported key type: " + keyType);
- }
-
- if (!isEDDSACurveSupported()) {
- throw new NoSuchAlgorithmException(EDDSA + " provider not supported");
- }
-
- throw new GeneralSecurityException("Full SSHD-440 implementation N/A");
- }
-
- //////////////////////////////////////////////////////////////////////////
-
- public static KeyPairResourceParser getKeyPairResourceParser() {
- KeyPairResourceParser parser;
- synchronized (KEYPAIRS_PARSER_HODLER) {
- parser = KEYPAIRS_PARSER_HODLER.get();
- if (parser != null) {
- return parser;
- }
-
- parser = KeyPairResourceParser.aggregate(
- PEMResourceParserUtils.PROXY,
- OpenSSHKeyPairResourceParser.INSTANCE);
- KEYPAIRS_PARSER_HODLER.set(parser);
- }
-
- return parser;
- }
-
- /**
- * @param parser The system-wide {@code KeyPairResourceParser} to use.
- * If set to {@code null}, then the default parser will be re-constructed
- * on next call to {@link #getKeyPairResourceParser()}
- */
- public static void setKeyPairResourceParser(KeyPairResourceParser parser) {
- synchronized (KEYPAIRS_PARSER_HODLER) {
- KEYPAIRS_PARSER_HODLER.set(parser);
- }
- }
-
- //////////////////////////// Security entities factories /////////////////////////////
-
- @SuppressWarnings("unchecked")
- public static <T> SecurityEntityFactory<T> resolveSecurityEntityFactory(
- Class<T> 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;
- synchronized (factoriesMap) {
- factoryEntry =
- factoriesMap.computeIfAbsent(
- effectiveName, k -> createSecurityEntityFactory(entityType, entitySelector));
- }
-
- return (SecurityEntityFactory<T>) factoryEntry;
- }
-
- public static <T> SecurityEntityFactory<T> createSecurityEntityFactory(
- Class<T> entityType, Predicate<? super SecurityProviderRegistrar> entitySelector) {
- register();
-
- SecurityProviderRegistrar registrar;
- synchronized (REGISTERED_PROVIDERS) {
- registrar =
- SecurityProviderRegistrar.findSecurityProviderRegistrarBySecurityEntity(
- entitySelector, REGISTERED_PROVIDERS.values());
- }
-
- try {
- return SecurityEntityFactory.toFactory(entityType, registrar, getDefaultProviderChoice());
- } catch (ReflectiveOperationException t) {
- Throwable e = GenericUtils.peelException(t);
- if (e instanceof RuntimeException) {
- throw (RuntimeException) e;
- } else if (e instanceof Error) {
- throw (Error) e;
- } else {
- throw new RuntimeException(e);
- }
- }
- }
-
- public static KeyFactory getKeyFactory(String algorithm) throws GeneralSecurityException {
- SecurityEntityFactory<KeyFactory> factory =
- resolveSecurityEntityFactory(KeyFactory.class, algorithm, r -> r.isKeyFactorySupported(algorithm));
- return factory.getInstance(algorithm);
- }
-
- public static Cipher getCipher(String transformation) throws GeneralSecurityException {
- SecurityEntityFactory<Cipher> factory =
- resolveSecurityEntityFactory(Cipher.class, transformation, r -> r.isCipherSupported(transformation));
- return factory.getInstance(transformation);
- }
-
- public static MessageDigest getMessageDigest(String algorithm) throws GeneralSecurityException {
- SecurityEntityFactory<MessageDigest> factory =
- resolveSecurityEntityFactory(MessageDigest.class, algorithm, r -> r.isMessageDigestSupported(algorithm));
- return factory.getInstance(algorithm);
- }
-
- public static KeyPairGenerator getKeyPairGenerator(String algorithm) throws GeneralSecurityException {
- SecurityEntityFactory<KeyPairGenerator> factory =
- resolveSecurityEntityFactory(KeyPairGenerator.class, algorithm, r -> r.isKeyPairGeneratorSupported(algorithm));
- return factory.getInstance(algorithm);
- }
-
- public static KeyAgreement getKeyAgreement(String algorithm) throws GeneralSecurityException {
- SecurityEntityFactory<KeyAgreement> factory =
- resolveSecurityEntityFactory(KeyAgreement.class, algorithm, r -> r.isKeyAgreementSupported(algorithm));
- return factory.getInstance(algorithm);
- }
-
- public static Mac getMac(String algorithm) throws GeneralSecurityException {
- SecurityEntityFactory<Mac> factory =
- resolveSecurityEntityFactory(Mac.class, algorithm, r -> r.isMacSupported(algorithm));
- return factory.getInstance(algorithm);
- }
-
- public static Signature getSignature(String algorithm) throws GeneralSecurityException {
- SecurityEntityFactory<Signature> factory =
- resolveSecurityEntityFactory(Signature.class, algorithm, r -> r.isSignatureSupported(algorithm));
- return factory.getInstance(algorithm);
- }
-
- public static CertificateFactory getCertificateFactory(String type) throws GeneralSecurityException {
- SecurityEntityFactory<CertificateFactory> factory =
- resolveSecurityEntityFactory(CertificateFactory.class, type, r -> r.isCertificateFactorySupported(type));
- return factory.getInstance(type);
- }
-}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-core/src/main/java/org/apache/sshd/common/util/security/bouncycastle/BouncyCastleGeneratorHostKeyProvider.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/util/security/bouncycastle/BouncyCastleGeneratorHostKeyProvider.java b/sshd-core/src/main/java/org/apache/sshd/common/util/security/bouncycastle/BouncyCastleGeneratorHostKeyProvider.java
deleted file mode 100644
index 3716719..0000000
--- a/sshd-core/src/main/java/org/apache/sshd/common/util/security/bouncycastle/BouncyCastleGeneratorHostKeyProvider.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.sshd.common.util.security.bouncycastle;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-import java.nio.charset.StandardCharsets;
-import java.nio.file.Path;
-import java.security.GeneralSecurityException;
-import java.security.KeyPair;
-
-import org.apache.sshd.server.keyprovider.AbstractGeneratorHostKeyProvider;
-
-/**
- * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
- */
-public class BouncyCastleGeneratorHostKeyProvider extends AbstractGeneratorHostKeyProvider {
- public BouncyCastleGeneratorHostKeyProvider(Path path) {
- setPath(path);
- }
-
- @SuppressWarnings("deprecation")
- @Override
- protected void doWriteKeyPair(String resourceKey, KeyPair kp, OutputStream outputStream) throws IOException, GeneralSecurityException {
- try (org.bouncycastle.openssl.PEMWriter w =
- new org.bouncycastle.openssl.PEMWriter(new OutputStreamWriter(outputStream, StandardCharsets.UTF_8))) {
- w.writeObject(kp);
- w.flush();
- }
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-core/src/main/java/org/apache/sshd/common/util/security/bouncycastle/BouncyCastleKeyPairResourceParser.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/util/security/bouncycastle/BouncyCastleKeyPairResourceParser.java b/sshd-core/src/main/java/org/apache/sshd/common/util/security/bouncycastle/BouncyCastleKeyPairResourceParser.java
deleted file mode 100644
index 4c8722a..0000000
--- a/sshd-core/src/main/java/org/apache/sshd/common/util/security/bouncycastle/BouncyCastleKeyPairResourceParser.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.sshd.common.util.security.bouncycastle;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.nio.charset.StandardCharsets;
-import java.security.GeneralSecurityException;
-import java.security.KeyPair;
-import java.security.NoSuchProviderException;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-
-import org.apache.sshd.common.config.keys.FilePasswordProvider;
-import org.apache.sshd.common.config.keys.loader.AbstractKeyPairResourceParser;
-import org.apache.sshd.common.util.ValidateUtils;
-import org.apache.sshd.common.util.io.IoUtils;
-import org.apache.sshd.common.util.security.SecurityProviderRegistrar;
-import org.apache.sshd.common.util.security.SecurityUtils;
-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.JcePEMDecryptorProviderBuilder;
-
-/**
- * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
- */
-public class BouncyCastleKeyPairResourceParser extends AbstractKeyPairResourceParser {
- public static final List<String> BEGINNERS =
- Collections.unmodifiableList(
- Arrays.asList(
- "BEGIN RSA PRIVATE KEY",
- "BEGIN DSA PRIVATE KEY",
- "BEGIN EC PRIVATE KEY"));
-
- public static final List<String> ENDERS =
- Collections.unmodifiableList(
- Arrays.asList(
- "END RSA PRIVATE KEY",
- "END DSA PRIVATE KEY",
- "END EC PRIVATE KEY"));
-
- public static final BouncyCastleKeyPairResourceParser INSTANCE = new BouncyCastleKeyPairResourceParser();
-
- public BouncyCastleKeyPairResourceParser() {
- super(BEGINNERS, ENDERS);
- }
-
- @Override
- public Collection<KeyPair> extractKeyPairs(
- String resourceKey, String beginMarker, String endMarker, FilePasswordProvider passwordProvider, List<String> lines)
- throws IOException, GeneralSecurityException {
- StringBuilder writer = new StringBuilder(beginMarker.length() + endMarker.length() + lines.size() * 80);
- writer.append(beginMarker).append(IoUtils.EOL);
- lines.forEach(l -> writer.append(l).append(IoUtils.EOL));
- writer.append(endMarker).append(IoUtils.EOL);
-
- String data = writer.toString();
- byte[] dataBytes = data.getBytes(StandardCharsets.UTF_8);
- try (InputStream bais = new ByteArrayInputStream(dataBytes)) {
- return extractKeyPairs(resourceKey, beginMarker, endMarker, passwordProvider, bais);
- }
- }
-
- @Override
- public Collection<KeyPair> extractKeyPairs(
- String resourceKey, String beginMarker, String endMarker, FilePasswordProvider passwordProvider, InputStream stream)
- throws IOException, GeneralSecurityException {
- KeyPair kp = loadKeyPair(resourceKey, stream, passwordProvider);
- return (kp == null) ? Collections.emptyList() : Collections.singletonList(kp);
- }
-
- public static KeyPair loadKeyPair(String resourceKey, InputStream inputStream, FilePasswordProvider provider)
- throws IOException, GeneralSecurityException {
- try (PEMParser r = new PEMParser(new InputStreamReader(inputStream, StandardCharsets.UTF_8))) {
- Object o = r.readObject();
-
- SecurityProviderRegistrar registrar = SecurityUtils.getRegisteredProvider(SecurityUtils.BOUNCY_CASTLE);
- if (registrar == null) {
- throw new NoSuchProviderException(SecurityUtils.BOUNCY_CASTLE + " registrar not available");
- }
-
- JcaPEMKeyConverter pemConverter = new JcaPEMKeyConverter();
- if (registrar.isNamedProviderUsed()) {
- pemConverter.setProvider(registrar.getName());
- } else {
- pemConverter.setProvider(registrar.getSecurityProvider());
- }
- if (o instanceof PEMEncryptedKeyPair) {
- ValidateUtils.checkNotNull(provider, "No password provider for resource=%s", resourceKey);
-
- String password = ValidateUtils.checkNotNullAndNotEmpty(provider.getPassword(resourceKey), "No password provided for resource=%s", resourceKey);
- JcePEMDecryptorProviderBuilder decryptorBuilder = new JcePEMDecryptorProviderBuilder();
- PEMDecryptorProvider pemDecryptor = decryptorBuilder.build(password.toCharArray());
- o = ((PEMEncryptedKeyPair) o).decryptKeyPair(pemDecryptor);
- }
-
- if (o instanceof PEMKeyPair) {
- return pemConverter.getKeyPair((PEMKeyPair) o);
- } else if (o instanceof KeyPair) {
- return (KeyPair) o;
- } else {
- throw new IOException("Failed to read " + resourceKey + " - unknown result object: " + o);
- }
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-core/src/main/java/org/apache/sshd/common/util/security/bouncycastle/BouncyCastleRandom.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/util/security/bouncycastle/BouncyCastleRandom.java b/sshd-core/src/main/java/org/apache/sshd/common/util/security/bouncycastle/BouncyCastleRandom.java
deleted file mode 100644
index 36c23e7..0000000
--- a/sshd-core/src/main/java/org/apache/sshd/common/util/security/bouncycastle/BouncyCastleRandom.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.sshd.common.util.security.bouncycastle;
-
-import java.security.SecureRandom;
-
-import org.apache.sshd.common.random.AbstractRandom;
-import org.apache.sshd.common.util.ValidateUtils;
-import org.apache.sshd.common.util.security.SecurityUtils;
-import org.bouncycastle.crypto.prng.RandomGenerator;
-import org.bouncycastle.crypto.prng.VMPCRandomGenerator;
-
-/**
- * BouncyCastle <code>Random</code>.
- * This pseudo random number generator uses the a very fast PRNG from BouncyCastle.
- * The JRE random will be used when creating a new generator to add some random
- * data to the seed.
- *
- * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
- */
-public final class BouncyCastleRandom extends AbstractRandom {
- public static final String NAME = SecurityUtils.BOUNCY_CASTLE;
- private final RandomGenerator random;
-
- public BouncyCastleRandom() {
- ValidateUtils.checkTrue(SecurityUtils.isBouncyCastleRegistered(), "BouncyCastle not registered");
- this.random = new VMPCRandomGenerator();
- byte[] seed = new SecureRandom().generateSeed(8);
- this.random.addSeedMaterial(seed);
- }
-
- @Override
- public String getName() {
- return NAME;
- }
-
- @Override
- public void fill(byte[] bytes, int start, int len) {
- this.random.nextBytes(bytes, start, len);
- }
-
- /**
- * Returns a pseudo-random uniformly distributed {@code int}
- * in the half-open range [0, n).
- */
- @Override
- public int random(int n) {
- ValidateUtils.checkTrue(n > 0, "Limit must be positive: %d", n);
- if ((n & -n) == n) {
- return (int) ((n * (long) next(31)) >> 31);
- }
-
- int bits;
- int val;
- do {
- bits = next(31);
- val = bits % n;
- } while (bits - val + (n - 1) < 0);
- return val;
- }
-
- private int next(int numBits) {
- int bytes = (numBits + 7) / 8;
- byte next[] = new byte[bytes];
- int ret = 0;
- random.nextBytes(next);
- for (int i = 0; i < bytes; i++) {
- ret = (next[i] & 0xFF) | (ret << 8);
- }
- return ret >>> (bytes * 8 - numBits);
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-core/src/main/java/org/apache/sshd/common/util/security/bouncycastle/BouncyCastleRandomFactory.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/util/security/bouncycastle/BouncyCastleRandomFactory.java b/sshd-core/src/main/java/org/apache/sshd/common/util/security/bouncycastle/BouncyCastleRandomFactory.java
deleted file mode 100644
index 720c7a5..0000000
--- a/sshd-core/src/main/java/org/apache/sshd/common/util/security/bouncycastle/BouncyCastleRandomFactory.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.sshd.common.util.security.bouncycastle;
-
-import org.apache.sshd.common.random.AbstractRandomFactory;
-import org.apache.sshd.common.random.Random;
-import org.apache.sshd.common.util.security.SecurityUtils;
-
-/**
- * Named factory for the BouncyCastle <code>Random</code>
- */
-public final class BouncyCastleRandomFactory extends AbstractRandomFactory {
- public static final String NAME = "bouncycastle";
- public static final BouncyCastleRandomFactory INSTANCE = new BouncyCastleRandomFactory();
-
- public BouncyCastleRandomFactory() {
- super(NAME);
- }
-
- @Override
- public boolean isSupported() {
- return SecurityUtils.isBouncyCastleRegistered();
- }
-
- @Override
- public Random create() {
- return new BouncyCastleRandom();
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-core/src/main/java/org/apache/sshd/common/util/security/bouncycastle/BouncyCastleSecurityProviderRegistrar.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/util/security/bouncycastle/BouncyCastleSecurityProviderRegistrar.java b/sshd-core/src/main/java/org/apache/sshd/common/util/security/bouncycastle/BouncyCastleSecurityProviderRegistrar.java
deleted file mode 100644
index b47ca80..0000000
--- a/sshd-core/src/main/java/org/apache/sshd/common/util/security/bouncycastle/BouncyCastleSecurityProviderRegistrar.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.sshd.common.util.security.bouncycastle;
-
-import java.security.KeyFactory;
-import java.security.KeyPairGenerator;
-import java.security.Provider;
-import java.security.Signature;
-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;
-
-/**
- * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
- */
-public class BouncyCastleSecurityProviderRegistrar extends AbstractSecurityProviderRegistrar {
- // We want to use reflection API so as not to require BouncyCastle to be present in the classpath
- public static final String PROVIDER_CLASS = "org.bouncycastle.jce.provider.BouncyCastleProvider";
- // Do not define a static registrar instance to minimize class loading issues
- private final AtomicReference<Boolean> supportHolder = new AtomicReference<>(null);
- private final AtomicReference<String> allSupportHolder = new AtomicReference<>();
-
- public BouncyCastleSecurityProviderRegistrar() {
- super(SecurityUtils.BOUNCY_CASTLE);
- }
-
- @Override
- public boolean isEnabled() {
- if (!super.isEnabled()) {
- return false;
- }
-
- // For backward compatibility
- return this.getBooleanProperty(SecurityUtils.REGISTER_BOUNCY_CASTLE_PROP, true);
- }
-
- @Override
- public Provider getSecurityProvider() {
- try {
- return getOrCreateProvider(PROVIDER_CLASS);
- } catch (ReflectiveOperationException t) {
- Throwable e = GenericUtils.peelException(t);
- log.error("getSecurityProvider({}) failed ({}) to instantiate {}: {}",
- getName(), e.getClass().getSimpleName(), PROVIDER_CLASS, e.getMessage());
- if (e instanceof RuntimeException) {
- throw (RuntimeException) e;
- }
-
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public String getDefaultSecurityEntitySupportValue(Class<?> entityType) {
- String allValue = allSupportHolder.get();
- if (GenericUtils.length(allValue) > 0) {
- return allValue;
- }
-
- String propName = getConfigurationPropertyName("supportAll");
- allValue = this.getStringProperty(propName, ALL_OPTIONS_VALUE);
- if (GenericUtils.isEmpty(allValue)) {
- allValue = NO_OPTIONS_VALUE;
- }
-
- allSupportHolder.set(allValue);
- return allValue;
- }
-
- @Override
- public boolean isSecurityEntitySupported(Class<?> entityType, String name) {
- if (!isSupported()) {
- return false;
- }
-
- // Some known values it does not support
- if (KeyPairGenerator.class.isAssignableFrom(entityType)
- || KeyFactory.class.isAssignableFrom(entityType)) {
- if (Objects.compare(name, SecurityUtils.EDDSA, String.CASE_INSENSITIVE_ORDER) == 0) {
- return false;
- }
- } else if (Signature.class.isAssignableFrom(entityType)) {
- if (Objects.compare(name, SecurityUtils.CURVE_ED25519_SHA512, String.CASE_INSENSITIVE_ORDER) == 0) {
- return false;
- }
- }
-
- return super.isSecurityEntitySupported(entityType, name);
- }
-
- @Override
- public boolean isSupported() {
- Boolean supported;
- synchronized (supportHolder) {
- supported = supportHolder.get();
- if (supported != null) {
- return supported.booleanValue();
- }
-
- ClassLoader cl = ThreadUtils.resolveDefaultClassLoader(getClass());
- supported = ReflectionUtils.isClassAvailable(cl, PROVIDER_CLASS);
- supportHolder.set(supported);
- }
-
- return supported.booleanValue();
- }
-}