Test with libcacard

This commit is contained in:
Jakub Jelen 2019-08-23 16:14:30 +02:00
parent 88b6e849e2
commit a5b7b9742a
4 changed files with 247 additions and 167 deletions

View File

@ -28,7 +28,7 @@ export TESTVERSION=1.0
BUILT_FILES= BUILT_FILES=
FILES=$(METADATA) runtest.sh Makefile PURPOSE cert.cfg FILES=$(METADATA) runtest.sh Makefile PURPOSE cert.cfg virtcacard.cil
.PHONY: all install download clean .PHONY: all install download clean
@ -51,9 +51,13 @@ $(METADATA): Makefile
@echo "Path: $(TEST_DIR)" >> $(METADATA) @echo "Path: $(TEST_DIR)" >> $(METADATA)
@echo "Description: This is a sanity test for pkcs11-tool" >> $(METADATA) @echo "Description: This is a sanity test for pkcs11-tool" >> $(METADATA)
@echo "Type: Sanity" >> $(METADATA) @echo "Type: Sanity" >> $(METADATA)
@echo "TestTime: 5m" >> $(METADATA) @echo "TestTime: 15m" >> $(METADATA)
@echo "RunFor: opensc" >> $(METADATA) @echo "RunFor: opensc" >> $(METADATA)
@echo "Requires: opensc openssl gnutls-utils opencryptoki-libs" >> $(METADATA) @echo "Requires: opensc openssl gnutls-utils" >> $(METADATA)
@echo "Requires: opencryptoki-libs opencryptoki opencryptoki-swtok" >> $(METADATA)
@echo "Requires: libcacard-devel autoconf" >> $(METADATA)
@echo "Requires: autoconf-archive automake libtool" >> $(METADATA)
@echo "Requires: softhsm help2man pcsc-lite-devel nss-tools policycoreutils" >> $(METADATA)
@echo "Priority: Normal" >> $(METADATA) @echo "Priority: Normal" >> $(METADATA)
@echo "License: GPLv2+" >> $(METADATA) @echo "License: GPLv2+" >> $(METADATA)
@echo "Confidential: yes" >> $(METADATA) @echo "Confidential: yes" >> $(METADATA)

View File

