Merge "Remove JCraft JSch dependency"
diff --git a/Documentation/config-gerrit.txt b/Documentation/config-gerrit.txt
index cccbd7b..a56055a 100644
--- a/Documentation/config-gerrit.txt
+++ b/Documentation/config-gerrit.txt
@@ -4896,16 +4896,6 @@
   replicate = replication start
 ----
 
-[[ssh]]
-=== Section ssh
-
-[[ssh.clientImplementation]]ssh.clientImplementation::
-+
-JCraft JSch client is supported in addition to Apache MINA SSH client.
-To use JSch client set the value to `JSCH`.
-+
-By default, `APACHE`.
-
 [[sshd]]
 === Section sshd
 
diff --git a/Documentation/dev-bazel.txt b/Documentation/dev-bazel.txt
index c3237ed..4069446 100644
--- a/Documentation/dev-bazel.txt
+++ b/Documentation/dev-bazel.txt
@@ -317,18 +317,6 @@
   bazel test //javatests/com/google/gerrit/acceptance/rest/account:rest_account
 ----
 
-To run SSH tests using JSch ssh client:
-
-----
-  bazel test --test_env=SSH_CLIENT_IMPLEMENTATION=JSCH //...
-----
-
-To run SSH tests using Apache MINA ssh client:
-
-----
-  bazel test --test_env=SSH_CLIENT_IMPLEMENTATION=APACHE //...
-----
-
 To run only tests that do not use SSH:
 
 ----
diff --git a/Documentation/dev-e2e-tests.txt b/Documentation/dev-e2e-tests.txt
index c50a293..802b484 100644
--- a/Documentation/dev-e2e-tests.txt
+++ b/Documentation/dev-e2e-tests.txt
@@ -102,8 +102,7 @@
 === SSH keys
 
 If you are running SSH commands, the private keys of the users used for testing need to go in
