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
40#if MBEDTLS_VERSION_NUMBER < 0x04000000
41#include <mbedtls/ctr_drbg.h>
43#else
44#include <mbedtls/oid.h>
45#endif /* MBEDTLS_VERSION_NUMBER < 0x04000000 */
46
47#ifdef HAVE_PSA_CRYPTO_H
48#include <psa/crypto.h>
49#endif
50
51static inline void
53{
54#if defined(HAVE_PSA_CRYPTO_H) && defined(MBEDTLS_PSA_CRYPTO_C)
55 if (psa_crypto_init() != PSA_SUCCESS)
56 {
57 msg(M_FATAL, "mbedtls: psa_crypto_init() failed");
58 }
59#else
60 return;
61#endif
62}
63
64#if MBEDTLS_VERSION_NUMBER >= 0x04000000
65typedef struct
66{
67 const char *name;
68 uint16_t tls_id;
69} mbedtls_ecp_curve_info;
70
71static inline int
72mbedtls_oid_get_attr_short_name(const mbedtls_asn1_buf *oid, const char **desc)
73{
74 /* The relevant OIDs all have equal length. */
75 if (oid->tag != MBEDTLS_ASN1_OID || oid->len != strlen(MBEDTLS_OID_AT_CN))
76 {
77 *desc = NULL;
78 return -1;
79 }
80
81 if (memcmp(oid->p, MBEDTLS_OID_AT_CN, oid->len) == 0)
82 {
83 *desc = "CN";
84 }
85 else if (memcmp(oid->p, MBEDTLS_OID_AT_SUR_NAME, oid->len) == 0)
86 {
87 *desc = "SN";
88 }
89 else if (memcmp(oid->p, MBEDTLS_OID_AT_SERIAL_NUMBER, oid->len) == 0)
90 {
91 *desc = "serialNumber";
92 }
93 else if (memcmp(oid->p, MBEDTLS_OID_AT_COUNTRY, oid->len) == 0)
94 {
95 *desc = "C";
96 }
97 else if (memcmp(oid->p, MBEDTLS_OID_AT_LOCALITY, oid->len) == 0)
98 {
99 *desc = "L";
100 }
101 else if (memcmp(oid->p, MBEDTLS_OID_AT_STATE, oid->len) == 0)
102 {
103 *desc = "ST";
104 }
105 else if (memcmp(oid->p, MBEDTLS_OID_AT_ORGANIZATION, oid->len) == 0)
106 {
107 *desc = "O";
108 }
109 else if (memcmp(oid->p, MBEDTLS_OID_AT_ORG_UNIT, oid->len) == 0)
110 {
111 *desc = "OU";
112 }
113 else if (memcmp(oid->p, MBEDTLS_OID_AT_TITLE, oid->len) == 0)
114 {
115 *desc = "title";
116 }
117 else if (memcmp(oid->p, MBEDTLS_OID_AT_POSTAL_ADDRESS, oid->len) == 0)
118 {
119 *desc = "postalAddress";
120 }
121 else if (memcmp(oid->p, MBEDTLS_OID_AT_POSTAL_CODE, oid->len) == 0)
122 {
123 *desc = "postalCode";
124 }
125 else if (memcmp(oid->p, MBEDTLS_OID_AT_GIVEN_NAME, oid->len) == 0)
126 {
127 *desc = "GN";
128 }
129 else if (memcmp(oid->p, MBEDTLS_OID_AT_INITIALS, oid->len) == 0)
130 {
131 *desc = "initials";
132 }
133 else if (memcmp(oid->p, MBEDTLS_OID_AT_GENERATION_QUALIFIER, oid->len) == 0)
134 {
135 *desc = "generationQualifier";
136 }
137 else if (memcmp(oid->p, MBEDTLS_OID_AT_UNIQUE_IDENTIFIER, oid->len) == 0)
138 {
139 *desc = "uniqueIdentifier";
140 }
141 else if (memcmp(oid->p, MBEDTLS_OID_AT_DN_QUALIFIER, oid->len) == 0)
142 {
143 *desc = "dnQualifier";
144 }
145 else if (memcmp(oid->p, MBEDTLS_OID_AT_PSEUDONYM, oid->len) == 0)
146 {
147 *desc = "pseudonym";
148 }
149 else
150 {
151 *desc = NULL;
152 return -1;
153 }
154 return 0;
155}
156
157static inline int
158mbedtls_oid_get_extended_key_usage(const mbedtls_asn1_buf *oid, const char **desc)
159{
160 /* The relevant OIDs all have equal length. */
161 if (oid->tag != MBEDTLS_ASN1_OID || oid->len != strlen(MBEDTLS_OID_SERVER_AUTH))
162 {
163 *desc = NULL;
164 return -1;
165 }
166
167 if (memcmp(oid->p, MBEDTLS_OID_SERVER_AUTH, oid->len) == 0)
168 {
169 *desc = "TLS Web Server Authentication";
170 }
171 else if (memcmp(oid->p, MBEDTLS_OID_CLIENT_AUTH, oid->len) == 0)
172 {
173 *desc = "TLS Web Client Authentication";
174 }
175 else if (memcmp(oid->p, MBEDTLS_OID_CODE_SIGNING, oid->len) == 0)
176 {
177 *desc = "Code Signing";
178 }
179 else if (memcmp(oid->p, MBEDTLS_OID_EMAIL_PROTECTION, oid->len) == 0)
180 {
181 *desc = "E-mail Protection";
182 }
183 else if (memcmp(oid->p, MBEDTLS_OID_TIME_STAMPING, oid->len) == 0)
184 {
185 *desc = "Time Stamping";
186 }
187 else if (memcmp(oid->p, MBEDTLS_OID_OCSP_SIGNING, oid->len) == 0)
188 {
189 *desc = "OCSP Signing";
190 }
191 else
192 {
193 *desc = NULL;
194 return -1;
195 }
196
197 return 0;
198}
199#endif /* MBEDTLS_VERSION_NUMBER >= 0x04000000 */
200
201/* Some functions that operate on private keys use randomness to protect against
202 * side channels. In Mbed TLS 4, they automatically use the RNG in the PSA
203 * library, but in Mbed TLS 3, they require them as explicit arguments. */
204static inline int
205mbedtls_compat_pk_parse_key(mbedtls_pk_context *ctx,
206 const unsigned char *key, size_t keylen,
207 const unsigned char *pwd, size_t pwdlen)
208{
209#if MBEDTLS_VERSION_NUMBER >= 0x04000000
210 return mbedtls_pk_parse_key(ctx, key, keylen, pwd, pwdlen);
211#else
212 return mbedtls_pk_parse_key(ctx, key, keylen, pwd, pwdlen, mbedtls_ctr_drbg_random, rand_ctx_get());
213#endif /* MBEDTLS_VERSION_NUMBER < 0x04000000 */
214}
215
216static inline int
217mbedtls_compat_pk_parse_keyfile(mbedtls_pk_context *ctx, const char *path, const char *password)
218{
219#if MBEDTLS_VERSION_NUMBER >= 0x04000000
220 return mbedtls_pk_parse_keyfile(ctx, path, password);
221#else
222 return mbedtls_pk_parse_keyfile(ctx, path, password, mbedtls_ctr_drbg_random, rand_ctx_get());
223#endif /* MBEDTLS_VERSION_NUMBER < 0x04000000 */
224}
225
226static inline int
227mbedtls_compat_pk_check_pair(const mbedtls_pk_context *pub, const mbedtls_pk_context *prv)
228{
229#if MBEDTLS_VERSION_NUMBER >= 0x04000000
230 return mbedtls_pk_check_pair(pub, prv);
231#else
232 return mbedtls_pk_check_pair(pub, prv, mbedtls_ctr_drbg_random, rand_ctx_get());
233#endif /* MBEDTLS_VERSION_NUMBER < 0x04000000 */
234}
235
236#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