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-2024 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, write to the Free Software Foundation, Inc.,
22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 */
24
30#ifdef HAVE_CONFIG_H
31#include "config.h"
32#endif
33
34#include "syshead.h"
35
36#if defined(ENABLE_PKCS11) && defined(ENABLE_CRYPTO_MBEDTLS)
37
38#include "errlevel.h"
39#include "pkcs11_backend.h"
40#include "ssl_verify_backend.h"
41#include <mbedtls/x509.h>
42
43static bool
44pkcs11_get_x509_cert(pkcs11h_certificate_t pkcs11_cert, mbedtls_x509_crt *cert)
45{
46 unsigned char *cert_blob = NULL;
47 size_t cert_blob_size = 0;
48 bool ret = false;
49
50 if (pkcs11h_certificate_getCertificateBlob(pkcs11_cert, NULL,
51 &cert_blob_size) != CKR_OK)
52 {
53 msg(M_WARN, "PKCS#11: Cannot retrieve certificate object size");
54 goto cleanup;
55 }
56
57 check_malloc_return((cert_blob = calloc(1, cert_blob_size)));
58 if (pkcs11h_certificate_getCertificateBlob(pkcs11_cert, cert_blob,
59 &cert_blob_size) != CKR_OK)
60 {
61 msg(M_WARN, "PKCS#11: Cannot retrieve certificate object");
62 goto cleanup;
63 }
64
65 if (!mbed_ok(mbedtls_x509_crt_parse(cert, cert_blob, cert_blob_size)))
66 {
67 msg(M_WARN, "PKCS#11: Could not parse certificate");
68 goto cleanup;
69 }
70
71 ret = true;
73 free(cert_blob);
74 return ret;
75}
76
77static bool
78pkcs11_sign(void *pkcs11_cert, const void *src, size_t src_len,
79 void *dst, size_t dst_len)
80{
81 return CKR_OK == pkcs11h_certificate_signAny(pkcs11_cert, CKM_RSA_PKCS,
82 src, src_len, dst, &dst_len);
83}
84
85int
86pkcs11_init_tls_session(pkcs11h_certificate_t certificate,
87 struct tls_root_ctx *const ssl_ctx)
88{
89 ASSERT(NULL != ssl_ctx);
90
91 ssl_ctx->pkcs11_cert = certificate;
92
93 ALLOC_OBJ_CLEAR(ssl_ctx->crt_chain, mbedtls_x509_crt);
94 if (!pkcs11_get_x509_cert(certificate, ssl_ctx->crt_chain))
95 {
96 msg(M_WARN, "PKCS#11: Cannot initialize certificate");
97 return 1;
98 }
99
100 if (tls_ctx_use_external_signing_func(ssl_ctx, pkcs11_sign, certificate))
101 {
102 msg(M_WARN, "PKCS#11: Cannot register signing function");
103 return 1;
104 }
105
106 return 0;
107}
108
109char *
110pkcs11_certificate_dn(pkcs11h_certificate_t cert, struct gc_arena *gc)
111{
112 char *ret = NULL;
113 mbedtls_x509_crt mbed_crt = { 0 };
114
115 if (!pkcs11_get_x509_cert(cert, &mbed_crt))
116 {
117 msg(M_WARN, "PKCS#11: Cannot retrieve mbed TLS certificate object");
118 goto cleanup;
119 }
120
121 if (!(ret = x509_get_subject(&mbed_crt, gc)))
122 {
123 msg(M_WARN, "PKCS#11: mbed TLS cannot parse subject");
124 goto cleanup;
125 }
126
127cleanup:
128 mbedtls_x509_crt_free(&mbed_crt);
129
130 return ret;
131}
132
133int
134pkcs11_certificate_serial(pkcs11h_certificate_t cert, char *serial,
135 size_t serial_len)
136{
137 int ret = 1;
138 mbedtls_x509_crt mbed_crt = { 0 };
139
140 if (!pkcs11_get_x509_cert(cert, &mbed_crt))
141 {
142 msg(M_WARN, "PKCS#11: Cannot retrieve mbed TLS certificate object");
143 goto cleanup;
144 }
145
146 if (mbedtls_x509_serial_gets(serial, serial_len, &mbed_crt.serial) < 0)
147 {
148 msg(M_WARN, "PKCS#11: mbed TLS cannot parse serial");
149 goto cleanup;
150 }
151
152 ret = 0;
153cleanup:
154 mbedtls_x509_crt_free(&mbed_crt);
155
156 return ret;
157}
158#endif /* defined(ENABLE_PKCS11) && defined(ENABLE_CRYPTO_MBEDTLS) */
static void check_malloc_return(void *p)
Definition buffer.h:1103
#define ALLOC_OBJ_CLEAR(dptr, type)
Definition buffer.h:1060
#define mbed_ok(errval)
Check errval and log on error.
#define msg(flags,...)
Definition error.h:144
#define ASSERT(x)
Definition error.h:195
#define M_WARN
Definition error.h:91
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:69
Garbage collection arena used to keep track of dynamically allocated memory.
Definition buffer.h:117
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:155