runtests: allow configuring SSH host/client key algorithm

via env `CURL_TEST_SSH_KEYALGO`, `rsa` (default), `ecdsa`, `ed25519`.

To ease debugging and testing and to make these code paths more
universal.

Closes #21223
This commit is contained in:
Viktor Szakats 2026-04-02 01:05:54 +02:00
parent 2e5d219205
commit acda4eae5e
No known key found for this signature in database
7 changed files with 44 additions and 13 deletions

View file

@ -96,6 +96,7 @@ my $listenaddr = '127.0.0.1'; # default address on which to listen
my $ipvnum = 4; # default IP version of listener address
my $idnum = 1; # default ssh daemon instance number
my $proto = 'ssh'; # protocol the ssh daemon speaks
my $keyalgo = 'rsa'; # key algorithm
my $path = getcwd(); # current working directory
my $logdir = $path .'/log'; # directory for log files
my $piddir; # directory for server config files
@ -190,6 +191,12 @@ while(@ARGV) {
}
}
}
elsif($ARGV[0] eq '--keyalgo') {
if($ARGV[1]) {
$keyalgo = $ARGV[1];
shift @ARGV;
}
}
else {
print STDERR "\nWarning: sshserver.pl unknown parameter: '$ARGV[0]'\n";
}
@ -373,6 +380,7 @@ if((($sshid =~ /OpenSSH/) && ($sshvernum < 299)) ||
# -N: new passphrase : OpenSSH 1.2.1 and later
# -q: quiet keygen : OpenSSH 1.2.1 and later
# -t: key type : OpenSSH 2.5.0 and later
# -m: key format : OpenSSH 5.6.0 and later
#
# -C: identity comment : SunSSH 1.0.0 and later
# -f: key filename : SunSSH 1.0.0 and later
@ -404,17 +412,17 @@ if((! -e pp($hstprvkeyf)) || (! -s pp($hstprvkeyf)) ||
# format, e.g. WinCNG.
# Accepted values: RFC4716, PKCS8, PEM (see also 'man ssh-keygen')
push @sshkeygenopt, '-m';
# Default to the most compatible RSA format for tests.
# Default to the most compatible format for tests.
push @sshkeygenopt, $ENV{'CURL_TEST_SSH_KEY_FORMAT'} ? $ENV{'CURL_TEST_SSH_KEY_FORMAT'} : 'PEM';
}
logmsg "generating host keys...\n" if($verbose);
if(system($sshkeygen, ('-q', '-t', 'rsa', '-f', pp($hstprvkeyf), '-C', 'curl test server', '-N', '', @sshkeygenopt))) {
if(system($sshkeygen, ('-q', '-t', $keyalgo, '-f', pp($hstprvkeyf), '-C', 'curl test server', '-N', '', @sshkeygenopt))) {
logmsg "Could not generate host key\n";
exit 1;
}
display_file_top(pp($hstprvkeyf)) if($verbose);
logmsg "generating client keys...\n" if($verbose);
if(system($sshkeygen, ('-q', '-t', 'rsa', '-f', pp($cliprvkeyf), '-C', 'curl test client', '-N', '', @sshkeygenopt))) {
if(system($sshkeygen, ('-q', '-t', $keyalgo, '-f', pp($cliprvkeyf), '-C', 'curl test client', '-N', '', @sshkeygenopt))) {
logmsg "Could not generate client key\n";
exit 1;
}
@ -604,7 +612,7 @@ if($sshdid !~ /OpenSSH-Windows/) {
push @cfgarr, "PidFile $pidfile_config";
push @cfgarr, '#';
}
if(($sshdid =~ /OpenSSH/) && ($sshdvernum >= 880)) {
if(($sshdid =~ /OpenSSH/) && ($sshdvernum >= 880) && ($keyalgo eq 'rsa')) {
push @cfgarr, 'HostKeyAlgorithms +ssh-rsa';
push @cfgarr, 'PubkeyAcceptedKeyTypes +ssh-rsa';
}
@ -828,11 +836,12 @@ if(system("\"$sshd\" -t -f $sshdconfig_abs > $sshdlog 2>&1")) {
if((! -e pp($knownhosts)) || (! -s pp($knownhosts))) {
logmsg "generating ssh client known hosts file...\n" if($verbose);
unlink(pp($knownhosts));
if(open(my $rsakeyfile, "<", pp($hstpubkeyf))) {
my @rsahostkey = do { local $/ = ' '; <$rsakeyfile> };
if(close($rsakeyfile)) {
if(open(my $keyfile, "<", pp($hstpubkeyf))) {
chomp(my $line = <$keyfile>);
if(close($keyfile)) {
if(open(my $knownhostsh, ">", pp($knownhosts))) {
print $knownhostsh "$listenaddr ssh-rsa $rsahostkey[1]\n";
my @hostkey = split /\s+/, $line;
print $knownhostsh "$listenaddr $hostkey[0] $hostkey[1]\n";
if(!close($knownhostsh)) {
$error = "Error: cannot close file $knownhosts";
}