Skip to content

Commit 6a2eb0f

Browse files
committed
libp11 PKCS#11 provider tests
1 parent 2278da2 commit 6a2eb0f

8 files changed

+785
-3
lines changed

tests/Makefile.am

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,12 @@ check_PROGRAMS = \
1515
fork-change-slot \
1616
list-tokens \
1717
rsa-pss-sign \
18+
rsa-pss-sign-prov \
1819
rsa-oaep \
1920
check-privkey \
2021
store-cert \
21-
dup-key
22+
dup-key \
23+
dup-key-prov
2224
dist_check_SCRIPTS = \
2325
rsa-testpkcs11.softhsm \
2426
rsa-testfork.softhsm \
@@ -36,7 +38,11 @@ dist_check_SCRIPTS = \
3638
fork-change-slot.softhsm \
3739
case-insensitive.softhsm \
3840
pkcs11-uri-without-token.softhsm \
39-
search-all-matching-tokens.softhsm
41+
search-all-matching-tokens.softhsm \
42+
provider-pkey-copy.softhsm \
43+
provider-rsa-pss-sign.softhsm \
44+
provider-pkcs11-uri-without-token.softhsm \
45+
provider-search-all-matching-tokens.softhsm
4046
dist_check_DATA = \
4147
rsa-cert.der rsa-privkey.der rsa-pubkey.der \
4248
ec-cert.der ec-privkey.der ec-pubkey.der

tests/dup-key-prov.c

Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
/*
2+
* Copyright © 2025 Mobi - Com Polska Sp. z o.o.
3+
* Author: Małgorzata Olszówka <Malgorzata.Olszowka@stunnel.org>
4+
* All rights reserved.
5+
*
6+
* Redistribution and use in source and binary forms, with or without
7+
* modification, are permitted provided that the following conditions
8+
* are met:
9+
* 1. Redistributions of source code must retain the above copyright
10+
* notice, this list of conditions and the following disclaimer.
11+
* 2. Redistributions in binary form must reproduce the above copyright
12+
* notice, this list of conditions and the following disclaimer in the
13+
* documentation and/or other materials provided with the distribution.
14+
*
15+
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16+
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18+
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19+
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20+
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21+
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22+
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23+
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24+
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25+
* SUCH DAMAGE.
26+
*/
27+
28+
#include <openssl/opensslv.h>
29+
30+
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
31+
32+
#include <stdio.h>
33+
#include <stdlib.h>
34+
#include <string.h>
35+
36+
#include <openssl/err.h>
37+
#include <openssl/store.h>
38+
#include <openssl/provider.h>
39+
#include <openssl/ui.h>
40+
41+
DEFINE_STACK_OF(OSSL_PROVIDER)
42+
static STACK_OF(OSSL_PROVIDER) *providers;
43+
44+
static void display_openssl_errors(void) {
45+
unsigned long e;
46+
const char *file = NULL, *func = NULL, *reason = NULL;
47+
int line = 0, flags = 0;
48+
char err_buf[256];
49+
50+
while ((e = ERR_get_error_all(&file, &line, &func, &reason, &flags))) {
51+
ERR_error_string_n(e, err_buf, sizeof(err_buf));
52+
fprintf(stderr, "%s:%d: %s: %s: %s\n", file ? file : "unknown file",
53+
line, func ? func : "unknown function",
54+
err_buf, reason ? reason : "unknown reason");
55+
}
56+
}
57+
58+
static EVP_PKEY *load_pkey(const char *uri)
59+
{
60+
EVP_PKEY *pkey = NULL;
61+
OSSL_STORE_INFO *info;
62+
OSSL_STORE_CTX *store_ctx;
63+
64+
store_ctx = OSSL_STORE_open(uri, NULL, NULL, NULL, NULL);
65+
if (!store_ctx) {
66+
return NULL;
67+
}
68+
if (!OSSL_STORE_expect(store_ctx, OSSL_STORE_INFO_PKEY)) {
69+
OSSL_STORE_close(store_ctx);
70+
return NULL;
71+
}
72+
info = OSSL_STORE_load(store_ctx);
73+
if (info == NULL) {
74+
OSSL_STORE_close(store_ctx);
75+
return NULL;
76+
}
77+
if (OSSL_STORE_INFO_get_type(info) == OSSL_STORE_INFO_PKEY) {
78+
pkey = OSSL_STORE_INFO_get1_PKEY(info);
79+
}
80+
OSSL_STORE_INFO_free(info);
81+
OSSL_STORE_close(store_ctx);
82+
return pkey;
83+
}
84+
85+
static void provider_free(OSSL_PROVIDER *prov)
86+
{
87+
printf("Provider \"%s\" unloaded.\n", OSSL_PROVIDER_get0_name(prov));
88+
OSSL_PROVIDER_unload(prov);
89+
}
90+
91+
static void providers_cleanup(void)
92+
{
93+
sk_OSSL_PROVIDER_pop_free(providers, provider_free);
94+
providers = NULL;
95+
}
96+
97+
static int provider_load(const char *pname)
98+
{
99+
OSSL_PROVIDER *prov = OSSL_PROVIDER_load(NULL, pname);
100+
if (prov == NULL) {
101+
fprintf(stderr, "Unable to load provider: %s\n", pname);
102+
return 0; /* FAILED */
103+
}
104+
if (providers == NULL) {
105+
providers = sk_OSSL_PROVIDER_new_null();
106+
}
107+
if (providers == NULL || !sk_OSSL_PROVIDER_push(providers, prov)) {
108+
providers_cleanup();
109+
return 0; /* FAILED */
110+
}
111+
printf("Provider \"%s\" set.\n", OSSL_PROVIDER_get0_name(prov));
112+
return 1; /* OK */
113+
}
114+
115+
int main(int argc, char *argv[])
116+
{
117+
EVP_PKEY *private_key = NULL;
118+
EVP_PKEY *private_key_dup = NULL;
119+
int ret = EXIT_FAILURE;
120+
121+
if (argc < 1) {
122+
fprintf(stderr, "Usage: %s [private key URL]\n", argv[0]);
123+
return ret;
124+
}
125+
126+
/* Load PKCS#11 provider */
127+
if (!OSSL_PROVIDER_available(NULL, "pkcs11prov")) {
128+
if (!provider_load("pkcs11prov")) {
129+
fprintf(stderr, "Failed to load \"pkcs11prov\" provider\n");
130+
display_openssl_errors();
131+
goto cleanup;
132+
}
133+
/* load the default provider explicitly */
134+
if (!provider_load("default")) {
135+
fprintf(stderr, "Failed to load \"default\" provider\n");
136+
display_openssl_errors();
137+
goto cleanup;
138+
}
139+
}
140+
141+
/* Load private key */
142+
private_key = load_pkey(argv[1]);
143+
if (!private_key) {
144+
fprintf(stderr, "Cannot load private key: %s\n", argv[1]);
145+
display_openssl_errors();
146+
goto cleanup;
147+
}
148+
printf("Private key found.\n");
149+
150+
private_key_dup = EVP_PKEY_dup(private_key);
151+
if (!private_key_dup) {
152+
fprintf(stderr, "Cannot duplicate private key\n");
153+
display_openssl_errors();
154+
goto cleanup;
155+
}
156+
printf("Duplicate private key created.\n");
157+
158+
EVP_PKEY_free(private_key_dup);
159+
EVP_PKEY_free(private_key);
160+
161+
/* Do it one more time */
162+
private_key = load_pkey(argv[1]);
163+
if (!private_key) {
164+
fprintf(stderr, "Cannot load private key: %s\n", argv[1]);
165+
display_openssl_errors();
166+
goto cleanup;
167+
}
168+
printf("Private key found.\n");
169+
170+
ret = EXIT_SUCCESS;
171+
cleanup:
172+
EVP_PKEY_free(private_key);
173+
providers_cleanup();
174+
175+
return ret;
176+
}
177+
178+
#else
179+
180+
int main() {
181+
return EXIT_SUCCESS;
182+
}
183+
184+
#endif /* OPENSSL_VERSION_NUMBER >= 0x30000000L */
185+