-`/tmp/ssh-keys`. The keys need to be generated this way (JSch won't validate them
-link:https://stackoverflow.com/questions/53134212/invalid-privatekey-when-using-jsch[otherwise,role=external,window=_blank]):
+`/tmp/ssh-keys`. The keys need to be generated this way and won't be validated.
 
 ----
 mkdir /tmp/ssh-keys
diff --git a/Documentation/licenses.txt b/Documentation/licenses.txt
index 86ff904..1302329 100644
--- a/Documentation/licenses.txt
+++ b/Documentation/licenses.txt
@@ -32,7 +32,7 @@
 Gerrit includes an SSH daemon (Apache SSHD), to support authenticated
 uploads of changes directly from `git push` command line clients.
 
-Gerrit includes an SSH client (JSch), to support authenticated
+Gerrit includes an SSH client (Apache SSHD), to support authenticated
 replication of changes to remote systems, such as for automatic
 updates of mirror servers, or realtime backups.
 
@@ -2394,43 +2394,6 @@
 ----
 
 
-[[jsch]]
-jsch
-
-* jsch
-
-[[jsch_license]]
-----
-Copyright (c) 2002-2012 Atsuhiko Yamanaka, JCraft,Inc.
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-  1. Redistributions of source code must retain the above copyright notice,
-     this list of conditions and the following disclaimer.
-
-  2. Redistributions in binary form must reproduce the above copyright
-     notice, this list of conditions and the following disclaimer in
-     the documentation and/or other materials provided with the distribution.
-
-  3. The names of the authors may not be used to endorse or promote products
-     derived from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
-INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
-FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
-INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
-INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
-OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
-EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----
-
-
 [[jsoup]]
 jsoup
 
diff --git a/contrib/convertkey/src/main/java/com/googlesource/gerrit/convertkey/ConvertKey.java b/contrib/convertkey/src/main/java/com/googlesource/gerrit/convertkey/ConvertKey.java
deleted file mode 100644
index 08a529c..0000000
--- a/contrib/convertkey/src/main/java/com/googlesource/gerrit/convertkey/ConvertKey.java
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright (C) 2015 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.googlesource.gerrit.convertkey;
-
-import com.jcraft.jsch.HostKey;
-import com.jcraft.jsch.JSchException;
-import java.io.File;
-import java.io.IOException;
-import java.io.StringWriter;
-import java.security.GeneralSecurityException;
-import java.security.KeyPair;
-import org.apache.sshd.common.util.Buffer;
-import org.apache.sshd.server.keyprovider.SimpleGeneratorHostKeyProvider;
-import org.bouncycastle.openssl.jcajce.JcaPEMWriter;
-
-public class ConvertKey {
-  public static void main(String[] args)
-      throws GeneralSecurityException, JSchException, IOException {
-    SimpleGeneratorHostKeyProvider p;
-
-    if (args.length != 1) {
-      System.err.println("Error: requires path to the SSH host key");
-      return;
-    } else {
-      File file = new File(args[0]);
-      if (!file.exists() || !file.isFile() || !file.canRead()) {
-        System.err.println("Error: ssh key should exist and be readable");
-        return;
-      }
-    }
-
-    p = new SimpleGeneratorHostKeyProvider();
-    // Gerrit's SSH "simple" keys are always RSA.
-    p.setPath(args[0]);
-    p.setAlgorithm("RSA");
-    Iterable<KeyPair> keys = p.loadKeys(); // forces the key to generate.
-    for (KeyPair k : keys) {
-      System.out.println("Public Key (" + k.getPublic().getAlgorithm() + "):");
-      // From Gerrit's SshDaemon class; use JSch to get the public
-      // key/type
-      final Buffer buf = new Buffer();
-      buf.putRawPublicKey(k.getPublic());
-      final byte[] keyBin = buf.getCompactData();
-      HostKey pub = new HostKey("localhost", keyBin);
-      System.out.println(pub.getType() + " " + pub.getKey());
-      System.out.println("Private Key:");
-      // Use Bouncy Castle to write the private key back in PEM format
-      // (PKCS#1)
-      // http://stackoverflow.com/questions/25129822/export-rsa-public-key-to-pem-string-using-java
-      StringWriter privout = new StringWriter();
-      JcaPEMWriter privWriter = new JcaPEMWriter(privout);
-      privWriter.writeObject(k.getPrivate());
-      privWriter.close();
-      System.out.println(privout);
-    }
-  }
-}
diff --git a/java/com/google/gerrit/acceptance/AbstractDaemonTest.java b/java/com/google/gerrit/acceptance/AbstractDaemonTest.java
index 2fb2127..4faa9ab 100644
--- a/java/com/google/gerrit/acceptance/AbstractDaemonTest.java
+++ b/java/com/google/gerrit/acceptance/AbstractDaemonTest.java
@@ -168,7 +168,6 @@
 import java.nio.file.FileSystems;
 import java.nio.file.Files;
 import java.nio.file.Path;
-import java.security.KeyPair;
 import java.sql.Timestamp;
 import java.time.Instant;
 import java.util.ArrayList;
@@ -586,8 +585,7 @@
         && SshMode.useSsh()
         && (adminSshSession == null || userSshSession == null)) {
       // Create Ssh sessions
-      KeyPair adminKeyPair = sshKeys.getKeyPair(admin);
-      SshSessionFactory.initSsh(adminKeyPair);
+      SshSessionFactory.initSsh();
       Context ctx = newRequestContext(user);
       atrScope.set(ctx);
       userSshSession = ctx.getSession();
diff --git a/java/com/google/gerrit/acceptance/BUILD b/java/com/google/gerrit/acceptance/BUILD
index fe6e160..cb5f667 100644
--- a/java/com/google/gerrit/acceptance/BUILD
+++ b/java/com/google/gerrit/acceptance/BUILD
@@ -39,9 +39,7 @@
     "//lib:gson",
     "//lib:guava-retrying",
     "//lib:jgit",
-    "//lib:jgit-ssh-jsch",
     "//lib:jgit-ssh-apache",
-    "//lib:jsch",
     "//lib/commons:compress",
     "//lib/commons:lang",
     "//lib/flogger:api",
diff --git a/java/com/google/gerrit/acceptance/SshSessionJsch.java b/java/com/google/gerrit/acceptance/SshSessionJsch.java
deleted file mode 100644
index a86c2d6..0000000
--- a/java/com/google/gerrit/acceptance/SshSessionJsch.java
+++ /dev/null
@@ -1,174 +0,0 @@
-// Copyright (C) 2021 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.gerrit.acceptance;
-
-import static java.nio.charset.StandardCharsets.US_ASCII;
-import static java.nio.charset.StandardCharsets.UTF_8;
-
-import com.google.gerrit.acceptance.testsuite.account.TestAccount;
-import com.google.gerrit.acceptance.testsuite.account.TestSshKeys;
-import com.jcraft.jsch.ChannelExec;
-import com.jcraft.jsch.JSch;
-import com.jcraft.jsch.JSchException;
-import com.jcraft.jsch.Session;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.Reader;
-import java.io.StringWriter;
-import java.net.InetSocketAddress;
-import java.nio.charset.StandardCharsets;
-import java.security.GeneralSecurityException;
-import java.security.KeyPair;
-import java.security.KeyPairGenerator;
-import java.security.NoSuchAlgorithmException;
-import java.security.SecureRandom;
-import java.util.Properties;
-import java.util.Scanner;
-import org.bouncycastle.openssl.jcajce.JcaPEMWriter;
-import org.bouncycastle.openssl.jcajce.JcaPKCS8Generator;
-import org.bouncycastle.util.io.pem.PemObject;
-import org.eclipse.jgit.transport.JschConfigSessionFactory;
-import org.eclipse.jgit.transport.OpenSshConfig.Host;
-import org.eclipse.jgit.transport.SshSessionFactory;
-import org.eclipse.jgit.util.FS;
-
-public class SshSessionJsch extends SshSession {
-
-  private Session session;
-
-  public static void initClient(KeyPair keyPair) {
-    Properties config = new Properties();
-    config.put("StrictHostKeyChecking", "no");
-    JSch.setConfig(config);
-
-    // register a JschConfigSessionFactory that adds the private key as identity
-    // to the JSch instance of JGit so that SSH communication via JGit can
-    // succeed
-    SshSessionFactory.setInstance(
-        new JschConfigSessionFactory() {
-          @Override
-          protected void configure(Host hc, Session session) {
-            try {
-              JSch jsch = getJSch(hc, FS.DETECTED);
-              jsch.addIdentity(
-                  "KeyPair", privateKey(keyPair), TestSshKeys.publicKeyBlob(keyPair), null);
-            } catch (JSchException | GeneralSecurityException | IOException e) {
-              throw new RuntimeException(e);
-            }
-          }
-        });
-  }
-
-  public static KeyPairGenerator initKeyPairGenerator() throws NoSuchAlgorithmException {
-    KeyPairGenerator gen;
-    gen = KeyPairGenerator.getInstance("RSA");
-    gen.initialize(512, new SecureRandom());
-    return gen;
-  }
-
-  public SshSessionJsch(TestSshKeys sshKeys, InetSocketAddress addr, TestAccount account) {
-    super(sshKeys, addr, account);
-  }
-
-  @Override
-  public void open() throws Exception {
-    getJschSession();
-  }
-
-  @Override
-  public void close() {
-    if (session != null) {
-      session.disconnect();
-      session = null;
-    }
-  }
-
-  @SuppressWarnings("resource")
-  @Override
-  public String exec(String command) throws Exception {
-    ChannelExec channel = (ChannelExec) getJschSession().openChannel("exec");
-    try {
-      channel.setCommand(command);
-      InputStream in = channel.getInputStream();
-      InputStream err = channel.getErrStream();
-      channel.connect();
-
-      Scanner s = new Scanner(err, UTF_8.name()).useDelimiter("\\A");
-      error = s.hasNext() ? s.next() : null;
-
-      s = new Scanner(in, UTF_8.name()).useDelimiter("\\A");
-      return s.hasNext() ? s.next() : "";
-    } finally {
-      channel.disconnect();
-    }
-  }
-
-  @SuppressWarnings("resource")
-  @Override
-  public int execAndReturnStatus(String command) throws Exception {
-    ChannelExec channel = (ChannelExec) getJschSession().openChannel("exec");
-    try {
-      channel.setCommand(command);
-      InputStream err = channel.getErrStream();
-      channel.connect();
-
-      Scanner s = new Scanner(err, UTF_8.name()).useDelimiter("\\A");
-      error = s.hasNext() ? s.next() : null;
-      return channel.getExitStatus();
-    } finally {
-      channel.disconnect();
-    }
-  }
-
-  @Override
-  public Reader execAndReturnReader(String command) throws Exception {
-    ChannelExec channel = (ChannelExec) getJschSession().openChannel("exec");
-    channel.setCommand(command);
-    channel.connect();
-
-    return new InputStreamReader(channel.getInputStream(), StandardCharsets.UTF_8) {
-      @Override
-      public void close() throws IOException {
-        super.close();
-        channel.disconnect();
-      }
-    };
-  }
-
-  private Session getJschSession() throws Exception {
-    if (session == null) {
-      KeyPair keyPair = sshKeys.getKeyPair(account);
-      JSch jsch = new JSch();
-      jsch.addIdentity("KeyPair", privateKey(keyPair), TestSshKeys.publicKeyBlob(keyPair), null);
-      String username = getUsername();
-      session = jsch.getSession(username, addr.getAddress().getHostAddress(), addr.getPort());
-      session.setConfig("StrictHostKeyChecking", "no");
-      session.connect();
-    }
-    return session;
-  }
-
-  private static byte[] privateKey(KeyPair keyPair) throws IOException {
-    // unencrypted form of PKCS#8 file
-    JcaPKCS8Generator gen1 = new JcaPKCS8Generator(keyPair.getPrivate(), null);
-    PemObject obj1 = gen1.generate();
-    StringWriter sw1 = new StringWriter();
-    try (JcaPEMWriter pw = new JcaPEMWriter(sw1)) {
-      pw.writeObject(obj1);
-    }
-    return sw1.toString().getBytes(US_ASCII.name());
-  }
-}
diff --git a/java/com/google/gerrit/acceptance/testsuite/request/SshSessionFactory.java b/java/com/google/gerrit/acceptance/testsuite/request/SshSessionFactory.java
index d5dd28a..3442b6e 100644
--- a/java/com/google/gerrit/acceptance/testsuite/request/SshSessionFactory.java
+++ b/java/com/google/gerrit/acceptance/testsuite/request/SshSessionFactory.java
@@ -14,10 +14,7 @@
 
 package com.google.gerrit.acceptance.testsuite.request;
 
-import static com.google.gerrit.server.config.SshClientImplementation.getFromEnvironment;
-
 import com.google.gerrit.acceptance.SshSession;
-import com.google.gerrit.acceptance.SshSessionJsch;
 import com.google.gerrit.acceptance.SshSessionMina;
 import com.google.gerrit.acceptance.testsuite.account.TestAccount;
 import com.google.gerrit.acceptance.testsuite.account.TestSshKeys;
@@ -28,25 +25,16 @@
 public class SshSessionFactory {
   public static SshSession createSession(
       TestSshKeys testSshKeys, InetSocketAddress sshAddress, TestAccount testAccount) {
-    return getFromEnvironment().isMina()
-        ? new SshSessionMina(testSshKeys, sshAddress, testAccount)
-        : new SshSessionJsch(testSshKeys, sshAddress, testAccount);
+    return new SshSessionMina(testSshKeys, sshAddress, testAccount);
   }
 
-  public static void initSsh(KeyPair keyPair) {
-    if (getFromEnvironment().isMina()) {
-      SshSessionMina.initClient();
-    } else {
-      SshSessionJsch.initClient(keyPair);
-    }
+  public static void initSsh() {
+    SshSessionMina.initClient();
   }
 
   private SshSessionFactory() {}
 
   public static KeyPair genSshKey() throws GeneralSecurityException {
-    return (getFromEnvironment().isMina()
-            ? SshSessionMina.initKeyPairGenerator()
-            : SshSessionJsch.initKeyPairGenerator())
-        .generateKeyPair();
+    return SshSessionMina.initKeyPairGenerator().generateKeyPair();
   }
 }
diff --git a/java/com/google/gerrit/httpd/init/WebAppInitializer.java b/java/com/google/gerrit/httpd/init/WebAppInitializer.java
index 13df520..fbdbd90 100644
--- a/java/com/google/gerrit/httpd/init/WebAppInitializer.java
+++ b/java/com/google/gerrit/httpd/init/WebAppInitializer.java
@@ -343,7 +343,7 @@
         });
     modules.add(new DefaultUrlFormatterModule());
 
