]> git.ipfire.org Git - thirdparty/openssh-portable.git/commitdiff
upstream: Test all mutually supported algorithms,
authordtucker@openbsd.org <dtucker@openbsd.org>
Wed, 27 May 2026 23:04:36 +0000 (23:04 +0000)
committerDarren Tucker <dtucker@dtucker.net>
Thu, 28 May 2026 08:33:20 +0000 (18:33 +1000)
using dropbear's new -Q option to query its algorithms where possible.

OpenBSD-Regress-ID: 7e1fa733dec3bfa9f8931e535a9397209b5953f3

regress/dropbear-server.sh

index c72c86bfd39e85423270665bffe5d2371abc963d..49379a53ec8d9443232547c94fbc4636bf9cd191 100644 (file)
@@ -1,8 +1,14 @@
-#      $OpenBSD: dropbear-server.sh,v 1.2 2025/06/29 05:35:00 dtucker Exp $
+#      $OpenBSD: dropbear-server.sh,v 1.3 2026/05/27 23:04:36 dtucker Exp $
 #      Placed in the Public Domain.
 
 tid="dropbear server"
 
+authkeydir=/var/run/dropbear-regress
+
+if [ -z "$SUDO" -a ! -w /var/run ]; then
+       skip "need SUDO to create dir in /var/run, test won't work without it"
+fi
+
 if test "x$REGRESS_INTEROP_DROPBEAR" != "xyes" ; then
        skip "dropbear interop tests not enabled"
 fi
@@ -21,37 +27,158 @@ else
        trace "dropbear version $ver (${major}.${minor}) ok"
 fi
 
-if [ -z "$SUDO" -a ! -w /var/run ]; then
-       skip "need SUDO to create dir in /var/run, test won't work without"
+# Dropbear versions 2026.91 and earlier only support 4 hostkeys in total,
+# however this was increased shortly after that release.  Test for this.
+$SUDO $DROPBEARCONVERT openssh dropbear "$OBJ/host.ed25519" "$OBJ/db.25519" >/dev/null 2>&1
+$SUDO chown $USER $OBJ/$dbkey
+k="-r $OBJ/db.ed25519"
+if $DROPBEAR $k $k $k $k $k -V >/dev/null 2>&1; then
+       limit_4_hostkeys=no
+else
+       trace "dropbear supports only 4 host keys"
+       limit_4_hostkeys=yes
 fi
-authkeydir=/var/run/dropbear-regress
 
-ciphers=`$DBCLIENT -c help hst 2>&1 | awk '/ ciphers: /{print $4}' | tr ',' ' '`
-macs=`$DBCLIENT -m help hst 2>&1 | awk '/ MACs: /{print $4}' | tr ',' ' '`
-if [ -z "$macs" ] || [ -z "$ciphers" ]; then
-       skip "dbclient query ciphers '$ciphers' or macs '$macs' failed"
+#
+# Determine the set of algos supported by the Dropbear we're testing against.
+#
+if $DROPBEAR -Q help >/dev/null 2>&1; then
+       # We can directly query the server for supported algos.
+       dbciphers=`$DROPBEAR -Q cipher`
+       dbmacs=`$DROPBEAR -Q mac`
+       dbkexs=`$DROPBEAR -Q kex`
+       dbhkalgs=`$DROPBEAR -Q sig`
+       dbpktypes=`$DROPBEAR -Q sig`
+else
+       # We infer ciphers and macs from dbclient and hard code the rest.
+       # Since this test only supports back to Dropbear 2025.07 (due to the
+       # need for '-D') we have a pretty good idea what to hard code.
+       dbciphers=`$DBCLIENT -c help hst 2>&1 | awk '/ ciphers: /{print $4}' | tr ',' ' '`
+       dbmacs=`$DBCLIENT -m help hst 2>&1 | awk '/ MACs: /{print $4}' | tr ',' ' '`
+       dbkexs="curve25519-sha256 curve25519-sha256@libssh.org"
+       dbkexs="$dbkexs diffie-hellman-group14-sha256"
+       dbkexs="$dbkexs ecdh-sha2-nistp256 ecdh-sha2-nistp384 ecdh-sha2-nistp521"
+       dbkexs="$dbkexs sntrup761x25519-sha512 mlkem768x25519-sha256"
+       dbhkalgs="ssh-ed25519 ecdsa-sha2-nistp256 ecdsa-sha2-nistp521 rsa-sha2-256"
+       dbpktypes="ecdsa-sha2-nistp256 ecdsa-sha2-nistp384 ecdsa-sha2-nistp521"
+       dbpktypes="$dbpktypes ssh-ed25519 rsa-sha2-256"
 fi
 
