http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-core/src/main/java/org/apache/sshd/common/keyprovider/KeyPairProvider.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/common/keyprovider/KeyPairProvider.java b/sshd-core/src/main/java/org/apache/sshd/common/keyprovider/KeyPairProvider.java deleted file mode 100644 index a816304..0000000 --- a/sshd-core/src/main/java/org/apache/sshd/common/keyprovider/KeyPairProvider.java +++ /dev/null @@ -1,181 +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.keyprovider; - -import java.security.KeyPair; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.LinkedHashSet; -import java.util.Objects; -import java.util.stream.Collectors; - -import org.apache.sshd.common.cipher.ECCurves; -import org.apache.sshd.common.config.keys.KeyUtils; -import org.apache.sshd.common.util.GenericUtils; -import org.apache.sshd.common.util.ValidateUtils; - -/** - * Provider for key pairs. This provider is used on the server side to provide - * the host key, or on the client side to provide the user key. - * - * @author <a href="mailto:[email protected]">Apache MINA SSHD Project</a> - */ -public interface KeyPairProvider extends KeyIdentityProvider { - - /** - * SSH identifier for RSA keys - */ - String SSH_RSA = "ssh-rsa"; - - /** - * SSH identifier for DSA keys - */ - String SSH_DSS = "ssh-dss"; - - /** - * SSH identifier for ED25519 elliptic curve keys - */ - String SSH_ED25519 = "ssh-ed25519"; - - /** - * SSH identifier for EC keys in NIST curve P-256 - */ - String ECDSA_SHA2_NISTP256 = ECCurves.nistp256.getKeyType(); - - /** - * SSH identifier for EC keys in NIST curve P-384 - */ - String ECDSA_SHA2_NISTP384 = ECCurves.nistp384.getKeyType(); - - /** - * SSH identifier for EC keys in NIST curve P-521 - */ - String ECDSA_SHA2_NISTP521 = ECCurves.nistp521.getKeyType(); - - /** - * A {@link KeyPairProvider} that has no keys - */ - KeyPairProvider EMPTY_KEYPAIR_PROVIDER = - new KeyPairProvider() { - @Override - public KeyPair loadKey(String type) { - return null; - } - - @Override - public Iterable<String> getKeyTypes() { - return Collections.emptyList(); - } - - @Override - public Iterable<KeyPair> loadKeys() { - return Collections.emptyList(); - } - - @Override - public String toString() { - return "EMPTY_KEYPAIR_PROVIDER"; - } - }; - - /** - * Load a key of the specified type which can be "ssh-rsa", "ssh-dss", - * or "ecdsa-sha2-nistp{256,384,521}". If there is no key of this type, return - * {@code null} - * - * @param type the type of key to load - * @return a valid key pair or {@code null} if this type of key is not available - */ - default KeyPair loadKey(String type) { - ValidateUtils.checkNotNullAndNotEmpty(type, "No key type to load"); - return GenericUtils.stream(loadKeys()) - .filter(key -> type.equals(KeyUtils.getKeyType(key))) - .findFirst() - .orElse(null); - } - - /** - * @return The available {@link Iterable} key types in preferred order - never {@code null} - */ - default Iterable<String> getKeyTypes() { - return GenericUtils.stream(loadKeys()) - .map(KeyUtils::getKeyType) - .filter(GenericUtils::isNotEmpty) - .collect(Collectors.toSet()); - } - - /** - * Wrap the provided {@link KeyPair}s into a {@link KeyPairProvider} - * - * @param pairs The available pairs - ignored if {@code null}/empty (i.e., - * returns {@link #EMPTY_KEYPAIR_PROVIDER}) - * @return The provider wrapper - * @see #wrap(Iterable) - */ - static KeyPairProvider wrap(KeyPair... pairs) { - return GenericUtils.isEmpty(pairs) ? EMPTY_KEYPAIR_PROVIDER : wrap(Arrays.asList(pairs)); - } - - /** - * Wrap the provided {@link KeyPair}s into a {@link KeyPairProvider} - * - * @param pairs The available pairs {@link Iterable} - ignored if {@code null} (i.e., - * returns {@link #EMPTY_KEYPAIR_PROVIDER}) - * @return The provider wrapper - */ - static KeyPairProvider wrap(Iterable<KeyPair> pairs) { - return (pairs == null) ? EMPTY_KEYPAIR_PROVIDER : new KeyPairProvider() { - @Override - public Iterable<KeyPair> loadKeys() { - return pairs; - } - - @Override - public KeyPair loadKey(String type) { - for (KeyPair kp : pairs) { - String t = KeyUtils.getKeyType(kp); - if (Objects.equals(type, t)) { - return kp; - } - } - - return null; - } - - @Override - public Iterable<String> getKeyTypes() { - // use a LinkedHashSet so as to preserve the order but avoid duplicates - Collection<String> types = new LinkedHashSet<>(); - for (KeyPair kp : pairs) { - String t = KeyUtils.getKeyType(kp); - if (GenericUtils.isEmpty(t)) { - continue; // avoid unknown key types - } - - if (!types.add(t)) { - continue; // debug breakpoint - } - } - - return types; - } - }; - } -}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-core/src/main/java/org/apache/sshd/common/keyprovider/KeyPairProviderHolder.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/common/keyprovider/KeyPairProviderHolder.java b/sshd-core/src/main/java/org/apache/sshd/common/keyprovider/KeyPairProviderHolder.java deleted file mode 100644 index 553d553..0000000 --- a/sshd-core/src/main/java/org/apache/sshd/common/keyprovider/KeyPairProviderHolder.java +++ /dev/null @@ -1,35 +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.keyprovider; - -/** - * @author <a href="mailto:[email protected]">Apache MINA SSHD Project</a> - */ -public interface KeyPairProviderHolder { - /** - * Retrieve the <code>KeyPairProvider</code> that will be used to find - * the host key to use on the server side or the user key on the client side. - * - * @return the <code>KeyPairProvider</code>, never {@code null} - */ - KeyPairProvider getKeyPairProvider(); - - void setKeyPairProvider(KeyPairProvider keyPairProvider); -} http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-core/src/main/java/org/apache/sshd/common/keyprovider/MappedKeyPairProvider.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/common/keyprovider/MappedKeyPairProvider.java b/sshd-core/src/main/java/org/apache/sshd/common/keyprovider/MappedKeyPairProvider.java deleted file mode 100644 index bf3ec8b..0000000 --- a/sshd-core/src/main/java/org/apache/sshd/common/keyprovider/MappedKeyPairProvider.java +++ /dev/null @@ -1,97 +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.keyprovider; - -import java.security.KeyPair; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.Map; -import java.util.TreeMap; -import java.util.function.Function; - -import org.apache.sshd.common.config.keys.KeyUtils; -import org.apache.sshd.common.util.GenericUtils; -import org.apache.sshd.common.util.ValidateUtils; - -/** - * Holds a {@link Map} of {@link String}->{@link KeyPair} where the map key - * is the type and value is the associated {@link KeyPair} - * - * @author <a href="mailto:[email protected]">Apache MINA SSHD Project</a> - */ -public class MappedKeyPairProvider implements KeyPairProvider { - /** - * Transforms a {@link Map} of {@link String}->{@link KeyPair} to a - * {@link KeyPairProvider} where map key is the type and value is the - * associated {@link KeyPair} - */ - public static final Function<Map<String, KeyPair>, KeyPairProvider> MAP_TO_KEY_PAIR_PROVIDER = - MappedKeyPairProvider::new; - - private final Map<String, KeyPair> pairsMap; - - public MappedKeyPairProvider(KeyPair... pairs) { - this(GenericUtils.isEmpty(pairs) ? Collections.emptyList() : Arrays.asList(pairs)); - } - - public MappedKeyPairProvider(Collection<? extends KeyPair> pairs) { - this(mapUniquePairs(pairs)); - } - - public MappedKeyPairProvider(Map<String, KeyPair> pairsMap) { - this.pairsMap = ValidateUtils.checkNotNullAndNotEmpty(pairsMap, "No pairs map provided"); - } - - @Override - public Iterable<KeyPair> loadKeys() { - return pairsMap.values(); - } - - @Override - public KeyPair loadKey(String type) { - return pairsMap.get(type); - } - - @Override - public Iterable<String> getKeyTypes() { - return pairsMap.keySet(); - } - - @Override - public String toString() { - return String.valueOf(getKeyTypes()); - } - - public static Map<String, KeyPair> mapUniquePairs(Collection<? extends KeyPair> pairs) { - if (GenericUtils.isEmpty(pairs)) { - return Collections.emptyMap(); - } - - Map<String, KeyPair> pairsMap = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); - for (KeyPair kp : pairs) { - String keyType = ValidateUtils.checkNotNullAndNotEmpty(KeyUtils.getKeyType(kp), "Cannot determine key type"); - KeyPair prev = pairsMap.put(keyType, kp); - ValidateUtils.checkTrue(prev == null, "Multiple keys of type=%s", keyType); - } - - return pairsMap; - } -} http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-core/src/main/java/org/apache/sshd/common/mac/BaseMac.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/common/mac/BaseMac.java b/sshd-core/src/main/java/org/apache/sshd/common/mac/BaseMac.java deleted file mode 100644 index e1681d4..0000000 --- a/sshd-core/src/main/java/org/apache/sshd/common/mac/BaseMac.java +++ /dev/null @@ -1,111 +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.mac; - -import javax.crypto.spec.SecretKeySpec; - -import org.apache.sshd.common.util.security.SecurityUtils; - -/** - * Base class for <code>Mac</code> implementations based on the JCE provider. - * - * @author <a href="mailto:[email protected]">Apache MINA SSHD Project</a> - */ -public class BaseMac implements Mac { - - private final String algorithm; - private final int defbsize; - private final int bsize; - private final byte[] tmp; - private javax.crypto.Mac mac; - private String s; - - public BaseMac(String algorithm, int bsize, int defbsize) { - this.algorithm = algorithm; - this.bsize = bsize; - this.defbsize = defbsize; - this.tmp = new byte[defbsize]; - } - - @Override - public final String getAlgorithm() { - return algorithm; - } - - @Override - public final int getBlockSize() { - return bsize; - } - - @Override - public final int getDefaultBlockSize() { - return defbsize; - } - - @Override - public void init(byte[] key) throws Exception { - if (key.length > defbsize) { - byte[] tmp = new byte[defbsize]; - System.arraycopy(key, 0, tmp, 0, defbsize); - key = tmp; - } - - SecretKeySpec skey = new SecretKeySpec(key, algorithm); - mac = SecurityUtils.getMac(algorithm); - mac.init(skey); - } - - @Override - public void updateUInt(long i) { - tmp[0] = (byte) (i >>> 24); - tmp[1] = (byte) (i >>> 16); - tmp[2] = (byte) (i >>> 8); - tmp[3] = (byte) i; - update(tmp, 0, 4); - } - - @Override - public void update(byte buf[], int offset, int len) { - mac.update(buf, offset, len); - } - - @Override - public void doFinal(byte[] buf, int offset) throws Exception { - int blockSize = getBlockSize(); - int defaultSize = getDefaultBlockSize(); - if (blockSize != defaultSize) { - mac.doFinal(tmp, 0); - System.arraycopy(tmp, 0, buf, offset, blockSize); - } else { - mac.doFinal(buf, offset); - } - } - - @Override - public String toString() { - synchronized (this) { - if (s == null) { - s = getClass().getSimpleName() + "[" + getAlgorithm() + "] - " - + " block=" + getBlockSize() + "/" + getDefaultBlockSize() + " bytes"; - } - } - - return s; - } -} http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-core/src/main/java/org/apache/sshd/common/mac/BuiltinMacs.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/common/mac/BuiltinMacs.java b/sshd-core/src/main/java/org/apache/sshd/common/mac/BuiltinMacs.java deleted file mode 100644 index 5a4528d..0000000 --- a/sshd-core/src/main/java/org/apache/sshd/common/mac/BuiltinMacs.java +++ /dev/null @@ -1,273 +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.mac; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.EnumSet; -import java.util.List; -import java.util.Map; -import java.util.NavigableSet; -import java.util.Objects; -import java.util.Set; -import java.util.TreeMap; - -import org.apache.sshd.common.NamedFactory; -import org.apache.sshd.common.NamedResource; -import org.apache.sshd.common.config.NamedFactoriesListParseResult; -import org.apache.sshd.common.util.GenericUtils; -import org.apache.sshd.common.util.ValidateUtils; - -/** - * Provides easy access to the currently implemented macs - * - * @author <a href="mailto:[email protected]">Apache MINA SSHD Project</a> - */ -public enum BuiltinMacs implements MacFactory { - hmacmd5(Constants.HMAC_MD5, "HmacMD5", 16, 16), - hmacmd596(Constants.HMAC_MD5_96, "HmacMD5", 12, 16), - hmacsha1(Constants.HMAC_SHA1, "HmacSHA1", 20, 20), - hmacsha196(Constants.HMAC_SHA1_96, "HmacSHA1", 12, 20), - /** See <A HREF="https://tools.ietf.org/html/rfc6668">RFC 6668</A> */ - hmacsha256(Constants.HMAC_SHA2_256, "HmacSHA256", 32, 32), - /** See <A HREF="https://tools.ietf.org/html/rfc6668">RFC 6668</A> */ - hmacsha512(Constants.HMAC_SHA2_512, "HmacSHA512", 64, 64); - - public static final Set<BuiltinMacs> VALUES = - Collections.unmodifiableSet(EnumSet.allOf(BuiltinMacs.class)); - - private static final Map<String, MacFactory> EXTENSIONS = - new TreeMap<>(String.CASE_INSENSITIVE_ORDER); - - private final String factoryName; - private final String algorithm; - private final int defbsize; - private final int bsize; - - BuiltinMacs(String factoryName, String algorithm, int bsize, int defbsize) { - this.factoryName = factoryName; - this.algorithm = algorithm; - this.bsize = bsize; - this.defbsize = defbsize; - } - - @Override - public Mac create() { - return new BaseMac(getAlgorithm(), getBlockSize(), getDefaultBlockSize()); - } - - @Override - public final String getName() { - return factoryName; - } - - @Override - public final String getAlgorithm() { - return algorithm; - } - - @Override - public final int getBlockSize() { - return bsize; - } - - @Override - public final int getDefaultBlockSize() { - return defbsize; - } - - @Override - public final boolean isSupported() { - return true; - } - - @Override - public final String toString() { - return getName(); - } - - /** - * Registered a {@link NamedFactory} to be available besides the built-in - * ones when parsing configuration - * - * @param extension The factory to register - * @throws IllegalArgumentException if factory instance is {@code null}, - * or overrides a built-in one or overrides another registered factory - * with the same name (case <U>insensitive</U>). - */ - public static void registerExtension(MacFactory extension) { - String name = Objects.requireNonNull(extension, "No extension provided").getName(); - ValidateUtils.checkTrue(fromFactoryName(name) == null, "Extension overrides built-in: %s", name); - - synchronized (EXTENSIONS) { - ValidateUtils.checkTrue(!EXTENSIONS.containsKey(name), "Extension overrides existing: %s", name); - EXTENSIONS.put(name, extension); - } - } - - /** - * @return A {@link NavigableSet} of the currently registered extensions, sorted - * according to the factory name (case <U>insensitive</U>) - */ - public static NavigableSet<MacFactory> getRegisteredExtensions() { - synchronized (EXTENSIONS) { - return GenericUtils.asSortedSet(NamedResource.BY_NAME_COMPARATOR, EXTENSIONS.values()); - } - } - - /** - * Unregisters specified extension - * - * @param name The factory name - ignored if {@code null}/empty - * @return The registered extension - {@code null} if not found - */ - public static MacFactory unregisterExtension(String name) { - if (GenericUtils.isEmpty(name)) { - return null; - } - - synchronized (EXTENSIONS) { - return EXTENSIONS.remove(name); - } - } - - /** - * @param s The {@link Enum}'s name - ignored if {@code null}/empty - * @return The matching {@link org.apache.sshd.common.mac.BuiltinMacs} whose {@link Enum#name()} matches - * (case <U>insensitive</U>) the provided argument - {@code null} if no match - */ - public static BuiltinMacs fromString(String s) { - if (GenericUtils.isEmpty(s)) { - return null; - } - - for (BuiltinMacs c : VALUES) { - if (s.equalsIgnoreCase(c.name())) { - return c; - } - } - - return null; - } - - /** - * @param factory The {@link org.apache.sshd.common.NamedFactory} for the MAC - ignored if {@code null} - * @return The matching {@link org.apache.sshd.common.mac.BuiltinMacs} whose factory name matches - * (case <U>insensitive</U>) the digest factory name - * @see #fromFactoryName(String) - */ - public static BuiltinMacs fromFactory(NamedFactory<Mac> factory) { - if (factory == null) { - return null; - } else { - return fromFactoryName(factory.getName()); - } - } - - /** - * @param name The factory name - ignored if {@code null}/empty - * @return The matching {@link BuiltinMacs} whose factory name matches - * (case <U>insensitive</U>) the provided name - {@code null} if no match - */ - public static BuiltinMacs fromFactoryName(String name) { - return NamedResource.findByName(name, String.CASE_INSENSITIVE_ORDER, VALUES); - } - - /** - * @param macs A comma-separated list of MACs' names - ignored - * if {@code null}/empty - * @return A {@link ParseResult} containing the successfully parsed - * factories and the unknown ones. <B>Note:</B> it is up to caller to - * ensure that the lists do not contain duplicates - */ - public static ParseResult parseMacsList(String macs) { - return parseMacsList(GenericUtils.split(macs, ',')); - } - - public static ParseResult parseMacsList(String... macs) { - return parseMacsList(GenericUtils.isEmpty((Object[]) macs) ? Collections.emptyList() : Arrays.asList(macs)); - } - - public static ParseResult parseMacsList(Collection<String> macs) { - if (GenericUtils.isEmpty(macs)) { - return ParseResult.EMPTY; - } - - List<MacFactory> factories = new ArrayList<>(macs.size()); - List<String> unknown = Collections.emptyList(); - for (String name : macs) { - MacFactory m = resolveFactory(name); - if (m != null) { - factories.add(m); - } else { - // replace the (unmodifiable) empty list with a real one - if (unknown.isEmpty()) { - unknown = new ArrayList<>(); - } - unknown.add(name); - } - } - - return new ParseResult(factories, unknown); - } - - /** - * @param name The factory name - * @return The factory or {@code null} if it is neither a built-in one - * or a registered extension - */ - public static MacFactory resolveFactory(String name) { - if (GenericUtils.isEmpty(name)) { - return null; - } - - MacFactory m = fromFactoryName(name); - if (m != null) { - return m; - } - - synchronized (EXTENSIONS) { - return EXTENSIONS.get(name); - } - } - - public static final class ParseResult extends NamedFactoriesListParseResult<Mac, MacFactory> { - public static final ParseResult EMPTY = new ParseResult(Collections.emptyList(), Collections.emptyList()); - - public ParseResult(List<MacFactory> parsed, List<String> unsupported) { - super(parsed, unsupported); - } - } - - public static final class Constants { - public static final String HMAC_MD5 = "hmac-md5"; - public static final String HMAC_MD5_96 = "hmac-md5-96"; - public static final String HMAC_SHA1 = "hmac-sha1"; - public static final String HMAC_SHA1_96 = "hmac-sha1-96"; - public static final String HMAC_SHA2_256 = "hmac-sha2-256"; - public static final String HMAC_SHA2_512 = "hmac-sha2-512"; - - private Constants() { - throw new UnsupportedOperationException("No instance allowed"); - } - } -} http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-core/src/main/java/org/apache/sshd/common/mac/Mac.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/common/mac/Mac.java b/sshd-core/src/main/java/org/apache/sshd/common/mac/Mac.java deleted file mode 100644 index 4b80447..0000000 --- a/sshd-core/src/main/java/org/apache/sshd/common/mac/Mac.java +++ /dev/null @@ -1,52 +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.mac; - -import org.apache.sshd.common.util.NumberUtils; - -/** - * Message Authentication Code for use in SSH. - * It usually wraps a javax.crypto.Mac class. - * - * @author <a href="mailto:[email protected]">Apache MINA SSHD Project</a> - */ -public interface Mac extends MacInformation { - void init(byte[] key) throws Exception; - - default void update(byte[] buf) { - update(buf, 0, NumberUtils.length(buf)); - } - - void update(byte[] buf, int start, int len); - - void updateUInt(long foo); - - default byte[] doFinal() throws Exception { - int blockSize = getBlockSize(); - byte[] buf = new byte[blockSize]; - doFinal(buf); - return buf; - } - - default void doFinal(byte[] buf) throws Exception { - doFinal(buf, 0); - } - - void doFinal(byte[] buf, int offset) throws Exception; -} http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-core/src/main/java/org/apache/sshd/common/mac/MacFactory.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/common/mac/MacFactory.java b/sshd-core/src/main/java/org/apache/sshd/common/mac/MacFactory.java deleted file mode 100644 index 4463600..0000000 --- a/sshd-core/src/main/java/org/apache/sshd/common/mac/MacFactory.java +++ /dev/null @@ -1,31 +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.mac; - -import org.apache.sshd.common.BuiltinFactory; - -/** - * @author <a href="mailto:[email protected]">Apache MINA SSHD Project</a> - */ -// CHECKSTYLE:OFF -public interface MacFactory extends MacInformation, BuiltinFactory<Mac> { - // nothing extra -} -//CHECKSTYLE:ON http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-core/src/main/java/org/apache/sshd/common/mac/MacInformation.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/common/mac/MacInformation.java b/sshd-core/src/main/java/org/apache/sshd/common/mac/MacInformation.java deleted file mode 100644 index 583165f..0000000 --- a/sshd-core/src/main/java/org/apache/sshd/common/mac/MacInformation.java +++ /dev/null @@ -1,41 +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.mac; - -/** - * @author <a href="mailto:[email protected]">Apache MINA SSHD Project</a> - */ -public interface MacInformation { - /** - * @return MAC algorithm name - */ - String getAlgorithm(); - - /** - * @return MAC output block size in bytes - may be less than the default - * - e.g., MD5-96 - */ - int getBlockSize(); - - /** - * @return The "natural" MAC block size in bytes - */ - int getDefaultBlockSize(); -} http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-core/src/main/java/org/apache/sshd/common/mac/package.html ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/common/mac/package.html b/sshd-core/src/main/java/org/apache/sshd/common/mac/package.html deleted file mode 100644 index 52a90ca..0000000 --- a/sshd-core/src/main/java/org/apache/sshd/common/mac/package.html +++ /dev/null @@ -1,25 +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. ---> -<html> -<head> -</head> -<body> - -<a href="{@docRoot}/org/apache/sshd/common/mac/Mac.html"><code>Mac</code></a> implementations. - -</body> -</html> http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-core/src/main/java/org/apache/sshd/common/random/AbstractRandom.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/common/random/AbstractRandom.java b/sshd-core/src/main/java/org/apache/sshd/common/random/AbstractRandom.java deleted file mode 100644 index 2a1f825..0000000 --- a/sshd-core/src/main/java/org/apache/sshd/common/random/AbstractRandom.java +++ /dev/null @@ -1,34 +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.random; - -/** - * @author <a href="mailto:[email protected]">Apache MINA SSHD Project</a> - */ -public abstract class AbstractRandom implements Random { - protected AbstractRandom() { - super(); - } - - @Override - public String toString() { - return getName(); - } -} http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-core/src/main/java/org/apache/sshd/common/random/AbstractRandomFactory.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/common/random/AbstractRandomFactory.java b/sshd-core/src/main/java/org/apache/sshd/common/random/AbstractRandomFactory.java deleted file mode 100644 index c1d7893..0000000 --- a/sshd-core/src/main/java/org/apache/sshd/common/random/AbstractRandomFactory.java +++ /dev/null @@ -1,43 +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.random; - -import org.apache.sshd.common.util.ValidateUtils; - -/** - * @author <a href="mailto:[email protected]">Apache MINA SSHD Project</a> - */ -public abstract class AbstractRandomFactory implements RandomFactory { - private final String name; - - protected AbstractRandomFactory(String name) { - this.name = ValidateUtils.checkNotNullAndNotEmpty(name, "No name"); - } - - @Override - public final String getName() { - return name; - } - - @Override - public String toString() { - return getName(); - } -} http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-core/src/main/java/org/apache/sshd/common/random/JceRandom.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/common/random/JceRandom.java b/sshd-core/src/main/java/org/apache/sshd/common/random/JceRandom.java deleted file mode 100644 index ba050e6..0000000 --- a/sshd-core/src/main/java/org/apache/sshd/common/random/JceRandom.java +++ /dev/null @@ -1,60 +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.random; - -import java.security.SecureRandom; - -/** - * A <code>Random</code> implementation using the built-in {@link SecureRandom} PRNG. - * - * @author <a href="mailto:[email protected]">Apache MINA SSHD Project</a> - */ -public class JceRandom extends AbstractRandom { - public static final String NAME = "JCE"; - - private byte[] tmp = new byte[16]; - private final SecureRandom random = new SecureRandom(); - - public JceRandom() { - super(); - } - - @Override - public String getName() { - return NAME; - } - - @Override - public synchronized void fill(byte[] foo, int start, int len) { - if ((start == 0) && (len == foo.length)) { - random.nextBytes(foo); - } else { - if (len > tmp.length) { - tmp = new byte[len]; - } - random.nextBytes(tmp); - System.arraycopy(tmp, 0, foo, start, len); - } - } - - @Override - public synchronized int random(int n) { - return random.nextInt(n); - } -} http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-core/src/main/java/org/apache/sshd/common/random/JceRandomFactory.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/common/random/JceRandomFactory.java b/sshd-core/src/main/java/org/apache/sshd/common/random/JceRandomFactory.java deleted file mode 100644 index 450a85e..0000000 --- a/sshd-core/src/main/java/org/apache/sshd/common/random/JceRandomFactory.java +++ /dev/null @@ -1,42 +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.random; - -/** - * Named factory for the JCE <code>Random</code> - */ -public class JceRandomFactory extends AbstractRandomFactory { - public static final String NAME = "default"; - public static final JceRandomFactory INSTANCE = new JceRandomFactory(); - - public JceRandomFactory() { - super(NAME); - } - - @Override - public boolean isSupported() { - return true; - } - - @Override - public Random create() { - return new JceRandom(); - } -} \ 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/random/Random.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/common/random/Random.java b/sshd-core/src/main/java/org/apache/sshd/common/random/Random.java deleted file mode 100644 index 6e597ef..0000000 --- a/sshd-core/src/main/java/org/apache/sshd/common/random/Random.java +++ /dev/null @@ -1,56 +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.random; - -import org.apache.sshd.common.NamedResource; - -/** - * A pseudo random number generator. - * - * @author <a href="mailto:[email protected]">Apache MINA SSHD Project</a> - */ -public interface Random extends NamedResource { - /** - * Fill the buffer with random values - * - * @param bytes The bytes to fill - * @see #fill(byte[], int, int) - */ - default void fill(byte[] bytes) { - fill(bytes, 0, bytes.length); - } - - /** - * Fill part of bytes with random values. - * - * @param bytes byte array to be filled. - * @param start index to start filling at. - * @param len length of segment to fill. - */ - void fill(byte[] bytes, int start, int len); - - /** - * Returns a pseudo-random uniformly distributed {@code int} - * in the half-open range [0, n). - * - * @param n The range upper limit - * @return The randomly selected value in the range - */ - int random(int n); -} http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-core/src/main/java/org/apache/sshd/common/random/RandomFactory.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/common/random/RandomFactory.java b/sshd-core/src/main/java/org/apache/sshd/common/random/RandomFactory.java deleted file mode 100644 index dded06f..0000000 --- a/sshd-core/src/main/java/org/apache/sshd/common/random/RandomFactory.java +++ /dev/null @@ -1,31 +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.random; - -import org.apache.sshd.common.BuiltinFactory; - -/** - * @author <a href="mailto:[email protected]">Apache MINA SSHD Project</a> - */ -// CHECKSTYLE:OFF -public interface RandomFactory extends BuiltinFactory<Random> { - // nothing extra -} -//CHECKSTYLE:ON http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-core/src/main/java/org/apache/sshd/common/random/SingletonRandomFactory.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/common/random/SingletonRandomFactory.java b/sshd-core/src/main/java/org/apache/sshd/common/random/SingletonRandomFactory.java deleted file mode 100644 index ce24112..0000000 --- a/sshd-core/src/main/java/org/apache/sshd/common/random/SingletonRandomFactory.java +++ /dev/null @@ -1,70 +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.random; - -import java.util.Objects; - -import org.apache.sshd.common.NamedFactory; -import org.apache.sshd.common.OptionalFeature; - -/** - * A random factory wrapper that uses a single random instance. - * The underlying random instance has to be thread safe. - * - * @author <a href="mailto:[email protected]">Apache MINA SSHD Project</a> - */ -public class SingletonRandomFactory extends AbstractRandom implements RandomFactory { - - private final NamedFactory<Random> factory; - private final Random random; - - public SingletonRandomFactory(NamedFactory<Random> factory) { - this.factory = Objects.requireNonNull(factory, "No factory"); - this.random = Objects.requireNonNull(factory.create(), "No random instance created"); - } - - @Override - public boolean isSupported() { - if (factory instanceof OptionalFeature) { - return ((OptionalFeature) factory).isSupported(); - } else { - return true; - } - } - - @Override - public void fill(byte[] bytes, int start, int len) { - random.fill(bytes, start, len); - } - - @Override - public int random(int max) { - return random.random(max); - } - - @Override - public String getName() { - return factory.getName(); - } - - @Override - public Random create() { - return this; - } -} http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-core/src/main/java/org/apache/sshd/common/random/package.html ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/common/random/package.html b/sshd-core/src/main/java/org/apache/sshd/common/random/package.html deleted file mode 100644 index 0e94d7f..0000000 --- a/sshd-core/src/main/java/org/apache/sshd/common/random/package.html +++ /dev/null @@ -1,25 +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. ---> -<html> -<head> -</head> -<body> - -<a href="{@docRoot}/org/apache/sshd/common/random/Random.html"><code>Random</code></a> implementations. - -</body> -</html> http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-core/src/main/java/org/apache/sshd/common/session/Session.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/common/session/Session.java b/sshd-core/src/main/java/org/apache/sshd/common/session/Session.java index def98a3..f8e80c5 100644 --- a/sshd-core/src/main/java/org/apache/sshd/common/session/Session.java +++ b/sshd-core/src/main/java/org/apache/sshd/common/session/Session.java @@ -19,10 +19,12 @@ package org.apache.sshd.common.session; import java.io.IOException; +import java.util.Objects; import java.util.concurrent.TimeUnit; import org.apache.sshd.common.AttributeStore; import org.apache.sshd.common.Closeable; +import org.apache.sshd.common.FactoryManager; import org.apache.sshd.common.FactoryManagerHolder; import org.apache.sshd.common.PropertyResolver; import org.apache.sshd.common.Service; @@ -318,6 +320,11 @@ public interface Session */ void startService(String name) throws Exception; + @Override + default <T> T resolveAttribute(AttributeKey<T> key) { + return resolveAttribute(this, key); + } + /** * @param version The reported client/server version * @return {@code true} if version not empty and starts with either @@ -327,4 +334,24 @@ public interface Session return GenericUtils.isNotEmpty(version) && (version.startsWith(DEFAULT_SSH_VERSION_PREFIX) || version.startsWith(FALLBACK_SSH_VERSION_PREFIX)); } + + /** + * Attempts to use the session's attribute, if not found then tries the factory manager + * + * @param <T> The generic attribute type + * @param session The {@link Session} - ignored if {@code null} + * @param key The attribute key - never {@code null} + * @return Associated value - {@code null} if not found + * @see Session#getFactoryManager() + * @see #resolveAttribute(FactoryManager, AttributeKey) + */ + static <T> T resolveAttribute(Session session, AttributeKey<T> key) { + Objects.requireNonNull(key, "No key"); + if (session == null) { + return null; + } + + T value = session.getAttribute(key); + return (value != null) ? value : FactoryManager.resolveAttribute(session.getFactoryManager(), key); + } } http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-core/src/main/java/org/apache/sshd/common/session/helpers/AbstractSession.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/common/session/helpers/AbstractSession.java b/sshd-core/src/main/java/org/apache/sshd/common/session/helpers/AbstractSession.java index 076de1e..a739c33 100644 --- a/sshd-core/src/main/java/org/apache/sshd/common/session/helpers/AbstractSession.java +++ b/sshd-core/src/main/java/org/apache/sshd/common/session/helpers/AbstractSession.java @@ -44,7 +44,6 @@ import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicReference; -import org.apache.sshd.common.AttributeStore; import org.apache.sshd.common.Closeable; import org.apache.sshd.common.Factory; import org.apache.sshd.common.FactoryManager; @@ -2253,11 +2252,6 @@ public abstract class AbstractSession extends AbstractKexFactoryManager implemen } @Override - public <T> T resolveAttribute(AttributeKey<T> key) { - return AttributeStore.resolveAttribute(this, key); - } - - @Override public String getUsername() { return username; } http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-core/src/main/java/org/apache/sshd/common/signature/AbstractSignature.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/common/signature/AbstractSignature.java b/sshd-core/src/main/java/org/apache/sshd/common/signature/AbstractSignature.java deleted file mode 100644 index ef06d15..0000000 --- a/sshd-core/src/main/java/org/apache/sshd/common/signature/AbstractSignature.java +++ /dev/null @@ -1,149 +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.signature; - -import java.nio.charset.StandardCharsets; -import java.security.GeneralSecurityException; -import java.security.PrivateKey; -import java.security.PublicKey; -import java.security.SignatureException; -import java.util.AbstractMap.SimpleImmutableEntry; -import java.util.Objects; - -import org.apache.sshd.common.util.NumberUtils; -import org.apache.sshd.common.util.ValidateUtils; -import org.apache.sshd.common.util.buffer.BufferUtils; -import org.apache.sshd.common.util.security.SecurityUtils; - -/** - * Useful base class for {@link Signature} implementation - * - * @author <a href="mailto:[email protected]">Apache MINA SSHD Project</a> - */ -public abstract class AbstractSignature implements Signature { - private java.security.Signature signatureInstance; - private final String algorithm; - - protected AbstractSignature(String algorithm) { - this.algorithm = ValidateUtils.checkNotNullAndNotEmpty(algorithm, "No signature algorithm specified"); - } - - @Override - public final String getAlgorithm() { - return algorithm; - } - - /** - * Initializes the internal signature instance - * - * @param algo The signature's algorithm - * @param forSigning If {@code true} then it is being initialized for signing, - * otherwise for verifying a signature - * @return The {@link java.security.Signature} instance - * @throws GeneralSecurityException if failed to initialize - */ - protected java.security.Signature doInitSignature(String algo, boolean forSigning) throws GeneralSecurityException { - return SecurityUtils.getSignature(algo); - } - - /** - * @return The current {@link java.security.Signature} instance - * - {@code null} if not initialized - * @see #doInitSignature(String, boolean) - */ - protected java.security.Signature getSignature() { - return signatureInstance; - } - - @Override - public byte[] sign() throws Exception { - java.security.Signature signature = Objects.requireNonNull(getSignature(), "Signature not initialized"); - return signature.sign(); - } - - @Override - public void initVerifier(PublicKey key) throws Exception { - String algo = getAlgorithm(); - signatureInstance = Objects.requireNonNull(doInitSignature(algo, false), "No signature instance create"); - signatureInstance.initVerify(Objects.requireNonNull(key, "No public key provided")); - } - - @Override - public void initSigner(PrivateKey key) throws Exception { - String algo = getAlgorithm(); - signatureInstance = Objects.requireNonNull(doInitSignature(algo, true), "No signature instance create"); - signatureInstance.initSign(Objects.requireNonNull(key, "No private key provided")); - } - - @Override - public void update(byte[] hash, int off, int len) throws Exception { - java.security.Signature signature = Objects.requireNonNull(getSignature(), "Signature not initialized"); - signature.update(hash, off, len); - } - - /** - * Makes an attempt to detect if the signature is encoded or pure data - * - * @param sig The original signature - * @return A {@link SimpleImmutableEntry} where first value is the key type and second - * value is the data - {@code null} if not encoded - */ - protected SimpleImmutableEntry<String, byte[]> extractEncodedSignature(byte[] sig) { - final int dataLen = NumberUtils.length(sig); - // if it is encoded then we must have at least 2 UINT32 values - if (dataLen < (2 * Integer.BYTES)) { - return null; - } - - long keyTypeLen = BufferUtils.getUInt(sig, 0, dataLen); - // after the key type we MUST have data bytes - if (keyTypeLen >= (dataLen - Integer.BYTES)) { - return null; - } - - int keyTypeStartPos = Integer.BYTES; - int keyTypeEndPos = keyTypeStartPos + (int) keyTypeLen; - int remainLen = dataLen - keyTypeEndPos; - // must have UINT32 with the data bytes length - if (remainLen < Integer.BYTES) { - return null; - } - - long dataBytesLen = BufferUtils.getUInt(sig, keyTypeEndPos, remainLen); - // make sure reported number of bytes does not exceed available - if (dataBytesLen > (remainLen - Integer.BYTES)) { - return null; - } - - String keyType = new String(sig, keyTypeStartPos, (int) keyTypeLen, StandardCharsets.UTF_8); - byte[] data = new byte[(int) dataBytesLen]; - System.arraycopy(sig, keyTypeEndPos + Integer.BYTES, data, 0, (int) dataBytesLen); - return new SimpleImmutableEntry<>(keyType, data); - } - - protected boolean doVerify(byte[] data) throws SignatureException { - java.security.Signature signature = Objects.requireNonNull(getSignature(), "Signature not initialized"); - return signature.verify(data); - } - - @Override - public String toString() { - return getClass().getSimpleName() + "[" + getAlgorithm() + "]"; - } -} http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-core/src/main/java/org/apache/sshd/common/signature/BuiltinSignatures.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/common/signature/BuiltinSignatures.java b/sshd-core/src/main/java/org/apache/sshd/common/signature/BuiltinSignatures.java deleted file mode 100644 index 7d4e1e2..0000000 --- a/sshd-core/src/main/java/org/apache/sshd/common/signature/BuiltinSignatures.java +++ /dev/null @@ -1,305 +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.signature; - -import java.security.spec.ECParameterSpec; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.EnumSet; -import java.util.List; -import java.util.Map; -import java.util.NavigableSet; -import java.util.Objects; -import java.util.Set; -import java.util.TreeMap; - -import org.apache.sshd.common.NamedFactory; -import org.apache.sshd.common.NamedResource; -import org.apache.sshd.common.cipher.ECCurves; -import org.apache.sshd.common.config.NamedFactoriesListParseResult; -import org.apache.sshd.common.keyprovider.KeyPairProvider; -import org.apache.sshd.common.util.GenericUtils; -import org.apache.sshd.common.util.ValidateUtils; -import org.apache.sshd.common.util.security.SecurityUtils; - -/** - * Provides easy access to the currently implemented signatures - * - * @author <a href="mailto:[email protected]">Apache MINA SSHD Project</a> - */ -public enum BuiltinSignatures implements SignatureFactory { - dsa(KeyPairProvider.SSH_DSS) { - @Override - public Signature create() { - return new SignatureDSA(); - } - }, - rsa(KeyPairProvider.SSH_RSA) { - @Override - public Signature create() { - return new SignatureRSA(); - } - }, - nistp256(KeyPairProvider.ECDSA_SHA2_NISTP256) { - @Override - public Signature create() { - return new SignatureECDSA.SignatureECDSA256(); - } - - @Override - public boolean isSupported() { - return SecurityUtils.isECCSupported(); - } - }, - nistp384(KeyPairProvider.ECDSA_SHA2_NISTP384) { - @Override - public Signature create() { - return new SignatureECDSA.SignatureECDSA384(); - } - - @Override - public boolean isSupported() { - return SecurityUtils.isECCSupported(); - } - }, - nistp521(KeyPairProvider.ECDSA_SHA2_NISTP521) { - @Override - public Signature create() { - return new SignatureECDSA.SignatureECDSA521(); - } - - @Override - public boolean isSupported() { - return SecurityUtils.isECCSupported(); - } - }, - ed25519(KeyPairProvider.SSH_ED25519) { - @Override - public Signature create() { - return SecurityUtils.getEDDSASigner(); - } - - @Override - public boolean isSupported() { - return SecurityUtils.isEDDSACurveSupported(); - } - }; - - public static final Set<BuiltinSignatures> VALUES = - Collections.unmodifiableSet(EnumSet.allOf(BuiltinSignatures.class)); - - private static final Map<String, SignatureFactory> EXTENSIONS = - new TreeMap<>(String.CASE_INSENSITIVE_ORDER); - - private final String factoryName; - - BuiltinSignatures(String facName) { - factoryName = facName; - } - - public static Signature getByCurveSize(ECParameterSpec params) { - int curveSize = ECCurves.getCurveSize(params); - if (curveSize <= 256) { - return nistp256.create(); - } else if (curveSize <= 384) { - return nistp384.create(); - } else { - return nistp521.create(); - } - } - - @Override - public final String getName() { - return factoryName; - } - - @Override - public final String toString() { - return getName(); - } - - @Override - public boolean isSupported() { - return true; - } - - /** - * Registered a {@link NamedFactory} to be available besides the built-in - * ones when parsing configuration - * - * @param extension The factory to register - * @throws IllegalArgumentException if factory instance is {@code null}, - * or overrides a built-in one or overrides another registered factory - * with the same name (case <U>insensitive</U>). - */ - public static void registerExtension(SignatureFactory extension) { - String name = Objects.requireNonNull(extension, "No extension provided").getName(); - ValidateUtils.checkTrue(fromFactoryName(name) == null, "Extension overrides built-in: %s", name); - - synchronized (EXTENSIONS) { - ValidateUtils.checkTrue(!EXTENSIONS.containsKey(name), "Extension overrides existing: %s", name); - EXTENSIONS.put(name, extension); - } - } - - /** - * @return A {@link NavigableSet} of the currently registered extensions, sorted - * according to the factory name (case <U>insensitive</U>) - */ - public static NavigableSet<SignatureFactory> getRegisteredExtensions() { - synchronized (EXTENSIONS) { - return GenericUtils.asSortedSet(NamedResource.BY_NAME_COMPARATOR, EXTENSIONS.values()); - } - } - - /** - * Unregisters specified extension - * - * @param name The factory name - ignored if {@code null}/empty - * @return The registered extension - {@code null} if not found - */ - public static SignatureFactory unregisterExtension(String name) { - if (GenericUtils.isEmpty(name)) { - return null; - } - - synchronized (EXTENSIONS) { - return EXTENSIONS.remove(name); - } - } - - /** - * @param s The {@link Enum}'s name - ignored if {@code null}/empty - * @return The matching {@link org.apache.sshd.common.signature.BuiltinSignatures} whose {@link Enum#name()} matches - * (case <U>insensitive</U>) the provided argument - {@code null} if no match - */ - public static BuiltinSignatures fromString(String s) { - if (GenericUtils.isEmpty(s)) { - return null; - } - - for (BuiltinSignatures c : VALUES) { - if (s.equalsIgnoreCase(c.name())) { - return c; - } - } - - return null; - } - - /** - * @param factory The {@link org.apache.sshd.common.NamedFactory} for the signature - ignored if {@code null} - * @return The matching {@link org.apache.sshd.common.signature.BuiltinSignatures} whose factory name matches - * (case <U>insensitive</U>) the digest factory name - * @see #fromFactoryName(String) - */ - public static BuiltinSignatures fromFactory(NamedFactory<Signature> factory) { - if (factory == null) { - return null; - } else { - return fromFactoryName(factory.getName()); - } - } - - /** - * @param name The factory name - ignored if {@code null}/empty - * @return The matching {@link BuiltinSignatures} whose factory name matches - * (case <U>insensitive</U>) the provided name - {@code null} if no match - */ - public static BuiltinSignatures fromFactoryName(String name) { - return NamedResource.findByName(name, String.CASE_INSENSITIVE_ORDER, VALUES); - } - - /** - * @param sigs A comma-separated list of signatures' names - ignored - * if {@code null}/empty - * @return A {@link ParseResult} of all the {@link NamedFactory} whose - * name appears in the string and represent a built-in signature. Any - * unknown name is <U>ignored</U>. The order of the returned result - * is the same as the original order - bar the unknown signatures. - * <B>Note:</B> it is up to caller to ensure that the list does not - * contain duplicates - */ - public static ParseResult parseSignatureList(String sigs) { - return parseSignatureList(GenericUtils.split(sigs, ',')); - } - - public static ParseResult parseSignatureList(String... sigs) { - return parseSignatureList(GenericUtils.isEmpty((Object[]) sigs) ? Collections.emptyList() : Arrays.asList(sigs)); - } - - public static ParseResult parseSignatureList(Collection<String> sigs) { - if (GenericUtils.isEmpty(sigs)) { - return ParseResult.EMPTY; - } - - List<SignatureFactory> factories = new ArrayList<>(sigs.size()); - List<String> unknown = Collections.emptyList(); - for (String name : sigs) { - SignatureFactory s = resolveFactory(name); - if (s != null) { - factories.add(s); - } else { - // replace the (unmodifiable) empty list with a real one - if (unknown.isEmpty()) { - unknown = new ArrayList<>(); - } - unknown.add(name); - } - } - - return new ParseResult(factories, unknown); - } - - /** - * @param name The factory name - * @return The factory or {@code null} if it is neither a built-in one - * or a registered extension - */ - public static SignatureFactory resolveFactory(String name) { - if (GenericUtils.isEmpty(name)) { - return null; - } - - SignatureFactory s = fromFactoryName(name); - if (s != null) { - return s; - } - - synchronized (EXTENSIONS) { - return EXTENSIONS.get(name); - } - } - - /** - * Holds the result of the {@link BuiltinSignatures#parseSignatureList(String)} - * - * @author <a href="mailto:[email protected]">Apache MINA SSHD Project</a> - */ - public static final class ParseResult extends NamedFactoriesListParseResult<Signature, SignatureFactory> { - public static final ParseResult EMPTY = new ParseResult(Collections.emptyList(), Collections.emptyList()); - - public ParseResult(List<SignatureFactory> parsed, List<String> unsupported) { - super(parsed, unsupported); - } - } -} http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-core/src/main/java/org/apache/sshd/common/signature/Signature.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/common/signature/Signature.java b/sshd-core/src/main/java/org/apache/sshd/common/signature/Signature.java deleted file mode 100644 index fd88a1d..0000000 --- a/sshd-core/src/main/java/org/apache/sshd/common/signature/Signature.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.signature; - -import java.security.PrivateKey; -import java.security.PublicKey; - -import org.apache.sshd.common.util.NumberUtils; - -/** - * Signature interface for SSH used to sign or verify packets - * Usually wraps a javax.crypto.Signature object - * - * @author <a href="mailto:[email protected]">Apache MINA SSHD Project</a> - */ -public interface Signature { - /** - * @return The signature algorithm name - */ - String getAlgorithm(); - - /** - * @param key The {@link PublicKey} to be used for verifying signatures - * @throws Exception If failed to initialize - */ - void initVerifier(PublicKey key) throws Exception; - - /** - * @param key The {@link PrivateKey} to be used for signing - * @throws Exception If failed to initialize - */ - void initSigner(PrivateKey key) throws Exception; - - /** - * Update the computed signature with the given data - * - * @param hash The hash data buffer - * @throws Exception If failed to update - * @see #update(byte[], int, int) - */ - default void update(byte[] hash) throws Exception { - update(hash, 0, NumberUtils.length(hash)); - } - - /** - * Update the computed signature with the given data - * - * @param hash The hash data buffer - * @param off Offset of hash data in buffer - * @param len Length of hash data - * @throws Exception If failed to update - */ - void update(byte[] hash, int off, int len) throws Exception; - - /** - * Verify against the given signature - * - * @param sig The signed data - * @return {@code true} if signature is valid - * @throws Exception If failed to extract signed data for validation - */ - boolean verify(byte[] sig) throws Exception; - - /** - * Compute the signature - * - * @return The signature value - * @throws Exception If failed to calculate the signature - */ - byte[] sign() throws Exception; - -} http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-core/src/main/java/org/apache/sshd/common/signature/SignatureDSA.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/common/signature/SignatureDSA.java b/sshd-core/src/main/java/org/apache/sshd/common/signature/SignatureDSA.java deleted file mode 100644 index 1f552bd..0000000 --- a/sshd-core/src/main/java/org/apache/sshd/common/signature/SignatureDSA.java +++ /dev/null @@ -1,142 +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.signature; - -import java.io.StreamCorruptedException; -import java.math.BigInteger; -import java.security.SignatureException; -import java.util.Map; - -import org.apache.sshd.common.keyprovider.KeyPairProvider; -import org.apache.sshd.common.util.NumberUtils; -import org.apache.sshd.common.util.ValidateUtils; -import org.apache.sshd.common.util.buffer.BufferUtils; -import org.apache.sshd.common.util.io.der.DERParser; -import org.apache.sshd.common.util.io.der.DERWriter; - - -/** - * DSA <code>Signature</code> - * - * @author <a href="mailto:[email protected]">Apache MINA SSHD Project</a> - * @see <A HREF="https://tools.ietf.org/html/rfc4253#section-6.6">RFC4253 section 6.6</A> - */ -public class SignatureDSA extends AbstractSignature { - public static final String DEFAULT_ALGORITHM = "SHA1withDSA"; - - public static final int DSA_SIGNATURE_LENGTH = 40; - // result must be 40 bytes, but length of r and s may not exceed 20 bytes - public static final int MAX_SIGNATURE_VALUE_LENGTH = DSA_SIGNATURE_LENGTH / 2; - - public SignatureDSA() { - this(DEFAULT_ALGORITHM); - } - - protected SignatureDSA(String algorithm) { - super(algorithm); - } - - @Override - public byte[] sign() throws Exception { - byte[] sig = super.sign(); - - try (DERParser parser = new DERParser(sig)) { - int type = parser.read(); - if (type != 0x30) { - throw new StreamCorruptedException("Invalid signature format - not a DER SEQUENCE: 0x" + Integer.toHexString(type)); - } - - // length of remaining encoding of the 2 integers - int remainLen = parser.readLength(); - /* - * There are supposed to be 2 INTEGERs, each encoded with: - * - * - one byte representing the fact that it is an INTEGER - * - one byte of the integer encoding length - * - at least one byte of integer data (zero length is not an option) - */ - if (remainLen < (2 * 3)) { - throw new StreamCorruptedException("Invalid signature format - not enough encoded data length: " + remainLen); - } - - BigInteger r = parser.readBigInteger(); - BigInteger s = parser.readBigInteger(); - - byte[] result = new byte[DSA_SIGNATURE_LENGTH]; - putBigInteger(r, result, 0); - putBigInteger(s, result, MAX_SIGNATURE_VALUE_LENGTH); - return result; - } - } - - public static void putBigInteger(BigInteger value, byte[] result, int offset) { - byte[] data = value.toByteArray(); - boolean maxExceeded = data.length > MAX_SIGNATURE_VALUE_LENGTH; - int dstOffset = maxExceeded ? 0 : (MAX_SIGNATURE_VALUE_LENGTH - data.length); - System.arraycopy(data, maxExceeded ? 1 : 0, - result, offset + dstOffset, - Math.min(MAX_SIGNATURE_VALUE_LENGTH, data.length)); - } - - @Override - public boolean verify(byte[] sig) throws Exception { - int sigLen = NumberUtils.length(sig); - byte[] data = sig; - - if (sigLen != DSA_SIGNATURE_LENGTH) { - // probably some encoded data - Map.Entry<String, byte[]> encoding = extractEncodedSignature(sig); - if (encoding != null) { - String keyType = encoding.getKey(); - ValidateUtils.checkTrue(KeyPairProvider.SSH_DSS.equals(keyType), "Mismatched key type: %s", keyType); - data = encoding.getValue(); - sigLen = NumberUtils.length(data); - } - } - - if (sigLen != DSA_SIGNATURE_LENGTH) { - throw new SignatureException("Bad signature length (" + sigLen + " instead of " + DSA_SIGNATURE_LENGTH + ")" - + " for " + BufferUtils.toHex(':', data)); - } - - byte[] rEncoding; - try (DERWriter w = new DERWriter(MAX_SIGNATURE_VALUE_LENGTH + 4)) { // in case length > 0x7F - w.writeBigInteger(data, 0, MAX_SIGNATURE_VALUE_LENGTH); - rEncoding = w.toByteArray(); - } - - byte[] sEncoding; - try (DERWriter w = new DERWriter(MAX_SIGNATURE_VALUE_LENGTH + 4)) { // in case length > 0x7F - w.writeBigInteger(data, MAX_SIGNATURE_VALUE_LENGTH, MAX_SIGNATURE_VALUE_LENGTH); - sEncoding = w.toByteArray(); - } - - int length = rEncoding.length + sEncoding.length; - byte[] encoded; - try (DERWriter w = new DERWriter(1 + length + 4)) { // in case length > 0x7F - w.write(0x30); // SEQUENCE - w.writeLength(length); - w.write(rEncoding); - w.write(sEncoding); - encoded = w.toByteArray(); - } - - return doVerify(encoded); - } -} http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-core/src/main/java/org/apache/sshd/common/signature/SignatureECDSA.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/common/signature/SignatureECDSA.java b/sshd-core/src/main/java/org/apache/sshd/common/signature/SignatureECDSA.java deleted file mode 100644 index 56964d3..0000000 --- a/sshd-core/src/main/java/org/apache/sshd/common/signature/SignatureECDSA.java +++ /dev/null @@ -1,144 +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.signature; - -import java.io.StreamCorruptedException; -import java.math.BigInteger; -import java.util.Map; - -import org.apache.sshd.common.cipher.ECCurves; -import org.apache.sshd.common.util.ValidateUtils; -import org.apache.sshd.common.util.buffer.Buffer; -import org.apache.sshd.common.util.buffer.ByteArrayBuffer; -import org.apache.sshd.common.util.io.der.DERParser; -import org.apache.sshd.common.util.io.der.DERWriter; - -/** - * Signature algorithm for EC keys using ECDSA. - * - * @author <a href="mailto:[email protected]">Apache MINA SSHD Project</a> - * @see <A HREF="http://tools.ietf.org/html/rfc3278#section-8.2">RFC3278 section 8.2</A> - */ -public class SignatureECDSA extends AbstractSignature { - public static class SignatureECDSA256 extends SignatureECDSA { - public static final String DEFAULT_ALGORITHM = "SHA256withECDSA"; - - public SignatureECDSA256() { - super(DEFAULT_ALGORITHM); - } - } - - public static class SignatureECDSA384 extends SignatureECDSA { - public static final String DEFAULT_ALGORITHM = "SHA384withECDSA"; - - public SignatureECDSA384() { - super(DEFAULT_ALGORITHM); - } - } - - public static class SignatureECDSA521 extends SignatureECDSA { - public static final String DEFAULT_ALGORITHM = "SHA512withECDSA"; - - public SignatureECDSA521() { - super(DEFAULT_ALGORITHM); - } - } - - protected SignatureECDSA(String algo) { - super(algo); - } - - @Override - public byte[] sign() throws Exception { - byte[] sig = super.sign(); - - try (DERParser parser = new DERParser(sig)) { - int type = parser.read(); - if (type != 0x30) { - throw new StreamCorruptedException("Invalid signature format - not a DER SEQUENCE: 0x" + Integer.toHexString(type)); - } - - // length of remaining encoding of the 2 integers - int remainLen = parser.readLength(); - /* - * There are supposed to be 2 INTEGERs, each encoded with: - * - * - one byte representing the fact that it is an INTEGER - * - one byte of the integer encoding length - * - at least one byte of integer data (zero length is not an option) - */ - if (remainLen < (2 * 3)) { - throw new StreamCorruptedException("Invalid signature format - not enough encoded data length: " + remainLen); - } - - BigInteger r = parser.readBigInteger(); - BigInteger s = parser.readBigInteger(); - // Write the <r,s> to its own types writer. - Buffer rsBuf = new ByteArrayBuffer(); - rsBuf.putMPInt(r); - rsBuf.putMPInt(s); - - return rsBuf.getCompactData(); - } - } - - @Override - public boolean verify(byte[] sig) throws Exception { - byte[] data = sig; - Map.Entry<String, byte[]> encoding = extractEncodedSignature(data); - if (encoding != null) { - String keyType = encoding.getKey(); - ECCurves curve = ECCurves.fromKeyType(keyType); - ValidateUtils.checkNotNull(curve, "Unknown curve type: %s", keyType); - data = encoding.getValue(); - } - - Buffer rsBuf = new ByteArrayBuffer(data); - byte[] rArray = rsBuf.getMPIntAsBytes(); - byte[] rEncoding; - try (DERWriter w = new DERWriter(rArray.length + 4)) { // in case length > 0x7F - w.writeBigInteger(rArray); - rEncoding = w.toByteArray(); - } - - byte[] sArray = rsBuf.getMPIntAsBytes(); - byte[] sEncoding; - try (DERWriter w = new DERWriter(sArray.length + 4)) { // in case length > 0x7F - w.writeBigInteger(sArray); - sEncoding = w.toByteArray(); - } - - int remaining = rsBuf.available(); - if (remaining != 0) { - throw new StreamCorruptedException("Signature had padding - remaining=" + remaining); - } - - int length = rEncoding.length + sEncoding.length; - byte[] encoded; - try (DERWriter w = new DERWriter(1 + length + 4)) { // in case length > 0x7F - w.write(0x30); // SEQUENCE - w.writeLength(length); - w.write(rEncoding); - w.write(sEncoding); - encoded = w.toByteArray(); - } - - return doVerify(encoded); - } -}
