diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 31342dbc..a96cd107 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -10,7 +10,7 @@ "version": "25", "jdkDistro": "tem", "installMaven": "true", - "mavenVersion": "3.9.14", + "mavenVersion": "3.9.15", "installGradle": "false" }, "ghcr.io/devcontainers/features/docker-in-docker:2": { diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 8e079ba0..64fff0f4 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -47,7 +47,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - java: ['8', '11', '17', '21', '25'] + java: ['8', '11', '17', '21', '25', '26'] steps: - name: Checkout repository uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -85,7 +85,7 @@ jobs: run: | LOWER_JDK="${{ matrix.java }}" UPPER_JDK=$((LOWER_JDK+1)) - ./mvnw -B -V -e -Pcoverage verify -Dtoolchain.jdk.version="[$LOWER_JDK,$UPPER_JDK)" -Dmaven.resources.skip=true -Dflatten.skip=true -Dmaven.main.skip=true -Dbnd.skip=true -Dassembly.skipAssembly=true -Dmaven.javadoc.skip=true -Dcyclonedx.skip=true -Dspdx.skip=true -Dformatter.skip=true -Dforbiddenapis.skip=true -DskipTests=false -DskipITs=false + ./mvnw -B -V -e -Pcoverage verify -Dtoolchain.jdk.version="[$LOWER_JDK,$UPPER_JDK)" -Dmaven.resources.skip=true -Dflatten.skip=true -Dmaven.main.skip=true -Dbnd.skip=true -Dassembly.skipAssembly=true -Dmaven.javadoc.skip=true -Dcyclonedx.skip=true -Dspdx.skip=true -Dformatter.skip=true -Dimpsort.skip=true -Dforbiddenapis.skip=true -DskipTests=false -DskipITs=false - name: Upload test results uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties index c595b009..52913720 100644 --- a/.mvn/wrapper/maven-wrapper.properties +++ b/.mvn/wrapper/maven-wrapper.properties @@ -1,3 +1,3 @@ wrapperVersion=3.3.4 distributionType=only-script -distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.14/apache-maven-3.9.14-bin.zip +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.15/apache-maven-3.9.15-bin.zip diff --git a/.sdkmanrc b/.sdkmanrc index 58625181..34888d2d 100644 --- a/.sdkmanrc +++ b/.sdkmanrc @@ -1,4 +1,4 @@ # Enable auto-env through the sdkman_auto_env config # Add key=value pairs of SDKs to use below java=25-tem -maven=3.9.14 +maven=3.9.15 diff --git a/examples/AES.java b/examples/AES.java index 7a918fc9..c8ee4dbe 100644 --- a/examples/AES.java +++ b/examples/AES.java @@ -1,4 +1,6 @@ -/** This program will demonstrate how to use "aes128-cbc". */ +/** + * This program will demonstrate how to use "aes128-cbc". + */ import com.jcraft.jsch.Channel; import com.jcraft.jsch.JSch; import com.jcraft.jsch.Session; @@ -33,7 +35,7 @@ public static void main(String[] arg) { host = host.substring(host.indexOf('@') + 1); Session session = jsch.getSession(user, host, 22); - // session.setPassword("your password"); + // session.setPassword("your password".getBytes()); // username and password will be given via UserInfo interface. UserInfo ui = new MyUserInfo(); diff --git a/examples/ChangePassphrase.java b/examples/ChangePassphrase.java index c1dd39ac..93ec0f51 100644 --- a/examples/ChangePassphrase.java +++ b/examples/ChangePassphrase.java @@ -6,6 +6,7 @@ */ import com.jcraft.jsch.JSch; import com.jcraft.jsch.KeyPair; +import java.util.Arrays; import javax.swing.JOptionPane; import javax.swing.JPasswordField; import javax.swing.JTextField; @@ -27,7 +28,7 @@ public static void main(String[] arg) { System.out .println(pkey + " has " + (kpair.isEncrypted() ? "been " : "not been ") + "encrypted"); - String passphrase = ""; + byte[] passphrase = null; while (kpair.isEncrypted()) { JTextField passphraseField = new JPasswordField(20); Object[] ob = {passphraseField}; @@ -36,7 +37,10 @@ public static void main(String[] arg) { if (result != JOptionPane.OK_OPTION) { System.exit(-1); } - passphrase = passphraseField.getText(); + passphrase = passphraseField.getText().getBytes(); + if (passphrase.length == 0) { + passphrase = null; + } if (!kpair.decrypt(passphrase)) { System.out.println("failed to decrypt " + pkey); } else { @@ -44,7 +48,10 @@ public static void main(String[] arg) { } } - passphrase = ""; + if (passphrase != null) { + Arrays.fill(passphrase, (byte) 0); + } + passphrase = null; JTextField passphraseField = new JPasswordField(20); Object[] ob = {passphraseField}; @@ -54,10 +61,16 @@ public static void main(String[] arg) { if (result != JOptionPane.OK_OPTION) { System.exit(-1); } - passphrase = passphraseField.getText(); + passphrase = passphraseField.getText().getBytes(); + if (passphrase.length == 0) { + passphrase = null; + } - kpair.writePrivateKey(pkey, passphrase.getBytes()); + kpair.writePrivateKey(pkey, passphrase); kpair.dispose(); + if (passphrase != null) { + Arrays.fill(passphrase, (byte) 0); + } } catch (Exception e) { System.out.println(e); } diff --git a/examples/Logger.java b/examples/Logger.java index 5c391004..4bdd313a 100644 --- a/examples/Logger.java +++ b/examples/Logger.java @@ -1,4 +1,6 @@ -/** This program will demonstrate how to enable logging mechanism and get logging messages. */ +/** + * This program will demonstrate how to enable logging mechanism and get logging messages. + */ import com.jcraft.jsch.Channel; import com.jcraft.jsch.JSch; import com.jcraft.jsch.Session; diff --git a/examples/OpenSSHConfig.java b/examples/OpenSSHConfig.java index e5c7db45..88719b91 100644 --- a/examples/OpenSSHConfig.java +++ b/examples/OpenSSHConfig.java @@ -44,7 +44,7 @@ public static void main(String[] arg) { // "foo" is from "Host foo" in the above config. Session session = jsch.getSession("foo"); - String passwd = JOptionPane.showInputDialog("Enter password"); + byte[] passwd = JOptionPane.showInputDialog("Enter password").getBytes(); session.setPassword(passwd); UserInfo ui = new MyUserInfo() { diff --git a/examples/Shell.java b/examples/Shell.java index 6ba9f730..217f1c46 100644 --- a/examples/Shell.java +++ b/examples/Shell.java @@ -30,7 +30,7 @@ public static void main(String[] arg) { Session session = jsch.getSession(user, host, 22); - String passwd = JOptionPane.showInputDialog("Enter password"); + byte[] passwd = JOptionPane.showInputDialog("Enter password").getBytes(); session.setPassword(passwd); UserInfo ui = new MyUserInfo() { diff --git a/examples/SocketForwardingL.java b/examples/SocketForwardingL.java index a1071a47..77ae9de7 100644 --- a/examples/SocketForwardingL.java +++ b/examples/SocketForwardingL.java @@ -29,7 +29,7 @@ public static void main(String[] arg) { Session session = jsch.getSession(user, host, 22); - String passwd = JOptionPane.showInputDialog("Enter password"); + byte[] passwd = JOptionPane.showInputDialog("Enter password").getBytes(); session.setPassword(passwd); UserInfo ui = new MyUserInfo() { diff --git a/examples/Subsystem.java b/examples/Subsystem.java index 2f3e85e9..2709e296 100644 --- a/examples/Subsystem.java +++ b/examples/Subsystem.java @@ -1,4 +1,6 @@ -/** This program will demonstrate how to use the Subsystem channel. */ +/** + * This program will demonstrate how to use the Subsystem channel. + */ import com.jcraft.jsch.Channel; import com.jcraft.jsch.ChannelSubsystem; import com.jcraft.jsch.JSch; diff --git a/examples/Sudo.java b/examples/Sudo.java index cb3da7c8..b1b70e30 100644 --- a/examples/Sudo.java +++ b/examples/Sudo.java @@ -1,4 +1,6 @@ -/** This program will demonstrate how to exec 'sudo' on the remote. */ +/** + * This program will demonstrate how to exec 'sudo' on the remote. + */ import com.jcraft.jsch.Channel; import com.jcraft.jsch.ChannelExec; import com.jcraft.jsch.JSch; diff --git a/pom.xml b/pom.xml index ed1125d4..93e73243 100644 --- a/pom.xml +++ b/pom.xml @@ -81,7 +81,7 @@ org.bouncycastle bcprov-jdk18on - 1.83 + 1.84 true @@ -260,7 +260,7 @@ 25 - 3.9.14 + 3.9.15 @@ -453,7 +453,7 @@ Import-Package: \ com.sun.jna*;version="${range;[=0,+)}";resolution:=optional,\ org.apache.logging.log4j*;version="${range;[=0,4)}";resolution:=optional,\ - org.bouncycastle*;version="[1.79,${versionmask;+})";resolution:=optional,\ + org.bouncycastle*;version="[1.84,${versionmask;+})";resolution:=optional,\ org.slf4j*;version="[1.7,${versionmask;+})";resolution:=optional,\ org.newsclub.net.unix;resolution:=optional,\ org.ietf.jgss;resolution:=optional,\ @@ -684,6 +684,26 @@ + + net.revelc.code + impsort-maven-plugin + 1.12.0 + + true + + ${project.build.sourceDirectory} + ${project.build.testSourceDirectory} + ${project.basedir}/examples + ${project.basedir}/src/main/java9 + ${project.basedir}/src/main/java10 + ${project.basedir}/src/main/java11 + ${project.basedir}/src/main/java15 + ${project.basedir}/src/main/java16 + ${project.basedir}/src/main/java24 + ${project.basedir}/src/main/java-templates + + + org.jacoco jacoco-maven-plugin @@ -856,6 +876,18 @@ + + net.revelc.code + impsort-maven-plugin + + + sort-imports + + sort + + + + @@ -878,6 +910,18 @@ + + net.revelc.code + impsort-maven-plugin + + + verify + + check + + + + diff --git a/src/main/java/com/jcraft/jsch/JSch.java b/src/main/java/com/jcraft/jsch/JSch.java index 40b9d323..406d7e28 100644 --- a/src/main/java/com/jcraft/jsch/JSch.java +++ b/src/main/java/com/jcraft/jsch/JSch.java @@ -460,7 +460,7 @@ public HostKeyRepository getHostKeyRepository() { * * @param prvkey filename of the private key. * @throws JSchException if prvkey is invalid. - * @see #addIdentity(String prvkey, String passphrase) + * @see #addIdentity(String prvkey, byte[] passphrase) */ public void addIdentity(String prvkey) throws JSchException { addIdentity(prvkey, (byte[]) null); @@ -474,7 +474,9 @@ public void addIdentity(String prvkey) throws JSchException { * @param passphrase passphrase for prvkey. * @throws JSchException if passphrase is not right. * @see #addIdentity(String prvkey, byte[] passphrase) + * @deprecated use #addIdentity(String prvkey, byte[] passphrase) */ + @Deprecated public void addIdentity(String prvkey, String passphrase) throws JSchException { byte[] _passphrase = null; if (passphrase != null) { diff --git a/src/main/java/com/jcraft/jsch/KeyPair.java b/src/main/java/com/jcraft/jsch/KeyPair.java index 6f9fb3bf..383b856b 100644 --- a/src/main/java/com/jcraft/jsch/KeyPair.java +++ b/src/main/java/com/jcraft/jsch/KeyPair.java @@ -919,6 +919,10 @@ public boolean isEncrypted() { return encrypted; } + /** + * @deprecated use #decrypt(byte[] _passphrase) + */ + @Deprecated public boolean decrypt(String _passphrase) { if (_passphrase == null || _passphrase.length() == 0) { return !encrypted; diff --git a/src/main/java/com/jcraft/jsch/OpenSshCertificateParser.java b/src/main/java/com/jcraft/jsch/OpenSshCertificateParser.java index 5f1464f0..1875ae8d 100644 --- a/src/main/java/com/jcraft/jsch/OpenSshCertificateParser.java +++ b/src/main/java/com/jcraft/jsch/OpenSshCertificateParser.java @@ -1,7 +1,6 @@ package com.jcraft.jsch; import com.jcraft.jsch.JSch.InstanceLogger; - import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.Collection; diff --git a/src/main/java/com/jcraft/jsch/OpenSshCertificateUtil.java b/src/main/java/com/jcraft/jsch/OpenSshCertificateUtil.java index 65ef372d..c8427ee4 100644 --- a/src/main/java/com/jcraft/jsch/OpenSshCertificateUtil.java +++ b/src/main/java/com/jcraft/jsch/OpenSshCertificateUtil.java @@ -1,6 +1,5 @@ package com.jcraft.jsch; -import java.nio.charset.StandardCharsets; import java.time.Instant; import java.util.ArrayList; import java.util.Arrays; @@ -11,7 +10,6 @@ import java.util.Map; import java.util.Objects; import java.util.Set; - import java.util.stream.Collectors; class OpenSshCertificateUtil { diff --git a/src/main/java/com/jcraft/jsch/Session.java b/src/main/java/com/jcraft/jsch/Session.java index 9ce63a6c..1fb5639a 100644 --- a/src/main/java/com/jcraft/jsch/Session.java +++ b/src/main/java/com/jcraft/jsch/Session.java @@ -26,7 +26,6 @@ package com.jcraft.jsch; - import java.io.IOException; import java.io.InputStream; import java.io.InterruptedIOException; @@ -2998,6 +2997,10 @@ public void setX11Cookie(String cookie) { ChannelX11.setCookie(cookie); } + /** + * @deprecated use #setPassword(byte[] password) + */ + @Deprecated public void setPassword(String password) { if (password != null) this.password = Util.str2byte(password); diff --git a/src/main/java/com/jcraft/jsch/bc/MLKEM.java b/src/main/java/com/jcraft/jsch/bc/MLKEM.java index 13742fc9..1ae751da 100644 --- a/src/main/java/com/jcraft/jsch/bc/MLKEM.java +++ b/src/main/java/com/jcraft/jsch/bc/MLKEM.java @@ -29,12 +29,12 @@ import com.jcraft.jsch.KEM; import java.security.SecureRandom; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; -import org.bouncycastle.pqc.crypto.mlkem.MLKEMExtractor; -import org.bouncycastle.pqc.crypto.mlkem.MLKEMKeyGenerationParameters; -import org.bouncycastle.pqc.crypto.mlkem.MLKEMKeyPairGenerator; -import org.bouncycastle.pqc.crypto.mlkem.MLKEMParameters; -import org.bouncycastle.pqc.crypto.mlkem.MLKEMPrivateKeyParameters; -import org.bouncycastle.pqc.crypto.mlkem.MLKEMPublicKeyParameters; +import org.bouncycastle.crypto.generators.MLKEMKeyPairGenerator; +import org.bouncycastle.crypto.kems.MLKEMExtractor; +import org.bouncycastle.crypto.params.MLKEMKeyGenerationParameters; +import org.bouncycastle.crypto.params.MLKEMParameters; +import org.bouncycastle.crypto.params.MLKEMPrivateKeyParameters; +import org.bouncycastle.crypto.params.MLKEMPublicKeyParameters; abstract class MLKEM implements KEM { protected MLKEMParameters params; diff --git a/src/main/java/com/jcraft/jsch/bc/MLKEM1024.java b/src/main/java/com/jcraft/jsch/bc/MLKEM1024.java index 6fa6affe..4d287854 100644 --- a/src/main/java/com/jcraft/jsch/bc/MLKEM1024.java +++ b/src/main/java/com/jcraft/jsch/bc/MLKEM1024.java @@ -26,7 +26,7 @@ package com.jcraft.jsch.bc; -import org.bouncycastle.pqc.crypto.mlkem.MLKEMParameters; +import org.bouncycastle.crypto.params.MLKEMParameters; public class MLKEM1024 extends MLKEM { public MLKEM1024() { diff --git a/src/main/java/com/jcraft/jsch/bc/MLKEM768.java b/src/main/java/com/jcraft/jsch/bc/MLKEM768.java index 6697bb20..c2f9b4de 100644 --- a/src/main/java/com/jcraft/jsch/bc/MLKEM768.java +++ b/src/main/java/com/jcraft/jsch/bc/MLKEM768.java @@ -26,7 +26,7 @@ package com.jcraft.jsch.bc; -import org.bouncycastle.pqc.crypto.mlkem.MLKEMParameters; +import org.bouncycastle.crypto.params.MLKEMParameters; public class MLKEM768 extends MLKEM { public MLKEM768() { diff --git a/src/main/java24/com/jcraft/jsch/jce/MLKEM.java b/src/main/java24/com/jcraft/jsch/jce/MLKEM.java index ab86a48b..1195ae75 100644 --- a/src/main/java24/com/jcraft/jsch/jce/MLKEM.java +++ b/src/main/java24/com/jcraft/jsch/jce/MLKEM.java @@ -28,11 +28,7 @@ import java.security.KeyPair; import java.security.KeyPairGenerator; -import java.security.PublicKey; import java.security.spec.NamedParameterSpec; -import java.util.Arrays; -import java.util.ArrayList; -import java.util.List; import javax.crypto.KEM; abstract class MLKEM implements com.jcraft.jsch.KEM { diff --git a/src/test/java/com/jcraft/jsch/HostCertificateDssIT.java b/src/test/java/com/jcraft/jsch/HostCertificateDssIT.java index 83eda07a..46e1d403 100644 --- a/src/test/java/com/jcraft/jsch/HostCertificateDssIT.java +++ b/src/test/java/com/jcraft/jsch/HostCertificateDssIT.java @@ -5,15 +5,14 @@ import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; +import com.github.valfirst.slf4jtest.LoggingEvent; +import com.github.valfirst.slf4jtest.TestLogger; +import com.github.valfirst.slf4jtest.TestLoggerFactory; import java.io.ByteArrayInputStream; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Paths; - -import com.github.valfirst.slf4jtest.LoggingEvent; -import com.github.valfirst.slf4jtest.TestLogger; -import com.github.valfirst.slf4jtest.TestLoggerFactory; import org.junit.jupiter.api.Test; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.wait.strategy.Wait; @@ -25,8 +24,8 @@ * Integration tests for {@code ssh-dss-cert-v01@openssh.com} host certificate validation. * * These tests verify that JSch correctly validates a host certificate whose underlying key - * algorithm is DSA ({@code ssh-dss-cert-v01@openssh.com}). The server runs Alpine 3.5 with OpenSSH - * 7.4, which is required because modern OpenSSH (9.8+) removed DSA support. + * algorithm is DSA ({@code ssh-dss-cert-v01@openssh.com}). The server runs Alpine 3.7 with OpenSSH + * 7.5, which is required because modern OpenSSH (9.8+) removed DSA support. * * * The DSA certificate is signed by an Ed25519 CA, so the client-side CA signature verification does @@ -46,7 +45,7 @@ public class HostCertificateDssIT { TestLoggerFactory.getTestLogger(HostCertificateDssIT.class); /** - * OpenSSH 7.4 (Alpine 3.5) container configured to serve a DSA host certificate + * OpenSSH 7.5 (Alpine 3.7) container configured to serve a DSA host certificate * ({@code ssh-dss-cert-v01@openssh.com}). The certificate is signed by an Ed25519 CA whose public * key is in the client's {@code known_hosts} file with the {@code @cert-authority} marker. *

diff --git a/src/test/java/com/jcraft/jsch/HostCertificateEd448IT.java b/src/test/java/com/jcraft/jsch/HostCertificateEd448IT.java index 53824200..5514e07c 100644 --- a/src/test/java/com/jcraft/jsch/HostCertificateEd448IT.java +++ b/src/test/java/com/jcraft/jsch/HostCertificateEd448IT.java @@ -6,15 +6,14 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.condition.JRE.JAVA_15; +import com.github.valfirst.slf4jtest.LoggingEvent; +import com.github.valfirst.slf4jtest.TestLogger; +import com.github.valfirst.slf4jtest.TestLoggerFactory; import java.io.ByteArrayInputStream; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Paths; - -import com.github.valfirst.slf4jtest.LoggingEvent; -import com.github.valfirst.slf4jtest.TestLogger; -import com.github.valfirst.slf4jtest.TestLoggerFactory; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.condition.EnabledForJreRange; import org.testcontainers.containers.GenericContainer; diff --git a/src/test/java/com/jcraft/jsch/HostCertificateIT.java b/src/test/java/com/jcraft/jsch/HostCertificateIT.java index 99619a7e..39c7d410 100644 --- a/src/test/java/com/jcraft/jsch/HostCertificateIT.java +++ b/src/test/java/com/jcraft/jsch/HostCertificateIT.java @@ -6,6 +6,9 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.condition.JRE.JAVA_15; +import com.github.valfirst.slf4jtest.LoggingEvent; +import com.github.valfirst.slf4jtest.TestLogger; +import com.github.valfirst.slf4jtest.TestLoggerFactory; import java.io.ByteArrayInputStream; import java.io.IOException; import java.nio.charset.StandardCharsets; @@ -13,12 +16,6 @@ import java.nio.file.Paths; import java.util.Arrays; import java.util.List; - -import com.github.valfirst.slf4jtest.LoggingEvent; -import com.github.valfirst.slf4jtest.TestLogger; -import com.github.valfirst.slf4jtest.TestLoggerFactory; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.condition.EnabledForJreRange; import org.junit.jupiter.params.ParameterizedTest; diff --git a/src/test/java/com/jcraft/jsch/JSchTest.java b/src/test/java/com/jcraft/jsch/JSchTest.java index a2d2d2b6..066d3c57 100644 --- a/src/test/java/com/jcraft/jsch/JSchTest.java +++ b/src/test/java/com/jcraft/jsch/JSchTest.java @@ -6,7 +6,6 @@ import java.util.Hashtable; import java.util.Map; - import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/jcraft/jsch/KeyPair2IT.java b/src/test/java/com/jcraft/jsch/KeyPair2IT.java index ba381ca0..55f4b413 100644 --- a/src/test/java/com/jcraft/jsch/KeyPair2IT.java +++ b/src/test/java/com/jcraft/jsch/KeyPair2IT.java @@ -6,7 +6,6 @@ import static org.junit.jupiter.api.condition.JRE.JAVA_15; import java.net.URISyntaxException; -import java.io.OutputStream; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; @@ -81,7 +80,7 @@ static Stream java15WriteOpenSSHv1KeyArgs() { @ParameterizedTest @MethodSource("com.jcraft.jsch.KeyPair2Test#keyArgs") - void connectWithPublicKey(String path, String password, String keyType) throws Exception { + void connectWithPublicKey(String path, byte[] password, String keyType) throws Exception { final JSch jSch = createIdentity(path, password); @@ -100,7 +99,7 @@ void connectWithPublicKey(String path, String password, String keyType) throws E @ParameterizedTest @MethodSource("com.jcraft.jsch.KeyPair2Test#keyArgs") - void connectWithPublicKeyAndUserInfo(String path, String password, String keyType) + void connectWithPublicKeyAndUserInfo(String path, byte[] password, String keyType) throws Exception { final JSch jSch = new JSch(); @@ -112,7 +111,7 @@ void connectWithPublicKeyAndUserInfo(String path, String password, String keyTyp session.setUserInfo(new UserInfo() { @Override public String getPassphrase() { - return password; + return Util.byte2str(password); } @Override @@ -206,7 +205,7 @@ void _writeOpenSSHv1Keys(KeyPair kp, String name, byte[] passphrase, String ciph } } - private JSch createIdentity(String path, String password) + private JSch createIdentity(String path, byte[] password) throws JSchException, URISyntaxException { JSch ssh = new JSch(); if (password != null) { diff --git a/src/test/java/com/jcraft/jsch/KeyPair2Test.java b/src/test/java/com/jcraft/jsch/KeyPair2Test.java index 22fad28f..9fbde6be 100644 --- a/src/test/java/com/jcraft/jsch/KeyPair2Test.java +++ b/src/test/java/com/jcraft/jsch/KeyPair2Test.java @@ -1,5 +1,6 @@ package com.jcraft.jsch; +import static java.nio.charset.StandardCharsets.UTF_8; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -23,22 +24,22 @@ static Stream keyArgs() { return Stream.of( // PuTTY v2 keys Arguments.of("ppkv2_ed448_unix.ppk", null, "ssh-ed448"), - Arguments.of("ppkv2_ed448_unix_encrypted.ppk", "secret123", "ssh-ed448"), + Arguments.of("ppkv2_ed448_unix_encrypted.ppk", "secret123".getBytes(UTF_8), "ssh-ed448"), Arguments.of("ppkv2_ed448_windows.ppk", null, "ssh-ed448"), - Arguments.of("ppkv2_ed448_windows_encrypted.ppk", "secret123", "ssh-ed448"), + Arguments.of("ppkv2_ed448_windows_encrypted.ppk", "secret123".getBytes(UTF_8), "ssh-ed448"), // PuTTY v3 keys Arguments.of("ppkv3_ed448_unix.ppk", null, "ssh-ed448"), - Arguments.of("ppkv3_ed448_unix_encrypted.ppk", "secret123", "ssh-ed448"), + Arguments.of("ppkv3_ed448_unix_encrypted.ppk", "secret123".getBytes(UTF_8), "ssh-ed448"), Arguments.of("ppkv3_ed448_windows.ppk", null, "ssh-ed448"), - Arguments.of("ppkv3_ed448_windows_encrypted.ppk", "secret123", "ssh-ed448"), + Arguments.of("ppkv3_ed448_windows_encrypted.ppk", "secret123".getBytes(UTF_8), "ssh-ed448"), // PKCS8 keys Arguments.of("pkcs8_ed448", null, "ssh-ed448"), - Arguments.of("pkcs8_ed448_encrypted_scrypt", "secret123", "ssh-ed448")); + Arguments.of("pkcs8_ed448_encrypted_scrypt", "secret123".getBytes(UTF_8), "ssh-ed448")); } @ParameterizedTest @MethodSource("keyArgs") - void loadKey(String path, String password, String keyType) + void loadKey(String path, byte[] password, String keyType) throws URISyntaxException, JSchException { final JSch jSch = new JSch(); final String prvkey = diff --git a/src/test/java/com/jcraft/jsch/KeyPairIT.java b/src/test/java/com/jcraft/jsch/KeyPairIT.java index fe7f0be4..b8394305 100644 --- a/src/test/java/com/jcraft/jsch/KeyPairIT.java +++ b/src/test/java/com/jcraft/jsch/KeyPairIT.java @@ -6,7 +6,6 @@ import static org.junit.jupiter.api.condition.JRE.JAVA_15; import java.net.URISyntaxException; -import java.io.OutputStream; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; @@ -91,7 +90,7 @@ static Stream java15WriteOpenSSHv1KeyArgs() { @ParameterizedTest @MethodSource("com.jcraft.jsch.KeyPairTest#keyArgs") - void connectWithPublicKey(String path, String password, String keyType) throws Exception { + void connectWithPublicKey(String path, byte[] password, String keyType) throws Exception { final JSch jSch = createIdentity(path, password); @@ -110,7 +109,7 @@ void connectWithPublicKey(String path, String password, String keyType) throws E @ParameterizedTest @MethodSource("com.jcraft.jsch.KeyPairTest#keyArgs") - void connectWithPublicKeyAndUserInfo(String path, String password, String keyType) + void connectWithPublicKeyAndUserInfo(String path, byte[] password, String keyType) throws Exception { final JSch jSch = new JSch(); @@ -122,7 +121,7 @@ void connectWithPublicKeyAndUserInfo(String path, String password, String keyTyp session.setUserInfo(new UserInfo() { @Override public String getPassphrase() { - return password; + return Util.byte2str(password); } @Override @@ -224,7 +223,7 @@ void _writeOpenSSHv1Keys(KeyPair kp, String name, byte[] passphrase, String ciph } } - private JSch createIdentity(String path, String password) + private JSch createIdentity(String path, byte[] password) throws JSchException, URISyntaxException { JSch ssh = new JSch(); if (password != null) { diff --git a/src/test/java/com/jcraft/jsch/KeyPairTest.java b/src/test/java/com/jcraft/jsch/KeyPairTest.java index cdbaa3f5..5e99860f 100644 --- a/src/test/java/com/jcraft/jsch/KeyPairTest.java +++ b/src/test/java/com/jcraft/jsch/KeyPairTest.java @@ -31,23 +31,27 @@ static Stream keyArgs() { // docker/ssh_host_rsa_key openssh format Arguments.of("docker/ssh_host_rsa_key", null, "ssh-rsa"), // encrypted_openssh_private_key_rsa - Arguments.of("encrypted_openssh_private_key_rsa", "secret123", "ssh-rsa"), - Arguments.of("encrypted_openssh_private_key_rsa_aes256gcm", "secret123", "ssh-rsa"), - Arguments.of("encrypted_openssh_private_key_rsa_chacha20poly1305", "secret123", "ssh-rsa"), + Arguments.of("encrypted_openssh_private_key_rsa", "secret123".getBytes(UTF_8), "ssh-rsa"), + Arguments.of("encrypted_openssh_private_key_rsa_aes256gcm", "secret123".getBytes(UTF_8), + "ssh-rsa"), + Arguments.of("encrypted_openssh_private_key_rsa_chacha20poly1305", + "secret123".getBytes(UTF_8), "ssh-rsa"), // docker/id_dsa Arguments.of("docker/id_dsa", null, "ssh-dss"), // dsa openssh format Arguments.of("docker/ssh_host_dsa_key", null, "ssh-dss"), // encrypted dsa - Arguments.of("encrypted_openssh_private_key_dsa", "secret123", "ssh-dss"), - Arguments.of("encrypted_openssh_private_key_dsa_aes256gcm", "secret123", "ssh-dss"), - Arguments.of("encrypted_openssh_private_key_dsa_chacha20poly1305", "secret123", "ssh-dss"), + Arguments.of("encrypted_openssh_private_key_dsa", "secret123".getBytes(UTF_8), "ssh-dss"), + Arguments.of("encrypted_openssh_private_key_dsa_aes256gcm", "secret123".getBytes(UTF_8), + "ssh-dss"), + Arguments.of("encrypted_openssh_private_key_dsa_chacha20poly1305", + "secret123".getBytes(UTF_8), "ssh-dss"), // unencrypted RSA with windows (\r\n) line endings Arguments.of("issue362_rsa", null, "ssh-rsa"), Arguments.of("issue_369_rsa_opensshv1", null, "ssh-rsa"), Arguments.of("issue_369_rsa_pem", null, "ssh-rsa"), - Arguments.of("encrypted_issue_369_rsa_opensshv1", "secret123", "ssh-rsa"), - Arguments.of("encrypted_issue_369_rsa_pem", "secret123", "ssh-rsa"), + Arguments.of("encrypted_issue_369_rsa_opensshv1", "secret123".getBytes(UTF_8), "ssh-rsa"), + Arguments.of("encrypted_issue_369_rsa_pem", "secret123".getBytes(UTF_8), "ssh-rsa"), // ecdsa EC private key format Arguments.of("docker/id_ecdsa256", null, "ecdsa-sha2-nistp256"), // Arguments.of("docker/id_ecdsa384", null, "ecdsa-sha2-nistp384"), // @@ -56,86 +60,108 @@ static Stream keyArgs() { Arguments.of("docker/ssh_host_ecdsa384_key", null, "ecdsa-sha2-nistp384"), Arguments.of("docker/ssh_host_ecdsa521_key", null, "ecdsa-sha2-nistp521"), // encrypted ecdsa - Arguments.of("encrypted_openssh_private_key_ecdsa", "secret123", "ecdsa-sha2-nistp256"), - Arguments.of("encrypted_openssh_private_key_ecdsa_aes256gcm", "secret123", + Arguments.of("encrypted_openssh_private_key_ecdsa", "secret123".getBytes(UTF_8), "ecdsa-sha2-nistp256"), - Arguments.of("encrypted_openssh_private_key_ecdsa_chacha20poly1305", "secret123", + Arguments.of("encrypted_openssh_private_key_ecdsa_aes256gcm", "secret123".getBytes(UTF_8), "ecdsa-sha2-nistp256"), + Arguments.of("encrypted_openssh_private_key_ecdsa_chacha20poly1305", + "secret123".getBytes(UTF_8), "ecdsa-sha2-nistp256"), // encrypted ed25519 - Arguments.of("encrypted_openssh_private_key_ed25519", "secret123", "ssh-ed25519"), - Arguments.of("encrypted_openssh_private_key_ed25519_aes256gcm", "secret123", "ssh-ed25519"), - Arguments.of("encrypted_openssh_private_key_ed25519_chacha20poly1305", "secret123", + Arguments.of("encrypted_openssh_private_key_ed25519", "secret123".getBytes(UTF_8), "ssh-ed25519"), + Arguments.of("encrypted_openssh_private_key_ed25519_aes256gcm", "secret123".getBytes(UTF_8), + "ssh-ed25519"), + Arguments.of("encrypted_openssh_private_key_ed25519_chacha20poly1305", + "secret123".getBytes(UTF_8), "ssh-ed25519"), // PuTTY v2 keys Arguments.of("ppkv2_dsa_unix.ppk", null, "ssh-dss"), - Arguments.of("ppkv2_dsa_unix_encrypted.ppk", "secret123", "ssh-dss"), + Arguments.of("ppkv2_dsa_unix_encrypted.ppk", "secret123".getBytes(UTF_8), "ssh-dss"), Arguments.of("ppkv2_dsa_windows.ppk", null, "ssh-dss"), - Arguments.of("ppkv2_dsa_windows_encrypted.ppk", "secret123", "ssh-dss"), + Arguments.of("ppkv2_dsa_windows_encrypted.ppk", "secret123".getBytes(UTF_8), "ssh-dss"), Arguments.of("ppkv2_rsa_unix.ppk", null, "ssh-rsa"), - Arguments.of("ppkv2_rsa_unix_encrypted.ppk", "secret123", "ssh-rsa"), + Arguments.of("ppkv2_rsa_unix_encrypted.ppk", "secret123".getBytes(UTF_8), "ssh-rsa"), Arguments.of("ppkv2_rsa_windows.ppk", null, "ssh-rsa"), - Arguments.of("ppkv2_rsa_windows_encrypted.ppk", "secret123", "ssh-rsa"), + Arguments.of("ppkv2_rsa_windows_encrypted.ppk", "secret123".getBytes(UTF_8), "ssh-rsa"), Arguments.of("ppkv2_ecdsa256_unix.ppk", null, "ecdsa-sha2-nistp256"), - Arguments.of("ppkv2_ecdsa256_unix_encrypted.ppk", "secret123", "ecdsa-sha2-nistp256"), + Arguments.of("ppkv2_ecdsa256_unix_encrypted.ppk", "secret123".getBytes(UTF_8), + "ecdsa-sha2-nistp256"), Arguments.of("ppkv2_ecdsa384_unix.ppk", null, "ecdsa-sha2-nistp384"), - Arguments.of("ppkv2_ecdsa384_unix_encrypted.ppk", "secret123", "ecdsa-sha2-nistp384"), + Arguments.of("ppkv2_ecdsa384_unix_encrypted.ppk", "secret123".getBytes(UTF_8), + "ecdsa-sha2-nistp384"), Arguments.of("ppkv2_ecdsa521_unix.ppk", null, "ecdsa-sha2-nistp521"), - Arguments.of("ppkv2_ecdsa521_unix_encrypted.ppk", "secret123", "ecdsa-sha2-nistp521"), + Arguments.of("ppkv2_ecdsa521_unix_encrypted.ppk", "secret123".getBytes(UTF_8), + "ecdsa-sha2-nistp521"), Arguments.of("ppkv2_ecdsa256_windows.ppk", null, "ecdsa-sha2-nistp256"), - Arguments.of("ppkv2_ecdsa256_windows_encrypted.ppk", "secret123", "ecdsa-sha2-nistp256"), + Arguments.of("ppkv2_ecdsa256_windows_encrypted.ppk", "secret123".getBytes(UTF_8), + "ecdsa-sha2-nistp256"), Arguments.of("ppkv2_ecdsa384_windows.ppk", null, "ecdsa-sha2-nistp384"), - Arguments.of("ppkv2_ecdsa384_windows_encrypted.ppk", "secret123", "ecdsa-sha2-nistp384"), + Arguments.of("ppkv2_ecdsa384_windows_encrypted.ppk", "secret123".getBytes(UTF_8), + "ecdsa-sha2-nistp384"), Arguments.of("ppkv2_ecdsa521_windows.ppk", null, "ecdsa-sha2-nistp521"), - Arguments.of("ppkv2_ecdsa521_windows_encrypted.ppk", "secret123", "ecdsa-sha2-nistp521"), + Arguments.of("ppkv2_ecdsa521_windows_encrypted.ppk", "secret123".getBytes(UTF_8), + "ecdsa-sha2-nistp521"), Arguments.of("ppkv2_ed25519_unix.ppk", null, "ssh-ed25519"), - Arguments.of("ppkv2_ed25519_unix_encrypted.ppk", "secret123", "ssh-ed25519"), + Arguments + .of("ppkv2_ed25519_unix_encrypted.ppk", "secret123".getBytes(UTF_8), "ssh-ed25519"), Arguments.of("ppkv2_ed25519_windows.ppk", null, "ssh-ed25519"), - Arguments.of("ppkv2_ed25519_windows_encrypted.ppk", "secret123", "ssh-ed25519"), + Arguments.of("ppkv2_ed25519_windows_encrypted.ppk", "secret123".getBytes(UTF_8), + "ssh-ed25519"), // PuTTY v3 keys Arguments.of("ppkv3_dsa_unix.ppk", null, "ssh-dss"), - Arguments.of("ppkv3_dsa_unix_encrypted.ppk", "secret123", "ssh-dss"), + Arguments.of("ppkv3_dsa_unix_encrypted.ppk", "secret123".getBytes(UTF_8), "ssh-dss"), Arguments.of("ppkv3_dsa_windows.ppk", null, "ssh-dss"), - Arguments.of("ppkv3_dsa_windows_encrypted.ppk", "secret123", "ssh-dss"), + Arguments.of("ppkv3_dsa_windows_encrypted.ppk", "secret123".getBytes(UTF_8), "ssh-dss"), Arguments.of("ppkv3_rsa_unix.ppk", null, "ssh-rsa"), - Arguments.of("ppkv3_rsa_unix_encrypted.ppk", "secret123", "ssh-rsa"), + Arguments.of("ppkv3_rsa_unix_encrypted.ppk", "secret123".getBytes(UTF_8), "ssh-rsa"), Arguments.of("ppkv3_rsa_windows.ppk", null, "ssh-rsa"), - Arguments.of("ppkv3_rsa_windows_encrypted.ppk", "secret123", "ssh-rsa"), + Arguments.of("ppkv3_rsa_windows_encrypted.ppk", "secret123".getBytes(UTF_8), "ssh-rsa"), Arguments.of("ppkv3_ecdsa256_unix.ppk", null, "ecdsa-sha2-nistp256"), - Arguments.of("ppkv3_ecdsa256_unix_encrypted.ppk", "secret123", "ecdsa-sha2-nistp256"), + Arguments.of("ppkv3_ecdsa256_unix_encrypted.ppk", "secret123".getBytes(UTF_8), + "ecdsa-sha2-nistp256"), Arguments.of("ppkv3_ecdsa384_unix.ppk", null, "ecdsa-sha2-nistp384"), - Arguments.of("ppkv3_ecdsa384_unix_encrypted.ppk", "secret123", "ecdsa-sha2-nistp384"), + Arguments.of("ppkv3_ecdsa384_unix_encrypted.ppk", "secret123".getBytes(UTF_8), + "ecdsa-sha2-nistp384"), Arguments.of("ppkv3_ecdsa521_unix.ppk", null, "ecdsa-sha2-nistp521"), - Arguments.of("ppkv3_ecdsa521_unix_encrypted.ppk", "secret123", "ecdsa-sha2-nistp521"), + Arguments.of("ppkv3_ecdsa521_unix_encrypted.ppk", "secret123".getBytes(UTF_8), + "ecdsa-sha2-nistp521"), Arguments.of("ppkv3_ecdsa256_windows.ppk", null, "ecdsa-sha2-nistp256"), - Arguments.of("ppkv3_ecdsa256_windows_encrypted.ppk", "secret123", "ecdsa-sha2-nistp256"), + Arguments.of("ppkv3_ecdsa256_windows_encrypted.ppk", "secret123".getBytes(UTF_8), + "ecdsa-sha2-nistp256"), Arguments.of("ppkv3_ecdsa384_windows.ppk", null, "ecdsa-sha2-nistp384"), - Arguments.of("ppkv3_ecdsa384_windows_encrypted.ppk", "secret123", "ecdsa-sha2-nistp384"), + Arguments.of("ppkv3_ecdsa384_windows_encrypted.ppk", "secret123".getBytes(UTF_8), + "ecdsa-sha2-nistp384"), Arguments.of("ppkv3_ecdsa521_windows.ppk", null, "ecdsa-sha2-nistp521"), - Arguments.of("ppkv3_ecdsa521_windows_encrypted.ppk", "secret123", "ecdsa-sha2-nistp521"), + Arguments.of("ppkv3_ecdsa521_windows_encrypted.ppk", "secret123".getBytes(UTF_8), + "ecdsa-sha2-nistp521"), Arguments.of("ppkv3_ed25519_unix.ppk", null, "ssh-ed25519"), - Arguments.of("ppkv3_ed25519_unix_encrypted.ppk", "secret123", "ssh-ed25519"), + Arguments + .of("ppkv3_ed25519_unix_encrypted.ppk", "secret123".getBytes(UTF_8), "ssh-ed25519"), Arguments.of("ppkv3_ed25519_windows.ppk", null, "ssh-ed25519"), - Arguments.of("ppkv3_ed25519_windows_encrypted.ppk", "secret123", "ssh-ed25519"), + Arguments.of("ppkv3_ed25519_windows_encrypted.ppk", "secret123".getBytes(UTF_8), + "ssh-ed25519"), // PKCS8 keys Arguments.of("pkcs8_dsa", null, "ssh-dss"), - Arguments.of("pkcs8_dsa_encrypted_hmacsha1", "secret123", "ssh-dss"), - Arguments.of("pkcs8_dsa_encrypted_hmacsha256", "secret123", "ssh-dss"), + Arguments.of("pkcs8_dsa_encrypted_hmacsha1", "secret123".getBytes(UTF_8), "ssh-dss"), + Arguments.of("pkcs8_dsa_encrypted_hmacsha256", "secret123".getBytes(UTF_8), "ssh-dss"), Arguments.of("pkcs8_rsa", null, "ssh-rsa"), - Arguments.of("pkcs8_rsa_encrypted_hmacsha1", "secret123", "ssh-rsa"), - Arguments.of("pkcs8_rsa_encrypted_hmacsha256", "secret123", "ssh-rsa"), + Arguments.of("pkcs8_rsa_encrypted_hmacsha1", "secret123".getBytes(UTF_8), "ssh-rsa"), + Arguments.of("pkcs8_rsa_encrypted_hmacsha256", "secret123".getBytes(UTF_8), "ssh-rsa"), Arguments.of("pkcs8_ecdsa256", null, "ecdsa-sha2-nistp256"), - Arguments.of("pkcs8_ecdsa256_encrypted_scrypt", "secret123", "ecdsa-sha2-nistp256"), + Arguments.of( + "pkcs8_ecdsa256_encrypted_scrypt", "secret123".getBytes(UTF_8), "ecdsa-sha2-nistp256"), Arguments.of("pkcs8_ecdsa384", null, "ecdsa-sha2-nistp384"), - Arguments.of("pkcs8_ecdsa384_encrypted_scrypt", "secret123", "ecdsa-sha2-nistp384"), + Arguments.of( + "pkcs8_ecdsa384_encrypted_scrypt", "secret123".getBytes(UTF_8), "ecdsa-sha2-nistp384"), Arguments.of("pkcs8_ecdsa521", null, "ecdsa-sha2-nistp521"), - Arguments.of("pkcs8_ecdsa521_encrypted_scrypt", "secret123", "ecdsa-sha2-nistp521"), + Arguments.of("pkcs8_ecdsa521_encrypted_scrypt", "secret123".getBytes(UTF_8), + "ecdsa-sha2-nistp521"), Arguments.of("pkcs8_ed25519", null, "ssh-ed25519"), - Arguments.of("pkcs8_ed25519_encrypted_scrypt", "secret123", "ssh-ed25519")); + Arguments.of("pkcs8_ed25519_encrypted_scrypt", "secret123".getBytes(UTF_8), "ssh-ed25519")); } @ParameterizedTest @MethodSource("keyArgs") - void loadKey(String path, String password, String keyType) + void loadKey(String path, byte[] password, String keyType) throws URISyntaxException, JSchException { final JSch jSch = new JSch(); final String prvkey = @@ -188,7 +214,7 @@ void decryptEncryptedOpensshKey(String keyFile) throws URISyntaxException, JSchE IdentityFile identity = IdentityFile.newInstance(prvkey, null, jSch.instLogger); // Decrypt the key file - assertTrue(identity.getKeyPair().decrypt("secret123")); + assertTrue(identity.getKeyPair().decrypt("secret123".getBytes(UTF_8))); // From now on, the pair now longer counts as encrypted assertFalse(identity.getKeyPair().isEncrypted()); @@ -196,6 +222,5 @@ void decryptEncryptedOpensshKey(String keyFile) throws URISyntaxException, JSchE // An unencrypted key pair should allow #decrypt(null) // com.jcraft.jsch.UserAuthPublicKey relies on this assertTrue(identity.getKeyPair().decrypt((byte[]) null)); - assertTrue(identity.getKeyPair().decrypt((String) null)); } } diff --git a/src/test/java/com/jcraft/jsch/OpenSshCertificateAwareIdentityFileTest.java b/src/test/java/com/jcraft/jsch/OpenSshCertificateAwareIdentityFileTest.java index 594e66a1..8c881a1c 100644 --- a/src/test/java/com/jcraft/jsch/OpenSshCertificateAwareIdentityFileTest.java +++ b/src/test/java/com/jcraft/jsch/OpenSshCertificateAwareIdentityFileTest.java @@ -8,7 +8,6 @@ import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.Locale; - import org.junit.jupiter.api.Test; public class OpenSshCertificateAwareIdentityFileTest { diff --git a/src/test/java/com/jcraft/jsch/OpenSshCertificateHostKeyVerifierTest.java b/src/test/java/com/jcraft/jsch/OpenSshCertificateHostKeyVerifierTest.java index 0325a976..449c7256 100644 --- a/src/test/java/com/jcraft/jsch/OpenSshCertificateHostKeyVerifierTest.java +++ b/src/test/java/com/jcraft/jsch/OpenSshCertificateHostKeyVerifierTest.java @@ -1,8 +1,6 @@ package com.jcraft.jsch; -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; import java.util.Arrays; diff --git a/src/test/java/com/jcraft/jsch/OpenSshCertificateUtilTest.java b/src/test/java/com/jcraft/jsch/OpenSshCertificateUtilTest.java index 82ae8c27..877aa6c9 100644 --- a/src/test/java/com/jcraft/jsch/OpenSshCertificateUtilTest.java +++ b/src/test/java/com/jcraft/jsch/OpenSshCertificateUtilTest.java @@ -8,10 +8,27 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import java.nio.charset.StandardCharsets; +import java.time.ZoneOffset; +import java.util.TimeZone; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; public class OpenSshCertificateUtilTest { + private static TimeZone timezone; + + @BeforeAll + public static void beforeAll() { + timezone = TimeZone.getDefault(); + TimeZone.setDefault(TimeZone.getTimeZone(ZoneOffset.UTC)); + } + + @AfterAll + public static void afterAll() { + TimeZone.setDefault(timezone); + } + @Test public void testExtractSpaceDelimitedString_nullInput() { assertNull(OpenSshCertificateUtil.extractSpaceDelimitedString(null, 0)); diff --git a/src/test/java/com/jcraft/jsch/SessionTest.java b/src/test/java/com/jcraft/jsch/SessionTest.java index cfc1b416..9e330e43 100644 --- a/src/test/java/com/jcraft/jsch/SessionTest.java +++ b/src/test/java/com/jcraft/jsch/SessionTest.java @@ -2,7 +2,6 @@ import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertSame; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -12,7 +11,6 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.CsvSource; import org.junit.jupiter.params.provider.MethodSource; class SessionTest { diff --git a/src/test/java/com/jcraft/jsch/UserCertAuthDssIT.java b/src/test/java/com/jcraft/jsch/UserCertAuthDssIT.java index 8f0c94fa..67fed2bc 100644 --- a/src/test/java/com/jcraft/jsch/UserCertAuthDssIT.java +++ b/src/test/java/com/jcraft/jsch/UserCertAuthDssIT.java @@ -20,7 +20,7 @@ * * These tests verify that JSch can authenticate to a server using an OpenSSH user certificate whose * underlying key algorithm is DSA ({@code ssh-dss-cert-v01@openssh.com}). The server runs Alpine - * 3.5 with OpenSSH 7.4 because DSA support was removed from OpenSSH 9.8+. + * 3.7 with OpenSSH 7.5 because DSA support was removed from OpenSSH 9.8+. * * * The DSA user certificate is signed by an Ed25519 CA; the server is configured with @@ -41,7 +41,7 @@ public class UserCertAuthDssIT { TestLoggerFactory.getTestLogger(UserCertAuthDssIT.class); /** - * OpenSSH 7.4 (Alpine 3.5) container configured to accept DSA user certificate authentication. + * OpenSSH 7.5 (Alpine 3.7) container configured to accept DSA user certificate authentication. * *

* The server uses {@code TrustedUserCAKeys} with the Ed25519 CA that signed the DSA user diff --git a/src/test/java/com/jcraft/jsch/UserCertAuthIT.java b/src/test/java/com/jcraft/jsch/UserCertAuthIT.java index d47f2823..aa6b09bc 100644 --- a/src/test/java/com/jcraft/jsch/UserCertAuthIT.java +++ b/src/test/java/com/jcraft/jsch/UserCertAuthIT.java @@ -2,6 +2,9 @@ import static org.junit.jupiter.api.condition.JRE.JAVA_15; +import com.github.valfirst.slf4jtest.LoggingEvent; +import com.github.valfirst.slf4jtest.TestLogger; +import com.github.valfirst.slf4jtest.TestLoggerFactory; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Paths; @@ -9,9 +12,6 @@ import java.util.Base64; import java.util.List; import java.util.Locale; -import com.github.valfirst.slf4jtest.LoggingEvent; -import com.github.valfirst.slf4jtest.TestLogger; -import com.github.valfirst.slf4jtest.TestLoggerFactory; import org.apache.commons.codec.digest.DigestUtils; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; @@ -26,7 +26,6 @@ import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; - /** * Integrated Test (IT) class to verify the JSch public key authentication mechanism using **OpenSSH * user certificates** against a Testcontainers-managed SSHD (SSH daemon) instance. diff --git a/src/test/resources/certificates/dss_host/Dockerfile b/src/test/resources/certificates/dss_host/Dockerfile index 852b729c..9b9044ff 100644 --- a/src/test/resources/certificates/dss_host/Dockerfile +++ b/src/test/resources/certificates/dss_host/Dockerfile @@ -1,4 +1,4 @@ -FROM alpine:3.5 +FROM alpine:3.7 RUN apk update && \ apk upgrade && \ apk add openssh bash && \ @@ -12,4 +12,5 @@ COPY ssh_host_dsa_key-cert.pub /etc/ssh/ssh_host_dsa_key-cert.pub COPY id_ecdsa_nistp521.pub /root/.ssh/authorized_keys RUN chmod 600 /etc/ssh/ssh_host_dsa_key /root/.ssh/authorized_keys && \ chmod +x /entrypoint.sh -ENTRYPOINT ["/entrypoint.sh"] \ No newline at end of file +RUN passwd -u root +ENTRYPOINT ["/entrypoint.sh"] diff --git a/src/test/resources/certificates/dss_user/Dockerfile b/src/test/resources/certificates/dss_user/Dockerfile index 1879a4f8..3e6b6ad8 100644 --- a/src/test/resources/certificates/dss_user/Dockerfile +++ b/src/test/resources/certificates/dss_user/Dockerfile @@ -1,4 +1,4 @@ -FROM alpine:3.5 +FROM alpine:3.7 RUN apk update && \ apk upgrade && \ apk add openssh bash && \ @@ -10,4 +10,5 @@ COPY entrypoint.sh /entrypoint.sh COPY ca_jsch_key.pub /etc/ssh/ca_jsch_key.pub RUN chmod 644 /etc/ssh/ca_jsch_key.pub && \ chmod +x /entrypoint.sh -ENTRYPOINT ["/entrypoint.sh"] \ No newline at end of file +RUN passwd -u root +ENTRYPOINT ["/entrypoint.sh"]