diff --git a/.gitignore b/.gitignore index e69de29..7903524 100644 --- a/.gitignore +++ b/.gitignore @@ -0,0 +1,9 @@ +/opensc-0.13.0.tar.gz +/opensc-0.14.0.tar.gz +/opensc-0.15.0.tar.gz +/opensc-0.16.0.tar.gz +/opensc-0.16.0-git0362439.tar.gz +/opensc-0.17.0.tar.gz +/opensc-0.18.0.tar.gz +/opensc-0.19.0.tar.gz +/opensc-0.20.0.tar.gz diff --git a/common.sh b/common.sh new file mode 100644 index 0000000..bc9747f --- /dev/null +++ b/common.sh @@ -0,0 +1,88 @@ +#!/bin/bash +## from OpenSC/src/tests/p11test/runtest.sh + +SOPIN="12345678" +PIN="123456" +PKCS11_TOOL="../src/tools/pkcs11-tool" + +softhsm_paths="/usr/local/lib/softhsm/libsofthsm2.so \ + /usr/lib64/pkcs11/libsofthsm2.so \ + /usr/lib/x86_64-linux-gnu/softhsm/libsofthsm2.so" + +for LIB in $softhsm_paths; do + echo "Testing $LIB" + if [[ -f $LIB ]]; then + P11LIB=$LIB + echo "Setting P11LIB=$LIB" + break + fi +done +if [[ -z "$P11LIB" ]]; then + echo "Warning: Could not find the softhsm pkcs11 module" +fi + +ERRORS=0 +function assert() { + if [[ $1 != 0 ]]; then + echo "====> ERROR: $2" + ERRORS=1 + fi +} + +function generate_key() { + TYPE="$1" + ID="$2" + LABEL="$3" + + # 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 + + # Extract public key from the card + $PKCS11_TOOL --read-object --id $ID --type pubkey --output-file $ID.der \ + --module="$P11LIB" + + # convert it to more digestible PEM format + if [[ ${TYPE:0:3} == "RSA" ]]; then + openssl rsa -inform DER -outform PEM -in $ID.der -pubin > $ID.pub + else + openssl ec -inform DER -outform PEM -in $ID.der -pubin > $ID.pub + fi + rm $ID.der +} + +function softhsm_initialize() { + 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" +} + +function card_setup() { + softhsm_initialize + + # Generate 1024b RSA Key pair + generate_key "RSA:1024" "01" "RSA_auth" + # Generate 2048b RSA Key pair + generate_key "RSA:2048" "02" "RSA2048" + # Generate 256b ECC Key pair + generate_key "EC:secp256r1" "03" "ECC_auth" + # Generate 521b ECC Key pair + generate_key "EC:secp521r1" "04" "ECC521" +} + +function softhsm_cleanup() { + rm .softhsm2.conf + rm -rf ".tokens" +} + +function card_cleanup() { + softhsm_cleanup + rm 0{1,2,3,4}.pub +} diff --git a/opensc-0.19.0-pinpad.patch b/opensc-0.19.0-pinpad.patch new file mode 100644 index 0000000..f531b8b --- /dev/null +++ b/opensc-0.19.0-pinpad.patch @@ -0,0 +1,13 @@ +diff -up opensc-0.19.0/etc/opensc.conf.pinpad opensc-0.19.0/etc/opensc.conf +--- opensc-0.19.0/etc/opensc.conf.pinpad 2018-10-22 14:31:12.082963540 +0200 ++++ opensc-0.19.0/etc/opensc.conf 2018-10-22 14:33:59.939410701 +0200 +@@ -4,4 +4,9 @@ app default { + framework pkcs15 { + # use_file_caching = true; + } ++ reader_driver pcsc { ++ # The pinpad is disabled by default, ++ # because of many broken readers out there ++ enable_pinpad = false; ++ } + } diff --git a/opensc-0.20.0-cardos.patch b/opensc-0.20.0-cardos.patch new file mode 100644 index 0000000..d885b7d --- /dev/null +++ b/opensc-0.20.0-cardos.patch @@ -0,0 +1,1338 @@ +From 592a641cb9f8eb17d4d1b1c9a96a1581f61e169b Mon Sep 17 00:00:00 2001 +From: Doug Engert +Date: Sun, 29 Mar 2020 05:56:21 -0500 +Subject: [PATCH 2/6] pkcs11-tool - use valid data for decription tests + +In tests, make sute test data is either padded, or "zero" padded +so size if data <= modlen - 11. The smallest pad in 11 bytes, +00 | NN | PS | 00. PS is at least 8 bytes. +"zero" padding has N = 00, PS >= 8 byte of 00. + + On branch cardos-5.3 + Changes to be committed: + modified: tools/pkcs11-tool.c +--- + src/tools/pkcs11-tool.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c +index 3ad9289033..b1674a76cf 100644 +--- a/src/tools/pkcs11-tool.c ++++ b/src/tools/pkcs11-tool.c +@@ -5044,8 +5044,8 @@ static int test_signature(CK_SESSION_HANDLE sess) + } + + if (firstMechType == CKM_RSA_X_509) { +- /* make sure our data is smaller than the modulus */ +- data[0] = 0x00; ++ /* make sure our data is smaller than the modulus - 11 */ ++ memset(data, 0, 11); /* in effect is zero padding */ + } + + ck_mech.mechanism = firstMechType; + +From 3043f5b8a15c7cff90adcd2d31095afa734e663c Mon Sep 17 00:00:00 2001 +From: Doug Engert +Date: Sun, 5 Apr 2020 11:04:42 -0500 +Subject: [PATCH 3/6] Increase SC_MAX_SUPPORTED_ALGORITHMS from 8 to 16 + +CardOS cards may have more then 8 supported_algo_info entries in tokenInfo. +We may bemissing some. We have seen 8 in some pkcs15-tool -i -v output. + +Simple fix is to incrase the limit. More appropriate fix is to remove the limit, +much like is done with sc_algorithm_info. and use realloc of the array. + + On branch cardos-5.3 + Changes to be committed: + modified: src/libopensc/pkcs15-prkey.c + modified: src/libopensc/pkcs15-skey.c + modified: src/libopensc/pkcs15.c + modified: src/libopensc/types.h +--- + src/libopensc/pkcs15-prkey.c | 10 +++++++++- + src/libopensc/pkcs15-skey.c | 10 +++++++++- + src/libopensc/pkcs15.c | 10 +++++++++- + src/libopensc/types.h | 6 ++++-- + 4 files changed, 31 insertions(+), 5 deletions(-) + +diff --git a/src/libopensc/pkcs15-prkey.c b/src/libopensc/pkcs15-prkey.c +index ed008ede14..a6c05415ec 100644 +--- a/src/libopensc/pkcs15-prkey.c ++++ b/src/libopensc/pkcs15-prkey.c +@@ -48,10 +48,18 @@ + #include "aux-data.h" + + /* +- * in src/libopensc/types.h SC_MAX_SUPPORTED_ALGORITHMS defined as 8 ++ * in src/libopensc/types.h SC_MAX_SUPPORTED_ALGORITHMS defined as 16 + */ + #define C_ASN1_SUPPORTED_ALGORITHMS_SIZE (SC_MAX_SUPPORTED_ALGORITHMS + 1) + static const struct sc_asn1_entry c_asn1_supported_algorithms[C_ASN1_SUPPORTED_ALGORITHMS_SIZE] = { ++ { "algorithmReference", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, SC_ASN1_OPTIONAL, NULL, NULL }, ++ { "algorithmReference", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, SC_ASN1_OPTIONAL, NULL, NULL }, ++ { "algorithmReference", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, SC_ASN1_OPTIONAL, NULL, NULL }, ++ { "algorithmReference", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, SC_ASN1_OPTIONAL, NULL, NULL }, ++ { "algorithmReference", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, SC_ASN1_OPTIONAL, NULL, NULL }, ++ { "algorithmReference", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, SC_ASN1_OPTIONAL, NULL, NULL }, ++ { "algorithmReference", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, SC_ASN1_OPTIONAL, NULL, NULL }, ++ { "algorithmReference", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, SC_ASN1_OPTIONAL, NULL, NULL }, + { "algorithmReference", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, SC_ASN1_OPTIONAL, NULL, NULL }, + { "algorithmReference", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, SC_ASN1_OPTIONAL, NULL, NULL }, + { "algorithmReference", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, SC_ASN1_OPTIONAL, NULL, NULL }, +diff --git a/src/libopensc/pkcs15-skey.c b/src/libopensc/pkcs15-skey.c +index b22e619723..4e58355ad7 100644 +--- a/src/libopensc/pkcs15-skey.c ++++ b/src/libopensc/pkcs15-skey.c +@@ -28,10 +28,18 @@ + #include + + /* +- * in src/libopensc/types.h SC_MAX_SUPPORTED_ALGORITHMS defined as 8 ++ * in src/libopensc/types.h SC_MAX_SUPPORTED_ALGORITHMS defined as 16 + */ + #define C_ASN1_SUPPORTED_ALGORITHMS_SIZE (SC_MAX_SUPPORTED_ALGORITHMS + 1) + static const struct sc_asn1_entry c_asn1_supported_algorithms[C_ASN1_SUPPORTED_ALGORITHMS_SIZE] = { ++ { "algorithmReference", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, SC_ASN1_OPTIONAL, NULL, NULL }, ++ { "algorithmReference", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, SC_ASN1_OPTIONAL, NULL, NULL }, ++ { "algorithmReference", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, SC_ASN1_OPTIONAL, NULL, NULL }, ++ { "algorithmReference", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, SC_ASN1_OPTIONAL, NULL, NULL }, ++ { "algorithmReference", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, SC_ASN1_OPTIONAL, NULL, NULL }, ++ { "algorithmReference", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, SC_ASN1_OPTIONAL, NULL, NULL }, ++ { "algorithmReference", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, SC_ASN1_OPTIONAL, NULL, NULL }, ++ { "algorithmReference", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, SC_ASN1_OPTIONAL, NULL, NULL }, + { "algorithmReference", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, SC_ASN1_OPTIONAL, NULL, NULL }, + { "algorithmReference", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, SC_ASN1_OPTIONAL, NULL, NULL }, + { "algorithmReference", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, SC_ASN1_OPTIONAL, NULL, NULL }, +diff --git a/src/libopensc/pkcs15.c b/src/libopensc/pkcs15.c +index ba04f531ef..d4a4496980 100644 +--- a/src/libopensc/pkcs15.c ++++ b/src/libopensc/pkcs15.c +@@ -64,9 +64,17 @@ static const struct sc_asn1_entry c_asn1_algorithm_info_parameters[3] = { + }; + + /* +- * in src/libopensc/types.h SC_MAX_SUPPORTED_ALGORITHMS defined as 8 ++ * in src/libopensc/types.h SC_MAX_SUPPORTED_ALGORITHMS defined as 16 + */ + static const struct sc_asn1_entry c_asn1_supported_algorithms[SC_MAX_SUPPORTED_ALGORITHMS + 1] = { ++ { "algorithmInfo", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL }, ++ { "algorithmInfo", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL }, ++ { "algorithmInfo", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL }, ++ { "algorithmInfo", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL }, ++ { "algorithmInfo", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL }, ++ { "algorithmInfo", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL }, ++ { "algorithmInfo", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL }, ++ { "algorithmInfo", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL }, + { "algorithmInfo", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL }, + { "algorithmInfo", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL }, + { "algorithmInfo", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL }, +diff --git a/src/libopensc/types.h b/src/libopensc/types.h +index 76cf4c1a71..17035b5505 100644 +--- a/src/libopensc/types.h ++++ b/src/libopensc/types.h +@@ -52,9 +52,11 @@ typedef unsigned char u8; + + /* When changing this value, pay attention to the initialization of the ASN1 + * static variables that use this macro, like, for example, +- * 'c_asn1_supported_algorithms' in src/libopensc/pkcs15.c ++ * 'c_asn1_supported_algorithms' in src/libopensc/pkcs15.c, ++ * src/libopensc/pkcs15-prkey.c and src/libopensc/pkcs15-skey.c ++ * `grep "src/libopensc/types.h SC_MAX_SUPPORTED_ALGORITHMS defined as"' + */ +-#define SC_MAX_SUPPORTED_ALGORITHMS 8 ++#define SC_MAX_SUPPORTED_ALGORITHMS 16 + + struct sc_lv_data { + unsigned char *value; + +From 8292ff57ad581995eca8209764813725594dd34f Mon Sep 17 00:00:00 2001 +From: Doug Engert +Date: Fri, 17 Apr 2020 12:26:14 -0500 +Subject: [PATCH 4/6] sc_supported_algo_info - Put ECDSA OID as inline + + Mismatch of ASN1 parsing of tokeninfo.supported_algos[n].paramters + in one place parameter was treated as a pointer to sc_object_id + and in another as inline structure. This caused segfaults + in pkcs15-tool when it tried to print the OID. + + Changes to be committed: + modified: src/libopensc/opensc.h + modified: src/libopensc/pkcs15.c +--- + src/libopensc/opensc.h | 2 +- + src/libopensc/pkcs15.c | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/libopensc/opensc.h b/src/libopensc/opensc.h +index 9e764665b2..0c3c73e229 100644 +--- a/src/libopensc/opensc.h ++++ b/src/libopensc/opensc.h +@@ -223,7 +223,7 @@ extern "C" { + struct sc_supported_algo_info { + unsigned int reference; + unsigned int mechanism; +- struct sc_object_id *parameters; /* OID for ECC, NULL for RSA */ ++ struct sc_object_id parameters; /* OID for ECC */ + unsigned int operations; + struct sc_object_id algo_id; + unsigned int algo_ref; +diff --git a/src/libopensc/pkcs15.c b/src/libopensc/pkcs15.c +index d4a4496980..c58c34fd13 100644 +--- a/src/libopensc/pkcs15.c ++++ b/src/libopensc/pkcs15.c +@@ -318,7 +318,7 @@ sc_pkcs15_encode_tokeninfo(sc_context_t *ctx, sc_pkcs15_tokeninfo_t *ti, + sc_format_asn1_entry(asn1_algo_infos[ii] + 1, &ti->supported_algos[ii].mechanism, &mechanism_len, 1); + sc_format_asn1_entry(asn1_algo_infos[ii] + 2, + asn1_algo_infos_parameters[ii], NULL, 1); +- if (!ti->supported_algos[ii].parameters) { ++ if (!sc_valid_oid(&ti->supported_algos[ii].parameters)) { + sc_format_asn1_entry(asn1_algo_infos_parameters[ii] + 0, + NULL, NULL, 1); + } + +From f9665e4d46ed278b6cf1188e0e7adb5b6e119ac9 Mon Sep 17 00:00:00 2001 +From: Doug Engert +Date: Thu, 26 Mar 2020 13:51:33 -0500 +Subject: [PATCH 5/6] pkcs15-tool.c - print Supported_algorithms from tokenInfo + +Some cards can provide supported algorithms in tokenInfo +which contain ECDSA OID, and PKCS11 mechanism + +Don't know how many Algo_refs were actually read, +and a ref of 0 may be valid. print at least one Algo_refs. + +Print the mechanism from PKCS11, and print operations +Use the $(top_srcdir)/src/pkcs11/pkcs11-display.c on Unix +Use the $(TOPDIR)\src\pkcs11\pkcs11-display.obj on Windows + +pkcs15.tool.c treat ECDSA OID as inline + +pkcs15-tool prints PKCS11 mechanisms using pkcs11-display.c +Automake now warns that the default will change, in the future +so "[subdir-objects]" is added to configure.ac + + Changes to be committed: + modified: configure.ac + modified: src/tools/Makefile.am + modified: src/tools/Makefile.mak + modified: src/tools/pkcs15-tool.c +--- + configure.ac | 2 +- + src/tools/Makefile.am | 2 +- + src/tools/Makefile.mak | 5 ++++ + src/tools/pkcs15-tool.c | 57 +++++++++++++++++++++++++++++++++++++++++ + 4 files changed, 64 insertions(+), 2 deletions(-) + +diff --git a/configure.ac b/configure.ac +index 705bc027f1..f54093b0aa 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -27,7 +27,7 @@ AC_INIT([PRODUCT_NAME],[PACKAGE_VERSION_MAJOR.PACKAGE_VERSION_MINOR.PACKAGE_VERS + AC_CONFIG_AUX_DIR([.]) + AC_CONFIG_HEADERS([config.h]) + AC_CONFIG_MACRO_DIR([m4]) +-AM_INIT_AUTOMAKE(foreign 1.10) ++AM_INIT_AUTOMAKE(foreign 1.10 [subdir-objects]) + + OPENSC_VERSION_MAJOR="PACKAGE_VERSION_MAJOR" + OPENSC_VERSION_MINOR="PACKAGE_VERSION_MINOR" +diff --git a/src/tools/Makefile.am b/src/tools/Makefile.am +index 5ee5edfb29..55beb631d5 100644 +--- a/src/tools/Makefile.am ++++ b/src/tools/Makefile.am +@@ -52,7 +52,7 @@ piv_tool_SOURCES = piv-tool.c util.c + piv_tool_LDADD = $(OPTIONAL_OPENSSL_LIBS) + opensc_explorer_SOURCES = opensc-explorer.c util.c + opensc_explorer_LDADD = $(OPTIONAL_READLINE_LIBS) +-pkcs15_tool_SOURCES = pkcs15-tool.c util.c ++pkcs15_tool_SOURCES = pkcs15-tool.c util.c ../pkcs11/pkcs11-display.c ../pkcs11/pkcs11-display.h + pkcs15_tool_LDADD = $(OPTIONAL_OPENSSL_LIBS) + pkcs11_tool_SOURCES = pkcs11-tool.c util.c + pkcs11_tool_LDADD = \ +diff --git a/src/tools/Makefile.mak b/src/tools/Makefile.mak +index 4637a44dc6..38e5ba4e7e 100644 +--- a/src/tools/Makefile.mak ++++ b/src/tools/Makefile.mak +@@ -52,6 +52,11 @@ pkcs11-register.exe: pkcs11-register-cmdline.obj fread_to_eof.obj $(LIBS) + link $(LINKFLAGS) /pdb:$*.pdb /out:$@ $*.obj pkcs11-register-cmdline.obj fread_to_eof.obj versioninfo-tools.res $(LIBS) gdi32.lib shell32.lib User32.lib ws2_32.lib + mt -manifest exe.manifest -outputresource:$@;1 + ++pkcs15-tool.exe: pkcs15-tool.obj $(TOPDIR)\src\pkcs11\pkcs11-display.obj ++ cl $(COPTS) /c $*.c ++ link $(LINKFLAGS) /pdb:$*.pdb /out:$@ $*.obj $(TOPDIR)\src\pkcs11\pkcs11-display.obj $(OBJECTS) $(LIBS) $(OPENSSL_LIB) gdi32.lib shell32.lib User32.lib ws2_32.lib ++ mt -manifest exe.manifest -outputresource:$@;1 ++ + .c.exe: + cl $(COPTS) /c $< + link $(LINKFLAGS) /pdb:$*.pdb /out:$@ $*.obj $(OBJECTS) $(LIBS) $(OPENSSL_LIB) gdi32.lib shell32.lib User32.lib ws2_32.lib +diff --git a/src/tools/pkcs15-tool.c b/src/tools/pkcs15-tool.c +index e901e17d0d..363bfb8272 100644 +--- a/src/tools/pkcs15-tool.c ++++ b/src/tools/pkcs15-tool.c +@@ -57,6 +57,7 @@ typedef unsigned __int32 uint32_t; + #include "libopensc/pkcs15.h" + #include "libopensc/asn1.h" + #include "util.h" ++#include "pkcs11/pkcs11-display.h" + + static const char *app_name = "pkcs15-tool"; + +@@ -607,6 +608,8 @@ static void print_prkey_info(const struct sc_pkcs15_object *obj) + struct sc_pkcs15_prkey_info *prkey = (struct sc_pkcs15_prkey_info *) obj->data; + unsigned char guid[40]; + size_t guid_len; ++ int i; ++ int last_algo_refs = 0; + + if (compact) { + printf("\t%-3s", key_types[7 & obj->type]); +@@ -635,6 +638,16 @@ static void print_prkey_info(const struct sc_pkcs15_object *obj) + printf("\tAccess Flags : [0x%02X]", prkey->access_flags); + print_key_access_flags(prkey->access_flags); + printf("\n"); ++ printf("\tAlgo_refs : "); ++ /* zero may be valid and don't know how many were read print at least 1*/ ++ for (i = 0; i< SC_MAX_SUPPORTED_ALGORITHMS; i++) { ++ if (prkey->algo_refs[i] != 0) ++ last_algo_refs = i; ++ } ++ for (i = 0; i< last_algo_refs + 1; i++) { ++ printf("%s%u", (i == 0) ? "" : ", ", prkey->algo_refs[i]); ++ } ++ printf("\n"); + + print_access_rules(obj->access_rules, SC_PKCS15_MAX_ACCESS_RULES); + +@@ -1645,6 +1658,21 @@ static int list_apps(FILE *fout) + return 0; + } + ++ ++static void print_supported_algo_info_operations(unsigned int operation) ++ ++{ ++ size_t i; ++ const char *operations[] = { ++ "compute_checksum", "compute_signature", "verify_checksum", "verify_signature", ++ "encipher", "decipher", "hash", "generate/derive_key" ++ }; ++ const size_t operations_count = NELEMENTS(operations); ++ for (i = 0; i < operations_count; i++) ++ if (operation & (1 << i)) ++ printf(", %s", operations[i]); ++} ++ + static void list_info(void) + { + const char *flags[] = { +@@ -1655,6 +1683,7 @@ static void list_info(void) + }; + char *last_update = sc_pkcs15_get_lastupdate(p15card); + int i, count = 0; ++ int idx; + + printf("PKCS#15 Card [%s]:\n", p15card->tokeninfo->label); + printf("\tVersion : %d\n", p15card->tokeninfo->version); +@@ -1675,6 +1704,34 @@ static void list_info(void) + count++; + } + } ++ printf("\n"); ++ for (i = 0; i < SC_MAX_SUPPORTED_ALGORITHMS; i++) { ++ struct sc_supported_algo_info * sa = &p15card->tokeninfo->supported_algos[i]; ++ ++ if (sa->reference == 0 && sa->reference == 0 && sa->mechanism == 0 ++ && sa->operations == 0 && sa->algo_ref == 0) ++ break; ++ printf("\t\t sc_supported_algo_info[%d]:\n", i); ++ printf("\t\t\t reference : %u (0x%02x)\n", sa->reference, sa->reference); ++ printf("\t\t\t mechanism : [0x%02x] %s\n", sa->mechanism, lookup_enum(MEC_T, sa->mechanism)); ++ if (sc_valid_oid(&sa->parameters)) { ++ printf("\t\t\t parameters: %i", sa->parameters.value[0]); ++ for (idx = 1; idx < SC_MAX_OBJECT_ID_OCTETS && sa->parameters.value[idx] != -1 ; idx++) ++ printf(".%i", sa->parameters.value[idx]); ++ printf("\n"); ++ } ++ printf("\t\t\t operations : [0x%2.2x]",sa->operations); ++ print_supported_algo_info_operations(sa->operations); ++ printf("\n"); ++ if (sc_valid_oid((const struct sc_object_id*)&sa->algo_id)) { ++ printf("\t\t\t algo_id : %i", sa->algo_id.value[0]); ++ for (idx = 1; idx < SC_MAX_OBJECT_ID_OCTETS && sa->algo_id.value[idx] != -1 ; idx++) ++ printf(".%i", sa->algo_id.value[idx]); ++ printf("\n"); ++ } ++ printf("\t\t\t algo_ref : [0x%02x]\n",sa->algo_ref); ++ } ++ + printf((compact) ? "\n" : "\n\n"); + } + + +From f472f0ec213adc096508997bf7e1786ffb557d52 Mon Sep 17 00:00:00 2001 +From: Doug Engert +Date: Fri, 17 Apr 2020 11:36:48 -0500 +Subject: [PATCH 6/6] Various CardOS V5_* improvements +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Treat CardOS V5_0 and V5_3 cards differently then older versions: + +Use card->dvr_data as a pointer to cardos_data_t to store private driver +data to pass internally, especially between set security environment +and the crypto operations. Sc_get_encoding_flags sets sec_flags from +algo_info->flags in pkcs15-sec.c and it passed to decipher. + +Some cards when doing a decipher may drop leading 00 byte when +returning data from RSA_RAW decipher. Add leading byte(s) as needed. + +Get Cryptographic Mechanism Reference from Key Reference: + +Key reference byte appears to be a 4 bit Cryptographic Mechanism Reference +and a 4 bit key reference. + +This is only done if key reference & 0xF0 != 0 i.e. default Cryptographic +mechanism reference is 0. which appears to be the case for RSA RAW. +PKCS1 appears to be 0x10 and ECDSA 0x30 + + See iso 7816-4 table 55 for DST: + 84 Reference of a private key + 95 Usage qualifier byte - Table 57 - 40 looks OK + 80 Cryptographic mechanism reference and referes to section 9.2 + +The 4 bit key reference limits card to 16 keys. In future this may not work, +but we can derive a Cryptographic Mechanism Reference from what OpenSC +thinks the card needs to do. Only know RSA RAW, PKCS1 and ECDSA. + +ECDSA code has not been tested, but expected to work. + +Allow setting CardOS type and flags from opensc.conf using card_atr stanza +This is a fallback if newer cards are added or older cards have problems +giving us time to make need changes in next release. + +It will help in identifying what flags are needed for each card. +As user can report what combination of flags work for them. They do this by +adding to opensc.conf with something like this. (Change the ATR to your card's ATR): + + card_atr 3b:d2:18:00:81:31:fe:58:c9:03:16 { + driver = "cardos"; + # type is decimal from cards.h: + # SC_CARD_TYPE_CARDOS_V5_0 is 1009 + # SC_CARD_TYPE_CARDOS_V5_3 is 1010 + type = 1010; + + # flags is hex from opensc.h: + #define SC_ALGORITHM_ONBOARD_KEY_GEN 0x80000000 + #define SC_ALGORITHM_NEED_USAGE 0x40000000 + + #define SC_ALGORITHM_RSA_RAW 0x00000001 /* RSA_RAW is PAD_NONE */ + #define SC_ALGORITHM_RSA_PAD_NONE 0x00000001 + #define SC_ALGORITHM_RSA_PAD_PKCS1 0x00000002 /* PKCS#1 v1.5 padding */ + #define SC_ALGORITHM_RSA_PAD_ANSI 0x00000004 + #define SC_ALGORITHM_RSA_PAD_ISO9796 0x00000008 + #define SC_ALGORITHM_RSA_PAD_PSS 0x00000010 /* PKCS#1 v2.0 PSS */ + #define SC_ALGORITHM_RSA_PAD_OAEP 0x00000020 /* PKCS#1 v2.0 OAEP */ + #define SC_ALGORITHM_RSA_HASH_NONE 0x00000100 /* only applies to PKCS1 padding */ + # example: SC_ALGORITHM_ONBOARD_KEY_GEN | SC_ALGORITHM_RSA_HASH_NONE | SC_ALGORITHM_RSA_RAW + flags = 80000101; + #example: SC_ALGORITHM_ONBOARD_KEY_GEN | SC_ALGORITHM_RSA_PAD_PKCS1 + flags = 80000002; + } + +For V5_0 and v5_3 cards, use sc_get_max_send_size and sc_get_max_recv_size +which takes care or reader sizes even on Windows where SCardControl can not get PART_10 sizes. + +(commit eddea6f3c2d3dafc2c09eba6695c745a61b5186f on Windows forces reader sizes to 255, 256 +in reader-pcsc.c if not already set. It should not do this, but leave that up to card drivers.) + +pkcs15-cardos.c added: + +New file, pkcs15-cardos.c, added as emulation only for CardOS +V5_0 and V5_3 cards. + +sc_pkcs15_bind_internal is called to get tokenInfo as CardOS +cards are substantially PKCS15 cards. But some V5_* cards have +errors in the tokenInfo, Which are corrected. + +For older CardOS cards, card-cardos.c will create all the +card->algorithms. + +Pkcs15-cardos.c will check for card->algorithms and if there +are none, it will do the following: + +SC_CARDCTL_CARDOS_PASS_ALGO_FLAGS is called twice. First to get +the flags as set by user via opensc.conf card_atr or default +flags set by the card driver. Then after determining from the +tokenInfo what algorithms the card can support, the new flags +are passed to card_cardos.c to create card->algorithms. + +https://atos.net/wp-content/uploads/2018/11/CT_181026_LPM_CardOS_V5-3_Multifunctionality_FS_en3_web.pdf +says card supports: "“Command chaining” in accordance with ISO/IEC 7816-4" + +To take advantage of this with older readers, max_send_size and max_recv_size +is now based on minimum of reader limits and "data_field_length" from card. +This should allow card to work in older readers not capable of extended APDU. +So far current cards we have seen do no appear to support “Command chaining”. + + Changes to be committed: + modified: src/libopensc/Makefile.am + modified: src/libopensc/Makefile.mak + modified: src/libopensc/card-cardos.c + modified: src/libopensc/cardctl.h + modified: src/libopensc/cards.h + new file: src/libopensc/pkcs15-cardos.c + modified: src/libopensc/pkcs15-syn.c + modified: src/libopensc/pkcs15-syn.h +--- + src/libopensc/Makefile.am | 4 +- + src/libopensc/Makefile.mak | 2 +- + src/libopensc/card-cardos.c | 336 +++++++++++++++++++++++++++++----- + src/libopensc/cardctl.h | 18 ++ + src/libopensc/cards.h | 1 + + src/libopensc/pkcs15-cardos.c | 177 ++++++++++++++++++ + src/libopensc/pkcs15-syn.c | 3 + + src/libopensc/pkcs15-syn.h | 1 + + 8 files changed, 492 insertions(+), 50 deletions(-) + create mode 100644 src/libopensc/pkcs15-cardos.c + +diff --git a/src/libopensc/Makefile.am b/src/libopensc/Makefile.am +index 140665c8a6..9f0dda5ecb 100644 +--- a/src/libopensc/Makefile.am ++++ b/src/libopensc/Makefile.am +@@ -51,7 +51,7 @@ libopensc_la_SOURCES_BASE = \ + ctbcs.c reader-ctapi.c reader-pcsc.c reader-openct.c reader-tr03119.c \ + \ + card-setcos.c card-miocos.c card-flex.c card-gpk.c \ +- card-cardos.c card-tcos.c card-default.c \ ++ card-cardos.c card-tcos.c pkcs15-cardos.c card-default.c \ + card-mcrd.c card-starcos.c card-openpgp.c card-jcop.c \ + card-oberthur.c card-belpic.c card-atrust-acos.c \ + card-entersafe.c card-epass2003.c card-coolkey.c card-incrypto34.c \ +@@ -134,7 +134,7 @@ TIDY_FILES = \ + card-npa.c card-esteid2018.c \ + \ + pkcs15-openpgp.c \ +- pkcs15-tcos.c pkcs15-esteid.c \ ++ pkcs15-tcos.c pkcs15-esteid.c pkcs15-cardos.c \ + pkcs15-actalis.c pkcs15-atrust-acos.c pkcs15-tccardos.c \ + pkcs15-cac.c pkcs15-esinit.c pkcs15-westcos.c pkcs15-pteid.c \ + pkcs15-oberthur.c pkcs15-itacns.c pkcs15-sc-hsm.c \ +diff --git a/src/libopensc/Makefile.mak b/src/libopensc/Makefile.mak +index 2e3c30c22b..1b0ff45c9b 100644 +--- a/src/libopensc/Makefile.mak ++++ b/src/libopensc/Makefile.mak +@@ -29,7 +29,7 @@ OBJECTS = \ + card-masktech.obj card-gids.obj card-jpki.obj \ + card-npa.obj card-esteid2018.obj \ + \ +- pkcs15-openpgp.obj pkcs15-starcert.obj \ ++ pkcs15-openpgp.obj pkcs15-starcert.obj pkcs15-cardos.obj \ + pkcs15-tcos.obj pkcs15-esteid.obj pkcs15-gemsafeGPK.obj \ + pkcs15-actalis.obj pkcs15-atrust-acos.obj pkcs15-tccardos.obj pkcs15-piv.obj \ + pkcs15-cac.obj pkcs15-esinit.obj pkcs15-westcos.obj pkcs15-pteid.obj pkcs15-din-66291.obj \ +diff --git a/src/libopensc/card-cardos.c b/src/libopensc/card-cardos.c +index 306822b974..4ef6ead0d2 100644 +--- a/src/libopensc/card-cardos.c ++++ b/src/libopensc/card-cardos.c +@@ -53,13 +53,42 @@ static const struct sc_atr_table cardos_atrs[] = { + /* CardOS v5.0 */ + { "3b:d2:18:00:81:31:fe:58:c9:01:14", NULL, NULL, SC_CARD_TYPE_CARDOS_V5_0, 0, NULL}, + /* CardOS v5.3 */ +- { "3b:d2:18:00:81:31:fe:58:c9:02:17", NULL, NULL, SC_CARD_TYPE_CARDOS_V5_0, 0, NULL}, +- { "3b:d2:18:00:81:31:fe:58:c9:03:16", NULL, NULL, SC_CARD_TYPE_CARDOS_V5_0, 0, NULL}, ++ { "3b:d2:18:00:81:31:fe:58:c9:02:17", NULL, NULL, SC_CARD_TYPE_CARDOS_V5_3, 0, NULL}, ++ { "3b:d2:18:00:81:31:fe:58:c9:03:16", NULL, NULL, SC_CARD_TYPE_CARDOS_V5_3, 0, NULL}, + { NULL, NULL, NULL, 0, 0, NULL } + }; + +-static unsigned int algorithm_ids_in_tokeninfo[SC_MAX_SUPPORTED_ALGORITHMS]; +-static unsigned int algorithm_ids_in_tokeninfo_count=0; ++/* private data for cardos driver */ ++typedef struct cardos_data { ++ /* constructed internally */ ++ unsigned int algorithm_ids_in_tokeninfo[SC_MAX_SUPPORTED_ALGORITHMS]; ++ unsigned int algorithm_ids_in_tokeninfo_count; ++ unsigned long flags; /* flags used by init to create sc_algorithms */ ++ unsigned long ec_flags; ++ unsigned long ext_flags; ++ int rsa_2048; ++ const sc_security_env_t * sec_env; ++} cardos_data_t; ++ ++/* copied from iso7816.c */ ++static void fixup_transceive_length(const struct sc_card *card, ++ struct sc_apdu *apdu) ++{ ++ if (card == NULL || apdu == NULL) { ++ return; ++ } ++ ++ if (apdu->lc > sc_get_max_send_size(card)) { ++ /* The lower layers will automatically do chaining */ ++ apdu->flags |= SC_APDU_FLAGS_CHAINING; ++ } ++ ++ if (apdu->le > sc_get_max_recv_size(card)) { ++ /* The lower layers will automatically do a GET RESPONSE, if possible. ++ * All other workarounds must be carried out by the upper layers. */ ++ apdu->le = sc_get_max_recv_size(card); ++ } ++} + + static int cardos_match_card(sc_card_t *card) + { +@@ -79,6 +108,8 @@ static int cardos_match_card(sc_card_t *card) + return 1; + if (card->type == SC_CARD_TYPE_CARDOS_V5_0) + return 1; ++ if (card->type == SC_CARD_TYPE_CARDOS_V5_3) ++ return 1; + if (card->type == SC_CARD_TYPE_CARDOS_M4_2) { + int rv; + sc_apdu_t apdu; +@@ -159,42 +190,102 @@ static int cardos_have_2048bit_package(sc_card_t *card) + return 0; + } + ++ ++/* Called from cardos_init for old cards, from cardos_cardctl_parsed_token_info for new cards */ ++/* TODO see if works from old cards too */ ++static int cardos_add_algs(sc_card_t *card, unsigned long flags, unsigned long ec_flags, unsigned long ext_flags) ++{ ++ ++ cardos_data_t * priv = (cardos_data_t *)card->drv_data; ++ ++ SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); ++ ++ _sc_card_add_rsa_alg(card, 512, flags, 0); ++ _sc_card_add_rsa_alg(card, 768, flags, 0); ++ _sc_card_add_rsa_alg(card, 1024, flags, 0); ++ if (priv->rsa_2048 == 1) { ++ _sc_card_add_rsa_alg(card, 1280, flags, 0); ++ _sc_card_add_rsa_alg(card, 1536, flags, 0); ++ _sc_card_add_rsa_alg(card, 1792, flags, 0); ++ _sc_card_add_rsa_alg(card, 2048, flags, 0); ++ } ++ ++ if (card->type == SC_CARD_TYPE_CARDOS_V5_0 || card->type == SC_CARD_TYPE_CARDOS_V5_3) { ++ /* Starting with CardOS 5, the card supports PIN query commands */ ++ card->caps |= SC_CARD_CAP_ISO7816_PIN_INFO; ++ _sc_card_add_rsa_alg(card, 3072, flags, 0); ++ _sc_card_add_rsa_alg(card, 4096, flags, 0); ++ } ++ ++ /* TODO need to get sizes from supported_algos too */ ++ if (ec_flags != 0) { ++ _sc_card_add_ec_alg(card, 256, ec_flags, priv->ext_flags, NULL); ++ _sc_card_add_ec_alg(card, 384, ec_flags, priv->ext_flags, NULL); ++ } ++ ++ return 0; ++} ++ + static int cardos_init(sc_card_t *card) + { +- unsigned long flags = 0, rsa_2048 = 0; ++ cardos_data_t * priv = NULL; ++ unsigned long flags = 0; + size_t data_field_length; + sc_apdu_t apdu; + u8 rbuf[2]; + int r; + ++ SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); ++ ++ priv = calloc(1, sizeof(cardos_data_t)); ++ if (!priv) ++ LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); ++ card->drv_data = priv; ++ + card->name = "Atos CardOS"; + card->cla = 0x00; + +- /* Set up algorithm info. */ +- flags = 0; +- if (card->type == SC_CARD_TYPE_CARDOS_V5_0) { +- flags |= SC_ALGORITHM_RSA_PAD_PKCS1; ++ /* let user override flags and type from opensc.conf */ ++ /* user can override card->type too.*/ ++ if (card->flags) { ++ flags = card->flags; + } else { +- flags |= SC_ALGORITHM_RSA_RAW +- | SC_ALGORITHM_RSA_HASH_NONE +- | SC_ALGORITHM_NEED_USAGE +- | SC_ALGORITHM_ONBOARD_KEY_GEN; ++ ++ /* Set up algorithm info. */ ++ flags = 0; ++ if (card->type == SC_CARD_TYPE_CARDOS_V5_0) { ++ flags |= SC_ALGORITHM_RSA_PAD_PKCS1; ++ } else if(card->type == SC_CARD_TYPE_CARDOS_V5_3) { ++ flags |= SC_ALGORITHM_RSA_RAW ++ | SC_ALGORITHM_RSA_HASH_NONE ++ | SC_ALGORITHM_ONBOARD_KEY_GEN; ++ } else { ++ flags |= SC_ALGORITHM_RSA_RAW ++ | SC_ALGORITHM_RSA_HASH_NONE ++ | SC_ALGORITHM_NEED_USAGE ++ | SC_ALGORITHM_ONBOARD_KEY_GEN; ++ } + } + ++ priv->flags = flags; ++ + if (card->type == SC_CARD_TYPE_CARDOS_M4_2) { + r = cardos_have_2048bit_package(card); + if (r < 0) + return SC_ERROR_INVALID_CARD; + if (r == 1) +- rsa_2048 = 1; ++ priv->rsa_2048 = 1; + card->caps |= SC_CARD_CAP_APDU_EXT; +- } else if (card->type == SC_CARD_TYPE_CARDOS_M4_3 ++ } else if (card->type == SC_CARD_TYPE_CARDOS_M4_3 + || card->type == SC_CARD_TYPE_CARDOS_M4_2B + || card->type == SC_CARD_TYPE_CARDOS_M4_2C + || card->type == SC_CARD_TYPE_CARDOS_M4_4 +- || card->type == SC_CARD_TYPE_CARDOS_V5_0) { +- rsa_2048 = 1; ++ || card->type == SC_CARD_TYPE_CARDOS_V5_0 ++ || card->type == SC_CARD_TYPE_CARDOS_V5_3) { ++ priv->rsa_2048 = 1; + card->caps |= SC_CARD_CAP_APDU_EXT; ++ /* TODO check this. EC only if in supported_algo */ ++ priv->ext_flags = SC_ALGORITHM_EXT_EC_NAMEDCURVE | SC_ALGORITHM_EXT_EC_UNCOMPRESES; + } + + /* probe DATA FIELD LENGTH with GET DATA */ +@@ -202,6 +293,7 @@ static int cardos_init(sc_card_t *card) + apdu.le = sizeof rbuf; + apdu.resp = rbuf; + apdu.resplen = sizeof(rbuf); ++ + r = sc_transmit_apdu(card, &apdu); + if (r < 0) + LOG_TEST_RET(card->ctx, +@@ -216,34 +308,99 @@ static int cardos_init(sc_card_t *card) + return SC_ERROR_INVALID_CARD; + data_field_length = ((rbuf[0] << 8) | rbuf[1]); + +- /* strip the length of possible Lc and Le bytes */ +- if (card->caps & SC_CARD_CAP_APDU_EXT) +- card->max_send_size = data_field_length - 6; +- else +- card->max_send_size = data_field_length - 3; +- /* strip the length of SW bytes */ +- card->max_recv_size = data_field_length - 2; ++ /* TODO is this really needed? strip the length of possible Lc and Le bytes */ ++ ++ /* Use Min card sizes and reader too. for V5_3 at least*/ ++ ++ if (card->type == SC_CARD_TYPE_CARDOS_V5_0 || card->type == SC_CARD_TYPE_CARDOS_V5_3) { ++ sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "data_field_length:%"SC_FORMAT_LEN_SIZE_T"u " ++ "card->reader->max_send_size:%"SC_FORMAT_LEN_SIZE_T"u " ++ "card->reader->max_recv_size:%"SC_FORMAT_LEN_SIZE_T"u %s", ++ data_field_length, card->reader->max_send_size, card->reader->max_recv_size, ++ (card->caps & SC_CARD_CAP_APDU_EXT) ? "SC_CARD_CAP_APDU_EXT" : " "); ++ ++ if (card->caps & SC_CARD_CAP_APDU_EXT) { ++ card->max_send_size = data_field_length - 6; ++#ifdef _WIN32 ++ /* Windows does not support PCSC PART_10 and may have forced reader to 255/256 ++ * https://github.com/OpenSC/OpenSC/commit/eddea6f3c2d3dafc2c09eba6695c745a61b5186f ++ * may have reset this. if so, will override and force extended ++ * Most, if not all, cardos cards do extended, but not chaining ++ */ ++ if (card->reader->max_send_size == 255 && card->reader->max_recv_size == 256) { ++ sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "reseting reader to use data_field_length"); ++ card->reader->max_send_size = data_field_length - 6; ++ card->reader->max_recv_size = data_field_length - 3; ++ } ++#endif ++ } else ++ card->max_send_size = data_field_length - 3; + +- _sc_card_add_rsa_alg(card, 512, flags, 0); +- _sc_card_add_rsa_alg(card, 768, flags, 0); +- _sc_card_add_rsa_alg(card, 1024, flags, 0); +- if (rsa_2048 == 1) { +- _sc_card_add_rsa_alg(card, 1280, flags, 0); +- _sc_card_add_rsa_alg(card, 1536, flags, 0); +- _sc_card_add_rsa_alg(card, 1792, flags, 0); +- _sc_card_add_rsa_alg(card, 2048, flags, 0); ++ card->max_send_size = sc_get_max_send_size(card); /* include reader sizes and protocol */ ++ card->max_recv_size = data_field_length - 2; ++ card->max_recv_size = sc_get_max_recv_size(card); ++ } else { ++ /* old way, disregards reader capabilities */ ++ if (card->caps & SC_CARD_CAP_APDU_EXT) ++ card->max_send_size = data_field_length - 6; ++ else ++ card->max_send_size = data_field_length - 3; ++ /* strip the length of SW bytes */ ++ card->max_recv_size = data_field_length - 2; + } + +- if (card->type == SC_CARD_TYPE_CARDOS_V5_0) { +- /* Starting with CardOS 5, the card supports PIN query commands */ +- card->caps |= SC_CARD_CAP_ISO7816_PIN_INFO; +- _sc_card_add_rsa_alg(card, 3072, flags, 0); +- _sc_card_add_rsa_alg(card, 4096, flags, 0); ++ /*for new cards, wait till after sc_pkcs15_bind_internal reads tokeninfo */ ++ if (card->type != SC_CARD_TYPE_CARDOS_V5_0 && card->type != SC_CARD_TYPE_CARDOS_V5_3) { ++ r = cardos_add_algs(card, flags, 0, 0); + } + + return 0; + } + ++static int cardos_pass_algo_flags(sc_card_t *card, struct sc_cardctl_cardos_pass_algo_flags * ptr) ++{ ++ cardos_data_t * priv = (cardos_data_t *)card->drv_data; ++ int r = 0; ++ ++ SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); ++ switch (ptr->pass) { ++ case 1: ++ ptr->card_flags = card->flags; ++ ptr->used_flags = priv->flags; ++ ptr->ec_flags = priv->ec_flags; ++ ptr->ext_flags = priv->ext_flags; ++ break; ++ case 2: ++ r = cardos_add_algs(card,ptr->new_flags, ptr->ec_flags, ptr->ext_flags); ++ break; ++ default: ++ sc_log(card->ctx, "ptr->pass: %ul invalid", ptr->pass); ++ r = SC_ERROR_INTERNAL; ++ } ++ LOG_FUNC_RETURN(card->ctx, r); ++} ++ ++ ++static int cardos_finish(sc_card_t *card) ++{ ++ int r = 0; ++ ++ if (card) ++ return 0; ++ ++ SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); ++ ++ /* free priv data */ ++ if (card->drv_data) { /* priv */ ++ free(card->drv_data); ++ card->drv_data = NULL; ++ } ++ ++ SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r); ++} ++ ++ ++ + static const struct sc_card_error cardos_errors[] = { + /* some error inside the card */ + /* i.e. nothing you can do */ +@@ -772,8 +929,9 @@ cardos_set_security_env(sc_card_t *card, + const sc_security_env_t *env, + int se_num) + { ++ cardos_data_t* priv = (cardos_data_t*)card->drv_data; + sc_apdu_t apdu; +- u8 data[6]; ++ u8 data[9]; + int key_id, r; + + assert(card != NULL && env != NULL); +@@ -782,6 +940,15 @@ cardos_set_security_env(sc_card_t *card, + sc_log(card->ctx, "No or invalid key reference\n"); + return SC_ERROR_INVALID_ARGUMENTS; + } ++ priv->sec_env = env; /* pass on to crypto routines */ ++ ++ /* key_ref includes card mechanism and key number ++ * But newer cards appear to get this some other way, ++ * We can use flags passed to know what OpenSC expects from the card ++ * and have derived what these machanisums are. ++ * Newer cards may change how this is done ++ */ ++ + key_id = env->key_ref[0]; + + sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0, 0); +@@ -802,16 +969,39 @@ cardos_set_security_env(sc_card_t *card, + return SC_ERROR_INVALID_ARGUMENTS; + } + +- if (card->type == SC_CARD_TYPE_CARDOS_V5_0) { ++ if (card->type == SC_CARD_TYPE_CARDOS_V5_0 || card->type == SC_CARD_TYPE_CARDOS_V5_3) { ++ /* some cards appear to have key_id be both Cryptographic mechanism reference 4 bits ++ * and key_ref 4 bits. But this limits card to 16 keys. ++ * TODO may need to be looked at at a later time ++ */ + /* Private key reference */ + data[0] = 0x84; + data[1] = 0x01; +- data[2] = key_id; ++ data[2] = key_id & 0x0F; + /* Usage qualifier byte */ + data[3] = 0x95; + data[4] = 0x01; + data[5] = 0x40; + apdu.lc = apdu.datalen = 6; ++ if (key_id & 0xF0) { ++ /* Cryptographic mechanism reference */ ++ data[6] = 0x80; ++ data[7] = 0x01; ++ data[8] = key_id & 0xF0; ++ apdu.lc = apdu.datalen = 9; ++ } else if (priv->sec_env->algorithm_flags & SC_ALGORITHM_RSA_PAD_PKCS1) { ++ /* TODO this may only apply to c903 cards */ ++ /* TODO or only for cards without any supported_algos or EIDComplient only */ ++ data[6] = 0x80; ++ data[7] = 0x01; ++ data[8] = 0x10; ++ apdu.lc = apdu.datalen = 9; ++ } else if (priv->sec_env->algorithm_flags & SC_ALGORITHM_ECDSA_RAW) { ++ data[6] = 0x80; ++ data[7] = 0x01; ++ data[8] = 0x30; ++ apdu.lc = apdu.datalen = 9; ++ } + } else { + data[0] = 0x83; + data[1] = 0x01; +@@ -839,12 +1029,12 @@ cardos_set_security_env(sc_card_t *card, + + sc_log(card->ctx, "is signature"); + sc_log(card->ctx, "Adding ID %d at index %d", algorithm_id, algorithm_id_count); +- algorithm_ids_in_tokeninfo[algorithm_id_count++] = algorithm_id; ++ priv->algorithm_ids_in_tokeninfo[algorithm_id_count++] = algorithm_id; + } + sc_log(card->ctx, "reference=%d, mechanism=%d, operations=%d, algo_ref=%d", + alg.reference, alg.mechanism, alg.operations, alg.algo_ref); + } +- algorithm_ids_in_tokeninfo_count = algorithm_id_count; ++ priv -> algorithm_ids_in_tokeninfo_count = algorithm_id_count; + } while (0); + + LOG_FUNC_RETURN(card->ctx, r); +@@ -859,6 +1049,7 @@ static int + do_compute_signature(sc_card_t *card, const u8 *data, size_t datalen, + u8 *out, size_t outlen) + { ++ /* cardos_data_t* priv = (cardos_data_t*)card->drv_dataa */; + int r; + sc_apdu_t apdu; + +@@ -873,6 +1064,7 @@ do_compute_signature(sc_card_t *card, const u8 *data, size_t datalen, + apdu.data = data; + apdu.lc = datalen; + apdu.datalen = datalen; ++ fixup_transceive_length(card, &apdu); + r = sc_transmit_apdu(card, &apdu); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); + +@@ -886,6 +1078,7 @@ static int + cardos_compute_signature(sc_card_t *card, const u8 *data, size_t datalen, + u8 *out, size_t outlen) + { ++ cardos_data_t* priv; + int r; + sc_context_t *ctx; + int do_rsa_pure_sig = 0; +@@ -895,8 +1088,21 @@ cardos_compute_signature(sc_card_t *card, const u8 *data, size_t datalen, + + assert(card != NULL && data != NULL && out != NULL); + ctx = card->ctx; ++ priv = (cardos_data_t*)card->drv_data; + SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE); + ++ /* sec_env has algorithm_flags set from sc_get_encoding_flags sec_flags ++ * If flags are set correctly we don't need to test anything ++ * TODO this assumes RSA is PSS, PKCS1 or RAW and we are passing ++ * the correct data. Should work for ECDSA too. ++ * use for V5 cards and TODO should for older cards too ++ */ ++ if (card->type == SC_CARD_TYPE_CARDOS_V5_0 || card->type == SC_CARD_TYPE_CARDOS_V5_3) { ++ ++ r = do_compute_signature(card, data, datalen, out, outlen); ++ LOG_FUNC_RETURN(ctx, r); ++ } ++ + /* There are two ways to create a signature, depending on the way, + * the key was created: RSA_SIG and RSA_PURE_SIG. + * We can use the following reasoning, to determine the correct operation: +@@ -913,8 +1119,8 @@ cardos_compute_signature(sc_card_t *card, const u8 *data, size_t datalen, + */ + + /* check the the algorithmIDs from the AlgorithmInfo */ +- for (i = 0; i < algorithm_ids_in_tokeninfo_count; ++i) { +- unsigned int id = algorithm_ids_in_tokeninfo[i]; ++ for (i = 0; i < priv->algorithm_ids_in_tokeninfo_count; ++i) { ++ unsigned int id = priv->algorithm_ids_in_tokeninfo[i]; + if (id == 0x86 || id == 0x88) { + do_rsa_sig = 1; + } else if (id == 0x8C || id == 0x8A) { +@@ -985,10 +1191,41 @@ cardos_decipher(struct sc_card *card, + const u8 * crgram, size_t crgram_len, + u8 * out, size_t outlen) + { ++ cardos_data_t* priv = (cardos_data_t*)card->drv_data; + int r; + size_t card_max_send_size = card->max_send_size; + size_t reader_max_send_size = card->reader->max_send_size; + ++ SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); ++ ++ /* 5.3 supports command chaining. Others may also ++ * card_max_send_size for 5.3 is already based on reader max_send_size */ ++ ++ if (card->type == SC_CARD_TYPE_CARDOS_V5_0 || card->type == SC_CARD_TYPE_CARDOS_V5_3) { ++ ++ r = iso_ops->decipher(card, crgram, crgram_len, out, outlen); ++ /* ++ * 5.3 supports RAW as well as PKCS1 and PSS ++ * decription may strip padding if card supports it ++ * with cards that support RAW, it always appears to ++ * drop first 00 that is start of padding. ++ */ ++ ++ if (r > 0 && priv->sec_env->algorithm_flags & SC_ALGORITHM_RSA_RAW) { ++ size_t rsize = r; ++ /* RSA RAW crgram_len == modlen */ ++ /* removed padding is always > 1 byte */ ++ /* add back missing leading zero if card dropped it */ ++ if (rsize == crgram_len - 1 && rsize < outlen) { ++ memmove(out+1, out, rsize); ++ out[0] =0x00; ++ r++; ++ } ++ } ++ ++ SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r); ++ } ++ + if (sc_get_max_send_size(card) < crgram_len + 1) { + /* CardOS doesn't support chaining for PSO:DEC, so we just _hope_ + * that both, the reader and the card are able to send enough data. +@@ -1003,7 +1240,7 @@ cardos_decipher(struct sc_card *card, + card->max_send_size = card_max_send_size; + card->reader->max_send_size = reader_max_send_size; + +- return r; ++ SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r); + } + + static int +@@ -1188,7 +1425,7 @@ static int cardos_get_serialnr(sc_card_t *card, sc_serial_number_t *serial) + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); + if (apdu.sw1 != 0x90 || apdu.sw2 != 0x00) + return SC_ERROR_INTERNAL; +- if ((apdu.resplen == 8) && (card->type == SC_CARD_TYPE_CARDOS_V5_0)) { ++ if ((apdu.resplen == 8) && (card->type == SC_CARD_TYPE_CARDOS_V5_0 || card->type == SC_CARD_TYPE_CARDOS_V5_3)) { + /* cache serial number */ + memcpy(card->serialnr.value, rbuf, 8); + card->serialnr.len = 8; +@@ -1223,6 +1460,9 @@ cardos_card_ctl(sc_card_t *card, unsigned long cmd, void *ptr) + case SC_CARDCTL_CARDOS_GENERATE_KEY: + return cardos_generate_key(card, + (struct sc_cardctl_cardos_genkey_info *) ptr); ++ case SC_CARDCTL_CARDOS_PASS_ALGO_FLAGS: ++ return cardos_pass_algo_flags(card, ++ (struct sc_cardctl_cardos_pass_algo_flags *) ptr); + case SC_CARDCTL_LIFECYCLE_GET: + return cardos_lifecycle_get(card, (int *) ptr); + case SC_CARDCTL_LIFECYCLE_SET: +@@ -1279,7 +1519,8 @@ cardos_logout(sc_card_t *card) + || card->type == SC_CARD_TYPE_CARDOS_M4_2C + || card->type == SC_CARD_TYPE_CARDOS_M4_3 + || card->type == SC_CARD_TYPE_CARDOS_M4_4 +- || card->type == SC_CARD_TYPE_CARDOS_V5_0) { ++ || card->type == SC_CARD_TYPE_CARDOS_V5_0 ++ || card->type == SC_CARD_TYPE_CARDOS_V5_3) { + sc_apdu_t apdu; + int r; + sc_path_t path; +@@ -1309,6 +1550,7 @@ static struct sc_card_driver * sc_get_driver(void) + cardos_ops = *iso_ops; + cardos_ops.match_card = cardos_match_card; + cardos_ops.init = cardos_init; ++ cardos_ops.finish = cardos_finish; + cardos_ops.select_file = cardos_select_file; + cardos_ops.create_file = cardos_create_file; + cardos_ops.set_security_env = cardos_set_security_env; +diff --git a/src/libopensc/cardctl.h b/src/libopensc/cardctl.h +index 0c68c4c625..10ddfa0545 100644 +--- a/src/libopensc/cardctl.h ++++ b/src/libopensc/cardctl.h +@@ -83,6 +83,7 @@ enum { + SC_CARDCTL_CARDOS_PUT_DATA_OCI, + SC_CARDCTL_CARDOS_PUT_DATA_SECI, + SC_CARDCTL_CARDOS_GENERATE_KEY, ++ SC_CARDCTL_CARDOS_PASS_ALGO_FLAGS, + + /* + * Starcos SPK 2.3 specific calls +@@ -350,6 +351,14 @@ typedef struct sc_cardctl_pkcs11_init_pin { + size_t pin_len; + } sc_cardctl_pkcs11_init_pin_t; + ++/* ++ * Generic cardctl - card driver can examine token info ++ */ ++struct sc_cardctl_parsed_token_info { ++ unsigned int flags; ++ struct sc_pkcs15_tokeninfo * tokeninfo; ++}; ++ + /* + * GPK lock file. + * Parent DF of file must be selected. +@@ -419,6 +428,15 @@ struct sc_cardctl_cardos_genkey_info { + unsigned short fid; + }; + ++struct sc_cardctl_cardos_pass_algo_flags { ++ unsigned int pass; ++ unsigned long card_flags; /* from card->flags i.e. user set */ ++ unsigned long used_flags; /* as set by default */ ++ unsigned long new_flags; /* set in pkcs15-cardos.c */ ++ unsigned long ec_flags; /* for EC keys */ ++ unsigned long ext_flags; /* for EC keys */ ++}; ++ + /* + * Incrypto34 PIN info + */ +diff --git a/src/libopensc/cards.h b/src/libopensc/cards.h +index cb0501c3aa..8d58fb9368 100644 +--- a/src/libopensc/cards.h ++++ b/src/libopensc/cards.h +@@ -47,6 +47,7 @@ enum { + SC_CARD_TYPE_CARDOS_CIE_V1, /* Italian CIE (eID) v1 */ + SC_CARD_TYPE_CARDOS_M4_4, + SC_CARD_TYPE_CARDOS_V5_0, ++ SC_CARD_TYPE_CARDOS_V5_3, + + /* flex/cyberflex drivers */ + SC_CARD_TYPE_FLEX_BASE = 2000, +diff --git a/src/libopensc/pkcs15-cardos.c b/src/libopensc/pkcs15-cardos.c +new file mode 100644 +index 0000000000..752631ce88 +--- /dev/null ++++ b/src/libopensc/pkcs15-cardos.c +@@ -0,0 +1,177 @@ ++/* ++ * PKCS15 emulation layer for CardOS cards ++ * Adapted from PKCS15 emulation layer for IAS/ECC card. ++ * ++ * Copyright (C) 2020, Douglas E. Engert ++ * Copyright (C) 2016, Viktor Tarasov ++ * Copyright (C) 2004, Bud P. Bruegger ++ * Copyright (C) 2004, Antonino Iacono ++ * Copyright (C) 2003, Olaf Kirch ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ */ ++ ++#if HAVE_CONFIG_H ++#include "config.h" ++#endif ++ ++#include ++#include ++#include ++ ++#include "internal.h" ++#include "pkcs15.h" ++ ++ ++/* ++ * Called after sc_pkcs15_bind_internal ++ * Create new flags based on supported_algos. ++ */ ++static int cardos_fix_token_info(sc_pkcs15_card_t *p15card) ++{ ++ sc_card_t *card; ++ struct sc_supported_algo_info (*saa)[SC_MAX_SUPPORTED_ALGORITHMS]; ++ struct sc_supported_algo_info *sa; ++ struct sc_cardctl_cardos_pass_algo_flags *passed = NULL; ++ int r = 0; ++ int i; ++ ++ card = p15card->card; ++ ++ SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); ++ ++ passed = calloc(1, sizeof(struct sc_cardctl_cardos_pass_algo_flags)); ++ if (!passed) ++ LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_ENOUGH_MEMORY); ++ ++ passed->pass = 1; /* get used_flags and card_flags from card */ ++ r = sc_card_ctl(p15card->card, SC_CARDCTL_CARDOS_PASS_ALGO_FLAGS, passed); ++ if (r < 0) { ++ free(passed); ++ LOG_FUNC_RETURN(card->ctx, r); ++ } ++ ++ saa = &(p15card->tokeninfo->supported_algos); ++ ++ sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Original Flags: 0x%8.8lx card->flags:0x%8.8lx", passed->used_flags, passed->card_flags); ++ ++ if (passed->card_flags) { /* user forced the flags, use them */ ++ passed->new_flags = passed->card_flags; /* from card_atr flags */ ++ } else { ++ ++ for (i = 0, sa = saa[0]; i < SC_MAX_SUPPORTED_ALGORITHMS; i++, sa++) { ++ ++ if (sa->reference == 0 && sa->reference == 0 && sa->mechanism == 0 ++ && sa->operations == 0 && sa->algo_ref == 0) ++ break; ++ ++ sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "supported_algos[%d] mechamism:0x%8.8x", i, sa->mechanism); ++ switch(sa->mechanism) { ++ case 0x01 : ++ /* ++ * Card appears to use lower 4 bits of reference as key, and upper ++ * 4 bits as mech for card. ++ * Also has a bug if mechanism = 1 (CKM_RSA_PKCS1) and reference 0x10 ++ * bit is set mechanism should be 3 (CKM_RSA_X_509) ++ * correct the mechanism in tokenInfo ++ */ ++ if (sa->reference & 0x10) { ++ sc_log(card->ctx, "Changeing mechanism to CKM_RSA_X_509 based on reference"); ++ passed->new_flags |= SC_ALGORITHM_RSA_RAW ++ | SC_ALGORITHM_RSA_PAD_NONE; ++ sa->mechanism = 0x03; ++ } else ++ passed->new_flags |= SC_ALGORITHM_RSA_PAD_PKCS1; ++ break; ++ case 0x03 : ++ passed->new_flags |= SC_ALGORITHM_RSA_RAW ++ | SC_ALGORITHM_RSA_PAD_NONE; ++ break; ++ case 0x06 : ++ passed->new_flags |= SC_ALGORITHM_RSA_HASH_SHA1; ++ break; ++ case 0x1041: ++ passed->ec_flags |= SC_ALGORITHM_ECDSA_RAW; ++ /* no old_ec_flags */ ++ /* TODO turn on sizes from ec curves OIDS */ ++ break; ++ default: ++ sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "UNKNOWN MECH: 0x%8.8x", sa->mechanism); ++ } ++ ++ sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "New_flags 0x%8.8lx New_ec_flags: 0x%8.8lx", ++ passed->new_flags, passed->ec_flags); ++ } ++ ++ if (passed->new_flags == 0) { ++ if (p15card->tokeninfo && p15card->tokeninfo->flags & SC_PKCS15_TOKEN_EID_COMPLIANT) { ++ sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "EID_COMPLIANT flag found"); ++ passed->new_flags = (passed->used_flags & ~SC_ALGORITHM_SPECIFIC_FLAGS) | SC_ALGORITHM_RSA_PAD_PKCS1; ++ } else ++ passed->new_flags = passed->used_flags; /* from default cardos_init */ ++ } ++ } ++ ++ sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL,"Final New_flags 0x%8.8lx New_ec_flags: 0x%8.8lx", passed->new_flags, passed->ec_flags); ++ ++ passed->pass = 2; /* tell card driver to use the new flags */ ++ r = sc_card_ctl(p15card->card, SC_CARDCTL_CARDOS_PASS_ALGO_FLAGS, passed); ++ ++ free(passed); ++ LOG_FUNC_RETURN(card->ctx, r); ++} ++ ++static int ++cardos_pkcs15emu_detect_card(sc_pkcs15_card_t *p15card) ++{ ++ if (p15card->card->type < SC_CARD_TYPE_CARDOS_BASE) ++ return SC_ERROR_WRONG_CARD; ++ ++ if (p15card->card->type >= SC_CARD_TYPE_CARDOS_BASE + 1000) ++ return SC_ERROR_WRONG_CARD; ++ ++ return SC_SUCCESS; ++} ++ ++ ++static int ++sc_pkcs15emu_cardos_init(struct sc_pkcs15_card *p15card, struct sc_aid *aid) ++{ ++ sc_card_t *card = p15card->card; ++ int r; ++ ++ LOG_FUNC_CALLED(card->ctx); ++ ++ r = sc_pkcs15_bind_internal(p15card, aid); ++ LOG_TEST_RET(card->ctx, r, "sc_pkcs15_bind_internal failed"); ++ ++ /* If card has created algorithms, return */ ++ sc_log(card->ctx, " card->algorithms:%p card->algorithm_count:%d", card->algorithms, card->algorithm_count); ++ if (!card->algorithms && card->algorithm_count == 0) { ++ r = cardos_fix_token_info(p15card); ++ } ++ ++ LOG_FUNC_RETURN(card->ctx, r); ++} ++ ++ ++int ++sc_pkcs15emu_cardos_init_ex(struct sc_pkcs15_card *p15card, struct sc_aid *aid) ++{ ++ if (cardos_pkcs15emu_detect_card(p15card)) ++ return SC_ERROR_WRONG_CARD; ++ ++ return sc_pkcs15emu_cardos_init(p15card, aid); ++} +diff --git a/src/libopensc/pkcs15-syn.c b/src/libopensc/pkcs15-syn.c +index aba6f52c0e..ecd06b13c6 100644 +--- a/src/libopensc/pkcs15-syn.c ++++ b/src/libopensc/pkcs15-syn.c +@@ -60,6 +60,7 @@ struct sc_pkcs15_emulator_handler builtin_emulators[] = { + { "coolkey", sc_pkcs15emu_coolkey_init_ex }, + { "din66291", sc_pkcs15emu_din_66291_init_ex }, + { "esteid2018", sc_pkcs15emu_esteid2018_init_ex }, ++ { "cardos", sc_pkcs15emu_cardos_init_ex }, + + { NULL, NULL } + }; +@@ -95,6 +96,8 @@ int sc_pkcs15_is_emulation_only(sc_card_t *card) + case SC_CARD_TYPE_PIV_II_NEO: + case SC_CARD_TYPE_PIV_II_YUBIKEY4: + case SC_CARD_TYPE_ESTEID_2018: ++ case SC_CARD_TYPE_CARDOS_V5_0: ++ case SC_CARD_TYPE_CARDOS_V5_3: + + return 1; + default: +diff --git a/src/libopensc/pkcs15-syn.h b/src/libopensc/pkcs15-syn.h +index ccaf693ca4..a15e0d95cf 100644 +--- a/src/libopensc/pkcs15-syn.h ++++ b/src/libopensc/pkcs15-syn.h +@@ -54,6 +54,7 @@ int sc_pkcs15emu_jpki_init_ex(sc_pkcs15_card_t *, struct sc_aid *); + int sc_pkcs15emu_jpki_init_ex(sc_pkcs15_card_t *, struct sc_aid *); + int sc_pkcs15emu_coolkey_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *); + int sc_pkcs15emu_din_66291_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *); ++int sc_pkcs15emu_cardos_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *); + + struct sc_pkcs15_emulator_handler { + const char *name; + diff --git a/opensc-0.20.0-lto-build.patch b/opensc-0.20.0-lto-build.patch new file mode 100644 index 0000000..5028307 --- /dev/null +++ b/opensc-0.20.0-lto-build.patch @@ -0,0 +1,24 @@ +From 8551e84d74af24638581a473775b71e6aad10dcf Mon Sep 17 00:00:00 2001 +From: Frank Morgner +Date: Wed, 4 Mar 2020 23:09:57 +0100 +Subject: [PATCH] fixed https://github.com/OpenSC/OpenSC/issues/1948 + +closes https://github.com/OpenSC/OpenSC/pull/1958 +--- + src/tests/p11test/p11test_case_pss_oaep.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/tests/p11test/p11test_case_pss_oaep.c b/src/tests/p11test/p11test_case_pss_oaep.c +index 0194711924..b114b73658 100644 +--- a/src/tests/p11test/p11test_case_pss_oaep.c ++++ b/src/tests/p11test/p11test_case_pss_oaep.c +@@ -376,7 +376,7 @@ int oaep_encrypt_decrypt_test(test_cert_t *o, token_info_t *info, test_mech_t *m + CK_BYTE *dec_message = NULL; + int dec_message_length = 0; + int message_length = 16; +- unsigned char *enc_message; ++ unsigned char *enc_message = NULL; + int enc_message_length, rv; + + if (o->private_handle == CK_INVALID_HANDLE) { + diff --git a/opensc-0.20.0-no-common.patch b/opensc-0.20.0-no-common.patch new file mode 100644 index 0000000..4c4444c --- /dev/null +++ b/opensc-0.20.0-no-common.patch @@ -0,0 +1,27 @@ +diff --git a/src/tests/p11test/p11test.c b/src/tests/p11test/p11test.c +index feecf6fb..a16282cb 100644 +--- a/src/tests/p11test/p11test.c ++++ b/src/tests/p11test/p11test.c +@@ -34,6 +34,9 @@ + + #define DEFAULT_P11LIB "../../pkcs11/.libs/opensc-pkcs11.so" + ++/* Global variable keeping information about token we are using */ ++token_info_t token; ++ + void display_usage() { + fprintf(stdout, + " Usage:\n" +diff --git a/src/tests/p11test/p11test_common.h b/src/tests/p11test/p11test_common.h +index 2f3b238d..9eb5cede 100644 +--- a/src/tests/p11test/p11test_common.h ++++ b/src/tests/p11test/p11test_common.h +@@ -84,7 +84,7 @@ typedef struct { + size_t num_keygen_mechs; + } token_info_t; + +-token_info_t token; ++extern token_info_t token; + + #endif /* P11TEST_COMMON_H */ + diff --git a/opensc.module b/opensc.module new file mode 100644 index 0000000..2071097 --- /dev/null +++ b/opensc.module @@ -0,0 +1,8 @@ +# This file describes how to load the opensc module +# See: http://p11-glue.freedesktop.org/doc/p11-kit/config.html + +# This is a relative path, which means it will be loaded from +# the p11-kit default path which is usually $(libdir)/pkcs11. +# Doing it this way allows for packagers to package opensc for +# 32-bit and 64-bit and make them parallel installable +module: opensc-pkcs11.so diff --git a/opensc.spec b/opensc.spec new file mode 100644 index 0000000..4328a7f --- /dev/null +++ b/opensc.spec @@ -0,0 +1,706 @@ +%define opensc_module "OpenSC PKCS #11 Module" +%define nssdb %{_sysconfdir}/pki/nssdb + +Name: opensc +Version: 0.20.0 +Release: 8%{?dist} +Summary: Smart card library and applications + +License: LGPLv2+ +URL: https://github.com/OpenSC/OpenSC/wiki +Source0: https://github.com/OpenSC/OpenSC/releases/download/%{version}/%{name}-%{version}.tar.gz +Source1: opensc.module +# Missing from release tarball +# https://github.com/OpenSC/OpenSC/blob/master/tests/common.sh +Source2: common.sh +Patch1: opensc-0.19.0-pinpad.patch +Patch2: opensc-0.20.0-no-common.patch +# https://github.com/OpenSC/OpenSC/pull/1987 +Patch3: opensc-0.20.0-cardos.patch +# https://github.com/OpenSC/OpenSC/commit/8551e84d +Patch4: opensc-0.20.0-lto-build.patch + +BuildRequires: pcsc-lite-devel +BuildRequires: readline-devel +BuildRequires: openssl-devel +BuildRequires: /usr/bin/xsltproc +BuildRequires: docbook-style-xsl +BuildRequires: autoconf automake libtool gcc +BuildRequires: bash-completion +BuildRequires: zlib-devel +# For tests +BuildRequires: libcmocka-devel +%if ! 0%{?rhel} +BuildRequires: softhsm +%endif +BuildRequires: openssl +Requires: pcsc-lite-libs%{?_isa} +Requires: pcsc-lite +Obsoletes: mozilla-opensc-signer < 0.12.0 +Obsoletes: opensc-devel < 0.12.0 +Obsoletes: coolkey <= 1.1.0-36 +# The simclist is bundled in upstream +Provides: bundled(simclist) = 1.5 + +%description +OpenSC provides a set of libraries and utilities to work with smart cards. Its +main focus is on cards that support cryptographic operations, and facilitate +their use in security applications such as authentication, mail encryption and +digital signatures. OpenSC implements the PKCS#11 API so applications +supporting this API (such as Mozilla Firefox and Thunderbird) can use it. On +the card OpenSC implements the PKCS#15 standard and aims to be compatible with +every software/card that does so, too. + + +%prep +%setup -q +%patch1 -p1 -b .pinpad +%patch2 -p1 -b .no-common +%patch3 -p1 -b .cardos +%patch4 -p1 -b .lto-build + +cp %{SOURCE2} tests/ +# The test-pkcs11-tool-allowed-mechanisms already works in Fedora +sed -i -e '/XFAIL_TESTS/,$ { + s/XFAIL_TESTS.*/XFAIL_TESTS=test-pkcs11-tool-test.sh/ + q +}' tests/Makefile.am + +cp -p src/pkcs15init/README ./README.pkcs15init +cp -p src/scconf/README.scconf . +# No {_libdir} here to avoid multilib conflicts; it's just an example +sed -i -e 's|/usr/local/towitoko/lib/|/usr/lib/ctapi/|' etc/opensc.conf.example.in + + +%build +autoreconf -fvi +%ifarch %{ix86} +sed -i -e 's/opensc.conf/opensc-%{_arch}.conf/g' src/libopensc/Makefile.in +%endif +sed -i -e 's|"/lib /usr/lib\b|"/%{_lib} %{_libdir}|' configure # lib64 rpaths +%configure --disable-static \ + --disable-autostart-items \ + --disable-notify \ + --disable-assert \ + --enable-pcsc \ + --enable-cmocka \ + --enable-sm \ + --with-pcsc-provider=libpcsclite.so.1 +%make_build + + +%check +make check + + +%install +%make_install +install -Dpm 644 %{SOURCE1} $RPM_BUILD_ROOT%{_datadir}/p11-kit/modules/opensc.module + +%ifarch %{ix86} +# To avoid multilib issues, move these files on 32b intel architectures +rm -f $RPM_BUILD_ROOT%{_sysconfdir}/opensc.conf +install -Dpm 644 etc/opensc.conf $RPM_BUILD_ROOT%{_sysconfdir}/opensc-%{_arch}.conf +rm -f $RPM_BUILD_ROOT%{_mandir}/man5/opensc.conf.5 +install -Dpm 644 doc/files/opensc.conf.5 $RPM_BUILD_ROOT%{_mandir}/man5/opensc-%{_arch}.conf.5 +# use NEWS file timestamp as reference for configuration file +touch -r NEWS $RPM_BUILD_ROOT%{_sysconfdir}/opensc-%{_arch}.conf +touch -r NEWS $RPM_BUILD_ROOT%{_mandir}/man5/opensc-%{_arch}.conf.5 +%else +# For backward compatibility, symlink the old location to the new files +ln -s %{_sysconfdir}/opensc.conf $RPM_BUILD_ROOT%{_sysconfdir}/opensc-%{_arch}.conf +%endif + +find $RPM_BUILD_ROOT%{_libdir} -type f -name "*.la" | xargs rm + +rm -rf $RPM_BUILD_ROOT%{_datadir}/doc/opensc + +# Upstream considers libopensc API internal and no longer ships +# public headers and pkgconfig files. +# Remove the symlink as nothing is supposed to link against libopensc. +rm -f $RPM_BUILD_ROOT%{_libdir}/libopensc.so +# remove the .pc file so we do not confuse users #1673139 +rm -f $RPM_BUILD_ROOT%{_libdir}/pkgconfig/*.pc +rm -f $RPM_BUILD_ROOT%{_libdir}/libsmm-local.so +%if 0%{?rhel} && 0%{?rhel} < 7 +rm -rf %{buildroot}%{_datadir}/bash-completion/ +%endif + +# the npa-tool builds to nothing since we do not have OpenPACE library +rm -rf %{buildroot}%{_bindir}/npa-tool +rm -rf %{buildroot}%{_mandir}/man1/npa-tool.1* + +# Remove the notification files +rm %{buildroot}%{_bindir}/opensc-notify +rm %{buildroot}%{_datadir}/applications/org.opensc.notify.desktop +rm %{buildroot}%{_mandir}/man1/opensc-notify.1* + + +%files +%doc COPYING NEWS README* + +%if ! 0%{?rhel} || 0%{?rhel} >= 7 +%{_datadir}/bash-completion/* +%endif + +%ifarch %{ix86} +%{_mandir}/man5/opensc-%{_arch}.conf.5* +%else +%config(noreplace) %{_sysconfdir}/opensc.conf +%{_mandir}/man5/opensc.conf.5* +%endif + +%config(noreplace) %{_sysconfdir}/opensc-%{_arch}.conf +# Co-owned with p11-kit so it is not hard dependency +%dir %{_datadir}/p11-kit +%dir %{_datadir}/p11-kit/modules +%{_datadir}/p11-kit/modules/opensc.module +%{_bindir}/cardos-tool +%{_bindir}/cryptoflex-tool +%{_bindir}/eidenv +%{_bindir}/iasecc-tool +%{_bindir}/gids-tool +%{_bindir}/netkey-tool +%{_bindir}/openpgp-tool +%{_bindir}/opensc-explorer +%{_bindir}/opensc-tool +%{_bindir}/opensc-asn1 +%{_bindir}/piv-tool +%{_bindir}/pkcs11-tool +%{_bindir}/pkcs15-crypt +%{_bindir}/pkcs15-init +%{_bindir}/pkcs15-tool +%{_bindir}/sc-hsm-tool +%{_bindir}/dnie-tool +%{_bindir}/westcos-tool +%{_bindir}/egk-tool +%{_bindir}/goid-tool +%{_bindir}/pkcs11-register +%{_libdir}/lib*.so.* +%{_libdir}/opensc-pkcs11.so +%{_libdir}/pkcs11-spy.so +%{_libdir}/onepin-opensc-pkcs11.so +%%dir %{_libdir}/pkcs11 +%{_libdir}/pkcs11/opensc-pkcs11.so +%{_libdir}/pkcs11/onepin-opensc-pkcs11.so +%{_libdir}/pkcs11/pkcs11-spy.so +%{_datadir}/opensc/ +%{_mandir}/man1/cardos-tool.1* +%{_mandir}/man1/cryptoflex-tool.1* +%{_mandir}/man1/eidenv.1* +%{_mandir}/man1/gids-tool.1* +%{_mandir}/man1/iasecc-tool.1* +%{_mandir}/man1/netkey-tool.1* +%{_mandir}/man1/openpgp-tool.1* +%{_mandir}/man1/opensc-explorer.* +%{_mandir}/man1/opensc-tool.1* +%{_mandir}/man1/opensc-asn1.1* +%{_mandir}/man1/piv-tool.1* +%{_mandir}/man1/pkcs11-tool.1* +%{_mandir}/man1/pkcs15-crypt.1* +%{_mandir}/man1/pkcs15-init.1* +%{_mandir}/man1/pkcs15-tool.1* +%{_mandir}/man1/sc-hsm-tool.1* +%{_mandir}/man1/westcos-tool.1* +%{_mandir}/man1/dnie-tool.1* +%{_mandir}/man1/egk-tool.1* +%{_mandir}/man5/pkcs15-profile.5* + + +%changelog +* Wed Aug 19 2020 Igor Raits - 0.20.0-8 +- Drop useless ldconfig scriptlets + +* Tue Jul 28 2020 Fedora Release Engineering - 0.20.0-7 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild + +* Wed May 13 2020 Jakub Jelen - 0.20.0-6 +- Unbreak CardOS 5.x support (#1830528) + +* Mon Feb 10 2020 Jakub Jelen - 0.20.0-5 +- Unbreak build on gcc10 with -fno-common (#1799836) + +* Wed Jan 29 2020 Fedora Release Engineering - 0.20.0-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild + +* Fri Jan 10 2020 Jakub Jelen - 0.20.0-3 +- Drop the notification support for now + +* Fri Jan 10 2020 Jakub Jelen - 0.20.0-2 +- Cleanup spec file +- Split notify support to separate subpackage + +* Thu Jan 02 2020 Jakub Jelen - 0.20.0-1 +- New upstream release (#1749357) +- Fixes for various security issues identified by fuzzing (#1765223, #1765231, #1782520, #1782951, #1782956) + +* Mon Sep 30 2019 Jakub Jelen - 0.19.0-8 +- Correctly mention bundled simclist library +- Add missing zlib build requires (#1756326) + +* Thu Jul 25 2019 Fedora Release Engineering - 0.19.0-7 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild + +* Wed Mar 27 2019 Jakub Jelen - 0.19.0-6 +- Make OpenSC multilib again by moving the offending files on ix86 arch +- Do not ship packageconfig files to avoid inadvertent linking against pkcs11 modules (#1673139) + +* Sun Feb 17 2019 Igor Gnatenko - 0.19.0-5 +- Rebuild for readline 8.0 + +* Fri Feb 01 2019 Fedora Release Engineering - 0.19.0-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild + +* Wed Oct 31 2018 Jakub Jelen - 0.19.0-3 +- Unbreak the RSA-PSS mechanisms +- Unbreak the signing using hashed mechanisms in CardOS and others + +* Mon Oct 22 2018 Jakub Jelen - 0.19.0-2 +- Fix verification after implementing RSA-PSS mechanisms +- Disable pinpad by default + +* Tue Sep 25 2018 Jakub Jelen - 0.19.0-1 +- New upstream release fixing various CVE-2018-16418 - 16421, 16423 - 16427 +- Add support for RSA-PSS signatures + +* Fri Jul 13 2018 Fedora Release Engineering - 0.18.0-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild + +* Thu Jul 12 2018 Jakub Jelen - 0.18.0-3 +- Do not add pkcs11 module to NSS after installation + (NSS is loading p11-kit modules by default) +- Remove pkcs11-switch since there is nothing to switch to + +* Mon May 21 2018 Jakub Jelen - 0.18.0-2 +- Backport a fix for C_WaitForSlotEvent crash (#1579933) + +* Thu May 17 2018 Jakub Jelen - 0.18.0-1 +- New upstream release (#1567503) + +* Wed Apr 04 2018 Jakub Jelen - 0.17.0-10 +- Install the PKCS#11 modules also to the new NSS DB +- Drop the pkcs11-switch as the coolkey is gone + +* Tue Apr 03 2018 Jakub Jelen - 0.17.0-9 +- Improved support for CloudHSM (#1562572) + +* Mon Mar 19 2018 Jakub Jelen - 0.17.0-8 +- Build requires gcc +- Backport a fix for feitian tokens (#1558099) + +* Fri Mar 02 2018 Jakub Jelen - 0.17.0-7 +- Obsolete coolkey +- Do not report bogus errors from pkcs11-switch +- Do not delete nonexisting modules during uninstall (#1526670) + +* Wed Feb 21 2018 Jakub Jelen - 0.17.0-6 +- PIV: Use Cardholder name in the token label +- Avoid infinite loop when reading CAC cards +- Properly parse multi-byte length in SimpleTLV +- Support CAC Alt tokens + +* Thu Feb 08 2018 Fedora Release Engineering - 0.17.0-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild + +* Mon Dec 04 2017 Jakub Jelen - 0.17.0-4 +- Allow functionality of a new Estonia ID cards (#1519751) + +* Thu Aug 03 2017 Fedora Release Engineering - 0.17.0-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild + +* Thu Jul 27 2017 Fedora Release Engineering - 0.17.0-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild + +* Wed Jul 19 2017 Jakub Jelen - 0.17.0-1 +- New upstream release including support for Coolkey and CAC cards + +* Tue Feb 28 2017 Jakub Jelen - 0.16.0-5.20161016git0362439 +- Add PKCS#11 library to the NSS DB (#1421692) + +* Sat Feb 11 2017 Fedora Release Engineering - 0.16.0-4.20161016git0362439 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild + +* Thu Jan 12 2017 Igor Gnatenko - 0.16.0-3.20161016git0362439 +- Rebuild for readline 7.x + +* Mon Oct 31 2016 Jakub Jelen - 0.16.0-2.20161016git0362439 +- Updated to latest git to address openssl 1.1.0 compilation issues (#1388895) +- Do not own /etc/bash_completion.d directory (#1303441) + +* Tue Aug 02 2016 Jakub Jelen - 0.16.0-1 +- New upstream release 0.16.0 (#1306071) + +* Tue Jul 12 2016 Jakub Jelen - 0.15.0-6 +- Add support for 2048 key length (#1350588) +- Explicitly set CKA_PRIVATE to false when writing certificates (#1272127) + +* Thu Feb 04 2016 Fedora Release Engineering - 0.15.0-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild + +* Mon Jan 18 2016 Nikos Mavrogiannopoulos - 0.15.0-4 +- Fix a crash in accessing public key (#1298669) + +* Thu Nov 19 2015 Nikos Mavrogiannopoulos - 0.15.0-3 +- Export PKCS#11 symbols from spy library (#1283306) + +* Tue Aug 4 2015 Nikos Mavrogiannopoulos - 0.15.0-2 +- Updated fix for issue with C_Initialize after fork() (#1218797) + +* Tue Jul 14 2015 Nikos Mavrogiannopoulos - 0.15.0-1 +- Update to 0.15.0 (#1209682) +- Solve issue with C_Initialize after fork() (#1218797) + +* Thu Jun 18 2015 Fedora Release Engineering - 0.14.0-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild + +* Sun Aug 17 2014 Fedora Release Engineering - 0.14.0-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild + +* Tue Jul 01 2014 Nikos Mavrogiannopoulos - 0.14.0-1 +- new upstream version + +* Sat Jun 07 2014 Fedora Release Engineering - 0.13.0-13 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild + +* Fri Feb 28 2014 Nikos Mavrogiannopoulos - 0.13.0-12 +- Added fix for crash when calling pkcs11-tool with an invalid module (#1071368) +- Added fix for invalid parameters passed to module by pkcs11-tool + when importing a private key (#1071369) +- Configuration file opensc.conf was renamed to opensc-arch.conf to + avoid multi-arch issues. + +* Fri Jan 31 2014 Nikos Mavrogiannopoulos - 0.13.0-11 +- Corrected installation path of opensc.module (#1060053) + +* Mon Jan 06 2014 Nikos Mavrogiannopoulos - 0.13.0-10 +- Applied myeid related patch (#1048576) + +* Thu Jan 02 2014 Nikos Mavrogiannopoulos - 0.13.0-9 +- Applied epass2003 related patch (#981462) + +* Mon Dec 23 2013 Nikos Mavrogiannopoulos - 0.13.0-8 +- Compile using the --enable-sm option (related but does not fix #981462) + +* Wed Dec 18 2013 Nikos Mavrogiannopoulos - 0.13.0-7 +- Ensure that pcsc-lite is depended on (#1029133) + +* Mon Sep 23 2013 Stef Walter - 0.13.0-6 +- Install p11-kit config file to the right place (#999190) + +* Sat Aug 03 2013 Fedora Release Engineering - 0.13.0-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_20_Mass_Rebuild + +* Fri Mar 08 2013 Stef Walter - 0.13.0-4 +- Use the standard name format for p11-kit module configs +- Put the p11-kit module config is the system location + +* Thu Feb 14 2013 Fedora Release Engineering - 0.13.0-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild + +* Sun Jan 13 2013 Kalev Lember - 0.13.0-2 +- Backport an upstream patch for fixing pkcs15 cert length calculation + +* Thu Jan 03 2013 Milan Broz - 0.13.0-1 +- Update to 0.13.0 (#890770) +- Remove no longer provided onepin-opensc-pkcs11.so. +- Add iasecc-tool, openpgp-tool and sc-hsm-tool. + +* Fri Jul 27 2012 Tomas Mraz - 0.12.2-6 +- Add a configuration file for p11-kit (#840504) + +* Fri Jul 20 2012 Fedora Release Engineering - 0.12.2-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild + +* Sun Mar 4 2012 Peter Robinson - 0.12.2-4 +- Add patch for dso + +* Fri Jan 13 2012 Fedora Release Engineering - 0.12.2-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild + +* Wed Aug 17 2011 Tomas Mraz - 0.12.2-2 +- Rebuilt to fix trailing slashes in filelist from rpmbuild bug + +* Tue Jul 19 2011 Kalev Lember - 0.12.2-1 +- Update to 0.12.2 (#722659) + +* Wed May 18 2011 Kalev Lember - 0.12.1-1 +- Update to 0.12.1 (#705743) +- Removed BR libtool-ltdl-devel to build with glibc's libdl instead + +* Tue Apr 12 2011 Tomas Mraz - 0.12.0-4 +- drop multilib conflicting and duplicated doc file (#695368) + +* Tue Feb 08 2011 Fedora Release Engineering - 0.12.0-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild + +* Mon Jan 03 2011 Kalev Lember - 0.12.0-2 +- Disabled asserts + +* Mon Jan 03 2011 Kalev Lember - 0.12.0-1 +- Update to 0.12.0 +- Removed and obsoleted mozilla-opensc-signer and opensc-devel subpackages +- Dropped patches which are now upstreamed +- It is no longer possible to build in both pcsc-lite and openct support, + so opensc now gets built exclusively with pcsc-lite. + +* Tue Dec 21 2010 Tomas Mraz - 0.11.13-6 +- fix buffer overflow on rogue card serial numbers + +* Tue Oct 19 2010 Tomas Mraz - 0.11.13-5 +- own the _libdir/pkcs11 subdirectory (#644527) + +* Tue Sep 7 2010 Tomas Mraz - 0.11.13-4 +- fix build with new pcsc-lite + +* Wed Aug 11 2010 Rex Dieter - 0.11.13-3 +- build against libassuan1 (f14+) + +* Wed Jun 9 2010 Tomas Mraz - 0.11.13-2 +- replace file dependency (#601943) + +* Tue Feb 16 2010 Kalev Lember - 0.11.13-1 +- new upstream version + +* Sun Feb 14 2010 Kalev Lember - 0.11.12-2 +- Added patch to fix linking with the new --no-add-needed default (#564758) + +* Mon Dec 21 2009 Kalev Lember - 0.11.12-1 +- new upstream version +- replaced %%define with %%global +- BR clean up from items not applicable to current Fedora releases + +* Tue Dec 8 2009 Michael Schwendt - 0.11.11-2 +- Explicitly BR libassuan-static in accordance with the Packaging + Guidelines (libassuan-devel is still static-only). + +* Thu Nov 19 2009 Tomas Mraz - 0.11.11-1 +- new upstream version + +* Tue Sep 29 2009 Tomas Mraz - 0.11.9-2 +- fix multilib conflict in the configuration file (#526269) + +* Wed Sep 09 2009 Tomas Mraz - 0.11.9-1 +- new upstream version + +* Fri Aug 21 2009 Tomas Mraz - 0.11.8-5 +- rebuilt with new openssl + +* Mon Jul 27 2009 Tomas Mraz - 0.11.8-4 +- Depend on specific arch of pcsc-lite-libs (reported by Kalev Lember) + +* Sat Jul 25 2009 Fedora Release Engineering - 0.11.8-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild + +* Mon Jun 15 2009 Tomas Mraz - 0.11.8-2 +- Rebuilt with new openct + +* Mon May 11 2009 Tomas Mraz - 0.11.8-1 +- new upstream version - fixes security issue + +* Fri Feb 27 2009 Tomas Mraz - 0.11.7-1 +- new upstream version - fixes CVE-2009-0368 + +* Thu Feb 26 2009 Fedora Release Engineering - 0.11.6-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild + +* Thu Jan 15 2009 Tomas Mraz - 0.11.6-2 +- Add explicit requires for pcsc-lite-libs. Dlopen libpcsclite with the full + soname. + +* Tue Sep 2 2008 Tomas Mraz - 0.11.6-1 +- Update to latest upstream, fixes CVE-2008-2235 + +* Thu Apr 10 2008 Hans de Goede - 0.11.4-5 +- BuildRequire libassuan-devel instead of libassuan-static (bz 441812) + +* Tue Feb 19 2008 Fedora Release Engineering - 0.11.4-4 +- Autorebuild for GCC 4.3 + +* Wed Dec 05 2007 Release Engineering - 0.11.4-3 +- Rebuild for deps + +* Wed Dec 5 2007 Ville Skyttä - 0.11.4-2 +- Rebuild. + +* Mon Sep 10 2007 Ville Skyttä - 0.11.4-1 +- 0.11.4. + +* Mon Aug 20 2007 Ville Skyttä - 0.11.4-0.1.rc1 +- 0.11.4-rc1, pkcs11-tool usage message fix applied upstream. +- License: LGPLv2+ + +* Thu Jul 26 2007 Ville Skyttä - 0.11.3-2 +- Fix pkcs11-tool usage message crash (#249702). + +* Tue Jul 17 2007 Ville Skyttä - 0.11.3-1 +- 0.11.3. + +* Sat Jun 30 2007 Ville Skyttä - 0.11.3-0.1.pre2 +- 0.11.3-pre2. + +* Thu Jun 21 2007 Ville Skyttä - 0.11.3-0.1.pre1 +- 0.11.3-pre1. + +* Sun May 6 2007 Ville Skyttä - 0.11.2-2 +- Add explicit build dependency on ncurses-devel. + +* Sat May 5 2007 Ville Skyttä - 0.11.2-1 +- 0.11.2. + +* Tue Apr 24 2007 Ville Skyttä - 0.11.2-0.3.rc2 +- 0.11.2-rc2. + +* Fri Mar 23 2007 Ville Skyttä - 0.11.2-0.3.rc1 +- 0.11.2-rc1. + +* Thu Mar 15 2007 Ville Skyttä - 0.11.2-0.2.pre6 +- 0.11.2-pre6. + +* Tue Mar 6 2007 Ville Skyttä - 0.11.2-0.2.pre4 +- 0.11.2-pre4. +- Require pinentry-gui instead of the pinentry executable in signer. + +* Sun Dec 3 2006 Ville Skyttä - 0.11.2-0.1.pre3 +- 0.11.2-pre3. +- Build with new libassuan. +- Don't run autotools during build. +- Adjust to readline/termcap/ncurses changes. + +* Sat Oct 14 2006 Ville Skyttä - 0.11.1-6 +- Rebuild with new libassuan. + +* Sun Oct 8 2006 Ville Skyttä - 0.11.1-5 +- Rebuild with new libassuan. + +* Mon Oct 2 2006 Ville Skyttä - 0.11.1-4 +- Rebuild. + +* Tue Sep 26 2006 Ville Skyttä - 0.11.1-3 +- Rebuild with new libassuan. + +* Sat Sep 2 2006 Ville Skyttä - 0.11.1-2 +- Rebuild. + +* Wed May 31 2006 Ville Skyttä - 0.11.1-1 +- 0.11.1. +- Avoid some multilib conflicts. + +* Sun May 7 2006 Ville Skyttä - 0.11.0-2 +- Sync example paths in openct.conf with ctapi-common. +- Update URL. + +* Thu May 4 2006 Ville Skyttä - 0.11.0-1 +- 0.11.0. + +* Thu Apr 27 2006 Ville Skyttä - 0.11.0-0.1.rc2 +- 0.11.0-rc2. + +* Sat Apr 22 2006 Ville Skyttä - 0.11.0-0.1.rc1 +- 0.11.0-rc1. + +* Mon Mar 6 2006 Ville Skyttä - 0.10.1-3 +- Rebuild. + +* Wed Feb 15 2006 Ville Skyttä - 0.10.1-2 +- Avoid standard rpaths on lib64 archs. + +* Sun Jan 8 2006 Ville Skyttä - 0.10.1-1 +- 0.10.1. + +* Wed Nov 9 2005 Ville Skyttä - 0.10.0-1 +- 0.10.0. +- Adapt to modularized X.Org. + +* Wed Oct 26 2005 Ville Skyttä - 0.10.0-0.1.rc2 +- 0.10.0-rc2. +- Install signer plugin only to plugin dir. + +* Sat Oct 22 2005 Ville Skyttä - 0.10.0-0.1.rc1 +- 0.10.0-rc1. + +* Wed Oct 19 2005 Ville Skyttä - 0.10.0-0.1.beta2.rc1 +- 0.10.0-beta2-rc1. +- Specfile cleanups. + +* Tue Apr 26 2005 Ville Skyttä - 0.9.6-2 +- 0.9.6, build patch applied upstream. +- Package summary and description improvements. +- Drop explicit openct dependency. + +* Fri Mar 18 2005 Ville Skyttä - 0.9.4-3 +- Fix FC4 build. +- Rename opensc-pam to pam_opensc per package naming guidelines. + +* Wed Feb 9 2005 Michael Schwendt - 0.9.4-2 +- Substitute hardcoded 'lib' in OpenSSL checks for multi-lib platforms. +- Use --with-plugin-dir instead of --with-plugin-path (fixes x86_64). + +* Thu Feb 3 2005 Ville Skyttä - 0.9.4-1 +- Drop unnecessary Epochs, pre-FC1 compat cruft, and no longer relevant + --with(out) rpmbuild options. +- Exclude *.la. + +* Wed Nov 3 2004 Ville Skyttä - 0:0.9.4-0.fdr.1 +- Update to 0.9.4, parallel build patch applied upstream. +- Patch to fix library paths and LDFLAGS. +- Don't require mozilla, but the plugin dir in signer. +- Build with dependency tracking disabled. + +* Tue Jul 27 2004 Ville Skyttä - 0:0.9.2-0.fdr.2 +- Building the signer plugin can be disabled with "--without signer". + Thanks to Fritz Elfert for the idea. +- Update description. + +* Sun Jul 25 2004 Ville Skyttä - 0:0.9.2-0.fdr.1 +- Update to 0.9.2, old patches applied upstream. +- Add patch to fix parallel builds. +- Convert man pages to UTF-8. + +* Thu Jul 22 2004 Ville Skyttä - 0:0.9.1-0.fdr.1 +- Update to 0.9.1 (preview). + +* Thu Jul 1 2004 Ville Skyttä - 0:0.9.0-0.fdr.0.1.alpha +- Update to 0.9.0-alpha. + +* Sat May 1 2004 Ville Skyttä - 0:0.8.1-0.fdr.8 +- Rebuild with libassuan 0.6.5. + +* Sat Jan 31 2004 Ville Skyttä - 0:0.8.1-0.fdr.7 +- Rebuild with libassuan 0.6.3. +- Add gdm example to PAM quickstart. + +* Mon Jan 19 2004 Ville Skyttä - 0:0.8.1-0.fdr.6 +- Use /%%{_lib} instead of hardcoding /lib. + +* Sat Dec 20 2003 Ville Skyttä - 0:0.8.1-0.fdr.5 +- Split PAM support into a subpackage. +- Rebuild with libassuan 0.6.2. + +* Sun Nov 23 2003 Ville Skyttä - 0:0.8.1-0.fdr.4 +- Rebuild with libassuan 0.6.1. +- Include PAM quickstart doc snippet. + +* Fri Nov 14 2003 Ville Skyttä - 0:0.8.1-0.fdr.3 +- Require OpenCT. + +* Fri Oct 17 2003 Ville Skyttä - 0:0.8.1-0.fdr.2 +- Install example config files as documentation. + +* Tue Oct 14 2003 Ville Skyttä - 0:0.8.1-0.fdr.1 +- Update to 0.8.1. + +* Wed Aug 27 2003 Ville Skyttä - 0:0.8.0-0.fdr.2 +- Signer can be built with oldssl too. + +* Wed Aug 27 2003 Ville Skyttä - 0:0.8.0-0.fdr.1 +- Update to 0.8.0. + +* Wed Jul 30 2003 Ville Skyttä - 0:0.8.0-0.fdr.0.2.cvs20030730 +- Update to 20030730. +- Clean up %%docs. +- Include *.la (uses ltdl). +- Own the %%{_libdir}/pkcs11 directory. +- Disable signer; assuan has disappeared from the tarball :( + +* Fri May 23 2003 Ville Skyttä - 0:0.8.0-0.fdr.0.1.rc1 +- First build. diff --git a/sources b/sources new file mode 100644 index 0000000..ac12c19 --- /dev/null +++ b/sources @@ -0,0 +1 @@ +SHA512 (opensc-0.20.0.tar.gz) = 71f71fa6062410e63c6c60f5b2d10d1d855cc6cc815ef0e42e42a1ddd25bbd52fc396c1e495ef54610f3243996dec84dacc8007b186deb670ed645b04ee6eda5 diff --git a/tests/pkcs11-tool/Makefile b/tests/pkcs11-tool/Makefile new file mode 100644 index 0000000..e36742f --- /dev/null +++ b/tests/pkcs11-tool/Makefile @@ -0,0 +1,66 @@ +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# Makefile of /CoreOS/opensc/Sanity/pkcs11-tool +# Description: This is a sanity test for pkcs11-tool +# Author: Jakub Jelen +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# Copyright (c) 2018 Red Hat, Inc. +# +# This program is free software: you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation, either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied +# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +# PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see http://www.gnu.org/licenses/. +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +export TEST=/CoreOS/opensc/Sanity/pkcs11-tool +export TESTVERSION=1.0 + +BUILT_FILES= + +FILES=$(METADATA) runtest.sh Makefile PURPOSE cert.cfg virtcacard.cil + +.PHONY: all install download clean + +run: $(FILES) build + ./runtest.sh + +build: $(BUILT_FILES) + test -x runtest.sh || chmod a+x runtest.sh + +clean: + rm -f *~ $(BUILT_FILES) + + +include /usr/share/rhts/lib/rhts-make.include + +$(METADATA): Makefile + @echo "Owner: Jakub Jelen " > $(METADATA) + @echo "Name: $(TEST)" >> $(METADATA) + @echo "TestVersion: $(TESTVERSION)" >> $(METADATA) + @echo "Path: $(TEST_DIR)" >> $(METADATA) + @echo "Description: This is a sanity test for pkcs11-tool" >> $(METADATA) + @echo "Type: Sanity" >> $(METADATA) + @echo "TestTime: 15m" >> $(METADATA) + @echo "RunFor: opensc" >> $(METADATA) + @echo "Requires: opensc openssl gnutls-utils libcacard" >> $(METADATA) + @echo "Requires: opencryptoki-libs opencryptoki opencryptoki-swtok" >> $(METADATA) + @echo "Requires: softhsm nss-tools policycoreutils" >> $(METADATA) + @echo "Priority: Normal" >> $(METADATA) + @echo "License: GPLv2+" >> $(METADATA) + @echo "Confidential: yes" >> $(METADATA) + @echo "Destructive: no" >> $(METADATA) + @echo "Releases: -RHEL4 -RHELClient5 -RHELServer5 -RHEL6" >> $(METADATA) + + rhts-lint $(METADATA) + diff --git a/tests/pkcs11-tool/PURPOSE b/tests/pkcs11-tool/PURPOSE new file mode 100644 index 0000000..0149f38 --- /dev/null +++ b/tests/pkcs11-tool/PURPOSE @@ -0,0 +1,3 @@ +PURPOSE of /CoreOS/opensc/Sanity/pkcs11-tool +Description: This is a sanity test for pkcs11-tool +Author: Jakub Jelen diff --git a/tests/pkcs11-tool/cert.cfg b/tests/pkcs11-tool/cert.cfg new file mode 100644 index 0000000..409aa93 --- /dev/null +++ b/tests/pkcs11-tool/cert.cfg @@ -0,0 +1,6 @@ +organization = "OpenSC" +expiration_days = 365 +email = "none@example.org" +signing_key +encryption_key + diff --git a/tests/pkcs11-tool/runtest.sh b/tests/pkcs11-tool/runtest.sh new file mode 100755 index 0000000..594fb2f --- /dev/null +++ b/tests/pkcs11-tool/runtest.sh @@ -0,0 +1,288 @@ +#!/bin/bash +# vim: dict+=/usr/share/beakerlib/dictionary.vim cpt=.,w,b,u,t,i,k +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# runtest.sh of /CoreOS/opensc/Sanity/pkcs11-tool +# Description: This is a sanity test for pkcs11-tool +# Author: Jakub Jelen +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# Copyright (c) 2018 Red Hat, Inc. +# +# This program is free software: you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation, either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied +# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +# PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see http://www.gnu.org/licenses/. +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +# Include Beaker environment +. /usr/share/beakerlib/beakerlib.sh || exit 1 + +PACKAGE="opensc" +## from OpenSC/src/tests/p11test/runtest.sh +SOPIN="12345678" +PIN="123456" +export GNUTLS_PIN=$PIN +GENERATE_KEYS=1 +PKCS11_TOOL="pkcs11-tool" +NSSDB=db + +function generate_cert() { + TYPE="$1" + ID="$2" + LABEL="$3" + + # 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 + + # 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" + + 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 + + p11tool --login --provider="$P11LIB" --list-all +} + +function card_setup() { + 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" + + # 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 and virt_cacard + rlRun "yes | dnf copr enable jjelen/vsmartcard" + rlRun "dnf install -y virt_cacard virtualsmartcard" + + # 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 "/usr/bin/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" + ;; + "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 "General setup" + rlAssertRpm $PACKAGE + rlPhaseEnd + + 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 + + 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" + + # 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 + + # Skip hashed algorithms (do not support encryption & decryption) + if [[ ! -z "$HASH" ]]; then + continue; + fi + 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}" + + # TODO pkcs11-tool encryption + rlPhaseEnd + done + done + + rlPhaseStartCleanup "Cleanup $BACKEND" + card_cleanup $BACKEND + rlRun "popd" + rlRun "rm -r $TmpDir" 0 "Removing tmp directory" + rlPhaseEnd + done +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 new file mode 100644 index 0000000..e1ee225 --- /dev/null +++ b/tests/tests.yml @@ -0,0 +1,29 @@ +--- +# Tests for docker container +- hosts: localhost + tags: + - container + # no compatible tests + +# Tests for classic environment and Atomic Host +- hosts: localhost + tags: + - all + - classic + - atomic + roles: + - role: standard-test-beakerlib + tests: + - pkcs11-tool + required_packages: + - softhsm # software PKCS#11 module + - openssl # openssl tools + - gnutls-utils # p11tool + - opencryptoki-libs # opencryptoki + - opencryptoki + - opencryptoki-swtok + - libcacard + - softhsm + - nss-tools # Handling NSS DB + - policycoreutils # Loading custom selinux modules +