> userKeys;
// endregion
// region Channel
/** Fallback for command of ChannelRequestExecMessage */
+ @XmlJavaTypeAdapter(IllegalStringAdapter.class)
private String channelCommand;
/** Default channel values including local channel id and window size */
private ChannelDefaults channelDefaults;
+ /**
+ * Whether dynamic actions should be generated to reopen a channel if it was closed.
+ *
+ * Is currently only implement for Client mode and SFTP subsystem
+ */
+ private Boolean reopenChannelOnClose = true;
+
/**
* Fallback for the wantReply field of messages extending the SSH_MSG_GLOBAL_REQUEST or
* SSH_MSG_CHANNEL_REQUEST messages
@@ -357,12 +408,14 @@ public class Config implements Serializable {
* Fallback for variableName of ChannelRequestEnvMessage, to change server-allowed environment
* variables
*/
+ @XmlJavaTypeAdapter(IllegalStringAdapter.class)
private String defaultVariableName;
/**
* Fallback for variableValue of ChannelRequestEnvMessage, to change server-allowed environment
* variables
*/
+ @XmlJavaTypeAdapter(IllegalStringAdapter.class)
private String defaultVariableValue;
/**
@@ -399,9 +452,11 @@ public class Config implements Serializable {
* Default value of TERM environment variable, to specify the terminal handling of a requested
* pseudo terminal(pty-req)
*/
+ @XmlJavaTypeAdapter(IllegalStringAdapter.class)
private String defaultTermEnvVariable;
/** Default name of a predefined subsystem, which should be executed on the remote */
+ @XmlJavaTypeAdapter(IllegalStringAdapter.class)
private String defaultSubsystemName;
/**
@@ -412,6 +467,104 @@ public class Config implements Serializable {
// endregion
+ // region general SSH settings
+ // TODO: Think about an option that reflects the modifications on the key exchange messages back
+ // to the context (including ExchangeHashInputHolder), so that the actually modified keys are
+ // used in the computations. Would maybe be interesting for fuzzing
+
+ /**
+ * Whether decryption should be omitted if an error occurs during the decryption of a packet.
+ * Otherwise, the packet is not parsed any further
+ */
+ private Boolean fallbackToNoDecryptionOnError;
+
+ /**
+ * Whether decompression should be omitted if an error occurs during the decompression of a
+ * packet. Otherwise, the packet is not parsed any further.
+ */
+ private Boolean fallbackToNoDecompressionOnError;
+
+ // endregion
+
+ // region SFTP Version Exchange
+ /** SFTP Client protocol version */
+ private Integer sftpClientVersion;
+
+ /** SFTP Server protocol version */
+ private Integer sftpServerVersion;
+
+ /** SFTP negotiated protocol version */
+ private Integer sftpNegotiatedVersion;
+
+ // endregion
+
+ // region SSH Extensions
+ /** List of SFTP extensions supported by the client */
+ @XmlElementWrapper
+ @XmlElements({
+ @XmlElement(type = SftpExtensionCheckFile.class, name = "SftpExtensionCheckFile"),
+ @XmlElement(type = SftpExtensionCopyData.class, name = "SftpExtensionCopyData"),
+ @XmlElement(type = SftpExtensionCopyFile.class, name = "SftpExtensionCopyFile"),
+ @XmlElement(type = SftpExtensionExpandPath.class, name = "SftpExtensionExpandPath"),
+ @XmlElement(type = SftpExtensionFileStatVfs.class, name = "SftpExtensionFileStatVfs"),
+ @XmlElement(type = SftpExtensionFileSync.class, name = "SftpExtensionFileSync"),
+ @XmlElement(type = SftpExtensionGetTempFolder.class, name = "SftpExtensionGetTempFolder"),
+ @XmlElement(type = SftpExtensionHardlink.class, name = "SftpExtensionHardlink"),
+ @XmlElement(type = SftpExtensionHomeDirectory.class, name = "SftpExtensionHomeDirectory"),
+ @XmlElement(type = SftpExtensionLimits.class, name = "SftpExtensionLimits"),
+ @XmlElement(type = SftpExtensionLinkSetStat.class, name = "SftpExtensionLinkSetStat"),
+ @XmlElement(type = SftpExtensionMakeTempFolder.class, name = "SftpExtensionMakeTempFolder"),
+ @XmlElement(type = SftpExtensionNewline.class, name = "SftpExtensionNewline"),
+ @XmlElement(type = SftpExtensionPosixRename.class, name = "SftpExtensionPosixRename"),
+ @XmlElement(type = SftpExtensionSpaceAvailable.class, name = "SftpExtensionSpaceAvailable"),
+ @XmlElement(type = SftpExtensionStatVfs.class, name = "SftpExtensionStatVfs"),
+ @XmlElement(type = SftpExtensionTextSeek.class, name = "SftpExtensionTextSeek"),
+ @XmlElement(type = SftpExtensionUnknown.class, name = "SftpExtensionUnknown"),
+ @XmlElement(
+ type = SftpExtensionUsersGroupsById.class,
+ name = "SftpExtensionUsersGroupsById"),
+ @XmlElement(type = SftpExtensionVendorId.class, name = "SftpExtensionVendorId"),
+ @XmlElement(type = SftpExtensionWithVersion.class, name = "SftpExtensionWithVersion")
+ })
+ private ArrayList> sftpClientSupportedExtensions;
+
+ /** List of SFTP extensions supported by the server */
+ @XmlElementWrapper
+ @XmlElements({
+ @XmlElement(type = SftpExtensionCheckFile.class, name = "SftpExtensionCheckFile"),
+ @XmlElement(type = SftpExtensionCopyData.class, name = "SftpExtensionCopyData"),
+ @XmlElement(type = SftpExtensionCopyFile.class, name = "SftpExtensionCopyFile"),
+ @XmlElement(type = SftpExtensionExpandPath.class, name = "SftpExtensionExpandPath"),
+ @XmlElement(type = SftpExtensionFileStatVfs.class, name = "SftpExtensionFileStatVfs"),
+ @XmlElement(type = SftpExtensionFileSync.class, name = "SftpExtensionFileSync"),
+ @XmlElement(type = SftpExtensionGetTempFolder.class, name = "SftpExtensionGetTempFolder"),
+ @XmlElement(type = SftpExtensionHardlink.class, name = "SftpExtensionHardlink"),
+ @XmlElement(type = SftpExtensionHomeDirectory.class, name = "SftpExtensionHomeDirectory"),
+ @XmlElement(type = SftpExtensionLimits.class, name = "SftpExtensionLimits"),
+ @XmlElement(type = SftpExtensionLinkSetStat.class, name = "SftpExtensionLinkSetStat"),
+ @XmlElement(type = SftpExtensionMakeTempFolder.class, name = "SftpExtensionMakeTempFolder"),
+ @XmlElement(type = SftpExtensionNewline.class, name = "SftpExtensionNewline"),
+ @XmlElement(type = SftpExtensionPosixRename.class, name = "SftpExtensionPosixRename"),
+ @XmlElement(type = SftpExtensionSpaceAvailable.class, name = "SftpExtensionSpaceAvailable"),
+ @XmlElement(type = SftpExtensionStatVfs.class, name = "SftpExtensionStatVfs"),
+ @XmlElement(type = SftpExtensionTextSeek.class, name = "SftpExtensionTextSeek"),
+ @XmlElement(type = SftpExtensionUnknown.class, name = "SftpExtensionUnknown"),
+ @XmlElement(
+ type = SftpExtensionUsersGroupsById.class,
+ name = "SftpExtensionUsersGroupsById"),
+ @XmlElement(type = SftpExtensionVendorId.class, name = "SftpExtensionVendorId"),
+ @XmlElement(type = SftpExtensionWithVersion.class, name = "SftpExtensionWithVersion")
+ })
+ private ArrayList> sftpServerSupportedExtensions;
+
+ // endregion
+
+ // region general SFTP settings
+ /** Whether the attributes in messages should be consistent with the attributes flags. */
+ private Boolean respectSftpAttributesFlags;
+
+ // endregion
+
// region Workflow settings
/** The path to load workflow trace from. The workflow trace must be stored in an XML-File. */
private String workflowInput;
@@ -428,7 +581,7 @@ public class Config implements Serializable {
*/
@XmlElement(name = "outputFilter")
@XmlElementWrapper
- private List outputFilters;
+ private ArrayList outputFilters;
/** The path to save the workflow trace as output */
private String workflowOutput;
@@ -451,6 +604,12 @@ public class Config implements Serializable {
/** Defines, whether the SSH-Attacker should stop after a disconnect or not */
private Boolean stopActionsAfterDisconnect = true;
+ /**
+ * Defines, whether the SSH attacker should treat a timeout when receiving messages like an IO
+ * Exception. or not.
+ */
+ private Boolean handleTimeoutOnReceiveAsIOException = false;
+
/** Defines, whether the SSH-Attacker should stop after a IO exception or not */
private Boolean stopActionsAfterIOException = true;
@@ -460,8 +619,19 @@ public class Config implements Serializable {
*/
private Boolean workflowExecutorShouldClose = true;
+ /**
+ * Defines if the workflow trace should be reset before executing, by resetting all SshActions.
+ */
+ private Boolean resetWorkflowTraceBeforeExecution = true;
+
/** Defines if the workflow trace should be reset before saving, by resetting all SshActions. */
- private Boolean resetWorkflowtracesBeforeSaving = false;
+ private Boolean resetWorkflowTraceBeforeSaving = false;
+
+ /**
+ * Defines whether the original values of all modifiable variables in the workflow trace should
+ * be reset to null when the workflow trace is reset.
+ */
+ private Boolean resetModifiableVariables = true;
/**
* Setting this to true results in the client transport handlers trying to acquire a new port on
@@ -481,15 +651,31 @@ public class Config implements Serializable {
*/
private Boolean stopTraceAfterUnexpected = false;
+ private Boolean allowDynamicGenerationOfActions = true;
+
+ /**
+ * Setting this to true will add dynamically generated Actions to the workflow trace. Warning:
+ * This can prevent successful re-execution of a workflow trace
+ */
+ private Boolean addDynamicallyGeneratedActionsToWorkflowTrace = false;
+
// endregion
// region ReceiveAction
/**
* If set to true, SSH-Attacker will not try to continue receiving when all expected messages
- * were received
+ * were received. If false and messages are expected, SSH-Attacker will try to continue
+ * receiving as long as the socket does not time out.
*/
private Boolean quickReceive = true;
+ /**
+ * If set to true, SSH-Attacker will not try to continue receiving when at least one message was
+ * received and no messages are expected. If false and no messages are expected, SSH-Attacker
+ * will try to continue receiving as long as the socket does not time out.
+ */
+ private Boolean endReceivingEarly = false;
+
/**
* The maximum number of bytes to receive in a single receive action. Defaults to 2^24 bytes,
* RFC 4253 requires each SSH implementation to be able to handle binary packets with a length
@@ -549,7 +735,7 @@ public Config() {
KeyExchangeAlgorithm.EXT_INFO_C,
KeyExchangeAlgorithm.KEX_STRICT_C_V00_OPENSSH_COM
})
- .collect(Collectors.toCollection(LinkedList::new));
+ .collect(Collectors.toCollection(ArrayList::new));
serverSupportedKeyExchangeAlgorithms =
Arrays.stream(
new KeyExchangeAlgorithm[] {
@@ -568,7 +754,7 @@ public Config() {
KeyExchangeAlgorithm.EXT_INFO_S,
KeyExchangeAlgorithm.KEX_STRICT_S_V00_OPENSSH_COM
})
- .collect(Collectors.toCollection(LinkedList::new));
+ .collect(Collectors.toCollection(ArrayList::new));
// We don't support SK (U2F) host keys (yet), only listed for
// completeness
@@ -594,8 +780,8 @@ public Config() {
PublicKeyAlgorithm.RSA_SHA2_256,
PublicKeyAlgorithm.SSH_RSA
})
- .collect(Collectors.toCollection(LinkedList::new));
- serverSupportedHostKeyAlgorithms = new LinkedList<>(clientSupportedHostKeyAlgorithms);
+ .collect(Collectors.toCollection(ArrayList::new));
+ serverSupportedHostKeyAlgorithms = new ArrayList<>(clientSupportedHostKeyAlgorithms);
clientSupportedEncryptionAlgorithmsClientToServer =
Arrays.stream(
@@ -607,13 +793,13 @@ public Config() {
EncryptionAlgorithm.AES128_GCM_OPENSSH_COM,
EncryptionAlgorithm.AES256_GCM_OPENSSH_COM
})
- .collect(Collectors.toCollection(LinkedList::new));
+ .collect(Collectors.toCollection(ArrayList::new));
clientSupportedEncryptionAlgorithmsServerToClient =
- new LinkedList<>(clientSupportedEncryptionAlgorithmsClientToServer);
+ new ArrayList<>(clientSupportedEncryptionAlgorithmsClientToServer);
serverSupportedEncryptionAlgorithmsClientToServer =
- new LinkedList<>(clientSupportedEncryptionAlgorithmsClientToServer);
+ new ArrayList<>(clientSupportedEncryptionAlgorithmsClientToServer);
serverSupportedEncryptionAlgorithmsServerToClient =
- new LinkedList<>(clientSupportedEncryptionAlgorithmsClientToServer);
+ new ArrayList<>(clientSupportedEncryptionAlgorithmsClientToServer);
clientSupportedMacAlgorithmsClientToServer =
Arrays.stream(
@@ -629,13 +815,13 @@ public Config() {
MacAlgorithm.HMAC_SHA2_512,
MacAlgorithm.HMAC_SHA1
})
- .collect(Collectors.toCollection(LinkedList::new));
+ .collect(Collectors.toCollection(ArrayList::new));
clientSupportedMacAlgorithmsServerToClient =
- new LinkedList<>(clientSupportedMacAlgorithmsClientToServer);
+ new ArrayList<>(clientSupportedMacAlgorithmsClientToServer);
serverSupportedMacAlgorithmsServerToClient =
- new LinkedList<>(clientSupportedMacAlgorithmsClientToServer);
+ new ArrayList<>(clientSupportedMacAlgorithmsClientToServer);
serverSupportedMacAlgorithmsClientToServer =
- new LinkedList<>(clientSupportedMacAlgorithmsClientToServer);
+ new ArrayList<>(clientSupportedMacAlgorithmsClientToServer);
clientSupportedCompressionMethodsClientToServer =
Arrays.stream(
@@ -644,21 +830,21 @@ public Config() {
CompressionMethod.ZLIB_OPENSSH_COM,
CompressionMethod.ZLIB
})
- .collect(Collectors.toCollection(LinkedList::new));
+ .collect(Collectors.toCollection(ArrayList::new));
clientSupportedCompressionMethodsServerToClient =
- new LinkedList<>(clientSupportedCompressionMethodsClientToServer);
+ new ArrayList<>(clientSupportedCompressionMethodsClientToServer);
serverSupportedCompressionMethodsServerToClient =
- new LinkedList<>(clientSupportedCompressionMethodsClientToServer);
+ new ArrayList<>(clientSupportedCompressionMethodsClientToServer);
serverSupportedCompressionMethodsClientToServer =
- new LinkedList<>(clientSupportedCompressionMethodsClientToServer);
+ new ArrayList<>(clientSupportedCompressionMethodsClientToServer);
- clientSupportedLanguagesClientToServer = new LinkedList<>();
+ clientSupportedLanguagesClientToServer = new ArrayList<>();
clientSupportedLanguagesServerToClient =
- new LinkedList<>(clientSupportedLanguagesClientToServer);
+ new ArrayList<>(clientSupportedLanguagesClientToServer);
serverSupportedLanguagesServerToClient =
- new LinkedList<>(clientSupportedLanguagesClientToServer);
+ new ArrayList<>(clientSupportedLanguagesClientToServer);
serverSupportedLanguagesClientToServer =
- new LinkedList<>(clientSupportedLanguagesClientToServer);
+ new ArrayList<>(clientSupportedLanguagesClientToServer);
clientFirstKeyExchangePacketFollows = false;
serverFirstKeyExchangePacketFollows = false;
@@ -687,7 +873,7 @@ public Config() {
PublicKeyAlgorithm.ECDSA_SHA2_NISTP521,
PublicKeyAlgorithm.SSH_ED25519
})
- .collect(Collectors.toCollection(LinkedList::new));
+ .collect(Collectors.toCollection(ArrayList::new));
// section delay-compression extension
clientSupportedDelayCompressionMethods =
@@ -697,10 +883,10 @@ public Config() {
CompressionMethod.ZLIB_OPENSSH_COM,
CompressionMethod.ZLIB
})
- .collect(Collectors.toCollection(LinkedList::new));
+ .collect(Collectors.toCollection(ArrayList::new));
serverSupportedDelayCompressionMethods =
- new LinkedList<>(clientSupportedDelayCompressionMethods);
+ new ArrayList<>(clientSupportedDelayCompressionMethods);
// endregion
// region KeyExchange initialization
@@ -717,152 +903,157 @@ public Config() {
// default host key
// TODO: Load host keys from file to reduce length of Config class
hostKeys =
- List.of(
- new SshPublicKey<>(
- PublicKeyFormat.SSH_RSA,
- new CustomRsaPublicKey(
- new BigInteger("010001", 16),
- new BigInteger(
- "00D9F6BFFAB8BC79C6E9AB6C3D4593F561CC93B41A70B9A750045ED0AC09"
- + "6EF4A6A8C7B2AAA4F44459481319AE956934BF9D5C5AD7C004ADE0B81E43"
- + "75FD1DF8797DF6F3CA130ED8A2A9B6E94467A05D97A0F8380A4CBB75FC5E"
- + "5C303433B61750063D3801D5C90658ACAEE140B09F95A0FD8886EFAE16EA"
- + "B779DF82E6A12C1BE011FECB417C788B72C42948AB54CCE1E8119CFB78E1"
- + "3B06090CEBF6D3806854FE09F03B20BA92505058EC64C44F0B4DA0BAE71D"
- + "52EDA11AB67F4B54D9FCEFE1FACEB520D595FFA33502FB91423EBD972F26"
- + "150715CB0E648F715E6E5E8FC9D8FA55E9DE0652CF85D7928B235486F54A"
- + "3F3EE64B04888B898864B08200A9E22909",
- 16)),
- new CustomRsaPrivateKey(
- new BigInteger(
- "7AAB5898AEE7C451A2A90B9DE04EC947656FAB69460FF68E1E278EA1841D"
- + "A22B39CA4A4FA7CEA1B8EDCB7224C38A1659D1226D2E07AF9A7C62A305AC"
- + "9DEC042FBC290443B23E24C64765DE1AD58777A522BF102B1BCC5536D794"
- + "62BCBE6DB8E91CD9CF6F98F62E5031BFAA9E51C93ED900579A39C26CBB64"
- + "CF7E6F998513E20B4B2A4DD36D4F6F074A0FDB04232FA6EDAB89A1B32BA5"
- + "2214696BDA66C4518A73F92807DD088AB11263519885A0CD6A42B6D9EAE9"
- + "EBD13241EDC4EB7205AE838A5EF7AE280D36410057B38ED05CEBA75F92AC"
- + "DF40226164BB3A0C4312B65A8C2FBA85CDB7CC5F77F53C45F64409AFC460"
- + "210C8EE4DAB818F009172387ED00E141",
- 16),
- new BigInteger(
- "00D9F6BFFAB8BC79C6E9AB6C3D4593F561CC93B41A70B9A750045ED0AC09"
- + "6EF4A6A8C7B2AAA4F44459481319AE956934BF9D5C5AD7C004ADE0B81E43"
- + "75FD1DF8797DF6F3CA130ED8A2A9B6E94467A05D97A0F8380A4CBB75FC5E"
- + "5C303433B61750063D3801D5C90658ACAEE140B09F95A0FD8886EFAE16EA"
- + "B779DF82E6A12C1BE011FECB417C788B72C42948AB54CCE1E8119CFB78E1"
- + "3B06090CEBF6D3806854FE09F03B20BA92505058EC64C44F0B4DA0BAE71D"
- + "52EDA11AB67F4B54D9FCEFE1FACEB520D595FFA33502FB91423EBD972F26"
- + "150715CB0E648F715E6E5E8FC9D8FA55E9DE0652CF85D7928B235486F54A"
- + "3F3EE64B04888B898864B08200A9E22909",
- 16))),
- // SSH enforces the use of 1024 / 160 bit DSA keys as per RFC 4253 Sec. 6.6
- new SshPublicKey<>(
- PublicKeyFormat.SSH_DSS,
- new CustomDsaPublicKey(
- new BigInteger(
- "008BD081A858028A729F0C04E0788C06BC5B2EA8B880A203986C90E92D20"
- + "322670248A305A3217737BF0256EFFD53CC512993F137A4F64162AF4F3E6"
- + "AA64D348343C86D1B3D18CAE017A48FD2FFA56A9DFC70D18BE8958938768"
- + "995AFD952719DE2066B0A7E3D90948D4E0437BD1A5C94F1A1FBBADDCEA3A"
- + "338E96A4CACCF4A855",
- 16),
- new BigInteger(
- "00B971EBD0321EEC38C15E01FD9C773CCA23E66879", 16),
- new BigInteger(
- "259DC09E04AD1818271F3E676B17A98B6F7B1D08B43B51FAEF06D2C9F921"
- + "0667ED3C14ABEBEE372D1F325C11C0304AE8B9BAC8914619CA05165BAE2B"
- + "E49BAD5DD8ECB8129CDDD2941D6DDF53C7D53A5FB9D88B58F362034CA6A1"
- + "3929D28942D0054FFA4166D3DDDE0B2FE2E4A0342A827DEF6B6FECDB0614"
- + "8ED403D3FC9C4C79",
- 16),
- new BigInteger(
- "1433495B5BB346BEB6A783DA2ADF1C5CFE946146E4A461B2A658CEC29DA2"
- + "1496A6D69119026059D0C2557D535E664A0F10B4DB006601D8848EA6B92F"
- + "C6313B03103C9C3C6F0ED55CB46EEC8B0FE0007D2411F46676A8761DADAA"
- + "171351322D29487E9AE8738C354DD04FFEACA50503AFEC8F0610A679FF81"
- + "6EFD9B162F152BDA",
- 16)),
- new CustomDsaPrivateKey(
- new BigInteger(
- "008BD081A858028A729F0C04E0788C06BC5B2EA8B880A203986C90E92D20"
- + "322670248A305A3217737BF0256EFFD53CC512993F137A4F64162AF4F3E6"
- + "AA64D348343C86D1B3D18CAE017A48FD2FFA56A9DFC70D18BE8958938768"
- + "995AFD952719DE2066B0A7E3D90948D4E0437BD1A5C94F1A1FBBADDCEA3A"
- + "338E96A4CACCF4A855",
- 16),
- new BigInteger(
- "00B971EBD0321EEC38C15E01FD9C773CCA23E66879", 16),
- new BigInteger(
- "259DC09E04AD1818271F3E676B17A98B6F7B1D08B43B51FAEF06D2C9F921"
- + "0667ED3C14ABEBEE372D1F325C11C0304AE8B9BAC8914619CA05165BAE2B"
- + "E49BAD5DD8ECB8129CDDD2941D6DDF53C7D53A5FB9D88B58F362034CA6A1"
- + "3929D28942D0054FFA4166D3DDDE0B2FE2E4A0342A827DEF6B6FECDB0614"
- + "8ED403D3FC9C4C79",
- 16),
- new BigInteger(
- "7C6B4E2B32192EFC09B7CB12D85CBB4141EF7348", 16))),
- new SshPublicKey<>(
- PublicKeyFormat.ECDSA_SHA2_NISTP256,
- new CustomEcPublicKey(
- PointFormatter.formatFromByteArray(
- NamedEcGroup.SECP256R1,
- ArrayConverter.hexStringToByteArray(
- "0492A8D4E6EECBED47D0AACD15D714FB619D6F3941028874B99117CF8EAE"
- + "BBCDF7CC981DE460635590F3AB5AE6F7DF0A12E6E0DE951DEAE3D2C48EC3"
- + "4C237C61E7")),
- NamedEcGroup.SECP256R1),
- new CustomEcPrivateKey(
- new BigInteger(
- "8DD62AA24F982B18446E3ECC7E50F8EB976610750242BA637C949F4C8FD6A1CF",
- 16),
- NamedEcGroup.SECP256R1)),
- new SshPublicKey<>(
- PublicKeyFormat.ECDSA_SHA2_NISTP384,
- new CustomEcPublicKey(
- PointFormatter.formatFromByteArray(
- NamedEcGroup.SECP384R1,
+ new ArrayList<>(
+ List.of(
+ new SshPublicKey<>(
+ PublicKeyFormat.SSH_RSA,
+ new CustomRsaPublicKey(
+ new BigInteger("010001", 16),
+ new BigInteger(
+ "00D9F6BFFAB8BC79C6E9AB6C3D4593F561CC93B41A70B9A750045ED0AC09"
+ + "6EF4A6A8C7B2AAA4F44459481319AE956934BF9D5C5AD7C004ADE0B81E43"
+ + "75FD1DF8797DF6F3CA130ED8A2A9B6E94467A05D97A0F8380A4CBB75FC5E"
+ + "5C303433B61750063D3801D5C90658ACAEE140B09F95A0FD8886EFAE16EA"
+ + "B779DF82E6A12C1BE011FECB417C788B72C42948AB54CCE1E8119CFB78E1"
+ + "3B06090CEBF6D3806854FE09F03B20BA92505058EC64C44F0B4DA0BAE71D"
+ + "52EDA11AB67F4B54D9FCEFE1FACEB520D595FFA33502FB91423EBD972F26"
+ + "150715CB0E648F715E6E5E8FC9D8FA55E9DE0652CF85D7928B235486F54A"
+ + "3F3EE64B04888B898864B08200A9E22909",
+ 16)),
+ new CustomRsaPrivateKey(
+ new BigInteger(
+ "7AAB5898AEE7C451A2A90B9DE04EC947656FAB69460FF68E1E278EA1841D"
+ + "A22B39CA4A4FA7CEA1B8EDCB7224C38A1659D1226D2E07AF9A7C62A305AC"
+ + "9DEC042FBC290443B23E24C64765DE1AD58777A522BF102B1BCC5536D794"
+ + "62BCBE6DB8E91CD9CF6F98F62E5031BFAA9E51C93ED900579A39C26CBB64"
+ + "CF7E6F998513E20B4B2A4DD36D4F6F074A0FDB04232FA6EDAB89A1B32BA5"
+ + "2214696BDA66C4518A73F92807DD088AB11263519885A0CD6A42B6D9EAE9"
+ + "EBD13241EDC4EB7205AE838A5EF7AE280D36410057B38ED05CEBA75F92AC"
+ + "DF40226164BB3A0C4312B65A8C2FBA85CDB7CC5F77F53C45F64409AFC460"
+ + "210C8EE4DAB818F009172387ED00E141",
+ 16),
+ new BigInteger(
+ "00D9F6BFFAB8BC79C6E9AB6C3D4593F561CC93B41A70B9A750045ED0AC09"
+ + "6EF4A6A8C7B2AAA4F44459481319AE956934BF9D5C5AD7C004ADE0B81E43"
+ + "75FD1DF8797DF6F3CA130ED8A2A9B6E94467A05D97A0F8380A4CBB75FC5E"
+ + "5C303433B61750063D3801D5C90658ACAEE140B09F95A0FD8886EFAE16EA"
+ + "B779DF82E6A12C1BE011FECB417C788B72C42948AB54CCE1E8119CFB78E1"
+ + "3B06090CEBF6D3806854FE09F03B20BA92505058EC64C44F0B4DA0BAE71D"
+ + "52EDA11AB67F4B54D9FCEFE1FACEB520D595FFA33502FB91423EBD972F26"
+ + "150715CB0E648F715E6E5E8FC9D8FA55E9DE0652CF85D7928B235486F54A"
+ + "3F3EE64B04888B898864B08200A9E22909",
+ 16))),
+ // SSH enforces the use of 1024 / 160 bit DSA keys as per RFC 4253
+ // Sec. 6.6
+ new SshPublicKey<>(
+ PublicKeyFormat.SSH_DSS,
+ new CustomDsaPublicKey(
+ new BigInteger(
+ "008BD081A858028A729F0C04E0788C06BC5B2EA8B880A203986C90E92D20"
+ + "322670248A305A3217737BF0256EFFD53CC512993F137A4F64162AF4F3E6"
+ + "AA64D348343C86D1B3D18CAE017A48FD2FFA56A9DFC70D18BE8958938768"
+ + "995AFD952719DE2066B0A7E3D90948D4E0437BD1A5C94F1A1FBBADDCEA3A"
+ + "338E96A4CACCF4A855",
+ 16),
+ new BigInteger(
+ "00B971EBD0321EEC38C15E01FD9C773CCA23E66879",
+ 16),
+ new BigInteger(
+ "259DC09E04AD1818271F3E676B17A98B6F7B1D08B43B51FAEF06D2C9F921"
+ + "0667ED3C14ABEBEE372D1F325C11C0304AE8B9BAC8914619CA05165BAE2B"
+ + "E49BAD5DD8ECB8129CDDD2941D6DDF53C7D53A5FB9D88B58F362034CA6A1"
+ + "3929D28942D0054FFA4166D3DDDE0B2FE2E4A0342A827DEF6B6FECDB0614"
+ + "8ED403D3FC9C4C79",
+ 16),
+ new BigInteger(
+ "1433495B5BB346BEB6A783DA2ADF1C5CFE946146E4A461B2A658CEC29DA2"
+ + "1496A6D69119026059D0C2557D535E664A0F10B4DB006601D8848EA6B92F"
+ + "C6313B03103C9C3C6F0ED55CB46EEC8B0FE0007D2411F46676A8761DADAA"
+ + "171351322D29487E9AE8738C354DD04FFEACA50503AFEC8F0610A679FF81"
+ + "6EFD9B162F152BDA",
+ 16)),
+ new CustomDsaPrivateKey(
+ new BigInteger(
+ "008BD081A858028A729F0C04E0788C06BC5B2EA8B880A203986C90E92D20"
+ + "322670248A305A3217737BF0256EFFD53CC512993F137A4F64162AF4F3E6"
+ + "AA64D348343C86D1B3D18CAE017A48FD2FFA56A9DFC70D18BE8958938768"
+ + "995AFD952719DE2066B0A7E3D90948D4E0437BD1A5C94F1A1FBBADDCEA3A"
+ + "338E96A4CACCF4A855",
+ 16),
+ new BigInteger(
+ "00B971EBD0321EEC38C15E01FD9C773CCA23E66879",
+ 16),
+ new BigInteger(
+ "259DC09E04AD1818271F3E676B17A98B6F7B1D08B43B51FAEF06D2C9F921"
+ + "0667ED3C14ABEBEE372D1F325C11C0304AE8B9BAC8914619CA05165BAE2B"
+ + "E49BAD5DD8ECB8129CDDD2941D6DDF53C7D53A5FB9D88B58F362034CA6A1"
+ + "3929D28942D0054FFA4166D3DDDE0B2FE2E4A0342A827DEF6B6FECDB0614"
+ + "8ED403D3FC9C4C79",
+ 16),
+ new BigInteger(
+ "7C6B4E2B32192EFC09B7CB12D85CBB4141EF7348",
+ 16))),
+ new SshPublicKey<>(
+ PublicKeyFormat.ECDSA_SHA2_NISTP256,
+ new CustomEcPublicKey(
+ PointFormatter.formatFromByteArray(
+ NamedEcGroup.SECP256R1,
+ ArrayConverter.hexStringToByteArray(
+ "0492A8D4E6EECBED47D0AACD15D714FB619D6F3941028874B99117CF8EAE"
+ + "BBCDF7CC981DE460635590F3AB5AE6F7DF0A12E6E0DE951DEAE3D2C48EC3"
+ + "4C237C61E7")),
+ NamedEcGroup.SECP256R1),
+ new CustomEcPrivateKey(
+ new BigInteger(
+ "8DD62AA24F982B18446E3ECC7E50F8EB976610750242BA637C949F4C8FD6A1CF",
+ 16),
+ NamedEcGroup.SECP256R1)),
+ new SshPublicKey<>(
+ PublicKeyFormat.ECDSA_SHA2_NISTP384,
+ new CustomEcPublicKey(
+ PointFormatter.formatFromByteArray(
+ NamedEcGroup.SECP384R1,
+ ArrayConverter.hexStringToByteArray(
+ "04650469DB4E282660E0DCB23197D10EE935BA038B8B62890EB098420211"
+ + "C38D5E4E737FF2A0DC53E1B8A55C65B2BD85673EFEEEE9CE4727374D2E2D"
+ + "E8EEA6B8AB146245C8627E2346C76944AEB1C0BDCE1B267773F6ED08473A"
+ + "DE8B6F5687A2B6")),
+ NamedEcGroup.SECP384R1),
+ new CustomEcPrivateKey(
+ new BigInteger(
+ "EA39EE919D73A1FE8F8FBFC8807E7ED36BE3D89FBC1F35619B04E825E8E8"
+ + "07E994348EE8095467499AE15F73FE0FD298",
+ 16),
+ NamedEcGroup.SECP384R1)),
+ new SshPublicKey<>(
+ PublicKeyFormat.ECDSA_SHA2_NISTP521,
+ new CustomEcPublicKey(
+ PointFormatter.formatFromByteArray(
+ NamedEcGroup.SECP521R1,
+ ArrayConverter.hexStringToByteArray(
+ "0400A97EC5412F12C6CCAEDF2F288041146015FBCE1B939F017039D63280"
+ + "9B170C1E51B5AFE19127F97146C0556A70E44D179B76DA98C39ACF418F98"
+ + "95F7E8483665A800AF936C1864E14340ABE09860281D9A015E0C78A540F1"
+ + "6CB36DD0275C9AF61A2A41F6AE6447ECCFCA1788878B7A249B195424BED8"
+ + "CD881C0C3C5CEB051D64366DE5")),
+ NamedEcGroup.SECP521R1),
+ new CustomEcPrivateKey(
+ new BigInteger(
+ "015B220911DD64BD8793BC5429093B7AE8E2B4F462751D553CE48E09D72E"
+ + "9981F4EF80334B981D6558C6498BFB4B6E1973BF60BF568C624934F1EF2B"
+ + "8561C67B2AD2",
+ 16),
+ NamedEcGroup.SECP521R1)),
+ new SshPublicKey<>(
+ PublicKeyFormat.SSH_ED25519,
+ new XCurveEcPublicKey(
ArrayConverter.hexStringToByteArray(
- "04650469DB4E282660E0DCB23197D10EE935BA038B8B62890EB098420211"
- + "C38D5E4E737FF2A0DC53E1B8A55C65B2BD85673EFEEEE9CE4727374D2E2D"
- + "E8EEA6B8AB146245C8627E2346C76944AEB1C0BDCE1B267773F6ED08473A"
- + "DE8B6F5687A2B6")),
- NamedEcGroup.SECP384R1),
- new CustomEcPrivateKey(
- new BigInteger(
- "EA39EE919D73A1FE8F8FBFC8807E7ED36BE3D89FBC1F35619B04E825E8E8"
- + "07E994348EE8095467499AE15F73FE0FD298",
- 16),
- NamedEcGroup.SECP384R1)),
- new SshPublicKey<>(
- PublicKeyFormat.ECDSA_SHA2_NISTP521,
- new CustomEcPublicKey(
- PointFormatter.formatFromByteArray(
- NamedEcGroup.SECP521R1,
+ "13E3591CC0D1BAE515EC44FD3FA01784E2103165ECCFE939D91A619F46DBED70"),
+ NamedEcGroup.CURVE25519),
+ new XCurveEcPrivateKey(
ArrayConverter.hexStringToByteArray(
- "0400A97EC5412F12C6CCAEDF2F288041146015FBCE1B939F017039D63280"
- + "9B170C1E51B5AFE19127F97146C0556A70E44D179B76DA98C39ACF418F98"
- + "95F7E8483665A800AF936C1864E14340ABE09860281D9A015E0C78A540F1"
- + "6CB36DD0275C9AF61A2A41F6AE6447ECCFCA1788878B7A249B195424BED8"
- + "CD881C0C3C5CEB051D64366DE5")),
- NamedEcGroup.SECP521R1),
- new CustomEcPrivateKey(
- new BigInteger(
- "015B220911DD64BD8793BC5429093B7AE8E2B4F462751D553CE48E09D72E"
- + "9981F4EF80334B981D6558C6498BFB4B6E1973BF60BF568C624934F1EF2B"
- + "8561C67B2AD2",
- 16),
- NamedEcGroup.SECP521R1)),
- new SshPublicKey<>(
- PublicKeyFormat.SSH_ED25519,
- new XCurveEcPublicKey(
- ArrayConverter.hexStringToByteArray(
- "13E3591CC0D1BAE515EC44FD3FA01784E2103165ECCFE939D91A619F46DBED70"),
- NamedEcGroup.CURVE25519),
- new XCurveEcPrivateKey(
- ArrayConverter.hexStringToByteArray(
- "092E829DE536BE8F7D74E7A3C6CD90EA6EADDDEEB2E50D8617EBDD132B53669B"),
- NamedEcGroup.CURVE25519)));
+ "092E829DE536BE8F7D74E7A3C6CD90EA6EADDDEEB2E50D8617EBDD132B53669B"),
+ NamedEcGroup.CURVE25519))));
fallbackRsaTransientPublicKey =
new SshPublicKey<>(
@@ -911,133 +1102,145 @@ public Config() {
username = "sshattacker";
password = "secret";
- preConfiguredAuthResponses = new LinkedList<>();
- AuthenticationResponse preConfiguredAuthResponse1 = new AuthenticationResponse();
- preConfiguredAuthResponse1.add(new AuthenticationResponse.ResponseEntry(password, false));
- preConfiguredAuthResponses.add(preConfiguredAuthResponse1);
- AuthenticationResponse preConfiguredAuthResponse2 = new AuthenticationResponse();
- preConfiguredAuthResponse2.add(new AuthenticationResponse.ResponseEntry(false));
- preConfiguredAuthResponses.add(preConfiguredAuthResponse2);
+ preConfiguredAuthResponses = new ArrayList<>();
+
+ ArrayList preConfiguredAuthResponse1 = new ArrayList<>();
+ preConfiguredAuthResponse1.add(new AuthenticationResponseEntry());
+ preConfiguredAuthResponses.add(
+ new AuthenticationResponseEntries(preConfiguredAuthResponse1));
+ ArrayList preConfiguredAuthResponse2 = new ArrayList<>();
+ preConfiguredAuthResponse2.add(new AuthenticationResponseEntry());
+ preConfiguredAuthResponses.add(
+ new AuthenticationResponseEntries(preConfiguredAuthResponse2));
+
+ preConfiguredAuthPrompts = new ArrayList<>();
+ ArrayList preConfiguredAuthPrompt1 = new ArrayList<>();
+ preConfiguredAuthPrompt1.add(new AuthenticationPromptEntry());
+ preConfiguredAuthPrompts.add(new AuthenticationPromptEntries(preConfiguredAuthPrompt1));
// sshkey generated with "openssl ecparam -name secp521r1 -genkey -out key.pem"
// pubkey for authorized_keys file on host generated with "ssh-keygen -y -f
// key.pem >
// key.pub"
userKeys =
- List.of(
- new SshPublicKey<>(
- PublicKeyFormat.SSH_RSA,
- new CustomRsaPublicKey(
- new BigInteger("10001", 16),
- new BigInteger(
- "009df0c70638448afef5799bc7c161d5bc286baeb8a4dc70ffefb2f4813a"
- + "810747d3cbfcd1c9a9ce76272731ed1e2c0ba64feb9af634ae8e4df699b2"
- + "d3b52af4df616ca8003502e38b81bfa6801148c7bab1870a694b44d82ff0"
- + "98633edb09bfbab52b3e7498ce1826813da010000f7c458877f859f46442"
- + "0853220d632d9d1fc113e885e631f15dfcf1fddba90c0c5aa520bc6a55a5"
- + "6a1b29ead5492f83fe7e6b9494afbe16615daa446c2909c218dcd750ae4a"
- + "9a9c69c74d748e904ba8e2ce2812d1ce3c4ed12fd82cca7fe81f88823907"
- + "6702656ef1d3f93e472aae509a0ae5e241c4fd9b661f4cc6ffb02d416a72"
- + "5469e51e27204b3db3f28961e244a9e6c3",
- 16)),
- new CustomRsaPrivateKey(
- new BigInteger(
- "008701ebcef848371c8c0f40c77719bf4f50aa03b7984d4b56abba286152"
- + "f63a97fe86ef7d10ca534f1256e1c99432085f490fd7edbfc8baa2103aff"
- + "ef127d3ec6b80bde6c16e47a47a54882f614504752e22fd20981aabeb5f4"
- + "0eff3f1a9371ce12d17d58c3c9e04101d700bccca070152bfb8952b3a304"
- + "0303b5270671564f6e2753e05e413931e22a6b115fd3264fd6e4c25cb901"
- + "ccdd006d9b5785379f7cbcc1bbd149afda6b51fe13430fb5ca19da594afc"
- + "cd2bd99473001e995033116d48d329d42255ef0eec11a6d2310eb97912d7"
- + "19b7b75d74696613e21305da6715846bf04c4e76046fbf86a793d96c0fe7"
- + "02638696eed4b7488c18233db879e70149",
- 16),
- new BigInteger(
- "009df0c70638448afef5799bc7c161d5bc286baeb8a4dc70ffefb2f4813a"
- + "810747d3cbfcd1c9a9ce76272731ed1e2c0ba64feb9af634ae8e4df699b2"
- + "d3b52af4df616ca8003502e38b81bfa6801148c7bab1870a694b44d82ff0"
- + "98633edb09bfbab52b3e7498ce1826813da010000f7c458877f859f46442"
- + "0853220d632d9d1fc113e885e631f15dfcf1fddba90c0c5aa520bc6a55a5"
- + "6a1b29ead5492f83fe7e6b9494afbe16615daa446c2909c218dcd750ae4a"
- + "9a9c69c74d748e904ba8e2ce2812d1ce3c4ed12fd82cca7fe81f88823907"
- + "6702656ef1d3f93e472aae509a0ae5e241c4fd9b661f4cc6ffb02d416a72"
- + "5469e51e27204b3db3f28961e244a9e6c3",
- 16))),
- new SshPublicKey<>(
- PublicKeyFormat.ECDSA_SHA2_NISTP521,
- new CustomEcPublicKey(
- PointFormatter.formatFromByteArray(
- NamedEcGroup.SECP521R1,
+ new ArrayList<>(
+ List.of(
+ new SshPublicKey<>(
+ PublicKeyFormat.SSH_RSA,
+ new CustomRsaPublicKey(
+ new BigInteger("10001", 16),
+ new BigInteger(
+ "009df0c70638448afef5799bc7c161d5bc286baeb8a4dc70ffefb2f4813a"
+ + "810747d3cbfcd1c9a9ce76272731ed1e2c0ba64feb9af634ae8e4df699b2"
+ + "d3b52af4df616ca8003502e38b81bfa6801148c7bab1870a694b44d82ff0"
+ + "98633edb09bfbab52b3e7498ce1826813da010000f7c458877f859f46442"
+ + "0853220d632d9d1fc113e885e631f15dfcf1fddba90c0c5aa520bc6a55a5"
+ + "6a1b29ead5492f83fe7e6b9494afbe16615daa446c2909c218dcd750ae4a"
+ + "9a9c69c74d748e904ba8e2ce2812d1ce3c4ed12fd82cca7fe81f88823907"
+ + "6702656ef1d3f93e472aae509a0ae5e241c4fd9b661f4cc6ffb02d416a72"
+ + "5469e51e27204b3db3f28961e244a9e6c3",
+ 16)),
+ new CustomRsaPrivateKey(
+ new BigInteger(
+ "008701ebcef848371c8c0f40c77719bf4f50aa03b7984d4b56abba286152"
+ + "f63a97fe86ef7d10ca534f1256e1c99432085f490fd7edbfc8baa2103aff"
+ + "ef127d3ec6b80bde6c16e47a47a54882f614504752e22fd20981aabeb5f4"
+ + "0eff3f1a9371ce12d17d58c3c9e04101d700bccca070152bfb8952b3a304"
+ + "0303b5270671564f6e2753e05e413931e22a6b115fd3264fd6e4c25cb901"
+ + "ccdd006d9b5785379f7cbcc1bbd149afda6b51fe13430fb5ca19da594afc"
+ + "cd2bd99473001e995033116d48d329d42255ef0eec11a6d2310eb97912d7"
+ + "19b7b75d74696613e21305da6715846bf04c4e76046fbf86a793d96c0fe7"
+ + "02638696eed4b7488c18233db879e70149",
+ 16),
+ new BigInteger(
+ "009df0c70638448afef5799bc7c161d5bc286baeb8a4dc70ffefb2f4813a"
+ + "810747d3cbfcd1c9a9ce76272731ed1e2c0ba64feb9af634ae8e4df699b2"
+ + "d3b52af4df616ca8003502e38b81bfa6801148c7bab1870a694b44d82ff0"
+ + "98633edb09bfbab52b3e7498ce1826813da010000f7c458877f859f46442"
+ + "0853220d632d9d1fc113e885e631f15dfcf1fddba90c0c5aa520bc6a55a5"
+ + "6a1b29ead5492f83fe7e6b9494afbe16615daa446c2909c218dcd750ae4a"
+ + "9a9c69c74d748e904ba8e2ce2812d1ce3c4ed12fd82cca7fe81f88823907"
+ + "6702656ef1d3f93e472aae509a0ae5e241c4fd9b661f4cc6ffb02d416a72"
+ + "5469e51e27204b3db3f28961e244a9e6c3",
+ 16))),
+ new SshPublicKey<>(
+ PublicKeyFormat.ECDSA_SHA2_NISTP521,
+ new CustomEcPublicKey(
+ PointFormatter.formatFromByteArray(
+ NamedEcGroup.SECP521R1,
+ ArrayConverter.hexStringToByteArray(
+ "0400c94546ca3a758e2be7700c6710dbc193db62b511b51c"
+ + "2e5ae09e92723527078bfc97d7cfe0b30adec350905d4c3b"
+ + "2f798b88d57ca1a4cc8600ffa9568b50b8553400ce85433f"
+ + "fb71641153d690d1c253c8ca395daa9100a547f42a0ca8ae"
+ + "e4711bcc750294fd6719bb6348d0b92c51d00b7a12ba0646"
+ + "433d2f56677b4540ddf89a5da5")),
+ NamedEcGroup.SECP521R1),
+ new CustomEcPrivateKey(
+ new BigInteger(
+ "000bf5ef2fdec03bfa6cf0e2c5ee58c8bcfe0d1b41920792151f2c"
+ + "51b0aa621743b613056155bd51bde866f92b3e9bcfed230381"
+ + "b3dab5100a03c5965538c6f1c30a9",
+ 16),
+ NamedEcGroup.SECP521R1)),
+ new SshPublicKey<>(
+ PublicKeyFormat.SSH_ED25519,
+ new XCurveEcPublicKey(
ArrayConverter.hexStringToByteArray(
- "0400c94546ca3a758e2be7700c6710dbc193db62b511b51c"
- + "2e5ae09e92723527078bfc97d7cfe0b30adec350905d4c3b"
- + "2f798b88d57ca1a4cc8600ffa9568b50b8553400ce85433f"
- + "fb71641153d690d1c253c8ca395daa9100a547f42a0ca8ae"
- + "e4711bcc750294fd6719bb6348d0b92c51d00b7a12ba0646"
- + "433d2f56677b4540ddf89a5da5")),
- NamedEcGroup.SECP521R1),
- new CustomEcPrivateKey(
- new BigInteger(
- "000bf5ef2fdec03bfa6cf0e2c5ee58c8bcfe0d1b41920792151f2c"
- + "51b0aa621743b613056155bd51bde866f92b3e9bcfed230381"
- + "b3dab5100a03c5965538c6f1c30a9",
- 16),
- NamedEcGroup.SECP521R1)),
- new SshPublicKey<>(
- PublicKeyFormat.SSH_ED25519,
- new XCurveEcPublicKey(
- ArrayConverter.hexStringToByteArray(
- "99AF546D30DD1770CC27A1A1CE7AD1CEC729823527529352141E89F7F3420F2C"),
- NamedEcGroup.CURVE25519),
- new XCurveEcPrivateKey(
- ArrayConverter.hexStringToByteArray(
- "6D3703876ED02075102F767E2EA969E311B7776F71630B7C1DF3E55C98D6641B"),
- NamedEcGroup.CURVE25519)),
- new SshPublicKey<>(
- PublicKeyFormat.SSH_DSS,
- new CustomDsaPublicKey(
- new BigInteger(
- "00D34ED25D35236E5A3EFCAE34C30F06F444D1FBE85DC29D71DAD5"
- + "A8EFD5ED45609F4E29484DF5E21DB9926664296EF910AA9822FECDD"
- + "97514479DC28C69AB424A12D792E3B38D56C2DE668DA788286E5136"
- + "8AC1B837C7C928B5B5A6A277ECEA9436FAF7CBF279CD103695B7AEC"
- + "96B4EF975A218483BB715FE0CFEE7BE9E07DFA5",
- 16),
- new BigInteger(
- "00D8F3DAC6BFAA2CEAFCBF0E249DD0750913A5BFE9", 16),
- new BigInteger(
- "42B4D9C983941ADFDA0E6D9C4583F6FA96417017B389D750CFD717C"
- + "591FD12931167D12C96E3345E79B6225360485FF2E839CA9C38"
- + "D443A4AE2F13D6593FF69605866AC4AD1CD677441FD0D6ED15F"
- + "F636D8231130CC07B8AA6F1DF54A6517983695E3E5FFA3BFF9A"
- + "30B44423D8504CF0748AF99CA79B6A8599759E7C6DBBB5DC",
- 16),
- new BigInteger(
- "68801435B2A260F778520BD23C9EBF38AF523CB81D64C56F8741890B"
- + "1206CA2E175EE94BFF2C84601F357FB5B6071AB2240D7258D1EDE3D8B"
- + "CC2F6E78DEA5DCBB5BC315B858A1DD833607E0433CDE2FD24240DD2D1"
- + "C45F9508FBA25DC8E6F40D9BC58B6D3246865027E9B5E48F410E084B5"
- + "2A1AE99D2966543243764436757F6",
- 16)),
- new CustomDsaPrivateKey(
- new BigInteger(
- "00D34ED25D35236E5A3EFCAE34C30F06F444D1FBE85DC29D71DAD5A8EFD5"
- + "ED45609F4E29484DF5E21DB9926664296EF910AA9822FECDD97514479D"
- + "C28C69AB424A12D792E3B38D56C2DE668DA788286E51368AC1B837C7C9"
- + "28B5B5A6A277ECEA9436FAF7CBF279CD103695B7AEC96B4EF975A21848"
- + "3BB715FE0CFEE7BE9E07DFA5",
- 16),
- new BigInteger(
- "00D8F3DAC6BFAA2CEAFCBF0E249DD0750913A5BFE9", 16),
- new BigInteger(
- "42B4D9C983941ADFDA0E6D9C4583F6FA96417017B389D750CFD717C591FD"
- + "12931167D12C96E3345E79B6225360485FF2E839CA9C38D443A4AE2F13D6"
- + "593FF69605866AC4AD1CD677441FD0D6ED15FF636D8231130CC07B8AA6F1"
- + "DF54A6517983695E3E5FFA3BFF9A30B44423D8504CF0748AF99CA79B6A85"
- + "99759E7C6DBBB5DC",
- 16),
- new BigInteger(
- "6616556442F6B8F1EA8B5FA3A93BB638D55737D8", 16))));
+ "99AF546D30DD1770CC27A1A1CE7AD1CEC729823527529352141E89F7F3420F2C"),
+ NamedEcGroup.CURVE25519),
+ new XCurveEcPrivateKey(
+ ArrayConverter.hexStringToByteArray(
+ "6D3703876ED02075102F767E2EA969E311B7776F71630B7C1DF3E55C98D6641B"),
+ NamedEcGroup.CURVE25519)),
+ new SshPublicKey<>(
+ PublicKeyFormat.SSH_DSS,
+ new CustomDsaPublicKey(
+ new BigInteger(
+ "00D34ED25D35236E5A3EFCAE34C30F06F444D1FBE85DC29D71DAD5"
+ + "A8EFD5ED45609F4E29484DF5E21DB9926664296EF910AA9822FECDD"
+ + "97514479DC28C69AB424A12D792E3B38D56C2DE668DA788286E5136"
+ + "8AC1B837C7C928B5B5A6A277ECEA9436FAF7CBF279CD103695B7AEC"
+ + "96B4EF975A218483BB715FE0CFEE7BE9E07DFA5",
+ 16),
+ new BigInteger(
+ "00D8F3DAC6BFAA2CEAFCBF0E249DD0750913A5BFE9",
+ 16),
+ new BigInteger(
+ "42B4D9C983941ADFDA0E6D9C4583F6FA96417017B389D750CFD717C"
+ + "591FD12931167D12C96E3345E79B6225360485FF2E839CA9C38"
+ + "D443A4AE2F13D6593FF69605866AC4AD1CD677441FD0D6ED15F"
+ + "F636D8231130CC07B8AA6F1DF54A6517983695E3E5FFA3BFF9A"
+ + "30B44423D8504CF0748AF99CA79B6A8599759E7C6DBBB5DC",
+ 16),
+ new BigInteger(
+ "68801435B2A260F778520BD23C9EBF38AF523CB81D64C56F8741890B"
+ + "1206CA2E175EE94BFF2C84601F357FB5B6071AB2240D7258D1EDE3D8B"
+ + "CC2F6E78DEA5DCBB5BC315B858A1DD833607E0433CDE2FD24240DD2D1"
+ + "C45F9508FBA25DC8E6F40D9BC58B6D3246865027E9B5E48F410E084B5"
+ + "2A1AE99D2966543243764436757F6",
+ 16)),
+ new CustomDsaPrivateKey(
+ new BigInteger(
+ "00D34ED25D35236E5A3EFCAE34C30F06F444D1FBE85DC29D71DAD5A8EFD5"
+ + "ED45609F4E29484DF5E21DB9926664296EF910AA9822FECDD97514479D"
+ + "C28C69AB424A12D792E3B38D56C2DE668DA788286E51368AC1B837C7C9"
+ + "28B5B5A6A277ECEA9436FAF7CBF279CD103695B7AEC96B4EF975A21848"
+ + "3BB715FE0CFEE7BE9E07DFA5",
+ 16),
+ new BigInteger(
+ "00D8F3DAC6BFAA2CEAFCBF0E249DD0750913A5BFE9",
+ 16),
+ new BigInteger(
+ "42B4D9C983941ADFDA0E6D9C4583F6FA96417017B389D750CFD717C591FD"
+ + "12931167D12C96E3345E79B6225360485FF2E839CA9C38D443A4AE2F13D6"
+ + "593FF69605866AC4AD1CD677441FD0D6ED15FF636D8231130CC07B8AA6F1"
+ + "DF54A6517983695E3E5FFA3BFF9A30B44423D8504CF0748AF99CA79B6A85"
+ + "99759E7C6DBBB5DC",
+ 16),
+ new BigInteger(
+ "6616556442F6B8F1EA8B5FA3A93BB638D55737D8",
+ 16)))));
// endregion
// region Channel initialization
@@ -1064,12 +1267,299 @@ public Config() {
defaultBreakLength = 600;
// endregion
+ // region general SSH Settings
+ fallbackToNoDecryptionOnError = true;
+ fallbackToNoDecompressionOnError = true;
+ // endregion
+
// region Workflow settings initialization
workflowTraceType = null;
outputFilters = new ArrayList<>();
outputFilters.add(FilterType.DEFAULT);
applyFiltersInPlace = false;
// endregion
+
+ // region SFTP Version Exchange initialization
+ sftpClientVersion = 3;
+ sftpServerVersion = 3;
+ sftpNegotiatedVersion = 4;
+ // endregion
+
+ // region SFTP Extension
+ sftpClientSupportedExtensions = new ArrayList<>();
+ addAllSftpExtensions(sftpClientSupportedExtensions);
+ sftpServerSupportedExtensions = new ArrayList<>();
+ addAllSftpExtensions(sftpServerSupportedExtensions);
+ // endregion
+
+ // region general SFTP settings
+ respectSftpAttributesFlags = true;
+ // endregion
+
+ }
+
+ public static void addAllSftpExtensions(List> extensions) {
+ extensions.add(new SftpExtensionCheckFile());
+ extensions.add(new SftpExtensionCopyData());
+ extensions.add(new SftpExtensionCopyFile());
+ extensions.add(new SftpExtensionExpandPath());
+ extensions.add(new SftpExtensionFileStatVfs());
+ extensions.add(new SftpExtensionFileSync());
+ extensions.add(new SftpExtensionGetTempFolder());
+ extensions.add(new SftpExtensionHardlink());
+ extensions.add(new SftpExtensionHomeDirectory());
+ extensions.add(new SftpExtensionLimits());
+ extensions.add(new SftpExtensionLinkSetStat());
+ extensions.add(new SftpExtensionMakeTempFolder());
+ extensions.add(new SftpExtensionPosixRename());
+ extensions.add(new SftpExtensionSpaceAvailable());
+ extensions.add(new SftpExtensionStatVfs());
+ extensions.add(new SftpExtensionUsersGroupsById());
+ extensions.add(new SftpExtensionVendorId());
+ extensions.add(new SftpExtensionTextSeek());
+ extensions.add(new SftpExtensionNewline());
+ }
+
+ // endregion
+
+ // region copy constructor
+
+ public Config(Config other) {
+ super();
+ defaultClientConnection =
+ other.defaultClientConnection != null
+ ? other.defaultClientConnection.createCopy()
+ : null;
+ defaultServerConnection =
+ other.defaultServerConnection != null
+ ? other.defaultServerConnection.createCopy()
+ : null;
+ defaultRunningMode = other.defaultRunningMode;
+ clientVersion = other.clientVersion;
+ clientComment = other.clientComment;
+ clientEndOfMessageSequence = other.clientEndOfMessageSequence;
+ serverVersion = other.serverVersion;
+ serverComment = other.serverComment;
+ serverEndOfMessageSequence = other.serverEndOfMessageSequence;
+ clientCookie = other.clientCookie != null ? other.clientCookie.clone() : null;
+ serverCookie = other.serverCookie != null ? other.serverCookie.clone() : null;
+ clientSupportedKeyExchangeAlgorithms =
+ other.clientSupportedKeyExchangeAlgorithms != null
+ ? new ArrayList<>(other.clientSupportedKeyExchangeAlgorithms)
+ : null;
+ serverSupportedKeyExchangeAlgorithms =
+ other.serverSupportedKeyExchangeAlgorithms != null
+ ? new ArrayList<>(other.serverSupportedKeyExchangeAlgorithms)
+ : null;
+ clientSupportedHostKeyAlgorithms =
+ other.clientSupportedHostKeyAlgorithms != null
+ ? new ArrayList<>(other.clientSupportedHostKeyAlgorithms)
+ : null;
+ serverSupportedHostKeyAlgorithms =
+ other.serverSupportedHostKeyAlgorithms != null
+ ? new ArrayList<>(other.serverSupportedHostKeyAlgorithms)
+ : null;
+ clientSupportedEncryptionAlgorithmsClientToServer =
+ other.clientSupportedEncryptionAlgorithmsClientToServer != null
+ ? new ArrayList<>(other.clientSupportedEncryptionAlgorithmsClientToServer)
+ : null;
+ clientSupportedEncryptionAlgorithmsServerToClient =
+ other.clientSupportedEncryptionAlgorithmsServerToClient != null
+ ? new ArrayList<>(other.clientSupportedEncryptionAlgorithmsServerToClient)
+ : null;
+ serverSupportedEncryptionAlgorithmsServerToClient =
+ other.serverSupportedEncryptionAlgorithmsServerToClient != null
+ ? new ArrayList<>(other.serverSupportedEncryptionAlgorithmsServerToClient)
+ : null;
+ serverSupportedEncryptionAlgorithmsClientToServer =
+ other.serverSupportedEncryptionAlgorithmsClientToServer != null
+ ? new ArrayList<>(other.serverSupportedEncryptionAlgorithmsClientToServer)
+ : null;
+ clientSupportedMacAlgorithmsClientToServer =
+ other.clientSupportedMacAlgorithmsClientToServer != null
+ ? new ArrayList<>(other.clientSupportedMacAlgorithmsClientToServer)
+ : null;
+ clientSupportedMacAlgorithmsServerToClient =
+ other.clientSupportedMacAlgorithmsServerToClient != null
+ ? new ArrayList<>(other.clientSupportedMacAlgorithmsServerToClient)
+ : null;
+ serverSupportedMacAlgorithmsServerToClient =
+ other.serverSupportedMacAlgorithmsServerToClient != null
+ ? new ArrayList<>(other.serverSupportedMacAlgorithmsServerToClient)
+ : null;
+ serverSupportedMacAlgorithmsClientToServer =
+ other.serverSupportedMacAlgorithmsClientToServer != null
+ ? new ArrayList<>(other.serverSupportedMacAlgorithmsClientToServer)
+ : null;
+ clientSupportedCompressionMethodsClientToServer =
+ other.clientSupportedCompressionMethodsClientToServer != null
+ ? new ArrayList<>(other.clientSupportedCompressionMethodsClientToServer)
+ : null;
+ clientSupportedCompressionMethodsServerToClient =
+ other.clientSupportedCompressionMethodsServerToClient != null
+ ? new ArrayList<>(other.clientSupportedCompressionMethodsServerToClient)
+ : null;
+ serverSupportedCompressionMethodsServerToClient =
+ other.serverSupportedCompressionMethodsServerToClient != null
+ ? new ArrayList<>(other.serverSupportedCompressionMethodsServerToClient)
+ : null;
+ serverSupportedCompressionMethodsClientToServer =
+ other.serverSupportedCompressionMethodsClientToServer != null
+ ? new ArrayList<>(other.serverSupportedCompressionMethodsClientToServer)
+ : null;
+ clientSupportedLanguagesClientToServer =
+ other.clientSupportedLanguagesClientToServer != null
+ ? new ArrayList<>(other.clientSupportedLanguagesClientToServer)
+ : null;
+ clientSupportedLanguagesServerToClient =
+ other.clientSupportedLanguagesServerToClient != null
+ ? new ArrayList<>(other.clientSupportedLanguagesServerToClient)
+ : null;
+ serverSupportedLanguagesServerToClient =
+ other.serverSupportedLanguagesServerToClient != null
+ ? new ArrayList<>(other.serverSupportedLanguagesServerToClient)
+ : null;
+ serverSupportedLanguagesClientToServer =
+ other.serverSupportedLanguagesClientToServer != null
+ ? new ArrayList<>(other.serverSupportedLanguagesClientToServer)
+ : null;
+ clientFirstKeyExchangePacketFollows = other.clientFirstKeyExchangePacketFollows;
+ serverFirstKeyExchangePacketFollows = other.serverFirstKeyExchangePacketFollows;
+ clientReserved = other.clientReserved;
+ serverReserved = other.serverReserved;
+ dhGexMinimalGroupSize = other.dhGexMinimalGroupSize;
+ dhGexPreferredGroupSize = other.dhGexPreferredGroupSize;
+ dhGexMaximalGroupSize = other.dhGexMaximalGroupSize;
+ defaultDhKeyExchangeAlgorithm = other.defaultDhKeyExchangeAlgorithm;
+ defaultEcdhKeyExchangeAlgorithm = other.defaultEcdhKeyExchangeAlgorithm;
+ defaultRsaKeyExchangeAlgorithm = other.defaultRsaKeyExchangeAlgorithm;
+ defaultHybridKeyExchangeAlgorithm = other.defaultHybridKeyExchangeAlgorithm;
+ enableEncryptionOnNewKeysMessage = other.enableEncryptionOnNewKeysMessage;
+ forcePacketCipherChange = other.forcePacketCipherChange;
+ enforceSettings = other.enforceSettings;
+ if (other.hostKeys != null) {
+ hostKeys = new ArrayList<>(other.hostKeys.size());
+ for (SshPublicKey, ?> item : other.hostKeys) {
+ hostKeys.add(item != null ? item.createCopy() : null);
+ }
+ }
+ fallbackRsaTransientPublicKey =
+ other.fallbackRsaTransientPublicKey != null
+ ? other.fallbackRsaTransientPublicKey.createCopy()
+ : null;
+ if (other.clientSupportedExtensions != null) {
+ clientSupportedExtensions = new ArrayList<>(other.clientSupportedExtensions.size());
+ for (AbstractExtension> item : other.clientSupportedExtensions) {
+ clientSupportedExtensions.add(item != null ? item.createCopy() : null);
+ }
+ }
+ if (other.serverSupportedExtensions != null) {
+ serverSupportedExtensions = new ArrayList<>(other.serverSupportedExtensions.size());
+ for (AbstractExtension> item : other.serverSupportedExtensions) {
+ serverSupportedExtensions.add(item != null ? item.createCopy() : null);
+ }
+ }
+ respectServerSigAlgsExtension = other.respectServerSigAlgsExtension;
+ serverSupportedPublicKeyAlgorithmsForAuthentication =
+ other.serverSupportedPublicKeyAlgorithmsForAuthentication != null
+ ? new ArrayList<>(other.serverSupportedPublicKeyAlgorithmsForAuthentication)
+ : null;
+ clientSupportedDelayCompressionMethods =
+ other.clientSupportedDelayCompressionMethods != null
+ ? new ArrayList<>(other.clientSupportedDelayCompressionMethods)
+ : null;
+ serverSupportedDelayCompressionMethods =
+ other.serverSupportedDelayCompressionMethods != null
+ ? new ArrayList<>(other.serverSupportedDelayCompressionMethods)
+ : null;
+ respectDelayCompressionExtension = other.respectDelayCompressionExtension;
+ authenticationMethod = other.authenticationMethod;
+ serviceName = other.serviceName;
+ username = other.username;
+ password = other.password;
+ if (other.preConfiguredAuthResponses != null) {
+ preConfiguredAuthResponses = new ArrayList<>(other.preConfiguredAuthResponses.size());
+ for (AuthenticationResponseEntries item : other.preConfiguredAuthResponses) {
+ preConfiguredAuthResponses.add(item != null ? item.createCopy() : null);
+ }
+ }
+ if (other.preConfiguredAuthPrompts != null) {
+ preConfiguredAuthPrompts = new ArrayList<>(other.preConfiguredAuthPrompts.size());
+ for (AuthenticationPromptEntries item : other.preConfiguredAuthPrompts) {
+ preConfiguredAuthPrompts.add(item != null ? item.createCopy() : null);
+ }
+ }
+ if (other.userKeys != null) {
+ userKeys = new ArrayList<>(other.userKeys.size());
+ for (SshPublicKey, ?> item : other.userKeys) {
+ userKeys.add(item != null ? item.createCopy() : null);
+ }
+ }
+ channelCommand = other.channelCommand;
+ channelDefaults = other.channelDefaults != null ? other.channelDefaults.createCopy() : null;
+ reopenChannelOnClose = other.reopenChannelOnClose;
+ replyWanted = other.replyWanted;
+ defaultVariableName = other.defaultVariableName;
+ defaultVariableValue = other.defaultVariableValue;
+ clientFlowControl = other.clientFlowControl;
+ defaultTerminalWidthPixels = other.defaultTerminalWidthPixels;
+ defaultTerminalWidthColumns = other.defaultTerminalWidthColumns;
+ defaultTerminalHeightRows = other.defaultTerminalHeightRows;
+ defaultTerminalHeightPixels = other.defaultTerminalHeightPixels;
+ defaultTermEnvVariable = other.defaultTermEnvVariable;
+ defaultSubsystemName = other.defaultSubsystemName;
+ defaultBreakLength = other.defaultBreakLength;
+ fallbackToNoDecryptionOnError = other.fallbackToNoDecryptionOnError;
+ fallbackToNoDecompressionOnError = other.fallbackToNoDecompressionOnError;
+ sftpClientVersion = other.sftpClientVersion;
+ sftpServerVersion = other.sftpServerVersion;
+ sftpNegotiatedVersion = other.sftpNegotiatedVersion;
+ if (other.sftpClientSupportedExtensions != null) {
+ sftpClientSupportedExtensions =
+ new ArrayList<>(other.sftpClientSupportedExtensions.size());
+ for (SftpAbstractExtension> item : other.sftpClientSupportedExtensions) {
+ sftpClientSupportedExtensions.add(item != null ? item.createCopy() : null);
+ }
+ }
+ if (other.sftpServerSupportedExtensions != null) {
+ sftpServerSupportedExtensions =
+ new ArrayList<>(other.sftpServerSupportedExtensions.size());
+ for (SftpAbstractExtension> item : other.sftpServerSupportedExtensions) {
+ sftpServerSupportedExtensions.add(item != null ? item.createCopy() : null);
+ }
+ }
+ respectSftpAttributesFlags = other.respectSftpAttributesFlags;
+ workflowInput = other.workflowInput;
+ workflowTraceType = other.workflowTraceType;
+ outputFilters = other.outputFilters != null ? new ArrayList<>(other.outputFilters) : null;
+ workflowOutput = other.workflowOutput;
+ workflowExecutorType = other.workflowExecutorType;
+ applyFiltersInPlace = other.applyFiltersInPlace;
+ filtersKeepUserSettings = other.filtersKeepUserSettings;
+ workflowExecutorShouldOpen = other.workflowExecutorShouldOpen;
+ stopActionsAfterDisconnect = other.stopActionsAfterDisconnect;
+ handleTimeoutOnReceiveAsIOException = other.handleTimeoutOnReceiveAsIOException;
+ stopActionsAfterIOException = other.stopActionsAfterIOException;
+ workflowExecutorShouldClose = other.workflowExecutorShouldClose;
+ resetWorkflowTraceBeforeExecution = other.resetWorkflowTraceBeforeExecution;
+ resetWorkflowTraceBeforeSaving = other.resetWorkflowTraceBeforeSaving;
+ resetModifiableVariables = other.resetModifiableVariables;
+ resetClientSourcePort = other.resetClientSourcePort;
+ retryFailedClientTcpSocketInitialization = other.retryFailedClientTcpSocketInitialization;
+ stopTraceAfterUnexpected = other.stopTraceAfterUnexpected;
+ allowDynamicGenerationOfActions = other.allowDynamicGenerationOfActions;
+ addDynamicallyGeneratedActionsToWorkflowTrace =
+ other.addDynamicallyGeneratedActionsToWorkflowTrace;
+ quickReceive = other.quickReceive;
+ endReceivingEarly = other.endReceivingEarly;
+ receiveMaximumBytes = other.receiveMaximumBytes;
+ stopReceivingAfterDisconnect = other.stopReceivingAfterDisconnect;
+ configOutput = other.configOutput;
+ chooserType = other.chooserType;
+ }
+
+ public Config createCopy() {
+ return new Config(this);
}
// endregion
@@ -1084,7 +1574,13 @@ public static Config createConfig() {
}
public static Config createConfig(File file) {
- return ConfigIO.read(file);
+ ConfigCache cachedConfig = PATH_CONFIG_CACHE.get(file);
+ if (cachedConfig != null) {
+ return cachedConfig.getCachedCopy();
+ }
+ Config resultConfig = ConfigIO.read(file);
+ PATH_CONFIG_CACHE.put(file, new ConfigCache(resultConfig.createCopy()));
+ return resultConfig;
}
public static Config createConfig(InputStream stream) {
@@ -1115,6 +1611,29 @@ public static Config createEmptyConfig() {
// endregion
+ // region storeConfig
+ /** Serialize and write config to file. */
+ public void storeConfig() {
+ Random random = new Random();
+ String configOutputName = configOutput;
+ if (configOutputName != null && !configOutputName.isEmpty()) {
+ try {
+
+ File file = new File(configOutputName);
+ if (file.isDirectory()) {
+ configOutputName = "config-" + random.nextInt() + ".xml";
+ file = new File(file, configOutputName);
+ }
+ ConfigIO.write(this, file);
+ } catch (RuntimeException ex) {
+ LOGGER.info("Could not serialize Config.");
+ LOGGER.debug(ex);
+ }
+ }
+ }
+
+ // endregion
+
public OutboundConnection getDefaultClientConnection() {
return defaultClientConnection;
}
@@ -1206,7 +1725,7 @@ public List getClientSupportedKeyExchangeAlgorithms() {
}
public void setClientSupportedKeyExchangeAlgorithms(
- List clientSupportedKeyExchangeAlgorithms) {
+ ArrayList clientSupportedKeyExchangeAlgorithms) {
this.clientSupportedKeyExchangeAlgorithms = clientSupportedKeyExchangeAlgorithms;
}
@@ -1270,19 +1789,19 @@ public List getServerSupportedCompressionMethodsClientToServe
return serverSupportedCompressionMethodsClientToServer;
}
- public List getClientSupportedLanguagesClientToServer() {
+ public List getClientSupportedLanguagesClientToServer() {
return clientSupportedLanguagesClientToServer;
}
- public List getClientSupportedLanguagesServerToClient() {
+ public List getClientSupportedLanguagesServerToClient() {
return clientSupportedLanguagesServerToClient;
}
- public List getServerSupportedLanguagesServerToClient() {
+ public List getServerSupportedLanguagesServerToClient() {
return serverSupportedLanguagesServerToClient;
}
- public List getServerSupportedLanguagesClientToServer() {
+ public List getServerSupportedLanguagesClientToServer() {
return serverSupportedLanguagesClientToServer;
}
@@ -1314,109 +1833,109 @@ public void setServerCookie(byte[] serverCookie) {
}
public void setServerSupportedKeyExchangeAlgorithms(
- List serverSupportedKeyExchangeAlgorithms) {
+ ArrayList serverSupportedKeyExchangeAlgorithms) {
this.serverSupportedKeyExchangeAlgorithms = serverSupportedKeyExchangeAlgorithms;
}
public void setClientSupportedHostKeyAlgorithms(
- List clientSupportedHostKeyAlgorithms) {
+ ArrayList clientSupportedHostKeyAlgorithms) {
this.clientSupportedHostKeyAlgorithms = clientSupportedHostKeyAlgorithms;
}
public void setServerSupportedHostKeyAlgorithms(
- List serverSupportedHostKeyAlgorithms) {
+ ArrayList serverSupportedHostKeyAlgorithms) {
this.serverSupportedHostKeyAlgorithms = serverSupportedHostKeyAlgorithms;
}
public void setClientSupportedEncryptionAlgorithmsClientToServer(
- List clientSupportedEncryptionAlgorithmsClientToServer) {
+ ArrayList clientSupportedEncryptionAlgorithmsClientToServer) {
this.clientSupportedEncryptionAlgorithmsClientToServer =
clientSupportedEncryptionAlgorithmsClientToServer;
}
public void setClientSupportedEncryptionAlgorithmsServerToClient(
- List clientSupportedEncryptionAlgorithmsServerToClient) {
+ ArrayList clientSupportedEncryptionAlgorithmsServerToClient) {
this.clientSupportedEncryptionAlgorithmsServerToClient =
clientSupportedEncryptionAlgorithmsServerToClient;
}
public void setServerSupportedEncryptionAlgorithmsServerToClient(
- List serverSupportedEncryptionAlgorithmsServerToClient) {
+ ArrayList serverSupportedEncryptionAlgorithmsServerToClient) {
this.serverSupportedEncryptionAlgorithmsServerToClient =
serverSupportedEncryptionAlgorithmsServerToClient;
}
public void setServerSupportedEncryptionAlgorithmsClientToServer(
- List serverSupportedEncryptionAlgorithmsClientToServer) {
+ ArrayList serverSupportedEncryptionAlgorithmsClientToServer) {
this.serverSupportedEncryptionAlgorithmsClientToServer =
serverSupportedEncryptionAlgorithmsClientToServer;
}
public void setClientSupportedMacAlgorithmsClientToServer(
- List clientSupportedMacAlgorithmsClientToServer) {
+ ArrayList clientSupportedMacAlgorithmsClientToServer) {
this.clientSupportedMacAlgorithmsClientToServer =
clientSupportedMacAlgorithmsClientToServer;
}
public void setClientSupportedMacAlgorithmsServerToClient(
- List clientSupportedMacAlgorithmsServerToClient) {
+ ArrayList clientSupportedMacAlgorithmsServerToClient) {
this.clientSupportedMacAlgorithmsServerToClient =
clientSupportedMacAlgorithmsServerToClient;
}
public void setServerSupportedMacAlgorithmsServerToClient(
- List serverSupportedMacAlgorithmsServerToClient) {
+ ArrayList serverSupportedMacAlgorithmsServerToClient) {
this.serverSupportedMacAlgorithmsServerToClient =
serverSupportedMacAlgorithmsServerToClient;
}
public void setServerSupportedMacAlgorithmsClientToServer(
- List serverSupportedMacAlgorithmsClientToServer) {
+ ArrayList serverSupportedMacAlgorithmsClientToServer) {
this.serverSupportedMacAlgorithmsClientToServer =
serverSupportedMacAlgorithmsClientToServer;
}
public void setClientSupportedCompressionMethodsClientToServer(
- List clientSupportedCompressionMethodsClientToServer) {
+ ArrayList clientSupportedCompressionMethodsClientToServer) {
this.clientSupportedCompressionMethodsClientToServer =
clientSupportedCompressionMethodsClientToServer;
}
public void setClientSupportedCompressionMethodsServerToClient(
- List clientSupportedCompressionMethodsServerToClient) {
+ ArrayList clientSupportedCompressionMethodsServerToClient) {
this.clientSupportedCompressionMethodsServerToClient =
clientSupportedCompressionMethodsServerToClient;
}
public void setServerSupportedCompressionMethodsServerToClient(
- List serverSupportedCompressionMethodsServerToClient) {
+ ArrayList serverSupportedCompressionMethodsServerToClient) {
this.serverSupportedCompressionMethodsServerToClient =
serverSupportedCompressionMethodsServerToClient;
}
public void setServerSupportedCompressionMethodsClientToServer(
- List serverSupportedCompressionMethodsClientToServer) {
+ ArrayList serverSupportedCompressionMethodsClientToServer) {
this.serverSupportedCompressionMethodsClientToServer =
serverSupportedCompressionMethodsClientToServer;
}
public void setClientSupportedLanguagesClientToServer(
- List clientSupportedLanguagesClientToServer) {
+ ArrayList clientSupportedLanguagesClientToServer) {
this.clientSupportedLanguagesClientToServer = clientSupportedLanguagesClientToServer;
}
public void setClientSupportedLanguagesServerToClient(
- List clientSupportedLanguagesServerToClient) {
+ ArrayList clientSupportedLanguagesServerToClient) {
this.clientSupportedLanguagesServerToClient = clientSupportedLanguagesServerToClient;
}
public void setServerSupportedLanguagesServerToClient(
- List serverSupportedLanguagesServerToClient) {
+ ArrayList serverSupportedLanguagesServerToClient) {
this.serverSupportedLanguagesServerToClient = serverSupportedLanguagesServerToClient;
}
public void setServerSupportedLanguagesClientToServer(
- List serverSupportedLanguagesClientToServer) {
+ ArrayList serverSupportedLanguagesClientToServer) {
this.serverSupportedLanguagesClientToServer = serverSupportedLanguagesClientToServer;
}
@@ -1443,11 +1962,11 @@ public void setServerReserved(int serverReserved) {
// region Getters SSH Extensions
// section general extensions
- public List> getClientSupportedExtensions() {
+ public ArrayList> getClientSupportedExtensions() {
return clientSupportedExtensions;
}
- public List> getServerSupportedExtensions() {
+ public ArrayList> getServerSupportedExtensions() {
return serverSupportedExtensions;
}
@@ -1478,17 +1997,19 @@ public boolean getRespectDelayCompressionExtension() {
// region Setters SSH Extensions
// section general extensions
- public void setClientSupportedExtensions(List> clientSupportedExtensions) {
+ public void setClientSupportedExtensions(
+ ArrayList> clientSupportedExtensions) {
this.clientSupportedExtensions = clientSupportedExtensions;
}
- public void setServerSupportedExtensions(List> serverSupportedExtensions) {
+ public void setServerSupportedExtensions(
+ ArrayList> serverSupportedExtensions) {
this.serverSupportedExtensions = serverSupportedExtensions;
}
// section server-sig-algs extension
public void setServerSupportedPublicKeyAlgorithmsForAuthentication(
- List serverSupportedPublicKeyAlgorithmsForAuthentication) {
+ ArrayList serverSupportedPublicKeyAlgorithmsForAuthentication) {
this.serverSupportedPublicKeyAlgorithmsForAuthentication =
serverSupportedPublicKeyAlgorithmsForAuthentication;
}
@@ -1499,12 +2020,12 @@ public void setRespectServerSigAlgsExtension(boolean respectServerSigAlgsExtensi
// section delay-compression extension
public void setClientSupportedDelayCompressionMethods(
- List clientSupportedDelayCompressionMethods) {
+ ArrayList clientSupportedDelayCompressionMethods) {
this.clientSupportedDelayCompressionMethods = clientSupportedDelayCompressionMethods;
}
public void setServerSupportedDelayCompressionMethods(
- List serverSupportedDelayCompressionMethods) {
+ ArrayList serverSupportedDelayCompressionMethods) {
this.serverSupportedDelayCompressionMethods = serverSupportedDelayCompressionMethods;
}
@@ -1598,7 +2119,7 @@ public void setDefaultRsaKeyExchangeAlgorithm(
this.defaultRsaKeyExchangeAlgorithm = defaultRsaKeyExchangeAlgorithm;
}
- public void setEnableEncryptionOnNewKeysMessageType(
+ public void setEnableEncryptionOnNewKeysMessage(
ConnectionDirection enableEncryptionOnNewKeysMessage) {
this.enableEncryptionOnNewKeysMessage = enableEncryptionOnNewKeysMessage;
}
@@ -1612,6 +2133,10 @@ public void setEnforceSettings(Boolean enforceSettings) {
}
public void setHostKeys(List> hostKeys) {
+ this.hostKeys = new ArrayList<>(Objects.requireNonNull(hostKeys));
+ }
+
+ public void setHostKeys(ArrayList> hostKeys) {
this.hostKeys = Objects.requireNonNull(hostKeys);
}
@@ -1634,10 +2159,14 @@ public String getServiceName() {
return serviceName;
}
- public List getPreConfiguredAuthResponses() {
+ public ArrayList getPreConfiguredAuthResponses() {
return preConfiguredAuthResponses;
}
+ public ArrayList getPreConfiguredAuthPrompts() {
+ return preConfiguredAuthPrompts;
+ }
+
public List> getUserKeys() {
return userKeys;
}
@@ -1661,11 +2190,20 @@ public void setServiceName(String serviceName) {
}
public void setPreConfiguredAuthResponses(
- List preConfiguredAuthResponses) {
+ ArrayList preConfiguredAuthResponses) {
this.preConfiguredAuthResponses = preConfiguredAuthResponses;
}
+ public void setPreConfiguredAuthPrompts(
+ ArrayList preConfiguredAuthPrompts) {
+ this.preConfiguredAuthPrompts = preConfiguredAuthPrompts;
+ }
+
public void setUserKeys(List> userKeys) {
+ this.userKeys = new ArrayList<>(Objects.requireNonNull(userKeys));
+ }
+
+ public void setUserKeys(ArrayList> userKeys) {
this.userKeys = Objects.requireNonNull(userKeys);
}
@@ -1684,6 +2222,10 @@ public ChannelDefaults getChannelDefaults() {
return channelDefaults;
}
+ public Boolean getReopenChannelOnClose() {
+ return reopenChannelOnClose;
+ }
+
public String getDefaultVariableValue() {
return defaultVariableValue;
}
@@ -1738,6 +2280,10 @@ public void setChannelDefaults(ChannelDefaults channelDefaults) {
this.channelDefaults = channelDefaults;
}
+ public void setReopenChannelOnClose(Boolean reopenChannelOnClose) {
+ this.reopenChannelOnClose = reopenChannelOnClose;
+ }
+
public void setDefaultVariableValue(String defaultVariableValue) {
this.defaultVariableValue = defaultVariableValue;
}
@@ -1780,6 +2326,25 @@ public void setDefaultBreakLength(int defaultBreakLength) {
// endregion
+ // region general SSH settings
+ public Boolean getFallbackToNoDecryptionOnError() {
+ return fallbackToNoDecryptionOnError;
+ }
+
+ public void setFallbackToNoDecryptionOnError(Boolean fallbackToNoDecryptionOnError) {
+ this.fallbackToNoDecryptionOnError = fallbackToNoDecryptionOnError;
+ }
+
+ public Boolean getFallbackToNoDecompressionOnError() {
+ return fallbackToNoDecompressionOnError;
+ }
+
+ public void setFallbackToNoDecompressionOnError(Boolean fallbackToNoDecompressionOnError) {
+ this.fallbackToNoDecompressionOnError = fallbackToNoDecompressionOnError;
+ }
+
+ // endregion
+
// region Getters for Workflow settings
public Boolean isFiltersKeepUserSettings() {
return filtersKeepUserSettings;
@@ -1813,10 +2378,14 @@ public Boolean getWorkflowExecutorShouldOpen() {
return workflowExecutorShouldOpen;
}
- public Boolean getStopActionsAfterDisconnect() {
+ public Boolean isStopActionsAfterDisconnect() {
return stopActionsAfterDisconnect;
}
+ public Boolean getHandleTimeoutOnReceiveAsIOException() {
+ return handleTimeoutOnReceiveAsIOException;
+ }
+
public Boolean getStopActionsAfterIOException() {
return stopActionsAfterIOException;
}
@@ -1825,8 +2394,16 @@ public Boolean getWorkflowExecutorShouldClose() {
return workflowExecutorShouldClose;
}
- public Boolean getResetWorkflowtracesBeforeSaving() {
- return resetWorkflowtracesBeforeSaving;
+ public Boolean getResetWorkflowTraceBeforeExecution() {
+ return resetWorkflowTraceBeforeExecution;
+ }
+
+ public Boolean getResetWorkflowTraceBeforeSaving() {
+ return resetWorkflowTraceBeforeSaving;
+ }
+
+ public Boolean getResetModifiableVariables() {
+ return resetModifiableVariables;
}
public Boolean getResetClientSourcePort() {
@@ -1841,6 +2418,14 @@ public Boolean getStopTraceAfterUnexpected() {
return stopTraceAfterUnexpected;
}
+ public Boolean getAllowDynamicGenerationOfActions() {
+ return allowDynamicGenerationOfActions;
+ }
+
+ public Boolean getAddDynamicallyGeneratedActionsToWorkflowTrace() {
+ return addDynamicallyGeneratedActionsToWorkflowTrace;
+ }
+
// endregion
// region Setters for Workflow settings
@@ -1856,7 +2441,7 @@ public void setWorkflowTraceType(WorkflowTraceType workflowTraceType) {
this.workflowTraceType = workflowTraceType;
}
- public void setOutputFilters(List outputFilters) {
+ public void setOutputFilters(ArrayList outputFilters) {
this.outputFilters = outputFilters;
}
@@ -1880,6 +2465,11 @@ public void setStopActionsAfterDisconnect(Boolean stopActionsAfterDisconnect) {
this.stopActionsAfterDisconnect = stopActionsAfterDisconnect;
}
+ public void setHandleTimeoutOnReceiveAsIOException(
+ Boolean handleTimeoutOnReceiveAsIOException) {
+ this.handleTimeoutOnReceiveAsIOException = handleTimeoutOnReceiveAsIOException;
+ }
+
public void setStopActionsAfterIOException(Boolean stopActionsAfterIOException) {
this.stopActionsAfterIOException = stopActionsAfterIOException;
}
@@ -1888,8 +2478,16 @@ public void setWorkflowExecutorShouldClose(Boolean workflowExecutorShouldClose)
this.workflowExecutorShouldClose = workflowExecutorShouldClose;
}
- public void setResetWorkflowtracesBeforeSaving(Boolean resetWorkflowtracesBeforeSaving) {
- this.resetWorkflowtracesBeforeSaving = resetWorkflowtracesBeforeSaving;
+ public void setResetWorkflowTraceBeforeExecution(Boolean resetWorkflowTraceBeforeExecution) {
+ this.resetWorkflowTraceBeforeExecution = resetWorkflowTraceBeforeExecution;
+ }
+
+ public void setResetWorkflowTraceBeforeSaving(Boolean resetWorkflowTraceBeforeSaving) {
+ this.resetWorkflowTraceBeforeSaving = resetWorkflowTraceBeforeSaving;
+ }
+
+ public void setResetModifiableVariables(Boolean resetModifiableVariables) {
+ this.resetModifiableVariables = resetModifiableVariables;
}
public void setResetClientSourcePort(Boolean resetClientSourcePort) {
@@ -1905,6 +2503,16 @@ public void setStopTraceAfterUnexpected(Boolean stopTraceAfterUnexpected) {
this.stopTraceAfterUnexpected = stopTraceAfterUnexpected;
}
+ public void setAllowDynamicGenerationOfActions(Boolean allowDynamicGenerationOfActions) {
+ this.allowDynamicGenerationOfActions = allowDynamicGenerationOfActions;
+ }
+
+ public void setAddDynamicallyGeneratedActionsToWorkflowTrace(
+ Boolean addDynamicallyGeneratedActionsToWorkflowTrace) {
+ this.addDynamicallyGeneratedActionsToWorkflowTrace =
+ addDynamicallyGeneratedActionsToWorkflowTrace;
+ }
+
// endregion
// region Getters for ReceiveAction
@@ -1916,6 +2524,14 @@ public Integer getReceiveMaximumBytes() {
return receiveMaximumBytes;
}
+ public Boolean isEndReceivingEarly() {
+ return endReceivingEarly;
+ }
+
+ public void setEndReceivingEarly(Boolean endReceivingEarly) {
+ this.endReceivingEarly = endReceivingEarly;
+ }
+
public Boolean isStopReceivingAfterDisconnect() {
return stopReceivingAfterDisconnect;
}
@@ -1951,4 +2567,71 @@ public ChooserType getChooserType() {
public void setChooserType(ChooserType chooserType) {
this.chooserType = chooserType;
}
+
+ // region Getters for SFTP Version Exchange
+ public Integer getSftpClientVersion() {
+ return sftpClientVersion;
+ }
+
+ public Integer getSftpServerVersion() {
+ return sftpServerVersion;
+ }
+
+ public Integer getSftpNegotiatedVersion() {
+ return sftpNegotiatedVersion;
+ }
+
+ // endregion
+ // region Setters for SFTP Version Exchange
+ public void setSftpClientVersion(Integer sftpClientVersion) {
+ this.sftpClientVersion = sftpClientVersion;
+ }
+
+ public void setSftpServerVersion(Integer sftpServerVersion) {
+ this.sftpServerVersion = sftpServerVersion;
+ }
+
+ public void setSftpNegotiatedVersion(Integer sftpNegotiatedVersion) {
+ this.sftpNegotiatedVersion = sftpNegotiatedVersion;
+ }
+
+ // endregion
+
+ // region Getters SFTP Extensions
+
+ // section general extensions
+ public ArrayList> getSftpClientSupportedExtensions() {
+ return sftpClientSupportedExtensions;
+ }
+
+ public ArrayList> getSftpServerSupportedExtensions() {
+ return sftpServerSupportedExtensions;
+ }
+
+ // endregion
+
+ // region Setters SFTP Extensions
+
+ // section general extensions
+ public void setSftpClientSupportedExtensions(
+ ArrayList> sftpClientSupportedExtensions) {
+ this.sftpClientSupportedExtensions = sftpClientSupportedExtensions;
+ }
+
+ public void setSftpServerSupportedExtensions(
+ ArrayList> sftpServerSupportedExtensions) {
+ this.sftpServerSupportedExtensions = sftpServerSupportedExtensions;
+ }
+
+ // endregion
+
+ // region general SFTP settings
+ public void setRespectSftpAttributesFlags(Boolean respectSftpAttributesFlags) {
+ this.respectSftpAttributesFlags = respectSftpAttributesFlags;
+ }
+
+ public Boolean getRespectSftpAttributesFlags() {
+ return respectSftpAttributesFlags;
+ }
+ // endregion
}
diff --git a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/config/ConfigCache.java b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/config/ConfigCache.java
index b7b0248d9..a880f9c16 100755
--- a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/config/ConfigCache.java
+++ b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/config/ConfigCache.java
@@ -7,8 +7,6 @@
*/
package de.rub.nds.sshattacker.core.config;
-import org.apache.commons.lang3.SerializationUtils;
-
public class ConfigCache {
private final Config cachedConfig;
@@ -19,6 +17,6 @@ public ConfigCache(Config cachedConfig) {
}
public Config getCachedCopy() {
- return SerializationUtils.clone(cachedConfig);
+ return cachedConfig.createCopy();
}
}
diff --git a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/config/ConfigIO.java b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/config/ConfigIO.java
index 9e960abd4..e050d7243 100755
--- a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/config/ConfigIO.java
+++ b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/config/ConfigIO.java
@@ -7,20 +7,15 @@
*/
package de.rub.nds.sshattacker.core.config;
+import de.rub.nds.modifiablevariable.VariableModification;
import de.rub.nds.sshattacker.core.config.filter.ConfigDisplayFilter;
import jakarta.xml.bind.JAXBContext;
import jakarta.xml.bind.JAXBException;
import jakarta.xml.bind.Unmarshaller;
import jakarta.xml.bind.util.JAXBSource;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
+import java.io.*;
+import java.util.HashSet;
+import java.util.Set;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
@@ -29,6 +24,7 @@
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
+import org.reflections.Reflections;
public final class ConfigIO {
@@ -37,15 +33,20 @@ public final class ConfigIO {
static synchronized JAXBContext getJAXBContext() throws JAXBException {
if (context == null) {
- context = JAXBContext.newInstance(Config.class);
+ Set> classes = new HashSet<>();
+ classes.add(Config.class);
+ // Add all VariableModification classes because they aren't strongly typed
+ Reflections reflections = new Reflections("de.rub.nds");
+ classes.addAll(reflections.getSubTypesOf(VariableModification.class));
+ context = JAXBContext.newInstance(classes.toArray(new Class>[0]));
}
return context;
}
public static void write(Config config, File file) {
- try {
- write(config, new FileOutputStream(file));
- } catch (FileNotFoundException ex) {
+ try (FileOutputStream fos = new FileOutputStream(file)) {
+ write(config, fos);
+ } catch (IOException ex) {
throw new RuntimeException(ex);
}
}
@@ -89,10 +90,12 @@ public static Config read(File file) {
// Raise an exception also on warnings
return false;
});
- return read(new FileInputStream(file), unmarshaller);
+ try (FileInputStream fis = new FileInputStream(file)) {
+ return read(fis, unmarshaller);
+ }
} catch (JAXBException e) {
throw new RuntimeException(e);
- } catch (FileNotFoundException e) {
+ } catch (IOException e) {
throw new IllegalArgumentException("File cannot be found", e);
}
}
diff --git a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/config/PubKeyUtil.java b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/config/PubKeyUtil.java
index 5717be18f..ba72ea0a3 100644
--- a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/config/PubKeyUtil.java
+++ b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/config/PubKeyUtil.java
@@ -9,11 +9,7 @@
import de.rub.nds.sshattacker.core.constants.NamedEcGroup;
import de.rub.nds.sshattacker.core.constants.PublicKeyFormat;
-import de.rub.nds.sshattacker.core.crypto.keys.CustomRsaPrivateKey;
-import de.rub.nds.sshattacker.core.crypto.keys.CustomRsaPublicKey;
-import de.rub.nds.sshattacker.core.crypto.keys.SshPublicKey;
-import de.rub.nds.sshattacker.core.crypto.keys.XCurveEcPrivateKey;
-import de.rub.nds.sshattacker.core.crypto.keys.XCurveEcPublicKey;
+import de.rub.nds.sshattacker.core.crypto.keys.*;
import java.io.IOException;
import java.io.Reader;
import java.nio.file.Files;
diff --git a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/config/SshDelegateConfig.java b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/config/SshDelegateConfig.java
index 4b3838f11..d66a16e6e 100755
--- a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/config/SshDelegateConfig.java
+++ b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/config/SshDelegateConfig.java
@@ -25,7 +25,7 @@ public class SshDelegateConfig {
@SuppressWarnings("unused")
@Parameter(
- names = "-config",
+ names = {"-c", "--config"},
description = "This parameter allows you to specify a default SshConfig")
private String defaultConfig;
diff --git a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/config/converter/LogLevelConverter.java b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/config/converter/LogLevelConverter.java
index 9836eb75b..be19baea5 100755
--- a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/config/converter/LogLevelConverter.java
+++ b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/config/converter/LogLevelConverter.java
@@ -16,12 +16,12 @@
public class LogLevelConverter implements IStringConverter {
@Override
- public Level convert(String s) {
- Level level = Level.toLevel(s);
+ public Level convert(String value) {
+ Level level = Level.toLevel(value, null);
if (level == null) {
throw new ParameterException(
"Value "
- + s
+ + value
+ " cannot be converted to a log4j level. "
+ "Available values are: "
+ Arrays.toString(Level.values()));
diff --git a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/config/converter/RunningModeConverter.java b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/config/converter/RunningModeConverter.java
index cecb89bf6..2ec54fdf6 100755
--- a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/config/converter/RunningModeConverter.java
+++ b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/config/converter/RunningModeConverter.java
@@ -16,14 +16,14 @@
public class RunningModeConverter implements IStringConverter {
@Override
- public RunningModeType convert(String s) {
+ public RunningModeType convert(String value) {
try {
- return RunningModeType.valueOf(s);
+ return RunningModeType.valueOf(value);
} catch (IllegalArgumentException e) {
throw new ParameterException(
"Value "
- + s
+ + value
+ " cannot be converted to a RunningModeType. "
+ "Available values are: "
+ Arrays.toString(RunningModeType.values()));
diff --git a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/config/converter/WorkflowTraceTypeConverter.java b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/config/converter/WorkflowTraceTypeConverter.java
index 36ab598ba..9e8b241cf 100755
--- a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/config/converter/WorkflowTraceTypeConverter.java
+++ b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/config/converter/WorkflowTraceTypeConverter.java
@@ -14,9 +14,9 @@
public class WorkflowTraceTypeConverter implements IStringConverter {
@Override
- public WorkflowTraceType convert(String s) {
+ public WorkflowTraceType convert(String value) {
try {
- return WorkflowTraceType.valueOf(s);
+ return WorkflowTraceType.valueOf(value);
} catch (IllegalArgumentException e) {
throw new ParameterException("Could not parse WorkflowTraceType.");
}
diff --git a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/config/delegate/ClientDelegate.java b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/config/delegate/ClientDelegate.java
index 17dd05124..d7794cf18 100755
--- a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/config/delegate/ClientDelegate.java
+++ b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/config/delegate/ClientDelegate.java
@@ -21,7 +21,7 @@ public class ClientDelegate extends Delegate {
private static final int DEFAULT_SSH_PORT = 22;
@Parameter(
- names = "-connect",
+ names = {"-to", "--connect"},
required = true,
description = "Who to connect to. Syntax: localhost:22")
private String host;
diff --git a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/config/delegate/ConfigOutputDelegate.java b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/config/delegate/ConfigOutputDelegate.java
index 395fc3677..445e99ee6 100755
--- a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/config/delegate/ConfigOutputDelegate.java
+++ b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/config/delegate/ConfigOutputDelegate.java
@@ -13,7 +13,7 @@
public class ConfigOutputDelegate extends Delegate {
@Parameter(
- names = "-config_output",
+ names = "--config-output",
description =
"Write XML representation "
+ "of the actual config used during execution to this file")
diff --git a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/config/delegate/GeneralDelegate.java b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/config/delegate/GeneralDelegate.java
index 825a62654..b6115ddf5 100755
--- a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/config/delegate/GeneralDelegate.java
+++ b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/config/delegate/GeneralDelegate.java
@@ -9,6 +9,7 @@
import com.beust.jcommander.Parameter;
import de.rub.nds.sshattacker.core.config.Config;
+import de.rub.nds.sshattacker.core.config.converter.LogLevelConverter;
import java.security.Provider;
import java.security.Security;
import org.apache.logging.log4j.Level;
@@ -23,17 +24,23 @@ public class GeneralDelegate extends Delegate {
private static final Logger LOGGER = LogManager.getLogger();
@Parameter(
- names = {"-h", "-help"},
+ names = {"-h", "--help"},
help = true,
description = "Prints usage for all the existing commands.")
private boolean help;
- @Parameter(names = "-debug", description = "Show extra debug output (sets logLevel to DEBUG)")
+ @Parameter(names = "--debug", description = "Show extra debug output (sets logLevel to DEBUG)")
private boolean debug;
- @Parameter(names = "-quiet", description = "No output (sets logLevel to NONE)")
+ @Parameter(names = "-quiet", description = "No output (sets logLevel to OFF)")
private boolean quiet;
+ @Parameter(
+ names = {"-ll", "--log-level"},
+ description = "Sets explicit log level.",
+ converter = LogLevelConverter.class)
+ private Level loglevel;
+
public boolean isHelp() {
return help;
}
@@ -58,6 +65,14 @@ public void setQuiet(boolean quiet) {
this.quiet = quiet;
}
+ public Level getLogLevel() {
+ return loglevel;
+ }
+
+ public void setLogLevel(Level loglevel) {
+ this.loglevel = loglevel;
+ }
+
@Override
public void applyDelegate(Config config) {
Security.addProvider(new BouncyCastleProvider());
@@ -67,6 +82,9 @@ public void applyDelegate(Config config) {
} else if (quiet) {
Configurator.setAllLevels("de.rub.nds.sshattacker", Level.OFF);
}
+ if (loglevel != null) {
+ Configurator.setAllLevels("de.rub.nds.sshattacker", loglevel);
+ }
LOGGER.debug("Using the following security providers");
for (Provider p : Security.getProviders()) {
LOGGER.debug("Provider {}, version, {}", p.getName(), p.getVersionStr());
diff --git a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/config/delegate/MitmDelegate.java b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/config/delegate/MitmDelegate.java
index d418b57b5..71da4cf46 100644
--- a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/config/delegate/MitmDelegate.java
+++ b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/config/delegate/MitmDelegate.java
@@ -26,14 +26,14 @@ public class MitmDelegate extends Delegate {
private static final Logger LOGGER = LogManager.getLogger();
@Parameter(
- names = "-accept",
+ names = {"-p", "--accept"},
description =
"A MiTM client can connect to this connection end."
+ " Allowed syntax: or :")
protected String inboundConnectionStr;
@Parameter(
- names = "-connect",
+ names = {"-to", "--connect"},
description =
"Add a server to which the MiTM will connect to."
+ " Allowed syntax: : or ::")
diff --git a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/config/delegate/RunningModeDelegate.java b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/config/delegate/RunningModeDelegate.java
index 711d1865d..77cdefbb5 100755
--- a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/config/delegate/RunningModeDelegate.java
+++ b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/config/delegate/RunningModeDelegate.java
@@ -15,7 +15,7 @@
public class RunningModeDelegate extends Delegate {
@Parameter(
- names = "-running_mode",
+ names = "--running-mode",
description = "The mode for which the workflow trace should be prepared",
converter = RunningModeConverter.class)
private RunningModeType runningMode = RunningModeType.CLIENT;
diff --git a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/config/delegate/ServerDelegate.java b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/config/delegate/ServerDelegate.java
index d4096fcdd..8c95cf868 100755
--- a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/config/delegate/ServerDelegate.java
+++ b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/config/delegate/ServerDelegate.java
@@ -15,7 +15,10 @@
public class ServerDelegate extends Delegate {
- @Parameter(names = "-port", required = true, description = "ServerPort")
+ @Parameter(
+ names = {"-p", "-port"},
+ required = true,
+ description = "ServerPort")
protected Integer port;
public Integer getPort() {
diff --git a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/config/delegate/TimeoutDelegate.java b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/config/delegate/TimeoutDelegate.java
index 4f054cc6d..2f7528817 100755
--- a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/config/delegate/TimeoutDelegate.java
+++ b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/config/delegate/TimeoutDelegate.java
@@ -14,7 +14,9 @@
public class TimeoutDelegate extends Delegate {
- @Parameter(names = "-timeout", description = "Timeout for socket connection")
+ @Parameter(
+ names = {"-t", "--timeout"},
+ description = "Timeout for socket connection")
private Integer timeout;
public Integer getTimeout() {
diff --git a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/config/delegate/WorkflowInputDelegate.java b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/config/delegate/WorkflowInputDelegate.java
index c422b2e06..e8105428e 100755
--- a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/config/delegate/WorkflowInputDelegate.java
+++ b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/config/delegate/WorkflowInputDelegate.java
@@ -13,7 +13,7 @@
public class WorkflowInputDelegate extends Delegate {
@Parameter(
- names = "-workflow_input",
+ names = "--workflow-input",
description =
"This parameter allows you to load the whole workflow trace from the specified XML configuration file")
private String workflowInput;
diff --git a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/config/delegate/WorkflowOutputDelegate.java b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/config/delegate/WorkflowOutputDelegate.java
index 5a2184019..09e18d41e 100755
--- a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/config/delegate/WorkflowOutputDelegate.java
+++ b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/config/delegate/WorkflowOutputDelegate.java
@@ -13,7 +13,7 @@
public class WorkflowOutputDelegate extends Delegate {
@Parameter(
- names = "-workflow_output",
+ names = "--workflow-output",
description =
"This parameter allows you to serialize the whole workflow trace into a specific XML file")
private String workflowOutput;
diff --git a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/config/delegate/WorkflowTypeDelegate.java b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/config/delegate/WorkflowTypeDelegate.java
index ca061e65e..49f3eabf6 100755
--- a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/config/delegate/WorkflowTypeDelegate.java
+++ b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/config/delegate/WorkflowTypeDelegate.java
@@ -15,7 +15,7 @@
public class WorkflowTypeDelegate extends Delegate {
@Parameter(
- names = "-workflow_trace_type",
+ names = "--workflow-trace-type",
description = "Type of the workflow trace",
converter = WorkflowTraceTypeConverter.class)
private WorkflowTraceType workflowTraceType;
diff --git a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/connection/AliasedConnection.java b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/connection/AliasedConnection.java
index c2d4f1d52..aefd37fb8 100755
--- a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/connection/AliasedConnection.java
+++ b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/connection/AliasedConnection.java
@@ -79,6 +79,8 @@ protected AliasedConnection(AliasedConnection other) {
alias = other.alias;
}
+ public abstract AliasedConnection createCopy();
+
public String getAlias() {
return alias;
}
diff --git a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/connection/InboundConnection.java b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/connection/InboundConnection.java
index 328afea91..82b6e3a9f 100755
--- a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/connection/InboundConnection.java
+++ b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/connection/InboundConnection.java
@@ -41,6 +41,11 @@ public InboundConnection(InboundConnection other) {
super(other);
}
+ @Override
+ public InboundConnection createCopy() {
+ return new InboundConnection(this);
+ }
+
@Override
public ConnectionEndType getLocalConnectionEndType() {
return LOCAL_CONNECTION_END_TYPE;
diff --git a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/connection/OutboundConnection.java b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/connection/OutboundConnection.java
index f828e3634..44611796d 100755
--- a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/connection/OutboundConnection.java
+++ b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/connection/OutboundConnection.java
@@ -41,6 +41,11 @@ public OutboundConnection(OutboundConnection other) {
super(other);
}
+ @Override
+ public OutboundConnection createCopy() {
+ return new OutboundConnection(this);
+ }
+
@Override
public ConnectionEndType getLocalConnectionEndType() {
return LOCAL_CONNECTION_END_TYPE;
diff --git a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/constants/ChannelDataType.java b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/constants/ChannelDataType.java
new file mode 100755
index 000000000..3dd685ea3
--- /dev/null
+++ b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/constants/ChannelDataType.java
@@ -0,0 +1,51 @@
+/*
+ * SSH-Attacker - A Modular Penetration Testing Framework for SSH
+ *
+ * Copyright 2014-2022 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.constants;
+
+/** Represents data types that can occur when receiving SSH_MSG_CHANNEL_DATA */
+public enum ChannelDataType {
+
+ // Only valid in channels in which no channel request has been confirmed yet
+ /** Not requested data */
+ UNSET,
+
+ // Only valid in SESSION ChannelType
+ /** Pseudo-terminal (pty) data stream */
+ PTY,
+ /** Arbitrary std-out data stream of programs, executed with exec or a shell */
+ SHELL,
+ /** SFTP protocol data */
+ SUBSYSTEM_SFTP,
+ /** Unknown subsystem data */
+ SUBSYSTEM_UNKNOWN,
+
+ // Only valid in X11 ChannelType
+ /** X11 forwarding data stream */
+ X11,
+
+ // Only valid in FORWARDED_TCPIP and DIRECT_TCPIP ChannelType
+ /** TCP IP data stream */
+ TCP_IP,
+
+ // Only valid in TUN_OPENSSH_COM ChannelType
+ /** TCP IP data stream */
+ TUN,
+
+ // Only valid in DIRECT_STREAMLOCAL_OPENSSH_COM and FORWARDED_STREAMLOCAL_OPENSSH_COM
+ // ChannelType
+ /** Unix domain socket data stream */
+ UNIX_DOMAIN,
+
+ // Only valid in AUTH_AGENT_OPENSSH_COM ChannelType
+ /** SSH Agent Protocol data */
+ AUTH_AGENT,
+ // Only valid if more than one channel request that changes the expected data type were
+ // confirmed
+ /** Unknown data stream, because multiple types are possible */
+ UNKNOWN
+}
diff --git a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/constants/ChannelRequestType.java b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/constants/ChannelRequestType.java
index 0b5b6a47f..cf7405e1a 100755
--- a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/constants/ChannelRequestType.java
+++ b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/constants/ChannelRequestType.java
@@ -16,6 +16,8 @@ public enum ChannelRequestType {
* Sources:
* - https://www.iana.org/assignments/ssh-parameters/ssh-parameters.xhtml#ssh-parameters-13
* - https://cvsweb.openbsd.org/src/usr.bin/ssh/PROTOCOL?annotate=HEAD
+ * - https://www.ietf.org/archive/id/draft-miller-ssh-agent-11.html for auth-agent-req@openssh.com
+ * - http://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/usr.bin/ssh/PROTOCOL for eow@openssh.com
*/
// [ RFC 4254 ]
PTY_REQ("pty-req"),
diff --git a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/constants/ChannelType.java b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/constants/ChannelType.java
index 3f3eee8f2..bf9a9e239 100755
--- a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/constants/ChannelType.java
+++ b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/constants/ChannelType.java
@@ -16,6 +16,7 @@ public enum ChannelType {
* Sources:
* - https://www.iana.org/assignments/ssh-parameters/ssh-parameters.html#ssh-parameters-11
* - https://cvsweb.openbsd.org/src/usr.bin/ssh/PROTOCOL?annotate=HEAD
+ * - https://www.ietf.org/archive/id/draft-miller-ssh-agent-11.html for auth-agent-req@openssh.com
*/
// [ RFC 4254 ]
SESSION("session"),
@@ -26,7 +27,10 @@ public enum ChannelType {
// [ OpenSSH ]
TUN_OPENSSH_COM("tun@openssh.com"),
DIRECT_STREAMLOCAL_OPENSSH_COM("direct-streamlocal@openssh.com"),
- FORWARDED_STREAMLOCAL_OPENSSH_COM("forwarded-streamlocal@openssh.com");
+ FORWARDED_STREAMLOCAL_OPENSSH_COM("forwarded-streamlocal@openssh.com"),
+ AUTH_AGENT_OPENSSH_COM("auth-agent@openssh.com"),
+ // For internal ssh-attacker use
+ UNKNOWN(null);
private final String name;
@@ -35,7 +39,9 @@ public enum ChannelType {
static {
Map mutableMap = new TreeMap<>();
for (ChannelType channelType : values()) {
- mutableMap.put(channelType.name, channelType);
+ if (channelType.name != null) {
+ mutableMap.put(channelType.name, channelType);
+ }
}
map = Collections.unmodifiableMap(mutableMap);
}
@@ -54,6 +60,10 @@ public String getName() {
}
public static ChannelType fromName(String name) {
- return map.get(name);
+ ChannelType result = map.get(name);
+ if (result != null) {
+ return result;
+ }
+ return UNKNOWN;
}
}
diff --git a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/constants/CharConstants.java b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/constants/CharConstants.java
index fa1e298ed..dc857d1cd 100755
--- a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/constants/CharConstants.java
+++ b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/constants/CharConstants.java
@@ -11,7 +11,8 @@ public final class CharConstants {
public static final byte CARRIAGE_RETURN = 0x0d;
public static final byte NEWLINE = 0x0a;
public static final char VERSION_COMMENT_SEPARATOR = ' ';
- public static final char ALGORITHM_SEPARATOR = ',';
+ public static final String NAME_LIST_SEPARATOR = ",";
+ public static final char NAME_LIST_SEPARATOR_CHAR = ',';
private CharConstants() {
super();
diff --git a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/constants/DataPacketLayerType.java b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/constants/DataPacketLayerType.java
new file mode 100644
index 000000000..14e4ebd46
--- /dev/null
+++ b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/constants/DataPacketLayerType.java
@@ -0,0 +1,13 @@
+/*
+ * SSH-Attacker - A Modular Penetration Testing Framework for SSH
+ *
+ * Copyright 2014-2022 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.constants;
+
+public enum DataPacketLayerType {
+ DATA,
+ PASS_THROUGH
+}
diff --git a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/constants/Extension.java b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/constants/Extension.java
index 749c9a7ec..24d314a33 100644
--- a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/constants/Extension.java
+++ b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/constants/Extension.java
@@ -28,6 +28,8 @@ public enum Extension {
PUBLICKEY_ALGORITHMS_ROUMENPETROV("publickey-algorithms@roumenpetrov.info"),
UNKNOWN(null);
+ // TODO: SFTPv5 defines the extensions: supported, md5-hash and md5-hash-handle
+
private final String name;
private static final Map map;
@@ -55,8 +57,9 @@ public String getName() {
}
public static Extension fromName(String name) {
- if (map.containsKey(name)) {
- return map.get(name);
+ Extension result = map.get(name);
+ if (result != null) {
+ return result;
}
return UNKNOWN;
}
diff --git a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/constants/HashAlgorithm.java b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/constants/HashAlgorithm.java
new file mode 100644
index 000000000..fd292cc63
--- /dev/null
+++ b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/constants/HashAlgorithm.java
@@ -0,0 +1,60 @@
+/*
+ * SSH-Attacker - A Modular Penetration Testing Framework for SSH
+ *
+ * Copyright 2014-2022 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.constants;
+
+import java.util.Collections;
+import java.util.Map;
+import java.util.TreeMap;
+
+/** These values are also used for hash-algorithm-list of SFTP check-file messages */
+public enum HashAlgorithm {
+ /*
+ * Sources:
+ * - https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-extensions-00#section-3
+ * - https://datatracker.ietf.org/doc/html/rfc1321
+ */
+ // [ RFC 1321 ]
+ MD5("md5"),
+ // [ FIPS-180-2 ]
+ SHA_1("sha1"),
+ SHA_224("sha224"),
+ SHA_256("sha256"),
+ SHA_384("sha384"),
+ SHA_512("sha512"),
+ // [ ISO.3309.1991 ]
+ CRC32("crc32");
+
+ private final String name;
+
+ public static final Map map;
+
+ static {
+ Map mutableMap = new TreeMap<>();
+ for (HashAlgorithm algorithm : values()) {
+ mutableMap.put(algorithm.name, algorithm);
+ }
+ map = Collections.unmodifiableMap(mutableMap);
+ }
+
+ HashAlgorithm(String name) {
+ this.name = name;
+ }
+
+ @Override
+ public String toString() {
+ return name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public static HashAlgorithm fromName(String name) {
+ return map.get(name);
+ }
+}
diff --git a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/constants/KeyExchangeAlgorithm.java b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/constants/KeyExchangeAlgorithm.java
index 396bed86f..d129bfe8c 100755
--- a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/constants/KeyExchangeAlgorithm.java
+++ b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/constants/KeyExchangeAlgorithm.java
@@ -9,8 +9,6 @@
import java.util.Map;
import java.util.TreeMap;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
public enum KeyExchangeAlgorithm {
/*
@@ -180,8 +178,6 @@ public enum KeyExchangeAlgorithm {
HashFunction.SHA512),
UNKNOWN(null, null, null);
- private static final Logger LOGGER = LogManager.getLogger();
-
private final String name;
private final HashFunction hashFunction;
private final KeyExchangeFlowType flowType;
@@ -217,8 +213,9 @@ public KeyExchangeFlowType getFlowType() {
}
public static KeyExchangeAlgorithm fromName(String name) {
- if (map.containsKey(name)) {
- return map.get(name);
+ KeyExchangeAlgorithm result = map.get(name);
+ if (result != null) {
+ return result;
}
return UNKNOWN;
}
diff --git a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/constants/LanguageTag.java b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/constants/LanguageTag.java
new file mode 100755
index 000000000..4617edad5
--- /dev/null
+++ b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/constants/LanguageTag.java
@@ -0,0 +1,147 @@
+/*
+ * SSH-Attacker - A Modular Penetration Testing Framework for SSH
+ *
+ * Copyright 2014-2022 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.constants;
+
+import java.util.Collections;
+import java.util.Map;
+import java.util.TreeMap;
+
+public enum LanguageTag {
+ /*
+ * Sources:
+ * - https://www.iana.org/assignments/lang-tag-apps/lang-tag-apps.xhtml
+ * - https://www.rfc-editor.org/rfc/rfc3066
+ *
+ * rfc3066 was replaced by rfc4646. But the tags are still valid
+ *
+ *
LanguageTag are mostly not used by SSH servers, but they can.
+ */
+ // [ RFC 3066 ]
+ ART_LOJBAN("art-lojban"),
+ AZ_ARAB("az-Arab"),
+ AZ_CYRL("az-Cyrl"),
+ AZ_LATN("az-Latn"),
+ BE_LATN("be-Latn"),
+ BS_CYRL("bs-Cyrl"),
+ BS_LATN("bs-Latn"),
+ CEL_GAULISH("cel-gaulish"),
+ DE_1901("de-1901"),
+ DE_1996("de-1996"),
+ DE_AT_1901("de-AT-1901"),
+ DE_AT_1996("de-AT-1996"),
+ DE_CH_1901("de-CH-1901"),
+ DE_CH_1996("de-CH-1996"),
+ DE_DE_1901("de-DE-1901"),
+ DE_DE_1996("de-DE-1996"),
+ EN_BOONT("en-boont"),
+ EN_GB_OED("en-GB-oed"),
+ EN_SCOUSE("en-scouse"),
+ ES_419("es-419"),
+ I_AMI("i-ami"),
+ I_BNN("i-bnn"),
+ I_DEFAULT("i-default"),
+ I_ENOCHIAN("i-enochian"),
+ I_HAK("i-hak"),
+ I_KLINGON("i-klingon"),
+ I_LUX("i-lux"),
+ I_MINGO("i-mingo"),
+ I_NAVAJO("i-navajo"),
+ I_PWN("i-pwn"),
+ I_TAO("i-tao"),
+ I_TAY("i-tay"),
+ I_TSU("i-tsu"),
+ IU_CANS("iu-Cans"),
+ IU_LATN("iu-Latn"),
+ MN_CYRL("mn-Cyrl"),
+ MN_MONG("mn-Mong"),
+ NO_BOK("no-bok"),
+ NO_NYN("no-nyn"),
+ SGN_BE_FR("sgn-BE-fr"),
+ SGN_BE_NL("sgn-BE-nl"),
+ SGN_BR("sgn-BR"),
+ SGN_CH_DE("sgn-CH-de"),
+ SGN_CO("sgn-CO"),
+ SGN_DE("sgn-DE"),
+ SGN_DK("sgn-DK"),
+ SGN_ES("sgn-ES"),
+ SGN_FR("sgn-FR"),
+ SGN_GB("sgn-GB"),
+ SGN_GR("sgn-GR"),
+ SGN_IE("sgn-IE"),
+ SGN_IT("sgn-IT"),
+ SGN_JP("sgn-JP"),
+ SGN_MX("sgn-MX"),
+ SGN_NL("sgn-NL"),
+ SGN_NO("sgn-NO"),
+ SGN_PT("sgn-PT"),
+ SGN_SE("sgn-SE"),
+ SGN_US("sgn-US"),
+ SGN_ZA("sgn-ZA"),
+ SL_ROZAJ("sl-rozaj"),
+ SR_CYRL("sr-Cyrl"),
+ SR_LATN("sr-Latn"),
+ TG_ARAB("tg-Arab"),
+ TG_CYRL("tg-Cyrl"),
+ UZ_CYRL("uz-Cyrl"),
+ UZ_LATN("uz-Latn"),
+ YI_LATN("yi-latn"),
+ ZH_CMN("zh-cmn"),
+ ZH_CMN_HANS("zh-cmn-Hans"),
+ ZH_CMN_HANT("zh-cmn-Hant"),
+ ZH_GAN("zh-gan"),
+ ZH_GUOYU("zh-guoyu"),
+ ZH_HAKKA("zh-hakka"),
+ ZH_HANS("zh-Hans"),
+ ZH_HANS_CN("zh-Hans-CN"),
+ ZH_HANS_HK("zh-Hans-HK"),
+ ZH_HANS_MO("zh-Hans-MO"),
+ ZH_HANS_SG("zh-Hans-SG"),
+ ZH_HANS_TW("zh-Hans-TW"),
+ ZH_HANT("zh-Hant"),
+ ZH_HANT_CN("zh-Hant-CN"),
+ ZH_HANT_HK("zh-Hant-HK"),
+ ZH_HANT_MO("zh-Hant-MO"),
+ ZH_HANT_SG("zh-Hant-SG"),
+ ZH_HANT_TW("zh-Hant-TW"),
+ ZH_MIN("zh-min"),
+ ZH_MIN_NAN("zh-min-nan"),
+ ZH_WUU("zh-wuu"),
+ ZH_XIANG("zh-xiang"),
+ ZH_YUE("zh-yue");
+
+ private final String name;
+
+ public static final Map map;
+
+ static {
+ Map mutableMap = new TreeMap<>();
+ for (LanguageTag tag : values()) {
+ if (tag.name != null) {
+ mutableMap.put(tag.name, tag);
+ }
+ }
+ map = Collections.unmodifiableMap(mutableMap);
+ }
+
+ LanguageTag(String name) {
+ this.name = name;
+ }
+
+ @Override
+ public String toString() {
+ return name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public static LanguageTag fromName(String name) {
+ return map.get(name);
+ }
+}
diff --git a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/constants/NamedEcGroup.java b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/constants/NamedEcGroup.java
index 1a4a154d0..844a62396 100644
--- a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/constants/NamedEcGroup.java
+++ b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/constants/NamedEcGroup.java
@@ -41,9 +41,11 @@ public enum NamedEcGroup {
SECP224K1("1.3.132.0.32", "1.3.132.0.32", "secp224k1", 224),
SECP224R1("1.3.132.0.33", "1.3.132.0.33", "secp224r1", 224),
SECP256K1("1.3.132.0.10", "1.3.132.0.10", "secp256k1", 256),
+ // Required Curves (RFC 5656, Section 10.1)
SECP256R1("nistp256", "1.2.840.10045.3.1.7", "secp256r1", 256),
SECP384R1("nistp384", "1.3.132.0.34", "secp384r1", 384),
SECP521R1("nistp521", "1.3.132.0.35", "secp521r1", 521),
+ // ---
BRAINPOOLP256R1("1.3.36.3.3.2.8.1.1.7", "1.3.36.3.3.2.8.1.1.7", "brainpoolp256r1", 256),
BRAINPOOLP384R1("1.3.36.3.3.2.8.1.1.11", "1.3.36.3.3.2.8.1.1.11", "brainpoolp384r1", 384),
BRAINPOOLP512R1("1.3.36.3.3.2.8.1.1.13", "1.3.36.3.3.2.8.1.1.13", "brainpoolp512r1", 512),
@@ -56,16 +58,24 @@ public enum NamedEcGroup {
private final int coordinateSizeInBit;
- public static final Map map;
+ public static final Map identifierMap;
+ public static final Map oidMap;
+ public static final Map javaNameMap;
static {
- Map mutableMap = new TreeMap<>();
+ Map mutableIdentifierMap = new TreeMap<>();
+ Map mutableOidMap = new TreeMap<>();
+ Map mutableJavaNameMap = new TreeMap<>();
for (NamedEcGroup group : values()) {
if (group.identifier != null) {
- mutableMap.put(group.identifier, group);
+ mutableIdentifierMap.put(group.identifier, group);
+ mutableOidMap.put(group.oid, group);
+ mutableJavaNameMap.put(group.javaName, group);
}
}
- map = Collections.unmodifiableMap(mutableMap);
+ identifierMap = Collections.unmodifiableMap(mutableIdentifierMap);
+ oidMap = Collections.unmodifiableMap(mutableOidMap);
+ javaNameMap = Collections.unmodifiableMap(mutableJavaNameMap);
}
NamedEcGroup(String identifier, String oid, String javaName, int coordinateSizeInBit) {
@@ -76,7 +86,15 @@ public enum NamedEcGroup {
}
public static NamedEcGroup fromIdentifier(String identifier) {
- return map.get(identifier);
+ return identifierMap.get(identifier);
+ }
+
+ public static NamedEcGroup fromOid(String oid) {
+ return oidMap.get(oid);
+ }
+
+ public static NamedEcGroup fromJavaName(String javaName) {
+ return javaNameMap.get(javaName);
}
public String getIdentifier() {
diff --git a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/constants/SftpAceFlag.java b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/constants/SftpAceFlag.java
new file mode 100644
index 000000000..507954156
--- /dev/null
+++ b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/constants/SftpAceFlag.java
@@ -0,0 +1,45 @@
+/*
+ * SSH-Attacker - A Modular Penetration Testing Framework for SSH
+ *
+ * Copyright 2014-2022 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.constants;
+
+public enum SftpAceFlag {
+ /*
+ * Sources:
+ * - https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-03#section-5.7
+ */
+ // [ From version 4 onwards ]
+ ACE4_FILE_INHERIT_ACE(0x00000001),
+ ACE4_DIRECTORY_INHERIT_ACE(0x00000002),
+ ACE4_NO_PROPAGATE_INHERIT_ACE(0x00000004),
+ ACE4_INHERIT_ONLY_ACE(0x00000008),
+ ACE4_SUCCESSFUL_ACCESS_ACE_FLAG(0x00000010),
+ ACE4_FAILED_ACCESS_ACE_FLAG(0x00000020),
+ ACE4_IDENTIFIER_GROUP(0x00000040);
+
+ private final int value;
+
+ SftpAceFlag(int value) {
+ this.value = value;
+ }
+
+ public int getValue() {
+ return value;
+ }
+
+ public static boolean isFlagSet(int flags, SftpAceFlag aceFlag) {
+ return (flags & aceFlag.value) != 0;
+ }
+
+ public static int flagsToInt(SftpAceFlag... aceFlags) {
+ int result = 0;
+ for (SftpAceFlag aceFlag : aceFlags) {
+ result |= aceFlag.value;
+ }
+ return result;
+ }
+}
diff --git a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/constants/SftpAceMask.java b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/constants/SftpAceMask.java
new file mode 100644
index 000000000..b62b2adcb
--- /dev/null
+++ b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/constants/SftpAceMask.java
@@ -0,0 +1,55 @@
+/*
+ * SSH-Attacker - A Modular Penetration Testing Framework for SSH
+ *
+ * Copyright 2014-2022 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.constants;
+
+public enum SftpAceMask {
+ /*
+ * Sources:
+ * - https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-03#section-5.7
+ */
+ // [ From version 4 onwards ]
+ ACE4_READ_DATA(0x00000001),
+ ACE4_LIST_DIRECTORY(0x00000001),
+ ACE4_WRITE_DATA(0x00000002),
+ ACE4_ADD_FILE(0x00000002),
+ ACE4_APPEND_DATA(0x00000004),
+ ACE4_ADD_SUBDIRECTORY(0x00000004),
+ ACE4_READ_NAMED_ATTRS(0x00000008),
+ ACE4_WRITE_NAMED_ATTRS(0x00000010),
+ ACE4_EXECUTE(0x00000020),
+ ACE4_DELETE_CHILD(0x00000040),
+ ACE4_READ_ATTRIBUTES(0x00000080),
+ ACE4_WRITE_ATTRIBUTES(0x00000100),
+ ACE4_DELETE(0x00010000),
+ ACE4_READ_ACL(0x00020000),
+ ACE4_WRITE_ACL(0x00040000),
+ ACE4_WRITE_OWNER(0x00080000),
+ ACE4_SYNCHRONIZE(0x00100000);
+
+ private final int value;
+
+ SftpAceMask(int value) {
+ this.value = value;
+ }
+
+ public int getValue() {
+ return value;
+ }
+
+ public static boolean isFlagSet(int flags, SftpAceMask flag) {
+ return (flags & flag.value) != 0;
+ }
+
+ public static int flagsToInt(SftpAceMask... flags) {
+ int result = 0;
+ for (SftpAceMask flag : flags) {
+ result |= flag.value;
+ }
+ return result;
+ }
+}
diff --git a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/constants/SftpAceSpecialIdentifiers.java b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/constants/SftpAceSpecialIdentifiers.java
new file mode 100755
index 000000000..fd3d817fb
--- /dev/null
+++ b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/constants/SftpAceSpecialIdentifiers.java
@@ -0,0 +1,59 @@
+/*
+ * SSH-Attacker - A Modular Penetration Testing Framework for SSH
+ *
+ * Copyright 2014-2022 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.constants;
+
+import java.util.Collections;
+import java.util.Map;
+import java.util.TreeMap;
+
+public enum SftpAceSpecialIdentifiers {
+ /*
+ * Sources:
+ * - https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-04#section-5.7
+ */
+ // [ From version 4 onwards ]
+ OWNER("OWNER@"),
+ GROUP("GROUP@"),
+ EVERYONE("EVERYONE@"),
+ INTERACTIVE("INTERACTIVE@"),
+ NETWORK("NETWORK@"),
+ DIALUP("DIALUP@"),
+ BATCH("BATCH@"),
+ ANONYMOUS("ANONYMOUS@"),
+ AUTHENTICATED("AUTHENTICATED@"),
+ SERVICE("SERVICE@");
+
+ private final String name;
+
+ SftpAceSpecialIdentifiers(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public static final Map map;
+
+ static {
+ Map mutableMap = new TreeMap<>();
+ for (SftpAceSpecialIdentifiers constant : values()) {
+ mutableMap.put(constant.name, constant);
+ }
+ map = Collections.unmodifiableMap(mutableMap);
+ }
+
+ public static SftpAceSpecialIdentifiers fromName(String who) {
+ return map.get(who);
+ }
+
+ @Override
+ public String toString() {
+ return name;
+ }
+}
diff --git a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/constants/SftpAceType.java b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/constants/SftpAceType.java
new file mode 100755
index 000000000..be0ed0c41
--- /dev/null
+++ b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/constants/SftpAceType.java
@@ -0,0 +1,56 @@
+/*
+ * SSH-Attacker - A Modular Penetration Testing Framework for SSH
+ *
+ * Copyright 2014-2022 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.constants;
+
+import java.util.Collections;
+import java.util.Map;
+import java.util.TreeMap;
+
+public enum SftpAceType {
+ /*
+ * Sources:
+ * - https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-03#section-5.7
+ */
+ // [ From version 4 onwards ]
+ ACE4_ACCESS_ALLOWED_ACE_TYPE(0),
+ ACE4_ACCESS_DENIED_ACE_TYPE(1),
+ ACE4_SYSTEM_AUDIT_ACE_TYPE(2),
+ ACE4_SYSTEM_ALARM_ACE_TYPE(3);
+
+ private final int type;
+
+ SftpAceType(int type) {
+ this.type = type;
+ }
+
+ public int getType() {
+ return type;
+ }
+
+ public static final Map map;
+
+ static {
+ Map mutableMap = new TreeMap<>();
+ for (SftpAceType constant : values()) {
+ mutableMap.put(constant.type, constant);
+ }
+ map = Collections.unmodifiableMap(mutableMap);
+ }
+
+ public static String getNameByType(int type) {
+ if (map.containsKey(type)) {
+ return map.get(type).toString();
+ } else {
+ return String.format("%d", type);
+ }
+ }
+
+ public static SftpAceType fromType(int type) {
+ return map.get(type);
+ }
+}
diff --git a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/constants/SftpExtension.java b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/constants/SftpExtension.java
new file mode 100644
index 000000000..215871b97
--- /dev/null
+++ b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/constants/SftpExtension.java
@@ -0,0 +1,99 @@
+/*
+ * SSH-Attacker - A Modular Penetration Testing Framework for SSH
+ *
+ * Copyright 2014-2022 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.constants;
+
+import java.util.Map;
+import java.util.TreeMap;
+
+public enum SftpExtension {
+ /*
+ * Sources:
+ * - https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-extensions-00
+ * - 2. vendor-id
+ * - 3. check-file
+ * - 4. space-available
+ * - 5. home-directory
+ * - 6. copy-file
+ * - 7. copy-data
+ * - http://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/usr.bin/ssh/PROTOCOL
+ * - 4.3. posix-rename@openssh.com
+ * - 4.4. statvfs@openssh.com
+ * - 4.5. hardlink@openssh.com
+ * - 4.6. fsync@openssh.com
+ * - 4.7. lsetstat@openssh.com
+ * - 4.8. limits@openssh.com
+ * - 4.9. expand-path@openssh.com
+ * - 4.10. expand-path@openssh.com
+ * - 4.12. users-groups-by-id@openssh.com
+ * - SFTP v4: https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-03
+ * - 4.3. new-line
+ * - 6.3. text-seek
+ */
+ // SFTP
+ VENDOR_ID("vendor-id"),
+ CHECK_FILE("check-file"),
+ CHECK_FILE_HANDLE(
+ "check-file-handle"), // only as request name - available if check-file was announced
+ CHECK_FILE_NAME(
+ "check-file-name"), // only as request name - available if check-file was announced
+ SPACE_AVAILABLE("space-available"),
+ HOME_DIRECTORY("home-directory"),
+ COPY_FILE("copy-file"),
+ COPY_DATA("copy-data"),
+ GET_TEMP_FOLDER("get-temp-folder"),
+ MAKE_TEMP_FOLDER("make-temp-folder"),
+ // SFTP v4
+ TEXT_SEEK("text-seek"),
+ NEWLINE("newline"),
+ // Vendor extensions
+ POSIX_RENAME_OPENSSH_COM("posix-rename@openssh.com"),
+ STAT_VFS_OPENSSH_COM("statvfs@openssh.com"),
+ F_STAT_VFS_OPENSSH_COM("fstatvfs@openssh.com"),
+ HARDLINK_OPENSSH_COM("hardlink@openssh.com"),
+ F_SYNC_OPENSSH_COM("fsync@openssh.com"),
+ L_SET_STAT_OPENSSH_COM("lsetstat@openssh.com"),
+ LIMITS_OPENSSH_COM("limits@openssh.com"),
+ EXPAND_PATH_OPENSSH_COM("expand-path@openssh.com"),
+ USERS_GROUPS_BY_ID_OPENSSH_COM("users-groups-by-id@openssh.com"),
+
+ UNKNOWN(null);
+
+ private final String name;
+
+ private static final Map map;
+
+ static {
+ map = new TreeMap<>();
+ for (SftpExtension extension : values()) {
+ if (extension.name != null) {
+ map.put(extension.name, extension);
+ }
+ }
+ }
+
+ SftpExtension(String name) {
+ this.name = name;
+ }
+
+ @Override
+ public String toString() {
+ return name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public static SftpExtension fromName(String name) {
+ SftpExtension result = map.get(name);
+ if (result != null) {
+ return result;
+ }
+ return UNKNOWN;
+ }
+}
diff --git a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/constants/SftpFileAttributeBits.java b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/constants/SftpFileAttributeBits.java
new file mode 100644
index 000000000..691cf1c9b
--- /dev/null
+++ b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/constants/SftpFileAttributeBits.java
@@ -0,0 +1,49 @@
+/*
+ * SSH-Attacker - A Modular Penetration Testing Framework for SSH
+ *
+ * Copyright 2014-2022 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.constants;
+
+public enum SftpFileAttributeBits {
+ /*
+ * Sources:
+ * - https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-05#page-17
+ */
+ // [ From version 5 onwards ]
+ SSH_FILEXFER_ATTR_FLAGS_READONLY(0x00000001),
+ SSH_FILEXFER_ATTR_FLAGS_SYSTEM(0x00000002),
+ SSH_FILEXFER_ATTR_FLAGS_HIDDEN(0x00000004),
+ SSH_FILEXFER_ATTR_FLAGS_CASE_INSENSITIVE(0x00000008),
+ SSH_FILEXFER_ATTR_FLAGS_ARCHIVE(0x00000010),
+ SSH_FILEXFER_ATTR_FLAGS_ENCRYPTED(0x00000020),
+ SSH_FILEXFER_ATTR_FLAGS_COMPRESSED(0x00000040),
+ SSH_FILEXFER_ATTR_FLAGS_SPARSE(0x00000080),
+ SSH_FILEXFER_ATTR_FLAGS_APPEND_ONLY(0x00000100),
+ SSH_FILEXFER_ATTR_FLAGS_IMMUTABLE(0x00000200),
+ SSH_FILEXFER_ATTR_FLAGS_SYNC(0x00000400);
+
+ private final int value;
+
+ SftpFileAttributeBits(int value) {
+ this.value = value;
+ }
+
+ public int getValue() {
+ return value;
+ }
+
+ public static boolean isBitSet(int bits, SftpFileAttributeBits bit) {
+ return (bits & bit.value) != 0;
+ }
+
+ public static int bitsToInt(SftpFileAttributeBits... attributeBits) {
+ int result = 0;
+ for (SftpFileAttributeBits attributeBit : attributeBits) {
+ result |= attributeBit.value;
+ }
+ return result;
+ }
+}
diff --git a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/constants/SftpFileAttributeFlag.java b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/constants/SftpFileAttributeFlag.java
new file mode 100644
index 000000000..a23abd366
--- /dev/null
+++ b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/constants/SftpFileAttributeFlag.java
@@ -0,0 +1,55 @@
+/*
+ * SSH-Attacker - A Modular Penetration Testing Framework for SSH
+ *
+ * Copyright 2014-2022 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.constants;
+
+public enum SftpFileAttributeFlag {
+ /*
+ * Sources:
+ * - https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-02#page-9
+ * - https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-03#page-9
+ */
+ SSH_FILEXFER_ATTR_SIZE(0x00000001),
+ SSH_FILEXFER_ATTR_UIDGID(0x00000002), // No longer available since version 4
+ // In version 4 it is unclear if the SSH_FILEXFER_ATTR_PERMISSIONS flag
+ // should be used, but it is valid again in version 5
+ SSH_FILEXFER_ATTR_PERMISSIONS(0x00000004),
+ // Name of SSH_FILEXFER_ATTR_ACMODTIME changed to SSH_FILEXFER_ATTR_ACCESSTIME in version 4
+ SSH_FILEXFER_ATTR_ACMODTIME(0x00000008),
+ SSH_FILEXFER_ATTR_ACCESSTIME(0x00000008),
+ SSH_FILEXFER_ATTR_EXTENDED(0x80000000),
+ // [ From version 4 onwards ]
+ SSH_FILEXFER_ATTR_CREATETIME(0x00000010),
+ SSH_FILEXFER_ATTR_MODIFYTIME(0x00000020),
+ SSH_FILEXFER_ATTR_ACL(0x00000040),
+ SSH_FILEXFER_ATTR_OWNERGROUP(0x00000080),
+ SSH_FILEXFER_ATTR_SUBSECOND_TIMES(0x00000100),
+ // [ From version 5 onwards ]
+ SSH_FILEXFER_ATTR_BITS(0x00000200);
+
+ private final int value;
+
+ SftpFileAttributeFlag(int value) {
+ this.value = value;
+ }
+
+ public int getValue() {
+ return value;
+ }
+
+ public static boolean isFlagSet(int attributes, SftpFileAttributeFlag attribute) {
+ return (attributes & attribute.value) != 0;
+ }
+
+ public static int flagsToInt(SftpFileAttributeFlag... attributeFlags) {
+ int result = 0;
+ for (SftpFileAttributeFlag attributeFlag : attributeFlags) {
+ result |= attributeFlag.value; // Use bitwise OR to set each flag
+ }
+ return result;
+ }
+}
diff --git a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/constants/SftpFileOpenFlag.java b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/constants/SftpFileOpenFlag.java
new file mode 100644
index 000000000..c5e829616
--- /dev/null
+++ b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/constants/SftpFileOpenFlag.java
@@ -0,0 +1,49 @@
+/*
+ * SSH-Attacker - A Modular Penetration Testing Framework for SSH
+ *
+ * Copyright 2014-2022 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.constants;
+
+public enum SftpFileOpenFlag {
+ /*
+ * Sources:
+ * - https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-02#page-12
+ * - https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-03#page-15
+ */
+ // [ From version 3 onwards ]
+ SSH_FXF_READ(0x00000001),
+ SSH_FXF_WRITE(0x00000002),
+ SSH_FXF_APPEND(0x00000004),
+ SSH_FXF_CREAT(0x00000008),
+ SSH_FXF_TRUNC(0x00000010),
+ SSH_FXF_EXCL(0x00000020),
+ // [ From version 4 onwards ]
+ SSH_FXF_TEXT(0x00000040);
+
+ // TODO: SFTPv5 changed the flags completely
+
+ private final int value;
+
+ SftpFileOpenFlag(int value) {
+ this.value = value;
+ }
+
+ public int getValue() {
+ return value;
+ }
+
+ public static boolean isFlagSet(int attributes, SftpFileOpenFlag attribute) {
+ return (attributes & attribute.value) != 0;
+ }
+
+ public static int flagsToInt(SftpFileOpenFlag... fileOpenFlags) {
+ int result = 0;
+ for (SftpFileOpenFlag fileOpenFlag : fileOpenFlags) {
+ result |= fileOpenFlag.value; // Use bitwise OR to set each flag
+ }
+ return result;
+ }
+}
diff --git a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/constants/SftpFilePermission.java b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/constants/SftpFilePermission.java
new file mode 100755
index 000000000..312761354
--- /dev/null
+++ b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/constants/SftpFilePermission.java
@@ -0,0 +1,105 @@
+/*
+ * SSH-Attacker - A Modular Penetration Testing Framework for SSH
+ *
+ * Copyright 2014-2022 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.constants;
+
+import java.util.*;
+
+public enum SftpFilePermission {
+ /*
+ * Sources:
+ * - https://chromium.googlesource.com/native_client/nacl-newlib/+/a9ae3c60b36dea3d8a10e18b1b6db952d21268c2/newlib/libc/include/sys/stat.h#80
+ */
+ // is a directory
+ IS_DIR(0040000),
+ // is a character special file / character device
+ IS_CHAR(0020000),
+ // is block special
+ IS_BLOCK(0060000),
+ // is regular file
+ IS_REGULAR(0100000),
+ // is symbolic link
+ IS_LINK(0120000),
+ // is socket
+ IS_SOCKET(0140000),
+ // is fifo
+ IS_FIFO(0010000),
+ // set user id on execution
+ SET_USER_ID(04000),
+ // set group id on execution
+ SET_GROUP_ID(02000),
+ // save swapped text even after use or prevents users from deleting others' files in a directory
+ STICKY_BIT(01000),
+ // read permission, owner
+ USER_READ(0400),
+ // write permission, owner
+ USER_WRITE(0200),
+ // execute/search permission, owner
+ USER_EXEC(0100),
+ // read permission, group
+ GROUP_READ(0040),
+ // write permission, group
+ GROUP_WRITE(0020),
+ // execute/search permission, group
+ GROUP_EXEC(0010),
+ // read permission, other
+ OTHER_READ(0004),
+ // write permission, other
+ OTHER_WRITE(0002),
+ // execute/search permission, other
+ OTHER_EXECUTE(0001);
+
+ private final int value;
+
+ SftpFilePermission(int value) {
+ this.value = value;
+ }
+
+ public int getValue() {
+ return value;
+ }
+
+ public static final Map map;
+
+ static {
+ Map mutableMap = new TreeMap<>();
+ for (SftpFilePermission constant : values()) {
+ mutableMap.put(constant.value, constant);
+ }
+ map = Collections.unmodifiableMap(mutableMap);
+ }
+
+ public static String getNameByValue(int value) {
+ if (map.containsKey(value)) {
+ return map.get(value).toString();
+ } else {
+ return String.format("%d", value);
+ }
+ }
+
+ public static Set fromValue(int value) {
+ Set permissions = EnumSet.noneOf(SftpFilePermission.class);
+ for (SftpFilePermission permission : values()) {
+ if ((value & permission.value) != 0) {
+ permissions.add(permission);
+ }
+ }
+ return permissions;
+ }
+
+ public static boolean isPermissionSet(SftpFilePermission permission, int value) {
+ return (value & permission.value) != 0;
+ }
+
+ public static int permissionsToInt(SftpFilePermission... permissions) {
+ int result = 0;
+ for (SftpFilePermission permission : permissions) {
+ result |= permission.value;
+ }
+ return result;
+ }
+}
diff --git a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/constants/SftpFileType.java b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/constants/SftpFileType.java
new file mode 100755
index 000000000..021a69a4e
--- /dev/null
+++ b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/constants/SftpFileType.java
@@ -0,0 +1,62 @@
+/*
+ * SSH-Attacker - A Modular Penetration Testing Framework for SSH
+ *
+ * Copyright 2014-2022 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.constants;
+
+import java.util.Collections;
+import java.util.Map;
+import java.util.TreeMap;
+
+public enum SftpFileType {
+ /*
+ * Sources:
+ * - https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-03#section-5.2
+ */
+ // [ From version 4 onwards ]
+ SSH_FILEXFER_TYPE_REGULAR((byte) 1),
+ SSH_FILEXFER_TYPE_DIRECTORY((byte) 2),
+ SSH_FILEXFER_TYPE_SYMLINK((byte) 3),
+ SSH_FILEXFER_TYPE_SPECIAL((byte) 4),
+ SSH_FILEXFER_TYPE_UNKNOWN((byte) 5),
+ // [ From version 5 onwards ]
+ SSH_FILEXFER_TYPE_SOCKET((byte) 6),
+ SSH_FILEXFER_TYPE_CHAR_DEVICE((byte) 7),
+ SSH_FILEXFER_TYPE_BLOCK_DEVICE((byte) 8),
+ SSH_FILEXFER_TYSSH_FILEXFER_TYPE_FIFOPE_UNKNOWN((byte) 9);
+
+ private final byte type;
+
+ SftpFileType(byte type) {
+ this.type = type;
+ }
+
+ public byte getType() {
+ return type;
+ }
+
+ public static final Map map;
+
+ static {
+ Map mutableMap = new TreeMap<>();
+ for (SftpFileType constant : values()) {
+ mutableMap.put(constant.type, constant);
+ }
+ map = Collections.unmodifiableMap(mutableMap);
+ }
+
+ public static String getNameByType(byte type) {
+ if (map.containsKey(type)) {
+ return map.get(type).toString();
+ } else {
+ return String.format("%d", type);
+ }
+ }
+
+ public static SftpFileType fromType(byte type) {
+ return map.get(type);
+ }
+}
diff --git a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/constants/SftpPacketTypeConstant.java b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/constants/SftpPacketTypeConstant.java
new file mode 100755
index 000000000..a21c29ca2
--- /dev/null
+++ b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/constants/SftpPacketTypeConstant.java
@@ -0,0 +1,94 @@
+/*
+ * SSH-Attacker - A Modular Penetration Testing Framework for SSH
+ *
+ * Copyright 2014-2022 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.constants;
+
+import java.util.Collections;
+import java.util.Map;
+import java.util.TreeMap;
+
+public enum SftpPacketTypeConstant {
+ /*
+ * Sources:
+ * - https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-02
+ */
+ // 1 - 2 protocol initialization
+ SSH_FXP_INIT((byte) 1),
+ SSH_FXP_VERSION((byte) 2),
+ // 2 - 20 requests from the client to the server
+ SSH_FXP_OPEN((byte) 3),
+ SSH_FXP_CLOSE((byte) 4),
+ SSH_FXP_READ((byte) 5),
+ SSH_FXP_WRITE((byte) 6),
+ SSH_FXP_LSTAT((byte) 7),
+ SSH_FXP_FSTAT((byte) 8),
+ SSH_FXP_SETSTAT((byte) 9),
+ SSH_FXP_FSETSTAT((byte) 10),
+ SSH_FXP_OPENDIR((byte) 11),
+ SSH_FXP_READDIR((byte) 12),
+ SSH_FXP_REMOVE((byte) 13),
+ SSH_FXP_MKDIR((byte) 14),
+ SSH_FXP_RMDIR((byte) 15),
+ SSH_FXP_REALPATH((byte) 16),
+ SSH_FXP_STAT((byte) 17),
+ SSH_FXP_RENAME((byte) 18), // First added in version 2
+ SSH_FXP_READLINK((byte) 19), // First added in version 3
+ SSH_FXP_SYMLINK((byte) 20), // First added in version 3
+ // 100 - 105 responses from the server to the client
+ SSH_FXP_STATUS((byte) 101),
+ SSH_FXP_HANDLE((byte) 102),
+ SSH_FXP_DATA((byte) 103),
+ SSH_FXP_NAME((byte) 104),
+ SSH_FXP_ATTRS((byte) 105),
+ // 200 - 201 vendor specific extensions
+ SSH_FXP_EXTENDED((byte) 200), // First added in version 3
+ SSH_FXP_EXTENDED_REPLY((byte) 201), // First added in version 3
+ // [ Only version 6 ]
+ SSH_FXP_LINK((byte) 21),
+ SSH_FXP_BLOCK((byte) 22),
+ SSH_FXP_UNBLOCK((byte) 23),
+ // Unknown
+ UNKNOWN(null);
+
+ private final Byte id;
+ public static final Map map;
+
+ static {
+ Map mutableMap = new TreeMap<>();
+ for (SftpPacketTypeConstant constant : values()) {
+ if (constant.id != null) {
+ mutableMap.put(constant.id, constant);
+ }
+ }
+ map = Collections.unmodifiableMap(mutableMap);
+ }
+
+ SftpPacketTypeConstant(Byte id) {
+ this.id = id;
+ }
+
+ public Byte getId() {
+ return id;
+ }
+
+ public static String getNameById(byte id) {
+ SftpPacketTypeConstant constant = map.get(id);
+ if (constant != null) {
+ return constant.toString();
+ } else {
+ return String.format("0x%02X", id);
+ }
+ }
+
+ public static SftpPacketTypeConstant fromId(byte id) {
+ SftpPacketTypeConstant result = map.get(id);
+ if (result != null) {
+ return result;
+ }
+ return UNKNOWN;
+ }
+}
diff --git a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/constants/SftpStatusCode.java b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/constants/SftpStatusCode.java
new file mode 100755
index 000000000..3fda9aa7f
--- /dev/null
+++ b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/constants/SftpStatusCode.java
@@ -0,0 +1,72 @@
+/*
+ * SSH-Attacker - A Modular Penetration Testing Framework for SSH
+ *
+ * Copyright 2014-2022 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.constants;
+
+import java.util.Collections;
+import java.util.Map;
+import java.util.TreeMap;
+
+public enum SftpStatusCode {
+ /*
+ * Sources:
+ * - https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-02#page-21
+ */
+ // [ From version 3 onwards ]
+ SSH_FX_OK(0),
+ SSH_FX_EOF(1),
+ SSH_FX_NO_SUCH_FILE(2),
+ SSH_FX_PERMISSION_DENIED(3),
+ SSH_FX_FAILURE(4),
+ SSH_FX_BAD_MESSAGE(5),
+ SSH_FX_NO_CONNECTION(6),
+ SSH_FX_CONNECTION_LOST(7),
+ SSH_FX_OP_UNSUPPORTED(8),
+ // [ From version 4 onwards ]
+ SSH_FX_INVALID_HANDLE(9),
+ SSH_FX_NO_SUCH_PATH(10),
+ SSH_FX_FILE_ALREADY_EXISTS(11),
+ SSH_FX_WRITE_PROTECT(12),
+ SSH_FX_NO_MEDIA(13),
+ // [ From version 5 onwards ]
+ SSH_FX_NO_SPACE_ON_FILESYSTEM(14),
+ SSH_FX_QUOTA_EXCEEDED(15),
+ SSH_FX_UNKNOWN_PRINCIPLE(16),
+ SSH_FX_LOCK_CONFlICT(17);
+
+ private final int code;
+
+ SftpStatusCode(int code) {
+ this.code = code;
+ }
+
+ public int getCode() {
+ return code;
+ }
+
+ public static final Map map;
+
+ static {
+ Map mutableMap = new TreeMap<>();
+ for (SftpStatusCode constant : values()) {
+ mutableMap.put(constant.code, constant);
+ }
+ map = Collections.unmodifiableMap(mutableMap);
+ }
+
+ public static String getNameByCode(int code) {
+ if (map.containsKey(code)) {
+ return map.get(code).toString();
+ } else {
+ return String.format("%d", code);
+ }
+ }
+
+ public static SftpStatusCode fromCode(int code) {
+ return map.get(code);
+ }
+}
diff --git a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/constants/SftpVfsFlag.java b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/constants/SftpVfsFlag.java
new file mode 100644
index 000000000..bb194c4f2
--- /dev/null
+++ b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/constants/SftpVfsFlag.java
@@ -0,0 +1,35 @@
+/*
+ * SSH-Attacker - A Modular Penetration Testing Framework for SSH
+ *
+ * Copyright 2014-2022 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.constants;
+
+public enum SftpVfsFlag {
+ SSH_FXE_STATVFS_ST_RDONLY(0x0000000000000001),
+ SSH_FXE_STATVFS_ST_NOSUID(0x0000000000000002);
+
+ private final long value;
+
+ SftpVfsFlag(long value) {
+ this.value = value;
+ }
+
+ public long getValue() {
+ return value;
+ }
+
+ public static boolean isFlagSet(long flags, SftpVfsFlag flag) {
+ return (flags & flag.value) != 0;
+ }
+
+ public static long flagsToLong(SftpVfsFlag... vfsFlags) {
+ long result = 0;
+ for (SftpVfsFlag vfsFlag : vfsFlags) {
+ result |= vfsFlag.value;
+ }
+ return result;
+ }
+}
diff --git a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/cipher/OaepCipher.java b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/cipher/OaepCipher.java
index c9195f98f..ebdfd3e5c 100644
--- a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/cipher/OaepCipher.java
+++ b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/cipher/OaepCipher.java
@@ -9,9 +9,15 @@
import de.rub.nds.sshattacker.core.constants.EncryptionAlgorithm;
import de.rub.nds.sshattacker.core.exceptions.CryptoException;
-import java.security.*;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.NoSuchAlgorithmException;
import java.security.spec.MGF1ParameterSpec;
-import javax.crypto.*;
+import javax.crypto.BadPaddingException;
+import javax.crypto.Cipher;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.OAEPParameterSpec;
import javax.crypto.spec.PSource;
import org.apache.logging.log4j.LogManager;
diff --git a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/ec/FieldElement.java b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/ec/FieldElement.java
index 7fe5c01aa..427c6ac9c 100644
--- a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/ec/FieldElement.java
+++ b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/ec/FieldElement.java
@@ -36,6 +36,14 @@ protected FieldElement(BigInteger data, BigInteger modulus) {
this.modulus = modulus;
}
+ protected FieldElement(FieldElement other) {
+ super();
+ data = other.data;
+ modulus = other.modulus;
+ }
+
+ public abstract FieldElement createCopy();
+
/**
* Performs an addition in the field, which this is an element of.
*
diff --git a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/ec/FieldElementF2m.java b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/ec/FieldElementF2m.java
index abaebe6a0..113b5b338 100644
--- a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/ec/FieldElementF2m.java
+++ b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/ec/FieldElementF2m.java
@@ -29,6 +29,15 @@ public FieldElementF2m(BigInteger data, BigInteger modulus) {
super(data, modulus);
}
+ public FieldElementF2m(FieldElementF2m other) {
+ super(other);
+ }
+
+ @Override
+ public FieldElementF2m createCopy() {
+ return new FieldElementF2m(this);
+ }
+
@Override
public FieldElement add(FieldElement element) {
// Coefficients are added mod 2.
diff --git a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/ec/FieldElementFp.java b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/ec/FieldElementFp.java
index 6d222ecc2..695f0d80d 100644
--- a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/ec/FieldElementFp.java
+++ b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/ec/FieldElementFp.java
@@ -27,6 +27,15 @@ private FieldElementFp() {
super(null, null);
}
+ public FieldElementFp(FieldElementFp other) {
+ super(other);
+ }
+
+ @Override
+ public FieldElementFp createCopy() {
+ return new FieldElementFp(this);
+ }
+
@Override
public FieldElement add(FieldElement element) {
BigInteger tmp = getData().add(element.getData());
diff --git a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/ec/Point.java b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/ec/Point.java
index fee7c03cd..59cec4b88 100644
--- a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/ec/Point.java
+++ b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/ec/Point.java
@@ -8,11 +8,7 @@
package de.rub.nds.sshattacker.core.crypto.ec;
import de.rub.nds.sshattacker.core.constants.NamedEcGroup;
-import jakarta.xml.bind.annotation.XmlAccessType;
-import jakarta.xml.bind.annotation.XmlAccessorType;
-import jakarta.xml.bind.annotation.XmlElement;
-import jakarta.xml.bind.annotation.XmlElements;
-import jakarta.xml.bind.annotation.XmlRootElement;
+import jakarta.xml.bind.annotation.*;
import java.io.Serializable;
import java.math.BigInteger;
import java.util.Objects;
@@ -73,6 +69,17 @@ public Point(FieldElement x, FieldElement y) {
atInfinity = false;
}
+ public Point(Point other) {
+ super();
+ fieldX = other.fieldX != null ? other.fieldX.createCopy() : null;
+ fieldY = other.fieldY != null ? other.fieldY.createCopy() : null;
+ atInfinity = other.atInfinity;
+ }
+
+ public Point createCopy() {
+ return new Point(this);
+ }
+
/**
* Checks whether the point is the point at infinity.
*
diff --git a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/ec/PointFormatter.java b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/ec/PointFormatter.java
index f28ba1606..e359a6af6 100644
--- a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/ec/PointFormatter.java
+++ b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/ec/PointFormatter.java
@@ -10,9 +10,7 @@
import de.rub.nds.modifiablevariable.util.ArrayConverter;
import de.rub.nds.sshattacker.core.constants.EcPointFormat;
import de.rub.nds.sshattacker.core.constants.NamedEcGroup;
-import de.rub.nds.sshattacker.core.exceptions.PreparationException;
import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.math.BigInteger;
import org.apache.logging.log4j.LogManager;
@@ -22,8 +20,11 @@ public final class PointFormatter {
private static final Logger LOGGER = LogManager.getLogger();
+ static final byte[] uncompressedFormat = {0x04};
+ static final byte[] compressedFormat = {0x03};
+ static final byte[] inverseAffineCompressedFormat = {0x02};
+
public static byte[] formatToByteArray(NamedEcGroup group, Point point, EcPointFormat format) {
- ByteArrayOutputStream stream = new ByteArrayOutputStream();
if (point.isAtInfinity()) {
return new byte[1];
}
@@ -32,18 +33,12 @@ public static byte[] formatToByteArray(NamedEcGroup group, Point point, EcPointF
if (group != NamedEcGroup.CURVE448 && group != NamedEcGroup.CURVE25519) {
switch (format) {
case UNCOMPRESSED:
- stream.write(0x04);
- try {
- stream.write(
- ArrayConverter.bigIntegerToNullPaddedByteArray(
- point.getFieldX().getData(), elementLength));
- stream.write(
- ArrayConverter.bigIntegerToNullPaddedByteArray(
- point.getFieldY().getData(), elementLength));
- } catch (IOException ex) {
- throw new PreparationException("Could not serialize ec point", ex);
- }
- return stream.toByteArray();
+ return ArrayConverter.concatenate(
+ uncompressedFormat,
+ ArrayConverter.bigIntegerToNullPaddedByteArray(
+ point.getFieldX().getData(), elementLength),
+ ArrayConverter.bigIntegerToNullPaddedByteArray(
+ point.getFieldY().getData(), elementLength));
case ANSIX962_COMPRESSED_CHAR2:
case ANSIX962_COMPRESSED_PRIME:
EllipticCurve curve = CurveFactory.getCurve(group);
@@ -51,52 +46,36 @@ public static byte[] formatToByteArray(NamedEcGroup group, Point point, EcPointF
.getFieldY()
.getData()
.equals(point.getFieldY().getData())) {
- stream.write(0x03);
+ return ArrayConverter.concatenate(
+ compressedFormat,
+ ArrayConverter.bigIntegerToNullPaddedByteArray(
+ point.getFieldX().getData(), elementLength));
} else {
- stream.write(0x02);
- }
- try {
- stream.write(
+ return ArrayConverter.concatenate(
+ inverseAffineCompressedFormat,
ArrayConverter.bigIntegerToNullPaddedByteArray(
point.getFieldX().getData(), elementLength));
- } catch (IOException ex) {
- throw new PreparationException("Could not serialize ec point", ex);
}
- return stream.toByteArray();
default:
throw new UnsupportedOperationException("Unsupported PointFormat: " + format);
}
} else {
- try {
- byte[] coordinate =
- ArrayConverter.bigIntegerToNullPaddedByteArray(
- point.getFieldX().getData(), elementLength);
- stream.write(coordinate);
- } catch (IOException ex) {
- throw new PreparationException("Could not serialize ec point", ex);
- }
- return stream.toByteArray();
+ return ArrayConverter.bigIntegerToNullPaddedByteArray(
+ point.getFieldX().getData(), elementLength);
}
}
public static byte[] toRawFormat(Point point) {
- ByteArrayOutputStream stream = new ByteArrayOutputStream();
if (point.isAtInfinity()) {
return new byte[1];
}
int elementLength =
ArrayConverter.bigIntegerToByteArray(point.getFieldX().getModulus()).length;
- try {
- stream.write(
- ArrayConverter.bigIntegerToNullPaddedByteArray(
- point.getFieldX().getData(), elementLength));
- stream.write(
- ArrayConverter.bigIntegerToNullPaddedByteArray(
- point.getFieldY().getData(), elementLength));
- } catch (IOException ex) {
- throw new PreparationException("Could not serialize ec point", ex);
- }
- return stream.toByteArray();
+ return ArrayConverter.concatenate(
+ ArrayConverter.bigIntegerToNullPaddedByteArray(
+ point.getFieldX().getData(), elementLength),
+ ArrayConverter.bigIntegerToNullPaddedByteArray(
+ point.getFieldY().getData(), elementLength));
}
public static Point fromRawFormat(NamedEcGroup group, byte[] pointBytes) {
diff --git a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/hash/ExchangeHash.java b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/hash/ExchangeHash.java
index d86d7e729..edbfb9e85 100644
--- a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/hash/ExchangeHash.java
+++ b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/hash/ExchangeHash.java
@@ -148,7 +148,7 @@ public static byte[] computeRsaHash(
private static byte[] compute(KeyExchangeAlgorithm algorithm, byte[] input)
throws CryptoException {
- LOGGER.debug("Exchange hash input: {}", ArrayConverter.bytesToRawHexString(input));
+ LOGGER.debug("Exchange hash input: {}", () -> ArrayConverter.bytesToRawHexString(input));
MessageDigest md;
try {
md = MessageDigest.getInstance(algorithm.getHashFunction().getJavaName());
@@ -162,7 +162,7 @@ private static byte[] compute(KeyExchangeAlgorithm algorithm, byte[] input)
e);
}
byte[] hash = md.digest(input);
- LOGGER.info("Computed exchange hash: {}", ArrayConverter.bytesToRawHexString(hash));
+ LOGGER.info("Computed exchange hash: {}", () -> ArrayConverter.bytesToRawHexString(hash));
return hash;
}
@@ -203,13 +203,9 @@ private static byte[] prepareCommonPrefixHashInput(ExchangeHashInputHolder input
Converter.stringToLengthPrefixedBinaryString(
inputHolder.getServerVersion().get().getIdentification()),
Converter.bytesToLengthPrefixedBinaryString(
- new KeyExchangeInitMessageSerializer(
- inputHolder.getClientKeyExchangeInit().get())
- .serialize()),
+ inputHolder.getClientKeyExchangeInit().get().serialize()),
Converter.bytesToLengthPrefixedBinaryString(
- new KeyExchangeInitMessageSerializer(
- inputHolder.getServerKeyExchangeInit().get())
- .serialize()),
+ inputHolder.getServerKeyExchangeInit().get().serialize()),
Converter.bytesToLengthPrefixedBinaryString(
PublicKeyHelper.encode(inputHolder.getServerHostKey().get())));
// Restore the old log level
diff --git a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/kex/DhKeyExchange.java b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/kex/DhKeyExchange.java
index 9a321fb67..74fc7cbf8 100644
--- a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/kex/DhKeyExchange.java
+++ b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/kex/DhKeyExchange.java
@@ -232,6 +232,6 @@ public void computeSharedSecret() throws CryptoException {
.toByteArray();
LOGGER.debug(
"Finished computation of shared secret: {}",
- ArrayConverter.bytesToRawHexString(sharedSecret));
+ () -> ArrayConverter.bytesToRawHexString(sharedSecret));
}
}
diff --git a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/kex/EcdhKeyExchange.java b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/kex/EcdhKeyExchange.java
index b8dd86b76..97cd49b47 100644
--- a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/kex/EcdhKeyExchange.java
+++ b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/kex/EcdhKeyExchange.java
@@ -9,7 +9,10 @@
import de.rub.nds.modifiablevariable.util.ArrayConverter;
import de.rub.nds.sshattacker.core.constants.NamedEcGroup;
-import de.rub.nds.sshattacker.core.crypto.ec.*;
+import de.rub.nds.sshattacker.core.crypto.ec.CurveFactory;
+import de.rub.nds.sshattacker.core.crypto.ec.EllipticCurve;
+import de.rub.nds.sshattacker.core.crypto.ec.Point;
+import de.rub.nds.sshattacker.core.crypto.ec.PointFormatter;
import de.rub.nds.sshattacker.core.crypto.keys.CustomEcPrivateKey;
import de.rub.nds.sshattacker.core.crypto.keys.CustomEcPublicKey;
import de.rub.nds.sshattacker.core.crypto.keys.CustomKeyPair;
@@ -89,6 +92,6 @@ public void computeSharedSecret() throws CryptoException {
sharedSecret = sharedPoint.getFieldX().getData().toByteArray();
LOGGER.debug(
"Finished computation of shared secret: {}",
- ArrayConverter.bytesToRawHexString(sharedSecret));
+ () -> ArrayConverter.bytesToRawHexString(sharedSecret));
}
}
diff --git a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/kex/RsaKeyExchange.java b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/kex/RsaKeyExchange.java
index b0651a76f..cbec1296e 100644
--- a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/kex/RsaKeyExchange.java
+++ b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/kex/RsaKeyExchange.java
@@ -7,7 +7,6 @@
*/
package de.rub.nds.sshattacker.core.crypto.kex;
-import de.rub.nds.modifiablevariable.util.ArrayConverter;
import de.rub.nds.sshattacker.core.constants.*;
import de.rub.nds.sshattacker.core.crypto.cipher.AbstractCipher;
import de.rub.nds.sshattacker.core.crypto.cipher.CipherFactory;
@@ -105,7 +104,7 @@ public void decapsulate() throws CryptoException {
AbstractCipher cipher = CipherFactory.getOaepCipher(hashFunction, privateKey);
byte[] decryptedSharedSecret = cipher.decrypt(encapsulation);
int sharedSecretLength =
- ArrayConverter.bytesToInt(
+ Converter.fourBytesToInt(
Arrays.copyOfRange(
decryptedSharedSecret, 0, DataFormatConstants.MPINT_SIZE_LENGTH));
sharedSecret =
diff --git a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/kex/XCurveEcdhKeyExchange.java b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/kex/XCurveEcdhKeyExchange.java
index eb7b7f55f..c4f1ba30e 100644
--- a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/kex/XCurveEcdhKeyExchange.java
+++ b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/kex/XCurveEcdhKeyExchange.java
@@ -10,7 +10,9 @@
import de.rub.nds.modifiablevariable.util.ArrayConverter;
import de.rub.nds.sshattacker.core.constants.CryptoConstants;
import de.rub.nds.sshattacker.core.constants.NamedEcGroup;
-import de.rub.nds.sshattacker.core.crypto.keys.*;
+import de.rub.nds.sshattacker.core.crypto.keys.CustomKeyPair;
+import de.rub.nds.sshattacker.core.crypto.keys.XCurveEcPrivateKey;
+import de.rub.nds.sshattacker.core.crypto.keys.XCurveEcPublicKey;
import de.rub.nds.sshattacker.core.exceptions.CryptoException;
import java.math.BigInteger;
import org.apache.logging.log4j.LogManager;
@@ -118,6 +120,6 @@ public void computeSharedSecret() throws CryptoException {
encodeSharedBytes ? new BigInteger(1, sharedBytes).toByteArray() : sharedBytes;
LOGGER.debug(
"Finished computation of shared secret: {}",
- ArrayConverter.bytesToRawHexString(sharedSecret));
+ () -> ArrayConverter.bytesToRawHexString(sharedSecret));
}
}
diff --git a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/keys/CustomCertDsaPublicKey.java b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/keys/CustomCertDsaPublicKey.java
index 779120cf7..8d5f99acc 100644
--- a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/keys/CustomCertDsaPublicKey.java
+++ b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/keys/CustomCertDsaPublicKey.java
@@ -7,8 +7,10 @@
*/
package de.rub.nds.sshattacker.core.crypto.keys;
+import de.rub.nds.sshattacker.core.crypto.keys.serializer.CertDsaPublicKeySerializer;
import java.math.BigInteger;
import java.security.interfaces.DSAPublicKey;
+import java.util.HashMap;
import java.util.Map;
/** A serializable DSA public key used in DSA certificates (SSH-DSA-CERT). */
@@ -31,8 +33,9 @@ public class CustomCertDsaPublicKey extends CustomDsaPublicKey {
private long validAfter;
private long validBefore;
- private Map criticalOptions; // Map to hold critical options as key-value pairs
- private Map extensions; // Map to hold extensions as key-value pairs
+ private HashMap
+ criticalOptions; // Map to hold critical options as key-value pairs
+ private HashMap extensions; // Map to hold extensions as key-value pairs
public CustomCertDsaPublicKey() {
super();
@@ -46,6 +49,29 @@ public CustomCertDsaPublicKey(BigInteger p, BigInteger q, BigInteger g, BigInteg
super(p, q, g, y);
}
+ public CustomCertDsaPublicKey(CustomCertDsaPublicKey other) {
+ super(other);
+ serial = other.serial;
+ signature = other.signature != null ? other.signature.clone() : null;
+ signatureKey = other.signatureKey != null ? other.signatureKey.clone() : null;
+ certType = other.certType;
+ certformat = other.certformat;
+ keyId = other.keyId;
+ reserved = other.reserved;
+ validPrincipals = other.validPrincipals != null ? other.validPrincipals.clone() : null;
+ nonce = other.nonce != null ? other.nonce.clone() : null;
+ validAfter = other.validAfter;
+ validBefore = other.validBefore;
+ criticalOptions =
+ other.criticalOptions != null ? new HashMap<>(other.criticalOptions) : null;
+ extensions = other.extensions != null ? new HashMap<>(other.extensions) : null;
+ }
+
+ @Override
+ public CustomCertDsaPublicKey createCopy() {
+ return new CustomCertDsaPublicKey(this);
+ }
+
public long getSerial() {
return serial;
}
@@ -131,7 +157,7 @@ public Map getCriticalOptions() {
return criticalOptions;
}
- public void setCriticalOptions(Map criticalOptions) {
+ public void setCriticalOptions(HashMap criticalOptions) {
this.criticalOptions = criticalOptions;
}
@@ -148,7 +174,14 @@ public void setReserved(String reserved) {
this.reserved = reserved;
}
- public void setExtensions(Map extensions) {
+ public void setExtensions(HashMap extensions) {
this.extensions = extensions;
}
+
+ public static final CertDsaPublicKeySerializer SERIALIZER = new CertDsaPublicKeySerializer();
+
+ @Override
+ public byte[] serialize() {
+ return SERIALIZER.serialize(this);
+ }
}
diff --git a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/keys/CustomCertEcdsaPublicKey.java b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/keys/CustomCertEcdsaPublicKey.java
index 6061843ea..b780b47ce 100644
--- a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/keys/CustomCertEcdsaPublicKey.java
+++ b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/keys/CustomCertEcdsaPublicKey.java
@@ -9,9 +9,11 @@
import de.rub.nds.sshattacker.core.constants.NamedEcGroup;
import de.rub.nds.sshattacker.core.crypto.ec.Point;
+import de.rub.nds.sshattacker.core.crypto.keys.serializer.CertEcdsaPublicKeySerializer;
import de.rub.nds.sshattacker.core.exceptions.CryptoException;
import java.math.BigInteger;
import java.security.interfaces.ECPublicKey;
+import java.util.HashMap;
import java.util.Map;
/** A serializable ECDSA public key used in ECDSA certificates (SSH-ECDSA-CERT). */
@@ -34,8 +36,9 @@ public class CustomCertEcdsaPublicKey extends CustomEcPublicKey {
private long validAfter;
private long validBefore;
- private Map criticalOptions; // Map to hold critical options as key-value pairs
- private Map extensions; // Map to hold extensions as key-value pairs
+ private HashMap
+ criticalOptions; // Map to hold critical options as key-value pairs
+ private HashMap extensions; // Map to hold extensions as key-value pairs
public CustomCertEcdsaPublicKey() {
super();
@@ -53,6 +56,29 @@ public CustomCertEcdsaPublicKey(BigInteger x, BigInteger y, NamedEcGroup group)
super(x, y, group);
}
+ public CustomCertEcdsaPublicKey(CustomCertEcdsaPublicKey other) {
+ super(other);
+ serial = other.serial;
+ signature = other.signature != null ? other.signature.clone() : null;
+ signatureKey = other.signatureKey != null ? other.signatureKey.clone() : null;
+ certType = other.certType;
+ certformat = other.certformat;
+ keyId = other.keyId;
+ reserved = other.reserved;
+ validPrincipals = other.validPrincipals != null ? other.validPrincipals.clone() : null;
+ nonce = other.nonce != null ? other.nonce.clone() : null;
+ validAfter = other.validAfter;
+ validBefore = other.validBefore;
+ criticalOptions =
+ other.criticalOptions != null ? new HashMap<>(other.criticalOptions) : null;
+ extensions = other.extensions != null ? new HashMap<>(other.extensions) : null;
+ }
+
+ @Override
+ public CustomCertEcdsaPublicKey createCopy() {
+ return new CustomCertEcdsaPublicKey(this);
+ }
+
public void setCertFormat(String certformat) {
this.certformat = certformat;
}
@@ -154,7 +180,7 @@ public Map getCriticalOptions() {
return criticalOptions;
}
- public void setCriticalOptions(Map criticalOptions) {
+ public void setCriticalOptions(HashMap criticalOptions) {
this.criticalOptions = criticalOptions;
}
@@ -163,7 +189,15 @@ public Map getExtensions() {
return extensions;
}
- public void setExtensions(Map extensions) {
+ public void setExtensions(HashMap extensions) {
this.extensions = extensions;
}
+
+ public static final CertEcdsaPublicKeySerializer SERIALIZER =
+ new CertEcdsaPublicKeySerializer();
+
+ @Override
+ public byte[] serialize() {
+ return SERIALIZER.serialize(this);
+ }
}
diff --git a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/keys/CustomCertRsaPublicKey.java b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/keys/CustomCertRsaPublicKey.java
index 480764820..663950320 100644
--- a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/keys/CustomCertRsaPublicKey.java
+++ b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/keys/CustomCertRsaPublicKey.java
@@ -7,8 +7,10 @@
*/
package de.rub.nds.sshattacker.core.crypto.keys;
+import de.rub.nds.sshattacker.core.crypto.keys.serializer.CertRsaPublicKeySerializer;
import java.math.BigInteger;
import java.security.interfaces.RSAPublicKey;
+import java.util.HashMap;
import java.util.Map;
/** A serializable RSA public key used in RSA certificates (SSH-RSA-CERT). */
@@ -31,8 +33,9 @@ public class CustomCertRsaPublicKey extends CustomRsaPublicKey {
private long validAfter;
private long validBefore;
- private Map extensions; // Map to hold extensions as key-value pairs
- private Map criticalOptions; // Map to hold critical options as key-value pairs
+ private HashMap extensions; // Map to hold extensions as key-value pairs
+ private HashMap
+ criticalOptions; // Map to hold critical options as key-value pairs
public CustomCertRsaPublicKey() {
super();
@@ -46,6 +49,29 @@ public CustomCertRsaPublicKey(BigInteger publicExponent, BigInteger modulus) {
super(publicExponent, modulus);
}
+ public CustomCertRsaPublicKey(CustomCertRsaPublicKey other) {
+ super(other);
+ serial = other.serial;
+ signature = other.signature != null ? other.signature.clone() : null;
+ signatureKey = other.signatureKey != null ? other.signatureKey.clone() : null;
+ certformat = other.certformat;
+ certType = other.certType;
+ keyId = other.keyId;
+ reserved = other.reserved;
+ validPrincipals = other.validPrincipals != null ? other.validPrincipals.clone() : null;
+ nonce = other.nonce != null ? other.nonce.clone() : null;
+ validAfter = other.validAfter;
+ validBefore = other.validBefore;
+ extensions = other.extensions != null ? new HashMap<>(other.extensions) : null;
+ criticalOptions =
+ other.criticalOptions != null ? new HashMap<>(other.criticalOptions) : null;
+ }
+
+ @Override
+ public CustomCertRsaPublicKey createCopy() {
+ return new CustomCertRsaPublicKey(this);
+ }
+
public void setCertFormat(String certformat) {
this.certformat = certformat;
}
@@ -138,7 +164,7 @@ public Map getExtensions() {
return extensions;
}
- public void setExtensions(Map extensions) {
+ public void setExtensions(HashMap extensions) {
this.extensions = extensions;
}
@@ -146,7 +172,14 @@ public Map getCriticalOptions() {
return criticalOptions;
}
- public void setCriticalOptions(Map criticalOptions) {
+ public void setCriticalOptions(HashMap criticalOptions) {
this.criticalOptions = criticalOptions;
}
+
+ public static final CertRsaPublicKeySerializer SERIALIZER = new CertRsaPublicKeySerializer();
+
+ @Override
+ public byte[] serialize() {
+ return SERIALIZER.serialize(this);
+ }
}
diff --git a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/keys/CustomCertXCurvePublicKey.java b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/keys/CustomCertXCurvePublicKey.java
index b1d502e3c..547900858 100644
--- a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/keys/CustomCertXCurvePublicKey.java
+++ b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/keys/CustomCertXCurvePublicKey.java
@@ -8,6 +8,8 @@
package de.rub.nds.sshattacker.core.crypto.keys;
import de.rub.nds.sshattacker.core.constants.NamedEcGroup;
+import de.rub.nds.sshattacker.core.crypto.keys.serializer.CertXCurvePublicKeySerializer;
+import java.util.HashMap;
import java.util.Map;
/** A serializable ED25519/ED448 certificate public key used in certificates (SSH-ED25519-CERT). */
@@ -25,8 +27,8 @@ public class CustomCertXCurvePublicKey extends XCurveEcPublicKey {
private long validBefore;
private byte[] signature;
private byte[] signatureKey;
- private Map criticalOptions;
- private Map extensions;
+ private HashMap criticalOptions;
+ private HashMap extensions;
public CustomCertXCurvePublicKey() {
super();
@@ -36,6 +38,29 @@ public CustomCertXCurvePublicKey(byte[] coordinate, NamedEcGroup group) {
super(coordinate, group);
}
+ public CustomCertXCurvePublicKey(CustomCertXCurvePublicKey other) {
+ super(other);
+ serial = other.serial;
+ certType = other.certType;
+ certformat = other.certformat;
+ keyId = other.keyId;
+ reserved = other.reserved;
+ validPrincipals = other.validPrincipals != null ? other.validPrincipals.clone() : null;
+ nonce = other.nonce != null ? other.nonce.clone() : null;
+ validAfter = other.validAfter;
+ validBefore = other.validBefore;
+ signature = other.signature != null ? other.signature.clone() : null;
+ signatureKey = other.signatureKey != null ? other.signatureKey.clone() : null;
+ criticalOptions =
+ other.criticalOptions != null ? new HashMap<>(other.criticalOptions) : null;
+ extensions = other.extensions != null ? new HashMap<>(other.extensions) : null;
+ }
+
+ @Override
+ public CustomCertXCurvePublicKey createCopy() {
+ return new CustomCertXCurvePublicKey(this);
+ }
+
// Getter and setter for serial number
public long getSerial() {
return serial;
@@ -139,7 +164,7 @@ public Map getCriticalOptions() {
return criticalOptions;
}
- public void setCriticalOptions(Map criticalOptions) {
+ public void setCriticalOptions(HashMap criticalOptions) {
this.criticalOptions = criticalOptions;
}
@@ -148,7 +173,15 @@ public Map getExtensions() {
return extensions;
}
- public void setExtensions(Map extensions) {
+ public void setExtensions(HashMap extensions) {
this.extensions = extensions;
}
+
+ public static final CertXCurvePublicKeySerializer SERIALIZER =
+ new CertXCurvePublicKeySerializer();
+
+ @Override
+ public byte[] serialize() {
+ return SERIALIZER.serialize(this);
+ }
}
diff --git a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/keys/CustomDhPrivateKey.java b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/keys/CustomDhPrivateKey.java
index fc527d96e..7ab577ba8 100644
--- a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/keys/CustomDhPrivateKey.java
+++ b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/keys/CustomDhPrivateKey.java
@@ -8,8 +8,6 @@
package de.rub.nds.sshattacker.core.crypto.keys;
import de.rub.nds.sshattacker.core.constants.NamedDhGroup;
-import jakarta.xml.bind.annotation.XmlAccessType;
-import jakarta.xml.bind.annotation.XmlAccessorType;
import jakarta.xml.bind.annotation.XmlRootElement;
import java.math.BigInteger;
import javax.crypto.interfaces.DHPrivateKey;
@@ -17,7 +15,6 @@
/** A serializable diffie-hellman private key used in the DH key exchange. */
@XmlRootElement
-@XmlAccessorType(XmlAccessType.FIELD)
public class CustomDhPrivateKey extends CustomPrivateKey implements DHPrivateKey {
// Group parameters
@@ -46,6 +43,18 @@ public BigInteger getModulus() {
return modulus;
}
+ public CustomDhPrivateKey(CustomDhPrivateKey other) {
+ super(other);
+ modulus = other.modulus;
+ generator = other.generator;
+ privateKey = other.privateKey;
+ }
+
+ @Override
+ public CustomDhPrivateKey createCopy() {
+ return new CustomDhPrivateKey(this);
+ }
+
public void setModulus(BigInteger modulus) {
this.modulus = modulus;
}
diff --git a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/keys/CustomDhPublicKey.java b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/keys/CustomDhPublicKey.java
index 3699cfe64..08fe5555d 100644
--- a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/keys/CustomDhPublicKey.java
+++ b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/keys/CustomDhPublicKey.java
@@ -8,8 +8,7 @@
package de.rub.nds.sshattacker.core.crypto.keys;
import de.rub.nds.sshattacker.core.constants.NamedDhGroup;
-import jakarta.xml.bind.annotation.XmlAccessType;
-import jakarta.xml.bind.annotation.XmlAccessorType;
+import de.rub.nds.sshattacker.core.exceptions.NotImplementedException;
import jakarta.xml.bind.annotation.XmlRootElement;
import java.math.BigInteger;
import javax.crypto.interfaces.DHPublicKey;
@@ -17,7 +16,6 @@
/** A serializable diffie-hellman public key used in the DH key exchange. */
@XmlRootElement
-@XmlAccessorType(XmlAccessType.FIELD)
public class CustomDhPublicKey extends CustomPublicKey implements DHPublicKey {
// Group parameters
@@ -42,6 +40,18 @@ public CustomDhPublicKey(BigInteger modulus, BigInteger generator, BigInteger pu
this.publicKey = publicKey;
}
+ public CustomDhPublicKey(CustomDhPublicKey other) {
+ super(other);
+ modulus = other.modulus;
+ generator = other.generator;
+ publicKey = other.publicKey;
+ }
+
+ @Override
+ public CustomDhPublicKey createCopy() {
+ return new CustomDhPublicKey(this);
+ }
+
public BigInteger getModulus() {
return modulus;
}
@@ -92,4 +102,9 @@ public String getFormat() {
public byte[] getEncoded() {
return publicKey.toByteArray();
}
+
+ @Override
+ public byte[] serialize() {
+ throw new NotImplementedException("Missing Serializer");
+ }
}
diff --git a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/keys/CustomDsaPrivateKey.java b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/keys/CustomDsaPrivateKey.java
index e4a17d84b..00ab7a739 100644
--- a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/keys/CustomDsaPrivateKey.java
+++ b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/keys/CustomDsaPrivateKey.java
@@ -7,8 +7,6 @@
*/
package de.rub.nds.sshattacker.core.crypto.keys;
-import jakarta.xml.bind.annotation.XmlAccessType;
-import jakarta.xml.bind.annotation.XmlAccessorType;
import jakarta.xml.bind.annotation.XmlRootElement;
import java.math.BigInteger;
import java.security.interfaces.DSAParams;
@@ -17,7 +15,6 @@
/** A serializable DSA private key used in the DSA signature algorithm. */
@XmlRootElement
-@XmlAccessorType(XmlAccessType.FIELD)
public class CustomDsaPrivateKey extends CustomPrivateKey implements DSAPrivateKey {
// Group parameters
@@ -40,6 +37,19 @@ public CustomDsaPrivateKey(BigInteger p, BigInteger q, BigInteger g, BigInteger
this.x = x;
}
+ public CustomDsaPrivateKey(CustomDsaPrivateKey other) {
+ super(other);
+ p = other.p;
+ q = other.q;
+ g = other.g;
+ x = other.x;
+ }
+
+ @Override
+ public CustomDsaPrivateKey createCopy() {
+ return new CustomDsaPrivateKey(this);
+ }
+
public BigInteger getP() {
return p;
}
diff --git a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/keys/CustomDsaPublicKey.java b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/keys/CustomDsaPublicKey.java
index a5f559e6d..f5b18cc43 100644
--- a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/keys/CustomDsaPublicKey.java
+++ b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/keys/CustomDsaPublicKey.java
@@ -7,8 +7,7 @@
*/
package de.rub.nds.sshattacker.core.crypto.keys;
-import jakarta.xml.bind.annotation.XmlAccessType;
-import jakarta.xml.bind.annotation.XmlAccessorType;
+import de.rub.nds.sshattacker.core.crypto.keys.serializer.DsaPublicKeySerializer;
import jakarta.xml.bind.annotation.XmlRootElement;
import java.math.BigInteger;
import java.security.interfaces.DSAParams;
@@ -17,7 +16,6 @@
/** A serializable DSA public key used in the DSA signature algorithm. */
@XmlRootElement
-@XmlAccessorType(XmlAccessType.FIELD)
public class CustomDsaPublicKey extends CustomPublicKey implements DSAPublicKey {
// Group parameters
@@ -48,6 +46,19 @@ public CustomDsaPublicKey(BigInteger p, BigInteger q, BigInteger g, BigInteger y
this.y = y;
}
+ public CustomDsaPublicKey(CustomDsaPublicKey other) {
+ super(other);
+ p = other.p;
+ q = other.q;
+ g = other.g;
+ y = other.y;
+ }
+
+ @Override
+ public CustomDsaPublicKey createCopy() {
+ return new CustomDsaPublicKey(this);
+ }
+
public BigInteger getP() {
return p;
}
@@ -91,4 +102,11 @@ public DSAParams getParams() {
public String getAlgorithm() {
return "DSA";
}
+
+ public static final DsaPublicKeySerializer SERIALIZER = new DsaPublicKeySerializer();
+
+ @Override
+ public byte[] serialize() {
+ return SERIALIZER.serialize(this);
+ }
}
diff --git a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/keys/CustomEcPrivateKey.java b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/keys/CustomEcPrivateKey.java
index 908834ed1..a86201b7e 100644
--- a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/keys/CustomEcPrivateKey.java
+++ b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/keys/CustomEcPrivateKey.java
@@ -9,8 +9,6 @@
import de.rub.nds.modifiablevariable.util.ArrayConverter;
import de.rub.nds.sshattacker.core.constants.NamedEcGroup;
-import jakarta.xml.bind.annotation.XmlAccessType;
-import jakarta.xml.bind.annotation.XmlAccessorType;
import jakarta.xml.bind.annotation.XmlRootElement;
import java.math.BigInteger;
import java.security.AlgorithmParameters;
@@ -25,7 +23,6 @@
* ECDSA.
*/
@XmlRootElement
-@XmlAccessorType(XmlAccessType.FIELD)
public class CustomEcPrivateKey extends CustomPrivateKey implements ECPrivateKey {
private NamedEcGroup group;
@@ -45,6 +42,17 @@ public CustomEcPrivateKey(BigInteger privateKey, NamedEcGroup group) {
this.privateKey = privateKey;
}
+ public CustomEcPrivateKey(CustomEcPrivateKey other) {
+ super(other);
+ group = other.group;
+ privateKey = other.privateKey;
+ }
+
+ @Override
+ public CustomEcPrivateKey createCopy() {
+ return new CustomEcPrivateKey(this);
+ }
+
public NamedEcGroup getGroup() {
return group;
}
diff --git a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/keys/CustomEcPublicKey.java b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/keys/CustomEcPublicKey.java
index 8856f1342..50e1fbff9 100644
--- a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/keys/CustomEcPublicKey.java
+++ b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/keys/CustomEcPublicKey.java
@@ -11,9 +11,8 @@
import de.rub.nds.sshattacker.core.constants.NamedEcGroup;
import de.rub.nds.sshattacker.core.crypto.ec.Point;
import de.rub.nds.sshattacker.core.crypto.ec.PointFormatter;
+import de.rub.nds.sshattacker.core.crypto.keys.serializer.EcPublicKeySerializer;
import de.rub.nds.sshattacker.core.exceptions.CryptoException;
-import jakarta.xml.bind.annotation.XmlAccessType;
-import jakarta.xml.bind.annotation.XmlAccessorType;
import jakarta.xml.bind.annotation.XmlRootElement;
import java.math.BigInteger;
import java.security.AlgorithmParameters;
@@ -30,7 +29,6 @@
* A serializable elliptic curve public key used in various EC-based algorithms like ECDH and ECDSA.
*/
@XmlRootElement
-@XmlAccessorType(XmlAccessType.FIELD)
public class CustomEcPublicKey extends CustomPublicKey implements ECPublicKey {
protected Point publicKey; // Public key as Point
@@ -66,12 +64,23 @@ public CustomEcPublicKey(ECPublicKey publicKey) throws CryptoException {
v.getJavaName(),
publicKey.getParams().getCurve().toString()))
.findFirst()
- .orElseThrow(CryptoException::new);
+ .orElseThrow(() -> new CryptoException("Named EC Group not found"));
this.publicKey =
Point.createPoint(
publicKey.getW().getAffineX(), publicKey.getW().getAffineY(), group);
}
+ public CustomEcPublicKey(CustomEcPublicKey other) {
+ super(other);
+ publicKey = other.publicKey != null ? other.publicKey.createCopy() : null;
+ group = other.group;
+ }
+
+ @Override
+ public CustomEcPublicKey createCopy() {
+ return new CustomEcPublicKey(this);
+ }
+
public NamedEcGroup getGroup() {
return group;
}
@@ -124,4 +133,11 @@ public ECParameterSpec getParams() {
public static CustomEcPublicKey parse(byte[] encoded, NamedEcGroup group) {
return new CustomEcPublicKey(PointFormatter.formatFromByteArray(group, encoded), group);
}
+
+ public static final EcPublicKeySerializer SERIALIZER = new EcPublicKeySerializer();
+
+ @Override
+ public byte[] serialize() {
+ return SERIALIZER.serialize(this);
+ }
}
diff --git a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/keys/CustomPrivateKey.java b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/keys/CustomPrivateKey.java
index 5925965f7..9992a3d34 100644
--- a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/keys/CustomPrivateKey.java
+++ b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/keys/CustomPrivateKey.java
@@ -7,6 +7,8 @@
*/
package de.rub.nds.sshattacker.core.crypto.keys;
+import jakarta.xml.bind.annotation.XmlAccessType;
+import jakarta.xml.bind.annotation.XmlAccessorType;
import java.security.PrivateKey;
/**
@@ -14,7 +16,19 @@
* overrides the getFormat() and getEncoded() methods of the PrivateKey interface to return null (no
* encoding support).
*/
+@XmlAccessorType(XmlAccessType.FIELD)
public abstract class CustomPrivateKey implements PrivateKey {
+
+ protected CustomPrivateKey() {
+ super();
+ }
+
+ protected CustomPrivateKey(CustomPrivateKey other) {
+ super();
+ }
+
+ public abstract CustomPrivateKey createCopy();
+
@Override
public String getFormat() {
return null;
diff --git a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/keys/CustomPublicKey.java b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/keys/CustomPublicKey.java
index ea05ce5d4..426cc4f71 100644
--- a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/keys/CustomPublicKey.java
+++ b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/keys/CustomPublicKey.java
@@ -7,6 +7,8 @@
*/
package de.rub.nds.sshattacker.core.crypto.keys;
+import jakarta.xml.bind.annotation.XmlAccessType;
+import jakarta.xml.bind.annotation.XmlAccessorType;
import java.security.PublicKey;
/**
@@ -14,7 +16,19 @@
* overrides the getFormat() and getEncoded() methods of the PrivateKey interface to return null (no
* encoding support).
*/
+@XmlAccessorType(XmlAccessType.FIELD)
public abstract class CustomPublicKey implements PublicKey {
+
+ protected CustomPublicKey() {
+ super();
+ }
+
+ protected CustomPublicKey(CustomPublicKey other) {
+ super();
+ }
+
+ public abstract CustomPublicKey createCopy();
+
@Override
public String getFormat() {
return null;
@@ -24,4 +38,6 @@ public String getFormat() {
public byte[] getEncoded() {
return null;
}
+
+ public abstract byte[] serialize();
}
diff --git a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/keys/CustomRsaPrivateKey.java b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/keys/CustomRsaPrivateKey.java
index 7a0a1f8af..391905dfa 100644
--- a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/keys/CustomRsaPrivateKey.java
+++ b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/keys/CustomRsaPrivateKey.java
@@ -7,15 +7,12 @@
*/
package de.rub.nds.sshattacker.core.crypto.keys;
-import jakarta.xml.bind.annotation.XmlAccessType;
-import jakarta.xml.bind.annotation.XmlAccessorType;
import jakarta.xml.bind.annotation.XmlRootElement;
import java.math.BigInteger;
import java.security.interfaces.RSAPrivateKey;
/** A serializable RSA private key used in RSA encryption and signatures. */
@XmlRootElement
-@XmlAccessorType(XmlAccessType.FIELD)
public class CustomRsaPrivateKey extends CustomPrivateKey implements RSAPrivateKey {
private BigInteger modulus;
@@ -37,6 +34,17 @@ public CustomRsaPrivateKey(BigInteger privateExponent, BigInteger modulus) {
this.privateExponent = privateExponent;
}
+ public CustomRsaPrivateKey(CustomRsaPrivateKey other) {
+ super(other);
+ modulus = other.modulus;
+ privateExponent = other.privateExponent;
+ }
+
+ @Override
+ public CustomRsaPrivateKey createCopy() {
+ return new CustomRsaPrivateKey(this);
+ }
+
@Override
public BigInteger getModulus() {
return modulus;
diff --git a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/keys/CustomRsaPublicKey.java b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/keys/CustomRsaPublicKey.java
index 6d4ff9cc1..ce95b952a 100644
--- a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/keys/CustomRsaPublicKey.java
+++ b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/keys/CustomRsaPublicKey.java
@@ -7,15 +7,13 @@
*/
package de.rub.nds.sshattacker.core.crypto.keys;
-import jakarta.xml.bind.annotation.XmlAccessType;
-import jakarta.xml.bind.annotation.XmlAccessorType;
+import de.rub.nds.sshattacker.core.crypto.keys.serializer.RsaPublicKeySerializer;
import jakarta.xml.bind.annotation.XmlRootElement;
import java.math.BigInteger;
import java.security.interfaces.RSAPublicKey;
/** A serializable RSA public key used in RSA encryption and signatures. */
@XmlRootElement
-@XmlAccessorType(XmlAccessType.FIELD)
public class CustomRsaPublicKey extends CustomPublicKey implements RSAPublicKey {
protected BigInteger modulus;
@@ -37,6 +35,17 @@ public CustomRsaPublicKey(BigInteger publicExponent, BigInteger modulus) {
this.publicExponent = publicExponent;
}
+ public CustomRsaPublicKey(CustomRsaPublicKey other) {
+ super(other);
+ modulus = other.modulus;
+ publicExponent = other.publicExponent;
+ }
+
+ @Override
+ public CustomRsaPublicKey createCopy() {
+ return new CustomRsaPublicKey(this);
+ }
+
@Override
public BigInteger getModulus() {
return modulus;
@@ -60,4 +69,11 @@ public void setPublicExponent(BigInteger publicExponent) {
public String getAlgorithm() {
return "RSA";
}
+
+ public static final RsaPublicKeySerializer SERIALIZER = new RsaPublicKeySerializer();
+
+ @Override
+ public byte[] serialize() {
+ return SERIALIZER.serialize(this);
+ }
}
diff --git a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/keys/CustomX509DsaPublicKey.java b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/keys/CustomX509DsaPublicKey.java
index 06d97e9d5..6e31761e0 100644
--- a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/keys/CustomX509DsaPublicKey.java
+++ b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/keys/CustomX509DsaPublicKey.java
@@ -7,8 +7,10 @@
*/
package de.rub.nds.sshattacker.core.crypto.keys;
+import de.rub.nds.sshattacker.core.crypto.keys.serializer.X509DsaPublicKeySerializer;
import java.math.BigInteger;
import java.security.interfaces.DSAPublicKey;
+import java.util.HashMap;
import java.util.Map;
/** A serializable DSA public key used in X.509 certificates (X509-SSH-DSA). */
@@ -29,7 +31,7 @@ public class CustomX509DsaPublicKey extends CustomDsaPublicKey {
private long validBefore; // Not After (valid before)
// Extensions (if any)
- private Map extensions; // Extensions (optional)
+ private HashMap extensions; // Extensions (optional)
public CustomX509DsaPublicKey() {
super();
@@ -52,6 +54,27 @@ public CustomX509DsaPublicKey(
this.signature = signature;
}
+ public CustomX509DsaPublicKey(CustomX509DsaPublicKey other) {
+ super(other);
+ issuer = other.issuer;
+ subject = other.subject;
+ publicKeyAlgorithm = other.publicKeyAlgorithm;
+ version = other.version;
+ serial = other.serial;
+ signatureAlgorithm = other.signatureAlgorithm;
+ signature = other.signature != null ? other.signature.clone() : null;
+ subjectKeyIdentifier =
+ other.subjectKeyIdentifier != null ? other.subjectKeyIdentifier.clone() : null;
+ validAfter = other.validAfter;
+ validBefore = other.validBefore;
+ extensions = other.extensions != null ? new HashMap<>(other.extensions) : null;
+ }
+
+ @Override
+ public CustomX509DsaPublicKey createCopy() {
+ return new CustomX509DsaPublicKey(this);
+ }
+
// Getter and setter for serial number
public long getSerial() {
return serial;
@@ -139,7 +162,7 @@ public Map getExtensions() {
return extensions;
}
- public void setExtensions(Map extensions) {
+ public void setExtensions(HashMap extensions) {
this.extensions = extensions;
}
@@ -151,4 +174,11 @@ public byte[] getSubjectKeyIdentifier() {
public void setSubjectKeyIdentifier(byte[] subjectKeyIdentifier) {
this.subjectKeyIdentifier = subjectKeyIdentifier;
}
+
+ public static final X509DsaPublicKeySerializer SERIALIZER = new X509DsaPublicKeySerializer();
+
+ @Override
+ public byte[] serialize() {
+ return SERIALIZER.serialize(this);
+ }
}
diff --git a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/keys/CustomX509EcdsaPublicKey.java b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/keys/CustomX509EcdsaPublicKey.java
index ab7827763..128b94d59 100644
--- a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/keys/CustomX509EcdsaPublicKey.java
+++ b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/keys/CustomX509EcdsaPublicKey.java
@@ -9,9 +9,11 @@
import de.rub.nds.sshattacker.core.constants.NamedEcGroup;
import de.rub.nds.sshattacker.core.crypto.ec.Point;
+import de.rub.nds.sshattacker.core.crypto.keys.serializer.X509EcdsaPublicKeySerializer;
import de.rub.nds.sshattacker.core.exceptions.CryptoException;
import java.math.BigInteger;
import java.security.interfaces.ECPublicKey;
+import java.util.HashMap;
import java.util.Map;
/** A serializable ECDSA public key used in X.509 certificates (X509-SSH-ECDSA). */
@@ -32,7 +34,7 @@ public class CustomX509EcdsaPublicKey extends CustomEcPublicKey {
private long validBefore; // Not After (valid before)
// Extensions (if any)
- private Map extensions; // Extensions (optional)
+ private HashMap extensions; // Extensions (optional)
public CustomX509EcdsaPublicKey() {
super();
@@ -64,6 +66,27 @@ public CustomX509EcdsaPublicKey(
this.signature = signature;
}
+ public CustomX509EcdsaPublicKey(CustomX509EcdsaPublicKey other) {
+ super(other);
+ issuer = other.issuer;
+ subject = other.subject;
+ publicKeyAlgorithm = other.publicKeyAlgorithm;
+ version = other.version;
+ serial = other.serial;
+ signatureAlgorithm = other.signatureAlgorithm;
+ signature = other.signature != null ? other.signature.clone() : null;
+ subjectKeyIdentifier =
+ other.subjectKeyIdentifier != null ? other.subjectKeyIdentifier.clone() : null;
+ validAfter = other.validAfter;
+ validBefore = other.validBefore;
+ extensions = other.extensions != null ? new HashMap<>(other.extensions) : null;
+ }
+
+ @Override
+ public CustomX509EcdsaPublicKey createCopy() {
+ return new CustomX509EcdsaPublicKey(this);
+ }
+
// Getter and setter for serial number
public long getSerial() {
return serial;
@@ -151,7 +174,7 @@ public Map getExtensions() {
return extensions;
}
- public void setExtensions(Map extensions) {
+ public void setExtensions(HashMap extensions) {
this.extensions = extensions;
}
@@ -163,4 +186,12 @@ public byte[] getSubjectKeyIdentifier() {
public void setSubjectKeyIdentifier(byte[] subjectKeyIdentifier) {
this.subjectKeyIdentifier = subjectKeyIdentifier;
}
+
+ public static final X509EcdsaPublicKeySerializer SERIALIZER =
+ new X509EcdsaPublicKeySerializer();
+
+ @Override
+ public byte[] serialize() {
+ return SERIALIZER.serialize(this);
+ }
}
diff --git a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/keys/CustomX509RsaPublicKey.java b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/keys/CustomX509RsaPublicKey.java
index d39906893..983984c44 100644
--- a/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/keys/CustomX509RsaPublicKey.java
+++ b/SSH-Core/src/main/java/de/rub/nds/sshattacker/core/crypto/keys/CustomX509RsaPublicKey.java
@@ -7,8 +7,10 @@
*/
package de.rub.nds.sshattacker.core.crypto.keys;
+import de.rub.nds.sshattacker.core.crypto.keys.serializer.X509RsaPublicKeySerializer;
import java.math.BigInteger;
import java.security.interfaces.RSAPublicKey;
+import java.util.HashMap;
import java.util.Map;
/** A serializable RSA public key used in X.509 certificates (X509-SSH-RSA). */
@@ -29,7 +31,7 @@ public class CustomX509RsaPublicKey extends CustomRsaPublicKey {
private long validBefore; // Not After (valid before)
// Extensions (if any)
- private Map extensions; // Extensions (optional)
+ private HashMap