Add support for PKCS#11 provider in OpenSSL 3.0

The engine API in OpenSSL 3.0 is deprecated so we are in the progress of working
on a PKCS#11 provider for OpenSSL. This commit introduces a conditional build
with the pkcs11-provider support (instead of engines) with all the changes
required for the provider to work with existing code and tests.

The CI modification is only temporary before we will have the real package in
Fedora or somewhere to use.

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Norbert Pocs <npocs@redhat.com>
This commit is contained in:
Jakub Jelen
2022-10-31 15:09:26 +01:00
parent 7291f2173c
commit 2539d72b7c
18 changed files with 276 additions and 62 deletions

View File

@@ -183,6 +183,16 @@ if (CLIENT_TESTING OR SERVER_TESTING)
if (NOT SOFTHSM_FOUND)
message(SEND_ERROR "Could not find softhsm module!")
endif (NOT SOFTHSM_FOUND)
if (WITH_PKCS11_PROVIDER)
find_package(PkgConfig)
if (PKG_CONFIG_FOUND)
pkg_check_modules(P11_KIT p11-kit-1)
if (P11_KIT_FOUND)
pkg_get_variable(P11_MODULE_PATH p11-kit-1 p11_module_path)
set(P11_KIT_CLIENT ${P11_MODULE_PATH}/p11-kit-client.so)
endif (P11_KIT_FOUND)
endif (PKG_CONFIG_FOUND)
endif (WITH_PKCS11_PROVIDER)
endif (WITH_PKCS11_URI)
find_program(SSH_EXECUTABLE NAMES ssh)
@@ -297,12 +307,14 @@ if (CLIENT_TESTING OR SERVER_TESTING)
file(COPY keys/certauth/id_rsa DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/home/bob/.ssh_cert/ FILE_PERMISSIONS OWNER_READ OWNER_WRITE)
file(COPY keys/certauth/id_rsa.pub DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/home/bob/.ssh_cert/ FILE_PERMISSIONS OWNER_READ OWNER_WRITE)
file(COPY keys/certauth/id_rsa-cert.pub DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/home/bob/.ssh_cert/ FILE_PERMISSIONS OWNER_READ OWNER_WRITE)
endif ()
if (WITH_PKCS11_URI)
#Copy the script to setup PKCS11 tokens
file(COPY pkcs11/setup-softhsm-tokens.sh DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/pkcs11 FILE_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE)
endif (WITH_PKCS11_URI)
message(STATUS "TORTURE_ENVIRONMENT=${TORTURE_ENVIRONMENT}")
endif ()
message(STATUS "TORTURE_ENVIRONMENT=${TORTURE_ENVIRONMENT}")
configure_file(tests_config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/tests_config.h)

View File