@ -35,201 +35,261 @@ PIN="123456"
export GNUTLS_PIN=$PIN export GNUTLS_PIN=$PIN
GENERATE_KEYS=1 GENERATE_KEYS=1
PKCS11_TOOL="pkcs11-tool" PKCS11_TOOL="pkcs11-tool"
NSSDB=db
function generate_cert() { function generate_cert() {
TYPE="$1" TYPE="$1"
ID="$2" ID="$2"
LABEL="$3" LABEL="$3"
# Generate key pair # Generate key pair
$PKCS11_TOOL --keypairgen --key-type="$TYPE" --login --pin=$PIN \ $PKCS11_TOOL --keypairgen --key-type="$TYPE" --login --pin=$PIN \
--module="$P11LIB" --label="$LABEL" --id=$ID --module="$P11LIB" --label="$LABEL" --id=$ID
if [[ "$?" -ne "0" ]]; then if [[ "$?" -ne "0" ]]; then
echo "Couldn't generate $TYPE key pair" echo "Couldn't generate $TYPE key pair"
return 1 return 1
fi fi
# check type value for the PKCS#11 URI (RHEL7 is using old "object-type") # check type value for the PKCS#11 URI (RHEL7 is using old "object-type")
TYPE_KEY="type" TYPE_KEY="type"
p11tool --list-all --provider="$P11LIB" --login | grep "object-type" && \ p11tool --list-all --provider="$P11LIB" --login | grep "object-type" && \
TYPE_KEY="object-type" TYPE_KEY="object-type"
# Generate certificate # Generate certificate
certtool --generate-self-signed --outfile="$ID.cert" --template=cert.cfg \ certtool --generate-self-signed --outfile="$ID.cert" --template=cert.cfg \
--provider="$P11LIB" --load-privkey "pkcs11:object=$LABEL;$TYPE_KEY=private" \ --provider="$P11LIB" --load-privkey "pkcs11:object=$LABEL;$TYPE_KEY=private" \
--load-pubkey "pkcs11:object=$LABEL;$TYPE_KEY=public" --load-pubkey "pkcs11:object=$LABEL;$TYPE_KEY=public"
# convert to DER: # convert to DER:
openssl x509 -inform PEM -outform DER -in "$ID.cert" -out "$ID.cert.der" openssl x509 -inform PEM -outform DER -in "$ID.cert" -out "$ID.cert.der"
# Write certificate # Write certificate
#p11tool --login --write --load-certificate="$ID.cert" --label="$LABEL" \ #p11tool --login --write --load-certificate="$ID.cert" --label="$LABEL" \
# --provider="$P11LIB" # --provider="$P11LIB"
$PKCS11_TOOL --write-object "$ID.cert.der" --type=cert --id=$ID \ $PKCS11_TOOL --write-object "$ID.cert.der" --type=cert --id=$ID \
--label="$LABEL" --module="$P11LIB" --label="$LABEL" --module="$P11LIB"
rm "$ID.cert.der" rm "$ID.cert.der"
# Extract public key, which is more digestible by some of the tools # Extract public key, which is more digestible by some of the tools
openssl x509 -inform PEM -in $ID.cert -pubkey > $ID.pub openssl x509 -inform PEM -in $ID.cert -pubkey > $ID.pub
p11tool --login --provider="$P11LIB" --list-all p11tool --login --provider="$P11LIB" --list-all
} }
function card_setup() { function card_setup() {
ECC_KEYS=1 case $1 in
case $1 in "softhsm")
"softhsm") P11LIB="/usr/lib64/pkcs11/libsofthsm2.so"
P11LIB="/usr/lib64/pkcs11/libsofthsm2.so" echo "directories.tokendir = .tokens/" > .softhsm2.conf
echo "directories.tokendir = .tokens/" > .softhsm2.conf echo "slots.removable = true" >> .softhsm2.conf
mkdir ".tokens" echo "objectstore.backend = file" >> .softhsm2.conf
export SOFTHSM2_CONF=".softhsm2.conf" echo "log.level = INFO" >> .softhsm2.conf
# Init token mkdir ".tokens"
softhsm2-util --init-token --slot 0 --label "SC test" --so-pin="$SOPIN" --pin="$PIN" export SOFTHSM2_CONF=".softhsm2.conf"
;; # Init token
"opencryptoki") softhsm2-util --init-token --slot 0 --label "SC test" --so-pin="$SOPIN" --pin="$PIN"
# Supports only RSA mechanisms ;;
ECC_KEYS=0 "opencryptoki")
P11LIB="/usr/lib64/pkcs11/libopencryptoki.so" # Supports only RSA mechanisms
SO_PIN=87654321 P11LIB="/usr/lib64/pkcs11/libopencryptoki.so"
SLOT_ID=3 # swtok slot SO_PIN=87654321
systemctl is-active pkcsslotd > /dev/null SLOT_ID=3 # swtok slot
if [[ "$?" -ne "0" ]]; then rlServiceStart "pkcsslotd"
echo "Opencryptoki needs pkcsslotd running" echo "test_swtok" | /usr/sbin/pkcsconf -I -c $SLOT_ID -S $SO_PIN
exit 1 /usr/sbin/pkcsconf -u -c $SLOT_ID -S $SO_PIN -n $PIN
fi ;;
groups | grep pkcs11 > /dev/null "libcacard")
if [[ "$?" -ne "0" ]]; then # Remove OpenSC from p11-kit so we do not recurse
echo "Opencryptoki requires the user to be in pkcs11 group" rlRun "rlFileBackup /usr/share/p11-kit/modules/"
exit 1 rlRun "rm /usr/share/p11-kit/modules/opensc.module"
fi
echo "test_swtok" | /usr/sbin/pkcsconf -I -c $SLOT_ID -S $SO_PIN
/usr/sbin/pkcsconf -u -c $SLOT_ID -S $SO_PIN -n $PIN
;;
*)
echo "Error: Missing argument."
exit 1;
;;
esac
if [[ $GENERATE_KEYS -eq 1 ]]; then # we use softhsm internally
# Generate 1024b RSA Key pair rlRun "card_setup softhsm"
generate_cert "RSA:1024" "01" "RSA_auth"
# Generate 2048b RSA Key pair # Setup NSS DB
generate_cert "RSA:2048" "02" "RSA2048" rlRun "mkdir $NSSDB"
if [[ $ECC_KEYS -eq 1 ]]; then # Do not add a softhsm2 to the nssdb if there is already p11-kit-proxy
# Generate 256b ECC Key pair rlRun "modutil -create -dbdir sql:$NSSDB -force"
generate_cert "EC:secp256r1" "03" "ECC_auth" rlRun "modutil -list -dbdir sql:$NSSDB | grep 'library name: p11-kit-proxy.so'" 0,1
# Generate 521b ECC Key pair if [ "$?" = "1" ]; then
generate_cert "EC:secp521r1" "04" "ECC521" rlRun "modutil -force -add 'SoftHSM PKCS#11' -dbdir sql:$NSSDB -libfile $P11LIB"
fi fi
fi
# Download and Install vsmartcard
rlRun "git clone https://github.com/frankmorgner/vsmartcard.git"
rlRun "pushd vsmartcard/virtualsmartcard"
rlRun "autoreconf -vis && ./configure && make -j4 && make install"
rlRun "popd"
# Download and Install virt_cacard
rlRun "git clone https://github.com/PL4typus/virt_cacard.git"
rlRun "pushd virt_cacard && ./autogen.sh && ./configure && make"
rlRun "popd"
# Install the temporary SELinux policy
rlRun "semodule -i virtcacard.cil"
# Restart pcscd
rlRun "systemctl restart pcscd"
# Start virtcacard
#rlRun "G_MESSAGES_DEBUG=libcacard LIBCACARD_DEBUG=1 ./virt_cacard/virt_cacard 2> virt_cacard.debug &"
rlRun "./virt_cacard/virt_cacard 2> virt_cacard.debug &"
rlRun "sleep 5"
# We will use OpenSC directly from here
P11LIB="/usr/lib64/pkcs11/opensc-pkcs11.so"
rlRun "$PKCS11_TOOL -O"
# The keys are already generated in softhsm
return 0
;;
*)
echo "Error: Missing argument."
exit 1;
;;
esac
if [[ $GENERATE_KEYS -eq 1 ]]; then
# Generate 1024b RSA Key pair
generate_cert "RSA:1024" "0001" "RSA1024"
# Generate 2048b RSA Key pair
generate_cert "RSA:2048" "0002" "RSA2048"
# Generate 3092b RSA Key pair
generate_cert "RSA:2048" "0003" "RSA3"
fi
} }
function card_cleanup() { function card_cleanup() {
case $1 in case $1 in
"softhsm") "softhsm")
rm .softhsm2.conf rm .softhsm2.conf
rm -rf ".tokens" rm -rf ".tokens"
;; ;;
esac "libcacard")
if [[ $GENERATE_KEYS -eq 1 ]]; then rlRun "pkill virt_cacard" 0,1
rm "0{1,2,3,4}.{cert,pub}" rlFileSubmit virt_cacard.debug
fi rlRun "rm -rf $NSSDB"
card_cleanup softhsm
rlRun "rlFileRestore"
;;
esac
if [[ $GENERATE_KEYS -eq 1 ]]; then
rm "0{1,2,3,4}.{cert,pub}"
fi
} }
rlJournalStart rlJournalStart
rlPhaseStartSetup rlPhaseStartSetup "General setup"
rlAssertRpm $PACKAGE rlAssertRpm $PACKAGE
rlRun "TmpDir=\$(mktemp -d)" 0 "Creating tmp directory"
rlRun "cp cert.cfg $TmpDir"
rlRun "pushd $TmpDir"
card_setup "softhsm"
rlRun 'echo "data to sign (max 100 bytes)" > data'
rlPhaseEnd rlPhaseEnd
for HASH in "" "SHA1" "SHA224" "SHA256" "SHA384" "SHA512"; do for BACKEND in "softhsm" "opencryptoki" "libcacard"; do
for SIGN_KEY in "01" "02"; do rlPhaseStartSetup "Set up $BACKEND"
METHOD="RSA-PKCS" rlAssertRpm $BACKEND
if [[ ! -z $HASH ]]; then rlRun "TmpDir=\$(mktemp -d)" 0 "Creating tmp directory"
METHOD="$HASH-$METHOD" rlRun "cp cert.cfg virtcacard.cil $TmpDir"
fi rlRun "pushd $TmpDir"
rlPhaseStartTest "$METHOD: Sing & Verify (KEY $SIGN_KEY)" rlRun "card_setup $BACKEND"
rlRun "$PKCS11_TOOL --id $SIGN_KEY -s -p $PIN -m $METHOD --module $P11LIB \ rlRun 'echo "data to sign (max 100 bytes)" > data'
--input-file data --output-file data.sig" # Read the certificates from the module (the IDs might get mixed up in libcacard)
for ID in "0001" "0002" "0003"; do
rlRun ">$ID.cert"
rlRun "$PKCS11_TOOL --read-object --id $ID --type cert --output-file $ID.cert --module $P11LIB"
rlRun "openssl x509 -inform DER -in $ID.cert -pubkey > $ID.pub"
done
rlPhaseEnd
# OpenSSL verification for HASH in "" "SHA1" "SHA224" "SHA256" "SHA384" "SHA512"; do
if [[ -z $HASH ]]; then for SIGN_KEY in "0001" "0002" "0003"; do
rlRun "openssl rsautl -verify -inkey $SIGN_KEY.cert -in data.sig -certin" METHOD="RSA-PKCS"
else if [[ ! -z $HASH ]]; then
rlRun "openssl dgst -keyform PEM -verify $SIGN_KEY.pub -${HASH,,*} \ METHOD="$HASH-$METHOD"
fi
# OpenCryptoki does not work with hashed mechanisms
if [[ "$BACKEND" != "opencryptoki" ]]; then
rlPhaseStartTest "$BACKEND: $METHOD: Sign & Verify (KEY $SIGN_KEY)"
rlRun "$PKCS11_TOOL --id $SIGN_KEY -s -p $PIN -m $METHOD --module $P11LIB \
--input-file data --output-file data.sig"
# OpenSSL verification
if [[ -z $HASH ]]; then
rlRun "openssl rsautl -verify -pubin -inkey $SIGN_KEY.pub -in data.sig"
else
rlRun "openssl dgst -verify $SIGN_KEY.pub -${HASH,,*} \
-signature data.sig data"
fi
# pkcs11-tool verification
rlRun "$PKCS11_TOOL --id $SIGN_KEY --verify -m $METHOD --module $P11LIB \
--input-file data --signature-file data.sig"
rlRun "rm data.sig"
rlPhaseEnd
fi
METHOD="$METHOD-PSS"
if [[ "$HASH" == "SHA512" ]]; then
continue; # This one is broken
fi
rlPhaseStartTest "$BACKEND: $METHOD: Sign & Verify (KEY $SIGN_KEY)"
if [[ -z $HASH ]]; then
# hashing is done outside of the module. We chose here SHA256
rlRun "openssl dgst -binary -sha256 data > data.hash"
HASH_ALGORITM="--hash-algorithm=SHA256"
VERIFY_DGEST="-sha256"
VERIFY_OPTS="-sigopt rsa_mgf1_md:sha256"
else
# hashing is done inside of the module
rlRun "cp data data.hash"
HASH_ALGORITM=""
VERIFY_DGEST="-${HASH,,*}"
VERIFY_OPTS="-sigopt rsa_mgf1_md:${HASH,,*}"
fi
rlRun "$PKCS11_TOOL --id $SIGN_KEY -s -p $PIN -m $METHOD --module $P11LIB \
$HASH_ALGORITM --salt-len=-1 \
--input-file data.hash --output-file data.sig"
# OpenSSL verification
rlRun "openssl dgst -verify $SIGN_KEY.pub $VERIFY_DGEST \
-sigopt rsa_padding_mode:pss $VERIFY_OPTS -sigopt rsa_pss_saltlen:-1 \
-signature data.sig data" -signature data.sig data"
fi
# pkcs11-tool verification # pkcs11-tool verification
rlRun "$PKCS11_TOOL --id $SIGN_KEY --verify -m $METHOD --module $P11LIB \ rlRun "$PKCS11_TOOL --id $SIGN_KEY --verify -m $METHOD --module $P11LIB \
--input-file data --signature-file data.sig" $HASH_ALGORITM --salt-len=-1 \
rlRun "rm data.sig" --input-file data.hash --signature-file data.sig"
rlPhaseEnd rlRun "rm data.{sig,hash}"
METHOD="$METHOD-PSS" rlPhaseEnd
if [[ "$HASH" == "SHA512" ]]; then done
continue; # This one is broken
# Skip hashed algorithms (do not support encryption & decryption)
if [[ ! -z "$HASH" ]]; then
continue;
fi fi
rlPhaseStartTest "$METHOD: Sing & Verify (KEY $SIGN_KEY)" METHOD="RSA-PKCS"
if [[ -z $HASH ]]; then for ENC_KEY in "0001" "0002" "0003"; do
# hashing is done outside of the module. We chouse here SHA256 rlPhaseStartTest "$BACKEND: $METHOD: Encrypt & Decrypt (KEY $ENC_KEY)"
rlRun "openssl dgst -binary -sha256 data > data.hash" # OpenSSL Encryption
HASH_ALGORITM="--hash-algorithm=SHA256" rlRun "openssl rsautl -encrypt -pubin -inkey $ENC_KEY.pub -in data \
VERIFY_DGEST="-sha256" -out data.crypt"
VERIFY_OPTS="-sigopt rsa_mgf1_md:sha256" rlRun "$PKCS11_TOOL --id $ENC_KEY --decrypt -p $PIN -m $METHOD \
else --module $P11LIB --input-file data.crypt > data.decrypted"
# hashing is done inside of the module rlRun "diff data{,.decrypted}"
rlRun "cp data data.hash" rlRun "rm data.{crypt,decrypted}"
HASH_ALGORITM=""
VERIFY_DGEST="-${HASH,,*}"
VERIFY_OPTS="-sigopt rsa_mgf1_md:${HASH,,*}"
fi
rlRun "$PKCS11_TOOL --id $SIGN_KEY -s -p $PIN -m $METHOD --module $P11LIB \
$HASH_ALGORITM --salt-len=-1 \
--input-file data.hash --output-file data.sig"
# OpenSSL verification # TODO pkcs11-tool encryption
rlRun "openssl dgst -keyform PEM -verify $SIGN_KEY.pub $VERIFY_DGEST \ rlPhaseEnd
-sigopt rsa_padding_mode:pss $VERIFY_OPTS -sigopt rsa_pss_saltlen:-1 \ done
-signature data.sig data"
# pkcs11-tool verification
rlRun "$PKCS11_TOOL --id $SIGN_KEY --verify -m $METHOD --module $P11LIB \
$HASH_ALGORITM --salt-len=-1 \
--input-file data.hash --signature-file data.sig"
rlRun "rm data.{sig,hash}"
rlPhaseEnd
done done
# Skip hashed algorithms (do not support encryption & decryption) rlPhaseStartCleanup "Cleanup $BACKEND"
if [[ ! -z "$HASH" ]]; then card_cleanup $BACKEND
continue; rlRun "popd"
fi rlRun "rm -r $TmpDir" 0 "Removing tmp directory"
METHOD="RSA-PKCS" rlPhaseEnd
for ENC_KEY in "01" "02"; do
rlPhaseStartTest "$METHOD: Encrypt & Decrypt (KEY $ENC_KEY)"
# OpenSSL Encryption
rlRun "openssl rsautl -encrypt -inkey $ENC_KEY.cert -in data \
-certin -out data.crypt"
rlRun "$PKCS11_TOOL --id $ENC_KEY --decrypt -p $PIN -m $METHOD \
--module $P11LIB --input-file data.crypt > data.decrypted"
rlRun "diff data{,.decrypted}"
rlRun "rm data.{crypt,decrypted}"
# TODO pkcs11-tool encryption
rlPhaseEnd
done
done done
rlPhaseStartCleanup
card_cleanup "softhsm"
rlRun "rm -r $TmpDir" 0 "Removing tmp directory"
rlPhaseEnd
rlJournalPrintText rlJournalPrintText
rlJournalEnd rlJournalEnd

View File

@ -0,0 +1,2 @@
(allow pcscd_t node_t (tcp_socket (node_bind)))

View File

@ -19,4 +19,18 @@
- softhsm # software PKCS#11 module - softhsm # software PKCS#11 module
- openssl # openssl tools - openssl # openssl tools
- gnutls-utils # p11tool - gnutls-utils # p11tool
- opencryptoki-libs # opencryptoki
- opencryptoki
- opencryptoki-swtok
- git # to download vsmartcard and virt_cacard projects
- libcacard-devel # Build requires for virt_cacard and vsmartcard
- autoconf
- autoconf-archive
- automake
- libtool
- softhsm
- help2man
- pcsc-lite-devel
- nss-tools # Handling NSS DB
- policycoreutils # Loading custom selinux modules