tests/openssl.cnf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ module = /usr/lib64/ossl-modules/pkcs11prov.so
2929
pkcs11_module = /usr/lib64/opensc-pkcs11.so
3030

3131
# set the debug level
32-
debug_level = 5
32+
debug_level = 7
3333

3434
# force login to the PKCS#11 module
3535
#force_login = 1

tests/provider-ec-copy.softhsm

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
#!/bin/bash
2+
3+
# Copyright © 2025 Mobi - Com Polska Sp. z o.o.
4+
# Author: Małgorzata Olszówka <Malgorzata.Olszowka@stunnel.org>
5+
#
6+
# This program is free software: you can redistribute it and/or modify
7+
# it under the terms of the GNU General Public License as published by
8+
# the Free Software Foundation, either version 3 of the License, or
9+
# (at your option) any later version.
10+
#
11+
# This program is distributed in the hope that it will be useful,
12+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
# GNU General Public License for more details.
15+
#
16+
# You should have received a copy of the GNU General Public License
17+
# along with this program. If not, see <http://www.gnu.org/licenses/>
18+
19+
outdir="output.$$"
20+
21+
PRIVATE_KEY="pkcs11:token=libp11-0;id=%01%02%03%04;object=server-key-0;type=private;pin-value=1234"
22+
23+
# Load common test functions
24+
. ${srcdir}/common.sh
25+
26+
if [[ "${OPENSSL_VERSION}" =~ ^[012].* ]]; then
27+
echo "Skipping test with OpenSSL ${OPENSSL_VERSION}"
28+
exit 77
29+
fi
30+
31+
# Do the token initialization
32+
init_token "ec" "1" "libp11" ${ID} "server-key" "privkey" "" ""
33+
34+
# Ensure the use of the locally built provider; applies after running 'pkcs11-tool'
35+
unset OPENSSL_ENGINES
36+
export OPENSSL_MODULES="../src/.libs/"
37+
export PKCS11_MODULE_PATH=${MODULE}
38+
echo "OPENSSL_MODULES=${OPENSSL_MODULES}"
39+
echo "PKCS11_MODULE_PATH=${PKCS11_MODULE_PATH}"
40+
41+
# Load openssl settings
42+
TEMP_LD_LIBRARY_PATH=${LD_LIBRARY_PATH}
43+
. ${srcdir}/openssl-settings.sh
44+
45+
# Run the test
46+
${WRAPPER} ./dup-key-prov ${PRIVATE_KEY}
47+
if [[ $? -ne 0 ]]; then
48+
echo "Could not duplicate private key"
49+
exit 1
50+
fi
51+
52+
# Restore settings
53+
export LD_LIBRARY_PATH=${TEMP_LD_LIBRARY_PATH}
54+
55+
rm -rf "$outdir"
56+
57+
exit 0
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
#!/bin/bash
2+
3+
# Copyright © 2024 Mobi - Com Polska Sp. z o.o.
4+
# Author: Małgorzata Olszówka <Malgorzata.Olszowka@stunnel.org>
5+
#
6+
# This program is free software: you can redistribute it and/or modify
7+
# it under the terms of the GNU General Public License as published by
8+
# the Free Software Foundation, either version 3 of the License, or
9+
# (at your option) any later version.
10+
#
11+
# This program is distributed in the hope that it will be useful,
12+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
# GNU General Public License for more details.
15+
#
16+
# You should have received a copy of the GNU General Public License
17+
# along with this program. If not, see <http://www.gnu.org/licenses/>
18+
19+
# This test checks if it is possible to use the keys without specifying the
20+
# token if there is only one initialized token available.
21+
22+
outdir="output.$$"
23+
24+
# These URIs don't contain the token specification
25+
PRIVATE_KEY="pkcs11:object=server-key-0;type=private;pin-value=1234"
26+
PUBLIC_KEY="pkcs11:object=server-key-0;type=public"
27+
CERTIFICATE="pkcs11:object=server-key-0;type=cert"
28+
29+
# Load common test functions
30+
. ${srcdir}/common.sh
31+
32+
if [[ "${OPENSSL_VERSION}" =~ ^[012].* ]]; then
33+
echo "Skipping test with OpenSSL ${OPENSSL_VERSION}"
34+
exit 77
35+
fi
36+
37+
# Do the token initialization
38+
init_token "rsa" "1" "libp11" ${ID} "server-key" "privkey" "pubkey" "cert"
39+
40+
# Ensure the use of the locally built provider; applies after running 'pkcs11-tool'
41+
unset OPENSSL_ENGINES
42+
export OPENSSL_MODULES="../src/.libs/"
43+
export PKCS11_MODULE_PATH=${MODULE}
44+
echo "OPENSSL_MODULES=${OPENSSL_MODULES}"
45+
echo "PKCS11_MODULE_PATH=${PKCS11_MODULE_PATH}"
46+
47+
# Create input file
48+
echo "secret" >"${outdir}/in.txt"
49+
50+
# Load openssl settings
51+
TEMP_LD_LIBRARY_PATH=${LD_LIBRARY_PATH}
52+
. ${srcdir}/openssl-settings.sh
53+
54+
# Run the test
55+
# Generate signature without specifying the token in the PKCS#11 URI
56+
${WRAPPER} ${OPENSSL} pkeyutl -provider pkcs11prov -provider default \
57+
-inkey ${PRIVATE_KEY} -sign -out "${outdir}/signature.bin" \
58+
-in "${outdir}/in.txt"
59+
if [[ $? -ne 0 ]]; then
60+
echo "Failed to generate signature using PKCS#11 URI ${PRIVATE_KEY}"
61+
exit 1
62+
fi
63+
64+
# Verify the signature using the public without specifying the token
65+
${OPENSSL} pkeyutl -provider pkcs11prov -provider default -pubin \
66+
-inkey ${PUBLIC_KEY} -verify -sigfile "${outdir}/signature.bin" \
67+
-in "${outdir}/in.txt"
68+
if [[ $? -ne 0 ]]; then
69+
echo "Failed to verify signature using PKCS#11 URI ${PUBLIC_KEY}"
70+
exit 1
71+
fi
72+
73+
# Verify the signature using a certificate without specifying the token
74+
${OPENSSL} pkeyutl -provider pkcs11prov -provider default -certin \
75+
-inkey ${PUBLIC_KEY} -verify -sigfile "${outdir}/signature.bin" \
76+
-in "${outdir}/in.txt"
77+
if [[ $? -ne 0 ]]; then
78+
echo "Failed to verify signature using PKCS#11 URI ${PUBLIC_KEY}"
79+
exit 1
80+
fi
81+
82+
# Restore settings
83+
export LD_LIBRARY_PATH=${TEMP_LD_LIBRARY_PATH}
84+
85+
rm -rf "$outdir"
86+
87+
exit 0

0 commit comments

Comments
 (0)