From f44f124a234785b9d2cd59a6da28737fb3c4ad9a Mon Sep 17 00:00:00 2001 From: "dtucker@openbsd.org" Date: Wed, 27 May 2026 23:04:36 +0000 Subject: [PATCH] upstream: Test all mutually supported algorithms, using dropbear's new -Q option to query its algorithms where possible. OpenBSD-Regress-ID: 7e1fa733dec3bfa9f8931e535a9397209b5953f3 --- regress/dropbear-server.sh | 202 ++++++++++++++++++++++++++++++++----- 1 file changed, 177 insertions(+), 25 deletions(-) diff --git a/regress/dropbear-server.sh b/regress/dropbear-server.sh index c72c86bfd..49379a53e 100644 --- a/regress/dropbear-server.sh +++ b/regress/dropbear-server.sh @@ -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="" ;; + *) + 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" = "" ]; 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 -- 2.47.3