xref: /lighttpd1.4/src/mod_wolfssl.c (revision 4933a225)
1 /*
2  * mod_wolfssl - wolfSSL 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  * Note: If session tickets are -not- disabled with
9  *     ssl.openssl.ssl-conf-cmd = ("Options" => "-SessionTicket")
10  *   mod_wolfssl rotates server ticket encryption key (STEK) every 8 hours
11  *   and keeps the prior two STEKs around, so ticket lifetime is 24 hours.
12  *   This is fine for use with a single lighttpd instance, but with multiple
13  *   lighttpd workers, no coordinated STEK (server ticket encryption key)
14  *   rotation occurs unless ssl.stek-file is defined and maintained (preferred),
15  *   or if some external job restarts lighttpd.  Restarting lighttpd generates a
16  *   new key that is shared by lighttpd workers for the lifetime of the new key.
17  *   If the rotation period expires and lighttpd has not been restarted, and if
18  *   ssl.stek-file is not in use, then lighttpd workers will generate new
19  *   independent keys, making session tickets less effective for session
20  *   resumption, since clients have a lower chance for future connections to
21  *   reach the same lighttpd worker.  However, things will still work, and a new
22  *   session will be created if session resumption fails.  Admins should plan to
23  *   restart lighttpd at least every 8 hours if session tickets are enabled and
24  *   multiple lighttpd workers are configured.  Since that is likely disruptive,
25  *   if multiple lighttpd workers are configured, ssl.stek-file should be
26  *   defined and the file maintained externally.
27  */
28 #include "first.h"
29 
30 #include <sys/types.h>
31 #include <sys/stat.h>
32 #include <errno.h>
33 #include <fcntl.h>
34 #include <stdint.h>
35 #include <stdlib.h>
36 #include <string.h>
37 
38 /*
39  * Note: mod_wolfssl.c is forked from mod_openssl.c
40  * Many internal symbol names in mod_wolfssl.c retain the mod_openssl_* prefix
41  * (wolfSSL provides an OpenSSL compatibility layer)
42  */
43 
44 /* wolfSSL needs to be built with ./configure --enable-lighty for lighttpd.
45  * Doing so defines OPENSSL_EXTRA and HAVE_LIGHTY in <wolfssl/options.h>, and
46  * these defines are necessary for wolfSSL headers to expose sufficient openssl
47  * compatibility layer for wolfSSL to be able to provide an openssl substitute
48  * for use by lighttpd */
49 
50 /* workaround fragile code in wolfssl/wolfcrypto/types.h */
51 #if !defined(SIZEOF_LONG) || !defined(SIZEOF_LONG_LONG)
52 #undef SIZEOF_LONG
53 #undef SIZEOF_LONG_LONG
54 #endif
55 
56 #include <wolfssl/options.h>
57 #include <wolfssl/ssl.h>
58 
59 static char global_err_buf[WOLFSSL_MAX_ERROR_SZ];
60 #undef ERR_error_string
61 #define ERR_error_string(e,b) \
62         (wolfSSL_ERR_error_string_n((e),global_err_buf,WOLFSSL_MAX_ERROR_SZ), \
63          global_err_buf)
64 /* WolfSSL does not provide OPENSSL_cleanse() */
65 #define OPENSSL_cleanse(x,sz) safe_memclear((x),(sz))
66 
67 #if 0 /* symbols and definitions requires WolfSSL built with -DOPENSSL_EXTRA */
68 #define SSL_TLSEXT_ERR_OK               0
69 #define SSL_TLSEXT_ERR_ALERT_FATAL      alert_fatal
70 #define SSL_TLSEXT_ERR_NOACK            alert_warning
71 
72 WOLFSSL_API void wolfSSL_set_verify_depth(WOLFSSL *ssl,int depth);
73 
74 WOLFSSL_API void wolfSSL_X509_NAME_free(WOLFSSL_X509_NAME* name);
75 WOLFSSL_API int wolfSSL_X509_NAME_cmp(const WOLFSSL_X509_NAME* x, const WOLFSSL_X509_NAME* y);
76 WOLFSSL_API WOLFSSL_X509_NAME* wolfSSL_X509_NAME_dup(WOLFSSL_X509_NAME*);
77 WOLFSSL_API char* wolfSSL_X509_get_name_oneline(WOLFSSL_X509_NAME*, char*, int);
78 
79 WOLFSSL_API const char* wolfSSL_OBJ_nid2sn(int n);
80 WOLFSSL_API int wolfSSL_OBJ_obj2nid(const WOLFSSL_ASN1_OBJECT *o);
81 WOLFSSL_API WOLFSSL_ASN1_OBJECT * wolfSSL_X509_NAME_ENTRY_get_object(WOLFSSL_X509_NAME_ENTRY *ne);
82 WOLFSSL_API WOLFSSL_X509_NAME_ENTRY *wolfSSL_X509_NAME_get_entry(WOLFSSL_X509_NAME *name, int loc);
83 #endif
84 
85 #ifndef OPENSSL_ALL
86 /*(invalid; but centralize making these calls no-ops)*/
87 #define wolfSSL_sk_X509_NAME_num(a)          0
88 #define wolfSSL_sk_X509_NAME_push(a, b)      0
89 #define wolfSSL_sk_X509_NAME_pop_free(a, b)  do { } while (0)
90 #define wolfSSL_sk_X509_NAME_free(a)         do { } while (0)
91 #define wolfSSL_X509_get_subject_name(ca) \
92         ((WOLFSSL_X509_NAME *)1) /* ! NULL */
93 #define wolfSSL_sk_X509_NAME_new(a) \
94         ((WOLF_STACK_OF(WOLFSSL_X509_NAME) *)1) /* ! NULL */
95 #endif
96 
97 #include "base.h"
98 #include "fdevent.h"
99 #include "http_header.h"
100 #include "http_kv.h"
101 #include "log.h"
102 #include "plugin.h"
103 #include "safe_memclear.h"
104 
105 typedef struct {
106     /* SNI per host: with COMP_SERVER_SOCKET, COMP_HTTP_SCHEME, COMP_HTTP_HOST */
107     buffer *ssl_pemfile_pkey;
108     buffer *ssl_pemfile_x509;
109     buffer **ssl_pemfile_chain;
110     buffer *ssl_stapling;
111     const buffer *ssl_pemfile;
112     const buffer *ssl_privkey;
113     const buffer *ssl_stapling_file;
114     time_t ssl_stapling_loadts;
115     time_t ssl_stapling_nextts;
116     char must_staple;
117 } plugin_cert;
118 
119 typedef struct {
120     WOLFSSL_CTX *ssl_ctx;
121 } plugin_ssl_ctx;
122 
123 typedef struct {
124     STACK_OF(X509_NAME) *names;
125     X509_STORE *certs;
126 } plugin_cacerts;
127 
128 typedef struct {
129     WOLFSSL_CTX *ssl_ctx; /* output from network_init_ssl() */
130 
131     /*(used only during startup; not patched)*/
132     unsigned char ssl_enabled; /* only interesting for setting up listening sockets. don't use at runtime */
133     unsigned char ssl_honor_cipher_order; /* determine SSL cipher in server-preferred order, not client-order */
134     unsigned char ssl_empty_fragments; /* whether to not set SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS */
135     unsigned char ssl_use_sslv2;
136     unsigned char ssl_use_sslv3;
137     const buffer *ssl_cipher_list;
138     const buffer *ssl_dh_file;
139     const buffer *ssl_ec_curve;
140     array *ssl_conf_cmd;
141 
142     /*(copied from plugin_data for socket ssl_ctx config)*/
143     const plugin_cert *pc;
144     const plugin_cacerts *ssl_ca_file;
145     STACK_OF(X509_NAME) *ssl_ca_dn_file;
146     const buffer *ssl_ca_crl_file;
147     unsigned char ssl_verifyclient;
148     unsigned char ssl_verifyclient_enforce;
149     unsigned char ssl_verifyclient_depth;
150     unsigned char ssl_read_ahead;
151     unsigned char ssl_disable_client_renegotiation;
152 } plugin_config_socket; /*(used at startup during configuration)*/
153 
154 typedef struct {
155     /* SNI per host: w/ COMP_SERVER_SOCKET, COMP_HTTP_SCHEME, COMP_HTTP_HOST */
156     plugin_cert *pc;
157     const plugin_cacerts *ssl_ca_file;
158     STACK_OF(X509_NAME) *ssl_ca_dn_file;
159     const buffer *ssl_ca_crl_file;
160 
161     unsigned char ssl_verifyclient;
162     unsigned char ssl_verifyclient_enforce;
163     unsigned char ssl_verifyclient_depth;
164     unsigned char ssl_verifyclient_export_cert;
165     unsigned char ssl_read_ahead;
166     unsigned char ssl_log_noise;
167     unsigned char ssl_disable_client_renegotiation;
168     const buffer *ssl_verifyclient_username;
169     const buffer *ssl_acme_tls_1;
170 } plugin_config;
171 
172 typedef struct {
173     PLUGIN_DATA;
174     plugin_ssl_ctx *ssl_ctxs;
175     plugin_config defaults;
176     server *srv;
177     array *cafiles;
178     const char *ssl_stek_file;
179 } plugin_data;
180 
181 static int ssl_is_init;
182 /* need assigned p->id for deep access of module handler_ctx for connection
183  *   i.e. handler_ctx *hctx = con->plugin_ctx[plugin_data_singleton->id]; */
184 static plugin_data *plugin_data_singleton;
185 #define LOCAL_SEND_BUFSIZE (16 * 1024)
186 static char *local_send_buffer;
187 
188 typedef struct {
189     WOLFSSL *ssl;
190     request_st *r;
191     connection *con;
192     short renegotiations; /* count of SSL_CB_HANDSHAKE_START */
193     short close_notify;
194     unsigned short alpn;
195     plugin_config conf;
196     buffer *tmp_buf;
197     log_error_st *errh;
198 } handler_ctx;
199 
200 
201 static handler_ctx *
202 handler_ctx_init (void)
203 {
204     handler_ctx *hctx = calloc(1, sizeof(*hctx));
205     force_assert(hctx);
206     return hctx;
207 }
208 
209 
210 static void
211 handler_ctx_free (handler_ctx *hctx)
212 {
213     if (hctx->ssl) SSL_free(hctx->ssl);
214     free(hctx);
215 }
216 
217 
218 #ifdef HAVE_SESSION_TICKET
219 /* ssl/ssl_local.h */
220 #define TLSEXT_KEYNAME_LENGTH  16
221 #define TLSEXT_TICK_KEY_LENGTH 32
222 
223 /* openssl has a huge number of interfaces, but not the most useful;
224  * construct our own session ticket encryption key structure */
225 typedef struct tlsext_ticket_key_st {
226     time_t active_ts; /* tickets not issued w/ key until activation timestamp */
227     time_t expire_ts; /* key not valid after expiration timestamp */
228     unsigned char tick_key_name[TLSEXT_KEYNAME_LENGTH];
229     unsigned char tick_hmac_key[TLSEXT_TICK_KEY_LENGTH];
230     unsigned char tick_aes_key[TLSEXT_TICK_KEY_LENGTH];
231 } tlsext_ticket_key_t;
232 
233 static tlsext_ticket_key_t session_ticket_keys[4];
234 static time_t stek_rotate_ts;
235 
236 
237 static int
238 mod_openssl_session_ticket_key_generate (time_t active_ts, time_t expire_ts)
239 {
240     /* openssl RAND_*bytes() functions are called multiple times since the
241      * funcs might have a 32-byte limit on number of bytes returned each call
242      *
243      * (Note: session ticket encryption key generation is not expected to fail)
244      *
245      * 3 keys are stored in session_ticket_keys[]
246      * The 4th element of session_ticket_keys[] is used for STEK construction
247      */
248     /*(RAND_priv_bytes() not in openssl 1.1.0; introduced in openssl 1.1.1)*/
249   #define RAND_priv_bytes(x,sz) RAND_bytes((x),(sz))
250     if (RAND_bytes(session_ticket_keys[3].tick_key_name,
251                    TLSEXT_KEYNAME_LENGTH) <= 0
252         || RAND_priv_bytes(session_ticket_keys[3].tick_hmac_key,
253                            TLSEXT_TICK_KEY_LENGTH) <= 0
254         || RAND_priv_bytes(session_ticket_keys[3].tick_aes_key,
255                            TLSEXT_TICK_KEY_LENGTH) <= 0)
256         return 0;
257     session_ticket_keys[3].active_ts = active_ts;
258     session_ticket_keys[3].expire_ts = expire_ts;
259     return 1;
260 }
261 
262 
263 static void
264 mod_openssl_session_ticket_key_rotate (void)
265 {
266     /* discard oldest key (session_ticket_keys[2]) and put newest key first
267      * 3 keys are stored in session_ticket_keys[0], [1], [2]
268      * session_ticket_keys[3] is used to construct and pass new STEK */
269 
270     session_ticket_keys[2] = session_ticket_keys[1];
271     session_ticket_keys[1] = session_ticket_keys[0];
272     /*memmove(session_ticket_keys+1,
273               session_ticket_keys+0, sizeof(tlsext_ticket_key_t)*2);*/
274     session_ticket_keys[0] = session_ticket_keys[3];
275 
276     OPENSSL_cleanse(session_ticket_keys+3, sizeof(tlsext_ticket_key_t));
277 }
278 
279 
280 static tlsext_ticket_key_t *
281 tlsext_ticket_key_get (void)
282 {
283     const time_t cur_ts = log_epoch_secs;
284     const int e = sizeof(session_ticket_keys)/sizeof(*session_ticket_keys) - 1;
285     for (int i = 0; i < e; ++i) {
286         if (session_ticket_keys[i].active_ts > cur_ts) continue;
287         if (session_ticket_keys[i].expire_ts < cur_ts) continue;
288         return &session_ticket_keys[i];
289     }
290     return NULL;
291 }
292 
293 
294 static tlsext_ticket_key_t *
295 tlsext_ticket_key_find (unsigned char key_name[16], int *refresh)
296 {
297     *refresh = 0;
298     const time_t cur_ts = log_epoch_secs;
299     const int e = sizeof(session_ticket_keys)/sizeof(*session_ticket_keys) - 1;
300     for (int i = 0; i < e; ++i) {
301         if (session_ticket_keys[i].expire_ts < cur_ts) continue;
302         if (0 == memcmp(session_ticket_keys[i].tick_key_name, key_name, 16))
303             return &session_ticket_keys[i];
304         if (session_ticket_keys[i].active_ts <= cur_ts)
305             *refresh = 1; /* newer active key is available */
306     }
307     return NULL;
308 }
309 
310 
311 static void
312 tlsext_ticket_wipe_expired (const time_t cur_ts)
313 {
314     const int e = sizeof(session_ticket_keys)/sizeof(*session_ticket_keys) - 1;
315     for (int i = 0; i < e; ++i) {
316         if (session_ticket_keys[i].expire_ts != 0
317             && session_ticket_keys[i].expire_ts < cur_ts)
318             OPENSSL_cleanse(session_ticket_keys+i, sizeof(tlsext_ticket_key_t));
319     }
320 }
321 
322 
323 /* based on reference implementation from openssl 1.1.1g man page
324  *   man SSL_CTX_set_tlsext_ticket_key_cb
325  * but openssl code uses EVP_aes_256_cbc() instead of EVP_aes_128_cbc()
326  */
327 static int
328 ssl_tlsext_ticket_key_cb (SSL *s, unsigned char key_name[16],
329                           unsigned char iv[EVP_MAX_IV_LENGTH],
330                           EVP_CIPHER_CTX *ctx, HMAC_CTX *hctx, int enc)
331 {
332     UNUSED(s);
333     if (enc) { /* create new session */
334         tlsext_ticket_key_t *k = tlsext_ticket_key_get();
335         if (NULL == k)
336             return 0; /* current key does not exist or is not valid */
337         memcpy(key_name, k->tick_key_name, 16);
338         if (RAND_bytes(iv, EVP_MAX_IV_LENGTH) <= 0)
339             return -1; /* insufficient random */
340         EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, k->tick_aes_key, iv);
341         HMAC_Init_ex(hctx, k->tick_hmac_key, sizeof(k->tick_hmac_key),
342                      EVP_sha256(), NULL);
343         return 1;
344     }
345     else { /* retrieve session */
346         int refresh;
347         tlsext_ticket_key_t *k = tlsext_ticket_key_find(key_name, &refresh);
348         if (NULL == k)
349             return 0;
350         HMAC_Init_ex(hctx, k->tick_hmac_key, sizeof(k->tick_hmac_key),
351                      EVP_sha256(), NULL);
352         EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, k->tick_aes_key, iv);
353         return refresh ? 2 : 1;
354         /* 'refresh' will trigger issuing new ticket for session
355          * even though the current ticket is still valid */
356     }
357 }
358 
359 
360 static int
361 mod_openssl_session_ticket_key_file (const char *fn)
362 {
363     /* session ticket encryption key (STEK)
364      *
365      * STEK file should be stored in non-persistent storage,
366      *   e.g. /dev/shm/lighttpd/stek-file  (in memory)
367      * with appropriate permissions set to keep stek-file from being
368      * read by other users.  Where possible, systems should also be
369      * configured without swap.
370      *
371      * admin should schedule an independent job to periodically
372      *   generate new STEK up to 3 times during key lifetime
373      *   (lighttpd stores up to 3 keys)
374      *
375      * format of binary file is:
376      *    4-byte - format version (always 0; for use if format changes)
377      *    4-byte - activation timestamp
378      *    4-byte - expiration timestamp
379      *   16-byte - session ticket key name
380      *   32-byte - session ticket HMAC encrpytion key
381      *   32-byte - session ticket AES encrpytion key
382      *
383      * STEK file can be created with a command such as:
384      *   dd if=/dev/random bs=1 count=80 status=none | \
385      *     perl -e 'print pack("iii",0,time()+300,time()+86400),<>' \
386      *     > STEK-file.$$ && mv STEK-file.$$ STEK-file
387      *
388      * The above delays activation time by 5 mins (+300 sec) to allow file to
389      * be propagated to other machines.  (admin must handle this independently)
390      * If STEK generation is performed immediately prior to starting lighttpd,
391      * admin should activate keys immediately (without +300).
392      */
393     int buf[23]; /* 92 bytes */
394     int rc = 0; /*(will retry on next check interval upon any error)*/
395     if (0 != fdevent_load_file_bytes((char *)buf,(off_t)sizeof(buf),0,fn,NULL))
396         return rc;
397     if (buf[0] == 0) { /*(format version 0)*/
398         session_ticket_keys[3].active_ts = buf[1];
399         session_ticket_keys[3].expire_ts = buf[2];
400       #ifndef __COVERITY__ /* intentional; hide from Coverity Scan */
401         /* intentionally copy 80 bytes into consecutive arrays
402          * tick_key_name[], tick_hmac_key[], tick_aes_key[] */
403         memcpy(&session_ticket_keys[3].tick_key_name, buf+3, 80);
404       #endif
405         rc = 1;
406     }
407 
408     OPENSSL_cleanse(buf, sizeof(buf));
409     return rc;
410 }
411 
412 
413 static void
414 mod_openssl_session_ticket_key_check (const plugin_data *p, const time_t cur_ts)
415 {
416     int rotate = 0;
417     if (p->ssl_stek_file) {
418         struct stat st;
419         if (0 == stat(p->ssl_stek_file, &st) && st.st_mtime > stek_rotate_ts)
420             rotate = mod_openssl_session_ticket_key_file(p->ssl_stek_file);
421         tlsext_ticket_wipe_expired(cur_ts);
422     }
423     else if (cur_ts - 28800 >= stek_rotate_ts)     /*(8 hours)*/
424         rotate = mod_openssl_session_ticket_key_generate(cur_ts, cur_ts+86400);
425 
426     if (rotate) {
427         mod_openssl_session_ticket_key_rotate();
428         stek_rotate_ts = cur_ts;
429     }
430 }
431 
432 #endif /* HAVE_SESSION_TICKET */
433 
434 
435 #ifdef HAVE_OCSP
436 static int
437 ssl_tlsext_status_cb(SSL *ssl, void *arg)
438 {
439   #ifdef SSL_get_tlsext_status_type
440     if (TLSEXT_STATUSTYPE_ocsp != SSL_get_tlsext_status_type(ssl))
441         return SSL_TLSEXT_ERR_NOACK; /* ignore if not client OCSP request */
442   #endif
443 
444     handler_ctx *hctx = (handler_ctx *) SSL_get_app_data(ssl);
445     buffer *ssl_stapling = hctx->conf.pc->ssl_stapling;
446     if (NULL == ssl_stapling) return SSL_TLSEXT_ERR_NOACK;
447     UNUSED(arg);
448 
449     int len = (int)buffer_string_length(ssl_stapling);
450 
451     /* WolfSSL does not require copy */
452     uint8_t *ocsp_resp = (uint8_t *)ssl_stapling->ptr;
453 
454     if (!SSL_set_tlsext_status_ocsp_resp(ssl, ocsp_resp, len)) {
455         log_error(hctx->r->conf.errh, __FILE__, __LINE__,
456           "SSL: failed to set OCSP response for TLS server name %s: %s",
457           hctx->r->uri.authority.ptr, ERR_error_string(ERR_get_error(), NULL));
458         return SSL_TLSEXT_ERR_NOACK; /* ignore OCSP request if error occurs */
459         /*return SSL_TLSEXT_ERR_ALERT_FATAL;*/
460     }
461     return SSL_TLSEXT_ERR_OK;
462 }
463 #endif
464 
465 
466 INIT_FUNC(mod_openssl_init)
467 {
468     plugin_data_singleton = (plugin_data *)calloc(1, sizeof(plugin_data));
469   #ifdef DEBUG_WOLFSSL
470     wolfSSL_Debugging_ON();
471   #endif
472     return plugin_data_singleton;
473 }
474 
475 
476 static int mod_openssl_init_once_openssl (server *srv)
477 {
478     if (ssl_is_init) return 1;
479 
480     if (wolfSSL_Init() != WOLFSSL_SUCCESS) {
481         log_error(srv->errh, __FILE__, __LINE__,
482           "SSL: wolfSSL_Init() failed");
483         return 0;
484     }
485     ssl_is_init = 1;
486 
487     if (0 == RAND_status()) {
488         log_error(srv->errh, __FILE__, __LINE__,
489           "SSL: not enough entropy in the pool");
490         return 0;
491     }
492 
493     local_send_buffer = malloc(LOCAL_SEND_BUFSIZE);
494     force_assert(NULL != local_send_buffer);
495 
496     return 1;
497 }
498 
499 
500 static void mod_openssl_free_openssl (void)
501 {
502     if (!ssl_is_init) return;
503 
504   #ifdef HAVE_SESSION_TICKET
505     OPENSSL_cleanse(session_ticket_keys, sizeof(session_ticket_keys));
506     stek_rotate_ts = 0;
507   #endif
508 
509     if (wolfSSL_Cleanup() != WOLFSSL_SUCCESS) {
510         log_error(plugin_data_singleton->srv->errh, __FILE__, __LINE__,
511           "SSL: wolfSSL_Cleanup() failed");
512     }
513 
514     free(local_send_buffer);
515     ssl_is_init = 0;
516 }
517 
518 
519 static void
520 mod_wolfssl_free_der_certs (buffer **certs)
521 {
522     if (NULL == certs) return;
523     for (int i = 0; NULL != certs[i]; ++i)
524         buffer_free(certs[i]);
525     free(certs);
526 }
527 
528 
529 static void
530 mod_openssl_free_config (server *srv, plugin_data * const p)
531 {
532     array_free(p->cafiles);
533 
534     if (NULL != p->ssl_ctxs) {
535         SSL_CTX * const ssl_ctx_global_scope = p->ssl_ctxs->ssl_ctx;
536         /* free ssl_ctx from $SERVER["socket"] (if not copy of global scope) */
537         for (uint32_t i = 1; i < srv->config_context->used; ++i) {
538             plugin_ssl_ctx * const s = p->ssl_ctxs + i;
539             if (s->ssl_ctx && s->ssl_ctx != ssl_ctx_global_scope)
540                 SSL_CTX_free(s->ssl_ctx);
541         }
542         /* free ssl_ctx from global scope */
543         if (ssl_ctx_global_scope)
544             SSL_CTX_free(ssl_ctx_global_scope);
545         free(p->ssl_ctxs);
546     }
547 
548     if (NULL == p->cvlist) return;
549     /* (init i to 0 if global context; to 1 to skip empty global context) */
550     for (int i = !p->cvlist[0].v.u2[1], used = p->nconfig; i < used; ++i) {
551         config_plugin_value_t *cpv = p->cvlist + p->cvlist[i].v.u2[0];
552         for (; -1 != cpv->k_id; ++cpv) {
553             switch (cpv->k_id) {
554               case 0: /* ssl.pemfile */
555                 if (cpv->vtype == T_CONFIG_LOCAL) {
556                     plugin_cert *pc = cpv->v.v;
557                     buffer_free(pc->ssl_pemfile_pkey);
558                     /*buffer_free(pc->ssl_pemfile_x509);*//*(part of chain)*/
559                     mod_wolfssl_free_der_certs(pc->ssl_pemfile_chain);
560                     buffer_free(pc->ssl_stapling);
561                     free(pc);
562                 }
563                 break;
564               case 2: /* ssl.ca-file */
565                 if (cpv->vtype == T_CONFIG_LOCAL) {
566                     plugin_cacerts *cacerts = cpv->v.v;
567                     wolfSSL_sk_X509_NAME_pop_free(cacerts->names,
568                                                   X509_NAME_free);
569                     X509_STORE_free(cacerts->certs);
570                     free(cacerts);
571                 }
572                 break;
573               case 3: /* ssl.ca-dn-file */
574                 if (cpv->vtype == T_CONFIG_LOCAL)
575                     wolfSSL_sk_X509_NAME_pop_free(cpv->v.v, X509_NAME_free);
576                 break;
577               default:
578                 break;
579             }
580         }
581     }
582 }
583 
584 
585 /* WolfSSL OpenSSL compat API does not wipe temp mem used; write our own */
586 /* (pemfile might contain private key)*/
587 /* code here is based on similar code in mod_nss */
588 #include "base64.h"
589 
590 #define PEM_BEGIN          "-----BEGIN "
591 #define PEM_END            "-----END "
592 #define PEM_BEGIN_CERT     "-----BEGIN CERTIFICATE-----"
593 #define PEM_END_CERT       "-----END CERTIFICATE-----"
594 #define PEM_BEGIN_TRUSTED_CERT "-----BEGIN TRUSTED CERTIFICATE-----"
595 #define PEM_END_TRUSTED_CERT   "-----END TRUSTED CERTIFICATE-----"
596 #define PEM_BEGIN_PKEY     "-----BEGIN PRIVATE KEY-----"
597 #define PEM_END_PKEY       "-----END PRIVATE KEY-----"
598 #define PEM_BEGIN_EC_PKEY  "-----BEGIN EC PRIVATE KEY-----"
599 #define PEM_END_EC_PKEY    "-----END EC PRIVATE KEY-----"
600 #define PEM_BEGIN_RSA_PKEY "-----BEGIN RSA PRIVATE KEY-----"
601 #define PEM_END_RSA_PKEY   "-----END RSA PRIVATE KEY-----"
602 #define PEM_BEGIN_DSA_PKEY "-----BEGIN DSA PRIVATE KEY-----"
603 #define PEM_END_DSA_PKEY   "-----END DSA PRIVATE KEY-----"
604 #define PEM_BEGIN_ANY_PKEY "-----BEGIN ANY PRIVATE KEY-----"
605 #define PEM_END_ANY_PKEY   "-----END ANY PRIVATE KEY-----"
606 /* (not implemented: support to get password from user for encrypted key) */
607 #define PEM_BEGIN_ENCRYPTED_PKEY "-----BEGIN ENCRYPTED PRIVATE KEY-----"
608 #define PEM_END_ENCRYPTED_PKEY   "-----END ENCRYPTED PRIVATE KEY-----"
609 
610 #define PEM_BEGIN_X509_CRL "-----BEGIN X509 CRL-----"
611 #define PEM_END_X509_CRL   "-----END X509 CRL-----"
612 
613 
614 static buffer *
615 mod_wolfssl_load_pem_file (const char *fn, log_error_st *errh, buffer ***chain)
616 {
617     off_t dlen = 512*1024*1024;/*(arbitrary limit: 512 MB file; expect < 1 MB)*/
618     char *data = fdevent_load_file(fn, &dlen, errh, malloc, free);
619     if (NULL == data) return NULL;
620 
621     buffer **certs = NULL;
622     int rc = -1;
623     do {
624         int count = 0;
625         char *b = data;
626         for (; (b = strstr(b, PEM_BEGIN_CERT)); b += sizeof(PEM_BEGIN_CERT)-1)
627             ++count;
628         b = data;
629         for (; (b = strstr(b, PEM_BEGIN_TRUSTED_CERT));
630                 b += sizeof(PEM_BEGIN_TRUSTED_CERT)-1)
631             ++count;
632         if (0 == count) {
633             rc = 0;
634             break;
635         }
636 
637         certs = malloc((count+1) * sizeof(buffer *));
638         force_assert(NULL != certs);
639         certs[count] = NULL;
640         for (int i = 0; i < count; ++i)
641             certs[i] = buffer_init();
642 
643         buffer *der;
644         int i = 0;
645         for (char *e = data; (b = strstr(e, PEM_BEGIN_CERT)); ++i) {
646             b += sizeof(PEM_BEGIN_CERT)-1;
647             if (*b == '\r') ++b;
648             if (*b == '\n') ++b;
649             e = strstr(b, PEM_END_CERT);
650             if (NULL == e) break;
651             uint32_t len = (uint32_t)(e - b);
652             e += sizeof(PEM_END_CERT)-1;
653             if (i >= count) break; /*(should not happen)*/
654             der = certs[i];
655             if (NULL == buffer_append_base64_decode(der,b,len,BASE64_STANDARD))
656                 break;
657         }
658         for (char *e = data; (b = strstr(e, PEM_BEGIN_TRUSTED_CERT)); ++i) {
659             b += sizeof(PEM_BEGIN_TRUSTED_CERT)-1;
660             if (*b == '\r') ++b;
661             if (*b == '\n') ++b;
662             e = strstr(b, PEM_END_TRUSTED_CERT);
663             if (NULL == e) break;
664             uint32_t len = (uint32_t)(e - b);
665             e += sizeof(PEM_END_TRUSTED_CERT)-1;
666             if (i >= count) break; /*(should not happen)*/
667             der = certs[i];
668             if (NULL == buffer_append_base64_decode(der,b,len,BASE64_STANDARD))
669                 break;
670         }
671         if (i == count)
672             rc = 0;
673         else
674             errno = EIO;
675     } while (0);
676 
677     if (dlen) safe_memclear(data, dlen);
678     free(data);
679 
680     if (rc < 0) {
681         log_perror(errh, __FILE__, __LINE__, "error loading %s", fn);
682         mod_wolfssl_free_der_certs(certs);
683         certs = NULL;
684     }
685 
686     *chain = certs;
687     return certs ? certs[0] : NULL;
688 }
689 
690 
691 static buffer *
692 mod_wolfssl_evp_pkey_load_pem_file (const char *fn, log_error_st *errh)
693 {
694     off_t dlen = 512*1024*1024;/*(arbitrary limit: 512 MB file; expect < 1 MB)*/
695     char *data = fdevent_load_file(fn, &dlen, errh, malloc, free);
696     if (NULL == data) return NULL;
697 
698     buffer *pkey = NULL;
699     int rc = -1;
700     do {
701         /*(expecting single private key in file, so first match)*/
702         char *b, *e;
703         if ((b = strstr(data, PEM_BEGIN_PKEY))
704             && (e = strstr(b, PEM_END_PKEY)))
705             b += sizeof(PEM_BEGIN_PKEY)-1;
706         else if ((b = strstr(data, PEM_BEGIN_EC_PKEY))
707                  && (e = strstr(b, PEM_END_EC_PKEY)))
708             b += sizeof(PEM_BEGIN_EC_PKEY)-1;
709         else if ((b = strstr(data, PEM_BEGIN_RSA_PKEY))
710                  && (e = strstr(b, PEM_END_RSA_PKEY)))
711             b += sizeof(PEM_BEGIN_RSA_PKEY)-1;
712         else if ((b = strstr(data, PEM_BEGIN_DSA_PKEY))
713                  && (e = strstr(b, PEM_END_DSA_PKEY)))
714             b += sizeof(PEM_BEGIN_DSA_PKEY)-1;
715         else if ((b = strstr(data, PEM_BEGIN_ANY_PKEY))
716                  && (e = strstr(b, PEM_END_ANY_PKEY)))
717             b += sizeof(PEM_BEGIN_ANY_PKEY)-1;
718         else
719             break;
720         if (*b == '\r') ++b;
721         if (*b == '\n') ++b;
722 
723         pkey = buffer_init();
724         size_t len = (size_t)(e - b);
725         if (NULL == buffer_append_base64_decode(pkey, b, len, BASE64_STANDARD))
726             break;
727         rc = 0;
728     } while (0);
729 
730     if (dlen) safe_memclear(data, dlen);
731     free(data);
732 
733     if (rc < 0) {
734         log_error(errh, __FILE__, __LINE__, "%s() %s", __func__, fn);
735         return NULL;
736     }
737 
738     return pkey;
739 }
740 
741 
742 static int
743 mod_wolfssl_CTX_use_certificate_chain_file (WOLFSSL_CTX *ssl_ctx, const char *fn, log_error_st *errh)
744 {
745     /* (While it should be possible to parse DERs from (buffer **)
746      *  s->pc->ssl_pemfile_chain, it is simpler to re-read file and use the
747      *  built-in wolfSSL_CTX_use_certificate_chain_buffer() interface) */
748     off_t dlen = 4*1024*1024;/*(arbitrary limit: 4 MB file; expect < 1 KB)*/
749     char *data = fdevent_load_file(fn, &dlen, errh, malloc, free);
750     if (NULL == data) return -1;
751 
752     int rc = wolfSSL_CTX_use_certificate_chain_buffer(ssl_ctx,
753                                                       (unsigned char *)data,
754                                                       (long)dlen);
755 
756     if (dlen) safe_memclear(data, dlen);
757     free(data);
758 
759     if (rc == WOLFSSL_SUCCESS)
760         return 1;
761 
762     log_error(errh, __FILE__, __LINE__,
763       "SSL: %s %s", ERR_error_string(rc, NULL), fn);
764     return 0;
765 }
766 
767 
768 static STACK_OF(X509_NAME) *
769 mod_wolfssl_load_client_CA_file (const buffer *ssl_ca_file, log_error_st *errh)
770 {
771     /* similar to wolfSSL_load_client_CA_file(), plus some processing */
772     buffer **certs = NULL;
773     if (NULL == mod_wolfssl_load_pem_file(ssl_ca_file->ptr, errh, &certs)) {
774       #ifdef __clang_analyzer__
775         mod_wolfssl_free_der_certs(certs); /*unnecessary; quiet clang analyzer*/
776       #endif
777         return NULL;
778     }
779 
780     WOLF_STACK_OF(WOLFSSL_X509_NAME) *canames = wolfSSL_sk_X509_NAME_new(NULL);
781     if (NULL == canames) {
782         mod_wolfssl_free_der_certs(certs);
783         return NULL;
784     }
785 
786     for (int i = 0; NULL != certs[i]; ++i) {
787         WOLFSSL_X509 *ca =
788           wolfSSL_X509_load_certificate_buffer((unsigned char *)certs[i]->ptr,
789                                                (int)
790                                                buffer_string_length(certs[i]),
791                                                WOLFSSL_FILETYPE_ASN1);
792         WOLFSSL_X509_NAME *subj = NULL;
793         if (NULL == ca
794             || NULL == (subj = wolfSSL_X509_get_subject_name(ca))
795             || 0 != wolfSSL_sk_X509_NAME_push(canames,
796                                               wolfSSL_X509_NAME_dup(subj))) {
797             log_error(errh, __FILE__, __LINE__,
798               "SSL: couldn't read X509 certificates from '%s'",
799               ssl_ca_file->ptr);
800             if (subj) wolfSSL_X509_NAME_free(subj);
801             if (ca) wolfSSL_X509_free(ca);
802             wolfSSL_sk_X509_NAME_free(canames);
803             mod_wolfssl_free_der_certs(certs);
804             return NULL;
805         }
806 
807         wolfSSL_X509_free(ca);
808     }
809 
810     mod_wolfssl_free_der_certs(certs);
811     return canames;
812 }
813 
814 
815 static plugin_cacerts *
816 mod_wolfssl_load_cacerts (const buffer *ssl_ca_file, log_error_st *errh)
817 {
818     /* similar to mod_wolfSSL_load_client_CA_file(), plus some processing */
819     /* similar to wolfSSL_load_client_CA_file(), plus some processing */
820     buffer **certs = NULL;
821     if (NULL == mod_wolfssl_load_pem_file(ssl_ca_file->ptr, errh, &certs)) {
822       #ifdef __clang_analyzer__
823         mod_wolfssl_free_der_certs(certs); /*unnecessary; quiet clang analyzer*/
824       #endif
825         return NULL;
826     }
827 
828     WOLFSSL_X509_STORE *castore = wolfSSL_X509_STORE_new();
829     if (NULL == castore) {
830         mod_wolfssl_free_der_certs(certs);
831         return NULL;
832     }
833 
834     WOLF_STACK_OF(WOLFSSL_X509_NAME) *canames = wolfSSL_sk_X509_NAME_new(NULL);
835     if (NULL == canames) {
836         wolfSSL_X509_STORE_free(castore);
837         mod_wolfssl_free_der_certs(certs);
838         return NULL;
839     }
840 
841     for (int i = 0; NULL != certs[i]; ++i) {
842         WOLFSSL_X509 *ca =
843           wolfSSL_X509_load_certificate_buffer((unsigned char *)certs[i]->ptr,
844                                                (int)
845                                                buffer_string_length(certs[i]),
846                                                WOLFSSL_FILETYPE_ASN1);
847         WOLFSSL_X509_NAME *subj = NULL;
848         if (NULL == ca || !wolfSSL_X509_STORE_add_cert(castore, ca)
849             || NULL == (subj = wolfSSL_X509_get_subject_name(ca))
850             || 0 != wolfSSL_sk_X509_NAME_push(canames,
851                                               wolfSSL_X509_NAME_dup(subj))) {
852             log_error(errh, __FILE__, __LINE__,
853               "SSL: couldn't read X509 certificates from '%s'",
854               ssl_ca_file->ptr);
855             if (subj) wolfSSL_X509_NAME_free(subj);
856             if (ca) wolfSSL_X509_free(ca);
857             wolfSSL_sk_X509_NAME_free(canames);
858             wolfSSL_X509_STORE_free(castore);
859             mod_wolfssl_free_der_certs(certs);
860             return NULL;
861         }
862 
863         wolfSSL_X509_free(ca);
864     }
865 
866     mod_wolfssl_free_der_certs(certs);
867 
868     plugin_cacerts *cacerts = malloc(sizeof(plugin_cacerts));
869     force_assert(cacerts);
870 
871     cacerts->names = canames;
872     cacerts->certs = castore;
873     return cacerts;
874 }
875 
876 
877 static int
878 mod_wolfssl_load_cacrls (WOLFSSL_CTX *ssl_ctx, const buffer *ssl_ca_crl_file, server *srv)
879 {
880   #ifdef HAVE_CRL /* <wolfssl/options.h> */
881     int rc = wolfSSL_CTX_EnableCRL(ssl_ctx,
882                                    WOLFSSL_CRL_CHECK | WOLFSSL_CRL_CHECKALL);
883     if (rc != WOLFSSL_SUCCESS) return 0;
884 
885     const char *fn = ssl_ca_crl_file->ptr;
886     off_t dlen = 512*1024*1024;/*(arbitrary limit: 512 MB file; expect < 1 MB)*/
887     char *data = fdevent_load_file(fn, &dlen, srv->errh, malloc, free);
888     if (NULL == data) return 0;
889 
890     rc = wolfSSL_CTX_LoadCRLBuffer(ssl_ctx, (byte *)data, (long)dlen,
891                                    WOLFSSL_FILETYPE_PEM);
892 
893     if (dlen) safe_memclear(data, dlen);
894     free(data);
895 
896     if (rc == WOLFSSL_SUCCESS)
897         return 1;
898 
899     log_error(srv->errh, __FILE__, __LINE__,
900       "SSL: %s %s", ERR_error_string(rc, NULL), fn);
901     return 0;
902   #else
903     UNUSED(ssl_ctx);
904     log_error(srv->errh, __FILE__, __LINE__,
905       "WolfSSL not built with CRL support; ignoring %s", ssl_ca_crl_file->ptr);
906     return WOLFSSL_FAILURE;
907   #endif
908 }
909 
910 
911 static int
912 mod_wolfssl_load_verify_locn (SSL_CTX *ssl_ctx, const buffer *b, server *srv)
913 {
914     const char *fn = b->ptr;
915     off_t dlen = 512*1024*1024;/*(arbitrary limit: 512 MB file; expect < 1 MB)*/
916     char *data = fdevent_load_file(fn, &dlen, srv->errh, malloc, free);
917     if (NULL == data) return 0;
918 
919     int rc = wolfSSL_CTX_load_verify_buffer(ssl_ctx, (unsigned char *)data,
920                                             (long)dlen, WOLFSSL_FILETYPE_PEM);
921 
922     if (dlen) safe_memclear(data, dlen);
923     free(data);
924 
925     if (rc == WOLFSSL_SUCCESS)
926         return 1;
927 
928     log_error(srv->errh, __FILE__, __LINE__,
929       "SSL: %s %s", ERR_error_string(rc, NULL), fn);
930     return 0;
931 }
932 
933 
934 static int
935 mod_wolfssl_load_ca_files (SSL_CTX *ssl_ctx, plugin_data *p, server *srv)
936 {
937     /* load all ssl.ca-files specified in the config into each SSL_CTX */
938 
939     for (uint32_t i = 0, used = p->cafiles->used; i < used; ++i) {
940         const buffer *b = &((data_string *)p->cafiles->data[i])->value;
941         if (!mod_wolfssl_load_verify_locn(ssl_ctx, b, srv))
942             return 0;
943     }
944     return 1;
945 }
946 
947 
948 FREE_FUNC(mod_openssl_free)
949 {
950     plugin_data *p = p_d;
951     if (NULL == p->srv) return;
952     mod_openssl_free_config(p->srv, p);
953     mod_openssl_free_openssl();
954 }
955 
956 
957 static void
958 mod_openssl_merge_config_cpv (plugin_config * const pconf, const config_plugin_value_t * const cpv)
959 {
960     switch (cpv->k_id) { /* index into static config_plugin_keys_t cpk[] */
961       case 0: /* ssl.pemfile */
962         if (cpv->vtype == T_CONFIG_LOCAL)
963             pconf->pc = cpv->v.v;
964         break;
965       case 1: /* ssl.privkey */
966         break;
967       case 2: /* ssl.ca-file */
968         if (cpv->vtype == T_CONFIG_LOCAL)
969             pconf->ssl_ca_file = cpv->v.v;
970         break;
971       case 3: /* ssl.ca-dn-file */
972         if (cpv->vtype == T_CONFIG_LOCAL)
973             pconf->ssl_ca_dn_file = cpv->v.v;
974         break;
975       case 4: /* ssl.ca-crl-file */
976         pconf->ssl_ca_crl_file = cpv->v.b;
977         break;
978       case 5: /* ssl.read-ahead */
979         pconf->ssl_read_ahead = (0 != cpv->v.u);
980         break;
981       case 6: /* ssl.disable-client-renegotiation */
982         pconf->ssl_disable_client_renegotiation = (0 != cpv->v.u);
983         break;
984       case 7: /* ssl.verifyclient.activate */
985         pconf->ssl_verifyclient = (0 != cpv->v.u);
986         break;
987       case 8: /* ssl.verifyclient.enforce */
988         pconf->ssl_verifyclient_enforce = (0 != cpv->v.u);
989         break;
990       case 9: /* ssl.verifyclient.depth */
991         pconf->ssl_verifyclient_depth = (unsigned char)cpv->v.shrt;
992         break;
993       case 10:/* ssl.verifyclient.username */
994         pconf->ssl_verifyclient_username = cpv->v.b;
995         break;
996       case 11:/* ssl.verifyclient.exportcert */
997         pconf->ssl_verifyclient_export_cert = (0 != cpv->v.u);
998         break;
999       case 12:/* ssl.acme-tls-1 */
1000         pconf->ssl_acme_tls_1 = cpv->v.b;
1001         break;
1002       case 13:/* ssl.stapling-file */
1003         break;
1004       case 14:/* debug.log-ssl-noise */
1005         pconf->ssl_log_noise = (0 != cpv->v.u);
1006         break;
1007       default:/* should not happen */
1008         return;
1009     }
1010 }
1011 
1012 
1013 static void
1014 mod_openssl_merge_config(plugin_config * const pconf, const config_plugin_value_t *cpv)
1015 {
1016     do {
1017         mod_openssl_merge_config_cpv(pconf, cpv);
1018     } while ((++cpv)->k_id != -1);
1019 }
1020 
1021 
1022 static void
1023 mod_openssl_patch_config (request_st * const r, plugin_config * const pconf)
1024 {
1025     plugin_data * const p = plugin_data_singleton;
1026     memcpy(pconf, &p->defaults, sizeof(plugin_config));
1027     for (int i = 1, used = p->nconfig; i < used; ++i) {
1028         if (config_check_cond(r, (uint32_t)p->cvlist[i].k_id))
1029             mod_openssl_merge_config(pconf, p->cvlist + p->cvlist[i].v.u2[0]);
1030     }
1031 }
1032 
1033 
1034 static int
1035 safer_X509_NAME_oneline(X509_NAME *name, char *buf, size_t sz)
1036 {
1037     if (wolfSSL_X509_get_name_oneline(name, buf, (int)sz))
1038         return (int)strlen(buf);
1039     else {
1040         buf[0] = '\0';
1041         return -1;
1042     }
1043 }
1044 
1045 
1046 static void
1047 ssl_info_callback (const SSL *ssl, int where, int ret)
1048 {
1049     UNUSED(ret);
1050 
1051     if (0 != (where & SSL_CB_HANDSHAKE_START)) {
1052         handler_ctx *hctx = (handler_ctx *) SSL_get_app_data(ssl);
1053         if (hctx->renegotiations >= 0) ++hctx->renegotiations;
1054     }
1055   #ifdef TLS1_3_VERSION
1056     /* https://github.com/openssl/openssl/issues/5721
1057      * "TLSv1.3 unexpected InfoCallback after handshake completed" */
1058     if (0 != (where & SSL_CB_HANDSHAKE_DONE)) {
1059         /* SSL_version() is valid after initial handshake completed */
1060         SSL *ssl_nonconst;
1061         *(const SSL **)&ssl_nonconst = ssl;
1062         if (wolfSSL_GetVersion(ssl_nonconst) >= WOLFSSL_TLSV1_3) {
1063             /* https://wiki.openssl.org/index.php/TLS1.3
1064              * "Renegotiation is not possible in a TLSv1.3 connection" */
1065             handler_ctx *hctx = (handler_ctx *) SSL_get_app_data(ssl);
1066             hctx->renegotiations = -1;
1067         }
1068     }
1069   #endif
1070 }
1071 
1072 /* https://wiki.openssl.org/index.php/Manual:SSL_CTX_set_verify(3)#EXAMPLES */
1073 static int
1074 verify_callback(int preverify_ok, X509_STORE_CTX *ctx)
1075 {
1076     char buf[256];
1077     X509 *err_cert;
1078     int err, depth;
1079     SSL *ssl;
1080     handler_ctx *hctx;
1081 
1082     err = X509_STORE_CTX_get_error(ctx);
1083     depth = X509_STORE_CTX_get_error_depth(ctx);
1084 
1085     /*
1086      * Retrieve the pointer to the SSL of the connection currently treated
1087      * and the application specific data stored into the SSL object.
1088      */
1089     ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
1090     hctx = (handler_ctx *) SSL_get_app_data(ssl);
1091 
1092     /*
1093      * Catch a too long certificate chain. The depth limit set using
1094      * wolfSSL_CTX_set_verify_depth() is by purpose set to "limit+1" so
1095      * that whenever the "depth>verify_depth" condition is met, we
1096      * have violated the limit and want to log this error condition.
1097      * We must do it here, because the CHAIN_TOO_LONG error would not
1098      * be found explicitly; only errors introduced by cutting off the
1099      * additional certificates would be logged.
1100      */
1101     if (depth > hctx->conf.ssl_verifyclient_depth) {
1102         preverify_ok = 0;
1103         err = X509_V_ERR_CERT_CHAIN_TOO_LONG;
1104         X509_STORE_CTX_set_error(ctx, err);
1105     }
1106 
1107     if (preverify_ok && 0 == depth && NULL != hctx->conf.ssl_ca_dn_file) {
1108         /* verify that client cert is issued by CA in ssl.ca-dn-file
1109          * if both ssl.ca-dn-file and ssl.ca-file were configured */
1110         STACK_OF(X509_NAME) * const cert_names = hctx->conf.ssl_ca_dn_file;
1111         X509_NAME *issuer;
1112         err_cert = ctx->current_cert;/*wolfSSL_X509_STORE_CTX_get_current_cert*/
1113         if (NULL == err_cert) return !hctx->conf.ssl_verifyclient_enforce;
1114         issuer = X509_get_issuer_name(err_cert);
1115       #if 0 /*(?desirable/undesirable to have cert_names sorted?)*/
1116         if (-1 != sk_X509_NAME_find(cert_names, issuer))
1117             return preverify_ok; /* match */
1118       #else
1119         for (int i=0, len=wolfSSL_sk_X509_NAME_num(cert_names); i < len; ++i) {
1120             if (0 == wolfSSL_X509_NAME_cmp(sk_X509_NAME_value(cert_names, i),
1121                                            issuer))
1122                 return preverify_ok; /* match */
1123         }
1124       #endif
1125 
1126         preverify_ok = 0;
1127         err = X509_V_ERR_CERT_REJECTED;
1128         X509_STORE_CTX_set_error(ctx, err);
1129     }
1130 
1131     if (preverify_ok) {
1132         return preverify_ok;
1133     }
1134 
1135     err_cert = ctx->current_cert; /*wolfSSL_X509_STORE_CTX_get_current_cert()*/
1136     if (NULL == err_cert) return !hctx->conf.ssl_verifyclient_enforce;
1137     safer_X509_NAME_oneline(X509_get_subject_name(err_cert),buf,sizeof(buf));
1138     log_error_st *errh = hctx->r->conf.errh;
1139     log_error(errh, __FILE__, __LINE__,
1140       "SSL: verify error:num=%d:%s:depth=%d:subject=%s",
1141       err, X509_verify_cert_error_string(err), depth, buf);
1142 
1143     /*
1144      * At this point, err contains the last verification error. We can use
1145      * it for something special
1146      */
1147     if (!preverify_ok && (err == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY ||
1148                           err == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT)) {
1149         safer_X509_NAME_oneline(X509_get_issuer_name(err_cert),buf,sizeof(buf));
1150         log_error(errh, __FILE__, __LINE__, "SSL: issuer=%s", buf);
1151     }
1152 
1153     return !hctx->conf.ssl_verifyclient_enforce;
1154 }
1155 
1156 static int
1157 mod_openssl_cert_cb (SSL *ssl, void *arg)
1158 {
1159     handler_ctx *hctx = (handler_ctx *) SSL_get_app_data(ssl);
1160     plugin_cert *pc = hctx->conf.pc;
1161     UNUSED(arg);
1162 
1163     if (NULL == pc->ssl_pemfile_x509 || NULL == pc->ssl_pemfile_pkey) {
1164         /* x509/pkey available <=> pemfile was set <=> pemfile got patched:
1165          * so this should never happen, unless you nest $SERVER["socket"] */
1166         log_error(hctx->r->conf.errh, __FILE__, __LINE__,
1167           "SSL: no certificate/private key for TLS server name %s",
1168           hctx->r->uri.authority.ptr);
1169         return 0;
1170     }
1171 
1172     /* first set certificate!
1173      * setting private key checks whether certificate matches it */
1174     buffer *cert = pc->ssl_pemfile_x509;
1175     if (1 != wolfSSL_use_certificate_ASN1(ssl, (unsigned char *)cert->ptr,
1176                                           (int)buffer_string_length(cert))) {
1177         log_error(hctx->r->conf.errh, __FILE__, __LINE__,
1178           "SSL: failed to set certificate for TLS server name %s: %s",
1179           hctx->r->uri.authority.ptr, ERR_error_string(ERR_get_error(), NULL));
1180         return 0;
1181     }
1182 
1183     buffer *pkey = pc->ssl_pemfile_pkey;
1184     if (1 != wolfSSL_use_PrivateKey_buffer(ssl, (unsigned char *)pkey->ptr,
1185                                            (int)buffer_string_length(pkey),
1186                                            WOLFSSL_FILETYPE_ASN1)) {
1187         log_error(hctx->r->conf.errh, __FILE__, __LINE__,
1188           "SSL: failed to set private key for TLS server name %s: %s",
1189           hctx->r->uri.authority.ptr, ERR_error_string(ERR_get_error(), NULL));
1190         return 0;
1191     }
1192 
1193     if (hctx->conf.ssl_verifyclient) {
1194         if (NULL == hctx->conf.ssl_ca_file) {
1195             log_error(hctx->r->conf.errh, __FILE__, __LINE__,
1196               "SSL: can't verify client without ssl.ca-file "
1197               "for TLS server name %s", hctx->r->uri.authority.ptr);
1198             return 0;
1199         }
1200         /* WolfSSL does not support setting per-session CA list;
1201          * limitation is to per-CTX CA list, and is not changed after SNI */
1202         int mode = SSL_VERIFY_PEER;
1203         if (hctx->conf.ssl_verifyclient_enforce)
1204             mode |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
1205         wolfSSL_set_verify(ssl, mode, verify_callback);
1206         wolfSSL_set_verify_depth(ssl, hctx->conf.ssl_verifyclient_depth + 1);
1207     }
1208     else {
1209         wolfSSL_set_verify(ssl, SSL_VERIFY_NONE, NULL);
1210     }
1211 
1212     return 1;
1213 }
1214 
1215 #ifdef HAVE_TLS_EXTENSIONS
1216 static int
1217 mod_openssl_SNI (handler_ctx *hctx, const char *servername, size_t len)
1218 {
1219     request_st * const r = hctx->r;
1220     if (len >= 1024) { /*(expecting < 256; TLSEXT_MAXLEN_host_name is 255)*/
1221         log_error(r->conf.errh, __FILE__, __LINE__,
1222                   "SSL: SNI name too long %.*s", (int)len, servername);
1223         return SSL_TLSEXT_ERR_ALERT_FATAL;
1224     }
1225 
1226     /* use SNI to patch mod_openssl config and then reset COMP_HTTP_HOST */
1227     buffer_copy_string_len(&r->uri.authority, servername, len);
1228     buffer_to_lower(&r->uri.authority);
1229   #if 0
1230     /*(r->uri.authority used below for configuration before request read;
1231      * revisit for h2)*/
1232     if (0 != http_request_host_policy(&r->uri.authority,
1233                                       r->conf.http_parseopts, 443))
1234         return SSL_TLSEXT_ERR_ALERT_FATAL;
1235   #endif
1236 
1237     r->conditional_is_valid |= (1 << COMP_HTTP_SCHEME)
1238                             |  (1 << COMP_HTTP_HOST);
1239     mod_openssl_patch_config(r, &hctx->conf);
1240     /* reset COMP_HTTP_HOST so that conditions re-run after request hdrs read */
1241     /*(done in response.c:config_cond_cache_reset() after request hdrs read)*/
1242     /*config_cond_cache_reset_item(r, COMP_HTTP_HOST);*/
1243     /*buffer_clear(&r->uri.authority);*/
1244 
1245     return (mod_openssl_cert_cb(hctx->ssl, NULL) == 1)
1246       ? SSL_TLSEXT_ERR_OK
1247       : SSL_TLSEXT_ERR_ALERT_FATAL;
1248 }
1249 
1250 static int
1251 network_ssl_servername_callback (SSL *ssl, int *al, void *srv)
1252 {
1253     handler_ctx *hctx = (handler_ctx *) SSL_get_app_data(ssl);
1254     buffer_copy_string(&hctx->r->uri.scheme, "https");
1255     UNUSED(al);
1256     UNUSED(srv);
1257 
1258     const char *servername;
1259     size_t len = (size_t)
1260     #ifdef HAVE_SNI
1261       wolfSSL_SNI_GetRequest(ssl, WOLFSSL_SNI_HOST_NAME, (void **)&servername);
1262     #else
1263       0;
1264     #endif
1265     if (0 == len)
1266         return SSL_TLSEXT_ERR_NOACK; /* client did not provide SNI */
1267   #if 0  /* WolfSSL does not provide per-session SSL_set_read_ahead() */
1268     int read_ahead = hctx->conf.ssl_read_ahead;
1269     int rc = mod_openssl_SNI(hctx, servername, len);
1270     if (!read_ahead && hctx->conf.ssl_read_ahead)
1271         SSL_set_read_ahead(ssl, hctx->conf.ssl_read_ahead);
1272     return rc;
1273   #else
1274     return mod_openssl_SNI(hctx, servername, len);
1275   #endif
1276 }
1277 #endif
1278 
1279 
1280 #ifdef HAVE_OCSP
1281 
1282 #define OCSP_RESPONSE             OcspResponse
1283 #define OCSP_RESPONSE_free        wolfSSL_OCSP_RESPONSE_free
1284 #define d2i_OCSP_RESPONSE_bio     wolfSSL_d2i_OCSP_RESPONSE_bio
1285 #define d2i_OCSP_RESPONSE         wolfSSL_d2i_OCSP_RESPONSE
1286 #define i2d_OCSP_RESPONSE         wolfSSL_i2d_OCSP_RESPONSE
1287 
1288 static buffer *
1289 mod_openssl_load_stapling_file (const char *file, log_error_st *errh, buffer *b)
1290 {
1291     /* load stapling .der into buffer *b only if successful
1292      *
1293      * Note: for some TLS libs, the OCSP stapling response is not copied when
1294      * assigned to a session (and is reasonable since not changed frequently)
1295      * - BoringSSL SSL_set_ocsp_response()
1296      * - WolfSSL SSL_set_tlsext_status_ocsp_resp() (differs from OpenSSL API)
1297      * Therefore, there is a potential race condition if the OCSP response is
1298      * assigned to the session during the handshake and the Server Hello is
1299      * partially sent, AND (unlikely, if possible at all), the TLS library is
1300      * in the middle of reading this OSCP response buffer.  If the OCSP response
1301      * is replaced due to an updated ssl.stapling-file (checked periodically),
1302      * AND the buffer is resized, this would be a problem.  Resizing the buffer
1303      * is unlikely since updated OSCP response for same certificate are
1304      * typically the same size with the signature and dates refreshed.
1305      */
1306 
1307     /* load raw .der file */
1308     off_t dlen = 1*1024*1024;/*(arbitrary limit: 1 MB file; expect < 1 KB)*/
1309     char *data = fdevent_load_file(file, &dlen, errh, malloc, free);
1310     if (NULL == data) return NULL;
1311 
1312     if (NULL == b)
1313         b = buffer_init();
1314     else if (b->ptr)
1315         free(b->ptr);
1316     b->ptr  = data;
1317     b->used = (uint32_t)dlen;
1318     b->size = (uint32_t)dlen+1;
1319     return b;
1320 }
1321 
1322 
1323 static time_t
1324 mod_openssl_asn1_time_to_posix (ASN1_TIME *asn1time)
1325 {
1326     /* Note: this does not check for integer overflow of time_t! */
1327     int day, sec;
1328     return wolfSSL_ASN1_TIME_diff(&day, &sec, NULL, asn1time)
1329       ? log_epoch_secs + day*86400 + sec
1330       : (time_t)-1;
1331 }
1332 
1333 
1334 static time_t
1335 mod_openssl_ocsp_next_update (plugin_cert *pc)
1336 {
1337   #if defined(WOLFSSL_VERSION)
1338     /* XXX: future TODO */
1339     UNUSED(pc);
1340     (void)mod_openssl_asn1_time_to_posix(NULL);
1341     return (time_t)-1; /*(not implemented)*/
1342   #else
1343     buffer *der = pc->ssl_stapling;
1344     const unsigned char *p = (unsigned char *)der->ptr; /*(p gets modified)*/
1345     OCSP_RESPONSE *ocsp = d2i_OCSP_RESPONSE(NULL,&p,buffer_string_length(der));
1346     if (NULL == ocsp) return (time_t)-1;
1347     OCSP_BASICRESP *bs = OCSP_response_get1_basic(ocsp);
1348     if (NULL == bs) {
1349         OCSP_RESPONSE_free(ocsp);
1350         return (time_t)-1;
1351     }
1352 
1353     /* XXX: should save and evaluate cert status returned by these calls */
1354     ASN1_TIME *nextupd = NULL;
1355    #ifdef WOLFSSL_VERSION /* WolfSSL limitation */
1356     /* WolfSSL does not provide OCSP_resp_get0() OCSP_single_get0_status() */
1357     /* (inactive code path; alternative path followed in #if above for WolfSSL)
1358      * (chain not currently available in mod_openssl when used with WolfSSL)
1359      * (For WolfSSL, pc->ssl_pemfile_chain might not be filled in with actual
1360      *  chain, but is used to store (buffer **) of DER decoded from PEM certs
1361      *  read from ssl.pemfile, which may be a single cert, pc->ssl_pemfile_x509.
1362      *  The chain is not calculated or filled in if single cert, and neither are
1363      *  (X509 *), though (X509 *) could be temporarily created to calculated
1364      *  (OCSP_CERTID *), which additionally could be calculated once at startup)
1365      */
1366     OCSP_CERTID *id = (NULL != pc->ssl_pemfile_chain)
1367       ? OCSP_cert_to_id(NULL, pc->ssl_pemfile_x509,
1368                         sk_X509_value(pc->ssl_pemfile_chain, 0))
1369       : NULL;
1370     if (id == NULL) {
1371         OCSP_BASICRESP_free(bs);
1372         OCSP_RESPONSE_free(ocsp);
1373         return (time_t)-1;
1374     }
1375     OCSP_resp_find_status(bs, id, NULL, NULL, NULL, NULL, &nextupd);
1376     OCSP_CERTID_free(id);
1377    #else
1378     OCSP_single_get0_status(OCSP_resp_get0(bs, 0), NULL, NULL, NULL, &nextupd);
1379    #endif
1380     time_t t = nextupd ? mod_openssl_asn1_time_to_posix(nextupd) : (time_t)-1;
1381 
1382     /* Note: trust external process which creates ssl.stapling-file to verify
1383      *       (as well as to validate certificate status)
1384      * future: verify OCSP response here to double-check */
1385 
1386     OCSP_BASICRESP_free(bs);
1387     OCSP_RESPONSE_free(ocsp);
1388 
1389     return t;
1390   #endif
1391 }
1392 
1393 
1394 static int
1395 mod_openssl_reload_stapling_file (server *srv, plugin_cert *pc, const time_t cur_ts)
1396 {
1397     buffer *b = mod_openssl_load_stapling_file(pc->ssl_stapling_file->ptr,
1398                                                srv->errh, pc->ssl_stapling);
1399     if (!b) return 0;
1400 
1401     pc->ssl_stapling = b; /*(unchanged unless orig was NULL)*/
1402     pc->ssl_stapling_loadts = cur_ts;
1403     pc->ssl_stapling_nextts = mod_openssl_ocsp_next_update(pc);
1404     if (pc->ssl_stapling_nextts == (time_t)-1) {
1405         /* "Next Update" might not be provided by OCSP responder
1406          * Use 3600 sec (1 hour) in that case. */
1407         /* retry in 1 hour if unable to determine Next Update */
1408         pc->ssl_stapling_nextts = cur_ts + 3600;
1409         pc->ssl_stapling_loadts = 0;
1410     }
1411 
1412     return 1;
1413 }
1414 
1415 
1416 static int
1417 mod_openssl_refresh_stapling_file (server *srv, plugin_cert *pc, const time_t cur_ts)
1418 {
1419     if (pc->ssl_stapling && pc->ssl_stapling_nextts - 256 > cur_ts)
1420         return 1; /* skip check for refresh unless close to expire */
1421     struct stat st;
1422     if (0 != stat(pc->ssl_stapling_file->ptr, &st)
1423         || st.st_mtime <= pc->ssl_stapling_loadts) {
1424         if (pc->ssl_stapling_nextts < cur_ts) {
1425             /* discard expired OCSP stapling response */
1426             buffer_free(pc->ssl_stapling);
1427             pc->ssl_stapling = NULL;
1428             if (pc->must_staple) {
1429                 log_error(srv->errh, __FILE__, __LINE__,
1430                           "certificate marked OCSP Must-Staple, "
1431                           "but OCSP response expired from ssl.stapling-file %s",
1432                           pc->ssl_stapling_file->ptr);
1433             }
1434         }
1435         return 1;
1436     }
1437     return mod_openssl_reload_stapling_file(srv, pc, cur_ts);
1438 }
1439 
1440 
1441 static void
1442 mod_openssl_refresh_stapling_files (server *srv, const plugin_data *p, const time_t cur_ts)
1443 {
1444     /* future: might construct array of (plugin_cert *) at startup
1445      *         to avoid the need to search for them here */
1446     for (int i = 0, used = p->nconfig; i < used; ++i) {
1447         const config_plugin_value_t *cpv = p->cvlist + p->cvlist[i].v.u2[0];
1448         for (; cpv->k_id != -1; ++cpv) {
1449             if (cpv->k_id != 0) continue; /* k_id == 0 for ssl.pemfile */
1450             if (cpv->vtype != T_CONFIG_LOCAL) continue;
1451             plugin_cert *pc = cpv->v.v;
1452             if (!buffer_string_is_empty(pc->ssl_stapling_file))
1453                 mod_openssl_refresh_stapling_file(srv, pc, cur_ts);
1454         }
1455     }
1456 }
1457 
1458 
1459 static int
1460 mod_openssl_crt_must_staple (const X509 *crt)
1461 {
1462     /* XXX: TODO: not implemented */
1463     UNUSED(crt);
1464     return 0;
1465 }
1466 
1467 #endif /* HAVE_OCSP */
1468 
1469 
1470 static plugin_cert *
1471 network_openssl_load_pemfile (server *srv, const buffer *pemfile, const buffer *privkey, const buffer *ssl_stapling_file)
1472 {
1473     if (!mod_openssl_init_once_openssl(srv)) return NULL;
1474 
1475     buffer **ssl_pemfile_chain = NULL;
1476     buffer *ssl_pemfile_x509 =
1477       mod_wolfssl_load_pem_file(pemfile->ptr, srv->errh, &ssl_pemfile_chain);
1478     if (NULL == ssl_pemfile_x509)
1479         return NULL;
1480 
1481     buffer *ssl_pemfile_pkey =
1482       mod_wolfssl_evp_pkey_load_pem_file(privkey->ptr, srv->errh);
1483     if (NULL == ssl_pemfile_pkey) {
1484         /*buffer_free(ssl_pemfile_x509);*//*(part of chain)*/
1485         mod_wolfssl_free_der_certs(ssl_pemfile_chain);
1486         return NULL;
1487     }
1488 
1489     /* X509_check_private_key() is a stub func (not implemented) in WolfSSL */
1490 
1491     plugin_cert *pc = malloc(sizeof(plugin_cert));
1492     force_assert(pc);
1493     pc->ssl_pemfile_pkey = ssl_pemfile_pkey;
1494     pc->ssl_pemfile_x509 = ssl_pemfile_x509;
1495     pc->ssl_pemfile_chain= ssl_pemfile_chain;
1496     pc->ssl_pemfile = pemfile;
1497     pc->ssl_privkey = privkey;
1498     pc->ssl_stapling     = NULL;
1499     pc->ssl_stapling_file= ssl_stapling_file;
1500     pc->ssl_stapling_loadts = 0;
1501     pc->ssl_stapling_nextts = 0;
1502   #ifdef HAVE_OCSP
1503     /*(not implemented for WolfSSL, though could convert the DER to (X509 *),
1504      * check Must-Staple, and then destroy (X509 *))*/
1505     (void)mod_openssl_crt_must_staple(NULL);
1506     pc->must_staple = 0;
1507   #else
1508     pc->must_staple = 0;
1509   #endif
1510 
1511     if (!buffer_string_is_empty(pc->ssl_stapling_file)) {
1512       #ifdef HAVE_OCSP
1513         if (!mod_openssl_reload_stapling_file(srv, pc, log_epoch_secs)) {
1514             /* continue without OCSP response if there is an error */
1515         }
1516       #else
1517         log_error(srv->errh, __FILE__, __LINE__, "SSL:"
1518           "OCSP stapling not supported; ignoring %s",
1519           pc->ssl_stapling_file->ptr);
1520       #endif
1521     }
1522     else if (pc->must_staple) {
1523         log_error(srv->errh, __FILE__, __LINE__,
1524                   "certificate %s marked OCSP Must-Staple, "
1525                   "but ssl.stapling-file not provided", pemfile->ptr);
1526     }
1527 
1528     return pc;
1529 }
1530 
1531 
1532 #ifdef HAVE_TLS_EXTENSIONS
1533 
1534 #ifdef HAVE_ALPN
1535 #ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
1536 
1537 static int
1538 mod_openssl_acme_tls_1 (SSL *ssl, handler_ctx *hctx)
1539 {
1540     buffer * const b = hctx->tmp_buf;
1541     const buffer * const name = &hctx->r->uri.authority;
1542     log_error_st * const errh = hctx->r->conf.errh;
1543     buffer *ssl_pemfile_x509 = NULL;
1544     buffer *ssl_pemfile_pkey = NULL;
1545     buffer **ssl_pemfile_chain = NULL;
1546     size_t len;
1547     int rc = SSL_TLSEXT_ERR_ALERT_FATAL;
1548 
1549     /* check if acme-tls/1 protocol is enabled (path to dir of cert(s) is set)*/
1550     if (buffer_string_is_empty(hctx->conf.ssl_acme_tls_1))
1551         return SSL_TLSEXT_ERR_NOACK; /*(reuse value here for not-configured)*/
1552     buffer_copy_buffer(b, hctx->conf.ssl_acme_tls_1);
1553     buffer_append_slash(b);
1554 
1555     /* check if SNI set server name (required for acme-tls/1 protocol)
1556      * and perform simple path checks for no '/'
1557      * and no leading '.' (e.g. ignore "." or ".." or anything beginning '.') */
1558     if (buffer_string_is_empty(name))   return rc;
1559     if (NULL != strchr(name->ptr, '/')) return rc;
1560     if (name->ptr[0] == '.')            return rc;
1561   #if 0
1562     if (0 != http_request_host_policy(name,hctx->r->conf.http_parseopts,443))
1563         return rc;
1564   #endif
1565     buffer_append_string_buffer(b, name);
1566     len = buffer_string_length(b);
1567 
1568     do {
1569         buffer_append_string_len(b, CONST_STR_LEN(".crt.pem"));
1570         ssl_pemfile_x509 =
1571           mod_wolfssl_load_pem_file(b->ptr, errh, &ssl_pemfile_chain);
1572         if (NULL == ssl_pemfile_x509) {
1573             log_error(errh, __FILE__, __LINE__,
1574               "SSL: Failed to load acme-tls/1 pemfile: %s", b->ptr);
1575             break;
1576         }
1577 
1578         buffer_string_set_length(b, len); /*(remove ".crt.pem")*/
1579         buffer_append_string_len(b, CONST_STR_LEN(".key.pem"));
1580         ssl_pemfile_pkey = mod_wolfssl_evp_pkey_load_pem_file(b->ptr, errh);
1581         if (NULL == ssl_pemfile_pkey) {
1582             log_error(errh, __FILE__, __LINE__,
1583               "SSL: Failed to load acme-tls/1 pemfile: %s", b->ptr);
1584             break;
1585         }
1586 
1587       #if 0 /* redundant with below? */
1588         if (!X509_check_private_key(ssl_pemfile_x509, ssl_pemfile_pkey)) {
1589             log_error(errh, __FILE__, __LINE__,
1590                "SSL: Private key does not match acme-tls/1 "
1591                "certificate public key, reason: %s %s"
1592                ERR_error_string(ERR_get_error(), NULL), b->ptr);
1593             break;
1594         }
1595       #endif
1596 
1597         /* first set certificate!
1598          * setting private key checks whether certificate matches it */
1599         buffer *cert = ssl_pemfile_x509;
1600         if (1 != wolfSSL_use_certificate_ASN1(ssl, (unsigned char *)cert->ptr,
1601                                               (int)buffer_string_length(cert))){
1602             log_error(errh, __FILE__, __LINE__,
1603               "SSL: failed to set acme-tls/1 certificate for TLS server "
1604               "name %s: %s", name->ptr, ERR_error_string(ERR_get_error(),NULL));
1605             break;
1606         }
1607 
1608         if (ssl_pemfile_chain) {
1609             /* WolfSSL limitation */
1610             /* WolfSSL does not support setting per-session chain;
1611              * limitation is to per-CTX chain, and so chain is not provided for
1612              * "acme-tls/1" (might be non-issue; chain might not be present) */
1613         }
1614 
1615         buffer *pkey = ssl_pemfile_pkey;
1616         if (1 != wolfSSL_use_PrivateKey_buffer(ssl, (unsigned char *)pkey->ptr,
1617                                                (int)buffer_string_length(pkey),
1618                                                WOLFSSL_FILETYPE_ASN1)) {
1619             log_error(errh, __FILE__, __LINE__,
1620               "SSL: failed to set acme-tls/1 private key for TLS server "
1621               "name %s: %s", name->ptr, ERR_error_string(ERR_get_error(),NULL));
1622             break;
1623         }
1624 
1625         hctx->conf.ssl_verifyclient_enforce = 0;
1626         wolfSSL_set_verify(ssl, SSL_VERIFY_NONE, NULL);
1627         rc = SSL_TLSEXT_ERR_OK;
1628     } while (0);
1629 
1630     if (ssl_pemfile_pkey) buffer_free(ssl_pemfile_pkey);
1631     /*if (ssl_pemfile_x509) buffer_free(ssl_pemfile_x509);*//*(part of chain)*/
1632     mod_wolfssl_free_der_certs(ssl_pemfile_chain);
1633 
1634     return rc;
1635 }
1636 
1637 enum {
1638   MOD_OPENSSL_ALPN_HTTP11      = 1
1639  ,MOD_OPENSSL_ALPN_HTTP10      = 2
1640  ,MOD_OPENSSL_ALPN_H2          = 3
1641  ,MOD_OPENSSL_ALPN_ACME_TLS_1  = 4
1642 };
1643 
1644 /* https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids */
1645 static int
1646 mod_openssl_alpn_select_cb (SSL *ssl, const unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *arg)
1647 {
1648     handler_ctx *hctx = (handler_ctx *) SSL_get_app_data(ssl);
1649     unsigned short proto;
1650     UNUSED(arg);
1651 
1652     for (unsigned int i = 0, n; i < inlen; i += n) {
1653         n = in[i++];
1654         if (i+n > inlen || 0 == n) break;
1655         switch (n) {
1656           case 2:  /* "h2" */
1657             if (in[i] == 'h' && in[i+1] == '2') {
1658                 if (!hctx->r->conf.h2proto) continue;
1659                 proto = MOD_OPENSSL_ALPN_H2;
1660                 hctx->r->http_version = HTTP_VERSION_2;
1661                 break;
1662             }
1663             continue;
1664           case 8:  /* "http/1.1" "http/1.0" */
1665             if (0 == memcmp(in+i, "http/1.", 7)) {
1666                 if (in[i+7] == '1') {
1667                     proto = MOD_OPENSSL_ALPN_HTTP11;
1668                     break;
1669                 }
1670                 if (in[i+7] == '0') {
1671                     proto = MOD_OPENSSL_ALPN_HTTP10;
1672                     break;
1673                 }
1674             }
1675             continue;
1676           case 10: /* "acme-tls/1" */
1677             if (0 == memcmp(in+i, "acme-tls/1", 10)) {
1678                 int rc = mod_openssl_acme_tls_1(ssl, hctx);
1679                 if (rc == SSL_TLSEXT_ERR_OK) {
1680                     proto = MOD_OPENSSL_ALPN_ACME_TLS_1;
1681                     break;
1682                 }
1683                 /* (use SSL_TLSEXT_ERR_NOACK for not-configured) */
1684                 if (rc == SSL_TLSEXT_ERR_NOACK) continue;
1685                 return rc;
1686             }
1687             continue;
1688           default:
1689             continue;
1690         }
1691 
1692         hctx->alpn = proto;
1693         *out = in+i;
1694         *outlen = n;
1695         return SSL_TLSEXT_ERR_OK;
1696     }
1697 
1698     return SSL_TLSEXT_ERR_NOACK;
1699 }
1700 
1701 #endif /* TLSEXT_TYPE_application_layer_protocol_negotiation */
1702 #endif /* HAVE_ALPN */
1703 
1704 #endif /* HAVE_TLS_EXTENSIONS */
1705 
1706 
1707 static int
1708 mod_openssl_ssl_conf_cmd (server *srv, plugin_config_socket *s);
1709 
1710 
1711 #ifndef NO_DH
1712 /* wolfSSL provides wolfSSL_DH_set0_pqg() for
1713  * Apache w/ OPENSSL_VERSION_NUMBER >= 0x10100000L
1714  * but does not provide most other openssl 1.1.0+ interfaces
1715  * and get_dh2048() might not be necessary if wolfSSL defines
1716  * HAVE_TLS_EXTENSIONS HAVE_DH_DEFAULT_PARAMS HAVE_FFDHE HAVE_SUPPORTED_CURVES*/
1717 #define DH_set0_pqg(dh, dh_p, NULL, dh_g) \
1718         ((dh)->p = (dh_p), (dh)->g = (dh_g), (dh_p) != NULL && (dh_g) != NULL)
1719 /* https://tools.ietf.org/html/rfc7919#appendix-A.1
1720  * A.1.  ffdhe2048
1721  *
1722  * https://ssl-config.mozilla.org/ffdhe2048.txt
1723  * C code generated with: openssl dhparam -C -in ffdhe2048.txt
1724  */
1725 static DH *get_dh2048(void)
1726 {
1727     static unsigned char dhp_2048[] = {
1728         0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xAD, 0xF8,
1729         0x54, 0x58, 0xA2, 0xBB, 0x4A, 0x9A, 0xAF, 0xDC, 0x56, 0x20,
1730         0x27, 0x3D, 0x3C, 0xF1, 0xD8, 0xB9, 0xC5, 0x83, 0xCE, 0x2D,
1731         0x36, 0x95, 0xA9, 0xE1, 0x36, 0x41, 0x14, 0x64, 0x33, 0xFB,
1732         0xCC, 0x93, 0x9D, 0xCE, 0x24, 0x9B, 0x3E, 0xF9, 0x7D, 0x2F,
1733         0xE3, 0x63, 0x63, 0x0C, 0x75, 0xD8, 0xF6, 0x81, 0xB2, 0x02,
1734         0xAE, 0xC4, 0x61, 0x7A, 0xD3, 0xDF, 0x1E, 0xD5, 0xD5, 0xFD,
1735         0x65, 0x61, 0x24, 0x33, 0xF5, 0x1F, 0x5F, 0x06, 0x6E, 0xD0,
1736         0x85, 0x63, 0x65, 0x55, 0x3D, 0xED, 0x1A, 0xF3, 0xB5, 0x57,
1737         0x13, 0x5E, 0x7F, 0x57, 0xC9, 0x35, 0x98, 0x4F, 0x0C, 0x70,
1738         0xE0, 0xE6, 0x8B, 0x77, 0xE2, 0xA6, 0x89, 0xDA, 0xF3, 0xEF,
1739         0xE8, 0x72, 0x1D, 0xF1, 0x58, 0xA1, 0x36, 0xAD, 0xE7, 0x35,
1740         0x30, 0xAC, 0xCA, 0x4F, 0x48, 0x3A, 0x79, 0x7A, 0xBC, 0x0A,
1741         0xB1, 0x82, 0xB3, 0x24, 0xFB, 0x61, 0xD1, 0x08, 0xA9, 0x4B,
1742         0xB2, 0xC8, 0xE3, 0xFB, 0xB9, 0x6A, 0xDA, 0xB7, 0x60, 0xD7,
1743         0xF4, 0x68, 0x1D, 0x4F, 0x42, 0xA3, 0xDE, 0x39, 0x4D, 0xF4,
1744         0xAE, 0x56, 0xED, 0xE7, 0x63, 0x72, 0xBB, 0x19, 0x0B, 0x07,
1745         0xA7, 0xC8, 0xEE, 0x0A, 0x6D, 0x70, 0x9E, 0x02, 0xFC, 0xE1,
1746         0xCD, 0xF7, 0xE2, 0xEC, 0xC0, 0x34, 0x04, 0xCD, 0x28, 0x34,
1747         0x2F, 0x61, 0x91, 0x72, 0xFE, 0x9C, 0xE9, 0x85, 0x83, 0xFF,
1748         0x8E, 0x4F, 0x12, 0x32, 0xEE, 0xF2, 0x81, 0x83, 0xC3, 0xFE,
1749         0x3B, 0x1B, 0x4C, 0x6F, 0xAD, 0x73, 0x3B, 0xB5, 0xFC, 0xBC,
1750         0x2E, 0xC2, 0x20, 0x05, 0xC5, 0x8E, 0xF1, 0x83, 0x7D, 0x16,
1751         0x83, 0xB2, 0xC6, 0xF3, 0x4A, 0x26, 0xC1, 0xB2, 0xEF, 0xFA,
1752         0x88, 0x6B, 0x42, 0x38, 0x61, 0x28, 0x5C, 0x97, 0xFF, 0xFF,
1753         0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
1754     };
1755     static unsigned char dhg_2048[] = {
1756         0x02
1757     };
1758     DH *dh = DH_new();
1759     BIGNUM *p, *g;
1760 
1761     if (dh == NULL)
1762         return NULL;
1763     p = BN_bin2bn(dhp_2048, sizeof(dhp_2048), NULL);
1764     g = BN_bin2bn(dhg_2048, sizeof(dhg_2048), NULL);
1765     if (p == NULL || g == NULL || !DH_set0_pqg(dh, p, NULL, g)) {
1766         DH_free(dh);
1767         BN_free(p);
1768         BN_free(g);
1769         return NULL;
1770     }
1771     return dh;
1772 }
1773 #endif
1774 
1775 
1776 static int
1777 mod_openssl_ssl_conf_curves(server *srv, plugin_config_socket *s, const buffer *ssl_ec_curve)
1778 {
1779     int nid = 0;
1780     /* Support for Elliptic-Curve Diffie-Hellman key exchange */
1781     if (!buffer_string_is_empty(ssl_ec_curve)) {
1782         /* OpenSSL only supports the "named curves"
1783          * from RFC 4492, section 5.1.1. */
1784         nid = wolfSSL_OBJ_sn2nid((char *) ssl_ec_curve->ptr);
1785         if (nid == 0) {
1786             log_error(srv->errh, __FILE__, __LINE__,
1787               "SSL: Unknown curve name %s", ssl_ec_curve->ptr);
1788             return 0;
1789         }
1790     }
1791     else {
1792         /* Default curve */
1793         nid = wolfSSL_OBJ_sn2nid("prime256v1");
1794     }
1795     if (nid) {
1796         EC_KEY *ecdh;
1797         ecdh = EC_KEY_new_by_curve_name(nid);
1798         if (ecdh == NULL) {
1799             log_error(srv->errh, __FILE__, __LINE__,
1800               "SSL: Unable to create curve %s", ssl_ec_curve->ptr);
1801             return 0;
1802         }
1803         wolfSSL_SSL_CTX_set_tmp_ecdh(s->ssl_ctx, ecdh);
1804         SSL_CTX_set_options(s->ssl_ctx, SSL_OP_SINGLE_ECDH_USE);
1805         EC_KEY_free(ecdh);
1806     }
1807 
1808     return 1;
1809 }
1810 
1811 
1812 static int
1813 network_init_ssl (server *srv, plugin_config_socket *s, plugin_data *p)
1814 {
1815     /* load SSL certificates */
1816 
1817       #ifndef SSL_OP_NO_COMPRESSION
1818       #define SSL_OP_NO_COMPRESSION 0
1819       #endif
1820         long ssloptions = SSL_OP_ALL
1821                         | SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION
1822                         | SSL_OP_NO_COMPRESSION;
1823 
1824         s->ssl_ctx = (!s->ssl_use_sslv2 && !s->ssl_use_sslv3)
1825           ? SSL_CTX_new(TLS_server_method())
1826           : SSL_CTX_new(SSLv23_server_method());
1827         if (NULL == s->ssl_ctx) {
1828             log_error(srv->errh, __FILE__, __LINE__,
1829               "SSL: %s", ERR_error_string(ERR_get_error(), NULL));
1830             return -1;
1831         }
1832 
1833       #ifdef SSL_OP_NO_RENEGOTIATION /* openssl 1.1.0 */
1834         if (s->ssl_disable_client_renegotiation)
1835             ssloptions |= SSL_OP_NO_RENEGOTIATION;
1836       #endif
1837 
1838         /* completely useless identifier;
1839          * required for client cert verification to work with sessions */
1840         if (0 == SSL_CTX_set_session_id_context(
1841                    s->ssl_ctx,(const unsigned char*)CONST_STR_LEN("lighttpd"))){
1842             log_error(srv->errh, __FILE__, __LINE__,
1843               "SSL: failed to set session context: %s",
1844               ERR_error_string(ERR_get_error(), NULL));
1845             return -1;
1846         }
1847 
1848       #if !defined(NO_SESSION_CACHE)
1849         const int disable_sess_cache =
1850           srv->srvconf.feature_flags
1851           && !config_plugin_value_tobool(
1852                array_get_element_klen(srv->srvconf.feature_flags,
1853                                       CONST_STR_LEN("ssl.session-cache")), 0);
1854         if (disable_sess_cache)
1855             /* disable session cache; session tickets are preferred */
1856             SSL_CTX_set_session_cache_mode(s->ssl_ctx,
1857                                              SSL_SESS_CACHE_OFF
1858                                            | SSL_SESS_CACHE_NO_AUTO_CLEAR
1859                                            | SSL_SESS_CACHE_NO_INTERNAL);
1860       #endif
1861 
1862         if (s->ssl_empty_fragments) {
1863           #ifdef SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS
1864             ssloptions &= ~SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS;
1865           #else
1866             ssloptions &= ~0x00000800L; /* hardcode constant */
1867             log_error(srv->errh, __FILE__, __LINE__,
1868               "WARNING: SSL: 'insert empty fragments' not supported by the "
1869               "openssl version used to compile lighttpd with");
1870           #endif
1871         }
1872 
1873         SSL_CTX_set_options(s->ssl_ctx, ssloptions);
1874         SSL_CTX_set_info_callback(s->ssl_ctx, ssl_info_callback);
1875 
1876         /*(wolfSSL does not support SSLv2)*/
1877 
1878         if (!s->ssl_use_sslv3 && 0 != SSL_OP_NO_SSLv3) {
1879             /* disable SSLv3 */
1880             if ((SSL_OP_NO_SSLv3
1881                  & SSL_CTX_set_options(s->ssl_ctx, SSL_OP_NO_SSLv3))
1882                 != SSL_OP_NO_SSLv3) {
1883                 log_error(srv->errh, __FILE__, __LINE__,
1884                   "SSL: %s", ERR_error_string(ERR_get_error(), NULL));
1885                 return -1;
1886             }
1887         }
1888 
1889         if (!buffer_string_is_empty(s->ssl_cipher_list)) {
1890             /* Disable support for low encryption ciphers */
1891             if (SSL_CTX_set_cipher_list(s->ssl_ctx,s->ssl_cipher_list->ptr)!=1){
1892                 log_error(srv->errh, __FILE__, __LINE__,
1893                   "SSL: %s", ERR_error_string(ERR_get_error(), NULL));
1894                 return -1;
1895             }
1896 
1897             if (s->ssl_honor_cipher_order) {
1898                 SSL_CTX_set_options(s->ssl_ctx,SSL_OP_CIPHER_SERVER_PREFERENCE);
1899             }
1900         }
1901 
1902       #ifdef SSL_OP_PRIORITIZE_CHACHA /*(openssl 1.1.1)*/
1903         if (s->ssl_honor_cipher_order)
1904             SSL_CTX_set_options(s->ssl_ctx, SSL_OP_PRIORITIZE_CHACHA);
1905       #endif
1906 
1907       #ifndef NO_DH
1908       {
1909         DH *dh;
1910         /* Support for Diffie-Hellman key exchange */
1911         if (!buffer_string_is_empty(s->ssl_dh_file)) {
1912             const char *fn = s->ssl_dh_file->ptr;
1913             off_t dlen = 1*1024*1024;/*(arbitrary limit: 1 MB; expect < 1 KB)*/
1914             char *data = fdevent_load_file(fn, &dlen, srv->errh, malloc, free);
1915             int rc = (NULL != data) ? 0 : -1;
1916             if (0 == rc)
1917                   wolfSSL_CTX_SetTmpDH_buffer(s->ssl_ctx, (unsigned char *)data,
1918                                               (long)dlen, WOLFSSL_FILETYPE_PEM);
1919             if (dlen) safe_memclear(data, dlen);
1920             free(data);
1921             if (rc < 0) {
1922                 log_error(srv->errh, __FILE__, __LINE__,
1923                   "SSL: Unable to read DH params from file %s",
1924                   s->ssl_dh_file->ptr);
1925                 return -1;
1926             }
1927         }
1928         else {
1929             dh = get_dh2048();
1930             if (dh == NULL) {
1931                 log_error(srv->errh, __FILE__, __LINE__,
1932                   "SSL: get_dh2048() failed");
1933                 return -1;
1934             }
1935             SSL_CTX_set_tmp_dh(s->ssl_ctx,dh);
1936             DH_free(dh);
1937         }
1938         SSL_CTX_set_options(s->ssl_ctx,SSL_OP_SINGLE_DH_USE);
1939       }
1940       #else
1941         if (!buffer_string_is_empty(s->ssl_dh_file)) {
1942             log_error(srv->errh, __FILE__, __LINE__,
1943               "SSL: openssl compiled without DH support, "
1944               "can't load parameters from %s", s->ssl_dh_file->ptr);
1945         }
1946       #endif
1947 
1948         if (!mod_openssl_ssl_conf_curves(srv, s, s->ssl_ec_curve))
1949             return -1;
1950 
1951       #ifdef HAVE_SESSION_TICKET
1952         wolfSSL_CTX_set_tlsext_ticket_key_cb(s->ssl_ctx, ssl_tlsext_ticket_key_cb);
1953       #endif
1954 
1955       #ifdef HAVE_OCSP
1956         wolfSSL_CTX_set_tlsext_status_cb(s->ssl_ctx, ssl_tlsext_status_cb);
1957       #endif
1958 
1959         /* load all ssl.ca-files specified in the config into each SSL_CTX
1960          * XXX: This might be a bit excessive, but are all trusted CAs
1961          *      TODO: prefer to load on-demand in mod_openssl_cert_cb()
1962          *            for openssl >= 1.0.2 */
1963         if (!mod_wolfssl_load_ca_files(s->ssl_ctx, p, srv))
1964             return -1;
1965 
1966         if (s->ssl_verifyclient) {
1967             if (NULL == s->ssl_ca_file) {
1968                 log_error(srv->errh, __FILE__, __LINE__,
1969                   "SSL: You specified ssl.verifyclient.activate "
1970                   "but no ssl.ca-file");
1971                 return -1;
1972             }
1973           #ifndef OPENSSL_ALL
1974                 log_error(srv->errh, __FILE__, __LINE__,
1975                   "SSL: You specified ssl.verifyclient.activate "
1976                   "but wolfssl library built without necessary support");
1977                 return -1;
1978           #else
1979             /* WTH wolfssl?  wolfSSL_dup_CA_list() is a stub which returns NULL
1980              * and so DN names in cert request are not set here.
1981              * (A patch has been submitted to WolfSSL to correct this)
1982              * https://github.com/wolfSSL/wolfssl/pull/3098 */
1983             STACK_OF(X509_NAME) * const cert_names = s->ssl_ca_dn_file
1984               ? s->ssl_ca_dn_file
1985               : s->ssl_ca_file->names;
1986             wolfSSL_CTX_set_client_CA_list(s->ssl_ctx,
1987                                            wolfSSL_dup_CA_list(cert_names));
1988             int mode = SSL_VERIFY_PEER;
1989             if (s->ssl_verifyclient_enforce) {
1990                 mode |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
1991             }
1992             wolfSSL_CTX_set_verify(s->ssl_ctx, mode, verify_callback);
1993             wolfSSL_CTX_set_verify_depth(s->ssl_ctx,
1994                                          s->ssl_verifyclient_depth + 1);
1995           #endif
1996             if (!buffer_string_is_empty(s->ssl_ca_crl_file)) {
1997                 if (!mod_wolfssl_load_cacrls(s->ssl_ctx,s->ssl_ca_crl_file,srv))
1998                     return -1;
1999             }
2000         }
2001 
2002         if (1 != mod_wolfssl_CTX_use_certificate_chain_file(
2003                    s->ssl_ctx, s->pc->ssl_pemfile->ptr, srv->errh))
2004             return -1;
2005 
2006         buffer *k = s->pc->ssl_pemfile_pkey;
2007         if (1 != wolfSSL_CTX_use_PrivateKey_buffer(s->ssl_ctx,
2008                                                    (unsigned char *)k->ptr,
2009                                                    (int)buffer_string_length(k),
2010                                                    WOLFSSL_FILETYPE_ASN1)) {
2011             log_error(srv->errh, __FILE__, __LINE__,
2012               "SSL: %s %s %s", ERR_error_string(ERR_get_error(), NULL),
2013               s->pc->ssl_pemfile->ptr, s->pc->ssl_privkey->ptr);
2014             return -1;
2015         }
2016 
2017         if (SSL_CTX_check_private_key(s->ssl_ctx) != 1) {
2018             log_error(srv->errh, __FILE__, __LINE__,
2019               "SSL: Private key does not match the certificate public key, "
2020               "reason: %s %s %s", ERR_error_string(ERR_get_error(), NULL),
2021               s->pc->ssl_pemfile->ptr, s->pc->ssl_privkey->ptr);
2022             return -1;
2023         }
2024 
2025         SSL_CTX_set_default_read_ahead(s->ssl_ctx, s->ssl_read_ahead);
2026         wolfSSL_CTX_set_mode(s->ssl_ctx,
2027                              SSL_MODE_ENABLE_PARTIAL_WRITE);
2028         wolfSSL_CTX_set_mode(s->ssl_ctx, /*(wolfSSL default mode)*/
2029                              WOLFSSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
2030       #ifdef wolfSSL_SSL_MODE_RELEASE_BUFFERS
2031         wolfSSL_CTX_set_mode(s->ssl_ctx, /*(not currently implemented)*/
2032                              wolfSSL_SSL_MODE_RELEASE_BUFFERS);
2033       #endif
2034 
2035       #ifdef HAVE_TLS_EXTENSIONS
2036         /*(wolfSSL preprocessor defines are obnoxious)*/
2037         /*(code should be HAVE_SNI, but is hidden by OPENSSL_ALL
2038          * even though the comment in wolfssl code on the #endif
2039          * says (OPENSSL_ALL
2040          *       || (OPENSSL_EXTRA
2041          *           && (HAVE_STUNNEL || WOLFSSL_NGINX || HAVE_LIGHTY)))
2042          * and sniRecvCb sniRecvCbArg are hidden by *different* set of defines
2043          * in wolfssl/internal.h)
2044          * Note: wolfSSL SNI callbacks members not present unless wolfSSL is
2045          * built OPENSSL_ALL or some additional combination of preprocessor
2046          * defines.  The following should work with more recent wolfSSL versions
2047          * (and HAVE_LIGHTY is not sufficient in wolfssl <= 4.5.0) */
2048        #if defined(OPENSSL_ALL) \
2049         || (defined(OPENSSL_EXTRA) \
2050             && (defined(HAVE_STUNNEL) \
2051                 || defined(WOLFSSL_NGINX) \
2052                 || defined(WOLFSSL_HAPROXY)))
2053        #else
2054        #undef HAVE_SNI
2055        #endif
2056        #ifdef HAVE_SNI
2057         wolfSSL_CTX_set_servername_callback(
2058             s->ssl_ctx, network_ssl_servername_callback);
2059         wolfSSL_CTX_set_servername_arg(s->ssl_ctx, srv);
2060        #else
2061         log_error(srv->errh, __FILE__, __LINE__,
2062           "SSL: WARNING: SNI callbacks *crippled* in wolfSSL library build");
2063         UNUSED(network_ssl_servername_callback);
2064        #endif
2065 
2066        #ifdef HAVE_ALPN
2067        #ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
2068         SSL_CTX_set_alpn_select_cb(s->ssl_ctx,mod_openssl_alpn_select_cb,NULL);
2069        #endif
2070        #endif
2071       #endif
2072 
2073         if (!s->ssl_use_sslv3 && !s->ssl_use_sslv2
2074             && wolfSSL_CTX_SetMinVersion(s->ssl_ctx, WOLFSSL_TLSV1_2)
2075                != WOLFSSL_SUCCESS)
2076             return -1;
2077 
2078         if (s->ssl_conf_cmd && s->ssl_conf_cmd->used) {
2079             if (0 != mod_openssl_ssl_conf_cmd(srv, s)) return -1;
2080         }
2081 
2082         return 0;
2083 }
2084 
2085 
2086 static int
2087 mod_openssl_set_defaults_sockets(server *srv, plugin_data *p)
2088 {
2089     static const config_plugin_keys_t cpk[] = {
2090       { CONST_STR_LEN("ssl.engine"),
2091         T_CONFIG_BOOL,
2092         T_CONFIG_SCOPE_CONNECTION }
2093      ,{ CONST_STR_LEN("ssl.cipher-list"),
2094         T_CONFIG_STRING,
2095         T_CONFIG_SCOPE_CONNECTION }
2096      ,{ CONST_STR_LEN("ssl.honor-cipher-order"),
2097         T_CONFIG_BOOL,
2098         T_CONFIG_SCOPE_CONNECTION }
2099      ,{ CONST_STR_LEN("ssl.dh-file"),
2100         T_CONFIG_STRING,
2101         T_CONFIG_SCOPE_CONNECTION }
2102      ,{ CONST_STR_LEN("ssl.ec-curve"),
2103         T_CONFIG_STRING,
2104         T_CONFIG_SCOPE_CONNECTION }
2105      ,{ CONST_STR_LEN("ssl.openssl.ssl-conf-cmd"),
2106         T_CONFIG_ARRAY_KVSTRING,
2107         T_CONFIG_SCOPE_CONNECTION }
2108      ,{ CONST_STR_LEN("ssl.pemfile"), /* included to process global scope */
2109         T_CONFIG_STRING,
2110         T_CONFIG_SCOPE_CONNECTION }
2111      ,{ CONST_STR_LEN("ssl.empty-fragments"),
2112         T_CONFIG_BOOL,
2113         T_CONFIG_SCOPE_CONNECTION }
2114      ,{ CONST_STR_LEN("ssl.use-sslv2"),
2115         T_CONFIG_BOOL,
2116         T_CONFIG_SCOPE_CONNECTION }
2117      ,{ CONST_STR_LEN("ssl.use-sslv3"),
2118         T_CONFIG_BOOL,
2119         T_CONFIG_SCOPE_CONNECTION }
2120      ,{ CONST_STR_LEN("ssl.stek-file"),
2121         T_CONFIG_STRING,
2122         T_CONFIG_SCOPE_SERVER }
2123      ,{ NULL, 0,
2124         T_CONFIG_UNSET,
2125         T_CONFIG_SCOPE_UNSET }
2126     };
2127     /* WolfSSL does not have mapping for "HIGH" */
2128     /* cipher list is (current) output of "openssl ciphers HIGH" */
2129     static const buffer default_ssl_cipher_list = { CONST_STR_LEN("TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256:TLS_AES_128_CCM_SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-DSS-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-CCM8:ECDHE-ECDSA-AES256-CCM:DHE-RSA-AES256-CCM8:DHE-RSA-AES256-CCM:ECDHE-ECDSA-ARIA256-GCM-SHA384:ECDHE-ARIA256-GCM-SHA384:DHE-DSS-ARIA256-GCM-SHA384:DHE-RSA-ARIA256-GCM-SHA384:ADH-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:DHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-CCM8:ECDHE-ECDSA-AES128-CCM:DHE-RSA-AES128-CCM8:DHE-RSA-AES128-CCM:ECDHE-ECDSA-ARIA128-GCM-SHA256:ECDHE-ARIA128-GCM-SHA256:DHE-DSS-ARIA128-GCM-SHA256:DHE-RSA-ARIA128-GCM-SHA256:ADH-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA256:ECDHE-ECDSA-CAMELLIA256-SHA384:ECDHE-RSA-CAMELLIA256-SHA384:DHE-RSA-CAMELLIA256-SHA256:DHE-DSS-CAMELLIA256-SHA256:ADH-AES256-SHA256:ADH-CAMELLIA256-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA256:DHE-DSS-AES128-SHA256:ECDHE-ECDSA-CAMELLIA128-SHA256:ECDHE-RSA-CAMELLIA128-SHA256:DHE-RSA-CAMELLIA128-SHA256:DHE-DSS-CAMELLIA128-SHA256:ADH-AES128-SHA256:ADH-CAMELLIA128-SHA256:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES256-SHA:DHE-DSS-AES256-SHA:DHE-RSA-CAMELLIA256-SHA:DHE-DSS-CAMELLIA256-SHA:AECDH-AES256-SHA:ADH-AES256-SHA:ADH-CAMELLIA256-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA:DHE-RSA-CAMELLIA128-SHA:DHE-DSS-CAMELLIA128-SHA:AECDH-AES128-SHA:ADH-AES128-SHA:ADH-CAMELLIA128-SHA:RSA-PSK-AES256-GCM-SHA384:DHE-PSK-AES256-GCM-SHA384:RSA-PSK-CHACHA20-POLY1305:DHE-PSK-CHACHA20-POLY1305:ECDHE-PSK-CHACHA20-POLY1305:DHE-PSK-AES256-CCM8:DHE-PSK-AES256-CCM:RSA-PSK-ARIA256-GCM-SHA384:DHE-PSK-ARIA256-GCM-SHA384:AES256-GCM-SHA384:AES256-CCM8:AES256-CCM:ARIA256-GCM-SHA384:PSK-AES256-GCM-SHA384:PSK-CHACHA20-POLY1305:PSK-AES256-CCM8:PSK-AES256-CCM:PSK-ARIA256-GCM-SHA384:RSA-PSK-AES128-GCM-SHA256:DHE-PSK-AES128-GCM-SHA256:DHE-PSK-AES128-CCM8:DHE-PSK-AES128-CCM:RSA-PSK-ARIA128-GCM-SHA256:DHE-PSK-ARIA128-GCM-SHA256:AES128-GCM-SHA256:AES128-CCM8:AES128-CCM:ARIA128-GCM-SHA256:PSK-AES128-GCM-SHA256:PSK-AES128-CCM8:PSK-AES128-CCM:PSK-ARIA128-GCM-SHA256:AES256-SHA256:CAMELLIA256-SHA256:AES128-SHA256:CAMELLIA128-SHA256:ECDHE-PSK-AES256-CBC-SHA384:ECDHE-PSK-AES256-CBC-SHA:SRP-DSS-AES-256-CBC-SHA:SRP-RSA-AES-256-CBC-SHA:SRP-AES-256-CBC-SHA:RSA-PSK-AES256-CBC-SHA384:DHE-PSK-AES256-CBC-SHA384:RSA-PSK-AES256-CBC-SHA:DHE-PSK-AES256-CBC-SHA:ECDHE-PSK-CAMELLIA256-SHA384:RSA-PSK-CAMELLIA256-SHA384:DHE-PSK-CAMELLIA256-SHA384:AES256-SHA:CAMELLIA256-SHA:PSK-AES256-CBC-SHA384:PSK-AES256-CBC-SHA:PSK-CAMELLIA256-SHA384:ECDHE-PSK-AES128-CBC-SHA256:ECDHE-PSK-AES128-CBC-SHA:SRP-DSS-AES-128-CBC-SHA:SRP-RSA-AES-128-CBC-SHA:SRP-AES-128-CBC-SHA:RSA-PSK-AES128-CBC-SHA256:DHE-PSK-AES128-CBC-SHA256:RSA-PSK-AES128-CBC-SHA:DHE-PSK-AES128-CBC-SHA:ECDHE-PSK-CAMELLIA128-SHA256:RSA-PSK-CAMELLIA128-SHA256:DHE-PSK-CAMELLIA128-SHA256:AES128-SHA:CAMELLIA128-SHA:PSK-AES128-CBC-SHA256:PSK-AES128-CBC-SHA:PSK-CAMELLIA128-SHA256"), 0 };
2130 
2131     p->ssl_ctxs = calloc(srv->config_context->used, sizeof(plugin_ssl_ctx));
2132     force_assert(p->ssl_ctxs);
2133 
2134     int rc = HANDLER_GO_ON;
2135     plugin_data_base srvplug;
2136     memset(&srvplug, 0, sizeof(srvplug));
2137     plugin_data_base * const ps = &srvplug;
2138     if (!config_plugin_values_init(srv, ps, cpk, "mod_openssl"))
2139         return HANDLER_ERROR;
2140 
2141     plugin_config_socket defaults;
2142     memset(&defaults, 0, sizeof(defaults));
2143     defaults.ssl_honor_cipher_order = 1;
2144     defaults.ssl_cipher_list = &default_ssl_cipher_list;
2145 
2146     /* process and validate config directives for global and $SERVER["socket"]
2147      * (init i to 0 if global context; to 1 to skip empty global context) */
2148     for (int i = !ps->cvlist[0].v.u2[1]; i < ps->nconfig; ++i) {
2149         config_cond_info cfginfo;
2150         config_get_config_cond_info(&cfginfo, (uint32_t)ps->cvlist[i].k_id);
2151         int is_socket_scope = (0 == i || cfginfo.comp == COMP_SERVER_SOCKET);
2152         int count_not_engine = 0;
2153 
2154         plugin_config_socket conf;
2155         memcpy(&conf, &defaults, sizeof(conf));
2156 
2157         /*(preserve prior behavior; not inherited)*/
2158         /*(forcing inheritance might break existing configs where SSL is enabled
2159          * by default in the global scope, but not $SERVER["socket"]=="*:80") */
2160         conf.ssl_enabled = 0;
2161 
2162         config_plugin_value_t *cpv = ps->cvlist + ps->cvlist[i].v.u2[0];
2163         for (; -1 != cpv->k_id; ++cpv) {
2164             /* ignore ssl.pemfile (k_id=6); included to process global scope */
2165             if (!is_socket_scope && cpv->k_id != 6) {
2166                 log_error(srv->errh, __FILE__, __LINE__,
2167                   "%s is valid only in global scope or "
2168                   "$SERVER[\"socket\"] condition", cpk[cpv->k_id].k);
2169                 continue;
2170             }
2171             ++count_not_engine;
2172             switch (cpv->k_id) {
2173               case 0: /* ssl.engine */
2174                 conf.ssl_enabled = (0 != cpv->v.u);
2175                 --count_not_engine;
2176                 break;
2177               case 1: /* ssl.cipher-list */
2178                 conf.ssl_cipher_list = cpv->v.b;
2179                 break;
2180               case 2: /* ssl.honor-cipher-order */
2181                 conf.ssl_honor_cipher_order = (0 != cpv->v.u);
2182                 break;
2183               case 3: /* ssl.dh-file */
2184                 conf.ssl_dh_file = cpv->v.b;
2185                 break;
2186               case 4: /* ssl.ec-curve */
2187                 conf.ssl_ec_curve = cpv->v.b;
2188                 break;
2189               case 5: /* ssl.openssl.ssl-conf-cmd */
2190                 *(const array **)&conf.ssl_conf_cmd = cpv->v.a;
2191                 break;
2192               case 6: /* ssl.pemfile */
2193                 /* ignore here; included to process global scope when
2194                  * ssl.pemfile is set, but ssl.engine is not "enable" */
2195                 break;
2196               case 7: /* ssl.empty-fragments */
2197                 conf.ssl_empty_fragments = (0 != cpv->v.u);
2198                 log_error(srv->errh, __FILE__, __LINE__, "SSL: "
2199                   "ssl.empty-fragments is deprecated and will soon be "
2200                   "removed.  It is disabled by default.");
2201                 if (conf.ssl_empty_fragments)
2202                     log_error(srv->errh, __FILE__, __LINE__, "SSL: "
2203                       "If needed, use: ssl.openssl.ssl-conf-cmd = "
2204                       "(\"Options\" => \"EmptyFragments\")");
2205                 log_error(srv->errh, __FILE__, __LINE__, "SSL: "
2206                   "ssl.empty-fragments is a "
2207                   "counter-measure against a SSL 3.0/TLS 1.0 protocol "
2208                   "vulnerability affecting CBC ciphers, which cannot be handled"
2209                   " by some broken (Microsoft) SSL implementations.");
2210                 break;
2211               case 8: /* ssl.use-sslv2 */
2212                 conf.ssl_use_sslv2 = (0 != cpv->v.u);
2213                 log_error(srv->errh, __FILE__, __LINE__, "SSL: "
2214                   "ssl.use-sslv2 is deprecated and will soon be removed.  "
2215                   "It is disabled by default.  "
2216                   "Many modern TLS libraries no longer support SSLv2.");
2217                 break;
2218               case 9: /* ssl.use-sslv3 */
2219                 conf.ssl_use_sslv3 = (0 != cpv->v.u);
2220                 log_error(srv->errh, __FILE__, __LINE__, "SSL: "
2221                   "ssl.use-sslv3 is deprecated and will soon be removed.  "
2222                   "It is disabled by default.  "
2223                   "Many modern TLS libraries no longer support SSLv3.");
2224                 if (conf.ssl_use_sslv3)
2225                     log_error(srv->errh, __FILE__, __LINE__, "SSL: "
2226                       "If needed, use: ssl.openssl.ssl-conf-cmd = "
2227                       "(\"MinProtocol\" => \"SSLv3\")");
2228                 break;
2229               case 10:/* ssl.stek-file */
2230                 if (!buffer_is_empty(cpv->v.b))
2231                     p->ssl_stek_file = cpv->v.b->ptr;
2232                 break;
2233               default:/* should not happen */
2234                 break;
2235             }
2236         }
2237         if (HANDLER_GO_ON != rc) break;
2238         if (0 == i) memcpy(&defaults, &conf, sizeof(conf));
2239 
2240         if (0 != i && !conf.ssl_enabled) continue;
2241 
2242         /* fill plugin_config_socket with global context then $SERVER["socket"]
2243          * only for directives directly in current $SERVER["socket"] condition*/
2244 
2245         /*conf.pc                     = p->defaults.pc;*/
2246         conf.ssl_ca_file              = p->defaults.ssl_ca_file;
2247         conf.ssl_ca_dn_file           = p->defaults.ssl_ca_dn_file;
2248         conf.ssl_ca_crl_file          = p->defaults.ssl_ca_crl_file;
2249         conf.ssl_verifyclient         = p->defaults.ssl_verifyclient;
2250         conf.ssl_verifyclient_enforce = p->defaults.ssl_verifyclient_enforce;
2251         conf.ssl_verifyclient_depth   = p->defaults.ssl_verifyclient_depth;
2252         conf.ssl_read_ahead           = p->defaults.ssl_read_ahead;
2253 
2254         int sidx = ps->cvlist[i].k_id;
2255         for (int j = !p->cvlist[0].v.u2[1]; j < p->nconfig; ++j) {
2256             if (p->cvlist[j].k_id != sidx) continue;
2257             /*if (0 == sidx) break;*//*(repeat to get ssl_pemfile,ssl_privkey)*/
2258             cpv = p->cvlist + p->cvlist[j].v.u2[0];
2259             for (; -1 != cpv->k_id; ++cpv) {
2260                 ++count_not_engine;
2261                 switch (cpv->k_id) {
2262                   case 0: /* ssl.pemfile */
2263                     if (cpv->vtype == T_CONFIG_LOCAL)
2264                         conf.pc = cpv->v.v;
2265                     break;
2266                   case 2: /* ssl.ca-file */
2267                     if (cpv->vtype == T_CONFIG_LOCAL)
2268                         conf.ssl_ca_file = cpv->v.v;
2269                     break;
2270                   case 3: /* ssl.ca-dn-file */
2271                     if (cpv->vtype == T_CONFIG_LOCAL)
2272                         conf.ssl_ca_dn_file = cpv->v.v;
2273                     break;
2274                   case 4: /* ssl.ca-crl-file */
2275                     conf.ssl_ca_crl_file = cpv->v.b;
2276                     break;
2277                   case 5: /* ssl.read-ahead */
2278                     conf.ssl_read_ahead = (0 != cpv->v.u);
2279                     break;
2280                   case 6: /* ssl.disable-client-renegotiation */
2281                     conf.ssl_disable_client_renegotiation = (0 != cpv->v.u);
2282                     break;
2283                   case 7: /* ssl.verifyclient.activate */
2284                     conf.ssl_verifyclient = (0 != cpv->v.u);
2285                     break;
2286                   case 8: /* ssl.verifyclient.enforce */
2287                     conf.ssl_verifyclient_enforce = (0 != cpv->v.u);
2288                     break;
2289                   case 9: /* ssl.verifyclient.depth */
2290                     conf.ssl_verifyclient_depth = (unsigned char)cpv->v.shrt;
2291                     break;
2292                   default:
2293                     break;
2294                 }
2295             }
2296             break;
2297         }
2298 
2299         if (NULL == conf.pc) {
2300             if (0 == i && !conf.ssl_enabled) continue;
2301             if (0 != i) {
2302                 /* inherit ssl settings from global scope
2303                  * (if only ssl.engine = "enable" and no other ssl.* settings)
2304                  * (This is for convenience when defining both IPv4 and IPv6
2305                  *  and desiring to inherit the ssl config from global context
2306                  *  without having to duplicate the directives)*/
2307                 if (count_not_engine
2308                     || (conf.ssl_enabled && NULL == p->ssl_ctxs[0].ssl_ctx)) {
2309                     log_error(srv->errh, __FILE__, __LINE__,
2310                       "ssl.pemfile has to be set in same $SERVER[\"socket\"] scope "
2311                       "as other ssl.* directives, unless only ssl.engine is set, "
2312                       "inheriting ssl.* from global scope");
2313                     rc = HANDLER_ERROR;
2314                     continue;
2315                 }
2316                 plugin_ssl_ctx * const s = p->ssl_ctxs + sidx;
2317                 *s = *p->ssl_ctxs;/*(copy struct of ssl_ctx from global scope)*/
2318                 continue;
2319             }
2320             /* PEM file is required */
2321             log_error(srv->errh, __FILE__, __LINE__,
2322               "ssl.pemfile has to be set when ssl.engine = \"enable\"");
2323             rc = HANDLER_ERROR;
2324             continue;
2325         }
2326 
2327         /* configure ssl_ctx for socket */
2328 
2329         /*conf.ssl_ctx = NULL;*//*(filled by network_init_ssl() even on error)*/
2330         if (0 == network_init_ssl(srv, &conf, p)) {
2331             plugin_ssl_ctx * const s = p->ssl_ctxs + sidx;
2332             s->ssl_ctx = conf.ssl_ctx;
2333         }
2334         else {
2335             SSL_CTX_free(conf.ssl_ctx);
2336             rc = HANDLER_ERROR;
2337         }
2338     }
2339 
2340   #ifdef HAVE_SESSION_TICKET
2341     if (rc == HANDLER_GO_ON && ssl_is_init)
2342         mod_openssl_session_ticket_key_check(p, log_epoch_secs);
2343   #endif
2344 
2345     free(srvplug.cvlist);
2346     return rc;
2347 }
2348 
2349 
2350 SETDEFAULTS_FUNC(mod_openssl_set_defaults)
2351 {
2352     static const config_plugin_keys_t cpk[] = {
2353       { CONST_STR_LEN("ssl.pemfile"),
2354         T_CONFIG_STRING,
2355         T_CONFIG_SCOPE_CONNECTION }
2356      ,{ CONST_STR_LEN("ssl.privkey"),
2357         T_CONFIG_STRING,
2358         T_CONFIG_SCOPE_CONNECTION }
2359      ,{ CONST_STR_LEN("ssl.ca-file"),
2360         T_CONFIG_STRING,
2361         T_CONFIG_SCOPE_CONNECTION }
2362      ,{ CONST_STR_LEN("ssl.ca-dn-file"),
2363         T_CONFIG_STRING,
2364         T_CONFIG_SCOPE_CONNECTION }
2365      ,{ CONST_STR_LEN("ssl.ca-crl-file"),
2366         T_CONFIG_STRING,
2367         T_CONFIG_SCOPE_CONNECTION }
2368      ,{ CONST_STR_LEN("ssl.read-ahead"),
2369         T_CONFIG_BOOL,
2370         T_CONFIG_SCOPE_CONNECTION }
2371      ,{ CONST_STR_LEN("ssl.disable-client-renegotiation"),
2372         T_CONFIG_BOOL,
2373         T_CONFIG_SCOPE_CONNECTION }
2374      ,{ CONST_STR_LEN("ssl.verifyclient.activate"),
2375         T_CONFIG_BOOL,
2376         T_CONFIG_SCOPE_CONNECTION }
2377      ,{ CONST_STR_LEN("ssl.verifyclient.enforce"),
2378         T_CONFIG_BOOL,
2379         T_CONFIG_SCOPE_CONNECTION }
2380      ,{ CONST_STR_LEN("ssl.verifyclient.depth"),
2381         T_CONFIG_SHORT,
2382         T_CONFIG_SCOPE_CONNECTION }
2383      ,{ CONST_STR_LEN("ssl.verifyclient.username"),
2384         T_CONFIG_STRING,
2385         T_CONFIG_SCOPE_CONNECTION }
2386      ,{ CONST_STR_LEN("ssl.verifyclient.exportcert"),
2387         T_CONFIG_BOOL,
2388         T_CONFIG_SCOPE_CONNECTION }
2389      ,{ CONST_STR_LEN("ssl.acme-tls-1"),
2390         T_CONFIG_STRING,
2391         T_CONFIG_SCOPE_CONNECTION }
2392      ,{ CONST_STR_LEN("ssl.stapling-file"),
2393         T_CONFIG_STRING,
2394         T_CONFIG_SCOPE_CONNECTION }
2395      ,{ CONST_STR_LEN("debug.log-ssl-noise"),
2396         T_CONFIG_BOOL,
2397         T_CONFIG_SCOPE_CONNECTION }
2398      ,{ NULL, 0,
2399         T_CONFIG_UNSET,
2400         T_CONFIG_SCOPE_UNSET }
2401     };
2402 
2403     plugin_data * const p = p_d;
2404     p->srv = srv;
2405     p->cafiles = array_init(0);
2406     if (!config_plugin_values_init(srv, p, cpk, "mod_openssl"))
2407         return HANDLER_ERROR;
2408 
2409     const buffer *default_ssl_ca_crl_file = NULL;
2410 
2411     /* process and validate config directives
2412      * (init i to 0 if global context; to 1 to skip empty global context) */
2413     for (int i = !p->cvlist[0].v.u2[1]; i < p->nconfig; ++i) {
2414         config_plugin_value_t *cpv = p->cvlist + p->cvlist[i].v.u2[0];
2415         config_plugin_value_t *pemfile = NULL;
2416         config_plugin_value_t *privkey = NULL;
2417         const buffer *ssl_stapling_file = NULL;
2418         const buffer *ssl_ca_file = NULL;
2419         const buffer *ssl_ca_dn_file = NULL;
2420         const buffer *ssl_ca_crl_file = NULL;
2421         X509_STORE *ca_store = NULL;
2422         for (; -1 != cpv->k_id; ++cpv) {
2423             switch (cpv->k_id) {
2424               case 0: /* ssl.pemfile */
2425                 if (!buffer_string_is_empty(cpv->v.b)) pemfile = cpv;
2426                 break;
2427               case 1: /* ssl.privkey */
2428                 if (!buffer_string_is_empty(cpv->v.b)) privkey = cpv;
2429                 break;
2430               case 2: /* ssl.ca-file */
2431                 if (buffer_string_is_empty(cpv->v.b)) break;
2432                 if (!mod_openssl_init_once_openssl(srv)) return HANDLER_ERROR;
2433                 ssl_ca_file = cpv->v.b;
2434                 cpv->v.v = mod_wolfssl_load_cacerts(ssl_ca_file, srv->errh);
2435                 if (NULL != cpv->v.v) {
2436                     cpv->vtype = T_CONFIG_LOCAL;
2437                     ca_store = ((plugin_cacerts *)cpv->v.v)->certs;
2438                 }
2439                 else {
2440                     log_error(srv->errh, __FILE__, __LINE__, "SSL: %s %s",
2441                       ERR_error_string(ERR_get_error(), NULL),
2442                       ssl_ca_file->ptr);
2443                     return HANDLER_ERROR;
2444                 }
2445                 break;
2446               case 3: /* ssl.ca-dn-file */
2447                 if (buffer_string_is_empty(cpv->v.b)) break;
2448                 if (!mod_openssl_init_once_openssl(srv)) return HANDLER_ERROR;
2449                 ssl_ca_dn_file = cpv->v.b;
2450                #ifndef OPENSSL_ALL
2451                 {
2452                     log_error(srv->errh, __FILE__, __LINE__,
2453                       "SSL: You specified ssl.ca-dn-file "
2454                       "but wolfssl library built without necessary support");
2455                     return HANDLER_ERROR;
2456                 }
2457                #endif
2458                 cpv->v.v = mod_wolfssl_load_client_CA_file(ssl_ca_dn_file,
2459                                                            srv->errh);
2460                 if (NULL != cpv->v.v) {
2461                     cpv->vtype = T_CONFIG_LOCAL;
2462                 }
2463                 else {
2464                     log_error(srv->errh, __FILE__, __LINE__, "SSL: %s %s",
2465                       ERR_error_string(ERR_get_error(), NULL),
2466                       ssl_ca_dn_file->ptr);
2467                     return HANDLER_ERROR;
2468                 }
2469                 break;
2470               case 4: /* ssl.ca-crl-file */
2471                 if (buffer_string_is_empty(cpv->v.b)) break;
2472                 ssl_ca_crl_file = cpv->v.b;
2473                 if (0 == i) default_ssl_ca_crl_file = cpv->v.b;
2474                 break;
2475               case 5: /* ssl.read-ahead */
2476               case 6: /* ssl.disable-client-renegotiation */
2477               case 7: /* ssl.verifyclient.activate */
2478               case 8: /* ssl.verifyclient.enforce */
2479                 break;
2480               case 9: /* ssl.verifyclient.depth */
2481                 if (cpv->v.shrt > 255) {
2482                     log_error(srv->errh, __FILE__, __LINE__,
2483                       "%s is absurdly large (%hu); limiting to 255",
2484                       cpk[cpv->k_id].k, cpv->v.shrt);
2485                     cpv->v.shrt = 255;
2486                 }
2487                 break;
2488               case 10:/* ssl.verifyclient.username */
2489               case 11:/* ssl.verifyclient.exportcert */
2490               case 12:/* ssl.acme-tls-1 */
2491                 break;
2492               case 13:/* ssl.stapling-file */
2493                 ssl_stapling_file = cpv->v.b;
2494                 break;
2495               case 14:/* debug.log-ssl-noise */
2496                 break;
2497               default:/* should not happen */
2498                 break;
2499             }
2500         }
2501 
2502         /* p->cafiles for legacy only */
2503         /* load all ssl.ca-files into a single chain */
2504         /*(certificate load order might matter)*/
2505         if (ssl_ca_dn_file)
2506             array_insert_value(p->cafiles, CONST_BUF_LEN(ssl_ca_dn_file));
2507         if (ssl_ca_file)
2508             array_insert_value(p->cafiles, CONST_BUF_LEN(ssl_ca_file));
2509         UNUSED(ca_store);
2510         UNUSED(ssl_ca_crl_file);
2511         UNUSED(default_ssl_ca_crl_file);
2512 
2513         if (pemfile) {
2514           #ifndef HAVE_TLS_EXTENSIONS
2515             config_cond_info cfginfo;
2516             uint32_t j = (uint32_t)p->cvlist[i].k_id;
2517             config_get_config_cond_info(&cfginfo, j);
2518             if (j > 0 && (COMP_SERVER_SOCKET != cfginfo.comp
2519                           || cfginfo.cond != CONFIG_COND_EQ)) {
2520                 if (COMP_HTTP_HOST == cfginfo.comp)
2521                     log_error(srv->errh, __FILE__, __LINE__, "SSL:"
2522                       "can't use ssl.pemfile with $HTTP[\"host\"], "
2523                       "as openssl version does not support TLS extensions");
2524                 else
2525                     log_error(srv->errh, __FILE__, __LINE__, "SSL:"
2526                       "ssl.pemfile only works in SSL socket binding context "
2527                       "as openssl version does not support TLS extensions");
2528                 return HANDLER_ERROR;
2529             }
2530           #endif
2531             if (NULL == privkey) privkey = pemfile;
2532             pemfile->v.v =
2533               network_openssl_load_pemfile(srv, pemfile->v.b, privkey->v.b,
2534                                            ssl_stapling_file);
2535             if (pemfile->v.v)
2536                 pemfile->vtype = T_CONFIG_LOCAL;
2537             else
2538                 return HANDLER_ERROR;
2539         }
2540     }
2541 
2542     p->defaults.ssl_verifyclient = 0;
2543     p->defaults.ssl_verifyclient_enforce = 1;
2544     p->defaults.ssl_verifyclient_depth = 9;
2545     p->defaults.ssl_verifyclient_export_cert = 0;
2546     p->defaults.ssl_disable_client_renegotiation = 1;
2547     p->defaults.ssl_read_ahead = 0;
2548 
2549     /* initialize p->defaults from global config context */
2550     if (p->nconfig > 0 && p->cvlist->v.u2[1]) {
2551         const config_plugin_value_t *cpv = p->cvlist + p->cvlist->v.u2[0];
2552         if (-1 != cpv->k_id)
2553             mod_openssl_merge_config(&p->defaults, cpv);
2554     }
2555 
2556     return mod_openssl_set_defaults_sockets(srv, p);
2557 }
2558 
2559 
2560     /* local_send_buffer is a static buffer of size (LOCAL_SEND_BUFSIZE)
2561      *
2562      * it has to stay at the same location all the time to satisfy the needs
2563      * of SSL_write to pass the SAME parameter in case of a _WANT_WRITE
2564      *
2565      * buffer is allocated once, is NOT realloced (note: not thread-safe)
2566      *
2567      * (Note: above restriction no longer true since SSL_CTX_set_mode() is
2568      *        called with SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER)
2569      * */
2570 
2571             /* copy small mem chunks into single large buffer before SSL_write()
2572              * to reduce number times write() called underneath SSL_write() and
2573              * potentially reduce number of packets generated if TCP_NODELAY */
2574 
2575 
2576 static int
2577 mod_openssl_close_notify(handler_ctx *hctx);
2578 
2579 
2580 static int
2581 connection_write_cq_ssl (connection *con, chunkqueue *cq, off_t max_bytes)
2582 {
2583     handler_ctx *hctx = con->plugin_ctx[plugin_data_singleton->id];
2584     SSL *ssl = hctx->ssl;
2585     log_error_st * const errh = hctx->errh;
2586 
2587     if (0 != hctx->close_notify) return mod_openssl_close_notify(hctx);
2588 
2589     chunkqueue_remove_finished_chunks(cq);
2590 
2591     while (max_bytes > 0 && !chunkqueue_is_empty(cq)) {
2592         char *data = local_send_buffer;
2593         uint32_t data_len = LOCAL_SEND_BUFSIZE < max_bytes
2594           ? LOCAL_SEND_BUFSIZE
2595           : (uint32_t)max_bytes;
2596         int wr;
2597 
2598         if (0 != chunkqueue_peek_data(cq, &data, &data_len, errh)) return -1;
2599 
2600         /**
2601          * SSL_write man-page
2602          *
2603          * WARNING
2604          *        When an SSL_write() operation has to be repeated because of
2605          *        SSL_ERROR_WANT_READ or SSL_ERROR_WANT_WRITE, it must be
2606          *        repeated with the same arguments.
2607          */
2608 
2609         ERR_clear_error();
2610         wr = SSL_write(ssl, data, data_len);
2611 
2612         if (hctx->renegotiations > 1
2613             && hctx->conf.ssl_disable_client_renegotiation) {
2614             log_error(errh, __FILE__, __LINE__,
2615               "SSL: renegotiation initiated by client, killing connection");
2616             return -1;
2617         }
2618 
2619         if (wr <= 0) {
2620             int ssl_r;
2621             unsigned long err;
2622 
2623             switch ((ssl_r = SSL_get_error(ssl, wr))) {
2624             case SSL_ERROR_WANT_READ:
2625                 con->is_readable = -1;
2626                 return 0; /* try again later */
2627             case SSL_ERROR_WANT_WRITE:
2628                 con->is_writable = -1;
2629                 return 0; /* try again later */
2630             case SSL_ERROR_SYSCALL:
2631                 /* perhaps we have error waiting in our error-queue */
2632                 if (0 != (err = ERR_get_error())) {
2633                     do {
2634                         log_error(errh, __FILE__, __LINE__,
2635                           "SSL: %d %d %s",ssl_r,wr,ERR_error_string(err,NULL));
2636                     } while((err = ERR_get_error()));
2637                 } else if (wr == -1) {
2638                     /* no, but we have errno */
2639                     switch(errno) {
2640                     case EPIPE:
2641                     case ECONNRESET:
2642                         return -2;
2643                     default:
2644                         log_perror(errh, __FILE__, __LINE__,
2645                           "SSL: %d %d", ssl_r, wr);
2646                         break;
2647                     }
2648                 } else {
2649                     /* neither error-queue nor errno ? */
2650                     log_perror(errh, __FILE__, __LINE__,
2651                       "SSL (error): %d %d", ssl_r, wr);
2652                 }
2653                 break;
2654 
2655             case SSL_ERROR_ZERO_RETURN:
2656                 /* clean shutdown on the remote side */
2657 
2658                 if (wr == 0) return -2;
2659 
2660                 /* fall through */
2661             default:
2662                 while((err = ERR_get_error())) {
2663                     log_error(errh, __FILE__, __LINE__,
2664                       "SSL: %d %d %s", ssl_r, wr, ERR_error_string(err, NULL));
2665                 }
2666                 break;
2667             }
2668             return -1;
2669         }
2670 
2671         chunkqueue_mark_written(cq, wr);
2672         max_bytes -= wr;
2673 
2674         if ((size_t) wr < data_len) break; /* try again later */
2675     }
2676 
2677     return 0;
2678 }
2679 
2680 
2681 static int
2682 connection_read_cq_ssl (connection *con, chunkqueue *cq, off_t max_bytes)
2683 {
2684     handler_ctx *hctx = con->plugin_ctx[plugin_data_singleton->id];
2685     int len;
2686     char *mem = NULL;
2687     size_t mem_len = 0;
2688 
2689     UNUSED(max_bytes);
2690 
2691     if (0 != hctx->close_notify) return mod_openssl_close_notify(hctx);
2692 
2693     ERR_clear_error();
2694     do {
2695         len = SSL_pending(hctx->ssl);
2696         mem_len = len < 2048 ? 2048 : (size_t)len;
2697         chunk * const ckpt = cq->last;
2698         mem = chunkqueue_get_memory(cq, &mem_len);
2699 
2700         len = SSL_read(hctx->ssl, mem, mem_len);
2701         if (len > 0) {
2702             chunkqueue_use_memory(cq, ckpt, len);
2703             con->bytes_read += len;
2704         } else {
2705             chunkqueue_use_memory(cq, ckpt, 0);
2706         }
2707 
2708         if (hctx->renegotiations > 1
2709             && hctx->conf.ssl_disable_client_renegotiation) {
2710             log_error(hctx->errh, __FILE__, __LINE__,
2711               "SSL: renegotiation initiated by client, killing connection");
2712             return -1;
2713         }
2714 
2715       #ifdef HAVE_ALPN
2716       #ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
2717         if (hctx->alpn) {
2718             if (hctx->alpn == MOD_OPENSSL_ALPN_ACME_TLS_1) {
2719                 chunkqueue_reset(cq);
2720                 /* initiate handshake in order to send ServerHello.
2721                  * Once TLS handshake is complete, return -1 to result in
2722                  * CON_STATE_ERROR so that socket connection is quickly closed*/
2723                 if (1 == SSL_do_handshake(hctx->ssl)) return -1;
2724                 len = -1;
2725                 break;
2726             }
2727             hctx->alpn = 0;
2728         }
2729       #endif
2730       #endif
2731     } while (len > 0
2732              && (hctx->conf.ssl_read_ahead || SSL_pending(hctx->ssl) > 0));
2733 
2734     if (len < 0) {
2735         int oerrno = errno;
2736         int rc, ssl_err;
2737         switch ((rc = SSL_get_error(hctx->ssl, len))) {
2738         case SSL_ERROR_WANT_WRITE:
2739             con->is_writable = -1;
2740             /* fall through */
2741         case SSL_ERROR_WANT_READ:
2742             con->is_readable = 0;
2743 
2744             /* the manual says we have to call SSL_read with the same arguments
2745              * next time.  we ignore this restriction; no one has complained
2746              * about it in 1.5 yet, so it probably works anyway.
2747              */
2748 
2749             return 0;
2750         case SSL_ERROR_SYSCALL:
2751             /**
2752              * man SSL_get_error()
2753              *
2754              * SSL_ERROR_SYSCALL
2755              *   Some I/O error occurred.  The OpenSSL error queue may contain
2756              *   more information on the error.  If the error queue is empty
2757              *   (i.e. ERR_get_error() returns 0), ret can be used to find out
2758              *   more about the error: If ret == 0, an EOF was observed that
2759              *   violates the protocol.  If ret == -1, the underlying BIO
2760              *   reported an I/O error (for socket I/O on Unix systems, consult
2761              *   errno for details).
2762              *
2763              */
2764             while((ssl_err = ERR_get_error())) {
2765                 /* get all errors from the error-queue */
2766                 log_error(hctx->errh, __FILE__, __LINE__,
2767                   "SSL: %d %s", rc, ERR_error_string(ssl_err, NULL));
2768             }
2769 
2770             switch(oerrno) {
2771             case ECONNRESET:
2772                 if (!hctx->conf.ssl_log_noise) break;
2773                 /* fall through */
2774             default:
2775                 /* (oerrno should be something like ECONNABORTED not 0
2776                  *  if client disconnected before anything was sent
2777                  *  (e.g. TCP connection probe), but it does not appear
2778                  *  that openssl provides such notification, not even
2779                  *  something like SSL_R_SSL_HANDSHAKE_FAILURE) */
2780                 if (0==oerrno && 0==cq->bytes_in && !hctx->conf.ssl_log_noise)
2781                     break;
2782 
2783                 log_error(hctx->errh, __FILE__, __LINE__,
2784                   "SSL: %d %d %d %s", len, rc, oerrno, strerror(oerrno));
2785                 break;
2786             }
2787 
2788             break;
2789         case SSL_ERROR_ZERO_RETURN:
2790             /* clean shutdown on the remote side */
2791 
2792             if (rc == 0) {
2793                 /* FIXME: later */
2794             }
2795 
2796             /* fall through */
2797         default:
2798             while((ssl_err = ERR_get_error())) {
2799                 switch (ERR_GET_REASON(ssl_err)) {
2800                 case SSL_R_SSL_HANDSHAKE_FAILURE:
2801               #ifdef SSL_R_UNEXPECTED_EOF_WHILE_READING
2802                 case SSL_R_UNEXPECTED_EOF_WHILE_READING:
2803               #endif
2804               #ifdef SSL_R_TLSV1_ALERT_UNKNOWN_CA
2805                 case SSL_R_TLSV1_ALERT_UNKNOWN_CA:
2806               #endif
2807               #ifdef SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN
2808                 case SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN:
2809               #endif
2810               #ifdef SSL_R_SSLV3_ALERT_BAD_CERTIFICATE
2811                 case SSL_R_SSLV3_ALERT_BAD_CERTIFICATE:
2812               #endif
2813                     if (!hctx->conf.ssl_log_noise) continue;
2814                     break;
2815                 default:
2816                     break;
2817                 }
2818                 /* get all errors from the error-queue */
2819                 log_error(hctx->errh, __FILE__, __LINE__,
2820                   "SSL: %d %s", rc, ERR_error_string(ssl_err, NULL));
2821             }
2822             break;
2823         }
2824         return -1;
2825     } else if (len == 0) {
2826         con->is_readable = 0;
2827         /* the other end close the connection -> KEEP-ALIVE */
2828 
2829         return -2;
2830     } else {
2831         return 0;
2832     }
2833 }
2834 
2835 
2836 CONNECTION_FUNC(mod_openssl_handle_con_accept)
2837 {
2838     server_socket *srv_sock = con->srv_socket;
2839     if (!srv_sock->is_ssl) return HANDLER_GO_ON;
2840 
2841     plugin_data *p = p_d;
2842     handler_ctx * const hctx = handler_ctx_init();
2843     request_st * const r = &con->request;
2844     hctx->r = r;
2845     hctx->con = con;
2846     hctx->tmp_buf = con->srv->tmp_buf;
2847     hctx->errh = r->conf.errh;
2848     con->plugin_ctx[p->id] = hctx;
2849 
2850     plugin_ssl_ctx * const s = p->ssl_ctxs + srv_sock->sidx;
2851     hctx->ssl = SSL_new(s->ssl_ctx);
2852     if (NULL != hctx->ssl
2853         && SSL_set_app_data(hctx->ssl, hctx)
2854         && SSL_set_fd(hctx->ssl, con->fd)) {
2855         SSL_set_accept_state(hctx->ssl);
2856         con->network_read = connection_read_cq_ssl;
2857         con->network_write = connection_write_cq_ssl;
2858         con->proto_default_port = 443; /* "https" */
2859         mod_openssl_patch_config(r, &hctx->conf);
2860         return HANDLER_GO_ON;
2861     }
2862     else {
2863         log_error(r->conf.errh, __FILE__, __LINE__,
2864           "SSL: %s", ERR_error_string(ERR_get_error(), NULL));
2865         return HANDLER_ERROR;
2866     }
2867 }
2868 
2869 
2870 static void
2871 mod_openssl_detach(handler_ctx *hctx)
2872 {
2873     /* step aside from further SSL processing
2874      * (used after handle_connection_shut_wr hook) */
2875     /* future: might restore prior network_read and network_write fn ptrs */
2876     hctx->con->is_ssl_sock = 0;
2877     /* if called after handle_connection_shut_wr hook, shutdown SHUT_WR */
2878     if (-1 == hctx->close_notify) shutdown(hctx->con->fd, SHUT_WR);
2879     hctx->close_notify = 1;
2880 }
2881 
2882 
2883 CONNECTION_FUNC(mod_openssl_handle_con_shut_wr)
2884 {
2885     plugin_data *p = p_d;
2886     handler_ctx *hctx = con->plugin_ctx[p->id];
2887     if (NULL == hctx) return HANDLER_GO_ON;
2888 
2889     hctx->close_notify = -2;
2890     if (SSL_is_init_finished(hctx->ssl)) {
2891         mod_openssl_close_notify(hctx);
2892     }
2893     else {
2894         mod_openssl_detach(hctx);
2895     }
2896 
2897     return HANDLER_GO_ON;
2898 }
2899 
2900 
2901 static int
2902 mod_openssl_close_notify(handler_ctx *hctx)
2903 {
2904         int ret, ssl_r;
2905         unsigned long err;
2906         log_error_st *errh;
2907 
2908         if (1 == hctx->close_notify) return -2;
2909 
2910         ERR_clear_error();
2911         switch ((ret = SSL_shutdown(hctx->ssl))) {
2912         case 1:
2913             mod_openssl_detach(hctx);
2914             return -2;
2915         case 0:
2916             /* Drain SSL read buffers in case pending records need processing.
2917              * Limit to reading next record to avoid denial of service when CPU
2918              * processing TLS is slower than arrival speed of TLS data packets.
2919              * (unless hctx->conf.ssl_read_ahead is set)
2920              *
2921              * references:
2922              *
2923              * "New session ticket breaks bidirectional shutdown of TLS 1.3 connection"
2924              * https://github.com/openssl/openssl/issues/6262
2925              *
2926              * The peer is still allowed to send data after receiving the
2927              * "close notify" event. If the peer did send data it need to be
2928              * processed by calling SSL_read() before calling SSL_shutdown() a
2929              * second time. SSL_read() will indicate the end of the peer data by
2930              * returning <= 0 and SSL_get_error() returning
2931              * SSL_ERROR_ZERO_RETURN. It is recommended to call SSL_read()
2932              * between SSL_shutdown() calls.
2933              *
2934              * Additional discussion in "Auto retry in shutdown"
2935              * https://github.com/openssl/openssl/pull/6340
2936              */
2937             ssl_r = SSL_pending(hctx->ssl);
2938             if (ssl_r) {
2939                 do {
2940                     char buf[4096];
2941                     ret = SSL_read(hctx->ssl, buf, (int)sizeof(buf));
2942                 } while (ret > 0 && (hctx->conf.ssl_read_ahead||(ssl_r-=ret)));
2943             }
2944 
2945             ERR_clear_error();
2946             switch ((ret = SSL_shutdown(hctx->ssl))) {
2947             case 1:
2948                 mod_openssl_detach(hctx);
2949                 return -2;
2950             case 0:
2951                 hctx->close_notify = -1;
2952                 return 0;
2953             default:
2954                 break;
2955             }
2956 
2957             /* fall through */
2958         default:
2959 
2960             if (!SSL_is_init_finished(hctx->ssl)) {
2961                 mod_openssl_detach(hctx);
2962                 return -2;
2963             }
2964 
2965             switch ((ssl_r = SSL_get_error(hctx->ssl, ret))) {
2966             case SSL_ERROR_ZERO_RETURN:
2967             case SSL_ERROR_WANT_WRITE:
2968             case SSL_ERROR_WANT_READ:
2969                 hctx->close_notify = -1;
2970                 return 0; /* try again later */
2971             case SSL_ERROR_SYSCALL:
2972                 /* perhaps we have error waiting in our error-queue */
2973                 errh = hctx->r->conf.errh;
2974                 if (0 != (err = ERR_get_error())) {
2975                     do {
2976                         log_error(errh, __FILE__, __LINE__,
2977                           "SSL: %d %d %s",ssl_r,ret,ERR_error_string(err,NULL));
2978                     } while((err = ERR_get_error()));
2979                 } else if (errno != 0) {
2980                     /*ssl bug (see lighttpd ticket #2213): sometimes errno==0*/
2981                     switch(errno) {
2982                     case EPIPE:
2983                     case ECONNRESET:
2984                         break;
2985                     default:
2986                         log_perror(errh, __FILE__, __LINE__,
2987                           "SSL (error): %d %d", ssl_r, ret);
2988                         break;
2989                     }
2990                 }
2991 
2992                 break;
2993             default:
2994                 errh = hctx->r->conf.errh;
2995                 while((err = ERR_get_error())) {
2996                     log_error(errh, __FILE__, __LINE__,
2997                       "SSL: %d %d %s", ssl_r, ret, ERR_error_string(err, NULL));
2998                 }
2999 
3000                 break;
3001             }
3002         }
3003         ERR_clear_error();
3004         hctx->close_notify = -1;
3005         return ret;
3006 }
3007 
3008 
3009 CONNECTION_FUNC(mod_openssl_handle_con_close)
3010 {
3011     plugin_data *p = p_d;
3012     handler_ctx *hctx = con->plugin_ctx[p->id];
3013     if (NULL != hctx) {
3014         con->plugin_ctx[p->id] = NULL;
3015         handler_ctx_free(hctx);
3016     }
3017 
3018     return HANDLER_GO_ON;
3019 }
3020 
3021 
3022 static void
3023 https_add_ssl_client_entries (request_st * const r, handler_ctx * const hctx)
3024 {
3025     buffer * const tb = r->tmp_buf;
3026     X509 *xs;
3027     X509_NAME *xn;
3028     int i, nentries;
3029 
3030     long vr = SSL_get_verify_result(hctx->ssl);
3031     if (vr != X509_V_OK) {
3032         char errstr[256];
3033         ERR_error_string_n(vr, errstr, sizeof(errstr));
3034         buffer_copy_string_len(tb, CONST_STR_LEN("FAILED:"));
3035         buffer_append_string(tb, errstr);
3036         http_header_env_set(r,
3037                             CONST_STR_LEN("SSL_CLIENT_VERIFY"),
3038                             CONST_BUF_LEN(tb));
3039         return;
3040     } else if (!(xs = SSL_get_peer_certificate(hctx->ssl))) {
3041         http_header_env_set(r,
3042                             CONST_STR_LEN("SSL_CLIENT_VERIFY"),
3043                             CONST_STR_LEN("NONE"));
3044         return;
3045     } else {
3046         http_header_env_set(r,
3047                             CONST_STR_LEN("SSL_CLIENT_VERIFY"),
3048                             CONST_STR_LEN("SUCCESS"));
3049     }
3050 
3051     xn = X509_get_subject_name(xs);
3052     {
3053         char buf[256];
3054         int len = safer_X509_NAME_oneline(xn, buf, sizeof(buf));
3055         if (len > 0) {
3056             if (len >= (int)sizeof(buf)) len = (int)sizeof(buf)-1;
3057             http_header_env_set(r,
3058                                 CONST_STR_LEN("SSL_CLIENT_S_DN"),
3059                                 buf, (size_t)len);
3060         }
3061     }
3062     buffer_copy_string_len(tb, CONST_STR_LEN("SSL_CLIENT_S_DN_"));
3063     for (i = 0, nentries = X509_NAME_entry_count(xn); i < nentries; ++i) {
3064         int xobjnid;
3065         const char * xobjsn;
3066         X509_NAME_ENTRY *xe;
3067 
3068         if (!(xe = wolfSSL_X509_NAME_get_entry(xn, i))) {
3069             continue;
3070         }
3071         xobjnid = OBJ_obj2nid((ASN1_OBJECT*)X509_NAME_ENTRY_get_object(xe));
3072         xobjsn = OBJ_nid2sn(xobjnid);
3073         if (xobjsn) {
3074             buffer_string_set_length(tb, sizeof("SSL_CLIENT_S_DN_")-1);
3075             buffer_append_string(tb, xobjsn);
3076             http_header_env_set(r,
3077                                 CONST_BUF_LEN(tb),
3078                                 (const char*)X509_NAME_ENTRY_get_data(xe)->data,
3079                                 X509_NAME_ENTRY_get_data(xe)->length);
3080         }
3081     }
3082 
3083     {
3084         byte buf[64];
3085         int bsz = (int)sizeof(buf);
3086         if (wolfSSL_X509_get_serial_number(xs, buf, &bsz) == WOLFSSL_SUCCESS) {
3087             char serialHex[128+1];
3088             li_tohex_uc(serialHex, sizeof(serialHex), (char *)buf, (size_t)bsz);
3089             http_header_env_set(r,
3090                                 CONST_STR_LEN("SSL_CLIENT_M_SERIAL"),
3091                                 serialHex, strlen(serialHex));
3092         }
3093     }
3094 
3095     if (!buffer_string_is_empty(hctx->conf.ssl_verifyclient_username)) {
3096         /* pick one of the exported values as "REMOTE_USER", for example
3097          *   ssl.verifyclient.username = "SSL_CLIENT_S_DN_UID"
3098          * or
3099          *   ssl.verifyclient.username = "SSL_CLIENT_S_DN_emailAddress"
3100          */
3101         const buffer *varname = hctx->conf.ssl_verifyclient_username;
3102         const buffer *vb = http_header_env_get(r, CONST_BUF_LEN(varname));
3103         if (vb) { /* same as http_auth.c:http_auth_setenv() */
3104             http_header_env_set(r,
3105                                 CONST_STR_LEN("REMOTE_USER"),
3106                                 CONST_BUF_LEN(vb));
3107             http_header_env_set(r,
3108                                 CONST_STR_LEN("AUTH_TYPE"),
3109                                 CONST_STR_LEN("SSL_CLIENT_VERIFY"));
3110         }
3111     }
3112 
3113     if (hctx->conf.ssl_verifyclient_export_cert) {
3114         int dersz, pemsz;
3115         const unsigned char *der = wolfSSL_X509_get_der(xs, &dersz);
3116         pemsz = der ? wc_DerToPemEx(der, dersz, NULL, 0, NULL, CERT_TYPE) : 0;
3117         if (pemsz > 0) {
3118             buffer_string_prepare_copy(tb, pemsz);
3119             if (0 == wc_DerToPemEx(der, dersz, (byte *)tb->ptr, pemsz,
3120                                    NULL, CERT_TYPE))
3121                 http_header_env_set(r,
3122                                     CONST_STR_LEN("SSL_CLIENT_CERT"),
3123                                     tb->ptr, (uint32_t)pemsz);
3124         }
3125     }
3126     X509_free(xs);
3127 }
3128 
3129 
3130 static void
3131 http_cgi_ssl_env (request_st * const r, handler_ctx * const hctx)
3132 {
3133     const char *s;
3134     const SSL_CIPHER *cipher;
3135 
3136     s = SSL_get_version(hctx->ssl);
3137     http_header_env_set(r, CONST_STR_LEN("SSL_PROTOCOL"), s, strlen(s));
3138 
3139     if ((cipher = SSL_get_current_cipher(hctx->ssl))) {
3140         s = SSL_CIPHER_get_name(cipher);
3141         http_header_env_set(r, CONST_STR_LEN("SSL_CIPHER"), s, strlen(s));
3142         /*(wolfSSL preprocessor defines are obnoxious)*/
3143       #if defined(OPENSSL_ALL) \
3144        || (defined(OPENSSL_EXTRA) \
3145            && (defined(HAVE_STUNNEL)    || \
3146                defined(WOLFSSL_NGINX)   || defined(HAVE_LIGHTY) || \
3147                defined(WOLFSSL_HAPROXY) || defined(WOLFSSL_OPENSSH)))
3148         int usekeysize, algkeysize = 0;
3149         char buf[LI_ITOSTRING_LENGTH];
3150         usekeysize = wolfSSL_CIPHER_get_bits(cipher, &algkeysize);
3151         if (0 == algkeysize) algkeysize = usekeysize;
3152         http_header_env_set(r, CONST_STR_LEN("SSL_CIPHER_USEKEYSIZE"),
3153                             buf, li_itostrn(buf, sizeof(buf), usekeysize));
3154         http_header_env_set(r, CONST_STR_LEN("SSL_CIPHER_ALGKEYSIZE"),
3155                             buf, li_itostrn(buf, sizeof(buf), algkeysize));
3156       #endif
3157     }
3158 }
3159 
3160 
3161 REQUEST_FUNC(mod_openssl_handle_request_env)
3162 {
3163     plugin_data *p = p_d;
3164     /* simple flag for request_env_patched */
3165     if (r->plugin_ctx[p->id]) return HANDLER_GO_ON;
3166     handler_ctx *hctx = r->con->plugin_ctx[p->id];
3167     if (NULL == hctx) return HANDLER_GO_ON;
3168     r->plugin_ctx[p->id] = (void *)(uintptr_t)1u;
3169 
3170     http_cgi_ssl_env(r, hctx);
3171     if (hctx->conf.ssl_verifyclient) {
3172         https_add_ssl_client_entries(r, hctx);
3173     }
3174 
3175     return HANDLER_GO_ON;
3176 }
3177 
3178 
3179 REQUEST_FUNC(mod_openssl_handle_uri_raw)
3180 {
3181     /* mod_openssl must be loaded prior to mod_auth
3182      * if mod_openssl is configured to set REMOTE_USER based on client cert */
3183     /* mod_openssl must be loaded after mod_extforward
3184      * if mod_openssl config is based on lighttpd.conf remote IP conditional
3185      * using remote IP address set by mod_extforward, *unless* PROXY protocol
3186      * is enabled with extforward.hap-PROXY = "enable", in which case the
3187      * reverse is true: mod_extforward must be loaded after mod_openssl */
3188     plugin_data *p = p_d;
3189     handler_ctx *hctx = r->con->plugin_ctx[p->id];
3190     if (NULL == hctx) return HANDLER_GO_ON;
3191 
3192     mod_openssl_patch_config(r, &hctx->conf);
3193     if (hctx->conf.ssl_verifyclient) {
3194         mod_openssl_handle_request_env(r, p);
3195     }
3196 
3197     return HANDLER_GO_ON;
3198 }
3199 
3200 
3201 REQUEST_FUNC(mod_openssl_handle_request_reset)
3202 {
3203     plugin_data *p = p_d;
3204     r->plugin_ctx[p->id] = NULL; /* simple flag for request_env_patched */
3205     return HANDLER_GO_ON;
3206 }
3207 
3208 
3209 TRIGGER_FUNC(mod_openssl_handle_trigger) {
3210     const plugin_data * const p = p_d;
3211     const time_t cur_ts = log_epoch_secs;
3212     if (cur_ts & 0x3f) return HANDLER_GO_ON; /*(continue once each 64 sec)*/
3213     UNUSED(srv);
3214     UNUSED(p);
3215 
3216   #ifdef HAVE_SESSION_TICKET
3217     mod_openssl_session_ticket_key_check(p, cur_ts);
3218   #endif
3219 
3220   #ifdef HAVE_OCSP
3221     mod_openssl_refresh_stapling_files(srv, p, cur_ts);
3222   #endif
3223 
3224     return HANDLER_GO_ON;
3225 }
3226 
3227 
3228 int mod_wolfssl_plugin_init (plugin *p);
3229 int mod_wolfssl_plugin_init (plugin *p)
3230 {
3231     p->version      = LIGHTTPD_VERSION_ID;
3232     p->name         = "wolfssl";
3233     p->init         = mod_openssl_init;
3234     p->cleanup      = mod_openssl_free;
3235     p->priv_defaults= mod_openssl_set_defaults;
3236 
3237     p->handle_connection_accept  = mod_openssl_handle_con_accept;
3238     p->handle_connection_shut_wr = mod_openssl_handle_con_shut_wr;
3239     p->handle_connection_close   = mod_openssl_handle_con_close;
3240     p->handle_uri_raw            = mod_openssl_handle_uri_raw;
3241     p->handle_request_env        = mod_openssl_handle_request_env;
3242     p->handle_request_reset      = mod_openssl_handle_request_reset;
3243     p->handle_trigger            = mod_openssl_handle_trigger;
3244 
3245     return 0;
3246 }
3247 
3248 
3249 static int
3250 mod_openssl_ssl_conf_proto_val (server *srv, plugin_config_socket *s, const buffer *b, int max)
3251 {
3252     if (NULL == b) /* default: min TLSv1.2, max TLSv1.3 */
3253       #ifdef TLS1_3_VERSION
3254         return max ? TLS1_3_VERSION : TLS1_2_VERSION;
3255       #else
3256         return TLS1_2_VERSION;
3257       #endif
3258     else if (buffer_eq_icase_slen(b, CONST_STR_LEN("None"))) /*"disable" limit*/
3259         return max
3260           ?
3261            #ifdef TLS1_3_VERSION
3262             TLS1_3_VERSION
3263            #else
3264             TLS1_2_VERSION
3265            #endif
3266           : (s->ssl_use_sslv3 ? SSL3_VERSION : TLS1_VERSION);
3267     else if (buffer_eq_icase_slen(b, CONST_STR_LEN("SSLv3")))
3268         return SSL3_VERSION;
3269     else if (buffer_eq_icase_slen(b, CONST_STR_LEN("TLSv1.0")))
3270         return TLS1_VERSION;
3271     else if (buffer_eq_icase_slen(b, CONST_STR_LEN("TLSv1.1")))
3272         return TLS1_1_VERSION;
3273     else if (buffer_eq_icase_slen(b, CONST_STR_LEN("TLSv1.2")))
3274         return TLS1_2_VERSION;
3275   #ifdef TLS1_3_VERSION
3276     else if (buffer_eq_icase_slen(b, CONST_STR_LEN("TLSv1.3")))
3277         return TLS1_3_VERSION;
3278   #endif
3279     else {
3280         if (buffer_eq_icase_slen(b, CONST_STR_LEN("DTLSv1"))
3281             || buffer_eq_icase_slen(b, CONST_STR_LEN("DTLSv1.2")))
3282             log_error(srv->errh, __FILE__, __LINE__,
3283                       "SSL: ssl.openssl.ssl-conf-cmd %s %s ignored",
3284                       max ? "MaxProtocol" : "MinProtocol", b->ptr);
3285         else
3286             log_error(srv->errh, __FILE__, __LINE__,
3287                       "SSL: ssl.openssl.ssl-conf-cmd %s %s invalid; ignored",
3288                       max ? "MaxProtocol" : "MinProtocol", b->ptr);
3289     }
3290   #ifdef TLS1_3_VERSION
3291     return max ? TLS1_3_VERSION : TLS1_2_VERSION;
3292   #else
3293     return TLS1_2_VERSION;
3294   #endif
3295 }
3296 
3297 
3298 static int
3299 mod_openssl_ssl_conf_cmd (server *srv, plugin_config_socket *s)
3300 {
3301     /* reference:
3302      * https://www.openssl.org/docs/man1.1.1/man3/SSL_CONF_cmd.html */
3303     int rc = 0;
3304     buffer *cipherstring = NULL;
3305     /*buffer *ciphersuites = NULL;*/
3306     buffer *minb = NULL;
3307     buffer *maxb = NULL;
3308     buffer *curves = NULL;
3309 
3310     for (size_t i = 0; i < s->ssl_conf_cmd->used; ++i) {
3311         data_string *ds = (data_string *)s->ssl_conf_cmd->data[i];
3312         if (buffer_eq_icase_slen(&ds->key, CONST_STR_LEN("CipherString")))
3313             cipherstring = &ds->value;
3314       #if 0
3315         else if (buffer_eq_icase_slen(&ds->key, CONST_STR_LEN("Ciphersuites")))
3316             ciphersuites = &ds->value;
3317       #endif
3318         else if (buffer_eq_icase_slen(&ds->key, CONST_STR_LEN("Curves"))
3319               || buffer_eq_icase_slen(&ds->key, CONST_STR_LEN("Groups")))
3320             curves = &ds->value;
3321         else if (buffer_eq_icase_slen(&ds->key, CONST_STR_LEN("MaxProtocol")))
3322             maxb = &ds->value;
3323         else if (buffer_eq_icase_slen(&ds->key, CONST_STR_LEN("MinProtocol")))
3324             minb = &ds->value;
3325         else if (buffer_eq_icase_slen(&ds->key, CONST_STR_LEN("Protocol"))) {
3326             /* openssl config for Protocol=... is complex and deprecated */
3327             log_error(srv->errh, __FILE__, __LINE__,
3328                       "SSL: ssl.openssl.ssl-conf-cmd %s ignored; "
3329                       "use MinProtocol=... and MaxProtocol=... instead",
3330                       ds->key.ptr);
3331         }
3332         else if (buffer_eq_icase_slen(&ds->key, CONST_STR_LEN("Options"))) {
3333             for (char *v = ds->value.ptr, *e; *v; v = e) {
3334                 while (*v == ' ' || *v == '\t' || *v == ',') ++v;
3335                 int flag = 1;
3336                 if (*v == '-') {
3337                     flag = 0;
3338                     ++v;
3339                 }
3340                 for (e = v; light_isalpha(*e); ++e) ;
3341                 switch ((int)(e-v)) {
3342                   case 11:
3343                     if (buffer_eq_icase_ssn(v, "Compression", 11)) {
3344                         if (flag)
3345                             SSL_CTX_clear_options(s->ssl_ctx,
3346                                                   SSL_OP_NO_COMPRESSION);
3347                         else
3348                             SSL_CTX_set_options(s->ssl_ctx,
3349                                                 SSL_OP_NO_COMPRESSION);
3350                         continue;
3351                     }
3352                     break;
3353                   case 13:
3354                     if (buffer_eq_icase_ssn(v, "SessionTicket", 13)) {
3355                         if (flag)
3356                             SSL_CTX_clear_options(s->ssl_ctx,
3357                                                   SSL_OP_NO_TICKET);
3358                         else
3359                             SSL_CTX_set_options(s->ssl_ctx,
3360                                                 SSL_OP_NO_TICKET);
3361                         continue;
3362                     }
3363                     break;
3364                   case 16:
3365                     if (buffer_eq_icase_ssn(v, "ServerPreference", 16)) {
3366                         if (flag)
3367                             SSL_CTX_set_options(s->ssl_ctx,
3368                                                SSL_OP_CIPHER_SERVER_PREFERENCE);
3369                         else
3370                             SSL_CTX_clear_options(s->ssl_ctx,
3371                                                SSL_OP_CIPHER_SERVER_PREFERENCE);
3372                         s->ssl_honor_cipher_order = flag;
3373                         continue;
3374                     }
3375                     break;
3376                   default:
3377                     break;
3378                 }
3379                 /* warn if not explicitly handled or ignored above */
3380                 if (!flag) --v;
3381                 log_error(srv->errh, __FILE__, __LINE__,
3382                           "SSL: ssl.openssl.ssl-conf-cmd Options %.*s "
3383                           "ignored", (int)(e-v), v);
3384             }
3385         }
3386       #if 0
3387         else if (buffer_eq_icase_slen(&ds->key, CONST_STR_LEN("..."))) {
3388         }
3389       #endif
3390         else {
3391             /* warn if not explicitly handled or ignored above */
3392             log_error(srv->errh, __FILE__, __LINE__,
3393                       "SSL: ssl.openssl.ssl-conf-cmd %s ignored",
3394                       ds->key.ptr);
3395         }
3396 
3397     }
3398 
3399     if (minb) {
3400         int n = mod_openssl_ssl_conf_proto_val(srv, s, minb, 0);
3401         /*(wolfSSL_CTX_SetMinVersion() alt uses enums with different values)*/
3402         switch (n) {
3403           case SSL3_VERSION:   n = WOLFSSL_SSLV3;   break;
3404           case TLS1_VERSION:   n = WOLFSSL_TLSV1;   break;
3405           case TLS1_1_VERSION: n = WOLFSSL_TLSV1_1; break;
3406           case TLS1_2_VERSION: n = WOLFSSL_TLSV1_2; break;
3407           case TLS1_3_VERSION: n = WOLFSSL_TLSV1_3; break;
3408           default: rc = -1; break;
3409         }
3410         if (wolfSSL_CTX_SetMinVersion(s->ssl_ctx, n) != WOLFSSL_SUCCESS)
3411             rc = -1;
3412     }
3413 
3414     if (maxb) {
3415         /* WolfSSL max ver is set at WolfSSL compile-time */
3416     }
3417 
3418     if (!buffer_string_is_empty(cipherstring)) {
3419         /* Disable support for low encryption ciphers */
3420         buffer_append_string_len(cipherstring,
3421                                  CONST_STR_LEN(":!aNULL:!eNULL:!EXP"));
3422         if (SSL_CTX_set_cipher_list(s->ssl_ctx, s->ssl_cipher_list->ptr) != 1) {
3423             log_error(srv->errh, __FILE__, __LINE__,
3424               "SSL: %s", ERR_error_string(ERR_get_error(), NULL));
3425             rc = -1;
3426         }
3427 
3428         if (s->ssl_honor_cipher_order)
3429             SSL_CTX_set_options(s->ssl_ctx, SSL_OP_CIPHER_SERVER_PREFERENCE);
3430     }
3431 
3432     if (curves) {
3433         if (!mod_openssl_ssl_conf_curves(srv, s, curves))
3434             rc = -1;
3435     }
3436 
3437     return rc;
3438 }
3439