OpenVPN
pkcs11_mbedtls.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_MBEDTLS)
36
37#include "errlevel.h"
38#include "pkcs11_backend.h"
39#include "ssl_verify_backend.h"
40#include <mbedtls/x509.h>
41
42static bool
43pkcs11_get_x509_cert(pkcs11h_certificate_t pkcs11_cert, mbedtls_x509_crt *cert)
44{
45 unsigned char *cert_blob = NULL;
46 size_t cert_blob_size = 0;
47 bool ret = false;
48
49 if (pkcs11h_certificate_getCertificateBlob(pkcs11_cert, NULL, &cert_blob_size) != CKR_OK)
50 {
51 msg(M_WARN, "PKCS#11: Cannot retrieve certificate object size");
52 goto cleanup;
53 }
54
55 check_malloc_return((cert_blob = calloc(1, cert_blob_size)));
56 if (pkcs11h_certificate_getCertificateBlob(pkcs11_cert, cert_blob, &cert_blob_size) != CKR_OK)
57 {
58 msg(M_WARN, "PKCS#11: Cannot retrieve certificate object");
59 goto cleanup;
60 }
61
62 if (!mbed_ok(mbedtls_x509_crt_parse(cert, cert_blob, cert_blob_size)))
63 {
64 msg(M_WARN, "PKCS#11: Could not parse certificate");
65 goto cleanup;
66 }
67
68 ret = true;
70 free(cert_blob);
71 return ret;
72}
73
74static bool
75pkcs11_sign(void *pkcs11_cert, const void *src, size_t src_len, void *dst, size_t dst_len)
76{
77 return CKR_OK
78 == pkcs11h_certificate_signAny(pkcs11_cert, CKM_RSA_PKCS, src, src_len, dst, &dst_len);
79}
80
81int
82pkcs11_init_tls_session(pkcs11h_certificate_t certificate, struct tls_root_ctx *const ssl_ctx)
83{
84 ASSERT(NULL != ssl_ctx);
85
86 ssl_ctx->pkcs11_cert = certificate;
87
88 ALLOC_OBJ_CLEAR(ssl_ctx->crt_chain, mbedtls_x509_crt);
89 if (!pkcs11_get_x509_cert(certificate, ssl_ctx->crt_chain))
90 {
91 msg(M_WARN, "PKCS#11: Cannot initialize certificate");
92 return 1;
93 }
94
95 if (tls_ctx_use_external_signing_func(ssl_ctx, pkcs11_sign, certificate))
96 {
97 msg(M_WARN, "PKCS#11: Cannot register signing function");
98 return 1;
99 }
100
101 return 0;
102}
103
104char *
105pkcs11_certificate_dn(pkcs11h_certificate_t cert, struct gc_arena *gc)
106{
107 char *ret = NULL;
108 mbedtls_x509_crt mbed_crt = { 0 };
109
110 if (!pkcs11_get_x509_cert(cert, &mbed_crt))
111 {
112 msg(M_WARN, "PKCS#11: Cannot retrieve mbed TLS certificate object");
113 goto cleanup;
114 }
115
116 if (!(ret = x509_get_subject(&mbed_crt, gc)))
117 {
118 msg(M_WARN, "PKCS#11: mbed TLS cannot parse subject");
119 goto cleanup;
120 }
121
122cleanup:
123 mbedtls_x509_crt_free(&mbed_crt);
124
125 return ret;
126}
127
128int
129pkcs11_certificate_serial(pkcs11h_certificate_t cert, char *serial, size_t serial_len)
130{
131 int ret = 1;
132 mbedtls_x509_crt mbed_crt = { 0 };
133
134 if (!pkcs11_get_x509_cert(cert, &mbed_crt))
135 {
136 msg(M_WARN, "PKCS#11: Cannot retrieve mbed TLS certificate object");
137 goto cleanup;
138 }
139
140 if (mbedtls_x509_serial_gets(serial, serial_len, &mbed_crt.serial) < 0)
141 {
142 msg(M_WARN, "PKCS#11: mbed TLS cannot parse serial");
143 goto cleanup;
144 }
145
146 ret = 0;
147cleanup:
148 mbedtls_x509_crt_free(&mbed_crt);
149
150 return ret;
151}
152#endif /* defined(ENABLE_PKCS11) && defined(ENABLE_CRYPTO_MBEDTLS) */
static void check_malloc_return(void *p)
Definition buffer.h:1085
#define ALLOC_OBJ_CLEAR(dptr, type)
Definition buffer.h:1042
#define mbed_ok(errval)
Check errval and log on error.
#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.
int tls_ctx_use_external_signing_func(struct tls_root_ctx *ctx, external_sign_func sign_func, void *sign_ctx)
Call the supplied signing function to create a TLS signature during the TLS handshake.
Control Channel Verification Module library-specific backend interface.
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.
mbedtls_x509_crt * crt_chain
Local Certificate chain.
static int cleanup(void **state)
struct gc_arena gc
Definition test_ssl.c:154