1 /*
2 * SSL/TLS interface functions for mbed TLS
3 *
4 * SPDX-FileCopyrightText: 2022 Glenn Strauss <gstrauss@gluelogic.com>
5 * SPDX-License-Identifier: BSD-3-Clause
6 *
7 * This software may be distributed under the terms of the BSD license.
8 * See README for more details.
9 *
10 * template: src/crypto/tls_none.c
11 * reference: src/crypto/tls_*.c
12 *
13 * Known Limitations:
14 * - no TLSv1.3 (not available in mbedtls 2.x; experimental in mbedtls 3.x)
15 * - no OCSP (not yet available in mbedtls)
16 * - mbedtls does not support all certificate encodings used by hwsim tests
17 * PCKS#5 v1.5
18 * PCKS#12
19 * DH DSA
20 * - EAP-FAST, EAP-TEAP session ticket support not implemented in tls_mbedtls.c
21 * - mbedtls does not currently provide way to set an attribute in a CSR
22 * https://github.com/Mbed-TLS/mbedtls/issues/4886
23 * so tests/hwsim dpp_enterprise tests fail
24 * - DPP2 not supported
25 * PKCS#7 parsing is not supported in mbedtls
26 * See crypto_mbedtls.c:crypto_pkcs7_get_certificates() comments
27 * - DPP3 not supported
28 * hpke_base_seal() and hpke_base_seal() not implemented in crypto_mbedtls.c
29 *
30 * Status:
31 * - code written to be compatible with mbedtls 2.x and mbedtls 3.x
32 * (currently requires mbedtls >= 2.27.0 for mbedtls_mpi_random())
33 * (currently requires mbedtls >= 2.18.0 for mbedtls_ssl_tls_prf())
34 * - builds with tests/build/build-wpa_supplicant-mbedtls.config
35 * - passes all tests/ crypto module tests (incomplete coverage)
36 * ($ cd tests; make clean; make -j 4 run-tests CONFIG_TLS=mbedtls)
37 * - passes almost all tests/hwsim tests
38 * (hwsim tests skipped for missing features)
39 *
40 * RFE:
41 * - EAP-FAST, EAP-TEAP session ticket support not implemented in tls_mbedtls.c
42 * - client/server session resumption, and/or save client session ticket
43 */
44
45 #include "includes.h"
46 #include "utils/common.h"
47
48 #ifndef CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_NONE
49
50 #include <mbedtls/version.h>
51 #include <mbedtls/ctr_drbg.h>
52 #include <mbedtls/error.h>
53 #include <mbedtls/oid.h>
54 #include <mbedtls/pem.h>
55 #include <mbedtls/platform.h> /* mbedtls_calloc() mbedtls_free() */
56 #include <mbedtls/platform_util.h> /* mbedtls_platform_zeroize() */
57 #include <mbedtls/ssl.h>
58 #include <mbedtls/ssl_ticket.h>
59 #include <mbedtls/x509.h>
60 #include <mbedtls/x509_crt.h>
61
62 extern int (*hostap_rng_fn)(void*, unsigned char*, size_t);
63 extern void* hostap_rng_ctx(void);
64
65 #ifdef MBEDTLS_DEBUG_C
66 #define DEBUG_THRESHOLD 4
67 #include <mbedtls/debug.h>
68 #ifdef __ZEPHYR__
69 #define PRINTF printk
70 #endif
71 #define tls_mbedtls_d(...) PRINTF("tls_mbedtls", ##__VA_ARGS__)
72 #else
73 #define tls_mbedtls_d(...)
74 #endif /* MBEDTLS_DEBUG_C */
75
76 #if MBEDTLS_VERSION_NUMBER >= 0x02040000 /* mbedtls 2.4.0 */
77 #include <mbedtls/net_sockets.h>
78 #else
79 #include <mbedtls/net.h>
80 #endif
81
82 #if MBEDTLS_VERSION_NUMBER < 0x03020000 /* mbedtls 3.2.0 */
83 #define mbedtls_ssl_get_ciphersuite_id_from_ssl(ssl) \
84 ((ssl)->MBEDTLS_PRIVATE(session) ? (ssl)->MBEDTLS_PRIVATE(session)->MBEDTLS_PRIVATE(ciphersuite) : 0)
85 #define mbedtls_ssl_ciphersuite_get_name(info) (info)->MBEDTLS_PRIVATE(name)
86 #endif
87
88 #include "crypto.h" /* sha256_vector() */
89 #include "tls.h"
90
91 #ifndef SHA256_DIGEST_LENGTH
92 #define SHA256_DIGEST_LENGTH 32
93 #endif
94
95 #ifndef MBEDTLS_EXPKEY_FIXED_SECRET_LEN
96 #define MBEDTLS_EXPKEY_FIXED_SECRET_LEN 48
97 #endif
98
99 #ifndef MBEDTLS_EXPKEY_RAND_LEN
100 #define MBEDTLS_EXPKEY_RAND_LEN 32
101 #endif
102
103 #if MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.0.0 */
104 static mbedtls_ssl_export_keys_t tls_connection_export_keys_cb;
105 #elif MBEDTLS_VERSION_NUMBER >= 0x02120000 /* mbedtls 2.18.0 */
106 static mbedtls_ssl_export_keys_ext_t tls_connection_export_keys_cb;
107 #else /*(not implemented; return error)*/
108 #define mbedtls_ssl_tls_prf(a, b, c, d, e, f, g, h) (-1)
109 typedef mbedtls_tls_prf_types int;
110 #endif
111
112 /* hostapd/wpa_supplicant provides forced_memzero(),
113 * but prefer mbedtls_platform_zeroize() */
114 #define forced_memzero(ptr, sz) mbedtls_platform_zeroize(ptr, sz)
115
116 /* much of fine-grained certificate subject matching (300+ LoC) could probably
117 * be replaced by sending a DN hint with ServerHello Certificate Request, and
118 * then checking the client cert against the DN hint in certificate verify_cb.
119 * Comment out to disable feature and remove ~3k from binary .text segment */
120 #define TLS_MBEDTLS_CERT_VERIFY_EXTMATCH
121 #define TLS_MBEDTLS_CERT_DISABLE_KEY_USAGE_CHECK
122
123 #if defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) || defined(EAP_SERVER_FAST) || defined(EAP_TEAP) || \
124 defined(EAP_SERVER_TEAP)
125 #ifdef MBEDTLS_SSL_SESSION_TICKETS
126 #ifdef MBEDTLS_SSL_TICKET_C
127 #define TLS_MBEDTLS_SESSION_TICKETS
128 #if defined(EAP_TEAP) || defined(EAP_SERVER_TEAP)
129 #define TLS_MBEDTLS_EAP_TEAP
130 #endif
131 #if !defined(CONFIG_FIPS) /* EAP-FAST keys cannot be exported in FIPS mode */
132 #if defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) || defined(EAP_SERVER_FAST)
133 #define TLS_MBEDTLS_EAP_FAST
134 #endif
135 #endif
136 #endif
137 #endif
138 #endif
139
140 struct tls_conf
141 {
142 mbedtls_ssl_config conf;
143
144 unsigned int verify_peer : 1;
145 unsigned int verify_depth0_only : 1;
146 unsigned int check_crl : 2; /*(needs :2 bits for 0, 1, 2)*/
147 unsigned int check_crl_strict : 1; /*(needs :1 bit for 0, 1)*/
148 unsigned int ca_cert_probe : 1;
149 unsigned int has_ca_cert : 1;
150 unsigned int has_client_cert : 1;
151 unsigned int has_private_key : 1;
152 unsigned int suiteb128 : 1;
153 unsigned int suiteb192 : 1;
154 mbedtls_x509_crl *crl;
155 mbedtls_x509_crt ca_cert;
156 mbedtls_x509_crt client_cert;
157 mbedtls_pk_context private_key;
158
159 uint32_t refcnt;
160
161 unsigned int flags;
162 #ifdef TLS_MBEDTLS_CERT_VERIFY_EXTMATCH
163 char *subject_match;
164 char *altsubject_match;
165 char *suffix_match;
166 char *domain_match;
167 char *check_cert_subject;
168 #endif
169 u8 ca_cert_hash[SHA256_DIGEST_LENGTH];
170
171 int *ciphersuites; /* list of ciphersuite ids for mbedtls_ssl_config */
172 #if MBEDTLS_VERSION_NUMBER < 0x03010000 /* mbedtls 3.1.0 */
173 mbedtls_ecp_group_id *curves;
174 #else
175 uint16_t *curves; /* list of curve ids for mbedtls_ssl_config */
176 #endif
177 };
178
179 struct tls_global
180 {
181 struct tls_conf *tls_conf;
182 char *ocsp_stapling_response;
183 mbedtls_ctr_drbg_context *ctr_drbg; /*(see crypto_mbedtls.c)*/
184 #ifdef MBEDTLS_SSL_SESSION_TICKETS
185 mbedtls_ssl_ticket_context ticket_ctx;
186 #endif
187 char *ca_cert_file;
188 struct os_reltime crl_reload_previous;
189 unsigned int crl_reload_interval;
190 uint32_t refcnt;
191 struct tls_config init_conf;
192 };
193
194 static struct tls_global tls_ctx_global;
195
196 struct tls_connection
197 {
198 struct tls_conf *tls_conf;
199 struct wpabuf *push_buf;
200 struct wpabuf *pull_buf;
201 size_t pull_buf_offset;
202
203 unsigned int established : 1;
204 unsigned int resumed : 1;
205 unsigned int verify_peer : 1;
206 unsigned int is_server : 1;
207
208 mbedtls_ssl_context ssl;
209
210 mbedtls_tls_prf_types tls_prf_type;
211 size_t expkey_keyblock_size;
212 size_t expkey_secret_len;
213 #if MBEDTLS_VERSION_NUMBER < 0x03000000 /* mbedtls 3.0.0 */
214 unsigned char expkey_secret[MBEDTLS_EXPKEY_FIXED_SECRET_LEN];
215 #else
216 unsigned char expkey_secret[48];
217 #endif
218 unsigned char expkey_randbytes[MBEDTLS_EXPKEY_RAND_LEN * 2];
219
220 int read_alerts, write_alerts, failed;
221
222 #ifdef TLS_MBEDTLS_SESSION_TICKETS
223 tls_session_ticket_cb session_ticket_cb;
224 void *session_ticket_cb_ctx;
225 unsigned char *clienthello_session_ticket;
226 size_t clienthello_session_ticket_len;
227 #endif
228 char *peer_subject; /* peer subject info for authenticated peer */
229 struct wpabuf *success_data;
230 };
231
232 #ifndef __has_attribute
233 #define __has_attribute(x) 0
234 #endif
235
236 #ifndef __GNUC_PREREQ
237 #define __GNUC_PREREQ(maj, min) 0
238 #endif
239
240 #ifndef __attribute_cold__
241 #if __has_attribute(cold) || __GNUC_PREREQ(4, 3)
242 #define __attribute_cold__ __attribute__((__cold__))
243 #else
244 #define __attribute_cold__
245 #endif
246 #endif
247
248 #ifndef __attribute_noinline__
249 #if __has_attribute(noinline) || __GNUC_PREREQ(3, 1)
250 #define __attribute_noinline__ __attribute__((__noinline__))
251 #else
252 #define __attribute_noinline__
253 #endif
254 #endif
255
emsg(int level,const char * const msg)256 __attribute_cold__ __attribute_noinline__ static void emsg(int level, const char *const msg)
257 {
258 wpa_printf(level, "MTLS: %s", msg);
259 }
260
emsgrc(int level,const char * const msg,int rc)261 __attribute_cold__ __attribute_noinline__ static void emsgrc(int level, const char *const msg, int rc)
262 {
263 #ifdef MBEDTLS_ERROR_C
264 /* error logging convenience function that decodes mbedtls result codes */
265 char buf[256];
266 mbedtls_strerror(rc, buf, sizeof(buf));
267 wpa_printf(level, "MTLS: %s: %s (-0x%04x)", msg, buf, -rc);
268 #else
269 wpa_printf(level, "MTLS: %s: (-0x%04x)", msg, -rc);
270 #endif
271 }
272
273 #define elog(rc, msg) emsgrc(MSG_ERROR, (msg), (rc))
274 #define ilog(rc, msg) emsgrc(MSG_INFO, (msg), (rc))
275
276 #ifdef MBEDTLS_DEBUG_C
277 static void (*g_f_dbg)(void *, int, const char *, int, const char *);
278
279 #ifdef __ICCARM__
280 #define PATH_SEPARATOR '\\'
281 #else
282 #define PATH_SEPARATOR '/'
283 #endif /* __ICCARM__ */
284
285 /*
286 * This function will return basename of filename i.e.
287 * it will return a pointer to basename in the filename after ignoring '/'.
288 *
289 * e.g. for filename "abc/xyx/some_name.c", this function will return
290 * pointer to basename i.e. "some_name.c"
291 */
get_basename(char * file_name)292 static char *get_basename(char *file_name)
293 {
294 char *p = strrchr(file_name, PATH_SEPARATOR);
295 return p ? ++p : file_name;
296 }
297
tls_mbedtls_f_dbg(void * ctx,int level,const char * file,int line,const char * str)298 static void tls_mbedtls_f_dbg(void *ctx, int level, const char *file, int line, const char *str)
299 {
300 (void)PRINTF("%s:%04d: |%d| %s\r\n", get_basename((char *)file), line, level, str);
301 }
302
tls_mbedtls_set_debug_cb(mbedtls_ssl_config * conf,int threshold,void (* f_dbg)(void *,int,const char *,int,const char *))303 void tls_mbedtls_set_debug_cb(mbedtls_ssl_config *conf,
304 int threshold,
305 void (*f_dbg)(void *, int, const char *, int, const char *))
306 {
307 if (!conf)
308 {
309 elog(-1, "Invalid SSL configuration context");
310 return;
311 }
312
313 if (!f_dbg && !g_f_dbg)
314 {
315 /**
316 * If 'NULL' dbg function and 'g_f_dbg' has not been set yet,
317 * then set 'g_f_dbg' pointing to global dbg function,
318 * and set it in conf.
319 */
320 g_f_dbg = tls_mbedtls_f_dbg;
321 mbedtls_ssl_conf_dbg(conf, g_f_dbg, NULL);
322 }
323 else if (!f_dbg && g_f_dbg)
324 {
325 /**
326 * If 'NULL' dbg function and already set 'g_f_dbg',
327 * we will not override 'g_f_dbg',
328 * but set it in conf.
329 */
330 mbedtls_ssl_conf_dbg(conf, g_f_dbg, NULL);
331 }
332 else if (f_dbg)
333 {
334 /**
335 * If valid dbg function then set it in conf.
336 */
337 mbedtls_ssl_conf_dbg(conf, f_dbg, NULL);
338 }
339 mbedtls_debug_set_threshold(threshold);
340 }
341 #endif /* MBEDTLS_DEBUG_C */
342
tls_conf_init(void * tls_ctx)343 struct tls_conf *tls_conf_init(void *tls_ctx)
344 {
345 struct tls_conf *tls_conf = os_zalloc(sizeof(*tls_conf));
346 if (tls_conf == NULL)
347 return NULL;
348 tls_conf->refcnt = 1;
349
350 mbedtls_ssl_config_init(&tls_conf->conf);
351 mbedtls_ssl_conf_rng(&tls_conf->conf, hostap_rng_fn, hostap_rng_ctx());
352 mbedtls_x509_crt_init(&tls_conf->ca_cert);
353 mbedtls_x509_crt_init(&tls_conf->client_cert);
354 mbedtls_pk_init(&tls_conf->private_key);
355
356 #ifdef MBEDTLS_DEBUG_C
357 tls_mbedtls_set_debug_cb(&tls_conf->conf, DEBUG_THRESHOLD, NULL);
358 #endif
359 return tls_conf;
360 }
361
tls_conf_deinit(struct tls_conf * tls_conf)362 struct tls_conf *tls_conf_deinit(struct tls_conf *tls_conf)
363 {
364 if (tls_conf == NULL || --tls_conf->refcnt != 0)
365 return tls_conf;
366
367 mbedtls_x509_crt_free(&tls_conf->ca_cert);
368 mbedtls_x509_crt_free(&tls_conf->client_cert);
369 if (tls_conf->crl)
370 {
371 mbedtls_x509_crl_free(tls_conf->crl);
372 os_free(tls_conf->crl);
373 }
374 mbedtls_pk_free(&tls_conf->private_key);
375 mbedtls_ssl_config_free(&tls_conf->conf);
376 os_free(tls_conf->curves);
377 os_free(tls_conf->ciphersuites);
378 #ifdef TLS_MBEDTLS_CERT_VERIFY_EXTMATCH
379 os_free(tls_conf->subject_match);
380 os_free(tls_conf->altsubject_match);
381 os_free(tls_conf->suffix_match);
382 os_free(tls_conf->domain_match);
383 os_free(tls_conf->check_cert_subject);
384 #endif
385 os_free(tls_conf);
386 return NULL;
387 }
388
389 #if !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
390 mbedtls_ctr_drbg_context *crypto_mbedtls_ctr_drbg(void); /*(not in header)*/
391 #endif
392
tls_init(const struct tls_config * conf)393 __attribute_cold__ void *tls_init(const struct tls_config *conf)
394 {
395 /* RFE: review struct tls_config *conf (different from tls_conf) */
396
397 if (++tls_ctx_global.refcnt > 1)
398 return &tls_ctx_global;
399
400 #if !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
401 tls_ctx_global.ctr_drbg = crypto_mbedtls_ctr_drbg();
402 #endif
403 #ifdef MBEDTLS_SSL_SESSION_TICKETS
404 mbedtls_ssl_ticket_init(&tls_ctx_global.ticket_ctx);
405 mbedtls_ssl_ticket_setup(&tls_ctx_global.ticket_ctx, hostap_rng_fn, hostap_rng_ctx(),
406 MBEDTLS_CIPHER_AES_256_GCM, 43200); /* ticket timeout: 12 hours */
407 #endif
408 /* copy struct for future use */
409 tls_ctx_global.init_conf = *conf;
410 if (conf->openssl_ciphers)
411 tls_ctx_global.init_conf.openssl_ciphers = os_strdup(conf->openssl_ciphers);
412
413 tls_ctx_global.crl_reload_interval = conf->crl_reload_interval;
414 os_get_reltime(&tls_ctx_global.crl_reload_previous);
415
416 return &tls_ctx_global;
417 }
418
tls_deinit(void * tls_ctx)419 __attribute_cold__ void tls_deinit(void *tls_ctx)
420 {
421 if (tls_ctx == NULL)
422 return;
423
424 tls_ctx_global.tls_conf = tls_conf_deinit(tls_ctx_global.tls_conf);
425
426 if (--tls_ctx_global.refcnt != 0)
427 return;
428
429 os_free(tls_ctx_global.ca_cert_file);
430 os_free(tls_ctx_global.ocsp_stapling_response);
431 char *openssl_ciphers; /*(allocated in tls_init())*/
432 *(const char **)&openssl_ciphers = tls_ctx_global.init_conf.openssl_ciphers;
433 os_free(openssl_ciphers);
434 #ifdef MBEDTLS_SSL_SESSION_TICKETS
435 mbedtls_ssl_ticket_free(&tls_ctx_global.ticket_ctx);
436 #endif
437 os_memset(&tls_ctx_global, 0, sizeof(tls_ctx_global));
438 }
439
tls_get_errors(void * tls_ctx)440 int tls_get_errors(void *tls_ctx)
441 {
442 return 0;
443 }
444
tls_connection_deinit_expkey(struct tls_connection * conn)445 static void tls_connection_deinit_expkey(struct tls_connection *conn)
446 {
447 conn->tls_prf_type = 0; /* MBEDTLS_SSL_TLS_PRF_NONE; */
448 conn->expkey_keyblock_size = 0;
449 conn->expkey_secret_len = 0;
450 forced_memzero(conn->expkey_secret, sizeof(conn->expkey_secret));
451 forced_memzero(conn->expkey_randbytes, sizeof(conn->expkey_randbytes));
452 }
453
454 #ifdef TLS_MBEDTLS_SESSION_TICKETS
tls_connection_deinit_clienthello_session_ticket(struct tls_connection * conn)455 void tls_connection_deinit_clienthello_session_ticket(struct tls_connection *conn)
456 {
457 if (conn->clienthello_session_ticket)
458 {
459 mbedtls_platform_zeroize(conn->clienthello_session_ticket, conn->clienthello_session_ticket_len);
460 mbedtls_free(conn->clienthello_session_ticket);
461 conn->clienthello_session_ticket = NULL;
462 conn->clienthello_session_ticket_len = 0;
463 }
464 }
465 #endif
466
tls_connection_deinit(void * tls_ctx,struct tls_connection * conn)467 void tls_connection_deinit(void *tls_ctx, struct tls_connection *conn)
468 {
469 if (conn == NULL)
470 return;
471
472 if (conn->tls_prf_type)
473 tls_connection_deinit_expkey(conn);
474
475 #ifdef TLS_MBEDTLS_SESSION_TICKETS
476 if (conn->clienthello_session_ticket)
477 tls_connection_deinit_clienthello_session_ticket(conn);
478 #endif
479
480 os_free(conn->peer_subject);
481 wpabuf_free(conn->success_data);
482 wpabuf_free(conn->push_buf);
483 wpabuf_free(conn->pull_buf);
484 mbedtls_ssl_free(&conn->ssl);
485 tls_conf_deinit(conn->tls_conf);
486 os_free(conn);
487 }
488
489 static void tls_mbedtls_refresh_crl(void);
490 static int tls_mbedtls_ssl_setup(struct tls_connection *conn);
491
tls_connection_init(void * tls_ctx)492 struct tls_connection *tls_connection_init(void *tls_ctx)
493 {
494 struct tls_connection *conn = os_zalloc(sizeof(*conn));
495 if (conn == NULL)
496 return NULL;
497
498 mbedtls_ssl_init(&conn->ssl);
499
500 conn->tls_conf = tls_ctx_global.tls_conf; /*(inherit global conf, if set)*/
501 if (conn->tls_conf)
502 {
503 ++conn->tls_conf->refcnt;
504 /* check for CRL refresh if inheriting from global config */
505 tls_mbedtls_refresh_crl();
506
507 conn->verify_peer = conn->tls_conf->verify_peer;
508 if (tls_mbedtls_ssl_setup(conn) != 0)
509 {
510 tls_connection_deinit(&tls_ctx_global, conn);
511 return NULL;
512 }
513 }
514
515 return conn;
516 }
517
tls_connection_established(void * tls_ctx,struct tls_connection * conn)518 int tls_connection_established(void *tls_ctx, struct tls_connection *conn)
519 {
520 return conn ? conn->established : 0;
521 }
522
tls_mbedtls_peer_serial_num(const mbedtls_x509_crt * crt,char * serial_num,size_t len)523 __attribute_noinline__ char *tls_mbedtls_peer_serial_num(const mbedtls_x509_crt *crt, char *serial_num, size_t len)
524 {
525 /* mbedtls_x509_serial_gets() inefficiently formats to hex separated by
526 * colons, so generate the hex serial number here. The func
527 * wpa_snprintf_hex_uppercase() is similarly inefficient. */
528 size_t i = 0; /* skip leading 0's per Distinguished Encoding Rules (DER) */
529 while (i < crt->serial.len && crt->serial.p[i] == 0)
530 ++i;
531 if (i == crt->serial.len)
532 --i;
533
534 const unsigned char *s = crt->serial.p + i;
535 const size_t e = (crt->serial.len - i) * 2;
536 if (e >= len)
537 return NULL;
538
539 for (i = 0; i < e; i += 2, ++s)
540 {
541 serial_num[i + 0] = "0123456789ABCDEF"[(*s >> 4)];
542 serial_num[i + 1] = "0123456789ABCDEF"[(*s & 0xF)];
543 }
544 serial_num[e] = '\0';
545
546 return serial_num;
547 }
548
tls_connection_peer_serial_num(void * tls_ctx,struct tls_connection * conn)549 char *tls_connection_peer_serial_num(void *tls_ctx, struct tls_connection *conn)
550 {
551 const mbedtls_x509_crt *crt = mbedtls_ssl_get_peer_cert(&conn->ssl);
552 if (crt == NULL)
553 return NULL;
554 size_t len = crt->serial.len * 2 + 1;
555 char *serial_num = os_malloc(len);
556 if (!serial_num)
557 return NULL;
558 return tls_mbedtls_peer_serial_num(crt, serial_num, len);
559 }
560
561 static void tls_pull_buf_reset(struct tls_connection *conn);
562
tls_connection_shutdown(void * tls_ctx,struct tls_connection * conn)563 int tls_connection_shutdown(void *tls_ctx, struct tls_connection *conn)
564 {
565 /* Note: this function called from eap_peer_tls_reauth_init()
566 * for session resumption, not for connection shutdown */
567
568 if (conn == NULL)
569 return -1;
570
571 tls_pull_buf_reset(conn);
572 wpabuf_free(conn->push_buf);
573 conn->push_buf = NULL;
574 conn->established = 0;
575 conn->resumed = 0;
576 if (conn->tls_prf_type)
577 tls_connection_deinit_expkey(conn);
578
579 /* RFE: prepare for session resumption? (see doc in crypto/tls.h) */
580
581 return mbedtls_ssl_session_reset(&conn->ssl);
582 }
583
tls_wpabuf_resize_put_data(struct wpabuf ** buf,const unsigned char * data,size_t dlen)584 static int tls_wpabuf_resize_put_data(struct wpabuf **buf, const unsigned char *data, size_t dlen)
585 {
586 if (wpabuf_resize(buf, dlen) < 0)
587 return 0;
588 wpabuf_put_data(*buf, data, dlen);
589 return 1;
590 }
591
tls_pull_buf_append(struct tls_connection * conn,const struct wpabuf * in_data)592 static int tls_pull_buf_append(struct tls_connection *conn, const struct wpabuf *in_data)
593 {
594 /*(interface does not lend itself to move semantics)*/
595 return tls_wpabuf_resize_put_data(&conn->pull_buf, wpabuf_head(in_data), wpabuf_len(in_data));
596 }
597
tls_pull_buf_reset(struct tls_connection * conn)598 static void tls_pull_buf_reset(struct tls_connection *conn)
599 {
600 /*(future: might consider reusing conn->pull_buf)*/
601 wpabuf_free(conn->pull_buf);
602 conn->pull_buf = NULL;
603 conn->pull_buf_offset = 0;
604 }
605
tls_pull_buf_discard(struct tls_connection * conn,const char * func)606 __attribute_cold__ static void tls_pull_buf_discard(struct tls_connection *conn, const char *func)
607 {
608 size_t discard = wpabuf_len(conn->pull_buf) - conn->pull_buf_offset;
609 if (discard)
610 wpa_printf(MSG_DEBUG, "%s - %zu bytes remaining in pull_buf; discarding", func, discard);
611 tls_pull_buf_reset(conn);
612 }
613
tls_pull_func(void * ptr,unsigned char * buf,size_t len)614 static int tls_pull_func(void *ptr, unsigned char *buf, size_t len)
615 {
616 struct tls_connection *conn = (struct tls_connection *)ptr;
617 if (conn->pull_buf == NULL)
618 return MBEDTLS_ERR_SSL_WANT_READ;
619 const size_t dlen = wpabuf_len(conn->pull_buf) - conn->pull_buf_offset;
620 if (dlen == 0)
621 return MBEDTLS_ERR_SSL_WANT_READ;
622
623 if (len > dlen)
624 len = dlen;
625 os_memcpy(buf, (u8 *)wpabuf_head(conn->pull_buf) + conn->pull_buf_offset, len);
626
627 if (len == dlen)
628 {
629 tls_pull_buf_reset(conn);
630 /*wpa_printf(MSG_DEBUG, "%s - emptied pull_buf", __func__);*/
631 }
632 else
633 {
634 conn->pull_buf_offset += len;
635 /*wpa_printf(MSG_DEBUG, "%s - %zu bytes remaining in pull_buf",
636 __func__, dlen - len);*/
637 }
638 return (int)len;
639 }
640
tls_push_func(void * ptr,const unsigned char * buf,size_t len)641 static int tls_push_func(void *ptr, const unsigned char *buf, size_t len)
642 {
643 struct tls_connection *conn = (struct tls_connection *)ptr;
644 return tls_wpabuf_resize_put_data(&conn->push_buf, buf, len) ? (int)len : MBEDTLS_ERR_SSL_ALLOC_FAILED;
645 }
646
647 static int tls_mbedtls_verify_cb(void *arg, mbedtls_x509_crt *crt, int depth, uint32_t *flags);
648
tls_mbedtls_ssl_setup(struct tls_connection * conn)649 static int tls_mbedtls_ssl_setup(struct tls_connection *conn)
650 {
651 int ret = mbedtls_ssl_setup(&conn->ssl, &conn->tls_conf->conf);
652 if (ret != 0)
653 {
654 elog(ret, "mbedtls_ssl_setup");
655 return -1;
656 }
657
658 mbedtls_ssl_set_bio(&conn->ssl, conn, tls_push_func, tls_pull_func, NULL);
659 #if MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.0.0 */
660 mbedtls_ssl_set_export_keys_cb(&conn->ssl, tls_connection_export_keys_cb, conn);
661 #elif MBEDTLS_VERSION_NUMBER >= 0x02120000 /* mbedtls 2.18.0 */
662 mbedtls_ssl_conf_export_keys_ext_cb(&conn->tls_conf->conf, tls_connection_export_keys_cb, conn);
663 #endif
664 if (conn->verify_peer)
665 mbedtls_ssl_set_verify(&conn->ssl, tls_mbedtls_verify_cb, conn);
666
667 return 0;
668 }
669
tls_mbedtls_data_is_pem(const u8 * data)670 static int tls_mbedtls_data_is_pem(const u8 *data)
671 {
672 return (NULL != os_strstr((char *)data, "-----"));
673 }
674
tls_mbedtls_set_allowed_tls_vers(struct tls_conf * tls_conf,mbedtls_ssl_config * conf)675 static void tls_mbedtls_set_allowed_tls_vers(struct tls_conf *tls_conf, mbedtls_ssl_config *conf)
676 {
677 #if !defined(MBEDTLS_SSL_PROTO_TLS1_3)
678 tls_conf->flags |= TLS_CONN_DISABLE_TLSv1_3;
679 #endif
680
681 /* unconditionally require TLSv1.2+ for TLS_CONN_SUITEB */
682 if (tls_conf->flags & TLS_CONN_SUITEB)
683 {
684 tls_conf->flags |= TLS_CONN_DISABLE_TLSv1_0;
685 tls_conf->flags |= TLS_CONN_DISABLE_TLSv1_1;
686 }
687
688 const unsigned int flags = tls_conf->flags;
689
690 /* attempt to map flags to min and max TLS protocol version */
691
692 int min = (flags & TLS_CONN_DISABLE_TLSv1_0) ?
693 (flags & TLS_CONN_DISABLE_TLSv1_1) ?
694 (flags & TLS_CONN_DISABLE_TLSv1_2) ? (flags & TLS_CONN_DISABLE_TLSv1_3) ? 4 : 3 : 2 :
695 1 :
696 0;
697
698 int max = (flags & TLS_CONN_DISABLE_TLSv1_3) ?
699 (flags & TLS_CONN_DISABLE_TLSv1_2) ?
700 (flags & TLS_CONN_DISABLE_TLSv1_1) ? (flags & TLS_CONN_DISABLE_TLSv1_0) ? -1 : 0 : 1 :
701 2 :
702 3;
703
704 if ((flags & TLS_CONN_ENABLE_TLSv1_2) && min > 2)
705 min = 2;
706 if ((flags & TLS_CONN_ENABLE_TLSv1_1) && min > 1)
707 min = 1;
708 if ((flags & TLS_CONN_ENABLE_TLSv1_0) && min > 0)
709 min = 0;
710 if (max < min)
711 {
712 emsg(MSG_ERROR, "invalid tls_disable_tlsv* params; ignoring");
713 return;
714 }
715 #if MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.0.0 */
716 /* mbed TLS 3.0.0 removes support for protocols < TLSv1.2 */
717 if (min < 2 || max < 2)
718 {
719 emsg(MSG_ERROR, "invalid tls_disable_tlsv* params; ignoring");
720 if (min < 2)
721 min = 2;
722 if (max < 2)
723 max = 2;
724 }
725 #endif
726
727 #if MBEDTLS_VERSION_NUMBER >= 0x03020000 /* mbedtls 3.2.0 */
728 /* MBEDTLS_SSL_VERSION_TLS1_2 = 0x0303 */ /*!< (D)TLS 1.2 */
729 /* MBEDTLS_SSL_VERSION_TLS1_3 = 0x0304 */ /*!< (D)TLS 1.3 */
730 min = (min == 2) ? MBEDTLS_SSL_VERSION_TLS1_2 : MBEDTLS_SSL_VERSION_TLS1_3;
731 max = (max == 2) ? MBEDTLS_SSL_VERSION_TLS1_2 : MBEDTLS_SSL_VERSION_TLS1_3;
732 mbedtls_ssl_conf_min_tls_version(conf, min);
733 mbedtls_ssl_conf_max_tls_version(conf, max);
734 #else
735 #ifndef MBEDTLS_SSL_MINOR_VERSION_4
736 if (min == 3)
737 min = 2;
738 if (max == 3)
739 max = 2;
740 #endif
741 /* MBEDTLS_SSL_MINOR_VERSION_0 0 */ /*!< SSL v3.0 */
742 /* MBEDTLS_SSL_MINOR_VERSION_1 1 */ /*!< TLS v1.0 */
743 /* MBEDTLS_SSL_MINOR_VERSION_2 2 */ /*!< TLS v1.1 */
744 /* MBEDTLS_SSL_MINOR_VERSION_3 3 */ /*!< TLS v1.2 */
745 /* MBEDTLS_SSL_MINOR_VERSION_4 4 */ /*!< TLS v1.3 */
746 mbedtls_ssl_conf_min_version(conf, MBEDTLS_SSL_MAJOR_VERSION_3, min + 1);
747 mbedtls_ssl_conf_max_version(conf, MBEDTLS_SSL_MAJOR_VERSION_3, max + 1);
748 #endif
749 }
750
751 __attribute_noinline__ static int tls_mbedtls_readfile(const char *path, u8 **buf, size_t *n);
752
753 #ifdef MBEDTLS_DHM_C
tls_mbedtls_set_dhparams(struct tls_conf * tls_conf,const struct tls_connection_params * params)754 static int tls_mbedtls_set_dhparams(struct tls_conf *tls_conf, const struct tls_connection_params *params)
755 {
756 size_t len;
757 const u8 *data;
758 // if (tls_mbedtls_readfile(dh_file, &data, &len))
759 // return 0;
760
761 data = params->dh_blob;
762 len = params->dh_blob_len;
763
764 /* parse only if DH parameters if in PEM format */
765 if (tls_mbedtls_data_is_pem(data) && NULL == os_strstr((char *)data, "-----BEGIN DH PARAMETERS-----"))
766 {
767 if (os_strstr((char *)data, "-----BEGIN DSA PARAMETERS-----"))
768 wpa_printf(MSG_WARNING, "DSA parameters not handled (%s)", "dh_file");
769 else
770 wpa_printf(MSG_WARNING, "unexpected DH param content (%s)", "dh_file");
771 //forced_memzero(data, len);
772 // os_free(data);
773 return 0;
774 }
775
776 /* mbedtls_dhm_parse_dhm() expects "-----BEGIN DH PARAMETERS-----" if PEM */
777 mbedtls_dhm_context dhm;
778 mbedtls_dhm_init(&dhm);
779 int rc = mbedtls_dhm_parse_dhm(&dhm, data, len);
780 if (0 == rc)
781 rc = mbedtls_ssl_conf_dh_param_ctx(&tls_conf->conf, &dhm);
782 if (0 != rc)
783 elog(rc, "dh_file");
784 mbedtls_dhm_free(&dhm);
785
786 // forced_memzero(data, len);
787 // os_free(data);
788 return (0 == rc);
789 }
790 #endif
791
792 /* reference: lighttpd src/mod_mbedtls.c:mod_mbedtls_ssl_append_curve()
793 * (same author: gstrauss@gluelogic.com; same license: BSD-3-Clause) */
794 #if MBEDTLS_VERSION_NUMBER < 0x03010000 /* mbedtls 3.1.0 */
tls_mbedtls_append_curve(mbedtls_ecp_group_id * ids,int nids,int idsz,const mbedtls_ecp_group_id id)795 static int tls_mbedtls_append_curve(mbedtls_ecp_group_id *ids, int nids, int idsz, const mbedtls_ecp_group_id id)
796 {
797 if (1 >= idsz - (nids + 1))
798 {
799 emsg(MSG_ERROR, "error: too many curves during list expand");
800 return -1;
801 }
802 ids[++nids] = id;
803 return nids;
804 }
805
tls_mbedtls_set_curves(struct tls_conf * tls_conf,const char * curvelist)806 static int tls_mbedtls_set_curves(struct tls_conf *tls_conf, const char *curvelist)
807 {
808 mbedtls_ecp_group_id ids[512];
809 int nids = -1;
810 const int idsz = (int)(sizeof(ids) / sizeof(*ids) - 1);
811 const mbedtls_ecp_curve_info *const curve_info = mbedtls_ecp_curve_list();
812
813 for (const char *e = curvelist - 1; e;)
814 {
815 const char *const n = e + 1;
816 e = os_strchr(n, ':');
817 size_t len = e ? (size_t)(e - n) : os_strlen(n);
818 mbedtls_ecp_group_id grp_id = MBEDTLS_ECP_DP_NONE;
819 switch (len)
820 {
821 case 5:
822 if (0 == os_memcmp("P-521", n, 5))
823 grp_id = MBEDTLS_ECP_DP_SECP521R1;
824 else if (0 == os_memcmp("P-384", n, 5))
825 grp_id = MBEDTLS_ECP_DP_SECP384R1;
826 else if (0 == os_memcmp("P-256", n, 5))
827 grp_id = MBEDTLS_ECP_DP_SECP256R1;
828 break;
829 case 6:
830 if (0 == os_memcmp("BP-521", n, 6))
831 grp_id = MBEDTLS_ECP_DP_BP512R1;
832 else if (0 == os_memcmp("BP-384", n, 6))
833 grp_id = MBEDTLS_ECP_DP_BP384R1;
834 else if (0 == os_memcmp("BP-256", n, 6))
835 grp_id = MBEDTLS_ECP_DP_BP256R1;
836 break;
837 default:
838 break;
839 }
840 if (grp_id != MBEDTLS_ECP_DP_NONE)
841 {
842 nids = tls_mbedtls_append_curve(ids, nids, idsz, grp_id);
843 if (-1 == nids)
844 return 0;
845 continue;
846 }
847 /* similar to mbedtls_ecp_curve_info_from_name() */
848 const mbedtls_ecp_curve_info *info;
849 for (info = curve_info; info->grp_id != MBEDTLS_ECP_DP_NONE; ++info)
850 {
851 if (0 == os_strncmp(info->name, n, len) && info->name[len] == '\0')
852 break;
853 }
854 if (info->grp_id == MBEDTLS_ECP_DP_NONE)
855 {
856 wpa_printf(MSG_ERROR, "MTLS: unrecognized curve: %.*s", (int)len, n);
857 return 0;
858 }
859
860 nids = tls_mbedtls_append_curve(ids, nids, idsz, info->grp_id);
861 if (-1 == nids)
862 return 0;
863 }
864
865 /* mod_openssl configures "prime256v1" if curve list not specified,
866 * but mbedtls provides a list of supported curves if not explicitly set */
867 if (-1 == nids)
868 return 1; /* empty list; no-op */
869
870 ids[++nids] = MBEDTLS_ECP_DP_NONE; /* terminate list */
871 ++nids;
872
873 /* curves list must be persistent for lifetime of mbedtls_ssl_config */
874 tls_conf->curves = os_malloc(nids * sizeof(mbedtls_ecp_group_id));
875 if (tls_conf->curves == NULL)
876 return 0;
877 os_memcpy(tls_conf->curves, ids, nids * sizeof(mbedtls_ecp_group_id));
878
879 mbedtls_ssl_conf_curves(&tls_conf->conf, tls_conf->curves);
880 return 1;
881 }
882 #else
tls_mbedtls_append_curve(uint16_t * ids,int nids,int idsz,const uint16_t id)883 static int tls_mbedtls_append_curve(uint16_t *ids, int nids, int idsz, const uint16_t id)
884 {
885 if (1 >= idsz - (nids + 1))
886 {
887 emsg(MSG_ERROR, "error: too many curves during list expand");
888 return -1;
889 }
890 ids[++nids] = id;
891 return nids;
892 }
893
tls_mbedtls_set_curves(struct tls_conf * tls_conf,const char * curvelist)894 static int tls_mbedtls_set_curves(struct tls_conf *tls_conf, const char *curvelist)
895 {
896 /* TLS Supported Groups (renamed from "EC Named Curve Registry")
897 * https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-8
898 */
899 uint16_t ids[512];
900 int nids = -1;
901 const int idsz = (int)(sizeof(ids) / sizeof(*ids) - 1);
902 const mbedtls_ecp_curve_info *const curve_info = mbedtls_ecp_curve_list();
903
904 for (const char *e = curvelist - 1; e;)
905 {
906 const char *const n = e + 1;
907 e = os_strchr(n, ':');
908 size_t len = e ? (size_t)(e - n) : os_strlen(n);
909 uint16_t tls_id = 0;
910 switch (len)
911 {
912 case 5:
913 if (0 == os_memcmp("P-521", n, 5))
914 tls_id = 25; /* mbedtls_ecp_group_id MBEDTLS_ECP_DP_SECP521R1 */
915 else if (0 == os_memcmp("P-384", n, 5))
916 tls_id = 24; /* mbedtls_ecp_group_id MBEDTLS_ECP_DP_SECP384R1 */
917 else if (0 == os_memcmp("P-256", n, 5))
918 tls_id = 23; /* mbedtls_ecp_group_id MBEDTLS_ECP_DP_SECP256R1 */
919 break;
920 case 6:
921 if (0 == os_memcmp("BP-521", n, 6))
922 tls_id = 28; /* mbedtls_ecp_group_id MBEDTLS_ECP_DP_BP512R1 */
923 else if (0 == os_memcmp("BP-384", n, 6))
924 tls_id = 27; /* mbedtls_ecp_group_id MBEDTLS_ECP_DP_BP384R1 */
925 else if (0 == os_memcmp("BP-256", n, 6))
926 tls_id = 26; /* mbedtls_ecp_group_id MBEDTLS_ECP_DP_BP256R1 */
927 break;
928 default:
929 break;
930 }
931 if (tls_id != 0)
932 {
933 nids = tls_mbedtls_append_curve(ids, nids, idsz, tls_id);
934 if (-1 == nids)
935 return 0;
936 continue;
937 }
938 /* similar to mbedtls_ecp_curve_info_from_name() */
939 const mbedtls_ecp_curve_info *info;
940 for (info = curve_info; info->tls_id != 0; ++info)
941 {
942 if (0 == os_strncmp(info->name, n, len) && info->name[len] == '\0')
943 break;
944 }
945 if (info->tls_id == 0)
946 {
947 wpa_printf(MSG_ERROR, "MTLS: unrecognized curve: %.*s", (int)len, n);
948 return 0;
949 }
950
951 nids = tls_mbedtls_append_curve(ids, nids, idsz, info->tls_id);
952 if (-1 == nids)
953 return 0;
954 }
955
956 /* mod_openssl configures "prime256v1" if curve list not specified,
957 * but mbedtls provides a list of supported curves if not explicitly set */
958 if (-1 == nids)
959 return 1; /* empty list; no-op */
960
961 ids[++nids] = 0; /* terminate list */
962 ++nids;
963
964 /* curves list must be persistent for lifetime of mbedtls_ssl_config */
965 tls_conf->curves = os_malloc(nids * sizeof(uint16_t));
966 if (tls_conf->curves == NULL)
967 return 0;
968 os_memcpy(tls_conf->curves, ids, nids * sizeof(uint16_t));
969
970 mbedtls_ssl_conf_groups(&tls_conf->conf, tls_conf->curves);
971 return 1;
972 }
973 #endif /* MBEDTLS_VERSION_NUMBER >= 0x03010000 */ /* mbedtls 3.1.0 */
974
975 /* data copied from lighttpd src/mod_mbedtls.c (BSD-3-Clause) */
976 static const int suite_AES_256_ephemeral[] = {
977 /* All AES-256 ephemeral suites */
978 MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
979 MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
980 MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384,
981 MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM,
982 MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM,
983 MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,
984 MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,
985 MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,
986 MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
987 MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
988 MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
989 MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8,
990 MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM_8};
991
992 /* data copied from lighttpd src/mod_mbedtls.c (BSD-3-Clause) */
993 static const int suite_AES_128_ephemeral[] = {
994 /* All AES-128 ephemeral suites */
995 MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
996 MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
997 MBEDTLS_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
998 MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM,
999 MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM,
1000 MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
1001 MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
1002 MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,
1003 MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
1004 MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
1005 MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
1006 MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8,
1007 MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM_8};
1008
1009 /* data copied from lighttpd src/mod_mbedtls.c (BSD-3-Clause) */
1010 /* HIGH cipher list (mapped from openssl list to mbedtls) */
1011 static const int suite_HIGH[] = {MBEDTLS_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
1012 MBEDTLS_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
1013 MBEDTLS_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
1014 MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
1015 MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
1016 MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384,
1017 MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM,
1018 MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM,
1019 MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,
1020 MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,
1021 MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,
1022 MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
1023 MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
1024 MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
1025 MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8,
1026 MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM_8,
1027 MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384,
1028 MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384,
1029 MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256,
1030 MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA,
1031 MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384,
1032 MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384,
1033 MBEDTLS_TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384,
1034 MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
1035 MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
1036 MBEDTLS_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
1037 MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM,
1038 MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM,
1039 MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
1040 MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
1041 MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,
1042 MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
1043 MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
1044 MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
1045 MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8,
1046 MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM_8,
1047 MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256,
1048 MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256,
1049 MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256,
1050 MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA,
1051 MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256,
1052 MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256,
1053 MBEDTLS_TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256,
1054 MBEDTLS_TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256,
1055 MBEDTLS_TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256,
1056 MBEDTLS_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384,
1057 MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CCM,
1058 MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384,
1059 MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384,
1060 MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA,
1061 MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA,
1062 MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384,
1063 MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384,
1064 MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CCM_8,
1065 MBEDTLS_TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384,
1066 MBEDTLS_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256,
1067 MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CCM,
1068 MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256,
1069 MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256,
1070 MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA,
1071 MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA,
1072 MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256,
1073 MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256,
1074 MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CCM_8,
1075 MBEDTLS_TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256,
1076 MBEDTLS_TLS_RSA_WITH_AES_256_GCM_SHA384,
1077 MBEDTLS_TLS_RSA_WITH_AES_256_CCM,
1078 MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA256,
1079 MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA,
1080 MBEDTLS_TLS_RSA_WITH_AES_256_CCM_8,
1081 MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256,
1082 MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA,
1083 MBEDTLS_TLS_RSA_WITH_ARIA_256_GCM_SHA384,
1084 MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256,
1085 MBEDTLS_TLS_RSA_WITH_AES_128_CCM,
1086 MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA256,
1087 MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA,
1088 MBEDTLS_TLS_RSA_WITH_AES_128_CCM_8,
1089 MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256,
1090 MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA,
1091 MBEDTLS_TLS_RSA_WITH_ARIA_128_GCM_SHA256,
1092 MBEDTLS_TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256,
1093 MBEDTLS_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384,
1094 MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384,
1095 MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA,
1096 MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384,
1097 MBEDTLS_TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384,
1098 MBEDTLS_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256,
1099 MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256,
1100 MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA,
1101 MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256,
1102 MBEDTLS_TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256,
1103 MBEDTLS_TLS_PSK_WITH_CHACHA20_POLY1305_SHA256,
1104 MBEDTLS_TLS_PSK_WITH_AES_256_GCM_SHA384,
1105 MBEDTLS_TLS_PSK_WITH_AES_256_CCM,
1106 MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA384,
1107 MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA,
1108 MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384,
1109 MBEDTLS_TLS_PSK_WITH_AES_256_CCM_8,
1110 MBEDTLS_TLS_PSK_WITH_ARIA_256_GCM_SHA384,
1111 MBEDTLS_TLS_PSK_WITH_AES_128_GCM_SHA256,
1112 MBEDTLS_TLS_PSK_WITH_AES_128_CCM,
1113 MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA256,
1114 MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA,
1115 MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256,
1116 MBEDTLS_TLS_PSK_WITH_AES_128_CCM_8,
1117 MBEDTLS_TLS_PSK_WITH_ARIA_128_GCM_SHA256};
1118
tls_mbedtls_append_ciphersuite(int * ids,int nids,int idsz,const int * x,int xsz)1119 __attribute_noinline__ static int tls_mbedtls_append_ciphersuite(int *ids, int nids, int idsz, const int *x, int xsz)
1120 {
1121 if (xsz >= idsz - (nids + 1))
1122 {
1123 emsg(MSG_ERROR, "error: too many ciphers during list expand");
1124 return -1;
1125 }
1126
1127 for (int i = 0; i < xsz; ++i)
1128 ids[++nids] = x[i];
1129
1130 return nids;
1131 }
1132
tls_mbedtls_translate_ciphername(int id,char * buf,size_t buflen)1133 static int tls_mbedtls_translate_ciphername(int id, char *buf, size_t buflen)
1134 {
1135 const mbedtls_ssl_ciphersuite_t *info = mbedtls_ssl_ciphersuite_from_id(id);
1136 if (info == NULL)
1137 return 0;
1138 const char *name = mbedtls_ssl_ciphersuite_get_name(info);
1139 const size_t len = os_strlen(name);
1140 if (len == 7 && 0 == os_memcmp(name, "unknown", 7))
1141 return 0;
1142 if (len >= buflen)
1143 return 0;
1144 os_strlcpy(buf, name, buflen);
1145
1146 /* attempt to translate mbedtls string to openssl string
1147 * (some heuristics; incomplete) */
1148 size_t i = 0, j = 0;
1149 if (buf[0] == 'T')
1150 {
1151 if (os_strncmp(buf, "TLS1-3-", 7) == 0)
1152 {
1153 buf[3] = '-';
1154 j = 4; /* remove "1-3" from "TLS1-3-" prefix */
1155 i = 7;
1156 }
1157 else if (os_strncmp(buf, "TLS-", 4) == 0)
1158 i = 4; /* remove "TLS-" prefix */
1159 }
1160 for (; buf[i]; ++i)
1161 {
1162 if (buf[i] == '-')
1163 {
1164 if (i >= 3)
1165 {
1166 if (0 == os_memcmp(buf + i - 3, "AES", 3))
1167 continue; /* "AES-" -> "AES" */
1168 }
1169 if (i >= 4)
1170 {
1171 if (0 == os_memcmp(buf + i - 4, "WITH", 4))
1172 {
1173 j -= 4; /* remove "WITH-" */
1174 continue;
1175 }
1176 }
1177 }
1178 buf[j++] = buf[i];
1179 }
1180 buf[j] = '\0';
1181
1182 return j;
1183 }
1184
tls_mbedtls_set_ciphersuites(struct tls_conf * tls_conf,int * ids,int nids)1185 __attribute_noinline__ static int tls_mbedtls_set_ciphersuites(struct tls_conf *tls_conf, int *ids, int nids)
1186 {
1187 /* ciphersuites list must be persistent for lifetime of mbedtls_ssl_config*/
1188 os_free(tls_conf->ciphersuites);
1189 tls_conf->ciphersuites = os_malloc(nids * sizeof(int));
1190 if (tls_conf->ciphersuites == NULL)
1191 return 0;
1192 os_memcpy(tls_conf->ciphersuites, ids, nids * sizeof(int));
1193 mbedtls_ssl_conf_ciphersuites(&tls_conf->conf, tls_conf->ciphersuites);
1194 return 1;
1195 }
1196
tls_mbedtls_set_ciphers(struct tls_conf * tls_conf,const char * ciphers)1197 static int tls_mbedtls_set_ciphers(struct tls_conf *tls_conf, const char *ciphers)
1198 {
1199 char buf[64];
1200 int ids[512];
1201 int nids = -1;
1202 const int idsz = (int)(sizeof(ids) / sizeof(*ids) - 1);
1203 const char *next;
1204 size_t blen, clen;
1205 do
1206 {
1207 next = os_strchr(ciphers, ':');
1208 clen = next ? (size_t)(next - ciphers) : os_strlen(ciphers);
1209 if (!clen)
1210 continue;
1211
1212 /* special-case a select set of openssl group names for hwsim tests */
1213 /* (review; remove excess code if tests are not run for non-OpenSSL?) */
1214 if (clen == 9 && os_memcmp(ciphers, "SUITEB192", 9) == 0)
1215 {
1216 static int ssl_preset_suiteb192_ciphersuites[] = {MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, 0};
1217 return tls_mbedtls_set_ciphersuites(tls_conf, ssl_preset_suiteb192_ciphersuites, 2);
1218 }
1219 if (clen == 9 && os_memcmp(ciphers, "SUITEB128", 9) == 0)
1220 {
1221 static int ssl_preset_suiteb128_ciphersuites[] = {MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0};
1222 return tls_mbedtls_set_ciphersuites(tls_conf, ssl_preset_suiteb128_ciphersuites, 2);
1223 }
1224 if (clen == 7 && os_memcmp(ciphers, "DEFAULT", 7) == 0)
1225 continue;
1226 if (clen == 6 && os_memcmp(ciphers, "AES128", 6) == 0)
1227 {
1228 nids = tls_mbedtls_append_ciphersuite(ids, nids, idsz, suite_AES_128_ephemeral,
1229 (int)ARRAY_SIZE(suite_AES_128_ephemeral));
1230 if (nids == -1)
1231 return 0;
1232 continue;
1233 }
1234 if (clen == 6 && os_memcmp(ciphers, "AES256", 6) == 0)
1235 {
1236 nids = tls_mbedtls_append_ciphersuite(ids, nids, idsz, suite_AES_256_ephemeral,
1237 (int)ARRAY_SIZE(suite_AES_256_ephemeral));
1238 if (nids == -1)
1239 return 0;
1240 continue;
1241 }
1242 if (clen == 4 && os_memcmp(ciphers, "HIGH", 4) == 0)
1243 {
1244 nids = tls_mbedtls_append_ciphersuite(ids, nids, idsz, suite_HIGH, (int)ARRAY_SIZE(suite_HIGH));
1245 if (nids == -1)
1246 return 0;
1247 continue;
1248 }
1249 /* ignore anonymous cipher group names (?not supported by mbedtls?) */
1250 if (clen == 4 && os_memcmp(ciphers, "!ADH", 4) == 0)
1251 continue;
1252 if (clen == 6 && os_memcmp(ciphers, "-aECDH", 6) == 0)
1253 continue;
1254 if (clen == 7 && os_memcmp(ciphers, "-aECDSA", 7) == 0)
1255 continue;
1256
1257 /* attempt to match mbedtls cipher names
1258 * nb: does not support openssl group names or list manipulation syntax
1259 * (alt: could copy almost 1200 lines (!!!) of lighttpd mod_mbedtls.c
1260 * mod_mbedtls_ssl_conf_ciphersuites() to translate strings)
1261 * note: not efficient to rewrite list for each ciphers entry,
1262 * but this code is expected to run only at startup
1263 */
1264 const int *list = mbedtls_ssl_list_ciphersuites();
1265 for (; *list; ++list)
1266 {
1267 blen = tls_mbedtls_translate_ciphername(*list, buf, sizeof(buf));
1268 if (!blen)
1269 continue;
1270
1271 /* matching heuristics additional to translate_ciphername above */
1272 if (blen == clen + 4)
1273 {
1274 char *cbc = os_strstr(buf, "CBC-");
1275 if (cbc)
1276 {
1277 os_memmove(cbc, cbc + 4, blen - (cbc + 4 - buf) + 1); /*(w/ '\0')*/
1278 blen -= 4;
1279 }
1280 }
1281 if (blen >= clen && os_memcmp(ciphers, buf, clen) == 0 &&
1282 (blen == clen || (blen == clen + 7 && os_memcmp(buf + clen, "-SHA256", 7))))
1283 {
1284 if (1 >= idsz - (nids + 1))
1285 {
1286 emsg(MSG_ERROR, "error: too many ciphers during list expand");
1287 return 0;
1288 }
1289 ids[++nids] = *list;
1290 break;
1291 }
1292 }
1293 if (*list == 0)
1294 {
1295 wpa_printf(MSG_ERROR, "MTLS: unrecognized cipher: %.*s", (int)clen, ciphers);
1296 return 0;
1297 }
1298 } while ((ciphers = next ? next + 1 : NULL));
1299
1300 if (-1 == nids)
1301 return 1; /* empty list; no-op */
1302
1303 ids[++nids] = 0; /* terminate list */
1304 ++nids;
1305
1306 return tls_mbedtls_set_ciphersuites(tls_conf, ids, nids);
1307 }
1308
1309 #ifdef TLS_MBEDTLS_CERT_VERIFY_EXTMATCH
1310
tls_mbedtls_set_item(char ** config_item,const char * item)1311 __attribute_noinline__ static int tls_mbedtls_set_item(char **config_item, const char *item)
1312 {
1313 os_free(*config_item);
1314 *config_item = NULL;
1315 return item ? (*config_item = os_strdup(item)) != NULL : 1;
1316 }
1317
tls_connection_set_subject_match(struct tls_conf * tls_conf,const struct tls_connection_params * params)1318 static int tls_connection_set_subject_match(struct tls_conf *tls_conf, const struct tls_connection_params *params)
1319 {
1320 int rc = 1;
1321 rc &= tls_mbedtls_set_item(&tls_conf->subject_match, params->subject_match);
1322 rc &= tls_mbedtls_set_item(&tls_conf->altsubject_match, params->altsubject_match);
1323 rc &= tls_mbedtls_set_item(&tls_conf->suffix_match, params->suffix_match);
1324 rc &= tls_mbedtls_set_item(&tls_conf->domain_match, params->domain_match);
1325 rc &= tls_mbedtls_set_item(&tls_conf->check_cert_subject, params->check_cert_subject);
1326 return rc;
1327 }
1328
1329 #endif /* TLS_MBEDTLS_CERT_VERIFY_EXTMATCH */
1330
1331 /* duplicated in crypto_mbedtls.c:crypto_mbedtls_readfile()*/
tls_mbedtls_readfile(const char * path,u8 ** buf,size_t * n)1332 __attribute_noinline__ static int tls_mbedtls_readfile(const char *path, u8 **buf, size_t *n)
1333 {
1334 /*(use os_readfile() so that we can use os_free()
1335 *(if we use mbedtls_pk_load_file() above, macros prevent calling free()
1336 * directly #if defined(OS_REJECT_C_LIB_FUNCTIONS) and calling os_free()
1337 * on buf aborts in tests if buf not allocated via os_malloc())*/
1338 *buf = (u8 *)os_readfile(path, n);
1339 if (!*buf)
1340 {
1341 wpa_printf(MSG_ERROR, "error: os_readfile %s", path);
1342 return -1;
1343 }
1344 u8 *buf0 = os_realloc(*buf, *n + 1);
1345 if (!buf0)
1346 {
1347 bin_clear_free(*buf, *n);
1348 *buf = NULL;
1349 return -1;
1350 }
1351 buf0[(*n)++] = '\0';
1352 *buf = buf0;
1353 return 0;
1354 }
1355
tls_mbedtls_set_crl(struct tls_conf * tls_conf,const u8 * data,size_t len)1356 static int tls_mbedtls_set_crl(struct tls_conf *tls_conf, const u8 *data, size_t len)
1357 {
1358 /* do not use mbedtls_x509_crl_parse() on PEM unless it contains CRL */
1359 if (len && data[len - 1] == '\0' && NULL == os_strstr((const char *)data, "-----BEGIN X509 CRL-----") &&
1360 tls_mbedtls_data_is_pem(data))
1361 return 0;
1362
1363 mbedtls_x509_crl crl;
1364 mbedtls_x509_crl_init(&crl);
1365 int rc = mbedtls_x509_crl_parse(&crl, data, len);
1366 if (rc < 0)
1367 {
1368 mbedtls_x509_crl_free(&crl);
1369 return rc == MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT ? 0 : rc;
1370 }
1371
1372 mbedtls_x509_crl *crl_new = os_malloc(sizeof(crl));
1373 if (crl_new == NULL)
1374 {
1375 mbedtls_x509_crl_free(&crl);
1376 return MBEDTLS_ERR_X509_ALLOC_FAILED;
1377 }
1378 os_memcpy(crl_new, &crl, sizeof(crl));
1379
1380 mbedtls_x509_crl *crl_old = tls_conf->crl;
1381 tls_conf->crl = crl_new;
1382 if (crl_old)
1383 {
1384 mbedtls_x509_crl_free(crl_old);
1385 os_free(crl_old);
1386 }
1387 return 0;
1388 }
1389
tls_mbedtls_set_ca(struct tls_conf * tls_conf,u8 * data,size_t len)1390 static int tls_mbedtls_set_ca(struct tls_conf *tls_conf, u8 *data, size_t len)
1391 {
1392 /* load crt struct onto stack and then copy into tls_conf in
1393 * order to preserve existing tls_conf value if error occurs
1394 *
1395 * hostapd is not threaded, or else should allocate memory and swap in
1396 * pointer reduce race condition. (If threaded, would also need to
1397 * keep reference count of use to avoid freeing while still in use.) */
1398
1399 mbedtls_x509_crt crt;
1400 mbedtls_x509_crt_init(&crt);
1401 int rc = mbedtls_x509_crt_parse(&crt, data, len);
1402 if (rc < 0)
1403 {
1404 mbedtls_x509_crt_free(&crt);
1405 return rc;
1406 }
1407
1408 mbedtls_x509_crt_free(&tls_conf->ca_cert);
1409 os_memcpy(&tls_conf->ca_cert, &crt, sizeof(crt));
1410 return 0;
1411 }
1412
tls_mbedtls_set_ca_and_crl(struct tls_conf * tls_conf,const char * ca_cert_file)1413 static int tls_mbedtls_set_ca_and_crl(struct tls_conf *tls_conf, const char *ca_cert_file)
1414 {
1415 size_t len;
1416 u8 *data;
1417 if (tls_mbedtls_readfile(ca_cert_file, &data, &len))
1418 return -1;
1419
1420 int rc;
1421 if (0 == (rc = tls_mbedtls_set_ca(tls_conf, data, len)) &&
1422 (!tls_mbedtls_data_is_pem(data) /*skip parse for CRL if not PEM*/
1423 || 0 == (rc = tls_mbedtls_set_crl(tls_conf, data, len))))
1424 {
1425 mbedtls_ssl_conf_ca_chain(&tls_conf->conf, &tls_conf->ca_cert, tls_conf->crl);
1426 }
1427 else
1428 {
1429 elog(rc, __func__);
1430 emsg(MSG_ERROR, ca_cert_file);
1431 }
1432
1433 forced_memzero(data, len);
1434 os_free(data);
1435 return rc;
1436 }
1437
tls_mbedtls_refresh_crl(void)1438 static void tls_mbedtls_refresh_crl(void)
1439 {
1440 /* check for CRL refresh
1441 * continue even if error occurs; continue with previous cert, CRL */
1442 unsigned int crl_reload_interval = tls_ctx_global.crl_reload_interval;
1443 const char *ca_cert_file = tls_ctx_global.ca_cert_file;
1444 if (!crl_reload_interval || !ca_cert_file)
1445 return;
1446
1447 struct os_reltime *previous = &tls_ctx_global.crl_reload_previous;
1448 struct os_reltime now;
1449 if (os_get_reltime(&now) != 0 || !os_reltime_expired(&now, previous, crl_reload_interval))
1450 return;
1451
1452 /* Note: modifying global state is not thread-safe
1453 * if in use by existing connections
1454 *
1455 * src/utils/os.h does not provide a portable stat()
1456 * or else it would be a good idea to check mtime and size,
1457 * and avoid reloading if file has not changed */
1458
1459 if (tls_mbedtls_set_ca_and_crl(tls_ctx_global.tls_conf, ca_cert_file) == 0)
1460 *previous = now;
1461 }
1462
tls_mbedtls_set_ca_cert(struct tls_conf * tls_conf,const struct tls_connection_params * params)1463 static int tls_mbedtls_set_ca_cert(struct tls_conf *tls_conf, const struct tls_connection_params *params)
1464 {
1465 if (params->ca_cert)
1466 {
1467 if (os_strncmp(params->ca_cert, "probe://", 8) == 0)
1468 {
1469 tls_conf->ca_cert_probe = 1;
1470 tls_conf->has_ca_cert = 1;
1471 return 0;
1472 }
1473
1474 if (os_strncmp(params->ca_cert, "hash://", 7) == 0)
1475 {
1476 const char *pos = params->ca_cert + 7;
1477 if (os_strncmp(pos, "server/sha256/", 14) != 0)
1478 {
1479 emsg(MSG_ERROR, "unsupported ca_cert hash value");
1480 return -1;
1481 }
1482 pos += 14;
1483 if (os_strlen(pos) != SHA256_DIGEST_LENGTH * 2)
1484 {
1485 emsg(MSG_ERROR, "unexpected ca_cert hash length");
1486 return -1;
1487 }
1488 if (hexstr2bin(pos, tls_conf->ca_cert_hash, SHA256_DIGEST_LENGTH) < 0)
1489 {
1490 emsg(MSG_ERROR, "invalid ca_cert hash value");
1491 return -1;
1492 }
1493 emsg(MSG_DEBUG, "checking only server certificate match");
1494 tls_conf->verify_depth0_only = 1;
1495 tls_conf->has_ca_cert = 1;
1496 return 0;
1497 }
1498
1499 if (tls_mbedtls_set_ca_and_crl(tls_conf, params->ca_cert) != 0)
1500 return -1;
1501 }
1502 if (params->ca_cert_blob)
1503 {
1504 size_t len = params->ca_cert_blob_len;
1505 int is_pem = tls_mbedtls_data_is_pem(params->ca_cert_blob);
1506 int ret = mbedtls_x509_crt_parse(&tls_conf->ca_cert, params->ca_cert_blob, len);
1507 if (ret != 0)
1508 {
1509 elog(ret, "mbedtls_x509_crt_parse");
1510 return -1;
1511 }
1512 if (is_pem)
1513 { /*(ca_cert_blob in DER format contains ca cert only)*/
1514 ret = tls_mbedtls_set_crl(tls_conf, params->ca_cert_blob, len);
1515 if (ret != 0)
1516 {
1517 elog(ret, "mbedtls_x509_crl_parse");
1518 return -1;
1519 }
1520 }
1521 }
1522
1523 if (mbedtls_x509_time_is_future(&tls_conf->ca_cert.valid_from) ||
1524 mbedtls_x509_time_is_past(&tls_conf->ca_cert.valid_to))
1525 {
1526 emsg(MSG_WARNING, "ca_cert expired or not yet valid");
1527 if (params->ca_cert)
1528 emsg(MSG_WARNING, params->ca_cert);
1529 }
1530
1531 tls_conf->has_ca_cert = 1;
1532 return 0;
1533 }
1534
tls_mbedtls_set_certs(struct tls_conf * tls_conf,const struct tls_connection_params * params)1535 static int tls_mbedtls_set_certs(struct tls_conf *tls_conf, const struct tls_connection_params *params)
1536 {
1537 int ret = -1;
1538
1539 if (params->ca_cert || params->ca_cert_blob)
1540 {
1541 if (tls_mbedtls_set_ca_cert(tls_conf, params) != 0)
1542 return -1;
1543 }
1544 else if (params->ca_path)
1545 {
1546 emsg(MSG_INFO, "ca_path support not implemented");
1547 return -1;
1548 }
1549
1550 if (!tls_conf->has_ca_cert)
1551 mbedtls_ssl_conf_authmode(&tls_conf->conf, MBEDTLS_SSL_VERIFY_NONE);
1552 else
1553 {
1554 /* Initial setting: REQUIRED for client, OPTIONAL for server
1555 * (see also tls_connection_set_verify()) */
1556 tls_conf->verify_peer = (tls_ctx_global.tls_conf == NULL);
1557 int authmode = tls_conf->verify_peer ? MBEDTLS_SSL_VERIFY_REQUIRED : MBEDTLS_SSL_VERIFY_OPTIONAL;
1558 mbedtls_ssl_conf_authmode(&tls_conf->conf, authmode);
1559 mbedtls_ssl_conf_ca_chain(&tls_conf->conf, &tls_conf->ca_cert, tls_conf->crl);
1560
1561 #ifdef TLS_MBEDTLS_CERT_VERIFY_EXTMATCH
1562 if (!tls_connection_set_subject_match(tls_conf, params))
1563 return -1;
1564 #endif
1565 }
1566
1567 if (params->client_cert2) /*(yes, server_cert2 in msg below)*/
1568 emsg(MSG_INFO, "server_cert2 support not implemented");
1569
1570 if (params->client_cert)
1571 {
1572 size_t len;
1573 u8 *data;
1574 if (tls_mbedtls_readfile(params->client_cert, &data, &len))
1575 return -1;
1576 ret = mbedtls_x509_crt_parse(&tls_conf->client_cert, data, len);
1577 forced_memzero(data, len);
1578 os_free(data);
1579 }
1580 if (params->client_cert_blob)
1581 {
1582 size_t len = params->client_cert_blob_len;
1583
1584 ret = mbedtls_x509_crt_parse(&tls_conf->client_cert, params->client_cert_blob, len);
1585 }
1586 if (params->client_cert || params->client_cert_blob)
1587 {
1588 if (ret < 0)
1589 {
1590 elog(ret, "mbedtls_x509_crt_parse");
1591 if (params->client_cert)
1592 emsg(MSG_ERROR, params->client_cert);
1593 return -1;
1594 }
1595 if (mbedtls_x509_time_is_future(&tls_conf->client_cert.valid_from) ||
1596 mbedtls_x509_time_is_past(&tls_conf->client_cert.valid_to))
1597 {
1598 emsg(MSG_WARNING, "cert expired or not yet valid");
1599 if (params->client_cert)
1600 emsg(MSG_WARNING, params->client_cert);
1601 }
1602 tls_conf->has_client_cert = 1;
1603 }
1604
1605 if (params->private_key || params->private_key_blob)
1606 {
1607 size_t len = params->private_key_blob_len;
1608 u8 *data;
1609
1610 *(const u8 **)&data = params->private_key_blob;
1611 if (params->private_key && tls_mbedtls_readfile(params->private_key, &data, &len))
1612 {
1613 return -1;
1614 }
1615 const char *pwd = params->private_key_passwd;
1616 #if MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.0.0 */
1617 ret = mbedtls_pk_parse_key(&tls_conf->private_key, data, len, (const unsigned char *)pwd,
1618 pwd ? os_strlen(pwd) : 0, hostap_rng_fn, hostap_rng_ctx());
1619 #else
1620 ret = mbedtls_pk_parse_key(&tls_conf->private_key, data, len, (const unsigned char *)pwd,
1621 pwd ? os_strlen(pwd) : 0);
1622 #endif
1623 if (params->private_key)
1624 {
1625 forced_memzero(data, len);
1626 os_free(data);
1627 }
1628 if (ret < 0)
1629 {
1630 elog(ret, "mbedtls_pk_parse_key");
1631 return -1;
1632 }
1633 tls_conf->has_private_key = 1;
1634 }
1635
1636 if (tls_conf->has_client_cert && tls_conf->has_private_key)
1637 {
1638 ret = mbedtls_ssl_conf_own_cert(&tls_conf->conf, &tls_conf->client_cert, &tls_conf->private_key);
1639 if (ret < 0)
1640 {
1641 elog(ret, "mbedtls_ssl_conf_own_cert");
1642 return -1;
1643 }
1644 }
1645
1646 return 0;
1647 }
1648
1649 /* mbedtls_x509_crt_profile_suiteb plus rsa_min_bitlen 2048 */
1650 /* (reference: see also mbedtls_x509_crt_profile_next) */
1651 /* ??? should permit SHA-512, too, and additional curves ??? */
1652 static const mbedtls_x509_crt_profile tls_mbedtls_crt_profile_suiteb128 = {
1653 /* Only SHA-256 and 384 */
1654 MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA256) | MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA384),
1655 /* Only ECDSA */
1656 MBEDTLS_X509_ID_FLAG(MBEDTLS_PK_ECDSA) | MBEDTLS_X509_ID_FLAG(MBEDTLS_PK_ECKEY),
1657 #if defined(MBEDTLS_ECP_C)
1658 /* Only NIST P-256 and P-384 */
1659 MBEDTLS_X509_ID_FLAG(MBEDTLS_ECP_DP_SECP256R1) | MBEDTLS_X509_ID_FLAG(MBEDTLS_ECP_DP_SECP384R1),
1660 #else
1661 0,
1662 #endif
1663 2048,
1664 };
1665
1666 /* stricter than mbedtls_x509_crt_profile_suiteb */
1667 /* (reference: see also mbedtls_x509_crt_profile_next) */
1668 /* ??? should permit SHA-512, too, and additional curves ??? */
1669 static const mbedtls_x509_crt_profile tls_mbedtls_crt_profile_suiteb192 = {
1670 /* Only SHA-384 */
1671 MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA384),
1672 /* Only ECDSA */
1673 MBEDTLS_X509_ID_FLAG(MBEDTLS_PK_ECDSA) | MBEDTLS_X509_ID_FLAG(MBEDTLS_PK_ECKEY),
1674 #if defined(MBEDTLS_ECP_C)
1675 /* Only NIST P-384 */
1676 MBEDTLS_X509_ID_FLAG(MBEDTLS_ECP_DP_SECP384R1),
1677 #else
1678 0,
1679 #endif
1680 3072,
1681 };
1682
1683 /* stricter than mbedtls_x509_crt_profile_suiteb except allow any PK alg */
1684 /* (reference: see also mbedtls_x509_crt_profile_next) */
1685 /* ??? should permit SHA-512, too, and additional curves ??? */
1686 static const mbedtls_x509_crt_profile tls_mbedtls_crt_profile_suiteb192_anypk = {
1687 /* Only SHA-384 */
1688 MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA384),
1689 0xFFFFFFF, /* Any PK alg */
1690 #if defined(MBEDTLS_ECP_C)
1691 /* Only NIST P-384 */
1692 MBEDTLS_X509_ID_FLAG(MBEDTLS_ECP_DP_SECP384R1),
1693 #else
1694 0,
1695 #endif
1696 3072,
1697 };
1698
tls_mbedtls_set_params(struct tls_conf * tls_conf,const struct tls_connection_params * params)1699 static int tls_mbedtls_set_params(struct tls_conf *tls_conf, const struct tls_connection_params *params)
1700 {
1701 tls_conf->flags = params->flags;
1702
1703 if (tls_conf->flags & TLS_CONN_REQUIRE_OCSP_ALL)
1704 {
1705 emsg(MSG_INFO, "ocsp=3 not supported");
1706 return -1;
1707 }
1708
1709 if (tls_conf->flags & TLS_CONN_REQUIRE_OCSP)
1710 {
1711 emsg(MSG_INFO, "ocsp not supported");
1712 return -1;
1713 }
1714
1715 int suiteb128 = 0;
1716 int suiteb192 = 0;
1717 if (params->openssl_ciphers)
1718 {
1719 if (os_strcmp(params->openssl_ciphers, "SUITEB192") == 0)
1720 {
1721 suiteb192 = 1;
1722 tls_conf->flags |= TLS_CONN_SUITEB;
1723 }
1724 if (os_strcmp(params->openssl_ciphers, "SUITEB128") == 0)
1725 {
1726 suiteb128 = 1;
1727 tls_conf->flags |= TLS_CONN_SUITEB;
1728 }
1729 }
1730
1731 int ret = mbedtls_ssl_config_defaults(
1732 &tls_conf->conf, tls_ctx_global.tls_conf ? MBEDTLS_SSL_IS_SERVER : MBEDTLS_SSL_IS_CLIENT,
1733 MBEDTLS_SSL_TRANSPORT_STREAM,
1734 /* TODO:
1735 * Technically suiteb192 rsa3k is wrong, it should be CNSA-RSA3K.
1736 * A proper way would be:
1737 * introduce a new preset CNSA and add RSA3K in MbedTLS. */
1738 MBEDTLS_SSL_PRESET_DEFAULT);
1739 if (ret != 0)
1740 {
1741 elog(ret, "mbedtls_ssl_config_defaults");
1742 return -1;
1743 }
1744
1745 if (suiteb128)
1746 {
1747 mbedtls_ssl_conf_cert_profile(&tls_conf->conf, &tls_mbedtls_crt_profile_suiteb128);
1748 #if defined(MBEDTLS_DHM_C)
1749 mbedtls_ssl_conf_dhm_min_bitlen(&tls_conf->conf, 2048);
1750 #endif
1751 }
1752 else if (suiteb192)
1753 {
1754 mbedtls_ssl_conf_cert_profile(&tls_conf->conf, &tls_mbedtls_crt_profile_suiteb192);
1755 #if defined(MBEDTLS_DHM_C)
1756 mbedtls_ssl_conf_dhm_min_bitlen(&tls_conf->conf, 3072);
1757 #endif
1758 }
1759 else if (tls_conf->flags & TLS_CONN_SUITEB)
1760 {
1761 /* treat as suiteb192 while allowing any PK algorithm */
1762 mbedtls_ssl_conf_cert_profile(&tls_conf->conf, &tls_mbedtls_crt_profile_suiteb192_anypk);
1763 #if defined(MBEDTLS_DHM_C)
1764 mbedtls_ssl_conf_dhm_min_bitlen(&tls_conf->conf, 3072);
1765 #endif
1766 }
1767
1768 tls_mbedtls_set_allowed_tls_vers(tls_conf, &tls_conf->conf);
1769 ret = tls_mbedtls_set_certs(tls_conf, params);
1770 if (ret != 0)
1771 return -1;
1772
1773 #ifdef MBEDTLS_DHM_C
1774 if (params->dh_blob && !tls_mbedtls_set_dhparams(tls_conf, params))
1775 {
1776 return -1;
1777 }
1778 #endif
1779
1780 if (params->openssl_ecdh_curves && !tls_mbedtls_set_curves(tls_conf, params->openssl_ecdh_curves))
1781 {
1782 return -1;
1783 }
1784
1785 if (params->openssl_ciphers)
1786 {
1787 if (!tls_mbedtls_set_ciphers(tls_conf, params->openssl_ciphers))
1788 return -1;
1789 }
1790 else if (tls_conf->flags & TLS_CONN_SUITEB)
1791 {
1792 /* special-case a select set of ciphers for hwsim tests */
1793 if (!tls_mbedtls_set_ciphers(tls_conf, (tls_conf->flags & TLS_CONN_SUITEB_NO_ECDH) ?
1794 "DHE-RSA-AES256-GCM-SHA384" :
1795 "ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384"))
1796 return -1;
1797 }
1798
1799 return 0;
1800 }
1801
tls_connection_set_params(void * tls_ctx,struct tls_connection * conn,const struct tls_connection_params * params)1802 int tls_connection_set_params(void *tls_ctx, struct tls_connection *conn, const struct tls_connection_params *params)
1803 {
1804 if (conn == NULL || params == NULL)
1805 return -1;
1806
1807 tls_conf_deinit(conn->tls_conf);
1808 struct tls_conf *tls_conf = conn->tls_conf = tls_conf_init(tls_ctx);
1809 if (tls_conf == NULL)
1810 return -1;
1811
1812 if (tls_ctx_global.tls_conf)
1813 {
1814 tls_conf->check_crl = tls_ctx_global.tls_conf->check_crl;
1815 tls_conf->check_crl_strict = tls_ctx_global.tls_conf->check_crl_strict;
1816 #ifdef TLS_MBEDTLS_CERT_VERIFY_EXTMATCH
1817 /*(tls_openssl.c inherits check_cert_subject from global conf)*/
1818 if (tls_ctx_global.tls_conf->check_cert_subject)
1819 {
1820 tls_conf->check_cert_subject = os_strdup(tls_ctx_global.tls_conf->check_cert_subject);
1821 if (tls_conf->check_cert_subject == NULL)
1822 return -1;
1823 }
1824 #endif
1825 }
1826
1827 if (tls_mbedtls_set_params(tls_conf, params) != 0)
1828 return -1;
1829 conn->verify_peer = tls_conf->verify_peer;
1830
1831 return tls_mbedtls_ssl_setup(conn);
1832 }
1833
1834 #ifdef TLS_MBEDTLS_SESSION_TICKETS
1835
tls_mbedtls_clienthello_session_ticket_prep(struct tls_connection * conn,const u8 * data,size_t len)1836 static int tls_mbedtls_clienthello_session_ticket_prep(struct tls_connection *conn, const u8 *data, size_t len)
1837 {
1838 if (conn->tls_conf->flags & TLS_CONN_DISABLE_SESSION_TICKET)
1839 return -1;
1840 if (conn->clienthello_session_ticket)
1841 tls_connection_deinit_clienthello_session_ticket(conn);
1842 if (len)
1843 {
1844 conn->clienthello_session_ticket = mbedtls_calloc(1, len);
1845 if (conn->clienthello_session_ticket == NULL)
1846 return -1;
1847 conn->clienthello_session_ticket_len = len;
1848 os_memcpy(conn->clienthello_session_ticket, data, len);
1849 }
1850 return 0;
1851 }
1852
tls_mbedtls_clienthello_session_ticket_set(struct tls_connection * conn)1853 static void tls_mbedtls_clienthello_session_ticket_set(struct tls_connection *conn)
1854 {
1855 mbedtls_ssl_session *sess = conn->ssl.MBEDTLS_PRIVATE(session_negotiate);
1856 if (sess->MBEDTLS_PRIVATE(ticket))
1857 {
1858 mbedtls_platform_zeroize(sess->MBEDTLS_PRIVATE(ticket), sess->MBEDTLS_PRIVATE(ticket_len));
1859 mbedtls_free(sess->MBEDTLS_PRIVATE(ticket));
1860 }
1861 sess->MBEDTLS_PRIVATE(ticket) = conn->clienthello_session_ticket;
1862 sess->MBEDTLS_PRIVATE(ticket_len) = conn->clienthello_session_ticket_len;
1863 sess->MBEDTLS_PRIVATE(ticket_lifetime) = 86400; /* XXX: can hint be 0? */
1864
1865 conn->clienthello_session_ticket = NULL;
1866 conn->clienthello_session_ticket_len = 0;
1867 }
1868
tls_mbedtls_ssl_ticket_write(void * p_ticket,const mbedtls_ssl_session * session,unsigned char * start,const unsigned char * end,size_t * tlen,uint32_t * lifetime)1869 static int tls_mbedtls_ssl_ticket_write(void *p_ticket,
1870 const mbedtls_ssl_session *session,
1871 unsigned char *start,
1872 const unsigned char *end,
1873 size_t *tlen,
1874 uint32_t *lifetime)
1875 {
1876 struct tls_connection *conn = p_ticket;
1877 if (conn && conn->session_ticket_cb)
1878 {
1879 /* see tls_mbedtls_clienthello_session_ticket_prep() */
1880 /* see tls_mbedtls_clienthello_session_ticket_set() */
1881 *tlen = 0;
1882 return 0;
1883 }
1884
1885 return mbedtls_ssl_ticket_write(&tls_ctx_global.ticket_ctx, session, start, end, tlen, lifetime);
1886 }
1887
tls_mbedtls_ssl_ticket_parse(void * p_ticket,mbedtls_ssl_session * session,unsigned char * buf,size_t len)1888 static int tls_mbedtls_ssl_ticket_parse(void *p_ticket, mbedtls_ssl_session *session, unsigned char *buf, size_t len)
1889 {
1890 /* XXX: TODO: not implemented in client;
1891 * mbedtls_ssl_conf_session_tickets_cb() callbacks only for TLS server*/
1892
1893 if (len == 0)
1894 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
1895
1896 struct tls_connection *conn = p_ticket;
1897 if (conn && conn->session_ticket_cb)
1898 {
1899 /* XXX: have random and secret been initialized yet?
1900 * or must keys first be exported?
1901 * EAP-FAST uses all args, EAP-TEAP only uses secret */
1902 struct tls_random data;
1903 if (tls_connection_get_random(NULL, conn, &data) != 0)
1904 return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
1905 int ret = conn->session_ticket_cb(conn->session_ticket_cb_ctx, buf, len, data.client_random, data.server_random,
1906 conn->expkey_secret);
1907 if (ret == 1)
1908 {
1909 conn->resumed = 1;
1910 return 0;
1911 }
1912 emsg(MSG_ERROR, "EAP session ticket ext not implemented");
1913 return MBEDTLS_ERR_SSL_INVALID_MAC;
1914 /*(non-zero return used for mbedtls debug logging)*/
1915 }
1916
1917 /* XXX: TODO always use tls_mbedtls_ssl_ticket_parse() for callback? */
1918 int rc = mbedtls_ssl_ticket_parse(&tls_ctx_global.ticket_ctx, session, buf, len);
1919 if (conn)
1920 conn->resumed = (rc == 0);
1921 return rc;
1922 }
1923
1924 #endif /* TLS_MBEDTLS_SESSION_TICKETS */
1925
tls_global_set_params(void * tls_ctx,const struct tls_connection_params * params)1926 __attribute_cold__ int tls_global_set_params(void *tls_ctx, const struct tls_connection_params *params)
1927 {
1928 /* XXX: why might global_set_params be called more than once? */
1929 if (tls_ctx_global.tls_conf)
1930 tls_conf_deinit(tls_ctx_global.tls_conf);
1931 tls_ctx_global.tls_conf = tls_conf_init(tls_ctx);
1932 if (tls_ctx_global.tls_conf == NULL)
1933 return -1;
1934
1935 #ifdef MBEDTLS_SSL_SESSION_TICKETS
1936 #ifdef MBEDTLS_SSL_TICKET_C
1937 if (!(params->flags & TLS_CONN_DISABLE_SESSION_TICKET))
1938 #ifdef TLS_MBEDTLS_SESSION_TICKETS
1939 mbedtls_ssl_conf_session_tickets_cb(&tls_ctx_global.tls_conf->conf, tls_mbedtls_ssl_ticket_write,
1940 tls_mbedtls_ssl_ticket_parse, NULL);
1941 #else
1942 mbedtls_ssl_conf_session_tickets_cb(&tls_ctx_global.tls_conf->conf, mbedtls_ssl_ticket_write,
1943 mbedtls_ssl_ticket_parse, &tls_ctx_global.ticket_ctx);
1944 #endif
1945 #endif
1946 #endif
1947
1948 os_free(tls_ctx_global.ocsp_stapling_response);
1949 tls_ctx_global.ocsp_stapling_response = NULL;
1950 if (params->ocsp_stapling_response)
1951 tls_ctx_global.ocsp_stapling_response = os_strdup(params->ocsp_stapling_response);
1952
1953 // os_free(tls_ctx_global.ca_cert_file);
1954 tls_ctx_global.ca_cert_file = NULL;
1955 if (params->ca_cert)
1956 tls_ctx_global.ca_cert_file = os_strdup(params->ca_cert);
1957 return tls_mbedtls_set_params(tls_ctx_global.tls_conf, params);
1958 }
1959
tls_global_set_verify(void * tls_ctx,int check_crl,int strict)1960 int tls_global_set_verify(void *tls_ctx, int check_crl, int strict)
1961 {
1962 tls_ctx_global.tls_conf->check_crl = check_crl;
1963 tls_ctx_global.tls_conf->check_crl_strict = strict; /*(time checks)*/
1964 return 0;
1965 }
1966
tls_connection_set_verify(void * tls_ctx,struct tls_connection * conn,int verify_peer,unsigned int flags,const u8 * session_ctx,size_t session_ctx_len)1967 int tls_connection_set_verify(void *tls_ctx,
1968 struct tls_connection *conn,
1969 int verify_peer,
1970 unsigned int flags,
1971 const u8 *session_ctx,
1972 size_t session_ctx_len)
1973 {
1974 /*(EAP server-side calls this from eap_server_tls_ssl_init())*/
1975 if (conn == NULL)
1976 return -1;
1977
1978 conn->tls_conf->flags |= flags; /* TODO: reprocess flags, if necessary */
1979
1980 int authmode;
1981 switch (verify_peer)
1982 {
1983 case 2:
1984 authmode = MBEDTLS_SSL_VERIFY_OPTIONAL;
1985 break; /*(eap_teap_init())*/
1986 case 1:
1987 authmode = MBEDTLS_SSL_VERIFY_REQUIRED;
1988 break;
1989 default:
1990 authmode = MBEDTLS_SSL_VERIFY_NONE;
1991 break;
1992 }
1993 #ifdef MBEDTLS_SSL_SERVER_NAME_INDICATION
1994 mbedtls_ssl_set_hs_authmode(&conn->ssl, authmode);
1995 #endif
1996 if ((conn->verify_peer = (authmode != MBEDTLS_SSL_VERIFY_NONE)))
1997 mbedtls_ssl_set_verify(&conn->ssl, tls_mbedtls_verify_cb, conn);
1998 else
1999 mbedtls_ssl_set_verify(&conn->ssl, NULL, NULL);
2000
2001 return 0;
2002 }
2003
2004 #if MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.0.0 */
tls_connection_export_keys_cb(void * p_expkey,mbedtls_ssl_key_export_type secret_type,const unsigned char * secret,size_t secret_len,const unsigned char client_random[MBEDTLS_EXPKEY_RAND_LEN],const unsigned char server_random[MBEDTLS_EXPKEY_RAND_LEN],mbedtls_tls_prf_types tls_prf_type)2005 static void tls_connection_export_keys_cb(void *p_expkey,
2006 mbedtls_ssl_key_export_type secret_type,
2007 const unsigned char *secret,
2008 size_t secret_len,
2009 const unsigned char client_random[MBEDTLS_EXPKEY_RAND_LEN],
2010 const unsigned char server_random[MBEDTLS_EXPKEY_RAND_LEN],
2011 mbedtls_tls_prf_types tls_prf_type)
2012 {
2013 struct tls_connection *conn = p_expkey;
2014 conn->tls_prf_type = tls_prf_type;
2015 if (!tls_prf_type)
2016 return;
2017 if (secret_len > sizeof(conn->expkey_secret))
2018 {
2019 emsg(MSG_ERROR, "tls_connection_export_keys_cb secret too long");
2020 conn->tls_prf_type = MBEDTLS_SSL_TLS_PRF_NONE; /* 0 */
2021 return;
2022 }
2023 conn->expkey_secret_len = secret_len;
2024 os_memcpy(conn->expkey_secret, secret, secret_len);
2025 os_memcpy(conn->expkey_randbytes, client_random, MBEDTLS_EXPKEY_RAND_LEN);
2026 os_memcpy(conn->expkey_randbytes + MBEDTLS_EXPKEY_RAND_LEN, server_random, MBEDTLS_EXPKEY_RAND_LEN);
2027 }
2028 #elif MBEDTLS_VERSION_NUMBER >= 0x02120000 /* mbedtls 2.18.0 */
tls_connection_export_keys_cb(void * p_expkey,const unsigned char * ms,const unsigned char * kb,size_t maclen,size_t keylen,size_t ivlen,const unsigned char client_random[MBEDTLS_EXPKEY_RAND_LEN],const unsigned char server_random[MBEDTLS_EXPKEY_RAND_LEN],mbedtls_tls_prf_types tls_prf_type)2029 static int tls_connection_export_keys_cb(void *p_expkey,
2030 const unsigned char *ms,
2031 const unsigned char *kb,
2032 size_t maclen,
2033 size_t keylen,
2034 size_t ivlen,
2035 const unsigned char client_random[MBEDTLS_EXPKEY_RAND_LEN],
2036 const unsigned char server_random[MBEDTLS_EXPKEY_RAND_LEN],
2037 mbedtls_tls_prf_types tls_prf_type)
2038 {
2039 struct tls_connection *conn = p_expkey;
2040 conn->tls_prf_type = tls_prf_type;
2041 if (!tls_prf_type)
2042 return -1; /*(return value ignored by mbedtls)*/
2043 conn->expkey_keyblock_size = maclen + keylen + ivlen;
2044 conn->expkey_secret_len = MBEDTLS_EXPKEY_FIXED_SECRET_LEN;
2045 os_memcpy(conn->expkey_secret, ms, MBEDTLS_EXPKEY_FIXED_SECRET_LEN);
2046 os_memcpy(conn->expkey_randbytes, client_random, MBEDTLS_EXPKEY_RAND_LEN);
2047 os_memcpy(conn->expkey_randbytes + MBEDTLS_EXPKEY_RAND_LEN, server_random, MBEDTLS_EXPKEY_RAND_LEN);
2048 return 0;
2049 }
2050 #endif
2051
tls_connection_get_random(void * tls_ctx,struct tls_connection * conn,struct tls_random * data)2052 int tls_connection_get_random(void *tls_ctx, struct tls_connection *conn, struct tls_random *data)
2053 {
2054 if (!conn || !conn->tls_prf_type)
2055 return -1;
2056 data->client_random = conn->expkey_randbytes;
2057 data->client_random_len = MBEDTLS_EXPKEY_RAND_LEN;
2058 data->server_random = conn->expkey_randbytes + MBEDTLS_EXPKEY_RAND_LEN;
2059 data->server_random_len = MBEDTLS_EXPKEY_RAND_LEN;
2060 return 0;
2061 }
2062
tls_connection_export_key(void * tls_ctx,struct tls_connection * conn,const char * label,const u8 * context,size_t context_len,u8 * out,size_t out_len)2063 int tls_connection_export_key(void *tls_ctx,
2064 struct tls_connection *conn,
2065 const char *label,
2066 const u8 *context,
2067 size_t context_len,
2068 u8 *out,
2069 size_t out_len)
2070 {
2071 /* (EAP-PEAP EAP-TLS EAP-TTLS) */
2072 #if MBEDTLS_VERSION_NUMBER >= 0x02120000 /* mbedtls 2.18.0 */
2073 return (conn && conn->established && conn->tls_prf_type) ?
2074 mbedtls_ssl_tls_prf(conn->tls_prf_type, conn->expkey_secret, conn->expkey_secret_len, label,
2075 conn->expkey_randbytes, sizeof(conn->expkey_randbytes), out, out_len) :
2076 -1;
2077 #else
2078 /* not implemented here for mbedtls < 2.18.0 */
2079 return -1;
2080 #endif
2081 }
2082
2083 #ifdef TLS_MBEDTLS_EAP_FAST
2084
2085 #if MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.0.0 */
2086 /* keyblock size info is not exposed in mbed TLS 3.0.0 */
2087 /* extracted from mbedtls library/ssl_tls.c:ssl_tls12_populate_transform() */
2088 #include <mbedtls/ssl_ciphersuites.h>
2089 #include <mbedtls/cipher.h>
tls_mbedtls_ssl_keyblock_size(mbedtls_ssl_context * ssl)2090 static size_t tls_mbedtls_ssl_keyblock_size(mbedtls_ssl_context *ssl)
2091 {
2092 #if !defined(MBEDTLS_USE_PSA_CRYPTO) /* XXX: (not extracted for PSA crypto) */
2093 #if defined(MBEDTLS_SSL_PROTO_TLS1_3)
2094 if (tls_version == MBEDTLS_SSL_VERSION_TLS1_3)
2095 return 0; /* (calculation not extracted) */
2096 #endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
2097
2098 int ciphersuite = mbedtls_ssl_get_ciphersuite_id_from_ssl(ssl);
2099 const mbedtls_ssl_ciphersuite_t *ciphersuite_info = mbedtls_ssl_ciphersuite_from_id(ciphersuite);
2100 if (ciphersuite_info == NULL)
2101 return 0;
2102
2103 const mbedtls_cipher_info_t *cipher_info = mbedtls_cipher_info_from_type(ciphersuite_info->MBEDTLS_PRIVATE(cipher));
2104 if (cipher_info == NULL)
2105 return 0;
2106
2107 #if MBEDTLS_VERSION_NUMBER >= 0x03010000 /* mbedtls 3.1.0 */
2108 size_t keylen = mbedtls_cipher_info_get_key_bitlen(cipher_info) / 8;
2109 mbedtls_cipher_mode_t mode = mbedtls_cipher_info_get_mode(cipher_info);
2110 #else
2111 size_t keylen = cipher_info->MBEDTLS_PRIVATE(key_bitlen) / 8;
2112 mbedtls_cipher_mode_t mode = cipher_info->MBEDTLS_PRIVATE(mode);
2113 #endif
2114 #if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
2115 if (mode == MBEDTLS_MODE_GCM || mode == MBEDTLS_MODE_CCM)
2116 return keylen + 4;
2117 else if (mode == MBEDTLS_MODE_CHACHAPOLY)
2118 return keylen + 12;
2119 else
2120 #endif /* MBEDTLS_GCM_C || MBEDTLS_CCM_C || MBEDTLS_CHACHAPOLY_C */
2121 #if defined(MBEDTLS_SSL_SOME_SUITES_USE_MAC)
2122 {
2123 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(ciphersuite_info->MBEDTLS_PRIVATE(mac));
2124 if (md_info == NULL)
2125 return 0;
2126 size_t mac_key_len = mbedtls_md_get_size(md_info);
2127 size_t ivlen = mbedtls_cipher_info_get_iv_size(cipher_info);
2128 return keylen + mac_key_len + ivlen;
2129 }
2130 #endif /* MBEDTLS_SSL_SOME_SUITES_USE_MAC */
2131 #endif /* !MBEDTLS_USE_PSA_CRYPTO */ /* (not extracted for PSA crypto) */
2132 return 0;
2133 }
2134 #endif /* MBEDTLS_VERSION_NUMBER >= 0x03000000 */ /* mbedtls 3.0.0 */
2135
tls_connection_get_eap_fast_key(void * tls_ctx,struct tls_connection * conn,u8 * out,size_t out_len)2136 int tls_connection_get_eap_fast_key(void *tls_ctx, struct tls_connection *conn, u8 *out, size_t out_len)
2137 {
2138 /* XXX: has export keys callback been run? */
2139 if (!conn || !conn->tls_prf_type)
2140 return -1;
2141
2142 #if MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.0.0 */
2143 conn->expkey_keyblock_size = tls_mbedtls_ssl_keyblock_size(&conn->ssl);
2144 if (conn->expkey_keyblock_size == 0)
2145 return -1;
2146 #endif
2147 size_t skip = conn->expkey_keyblock_size * 2;
2148 unsigned char *tmp_out = os_malloc(skip + out_len);
2149 if (!tmp_out)
2150 return -1;
2151
2152 /* server_random and then client_random */
2153 unsigned char seed[MBEDTLS_EXPKEY_RAND_LEN * 2];
2154 os_memcpy(seed, conn->expkey_randbytes + MBEDTLS_EXPKEY_RAND_LEN, MBEDTLS_EXPKEY_RAND_LEN);
2155 os_memcpy(seed + MBEDTLS_EXPKEY_RAND_LEN, conn->expkey_randbytes, MBEDTLS_EXPKEY_RAND_LEN);
2156
2157 #if MBEDTLS_VERSION_NUMBER >= 0x02120000 /* mbedtls 2.18.0 */
2158 int ret = mbedtls_ssl_tls_prf(conn->tls_prf_type, conn->expkey_secret, conn->expkey_secret_len, "key expansion",
2159 seed, sizeof(seed), tmp_out, skip + out_len);
2160 if (ret == 0)
2161 os_memcpy(out, tmp_out + skip, out_len);
2162 #else
2163 int ret = -1; /*(not reached if not impl; return -1 at top of func)*/
2164 #endif
2165
2166 bin_clear_free(tmp_out, skip + out_len);
2167 forced_memzero(seed, sizeof(seed));
2168 return ret;
2169 }
2170
2171 #endif /* TLS_MBEDTLS_EAP_FAST */
2172
tls_mbedtls_suiteb_handshake_alert(struct tls_connection * conn)2173 __attribute_cold__ static void tls_mbedtls_suiteb_handshake_alert(struct tls_connection *conn)
2174 {
2175 /* tests/hwsim/test_suite_b.py test_suite_b_192_rsa_insufficient_dh */
2176 if (!(conn->tls_conf->flags & TLS_CONN_SUITEB))
2177 return;
2178 if (tls_ctx_global.tls_conf) /*(is server; want issue event on client)*/
2179 return;
2180
2181 struct tls_config *init_conf = &tls_ctx_global.init_conf;
2182 if (init_conf->event_cb)
2183 {
2184 union tls_event_data ev;
2185 os_memset(&ev, 0, sizeof(ev));
2186 ev.alert.is_local = 1;
2187 ev.alert.type = "fatal";
2188 /*"internal error" string for tests/hwsim/test_suiteb.py */
2189 ev.alert.description = "internal error: handshake failure";
2190 /*ev.alert.description = "insufficient security";*/
2191 init_conf->event_cb(init_conf->cb_ctx, TLS_ALERT, &ev);
2192 }
2193 }
2194
tls_connection_handshake(void * tls_ctx,struct tls_connection * conn,const struct wpabuf * in_data,struct wpabuf ** appl_data)2195 struct wpabuf *tls_connection_handshake(void *tls_ctx,
2196 struct tls_connection *conn,
2197 const struct wpabuf *in_data,
2198 struct wpabuf **appl_data)
2199 {
2200 if (appl_data)
2201 *appl_data = NULL;
2202
2203 if (in_data && wpabuf_len(in_data))
2204 {
2205 /*(unsure why tls_gnutls.c discards buffer contents; skip here)*/
2206 if (conn->pull_buf && 0) /* disable; appears unwise */
2207 tls_pull_buf_discard(conn, __func__);
2208 if (!tls_pull_buf_append(conn, in_data))
2209 return NULL;
2210 }
2211
2212 if (conn->tls_conf == NULL)
2213 {
2214 struct tls_connection_params params;
2215 os_memset(¶ms, 0, sizeof(params));
2216 params.openssl_ciphers = tls_ctx_global.init_conf.openssl_ciphers;
2217 params.flags = tls_ctx_global.tls_conf->flags;
2218 if (tls_connection_set_params(tls_ctx, conn, ¶ms) != 0)
2219 return NULL;
2220 }
2221
2222 if (conn->verify_peer) /*(call here might be redundant; nbd)*/
2223 mbedtls_ssl_set_verify(&conn->ssl, tls_mbedtls_verify_cb, conn);
2224
2225 #ifdef TLS_MBEDTLS_SESSION_TICKETS
2226 if (conn->clienthello_session_ticket)
2227 /*(starting handshake for EAP-FAST and EAP-TEAP)*/
2228 tls_mbedtls_clienthello_session_ticket_set(conn);
2229
2230 /* (not thread-safe due to need to set userdata 'conn' for callback) */
2231 /* (unable to use mbedtls_ssl_set_user_data_p() with mbedtls 3.2.0+
2232 * since ticket write and parse callbacks take (mbedtls_ssl_session *)
2233 * param instead of (mbedtls_ssl_context *) param) */
2234 if (conn->tls_conf->flags & TLS_CONN_DISABLE_SESSION_TICKET)
2235 mbedtls_ssl_conf_session_tickets_cb(&conn->tls_conf->conf, NULL, NULL, NULL);
2236 else
2237 mbedtls_ssl_conf_session_tickets_cb(&conn->tls_conf->conf, tls_mbedtls_ssl_ticket_write,
2238 tls_mbedtls_ssl_ticket_parse, conn);
2239 #endif
2240
2241 #if MBEDTLS_VERSION_NUMBER >= 0x03020000 /* mbedtls 3.2.0 */
2242 int ret = mbedtls_ssl_handshake(&conn->ssl);
2243 #else
2244 int ret = 0;
2245 while (conn->ssl.MBEDTLS_PRIVATE(state) != MBEDTLS_SSL_HANDSHAKE_OVER)
2246 {
2247 ret = mbedtls_ssl_handshake_step(&conn->ssl);
2248 if (ret != 0)
2249 break;
2250 }
2251 #endif
2252
2253 #ifdef TLS_MBEDTLS_SESSION_TICKETS
2254 mbedtls_ssl_conf_session_tickets_cb(&conn->tls_conf->conf, tls_mbedtls_ssl_ticket_write,
2255 tls_mbedtls_ssl_ticket_parse, NULL);
2256 #endif
2257
2258 switch (ret)
2259 {
2260 case 0:
2261 conn->established = 1;
2262 if (conn->push_buf == NULL)
2263 /* Need to return something to get final TLS ACK. */
2264 conn->push_buf = wpabuf_alloc(0);
2265
2266 if (appl_data /*&& conn->pull_buf && wpabuf_len(conn->pull_buf)*/)
2267 *appl_data = NULL; /* RFE: check for application data */
2268 break;
2269 case MBEDTLS_ERR_SSL_WANT_WRITE:
2270 case MBEDTLS_ERR_SSL_WANT_READ:
2271 case MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS:
2272 case MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS:
2273 if (tls_ctx_global.tls_conf /*(is server)*/
2274 && conn->established && conn->push_buf == NULL)
2275 /* Need to return something to trigger completion of EAP-TLS. */
2276 conn->push_buf = wpabuf_alloc(0);
2277 break;
2278 default:
2279 ++conn->failed;
2280 switch (ret)
2281 {
2282 case MBEDTLS_ERR_SSL_CLIENT_RECONNECT:
2283 case MBEDTLS_ERR_NET_CONN_RESET:
2284 case MBEDTLS_ERR_NET_SEND_FAILED:
2285 ++conn->write_alerts;
2286 break;
2287 #if MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.0.0 */
2288 case MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE:
2289 #else
2290 case MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE:
2291 #endif
2292 tls_mbedtls_suiteb_handshake_alert(conn);
2293 /* fall through */
2294 case MBEDTLS_ERR_NET_RECV_FAILED:
2295 case MBEDTLS_ERR_SSL_CONN_EOF:
2296 case MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY:
2297 case MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE:
2298 ++conn->read_alerts;
2299 break;
2300 default:
2301 break;
2302 }
2303
2304 ilog(ret, "mbedtls_ssl_handshake");
2305 break;
2306 }
2307
2308 struct wpabuf *out_data = conn->push_buf;
2309 conn->push_buf = NULL;
2310 return out_data;
2311 }
2312
tls_connection_server_handshake(void * tls_ctx,struct tls_connection * conn,const struct wpabuf * in_data,struct wpabuf ** appl_data)2313 struct wpabuf *tls_connection_server_handshake(void *tls_ctx,
2314 struct tls_connection *conn,
2315 const struct wpabuf *in_data,
2316 struct wpabuf **appl_data)
2317 {
2318 conn->is_server = 1;
2319 return tls_connection_handshake(tls_ctx, conn, in_data, appl_data);
2320 }
2321
tls_connection_encrypt(void * tls_ctx,struct tls_connection * conn,const struct wpabuf * in_data)2322 struct wpabuf *tls_connection_encrypt(void *tls_ctx, struct tls_connection *conn, const struct wpabuf *in_data)
2323 {
2324 int res = mbedtls_ssl_write(&conn->ssl, wpabuf_head_u8(in_data), wpabuf_len(in_data));
2325 if (res < 0)
2326 {
2327 elog(res, "mbedtls_ssl_write");
2328 return NULL;
2329 }
2330
2331 struct wpabuf *buf = conn->push_buf;
2332 conn->push_buf = NULL;
2333 return buf;
2334 }
2335
tls_connection_decrypt(void * tls_ctx,struct tls_connection * conn,const struct wpabuf * in_data)2336 struct wpabuf *tls_connection_decrypt(void *tls_ctx, struct tls_connection *conn, const struct wpabuf *in_data)
2337 {
2338 int res;
2339 struct wpabuf *out;
2340
2341 /*assert(in_data != NULL);*/
2342 if (!tls_pull_buf_append(conn, in_data))
2343 return NULL;
2344
2345 #if defined(MBEDTLS_ZLIB_SUPPORT) /* removed in mbedtls 3.x */
2346 /* Add extra buffer space to handle the possibility of decrypted
2347 * data being longer than input data due to TLS compression. */
2348 out = wpabuf_alloc((wpabuf_len(in_data) + 500) * 3);
2349 #else /* TLS compression is disabled in mbedtls 3.x */
2350 out = wpabuf_alloc(wpabuf_len(in_data));
2351 #endif
2352 if (out == NULL)
2353 return NULL;
2354
2355 while ((conn->pull_buf) && ((wpabuf_len(conn->pull_buf) - conn->pull_buf_offset) > 0))
2356 {
2357 res = mbedtls_ssl_read(&conn->ssl, wpabuf_mhead(out), wpabuf_size(out));
2358 if (res < 0)
2359 {
2360 /*(seems like a different error if wpabuf_len(in_data) == 0)*/
2361 if (res == MBEDTLS_ERR_SSL_WANT_READ)
2362 {
2363 return out;
2364 }
2365 elog(res, "mbedtls_ssl_read");
2366 wpabuf_free(out);
2367 return NULL;
2368 }
2369 wpabuf_put(out, res);
2370 }
2371
2372 return out;
2373 }
2374
tls_connection_resumed(void * tls_ctx,struct tls_connection * conn)2375 int tls_connection_resumed(void *tls_ctx, struct tls_connection *conn)
2376 {
2377 /* XXX: might need to detect if session resumed from TLS session ticket
2378 * even if not special session ticket handling for EAP-FAST, EAP-TEAP */
2379 /* (?ssl->handshake->resume during session ticket validation?) */
2380 return conn && conn->resumed;
2381 }
2382
2383 #ifdef TLS_MBEDTLS_EAP_FAST
tls_connection_set_cipher_list(void * tls_ctx,struct tls_connection * conn,u8 * ciphers)2384 int tls_connection_set_cipher_list(void *tls_ctx, struct tls_connection *conn, u8 *ciphers)
2385 {
2386 /* ciphers is list of TLS_CIPHER_* from hostap/src/crypto/tls.h */
2387 int ids[7];
2388 const int idsz = (int)sizeof(ids);
2389 int nids = -1, id;
2390 for (; *ciphers != TLS_CIPHER_NONE; ++ciphers)
2391 {
2392 switch (*ciphers)
2393 {
2394 case TLS_CIPHER_RC4_SHA:
2395 #ifdef MBEDTLS_TLS_RSA_WITH_RC4_128_SHA
2396 id = MBEDTLS_TLS_RSA_WITH_RC4_128_SHA;
2397 break;
2398 #else
2399 continue; /*(not supported in mbedtls 3.x; ignore)*/
2400 #endif
2401 case TLS_CIPHER_AES128_SHA:
2402 id = MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA;
2403 break;
2404 case TLS_CIPHER_RSA_DHE_AES128_SHA:
2405 id = MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA;
2406 break;
2407 case TLS_CIPHER_ANON_DH_AES128_SHA:
2408 continue; /*(not supported in mbedtls; ignore)*/
2409 case TLS_CIPHER_RSA_DHE_AES256_SHA:
2410 id = MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA;
2411 break;
2412 case TLS_CIPHER_AES256_SHA:
2413 id = MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA;
2414 break;
2415 default:
2416 return -1; /* should not happen */
2417 }
2418 if (++nids == idsz)
2419 return -1; /* should not happen */
2420 ids[nids] = id;
2421 }
2422 if (nids < 0)
2423 return 0; /* nothing to do */
2424 if (++nids == idsz)
2425 return -1; /* should not happen */
2426 ids[nids] = 0; /* terminate list */
2427 ++nids;
2428
2429 return tls_mbedtls_set_ciphersuites(conn->tls_conf, ids, nids) ? 0 : -1;
2430 }
2431 #endif
2432
tls_get_version(void * ssl_ctx,struct tls_connection * conn,char * buf,size_t buflen)2433 int tls_get_version(void *ssl_ctx, struct tls_connection *conn, char *buf, size_t buflen)
2434 {
2435 if (conn == NULL)
2436 return -1;
2437 os_strlcpy(buf, mbedtls_ssl_get_version(&conn->ssl), buflen);
2438 return buf[0] != 'u' ? 0 : -1; /*(-1 if "unknown")*/
2439 }
2440
2441 #ifdef TLS_MBEDTLS_EAP_TEAP
tls_connection_get_cipher_suite(struct tls_connection * conn)2442 u16 tls_connection_get_cipher_suite(struct tls_connection *conn)
2443 {
2444 if (conn == NULL)
2445 return 0;
2446 return (u16)mbedtls_ssl_get_ciphersuite_id_from_ssl(&conn->ssl);
2447 }
2448 #endif
2449
tls_get_cipher(void * tls_ctx,struct tls_connection * conn,char * buf,size_t buflen)2450 int tls_get_cipher(void *tls_ctx, struct tls_connection *conn, char *buf, size_t buflen)
2451 {
2452 if (conn == NULL)
2453 return -1;
2454 const int id = mbedtls_ssl_get_ciphersuite_id_from_ssl(&conn->ssl);
2455 return tls_mbedtls_translate_ciphername(id, buf, buflen) ? 0 : -1;
2456 }
2457
2458 #ifdef TLS_MBEDTLS_SESSION_TICKETS
2459
tls_connection_enable_workaround(void * tls_ctx,struct tls_connection * conn)2460 int tls_connection_enable_workaround(void *tls_ctx, struct tls_connection *conn)
2461 {
2462 /* (see comment in src/eap_peer/eap_fast.c:eap_fast_init()) */
2463 /* XXX: is there a relevant setting for this in mbed TLS? */
2464 /* (do we even care that much about older CBC ciphers?) */
2465 return 0;
2466 }
2467
tls_connection_client_hello_ext(void * tls_ctx,struct tls_connection * conn,int ext_type,const u8 * data,size_t data_len)2468 int tls_connection_client_hello_ext(
2469 void *tls_ctx, struct tls_connection *conn, int ext_type, const u8 *data, size_t data_len)
2470 {
2471 /* (EAP-FAST and EAP-TEAP) */
2472 if (ext_type == MBEDTLS_TLS_EXT_SESSION_TICKET) /*(ext_type == 35)*/
2473 return tls_mbedtls_clienthello_session_ticket_prep(conn, data, data_len);
2474
2475 return -1;
2476 }
2477
2478 #endif /* TLS_MBEDTLS_SESSION_TICKETS */
2479
tls_connection_get_failed(void * tls_ctx,struct tls_connection * conn)2480 int tls_connection_get_failed(void *tls_ctx, struct tls_connection *conn)
2481 {
2482 return conn ? conn->failed : -1;
2483 }
2484
tls_connection_get_read_alerts(void * tls_ctx,struct tls_connection * conn)2485 int tls_connection_get_read_alerts(void *tls_ctx, struct tls_connection *conn)
2486 {
2487 return conn ? conn->read_alerts : -1;
2488 }
2489
tls_connection_get_write_alerts(void * tls_ctx,struct tls_connection * conn)2490 int tls_connection_get_write_alerts(void *tls_ctx, struct tls_connection *conn)
2491 {
2492 return conn ? conn->write_alerts : -1;
2493 }
2494
2495 #ifdef TLS_MBEDTLS_SESSION_TICKETS
tls_connection_set_session_ticket_cb(void * tls_ctx,struct tls_connection * conn,tls_session_ticket_cb cb,void * ctx)2496 int tls_connection_set_session_ticket_cb(void *tls_ctx,
2497 struct tls_connection *conn,
2498 tls_session_ticket_cb cb,
2499 void *ctx)
2500 {
2501 if (!(conn->tls_conf->flags & TLS_CONN_DISABLE_SESSION_TICKET))
2502 {
2503 /* (EAP-FAST and EAP-TEAP) */
2504 conn->session_ticket_cb = cb;
2505 conn->session_ticket_cb_ctx = ctx;
2506 return 0;
2507 }
2508 return -1;
2509 }
2510 #endif
2511
tls_get_library_version(char * buf,size_t buf_len)2512 int tls_get_library_version(char *buf, size_t buf_len)
2513 {
2514 #ifndef MBEDTLS_VERSION_C
2515 const char *const ver = "n/a";
2516 #else
2517 char ver[9];
2518 mbedtls_version_get_string(ver);
2519 #endif
2520 return os_snprintf(buf, buf_len, "mbed TLS build=" MBEDTLS_VERSION_STRING " run=%s", ver);
2521 }
2522
tls_connection_set_success_data(struct tls_connection * conn,struct wpabuf * data)2523 void tls_connection_set_success_data(struct tls_connection *conn, struct wpabuf *data)
2524 {
2525 wpabuf_free(conn->success_data);
2526 conn->success_data = data;
2527 }
2528
tls_connection_set_success_data_resumed(struct tls_connection * conn)2529 void tls_connection_set_success_data_resumed(struct tls_connection *conn)
2530 {
2531 }
2532
tls_connection_get_success_data(struct tls_connection * conn)2533 const struct wpabuf *tls_connection_get_success_data(struct tls_connection *conn)
2534 {
2535 return conn->success_data;
2536 }
2537
tls_connection_remove_session(struct tls_connection * conn)2538 void tls_connection_remove_session(struct tls_connection *conn)
2539 {
2540 }
2541
2542 #ifdef TLS_MBEDTLS_EAP_TEAP
tls_get_tls_unique(struct tls_connection * conn,u8 * buf,size_t max_len)2543 int tls_get_tls_unique(struct tls_connection *conn, u8 *buf, size_t max_len)
2544 {
2545 #if defined(MBEDTLS_SSL_RENEGOTIATION) /* XXX: renegotiation or resumption? */
2546 /* data from TLS handshake Finished message */
2547 size_t verify_len = conn->ssl.MBEDTLS_PRIVATE(verify_data_len);
2548 char *verify_data = (conn->is_server ^ conn->resumed) ? conn->ssl.MBEDTLS_PRIVATE(peer_verify_data) :
2549 conn->ssl.MBEDTLS_PRIVATE(own_verify_data);
2550 if (verify_len && verify_len <= max_len)
2551 {
2552 os_memcpy(buf, verify_data, verify_len);
2553 return (int)verify_len;
2554 }
2555 #endif
2556 return -1;
2557 }
2558 #endif
2559
tls_mbedtls_set_peer_subject(struct tls_connection * conn,const mbedtls_x509_crt * crt)2560 __attribute_noinline__ static void tls_mbedtls_set_peer_subject(struct tls_connection *conn,
2561 const mbedtls_x509_crt *crt)
2562 {
2563 if (conn->peer_subject)
2564 return;
2565 char buf[MBEDTLS_X509_MAX_DN_NAME_SIZE * 2];
2566 int buflen = mbedtls_x509_dn_gets(buf, sizeof(buf), &crt->subject);
2567 if (buflen >= 0 && (conn->peer_subject = os_malloc((size_t)buflen + 1)))
2568 os_memcpy(conn->peer_subject, buf, (size_t)buflen + 1);
2569 }
2570
2571 #ifdef TLS_MBEDTLS_EAP_TEAP
tls_connection_get_peer_subject(struct tls_connection * conn)2572 const char *tls_connection_get_peer_subject(struct tls_connection *conn)
2573 {
2574 if (!conn)
2575 return NULL;
2576 if (!conn->peer_subject)
2577 { /*(if not set during cert verify)*/
2578 const mbedtls_x509_crt *peer_cert = mbedtls_ssl_get_peer_cert(&conn->ssl);
2579 if (peer_cert)
2580 tls_mbedtls_set_peer_subject(conn, peer_cert);
2581 }
2582 return conn->peer_subject;
2583 }
2584 #endif
2585
2586 #ifdef TLS_MBEDTLS_EAP_TEAP
tls_connection_get_own_cert_used(struct tls_connection * conn)2587 bool tls_connection_get_own_cert_used(struct tls_connection *conn)
2588 {
2589 /* XXX: availability of cert does not necessary mean that client
2590 * received certificate request from server and then sent cert.
2591 * ? step handshake in tls_connection_handshake() looking for
2592 * MBEDTLS_SSL_CERTIFICATE_REQUEST ? */
2593 const struct tls_conf *const tls_conf = conn->tls_conf;
2594 return (tls_conf->has_client_cert && tls_conf->has_private_key);
2595 }
2596 #endif
2597
2598 #if defined(CONFIG_FIPS)
2599 #define TLS_MBEDTLS_CONFIG_FIPS
2600 #endif
2601
2602 #if defined(CONFIG_SHA256)
2603 #define TLS_MBEDTLS_TLS_PRF_SHA256
2604 #endif
2605
2606 #if defined(CONFIG_SHA384)
2607 #define TLS_MBEDTLS_TLS_PRF_SHA384
2608 #endif
2609
2610 #ifndef TLS_MBEDTLS_CONFIG_FIPS
2611 #if defined(CONFIG_MODULE_TESTS)
2612 /* unused with CONFIG_TLS=mbedtls except in crypto_module_tests.c */
2613 #if MBEDTLS_VERSION_NUMBER >= 0x02120000 /* mbedtls 2.18.0 */ \
2614 && MBEDTLS_VERSION_NUMBER < 0x03000000 /* mbedtls 3.0.0 */
2615 /* sha1-tlsprf.c */
2616 #include "sha1.h"
tls_prf_sha1_md5(const u8 * secret,size_t secret_len,const char * label,const u8 * seed,size_t seed_len,u8 * out,size_t outlen)2617 int tls_prf_sha1_md5(
2618 const u8 *secret, size_t secret_len, const char *label, const u8 *seed, size_t seed_len, u8 *out, size_t outlen)
2619 {
2620 return mbedtls_ssl_tls_prf(MBEDTLS_SSL_TLS_PRF_TLS1, secret, secret_len, label, seed, seed_len, out, outlen) ? -1 :
2621 0;
2622 }
2623 #else
2624 #include "sha1-tlsprf.c" /* pull in hostap local implementation */
2625 #endif
2626 #endif
2627 #endif
2628
2629 #ifdef TLS_MBEDTLS_TLS_PRF_SHA256
2630 /* sha256-tlsprf.c */
2631 #if MBEDTLS_VERSION_NUMBER >= 0x02120000 /* mbedtls 2.18.0 */
2632 #include "sha256.h"
tls_prf_sha256(const u8 * secret,size_t secret_len,const char * label,const u8 * seed,size_t seed_len,u8 * out,size_t outlen)2633 int tls_prf_sha256(
2634 const u8 *secret, size_t secret_len, const char *label, const u8 *seed, size_t seed_len, u8 *out, size_t outlen)
2635 {
2636 return mbedtls_ssl_tls_prf(MBEDTLS_SSL_TLS_PRF_SHA256, secret, secret_len, label, seed, seed_len, out, outlen) ?
2637 -1 :
2638 0;
2639 }
2640 #else
2641 #include "sha256-tlsprf.c" /* pull in hostap local implementation */
2642 #endif
2643 #endif
2644
2645 #ifdef TLS_MBEDTLS_TLS_PRF_SHA384
2646 /* sha384-tlsprf.c */
2647 #if MBEDTLS_VERSION_NUMBER >= 0x02120000 /* mbedtls 2.18.0 */
2648 #include "sha384.h"
tls_prf_sha384(const u8 * secret,size_t secret_len,const char * label,const u8 * seed,size_t seed_len,u8 * out,size_t outlen)2649 int tls_prf_sha384(
2650 const u8 *secret, size_t secret_len, const char *label, const u8 *seed, size_t seed_len, u8 *out, size_t outlen)
2651 {
2652 return mbedtls_ssl_tls_prf(MBEDTLS_SSL_TLS_PRF_SHA384, secret, secret_len, label, seed, seed_len, out, outlen) ?
2653 -1 :
2654 0;
2655 }
2656 #else
2657 #include "sha384-tlsprf.c" /* pull in hostap local implementation */
2658 #endif
2659 #endif
2660
2661 #ifdef TLS_MBEDTLS_CERT_VERIFY_EXTMATCH
2662
2663 #if MBEDTLS_VERSION_NUMBER < 0x03020000 /* mbedtls 3.2.0 */
2664 #define mbedtls_x509_crt_has_ext_type(crt, ext_type) ((crt)->MBEDTLS_PRIVATE(ext_types) & (ext_type))
2665 #endif
2666
2667 struct mlist
2668 {
2669 const char *p;
2670 size_t n;
2671 };
2672
tls_mbedtls_match_altsubject(mbedtls_x509_crt * crt,const char * match)2673 static int tls_mbedtls_match_altsubject(mbedtls_x509_crt *crt, const char *match)
2674 {
2675 /* RFE: this could be pre-parsed into structured data at config time */
2676 struct mlist list[256]; /*(much larger than expected)*/
2677 int nlist = 0;
2678 if (os_strncmp(match, "EMAIL:", 6) != 0 && os_strncmp(match, "DNS:", 4) != 0 && os_strncmp(match, "URI:", 4) != 0)
2679 {
2680 wpa_printf(MSG_INFO, "MTLS: Invalid altSubjectName match '%s'", match);
2681 return 0;
2682 }
2683 for (const char *s = match, *tok; *s; s = tok ? tok + 1 : "")
2684 {
2685 do
2686 {
2687 } while ((tok = os_strchr(s, ';')) && os_strncmp(tok + 1, "EMAIL:", 6) != 0 &&
2688 os_strncmp(tok + 1, "DNS:", 4) != 0 && os_strncmp(tok + 1, "URI:", 4) != 0);
2689 list[nlist].p = s;
2690 list[nlist].n = tok ? (size_t)(tok - s) : os_strlen(s);
2691 if (list[nlist].n && ++nlist == sizeof(list) / sizeof(*list))
2692 {
2693 wpa_printf(MSG_INFO, "MTLS: excessive altSubjectName match '%s'", match);
2694 break; /* truncate huge list and continue */
2695 }
2696 }
2697
2698 if (!mbedtls_x509_crt_has_ext_type(crt, MBEDTLS_X509_EXT_SUBJECT_ALT_NAME))
2699 return 0;
2700
2701 const mbedtls_x509_sequence *cur = &crt->subject_alt_names;
2702 for (; cur != NULL; cur = cur->next)
2703 {
2704 const unsigned char san_type = (unsigned char)cur->buf.tag & MBEDTLS_ASN1_TAG_VALUE_MASK;
2705 char t;
2706 size_t step = 4;
2707 switch (san_type)
2708 { /* "EMAIL:" or "DNS:" or "URI:" */
2709 case MBEDTLS_X509_SAN_RFC822_NAME:
2710 step = 6;
2711 t = 'E';
2712 break;
2713 case MBEDTLS_X509_SAN_DNS_NAME:
2714 t = 'D';
2715 break;
2716 case MBEDTLS_X509_SAN_UNIFORM_RESOURCE_IDENTIFIER:
2717 t = 'U';
2718 break;
2719 default:
2720 continue;
2721 }
2722
2723 for (int i = 0; i < nlist; ++i)
2724 {
2725 /* step over "EMAIL:" or "DNS:" or "URI:" in list[i].p */
2726 /* Note: v is not '\0'-terminated, but is a known length vlen,
2727 * so okay to pass to os_strncasecmp() even though not z-string */
2728 if (cur->buf.len == list[i].n - step && t == *list[i].p &&
2729 0 == os_strncasecmp((char *)cur->buf.p, list[i].p + step, cur->buf.len))
2730 {
2731 return 1; /* match */
2732 }
2733 }
2734 }
2735 return 0; /* no match */
2736 }
2737
tls_mbedtls_match_suffix(const char * v,size_t vlen,const struct mlist * list,int nlist,int full)2738 static int tls_mbedtls_match_suffix(const char *v, size_t vlen, const struct mlist *list, int nlist, int full)
2739 {
2740 /* Note: v is not '\0'-terminated, but is a known length vlen,
2741 * so okay to pass to os_strncasecmp() even though not z-string */
2742 for (int i = 0; i < nlist; ++i)
2743 {
2744 size_t n = list[i].n;
2745 if ((n == vlen || (n < vlen && v[vlen - n - 1] == '.' && !full)) &&
2746 0 == os_strncasecmp(v + vlen - n, list[i].p, n))
2747 return 1; /* match */
2748 }
2749 return 0; /* no match */
2750 }
2751
tls_mbedtls_match_suffixes(mbedtls_x509_crt * crt,const char * match,int full)2752 static int tls_mbedtls_match_suffixes(mbedtls_x509_crt *crt, const char *match, int full)
2753 {
2754 /* RFE: this could be pre-parsed into structured data at config time */
2755 struct mlist list[256]; /*(much larger than expected)*/
2756 int nlist = 0;
2757 for (const char *s = match, *tok; *s; s = tok ? tok + 1 : "")
2758 {
2759 tok = os_strchr(s, ';');
2760 list[nlist].p = s;
2761 list[nlist].n = tok ? (size_t)(tok - s) : os_strlen(s);
2762 if (list[nlist].n && ++nlist == sizeof(list) / sizeof(*list))
2763 {
2764 wpa_printf(MSG_INFO, "MTLS: excessive suffix match '%s'", match);
2765 break; /* truncate huge list and continue */
2766 }
2767 }
2768
2769 /* check subjectAltNames */
2770 if (mbedtls_x509_crt_has_ext_type(crt, MBEDTLS_X509_EXT_SUBJECT_ALT_NAME))
2771 {
2772 const mbedtls_x509_sequence *cur = &crt->subject_alt_names;
2773 for (; cur != NULL; cur = cur->next)
2774 {
2775 const unsigned char san_type = (unsigned char)cur->buf.tag & MBEDTLS_ASN1_TAG_VALUE_MASK;
2776 if (san_type == MBEDTLS_X509_SAN_DNS_NAME &&
2777 tls_mbedtls_match_suffix((char *)cur->buf.p, cur->buf.len, list, nlist, full))
2778 {
2779 return 1; /* match */
2780 }
2781 }
2782 }
2783
2784 /* check subject CN */
2785 const mbedtls_x509_name *name = &crt->subject;
2786 for (; name != NULL; name = name->next)
2787 {
2788 if (name->oid.p && MBEDTLS_OID_CMP(MBEDTLS_OID_AT_CN, &name->oid) == 0)
2789 break;
2790 }
2791 if (name && tls_mbedtls_match_suffix((char *)name->val.p, name->val.len, list, nlist, full))
2792 {
2793 return 1; /* match */
2794 }
2795
2796 return 0; /* no match */
2797 }
2798
tls_mbedtls_match_dn_field(mbedtls_x509_crt * crt,const char * match)2799 static int tls_mbedtls_match_dn_field(mbedtls_x509_crt *crt, const char *match)
2800 {
2801 /* RFE: this could be pre-parsed into structured data at config time */
2802 struct mlistoid
2803 {
2804 const char *p;
2805 size_t n;
2806 const char *oid;
2807 size_t olen;
2808 int prefix;
2809 };
2810 struct mlistoid list[32]; /*(much larger than expected)*/
2811 int nlist = 0;
2812 for (const char *s = match, *tok, *e; *s; s = tok ? tok + 1 : "")
2813 {
2814 tok = os_strchr(s, '/');
2815 list[nlist].oid = NULL;
2816 list[nlist].olen = 0;
2817 list[nlist].n = tok ? (size_t)(tok - s) : os_strlen(s);
2818 e = memchr(s, '=', list[nlist].n);
2819 if (e == NULL)
2820 {
2821 if (list[nlist].n == 0)
2822 continue; /* skip consecutive, repeated '/' */
2823 if (list[nlist].n == 1 && *s == '*')
2824 {
2825 /* special-case "*" to match any OID and value */
2826 s = e = "=*";
2827 list[nlist].n = 2;
2828 list[nlist].oid = "";
2829 }
2830 else
2831 {
2832 wpa_printf(MSG_INFO, "MTLS: invalid check_cert_subject '%s' missing '='", match);
2833 return 0;
2834 }
2835 }
2836 switch (e - s)
2837 {
2838 case 1:
2839 if (*s == 'C')
2840 {
2841 list[nlist].oid = MBEDTLS_OID_AT_COUNTRY;
2842 list[nlist].olen = sizeof(MBEDTLS_OID_AT_COUNTRY) - 1;
2843 }
2844 else if (*s == 'L')
2845 {
2846 list[nlist].oid = MBEDTLS_OID_AT_LOCALITY;
2847 list[nlist].olen = sizeof(MBEDTLS_OID_AT_LOCALITY) - 1;
2848 }
2849 else if (*s == 'O')
2850 {
2851 list[nlist].oid = MBEDTLS_OID_AT_ORGANIZATION;
2852 list[nlist].olen = sizeof(MBEDTLS_OID_AT_ORGANIZATION) - 1;
2853 }
2854 break;
2855 case 2:
2856 if (s[0] == 'C' && s[1] == 'N')
2857 {
2858 list[nlist].oid = MBEDTLS_OID_AT_CN;
2859 list[nlist].olen = sizeof(MBEDTLS_OID_AT_CN) - 1;
2860 }
2861 else if (s[0] == 'S' && s[1] == 'T')
2862 {
2863 list[nlist].oid = MBEDTLS_OID_AT_STATE;
2864 list[nlist].olen = sizeof(MBEDTLS_OID_AT_STATE) - 1;
2865 }
2866 else if (s[0] == 'O' && s[1] == 'U')
2867 {
2868 list[nlist].oid = MBEDTLS_OID_AT_ORG_UNIT;
2869 list[nlist].olen = sizeof(MBEDTLS_OID_AT_ORG_UNIT) - 1;
2870 }
2871 break;
2872 case 12:
2873 if (os_memcmp(s, "emailAddress", 12) == 0)
2874 {
2875 list[nlist].oid = MBEDTLS_OID_PKCS9_EMAIL;
2876 list[nlist].olen = sizeof(MBEDTLS_OID_PKCS9_EMAIL) - 1;
2877 }
2878 break;
2879 default:
2880 break;
2881 }
2882 if (list[nlist].oid == NULL)
2883 {
2884 wpa_printf(MSG_INFO, "MTLS: Unknown field in check_cert_subject '%s'", match);
2885 return 0;
2886 }
2887 list[nlist].n -= (size_t)(++e - s);
2888 list[nlist].p = e;
2889 if (list[nlist].n && e[list[nlist].n - 1] == '*')
2890 {
2891 --list[nlist].n;
2892 list[nlist].prefix = 1;
2893 }
2894 /*(could easily add support for suffix matches if value begins with '*',
2895 * but suffix match is not currently supported by other TLS modules)*/
2896
2897 if (list[nlist].n && ++nlist == sizeof(list) / sizeof(*list))
2898 {
2899 wpa_printf(MSG_INFO, "MTLS: excessive check_cert_subject match '%s'", match);
2900 break; /* truncate huge list and continue */
2901 }
2902 }
2903
2904 /* each component in match string must match cert Subject in order listed
2905 * The behavior below preserves ordering but is slightly different than
2906 * the grossly inefficient contortions implemented in tls_openssl.c */
2907 const mbedtls_x509_name *name = &crt->subject;
2908 for (int i = 0; i < nlist; ++i)
2909 {
2910 int found = 0;
2911 for (; name != NULL && !found; name = name->next)
2912 {
2913 if (!name->oid.p)
2914 continue;
2915 /* special-case "*" to match any OID and value */
2916 if (list[i].olen == 0)
2917 {
2918 found = 1;
2919 continue;
2920 }
2921 /* perform equalent of !MBEDTLS_OID_CMP() with oid ptr and len */
2922 if (list[i].olen != name->oid.len || os_memcmp(list[i].oid, name->oid.p, name->oid.len) != 0)
2923 continue;
2924 /* Note: v is not '\0'-terminated, but is a known length vlen,
2925 * so okay to pass to os_strncasecmp() even though not z-string */
2926 if ((list[i].prefix ? list[i].n <= name->val.len /* prefix match */
2927 :
2928 list[i].n == name->val.len) /* full match */
2929 && 0 == os_strncasecmp((char *)name->val.p, list[i].p, list[i].n))
2930 {
2931 found = 1;
2932 continue;
2933 }
2934 }
2935 if (!found)
2936 return 0; /* no match */
2937 }
2938 return 1; /* match */
2939 }
2940
2941 #endif /* TLS_MBEDTLS_CERT_VERIFY_EXTMATCH */
2942
tls_mbedtls_verify_fail_event(mbedtls_x509_crt * crt,int depth,const char * errmsg,enum tls_fail_reason reason)2943 __attribute_cold__ static void tls_mbedtls_verify_fail_event(mbedtls_x509_crt *crt,
2944 int depth,
2945 const char *errmsg,
2946 enum tls_fail_reason reason)
2947 {
2948 struct tls_config *init_conf = &tls_ctx_global.init_conf;
2949 if (init_conf->event_cb == NULL)
2950 return;
2951
2952 struct wpabuf *certbuf = wpabuf_alloc_copy(crt->raw.p, crt->raw.len);
2953 char subject[MBEDTLS_X509_MAX_DN_NAME_SIZE * 2];
2954 if (mbedtls_x509_dn_gets(subject, sizeof(subject), &crt->subject) < 0)
2955 subject[0] = '\0';
2956 union tls_event_data ev;
2957 os_memset(&ev, 0, sizeof(ev));
2958 ev.cert_fail.reason = reason;
2959 ev.cert_fail.depth = depth;
2960 ev.cert_fail.subject = subject;
2961 ev.cert_fail.reason_txt = errmsg;
2962 ev.cert_fail.cert = certbuf;
2963
2964 init_conf->event_cb(init_conf->cb_ctx, TLS_CERT_CHAIN_FAILURE, &ev);
2965
2966 wpabuf_free(certbuf);
2967 }
2968
tls_mbedtls_verify_cert_event(struct tls_connection * conn,mbedtls_x509_crt * crt,int depth)2969 __attribute_noinline__ static void tls_mbedtls_verify_cert_event(struct tls_connection *conn,
2970 mbedtls_x509_crt *crt,
2971 int depth)
2972 {
2973 struct tls_config *init_conf = &tls_ctx_global.init_conf;
2974 if (init_conf->event_cb == NULL)
2975 return;
2976
2977 struct wpabuf *certbuf = NULL;
2978 union tls_event_data ev;
2979 os_memset(&ev, 0, sizeof(ev));
2980
2981 #ifdef MBEDTLS_SHA256_C
2982 u8 hash[SHA256_DIGEST_LENGTH];
2983 const u8 *addr[] = {(u8 *)crt->raw.p};
2984 if (sha256_vector(1, addr, &crt->raw.len, hash) == 0)
2985 {
2986 ev.peer_cert.hash = hash;
2987 ev.peer_cert.hash_len = sizeof(hash);
2988 }
2989 #endif
2990 ev.peer_cert.depth = depth;
2991 char subject[MBEDTLS_X509_MAX_DN_NAME_SIZE * 2];
2992 if (depth == 0)
2993 ev.peer_cert.subject = conn->peer_subject;
2994 if (ev.peer_cert.subject == NULL)
2995 {
2996 ev.peer_cert.subject = subject;
2997 if (mbedtls_x509_dn_gets(subject, sizeof(subject), &crt->subject) < 0)
2998 subject[0] = '\0';
2999 }
3000
3001 char serial_num[128 + 1];
3002 ev.peer_cert.serial_num = tls_mbedtls_peer_serial_num(crt, serial_num, sizeof(serial_num));
3003
3004 const mbedtls_x509_sequence *cur;
3005
3006 cur = NULL;
3007 if (mbedtls_x509_crt_has_ext_type(crt, MBEDTLS_X509_EXT_SUBJECT_ALT_NAME))
3008 cur = &crt->subject_alt_names;
3009 for (; cur != NULL; cur = cur->next)
3010 {
3011 const unsigned char san_type = (unsigned char)cur->buf.tag & MBEDTLS_ASN1_TAG_VALUE_MASK;
3012 size_t prelen = 4;
3013 const char *pre;
3014 switch (san_type)
3015 {
3016 case MBEDTLS_X509_SAN_RFC822_NAME:
3017 prelen = 6;
3018 pre = "EMAIL:";
3019 break;
3020 case MBEDTLS_X509_SAN_DNS_NAME:
3021 pre = "DNS:";
3022 break;
3023 case MBEDTLS_X509_SAN_UNIFORM_RESOURCE_IDENTIFIER:
3024 pre = "URI:";
3025 break;
3026 default:
3027 continue;
3028 }
3029
3030 char *pos = os_malloc(prelen + cur->buf.len + 1);
3031 if (pos == NULL)
3032 break;
3033 ev.peer_cert.altsubject[ev.peer_cert.num_altsubject] = pos;
3034 os_memcpy(pos, pre, prelen);
3035 /* data should be properly backslash-escaped if needed,
3036 * so code below does not re-escape, but does replace CTLs */
3037 /*os_memcpy(pos+prelen, cur->buf.p, cur->buf.len);*/
3038 /*pos[prelen+cur->buf.len] = '\0';*/
3039 pos += prelen;
3040 for (size_t i = 0; i < cur->buf.len; ++i)
3041 {
3042 unsigned char c = cur->buf.p[i];
3043 *pos++ = (c >= 32 && c != 127) ? c : '?';
3044 }
3045 *pos = '\0';
3046
3047 if (++ev.peer_cert.num_altsubject == TLS_MAX_ALT_SUBJECT)
3048 break;
3049 }
3050
3051 cur = NULL;
3052 if (mbedtls_x509_crt_has_ext_type(crt, MBEDTLS_X509_EXT_CERTIFICATE_POLICIES))
3053 cur = &crt->certificate_policies;
3054 for (; cur != NULL; cur = cur->next)
3055 {
3056 if (cur->buf.len != 11) /* len of OID_TOD_STRICT or OID_TOD_TOFU */
3057 continue;
3058 /* TOD-STRICT "1.3.6.1.4.1.40808.1.3.1" */
3059 /* TOD-TOFU "1.3.6.1.4.1.40808.1.3.2" */
3060 #define OID_TOD_STRICT "\x2b\x06\x01\x04\x01\x82\xbe\x68\x01\x03\x01"
3061 #define OID_TOD_TOFU "\x2b\x06\x01\x04\x01\x82\xbe\x68\x01\x03\x02"
3062 if (os_memcmp(cur->buf.p, OID_TOD_STRICT, sizeof(OID_TOD_STRICT) - 1) == 0)
3063 {
3064 ev.peer_cert.tod = 1; /* TOD-STRICT */
3065 break;
3066 }
3067 if (os_memcmp(cur->buf.p, OID_TOD_TOFU, sizeof(OID_TOD_TOFU) - 1) == 0)
3068 {
3069 ev.peer_cert.tod = 2; /* TOD-TOFU */
3070 break;
3071 }
3072 }
3073
3074 struct tls_conf *tls_conf = conn->tls_conf;
3075 if (tls_conf->ca_cert_probe || (tls_conf->flags & TLS_CONN_EXT_CERT_CHECK) || init_conf->cert_in_cb)
3076 {
3077 certbuf = wpabuf_alloc_copy(crt->raw.p, crt->raw.len);
3078 ev.peer_cert.cert = certbuf;
3079 }
3080
3081 init_conf->event_cb(init_conf->cb_ctx, TLS_PEER_CERTIFICATE, &ev);
3082
3083 wpabuf_free(certbuf);
3084 char **altsubject;
3085 *(const char ***)&altsubject = ev.peer_cert.altsubject;
3086 for (size_t i = 0; i < ev.peer_cert.num_altsubject; ++i)
3087 os_free(altsubject[i]);
3088 }
3089
tls_mbedtls_verify_cb(void * arg,mbedtls_x509_crt * crt,int depth,uint32_t * flags)3090 static int tls_mbedtls_verify_cb(void *arg, mbedtls_x509_crt *crt, int depth, uint32_t *flags)
3091 {
3092 /* XXX: N.B. verify code not carefully tested besides hwsim tests
3093 *
3094 * RFE: mbedtls_x509_crt_verify_info() and enhance log trace messages
3095 * RFE: review and add support for additional TLS_CONN_* flags
3096 * not handling OCSP (not available in mbedtls)
3097 * ... */
3098
3099 struct tls_connection *conn = (struct tls_connection *)arg;
3100 struct tls_conf *tls_conf = conn->tls_conf;
3101 uint32_t flags_in = *flags;
3102
3103 #if defined(TLS_MBEDTLS_CERT_DISABLE_KEY_USAGE_CHECK)
3104 crt->MBEDTLS_PRIVATE(ext_types) &= ~MBEDTLS_X509_EXT_KEY_USAGE;
3105 crt->MBEDTLS_PRIVATE(ext_types) &= ~MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE;
3106 #endif
3107
3108 if (depth > 8)
3109 { /*(depth 8 picked as arbitrary limit)*/
3110 emsg(MSG_WARNING, "client cert chain too long");
3111 *flags |= MBEDTLS_X509_BADCERT_OTHER; /* cert chain too long */
3112 tls_mbedtls_verify_fail_event(crt, depth, "client cert chain too long", TLS_FAIL_BAD_CERTIFICATE);
3113 }
3114 else if (tls_conf->verify_depth0_only)
3115 {
3116 if (depth > 0)
3117 *flags = 0;
3118 else
3119 {
3120 #ifdef MBEDTLS_SHA256_C
3121 u8 hash[SHA256_DIGEST_LENGTH];
3122 const u8 *addr[] = {(u8 *)crt->raw.p};
3123 if (sha256_vector(1, addr, &crt->raw.len, hash) < 0 ||
3124 os_memcmp(tls_conf->ca_cert_hash, hash, sizeof(hash)) != 0)
3125 {
3126 *flags |= MBEDTLS_X509_BADCERT_NOT_TRUSTED;
3127 tls_mbedtls_verify_fail_event(crt, depth, "cert hash mismatch", TLS_FAIL_UNTRUSTED);
3128 }
3129 else /* hash matches; ignore other issues *except* if revoked)*/
3130 *flags &= MBEDTLS_X509_BADCERT_REVOKED;
3131 #endif
3132 }
3133 }
3134 else if (depth == 0)
3135 {
3136 if (!conn->peer_subject)
3137 tls_mbedtls_set_peer_subject(conn, crt);
3138 /*(use same labels to tls_mbedtls_verify_fail_event() as used in
3139 * other TLS modules so that hwsim tests find exact string match)*/
3140 if (!conn->peer_subject)
3141 { /* error copying subject string */
3142 *flags |= MBEDTLS_X509_BADCERT_OTHER;
3143 tls_mbedtls_verify_fail_event(crt, depth, "internal error", TLS_FAIL_UNSPECIFIED);
3144 }
3145 #ifdef TLS_MBEDTLS_CERT_VERIFY_EXTMATCH
3146 /*(use os_strstr() for subject match as is done in tls_mbedtls.c
3147 * to follow the same behavior, even though a suffix match would
3148 * make more sense. Also, note that strstr match does not
3149 * normalize whitespace (between components) for comparison)*/
3150 else if (tls_conf->subject_match && os_strstr(conn->peer_subject, tls_conf->subject_match) == NULL)
3151 {
3152 wpa_printf(MSG_WARNING, "MTLS: Subject '%s' did not match with '%s'", conn->peer_subject,
3153 tls_conf->subject_match);
3154 *flags |= MBEDTLS_X509_BADCERT_CN_MISMATCH;
3155 tls_mbedtls_verify_fail_event(crt, depth, "Subject mismatch", TLS_FAIL_SUBJECT_MISMATCH);
3156 }
3157 if (tls_conf->altsubject_match && !tls_mbedtls_match_altsubject(crt, tls_conf->altsubject_match))
3158 {
3159 wpa_printf(MSG_WARNING, "MTLS: altSubjectName match '%s' not found", tls_conf->altsubject_match);
3160 *flags |= MBEDTLS_X509_BADCERT_CN_MISMATCH;
3161 tls_mbedtls_verify_fail_event(crt, depth, "AltSubject mismatch", TLS_FAIL_ALTSUBJECT_MISMATCH);
3162 }
3163 if (tls_conf->suffix_match && !tls_mbedtls_match_suffixes(crt, tls_conf->suffix_match, 0))
3164 {
3165 wpa_printf(MSG_WARNING, "MTLS: Domain suffix match '%s' not found", tls_conf->suffix_match);
3166 *flags |= MBEDTLS_X509_BADCERT_CN_MISMATCH;
3167 tls_mbedtls_verify_fail_event(crt, depth, "Domain suffix mismatch", TLS_FAIL_DOMAIN_SUFFIX_MISMATCH);
3168 }
3169 if (tls_conf->domain_match && !tls_mbedtls_match_suffixes(crt, tls_conf->domain_match, 1))
3170 {
3171 wpa_printf(MSG_WARNING, "MTLS: Domain match '%s' not found", tls_conf->domain_match);
3172 *flags |= MBEDTLS_X509_BADCERT_CN_MISMATCH;
3173 tls_mbedtls_verify_fail_event(crt, depth, "Domain mismatch", TLS_FAIL_DOMAIN_MISMATCH);
3174 }
3175 if (tls_conf->check_cert_subject && !tls_mbedtls_match_dn_field(crt, tls_conf->check_cert_subject))
3176 {
3177 *flags |= MBEDTLS_X509_BADCERT_CN_MISMATCH;
3178 tls_mbedtls_verify_fail_event(crt, depth, "Distinguished Name", TLS_FAIL_DN_MISMATCH);
3179 }
3180 #endif
3181 if (tls_conf->flags & TLS_CONN_SUITEB)
3182 {
3183 /* check RSA modulus size (public key bitlen) */
3184 const mbedtls_pk_type_t pk_alg = mbedtls_pk_get_type(&crt->pk);
3185 if ((pk_alg == MBEDTLS_PK_RSA || pk_alg == MBEDTLS_PK_RSASSA_PSS)
3186 #ifdef CONFIG_SUITEB192
3187 && mbedtls_pk_get_bitlen(&crt->pk) < 3072
3188 #else
3189 && mbedtls_pk_get_bitlen(&crt->pk) < 2048
3190 #endif
3191 )
3192 {
3193 /* hwsim suite_b RSA tests expect 3072
3194 * suite_b_192_rsa_ecdhe_radius_rsa2048_client
3195 * suite_b_192_rsa_dhe_radius_rsa2048_client */
3196 *flags |= MBEDTLS_X509_BADCERT_BAD_KEY;
3197 tls_mbedtls_verify_fail_event(crt, depth, "Insufficient RSA modulus size",
3198 TLS_FAIL_INSUFFICIENT_KEY_LEN);
3199 }
3200 }
3201 if (tls_conf->check_crl && tls_conf->crl == NULL)
3202 {
3203 /* see tests/hwsim test_ap_eap.py ap_wpa2_eap_tls_check_crl */
3204 emsg(MSG_WARNING, "check_crl set but no CRL loaded; reject all?");
3205 *flags |= MBEDTLS_X509_BADCERT_OTHER;
3206 tls_mbedtls_verify_fail_event(crt, depth,
3207 "check_crl set but no CRL loaded; "
3208 "reject all?",
3209 TLS_FAIL_BAD_CERTIFICATE);
3210 }
3211 }
3212 else
3213 {
3214 if (tls_conf->check_crl != 2) /* 2 == verify CRLs for all certs */
3215 *flags &= ~MBEDTLS_X509_BADCERT_REVOKED;
3216 }
3217
3218 if (!tls_conf->check_crl_strict)
3219 {
3220 *flags &= ~MBEDTLS_X509_BADCRL_EXPIRED;
3221 *flags &= ~MBEDTLS_X509_BADCRL_FUTURE;
3222 }
3223
3224 if (tls_conf->flags & TLS_CONN_DISABLE_TIME_CHECKS)
3225 {
3226 *flags &= ~MBEDTLS_X509_BADCERT_EXPIRED;
3227 *flags &= ~MBEDTLS_X509_BADCERT_FUTURE;
3228 }
3229
3230 tls_mbedtls_verify_cert_event(conn, crt, depth);
3231
3232 if (*flags)
3233 {
3234 if (*flags &
3235 (MBEDTLS_X509_BADCERT_NOT_TRUSTED | MBEDTLS_X509_BADCERT_CN_MISMATCH | MBEDTLS_X509_BADCERT_REVOKED))
3236 {
3237 emsg(MSG_WARNING, "client cert not trusted");
3238 }
3239 /* report event if flags set but no additional flags set above */
3240 /* (could translate flags to more detailed TLS_FAIL_* if needed) */
3241 if (!(*flags & ~flags_in))
3242 {
3243 enum tls_fail_reason reason = TLS_FAIL_UNSPECIFIED;
3244 const char *errmsg = "cert verify fail unspecified";
3245 if (*flags & MBEDTLS_X509_BADCERT_NOT_TRUSTED)
3246 {
3247 reason = TLS_FAIL_UNTRUSTED;
3248 errmsg = "certificate not trusted";
3249 }
3250 if (*flags & MBEDTLS_X509_BADCERT_REVOKED)
3251 {
3252 reason = TLS_FAIL_REVOKED;
3253 errmsg = "certificate has been revoked";
3254 }
3255 if (*flags & MBEDTLS_X509_BADCERT_FUTURE)
3256 {
3257 reason = TLS_FAIL_NOT_YET_VALID;
3258 errmsg = "certificate not yet valid";
3259 }
3260 if (*flags & MBEDTLS_X509_BADCERT_EXPIRED)
3261 {
3262 reason = TLS_FAIL_EXPIRED;
3263 errmsg = "certificate has expired";
3264 }
3265 if (*flags & MBEDTLS_X509_BADCERT_BAD_MD)
3266 {
3267 reason = TLS_FAIL_BAD_CERTIFICATE;
3268 errmsg = "certificate uses insecure algorithm";
3269 }
3270 tls_mbedtls_verify_fail_event(crt, depth, errmsg, reason);
3271 }
3272
3273 /*(do not preserve subject if verification failed but was optional)*/
3274 if (depth == 0 && conn->peer_subject)
3275 {
3276 os_free(conn->peer_subject);
3277 conn->peer_subject = NULL;
3278 }
3279 }
3280 else if (depth == 0)
3281 {
3282 struct tls_config *init_conf = &tls_ctx_global.init_conf;
3283 if (tls_conf->ca_cert_probe)
3284 {
3285 /* reject server certificate on probe-only run */
3286 *flags |= MBEDTLS_X509_BADCERT_OTHER;
3287 tls_mbedtls_verify_fail_event(crt, depth, "server chain probe", TLS_FAIL_SERVER_CHAIN_PROBE);
3288 }
3289 else if (init_conf->event_cb)
3290 {
3291 /* ??? send event as soon as depth == 0 is verified ???
3292 * What about rest of chain?
3293 * Follows tls_mbedtls.c behavior: */
3294 init_conf->event_cb(init_conf->cb_ctx, TLS_CERT_CHAIN_SUCCESS, NULL);
3295 }
3296 }
3297
3298 return 0;
3299 }
3300 #endif
3301