http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/17f2d627/sshd-core/src/main/java/org/apache/sshd/common/config/SyslogFacilityValue.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/common/config/SyslogFacilityValue.java b/sshd-core/src/main/java/org/apache/sshd/common/config/SyslogFacilityValue.java index 680ef61..8d5dfd1 100644 --- a/sshd-core/src/main/java/org/apache/sshd/common/config/SyslogFacilityValue.java +++ b/sshd-core/src/main/java/org/apache/sshd/common/config/SyslogFacilityValue.java @@ -32,7 +32,7 @@ import org.apache.sshd.common.util.GenericUtils; public enum SyslogFacilityValue { DAEMON, USER, AUTH, LOCAL0, LOCAL1, LOCAL2, LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7; - public static final Set<SyslogFacilityValue> VALUES= + public static final Set<SyslogFacilityValue> VALUES = Collections.unmodifiableSet(EnumSet.allOf(SyslogFacilityValue.class)); public static SyslogFacilityValue fromName(String n) {
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/17f2d627/sshd-core/src/main/java/org/apache/sshd/common/config/TimeValueConfig.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/common/config/TimeValueConfig.java b/sshd-core/src/main/java/org/apache/sshd/common/config/TimeValueConfig.java index 41875cd..5c890d2 100644 --- a/sshd-core/src/main/java/org/apache/sshd/common/config/TimeValueConfig.java +++ b/sshd-core/src/main/java/org/apache/sshd/common/config/TimeValueConfig.java @@ -39,7 +39,19 @@ public enum TimeValueConfig { DAYS('d', 'D', TimeUnit.DAYS.toMillis(1L)), WEEKS('w', 'W', TimeUnit.DAYS.toMillis(7L)); - private final char loChar, hiChar; + public static final Set<TimeValueConfig> VALUES = + Collections.unmodifiableSet(EnumSet.allOf(TimeValueConfig.class)); + + private final char loChar; + private final char hiChar; + private final long interval; + + TimeValueConfig(char lo, char hi, long interval) { + loChar = lo; + hiChar = hi; + this.interval = interval; + } + public final char getLowerCaseValue() { return loChar; } @@ -48,20 +60,10 @@ public enum TimeValueConfig { return hiChar; } - private final long interval; public final long getInterval() { return interval; } - TimeValueConfig(char lo, char hi, long duration) { - loChar = lo; - hiChar = hi; - interval = duration; - } - - public static final Set<TimeValueConfig> VALUES= - Collections.unmodifiableSet(EnumSet.allOf(TimeValueConfig.class)); - public static TimeValueConfig fromValueChar(char ch) { if ((ch <= ' ') || (ch >= 0x7F)) { return null; @@ -83,26 +85,26 @@ public enum TimeValueConfig { * @see #durationOf(Map) */ public static long durationOf(String s) { - Map<TimeValueConfig,Long> spec=parse(s); + Map<TimeValueConfig, Long> spec = parse(s); return durationOf(spec); } /** * @param s An input time specification containing possibly mixed numbers - * and units - e.g., {@code 3h10m} to indicate 3 hours and 10 minutes + * and units - e.g., {@code 3h10m} to indicate 3 hours and 10 minutes * @return A {@link Map} specifying for each time unit its count - * @throws NumberFormatException If bad numbers found - e.g., negative counts + * @throws NumberFormatException If bad numbers found - e.g., negative counts * @throws IllegalArgumentException If bad format - e.g., unknown unit */ - public static Map<TimeValueConfig,Long> parse(String s) throws NumberFormatException, IllegalArgumentException { + public static Map<TimeValueConfig, Long> parse(String s) throws NumberFormatException, IllegalArgumentException { if (GenericUtils.isEmpty(s)) { return Collections.emptyMap(); } - int lastPos=0; - Map<TimeValueConfig,Long> spec=new EnumMap<TimeValueConfig,Long>(TimeValueConfig.class); - for (int curPos=0; curPos < s.length(); curPos++) { - char ch=s.charAt(curPos); + int lastPos = 0; + Map<TimeValueConfig, Long> spec = new EnumMap<TimeValueConfig, Long>(TimeValueConfig.class); + for (int curPos = 0; curPos < s.length(); curPos++) { + char ch = s.charAt(curPos); if ((ch >= '0') && (ch <= '9')) { continue; } @@ -111,35 +113,36 @@ public enum TimeValueConfig { throw new IllegalArgumentException("parse(" + s + ") missing count value at index=" + curPos); } - TimeValueConfig c=fromValueChar(ch); + TimeValueConfig c = fromValueChar(ch); if (c == null) { throw new IllegalArgumentException("parse(" + s + ") unknown time value character: " + String.valueOf(ch)); } - String v=s.substring(lastPos, curPos); - long count=Long.parseLong(v); + String v = s.substring(lastPos, curPos); + long count = Long.parseLong(v); if (count < 0L) { throw new IllegalArgumentException("parse(" + s + ") negative count (" + v + ") for " + c.name()); } - Long prev=spec.put(c, count); + Long prev = spec.put(c, count); if (prev != null) { throw new IllegalArgumentException("parse(" + s + ") " + c.name() + " value re-specified: current=" + count + ", previous=" + prev); } - if ((lastPos=curPos+1) >= s.length()) { + lastPos = curPos + 1; + if (lastPos >= s.length()) { break; } } if (lastPos < s.length()) { - String v=s.substring(lastPos); - long count=Long.parseLong(v); + String v = s.substring(lastPos); + long count = Long.parseLong(v); if (count < 0L) { throw new IllegalArgumentException("parse(" + s + ") negative count (" + v + ") for last component"); } - Long prev=spec.put(SECONDS, count); + Long prev = spec.put(SECONDS, count); if (prev != null) { throw new IllegalArgumentException("parse(" + s + ") last component (" + SECONDS.name() + ") value re-specified: current=" + count + ", previous=" + prev); } @@ -153,21 +156,21 @@ public enum TimeValueConfig { * @return The total duration in milliseconds * @throws IllegalArgumentException If negative count for a time unit */ - public static long durationOf(Map<TimeValueConfig,? extends Number> spec) throws IllegalArgumentException { + public static long durationOf(Map<TimeValueConfig, ? extends Number> spec) throws IllegalArgumentException { if (GenericUtils.isEmpty(spec)) { - return (-1L); + return -1L; } - long total=0L; - for (Map.Entry<TimeValueConfig,? extends Number> se : spec.entrySet()) { - TimeValueConfig v=se.getKey(); - Number c=se.getValue(); - long factor=c.longValue(); + long total = 0L; + for (Map.Entry<TimeValueConfig, ? extends Number> se : spec.entrySet()) { + TimeValueConfig v = se.getKey(); + Number c = se.getValue(); + long factor = c.longValue(); if (factor < 0L) { throw new IllegalArgumentException("valueOf(" + spec + ") bad factor (" + c + ") for " + v.name()); } - long added=v.getInterval() * factor; + long added = v.getInterval() * factor; total += added; } http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/17f2d627/sshd-core/src/main/java/org/apache/sshd/common/config/VersionProperties.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/common/config/VersionProperties.java b/sshd-core/src/main/java/org/apache/sshd/common/config/VersionProperties.java index 7f3e73a..d9d0f83 100644 --- a/sshd-core/src/main/java/org/apache/sshd/common/config/VersionProperties.java +++ b/sshd-core/src/main/java/org/apache/sshd/common/config/VersionProperties.java @@ -36,34 +36,34 @@ import org.slf4j.LoggerFactory; */ public final class VersionProperties { private static class LazyHolder { - private static final Map<String,String> properties = + private static final Map<String, String> PROPERTIES = Collections.unmodifiableMap(loadVersionProperties(LazyHolder.class)); - - private static Map<String,String> loadVersionProperties(Class<?> anchor) { + + private static Map<String, String> loadVersionProperties(Class<?> anchor) { return loadVersionProperties(anchor, ThreadUtils.resolveDefaultClassLoader(anchor)); } - private static Map<String,String> loadVersionProperties(Class<?> anchor, ClassLoader loader) { - Map<String,String> result = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); + private static Map<String, String> loadVersionProperties(Class<?> anchor, ClassLoader loader) { + Map<String, String> result = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); try { InputStream input = loader.getResourceAsStream("org/apache/sshd/sshd-version.properties"); if (input == null) { throw new FileNotFoundException("Resource does not exists"); } - + Properties props = new Properties(); try { props.load(input); } finally { input.close(); } - + for (String key : props.stringPropertyNames()) { String value = GenericUtils.trimToEmpty(props.getProperty(key)); if (GenericUtils.isEmpty(value)) { continue; // we have no need for empty value } - + String prev = result.put(key, value); if (prev != null) { Logger log = LoggerFactory.getLogger(anchor); @@ -74,17 +74,18 @@ public final class VersionProperties { Logger log = LoggerFactory.getLogger(anchor); log.warn("Failed (" + e.getClass().getSimpleName() + ") to load version properties: " + e.getMessage()); } - + return result; } } - - @SuppressWarnings("synthetic-access") - public static Map<String,String> getVersionProperties() { - return LazyHolder.properties; - } - + private VersionProperties() { throw new UnsupportedOperationException("No instance"); } + + @SuppressWarnings("synthetic-access") + public static Map<String, String> getVersionProperties() { + return LazyHolder.PROPERTIES; + } + } http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/17f2d627/sshd-core/src/main/java/org/apache/sshd/common/config/keys/AbstractPublicKeyEntryDecoder.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/common/config/keys/AbstractPublicKeyEntryDecoder.java b/sshd-core/src/main/java/org/apache/sshd/common/config/keys/AbstractPublicKeyEntryDecoder.java index 555bcc9..e471806 100644 --- a/sshd-core/src/main/java/org/apache/sshd/common/config/keys/AbstractPublicKeyEntryDecoder.java +++ b/sshd-core/src/main/java/org/apache/sshd/common/config/keys/AbstractPublicKeyEntryDecoder.java @@ -45,12 +45,13 @@ import org.apache.sshd.common.util.io.IoUtils; /** * @author <a href="mailto:[email protected]">Apache MINA SSHD Project</a> */ -public abstract class AbstractPublicKeyEntryDecoder<PUB extends PublicKey,PRV extends PrivateKey> - implements PublicKeyEntryDecoder<PUB,PRV> { +public abstract class AbstractPublicKeyEntryDecoder<PUB extends PublicKey, PRV extends PrivateKey> + implements PublicKeyEntryDecoder<PUB, PRV> { + private final Class<PUB> pubType; private final Class<PRV> prvType; - private final Collection<String> names; - + private final Collection<String> names; + protected AbstractPublicKeyEntryDecoder(Class<PUB> pubType, Class<PRV> prvType, Collection<String> names) { this.pubType = ValidateUtils.checkNotNull(pubType, "No public key type specified"); this.prvType = ValidateUtils.checkNotNull(prvType, "No private key type specified"); @@ -72,33 +73,29 @@ public abstract class AbstractPublicKeyEntryDecoder<PUB extends PublicKey,PRV ex if (kp == null) { return null; } - + PUB pubCloned = null; - { - PublicKey pubOriginal = kp.getPublic(); - Class<PUB> pubExpected = getPublicKeyType(); - if (pubOriginal != null) { - Class<?> orgType = pubOriginal.getClass(); - if (!pubExpected.isAssignableFrom(orgType)) { - throw new InvalidKeyException("Mismatched public key types: expected=" + pubExpected.getSimpleName() + ", actual=" + orgType.getSimpleName()); - } - - pubCloned = clonePublicKey(pubExpected.cast(pubOriginal)); + PublicKey pubOriginal = kp.getPublic(); + Class<PUB> pubExpected = getPublicKeyType(); + if (pubOriginal != null) { + Class<?> orgType = pubOriginal.getClass(); + if (!pubExpected.isAssignableFrom(orgType)) { + throw new InvalidKeyException("Mismatched public key types: expected=" + pubExpected.getSimpleName() + ", actual=" + orgType.getSimpleName()); } + + pubCloned = clonePublicKey(pubExpected.cast(pubOriginal)); } PRV prvCloned = null; - { - PrivateKey prvOriginal = kp.getPrivate(); - Class<PRV> prvExpected = getPrivateKeyType(); - if (prvOriginal != null) { - Class<?> orgType = prvOriginal.getClass(); - if (!prvExpected.isAssignableFrom(orgType)) { - throw new InvalidKeyException("Mismatched private key types: expected=" + prvExpected.getSimpleName() + ", actual=" + orgType.getSimpleName()); - } - - prvCloned = clonePrivateKey(prvExpected.cast(prvOriginal)); + PrivateKey prvOriginal = kp.getPrivate(); + Class<PRV> prvExpected = getPrivateKeyType(); + if (prvOriginal != null) { + Class<?> orgType = prvOriginal.getClass(); + if (!prvExpected.isAssignableFrom(orgType)) { + throw new InvalidKeyException("Mismatched private key types: expected=" + prvExpected.getSimpleName() + ", actual=" + orgType.getSimpleName()); } + + prvCloned = clonePrivateKey(prvExpected.cast(prvOriginal)); } return new KeyPair(pubCloned, prvCloned); @@ -120,7 +117,7 @@ public abstract class AbstractPublicKeyEntryDecoder<PUB extends PublicKey,PRV ex return null; } - try(InputStream stream=new ByteArrayInputStream(keyData, offset, length)) { + try (InputStream stream = new ByteArrayInputStream(keyData, offset, length)) { return decodePublicKey(stream); } } @@ -142,30 +139,30 @@ public abstract class AbstractPublicKeyEntryDecoder<PUB extends PublicKey,PRV ex } public PUB generatePublicKey(KeySpec keySpec) throws GeneralSecurityException { - KeyFactory factory = getKeyFactoryInstance(); - Class<PUB> keyType = getPublicKeyType(); + KeyFactory factory = getKeyFactoryInstance(); + Class<PUB> keyType = getPublicKeyType(); return keyType.cast(factory.generatePublic(keySpec)); } public PRV generatePrivateKey(KeySpec keySpec) throws GeneralSecurityException { - KeyFactory factory = getKeyFactoryInstance(); - Class<PRV> keyType = getPrivateKeyType(); + KeyFactory factory = getKeyFactoryInstance(); + Class<PRV> keyType = getPrivateKeyType(); return keyType.cast(factory.generatePrivate(keySpec)); } /** * @param keyType The reported / encode key type * @param keyData The key data bytes stream positioned after the key type decoding - * and making sure it is one of the supported types + * and making sure it is one of the supported types * @return The decoded {@link PublicKey} - * @throws IOException If failed to read from the data stream + * @throws IOException If failed to read from the data stream * @throws GeneralSecurityException If failed to generate the key */ public abstract PUB decodePublicKey(String keyType, InputStream keyData) throws IOException, GeneralSecurityException; @Override public KeyPair generateKeyPair(int keySize) throws GeneralSecurityException { - KeyPairGenerator gen=getKeyPairGenerator(); + KeyPairGenerator gen = getKeyPairGenerator(); gen.initialize(keySize); return gen.generateKeyPair(); } @@ -191,23 +188,23 @@ public abstract class AbstractPublicKeyEntryDecoder<PUB extends PublicKey,PRV ex return writeRLEBytes(s, v.toByteArray()); } - public static int writeRLEBytes(OutputStream s, byte ... bytes) throws IOException { + public static int writeRLEBytes(OutputStream s, byte... bytes) throws IOException { return writeRLEBytes(s, bytes, 0, bytes.length); } public static int writeRLEBytes(OutputStream s, byte[] bytes, int off, int len) throws IOException { - byte[] lenBytes=encodeInt(s, len); + byte[] lenBytes = encodeInt(s, len); s.write(bytes, off, len); return lenBytes.length + len; } public static byte[] encodeInt(OutputStream s, int v) throws IOException { - byte[] bytes={ - (byte) ((v >> 24) & 0xFF), - (byte) ((v >> 16) & 0xFF), - (byte) ((v >> 8) & 0xFF), - (byte) ( v & 0xFF) - }; + byte[] bytes = { + (byte) ((v >> 24) & 0xFF), + (byte) ((v >> 16) & 0xFF), + (byte) ((v >> 8) & 0xFF), + (byte) (v & 0xFF) + }; s.write(bytes); return bytes; } @@ -221,7 +218,7 @@ public abstract class AbstractPublicKeyEntryDecoder<PUB extends PublicKey,PRV ex } public static String decodeString(InputStream s, Charset cs) throws IOException { - byte[] bytes=readRLEBytes(s); + byte[] bytes = readRLEBytes(s); return new String(bytes, cs); } @@ -230,18 +227,18 @@ public abstract class AbstractPublicKeyEntryDecoder<PUB extends PublicKey,PRV ex } public static byte[] readRLEBytes(InputStream s) throws IOException { - int len=decodeInt(s); - byte[] bytes=new byte[len]; + int len = decodeInt(s); + byte[] bytes = new byte[len]; IoUtils.readFully(s, bytes); return bytes; } public static int decodeInt(InputStream s) throws IOException { - byte[] bytes={ 0, 0, 0, 0 }; + byte[] bytes = {0, 0, 0, 0}; IoUtils.readFully(s, bytes); return ((bytes[0] & 0xFF) << 24) - | ((bytes[1] & 0xFF) << 16) - | ((bytes[2] & 0xFF) << 8) - | (bytes[3] & 0xFF); + | ((bytes[1] & 0xFF) << 16) + | ((bytes[2] & 0xFF) << 8) + | (bytes[3] & 0xFF); } } http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/17f2d627/sshd-core/src/main/java/org/apache/sshd/common/config/keys/BuiltinIdentities.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/common/config/keys/BuiltinIdentities.java b/sshd-core/src/main/java/org/apache/sshd/common/config/keys/BuiltinIdentities.java index 167d004..bf74ff3 100644 --- a/sshd-core/src/main/java/org/apache/sshd/common/config/keys/BuiltinIdentities.java +++ b/sshd-core/src/main/java/org/apache/sshd/common/config/keys/BuiltinIdentities.java @@ -52,10 +52,34 @@ public enum BuiltinIdentities implements Identity { } }; - private final String name, algorithm; + public static final Set<BuiltinIdentities> VALUES = + Collections.unmodifiableSet(EnumSet.allOf(BuiltinIdentities.class)); + + public static final Set<String> NAMES = + Collections.unmodifiableSet(new TreeSet<String>(String.CASE_INSENSITIVE_ORDER) { + private static final long serialVersionUID = 1L; // we're not serializing it + + { + addAll(NamedResource.Utils.getNameList(VALUES)); + } + }); + + private final String name; + private final String algorithm; private final Class<? extends PublicKey> pubType; private final Class<? extends PrivateKey> prvType; - + + BuiltinIdentities(String type, Class<? extends PublicKey> pubType, Class<? extends PrivateKey> prvType) { + this(type, type, pubType, prvType); + } + + BuiltinIdentities(String name, String algorithm, Class<? extends PublicKey> pubType, Class<? extends PrivateKey> prvType) { + this.name = name.toLowerCase(); + this.algorithm = algorithm.toUpperCase(); + this.pubType = pubType; + this.prvType = prvType; + } + @Override public final String getName() { return name; @@ -81,29 +105,6 @@ public enum BuiltinIdentities implements Identity { return prvType; } - BuiltinIdentities(String type, Class<? extends PublicKey> pubType, Class<? extends PrivateKey> prvType) { - this(type, type, pubType, prvType); - } - - BuiltinIdentities(String name, String algorithm, Class<? extends PublicKey> pubType, Class<? extends PrivateKey> prvType) { - this.name = name.toLowerCase(); - this.algorithm = algorithm.toUpperCase(); - this.pubType = pubType; - this.prvType = prvType; - } - - public static final Set<BuiltinIdentities> VALUES = - Collections.unmodifiableSet(EnumSet.allOf(BuiltinIdentities.class)); - - public static final Set<String> NAMES = - Collections.unmodifiableSet(new TreeSet<String>(String.CASE_INSENSITIVE_ORDER) { - private static final long serialVersionUID = 1L; // we're not serializing it - - { - addAll(NamedResource.Utils.getNameList(VALUES)); - } - }); - /** * @param name The identity name - ignored if {@code null}/empty * @return The matching {@link BuiltinIdentities} whose {@link #getName()} @@ -122,13 +123,13 @@ public enum BuiltinIdentities implements Identity { if (GenericUtils.isEmpty(algorithm)) { return null; } - + for (BuiltinIdentities id : VALUES) { if (algorithm.equalsIgnoreCase(id.getAlgorithm())) { return id; } } - + return null; } @@ -144,8 +145,8 @@ public enum BuiltinIdentities implements Identity { return null; } - BuiltinIdentities i1 = fromKey(kp.getPublic()); - BuiltinIdentities i2 = fromKey(kp.getPrivate()); + BuiltinIdentities i1 = fromKey(kp.getPublic()); + BuiltinIdentities i2 = fromKey(kp.getPrivate()); if (Objects.equals(i1, i2)) { return i1; } else { @@ -165,11 +166,11 @@ public enum BuiltinIdentities implements Identity { /** * @param clazz The key type - ignored if {@code null} or not - * a {@link Key} class + * a {@link Key} class * @return The matching {@link BuiltinIdentities} whose either public or * private key type matches the requested one or {@code null} if no match found * @see #getPublicKeyType() - * @see #getPrivateKeyType() + * @see #getPrivateKeyType() */ public static BuiltinIdentities fromKeyType(Class<?> clazz) { if ((clazz == null) || (!Key.class.isAssignableFrom(clazz))) { @@ -177,12 +178,13 @@ public enum BuiltinIdentities implements Identity { } for (BuiltinIdentities id : VALUES) { - Class<?> pubType = id.getPublicKeyType(), prvType = id.getPrivateKeyType(); + Class<?> pubType = id.getPublicKeyType(); + Class<?> prvType = id.getPrivateKeyType(); if (pubType.isAssignableFrom(clazz) || prvType.isAssignableFrom(clazz)) { return id; } } - + return null; } http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/17f2d627/sshd-core/src/main/java/org/apache/sshd/common/config/keys/DSSPublicKeyEntryDecoder.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/common/config/keys/DSSPublicKeyEntryDecoder.java b/sshd-core/src/main/java/org/apache/sshd/common/config/keys/DSSPublicKeyEntryDecoder.java index b9b7712..3bd5667 100644 --- a/sshd-core/src/main/java/org/apache/sshd/common/config/keys/DSSPublicKeyEntryDecoder.java +++ b/sshd-core/src/main/java/org/apache/sshd/common/config/keys/DSSPublicKeyEntryDecoder.java @@ -36,14 +36,13 @@ import java.security.spec.InvalidKeySpecException; import java.util.Collections; import org.apache.sshd.common.keyprovider.KeyPairProvider; -import org.apache.sshd.common.util.GenericUtils; import org.apache.sshd.common.util.SecurityUtils; import org.apache.sshd.common.util.ValidateUtils; /** * @author <a href="mailto:[email protected]">Apache MINA SSHD Project</a> */ -public class DSSPublicKeyEntryDecoder extends AbstractPublicKeyEntryDecoder<DSAPublicKey,DSAPrivateKey> { +public class DSSPublicKeyEntryDecoder extends AbstractPublicKeyEntryDecoder<DSAPublicKey, DSAPrivateKey> { public static final DSSPublicKeyEntryDecoder INSTANCE = new DSSPublicKeyEntryDecoder(); public DSSPublicKeyEntryDecoder() { @@ -56,10 +55,10 @@ public class DSSPublicKeyEntryDecoder extends AbstractPublicKeyEntryDecoder<DSAP throw new InvalidKeySpecException("Unepected key type: " + keyType); } - BigInteger p=decodeBigInt(keyData); - BigInteger q=decodeBigInt(keyData); - BigInteger g=decodeBigInt(keyData); - BigInteger y=decodeBigInt(keyData); + BigInteger p = decodeBigInt(keyData); + BigInteger q = decodeBigInt(keyData); + BigInteger g = decodeBigInt(keyData); + BigInteger y = decodeBigInt(keyData); return generatePublicKey(new DSAPublicKeySpec(y, p, q, g)); } @@ -74,7 +73,7 @@ public class DSSPublicKeyEntryDecoder extends AbstractPublicKeyEntryDecoder<DSAP encodeBigInt(s, keyParams.getQ()); encodeBigInt(s, keyParams.getG()); encodeBigInt(s, key.getY()); - + return KeyPairProvider.SSH_DSS; } @@ -83,10 +82,10 @@ public class DSSPublicKeyEntryDecoder extends AbstractPublicKeyEntryDecoder<DSAP if (key == null) { return null; } - + DSAParams params = key.getParams(); if (params == null) { - throw new InvalidKeyException("Missing parameters in key"); + throw new InvalidKeyException("Missing parameters in key"); } return generatePublicKey(new DSAPublicKeySpec(key.getY(), params.getP(), params.getQ(), params.getG())); @@ -97,10 +96,10 @@ public class DSSPublicKeyEntryDecoder extends AbstractPublicKeyEntryDecoder<DSAP if (key == null) { return null; } - + DSAParams params = key.getParams(); if (params == null) { - throw new InvalidKeyException("Missing parameters in key"); + throw new InvalidKeyException("Missing parameters in key"); } return generatePrivateKey(new DSAPrivateKeySpec(key.getX(), params.getP(), params.getQ(), params.getG())); http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/17f2d627/sshd-core/src/main/java/org/apache/sshd/common/config/keys/ECDSAPublicKeyEntryDecoder.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/common/config/keys/ECDSAPublicKeyEntryDecoder.java b/sshd-core/src/main/java/org/apache/sshd/common/config/keys/ECDSAPublicKeyEntryDecoder.java index dd499f8..65679e3 100644 --- a/sshd-core/src/main/java/org/apache/sshd/common/config/keys/ECDSAPublicKeyEntryDecoder.java +++ b/sshd-core/src/main/java/org/apache/sshd/common/config/keys/ECDSAPublicKeyEntryDecoder.java @@ -52,9 +52,16 @@ import org.apache.sshd.common.util.buffer.BufferUtils; /** * @author <a href="mailto:[email protected]">Apache MINA SSHD Project</a> */ -public class ECDSAPublicKeyEntryDecoder extends AbstractPublicKeyEntryDecoder<ECPublicKey,ECPrivateKey> { +public class ECDSAPublicKeyEntryDecoder extends AbstractPublicKeyEntryDecoder<ECPublicKey, ECPrivateKey> { + public static final ECDSAPublicKeyEntryDecoder INSTANCE = new ECDSAPublicKeyEntryDecoder(); + // see rfc5480 section 2.2 + public static final byte ECPOINT_UNCOMPRESSED_FORM_INDICATOR = 0x04; + public static final byte ECPOINT_COMPRESSED_VARIANT_2 = 0x02; + public static final byte ECPOINT_COMPRESSED_VARIANT_3 = 0x02; + + public ECDSAPublicKeyEntryDecoder() { super(ECPublicKey.class, ECPrivateKey.class, ECCurves.KEY_TYPES); } @@ -65,7 +72,7 @@ public class ECDSAPublicKeyEntryDecoder extends AbstractPublicKeyEntryDecoder<EC if (curve == null) { throw new InvalidKeySpecException("Not an EC curve name: " + keyType); } - + if (!SecurityUtils.hasEcc()) { throw new NoSuchProviderException("ECC not supported"); } @@ -78,17 +85,18 @@ public class ECDSAPublicKeyEntryDecoder extends AbstractPublicKeyEntryDecoder<EC throw new InvalidKeySpecException("Mismatched key curve name (" + keyCurveName + ") vs. encoded one (" + encCurveName + ")"); } - byte[] octets = readRLEBytes(keyData); + byte[] octets = readRLEBytes(keyData); final ECPoint w; try { - if ((w = octetStringToEcPoint(octets)) == null) { + w = octetStringToEcPoint(octets); + if (w == null) { throw new InvalidKeySpecException("No ECPoint generated for curve=" + keyCurveName + " from octets=" + BufferUtils.printHex(':', octets)); } - } catch(RuntimeException e) { + } catch (RuntimeException e) { throw new InvalidKeySpecException("Failed (" + e.getClass().getSimpleName() + ")" - + " to generate ECPoint for curve=" + keyCurveName - + " from octets=" + BufferUtils.printHex(':', octets) - + ": " + e.getMessage()); + + " to generate ECPoint for curve=" + keyCurveName + + " from octets=" + BufferUtils.printHex(':', octets) + + ": " + e.getMessage()); } return generatePublicKey(new ECPublicKeySpec(w, paramSpec)); @@ -103,7 +111,7 @@ public class ECDSAPublicKeyEntryDecoder extends AbstractPublicKeyEntryDecoder<EC if (key == null) { return null; } - + ECParameterSpec params = key.getParams(); if (params == null) { throw new InvalidKeyException("Missing parameters in key"); @@ -121,7 +129,7 @@ public class ECDSAPublicKeyEntryDecoder extends AbstractPublicKeyEntryDecoder<EC if (key == null) { return null; } - + ECParameterSpec params = key.getParams(); if (params == null) { throw new InvalidKeyException("Missing parameters in key"); @@ -133,10 +141,11 @@ public class ECDSAPublicKeyEntryDecoder extends AbstractPublicKeyEntryDecoder<EC @Override public String encodePublicKey(OutputStream s, ECPublicKey key) throws IOException { ValidateUtils.checkNotNull(key, "No public key provided"); - + ECParameterSpec params = ValidateUtils.checkNotNull(key.getParams(), "No EC parameters available"); ECCurves curve = ValidateUtils.checkNotNull(ECCurves.fromCurveParameters(params), "Cannot determine curve"); - String keyType = curve.getKeyType(), curveName = curve.getName(); + String keyType = curve.getKeyType(); + String curveName = curve.getName(); encodeString(s, keyType); // see rfc5656 section 3.1 encodeString(s, curveName); @@ -159,7 +168,7 @@ public class ECDSAPublicKeyEntryDecoder extends AbstractPublicKeyEntryDecoder<EC if (curve == null) { throw new InvalidKeySpecException("Unknown curve for key size=" + keySize); } - + KeyPairGenerator gen = getKeyPairGenerator(); gen.initialize(curve.getParameters()); return gen.generateKeyPair(); @@ -174,23 +183,18 @@ public class ECDSAPublicKeyEntryDecoder extends AbstractPublicKeyEntryDecoder<EC } } - // see rfc5480 section 2.2 - public static final byte ECPOINT_UNCOMPRESSED_FORM_INDICATOR=0x04; - public static final byte ECPOINT_COMPRESSED_VARIANT_2=0x02; - public static final byte ECPOINT_COMPRESSED_VARIANT_3=0x02; - - public static ECPoint octetStringToEcPoint(byte ... octets) { + public static ECPoint octetStringToEcPoint(byte... octets) { if (GenericUtils.isEmpty(octets)) { return null; } - int startIndex=findFirstNonZeroIndex(octets); + int startIndex = findFirstNonZeroIndex(octets); if (startIndex < 0) { throw new IllegalArgumentException("All zeroes ECPoint N/A"); } - byte indicator=octets[startIndex]; - ECPointCompression compression=ECPointCompression.fromIndicatorValue(indicator); + byte indicator = octets[startIndex]; + ECPointCompression compression = ECPointCompression.fromIndicatorValue(indicator); if (compression == null) { throw new UnsupportedOperationException("Unknown compression indicator value: 0x" + Integer.toHexString(indicator & 0xFF)); } @@ -199,21 +203,23 @@ public class ECDSAPublicKeyEntryDecoder extends AbstractPublicKeyEntryDecoder<EC return compression.octetStringToEcPoint(octets, startIndex + 1, octets.length - startIndex - 1); } - private static int findFirstNonZeroIndex(byte ... octets) { + private static int findFirstNonZeroIndex(byte... octets) { if (GenericUtils.isEmpty(octets)) { - return (-1); + return -1; } - for (int index=0; index < octets.length; index++) { + for (int index = 0; index < octets.length; index++) { if (octets[index] != 0) { return index; } } - return (-1); // all zeroes + return -1; // all zeroes } + /** * The various {@link ECPoint} representation compression indicators + * * @author <a href="mailto:[email protected]">Apache MINA SSHD Project</a> * @see <A HREF="https://www.ietf.org/rfc/rfc5480.txt">RFC-5480 - section 2.2</A> */ @@ -221,83 +227,88 @@ public class ECDSAPublicKeyEntryDecoder extends AbstractPublicKeyEntryDecoder<EC // see http://tools.ietf.org/html/draft-jivsov-ecc-compact-00 // see http://crypto.stackexchange.com/questions/8914/ecdsa-compressed-public-key-point-back-to-uncompressed-public-key-point VARIANT2((byte) 0x02) { - @Override - public ECPoint octetStringToEcPoint(byte[] octets, int startIndex, int len) { - byte[] xp=new byte[len]; - System.arraycopy(octets, startIndex, xp, 0, len); - BigInteger x=octetStringToInteger(xp); - - // TODO derive even Y... - throw new UnsupportedOperationException("octetStringToEcPoint(" + name() + ")(X=" + x + ") compression support N/A"); - } - }, + @Override + public ECPoint octetStringToEcPoint(byte[] octets, int startIndex, int len) { + byte[] xp = new byte[len]; + System.arraycopy(octets, startIndex, xp, 0, len); + BigInteger x = octetStringToInteger(xp); + + // TODO derive even Y... + throw new UnsupportedOperationException("octetStringToEcPoint(" + name() + ")(X=" + x + ") compression support N/A"); + } + }, VARIANT3((byte) 0x03) { - @Override - public ECPoint octetStringToEcPoint(byte[] octets, int startIndex, int len) { - byte[] xp=new byte[len]; - System.arraycopy(octets, startIndex, xp, 0, len); - BigInteger x=octetStringToInteger(xp); - - // TODO derive odd Y... - throw new UnsupportedOperationException("octetStringToEcPoint(" + name() + ")(X=" + x + ") compression support N/A"); - } - }, + @Override + public ECPoint octetStringToEcPoint(byte[] octets, int startIndex, int len) { + byte[] xp = new byte[len]; + System.arraycopy(octets, startIndex, xp, 0, len); + BigInteger x = octetStringToInteger(xp); + + // TODO derive odd Y... + throw new UnsupportedOperationException("octetStringToEcPoint(" + name() + ")(X=" + x + ") compression support N/A"); + } + }, UNCOMPRESSED((byte) 0x04) { - @Override - public ECPoint octetStringToEcPoint(byte[] octets, int startIndex, int len) { - int numElements=len / 2; /* x, y */ - if (len != (numElements * 2 )) { // make sure length is not odd - throw new IllegalArgumentException("octetStringToEcPoint(" + name() + ") " - + " invalid remainder octets representation: " - + " expected=" + (2 * numElements) + ", actual=" + len); - } - - byte[] xp=new byte[numElements], yp=new byte[numElements]; - System.arraycopy(octets, startIndex, xp, 0, numElements); - System.arraycopy(octets, startIndex + numElements, yp, 0, numElements); - - BigInteger x=octetStringToInteger(xp); - BigInteger y=octetStringToInteger(yp); - return new ECPoint(x, y); + @Override + public ECPoint octetStringToEcPoint(byte[] octets, int startIndex, int len) { + int numElements = len / 2; /* x, y */ + if (len != (numElements * 2)) { // make sure length is not odd + throw new IllegalArgumentException("octetStringToEcPoint(" + name() + ") " + + " invalid remainder octets representation: " + + " expected=" + (2 * numElements) + ", actual=" + len); } - - @Override - public void writeECPoint(OutputStream s, String curveName, ECPoint p) throws IOException { - ECCurves curve = ECCurves.fromCurveName(curveName); - if (curve == null) { - throw new StreamCorruptedException("writeECPoint(" + name() + ")[" + curveName + "] cannot determine octets count"); - } - - int numElements = curve.getNumPointOctets(); - AbstractPublicKeyEntryDecoder.encodeInt(s, 1 /* the indicator */ + 2 * numElements); - s.write(getIndicatorValue()); - writeCoordinate(s, "X", p.getAffineX(), numElements); - writeCoordinate(s, "Y", p.getAffineY(), numElements); + + byte[] xp = new byte[numElements]; + byte[] yp = new byte[numElements]; + System.arraycopy(octets, startIndex, xp, 0, numElements); + System.arraycopy(octets, startIndex + numElements, yp, 0, numElements); + + BigInteger x = octetStringToInteger(xp); + BigInteger y = octetStringToInteger(yp); + return new ECPoint(x, y); + } + + @Override + public void writeECPoint(OutputStream s, String curveName, ECPoint p) throws IOException { + ECCurves curve = ECCurves.fromCurveName(curveName); + if (curve == null) { + throw new StreamCorruptedException("writeECPoint(" + name() + ")[" + curveName + "] cannot determine octets count"); } - }; + int numElements = curve.getNumPointOctets(); + AbstractPublicKeyEntryDecoder.encodeInt(s, 1 /* the indicator */ + 2 * numElements); + s.write(getIndicatorValue()); + writeCoordinate(s, "X", p.getAffineX(), numElements); + writeCoordinate(s, "Y", p.getAffineY(), numElements); + } - private final byte indicatorValue; - public final byte getIndicatorValue() { - return indicatorValue; - } + }; + + public static final Set<ECPointCompression> VALUES = + Collections.unmodifiableSet(EnumSet.allOf(ECPointCompression.class)); + + private final byte indicatorValue; ECPointCompression(byte indicator) { indicatorValue = indicator; } + public final byte getIndicatorValue() { + return indicatorValue; + } + public abstract ECPoint octetStringToEcPoint(byte[] octets, int startIndex, int len); public byte[] ecPointToOctetString(String curveName, ECPoint p) { - try(ByteArrayOutputStream baos = new ByteArrayOutputStream((2 * 66) + Long.SIZE)) { + try (ByteArrayOutputStream baos = new ByteArrayOutputStream((2 * 66) + Long.SIZE)) { writeECPoint(baos, curveName, p); return baos.toByteArray(); - } catch(IOException e) { + } catch (IOException e) { throw new RuntimeException("ecPointToOctetString(" + curveName + ")" - + " failed (" + e.getClass().getSimpleName() + ")" - + " to write data: " + e.getMessage(), - e); - } + + " failed (" + e.getClass().getSimpleName() + ")" + + " to write data: " + e.getMessage(), + e); + } } public void writeECPoint(OutputStream s, String curveName, ECPoint p) throws IOException { @@ -309,9 +320,9 @@ public class ECDSAPublicKeyEntryDecoder extends AbstractPublicKeyEntryDecoder<EC } protected void writeCoordinate(OutputStream s, String n, BigInteger v, int numElements) throws IOException { - byte[] vp=v.toByteArray(); - int startIndex=0; - int vLen=vp.length; + byte[] vp = v.toByteArray(); + int startIndex = 0; + int vLen = vp.length; if (vLen > numElements) { if (vp[0] == 0) { // skip artificial positive sign startIndex++; @@ -321,12 +332,12 @@ public class ECDSAPublicKeyEntryDecoder extends AbstractPublicKeyEntryDecoder<EC if (vLen > numElements) { throw new StreamCorruptedException("writeCoordinate(" + name() + ")[" + n + "]" - + " value length (" + vLen + ") exceeds max. (" + numElements + ")" - + " for " + v); + + " value length (" + vLen + ") exceeds max. (" + numElements + ")" + + " for " + v); } if (vLen < numElements) { - byte[] tmp=new byte[numElements]; + byte[] tmp = new byte[numElements]; System.arraycopy(vp, startIndex, tmp, numElements - vLen, vLen); vp = tmp; } @@ -334,9 +345,6 @@ public class ECDSAPublicKeyEntryDecoder extends AbstractPublicKeyEntryDecoder<EC s.write(vp, startIndex, vLen); } - public static final Set<ECPointCompression> VALUES= - Collections.unmodifiableSet(EnumSet.allOf(ECPointCompression.class)); - public static ECPointCompression fromIndicatorValue(int value) { if ((value < 0) || (value > 0xFF)) { return null; // must be a byte value @@ -356,10 +364,11 @@ public class ECDSAPublicKeyEntryDecoder extends AbstractPublicKeyEntryDecoder<EC * As octet strings always represent positive integers, a zero-byte is prepended to * the given array if necessary (if is MSB equal to 1), then this is converted to BigInteger * The conversion is defined in the Section 2.3.8 + * * @param octets - octet string bytes to be converted * @return The {@link BigInteger} representation of the octet string */ - public static BigInteger octetStringToInteger(byte ... octets) { + public static BigInteger octetStringToInteger(byte... octets) { if (octets == null) { return null; } else if (octets.length == 0) { http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/17f2d627/sshd-core/src/main/java/org/apache/sshd/common/config/keys/FilePasswordProvider.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/common/config/keys/FilePasswordProvider.java b/sshd-core/src/main/java/org/apache/sshd/common/config/keys/FilePasswordProvider.java index 3a6f920..ea5b227 100644 --- a/sshd-core/src/main/java/org/apache/sshd/common/config/keys/FilePasswordProvider.java +++ b/sshd-core/src/main/java/org/apache/sshd/common/config/keys/FilePasswordProvider.java @@ -27,7 +27,7 @@ import java.io.IOException; public interface FilePasswordProvider { /** * @param resourceKey The resource key representing the <U>private</U> - * file + * file * @return The password - if {@code null}/empty then no password is required * @throws IOException if cannot resolve password */ http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/17f2d627/sshd-core/src/main/java/org/apache/sshd/common/config/keys/Identity.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/common/config/keys/Identity.java b/sshd-core/src/main/java/org/apache/sshd/common/config/keys/Identity.java index 75b68be..343997e 100644 --- a/sshd-core/src/main/java/org/apache/sshd/common/config/keys/Identity.java +++ b/sshd-core/src/main/java/org/apache/sshd/common/config/keys/Identity.java @@ -27,6 +27,7 @@ import org.apache.sshd.common.OptionalFeature; /** * Represents an SSH key type + * * @author <a href="mailto:[email protected]">Apache MINA SSHD Project</a> */ public interface Identity extends NamedResource, OptionalFeature { @@ -34,7 +35,8 @@ public interface Identity extends NamedResource, OptionalFeature { * @return The key algorithm - e.g., RSA, DSA, EC */ String getAlgorithm(); - + Class<? extends PublicKey> getPublicKeyType(); + Class<? extends PrivateKey> getPrivateKeyType(); } http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/17f2d627/sshd-core/src/main/java/org/apache/sshd/common/config/keys/IdentityUtils.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/common/config/keys/IdentityUtils.java b/sshd-core/src/main/java/org/apache/sshd/common/config/keys/IdentityUtils.java index 062446b..4af6b9a 100644 --- a/sshd-core/src/main/java/org/apache/sshd/common/config/keys/IdentityUtils.java +++ b/sshd-core/src/main/java/org/apache/sshd/common/config/keys/IdentityUtils.java @@ -46,7 +46,7 @@ public final class IdentityUtils { /** * @param prefix The file name prefix - ignored if {@code null}/empty - * @param type The identity type - ignored if {@code null}/empty + * @param type The identity type - ignored if {@code null}/empty * @param suffix The file name suffix - ignored if {@code null}/empty * @return The identity file name or {@code null} if no name */ @@ -60,20 +60,20 @@ public final class IdentityUtils { } /** - * @param ids A {@link Map} of the loaded identities where key=the identity type, - * value=the matching {@link KeyPair} - ignored if {@code null}/empty + * @param ids A {@link Map} of the loaded identities where key=the identity type, + * value=the matching {@link KeyPair} - ignored if {@code null}/empty * @param supportedOnly If {@code true} then ignore identities that are not - * supported internally + * supported internally * @return A {@link KeyPair} for the identities - {@code null} if no identities * available (e.g., after filtering unsupported ones) * @see BuiltinIdentities */ - public static KeyPairProvider createKeyPairProvider(Map<String,KeyPair> ids, boolean supportedOnly) { + public static KeyPairProvider createKeyPairProvider(Map<String, KeyPair> ids, boolean supportedOnly) { if (GenericUtils.isEmpty(ids)) { return null; } - - Map<String,KeyPair> pairsMap = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); + + Map<String, KeyPair> pairsMap = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); for (Map.Entry<String, KeyPair> ide : ids.entrySet()) { String type = ide.getKey(); KeyPair kp = ide.getValue(); @@ -81,22 +81,22 @@ public final class IdentityUtils { if (id == null) { id = BuiltinIdentities.fromKeyPair(kp); } - + if (supportedOnly && ((id == null) || (!id.isSupported()))) { continue; } - + String keyType = KeyUtils.getKeyType(kp); if (GenericUtils.isEmpty(keyType)) { continue; } - + KeyPair prev = pairsMap.put(keyType, kp); if (prev != null) { continue; // less of an offense if 2 pairs mapped to same key type } } - + if (GenericUtils.isEmpty(pairsMap)) { return null; } else { @@ -105,36 +105,36 @@ public final class IdentityUtils { } /** - * @param paths A {@link Map} of the identities where key=identity type (case - * <U>insensitive</U>), value=the {@link Path} of file with the identity key + * @param paths A {@link Map} of the identities where key=identity type (case + * <U>insensitive</U>), value=the {@link Path} of file with the identity key * @param provider A {@link FilePasswordProvider} - may be {@code null} - * if the loaded keys are <U>guaranteed</U> not to be encrypted. The argument - * to {@link FilePasswordProvider#getPassword(String)} is the path of the - * file whose key is to be loaded - * @param options The {@link OpenOption}s to use when reading the key data + * if the loaded keys are <U>guaranteed</U> not to be encrypted. The argument + * to {@link FilePasswordProvider#getPassword(String)} is the path of the + * file whose key is to be loaded + * @param options The {@link OpenOption}s to use when reading the key data * @return A {@link Map} of the identities where key=identity type (case * <U>insensitive</U>), value=the {@link KeyPair} of the identity - * @throws IOException If failed to access the file system + * @throws IOException If failed to access the file system * @throws GeneralSecurityException If failed to load the keys * @see SecurityUtils#loadKeyPairIdentity(String, InputStream, FilePasswordProvider) */ - public static Map<String,KeyPair> loadIdentities(Map<String,? extends Path> paths, FilePasswordProvider provider, OpenOption ... options) - throws IOException, GeneralSecurityException { + public static Map<String, KeyPair> loadIdentities(Map<String, ? extends Path> paths, FilePasswordProvider provider, OpenOption... options) + throws IOException, GeneralSecurityException { if (GenericUtils.isEmpty(paths)) { return Collections.emptyMap(); } - - Map<String,KeyPair> ids = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); - for (Map.Entry<String,? extends Path> pe : paths.entrySet()) { + + Map<String, KeyPair> ids = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); + for (Map.Entry<String, ? extends Path> pe : paths.entrySet()) { String type = pe.getKey(); Path path = pe.getValue(); - try(InputStream inputStream = Files.newInputStream(path, options)) { + try (InputStream inputStream = Files.newInputStream(path, options)) { KeyPair kp = SecurityUtils.loadKeyPairIdentity(path.toString(), inputStream, provider); KeyPair prev = ids.put(type, kp); ValidateUtils.checkTrue(prev == null, "Multiple keys for type=%s", type); } } - + return ids; } } http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/17f2d627/sshd-core/src/main/java/org/apache/sshd/common/config/keys/KeyUtils.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/common/config/keys/KeyUtils.java b/sshd-core/src/main/java/org/apache/sshd/common/config/keys/KeyUtils.java index da07183..97013cf 100644 --- a/sshd-core/src/main/java/org/apache/sshd/common/config/keys/KeyUtils.java +++ b/sshd-core/src/main/java/org/apache/sshd/common/config/keys/KeyUtils.java @@ -72,16 +72,6 @@ import org.apache.sshd.common.util.io.IoUtils; * @author <a href="mailto:[email protected]">Apache MINA SSHD Project</a> */ public final class KeyUtils { - private static final Map<String,PublicKeyEntryDecoder<?,?>> byKeyTypeDecodersMap = - new TreeMap<String, PublicKeyEntryDecoder<?,?>>(String.CASE_INSENSITIVE_ORDER); - private static final Map<Class<?>,PublicKeyEntryDecoder<?,?>> byKeyClassDecodersMap = - new HashMap<Class<?>, PublicKeyEntryDecoder<?,?>>(); - - static { - registerPublicKeyEntryDecoder(RSAPublicKeyDecoder.INSTANCE); - registerPublicKeyEntryDecoder(DSSPublicKeyEntryDecoder.INSTANCE); - registerPublicKeyEntryDecoder(ECDSAPublicKeyEntryDecoder.INSTANCE); - } /** * The {@link Set} of {@link PosixFilePermission} <U>not</U> allowed if strict @@ -90,7 +80,28 @@ public final class KeyUtils { public static final Set<PosixFilePermission> STRICTLY_PROHIBITED_FILE_PERMISSION = Collections.unmodifiableSet( EnumSet.of(PosixFilePermission.GROUP_READ, PosixFilePermission.GROUP_WRITE, PosixFilePermission.GROUP_EXECUTE, - PosixFilePermission.OTHERS_READ, PosixFilePermission.OTHERS_WRITE, PosixFilePermission.OTHERS_EXECUTE)); + PosixFilePermission.OTHERS_READ, PosixFilePermission.OTHERS_WRITE, PosixFilePermission.OTHERS_EXECUTE)); + + /** + * The default {@link Factory} of {@link Digest}s initialized + * as the value of {@link #getDefaultFingerPrintFactory()} + */ + public static final Factory<Digest> DEFAULT_FINGERPRINT_DIGEST_FACTORY = BuiltinDigests.md5; + + private static final AtomicReference<Factory<? extends Digest>> DEFAULT_DIGEST_HOLDER = + new AtomicReference<Factory<? extends Digest>>(DEFAULT_FINGERPRINT_DIGEST_FACTORY); + + private static final Map<String, PublicKeyEntryDecoder<?, ?>> BY_KEY_TYPE_DECODERS_MAP = + new TreeMap<String, PublicKeyEntryDecoder<?, ?>>(String.CASE_INSENSITIVE_ORDER); + + private static final Map<Class<?>, PublicKeyEntryDecoder<?, ?>> BY_KEY_CLASS_DECODERS_MAP = + new HashMap<Class<?>, PublicKeyEntryDecoder<?, ?>>(); + + static { + registerPublicKeyEntryDecoder(RSAPublicKeyDecoder.INSTANCE); + registerPublicKeyEntryDecoder(DSSPublicKeyEntryDecoder.INSTANCE); + registerPublicKeyEntryDecoder(ECDSAPublicKeyEntryDecoder.INSTANCE); + } private KeyUtils() { throw new UnsupportedOperationException("No instance"); @@ -99,29 +110,30 @@ public final class KeyUtils { /** * <P>Checks if a path has strict permissions</P></BR> * <UL> - * <LI> - * The path may not have {@link PosixFilePermission#OTHERS_EXECUTE} - * permission - * </LI> - * - * <LI> - * (For {@code Unix}) The path may not have group or others permissions - * </LI> - * - * <LI> - * (For {@code Unix}) If the path is a file, then its folder may not have - * group or others permissions - * </LI> + * <LI> + * The path may not have {@link PosixFilePermission#OTHERS_EXECUTE} + * permission + * </LI> + * <p/> + * <LI> + * (For {@code Unix}) The path may not have group or others permissions + * </LI> + * <p/> + * <LI> + * (For {@code Unix}) If the path is a file, then its folder may not have + * group or others permissions + * </LI> * </UL> - * @param path The {@link Path} to be checked - ignored if {@code null} - * or does not exist + * + * @param path The {@link Path} to be checked - ignored if {@code null} + * or does not exist * @param options The {@link LinkOption}s to use to query the file's permissions * @return The violated {@link PosixFilePermission} - {@code null} if * no violations detected * @throws IOException If failed to retrieve the permissions * @see #STRICTLY_PROHIBITED_FILE_PERMISSION */ - public static PosixFilePermission validateStrictKeyFilePermissions(Path path, LinkOption ... options) throws IOException { + public static PosixFilePermission validateStrictKeyFilePermissions(Path path, LinkOption... options) throws IOException { if ((path == null) || (!Files.exists(path, options))) { return null; } @@ -135,15 +147,16 @@ public final class KeyUtils { return PosixFilePermission.OTHERS_EXECUTE; } - if (OsUtils.isUNIX()) { + if (OsUtils.isUNIX()) { PosixFilePermission p = IoUtils.validateExcludedPermissions(perms, STRICTLY_PROHIBITED_FILE_PERMISSION); if (p != null) { return p; } if (Files.isRegularFile(path, options)) { - Path parent=path.getParent(); - if ((p = IoUtils.validateExcludedPermissions(IoUtils.getPermissions(parent, options), STRICTLY_PROHIBITED_FILE_PERMISSION)) != null) { + Path parent = path.getParent(); + p = IoUtils.validateExcludedPermissions(IoUtils.getPermissions(parent, options), STRICTLY_PROHIBITED_FILE_PERMISSION); + if (p != null) { return p; } } @@ -161,24 +174,25 @@ public final class KeyUtils { * @see PublicKeyEntryDecoder#generateKeyPair(int) */ public static KeyPair generateKeyPair(String keyType, int keySize) throws GeneralSecurityException { - PublicKeyEntryDecoder<?,?> decoder = getPublicKeyEntryDecoder(keyType); + PublicKeyEntryDecoder<?, ?> decoder = getPublicKeyEntryDecoder(keyType); if (decoder == null) { throw new InvalidKeySpecException("No decoder for key type=" + keyType); } - + return decoder.generateKeyPair(keySize); } /** * Performs a deep-clone of the original {@link KeyPair} - i.e., creates * <U>new</U> public/private keys that are clones of the original one + * * @param keyType The key type - {@code OpenSSH} name - e.g., {@code ssh-rsa, ssh-dss} - * @param kp The {@link KeyPair} to clone - ignored if {@code null} + * @param kp The {@link KeyPair} to clone - ignored if {@code null} * @return The cloned instance * @throws GeneralSecurityException If failed to clone the pair */ public static KeyPair cloneKeyPair(String keyType, KeyPair kp) throws GeneralSecurityException { - PublicKeyEntryDecoder<?,?> decoder = getPublicKeyEntryDecoder(keyType); + PublicKeyEntryDecoder<?, ?> decoder = getPublicKeyEntryDecoder(keyType); if (decoder == null) { throw new InvalidKeySpecException("No decoder for key type=" + keyType); } @@ -189,24 +203,24 @@ public final class KeyUtils { /** * @param decoder The decoder to register * @throws IllegalArgumentException if no decoder or not key type or no - * supported names for the decoder + * supported names for the decoder * @see PublicKeyEntryDecoder#getPublicKeyType() * @see PublicKeyEntryDecoder#getSupportedTypeNames() */ - public static void registerPublicKeyEntryDecoder(PublicKeyEntryDecoder<?,?> decoder) { + public static void registerPublicKeyEntryDecoder(PublicKeyEntryDecoder<?, ?> decoder) { ValidateUtils.checkNotNull(decoder, "No decoder specified"); Class<?> pubType = ValidateUtils.checkNotNull(decoder.getPublicKeyType(), "No public key type declared"); Class<?> prvType = ValidateUtils.checkNotNull(decoder.getPrivateKeyType(), "No private key type declared"); - synchronized(byKeyClassDecodersMap) { - byKeyClassDecodersMap.put(pubType, decoder); - byKeyClassDecodersMap.put(prvType, decoder); + synchronized (BY_KEY_CLASS_DECODERS_MAP) { + BY_KEY_CLASS_DECODERS_MAP.put(pubType, decoder); + BY_KEY_CLASS_DECODERS_MAP.put(prvType, decoder); } Collection<String> names = ValidateUtils.checkNotNullAndNotEmpty(decoder.getSupportedTypeNames(), "No supported key type"); - synchronized(byKeyTypeDecodersMap) { + synchronized (BY_KEY_TYPE_DECODERS_MAP) { for (String n : names) { - PublicKeyEntryDecoder<?,?> prev = byKeyTypeDecodersMap.put(n, decoder); + PublicKeyEntryDecoder<?, ?> prev = BY_KEY_TYPE_DECODERS_MAP.put(n, decoder); if (prev != null) { continue; // debug breakpoint } @@ -216,16 +230,16 @@ public final class KeyUtils { /** * @param keyType The {@code OpenSSH} key type string - e.g., {@code ssh-rsa, ssh-dss} - * - ignored if {@code null}/empty + * - ignored if {@code null}/empty * @return The registered {@link PublicKeyEntryDecoder} or {code null} if not found */ - public static PublicKeyEntryDecoder<?,?> getPublicKeyEntryDecoder(String keyType) { + public static PublicKeyEntryDecoder<?, ?> getPublicKeyEntryDecoder(String keyType) { if (GenericUtils.isEmpty(keyType)) { return null; } - - synchronized(byKeyTypeDecodersMap) { - return byKeyTypeDecodersMap.get(keyType); + + synchronized (BY_KEY_TYPE_DECODERS_MAP) { + return BY_KEY_TYPE_DECODERS_MAP.get(keyType); } } @@ -236,13 +250,13 @@ public final class KeyUtils { * match found * @see #getPublicKeyEntryDecoder(Key) */ - public static PublicKeyEntryDecoder<?,?> getPublicKeyEntryDecoder(KeyPair kp) { + public static PublicKeyEntryDecoder<?, ?> getPublicKeyEntryDecoder(KeyPair kp) { if (kp == null) { return null; } - - PublicKeyEntryDecoder<?,?> d1 = getPublicKeyEntryDecoder(kp.getPublic()); - PublicKeyEntryDecoder<?,?> d2 = getPublicKeyEntryDecoder(kp.getPrivate()); + + PublicKeyEntryDecoder<?, ?> d1 = getPublicKeyEntryDecoder(kp.getPublic()); + PublicKeyEntryDecoder<?, ?> d2 = getPublicKeyEntryDecoder(kp.getPrivate()); if (d1 == d2) { return d1; } else { @@ -255,7 +269,7 @@ public final class KeyUtils { * @return The registered {@link PublicKeyEntryDecoder} for this key or {code null} if no match found * @see #getPublicKeyEntryDecoder(Class) */ - public static PublicKeyEntryDecoder<?,?> getPublicKeyEntryDecoder(Key key) { + public static PublicKeyEntryDecoder<?, ?> getPublicKeyEntryDecoder(Key key) { if (key == null) { return null; } else { @@ -265,58 +279,49 @@ public final class KeyUtils { /** * @param keyType The key {@link Class} - ignored if {@code null} or not a {@link Key} - * compatible type + * compatible type * @return The registered {@link PublicKeyEntryDecoder} or {code null} if no match found */ - public static PublicKeyEntryDecoder<?,?> getPublicKeyEntryDecoder(Class<?> keyType) { + public static PublicKeyEntryDecoder<?, ?> getPublicKeyEntryDecoder(Class<?> keyType) { if ((keyType == null) || (!Key.class.isAssignableFrom(keyType))) { return null; } - - synchronized(byKeyTypeDecodersMap) { - { - PublicKeyEntryDecoder<?,?> decoder=byKeyClassDecodersMap.get(keyType); - if (decoder != null) { - return decoder; - } + + synchronized (BY_KEY_TYPE_DECODERS_MAP) { + PublicKeyEntryDecoder<?, ?> decoder = BY_KEY_CLASS_DECODERS_MAP.get(keyType); + if (decoder != null) { + return decoder; } - + // in case it is a derived class - for (PublicKeyEntryDecoder<?,?> decoder : byKeyClassDecodersMap.values()) { - Class<?> pubType = decoder.getPublicKeyType(), prvType = decoder.getPrivateKeyType(); + for (PublicKeyEntryDecoder<?, ?> dec : BY_KEY_CLASS_DECODERS_MAP.values()) { + Class<?> pubType = dec.getPublicKeyType(); + Class<?> prvType = dec.getPrivateKeyType(); if (pubType.isAssignableFrom(keyType) || prvType.isAssignableFrom(keyType)) { - return decoder; + return dec; } } } - + return null; } /** - * The default {@link Factory} of {@link Digest}s initialized - * as the value of {@link #getDefaultFingerPrintFactory()} - */ - public static final Factory<Digest> DEFAULT_FINGERPRINT_DIGEST_FACTORY = BuiltinDigests.md5; - private static final AtomicReference<Factory<? extends Digest>> defaultDigestHolder = - new AtomicReference<Factory<? extends Digest>>(DEFAULT_FINGERPRINT_DIGEST_FACTORY); - - /** * @return The default {@link Factory} of {@link Digest}s used * by the {@link #getFingerPrint(PublicKey)} and {@link #getFingerPrint(String)} * methods * @see #setDefaultFingerPrintFactory(Factory) */ public static Factory<? extends Digest> getDefaultFingerPrintFactory() { - return defaultDigestHolder.get(); + return DEFAULT_DIGEST_HOLDER.get(); } /** * @param f The {@link Factory} of {@link Digest}s to be used - may - * not be {@code null} + * not be {@code null} */ - public static void setDefaultFingerPrintFactory (Factory<? extends Digest> f) { - defaultDigestHolder.set(ValidateUtils.checkNotNull(f, "No digest factory")); + public static void setDefaultFingerPrintFactory(Factory<? extends Digest> f) { + DEFAULT_DIGEST_HOLDER.set(ValidateUtils.checkNotNull(f, "No digest factory")); } /** @@ -331,7 +336,7 @@ public final class KeyUtils { /** * @param password The {@link String} to digest - ignored if {@code null}/empty, - * otherwise its UTF-8 representation is used as input for the fingerprint + * otherwise its UTF-8 representation is used as input for the fingerprint * @return The fingerprint - {@code null} if {@code null}/empty input. * <B>Note:</B> if exception encountered then returns the exception's simple class name * @see #getFingerPrint(String, Charset) @@ -342,8 +347,8 @@ public final class KeyUtils { /** * @param password The {@link String} to digest - ignored if {@code null}/empty - * @param charset The {@link Charset} to use in order to convert the - * string to its byte representation to use as input for the fingerprint + * @param charset The {@link Charset} to use in order to convert the + * string to its byte representation to use as input for the fingerprint * @return The fingerprint - {@code null} if {@code null}/empty input. * <B>Note:</B> if exception encountered then returns the exception's simple class name * @see #getFingerPrint(Factory, String, Charset) @@ -354,7 +359,7 @@ public final class KeyUtils { } /** - * @param f The {@link Factory} to create the {@link Digest} to use + * @param f The {@link Factory} to create the {@link Digest} to use * @param key the public key - ignored if {@code null} * @return the fingerprint or {@code null} if no key. * <B>Note:</B> if exception encountered then returns the exception's simple class name @@ -365,7 +370,7 @@ public final class KeyUtils { } /** - * @param d The {@link Digest} to use + * @param d The {@link Digest} to use * @param key the public key - ignored if {@code null} * @return the fingerprint or {@code null} if no key. * <B>Note:</B> if exception encountered then returns the exception's simple class name @@ -375,12 +380,11 @@ public final class KeyUtils { if (key == null) { return null; } - try { Buffer buffer = new ByteArrayBuffer(); buffer.putRawPublicKey(key); return DigestUtils.getFingerPrint(d, buffer.array(), 0, buffer.wpos()); - } catch(Exception e) { + } catch (Exception e) { return e.getClass().getSimpleName(); } } @@ -388,7 +392,7 @@ public final class KeyUtils { /** * @param f The {@link Factory} to create the {@link Digest} to use * @param s The {@link String} to digest - ignored if {@code null}/empty, - * otherwise its UTF-8 representation is used as input for the fingerprint + * otherwise its UTF-8 representation is used as input for the fingerprint * @return The fingerprint - {@code null} if {@code null}/empty input. * <B>Note:</B> if exception encountered then returns the exception's simple class name * @see #getFingerPrint(Digest, String, Charset) @@ -398,10 +402,10 @@ public final class KeyUtils { } /** - * @param f The {@link Factory} to create the {@link Digest} to use - * @param s The {@link String} to digest - ignored if {@code null}/empty + * @param f The {@link Factory} to create the {@link Digest} to use + * @param s The {@link String} to digest - ignored if {@code null}/empty * @param charset The {@link Charset} to use in order to convert the - * string to its byte representation to use as input for the fingerprint + * string to its byte representation to use as input for the fingerprint * @return The fingerprint - {@code null} if {@code null}/empty input * <B>Note:</B> if exception encountered then returns the exception's simple class name * @see DigestUtils#getFingerPrint(Digest, String, Charset) @@ -413,7 +417,7 @@ public final class KeyUtils { /** * @param d The {@link Digest} to use * @param s The {@link String} to digest - ignored if {@code null}/empty, - * otherwise its UTF-8 representation is used as input for the fingerprint + * otherwise its UTF-8 representation is used as input for the fingerprint * @return The fingerprint - {@code null} if {@code null}/empty input. * <B>Note:</B> if exception encountered then returns the exception's simple class name * @see DigestUtils#getFingerPrint(Digest, String, Charset) @@ -423,10 +427,10 @@ public final class KeyUtils { } /** - * @param d The {@link Digest} to use to calculate the fingerprint - * @param s The string to digest - ignored if {@code null}/empty + * @param d The {@link Digest} to use to calculate the fingerprint + * @param s The string to digest - ignored if {@code null}/empty * @param charset The {@link Charset} to use in order to convert the - * string to its byte representation to use as input for the fingerprint + * string to its byte representation to use as input for the fingerprint * @return The fingerprint - {@code null} if {@code null}/empty input. * <B>Note:</B> if exception encountered then returns the exception's simple class name * @see DigestUtils#getFingerPrint(Digest, String, Charset) @@ -435,10 +439,9 @@ public final class KeyUtils { if (GenericUtils.isEmpty(s)) { return null; } - try { return DigestUtils.getFingerPrint(d, s, charset); - } catch(Exception e) { + } catch (Exception e) { return e.getClass().getSimpleName(); } } @@ -446,8 +449,8 @@ public final class KeyUtils { /** * @param kp a key pair - ignored if {@code null}. If the private - * key is non-{@code null} then it is used to determine the type, - * otherwise the public one is used. + * key is non-{@code null} then it is used to determine the type, + * otherwise the public one is used. * @return the key type or {@code null} if cannot determine it * @see #getKeyType(Key) */ @@ -455,7 +458,6 @@ public final class KeyUtils { if (kp == null) { return null; } - PrivateKey key = kp.getPrivate(); if (key != null) { return getKeyType(key); @@ -488,14 +490,14 @@ public final class KeyUtils { } /** - * @param key The {@link PublicKey} to be checked - ignored if {@code null} + * @param key The {@link PublicKey} to be checked - ignored if {@code null} * @param keySet The keys to be searched - ignored if {@code null}/empty * @return The matching {@link PublicKey} from the keys or {@code null} if * no match found * @see #compareKeys(PublicKey, PublicKey) */ - public static PublicKey findMatchingKey(PublicKey key, PublicKey ... keySet) { - if ((key == null) || GenericUtils.isEmpty(keySet)) { + public static PublicKey findMatchingKey(PublicKey key, PublicKey... keySet) { + if (key == null || GenericUtils.isEmpty(keySet)) { return null; } else { return findMatchingKey(key, Arrays.asList(keySet)); @@ -503,38 +505,32 @@ public final class KeyUtils { } /** - * @param key The {@link PublicKey} to be checked - ignored if {@code null} + * @param key The {@link PublicKey} to be checked - ignored if {@code null} * @param keySet The keys to be searched - ignored if {@code null}/empty * @return The matching {@link PublicKey} from the keys or {@code null} if * no match found * @see #compareKeys(PublicKey, PublicKey) */ public static PublicKey findMatchingKey(PublicKey key, Collection<? extends PublicKey> keySet) { - if ((key == null) || GenericUtils.isEmpty(keySet)) { + if (key == null || GenericUtils.isEmpty(keySet)) { return null; } - for (PublicKey k : keySet) { if (compareKeys(key, k)) { return k; } } - return null; } public static boolean compareKeyPairs(KeyPair k1, KeyPair k2) { if (Objects.equals(k1, k2)) { return true; - } else if ((k1 == null) || (k2 == null)) { + } else if (k1 == null || k2 == null) { return false; // both null is covered by Objects#equals - } - - if (compareKeys(k1.getPublic(), k2.getPublic()) - && compareKeys(k1.getPrivate(), k2.getPrivate())) { - return true; } else { - return false; + return compareKeys(k1.getPublic(), k2.getPublic()) + && compareKeys(k1.getPrivate(), k2.getPrivate()); } } @@ -553,39 +549,33 @@ public final class KeyUtils { public static boolean compareRSAKeys(RSAPrivateKey k1, RSAPrivateKey k2) { if (Objects.equals(k1, k2)) { return true; - } else if ((k1 == null) || (k2 == null)) { + } else if (k1 == null || k2 == null) { return false; // both null is covered by Objects#equals - } else if (Objects.equals(k1.getModulus(), k2.getModulus()) - && Objects.equals(k1.getPrivateExponent(), k2.getPrivateExponent())) { - return true; } else { - return false; + return Objects.equals(k1.getModulus(), k2.getModulus()) + && Objects.equals(k1.getPrivateExponent(), k2.getPrivateExponent()); } } public static boolean compareDSAKeys(DSAPrivateKey k1, DSAPrivateKey k2) { if (Objects.equals(k1, k2)) { return true; - } else if ((k1 == null) || (k2 == null)) { + } else if (k1 == null || k2 == null) { return false; // both null is covered by Objects#equals - } else if (Objects.equals(k1.getX(), k2.getAlgorithm()) - && compareDSAParams(k1.getParams(), k2.getParams())) { - return true; } else { - return false; + return Objects.equals(k1.getX(), k2.getX()) + && compareDSAParams(k1.getParams(), k2.getParams()); } } public static boolean compareECKeys(ECPrivateKey k1, ECPrivateKey k2) { if (Objects.equals(k1, k2)) { return true; - } else if ((k1 == null) || (k2 == null)) { + } else if (k1 == null || k2 == null) { return false; // both null is covered by Objects#equals - } else if (Objects.equals(k1.getS(), k2.getS()) - && compareECParams(k1.getParams(), k2.getParams())) { - return true; } else { - return false; + return Objects.equals(k1.getS(), k2.getS()) + && compareECParams(k1.getParams(), k2.getParams()); } } @@ -600,72 +590,62 @@ public final class KeyUtils { return false; // either key is null or not of same class } } - + public static boolean compareRSAKeys(RSAPublicKey k1, RSAPublicKey k2) { if (Objects.equals(k1, k2)) { return true; - } else if ((k1 == null) || (k2 == null)) { + } else if (k1 == null || k2 == null) { return false; // both null is covered by Objects#equals - } else if (Objects.equals(k1.getPublicExponent(), k2.getPublicExponent()) - && Objects.equals(k1.getModulus(), k2.getModulus())) { - return true; } else { - return false; + return Objects.equals(k1.getPublicExponent(), k2.getPublicExponent()) + && Objects.equals(k1.getModulus(), k2.getModulus()); } } public static boolean compareDSAKeys(DSAPublicKey k1, DSAPublicKey k2) { if (Objects.equals(k1, k2)) { return true; - } else if ((k1 == null) || (k2 == null)) { + } else if (k1 == null || k2 == null) { return false; // both null is covered by Objects#equals - } else if (Objects.equals(k1.getY(), k2.getY()) - && compareDSAParams(k1.getParams(), k2.getParams())) { - return true; } else { - return false; + return Objects.equals(k1.getY(), k2.getY()) + && compareDSAParams(k1.getParams(), k2.getParams()); } } - + public static boolean compareDSAParams(DSAParams p1, DSAParams p2) { if (Objects.equals(p1, p2)) { return true; - } else if ((p1 == null) || (p2 == null)) { + } else if (p1 == null || p2 == null) { return false; // both null is covered by Objects#equals - } else if (Objects.equals(p1.getG(), p2.getG()) - && Objects.equals(p1.getP(), p2.getP()) - && Objects.equals(p1.getQ(), p2.getQ())) { - return true; } else { - return false; + return Objects.equals(p1.getG(), p2.getG()) + && Objects.equals(p1.getP(), p2.getP()) + && Objects.equals(p1.getQ(), p2.getQ()); } } - + public static boolean compareECKeys(ECPublicKey k1, ECPublicKey k2) { if (Objects.equals(k1, k2)) { return true; - } else if ((k1 == null) || (k2 == null)) { + } else if (k1 == null || k2 == null) { return false; // both null is covered by Objects#equals - } else if (Objects.equals(k1.getW(), k2.getW()) - && compareECParams(k1.getParams(), k2.getParams())) { - return true; } else { - return false; + return Objects.equals(k1.getW(), k2.getW()) + && compareECParams(k1.getParams(), k2.getParams()); } } public static boolean compareECParams(ECParameterSpec s1, ECParameterSpec s2) { if (Objects.equals(s1, s2)) { return true; - } else if ((s1 == null) || (s2 == null)) { + } else if (s1 == null || s2 == null) { return false; // both null is covered by Objects#equals - } else if (Objects.equals(s1.getOrder(), s2.getOrder()) - && (s1.getCofactor() == s2.getCofactor()) - && Objects.equals(s1.getGenerator(), s2.getGenerator()) - && Objects.equals(s1.getCurve(), s2.getCurve())) { - return true; } else { - return false; + return Objects.equals(s1.getOrder(), s2.getOrder()) + && (s1.getCofactor() == s2.getCofactor()) + && Objects.equals(s1.getGenerator(), s2.getGenerator()) + && Objects.equals(s1.getCurve(), s2.getCurve()); } } }
