Skip to content

SSH Transport fails with "RuntimeSshException: Failed to execute: null" after upgrading JGit to 7.4 #221

@salil-sharma-ar

Description

@salil-sharma-ar

After upgrading JGit from 6.10 to 7.4, all the SSH-based Git operations (clone, fetch, checkout) are failing with the error:
RuntimeSshException: Failed to execute: null

This issue occurs specifically in server when running the application in containerized environment. It works fine when running the same commands from my local.

This is the old 6.10 code:

SessionFactory createSshSessionFactory() throws IOException {
        try {
            val privateKeyBase64 = ""; //loads from db
            val publicKeyBase64 = //loads from db
            val keyPair = EncryptionUtils.generateKeyPair(privateKeyBase64, publicKeyBase64);

            return new SessionFactory(keyPair);
        } catch (NoSuchAlgorithmException | InvalidKeySpecException ex) {
            throw new IOException(ex);
        }
    }

// Later in the file, i will set it as follows:
((SshTransport) transport).setSshSessionFactory(sessionFactory);

This is my current 7.4 code:

SshdSessionFactory createSshSessionFactory(File workingDir) throws IOException {
        try {
            val privateKeyBase64 = ""; //loads from db
            val publicKeyBase64 = ""; //loads from db

            // Convert FIPS keys to standard Java KeyPair for JGit compatibility
            val keyPair = EncryptionUtils.convertFipsKeysToStandardKeyPair(privateKeyBase64, publicKeyBase64);

            SshdSessionFactoryBuilder builder = new SshdSessionFactoryBuilder();
            return builder
                    .setHomeDirectory(workingDir)
                    .setSshDirectory(workingDir)
                    .setConfigStoreFactory((h, f, u) -> null)
                    .setDefaultIdentities(ignore -> new ArrayList<>())
                    .setDefaultKeysProvider(ignore -> Collections.singletonList(keyPair))
                    .setServerKeyDatabase((homeDir, sshDir) -> new NoAskAcceptServerKeyDatabase())
                    .build(null);
        } catch (NoSuchAlgorithmException | InvalidKeySpecException ex) {
            throw new IOException(ex);
        }
    }

    static class NoAskAcceptServerKeyDatabase implements ServerKeyDatabase, ServerKeyVerifier {
        @Override
        public boolean accept(String connectAddress, InetSocketAddress remoteAddress, PublicKey serverKey,
                ServerKeyDatabase.Configuration config, CredentialsProvider provider) {
            // Always accept server keys to avoid validation issues
            return true;
        }

        @Override
        public List<PublicKey> lookup(String connectAddress, InetSocketAddress remoteAddress, ServerKeyDatabase.Configuration config) {
              // Return empty list since we accept all keys
              return Collections.emptyList();
        }

        @Override
        public boolean verifyServerKey(ClientSession clientSession, SocketAddress socketAddress, PublicKey publicKey) {
            return true;
        }
    }

Two things to note:

  1. I was previously running in FIPS compliant environment, so all my keys were being converted using FIPS compliant bouncycastle algorithms, which was not working with new Jgit 7.x versions since it is heavily reliant on Non-FIPS bouncycasyle. I had to manually add bcprov-jdk18on library otherwise it would throw ClassNotFoundException during runtime, and convert existing keys to ones that can be read by Jgit BC.
  2. Don't remember the exact error why I had to set home and ssh directories manually, but it was not picking up the keys I was passing and defaulting to keys saved in my .ssh folder.

Could someone please provide some guidance on how to tackle this? The error message "Failed to execute: null" provides no actionable information for me to work on.

Environment Details
Java Version: 17
Operating System: Linux

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions