diff --git a/tests/pkcs11-tool/Makefile b/tests/pkcs11-tool/Makefile index 4408ace..ce6b185 100644 --- a/tests/pkcs11-tool/Makefile +++ b/tests/pkcs11-tool/Makefile @@ -28,7 +28,7 @@ export TESTVERSION=1.0 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 @@ -51,9 +51,13 @@ $(METADATA): Makefile @echo "Path: $(TEST_DIR)" >> $(METADATA) @echo "Description: This is a sanity test for pkcs11-tool" >> $(METADATA) @echo "Type: Sanity" >> $(METADATA) - @echo "TestTime: 5m" >> $(METADATA) + @echo "TestTime: 15m" >> $(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 "License: GPLv2+" >> $(METADATA) @echo "Confidential: yes" >> $(METADATA) diff --git a/tests/pkcs11-tool/runtest.sh b/tests/pkcs11-tool/runtest.sh index a3d2379..f6c3120 100755 --- a/tests/pkcs11-tool/runtest.sh +++ b/tests/pkcs11-tool/runtest.sh @@ -35,201 +35,261 @@ PIN="123456" export GNUTLS_PIN=$PIN GENERATE_KEYS=1 PKCS11_TOOL="pkcs11-tool" +NSSDB=db function generate_cert() { - TYPE="$1" - ID="$2" - LABEL="$3" + TYPE="$1" + ID="$2" + LABEL="$3" - # Generate key pair - $PKCS11_TOOL --keypairgen --key-type="$TYPE" --login --pin=$PIN \ - --module="$P11LIB" --label="$LABEL" --id=$ID + # Generate key pair + $PKCS11_TOOL --keypairgen --key-type="$TYPE" --login --pin=$PIN \ + --module="$P11LIB" --label="$LABEL" --id=$ID - if [[ "$?" -ne "0" ]]; then - echo "Couldn't generate $TYPE key pair" - return 1 - fi + if [[ "$?" -ne "0" ]]; then + echo "Couldn't generate $TYPE key pair" + return 1 + fi - # check type value for the PKCS#11 URI (RHEL7 is using old "object-type") - TYPE_KEY="type" - p11tool --list-all --provider="$P11LIB" --login | grep "object-type" && \ - TYPE_KEY="object-type" + # check type value for the PKCS#11 URI (RHEL7 is using old "object-type") + TYPE_KEY="type" + p11tool --list-all --provider="$P11LIB" --login | grep "object-type" && \ + TYPE_KEY="object-type" - # Generate certificate - certtool --generate-self-signed --outfile="$ID.cert" --template=cert.cfg \ - --provider="$P11LIB" --load-privkey "pkcs11:object=$LABEL;$TYPE_KEY=private" \ - --load-pubkey "pkcs11:object=$LABEL;$TYPE_KEY=public" - # convert to DER: - openssl x509 -inform PEM -outform DER -in "$ID.cert" -out "$ID.cert.der" - # Write certificate - #p11tool --login --write --load-certificate="$ID.cert" --label="$LABEL" \ - # --provider="$P11LIB" - $PKCS11_TOOL --write-object "$ID.cert.der" --type=cert --id=$ID \ - --label="$LABEL" --module="$P11LIB" + # Generate certificate + certtool --generate-self-signed --outfile="$ID.cert" --template=cert.cfg \ + --provider="$P11LIB" --load-privkey "pkcs11:object=$LABEL;$TYPE_KEY=private" \ + --load-pubkey "pkcs11:object=$LABEL;$TYPE_KEY=public" + # convert to DER: + openssl x509 -inform PEM -outform DER -in "$ID.cert" -out "$ID.cert.der" + # Write certificate + #p11tool --login --write --load-certificate="$ID.cert" --label="$LABEL" \ + # --provider="$P11LIB" + $PKCS11_TOOL --write-object "$ID.cert.der" --type=cert --id=$ID \ + --label="$LABEL" --module="$P11LIB" - rm "$ID.cert.der" + rm "$ID.cert.der" - # Extract public key, which is more digestible by some of the tools - openssl x509 -inform PEM -in $ID.cert -pubkey > $ID.pub + # Extract public key, which is more digestible by some of the tools + 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() { - ECC_KEYS=1 - case $1 in - "softhsm") - P11LIB="/usr/lib64/pkcs11/libsofthsm2.so" - echo "directories.tokendir = .tokens/" > .softhsm2.conf - mkdir ".tokens" - export SOFTHSM2_CONF=".softhsm2.conf" - # Init token - softhsm2-util --init-token --slot 0 --label "SC test" --so-pin="$SOPIN" --pin="$PIN" - ;; - "opencryptoki") - # Supports only RSA mechanisms - ECC_KEYS=0 - P11LIB="/usr/lib64/pkcs11/libopencryptoki.so" - SO_PIN=87654321 - SLOT_ID=3 # swtok slot - systemctl is-active pkcsslotd > /dev/null - if [[ "$?" -ne "0" ]]; then - echo "Opencryptoki needs pkcsslotd running" - exit 1 - fi - groups | grep pkcs11 > /dev/null - if [[ "$?" -ne "0" ]]; then - echo "Opencryptoki requires the user to be in pkcs11 group" - exit 1 - 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 + case $1 in + "softhsm") + P11LIB="/usr/lib64/pkcs11/libsofthsm2.so" + echo "directories.tokendir = .tokens/" > .softhsm2.conf + echo "slots.removable = true" >> .softhsm2.conf + echo "objectstore.backend = file" >> .softhsm2.conf + echo "log.level = INFO" >> .softhsm2.conf + mkdir ".tokens" + export SOFTHSM2_CONF=".softhsm2.conf" + # Init token + softhsm2-util --init-token --slot 0 --label "SC test" --so-pin="$SOPIN" --pin="$PIN" + ;; + "opencryptoki") + # Supports only RSA mechanisms + P11LIB="/usr/lib64/pkcs11/libopencryptoki.so" + SO_PIN=87654321 + SLOT_ID=3 # swtok slot + rlServiceStart "pkcsslotd" + 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 + ;; + "libcacard") + # Remove OpenSC from p11-kit so we do not recurse + rlRun "rlFileBackup /usr/share/p11-kit/modules/" + rlRun "rm /usr/share/p11-kit/modules/opensc.module" - if [[ $GENERATE_KEYS -eq 1 ]]; then - # Generate 1024b RSA Key pair - generate_cert "RSA:1024" "01" "RSA_auth" - # Generate 2048b RSA Key pair - generate_cert "RSA:2048" "02" "RSA2048" - if [[ $ECC_KEYS -eq 1 ]]; then - # Generate 256b ECC Key pair - generate_cert "EC:secp256r1" "03" "ECC_auth" - # Generate 521b ECC Key pair - generate_cert "EC:secp521r1" "04" "ECC521" - fi - fi + # we use softhsm internally + rlRun "card_setup softhsm" + + # Setup NSS DB + rlRun "mkdir $NSSDB" + # Do not add a softhsm2 to the nssdb if there is already p11-kit-proxy + rlRun "modutil -create -dbdir sql:$NSSDB -force" + rlRun "modutil -list -dbdir sql:$NSSDB | grep 'library name: p11-kit-proxy.so'" 0,1 + if [ "$?" = "1" ]; then + rlRun "modutil -force -add 'SoftHSM PKCS#11' -dbdir sql:$NSSDB -libfile $P11LIB" + 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() { - case $1 in - "softhsm") - rm .softhsm2.conf - rm -rf ".tokens" - ;; - esac - if [[ $GENERATE_KEYS -eq 1 ]]; then - rm "0{1,2,3,4}.{cert,pub}" - fi + case $1 in + "softhsm") + rm .softhsm2.conf + rm -rf ".tokens" + ;; + "libcacard") + rlRun "pkill virt_cacard" 0,1 + rlFileSubmit virt_cacard.debug + 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 - rlPhaseStartSetup + rlPhaseStartSetup "General setup" 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 - for HASH in "" "SHA1" "SHA224" "SHA256" "SHA384" "SHA512"; do - for SIGN_KEY in "01" "02"; do - METHOD="RSA-PKCS" - if [[ ! -z $HASH ]]; then - METHOD="$HASH-$METHOD" - fi - rlPhaseStartTest "$METHOD: Sing & Verify (KEY $SIGN_KEY)" - rlRun "$PKCS11_TOOL --id $SIGN_KEY -s -p $PIN -m $METHOD --module $P11LIB \ - --input-file data --output-file data.sig" + for BACKEND in "softhsm" "opencryptoki" "libcacard"; do + rlPhaseStartSetup "Set up $BACKEND" + rlAssertRpm $BACKEND + rlRun "TmpDir=\$(mktemp -d)" 0 "Creating tmp directory" + rlRun "cp cert.cfg virtcacard.cil $TmpDir" + rlRun "pushd $TmpDir" + rlRun "card_setup $BACKEND" + rlRun 'echo "data to sign (max 100 bytes)" > data' + # 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 - if [[ -z $HASH ]]; then - rlRun "openssl rsautl -verify -inkey $SIGN_KEY.cert -in data.sig -certin" - else - rlRun "openssl dgst -keyform PEM -verify $SIGN_KEY.pub -${HASH,,*} \ + for HASH in "" "SHA1" "SHA224" "SHA256" "SHA384" "SHA512"; do + for SIGN_KEY in "0001" "0002" "0003"; do + METHOD="RSA-PKCS" + if [[ ! -z $HASH ]]; then + 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" - 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 + # 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}" - METHOD="$METHOD-PSS" - if [[ "$HASH" == "SHA512" ]]; then - continue; # This one is broken + rlPhaseEnd + done + + # Skip hashed algorithms (do not support encryption & decryption) + if [[ ! -z "$HASH" ]]; then + continue; fi - rlPhaseStartTest "$METHOD: Sing & Verify (KEY $SIGN_KEY)" - if [[ -z $HASH ]]; then - # hashing is done outside of the module. We chouse 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" + METHOD="RSA-PKCS" + for ENC_KEY in "0001" "0002" "0003"; do + rlPhaseStartTest "$BACKEND: $METHOD: Encrypt & Decrypt (KEY $ENC_KEY)" + # OpenSSL Encryption + rlRun "openssl rsautl -encrypt -pubin -inkey $ENC_KEY.pub -in data \ + -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}" - # OpenSSL verification - rlRun "openssl dgst -keyform PEM -verify $SIGN_KEY.pub $VERIFY_DGEST \ - -sigopt rsa_padding_mode:pss $VERIFY_OPTS -sigopt rsa_pss_saltlen:-1 \ - -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 + # TODO pkcs11-tool encryption + rlPhaseEnd + done done - # Skip hashed algorithms (do not support encryption & decryption) - if [[ ! -z "$HASH" ]]; then - continue; - fi - METHOD="RSA-PKCS" - 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 + rlPhaseStartCleanup "Cleanup $BACKEND" + card_cleanup $BACKEND + rlRun "popd" + rlRun "rm -r $TmpDir" 0 "Removing tmp directory" + rlPhaseEnd done - - rlPhaseStartCleanup - card_cleanup "softhsm" - rlRun "rm -r $TmpDir" 0 "Removing tmp directory" - rlPhaseEnd rlJournalPrintText rlJournalEnd diff --git a/tests/pkcs11-tool/virtcacard.cil b/tests/pkcs11-tool/virtcacard.cil new file mode 100644 index 0000000..51176ef --- /dev/null +++ b/tests/pkcs11-tool/virtcacard.cil @@ -0,0 +1,2 @@ +(allow pcscd_t node_t (tcp_socket (node_bind))) + diff --git a/tests/tests.yml b/tests/tests.yml index dcddb29..21150ec 100644 --- a/tests/tests.yml +++ b/tests/tests.yml @@ -19,4 +19,18 @@ - softhsm # software PKCS#11 module - openssl # openssl tools - 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