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-2023 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 
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 
42 static bool
43 pkcs11_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,
50  &cert_blob_size) != CKR_OK)
51  {
52  msg(M_WARN, "PKCS#11: Cannot retrieve certificate object size");
53  goto cleanup;
54  }
55 
56  check_malloc_return((cert_blob = calloc(1, cert_blob_size)));
57  if (pkcs11h_certificate_getCertificateBlob(pkcs11_cert, cert_blob,
58  &cert_blob_size) != CKR_OK)
59  {
60  msg(M_WARN, "PKCS#11: Cannot retrieve certificate object");
61  goto cleanup;
62  }
63 
64  if (!mbed_ok(mbedtls_x509_crt_parse(cert, cert_blob, cert_blob_size)))
65  {
66  msg(M_WARN, "PKCS#11: Could not parse certificate");
67  goto cleanup;
68  }
69 
70  ret = true;
71 cleanup:
72  free(cert_blob);
73  return ret;
74 }
75 
76 static bool
77 pkcs11_sign(void *pkcs11_cert, const void *src, size_t src_len,
78  void *dst, size_t dst_len)
79 {
80  return CKR_OK == pkcs11h_certificate_signAny(pkcs11_cert, CKM_RSA_PKCS,
81  src, src_len, dst, &dst_len);
82 }
83 
84 int
85 pkcs11_init_tls_session(pkcs11h_certificate_t certificate,
86  struct tls_root_ctx *const ssl_ctx)
87 {
88  ASSERT(NULL != ssl_ctx);
89 
90  ssl_ctx->pkcs11_cert = certificate;
91 
92  ALLOC_OBJ_CLEAR(ssl_ctx->crt_chain, mbedtls_x509_crt);
93  if (!pkcs11_get_x509_cert(certificate, ssl_ctx->crt_chain))
94  {
95  msg(M_WARN, "PKCS#11: Cannot initialize certificate");
96  return 1;
97  }
98 
99  if (tls_ctx_use_external_signing_func(ssl_ctx, pkcs11_sign, certificate))
100  {
101  msg(M_WARN, "PKCS#11: Cannot register signing function");
102  return 1;
103  }
104 
105  return 0;
106 }
107 
108 char *
109 pkcs11_certificate_dn(pkcs11h_certificate_t cert, struct gc_arena *gc)
110 {
111  char *ret = NULL;
112  mbedtls_x509_crt mbed_crt = { 0 };
113 
114  if (!pkcs11_get_x509_cert(cert, &mbed_crt))
115  {
116  msg(M_WARN, "PKCS#11: Cannot retrieve mbed TLS certificate object");
117  goto cleanup;
118  }
119 
120  if (!(ret = x509_get_subject(&mbed_crt, gc)))
121  {
122  msg(M_WARN, "PKCS#11: mbed TLS cannot parse subject");
123  goto cleanup;
124  }
125 
126 cleanup:
127  mbedtls_x509_crt_free(&mbed_crt);
128 
129  return ret;
130 }
131 
132 int
133 pkcs11_certificate_serial(pkcs11h_certificate_t cert, char *serial,
134  size_t serial_len)
135 {
136  int ret = 1;
137  mbedtls_x509_crt mbed_crt = { 0 };
138 
139  if (!pkcs11_get_x509_cert(cert, &mbed_crt))
140  {
141  msg(M_WARN, "PKCS#11: Cannot retrieve mbed TLS certificate object");
142  goto cleanup;
143  }
144 
145  if (mbedtls_x509_serial_gets(serial, serial_len, &mbed_crt.serial) < 0)
146  {
147  msg(M_WARN, "PKCS#11: mbed TLS cannot parse serial");
148  goto cleanup;
149  }
150 
151  ret = 0;
152 cleanup:
153  mbedtls_x509_crt_free(&mbed_crt);
154 
155  return ret;
156 }
157 #endif /* defined(ENABLE_PKCS11) && defined(ENABLE_CRYPTO_MBEDTLS) */
ssl_verify_backend.h
mbed_ok
#define mbed_ok(errval)
Check errval and log on error.
Definition: crypto_mbedtls.h:146
ASSERT
#define ASSERT(x)
Definition: error.h:201
M_WARN
#define M_WARN
Definition: error.h:97
pkcs11_backend.h
tls_root_ctx::crt_chain
mbedtls_x509_crt * crt_chain
Local Certificate chain.
Definition: ssl_mbedtls.h:110
errlevel.h
syshead.h
gc_arena
Garbage collection arena used to keep track of dynamically allocated memory.
Definition: buffer.h:116
tls_root_ctx
Structure that wraps the TLS context.
Definition: ssl_mbedtls.h:104
ALLOC_OBJ_CLEAR
#define ALLOC_OBJ_CLEAR(dptr, type)
Definition: buffer.h:1066
x509_get_subject
char * x509_get_subject(openvpn_x509_cert_t *cert, struct gc_arena *gc)
Definition: ssl_verify_openssl.c:367
config.h
check_malloc_return
static void check_malloc_return(void *p)
Definition: buffer.h:1109
msg
#define msg(flags,...)
Definition: error.h:150
tls_ctx_use_external_signing_func
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.
cleanup
static int cleanup(void **state)
Definition: test_pkcs11.c:280