Skip to content

Commit c9bf130

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

13 files changed

+1478
-3
lines changed

tests/Makefile.am

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,14 @@ check_PROGRAMS = \
1515
fork-change-slot \
1616
list-tokens \
1717
rsa-pss-sign \
18+
rsa-pss-sign-prov \
1819
rsa-oaep \
20+
rsa-oaep-prov \
1921
check-privkey \
22+
check-privkey-prov \
2023
store-cert \
21-
dup-key
24+
dup-key \
25+
dup-key-prov
2226
dist_check_SCRIPTS = \
2327
rsa-testpkcs11.softhsm \
2428
rsa-testfork.softhsm \
@@ -36,7 +40,14 @@ dist_check_SCRIPTS = \
3640
fork-change-slot.softhsm \
3741
case-insensitive.softhsm \
3842
pkcs11-uri-without-token.softhsm \
39-
search-all-matching-tokens.softhsm
43+
search-all-matching-tokens.softhsm \
44+
provider-ec-check-privkey.softhsm \
45+
provider-ec-copy.softhsm \
46+
provider-rsa-check-privkey.softhsm \
47+
provider-rsa-oaep.softhsm \
48+
provider-rsa-pss-sign.softhsm \
49+
provider-pkcs11-uri-without-token.softhsm \
50+
provider-search-all-matching-tokens.softhsm
4051
dist_check_DATA = \
4152
rsa-cert.der rsa-privkey.der rsa-pubkey.der \
4253
ec-cert.der ec-privkey.der ec-pubkey.der

tests/check-privkey-prov.c

