diff app/src/main/java/ch/ethz/ssh2/Connection.java @ 510:7953570e5210

update to ganymed-ssh2 tag 263 and fix hmac-sha2-512
author Carl Byington <carl@five-ten-sg.com>
date Wed, 01 Feb 2023 17:55:29 -0700
parents d29cce60f393
children
line wrap: on
line diff
--- a/app/src/main/java/ch/ethz/ssh2/Connection.java	Sun Jan 29 10:25:21 2023 -0700
+++ b/app/src/main/java/ch/ethz/ssh2/Connection.java	Wed Feb 01 17:55:29 2023 -0700
@@ -1242,14 +1242,55 @@
     }
 
     /**
+     * Removes duplicates from a String array, keeps only first occurence
+     * of each element. Does not destroy order of elements; can handle nulls.
+     * Uses a very efficient O(N^2) algorithm =)
+     *
+     * @param list a String array.
+     * @return a cleaned String array.
+     */
+    private String[] removeDuplicates(String[] list) {
+        if((list == null) || (list.length < 2)) {
+            return list;
+        }
+
+        String[] list2 = new String[list.length];
+
+        int count = 0;
+
+        for(final String element : list) {
+            boolean duplicate = false;
+            for(int j = 0; j < count; j++) {
+                if(((element == null) && (list2[j] == null)) || ((element != null) && (element.equals(list2[j])))) {
+                    duplicate = true;
+                    break;
+                }
+            }
+            if(duplicate) {
+                continue;
+            }
+            list2[count++] = element;
+        }
+
+        if(count == list2.length) {
+            return list2;
+        }
+
+        String[] tmp = new String[count];
+        System.arraycopy(list2, 0, tmp, 0, count);
+
+        return tmp;
+    }
+
+    /**
      * Unless you know what you are doing, you will never need this.
      */
 
-    public synchronized void setClient2ServerCiphers(final String[] ciphers) {
+    public synchronized void setClient2ServerCiphers(String[] ciphers) {
         if ((ciphers == null) || (ciphers.length == 0)) {
             throw new IllegalArgumentException();
         }
-
+        ciphers = removeDuplicates(ciphers);
         BlockCipherFactory.checkCipherList(ciphers);
         cryptoWishList.c2s_enc_algos = ciphers;
     }
@@ -1258,7 +1299,11 @@
      * Unless you know what you are doing, you will never need this.
      */
 
-    public synchronized void setClient2ServerMACs(final String[] macs) {
+    public synchronized void setClient2ServerMACs(String[] macs) {
+        if((macs == null) || (macs.length == 0)) {
+            throw new IllegalArgumentException();
+        }
+        macs = removeDuplicates(macs);
         MAC.checkMacList(macs);
         cryptoWishList.c2s_mac_algos = macs;
     }
@@ -1283,7 +1328,11 @@
      * Unless you know what you are doing, you will never need this.
      */
 
-    public synchronized void setServer2ClientCiphers(final String[] ciphers) {
+    public synchronized void setServer2ClientCiphers(String[] ciphers) {
+        if((ciphers == null) || (ciphers.length == 0)) {
+            throw new IllegalArgumentException();
+        }
+        ciphers = removeDuplicates(ciphers);
         BlockCipherFactory.checkCipherList(ciphers);
         cryptoWishList.s2c_enc_algos = ciphers;
     }
@@ -1292,7 +1341,11 @@
      * Unless you know what you are doing, you will never need this.
      */
 
-    public synchronized void setServer2ClientMACs(final String[] macs) {
+    public synchronized void setServer2ClientMACs(String[] macs) {
+        if((macs == null) || (macs.length == 0)) {
+            throw new IllegalArgumentException();
+        }
+        macs = removeDuplicates(macs);
         MAC.checkMacList(macs);
         cryptoWishList.s2c_mac_algos = macs;
     }
@@ -1310,12 +1363,36 @@
      *              at least one entry.
      */
 
-    public synchronized void setServerHostKeyAlgorithms(final String[] algos) {
+    public synchronized void setServerHostKeyAlgorithms(String[] algos) {
+        if ((algos == null) || (algos.length == 0)) {
+            throw new IllegalArgumentException();
+        }
+        algos = removeDuplicates(algos);
         KexManager.checkServerHostkeyAlgorithmsList(algos);
         cryptoWishList.serverHostKeyAlgorithms = algos;
     }
 
     /**
+     * Define the set of allowed key exchange methods.
+     *
+     * @param algos An array of allowed key exchange methods. The following are supported:
+     *              diffie-hellman-group14-sha256,
+     *              diffie-hellman-group16-sha512,
+     *              diffie-hellman-group18-sha512,
+     *              diffie-hellman-group14-sha1,
+     *              diffie-hellman-group1-sha1,
+     *              diffie-hellman-group-exchange-sha1
+     */
+    public synchronized void setClientKexAlgorithms(String[] algos) {
+        if ((algos == null) || (algos.length == 0)) {
+            throw new IllegalArgumentException();
+        }
+        algos = removeDuplicates(algos);
+        KexManager.checkClientKexAlgorithmList(algos);
+        cryptoWishList.kexAlgorithms = algos;
+    }
+
+    /**
      * Enable/disable TCP_NODELAY (disable/enable Nagle's algorithm) on the underlying socket.
      * <p/>
      * Can be called at any time. If the connection has not yet been established