+if [ -z "$dbmacs" ] || [ -z "$dbciphers" ] || [ -z "$dbkexs" ] || \
+    [ -z "$dbhkalgs" ] || [ -z "$dbpktypes" ]; then
+       fail "query ciphers '$dbciphers' macs '$dbmacs' kexs '$dbkexs' " \
+          "dbhkalgs '$dbhkalgs' or bpktypes '$bpktypes' failed"
+fi
+
+#
+# Filter out ciphers, macs and kexes not supported by the OpenSSH we're testing
+# and put the ones we want into ciphers, macs and kexes.
+#
+ciphers=""
+for c in $dbciphers; do
+       if $SSH -Q Ciphers | grep -E "^$c\$" >/dev/null; then
+               ciphers="$ciphers $c"
+       else
+               trace "ssh does not support cipher '$c'"
+       fi
+done
+
+macs=""
+for m in $dbmacs; do
+       if $SSH -Q MACs | grep -E "^$m\$" >/dev/null; then
+               macs="$macs $m"
+       else
+               trace "ssh does not support mac '$m'"
+       fi
+done
+
+kexs=""
+for k in $dbkexs; do
+       if $SSH -Q KexAlgorithms | grep -E "^$k\$" >/dev/null; then
+               kexs="$kexs $k"
+       else
+               trace "ssh does not support kex '$k'"
+       fi
+done
+
+#
+# Now filter by supported HostKeyAlgorithms.  The key types are not a 1:1
+# correlation with the algos, so we first check that the algo is supported,
+# and if so put it in hkalgs add the appropriate key type to keytypes for
+# later deduplication and processing.
+#
+hkalgs=""
+keytypes=""
+for alg in $dbhkalgs; do
+       if ! $SSH -Q HostKeyAlgorithms | grep -E "^$alg\$" >/dev/null; then
+               trace "ssh does not support $alg"
+               alg=""
+       fi
+
+       kt="$alg"
+       case "$alg" in
+       sk-*)
+               trace "omitting sk alg $alg"
+               alg=""
+               ;;
+       ecdsa-sha2-nistp384)
+               if [ "$limit_4_hostkeys" = "yes" ]; then
+                       trace "dropbear host key limit=4, omitting $alg"
+                       alg=""
+               fi
+               ;;
+       rsa-sha2*)
+               kt=ssh-rsa
+               ;;
+       esac
+
+       if [ "$alg" != "" ]; then
+               hkalgs="$hkalgs $alg"
+               keytypes="$keytypes $kt"
+       fi
+done
+
+#
+# Deduplicate key types (because the various RSA hostkey algos use the same
+# type and Dropbear has a limit on the number of hostkeys it'll load) and
+# construct hkeyopts to be passed to dropbear command line.
+#
+hkeyopts=""
+for kt in `for i in $keytypes; do echo $i; done | sort -u`; do
+       key="host.$kt"
+       dbkey="db.$kt"
+       trace "convert hostkey '$key' to '$dbkey'"
+       if $SUDO $DROPBEARCONVERT openssh dropbear "$OBJ/$key" \
+            "$OBJ/$dbkey" >/dev/null 2>&1; then
+               if [ ! -f "$OBJ/$dbkey" ]; then
+                       fail "convert $key to $dbkey"
+               fi
+               $SUDO chown $USER $OBJ/$dbkey
+       fi
+       trace "hkeyopts add -r $OBJ/db.$kt"
+       hkeyopts="$hkeyopts -r $OBJ/db.$kt"
+done
+
+pktypes=""
+for pk in $dbpktypes; do
+       if $SSH -Q PubkeyAcceptedAlgorithms | grep -E "^$pk\$" >/dev/null; then
+               case "$pk" in
+               sk-*)   ;;
+               *)      pktypes="$pktypes $pk" ;;
+               esac
+       else
+               trace "ssh does not support pubkey type '$pk'"
+       fi
+done
+
 # Set up authorized_keys for dropbear.
 umask 077
 $SUDO mkdir -p $authkeydir
 $SUDO chown -R $USER $authkeydir
 cp $OBJ/authorized_keys_$USER $authkeydir/authorized_keys
 
-for i in `$SUDO $SSHD -f $OBJ/sshd_config -T | grep -v sk- | \
-    awk '$1=="hostkey" {print $2}'`; do
-       file=`basename "$i"`
-       file=`echo "$file" | sed s/^host\./db\./g`
-       if $SUDO $DROPBEARCONVERT openssh dropbear "$i" "$OBJ/$file" \
-           >/dev/null 2>&1; then
-               $SUDO chown $USER $OBJ/$file
-               hkeys="-r $OBJ/$file"
-       fi
-done
-
 rm -f $OBJ/dropbear.pid
-$DROPBEAR -D $authkeydir -p $PORT -P $OBJ/dropbear.pid $hkeys -E \
-    2>$OBJ/sshd.log
+$DROPBEAR -E -D $authkeydir -p $PORT -P $OBJ/dropbear.pid $hkeyopts 2>>$OBJ/sshd.log
 if [ $? -ne 0 ]; then
        fatal "starting dropbear server failed"
 fi
@@ -62,15 +189,40 @@ done
 pid=`cat $OBJ/dropbear.pid`
 trap "kill $pid; $SUDO rm -rf $authkeydir" 0
 
+trace ciphers $ciphers
+trace macs $macs
+trace kexs $kexs
+trace hkalgs $hkalgs
+trace pktypes $pktypes
+
 for c in $ciphers; do
-  for m in $macs; do
-       trace "$tid: cipher $c mac $m hk $hk"
+  case "$c" in
+  chacha20-poly1305@openssh.com|aes*-gcm@openssh.com)
+    tmpmacs="<implicit>" ;;
+  *)
+    tmpmacs="$macs" ;;
+  esac
+
+  for m in $tmpmacs; do
+   for k in $kexs; do
+    for hk in $hkalgs; do
+     for pk in $pktypes; do
+       verbose "$tid: cipher $c mac $m kex $k hkalg $hk pk $pk"
        rm -f ${COPY}
-       ${SSH} -F $OBJ/ssh_config -oCiphers=$c -oMacs=$m \
-          somehost cat ${DATA} > ${COPY}
+       if [ "$m" = "<implicit>" ]; then
+               macopts=""
+       else
+               macopts="-oMacs=$m"
+       fi
+       ${SSH} -F $OBJ/ssh_config -oCiphers=$c $macopts -oKexAlgorithms=$k \
+           -oHostKeyAlgorithms=$hk -oPubkeyAcceptedAlgorithms=$pk \
+           somehost cat ${DATA} > ${COPY}
        if [ $? -ne 0 ]; then
                fail "connect dropbear server failed"
        fi
        cmp ${DATA} ${COPY}             || fail "corrupted copy"
+     done
+    done
+   done
   done
 done