Skip to content

Commit

Permalink
PKCS#11 testsuite (OpenSC#1224)
Browse files Browse the repository at this point in the history
* Initial version of pkcs11 testsuite

* Refactor test cases to several files, clean up awful and unused stuff

* Static mechanism list based on the actual token offer

* Get rid of magic numbers

* Documentation

* License update based on the original project

* Verbose readme

* Cleanup unused code, long lines and method order

* Typo; More verbose errors

* Use fallback mechanisms

* Refactor object allocation and certificate search

* PKCS11SPY mentioned, more TODO

* add SHA mechanisms

* Do not try to Finalize already finalized cryptoki

* Add more flags and mechanisms

* Do not list table for no results

* Logical order of the tests (regression last)

* read ALWAYS_AUTHENTICATE from correct place

* ALWAYS_AUTHENTICATE for decryption

* Test EC key length signature based on the actual key length

* Shorten CKM_ list output, add keygen types detection

* Skip decrypting on non-supported mechanisms

* Fail hard if the C_Login fails

* Reorganize local FLAGS_ constants

* Test RSA Digest mechanisms

* Correct mechanisms naming, typos

* Do not attempt to do signature using empty keys

* CKM_ECDSA_SHA1 support

* Correct type cast when getting attributes

* Report failures from all mechanisms

* Standardize return values, eliminate complete fails, documentation interface

* Wait for slot event test

* Add switch to allow interaction with a card (WaitForSlotEvent)

* At least try to verify using C_Verify, if it fails, fall back to openssl

* Get rid of function_pointers

* Get rid of additional newline

* Share always_authenticate() function between the test cases

* Refactor Encrypt&decrypt test to functions

* Do not overwrite bits if they are not provided by CKA, indentation

* Cleanup and Break to more functions Sign&Verify test

* CKM_RSA_X_509 sign and verify with openssl padding

* More TODO's

* Proper abstracted padding with RSA_X_509 mechanism

* Add ongoing tasks from different TODO list

* Update instructions. Another todo

* Variables naming

* Increase mechanism list size, use different static buffers for flags and mechanism names

* nonstandard mechanism CKM_SHA224_RSA_PKCS supported by some softotkens

* Get rid of loop initial declarations

* Loop initial declaration, typos, strict warnings

* Move the p11test to the new folder to avoid problems with dynamically linked opensc.so

* Update path in README

* Possibility to validate the testsuite agains software tokens

* Add possibility to select slot ID on command-line (when there are more cards present)

* Clean up readme to reflect current options and TODOs

* Do not attempt to use keys without advertised sign&verify bits to avoid false positives

* Get and present more object attributes in readonly test; refactor table

* New test checking if the set of attributes (usage flags) is reasonable

* Test multipart signatures. There is not reasonable mechanism supporting multipart encryption

* Use PKCS#11 encryption if possible (with openssl fallback)

* Identify few more mechanisms (PSS) in the lest

* Resize table to fit new mechanisms

* Remove initial loop declaration from multipart test

* Use pkcs11-tool instead of p11tool form most of the operations (master have most of the features)

* Preparation for machine readable results

* Refactor log variables out of the main context, try to export generic data

* Do not write to non-existing FD if not logging

* Export missing data into the log file in JSON

* Store database in json

* Sanity check

* Avoid uninitialized structure fields using in state structure

* Dump always_authenticate attribute too

* Manual selection of slots with possibility to use slots without tokens

* Do not free before finalizing

* Proper cleanup of message in all cases

* Proper allocation and deallocation of messages

* Sanitize missing cases (memory leaks)

* Suppressions for testing under valgrind

* Better handling message_lengt during sign&verify (avoid invalid access)

* Suppress another PCSC error

* Do not use default PIN. Fail if none specified

* Sanitize initialization. Skip incomplete key pairs

* Add missing newline in errors

* Fix condition for certificate search

* Avoid several calls for attributes of zero length

* Handle if the private key is not present on the card

* Improve memory handling, silent GCC warning of 'unused' variable

* Fail early with missing private key, cleanup the messages

* Use correct padding for encryption

* Cache if the card supports Verify/Encrypt and avoid trying over and over again

* Loosen the condition for the Usage flags

* OpenSSL 1.1.0 compatibility

* Add missing mechanisms

* Do not require certificates on the card and pass valid data for RSA_PKCS mechanisms

* Add missing PIN argument in runtest.sh

* Add OpenSSL < 1.1 comatible bits

* Add SHA2 ECDSA mechanisms handling

* Use public key from PKCS#11 if the certificate is missing (or compare it with certificate)

* Avoid long definitions in OpenSSL compat layer

* In older OpenSSL, the header file is ecdsa.h

