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-2025 OpenVPN Inc <sales@openvpn.net>
9 * Copyright (C) 2010-2021 Fox Crypto B.V. <openvpn@foxcrypto.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 sigalg.op = "Sign";
188 }
189 else
190 {
191 return 0;
192 }
193 }
194
195 if (!strcmp(sigalg.keytype, "EC"))
196 {
197 msg(D_XKEY, "xkey_pkcs11h_sign: signing with EC key");
198 mech.mechanism = CKM_ECDSA;
199 }
200 else if (!strcmp(sigalg.keytype, "RSA"))
201 {
202 msg(D_XKEY, "xkey_pkcs11h_sign: signing with RSA key: padmode = %s", sigalg.padmode);
203 if (!strcmp(sigalg.padmode, "none"))
204 {
205 mech.mechanism = CKM_RSA_X_509;
206 }
207 else if (!strcmp(sigalg.padmode, "pss"))
208 {
209 mech.mechanism = CKM_RSA_PKCS_PSS;
210
211 if (!set_pss_params(&pss_params, sigalg, cert))
212 {
213 return 0;
214 }
215
216 mech.pParameter = &pss_params;
217 mech.ulParameterLen = sizeof(pss_params);
218 }
219 else if (!strcmp(sigalg.padmode, "pkcs1"))
220 {
221 /* CMA_RSA_PKCS needs pkcs1 encoded digest */
222
223 if (!encode_pkcs1(enc, &enc_len, sigalg.mdname, tbs, tbslen))
224 {
225 return 0;
226 }
227 tbs = enc;
228 tbslen = enc_len;
229 }
230 else /* should not happen */
231 {
232 msg(M_WARN, "PKCS#11: Unknown padmode <%s>", sigalg.padmode);
233 }
234 }
235 else
236 {
237 ASSERT(0); /* coding error -- we couldnt have created any such key */
238 }
239
240 if (CKR_OK != pkcs11h_certificate_signAny_ex(cert, &mech, tbs, tbslen, sig, siglen))
241 {
242 return 0;
243 }
244 if (strcmp(sigalg.keytype, "EC"))
245 {
246 return 1;
247 }
248
249 /* For EC keys, pkcs11 returns signature as r|s: convert to der encoded */
250 int derlen = ecdsa_bin2der(sig, (int)*siglen, siglen_max);
251
252 if (derlen <= 0)
253 {
254 return 0;
255 }
256 *siglen = derlen;
257
258 return 1;
259}
260
261/* wrapper for handle free */
262static void
263xkey_handle_free(void *handle)
264{
265 pkcs11h_certificate_freeCertificate(handle);
266}
267
268
279static int
280xkey_load_from_pkcs11h(pkcs11h_certificate_t certificate, struct tls_root_ctx *const ctx)
281{
282 int ret = 0;
283
284 X509 *x509 = pkcs11h_openssl_getX509(certificate);
285 if (!x509)
286 {
287 msg(M_WARN, "PKCS#11: Unable get x509 certificate object");
288 return 0;
289 }
290
291 EVP_PKEY *pubkey = X509_get0_pubkey(x509);
292
293 XKEY_PRIVKEY_FREE_fn *free_op = xkey_handle_free; /* it calls pkcs11h_..._freeCertificate() */
294 XKEY_EXTERNAL_SIGN_fn *sign_op = xkey_pkcs11h_sign;
295
296 EVP_PKEY *pkey = xkey_load_generic_key(tls_libctx, certificate, pubkey, sign_op, free_op);
297 if (!pkey)
298 {
299 msg(M_WARN, "PKCS#11: Failed to load private key into xkey provider");
300 goto cleanup;
301 }
302 /* provider took ownership of the pkcs11h certificate object -- do not free below */
303 certificate = NULL;
304
305 if (!SSL_CTX_use_cert_and_key(ctx->ctx, x509, pkey, NULL, 0))
306 {
308 msg(M_FATAL, "PKCS#11: Failed to set cert and private key for OpenSSL");
309 goto cleanup;
310 }
311 ret = 1;
312
313cleanup:
314 if (x509)
315 {
316 X509_free(x509);
317 }
318 if (pkey)
319 {
320 EVP_PKEY_free(pkey);
321 }
322 if (certificate)
323 {
324 pkcs11h_certificate_freeCertificate(certificate);
325 }
326 return ret;
327}
328#endif /* HAVE_XKEY_PROVIDER */
329
330int
331pkcs11_init_tls_session(pkcs11h_certificate_t certificate, struct tls_root_ctx *const ssl_ctx)
332{
333#ifdef HAVE_XKEY_PROVIDER
334 return (xkey_load_from_pkcs11h(certificate, ssl_ctx) == 0); /* inverts the return value */
335#else
336 int ret = 1;
337
338 X509 *x509 = NULL;
339 EVP_PKEY *evp = NULL;
340 pkcs11h_openssl_session_t openssl_session = NULL;
341
342 if ((openssl_session = pkcs11h_openssl_createSession(certificate)) == NULL)
343 {
344 msg(M_WARN, "PKCS#11: Cannot initialize openssl session");
345 goto cleanup;
346 }
347
348 /*
349 * Will be released by openssl_session
350 */
351 certificate = NULL;
352
353 if ((evp = pkcs11h_openssl_session_getEVP(openssl_session)) == NULL)
354 {
355 msg(M_WARN, "PKCS#11: Unable get evp object");
356 goto cleanup;
357 }
358
359 if ((x509 = pkcs11h_openssl_session_getX509(openssl_session)) == NULL)
360 {
361 msg(M_WARN, "PKCS#11: Unable get certificate object");
362 goto cleanup;
363 }
364
365 if (!SSL_CTX_use_PrivateKey(ssl_ctx->ctx, evp))
366 {
367 msg(M_WARN, "PKCS#11: Cannot set private key for openssl");
368 goto cleanup;
369 }
370
371 if (!SSL_CTX_use_certificate(ssl_ctx->ctx, x509))
372 {
374 msg(M_FATAL, "PKCS#11: Cannot set certificate for openssl");
375 goto cleanup;
376 }
377 ret = 0;
378
379cleanup:
380 /*
381 * Certificate freeing is usually handled by openssl_session.
382 * If something went wrong, creating the session we have to do it manually.
383 */
384 if (certificate != NULL)
385 {
386 pkcs11h_certificate_freeCertificate(certificate);
387 certificate = NULL;
388 }
389
390 /*
391 * openssl objects have reference
392 * count, so release them
393 */
394 X509_free(x509);
395 x509 = NULL;
396
397 EVP_PKEY_free(evp);
398 evp = NULL;
399
400 if (openssl_session != NULL)
401 {
402 pkcs11h_openssl_freeSession(openssl_session);
403 openssl_session = NULL;
404 }
405 return ret;
406#endif /* ifdef HAVE_XKEY_PROVIDER */
407}
408
409char *
410pkcs11_certificate_dn(pkcs11h_certificate_t certificate, struct gc_arena *gc)
411{
412 X509 *x509 = NULL;
413
414 char *dn = NULL;
415
416 if ((x509 = pkcs11h_openssl_getX509(certificate)) == NULL)
417 {
418 msg(M_FATAL, "PKCS#11: Cannot get X509");
419 goto cleanup;
420 }
421
422 dn = x509_get_subject(x509, gc);
423
424cleanup:
425 X509_free(x509);
426 x509 = NULL;
427
428 return dn;
429}
430
431int
432pkcs11_certificate_serial(pkcs11h_certificate_t certificate, char *serial, size_t serial_len)
433{
434 X509 *x509 = NULL;
435 BIO *bio = NULL;
436 int ret = 1;
437 int n;
438
439 if ((x509 = pkcs11h_openssl_getX509(certificate)) == NULL)
440 {
441 msg(M_FATAL, "PKCS#11: Cannot get X509");
442 goto cleanup;
443 }
444
445 if ((bio = BIO_new(BIO_s_mem())) == NULL)
446 {
447 msg(M_FATAL, "PKCS#11: Cannot create BIO");
448 goto cleanup;
449 }
450
451 i2a_ASN1_INTEGER(bio, X509_get_serialNumber(x509));
452 n = BIO_read(bio, serial, serial_len - 1);
453
454 if (n < 0)
455 {
456 serial[0] = '\x0';
457 }
458 else
459 {
460 serial[n] = 0;
461 }
462
463 ret = 0;
464
465cleanup:
466 X509_free(x509);
467 x509 = NULL;
468
469 return ret;
470}
471#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:88
#define M_NONFATAL
Definition error.h:89
#define msg(flags,...)
Definition error.h:150
#define ASSERT(x)
Definition error.h:217
#define M_WARN
Definition error.h:90
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:68
Garbage collection arena used to keep track of dynamically allocated memory.
Definition buffer.h:116
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:154