[Pkg-sssd-devel] [Git][sssd-team/sssd][master] 2 commits: debian: Add pam-auth-update SSSD Smart card configurations

Timo Aaltonen (@tjaalton) gitlab at salsa.debian.org
Fri Sep 15 09:15:22 BST 2023



Timo Aaltonen pushed to branch master at Debian SSSD packaging / sssd


Commits:
18d2eb09 by Marco Trevisan (Treviño) at 2023-09-14T11:45:30+02:00
debian: Add pam-auth-update SSSD Smart card configurations

Make it easier to use smart card authentication via pam_sss.so, adding
profiles that can be used for the common authentication.

The required and optional modes are conflicting each other, while the
priority is higher than unix authentication so that user password access
has lower priority.

- - - - -
38380c03 by Marco Trevisan (Treviño) at 2023-09-14T12:34:26+02:00
debian/tests: Add tests for smart card verification

Add integration tests verifying how smart card authentication can be
used and configured using pam-auth-update

- - - - -


7 changed files:

- + debian/libpam-sss-smart-card-optional.pam-auth-update
- + debian/libpam-sss-smart-card-required.pam-auth-update
- debian/libpam-sss.prerm
- debian/rules
- debian/tests/control
- + debian/tests/sssd-smart-card-pam-auth-configs-tester.sh
- + debian/tests/sssd-softhism2-certificates-tests.sh


Changes:

=====================================
debian/libpam-sss-smart-card-optional.pam-auth-update
=====================================
@@ -0,0 +1,8 @@
+Name: SSS optional smart card authentication
+Default: no
+Priority: 264
+Conflicts: sss-smart-card-required
+
+Auth-Type: Primary
+Auth:
+	[success=end default=ignore]	pam_sss.so allow_missing_name try_cert_auth


=====================================
debian/libpam-sss-smart-card-required.pam-auth-update
=====================================
@@ -0,0 +1,8 @@
+Name: SSS required smart card authentication
+Default: no
+Priority: 264
+Conflicts: sss-smart-card-optional
+
+Auth-Type: Primary
+Auth:
+	[success=end ignore=ignore default=die]	pam_sss.so allow_missing_name require_cert_auth


=====================================
debian/libpam-sss.prerm
=====================================
@@ -2,7 +2,10 @@
 
 
 if [ "$1" = remove ] && [ "${DPKG_MAINTSCRIPT_PACKAGE_REFCOUNT:-1}" = 1 ]; then
-    pam-auth-update --package --remove sss
+    pam-auth-update --package --remove \
+        sss \
+        sss-smart-card-optional \
+        sss-smart-card-required
 fi
 
 #DEBHELPER#


=====================================
debian/rules
=====================================
@@ -70,6 +70,10 @@ override_dh_install:
 	mkdir -p $(CURDIR)/debian/libpam-sss/usr/share/pam-configs
 	install -m644 debian/libpam-sss.pam-auth-update \
 		$(CURDIR)/debian/libpam-sss/usr/share/pam-configs/sss
+	install -m644 debian/libpam-sss-smart-card-optional.pam-auth-update \
+		$(CURDIR)/debian/libpam-sss/usr/share/pam-configs/sss-smart-card-optional
+	install -m644 debian/libpam-sss-smart-card-required.pam-auth-update \
+		$(CURDIR)/debian/libpam-sss/usr/share/pam-configs/sss-smart-card-required
 	install -m644 -D $(CURDIR)/debian/apparmor-profile \
 		$(CURDIR)/debian/sssd-common/etc/apparmor.d/usr.sbin.sssd
 


=====================================
debian/tests/control
=====================================
@@ -5,3 +5,35 @@ Restrictions: isolation-container, needs-root, allow-stderr
 Tests: ldap-user-group-krb5-auth
 Depends: @, slapd, ldap-utils, openssl, expect, lsb-release, krb5-user, krb5-admin-server, krb5-kdc
 Restrictions: isolation-container, needs-root, allow-stderr
+
+Test-Command: sudo
+  bash debian/tests/sssd-softhism2-certificates-tests.sh
+Features: test-name=sssd-softhism2-certificates-tests
+Depends: bash,
+         gnutls-bin,
+         openssl,
+         passwd,
+         softhsm2,
+         sssd,
+         util-linux
+Restrictions: needs-sudo,
+              allow-stderr
+
+Test-Command: sudo env
+  OFFLINE_MODE=1
+  bash debian/tests/sssd-smart-card-pam-auth-configs-tester.sh
+Features: test-name=sssd-smart-card-pam-auth-configs
+Depends: bash,
+         gnutls-bin,
+         libpam-sss,
+         openssl,
+         pamtester,
+         passwd,
+         softhsm2,
+         sssd,
+         util-linux
+Restrictions: breaks-testbed,
+              isolation-container,
+              needs-sudo,
+              allow-stderr
+


