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