@@ -39,7 +39,6 @@
#define LIBSSH_ECDSA_256_TESTKEY "id_pkcs11_ecdsa_256"
#define LIBSSH_ECDSA_384_TESTKEY "id_pkcs11_ecdsa_384"
#define LIBSSH_ECDSA_521_TESTKEY "id_pkcs11_ecdsa_521"
#define SOFTHSM_CONF "softhsm.conf"
const char template[] = "temp_dir_XXXXXX";
@@ -109,7 +108,6 @@ static int setup_session(void **state)
struct torture_state *s = *state;
struct pki_st *test_state = NULL;
int rc;
char conf_path[1024] = {0};
char keys_dir[1024] = {0};
char *temp_dir;
@@ -134,9 +132,6 @@ static int setup_session(void **state)
test_state->keys_dir = strdup(keys_dir);
snprintf(conf_path, sizeof(conf_path), "%s/softhsm.conf", test_state->temp_dir);
setenv("SOFTHSM2_CONF", conf_path, 1);
setup_tokens(state, LIBSSH_RSA_TESTKEY, "rsa");
setup_tokens(state, LIBSSH_ECDSA_256_TESTKEY, "ecdsa256");
setup_tokens(state, LIBSSH_ECDSA_384_TESTKEY, "ecdsa384");
@@ -160,7 +155,7 @@ static int sshd_teardown(void **state) {
struct pki_st *test_state = s->private_data;
int rc;
unsetenv("SOFTHSM2_CONF");
torture_cleanup_tokens(test_state->temp_dir);
rc = torture_change_dir(test_state->orig_dir);
assert_int_equal(rc, 0);

View File

@@ -5,8 +5,10 @@
TESTDIR=$1
PRIVKEY=$2
OBJNAME=$3
TOKENLABEL=$3 # yeah. The same as object label
LOADPUBLIC=$4
LIBSOFTHSM_PATH=$5
P11_KIT_CLIENT=$6
shift 5
PUBKEY="$PRIVKEY.pub"
@@ -15,24 +17,27 @@ echo "TESTDIR: $TESTDIR"
echo "PRIVKEY: $PRIVKEY"
echo "PUBKEY: $PUBKEY"
echo "OBJNAME: $OBJNAME"
echo "TOKENLABEL: $TOKENLABEL"
echo "LOADPUBLIC: $LOADPUBLIC"
# Create temporary directory for tokens
install -d -m 0755 "$TESTDIR/db"
if [ ! -d "$TESTDIR/db" ]; then
# Create temporary directory for tokens
install -d -m 0755 "$TESTDIR/db"
# Create SoftHSM configuration file
cat >"$TESTDIR/softhsm.conf" <<EOF
# Create SoftHSM configuration file
cat >"$TESTDIR/softhsm.conf" <<EOF
directories.tokendir = $TESTDIR/db
objectstore.backend = file
log.level = DEBUG
EOF
cat "$TESTDIR/softhsm.conf"
fi
export SOFTHSM2_CONF=$TESTDIR/softhsm.conf
cat "$TESTDIR/softhsm.conf"
#init
cmd="softhsm2-util --init-token --label $OBJNAME --free --pin 1234 --so-pin 1234"
#init -- each object will have its own token
cmd="softhsm2-util --init-token --label $TOKENLABEL --free --pin 1234 --so-pin 1234"
eval echo "$cmd"
out=$(eval "$cmd")
ret=$?
@@ -43,7 +48,7 @@ if [ $ret -ne 0 ]; then
fi
#load private key
cmd="p11tool --provider $LIBSOFTHSM_PATH --write --load-privkey $PRIVKEY --label $OBJNAME --login --set-pin=1234 \"pkcs11:token=$OBJNAME\""
cmd="p11tool --provider $LIBSOFTHSM_PATH --write --load-privkey $PRIVKEY --label $OBJNAME --login --set-pin=1234 \"pkcs11:token=$TOKENLABEL\""
eval echo "$cmd"
out=$(eval "$cmd")
ret=$?
@@ -59,7 +64,7 @@ ls -l "$TESTDIR"
if [ "$LOADPUBLIC" -ne 0 ]; then
#load public key
cmd="p11tool --provider $LIBSOFTHSM_PATH --write --load-pubkey $PUBKEY --label $OBJNAME --login --set-pin=1234 \"pkcs11:token=$OBJNAME\""
cmd="p11tool --provider $LIBSOFTHSM_PATH --write --load-pubkey $PUBKEY --label $OBJNAME --login --set-pin=1234 \"pkcs11:token=$TOKENLABEL\""
eval echo "$cmd"
out=$(eval "$cmd")
ret=$?
@@ -70,7 +75,7 @@ if [ "$LOADPUBLIC" -ne 0 ]; then
fi
fi
cmd="p11tool --list-all --login \"pkcs11:token=$OBJNAME\" --set-pin=1234"
cmd="p11tool --list-all --login \"pkcs11:token=$TOKENLABEL\" --set-pin=1234"
eval echo "$cmd"
out=$(eval "$cmd")
ret=$?
@@ -81,4 +86,55 @@ if [ $ret -ne 0 ]; then
fi
echo "$out"
# Skip the p11-kit if not needed
if [ -z "$P11_KIT_CLIENT" ]; then
exit 0
fi
# when creating more keys, we need to restart the p11-kit
# so it can pick up the new keys
if [ -h "$TESTDIR/p11-kit-server.socket" ]; then
kill -9 $(cat $TESTDIR/p11-kit-server.pid)
rm $TESTDIR/p11-kit-server.socket
fi
# p11-kit complains if there is no runtime directory
if [ -z "$XDG_RUNTIME_DIR" ]; then
export XDG_RUNTIME_DIR=$PWD
fi
# Start the p11-kit server
cmd="p11-kit server --provider $LIBSOFTHSM_PATH pkcs11:"
echo "$cmd"
out=$(eval "$cmd")
ret=$?
if [ $ret -ne 0 ]; then
echo "Starting p11-kit server failed"
echo "$out"
exit 1
fi
eval $out
# Symlink the p11-kit-server socket to "known place"
P11_KIT_SERVER_ADDRESS_PATH=${P11_KIT_SERVER_ADDRESS:10}
cmd="ln -s $P11_KIT_SERVER_ADDRESS_PATH $TESTDIR/p11-kit-server.socket"
echo "$cmd"
out=$(eval "$cmd")
# Save the PID for the C code to clean up
cmd="echo $P11_KIT_SERVER_PID > $TESTDIR/p11-kit-server.pid"
echo "$cmd"
out=$(eval "$cmd")
cmd="pkcs11-tool -O --login --pin=1234 --module=$P11_KIT_CLIENT --token-label=$TOKENLABEL"
echo "$cmd"
out=$(eval "$cmd")
ret=$?
echo "$out"
if [ $ret -ne 0 ]; then
echo "Failed to list keys through p11-kit remoting"
echo "$out"
exit 1
fi
exit 0

View File

@@ -68,3 +68,4 @@
#cmakedefine WITH_TIMEOUT ${WITH_TIMEOUT}
#cmakedefine TIMEOUT_EXECUTABLE "${TIMEOUT_EXECUTABLE}"
#cmakedefine SOFTHSM2_LIBRARY "${SOFTHSM2_LIBRARY}"
#cmakedefine P11_KIT_CLIENT "${P11_KIT_CLIENT}"

View File

@@ -1193,19 +1193,60 @@ void torture_setup_tokens(const char *temp_dir,
const char *load_public)
{
char token_setup_start_cmd[1024] = {0};
char socket_path[1204] = {0};
char conf_path[1024] = {0};
int rc;
snprintf(token_setup_start_cmd, sizeof(token_setup_start_cmd),
"%s/tests/pkcs11/setup-softhsm-tokens.sh %s %s %s %s %s",
BINARYDIR,
temp_dir,
filename,
object_name,
load_public,
SOFTHSM2_LIBRARY);
rc = snprintf(token_setup_start_cmd,
sizeof(token_setup_start_cmd),
"%s/tests/pkcs11/setup-softhsm-tokens.sh %s %s %s %s %s %s",
BINARYDIR,
temp_dir,
filename,
object_name,
load_public,
SOFTHSM2_LIBRARY,
#ifdef WITH_PKCS11_PROVIDER
P11_KIT_CLIENT
#else
""
#endif
);
assert_int_not_equal(rc, sizeof(token_setup_start_cmd));
rc = system(token_setup_start_cmd);
assert_return_code(rc, errno);
#ifdef WITH_PKCS11_PROVIDER
rc = snprintf(socket_path,
sizeof(socket_path),
"unix:path=%s/p11-kit-server.socket",
temp_dir);
assert_int_not_equal(rc, sizeof(socket_path));
setenv("P11_KIT_SERVER_ADDRESS", socket_path, 1);
setenv("PKCS11_PROVIDER_MODULE", P11_KIT_CLIENT, 1);
/* This is useful for debugging PKCS#11 calls */
setenv("PKCS11SPY", P11_KIT_CLIENT, 1);
setenv("PKCS11_PROVIDER_MODULE", "/usr/lib64/pkcs11-spy.so", 1);
#else
snprintf(conf_path, sizeof(conf_path), "%s/softhsm.conf", temp_dir);
setenv("SOFTHSM2_CONF", conf_path, 1);
#endif /* WITH_PKCS11_PROVIDER */
}
void torture_cleanup_tokens(const char *temp_dir)
{
char pidfile[1024] = {0};
int rc;
pid_t pid;
#ifdef WITH_PKCS11_PROVIDER
snprintf(pidfile, sizeof(pidfile), "%s/p11-kit-server.pid", temp_dir);
torture_terminate_process(pidfile);
#else
unsetenv("SOFTHSM2_CONF");
#endif /* WITH_PKCS11_PROVIDER */
}
#endif /* WITH_PKCS11_URI */

View File

@@ -135,6 +135,7 @@ void torture_setup_tokens(const char *temp_dir,
const char *filename,
const char object_name[],
const char *load_public);
void torture_cleanup_tokens(const char *temp_dir);
#endif /* WITH_PKCS11_URI */
void torture_reset_config(ssh_session session);

View File

@@ -69,6 +69,7 @@ if (UNIX AND NOT WIN32)
torture_pki_rsa_uri
torture_pki_ecdsa_uri
)
list(APPEND TORTURE_UNIT_ENVIRONMENT PKCS11_PROVIDER_DEBUG=file:/tmp/p11prov-debug.log)
endif()
if (HAVE_ECC)

