From 7be2c421bf2e9f71d2883e30cb98bae6a3b5e97d Mon Sep 17 00:00:00 2001 From: Viktor Szakats Date: Fri, 28 Mar 2025 14:33:02 +0100 Subject: [PATCH] runtests: rewrite `genserv.sh` in Perl To remove POSIX shell as an extra dependency for runtests. Also fix to `chmod 0600` the `.pem` file (was: `.prm`), and apply it _before_ writing the keys. Follow-up to 44341e736a3e2f7a2b25a774be3a9796e81abab9 #16824 Closes #16858 --- RELEASE-NOTES | 2 - docs/INSTALL-CMAKE.md | 1 - tests/certs/CMakeLists.txt | 18 ++---- tests/certs/Makefile.am | 8 +-- tests/certs/genserv.pl | 109 +++++++++++++++++++++++++++++++++++++ tests/certs/genserv.sh | 101 ---------------------------------- 6 files changed, 119 insertions(+), 120 deletions(-) create mode 100755 tests/certs/genserv.pl delete mode 100755 tests/certs/genserv.sh diff --git a/RELEASE-NOTES b/RELEASE-NOTES index 0bee551db2..3a84647ff7 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -62,7 +62,6 @@ This release includes the following bugfixes: o cmake: allow empty `IMPORT_LIB_SUFFIX`, add suffix collision detection [41] o cmake: avoid `-Wnonnull` warning in `HAVE_FSETXATTR_5` detection [81] o cmake: disable HTTPS-proxy as a feature if proxy is disabled [77] - o cmake: document `SH_EXECUTABLE` option [252] o cmake: drop `CURL_DISABLE_TESTS` option [94] o cmake: drop `HAVE_C_FLAG_Wno_long_double` logic for ancient Apple gcc [126] o cmake: drop `HAVE_IN_ADDR_T` from pre-fill too @@ -603,7 +602,6 @@ References to bug reports and discussions on issues: [249] = https://curl.se/bug/?i=16673 [250] = https://curl.se/bug/?i=16671 [251] = https://curl.se/bug/?i=16720 - [252] = https://curl.se/bug/?i=16830 [253] = https://curl.se/bug/?i=16723 [254] = https://curl.se/bug/?i=16705 [255] = https://curl.se/bug/?i=16719 diff --git a/docs/INSTALL-CMAKE.md b/docs/INSTALL-CMAKE.md index ddfaeffd57..5091e0d569 100644 --- a/docs/INSTALL-CMAKE.md +++ b/docs/INSTALL-CMAKE.md @@ -395,7 +395,6 @@ Details via CMake - `CLANG_TIDY`: `clang-tidy` tool used with `CURL_CLANG_TIDY=ON`. Default: `clang-tidy` - `PERL_EXECUTABLE`: Perl binary used throughout the build and tests. -- `SH_EXECUTABLE`: POSIX shell binary used throughout the build (for generating test certificates). ## Dependency options (libraries) diff --git a/tests/certs/CMakeLists.txt b/tests/certs/CMakeLists.txt index f2035b132c..83c0967377 100644 --- a/tests/certs/CMakeLists.txt +++ b/tests/certs/CMakeLists.txt @@ -25,18 +25,12 @@ curl_transform_makefile_inc("Makefile.inc" "${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake") include("${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake") -find_program(SH_EXECUTABLE "sh") -mark_as_advanced(SH_EXECUTABLE) -if(SH_EXECUTABLE) - string(REPLACE ";" " " _certconfigs "${CERTCONFIGS}") - add_custom_command(OUTPUT ${GENERATEDCERTS} - COMMAND ${SH_EXECUTABLE} -c "${CMAKE_CURRENT_SOURCE_DIR}/genserv.sh test ${_certconfigs}" - DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/genserv.sh" ${CERTCONFIG_CA} ${CERTCONFIGS} - VERBATIM - ) - add_custom_target(build-certs - DEPENDS ${GENERATEDCERTS}) -endif() +add_custom_command(OUTPUT ${GENERATEDCERTS} + COMMAND "${PERL_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/genserv.pl" "test" ${CERTCONFIGS} + DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/genserv.pl" ${CERTCONFIG_CA} ${CERTCONFIGS} + VERBATIM +) +add_custom_target(build-certs DEPENDS ${GENERATEDCERTS}) add_custom_target(clean-certs COMMAND ${CMAKE_COMMAND} -E remove ${GENERATEDCERTS} diff --git a/tests/certs/Makefile.am b/tests/certs/Makefile.am index 0e34fd7d06..1da0286889 100644 --- a/tests/certs/Makefile.am +++ b/tests/certs/Makefile.am @@ -26,7 +26,7 @@ AUTOMAKE_OPTIONS = foreign include Makefile.inc EXTRA_DIST = $(CERTCONFIG_CA) $(CERTCONFIGS) $(SRPFILES) CMakeLists.txt \ - genserv.sh + genserv.pl DISTCLEANFILES = $(GENERATEDCERTS) @@ -45,6 +45,6 @@ clean-certs: build-certs: test-ca.cacert # Generate all certs in a single shot, but declare just a single target file -# to support GNU Make <4.3 without "grouped explicit targets" support. -test-ca.cacert: $(CERTCONFIG_CA) $(CERTCONFIGS) genserv.sh - $(srcdir)/genserv.sh test $(CERTCONFIGS) +# to support GNU Make <4.3 without the "grouped explicit targets" feature. +test-ca.cacert: $(CERTCONFIG_CA) $(CERTCONFIGS) genserv.pl + $(PERL) $(srcdir)/genserv.pl test $(CERTCONFIGS) diff --git a/tests/certs/genserv.pl b/tests/certs/genserv.pl new file mode 100755 index 0000000000..092848988c --- /dev/null +++ b/tests/certs/genserv.pl @@ -0,0 +1,109 @@ +#!/usr/bin/env perl +#*************************************************************************** +# _ _ ____ _ +# Project ___| | | | _ \| | +# / __| | | | |_) | | +# | (__| |_| | _ <| |___ +# \___|\___/|_| \_\_____| +# +# Copyright (C) EdelWeb for EdelKey and OpenEvidence +# +# This software is licensed as described in the file COPYING, which +# you should have received as part of this distribution. The terms +# are also available at https://curl.se/docs/copyright.html. +# +# You may opt to use, copy, modify, merge, publish, distribute and/or sell +# copies of the Software, and permit persons to whom the Software is +# furnished to do so, under the terms of the COPYING file. +# +# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY +# KIND, either express or implied. +# +# SPDX-License-Identifier: curl +# +########################################################################### + +use strict; +use warnings; + +use File::Basename; + +my $OPENSSL = 'openssl'; +if(-f '/usr/local/ssl/bin/openssl') { + $OPENSSL = '/usr/local/ssl/bin/openssl'; +} + +my $SRCDIR = dirname(__FILE__); +my $fh; +my $dev_null = $^O eq 'MSWin32' ? 'NUL' : '/dev/null'; + +my $KEYSIZE = 'prime256v1'; +my $DURATION; +my $PREFIX; + +my $CAPREFIX = shift @ARGV; +if(!$CAPREFIX) { + print "Usage: genserv.pl [ ...]\n"; + exit 1; +} elsif(! -f "$CAPREFIX-ca.cacert" || + ! -f "$CAPREFIX-ca.key") { + + system($^O eq 'MSWin32' ? 'which' : 'command -v' ." $OPENSSL"); + system("$OPENSSL version"); + + $PREFIX = $CAPREFIX; + $DURATION = 6000; + + system("$OPENSSL genpkey -algorithm EC -pkeyopt ec_paramgen_curve:$KEYSIZE -pkeyopt ec_param_enc:named_curve " . + "-out $PREFIX-ca.key -pass pass:secret"); + system("$OPENSSL req -config $SRCDIR/$PREFIX-ca.prm -new -key $PREFIX-ca.key -out $PREFIX-ca.csr -passin pass:secret 2>$dev_null"); + system("$OPENSSL x509 -sha256 -extfile $SRCDIR/$PREFIX-ca.prm -days $DURATION " . + "-req -signkey $PREFIX-ca.key -in $PREFIX-ca.csr -out $PREFIX-ca.raw-cacert"); + system("$OPENSSL x509 -in $PREFIX-ca.raw-cacert -text -nameopt multiline > $PREFIX-ca.cacert"); + system("$OPENSSL x509 -in $PREFIX-ca.cacert -outform der -out $PREFIX-ca.der"); + system("$OPENSSL x509 -in $PREFIX-ca.cacert -text -nameopt multiline > $PREFIX-ca.crt"); + + print "CA root generated: $PREFIX $DURATION days $KEYSIZE\n"; +} + +$DURATION = 300; + +open($fh, '>>', "$CAPREFIX-ca.db") and close($fh); # for revoke server cert + +while(@ARGV) { + $PREFIX = shift @ARGV; + $PREFIX =~ s/\.prm$//; + + # pseudo-secrets + system("$OPENSSL genpkey -algorithm EC -pkeyopt ec_paramgen_curve:$KEYSIZE -pkeyopt ec_param_enc:named_curve " . + "-out $PREFIX.keyenc -pass pass:secret"); + system("$OPENSSL req -config $SRCDIR/$PREFIX.prm -new -key $PREFIX.keyenc -out $PREFIX.csr -passin pass:secret 2>$dev_null"); + system("$OPENSSL pkey -in $PREFIX.keyenc -out $PREFIX.key -passin pass:secret"); + + system("$OPENSSL pkey -in $PREFIX.key -pubout -outform DER -out $PREFIX.pub.der"); + system("$OPENSSL pkey -in $PREFIX.key -pubout -outform PEM -out $PREFIX.pub.pem"); + system("$OPENSSL x509 -sha256 -extfile $SRCDIR/$PREFIX.prm -days $DURATION " . + "-req -CA $CAPREFIX-ca.cacert -CAkey $CAPREFIX-ca.key -CAcreateserial -in $PREFIX.csr > $PREFIX.crt 2>$dev_null"); + + # revoke server cert + if(open($fh, '>', "$CAPREFIX-ca.cnt")) { + print $fh '01'; + close($fh); + } + system("$OPENSSL ca -config $SRCDIR/$CAPREFIX-ca.cnf -revoke $PREFIX.crt 2>$dev_null"); + + # issue CRL + system("$OPENSSL ca -config $SRCDIR/$CAPREFIX-ca.cnf -gencrl -out $PREFIX.crl 2>$dev_null"); + system("$OPENSSL x509 -in $PREFIX.crt -outform der -out $PREFIX.der"); + + # concatenate all together now + open($fh, '>', "$PREFIX.pem") and close($fh); + chmod 0600, "$PREFIX.pem"; + if(open($fh, '>>', "$PREFIX.pem")) { + my $fi; + print $fh do { local $/; open $fi, '<', $_ and <$fi> } for("$SRCDIR/$PREFIX.prm", "$PREFIX.key", "$PREFIX.crt"); + close($fh); + } + + print "Certificate generated: CA=$CAPREFIX ${DURATION}days $KEYSIZE $PREFIX\n"; +} diff --git a/tests/certs/genserv.sh b/tests/certs/genserv.sh deleted file mode 100755 index 1a818f35bf..0000000000 --- a/tests/certs/genserv.sh +++ /dev/null @@ -1,101 +0,0 @@ -#!/bin/sh -#*************************************************************************** -# _ _ ____ _ -# Project ___| | | | _ \| | -# / __| | | | |_) | | -# | (__| |_| | _ <| |___ -# \___|\___/|_| \_\_____| -# -# Copyright (C) EdelWeb for EdelKey and OpenEvidence -# -# This software is licensed as described in the file COPYING, which -# you should have received as part of this distribution. The terms -# are also available at https://curl.se/docs/copyright.html. -# -# You may opt to use, copy, modify, merge, publish, distribute and/or sell -# copies of the Software, and permit persons to whom the Software is -# furnished to do so, under the terms of the COPYING file. -# -# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY -# KIND, either express or implied. -# -# SPDX-License-Identifier: curl -# -########################################################################### - -# exit on first fail -set -eu - -OPENSSL=openssl -if [ -f /usr/local/ssl/bin/openssl ]; then - OPENSSL=/usr/local/ssl/bin/openssl -fi - -USAGE='echo Usage is genserv.sh [ ...]' - -SRCDIR="$(dirname "${0}")" - -KEYSIZE=prime256v1 - -CAPREFIX="${1:-}" -shift -if [ -z "$CAPREFIX" ]; then - echo 'No CA prefix' - $USAGE - exit -elif [ ! -f "$CAPREFIX-ca.cacert" ] || \ - [ ! -f "$CAPREFIX-ca.key" ]; then - - command -v "$OPENSSL" - "$OPENSSL" version - - # Generating CA root - PREFIX=$CAPREFIX - DURATION=6000 - - "$OPENSSL" genpkey -algorithm EC -pkeyopt ec_paramgen_curve:"$KEYSIZE" -pkeyopt ec_param_enc:named_curve \ - -out "$PREFIX-ca.key" -pass 'pass:secret' - "$OPENSSL" req -config "$SRCDIR/$PREFIX-ca.prm" -new -key "$PREFIX-ca.key" -out "$PREFIX-ca.csr" -passin 'pass:secret' 2>/dev/null - "$OPENSSL" x509 -sha256 -extfile "$SRCDIR/$PREFIX-ca.prm" -days "$DURATION" \ - -req -signkey "$PREFIX-ca.key" -in "$PREFIX-ca.csr" -out "$PREFIX-ca.raw-cacert" - "$OPENSSL" x509 -in "$PREFIX-ca.raw-cacert" -text -nameopt multiline > "$PREFIX-ca.cacert" - "$OPENSSL" x509 -in "$PREFIX-ca.cacert" -outform der -out "$PREFIX-ca.der" - "$OPENSSL" x509 -in "$PREFIX-ca.cacert" -text -nameopt multiline > "$PREFIX-ca.crt" - - echo "CA root generated: $PREFIX ${DURATION}days $KEYSIZE" -fi - -DURATION=300 - -while [ -n "${1:-}" ]; do - - PREFIX="${1%.prm}" - shift - - # pseudo-secrets - "$OPENSSL" genpkey -algorithm EC -pkeyopt ec_paramgen_curve:"$KEYSIZE" -pkeyopt ec_param_enc:named_curve \ - -out "$PREFIX.keyenc" -pass 'pass:secret' - "$OPENSSL" req -config "$SRCDIR/$PREFIX.prm" -new -key "$PREFIX.keyenc" -out "$PREFIX.csr" -passin 'pass:secret' 2>/dev/null - "$OPENSSL" pkey -in "$PREFIX.keyenc" -out "$PREFIX.key" -passin 'pass:secret' - - "$OPENSSL" pkey -in "$PREFIX.key" -pubout -outform DER -out "$PREFIX.pub.der" - "$OPENSSL" pkey -in "$PREFIX.key" -pubout -outform PEM -out "$PREFIX.pub.pem" - "$OPENSSL" x509 -sha256 -extfile "$SRCDIR/$PREFIX.prm" -days "$DURATION" \ - -req -CA "$CAPREFIX-ca.cacert" -CAkey "$CAPREFIX-ca.key" -CAcreateserial -in "$PREFIX.csr" > "$PREFIX.crt" 2>/dev/null - - # revoke server cert - touch "$CAPREFIX-ca.db" - echo 01 > "$CAPREFIX-ca.cnt" - "$OPENSSL" ca -config "$SRCDIR/$CAPREFIX-ca.cnf" -revoke "$PREFIX.crt" 2>/dev/null - - # issue CRL - "$OPENSSL" ca -config "$SRCDIR/$CAPREFIX-ca.cnf" -gencrl -out "$PREFIX.crl" 2>/dev/null - - "$OPENSSL" x509 -in "$PREFIX.crt" -outform der -out "$PREFIX.der" - - # all together now - cat "$SRCDIR/$PREFIX.prm" "$PREFIX.key" "$PREFIX.crt" > "$PREFIX.pem" - chmod o-r "$SRCDIR/$PREFIX.prm" - - echo "Certificate generated: CA=$CAPREFIX ${DURATION}days $KEYSIZE $PREFIX" -done -- 2.47.2