upstream: Add tests for ecdsa 256, 384 and 521 keys in DNS

fingerprints. Dynamically generate the required zone file.

OpenBSD-Regress-ID: 61acdf25efc8c5d3bb0156fd3a53bf8159d3e13a
This commit is contained in:
dtucker@openbsd.org authored and Darren Tucker committed 2026-07-12 21:42:11 +10:00
1 parent 932212db4d
commit cadefc724f
7 files changed
+105 -34

No files matched your search

+8
View File
@@ -0,0 +1,8 @@
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAaAAAABNlY2RzYS
1zaGEyLW5pc3RwMjU2AAAACG5pc3RwMjU2AAAAQQQ6jrM+3cAsaW9s1EQvnlIecMIu8QHo
jcOibC0VHnaMAifXV/2KGzUz/RCX8U46sa7ilmPu91Lbnw9URWeigfBVAAAAmI7jFK2O4x
StAAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBDqOsz7dwCxpb2zU
RC+eUh5wwi7xAeiNw6JsLRUedowCJ9dX/YobNTP9EJfxTjqxruKWY+73UtufD1RFZ6KB8F
UAAAAgU1l4gRkaM0BsXp/EaHL9G4ovVao4sQy81HPzu61BMq8AAAAA
-----END OPENSSH PRIVATE KEY-----
+1
View File
@@ -0,0 +1 @@
ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBDqOsz7dwCxpb2zURC+eUh5wwi7xAeiNw6JsLRUedowCJ9dX/YobNTP9EJfxTjqxruKWY+73UtufD1RFZ6KB8FU=
+10
View File
@@ -0,0 +1,10 @@
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAiAAAABNlY2RzYS
1zaGEyLW5pc3RwMzg0AAAACG5pc3RwMzg0AAAAYQQtRwcGddCQ0tt6PZBUJw8aoLayT0zg
hPuwuF6Pu2XDtD3gyUe0IG7C4AoFCBdfOpHq+zc2Crj9/MTvklThDEft4Pbgs7Mnsi20tV
76TvsZ/h2p7TbBPwAqp3RyEivq7TMAAADQXn/G1V5/xtUAAAATZWNkc2Etc2hhMi1uaXN0
cDM4NAAAAAhuaXN0cDM4NAAAAGEELUcHBnXQkNLbej2QVCcPGqC2sk9M4IT7sLhej7tlw7
Q94MlHtCBuwuAKBQgXXzqR6vs3Ngq4/fzE75JU4QxH7eD24LOzJ7IttLVe+k77Gf4dqe02
wT8AKqd0chIr6u0zAAAAMQCy9lLIJKu0mSNMYvpi8c1Pql04WZ7likMirzjyboMFAOpo/x
fNaN7kaHNRE2lDWZcAAAAAAQIDBAUGBw==
-----END OPENSSH PRIVATE KEY-----
+1
View File
@@ -0,0 +1 @@
ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBC1HBwZ10JDS23o9kFQnDxqgtrJPTOCE+7C4Xo+7ZcO0PeDJR7QgbsLgCgUIF186ker7NzYKuP38xO+SVOEMR+3g9uCzsyeyLbS1XvpO+xn+HantNsE/ACqndHISK+rtMw==
+12
View File
@@ -0,0 +1,12 @@
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAArAAAABNlY2RzYS
1zaGEyLW5pc3RwNTIxAAAACG5pc3RwNTIxAAAAhQQBQtMWq99Otw8xIvYCOZ5H3FSbhMBg
JYgBRZV7kDA+fRhdl4oufhs1bZCsW9sHi7AAfuEzVHZeHKJCN399U3zJZaQBqXToX5k339
H2yIdFPiMeANZDka4V6OcfhvMQoKnXAjGM02TmKZbSI7o/+dKYNtfry42a74POYt3ap1HF
En/2QF0AAAEADdHzuw3R87sAAAATZWNkc2Etc2hhMi1uaXN0cDUyMQAAAAhuaXN0cDUyMQ
AAAIUEAULTFqvfTrcPMSL2AjmeR9xUm4TAYCWIAUWVe5AwPn0YXZeKLn4bNW2QrFvbB4uw
AH7hM1R2XhyiQjd/fVN8yWWkAal06F+ZN9/R9siHRT4jHgDWQ5GuFejnH4bzEKCp1wIxjN
Nk5imW0iO6P/nSmDbX68uNmu+DzmLd2qdRxRJ/9kBdAAAAQgE8QNeKcFVXfiM8t83p+J/0
yOHixM0Nqe0FhzeIHqHB+6QMu3oiz45oZcYxTg5Wvz8y27YkhWRmwXwFXkn07tgWCwAAAA
ABAg==
-----END OPENSSH PRIVATE KEY-----
+1
View File
@@ -0,0 +1 @@
ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAFC0xar3063DzEi9gI5nkfcVJuEwGAliAFFlXuQMD59GF2Xii5+GzVtkKxb2weLsAB+4TNUdl4cokI3f31TfMllpAGpdOhfmTff0fbIh0U+Ix4A1kORrhXo5x+G8xCgqdcCMYzTZOYpltIjuj/50pg21+vLjZrvg85i3dqnUcUSf/ZAXQ==
+72 -34
View File
@@ -1,4 +1,4 @@
# $OpenBSD: sshfp-connect.sh,v 1.7 2026/07/12 06:10:32 dtucker Exp $
# $OpenBSD: sshfp-connect.sh,v 1.8 2026/07/12 11:19:33 dtucker Exp $
# Placed in the Public Domain.
# This test requires external setup and thus is skipped unless
@@ -8,30 +8,13 @@
# containing he following SSHFP records with fingerprints from
# rsa_openssh.pub in that domain that are expected to succeed:
# rsa: valid sha1 and sha256 fingerprints.
# rsa-sha{1,256}, : valid fingerprints for that type only.
# rsa-sha{1,256}: valid fingerprints for that type only.
# and the following records that are expected to fail:
# rsa-bad: invalid sha1 fingerprint and good sha256 fingerprint
# rsa-sha{1,256}-bad: invalid fingerprints for that type only.
# The SSHFP records for the other key types (ed25519_openssh.prv)
# follow the same pattern.
dnsfps='\
rsa IN SSHFP 1 1 99C79CC09F5F81069CC017CDF9552CFC94B3B929
rsa IN SSHFP 1 2 E30D6B9EB7A4DE495324E4D5870B8220577993EA6AF417E8E4A4F1C5BF01A9B6
rsa-sha1 IN SSHFP 1 1 99C79CC09F5F81069CC017CDF9552CFC94B3B929
rsa-sha256 IN SSHFP 1 2 E30D6B9EB7A4DE495324E4D5870B8220577993EA6AF417E8E4A4F1C5BF01A9B6
rsa-bad IN SSHFP 1 1 99C79CC09F5F81069CC017CDF9552CFC94B3B928
rsa-bad IN SSHFP 1 2 E30D6B9EB7A4DE495324E4D5870B8220577993EA6AF417E8E4A4F1C5BF01A9B6
rsa-sha1-bad IN SSHFP 1 1 99D79CC09F5F81069CC017CDF9552CFC94B3B929
rsa-sha256-bad IN SSHFP 1 2 E30D6B9EB7A4DE495324E4D5870B8220577993EA6AF417E8E4A4F1C5BF01A9B5
ed25519 IN SSHFP 4 1 8A8647A7567E202CE317E62606C799C53D4C121F
ed25519 IN SSHFP 4 2 54A506FB849AAFB9F229CF78A94436C281EFCB4AE67C8A430E8C06AFCB5EE18F
ed25519-sha1 IN SSHFP 4 1 8A8647A7567E202CE317E62606C799C53D4C121F
ed25519-sha256 IN SSHFP 4 2 54A506FB849AAFB9F229CF78A94436C281EFCB4AE67C8A430E8C06AFCB5EE18F
ed25519-bad IN SSHFP 4 1 8A8647A7567E202CE317E62606C799C53D4C121E
ed25519-bad IN SSHFP 4 2 54A506FB849AAFB9F229CF78A94436C281EFCB4AE67C8A430E8C06AFCB5EE18F
ed25519-sha1-bad IN SSHFP 4 1 8A8647A7567E202CE317E62606C799C53D4C121E
ed25519-sha256-bad IN SSHFP 4 2 54A506FB849AAFB9F229CF78A94436C281EFCB4AE67C8A430E8C06AFCB5EE18E'
# The SSHFP records for the other key types follow the same pattern.
# The BIND-format zone file $OBJ/sshfp-connect.zone is created
# containing these records.
tid="sshfp connect"
@@ -39,32 +22,55 @@ if [ -z "${TEST_SSH_SSHFP_DOMAIN}" ]; then
skip "TEST_SSH_SSHFP_DOMAIN not set."
fi
# Generate expected SSHFP zone file. This can also be handy to import if
# you're setting this up from scratch.
for kt in `$SSH -Q key-plain | grep -v sk- | \
egrep '^(ssh-rsa|ecdsa-sha2|ssh-ed25519)'`; do
case "$kt" in
ssh-rsa) dnsname=rsa ;;
ecdsa-sha2-nistp256) dnsname=ecdsa256 ;;
ecdsa-sha2-nistp384) dnsname=ecdsa384 ;;
ecdsa-sha2-nistp521) dnsname=ecdsa521 ;;
ssh-ed25519) dnsname=ed25519 ;;
*) fatal "unknown keytype $kt" ;;
esac
file="${dnsname}_openssh"
# Make good fingerprints
$SSHKEYGEN -r ${dnsname} -f ${SRC}/${file}.pub
$SSHKEYGEN -r ${dnsname}-sha1 -f ${SRC}/${file}.pub | awk '$5=="1"'
$SSHKEYGEN -r ${dnsname}-sha256 -f ${SRC}/${file}.pub | awk '$5=="2"'
# Make bad fingerprints.
# For the name with both types we only want the sha1 to be bad.
$SSHKEYGEN -r ${dnsname}-bad -f ${SRC}/${file}.pub | awk '$5=="1"' | tr f e
$SSHKEYGEN -r ${dnsname}-bad -f ${SRC}/${file}.pub | awk '$5=="2"'
$SSHKEYGEN -r ${dnsname}-sha1-bad -f ${SRC}/${file}.pub | awk '$5=="1"' | tr f e
$SSHKEYGEN -r ${dnsname}-sha256-bad -f ${SRC}/${file}.pub | awk '$5=="2"' | tr f e
done | sort -n -k4,5 > $OBJ/sshfp-connect.zone
# Check that the required DNS entries exist.
# This also primes any DNS caches and resolvers.
#
# It uses here documents instead of the more obvious "foo | while read"
# since the latter runs the loop inside a subshell and any variables set in it
# vanish when the subshell does.
while read line; do
name=`echo "$line" | awk '{print $1}'`
expected=`echo "$line" | awk '{print $4" "$5" "$6}'`
expected=`echo "$line" | awk '{print $4" "$5" "$6}' | tr a-z A-Z`
# Ensure at least one result matches exactly
matched=no
# This uses a here document instead of "foo | while read" since the
# the latter runs the loop inside a subshell and any variables set
# vanish when the subshell does.
while read result; do
if [ "$result" = "$expected" ]; then
matched=yes
fi
done <<EOD
`host -t sshfp "${name}.${TEST_SSH_SSHFP_DOMAIN}" | \
awk '{print $5" "$6" "$7$8}'`
awk '{print $5" "$6" "$7$8}' | tr a-z A-Z`
EOD
if [ "$matched" = "no" ]; then
fatal "$name.${TEST_SSH_SSHFP_DOMAIN} does not match required"
fatal "$name.${TEST_SSH_SSHFP_DOMAIN} SSHFP record does not match required"
fi
trace "verified sshfp record '$name' -> '$expected'"
done <<EOD
$dnsfps
EOD
done <${OBJ}/sshfp-connect.zone
verbose "all required sshfp entries exist"
# Zero out known hosts and key aliases to force use of SSHFP records.
@@ -100,12 +106,44 @@ if $SSH -Q key-plain | grep ssh-rsa >/dev/null; then
trace "sshfp connect $n bad fingerprint"
host="${n}-bad.${TEST_SSH_SSHFP_DOMAIN}"
if ${SSH} $opts ${host} true 2>/dev/null; then
if ${SSH} $opts $algs ${host} true 2>/dev/null; then
fail "sshfp-connect succeeded with bad SSHFP record"
fi
done
fi
if $SSH -Q key-plain | grep ecdsa-sha2-nistp >/dev/null; then
for b in 256 384 521; do
verbose "connect sshfp ecdsa${b}"
# Set ecdsa host key to match fingerprints above.
mv $OBJ/sshd_proxy $OBJ/sshd_proxy.orig
$SUDO cp $SRC/ecdsa${b}_openssh.prv $OBJ/host.ecdsa-sha2-nistp${b}
$SUDO chmod 600 $OBJ/host.ecdsa-sha2-nistp${b}
sed -e "s|$OBJ/ecdsa-sha2-nistp${b}|$OBJ/host.ecdsa-sha2-nistp${b}|" \
$OBJ/sshd_proxy.orig > $OBJ/sshd_proxy
for n in ecdsa${b} ecdsa${b}-sha1 ecdsa${b}-sha256; do
trace "sshfp connect $n good fingerprint"
algs="$opts -oHostKeyAlgorithms=ecdsa-sha2-nistp${b}"
host="${n}.${TEST_SSH_SSHFP_DOMAIN}"
SSH_CONNECTION=`${SSH} $opts $algs $host 'echo $SSH_CONNECTION'`
if [ $? -ne 0 ]; then
fail "ssh sshfp connect $n failed"
fi
if [ "$SSH_CONNECTION" != "UNKNOWN 65535 UNKNOWN 65535" ]; then
fail "bad SSH_CONNECTION: $SSH_CONNECTION"
fi
trace "sshfp connect $n bad fingerprint"
host="${n}-bad.${TEST_SSH_SSHFP_DOMAIN}"
if ${SSH} $opts $algs ${host} true 2>/dev/null; then
fail "sshfp-connect succeeded with bad SSHFP record"
fi
done
done
fi
if $SSH -Q key-plain | grep ssh-ed25519 >/dev/null; then
verbose "connect sshfp ed25519"
@@ -130,7 +168,7 @@ if $SSH -Q key-plain | grep ssh-ed25519 >/dev/null; then
trace "sshfp connect $n bad fingerprint"
host="${n}-bad.${TEST_SSH_SSHFP_DOMAIN}"
if ${SSH} $opts ${host} true 2>/dev/null; then
if ${SSH} $opts $algs ${host} true 2>/dev/null; then
fail "sshfp-connect succeeded with bad SSHFP record"
fi
done