OpenVPN
pkcs11_openssl.c
Go to the documentation of this file.
1/*
2 * OpenVPN -- An application to securely tunnel IP networks
3 * over a single TCP/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) 2002-2026 OpenVPN Inc <sales@openvpn.net>
9 * Copyright (C) 2010-2026 Sentyron B.V. <openvpn@sentyron.com>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2
13 * as published by the Free Software Foundation.
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, see <https://www.gnu.org/licenses/>.
22 */
23
28
29#ifdef HAVE_CONFIG_H
30#include "config.h"
31#endif
32
33#include "syshead.h"
34
35#if defined(ENABLE_PKCS11) && defined(ENABLE_CRYPTO_OPENSSL)
36
37#include "errlevel.h"
38#include "pkcs11_backend.h"
39#include "ssl_verify.h"
40#include "xkey_common.h"
41#include <pkcs11-helper-1.0/pkcs11h-openssl.h>
42
43#ifdef HAVE_XKEY_PROVIDER
44static XKEY_EXTERNAL_SIGN_fn xkey_pkcs11h_sign;
45
46/* Table linking OpenSSL digest NID with CKM and CKG constants in PKCS#11 */
47#define MD_TYPE(n) { NID_sha##n, CKM_SHA##n, CKG_MGF1_SHA##n }
48static const struct
49{
50 int nid;
51 unsigned long ckm_id;
52 unsigned long mgf_id;
53} mdtypes[] = { MD_TYPE(224),
54 MD_TYPE(256),
55 MD_TYPE(384),
56 MD_TYPE(512),
57 { NID_sha1, CKM_SHA_1, CKG_MGF1_SHA1 }, /* SHA_1 naming is an oddity */
58 { NID_undef, 0, 0 } };
59
60/* From sigalg, derive parameters for pss signature and fill in pss_params.
61 * Its of type CK_RSA_PKCS_PSS_PARAMS struct with three fields to be filled in:
62 * {enum hashAlg, enum mgf, ulong sLen}
63 * where hashAlg is CKM_SHA256 etc., mgf is CKG_MGF1_SHA256 etc.
64 */
65static int
66set_pss_params(CK_RSA_PKCS_PSS_PARAMS *pss_params, XKEY_SIGALG sigalg, pkcs11h_certificate_t cert)
67{
68 int ret = 0;
69 X509 *x509 = NULL;
70 EVP_PKEY *pubkey = NULL;
71
72 if ((x509 = pkcs11h_openssl_getX509(cert)) == NULL || (pubkey = X509_get0_pubkey(x509)) == NULL)
73 {
74 msg(M_WARN, "PKCS#11: Unable get public key");
75 goto cleanup;
76 }
77
78 /* map mdname to CKM and CKG constants for hash and mgf algorithms */
79 int i = 0;
80 int nid = OBJ_sn2nid(sigalg.mdname);
81 while (mdtypes[i].nid != NID_undef && mdtypes[i].nid != nid)
82 {
83 i++;
84 }
85 pss_params->hashAlg = mdtypes[i].ckm_id;
86 pss_params->mgf = mdtypes[i].mgf_id;
87
88 /* determine salt length */
89 const EVP_MD *md = EVP_get_digestbyname(sigalg.mdname);
90 if (!md)
91 {
92 msg(M_WARN,
93 "WARN: set_pss_params: EVP_get_digestbyname returned NULL "
94 "for mdname = <%s>",
95 sigalg.mdname);
96 goto cleanup;
97 }
98 int mdsize = EVP_MD_get_size(md);
99
100 int saltlen = -1;
101 if (!strcmp(sigalg.saltlen, "digest")) /* same as digest size */
102 {
103 saltlen = mdsize;
104 }
105 else if (!strcmp(sigalg.saltlen, "max")) /* maximum possible value */
106 {
107 saltlen = xkey_max_saltlen(EVP_PKEY_get_bits(pubkey), mdsize);
108 }
109
110 if (saltlen < 0 || pss_params->hashAlg == 0)
111 {
112 msg(M_WARN,
113 "WARN: invalid RSA_PKCS1_PSS parameters: saltlen = <%s> "
114 "mdname = <%s>.",
115 sigalg.saltlen, sigalg.mdname);
116 goto cleanup;
117 }
118 pss_params->sLen = (unsigned long)saltlen; /* saltlen >= 0 at this point */
119
120 msg(D_XKEY, "set_pss_params: sLen = %lu, hashAlg = %lu, mgf = %lu", pss_params->sLen,
121 pss_params->hashAlg, pss_params->mgf);
122
123 ret = 1;
124
125cleanup:
126 if (x509)
127 {
128 X509_free(x509);
129 }
130 return ret;
131}
132
138static int
139xkey_pkcs11h_sign(void *handle, unsigned char *sig, size_t *siglen, const unsigned char *tbs,
140 size_t tbslen, XKEY_SIGALG sigalg)
141{
142 pkcs11h_certificate_t cert = handle;
143 CK_MECHANISM mech = { CKM_RSA_PKCS, NULL, 0 }; /* default value */
144 CK_RSA_PKCS_PSS_PARAMS pss_params = { 0 };
145
146 unsigned char buf[EVP_MAX_MD_SIZE];
147 size_t buflen = 0;
148 size_t siglen_max = *siglen;
149
150 unsigned char enc[EVP_MAX_MD_SIZE + 32]; /* 32 bytes enough for DigestInfo header */
151 size_t enc_len = sizeof(enc);
152
153 if (!strcmp(sigalg.op, "DigestSign"))
154 {
155 msg(D_XKEY, "xkey_pkcs11h_sign: computing digest");
156 if (xkey_digest(tbs, tbslen, buf, &buflen, sigalg.mdname))
157 {
158 tbs = buf;
159 tbslen = (size_t)buflen;
160 }
161 else
162 {
163 return 0;
164 }
165 }
166
167 if (!strcmp(sigalg.keytype, "EC"))
168 {
169 msg(D_XKEY, "xkey_pkcs11h_sign: signing with EC key");
170 mech.mechanism = CKM_ECDSA;
171 }
172 else if (!strcmp(sigalg.keytype, "RSA"))
173 {
174 msg(D_XKEY, "xkey_pkcs11h_sign: signing with RSA key: padmode = %s", sigalg.padmode);
175 if (!strcmp(sigalg.padmode, "none"))
176 {
177 mech.mechanism = CKM_RSA_X_509;
178 }
179 else if (!strcmp(sigalg.padmode, "pss"))
180 {
181 mech.mechanism = CKM_RSA_PKCS_PSS;
182
183 if (!set_pss_params(&pss_params, sigalg, cert))
184 {
185 return 0;
186 }
187
188 mech.pParameter = &pss_params;
189 mech.ulParameterLen = sizeof(pss_params);
190 }
191 else if (!strcmp(sigalg.padmode, "pkcs1"))
192 {
193 /* CMA_RSA_PKCS needs pkcs1 encoded digest */
194
195 if (!encode_pkcs1(enc, &enc_len, sigalg.mdname, tbs, tbslen))
196 {
197 return 0;
198 }
199 tbs = enc;
200 tbslen = enc_len;
201 }
202 else /* should not happen */
203 {
204 msg(M_WARN, "PKCS#11: Unknown padmode <%s>", sigalg.padmode);
205 }
206 }
207 else
208 {
209 ASSERT(0); /* coding error -- we couldnt have created any such key */
210 }
211
212 if (CKR_OK != pkcs11h_certificate_signAny_ex(cert, &mech, tbs, tbslen, sig, siglen))
213 {
214 return 0;
215 }
216 if (strcmp(sigalg.keytype, "EC"))
217 {
218 return 1;
219 }
220
221 /* For EC keys, pkcs11 returns signature as r|s: convert to der encoded */
222 int derlen = ecdsa_bin2der(sig, (int)*siglen, siglen_max);
223
224 if (derlen <= 0)
225 {
226 return 0;
227 }
228 *siglen = derlen;
229
230 return 1;
231}
232
233/* wrapper for handle free */
234static void
235xkey_handle_free(void *handle)
236{
237 pkcs11h_certificate_freeCertificate(handle);
238}
239
240
251static int
252xkey_load_from_pkcs11h(pkcs11h_certificate_t certificate, struct tls_root_ctx *const ctx)
253{
254 int ret = 0;
255
256 X509 *x509 = pkcs11h_openssl_getX509(certificate);
257 if (!x509)
258 {
259 msg(M_WARN, "PKCS#11: Unable get x509 certificate object");
260 return 0;
261 }
262
263 EVP_PKEY *pubkey = X509_get0_pubkey(x509);
264
265 XKEY_PRIVKEY_FREE_fn *free_op = xkey_handle_free; /* it calls pkcs11h_..._freeCertificate() */
266 XKEY_EXTERNAL_SIGN_fn *sign_op = xkey_pkcs11h_sign;
267
268 EVP_PKEY *pkey = xkey_load_generic_key(tls_libctx, certificate, pubkey, sign_op, free_op);
269 if (!pkey)
270 {
271 msg(M_WARN, "PKCS#11: Failed to load private key into xkey provider");
272 goto cleanup;
273 }
274 /* provider took ownership of the pkcs11h certificate object -- do not free below */
275 certificate = NULL;
276
277 if (!SSL_CTX_use_cert_and_key(ctx->ctx, x509, pkey, NULL, 0))
278 {
280 msg(M_FATAL, "PKCS#11: Failed to set cert and private key for OpenSSL");
281 goto cleanup;
282 }
283 ret = 1;
284
285cleanup:
286 if (x509)
287 {
288 X509_free(x509);
289 }
290 if (pkey)
291 {
292 EVP_PKEY_free(pkey);
293 }
294 if (certificate)
295 {
296 pkcs11h_certificate_freeCertificate(certificate);
297 }
298 return ret;
299}
300#endif /* HAVE_XKEY_PROVIDER */
301
302int
303pkcs11_init_tls_session(pkcs11h_certificate_t certificate, struct tls_root_ctx *const ssl_ctx)
304{
305#ifdef HAVE_XKEY_PROVIDER
306 return (xkey_load_from_pkcs11h(certificate, ssl_ctx) == 0); /* inverts the return value */
307#else
308 int ret = 1;
309
310 X509 *x509 = NULL;
311 EVP_PKEY *evp = NULL;
312 pkcs11h_openssl_session_t openssl_session = NULL;
313
314 if ((openssl_session = pkcs11h_openssl_createSession(certificate)) == NULL)
315 {
316 msg(M_WARN, "PKCS#11: Cannot initialize openssl session");
317 goto cleanup;
318 }
319
320 /*
321 * Will be released by openssl_session
322 */
323 certificate = NULL;
324
325 if ((evp = pkcs11h_openssl_session_getEVP(openssl_session)) == NULL)
326 {
327 msg(M_WARN, "PKCS#11: Unable get evp object");
328 goto cleanup;
329 }
330
331 if ((x509 = pkcs11h_openssl_session_getX509(openssl_session)) == NULL)
332 {
333 msg(M_WARN, "PKCS#11: Unable get certificate object");
334 goto cleanup;
335 }
336
337 if (!SSL_CTX_use_PrivateKey(ssl_ctx->ctx, evp))
338 {
339 msg(M_WARN, "PKCS#11: Cannot set private key for openssl");
340 goto cleanup;
341 }
342
343 if (!SSL_CTX_use_certificate(ssl_ctx->ctx, x509))
344 {
346 msg(M_FATAL, "PKCS#11: Cannot set certificate for openssl");
347 goto cleanup;
348 }
349 ret = 0;
350
351cleanup:
352 /*
353 * Certificate freeing is usually handled by openssl_session.
354 * If something went wrong, creating the session we have to do it manually.
355 */
356 if (certificate != NULL)
357 {
358 pkcs11h_certificate_freeCertificate(certificate);
359 }
360
361 /*
362 * openssl objects have reference
363 * count, so release them
364 */
365 X509_free(x509);
366 x509 = NULL;
367
368 EVP_PKEY_free(evp);
369 evp = NULL;
370
371 if (openssl_session != NULL)
372 {
373 pkcs11h_openssl_freeSession(openssl_session);
374 }
375 return ret;
376#endif /* ifdef HAVE_XKEY_PROVIDER */
377}
378
379char *
380pkcs11_certificate_dn(pkcs11h_certificate_t certificate, struct gc_arena *gc)
381{
382 X509 *x509 = NULL;
383
384 char *dn = NULL;
385
386 if ((x509 = pkcs11h_openssl_getX509(certificate)) == NULL)
387 {
388 msg(M_FATAL, "PKCS#11: Cannot get X509");
389 goto cleanup;
390 }
391
392 dn = x509_get_subject(x509, gc);
393
394cleanup:
395 X509_free(x509);
396 x509 = NULL;
397
398 return dn;
399}
400
401int
402pkcs11_certificate_serial(pkcs11h_certificate_t certificate, char *serial, size_t serial_len)
403{
404 X509 *x509 = NULL;
405 BIO *bio = NULL;
406 int ret = 1;
407
408 if ((x509 = pkcs11h_openssl_getX509(certificate)) == NULL)
409 {
410 msg(M_FATAL, "PKCS#11: Cannot get X509");
411 goto cleanup;
412 }
413
414 if ((bio = BIO_new(BIO_s_mem())) == NULL)
415 {
416 msg(M_FATAL, "PKCS#11: Cannot create BIO");
417 goto cleanup;
418 }
419
420 i2a_ASN1_INTEGER(bio, X509_get_serialNumber(x509));
421 ASSERT(serial_len <= INT_MAX);
422 int n = BIO_read(bio, serial, (int)serial_len - 1);
423
424 if (n < 0)
425 {
426 serial[0] = '\x0';
427 }
428 else
429 {
430 serial[n] = 0;
431 }
432
433 ret = 0;
434
435cleanup:
436 X509_free(x509);
437 x509 = NULL;
438
439 return ret;
440}
441
442#endif /* defined(ENABLE_PKCS11) && defined(ENABLE_OPENSSL) */
void crypto_print_openssl_errors(const unsigned int flags)
Retrieve any occurred OpenSSL errors and print those errors.
#define D_XKEY
Definition errlevel.h:116
#define M_FATAL
Definition error.h:90
#define msg(flags,...)
Definition error.h:152
#define ASSERT(x)
Definition error.h:221
#define M_WARN
Definition error.h:92
PKCS #11 SSL library-specific backend.
OSSL_LIB_CTX * tls_libctx
Definition ssl_openssl.c:78
Control Channel Verification Module.
char * x509_get_subject(openvpn_x509_cert_t *cert, struct gc_arena *gc)
Definition test_pkcs11.c:70
Garbage collection arena used to keep track of dynamically allocated memory.
Definition buffer.h:127
Structure that wraps the TLS context.
SSL_CTX * ctx
Definition ssl_openssl.h:41
static int cleanup(void **state)
struct gc_arena gc
Definition test_ssl.c:122