OpenVPN
mbedtls_compat.h
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) 2023-2026 Sentyron B.V. <openvpn@sentyron.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2
12 * as published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, see <https://www.gnu.org/licenses/>.
21 */
22
30#ifndef MBEDTLS_COMPAT_H_
31#define MBEDTLS_COMPAT_H_
32
33#include "syshead.h"
34
35#include "errlevel.h"
36
37#include <mbedtls/asn1.h>
38#include <mbedtls/pk.h>
39#include <mbedtls/version.h>
40
41#if MBEDTLS_VERSION_NUMBER < 0x04000000
42#include <mbedtls/ctr_drbg.h>
44#else
45#include <mbedtls/oid.h>
46#endif /* MBEDTLS_VERSION_NUMBER < 0x04000000 */
47
48#ifdef HAVE_PSA_CRYPTO_H
49#include <psa/crypto.h>
50#endif
51
52static inline void
54{
55#if defined(HAVE_PSA_CRYPTO_H) && defined(MBEDTLS_PSA_CRYPTO_C)
56 if (psa_crypto_init() != PSA_SUCCESS)
57 {
58 msg(M_FATAL, "mbedtls: psa_crypto_init() failed");
59 }
60#else
61 return;
62#endif
63}
64
65#if MBEDTLS_VERSION_NUMBER >= 0x04000000
66typedef struct
67{
68 const char *name;
69 uint16_t tls_id;
70} mbedtls_ecp_curve_info;
71
72static inline int
73mbedtls_oid_get_attr_short_name(const mbedtls_asn1_buf *oid, const char **desc)
74{
75 /* The relevant OIDs all have equal length. */
76 if (oid->tag != MBEDTLS_ASN1_OID || oid->len != strlen(MBEDTLS_OID_AT_CN))
77 {
78 *desc = NULL;
79 return -1;
80 }
81
82 if (memcmp(oid->p, MBEDTLS_OID_AT_CN, oid->len) == 0)
83 {
84 *desc = "CN";
85 }
86 else if (memcmp(oid->p, MBEDTLS_OID_AT_SUR_NAME, oid->len) == 0)
87 {
88 *desc = "SN";
89 }
90 else if (memcmp(oid->p, MBEDTLS_OID_AT_SERIAL_NUMBER, oid->len) == 0)
91 {
92 *desc = "serialNumber";
93 }
94 else if (memcmp(oid->p, MBEDTLS_OID_AT_COUNTRY, oid->len) == 0)
95 {
96 *desc = "C";
97 }
98 else if (memcmp(oid->p, MBEDTLS_OID_AT_LOCALITY, oid->len) == 0)
99 {
100 *desc = "L";
101 }
102 else if (memcmp(oid->p, MBEDTLS_OID_AT_STATE, oid->len) == 0)
103 {
104 *desc = "ST";
105 }
106 else if (memcmp(oid->p, MBEDTLS_OID_AT_ORGANIZATION, oid->len) == 0)
107 {
108 *desc = "O";
109 }
110 else if (memcmp(oid->p, MBEDTLS_OID_AT_ORG_UNIT, oid->len) == 0)
111 {
112 *desc = "OU";
113 }
114 else if (memcmp(oid->p, MBEDTLS_OID_AT_TITLE, oid->len) == 0)
115 {
116 *desc = "title";
117 }
118 else if (memcmp(oid->p, MBEDTLS_OID_AT_POSTAL_ADDRESS, oid->len) == 0)
119 {
120 *desc = "postalAddress";
121 }
122 else if (memcmp(oid->p, MBEDTLS_OID_AT_POSTAL_CODE, oid->len) == 0)
123 {
124 *desc = "postalCode";
125 }
126 else if (memcmp(oid->p, MBEDTLS_OID_AT_GIVEN_NAME, oid->len) == 0)
127 {
128 *desc = "GN";
129 }
130 else if (memcmp(oid->p, MBEDTLS_OID_AT_INITIALS, oid->len) == 0)
131 {
132 *desc = "initials";
133 }
134 else if (memcmp(oid->p, MBEDTLS_OID_AT_GENERATION_QUALIFIER, oid->len) == 0)
135 {
136 *desc = "generationQualifier";
137 }
138 else if (memcmp(oid->p, MBEDTLS_OID_AT_UNIQUE_IDENTIFIER, oid->len) == 0)
139 {
140 *desc = "uniqueIdentifier";
141 }
142 else if (memcmp(oid->p, MBEDTLS_OID_AT_DN_QUALIFIER, oid->len) == 0)
143 {
144 *desc = "dnQualifier";
145 }
146 else if (memcmp(oid->p, MBEDTLS_OID_AT_PSEUDONYM, oid->len) == 0)
147 {
148 *desc = "pseudonym";
149 }
150 else
151 {
152 *desc = NULL;
153 return -1;
154 }
155 return 0;
156}
157
158static inline int
159mbedtls_oid_get_extended_key_usage(const mbedtls_asn1_buf *oid, const char **desc)
160{
161 /* The relevant OIDs all have equal length. */
162 if (oid->tag != MBEDTLS_ASN1_OID || oid->len != strlen(MBEDTLS_OID_SERVER_AUTH))
163 {
164 *desc = NULL;
165 return -1;
166 }
167
168 if (memcmp(oid->p, MBEDTLS_OID_SERVER_AUTH, oid->len) == 0)
169 {
170 *desc = "TLS Web Server Authentication";
171 }
172 else if (memcmp(oid->p, MBEDTLS_OID_CLIENT_AUTH, oid->len) == 0)
173 {
174 *desc = "TLS Web Client Authentication";
175 }
176 else if (memcmp(oid->p, MBEDTLS_OID_CODE_SIGNING, oid->len) == 0)
177 {
178 *desc = "Code Signing";
179 }
180 else if (memcmp(oid->p, MBEDTLS_OID_EMAIL_PROTECTION, oid->len) == 0)
181 {
182 *desc = "E-mail Protection";
183 }
184 else if (memcmp(oid->p, MBEDTLS_OID_TIME_STAMPING, oid->len) == 0)
185 {
186 *desc = "Time Stamping";
187 }
188 else if (memcmp(oid->p, MBEDTLS_OID_OCSP_SIGNING, oid->len) == 0)
189 {
190 *desc = "OCSP Signing";
191 }
192 else
193 {
194 *desc = NULL;
195 return -1;
196 }
197
198 return 0;
199}
200#endif /* MBEDTLS_VERSION_NUMBER >= 0x04000000 */
201
202/* Some functions that operate on private keys use randomness to protect against
203 * side channels. In Mbed TLS 4, they automatically use the RNG in the PSA
204 * library, but in Mbed TLS 3, they require them as explicit arguments. */
205static inline int
206mbedtls_compat_pk_parse_key(mbedtls_pk_context *ctx,
207 const unsigned char *key, size_t keylen,
208 const unsigned char *pwd, size_t pwdlen)
209{
210#if MBEDTLS_VERSION_NUMBER >= 0x04000000
211 return mbedtls_pk_parse_key(ctx, key, keylen, pwd, pwdlen);
212#else
213 return mbedtls_pk_parse_key(ctx, key, keylen, pwd, pwdlen, mbedtls_ctr_drbg_random, rand_ctx_get());
214#endif /* MBEDTLS_VERSION_NUMBER < 0x04000000 */
215}
216
217static inline int
218mbedtls_compat_pk_parse_keyfile(mbedtls_pk_context *ctx, const char *path, const char *password)
219{
220#if MBEDTLS_VERSION_NUMBER >= 0x04000000
221 return mbedtls_pk_parse_keyfile(ctx, path, password);
222#else
223 return mbedtls_pk_parse_keyfile(ctx, path, password, mbedtls_ctr_drbg_random, rand_ctx_get());
224#endif /* MBEDTLS_VERSION_NUMBER < 0x04000000 */
225}
226
227static inline int
228mbedtls_compat_pk_check_pair(const mbedtls_pk_context *pub, const mbedtls_pk_context *prv)
229{
230#if MBEDTLS_VERSION_NUMBER >= 0x04000000
231 return mbedtls_pk_check_pair(pub, prv);
232#else
233 return mbedtls_pk_check_pair(pub, prv, mbedtls_ctr_drbg_random, rand_ctx_get());
234#endif /* MBEDTLS_VERSION_NUMBER < 0x04000000 */
235}
236
237#endif /* MBEDTLS_COMPAT_H_ */
Data Channel Cryptography mbed TLS-specific backend interface.
mbedtls_ctr_drbg_context * rand_ctx_get(void)
Returns a singleton instance of the mbed TLS random number generator.
static int mbedtls_compat_pk_parse_key(mbedtls_pk_context *ctx, const unsigned char *key, size_t keylen, const unsigned char *pwd, size_t pwdlen)
static void mbedtls_compat_psa_crypto_init(void)
static int mbedtls_compat_pk_check_pair(const mbedtls_pk_context *pub, const mbedtls_pk_context *prv)
static int mbedtls_compat_pk_parse_keyfile(mbedtls_pk_context *ctx, const char *path, const char *password)
#define M_FATAL
Definition error.h:90
#define msg(flags,...)
Definition error.h:152
Container for unidirectional cipher and HMAC key material.
Definition crypto.h:152