* Add missing config.h to apply compat OpenSSL layer

* ASN1_STRING_get0_data() is also new in 1.1.0

* Return back RSA_X_509 mechanism

* Drop bogus CKM_* in the definitions

* Drop CKM_SHA224_RSA_PKCS as it is already in pkcs11.h

* Update documentation

* Use NDEBUG as intended

* typos, cleanup

* Typos, cleanup, update copyright

* Additional check for OpenCryptoki, generate more key types on soft tokens

* Prepare for RSA-PSS and RSA-OAEP

* Use usage&result flags for the tests, gracefully ignore PSS&OAEP

* pkcs11.h: Add missing definitions for PSS

* PSS and OAEP tests

readonly: Typos, reformat

* Working version, memory leak

* Tweak message lengths for OAEP and PSS

* Skip tests that are not aplicable for tokens

* configure.ac: New switch --enable-tests

Do not attempt to build tests if cmocka is not available or
--enable-tests is provided. It makes also more lightweight release
builds out of the box (or with --disable-tests).

* travis: Install cmocka if not available

* Do not build tests on Windows and make dist pass

* Try to install cmocka from apt and from brew

* Do not require sudo (cmocka from apt and brew works)
  • Loading branch information
Jakuje authored and frankmorgner committed May 18, 2018
1 parent eb60481 commit 9858d05
Show file tree
Hide file tree
Showing 37 changed files with 4,126 additions and 9 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -128,5 +128,6 @@ src/tests/lottery
src/tests/p15dump
src/tests/pintest
src/tests/prngtest
src/tests/p11test/p11test

version.m4.ci
5 changes: 2 additions & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
language: c

sudo: false

addons:
apt_packages:
- binutils-mingw-w64-i686
Expand All @@ -15,6 +13,7 @@ addons:
- xsltproc
- gengetopt
- help2man
- libcmocka-dev

env:
global:
Expand Down Expand Up @@ -52,7 +51,7 @@ before_install:
brew update;
brew uninstall libtool;
brew install libtool;
brew install gengetopt help2man;
brew install gengetopt help2man cmocka;
fi

before_script:
Expand Down
30 changes: 30 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,13 @@ AC_ARG_ENABLE(
[enable_notify="detect"]
)

AC_ARG_ENABLE(
[tests],
[AS_HELP_STRING([--enable-tests],[Build tests in src/tests/ directory @<:@detect@:>@])],
,
[enable_tests="detect"]
)