View File

@@ -76,7 +76,6 @@ static int setup_directory_structure(void **state)
struct pki_st *test_state = NULL;
char *temp_dir;
int rc;
char conf_path[1024] = {0};
test_state = (struct pki_st *)malloc(sizeof(struct pki_st));
assert_non_null(test_state);
@@ -96,9 +95,6 @@ static int setup_directory_structure(void **state)
*state = test_state;
snprintf(conf_path, sizeof(conf_path), "%s/softhsm.conf", test_state->temp_dir);
setenv("SOFTHSM2_CONF", conf_path, 1);
setup_tokens_ecdsa(state, 256, "ecdsa256", "1");
setup_tokens_ecdsa(state, 384, "ecdsa384", "1");
setup_tokens_ecdsa(state, 521, "ecdsa521", "1");
@@ -114,7 +110,7 @@ static int teardown_directory_structure(void **state)
struct pki_st *test_state = *state;
int rc;
unsetenv("SOFTHSM2_CONF");
torture_cleanup_tokens(test_state->temp_dir);
rc = torture_change_dir(test_state->orig_dir);
assert_int_equal(rc, 0);

View File

@@ -13,7 +13,6 @@
#define LIBSSH_RSA_TESTKEY "libssh_testkey.id_rsa"
#define LIBSSH_RSA_TESTKEY_PASSPHRASE "libssh_testkey_passphrase.id_rsa"
#define SOFTHSM_CONF "softhsm.conf"
#define PUB_URI_FMT "pkcs11:token=%s;object=%s;type=public"
#define PRIV_URI_FMT "pkcs11:token=%s;object=%s;type=private?pin-value=%s"
@@ -33,7 +32,6 @@ struct pki_st {
static int setup_tokens(void **state)
{
char conf_path[1024] = {0};
char keys_path[1024] = {0};
char keys_path_pub[1024] = {0};
char *cwd = NULL;
@@ -85,10 +83,6 @@ static int setup_tokens(void **state)
torture_setup_tokens(cwd, keys_path, obj_tempname, "1");
snprintf(conf_path, sizeof(conf_path), "%s/softhsm.conf", cwd);
setenv("SOFTHSM2_CONF", conf_path, 1);
return 0;
}
@@ -126,6 +120,8 @@ static int teardown_directory_structure(void **state)
struct pki_st *test_state = *state;
int rc;
torture_cleanup_tokens(test_state->temp_dir);
rc = torture_change_dir(test_state->orig_dir);
assert_int_equal(rc, 0);
@@ -142,8 +138,6 @@ static int teardown_directory_structure(void **state)
SAFE_FREE(test_state->pub_uri_invalid_token);
SAFE_FREE(test_state);
unsetenv("SOFTHSM2_CONF");
return 0;
}