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
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#if PKCS11H_VERSION > ((1 << 16) | (27 << 8)) /* version > 1.27 */
47
48/* Table linking OpenSSL digest NID with CKM and CKG constants in PKCS#11 */
49#define MD_TYPE(n) { NID_sha##n, CKM_SHA##n, CKG_MGF1_SHA##n }
50static const struct
51{
52 int nid;
53 unsigned long ckm_id;
54 unsigned long mgf_id;
55} mdtypes[] = { MD_TYPE(224),
56 MD_TYPE(256),
57 MD_TYPE(384),
58 MD_TYPE(512),
59 { NID_sha1, CKM_SHA_1, CKG_MGF1_SHA1 }, /* SHA_1 naming is an oddity */
60 { NID_undef, 0, 0 } };
61
62/* From sigalg, derive parameters for pss signature and fill in pss_params.
63 * Its of type CK_RSA_PKCS_PSS_PARAMS struct with three fields to be filled in:
64 * {enum hashAlg, enum mgf, ulong sLen}
65 * where hashAlg is CKM_SHA256 etc., mgf is CKG_MGF1_SHA256 etc.
66 */
67static int
68set_pss_params(CK_RSA_PKCS_PSS_PARAMS *pss_params, XKEY_SIGALG sigalg, pkcs11h_certificate_t cert)
69{
70 int ret = 0;
71 X509 *x509 = NULL;
72 EVP_PKEY *pubkey = NULL;
73
74 if ((x509 = pkcs11h_openssl_getX509(cert)) == NULL || (pubkey = X509_get0_pubkey(x509)) == NULL)
75 {
76 msg(M_WARN, "PKCS#11: Unable get public key");
77 goto cleanup;
78 }
79
80 /* map mdname to CKM and CKG constants for hash and mgf algorithms */
81 int i = 0;
82 int nid = OBJ_sn2nid(sigalg.mdname);
83 while (mdtypes[i].nid != NID_undef && mdtypes[i].nid != nid)
84 {
85 i++;
86 }
87 pss_params->hashAlg = mdtypes[i].ckm_id;
88 pss_params->mgf = mdtypes[i].mgf_id;
89
90 /* determine salt length */
91 const EVP_MD *md = EVP_get_digestbyname(sigalg.mdname);
92 if (!md)
93 {
94 msg(M_WARN,
95 "WARN: set_pss_params: EVP_get_digestbyname returned NULL "
96 "for mdname = <%s>",
97 sigalg.mdname);
98 goto cleanup;
99 }
100 int mdsize = EVP_MD_get_size(md);
101
102 int saltlen = -1;
103 if (!strcmp(sigalg.saltlen, "digest")) /* same as digest size */
104 {
105 saltlen = mdsize;
106 }
107 else if (!strcmp(sigalg.saltlen, "max")) /* maximum possible value */
108 {
109 saltlen = xkey_max_saltlen(EVP_PKEY_get_bits(pubkey), mdsize);
110 }
111
112 if (saltlen < 0 || pss_params->hashAlg == 0)
113 {
114 msg(M_WARN,
115 "WARN: invalid RSA_PKCS1_PSS parameters: saltlen = <%s> "
116 "mdname = <%s>.",
117 sigalg.saltlen, sigalg.mdname);
118 goto cleanup;
119 }
120 pss_params->sLen = (unsigned long)saltlen; /* saltlen >= 0 at this point */
121
122 msg(D_XKEY, "set_pss_params: sLen = %lu, hashAlg = %lu, mgf = %lu", pss_params->sLen,
123 pss_params->hashAlg, pss_params->mgf);
124
125 ret = 1;
126
127cleanup:
128 if (x509)
129 {
130 X509_free(x509);
131 }
132 return ret;
133}
134
135#else /* if PKCS11H_VERSION > ((1<<16) | (27<<8)) */
136
137/* Make set_pss_params a no-op that always succeeds */
138#define set_pss_params(...) (1)
139
140/* Use a wrapper for pkcs11h_certificate_signAny_ex() for versions < 1.28
141 * where its not available.
142 * We just call pkcs11h_certificate_signAny() unless the padding
143 * is PSS in which case we return an error.
144 */
145static CK_RV
146pkcs11h_certificate_signAny_ex(const pkcs11h_certificate_t cert, const CK_MECHANISM *mech,
147 const unsigned char *tbs, size_t tbslen, unsigned char *sig,
148 size_t *siglen)
149{
150 if (mech->mechanism == CKM_RSA_PKCS_PSS)
151 {
152 msg(M_NONFATAL, "PKCS#11: Error: PSS padding is not supported by "
153 "this version of pkcs11-helper library.");
154 return CKR_MECHANISM_INVALID;
155 }
156 return pkcs11h_certificate_signAny(cert, mech->mechanism, tbs, tbslen, sig, siglen);
157}
158#endif /* PKCS11H_VERSION > 1.27 */
159
165static int
166xkey_pkcs11h_sign(void *handle, unsigned char *sig, size_t *siglen, const unsigned char *tbs,
167 size_t tbslen, XKEY_SIGALG sigalg)
168{
169 pkcs11h_certificate_t cert = handle;
170 CK_MECHANISM mech = { CKM_RSA_PKCS, NULL, 0 }; /* default value */
171 CK_RSA_PKCS_PSS_PARAMS pss_params = { 0 };
172
173 unsigned char buf[EVP_MAX_MD_SIZE];
174 size_t buflen = 0;
175 size_t siglen_max = *siglen;
176
177 unsigned char enc[EVP_MAX_MD_SIZE + 32]; /* 32 bytes enough for DigestInfo header */
178 size_t enc_len = sizeof(enc);
179
180 if (!strcmp(sigalg.op, "DigestSign"))
181 {
182 msg(D_XKEY, "xkey_pkcs11h_sign: computing digest");
183 if (xkey_digest(tbs, tbslen, buf, &buflen, sigalg.mdname))
184 {
185 tbs = buf;
186 tbslen = (size_t)buflen;
187 }
188 else
189 {
190 return 0;
191 }
192 }
193
194 if (!strcmp(sigalg.keytype, "EC"))
195 {
196 msg(D_XKEY, "xkey_pkcs11h_sign: signing with EC key");
197 mech.mechanism = CKM_ECDSA;
198 }
199 else if (!strcmp(sigalg.keytype, "RSA"))
200 {
201 msg(D_XKEY, "xkey_pkcs11h_sign: signing with RSA key: padmode = %s", sigalg.padmode);
202 if (!strcmp(sigalg.padmode, "none"))
203 {
204 mech.mechanism = CKM_RSA_X_509;
205 }
206 else if (!strcmp(sigalg.padmode, "pss"))
207 {
208 mech.mechanism = CKM_RSA_PKCS_PSS;
209
210 if (!set_pss_params(&pss_params, sigalg, cert))
211 {
212 return 0;
213 }
214
215 mech.pParameter = &pss_params;
216 mech.ulParameterLen = sizeof(pss_params);
217 }
218 else if (!strcmp(sigalg.padmode, "pkcs1"))
219 {
220 /* CMA_RSA_PKCS needs pkcs1 encoded digest */
221
222 if (!encode_pkcs1(enc, &enc_len, sigalg.mdname, tbs, tbslen))
223 {
224 return 0;
225 }
226 tbs = enc;
227 tbslen = enc_len;
228 }
229 else /* should not happen */
230 {
231 msg(M_WARN, "PKCS#11: Unknown padmode <%s>", sigalg.padmode);
232 }
233 }
234 else
235 {
236 ASSERT(0); /* coding error -- we couldnt have created any such key */
237 }
238
239 if (CKR_OK != pkcs11h_certificate_signAny_ex(cert, &mech, tbs, tbslen, sig, siglen))
240 {
241 return 0;
242 }
243 if (strcmp(sigalg.keytype, "EC"))
244 {
245 return 1;
246 }
247
248 /* For EC keys, pkcs11 returns signature as r|s: convert to der encoded */
249 int derlen = ecdsa_bin2der(sig, (int)*siglen, siglen_max);
250
251 if (derlen <= 0)
252 {
253 return 0;
254 }
255 *siglen = derlen;
256
257 return 1;
258}
259
260/* wrapper for handle free */
261static void
262xkey_handle_free(void *handle)
263{
264 pkcs11h_certificate_freeCertificate(handle);
265}
266
267
278static int
279xkey_load_from_pkcs11h(pkcs11h_certificate_t certificate, struct tls_root_ctx *const ctx)
280{
281 int ret = 0;
282
283 X509 *x509 = pkcs11h_openssl_getX509(certificate);
284 if (!x509)
285 {
286 msg(M_WARN, "PKCS#11: Unable get x509 certificate object");
287 return 0;
288 }
289
290 EVP_PKEY *pubkey = X509_get0_pubkey(x509);
291
292 XKEY_PRIVKEY_FREE_fn *free_op = xkey_handle_free; /* it calls pkcs11h_..._freeCertificate() */
293 XKEY_EXTERNAL_SIGN_fn *sign_op = xkey_pkcs11h_sign;
294
295 EVP_PKEY *pkey = xkey_load_generic_key(tls_libctx, certificate, pubkey, sign_op, free_op);
296 if (!pkey)
297 {
298 msg(M_WARN, "PKCS#11: Failed to load private key into xkey provider");
299 goto cleanup;
300 }
301 /* provider took ownership of the pkcs11h certificate object -- do not free below */
302 certificate = NULL;
303
304 if (!SSL_CTX_use_cert_and_key(ctx->ctx, x509, pkey, NULL, 0))
305 {
307 msg(M_FATAL, "PKCS#11: Failed to set cert and private key for OpenSSL");
308 goto cleanup;
309 }
310 ret = 1;
311
312cleanup:
313 if (x509)
314 {
315 X509_free(x509);
316 }
317 if (pkey)
318 {
319 EVP_PKEY_free(pkey);
320 }
321 if (certificate)
322 {
323 pkcs11h_certificate_freeCertificate(certificate);
324 }
325 return ret;
326}
327#endif /* HAVE_XKEY_PROVIDER */
328
329int
330pkcs11_init_tls_session(pkcs11h_certificate_t certificate, struct tls_root_ctx *const ssl_ctx)
331{
332#ifdef HAVE_XKEY_PROVIDER
333 return (xkey_load_from_pkcs11h(certificate, ssl_ctx) == 0); /* inverts the return value */
334#else
335 int ret = 1;
336
337 X509 *x509 = NULL;
338 EVP_PKEY *evp = NULL;
339 pkcs11h_openssl_session_t openssl_session = NULL;
340
341 if ((openssl_session = pkcs11h_openssl_createSession(certificate)) == NULL)
342 {
343 msg(M_WARN, "PKCS#11: Cannot initialize openssl session");
344 goto cleanup;
345 }
346
347 /*
348 * Will be released by openssl_session
349 */
350 certificate = NULL;
351
352 if ((evp = pkcs11h_openssl_session_getEVP(openssl_session)) == NULL)
353 {
354 msg(M_WARN, "PKCS#11: Unable get evp object");
355 goto cleanup;
356 }
357
358 if ((x509 = pkcs11h_openssl_session_getX509(openssl_session)) == NULL)
359 {
360 msg(M_WARN, "PKCS#11: Unable get certificate object");
361 goto cleanup;
362 }
363
364 if (!SSL_CTX_use_PrivateKey(ssl_ctx->ctx, evp))
365 {
366 msg(M_WARN, "PKCS#11: Cannot set private key for openssl");
367 goto cleanup;
368 }
369
370 if (!SSL_CTX_use_certificate(ssl_ctx->ctx, x509))
371 {
373 msg(M_FATAL, "PKCS#11: Cannot set certificate for openssl");
374 goto cleanup;
375 }
376 ret = 0;
377
378cleanup:
379 /*
380 * Certificate freeing is usually handled by openssl_session.
381 * If something went wrong, creating the session we have to do it manually.
382 */
383 if (certificate != NULL)
384 {
385 pkcs11h_certificate_freeCertificate(certificate);
386 }
387
388 /*
389 * openssl objects have reference
390 * count, so release them
391 */
392 X509_free(x509);
393 x509 = NULL;
394
395 EVP_PKEY_free(evp);
396 evp = NULL;
397
398 if (openssl_session != NULL)
399 {
400 pkcs11h_openssl_freeSession(openssl_session);
401 }
402 return ret;
403#endif /* ifdef HAVE_XKEY_PROVIDER */
404}
405
406char *
407pkcs11_certificate_dn(pkcs11h_certificate_t certificate, struct gc_arena *gc)
408{
409 X509 *x509 = NULL;
410
411 char *dn = NULL;
412
413 if ((x509 = pkcs11h_openssl_getX509(certificate)) == NULL)
414 {
415 msg(M_FATAL, "PKCS#11: Cannot get X509");
416 goto cleanup;
417 }
418
419 dn = x509_get_subject(x509, gc);
420
421cleanup:
422 X509_free(x509);
423 x509 = NULL;
424
425 return dn;
426}
427
428int
429pkcs11_certificate_serial(pkcs11h_certificate_t certificate, char *serial, size_t serial_len)
430{
431 X509 *x509 = NULL;
432 BIO *bio = NULL;
433 int ret = 1;
434
435 if ((x509 = pkcs11h_openssl_getX509(certificate)) == NULL)
436 {
437 msg(M_FATAL, "PKCS#11: Cannot get X509");
438 goto cleanup;
439 }
440
441 if ((bio = BIO_new(BIO_s_mem())) == NULL)
442 {
443 msg(M_FATAL, "PKCS#11: Cannot create BIO");
444 goto cleanup;
445 }
446
447 i2a_ASN1_INTEGER(bio, X509_get_serialNumber(x509));
448 ASSERT(serial_len <= INT_MAX);
449 int n = BIO_read(bio, serial, (int)serial_len - 1);
450
451 if (n < 0)
452 {
453 serial[0] = '\x0';
454 }
455 else
456 {
457 serial[n] = 0;
458 }
459
460 ret = 0;
461
462cleanup:
463 X509_free(x509);
464 x509 = NULL;
465
466 return ret;
467}
468
469#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 M_NONFATAL
Definition error.h:91
#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)
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