summaryrefslogtreecommitdiffstats
path: root/debian/tests
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 17:43:08 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 17:43:08 +0000
commitf450ba4056f3af0d17aeb1e5534619ce2231b63d (patch)
tree22ac78ea73d361fe6af5cafc06a338dc03c1745a /debian/tests
parentAdding upstream version 43.0. (diff)
downloadgdm3-f450ba4056f3af0d17aeb1e5534619ce2231b63d.tar.xz
gdm3-f450ba4056f3af0d17aeb1e5534619ce2231b63d.zip
Adding debian version 43.0-3.debian/43.0-3debian
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'debian/tests')
-rw-r--r--debian/tests/control20
-rw-r--r--debian/tests/sssd-gdm-smartcard-pam-auth-tester.sh256
-rw-r--r--debian/tests/sssd-softhism2-certificates-tests.sh896
3 files changed, 1172 insertions, 0 deletions
diff --git a/debian/tests/control b/debian/tests/control
new file mode 100644
index 0000000..10844ad
--- /dev/null
+++ b/debian/tests/control
@@ -0,0 +1,20 @@
+Test-Command: sudo env
+ OFFLINE_MODE=1
+ GDM_USER=Debian-gdm
+ bash debian/tests/sssd-gdm-smartcard-pam-auth-tester.sh
+Features: test-name=sssd-gdm-smartcard-auth-test
+Classes: desktop
+Depends: bash,
+ gdm3,
+ gnutls-bin,
+ openssl,
+ pamtester,
+ passwd,
+ softhsm2,
+ sssd,
+ util-linux
+Restrictions: breaks-testbed,
+ isolation-container,
+ needs-sudo,
+ allow-stderr
+
diff --git a/debian/tests/sssd-gdm-smartcard-pam-auth-tester.sh b/debian/tests/sssd-gdm-smartcard-pam-auth-tester.sh
new file mode 100644
index 0000000..0745ad4
--- /dev/null
+++ b/debian/tests/sssd-gdm-smartcard-pam-auth-tester.sh
@@ -0,0 +1,256 @@
+#!/usr/bin/env bash
+# Copyright 2023 - Marco Trevisan
+# Released under the GPLv3 terms
+#
+# A simple tool to simulate PAM authentication using GDM smartcard settings
+#
+# To be used with https://gist.github.com/3v1n0/287d02ca8e03936f1c7bba992173d47a
+set -xe
+
+required_tools=(
+ gdm3 # debian package: gdm3
+ pamtester # debian package: pamtester
+ softhsm2-util # debian package: softhsm2
+ sssd # debian package: sssd
+)
+
+if [[ ! -v OFFLINE_MODE ]]; then
+ required_tools+=(
+ wget # debian package: wget
+ )
+fi
+
+if [ "$(id -u)" != 0 ] || [ -z "$SUDO_USER" ]; then
+ echo "This tool requires sudo!"
+ exit 2
+fi
+
+for cmd in "${required_tools[@]}"; do
+ if ! command -v "$cmd" > /dev/null; then
+ echo "Tool $cmd missing"
+ exit 1
+ fi
+done
+
+PIN=${PIN:-123456}
+GDM_USER=${GDM_USER:-gdm}
+tmpdir=${TEST_TMPDIR:-$(mktemp -d -t "sssd-softhsm2-gdm-certs-XXXXXX")}
+backupsdir=
+
+alternative_pam_configs=(
+ /etc/pam.d/gdm-smartcard-sssd-exclusive
+ /etc/pam.d/gdm-smartcard-sssd-or-password
+)
+
+declare -a restore_paths
+declare -a delete_paths
+
+function restore_changes() {
+ for path in "${restore_paths[@]}"; do
+ local original_path
+ original_path="/$(realpath --strip --relative-base="$backupsdir" "$path")"
+ rm "$original_path" && mv "$path" "$original_path" || true
+ done
+
+ for path in "${delete_paths[@]}"; do
+ rm -f "$path"
+ #find "$(dirname "$path")" -empty -delete || true
+ done
+
+ update-alternatives --auto gdm-smartcard
+
+ if [ -e /etc/sssd/sssd.conf ]; then
+ chmod 600 /etc/sssd/sssd.conf || return 1
+ systemctl restart sssd || true
+ else
+ systemctl stop sssd || true
+ fi
+
+ if [ -e /etc/softhsm/softhsm2.conf ]; then
+ chmod 600 /etc/softhsm/softhsm2.conf || return 1
+ fi
+
+ rm -rf "$tmpdir"
+}
+
+function backup_file() {
+ if [ -z "$backupsdir" ]; then
+ backupsdir=$(mktemp -d -t "sssd-softhsm2-gdm-backups-XXXXXX")
+ fi
+
+ if [ -e "$1" ]; then
+ local back_dir="$backupsdir/$(dirname "$1")"
+ local back_path="$back_dir/$(basename "$1")"
+ [ ! -e "$back_path" ] || return 1
+
+ mkdir -p "$back_dir" || return 1
+ cp -a "$1" "$back_path" || return 1
+
+ restore_paths+=("$back_path")
+ else
+ delete_paths+=("$1")
+ fi
+}
+
+function handle_exit() {
+ exit_code=$?
+
+ restore_changes || return 1
+
+ if [ $exit_code = 0 ]; then
+ rm -rf "$backupsdir"
+ set +x
+ echo "Script completed successfully!"
+ else
+ set +x
+ echo "Script failed, check the log!"
+ echo " Backup preserved at $backupsdir"
+ echo " PAM Log: /var/log/auth.log"
+ echo " SSSD PAM Log: /var/log/sssd/sssd_pam.log"
+ echo " SSSD p11_child Log: /var/log/sssd/p11_child.log"
+ fi
+}
+
+trap 'handle_exit' EXIT
+
+tester="$(dirname "$0")"/sssd-softhism2-certificates-tests.sh
+if [ ! -e "$tester" ]; then
+ echo "Required $tester missing, we're downloading it..."
+ tester="$tmpdir/sssd-softhism2-certificates-tests.sh"
+ wget -q -c https://gist.github.com/3v1n0/287d02ca8e03936f1c7bba992173d47a/raw/sssd-softhism2-certificates-tests.sh \
+ -O "$tester"
+ [ -e "$tester" ] || exit 1
+fi
+
+export PIN TEST_TMPDIR="$tmpdir" GENERATE_SMART_CARDS=1 KEEP_TEMPORARY_FILES=1 NO_SSSD_TESTS=1
+bash "$tester"
+
+find "$tmpdir" -type d -exec chmod 777 {} \;
+find "$tmpdir" -type f -exec chmod 666 {} \;
+
+backup_file /etc/passwd
+backup_file /etc/shadow
+
+# Ensure that the test user has a non-trivial password. If it had a blank
+# password, then /etc/pam.d/gdm-smartcard-sssd-or-password would always
+# authenticate successfully
+if pamtester -v gdm-password "$SUDO_USER" authenticate; then
+ ( echo -n "$SUDO_USER:"; cat /proc/sys/kernel/random/uuid ) | chpasswd
+fi
+# Same, but for root
+if pamtester -v gdm-password root authenticate; then
+ ( echo -n "root:"; cat /proc/sys/kernel/random/uuid ) | chpasswd
+fi
+
+backup_file /etc/sssd/sssd.conf
+rm -f /etc/sssd/sssd.conf
+
+user_home="$(runuser -u "$SUDO_USER" -- sh -c 'echo ~')"
+mkdir -p "$user_home"
+chown "$SUDO_USER:$SUDO_USER" "$user_home"
+
+gdm_home="$(runuser -u "$GDM_USER" -- sh -c 'echo ~')"
+mkdir -p "$gdm_home"
+chown "$GDM_USER:$GDM_USER" "$gdm_home"
+
+user_config="$(runuser -u "$SUDO_USER" -- sh -c 'echo ${XDG_CONFIG_HOME:-~/.config}')"
+gdm_config="$(runuser -u "$GDM_USER" -- sh -c 'echo ${XDG_CONFIG_HOME:-~/.config}')"
+system_config="/etc"
+
+softhsm2_conf_paths=(
+ "$SUDO_USER:$user_config/softhsm2/softhsm2.conf"
+ "$GDM_USER:$gdm_config/softhsm2/softhsm2.conf"
+ "root:$system_config/softhsm/softhsm2.conf"
+)
+
+for path_pair in "${softhsm2_conf_paths[@]}"; do
+ IFS=":" read -r -a path <<< "${path_pair}"
+ path="${path[1]}"
+ backup_file "$path"
+ rm -f "$path"
+done
+
+function test_authentication() {
+ certificate_config="$1"
+ ca_db="$2"
+ verification_options="$3"
+
+ mkdir -p -m 700 /etc/sssd
+
+ cat <<EOF > /etc/sssd/sssd.conf || return 2
+[sssd]
+enable_files_domain = True
+services = pam
+#certificate_verification = $verification_options
+
+[certmap/implicit_files/$SUDO_USER]
+matchrule = <SUBJECT>.*Test Organization.*
+
+[pam]
+pam_cert_db_path = $ca_db
+pam_cert_verification = $verification_options
+pam_cert_auth = True
+pam_verbosity = 10
+debug_level = 10
+EOF
+
+ chmod 600 /etc/sssd/sssd.conf || return 2
+
+ for path_pair in "${softhsm2_conf_paths[@]}"; do
+ IFS=":" read -r -a path <<< "${path_pair}"
+ user="${path[0]}"
+ path="${path[1]}"
+
+ runuser -u "$user" -- mkdir -p "$(dirname "$path")" || return 2
+ runuser -u "$user" -- ln -sf "$certificate_config" "$path" || return 2
+ runuser -u "$user" -- softhsm2-util --show-slots | grep "Test Organization" \
+ || return 2
+ done
+
+ systemctl restart sssd || return 2
+
+ for alternative in "${alternative_pam_configs[@]}"; do
+ sudo update-alternatives --set gdm-smartcard "$alternative"
+
+ echo -n -e "$PIN" | runuser -u "$SUDO_USER" -- \
+ pamtester -v gdm-smartcard "$SUDO_USER" authenticate || return 2
+ echo -n -e "$PIN" | runuser -u "$SUDO_USER" -- \
+ pamtester -v gdm-smartcard "" authenticate || return 2
+
+ if echo -n -e "wrong${PIN}" | runuser -u "$SUDO_USER" -- \
+ pamtester -v gdm-smartcard "$SUDO_USER" authenticate; then
+ echo "Unexpected pass!"
+ return 2
+ fi
+
+ if echo -n -e "wrong${PIN}" | runuser -u "$SUDO_USER" -- \
+ pamtester -v gdm-smartcard "" authenticate; then
+ echo "Unexpected pass!"
+ return 2
+ fi
+
+ if echo -n -e "$PIN" | pamtester -v gdm-smartcard root authenticate; then
+ echo "Unexpected pass!"
+ return 2
+ fi
+
+ if [[ -v WAIT ]]; then
+ echo "Press any key and enter to continue"
+ systemctl restart gdm3
+ read
+ fi
+ done
+}
+
+test_authentication \
+ "$tmpdir/softhsm2-test-root-CA-trusted-certificate-0001.conf" \
+ "$tmpdir/test-full-chain-CA.pem"
+
+test_authentication \
+ "$tmpdir/softhsm2-test-sub-intermediate-CA-trusted-certificate-0001.conf" \
+ "$tmpdir/test-full-chain-CA.pem"
+
+test_authentication \
+ "$tmpdir/softhsm2-test-sub-intermediate-CA-trusted-certificate-0001.conf" \
+ "$tmpdir/test-sub-intermediate-CA.pem" \
+ "partial_chain"
diff --git a/debian/tests/sssd-softhism2-certificates-tests.sh b/debian/tests/sssd-softhism2-certificates-tests.sh
new file mode 100644
index 0000000..858af04
--- /dev/null
+++ b/debian/tests/sssd-softhism2-certificates-tests.sh
@@ -0,0 +1,896 @@
+#!/usr/bin/env bash
+# Copyright 2023 - Marco Trevisan
+# Released under the GPLv3 terms
+#
+# A simple tool to generate CA certificates signed by both a root cert authority
+# and by an intermediate one, to verify smartcard usage using softhism2.
+# Used to verify p11_child usage in SSSD.
+set -xe
+
+required_tools=(
+ p11tool # debian package: gnutls-bin
+ openssl # debian package: openssl
+ softhsm2-util # debian package: softhsm2
+)
+
+for cmd in "${required_tools[@]}"; do
+ if ! command -v "$cmd" > /dev/null; then
+ echo "Tool $cmd missing"
+ exit 1
+ fi
+done
+
+PIN=${PIN:-053350}
+SOFTHSM2_MODULE=${SOFTHSM2_MODULE:-$(realpath "$(find /usr/lib/*softhsm/libsofthsm2.so | head -n 1)")}
+SSSD_P11_CHILD=${SSSD_P11_CHILD:-/usr/libexec/sssd/p11_child}
+TOKEN_ID=${TOKEN_ID:-00112233445566778899FFAABBCCDDEEFF012345}
+
+if [ ! -v NO_SSSD_TESTS ]; then
+ if [ ! -x "$SSSD_P11_CHILD" ]; then
+ if [ ! -e "$$SSSD_P11_CHILD" ]; then
+ echo "Cannot find $SSSD_P11_CHILD"
+ else
+ echo "Cannot execute $SSSD_P11_CHILD, try using sudo..."
+ fi
+ exit 1
+ else
+ ca_db_arg="ca_db"
+ p11_child_help=$("$SSSD_P11_CHILD" --help &>/dev/stdout)
+ if echo "$p11_child_help" | grep nssdb -qs; then
+ ca_db_arg=nssdb
+ fi
+
+ echo "$p11_child_help" | grep -qs -- "--${ca_db_arg}"
+ fi
+fi
+
+if [ ! -e "$SOFTHSM2_MODULE" ]; then
+ echo "Cannot find softhsm2-module at $SOFTHSM2_MODULE"
+ exit 1
+fi
+
+tmpdir=${TEST_TMPDIR:-$(mktemp -d -t "sssd-softhsm2-XXXXXX")}
+keys_size=1024
+
+if [[ ! -v KEEP_TEMPORARY_FILES ]]; then
+ trap 'rm -rf "$tmpdir"' EXIT
+fi
+trap 'set +x; echo -e "\nUnexpected failure!!!"' ERR
+
+echo -n 01 > "$tmpdir/serial"
+touch "$tmpdir/index.txt"
+mkdir -p "$tmpdir/new_certs"
+
+function expect_fail() {
+ local cmd="$1"
+ shift
+
+ if "$cmd" "$@"; then
+ echo "Unexpected failure!"
+ exit 1
+ fi
+}
+
+
+## Root CA certificate generation
+
+cat <<EOF > "$tmpdir/test-root-CA.config"
+[ ca ]
+default_ca = CA_default
+
+[ CA_default ]
+dir = $tmpdir
+database = \$dir/index.txt
+new_certs_dir = \$dir/new_certs
+
+certificate = \$dir/test-root-CA.pem
+serial = \$dir/serial
+private_key = \$dir/test-root-CA-key.pem
+RANDFILE = \$dir/rand
+
+default_days = 365
+default_crl_days = 30
+default_md = sha256
+
+policy = policy_any
+email_in_dn = no
+
+name_opt = ca_default
+cert_opt = ca_default
+copy_extensions = copy
+
+[ usr_cert ]
+authorityKeyIdentifier = keyid, issuer
+
+[ v3_ca ]
+subjectKeyIdentifier = hash
+authorityKeyIdentifier = keyid:always,issuer:always
+basicConstraints = CA:true
+keyUsage = critical, digitalSignature, cRLSign, keyCertSign
+
+[ v3_intermediate_ca ]
+subjectKeyIdentifier = hash
+authorityKeyIdentifier = keyid:always,issuer:always
+basicConstraints = CA:true
+keyUsage = critical, digitalSignature, cRLSign, keyCertSign
+
+[ policy_any ]
+organizationName = supplied
+organizationalUnitName = supplied
+commonName = supplied
+emailAddress = optional
+
+[ req ]
+distinguished_name = req_distinguished_name
+prompt = no
+
+[ req_distinguished_name ]
+O = Test Organization
+OU = Test Organization Unit
+CN = Test Organization Root CA
+EOF
+
+root_ca_key_pass="pass:random-root-CA-password-${RANDOM}"
+
+openssl genrsa -aes256 \
+ -out "$tmpdir/test-root-CA-key.pem" \
+ -passout "$root_ca_key_pass" \
+ "$keys_size"
+
+openssl req -passin "$root_ca_key_pass" \
+ -batch -config "$tmpdir/test-root-CA.config" -x509 -new -nodes \
+ -key "$tmpdir/test-root-CA-key.pem" -sha256 -days 1024 -set_serial 0 \
+ -extensions v3_ca -out "$tmpdir/test-root-CA.pem"
+
+openssl x509 -noout -in "$tmpdir/test-root-CA.pem"
+
+
+## Intermediate CA certificate generation
+
+cat <<EOF > "$tmpdir/test-intermediate-CA.config"
+[ ca ]
+default_ca = CA_default
+
+[ CA_default ]
+dir = $tmpdir
+database = \$dir/index.txt
+new_certs_dir = \$dir/new_certs
+
+certificate = \$dir/test-intermediate-CA.pem
+serial = \$dir/serial
+private_key = \$dir/test-intermediate-CA-key.pem
+RANDFILE = \$dir/rand
+
+default_days = 365
+default_crl_days = 30
+default_md = sha256
+
+policy = policy_any
+email_in_dn = no
+
+name_opt = ca_default
+cert_opt = ca_default
+copy_extensions = copy
+
+[ usr_cert ]
+authorityKeyIdentifier = keyid, issuer
+
+[ v3_ca ]
+subjectKeyIdentifier = hash
+authorityKeyIdentifier = keyid:always,issuer:always
+basicConstraints = CA:true
+keyUsage = critical, digitalSignature, cRLSign, keyCertSign
+
+[ v3_intermediate_ca ]
+subjectKeyIdentifier = hash
+authorityKeyIdentifier = keyid:always,issuer:always
+basicConstraints = CA:true
+keyUsage = critical, digitalSignature, cRLSign, keyCertSign
+
+[ policy_any ]
+organizationName = supplied
+organizationalUnitName = supplied
+commonName = supplied
+emailAddress = optional
+
+[ req ]
+distinguished_name = req_distinguished_name
+prompt = no
+
+[ req_distinguished_name ]
+O = Test Organization
+OU = Test Organization Unit
+CN = Test Organization Intermediate CA
+EOF
+
+intermediate_ca_key_pass="pass:random-intermediate-CA-password-${RANDOM}"
+
+openssl genrsa -aes256 \
+ -out "$tmpdir/test-intermediate-CA-key.pem" \
+ -passout "$intermediate_ca_key_pass" \
+ "$keys_size"
+
+openssl req \
+ -batch -new -nodes \
+ -passin "$intermediate_ca_key_pass" \
+ -config "$tmpdir/test-intermediate-CA.config" \
+ -key "$tmpdir/test-intermediate-CA-key.pem" \
+ -passout "$root_ca_key_pass" \
+ -sha256 \
+ -extensions v3_ca \
+ -out "$tmpdir/test-intermediate-CA-certificate-request.pem"
+
+openssl req -text -noout -in "$tmpdir/test-intermediate-CA-certificate-request.pem"
+
+openssl ca \
+ -batch -notext \
+ -config "$tmpdir/test-root-CA.config" \
+ -passin "$root_ca_key_pass"\
+ -keyfile "$tmpdir/test-root-CA-key.pem" \
+ -in "$tmpdir/test-intermediate-CA-certificate-request.pem" \
+ -days 365 -extensions v3_intermediate_ca -out "$tmpdir/test-intermediate-CA.pem"
+
+openssl x509 -noout -in "$tmpdir/test-intermediate-CA.pem"
+openssl verify -CAfile "$tmpdir/test-root-CA.pem" "$tmpdir/test-intermediate-CA.pem"
+
+
+## Sub-Intermediate CA certificate generation
+
+cat <<EOF > "$tmpdir/test-sub-intermediate-CA.config"
+[ ca ]
+default_ca = CA_default
+
+[ CA_default ]
+dir = $tmpdir
+database = \$dir/index.txt
+new_certs_dir = \$dir/new_certs
+
+certificate = \$dir/test-sub-intermediate-CA.pem
+serial = \$dir/serial
+private_key = \$dir/test-sub-intermediate-CA-key.pem
+RANDFILE = \$dir/rand
+
+default_days = 365
+default_crl_days = 30
+default_md = sha256
+
+policy = policy_any
+email_in_dn = no
+
+name_opt = ca_default
+cert_opt = ca_default
+copy_extensions = copy
+
+[ usr_cert ]
+authorityKeyIdentifier = keyid, issuer
+
+[ v3_ca ]
+subjectKeyIdentifier = hash
+authorityKeyIdentifier = keyid:always,issuer:always
+basicConstraints = CA:true
+keyUsage = critical, digitalSignature, cRLSign, keyCertSign
+
+[ v3_intermediate_ca ]
+subjectKeyIdentifier = hash
+authorityKeyIdentifier = keyid:always,issuer:always
+basicConstraints = CA:true
+keyUsage = critical, digitalSignature, cRLSign, keyCertSign
+
+[ policy_any ]
+organizationName = supplied
+organizationalUnitName = supplied
+commonName = supplied
+emailAddress = optional
+
+[ req ]
+distinguished_name = req_distinguished_name
+prompt = no
+
+[ req_distinguished_name ]
+O = Test Organization
+OU = Test Organization Unit
+CN = Test Organization Sub Intermediate CA
+EOF
+
+sub_intermediate_ca_key_pass="pass:random-sub-intermediate-CA-password-${RANDOM}"
+
+openssl genrsa -aes256 \
+ -out "$tmpdir/test-sub-intermediate-CA-key.pem" \
+ -passout "$sub_intermediate_ca_key_pass" \
+ "$keys_size"
+
+openssl req \
+ -batch -new -nodes \
+ -passin "$sub_intermediate_ca_key_pass" \
+ -config "$tmpdir/test-sub-intermediate-CA.config" \
+ -key "$tmpdir/test-sub-intermediate-CA-key.pem" \
+ -passout "$intermediate_ca_key_pass" \
+ -sha256 \
+ -extensions v3_ca \
+ -out "$tmpdir/test-sub-intermediate-CA-certificate-request.pem"
+
+openssl req -text -noout -in "$tmpdir/test-sub-intermediate-CA-certificate-request.pem"
+
+openssl ca \
+ -batch -notext \
+ -config "$tmpdir/test-intermediate-CA.config" \
+ -passin "$intermediate_ca_key_pass"\
+ -keyfile "$tmpdir/test-intermediate-CA-key.pem" \
+ -in "$tmpdir/test-sub-intermediate-CA-certificate-request.pem" \
+ -days 365 -extensions v3_intermediate_ca -out "$tmpdir/test-sub-intermediate-CA.pem"
+
+openssl x509 -noout -in "$tmpdir/test-sub-intermediate-CA.pem"
+openssl verify \
+ -partial_chain \
+ -CAfile "$tmpdir/test-intermediate-CA.pem" "$tmpdir/test-sub-intermediate-CA.pem"
+
+expect_fail\
+ openssl verify \
+ -CAfile "$tmpdir/test-root-CA.pem" "$tmpdir/test-sub-intermediate-CA.pem"
+
+
+## Root CA Trusted Certificate generation
+
+cat <<"EOF" > "$tmpdir/test-root-CA-trusted-certificate-0001.config"
+[ req ]
+distinguished_name = req_distinguished_name
+prompt = no
+
+[ req_distinguished_name ]
+O = Test Organization
+OU = Test Organization Unit
+CN = Test Organization Root Trusted Certificate 0001
+
+[ req_exts ]
+basicConstraints = CA:FALSE
+nsCertType = client, email
+nsComment = "Test Organization Root CA trusted Certificate"
+subjectKeyIdentifier = hash
+keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment
+extendedKeyUsage = clientAuth, emailProtection
+subjectAltName = email:mail@3v1n0.net,URI:https://github.com/3v1n0/
+EOF
+
+root_ca_trusted_cert_0001_key_pass="pass:random-root-ca-trusted-cert-0001-${RANDOM}"
+openssl genrsa -aes256 \
+ -out "$tmpdir/test-root-CA-trusted-certificate-0001-key.pem" \
+ -passout "$root_ca_trusted_cert_0001_key_pass" \
+ "$keys_size"
+
+openssl req \
+ -new -nodes \
+ -reqexts req_exts \
+ -passin "$root_ca_trusted_cert_0001_key_pass" \
+ -key "$tmpdir/test-root-CA-trusted-certificate-0001-key.pem" \
+ -config "$tmpdir/test-root-CA-trusted-certificate-0001.config" \
+ -out "$tmpdir/test-root-CA-trusted-certificate-0001-request.pem"
+
+openssl req -text -noout \
+ -in "$tmpdir/test-root-CA-trusted-certificate-0001-request.pem"
+
+openssl ca \
+ -batch -notext \
+ -config "$tmpdir/test-root-CA.config" \
+ -passin "$root_ca_key_pass" \
+ -keyfile "$tmpdir/test-root-CA-key.pem" \
+ -in "$tmpdir/test-root-CA-trusted-certificate-0001-request.pem" \
+ -days 365 -extensions usr_cert \
+ -out "$tmpdir/test-root-CA-trusted-certificate-0001.pem"
+
+openssl x509 -noout \
+ -in "$tmpdir/test-root-CA-trusted-certificate-0001.pem"
+
+openssl verify -CAfile \
+ "$tmpdir/test-root-CA.pem" \
+ "$tmpdir/test-root-CA-trusted-certificate-0001.pem"
+
+expect_fail \
+ openssl verify -CAfile \
+ "$tmpdir/test-intermediate-CA.pem" \
+ "$tmpdir/test-root-CA-trusted-certificate-0001.pem"
+
+
+## Intermediate CA Trusted Certificate generation
+
+cat <<"EOF" > "$tmpdir/test-intermediate-CA-trusted-certificate-0001.config"
+[ req ]
+distinguished_name = req_distinguished_name
+prompt = no
+
+[ req_distinguished_name ]
+O = Test Organization
+OU = Test Organization Unit
+CN = Test Organization Intermediate Trusted Certificate 0001
+
+[ req_exts ]
+basicConstraints = CA:FALSE
+nsCertType = client, email
+nsComment = "Test Organization Intermediate CA trusted Certificate"
+subjectKeyIdentifier = hash
+keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment
+extendedKeyUsage = clientAuth, emailProtection
+subjectAltName = email:mail@3v1n0.net,URI:https://github.com/3v1n0/
+EOF
+
+intermediate_ca_trusted_cert_0001_key_pass="pass:random-intermediate-ca-trusted-cert-0001-${RANDOM}"
+
+openssl genrsa -aes256 \
+ -out "$tmpdir/test-intermediate-CA-trusted-certificate-0001-key.pem" \
+ -passout "$intermediate_ca_trusted_cert_0001_key_pass" \
+ "$keys_size"
+
+openssl req \
+ -new -nodes \
+ -reqexts req_exts \
+ -passin "$intermediate_ca_trusted_cert_0001_key_pass" \
+ -key "$tmpdir/test-intermediate-CA-trusted-certificate-0001-key.pem" \
+ -config "$tmpdir/test-intermediate-CA-trusted-certificate-0001.config" \
+ -out "$tmpdir/test-intermediate-CA-trusted-certificate-0001-request.pem"
+
+openssl req -text -noout \
+ -in "$tmpdir/test-intermediate-CA-trusted-certificate-0001-request.pem"
+
+openssl ca \
+ -passin "$intermediate_ca_key_pass" \
+ -config "$tmpdir/test-intermediate-CA.config" -batch -notext \
+ -keyfile "$tmpdir/test-intermediate-CA-key.pem" \
+ -in "$tmpdir/test-intermediate-CA-trusted-certificate-0001-request.pem" \
+ -days 365 -extensions usr_cert \
+ -out "$tmpdir/test-intermediate-CA-trusted-certificate-0001.pem"
+
+openssl x509 -noout \
+ -in "$tmpdir/test-intermediate-CA-trusted-certificate-0001.pem"
+
+echo "This certificate should not be trusted fully"
+expect_fail \
+ openssl verify \
+ -CAfile "$tmpdir/test-intermediate-CA.pem" \
+ "$tmpdir/test-intermediate-CA-trusted-certificate-0001.pem"
+
+openssl verify -partial_chain \
+ -CAfile "$tmpdir/test-intermediate-CA.pem" \
+ "$tmpdir/test-intermediate-CA-trusted-certificate-0001.pem"
+
+
+## Sub Intermediate CA Trusted Certificate generation
+
+cat <<"EOF" > "$tmpdir/test-sub-intermediate-CA-trusted-certificate-0001.config"
+[ req ]
+distinguished_name = req_distinguished_name
+prompt = no
+
+[ req_distinguished_name ]
+O = Test Organization
+OU = Test Organization Unit
+CN = Test Organization Sub Intermediate Trusted Certificate 0001
+
+[ req_exts ]
+basicConstraints = CA:FALSE
+nsCertType = client, email
+nsComment = "Test Organization Sub Intermediate CA trusted Certificate"
+subjectKeyIdentifier = hash
+keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment
+extendedKeyUsage = clientAuth, emailProtection
+subjectAltName = email:mail@3v1n0.net,URI:https://github.com/3v1n0/
+EOF
+
+sub_intermediate_ca_trusted_cert_0001_key_pass="pass:random-sub-intermediate-ca-trusted-cert-0001-${RANDOM}"
+
+openssl genrsa -aes256 \
+ -out "$tmpdir/test-sub-intermediate-CA-trusted-certificate-0001-key.pem" \
+ -passout "$sub_intermediate_ca_trusted_cert_0001_key_pass" \
+ "$keys_size"
+
+openssl req \
+ -new -nodes \
+ -reqexts req_exts \
+ -passin "$sub_intermediate_ca_trusted_cert_0001_key_pass" \
+ -key "$tmpdir/test-sub-intermediate-CA-trusted-certificate-0001-key.pem" \
+ -config "$tmpdir/test-sub-intermediate-CA-trusted-certificate-0001.config" \
+ -out "$tmpdir/test-sub-intermediate-CA-trusted-certificate-0001-request.pem"
+
+openssl req -text -noout \
+ -in "$tmpdir/test-sub-intermediate-CA-trusted-certificate-0001-request.pem"
+
+openssl ca \
+ -passin "$sub_intermediate_ca_key_pass" \
+ -config "$tmpdir/test-sub-intermediate-CA.config" -batch -notext \
+ -keyfile "$tmpdir/test-sub-intermediate-CA-key.pem" \
+ -in "$tmpdir/test-sub-intermediate-CA-trusted-certificate-0001-request.pem" \
+ -days 365 -extensions usr_cert \
+ -out "$tmpdir/test-sub-intermediate-CA-trusted-certificate-0001.pem"
+
+openssl x509 -noout \
+ -in "$tmpdir/test-sub-intermediate-CA-trusted-certificate-0001.pem"
+
+echo "This certificate should not be trusted fully"
+expect_fail \
+ openssl verify \
+ -CAfile "$tmpdir/test-sub-intermediate-CA.pem" \
+ "$tmpdir/test-sub-intermediate-CA-trusted-certificate-0001.pem"
+
+expect_fail \
+ openssl verify \
+ -CAfile "$tmpdir/test-intermediate-CA.pem" \
+ "$tmpdir/test-sub-intermediate-CA-trusted-certificate-0001.pem"
+
+openssl verify -partial_chain \
+ -CAfile "$tmpdir/test-sub-intermediate-CA.pem" \
+ "$tmpdir/test-sub-intermediate-CA-trusted-certificate-0001.pem"
+
+expect_fail \
+ openssl verify -partial_chain \
+ -CAfile "$tmpdir/test-intermediate-CA.pem" \
+ "$tmpdir/test-sub-intermediate-CA-trusted-certificate-0001.pem"
+
+
+## Full chain verification tests
+
+echo "Building a the full-chain CA file..."
+cat \
+ "$tmpdir/test-root-CA.pem" \
+ "$tmpdir/test-intermediate-CA.pem" \
+ "$tmpdir/test-sub-intermediate-CA.pem" \
+ > "$tmpdir/test-full-chain-CA.pem"
+
+cat \
+ "$tmpdir/test-root-CA.pem" \
+ "$tmpdir/test-intermediate-CA.pem" \
+ > "$tmpdir/test-root-intermediate-chain-CA.pem"
+
+cat \
+ "$tmpdir/test-intermediate-CA.pem" \
+ "$tmpdir/test-sub-intermediate-CA.pem" \
+ > "$tmpdir/test-intermediate-sub-chain-CA.pem"
+
+openssl crl2pkcs7 \
+ -nocrl -certfile "$tmpdir/test-full-chain-CA.pem" \
+ | openssl pkcs7 -print_certs -noout
+
+openssl verify \
+ -CAfile "$tmpdir/test-full-chain-CA.pem" \
+ "$tmpdir/test-intermediate-CA.pem"
+
+openssl verify \
+ -CAfile "$tmpdir/test-full-chain-CA.pem" \
+ "$tmpdir/test-root-CA-trusted-certificate-0001.pem"
+
+openssl verify \
+ -CAfile "$tmpdir/test-full-chain-CA.pem" \
+ "$tmpdir/test-intermediate-CA-trusted-certificate-0001.pem"
+
+openssl verify \
+ -CAfile "$tmpdir/test-full-chain-CA.pem" \
+ "$tmpdir/test-root-intermediate-chain-CA.pem"
+
+openssl verify \
+ -CAfile "$tmpdir/test-full-chain-CA.pem" \
+ "$tmpdir/test-sub-intermediate-CA-trusted-certificate-0001.pem"
+
+echo "Certificates generation completed!"
+
+function prepare_softhsm2_card() {
+ local certificate="$1"
+ local key_pass="$2"
+
+ local key_cn
+ local key_name
+ local tokens_dir
+ local output_cert_file
+
+ token_name=
+ key_name="$(basename "$certificate" .pem)"
+ key_cn="$(openssl x509 -noout -subject -nameopt multiline -in "$certificate" \
+ | sed -n 's/ *commonName *= //p')"
+
+ if [ -v SOFTHSM2_ISOLATED_CONFIGS ]; then
+ key_name+="-${RANDOM}"
+ fi
+
+ export SOFTHSM2_CONF="$tmpdir/softhsm2-${key_name}.conf"
+
+ tokens_dir="$tmpdir/$(basename "$SOFTHSM2_CONF" .conf)"
+ token_name="${key_cn:0:25} Token"
+
+ if [ ! -e "$SOFTHSM2_CONF" ] || [ ! -d "$tokens_dir" ]; then
+ local key_file
+ local decrypted_key
+
+ mkdir -p "$tokens_dir"
+
+ key_file="$tmpdir/${key_name}-key.pem"
+ decrypted_key="$tmpdir/${key_name}-key-decrypted.pem"
+
+ cat <<EOF > "$SOFTHSM2_CONF"
+directories.tokendir = $tokens_dir
+objectstore.backend = file
+slots.removable = true
+EOF
+
+ softhsm2-util --init-token \
+ --label "$token_name" \
+ --pin "$PIN" --so-pin "$PIN" --free || return 2
+
+ softhsm2-util --show-slots || return 2
+
+ p11tool \
+ --provider="$SOFTHSM2_MODULE" \
+ --write \
+ --no-mark-private \
+ --load-certificate="$certificate" \
+ --login --set-pin="$PIN" \
+ --label "$key_cn" \
+ --id "$TOKEN_ID" || return 2
+
+ openssl rsa \
+ -passin "$key_pass" \
+ -in "$key_file" \
+ -out "$decrypted_key" || return 2
+
+ p11tool \
+ --provider="$SOFTHSM2_MODULE" \
+ --write \
+ --load-privkey="$decrypted_key" \
+ --login --set-pin="$PIN" \
+ --label "$key_cn Key" \
+ --id "$TOKEN_ID" || return 2
+
+ rm "$decrypted_key"
+
+ p11tool \
+ --provider="$SOFTHSM2_MODULE" \
+ --list-all || return 2
+ fi
+
+ echo "$token_name"
+}
+
+function check_certificate() {
+ local certificate="$1"
+ local key_pass="$2"
+ local key_ring="$3"
+ local verify_option="$4"
+
+ prepare_softhsm2_card "$certificate" "$key_pass" || return 2
+
+ if [ -n "$verify_option" ]; then
+ local verify_arg="--verify=$verify_option"
+ fi
+
+ local output_base_name="SSSD-child-${RANDOM}"
+ local output_file="$tmpdir/$output_base_name.output"
+ output_cert_file="$tmpdir/$output_base_name.pem"
+
+ "$SSSD_P11_CHILD" \
+ --pre -d 10 \
+ --logger=stderr \
+ --debug-fd=2 \
+ "$verify_arg" \
+ --${ca_db_arg}="$key_ring" > "$output_file" || return 2
+
+ grep -qs "$TOKEN_ID" "$output_file" || return 2
+
+ echo "-----BEGIN CERTIFICATE-----" > "$output_cert_file"
+ tail -n1 "$output_file" >> "$output_cert_file"
+ echo "-----END CERTIFICATE-----" >> "$output_cert_file"
+
+ openssl x509 -text -noout -in "$output_cert_file" || return 2
+
+ local found_md5 expected_md5
+ expected_md5=$(openssl x509 -noout -modulus -in "$certificate")
+ found_md5=$(openssl x509 -noout -modulus -in "$output_cert_file")
+
+ if [ "$expected_md5" != "$found_md5" ]; then
+ echo "Unexpected certificate found: $found_md5"
+ return 3
+ fi
+
+ # Try to authorize now!
+
+ output_file="$tmpdir/${output_base_name}-auth.output"
+ output_cert_file="$tmpdir/$(basename "$output_file" .output).pem"
+
+ echo -n "$PIN" | "$SSSD_P11_CHILD" \
+ --auth -d 10 --debug-fd=2 \
+ --${ca_db_arg}="$key_ring" \
+ --pin \
+ --key_id "$TOKEN_ID" \
+ "$verify_arg" \
+ --token_name "$token_name" \
+ --module_name "$SOFTHSM2_MODULE" > "$output_file" || return 2
+
+ grep -qs "$TOKEN_ID" "$output_file" || return 2
+
+ echo "-----BEGIN CERTIFICATE-----" > "$output_cert_file"
+ tail -n1 "$output_file" >> "$output_cert_file"
+ echo "-----END CERTIFICATE-----" >> "$output_cert_file"
+
+ openssl x509 -text -noout -in "$output_cert_file" || return 2
+
+ found_md5=$(openssl x509 -noout -modulus -in "$output_cert_file")
+
+ if [ "$expected_md5" != "$found_md5" ]; then
+ echo "Unexpected certificate found: $found_md5"
+ return 3
+ fi
+}
+
+function valid_certificate() {
+ if ! check_certificate "$@"; then
+ echo "Unexpected failure!"
+ exit 2
+ fi
+}
+
+
+function invalid_certificate() {
+ if check_certificate "$@"; then
+ echo "Unexpected pass!"
+ exit 2
+ fi
+}
+
+if [[ -v NO_SSSD_TESTS ]]; then
+ if [[ -v GENERATE_SMART_CARDS ]]; then
+ prepare_softhsm2_card \
+ "$tmpdir/test-root-CA-trusted-certificate-0001.pem" \
+ "$root_ca_trusted_cert_0001_key_pass"
+
+ prepare_softhsm2_card \
+ "$tmpdir/test-intermediate-CA-trusted-certificate-0001.pem" \
+ "$intermediate_ca_trusted_cert_0001_key_pass"
+
+ prepare_softhsm2_card \
+ "$tmpdir/test-sub-intermediate-CA-trusted-certificate-0001.pem" \
+ "$sub_intermediate_ca_trusted_cert_0001_key_pass"
+ fi
+
+ echo "Certificates generation completed!"
+ exit 0
+fi
+
+## Checking that Root CA Trusted certificate is accepted
+
+invalid_certificate \
+ "$tmpdir/test-root-CA-trusted-certificate-0001.pem" \
+ "$root_ca_trusted_cert_0001_key_pass" \
+ /dev/null
+
+valid_certificate \
+ "$tmpdir/test-root-CA-trusted-certificate-0001.pem" \
+ "$root_ca_trusted_cert_0001_key_pass" \
+ /dev/null \
+ "no_verification"
+
+valid_certificate \
+ "$tmpdir/test-root-CA-trusted-certificate-0001.pem" \
+ "$root_ca_trusted_cert_0001_key_pass" \
+ "$tmpdir/test-root-CA.pem"
+
+valid_certificate \
+ "$tmpdir/test-root-CA-trusted-certificate-0001.pem" \
+ "$root_ca_trusted_cert_0001_key_pass" \
+ "$tmpdir/test-root-CA.pem" \
+ "partial_chain"
+
+valid_certificate \
+ "$tmpdir/test-root-CA-trusted-certificate-0001.pem" \
+ "$root_ca_trusted_cert_0001_key_pass" \
+ "$tmpdir/test-full-chain-CA.pem"
+
+valid_certificate \
+ "$tmpdir/test-root-CA-trusted-certificate-0001.pem" \
+ "$root_ca_trusted_cert_0001_key_pass" \
+ "$tmpdir/test-full-chain-CA.pem" \
+ "partial_chain"
+
+invalid_certificate \
+ "$tmpdir/test-root-CA-trusted-certificate-0001.pem" \
+ "$root_ca_trusted_cert_0001_key_pass" \
+ "$tmpdir/test-intermediate-CA.pem"
+
+invalid_certificate \
+ "$tmpdir/test-root-CA-trusted-certificate-0001.pem" \
+ "$root_ca_trusted_cert_0001_key_pass" \
+ "$tmpdir/test-intermediate-CA.pem" \
+ "partial_chain"
+
+
+## Checking that Intermediate CA Trusted certificate is accepted
+
+invalid_certificate \
+ "$tmpdir/test-intermediate-CA-trusted-certificate-0001.pem" \
+ "$intermediate_ca_trusted_cert_0001_key_pass" \
+ /dev/null
+
+valid_certificate \
+ "$tmpdir/test-intermediate-CA-trusted-certificate-0001.pem" \
+ "$intermediate_ca_trusted_cert_0001_key_pass" \
+ /dev/null \
+ "no_verification"
+
+invalid_certificate \
+ "$tmpdir/test-intermediate-CA-trusted-certificate-0001.pem" \
+ "$intermediate_ca_trusted_cert_0001_key_pass" \
+ "$tmpdir/test-root-CA.pem"
+
+invalid_certificate \
+ "$tmpdir/test-intermediate-CA-trusted-certificate-0001.pem" \
+ "$intermediate_ca_trusted_cert_0001_key_pass" \
+ "$tmpdir/test-root-CA.pem" \
+ "partial_chain"
+
+valid_certificate \
+ "$tmpdir/test-intermediate-CA-trusted-certificate-0001.pem" \
+ "$intermediate_ca_trusted_cert_0001_key_pass" \
+ "$tmpdir/test-full-chain-CA.pem"
+
+valid_certificate \
+ "$tmpdir/test-intermediate-CA-trusted-certificate-0001.pem" \
+ "$intermediate_ca_trusted_cert_0001_key_pass" \
+ "$tmpdir/test-full-chain-CA.pem" \
+ "partial_chain"
+
+invalid_certificate \
+ "$tmpdir/test-intermediate-CA-trusted-certificate-0001.pem" \
+ "$intermediate_ca_trusted_cert_0001_key_pass" \
+ "$tmpdir/test-intermediate-CA.pem"
+
+valid_certificate \
+ "$tmpdir/test-intermediate-CA-trusted-certificate-0001.pem" \
+ "$intermediate_ca_trusted_cert_0001_key_pass" \
+ "$tmpdir/test-intermediate-CA.pem" \
+ "partial_chain"
+
+
+## Checking that Sub Intermediate CA Trusted certificate is accepted
+
+invalid_certificate \
+ "$tmpdir/test-sub-intermediate-CA-trusted-certificate-0001.pem" \
+ "$sub_intermediate_ca_trusted_cert_0001_key_pass" \
+ "$tmpdir/test-root-CA.pem"
+
+invalid_certificate \
+ "$tmpdir/test-sub-intermediate-CA-trusted-certificate-0001.pem" \
+ "$sub_intermediate_ca_trusted_cert_0001_key_pass" \
+ "$tmpdir/test-root-CA.pem" \
+ "partial_chain"
+
+valid_certificate \
+ "$tmpdir/test-sub-intermediate-CA-trusted-certificate-0001.pem" \
+ "$sub_intermediate_ca_trusted_cert_0001_key_pass" \
+ "$tmpdir/test-full-chain-CA.pem"
+
+valid_certificate \
+ "$tmpdir/test-sub-intermediate-CA-trusted-certificate-0001.pem" \
+ "$sub_intermediate_ca_trusted_cert_0001_key_pass" \
+ "$tmpdir/test-full-chain-CA.pem" \
+ "partial_chain"
+
+invalid_certificate \
+ "$tmpdir/test-sub-intermediate-CA-trusted-certificate-0001.pem" \
+ "$sub_intermediate_ca_trusted_cert_0001_key_pass" \
+ "$tmpdir/test-sub-intermediate-CA.pem"
+
+invalid_certificate \
+ "$tmpdir/test-sub-intermediate-CA-trusted-certificate-0001.pem" \
+ "$sub_intermediate_ca_trusted_cert_0001_key_pass" \
+ "$tmpdir/test-root-intermediate-chain-CA.pem" \
+ "partial_chain"
+
+valid_certificate \
+ "$tmpdir/test-sub-intermediate-CA-trusted-certificate-0001.pem" \
+ "$sub_intermediate_ca_trusted_cert_0001_key_pass" \
+ "$tmpdir/test-sub-intermediate-CA.pem" \
+ "partial_chain"
+
+valid_certificate \
+ "$tmpdir/test-sub-intermediate-CA-trusted-certificate-0001.pem" \
+ "$sub_intermediate_ca_trusted_cert_0001_key_pass" \
+ "$tmpdir/test-intermediate-sub-chain-CA.pem" \
+ "partial_chain"
+
+set +x
+
+echo
+echo "Test completed, Root CA and intermediate issued certificates verified!"