-    SshSessionFactoryInitializer.init(config);
+    SshSessionFactoryInitializer.init();
     modules.add(SshKeyCacheImpl.module());
     modules.add(
         new AbstractModule() {
diff --git a/java/com/google/gerrit/pgm/Daemon.java b/java/com/google/gerrit/pgm/Daemon.java
index f3691ed..402d839 100644
--- a/java/com/google/gerrit/pgm/Daemon.java
+++ b/java/com/google/gerrit/pgm/Daemon.java
@@ -491,7 +491,7 @@
           });
     }
     modules.add(new DefaultUrlFormatterModule());
-    SshSessionFactoryInitializer.init(config);
+    SshSessionFactoryInitializer.init();
     if (sshd) {
       modules.add(SshKeyCacheImpl.module());
     } else {
diff --git a/java/com/google/gerrit/server/config/SshClientImplementation.java b/java/com/google/gerrit/server/config/SshClientImplementation.java
deleted file mode 100644
index 5811e4d..0000000
--- a/java/com/google/gerrit/server/config/SshClientImplementation.java
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright (C) 2020 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.gerrit.server.config;
-
-import static com.google.common.base.Preconditions.checkArgument;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Enums;
-import com.google.common.base.Strings;
-
-/* SSH implementation to use by JGit SSH client transport protocol. */
-public enum SshClientImplementation {
-  /** JCraft JSch implementation. */
-  JSCH,
-
-  /** Apache MINA implementation. */
-  APACHE;
-
-  private static final String ENV_VAR = "SSH_CLIENT_IMPLEMENTATION";
-  private static final String SYS_PROP = "gerrit.sshClientImplementation";
-
-  @VisibleForTesting
-  public static SshClientImplementation getFromEnvironment() {
-    String value = System.getenv(ENV_VAR);
-    if (Strings.isNullOrEmpty(value)) {
-      value = System.getProperty(SYS_PROP);
-    }
-    if (Strings.isNullOrEmpty(value)) {
-      return APACHE;
-    }
-    SshClientImplementation client =
-        Enums.getIfPresent(SshClientImplementation.class, value).orNull();
-    if (!Strings.isNullOrEmpty(System.getenv(ENV_VAR))) {
-      checkArgument(
-          client != null, "Invalid value for env variable %s: %s", ENV_VAR, System.getenv(ENV_VAR));
-    } else {
-      checkArgument(
-          client != null,
-          "Invalid value for system property %s: %s",
-          SYS_PROP,
-          System.getProperty(SYS_PROP));
-    }
-    return client;
-  }
-
-  public boolean isMina() {
-    return this == APACHE;
-  }
-}
diff --git a/java/com/google/gerrit/sshd/BUILD b/java/com/google/gerrit/sshd/BUILD
index f3bd5e1..af7078d 100644
--- a/java/com/google/gerrit/sshd/BUILD
+++ b/java/com/google/gerrit/sshd/BUILD
@@ -4,7 +4,6 @@
     name = "sshd",
     srcs = glob(["**/*.java"]),
     visibility = ["//visibility:public"],
-    runtime_deps = ["//lib:jsch"],
     deps = [
         "//java/com/google/gerrit/common:annotations",
         "//java/com/google/gerrit/common:server",
diff --git a/java/com/google/gerrit/sshd/SshSessionFactoryInitializer.java b/java/com/google/gerrit/sshd/SshSessionFactoryInitializer.java
index 1cdf923..de91b68 100644
--- a/java/com/google/gerrit/sshd/SshSessionFactoryInitializer.java
+++ b/java/com/google/gerrit/sshd/SshSessionFactoryInitializer.java
@@ -14,9 +14,6 @@
 
 package com.google.gerrit.sshd;
 
-import static com.google.gerrit.server.config.SshClientImplementation.APACHE;
-
-import org.eclipse.jgit.lib.Config;
 import org.eclipse.jgit.transport.SshSessionFactory;
 import org.eclipse.jgit.transport.sshd.DefaultProxyDataFactory;
 import org.eclipse.jgit.transport.sshd.JGitKeyCache;
@@ -24,13 +21,11 @@
 import org.eclipse.jgit.util.FS;
 
 public class SshSessionFactoryInitializer {
-  public static void init(Config config) {
-    if (APACHE == config.getEnum("ssh", null, "clientImplementation", APACHE)) {
-      SshdSessionFactory factory =
-          new SshdSessionFactory(new JGitKeyCache(), new DefaultProxyDataFactory());
-      factory.setHomeDirectory(FS.DETECTED.userHome());
-      SshSessionFactory.setInstance(factory);
-    }
+  public static void init() {
+    SshdSessionFactory factory =
+        new SshdSessionFactory(new JGitKeyCache(), new DefaultProxyDataFactory());
+    factory.setHomeDirectory(FS.DETECTED.userHome());
+    SshSessionFactory.setInstance(factory);
   }
 
   private SshSessionFactoryInitializer() {}
diff --git a/lib/BUILD b/lib/BUILD
index b2810cf..01e6a25 100644
--- a/lib/BUILD
+++ b/lib/BUILD
@@ -47,13 +47,6 @@
 )
 
 java_library(
-    name = "jgit-ssh-jsch",
-    data = ["//lib:LICENSE-jgit"],
-    visibility = ["//visibility:public"],
-    exports = ["@jgit//org.eclipse.jgit.ssh.jsch:ssh-jsch"],
-)
-
-java_library(
     name = "jgit-ssh-apache",
     data = ["//lib:LICENSE-jgit"],
     visibility = ["//visibility:public"],
@@ -162,13 +155,6 @@
 )
 
 java_library(
-    name = "jsch",
-    data = ["//lib:LICENSE-jsch"],
-    visibility = ["//visibility:public"],
-    exports = ["@jsch//jar"],
-)
-
-java_library(
     name = "juniversalchardet",
     data = ["//lib:LICENSE-MPL1.1"],
     visibility = ["//visibility:public"],
diff --git a/plugins/BUILD b/plugins/BUILD
index 0e5df2c..4b5343c 100644
--- a/plugins/BUILD
+++ b/plugins/BUILD
@@ -85,7 +85,6 @@
     "//lib/jackson:jackson-core",
     "//lib:jgit-servlet",
     "//lib:jgit",
-    "//lib:jgit-ssh-jsch",
     "//lib:jsr305",
     "//lib/log:api",
     "//lib/log:log4j",
@@ -100,7 +99,6 @@
     "//lib:guava-retrying",
     "//lib:gson",
     "//lib:icu4j",
-    "//lib:jsch",
     "//lib:mime-util",
     "//lib:protobuf",
     "//lib:servlet-api-without-neverlink",
diff --git a/tools/bzl/license-map.py b/tools/bzl/license-map.py
index 43b172c..79285e6 100644
--- a/tools/bzl/license-map.py
+++ b/tools/bzl/license-map.py
@@ -170,7 +170,7 @@
 Gerrit includes an SSH daemon (Apache SSHD), to support authenticated
 uploads of changes directly from `git push` command line clients.
 
-Gerrit includes an SSH client (JSch), to support authenticated
+Gerrit includes an SSH client (Apache SSHD), to support authenticated
 replication of changes to remote systems, such as for automatic
 updates of mirror servers, or realtime backups.
 
diff --git a/tools/bzl/pkg_war.bzl b/tools/bzl/pkg_war.bzl
index 2b473bc..c9ac0fe 100644
--- a/tools/bzl/pkg_war.bzl
+++ b/tools/bzl/pkg_war.bzl
@@ -23,7 +23,6 @@
     "//lib/bouncycastle:bcprov",
     "//lib/bouncycastle:bcpg",
     "//lib/log:impl-log4j",
-    "//lib:jgit-ssh-jsch",
     "//prolog:gerrit-prolog-common",
     "//resources:log4j-config",
 ]
diff --git a/tools/deps.bzl b/tools/deps.bzl
index 89c5584..94d0e98 100644
--- a/tools/deps.bzl
+++ b/tools/deps.bzl
@@ -75,12 +75,6 @@
     )
 
     maven_jar(
-        name = "jzlib",
-        artifact = "com.jcraft:jzlib:1.1.1",
-        sha1 = "a1551373315ffc2f96130a0e5704f74e151777ba",
-    )
-
-    maven_jar(
         name = "javaewah",
         artifact = "com.googlecode.javaewah:JavaEWAH:1.1.6",
         attach_source = False,
@@ -112,12 +106,6 @@
     )
 
     maven_jar(
-        name = "jsch",
-        artifact = "com.jcraft:jsch:0.1.54",
-        sha1 = "da3584329a263616e277e15462b387addd1b208d",
-    )
-
-    maven_jar(
         name = "juniversalchardet",
         artifact = "com.github.albfernandez:juniversalchardet:2.0.0",
         sha1 = "28c59f58f5adcc307604602e2aa89e2aca14c554",
diff --git a/tools/eclipse/project.py b/tools/eclipse/project.py
index ef20ace..ed5b464 100755
--- a/tools/eclipse/project.py
+++ b/tools/eclipse/project.py
@@ -186,8 +186,6 @@
         classpathentry('src', 'modules/jgit/org.eclipse.jgit.http.server/src')
         classpathentry('src', 'modules/jgit/org.eclipse.jgit.http.server/resources')
         classpathentry('src', 'modules/jgit/org.eclipse.jgit.junit/src')
-        classpathentry('src', 'modules/jgit/org.eclipse.jgit.ssh.jsch/src')
-        classpathentry('src', 'modules/jgit/org.eclipse.jgit.ssh.jsch/resources')
         classpathentry('src', 'modules/jgit/org.eclipse.jgit.ssh.apache/src')
         classpathentry('src', 'modules/jgit/org.eclipse.jgit.ssh.apache/resources')