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