AC_ARG_WITH(
[xsl-stylesheetsdir],
[AS_HELP_STRING([--with-xsl-stylesheetsdir=PATH],[docbook xsl-stylesheets for svn build @<:@detect@:>@])],
Expand Down Expand Up @@ -511,6 +518,26 @@ if test "${enable_notify}" = "yes"; then
fi
fi

PKG_CHECK_MODULES( [CMOCKA], [cmocka],
[ have_cmocka="yes" ],
[ have_cmocka="no" ])

if test "${enable_tests}" = "detect"; then
if test "${have_cmocka}" = "yes"; then
enable_tests="yes"
else
enable_tests="no"
fi
fi

if test "${enable_tests}" = "yes"; then
if test "${have_cmocka}" = "yes"; then
AC_DEFINE([ENABLE_TESTS], [1], [Build tests in tests/ subdirectory])
else
AC_MSG_ERROR([Tests required, but cmocka is not available])
fi
fi

AC_ARG_VAR([ZLIB_CFLAGS], [C compiler flags for zlib])
AC_ARG_VAR([ZLIB_LIBS], [linker flags for zlib])
if test -z "${ZLIB_LIBS}"; then
Expand Down Expand Up @@ -997,6 +1024,7 @@ AM_CONDITIONAL([ENABLE_MINIDRIVER_SETUP_CUSTOMACTION], [test "${enable_minidrive
AM_CONDITIONAL([ENABLE_SM], [test "${enable_sm}" = "yes"])
AM_CONDITIONAL([ENABLE_DNIE_UI], [test "${enable_dnie_ui}" = "yes"])
AM_CONDITIONAL([ENABLE_NPATOOL], [test "${ENABLE_NPATOOL}" = "yes"])
AM_CONDITIONAL([ENABLE_TESTS], [test "${ENABLE_TESTS}" = "yes"])
AM_CONDITIONAL([GIT_CHECKOUT], [test "${GIT_CHECKOUT}" = "yes"])

if test "${enable_pedantic}" = "yes"; then
Expand Down Expand Up @@ -1025,6 +1053,7 @@ AC_CONFIG_FILES([
src/scconf/Makefile
src/tests/Makefile
src/tests/regression/Makefile
src/tests/p11test/Makefile
src/tools/Makefile
src/tools/versioninfo-tools.rc
src/tools/versioninfo-opensc-notify.rc
Expand Down Expand Up @@ -1082,6 +1111,7 @@ SM support: ${enable_sm}
SM default module: ${DEFAULT_SM_MODULE}
DNIe UI support: ${enable_dnie_ui}
Notification support: ${enable_notify}
Build tests: ${enable_tests}
Debug file: ${DEBUG_FILE}

PC/SC default provider: ${DEFAULT_PCSC_PROVIDER}
Expand Down
6 changes: 5 additions & 1 deletion src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,12 @@ EXTRA_DIST = Makefile.mak

# Order IS important
SUBDIRS = common scconf ui pkcs15init sm \
libopensc pkcs11 tools tests minidriver
libopensc pkcs11 tools minidriver

if ENABLE_SM
SUBDIRS += smm
endif

if ENABLE_TESTS
SUBDIRS += tests
endif
6 changes: 5 additions & 1 deletion src/Makefile.mak
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
TOPDIR = ..

SUBDIRS = common scconf ui sm pkcs15init \
libopensc pkcs11 tools tests
libopensc pkcs11 tools

default: all

Expand All @@ -15,6 +15,10 @@ SUBDIRS = $(SUBDIRS) minidriver
SUBDIRS = $(SUBDIRS) smm
!ENDIF

!IF "$(TESTS_DEF)" == "/DENABLE_TESTS"
SUBDIRS = $(SUBDIRS) tests
!ENDIF

all clean::
@for %i in ( $(SUBDIRS) ) do \
@cmd /c "cd %i && $(MAKE) /nologo /f Makefile.mak $@"
24 changes: 24 additions & 0 deletions src/libopensc/sc-ossl-compat.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ extern "C" {
#define OPENSSL_malloc_init CRYPTO_malloc_init

#define EVP_PKEY_get0_RSA(x) (x->pkey.rsa)
#define EVP_PKEY_get0_EC_KEY(x) (x->pkey.ec)
#define EVP_PKEY_get0_DSA(x) (x->pkey.dsa)
#define X509_get_extension_flags(x) (x->ex_flags)
#define X509_get_key_usage(x) (x->ex_kusage)
Expand All @@ -103,6 +104,11 @@ extern "C" {
#endif
#endif

/* ASN1_STRING_data is deprecated in OpenSSL 1.1.0 */
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
#define ASN1_STRING_get0_data(x) ASN1_STRING_data(x)
#endif

/*
* OpenSSL-1.1.0-pre5 has hidden the RSA and DSA structures
* One can no longer use statements like rsa->n = ...
Expand Down Expand Up @@ -140,6 +146,9 @@ extern "C" {
#ifndef OPENSSL_NO_DSA
#include <openssl/dsa.h>
#endif
#ifndef OPENSSL_NO_EC
#include <openssl/ecdsa.h>
#endif

#ifndef OPENSSL_NO_RSA
static sc_ossl_inline int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d)
Expand Down Expand Up @@ -239,6 +248,21 @@ static sc_ossl_inline void DSA_get0_key(const DSA *d, const BIGNUM **pub_key, co
/* NOTE: DSA_set0_* functions not defined because they are not currently used in OpenSC */
#endif /* OPENSSL_NO_DSA */


#ifndef OPENSSL_NO_EC
static sc_ossl_inline int ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s)
{
if (r == NULL || s == NULL)
return 0;
BN_clear_free(sig->r);
BN_clear_free(sig->s);
sig->r = r;
sig->s = s;
return 1;
}
#endif /* OPENSSL_NO_EC */


#endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */

#ifdef __cplusplus
Expand Down
4 changes: 3 additions & 1 deletion src/pkcs11/pkcs11.h
Original file line number Diff line number Diff line change
Expand Up @@ -776,7 +776,7 @@ typedef struct CK_RSA_PKCS_OAEP_PARAMS {

typedef struct CK_RSA_PKCS_PSS_PARAMS {
ck_mechanism_type_t hashAlg;
unsigned long mgf;
CK_RSA_PKCS_MGF_TYPE mgf;
unsigned long sLen;
} CK_RSA_PKCS_PSS_PARAMS;

Expand All @@ -786,6 +786,8 @@ typedef struct CK_RSA_PKCS_PSS_PARAMS {
#define CKG_MGF1_SHA384 (0x00000003UL)
#define CKG_MGF1_SHA512 (0x00000004UL)

#define CKZ_DATA_SPECIFIED (0x00000001UL)

typedef unsigned long ck_rv_t;


Expand Down
2 changes: 1 addition & 1 deletion src/tests/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ include $(top_srcdir)/win32/ltrc.inc
MAINTAINERCLEANFILES = $(srcdir)/Makefile.in
EXTRA_DIST = Makefile.mak

SUBDIRS = regression
SUBDIRS = regression p11test
noinst_PROGRAMS = base64 lottery p15dump pintest prngtest

AM_CPPFLAGS = -I$(top_srcdir)/src
Expand Down
30 changes: 30 additions & 0 deletions src/tests/p11test/Makefile.am
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
include $(top_srcdir)/win32/ltrc.inc

MAINTAINERCLEANFILES = $(srcdir)/Makefile.in
EXTRA_DIST = Makefile.mak

noinst_PROGRAMS = p11test
noinst_HEADERS = p11test_loader.h p11test_case_common.h \
p11test_case_readonly.h p11test_case_multipart.h \
p11test_case_mechs.h p11test_case_ec_sign.h \
p11test_case_usage.h p11test_case_wait.h \
p11test_case_pss_oaep.h p11test_helpers.h

AM_CPPFLAGS = -I$(top_srcdir)/src

p11test_SOURCES = p11test.c p11test_loader.c \
p11test_case_common.c \
p11test_case_readonly.c \
p11test_case_multipart.c \
p11test_case_mechs.c \
p11test_case_ec_sign.c \
p11test_case_usage.c \
p11test_case_wait.c \
p11test_case_pss_oaep.c \
p11test_helpers.c
p11test_CFLAGS = -DNDEBUG
p11test_LDADD = -lssl -lcrypto -lcmocka

if WIN32
p11test_SOURCES += $(top_builddir)/win32/versioninfo.rc
endif
26 changes: 26 additions & 0 deletions src/tests/p11test/Makefile.mak
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
TOPDIR = ..\..\..

TARGETS = p11test.exe

OBJECTS = p11test_loader.obj \
p11test_case_common.obj \
p11test_case_readonly.obj \
p11test_case_multipart.obj \
p11test_case_mechs.obj \
p11test_case_ec_sign.obj \
p11test_case_usage.obj \
p11test_case_wait.obj \
p11test_case_pss_oaep.obj \
p11test_helpers.obj \
$(TOPDIR)\win32\versioninfo.res

all: $(TARGETS)

!INCLUDE $(TOPDIR)\win32\Make.rules.mak

$(TARGETS): $(OBJECTS) $(LIBS)

.c.exe:
cl $(COPTS) /c $<
link $(LINKFLAGS) /pdb:$*.pdb /out:$@ $*.obj $(OBJECTS) $(LIBS)
if EXIST $@.manifest mt -manifest $@.manifest -outputresource:$@;1
57 changes: 57 additions & 0 deletions src/tests/p11test/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# Non-destructive PKCS#11 test suite (not only for readonly cards)

## What are the dependencies?

In addition to the dependencies needed by OpenSC, the test suite is
using [`cmocka`](https://cmocka.org/) unit testing framework
(`libcmocka-devel` package in Fedora/EPEL).

## How to use?

Build OpenSC from source:

git clone git@github.com:Jakuje/OpenSC.git
cd OpenSC
git checkout jjelen-testsuite # not in master yet
./bootstrap
./configure
make -j4

Plug in the card/reader, change to test directory and run the test:

cd src/tests/p11test
./p11test -p 123456

It will run all tests on the first card found in PKCS#11 API
with pin `123456` and using just built OpenSC shared library from master.

### I have more slots with different cards.

Slot can be selected using `-s` switch on command-line.

./p11test -s 4

Slot numbers can be obtained using from `pkcs11-tool -L` (note that different
libraries might have different numbers for the slots).

### I want to test different pkcs11 library

You can specify different library or build from different branch
on command-line:

./p11test -m /usr/lib64/pkcs11/libcoolkeypk11.so

or to debug PKCS#11 calls using `/usr/lib64/pkcs11-spy.so`:

export PKCS11SPY="../pkcs11/.libs/opensc-pkcs11.so"
./p11test -m ../pkcs11/.libs/pkcs11-spy.so

You can run the test suite also on the soft tokens. The testbench for
`softhsm` and `opencryptoki` is available in the script `runtest.sh`.

TODO:

* Test `CKM_ECDSA_DERIVE` mechanism(s)
* Read pin from environment variable?
* Keygen write tests (optional)
* Reflect cmocka dependency in the configure
6 changes: 6 additions & 0 deletions src/tests/p11test/cert.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
organization = "OpenSC"
expiration_days = 365
email = "none@example.org"
signing_key
encryption_key

Loading

0 comments on commit 9858d05

Please sign in to comment.