• Icon: Improvement Improvement
    • Resolution: Unresolved
    • Icon: Minor Minor
    • ssh-credentials-plugin
    • None
    • RHEL 9.5
      Jenkins 2.492.2 LTS
      OpenJDK 17
      SSH Build Agents Plugin 3.1031.v72c6b_883b_869
      SSH Credentials Plugin 355.v9b_e5b_cde5003

      I am volunteering to update the Jenkins fork of trilead-ssh2 library to add the below improvement. This ticket is to have a JIRA ticket number for my PR.

      Improvement:

      Add aes256-gcm cipher to the Jenkins SSH Credentials plugin, to support more secure ciphers.

      The current list of supported ciphers is below:

      1. des-ede3-cbc
      2. des-cbc
      3. aes-128-cbc
      4. aes-192-cbc
      5. aes-256-cbc
      6. aes-256-ctr

      Related Issues:

      1. JENKINS-71561 - ciphers aes256-gcm@openssh.com,aes128-gcm@openssh.com NOT Supported
      2. JENKINS-71852 - com.jcraft.jsch.JSchException: Auth fail
      3. JENKINS-25258 - SSH Plugin fails to connect to openssh 6.7

      Detailed Explanation

      On a clean install of RHEL9.5, the default SSH ciphers are as follows:

       

      cat /etc/crypto-policies/back-ends/opensshserver.config
      ...
      Ciphers aes256-gcm@openssh.com,chacha20-poly1305@openssh.com,aes256-ctr,aes128-gcm@openssh.com,aes128-ctr
       ...

       

      It is not possible to use an ssh-key using the aes256-gcm cipher, as the underlying com.trilead.ssh2 library only supports the following ciphers:

      https://github.com/jenkinsci/trilead-ssh2/blob/721a1861cff664a81afdd9803ccef9e5bd79cb02/src/com/trilead/ssh2/signature/OpenSshCertificateDecoder.java#L139

       

      ...
       private enum SshCipher {        DESEDE_CBC(24, 8, "des-ede3-cbc") {
                  @Override
                  BlockCipher createBlockCipher(byte[] key, byte[] iv, boolean encrypt) {
                      return BlockCipherFactory.createCipher("3des-cbc", encrypt, key, iv);
                  }
              },
              DES_CBC(8, 8, "des-cbc") {
                  @Override
                  BlockCipher createBlockCipher(byte[] key, byte[] iv, boolean encrypt) {
                      DES des = new DES();
                      des.init(encrypt, key);
                      return new CBCMode(des, iv, encrypt);
                  }
              },
              AES128_CBC(16, 16, "aes-128-cbc", "aes128-cbc") {
                  @Override
                  BlockCipher createBlockCipher(byte[] key, byte[] iv, boolean encrypt) {
                      return BlockCipherFactory.createCipher("aes128-cbc", encrypt, key, iv);
                  }
              },
              AES192_CBC(24, 16, "aes-192-cbc", "aes192-cbc") {
                  @Override
                  BlockCipher createBlockCipher(byte[] key, byte[] iv, boolean encrypt) {
                      return BlockCipherFactory.createCipher("aes192-cbc", encrypt, key, iv);
                  }
              },
              AES256_CBC(32, 16, "aes-256-cbc", "aes256-cbc") {
                  @Override
                  BlockCipher createBlockCipher(byte[] key, byte[] iv, boolean encrypt) {
                      return BlockCipherFactory.createCipher("aes256-cbc", encrypt, key, iv);
                  }
              },
              AES256_CTR(32, 16, "aes-256-ctr", "aes256-ctr") {
                  @Override
                  BlockCipher createBlockCipher(byte[] key, byte[] iv, boolean encrypt) {
                      return BlockCipherFactory.createCipher("aes256-ctr", encrypt, key, iv);
                  }
              };        private final String[] sshCipherNames;
              private final int keyLength;
              private final int blockSize;        SshCipher(int keyLength, int blockSize, String cipherName, String... cipherAliases) {
                  this.keyLength = keyLength;
                  this.blockSize = blockSize;
                  String[] sshCipherNames = new String[1 + (null == cipherAliases ? 0 : cipherAliases.length)];
                  sshCipherNames[0] = cipherName;
                  if (null != cipherAliases) {
                      System.arraycopy(cipherAliases, 0, sshCipherNames, 1, cipherAliases.length);
                  }
                  this.sshCipherNames = sshCipherNames;
              }        abstract BlockCipher createBlockCipher(byte[] key, byte[] iv, boolean encrypt);        public int getBlockSize() {
                  return blockSize;
              }        public int getKeyLength() {
                  return keyLength;
              }        public static SshCipher getInstance(String cipher) {
                  for (SshCipher instance : values()) {
                      for (String name : instance.sshCipherNames) {
                          if (name.equalsIgnoreCase(cipher)) {
                              return instance;
                          }
                      }
                  }
                  throw new IllegalArgumentException("Unknown Cipher: " + cipher);
              }    }
      
      ... 

      See below exception:

       

      verificationStrategy=hudson.plugins.sshslaves.verifiers.NonVerifyingKeyVerificationStrategy, tcpNoDelay=true, trackCredentials=true}[03/16/25 09:47:38] [SSH] Opening SSH connection to jenkins-agent-1.shelltech.net:22.[03/16/25 09:47:38] [SSH] WARNING: SSH Host Keys are not being verified. Man-in-the-middle attacks may be possible against this connection.ERROR: SSH authentication failedjava.lang.IllegalArgumentException: Unknown Cipher: aes256-gcm@openssh.com	at PluginClassLoader for trilead-api//com.trilead.ssh2.signature.OpenSshCertificateDecoder$SshCipher.getInstance(OpenSshCertificateDecoder.java:213)	at PluginClassLoader for trilead-api//com.trilead.ssh2.signature.OpenSshCertificateDecoder.createKeyPair(OpenSshCertificateDecoder.java:77)	at PluginClassLoader for trilead-api//com.trilead.ssh2.crypto.PEMDecoder.decodeKeyPair(PEMDecoder.java:471)	at PluginClassLoader for trilead-api//com.trilead.ssh2.auth.AuthenticationManager.authenticatePublicKey(AuthenticationManager.java:303)	at PluginClassLoader for trilead-api//com.trilead.ssh2.Connection.authenticateWithPublicKey(Connection.java:474)	at PluginClassLoader for ssh-credentials//com.cloudbees.jenkins.plugins.sshcredentials.impl.TrileadSSHPublicKeyAuthenticator.doAuthenticate(TrileadSSHPublicKeyAuthenticator.java:110)	at PluginClassLoader for ssh-credentials//com.cloudbees.jenkins.plugins.sshcredentials.SSHAuthenticator.authenticate(SSHAuthenticator.java:431)	at PluginClassLoader for ssh-credentials//com.cloudbees.jenkins.plugins.sshcredentials.SSHAuthenticator.authenticate(SSHAuthenticator.java:468)	at PluginClassLoader for ssh-slaves//hudson.plugins.sshslaves.SSHLauncher.openConnection(SSHLauncher.java:875)	at PluginClassLoader for ssh-slaves//hudson.plugins.sshslaves.SSHLauncher.lambda$launch$0(SSHLauncher.java:440)	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)	at java.base/java.lang.Thread.run(Thread.java:840)[03/16/25 09:47:38] [SSH] Authentication failed.Authentication failed.[03/16/25 09:47:38] Launch failed - cleaning up connection[03/16/25 09:47:38] [SSH] Connection closed. 

          [JENKINS-75436] Add aes256-gcm@openssh.com to

          Steven added a comment -

          Issues I'm fairly certain would be solved by this improvement

          Steven added a comment - Issues I'm fairly certain would be solved by this improvement

          Steven added a comment -

          tisha56morris, I'm working on it now.

          I'm finding it difficult to not refactor this library since it appears to be Java 1.4 source.... which is horrible. I hope to have something finished this weekend, but of course this lib will have to work downstream to the ssh plugin.

          Steven added a comment - tisha56morris , I'm working on it now. I'm finding it difficult to not refactor this library since it appears to be Java 1.4 source.... which is horrible. I hope to have something finished this weekend, but of course this lib will have to work downstream to the ssh plugin.

          Mark Waite added a comment -

          is Tisha a bot?

          A spammer that had not been detected. Thanks for asking the question. Spam account blocked and spam comment deleted.

          Mark Waite added a comment - is Tisha a bot? A spammer that had not been detected. Thanks for asking the question. Spam account blocked and spam comment deleted.

          eraonel added a comment -

          We got a vulnerability warnings for EdDSA-java library which is used in Trilead library, Which may prevent us from using Trilead

          https://github.com/advisories/GHSA-p53j-g8pw-4w5f
          https://github.com/str4d/ed25519-java/issues/82#issue-727629226

          https://eprint.iacr.org/2020/1244

          https://www.cve.org/CVERecord?id=CVE-2020-36843

          https://nvd.nist.gov/vuln/detail/CVE-2020-36843

           

          Currently used EdDSA-java library which has this vulnerability has no new version since 2018, which is the one Trilead uses.

          https://mvnrepository.com/artifact/net.i2p.crypto/eddsa 

          https://github.com/str4d/ed25519-java

           ++ 

          Solution 1: A similar library seems to provide a fix, i2p

          https://github.com/str4d/ed25519-java/issues/82#issue-727629226

          https://github.com/i2p/i2p.i2p/blob/ec1458d75dbc18fe055f638a4a52d134fb35b466/core/java/src/net/i2p/crypto/eddsa/EdDSAEngine.java#L316 

          and the class looks almost identical to the class in question with the vulnerability

          https://github.com/str4d/ed25519-java/blob/master/src/net/i2p/crypto/eddsa/EdDSAEngine.java#L307 

                          but not an obvious replacement to EdDSA-Java

           ** 

          Solution2: Use fork of EdDSA-Java like here:

          https://github.com/bloxbean/cardano-client-lib/pull/496

           

          Solution3: reuse implementation from trilead fork: https://github.com/connectbot/sshlib/ 

          which it uses tink dependency, which trilead already has anyway.

          It could still have vulnerability, as it has not been tested in: https://github.com/novifinancial/ed25519-speccheck/blob/main/scripts/ed25519-java/src/main/java/Ed25519TestCase.java

          Solution4: use Bouncy Castle seems to have ed25519 Impl, (given it has this issue fixed, which I guess it would have now)

           

          Any thoughts? Mine:

          Solution2, Probably is the fastest quick and dirty fix.

          Solution 3-4 probably the preferred solutions long term. 

          eraonel added a comment - We got a vulnerability warnings for EdDSA-java library which is used in Trilead library, Which may prevent us from using Trilead https://github.com/advisories/GHSA-p53j-g8pw-4w5f https://github.com/str4d/ed25519-java/issues/82#issue-727629226 https://eprint.iacr.org/2020/1244 https://www.cve.org/CVERecord?id=CVE-2020-36843 https://nvd.nist.gov/vuln/detail/CVE-2020-36843   Currently used EdDSA-java library which has this vulnerability has no new version since 2018, which is the one Trilead uses. https://mvnrepository.com/artifact/net.i2p.crypto/eddsa   https://github.com/str4d/ed25519-java  ++  Solution 1 : A similar library seems to provide a fix, i2p https://github.com/str4d/ed25519-java/issues/82#issue-727629226 https://github.com/i2p/i2p.i2p/blob/ec1458d75dbc18fe055f638a4a52d134fb35b466/core/java/src/net/i2p/crypto/eddsa/EdDSAEngine.java#L316   and the class looks almost identical to the class in question with the vulnerability https://github.com/str4d/ed25519-java/blob/master/src/net/i2p/crypto/eddsa/EdDSAEngine.java#L307                   but not an obvious replacement to EdDSA-Java  **  Solution2: Use fork of EdDSA-Java like here: https://github.com/bloxbean/cardano-client-lib/pull/496   Solution3: reuse implementation from trilead fork: https://github.com/connectbot/sshlib/   which it uses tink dependency, which trilead already has anyway. It could still have vulnerability, as it has not been tested in: https://github.com/novifinancial/ed25519-speccheck/blob/main/scripts/ed25519-java/src/main/java/Ed25519TestCase.java Solution4: use Bouncy Castle seems to have ed25519 Impl, (given it has this issue fixed, which I guess it would have now)   Any thoughts? Mine: Solution2, Probably is the fastest quick and dirty fix. Solution 3-4 probably the preferred solutions long term. 

          Mark Waite added a comment - - edited

          Solution2: Use fork of EdDSA-Java

          As far as I know, Jenkins has implemented a fork as part of SECURITY-3404. The advisory says:

          EDDSA API Plugin 0.3.0.1-16.vcb_4a_98a_3531c inlines the EdDSA-Java library (ed25519-java) directly into the plugin and adds validation to prevent signature malleability and ensure the SUF-CMA property.

          Mark Waite added a comment - - edited Solution2 : Use fork of EdDSA-Java As far as I know, Jenkins has implemented a fork as part of SECURITY-3404 . The advisory says: EDDSA API Plugin 0.3.0.1-16.vcb_4a_98a_3531c inlines the EdDSA-Java library (ed25519-java) directly into the plugin and adds validation to prevent signature malleability and ensure the SUF-CMA property.

            jvz Matt Sicker
            speedythesnail Steven
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated: