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