OpenVPN
test_pkcs11.c
Go to the documentation of this file.
1 /*
2  * OpenVPN -- An application to securely tunnel IP networks
3  * over a single UDP port, with support for SSL/TLS-based
4  * session authentication and key exchange,
5  * packet encryption, packet authentication, and
6  * packet compression.
7  *
8  * Copyright (C) 2023-2024 Selva Nair <selva.nair@gmail.com>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by the
12  * Free Software Foundation, either version 2 of the License,
13  * or (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License along
21  * with this program; if not, write to the Free Software Foundation, Inc.,
22  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23  */
24 
25 #ifdef HAVE_CONFIG_H
26 #include "config.h"
27 #endif
28 
29 #include "syshead.h"
30 #include "manage.h"
31 #include "base64.h"
32 #include "run_command.h"
33 #include "xkey_common.h"
34 #include "cert_data.h"
35 #include "pkcs11.h"
36 #include "ssl.h"
37 
38 #include <setjmp.h>
39 #include <cmocka.h>
40 #include "test_common.h"
41 
42 #define token_name "Test Token"
43 #define PIN "12345"
44 #define HASHSIZE 20
45 
46 
47 struct management *management; /* global */
48 
49 /* replacement for crypto_print_openssl_errors() */
50 void
51 crypto_print_openssl_errors(const unsigned int flags)
52 {
53  unsigned long e;
54  while ((e = ERR_get_error()))
55  {
56  msg(flags, "OpenSSL error %lu: %s\n", e, ERR_error_string(e, NULL));
57  }
58 }
59 
60 /* stubs for some unused functions instead of pulling in too many dependencies */
61 int
62 parse_line(const char *line, char **p, const int n, const char *file,
63  const int line_num, int msglevel, struct gc_arena *gc)
64 {
65  assert_true(0);
66  return 0;
67 }
68 char *
70 {
71  return "N/A";
72 }
73 void
75 {
76  assert_true(0);
77 }
78 bool
80 {
81  assert_true(0);
82  return false;
83 }
84 void
85 query_user_add(char *prompt, size_t prompt_len, char *resp, size_t resp_len, bool echo)
86 {
87  (void) prompt;
88  (void) prompt_len;
89  (void) resp;
90  (void) resp_len;
91  (void) echo;
92  assert_true(0);
93 }
94 void
95 purge_user_pass(struct user_pass *up, const bool force)
96 {
97  (void) force;
98  secure_memzero(up, sizeof(*up));
99 }
100 
101 char *
102 management_query_pk_sig(struct management *man, const char *b64_data,
103  const char *algorithm)
104 {
105  (void) man;
106  (void) b64_data;
107  (void) algorithm;
108  return NULL;
109 }
110 
111 int
112 digest_sign_verify(EVP_PKEY *privkey, EVP_PKEY *pubkey);
113 
114 /* Test certificate database: data for cert1, cert2 .. key1, key2 etc.
115  * are defined in cert_data.h
116  */
117 static struct test_cert
118 {
119  const char *const cert; /* certificate as PEM */
120  const char *const key; /* key as unencrypted PEM */
121  const char *const cname; /* common-name */
122  const char *const issuer; /* issuer common-name */
123  const char *const friendly_name; /* identifies certs loaded to the store -- keep unique */
124  uint8_t hash[HASHSIZE]; /* SHA1 fingerprint: computed and filled in later */
125  char *p11_id; /* PKCS#11 id -- filled in later */
126 } certs[5];
127 
129 static char softhsm2_tokens_path[] = "softhsm2_tokens_XXXXXX";
130 static char softhsm2_conf_path[] = "softhsm2_conf_XXXXXX";
132 static const char *pkcs11_id_current;
133 struct env_set *es;
134 
135 /* Fill-in certs[] array */
136 void
138 {
139  struct test_cert certs_local[] = {
140  {cert1, key1, cname1, "OVPN TEST CA1", "OVPN Test Cert 1", {0}, NULL},
141  {cert2, key2, cname2, "OVPN TEST CA2", "OVPN Test Cert 2", {0}, NULL},
142  {cert3, key3, cname3, "OVPN TEST CA1", "OVPN Test Cert 3", {0}, NULL},
143  {cert4, key4, cname4, "OVPN TEST CA2", "OVPN Test Cert 4", {0}, NULL},
144  {0}
145  };
146  assert(sizeof(certs_local) == sizeof(certs));
147  memcpy(certs, certs_local, sizeof(certs_local));
148 }
149 
150 /* Intercept get_user_pass for PIN and other prompts */
151 bool
152 get_user_pass_cr(struct user_pass *up, const char *auth_file, const char *prefix,
153  const unsigned int flags, const char *unused)
154 {
155  (void) unused;
156  bool ret = true;
157  if (!strcmp(prefix, "pkcs11-id-request") && flags&GET_USER_PASS_NEED_STR)
158  {
159  assert_true(pkcs11_id_management);
160  strncpynt(up->password, pkcs11_id_current, sizeof(up->password));
161  }
162  else if (flags & GET_USER_PASS_PASSWORD_ONLY)
163  {
164  snprintf(up->password, sizeof(up->password), "%s", PIN);
165  }
166  else
167  {
168  msg(M_NONFATAL, "ERROR: get_user_pass called with unknown request <%s> ignored\n", prefix);
169  ret = false;
170  }
171 
172  return ret;
173 }
174 
175 /* Compute sha1 hash of a X509 certificate */
176 static void
177 sha1_fingerprint(X509 *x509, uint8_t *hash, int capacity)
178 {
179  assert_true(capacity >= EVP_MD_size(EVP_sha1()));
180  assert_int_equal(X509_digest(x509, EVP_sha1(), hash, NULL), 1);
181 }
182 
183 #if defined(HAVE_XKEY_PROVIDER)
185 OSSL_PROVIDER *prov[2];
186 #endif
187 
188 static int
189 init(void **state)
190 {
191  (void) state;
192 
193  umask(0077); /* ensure all files and directories we create get user only access */
194  char config[256];
195 
196  init_cert_data();
197  if (!mkdtemp(softhsm2_tokens_path))
198  {
199  fail_msg("make tmpdir using template <%s> failed (error = %d)", softhsm2_tokens_path, errno);
200  }
201 
202  int fd = mkstemp(softhsm2_conf_path);
203  if (fd < 0)
204  {
205  fail_msg("make tmpfile using template <%s> failed (error = %d)", softhsm2_conf_path, errno);
206  }
207  snprintf(config, sizeof(config), "directories.tokendir=%s/",
209  assert_int_equal(write(fd, config, strlen(config)), strlen(config));
210  close(fd);
211 
212  /* environment */
213  setenv("SOFTHSM2_CONF", softhsm2_conf_path, 1);
214  es = env_set_create(NULL);
215  setenv_str(es, "SOFTHSM2_CONF", softhsm2_conf_path);
216  setenv_str(es, "GNUTLS_PIN", PIN);
217 
218  /* init the token using the temporary location as storage */
219  struct argv a = argv_new();
220  argv_printf(&a, "%s --init-token --free --label \"%s\" --so-pin %s --pin %s",
221  SOFTHSM2_UTIL_PATH, token_name, PIN, PIN);
222  assert_true(openvpn_execve_check(&a, es, 0, "Failed to initialize token"));
223 
224  /* Import certificates and keys in our test database into the token */
225  char cert[] = "cert_XXXXXX";
226  char key[] = "key_XXXXXX";
227  int cert_fd = mkstemp(cert);
228  int key_fd = mkstemp(key);
229  if (cert_fd < 0 || key_fd < 0)
230  {
231  fail_msg("make tmpfile for certificate or key data failed (error = %d)", errno);
232  }
233 
234  for (struct test_cert *c = certs; c->cert; c++)
235  {
236  /* fill-in the hash of the cert */
237  BIO *buf = BIO_new_mem_buf(c->cert, -1);
238  X509 *x509 = NULL;
239  if (buf)
240  {
241  x509 = PEM_read_bio_X509(buf, NULL, NULL, NULL);
242  BIO_free(buf);
243  }
244  assert_non_null(x509);
245  sha1_fingerprint(x509, c->hash, HASHSIZE);
246  X509_free(x509);
247 
248  /* we load all cert/key pairs even if expired as
249  * signing should still work */
250  assert_int_equal(write(cert_fd, c->cert, strlen(c->cert)), strlen(c->cert));
251  assert_int_equal(write(key_fd, c->key, strlen(c->key)), strlen(c->key));
252 
253  argv_free(&a);
254  a = argv_new();
255  /* Use numcerts+1 as a unique id of the object -- same id for matching cert and key */
256  argv_printf(&a, "%s --provider %s --load-certificate %s --label \"%s\" --id %08x --login --write",
257  P11TOOL_PATH, SOFTHSM2_MODULE_PATH, cert, c->friendly_name, num_certs+1);
258  assert_true(openvpn_execve_check(&a, es, 0, "Failed to upload certificate into token"));
259 
260  argv_free(&a);
261  a = argv_new();
262  argv_printf(&a, "%s --provider %s --load-privkey %s --label \"%s\" --id %08x --login --write",
263  P11TOOL_PATH, SOFTHSM2_MODULE_PATH, key, c->friendly_name, num_certs+1);
264  assert_true(openvpn_execve_check(&a, es, 0, "Failed to upload key into token"));
265 
266  assert_int_equal(ftruncate(cert_fd, 0), 0);
267  assert_int_equal(ftruncate(key_fd, 0), 0);
268  num_certs++;
269  }
270 
271  argv_free(&a);
272  close(cert_fd);
273  close(key_fd);
274  unlink(cert);
275  unlink(key);
276  return 0;
277 }
278 
279 static int
280 cleanup(void **state)
281 {
282  (void) state;
283  struct argv a = argv_new();
284 
285  argv_printf(&a, "%s --delete-token --token \"%s\"", SOFTHSM2_UTIL_PATH, token_name);
286  assert_true(openvpn_execve_check(&a, es, 0, "Failed to delete token"));
287  argv_free(&a);
288 
289  rmdir(softhsm2_tokens_path); /* this must be empty after delete token */
290  unlink(softhsm2_conf_path);
291  for (struct test_cert *c = certs; c->cert; c++)
292  {
293  free(c->p11_id);
294  c->p11_id = NULL;
295  }
297  return 0;
298 }
299 
300 static int
301 setup_pkcs11(void **state)
302 {
303 #if defined(HAVE_XKEY_PROVIDER)
304  /* Initialize providers in a way matching what OpenVPN core does */
305  tls_libctx = OSSL_LIB_CTX_new();
306  prov[0] = OSSL_PROVIDER_load(tls_libctx, "default");
307  OSSL_PROVIDER_add_builtin(tls_libctx, "ovpn.xkey", xkey_provider_init);
308  prov[1] = OSSL_PROVIDER_load(tls_libctx, "ovpn.xkey");
309  assert_non_null(prov[1]);
310 
311  /* set default propq as we do in ssl_openssl.c */
312  EVP_set_default_properties(tls_libctx, "?provider!=ovpn.xkey");
313 #endif
314  pkcs11_initialize(true, 0); /* protected auth enabled, pin-cache = 0 */
315  pkcs11_addProvider(SOFTHSM2_MODULE_PATH, false, 0, false);
316  return 0;
317 }
318 
319 static int
320 teardown_pkcs11(void **state)
321 {
322  pkcs11_terminate();
323 #if defined(HAVE_XKEY_PROVIDER)
324  for (size_t i = 0; i < SIZE(prov); i++)
325  {
326  if (prov[i])
327  {
328  OSSL_PROVIDER_unload(prov[i]);
329  prov[i] = NULL;
330  }
331  }
332  OSSL_LIB_CTX_free(tls_libctx);
333 #endif
334  return 0;
335 }
336 
337 static struct test_cert *
338 lookup_cert_byhash(uint8_t *sha1)
339 {
340  struct test_cert *c = certs;
341  while (c->cert && memcmp(c->hash, sha1, HASHSIZE))
342  {
343  c++;
344  }
345  return c->cert ? c : NULL;
346 }
347 
348 /* Enumerate usable items in the token and collect their pkcs11-ids */
349 static void
350 test_pkcs11_ids(void **state)
351 {
352  char *p11_id = NULL;
353  char *base64 = NULL;
354 
355  int n = pkcs11_management_id_count();
356  assert_int_equal(n, num_certs);
357 
358  for (int i = 0; i < n; i++)
359  {
360  X509 *x509 = NULL;
361  uint8_t sha1[HASHSIZE];
362 
363  /* We use the management interface functions as a quick way
364  * to enumerate objects available for private key operations */
365  if (!pkcs11_management_id_get(i, &p11_id, &base64))
366  {
367  fail_msg("Failed to get pkcs11-id for index (%d) from pkcs11-helper", i);
368  }
369  /* decode the base64 data and convert to X509 and get its sha1 fingerprint */
370  unsigned char *der = malloc(strlen(base64));
371  assert_non_null(der);
372  int derlen = openvpn_base64_decode(base64, der, strlen(base64));
373  free(base64);
374  assert_true(derlen > 0);
375 
376  const unsigned char *ppin = der; /* alias needed as d2i_X509 alters the pointer */
377  assert_non_null(d2i_X509(&x509, &ppin, derlen));
378  sha1_fingerprint(x509, sha1, HASHSIZE);
379  X509_free(x509);
380  free(der);
381 
382  /* Save the pkcs11-id of this ceritificate in our database */
383  struct test_cert *c = lookup_cert_byhash(sha1);
384  assert_non_null(c);
385  c->p11_id = p11_id; /* p11_id is freed in cleanup */
386  assert_memory_equal(c->hash, sha1, HASHSIZE);
387  }
388  /* check whether all certs in our db were found by pkcs11-helper*/
389  for (struct test_cert *c = certs; c->cert; c++)
390  {
391  if (!c->p11_id)
392  {
393  fail_msg("Certificate <%s> not enumerated by pkcs11-helper", c->friendly_name);
394  }
395  }
396 }
397 
398 /* For each available pkcs11-id, load it into an SSL_CTX
399  * and test signing with it.
400  */
401 static void
403 {
404  (void) state;
405  struct tls_root_ctx tls_ctx = {};
406  uint8_t sha1[HASHSIZE];
407  for (struct test_cert *c = certs; c->cert; c++)
408  {
409 #ifdef HAVE_XKEY_PROVIDER
410  tls_ctx.ctx = SSL_CTX_new_ex(tls_libctx, NULL, SSLv23_client_method());
411 #else
412  tls_ctx.ctx = SSL_CTX_new(SSLv23_client_method());
413 #endif
415  {
416  /* The management callback will return pkcs11_id_current as the
417  * selection. Set it here as the current certificate's p11_id
418  */
419  pkcs11_id_current = c->p11_id;
420  tls_ctx_use_pkcs11(&tls_ctx, 1, NULL);
421  }
422  else
423  {
424  /* directly use c->p11_id */
425  tls_ctx_use_pkcs11(&tls_ctx, 0, c->p11_id);
426  }
427 
428  /* check that the cert set in SSL_CTX is what we intended */
429  X509 *x509 = SSL_CTX_get0_certificate(tls_ctx.ctx);
430  assert_non_null(x509);
431  sha1_fingerprint(x509, sha1, HASHSIZE);
432  assert_memory_equal(sha1, c->hash, HASHSIZE);
433 
434  /* Test signing with the private key in SSL_CTX */
435  EVP_PKEY *pubkey = X509_get0_pubkey(x509);
436  EVP_PKEY *privkey = SSL_CTX_get0_privatekey(tls_ctx.ctx);
437  assert_non_null(pubkey);
438  assert_non_null(privkey);
439 #ifdef HAVE_XKEY_PROVIDER
440  /* this will exercise signing via pkcs11 backend */
441  assert_int_equal(digest_sign_verify(privkey, pubkey), 1);
442 #else
443  if (!SSL_CTX_check_private_key(tls_ctx.ctx))
444  {
445  fail_msg("Certificate and private key in ssl_ctx do not match for <%s>", c->friendly_name);
446  return;
447  }
448 #endif
449  SSL_CTX_free(tls_ctx.ctx);
450  }
451 }
452 
453 /* same test as test_tls_ctx_use_pkcs11, with id selected via management i/f */
454 static void
456 {
457  pkcs11_id_management = true;
459 }
460 
461 int
462 main(void)
463 {
465  const struct CMUnitTest tests[] = {
466  cmocka_unit_test_setup_teardown(test_pkcs11_ids, setup_pkcs11,
468  cmocka_unit_test_setup_teardown(test_tls_ctx_use_pkcs11, setup_pkcs11,
470  cmocka_unit_test_setup_teardown(test_tls_ctx_use_pkcs11__management, setup_pkcs11,
472  };
473  int ret = cmocka_run_group_tests_name("pkcs11_tests", tests, init, cleanup);
474 
475  return ret;
476 }
query_user_clear
void query_user_clear(void)
Wipes all data put into all of the query_user structs.
Definition: test_pkcs11.c:74
cert_data.h
cert2
static const char *const cert2
Definition: cert_data.h:65
openvpn_base64_decode
int openvpn_base64_decode(const char *str, void *data, int size)
Definition: base64.c:158
setup_pkcs11
static int setup_pkcs11(void **state)
Definition: test_pkcs11.c:301
cert1
static const char *const cert1
Definition: cert_data.h:39
x509_get_subject
char * x509_get_subject(openvpn_x509_cert_t *cert, struct gc_arena *gc)
Definition: test_pkcs11.c:69
pkcs11_id_current
static const char * pkcs11_id_current
Definition: test_pkcs11.c:132
run_command.h
HASHSIZE
#define HASHSIZE
Definition: test_pkcs11.c:44
key2
#define key2
Definition: cert_data.h:82
env_set_destroy
void env_set_destroy(struct env_set *es)
Definition: env_set.c:166
argv
Definition: argv.h:35
M_NONFATAL
#define M_NONFATAL
Definition: error.h:90
manage.h
es
struct env_set * es
Definition: test_pkcs11.c:133
hash
Definition: list.h:56
test_common.h
cname4
#define cname4
Definition: cert_data.h:164
key1
static const char *const key1
Definition: cert_data.h:56
init_cert_data
void init_cert_data(void)
Definition: test_pkcs11.c:137
argv_free
void argv_free(struct argv *a)
Frees all memory allocations allocated by the struct argv related functions.
Definition: argv.c:102
parse_line
int parse_line(const char *line, char **p, const int n, const char *file, const int line_num, int msglevel, struct gc_arena *gc)
Definition: test_pkcs11.c:62
xkey_common.h
test_cert::friendly_name
const char *const friendly_name
Definition: test_pkcs11.c:123
softhsm2_tokens_path
static char softhsm2_tokens_path[]
Definition: test_pkcs11.c:129
test_cert::p11_id
char * p11_id
Definition: test_pkcs11.c:125
key
Container for unidirectional cipher and HMAC key material.
Definition: crypto.h:149
sha1_fingerprint
static void sha1_fingerprint(X509 *x509, uint8_t *hash, int capacity)
Definition: test_pkcs11.c:177
openvpn_execve_check
int openvpn_execve_check(const struct argv *a, const struct env_set *es, const unsigned int flags, const char *error_message)
Definition: run_command.c:193
secure_memzero
static void secure_memzero(void *data, size_t len)
Securely zeroise memory.
Definition: buffer.h:414
certs
static struct test_cert certs[5]
write
@ write
Definition: interactive.c:219
SSL_CTX_new_ex
#define SSL_CTX_new_ex(libctx, propq, method)
Reduce SSL_CTX_new_ex() to SSL_CTX_new() for OpenSSL < 3.
Definition: openssl_compat.h:125
test_cert::cert
const char *const cert
Definition: test_pkcs11.c:119
teardown_pkcs11
static int teardown_pkcs11(void **state)
Definition: test_pkcs11.c:320
management
struct management * management
Definition: test_pkcs11.c:47
test_cert
Definition: test_pkcs11.c:117
crypto_print_openssl_errors
void crypto_print_openssl_errors(const unsigned int flags)
Retrieve any occurred OpenSSL errors and print those errors.
Definition: test_pkcs11.c:51
cname2
static const char *const cname2
Definition: cert_data.h:84
base64.h
cname3
static const char *const cname3
Definition: cert_data.h:138
test_cert::hash
uint8_t hash[HASHSIZE]
Definition: test_pkcs11.c:124
key3
static const char *const key3
Definition: cert_data.h:108
query_user_add
void query_user_add(char *prompt, size_t prompt_len, char *resp, size_t resp_len, bool echo)
Adds an item to ask the user for.
Definition: test_pkcs11.c:85
SIZE
#define SIZE(x)
Definition: basic.h:30
ssl.h
env_set_create
struct env_set * env_set_create(struct gc_arena *gc)
Definition: env_set.c:156
management_query_pk_sig
char * management_query_pk_sig(struct management *man, const char *b64_data, const char *algorithm)
Definition: test_pkcs11.c:102
test_pkcs11_ids
static void test_pkcs11_ids(void **state)
Definition: test_pkcs11.c:350
syshead.h
pkcs11.h
cname1
static const char *const cname1
Definition: cert_data.h:63
gc_arena
Garbage collection arena used to keep track of dynamically allocated memory.
Definition: buffer.h:116
setenv_str
void setenv_str(struct env_set *es, const char *name, const char *value)
Definition: env_set.c:283
PIN
#define PIN
Definition: test_pkcs11.c:43
init
static int init(void **state)
Definition: test_pkcs11.c:189
openvpn_unit_test_setup
static void openvpn_unit_test_setup(void)
Sets up the environment for unit tests like making both stderr and stdout non-buffered to avoid messa...
Definition: test_common.h:36
strncpynt
static void strncpynt(char *dest, const char *src, size_t maxlen)
Definition: buffer.h:361
env_set
Definition: env_set.h:42
openvpn_x509_cert_t
X509 openvpn_x509_cert_t
Definition: openvpn-plugin.h:40
key4
#define key4
Definition: cert_data.h:162
argv_new
struct argv argv_new(void)
Allocates a new struct argv and ensures it is initialised.
Definition: argv.c:88
token_name
#define token_name
Definition: test_pkcs11.c:42
get_user_pass_cr
bool get_user_pass_cr(struct user_pass *up, const char *auth_file, const char *prefix, const unsigned int flags, const char *unused)
Retrieves the user credentials from various sources depending on the flags.
Definition: test_pkcs11.c:152
argv_printf
bool argv_printf(struct argv *argres, const char *format,...)
printf() variant which populates a struct argv.
Definition: argv.c:440
digest_sign_verify
int digest_sign_verify(EVP_PKEY *privkey, EVP_PKEY *pubkey)
tls_root_ctx
Structure that wraps the TLS context.
Definition: ssl_mbedtls.h:106
main
int main(void)
Definition: test_pkcs11.c:462
management
Definition: manage.h:335
test_tls_ctx_use_pkcs11
static void test_tls_ctx_use_pkcs11(void **state)
Definition: test_pkcs11.c:402
GET_USER_PASS_PASSWORD_ONLY
#define GET_USER_PASS_PASSWORD_ONLY
Definition: misc.h:109
OSSL_PROVIDER
void OSSL_PROVIDER
Definition: openssl_compat.h:130
config.h
lookup_cert_byhash
static struct test_cert * lookup_cert_byhash(uint8_t *sha1)
Definition: test_pkcs11.c:338
tls_root_ctx::ctx
SSL_CTX * ctx
Definition: ssl_openssl.h:40
test_cert::cname
const char *const cname
Definition: test_pkcs11.c:121
tls_libctx
OSSL_LIB_CTX * tls_libctx
Definition: ssl_openssl.c:72
softhsm2_conf_path
static char softhsm2_conf_path[]
Definition: test_pkcs11.c:130
user_pass::password
char password[USER_PASS_LEN]
Definition: misc.h:72
query_user_exec_builtin
bool query_user_exec_builtin(void)
Executes a configured setup, using the built-in method for querying the user.
Definition: test_pkcs11.c:79
test_cert::key
const char *const key
Definition: test_pkcs11.c:120
purge_user_pass
void purge_user_pass(struct user_pass *up, const bool force)
Definition: test_pkcs11.c:95
test_cert::issuer
const char *const issuer
Definition: test_pkcs11.c:122
user_pass
Definition: misc.h:56
GET_USER_PASS_NEED_STR
#define GET_USER_PASS_NEED_STR
Definition: misc.h:112
msg
#define msg(flags,...)
Definition: error.h:144
pkcs11_id_management
static bool pkcs11_id_management
Definition: test_pkcs11.c:128
OSSL_LIB_CTX
void OSSL_LIB_CTX
Definition: openssl_compat.h:129
test_tls_ctx_use_pkcs11__management
static void test_tls_ctx_use_pkcs11__management(void **state)
Definition: test_pkcs11.c:455
num_certs
int num_certs
Definition: test_pkcs11.c:131
cert4
static const char *const cert4
Definition: cert_data.h:140
cert3
static const char *const cert3
Definition: cert_data.h:86
cleanup
static int cleanup(void **state)
Definition: test_pkcs11.c:280