diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 103b04a49c..a66e03a430 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -719,6 +719,7 @@ cross-version-config-tests: untracked: true expire_in: "1 day" when: always + allow_failure: true # GL !9201 removed a test script that v9.20.0 attempts to call in conf.sh # Jobs for regular GCC builds on Alpine Linux 3.20 (amd64) diff --git a/bin/tests/system/autosign/ns3/keygen.sh b/bin/tests/system/autosign/ns3/keygen.sh index bc4dd5d8c2..54f53a46c8 100644 --- a/bin/tests/system/autosign/ns3/keygen.sh +++ b/bin/tests/system/autosign/ns3/keygen.sh @@ -157,10 +157,7 @@ $DSFROMKEY $ksk.key >dsset-${zone}. # None of these algorithms are supported for signing in FIPS mode # as they are MD5 and SHA1 based. # -if ( - cd .. - $SHELL ../testcrypto.sh -q RSASHA1 -); then +if [ $RSASHA1_SUPPORTED = 1 ]; then setup nsec-only.example cp $infile $zonefile ksk=$($KEYGEN -q -a RSASHA1 -fk $zone 2>kg.out) || dumpit kg.out diff --git a/bin/tests/system/autosign/tests.sh b/bin/tests/system/autosign/tests.sh index 3b7613226d..14064affe2 100755 --- a/bin/tests/system/autosign/tests.sh +++ b/bin/tests/system/autosign/tests.sh @@ -892,7 +892,7 @@ checkprivate nsec3.nsec3.example 10.53.0.3 || ret=1 checkprivate nsec3.optout.example 10.53.0.3 || ret=1 checkprivate nsec3-to-nsec.example 10.53.0.3 2 || ret=1 # automatically removed checkprivate nsec3-to-nsec3.example 10.53.0.3 2 || ret=1 # automatically removed -if $SHELL ../testcrypto.sh -q RSASHA1; then +if [ $RSASHA1_SUPPORTED = 1 ]; then checkprivate nsec-only.example 10.53.0.3 || ret=1 fi checkprivate oldsigs.example 10.53.0.3 2 || ret=1 # pre-signed @@ -1252,7 +1252,7 @@ del=$(grep "DNSKEY .* is now deleted" ns2/named.run | wc -l) [ "$del" -eq 0 ] || ret=1 pub=$(grep "DNSKEY .* is now published" ns3/named.run | grep -v "CDNSKEY" | wc -l) act=$(grep "DNSKEY .* is now active" ns3/named.run | wc -l) -if $SHELL ../testcrypto.sh -q RSASHA1; then +if [ $RSASHA1_SUPPORTED = 1 ]; then # Include two log lines for nsec-only zone. [ "$pub" -eq 53 ] || ret=1 [ "$act" -eq 53 ] || ret=1 diff --git a/bin/tests/system/checkconf/tests.sh b/bin/tests/system/checkconf/tests.sh index c995890aaa..ad7e2fbb47 100644 --- a/bin/tests/system/checkconf/tests.sh +++ b/bin/tests/system/checkconf/tests.sh @@ -642,7 +642,7 @@ status=$((status + ret)) n=$((n + 1)) echo_i "checking named-checkconf kasp nsec3 iterations errors ($n)" ret=0 -if ! ($SHELL ../testcrypto.sh -q RSASHA1); then +if [ $RSASHA1_SUPPORTED = 0 ]; then conf=kasp-bad-nsec3-iter-fips.conf expect=2 else @@ -660,7 +660,7 @@ n=$((n + 1)) echo_i "checking named-checkconf kasp nsec3 algorithm errors ($n)" ret=0 $CHECKCONF kasp-bad-nsec3-alg.conf >checkconf.out$n 2>&1 && ret=1 -if ! ($SHELL ../testcrypto.sh -q RSASHA1); then +if [ $RSASHA1_SUPPORTED = 0 ]; then grep "dnssec-policy: algorithm rsasha1 not supported" /dev/null || ret=1 else grep "dnssec-policy: cannot use nsec3 with algorithm 'RSASHA1'" /dev/null || ret=1 diff --git a/bin/tests/system/conf.sh b/bin/tests/system/conf.sh index e3e9a08fb9..320cf64795 100644 --- a/bin/tests/system/conf.sh +++ b/bin/tests/system/conf.sh @@ -99,42 +99,6 @@ send() { $PERL "$TOP_SRCDIR/bin/tests/system/send.pl" "$@" } -# -# Useful variables in test scripts -# - -# The following script sets the following algorithm-related variables. These -# are selected randomly at runtime from a list of supported algorithms. The -# randomization is deterministic and remains stable for a period of time for a -# given platform. -# -# Default algorithm for testing. -# DEFAULT_ALGORITHM -# DEFAULT_ALGORITHM_NUMBER -# DEFAULT_BITS -# -# This is an alternative algorithm for test cases that require more than one -# algorithm (for example algorithm rollover). Must be different from -# DEFAULT_ALGORITHM. -# ALTERNATIVE_ALGORITHM -# ALTERNATIVE_ALGORITHM_NUMBER -# ALTERNATIVE_BITS -# -# This is an algorithm that is used for tests against the "disable-algorithms" -# configuration option. Must be different from above algorithms. -# DISABLED_ALGORITHM -# DISABLED_ALGORITHM_NUMBER -# DISABLED_BITS -# -# There are multiple algoritms sets to choose from (see get_algorithms.py). To -# override the default choice, set the ALGORITHM_SET env var (see mkeys system -# test for example). -eval "$($PYTHON "$TOP_SRCDIR/bin/tests/system/get_algorithms.py")" - -# Default HMAC algorithm. -# also update _common/rndc.conf and _common/rndc.key when updating DEFAULT_HMAC -export DEFAULT_HMAC=hmac-sha256 - # # Useful functions in test scripts # diff --git a/bin/tests/system/conftest.py b/bin/tests/system/conftest.py index 5585d1e402..c578e4a8fd 100644 --- a/bin/tests/system/conftest.py +++ b/bin/tests/system/conftest.py @@ -277,6 +277,17 @@ def wait_for_zones_loaded(request, servers): watcher.wait_for_line("all zones loaded") +@pytest.fixture(scope="module", autouse=True) +def configure_algorithm_set(request): + """Configure the algorithm set to use in tests.""" + mark = _get_marker(request.node, "algorithm_set") + if not mark: + name = None + else: + name = mark.args[0] + isctest.vars.set_algorithm_set(name) + + @pytest.fixture(autouse=True) def logger(request, system_test_name): """Sets up logging facility specific to a particular test.""" diff --git a/bin/tests/system/dnssec/tests.sh b/bin/tests/system/dnssec/tests.sh index db6e2e5083..041443271c 100644 --- a/bin/tests/system/dnssec/tests.sh +++ b/bin/tests/system/dnssec/tests.sh @@ -1462,7 +1462,7 @@ echo_ic "check that 'dnssec-signzone -F' failed with disallowed algorithm ($n)" ret=0 if ! $FEATURETEST --fips-provider; then echo_i "skipped no FIPS provider available" -elif ! $SHELL ../testcrypto.sh -q RSASHA1; then +elif [ $RSASHA1_SUPPORTED = 0 ]; then echo_i "skipped: RSASHA1 is not supported" else ( @@ -3417,7 +3417,7 @@ if $FEATURETEST --have-fips-mode; then echo_i "skipped: already in FIPS mode" elif ! $FEATURETEST --fips-provider; then echo_i "skipped no FIPS provider available" -elif ! $SHELL ../testcrypto.sh -q RSASHA1; then +elif [ $RSASHA1_SUPPORTED = 0 ]; then echo_i "skipped: RSASHA1 is not supported" else $KEYGEN -F -a rsasha1 example.fips 2>keygen.err$n || true @@ -3433,7 +3433,7 @@ if $FEATURETEST --have-fips-mode; then echo_i "skipped: already in FIPS mode" elif ! $FEATURETEST --fips-provider; then echo_i "skipped: cannot switch to FIPS mode" -elif ! $SHELL ../testcrypto.sh -q RSASHA1; then +elif [ $RSASHA1_SUPPORTED = 0 ]; then echo_i "skipped: RSASHA1 is not supported" else $KEYGEN -F -a nsec3rsasha1 example.fips 2>keygen.err$n || true diff --git a/bin/tests/system/ecdsa/clean.sh b/bin/tests/system/ecdsa/clean.sh index 16b3aab06c..7cc30b604b 100644 --- a/bin/tests/system/ecdsa/clean.sh +++ b/bin/tests/system/ecdsa/clean.sh @@ -24,4 +24,3 @@ rm -f ns*/named.run rm -f ns*/root.db rm -f ns*/signer.err rm -f ns*/trusted.conf -rm -f *-supported.file diff --git a/bin/tests/system/ecdsa/ns1/sign.sh b/bin/tests/system/ecdsa/ns1/sign.sh index b7733442a1..2d49065639 100644 --- a/bin/tests/system/ecdsa/ns1/sign.sh +++ b/bin/tests/system/ecdsa/ns1/sign.sh @@ -23,14 +23,14 @@ echo_i "ns1/sign.sh" cp $infile $zonefile -if [ -f ../ecdsa256-supported.file ]; then +if [ $ECDSAP256SHA256_SUPPORTED = 1 ]; then zsk256=$($KEYGEN -q -a ECDSA256 -n zone "$zone") ksk256=$($KEYGEN -q -a ECDSA256 -n zone -f KSK "$zone") cat "$ksk256.key" "$zsk256.key" >>"$zonefile" $DSFROMKEY -a sha-256 "$ksk256.key" >>dsset-256 fi -if [ -f ../ecdsa384-supported.file ]; then +if [ $ECDSAP384SHA384_SUPPORTED = 1 ]; then zsk384=$($KEYGEN -q -a ECDSA384 -n zone "$zone") ksk384=$($KEYGEN -q -a ECDSA384 -n zone -f KSK "$zone") cat "$ksk384.key" "$zsk384.key" >>"$zonefile" @@ -38,7 +38,7 @@ if [ -f ../ecdsa384-supported.file ]; then fi # Configure the resolving server with a static key. -if [ -f ../ecdsa256-supported.file ]; then +if [ $ECDSAP256SHA256_SUPPORTED = 1 ]; then keyfile_to_static_ds $ksk256 >trusted.conf cp trusted.conf ../ns2/trusted.conf else @@ -46,7 +46,7 @@ else cp trusted.conf ../ns2/trusted.conf fi -if [ -f ../ecdsa384-supported.file ]; then +if [ $ECDSAP384SHA384_SUPPORTED = 1 ]; then keyfile_to_static_ds $ksk384 >trusted.conf cp trusted.conf ../ns3/trusted.conf else diff --git a/bin/tests/system/ecdsa/setup.sh b/bin/tests/system/ecdsa/setup.sh index 466d015983..89aa024bb7 100644 --- a/bin/tests/system/ecdsa/setup.sh +++ b/bin/tests/system/ecdsa/setup.sh @@ -15,14 +15,6 @@ set -e . ../conf.sh -if $SHELL ../testcrypto.sh ecdsap256sha256; then - echo "yes" >ecdsa256-supported.file -fi - -if $SHELL ../testcrypto.sh ecdsap384sha384; then - echo "yes" >ecdsa384-supported.file -fi - copy_setports ns1/named.conf.in ns1/named.conf copy_setports ns2/named.conf.in ns2/named.conf copy_setports ns3/named.conf.in ns3/named.conf diff --git a/bin/tests/system/ecdsa/tests.sh b/bin/tests/system/ecdsa/tests.sh index f596fbf78f..7016bf2ab5 100644 --- a/bin/tests/system/ecdsa/tests.sh +++ b/bin/tests/system/ecdsa/tests.sh @@ -22,7 +22,7 @@ dig_with_opts() { "$DIG" +tcp +noau +noadd +nosea +nostat +nocmd +dnssec -p "$PORT" "$@" } -if [ -f ecdsa256-supported.file ]; then +if [ $ECDSAP256SHA256_SUPPORTED = 1 ]; then n=$((n + 1)) echo_i "checking that ECDSA256 positive validation works ($n)" ret=0 @@ -36,7 +36,7 @@ else echo_i "algorithm ECDSA256 not supported, skipping test" fi -if [ -f ecdsa384-supported.file ]; then +if [ $ECDSAP384SHA384_SUPPORTED = 1 ]; then n=$((n + 1)) echo_i "checking that ECDSA384 positive validation works ($n)" ret=0 diff --git a/bin/tests/system/eddsa/clean.sh b/bin/tests/system/eddsa/clean.sh index c1238313d5..38be2c969d 100644 --- a/bin/tests/system/eddsa/clean.sh +++ b/bin/tests/system/eddsa/clean.sh @@ -25,4 +25,3 @@ rm -f ns*/root.db rm -f ns*/signer.err rm -f ns*/trusted.conf rm -f ns*/example.com.db -rm -f *-supported.file diff --git a/bin/tests/system/eddsa/ns1/sign.sh b/bin/tests/system/eddsa/ns1/sign.sh index f2df3284dc..d1b06f7c05 100644 --- a/bin/tests/system/eddsa/ns1/sign.sh +++ b/bin/tests/system/eddsa/ns1/sign.sh @@ -23,14 +23,14 @@ echo_i "ns1/sign.sh" cp $infile $zonefile -if [ -f ../ed25519-supported.file ]; then +if [ $ED25519_SUPPORTED = 1 ]; then zsk25519=$($KEYGEN -q -a ED25519 -n zone "$zone") ksk25519=$($KEYGEN -q -a ED25519 -n zone -f KSK "$zone") cat "$ksk25519.key" "$zsk25519.key" >>"$zonefile" $DSFROMKEY -a sha-256 "$ksk25519.key" >>dsset-256 fi -if [ -f ../ed448-supported.file ]; then +if [ $ED448_SUPPORTED = 1 ]; then zsk448=$($KEYGEN -q -a ED448 -n zone "$zone") ksk448=$($KEYGEN -q -a ED448 -n zone -f KSK "$zone") cat "$ksk448.key" "$zsk448.key" >>"$zonefile" @@ -38,7 +38,7 @@ if [ -f ../ed448-supported.file ]; then fi # Configure the resolving server with a static key. -if [ -f ../ed25519-supported.file ]; then +if [ $ED25519_SUPPORTED = 1 ]; then keyfile_to_static_ds $ksk25519 >trusted.conf cp trusted.conf ../ns2/trusted.conf else @@ -46,7 +46,7 @@ else cp trusted.conf ../ns2/trusted.conf fi -if [ -f ../ed448-supported.file ]; then +if [ $ED448_SUPPORTED = 1 ]; then keyfile_to_static_ds $ksk448 >trusted.conf cp trusted.conf ../ns3/trusted.conf else diff --git a/bin/tests/system/eddsa/ns2/sign.sh b/bin/tests/system/eddsa/ns2/sign.sh index 04322fd272..175263cdf9 100644 --- a/bin/tests/system/eddsa/ns2/sign.sh +++ b/bin/tests/system/eddsa/ns2/sign.sh @@ -25,7 +25,7 @@ echo_i "ns2/sign.sh" cp $infile $zonefile -if [ -f ../ed25519-supported.file ]; then +if [ $ED25519_SUPPORTED = 1 ]; then for i in Xexample.com.+015+03613 Xexample.com.+015+35217; do cp "$i.key" "$(echo $i.key | sed s/X/K/)" diff --git a/bin/tests/system/eddsa/ns3/sign.sh b/bin/tests/system/eddsa/ns3/sign.sh index 7c625bcd31..1245adb3ad 100644 --- a/bin/tests/system/eddsa/ns3/sign.sh +++ b/bin/tests/system/eddsa/ns3/sign.sh @@ -25,7 +25,7 @@ echo_i "ns3/sign.sh" cp $infile $zonefile -if [ -f ../ed448-supported.file ]; then +if [ $ED448_SUPPORTED = 1 ]; then for i in Xexample.com.+016+09713 Xexample.com.+016+38353; do cp "$i.key" "$(echo $i.key | sed s/X/K/)" cp "$i.private" "$(echo $i.private | sed s/X/K/)" diff --git a/bin/tests/system/eddsa/prereq.sh b/bin/tests/system/eddsa/prereq.sh index 98ed0323d4..ccf967b9f2 100644 --- a/bin/tests/system/eddsa/prereq.sh +++ b/bin/tests/system/eddsa/prereq.sh @@ -15,12 +15,6 @@ set -e . ../conf.sh -supported=0 -if $SHELL ../testcrypto.sh ed25519; then - supported=1 +if [ $ED25519_SUPPORTED = 0 ] && [ $ED448_SUPPORTED = 0 ]; then + exit 1 fi -if $SHELL ../testcrypto.sh ed448; then - supported=1 -fi - -[ "$supported" -eq 1 ] || exit 1 diff --git a/bin/tests/system/eddsa/setup.sh b/bin/tests/system/eddsa/setup.sh index cad2756064..5d25331aff 100644 --- a/bin/tests/system/eddsa/setup.sh +++ b/bin/tests/system/eddsa/setup.sh @@ -15,14 +15,6 @@ set -e . ../conf.sh -if $SHELL ../testcrypto.sh ed25519; then - echo "yes" >ed25519-supported.file -fi - -if $SHELL ../testcrypto.sh ed448; then - echo "yes" >ed448-supported.file -fi - copy_setports ns1/named.conf.in ns1/named.conf copy_setports ns2/named.conf.in ns2/named.conf copy_setports ns3/named.conf.in ns3/named.conf diff --git a/bin/tests/system/eddsa/tests.sh b/bin/tests/system/eddsa/tests.sh index 93cf5cb9c8..4967ff2835 100644 --- a/bin/tests/system/eddsa/tests.sh +++ b/bin/tests/system/eddsa/tests.sh @@ -22,7 +22,7 @@ dig_with_opts() { "$DIG" +tcp +noau +noadd +nosea +nostat +nocmd +dnssec -p "$PORT" "$@" } -if [ -f ed25519-supported.file ]; then +if [ $ED25519_SUPPORTED = 1 ]; then # Check the example. domain n=$((n + 1)) echo_i "checking that Ed25519 positive validation works ($n)" @@ -50,7 +50,7 @@ fi n=$((n + 1)) ret=0 -if [ -f ed448-supported.file ]; then +if [ $ED448_SUPPORTED = 1 ]; then # Check the example. domain n=$((n + 1)) echo_i "checking that Ed448 positive validation works ($n)" diff --git a/bin/tests/system/enginepkcs11/setup.sh b/bin/tests/system/enginepkcs11/setup.sh index 51d59dd854..e0dd87ae49 100644 --- a/bin/tests/system/enginepkcs11/setup.sh +++ b/bin/tests/system/enginepkcs11/setup.sh @@ -59,9 +59,11 @@ for algtypebits in rsasha256:rsa:2048 rsasha512:rsa:2048 \ alg=$(echo "$algtypebits" | cut -f 1 -d :) type=$(echo "$algtypebits" | cut -f 2 -d :) bits=$(echo "$algtypebits" | cut -f 3 -d :) + alg_upper=$(echo "$alg" | tr '[:lower:]' '[:upper:]') + supported=$(eval "echo \$${alg_upper}_SUPPORTED") tld="example" - if $SHELL ../testcrypto.sh $alg; then + if [ "${supported}" = 1 ]; then zone="$alg.$tld" zonefile="zone.$alg.$tld.db" ret=0 @@ -191,9 +193,11 @@ algtypebits="ecdsap256sha256:EC:prime256v1" alg=$(echo "$algtypebits" | cut -f 1 -d :) type=$(echo "$algtypebits" | cut -f 2 -d :) bits=$(echo "$algtypebits" | cut -f 3 -d :) +alg_upper=$(echo "$alg" | tr '[:lower:]' '[:upper:]') +supported=$(eval "echo \$${alg_upper}_SUPPORTED") tld="views" -if $SHELL ../testcrypto.sh $alg; then +if [ "${supported}" = 1 ]; then zone="$alg.$tld" zonefile1="zone.$alg.$tld.view1.db" zonefile2="zone.$alg.$tld.view2.db" diff --git a/bin/tests/system/isctest/__main__.py b/bin/tests/system/isctest/__main__.py index 2b82a81d46..d1be74c727 100644 --- a/bin/tests/system/isctest/__main__.py +++ b/bin/tests/system/isctest/__main__.py @@ -9,9 +9,16 @@ # See the COPYRIGHT file distributed with this work for additional # information regarding copyright ownership. -from .vars import ALL +import logging + +from . import log +from .vars import ALL, init_vars if __name__ == "__main__": + # use root logger as fallback - we're not interested in proper logs here + log.basic.LOGGERS["conftest"] = logging.getLogger() + + init_vars() for name, value in ALL.items(): print(f"export {name}={value}") diff --git a/bin/tests/system/isctest/log/basic.py b/bin/tests/system/isctest/log/basic.py index b3987b27f9..67121d2e24 100644 --- a/bin/tests/system/isctest/log/basic.py +++ b/bin/tests/system/isctest/log/basic.py @@ -14,7 +14,6 @@ from pathlib import Path from typing import Dict, Optional -CONFTEST_LOGGER = logging.getLogger("conftest") LOG_FORMAT = "%(asctime)s %(levelname)7s:%(name)s %(message)s" LOGGERS = { diff --git a/bin/tests/system/isctest/vars/__init__.py b/bin/tests/system/isctest/vars/__init__.py index 7c06a247a2..1af9e20767 100644 --- a/bin/tests/system/isctest/vars/__init__.py +++ b/bin/tests/system/isctest/vars/__init__.py @@ -12,12 +12,15 @@ import os from .all import ALL +from .algorithms import init_crypto_supported, set_algorithm_set from .openssl import parse_openssl_config from .. import log def init_vars(): """Initializes the environment variables.""" + init_crypto_supported() + set_algorithm_set(os.getenv("ALGORITHM_SET")) parse_openssl_config(ALL["OPENSSL_CONF"]) os.environ.update(ALL) diff --git a/bin/tests/system/get_algorithms.py b/bin/tests/system/isctest/vars/algorithms.py old mode 100755 new mode 100644 similarity index 59% rename from bin/tests/system/get_algorithms.py rename to bin/tests/system/isctest/vars/algorithms.py index 663b986333..26bcc579f8 --- a/bin/tests/system/get_algorithms.py +++ b/bin/tests/system/isctest/vars/algorithms.py @@ -1,5 +1,3 @@ -#!/usr/bin/python3 - # Copyright (C) Internet Systems Consortium, Inc. ("ISC") # # SPDX-License-Identifier: MPL-2.0 @@ -11,22 +9,43 @@ # See the COPYRIGHT file distributed with this work for additional # information regarding copyright ownership. -# This script is a 'port' broker. It keeps track of ports given to the -# individual system subtests, so every test is given a unique port range. - -import logging import os -from pathlib import Path import platform import random import subprocess +import tempfile import time -from typing import Dict, List, NamedTuple, Union +from typing import Dict, List, NamedTuple, Optional, Union -# Uncomment to enable DEBUG logging -# logging.basicConfig( -# format="get_algorithms.py %(levelname)s %(message)s", level=logging.DEBUG -# ) +from .basic import BASIC_VARS +from .. import log + +# Algorithms are selected randomly at runtime from a list of supported +# algorithms. The randomization is deterministic and remains stable for a +# period of time for a given platform. +ALG_VARS = { + # There are multiple algoritms sets to choose from (see ALGORITHM_SETS). To + # override the default choice, set the ALGORITHM_SET env var prior to + # loading this module or call set_algorithm_set(). + "ALGORITHM_SET": "none", + "DEFAULT_ALGORITHM": "", + "DEFAULT_ALGORITHM_NUMBER": "", + "DEFAULT_BITS": "", + # Alternative algorithm for test cases that require more than one algorithm + # (for example algorithm rollover). Must be different from + # DEFAULT_ALGORITHM. + "ALTERNATIVE_ALGORITHM": "", + "ALTERNATIVE_ALGORITHM_NUMBER": "", + "ALTERNATIVE_BITS": "", + # Algorithm that is used for tests against the "disable-algorithms" + # configuration option. Must be different from above algorithms. + "DISABLED_ALGORITHM": "", + "DISABLED_ALGORITHM_NUMBER": "", + "DISABLED_BITS": "", + # Default HMAC algorithm. Must match the rndc configuration in + # bin/tests/system/_common (rndc.conf, rndc.key) + "DEFAULT_HMAC": "hmac-sha256", +} STABLE_PERIOD = 3600 * 3 """number of secs during which algorithm selection remains stable""" @@ -93,57 +112,77 @@ ALGORITHM_SETS = { # ), } -TESTCRYPTO = Path(__file__).resolve().parent / "testcrypto.sh" -KEYGEN = os.getenv("KEYGEN", "") -if not KEYGEN: - raise RuntimeError("KEYGEN environment variable has to be set") - -ALGORITHM_SET = os.getenv("ALGORITHM_SET", "stable") -assert ALGORITHM_SET in ALGORITHM_SETS, f'ALGORITHM_SET "{ALGORITHM_SET}" unknown' -logging.debug('choosing from ALGORITHM_SET "%s"', ALGORITHM_SET) - - -def is_supported(alg: Algorithm) -> bool: +def is_crypto_supported(alg: Algorithm) -> bool: """Test whether a given algorithm is supported on the current platform.""" - try: - subprocess.run( - f"{TESTCRYPTO} -q {alg.name}", - shell=True, - check=True, - env={ - "KEYGEN": KEYGEN, - "TMPDIR": os.getenv("TMPDIR", "/tmp"), - }, + assert alg in ALL_ALGORITHMS, f"unknown algorithm: {alg}" + with tempfile.TemporaryDirectory() as tmpdir: + proc = subprocess.run( + [ + BASIC_VARS["KEYGEN"], + "-a", + alg.name, + "-b", + str(alg.bits), + "foo", + ], + cwd=tmpdir, + check=False, stdout=subprocess.DEVNULL, + stderr=subprocess.PIPE, ) - except subprocess.CalledProcessError as exc: - logging.debug(exc) - logging.info("algorithm %s not supported", alg.name) + if proc.returncode == 0: + return True + log.debug(f"dnssec-keygen stderr: {proc.stderr.decode('utf-8')}") + log.info("algorithm %s not supported", alg.name) return False - return True -def filter_supported(algs: AlgorithmSet) -> AlgorithmSet: +# Indicate algorithm support on the current platform. +CRYPTO_SUPPORTED_VARS = { + "RSASHA1_SUPPORTED": "0", + "RSASHA256_SUPPORTED": "0", + "RSASHA512_SUPPORTED": "0", + "ECDSAP256SHA256_SUPPORTED": "0", + "ECDSAP384SHA384_SUPPORTED": "0", + "ED25519_SUPPORTED": "0", + "ED448_SUPPORTED": "0", +} + +SUPPORTED_ALGORITHMS: List[Algorithm] = [] + + +def init_crypto_supported(): + """Initialize the environment variables indicating cryptography support.""" + for alg in ALL_ALGORITHMS: + supported = is_crypto_supported(alg) + if supported: + SUPPORTED_ALGORITHMS.append(alg) + envvar = f"{alg.name}_SUPPORTED" + val = "1" if supported else "0" + CRYPTO_SUPPORTED_VARS[envvar] = val + os.environ[envvar] = val + + +def _filter_supported(algs: AlgorithmSet) -> AlgorithmSet: """Select supported algorithms from the set.""" filtered = {} for alg_type in algs._fields: candidates = getattr(algs, alg_type) if isinstance(candidates, Algorithm): candidates = [candidates] - supported = list(filter(is_supported, candidates)) + supported = [alg for alg in candidates if alg in SUPPORTED_ALGORITHMS] if len(supported) == 1: supported = supported.pop() elif not supported: raise RuntimeError( - f'no {alg_type.upper()} algorithm from "{ALGORITHM_SET}" set ' - "supported on this platform" + f"no {alg_type.upper()} algorithm " "supported on this platform" ) filtered[alg_type] = supported return AlgorithmSet(**filtered) -def select_random(algs: AlgorithmSet, stable_period=STABLE_PERIOD) -> AlgorithmSet: +def _select_random(algs: AlgorithmSet, stable_period=STABLE_PERIOD) -> AlgorithmSet: """Select random DEFAULT, ALTERNATIVE and DISABLED algorithms from the set. The algorithm selection is deterministic for a given time period and @@ -200,9 +239,11 @@ def select_random(algs: AlgorithmSet, stable_period=STABLE_PERIOD) -> AlgorithmS return AlgorithmSet(default, alternative, disabled) -def algorithms_env(algs: AlgorithmSet) -> Dict[str, str]: +def _algorithms_env(algs: AlgorithmSet, name: str) -> Dict[str, str]: """Return environment variables with selected algorithms as a dict.""" - algs_env: Dict[str, str] = {} + algs_env = { + "ALGORITHM_SET": name, + } def set_alg_env(alg: Algorithm, prefix): algs_env[f"{prefix}_ALGORITHM"] = alg.name @@ -217,25 +258,23 @@ def algorithms_env(algs: AlgorithmSet) -> Dict[str, str]: set_alg_env(algs.alternative, "ALTERNATIVE") set_alg_env(algs.disabled, "DISABLED") - logging.info("selected algorithms: %s", algs_env) + log.info("selected algorithms: %s", algs_env) return algs_env -def main(): - try: - algs = ALGORITHM_SETS[ALGORITHM_SET] - algs = filter_supported(algs) - algs = select_random(algs) - algs_env = algorithms_env(algs) - except Exception: - # if anything goes wrong, the conf.sh ignores error codes, so make sure - # we set an environment variable to an error value that can be checked - # later by the test runner and/or tests themselves - print("export ALGORITHM_SET=error") - raise - for name, value in algs_env.items(): - print(f"export {name}={value}") +def set_algorithm_set(name: Optional[str]): + if name is None: + name = "stable" + assert name in ALGORITHM_SETS, f'ALGORITHM_SET "{name}" unknown' + if name == ALG_VARS["ALGORITHM_SET"]: + log.debug('algorithm set already configured: "%s"', name) + return + log.debug('choosing from ALGORITHM_SET "%s"', name) + algs = ALGORITHM_SETS[name] + algs = _filter_supported(algs) + algs = _select_random(algs) + algs_env = _algorithms_env(algs, name) -if __name__ == "__main__": - main() + ALG_VARS.update(algs_env) + os.environ.update(algs_env) diff --git a/bin/tests/system/isctest/vars/all.py b/bin/tests/system/isctest/vars/all.py index 3e6d49dc74..eabe2c3791 100644 --- a/bin/tests/system/isctest/vars/all.py +++ b/bin/tests/system/isctest/vars/all.py @@ -15,6 +15,7 @@ from collections import ChainMap from .autoconf import AC_VARS # type: ignore # pylint: enable=import-error +from .algorithms import ALG_VARS, CRYPTO_SUPPORTED_VARS from .basic import BASIC_VARS from .dirs import DIR_VARS from .openssl import OPENSSL_VARS @@ -52,4 +53,12 @@ class VarLookup(ChainMap): return iter(self.keys()) -ALL = VarLookup(AC_VARS, BASIC_VARS, OPENSSL_VARS, PORT_VARS, DIR_VARS) +ALL = VarLookup( + AC_VARS, + BASIC_VARS, + OPENSSL_VARS, + PORT_VARS, + DIR_VARS, + ALG_VARS, + CRYPTO_SUPPORTED_VARS, +) diff --git a/bin/tests/system/kasp/clean.sh b/bin/tests/system/kasp/clean.sh index 8102d50597..08acb23c1c 100644 --- a/bin/tests/system/kasp/clean.sh +++ b/bin/tests/system/kasp/clean.sh @@ -33,7 +33,6 @@ rm -rf ns3/keys/ rm -f *.created published.test* retired.test* rm -f rndc.dnssec.*.out.* rndc.zonestatus.out.* rm -f python.out.* -rm -f *-supported.file rm -f created.key-* unused.key-* rm -f ns3/ksk/K* ns3/zsk/K* rm -rf ./ns3/ksk/ ./ns3/zsk/ diff --git a/bin/tests/system/kasp/ns3/setup.sh b/bin/tests/system/kasp/ns3/setup.sh index dd9dc83d8f..69150ada52 100644 --- a/bin/tests/system/kasp/ns3/setup.sh +++ b/bin/tests/system/kasp/ns3/setup.sh @@ -66,10 +66,7 @@ cp template.db.in "i-am.special.kasp.db" # Set up RSASHA1 based zones # for zn in rsasha1 rsasha1-nsec3; do - if ( - cd .. - $SHELL ../testcrypto.sh -q RSASHA1 - ); then + if [ $RSASHA1_SUPPORTED = 1 ]; then setup "${zn}.kasp" cp template.db.in "$zonefile" else @@ -79,13 +76,13 @@ for zn in rsasha1 rsasha1-nsec3; do fi done -if [ -f ../ed25519-supported.file ]; then +if [ $ED25519_SUPPORTED = 1 ]; then setup "ed25519.kasp" cp template.db.in "$zonefile" cat ed25519.conf >>named.conf fi -if [ -f ../ed448-supported.file ]; then +if [ $ED448_SUPPORTED = 1 ]; then setup "ed448.kasp" cp template.db.in "$zonefile" cat ed448.conf >>named.conf diff --git a/bin/tests/system/kasp/setup.sh b/bin/tests/system/kasp/setup.sh index 1d11ba96fd..321fd689d7 100644 --- a/bin/tests/system/kasp/setup.sh +++ b/bin/tests/system/kasp/setup.sh @@ -22,7 +22,7 @@ mkdir keys mkdir ns3/keys copy_setports ns2/named.conf.in ns2/named.conf -if ! $SHELL ../testcrypto.sh -q RSASHA1; then +if [ $RSASHA1_SUPPORTED = 0 ]; then copy_setports ns3/named-fips.conf.in ns3/named.conf else copy_setports ns3/named-fips.conf.in ns3/named-fips.conf @@ -32,18 +32,10 @@ copy_setports ns4/named.conf.in ns4/named.conf copy_setports ns5/named.conf.in ns5/named.conf copy_setports ns6/named.conf.in ns6/named.conf -if $SHELL ../testcrypto.sh ed25519; then - echo "yes" >ed25519-supported.file -fi - -if $SHELL ../testcrypto.sh ed448; then - echo "yes" >ed448-supported.file -fi - copy_setports ns3/policies/autosign.conf.in ns3/policies/autosign.conf copy_setports ns3/policies/kasp-fips.conf.in ns3/policies/kasp-fips.conf copy_setports ns3/policies/kasp.conf.in ns3/policies/kasp.conf -if ! $SHELL ../testcrypto.sh -q RSASHA1; then +if [ $RSASHA1_SUPPORTED = 0 ]; then cp ns3/policies/kasp-fips.conf ns3/policies/kasp.conf fi @@ -51,7 +43,7 @@ copy_setports ns6/policies/csk1.conf.in ns6/policies/csk1.conf copy_setports ns6/policies/csk2.conf.in ns6/policies/csk2.conf copy_setports ns6/policies/kasp-fips.conf.in ns6/policies/kasp-fips.conf copy_setports ns6/policies/kasp.conf.in ns6/policies/kasp.conf -if ! $SHELL ../testcrypto.sh -q RSASHA1; then +if [ $RSASHA1_SUPPORTED = 0 ]; then cp ns6/policies/kasp-fips.conf ns6/policies/kasp.conf fi diff --git a/bin/tests/system/kasp/tests.sh b/bin/tests/system/kasp/tests.sh index fb4065acd3..8f538e4a53 100644 --- a/bin/tests/system/kasp/tests.sh +++ b/bin/tests/system/kasp/tests.sh @@ -826,7 +826,7 @@ set_keytimes_algorithm_policy() { # # Zone: rsasha1.kasp. # -if $SHELL ../testcrypto.sh -q RSASHA1; then +if [ $RSASHA1_SUPPORTED = 1 ]; then set_zone "rsasha1.kasp" set_policy "rsasha1" "3" "1234" set_server "ns3" "10.53.0.3" @@ -1173,7 +1173,7 @@ status=$((status + ret)) # # Zone: rsasha1-nsec3.kasp. # -if $SHELL ../testcrypto.sh -q RSASHA1; then +if [ $RSASHA1_SUPPORTED = 1 ]; then set_zone "rsasha1-nsec3.kasp" set_policy "rsasha1-nsec3" "3" "1234" set_server "ns3" "10.53.0.3" @@ -1275,7 +1275,7 @@ dnssec_verify # # Zone: ed25519.kasp. # -if [ -f ed25519-supported.file ]; then +if [ $ED25519_SUPPORTED = 1 ]; then set_zone "ed25519.kasp" set_policy "ed25519" "3" "1234" set_server "ns3" "10.53.0.3" @@ -1297,7 +1297,7 @@ fi # # Zone: ed448.kasp. # -if [ -f ed448-supported.file ]; then +if [ $ED448_SUPPORTED = 1 ]; then set_zone "ed448.kasp" set_policy "ed448" "3" "1234" set_server "ns3" "10.53.0.3" diff --git a/bin/tests/system/keyfromlabel/tests.sh b/bin/tests/system/keyfromlabel/tests.sh index f29f327098..ae4c9a6e6e 100644 --- a/bin/tests/system/keyfromlabel/tests.sh +++ b/bin/tests/system/keyfromlabel/tests.sh @@ -47,8 +47,10 @@ for algtypebits in rsasha256:rsa:2048 rsasha512:rsa:2048 \ alg=$(echo "$algtypebits" | cut -f 1 -d :) type=$(echo "$algtypebits" | cut -f 2 -d :) bits=$(echo "$algtypebits" | cut -f 3 -d :) + alg_upper=$(echo "$alg" | tr '[:lower:]' '[:upper:]') + supported=$(eval "echo \$${alg_upper}_SUPPORTED") - if $SHELL ../testcrypto.sh $alg; then + if [ "${supported}" = 1 ]; then zone="$alg.example" zonefile="zone.$alg.example.db" ret=0 diff --git a/bin/tests/system/mkeys/setup.sh b/bin/tests/system/mkeys/setup.sh index 7251e30f17..4b5e752afd 100644 --- a/bin/tests/system/mkeys/setup.sh +++ b/bin/tests/system/mkeys/setup.sh @@ -11,14 +11,11 @@ # See the COPYRIGHT file distributed with this work for additional # information regarding copyright ownership. +# Explicitly setting ALGORITHM_SET is only needed is the script is executed +# standalone without the pytest runner (e.g. for debugging). export ALGORITHM_SET="ecc_default" -. ../conf.sh -# Ensure the selected algorithm set is okay. -if [ "$ALGORITHM_SET" = "error" ]; then - echofail "Algorithm selection failed." >&2 - exit 1 -fi +. ../conf.sh copy_setports ns1/named1.conf.in ns1/named.conf copy_setports ns2/named.conf.in ns2/named.conf diff --git a/bin/tests/system/mkeys/tests.sh b/bin/tests/system/mkeys/tests.sh index 40248f96d9..b460121b04 100644 --- a/bin/tests/system/mkeys/tests.sh +++ b/bin/tests/system/mkeys/tests.sh @@ -13,7 +13,6 @@ set -e -export ALGORITHM_SET="ecc_default" #shellcheck source=conf.sh . ../conf.sh diff --git a/bin/tests/system/mkeys/tests_sh_mkeys.py b/bin/tests/system/mkeys/tests_sh_mkeys.py index 141ee838aa..48d79acf28 100644 --- a/bin/tests/system/mkeys/tests_sh_mkeys.py +++ b/bin/tests/system/mkeys/tests_sh_mkeys.py @@ -9,6 +9,10 @@ # See the COPYRIGHT file distributed with this work for additional # information regarding copyright ownership. +import pytest + +pytestmark = pytest.mark.algorithm_set("ecc_default") + def test_mkeys(run_tests_sh): run_tests_sh() diff --git a/bin/tests/system/nsec3/ns3/setup.sh b/bin/tests/system/nsec3/ns3/setup.sh index 5ddcfc01b0..7db6d3910c 100644 --- a/bin/tests/system/nsec3/ns3/setup.sh +++ b/bin/tests/system/nsec3/ns3/setup.sh @@ -31,10 +31,7 @@ for zn in nsec-to-nsec3 nsec3 nsec3-other nsec3-change nsec3-to-nsec \ setup "${zn}.kasp" done -if ( - cd .. - $SHELL ../testcrypto.sh -q RSASHA1 -); then +if [ $RSASHA1_SUPPORTED = 1 ]; then for zn in rsasha1-to-nsec3 rsasha1-to-nsec3-wait nsec3-to-rsasha1 \ nsec3-to-rsasha1-ds; do setup "${zn}.kasp" diff --git a/bin/tests/system/nsec3/setup.sh b/bin/tests/system/nsec3/setup.sh index b9112958e1..33772fd3f6 100644 --- a/bin/tests/system/nsec3/setup.sh +++ b/bin/tests/system/nsec3/setup.sh @@ -24,7 +24,7 @@ copy_setports ns2/named.conf.in ns2/named.conf $SHELL setup.sh ) -if ! ($SHELL ../testcrypto.sh -q RSASHA1); then +if [ $RSASHA1_SUPPORTED = 0 ]; then copy_setports ns3/named-fips.conf.in ns3/named.conf else copy_setports ns3/named-fips.conf.in ns3/named-fips.conf diff --git a/bin/tests/system/nsec3/tests.sh b/bin/tests/system/nsec3/tests.sh index f7ab72a7d4..bae2279aa4 100644 --- a/bin/tests/system/nsec3/tests.sh +++ b/bin/tests/system/nsec3/tests.sh @@ -242,7 +242,7 @@ set_key_default_values "KEY1" echo_i "initial check zone ${ZONE}" check_nsec -if ($SHELL ../testcrypto.sh -q RSASHA1); then +if [ $RSASHA1_SUPPORTED = 1 ]; then # Zone: rsasha1-to-nsec3.kasp. set_zone_policy "rsasha1-to-nsec3.kasp" "rsasha1" 1 3600 set_server "ns3" "10.53.0.3" @@ -391,7 +391,7 @@ check_nsec # Reconfig named. ret=0 echo_i "reconfig dnssec-policy to trigger nsec3 rollovers" -if ! ($SHELL ../testcrypto.sh -q RSASHA1); then +if [ $RSASHA1_SUPPORTED = 0 ]; then copy_setports ns3/named2-fips.conf.in ns3/named.conf else copy_setports ns3/named2-fips.conf.in ns3/named-fips.conf @@ -407,7 +407,7 @@ set_key_default_values "KEY1" echo_i "check zone ${ZONE} after reconfig" check_nsec3 -if ($SHELL ../testcrypto.sh -q RSASHA1); then +if [ $RSASHA1_SUPPORTED = 1 ]; then # Zone: rsasha1-to-nsec3.kasp. set_zone_policy "rsasha1-to-nsec3.kasp" "nsec3" 2 3600 set_server "ns3" "10.53.0.3" diff --git a/bin/tests/system/pytest.ini b/bin/tests/system/pytest.ini index ff17998e35..766b3dad2e 100644 --- a/bin/tests/system/pytest.ini +++ b/bin/tests/system/pytest.ini @@ -20,3 +20,4 @@ junit_logging = log junit_log_passing_tests = 0 markers = requires_zones_loaded: ensures the test does not start until the specified named instances load all configured zones + algorithm_set: use to select desired algorithms from isctest/vars/algorithms.py diff --git a/bin/tests/system/testcrypto.sh b/bin/tests/system/testcrypto.sh deleted file mode 100755 index aaf793b192..0000000000 --- a/bin/tests/system/testcrypto.sh +++ /dev/null @@ -1,94 +0,0 @@ -#!/bin/sh - -# Copyright (C) Internet Systems Consortium, Inc. ("ISC") -# -# SPDX-License-Identifier: MPL-2.0 -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, you can obtain one at https://mozilla.org/MPL/2.0/. -# -# See the COPYRIGHT file distributed with this work for additional -# information regarding copyright ownership. - -prog=$0 -args="" -quiet=0 -dir="" -msg="cryptography" - -if test -z "$KEYGEN"; then - . ../conf.sh - alg="-a $DEFAULT_ALGORITHM -b $DEFAULT_BITS" -else - alg="" - quiet=1 - args="-q" -fi - -while test "$#" -gt 0; do - case $1 in - -q) - if test $quiet -eq 0; then - args="$args -q" - quiet=1 - fi - ;; - rsa | RSA | rsasha1 | RSASHA1) - alg="-a RSASHA1" - msg="RSA cryptography" - ;; - rsasha256 | RSASHA256) - alg="-a RSASHA256" - msg="RSA cryptography" - ;; - rsasha512 | RSASHA512) - alg="-a RSASHA512" - msg="RSA cryptography" - ;; - ecdsa | ECDSA | ecdsap256sha256 | ECDSAP256SHA256) - alg="-a ECDSAP256SHA256" - msg="ECDSA cryptography" - ;; - ecdsap384sha384 | ECDSAP384SHA384) - alg="-a ECDSAP384SHA384" - msg="ECDSA cryptography" - ;; - eddsa | EDDSA | ed25519 | ED25519) - alg="-a ED25519" - msg="EDDSA cryptography" - ;; - ed448 | ED448) - alg="-a ED448" - msg="EDDSA cryptography" - ;; - *) - echo "${prog}: unknown argument" - exit 1 - ;; - esac - shift -done - -if test -z "$alg"; then - echo "${prog}: no algorithm selected" - exit 1 -fi - -if test -n "$TMPDIR"; then - dir=$(mktemp -d "$TMPDIR/XXXXXX") - args="$args -K $dir" -fi - -if $KEYGEN $args $alg foo >/dev/null 2>&1; then - if test -z "$dir"; then - rm -f Kfoo* - else - rm -rf "$dir" - fi -else - if test $quiet -eq 0; then - echo_i "This test requires support for $msg" >&2 - fi - exit 255 -fi