Lines changed: 212 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,212 @@
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/rand.h>
40+
#include <openssl/ui.h>
41+
42+
DEFINE_STACK_OF(OSSL_PROVIDER)
43+
static STACK_OF(OSSL_PROVIDER) *providers;
44+
45+
static void display_openssl_errors(void) {
46+
unsigned long e;
47+
const char *file = NULL, *func = NULL, *reason = NULL;
48+
int line = 0, flags = 0;
49+
char err_buf[256];
50+
51+
while ((e = ERR_get_error_all(&file, &line, &func, &reason, &flags))) {
52+
ERR_error_string_n(e, err_buf, sizeof(err_buf));
53+
fprintf(stderr, "%s:%d: %s: %s: %s\n", file ? file : "unknown file",
54+
line, func ? func : "unknown function",
55+
err_buf, reason ? reason : "unknown reason");
56+
}
57+
}
58+
59+
static EVP_PKEY *load_pkey(const char *uri)
60+
{
61+
EVP_PKEY *pkey = NULL;
62+
OSSL_STORE_INFO *info;
63+
OSSL_STORE_CTX *store_ctx;
64+
65+
store_ctx = OSSL_STORE_open(uri, NULL, NULL, NULL, NULL);
66+
if (!store_ctx) {
67+
return NULL;
68+
}
69+
if (!OSSL_STORE_expect(store_ctx, OSSL_STORE_INFO_PKEY)) {
70+
OSSL_STORE_close(store_ctx);
71+
return NULL;
72+
}
73+
info = OSSL_STORE_load(store_ctx);
74+
if (info == NULL) {
75+
OSSL_STORE_close(store_ctx);
76+
return NULL;
77+
}
78+
if (OSSL_STORE_INFO_get_type(info) == OSSL_STORE_INFO_PKEY) {
79+
pkey = OSSL_STORE_INFO_get1_PKEY(info);
80+
}
81+
OSSL_STORE_INFO_free(info);
82+
OSSL_STORE_close(store_ctx);
83+
return pkey;
84+
}
85+
86+
static X509 *load_cert(const char *uri)
87+
{
88+
X509 *cert = NULL;
89+
OSSL_STORE_INFO *info;
90+
OSSL_STORE_CTX *store_ctx;
91+
92+
store_ctx = OSSL_STORE_open(uri, NULL, NULL, NULL, NULL);
93+
if (!store_ctx) {
94+
return NULL;
95+
}
96+
if (!OSSL_STORE_expect(store_ctx, OSSL_STORE_INFO_CERT)) {
97+
OSSL_STORE_close(store_ctx);
98+
return NULL;
99+
}
100+
info = OSSL_STORE_load(store_ctx);
101+
if (info == NULL) {
102+
OSSL_STORE_close(store_ctx);
103+
return NULL;
104+
}
105+
if (OSSL_STORE_INFO_get_type(info) == OSSL_STORE_INFO_CERT) {
106+
cert = OSSL_STORE_INFO_get1_CERT(info);
107+
}
108+
OSSL_STORE_INFO_free(info);
109+
OSSL_STORE_close(store_ctx);
110+
return cert;
111+
}
112+
113+
static void provider_free(OSSL_PROVIDER *prov)
114+
{
115+
printf("Provider \"%s\" unloaded.\n", OSSL_PROVIDER_get0_name(prov));
116+
OSSL_PROVIDER_unload(prov);
117+
}
118+
119+
static void providers_cleanup(void)
120+
{
121+
sk_OSSL_PROVIDER_pop_free(providers, provider_free);
122+
providers = NULL;
123+
}
124+
125+
static int provider_load(const char *pname)
126+
{
127+
OSSL_PROVIDER *prov = OSSL_PROVIDER_load(NULL, pname);
128+
if (prov == NULL) {
129+
fprintf(stderr, "Unable to load provider: %s\n", pname);
130+
return 0; /* FAILED */
131+
}
132+
if (providers == NULL) {
133+
providers = sk_OSSL_PROVIDER_new_null();
134+
}
135+
if (providers == NULL || !sk_OSSL_PROVIDER_push(providers, prov)) {
136+
providers_cleanup();
137+
return 0; /* FAILED */
138+
}
139+
printf("Provider \"%s\" set.\n", OSSL_PROVIDER_get0_name(prov));
140+
return 1; /* OK */
141+
}
142+
143+
int main(int argc, char *argv[])
144+
{
145+
EVP_PKEY *private_key = NULL;
146+
X509 *cert = NULL;
147+
int ret = EXIT_FAILURE;
148+
149+
if (argc < 2) {
150+
fprintf(stderr, "usage: %s [certificate (PEM or URL)] [private key URL]n", argv[0]);
151+
return ret;
152+
}
153+
154+
/* Load PKCS#11 provider */
155+
if (!OSSL_PROVIDER_available(NULL, "pkcs11prov")) {
156+
if (!provider_load("pkcs11prov")) {
157+
fprintf(stderr, "Failed to load \"pkcs11prov\" provider\n");
158+
display_openssl_errors();
159+
goto cleanup;
160+
}
161+
/* load the default provider explicitly */
162+
if (!provider_load("default")) {
163+
fprintf(stderr, "Failed to load \"default\" provider\n");
164+
display_openssl_errors();
165+
goto cleanup;
166+
}
167+
}
168+
169+
/* Load certificate */
170+
cert = load_cert(argv[1]);
171+
if (!cert) {
172+
fprintf(stderr, "Cannot load certificate: %s\n", argv[1]);
173+
display_openssl_errors();
174+
goto cleanup;
175+
}
176+
printf("Certificate found: %s\n", argv[1]);
177+
178+
/* Load private key */
179+
private_key = load_pkey(argv[2]);
180+
if (!private_key) {
181+
fprintf(stderr, "Cannot load private key: %s\n", argv[1]);
182+
display_openssl_errors();
183+
goto cleanup;
184+
}
185+
printf("Private key found.\n");
186+
187+
ret = X509_check_private_key(cert, private_key);
188+
if (!ret) {
189+
printf("Could not check private key.\n");
190+
display_openssl_errors();
191+
goto cleanup;
192+
}
193+
194+
printf("Key and certificate matched.\n");
195+
ret = EXIT_SUCCESS;
196+
197+
cleanup:
198+
X509_free(cert);
199+
EVP_PKEY_free(private_key);
200+
providers_cleanup();
201+
return ret;
202+
}
203+
204+
#else
205+
206+
int main() {
207+
return 0;
208+
}
209+
210+
#endif /* OPENSSL_VERSION_NUMBER >= 0x30000000L */
211+
212+
/* vim: set noexpandtab: */

0 commit comments

Comments
 (0)