Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ public class ClientCommandConfig extends SshDelegateConfig {
@ParametersDelegate private final WorkflowOutputDelegate workflowOutputDelegate;
@ParametersDelegate private final WorkflowTypeDelegate workflowTypeDelegate;

@ParametersDelegate private final UserKeysPathDelegate userKeysPathDelegate;
@ParametersDelegate private final HostKeysPathDelegate hostKeysPathDelegate;

public ClientCommandConfig(GeneralDelegate delegate) {
super(delegate);
clientDelegate = new ClientDelegate();
Expand All @@ -30,12 +33,16 @@ public ClientCommandConfig(GeneralDelegate delegate) {
workflowInputDelegate = new WorkflowInputDelegate();
workflowOutputDelegate = new WorkflowOutputDelegate();
workflowTypeDelegate = new WorkflowTypeDelegate();
userKeysPathDelegate = new UserKeysPathDelegate();
hostKeysPathDelegate = new HostKeysPathDelegate();
addDelegate(clientDelegate);
addDelegate(configOutputDelegate);
addDelegate(timeoutDelegate);
addDelegate(workflowInputDelegate);
addDelegate(workflowOutputDelegate);
addDelegate(workflowTypeDelegate);
addDelegate(userKeysPathDelegate);
addDelegate(hostKeysPathDelegate);
}

@Override
Expand Down
391 changes: 79 additions & 312 deletions SSH-Core/src/main/java/de/rub/nds/sshattacker/core/config/Config.java

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* SSH-Attacker - A Modular Penetration Testing Framework for SSH
*
* Copyright 2014-2023 Ruhr University Bochum, Paderborn University, and Hackmanit GmbH
*
* Licensed under Apache License 2.0 http://www.apache.org/licenses/LICENSE-2.0
*/
package de.rub.nds.sshattacker.core.config.delegate;

import com.beust.jcommander.Parameter;
import de.rub.nds.sshattacker.core.config.Config;
import java.util.ArrayList;
import java.util.List;

public class HostKeysPathDelegate extends Delegate {

@Parameter(
names = "-host_keys",
description =
"Comma seperated list of paths to host keys (no white-space). "
+ "If no host keys are provided, the default host keys will be used.")
private List<String> paths = new ArrayList<>();

public List<String> getHostKeyPaths() {
return paths;
}

public void setHostKeyPaths(List<String> paths) {
this.paths = paths;
}

@Override
public void applyDelegate(Config config) {
if (paths != null && !paths.isEmpty()) {
config.setHostKeyPaths(paths);
// after overwriting the list of paths, we need to load the host keys again
config.loadHostKeys();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* SSH-Attacker - A Modular Penetration Testing Framework for SSH
*
* Copyright 2014-2023 Ruhr University Bochum, Paderborn University, and Hackmanit GmbH
*
* Licensed under Apache License 2.0 http://www.apache.org/licenses/LICENSE-2.0
*/
package de.rub.nds.sshattacker.core.config.delegate;

import com.beust.jcommander.Parameter;
import de.rub.nds.sshattacker.core.config.Config;
import java.util.ArrayList;
import java.util.List;

public class UserKeysPathDelegate extends Delegate {

@Parameter(
names = "-user_keys",
description =
"Comma seperated list of paths to user keys (no white-space). "
+ "If no user keys are provided, the default user keys will be used.")
private List<String> paths = new ArrayList<>();

public List<String> getUserKeyPaths() {
return paths;
}

public void setUserKeyPaths(List<String> paths) {
this.paths = paths;
}

@Override
public void applyDelegate(Config config) {
if (paths != null && !paths.isEmpty()) {
config.setUserKeyPaths(paths);
// after overwriting the list of paths, we need to load the user keys again
config.loadUserKeys();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import java.security.interfaces.DSAParams;
import java.security.interfaces.DSAPrivateKey;
import java.security.spec.DSAParameterSpec;
import java.util.Objects;

/** A serializable DSA private key used in the DSA signature algorithm. */
@XmlRootElement
Expand Down Expand Up @@ -83,4 +84,20 @@ public String getAlgorithm() {
public DSAParams getParams() {
return new DSAParameterSpec(p, q, g);
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
CustomDsaPrivateKey that = (CustomDsaPrivateKey) o;
return Objects.equals(p, that.p)
&& Objects.equals(q, that.q)
&& Objects.equals(g, that.g)
&& Objects.equals(x, that.x);
}

@Override
public int hashCode() {
return Objects.hash(p, q, g, x);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import java.security.interfaces.DSAParams;
import java.security.interfaces.DSAPublicKey;
import java.security.spec.DSAParameterSpec;
import java.util.Objects;

/** A serializable DSA public key used in the DSA signature algorithm. */
@XmlRootElement
Expand Down Expand Up @@ -83,4 +84,20 @@ public DSAParams getParams() {
public String getAlgorithm() {
return "DSA";
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
CustomDsaPublicKey that = (CustomDsaPublicKey) o;
return Objects.equals(p, that.p)
&& Objects.equals(q, that.q)
&& Objects.equals(g, that.g)
&& Objects.equals(y, that.y);
}

@Override
public int hashCode() {
return Objects.hash(p, q, g, y);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import java.security.spec.ECGenParameterSpec;
import java.security.spec.ECParameterSpec;
import java.security.spec.InvalidParameterSpecException;
import java.util.Objects;

/**
* A serializable elliptic curve private key used in various EC-based algorithms like ECDH and
Expand Down Expand Up @@ -97,4 +98,17 @@ public String getFormat() {
public byte[] getEncoded() {
return ArrayConverter.bigIntegerToByteArray(privateKey);
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
CustomEcPrivateKey that = (CustomEcPrivateKey) o;
return group == that.group && Objects.equals(privateKey, that.privateKey);
}

@Override
public int hashCode() {
return Objects.hash(group, privateKey);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import java.security.spec.ECParameterSpec;
import java.security.spec.ECPoint;
import java.security.spec.InvalidParameterSpecException;
import java.util.Objects;

/**
* A serializable elliptic curve public key used in various EC-based algorithms like ECDH and ECDSA.
Expand Down Expand Up @@ -98,4 +99,17 @@ public ECParameterSpec getParams() {
public static CustomEcPublicKey parse(byte[] encoded, NamedEcGroup group) {
return new CustomEcPublicKey(PointFormatter.formatFromByteArray(group, encoded), group);
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
CustomEcPublicKey that = (CustomEcPublicKey) o;
return Objects.equals(publicKey, that.publicKey) && group == that.group;
}

@Override
public int hashCode() {
return Objects.hash(publicKey, group);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import jakarta.xml.bind.annotation.XmlRootElement;
import java.math.BigInteger;
import java.security.interfaces.RSAPrivateKey;
import java.util.Objects;

/** A serializable RSA private key used in RSA encryption and signatures. */
@XmlRootElement
Expand Down Expand Up @@ -60,4 +61,18 @@ public void setPrivateExponent(BigInteger privateExponent) {
public String getAlgorithm() {
return "RSA";
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
CustomRsaPrivateKey that = (CustomRsaPrivateKey) o;
return Objects.equals(modulus, that.modulus)
&& Objects.equals(privateExponent, that.privateExponent);
}

@Override
public int hashCode() {
return Objects.hash(modulus, privateExponent);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import jakarta.xml.bind.annotation.XmlRootElement;
import java.math.BigInteger;
import java.security.interfaces.RSAPublicKey;
import java.util.Objects;

/** A serializable RSA public key used in RSA encryption and signatures. */
@XmlRootElement
Expand Down Expand Up @@ -60,4 +61,18 @@ public void setPublicExponent(BigInteger publicExponent) {
public String getAlgorithm() {
return "RSA";
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
CustomRsaPublicKey that = (CustomRsaPublicKey) o;
return Objects.equals(modulus, that.modulus)
&& Objects.equals(publicExponent, that.publicExponent);
}

@Override
public int hashCode() {
return Objects.hash(modulus, publicExponent);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
import java.util.Objects;
import java.util.Optional;

/**
Expand Down Expand Up @@ -132,12 +133,31 @@ public Optional<PRIVATE> getPrivateKey() {
return Optional.ofNullable(privateKey);
}

public void setPrivateKey(PRIVATE privateKey) {
this.privateKey = privateKey;
}

public String toString() {
return String.format(
"SshPublicKey[%s,%s]",
publicKeyFormat.toString(), getPrivateKey().map(key -> "private").orElse("public"));
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
SshPublicKey<?, ?> that = (SshPublicKey<?, ?>) o;
return publicKeyFormat == that.publicKeyFormat
&& Objects.equals(publicKey, that.publicKey)
&& Objects.equals(privateKey, that.privateKey);
}

@Override
public int hashCode() {
return Objects.hash(publicKeyFormat, publicKey, privateKey);
}

public enum FingerprintType {
SHA1,
SHA256
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
import java.security.PrivateKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Arrays;
import java.util.Objects;
import org.bouncycastle.asn1.DEROctetString;
import org.bouncycastle.asn1.edec.EdECObjectIdentifiers;
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
Expand Down Expand Up @@ -114,4 +116,19 @@ public String getFormat() {
public byte[] getEncoded() {
return scalar;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
XCurveEcPrivateKey that = (XCurveEcPrivateKey) o;
return group == that.group && Arrays.equals(scalar, that.scalar);
}

@Override
public int hashCode() {
int result = Objects.hash(group);
result = 31 * result + Arrays.hashCode(scalar);
return result;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
import java.security.PublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.X509EncodedKeySpec;
import java.util.Arrays;
import java.util.Objects;
import org.bouncycastle.asn1.edec.EdECObjectIdentifiers;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
Expand Down Expand Up @@ -112,4 +114,19 @@ public String getFormat() {
public byte[] getEncoded() {
return coordinate;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
XCurveEcPublicKey that = (XCurveEcPublicKey) o;
return group == that.group && Arrays.equals(coordinate, that.coordinate);
}

@Override
public int hashCode() {
int result = Objects.hash(group);
result = 31 * result + Arrays.hashCode(coordinate);
return result;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import de.rub.nds.sshattacker.core.protocol.connection.preparator.GlobalRequestOpenSshHostKeysMessagePreparator;
import de.rub.nds.sshattacker.core.protocol.connection.serializer.GlobalRequestOpenSshHostKeysMessageSerializer;
import de.rub.nds.sshattacker.core.state.SshContext;
import de.rub.nds.sshattacker.core.util.KeyParser;

public class GlobalRequestOpenSshHostKeysMessageHandler
extends SshMessageHandler<GlobalRequestOpenSshHostKeysMessage> {
Expand All @@ -27,7 +28,10 @@ public GlobalRequestOpenSshHostKeysMessageHandler(
}

@Override
public void adjustContext() {}
public void adjustContext() {
// this parses the hostkeyblob and sets the hostkeys in the context
context.setServerHostKeys(KeyParser.parseHostkeyBlob(message.getHostKeys().getValue()));
}

@Override
public SshMessageParser<GlobalRequestOpenSshHostKeysMessage> getParser(byte[] array) {
Expand Down
Loading