xref: /lighttpd1.4/src/mod_mbedtls.c (revision 66698469)
1 /*
2  * mod_mbedtls - mbedTLS support for lighttpd
3  *
4  * Copyright(c) 2020 Glenn Strauss gstrauss()gluelogic.com  All rights reserved
5  * License: BSD 3-clause (same as lighttpd)
6  */
7 /*
8  * reference:
9  * https://tls.mbed.org/high-level-design
10  * https://tls.mbed.org/tech-updates/blog/mbedtls-2.0-defaults-best-practices
11  * mbedTLS header files (mbedtls/ssl.h and others) are extremely well-documented
12  * https://tls.mbed.org/api/  (generated from mbedTLS headers and code)
13  *
14  * mbedTLS limitations:
15  * - mbedTLS does not currently support OCSP
16  *   https://tls.mbed.org/discussions/feature-request/ocsp-stapling
17  *   TLS/DTLS: OCSP Stapling support #880
18  *   https://github.com/ARMmbed/mbedtls/issues/880
19  *   Add support for writing OCSP requests and parsing OCSP responses #1197
20  *   https://github.com/ARMmbed/mbedtls/issues/1197
21  *
22  * future possible enhancements to lighttpd mod_mbedtls:
23  * - session cache (though session tickets are implemented)
24  *     sample code in mbedtls:programs/ssl/ssl_server2.c
25  *     (and do not enable unless server.feature-flags ssl.session-cache enabled)
26  *
27  * Note: If session tickets are -not- disabled with
28  *     ssl.openssl.ssl-conf-cmd = ("Options" => "-SessionTicket")
29  *   mbedtls rotates the session ticket key according to 2x timeout set with
30  *   mbedtls_ssl_ticket_setup() (currently 43200 s, so 24 hour ticket lifetime)
31  *   This is fine for use with a single lighttpd instance, but with multiple
32  *   lighttpd workers, no coordinated STEK (server ticket encryption key)
33  *   rotation occurs unless ssl.stek-file is defined and maintained (preferred),
34  *   or if some external job restarts lighttpd.  Restarting lighttpd generates a
35  *   new key that is shared by lighttpd workers for the lifetime of the new key.
36  *   If the rotation period expires and lighttpd has not been restarted, and if
37  *   ssl.stek-file is not in use, then lighttpd workers will generate new
38  *   independent keys, making session tickets less effective for session
39  *   resumption, since clients have a lower chance for future connections to
40  *   reach the same lighttpd worker.  However, things will still work, and a new
41  *   session will be created if session resumption fails.  Admins should plan to
42  *   restart lighttpd at least every 12 hours if session tickets are enabled and
43  *   multiple lighttpd workers are configured.  Since that is likely disruptive,
44  *   if multiple lighttpd workers are configured, ssl.stek-file should be
45  *   defined and the file maintained externally.
46  */
47 #include "first.h"
48 
49 #include <sys/types.h>
50 #include <sys/stat.h>
51 #include <errno.h>
52 #include <fcntl.h>
53 #include <stdarg.h>
54 #include <stdlib.h>
55 #include <stdio.h>      /* vsnprintf() */
56 #include <string.h>
57 
58 #include <mbedtls/version.h>
59 /*(compatibility while waiting for future mbedtls 3.x interfaces)*/
60 #if MBEDTLS_VERSION_NUMBER < 0x03020000 /* mbedtls 3.02.0 */
61 #ifndef MBEDTLS_ALLOW_PRIVATE_ACCESS
62 #define MBEDTLS_ALLOW_PRIVATE_ACCESS
63 #endif
64 #endif
65 #include <mbedtls/ctr_drbg.h>
66 #include <mbedtls/debug.h>
67 #include <mbedtls/dhm.h>
68 #include <mbedtls/error.h>
69 #include <mbedtls/entropy.h>
70 #include <mbedtls/oid.h>
71 #include <mbedtls/pem.h>
72 #include <mbedtls/ssl.h>
73 #if MBEDTLS_VERSION_NUMBER < 0x03000000 /* mbedtls 3.00.0 */
74 #include <mbedtls/ssl_internal.h> /* struct mbedtls_ssl_transform */
75 #endif
76 #include <mbedtls/x509.h>
77 #include <mbedtls/x509_crt.h>
78 #include <mbedtls/platform_util.h> /* mbedtls_platform_zeroize() */
79 
80 #if MBEDTLS_VERSION_NUMBER >= 0x02040000 /* mbedtls 2.04.0 */
81 #include <mbedtls/net_sockets.h>
82 #else
83 #include <mbedtls/net.h>
84 #endif
85 
86 #if defined(MBEDTLS_SSL_TICKET_C)
87 #include <mbedtls/ssl_ticket.h>
88 #endif
89 
90 #ifndef MBEDTLS_X509_CRT_PARSE_C
91 #error "lighttpd requires that mbedtls be built with MBEDTLS_X509_CRT_PARSE_C"
92 #endif
93 
94 #ifndef MBEDTLS_PRIVATE
95 #define MBEDTLS_PRIVATE(x) x
96 #endif
97 
98 #include "base.h"
99 #include "ck.h"
100 #include "fdevent.h"
101 #include "http_header.h"
102 #include "http_kv.h"
103 #include "log.h"
104 #include "plugin.h"
105 
106 typedef struct {
107     /* SNI per host: with COMP_SERVER_SOCKET, COMP_HTTP_SCHEME, COMP_HTTP_HOST */
108     mbedtls_pk_context ssl_pemfile_pkey;/* parsed private key structure */
109     mbedtls_x509_crt ssl_pemfile_x509;  /* parsed public key structure */
110     const buffer *ssl_pemfile;
111     const buffer *ssl_privkey;
112     int8_t need_chain;
113 } plugin_cert;
114 
115 typedef struct {
116     mbedtls_ssl_config *ssl_ctx;        /* context shared between mbedtls_ssl_CONTEXT structures */
117     int *ciphersuites;
118     void *curves;
119 } plugin_ssl_ctx;
120 
121 typedef struct {
122     mbedtls_ssl_config *ssl_ctx;        /* output from network_init_ssl() */
123     int *ciphersuites;                  /* output from network_init_ssl() */
124     void *curves;                       /* output from network_init_ssl() */
125 
126     /*(used only during startup; not patched)*/
127     unsigned char ssl_enabled; /* only interesting for setting up listening sockets. don't use at runtime */
128     unsigned char ssl_honor_cipher_order; /* determine SSL cipher in server-preferred order, not client-order */
129     unsigned char ssl_empty_fragments;
130     unsigned char ssl_use_sslv2;
131     unsigned char ssl_use_sslv3;
132     const buffer *ssl_cipher_list;
133     const buffer *ssl_dh_file;
134     const buffer *ssl_ec_curve;
135     const buffer *ssl_acme_tls_1;
136     array *ssl_conf_cmd;
137 
138     /*(copied from plugin_data for socket ssl_ctx config)*/
139     plugin_cert *pc;
140     mbedtls_pk_context *ssl_pemfile_pkey; /* parsed private key structure */
141     mbedtls_x509_crt *ssl_pemfile_x509;   /* parsed public key structure */
142     mbedtls_x509_crt *ssl_ca_file;
143     const buffer *ssl_pemfile;
144     const buffer *ssl_privkey;
145     unsigned char ssl_session_ticket;
146     unsigned char ssl_verifyclient;
147     unsigned char ssl_verifyclient_enforce;
148     unsigned char ssl_verifyclient_depth;
149 } plugin_config_socket; /*(used at startup during configuration)*/
150 
151 typedef struct {
152     /* SNI per host: w/ COMP_SERVER_SOCKET, COMP_HTTP_SCHEME, COMP_HTTP_HOST */
153     plugin_cert *pc;
154     mbedtls_pk_context *ssl_pemfile_pkey; /* parsed private key structure */
155     mbedtls_x509_crt *ssl_pemfile_x509;   /* parsed public key structure */
156     const buffer *ssl_pemfile;
157     mbedtls_x509_crt *ssl_ca_file;
158     mbedtls_x509_crt *ssl_ca_dn_file;
159     mbedtls_x509_crl *ssl_ca_crl_file;
160 
161     unsigned char ssl_verifyclient;
162     unsigned char ssl_verifyclient_enforce;
163     unsigned char ssl_verifyclient_depth;
164     unsigned char ssl_verifyclient_export_cert;
165     unsigned char ssl_read_ahead;
166     unsigned char ssl_log_noise;
167     unsigned char ssl_disable_client_renegotiation;
168     const buffer *ssl_verifyclient_username;
169     const buffer *ssl_acme_tls_1;
170 } plugin_config;
171 
172 typedef struct {
173     PLUGIN_DATA;
174     plugin_ssl_ctx *ssl_ctxs;
175     plugin_config defaults;
176     server *srv;
177     /* NIST counter-mode deterministic random byte generator */
178     mbedtls_ctr_drbg_context ctr_drbg;
179     /* entropy collection and state management */
180     mbedtls_entropy_context entropy;
181   #if defined(MBEDTLS_SSL_SESSION_TICKETS)
182     mbedtls_ssl_ticket_context ticket_ctx;
183     const char *ssl_stek_file;
184   #endif
185 } plugin_data;
186 
187 static int ssl_is_init;
188 /* need assigned p->id for deep access of module handler_ctx for connection
189  *   i.e. handler_ctx *hctx = con->plugin_ctx[plugin_data_singleton->id]; */
190 static plugin_data *plugin_data_singleton;
191 #ifdef MBEDTLS_SSL_OUT_CONTENT_LEN
192 #define LOCAL_SEND_BUFSIZE MBEDTLS_SSL_OUT_CONTENT_LEN
193 #else
194 #define LOCAL_SEND_BUFSIZE MBEDTLS_SSL_MAX_CONTENT_LEN
195 #endif
196 static char *local_send_buffer;
197 
198 typedef struct {
199     mbedtls_ssl_context ssl;      /* mbedtls request/connection context */
200     request_st *r;
201     connection *con;
202     int8_t close_notify;
203     unsigned short alpn;
204     int handshake_done;
205     size_t pending_write;
206     plugin_config conf;
207     buffer *tmp_buf;
208     log_error_st *errh;
209     mbedtls_ssl_config *ssl_ctx;
210     mbedtls_pk_context *acme_tls_1_pkey;
211     mbedtls_x509_crt *acme_tls_1_x509;
212 } handler_ctx;
213 
214 
215 static handler_ctx *
216 handler_ctx_init (void)
217 {
218     handler_ctx *hctx = calloc(1, sizeof(*hctx));
219     force_assert(hctx);
220     return hctx;
221 }
222 
223 
224 static void
225 handler_ctx_free (handler_ctx *hctx)
226 {
227     mbedtls_ssl_free(&hctx->ssl);
228     if (hctx->acme_tls_1_pkey) {
229         mbedtls_pk_free(hctx->acme_tls_1_pkey);
230         free(hctx->acme_tls_1_pkey);
231     }
232     if (hctx->acme_tls_1_x509) {
233         mbedtls_x509_crt_free(hctx->acme_tls_1_x509);
234         free(hctx->acme_tls_1_x509);
235     }
236     free(hctx);
237 }
238 
239 
240 #ifdef MBEDTLS_ERROR_C
241 __attribute_cold__
242 static void elog(log_error_st * const errh,
243                  const char * const file, const int line,
244                  const int rc, const char * const msg)
245 {
246     /* error logging convenience function that decodes mbedtls result codes */
247     char buf[256];
248     mbedtls_strerror(rc, buf, sizeof(buf));
249     log_error(errh, file, line, "MTLS: %s: %s (-0x%04x)", msg, buf, -rc);
250 }
251 #else
252 #define elog(errh, file, line, rc, msg) \
253     log_error((errh), (file), (line), "MTLS: %s: (-0x%04x)", (msg), -(rc))
254 #endif
255 
256 
257 __attribute_cold__
258 __attribute_format__((__printf__, 5, 6))
259 static void elogf(log_error_st * const errh,
260                   const char * const file, const int line,
261                   const int rc, const char * const fmt, ...)
262 {
263     char msg[1024];
264     va_list ap;
265     va_start(ap, fmt);
266     vsnprintf(msg, sizeof(msg), fmt, ap);
267     va_end(ap);
268     elog(errh, file, line, rc, msg);
269 }
270 
271 
272 #ifdef MBEDTLS_SSL_SESSION_TICKETS
273 
274 #define TLSEXT_KEYNAME_LENGTH  16
275 #define TLSEXT_TICK_KEY_LENGTH 32
276 
277 /* construct our own session ticket encryption key structure
278  * to store keys that are not yet active
279  * (mirror from mod_openssl, even though not all bits are used here) */
280 typedef struct tlsext_ticket_key_st {
281     unix_time64_t active_ts; /* tickets not issued w/ key until activation ts*/
282     unix_time64_t expire_ts; /* key not valid after expiration timestamp */
283     unsigned char tick_key_name[TLSEXT_KEYNAME_LENGTH];
284     unsigned char tick_hmac_key[TLSEXT_TICK_KEY_LENGTH];
285     unsigned char tick_aes_key[TLSEXT_TICK_KEY_LENGTH];
286 } tlsext_ticket_key_t;
287 
288 static tlsext_ticket_key_t session_ticket_keys[1]; /* temp store until active */
289 static unix_time64_t stek_rotate_ts;
290 
291 
292 static int
293 mod_mbedtls_session_ticket_key_file (const char *fn)
294 {
295     /* session ticket encryption key (STEK)
296      *
297      * STEK file should be stored in non-persistent storage,
298      *   e.g. /dev/shm/lighttpd/stek-file  (in memory)
299      * with appropriate permissions set to keep stek-file from being
300      * read by other users.  Where possible, systems should also be
301      * configured without swap.
302      *
303      * admin should schedule an independent job to periodically
304      *   generate new STEK up to 3 times during key lifetime
305      *   (lighttpd stores up to 3 keys)
306      *
307      * format of binary file is:
308      *    4-byte - format version (always 0; for use if format changes)
309      *    4-byte - activation timestamp
310      *    4-byte - expiration timestamp
311      *   16-byte - session ticket key name
312      *   32-byte - session ticket HMAC encrpytion key
313      *   32-byte - session ticket AES encrpytion key
314      *
315      * STEK file can be created with a command such as:
316      *   dd if=/dev/random bs=1 count=80 status=none | \
317      *     perl -e 'print pack("iii",0,time()+300,time()+86400),<>' \
318      *     > STEK-file.$$ && mv STEK-file.$$ STEK-file
319      *
320      * The above delays activation time by 5 mins (+300 sec) to allow file to
321      * be propagated to other machines.  (admin must handle this independently)
322      * If STEK generation is performed immediately prior to starting lighttpd,
323      * admin should activate keys immediately (without +300).
324      */
325     int buf[23]; /* 92 bytes */
326     int rc = 0; /*(will retry on next check interval upon any error)*/
327     if (0 != fdevent_load_file_bytes((char *)buf,(off_t)sizeof(buf),0,fn,NULL))
328         return rc;
329     if (buf[0] == 0) { /*(format version 0)*/
330         session_ticket_keys[0].active_ts = TIME64_CAST(buf[1]);
331         session_ticket_keys[0].expire_ts = TIME64_CAST(buf[2]);
332       #ifndef __COVERITY__
333         memcpy(&session_ticket_keys[0].tick_key_name, buf+3, 80);
334       #else
335         memcpy(&session_ticket_keys[0].tick_key_name,
336                buf+3, TLSEXT_KEYNAME_LENGTH);
337         memcpy(&session_ticket_keys[0].tick_hmac_key,
338                buf+7, TLSEXT_TICK_KEY_LENGTH);
339         memcpy(&session_ticket_keys[0].tick_aes_key,
340                buf+15, TLSEXT_TICK_KEY_LENGTH);
341       #endif
342         rc = 1;
343     }
344 
345     mbedtls_platform_zeroize(buf, sizeof(buf));
346     return rc;
347 }
348 
349 
350 static void
351 mod_mbedtls_session_ticket_key_check (plugin_data *p, const unix_time64_t cur_ts)
352 {
353     if (NULL == p->ssl_stek_file) return;
354 
355     struct stat st;
356     if (0 == stat(p->ssl_stek_file, &st)
357         && TIME64_CAST(st.st_mtime) > stek_rotate_ts
358         && mod_mbedtls_session_ticket_key_file(p->ssl_stek_file)) {
359         stek_rotate_ts = cur_ts;
360     }
361 
362     tlsext_ticket_key_t *stek = session_ticket_keys;
363     if (stek->active_ts != 0 && stek->active_ts - 63 <= cur_ts) {
364       #if MBEDTLS_VERSION_NUMBER >= 0x03020000 /* mbedtls 3.02.0 */
365         int rc = mbedtls_ssl_ticket_rotate(&p->ticket_ctx,
366                    stek->tick_key_name, sizeof(stek->tick_key_name),
367                    stek->tick_aes_key, sizeof(stek->tick_aes_key),
368                    (uint32_t)(stek->expire_ts - stek->active_ts));
369         if (0 != rc)
370             elog(p->srv->errh, __FILE__,__LINE__, rc,
371                  "session ticket encryption key rotation failed");
372       #else /*(mbedtls_allow_private_access at top of file for [3.0.0,3.2.0))*/
373         /* expect to get newer ssl.stek-file prior to mbedtls detecting
374          * expiration and internally generating a new key.  If not, then
375          * lifetime may be up to 2x specified lifetime until overwritten
376          * by mbedtls, but original key will be overwritten and discarded */
377         mbedtls_ssl_ticket_context *ctx = &p->ticket_ctx;
378         ctx->ticket_lifetime = stek->expire_ts - stek->active_ts;
379         ctx->active = 1 - ctx->active;
380         mbedtls_ssl_ticket_key *key = ctx->keys + ctx->active;
381         /* set generation_time to cur_ts instead of stek->active_ts
382          * since ctx->active was updated */
383         key->generation_time = cur_ts;
384         memcpy(key->name, stek->tick_key_name, sizeof(key->name));
385         /* With GCM and CCM, same context can encrypt & decrypt */
386         int rc = mbedtls_cipher_setkey(&key->ctx, stek->tick_aes_key,
387                                        mbedtls_cipher_get_key_bitlen(&key->ctx),
388                                        MBEDTLS_ENCRYPT);
389         if (0 != rc) { /* expire key immediately if error occurs */
390             key->generation_time = cur_ts > (unix_time64_t)ctx->ticket_lifetime
391               ? cur_ts - ctx->ticket_lifetime - 1
392               : 0;
393             ctx->active = 1 - ctx->active;
394         }
395       #endif
396         mbedtls_platform_zeroize(stek, sizeof(tlsext_ticket_key_t));
397     }
398 }
399 
400 #endif /* MBEDTLS_SSL_SESSION_TICKETS */
401 
402 
403 INIT_FUNC(mod_mbedtls_init)
404 {
405     plugin_data_singleton = (plugin_data *)calloc(1, sizeof(plugin_data));
406   #if defined(MBEDTLS_SSL_SESSION_TICKETS)
407     mbedtls_ssl_ticket_init(&plugin_data_singleton->ticket_ctx);
408   #endif
409     return plugin_data_singleton;
410 }
411 
412 
413 static int mod_mbedtls_init_once_mbedtls (server *srv)
414 {
415     if (ssl_is_init) return 1;
416     ssl_is_init = 1;
417 
418     plugin_data * const p = plugin_data_singleton;
419     mbedtls_ctr_drbg_init(&p->ctr_drbg); /* init empty NSIT random num gen */
420     mbedtls_entropy_init(&p->entropy);   /* init empty entropy collection struct
421                                                .. could add sources here too */
422 
423     int rc =                                      /* init RNG */
424       mbedtls_ctr_drbg_seed(&p->ctr_drbg,         /* random number generator */
425                             mbedtls_entropy_func, /* default entropy func */
426                             &p->entropy,          /* entropy context */
427                             NULL, 0);             /* no personalization data */
428     if (0 != rc) {
429         elog(srv->errh, __FILE__,__LINE__, rc,
430              "Init of random number generator failed");
431         return 0;
432     }
433 
434     local_send_buffer = malloc(LOCAL_SEND_BUFSIZE);
435     force_assert(NULL != local_send_buffer);
436 
437     return 1;
438 }
439 
440 
441 static void mod_mbedtls_free_mbedtls (void)
442 {
443     if (!ssl_is_init) return;
444 
445   #ifdef MBEDTLS_SSL_SESSION_TICKETS
446     mbedtls_platform_zeroize(session_ticket_keys, sizeof(session_ticket_keys));
447     stek_rotate_ts = 0;
448   #endif
449 
450     plugin_data * const p = plugin_data_singleton;
451     mbedtls_ctr_drbg_free(&p->ctr_drbg);
452     mbedtls_entropy_free(&p->entropy);
453   #if defined(MBEDTLS_SSL_SESSION_TICKETS)
454     mbedtls_ssl_ticket_free(&p->ticket_ctx);
455   #endif
456 
457     free(local_send_buffer);
458     ssl_is_init = 0;
459 }
460 
461 
462 static void
463 mod_mbedtls_free_config (server *srv, plugin_data * const p)
464 {
465     if (NULL != p->ssl_ctxs) {
466         mbedtls_ssl_config * const ssl_ctx_global_scope = p->ssl_ctxs->ssl_ctx;
467         /* free ssl_ctx from $SERVER["socket"] (if not copy of global scope) */
468         for (uint32_t i = 1; i < srv->config_context->used; ++i) {
469             plugin_ssl_ctx * const s = p->ssl_ctxs + i;
470             if (s->ssl_ctx && s->ssl_ctx != ssl_ctx_global_scope) {
471                 mbedtls_ssl_config_free(s->ssl_ctx);
472                 free(s->ciphersuites);
473                 free(s->curves);
474             }
475         }
476         /* free ssl_ctx from global scope */
477         if (ssl_ctx_global_scope) {
478             mbedtls_ssl_config_free(ssl_ctx_global_scope);
479             free(p->ssl_ctxs[0].ciphersuites);
480             free(p->ssl_ctxs[0].curves);
481         }
482         free(p->ssl_ctxs);
483     }
484 
485     if (NULL == p->cvlist) return;
486     /* (init i to 0 if global context; to 1 to skip empty global context) */
487     for (int i = !p->cvlist[0].v.u2[1], used = p->nconfig; i < used; ++i) {
488         config_plugin_value_t *cpv = p->cvlist + p->cvlist[i].v.u2[0];
489         for (; -1 != cpv->k_id; ++cpv) {
490             switch (cpv->k_id) {
491               case 0: /* ssl.pemfile */
492                 if (cpv->vtype == T_CONFIG_LOCAL) {
493                     plugin_cert *pc = cpv->v.v;
494                     mbedtls_pk_free(&pc->ssl_pemfile_pkey);
495                     mbedtls_x509_crt_free(&pc->ssl_pemfile_x509);
496                     free(pc);
497                 }
498                 break;
499               case 2: /* ssl.ca-file */
500               case 3: /* ssl.ca-dn-file */
501                 if (cpv->vtype == T_CONFIG_LOCAL) {
502                     mbedtls_x509_crt *cacert = cpv->v.v;
503                     mbedtls_x509_crt_free(cacert);
504                     free(cacert);
505                 }
506                 break;
507               case 4: /* ssl.ca-crl-file */
508                 if (cpv->vtype == T_CONFIG_LOCAL) {
509                     mbedtls_x509_crl *crl = cpv->v.v;
510                     mbedtls_x509_crl_free(crl);
511                     free(crl);
512                 }
513                 break;
514               default:
515                 break;
516             }
517         }
518     }
519 }
520 
521 
522 FREE_FUNC(mod_mbedtls_free)
523 {
524     plugin_data *p = p_d;
525     if (NULL == p->srv) return;
526     mod_mbedtls_free_config(p->srv, p);
527     mod_mbedtls_free_mbedtls();
528 }
529 
530 
531 static void
532 mod_mbedtls_merge_config_cpv (plugin_config * const pconf, const config_plugin_value_t * const cpv)
533 {
534     switch (cpv->k_id) { /* index into static config_plugin_keys_t cpk[] */
535       case 0: /* ssl.pemfile */
536         if (cpv->vtype == T_CONFIG_LOCAL)
537             pconf->pc = cpv->v.v;
538         break;
539       case 1: /* ssl.privkey */
540         break;
541       case 2: /* ssl.ca-file */
542         if (cpv->vtype == T_CONFIG_LOCAL)
543             pconf->ssl_ca_file = cpv->v.v;
544         break;
545       case 3: /* ssl.ca-dn-file */
546         if (cpv->vtype == T_CONFIG_LOCAL)
547             pconf->ssl_ca_dn_file = cpv->v.v;
548         break;
549       case 4: /* ssl.ca-crl-file */
550         if (cpv->vtype == T_CONFIG_LOCAL)
551             pconf->ssl_ca_dn_file = cpv->v.v;
552         break;
553       case 5: /* ssl.read-ahead */
554         pconf->ssl_read_ahead = (0 != cpv->v.u);
555         break;
556       case 6: /* ssl.disable-client-renegotiation */
557         pconf->ssl_disable_client_renegotiation = (0 != cpv->v.u);
558         break;
559       case 7: /* ssl.verifyclient.activate */
560         pconf->ssl_verifyclient = (0 != cpv->v.u);
561         break;
562       case 8: /* ssl.verifyclient.enforce */
563         pconf->ssl_verifyclient_enforce = (0 != cpv->v.u);
564         break;
565       case 9: /* ssl.verifyclient.depth */
566         pconf->ssl_verifyclient_depth = (unsigned char)cpv->v.shrt;
567         break;
568       case 10:/* ssl.verifyclient.username */
569         pconf->ssl_verifyclient_username = cpv->v.b;
570         break;
571       case 11:/* ssl.verifyclient.exportcert */
572         pconf->ssl_verifyclient_export_cert = (0 != cpv->v.u);
573         break;
574       case 12:/* ssl.acme-tls-1 */
575         pconf->ssl_acme_tls_1 = cpv->v.b;
576         break;
577       case 13:/* debug.log-ssl-noise */
578         pconf->ssl_log_noise = (unsigned char)cpv->v.shrt;
579         break;
580      #if 0    /*(cpk->k_id remapped in mod_mbedtls_set_defaults())*/
581       case 14:/* ssl.verifyclient.ca-file */
582       case 15:/* ssl.verifyclient.ca-dn-file */
583       case 16:/* ssl.verifyclient.ca-crl-file */
584         break;
585      #endif
586       default:/* should not happen */
587         return;
588     }
589 }
590 
591 
592 static void
593 mod_mbedtls_merge_config(plugin_config * const pconf, const config_plugin_value_t *cpv)
594 {
595     do {
596         mod_mbedtls_merge_config_cpv(pconf, cpv);
597     } while ((++cpv)->k_id != -1);
598 }
599 
600 
601 static void
602 mod_mbedtls_patch_config (request_st * const r, plugin_config * const pconf)
603 {
604     plugin_data * const p = plugin_data_singleton;
605     memcpy(pconf, &p->defaults, sizeof(plugin_config));
606     for (int i = 1, used = p->nconfig; i < used; ++i) {
607         if (config_check_cond(r, (uint32_t)p->cvlist[i].k_id))
608             mod_mbedtls_merge_config(pconf, p->cvlist + p->cvlist[i].v.u2[0]);
609     }
610 }
611 
612 
613 __attribute_pure__
614 static int
615 mod_mbedtls_crt_is_self_issued (const mbedtls_x509_crt * const crt)
616 {
617     const mbedtls_x509_buf * const issuer  = &crt->issuer_raw;
618     const mbedtls_x509_buf * const subject = &crt->subject_raw;
619     return subject->len == issuer->len
620         && 0 == memcmp(issuer->p, subject->p, subject->len);
621 }
622 
623 
624 static int
625 mod_mbedtls_construct_crt_chain (mbedtls_x509_crt *leaf, mbedtls_x509_crt *store, log_error_st *errh)
626 {
627     /* Historically, openssl will use the cert chain in (SSL_CTX *) if a cert
628      * does not have a chain configured in (SSL *).  While similar behavior
629      * could be achieved with mbedtls_x509_crt_parse_file(crt, ssl_ca_file->ptr)
630      * instead attempt to do better and build a proper, ordered cert chain. */
631 
632     if (leaf->next) return 0; /*(presume chain has already been provided)*/
633     if (store == NULL) return 0;/*(unable to proceed; chain may be incomplete)*/
634 
635     /* attempt to construct certificate chain from certificate store */
636     for (mbedtls_x509_crt *crt = leaf; crt; ) {
637         const mbedtls_x509_buf * const issuer = &crt->issuer_raw;
638 
639         /*(walk entire store in case certs are not properly sorted)*/
640         for (crt = store; crt; crt = crt->next) {
641             /* The raw issuer/subject data (DER) is used for quick comparison */
642             /* (see comments in mod_mbedtls_verify_cb())*/
643             const mbedtls_x509_buf * const subject = &crt->subject_raw;
644             if (issuer->len != subject->len
645                 || 0 != memcmp(subject->p, issuer->p, issuer->len)) continue;
646 
647             /* root cert is end condition; omit from chain of intermediates */
648             if (mod_mbedtls_crt_is_self_issued(crt))
649                 return 0;
650 
651             int rc =
652           #if MBEDTLS_VERSION_NUMBER >= 0x02110000 /* mbedtls 2.17.0 */
653               /* save memory by eliding copy of already-loaded raw DER */
654               mbedtls_x509_crt_parse_der_nocopy(leaf, crt->raw.p, crt->raw.len);
655           #else
656               mbedtls_x509_crt_parse_der(leaf, crt->raw.p, crt->raw.len);
657           #endif
658             if (0 != rc) { /*(failure not unexpected since already parsed)*/
659                 elog(errh, __FILE__, __LINE__, rc, "cert copy failed");
660                 return rc;
661             }
662             break;
663         }
664     }
665 
666     return 0; /*(no error, though cert chain may or may not be complete)*/
667 }
668 
669 
670 static int
671 mod_mbedtls_verify_cb (void *arg, mbedtls_x509_crt *crt, int depth, uint32_t *flags)
672 {
673     handler_ctx * const hctx = (handler_ctx *)arg;
674 
675     if (depth > hctx->conf.ssl_verifyclient_depth) {
676         log_error(hctx->r->conf.errh, __FILE__, __LINE__,
677                   "MTLS: client cert chain too long");
678         *flags |= MBEDTLS_X509_BADCERT_OTHER; /* cert chain too long */
679     }
680     else if (0 == depth && NULL != hctx->conf.ssl_ca_dn_file) {
681         /* verify that client cert is issued by CA in ssl.ca-dn-file
682          * if both ssl.ca-dn-file and ssl.ca-file were configured */
683         /* The raw issuer/subject data (DER) is used for quick comparison. */
684         const size_t len = crt->issuer_raw.len;
685         mbedtls_x509_crt *chain = hctx->conf.ssl_ca_dn_file;
686         do {
687           #if 0 /* x509_name_cmp() is not a public func in mbedtls */
688             if (0 == x509_name_cmp(&crt->issuer, &chain->subject))
689                 break;
690           #else
691             if (len == chain->subject_raw.len
692                 && 0 == memcmp(chain->subject_raw.p, crt->issuer_raw.p, len))
693                 break;
694           #endif
695         } while ((chain = chain->next));
696 
697         if (NULL == chain)
698             *flags |= MBEDTLS_X509_BADCERT_NOT_TRUSTED;
699     }
700     if (*flags & MBEDTLS_X509_BADCERT_NOT_TRUSTED) {
701         log_error(hctx->r->conf.errh, __FILE__, __LINE__,
702                   "MTLS: client cert not trusted");
703     }
704 
705     return 0;
706 }
707 
708 
709 enum {
710   MOD_MBEDTLS_ALPN_HTTP11      = 1
711  ,MOD_MBEDTLS_ALPN_HTTP10      = 2
712  ,MOD_MBEDTLS_ALPN_H2          = 3
713  ,MOD_MBEDTLS_ALPN_ACME_TLS_1  = 4
714 };
715 
716 #ifdef MBEDTLS_SSL_SERVER_NAME_INDICATION
717 #ifdef MBEDTLS_SSL_ALPN
718 
719 static int
720 mod_mbedtls_acme_tls_1 (handler_ctx *hctx);
721 
722 #endif
723 #endif
724 
725 
726 #if MBEDTLS_VERSION_NUMBER < 0x03000000 /* mbedtls 3.00.0 */
727 #define MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO
728 #define MBEDTLS_ERR_SSL_DECODE_ERROR      MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO
729 #endif
730 
731 
732 #ifdef MBEDTLS_SSL_SERVER_NAME_INDICATION
733 static int
734 mod_mbedtls_SNI (void *arg, mbedtls_ssl_context *ssl, const unsigned char *servername, size_t len)
735 {
736     handler_ctx * const hctx = (handler_ctx *) arg;
737     request_st * const r = hctx->r;
738     buffer_copy_string_len(&r->uri.scheme, CONST_STR_LEN("https"));
739 
740     if (len >= 1024) { /*(expecting < 256; TLSEXT_MAXLEN_host_name is 255)*/
741         log_error(r->conf.errh, __FILE__, __LINE__,
742                   "MTLS: SNI name too long %.*s", (int)len, servername);
743         return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
744     }
745 
746     /* use SNI to patch mod_mbedtls config and then reset COMP_HTTP_HOST */
747     buffer_copy_string_len_lc(&r->uri.authority, (const char *)servername, len);
748   #if 0
749     /*(r->uri.authority used below for configuration before request read;
750      * revisit for h2)*/
751     if (0 != http_request_host_policy(&r->uri.authority,
752                                       r->conf.http_parseopts, 443))
753         return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
754   #endif
755 
756     const buffer * const ssl_pemfile = hctx->conf.pc->ssl_pemfile;
757 
758     r->conditional_is_valid |= (1 << COMP_HTTP_SCHEME)
759                             |  (1 << COMP_HTTP_HOST);
760 
761     mod_mbedtls_patch_config(r, &hctx->conf);
762     /* reset COMP_HTTP_HOST so that conditions re-run after request hdrs read */
763     /*(done in configfile-glue.c:config_cond_cache_reset() after request hdrs read)*/
764     /*config_cond_cache_reset_item(r, COMP_HTTP_HOST);*/
765     /*buffer_clear(&r->uri.authority);*/
766 
767   #ifdef MBEDTLS_SSL_ALPN
768     /* TLS-ALPN-01 (ALPN "acme-tls/1") requires SNI */
769     if (hctx->alpn == MOD_MBEDTLS_ALPN_ACME_TLS_1)
770         return mod_mbedtls_acme_tls_1(hctx);
771   #endif
772 
773     /*(compare strings as ssl.pemfile might repeat same file in lighttpd.conf
774      * and mod_mbedtls does not attempt to de-dup)*/
775     if (!buffer_is_equal(hctx->conf.pc->ssl_pemfile, ssl_pemfile)) {
776         /* if needed, attempt to construct certificate chain for server cert */
777         if (hctx->conf.pc->need_chain) {
778             hctx->conf.pc->need_chain = 0; /*(attempt once to complete chain)*/
779             mbedtls_x509_crt *ssl_cred = &hctx->conf.pc->ssl_pemfile_x509;
780             mbedtls_x509_crt *store = hctx->conf.ssl_ca_file;
781             if (!mod_mbedtls_construct_crt_chain(ssl_cred, store, r->conf.errh))
782                 return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
783         }
784         /* reconfigure to use SNI-specific cert */
785         int rc =
786           mbedtls_ssl_set_hs_own_cert(ssl,
787                                       &hctx->conf.pc->ssl_pemfile_x509,
788                                       &hctx->conf.pc->ssl_pemfile_pkey);
789         if (0 != rc) {
790             elogf(r->conf.errh, __FILE__, __LINE__, rc,
791                   "failed to set SNI certificate for TLS server name %s",
792                   r->uri.authority.ptr);
793             return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
794         }
795     }
796 
797     return 0;
798 }
799 #endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
800 
801 
802 static int
803 mod_mbedtls_conf_verify (handler_ctx *hctx)
804 {
805     if (NULL == hctx->conf.ssl_ca_file) {
806         log_error(hctx->r->conf.errh, __FILE__, __LINE__,
807           "MTLS: can't verify client without ssl.verifyclient.ca-file "
808           "for TLS server name %s",
809           hctx->r->uri.authority.ptr);
810         return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
811     }
812 
813     mbedtls_ssl_context * const ssl = &hctx->ssl;
814 
815   #if MBEDTLS_VERSION_NUMBER >= 0x03020000 /* mbedtls 3.02.0 */
816     int mode = (hctx->conf.ssl_verifyclient_enforce)
817       ? MBEDTLS_SSL_VERIFY_REQUIRED
818       : MBEDTLS_SSL_VERIFY_OPTIONAL;
819     mbedtls_ssl_set_hs_authmode(ssl, mode);
820     mbedtls_ssl_set_hs_ca_chain(ssl, hctx->conf.ssl_ca_file,
821                                      hctx->conf.ssl_ca_crl_file);
822     if (hctx->conf.ssl_ca_dn_file)
823         mbedtls_ssl_set_hs_dn_hints(ssl, hctx->conf.ssl_ca_dn_file);
824   #else
825     /* send ssl_ca_dn_file (if set) in client certificate request
826      * (later changed to ssl_ca_file before client certificate verification) */
827     mbedtls_x509_crt *ca_certs = hctx->conf.ssl_ca_dn_file
828                                ? hctx->conf.ssl_ca_dn_file
829                                : hctx->conf.ssl_ca_file;
830     mbedtls_ssl_set_hs_ca_chain(ssl, ca_certs, hctx->conf.ssl_ca_crl_file);
831   #endif
832   #if MBEDTLS_VERSION_NUMBER >= 0x02120000 /* mbedtls 2.18.0 */
833     mbedtls_ssl_set_verify(ssl, mod_mbedtls_verify_cb, hctx);
834   #else
835     /* overwrite callback with hctx each time we enter here, before handshake
836      * (Some callbacks are on mbedtls_ssl_config, not mbedtls_ssl_context)
837      * (Not thread-safe if config (mbedtls_ssl_config *ssl_ctx) is shared)
838      * (XXX: there is probably a better way to do this...) */
839     mbedtls_ssl_conf_verify(hctx->ssl_ctx, mod_mbedtls_verify_cb, hctx);
840   #endif
841     return 0;
842 }
843 
844 
845 /* mbedTLS interfaces are generally excellent.  mbedTLS convenience interfaces
846  * to read CRLs, X509 certs, and private keys are uniformly paranoid about
847  * clearing memory.  At the moment, stdio routines fopen(), fread(), fclose()
848  * are used for portability, but without setvbuf(stream, NULL, _IOLBF, 0),
849  * again for portability, since setvbuf() is not necessarily available.  Since
850  * stdio buffers by default, use our own funcs to read files without buffering.
851  * mbedtls_pk_load_file() includes trailing '\0' in size when contents in PEM
852  * format, so do the same with the value returned from fdevent_load_file().
853  */
854 
855 
856 static int
857 mod_mbedtls_x509_crl_parse_file (mbedtls_x509_crl *chain, const char *fn)
858 {
859     int rc = MBEDTLS_ERR_X509_FILE_IO_ERROR;
860     off_t dlen = 512*1024*1024;/*(arbitrary limit: 512 MB file; expect < 1 MB)*/
861     char *data = fdevent_load_file(fn, &dlen, NULL, malloc, free);
862     if (NULL == data) return rc;
863 
864     rc = mbedtls_x509_crl_parse(chain, (unsigned char *)data, (size_t)dlen+1);
865 
866     if (dlen) ck_memzero(data, (size_t)dlen);
867     free(data);
868 
869     return rc;
870 }
871 
872 
873 static int
874 mod_mbedtls_cert_is_active (const mbedtls_x509_crt *crt)
875 {
876     return (   !mbedtls_x509_time_is_future(&crt->valid_from)
877             && !mbedtls_x509_time_is_past(&crt->valid_to));
878 }
879 
880 
881 #if MBEDTLS_VERSION_NUMBER >= 0x02170000 /* mbedtls 2.23.0 */
882 
883 static int
884 mod_mbedtls_x509_crt_ext_cb (void *p_ctx,
885                              mbedtls_x509_crt const *crt,
886                              mbedtls_x509_buf const *oid,
887                              int critical,
888                              const unsigned char *p,
889                              const unsigned char *end)
890 {
891     UNUSED(p_ctx);
892     if (!mod_mbedtls_cert_is_active(crt))
893         return MBEDTLS_ERR_X509_INVALID_DATE;
894     /* id-pe-acmeIdentifier 1.3.6.1.5.5.7.1.31 */
895     static const unsigned char acmeIdentifier[] = MBEDTLS_OID_PKIX "\x01\x1f";
896     if (0 == MBEDTLS_OID_CMP(acmeIdentifier, oid)) {
897         if (!critical) /* required by RFC 8737 */
898             return MBEDTLS_ERR_X509_INVALID_EXTENSIONS
899                  + MBEDTLS_ERR_ASN1_INVALID_DATA;
900         /*(mbedtls_asn1_get_tag() should take first param as
901          * (const unsigned char **) so safe to cast away const)*/
902         unsigned char *q;
903         *(const unsigned char **)&q = p;
904         size_t len;
905         int rc = mbedtls_asn1_get_tag(&q, end, &len,
906                                       MBEDTLS_ASN1_OCTET_STRING
907                                      |MBEDTLS_ASN1_PRIMITIVE);
908         if (0 != rc)
909             return MBEDTLS_ERR_X509_INVALID_EXTENSIONS + rc;
910         if (q + len != end)
911             return MBEDTLS_ERR_X509_INVALID_EXTENSIONS
912                  + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
913         if (len != 32) /* must be OCTET STRING (SIZE (32)) */
914             return MBEDTLS_ERR_X509_INVALID_EXTENSIONS
915                  + MBEDTLS_ERR_ASN1_INVALID_LENGTH;
916         return 0;
917     }
918     return MBEDTLS_ERR_ASN1_UNEXPECTED_TAG;
919 }
920 
921 static int
922 mod_mbedtls_x509_crt_parse_acme (mbedtls_x509_crt *chain, const char *fn)
923 {
924     /* similar to mod_mbedtls_x509_crt_parse_file(), but read single cert
925      * and special case to handle id-pe-acmeIdentifier OID */
926     /* https://github.com/ARMmbed/mbedtls/issues/3241 */
927     int rc = MBEDTLS_ERR_X509_FILE_IO_ERROR;
928     off_t dlen = 512*1024*1024;/*(arbitrary limit: 512 MB file; expect < 1 MB)*/
929     char *data = fdevent_load_file(fn, &dlen, NULL, malloc, free);
930     if (NULL == data) return rc;
931 
932     mbedtls_pem_context pem;
933     mbedtls_pem_init(&pem);
934 
935     size_t use_len;
936     rc = mbedtls_pem_read_buffer(&pem,
937                                  "-----BEGIN CERTIFICATE-----",
938                                  "-----END CERTIFICATE-----",
939                                  (unsigned char *)data, NULL, 0, &use_len);
940     if (0 == rc) {
941         mbedtls_x509_crt_ext_cb_t cb = mod_mbedtls_x509_crt_ext_cb;
942       #if MBEDTLS_VERSION_NUMBER >= 0x03020000 /* mbedtls 3.02.0 */
943         size_t buflen;
944         const unsigned char *buf = mbedtls_pem_get_buffer(&pem, &buflen);
945       #else
946         const unsigned char *buf = pem.MBEDTLS_PRIVATE(buf);
947         size_t buflen = pem.MBEDTLS_PRIVATE(buflen);
948       #endif
949         rc = mbedtls_x509_crt_parse_der_with_ext_cb(chain,buf,buflen,1,cb,NULL);
950     }
951 
952     mbedtls_pem_free(&pem);
953 
954     if (dlen) ck_memzero(data, (size_t)dlen);
955     free(data);
956 
957     return rc;
958 }
959 
960 #endif
961 
962 
963 static int
964 mod_mbedtls_x509_crt_parse_file (mbedtls_x509_crt *chain, const char *fn)
965 {
966     int rc = MBEDTLS_ERR_X509_FILE_IO_ERROR;
967     off_t dlen = 512*1024*1024;/*(arbitrary limit: 512 MB file; expect < 1 MB)*/
968     char *data = fdevent_load_file(fn, &dlen, NULL, malloc, free);
969     if (NULL == data) return rc;
970 
971     rc = mbedtls_x509_crt_parse(chain, (unsigned char *)data, (size_t)dlen+1);
972 
973     if (dlen) ck_memzero(data, (size_t)dlen);
974     free(data);
975 
976     return rc;
977 }
978 
979 
980 static int
981 mod_mbedtls_pk_parse_keyfile (mbedtls_pk_context *ctx, const char *fn, const char *pwd)
982 {
983     int rc = MBEDTLS_ERR_PK_FILE_IO_ERROR;
984     off_t dlen = 512*1024*1024;/*(arbitrary limit: 512 MB file; expect < 1 MB)*/
985     char *data = fdevent_load_file(fn, &dlen, NULL, malloc, free);
986     if (NULL == data) return rc;
987 
988   #if MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.00.0 */
989     plugin_data * const p = plugin_data_singleton;
990     rc = mbedtls_pk_parse_key(ctx, (unsigned char *)data, (size_t)dlen+1,
991                               (const unsigned char *)pwd,
992                               pwd ? strlen(pwd) : 0,
993                               mbedtls_ctr_drbg_random, &p->ctr_drbg);
994   #else
995     rc = mbedtls_pk_parse_key(ctx, (unsigned char *)data, (size_t)dlen+1,
996                               (const unsigned char *)pwd,
997                               pwd ? strlen(pwd) : 0);
998   #endif
999 
1000     if (dlen) ck_memzero(data, (size_t)dlen);
1001     free(data);
1002 
1003     return rc;
1004 }
1005 
1006 
1007 static void *
1008 network_mbedtls_load_pemfile (server *srv, const buffer *pemfile, const buffer *privkey)
1009 {
1010     mbedtls_x509_crt ssl_pemfile_x509;   /* parsed public key structure */
1011     mbedtls_pk_context ssl_pemfile_pkey; /* parsed private key structure */
1012     int rc;
1013 
1014     mbedtls_x509_crt_init(&ssl_pemfile_x509); /* init cert structure */
1015     rc = mod_mbedtls_x509_crt_parse_file(&ssl_pemfile_x509, pemfile->ptr);
1016     if (0 != rc) {
1017         elogf(srv->errh, __FILE__, __LINE__, rc,
1018               "PEM file cert read failed (%s)", pemfile->ptr);
1019         return NULL;
1020     }
1021     else if (!mod_mbedtls_cert_is_active(&ssl_pemfile_x509)) {
1022         log_error(srv->errh, __FILE__, __LINE__,
1023           "MTLS: inactive/expired X509 certificate '%s'", pemfile->ptr);
1024     }
1025 
1026     mbedtls_pk_init(&ssl_pemfile_pkey);  /* init private key context */
1027     rc = mod_mbedtls_pk_parse_keyfile(&ssl_pemfile_pkey, privkey->ptr, NULL);
1028     if (0 != rc) {
1029         elogf(srv->errh, __FILE__, __LINE__, rc,
1030               "PEM file private key read failed %s", privkey->ptr);
1031         mbedtls_x509_crt_free(&ssl_pemfile_x509);
1032         return NULL;
1033     }
1034 
1035   #if MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.00.0 */
1036     plugin_data * const p = plugin_data_singleton;
1037     rc = mbedtls_pk_check_pair(&ssl_pemfile_x509.pk, &ssl_pemfile_pkey,
1038                                mbedtls_ctr_drbg_random, &p->ctr_drbg);
1039   #else
1040     rc = mbedtls_pk_check_pair(&ssl_pemfile_x509.pk, &ssl_pemfile_pkey);
1041   #endif
1042     if (0 != rc) {
1043         elogf(srv->errh, __FILE__, __LINE__, rc,
1044               "PEM cert and private key did not verify (%s) (%s)",
1045               pemfile->ptr, privkey->ptr);
1046         mbedtls_pk_free(&ssl_pemfile_pkey);
1047         mbedtls_x509_crt_free(&ssl_pemfile_x509);
1048         return NULL;
1049     }
1050 
1051     plugin_cert *pc = malloc(sizeof(plugin_cert));
1052     force_assert(pc);
1053     pc->ssl_pemfile_pkey = ssl_pemfile_pkey;
1054     pc->ssl_pemfile_x509 = ssl_pemfile_x509;
1055     pc->ssl_pemfile = pemfile;
1056     pc->ssl_privkey = privkey;
1057     pc->need_chain = (ssl_pemfile_x509.next == NULL
1058                       && !mod_mbedtls_crt_is_self_issued(&ssl_pemfile_x509));
1059     mbedtls_platform_zeroize(&ssl_pemfile_pkey, sizeof(ssl_pemfile_pkey));
1060 
1061   #if 0
1062     /* needed at top of file for portable timegm(): #include "sys-time.h" */
1063     struct tm tm;
1064     memset(&tm, 0, sizeof(tm));
1065     mbedtls_x509_time *notAfter = &ssl_pemfile_x509->valid_to;
1066     tm.tm_sec   = notAfter->sec;
1067     tm.tm_min   = notAfter->min;
1068     tm.tm_hour  = notAfter->hour;
1069     tm.tm_mday  = notAfter->day;
1070     tm.tm_mon   = notAfter->mon;
1071     tm.tm_year  = notAfter->year;
1072     pc->notAfter = TIME64_CAST(timegm(&tm));
1073   #endif
1074 
1075     return pc;
1076 }
1077 
1078 
1079 #ifdef MBEDTLS_SSL_ALPN
1080 
1081 #ifdef MBEDTLS_SSL_SERVER_NAME_INDICATION
1082 static int
1083 mod_mbedtls_acme_tls_1 (handler_ctx *hctx)
1084 {
1085     buffer * const b = hctx->tmp_buf;
1086     const buffer * const name = &hctx->r->uri.authority;
1087     log_error_st * const errh = hctx->r->conf.errh;
1088     mbedtls_x509_crt *ssl_pemfile_x509 = NULL;
1089     mbedtls_pk_context *ssl_pemfile_pkey = NULL;
1090     size_t len;
1091     int rc = MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
1092 
1093     /* check if acme-tls/1 protocol is enabled (path to dir of cert(s) is set)*/
1094     if (!hctx->conf.ssl_acme_tls_1)
1095         return 0; /*(should not happen)*/
1096 
1097     /* check if SNI set server name (required for acme-tls/1 protocol)
1098      * and perform simple path checks for no '/'
1099      * and no leading '.' (e.g. ignore "." or ".." or anything beginning '.') */
1100     if (buffer_is_blank(name))          return rc;
1101     if (NULL != strchr(name->ptr, '/')) return rc;
1102     if (name->ptr[0] == '.')            return rc;
1103   #if 0
1104     if (0 != http_request_host_policy(name,hctx->r->conf.http_parseopts,443))
1105         return rc;
1106   #endif
1107     buffer_copy_path_len2(b, BUF_PTR_LEN(hctx->conf.ssl_acme_tls_1),
1108                              BUF_PTR_LEN(name));
1109     len = buffer_clen(b);
1110 
1111     do {
1112         buffer_append_string_len(b, CONST_STR_LEN(".crt.pem"));
1113         ssl_pemfile_x509 = malloc(sizeof(*ssl_pemfile_x509));
1114         force_assert(ssl_pemfile_x509);
1115         mbedtls_x509_crt_init(ssl_pemfile_x509); /* init cert structure */
1116       #if MBEDTLS_VERSION_NUMBER >= 0x02170000 /* mbedtls 2.23.0 */
1117         rc = mod_mbedtls_x509_crt_parse_acme(ssl_pemfile_x509, b->ptr);
1118       #else /*(will fail; unable to handle id-pe-acmeIdentifier OID)*/
1119         rc = mod_mbedtls_x509_crt_parse_file(ssl_pemfile_x509, b->ptr);
1120       #endif
1121         if (0 != rc) {
1122             elogf(errh, __FILE__, __LINE__, rc,
1123                   "Failed to load acme-tls/1 pemfile: %s", b->ptr);
1124             break;
1125         }
1126 
1127         buffer_truncate(b, len); /*(remove ".crt.pem")*/
1128         buffer_append_string_len(b, CONST_STR_LEN(".key.pem"));
1129         ssl_pemfile_pkey = malloc(sizeof(*ssl_pemfile_pkey));
1130         force_assert(ssl_pemfile_pkey);
1131         mbedtls_pk_init(ssl_pemfile_pkey);  /* init private key context */
1132         rc = mod_mbedtls_pk_parse_keyfile(ssl_pemfile_pkey, b->ptr, NULL);
1133         if (0 != rc) {
1134             elogf(errh, __FILE__, __LINE__, rc,
1135                   "Failed to load acme-tls/1 pemfile: %s", b->ptr);
1136             break;
1137         }
1138 
1139         rc = mbedtls_ssl_set_hs_own_cert(&hctx->ssl,
1140                                          ssl_pemfile_x509, ssl_pemfile_pkey);
1141         if (0 != rc) {
1142             elogf(errh, __FILE__, __LINE__, rc,
1143                   "failed to set acme-tls/1 certificate for TLS server "
1144                   "name %s", name->ptr);
1145             break;
1146         }
1147 
1148         hctx->acme_tls_1_pkey = ssl_pemfile_pkey; /* save ptr and free later */
1149         hctx->acme_tls_1_x509 = ssl_pemfile_x509; /* save ptr and free later */
1150         return 0;
1151 
1152     } while (0);
1153 
1154     if (ssl_pemfile_pkey) {
1155         mbedtls_pk_free(ssl_pemfile_pkey);
1156         free(ssl_pemfile_pkey);
1157     }
1158     if (ssl_pemfile_x509) {
1159         mbedtls_x509_crt_free(ssl_pemfile_x509);
1160         free(ssl_pemfile_x509);
1161     }
1162 
1163     return rc;
1164 }
1165 #endif
1166 
1167 
1168 static int
1169 mod_mbedtls_alpn_h2_policy (handler_ctx * const hctx)
1170 {
1171     /*(currently called after handshake has completed)*/
1172   #if 0 /* SNI omitted by client when connecting to IP instead of to name */
1173     if (buffer_is_blank(&hctx->r->uri.authority)) {
1174         log_error(hctx->errh, __FILE__, __LINE__,
1175           "SSL: error ALPN h2 without SNI");
1176         return -1;
1177     }
1178   #endif
1179   #if MBEDTLS_VERSION_NUMBER < 0x03000000 /* mbedtls 3.00.0 */
1180     if (hctx->ssl.major_ver == MBEDTLS_SSL_MAJOR_VERSION_3
1181         && hctx->ssl.minor_ver < MBEDTLS_SSL_MINOR_VERSION_3) {
1182         log_error(hctx->errh, __FILE__, __LINE__,
1183           "SSL: error ALPN h2 requires TLSv1.2 or later");
1184         return -1;
1185     }
1186   #else /*(mbedTLS 3.0.0 dropped support for TLSv1.1 and earlier)*/
1187     UNUSED(hctx);
1188   #endif
1189 
1190     return 0;
1191 }
1192 
1193 
1194 static int
1195 mod_mbedtls_alpn_selected (handler_ctx * const hctx, const char * const in)
1196 {
1197     const int n = (int)strlen(in);
1198     const int i = 0;
1199     unsigned short proto;
1200 
1201     switch (n) {
1202       case 2:  /* "h2" */
1203         if (in[i] == 'h' && in[i+1] == '2') {
1204             proto = MOD_MBEDTLS_ALPN_H2;
1205             if (hctx->r->handler_module == NULL)/*(e.g. not mod_sockproxy)*/
1206                 hctx->r->http_version = HTTP_VERSION_2;
1207             break;
1208         }
1209         return 0;
1210       case 8:  /* "http/1.1" "http/1.0" */
1211         if (0 == memcmp(in+i, "http/1.", 7)) {
1212             if (in[i+7] == '1') {
1213                 proto = MOD_MBEDTLS_ALPN_HTTP11;
1214                 break;
1215             }
1216             if (in[i+7] == '0') {
1217                 proto = MOD_MBEDTLS_ALPN_HTTP10;
1218                 break;
1219             }
1220         }
1221         return 0;
1222       case 10: /* "acme-tls/1" */
1223         if (0 == memcmp(in+i, "acme-tls/1", 10)) {
1224             proto = MOD_MBEDTLS_ALPN_ACME_TLS_1;
1225             break;
1226         }
1227         return 0;
1228       default:
1229         return 0;
1230     }
1231 
1232     hctx->alpn = proto;
1233     return 0;
1234 }
1235 
1236 
1237 #if MBEDTLS_VERSION_NUMBER < 0x03000000 /* mbedtls 3.00.0 */
1238 #ifdef MBEDTLS_SSL_SERVER_NAME_INDICATION
1239 static int
1240 mod_mbedtls_alpn_select_cb (handler_ctx *hctx, const unsigned char *in, const unsigned int inlen)
1241 {
1242     /*(skip first two bytes which should match inlen-2)*/
1243     for (unsigned int i = 2, n; i < inlen; i += n) {
1244         n = in[i++];
1245         if (i+n > inlen || 0 == n) break;
1246         switch (n) {
1247           case 2:  /* "h2" */
1248             if (in[i] == 'h' && in[i+1] == '2') {
1249                 if (!hctx->r->conf.h2proto) continue;
1250                 hctx->alpn = MOD_MBEDTLS_ALPN_H2;
1251                 if (hctx->r->handler_module == NULL)/*(e.g. not mod_sockproxy)*/
1252                     hctx->r->http_version = HTTP_VERSION_2;
1253                 return 0;
1254             }
1255             continue;
1256           case 8:  /* "http/1.1" "http/1.0" */
1257             if (0 == memcmp(in+i, "http/1.", 7)) {
1258                 if (in[i+7] == '1') {
1259                     hctx->alpn = MOD_MBEDTLS_ALPN_HTTP11;
1260                     return 0;
1261                 }
1262                 if (in[i+7] == '0') {
1263                     hctx->alpn = MOD_MBEDTLS_ALPN_HTTP10;
1264                     return 0;
1265                 }
1266             }
1267             continue;
1268           case 10: /* "acme-tls/1" */
1269             if (0 == memcmp(in+i, "acme-tls/1", 10)) {
1270                 hctx->alpn = MOD_MBEDTLS_ALPN_ACME_TLS_1;
1271                 return 0;
1272             }
1273             continue;
1274           default:
1275             continue;
1276         }
1277     }
1278 
1279     return 0;
1280 }
1281 #endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
1282 #endif /* MBEDTLS_VERSION_NUMBER < 0x03000000 */ /* mbedtls 3.00.0 */
1283 
1284 #endif /* MBEDTLS_SSL_ALPN */
1285 
1286 
1287 #if MBEDTLS_VERSION_NUMBER >= 0x03020000 /* mbedtls 3.02.0 */
1288 static int
1289 mod_mbedtls_cert_cb (mbedtls_ssl_context * const ssl)
1290 {
1291     handler_ctx * const hctx = mbedtls_ssl_get_user_data_p(ssl);
1292     int rc = 0;
1293 
1294   #ifdef MBEDTLS_SSL_ALPN
1295     const char *alpn = mbedtls_ssl_get_alpn_protocol(&hctx->ssl);
1296     if (NULL != alpn) {
1297         rc = mod_mbedtls_alpn_selected(hctx, alpn);
1298         if (0 != rc) return rc;
1299     }
1300   #endif
1301 
1302   #ifdef MBEDTLS_SSL_SERVER_NAME_INDICATION
1303     size_t len;
1304     const unsigned char *servername = mbedtls_ssl_get_hs_sni(ssl, &len);
1305     if (servername) {
1306         rc = mod_mbedtls_SNI(hctx, ssl, servername, len);
1307         if (0 != rc) return rc;
1308     } /*(else no SNI)*/
1309    #if 0 /*"acme-tls/1" required SNI; use default cert; let cert challenge fail*/
1310     else if (hctx->alpn == MOD_MBEDTLS_ALPN_ACME_TLS_1)
1311         return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
1312    #endif
1313   #endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
1314 
1315     if (hctx->conf.ssl_verifyclient
1316         && hctx->alpn != MOD_MBEDTLS_ALPN_ACME_TLS_1) { /*(not "acme-tls/1")*/
1317         rc = mod_mbedtls_conf_verify(hctx);
1318         if (0 != rc) return rc;
1319     }
1320 
1321     return rc;
1322 }
1323 #endif
1324 
1325 
1326 static int
1327 mod_mbedtls_ssl_conf_ciphersuites (server *srv, plugin_config_socket *s, buffer *ciphersuites, const buffer *cipherstring);
1328 
1329 
1330 static int
1331 mod_mbedtls_ssl_conf_curves(server *srv, plugin_config_socket *s, const buffer *curvelist);
1332 
1333 
1334 static void
1335 mod_mbedtls_ssl_conf_proto (server *srv, plugin_config_socket *s, const buffer *b, int max);
1336 
1337 
1338 static int
1339 mod_mbedtls_ssl_conf_cmd (server *srv, plugin_config_socket *s)
1340 {
1341     /* reference:
1342      * https://www.openssl.org/docs/man1.1.1/man3/SSL_CONF_cmd.html */
1343     int rc = 0;
1344     buffer *cipherstring = NULL;
1345     buffer *ciphersuites = NULL;
1346 
1347     for (size_t i = 0; i < s->ssl_conf_cmd->used; ++i) {
1348         data_string *ds = (data_string *)s->ssl_conf_cmd->data[i];
1349         if (buffer_eq_icase_slen(&ds->key, CONST_STR_LEN("CipherString")))
1350             cipherstring = &ds->value;
1351         else if (buffer_eq_icase_slen(&ds->key, CONST_STR_LEN("Ciphersuites")))
1352             ciphersuites = &ds->value;
1353         else if (buffer_eq_icase_slen(&ds->key, CONST_STR_LEN("Curves"))
1354               || buffer_eq_icase_slen(&ds->key, CONST_STR_LEN("Groups"))) {
1355             if (!mod_mbedtls_ssl_conf_curves(srv, s, &ds->value))
1356                 rc = -1;
1357         }
1358         else if (buffer_eq_icase_slen(&ds->key, CONST_STR_LEN("MaxProtocol")))
1359             mod_mbedtls_ssl_conf_proto(srv, s, &ds->value, 1); /* max */
1360         else if (buffer_eq_icase_slen(&ds->key, CONST_STR_LEN("MinProtocol")))
1361             mod_mbedtls_ssl_conf_proto(srv, s, &ds->value, 0); /* min */
1362         else if (buffer_eq_icase_slen(&ds->key, CONST_STR_LEN("Protocol"))) {
1363             /* openssl config for Protocol=... is complex and deprecated */
1364             log_error(srv->errh, __FILE__, __LINE__,
1365                       "MTLS: ssl.openssl.ssl-conf-cmd %s ignored; "
1366                       "use MinProtocol=... and MaxProtocol=... instead",
1367                       ds->key.ptr);
1368         }
1369         else if (buffer_eq_icase_slen(&ds->key, CONST_STR_LEN("Options"))) {
1370             for (char *v = ds->value.ptr, *e; *v; v = e) {
1371                 while (*v == ' ' || *v == '\t' || *v == ',') ++v;
1372                 int flag = 1;
1373                 if (*v == '-') {
1374                     flag = 0;
1375                     ++v;
1376                 }
1377                 for (e = v; light_isalpha(*e); ++e) ;
1378                 switch ((int)(e-v)) {
1379                   case 11:
1380                     if (buffer_eq_icase_ssn(v, "Compression", 11)) {
1381                         /* mbedtls defaults to no record compression unless
1382                          * mbedtls is built with MBEDTLS_ZLIB_SUPPORT, which
1383                          * is deprecated and slated for removal*/
1384                         if (!flag) continue;
1385                     }
1386                     break;
1387                   case 13:
1388                     if (buffer_eq_icase_ssn(v, "SessionTicket", 13)) {
1389                         s->ssl_session_ticket = flag;
1390                         continue;
1391                     }
1392                     break;
1393                   case 16:
1394                     if (buffer_eq_icase_ssn(v, "ServerPreference", 16)) {
1395                         /* Note: before mbedTLS 3.0.0, the server uses its own
1396                          * preferences over the preference of the client unless
1397                          * MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE defined! */
1398                         s->ssl_honor_cipher_order = flag;
1399                         continue;
1400                     }
1401                     break;
1402                   default:
1403                     break;
1404                 }
1405                 /* warn if not explicitly handled or ignored above */
1406                 if (!flag) --v;
1407                 log_error(srv->errh, __FILE__, __LINE__,
1408                           "MTLS: ssl.openssl.ssl-conf-cmd Options %.*s ignored",
1409                           (int)(e-v), v);
1410             }
1411         }
1412       #if 0
1413         else if (buffer_eq_icase_slen(&ds->key, CONST_STR_LEN("..."))) {
1414         }
1415       #endif
1416         else {
1417             /* warn if not explicitly handled or ignored above */
1418             log_error(srv->errh, __FILE__, __LINE__,
1419                       "MTLS: ssl.openssl.ssl-conf-cmd %s ignored",
1420                       ds->key.ptr);
1421         }
1422     }
1423 
1424     if (!mod_mbedtls_ssl_conf_ciphersuites(srv, s, ciphersuites, cipherstring))
1425         rc = -1;
1426 
1427     return rc;
1428 }
1429 
1430 
1431 static int
1432 network_init_ssl (server *srv, plugin_config_socket *s, plugin_data *p)
1433 {
1434     int rc;
1435 
1436     s->ssl_ctx = malloc(sizeof(mbedtls_ssl_config));
1437     force_assert(s->ssl_ctx);
1438     mbedtls_ssl_config_init(s->ssl_ctx);
1439 
1440     /* set the RNG in the ssl config context, using the default random func */
1441     mbedtls_ssl_conf_rng(s->ssl_ctx, mbedtls_ctr_drbg_random, &p->ctr_drbg);
1442 
1443     /* mbedtls defaults to disable client renegotiation
1444      * mbedtls defaults to no record compression unless mbedtls is built
1445      *   with MBEDTLS_ZLIB_SUPPORT, which is deprecated and slated for removal
1446      * MBEDTLS_SSL_PRESET_SUITEB is stricter than MBEDTLS_SSL_PRESET_DEFAULT
1447      * (and is attempted to be supported in mod_mbedtls_ssl_conf_ciphersuites())
1448      * explanation: https://github.com/ARMmbed/mbedtls/issues/1591
1449      * reference: RFC 6460 */
1450     rc = mbedtls_ssl_config_defaults(s->ssl_ctx,
1451                                      MBEDTLS_SSL_IS_SERVER,
1452                                      MBEDTLS_SSL_TRANSPORT_STREAM,
1453                                      MBEDTLS_SSL_PRESET_DEFAULT);
1454     if (0 != rc) {
1455         elog(srv->errh, __FILE__,__LINE__, rc,
1456              "Init of ssl config context defaults failed");
1457         return -1;
1458     }
1459 
1460     /* mbedtls defaults minimum accepted SSL/TLS protocol version TLS v1.0
1461      * use of SSL v3 should be avoided, and SSL v2 is not supported */
1462   #ifdef MBEDTLS_SSL_PROTO_SSL3
1463     if (s->ssl_use_sslv3)
1464         mbedtls_ssl_conf_min_version(s->ssl_ctx, MBEDTLS_SSL_MAJOR_VERSION_3,
1465                                                  MBEDTLS_SSL_MINOR_VERSION_0);
1466   #endif
1467 
1468     if (s->ssl_cipher_list) {
1469         if (!mod_mbedtls_ssl_conf_ciphersuites(srv,s,NULL,s->ssl_cipher_list))
1470             return -1;
1471     }
1472 
1473     if (s->ssl_dh_file) {
1474         mbedtls_dhm_context dhm;
1475         mbedtls_dhm_init(&dhm);
1476         rc = mbedtls_dhm_parse_dhmfile(&dhm, s->ssl_dh_file->ptr);
1477         if (0 != rc)
1478             elogf(srv->errh, __FILE__,__LINE__, rc,
1479                  "mbedtls_dhm_parse_dhmfile() %s", s->ssl_dh_file->ptr);
1480         else {
1481             rc = mbedtls_ssl_conf_dh_param_ctx(s->ssl_ctx, &dhm);
1482             if (0 != rc)
1483                 elogf(srv->errh, __FILE__,__LINE__, rc,
1484                      "mbedtls_ssl_conf_dh_param_ctx() %s", s->ssl_dh_file->ptr);
1485         }
1486         mbedtls_dhm_free(&dhm);
1487         if (0 != rc)
1488             return -1;
1489     }
1490 
1491     if (s->ssl_ec_curve) {
1492         if (!mod_mbedtls_ssl_conf_curves(srv, s, s->ssl_ec_curve))
1493             return -1;
1494     }
1495 
1496     /* if needed, attempt to construct certificate chain for server cert */
1497     if (s->pc->need_chain) {
1498         s->pc->need_chain = 0; /*(attempt once to complete chain)*/
1499         if (!mod_mbedtls_construct_crt_chain(s->ssl_pemfile_x509,
1500                                              s->ssl_ca_file, srv->errh))
1501             return -1;
1502     }
1503 
1504     rc = mbedtls_ssl_conf_own_cert(s->ssl_ctx,
1505                                    s->ssl_pemfile_x509, s->ssl_pemfile_pkey);
1506     if (0 != rc) {
1507         elogf(srv->errh, __FILE__, __LINE__, rc,
1508               "PEM cert and private key did not verify (%s) (%s)",
1509               s->ssl_pemfile->ptr, s->ssl_privkey->ptr);
1510         return -1;
1511     }
1512 
1513   #if MBEDTLS_VERSION_NUMBER >= 0x03020000 /* mbedtls 3.02.0 */
1514     mbedtls_ssl_conf_cert_cb(s->ssl_ctx, mod_mbedtls_cert_cb);
1515   #endif
1516 
1517   #ifdef MBEDTLS_SSL_ALPN
1518     /* https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids */
1519     static const char *alpn_protos_http_acme[] = {
1520       "h2"
1521      ,"http/1.1"
1522      ,"http/1.0"
1523      ,"acme-tls/1"
1524      ,NULL
1525     };
1526     static const char *alpn_protos_http[] = {
1527       "h2"
1528      ,"http/1.1"
1529      ,"http/1.0"
1530      ,NULL
1531     };
1532     const char **alpn_protos = (s->ssl_acme_tls_1)
1533       ? alpn_protos_http_acme
1534       : alpn_protos_http;
1535     if (!srv->srvconf.h2proto) ++alpn_protos;
1536     rc = mbedtls_ssl_conf_alpn_protocols(s->ssl_ctx, alpn_protos);
1537     if (0 != rc) {
1538         elog(srv->errh, __FILE__, __LINE__, rc, "error setting ALPN protocols");
1539         return -1;
1540     }
1541   #endif
1542 
1543     if (!s->ssl_use_sslv3 && !s->ssl_use_sslv2)
1544         mod_mbedtls_ssl_conf_proto(srv, s, NULL, 0); /* min */
1545 
1546     if (s->ssl_conf_cmd && s->ssl_conf_cmd->used) {
1547         if (0 != mod_mbedtls_ssl_conf_cmd(srv, s)) return -1;
1548     }
1549 
1550  #if MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.00.0 */
1551     int order = s->ssl_honor_cipher_order
1552       ? MBEDTLS_SSL_SRV_CIPHERSUITE_ORDER_SERVER
1553       : MBEDTLS_SSL_SRV_CIPHERSUITE_ORDER_CLIENT;
1554     mbedtls_ssl_conf_preference_order(s->ssl_ctx, order);
1555  #else
1556     /* server preference is used (default) unless mbedtls is built with
1557      * MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE defined (not default) */
1558   #ifndef MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE
1559     if (!s->ssl_honor_cipher_order)
1560         log_error(srv->errh, __FILE__, __LINE__,
1561           "MTLS: "
1562           "ignoring ssl.honor-cipher-order; mbedtls uses server preference "
1563           "unless mbedtls built MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE");
1564   #else
1565     if (s->ssl_honor_cipher_order)
1566         log_error(srv->errh, __FILE__, __LINE__,
1567           "MTLS: "
1568           "ignoring ssl.honor-cipher-order; mbedtls uses client preference "
1569           "since mbedtls built MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE");
1570   #endif
1571  #endif
1572 
1573   #if defined(MBEDTLS_SSL_SESSION_TICKETS)
1574     if (s->ssl_session_ticket            /*(.ticket_lifetime is private)*/
1575         && !*(unsigned char *)&p->ticket_ctx) { /*init once*/
1576         rc = mbedtls_ssl_ticket_setup(&p->ticket_ctx, mbedtls_ctr_drbg_random,
1577                                       &p->ctr_drbg, MBEDTLS_CIPHER_AES_256_GCM,
1578                                       43200); /* ticket timeout: 12 hours */
1579         if (0 != rc) {
1580             elog(srv->errh, __FILE__,__LINE__, rc,
1581                  "mbedtls_ssl_ticket_setup()");
1582             return -1;
1583         }
1584     }
1585 
1586    #if defined(MBEDTLS_SSL_TICKET_C)
1587     if (s->ssl_session_ticket)
1588         mbedtls_ssl_conf_session_tickets_cb(s->ssl_ctx,
1589                                             mbedtls_ssl_ticket_write,
1590                                             mbedtls_ssl_ticket_parse,
1591                                             &p->ticket_ctx);
1592    #endif
1593   #endif /* MBEDTLS_SSL_SESSION_TICKETS */
1594 
1595     return 0;
1596 }
1597 
1598 
1599 static int
1600 mod_mbedtls_set_defaults_sockets(server *srv, plugin_data *p)
1601 {
1602     static const config_plugin_keys_t cpk[] = {
1603       { CONST_STR_LEN("ssl.engine"),
1604         T_CONFIG_BOOL,
1605         T_CONFIG_SCOPE_SOCKET }
1606      ,{ CONST_STR_LEN("ssl.cipher-list"),
1607         T_CONFIG_STRING,
1608         T_CONFIG_SCOPE_SOCKET }
1609      ,{ CONST_STR_LEN("ssl.honor-cipher-order"),
1610         T_CONFIG_BOOL,
1611         T_CONFIG_SCOPE_SOCKET }
1612      ,{ CONST_STR_LEN("ssl.dh-file"),
1613         T_CONFIG_STRING,
1614         T_CONFIG_SCOPE_SOCKET }
1615      ,{ CONST_STR_LEN("ssl.ec-curve"),
1616         T_CONFIG_STRING,
1617         T_CONFIG_SCOPE_SOCKET }
1618      ,{ CONST_STR_LEN("ssl.openssl.ssl-conf-cmd"),
1619         T_CONFIG_ARRAY_KVSTRING,
1620         T_CONFIG_SCOPE_SOCKET }
1621      ,{ CONST_STR_LEN("ssl.pemfile"), /* included to process global scope */
1622         T_CONFIG_STRING,
1623         T_CONFIG_SCOPE_CONNECTION }
1624      ,{ CONST_STR_LEN("ssl.empty-fragments"),
1625         T_CONFIG_BOOL,
1626         T_CONFIG_SCOPE_SOCKET }
1627      ,{ CONST_STR_LEN("ssl.use-sslv2"),
1628         T_CONFIG_BOOL,
1629         T_CONFIG_SCOPE_SOCKET }
1630      ,{ CONST_STR_LEN("ssl.use-sslv3"),
1631         T_CONFIG_BOOL,
1632         T_CONFIG_SCOPE_SOCKET }
1633      ,{ CONST_STR_LEN("ssl.stek-file"),
1634         T_CONFIG_STRING,
1635         T_CONFIG_SCOPE_SERVER }
1636      ,{ NULL, 0,
1637         T_CONFIG_UNSET,
1638         T_CONFIG_SCOPE_UNSET }
1639     };
1640     static const buffer default_ssl_cipher_list = { CONST_STR_LEN("HIGH"), 0 };
1641 
1642     p->ssl_ctxs = calloc(srv->config_context->used, sizeof(plugin_ssl_ctx));
1643     force_assert(p->ssl_ctxs);
1644 
1645     int rc = HANDLER_GO_ON;
1646     plugin_data_base srvplug;
1647     memset(&srvplug, 0, sizeof(srvplug));
1648     plugin_data_base * const ps = &srvplug;
1649     if (!config_plugin_values_init(srv, ps, cpk, "mod_mbedtls"))
1650         return HANDLER_ERROR;
1651 
1652     plugin_config_socket defaults;
1653     memset(&defaults, 0, sizeof(defaults));
1654   #ifndef MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE
1655     defaults.ssl_honor_cipher_order = 1;
1656   #endif
1657     defaults.ssl_session_ticket     = 1; /* enabled by default */
1658     defaults.ssl_cipher_list = &default_ssl_cipher_list;
1659 
1660     /* process and validate config directives for global and $SERVER["socket"]
1661      * (init i to 0 if global context; to 1 to skip empty global context) */
1662     for (int i = !ps->cvlist[0].v.u2[1]; i < ps->nconfig; ++i) {
1663         config_cond_info cfginfo;
1664         config_get_config_cond_info(&cfginfo, (uint32_t)ps->cvlist[i].k_id);
1665         int is_socket_scope = (0 == i || cfginfo.comp == COMP_SERVER_SOCKET);
1666         int count_not_engine = 0;
1667 
1668         plugin_config_socket conf;
1669         memcpy(&conf, &defaults, sizeof(conf));
1670 
1671         /*(preserve prior behavior; not inherited)*/
1672         /*(forcing inheritance might break existing configs where SSL is enabled
1673          * by default in the global scope, but not $SERVER["socket"]=="*:80") */
1674         conf.ssl_enabled = 0;
1675 
1676         config_plugin_value_t *cpv = ps->cvlist + ps->cvlist[i].v.u2[0];
1677         for (; -1 != cpv->k_id; ++cpv) {
1678             /* ignore ssl.pemfile (k_id=6); included to process global scope */
1679             if (!is_socket_scope && cpv->k_id != 6) {
1680                 log_error(srv->errh, __FILE__, __LINE__,
1681                   "MTLS: %s is valid only in global scope or "
1682                   "$SERVER[\"socket\"] condition", cpk[cpv->k_id].k);
1683                 continue;
1684             }
1685             ++count_not_engine;
1686             switch (cpv->k_id) {
1687               case 0: /* ssl.engine */
1688                 conf.ssl_enabled = (0 != cpv->v.u);
1689                 --count_not_engine;
1690                 break;
1691               case 1: /* ssl.cipher-list */
1692                 if (!buffer_is_blank(cpv->v.b))
1693                     conf.ssl_cipher_list = cpv->v.b;
1694                 break;
1695               case 2: /* ssl.honor-cipher-order */
1696                 conf.ssl_honor_cipher_order = (0 != cpv->v.u);
1697                 break;
1698               case 3: /* ssl.dh-file */
1699                 if (!buffer_is_blank(cpv->v.b))
1700                     conf.ssl_dh_file = cpv->v.b;
1701                 break;
1702               case 4: /* ssl.ec-curve */
1703                 if (!buffer_is_blank(cpv->v.b))
1704                     conf.ssl_ec_curve = cpv->v.b;
1705                 break;
1706               case 5: /* ssl.openssl.ssl-conf-cmd */
1707                 *(const array **)&conf.ssl_conf_cmd = cpv->v.a;
1708                 break;
1709               case 6: /* ssl.pemfile */
1710                 /* ignore here; included to process global scope when
1711                  * ssl.pemfile is set, but ssl.engine is not "enable" */
1712                 break;
1713               case 7: /* ssl.empty-fragments */
1714                 conf.ssl_empty_fragments = (0 != cpv->v.u);
1715                 log_error(srv->errh, __FILE__, __LINE__,
1716                   "MTLS: ignoring ssl.empty-fragments; openssl-specific "
1717                   "counter-measure against a SSL 3.0/TLS 1.0 protocol "
1718                   "vulnerability affecting CBC ciphers, which cannot be handled"
1719                   " by some broken (Microsoft) SSL implementations.");
1720                 break;
1721               case 8: /* ssl.use-sslv2 */
1722                 conf.ssl_use_sslv2 = (0 != cpv->v.u);
1723                 log_error(srv->errh, __FILE__, __LINE__, "MTLS: "
1724                   "ssl.use-sslv2 is deprecated and will soon be removed.  "
1725                   "Many modern TLS libraries no longer support SSLv2.");
1726                 break;
1727               case 9: /* ssl.use-sslv3 */
1728                 conf.ssl_use_sslv3 = (0 != cpv->v.u);
1729                 log_error(srv->errh, __FILE__, __LINE__, "MTLS: "
1730                   "ssl.use-sslv3 is deprecated and will soon be removed.  "
1731                   "Many modern TLS libraries no longer support SSLv3.  "
1732                   "If needed, use: "
1733                   "ssl.openssl.ssl-conf-cmd = (\"MinProtocol\" => \"SSLv3\")");
1734                 break;
1735               case 10:/* ssl.stek-file */
1736                #ifdef MBEDTLS_SSL_SESSION_TICKETS
1737                 if (!buffer_is_blank(cpv->v.b))
1738                     p->ssl_stek_file = cpv->v.b->ptr;
1739                #else
1740                 log_error(srv->errh, __FILE__, __LINE__, "MTLS: "
1741                   "ssl.stek-file ignored; mbedtls library not built with "
1742                   "support for SSL session tickets");
1743                #endif
1744                 break;
1745               default:/* should not happen */
1746                 break;
1747             }
1748         }
1749         if (HANDLER_GO_ON != rc) break;
1750         if (0 == i) memcpy(&defaults, &conf, sizeof(conf));
1751 
1752         if (0 != i && !conf.ssl_enabled) continue;
1753 
1754         /* fill plugin_config_socket with global context then $SERVER["socket"]
1755          * only for directives directly in current $SERVER["socket"] condition*/
1756 
1757         /*conf.ssl_pemfile_pkey       = p->defaults.ssl_pemfile_pkey;*/
1758         /*conf.ssl_pemfile_x509       = p->defaults.ssl_pemfile_x509;*/
1759         conf.ssl_verifyclient         = p->defaults.ssl_verifyclient;
1760         conf.ssl_verifyclient_enforce = p->defaults.ssl_verifyclient_enforce;
1761         conf.ssl_verifyclient_depth   = p->defaults.ssl_verifyclient_depth;
1762         conf.ssl_acme_tls_1           = p->defaults.ssl_acme_tls_1;
1763 
1764         int sidx = ps->cvlist[i].k_id;
1765         for (int j = !p->cvlist[0].v.u2[1]; j < p->nconfig; ++j) {
1766             if (p->cvlist[j].k_id != sidx) continue;
1767             /*if (0 == sidx) break;*//*(repeat to get ssl_pemfile,ssl_privkey)*/
1768             cpv = p->cvlist + p->cvlist[j].v.u2[0];
1769             for (; -1 != cpv->k_id; ++cpv) {
1770                 ++count_not_engine;
1771                 switch (cpv->k_id) {
1772                   case 0: /* ssl.pemfile */
1773                     if (cpv->vtype == T_CONFIG_LOCAL) {
1774                         plugin_cert *pc = cpv->v.v;
1775                         conf.pc               = pc;
1776                         conf.ssl_pemfile_pkey = &pc->ssl_pemfile_pkey;
1777                         conf.ssl_pemfile_x509 = &pc->ssl_pemfile_x509;
1778                         conf.ssl_pemfile      = pc->ssl_pemfile;
1779                         conf.ssl_privkey      = pc->ssl_privkey;
1780                     }
1781                     break;
1782                   case 2: /* ssl.ca-file */
1783                     if (cpv->vtype == T_CONFIG_LOCAL)
1784                         conf.ssl_ca_file = cpv->v.v;
1785                     break;
1786                   case 7: /* ssl.verifyclient.activate */
1787                     conf.ssl_verifyclient = (0 != cpv->v.u);
1788                     break;
1789                   case 8: /* ssl.verifyclient.enforce */
1790                     conf.ssl_verifyclient_enforce = (0 != cpv->v.u);
1791                     break;
1792                   case 9: /* ssl.verifyclient.depth */
1793                     conf.ssl_verifyclient_depth = (unsigned char)cpv->v.shrt;
1794                     break;
1795                   case 12:/* ssl.acme-tls-1 */
1796                     conf.ssl_acme_tls_1 = cpv->v.b;
1797                     break;
1798                  #if 0    /*(cpk->k_id remapped in mod_mbedtls_set_defaults())*/
1799                   case 14:/* ssl.verifyclient.ca-file */
1800                  #endif
1801                   default:
1802                     break;
1803                 }
1804             }
1805             break;
1806         }
1807 
1808         if (NULL == conf.ssl_pemfile_x509) {
1809             if (0 == i && !conf.ssl_enabled) continue;
1810             if (0 != i) {
1811                 /* inherit ssl settings from global scope
1812                  * (if only ssl.engine = "enable" and no other ssl.* settings)
1813                  * (This is for convenience when defining both IPv4 and IPv6
1814                  *  and desiring to inherit the ssl config from global context
1815                  *  without having to duplicate the directives)*/
1816                 if (count_not_engine
1817                     || (conf.ssl_enabled && NULL == p->ssl_ctxs[0].ssl_ctx)) {
1818                     log_error(srv->errh, __FILE__, __LINE__,
1819                       "MTLS: ssl.pemfile has to be set in same "
1820                       "$SERVER[\"socket\"] scope as other ssl.* directives, "
1821                       "unless only ssl.engine is set, inheriting ssl.* from "
1822                       "global scope");
1823                     rc = HANDLER_ERROR;
1824                     continue;
1825                 }
1826                 plugin_ssl_ctx * const s = p->ssl_ctxs + sidx;
1827                 *s = *p->ssl_ctxs;/*(copy struct of ssl_ctx from global scope)*/
1828                 continue;
1829             }
1830             /* PEM file is required */
1831             log_error(srv->errh, __FILE__, __LINE__,
1832               "MTLS: ssl.pemfile has to be set when ssl.engine = \"enable\"");
1833             rc = HANDLER_ERROR;
1834             continue;
1835         }
1836 
1837         /* (initialize once if module enabled) */
1838         if (!mod_mbedtls_init_once_mbedtls(srv)) {
1839             rc = HANDLER_ERROR;
1840             break;
1841         }
1842 
1843         /* configure ssl_ctx for socket */
1844 
1845         /*conf.ssl_ctx = NULL;*//*(filled by network_init_ssl() even on error)*/
1846         if (0 == network_init_ssl(srv, &conf, p)) {
1847             plugin_ssl_ctx * const s = p->ssl_ctxs + sidx;
1848             s->ssl_ctx            = conf.ssl_ctx;
1849             s->ciphersuites       = conf.ciphersuites;
1850             s->curves             = conf.curves;
1851         }
1852         else {
1853             mbedtls_ssl_config_free(conf.ssl_ctx);
1854             free(conf.ciphersuites);
1855             free(conf.curves);
1856             rc = HANDLER_ERROR;
1857         }
1858     }
1859 
1860   #ifdef MBEDTLS_SSL_SESSION_TICKETS
1861     if (rc == HANDLER_GO_ON && ssl_is_init)
1862         mod_mbedtls_session_ticket_key_check(p, log_epoch_secs);
1863   #endif
1864 
1865     free(srvplug.cvlist);
1866     return rc;
1867 }
1868 
1869 
1870 SETDEFAULTS_FUNC(mod_mbedtls_set_defaults)
1871 {
1872     static const config_plugin_keys_t cpk[] = {
1873       { CONST_STR_LEN("ssl.pemfile"),
1874         T_CONFIG_STRING,
1875         T_CONFIG_SCOPE_CONNECTION }
1876      ,{ CONST_STR_LEN("ssl.privkey"),
1877         T_CONFIG_STRING,
1878         T_CONFIG_SCOPE_CONNECTION }
1879      ,{ CONST_STR_LEN("ssl.ca-file"),
1880         T_CONFIG_STRING,
1881         T_CONFIG_SCOPE_CONNECTION }
1882      ,{ CONST_STR_LEN("ssl.ca-dn-file"),
1883         T_CONFIG_STRING,
1884         T_CONFIG_SCOPE_CONNECTION }
1885      ,{ CONST_STR_LEN("ssl.ca-crl-file"),
1886         T_CONFIG_STRING,
1887         T_CONFIG_SCOPE_CONNECTION }
1888      ,{ CONST_STR_LEN("ssl.read-ahead"),
1889         T_CONFIG_BOOL,
1890         T_CONFIG_SCOPE_CONNECTION }
1891      ,{ CONST_STR_LEN("ssl.disable-client-renegotiation"),
1892         T_CONFIG_BOOL,
1893         T_CONFIG_SCOPE_CONNECTION }
1894      ,{ CONST_STR_LEN("ssl.verifyclient.activate"),
1895         T_CONFIG_BOOL,
1896         T_CONFIG_SCOPE_CONNECTION }
1897      ,{ CONST_STR_LEN("ssl.verifyclient.enforce"),
1898         T_CONFIG_BOOL,
1899         T_CONFIG_SCOPE_CONNECTION }
1900      ,{ CONST_STR_LEN("ssl.verifyclient.depth"),
1901         T_CONFIG_SHORT,
1902         T_CONFIG_SCOPE_CONNECTION }
1903      ,{ CONST_STR_LEN("ssl.verifyclient.username"),
1904         T_CONFIG_STRING,
1905         T_CONFIG_SCOPE_CONNECTION }
1906      ,{ CONST_STR_LEN("ssl.verifyclient.exportcert"),
1907         T_CONFIG_BOOL,
1908         T_CONFIG_SCOPE_CONNECTION }
1909      ,{ CONST_STR_LEN("ssl.acme-tls-1"),
1910         T_CONFIG_STRING,
1911         T_CONFIG_SCOPE_CONNECTION }
1912      ,{ CONST_STR_LEN("debug.log-ssl-noise"),
1913         T_CONFIG_BOOL,
1914         T_CONFIG_SCOPE_CONNECTION }
1915      ,{ CONST_STR_LEN("ssl.verifyclient.ca-file"),
1916         T_CONFIG_STRING,
1917         T_CONFIG_SCOPE_CONNECTION }
1918      ,{ CONST_STR_LEN("ssl.verifyclient.ca-dn-file"),
1919         T_CONFIG_STRING,
1920         T_CONFIG_SCOPE_CONNECTION }
1921      ,{ CONST_STR_LEN("ssl.verifyclient.ca-crl-file"),
1922         T_CONFIG_STRING,
1923         T_CONFIG_SCOPE_CONNECTION }
1924      ,{ NULL, 0,
1925         T_CONFIG_UNSET,
1926         T_CONFIG_SCOPE_UNSET }
1927     };
1928 
1929     plugin_data * const p = p_d;
1930     p->srv = srv;
1931     if (!config_plugin_values_init(srv, p, cpk, "mod_mbedtls"))
1932         return HANDLER_ERROR;
1933 
1934     /* process and validate config directives
1935      * (init i to 0 if global context; to 1 to skip empty global context) */
1936     for (int i = !p->cvlist[0].v.u2[1]; i < p->nconfig; ++i) {
1937         config_plugin_value_t *cpv = p->cvlist + p->cvlist[i].v.u2[0];
1938         config_plugin_value_t *pemfile = NULL;
1939         config_plugin_value_t *privkey = NULL;
1940         for (; -1 != cpv->k_id; ++cpv) {
1941             switch (cpv->k_id) {
1942               case 0: /* ssl.pemfile */
1943                 if (!buffer_is_blank(cpv->v.b)) pemfile = cpv;
1944                 break;
1945               case 1: /* ssl.privkey */
1946                 if (!buffer_is_blank(cpv->v.b)) privkey = cpv;
1947                 break;
1948               case 14:/* ssl.verifyclient.ca-file */
1949                 if (cpv->k_id == 14) cpv->k_id = 2;
1950                 __attribute_fallthrough__
1951               case 15:/* ssl.verifyclient.ca-dn-file */
1952                 if (cpv->k_id == 15) cpv->k_id = 3;
1953                 __attribute_fallthrough__
1954               case 2: /* ssl.ca-file */
1955               case 3: /* ssl.ca-dn-file */
1956                #if 0 /* defer; not necessary for pemfile parsing */
1957                 if (!mod_mbedtls_init_once_mbedtls(srv)) return HANDLER_ERROR;
1958                #endif
1959                 if (!buffer_is_blank(cpv->v.b)) {
1960                     mbedtls_x509_crt *cacert = calloc(1, sizeof(*cacert));
1961                     force_assert(cacert);
1962                     mbedtls_x509_crt_init(cacert);
1963                     int rc =
1964                       mod_mbedtls_x509_crt_parse_file(cacert, cpv->v.b->ptr);
1965                     if (0 == rc) {
1966                         cpv->vtype = T_CONFIG_LOCAL;
1967                         cpv->v.v = cacert;
1968                     }
1969                     else {
1970                         elogf(srv->errh, __FILE__, __LINE__, rc,
1971                               "%s = %s", cpk[cpv->k_id].k, cpv->v.b->ptr);
1972                         mbedtls_x509_crt_free(cacert);
1973                         free(cacert);
1974                         return HANDLER_ERROR;
1975                     }
1976                 }
1977                 break;
1978               case 16:/* ssl.verifyclient.ca-crl-file */
1979                 cpv->k_id = 4;
1980                 __attribute_fallthrough__
1981               case 4: /* ssl.ca-crl-file */
1982                 if (!buffer_is_blank(cpv->v.b)) {
1983                     mbedtls_x509_crl *crl = malloc(sizeof(*crl));
1984                     force_assert(crl);
1985                     mbedtls_x509_crl_init(crl);
1986                     int rc =
1987                       mod_mbedtls_x509_crl_parse_file(crl, cpv->v.b->ptr);
1988                     if (0 == rc) {
1989                         cpv->vtype = T_CONFIG_LOCAL;
1990                         cpv->v.v = crl;
1991                     }
1992                     else {
1993                         elogf(srv->errh, __FILE__, __LINE__, rc,
1994                               "CRL file read failed (%s)", cpv->v.b->ptr);
1995                         free(crl);
1996                         return HANDLER_ERROR;
1997                     }
1998                 }
1999                 break;
2000               case 5: /* ssl.read-ahead */
2001                 break;
2002               case 6: /* ssl.disable-client-renegotiation */
2003                 /* (force disabled, the default, if HTTP/2 enabled in server) */
2004                 if (srv->srvconf.h2proto)
2005                     cpv->v.u = 1; /* disable client renegotiation */
2006                 break;
2007               case 7: /* ssl.verifyclient.activate */
2008               case 8: /* ssl.verifyclient.enforce */
2009                 break;
2010               case 9: /* ssl.verifyclient.depth */
2011                 if (cpv->v.shrt > 255) {
2012                     log_error(srv->errh, __FILE__, __LINE__,
2013                       "MTLS: %s is absurdly large (%hu); limiting to 255",
2014                       cpk[cpv->k_id].k, cpv->v.shrt);
2015                     cpv->v.shrt = 255;
2016                 }
2017                 break;
2018               case 10:/* ssl.verifyclient.username */
2019                 if (buffer_is_blank(cpv->v.b))
2020                     cpv->v.b = NULL;
2021                 break;
2022               case 11:/* ssl.verifyclient.exportcert */
2023                 break;
2024               case 12:/* ssl.acme-tls-1 */
2025                 if (buffer_is_blank(cpv->v.b))
2026                     cpv->v.b = NULL;
2027                 break;
2028               case 13:/* debug.log-ssl-noise */
2029              #if 0    /*(handled further above)*/
2030               case 14:/* ssl.verifyclient.ca-file */
2031               case 15:/* ssl.verifyclient.ca-dn-file */
2032               case 16:/* ssl.verifyclient.ca-crl-file */
2033              #endif
2034                 break;
2035               default:/* should not happen */
2036                 break;
2037             }
2038         }
2039 
2040         if (pemfile) {
2041             if (NULL == privkey) privkey = pemfile;
2042             pemfile->v.v =
2043               network_mbedtls_load_pemfile(srv, pemfile->v.b, privkey->v.b);
2044             if (pemfile->v.v)
2045                 pemfile->vtype = T_CONFIG_LOCAL;
2046             else
2047                 return HANDLER_ERROR;
2048         }
2049     }
2050 
2051     p->defaults.ssl_verifyclient = 0;
2052     p->defaults.ssl_verifyclient_enforce = 1;
2053     p->defaults.ssl_verifyclient_depth = 9;
2054     p->defaults.ssl_verifyclient_export_cert = 0;
2055     p->defaults.ssl_disable_client_renegotiation = 1;
2056     p->defaults.ssl_read_ahead = 0;
2057 
2058     /* initialize p->defaults from global config context */
2059     if (p->nconfig > 0 && p->cvlist->v.u2[1]) {
2060         const config_plugin_value_t *cpv = p->cvlist + p->cvlist->v.u2[0];
2061         if (-1 != cpv->k_id)
2062             mod_mbedtls_merge_config(&p->defaults, cpv);
2063     }
2064 
2065   #ifndef MBEDTLS_ERROR_C
2066     log_error(srv->errh, __FILE__, __LINE__,
2067               "MTLS: No error strings available. "
2068               "Compile mbedtls with MBEDTLS_ERROR_C to enable.");
2069   #endif
2070 
2071     return mod_mbedtls_set_defaults_sockets(srv, p);
2072 }
2073 
2074 
2075     /* local_send_buffer is a static buffer of size (LOCAL_SEND_BUFSIZE)
2076      *
2077      * buffer is allocated once, is NOT realloced (note: not thread-safe)
2078      * */
2079 
2080             /* copy small mem chunks into single large buffer
2081              * before mbedtls_ssl_write() to reduce number times
2082              * write() called underneath mbedtls_ssl_write() and
2083              * potentially reduce number of packets generated if TCP_NODELAY */
2084 
2085 
2086 __attribute_cold__
2087 static int
2088 mod_mbedtls_ssl_write_err(connection *con, handler_ctx *hctx, int wr, size_t wr_len)
2089 {
2090     switch (wr) {
2091       case MBEDTLS_ERR_SSL_WANT_READ:
2092         con->is_readable = -1;
2093         break; /* try again later */
2094       case MBEDTLS_ERR_SSL_WANT_WRITE:
2095         con->is_writable = -1;
2096         break; /* try again later */
2097       case MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS:
2098       case MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS:
2099         break; /* try again later */
2100       case MBEDTLS_ERR_NET_CONN_RESET:
2101         if (hctx->conf.ssl_log_noise)
2102             elog(hctx->r->conf.errh, __FILE__, __LINE__, wr,
2103                  "peer closed connection");
2104         return -1;
2105       default:
2106         elog(hctx->r->conf.errh, __FILE__, __LINE__, wr, __func__);
2107         return -1;
2108     }
2109 
2110   #if MBEDTLS_VERSION_NUMBER < 0x03000000 /* mbedtls 3.00.0 */
2111     if (0 != hctx->ssl.out_left)  /* partial write; save attempted wr_len */
2112   #endif
2113         hctx->pending_write = wr_len;
2114 
2115     return 0; /* try again later */
2116 }
2117 
2118 
2119 static int
2120 mod_mbedtls_close_notify(handler_ctx *hctx);
2121 
2122 
2123 static int
2124 connection_write_cq_ssl (connection * const con, chunkqueue * const cq, off_t max_bytes)
2125 {
2126     handler_ctx * const hctx = con->plugin_ctx[plugin_data_singleton->id];
2127     mbedtls_ssl_context * const ssl = &hctx->ssl;
2128 
2129     if (hctx->pending_write) {
2130         int wr = (int)hctx->pending_write;
2131       #if MBEDTLS_VERSION_NUMBER < 0x03000000 /* mbedtls 3.00.0 */
2132         if (0 != ssl->out_left)
2133       #endif
2134         {
2135             /*(would prefer mbedtls_ssl_flush_output() from ssl_internal.h)*/
2136             size_t data_len = hctx->pending_write;
2137             wr = mbedtls_ssl_write(ssl, NULL, data_len);
2138             if (wr <= 0)
2139                 return mod_mbedtls_ssl_write_err(con, hctx, wr, data_len);
2140             max_bytes -= wr;
2141         }
2142         hctx->pending_write = 0;
2143         chunkqueue_mark_written(cq, wr);
2144     }
2145 
2146     if (__builtin_expect( (0 != hctx->close_notify), 0))
2147         return mod_mbedtls_close_notify(hctx);
2148 
2149     const int lim = mbedtls_ssl_get_max_out_record_payload(ssl);
2150     if (lim < 0) return mod_mbedtls_ssl_write_err(con, hctx, lim, 0);
2151 
2152     log_error_st * const errh = hctx->errh;
2153     while (max_bytes > 0 && !chunkqueue_is_empty(cq)) {
2154         char *data = local_send_buffer;
2155         uint32_t data_len = LOCAL_SEND_BUFSIZE < max_bytes
2156           ? LOCAL_SEND_BUFSIZE
2157           : (uint32_t)max_bytes;
2158         int wr;
2159 
2160         if (0 != chunkqueue_peek_data(cq, &data, &data_len, errh)) return -1;
2161         if (__builtin_expect( (0 == data_len), 0)) {
2162             chunkqueue_remove_finished_chunks(cq);
2163             continue;
2164         }
2165 
2166         /* mbedtls_ssl_write() copies the data, up to max record size, but if
2167          * (temporarily) unable to write the entire record, it is documented
2168          * that the caller must call mbedtls_ssl_write() again, later, with the
2169          * same arguments.  This appears to be because mbedtls_ssl_context does
2170          * not keep track of the original size of the caller data that
2171          * mbedtls_ssl_write() attempted to write (and may have transformed to
2172          * a different size).  The func may return MBEDTLS_ERR_SSL_WANT_READ or
2173          * MBEDTLS_ERR_SSL_WANT_WRITE to indicate that the caller should wait
2174          * for the fd to be readable/writable before calling the func again,
2175          * which is why those (temporary) errors are returned instead of telling
2176          * the caller that the data was successfully copied.  When the record is
2177          * written successfully, the return value is supposed to indicate the
2178          * number of (originally submitted) bytes written, but since that value
2179          * is unknown (not saved), the caller's len parameter is reflected back,
2180          * which is why the caller must call the func again with the same args.
2181          * Additionally, to be accurate, the size must fit into a record which
2182          * is why we restrict ourselves to sending max out record payload each
2183          * iteration.
2184          */
2185 
2186         int wr_total = 0;
2187         do {
2188             size_t wr_len = (data_len > (size_t)lim) ? (size_t)lim : data_len;
2189             wr = mbedtls_ssl_write(ssl, (const unsigned char *)data, wr_len);
2190             if (wr <= 0) {
2191                 if (wr_total) chunkqueue_mark_written(cq, wr_total);
2192                 return mod_mbedtls_ssl_write_err(con, hctx, wr, wr_len);
2193             }
2194             wr_total += wr;
2195             data += wr;
2196         } while ((data_len -= wr));
2197         chunkqueue_mark_written(cq, wr_total);
2198         max_bytes -= wr_total;
2199     }
2200 
2201     return 0;
2202 }
2203 
2204 
2205 #if MBEDTLS_VERSION_NUMBER >= 0x03020000 /* mbedtls 3.02.0 */
2206 #elif MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.00.0 */
2207 #define handshake_state(ssl) (ssl)->MBEDTLS_PRIVATE(state)
2208 #else /* MBEDTLS_VERSION_NUMBER < 0x03000000 */ /* mbedtls 3.00.0 */
2209 #define handshake_state(ssl) (ssl)->state
2210 #ifdef MBEDTLS_SSL_SERVER_NAME_INDICATION
2211 #ifdef MBEDTLS_SSL_ALPN
2212 static int ssl_parse_client_hello( mbedtls_ssl_context *ssl, handler_ctx *hctx );
2213 #endif
2214 #endif
2215 #endif /* MBEDTLS_VERSION_NUMBER < 0x03000000 */ /* mbedtls 3.00.0 */
2216 
2217 
2218 static int
2219 mod_mbedtls_ssl_handshake (handler_ctx *hctx)
2220 {
2221     int rc = 0;
2222 
2223  #if MBEDTLS_VERSION_NUMBER >= 0x03020000 /* mbedtls 3.02.0 */
2224 
2225     rc = mbedtls_ssl_handshake(&hctx->ssl);
2226 
2227  #else
2228 
2229     /* overwrite callback with hctx each time we enter here, before handshake
2230      * (Some callbacks are on mbedtls_ssl_config, not mbedtls_ssl_context)
2231      * (Not thread-safe if config (mbedtls_ssl_config *ssl_ctx) is shared)
2232      * (XXX: there is probably a better way to do this...) */
2233   #ifdef MBEDTLS_SSL_SERVER_NAME_INDICATION
2234     mbedtls_ssl_conf_sni(hctx->ssl_ctx, mod_mbedtls_SNI, hctx);
2235   #endif
2236 
2237     if (handshake_state(&hctx->ssl) < MBEDTLS_SSL_SERVER_HELLO) {
2238         while (handshake_state(&hctx->ssl) != MBEDTLS_SSL_SERVER_HELLO
2239             && handshake_state(&hctx->ssl) != MBEDTLS_SSL_HANDSHAKE_OVER) {
2240           /* disable in mbedtls 3.0+ until alternative callbacks are available
2241            * https://github.com/ARMmbed/mbedtls/issues/5430 */
2242           #if MBEDTLS_VERSION_NUMBER < 0x03000000 /* mbedtls 3.00.0 */
2243           #ifdef MBEDTLS_SSL_SERVER_NAME_INDICATION
2244           #ifdef MBEDTLS_SSL_ALPN
2245             /* parse client_hello for ALPN extension prior to mbedtls handshake
2246              * in order to perform certificate selection in mod_mbedtls_SNI() */
2247             if (hctx->conf.ssl_acme_tls_1) {
2248                 rc = ssl_parse_client_hello(&hctx->ssl, hctx);
2249                 if (0 != rc) break;
2250             }
2251           #endif
2252           #endif
2253           #endif /* MBEDTLS_VERSION_NUMBER < 0x03000000 */ /* mbedtls 3.00.0 */
2254             rc = mbedtls_ssl_handshake_step(&hctx->ssl);
2255             if (0 != rc) break;
2256         }
2257         if (0 == rc
2258             && handshake_state(&hctx->ssl) == MBEDTLS_SSL_SERVER_HELLO) {
2259           #ifdef MBEDTLS_SSL_ALPN
2260             const char *alpn = mbedtls_ssl_get_alpn_protocol(&hctx->ssl);
2261             if (NULL != alpn)
2262                 rc = mod_mbedtls_alpn_selected(hctx, alpn);
2263           #endif
2264         }
2265     }
2266 
2267     if (0 == rc && hctx->conf.ssl_verifyclient  /*(after SNI and ALPN)*/
2268         && handshake_state(&hctx->ssl) >= MBEDTLS_SSL_SERVER_HELLO
2269         && handshake_state(&hctx->ssl) <= MBEDTLS_SSL_SERVER_HELLO_DONE
2270         && hctx->alpn != MOD_MBEDTLS_ALPN_ACME_TLS_1) { /*(not "acme-tls/1")*/
2271         int mode = (hctx->conf.ssl_verifyclient_enforce)
2272           ? MBEDTLS_SSL_VERIFY_REQUIRED
2273           : MBEDTLS_SSL_VERIFY_OPTIONAL;
2274         mbedtls_ssl_set_hs_authmode(&hctx->ssl, mode);
2275         while (handshake_state(&hctx->ssl) != MBEDTLS_SSL_CERTIFICATE_REQUEST
2276             && handshake_state(&hctx->ssl) != MBEDTLS_SSL_HANDSHAKE_OVER) {
2277             rc = mbedtls_ssl_handshake_step(&hctx->ssl);
2278             if (0 != rc) break;
2279         }
2280         if (0 == rc
2281             && handshake_state(&hctx->ssl) == MBEDTLS_SSL_CERTIFICATE_REQUEST) {
2282             rc = mod_mbedtls_conf_verify(hctx);
2283             if (0 == rc)
2284                 rc = mbedtls_ssl_handshake_step(&hctx->ssl);
2285             /* reconfigure CA trust chain after sending client certificate
2286              * request (if ssl_ca_dn_file is set), before client certificate
2287              * verification (MBEDTLS_SSL_CERTIFICATE_VERIFY) */
2288             if (0 == rc && hctx->conf.ssl_ca_dn_file
2289                 && handshake_state(&hctx->ssl)==MBEDTLS_SSL_SERVER_HELLO_DONE) {
2290                 mbedtls_ssl_context * const ssl = &hctx->ssl;
2291                 mbedtls_x509_crt *ca_certs = hctx->conf.ssl_ca_file;
2292                 mbedtls_x509_crl *ca_crl = hctx->conf.ssl_ca_crl_file;
2293                 mbedtls_ssl_set_hs_ca_chain(ssl, ca_certs, ca_crl);
2294             }
2295         }
2296     }
2297 
2298     if (0 == rc && handshake_state(&hctx->ssl) != MBEDTLS_SSL_HANDSHAKE_OVER) {
2299         rc = mbedtls_ssl_handshake(&hctx->ssl);
2300     }
2301 
2302  #endif
2303 
2304     switch (rc) {
2305       case 0:
2306         hctx->handshake_done = 1;
2307        #ifdef MBEDTLS_SSL_ALPN
2308         if (hctx->alpn == MOD_MBEDTLS_ALPN_H2) {
2309             if (0 != mod_mbedtls_alpn_h2_policy(hctx))
2310                 return -1;
2311         }
2312         else if (hctx->alpn == MOD_MBEDTLS_ALPN_ACME_TLS_1) {
2313             /* Once TLS handshake is complete, return -1 to result in
2314              * CON_STATE_ERROR so that socket connection is quickly closed */
2315             return -1;
2316         }
2317         hctx->alpn = 0;
2318        #endif
2319         return 1; /* continue reading */
2320       case MBEDTLS_ERR_SSL_WANT_WRITE:
2321         hctx->con->is_writable = -1;
2322         __attribute_fallthrough__
2323       case MBEDTLS_ERR_SSL_WANT_READ:
2324         hctx->con->is_readable = 0;
2325         return 0;
2326       case MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS:
2327       case MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS:
2328         return 0;
2329       case MBEDTLS_ERR_SSL_CLIENT_RECONNECT:
2330         return -1;
2331       case MBEDTLS_ERR_NET_CONN_RESET:
2332       case MBEDTLS_ERR_SSL_CONN_EOF:
2333         if (!hctx->conf.ssl_log_noise) return -1;
2334         __attribute_fallthrough__
2335       default:
2336         elog(hctx->r->conf.errh, __FILE__, __LINE__, rc, __func__);
2337         return -1;
2338     }
2339 }
2340 
2341 
2342 static int
2343 connection_read_cq_ssl (connection * const con, chunkqueue * const cq, off_t max_bytes)
2344 {
2345     handler_ctx * const hctx = con->plugin_ctx[plugin_data_singleton->id];
2346     int len;
2347     char *mem = NULL;
2348     size_t mem_len = 0;
2349 
2350     UNUSED(max_bytes);
2351 
2352     if (__builtin_expect( (0 != hctx->close_notify), 0))
2353         return mod_mbedtls_close_notify(hctx);
2354 
2355     if (!hctx->handshake_done) {
2356         int rc = mod_mbedtls_ssl_handshake(hctx);
2357         if (1 != rc) return rc; /* !hctx->handshake_done; not done, or error */
2358     }
2359 
2360     do {
2361         len = mbedtls_ssl_get_bytes_avail(&hctx->ssl);
2362         mem_len = len < 2048 ? 2048 : (size_t)len;
2363         chunk * const ckpt = cq->last;
2364         mem = chunkqueue_get_memory(cq, &mem_len);
2365 
2366         len = mbedtls_ssl_read(&hctx->ssl, (unsigned char *)mem, mem_len);
2367         chunkqueue_use_memory(cq, ckpt, len > 0 ? len : 0);
2368     } while (len > 0
2369              && mbedtls_ssl_check_pending(&hctx->ssl));
2370 
2371     if (len < 0) {
2372         int rc = len;
2373         request_st * const r = &con->request;
2374         switch (rc) {
2375           case MBEDTLS_ERR_SSL_WANT_WRITE:
2376             con->is_writable = -1;
2377             __attribute_fallthrough__
2378           case MBEDTLS_ERR_SSL_WANT_READ:
2379             con->is_readable = 0;
2380             return 0;
2381           case MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY:
2382           case MBEDTLS_ERR_SSL_CONN_EOF:
2383             /* XXX: future: save state to avoid future read after response? */
2384             con->is_readable = 0;
2385             r->keep_alive = 0;
2386             return -2;
2387           case MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS:
2388           case MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS:
2389             return 0;
2390           case MBEDTLS_ERR_SSL_CLIENT_RECONNECT:
2391             return -1;
2392           case MBEDTLS_ERR_NET_CONN_RESET:
2393             if (!hctx->conf.ssl_log_noise) return -1;
2394             __attribute_fallthrough__
2395           default:
2396             elog(hctx->errh, __FILE__, __LINE__, rc, "Reading mbedtls");
2397             return -1;
2398         }
2399     } else if (len == 0) {
2400         con->is_readable = 0;
2401         /* the other end closed the connection -> KEEP-ALIVE */
2402 
2403         return -2;
2404     } else {
2405         return 0;
2406     }
2407 }
2408 
2409 
2410 static void
2411 mod_mbedtls_debug_cb(void *ctx, int level,
2412                      const char *file, int line,
2413                      const char *str)
2414 {
2415     if (level < (intptr_t)ctx) /* level */
2416         log_error(plugin_data_singleton->srv->errh,file,line,"MTLS: %s",str);
2417 }
2418 
2419 
2420 CONNECTION_FUNC(mod_mbedtls_handle_con_accept)
2421 {
2422     const server_socket *srv_sock = con->srv_socket;
2423     if (!srv_sock->is_ssl) return HANDLER_GO_ON;
2424 
2425     plugin_data *p = p_d;
2426     handler_ctx * const hctx = handler_ctx_init();
2427     request_st * const r = &con->request;
2428     hctx->r = r;
2429     hctx->con = con;
2430     hctx->tmp_buf = con->srv->tmp_buf;
2431     hctx->errh = r->conf.errh;
2432     con->plugin_ctx[p->id] = hctx;
2433     buffer_blank(&r->uri.authority);
2434 
2435     hctx->ssl_ctx = p->ssl_ctxs[srv_sock->sidx].ssl_ctx;
2436     mbedtls_ssl_init(&hctx->ssl);
2437     int rc = mbedtls_ssl_setup(&hctx->ssl, hctx->ssl_ctx);
2438     if (0 == rc) {
2439         con->network_read = connection_read_cq_ssl;
2440         con->network_write = connection_write_cq_ssl;
2441         con->proto_default_port = 443; /* "https" */
2442         mod_mbedtls_patch_config(r, &hctx->conf);
2443     }
2444     else {
2445         elog(r->conf.errh, __FILE__, __LINE__, rc, "ssl_setup() failed");
2446         return HANDLER_ERROR;
2447     }
2448 
2449   #if MBEDTLS_VERSION_NUMBER >= 0x03020000 /* mbedtls 3.02.0 */
2450     mbedtls_ssl_set_user_data_p(&hctx->ssl, hctx);
2451   #endif
2452 
2453     mbedtls_ssl_set_bio(&hctx->ssl, (mbedtls_net_context *)&con->fd,
2454                         mbedtls_net_send, mbedtls_net_recv, NULL);
2455 
2456     /* (mbedtls_ssl_config *) is shared across multiple connections, which may
2457      * overlap, and so this debug setting is not reset upon connection close.
2458      * Once enabled, debug hook will remain so for this mbedtls_ssl_config */
2459     if (hctx->conf.ssl_log_noise) {/* volume level for debug message callback */
2460       #if MBEDTLS_VERSION_NUMBER >= 0x02000000 /* mbedtls 2.0.0 */
2461         mbedtls_debug_set_threshold(hctx->conf.ssl_log_noise);
2462       #endif
2463         mbedtls_ssl_conf_dbg(hctx->ssl_ctx, mod_mbedtls_debug_cb,
2464                              (void *)(intptr_t)hctx->conf.ssl_log_noise);
2465     }
2466 
2467     /* (mbedtls_ssl_config *) is shared across multiple connections, which may
2468      * overlap, and so renegotiation setting is not reset upon connection close.
2469      * Once enabled, renegotiation will remain so for this mbedtls_ssl_config.
2470      * mbedtls defaults to disable client renegotiation
2471      *   (MBEDTLS_LEGACY_SSL_RENEGOTIATION_DISABLED)
2472      * and it is recommended to leave it disabled (lighttpd mbedtls default) */
2473   #ifdef MBEDTLS_LEGACY_SSL_RENEGOTIATION_ENABLED
2474     if (!hctx->conf.ssl_disable_client_renegotiation)
2475         mbedtls_legacy_ssl_conf_renegotiation(hctx->ssl_ctx,
2476                                       MBEDTLS_LEGACY_SSL_RENEGOTIATION_ENABLED);
2477   #endif
2478 
2479     return HANDLER_GO_ON;
2480 }
2481 
2482 
2483 static void
2484 mod_mbedtls_detach(handler_ctx *hctx)
2485 {
2486     /* step aside from further SSL processing
2487      * (used after handle_connection_shut_wr hook) */
2488     /* future: might restore prior network_read and network_write fn ptrs */
2489     hctx->con->is_ssl_sock = 0;
2490     /* if called after handle_connection_shut_wr hook, shutdown SHUT_WR */
2491     if (-1 == hctx->close_notify) shutdown(hctx->con->fd, SHUT_WR);
2492     hctx->close_notify = 1;
2493 }
2494 
2495 
2496 CONNECTION_FUNC(mod_mbedtls_handle_con_shut_wr)
2497 {
2498     plugin_data *p = p_d;
2499     handler_ctx *hctx = con->plugin_ctx[p->id];
2500     if (NULL == hctx) return HANDLER_GO_ON;
2501 
2502     hctx->close_notify = -2;
2503     if (hctx->handshake_done) {
2504         mod_mbedtls_close_notify(hctx);
2505     }
2506     else {
2507         mod_mbedtls_detach(hctx);
2508     }
2509 
2510     return HANDLER_GO_ON;
2511 }
2512 
2513 
2514 static int
2515 mod_mbedtls_close_notify (handler_ctx *hctx)
2516 {
2517     if (1 == hctx->close_notify) return -2;
2518 
2519     int rc = mbedtls_ssl_close_notify(&hctx->ssl);
2520     switch (rc) {
2521       case 0:
2522         mod_mbedtls_detach(hctx);
2523         return -2;
2524       case MBEDTLS_ERR_SSL_WANT_READ:
2525       case MBEDTLS_ERR_SSL_WANT_WRITE:
2526         return 0;
2527       default:
2528         elog(hctx->r->conf.errh, __FILE__, __LINE__, rc,
2529              "mbedtls_ssl_close_notify()");
2530         __attribute_fallthrough__
2531       case MBEDTLS_ERR_NET_CONN_RESET:
2532         mbedtls_ssl_session_reset(&hctx->ssl);
2533         mod_mbedtls_detach(hctx);
2534         return -1;
2535     }
2536 }
2537 
2538 
2539 CONNECTION_FUNC(mod_mbedtls_handle_con_close)
2540 {
2541     plugin_data *p = p_d;
2542     handler_ctx *hctx = con->plugin_ctx[p->id];
2543     if (NULL != hctx) {
2544         con->plugin_ctx[p->id] = NULL;
2545         if (1 != hctx->close_notify)
2546             mod_mbedtls_close_notify(hctx); /*(one final try)*/
2547         handler_ctx_free(hctx);
2548     }
2549 
2550     return HANDLER_GO_ON;
2551 }
2552 
2553 
2554 #if defined(MBEDTLS_PEM_WRITE_C)
2555 __attribute_noinline__
2556 static void
2557 https_add_ssl_client_cert (request_st * const r, const mbedtls_x509_crt * const peer)
2558 {
2559     #define PEM_BEGIN_CRT "-----BEGIN CERTIFICATE-----\n"
2560     #define PEM_END_CRT   "-----END CERTIFICATE-----\n"
2561     unsigned char buf[4096];
2562     size_t olen;
2563     if (0 == mbedtls_pem_write_buffer(PEM_BEGIN_CRT, PEM_END_CRT,
2564                                       peer->raw.p, peer->raw.len,
2565                                       buf, sizeof(buf), &olen))
2566         http_header_env_set(r,
2567                             CONST_STR_LEN("SSL_CLIENT_CERT"),
2568                             (char *)buf, olen);
2569 }
2570 #endif
2571 
2572 
2573 static void
2574 https_add_ssl_client_subject (request_st * const r, const mbedtls_x509_name *name)
2575 {
2576     /* add components of client Subject DN */
2577     /* code block is similar to mbedtls_x509_dn_gets() */
2578     /* code block specialized for creating env vars of Subject DN components
2579      * and splits multi-valued RDNs into separate env vars for attribute=value*/
2580     size_t n = 0;
2581     const size_t prelen = sizeof("SSL_CLIENT_S_DN_")-1;
2582     char key[64] = "SSL_CLIENT_S_DN_";
2583     char buf[512]; /* MBEDTLS_X509_MAX_DN_NAME_SIZE is (256) */
2584 
2585     for (; name != NULL; name = name->next) {
2586         if (!name->oid.p)
2587             continue;
2588         const char *short_name = NULL;
2589         if (0 != mbedtls_oid_get_attr_short_name(&name->oid, &short_name))
2590             continue;
2591         const size_t len = strlen(short_name);
2592         if (prelen+len >= sizeof(key)) continue;
2593         memcpy(key+prelen, short_name, len); /*(not '\0'-terminated)*/
2594 
2595         if (n+2+len+1+name->val.len > sizeof(buf)) continue;
2596         buf[n++] = ','; /*(", " at beginning is skipped outside loop below)*/
2597         buf[n++] = ' ';
2598         memcpy(buf+n, short_name, len);
2599         n += len;
2600         buf[n++] = '=';
2601 
2602         for (size_t i = 0; i < name->val.len; ++i) {
2603             unsigned char c = name->val.p[i];
2604             buf[n+i] = (c >= 32 && c != 127) ? c : '?';
2605         }
2606 
2607         http_header_env_set(r, key, prelen+len, buf+n, name->val.len);
2608         n += name->val.len;
2609     }
2610 
2611     /* mbedtls_x509_dn_gets() is not used to construct DN because that func does
2612      * not support non-ASCII UTF-8.  This func allows non-ASCII UTF-8 but does
2613      * not check for need to backslash-encode special chars.  This func
2614      * *assumes* a trusted and validated cert which does contain any chars which
2615      * need to be backslash-encoded in the stringified DN, even if such chars
2616      * are allowed in ASN.1 DN.  Above, CTLs are encoded as '?' above, even
2617      * though some are allowed if backslash-encoded.  Multi-valued RDNs are not
2618      * combined with '+' above, as name->next_merged is private in mbedtls 3.0.0
2619      */
2620     if (n > 2)
2621         http_header_env_set(r, CONST_STR_LEN("SSL_CLIENT_S_DN"), buf+2, n-2);
2622 }
2623 
2624 
2625 __attribute_cold__
2626 static void
2627 https_add_ssl_client_verify_err (buffer * const b, uint32_t status)
2628 {
2629   #ifndef MBEDTLS_X509_REMOVE_INFO
2630     /* get failure string and translate newline to ':', removing last one */
2631     char buf[512];
2632     int n = mbedtls_x509_crt_verify_info(buf, sizeof(buf), "", status);
2633     if (n > 0) {
2634         for (char *nl = buf; NULL != (nl = strchr(nl, '\n')); ++nl)
2635             nl[0] = ('\0' == nl[1] ? (--n, '\0') : ':');
2636         buffer_append_string_len(b, buf, n);
2637     }
2638   #else
2639     UNUSED(b);
2640     UNUSED(status);
2641   #endif
2642 }
2643 
2644 
2645 __attribute_noinline__
2646 static void
2647 https_add_ssl_client_entries (request_st * const r, handler_ctx * const hctx)
2648 {
2649     /* Note: starting with mbedtls-2.17.0, peer cert is not available here if
2650      * MBEDTLS_SSL_KEEP_PEER_CERTIFICATE *is not* defined at compile time,
2651      * though default behavior is to have it defined.  However, since earlier
2652      * versions do keep the cert, but not set this define, attempt to retrieve
2653      * the peer cert and check for NULL before using it. */
2654     const mbedtls_x509_crt *crt = mbedtls_ssl_get_peer_cert(&hctx->ssl);
2655     buffer *vb = http_header_env_set_ptr(r, CONST_STR_LEN("SSL_CLIENT_VERIFY"));
2656 
2657     uint32_t rc = (NULL != crt)
2658       ? mbedtls_ssl_get_verify_result(&hctx->ssl)
2659       : 0xFFFFFFFF;
2660     if (0xFFFFFFFF == rc) { /*(e.g. no cert, or verify result not available)*/
2661         buffer_copy_string_len(vb, CONST_STR_LEN("NONE"));
2662         return;
2663     }
2664     else if (0 != rc) {
2665         buffer_copy_string_len(vb, CONST_STR_LEN("FAILED:"));
2666         https_add_ssl_client_verify_err(vb, rc);
2667         return;
2668     }
2669     else {
2670         buffer_copy_string_len(vb, CONST_STR_LEN("SUCCESS"));
2671     }
2672 
2673     https_add_ssl_client_subject(r, &crt->subject);
2674 
2675     /* mbedtls_x509_serial_gets() (inefficiently) formats to hex separated by
2676      * colons, but would differ from behavior of other lighttpd TLS modules */
2677     size_t i = 0; /* skip leading 0's per Distinguished Encoding Rules (DER) */
2678     while (i < crt->serial.len && crt->serial.p[i] == 0) ++i;
2679     if (i == crt->serial.len) --i;
2680     buffer_append_string_encoded_hex_uc(
2681       http_header_env_set_ptr(r, CONST_STR_LEN("SSL_CLIENT_M_SERIAL")),
2682       (char *)crt->serial.p+i, crt->serial.len-i);
2683 
2684     if (hctx->conf.ssl_verifyclient_username) {
2685         /* pick one of the exported values as "REMOTE_USER", for example
2686          *   ssl.verifyclient.username = "SSL_CLIENT_S_DN_UID"
2687          * or
2688          *   ssl.verifyclient.username = "SSL_CLIENT_S_DN_emailAddress"
2689          */
2690         const buffer *varname = hctx->conf.ssl_verifyclient_username;
2691         vb = http_header_env_get(r, BUF_PTR_LEN(varname));
2692         if (vb) { /* same as mod_auth_api.c:http_auth_setenv() */
2693             http_header_env_set(r,
2694                                 CONST_STR_LEN("REMOTE_USER"),
2695                                 BUF_PTR_LEN(vb));
2696             http_header_env_set(r,
2697                                 CONST_STR_LEN("AUTH_TYPE"),
2698                                 CONST_STR_LEN("SSL_CLIENT_VERIFY"));
2699         }
2700     }
2701 
2702   #if defined(MBEDTLS_PEM_WRITE_C)
2703     /* if (NULL != crt) (e.g. not PSK-based ciphersuite) */
2704     if (hctx->conf.ssl_verifyclient_export_cert)
2705         https_add_ssl_client_cert(r, crt);
2706   #endif
2707 }
2708 
2709 
2710 #if MBEDTLS_VERSION_NUMBER < 0x03020000 /* mbedtls 3.02.0 */
2711 #define mbedtls_ssl_get_ciphersuite_id_from_ssl(ssl) \
2712         (ssl)->MBEDTLS_PRIVATE(session)->MBEDTLS_PRIVATE(ciphersuite)
2713 #define mbedtls_ssl_ciphersuite_get_name(info) \
2714         (info)->MBEDTLS_PRIVATE(name)
2715 #endif
2716 
2717 static void
2718 http_cgi_ssl_env (request_st * const r, handler_ctx * const hctx)
2719 {
2720     const char *s;
2721 
2722     s = mbedtls_ssl_get_version(&hctx->ssl);
2723     http_header_env_set(r, CONST_STR_LEN("SSL_PROTOCOL"), s, strlen(s));
2724 
2725     const int ciphersuite_id =
2726       mbedtls_ssl_get_ciphersuite_id_from_ssl(&hctx->ssl);
2727     const mbedtls_ssl_ciphersuite_t * const ciphersuite_info =
2728       mbedtls_ssl_ciphersuite_from_id(ciphersuite_id);
2729     if (__builtin_expect( (NULL == ciphersuite_info), 0)) return;
2730 
2731     s = mbedtls_ssl_ciphersuite_get_name(ciphersuite_info);
2732     http_header_env_set(r, CONST_STR_LEN("SSL_CIPHER"), s, strlen(s));
2733 
2734     {
2735         /* SSL_CIPHER_ALGKEYSIZE - Number of cipher bits (possible) */
2736         /* SSL_CIPHER_USEKEYSIZE - Number of cipher bits (actually used) */
2737       #if MBEDTLS_VERSION_NUMBER >= 0x03020000 /* mbedtls 3.02.0 */
2738         size_t algkeysize =
2739           mbedtls_ssl_ciphersuite_get_cipher_key_bitlen(ciphersuite_info);
2740         unsigned int usekeysize = algkeysize; /*(equivalent in modern ciphers)*/
2741       #elif MBEDTLS_VERSION_NUMBER >= 0x03000000 /* mbedtls 3.00.0 */
2742        #ifdef MBEDTLS_CIPHER_C
2743         /*(messy transition; ssl->transform is hidden in ssl_internal.h)*/
2744         const mbedtls_cipher_info_t * const cipher_info =
2745           mbedtls_cipher_info_from_type(
2746             ciphersuite_info->MBEDTLS_PRIVATE(cipher));
2747         if (__builtin_expect( (NULL == cipher_info), 0)) return;
2748         unsigned int algkeysize = cipher_info->MBEDTLS_PRIVATE(key_bitlen);
2749        #else
2750         if (1) return;
2751        #endif
2752         unsigned int usekeysize = algkeysize; /*(equivalent in modern ciphers)*/
2753       #else
2754         /* XXX: is usekeysize correct? XXX: reaching into ssl_internal.h here */
2755         unsigned int usekeysize =
2756           hctx->ssl.transform->cipher_ctx_enc.key_bitlen;
2757        #ifdef MBEDTLS_CIPHER_C
2758         unsigned int algkeysize =
2759           hctx->ssl.transform->cipher_ctx_enc.cipher_info->key_bitlen;
2760        #else
2761         unsigned int algkeysize = usekeysize;
2762        #endif
2763       #endif
2764         char buf[LI_ITOSTRING_LENGTH];
2765         http_header_env_set(r, CONST_STR_LEN("SSL_CIPHER_ALGKEYSIZE"),
2766                             buf, li_utostrn(buf, sizeof(buf), algkeysize));
2767         http_header_env_set(r, CONST_STR_LEN("SSL_CIPHER_USEKEYSIZE"),
2768                             buf, li_utostrn(buf, sizeof(buf), usekeysize));
2769     }
2770 }
2771 
2772 
2773 REQUEST_FUNC(mod_mbedtls_handle_request_env)
2774 {
2775     plugin_data *p = p_d;
2776     /* simple flag for request_env_patched */
2777     if (r->plugin_ctx[p->id]) return HANDLER_GO_ON;
2778     handler_ctx *hctx = r->con->plugin_ctx[p->id];
2779     if (NULL == hctx) return HANDLER_GO_ON;
2780     r->plugin_ctx[p->id] = (void *)(uintptr_t)1u;
2781 
2782     http_cgi_ssl_env(r, hctx);
2783     if (hctx->conf.ssl_verifyclient) {
2784         https_add_ssl_client_entries(r, hctx);
2785     }
2786 
2787     return HANDLER_GO_ON;
2788 }
2789 
2790 
2791 REQUEST_FUNC(mod_mbedtls_handle_uri_raw)
2792 {
2793     /* mod_mbedtls must be loaded prior to mod_auth
2794      * if mod_mbedtls is configured to set REMOTE_USER based on client cert */
2795     /* mod_mbedtls must be loaded after mod_extforward
2796      * if mod_mbedtls config is based on lighttpd.conf remote IP conditional
2797      * using remote IP address set by mod_extforward, *unless* PROXY protocol
2798      * is enabled with extforward.hap-PROXY = "enable", in which case the
2799      * reverse is true: mod_extforward must be loaded after mod_mbedtls */
2800     plugin_data *p = p_d;
2801     handler_ctx *hctx = r->con->plugin_ctx[p->id];
2802     if (NULL == hctx) return HANDLER_GO_ON;
2803 
2804     mod_mbedtls_patch_config(r, &hctx->conf);
2805     if (hctx->conf.ssl_verifyclient) {
2806         mod_mbedtls_handle_request_env(r, p);
2807     }
2808 
2809     return HANDLER_GO_ON;
2810 }
2811 
2812 
2813 REQUEST_FUNC(mod_mbedtls_handle_request_reset)
2814 {
2815     plugin_data *p = p_d;
2816     r->plugin_ctx[p->id] = NULL; /* simple flag for request_env_patched */
2817     return HANDLER_GO_ON;
2818 }
2819 
2820 
2821 TRIGGER_FUNC(mod_mbedtls_handle_trigger) {
2822     plugin_data * const p = p_d;
2823     const unix_time64_t cur_ts = log_epoch_secs;
2824     if (cur_ts & 0x3f) return HANDLER_GO_ON; /*(continue once each 64 sec)*/
2825     UNUSED(srv);
2826     UNUSED(p);
2827 
2828   #ifdef MBEDTLS_SSL_SESSION_TICKETS
2829     mod_mbedtls_session_ticket_key_check(p, cur_ts);
2830   #endif
2831 
2832     return HANDLER_GO_ON;
2833 }
2834 
2835 
2836 int mod_mbedtls_plugin_init (plugin *p);
2837 int mod_mbedtls_plugin_init (plugin *p)
2838 {
2839     p->version      = LIGHTTPD_VERSION_ID;
2840     p->name         = "mbedtls";
2841     p->init         = mod_mbedtls_init;
2842     p->cleanup      = mod_mbedtls_free;
2843     p->priv_defaults= mod_mbedtls_set_defaults;
2844 
2845     p->handle_connection_accept  = mod_mbedtls_handle_con_accept;
2846     p->handle_connection_shut_wr = mod_mbedtls_handle_con_shut_wr;
2847     p->handle_connection_close   = mod_mbedtls_handle_con_close;
2848     p->handle_uri_raw            = mod_mbedtls_handle_uri_raw;
2849     p->handle_request_env        = mod_mbedtls_handle_request_env;
2850     p->handle_request_reset      = mod_mbedtls_handle_request_reset;
2851     p->handle_trigger            = mod_mbedtls_handle_trigger;
2852 
2853     return 0;
2854 }
2855 
2856 
2857 /* cipher suites (taken from mbedtls/ssl_ciphersuites.[ch]) */
2858 
2859 static const int suite_CHACHAPOLY_ephemeral[] = {
2860     /* Chacha-Poly ephemeral suites */
2861     MBEDTLS_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
2862     MBEDTLS_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
2863     MBEDTLS_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256
2864 };
2865 
2866 static const int suite_AES_256_ephemeral[] = {
2867     /* All AES-256 ephemeral suites */
2868     MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
2869     MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
2870     MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384,
2871     MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM,
2872     MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM,
2873     MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,
2874     MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,
2875     MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,
2876     MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
2877     MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
2878     MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
2879     MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8,
2880     MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM_8
2881 };
2882 
2883 static const int suite_CAMELLIA_256_ephemeral[] = {
2884     /* All CAMELLIA-256 ephemeral suites */
2885     MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384,
2886     MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384,
2887     MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384,
2888     MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384,
2889     MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384,
2890     MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256,
2891     MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA
2892 };
2893 
2894 static const int suite_ARIA_256_ephemeral[] = {
2895     /* All ARIA-256 ephemeral suites */
2896     MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384,
2897     MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384,
2898     MBEDTLS_TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384,
2899     MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384,
2900     MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384,
2901     MBEDTLS_TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384
2902 };
2903 
2904 static const int suite_AES_128_ephemeral[] = {
2905     /* All AES-128 ephemeral suites */
2906     MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
2907     MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
2908     MBEDTLS_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
2909     MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM,
2910     MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM,
2911     MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
2912     MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
2913     MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,
2914     MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
2915     MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
2916     MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
2917     MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8,
2918     MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM_8
2919 };
2920 
2921 static const int suite_CAMELLIA_128_ephemeral[] = {
2922     /* All CAMELLIA-128 ephemeral suites */
2923     MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256,
2924     MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256,
2925     MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256,
2926     MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256,
2927     MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256,
2928     MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256,
2929     MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA
2930 };
2931 
2932 static const int suite_ARIA_128_ephemeral[] = {
2933     /* All ARIA-128 ephemeral suites */
2934     MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256,
2935     MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256,
2936     MBEDTLS_TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256,
2937     MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256,
2938     MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256,
2939     MBEDTLS_TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256
2940 };
2941 
2942 static const int suite_PSK_ephemeral[] = {
2943     /* The PSK ephemeral suites */
2944     MBEDTLS_TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256,
2945     MBEDTLS_TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256,
2946     MBEDTLS_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384,
2947     MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CCM,
2948     MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384,
2949     MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384,
2950     MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA,
2951     MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA,
2952     MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384,
2953     MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384,
2954     MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384,
2955     MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CCM_8,
2956     MBEDTLS_TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384,
2957     MBEDTLS_TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384,
2958     MBEDTLS_TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384,
2959 
2960     MBEDTLS_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256,
2961     MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CCM,
2962     MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256,
2963     MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256,
2964     MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA,
2965     MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA,
2966     MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256,
2967     MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256,
2968     MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256,
2969     MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CCM_8,
2970     MBEDTLS_TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256,
2971     MBEDTLS_TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256,
2972     MBEDTLS_TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256
2973 };
2974 
2975 #if 0
2976 static const int suite_ECJPAKE[] = {
2977     /* The ECJPAKE suite */
2978     MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8
2979 };
2980 #endif
2981 
2982 static const int suite_AES_256[] = {
2983     /* All AES-256 suites */
2984     MBEDTLS_TLS_RSA_WITH_AES_256_GCM_SHA384,
2985     MBEDTLS_TLS_RSA_WITH_AES_256_CCM,
2986     MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA256,
2987     MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA,
2988     MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384,
2989     MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384,
2990     MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,
2991     MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384,
2992     MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384,
2993     MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,
2994     MBEDTLS_TLS_RSA_WITH_AES_256_CCM_8
2995 };
2996 
2997 static const int suite_CAMELLIA_256[] = {
2998     /* All CAMELLIA-256 suites */
2999     MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384,
3000     MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256,
3001     MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA,
3002     MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384,
3003     MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384,
3004     MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384,
3005     MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384
3006 };
3007 
3008 static const int suite_ARIA_256[] = {
3009     /* All ARIA-256 suites */
3010     MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384,
3011     MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384,
3012     MBEDTLS_TLS_RSA_WITH_ARIA_256_GCM_SHA384,
3013     MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384,
3014     MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384,
3015     MBEDTLS_TLS_RSA_WITH_ARIA_256_CBC_SHA384
3016 };
3017 
3018 static const int suite_AES_128[] = {
3019     /* All AES-128 suites */
3020     MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256,
3021     MBEDTLS_TLS_RSA_WITH_AES_128_CCM,
3022     MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA256,
3023     MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA,
3024     MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256,
3025     MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256,
3026     MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,
3027     MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256,
3028     MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256,
3029     MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,
3030     MBEDTLS_TLS_RSA_WITH_AES_128_CCM_8
3031 };
3032 
3033 static const int suite_CAMELLIA_128[] = {
3034     /* All CAMELLIA-128 suites */
3035     MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256,
3036     MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256,
3037     MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA,
3038     MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256,
3039     MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256,
3040     MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256,
3041     MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256
3042 };
3043 
3044 static const int suite_ARIA_128[] = {
3045     /* All ARIA-128 suites */
3046     MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256,
3047     MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256,
3048     MBEDTLS_TLS_RSA_WITH_ARIA_128_GCM_SHA256,
3049     MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256,
3050     MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256,
3051     MBEDTLS_TLS_RSA_WITH_ARIA_128_CBC_SHA256
3052 };
3053 
3054 static const int suite_RSA_PSK[] = {
3055     /* The RSA PSK suites */
3056     MBEDTLS_TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256,
3057     MBEDTLS_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384,
3058     MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384,
3059     MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA,
3060     MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384,
3061     MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384,
3062     MBEDTLS_TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384,
3063     MBEDTLS_TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384,
3064 
3065     MBEDTLS_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256,
3066     MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256,
3067     MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA,
3068     MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256,
3069     MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256,
3070     MBEDTLS_TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256,
3071     MBEDTLS_TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256
3072 };
3073 
3074 static const int suite_PSK[] = {
3075     /* The PSK suites */
3076     MBEDTLS_TLS_PSK_WITH_CHACHA20_POLY1305_SHA256,
3077     MBEDTLS_TLS_PSK_WITH_AES_256_GCM_SHA384,
3078     MBEDTLS_TLS_PSK_WITH_AES_256_CCM,
3079     MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA384,
3080     MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA,
3081     MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384,
3082     MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384,
3083     MBEDTLS_TLS_PSK_WITH_AES_256_CCM_8,
3084     MBEDTLS_TLS_PSK_WITH_ARIA_256_GCM_SHA384,
3085     MBEDTLS_TLS_PSK_WITH_ARIA_256_CBC_SHA384,
3086 
3087     MBEDTLS_TLS_PSK_WITH_AES_128_GCM_SHA256,
3088     MBEDTLS_TLS_PSK_WITH_AES_128_CCM,
3089     MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA256,
3090     MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA,
3091     MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256,
3092     MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256,
3093     MBEDTLS_TLS_PSK_WITH_AES_128_CCM_8,
3094     MBEDTLS_TLS_PSK_WITH_ARIA_128_GCM_SHA256,
3095     MBEDTLS_TLS_PSK_WITH_ARIA_128_CBC_SHA256
3096 };
3097 
3098 #ifdef MBEDTLS_SSL_PROTO_TLS1
3099 static const int suite_3DES[] = {
3100     /* 3DES suites */
3101     MBEDTLS_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,
3102     MBEDTLS_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
3103     MBEDTLS_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA,
3104     MBEDTLS_TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA,
3105     MBEDTLS_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA,
3106     MBEDTLS_TLS_RSA_WITH_3DES_EDE_CBC_SHA,
3107     MBEDTLS_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,
3108     MBEDTLS_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,
3109     MBEDTLS_TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA,
3110     MBEDTLS_TLS_PSK_WITH_3DES_EDE_CBC_SHA
3111 };
3112 #endif
3113 
3114 #ifdef MBEDTLS_SSL_PROTO_TLS1
3115 static const int suite_RC4[] = {
3116     /* RC4 suites */
3117     MBEDTLS_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
3118     MBEDTLS_TLS_ECDHE_RSA_WITH_RC4_128_SHA,
3119     MBEDTLS_TLS_ECDHE_PSK_WITH_RC4_128_SHA,
3120     MBEDTLS_TLS_DHE_PSK_WITH_RC4_128_SHA,
3121     MBEDTLS_TLS_RSA_WITH_RC4_128_SHA,
3122     MBEDTLS_TLS_RSA_WITH_RC4_128_MD5,
3123     MBEDTLS_TLS_ECDH_RSA_WITH_RC4_128_SHA,
3124     MBEDTLS_TLS_ECDH_ECDSA_WITH_RC4_128_SHA,
3125     MBEDTLS_TLS_RSA_PSK_WITH_RC4_128_SHA,
3126     MBEDTLS_TLS_PSK_WITH_RC4_128_SHA
3127 };
3128 #endif
3129 
3130 #ifdef MBEDTLS_SSL_PROTO_SSL3
3131 static const int suite_weak[] = {
3132     /* Weak suites */
3133     MBEDTLS_TLS_DHE_RSA_WITH_DES_CBC_SHA,
3134     MBEDTLS_TLS_RSA_WITH_DES_CBC_SHA
3135 };
3136 #endif
3137 
3138 static const int suite_null[] = {
3139     /* NULL suites */
3140     MBEDTLS_TLS_ECDHE_ECDSA_WITH_NULL_SHA,
3141     MBEDTLS_TLS_ECDHE_RSA_WITH_NULL_SHA,
3142     MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA384,
3143     MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA256,
3144     MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA,
3145     MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA384,
3146     MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA256,
3147     MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA,
3148 
3149     MBEDTLS_TLS_RSA_WITH_NULL_SHA256,
3150     MBEDTLS_TLS_RSA_WITH_NULL_SHA,
3151     MBEDTLS_TLS_RSA_WITH_NULL_MD5,
3152     MBEDTLS_TLS_ECDH_RSA_WITH_NULL_SHA,
3153     MBEDTLS_TLS_ECDH_ECDSA_WITH_NULL_SHA,
3154     MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA384,
3155     MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA256,
3156     MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA,
3157     MBEDTLS_TLS_PSK_WITH_NULL_SHA384,
3158     MBEDTLS_TLS_PSK_WITH_NULL_SHA256,
3159     MBEDTLS_TLS_PSK_WITH_NULL_SHA
3160 };
3161 
3162 /* TLSv1.2 cipher list (supported in mbedtls)
3163  * marked with minimum version MBEDTLS_SSL_MINOR_VERSION_3 in
3164  *   ciphersuite_definitions[] and then sorted by ciphersuite_preference[]
3165  *   from mbedtls library/ssl_ciphersuites.c */
3166 static const int suite_TLSv12[] = {
3167     MBEDTLS_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
3168     MBEDTLS_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
3169     MBEDTLS_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
3170     MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
3171     MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
3172     MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384,
3173     MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM,
3174     MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM,
3175     MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,
3176     MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,
3177     MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,
3178     MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8,
3179     MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM_8,
3180     MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384,
3181     MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384,
3182     MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384,
3183     MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256,
3184     MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384,
3185     MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384,
3186     MBEDTLS_TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384,
3187     MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384,
3188     MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384,
3189     MBEDTLS_TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384,
3190     MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
3191     MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
3192     MBEDTLS_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
3193     MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM,
3194     MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM,
3195     MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
3196     MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
3197     MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,
3198     MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8,
3199     MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM_8,
3200     MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256,
3201     MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256,
3202     MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256,
3203     MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256,
3204     MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256,
3205     MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256,
3206     MBEDTLS_TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256,
3207     MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256,
3208     MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256,
3209     MBEDTLS_TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256,
3210     MBEDTLS_TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256,
3211     MBEDTLS_TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256,
3212     MBEDTLS_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384,
3213     MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CCM,
3214     MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384,
3215     MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CCM_8,
3216     MBEDTLS_TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384,
3217     MBEDTLS_TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384,
3218     MBEDTLS_TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384,
3219     MBEDTLS_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256,
3220     MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CCM,
3221     MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256,
3222     MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CCM_8,
3223     MBEDTLS_TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256,
3224     MBEDTLS_TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256,
3225     MBEDTLS_TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256,
3226     MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8,
3227     MBEDTLS_TLS_RSA_WITH_AES_256_GCM_SHA384,
3228     MBEDTLS_TLS_RSA_WITH_AES_256_CCM,
3229     MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA256,
3230     MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384,
3231     MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384,
3232     MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384,
3233     MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384,
3234     MBEDTLS_TLS_RSA_WITH_AES_256_CCM_8,
3235     MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384,
3236     MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256,
3237     MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384,
3238     MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384,
3239     MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384,
3240     MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384,
3241     MBEDTLS_TLS_RSA_WITH_ARIA_256_GCM_SHA384,
3242     MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384,
3243     MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384,
3244     MBEDTLS_TLS_RSA_WITH_ARIA_256_CBC_SHA384,
3245     MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256,
3246     MBEDTLS_TLS_RSA_WITH_AES_128_CCM,
3247     MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA256,
3248     MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256,
3249     MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256,
3250     MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256,
3251     MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256,
3252     MBEDTLS_TLS_RSA_WITH_AES_128_CCM_8,
3253     MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256,
3254     MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256,
3255     MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256,
3256     MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256,
3257     MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256,
3258     MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256,
3259     MBEDTLS_TLS_RSA_WITH_ARIA_128_GCM_SHA256,
3260     MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256,
3261     MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256,
3262     MBEDTLS_TLS_RSA_WITH_ARIA_128_CBC_SHA256,
3263     MBEDTLS_TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256,
3264     MBEDTLS_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384,
3265     MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384,
3266     MBEDTLS_TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384,
3267     MBEDTLS_TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384,
3268     MBEDTLS_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256,
3269     MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256,
3270     MBEDTLS_TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256,
3271     MBEDTLS_TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256,
3272     MBEDTLS_TLS_PSK_WITH_CHACHA20_POLY1305_SHA256,
3273     MBEDTLS_TLS_PSK_WITH_AES_256_GCM_SHA384,
3274     MBEDTLS_TLS_PSK_WITH_AES_256_CCM,
3275     MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384,
3276     MBEDTLS_TLS_PSK_WITH_AES_256_CCM_8,
3277     MBEDTLS_TLS_PSK_WITH_ARIA_256_GCM_SHA384,
3278     MBEDTLS_TLS_PSK_WITH_ARIA_256_CBC_SHA384,
3279     MBEDTLS_TLS_PSK_WITH_AES_128_GCM_SHA256,
3280     MBEDTLS_TLS_PSK_WITH_AES_128_CCM,
3281     MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256,
3282     MBEDTLS_TLS_PSK_WITH_AES_128_CCM_8,
3283     MBEDTLS_TLS_PSK_WITH_ARIA_128_GCM_SHA256,
3284     MBEDTLS_TLS_PSK_WITH_ARIA_128_CBC_SHA256
3285 };
3286 
3287 #ifdef MBEDTLS_SSL_PROTO_TLS1
3288 /* TLSv1.0 cipher list (supported in mbedtls)
3289  * marked with minimum version MBEDTLS_SSL_MINOR_VERSION_1 in
3290  *   ciphersuite_definitions[] and then sorted by ciphersuite_preference[]
3291  *   from mbedtls library/ssl_ciphersuites.c */
3292 /* XXX: intentionally not including overlapping eNULL ciphers */
3293 static const int suite_TLSv10[] = {
3294     MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
3295     MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
3296     MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384,
3297     MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384,
3298     MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
3299     MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
3300     MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256,
3301     MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256,
3302     MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384,
3303     MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384,
3304     MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA,
3305     MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384,
3306     MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384,
3307     MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256,
3308     MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256,
3309     MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA,
3310     MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256,
3311     MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256,
3312     MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,
3313     MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,
3314     MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384,
3315     MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384,
3316     MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,
3317     MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,
3318     MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256,
3319     MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256,
3320     MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384,
3321     MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA,
3322     MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384,
3323     MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256,
3324     MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA,
3325     MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256,
3326     MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA384,
3327     MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384,
3328     MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA256,
3329     MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256,
3330     MBEDTLS_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,
3331     MBEDTLS_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
3332     MBEDTLS_TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA,
3333     MBEDTLS_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,
3334     MBEDTLS_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,
3335     MBEDTLS_TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA,
3336     MBEDTLS_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
3337     MBEDTLS_TLS_ECDHE_RSA_WITH_RC4_128_SHA,
3338     MBEDTLS_TLS_ECDHE_PSK_WITH_RC4_128_SHA,
3339     MBEDTLS_TLS_ECDH_RSA_WITH_RC4_128_SHA,
3340     MBEDTLS_TLS_ECDH_ECDSA_WITH_RC4_128_SHA,
3341     MBEDTLS_TLS_RSA_PSK_WITH_RC4_128_SHA
3342 };
3343 #endif
3344 
3345 #ifdef MBEDTLS_SSL_PROTO_SSL3
3346 /* SSLv3 cipher list (supported in mbedtls)
3347  * marked with minimum version MBEDTLS_SSL_MINOR_VERSION_0 in
3348  *   ciphersuite_definitions[] and then sorted by ciphersuite_preference[]
3349  *   from mbedtls library/ssl_ciphersuites.c */
3350 /* XXX: intentionally not including overlapping eNULL ciphers */
3351 static const int suite_SSLv3[] = {
3352     MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
3353     MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA,
3354     MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
3355     MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA,
3356     MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA,
3357     MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA,
3358     MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA,
3359     MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA,
3360     MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA,
3361     MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA,
3362     MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA,
3363     MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA,
3364     MBEDTLS_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA,
3365     MBEDTLS_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA,
3366     MBEDTLS_TLS_RSA_WITH_3DES_EDE_CBC_SHA,
3367     MBEDTLS_TLS_PSK_WITH_3DES_EDE_CBC_SHA,
3368     MBEDTLS_TLS_DHE_PSK_WITH_RC4_128_SHA,
3369     MBEDTLS_TLS_RSA_WITH_RC4_128_SHA,
3370     MBEDTLS_TLS_RSA_WITH_RC4_128_MD5,
3371     MBEDTLS_TLS_PSK_WITH_RC4_128_SHA,
3372     MBEDTLS_TLS_DHE_RSA_WITH_DES_CBC_SHA,
3373     MBEDTLS_TLS_RSA_WITH_DES_CBC_SHA
3374 };
3375 #endif
3376 
3377 /* HIGH cipher list (mapped from openssl list to mbedtls) */
3378 static const int suite_HIGH[] = {
3379     MBEDTLS_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
3380     MBEDTLS_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
3381     MBEDTLS_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
3382     MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
3383     MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
3384     MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384,
3385     MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM,
3386     MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM,
3387     MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,
3388     MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,
3389     MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,
3390     MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
3391     MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
3392     MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
3393     MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8,
3394     MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM_8,
3395     MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384,
3396     MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384,
3397     MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256,
3398     MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA,
3399     MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384,
3400     MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384,
3401     MBEDTLS_TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384,
3402     MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
3403     MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
3404     MBEDTLS_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
3405     MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM,
3406     MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM,
3407     MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
3408     MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
3409     MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,
3410     MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
3411     MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
3412     MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
3413     MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8,
3414     MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM_8,
3415     MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256,
3416     MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256,
3417     MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256,
3418     MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA,
3419     MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256,
3420     MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256,
3421     MBEDTLS_TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256,
3422     MBEDTLS_TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256,
3423     MBEDTLS_TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256,
3424     MBEDTLS_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384,
3425     MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CCM,
3426     MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384,
3427     MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384,
3428     MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA,
3429     MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA,
3430     MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384,
3431     MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384,
3432     MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CCM_8,
3433     MBEDTLS_TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384,
3434     MBEDTLS_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256,
3435     MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CCM,
3436     MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256,
3437     MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256,
3438     MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA,
3439     MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA,
3440     MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256,
3441     MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256,
3442     MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CCM_8,
3443     MBEDTLS_TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256,
3444     MBEDTLS_TLS_RSA_WITH_AES_256_GCM_SHA384,
3445     MBEDTLS_TLS_RSA_WITH_AES_256_CCM,
3446     MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA256,
3447     MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA,
3448     MBEDTLS_TLS_RSA_WITH_AES_256_CCM_8,
3449     MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256,
3450     MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA,
3451     MBEDTLS_TLS_RSA_WITH_ARIA_256_GCM_SHA384,
3452     MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256,
3453     MBEDTLS_TLS_RSA_WITH_AES_128_CCM,
3454     MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA256,
3455     MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA,
3456     MBEDTLS_TLS_RSA_WITH_AES_128_CCM_8,
3457     MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256,
3458     MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA,
3459     MBEDTLS_TLS_RSA_WITH_ARIA_128_GCM_SHA256,
3460     MBEDTLS_TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256,
3461     MBEDTLS_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384,
3462     MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384,
3463     MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA,
3464     MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384,
3465     MBEDTLS_TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384,
3466     MBEDTLS_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256,
3467     MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256,
3468     MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA,
3469     MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256,
3470     MBEDTLS_TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256,
3471     MBEDTLS_TLS_PSK_WITH_CHACHA20_POLY1305_SHA256,
3472     MBEDTLS_TLS_PSK_WITH_AES_256_GCM_SHA384,
3473     MBEDTLS_TLS_PSK_WITH_AES_256_CCM,
3474     MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA384,
3475     MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA,
3476     MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384,
3477     MBEDTLS_TLS_PSK_WITH_AES_256_CCM_8,
3478     MBEDTLS_TLS_PSK_WITH_ARIA_256_GCM_SHA384,
3479     MBEDTLS_TLS_PSK_WITH_AES_128_GCM_SHA256,
3480     MBEDTLS_TLS_PSK_WITH_AES_128_CCM,
3481     MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA256,
3482     MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA,
3483     MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256,
3484     MBEDTLS_TLS_PSK_WITH_AES_128_CCM_8,
3485     MBEDTLS_TLS_PSK_WITH_ARIA_128_GCM_SHA256,
3486 };
3487 
3488 
3489 /* true if RC4 or weak or NULL cipher suite
3490  *   (These ciphersuites are excluded from openssl "DEFAULT")
3491  * This is a subset of ciphers excluded for mod_openssl "!aNULL:!eNULL:!EXP" */
3492 static int
3493 mod_mbedtls_ssl_is_weak_ciphersuite (int id)
3494 {
3495   #ifdef MBEDTLS_SSL_PROTO_TLS1
3496     for (uint32_t i = 0; i < sizeof(suite_RC4)/sizeof(suite_RC4[0]); ++i) {
3497         if (id == suite_RC4[i]) return 1;
3498     }
3499   #endif
3500   #ifdef MBEDTLS_SSL_PROTO_SSL3
3501     for (uint32_t i = 0; i < sizeof(suite_weak)/sizeof(suite_weak[0]); ++i) {
3502         if (id == suite_weak[i]) return 1;
3503     }
3504   #endif
3505     for (uint32_t i = 0; i < sizeof(suite_null)/sizeof(suite_null[0]); ++i) {
3506         if (id == suite_null[i]) return 1;
3507     }
3508     return 0;
3509 }
3510 
3511 
3512 static int
3513 mod_mbedtls_ssl_DEFAULT_ciphersuite (server *srv, int *ids, int nids, int idsz)
3514 {
3515     /* obtain default ciphersuite list and filter out weak or NULL */
3516     const int *dids = mbedtls_ssl_list_ciphersuites();
3517     int i = 0;
3518     while (dids[i] != 0) ++i;
3519 
3520     if (i >= idsz - (nids + 1)) {
3521         log_error(srv->errh, __FILE__, __LINE__,
3522           "MTLS: error: too many ciphersuites during list expand");
3523         return -1;
3524     }
3525 
3526     for (i = 0; dids[i] != 0; ++i) {
3527         if (!mod_mbedtls_ssl_is_weak_ciphersuite(dids[i]))
3528             ids[++nids] = dids[i];
3529     }
3530 
3531     return nids;
3532 }
3533 
3534 
3535 static int
3536 mod_mbedtls_ssl_append_ciphersuite (server *srv, int *ids, int nids, int idsz, const int *x, int xsz)
3537 {
3538     if (xsz >= idsz - (nids + 1)) {
3539         log_error(srv->errh, __FILE__, __LINE__,
3540           "MTLS: error: too many ciphersuites during list expand");
3541         return -1;
3542     }
3543 
3544     for (int i = 0; i < xsz; ++i)
3545         ids[++nids] = x[i];
3546 
3547     return nids;
3548 }
3549 
3550 
3551 static int
3552 mod_mbedtls_ssl_conf_ciphersuites (server *srv, plugin_config_socket *s, buffer *ciphersuites, const buffer *cipherstring)
3553 {
3554     /* reference: https://www.openssl.org/docs/man1.1.1/man1/ciphers.html
3555      * Attempt to parse *some* keywords from Ciphersuites and CipherString
3556      * !!! openssl uses a *different* naming scheme than does mbedTLS !!!
3557      * Since Ciphersuites in openssl takes only TLSv1.3 suites, and mbedTLS
3558      * does not currently support TLSv1.3, mapping of those names is not
3559      * currently provided.  Note that CipherString does allow cipher suites to
3560      * be listed, and this code does not currently attempt to provide mapping */
3561 
3562     char n[128]; /*(most ciphersuite names are about 40 chars)*/
3563     int ids[512];
3564     int nids = -1;
3565     const int idsz = (int)(sizeof(ids)/sizeof(*ids)-1);
3566     int crt_profile_default = 0;
3567 
3568     if (ciphersuites) {
3569         buffer *b = ciphersuites;
3570         buffer_to_upper(b); /*(ciphersuites are all uppercase (currently))*/
3571         for (const char *e = b->ptr-1; e; ) {
3572             const char * const p = e+1;
3573             e = strchr(p, ':');
3574             size_t len = e ? (size_t)(e - p) : strlen(p);
3575             if (len >= sizeof(n)) {
3576                 log_error(srv->errh, __FILE__, __LINE__,
3577                   "MTLS: skipped ciphersuite; too long: %.*s",
3578                   (int)len, p);
3579                 continue;
3580             }
3581             memcpy(n, p, len);
3582             n[len] = '\0';
3583 
3584             int id = mbedtls_ssl_get_ciphersuite_id(n);
3585             if (0 == id) {
3586                 log_error(srv->errh, __FILE__, __LINE__,
3587                   "MTLS: skipped ciphersuite; not recognized: %.*s",
3588                   (int)len, n);
3589                 continue;
3590             }
3591 
3592             /* allow any ciphersuite if explicitly listed, even weak or eNULL */
3593           #if 0
3594             if (mod_mbedtls_ssl_is_weak_ciphersuite(id)) {
3595                 log_error(srv->errh, __FILE__, __LINE__,
3596                   "MTLS: skipped ciphersuite; weak or NULL suite: %.*s",
3597                   (int)len, n);
3598                 continue;
3599             }
3600           #endif
3601 
3602             if (nids >= idsz) {
3603                 log_error(srv->errh, __FILE__, __LINE__,
3604                   "MTLS: skipped ciphersuite; too many listed: %.*s",
3605                   (int)len, n);
3606                 continue;
3607             }
3608 
3609             ids[++nids] = id;
3610         }
3611     }
3612 
3613     /* XXX: openssl config for CipherString=... is excessively complex.
3614      * If there is a need to enable specific ciphersuites, then that
3615      * can be accomplished with mod_mbedtls by specifying the list in
3616      * Ciphersuites=... in the ssl.openssl.ssl-conf-cmd directive.
3617      * (Alternatively, build mbedtls with specific set of cipher suites
3618      *  or modify mod_mbedtls code to specify the precise list).
3619      *
3620      * The tokens parsed here are a quick attempt to handle a few cases
3621      *
3622      * XXX: not done: could make a list of ciphers with bitflag of attributes
3623      *      to make future combining easier */
3624     if (cipherstring && !buffer_is_blank(cipherstring)) {
3625         const buffer *b = cipherstring;
3626         const char *e = b->ptr;
3627 
3628         /* XXX: not done: no checking for duplication of ciphersuites
3629          * even if tokens overlap or are repeated */
3630 
3631         /* XXX: not done: might walk string and build up exclude list of !xxxxx
3632          * ciphersuites and walk string again, excluding as result list built */
3633 
3634         /* manually handle first token, since one-offs apply */
3635         /* (openssl syntax NOT fully supported) */
3636         int default_suite = 0;
3637         #define strncmp_const(s,cs) strncmp((s),(cs),sizeof(cs)-1)
3638         if (0 == strncmp_const(e, "!ALL") || 0 == strncmp_const(e, "-ALL")) {
3639             /* "!ALL" excluding all ciphers does not make sense; ignore */
3640             e += sizeof("!ALL")-1; /* same as sizeof("-ALL")-1 */
3641         }
3642         else if (0 == strncmp_const(e, "!DEFAULT")
3643               || 0 == strncmp_const(e, "-DEFAULT")) {
3644             /* "!DEFAULT" excluding default ciphers is empty list; no effect */
3645             e += sizeof("!DEFAULT")-1; /* same as sizeof("-DEFAULT")-1 */
3646         }
3647         else if (0 == strncmp_const(e, "DEFAULT")) {
3648             e += sizeof("DEFAULT")-1;
3649             default_suite = 1;
3650         }
3651         else if (0 == /* effectively the same as "DEFAULT" */
3652                  strncmp_const(e, "ALL:!COMPLEMENTOFDEFAULT:!eNULL")) {
3653             e += sizeof("ALL:!COMPLEMENTOFDEFAULT:!eNULL")-1;
3654             default_suite = 1;
3655         }
3656         else if (0 == strncmp_const(e, "SUITEB128")
3657               || 0 == strncmp_const(e, "SUITEB128ONLY")
3658               || 0 == strncmp_const(e, "SUITEB192")) {
3659             mbedtls_ssl_conf_cert_profile(s->ssl_ctx,
3660                                           &mbedtls_x509_crt_profile_suiteb);
3661             /* re-initialize mbedtls_ssl_config defaults */
3662           #if MBEDTLS_VERSION_NUMBER < 0x03020000 /* mbedtls 3.02.0 */
3663             mbedtls_mpi_free(&s->ssl_ctx->MBEDTLS_PRIVATE(dhm_P));
3664             mbedtls_mpi_free(&s->ssl_ctx->MBEDTLS_PRIVATE(dhm_G));
3665           #endif
3666             int rc = mbedtls_ssl_config_defaults(s->ssl_ctx,
3667                                                  MBEDTLS_SSL_IS_SERVER,
3668                                                  MBEDTLS_SSL_TRANSPORT_STREAM,
3669                                                  MBEDTLS_SSL_PRESET_SUITEB);
3670             if (0 != rc) {
3671                 elog(srv->errh, __FILE__,__LINE__, rc,
3672                      "Init of ssl config context SUITEB defaults failed");
3673                 return 0;
3674             }
3675             e += (0 == strncmp_const(e, "SUITEB128ONLY"))
3676                  ? sizeof("SUITEB128ONLY")-1
3677                  : sizeof("SUITEB128")-1;
3678             if (*e)
3679                 log_error(srv->errh, __FILE__, __LINE__,
3680                   "MTLS: ignoring cipher string after SUITEB: %s", e);
3681             return 1;
3682         }
3683         else if (0 == strncmp_const(e,
3684                   "ECDHE+AESGCM:ECDHE+AES256:CHACHA20:!SHA1:!SHA256:!SHA384")
3685               || 0 == strncmp_const(e,
3686                   "EECDH+AESGCM:AES256+EECDH:CHACHA20:!SHA1:!SHA256:!SHA384")) {
3687             e += sizeof(
3688                   "EECDH+AESGCM:AES256+EECDH:CHACHA20:!SHA1:!SHA256:!SHA384")-1;
3689             if (nids + 9 >= idsz) {
3690                 log_error(srv->errh, __FILE__, __LINE__,
3691                   "MTLS: error: too many ciphersuites during list expand");
3692                 return 0;
3693             }
3694             ids[++nids] = MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384;
3695             ids[++nids] = MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384;
3696             ids[++nids] = MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256;
3697             ids[++nids] = MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256;
3698             ids[++nids] = MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM;
3699             ids[++nids] = MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8;
3700             ids[++nids] = MBEDTLS_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256;
3701             ids[++nids] = MBEDTLS_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256;
3702             ids[++nids] = MBEDTLS_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256;
3703         }
3704 
3705         if (e != b->ptr && *e != ':' && *e != '\0') {
3706             log_error(srv->errh, __FILE__, __LINE__,
3707               "MTLS: error: missing support for cipher list: %s", b->ptr);
3708             return 0;
3709         }
3710 
3711         if (default_suite) {
3712             crt_profile_default = 1;
3713             nids =
3714               mod_mbedtls_ssl_DEFAULT_ciphersuite(srv, ids, nids, idsz);
3715             if (-1 == nids) return 0;
3716         }
3717 
3718         /* not handled: "ALL" is "DEFAULT" and "RC4" */
3719         /* not handled: "COMPLEMENTOFALL" is "eNULL" */
3720 
3721         int rc = 1;
3722         if (e == b->ptr || *e == '\0') --e; /*initial condition for loop below*/
3723         do {
3724             const char * const p = e+1;
3725             e = strchr(p, ':');
3726             size_t len = e ? (size_t)(e - p) : strlen(p);
3727             if (0 == len) continue;
3728             if (len >= sizeof(n)) {
3729                 log_error(srv->errh, __FILE__, __LINE__,
3730                   "MTLS: skipped ciphersuite; too long: %.*s",
3731                   (int)len, p);
3732                 continue;
3733             }
3734             char c = (*p == '!' || *p == '-' || *p == '+') ? *p : 0;
3735             size_t nlen = c ? len-1 : len;
3736             memcpy(n, c ? p+1 : p, nlen);
3737             n[nlen] = '\0';
3738 
3739             /* not handled: !xxxxx -xxxxx and most +xxxxx */
3740             if (c) {
3741                 log_error(srv->errh, __FILE__, __LINE__,
3742                   "MTLS: error: missing support for cipher list: %s", b->ptr);
3743             }
3744 
3745             /* ignore @STRENGTH sorting and ignore @SECLEVEL=n */
3746             char *a = strchr(n, '@');
3747             if (a) {
3748                 log_error(srv->errh, __FILE__, __LINE__,
3749                   "MTLS: ignored %s in %.*s", a, (int)len, p);
3750                 *a = '\0';
3751                 nlen = (size_t)(a - n);
3752             }
3753 
3754             if (buffer_eq_icase_ss(n, nlen, CONST_STR_LEN("TLSv1.2"))) {
3755                 nids = mod_mbedtls_ssl_append_ciphersuite(srv, ids, nids, idsz,
3756                          suite_TLSv12,
3757                          (int)(sizeof(suite_TLSv12)/sizeof(*suite_TLSv12)));
3758                 if (-1 == nids) return 0;
3759                 continue;
3760             }
3761 
3762           #ifdef MBEDTLS_SSL_PROTO_TLS1
3763             if (buffer_eq_icase_ss(n, nlen, CONST_STR_LEN("TLSv1.0"))) {
3764                 crt_profile_default = 1;
3765                 nids = mod_mbedtls_ssl_append_ciphersuite(srv, ids, nids, idsz,
3766                          suite_TLSv10,
3767                          (int)(sizeof(suite_TLSv10)/sizeof(*suite_TLSv10)));
3768                 if (-1 == nids) return 0;
3769                 continue;
3770             }
3771           #endif
3772 
3773           #ifdef MBEDTLS_SSL_PROTO_SSL3
3774             if (buffer_eq_icase_ss(n, nlen, CONST_STR_LEN("SSLv3"))) {
3775                 crt_profile_default = 1;
3776                 nids = mod_mbedtls_ssl_append_ciphersuite(srv, ids, nids, idsz,
3777                          suite_SSLv3,
3778                          (int)(sizeof(suite_SSLv3)/sizeof(*suite_SSLv3)));
3779                 if (-1 == nids) return 0;
3780                 continue;
3781             }
3782           #endif
3783 
3784             /* handle a popular recommendations
3785              *   ssl.cipher-list = "EECDH+AESGCM:EDH+AESGCM"
3786              *   ssl.cipher-list = "AES256+EECDH:AES256+EDH"
3787              * which uses AES hardware acceleration built into popular CPUs */
3788             if (buffer_eq_icase_ss(n, nlen, CONST_STR_LEN("ECDHE+AESGCM"))
3789              || buffer_eq_icase_ss(n, nlen, CONST_STR_LEN("EECDH+AESGCM"))) {
3790                 if (nids + 4 >= idsz) {
3791                     log_error(srv->errh, __FILE__, __LINE__,
3792                       "MTLS: error: too many ciphersuites during list expand");
3793                     return 0;
3794                 }
3795                 ids[++nids] = MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384;
3796                 ids[++nids] = MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384;
3797                 ids[++nids] = MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256;
3798                 ids[++nids] = MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256;
3799                 continue;
3800             }
3801             if (buffer_eq_icase_ss(n, nlen, CONST_STR_LEN("DHE+AESGCM"))
3802              || buffer_eq_icase_ss(n, nlen, CONST_STR_LEN("EDH+AESGCM"))) {
3803                 if (nids + 2 >= idsz) {
3804                     log_error(srv->errh, __FILE__, __LINE__,
3805                       "MTLS: error: too many ciphersuites during list expand");
3806                     return 0;
3807                 }
3808                 ids[++nids] = MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384;
3809                 ids[++nids] = MBEDTLS_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256;
3810                 continue;
3811             }
3812             if (buffer_eq_icase_ss(n, nlen, CONST_STR_LEN("AES256+EECDH"))) {
3813                 if (nids + 8 >= idsz) {
3814                     log_error(srv->errh, __FILE__, __LINE__,
3815                       "MTLS: error: too many ciphersuites during list expand");
3816                     return 0;
3817                 }
3818                 ids[++nids] = MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384;
3819                 ids[++nids] = MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384;
3820                 ids[++nids] = MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM;
3821                 ids[++nids] = MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384;
3822                 ids[++nids] = MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384;
3823                 ids[++nids] = MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA;
3824                 ids[++nids] = MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA;
3825                 ids[++nids] = MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8;
3826                 continue;
3827             }
3828             if (buffer_eq_icase_ss(n, nlen, CONST_STR_LEN("AES256+EDH"))) {
3829                 if (nids + 5 >= idsz) {
3830                     log_error(srv->errh, __FILE__, __LINE__,
3831                       "MTLS: error: too many ciphersuites during list expand");
3832                     return 0;
3833                 }
3834                 ids[++nids] = MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384;
3835                 ids[++nids] = MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM;
3836                 ids[++nids] = MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256;
3837                 ids[++nids] = MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA;
3838                 ids[++nids] = MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM_8;
3839                 continue;
3840             }
3841 
3842             if (buffer_eq_icase_ss(n, nlen, CONST_STR_LEN("HIGH"))) {
3843                 nids = mod_mbedtls_ssl_append_ciphersuite(srv, ids, nids, idsz,
3844                          suite_HIGH,
3845                          (int)(sizeof(suite_HIGH)/sizeof(*suite_HIGH)));
3846                 if (-1 == nids) return 0;
3847                 continue;
3848             }
3849 
3850             if (buffer_eq_icase_ss(n, nlen, CONST_STR_LEN("AES256"))
3851              || buffer_eq_icase_ss(n, nlen, CONST_STR_LEN("AES"))) {
3852                 nids = mod_mbedtls_ssl_append_ciphersuite(srv, ids, nids, idsz,
3853                          suite_AES_256_ephemeral,
3854                          (int)(sizeof(suite_AES_256_ephemeral)
3855                               /sizeof(*suite_AES_256_ephemeral)));
3856                 if (-1 == nids) return 0;
3857                 nids = mod_mbedtls_ssl_append_ciphersuite(srv, ids, nids, idsz,
3858                          suite_AES_256,
3859                          (int)(sizeof(suite_AES_256)/sizeof(*suite_AES_256)));
3860                 if (-1 == nids) return 0;
3861                 /* XXX: not done: AES256 PSK suites */
3862                 if (nlen == sizeof("AES256")-1) continue;
3863             }
3864 
3865             if (buffer_eq_icase_ss(n, nlen, CONST_STR_LEN("AES128"))
3866              || buffer_eq_icase_ss(n, nlen, CONST_STR_LEN("AES"))) {
3867                 nids = mod_mbedtls_ssl_append_ciphersuite(srv, ids, nids, idsz,
3868                          suite_AES_128_ephemeral,
3869                          (int)(sizeof(suite_AES_128_ephemeral)
3870                               /sizeof(*suite_AES_128_ephemeral)));
3871                 if (-1 == nids) return 0;
3872                 nids = mod_mbedtls_ssl_append_ciphersuite(srv, ids, nids, idsz,
3873                          suite_AES_128,
3874                          (int)(sizeof(suite_AES_128)/sizeof(*suite_AES_128)));
3875                 if (-1 == nids) return 0;
3876                 /* XXX: not done: AES128 PSK suites */
3877                 continue;
3878             }
3879 
3880             if (buffer_eq_icase_ss(n, nlen, CONST_STR_LEN("CAMELLIA256"))
3881              || buffer_eq_icase_ss(n, nlen, CONST_STR_LEN("CAMELLIA"))) {
3882                 nids = mod_mbedtls_ssl_append_ciphersuite(srv, ids, nids, idsz,
3883                          suite_CAMELLIA_256_ephemeral,
3884                          (int)(sizeof(suite_CAMELLIA_256_ephemeral)
3885                               /sizeof(*suite_CAMELLIA_256_ephemeral)));
3886                 if (-1 == nids) return 0;
3887                 nids = mod_mbedtls_ssl_append_ciphersuite(srv, ids, nids, idsz,
3888                          suite_CAMELLIA_256,
3889                          (int)(sizeof(suite_CAMELLIA_256)
3890                               /sizeof(*suite_CAMELLIA_256)));
3891                 if (-1 == nids) return 0;
3892                 /* XXX: not done: CAMELLIA256 PSK suites */
3893                 if (nlen == sizeof("CAMELLIA256")-1) continue;
3894             }
3895 
3896             if (buffer_eq_icase_ss(n, nlen, CONST_STR_LEN("CAMELLIA128"))
3897              || buffer_eq_icase_ss(n, nlen, CONST_STR_LEN("CAMELLIA"))) {
3898                 nids = mod_mbedtls_ssl_append_ciphersuite(srv, ids, nids, idsz,
3899                          suite_CAMELLIA_128_ephemeral,
3900                          (int)(sizeof(suite_CAMELLIA_128_ephemeral)
3901                               /sizeof(*suite_CAMELLIA_128_ephemeral)));
3902                 if (-1 == nids) return 0;
3903                 nids = mod_mbedtls_ssl_append_ciphersuite(srv, ids, nids, idsz,
3904                          suite_CAMELLIA_128,
3905                          (int)(sizeof(suite_CAMELLIA_128)
3906                               /sizeof(*suite_CAMELLIA_128)));
3907                 if (-1 == nids) return 0;
3908                 /* XXX: not done: CAMELLIA128 PSK suites */
3909                 continue;
3910             }
3911 
3912             if (buffer_eq_icase_ss(n, nlen, CONST_STR_LEN("ARIA256"))
3913              || buffer_eq_icase_ss(n, nlen, CONST_STR_LEN("ARIA"))) {
3914                 nids = mod_mbedtls_ssl_append_ciphersuite(srv, ids, nids, idsz,
3915                          suite_ARIA_256_ephemeral,
3916                          (int)(sizeof(suite_ARIA_256_ephemeral)
3917                               /sizeof(*suite_ARIA_256_ephemeral)));
3918                 if (-1 == nids) return 0;
3919                 nids = mod_mbedtls_ssl_append_ciphersuite(srv, ids, nids, idsz,
3920                          suite_ARIA_256,
3921                          (int)(sizeof(suite_ARIA_256)/sizeof(*suite_ARIA_256)));
3922                 if (-1 == nids) return 0;
3923                 /* XXX: not done: ARIA256 PSK suites */
3924                 if (nlen == sizeof("ARIA256")-1) continue;
3925             }
3926 
3927             if (buffer_eq_icase_ss(n, nlen, CONST_STR_LEN("ARIA128"))
3928              || buffer_eq_icase_ss(n, nlen, CONST_STR_LEN("ARIA"))) {
3929                 nids = mod_mbedtls_ssl_append_ciphersuite(srv, ids, nids, idsz,
3930                          suite_ARIA_128_ephemeral,
3931                          (int)(sizeof(suite_ARIA_128_ephemeral)
3932                               /sizeof(*suite_ARIA_128_ephemeral)));
3933                 if (-1 == nids) return 0;
3934                 nids = mod_mbedtls_ssl_append_ciphersuite(srv, ids, nids, idsz,
3935                          suite_ARIA_128,
3936                          (int)(sizeof(suite_ARIA_128)/sizeof(*suite_ARIA_128)));
3937                 if (-1 == nids) return 0;
3938                 /* XXX: not done: ARIA128 PSK suites */
3939                 continue;
3940             }
3941 
3942             if (buffer_eq_icase_ss(n, nlen, CONST_STR_LEN("CHACHA20"))) {
3943                 nids = mod_mbedtls_ssl_append_ciphersuite(srv, ids, nids, idsz,
3944                          suite_CHACHAPOLY_ephemeral,
3945                          (int)(sizeof(suite_CHACHAPOLY_ephemeral)
3946                               /sizeof(*suite_CHACHAPOLY_ephemeral)));
3947                 if (-1 == nids) return 0;
3948                 /* XXX: not done: CHACHA20 PSK suites */
3949                 continue;
3950             }
3951 
3952             if (buffer_eq_icase_ss(n, nlen, CONST_STR_LEN("PSK"))) {
3953                 /* XXX: intentionally not including overlapping eNULL ciphers */
3954                 nids = mod_mbedtls_ssl_append_ciphersuite(srv, ids, nids, idsz,
3955                          suite_PSK_ephemeral,
3956                          (int)(sizeof(suite_PSK_ephemeral)
3957                               /sizeof(*suite_PSK_ephemeral)));
3958                 if (-1 == nids) return 0;
3959                 nids = mod_mbedtls_ssl_append_ciphersuite(srv, ids, nids, idsz,
3960                          suite_RSA_PSK,
3961                          (int)(sizeof(suite_RSA_PSK)/sizeof(*suite_RSA_PSK)));
3962                 if (-1 == nids) return 0;
3963                 nids = mod_mbedtls_ssl_append_ciphersuite(srv, ids, nids, idsz,
3964                          suite_PSK,
3965                          (int)(sizeof(suite_PSK)/sizeof(*suite_PSK)));
3966                 if (-1 == nids) return 0;
3967                 continue;
3968             }
3969 
3970           #ifdef MBEDTLS_SSL_PROTO_TLS1
3971             if (buffer_eq_icase_ss(n, nlen, CONST_STR_LEN("3DES"))) {
3972                 crt_profile_default = 1;
3973                 nids = mod_mbedtls_ssl_append_ciphersuite(srv, ids, nids, idsz,
3974                          suite_3DES,
3975                          (int)(sizeof(suite_3DES)/sizeof(*suite_3DES)));
3976                 if (-1 == nids) return 0;
3977                 continue;
3978             }
3979           #endif
3980 
3981           #ifdef MBEDTLS_SSL_PROTO_TLS1
3982             /* not recommended, but permitted if explicitly requested */
3983             /* "RC4" is same as openssl "COMPLEMENTOFALL" */
3984             if (buffer_eq_icase_ss(n, nlen, CONST_STR_LEN("RC4"))) {
3985                 crt_profile_default = 1;
3986                 nids = mod_mbedtls_ssl_append_ciphersuite(srv, ids, nids, idsz,
3987                          suite_RC4,
3988                          (int)(sizeof(suite_RC4)/sizeof(*suite_RC4)));
3989                 if (-1 == nids) return 0;
3990                 continue;
3991             }
3992           #endif
3993 
3994             /* not recommended, but permitted if explicitly requested */
3995             if (buffer_eq_icase_ss(n, nlen, CONST_STR_LEN("NULL"))
3996              || buffer_eq_icase_ss(n, nlen, CONST_STR_LEN("eNULL"))) {
3997                 crt_profile_default = 1;
3998                 nids = mod_mbedtls_ssl_append_ciphersuite(srv, ids, nids, idsz,
3999                          suite_null,
4000                          (int)(sizeof(suite_null)/sizeof(*suite_null)));
4001                 if (-1 == nids) return 0;
4002                 continue;
4003             }
4004 
4005             {
4006                 log_error(srv->errh, __FILE__, __LINE__,
4007                   "MTLS: error: missing support for cipher list: %.*s",
4008                   (int)len, p);
4009                 rc = 0;
4010                 continue;
4011             }
4012         } while (e);
4013         if (0 == rc) return 0;
4014     }
4015 
4016     if (-1 == nids) {
4017         /* Do not set a default if ssl.cipher-list was set (and we are
4018          * are processing ssl.openssl.ssl-conf-cmd, not ssl.cipher-list) */
4019         if (cipherstring != s->ssl_cipher_list && s->ssl_cipher_list)
4020             return 1;
4021 
4022         /* obtain default ciphersuite list and filter out RC4, weak, and NULL */
4023         nids =
4024           mod_mbedtls_ssl_DEFAULT_ciphersuite(srv, ids, nids,
4025                                               sizeof(ids)/sizeof(*ids));
4026         if (-1 == nids) return 0;
4027     }
4028 
4029     if (nids >= idsz) {
4030         log_error(srv->errh, __FILE__, __LINE__,
4031           "MTLS: error: too many ciphersuites during list expand");
4032         return 0;
4033     }
4034     ids[++nids] = 0; /* terminate list */
4035     ++nids;
4036 
4037     if (!crt_profile_default)
4038         mbedtls_ssl_conf_cert_profile(s->ssl_ctx,
4039                                       &mbedtls_x509_crt_profile_next);
4040 
4041     /* ciphersuites list must be persistent for lifetime of mbedtls_ssl_config*/
4042     s->ciphersuites = malloc(nids * sizeof(int));
4043     force_assert(s->ciphersuites);
4044     memcpy(s->ciphersuites, ids, nids * sizeof(int));
4045 
4046     mbedtls_ssl_conf_ciphersuites(s->ssl_ctx, s->ciphersuites);
4047     return 1;
4048 }
4049 
4050 
4051 #if MBEDTLS_VERSION_NUMBER < 0x03010000 /* mbedtls 3.01.0 */
4052 static int
4053 mod_mbedtls_ssl_append_curve (server *srv, mbedtls_ecp_group_id *ids, int nids, int idsz, const mbedtls_ecp_group_id id)
4054 {
4055     if (1 >= idsz - (nids + 1)) {
4056         log_error(srv->errh, __FILE__, __LINE__,
4057           "MTLS: error: too many curves during list expand");
4058         return -1;
4059     }
4060     ids[++nids] = id;
4061     return nids;
4062 }
4063 
4064 
4065 static int
4066 mod_mbedtls_ssl_conf_curves(server *srv, plugin_config_socket *s, const buffer *curvelist)
4067 {
4068     mbedtls_ecp_group_id ids[512];
4069     int nids = -1;
4070     const int idsz = (int)(sizeof(ids)/sizeof(*ids)-1);
4071     const mbedtls_ecp_curve_info * const curve_info = mbedtls_ecp_curve_list();
4072 
4073     const buffer * const b = curvelist;
4074     for (const char *e = b->ptr-1; e; ) {
4075         const char * const n = e+1;
4076         e = strchr(n, ':');
4077         size_t len = e ? (size_t)(e - n) : strlen(n);
4078         /* similar to mbedtls_ecp_curve_info_from_name() */
4079         const mbedtls_ecp_curve_info *info;
4080         for (info = curve_info; info->grp_id != MBEDTLS_ECP_DP_NONE; ++info) {
4081             if (0 == strncmp(info->name, n, len) && info->name[len] == '\0')
4082                 break;
4083         }
4084         if (info->grp_id == MBEDTLS_ECP_DP_NONE) {
4085             log_error(srv->errh, __FILE__, __LINE__,
4086                       "MTLS: unrecognized curve: %.*s; ignored", (int)len, n);
4087             continue;
4088         }
4089 
4090         nids = mod_mbedtls_ssl_append_curve(srv, ids, nids, idsz, info->grp_id);
4091         if (-1 == nids) return 0;
4092     }
4093 
4094     /* XXX: mod_openssl configures "prime256v1" if curve list not specified,
4095      * but mbedtls provides a list of supported curves if not explicitly set */
4096     if (-1 == nids) return 1; /* empty list; no-op */
4097 
4098     ids[++nids] = MBEDTLS_ECP_DP_NONE; /* terminate list */
4099     ++nids;
4100 
4101     /* curves list must be persistent for lifetime of mbedtls_ssl_config */
4102     s->curves = malloc(nids * sizeof(mbedtls_ecp_group_id));
4103     force_assert(s->curves);
4104     memcpy(s->curves, ids, nids * sizeof(mbedtls_ecp_group_id));
4105 
4106     mbedtls_ssl_conf_curves(s->ssl_ctx, s->curves);
4107     return 1;
4108 }
4109 #else
4110 static int
4111 mod_mbedtls_ssl_append_curve (server *srv, uint16_t *ids, int nids, int idsz, const uint16_t id)
4112 {
4113     if (1 >= idsz - (nids + 1)) {
4114         log_error(srv->errh, __FILE__, __LINE__,
4115           "MTLS: error: too many curves during list expand");
4116         return -1;
4117     }
4118     ids[++nids] = id;
4119     return nids;
4120 }
4121 
4122 
4123 static int
4124 mod_mbedtls_ssl_conf_curves(server *srv, plugin_config_socket *s, const buffer *curvelist)
4125 {
4126     uint16_t ids[512];
4127     int nids = -1;
4128     const int idsz = (int)(sizeof(ids)/sizeof(*ids)-1);
4129     const mbedtls_ecp_curve_info * const curve_info = mbedtls_ecp_curve_list();
4130 
4131     const buffer * const b = curvelist;
4132     for (const char *e = b->ptr-1; e; ) {
4133         const char * const n = e+1;
4134         e = strchr(n, ':');
4135         size_t len = e ? (size_t)(e - n) : strlen(n);
4136         /* similar to mbedtls_ecp_curve_info_from_name() */
4137         const mbedtls_ecp_curve_info *info;
4138         for (info = curve_info; info->tls_id != 0; ++info) {
4139             if (0 == strncmp(info->name, n, len) && info->name[len] == '\0')
4140                 break;
4141         }
4142         if (info->tls_id == 0) {
4143             log_error(srv->errh, __FILE__, __LINE__,
4144                       "MTLS: unrecognized curve: %.*s; ignored", (int)len, n);
4145             continue;
4146         }
4147 
4148         nids = mod_mbedtls_ssl_append_curve(srv, ids, nids, idsz, info->tls_id);
4149         if (-1 == nids) return 0;
4150     }
4151 
4152     /* XXX: mod_openssl configures "prime256v1" if curve list not specified,
4153      * but mbedtls provides a list of supported curves if not explicitly set */
4154     if (-1 == nids) return 1; /* empty list; no-op */
4155 
4156     ids[++nids] = 0; /* terminate list */
4157     ++nids;
4158 
4159     /* curves list must be persistent for lifetime of mbedtls_ssl_config */
4160     s->curves = malloc(nids * sizeof(uint16_t));
4161     force_assert(s->curves);
4162     memcpy(s->curves, ids, nids * sizeof(uint16_t));
4163 
4164     mbedtls_ssl_conf_groups(s->ssl_ctx, s->curves);
4165     return 1;
4166 }
4167 #endif /* MBEDTLS_VERSION_NUMBER >= 0x03010000 */ /* mbedtls 3.01.0 */
4168 
4169 
4170 #if MBEDTLS_VERSION_NUMBER < 0x03020000 /* mbedtls 3.02.0 */
4171 static void
4172 mod_mbedtls_ssl_conf_proto (server *srv, plugin_config_socket *s, const buffer *b, int max)
4173 {
4174     int v = MBEDTLS_SSL_MINOR_VERSION_3; /* default: TLS v1.2 */
4175     if (NULL == b) /* default: min TLSv1.2, max TLSv1.3 */
4176       #ifdef MBEDTLS_SSL_MINOR_VERSION_4
4177         v = max ? MBEDTLS_SSL_MINOR_VERSION_4 : MBEDTLS_SSL_MINOR_VERSION_3;
4178       #else
4179         v = MBEDTLS_SSL_MINOR_VERSION_3;
4180       #endif
4181     else if (buffer_eq_icase_slen(b, CONST_STR_LEN("None"))) /*"disable" limit*/
4182         v = max
4183           ?
4184            #ifdef MBEDTLS_SSL_MINOR_VERSION_4
4185             MBEDTLS_SSL_MINOR_VERSION_4  /* TLS v1.3 */
4186            #else
4187             MBEDTLS_SSL_MINOR_VERSION_3  /* TLS v1.2 */
4188            #endif
4189           :
4190            #if defined(MBEDTLS_SSL_MINOR_VERSION_0) \
4191             || defined(MBEDTLS_SSL_MINOR_VERSION_1)
4192             s->ssl_use_sslv3
4193               ?
4194                #ifdef MBEDTLS_SSL_MINOR_VERSION_0
4195                 MBEDTLS_SSL_MINOR_VERSION_0  /* SSL v3.0 */
4196                #else
4197                 MBEDTLS_SSL_MINOR_VERSION_1  /* TLS v1.0 */
4198                #endif
4199               : MBEDTLS_SSL_MINOR_VERSION_1  /* TLS v1.0 */
4200            #elif defined(MBEDTLS_SSL_MINOR_VERSION_2)
4201             MBEDTLS_SSL_MINOR_VERSION_2      /* TLS v1.1 */
4202            #else
4203             MBEDTLS_SSL_MINOR_VERSION_3      /* TLS v1.2 */
4204            #endif
4205             ;
4206   #ifdef MBEDTLS_SSL_MINOR_VERSION_0
4207     else if (buffer_eq_icase_slen(b, CONST_STR_LEN("SSLv3")))
4208         v = MBEDTLS_SSL_MINOR_VERSION_0; /* SSL v3.0 */
4209   #endif
4210   #ifdef MBEDTLS_SSL_MINOR_VERSION_1
4211     else if (buffer_eq_icase_slen(b, CONST_STR_LEN("TLSv1.0")))
4212         v = MBEDTLS_SSL_MINOR_VERSION_1; /* TLS v1.0 */
4213   #endif
4214   #ifdef MBEDTLS_SSL_MINOR_VERSION_2
4215     else if (buffer_eq_icase_slen(b, CONST_STR_LEN("TLSv1.1")))
4216         v = MBEDTLS_SSL_MINOR_VERSION_2; /* TLS v1.1 */
4217   #endif
4218   #ifdef MBEDTLS_SSL_MINOR_VERSION_3
4219     else if (buffer_eq_icase_slen(b, CONST_STR_LEN("TLSv1.2")))
4220         v = MBEDTLS_SSL_MINOR_VERSION_3; /* TLS v1.2 */
4221   #endif
4222   #ifdef MBEDTLS_SSL_MINOR_VERSION_4
4223     else if (buffer_eq_icase_slen(b, CONST_STR_LEN("TLSv1.3")))
4224         v = MBEDTLS_SSL_MINOR_VERSION_4; /* TLS v1.3 */
4225   #endif
4226     else {
4227       #ifndef MBEDTLS_SSL_MINOR_VERSION_4
4228         if (buffer_eq_icase_slen(b, CONST_STR_LEN("TLSv1.3")))
4229             log_error(srv->errh, __FILE__, __LINE__,
4230                       "MTLS: ssl.openssl.ssl-conf-cmd %s TLSv1.3 not supported "
4231                       "by mod_mbedtls; using TLSv1.2",
4232                       max ? "MaxProtocol" : "MinProtocol");
4233         else
4234       #endif
4235         if (buffer_eq_icase_slen(b, CONST_STR_LEN("DTLSv1"))
4236                  || buffer_eq_icase_slen(b, CONST_STR_LEN("DTLSv1.2"))) {
4237             log_error(srv->errh, __FILE__, __LINE__,
4238                       "MTLS: ssl.openssl.ssl-conf-cmd %s %s ignored",
4239                       max ? "MaxProtocol" : "MinProtocol", b->ptr);
4240             return;
4241         }
4242         else {
4243             log_error(srv->errh, __FILE__, __LINE__,
4244                       "MTLS: ssl.openssl.ssl-conf-cmd %s %s invalid; ignored",
4245                       max ? "MaxProtocol" : "MinProtocol", b->ptr);
4246             return;
4247         }
4248     }
4249 
4250     max
4251       ? mbedtls_ssl_conf_max_version(s->ssl_ctx,MBEDTLS_SSL_MAJOR_VERSION_3,v)
4252       : mbedtls_ssl_conf_min_version(s->ssl_ctx,MBEDTLS_SSL_MAJOR_VERSION_3,v);
4253 }
4254 #else /* MBEDTLS_VERSION_NUMBER >= 0x03020000 */ /* mbedtls 3.02.0 */
4255 static void
4256 mod_mbedtls_ssl_conf_proto (server *srv, plugin_config_socket *s, const buffer *b, int max)
4257 {
4258     int v = MBEDTLS_SSL_VERSION_TLS1_2; /* default: TLS v1.2 */
4259     if (NULL == b) /* default: min TLSv1.2, max TLSv1.3 */
4260         v = max ? MBEDTLS_SSL_VERSION_TLS1_3 : MBEDTLS_SSL_VERSION_TLS1_2;
4261     else if (buffer_eq_icase_slen(b, CONST_STR_LEN("None"))) /*"disable" limit*/
4262         v = max ? MBEDTLS_SSL_VERSION_TLS1_3 : MBEDTLS_SSL_VERSION_TLS1_2;
4263     else if (buffer_eq_icase_slen(b, CONST_STR_LEN("TLSv1.2")))
4264         v = MBEDTLS_SSL_VERSION_TLS1_2;
4265     else if (buffer_eq_icase_slen(b, CONST_STR_LEN("TLSv1.3")))
4266         v = MBEDTLS_SSL_VERSION_TLS1_3;
4267     else {
4268         if (buffer_eq_icase_slen(b, CONST_STR_LEN("DTLSv1"))
4269             || buffer_eq_icase_slen(b, CONST_STR_LEN("DTLSv1.2"))) {
4270             log_error(srv->errh, __FILE__, __LINE__,
4271                       "MTLS: ssl.openssl.ssl-conf-cmd %s %s ignored",
4272                       max ? "MaxProtocol" : "MinProtocol", b->ptr);
4273             return;
4274         }
4275         else {
4276             log_error(srv->errh, __FILE__, __LINE__,
4277                       "MTLS: ssl.openssl.ssl-conf-cmd %s %s invalid; ignored",
4278                       max ? "MaxProtocol" : "MinProtocol", b->ptr);
4279             return;
4280         }
4281     }
4282 
4283     max
4284       ? mbedtls_ssl_conf_max_tls_version(s->ssl_ctx, v)
4285       : mbedtls_ssl_conf_min_tls_version(s->ssl_ctx, v);
4286 }
4287 #endif /* MBEDTLS_VERSION_NUMBER >= 0x03020000 */ /* mbedtls 3.02.0 */
4288 
4289 #if MBEDTLS_VERSION_NUMBER < 0x03000000 /* mbedtls 3.00.0 */
4290 #ifdef MBEDTLS_SSL_SERVER_NAME_INDICATION
4291 #ifdef MBEDTLS_SSL_ALPN
4292 /*
4293  * XXX: forked from mbedtls
4294  *
4295  * ssl_parse_client_hello() is forked and modified from mbedtls
4296  *   library/ssl_srv.c:ssl_parse_client_hello()
4297  * due to limitations in mbedtls hooks.  Other than fetching input, ssl is not
4298  * modified here so that it can be reprocessed during handshake.
4299  *
4300  * It would be beneficial to have a callback after parsing client hello and all
4301  * extensions, and before certificate selection.  (SNI extension might occur
4302  * prior to ALPN extension, and a different certificate may be needed by
4303  * ALPN "acme-tls/1".)  Alternatively, mbedtls could provide an API to clear
4304  * &ssl->handshake->sni_key_cert, rather than forcing ssl_append_key_cert() with
4305  * no other option.
4306  */
4307 static int ssl_parse_client_hello( mbedtls_ssl_context *ssl, handler_ctx *hctx )
4308 {
4309     int ret;
4310     size_t msg_len;
4311     unsigned char *buf;
4312 
4313     /*
4314      * If renegotiating, then the input was read with mbedtls_ssl_read_record(),
4315      * otherwise read it ourselves manually in order to support SSLv2
4316      * ClientHello, which doesn't use the same record layer format.
4317      */
4318 #if defined(MBEDTLS_SSL_RENEGOTIATION)
4319     if( ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE )
4320 #endif
4321     {
4322         if( ( ret = mbedtls_ssl_fetch_input( ssl, 5 ) ) != 0 )
4323         {
4324             /* No alert on a read error. */
4325             MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_fetch_input", ret );
4326             return( ret );
4327         }
4328     }
4329 
4330     buf = ssl->in_hdr;
4331 
4332     /*
4333      * TLS Client Hello
4334      *
4335      * Record layer:
4336      *     0  .   0   message type
4337      *     1  .   2   protocol version
4338      *     3  .   11  DTLS: epoch + record sequence number
4339      *     3  .   4   message length
4340      */
4341     if( buf[0] != MBEDTLS_SSL_MSG_HANDSHAKE )
4342     {
4343         return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
4344     }
4345 
4346 #if defined(MBEDTLS_SSL_PROTO_DTLS)
4347     /*(not supported in lighttpd for now)*/
4348     /*(mbedtls_ssl_in_hdr_len() and mbedtls_ssl_hs_hdr_len() are in
4349      * mbedtls/ssl_internal.h but simple enough to repeat here) */
4350     if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
4351         return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
4352 #endif /* MBEDTLS_SSL_PROTO_DTLS */
4353 
4354     msg_len = ( ssl->in_len[0] << 8 ) | ssl->in_len[1];
4355 
4356 #if defined(MBEDTLS_SSL_RENEGOTIATION)
4357     if( ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE )
4358     {
4359         /* Set by mbedtls_ssl_read_record() */
4360         msg_len = ssl->in_hslen;
4361     }
4362     else
4363 #endif
4364     {
4365         if( msg_len > MBEDTLS_SSL_IN_CONTENT_LEN )
4366         {
4367             return( MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER );
4368         }
4369 
4370         if( ( ret = mbedtls_ssl_fetch_input( ssl,
4371                        5 /*mbedtls_ssl_in_hdr_len( ssl )*/ + msg_len ) ) != 0 )
4372         {
4373             MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_fetch_input", ret );
4374             return( ret );
4375         }
4376     }
4377 
4378     buf = ssl->in_msg;
4379 
4380     /*
4381      * Handshake layer:
4382      *     0  .   0   handshake type
4383      *     1  .   3   handshake length
4384      *     4  .   5   DTLS only: message seqence number
4385      *     6  .   8   DTLS only: fragment offset
4386      *     9  .  11   DTLS only: fragment length
4387      */
4388     if( msg_len < 4 /*mbedtls_ssl_hs_hdr_len( ssl )*/ )
4389     {
4390         return( MBEDTLS_ERR_SSL_DECODE_ERROR );
4391     }
4392 
4393     if( buf[0] != MBEDTLS_SSL_HS_CLIENT_HELLO )
4394     {
4395         return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
4396     }
4397 
4398     /* We don't support fragmentation of ClientHello (yet?) */
4399     if( buf[1] != 0 ||
4400         msg_len != 4u /*mbedtls_ssl_hs_hdr_len( ssl )*/ + ( ( buf[2] << 8 ) | buf[3] ) )
4401     {
4402         return( MBEDTLS_ERR_SSL_DECODE_ERROR );
4403     }
4404 
4405     buf += 4; /* mbedtls_ssl_hs_hdr_len( ssl ); */
4406     msg_len -= 4; /* mbedtls_ssl_hs_hdr_len( ssl ); */
4407 
4408     /*
4409      * ClientHello layer:
4410      *     0  .   1   protocol version
4411      *     2  .  33   random bytes (starting with 4 bytes of Unix time)
4412      *    34  .  35   session id length (1 byte)
4413      *    35  . 34+x  session id
4414      *   35+x . 35+x  DTLS only: cookie length (1 byte)
4415      *   36+x .  ..   DTLS only: cookie
4416      *    ..  .  ..   ciphersuite list length (2 bytes)
4417      *    ..  .  ..   ciphersuite list
4418      *    ..  .  ..   compression alg. list length (1 byte)
4419      *    ..  .  ..   compression alg. list
4420      *    ..  .  ..   extensions length (2 bytes, optional)
4421      *    ..  .  ..   extensions (optional)
4422      */
4423 
4424     /*
4425      * Minimal length (with everything empty and extensions omitted) is
4426      * 2 + 32 + 1 + 2 + 1 = 38 bytes. Check that first, so that we can
4427      * read at least up to session id length without worrying.
4428      */
4429     if( msg_len < 38 )
4430     {
4431         return( MBEDTLS_ERR_SSL_DECODE_ERROR );
4432     }
4433 
4434     /*
4435      * Check and save the protocol version
4436      */
4437     int major_ver, minor_ver;
4438     mbedtls_ssl_read_version( &major_ver, &minor_ver,
4439                       ssl->conf->transport, buf );
4440 
4441     /*
4442      * Check the session ID length and save session ID
4443      */
4444     const size_t sess_len = buf[34];
4445 
4446     if( sess_len > sizeof( ssl->session_negotiate->id ) ||
4447         sess_len + 34 + 2 > msg_len ) /* 2 for cipherlist length field */
4448     {
4449         return( MBEDTLS_ERR_SSL_DECODE_ERROR );
4450     }
4451 
4452     /*
4453      * Check the cookie length and content
4454      */
4455     const size_t ciph_offset = 35 + sess_len;
4456 
4457     const size_t ciph_len = ( buf[ciph_offset + 0] << 8 )
4458                           | ( buf[ciph_offset + 1]      );
4459 
4460     if( ciph_len < 2 ||
4461         ciph_len + 2 + ciph_offset + 1 > msg_len || /* 1 for comp. alg. len */
4462         ( ciph_len % 2 ) != 0 )
4463     {
4464         return( MBEDTLS_ERR_SSL_DECODE_ERROR );
4465     }
4466 
4467     /*
4468      * Check the compression algorithms length and pick one
4469      */
4470     const size_t comp_offset = ciph_offset + 2 + ciph_len;
4471 
4472     const size_t comp_len = buf[comp_offset];
4473 
4474     if( comp_len < 1 ||
4475         comp_len > 16 ||
4476         comp_len + comp_offset + 1 > msg_len )
4477     {
4478         return( MBEDTLS_ERR_SSL_DECODE_ERROR );
4479     }
4480 
4481     /* Do not parse the extensions if the protocol is SSLv3 */
4482 #if defined(MBEDTLS_SSL_PROTO_SSL3)
4483     if( ( major_ver != 3 ) || ( minor_ver != 0 ) )
4484     {
4485 #endif
4486         /*
4487          * Check the extension length
4488          */
4489         const size_t ext_offset = comp_offset + 1 + comp_len;
4490         size_t ext_len;
4491         if( msg_len > ext_offset )
4492         {
4493             if( msg_len < ext_offset + 2 )
4494             {
4495                 return( MBEDTLS_ERR_SSL_DECODE_ERROR );
4496             }
4497 
4498             ext_len = ( buf[ext_offset + 0] << 8 )
4499                     | ( buf[ext_offset + 1]      );
4500 
4501             if( msg_len != ext_offset + 2 + ext_len )
4502             {
4503                 return( MBEDTLS_ERR_SSL_DECODE_ERROR );
4504             }
4505         }
4506         else
4507             ext_len = 0;
4508 
4509         unsigned char *ext = buf + ext_offset + 2;
4510 
4511         while( ext_len != 0 )
4512         {
4513             unsigned int ext_id;
4514             unsigned int ext_size;
4515             if ( ext_len < 4 ) {
4516                 return( MBEDTLS_ERR_SSL_DECODE_ERROR );
4517             }
4518             ext_id   = ( ( ext[0] <<  8 ) | ( ext[1] ) );
4519             ext_size = ( ( ext[2] <<  8 ) | ( ext[3] ) );
4520 
4521             if( ext_size + 4 > ext_len )
4522             {
4523                 return( MBEDTLS_ERR_SSL_DECODE_ERROR );
4524             }
4525             switch( ext_id )
4526             {
4527 #if defined(MBEDTLS_SSL_ALPN)
4528             case MBEDTLS_TLS_EXT_ALPN:
4529                 MBEDTLS_SSL_DEBUG_MSG( 3, ( "found alpn extension" ) );
4530 
4531                 /*(lighttpd-specific)*/
4532                 ret = mod_mbedtls_alpn_select_cb(hctx, ext + 4, ext_size);
4533                 if( ret != 0 )
4534                     return( ret );
4535                 break;
4536 #endif /* MBEDTLS_SSL_ALPN */
4537 
4538             default:
4539                 break;
4540             }
4541 
4542             ext_len -= 4 + ext_size;
4543             ext += 4 + ext_size;
4544         }
4545 #if defined(MBEDTLS_SSL_PROTO_SSL3)
4546     }
4547 #endif
4548 
4549     return( 0 );
4550 }
4551 #endif /* MBEDTLS_SSL_ALPN */
4552 #endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
4553 #endif /* MBEDTLS_VERSION_NUMBER < 0x03000000 */ /* mbedtls 3.00.0 */
4554