=====================================
debian/tests/sssd-smart-card-pam-auth-configs-tester.sh
=====================================
@@ -0,0 +1,247 @@
+#!/usr/bin/env bash
+# Copyright 2023 - Marco Trevisan
+# Released under the GPLv3 terms
+#
+# A simple tool to simulate PAM authentication using SSSD smartcard settings.
+#
+# To be used with softhsm2 smart cards generators from
+# https://gist.github.com/3v1n0/287d02ca8e03936f1c7bba992173d47a
+#
+# Origin: https://gist.github.com/3v1n0/d7bc0f10cf44a11288648ae9d228430d
+
+set -xe
+
+export DEBIAN_FRONTEND=noninteractive
+
+required_tools=(
+    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}
+tmpdir=${TEST_TMPDIR:-$(mktemp -d -t "sssd-softhsm2-certs-XXXXXX")}
+backupsdir=
+
+alternative_pam_configs=(
+  sss-smart-card-optional
+  sss-smart-card-required
+)
+
+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
+
+  pam-auth-update --disable "${alternative_pam_configs[@]}" || return 2
+
+  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-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" ] && [[ ! -v OFFLINE_MODE ]]; 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
+elif [ ! -e "$tester" ] && [[ -v OFFLINE_MODE ]]; then
+  echo "Required $tester missing"
+  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/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"
+
+user_config="$(runuser -u "$SUDO_USER" -- sh -c 'echo ${XDG_CONFIG_HOME:-~/.config}')"
+system_config="/etc"
+
+softhsm2_conf_paths=(
+  "$SUDO_USER:$user_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() {
+  pam_service="$1"
+  certificate_config="$2"
+  ca_db="$3"
+  verification_options="$4"
+
+  mkdir -p -m 700 /etc/sssd
+
+  echo "Using CA DB '$ca_db' with verification options: '$verification_options'"
+
+  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
+
+  pam-auth-update --disable "${alternative_pam_configs[@]}" || return 2
+
+  for alternative in "${alternative_pam_configs[@]}"; do
+    pam-auth-update --enable "$alternative" || return 2
+    cat /etc/pam.d/common-auth
+
+    echo -n -e "$PIN" | runuser -u "$SUDO_USER" -- \
+      pamtester -v "$pam_service" "$SUDO_USER" authenticate  || return 2
+    echo -n -e "$PIN" | runuser -u "$SUDO_USER" -- \
+      pamtester -v "$pam_service" "" authenticate  || return 2
+
+    if echo -n -e "wrong${PIN}" | runuser -u "$SUDO_USER" -- \
+        pamtester -v "$pam_service" "$SUDO_USER" authenticate; then
+      echo "Unexpected pass!"
+      return 2
+    fi
+
+    if echo -n -e "wrong${PIN}" | runuser -u "$SUDO_USER" -- \
+        pamtester -v "$pam_service" "" authenticate; then
+      echo "Unexpected pass!"
+      return 2
+    fi
+
+    if echo -n -e "$PIN" | pamtester -v "$pam_service" root authenticate; then
+      echo "Unexpected pass!"
+      return 2
+    fi
+  done
+}
+
+test_authentication \
+  login \
+  "$tmpdir/softhsm2-test-root-CA-trusted-certificate-0001.conf" \
+  "$tmpdir/test-full-chain-CA.pem"
+
+test_authentication \
+  login \
+  "$tmpdir/softhsm2-test-sub-intermediate-CA-trusted-certificate-0001.conf" \
+  "$tmpdir/test-full-chain-CA.pem"
+
+test_authentication \
+  login \
+  "$tmpdir/softhsm2-test-sub-intermediate-CA-trusted-certificate-0001.conf" \
+  "$tmpdir/test-sub-intermediate-CA.pem" \
+  "partial_chain"
+


=====================================
debian/tests/sssd-softhism2-certificates-tests.sh
=====================================
@@ -0,0 +1,897 @@
+#!/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 at 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 at 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 at 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 \
+    --module_name="$SOFTHSM2_MODULE" \
+    "$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!"



View it on GitLab: https://salsa.debian.org/sssd-team/sssd/-/compare/8cb92c88690babf57a6237354702c6d68a5589f8...38380c0368f03fc47e2a659e784ae30d8686d8a5

-- 
View it on GitLab: https://salsa.debian.org/sssd-team/sssd/-/compare/8cb92c88690babf57a6237354702c6d68a5589f8...38380c0368f03fc47e2a659e784ae30d8686d8a5
You're receiving this email because of your account on salsa.debian.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-sssd-devel/attachments/20230915/15bc961d/attachment-0001.htm>


More information about the Pkg-sssd-devel mailing list